fungsi CM_Unregister_Notification (cfgmgr32.h)

Gunakan UnregisterDeviceNotification alih-alih CM_Unregister_Notification jika kode Anda menargetkan Windows 7 atau versi Windows yang lebih lama.

Fungsi CM_Unregister_Notification menutup handel HCMNOTIFICATION yang ditentukan.

Sintaks

CMAPI CONFIGRET CM_Unregister_Notification(
  [in] HCMNOTIFICATION NotifyContext
);

Parameter

[in] NotifyContext

Handel HCMNOTIFICATION yang dikembalikan oleh fungsi CM_Register_Notification .

Menampilkan nilai

Jika operasi berhasil, fungsi akan mengembalikan CR_SUCCESS. Jika tidak, ia mengembalikan salah satu kode kesalahan awalan CR_ yang ditentukan dalam Cfgmgr32.h.

Keterangan

Jangan memanggil CM_Unregister_Notification dari panggilan balik pemberitahuan. Melakukannya dapat menyebabkan kebuntuan karena CM_Unregister_Notification menunggu panggilan balik tertunda selesai.

Sebaliknya, jika Anda ingin membatalkan pendaftaran dari panggilan balik pemberitahuan, Anda harus melakukannya secara asinkron. Urutan berikut menunjukkan salah satu cara untuk melakukan ini:

  1. Alokasikan struktur konteks untuk digunakan dengan pemberitahuan Anda. Sertakan pointer ke struktur kerja threadpool (PTP_WORK) dan informasi lain yang ingin Anda berikan ke panggilan balik pemberitahuan.
  2. Panggil CreateThreadpoolWork. Berikan fungsi panggilan balik yang memanggil CM_Unregister_Notification. Tambahkan struktur kerja yang dikembalikan ke struktur konteks yang dialokasikan sebelumnya.
  3. Panggil CM_Register_Notification dan berikan struktur konteks sebagai parameter pContext .
  4. Melakukan pekerjaan, mendapatkan pemberitahuan, dll.
  5. Panggil SubmitThreadpoolWork dari dalam panggilan balik pemberitahuan, menyediakan penunjuk ke struktur kerja threadpool (PTP_WORK) yang disimpan dalam struktur konteks Anda.
  6. Saat utas threadpool berjalan, item kerja memanggil CM_Unregister_Notification.
  7. Panggil CloseThreadpoolWork untuk merilis objek kerja.
Jika Anda selesai dengan struktur konteks, jangan lupa untuk merilis sumber daya dan membebaskan struktur.
Hati Jangan bebaskan struktur konteks hingga setelah item kerja dipanggil CM_Unregister_Notification. Anda masih dapat menerima pemberitahuan setelah mengirimkan item kerja threadpool dan sebelum item kerja memanggil CM_Unregister_Notification.
 

Contoh

Contoh berikut menunjukkan cara membatalkan pendaftaran dari panggilan balik pemberitahuan, seperti yang dijelaskan di bagian Keterangan.

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;
}

Persyaratan

Persyaratan Nilai
Klien minimum yang didukung Tersedia di Microsoft Windows 8 dan versi Windows yang lebih baru.
Target Platform Universal
Header cfgmgr32.h (termasuk Cfgmgr32.h)
Pustaka Cfgmgr32.lib; OneCoreUAP.lib di Windows 10
DLL CfgMgr32.dll

Lihat juga

UnregisterDeviceNotification