Decrypt with BlowFish and load into DBGrid lazarus / 16-Databases ---------------------------------------------------------------------- CyberFilth · 2016-03-21 12:26 Hi, I have a small, simple program that stores users login details in an unencrypted CSV file and loads them into a DBGrid, https://sourceforge.net/projects/lazlock/files/0.4/ I want to be able to encrypt the file with BlowFish before saving it which I seem to have successfully done with this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  {$IFDEF Windows}  C_FNAME = 'files\data.csv';  {$ENDIF}  {$IFDEF Linux}  C_FNAME = 'files/data.csv';  {$ENDIF} procedure TLazLock.EncryptSaveClick(Sender: TObject);var  encrypt: TBlowFishEncryptStream;  SSun, SSen, SStream: TStringStream;  SList: TStringList;  FileContents: string; begin   FileContents:=Utf8Encode(ZMQueryDataset1.TableName); // Copy the contents of the DBGrid to FileContents   SSen:=TStringStream.Create('');   encrypt:=TBlowFishEncryptStream.Create(PasswordKey,SSen); // Encrypt with user entered PasswordKey   encrypt.Write(FileContents[1],Length(FileContents));   encrypt.Free;   SSun:=TStringStream.Create('');   SSun.Position:=0;   SStream:=TStringStream.Create(SSen.DataString);   SList:= TStringList.Create;   SList.LoadFromStream(SStream);   SList.SaveToFile(C_FNAME);   SSun.Free;   SSen.Free;   SStream.Free;end; I'm struggling to then load the file back into the DBGrid. I've tried using the procedure below but with no success. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TLazLock.DecryptAndOpenFile; { TODO : Use a constant for the password during testing }var   MemStream: TMemoryStream;   SL: TStringList;begin    MemStream := TMemoryStream.Create;    MemStream.LoadFromFile(C_FNAME);    DecryptionStream:= TBlowFishDeCryptStream.Create(PasswordKey,MemStream);    SL := TStringlist.Create;    SL.LoadFromStream(MemStream);     DBGrid1.Columns[2].PickList.Assign(SL);     ZMQueryDataset1.LoadFromTable;     MemStream.Free;     SL.Free;end; I'm definitely at the "a little knowledge is dangerous" end of the coding spectrum but wondered if anyone could give me some pointers to the problem. I'm assuming that I can't just load a StringList into a DBGrid this way but also wondered if the method I've used for decrypting the file could be an issue? The full code is at https://sourceforge.net/projects/lazlock/files/0.5.5/ Any help would be appreciated. ---------------------------------------------------------------------- dogriz · 2016-03-22 06:38 I don't know if this can help you in any way, but here's what i used with ClientDataSet in Delphi: Code: [Select]procedure TForm1.clientDataSet1GetText(Sender: TField;   var Text: String; DisplayText: Boolean); begin   if Sender.IsNull then     Text:='0'   else     Text:=Sender.AsString; end;This code has nothing to do with encryption, but I hope you get the idea. ---------------------------------------------------------------------- vfclists · 2016-03-31 23:03 You need to use the OnGetText event of the TField to decode the text. ---------------------------------------------------------------------- CyberFilth · 2016-04-06 12:33 Well previously, I successfully loaded an unencrypted CSV file into a DBGrid with; Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TLazLock.OpenFile;var   SL: TStringList;   MyStringStream:TStringStream;begin     SL:= TStringList.Create;     SL.LoadFromFile(C_FNAME);     DBGrid1.Columns[2].PickList.Assign(SL);     ZMQueryDataset1.LoadFromTable;     SL.Free; end; I was hoping to combine this with a small program I wrote that loaded an encrypted filestream and decrypted it, to come up with this; Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TLazLock.DecryptAndOpenFile;var   DecryptionStream: TBlowFishDeCryptStream;   MyStringStream, SSen, SStream2: TStringStream;   SL, SL2: TStringList;   tempdec: string;begin     SL:= TStringList.Create;     SL.LoadFromFile(C_FNAME);      SStream2:=TStringStream.Create('');     SL.SaveToStream(SStream2);   SL.Free;     SSen:=TStringStream.Create(SStream2.DataString);     SStream2.Free;     DecryptionStream:=TBlowFishDeCryptStream.Create(password,SSen);     SSen.Position:=0;     SetLength(tempdec,SSen.Size);     DecryptionStream.Read(tempdec[1],SSen.Size);     SL2:=TstringList.Create;     SL2.Text:=tempdec;     DBGrid1.Columns[2].PickList.Assign(SL2);     ZMQueryDataset1.LoadFromTable;     SL2.Free; end; But this doesn't display anything. I can decrypt the file and display it in a TMemo however... just not a DBGrid. ---------------------------------------------------------------------- Mike.Cornflake · 2016-04-06 13:18 I'm not sure how your original code worked. QuoteCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i DBGrid1.Columns[2].PickList.Assign(SL); A PickList is a dropdownlist that's added to that specific column.  I can't see how that populates the DBGrid QuoteCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ZMQueryDataset1.LoadFromTable; This makes a more sense.  It's the contents of ZMSQuery that you're displaying in the DBGrid, so in order to populate the Grid, you need the ZMSQuery populating first. I've never used ZMSQL, but from the wiki http://wiki.freepascal.org/ZMSQL Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure LoadFromTable; //Loads data (or data and schema) from a .csv file (TableName.csv), set in property TableName, from path specified in ZMConnection property So, what was possibly happening in your original code, was that you had the TableName property set in the Object Inspector, and this was pointing to a valid CSV on your system somewhere.  When you fired the LoadFromTable, it's that CSV that was loaded, nothing to do with PickList code. IF my guess is right, then all you need to do is change your routine to something like.. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TLazLock.DecryptAndOpenFile;var   DecryptionStream: TBlowFishDeCryptStream;   MyStringStream, SSen, SStream2: TStringStream;   SL, SL2: TStringList;   tempdec: string;begin     SL:= TStringList.Create;     SL.LoadFromFile(C_FNAME);     SStream2:=TStringStream.Create('');     SL.SaveToStream(SStream2);   SL.Free;     SSen:=TStringStream.Create(SStream2.DataString);     SStream2.Free;     DecryptionStream:=TBlowFishDeCryptStream.Create(password,SSen);     SSen.Position:=0;     SetLength(tempdec,SSen.Size);     DecryptionStream.Read(tempdec[1],SSen.Size);     SL2:=TstringList.Create;     SL2.Text:=tempdec;     //DBGrid1.Columns[2].PickList.Assign(SL2);     SL2.SaveToFile('C:\Temp\test.csv');       ZMConnection.Path := 'C:\Temp';  { Wild guess that this is how you set the path, and that this is what you called your connection }     ZMQueryDataset1.TableName := 'test.csv';          ZMQueryDataset1.LoadFromTable;     SL2.Free;end; Obviously, this ('C:\Temp\test.csv') is a hack :-)   You'd actually want to investigate loading ZMQuery from a stream, not a file.  I couldn't find that info in the wiki... ---------------------------------------------------------------------- CyberFilth · 2016-04-06 14:30 I think you're right! I'll check properly when I finish work but I believe that the tablename was originally set in the Object Inspector... I'll play around with it later and see if I can get this working. I'll also look into loading the ZMQuery from a stream as I don't want to save an unencrypted version of the file back to disk. Thanks for looking into this! ---------------------------------------------------------------------- Mike.Cornflake · 2016-04-06 15:18 No probs. Turns out ZMQuery is descended from TBufDataset, so should handle the streaming. Quickly skimmed this - may help http://wiki.freepascal.org/How_to_write_in- memory_database_applications_in_Lazarus/FPC and this entire topic :-)  Someone may have posted something relevant along the way... http://forum.lazarus.freepascal.org/index.php/topic,13821.105.html