[NTOSKRNL]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 29 Sep 2012 13:22:31 +0000 (13:22 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Sat, 29 Sep 2012 13:22:31 +0000 (13:22 +0000)
- Allocate a capture buffer outside of SEH in NtAddAtom and NtRaiseHardError
- Call ExpGetCurrentUserUILanguage outside of SEH in NtQueryDefaultUILanguage and return the actual result instead of returning PsInstallUILanguageId in case of success.
- Don't allocate a unicode string inside SEH in NtQuerySystemEnvironmentValue, instead use RtlAnsiStringToUnicodeString directly on the callers buffer.
CORE-6624

svn path=/trunk/; revision=57429

reactos/ntoskrnl/ex/atom.c
reactos/ntoskrnl/ex/harderr.c
reactos/ntoskrnl/ex/locale.c
reactos/ntoskrnl/ex/sysinfo.c

index 29e6a3d..7f75947 100644 (file)
@@ -107,50 +107,56 @@ NtAddAtom(IN PWSTR AtomName,
         DPRINT1("Atom name too long\n");
         return STATUS_INVALID_PARAMETER;
     }
         DPRINT1("Atom name too long\n");
         return STATUS_INVALID_PARAMETER;
     }
-    
-    /* Re-use the given name if kernel mode or no atom name */
-    CapturedName = AtomName;
 
 
-    /* Check if we're called from user-mode*/
-    if (PreviousMode != KernelMode)
+    /* Check if we're called from user-mode or kernel-mode */
+    if (PreviousMode == KernelMode)
     {
     {
-        /* Enter SEH */
-        _SEH2_TRY
+        /* Re-use the given name if kernel mode */
+        CapturedName = AtomName;
+    }
+    else
+    {
+        /* Check if we have a name */
+        if (AtomName)
         {
         {
-            /* Check if we have a name */
-            if (AtomName)
+            /* Allocate an aligned buffer + the null char */
+            CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &
+                            ~(sizeof(WCHAR) -1));
+            CapturedName = ExAllocatePoolWithTag(PagedPool,
+                                                 CapturedSize,
+                                                 TAG_ATOM);
+
+            if (!CapturedName)
+            {
+                /* Fail the call */
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+
+            /* Enter SEH */
+            _SEH2_TRY
             {
                 /* Probe the atom */
                 ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
 
             {
                 /* Probe the atom */
                 ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
 
-                /* Allocate an aligned buffer + the null char */
-                CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &~
-                                (sizeof(WCHAR) -1));
-                CapturedName = ExAllocatePoolWithTag(PagedPool,
-                                                     CapturedSize,
-                                                     TAG_ATOM);
-                if (!CapturedName)
-                {
-                    /* Fail the call */
-                    Status = STATUS_INSUFFICIENT_RESOURCES;
-                }
-                else
-                {
-                    /* Copy the name and null-terminate it */
-                    RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
-                    CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
-                }
+                /* Copy the name and null-terminate it */
+                RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
+                CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
 
                 /* Probe the atom too */
                 if (Atom) ProbeForWriteUshort(Atom);
             }
 
                 /* Probe the atom too */
                 if (Atom) ProbeForWriteUshort(Atom);
             }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                /* Return the exception code */
+                _SEH2_YIELD(return _SEH2_GetExceptionCode());
+            }
+            _SEH2_END;
         }
         }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        else
         {
         {
-            /* Return the exception code */
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
+            /* No name */
+            CapturedName = NULL;
         }
         }
-        _SEH2_END;
     }
 
     /* Call the runtime function */
     }
 
     /* Call the runtime function */
@@ -172,7 +178,7 @@ NtAddAtom(IN PWSTR AtomName,
     }
 
     /* If we captured anything, free it */
     }
 
     /* If we captured anything, free it */
-    if ((CapturedName) && (CapturedName != AtomName))
+    if ((CapturedName != NULL) && (CapturedName != AtomName))
         ExFreePoolWithTag(CapturedName, TAG_ATOM);
 
     /* Return to caller */
         ExFreePoolWithTag(CapturedName, TAG_ATOM);
 
     /* Return to caller */
@@ -258,7 +264,7 @@ NtFindAtom(IN PWSTR AtomName,
         DPRINT1("Atom name too long\n");
         return STATUS_INVALID_PARAMETER;
     }
         DPRINT1("Atom name too long\n");
         return STATUS_INVALID_PARAMETER;
     }
