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

ReOpenFile

関数
既存のファイルハンドルを別のアクセス権で再オープンする。
DLLKERNEL32.dll呼出規約winapiSetLastErrorあり対応OSWindows Vista 以降

シグネチャ

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

HANDLE ReOpenFile(
    HANDLE hOriginalFile,
    DWORD dwDesiredAccess,
    FILE_SHARE_MODE dwShareMode,
    FILE_FLAGS_AND_ATTRIBUTES dwFlagsAndAttributes
);

パラメーター

名前方向説明
hOriginalFileHANDLEin再オープンするオブジェクトへのハンドル。オブジェクトは CreateFile 関数によって作成されたものである必要があります。
dwDesiredAccessDWORDin

オブジェクトに対して要求するアクセス権。値の一覧については、 File Security and Access Rights を参照してください。ハンドルがまだ開いている以前のオープン要求で指定された共有モードと競合するアクセスモードを要求することはできません。

このパラメーターがゼロ (0) の場合、アプリケーションはデバイスにアクセスせずにデバイス属性を照会できます。これは、ドライブにフロッピーを入れずに、フロッピーディスクドライブのサイズやサポートするフォーマットを判別したい場合に便利です。

dwShareModeFILE_SHARE_MODEin

オブジェクトの共有モード。ハンドルがまだ開いている以前のオープン要求で指定されたアクセスモードと競合する共有モードを要求することはできません。

このパラメーターがゼロ (0) で CreateFile が成功した場合、オブジェクトは共有できず、ハンドルが閉じられるまで再びオープンすることはできません。

プロセスがオブジェクトを開いている間に他のプロセスとオブジェクトを共有できるようにするには、次の値を1つ以上組み合わせて、他のプロセスがオブジェクトを開く際に要求できるアクセスの種類を指定します。これらの共有オプションは、オブジェクトへのハンドルを閉じるまで有効です。

意味
FILE_SHARE_DELETE
0x00000004
以降のオブジェクトに対するオープン操作で、削除アクセスを要求できるようにします。これを指定しない場合、他のプロセスが削除アクセスを要求してオブジェクトを開くことはできません。

オブジェクトが既に削除アクセスで開かれている場合、共有モードにこのフラグを含める必要があります。

FILE_SHARE_READ
0x00000001
以降のオブジェクトに対するオープン操作で、読み取りアクセスを要求できるようにします。これを指定しない場合、他のプロセスが読み取りアクセスを要求してオブジェクトを開くことはできません。

オブジェクトが既に読み取りアクセスで開かれている場合、共有モードにこのフラグを含める必要があります。

FILE_SHARE_WRITE
0x00000002
以降のオブジェクトに対するオープン操作で、書き込みアクセスを要求できるようにします。これを指定しない場合、他のプロセスが書き込みアクセスを要求してオブジェクトを開くことはできません。

オブジェクトが既に書き込みアクセスで開かれている場合、共有モードにこのフラグを含める必要があります。

dwFlagsAndAttributesFILE_FLAGS_AND_ATTRIBUTESin

ファイルフラグ。このパラメーターには、次の値を1つ以上指定できます。

意味
FILE_FLAG_BACKUP_SEMANTICS
0x02000000
ファイルがバックアップまたは復元操作のために開かれる、または作成されることを示します。呼び出し元プロセスが SE_BACKUP_NAME および SE_RESTORE_NAME 特権を持っている場合、システムはそのプロセスがファイルのセキュリティチェックを上書きできるようにします。詳細については、 Changing Privileges in a Token を参照してください。

このフラグは、ディレクトリへのハンドルを取得するために設定することもできます。指定されている箇所では、ディレクトリハンドルをファイルハンドルの代わりに一部の関数へ渡すことができます。

FILE_FLAG_DELETE_ON_CLOSE
0x04000000
指定したハンドルだけでなく、その他の開いているハンドルや複製されたハンドルも含め、ファイルのすべてのハンドルが閉じられた直後に、オペレーティングシステムがファイルを削除することを示します。

