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
接收重複句柄之變數的指標。 此句柄值在目標進程的內容中有效。
如果 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 可以複製下列類型的物件句柄。
Object | 描述 |
---|---|
存取權杖 | 句柄是由 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) 函式。 |
Pipe | 命名管道句柄是由 CreateNamedPipe 或 CreateFile 函式傳回。 CreatePipe 函式會傳回匿名管道句柄。 |
流程 | CreateProcess、GetCurrentProcess 或 OpenProcess 函式會傳回句柄。 |
登錄機碼 | RegCreateKey、RegCreateKeyEx、RegOpenKey 或 RegOpenKeyEx 函式會傳回句柄。 請注意, RegConnectRegistry 函式所傳回的登錄機碼句柄不能用於對 DuplicateHandle 的呼叫。 |
Semaphore | 句柄是由 CreateSemaphore 或 OpenSemaphore 函式傳回。 |
執行緒 | CreateProcess、CreateThread、CreateRemoteThread 或 GetCurrentThread 函式會傳回句柄 |
計時器 | CreateWaitableTimerW 或 OpenWaitableTimerW 函式會傳回句柄。 |
交易 | CreateTransaction 函式會傳回句柄。 |
視窗月臺 | GetProcessWindowStation 函式會傳回句柄。 |
您不應該使用 DuplicateHandle 來複製下列物件的句柄:
- I/O 完成埠。 不會傳回錯誤,但無法使用重複的句柄。
- 通訊端。 不會傳回任何錯誤,但目標進程的 Winsock 可能無法辨識重複的句柄。 此外,使用 DuplicateHandle 會干擾基礎對象的內部參考計數。 若要複製套接字句柄,請使用 WSADuplicateSocket 函式。
- 除了 GetCurrentProcess 或 GetCurrentThread 函式所傳回的虛擬句柄以外。
- 桌面安全性與訪問許可權
- 檔案安全性和訪問許可權
- 檔案對應安全性和訪問許可權
- 作業物件安全性和訪問許可權
- 處理安全性和訪問許可權
- 登錄機碼安全性和訪問許可權
- 同步處理物件安全性和訪問許可權
- 線程安全性和訪問許可權
- 視窗月台安全性和訪問許可權
目標進程通常會在使用句柄完成時關閉重複的句柄。 若要從來源進程關閉重複的句柄,請使用下列參數呼叫 DuplicateHandle :
- 從建立句柄的 DuplicateHandle 呼叫,將 hSourceProcessHandle 設定為目標進程。
- 將 hSourceHandle 設定為要關閉的重複句柄。
- 將 hTargetProcessHandle 設定為 NULL。
- 將 dwOptions 設定為 DUPLICATE_CLOSE_SOURCE。
範例
下列範例會建立 mutex、複製 mutex 的句柄,並將它傳遞給另一個線程。 複製句柄可確保參考計數增加,因此在兩個線程都關閉句柄之前,Mutex 物件將不會終結。
#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 專業版 [傳統型應用程式 |UWP 應用程式] |
最低支援的伺服器 | Windows 2000 Server [傳統型應用程式 |UWP 應用程式] |
目標平台 | Windows |
標頭 | handleapi.h (包含 Windows.h) |
程式庫 | Kernel32.lib |
DLL | Kernel32.dll |