diff options
Diffstat (limited to 'src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp')
-rw-r--r-- | src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp b/src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp new file mode 100644 index 00000000..8174c43e --- /dev/null +++ b/src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp | |||
@@ -0,0 +1,169 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | #include "precomp.h" | ||
4 | |||
5 | static HMODULE s_hKernel32; | ||
6 | static BOOL s_fWow64Initialized; | ||
7 | static BOOL (*s_pfnDisableWow64)(__out PVOID* ); | ||
8 | static BOOL (*s_pfnRevertWow64)(__in PVOID ); | ||
9 | static BOOL (*s_pfnIsWow64Process) (HANDLE, PBOOL); | ||
10 | static PVOID s_Wow64FSRevertState; | ||
11 | static BOOL s_fWow64FSDisabled; | ||
12 | |||
13 | /******************************************************************** | ||
14 | WcaInitializeWow64() - Initializes the Wow64 API | ||
15 | |||
16 | ********************************************************************/ | ||
17 | extern "C" HRESULT WIXAPI WcaInitializeWow64() | ||
18 | { | ||
19 | AssertSz(WcaIsInitialized(), "WcaInitialize() should be called before calling WcaInitializeWow64()"); | ||
20 | AssertSz(!WcaIsWow64Initialized(), "WcaInitializeWow64() should not be called twice without calling WcaFinalizeWow64()"); | ||
21 | |||
22 | s_fWow64Initialized = FALSE; | ||
23 | HRESULT hr = S_OK; | ||
24 | s_Wow64FSRevertState = NULL; | ||
25 | s_fWow64FSDisabled = false; | ||
26 | |||
27 | // Test if we have access to the Wow64 API, and store the result in bWow64APIPresent | ||
28 | s_hKernel32 = ::GetModuleHandleW(L"kernel32.dll"); | ||
29 | if (!s_hKernel32) | ||
30 | { | ||
31 | ExitWithLastError(hr, "failed to get handle to kernel32.dll"); | ||
32 | } | ||
33 | |||
34 | // This will test if we have access to the Wow64 API | ||
35 | s_pfnIsWow64Process = (BOOL (*)(HANDLE, PBOOL))::GetProcAddress(s_hKernel32, "IsWow64Process"); | ||
36 | if (NULL != s_pfnIsWow64Process) | ||
37 | { | ||
38 | s_pfnDisableWow64 = (BOOL (*)(PVOID *))::GetProcAddress(s_hKernel32, "Wow64DisableWow64FsRedirection"); | ||
39 | // If we fail, log the error but proceed, because we may not need a particular function, or the Wow64 API at all | ||
40 | if (!s_pfnDisableWow64) | ||
41 | { | ||
42 | return S_FALSE; | ||
43 | } | ||
44 | |||
45 | s_pfnRevertWow64 = (BOOL (*)(PVOID))::GetProcAddress(s_hKernel32, "Wow64RevertWow64FsRedirection"); | ||
46 | if (!s_pfnRevertWow64) | ||
47 | { | ||
48 | return S_FALSE; | ||
49 | } | ||
50 | |||
51 | if (s_pfnDisableWow64 && s_pfnRevertWow64) | ||
52 | { | ||
53 | s_fWow64Initialized = TRUE; | ||
54 | } | ||
55 | } | ||
56 | else | ||
57 | { | ||
58 | return S_FALSE; | ||
59 | } | ||
60 | |||
61 | LExit: | ||
62 | |||
63 | return hr; | ||
64 | } | ||
65 | |||
66 | /******************************************************************** | ||
67 | WcaIsWow64Process() - determines if the current process is running | ||
68 | in WOW | ||
69 | |||
70 | ********************************************************************/ | ||
71 | extern "C" BOOL WIXAPI WcaIsWow64Process() | ||
72 | { | ||
73 | BOOL fIsWow64Process = FALSE; | ||
74 | if (s_fWow64Initialized) | ||
75 | { | ||
76 | if (!s_pfnIsWow64Process(GetCurrentProcess(), &fIsWow64Process)) | ||
77 | { | ||
78 | // clear out the value since call failed | ||
79 | fIsWow64Process = FALSE; | ||
80 | } | ||
81 | } | ||
82 | return fIsWow64Process; | ||
83 | } | ||
84 | |||
85 | /******************************************************************** | ||
86 | WcaIsWow64Initialized() - determines if WcaInitializeWow64() has | ||
87 | been successfully called | ||
88 | |||
89 | ********************************************************************/ | ||
90 | extern "C" BOOL WIXAPI WcaIsWow64Initialized() | ||
91 | { | ||
92 | return s_fWow64Initialized; | ||
93 | } | ||
94 | |||
95 | /******************************************************************** | ||
96 | WcaDisableWow64FSRedirection() - Disables Wow64 FS Redirection | ||
97 | |||
98 | ********************************************************************/ | ||
99 | extern "C" HRESULT WIXAPI WcaDisableWow64FSRedirection() | ||
100 | { | ||
101 | AssertSz(s_fWow64Initialized && s_pfnDisableWow64 != NULL, "WcaDisableWow64FSRedirection() called, but Wow64 API was not initialized"); | ||
102 | |||
103 | #ifdef DEBUG | ||
104 | AssertSz(!s_fWow64FSDisabled, "You must call WcaRevertWow64FSRedirection() before calling WcaDisableWow64FSRedirection() again"); | ||
105 | #endif | ||
106 | |||
107 | HRESULT hr = S_OK; | ||
108 | if (s_pfnDisableWow64(&s_Wow64FSRevertState)) | ||
109 | { | ||
110 | s_fWow64FSDisabled = TRUE; | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | ExitWithLastError(hr, "Failed to disable WOW64."); | ||
115 | } | ||
116 | |||
117 | LExit: | ||
118 | return hr; | ||
119 | } | ||
120 | |||
121 | /******************************************************************** | ||
122 | WcaRevertWow64FSRedirection() - Reverts Wow64 FS Redirection to its | ||
123 | pre-disabled state | ||
124 | |||
125 | ********************************************************************/ | ||
126 | extern "C" HRESULT WIXAPI WcaRevertWow64FSRedirection() | ||
127 | { | ||
128 | AssertSz(s_fWow64Initialized && s_pfnDisableWow64 != NULL, "WcaRevertWow64FSRedirection() called, but Wow64 API was not initialized"); | ||
129 | |||
130 | #ifdef DEBUG | ||
131 | AssertSz(s_fWow64FSDisabled, "You must call WcaDisableWow64FSRedirection() before calling WcaRevertWow64FSRedirection()"); | ||
132 | #endif | ||
133 | |||
134 | HRESULT hr = S_OK; | ||
135 | if (s_pfnRevertWow64(s_Wow64FSRevertState)) | ||
136 | { | ||
137 | s_fWow64FSDisabled = FALSE; | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | ExitWithLastError(hr, "Failed to revert WOW64."); | ||
142 | } | ||
143 | |||
144 | LExit: | ||
145 | return hr; | ||
146 | } | ||
147 | |||
148 | /******************************************************************** | ||
149 | WcaFinalizeWow64() - Cleans up after Wow64 API Initialization | ||
150 | |||
151 | ********************************************************************/ | ||
152 | extern "C" HRESULT WIXAPI WcaFinalizeWow64() | ||
153 | { | ||
154 | if (s_fWow64FSDisabled) | ||
155 | { | ||
156 | #ifdef DEBUG | ||
157 | AssertSz(FALSE, "WcaFinalizeWow64() called while Filesystem redirection was disabled."); | ||
158 | #else | ||
159 | // If we aren't in debug mode, let's do our best to recover gracefully | ||
160 | WcaRevertWow64FSRedirection(); | ||
161 | #endif | ||
162 | } | ||
163 | |||
164 | s_fWow64Initialized = FALSE; | ||
165 | s_pfnDisableWow64 = NULL; | ||
166 | s_pfnRevertWow64 = NULL; | ||
167 | |||
168 | return S_OK; | ||
169 | } | ||