FILE_SHARE_DELETE が使用されていない限り、以降のファイルに対するオープン要求は失敗します。

FILE_FLAG_NO_BUFFERING
0x20000000
中間バッファリングやキャッシュを行わずにファイルを開くようシステムに指示します。 FILE_FLAG_OVERLAPPED と組み合わせると、I/O がメモリマネージャーの同期操作に依存しないため、最大の非同期パフォーマンスが得られます。ただし、データがキャッシュに保持されないため、一部の I/O 操作には時間がかかります。

FILE_FLAG_NO_BUFFERING で開いたファイルを扱う場合、アプリケーションは次の要件を満たす必要があります。

  • ファイルアクセスは、ファイル内でボリュームのセクターサイズの整数倍となるバイトオフセットから開始する必要があります。
  • ファイルアクセスは、ボリュームのセクターサイズの整数倍となるバイト数で行う必要があります。たとえば、セクターサイズが 512 バイトの場合、アプリケーションは 512、1024、1536、2048 バイトの読み書きを要求できますが、335、981、7171 バイトの読み書きは要求できません。
  • 読み書き操作のバッファアドレスは、セクター境界に揃える(ボリュームのセクターサイズの整数倍となるメモリアドレスに揃える)必要があります。ディスクによっては、この要件が強制されない場合があります。
バッファをボリュームのセクターサイズの整数倍に揃える方法の1つは、 VirtualAlloc を使用してバッファを割り当てることです。この関数は、オペレーティングシステムのメモリページサイズの整数倍となるアドレスに揃えてメモリを割り当てます。メモリページサイズもボリュームセクターサイズもどちらも2のべき乗であるため、このメモリはボリュームセクターサイズの整数倍となるアドレスにも揃えられます。メモリページのサイズは 4〜8 KB であり、セクターは 512 バイト(ハードディスク)または 2048 バイト(CD)です。したがって、ボリュームセクターがメモリページより大きくなることはありません。

アプリケーションは、 GetDiskFreeSpace 関数を呼び出すことで、ボリュームのセクターサイズを判別できます。

FILE_FLAG_OPEN_NO_RECALL
0x00100000
ファイルデータが要求されているものの、データはリモートストレージに留めておくべきであることを示します。ローカルストレージへ戻すべきではありません。このフラグはリモートストレージシステムでの使用を想定しています。
FILE_FLAG_OPEN_REPARSE_POINT
0x00200000
このフラグを使用すると、通常の reparse point 処理は行われず、ReOpenFile はリパースポイント自体を開こうとします。ファイルが開かれると、リパースポイントを制御するフィルターが動作しているかどうかにかかわらず、ファイルハンドルが返されます。このフラグは CREATE_ALWAYS フラグと併用できません。ファイルがリパースポイントでない場合、このフラグは無視されます。
FILE_FLAG_OVERLAPPED
0x40000000
処理に相当の時間がかかる操作が ERROR_IO_PENDING を返すようにオブジェクトを初期化するようシステムに指示します。操作が完了すると、指定されたイベントがシグナル状態に設定されます。

FILE_FLAG_OVERLAPPED を指定する場合、ファイルの読み書き関数は OVERLAPPED 構造体を 必ず 指定する必要があります。つまり、 FILE_FLAG_OVERLAPPED が指定されている場合、アプリケーションは 必ず オーバーラップ読み書きを実行する必要があります。

FILE_FLAG_OVERLAPPED が指定されている場合、システムはファイルポインターを保持しません。ファイル位置は、ファイルの読み書き関数へ lpOverlapped パラメーター(OVERLAPPED 構造体を指す)の一部として渡す必要があります。

このフラグにより、1つのハンドルで複数の操作を同時に実行することも可能になります(たとえば、読み取りと書き込みの同時操作)。

