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:

  1. 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.
  2. 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.
  3. Llame a CM_Register_Notification y proporcione la estructura de contexto como parámetro pContext .
  4. Hacer trabajo, obtener notificaciones, etc.
  5. 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.
  6. Cuando se ejecuta el subproceso del grupo de subprocesos, el elemento de trabajo llama a CM_Unregister_Notification.
  7. Llame a CloseThreadpoolWork para liberar el objeto de trabajo.
Si ha terminado con la estructura de contexto, no olvide liberar los recursos y liberar la estructura.
Precaución No libere la estructura de contexto hasta que el elemento de trabajo haya llamado a CM_Unregister_Notification. Todavía puede recibir notificaciones después de enviar el elemento de trabajo threadpool y antes de que el elemento de trabajo llame a CM_Unregister_Notification.
 

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

Consulte también

UnregisterDeviceNotification