-    
+
     /* Re-use the given name if kernel mode or no atom name */
     CapturedName = AtomName;
 
     /* Re-use the given name if kernel mode or no atom name */
     CapturedName = AtomName;
 
index bf37ba0..a43bc24 100644 (file)
@@ -523,7 +523,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
     ULONG SafeResponse;
     UNICODE_STRING SafeString;
     ULONG i;
     ULONG SafeResponse;
     UNICODE_STRING SafeString;
     ULONG i;
-    ULONG ParamSize;
+    ULONG ParamSize = 0;
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
 
     /* Validate parameter count */
     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
 
     /* Validate parameter count */
@@ -534,7 +534,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
     }
 
     /* Make sure we have some at least */
     }
 
     /* Make sure we have some at least */
-    if ((Parameters) && !(NumberOfParameters))
+    if ((Parameters != NULL) && (NumberOfParameters == 0))
     {
         /* Fail */
         return STATUS_INVALID_PARAMETER_2;
     {
         /* Fail */
         return STATUS_INVALID_PARAMETER_2;
@@ -561,6 +561,20 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
                 return STATUS_INVALID_PARAMETER_4;
         }
 
                 return STATUS_INVALID_PARAMETER_4;
         }
 
+        /* Check if we have parameters */
+        if (Parameters)
+        {
+            /* Calculate size of the parameters */
+            ParamSize = sizeof(ULONG_PTR) * NumberOfParameters;
+
+            /* Allocate a safe buffer */
+            SafeParams = ExAllocatePoolWithTag(PagedPool, ParamSize, TAG_ERR);
+            if (!SafeParams)
+            {
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+        }
+
         /* Enter SEH Block */
         _SEH2_TRY
         {
         /* Enter SEH Block */
         _SEH2_TRY
         {
@@ -571,14 +585,8 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
             if (Parameters)
             {
                 /* Validate the parameter pointers */
             if (Parameters)
             {
                 /* Validate the parameter pointers */
-                ParamSize = sizeof(ULONG_PTR) * NumberOfParameters;
                 ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR));
 
                 ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR));
 
-                /* Allocate a safe buffer */
-                SafeParams = ExAllocatePoolWithTag(PagedPool,
-                                                   ParamSize,
-                                                   TAG_ERR);
-
                 /* Copy them */
                 RtlCopyMemory(SafeParams, Parameters, ParamSize);
 
                 /* Copy them */
                 RtlCopyMemory(SafeParams, Parameters, ParamSize);
 
index 8f30639..9347cc7 100644 (file)
@@ -349,9 +349,13 @@ NTSTATUS
 NTAPI
 NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
 {
 NTAPI
 NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
 {
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
+    LANGID SafeLanguageId;
     PAGED_CODE();
 
     PAGED_CODE();
 
+    /* Call the executive helper routine */
+    Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", &SafeLanguageId);
+
     /* Enter SEH for probing */
     _SEH2_TRY
     {
     /* Enter SEH for probing */
     _SEH2_TRY
     {
@@ -362,11 +366,14 @@ NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
             ProbeForWriteLangid(LanguageId);
         }
 
             ProbeForWriteLangid(LanguageId);
         }
 
-        /* Call the executive helper routine */
-        Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", LanguageId);
         if (NT_SUCCESS(Status))
         {
             /* Success, return the language */
         if (NT_SUCCESS(Status))
         {
             /* Success, return the language */
+            *LanguageId = SafeLanguageId;
+        }
+        else
+        {
+            /* Failed, use fallback value */
             *LanguageId = PsInstallUILanguageId;
         }
     }
             *LanguageId = PsInstallUILanguageId;
         }
     }
index 71460af..00053e7 100644 (file)
@@ -211,27 +211,22 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
     ANSI_STRING AName;
     UNICODE_STRING WName;
     ARC_STATUS Result;
     ANSI_STRING AName;
     UNICODE_STRING WName;
     ARC_STATUS Result;
-    PCH Value;
+    PCH AnsiValueBuffer;
     ANSI_STRING AValue;
     UNICODE_STRING WValue;
     KPROCESSOR_MODE PreviousMode;
     NTSTATUS Status;
     PAGED_CODE();
 
     ANSI_STRING AValue;
     UNICODE_STRING WValue;
     KPROCESSOR_MODE PreviousMode;
     NTSTATUS Status;
     PAGED_CODE();
 
+    /* Check if the call came from user mode */
     PreviousMode = ExGetPreviousMode();
     PreviousMode = ExGetPreviousMode();
-
     if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
     if (PreviousMode != KernelMode)
     {
         _SEH2_TRY
         {
-            ProbeForRead(VariableName,
-                         sizeof(UNICODE_STRING),
-                         sizeof(ULONG));
-
-            ProbeForWrite(ValueBuffer,
-                          ValueBufferLength,
-                          sizeof(WCHAR));
-
+            /* Probe the input and output buffers */
+            ProbeForRead(VariableName, sizeof(UNICODE_STRING), sizeof(ULONG));
+            ProbeForWrite(ValueBuffer, ValueBufferLength, sizeof(WCHAR));
             if (ReturnLength != NULL) ProbeForWriteUlong(ReturnLength);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
             if (ReturnLength != NULL) ProbeForWriteUlong(ReturnLength);
         }
         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -240,103 +235,80 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
             _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
             _SEH2_YIELD(return _SEH2_GetExceptionCode());
         }
         _SEH2_END;
+
+    }
+
+    /* Allocate a buffer for the value */
+    AnsiValueBuffer = ExAllocatePoolWithTag(NonPagedPool, ValueBufferLength, 'pmeT');
+    if (AnsiValueBuffer == NULL)
+    {
+        return STATUS_INSUFFICIENT_RESOURCES;
     }
 
     /*
      * Copy the name to kernel space if necessary and convert it to ANSI.
      */
     }
 
     /*
      * Copy the name to kernel space if necessary and convert it to ANSI.
      */