FILE_FLAG_POSIX_SEMANTICS
0x01000000
ファイルが POSIX の規則に従ってアクセスされることを示します。これには、そのような命名をサポートするファイルシステムにおいて、大文字小文字の違いだけが異なる複数のファイル名を許可することが含まれます。このオプションを使用するときは注意してください。このフラグを付けて作成されたファイルは、MS-DOS や 16 ビット Windows 向けに記述されたアプリケーションからはアクセスできない場合があります。
FILE_FLAG_RANDOM_ACCESS
0x10000000
ファイルがランダムにアクセスされることを示します。システムはこれをファイルキャッシュ最適化のヒントとして使用できます。
FILE_FLAG_SEQUENTIAL_SCAN
0x08000000
ファイルが先頭から末尾へ順次アクセスされることを示します。システムはこれをファイルキャッシュ最適化のヒントとして使用できます。アプリケーションがランダムアクセスのためにファイルポインターを移動すると、最適なキャッシュが行われない場合がありますが、正しい動作は引き続き保証されます。

このフラグを指定すると、順次アクセスで大きなファイルを読み取るアプリケーションのパフォーマンスが向上することがあります。大きなファイルをおおむね順次に読み取りつつ、時折わずかなバイト範囲をスキップするアプリケーションでは、さらに顕著なパフォーマンス向上が得られる場合があります。

FILE_FLAG_WRITE_THROUGH
0x80000000
中間キャッシュを介さずにディスクへ直接書き込むようシステムに指示します。システムは書き込み操作をキャッシュすることはできますが、遅延フラッシュを行うことはできません。

ハンドルが名前付きパイプのクライアント側を表す場合、dwFlags パラメーターには Security Quality of Service 情報を含めることもできます。詳細については、 Impersonation Levels を参照してください。呼び出し元アプリケーションが SECURITY_SQOS_PRESENT フラグを指定する場合、dwFlags パラメーターには次の値を1つ以上含めることができます。

意味
SECURITY_ANONYMOUS
Anonymous(匿名)偽装レベルでクライアントを偽装します。
SECURITY_CONTEXT_TRACKING
セキュリティ追跡モードを動的にします。このフラグを指定しない場合、セキュリティ追跡モードは静的になります。
SECURITY_DELEGATION
Delegation(委任)偽装レベルでクライアントを偽装します。
SECURITY_EFFECTIVE_ONLY
クライアントセキュリティコンテキストのうち、有効になっている側面のみがサーバーで利用可能になります。このフラグを指定しない場合、クライアントセキュリティコンテキストのすべての側面が利用可能になります。

これにより、クライアントは、サーバーがクライアントを偽装する際に使用できるグループや特権を制限できます。

SECURITY_IDENTIFICATION
Identification(識別)偽装レベルでクライアントを偽装します。
SECURITY_IMPERSONATION
Impersonation(偽装)偽装レベルでクライアントを偽装します。

戻り値の型: HANDLE

公式ドキュメント

指定したファイルシステムオブジェクトを、異なるアクセス権、共有モード、フラグで再オープンします。

戻り値

関数が成功した場合、戻り値は指定したファイルへの開いているハンドルです。

関数が失敗した場合、戻り値は INVALID_HANDLE_VALUE です。拡張エラー情報を取得するには、GetLastError を呼び出してください。

解説(Remarks)

dwFlags パラメーターには、ファイル属性フラグ(FILE_ATTRIBUTE_*)を一切含めることはできません。これらはファイルの作成時にのみ指定できます。

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

テクノロジ サポート
Server Message Block (SMB) 3.0 プロトコル はい
SMB 3.0 Transparent Failover (TFO) はい
SMB 3.0 with Scale-out File Shares (SO) はい
Cluster Shared Volume File System (CsvFS) はい
Resilient File System (ReFS) はい
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

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

