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

MoveFileTransactedA

関数
トランザクション内でファイルを移動・改名する(ANSI版)。
DLLKERNEL32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows Vista 以降

シグネチャ

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

BOOL MoveFileTransactedA(
    LPCSTR lpExistingFileName,
    LPCSTR lpNewFileName,   // optional
    LPPROGRESS_ROUTINE lpProgressRoutine,   // optional
    void* lpData,   // optional
    MOVE_FILE_FLAGS dwFlags,
    HANDLE hTransaction
);

パラメーター

名前方向説明
lpExistingFileNameLPCSTRin

ローカルコンピューター上の既存のファイルまたはディレクトリの現在の名前です。

既定では、名前は MAX_PATH 文字に制限されます。この制限を 32,767 ワイド文字に拡張するには、パスの先頭に "\\?\" を付加します。詳細については、ファイル、パス、名前空間の名前付けを参照してください。

ヒント

Windows 10 バージョン 1607 以降では、"\\?\" を付加せずに MAX_PATH の制限を解除するようにオプトインできます。詳細については、ファイル、パス、名前空間の名前付けの「Maximum Path Length Limitation」セクションを参照してください。

lpNewFileNameLPCSTRinoptional

ファイルまたはディレクトリの新しい名前です。新しい名前は既に存在していてはなりません。新しいファイルは 別のファイルシステムまたはドライブ上に置くことができます。新しいディレクトリは同じドライブ上になければなりません。

既定では、名前は MAX_PATH 文字に制限されます。この制限を 32,767 ワイド文字に拡張するには、パスの先頭に "\\?\" を付加します。詳細については、ファイル、パス、名前空間の名前付けを参照してください。

ヒント

Windows 10 バージョン 1607 以降では、"\\?\" を付加せずに MAX_PATH の制限を解除するようにオプトインできます。詳細については、ファイル、パス、名前空間の名前付けの「Maximum Path Length Limitation」セクションを参照してください。

lpProgressRoutineLPPROGRESS_ROUTINEinoptionalファイルの別の部分が移動されるたびに呼び出される CopyProgressRoutine コールバック 関数へのポインターです。このコールバック関数は、操作の進行状況を表示するユーザーインターフェイスを提供する場合に 役立ちます。このパラメーターには NULL を指定できます。
lpDatavoid*inoptionalCopyProgressRoutine コールバック関数に渡される引数です。この パラメーターには NULL を指定できます。
dwFlagsMOVE_FILE_FLAGSin

移動オプションです。このパラメーターには、次の値を 1 つ以上指定できます。

意味
MOVEFILE_COPY_ALLOWED
2 (0x2)
ファイルを別のボリュームに移動する場合、この関数は CopyFile 関数と DeleteFile 関数を使用して移動をシミュレートします。

ファイルが別のボリュームに正常にコピーされ、元のファイルを削除できなかった場合、 この関数は成功し、ソースファイルはそのまま残されます。

この値は MOVEFILE_DELAY_UNTIL_REBOOT と併用できません。

MOVEFILE_CREATE_HARDLINK
16 (0x10)
将来の使用のために予約されています。
MOVEFILE_DELAY_UNTIL_REBOOT
4 (0x4)
システムは、オペレーティングシステムが再起動されるまでファイルを移動しません。システムは AUTOCHK が実行された 直後、ただしページングファイルを作成する前にファイルを移動します。その結果、このパラメーターを使用すると、 以前の起動時のページングファイルを削除できます。

この値は、プロセスが administrators グループに属するユーザー、または LocalSystem アカウントの コンテキストにある場合にのみ使用できます。

この値は MOVEFILE_COPY_ALLOWED と併用できません。

トランザクション処理されるのは、「解説」セクションで詳述するレジストリ値への書き込み操作です。 ファイルの移動は、トランザクションが完了した後、コンピューターの再起動時に完了します。

MOVEFILE_REPLACE_EXISTING
1 (0x1)
lpNewFileName という名前のファイルが存在する場合、この関数はその内容を lpExistingFileName ファイルの内容で置き換えます。

