Win32 API 日本語リファレンス
ホームStorage.FileSystem › Wow64DisableWow64FsRedirection

Wow64DisableWow64FsRedirection

関数
WOW64のファイルシステムリダイレクトを無効化し旧状態を保存する。
DLLKERNEL32.dll呼出規約winapiSetLastErrorあり対応OSWindows Vista 以降

シグネチャ

// KERNEL32.dll
#include <windows.h>

BOOL Wow64DisableWow64FsRedirection(
    void** OldValue
);

パラメーター

名前方向説明
OldValuevoid**out

WOW64 ファイルシステムリダイレクトの値です。システムはこのパラメーターを使用して、ファイルシステムリダイレクトを 元に戻す(再度有効にする)ために必要な情報を格納します。

Note この値はシステム専用です。予期しない動作を避けるため、この値をいかなる方法でも 変更しないでください。

戻り値の型: BOOL

公式ドキュメント

呼び出し元スレッドのファイルシステムリダイレクトを無効にします。ファイルシステムリダイレクトは既定で有効になっています。

戻り値

関数が成功した場合、戻り値は 0 以外の値になります。

関数が失敗した場合、戻り値は 0 になります。拡張エラー情報を取得するには、 GetLastError を呼び出します。

解説(Remarks)

この関数は、ネイティブの system32 ディレクトリへのアクセスを得たい 32 ビットアプリケーションに役立ちます。 既定では、WOW64 ファイルシステムリダイレクトは有効になっています。

Wow64DisableWow64FsRedirection/Wow64RevertWow64FsRedirection 関数の組み合わせは、 Wow64EnableWow64FsRedirection 関数の機能を置き換えるものです。

ファイルシステムリダイレクトを復元するには、 Wow64RevertWow64FsRedirection 関数を呼び出します。 Wow64DisableWow64FsRedirection 関数の成功した呼び出しごとに、対応する Wow64RevertWow64FsRedirection 関数の呼び出しが必要です。これにより、リダイレクトが再度有効になり、関連するシステムリソースが解放されることが保証されます。

Note Wow64DisableWow64FsRedirection 関数は現在のスレッドが実行するすべてのファイル操作に影響します。そのため、ファイルシステムリダイレクトを長時間無効にすると、 意図しない結果を招くことがあります。たとえば、DLL の読み込みはファイルシステムリダイレクトに依存しているため、 ファイルシステムリダイレクトを無効にすると DLL の読み込みが失敗します。また、多くの機能の実装は遅延読み込みを使用しており、 リダイレクトが無効な間は失敗します。最初の遅延読み込み操作の失敗状態は保持されるため、ファイルシステムリダイレクトを 再度有効にした後でも、その遅延読み込み関数の以降の使用は失敗します。これらの問題を避けるには、リダイレクトしてはならない 特定のファイル I/O 関数(CreateFile など)の 呼び出しの直前にファイルシステムリダイレクトを無効にし、その直後に Wow64RevertWow64FsRedirection を使用してファイルシステムリダイレクトを再度有効にしてください。
ファイルシステムリダイレクトを無効にしても、現在のスレッドが行う操作にのみ影響します。 CreateProcessAsUser などの一部の関数は、 別のスレッドで処理を行うため、呼び出し元スレッドのファイルシステムリダイレクトの状態には影響されません。

Windows 8 および Windows Server 2012 では、この関数は以下のテクノロジでサポートされています。

テクノロジ サポート状況
Server Message Block (SMB) 3.0 プロトコル いいえ
SMB 3.0 透過的フェールオーバー (TFO) いいえ
SMB 3.0 とスケールアウトファイル共有 (SO) いいえ
クラスター共有ボリュームファイルシステム (CsvFS) はい
回復性ファイルシステム (ReFS) いいえ