HANDLE ReOpenFile(
    HANDLE hOriginalFile,
    DWORD dwDesiredAccess,
    FILE_SHARE_MODE dwShareMode,
    FILE_FLAGS_AND_ATTRIBUTES dwFlagsAndAttributes
);
[DllImport("KERNEL32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr ReOpenFile(
    IntPtr hOriginalFile,   // HANDLE
    uint dwDesiredAccess,   // DWORD
    uint dwShareMode,   // FILE_SHARE_MODE
    uint dwFlagsAndAttributes   // FILE_FLAGS_AND_ATTRIBUTES
);
<DllImport("KERNEL32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function ReOpenFile(
    hOriginalFile As IntPtr,   ' HANDLE
    dwDesiredAccess As UInteger,   ' DWORD
    dwShareMode As UInteger,   ' FILE_SHARE_MODE
    dwFlagsAndAttributes As UInteger   ' FILE_FLAGS_AND_ATTRIBUTES
) As IntPtr
End Function
' hOriginalFile : HANDLE
' dwDesiredAccess : DWORD
' dwShareMode : FILE_SHARE_MODE
' dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES
Declare PtrSafe Function ReOpenFile Lib "kernel32" ( _
    ByVal hOriginalFile As LongPtr, _
    ByVal dwDesiredAccess As Long, _
    ByVal dwShareMode As Long, _
    ByVal dwFlagsAndAttributes As Long) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

ReOpenFile = ctypes.windll.kernel32.ReOpenFile
ReOpenFile.restype = ctypes.c_void_p
ReOpenFile.argtypes = [
    wintypes.HANDLE,  # hOriginalFile : HANDLE
    wintypes.DWORD,  # dwDesiredAccess : DWORD
    wintypes.DWORD,  # dwShareMode : FILE_SHARE_MODE
    wintypes.DWORD,  # dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
ReOpenFile = Fiddle::Function.new(
  lib['ReOpenFile'],
  [
    Fiddle::TYPE_VOIDP,  # hOriginalFile : HANDLE
    -Fiddle::TYPE_INT,  # dwDesiredAccess : DWORD
    -Fiddle::TYPE_INT,  # dwShareMode : FILE_SHARE_MODE
    -Fiddle::TYPE_INT,  # dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES
  ],
  Fiddle::TYPE_VOIDP)
#[link(name = "kernel32")]
extern "system" {
    fn ReOpenFile(
        hOriginalFile: *mut core::ffi::c_void,  // HANDLE
        dwDesiredAccess: u32,  // DWORD
        dwShareMode: u32,  // FILE_SHARE_MODE
        dwFlagsAndAttributes: u32  // FILE_FLAGS_AND_ATTRIBUTES
    ) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("KERNEL32.dll", SetLastError = true)]
public static extern IntPtr ReOpenFile(IntPtr hOriginalFile, uint dwDesiredAccess, uint dwShareMode, uint dwFlagsAndAttributes);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_ReOpenFile' -Namespace Win32 -PassThru
# $api::ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
#uselib "KERNEL32.dll"
#func global ReOpenFile "ReOpenFile" sptr, sptr, sptr, sptr
; ReOpenFile hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes   ; 戻り値は stat
; hOriginalFile : HANDLE -> "sptr"
; dwDesiredAccess : DWORD -> "sptr"
; dwShareMode : FILE_SHARE_MODE -> "sptr"
; dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global ReOpenFile "ReOpenFile" sptr, int, int, int
; res = ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
; hOriginalFile : HANDLE -> "sptr"
; dwDesiredAccess : DWORD -> "int"
; dwShareMode : FILE_SHARE_MODE -> "int"
; dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "int"
; HANDLE ReOpenFile(HANDLE hOriginalFile, DWORD dwDesiredAccess, FILE_SHARE_MODE dwShareMode, FILE_FLAGS_AND_ATTRIBUTES dwFlagsAndAttributes)
#uselib "KERNEL32.dll"
#cfunc global ReOpenFile "ReOpenFile" intptr, int, int, int
; res = ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
; hOriginalFile : HANDLE -> "intptr"
; dwDesiredAccess : DWORD -> "int"
; dwShareMode : FILE_SHARE_MODE -> "int"
; dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "int"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procReOpenFile = kernel32.NewProc("ReOpenFile")
)

// hOriginalFile (HANDLE), dwDesiredAccess (DWORD), dwShareMode (FILE_SHARE_MODE), dwFlagsAndAttributes (FILE_FLAGS_AND_ATTRIBUTES)
r1, _, err := procReOpenFile.Call(
	uintptr(hOriginalFile),
	uintptr(dwDesiredAccess),
	uintptr(dwShareMode),
	uintptr(dwFlagsAndAttributes),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HANDLE
function ReOpenFile(
  hOriginalFile: THandle;   // HANDLE
  dwDesiredAccess: DWORD;   // DWORD
  dwShareMode: DWORD;   // FILE_SHARE_MODE
  dwFlagsAndAttributes: DWORD   // FILE_FLAGS_AND_ATTRIBUTES
): THandle; stdcall;
  external 'KERNEL32.dll' name 'ReOpenFile';
result := DllCall("KERNEL32\ReOpenFile"
    , "Ptr", hOriginalFile   ; HANDLE
    , "UInt", dwDesiredAccess   ; DWORD
    , "UInt", dwShareMode   ; FILE_SHARE_MODE
    , "UInt", dwFlagsAndAttributes   ; FILE_FLAGS_AND_ATTRIBUTES
    , "Ptr")   ; return: HANDLE
●ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes) = DLL("KERNEL32.dll", "void* ReOpenFile(void*, dword, dword, dword)")
# 呼び出し: ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
# hOriginalFile : HANDLE -> "void*"
# dwDesiredAccess : DWORD -> "dword"
# dwShareMode : FILE_SHARE_MODE -> "dword"
# dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "kernel32" fn ReOpenFile(
    hOriginalFile: ?*anyopaque, // HANDLE
    dwDesiredAccess: u32, // DWORD
    dwShareMode: u32, // FILE_SHARE_MODE
    dwFlagsAndAttributes: u32 // FILE_FLAGS_AND_ATTRIBUTES
) callconv(std.os.windows.WINAPI) ?*anyopaque;
proc ReOpenFile(
    hOriginalFile: pointer,  # HANDLE
    dwDesiredAccess: uint32,  # DWORD
    dwShareMode: uint32,  # FILE_SHARE_MODE
    dwFlagsAndAttributes: uint32  # FILE_FLAGS_AND_ATTRIBUTES
): pointer {.importc: "ReOpenFile", stdcall, dynlib: "KERNEL32.dll".}
pragma(lib, "kernel32");
extern(Windows)
void* ReOpenFile(
    void* hOriginalFile,   // HANDLE
    uint dwDesiredAccess,   // DWORD
    uint dwShareMode,   // FILE_SHARE_MODE
    uint dwFlagsAndAttributes   // FILE_FLAGS_AND_ATTRIBUTES
);
ccall((:ReOpenFile, "KERNEL32.dll"), stdcall, Ptr{Cvoid},
      (Ptr{Cvoid}, UInt32, UInt32, UInt32),
      hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
# hOriginalFile : HANDLE -> Ptr{Cvoid}
# dwDesiredAccess : DWORD -> UInt32
# dwShareMode : FILE_SHARE_MODE -> UInt32
# dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
void* ReOpenFile(
    void* hOriginalFile,
    uint32_t dwDesiredAccess,
    uint32_t dwShareMode,
    uint32_t dwFlagsAndAttributes);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
-- hOriginalFile : HANDLE
-- dwDesiredAccess : DWORD
-- dwShareMode : FILE_SHARE_MODE
-- dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const ReOpenFile = lib.func('__stdcall', 'ReOpenFile', 'void *', ['void *', 'uint32_t', 'uint32_t', 'uint32_t']);
// ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
// hOriginalFile : HANDLE -> 'void *'
// dwDesiredAccess : DWORD -> 'uint32_t'
// dwShareMode : FILE_SHARE_MODE -> 'uint32_t'
// dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  ReOpenFile: { parameters: ["pointer", "u32", "u32", "u32"], result: "pointer" },
});
// lib.symbols.ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes)
// hOriginalFile : HANDLE -> "pointer"
// dwDesiredAccess : DWORD -> "u32"
// dwShareMode : FILE_SHARE_MODE -> "u32"
// dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> "u32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
void* ReOpenFile(
    void* hOriginalFile,
    uint32_t dwDesiredAccess,
    uint32_t dwShareMode,
    uint32_t dwFlagsAndAttributes);
