DuplicateHandle
関数シグネチャ
// KERNEL32.dll
#include <windows.h>
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
HANDLE* lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DUPLICATE_HANDLE_OPTIONS dwOptions
);パラメーター
| 名前 | 型 | 方向 | 説明 | ||||||
|---|---|---|---|---|---|---|---|---|---|
| hSourceProcessHandle | HANDLE | in | 複製対象のハンドルを保持しているプロセスへのハンドルです。 このハンドルには PROCESS_DUP_HANDLE アクセス権が必要です。詳細については、 Process Security and Access Rights を参照してください。 | ||||||
| hSourceHandle | HANDLE | in | 複製対象のハンドルです。これは、ソースプロセスのコンテキストにおいて有効な、開いているオブジェクトハンドルです。ハンドルを複製できるオブジェクトの一覧については、後述の「解説」セクションを参照してください。 hSourceHandle が GetCurrentProcess または GetCurrentThread によって返された擬似ハンドルである場合、hSourceProcessHandle には DuplicateHandle を呼び出すプロセスへのハンドルを指定する必要があります。 | ||||||
| hTargetProcessHandle | HANDLE | in | 複製されたハンドルを受け取るプロセスへのハンドルです。このハンドルには PROCESS_DUP_HANDLE アクセス権が必要です。 このパラメーターは省略可能であり、Options に DUPLICATE_CLOSE_SOURCE フラグが設定されている場合は NULL を指定できます。 | ||||||
| lpTargetHandle | HANDLE* | out | 複製されたハンドルを受け取る変数へのポインターです。このハンドル値は、ターゲットプロセスのコンテキストにおいて有効です。 hSourceHandle が GetCurrentProcess または GetCurrentThread によって返された擬似ハンドルである場合、DuplicateHandle はそれをそれぞれプロセスまたはスレッドへの実際のハンドルに変換します。 lpTargetHandle が NULL の場合、関数はハンドルを複製しますが、複製されたハンドル値を呼び出し元に返しません。この動作は、本関数の以前のバージョンとの後方互換性のためにのみ存在します。ターゲットプロセスが終了するまでシステムリソースを消費し続けることになるため、この機能は使用しないでください。 このパラメーターは、hTargetProcessHandle が NULL の場合は無視されます。 | ||||||
| dwDesiredAccess | DWORD | in | 新しいハンドルに対して要求されるアクセス権です。各オブジェクトタイプに対して指定できるフラグについては、後述の「解説」セクションを参照してください。 このパラメーターは、dwOptions パラメーターに DUPLICATE_SAME_ACCESS フラグが指定されている場合は無視されます。それ以外の場合、指定できるフラグは、ハンドルを複製するオブジェクトのタイプによって異なります。 このパラメーターは、hTargetProcessHandle が NULL の場合は無視されます。 | ||||||
| bInheritHandle | BOOL | in | ハンドルが継承可能かどうかを示す変数です。TRUE の場合、複製されたハンドルは、ターゲットプロセスによって作成される新しいプロセスに継承されます。FALSE の場合、新しいハンドルは継承されません。 このパラメーターは、hTargetProcessHandle が NULL の場合は無視されます。 | ||||||
| dwOptions | DUPLICATE_HANDLE_OPTIONS | in | 省略可能なアクションです。このパラメーターには 0、または次の値の任意の組み合わせを指定できます。
|
戻り値の型: BOOL
公式ドキュメント
オブジェクトのハンドルを複製します。
戻り値
関数が成功した場合、戻り値は 0 以外の値になります。
関数が失敗した場合、戻り値は 0 になります。拡張エラー情報を取得するには、 GetLastError を呼び出してください。
解説(Remarks)
複製されたハンドルは、元のハンドルと同じオブジェクトを参照します。したがって、オブジェクトに対する変更は両方のハンドルに反映されます。たとえば、ファイルハンドルを複製した場合、現在のファイル位置は常に両方のハンドルで同じになります。ファイルハンドルごとに異なるファイル位置を持たせるには、CreateFile 関数を使用して、同じファイルへのアクセスを共有するファイルハンドルを作成してください。
DuplicateHandle は、ソースプロセスまたはターゲットプロセス(あるいはソースとターゲットの両方を兼ねるプロセス)のいずれからでも呼び出すことができます。たとえば、プロセスは DuplicateHandle を使用して、継承可能なハンドルから継承不可能な複製を作成したり、元のハンドルとは異なるアクセス権を持つハンドルを作成したりできます。
ソースプロセスは、 GetCurrentProcess 関数を使用して自身へのハンドルを取得します。このハンドルは擬似ハンドルですが、DuplicateHandle はこれを実際のプロセスハンドルに変換します。ターゲットプロセスのハンドルを取得するには、何らかのプロセス間通信(たとえば名前付きパイプや共有メモリ)を使用して、プロセス識別子をソースプロセスに伝える必要がある場合があります。ソースプロセスは、この識別子を OpenProcess 関数で使用して、ターゲットプロセスへのハンドルを取得できます。
DuplicateHandle を呼び出すプロセスがターゲットプロセスでもない場合、ソースプロセスはプロセス間通信を使用して、複製されたハンドルの値をターゲットプロセスに渡す必要があります。
DuplicateHandle は、32 ビットプロセスと 64 ビットプロセスの間でハンドルを複製するために使用できます。生成されるハンドルは、ターゲットプロセスで動作するように適切なサイズになります。詳細については、Process Interoperability を参照してください。
DuplicateHandle は、次のタイプのオブジェクトに対するハンドルを複製できます。
| オブジェクト | 説明 |
|---|---|
| アクセストークン | ハンドルは、 CreateRestrictedToken、 DuplicateToken、 DuplicateTokenEx、 OpenProcessToken、または OpenThreadToken 関数によって返されます。 |
| 変更通知 | ハンドルは、FindFirstChangeNotification 関数によって返されます。 |
| 通信デバイス | ハンドルは、 CreateFile 関数によって返されます。 |
| コンソール入力 | ハンドルは、CONIN$ を指定した場合に CreateFile 関数によって、または STD_INPUT_HANDLE を指定した場合に GetStdHandle 関数によって返されます。コンソールハンドルは、同じプロセス内で使用する場合にのみ複製できます。 |
| コンソール画面バッファー | ハンドルは、CONOUT$ を指定した場合に CreateFile 関数によって、または STD_OUTPUT_HANDLE を指定した場合に GetStdHandle 関数によって返されます。コンソールハンドルは、同じプロセス内で使用する場合にのみ複製できます。 |
| デスクトップ | ハンドルは、 GetThreadDesktop 関数によって返されます。 |
| イベント | ハンドルは、 CreateEvent または OpenEvent 関数によって返されます。 |
| ファイル | ハンドルは、 CreateFile 関数によって返されます。 |
| ファイルマッピング | ハンドルは、 CreateFileMapping 関数によって返されます。 |
| ジョブ | ハンドルは、 CreateJobObject 関数によって返されます。 |
| メールスロット | ハンドルは、 CreateMailslot 関数によって返されます。 |
| ミューテックス | ハンドルは、 CreateMutex または [OpenMutex](../synchapi/nf-synchapi-openmutexw.md) 関数によって返されます。 |
| パイプ | 名前付きパイプハンドルは、 CreateNamedPipe または CreateFile 関数によって返されます。匿名パイプハンドルは、 CreatePipe 関数によって返されます。 |
| プロセス | ハンドルは、 CreateProcess、 GetCurrentProcess、または OpenProcess 関数によって返されます。 |
| レジストリキー | ハンドルは、 RegCreateKey、 RegCreateKeyEx、 RegOpenKey、または RegOpenKeyEx 関数によって返されます。なお、 RegConnectRegistry 関数によって返されるレジストリキーハンドルは、 DuplicateHandle の呼び出しでは使用できません。 |
| セマフォ | ハンドルは、 CreateSemaphore または OpenSemaphore 関数によって返されます。 |
| スレッド | ハンドルは、 CreateProcess、 CreateThread、 CreateRemoteThread、または GetCurrentThread 関数によって返されます。 |
| タイマー | ハンドルは、 CreateWaitableTimerW または OpenWaitableTimerW 関数によって返されます。 |
| トランザクション | ハンドルは、CreateTransaction 関数によって返されます。 |
| ウィンドウステーション | ハンドルは、 GetProcessWindowStation 関数によって返されます。 |
次のオブジェクトに対するハンドルの複製には、 DuplicateHandle を使用しないでください。
- I/O 完了ポート。エラーは返されませんが、複製されたハンドルは使用できません。
- ソケット。エラーは返されませんが、複製されたハンドルがターゲットプロセスの Winsock で認識されない場合があります。また、DuplicateHandle を使用すると、基になるオブジェクトの内部参照カウントに支障をきたします。ソケットハンドルを複製するには、WSADuplicateSocket 関数を使用してください。
- GetCurrentProcess または GetCurrentThread 関数によって返されるもの以外の擬似ハンドル。
- Desktop Security and Access Rights
- File Security and Access Rights
- File-Mapping Security and Access Rights
- Job Object Security and Access Rights
- Process Security and Access Rights
- Registry Key Security and Access Rights
- Synchronization Object Security and Access Rights
- Thread Security and Access Rights
- Window-Station Security and Access Rights
通常、ターゲットプロセスは、複製されたハンドルの使用が終わった時点でそのハンドルを閉じます。ソースプロセスから複製されたハンドルを閉じるには、次のパラメーターを指定して DuplicateHandle を呼び出します。
- hSourceProcessHandle に、ハンドルを作成した DuplicateHandle 呼び出しのターゲットプロセスを設定します。
- hSourceHandle に、閉じる複製されたハンドルを設定します。
- hTargetProcessHandle に NULL を設定します。
- dwOptions に DUPLICATE_CLOSE_SOURCE を設定します。
例
次の例では、ミューテックスを作成し、そのミューテックスへのハンドルを複製して、別のスレッドに渡します。ハンドルを複製することで参照カウントが増加するため、両方のスレッドがハンドルを閉じるまでミューテックスオブジェクトが破棄されないことが保証されます。
#include <windows.h>
DWORD CALLBACK ThreadProc(PVOID pvParam);
int main()
{
HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
HANDLE hMutexDup, hThread;
DWORD dwThreadId;
DuplicateHandle(GetCurrentProcess(),
hMutex,
GetCurrentProcess(),
&hMutexDup,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
hThread = CreateThread(NULL, 0, ThreadProc,
(LPVOID) hMutexDup, 0, &dwThreadId);
// Perform work here, closing the handle when finished with the
// mutex. If the reference count is zero, the object is destroyed.
CloseHandle(hMutex);
// Wait for the worker thread to terminate and clean up.
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0;
}
DWORD CALLBACK ThreadProc(PVOID pvParam)
{
HANDLE hMutex = (HANDLE)pvParam;
// Perform work here, closing the handle when finished with the
// mutex. If the reference count is zero, the object is destroyed.
CloseHandle(hMutex);
return 0;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// KERNEL32.dll
#include <windows.h>
BOOL DuplicateHandle(
HANDLE hSourceProcessHandle,
HANDLE hSourceHandle,
HANDLE hTargetProcessHandle,
HANDLE* lpTargetHandle,
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DUPLICATE_HANDLE_OPTIONS dwOptions
);[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool DuplicateHandle(
IntPtr hSourceProcessHandle, // HANDLE
IntPtr hSourceHandle, // HANDLE
IntPtr hTargetProcessHandle, // HANDLE
IntPtr lpTargetHandle, // HANDLE* out
uint dwDesiredAccess, // DWORD
bool bInheritHandle, // BOOL
uint dwOptions // DUPLICATE_HANDLE_OPTIONS
);<DllImport("KERNEL32.dll", SetLastError:=True, ExactSpelling:=True)>
Public Shared Function DuplicateHandle(
hSourceProcessHandle As IntPtr, ' HANDLE
hSourceHandle As IntPtr, ' HANDLE
hTargetProcessHandle As IntPtr, ' HANDLE
lpTargetHandle As IntPtr, ' HANDLE* out
dwDesiredAccess As UInteger, ' DWORD
bInheritHandle As Boolean, ' BOOL
dwOptions As UInteger ' DUPLICATE_HANDLE_OPTIONS
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function' hSourceProcessHandle : HANDLE
' hSourceHandle : HANDLE
' hTargetProcessHandle : HANDLE
' lpTargetHandle : HANDLE* out
' dwDesiredAccess : DWORD
' bInheritHandle : BOOL
' dwOptions : DUPLICATE_HANDLE_OPTIONS
Declare PtrSafe Function DuplicateHandle Lib "kernel32" ( _
ByVal hSourceProcessHandle As LongPtr, _
ByVal hSourceHandle As LongPtr, _
ByVal hTargetProcessHandle As LongPtr, _
ByVal lpTargetHandle As LongPtr, _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwOptions As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
DuplicateHandle = ctypes.windll.kernel32.DuplicateHandle
DuplicateHandle.restype = wintypes.BOOL
DuplicateHandle.argtypes = [
wintypes.HANDLE, # hSourceProcessHandle : HANDLE
wintypes.HANDLE, # hSourceHandle : HANDLE
wintypes.HANDLE, # hTargetProcessHandle : HANDLE
ctypes.c_void_p, # lpTargetHandle : HANDLE* out
wintypes.DWORD, # dwDesiredAccess : DWORD
wintypes.BOOL, # bInheritHandle : BOOL
wintypes.DWORD, # dwOptions : DUPLICATE_HANDLE_OPTIONS
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('KERNEL32.dll')
DuplicateHandle = Fiddle::Function.new(
lib['DuplicateHandle'],
[
Fiddle::TYPE_VOIDP, # hSourceProcessHandle : HANDLE
Fiddle::TYPE_VOIDP, # hSourceHandle : HANDLE
Fiddle::TYPE_VOIDP, # hTargetProcessHandle : HANDLE
Fiddle::TYPE_VOIDP, # lpTargetHandle : HANDLE* out
-Fiddle::TYPE_INT, # dwDesiredAccess : DWORD
Fiddle::TYPE_INT, # bInheritHandle : BOOL
-Fiddle::TYPE_INT, # dwOptions : DUPLICATE_HANDLE_OPTIONS
],
Fiddle::TYPE_INT)#[link(name = "kernel32")]
extern "system" {
fn DuplicateHandle(
hSourceProcessHandle: *mut core::ffi::c_void, // HANDLE
hSourceHandle: *mut core::ffi::c_void, // HANDLE
hTargetProcessHandle: *mut core::ffi::c_void, // HANDLE
lpTargetHandle: *mut *mut core::ffi::c_void, // HANDLE* out
dwDesiredAccess: u32, // DWORD
bInheritHandle: i32, // BOOL
dwOptions: u32 // DUPLICATE_HANDLE_OPTIONS
) -> 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 DuplicateHandle(IntPtr hSourceProcessHandle, IntPtr hSourceHandle, IntPtr hTargetProcessHandle, IntPtr lpTargetHandle, uint dwDesiredAccess, bool bInheritHandle, uint dwOptions);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_DuplicateHandle' -Namespace Win32 -PassThru
# $api::DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)#uselib "KERNEL32.dll"
#func global DuplicateHandle "DuplicateHandle" sptr, sptr, sptr, sptr, sptr, sptr, sptr
; DuplicateHandle hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions ; 戻り値は stat
; hSourceProcessHandle : HANDLE -> "sptr"
; hSourceHandle : HANDLE -> "sptr"
; hTargetProcessHandle : HANDLE -> "sptr"
; lpTargetHandle : HANDLE* out -> "sptr"
; dwDesiredAccess : DWORD -> "sptr"
; bInheritHandle : BOOL -> "sptr"
; dwOptions : DUPLICATE_HANDLE_OPTIONS -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "KERNEL32.dll"
#cfunc global DuplicateHandle "DuplicateHandle" sptr, sptr, sptr, sptr, int, int, int
; res = DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
; hSourceProcessHandle : HANDLE -> "sptr"
; hSourceHandle : HANDLE -> "sptr"
; hTargetProcessHandle : HANDLE -> "sptr"
; lpTargetHandle : HANDLE* out -> "sptr"
; dwDesiredAccess : DWORD -> "int"
; bInheritHandle : BOOL -> "int"
; dwOptions : DUPLICATE_HANDLE_OPTIONS -> "int"; BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, HANDLE* lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DUPLICATE_HANDLE_OPTIONS dwOptions)
#uselib "KERNEL32.dll"
#cfunc global DuplicateHandle "DuplicateHandle" intptr, intptr, intptr, intptr, int, int, int
; res = DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
; hSourceProcessHandle : HANDLE -> "intptr"
; hSourceHandle : HANDLE -> "intptr"
; hTargetProcessHandle : HANDLE -> "intptr"
; lpTargetHandle : HANDLE* out -> "intptr"
; dwDesiredAccess : DWORD -> "int"
; bInheritHandle : BOOL -> "int"
; dwOptions : DUPLICATE_HANDLE_OPTIONS -> "int"import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
procDuplicateHandle = kernel32.NewProc("DuplicateHandle")
)
// hSourceProcessHandle (HANDLE), hSourceHandle (HANDLE), hTargetProcessHandle (HANDLE), lpTargetHandle (HANDLE* out), dwDesiredAccess (DWORD), bInheritHandle (BOOL), dwOptions (DUPLICATE_HANDLE_OPTIONS)
r1, _, err := procDuplicateHandle.Call(
uintptr(hSourceProcessHandle),
uintptr(hSourceHandle),
uintptr(hTargetProcessHandle),
uintptr(lpTargetHandle),
uintptr(dwDesiredAccess),
uintptr(bInheritHandle),
uintptr(dwOptions),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // BOOLfunction DuplicateHandle(
hSourceProcessHandle: THandle; // HANDLE
hSourceHandle: THandle; // HANDLE
hTargetProcessHandle: THandle; // HANDLE
lpTargetHandle: Pointer; // HANDLE* out
dwDesiredAccess: DWORD; // DWORD
bInheritHandle: BOOL; // BOOL
dwOptions: DWORD // DUPLICATE_HANDLE_OPTIONS
): BOOL; stdcall;
external 'KERNEL32.dll' name 'DuplicateHandle';result := DllCall("KERNEL32\DuplicateHandle"
, "Ptr", hSourceProcessHandle ; HANDLE
, "Ptr", hSourceHandle ; HANDLE
, "Ptr", hTargetProcessHandle ; HANDLE
, "Ptr", lpTargetHandle ; HANDLE* out
, "UInt", dwDesiredAccess ; DWORD
, "Int", bInheritHandle ; BOOL
, "UInt", dwOptions ; DUPLICATE_HANDLE_OPTIONS
, "Int") ; return: BOOL●DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions) = DLL("KERNEL32.dll", "bool DuplicateHandle(void*, void*, void*, void*, dword, bool, dword)")
# 呼び出し: DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
# hSourceProcessHandle : HANDLE -> "void*"
# hSourceHandle : HANDLE -> "void*"
# hTargetProcessHandle : HANDLE -> "void*"
# lpTargetHandle : HANDLE* out -> "void*"
# dwDesiredAccess : DWORD -> "dword"
# bInheritHandle : BOOL -> "bool"
# dwOptions : DUPLICATE_HANDLE_OPTIONS -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "kernel32" fn DuplicateHandle(
hSourceProcessHandle: ?*anyopaque, // HANDLE
hSourceHandle: ?*anyopaque, // HANDLE
hTargetProcessHandle: ?*anyopaque, // HANDLE
lpTargetHandle: ?*anyopaque, // HANDLE* out
dwDesiredAccess: u32, // DWORD
bInheritHandle: i32, // BOOL
dwOptions: u32 // DUPLICATE_HANDLE_OPTIONS
) callconv(std.os.windows.WINAPI) i32;proc DuplicateHandle(
hSourceProcessHandle: pointer, # HANDLE
hSourceHandle: pointer, # HANDLE
hTargetProcessHandle: pointer, # HANDLE
lpTargetHandle: pointer, # HANDLE* out
dwDesiredAccess: uint32, # DWORD
bInheritHandle: int32, # BOOL
dwOptions: uint32 # DUPLICATE_HANDLE_OPTIONS
): int32 {.importc: "DuplicateHandle", stdcall, dynlib: "KERNEL32.dll".}pragma(lib, "kernel32");
extern(Windows)
int DuplicateHandle(
void* hSourceProcessHandle, // HANDLE
void* hSourceHandle, // HANDLE
void* hTargetProcessHandle, // HANDLE
void* lpTargetHandle, // HANDLE* out
uint dwDesiredAccess, // DWORD
int bInheritHandle, // BOOL
uint dwOptions // DUPLICATE_HANDLE_OPTIONS
);ccall((:DuplicateHandle, "KERNEL32.dll"), stdcall, Int32,
(Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, Ptr{Cvoid}, UInt32, Int32, UInt32),
hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
# hSourceProcessHandle : HANDLE -> Ptr{Cvoid}
# hSourceHandle : HANDLE -> Ptr{Cvoid}
# hTargetProcessHandle : HANDLE -> Ptr{Cvoid}
# lpTargetHandle : HANDLE* out -> Ptr{Cvoid}
# dwDesiredAccess : DWORD -> UInt32
# bInheritHandle : BOOL -> Int32
# dwOptions : DUPLICATE_HANDLE_OPTIONS -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t DuplicateHandle(
void* hSourceProcessHandle,
void* hSourceHandle,
void* hTargetProcessHandle,
void* lpTargetHandle,
uint32_t dwDesiredAccess,
int32_t bInheritHandle,
uint32_t dwOptions);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
-- hSourceProcessHandle : HANDLE
-- hSourceHandle : HANDLE
-- hTargetProcessHandle : HANDLE
-- lpTargetHandle : HANDLE* out
-- dwDesiredAccess : DWORD
-- bInheritHandle : BOOL
-- dwOptions : DUPLICATE_HANDLE_OPTIONS
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const DuplicateHandle = lib.func('__stdcall', 'DuplicateHandle', 'int32_t', ['void *', 'void *', 'void *', 'void *', 'uint32_t', 'int32_t', 'uint32_t']);
// DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
// hSourceProcessHandle : HANDLE -> 'void *'
// hSourceHandle : HANDLE -> 'void *'
// hTargetProcessHandle : HANDLE -> 'void *'
// lpTargetHandle : HANDLE* out -> 'void *'
// dwDesiredAccess : DWORD -> 'uint32_t'
// bInheritHandle : BOOL -> 'int32_t'
// dwOptions : DUPLICATE_HANDLE_OPTIONS -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("KERNEL32.dll", {
DuplicateHandle: { parameters: ["pointer", "pointer", "pointer", "pointer", "u32", "i32", "u32"], result: "i32" },
});
// lib.symbols.DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)
// hSourceProcessHandle : HANDLE -> "pointer"
// hSourceHandle : HANDLE -> "pointer"
// hTargetProcessHandle : HANDLE -> "pointer"
// lpTargetHandle : HANDLE* out -> "pointer"
// dwDesiredAccess : DWORD -> "u32"
// bInheritHandle : BOOL -> "i32"
// dwOptions : DUPLICATE_HANDLE_OPTIONS -> "u32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t DuplicateHandle(
void* hSourceProcessHandle,
void* hSourceHandle,
void* hTargetProcessHandle,
void* lpTargetHandle,
uint32_t dwDesiredAccess,
int32_t bInheritHandle,
uint32_t dwOptions);
C, "KERNEL32.dll");
// $ffi->DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
// hSourceProcessHandle : HANDLE
// hSourceHandle : HANDLE
// hTargetProcessHandle : HANDLE
// lpTargetHandle : HANDLE* out
// dwDesiredAccess : DWORD
// bInheritHandle : BOOL
// dwOptions : DUPLICATE_HANDLE_OPTIONS
// 構造体/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 DuplicateHandle(
Pointer hSourceProcessHandle, // HANDLE
Pointer hSourceHandle, // HANDLE
Pointer hTargetProcessHandle, // HANDLE
Pointer lpTargetHandle, // HANDLE* out
int dwDesiredAccess, // DWORD
boolean bInheritHandle, // BOOL
int dwOptions // DUPLICATE_HANDLE_OPTIONS
);
}@[Link("kernel32")]
lib LibKERNEL32
fun DuplicateHandle = DuplicateHandle(
hSourceProcessHandle : Void*, # HANDLE
hSourceHandle : Void*, # HANDLE
hTargetProcessHandle : Void*, # HANDLE
lpTargetHandle : Void*, # HANDLE* out
dwDesiredAccess : UInt32, # DWORD
bInheritHandle : Int32, # BOOL
dwOptions : UInt32 # DUPLICATE_HANDLE_OPTIONS
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef DuplicateHandleNative = Int32 Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, Uint32, Int32, Uint32);
typedef DuplicateHandleDart = int Function(Pointer<Void>, Pointer<Void>, Pointer<Void>, Pointer<Void>, int, int, int);
final DuplicateHandle = DynamicLibrary.open('KERNEL32.dll')
.lookupFunction<DuplicateHandleNative, DuplicateHandleDart>('DuplicateHandle');
// hSourceProcessHandle : HANDLE -> Pointer<Void>
// hSourceHandle : HANDLE -> Pointer<Void>
// hTargetProcessHandle : HANDLE -> Pointer<Void>
// lpTargetHandle : HANDLE* out -> Pointer<Void>
// dwDesiredAccess : DWORD -> Uint32
// bInheritHandle : BOOL -> Int32
// dwOptions : DUPLICATE_HANDLE_OPTIONS -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function DuplicateHandle(
hSourceProcessHandle: THandle; // HANDLE
hSourceHandle: THandle; // HANDLE
hTargetProcessHandle: THandle; // HANDLE
lpTargetHandle: Pointer; // HANDLE* out
dwDesiredAccess: DWORD; // DWORD
bInheritHandle: BOOL; // BOOL
dwOptions: DWORD // DUPLICATE_HANDLE_OPTIONS
): BOOL; stdcall;
external 'KERNEL32.dll' name 'DuplicateHandle';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "DuplicateHandle"
c_DuplicateHandle :: Ptr () -> Ptr () -> Ptr () -> Ptr () -> Word32 -> CInt -> Word32 -> IO CInt
-- hSourceProcessHandle : HANDLE -> Ptr ()
-- hSourceHandle : HANDLE -> Ptr ()
-- hTargetProcessHandle : HANDLE -> Ptr ()
-- lpTargetHandle : HANDLE* out -> Ptr ()
-- dwDesiredAccess : DWORD -> Word32
-- bInheritHandle : BOOL -> CInt
-- dwOptions : DUPLICATE_HANDLE_OPTIONS -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let duplicatehandle =
foreign "DuplicateHandle"
((ptr void) @-> (ptr void) @-> (ptr void) @-> (ptr void) @-> uint32_t @-> int32_t @-> uint32_t @-> returning int32_t)
(* hSourceProcessHandle : HANDLE -> (ptr void) *)
(* hSourceHandle : HANDLE -> (ptr void) *)
(* hTargetProcessHandle : HANDLE -> (ptr void) *)
(* lpTargetHandle : HANDLE* out -> (ptr void) *)
(* dwDesiredAccess : DWORD -> uint32_t *)
(* bInheritHandle : BOOL -> int32_t *)
(* dwOptions : DUPLICATE_HANDLE_OPTIONS -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)
(cffi:defcfun ("DuplicateHandle" duplicate-handle :convention :stdcall) :int32
(h-source-process-handle :pointer) ; HANDLE
(h-source-handle :pointer) ; HANDLE
(h-target-process-handle :pointer) ; HANDLE
(lp-target-handle :pointer) ; HANDLE* out
(dw-desired-access :uint32) ; DWORD
(b-inherit-handle :int32) ; BOOL
(dw-options :uint32)) ; DUPLICATE_HANDLE_OPTIONS
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $DuplicateHandle = Win32::API::More->new('KERNEL32',
'BOOL DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, HANDLE lpTargetHandle, DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwOptions)');
# my $ret = $DuplicateHandle->Call($hSourceProcessHandle, $hSourceHandle, $hTargetProcessHandle, $lpTargetHandle, $dwDesiredAccess, $bInheritHandle, $dwOptions);
# hSourceProcessHandle : HANDLE -> HANDLE
# hSourceHandle : HANDLE -> HANDLE
# hTargetProcessHandle : HANDLE -> HANDLE
# lpTargetHandle : HANDLE* out -> HANDLE
# dwDesiredAccess : DWORD -> DWORD
# bInheritHandle : BOOL -> BOOL
# dwOptions : DUPLICATE_HANDLE_OPTIONS -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f CloseHandle — オープンされたオブジェクトハンドルを閉じる。