この値は、lpNewFileName または lpExistingFileName がディレクトリを指している場合は使用できません。

MOVEFILE_WRITE_THROUGH
8 (0x8)
MoveFileTransacted の呼び出しは、 コミット操作が完了した時点でファイル移動操作が完了することを意味します。このフラグは不要です。このフラグを指定しても、 操作が遅くなる以外に悪影響はありません。この関数は、ファイルが実際にディスク上で移動されるまで 戻りません。

この値を設定すると、コピーと削除の操作として実行された移動が、関数が戻る前に確実にディスクへ フラッシュされます。フラッシュはコピー操作の終了時に発生します。

この値は MOVEFILE_DELAY_UNTIL_REBOOT が設定されている場合は効果がありません。

hTransactionHANDLEinトランザクションへのハンドルです。このハンドルは CreateTransaction 関数によって返されます。

戻り値の型: BOOL

公式ドキュメント

既存のファイル、またはディレクトリ(その子を含む)を、トランザクション操作として移動します。(ANSI)

戻り値

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

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

ボリューム間でファイルを移動する際、ユーザーが操作をキャンセルしたことにより lpProgressRoutinePROGRESS_CANCEL を返した場合、 MoveFileTransacted は 0 を返し、 GetLastErrorERROR_REQUEST_ABORTED を返します。既存のファイルはそのまま残されます。

ボリューム間でファイルを移動する際、ユーザーが操作を停止したことにより lpProgressRoutinePROGRESS_STOP を返した場合、 MoveFileTransacted は 0 を返し、 GetLastErrorERROR_REQUEST_ABORTED を返します。既存のファイルはそのまま残されます。

解説(Remarks)

dwFlags パラメーターに MOVEFILE_DELAY_UNTIL_REBOOT が指定されている場合、 MoveFileTransacted はレジストリにアクセスできないと失敗します。この 関数は、再起動時に名前を変更するファイルの場所を、次のレジストリ値に トランザクション処理で格納します: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations

このレジストリ値は REG_MULTI_SZ 型です。各名前変更操作は、その名前変更が削除であるかどうかに応じて、 次の NULL 終端文字列のいずれかを格納します:

szDstFile\0\0

szSrcFile\0szDstFile\0

文字列 szDstFile\0\0 は、ファイル szDstFile が再起動時に削除されることを示します。

文字列 szSrcFile\0szDstFile\0 は、 szSrcFile が再起動時に szDstFile に名前変更されることを示します。

\0\0 は技術的には REG_MULTI_SZ ノードでは許可されていませんが、 ファイルが null 名に名前変更されるとみなされるため、これが可能です。
システムはこれらのレジストリエントリを使用して、発行されたのと同じ順序で再起動時に操作を完了します。 MOVEFILE_DELAY_UNTIL_REBOOT フラグの使用方法の詳細については、 MoveFileWithProgress を参照してください。

ファイルがボリューム間で移動される場合、 MoveFileTransacted はセキュリティ 記述子をファイルと共に移動しません。ファイルには、移動先ディレクトリの既定のセキュリティ記述子が割り当てられます。

この関数は、MOVEFILE_FAIL_IF_NOT_TRACKABLE フラグを指定すると常に失敗します。 トラッキングは TxF ではサポートされていません。

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

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

SMB 3.0 は TxF をサポートしていません。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

