次の方法で共有


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

複製するハンドル。 これは、ソース プロセスのコンテキストで有効なオープン オブジェクト ハンドルです。 ハンドルを複製できるオブジェクトの一覧については、次の「解説」セクションを参照してください。

hSourceHandleGetCurrentProcess または GetCurrentThread によって返される擬似ハンドルである場合、hSourceProcessHandleDuplicateHandle を呼び出すプロセスのハンドルである必要があります。

[in] hTargetProcessHandle

重複したハンドルを受け取るプロセスのハンドル。 ハンドルには、PROCESS_DUP_HANDLEアクセス権が必要です。

このパラメーターは省略可能であり、DUPLICATE_CLOSE_SOURCE フラグが Optionsで設定されている場合は 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 は、次の種類のオブジェクトにハンドルを複製できます。

オブジェクト 説明
アクセス トークン ハンドルは、CreateRestrictedTokenDuplicateToken、DuplicateTokenExOpenProcessToken、または OpenThreadToken 関数によって返されます。
変更通知 ハンドルは FindFirstChangeNotification 関数によって返されます。
通信デバイス ハンドルは CreateFile 関数によって返されます。
コンソール入力 ハンドルは、CONIN$ が指定されている場合は CreateFile 関数によって、STD_INPUT_HANDLEが指定されている場合は GetStdHandle 関数によって返されます。 コンソール ハンドルは、同じプロセスでのみ使用するために複製できます。
コンソール画面バッファー ハンドルは、CONOUT$ が指定されている場合は CreateFile 関数によって、STD_OUTPUT_HANDLEが指定されている場合は GetStdHandle 関数によって返されます。 コンソール ハンドルは、同じプロセスでのみ使用するために複製できます。
デスクトップ ハンドルは GetThreadDesktop 関数によって返されます。
出来事 ハンドルは、 CreateEvent または OpenEvent 関数によって返されます。
ファイル ハンドルは CreateFile 関数によって返されます。
ファイル マッピング ハンドルは CreateFileMapping 関数によって返されます。
仕事 ハンドルは CreateJobObject 関数によって返されます。
Mailslot ハンドルは CreateMailslot 関数によって返されます。
ミューテックス ハンドルは、 CreateMutex または [OpenMutex](.. によって返されます。/synchapi/nf-synchapi-openmutexw.md) 関数。
パイプ 名前付きパイプ ハンドルは、 CreateNamedPipe または CreateFile 関数によって返されます。 匿名パイプ ハンドルは、 CreatePipe 関数によって返されます。
プロセス ハンドルは、 CreateProcessGetCurrentProcess、または OpenProcess 関数によって返されます。
レジストリ キー ハンドルは、 RegCreateKeyRegCreateKeyExRegOpenKey、または RegOpenKeyEx 関数によって返されます。 RegConnectRegistry 関数によって返されるレジストリ キー ハンドルは、DuplicateHandle の呼び出しでは使用できないことに注意してください。
セマフォ ハンドルは、 CreateSemaphore または OpenSemaphore 関数によって返されます。
スレッド ハンドルは、 CreateProcessCreateThreadCreateRemoteThread、または GetCurrentThread 関数によって返されます。
タイマー ハンドルは、 CreateWaitableTimerW または OpenWaitableTimerW 関数によって返されます。
トランザクション ハンドルは CreateTransaction 関数によって返されます。
窓ステーション ハンドルは GetProcessWindowStation 関数によって返されます。
 

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

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

通常、ターゲット プロセスは、ハンドルを使用してプロセスが完了すると、重複したハンドルを閉じます。 ソース プロセスから重複するハンドルを閉じるには、次のパラメーターを指定して DuplicateHandle を呼び出します。

  • ハンドルを作成した DuplicateHandle 呼び出しから、hSourceProcessHandle をターゲット プロセスに設定します。
  • hSourceHandle を重複するハンドルに設定して閉じます。
  • hTargetProcessHandleNULL に設定します。
  • 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 アプリ]
ターゲット プラットフォーム ウィンドウズ
ヘッダー handleapi.h (Windows.h を含む)
図書館 カーネル32.lib
DLL Kernel32.dll

こちらも参照ください

CloseHandle の

継承の処理

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