mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-03 04:13:31 +00:00
[NTOSKRNL]
- 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
This commit is contained in:
+38
-32
@@ -107,50 +107,56 @@ NtAddAtom(IN PWSTR AtomName,
|
||||
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));
|
||||
|
||||
/* 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);
|
||||
}
|
||||
_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 */
|
||||
@@ -172,7 +178,7 @@ NtAddAtom(IN PWSTR AtomName,
|
||||
}
|
||||
|
||||
/* If we captured anything, free it */
|
||||
if ((CapturedName) && (CapturedName != AtomName))
|
||||
if ((CapturedName != NULL) && (CapturedName != AtomName))
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* Re-use the given name if kernel mode or no atom name */
|
||||
CapturedName = AtomName;
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
|
||||
ULONG SafeResponse;
|
||||
UNICODE_STRING SafeString;
|
||||
ULONG i;
|
||||
ULONG ParamSize;
|
||||
ULONG ParamSize = 0;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
|
||||
/* Validate parameter count */
|
||||
@@ -534,7 +534,7 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
|
||||
}
|
||||
|
||||
/* Make sure we have some at least */
|
||||
if ((Parameters) && !(NumberOfParameters))
|
||||
if ((Parameters != NULL) && (NumberOfParameters == 0))
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_INVALID_PARAMETER_2;
|
||||
@@ -561,6 +561,20 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
|
||||
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
|
||||
{
|
||||
@@ -571,14 +585,8 @@ NtRaiseHardError(IN NTSTATUS ErrorStatus,
|
||||
if (Parameters)
|
||||
{
|
||||
/* Validate the parameter pointers */
|
||||
ParamSize = sizeof(ULONG_PTR) * NumberOfParameters;
|
||||
ProbeForRead(Parameters, ParamSize, sizeof(ULONG_PTR));
|
||||
|
||||
/* Allocate a safe buffer */
|
||||
SafeParams = ExAllocatePoolWithTag(PagedPool,
|
||||
ParamSize,
|
||||
TAG_ERR);
|
||||
|
||||
/* Copy them */
|
||||
RtlCopyMemory(SafeParams, Parameters, ParamSize);
|
||||
|
||||
|
||||
@@ -349,9 +349,13 @@ NTSTATUS
|
||||
NTAPI
|
||||
NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
NTSTATUS Status;
|
||||
LANGID SafeLanguageId;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Call the executive helper routine */
|
||||
Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", &SafeLanguageId);
|
||||
|
||||
/* Enter SEH for probing */
|
||||
_SEH2_TRY
|
||||
{
|
||||
@@ -362,11 +366,14 @@ NtQueryDefaultUILanguage(OUT LANGID* LanguageId)
|
||||
ProbeForWriteLangid(LanguageId);
|
||||
}
|
||||
|
||||
/* Call the executive helper routine */
|
||||
Status = ExpGetCurrentUserUILanguage(L"MultiUILanguageId", LanguageId);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Success, return the language */
|
||||
*LanguageId = SafeLanguageId;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed, use fallback value */
|
||||
*LanguageId = PsInstallUILanguageId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,27 +211,22 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
|
||||
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();
|
||||
|
||||
/* Check if the call came from user mode */
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
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)
|
||||
@@ -240,102 +235,79 @@ NtQuerySystemEnvironmentValue(IN PUNICODE_STRING VariableName,
|
||||
_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.
|
||||
*/
|
||||
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);
|
||||
DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
/* 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;
|
||||
|
||||
/*
|
||||
* Create a temporary buffer for the value
|
||||
*/
|
||||
Value = ExAllocatePool(NonPagedPool, ValueBufferLength);
|
||||
if (Value == NULL)
|
||||
{
|
||||
RtlFreeAnsiString(&AName);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
/* Get the environment variable */
|
||||
Result = HalGetEnvironmentVariable(AName.Buffer,
|
||||
(USHORT)ValueBufferLength,
|
||||
AnsiValueBuffer);
|
||||
|
||||
/*
|
||||
* Get the environment variable
|
||||
*/
|
||||
Result = HalGetEnvironmentVariable(AName.Buffer,
|
||||
(USHORT)ValueBufferLength,
|
||||
Value);
|
||||
if (!Result)
|
||||
{
|
||||
RtlFreeAnsiString(&AName);
|
||||
ExFreePool(Value);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -466,7 +438,7 @@ ExQueryPoolUsage(OUT PULONG PagedPoolPages,
|
||||
OUT PULONG NonPagedPoolAllocs,
|
||||
OUT PULONG NonPagedPoolFrees,
|
||||
OUT PULONG NonPagedPoolLookasideHits);
|
||||
|
||||
|
||||
/* Class 0 - Basic Information */
|
||||
QSI_DEF(SystemBasicInformation)
|
||||
{
|
||||
@@ -741,7 +713,7 @@ QSI_DEF(SystemProcessInformation)
|
||||
do
|
||||
{
|
||||
SpiCurrent = (PSYSTEM_PROCESS_INFORMATION) Current;
|
||||
|
||||
|
||||
if ((Process->ProcessExiting) &&
|
||||
(Process->Pcb.Header.SignalState) &&
|
||||
!(Process->ActiveThreads) &&
|
||||
@@ -1801,9 +1773,9 @@ SSI_DEF(SystemCreateSession)
|
||||
ULONG SessionId;
|
||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||
NTSTATUS Status;
|
||||
|
||||
|
||||
if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
|
||||
@@ -1811,7 +1783,7 @@ SSI_DEF(SystemCreateSession)
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Status = MmSessionCreate(&SessionId);
|
||||
if (NT_SUCCESS(Status)) *(PULONG)Buffer = SessionId;
|
||||
|
||||
@@ -1824,9 +1796,9 @@ SSI_DEF(SystemDeleteSession)
|
||||
{
|
||||
ULONG SessionId;
|
||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||
|
||||
|
||||
if (Size != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH;
|
||||
|
||||
|
||||
if (PreviousMode != KernelMode)
|
||||
{
|
||||
if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, PreviousMode))
|
||||
@@ -1834,9 +1806,9 @@ SSI_DEF(SystemDeleteSession)
|
||||
return STATUS_PRIVILEGE_NOT_HELD;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SessionId = *(PULONG)Buffer;
|
||||
|
||||
|
||||
return MmSessionDelete(SessionId);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user