DuplicateHandle Function

Duplicates an object handle.

Syntax

C++
BOOL WINAPI DuplicateHandle(
  __in   HANDLE hSourceProcessHandle,
  __in   HANDLE hSourceHandle,
  __in   HANDLE hTargetProcessHandle,
  __out  LPHANDLE lpTargetHandle,
  __in   DWORD dwDesiredAccess,
  __in   BOOL bInheritHandle,
  __in   DWORD dwOptions
);

Parameters

hSourceProcessHandle [in]

A handle to the process with the handle to be duplicated.

The handle must have the PROCESS_DUP_HANDLE access right. For more information, see Process Security and Access Rights.

hSourceHandle [in]

The handle to be duplicated. This is an open object handle that is valid in the context of the source process. For a list of objects whose handles can be duplicated, see the following Remarks section.

hTargetProcessHandle [in]

A handle to the process that is to receive the duplicated handle. The handle must have the PROCESS_DUP_HANDLE access right.

lpTargetHandle [out]

A pointer to a variable that receives the duplicate handle. This handle value is valid in the context of the target process.

If hSourceHandle is a pseudo handle returned by GetCurrentProcess or GetCurrentThread, DuplicateHandle converts it to a real handle to a process or thread, respectively.

If lpTargetHandle is NULL, the function duplicates the handle, but does not return the duplicate handle value to the caller. This behavior exists only for backward compatibility with previous versions of this function. You should not use this feature, as you will lose system resources until the target process terminates.

dwDesiredAccess [in]

The access requested for the new handle. For the flags that can be specified for each object type, see the following Remarks section.

This parameter is ignored if the dwOptions parameter specifies the DUPLICATE_SAME_ACCESS flag. Otherwise, the flags that can be specified depend on the type of object whose handle is to be duplicated.

bInheritHandle [in]

A variable that indicates whether the handle is inheritable. If TRUE, the duplicate handle can be inherited by new processes created by the target process. If FALSE, the new handle cannot be inherited.

dwOptions [in]

Optional actions. This parameter can be zero, or any combination of the following values.

ValueMeaning
DUPLICATE_CLOSE_SOURCE
0x00000001

Closes the source handle. This occurs regardless of any error status returned.

DUPLICATE_SAME_ACCESS
0x00000002

Ignores the dwDesiredAccess parameter. The duplicate handle has the same access as the source handle.

 

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.

Remarks

The duplicate handle refers to the same object as the original handle. Therefore, any changes to the object are reflected through both handles. For example, if you duplicate a file handle, the current file position is always the same for both handles. For file handles to have different file positions, use the CreateFile function to create file handles that share access to the same file.

DuplicateHandle can be called by either the source process or the target process (or a process that is both the source and target process). For example, a process can use DuplicateHandle to create a noninheritable duplicate of an inheritable handle, or a handle with different access than the original handle.

The source process uses the GetCurrentProcess function to get a handle to itself. This handle is a pseudo handle, but DuplicateHandle converts it to a real process handle. To get the target process handle, it may be necessary to use some form of interprocess communication (for example, a named pipe or shared memory) to communicate the process identifier to the source process. The source process can use this identifier in the OpenProcess function to obtain a handle to the target process.

If the process that calls DuplicateHandle is not also the target process, the source process must use interprocess communication to pass the value of the duplicate handle to the target process.

DuplicateHandle can be used to duplicate a handle between a 32-bit process and a 64-bit process. The resulting handle is appropriately sized to work in the target process. For more information, see Process Interoperability.

DuplicateHandle can duplicate handles to the following types of objects.

