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 中可用。 |
目标平台 | 通用 |
标头 | cfgmgr32.h (包括 Cfgmgr32.h) |
Library | Cfgmgr32.lib;Windows 10 上的 OneCoreUAP.lib |
DLL | CfgMgr32.dll |
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