-    Status = ProbeAndCaptureUnicodeString(&WName,
-                                          PreviousMode,
-                                          VariableName);
-    if (NT_SUCCESS(Status))
+    Status = ProbeAndCaptureUnicodeString(&WName, PreviousMode, VariableName);
+    if (!NT_SUCCESS(Status))
     {
     {
-        /*
-         * according to ntinternals the SeSystemEnvironmentName privilege is required!
-         */
-        if (!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
-                                    PreviousMode))
-        {
-            ReleaseCapturedUnicodeString(&WName, PreviousMode);
-            DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
-            return STATUS_PRIVILEGE_NOT_HELD;
-        }
+        return Status;
+    }
 
 
-        /*
-         * convert the value name to ansi
-         */
-        Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
+    /*
+     * according to ntinternals the SeSystemEnvironmentName privilege is required!
+     */
+    if (!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege, PreviousMode))
+    {
         ReleaseCapturedUnicodeString(&WName, PreviousMode);
         ReleaseCapturedUnicodeString(&WName, PreviousMode);
+        DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
+        return STATUS_PRIVILEGE_NOT_HELD;
+    }
 
 
-        if (!NT_SUCCESS(Status)) return Status;
-
-        /*
-         * Create a temporary buffer for the value
-         */
-        Value = ExAllocatePool(NonPagedPool, ValueBufferLength);
-        if (Value == NULL)
-        {
-            RtlFreeAnsiString(&AName);
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
+    /* Convert the value name to ansi and release the captured unicode string */
+    Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
+    ReleaseCapturedUnicodeString(&WName, PreviousMode);
+    if (!NT_SUCCESS(Status)) return Status;
 
 
-        /*
-         * Get the environment variable
-         */
-        Result = HalGetEnvironmentVariable(AName.Buffer,
-                                           (USHORT)ValueBufferLength,
-                                           Value);
-        if (!Result)
-        {
-            RtlFreeAnsiString(&AName);
-            ExFreePool(Value);
-            return STATUS_UNSUCCESSFUL;
-        }
+    /* Get the environment variable */
+    Result = HalGetEnvironmentVariable(AName.Buffer,
+                                       (USHORT)ValueBufferLength,
+                                       AnsiValueBuffer);
 
 
-        /*
-         * Convert the result to UNICODE, protect with SEH in case the value buffer
-         * isn't NULL-terminated!
-         */
+    /* Check if we had success */
+    if (Result == ESUCCESS)
+    {
+        /* Copy the result back to the caller. */
         _SEH2_TRY
         {
         _SEH2_TRY
         {
-            RtlInitAnsiString(&AValue, Value);
-            Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE);
+            /* Initialize ansi string from the result */
+            RtlInitAnsiString(&AValue, AnsiValueBuffer);
+
+            /* Initialize a unicode string from the callers buffer */
+            RtlInitEmptyUnicodeString(&WValue, ValueBuffer, ValueBufferLength);
+
+            /* Convert the result to unicode */
+            Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, FALSE);
+
+            if (ReturnLength != NULL)
+            {
+                *ReturnLength = WValue.Length;
+            }
         }
         _SEH2_EXCEPT(ExSystemExceptionFilter())
         {
             Status = _SEH2_GetExceptionCode();
         }
         _SEH2_END;
         }
         _SEH2_EXCEPT(ExSystemExceptionFilter())
         {
             Status = _SEH2_GetExceptionCode();
         }
         _SEH2_END;
