Enchanted Keyfinder

Antworten
mheide
Beiträge: 4
Registriert: 20 Feb 2017, 14:58

Enchanted Keyfinder

Beitrag von mheide »

Huhu,

ihr verwendet anscheinend eine angepasste Version des Enchanted Keyfinder. Gibt es dazu auch irgendwo die Sourcen? Ich finde irgenwie überall - inklusive der swaudit-Repositories - nur das Binary (keyfinder.exe). Die Sourcen müssten ja doch auch irgendwo sein!?

Grüße
Michael
Benutzeravatar
d.oertel
uib-Team
Beiträge: 3319
Registriert: 04 Jun 2008, 14:27

Re: Enchanted Keyfinder

Beitrag von d.oertel »

Hi,

ich habe die sourcen jetzt abgelegt und zwar hier:
http://download.uib.de/opsi4.0/src/EKey ... source.zip

Kompiliert ist das ganze mit delphi7.

Und das ist alles lange her .....

gruss
detlef oertel
opsi support - uib gmbh

For productive opsi installations we recommend support contracts.
http://www.uib.de
http://www.opsi.org
mheide
Beiträge: 4
Registriert: 20 Feb 2017, 14:58

Re: Enchanted Keyfinder

Beitrag von mheide »

Vielen Dank. Ich möchte entsprechendes zurückliefern. Ich habe ein klein wenig die 64-Bit-Kompatibilität erhöht.

Allerdings ist das mein erster Kontakt mit Pascal seit der Schulzeit gewesen, welche schon etliche Jahre zurückliegt. Ich hab's auch nur kurz rein gehackt, ohne großartig die genaue Funktionsweise nachzuvollziehen. Die Codequalität ist damit Anfängerniveau und damit wohl ungefähr auf dem Niveau desjenigen, der das Produkt ursprünglich mal entwickelt hat. (sorry, ist so; da wurden Codeblöcke mehrfach kopiert und Texte einzeln von Hand angepasst statt eine Schleife mit Variablen zu nutzen. Oder Schleifenzähler von i = 1 bis x und dann jeweils j:=i-1 in der Schleife statt direkt ein i = 0 bis x-1 zu nutzen... und das sind nur die Schnitzer, die mir mal eben so auf die Schnelle aufgefallen sind...)

Wie auch immer, es erfüllt seinen Zweck, daher will ich da mal nichts weiter zu sagen.

Anhänge sind hier deaktiviert!? Ich hätt da eine modifizierte main.pas, die es tut...
mheide
Beiträge: 4
Registriert: 20 Feb 2017, 14:58

Re: Enchanted Keyfinder

Beitrag von mheide »

Es kompiliert übrigens auch mit neueren Dephi-Versionen, wie z.B. dem aktuellen Embarcadero Delphi DX 10.1 Berlin. Um auch installierte 64-Bit-Software zu erkennen muss man jedoch die Main.pas patchen. Siehe unten.

Was auf Anhieb nicht so gut funktioniert ist es mit Lazarus und FreePascal zu übersetzen. Der automatische Import erzeugt etwas nicht sonderlich funktionelles. Alles inkompatible herauszustreichen hat jedoch zu einem halbwegs funktionellen Produkt geführt, so dass ein echter Port nach Lazarus/FreePascal gar nicht mal so aufwändig sein dürfte.

Code: Alles auswählen

--- Main-opsi-original.pas	2017-02-22 13:05:27.913449803 +0100
+++ Main.pas	2017-02-21 11:47:30.000000000 +0100
@@ -770,7 +770,7 @@ begin
     ChangeWindowsKey1.Enabled := True;
   if Win32Platform <> VER_PLATFORM_WIN32_NT then
   begin
-	  ChangeWindowsKey1.Enabled := False;
+    ChangeWindowsKey1.Enabled := False;
     MnuItmLoadHive1.Enabled := False;
 
   end;
@@ -783,7 +783,7 @@ begin
     frmMain.Scaled := False;
     ChangeRegistrationInfo1.Enabled := False;
     PrintAll1.Enabled := False;
-	  ChangeWindowsKey1.Enabled := False;
+    ChangeWindowsKey1.Enabled := False;
   end;
 
   sPCName := GetPCName;
@@ -856,23 +856,23 @@ begin
       SaveDialog1.FileName := sPCName + '.csv';
     end;
 
-		if sCurParam = '/saveini' then
-		begin
-			bAutoSave := True;
-			if LeftStr(ParamStr(i + 1), 1) <> '/' then
-				sAutoSaveDir := ParamStr(i + 1);
-			SaveDialog1.FilterIndex := 3;
-			SaveDialog1.FileName := sPCName + '.ini';
-		end;
-
-		if sCurParam = '/savehtml' then
-		begin
-			bAutoSave := True;
-			if LeftStr(ParamStr(i + 1), 1) <> '/' then
-				sAutoSaveDir := ParamStr(i + 1);
-			SaveDialog1.FilterIndex := 4;
-			SaveDialog1.FileName := sPCName + '.html';
-		end;
+    if sCurParam = '/saveini' then
+    begin
+      bAutoSave := True;
+      if LeftStr(ParamStr(i + 1), 1) <> '/' then
+        sAutoSaveDir := ParamStr(i + 1);
+      SaveDialog1.FilterIndex := 3;
+      SaveDialog1.FileName := sPCName + '.ini';
+    end;
+
+    if sCurParam = '/savehtml' then
+    begin
+      bAutoSave := True;
+      if LeftStr(ParamStr(i + 1), 1) <> '/' then
+        sAutoSaveDir := ParamStr(i + 1);
+      SaveDialog1.FilterIndex := 4;
+      SaveDialog1.FileName := sPCName + '.html';
+    end;
 
     //if sCurParam = '/appendtop' then
     //  bAppendTop := True;
@@ -929,7 +929,7 @@ begin
   try
     MyReg.RootKey := HKEY_LOCAL_MACHINE;
     // This bit won't work for NT 4 as there is no ProductName value
