Browse Source

Delay-load CoWaitForMultipleHandles to not force the dependency on ole32.dll.

Rika Ichinose 2 years ago
parent
commit
943b88e3da
3 changed files with 30 additions and 1 deletions
  1. 20 1
      rtl/win/systhrd.inc
  2. 5 0
      rtl/win32/system.pp
  3. 5 0
      rtl/win64/system.pp

+ 20 - 1
rtl/win/systhrd.inc

@@ -545,7 +545,26 @@ end;
 type 
 type 
       PWOHandleArray = ^THandle;
       PWOHandleArray = ^THandle;
 
 
-function CoWaitForMultipleHandles(dwFlags, dwTimeout: DWORD; cHandles: uint32; pHandles: PWOHandleArray; out lpdwindex: DWORD): HRESULT; stdcall; external 'ole32.dll' name 'CoWaitForMultipleHandles';
+function FirstCoWaitForMultipleHandles(dwFlags, dwTimeout: DWORD; cHandles: uint32; pHandles: PWOHandleArray; out lpdwindex: DWORD): HRESULT; stdcall; forward;
+
+var
+  Ole32Dll: THandle = 0; { Unloaded at win32 & win64 system_exit. }
+  CoWaitForMultipleHandles: function(dwFlags, dwTimeout: DWORD; cHandles: uint32; pHandles: PWOHandleArray; out lpdwindex: DWORD): HRESULT; stdcall;
+    = @FirstCoWaitForMultipleHandles;
+
+function FirstCoWaitForMultipleHandles(dwFlags, dwTimeout: DWORD; cHandles: uint32; pHandles: PWOHandleArray; out lpdwindex: DWORD): HRESULT; stdcall;
+var
+  LocalOle32Dll: THandle;
+begin
+  if Ole32Dll = 0 then
+  begin
+    LocalOle32Dll := WinLoadLibraryW('ole32.dll');
+    if InterlockedCompareExchange(Pointer(Ole32Dll), Pointer(LocalOle32Dll), nil) <> nil then
+      WinFreeLibrary(LocalOle32Dll);
+  end;
+  CodePointer(CoWaitForMultipleHandles) := WinGetProcAddress(Ole32Dll, 'CoWaitForMultipleHandles');
+  Result := CoWaitForMultipleHandles(dwFlags, dwTimeout, cHandles, pHandles, lpdwindex);
+end;
 
 
 function intbasiceventWaitFor(Timeout : Cardinal;state:peventstate;UseCOMWait: Boolean = False) : longint;
 function intbasiceventWaitFor(Timeout : Cardinal;state:peventstate;UseCOMWait: Boolean = False) : longint;
 const COWAIT_DEFAULT = 0;
 const COWAIT_DEFAULT = 0;

+ 5 - 0
rtl/win32/system.pp

@@ -117,6 +117,11 @@ begin
      { what about Input and Output ?? PM }
      { what about Input and Output ?? PM }
      { now handled, FPK }
      { now handled, FPK }
    end;
    end;
+  if Ole32Dll <> 0 then
+    begin
+      WinFreeLibrary(Ole32Dll); { Careful, FreeLibrary should not be called from DllMain. }
+      Ole32Dll := 0;
+    end;
 {$ifndef FPC_USE_WIN32_SEH}
 {$ifndef FPC_USE_WIN32_SEH}
   if not IsLibrary then
   if not IsLibrary then
     remove_exception_handlers;
     remove_exception_handlers;

+ 5 - 0
rtl/win64/system.pp

@@ -117,6 +117,11 @@ begin
      { what about Input and Output ?? PM }
      { what about Input and Output ?? PM }
      { now handled, FPK }
      { now handled, FPK }
    end;
    end;
+  if Ole32Dll <> 0 then
+    begin
+      WinFreeLibrary(Ole32Dll); { Careful, FreeLibrary should not be called from DllMain. }
+      Ole32Dll := 0;
+    end;
 
 
   { call exitprocess, with cleanup as required }
   { call exitprocess, with cleanup as required }
   ExitProcess(exitcode);
   ExitProcess(exitcode);