-
-        if (NT_SUCCESS(Status))
-        {
-            /*
-             * Copy the result back to the caller.
-             */
-            _SEH2_TRY
-            {
-                RtlCopyMemory(ValueBuffer, WValue.Buffer, WValue.Length);
-                ValueBuffer[WValue.Length / sizeof(WCHAR)] = L'\0';
-                if (ReturnLength != NULL)
-                {
-                    *ReturnLength = WValue.Length + sizeof(WCHAR);
-                }
-
-                Status = STATUS_SUCCESS;
-            }
-            _SEH2_EXCEPT(ExSystemExceptionFilter())
-            {
-                Status = _SEH2_GetExceptionCode();
-            }
-            _SEH2_END;
-        }
-
-        /*
-         * Cleanup allocated resources.
-         */
-        RtlFreeAnsiString(&AName);
-        ExFreePool(Value);
+    }
+    else
+    {
+        Status = STATUS_UNSUCCESSFUL;
     }
 
     }
 
+    /* Cleanup allocated resources. */
+    RtlFreeAnsiString(&AName);
+    ExFreePoolWithTag(AnsiValueBuffer, 'pmeT');
+
     return Status;
 }
 
     return Status;
 }
 
@@ -466,7 +438,7 @@ ExQueryPoolUsage(OUT PULONG PagedPoolPages,
                  OUT PULONG NonPagedPoolAllocs,
                  OUT PULONG NonPagedPoolFrees,
                  OUT PULONG NonPagedPoolLookasideHits);
                  OUT PULONG NonPagedPoolAllocs,
                  OUT PULONG NonPagedPoolFrees,
                  OUT PULONG NonPagedPoolLookasideHits);
-    
+
 /* Class 0 - Basic Information */
 QSI_DEF(SystemBasicInformation)
 {
 /* Class 0 - Basic Information */
 QSI_DEF(SystemBasicInformation)
 {
@@ -741,7 +713,7 @@ QSI_DEF(SystemProcessInformation)
         do
         {
             SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
         do
         {
             SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
-            
+
             if ((Process->ProcessExiting) &&
                 (Process->Pcb.Header.SignalState) &&
                 !(Process->ActiveThreads) &&
             if ((Process->ProcessExiting) &&
                 (Process->Pcb.Header.SignalState) &&
                 !(Process->ActiveThreads) &&
@@ -1801,9 +1773,9 @@ SSI_DEF(SystemCreateSession)
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     NTSTATUS Status;
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
     NTSTATUS Status;
-    
+
     if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
     if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
-    
+
     if (PreviousMode != KernelMode)
     {
         if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
     if (PreviousMode != KernelMode)
     {
         if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
@@ -1811,7 +1783,7 @@ SSI_DEF(SystemCreateSession)
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
-    
+
     Status = MmSessionCreate(&SessionId);
     if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
 
     Status = MmSessionCreate(&SessionId);
     if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
 
@@ -1824,9 +1796,9 @@ SSI_DEF(SystemDeleteSession)
 {
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
 {
     ULONG SessionId;
     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    
+
     if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
     if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
-    
+
     if (PreviousMode != KernelMode)
     {
         if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
     if (PreviousMode != KernelMode)
     {
         if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
@@ -1834,9 +1806,9 @@ SSI_DEF(SystemDeleteSession)
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
             return STATUS_PRIVILEGE_NOT_HELD;
         }
     }
-    
+
     SessionId = *(PULONG)Buffer;
     SessionId = *(PULONG)Buffer;
-    
+
     return MmSessionDelete(SessionId);
 }
 
     return MmSessionDelete(SessionId);
 }