ObjectDescription
Access tokenThe handle is returned by the CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken function.
Change notificationThe handle is returned by the FindFirstChangeNotification function.
Communications deviceThe handle is returned by the CreateFile function.
Console inputThe handle is returned by the CreateFile function when CONIN$ is specified, or by the GetStdHandle function when STD_INPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
Console screen bufferThe handle is returned by the CreateFile function when CONOUT$ is specified, or by the GetStdHandle function when STD_OUTPUT_HANDLE is specified. Console handles can be duplicated for use only in the same process.
DesktopThe handle is returned by the GetThreadDesktop function.
EventThe handle is returned by the CreateEvent or OpenEvent function.
FileThe handle is returned by the CreateFile function.
File mappingThe handle is returned by the CreateFileMapping function.
JobThe handle is returned by the CreateJobObject function.
MailslotThe handle is returned by the CreateMailslot function.
MutexThe handle is returned by the CreateMutex or OpenMutex function.
PipeA named pipe handle is returned by the CreateNamedPipe or CreateFile function. An anonymous pipe handle is returned by the CreatePipe function.
ProcessThe handle is returned by the CreateProcess, GetCurrentProcess, or OpenProcess function.
Registry keyThe handle is returned by the RegCreateKey, RegCreateKeyEx, RegOpenKey, or RegOpenKeyEx function. Note that registry key handles returned by the RegConnectRegistry function cannot be used in a call to DuplicateHandle.
SemaphoreThe handle is returned by the CreateSemaphore or OpenSemaphore function.
ThreadThe handle is returned by the CreateProcess, CreateThread, CreateRemoteThread, or GetCurrentThread function
TimerThe handle is returned by the CreateWaitableTimer or OpenWaitableTimer function.
TransactionThe handle is returned by the CreateTransaction function.
Window stationThe handle is returned by the GetProcessWindowStation function.

 

You should not use DuplicateHandle to duplicate handles to the following objects:

  • I/O completion ports. No error is returned, but the duplicate handle cannot be used.
  • Sockets. No error is returned, but the duplicate handle may not be recognized by Winsock at the target process. Also, using DuplicateHandle interferes with internal reference counting on the underlying object. To duplicate a socket handle, use the WSADuplicateSocket function.

The dwDesiredAccess parameter specifies the new handle's access rights. All objects support the standard access rights. Objects may also support additional access rights depending on the object type. For more information, see the following topics:

In some cases, the new handle can have more access rights than the original handle. However, in other cases, DuplicateHandle cannot create a handle with more access rights than the original. For example, a file handle created with the GENERIC_READ access right cannot be duplicated so that it has both the GENERIC_READ and GENERIC_WRITE access right.

Normally the target process closes a duplicated handle when that process is finished using the handle. To close a duplicated handle from the source process, call DuplicateHandle with the following parameters:

  • Set hSourceProcessHandle to the target process from the DuplicateHandle call that created the handle.
  • Set hSourceHandle to the duplicated handle to close.
  • Set lpTargetHandle to NULL.
  • Set dwOptions to DUPLICATE_CLOSE_SOURCE.

Examples

The following example creates a mutex, duplicates a handle to the mutex, and passes it to another thread. Duplicating the handle ensures that the reference count is increased so that the mutex object will not be destroyed until both threads have closed the handle.

#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;
}

Requirements

Minimum supported clientWindows 2000 Professional
Minimum supported serverWindows 2000 Server
HeaderWinbase.h (include Windows.h)
LibraryKernel32.lib
DLLKernel32.dll

See Also

CloseHandle
Handle and Object Functions
Handle Inheritance

Send comments about this topic to Microsoft

Build date: 11/19/2009

Tags :


Community Content

koglian
Why do I need PROCESS_DUP_HANDLE right on hTargetProcessHandle?

If i duplicate a handle of my own process (let's say an EventHandle) to some other process to synchronize on, why would i need to have the PROCESS_DUP_HANDLE access right of the target process, like it is indicated in the parameter description of hTargetProcessHandle. I mean, I am not duplicating a handle of the target but of my own process, i'm just targeting it to the target process.


I couldn't even think of a way my process could somehow take control over the target process by duplicating a handle in it's context. I mean the target process still needs to accept this handle by some forms of inter process communication and can still verify the source process before it really decides to do anything with it.


I'm programming an RPC server service that communicates with many client processes and i need a form of async synchronization between the client and the server. When the client calls the RPC server I want the server to return an event handle in the clients context on which the client can call WaitForSingleObject and on which the server will call SetEvent when appropriate. Giving the RPC server the PROCESS_DUP_HANDLE access right on the client process handle is not option, because then i could gain full access by duplicating the pseudo handle of the client into my context and that would be a great security risk.


Thanks!


Page view tracker