aboutsummaryrefslogtreecommitdiff
path: root/src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp')
-rw-r--r--src/libs/wcautil/WixToolset.WcaUtil/wcawow64.cpp169
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
5static HMODULE s_hKernel32;
6static BOOL s_fWow64Initialized;
7static BOOL (*s_pfnDisableWow64)(__out PVOID* );
8static BOOL (*s_pfnRevertWow64)(__in PVOID );
9static BOOL (*s_pfnIsWow64Process) (HANDLE, PBOOL);
10static PVOID s_Wow64FSRevertState;
11static BOOL s_fWow64FSDisabled;
12
13/********************************************************************
14 WcaInitializeWow64() - Initializes the Wow64 API
15
16********************************************************************/
17extern "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
61LExit:
62
63 return hr;
64}
65
66/********************************************************************
67 WcaIsWow64Process() - determines if the current process is running
68 in WOW
69
70********************************************************************/
71extern "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********************************************************************/
90extern "C" BOOL WIXAPI WcaIsWow64Initialized()
91{
92 return s_fWow64Initialized;
93}
94
95/********************************************************************
96 WcaDisableWow64FSRedirection() - Disables Wow64 FS Redirection
97
98********************************************************************/
99extern "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
117LExit:
118 return hr;
119}
120
121/********************************************************************
122 WcaRevertWow64FSRedirection() - Reverts Wow64 FS Redirection to its
123 pre-disabled state
124
125********************************************************************/
126extern "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
144LExit:
145 return hr;
146}
147
148/********************************************************************
149 WcaFinalizeWow64() - Cleans up after Wow64 API Initialization
150
151********************************************************************/
152extern "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}