Funzione DevCreateObjectQuery (devquery.h)
Crea una query del dispositivo per recuperare le proprietà in base ai parametri di query specificati.
Sintassi
HRESULT DevCreateObjectQuery(
[in] DEV_OBJECT_TYPE ObjectType,
[in] ULONG QueryFlags,
[in] ULONG cRequestedProperties,
[in] const DEVPROPCOMPKEY *pRequestedProperties,
[in] ULONG cFilterExpressionCount,
[in, optional] const DEVPROP_FILTER_EXPRESSION *pFilter,
[in] PDEV_QUERY_RESULT_CALLBACK pCallback,
[in, optional] PVOID pContext,
[out] PHDEVQUERY phDevQuery
);
Parametri
[in] ObjectType
Valore dell'enumerazione DEV_OBJECT_TYPE che determina il tipo di oggetto su cui deve operare la query.
[in] QueryFlags
Combinazione di valori DEV_QUERY_FLAGS combinati tramite un'operazione OR bit per bit.
[in] cRequestedProperties
Numero di strutture di DEVPROPCOMPKEY fornite in pRequestedProperties. Se si specifica DevQueryFlagAllProperties, deve essere impostato su 0.
[in] pRequestedProperties
Facoltativamente, fornisce una matrice di strutture
Se DevQueryFlagUpdateResults è stato specificato in QueryFlags, la query riceverà una notifica se il valore di una di queste proprietà cambia per qualsiasi oggetto nel set di risultati della query.
Il campo LocaleName della struttura DEVPROPCOMPKEY viene ignorato e deve essere impostato su NULL.
Se cRequestedProperties è 0, deve essere NULL.
[in] cFilterExpressionCount
Numero di strutture DEVPROP_FILTER_EXPRESSION fornite in pFilter.
[in, optional] pFilter
Facoltativamente, fornisce una matrice di strutture di DEVPROP_FILTER_EXPRESSION che specificano i criteri di filtro per gli oggetti che devono far parte del set di risultati della query. Se cFilterExpressionCount è 0, deve essere NULL.
[in] pCallback
Una funzione di callback PDEV_QUERY_RESULT_CALLBACK a cui devono essere inviati i risultati per questa query.
[in, optional] pContext
Contesto fornito dal chiamante. Questo valore viene passato alla funzione di callback non modificata.
[out] phDevQuery
Puntatore che riceve l'handle che rappresenta la query. Se viene specificato DevQueryFlagsUpdateResults, la query riceverà gli aggiornamenti fino alla chiusura dell'handle. Chiamare DevCloseObjectQuery per chiudere questo handle per arrestare la query.
Valore restituito
S_OK viene restituito se una query è stata creata correttamente; in caso contrario, un valore di errore appropriato.
Osservazioni
Usare il devCreateObjectQuery di
Per impostazione predefinita, le query non ricevono aggiornamenti dopo l'elaborazione dello stato corrente del sistema. Dopo aver aggiunto tutti gli oggetti corrispondenti al set di risultati, la query immette il DevQueryStateEnumCompleted stato e non verranno eseguiti altri callback. Quando una query esegue la registrazione per gli aggiornamenti specificando il flag
È possibile che una query venga interrotta. Ciò si verifica quando si verifica un errore interno che rende impossibile comunicare una notifica al client. Ad esempio, ciò può verificarsi quando il sistema si trova in una condizione di memoria insufficiente. In questo caso, il set di risultati del chiamante non riflette più una vera rappresentazione dello stato della query. Il chiamante riceverà un callback DevQueryStateAborted. Non verranno ricevuti altri callback. Il chiamante deve chiudere la query e creare una nuova query per il ripristino da questa condizione.
Esempi
Nell'esempio seguente il metodo PDEV_QUERY_RESULT_CALLBACK viene implementato per stampare i messaggi di stato quando lo stato della query cambia, quando gli elementi sono stati aggiunti, aggiornati o rimossi dal risultato della query. Viene quindi implementato uno scenario di query semplice in cui
void WINAPI
Example1Callback(
HDEVQUERY hDevQuery,
PVOID pContext,
const DEV_QUERY_RESULT_ACTION_DATA *pActionData
)
{
const DEVPROPERTY* NameProperty = NULL;
UNREFERENCED_PARAMETER(hDevQuery);
UNREFERENCED_PARAMETER(pContext);
switch (pActionData->Action)
{
case DevQueryResultStateChange:
if (pActionData->Data.State == DevQueryStateEnumCompleted)
{
wprintf(L"Enumeration of current system state complete.\n");
}
else if (pActionData->Data.State == DevQueryStateAborted)
{
wprintf(L"Query has aborted. No further results will be received.\n");
// Communicate back to the creator of the query that it has aborted
// so it can handle that appropriately, such as by recreating the
// query
}
break;
case DevQueryResultAdd:
wprintf(L"Object '%ws' has been added to the result set.\n",
pActionData->Data.DeviceObject.pszObjectId);
NameProperty = DevFindProperty(&DEVPKEY_NAME,
DEVPROP_STORE_SYSTEM,
NULL,
pActionData->Data.DeviceObject.cPropertyCount,
pActionData->Data.DeviceObject.pProperties);
if ((NameProperty == NULL) ||
(NameProperty->Type == DEVPROP_TYPE_EMPTY) ||
(NameProperty->Buffer == NULL))
{
wprintf(L"Object '%ws' had no name property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else if ((NameProperty->Type != DEVPROP_TYPE_STRING) ||
(NameProperty->BufferSize < sizeof(WCHAR)))
{
wprintf(L"Object '%ws' had a corrupted name property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else
{
wprintf(L"Object '%ws' has name '%ws'.\n",
pActionData->Data.DeviceObject.pszObjectId,
(PWSTR)NameProperty->Buffer);
}
break;
case DevQueryResultUpdate:
wprintf(L"Object '%ws' was updated.\n",
pActionData->Data.DeviceObject.pszObjectId);
NameProperty = DevFindProperty(&DEVPKEY_NAME,
DEVPROP_STORE_SYSTEM,
NULL,
pActionData->Data.DeviceObject.cPropertyCount,
pActionData->Data.DeviceObject.pProperties);
if ((NameProperty == NULL) ||
(NameProperty->Type == DEVPROP_TYPE_EMPTY) ||
(NameProperty->Buffer == NULL))
{
wprintf(L"Object '%ws' had no name property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else if ((NameProperty->Type != DEVPROP_TYPE_STRING) ||
(NameProperty->BufferSize < sizeof(WCHAR)))
{
wprintf(L"Object '%ws' had a corrupted name property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else
{
wprintf(L"Object '%ws' has name '%ws'.\n",
pActionData->Data.DeviceObject.pszObjectId,
(PWSTR)NameProperty->Buffer);
}
break;
case DevQueryResultRemove:
wprintf(L"Object '%ws' has been removed from the result set.\n",
pActionData->Data.DeviceObject.pszObjectId);
break;
}
}
void
Example1()
{
DEVPROPCOMPKEY RequestedProperties[] =
{
{ DEVPKEY_NAME, DEVPROP_STORE_SYSTEM, NULL }
};
DEVPROP_FILTER_EXPRESSION ObjectFilter[] =
{
{
DEVPROP_OPERATOR_EQUALS,
{
{ DEVPKEY_Device_ClassGuid, DEVPROP_STORE_SYSTEM, NULL },
DEVPROP_TYPE_GUID,
sizeof(GUID),
(void*)&GUID_DEVCLASS_NET
}
}
};
HDEVQUERY hDevQuery = NULL;
HRESULT hr = DevCreateObjectQuery(DevObjectTypeDevice,
DevQueryFlagUpdateResults,
RTL_NUMBER_OF(RequestedProperties),
RequestedProperties,
RTL_NUMBER_OF(ObjectFilter),
ObjectFilter,
Example1Callback,
NULL,
&hDevQuery);
if (FAILED(hr))
{
wprintf(L"Failed to create query. hr = 0x%08x\n", hr);
goto exit;
}
// do other work while the query monitors system state in the background
exit:
if (hDevQuery != NULL)
{
DevCloseObjectQuery(hDevQuery);
}
return;
}
Nell'esempio seguente viene usato il parametro pContext definito dal chiamante facoltativo
typedef struct _MY_QUERY_CONTEXT {
HANDLE CompletionEvent;
HRESULT hr;
} MY_QUERY_CONTEXT, *PMY_QUERY_CONTEXT;
void WINAPI
Example2Callback(
HDEVQUERY hDevQuery,
PVOID pContext,
const DEV_QUERY_RESULT_ACTION_DATA *pActionData
)
{
PMY_QUERY_CONTEXT QueryContext = (PMY_QUERY_CONTEXT)pContext;
const DEVPROPERTY* DevProperty = NULL;
UNREFERENCED_PARAMETER(hDevQuery);
switch (pActionData->Action)
{
case DevQueryResultStateChange:
if (pActionData->Data.State == DevQueryStateEnumCompleted)
{
wprintf(L"Enumeration of current system state complete.\n");
// The query did not use DevQueryFlagUpdateResults so the result set
// is now complete. Signal the caller to stop waiting.
if (!SetEvent(QueryContext->CompletionEvent))
{
wprintf(L"Failed to signal completion event. Err = 0x%08x\n",
GetLastError());
}
}
else if (pActionData->Data.State == DevQueryStateAborted)
{
wprintf(L"Query has aborted. No further results will be received.\n");
QueryContext->hr = E_FAIL;
// Communicate back to the creator of the query that it has aborted
// so it can handle that appropriately, such as by recreating the
// query.
if (!SetEvent(QueryContext->CompletionEvent))
{
wprintf(L"Failed to signal completion event. Err = 0x%08x\n",
GetLastError());
}
}
break;
case DevQueryResultAdd:
wprintf(L"Object '%ws' has been added to the result set.\n",
pActionData->Data.DeviceObject.pszObjectId);
DevProperty = DevFindProperty(&DEVPKEY_Device_InstanceId,
DEVPROP_STORE_SYSTEM,
NULL,
pActionData->Data.DeviceObject.cPropertyCount,
pActionData->Data.DeviceObject.pProperties);
if ((DevProperty == NULL) ||
(DevProperty->Type == DEVPROP_TYPE_EMPTY) ||
(DevProperty->Buffer == NULL))
{
wprintf(L"Object '%ws' had no instance ID property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else if ((DevProperty->Type != DEVPROP_TYPE_STRING) ||
(DevProperty->BufferSize < sizeof(WCHAR)))
{
wprintf(L"Object '%ws' had a corrupted instance ID property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else
{
wprintf(L"Object '%ws' was exposed by instance ID '%ws'.\n",
pActionData->Data.DeviceObject.pszObjectId,
(PWSTR)DevProperty->Buffer);
}
break;
case DevQueryResultUpdate:
wprintf(L"Object '%ws' was updated.\n",
pActionData->Data.DeviceObject.pszObjectId);
DevProperty = DevFindProperty(&DEVPKEY_Device_InstanceId,
DEVPROP_STORE_SYSTEM,
NULL,
pActionData->Data.DeviceObject.cPropertyCount,
pActionData->Data.DeviceObject.pProperties);
if ((DevProperty == NULL) ||
(DevProperty->Type == DEVPROP_TYPE_EMPTY) ||
(DevProperty->Buffer == NULL))
{
wprintf(L"Object '%ws' had no instance ID property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else if ((DevProperty->Type != DEVPROP_TYPE_STRING) ||
(DevProperty->BufferSize < sizeof(WCHAR)))
{
wprintf(L"Object '%ws' had a corrupted instance ID property.\n",
pActionData->Data.DeviceObject.pszObjectId);
}
else
{
wprintf(L"Object '%ws' was exposed by instance ID '%ws'.\n",
pActionData->Data.DeviceObject.pszObjectId,
(PWSTR)DevProperty->Buffer);
}
break;
case DevQueryResultRemove:
wprintf(L"Object '%ws' has been removed from the result set.\n",
pActionData->Data.DeviceObject.pszObjectId);
break;
}
}
void
Example2()
{
HRESULT hr = S_OK;
MY_QUERY_CONTEXT QueryContext = {0};
HDEVQUERY hDevQuery = NULL;
DEVPROP_BOOLEAN DevPropTrue = DEVPROP_TRUE;
DEVPROPCOMPKEY RequestedProperties[] =
{
{ DEVPKEY_Device_InstanceId, DEVPROP_STORE_SYSTEM, NULL }
};
DEVPROP_FILTER_EXPRESSION ObjectFilter[] =
{
{
DEVPROP_OPERATOR_AND_OPEN, {0}
},
{
DEVPROP_OPERATOR_EQUALS,
{
{ DEVPKEY_DeviceInterface_Enabled, DEVPROP_STORE_SYSTEM, NULL },
DEVPROP_TYPE_BOOLEAN,
sizeof(DevPropTrue),
(void*)&DevPropTrue
}
},
{
DEVPROP_OPERATOR_OR_OPEN, {0}
},
{
DEVPROP_OPERATOR_EQUALS,
{
{ DEVPKEY_DeviceInterface_ClassGuid, DEVPROP_STORE_SYSTEM, NULL },
DEVPROP_TYPE_GUID,
sizeof(GUID),
(void*)&GUID_DEVINTERFACE_MOUSE
}
},
{
DEVPROP_OPERATOR_EQUALS,
{
{ DEVPKEY_DeviceInterface_ClassGuid, DEVPROP_STORE_SYSTEM, NULL },
DEVPROP_TYPE_GUID,
sizeof(GUID),
(void*)&GUID_DEVINTERFACE_KEYBOARD
}
},
{
DEVPROP_OPERATOR_OR_CLOSE, {0}
},
{
DEVPROP_OPERATOR_AND_CLOSE, {0}
}
};
QueryContext.CompletionEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!QueryContext.CompletionEvent)
{
wprintf(L"Failed to create event. Error = 0x%08x\n",
GetLastError());
goto exit;
}
hr = DevCreateObjectQuery(DevObjectTypeDeviceInterface,
DevQueryFlagNone,
RTL_NUMBER_OF(RequestedProperties),
RequestedProperties,
RTL_NUMBER_OF(ObjectFilter),
ObjectFilter,
Example2Callback,
&QueryContext,
&hDevQuery);
if (FAILED(hr))
{
wprintf(L"Failed to create query. hr = 0x%08x\n", hr);
goto exit;
}
switch (WaitForSingleObject(QueryContext.CompletionEvent, INFINITE))
{
case WAIT_OBJECT_0:
if (SUCCEEDED(QueryContext.hr))
{
wprintf(L"Successfully enumerated results.\n");
}
else
{
wprintf(L"Failed to Successfully enumerate results. hr = 0x%08x\n",
QueryContext.hr);
}
break;
default:
wprintf(L"An error waiting occurred.\n");
break;
}
exit:
if (hDevQuery != NULL)
{
DevCloseObjectQuery(hDevQuery);
}
if (QueryContext.CompletionEvent != NULL)
{
CloseHandle(QueryContext.CompletionEvent);
}
return;
}
Fabbisogno
Requisito | Valore |
---|---|
client minimo supportato | Windows 10 versione 1809 |
server minimo supportato | Windows Server 2019 |
intestazione |
devquery.h |
libreria |
onecore.lib |
dll | Cfgmgr32.dll |