-    if MyReg.OpenKey(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion', False) and
+    if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion') and
       MyReg.ValueExists('ProductName') then
     begin
       ListBox1.Items.Add(MyReg.ReadString('ProductName'));
@@ -969,7 +969,7 @@ var
   sOSEdition: string;
   sCSDVersion, sProductKey,
   sProductID, sRegOwn,
-	sRegOrg, sRegVersion: string;
+  sRegOrg, sRegVersion: string;
 
 begin
   sCSDVersion := '';
@@ -996,27 +996,27 @@ begin
 
   // Retrieve ID, User + Company name
   with TRegistry.Create() do
-	try
-		RootKey := HKEY_LOCAL_MACHINE;
-		Access := KEY_WOW64_64KEY or KEY_READ;
-    if (OpenKey(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion', False)) then
+  try
+    RootKey := HKEY_LOCAL_MACHINE;
+    Access := KEY_WOW64_64KEY or KEY_READ;
+    if (OpenKeyReadOnly(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion')) then
     begin
       sRegOwn := ReadString('RegisteredOwner');
       sRegOrg := ReadString('RegisteredOrganization');
       if sOSEdition = '' then
         sOSEdition := ReadString('EditionID');
       // Get Service Pack level
-			sCSDVersion := ReadString('CSDVersion');
-			sRegVersion := ReadString('CurrentVersion');
+      sCSDVersion := ReadString('CSDVersion');
+      sRegVersion := ReadString('CurrentVersion');
       CloseKey;
     end;
   finally
     Free;
   end; // try..finally
   if sCSDVersion <> '' then
-		Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
-	Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
-	Memo1.Lines.Add('Uninstall Product Name: ' + PChar('Microsoft ' + sOSEdition));
+    Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
+  Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
+  Memo1.Lines.Add('Uninstall Product Name: ' + PChar('Microsoft ' + sOSEdition));
   if sCSDVersion <> '' then
     Memo1.Lines[4] := Memo1.Lines[4] + ' (' + sCSDVersion + ')';
   Memo1.Lines.Add('Uninstall Product Version: ' + PChar(sRegVersion));
@@ -1028,7 +1028,7 @@ begin
   else
   begin
     Memo1.Lines.Add('Uninstall Architecture: 32Bit');
-	end;
+  end;
   Memo1.Lines.Add('Product ID: ' + PChar(sProductID));
   if not IsValidWinProdID(sProductID) then
   begin
@@ -1036,7 +1036,7 @@ begin
       'http://support.microsoft.com/default.aspx?scid=kb;en-us;Q326904');
   end
   else
-		Memo1.Lines.Add('License Key: ' + sProductKey);
+    Memo1.Lines.Add('License Key: ' + sProductKey);
 
   Memo1.Lines.Add(Trim('Computer Name: ' + GetPCName()));
   Memo1.Lines.Add(Trim('Registered Owner: ' + PChar(sRegOwn)));
@@ -1066,7 +1066,7 @@ var
   sProductID,
   sRegOwn,
   sRegOrg,
-	sRegVersion: string;
+  sRegVersion: string;
 
   function IsTabletOS: boolean;
   const
@@ -1129,29 +1129,29 @@ begin
   try
     RootKey := HKEY_LOCAL_MACHINE;
     Access := KEY_WOW64_64KEY or KEY_READ;
-    if (OpenKey(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion', False)) then
+    if (OpenKeyReadOnly(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion')) then
     begin
       sRegOwn := ReadString('RegisteredOwner');
       sRegOrg := ReadString('RegisteredOrganization');
       if sOSEdition = '' then
         sOSEdition := ReadString('EditionID');
       // Get Service Pack level
-			sCSDVersion := ReadString('CSDVersion');
-			sRegVersion := ReadString('CurrentVersion');
+      sCSDVersion := ReadString('CSDVersion');
+      sRegVersion := ReadString('CurrentVersion');
       CloseKey;
     end;
   //if (OpenKey(sHiveLoc + '\Microsoft\Windows\CurrentVersion\Reliability', False)) then
   //begin
   //  sCompName := ReadString('LastComputerName');
   //  CloseKey;
-  //end;	
+  //end;
   finally
     Free;
   end; // try..finally
 
   if sCSDVersion <> '' then
-		Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
-	Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
+    Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
+  Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
   Memo1.Lines.Add('Uninstall Product Name: ' + PChar('Microsoft ' + sOSEdition));
   if sCSDVersion <> '' then
     Memo1.Lines[4] := Memo1.Lines[4] + ' (' + sCSDVersion + ')';
@@ -1163,7 +1163,7 @@ begin
   else
   begin
     Memo1.Lines.Add('Uninstall Architecture: 32Bit');
-	end;
+  end;
   Memo1.Lines.Add('Product ID: ' + PChar(sProductID));
   if not IsValidWinProdID(sProductID) then
   begin
@@ -1171,7 +1171,7 @@ begin
       'http://support.microsoft.com/default.aspx?scid=kb;en-us;Q326904');
   end
   else
-		Memo1.Lines.Add('License key: ' + sProductKey);
+    Memo1.Lines.Add('License key: ' + sProductKey);
 
   Memo1.Lines.Add('Computer Name: ' + GetPCName());
   Memo1.Lines.Add('Registered Owner: ' + PChar(sRegOwn));
@@ -1212,7 +1212,7 @@ begin
   if MyReg.ValueExists('ProductKey') then
   begin
     sProductKey := MyReg.ReadString('ProductKey');
-		Memo1.Lines.Add('License key: ' + sProductKey);
+    Memo1.Lines.Add('License key: ' + sProductKey);
   end;
   if MyReg.ValueExists('RegisteredOwner') then
   begin
@@ -1244,7 +1244,7 @@ var
   sOSEdition: string;
   sTmp:     string;
   ProdSpec: TIniFile;
-	sCSDVersion, sProductKey, sRegOwn, sRegOrg, sRegVersion, sProductID: string;
+  sCSDVersion, sProductKey, sRegOwn, sRegOrg, sRegVersion, sProductID: string;
 begin
   sOSEdition := 'Unknown Windows NT Edition';
   if (sHiveLoc = 'Software') and (FileExists(GetEnvironmentVariable('SystemRoot') +
@@ -1271,16 +1271,16 @@ begin
   sRegOwn     := MyReg.ReadString('RegisteredOwner');
   sRegOrg     := MyReg.ReadString('RegisteredOrganization');
   // Get Service Pack level
-	sCSDVersion := MyReg.ReadString('CSDVersion');
-	sRegVersion := MyReg.ReadString('CurrentVersion');
-	sProductID  := MyReg.ReadString('ProductId');
+  sCSDVersion := MyReg.ReadString('CSDVersion');
+  sRegVersion := MyReg.ReadString('CurrentVersion');
+  sProductID  := MyReg.ReadString('ProductId');
   if sCSDVersion <> '' then
-		Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
-	Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
+    Memo1.Lines[0] := Memo1.Lines[0] + ' ' + sCSDVersion;
+  Memo1.Lines.Add('Uninstall Product ID: MS_WINDOWS_' + PChar(LeftStr(sProductID,9)));
   Memo1.Lines.Add('Uninstall Product Name: ' + PChar('Microsoft ' + sOSEdition));
   if sCSDVersion <> '' then
     Memo1.Lines[4] := Memo1.Lines[4] + ' (' + sCSDVersion + ')';
-	Memo1.Lines.Add('Uninstall Product Version: ' + PChar(sRegVersion));
+  Memo1.Lines.Add('Uninstall Product Version: ' + PChar(sRegVersion));
   sTmp := MyReg.ReadString('ProductID');
   sProductKey := sTmp;
   // Product ID is in 'xxx-xxxxxxx' or 'xxxxx-OEM-xxxxxxx-xxxxx' format with regard to NT4.
@@ -1335,12 +1335,12 @@ begin
   cSAMDesired := KEY_READ;
   if IsWow64 then
     cSAMDesired := KEY_WOW64_64KEY or KEY_READ;
-  MyReg   := TRegistry.Create;
+  MyReg   := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
   MyReg.RootKey := HKEY_LOCAL_MACHINE;
     MyReg.Access := cSAMDesired;
-  if (MyReg.OpenKey(sHivePath, False)) and MyReg.ValueExists('DigitalProductID') then
+  if (MyReg.OpenKeyReadOnly(sHivePath)) and MyReg.ValueExists('DigitalProductID') then
   begin
-      MyReg.Access := cSAMDesired;
+    MyReg.Access := cSAMDesired;
     iBinarySize := MyReg.GetDataSize('DigitalProductID');
     if iBinarySize >= 67 then  // Incomplete data  but still might be enough
     begin
@@ -1377,10 +1377,10 @@ begin
       begin
         dwChannel := (HexBuf[83] shl 24) or (HexBuf[82] shl 16) or (HexBuf[81] shl 8) or HexBuf[80];
         case dwChannel of
-					0: Memo1.Lines.Add('Installed from: ''Full Packaged Product'' media.');
-					1: Memo1.Lines.Add('Installed from: ''Compliance Checked Product'' media.');
-					2: Memo1.Lines.Add('Installed from: ''OEM'' media.');
-					3: Memo1.Lines.Add('Installed from: ''Volume'' media.');
+          0: Memo1.Lines.Add('Installed from: ''Full Packaged Product'' media.');
+          1: Memo1.Lines.Add('Installed from: ''Compliance Checked Product'' media.');
+          2: Memo1.Lines.Add('Installed from: ''OEM'' media.');
+          3: Memo1.Lines.Add('Installed from: ''Volume'' media.');
           end; // case dwChannel of
         end; // if wMajor
         sMSKey := rsNotFound;
@@ -1397,42 +1397,47 @@ end; // GetMSDPID3
 
 procedure TfrmMain.GetOfficeKey;
 var
-	MyReg: TRegistry;
-	My2Reg:  TRegistry;
+  MyReg: TRegistry;
+  My2Reg:  TRegistry;
   i: integer;
   sOfficeVer: string;
   sOfficeKey: string;
   sProductID: string;
   sProductKey: string;
   sOffRegPath: string;
+  sHiveLocTmp: string;
 const
   rel1='Release: ';
   rel2='Release Type: ';
 begin
-	My2Reg   := TRegistry.Create;
-	My2Reg.RootKey := HKEY_LOCAL_MACHINE;
+  My2Reg   := TRegistry.Create;
+  My2Reg.RootKey := HKEY_LOCAL_MACHINE;
   for i := 0 to (ListBox1.Items.Count - 1) do
   begin
     if ListBox1.Selected[i] then
     begin
+      sHiveLocTmp := MidStr(ListBox2.Items.Strings[i], 9,
+        Pos('|', ListBox2.Items.Strings[i]) - 9);
       sOfficeKey := RightStr(ListBox2.Items.Strings[i], Length(
-        ListBox2.Items.Strings[i]) - 8);
+        ListBox2.Items.Strings[i]) - Pos('|', ListBox2.Items.Strings[i]));
       sOfficeVer := MidStr(ListBox2.Items.Strings[i], 7, 2);
-      MyReg      := TRegistry.Create;
+      MyReg      := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
       MyReg.RootKey := HKEY_LOCAL_MACHINE;
-      sOffRegPath := sHiveLoc + '\Microsoft\Office\' + sOfficeVer + '.0\Registration\' + sOfficeKey;
+
+
+      sOffRegPath := sHiveLocTmp + '\Microsoft\Office\' + sOfficeVer + '.0\Registration\' + sOfficeKey;
       if MyReg.OpenKeyReadOnly(sOffRegPath) then
-			begin
-				sProductID  := MyReg.ReadString('ProductID');
-				GetMSDPID3(sOffRegPath, sProductID, sProductKey);
-
-				Memo1.Lines.Add('Product ID: ' + PChar(sProductID));
-				My2Reg.OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\uninstall\' + sOfficeKey);
-				Memo1.Lines.Add('Uninstall Product ID: ' + PChar(sOfficeKey));
-				Memo1.Lines.Add('Uninstall Product Name: ' + PChar(My2Reg.ReadString('DisplayName')));
-				Memo1.Lines.Add('Uninstall Product Version: ' + PChar(My2Reg.ReadString('DisplayVersion')));
-				My2Reg.CloseKey;
-				My2Reg.Free;
+      begin
+        sProductID  := MyReg.ReadString('ProductID');
+        GetMSDPID3(sOffRegPath, sProductID, sProductKey);
+
+        Memo1.Lines.Add('Product ID: ' + PChar(sProductID));
+        My2Reg.OpenKeyReadOnly('Software\Microsoft\Windows\CurrentVersion\uninstall\' + sOfficeKey);
+        Memo1.Lines.Add('Uninstall Product ID: ' + PChar(sOfficeKey));
+        Memo1.Lines.Add('Uninstall Product Name: ' + PChar(My2Reg.ReadString('DisplayName')));
+        Memo1.Lines.Add('Uninstall Product Version: ' + PChar(My2Reg.ReadString('DisplayVersion')));
+        My2Reg.CloseKey;
+        My2Reg.Free;
         if not IsValidWinProdID(sProductID) then
         begin
           Memo1.Lines.Add('Invalid Product ID detected as listed by Microsoft KB ' +
@@ -1440,7 +1445,7 @@ begin
         end
         else
         begin
-					Memo1.Lines.Add('License key: ' + sProductKey);
+          Memo1.Lines.Add('License key: ' + sProductKey);
           //ShowMessage('sOfficeKey='+sOfficeKey+sLineBreak+ RightStr(LeftStr(sOfficeKey,2),1) + ' ' + RightStr(LeftStr(sOfficeKey,3),1));
           //RightStr(LeftStr(sOfficeKey,2),1) + ' ' + RightStr(LeftStr(sOfficeKey,3),1)
           //http://support.microsoft.com/kb/2186281
@@ -1448,18 +1453,18 @@ begin
             0: Memo1.Lines.Add(rel1+'Pre Beta');
             1: Memo1.Lines.Add(rel1+'Beta 1');
             2: Memo1.Lines.Add(rel1+'Beta 2');
-            3: Memo1.Lines.Add(rel1+'Release Candidate 0'); 
+            3: Memo1.Lines.Add(rel1+'Release Candidate 0');
             4: Memo1.Lines.Add(rel1+'Release Candidate 1/OEM Preview Release');
             9: Memo1.Lines.Add(rel1+'RTM');
             10: Memo1.Lines.Add(rel1+'Service Pack 1');
             11: Memo1.Lines.Add(rel1+'Service Pack 2');
-            12: Memo1.Lines.Add(rel1+'Service Pack 3'); 
+            12: Memo1.Lines.Add(rel1+'Service Pack 3');
           end;
           case StrToInt('0x' + RightStr(LeftStr(sOfficeKey, 3), 1)) of
-            0: Memo1.Lines.Add(rel2+'Volume License'); 
-            1: Memo1.Lines.Add(rel2+'Retail/OEM'); 
-            2: Memo1.Lines.Add(rel2+'Trial'); 
-            5: Memo1.Lines.Add(rel2+'Download'); 
+            0: Memo1.Lines.Add(rel2+'Volume License');
+            1: Memo1.Lines.Add(rel2+'Retail/OEM');
+            2: Memo1.Lines.Add(rel2+'Trial');
+            5: Memo1.Lines.Add(rel2+'Download');
           end;
         end;
       end;
@@ -1485,7 +1490,7 @@ var
   ConfigFile: TextFile;
   CurrentLine: string;
   s: string;
-	i: integer;
+  i: integer;
 begin
   CurrentLine := '';
   s := '';
@@ -1605,7 +1610,7 @@ var
   Subkeys: TStrings; 
   I: Integer; 
   PrefixKey: String; 
-begin 
+begin
   I := 1; 
   while i < length(ValueWithWildCard) do
    begin 
@@ -1618,7 +1623,7 @@ begin
   Subkeys := TStringList.Create; 
   try 
     MyReg.RootKey := RootKey;
-    if (MyReg.OpenKey(RootPath, False)) then
+    if (MyReg.OpenKeyReadOnly(RootPath)) then
       begin 
       MyReg.GetValueNames(Subkeys);
       for I := 0 to (Subkeys.Count - 1) do 
@@ -1650,10 +1655,10 @@ var
   sTmp: string;
   sProdID: string;
   foundSerial: boolean;
-	whileIndex: integer;
-	s_identifier: string;
-	sUninstallKey: string;
-	sBaseUninstallKey: string;
+  whileIndex: integer;
+  s_identifier: string;
+  sUninstallKey: string;
+  sBaseUninstallKey: string;
 
 begin
   for i := 0 to (ListBox1.Items.Count - 1) do
@@ -1669,20 +1674,22 @@ begin
         begin
           s  := RightStr(s, Length(s) - 1);
           j  := Pos('=', s);
-					s2 := RightStr(s, Length(s) - Pos('\', s));
-					s_identifier := LeftStr(s, j - 1);
-					sRegRootKey := UpperCase(MidStr(s, j + 1, Pos('\', s) - j - 1));
-					sRegOpenKey := LeftStr(s2, Pos('=', s2) - 1);
-					if UpperCase(s_identifier) = 'UNINSTALLKEY' then
+          s2 := RightStr(s, Length(s) - Pos('\', s));
+          s_identifier := LeftStr(s, j - 1);
+          sRegRootKey := UpperCase(MidStr(s, j + 1, Pos('\', s) - j - 1));
+          sRegOpenKey := LeftStr(s2, Pos('=', s2) - 1);
+
+          // TODO: this method was heavily modified by uib/opsi - compare old and new
+          if UpperCase(s_identifier) = 'UNINSTALLKEY' then
           begin
             //32Bit
             sUninstallKey :=  RightStr(s, Length(s) - 13);
-						MyReg := TRegistry.Create;
-						MyReg.RootKey := HKEY_LOCAL_MACHINE;
-						MyReg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' +  sUninstallKey, false);
+            MyReg := TRegistry.Create;
+            MyReg.RootKey := HKEY_LOCAL_MACHINE;
+            MyReg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' +  sUninstallKey, false);
             Memo1.Lines.Add('Uninstall Product ID: ' + sUninstallKey);
-						Memo1.Lines.Add('Uninstall Product Name: ' + myReg.ReadString('DisplayName'));
-						Memo1.Lines.Add('Uninstall Product Version: ' + myReg.ReadString('DisplayVersion'));
+            Memo1.Lines.Add('Uninstall Product Name: ' + myReg.ReadString('DisplayName'));
+            Memo1.Lines.Add('Uninstall Product Version: ' + myReg.ReadString('DisplayVersion'));
             Memo1.Lines.Add('Uninstall Architecture: 32Bit');
             MyReg.CloseKey;
             MyReg.Free;
@@ -1690,127 +1697,127 @@ begin
             if IsWow64 then
             begin
               sUninstallKey :=  RightStr(s, Length(s) - 13);
-							MyReg := TRegistry.Create;
-							MyReg.Access := KEY_WOW64_64KEY or KEY_READ;
+              MyReg := TRegistry.Create;
+              MyReg.Access := KEY_WOW64_64KEY or KEY_READ;
               MyReg.RootKey := HKEY_LOCAL_MACHINE;
-							MyReg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' +  sUninstallKey, false);
-							Memo1.Lines.Add('Uninstall Product ID: ' + sUninstallKey);
-							Memo1.Lines.Add('Uninstall Product Name: ' + myReg.ReadString('DisplayName'));
-							Memo1.Lines.Add('Uninstall Product Version: ' + myReg.ReadString('DisplayVersion'));
-							Memo1.Lines.Add('Uninstall Architecture: 64Bit');
-							MyReg.CloseKey;
-							MyReg.Free;
-						end
-					end
-					else
-					begin
-						if Pos('|', s2) > 0 then
-							sRegValue := MidStr(s2, Pos('=', s2), Pos('|', s2) - Pos('=', s2))
-						else
-							sRegValue := RightStr(s2, Pos('=', ReverseString(s2)));
-						sRegValue := RightStr(sRegValue, Length(sRegValue) - 1);
-						sTmp := Uppercase(LeftStr(sRegOpenKey, 8));
-						if (sRegRootKey = 'HKEY_LOCAL_MACHINE') or (sRegRootKey = 'HKEY_CURRENT_USER') and (sTmp = 'SOFTWARE') then
-							sRegOpenKey := sHiveLoc + RightStr(sRegOpenKey, Length(sRegOpenKey) - 8);
-
-						// Set the registry rootkeys
-
-						MyReg := TRegistry.Create;
-						if sRegRootKey = 'HKEY_LOCAL_MACHINE' then
-							MyReg.RootKey := HKEY_LOCAL_MACHINE
-						else if (sRegRootKey = 'HKEY_CURRENT_USER') and (Uppercase(sHiveLoc) = 'SOFTWARE') then
-							MyReg.RootKey := HKEY_CURRENT_USER
-						// this is done to avoid confusion - reading current registry instead of hive
-						else
-						begin
-							ListBox1.Items.Delete(i);
-							ListBox2.Items.Delete(i);
-							MyReg.Free;
-							Exit;
-						end;
-
-						// Check for MS digital id entry in .cfg and decode if true
-						sTmp := '';
-						if LowerCase(sRegValue) = 'digitalproductid' then
-							GetMSDPID3(sHiveLoc + sRegOpenKey, sProdID, sTmp)
-						else // not an ms digital id
-						begin
-							if Listbox1.Items[0] <> 'Microsoft Windows 2000' then
-								MyReg.Access := KEY_WOW64_64KEY or KEY_READ;
-							if MyReg.OpenKey(sHiveLoc + sRegOpenKey, False) then
-							begin
-								try
-									try
-										RegDataType := MyReg.GetDataType(sRegValue);
-										if (RegDataType = rdString) or (RegDataType = rdExpandString) then
-											sTmp := MyReg.ReadString(sRegValue)
-										else if RegDataType = rdInteger then
-											sTmp := IntToStr(MyReg.ReadInteger(sRegValue));
-									except
-										on E: ERegistryException do
-											//MessageDlg('Can''t read a Registry key. [' + sRegOpenKey + ']' + #13 + 'Error: ' + E.Message, mtError, [mbOK], 0);
-											MessageDlg('Keyfinder ' + E.Message + '.', mtError, [mbOK], 0);
-									end;
-								finally
-									MyReg.CloseKey;
-									MyReg.Free;
-								end; // try .. finally
-							end; // if MyReg.OpenKey
-						end;
-
-						// start reading the registry
-						// Can't use MyReg.ValueExists(sRegValue) or some programs won't show when they should
-						if (MyReg.OpenKeyReadOnly(sRegOpenKey)) then
-						begin
-							if FindRegistryValue(MyReg.Rootkey,sRegOpenKey,sRegValue) <> Null then
-							try
-								sTmp := MyReg.ReadString(FindRegistryValue(MyReg.Rootkey,sRegOpenKey,sRegValue));
-							except
-								on E: Exception do
-									sTmp := 'Error! Invalid data type.  Check key.';
-							end;
-						end
-						else
-						begin
-							ListBox1.Items.Delete(i);
-							ListBox2.Items.Delete(i);
-							MyReg.Free;
-							Exit;
-						end;
-
-						// Do a quick test for an Adobe entry in .cfg and decode if true
-						if (pos('adobe ', LowerCase(ListBox1.Items.Strings[i])) <> 0) and (IsNumeric(sTmp, True)) then
-						begin
-							if (pos('lightroom 1', LowerCase(ListBox1.Items.Strings[i])) = 0) and (pos('photoshop 7', LowerCase(ListBox1.Items.Strings[i])) = 0) then
-							begin  // The Lightroom 1 & Photoshop 7 serial is not encoded
-								if (LowerCase(sRegValue) = 'epic_serial') or (LowerCase(sRegValue) = 'serial') or (LowerCase(sRegValue) = 'serial_number') then
-								begin  // Only try decode serial keys
-									sRegValue := DecodeAdobeKey(sTmp);  // Just stealing use of sRegValue
-									sTmp      := sRegValue;             // to do some string swapping
-								end;
-							end
-						end
-						else
-							FormatAdobeKey(sTmp);
-
-						//fix bug for blank entry
-						//MessageDlg('Lines:  ' + IntToStr(Memo1.Lines.Count) + '; Length: ' + IntToStr(Length(sTmp)), mtInformation , [mbOK], 0);
-						//add entry to the list
-						if j > 1 then
-						begin
-							if (Length(sTmp) > 0) or showBlankSerials then
-							begin
-								Memo1.Lines.Add(s_identifier + ': ' + sTmp);
-								//Memo1.Lines.Add(LeftStr(s, j - 1) + ': ' + sTmp);
-								if whileIndex = 0 then
-									foundSerial := True;
-							end;
-						end
-						else if Length(sTmp) > 0 then
-						begin
-							Memo1.Lines.Add(sTmp);
-						end;
-					end;
+              MyReg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\' +  sUninstallKey, false);
+              Memo1.Lines.Add('Uninstall Product ID: ' + sUninstallKey);
+              Memo1.Lines.Add('Uninstall Product Name: ' + myReg.ReadString('DisplayName'));
+              Memo1.Lines.Add('Uninstall Product Version: ' + myReg.ReadString('DisplayVersion'));
+              Memo1.Lines.Add('Uninstall Architecture: 64Bit');
+              MyReg.CloseKey;
+              MyReg.Free;
+            end
+          end
+          else
+          begin
+            if Pos('|', s2) > 0 then
+              sRegValue := MidStr(s2, Pos('=', s2), Pos('|', s2) - Pos('=', s2))
+            else
+              sRegValue := RightStr(s2, Pos('=', ReverseString(s2)));
+            sRegValue := RightStr(sRegValue, Length(sRegValue) - 1);
+            sTmp := Uppercase(LeftStr(sRegOpenKey, 8));
+            if (sRegRootKey = 'HKEY_LOCAL_MACHINE') or (sRegRootKey = 'HKEY_CURRENT_USER') and (sTmp = 'SOFTWARE') then
+              sRegOpenKey := sHiveLoc + RightStr(sRegOpenKey, Length(sRegOpenKey) - 8);
+
+            // Set the registry rootkeys
+
+            MyReg := TRegistry.Create;
+            if sRegRootKey = 'HKEY_LOCAL_MACHINE' then
+              MyReg.RootKey := HKEY_LOCAL_MACHINE
+            else if (sRegRootKey = 'HKEY_CURRENT_USER') and (Uppercase(sHiveLoc) = 'SOFTWARE') then
+              MyReg.RootKey := HKEY_CURRENT_USER
+            // this is done to avoid confusion - reading current registry instead of hive
+            else
+            begin
+              ListBox1.Items.Delete(i);
+              ListBox2.Items.Delete(i);
+              MyReg.Free;
+              Exit;
+            end;
+
+            // Check for MS digital id entry in .cfg and decode if true
+            sTmp := '';
+            if LowerCase(sRegValue) = 'digitalproductid' then
+              GetMSDPID3(sHiveLoc + sRegOpenKey, sProdID, sTmp)
+            else // not an ms digital id
+            begin
+              if Listbox1.Items[0] <> 'Microsoft Windows 2000' then
+                MyReg.Access := KEY_WOW64_64KEY or KEY_READ;
+              if MyReg.OpenKey(sHiveLoc + sRegOpenKey, False) then
+              begin
+                try
+                  try
+                    RegDataType := MyReg.GetDataType(sRegValue);
+                    if (RegDataType = rdString) or (RegDataType = rdExpandString) then
+                      sTmp := MyReg.ReadString(sRegValue)
+                    else if RegDataType = rdInteger then
+                      sTmp := IntToStr(MyReg.ReadInteger(sRegValue));
+                  except
+                    on E: ERegistryException do
+                      //MessageDlg('Can''t read a Registry key. [' + sRegOpenKey + ']' + #13 + 'Error: ' + E.Message, mtError, [mbOK], 0);
+                      MessageDlg('Keyfinder ' + E.Message + '.', mtError, [mbOK], 0);
+                  end;
+                finally
+                  MyReg.CloseKey;
+                  MyReg.Free;
+                end; // try .. finally
+              end; // if MyReg.OpenKey
+            end;
+
+            // start reading the registry
+            // Can't use MyReg.ValueExists(sRegValue) or some programs won't show when they should
+            if (MyReg.OpenKeyReadOnly(sRegOpenKey)) then
+            begin
+              if FindRegistryValue(MyReg.Rootkey,sRegOpenKey,sRegValue) <> Null then
+              try
+                sTmp := MyReg.ReadString(FindRegistryValue(MyReg.Rootkey,sRegOpenKey,sRegValue));
+              except
+                on E: Exception do
+                  sTmp := 'Error! Invalid data type.  Check key.';
+              end;
+            end
+            else
+            begin
+              ListBox1.Items.Delete(i);
+              ListBox2.Items.Delete(i);
+              MyReg.Free;
+              Exit;
+            end;
+
+            // Do a quick test for an Adobe entry in .cfg and decode if true
+            if (pos('adobe ', LowerCase(ListBox1.Items.Strings[i])) <> 0) and (IsNumeric(sTmp, True)) then
+            begin
+              if (pos('lightroom 1', LowerCase(ListBox1.Items.Strings[i])) = 0) and (pos('photoshop 7', LowerCase(ListBox1.Items.Strings[i])) = 0) then
+              begin  // The Lightroom 1 & Photoshop 7 serial is not encoded
+                if (LowerCase(sRegValue) = 'epic_serial') or (LowerCase(sRegValue) = 'serial') or (LowerCase(sRegValue) = 'serial_number') then
+                begin  // Only try decode serial keys
+                  sRegValue := DecodeAdobeKey(sTmp);  // Just stealing use of sRegValue
+                  sTmp      := sRegValue;             // to do some string swapping
+                end;
+              end
+            end
+            else
+              FormatAdobeKey(sTmp);
+
+            //fix bug for blank entry
+            //MessageDlg('Lines:  ' + IntToStr(Memo1.Lines.Count) + '; Length: ' + IntToStr(Length(sTmp)), mtInformation , [mbOK], 0);
+            //add entry to the list
+            if j > 1 then
+            begin
+              if (Length(sTmp) > 0) or showBlankSerials then
+              begin
+                Memo1.Lines.Add(s_identifier + ': ' + sTmp);
+                //Memo1.Lines.Add(LeftStr(s, j - 1) + ': ' + sTmp);
+                if whileIndex = 0 then
+                  foundSerial := True;
+              end;
+            end
+            else if Length(sTmp) > 0 then
+            begin
+              Memo1.Lines.Add(sTmp);
+            end;
+          end;
 
 
           //ShowMessage(LeftStr(s, j - 1) + sLineBreak + inttostr(whileIndex))
@@ -1866,16 +1873,26 @@ begin
 end; // TfrmMain.ParseConfig
 
 procedure TfrmMain.OfficeList;
+type
+  TOfficeVer = array[1..2] of string;
+  TOfficeVers = array[1..5] of TOfficeVer;
 var
-	MyReg: TRegistry;
-	slOfficeList: TStringList;
-	I: integer;
-	J: integer;
-	K: string;
-begin
-	MyReg := TRegistry.Create;
-	slOfficeList  := TStringList.Create;
-	MyReg.RootKey := HKEY_LOCAL_MACHINE;
+  MyReg: TRegistry;
+  slOfficeList: TStringList;
+  I: integer;
+  J: integer;
+  K: string;
+  sHiveLocTmp: string;
+  Wow6432NodeChecked: boolean;
+  OfficeVer: TOfficeVer;
+  OfficeReg: string;
+const
+  OfficeVers: TOfficeVers =
+    (('10','XP'),('11','2003'),('12','2007'),('14','2010'),('15','2013'));
+begin
+  MyReg := TRegistry.Create(KEY_READ OR KEY_WOW64_64KEY);
+  slOfficeList  := TStringList.Create;
+  MyReg.RootKey := HKEY_LOCAL_MACHINE;
 
   if RemotePC1.Checked = True then
   begin
@@ -1904,43 +1921,62 @@ begin
     end;
   end; // if RemotePC1.Checked
 
-  // Office XP
-  if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\10.0\Registration') then
+  // general Office XP - 2010 (ex Office XP)
+  // TODO: bzgl. opsi-port anpassen
+  Wow6432NodeChecked := False;
+  sHiveLocTmp := sHiveLoc+'\Wow6432Node';
+  while True do // leaving via break at the end
   begin
-    MyReg.GetKeyNames(slOfficeList);
-    MyReg.CloseKey;
-    for I := 1 to slOfficeList.Count do
+    for OfficeVer in OfficeVers do
     begin
-      J := I - 1;
-      K := slOfficeList.Strings[J];
-      if LeftStr(K, 1) = '{' then
+      OfficeReg := sHiveLocTmp + '\Microsoft\Office\'+OfficeVer[1]+'.0\Registration';
+      
+
+      if MyReg.OpenKeyReadOnly(OfficeReg) then
       begin
-        MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\10.0\Registration\' + K);
-        if MyReg.ValueExists('DigitalProductID') then
+        MyReg.GetKeyNames(slOfficeList);
+        MyReg.CloseKey;
+        for I := 1 to slOfficeList.Count do
         begin
-          if MyReg.ReadString('ProductName') <> '' then
-            ListBox1.Items.Add(MyReg.ReadString('ProductName'))
-          else
+          J := I - 1;
+          K := slOfficeList.Strings[J];
+          if LeftStr(K, 1) = '{' then
           begin
+            MyReg.OpenKeyReadOnly(OfficeReg + '\' + K);
+            if MyReg.ValueExists('DigitalProductID') then
+            begin
+              if MyReg.ReadString('ProductName') <> '' then
+                ListBox1.Items.Add(MyReg.ReadString('ProductName'))
+              else
+              begin
+                MyReg.CloseKey;
+                MyReg.OpenKeyReadOnly(sHiveLocTmp +
+                  '\Microsoft\Windows\CurrentVersion\Uninstall\' + K);
+                if MyReg.ReadString('DisplayName') <> '' then
+                  ListBox1.Items.Add(MyReg.ReadString('DisplayName'))
+                else
+                  ListBox1.Items.Add('Unidentifiable Office '+OfficeVer[2]+' Installation');
+              end;
+              ListBox2.Items.Add('Office' + OfficeVer[1] + sHiveLocTmp + '|' + K);
+            end;
             MyReg.CloseKey;
-            MyReg.OpenKeyReadOnly(sHiveLoc +
-              '\Microsoft\Windows\CurrentVersion\Uninstall\' + K);
-            if MyReg.ReadString('DisplayName') <> '' then
-              ListBox1.Items.Add(MyReg.ReadString('DisplayName'))
-            else
-              ListBox1.Items.Add('Unidentifiable Office XP Installation');
           end;
-          ListBox2.Items.Add('Office10' + K);
         end;
-        MyReg.CloseKey;
       end;
+
     end;
+    if Wow6432NodeChecked then // won't find parallel 32bit and 64bit office installs
+      break;
+    Wow6432NodeChecked := True;
+    //sHiveLocTmp := sHiveLoc+'\Wow6432Node';
+    sHiveLocTmp := sHiveLoc;
+    //sHiveLocTmp := 'SOFTWARE';
   end;
 
-  // Office 2003
+  // Office 2003 TODO: handled by general office loop up there
   // Office 2003 with no service packs {90110409-6000-11D3-8CFE-0150048383C9}
   // Office 2003 with SP1 {91110409-6000-11D3-8CFE-0150048383C9}
-  if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\11.0\Registration') then
+  if False and MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\11.0\Registration') then
   begin
     MyReg.GetKeyNames(slOfficeList);
     MyReg.CloseKey;
@@ -1972,8 +2008,8 @@ begin
     end;
   end;
 
-  // Office 2007
-  if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\12.0\Registration') then
+  // Office 2007 TODO: handled by general office loop up there
+  if False and MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\12.0\Registration') then
   begin
     MyReg.GetKeyNames(slOfficeList);
     MyReg.CloseKey;
@@ -2005,8 +2041,8 @@ begin
     end;
   end;
 
-  // Office 2010
-  if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\14.0\Registration') then
+  // Office 2010 TODO: handled by general office loop up there
+  if False and MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Office\14.0\Registration') then
   begin
     MyReg.GetKeyNames(slOfficeList);
     MyReg.CloseKey;
@@ -2245,8 +2281,8 @@ begin
   else
   begin
     if bAutoSave = True then
-		begin
-			ConvertSaveFormat;
+    begin
+      ConvertSaveFormat;
       try
         Memo2.Lines.SaveToFile(sAutoSaveDir + SaveDialog1.FileName);
       except
@@ -2263,11 +2299,11 @@ begin
       bAutoSave := False;
     end
     else if SaveDialog1.Execute then
-		begin
-			ConvertSaveFormat;
+    begin
+      ConvertSaveFormat;
       try
-				Memo2.Lines.SaveToFile(SaveDialog1.FileName);
-				if SaveDialog1.FilterIndex = 3 then convertIniFile(SaveDialog1.FileName);
+        Memo2.Lines.SaveToFile(SaveDialog1.FileName);
+        if SaveDialog1.FilterIndex = 3 then convertIniFile(SaveDialog1.FileName);
       except
         on E: EFCreateError do
         begin
@@ -2706,7 +2742,7 @@ begin
     // Don't change MyReg.Access method if Win2k
     if Listbox1.Items[0] <> 'Microsoft Windows 2000' then
       MyReg.Access := KEY_WOW64_64KEY or KEY_READ;
-    if MyReg.OpenKey(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion', False) and
+    if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Windows NT\CurrentVersion') and
       MyReg.ValueExists('RegisteredOwner') and
       MyReg.ValueExists('RegisteredOrganization') then
     begin
@@ -2724,7 +2760,7 @@ begin
     MyReg := TRegistry.Create;
     MyReg.RootKey := HKEY_LOCAL_MACHINE;
     MyReg.Access := KEY_READ;
-    if MyReg.OpenKey(sHiveLoc + '\Microsoft\Windows\CurrentVersion', False) and
+    if MyReg.OpenKeyReadOnly(sHiveLoc + '\Microsoft\Windows\CurrentVersion') and
       MyReg.ValueExists('RegisteredOwner') and
       MyReg.ValueExists('RegisteredOrganization') then
     begin
@@ -2813,24 +2849,24 @@ var
   i, k : integer;
   newheader, aktsection: string;
 begin
-	seclist := TStringlist.Create;
-	strlist := TStringlist.Create;
-	myINI := TMemIniFile.Create(FileName);
-	myINI.readsections(seclist);
-	for i := 0 to seclist.count - 1 do
-	begin
-		aktsection := seclist[i];
-		myINI.ReadSectionValues(aktsection,strlist);
-		newheader := strlist.Values['Uninstall Product ID'];
-		if newheader <> '' then
-			for k := 0 to strlist.count-1 do
-				myINI.WriteString(newheader,strlist.Names[k],strlist.ValueFromIndex[k]);
-		myINI.EraseSection(seclist[i]);
-	end;
-	seclist.free;
-	strlist.free;
-	myINI.UpdateFile;
-	myINI.Free;
+  seclist := TStringlist.Create;
+  strlist := TStringlist.Create;
+  myINI := TMemIniFile.Create(FileName);
+  myINI.readsections(seclist);
+  for i := 0 to seclist.count - 1 do
+  begin
+    aktsection := seclist[i];
+    myINI.ReadSectionValues(aktsection,strlist);
+    newheader := strlist.Values['Uninstall Product ID'];
+    if newheader <> '' then
+      for k := 0 to strlist.count-1 do
+        myINI.WriteString(newheader,strlist.Names[k],strlist.ValueFromIndex[k]);
+    myINI.EraseSection(seclist[i]);
+  end;
+  seclist.free;
+  strlist.free;
+  myINI.UpdateFile;
+  myINI.Free;
 end;
 
 procedure TfrmMain.ConvertSaveFormat;
@@ -2873,21 +2909,21 @@ begin
       sDelimCSV + '"Key/Serial"' + sDelimCSV + '"Other 1"' + sDelimCSV +
       '"Other 2"' + sDelimCSV + '"Other 3"');
     for j := 0 to Memo3.Lines.Count do
-			if Memo3.Lines[j] <> '' then
-				Memo2.Lines.Add('"' + sCurrentUserName + '"' + sDelimCSV + '"' +
-					sPCName + '"' + sDelimCSV + '"' + DateToStr(Now) + '"' + sDelimCSV +
-					'"' + Memo3.Lines[j] + '"');
-	end;
-
-	if SaveDialog1.FilterIndex = 3 then  // INI Save Format
-	begin
-		for i := 0 to Memo2.Lines.Count-1 do
-		begin
-			Memo2.Lines[i] := StringReplace(Memo2.Lines[i],':','=',[]);
-			if 0 = pos('=',Memo2.Lines[i]) then
-			Memo2.Lines[i] := '[' + Memo2.Lines[i] + ']';
-		end;
-	end;
+      if Memo3.Lines[j] <> '' then
+        Memo2.Lines.Add('"' + sCurrentUserName + '"' + sDelimCSV + '"' +
+          sPCName + '"' + sDelimCSV + '"' + DateToStr(Now) + '"' + sDelimCSV +
+          '"' + Memo3.Lines[j] + '"');
+  end;
+
+  if SaveDialog1.FilterIndex = 3 then  // INI Save Format
+  begin
+    for i := 0 to Memo2.Lines.Count-1 do
+    begin
+      Memo2.Lines[i] := StringReplace(Memo2.Lines[i],':','=',[]);
+      if 0 = pos('=',Memo2.Lines[i]) then
+      Memo2.Lines[i] := '[' + Memo2.Lines[i] + ']';
+    end;
+  end;
 
   if SaveDialog1.FilterIndex = 4 then  // HTML Save Format
   begin
@@ -2951,23 +2987,23 @@ var
 begin
   i := (frmMain.Width div 100) * 50;
   StatusBar1.Panels.Items[0].Width := i;
-	i := (i div 100) * 50;
-	StatusBar1.Panels.Items[1].Width := i;
+  i := (i div 100) * 50;
+  StatusBar1.Panels.Items[1].Width := i;
   StatusBar1.Panels.Items[2].Width := i;
 end;
 
 function TfrmMain.StripTags(const sText: string): string;
-	// We want to strip 'Product ID: ', 'CD Key: ' etc. from csv output
-	// We want to strip 'Product ID: ', 'License key: ' etc. from csv output
+  // We want to strip 'Product ID: ', 'CD Key: ' etc. from csv output
+  // We want to strip 'Product ID: ', 'License key: ' etc. from csv output
 var
   sSourceTest: string;
 begin
   sSourceTest := sText;
   if LeftStr(sSourceTest, 12) = 'Product ID: ' then
     Delete(sSourceTest, 1, 12)
-	else if LeftStr(sSourceTest, 8) = 'License key: ' then
+  else if LeftStr(sSourceTest, 8) = 'License key: ' then //TODO: License key two times??
     Delete(sSourceTest, 1, 8)
-  else if LeftStr(sSourceTest, 13) = 'License Key: ' then
+  else if LeftStr(sSourceTest, 13) = 'License Key: ' then //TODO: License key two times??
     Delete(sSourceTest, 1, 13)
   else if LeftStr(sSourceTest, 18) = 'Registered Owner: ' then
     Delete(sSourceTest, 1, 18)
(sorry, der Patch ist unnötig groß weil ich auch die unüblichen 2-char-tabs ersetzt habe)

Wie auch immer... da es ein kostenpflichtiges Lizenzmodul gibt, kann ich mir vorstellen, dass hier an einem funktionierenden keyfinder.exe wohl kaum noch Interesse bestehen dürfte...
Antworten