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