CM_Unregister_Notification関数 (cfgmgr32.h)
コードが Windows 7 以前のバージョンの Windows を対象とする場合は、CM_Unregister_Notificationの代わりに UnregisterDeviceNotification を使用します。
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 が待機するため、デッドロックが発生する可能性があります。
代わりに、通知コールバックから登録を解除する場合は、非同期で行う必要があります。 次のシーケンスは、これを行う 1 つの方法を示しています。
- 通知で使用するコンテキスト構造を割り当てます。 スレッドプールの作業構造 (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 で使用できます。 |
対象プラットフォーム | ユニバーサル |
Header | cfgmgr32.h (Cfgmgr32.h を含む) |
Library | Cfgmgr32.lib;Windows 10の OneCoreUAP.lib |
[DLL] | CfgMgr32.dll |