BOOL MoveFileTransactedA(
    LPCSTR lpExistingFileName,
    LPCSTR lpNewFileName,   // optional
    LPPROGRESS_ROUTINE lpProgressRoutine,   // optional
    void* lpData,   // optional
    MOVE_FILE_FLAGS dwFlags,
    HANDLE hTransaction
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern bool MoveFileTransactedA(
    [MarshalAs(UnmanagedType.LPStr)] string lpExistingFileName,   // LPCSTR
    [MarshalAs(UnmanagedType.LPStr)] string lpNewFileName,   // LPCSTR optional
    IntPtr lpProgressRoutine,   // LPPROGRESS_ROUTINE optional
    IntPtr lpData,   // void* optional
    uint dwFlags,   // MOVE_FILE_FLAGS
    IntPtr hTransaction   // HANDLE
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function MoveFileTransactedA(
    <MarshalAs(UnmanagedType.LPStr)> lpExistingFileName As String,   ' LPCSTR
    <MarshalAs(UnmanagedType.LPStr)> lpNewFileName As String,   ' LPCSTR optional
    lpProgressRoutine As IntPtr,   ' LPPROGRESS_ROUTINE optional
    lpData As IntPtr,   ' void* optional
    dwFlags As UInteger,   ' MOVE_FILE_FLAGS
    hTransaction As IntPtr   ' HANDLE
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' lpExistingFileName : LPCSTR
' lpNewFileName : LPCSTR optional
' lpProgressRoutine : LPPROGRESS_ROUTINE optional
' lpData : void* optional
' dwFlags : MOVE_FILE_FLAGS
' hTransaction : HANDLE
Declare PtrSafe Function MoveFileTransactedA Lib "kernel32" ( _
    ByVal lpExistingFileName As String, _
    ByVal lpNewFileName As String, _
    ByVal lpProgressRoutine As LongPtr, _
    ByVal lpData As LongPtr, _
    ByVal dwFlags As Long, _
    ByVal hTransaction As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

MoveFileTransactedA = ctypes.windll.kernel32.MoveFileTransactedA
MoveFileTransactedA.restype = wintypes.BOOL
MoveFileTransactedA.argtypes = [
    wintypes.LPCSTR,  # lpExistingFileName : LPCSTR
    wintypes.LPCSTR,  # lpNewFileName : LPCSTR optional
    ctypes.c_void_p,  # lpProgressRoutine : LPPROGRESS_ROUTINE optional
    ctypes.POINTER(None),  # lpData : void* optional
    wintypes.DWORD,  # dwFlags : MOVE_FILE_FLAGS
    wintypes.HANDLE,  # hTransaction : HANDLE
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
MoveFileTransactedA = Fiddle::Function.new(
  lib['MoveFileTransactedA'],
  [
    Fiddle::TYPE_VOIDP,  # lpExistingFileName : LPCSTR
    Fiddle::TYPE_VOIDP,  # lpNewFileName : LPCSTR optional
    Fiddle::TYPE_VOIDP,  # lpProgressRoutine : LPPROGRESS_ROUTINE optional
    Fiddle::TYPE_VOIDP,  # lpData : void* optional
    -Fiddle::TYPE_INT,  # dwFlags : MOVE_FILE_FLAGS
    Fiddle::TYPE_VOIDP,  # hTransaction : HANDLE
  ],
  Fiddle::TYPE_INT)
#[link(name = "kernel32")]
extern "system" {
    fn MoveFileTransactedA(
        lpExistingFileName: *const u8,  // LPCSTR
        lpNewFileName: *const u8,  // LPCSTR optional
        lpProgressRoutine: *const core::ffi::c_void,  // LPPROGRESS_ROUTINE optional
        lpData: *mut (),  // void* optional
        dwFlags: u32,  // MOVE_FILE_FLAGS
        hTransaction: *mut core::ffi::c_void  // HANDLE
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool MoveFileTransactedA([MarshalAs(UnmanagedType.LPStr)] string lpExistingFileName, [MarshalAs(UnmanagedType.LPStr)] string lpNewFileName, IntPtr lpProgressRoutine, IntPtr lpData, uint dwFlags, IntPtr hTransaction);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_MoveFileTransactedA' -Namespace Win32 -PassThru
# $api::MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
#uselib "KERNEL32.dll"
#func global MoveFileTransactedA "MoveFileTransactedA" sptr, sptr, sptr, sptr, sptr, sptr
; MoveFileTransactedA lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction   ; 戻り値は stat
; lpExistingFileName : LPCSTR -> "sptr"
; lpNewFileName : LPCSTR optional -> "sptr"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "sptr"
; lpData : void* optional -> "sptr"
; dwFlags : MOVE_FILE_FLAGS -> "sptr"
; hTransaction : HANDLE -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
#uselib "KERNEL32.dll"
#cfunc global MoveFileTransactedA "MoveFileTransactedA" str, str, sptr, sptr, int, sptr
; res = MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
; lpExistingFileName : LPCSTR -> "str"
; lpNewFileName : LPCSTR optional -> "str"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "sptr"
; lpData : void* optional -> "sptr"
; dwFlags : MOVE_FILE_FLAGS -> "int"
; hTransaction : HANDLE -> "sptr"
; BOOL MoveFileTransactedA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, LPPROGRESS_ROUTINE lpProgressRoutine, void* lpData, MOVE_FILE_FLAGS dwFlags, HANDLE hTransaction)
#uselib "KERNEL32.dll"
#cfunc global MoveFileTransactedA "MoveFileTransactedA" str, str, intptr, intptr, int, intptr
; res = MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
; lpExistingFileName : LPCSTR -> "str"
; lpNewFileName : LPCSTR optional -> "str"
; lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "intptr"
; lpData : void* optional -> "intptr"
; dwFlags : MOVE_FILE_FLAGS -> "int"
; hTransaction : HANDLE -> "intptr"
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procMoveFileTransactedA = kernel32.NewProc("MoveFileTransactedA")
)

// lpExistingFileName (LPCSTR), lpNewFileName (LPCSTR optional), lpProgressRoutine (LPPROGRESS_ROUTINE optional), lpData (void* optional), dwFlags (MOVE_FILE_FLAGS), hTransaction (HANDLE)
r1, _, err := procMoveFileTransactedA.Call(
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpExistingFileName))),
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpNewFileName))),
	uintptr(lpProgressRoutine),
	uintptr(lpData),
	uintptr(dwFlags),
	uintptr(hTransaction),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function MoveFileTransactedA(
  lpExistingFileName: PAnsiChar;   // LPCSTR
  lpNewFileName: PAnsiChar;   // LPCSTR optional
  lpProgressRoutine: Pointer;   // LPPROGRESS_ROUTINE optional
  lpData: Pointer;   // void* optional
  dwFlags: DWORD;   // MOVE_FILE_FLAGS
  hTransaction: THandle   // HANDLE
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'MoveFileTransactedA';
result := DllCall("KERNEL32\MoveFileTransactedA"
    , "AStr", lpExistingFileName   ; LPCSTR
    , "AStr", lpNewFileName   ; LPCSTR optional
    , "Ptr", lpProgressRoutine   ; LPPROGRESS_ROUTINE optional
    , "Ptr", lpData   ; void* optional
    , "UInt", dwFlags   ; MOVE_FILE_FLAGS
    , "Ptr", hTransaction   ; HANDLE
    , "Int")   ; return: BOOL
●MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction) = DLL("KERNEL32.dll", "bool MoveFileTransactedA(char*, char*, void*, void*, dword, void*)")
# 呼び出し: MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
# lpExistingFileName : LPCSTR -> "char*"
# lpNewFileName : LPCSTR optional -> "char*"
# lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "void*"
# lpData : void* optional -> "void*"
# dwFlags : MOVE_FILE_FLAGS -> "dword"
# hTransaction : HANDLE -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "kernel32" fn MoveFileTransactedA(
    lpExistingFileName: [*c]const u8, // LPCSTR
    lpNewFileName: [*c]const u8, // LPCSTR optional
    lpProgressRoutine: ?*anyopaque, // LPPROGRESS_ROUTINE optional
    lpData: ?*anyopaque, // void* optional
    dwFlags: u32, // MOVE_FILE_FLAGS
    hTransaction: ?*anyopaque // HANDLE
) callconv(std.os.windows.WINAPI) i32;
proc MoveFileTransactedA(
    lpExistingFileName: cstring,  # LPCSTR
    lpNewFileName: cstring,  # LPCSTR optional
    lpProgressRoutine: pointer,  # LPPROGRESS_ROUTINE optional
    lpData: pointer,  # void* optional
    dwFlags: uint32,  # MOVE_FILE_FLAGS
    hTransaction: pointer  # HANDLE
): int32 {.importc: "MoveFileTransactedA", stdcall, dynlib: "KERNEL32.dll".}
pragma(lib, "kernel32");
extern(Windows)
int MoveFileTransactedA(
    const(char)* lpExistingFileName,   // LPCSTR
    const(char)* lpNewFileName,   // LPCSTR optional
    void* lpProgressRoutine,   // LPPROGRESS_ROUTINE optional
    void* lpData,   // void* optional
    uint dwFlags,   // MOVE_FILE_FLAGS
    void* hTransaction   // HANDLE
);
ccall((:MoveFileTransactedA, "KERNEL32.dll"), stdcall, Int32,
      (Cstring, Cstring, Ptr{Cvoid}, Ptr{Cvoid}, UInt32, Ptr{Cvoid}),
      lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
# lpExistingFileName : LPCSTR -> Cstring
# lpNewFileName : LPCSTR optional -> Cstring
# lpProgressRoutine : LPPROGRESS_ROUTINE optional -> Ptr{Cvoid}
# lpData : void* optional -> Ptr{Cvoid}
# dwFlags : MOVE_FILE_FLAGS -> UInt32
# hTransaction : HANDLE -> Ptr{Cvoid}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t MoveFileTransactedA(
    const char* lpExistingFileName,
    const char* lpNewFileName,
    void* lpProgressRoutine,
    void* lpData,
    uint32_t dwFlags,
    void* hTransaction);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
-- lpExistingFileName : LPCSTR
-- lpNewFileName : LPCSTR optional
-- lpProgressRoutine : LPPROGRESS_ROUTINE optional
-- lpData : void* optional
-- dwFlags : MOVE_FILE_FLAGS
-- hTransaction : HANDLE
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const MoveFileTransactedA = lib.func('__stdcall', 'MoveFileTransactedA', 'int32_t', ['str', 'str', 'void *', 'void *', 'uint32_t', 'void *']);
// MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
// lpExistingFileName : LPCSTR -> 'str'
// lpNewFileName : LPCSTR optional -> 'str'
// lpProgressRoutine : LPPROGRESS_ROUTINE optional -> 'void *'
// lpData : void* optional -> 'void *'
// dwFlags : MOVE_FILE_FLAGS -> 'uint32_t'
// hTransaction : HANDLE -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
// コールバック(関数ポインタ)は koffi.proto/koffi.register で型を定義して渡す(素の void* では JS 関数を渡せない)。
const lib = Deno.dlopen("KERNEL32.dll", {
  MoveFileTransactedA: { parameters: ["buffer", "buffer", "pointer", "pointer", "u32", "pointer"], result: "i32" },
});
// lib.symbols.MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction)
// lpExistingFileName : LPCSTR -> "buffer"
// lpNewFileName : LPCSTR optional -> "buffer"
// lpProgressRoutine : LPPROGRESS_ROUTINE optional -> "pointer"
// lpData : void* optional -> "pointer"
// dwFlags : MOVE_FILE_FLAGS -> "u32"
// hTransaction : HANDLE -> "pointer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t MoveFileTransactedA(
    const char* lpExistingFileName,
    const char* lpNewFileName,
    void* lpProgressRoutine,
    void* lpData,
    uint32_t dwFlags,
    void* hTransaction);
C, "KERNEL32.dll");
// $ffi->MoveFileTransactedA(lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags, hTransaction);
// lpExistingFileName : LPCSTR
// lpNewFileName : LPCSTR optional
// lpProgressRoutine : LPPROGRESS_ROUTINE optional
// lpData : void* optional
// dwFlags : MOVE_FILE_FLAGS
// hTransaction : HANDLE
// 構造体/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, W32APIOptions.ASCII_OPTIONS);
    boolean MoveFileTransactedA(
        String lpExistingFileName,   // LPCSTR
        String lpNewFileName,   // LPCSTR optional
        Callback lpProgressRoutine,   // LPPROGRESS_ROUTINE optional
        Pointer lpData,   // void* optional
        int dwFlags,   // MOVE_FILE_FLAGS
        Pointer hTransaction   // HANDLE
    );
}
@[Link("kernel32")]
lib LibKERNEL32
  fun MoveFileTransactedA = MoveFileTransactedA(
    lpExistingFileName : UInt8*,   # LPCSTR
    lpNewFileName : UInt8*,   # LPCSTR optional
    lpProgressRoutine : Void*,   # LPPROGRESS_ROUTINE optional
    lpData : Void*,   # void* optional
    dwFlags : UInt32,   # MOVE_FILE_FLAGS
    hTransaction : Void*   # HANDLE
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef MoveFileTransactedANative = Int32 Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>, Uint32, Pointer<Void>);
typedef MoveFileTransactedADart = int Function(Pointer<Utf8>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>, int, Pointer<Void>);
final MoveFileTransactedA = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<MoveFileTransactedANative, MoveFileTransactedADart>('MoveFileTransactedA');
// lpExistingFileName : LPCSTR -> Pointer<Utf8>
// lpNewFileName : LPCSTR optional -> Pointer<Utf8>
// lpProgressRoutine : LPPROGRESS_ROUTINE optional -> Pointer<Void>
// lpData : void* optional -> Pointer<Void>
// dwFlags : MOVE_FILE_FLAGS -> Uint32
// hTransaction : HANDLE -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function MoveFileTransactedA(
  lpExistingFileName: PAnsiChar;   // LPCSTR
  lpNewFileName: PAnsiChar;   // LPCSTR optional
  lpProgressRoutine: Pointer;   // LPPROGRESS_ROUTINE optional
  lpData: Pointer;   // void* optional
  dwFlags: DWORD;   // MOVE_FILE_FLAGS
  hTransaction: THandle   // HANDLE
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'MoveFileTransactedA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "MoveFileTransactedA"
  c_MoveFileTransactedA :: CString -> CString -> Ptr () -> Ptr () -> Word32 -> Ptr () -> IO CInt
