Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwenden Sie UnregisterDeviceNotification anstelle von CM_Unregister_Notification , wenn Ihr Code auf Windows 7 oder frühere Versionen von Windows abzielt.
Die CM_Unregister_Notification-Funktion schließt das angegebene HCMNOTIFICATION-Handle.
Syntax
CMAPI CONFIGRET CM_Unregister_Notification(
[in] HCMNOTIFICATION NotifyContext
);
Parameter
[in] NotifyContext
Das HCMNOTIFICATION-Handle, das von der CM_Register_Notification-Funktion zurückgegeben wird.
Rückgabewert
Wenn der Vorgang erfolgreich ist, gibt die Funktion CR_SUCCESS zurück. Andernfalls wird einer der CR_-Präfix-Fehlercodes zurückgegeben, die in Cfgmgr32.h definiert sind.
Hinweise
Rufen Sie CM_Unregister_Notification nicht über einen Benachrichtigungsrückruf auf. Dies kann zu einem Deadlock führen, da CM_Unregister_Notification wartet, bis ausstehende Rückrufe abgeschlossen sind.
Wenn Sie stattdessen die Registrierung vom Benachrichtigungsrückruf aufheben möchten, müssen Sie dies asynchron tun. Die folgende Sequenz zeigt eine Möglichkeit, dies zu tun:
- Ordnen Sie eine Kontextstruktur zu, die mit Ihren Benachrichtigungen verwendet werden soll. Fügen Sie einen Zeiger auf eine Threadpool-Arbeitsstruktur (PTP_WORK) und alle anderen Informationen ein, die Sie an den Benachrichtigungsrückruf übergeben möchten.
- Rufen Sie CreateThreadpoolWork auf. Stellen Sie eine Rückruffunktion bereit, die CM_Unregister_Notification aufruft. Fügen Sie die zurückgegebene Arbeitsstruktur der zuvor zugewiesenen Kontextstruktur hinzu.
- Rufen Sie CM_Register_Notification auf, und geben Sie die Kontextstruktur als pContext-Parameter an.
- Arbeiten Sie, erhalten Sie Benachrichtigungen usw.
- Rufen Sie SubmitThreadpoolWork innerhalb des Benachrichtigungsrückrufs auf, und geben Sie den Zeiger auf eine threadpool-Arbeitsstruktur (PTP_WORK) an, die in Ihrer Kontextstruktur gespeichert ist.
- Wenn der Threadpoolthread ausgeführt wird, ruft das Arbeitselement CM_Unregister_Notification auf.
- Rufen Sie CloseThreadpoolWork auf, um das Arbeitsobjekt freizugeben.
Beispiele
Das folgende Beispiel zeigt, wie Sie die Registrierung vom Benachrichtigungsrückruf aufheben, wie im Abschnitt Hinweise beschrieben.
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;
}
Anforderungen
| Anforderung | Wert |
|---|---|
| Unterstützte Mindestversion (Client) | Verfügbar in Microsoft Windows 8 und höheren Versionen von Windows. |
| Zielplattform | Universell |
| Header | cfgmgr32.h (einschließlich Cfgmgr32.h) |
| Bibliothek | Cfgmgr32.lib; OneCoreUAP.lib auf Windows 10 |
| DLL | CfgMgr32.dll |