/* INCLUDES *****************************************************************/
#include <rtl.h>
+
+#include <ndk/cmfuncs.h>
+
#define NDEBUG
#include <debug.h>
IN ULONG ValueLength,
IN PVOID Buffer)
{
- USHORT ActualLength = (USHORT)ValueLength;
+ USHORT ActualLength;
PUNICODE_STRING ReturnString = Buffer;
PULONG Length = Buffer;
ULONG RealLength;
(ValueType == REG_MULTI_SZ))
{
/* Normalize the length */
- if (ValueLength > MAXUSHORT) ValueLength = MAXUSHORT;
+ if (ValueLength > MAXUSHORT)
+ ActualLength = MAXUSHORT;
+ else
+ ActualLength = (USHORT)ValueLength;
/* Check if the return string has been allocated */
if (!ReturnString->Buffer)
IN PVOID Context,
IN PVOID Environment)
{
- ULONG InfoLength, Length, c;
- LONG RequiredLength, SpareLength;
+ ULONG InfoLength;
+ SIZE_T Length, SpareLength, c;
+ ULONG RequiredLength;
PCHAR SpareData, DataEnd;
ULONG Type;
PWCHAR Name, p, ValueEnd;
/* Check if we have space to copy the data */
RequiredLength = KeyValueInfo->NameLength + sizeof(UNICODE_NULL);
- if (SpareLength < RequiredLength)
+ if ((SpareData > DataEnd) || (SpareLength < RequiredLength))
{
/* Fail and return the missing length */
- *InfoSize = SpareData - (PCHAR)KeyValueInfo + RequiredLength;
+ *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength;
return STATUS_BUFFER_TOO_SMALL;
}
{
/* Prepare defaults */
Status = STATUS_SUCCESS;
- ValueEnd = (PWSTR)((ULONG_PTR)Data + Length) - sizeof(UNICODE_NULL);
+ /* Skip the last two UNICODE_NULL chars (the terminating null string) */
+ ValueEnd = (PWSTR)((ULONG_PTR)Data + Length - 2 * sizeof(UNICODE_NULL));
p = Data;
/* Loop all strings */
/* Do the query */
Status = RtlpQueryRegistryDirect(REG_SZ,
Data,
- Length,
+ (ULONG)Length,
QueryTable->EntryContext);
- QueryTable->EntryContext = (PVOID)((ULONG_PTR)QueryTable->
- EntryContext +
- sizeof(UNICODE_STRING));
+ QueryTable->EntryContext =
+ (PVOID)((ULONG_PTR)QueryTable->EntryContext +
+ sizeof(UNICODE_STRING));
}
else
{
Status = QueryTable->QueryRoutine(Name,
REG_SZ,
Data,
- Length,
+ (ULONG)Length,
Context,
QueryTable->EntryContext);
}
if (FoundExpander)
{
/* Setup the source string */
- RtlInitEmptyUnicodeString(&Source, Data, Length);
+ RtlInitEmptyUnicodeString(&Source, Data, (USHORT)Length);
Source.Length = Source.MaximumLength - sizeof(UNICODE_NULL);
/* Setup the desination string */
else if (SpareLength <= MAXUSHORT)
{
/* This is the good case, where we fit into a string */
- Destination.MaximumLength = SpareLength;
- Destination.Buffer[SpareLength / 2 - 1] = UNICODE_NULL;
+ Destination.MaximumLength = (USHORT)SpareLength;
+ Destination.Buffer[SpareLength / sizeof(WCHAR) - 1] = UNICODE_NULL;
}
else
{
/* We can't fit into a string, so truncate */
Destination.MaximumLength = MAXUSHORT;
- Destination.Buffer[MAXUSHORT / 2 - 1] = UNICODE_NULL;
+ Destination.Buffer[MAXUSHORT / sizeof(WCHAR) - 1] = UNICODE_NULL;
}
/* Expand the strings and set our type as one string */
Status = RtlExpandEnvironmentStrings_U(Environment,
&Source,
&Destination,
- (PULONG)&RequiredLength);
+ &RequiredLength);
Type = REG_SZ;
/* Check for success */
if (Status == STATUS_BUFFER_TOO_SMALL)
{
/* Set the required missing length */
- *InfoSize = SpareData -
- (PCHAR)KeyValueInfo +
- RequiredLength;
+ *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) +
+ RequiredLength;
/* Notify debugger */
DPRINT1("RTL: Expand variables for %wZ failed - "
/* Return the data */
Status = RtlpQueryRegistryDirect(Type,
Data,
- Length,
+ (ULONG)Length,
QueryTable->EntryContext);
}
else
Status = QueryTable->QueryRoutine(Name,
Type,
Data,
- Length,
+ (ULONG)Length,
Context,
QueryTable->EntryContext);
}
return (Status == STATUS_BUFFER_TOO_SMALL) ? STATUS_SUCCESS : Status;
}
+_Success_(return!=NULL || BufferSize==0)
+_When_(BufferSize!=NULL,__drv_allocatesMem(Mem))
PVOID
NTAPI
-RtlpAllocDeallocQueryBuffer(IN OUT PSIZE_T BufferSize,
- IN PVOID OldBuffer,
- IN SIZE_T OldBufferSize,
- OUT PNTSTATUS Status)
+RtlpAllocDeallocQueryBuffer(
+ _In_opt_ PSIZE_T BufferSize,
+ _In_opt_ __drv_freesMem(Mem) PVOID OldBuffer,
+ _In_ SIZE_T OldBufferSize,
+ _Out_opt_ _On_failure_(_Post_satisfies_(*Status < 0)) PNTSTATUS Status)
{
PVOID Buffer = NULL;
return Status;
}
+FORCEINLINE
+VOID
+RtlpCloseRegistryHandle(
+ _In_ ULONG RelativeTo,
+ _In_ HANDLE KeyHandle)
+{
+ /* Did the caller pass a key handle? */
+ if (!(RelativeTo & RTL_REGISTRY_HANDLE))
+ {
+ /* We opened the key in RtlpGetRegistryHandle, so close it now */
+ ZwClose(KeyHandle);
+ }
+}
+
/* PUBLIC FUNCTIONS **********************************************************/
/*
&KeyHandle);
if (!NT_SUCCESS(Status)) return Status;
- /* All went well, close the handle and return success */
+ /* Close the handle even for RTL_REGISTRY_HANDLE */
ZwClose(KeyHandle);
return STATUS_SUCCESS;
}
&KeyHandle);
if (!NT_SUCCESS(Status)) return Status;
- /* All went well, close the handle and return success */
- ZwClose(KeyHandle);
+ /* All went well, close the handle and return status */
+ RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
return STATUS_SUCCESS;
}
RtlInitUnicodeString(&Name, ValueName);
Status = ZwDeleteValueKey(KeyHandle, &Name);
- /* All went well, close the handle and return status */
- ZwClose(KeyHandle);
+ /* Close the handle and return status */
+ RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
return Status;
}
ValueData,
ValueLength);
- /* All went well, close the handle and return status */
- ZwClose(KeyHandle);
+ /* Close the handle and return status */
+ RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
return Status;
}
/* Initialize a string */
RtlInitEmptyUnicodeString(KeyPath,
RtlpAllocateStringMemory(Length, TAG_USTR),
- Length);
+ (USHORT)Length);
if (!KeyPath->Buffer)
{
/* Free the string and fail */
KeyInfo,
BufferLength,
&ReturnedLength);
- if (NT_SUCCESS(Status))
+ if (NT_SUCCESS(Status) && (KeyInfo != NULL))
{
/* Check if the name fits */
if (KeyInfo->NameLength <= SubKeyName->MaximumLength)
{
/* Set the length */
- SubKeyName->Length = KeyInfo->NameLength;
+ SubKeyName->Length = (USHORT)KeyInfo->NameLength;
/* Copy it */
RtlMoveMemory(SubKeyName->Buffer,
if (!KeyValueInfo)
{
/* Close the handle if we have one and fail */
- if (!(RelativeTo & RTL_REGISTRY_HANDLE)) ZwClose(KeyHandle);
+ RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
return Status;
}
&KeyValueName,
KeyValueFullInformation,
KeyValueInfo,
- InfoSize,
+ (ULONG)InfoSize,
&ResultLength);
if (Status == STATUS_BUFFER_OVERFLOW)
{
/* Setup a default */
KeyValueInfo->Type = REG_NONE;
KeyValueInfo->DataLength = 0;
- ResultLength = InfoSize;
+ ResultLength = (ULONG)InfoSize;
/* Call the query routine */
Status = RtlpCallQueryRegistryRoutine(QueryTable,
if (KeyValueInfo->Type == REG_MULTI_SZ)
{
/* Add a null-char */
- ((PWCHAR)KeyValueInfo)[ResultLength / 2] = UNICODE_NULL;
+ ((PWCHAR)KeyValueInfo)[ResultLength / sizeof(WCHAR)] = UNICODE_NULL;
KeyValueInfo->DataLength += sizeof(UNICODE_NULL);
}
/* Call the query routine */
- ResultLength = InfoSize;
+ ResultLength = (ULONG)InfoSize;
Status = RtlpCallQueryRegistryRoutine(QueryTable,
KeyValueInfo,
&ResultLength,
Value,
KeyValueFullInformation,
KeyValueInfo,
- InfoSize,
+ (ULONG)InfoSize,
&ResultLength);
if (Status == STATUS_BUFFER_OVERFLOW)
{
if (NT_SUCCESS(Status))
{
/* Call the query routine */
- ResultLength = InfoSize;
+ ResultLength = (ULONG)InfoSize;
Status = RtlpCallQueryRegistryRoutine(QueryTable,
KeyValueInfo,
&ResultLength,
}
/* Check if we need to close our handle */
- if ((KeyHandle) && !(RelativeTo & RTL_REGISTRY_HANDLE)) ZwClose(KeyHandle);
+ if (KeyHandle) RtlpCloseRegistryHandle(RelativeTo, KeyHandle);
if ((CurrentKey) && (CurrentKey != KeyHandle)) ZwClose(CurrentKey);
/* Free our buffer and return status */