그냥 사는 이야기

Wow64 redirection 해제(x64) 본문

Development/System

Wow64 redirection 해제(x64)

없다캐라 2010. 1. 27. 18:01
반응형

Sys 파일 로딩 실패

우리 제품 중 Windows Server 2003 x64에서 driver파일 로딩에서 에러가 발생하였다.

::LoadLibraryEx("C:\\WINDOWS\\System32\\drivers\\acpi.sys", 0, LOAD_LIBRARY_AS_DATAFILE);

실패한 함수는 LoadLibraryEx()였고 GetLastError()에서 파일이 존재하지 않는다고 알려준다. 하지만 저 경로에 acpi.sys 파일은 분명 있다. Wow64 지원을 위해 저 경로를 SysWow64 경로로 돌려버리는 redirection 때문에 발생하였다.

간단히 이 코드로 테스트 해보면 알 수 있다.

if( 0 == _waccess_s(_T("C:\\WINDOWS\\System32\\drivers\\acpi.sys"), 0) )
{
    printf("exist\n");
}

해결책

이것을 해결하기 위해서는 Wow64DisableWow64FsRedirection으로 redirection을 잠시 꺼두고 sys파일을 로드한 후 다시 revert 해주면 된다.

if( Wow64DisableWow64FsRedirection(&OldValue) ) 
{
    if( 0 == _waccess_s(_T("C:\\WINDOWS\\System32\\drivers\\acpi.sys"), 0) )
    {
        printf("exist\n");
    }


    if ( FALSE == Wow64RevertWow64FsRedirection(OldValue) )
    {
        printf("Wow64RevertWow64FsRedirection failed\n");
    }
}

System32를 가리킬 땐 SysWow64로 가지 않고 System32로 접근이 가능해진다.

레거시 OS

여기서 주의할 점으로는 Wow64DisableWow64FsRedirection()와 Wow64RevertWow64FsRedirection()은 최소 사용 가능 OS 버전이 Windows XP x64부터이다.

그럼 XP x86은? 그래서 위의 예처럼 직접적으로 사용하지 않고 kernel32에서 load 하여 모듈에서 function을 가져와서 사용한다. 조금 더 안정적으로 사용하려면,

...
BOOL bDisabledRedirection = FALSE;
typedef BOOL (WINAPI * LPWOW64FSREDIRECTION)(PVOID *);
...
{
    LPWOW64FSREDIRECTION lpfWow64DisableWow64FsRedirection = NULL;

    HMODULE hModule = LoadLibrary( _T("kernel32.dll") );

    if (hModule)
    {
        lpfWow64DisableWow64FsRedirection = 
            (LPWOW64FSREDIRECTION)GetProcAddress(hModule, "Wow64DisableWow64FsRedirection");

        if (lpfWow64DisableWow64FsRedirection)
        {
            bDisabledRedirection = (*lpfWow64DisableWow64FsRedirection)(&old_value);
        }

        FreeLibrary(hModule);
    }
}

위와 같은 형태로 사용하면 된다.

Comments