次の例では、Wow64DisableWow64FsRedirection を使用してファイルシステムリダイレクトを無効にし、 WOW64 上で実行されている 32 ビットアプリケーションが、%SystemRoot%\SysWOW64 の 32 ビット版に リダイレクトされる代わりに、%SystemRoot%\System32 にある 64 ビット版の Notepad.exe を開けるようにします。

#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0501

#ifdef NTDDI_VERSION
#undef NTDDI_VERSION
#endif
#define NTDDI_VERSION 0x05010000

#include <Windows.h>

void main()
{
    HANDLE hFile = INVALID_HANDLE_VALUE;
    PVOID OldValue = NULL;

    //  Disable redirection immediately prior to the native API
    //  function call.
    if( Wow64DisableWow64FsRedirection(&OldValue) ) 
    {
        //  Any function calls in this block of code should be as concise
        //  and as simple as possible to avoid unintended results.
        hFile = CreateFile(TEXT("C:\\Windows\\System32\\Notepad.exe"),
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL,
            OPEN_EXISTING,
            FILE_ATTRIBUTE_NORMAL,
            NULL);

        //  Immediately re-enable redirection. Note that any resources
        //  associated with OldValue are cleaned up by this call.
        if ( FALSE == Wow64RevertWow64FsRedirection(OldValue) )
        {
            //  Failure to re-enable redirection should be considered
            //  a critical failure and execution aborted.
            return;
        }
    }
    
    //  The handle, if valid, now can be used as usual, and without
    //  leaving redirection disabled. 
    if( INVALID_HANDLE_VALUE != hFile )  
    {
        // Use the file handle
    }
}
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// KERNEL32.dll
#include <windows.h>

BOOL Wow64DisableWow64FsRedirection(
    void** OldValue
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool Wow64DisableWow64FsRedirection(
    IntPtr OldValue   // void** out
);
<DllImport("KERNEL32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function Wow64DisableWow64FsRedirection(
    OldValue As IntPtr   ' void** out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' OldValue : void** out
Declare PtrSafe Function Wow64DisableWow64FsRedirection Lib "kernel32" ( _
    ByVal OldValue As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

Wow64DisableWow64FsRedirection = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
Wow64DisableWow64FsRedirection.restype = wintypes.BOOL
Wow64DisableWow64FsRedirection.argtypes = [
    ctypes.c_void_p,  # OldValue : void** out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
Wow64DisableWow64FsRedirection = Fiddle::Function.new(
  lib['Wow64DisableWow64FsRedirection'],
  [
    Fiddle::TYPE_VOIDP,  # OldValue : void** out
  ],
  Fiddle::TYPE_INT)
#[link(name = "kernel32")]
extern "system" {
    fn Wow64DisableWow64FsRedirection(
        OldValue: *mut *mut ()  // void** out
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", SetLastError = true)]
public static extern bool Wow64DisableWow64FsRedirection(IntPtr OldValue);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_Wow64DisableWow64FsRedirection' -Namespace Win32 -PassThru
# $api::Wow64DisableWow64FsRedirection(OldValue)
#uselib "KERNEL32.dll"
#func global Wow64DisableWow64FsRedirection "Wow64DisableWow64FsRedirection" sptr
; Wow64DisableWow64FsRedirection OldValue   ; 戻り値は stat
; OldValue : void** out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global Wow64DisableWow64FsRedirection "Wow64DisableWow64FsRedirection" sptr
; res = Wow64DisableWow64FsRedirection(OldValue)
; OldValue : void** out -> "sptr"
; BOOL Wow64DisableWow64FsRedirection(void** OldValue)
#uselib "KERNEL32.dll"
#cfunc global Wow64DisableWow64FsRedirection "Wow64DisableWow64FsRedirection" intptr
; res = Wow64DisableWow64FsRedirection(OldValue)
; OldValue : void** out -> "intptr"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procWow64DisableWow64FsRedirection = kernel32.NewProc("Wow64DisableWow64FsRedirection")
)

// OldValue (void** out)
r1, _, err := procWow64DisableWow64FsRedirection.Call(
	uintptr(OldValue),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function Wow64DisableWow64FsRedirection(
  OldValue: Pointer   // void** out
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'Wow64DisableWow64FsRedirection';
result := DllCall("KERNEL32\Wow64DisableWow64FsRedirection"
    , "Ptr", OldValue   ; void** out
    , "Int")   ; return: BOOL
●Wow64DisableWow64FsRedirection(OldValue) = DLL("KERNEL32.dll", "bool Wow64DisableWow64FsRedirection(void*)")
# 呼び出し: Wow64DisableWow64FsRedirection(OldValue)
# OldValue : void** out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "kernel32" fn Wow64DisableWow64FsRedirection(
    OldValue: ?*anyopaque // void** out
) callconv(std.os.windows.WINAPI) i32;
proc Wow64DisableWow64FsRedirection(
    OldValue: pointer  # void** out
): int32 {.importc: "Wow64DisableWow64FsRedirection", stdcall, dynlib: "KERNEL32.dll".}
pragma(lib, "kernel32");
extern(Windows)
int Wow64DisableWow64FsRedirection(
    void** OldValue   // void** out
);
ccall((:Wow64DisableWow64FsRedirection, "KERNEL32.dll"), stdcall, Int32,
      (Ptr{Cvoid},),
      OldValue)
# OldValue : void** out -> Ptr{Cvoid}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t Wow64DisableWow64FsRedirection(
    void** OldValue);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.Wow64DisableWow64FsRedirection(OldValue)
-- OldValue : void** out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const Wow64DisableWow64FsRedirection = lib.func('__stdcall', 'Wow64DisableWow64FsRedirection', 'int32_t', ['void *']);
// Wow64DisableWow64FsRedirection(OldValue)
// OldValue : void** out -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  Wow64DisableWow64FsRedirection: { parameters: ["pointer"], result: "i32" },
});
// lib.symbols.Wow64DisableWow64FsRedirection(OldValue)
// OldValue : void** out -> "pointer"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t Wow64DisableWow64FsRedirection(
    void** OldValue);
C, "KERNEL32.dll");
// $ffi->Wow64DisableWow64FsRedirection(OldValue);
// OldValue : void** out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Kernel32 extends StdCallLibrary {
    Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class);
    boolean Wow64DisableWow64FsRedirection(
        Pointer OldValue   // void** out
    );
}
@[Link("kernel32")]
lib LibKERNEL32
  fun Wow64DisableWow64FsRedirection = Wow64DisableWow64FsRedirection(
    OldValue : Void**   # void** out
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef Wow64DisableWow64FsRedirectionNative = Int32 Function(Pointer<Void>);
typedef Wow64DisableWow64FsRedirectionDart = int Function(Pointer<Void>);
final Wow64DisableWow64FsRedirection = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<Wow64DisableWow64FsRedirectionNative, Wow64DisableWow64FsRedirectionDart>('Wow64DisableWow64FsRedirection');
// OldValue : void** out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function Wow64DisableWow64FsRedirection(
  OldValue: Pointer   // void** out
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'Wow64DisableWow64FsRedirection';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "Wow64DisableWow64FsRedirection"
  c_Wow64DisableWow64FsRedirection :: Ptr () -> IO CInt
-- OldValue : void** out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let wow64disablewow64fsredirection =
  foreign "Wow64DisableWow64FsRedirection"
    ((ptr void) @-> returning int32_t)
(* OldValue : void** out -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("Wow64DisableWow64FsRedirection" wow64-disable-wow64-fs-redirection :convention :stdcall) :int32
  (old-value :pointer))   ; void** out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $Wow64DisableWow64FsRedirection = Win32::API::More->new('KERNEL32',
    'BOOL Wow64DisableWow64FsRedirection(LPVOID OldValue)');
# my $ret = $Wow64DisableWow64FsRedirection->Call($OldValue);
# OldValue : void** out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目