From 02c02382be619ce45080cce86e7fdfc43d64f69a Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sun, 11 Jul 2004 22:35:07 +0000 Subject: [PATCH] do not statically link to ole32.dll, import the functions dynamically instead. This is required since winlogon statically links to userenv.dll and then ole32.dll would automatically be loaded which causes ole32.dll to register a window class before the first window station is created (-> the ole32 window class(es) couldn't be registered). Besides it's bad to have winlogon depend on ole32.dll svn path=/trunk/; revision=10083 --- reactos/lib/userenv/desktop.c | 47 ++++++++++++++--------- reactos/lib/userenv/internal.h | 32 +++++++++++++++- reactos/lib/userenv/makefile | 2 +- reactos/lib/userenv/misc.c | 69 +++++++++++++++++++++++++++++++++- 4 files changed, 130 insertions(+), 20 deletions(-) diff --git a/reactos/lib/userenv/desktop.c b/reactos/lib/userenv/desktop.c index 6163db7411e..942b5ac4df6 100644 --- a/reactos/lib/userenv/desktop.c +++ b/reactos/lib/userenv/desktop.c @@ -1,4 +1,4 @@ -/* $Id: desktop.c,v 1.6 2004/05/07 11:18:53 ekohl Exp $ +/* $Id: desktop.c,v 1.7 2004/07/11 22:35:07 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -150,6 +150,7 @@ AddDesktopItemW (BOOL bCommonDesktop, WORD wHotKey, INT iShowCmd) { + DYN_FUNCS Ole32; WCHAR szLinkPath[MAX_PATH]; WCHAR szArguments[MAX_PATH]; WCHAR szCommand[MAX_PATH]; @@ -216,16 +217,20 @@ AddDesktopItemW (BOOL bCommonDesktop, DPRINT ("szCommand: '%S'\n", szCommand); DPRINT ("szArguments: '%S'\n", szArguments); - CoInitialize(NULL); + /* dynamically load ole32.dll */ + LoadDynamicImports(&DynOle32, &Ole32); - hr = CoCreateInstance(&CLSID_ShellLink, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IShellLinkW, - (LPVOID*)&psl); + Ole32.fn.CoInitialize(NULL); + + hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, + (LPVOID*)&psl); if (!SUCCEEDED(hr)) { - CoUninitialize(); + Ole32.fn.CoUninitialize(); + UnloadDynamicImports(&Ole32); return FALSE; } @@ -275,7 +280,9 @@ AddDesktopItemW (BOOL bCommonDesktop, psl->lpVtbl->Release(psl); - CoUninitialize(); + Ole32.fn.CoUninitialize(); + + UnloadDynamicImports(&Ole32); DPRINT ("AddDesktopItemW() done\n"); @@ -428,6 +435,7 @@ AddItemW (LPCWSTR lpGroupName, WORD wHotKey, INT iShowCmd) { + DYN_FUNCS Ole32; WCHAR szLinkPath[MAX_PATH]; WCHAR szArguments[MAX_PATH]; WCHAR szCommand[MAX_PATH]; @@ -499,16 +507,20 @@ AddItemW (LPCWSTR lpGroupName, DPRINT ("szCommand: '%S'\n", szCommand); DPRINT ("szArguments: '%S'\n", szArguments); - CoInitialize(NULL); + /* dynamically load ole32.dll */ + LoadDynamicImports(&DynOle32, &Ole32); - hr = CoCreateInstance(&CLSID_ShellLink, - NULL, - CLSCTX_INPROC_SERVER, - &IID_IShellLinkW, - (LPVOID*)&psl); + Ole32.fn.CoInitialize(NULL); + + hr = Ole32.fn.CoCreateInstance(&CLSID_ShellLink, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IShellLinkW, + (LPVOID*)&psl); if (!SUCCEEDED(hr)) { - CoUninitialize(); + Ole32.fn.CoUninitialize(); + UnloadDynamicImports(&Ole32); return FALSE; } @@ -558,7 +570,8 @@ AddItemW (LPCWSTR lpGroupName, psl->lpVtbl->Release(psl); - CoUninitialize(); + Ole32.fn.CoUninitialize(); + UnloadDynamicImports(&Ole32); DPRINT ("AddItemW() done\n"); diff --git a/reactos/lib/userenv/internal.h b/reactos/lib/userenv/internal.h index 8343e2d4354..fdeecd9924a 100644 --- a/reactos/lib/userenv/internal.h +++ b/reactos/lib/userenv/internal.h @@ -1,4 +1,4 @@ -/* $Id: internal.h,v 1.6 2004/05/07 11:18:53 ekohl Exp $ +/* $Id: internal.h,v 1.7 2004/07/11 22:35:07 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -37,6 +37,36 @@ BOOL RemoveDirectoryPath (LPCWSTR lpPathName); /* misc.c */ +typedef struct _DYN_FUNCS +{ + HMODULE hModule; + union + { + PVOID foo; + struct + { + HRESULT (STDCALL *CoInitialize)(LPVOID pvReserved); + HRESULT (STDCALL *CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID * ppv); + HRESULT (STDCALL *CoUninitialize)(VOID); + }; + } fn; +} DYN_FUNCS, *PDYN_FUNCS; + +typedef struct _DYN_MODULE +{ + LPWSTR Library; /* dll file name */ + int nFunctions; /* number of functions in the Functions array */ + LPSTR *Functions; /* function names */ +} DYN_MODULE, *PDYN_MODULE; + +extern DYN_MODULE DynOle32; + +BOOL +LoadDynamicImports(PDYN_MODULE Module, PDYN_FUNCS DynFuncs); + +VOID +UnloadDynamicImports(PDYN_FUNCS DynFuncs); + LPWSTR AppendBackslash (LPWSTR String); diff --git a/reactos/lib/userenv/makefile b/reactos/lib/userenv/makefile index 18c5e800746..ba98f620ce5 100644 --- a/reactos/lib/userenv/makefile +++ b/reactos/lib/userenv/makefile @@ -13,7 +13,7 @@ TARGET_CFLAGS += -DUNICODE -D_UNICODE -Wall -Werror TARGET_LFLAGS = -nostdlib -nostartfiles -TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a ole32.a wine_uuid.a +TARGET_SDKLIBS = ntdll.a kernel32.a advapi32.a wine_uuid.a TARGET_OBJECTS = desktop.o directory.o environment.o profile.o misc.o \ registry.o setup.o userenv.o diff --git a/reactos/lib/userenv/misc.c b/reactos/lib/userenv/misc.c index 4548eaa98ff..d57f89b2e98 100644 --- a/reactos/lib/userenv/misc.c +++ b/reactos/lib/userenv/misc.c @@ -1,4 +1,4 @@ -/* $Id: misc.c,v 1.2 2004/03/13 20:49:07 ekohl Exp $ +/* $Id: misc.c,v 1.3 2004/07/11 22:35:07 weiden Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -91,4 +91,71 @@ GetUserSidFromToken (HANDLE hToken, return TRUE; } +/* Dynamic DLL loading interface **********************************************/ + +/* OLE32.DLL import table */ +LPSTR Ole32Imports[] = +{ + "CoInitialize", + "CoCreateInstance", + "CoUninitialize", +}; + +DYN_MODULE DynOle32 = +{ + L"ole32.dll", + sizeof(Ole32Imports) / sizeof(LPSTR), + Ole32Imports +}; + +/* + Use this function to load functions from other modules. We cannot statically + link to e.g. ole32.dll because those dlls would get loaded on startup with + winlogon and they may try to register classes etc when not even a window station + has been created! +*/ + +BOOL +LoadDynamicImports(PDYN_MODULE Module, PDYN_FUNCS DynFuncs) +{ + int i; + PVOID *fn; + + ZeroMemory(DynFuncs, sizeof(DYN_FUNCS)); + + DynFuncs->hModule = LoadLibraryW(Module->Library); + if(!DynFuncs->hModule) + { + return FALSE; + } + + /* begin with the first function */ + fn = &DynFuncs->fn.foo; /* warning: assignment from incompatible pointer type */ + + /* load the imports */ + for(i = 0; i < Module->nFunctions; i++) + { + *fn = GetProcAddress(DynFuncs->hModule, Module->Functions[i]); + if(*fn == NULL) + { + FreeLibrary(DynFuncs->hModule); + DynFuncs->hModule = (HMODULE)0; + return FALSE; + } + fn++; + } + + return TRUE; +} + +VOID +UnloadDynamicImports(PDYN_FUNCS DynFuncs) +{ + if(DynFuncs->hModule) + { + FreeLibrary(DynFuncs->hModule); + DynFuncs->hModule = (HMODULE)0; + } +} + /* EOF */