función CM_Unregister_Notification (cfgmgr32.h)
Usa UnregisterDeviceNotification en lugar de CM_Unregister_Notification si el código tiene como destino Windows 7 o versiones anteriores de Windows.
La función CM_Unregister_Notification cierra el identificador HCMNOTIFICATION especificado.
Sintaxis
CMAPI CONFIGRET CM_Unregister_Notification(
[in] HCMNOTIFICATION NotifyContext
);
Parámetros
[in] NotifyContext
Identificador HCMNOTIFICATION devuelto por la función CM_Register_Notification .
Valor devuelto
Si la operación se realiza correctamente, la función devuelve CR_SUCCESS. De lo contrario, devuelve uno de los códigos de error con prefijo CR_ definidos en Cfgmgr32.h.
Comentarios
No llame a CM_Unregister_Notification desde una devolución de llamada de notificación. Si lo hace, puede provocar un interbloqueo porque CM_Unregister_Notification espera a que finalicen las devoluciones de llamada pendientes.
En su lugar, si desea anular el registro de la devolución de llamada de notificación, debe hacerlo de forma asincrónica. En la secuencia siguiente se muestra una manera de hacerlo:
- Asigne una estructura de contexto para usarla con las notificaciones. Incluya un puntero a una estructura de trabajo de grupo de subprocesos (PTP_WORK) y cualquier otra información que desee pasar a la devolución de llamada de notificación.
- Llame a CreateThreadpoolWork. Proporcione una función de devolución de llamada que llame a CM_Unregister_Notification. Agregue la estructura de trabajo devuelta a la estructura de contexto asignada anteriormente.
- Llame a CM_Register_Notification y proporcione la estructura de contexto como parámetro pContext .
- Hacer trabajo, obtener notificaciones, etc.
- Llame a SubmitThreadpoolWork desde la devolución de llamada de notificación, lo que proporciona el puntero a una estructura de trabajo del grupo de subprocesos (PTP_WORK) almacenada en la estructura de contexto.
- Cuando se ejecuta el subproceso del grupo de subprocesos, el elemento de trabajo llama a CM_Unregister_Notification.
- Llame a CloseThreadpoolWork para liberar el objeto de trabajo.
Ejemplos
En el ejemplo siguiente se muestra cómo anular el registro de la devolución de llamada de notificación, como se describe en la sección Comentarios.
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;
}
Requisitos
Requisito | Value |
---|---|
Cliente mínimo compatible | Disponible en Microsoft Windows 8 y versiones posteriores de Windows. |
Plataforma de destino | Universal |
Encabezado | cfgmgr32.h (incluya Cfgmgr32.h) |
Library | Cfgmgr32.lib; OneCoreUAP.lib en Windows 10 |
Archivo DLL | CfgMgr32.dll |