Nach eingen Diskussionen mit hier nicht näher genannten Kollegen um das Thema File und Registry-Redirection unter 64Bit Windows habe ich mir die Frage gestellt, kann ein 32Bit-Prozess das automatische Redirecten überwinden oder nicht? Ich will die Antwort nicht vorweg nehmen, also hier das gesteckte Ziel:
"Ein 32Bit-Prozess soll einen Datei im 64Bit-Directory %systemroot%\System32 anlegen."
Unter 64Bit Windows wird das System32-Directory in einem 32Bit-Prozess, der unter der WOW64 Emulation getstartet wird, umgeleitet bzw. überblendet. Ein 64Bit Prozess sieht die Dateien aus %systemroot%\System32 ein 32Bit-Prozess hingegen die Dateien aus %systemroot%\SysWOW64. Nach einiger Einarbeitung in die SDK-Dokumentation zu WOW64 haben sich folgende APIs als Goldgrube erwiesen:
- Mit IsWow64Process kann geprüft werden ob der aufgerufene Prozess unter WOW64 läuft. Ist das nicht der fall muss es ein 64Bit-Prozess sein oder ein 32Bit auf einem 32Bit OS. GetNativeSystemInfo hilft hier weiter.
- Wow64DisableWow64FsRedirection schaltet wie der Name schon sagt das WOW64 File-Redirecting für den aufrufenden Thread aus. Zum reverten (nicht wieder einschalten, weil es ja bereits abgeschaltet gewesen sein kann) wird Wow64RevertWow64FsRedirection angeboten.
Der Ablauf um in das System32 für 64Bit Prozesse aus einem 32Bit Prozess zu schreiben sieht dann wie folgt aus:
- Prüfen ob Prozess in der WOW64 Emulation läuft
- FsRedirection ausschalten
- Jetzt kann direkt auf das System32 zugegriffen werden, ohne das der Prozess in SysWOW64 umgeleitet wird.
- FsRedirection reverten
Folgendes Beispiel demonstriert das beschriebene Verfahren:
int _tmain(int argc, _TCHAR* argv[])
{
BOOL bIsWOW64 = FALSE;
if ( IsWow64Process( GetCurrentProcess(), &bIsWOW64 ) && bIsWOW64 == TRUE )
{
LPCTSTR lpszFileToCreate = _T("C:\\windows\\system32\\wow64test.txt");
// Create the file in C:\windows\syswow64
HANDLE hFile = CreateFile( lpszFileToCreate, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
CloseHandle( hFile );
// Create the file in C:\windows\system32
PVOID pOldValue = NULL;
if ( Wow64DisableWow64FsRedirection( &pOldValue ) )
{
HANDLE hFile64 = CreateFile( lpszFileToCreate, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
CloseHandle( hFile64 );
Wow64RevertWow64FsRedirection( pOldValue );
}
}
return 0;
}