Advertisement
Guest User

lvsb.dll

a guest
Apr 5th, 2015
458
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 68.59 KB | None | 0 0
  1. library lvsb;
  2.  
  3. uses
  4.   SysUtils, Windows, Dialogs, Classes;
  5.  
  6. {$R *.res}
  7.  
  8. var
  9.  
  10. //jump over LIsb check
  11. PatchReload_First : Array[0..0] of byte = ($EB);
  12.  
  13. PatchReload_Second : Array[0..130] of byte =
  14. ($FF,$75,$24, //push [ebp+24]
  15. $FF,$75,$20, //push [ebp+20]
  16. $FF,$75,$1C, //push [ebp+1C]
  17. $50, //push EAX
  18. $FF,$15,$90,$90,$90,$90, //call @ProcessExternal
  19. $89,$C2, //mov EDX,EAX
  20. $58, //pop EAX
  21. $83,$C4,$0C, //add ESP, 0C
  22. $85,$D2, //test EDX,EDX
  23. $74,$7C, //je short 163811B
  24. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  25. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  26. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  27. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  28. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  29. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  30. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  31. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  32. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  33. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  34. $90,$90,$90,$90,$90
  35. );
  36. PatchReload_ForSave : Array[0..73] of byte =
  37. ($FF,$75,$18, //push [ebp+18] (arg5)
  38. $FF,$75,$14, //push [ebp+14] (arg4)
  39. $FF,$75,$10, //push [ebp+10] (arg3)
  40. $FF,$75,$0C, //push [ebp+0C] (arg2)
  41. $FF,$75,$08, //push [ebp+08] (arg1)
  42. $FF,$15,$90,$90,$90,$90, //call @SaveCIN
  43. $89,$C2, //mov EDX,EAX
  44. $83,$C4,$14, //add ESP, 14
  45. $85,$D2, //test EDX,EDX
  46. $75,$31, //jne short 103bbe2
  47. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  48. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  49. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  50. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  51. $90,$90,$90,$90
  52. );
  53. PatchReload_Second_RTE : Array[0..101] of byte =
  54. ($FF,$75,$24, //push [ebp+24]
  55. $FF,$75,$20, //push [ebp+20]
  56. $FF,$75,$1C, //push [ebp+1C]
  57. $50, //push EAX
  58. $FF,$15,$90,$90,$90,$90, //call @ProcessExternal
  59. $89,$C2, //mov EDX,EAX
  60. $58, //pop EAX
  61. $83,$C4,$0C, //add ESP, 0C
  62. $85,$D2, //test EDX,EDX
  63. $75,$C9, //jne short UP
  64. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  65. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  66. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  67. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  68. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  69. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  70. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  71. $90,$90,$90,$90,$90,$90
  72. );
  73. PatchReload_ForPurge : Array[0..24] of byte =
  74. ($51, //push ECX (arg2)
  75. $8B,$10, //mov EDX, dword ptr ds:[EAX]
  76. $8B,$C8, //mov ECX, EAX
  77. $8B,$42,$1C, //mov EAX, dword ptr ds:[EDX+1C]
  78. $FF,$D0, //call EAX
  79. $50, //push EAX (arg1)
  80. //$8B,$8E,$C0,$00,$00,$00, //mov ECX,dword ptr ds:[ESI+C0]
  81. //$8B,$8D,$A0,$00,$00,$00, //mov ECX,dword ptr ds:[EBP+A0]
  82. //$51, //push ECX (arg1)
  83. $FF,$15,$90,$90,$90,$90, //call @PurgeCIN
  84. //$83,$C4,$10, //add ESP,10
  85. $83,$C4,$0C, //add ESP,C
  86. $5E, //pop ESI
  87. $8B,$E5, //mov ESP, EBP
  88. $5D, //pop EBP
  89. $C3 //retn
  90. {
  91. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  92. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  93. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  94. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  95. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  96. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  97. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  98. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  99. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  100. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  101. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  102. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  103. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  104. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  105. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  106. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  107. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  108. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  109. $90,$90,$90,$90   }
  110. );
  111. PatchReload_ForPurge2 : Array[0..3] of byte =
  112. ($90,$90,$90,$90); //jne LV.01637C4B insted of LV.01637CF8
  113. {
  114. PatchReload_ForPurge_RTE : Array[0..181] of byte = //181
  115. ($51, //push ECX (arg2)
  116. $8B,$10, //mov EDX, dword ptr ds:[EAX]
  117. $8B,$C8, //mov ECX, EAX
  118. $8B,$42,$1C, //mov EAX, dword ptr ds:[EDX+1C]
  119. $FF,$D0, //call EAX
  120. $50, //push EAX (arg1)
  121. //$8B,$8E,$C0,$00,$00,$00, //mov ECX,dword ptr ds:[ESI+C0]
  122. //$8B,$8D,$A0,$00,$00,$00, //mov ECX,dword ptr ds:[EBP+A0]
  123. //$51, //push ECX (arg1)
  124. $FF,$15,$90,$90,$90,$90, //call @PurgeCIN
  125. //$83,$C4,$10, //add ESP,10
  126. $83,$C4,$0C, //add ESP,C
  127. //$5E, //pop ESI
  128. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  129. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  130. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  131. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  132. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  133. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  134. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  135. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  136. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  137. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  138. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  139. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  140. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  141. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  142. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  143. $90,$90,$90,$90,$90,$90,$90,$90,$90,$90,
  144. $90,$90
  145. );         }
  146. //Backup arrays
  147. Backup_First : Array[0..0] of byte;
  148. Backup_Second : Array[0..130] of byte;
  149. Backup_ForSave : Array[0..73] of byte;
  150. Backup_Second_RTE : Array[0..101] of byte;
  151. //Backup_ForPurge : Array[0..203] of byte;
  152. Backup_ForPurge : Array[0..24] of byte;
  153. Backup_ForPurge2 : Array[0..3] of byte;
  154. //Backup_ForPurge_RTE : Array[0..181] of byte;
  155. ProcessExternalAddress, SaveCINAddress, PurgeCINAddress: pointer;
  156. LVInstance, LVRTTable, mgcore: cardinal;
  157. DbgPrintf: function (str: pchar): integer; cdecl;
  158. DbgPrintf_Format: function (format: pchar; var1: cardinal): integer; cdecl;
  159. DbgPrintf_PStr: function (format: pchar; var1: PShortString): integer; cdecl;
  160. MoveBlock: procedure (source: pointer; dest: pointer; size: integer); cdecl;
  161. SPrintf: function(dest: pchar; format: pchar; var1: cardinal): integer; cdecl;
  162. //AZCheckPtr: function(p: pointer): integer; cdecl;
  163. DSGetHandleSize: function(Handle: pointer): integer; cdecl;
  164. DSNewPtr: function(size: integer): pointer; cdecl;
  165. DSNewPClr: function(size: integer): pointer; cdecl;
  166. DSDisposePtr: function(p: pointer): integer; cdecl;
  167. DSCheckPtr: function(p: pointer): integer; cdecl;
  168. DSNewHandle: function(size: integer): pointer; cdecl;
  169. DSDisposeHandle: function(h: pointer): integer; cdecl;
  170. DSRecoverHandle: function(p: pointer): pointer; cdecl;
  171. RGetNamed: function(ResFileHandle: cardinal; ResType: integer;
  172.                     ResName: PShortString; BinDataHandle: pointer): integer; cdecl;
  173. RGet: function(ResFileHandle: cardinal; ResType: integer;
  174.                Id: integer; BinDataHandle: pointer): integer; cdecl;
  175. RGetInfo: function(BinDataHandle: pointer; Id, ResType: pcardinal;
  176.                    ResName: PShortString): integer; cdecl;
  177. ROpenFile: function(path: cardinal;
  178.                     OpenMode: integer; //0-openReadWrite, 1-openReadOnly
  179.                     PResFileHandle: pointer; PResType,
  180.                     FileCreator: PCardinal): integer; cdecl;
  181. RCloseFile: function(ResFileHandle: cardinal): integer; cdecl;
  182. RRelease: function(BinDataHandle: pointer): integer; cdecl;
  183. RDetach: function(BinDataHandle: pointer): integer; cdecl;
  184. RAdd: function(BinDataHandle: pointer; ResFileHandle: cardinal; ResType,
  185.                ResIndex: integer; ResName: PShortString): integer; cdecl;
  186. RFReadWrite_Remove: function(ResType: integer; Id: integer): integer; stdcall;
  187. RFReadWrite_LowLevelResFile: function: cardinal; stdcall;
  188. LVResFile_RGet: function(ResType: integer; Id: integer;
  189.                          class_Resource_ptr: pcardinal): integer; stdcall;
  190. LVResFile_RRemove: function(class_Resource: cardinal): integer; stdcall;
  191. LVResource_RGetInfo: function(Id, ResType: pcardinal;
  192.                               ResName: PShortString): integer; stdcall;
  193. FEmptyPath: function(path: cardinal): cardinal; cdecl;
  194. FFlattenPath: function(path: cardinal; str_buffer: pointer): integer; cdecl;
  195. FUnFlattenPath: function(str_buffer: pointer; path_ptr: pointer): integer; cdecl;
  196. PathIsPseudoPath: function(path: cardinal; x: pointer): longbool; cdecl;
  197. PseudoPathToPath: function(path: cardinal; x: pointer): integer; cdecl;
  198. FDestroyPath: procedure(path_ptr: pointer); cdecl;
  199. FTextToPath: function(Str: pointer; StrLength: integer;
  200.                       path_ptr: pointer): integer; cdecl;
  201. FNamePtr: function(path: cardinal; name: PShortString): integer; cdecl;
  202. FAddPath: function(BasePath, RelPath, NewPath: cardinal): integer; cdecl;
  203. FIsEmptyPath: function(path: cardinal): longbool; cdecl;
  204. FDirName: function(Path, Dir: cardinal): integer; cdecl;
  205. FPathCpy: function(DestPath, SrcPath: cardinal): integer; cdecl;
  206. OneButtonAlert: function(StrType: integer; MsgText, ButtonText: PShortString;
  207.                          X, Y: integer; Caption: PShortString): PCardinal; cdecl;
  208. ExtFileDialog: function(Caption: PShortString; Init_Res_Path: Cardinal;
  209.                         FileName: PShortString; CustomFilter: integer;
  210.                         WindowType: integer; LVFilter: integer;
  211.                         NotUsed: integer): integer; cdecl;
  212. RevBL: procedure(NumberPtr: Pointer); cdecl;
  213. gLVRTVersion: pchar;
  214. GlobalSubNames, GlobalLVSBs, GlobalParents, GlobalSubPaths, GlobalOffsets: TStringList;
  215. RTE: boolean;
  216. DbgFilePath: string;
  217. DbgFile: TextFile;
  218. PatchAddress_First, PatchAddress_Second, PatchAddress_ForSave,
  219. PatchAddress_ForPurge, PatchAddress_ForPurge2: cardinal;
  220.  
  221. Function WriteBytes(pAddress: Pointer; Bytes: Array of Byte): Boolean;
  222. var
  223.   OldProtect, DummyProtect: DWord;
  224. begin
  225.   if VirtualProtect(pAddress, SizeOf(Bytes), PAGE_EXECUTE_READWRITE, @OldProtect) then
  226.    begin
  227.     Move(Bytes, pAddress^, Length(Bytes));
  228.     VirtualProtect(pAddress, SizeOf(Bytes), OldProtect, @DummyProtect);
  229.     Result := True
  230.    end
  231.    else
  232.     Result := False;
  233. end;
  234.  
  235. Function WriteBytesWithBackup(pAddress: Pointer; Bytes: Array of Byte;
  236.                               var Backup: Array of Byte): Boolean;
  237. var
  238.   OldProtect, DummyProtect: DWord;
  239. begin
  240.   if VirtualProtect(pAddress, SizeOf(Bytes), PAGE_EXECUTE_READWRITE, @OldProtect) then
  241.    begin
  242.     Move(pAddress^, Backup, Length(Backup));
  243.     Move(Bytes, pAddress^, Length(Bytes));
  244.     VirtualProtect(pAddress, SizeOf(Bytes), OldProtect, @DummyProtect);
  245.     Result := True
  246.    end
  247.    else
  248.     Result := False;
  249. end;
  250.  
  251. function NumToChars(Value: Cardinal): String;
  252. var
  253.   C1, C2, C3, C4: Char;
  254. begin
  255.   C1 := PChar(@Value)^;
  256.   C2 := PChar(Cardinal(@Value) + 1)^;
  257.   C3 := PChar(Cardinal(@Value) + 2)^;
  258.   C4 := PChar(Cardinal(@Value) + 3)^;
  259.   if C1<>#0 then Result := C1;
  260.   if C2<>#0 then Result := Result+C2;
  261.   if C3<>#0 then Result := Result+C3;
  262.   if C4<>#0 then Result := Result+C4;
  263. end;
  264.  
  265. function CharsToNum(Value: String): Cardinal;
  266. begin
  267. case Length(Value) of
  268. 0: Result := 0;
  269. 1: Result := PByte(@Value[1])^;
  270. 2: Result := PWord(@Value[1])^;
  271. else
  272. Result := PCardinal(@Value[1])^;
  273. end;
  274. end;
  275.  
  276. function UnloadCIN(LVSBHead: cardinal): integer;
  277. var CINModuleAddress: cardinal;
  278.     ModuleName: pchar;
  279. begin
  280. UnloadCIN:=0;
  281. if (LVSBHead<>0) then begin
  282. Try
  283. CINModuleAddress := PCardinal(LVSBHead + $1C)^;
  284. Except on E:Exception do
  285. CINModuleAddress := 0;
  286. End;
  287.  
  288. if (CINModuleAddress<>0) then begin
  289. GetMem(ModuleName, $104);
  290. GetModuleFileName(CINModuleAddress, ModuleName, $104);
  291.  
  292. if FreeLibrary(CINModuleAddress) then
  293.  DeleteFile(ModuleName)
  294. else
  295.  UnloadCIN:=GetLastError;
  296.  
  297. FreeMem(ModuleName);
  298. end
  299. else DSDisposePtr(Ptr(LVSBHead));
  300. end;
  301. end;
  302.  
  303. //CIN Lists procedures
  304. procedure SortList(var List: TStringList);
  305. var i, n: integer;
  306.     b: boolean;
  307.     p: string;
  308. begin
  309. n := List.Count;
  310. if (n < 2) then exit;
  311. repeat
  312.   b := false;
  313.   Dec(n);
  314.   if (n > 0) then
  315.   for i := 0 to n-1 do
  316.    if StrToInt(List[i]) > StrToInt(List[i+1]) then begin
  317.      p := List[i];
  318.      List[i] := List[i+1];
  319.      List[i+1] := p;
  320.      b := true;
  321.     end;
  322. until not b;
  323. end;
  324.  
  325. procedure ListCINTree(var TempList: TStringList; CIN_Name: string);
  326. var i: integer;
  327. begin
  328. for i:=0 to GlobalParents.Count-1 do
  329.  if (GlobalParents.Strings[i]=CIN_Name) then begin
  330.   TempList.Add(GlobalSubNames[i]);
  331.   ListCINTree(TempList, GlobalSubNames[i]);
  332.  end;
  333. //you'd remove duplicates from TempList on your own!
  334. end;
  335.  
  336. procedure RemoveDuplicates(var List: TStringList);
  337. var i: integer;
  338.     TmpList: TStringList;
  339. begin
  340. TmpList := TStringList.Create;
  341. TmpList.CaseSensitive := false;
  342. for i:=0 to List.Count-1 do
  343.  if TmpList.IndexOf(List[i])=-1 then TmpList.Add(List[i]);
  344. List.Clear;
  345. List.AddStrings(TmpList);
  346. TmpList.Free;
  347. end;
  348.  
  349. //define top level parent CINs by subroutine name
  350. procedure DetermineMasterCIN(var Masters: TStringList; SubName: String);
  351. var i, j: integer;
  352.     SubNames, SubParents: TStringList;
  353. begin
  354. If (GlobalSubNames.IndexOf(SubName)>-1) or (GlobalParents.IndexOf(SubName)>-1) Then Begin
  355. SubNames := TStringList.Create;
  356. SubNames.CaseSensitive := false;
  357. SubParents := TStringList.Create;
  358. SubParents.CaseSensitive := false;
  359. SubNames.Add(SubName);
  360. Repeat
  361. SubParents.Clear;
  362. for i:=0 to SubNames.Count-1 do
  363.  for j:=0 to GlobalSubNames.Count-1 do
  364.   if GlobalSubNames[j]=SubNames[i] then
  365.    SubParents.Add(GlobalParents[j]);
  366.  
  367. if (SubParents.Count>0) then begin
  368.  
  369. for i:=0 to SubNames.Count-1 do
  370.  //keep master CIN names from erase
  371.  if (GlobalSubNames.IndexOf(SubNames[i])=-1) then SubParents.Add(SubNames[i]);
  372. SubNames.Clear;
  373. SubNames.AddStrings(SubParents);
  374. end;
  375. Until (SubParents.Count = 0);
  376.  
  377. SubParents.Free;
  378. RemoveDuplicates(SubNames);
  379.  
  380. Masters.AddStrings(SubNames);
  381. SubNames.Free;
  382. End;
  383. end;
  384.  
  385. procedure DeleteESFromLists(SubNames: TStringList; MasterCIN: string);
  386. var i,j: integer;
  387.     indexes, Masters: TStringList;
  388. begin
  389. indexes := TStringList.Create;
  390. indexes.CaseSensitive := false;
  391. Masters := TStringList.Create;
  392. Masters.CaseSensitive := false;
  393. for i:=0 to SubNames.Count-1 do
  394.  for j:=0 to GlobalSubNames.Count-1 do
  395.   if (GlobalSubNames[j]=SubNames[i]) then begin
  396.    Masters.Clear;
  397.    DetermineMasterCIN(Masters,GlobalParents[j]);
  398.    if (GlobalParents[j]=MasterCIN) or (Masters.IndexOf(MasterCIN)>-1) then begin
  399.     { this condition can delete subs from list only by master name or
  400.       by sub's parent name.
  401.       it can not delete subs by its intermediate parent, e.g. we have
  402.       sub <- parent :
  403.       1 <- MC1
  404.       2 <- 1
  405.       3 <- 2
  406.       so, DeleteESFromLists('3', 'MC1') will delete "3 <- 2" string (by master),
  407.       DeleteESFromLists('3', '2') will delete "3 <- 2" string (by parent)
  408.       and DeleteESFromLists('3', '1') does nothing! }
  409.     indexes.Add(IntToStr(j));
  410.    end;
  411.   end;
  412. Masters.Free;
  413. RemoveDuplicates(indexes);
  414. SortList(indexes);
  415.  
  416. //erase subroutine from all lists
  417. for i:=indexes.Count-1 downto 0 do begin
  418. GlobalLVSBs.Delete(StrToInt(indexes[i]));
  419. GlobalSubNames.Delete(StrToInt(indexes[i]));
  420. GlobalParents.Delete(StrToInt(indexes[i]));
  421. GlobalSubPaths.Delete(StrToInt(indexes[i]));
  422. GlobalOffsets.Delete(StrToInt(indexes[i]));
  423. end;
  424. indexes.Free;
  425. end;
  426.  
  427. procedure FreeCINTree(CIN_Name: string);
  428. var i,j: integer;
  429.     TempList, Masters: TStringList;
  430. begin
  431. TempList := TStringList.Create;
  432. TempList.CaseSensitive := false;
  433. Masters := TStringList.Create;
  434. Masters.CaseSensitive := false;
  435. ListCINTree(TempList, CIN_Name); //get all child subroutines of current CIN
  436. RemoveDuplicates(TempList);
  437. for i:=0 to TempList.Count-1 do begin
  438.  Masters.Clear;
  439.  DetermineMasterCIN(Masters, TempList[i]);
  440.  if (Masters.Count=1) then begin
  441.   j:=GlobalSubNames.IndexOf(TempList[i]);
  442.   if (j<>-1) then begin
  443.    //DSDisposePtr(Ptr(StrToInt(GlobalLVSBs[j])));
  444.    UnloadCIN(StrToInt(GlobalLVSBs[j]));
  445.   end;
  446.  end; //end to if (Masters.Count=1) then begin
  447.  //DeleteESFromLists(TempList[i], CIN_Name);
  448. end; //end to for
  449.  
  450. DeleteESFromLists(TempList, CIN_Name);
  451. Masters.Free;
  452. TempList.Free;
  453. end;
  454.  
  455. //End of CIN Lists procedures
  456.  
  457. procedure LVMessage(Text: ShortString);
  458. begin
  459. OneButtonAlert($35, @Text, nil, $7FFF, $7FFF, nil);
  460. end;
  461.  
  462. function LVDialog(Caption: ShortString; Init_Res_Path: Cardinal;
  463.                   WindowType: integer; LVFilter: integer): integer;
  464. begin
  465. Result := ExtFileDialog(@Caption, Init_Res_Path, nil, 0,
  466.                         WindowType, LVFilter, 0);
  467. end;
  468.  
  469. procedure Dbg(fmt: string; str: string);
  470. var DbgStr: ShortString;
  471. begin
  472. DbgStr:=str;
  473. DbgPrintf_PStr(pchar(fmt), @DbgStr);
  474. end;
  475.  
  476. procedure DumpToFile(const FileName: string; DataPtr: pointer; Length: integer);
  477. var
  478.   Stream: TFileStream;
  479. begin
  480.   Stream:= TFileStream.Create(FileName, fmCreate);
  481.   try
  482.     Stream.WriteBuffer(DataPtr^, Length);
  483.   finally
  484.     Stream.Free;
  485.   end;
  486. end;
  487.  
  488. function LVVersion: integer;
  489. var tmp: string;
  490.     version: integer;
  491. begin
  492. tmp:=Copy(gLVRTVersion, 1, 2);
  493. if TryStrToInt(tmp, version) then
  494.  LVVersion:=version
  495.  else LVVersion:=0;
  496. end;
  497.  
  498. function LoadCINFromRsrc(BinLVSBRsrc: PCardinal; RsrcName: string): cardinal;
  499. var FileHandle, HandleSize, LibHandle: integer;
  500.     TempPath, TempFileName: string;
  501.     NumOfBytes, LVSBHeader: cardinal;
  502.     GetLVSBHeader: function: Cardinal; cdecl;
  503.     SetLVRTModule: procedure(Module: Cardinal); cdecl;
  504.     Off1, Off2, Off3, Off4, Off5, CINLength, FullLength,
  505.     Local1, Local2, TmpAddr: Cardinal;
  506.     NewCINPtr: pointer;
  507.     CINVer, OldProtect: Cardinal;
  508. begin
  509. Result := 0;
  510. If (PWord(BinLVSBRsrc^)^=CharsToNum('MQ')) Then Begin
  511. //CIN is in *.REX format (Phar Lap relocatable executable) (WATCOM compiler)
  512. Off1 := PWord(BinLVSBRsrc^ + $6)^; //e.g., 1D
  513. Off2 := PWord(BinLVSBRsrc^ + $A)^ shl $C; //e.g., 1 -> 1000
  514. Off3 := PWord(BinLVSBRsrc^ + $8)^ shl $4; //REX header size (e.g., A -> A0)
  515. Off4 := PWord(BinLVSBRsrc^ + $2)^; //e.g., C8
  516. CINLength := PWord(BinLVSBRsrc^ + $4)^ shl $9; //C -> 1800
  517. if (Off4<>0) then CINLength := Off4 + CINLength - $200; //C8 + 1800 - 200 = 16C8
  518. FullLength := CINLength - Off3 + Off2; //16C8 - A0 + 1000 = 2628
  519. NewCINPtr := DSNewPClr(FullLength);
  520. if (Cardinal(NewCINPtr)=0) then Exit;
  521. Move(PCardinal(BinLVSBRsrc^ + Off3)^, NewCINPtr^, FullLength - Off2);
  522. Off5 := PWord(BinLVSBRsrc^ + $18)^; //e.g., 1E
  523. Local1 := Off5 + BinLVSBRsrc^;
  524. Local2 := Off1; //1D
  525.  
  526. if (Off1<>0) then
  527.  while (Local2 > 0) do begin
  528.   TmpAddr := (PCardinal(Local1)^ and $7FFFFFFF) + Cardinal(NewCINPtr);
  529.   if (TmpAddr) >= (FullLength + Cardinal(NewCINPtr)) then begin
  530.    DbgPrintf('While loop error');
  531.    DSDisposePtr(NewCINPtr);
  532.    Exit;
  533.   end;
  534.   if (PCardinal(Local1)^ and $80000000)=0 then //address in range [0..2147483647 (7FFFFFFF)]
  535.    PWord(TmpAddr)^ := PWord(TmpAddr)^ + Word(NewCINPtr)
  536.    else PCardinal(TmpAddr)^ := PCardinal(TmpAddr)^ + Cardinal(NewCINPtr);
  537.   Inc(Local1, 4);
  538.   Dec(Local2);
  539.  end;
  540.  
  541. RevBL(Ptr(Cardinal(NewCINPtr) + $C)); //reverse bytes in an integer: e.g., 00|00|00|04 -> 04|00|00|00
  542. CINVer := PCardinal(Cardinal(NewCINPtr) + $C)^;
  543. DbgPrintf_Format('CIN version = %x',CINVer);
  544. if (CINver<2) then begin
  545.  LVMessage('The "'+RsrcName+'" CIN is compiled with an old version of the compiler. Please recompile.');
  546.  DSDisposePtr(NewCINPtr);
  547.  Exit;
  548. end;
  549. if (CINver>4) then begin
  550.  LVMessage('The "'+RsrcName+'" CIN was built with a newer version of cintools and could not be loaded.');
  551.  DSDisposePtr(NewCINPtr);
  552.  Exit;
  553. end;
  554.  
  555. local1 := PCardinal(BinLVSBRsrc^ + $14)^;
  556. if (CINVer<4) then begin
  557.  PCardinal(Cardinal(NewCINPtr) + $10)^ := local1 + Cardinal(NewCINPtr);
  558.  if (local1=0) then begin
  559.   if (PByte(NewCINPtr)^<>$E9) then begin
  560.    DbgPrintf('E9 Error!');
  561.    DSDisposePtr(NewCINPtr);
  562.    Exit;
  563.   end
  564.   else
  565.    PCardinal(Cardinal(NewCINPtr) + $10)^ := Cardinal(NewCINPtr) + PCardinal(Cardinal(NewCINPtr) + $1)^ + 5;
  566.  end;
  567.  PCardinal(NewCINPtr)^ := 0;
  568.  PCardinal(Cardinal(NewCINPtr) + $4)^ := 0;
  569. end;
  570. PCardinal(Cardinal(NewCINPtr) + $18)^ := 0;
  571. PCardinal(Cardinal(NewCINPtr) + $1C)^ := 0;
  572. PCardinal(Cardinal(NewCINPtr) + $20)^ := 0;
  573. PCardinal(Cardinal(NewCINPtr) + $24)^ := LVRTTable;
  574. LVSBHeader := local1 + Cardinal(NewCINPtr);
  575. PCardinal(Cardinal(NewCINPtr) + $28)^ := LVSBHeader;
  576.  
  577. if (not VirtualProtect(NewCINPtr, FullLength, PAGE_EXECUTE_READWRITE, @OldProtect)) then begin
  578.  DSDisposePtr(NewCINPtr);
  579.  Exit;
  580. end;
  581. //DumpToFile('C:\'+RsrcName+'.bin',NewCINPtr,FullLength - Off2);
  582. //Showmessage(Format('LVSBHeader = 0x%x',[LVSBHeader]));
  583. Result := LVSBHeader;
  584. End
  585. Else Begin //CIN is standard executable/DLL (MZ)
  586. SetLength(TempPath, 260);
  587. if GetTempPath(260, @TempPath[1])>0 then begin
  588.  SetLength(TempFileName, MAX_PATH);
  589.  if GetTempFileName(@TempPath[1], 'lvsb', 0, @TempFileName[1])>0 then begin
  590.   FileHandle:=CreateFile(@TempFileName[1], GENERIC_READ or GENERIC_WRITE,
  591.                          0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or
  592.                          FILE_FLAG_WRITE_THROUGH, 0);
  593.   if (FileHandle<>-1) then begin
  594.    HandleSize := DSGetHandleSize(BinLVSBRsrc);
  595.    if WriteFile(FileHandle, PCardinal(BinLVSBRsrc^)^, HandleSize, NumOfBytes, nil) then begin
  596.     FlushFileBuffers(FileHandle);
  597.     CloseHandle(FileHandle);
  598.     SetErrorMode(0);
  599.     LibHandle:=LoadLibrary(@TempFileName[1]);
  600.     SetErrorMode(SEM_NOOPENFILEERRORBOX);
  601.     if (LibHandle>0) then begin
  602.      GetLVSBHeader := GetProcAddress(LibHandle, 'GetLVSBHeader');
  603.      if Assigned(GetLVSBHeader) then begin
  604.       LVSBHeader:=GetLVSBHeader;
  605.       if (LVSBHeader>0) then
  606.        if PCardinal(LVSBHeader+$C)^<=4 then begin
  607.         SetLVRTModule := GetProcAddress(LibHandle, 'SetLVRTModule');
  608.         if Assigned(SetLVRTModule) then SetLVRTModule(LVInstance);
  609.         //GlobalSubNames.Add(RsrcName);
  610.         //GlobalLVSBs.Add(IntToStr(LVSBHeader));
  611.         PCardinal(LVSBHeader+$18)^:=0;
  612.         PCardinal(LVSBHeader+$1C)^:=LibHandle;
  613.         PCardinal(LVSBHeader+$20)^:=0;
  614.         PCardinal(LVSBHeader+$24)^:=LVRTTable;
  615.         PCardinal(LVSBHeader+$28)^:=LVSBHeader;
  616.         Result := LVSBHeader;
  617.        end //end to if PCardinal(LVSBHeader+$C)^<=4
  618.        else begin
  619.         FreeLibrary(LibHandle);
  620.         DeleteFile(@TempFileName[1]);
  621.         LVMessage('The "'+RsrcName+'" CIN was built with a newer version of cintools and could not be loaded.');
  622.        end;
  623.      end //end to if Assigned(GetLVSBHeader)
  624.      else begin
  625.       FreeLibrary(LibHandle);
  626.       DeleteFile(@TempFileName[1]);
  627.      end;
  628.     end //if (LibHandle>0)
  629.     else DeleteFile(@TempFileName[1]);
  630.    end //end to if WriteFile
  631.    else CloseHandle(FileHandle);
  632.   end //end to if (FileHandle<>-1)
  633.   else
  634.    LVMessage('There was an error trying to create a temporary file. Please verify that your TEMP variable is ok.');
  635.   end //end to if GetTempFileName
  636.   else
  637.    LVMessage('There was an error trying to create a temporary file. Please verify that your TEMP variable is ok.');
  638.  end //end to if GetTempPath
  639.  else
  640.   LVMessage('There was an error trying to create a temporary file. Please verify that your TEMP variable is ok.');
  641. End;
  642. end;
  643.  
  644. function RecursiveCINLoad(LVSBHead, ResHandle, LSB_VI_Path: cardinal;
  645.          ResNamePtr: PShortString): longbool;
  646. var TmpPath, TmpPath2, extLVSBHead,
  647.     TempResource, TempResType, TempResCreator, HandleSize: Cardinal;
  648.     tmp1, tmp2, BinLVSBRsrc, BinLIsbRsrc: PCardinal;
  649.     LSB_VI_PathStr, LIsb, TempStr, RawPart: string;
  650.     TempPStr: ShortString;
  651.     i, j, Return, index, NumBytes: integer;
  652.     SubNames, SubPaths, SubOffsets{, LVSBs}: TStringList;
  653.     Offset: array[0..3] of byte;
  654.     Exists: boolean;
  655. begin
  656. Result := True;
  657. ////////////
  658. //Return:=RGetNamed(Resource_class_handle, $6273494C, Res_Name_Ptr, tmp1);
  659. Return:=RGetNamed(ResHandle, CharsToNum('LIsb'), ResNamePtr, @tmp1);
  660. If RTE then Writeln(DbgFile,'RGetNamed returned '+IntToStr(Return)) else
  661.  DbgPrintf_Format(pchar('RGetNamed returned %d'), Return);
  662. if (Return <> 0) then begin
  663.  if (Return<>15) then Result:=False; //no LIsb in resource
  664. Exit;
  665. end;
  666. Return:=RDetach(tmp1);
  667. If RTE then Writeln(DbgFile,'RDetach returned '+IntToStr(Return)) else
  668.  DbgPrintf_Format(pchar('RDetach returned %d'), Return);
  669. if (Return <> 0) then begin
  670. Result:=False;
  671. Exit;
  672. end;
  673. HandleSize:=DSGetHandleSize(tmp1);
  674. If RTE then Writeln(DbgFile,Format('Handle size = 0x%x',[Return])) else
  675.  DbgPrintf_Format(pchar('Handle size = 0x%x'), HandleSize);
  676. tmp2 := PCardinal(tmp1^); //get pointer from handle
  677. SetLength(LIsb, HandleSize);
  678. Move(tmp2^, LIsb[1], Length(LIsb) * SizeOf(LIsb[1]));
  679. If RTE then Writeln(DbgFile,'LIsb = '+LIsb) else
  680.  Dbg('LIsb = %p', LIsb);
  681.  
  682. //If RTE then Writeln(DbgFile,Format('Handle size = 0x%x',[Return])) else
  683. DbgPrintf_Format(pchar('LSB (vi) Path is %z'), LSB_VI_Path);
  684. //convert Path to Delphi string
  685. NumBytes := SPrintf(nil, '%z', LSB_VI_Path);
  686. SetLength(TempStr, NumBytes);
  687. SPrintf(@TempStr[1], '%z', LSB_VI_Path);
  688. //end of convert
  689. LSB_VI_PathStr:=ExtractFilePath(TempStr); //путь к файлу, заканчивающийся "\"
  690.  
  691. //parsing SubNames, SubPaths and SubOffsets
  692.  
  693. SubNames:=TStringList.Create;
  694. SubNames.CaseSensitive := false;
  695. SubPaths:=TStringList.Create;
  696. SubPaths.CaseSensitive := false;
  697. SubOffsets:=TStringList.Create;
  698. SubOffsets.CaseSensitive := false;
  699. //list of LVSBHeaders to clean up if error
  700. //LVSBs:=TStringList.Create;
  701. //LVSBs.CaseSensitive := false;
  702.  
  703. i:=Pos(#02'LVSB', LIsb);
  704. While (i<>0) do begin
  705. LIsb := Copy(LIsb, i+5, Length(LIsb));
  706. j:=Pos(#02'LVSB', LIsb);
  707. If (j<>0) then
  708.  TempStr := Copy(LIsb, 1, j-1)
  709.  else
  710.  TempStr := Copy(LIsb, 1, Length(LIsb));
  711. j:=Ord(TempStr[1]);
  712. //If (Copy(TempStr,2,j)<>ResNamePtr^) then begin
  713. If CompareText(Copy(TempStr,2,j),ResNamePtr^)<>0 then begin
  714. SubNames.Add(Copy(TempStr,2,j));
  715. RawPart:=Copy(TempStr, 1+j+1, Length(TempStr));
  716. j:=pos('PTH', RawPart);
  717. if (j<>0) then begin
  718.  //SubPaths.Add(Copy(RawPart, j, Length(RawPart)));
  719.  TmpPath := FEmptyPath(0);
  720.  TempStr := Copy(RawPart, j, Length(RawPart));
  721.  FUnFlattenPath(@TempStr[1], @TmpPath);
  722.  If PathIsPseudoPath(TmpPath, nil) then PseudoPathToPath(TmpPath, nil);
  723.  //resolve relative path (if any)
  724.  TmpPath2 := FEmptyPath(0);
  725.  FAddPath(LSB_VI_Path, TmpPath, TmpPath2);
  726.  If not FIsEmptyPath(TmpPath2) then FPathCpy(TmpPath, TmpPath2);
  727.  FDestroyPath(@TmpPath2);
  728.  //convert Path to Delphi string
  729.  NumBytes := SPrintf(nil, '%z', TmpPath);
  730.  SetLength(TempStr, NumBytes);
  731.  SPrintf(@TempStr[1], '%z', TmpPath);
  732.  FDestroyPath(@TmpPath);
  733.  //end of convert
  734.  SubPaths.Add(TempStr);
  735.  if ((j-6)>=0) then begin
  736.   Offset[3]:=Ord(RawPart[j-6]);
  737.   Offset[2]:=Ord(RawPart[j-5]);
  738.   Offset[1]:=Ord(RawPart[j-4]);
  739.   Offset[0]:=Ord(RawPart[j-3]);
  740.   SubOffsets.Add(IntToStr(PCardinal(@Offset)^));
  741.  end
  742.  else SubOffsets.Add('');
  743.  end
  744.  else begin
  745.  SubPaths.Add('');
  746.  SubOffsets.Add('');
  747.  end;
  748. end;
  749. i:=Pos(#02'LVSB', LIsb);
  750. end;
  751. //end of parsing
  752.  
  753. for i:=0 to SubNames.Count-1 do begin
  754. If RTE then begin
  755. Writeln(DbgFile,'Sub name '+inttostr(i)+' = '+SubNames[i]);
  756. Writeln(DbgFile,'Sub path '+inttostr(i)+' = '+SubPaths[i]);
  757. Writeln(DbgFile,'Sub offset '+inttostr(i)+' = '+SubOffsets[i]);
  758. end
  759. else begin
  760. Dbg('Sub name '+inttostr(i)+' = %p', SubNames[i]);
  761. Dbg('Sub path '+inttostr(i)+' = %p', SubPaths[i]);
  762. Dbg('Sub offset '+inttostr(i)+' = %p', SubOffsets[i]);
  763. end;
  764. end;
  765.        
  766. //load ext. subroutines
  767. TmpPath := FEmptyPath(0);
  768. For i:=0 to SubNames.Count-1 do begin
  769.  
  770. //check if current LIsb resource is in global list
  771. index := GlobalSubNames.IndexOf(SubNames[i]);
  772. if (index>-1) then begin
  773. If RTE then Writeln(DbgFile,'Ext. subroutine is in global list!') else
  774.  DbgPrintf('Ext. subroutine is in global list!');
  775. extLVSBHead := StrToInt(GlobalLVSBs[index]);
  776. //write link to ext. sub
  777. tmp1 := Ptr(LVSBHead + Cardinal(StrToInt(SubOffsets[i])));
  778. tmp2 := Ptr(PCardinal(extLVSBHead + $10)^ + 0); //LVSBMain
  779. if (PCardinal(extLVSBHead + $C)^ < $4) then
  780.  tmp1^ := Cardinal(tmp2) else //WATCOM CIN
  781.  tmp1^ := Cardinal(Ptr(tmp2^)); //standard CIN
  782. //end of write
  783.  
  784. //if (GlobalParents[index]<>ResNamePtr^) then begin
  785. if CompareText(GlobalParents[index],ResNamePtr^)<>0 then begin
  786. //parents are different
  787. //add new record to all string lists
  788. GlobalSubNames.Add(GlobalSubNames[index]);
  789. GlobalLVSBs.Add(GlobalLVSBs[index]);
  790. GlobalParents.Add(ResNamePtr^);
  791. GlobalSubPaths.Add(GlobalSubPaths[index]);
  792. GlobalOffsets.Add(GlobalOffsets[index]);
  793. end;
  794. end
  795. //end of check
  796. else begin
  797. Exists:=false;
  798.  
  799. If RTE then begin
  800.   //going up one level
  801.   //for example, from C:\Users\Ulyanov\Desktop\Application.exe\sum.lsb
  802.   //to C:\Users\Ulyanov\Desktop\sum.lsb
  803.   TempStr := ExtractFilePath(ExcludeTrailingPathDelimiter(LSB_VI_PathStr))+SubNames[i]+'.lsb';
  804.   if FileExists(TempStr) then begin
  805.    FTextToPath(@TempStr[1], Length(TempStr), @TmpPath);
  806.    SubPaths[i] := TempStr; //
  807.    Exists := true;
  808.   end
  809. End;
  810.  
  811. If not Exists then begin
  812.  If FileExists(SubPaths[i]) then begin
  813.   TempStr := SubPaths[i];
  814.   FTextToPath(@TempStr[1], Length(TempStr), @TmpPath);
  815.   Exists := true;
  816.  End
  817. end;
  818.  
  819. If not Exists then begin
  820.  If FileExists(LSB_VI_PathStr+SubNames[i]+'.lsb') then begin
  821.   TempStr := LSB_VI_PathStr+SubNames[i]+'.lsb';
  822.   FTextToPath(@TempStr[1], Length(TempStr), @TmpPath);
  823.   SubPaths[i] := TempStr; //
  824.   Exists := true;
  825.  End
  826. end;
  827.  
  828. If not Exists then begin
  829. //check in previous paths
  830.   j:=0;
  831.   while (j<=GlobalSubPaths.Count-1) and (not Exists) do begin
  832.    TempStr := ExtractFilePath(GlobalSubPaths[j])+SubNames[i]+'.lsb';
  833.    if FileExists(TempStr) then begin
  834.     FTextToPath(@TempStr[1], Length(TempStr), @TmpPath);
  835.     SubPaths[i] := TempStr; //
  836.     Exists := true;
  837.    end;
  838.    Inc(j);
  839.   end;
  840. End;
  841.  
  842. If not Exists then begin //show dialog
  843.   //set dialog path
  844.   If not FIsEmptyPath(LSB_VI_Path) then FPathCpy(TmpPath, LSB_VI_Path);
  845.   Return:=LVDialog('Please find the file of type LVSB named "'+
  846.                    SubNames[i]+'.lsb"', TmpPath, $40149, $82);
  847.   If (Return<>0) then begin
  848.    FDestroyPath(@TmpPath);
  849.    SubNames.Free;
  850.    SubPaths.Free;
  851.    SubOffsets.Free;
  852.    //DSDisposePtr(Ptr(LVSBHead));
  853.    //UnloadCIN(LVSBHead);
  854.    {for j:=0 to LVSBs.Count-1 do begin
  855.     DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  856.     UnloadCIN(StrToInt(LVSBs[j]));
  857.    end;}
  858.    //LVSBs.Free;
  859.    If RTE then Writeln(DbgFile,Format('Bad return from LVDialog: %d',[Return])) else
  860.     DbgPrintf_Format('Bad return from LVDialog: %d',Return);
  861.    Result:=False;
  862.    Exit;
  863.   end;
  864.    //convert Path to Delphi string
  865.    NumBytes := SPrintf(nil, '%z', TmpPath);
  866.    SetLength(TempStr, NumBytes);
  867.    SPrintf(@TempStr[1], '%z', TmpPath);
  868.    //end of convert
  869.    SubPaths[i] := TempStr;
  870.    //if ExtractFileName(TempStr)<>SubNames[i]+'.lsb' then begin
  871.    if CompareText(ExtractFileName(TempStr),SubNames[i]+'.lsb')<>0 then begin
  872.     FDestroyPath(@TmpPath);
  873.     SubNames.Free;
  874.     SubPaths.Free;
  875.     SubOffsets.Free;
  876.     //DSDisposePtr(Ptr(LVSBHead));
  877.     //UnloadCIN(LVSBHead);
  878.     {for j:=0 to LVSBs.Count-1 do begin
  879.      DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  880.      UnloadCIN(StrToInt(LVSBs[j]));
  881.     end;}
  882.     //LVSBs.Free;
  883.     If RTE then Writeln(DbgFile,'ExtractFileName not equals') else
  884.      DbgPrintf('ExtractFileName not equals');
  885.     Result:=False;
  886.     Exit;
  887.    end;
  888. End; //end to LVDialog
  889.  
  890. DbgPrintf_Format(pchar('Path for '+SubNames[i]+' is %z'), TmpPath);
  891. //load and analyse resource lsb
  892. Return:=ROpenFile(TmpPath, 1, @TempResource, @TempResType, @TempResCreator);
  893. If RTE then Writeln(DbgFile,Format('ROpenFile returned %d',[Return])) else
  894.  DbgPrintf_Format(pchar('ROpenFile returned %d'), Return);
  895. If RTE then Writeln(DbgFile,'TempResType^ = '+NumToChars(TempResType)) else
  896.  DbgPrintf(pchar('TempResType^ = '+NumToChars(TempResType)));
  897. //if (Return<>0) or (TempResType^<>$4253564C) then begin //string "LVSB"
  898. if (Return<>0) or (TempResType<>CharsToNum('LVSB')) then begin
  899.  if (TempResType<>CharsToNum('LVSB')) then RCloseFile(TempResource);
  900. FDestroyPath(@TmpPath);
  901. SubNames.Free;
  902. SubPaths.Free;
  903. SubOffsets.Free;
  904. //DSDisposePtr(Ptr(LVSBHead));
  905. //UnloadCIN(LVSBHead);
  906. {for j:=0 to LVSBs.Count-1 do begin
  907.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  908.  UnloadCIN(StrToInt(LVSBs[j]));
  909. end;}
  910. //LVSBs.Free;
  911. Result:=False;
  912. Exit;
  913. end;
  914. If RTE then Writeln(DbgFile,Format('ResFile handle for '+SubNames[i]+' is 0x%x',[TempResource])) else
  915.  DbgPrintf_Format(pchar('ResFile handle for '+SubNames[i]+' is 0x%x'), TempResource);
  916. //
  917. TempPStr := SubNames[i];
  918. //Return:=RGetNamed(TempResPtr^, $54414C50, @TempPStr, tmp1); //"PLAT"
  919. Return:=RGetNamed(TempResource, CharsToNum('PLAT'), @TempPStr, @tmp1);
  920. If RTE then Writeln(DbgFile,Format('RGetNamed(PLAT) returned %d',[Return])) else
  921.  DbgPrintf_Format(pchar('RGetNamed(PLAT) returned %d'), Return);
  922. if (Return <> 0) then begin
  923. RCloseFile(TempResource);
  924. FDestroyPath(@TmpPath);
  925. SubNames.Free;
  926. SubPaths.Free;
  927. SubOffsets.Free;
  928. //DSDisposePtr(Ptr(LVSBHead));
  929. //UnloadCIN(LVSBHead);
  930. {for j:=0 to LVSBs.Count-1 do begin
  931.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  932.  UnloadCIN(StrToInt(LVSBs[j]));
  933. end;}
  934. //LVSBs.Free;
  935. Result:=False;
  936. Exit;
  937. end;
  938. tmp2 := PCardinal(tmp1^);
  939. Return:=RRelease(tmp1);
  940. If RTE then Writeln(DbgFile,Format('RRelease returned %d',[Return])) else
  941.  DbgPrintf_Format(pchar('RRelease returned %d'), Return);
  942. If RTE then Writeln(DbgFile,'PLAT = '+NumToChars(tmp2^)) else
  943.  Dbg('PLAT = %p', NumToChars(tmp2^));
  944. If (NumToChars(tmp2^)<>'i386') then begin
  945. RCloseFile(TempResource);
  946. FDestroyPath(@TmpPath);
  947. SubNames.Free;
  948. SubPaths.Free;
  949. SubOffsets.Free;
  950. //DSDisposePtr(Ptr(LVSBHead));
  951. //UnloadCIN(LVSBHead);
  952. {for j:=0 to LVSBs.Count-1 do begin
  953.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  954.  UnloadCIN(StrToInt(LVSBs[j]));
  955. end;}
  956. //LVSBs.Free;
  957. Result:=False;
  958. Exit;
  959. end;
  960.  
  961. TempPStr := SubNames[i];
  962. Return:=RGetNamed(TempResource, CharsToNum('LVSB'), @TempPStr, @BinLVSBRsrc);
  963. If RTE then Writeln(DbgFile,Format('RRelease returned %d',[Return])) else
  964.  DbgPrintf_Format(pchar('RRelease returned %d'), Return);
  965. if (Return <> 0) then begin
  966. LVMessage('Could not get resource named "'+TempPStr+'" from "'+
  967.           ExtractFilePath(SubPaths[i])+'".');
  968. RCloseFile(TempResource);
  969. FDestroyPath(@TmpPath);
  970. SubNames.Free;
  971. SubPaths.Free;
  972. SubOffsets.Free;
  973. //DSDisposePtr(Ptr(LVSBHead));
  974. //UnloadCIN(LVSBHead);
  975. {for j:=0 to LVSBs.Count-1 do begin
  976.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  977.  UnloadCIN(StrToInt(LVSBs[j]));
  978. end;}
  979. //LVSBs.Free;
  980. Result:=False;
  981. Exit;
  982. end;
  983.  
  984. New(tmp1);
  985. New(tmp2);
  986. SetLength(TempPStr, 256);
  987. Return:=RGetInfo(BinLVSBRsrc, tmp1, tmp2, @TempPStr);
  988. If RTE then Writeln(DbgFile,Format('RGetInfo returned %d',[Return])) else
  989.  DbgPrintf_Format(pchar('RGetInfo returned %d'), Return);
  990. If RTE then Writeln(DbgFile,Format('Index is %d',[tmp1^])) else
  991.  DbgPrintf_Format(pchar('Index is %d'), tmp1^);
  992. If RTE then Writeln(DbgFile,'Type is '+NumToChars(tmp2^)) else
  993.  Dbg('Type is %p', NumToChars(tmp2^));
  994. If RTE then Writeln(DbgFile,'Name is '+TempPStr) else
  995.  Dbg('Name is %p', TempPStr);
  996. Dispose(tmp2);
  997. Dispose(tmp1);
  998.  
  999. Return:=RDetach(BinLVSBRsrc);
  1000. If RTE then Writeln(DbgFile,Format('RDetach returned %d',[Return])) else
  1001.  DbgPrintf_Format(pchar('RDetach returned %d'), Return);
  1002. if (Return <> 0) then begin
  1003. RCloseFile(TempResource);
  1004. FDestroyPath(@TmpPath);
  1005. SubNames.Free;
  1006. SubPaths.Free;
  1007. SubOffsets.Free;
  1008. //DSDisposePtr(Ptr(LVSBHead));
  1009. //UnloadCIN(LVSBHead);
  1010. {for j:=0 to LVSBs.Count-1 do begin
  1011.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  1012.  UnloadCIN(StrToInt(LVSBs[j]));
  1013. end;}
  1014. //LVSBs.Free;
  1015. Result:=False;
  1016. Exit;
  1017. end;
  1018.  
  1019. extLVSBHead:=LoadCINFromRsrc(BinLVSBRsrc, SubNames[i]);
  1020. If RTE then Writeln(DbgFile,Format('New LVSB header is 0x%x',[extLVSBHead])) else
  1021.  DbgPrintf_Format(pchar('New LVSB header is 0x%x'),extLVSBHead);
  1022. if (extLVSBHead=0) then begin
  1023. If RTE then Writeln(DbgFile,'External sub LVSBHeader is null') else
  1024.  DbgPrintf('External sub LVSBHeader is null');
  1025. RCloseFile(TempResource);
  1026. FDestroyPath(@TmpPath);
  1027. SubNames.Free;
  1028. SubPaths.Free;
  1029. SubOffsets.Free;
  1030. //DSDisposePtr(Ptr(LVSBHead));
  1031. //UnloadCIN(LVSBHead);
  1032. {for j:=0 to LVSBs.Count-1 do begin
  1033.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  1034.  UnloadCIN(StrToInt(LVSBs[j]));
  1035. end;}
  1036. //LVSBs.Free;
  1037. Result:=False;
  1038. Exit;
  1039. end;
  1040.  
  1041. if (StrToInt(SubOffsets[i])<$38) then begin
  1042. If RTE then Writeln(DbgFile,'Patching LVSB with LVSB at bad offset') else
  1043.  DbgPrintf('Patching LVSB with LVSB at bad offset');
  1044. RCloseFile(TempResource);
  1045. FDestroyPath(@TmpPath);
  1046. SubNames.Free;
  1047. SubPaths.Free;
  1048. SubOffsets.Free;
  1049. //DSDisposePtr(Ptr(extLVSBHead));
  1050. UnloadCIN(extLVSBHead);
  1051. {for j:=0 to LVSBs.Count-1 do begin
  1052.  DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  1053.  UnloadCIN(StrToInt(LVSBs[j]));
  1054. end;}
  1055. //LVSBs.Free;
  1056. Result:=False;
  1057. Exit;
  1058. end;
  1059.  
  1060. GlobalSubNames.Add(SubNames[i]);
  1061. GlobalLVSBs.Add(IntToStr(extLVSBHead));
  1062. GlobalParents.Add(ResNamePtr^);
  1063. GlobalSubPaths.Add(SubPaths[i]);
  1064. GlobalOffsets.Add(SubOffsets[i]);
  1065.  
  1066. //write link to ext. sub
  1067. tmp1 := Ptr(LVSBHead + Cardinal(StrToInt(SubOffsets[i])));
  1068. tmp2 := Ptr(PCardinal(extLVSBHead + $10)^ + 0); //LVSBMain
  1069. if (PCardinal(extLVSBHead + $C)^ < $4) then
  1070.  tmp1^ := Cardinal(tmp2) else //WATCOM CIN
  1071.  tmp1^ := Cardinal(Ptr(tmp2^)); //standard CIN
  1072. //end of write
  1073.  
  1074. TempPStr := SubNames[i];
  1075. RGetNamed(TempResource, CharsToNum('LIsb'), @TempPStr, @BinLIsbRsrc);
  1076. if Assigned(BinLIsbRsrc) then begin
  1077.   If not RecursiveCINLoad(extLVSBHead,TempResource,LSB_VI_Path,@TempPStr)
  1078.   then begin
  1079.    RCloseFile(TempResource);
  1080.    FDestroyPath(@TmpPath);
  1081.    SubNames.Free;
  1082.    SubPaths.Free;
  1083.    SubOffsets.Free;
  1084.    //DSDisposePtr(Ptr(extLVSBHead));  !
  1085.    //UnloadCIN(extLVSBHead);
  1086.    {for j:=0 to LVSBs.Count-1 do begin
  1087.     DSDisposePtr(Ptr(StrToInt(LVSBs[j])));
  1088.     UnloadCIN(StrToInt(LVSBs[j]));
  1089.    end;}
  1090.    //LVSBs.Free;
  1091.    Result:=False;
  1092.    Exit;
  1093.   end;
  1094. end;
  1095. RCloseFile(TempResource);
  1096. //LVSBs.Add(IntToStr(extLVSBHead));
  1097. //end of load and analyse
  1098. end;
  1099. End; //end to For
  1100. FDestroyPath(@TmpPath); //MUST BE HERE~!
  1101. //RCloseFile(TempResource);
  1102. //FDestroyPath(@TmpPath);
  1103. //end of load
  1104. SubNames.Free;
  1105. SubPaths.Free;
  1106. SubOffsets.Free;
  1107. //LVSBs.Free;
  1108. ///////////
  1109. end;
  1110.  
  1111. function ProcessExternal(LVSBHead, void, Resource_class_handle,
  1112.          LinkIdentity_class_ptr: cardinal; FuncResult: PCardinal;
  1113.          Res_Name_Ptr: PShortString; RFReader: cardinal): integer; cdecl;
  1114. var CINModuleAddress, LSB_VI_Path,
  1115.     TempResource, TempResType, TempResCreator: Cardinal;
  1116.     tmp1, tmp2: PCardinal;
  1117.     ModuleName: pchar;
  1118.     ReloadCounter,i,j: integer;
  1119. begin
  1120. ProcessExternal:=0;
  1121. If RTE then begin
  1122. Writeln(DbgFile,'-----LOAD CIN BEGIN-----');
  1123. //Writeln(DbgFile,'Resource name is "'+Res_Name_Ptr+'"');
  1124. Writeln(DbgFile,Format('Resource name is "%s"',[Res_Name_Ptr^]));
  1125. Writeln(DbgFile,Format('void is 0x%x',[void]));
  1126. Writeln(DbgFile,Format('LVSB ResFile handle is 0x%x',[Resource_class_handle]));
  1127. Writeln(DbgFile,Format('LinkIdentity_class_ptr is 0x%x',[LinkIdentity_class_ptr]));
  1128. Writeln(DbgFile,Format('RFReader is 0x%x',[RFReader]));
  1129. end
  1130. else begin
  1131. DbgPrintf('-----LOAD CIN BEGIN-----');
  1132. DbgPrintf_PStr(pchar('Resource name is "%p"'), Res_Name_Ptr);
  1133. DbgPrintf_Format(pchar('void is 0x%x'),void);
  1134. DbgPrintf_Format(pchar('LVSB ResFile handle is 0x%x'),Resource_class_handle);
  1135. DbgPrintf_Format(pchar('LinkIdentity_class_ptr is 0x%x'),LinkIdentity_class_ptr);
  1136. DbgPrintf_Format(pchar('RFReader is 0x%x'),RFReader);
  1137. end;
  1138.  
  1139. Try
  1140. tmp1 := Ptr(LVSBHead + $1C);
  1141. CINModuleAddress := tmp1^;
  1142. tmp1 := Ptr(LVSBHead + $14);
  1143. ReloadCounter := tmp1^;
  1144. Except on E:Exception do begin
  1145. CINModuleAddress := 0;
  1146. ReloadCounter := 0;
  1147. end;
  1148. End;
  1149.  
  1150. If RTE then begin
  1151. Writeln(DbgFile,Format('cin hdr = 0x%x',[LVSBHead]));
  1152. Writeln(DbgFile,Format('cin module addr = 0x%x',[CINModuleAddress]));
  1153. Writeln(DbgFile,Format('rld counter = %d',[ReloadCounter]));
  1154. end
  1155. else begin
  1156. DbgPrintf_Format(pchar('cin hdr = 0x%x'), LVSBHead);
  1157. DbgPrintf_Format(pchar('cin module addr = 0x%x'), CINModuleAddress);
  1158. DbgPrintf_Format(pchar('rld counter = %d'), ReloadCounter);
  1159. end;
  1160.  
  1161. GetMem(ModuleName, $104);
  1162. GetModuleFileName(CINModuleAddress, ModuleName, $104);
  1163. If RTE then Writeln(DbgFile,'CIN name = '+ModuleName) else
  1164.  Dbg('CIN name = %p', ModuleName);
  1165. FreeMem(ModuleName);
  1166.  
  1167. //If (PCardinal(LVSBHead+$8)^<>$204E4943) then begin //string "CIN "
  1168.  //If (PCardinal(LVSBHead+$1C)^=$454B4146) then //string "FAKE"
  1169. If (PCardinal(LVSBHead+$8)^<>CharsToNum('CIN ')) then begin
  1170.  If (PCardinal(LVSBHead+$1C)^=CharsToNum('FAKE')) then
  1171.   DSDisposePtr(Ptr(LVSBHead))
  1172.  else UnloadCIN(LVSBHead);
  1173. FuncResult^ := $0F;
  1174. //OneButtonAlert($35,'Cannot load a Subroutine as a CIN.',0,$7FFF,$7FFF,0);
  1175. LVMessage('Cannot load a Subroutine as a CIN.');
  1176. If RTE then Writeln(DbgFile,'-----LOAD CIN END-----') else
  1177.  DbgPrintf('-----LOAD CIN END-----');
  1178. ProcessExternal:=1;
  1179. Exit;
  1180. end;
  1181.  
  1182. //determine path to current *.lsb or current VI
  1183. LSB_VI_Path:=0;
  1184. Try
  1185. //LinkIdentity::GetPath function
  1186. tmp1 := Ptr(LinkIdentity_class_ptr);
  1187. if (tmp1^<>0) then begin
  1188.  if (LVVersion<14) then tmp2 := Ptr(tmp1^ + $240)
  1189.  else tmp2 := Ptr(tmp1^ + $40);
  1190.  LSB_VI_Path := tmp2^;
  1191. end;
  1192. Except on E:Exception do
  1193. LSB_VI_Path := 0;
  1194. End;
  1195.  
  1196. if (LSB_VI_Path=0) then begin
  1197. Try
  1198. tmp1 := Ptr(void + $51);
  1199. //LI_vi := tmp1^ + $2C;
  1200. //LinkIdentity::GetPath function
  1201. if (tmp1^<>0) then begin
  1202.  tmp1 := Ptr(tmp1^ + $2C);
  1203.  //DbgPrintf_Format(pchar('LI_vi is 0x%x'), cardinal(tmp1));
  1204.  if (tmp1^<>0) then begin
  1205.   if (LVVersion<14) then tmp2 := Ptr(tmp1^ + $240)
  1206.   else tmp2 := Ptr(tmp1^ + $40);
  1207.   LSB_VI_Path := tmp2^;
  1208.  end;
  1209. end;
  1210. Except on E:Exception do
  1211. LSB_VI_Path := 0;
  1212. End;
  1213. end;
  1214.  
  1215. if (LSB_VI_Path=0) then begin
  1216. Try
  1217. tmp1 := Ptr(LinkIdentity_class_ptr + $B);
  1218. if (tmp1^<>0) then begin
  1219.  tmp2 := Ptr(tmp1^ + $29);
  1220.  if (tmp2^<>0) then begin
  1221.   if (LVVersion<14) then tmp1 := Ptr(tmp2^ + $240)
  1222.   else tmp1 := Ptr(tmp2^ + $40);
  1223.   LSB_VI_Path := tmp1^;
  1224.  end;
  1225. end;
  1226. Except on E:Exception do
  1227. LSB_VI_Path := 0;
  1228. End;
  1229. end;
  1230.  
  1231. //for RTE 2010
  1232. if (LSB_VI_Path=0) then begin
  1233. Try
  1234. tmp1 := Ptr(LinkIdentity_class_ptr + $8);
  1235. if (tmp1^<>0) then begin
  1236.  tmp2 := Ptr(tmp1^ + $B8); //~!
  1237.  if (tmp2^<>0) then begin
  1238.   //tmp1 := Ptr(tmp2^ + $240);
  1239.   //LSB_VI_Path := tmp1^;
  1240.   tmp1 := Ptr(tmp2^);
  1241.   if (tmp1^<>0) then begin
  1242.    tmp2 := Ptr(tmp1^ + $8);
  1243.    if (tmp2^<>0) then begin
  1244.     tmp1 := Ptr(tmp2^ + $24); //24 instead of 2C
  1245.     if (tmp1^<>0) then begin
  1246.      tmp2 := Ptr(tmp1^ + $240);
  1247.      LSB_VI_Path := tmp2^;
  1248.     end;
  1249.    end;
  1250.   end;
  1251.  end;
  1252. end;
  1253. Except on E:Exception do
  1254. LSB_VI_Path := 0;
  1255. End;
  1256. end;
  1257.  
  1258. //for RTE 2011 & 2012
  1259. if (LSB_VI_Path=0) then begin
  1260. Try
  1261. tmp1 := Ptr(LinkIdentity_class_ptr + $8);
  1262. if (tmp1^<>0) then begin
  1263.  tmp2 := Ptr(tmp1^ + $B8); //~!
  1264.  if (tmp2^<>0) then begin
  1265.   //tmp1 := Ptr(tmp2^ + $240);
  1266.   //LSB_VI_Path := tmp1^;
  1267.   tmp1 := Ptr(tmp2^);
  1268.   if (tmp1^<>0) then begin
  1269.    tmp2 := Ptr(tmp1^ + $8);
  1270.    if (tmp2^<>0) then begin
  1271.     tmp1 := Ptr(tmp2^ + $2C); //~!
  1272.     if (tmp1^<>0) then begin
  1273.      tmp2 := Ptr(tmp1^ + $240);
  1274.      LSB_VI_Path := tmp2^;
  1275.     end;
  1276.    end;
  1277.   end;
  1278.  end;
  1279. end;
  1280. Except on E:Exception do
  1281. LSB_VI_Path := 0;
  1282. End;
  1283. end;
  1284.  
  1285. //for RTE 2013
  1286. if (LSB_VI_Path=0) then begin
  1287. Try
  1288. tmp1 := Ptr(LinkIdentity_class_ptr + $8);
  1289. if (tmp1^<>0) then begin
  1290.  tmp2 := Ptr(tmp1^ + $BC); //BC instead of B8
  1291.  if (tmp2^<>0) then begin
  1292.   //tmp1 := Ptr(tmp2^ + $240);
  1293.   //LSB_VI_Path := tmp1^;
  1294.   tmp1 := Ptr(tmp2^);
  1295.   if (tmp1^<>0) then begin
  1296.    tmp2 := Ptr(tmp1^ + $8);
  1297.    if (tmp2^<>0) then begin
  1298.     tmp1 := Ptr(tmp2^ + $2C); //~!
  1299.     if (tmp1^<>0) then begin
  1300.      tmp2 := Ptr(tmp1^ + $240);
  1301.      LSB_VI_Path := tmp2^;
  1302.     end;
  1303.    end;
  1304.   end;
  1305.  end;
  1306. end;
  1307. Except on E:Exception do
  1308. LSB_VI_Path := 0;
  1309. End;
  1310. end;
  1311.  
  1312. //for RTE 2014
  1313. if (LSB_VI_Path=0) then begin
  1314. Try
  1315. tmp1 := Ptr(LinkIdentity_class_ptr + $8);
  1316. if (tmp1^<>0) then begin
  1317.  tmp2 := Ptr(tmp1^ + $4C); //~!
  1318.  if (tmp2^<>0) then begin
  1319.   //tmp1 := Ptr(tmp2^ + $240);
  1320.   //LSB_VI_Path := tmp1^;
  1321.   tmp1 := Ptr(tmp2^);
  1322.   if (tmp1^<>0) then begin
  1323.    tmp2 := Ptr(tmp1^ + $8);
  1324.    if (tmp2^<>0) then begin
  1325.     tmp1 := Ptr(tmp2^ + $4); //~!
  1326.     if (tmp1^<>0) then begin
  1327.      tmp2 := Ptr(tmp1^ + $40); //~!!
  1328.      LSB_VI_Path := tmp2^;
  1329.     end;
  1330.    end;
  1331.   end;
  1332.  end;
  1333. end;
  1334. Except on E:Exception do
  1335. LSB_VI_Path := 0;
  1336. End;
  1337. end;
  1338. //end of determine
  1339.  
  1340. if (LSB_VI_Path=0) then begin
  1341.   LVMessage('LSB/VI Path is empty!');
  1342.   If RTE then Writeln(DbgFile,'-----LOAD CIN END-----') else
  1343.    DbgPrintf('-----LOAD CIN END-----');
  1344.   FuncResult^ := $0F;
  1345.   ProcessExternal:=1;
  1346.   Exit;
  1347. end
  1348. else DbgPrintf_Format(pchar('Resolved path is "%z"'), LSB_VI_Path);  
  1349.  
  1350. TempResource := 0;
  1351. if (Resource_class_handle=0) then begin
  1352. {
  1353. Try
  1354. //class ResChain & __thiscall RFReader::LowLevelResChain(void)
  1355. tmp1 := Ptr(RFReader + $5);
  1356. if (tmp1^<>0) then begin
  1357. tmp2 := Ptr(tmp1^);
  1358. Resource_class_handle := tmp2^;
  1359. end;
  1360. Except on E:Exception do
  1361. Resource_class_handle := 0;
  1362. End;}
  1363. //
  1364. {
  1365. asm
  1366. mov ECX, RFReader
  1367. end;
  1368. Resource_class_handle := RFReader_MapToObsoleteRsrcFile;
  1369. }
  1370. ROpenFile(LSB_VI_Path, 1, @TempResource, @TempResType, @TempResCreator);
  1371. Resource_class_handle := TempResource;
  1372. end;
  1373.  
  1374. if (Resource_class_handle=0) then begin
  1375.   If RTE then Writeln(DbgFile,'Resource class handle is empty!') else
  1376.    DbgPrintf('Resource class handle is empty!');
  1377.   If RTE then Writeln(DbgFile,'-----LOAD CIN END-----') else
  1378.    DbgPrintf('-----LOAD CIN END-----');
  1379.   FuncResult^ := $0F;
  1380.   ProcessExternal:=1;
  1381.   Exit;
  1382. end
  1383. else
  1384. If RTE then Writeln(DbgFile,Format('Resource class handle is 0x%x',[Resource_class_handle])) else
  1385.  DbgPrintf_Format(pchar('Resource class handle is 0x%x'), Resource_class_handle);
  1386.  
  1387.  
  1388. If not RecursiveCINLoad(LVSBHead,Resource_class_handle,LSB_VI_Path,Res_Name_Ptr)
  1389.  then begin
  1390.   //DSDisposePtr(Ptr(LVSBHead));
  1391.   UnloadCIN(LVSBHead);
  1392.   FreeCINTree(Res_Name_Ptr^);
  1393.   LVMessage('Error loading external subroutine.');
  1394.   FuncResult^ := $0F;
  1395.   ProcessExternal:=1;
  1396.  end;
  1397. //$18 - Ext subs not supported
  1398. //$0F - Bad platform
  1399. if (TempResource<>0) then RCloseFile(TempResource);
  1400. If RTE then Writeln(DbgFile,'-----LOAD CIN END-----') else
  1401.  DbgPrintf('-----LOAD CIN END-----');
  1402. If RTE then Flush(DbgFile);
  1403. end;
  1404.  
  1405. function SaveCIN(LVSBdata: pointer; DataSize, Res_Index: integer;
  1406.                  LVSB_Name: PShortString;
  1407.                  LinkIdentity_class_ptr: cardinal): integer; cdecl;
  1408. var tmp1, tmp2: PCardinal;
  1409.     Resource_class_handle, TmpPath: cardinal;
  1410.     TempStr: string;
  1411.     i,j,k, Return, NumBytes, NumOfSubs, TempOffset: integer;
  1412.     LIsbBinData, FlatPath: array of byte;
  1413.     Offset: array[0..3] of byte;
  1414. begin
  1415. SaveCIN:=0;
  1416. If RTE then begin
  1417. Writeln(DbgFile,'-----SAVE CIN BEGIN-----');
  1418. Writeln(DbgFile,Format('LVSBdata ptr is 0x%x',[cardinal(LVSBdata)]));
  1419. Writeln(DbgFile,Format('Data size is 0x%x',[DataSize]));
  1420. Writeln(DbgFile,Format('Res_Index is 0x%x',[Res_Index]));
  1421. Writeln(DbgFile,Format('LVSB name is "%s"',[LVSB_Name]));
  1422. Writeln(DbgFile,Format('LI ptr is 0x%x',[LinkIdentity_class_ptr]));
  1423. end
  1424. else begin
  1425. DbgPrintf('-----SAVE CIN BEGIN-----');
  1426. DbgPrintf_Format(pchar('LVSBdata ptr is 0x%x'),cardinal(LVSBdata));
  1427. DbgPrintf_Format(pchar('Data size is 0x%x'),DataSize);
  1428. DbgPrintf_Format(pchar('Res_Index is 0x%x'),Res_Index);
  1429. DbgPrintf_PStr(pchar('LVSB name is "%p"'), LVSB_Name);
  1430. DbgPrintf_Format(pchar('LI ptr is 0x%x'),LinkIdentity_class_ptr);
  1431. end;
  1432.      
  1433. //get Resource class from LinkIdentity class ptr
  1434. Try
  1435. Resource_class_handle := PCardinal(LinkIdentity_class_ptr + $8)^;
  1436. Except on E:Exception do
  1437. Resource_class_handle := 0;
  1438. End;
  1439.  
  1440. if (Resource_class_handle=0) then begin
  1441. Try
  1442. Resource_class_handle := PCardinal(LinkIdentity_class_ptr + $C)^;
  1443. Except on E:Exception do
  1444. Resource_class_handle := 0;
  1445. End;
  1446. end;
  1447. //end of get Resource class
  1448. If RTE then Writeln(DbgFile,Format('Resource_class_handle is 0x%x',[Resource_class_handle])) else
  1449.  DbgPrintf_Format(pchar('Resource_class_handle is 0x%x'),Resource_class_handle);
  1450.  
  1451. //write PLAT
  1452. TempStr := 'i386';
  1453. //tmp1 := @TempStr[1];
  1454. //tmp2 := @tmp1;
  1455. tmp1 := DSNewHandle(4);
  1456. tmp2 := Ptr(tmp1^);
  1457. Move(TempStr[1], tmp2^, Length(TempStr) * SizeOf(TempStr[1]));
  1458. Return:=RAdd(tmp1, Resource_class_handle, CharsToNum('PLAT'), Res_Index, LVSB_Name);
  1459. //DSDisposeHandle(tmp2);
  1460. if (Return<>0) then begin
  1461. If RTE then Writeln(DbgFile,'-----SAVE CIN END-----') else
  1462.  DbgPrintf('-----SAVE CIN END-----');
  1463. Finalize(LIsbBinData);
  1464. Finalize(FlatPath);
  1465. Exit;
  1466. end;
  1467. //end of write PLAT
  1468.  
  1469. //write LVSB
  1470. tmp1 := DSNewHandle(DataSize);
  1471. tmp2 := Ptr(tmp1^);
  1472. Move(LVSBdata^, tmp2^, DataSize);
  1473. Return:=RAdd(tmp1, Resource_class_handle, CharsToNum('LVSB'), Res_Index, LVSB_Name);
  1474. //DSDisposeHandle(tmp2);
  1475. if (Return<>0) then begin
  1476. If RTE then Writeln(DbgFile,'-----SAVE CIN END-----') else
  1477.  DbgPrintf('-----SAVE CIN END-----');
  1478. Finalize(LIsbBinData);
  1479. Finalize(FlatPath);
  1480. Exit;
  1481. end;
  1482. //end of write LVSB
  1483.  
  1484. //write LIsb
  1485. j := Length(LVSB_Name^);
  1486. SetLength(LIsbBinData, 7+j+7);
  1487. LIsbBinData[0]:=$00; //test -- must be $00
  1488. LIsbBinData[1]:=$01;
  1489. LIsbBinData[2]:=$4C; //"L"
  1490. LIsbBinData[3]:=$56; //"V"
  1491. LIsbBinData[4]:=$53; //"S"
  1492. LIsbBinData[5]:=$42; //"B"
  1493. Move(LVSB_Name^,LIsbBinData[6],j+1);
  1494. LIsbBinData[7+j+0]:=$00;
  1495. LIsbBinData[7+j+1]:=$00;
  1496. LIsbBinData[7+j+2]:=$00;
  1497. LIsbBinData[7+j+3]:=$00;
  1498. LIsbBinData[7+j+4]:=$00;
  1499. LIsbBinData[7+j+5]:=$00;
  1500. LIsbBinData[7+j+6]:=$01; //num of subs
  1501. {
  1502. LIsbBinData[7+j+7]:=$00;
  1503. LIsbBinData[7+j+8]:=$02;
  1504. LIsbBinData[7+j+9]:=$4C; //"L"
  1505. LIsbBinData[7+j+10]:=$56; //"V"
  1506. LIsbBinData[7+j+11]:=$53; //"S"
  1507. LIsbBinData[7+j+12]:=$42; //"B"
  1508. }
  1509. TmpPath := FEmptyPath(0);
  1510. NumOfSubs := 0;
  1511. For i:=0 to GlobalParents.Count-1 do Begin
  1512.  If (CompareText(GlobalParents.Strings[i],LVSB_Name^)=0) then begin
  1513.  //sub name -> GlobalSubNames
  1514.  //sub offset -> GlobalOffsets
  1515.  //sub path -> GlobalSubPaths
  1516.  //convert Delphi path to LV flattened path
  1517.  TempStr := GlobalSubPaths.Strings[i];
  1518.  FTextToPath(@TempStr[1], Length(TempStr), @TmpPath);
  1519.  NumBytes := FFlattenPath(TmpPath, nil);
  1520.  //SetLength(TempStr, NumBytes);
  1521.  SetLength(FlatPath, NumBytes);
  1522.  //FFlattenPath(TmpPath, @TempStr[1]);
  1523.  FFlattenPath(TmpPath, @FlatPath[0]);
  1524.  //FlatPath := TempStr;
  1525.  //end of convert
  1526.  //convert sub offset to hex form
  1527.  if not TryStrToInt(GlobalOffsets.Strings[i], TempOffset) then
  1528.   TempOffset := $38;
  1529.   Offset[0] := Hi(TempOffset shr 16);
  1530.   Offset[1] := Lo(TempOffset shr 16);
  1531.   Offset[2] := Lo(TempOffset shr 8);
  1532.   Offset[3] := Lo(TempOffset);
  1533.  //end of convert
  1534.   //j := 6+1+Length(GlobalSubNames.Strings[i])+4+Length(Offset)+2+Length(FlatPath);
  1535.   //SetLength(LIsbBinData, Length(LIsbBinData)+j);
  1536.   j := Length(LIsbBinData);
  1537.   SetLength(LIsbBinData, j+6+1+Length(GlobalSubNames.Strings[i])+4+Length(Offset)+2+Length(FlatPath));
  1538.   LIsbBinData[j+0]:=$00;
  1539.   LIsbBinData[j+1]:=$02;
  1540.   LIsbBinData[j+2]:=$4C; //"L"
  1541.   LIsbBinData[j+3]:=$56; //"V"
  1542.   LIsbBinData[j+4]:=$53; //"S"
  1543.   LIsbBinData[j+5]:=$42; //"B"
  1544.   k := Length(GlobalSubNames.Strings[i]);
  1545.   LIsbBinData[j+6]:=k;
  1546.   Move(GlobalSubNames.Strings[i][1],LIsbBinData[j+7],k);
  1547.   LIsbBinData[j+7+k]:=$00;
  1548.   LIsbBinData[j+7+k+1]:=$00;
  1549.   LIsbBinData[j+7+k+2]:=$00;
  1550.   LIsbBinData[j+7+k+3]:=$01;
  1551.   //Length(Offset) is always =4, so it's const
  1552.   Move(Offset[0],LIsbBinData[j+7+k+4],4);
  1553.   LIsbBinData[j+7+k+8]:=$00;
  1554.   LIsbBinData[j+7+k+9]:=$00;
  1555.   Move(FlatPath[0],LIsbBinData[j+7+k+10],Length(FlatPath));
  1556.   Inc(NumOfSubs);
  1557.   LIsbBinData[7+Length(LVSB_Name^)+6]:=NumOfSubs; //num of subs
  1558.  end;
  1559. End;
  1560. FDestroyPath(@TmpPath);
  1561.  
  1562. if (NumOfSubs>0) then begin
  1563. //write LIsb
  1564. tmp1 := DSNewHandle(Length(LIsbBinData));
  1565. tmp2 := Ptr(tmp1^);
  1566. Move(LIsbBinData[0], tmp2^, Length(LIsbBinData));
  1567. Return:=RAdd(tmp1, Resource_class_handle, CharsToNum('LIsb'), Res_Index, LVSB_Name);
  1568. If RTE then Writeln(DbgFile,Format('RAdd LIsb returned %d',[Return])) else
  1569.  DbgPrintf_Format(pchar('RAdd LIsb returned %d'),Return);
  1570. //end of write LIsb
  1571. end;
  1572.    DumpToFile('C:\LV4.bin',@LIsbBinData[0],Length(LIsbBinData));
  1573.  
  1574. //end of write LIsb
  1575. If RTE then Writeln(DbgFile,'-----SAVE CIN END-----') else
  1576.  DbgPrintf('-----SAVE CIN END-----');
  1577. Finalize(LIsbBinData);
  1578. Finalize(FlatPath);
  1579. If RTE then Flush(DbgFile);
  1580. end;
  1581.  
  1582. procedure PurgeCIN(RFReadWrite, LVSBHead: cardinal); cdecl;
  1583. var tmp1, tmp2: PCardinal;
  1584.     Return, Id: integer;
  1585.     ResType, LVResFile, LVResource: cardinal;
  1586.     CIN_Name: ShortString;
  1587. begin
  1588. //
  1589. If RTE then begin
  1590. Writeln(DbgFile,'-----PURGE CIN BEGIN-----');
  1591. Writeln(DbgFile,Format('RFReadWrite class is 0x%x',[RFReadWrite]));
  1592. Writeln(DbgFile,Format('LVSBHead is 0x%x',[LVSBHead]));
  1593. end
  1594. else begin
  1595. DbgPrintf('-----PURGE CIN BEGIN-----');
  1596. DbgPrintf_Format(pchar('RFReadWrite class is 0x%x'),RFReadWrite);
  1597. DbgPrintf_Format(pchar('LVSBHead is 0x%x'),LVSBHead);
  1598. end;
  1599.  
  1600. If (PCardinal(LVSBHead+$8)^=CharsToNum('CIN ')) then begin
  1601.  
  1602. Id := PCardinal(LVSBHead+$14)^;
  1603. If RTE then Writeln(DbgFile,Format('Id = %d',[Id])) else
  1604.  DbgPrintf_Format(pchar('Id = %d'), Id);
  1605.  
  1606. if (RTE) or (mgcore=0) then begin     //1
  1607. LVResFile := 0;
  1608. Try
  1609. //RFReadWrite::LowLevelResFile function
  1610. tmp1 := Ptr(RFReadWrite + $5);
  1611. if (tmp1^<>0) then begin
  1612.  LVResFile := tmp1^;
  1613. end;
  1614. Except on E:Exception do
  1615. LVResFile := 0;
  1616. End;
  1617. end
  1618. else begin
  1619. asm
  1620. mov ecx, RFReadWrite
  1621. end;
  1622. LVResFile := RFReadWrite_LowLevelResFile;
  1623. end;
  1624. If RTE then Writeln(DbgFile,Format('Low level res file: 0x%x',[LVResFile])) else
  1625.  DbgPrintf_Format(pchar('Low level res file: 0x%x'), LVResFile);
  1626.  
  1627. ResType := CharsToNum('LVSB');
  1628.  
  1629. if (RTE) or (mgcore=0) then begin //define LVResFile::RGet     2
  1630. @LVResFile_RGet := nil;
  1631. Try
  1632. tmp1 := Ptr(LVResFile);
  1633. if (tmp1^<>0) then begin
  1634.  tmp2 := Ptr(tmp1^ + $8);
  1635.  if (tmp2^<>0) then begin
  1636.   @LVResFile_RGet := Ptr(tmp2^);
  1637.  end;
  1638. end;
  1639. Except on E:Exception do
  1640. @LVResFile_RGet := nil;
  1641. End;
  1642. end;
  1643.  
  1644. if Assigned(LVResFile_RGet) then begin
  1645. asm
  1646. mov ecx, LVResFile
  1647. end;
  1648. LVResFile_RGet(ResType, Id, @LVResource);
  1649. end;
  1650.  
  1651. if (RTE) or (mgcore=0) then begin //define LVResource::RGetInfo     3
  1652. @LVResource_RGetInfo := nil;
  1653. Try
  1654. tmp1 := Ptr(LVResource);
  1655. if (tmp1^<>0) then begin
  1656.  tmp2 := Ptr(tmp1^ + $18);
  1657.  if (tmp2^<>0) then begin
  1658.   @LVResource_RGetInfo := Ptr(tmp2^);
  1659.  end;
  1660. end;
  1661. Except on E:Exception do
  1662. @LVResource_RGetInfo := nil;
  1663. End;
  1664. end;
  1665.  
  1666. if Assigned(LVResource_RGetInfo) then begin
  1667. New(tmp1);
  1668. New(tmp2);
  1669. asm
  1670. mov ecx, LVResource
  1671. end;
  1672. Return:=LVResource_RGetInfo(tmp1, tmp2, @CIN_Name);
  1673. If RTE then Writeln(DbgFile,Format('LVResource_RGetInfo returned %d',[Return])) else
  1674.  DbgPrintf_Format(pchar('LVResource_RGetInfo returned %d'), Return);
  1675. If RTE then Writeln(DbgFile,Format('Index is %d',[tmp1^])) else
  1676.  DbgPrintf_Format(pchar('Index is %d'), tmp1^);
  1677. If RTE then Writeln(DbgFile,'Type is '+NumToChars(tmp2^)) else
  1678.  Dbg('Type is %p', NumToChars(tmp2^));
  1679. If RTE then Writeln(DbgFile,'Name is '+CIN_Name) else
  1680.  Dbg('Name is %p', CIN_Name);
  1681. Dispose(tmp2);
  1682. Dispose(tmp1);
  1683. end;
  1684.  
  1685. FreeCINTree(CIN_Name);
  1686.  
  1687. //remove LVSB, PLAT & LIsb resources from main VI resource
  1688. if (RTE) or (mgcore=0) then begin                    //4
  1689. //define LVResFile::RRemove
  1690. @LVResFile_RRemove := nil;
  1691. Try
  1692. tmp1 := Ptr(LVResFile);
  1693. if (tmp1^<>0) then begin
  1694.  tmp2 := Ptr(tmp1^ + $34);
  1695.  if (tmp2^<>0) then begin
  1696.   @LVResFile_RRemove := Ptr(tmp2^);
  1697.  end;
  1698. end;
  1699. Except on E:Exception do
  1700. @LVResFile_RRemove := nil;
  1701. End;
  1702.  
  1703. ResType := CharsToNum('LVSB');
  1704.  
  1705. if Assigned(LVResFile_RGet) then begin
  1706. asm
  1707. mov ecx, LVResFile
  1708. end;
  1709. LVResFile_RGet(ResType, Id, @LVResource);
  1710. end;
  1711.  
  1712. if Assigned(LVResFile_RRemove) then begin
  1713. asm
  1714. mov ecx, LVResFile
  1715. end;
  1716. LVResFile_RRemove(LVResource);
  1717. end;
  1718.  
  1719. ResType := CharsToNum('PLAT');
  1720.  
  1721. if Assigned(LVResFile_RGet) then begin
  1722. asm
  1723. mov ecx, LVResFile
  1724. end;
  1725. LVResFile_RGet(ResType, Id, @LVResource);
  1726. end;
  1727.  
  1728. if Assigned(LVResFile_RRemove) then begin
  1729. asm
  1730. mov ecx, LVResFile
  1731. end;
  1732. LVResFile_RRemove(LVResource);
  1733. end;
  1734.  
  1735. ResType := CharsToNum('LIsb');
  1736.  
  1737. if Assigned(LVResFile_RGet) then begin
  1738. asm
  1739. mov ecx, LVResFile
  1740. end;
  1741. LVResFile_RGet(ResType, Id, @LVResource);
  1742. end;
  1743.  
  1744. if Assigned(LVResFile_RRemove) then begin
  1745. asm
  1746. mov ecx, LVResFile
  1747. end;
  1748. LVResFile_RRemove(LVResource);
  1749. end;
  1750.  
  1751. end
  1752. else begin
  1753. ResType := CharsToNum('LVSB');
  1754.  
  1755. asm
  1756. mov ecx, RFReadWrite
  1757. end;
  1758. RFReadWrite_Remove(ResType, Id);
  1759.  
  1760. ResType := CharsToNum('PLAT');
  1761.  
  1762. asm
  1763. mov ecx, RFReadWrite
  1764. end;
  1765. RFReadWrite_Remove(ResType, Id);
  1766.  
  1767. ResType := CharsToNum('LIsb');
  1768.  
  1769. asm
  1770. mov ecx, RFReadWrite
  1771. end;
  1772. RFReadWrite_Remove(ResType, Id);
  1773. end;
  1774. end; //end to If (PCardinal(LVSBHead+$8)^=CharsToNum('CIN '))
  1775.  
  1776. if (PCardinal(LVSBHead+$1C)^=CharsToNum('FAKE')) then
  1777.   DSDisposePtr(Ptr(LVSBHead))
  1778.   else UnloadCIN(LVSBHead);
  1779.  
  1780. If RTE then Writeln(DbgFile,'-----PURGE CIN END-----') else
  1781.  DbgPrintf('-----PURGE CIN END-----');
  1782. //
  1783. end;
  1784.  
  1785. procedure ShowGlobalList; cdecl;
  1786. var i: integer;
  1787.     pth: string;
  1788. begin
  1789. for i:=0 to GlobalSubNames.Count-1 do begin
  1790. pth := StringReplace(GlobalSubPaths[i],'\','\\',[rfReplaceAll]);
  1791.      
  1792. If RTE then Writeln(DbgFile,Format('"'+GlobalSubNames[i]+'" (0x%x) [parent="'+
  1793.                  GlobalParents[i]+'", path="'+pth+'", offset='+
  1794.                  GlobalOffsets[i]+']',[StrToInt(GlobalLVSBs[i])])) else
  1795. DbgPrintf_Format(pchar('"'+GlobalSubNames[i]+'" (0x%x) [parent="'+
  1796.                  GlobalParents[i]+'", path="'+pth+'", offset='+
  1797.                  GlobalOffsets[i]+']'),
  1798.                  StrToInt(GlobalLVSBs[i]));
  1799. end;
  1800. If RTE then Flush(DbgFile);
  1801. end;
  1802.  
  1803. exports ShowGlobalList name 'ShowGlobalList';
  1804.  
  1805. procedure DLLEntryPoint(Reason: DWORD);
  1806. var A: PCardinal;
  1807.     B: PByte;
  1808.     i, poffset, LIsb, LowerLimit, UpperLimit, ThisLibInstance, Return: cardinal;
  1809.     found: boolean;
  1810.     LVHeader: PImageOptionalHeader;
  1811.     LVInstanceName: string;
  1812.     const SearchSeq : Array[0..8] of byte =
  1813.     ($C7,$45,$FC,$69,$33,$38,$36,$FF,$D2);
  1814.     const SearchSeq2 : Array[0..6] of byte =
  1815.     ($81,$78,$08,$43,$49,$4E,$20);
  1816.     const SearchSeq3 : Array[0..8] of byte = //for PurgeCIN
  1817.     ($68,$4C,$56,$53,$42,$FF,$D0,$8B,$C8);
  1818.     const SearchSeq4 : Array[0..3] of byte = //for PurgeCIN
  1819.     ($43,$49,$4E,$20);
  1820. begin
  1821. case Reason of
  1822. DLL_PROCESS_ATTACH: begin
  1823. LVInstance := GetModuleHandle(nil);
  1824.  
  1825. //If (LVInstance<>0) then begin
  1826. SetLength(LVInstanceName, MAX_PATH);
  1827. Return:=GetModuleFileName(LVInstance, @LVInstanceName[1], MAX_PATH);
  1828. SetLength(LVInstanceName, Return);
  1829. //LVInstanceName := ChangeFileExt(ExtractFileName(LVInstanceName), '');
  1830. If (ChangeFileExt(ExtractFileName(LVInstanceName), '')<>'LabVIEW') then begin
  1831.   LVInstance := GetModuleHandle('lvrt.dll');
  1832.   SetLength(LVInstanceName, MAX_PATH);
  1833.   Return:=GetModuleFileName(LVInstance, @LVInstanceName[1], MAX_PATH);
  1834.   SetLength(LVInstanceName, Return);
  1835.   RTE:=True;
  1836.   //create new debug file for errors
  1837.   ThisLibInstance := GetModuleHandle('lvsb.dll');
  1838.   SetLength(DbgFilePath, MAX_PATH);
  1839.   Return:=GetModuleFileName(ThisLibInstance, @DbgFilePath[1], MAX_PATH);
  1840.   SetLength(DbgFilePath, Return);
  1841.   DbgFilePath := ExtractFilePath(DbgFilePath)+'lvsb_debug.txt';
  1842.   AssignFile(DbgFile, DbgFilePath);
  1843.   {$I-}
  1844.   repeat
  1845.   Rewrite(DbgFile);
  1846.   until (IOResult=0);
  1847.   {$I+}
  1848. end;
  1849. If (LVInstance<>0) then begin
  1850.   DbgPrintf := GetProcAddress(LVInstance, 'DbgPrintf');
  1851.   DbgPrintf_Format := @DbgPrintf;
  1852.   DbgPrintf_PStr := @DbgPrintf;
  1853.   MoveBlock := GetProcAddress(LVInstance, 'MoveBlock');
  1854.   SPrintf := GetProcAddress(LVInstance, 'SPrintf');
  1855.   //AZCheckPtr := GetProcAddress(LVInstance, 'AZCheckPtr');
  1856.   DSGetHandleSize := GetProcAddress(LVInstance, 'DSGetHandleSize');
  1857.   DSNewPtr := GetProcAddress(LVInstance, 'DSNewPtr');
  1858.   DSNewPClr := GetProcAddress(LVInstance, 'DSNewPClr');
  1859.   DSDisposePtr := GetProcAddress(LVInstance, 'DSDisposePtr');
  1860.   DSCheckPtr := GetProcAddress(LVInstance, 'DSCheckPtr');
  1861.   DSNewHandle := GetProcAddress(LVInstance, 'DSNewHandle');
  1862.   DSDisposeHandle := GetProcAddress(LVInstance, 'DSDisposeHandle');
  1863.   DSRecoverHandle := GetProcAddress(LVInstance, 'DSRecoverHandle');
  1864.   RGetNamed := GetProcAddress(LVInstance, 'RGetNamed');
  1865.   RGet := GetProcAddress(LVInstance, 'RGet');
  1866.   RGetInfo := GetProcAddress(LVInstance, 'RGetInfo');
  1867.   ROpenFile := GetProcAddress(LVInstance, 'ROpenFile');
  1868.   RCloseFile := GetProcAddress(LVInstance, 'RCloseFile');
  1869.   RRelease := GetProcAddress(LVInstance, 'RRelease');
  1870.   RDetach := GetProcAddress(LVInstance, 'RDetach');
  1871.   RAdd := GetProcAddress(LVInstance, 'RAdd');
  1872.   gLVRTVersion := PChar(PCardinal(GetProcAddress(LVInstance, 'gLVRTVersion'))^);
  1873.   FEmptyPath := GetProcAddress(LVInstance, 'FEmptyPath');
  1874.   FFlattenPath := GetProcAddress(LVInstance, 'FFlattenPath');
  1875.   FUnFlattenPath := GetProcAddress(LVInstance, 'FUnFlattenPath');
  1876.   PathIsPseudoPath := GetProcAddress(LVInstance, 'PathIsPseudoPath');
  1877.   PseudoPathToPath := GetProcAddress(LVInstance, 'PseudoPathToPath');
  1878.   FDestroyPath := GetProcAddress(LVInstance, 'FDestroyPath');
  1879.   FTextToPath := GetProcAddress(LVInstance, 'FTextToPath');
  1880.   FNamePtr := GetProcAddress(LVInstance, 'FNamePtr');
  1881.   FAddPath := GetProcAddress(LVInstance, 'FAddPath');
  1882.   FDirName := GetProcAddress(LVInstance, 'FDirName');
  1883.   FIsEmptyPath := GetProcAddress(LVInstance, 'FIsEmptyPath');
  1884.   FPathCpy := GetProcAddress(LVInstance, 'FPathCpy');
  1885.   OneButtonAlert := GetProcAddress(LVInstance, 'OneButtonAlert');
  1886.   ExtFileDialog := GetProcAddress(LVInstance, 'ExtFileDialog');
  1887.   RevBL := GetProcAddress(LVInstance, 'RevBL');  
  1888.   LVRTTable := Cardinal(GetProcAddress(LVInstance, 'LVRTTable'));
  1889. mgcore := GetModuleHandle(pchar('mgcore_SH_'+IntToStr(LVVersion)+'_0.dll'));
  1890. If (mgcore<>0) then begin
  1891. //RFReader_MapToObsoleteRsrcFile := GetProcAddress(mgcore, '?MapToObsoleteRsrcFile@RFReader@@UAEKXZ');
  1892. RFReadWrite_Remove := GetProcAddress(mgcore, '?Remove@RFReadWrite@@QAEJW4_ResourceType@@J@Z');
  1893. RFReadWrite_LowLevelResFile := GetProcAddress(mgcore, '?LowLevelResFile@RFReadWrite@@QAEAAVResFile@@XZ');
  1894. LVResFile_RGet := GetProcAddress(mgcore, '?RGet@LVResFile@@UAEJW4_ResourceType@@JPAPAVResource@@@Z');
  1895. LVResource_RGetInfo := GetProcAddress(mgcore, '?RGetInfo@LVResource@@UBEJPAJPAW4_ResourceType@@PAE@Z');
  1896. end
  1897. else
  1898.  If RTE then Writeln(DbgFile,'mgcore_SH_'+IntToStr(LVVersion)+'_0.dll not found!')
  1899.  else DbgPrintf(pchar('mgcore_SH_'+IntToStr(LVVersion)+'_0.dll not found!'));
  1900.  
  1901. LVHeader := PImageOptionalHeader(pointer(integer(LVInstance) +
  1902.             PImageDosHeader(LVInstance)._lfanew + SizeOf(DWORD) +
  1903.             SizeOf(TImageFileHeader)));
  1904. If RTE then begin
  1905. Writeln(DbgFile,'Working in '+LVInstanceName);
  1906. //showmessage(Format('CodeBase is 0x%x',[LVHeader.BaseOfCode]));
  1907. Writeln(DbgFile,Format('CodeBase is 0x%x',[LVHeader.BaseOfCode]));
  1908. Writeln(DbgFile,Format('CodeSize is 0x%x',[LVHeader.SizeOfCode]));
  1909. end
  1910. else begin
  1911. DbgPrintf(pchar('Working in '+LVInstanceName));
  1912. DbgPrintf_Format(pchar('CodeBase is 0x%x'),LVHeader.BaseOfCode);
  1913. DbgPrintf_Format(pchar('CodeSize is 0x%x'),LVHeader.SizeOfCode);
  1914. end;
  1915. LowerLimit := LVInstance + LVHeader.BaseOfCode;
  1916. UpperLimit := LowerLimit + LVHeader.SizeOfCode - 1;
  1917. found:=false; i:=0;
  1918. LIsb := CharsToNum('LIsb');
  1919.  
  1920. //patching first sequence
  1921. while (not found) and (LowerLimit+i <= UpperLimit) do begin
  1922. i:=i+1;
  1923. A := Ptr(LowerLimit+i);
  1924. if Assigned(A) then
  1925.  //if A^ = $6273494C then found:=true; //string "LIsb"
  1926.  if A^ = LIsb then found:=true;
  1927. end;
  1928. if found then begin
  1929. PatchAddress_First := LowerLimit+i+13;
  1930. If RTE then begin
  1931. Writeln(DbgFile,Format('Found First offset: 0x%x',[LowerLimit+i]));
  1932. Writeln(DbgFile,Format('ProcessExternal proc is 0x%x',[cardinal(@ProcessExternal)]));
  1933. end
  1934. else begin
  1935. DbgPrintf_Format(pchar('Found First offset: 0x%x'),LowerLimit+i);
  1936. DbgPrintf_Format(pchar('ProcessExternal proc is 0x%x'),cardinal(@ProcessExternal));
  1937. end;
  1938.  
  1939. WriteBytesWithBackup(ptr(PatchAddress_First), PatchReload_First, Backup_First);
  1940. //ProcessExternalAddress := @ProcessExternal; //pointer to ProcessExternal func
  1941.    {
  1942. //write pointer address to byte array (PatchReload_Second)
  1943. PatchReload_Second[15] := Hi(Cardinal(@ProcessExternalAddress) shr 16);
  1944. PatchReload_Second[14] := Lo(Cardinal(@ProcessExternalAddress) shr 16);
  1945. PatchReload_Second[13] := Lo(Cardinal(@ProcessExternalAddress) shr 8);
  1946. PatchReload_Second[12] := Lo(Cardinal(@ProcessExternalAddress));
  1947.  
  1948. If RTE then PatchAddress := LowerLimit+i-376 else
  1949.  PatchAddress := LowerLimit+i-425;
  1950. WriteBytes(ptr(PatchAddress), PatchReload_Second);
  1951. }
  1952. end;
  1953. //end of patching
  1954.  
  1955. //patching second sequence
  1956. found:=false; i:=0;
  1957. while (not found) and (LowerLimit+i <= UpperLimit) do begin
  1958. i:=i+1;
  1959. A := Ptr(LowerLimit+i);
  1960. if Assigned(A) then
  1961.  if CompareMem(A,@SearchSeq2[0],7) then found:=true;
  1962. end;
  1963. if found then begin
  1964. If RTE then Writeln(DbgFile,Format('Found Second offset: 0x%x',[LowerLimit+i])) else
  1965.  DbgPrintf_Format(pchar('Found Second offset: 0x%x'),LowerLimit+i);
  1966. PatchAddress_Second := LowerLimit+i-3;
  1967. ProcessExternalAddress := @ProcessExternal; //pointer to ProcessExternal func
  1968.  
  1969. //write pointer address to byte array (PatchReload_Second)
  1970. if RTE then begin
  1971. PatchReload_Second_RTE[15] := Hi(Cardinal(@ProcessExternalAddress) shr 16);
  1972. PatchReload_Second_RTE[14] := Lo(Cardinal(@ProcessExternalAddress) shr 16);
  1973. PatchReload_Second_RTE[13] := Lo(Cardinal(@ProcessExternalAddress) shr 8);
  1974. PatchReload_Second_RTE[12] := Lo(Cardinal(@ProcessExternalAddress));
  1975.  
  1976. WriteBytesWithBackup(ptr(PatchAddress_Second), PatchReload_Second_RTE, Backup_Second_RTE);
  1977. end
  1978. else begin
  1979. PatchReload_Second[15] := Hi(Cardinal(@ProcessExternalAddress) shr 16);
  1980. PatchReload_Second[14] := Lo(Cardinal(@ProcessExternalAddress) shr 16);
  1981. PatchReload_Second[13] := Lo(Cardinal(@ProcessExternalAddress) shr 8);
  1982. PatchReload_Second[12] := Lo(Cardinal(@ProcessExternalAddress));
  1983.  
  1984. WriteBytesWithBackup(ptr(PatchAddress_Second), PatchReload_Second, Backup_Second);
  1985. end;
  1986. end
  1987. else
  1988. If RTE then Writeln(DbgFile,'Second offset not found!') else
  1989.  DbgPrintf('Second offset not found!');
  1990. //end of patching
  1991.  
  1992. //patching Save option
  1993. found:=false; i:=0;
  1994. while (not found) and (LowerLimit+i <= UpperLimit) do begin
  1995. i:=i+1;
  1996. A := Ptr(LowerLimit+i);
  1997. if Assigned(A) then
  1998.  if CompareMem(A,@SearchSeq[0],9) then found:=true;
  1999. end;
  2000. if found then begin
  2001. If RTE then Writeln(DbgFile,Format('Found Save offset: 0x%x',[LowerLimit+i])) else
  2002.  DbgPrintf_Format(pchar('Found Save offset: 0x%x'),LowerLimit+i);
  2003. PatchAddress_ForSave := LowerLimit+i-33;
  2004. SaveCINAddress := @SaveCIN; //pointer to SaveCIN func
  2005.  
  2006. //write pointer address to byte array (PatchReload_ForSave)
  2007. PatchReload_ForSave[20] := Hi(Cardinal(@SaveCINAddress) shr 16);
  2008. PatchReload_ForSave[19] := Lo(Cardinal(@SaveCINAddress) shr 16);
  2009. PatchReload_ForSave[18] := Lo(Cardinal(@SaveCINAddress) shr 8);
  2010. PatchReload_ForSave[17] := Lo(Cardinal(@SaveCINAddress));
  2011.  
  2012. WriteBytesWithBackup(ptr(PatchAddress_ForSave), PatchReload_ForSave, Backup_ForSave);
  2013. end
  2014. else
  2015. If RTE then Writeln(DbgFile,'Save offset not found!') else
  2016.  DbgPrintf('Save offset not found!');
  2017.  
  2018. //patching Purge option
  2019. found:=false; i:=0;
  2020. while (not found) and (LowerLimit+i <= UpperLimit) do begin
  2021. i:=i+1;
  2022. A := Ptr(LowerLimit+i);
  2023. if Assigned(A) then
  2024.  if CompareMem(A,@SearchSeq3[0],9) then found:=true;
  2025. end;
  2026. if found then begin //1
  2027. If RTE then Writeln(DbgFile,Format('Found Purge offset: 0x%x',[LowerLimit+i])) else
  2028.  DbgPrintf_Format(pchar('Found Purge offset: 0x%x'),LowerLimit+i);
  2029. PatchAddress_ForPurge := LowerLimit+i-11;
  2030. PurgeCINAddress := @PurgeCIN; //pointer to PurgeCIN func
  2031.  
  2032. //write pointer address to byte array (PatchReload_ForSave)
  2033.  
  2034. PatchReload_ForPurge[16] := Hi(Cardinal(@PurgeCINAddress) shr 16);
  2035. PatchReload_ForPurge[15] := Lo(Cardinal(@PurgeCINAddress) shr 16);
  2036. PatchReload_ForPurge[14] := Lo(Cardinal(@PurgeCINAddress) shr 8);
  2037. PatchReload_ForPurge[13] := Lo(Cardinal(@PurgeCINAddress));
  2038.  
  2039. WriteBytesWithBackup(ptr(PatchAddress_ForPurge), PatchReload_ForPurge, Backup_ForPurge);
  2040.  
  2041. //apply second patch
  2042.  
  2043. //go up and search for first CALL function
  2044. found:=false; i:=PatchAddress_ForPurge-LowerLimit;
  2045. while (not found) and (i>0) do begin
  2046. i:=i-1;
  2047. B := Ptr(LowerLimit+i);
  2048. if Assigned(B) then
  2049.  if (B^ = $E8) then found:=true;
  2050. end;
  2051. if found then begin //2
  2052. poffset := LowerLimit+i;
  2053.  
  2054. //go up and search for "CIN " string test
  2055. found:=false; //i:=PatchAddress_ForPurge-LowerLimit;
  2056. while (not found) and (i>0) do begin
  2057. i:=i-1;
  2058. A := Ptr(LowerLimit+i);
  2059. if Assigned(A) then
  2060.  if CompareMem(A,@SearchSeq4[0],4) then found:=true;
  2061. end;
  2062. if found then begin //3
  2063. If RTE then Writeln(DbgFile,Format('Found Purge offset 2: 0x%x',[LowerLimit+i])) else
  2064.  DbgPrintf_Format(pchar('Found Purge offset 2: 0x%x'),LowerLimit+i);
  2065. PatchAddress_ForPurge2 := LowerLimit+i+6;
  2066. poffset := poffset - (PatchAddress_ForPurge2+4);
  2067. PatchReload_ForPurge2[3] := Hi(poffset shr 16);
  2068. PatchReload_ForPurge2[2] := Lo(poffset shr 16);
  2069. PatchReload_ForPurge2[1] := Lo(poffset shr 8);
  2070. PatchReload_ForPurge2[0] := Lo(poffset);
  2071. WriteBytesWithBackup(ptr(PatchAddress_ForPurge2), PatchReload_ForPurge2, Backup_ForPurge2);
  2072. end //end to if found 3
  2073. else
  2074. If RTE then Writeln(DbgFile,'Purge offset 2 not found!') else
  2075.  DbgPrintf('Purge offset 2 not found!');
  2076. end //end to if found 2
  2077. else
  2078. If RTE then Writeln(DbgFile,'Purge first call not found!') else
  2079.  DbgPrintf('Purge first call not found!');
  2080. end //end to if found 1
  2081. else
  2082. If RTE then Writeln(DbgFile,'Purge offset not found!') else
  2083.  DbgPrintf('Purge offset not found!');
  2084.  
  2085. GlobalSubNames:=TStringList.Create;
  2086. GlobalSubNames.CaseSensitive := false;
  2087. GlobalLVSBs:=TStringList.Create;
  2088. GlobalLVSBs.CaseSensitive := false;
  2089. GlobalParents:=TStringList.Create;
  2090. GlobalParents.CaseSensitive := false;
  2091. GlobalSubPaths:=TStringList.Create;
  2092. GlobalSubPaths.CaseSensitive := false;
  2093. GlobalOffsets:=TStringList.Create;
  2094. GlobalOffsets.CaseSensitive := false;
  2095.  
  2096. If RTE then Flush(DbgFile);
  2097. end; // If (LVInstance<>0)
  2098. //end; // If (LVInstance<>0)
  2099. end; // DLL_PROCESS_ATTACH
  2100. DLL_THREAD_ATTACH:
  2101. begin
  2102. //MessageBox(0, 'Подключение потока', 'Инфо', mb_Ok);
  2103. end;
  2104. DLL_THREAD_DETACH:
  2105. begin
  2106. //MessageBox(0, 'Отключение потока', 'Инфо', mb_Ok);
  2107. end;
  2108. DLL_PROCESS_DETACH:
  2109. begin
  2110. GlobalSubNames.Free;
  2111. GlobalLVSBs.Free;
  2112. GlobalParents.Free;
  2113. GlobalSubPaths.Free;
  2114. GlobalOffsets.Free;
  2115. If RTE then CloseFile(DbgFile);
  2116. //restore LV data
  2117. WriteBytes(ptr(PatchAddress_First), Backup_First);
  2118. WriteBytes(ptr(PatchAddress_Second), Backup_Second);
  2119. WriteBytes(ptr(PatchAddress_ForSave), Backup_ForSave);
  2120. WriteBytes(ptr(PatchAddress_ForPurge), Backup_ForPurge);
  2121. WriteBytes(ptr(PatchAddress_ForPurge2), Backup_ForPurge2);
  2122. end;
  2123. end; //case Reason of
  2124. end; //proc
  2125.  
  2126. begin
  2127. DllProc := @DLLEntryPoint;
  2128. DllProc(DLL_PROCESS_ATTACH);
  2129. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement