DuplicateHandle 関数 (handleapi.h)
オブジェクト ハンドルを複製します。
構文
BOOL DuplicateHandle(
[in] HANDLE hSourceProcessHandle,
[in] HANDLE hSourceHandle,
[in] HANDLE hTargetProcessHandle,
[out] LPHANDLE lpTargetHandle,
[in] DWORD dwDesiredAccess,
[in] BOOL bInheritHandle,
[in] DWORD dwOptions
);
パラメーター
[in] hSourceProcessHandle
重複するハンドルを持つプロセスへのハンドル。
ハンドルには、PROCESS_DUP_HANDLEアクセス権が必要です。 詳細については、「 プロセス のセキュリティとアクセス権」を参照してください。
[in] hSourceHandle
複製するハンドル。 これは、ソース プロセスのコンテキストで有効なオープン オブジェクト ハンドルです。 ハンドルを複製できるオブジェクトの一覧については、次の「解説」セクションを参照してください。
[in] hTargetProcessHandle
重複したハンドルを受け取るプロセスへのハンドル。 ハンドルには、PROCESS_DUP_HANDLEアクセス権が必要です。
このパラメーターは省略可能であり、 [オプション] でDUPLICATE_CLOSE_SOURCE フラグが設定されている場合は NULL として指定できます。
[out] lpTargetHandle
重複するハンドルを受け取る変数へのポインター。 このハンドル値は、ターゲット プロセスのコンテキストで有効です。
hSourceHandle が GetCurrentProcess または GetCurrentThread によって返される擬似ハンドルの場合、DuplicateHandle は、それぞれプロセスまたはスレッドに実際のハンドルに変換します。
lpTargetHandle が NULL の場合、関数はハンドルを複製しますが、重複するハンドル値は呼び出し元に返しません。 この動作は、この関数の以前のバージョンとの下位互換性のためにのみ存在します。 ターゲット プロセスが終了するまでシステム リソースが失われるので、この機能を使用しないでください。
hTargetProcessHandle が NULL の場合、このパラメーターは無視されます。
[in] dwDesiredAccess
新しいハンドルに対して要求されたアクセス。 オブジェクトの種類ごとに指定できるフラグについては、次の「解説」セクションを参照してください。
dwOptions パラメーターでDUPLICATE_SAME_ACCESS フラグが指定されている場合、このパラメーターは無視されます。 それ以外の場合、指定できるフラグは、ハンドルを複製するオブジェクトの種類によって異なります。
hTargetProcessHandle が NULL の場合、このパラメーターは無視されます。
[in] bInheritHandle
ハンドルが継承可能かどうかを示す変数。 TRUE の場合、重複するハンドルは、ターゲット プロセスによって作成された新しいプロセスによって継承できます。 FALSE の場合、新しいハンドルを継承できません。
hTargetProcessHandle が NULL の場合、このパラメーターは無視されます。
[in] dwOptions
オプションのアクション。 このパラメーターには、0 または次の値の任意の組み合わせを指定できます。
値 | 意味 |
---|---|
|
ソース ハンドルを閉じます。 これは、返されたエラー状態に関係なく発生します。 |
|
dwDesiredAccess パラメーターを無視します。 重複するハンドルには、ソース ハンドルと同じアクセス権があります。 |
戻り値
関数が成功すると、戻り値は 0 以外になります。
関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。
解説
重複するハンドルは、元のハンドルと同じオブジェクトを参照します。 したがって、オブジェクトに対する変更は、両方のハンドルを介して反映されます。 たとえば、ファイル ハンドルを複製した場合、現在のファイル位置は常に両方のハンドルで同じです。 ファイル ハンドルのファイル位置が異なる場合は、 CreateFile 関数を使用して、同じファイルへのアクセスを共有するファイル ハンドルを作成します。
DuplicateHandle は、ソース プロセスまたはターゲット プロセス (またはソース プロセスとターゲット プロセスの両方であるプロセス) によって呼び出すことができます。 たとえば、プロセスで DuplicateHandle を 使用して、継承可能なハンドルの継承不可能な重複、または元のハンドルとは異なるアクセス権を持つハンドルを作成できます。
ソース プロセスでは 、GetCurrentProcess 関数を使用して、それ自体へのハンドルを取得します。 このハンドルは擬似ハンドルですが、 DuplicateHandle は実際のプロセス ハンドルに変換します。 ターゲット プロセス ハンドルを取得するには、何らかの形式のプロセス間通信 (名前付きパイプや共有メモリなど) を使用して、プロセス識別子をソース プロセスに通信する必要がある場合があります。 ソース プロセスでは、 OpenProcess 関数でこの識別子を使用して、ターゲット プロセスへのハンドルを取得できます。
DuplicateHandle を呼び出すプロセスがターゲット プロセスでなければ、ソース プロセスはプロセス間通信を使用して、重複するハンドルの値をターゲット プロセスに渡す必要があります。
DuplicateHandle を使用すると、32 ビット プロセスと 64 ビット プロセスの間でハンドルを複製できます。 結果のハンドルは、ターゲット プロセスで動作するように適切なサイズに設定されます。 詳細については、「 プロセスの相互運用性」を参照してください。
DuplicateHandle では、次の種類のオブジェクトにハンドルを複製できます。
Object | 説明 |
---|---|
アクセス トークン | ハンドルは、 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 関数によって返されます。 |
Mailslot | ハンドルは CreateMailslot 関数によって返されます。 |
Mutex | ハンドルは、 CreateMutex または [OpenMutex ](.. によって返されます。/synchapi/nf-synchapi-openmutexw.md) 関数。 |
Pipe | 名前付きパイプ ハンドルは、 CreateNamedPipe または CreateFile 関数によって返されます。 匿名パイプ ハンドルは、 CreatePipe 関数によって返されます。 |
Process | ハンドルは、 CreateProcess、 GetCurrentProcess、または OpenProcess 関数によって返されます。 |
レジストリ キー | ハンドルは、RegCreateKey、RegCreateKeyEx、RegOpenKey、または RegOpenKeyEx 関数によって返されます。 RegConnectRegistry 関数によって返されるレジストリ キー ハンドルは、DuplicateHandle の呼び出しでは使用できないことに注意してください。 |
Semaphore | ハンドルは、 CreateSemaphore 関数または OpenSemaphore 関数によって返されます。 |
スレッド | ハンドルは、 CreateProcess、 CreateThread、 CreateRemoteThread、または GetCurrentThread 関数によって返されます。 |
Timer | ハンドルは、 CreateWaitableTimerW または OpenWaitableTimerW 関数によって返されます。 |
トランザクション | ハンドルは CreateTransaction 関数によって返されます。 |
ウィンドウステーション | ハンドルは GetProcessWindowStation 関数によって返されます。 |
DuplicateHandle を使用して、次のオブジェクトにハンドルを複製しないでください。
- I/O 完了ポート。 エラーは返されませんが、重複するハンドルは使用できません。
- ソケット。 エラーは返されませんが、ターゲット プロセスで Winsock によって重複ハンドルが認識されない可能性があります。 また、 DuplicateHandle を 使用すると、基になるオブジェクトの内部参照カウントに干渉します。 ソケット ハンドルを複製するには、 WSADuplicateSocket 関数を使用します。
- GetCurrentProcess 関数または GetCurrentThread 関数によって返される以外の擬似ハンドル。
- デスクトップ のセキュリティとアクセス権
- ファイルのセキュリティとアクセス権
- ファイル マッピングのセキュリティとアクセス権
- ジョブ オブジェクトのセキュリティとアクセス権
- セキュリティとアクセス権の処理
- レジストリ キーのセキュリティとアクセス権
- 同期オブジェクトのセキュリティとアクセス権
- スレッド セキュリティとアクセス権
- Window-Station のセキュリティとアクセス権
通常、ターゲット プロセスは、そのプロセスがハンドルを使用して終了したときに、重複するハンドルを閉じます。 ソース プロセスから重複するハンドルを閉じるには、次のパラメーターを指定 して DuplicateHandle を呼び出します。
- ハンドルを作成した DuplicateHandle 呼び出しから、hSourceProcessHandle をターゲット プロセスに設定します。
- 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;
}
要件
要件 | 値 |
---|---|
サポートされている最小のクライアント | Windows 2000 Professional [デスクトップ アプリ |UWP アプリ] |
サポートされている最小のサーバー | Windows 2000 Server [デスクトップ アプリ |UWP アプリ] |
対象プラットフォーム | Windows |
ヘッダー | handleapi.h (Windows.h を含む) |
Library | Kernel32.lib |
[DLL] | Kernel32.dll |