Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[reactos.git] / lib / rtl / registry.c
index d6e4458..7c3ac49 100644 (file)
@@ -38,7 +38,7 @@ RtlpQueryRegistryDirect(IN ULONG ValueType,
                         IN ULONG ValueLength,
                         IN PVOID Buffer)
 {
-    USHORT ActualLength = (USHORT)ValueLength;
+    USHORT ActualLength;
     PUNICODE_STRING ReturnString = Buffer;
     PULONG Length = Buffer;
     ULONG RealLength;
@@ -49,7 +49,10 @@ RtlpQueryRegistryDirect(IN ULONG ValueType,
         (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)
@@ -116,8 +119,9 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
                              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;
@@ -207,7 +211,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
             if (SpareLength < RequiredLength)
             {
                 /* Fail and return the missing length */
-                *InfoSize = SpareData - (PCHAR)KeyValueInfo + RequiredLength;
+                *InfoSize = (ULONG)(SpareData - (PCHAR)KeyValueInfo) + RequiredLength;
                 return STATUS_BUFFER_TOO_SMALL;
             }
 
@@ -241,7 +245,8 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
         {
             /* 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 */
@@ -257,11 +262,11 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
                     /* 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
                 {
@@ -269,7 +274,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
                     Status = QueryTable->QueryRoutine(Name,
                                                       REG_SZ,
                                                       Data,
-                                                      Length,
+                                                      (ULONG)Length,
                                                       Context,
                                                       QueryTable->EntryContext);
                 }
@@ -311,7 +316,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
             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 */
@@ -326,21 +331,21 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
                 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 */
@@ -356,9 +361,8 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
                     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 - "
@@ -391,7 +395,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
         /* Return the data */
         Status = RtlpQueryRegistryDirect(Type,
                                          Data,
-                                         Length,
+                                         (ULONG)Length,
                                          QueryTable->EntryContext);
     }
     else
@@ -400,7 +404,7 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
         Status = QueryTable->QueryRoutine(Name,
                                           Type,
                                           Data,
-                                          Length,
+                                          (ULONG)Length,
                                           Context,
                                           QueryTable->EntryContext);
     }
@@ -409,12 +413,15 @@ RtlpCallQueryRegistryRoutine(IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
     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;
 
@@ -756,7 +763,7 @@ RtlFormatCurrentUserKeyPath(OUT PUNICODE_STRING KeyPath)
     /* Initialize a string */
     RtlInitEmptyUnicodeString(KeyPath,
                               RtlpAllocateStringMemory(Length, TAG_USTR),
-                              Length);
+                              (USHORT)Length);
     if (!KeyPath->Buffer)
     {
         /* Free the string and fail */
@@ -834,13 +841,13 @@ RtlpNtEnumerateSubKey(IN HANDLE KeyHandle,
                             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,
@@ -1094,7 +1101,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
                                          &KeyValueName,
                                          KeyValueFullInformation,
                                          KeyValueInfo,
-                                         InfoSize,
+                                         (ULONG)InfoSize,
                                          &ResultLength);
                 if (Status == STATUS_BUFFER_OVERFLOW)
                 {
@@ -1111,7 +1118,7 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
                         /* Setup a default */
                         KeyValueInfo->Type = REG_NONE;
                         KeyValueInfo->DataLength = 0;
-                        ResultLength = InfoSize;
+                        ResultLength = (ULONG)InfoSize;
 
                         /* Call the query routine */
                         Status = RtlpCallQueryRegistryRoutine(QueryTable,
@@ -1146,12 +1153,12 @@ RtlQueryRegistryValues(IN ULONG RelativeTo,
                     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,
@@ -1212,7 +1219,7 @@ ProcessValues:
                                              Value,
                                              KeyValueFullInformation,
                                              KeyValueInfo,
-                                             InfoSize,
+                                             (ULONG)InfoSize,
                                              &ResultLength);
                 if (Status == STATUS_BUFFER_OVERFLOW)
                 {
@@ -1242,7 +1249,7 @@ ProcessValues:
                 if (NT_SUCCESS(Status))
                 {
                     /* Call the query routine */
-                    ResultLength = InfoSize;
+                    ResultLength = (ULONG)InfoSize;
                     Status = RtlpCallQueryRegistryRoutine(QueryTable,
                                                           KeyValueInfo,
                                                           &ResultLength,