CM_Unregister_Notification函式 (cfgmgr32.h)
如果您的程式代碼是以 Windows 7 或舊版 Windows 為目標,請使用 UnregisterDeviceNotification 而不是 CM_Unregister_Notification 。
CM_Unregister_Notification函式會關閉指定的 HCMNOTIFICATION 句柄。
語法
CMAPI CONFIGRET CM_Unregister_Notification(
[in] HCMNOTIFICATION NotifyContext
);
參數
[in] NotifyContext
CM_Register_Notification函式所傳回的 HCMNOTIFICATION 句柄。
傳回值
如果作業成功,函式會傳回CR_SUCCESS。 否則,它會傳回 Cfgmgr32.h 中定義的其中一個CR_前置錯誤碼。
備註
請勿從通知回呼呼叫 CM_Unregister_Notification 。 這樣做可能會導致死結,因為 CM_Unregister_Notification 等候擱置回呼完成。
相反地,如果您想要從通知回呼取消註冊,您必須以異步方式執行此動作。 下列順序顯示執行此動作的其中一種方式:
- 配置要與您的通知搭配使用的內容結構。 包含線程緩衝處理工作結構的指標 (PTP_WORK) ,以及您想要傳遞至通知回呼的任何其他資訊。
- 呼叫 CreateThreadpoolWork。 提供呼叫 CM_Unregister_Notification的回呼函式。 將傳回的工作結構新增至先前配置的內容結構。
- 呼叫 CM_Register_Notification 並提供內容結構作為 pContext 參數。
- 執行工作、取得通知等等。
- 從通知回呼內呼叫 SubmitThreadpoolWork ,提供線程緩衝處理工作結構的指標, (PTP_WORK 儲存在內容結構) 。
- 線程緩衝處理線程執行時,工作專案會呼叫 CM_Unregister_Notification。
- 呼叫 CloseThreadpoolWork 以釋放工作物件。
謹慎 在工作專案呼叫 CM_Unregister_Notification之後,請勿釋放內容結構。 您仍然可以在提交線程緩衝處理工作項目之後,以及在工作專案呼叫 CM_Unregister_Notification之前收到通知。
範例
下列範例示範如何取消註冊通知回呼,如一節所述。
typedef struct _CALLBACK_CONTEXT {
BOOL bUnregister;
PTP_WORK pWork;
HCMNOTIFICATION hNotify;
CRITICAL_SECTION lock;
} CALLBACK_CONTEXT, *PCALLBACK_CONTEXT;
DWORD
WINAPI
EventCallback(
__in HCMNOTIFICATION hNotification,
__in PVOID Context,
__in CM_NOTIFY_ACTION Action,
__in PCM_NOTIFY_EVENT_DATA EventData,
__in DWORD EventDataSize
)
{
PCALLBACK_CONTEXT pCallbackContext = (PCALLBACK_CONTEXT)Context;
// unregister from the callback
EnterCriticalSection(&(pCallbackContext->lock));
// in case this callback fires before the registration call returns, make sure the notification handle is properly set
Context->hNotify = hNotification;
if (!pCallbackContext->bUnregister) {
pCallbackContext->bUnregister = TRUE;
SubmitThreadpoolWork(pCallbackContext->pWork);
}
LeaveCriticalSection(&(pCallbackContext->lock));
return ERROR_SUCCESS;
};
VOID
CALLBACK
WorkCallback(
_Inout_ PTP_CALLBACK_INSTANCE Instance,
_Inout_opt_ PVOID Context,
_Inout_ PTP_WORK pWork
)
{
PCALLBACK_CONTEXT pCallbackContext = (PCALLBACK_CONTEXT)Context;
CM_Unregister_Notification(pCallbackContext->hNotify);
}
VOID NotificationFunction()
{
CONFIGRET cr = CR_SUCCESS;
HRESULT hr = S_OK;
CM_NOTIFY_FILTER NotifyFilter = { 0 };
BOOL bShouldUnregister = FALSE;
PCALLBACK_CONTEXT context;
context = (PCALLBACK_CONTEXT)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CALLBACK_CONTEXT));
if (context == NULL) {
goto end;
}
InitializeCriticalSection(&(context->lock));
NotifyFilter.cbSize = sizeof(NotifyFilter);
NotifyFilter.Flags = 0;
NotifyFilter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE;
NotifyFilter.Reserved = 0;
hr = StringCchCopy(NotifyFilter.u.DeviceInstance.InstanceId,
MAX_DEVICE_ID_LEN,
TEST_DEVICE_INSTANCE_ID);
if (FAILED(hr)) {
goto end;
}
context->pWork = CreateThreadpoolWork(WorkCallback, context, NULL);
if (context->pWork == NULL) {
goto end;
}
cr = CM_Register_Notification(&NotifyFilter,
context,
EventCallback,
&context->hNotify);
if (cr != CR_SUCCESS) {
goto end;
}
// ... do work here ...
EnterCriticalSection(&(context->lock));
if (!context->bUnregister) {
// unregister not from the callback
bShouldUnregister = TRUE;
context->bUnregister = TRUE;
}
LeaveCriticalSection(&(context->lock));
if (bShouldUnregister) {
cr = CM_Unregister_Notification(context->hNotify);
if (cr != CR_SUCCESS) {
goto end;
}
} else {
// if the callback is the one performing the unregister, wait for the threadpool work item to complete the unregister
WaitForThreadpoolWorkCallbacks(context->pWork, FALSE);
}
end:
if (context != NULL) {
if (context->pWork != NULL) {
CloseThreadpoolWork(context->pWork);
}
DeleteCriticalSection(&(context->lock));
HeapFree(GetProcessHeap(), 0, context);
}
return;
}
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | 可在 Microsoft Windows 8 和更新版本的 Windows 中使用。 |
目標平台 | Universal |
標頭 | cfgmgr32.h (包含 Cfgmgr32.h) |
程式庫 | Cfgmgr32.lib;Windows 10 上的 OneCoreUAP.lib |
Dll | CfgMgr32.dll |