aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-06-24 12:26:42 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-06-27 11:14:21 -0500
commit6ee12a64cb75097a238e60d4fd0ea542e8312214 (patch)
tree0cd7d8637e167e8c294a107ccdb99db016f67a60
parent78b5daf01555d86293c1012ed3de704752880a6a (diff)
downloadwix-6ee12a64cb75097a238e60d4fd0ea542e8312214.tar.gz
wix-6ee12a64cb75097a238e60d4fd0ea542e8312214.tar.bz2
wix-6ee12a64cb75097a238e60d4fd0ea542e8312214.zip
Add LoadSystemApiSet.
-rw-r--r--src/libs/dutil/WixToolset.DUtil/apputil.cpp84
-rw-r--r--src/libs/dutil/WixToolset.DUtil/inc/dutil.h16
2 files changed, 87 insertions, 13 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/apputil.cpp b/src/libs/dutil/WixToolset.DUtil/apputil.cpp
index 147d1d1e..b70c8cfb 100644
--- a/src/libs/dutil/WixToolset.DUtil/apputil.cpp
+++ b/src/libs/dutil/WixToolset.DUtil/apputil.cpp
@@ -17,10 +17,13 @@
17#define AppExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_APPUTIL, e, x, s, __VA_ARGS__) 17#define AppExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_APPUTIL, e, x, s, __VA_ARGS__)
18#define AppExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_APPUTIL, g, x, s, __VA_ARGS__) 18#define AppExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_APPUTIL, g, x, s, __VA_ARGS__)
19 19
20const DWORD PRIVATE_LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800;
21typedef BOOL(WINAPI *LPFN_SETDEFAULTDLLDIRECTORIES)(DWORD); 20typedef BOOL(WINAPI *LPFN_SETDEFAULTDLLDIRECTORIES)(DWORD);
22typedef BOOL(WINAPI *LPFN_SETDLLDIRECTORYW)(LPCWSTR); 21typedef BOOL(WINAPI *LPFN_SETDLLDIRECTORYW)(LPCWSTR);
23 22
23static BOOL vfInitialized = FALSE;
24static LPFN_SETDEFAULTDLLDIRECTORIES vpfnSetDefaultDllDirectories = NULL;
25static LPFN_SETDLLDIRECTORYW vpfnSetDllDirectory = NULL;
26
24/******************************************************************** 27/********************************************************************
25EscapeCommandLineArgument - encodes wzArgument such that 28EscapeCommandLineArgument - encodes wzArgument such that
26 ::CommandLineToArgv() will parse it back unaltered. If no escaping 29 ::CommandLineToArgv() will parse it back unaltered. If no escaping
@@ -32,12 +35,48 @@ static HRESULT EscapeCommandLineArgument(
32 __out_z LPWSTR* psczEscaped 35 __out_z LPWSTR* psczEscaped
33 ); 36 );
34 37
38static void Initialize()
39{
40 HRESULT hr = S_OK;
41 HMODULE hKernel32 = NULL;
42
43 if (vfInitialized)
44 {
45 ExitFunction();
46 }
47
48 hKernel32 = ::GetModuleHandleW(L"kernel32");
49 AppExitOnNullWithLastError(hKernel32, hr, "Failed to get module handle for kernel32.");
50
51 vpfnSetDefaultDllDirectories = (LPFN_SETDEFAULTDLLDIRECTORIES)::GetProcAddress(hKernel32, "SetDefaultDllDirectories");
52 vpfnSetDllDirectory = (LPFN_SETDLLDIRECTORYW)::GetProcAddress(hKernel32, "SetDllDirectoryW");
53
54 vfInitialized = TRUE;
55
56LExit:
57 return;
58}
59
35DAPI_(HRESULT) LoadSystemLibrary( 60DAPI_(HRESULT) LoadSystemLibrary(
36 __in_z LPCWSTR wzModuleName, 61 __in_z LPCWSTR wzModuleName,
37 __out HMODULE* phModule 62 __out HMODULE* phModule
38 ) 63 )
39{ 64{
40 HRESULT hr = LoadSystemLibraryWithPath(wzModuleName, phModule, NULL); 65 HRESULT hr = S_OK;
66
67 Initialize();
68
69 if (vpfnSetDefaultDllDirectories) // LOAD_LIBRARY_SEARCH_SYSTEM32 was added at same time as SetDefaultDllDirectories.
70 {
71 *phModule = ::LoadLibraryExW(wzModuleName, NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
72 AppExitOnNullWithLastError(*phModule, hr, "Failed to get load library with LOAD_LIBRARY_SEARCH_SYSTEM32.");
73 }
74 else
75 {
76 hr = LoadSystemLibraryWithPath(wzModuleName, phModule, NULL);
77 }
78
79LExit:
41 return hr; 80 return hr;
42} 81}
43 82
@@ -63,7 +102,7 @@ DAPI_(HRESULT) LoadSystemLibraryWithPath(
63 hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName); 102 hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName);
64 AppExitOnRootFailure(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName); 103 AppExitOnRootFailure(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName);
65 104
66 *phModule = ::LoadLibraryW(wzPath); 105 *phModule = ::LoadLibraryExW(wzPath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
67 AppExitOnNullWithLastError(*phModule, hr, "Failed to load the library %ls.", wzModuleName); 106 AppExitOnNullWithLastError(*phModule, hr, "Failed to load the library %ls.", wzModuleName);
68 107
69 if (psczPath) 108 if (psczPath)
@@ -76,6 +115,31 @@ LExit:
76 return hr; 115 return hr;
77} 116}
78 117
118DAPI_(HRESULT) LoadSystemApiSet(
119 __in_z LPCWSTR wzApiSet,
120 __out HMODULE* phModule
121 )
122{
123 HRESULT hr = S_OK;
124
125 Initialize();
126
127 if (!vpfnSetDefaultDllDirectories)
128 {
129 // For many API sets, the .dll does not actually exist on disk so there's no point on even trying if SetDefaultDllDirectories is not available.
130 // On OS's where API sets are implemented, the loader requires just the API set name with .dll.
131 // It is not safe to pass such strings to LoadLibraryEx without LOAD_LIBRARY_SEARCH_SYSTEM32, which isn't available on old OS's.
132 AppExitWithRootFailure(hr, E_MODNOTFOUND, "OS doesn't support API sets.");
133 }
134 else
135 {
136 hr = LoadSystemLibrary(wzApiSet, phModule);
137 }
138
139LExit:
140 return hr;
141}
142
79DAPI_(void) AppInitialize( 143DAPI_(void) AppInitialize(
80 __in_ecount(cSafelyLoadSystemDlls) LPCWSTR rgsczSafelyLoadSystemDlls[], 144 __in_ecount(cSafelyLoadSystemDlls) LPCWSTR rgsczSafelyLoadSystemDlls[],
81 __in DWORD cSafelyLoadSystemDlls 145 __in DWORD cSafelyLoadSystemDlls
@@ -87,13 +151,12 @@ DAPI_(void) AppInitialize(
87 151
88 ::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); 152 ::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
89 153
154 Initialize();
155
90 // Best effort call to initialize default DLL directories to system only. 156 // Best effort call to initialize default DLL directories to system only.
91 HMODULE hKernel32 = ::GetModuleHandleW(L"kernel32"); 157 if (vpfnSetDefaultDllDirectories)
92 Assert(hKernel32);
93 LPFN_SETDEFAULTDLLDIRECTORIES pfnSetDefaultDllDirectories = (LPFN_SETDEFAULTDLLDIRECTORIES)::GetProcAddress(hKernel32, "SetDefaultDllDirectories");
94 if (pfnSetDefaultDllDirectories)
95 { 158 {
96 if (pfnSetDefaultDllDirectories(PRIVATE_LOAD_LIBRARY_SEARCH_SYSTEM32)) 159 if (vpfnSetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32))
97 { 160 {
98 fSetDefaultDllDirectories = TRUE; 161 fSetDefaultDllDirectories = TRUE;
99 } 162 }
@@ -109,10 +172,9 @@ DAPI_(void) AppInitialize(
109 if (!fSetDefaultDllDirectories) 172 if (!fSetDefaultDllDirectories)
110 { 173 {
111 // Remove current working directory from search order. 174 // Remove current working directory from search order.
112 LPFN_SETDLLDIRECTORYW pfnSetDllDirectory = (LPFN_SETDLLDIRECTORYW)::GetProcAddress(hKernel32, "SetDllDirectoryW"); 175 if (!vpfnSetDllDirectory || !vpfnSetDllDirectory(L""))
113 if (!pfnSetDllDirectory || !pfnSetDllDirectory(L""))
114 { 176 {
115 hr = HRESULT_FROM_WIN32(::GetLastError()); 177 hr = vpfnSetDllDirectory ? HRESULT_FROM_WIN32(::GetLastError()) : HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND);
116 TraceError(hr, "Failed to call SetDllDirectory."); 178 TraceError(hr, "Failed to call SetDllDirectory.");
117 } 179 }
118 180
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
index 4a29b66b..6f099f35 100644
--- a/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
+++ b/src/libs/dutil/WixToolset.DUtil/inc/dutil.h
@@ -207,8 +207,8 @@ extern "C" {
207// other functions 207// other functions
208 208
209/******************************************************************* 209/*******************************************************************
210 LoadSystemLibrary - Fully qualifies the path to a module in the 210 LoadSystemLibrary - Securely loads the module from the
211 Windows system directory and loads it. 211 Windows system directory.
212 212
213 Returns 213 Returns
214 E_MODNOTFOUND - The module could not be found. 214 E_MODNOTFOUND - The module could not be found.
@@ -234,6 +234,18 @@ HRESULT DAPI LoadSystemLibraryWithPath(
234 __deref_out_z_opt LPWSTR* psczPath 234 __deref_out_z_opt LPWSTR* psczPath
235 ); 235 );
236 236
237/*******************************************************************
238 LoadSystemApiSet - Securely loads the API set provided by the system.
239
240 Returns
241 E_MODNOTFOUND - The module could not be found.
242 * - Another error occured.
243********************************************************************/
244DAPI_(HRESULT) LoadSystemApiSet(
245 __in_z LPCWSTR wzApiSet,
246 __out HMODULE* phModule
247 );
248
237#ifdef __cplusplus 249#ifdef __cplusplus
238} 250}
239#endif 251#endif