C, "KERNEL32.dll");
// $ffi->ReOpenFile(hOriginalFile, dwDesiredAccess, dwShareMode, dwFlagsAndAttributes);
// hOriginalFile : HANDLE
// dwDesiredAccess : DWORD
// dwShareMode : FILE_SHARE_MODE
// dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES
// 構造体/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);
    Pointer ReOpenFile(
        Pointer hOriginalFile,   // HANDLE
        int dwDesiredAccess,   // DWORD
        int dwShareMode,   // FILE_SHARE_MODE
        int dwFlagsAndAttributes   // FILE_FLAGS_AND_ATTRIBUTES
    );
}
@[Link("kernel32")]
lib LibKERNEL32
  fun ReOpenFile = ReOpenFile(
    hOriginalFile : Void*,   # HANDLE
    dwDesiredAccess : UInt32,   # DWORD
    dwShareMode : UInt32,   # FILE_SHARE_MODE
    dwFlagsAndAttributes : UInt32   # FILE_FLAGS_AND_ATTRIBUTES
  ) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef ReOpenFileNative = Pointer<Void> Function(Pointer<Void>, Uint32, Uint32, Uint32);
typedef ReOpenFileDart = Pointer<Void> Function(Pointer<Void>, int, int, int);
final ReOpenFile = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<ReOpenFileNative, ReOpenFileDart>('ReOpenFile');
// hOriginalFile : HANDLE -> Pointer<Void>
// dwDesiredAccess : DWORD -> Uint32
// dwShareMode : FILE_SHARE_MODE -> Uint32
// dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function ReOpenFile(
  hOriginalFile: THandle;   // HANDLE
  dwDesiredAccess: DWORD;   // DWORD
  dwShareMode: DWORD;   // FILE_SHARE_MODE
  dwFlagsAndAttributes: DWORD   // FILE_FLAGS_AND_ATTRIBUTES
): THandle; stdcall;
  external 'KERNEL32.dll' name 'ReOpenFile';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "ReOpenFile"
  c_ReOpenFile :: Ptr () -> Word32 -> Word32 -> Word32 -> IO (Ptr ())
