复制对象句柄。
语法
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
要复制的句柄。 这是在源进程的上下文中有效的开放对象句柄。 有关可以复制其句柄的对象的列表,请参阅以下“备注”部分。
如果 hSourceHandle 是由 GetCurrentProcess 或 GetCurrentThread 返回的伪句柄,则 hSourceProcessHandle 应该是调用 DuplicateHandle 的进程句柄。
[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
可选作。 此参数可以是零,也可以是以下值的任意组合。
价值 | 含义 |
---|---|
|
关闭源句柄。 无论返回的任何错误状态如何,都会发生这种情况。 |
|
忽略 dwDesiredAccess 参数。 重复句柄具有与源句柄相同的访问权限。 |
返回值
如果函数成功,则返回值为非零。
如果函数失败,则返回值为零。 若要获取扩展的错误信息,请调用 GetLastError。
注解
重复句柄引用与原始句柄相同的对象。 因此,对对象所做的任何更改都通过这两个句柄反映。 例如,如果复制文件句柄,则两个句柄的当前文件位置始终相同。 若要使文件句柄具有不同的文件位置,请使用 CreateFile 函数创建共享对同一文件的访问权限的文件句柄。
源进程或目标进程(或源进程和目标进程)可以调用 DuplicateHandle。 例如,进程可以使用 DuplicateHandle 创建可继承句柄的非可继承副本,或者具有与原始句柄不同的访问权限的句柄。
源进程使用 GetCurrentProcess 函数获取自身句柄。 此句柄是伪句柄,但 DuplicateHandle 将其转换为实际进程句柄。 若要获取目标进程句柄,可能需要使用某种形式的进程间通信(例如命名管道或共享内存)将进程标识符传达给源进程。 源进程可以使用 OpenProcess 函数中的此标识符来获取目标进程的句柄。
如果调用 DuplicateHandle 的进程不是目标进程,则源进程必须使用进程间通信将重复句柄的值传递给目标进程。
DuplicateHandle 可用于在 32 位进程和 64 位进程之间复制句柄。 生成的句柄的大小适当,用于在目标进程中工作。 有关详细信息,请参阅 进程互作性。
DuplicateHandle 可以复制以下类型的对象的句柄。
物体 | 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 函数返回句柄。 |
互斥 | 句柄由 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 函数返回的处理以外的伪句柄。
- 桌面安全和访问权限
- 文件安全性和访问权限
- File-Mapping 安全和访问权限
- 作业对象安全和访问权限
- 进程安全性和访问权限
- 注册表项安全和访问权限
- 同步对象安全性和访问权限
- 线程安全和访问权限
- 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) |
图书馆 | 内核 32.lib |
DLL | Kernel32.dll |