forked from jrsoftware/issrc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRegDLL.pas
100 lines (87 loc) · 3.16 KB
/
RegDLL.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
unit RegDLL;
{
Inno Setup
Copyright (C) 1997-2012 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
Registers 32-bit/64-bit DLL-based OLE servers in a child process (regsvr32.exe)
}
interface
uses
Windows;
procedure RegisterServer(const AUnregister: Boolean; const AIs64Bit: Boolean;
const Filename: String; const AFailCriticalErrors: Boolean);
implementation
uses
SysUtils, Forms, PathFunc, CmnFunc, CmnFunc2, InstFunc, Msgs, MsgIDs,
Logging, RedirFunc, Main;
function WaitForAndCloseProcessHandle(var AProcessHandle: THandle): DWORD;
var
WaitResult: DWORD;
begin
try
repeat
{ Process any pending messages first because MsgWaitForMultipleObjects
(called below) only returns when *new* messages arrive }
Application.ProcessMessages;
WaitResult := MsgWaitForMultipleObjects(1, AProcessHandle, False, INFINITE, QS_ALLINPUT);
until WaitResult <> WAIT_OBJECT_0+1;
if WaitResult = WAIT_FAILED then
Win32ErrorMsg('MsgWaitForMultipleObjects');
if not GetExitCodeProcess(AProcessHandle, Result) then
Win32ErrorMsg('GetExitCodeProcess');
finally
CloseHandle(AProcessHandle);
end;
end;
procedure RegisterServerUsingRegSvr32(const AUnregister: Boolean;
const AIs64Bit: Boolean; const Filename: String);
var
SysDir, CmdLine: String;
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
ExitCode: DWORD;
begin
SysDir := GetSystemDir;
CmdLine := '"' + AddBackslash(SysDir) + 'regsvr32.exe"';
if AUnregister then
CmdLine := CmdLine + ' /u';
CmdLine := CmdLine + ' /s "' + Filename + '"';
if AIs64Bit then
Log('Spawning 64-bit RegSvr32: ' + CmdLine)
else
Log('Spawning 32-bit RegSvr32: ' + CmdLine);
FillChar(StartupInfo, SizeOf(StartupInfo), 0);
StartupInfo.cb := SizeOf(StartupInfo);
if not CreateProcessRedir(AIs64Bit, nil, PChar(CmdLine), nil, nil, False,
CREATE_DEFAULT_ERROR_MODE, nil, PChar(SysDir), StartupInfo,
ProcessInfo) then
Win32ErrorMsg('CreateProcess');
CloseHandle(ProcessInfo.hThread);
ExitCode := WaitForAndCloseProcessHandle(ProcessInfo.hProcess);
if ExitCode <> 0 then
raise Exception.Create(FmtSetupMessage1(msgErrorRegSvr32Failed,
Format('0x%x', [ExitCode])));
end;
procedure RegisterServer(const AUnregister: Boolean; const AIs64Bit: Boolean;
const Filename: String; const AFailCriticalErrors: Boolean);
var
WindowDisabler: TWindowDisabler;
begin
if AIs64Bit and not IsWin64 then
InternalError('Cannot register 64-bit DLLs on this version of Windows');
{ Disable windows so the user can't utilize our UI while the child process
is running }
WindowDisabler := TWindowDisabler.Create;
try
{ On Windows Vista, to get the "WRP Mitigation" compatibility hack which
a lot of DLLs a require, we must use regsvr32.exe to handle the
(un)registration.
On Windows 2000/XP/2003, use regsvr32.exe as well for behavioral &
error message consistency. }
RegisterServerUsingRegSvr32(AUnregister, AIs64Bit, Filename);
finally
WindowDisabler.Free;
end;
end;
end.