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 Description
액세스 토큰 핸들은 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) 함수입니다.
파이프 명명된 파이프 핸들은 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 함수에서 반환하는 것 이외의 의사 핸들입니다.
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 포함)
라이브러리 Kernel32.lib
DLL Kernel32.dll

참고 항목

CloseHandle

상속 처리

핸들 및 개체 함수