mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:25:39 +00:00
[UMPNPMGR] PNP_GetDeviceList / PNP_GetDeviceListSize: Implement the buffer size calculation and device instance enumeration for a given enumerator and device name.
This commit is contained in:
parent
830f2998ab
commit
a9b88efa7c
1 changed files with 214 additions and 51 deletions
|
@ -184,6 +184,53 @@ NtStatusToCrError(NTSTATUS Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
|
||||||
|
OUT LPWSTR pszEnumerator,
|
||||||
|
OUT LPWSTR pszDevice,
|
||||||
|
OUT LPWSTR pszInstance)
|
||||||
|
{
|
||||||
|
WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
|
||||||
|
LPWSTR lpEnumerator = NULL;
|
||||||
|
LPWSTR lpDevice = NULL;
|
||||||
|
LPWSTR lpInstance = NULL;
|
||||||
|
LPWSTR ptr;
|
||||||
|
|
||||||
|
wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
|
||||||
|
|
||||||
|
*pszEnumerator = 0;
|
||||||
|
*pszDevice = 0;
|
||||||
|
*pszInstance = 0;
|
||||||
|
|
||||||
|
lpEnumerator = szLocalDeviceInstanceID;
|
||||||
|
|
||||||
|
ptr = wcschr(lpEnumerator, L'\\');
|
||||||
|
if (ptr != NULL)
|
||||||
|
{
|
||||||
|
*ptr = 0;
|
||||||
|
lpDevice = ++ptr;
|
||||||
|
|
||||||
|
ptr = wcschr(lpDevice, L'\\');
|
||||||
|
if (ptr != NULL)
|
||||||
|
{
|
||||||
|
*ptr = 0;
|
||||||
|
lpInstance = ++ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpEnumerator != NULL)
|
||||||
|
wcscpy(pszEnumerator, lpEnumerator);
|
||||||
|
|
||||||
|
if (lpDevice != NULL)
|
||||||
|
wcscpy(pszDevice, lpDevice);
|
||||||
|
|
||||||
|
if (lpInstance != NULL)
|
||||||
|
wcscpy(pszInstance, lpInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/* Function 0 */
|
/* Function 0 */
|
||||||
DWORD
|
DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -482,6 +529,77 @@ PNP_EnumerateSubKeys(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
CONFIGRET
|
||||||
|
GetDeviceInstanceList(
|
||||||
|
_In_ PWSTR pszDevice,
|
||||||
|
_Inout_ PWSTR pszBuffer,
|
||||||
|
_Inout_ PDWORD pulLength)
|
||||||
|
{
|
||||||
|
WCHAR szInstanceBuffer[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR szPathBuffer[512];
|
||||||
|
HKEY hDeviceKey;
|
||||||
|
DWORD dwInstanceLength, dwPathLength, dwUsedLength;
|
||||||
|
DWORD dwIndex, dwError;
|
||||||
|
PWSTR pPtr;
|
||||||
|
CONFIGRET ret = CR_SUCCESS;
|
||||||
|
|
||||||
|
dwError = RegOpenKeyExW(hEnumKey,
|
||||||
|
pszDevice,
|
||||||
|
0,
|
||||||
|
KEY_ENUMERATE_SUB_KEYS,
|
||||||
|
&hDeviceKey);
|
||||||
|
if (dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("Failed to open the device key (Error %lu)\n", dwError);
|
||||||
|
return CR_REGISTRY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwUsedLength = 0;
|
||||||
|
pPtr = pszBuffer;
|
||||||
|
|
||||||
|
for (dwIndex = 0; ; dwIndex++)
|
||||||
|
{
|
||||||
|
dwInstanceLength = MAX_DEVICE_ID_LEN;
|
||||||
|
dwError = RegEnumKeyExW(hDeviceKey,
|
||||||
|
dwIndex,
|
||||||
|
szInstanceBuffer,
|
||||||
|
&dwInstanceLength,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (dwError != ERROR_SUCCESS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
wsprintf(szPathBuffer, L"%s\\%s", pszDevice, szInstanceBuffer);
|
||||||
|
DPRINT("Path: %S\n", szPathBuffer);
|
||||||
|
|
||||||
|
dwPathLength = wcslen(szPathBuffer) + 1;
|
||||||
|
if (dwUsedLength + dwPathLength + 1 > *pulLength)
|
||||||
|
{
|
||||||
|
ret = CR_BUFFER_SMALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
wcscpy(pPtr, szPathBuffer);
|
||||||
|
dwUsedLength += dwPathLength;
|
||||||
|
pPtr += dwPathLength;
|
||||||
|
|
||||||
|
*pPtr = UNICODE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hDeviceKey);
|
||||||
|
|
||||||
|
if (ret == CR_SUCCESS)
|
||||||
|
*pulLength = dwUsedLength + 1;
|
||||||
|
else
|
||||||
|
*pulLength = 0;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 10 */
|
/* Function 10 */
|
||||||
DWORD
|
DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -493,6 +611,9 @@ PNP_GetDeviceList(
|
||||||
DWORD ulFlags)
|
DWORD ulFlags)
|
||||||
{
|
{
|
||||||
PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
|
PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
|
||||||
|
WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR szDevice[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR szInstance[MAX_DEVICE_ID_LEN];
|
||||||
CONFIGRET ret = CR_SUCCESS;
|
CONFIGRET ret = CR_SUCCESS;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -501,11 +622,12 @@ PNP_GetDeviceList(
|
||||||
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
|
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
|
||||||
return CR_INVALID_FLAG;
|
return CR_INVALID_FLAG;
|
||||||
|
|
||||||
if (pulLength == NULL || pszFilter == NULL)
|
if (pulLength == NULL)
|
||||||
return CR_INVALID_POINTER;
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
// if (Buffer == NULL)
|
if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
|
||||||
// return CR_INVALID_POINTER;
|
(pszFilter == NULL))
|
||||||
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
if (ulFlags &
|
if (ulFlags &
|
||||||
(CM_GETIDLIST_FILTER_BUSRELATIONS |
|
(CM_GETIDLIST_FILTER_BUSRELATIONS |
|
||||||
|
@ -553,7 +675,21 @@ PNP_GetDeviceList(
|
||||||
}
|
}
|
||||||
else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
|
else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
|
||||||
{
|
{
|
||||||
ret = CR_CALL_NOT_IMPLEMENTED;
|
SplitDeviceInstanceID(pszFilter,
|
||||||
|
szEnumerator,
|
||||||
|
szDevice,
|
||||||
|
szInstance);
|
||||||
|
|
||||||
|
if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
|
||||||
|
{
|
||||||
|
ret = GetDeviceInstanceList(pszFilter,
|
||||||
|
Buffer,
|
||||||
|
pulLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* CM_GETIDLIST_FILTER_NONE */
|
else /* CM_GETIDLIST_FILTER_NONE */
|
||||||
{
|
{
|
||||||
|
@ -564,6 +700,58 @@ PNP_GetDeviceList(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
CONFIGRET
|
||||||
|
GetDeviceInstanceListSize(
|
||||||
|
_In_ LPCWSTR pszDevice,
|
||||||
|
_Out_ PULONG pulLength)
|
||||||
|
{
|
||||||
|
HKEY hDeviceKey;
|
||||||
|
DWORD dwSubKeys, dwMaxSubKeyLength;
|
||||||
|
DWORD dwError;
|
||||||
|
|
||||||
|
/* Open the device key */
|
||||||
|
dwError = RegOpenKeyExW(hEnumKey,
|
||||||
|
pszDevice,
|
||||||
|
0,
|
||||||
|
KEY_READ,
|
||||||
|
&hDeviceKey);
|
||||||
|
if (dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("Failed to open the device key (Error %lu)\n", dwError);
|
||||||
|
return CR_REGISTRY_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Retrieve the number of device instances and the maximum name length */
|
||||||
|
dwError = RegQueryInfoKeyW(hDeviceKey,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&dwSubKeys,
|
||||||
|
&dwMaxSubKeyLength,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (dwError != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT("RegQueryInfoKeyW failed (Error %lu)\n", dwError);
|
||||||
|
dwSubKeys = 0;
|
||||||
|
dwMaxSubKeyLength = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the device key */
|
||||||
|
RegCloseKey(hDeviceKey);
|
||||||
|
|
||||||
|
/* Return the largest possible buffer size */
|
||||||
|
*pulLength = (dwSubKeys * (wcslen(pszDevice) + 1 + dwMaxSubKeyLength + 1)) + 1;
|
||||||
|
|
||||||
|
return CR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Function 11 */
|
/* Function 11 */
|
||||||
DWORD
|
DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
|
@ -574,6 +762,9 @@ PNP_GetDeviceListSize(
|
||||||
DWORD ulFlags)
|
DWORD ulFlags)
|
||||||
{
|
{
|
||||||
PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
|
PLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA PlugPlayData;
|
||||||
|
WCHAR szEnumerator[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR szDevice[MAX_DEVICE_ID_LEN];
|
||||||
|
WCHAR szInstance[MAX_DEVICE_ID_LEN];
|
||||||
CONFIGRET ret = CR_SUCCESS;
|
CONFIGRET ret = CR_SUCCESS;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -582,7 +773,11 @@ PNP_GetDeviceListSize(
|
||||||
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
|
if (ulFlags & ~CM_GETIDLIST_FILTER_BITS)
|
||||||
return CR_INVALID_FLAG;
|
return CR_INVALID_FLAG;
|
||||||
|
|
||||||
if (pulLength == NULL || pszFilter == NULL)
|
if (pulLength == NULL)
|
||||||
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
|
if ((ulFlags != CM_GETIDLIST_FILTER_NONE) &&
|
||||||
|
(pszFilter == NULL))
|
||||||
return CR_INVALID_POINTER;
|
return CR_INVALID_POINTER;
|
||||||
|
|
||||||
*pulLength = 0;
|
*pulLength = 0;
|
||||||
|
@ -633,7 +828,20 @@ PNP_GetDeviceListSize(
|
||||||
}
|
}
|
||||||
else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
|
else if (ulFlags & CM_GETIDLIST_FILTER_ENUMERATOR)
|
||||||
{
|
{
|
||||||
ret = CR_CALL_NOT_IMPLEMENTED;
|
SplitDeviceInstanceID(pszFilter,
|
||||||
|
szEnumerator,
|
||||||
|
szDevice,
|
||||||
|
szInstance);
|
||||||
|
|
||||||
|
if (*szEnumerator != UNICODE_NULL && *szDevice != UNICODE_NULL)
|
||||||
|
{
|
||||||
|
ret = GetDeviceInstanceListSize(pszFilter,
|
||||||
|
pulLength);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = CR_CALL_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else /* CM_GETIDLIST_FILTER_NONE */
|
else /* CM_GETIDLIST_FILTER_NONE */
|
||||||
{
|
{
|
||||||
|
@ -1630,51 +1838,6 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID
|
|
||||||
SplitDeviceInstanceID(IN LPWSTR pszDeviceInstanceID,
|
|
||||||
OUT LPWSTR pszEnumerator,
|
|
||||||
OUT LPWSTR pszDevice,
|
|
||||||
OUT LPWSTR pszInstance)
|
|
||||||
{
|
|
||||||
WCHAR szLocalDeviceInstanceID[MAX_DEVICE_ID_LEN];
|
|
||||||
LPWSTR lpEnumerator = NULL;
|
|
||||||
LPWSTR lpDevice = NULL;
|
|
||||||
LPWSTR lpInstance = NULL;
|
|
||||||
LPWSTR ptr;
|
|
||||||
|
|
||||||
wcscpy(szLocalDeviceInstanceID, pszDeviceInstanceID);
|
|
||||||
|
|
||||||
*pszEnumerator = 0;
|
|
||||||
*pszDevice = 0;
|
|
||||||
*pszInstance = 0;
|
|
||||||
|
|
||||||
lpEnumerator = szLocalDeviceInstanceID;
|
|
||||||
|
|
||||||
ptr = wcschr(lpEnumerator, L'\\');
|
|
||||||
if (ptr != NULL)
|
|
||||||
{
|
|
||||||
*ptr = 0;
|
|
||||||
lpDevice = ++ptr;
|
|
||||||
|
|
||||||
ptr = wcschr(lpDevice, L'\\');
|
|
||||||
if (ptr != NULL)
|
|
||||||
{
|
|
||||||
*ptr = 0;
|
|
||||||
lpInstance = ++ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpEnumerator != NULL)
|
|
||||||
wcscpy(pszEnumerator, lpEnumerator);
|
|
||||||
|
|
||||||
if (lpDevice != NULL)
|
|
||||||
wcscpy(pszDevice, lpDevice);
|
|
||||||
|
|
||||||
if (lpInstance != NULL)
|
|
||||||
wcscpy(pszInstance, lpInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static CONFIGRET
|
static CONFIGRET
|
||||||
CreateDeviceInstance(LPWSTR pszDeviceID)
|
CreateDeviceInstance(LPWSTR pszDeviceID)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue