From 97771b148768a837e35b1fa1c423be85c3deec41 Mon Sep 17 00:00:00 2001 From: David Welch Date: Sun, 2 Sep 2001 17:29:52 +0000 Subject: [PATCH] Implemented NtSetEnvironmentVariable svn path=/trunk/; revision=2223 --- reactos/include/ddk/zw.h | 11 +- reactos/ntoskrnl/ex/power.c | 2 +- reactos/ntoskrnl/ex/sysinfo.c | 165 ++++++++++++++++------- reactos/ntoskrnl/include/internal/safe.h | 4 + 4 files changed, 130 insertions(+), 52 deletions(-) diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index acce6d20598..ec292302a22 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -1,5 +1,5 @@ -/* $Id: zw.h,v 1.46 2001/06/11 19:45:29 ekohl Exp $ +/* $Id: zw.h,v 1.47 2001/09/02 17:29:50 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -5230,11 +5230,10 @@ NtGetPlugPlayEvent ( /* --- POWER MANAGEMENT --- */ -NTSTATUS -STDCALL -NtSetSystemPowerState ( - VOID - ); +NTSTATUS STDCALL +NtSetSystemPowerState(IN POWER_ACTION SystemAction, + IN SYSTEM_POWER_STATE MinSystemState, + IN ULONG Flags); /* --- DEBUG SUBSYSTEM --- */ diff --git a/reactos/ntoskrnl/ex/power.c b/reactos/ntoskrnl/ex/power.c index d34d1b59d4b..34c63a657e8 100644 --- a/reactos/ntoskrnl/ex/power.c +++ b/reactos/ntoskrnl/ex/power.c @@ -28,7 +28,7 @@ NtSetSystemPowerState(IN POWER_ACTION SystemAction, IN ULONG Flags) { /* Windows 2000 only */ - return(STATUS_UNIMPLEMENTED); + return(STATUS_NOT_IMPLEMENTED); } NTSTATUS STDCALL diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 87682084011..1d70c779924 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -1,4 +1,4 @@ -/* $Id: sysinfo.c,v 1.12 2001/09/02 15:38:46 dwelch Exp $ +/* $Id: sysinfo.c,v 1.13 2001/09/02 17:29:51 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -12,8 +12,12 @@ /* INCLUDES *****************************************************************/ #include +#include +#include +#include #include #include +#include #include @@ -27,11 +31,9 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, IN ULONG Length, IN OUT PULONG UnsafeReturnLength) { - PWCH WNameBuffer; NTSTATUS Status; - USHORT NameLength; ANSI_STRING AName; - UNICODE_STRING Name; + UNICODE_STRING WName; BOOLEAN Result; PCH Value; ANSI_STRING AValue; @@ -43,73 +45,57 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, */ if (ExGetPreviousMode() != KernelMode) { - Status = MmSafeCopyFromUser(&NameLength, &UnsafeName->Length, - sizeof(NameLength)); + Status = RtlCaptureUnicodeString(&WName, UnsafeName); if (!NT_SUCCESS(Status)) { return(Status); } - - WNameBuffer = ExAllocatePool(NonPagedPool, NameLength + sizeof(WCHAR)); - if (WNameBuffer != NULL) - { - return(STATUS_NO_MORE_MEMORY); - } - memset(WNameBuffer, 0, NameLength + sizeof(WCHAR)); - - Status = MmSafeCopyFromUser(WNameBuffer, UnsafeName->Buffer, - NameLength * sizeof(WCHAR)); + Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE); if (!NT_SUCCESS(Status)) { - ExFreePool(WNameBuffer); - return(Status); - } - WNameBuffer[NameLength / sizeof(WCHAR)] = 0; - - RtlInitUnicodeString(&Name, WNameBuffer); - Status = RtlUnicodeStringToAnsiString(&AName, &Name, TRUE); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&Name); return(Status); } } else { - RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE); + Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } } /* * Create a temporary buffer for the value */ - ValueBuffer = ExAllocatePool(NonPagedPool, Length); - if (ValueBuffer == NULL) + Value = ExAllocatePool(NonPagedPool, Length); + if (Value == NULL) { RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } - return(STATUS_NO_MORE_MEMORY); + return(STATUS_NO_MEMORY); } /* * Get the environment variable */ - Result = HalGetEnvironmentVariable(AName->Buffer, Value, Length); + Result = HalGetEnvironmentVariable(AName.Buffer, Value, Length); if (!Result) { RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } ExFreePool(Value); return(STATUS_UNSUCCESSFUL); } /* - * Convert the result to ANSI. + * Convert the result to UNICODE. */ RtlInitAnsiString(&AValue, Value); Status = RtlAnsiStringToUnicodeString(&WValue, &AValue, TRUE); @@ -118,38 +104,39 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } ExFreePool(Value); return(Status); } - ReturnLength = WValue->Length; + ReturnLength = WValue.Length; /* * Copy the result back to the caller. */ if (ExGetPreviousMode() != KernelMode) { - Status = MmCopyToUser(UnsafeValue, WValue->Buffer, ReturnLength); + Status = MmCopyToCaller(UnsafeValue, WValue.Buffer, ReturnLength); if (!NT_SUCCESS(Status)) { RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } ExFreePool(Value); RtlFreeUnicodeString(&WValue); return(Status); } - Status = MmCopyToUser(UnsafeReturnLength, &ReturnLength, sizeof(ULONG)); + Status = MmCopyToCaller(UnsafeReturnLength, &ReturnLength, + sizeof(ULONG)); if (!NT_SUCCESS(Status)) { RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } ExFreePool(Value); RtlFreeUnicodeString(&WValue); @@ -158,7 +145,7 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, } else { - memcpy(UnsafeValue, WValue->Buffer, ReturnLength); + memcpy(UnsafeValue, WValue.Buffer, ReturnLength); memcpy(UnsafeReturnLength, &ReturnLength, sizeof(ULONG)); } @@ -168,7 +155,7 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, RtlFreeAnsiString(&AName); if (ExGetPreviousMode() != KernelMode) { - RtlFreeUnicodeString(&Name); + RtlFreeUnicodeString(&WName); } ExFreePool(Value); RtlFreeUnicodeString(&WValue); @@ -178,10 +165,98 @@ NtQuerySystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, NTSTATUS STDCALL -NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeVariableName, - IN PUNICODE_STRING Value) +NtSetSystemEnvironmentValue (IN PUNICODE_STRING UnsafeName, + IN PUNICODE_STRING UnsafeValue) { - UNIMPLEMENTED; + UNICODE_STRING WName; + ANSI_STRING AName; + UNICODE_STRING WValue; + ANSI_STRING AValue; + BOOLEAN Result; + NTSTATUS Status; + + /* + * Check for required privilege. + */ + /* FIXME: Not implemented. */ + + /* + * Copy the name to kernel space if necessary and convert it to ANSI. + */ + if (ExGetPreviousMode() != KernelMode) + { + Status = RtlCaptureUnicodeString(&WName, UnsafeName); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + else + { + Status = RtlUnicodeStringToAnsiString(&AName, UnsafeName, TRUE); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + } + + /* + * Copy the value to kernel space and convert to ANSI. + */ + if (ExGetPreviousMode() != KernelMode) + { + Status = RtlCaptureUnicodeString(&WValue, UnsafeValue); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&WName); + RtlFreeAnsiString(&AName); + return(Status); + } + Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&WName); + RtlFreeAnsiString(&AName); + RtlFreeUnicodeString(&WValue); + return(Status); + } + } + else + { + Status = RtlUnicodeStringToAnsiString(&AValue, UnsafeValue, TRUE); + if (!NT_SUCCESS(Status)) + { + RtlFreeAnsiString(&AName); + return(Status); + } + } + + /* + * Set the environment variable + */ + Result = HalSetEnvironmentVariable(AName.Buffer, AValue.Buffer); + + /* + * Free everything and return status. + */ + RtlFreeAnsiString(&AName); + RtlFreeAnsiString(&AValue); + if (ExGetPreviousMode() != KernelMode) + { + RtlFreeUnicodeString(&WName); + RtlFreeUnicodeString(&WValue); + } + + if (!Result) + { + return(STATUS_UNSUCCESSFUL); + } + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/include/internal/safe.h b/reactos/ntoskrnl/include/internal/safe.h index 4c8c41e94e2..35bbfe5468f 100644 --- a/reactos/ntoskrnl/include/internal/safe.h +++ b/reactos/ntoskrnl/include/internal/safe.h @@ -9,4 +9,8 @@ MmCopyFromCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes); NTSTATUS MmCopyToCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes); +NTSTATUS +RtlCaptureUnicodeString(PUNICODE_STRING Dest, + PUNICODE_STRING UnsafeSrc); + #endif /* __NTOSKRNL_INCLUDE_INTERNAL_SAFE_Hb */