-- lpExistingFileName : LPCSTR -> CString
-- lpNewFileName : LPCSTR optional -> CString
-- lpProgressRoutine : LPPROGRESS_ROUTINE optional -> Ptr ()
-- lpData : void* optional -> Ptr ()
-- dwFlags : MOVE_FILE_FLAGS -> Word32
-- hTransaction : HANDLE -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let movefiletransacteda =
  foreign "MoveFileTransactedA"
    (string @-> string @-> (ptr void) @-> (ptr void) @-> uint32_t @-> (ptr void) @-> returning int32_t)
(* lpExistingFileName : LPCSTR -> string *)
(* lpNewFileName : LPCSTR optional -> string *)
(* lpProgressRoutine : LPPROGRESS_ROUTINE optional -> (ptr void) *)
(* lpData : void* optional -> (ptr void) *)
(* dwFlags : MOVE_FILE_FLAGS -> uint32_t *)
(* hTransaction : HANDLE -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("MoveFileTransactedA" move-file-transacted-a :convention :stdcall) :int32
  (lp-existing-file-name :string)   ; LPCSTR
  (lp-new-file-name :string)   ; LPCSTR optional
  (lp-progress-routine :pointer)   ; LPPROGRESS_ROUTINE optional
  (lp-data :pointer)   ; void* optional
  (dw-flags :uint32)   ; MOVE_FILE_FLAGS
  (h-transaction :pointer))   ; HANDLE
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $MoveFileTransactedA = Win32::API::More->new('KERNEL32',
    'BOOL MoveFileTransactedA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, LPVOID lpProgressRoutine, LPVOID lpData, DWORD dwFlags, HANDLE hTransaction)');
# my $ret = $MoveFileTransactedA->Call($lpExistingFileName, $lpNewFileName, $lpProgressRoutine, $lpData, $dwFlags, $hTransaction);
# lpExistingFileName : LPCSTR -> LPCSTR
# lpNewFileName : LPCSTR optional -> LPCSTR
# lpProgressRoutine : LPPROGRESS_ROUTINE optional -> LPVOID
# lpData : void* optional -> LPVOID
# dwFlags : MOVE_FILE_FLAGS -> DWORD
# hTransaction : HANDLE -> HANDLE
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。
# コールバック(関数ポインタ)は Perl sub を直接渡せません。Win32::API::Callback を使用してください。

関連項目

文字セット違い
公式の関連項目
使用する型