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

重複するハンドルを受け取る変数へのポインター。 このハンドル値は、ターゲット プロセスのコンテキストで有効です。

hSourceHandleGetCurrentProcess または GetCurrentThread によって返される擬似ハンドルの場合、DuplicateHandle は、それぞれプロセスまたはスレッドに実際のハンドルに変換します。

lpTargetHandleNULL の場合、関数はハンドルを複製しますが、重複するハンドル値は呼び出し元に返しません。 この動作は、この関数の以前のバージョンとの下位互換性のためにのみ存在します。 ターゲット プロセスが終了するまでシステム リソースが失われるので、この機能を使用しないでください。

hTargetProcessHandleNULL の場合、このパラメーターは無視されます。

[in] dwDesiredAccess

新しいハンドルに対して要求されたアクセス。 オブジェクトの種類ごとに指定できるフラグについては、次の「解説」セクションを参照してください。

dwOptions パラメーターでDUPLICATE_SAME_ACCESS フラグが指定されている場合、このパラメーターは無視されます。 それ以外の場合、指定できるフラグは、ハンドルを複製するオブジェクトの種類によって異なります。

hTargetProcessHandleNULL の場合、このパラメーターは無視されます。

[in] bInheritHandle

ハンドルが継承可能かどうかを示す変数。 TRUE の場合、重複するハンドルは、ターゲット プロセスによって作成された新しいプロセスによって継承できます。 FALSE の場合、新しいハンドルを継承できません。

hTargetProcessHandleNULL の場合、このパラメーターは無視されます。

[in] dwOptions

オプションのアクション。 このパラメーターには、0 または次の値の任意の組み合わせを指定できます。

意味
DUPLICATE_CLOSE_SOURCE
0x00000001
ソース ハンドルを閉じます。 これは、返されたエラー状態に関係なく発生します。
DUPLICATE_SAME_ACCESS
0x00000002
dwDesiredAccess パラメーターを無視します。 重複するハンドルには、ソース ハンドルと同じアクセス権があります。

戻り値

関数が成功すると、戻り値は 0 以外になります。

関数が失敗した場合は、0 を返します。 詳細なエラー情報を得るには、GetLastError を呼び出します。

解説

重複するハンドルは、元のハンドルと同じオブジェクトを参照します。 したがって、オブジェクトに対する変更は、両方のハンドルを介して反映されます。 たとえば、ファイル ハンドルを複製した場合、現在のファイル位置は常に両方のハンドルで同じです。 ファイル ハンドルのファイル位置が異なる場合は、 CreateFile 関数を使用して、同じファイルへのアクセスを共有するファイル ハンドルを作成します。

DuplicateHandle は、ソース プロセスまたはターゲット プロセス (またはソース プロセスとターゲット プロセスの両方であるプロセス) によって呼び出すことができます。 たとえば、プロセスで DuplicateHandle を 使用して、継承可能なハンドルの継承不可能な重複、または元のハンドルとは異なるアクセス権を持つハンドルを作成できます。

ソース プロセスでは 、GetCurrentProcess 関数を使用して、それ自体へのハンドルを取得します。 このハンドルは擬似ハンドルですが、 DuplicateHandle は実際のプロセス ハンドルに変換します。 ターゲット プロセス ハンドルを取得するには、何らかの形式のプロセス間通信 (名前付きパイプや共有メモリなど) を使用して、プロセス識別子をソース プロセスに通信する必要がある場合があります。 ソース プロセスでは、 OpenProcess 関数でこの識別子を使用して、ターゲット プロセスへのハンドルを取得できます。

DuplicateHandle を呼び出すプロセスがターゲット プロセスでなければ、ソース プロセスはプロセス間通信を使用して、重複するハンドルの値をターゲット プロセスに渡す必要があります。

DuplicateHandle を使用すると、32 ビット プロセスと 64 ビット プロセスの間でハンドルを複製できます。 結果のハンドルは、ターゲット プロセスで動作するように適切なサイズに設定されます。 詳細については、「 プロセスの相互運用性」を参照してください。

DuplicateHandle では、次の種類のオブジェクトにハンドルを複製できます。

Object 説明
アクセス トークン ハンドルは、 CreateRestrictedTokenDuplicateTokenDuplicateTokenExOpenProcessToken、または 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 ハンドルは、 CreateProcessGetCurrentProcess、または OpenProcess 関数によって返されます。
レジストリ キー ハンドルは、RegCreateKeyRegCreateKeyEx、RegOpenKey、または RegOpenKeyEx 関数によって返されます。 RegConnectRegistry 関数によって返されるレジストリ キー ハンドルは、DuplicateHandle の呼び出しでは使用できないことに注意してください。
Semaphore ハンドルは、 CreateSemaphore 関数または OpenSemaphore 関数によって返されます。
スレッド ハンドルは、 CreateProcessCreateThreadCreateRemoteThread、または GetCurrentThread 関数によって返されます。
Timer ハンドルは、 CreateWaitableTimerW または OpenWaitableTimerW 関数によって返されます。
トランザクション ハンドルは CreateTransaction 関数によって返されます。
ウィンドウステーション ハンドルは GetProcessWindowStation 関数によって返されます。
 

DuplicateHandle を使用して、次のオブジェクトにハンドルを複製しないでください。

  • I/O 完了ポート。 エラーは返されませんが、重複するハンドルは使用できません。
  • ソケット。 エラーは返されませんが、ターゲット プロセスで Winsock によって重複ハンドルが認識されない可能性があります。 また、 DuplicateHandle を 使用すると、基になるオブジェクトの内部参照カウントに干渉します。 ソケット ハンドルを複製するには、 WSADuplicateSocket 関数を使用します。
  • GetCurrentProcess 関数または GetCurrentThread 関数によって返される以外の擬似ハンドル。
dwDesiredAccess パラメーターは、新しいハンドルのアクセス権を指定します。 すべてのオブジェクトは 、標準のアクセス権をサポートします。 オブジェクトは、オブジェクトの種類に応じて追加のアクセス権をサポートする場合もあります。 詳細については、次のトピックを参照してください。 場合によっては、新しいハンドルは元のハンドルよりも多くのアクセス権を持つことができます。 ただし、その他の場合、 DuplicateHandle は元のハンドルよりも多くのアクセス権を持つハンドルを作成できません。 たとえば、GENERIC_READアクセス権を使用して作成されたファイル ハンドルは、GENERIC_READとGENERIC_WRITEの両方のアクセス権を持つように複製できません。

通常、ターゲット プロセスは、そのプロセスがハンドルを使用して終了したときに、重複するハンドルを閉じます。 ソース プロセスから重複するハンドルを閉じるには、次のパラメーターを指定 して 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

関連項目

CloseHandle

継承の処理

ハンドル関数とオブジェクト関数