mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
cf40421041
Spotted by Vadim Galyant.
195 lines
5.7 KiB
C
195 lines
5.7 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: ntoskrnl/io/pnpmgr/pnputil.c
|
|
* PURPOSE: PnP Utility Code
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include <ntoskrnl.h>
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
VOID
|
|
NTAPI
|
|
PnpFreeUnicodeStringList(IN PUNICODE_STRING UnicodeStringList,
|
|
IN ULONG StringCount)
|
|
{
|
|
ULONG i;
|
|
|
|
/* Go through the list */
|
|
if (UnicodeStringList)
|
|
{
|
|
/* Go through each string */
|
|
for (i = 0; i < StringCount; i++)
|
|
{
|
|
/* Check if it exists */
|
|
if (UnicodeStringList[i].Buffer)
|
|
{
|
|
/* Free it */
|
|
ExFreePool(UnicodeStringList[i].Buffer);
|
|
}
|
|
}
|
|
|
|
/* Free the whole list */
|
|
ExFreePool(UnicodeStringList);
|
|
}
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
PnpRegMultiSzToUnicodeStrings(IN PKEY_VALUE_FULL_INFORMATION KeyValueInformation,
|
|
OUT PUNICODE_STRING *UnicodeStringList,
|
|
OUT PULONG UnicodeStringCount)
|
|
{
|
|
PWCHAR p, pp, ps;
|
|
ULONG i = 0;
|
|
SIZE_T n;
|
|
ULONG Count = 0;
|
|
|
|
/* Validate the key information */
|
|
if (KeyValueInformation->Type != REG_MULTI_SZ) return STATUS_INVALID_PARAMETER;
|
|
|
|
/* Set the pointers */
|
|
p = (PWCHAR)((ULONG_PTR)KeyValueInformation +
|
|
KeyValueInformation->DataOffset);
|
|
pp = (PWCHAR)((ULONG_PTR)p + KeyValueInformation->DataLength);
|
|
|
|
/* Loop the data */
|
|
while (p != pp)
|
|
{
|
|
/* If we find a NULL, that means one string is done */
|
|
if (!*p)
|
|
{
|
|
/* Add to our string count */
|
|
Count++;
|
|
|
|
/* Check for a double-NULL, which means we're done */
|
|
if (((p + 1) == pp) || !(*(p + 1))) break;
|
|
}
|
|
|
|
/* Go to the next character */
|
|
p++;
|
|
}
|
|
|
|
/* If we looped the whole list over, we missed increment a string, do it */
|
|
if (p == pp) Count++;
|
|
|
|
/* Allocate the list now that we know how big it is */
|
|
*UnicodeStringList = ExAllocatePoolWithTag(PagedPool,
|
|
sizeof(UNICODE_STRING) * Count,
|
|
'sUpP');
|
|
if (!(*UnicodeStringList)) return STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
/* Set pointers for second loop */
|
|
ps = p = (PWCHAR)((ULONG_PTR)KeyValueInformation +
|
|
KeyValueInformation->DataOffset);
|
|
|
|
/* Loop again, to do the copy this time */
|
|
while (p != pp)
|
|
{
|
|
/* If we find a NULL, that means one string is done */
|
|
if (!*p)
|
|
{
|
|
/* Check how long this string is */
|
|
n = (ULONG_PTR)p - (ULONG_PTR)ps + sizeof(UNICODE_NULL);
|
|
|
|
/* Allocate the buffer */
|
|
(*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool,
|
|
n,
|
|
'sUpP');
|
|
if (!(*UnicodeStringList)[i].Buffer)
|
|
{
|
|
/* Back out of everything */
|
|
PnpFreeUnicodeStringList(*UnicodeStringList, i);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
/* Copy the string into the buffer */
|
|
RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n);
|
|
|
|
/* Set the lengths */
|
|
(*UnicodeStringList)[i].MaximumLength = (USHORT)n;
|
|
(*UnicodeStringList)[i].Length = (USHORT)(n - sizeof(UNICODE_NULL));
|
|
|
|
/* One more entry done */
|
|
i++;
|
|
|
|
/* Check for a double-NULL, which means we're done */
|
|
if (((p + 1) == pp) || !(*(p + 1))) break;
|
|
|
|
/* New string */
|
|
ps = p + 1;
|
|
}
|
|
|
|
/* New string */
|
|
p++;
|
|
}
|
|
|
|
/* Check if we've reached the last string */
|
|
if (p == pp)
|
|
{
|
|
/* Calculate the string length */
|
|
n = (ULONG_PTR)p - (ULONG_PTR)ps;
|
|
|
|
/* Allocate the buffer for it */
|
|
(*UnicodeStringList)[i].Buffer = ExAllocatePoolWithTag(PagedPool,
|
|
n +
|
|
sizeof(UNICODE_NULL),
|
|
'sUpP');
|
|
if (!(*UnicodeStringList)[i].Buffer)
|
|
{
|
|
/* Back out of everything */
|
|
PnpFreeUnicodeStringList(*UnicodeStringList, i);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
/* Make sure there's an actual string here */
|
|
if (n) RtlCopyMemory((*UnicodeStringList)[i].Buffer, ps, n);
|
|
|
|
/* Null-terminate the string ourselves */
|
|
(*UnicodeStringList)[i].Buffer[n / sizeof(WCHAR)] = UNICODE_NULL;
|
|
|
|
/* Set the lengths */
|
|
(*UnicodeStringList)[i].Length = (USHORT)n;
|
|
(*UnicodeStringList)[i].MaximumLength = (USHORT)(n + sizeof(UNICODE_NULL));
|
|
}
|
|
|
|
/* And we're done */
|
|
*UnicodeStringCount = Count;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
BOOLEAN
|
|
NTAPI
|
|
PnpRegSzToString(IN PWCHAR RegSzData,
|
|
IN ULONG RegSzLength,
|
|
OUT PUSHORT StringLength OPTIONAL)
|
|
{
|
|
PWCHAR p, pp;
|
|
|
|
/* Find the end */
|
|
pp = RegSzData + RegSzLength / sizeof(WCHAR);
|
|
for (p = RegSzData; p < pp; p++)
|
|
{
|
|
if (!*p)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Return the length. Truncation can happen but is of no consequence. */
|
|
if (StringLength)
|
|
{
|
|
*StringLength = (USHORT)(p - RegSzData) * sizeof(WCHAR);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/* EOF */
|