-- hOriginalFile : HANDLE -> Ptr ()
-- dwDesiredAccess : DWORD -> Word32
-- dwShareMode : FILE_SHARE_MODE -> Word32
-- dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let reopenfile =
  foreign "ReOpenFile"
    ((ptr void) @-> uint32_t @-> uint32_t @-> uint32_t @-> returning (ptr void))
(* hOriginalFile : HANDLE -> (ptr void) *)
(* dwDesiredAccess : DWORD -> uint32_t *)
(* dwShareMode : FILE_SHARE_MODE -> uint32_t *)
(* dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("ReOpenFile" re-open-file :convention :stdcall) :pointer
  (h-original-file :pointer)   ; HANDLE
  (dw-desired-access :uint32)   ; DWORD
  (dw-share-mode :uint32)   ; FILE_SHARE_MODE
  (dw-flags-and-attributes :uint32))   ; FILE_FLAGS_AND_ATTRIBUTES
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $ReOpenFile = Win32::API::More->new('KERNEL32',
    'HANDLE ReOpenFile(HANDLE hOriginalFile, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwFlagsAndAttributes)');
# my $ret = $ReOpenFile->Call($hOriginalFile, $dwDesiredAccess, $dwShareMode, $dwFlagsAndAttributes);
# hOriginalFile : HANDLE -> HANDLE
# dwDesiredAccess : DWORD -> DWORD
# dwShareMode : FILE_SHARE_MODE -> DWORD
# dwFlagsAndAttributes : FILE_FLAGS_AND_ATTRIBUTES -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

公式の関連項目
使用する型