From 326a3cd58bb03d1a1d7e11b66a9b34af050993fc Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sat, 5 Feb 2000 16:08:49 +0000 Subject: [PATCH] Added some string functions Added security descriptor functions Implemented environment functions Implemented current directory functions svn path=/trunk/; revision=980 --- reactos/include/ddk/rtl.h | 18 +- reactos/include/ntdll/rtl.h | 105 ++++- reactos/lib/ntdll/def/ntdll.def | 15 +- reactos/lib/ntdll/def/ntdll.edf | 15 +- reactos/lib/ntdll/ldr/startup.c | 5 +- reactos/lib/ntdll/makefile | 6 +- reactos/lib/ntdll/rtl/env.c | 328 +++++++++++++- reactos/lib/ntdll/rtl/path.c | 733 +++++++++++++++++++++++++++++++ reactos/lib/ntdll/rtl/process.c | 14 +- reactos/lib/ntdll/rtl/sd.c | 290 ++++++++++++ reactos/lib/ntdll/rtl/security.c | 28 -- reactos/lib/ntdll/rtl/unicode.c | 357 ++++++++++----- 12 files changed, 1750 insertions(+), 164 deletions(-) create mode 100644 reactos/lib/ntdll/rtl/path.c create mode 100644 reactos/lib/ntdll/rtl/sd.c delete mode 100644 reactos/lib/ntdll/rtl/security.c diff --git a/reactos/include/ddk/rtl.h b/reactos/include/ddk/rtl.h index 47685a2595e..e64b51b8864 100644 --- a/reactos/include/ddk/rtl.h +++ b/reactos/include/ddk/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.24 1999/12/29 01:36:58 ekohl Exp $ +/* $Id: rtl.h,v 1.25 2000/02/05 16:04:52 ekohl Exp $ * */ @@ -977,6 +977,14 @@ RtlUnicodeStringToOemSize ( IN PUNICODE_STRING UnicodeString ); +NTSTATUS +STDCALL +RtlUnicodeStringToCountedOemString ( + IN OUT POEM_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + NTSTATUS STDCALL RtlUnicodeStringToOemString ( @@ -1041,6 +1049,14 @@ RtlUpcaseUnicodeStringToAnsiString ( IN BOOLEAN AllocateDestinationString ); +NTSTATUS +STDCALL +RtlUpcaseUnicodeStringToCountedOemString ( + IN OUT POEM_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ); + NTSTATUS STDCALL RtlUpcaseUnicodeStringToOemString ( diff --git a/reactos/include/ntdll/rtl.h b/reactos/include/ntdll/rtl.h index 380fba923cd..fa96bdf7c9b 100644 --- a/reactos/include/ntdll/rtl.h +++ b/reactos/include/ntdll/rtl.h @@ -1,4 +1,4 @@ -/* $Id: rtl.h,v 1.7 2000/01/26 10:07:22 dwelch Exp $ +/* $Id: rtl.h,v 1.8 2000/02/05 16:06:09 ekohl Exp $ * */ @@ -27,6 +27,83 @@ RtlEraseUnicodeString ( IN PUNICODE_STRING String ); +/* Path functions */ + +ULONG +STDCALL +RtlDetermineDosPathNameType_U ( + PWSTR Path + ); + +BOOLEAN +STDCALL +RtlDoesFileExists_U ( + PWSTR FileName + ); + +BOOLEAN +STDCALL +RtlDosPathNameToNtPathName_U ( + PWSTR dosname, + PUNICODE_STRING ntname, + PWSTR *shortname, + PCURDIR nah + ); + +ULONG +STDCALL +RtlDosSearchPath_U ( + WCHAR *sp, + WCHAR *name, + WCHAR *ext, + ULONG buf_sz, + WCHAR *buffer, + WCHAR **shortname + ); + +ULONG +STDCALL +RtlGetCurrentDirectory_U ( + ULONG MaximumLength, + PWSTR Buffer + ); + +ULONG +STDCALL +RtlGetFullPathName_U ( + WCHAR *dosname, + ULONG size, + WCHAR *buf, + WCHAR **shortname + ); + +ULONG +STDCALL +RtlGetLongestNtPathLength ( + VOID + ); + +ULONG +STDCALL +RtlIsDosDeviceName_U ( + PWSTR DeviceName + ); + +BOOLEAN +STDCALL +RtlIsNameLegalDOS8Dot3 ( + PUNICODE_STRING us, + PANSI_STRING as, + PBOOLEAN pb + ); + +NTSTATUS +STDCALL +RtlSetCurrentDirectory_U ( + PUNICODE_STRING name + ); + +/* Environment functions */ VOID STDCALL RtlAcquirePebLock ( @@ -52,6 +129,23 @@ RtlDestroyEnvironment ( PVOID Environment ); +NTSTATUS +STDCALL +RtlExpandEnvironmentStrings_U ( + PVOID Environment, + PUNICODE_STRING Source, + PUNICODE_STRING Destination, + PULONG Length + ); + +NTSTATUS +STDCALL +RtlQueryEnvironmentVariable_U ( + PVOID Environment, + PUNICODE_STRING Name, + PUNICODE_STRING Value + ); + VOID STDCALL RtlSetCurrentEnvironment ( @@ -67,15 +161,6 @@ RtlSetEnvironmentVariable ( PUNICODE_STRING Value ); -NTSTATUS -STDCALL -RtlQueryEnvironmentVariable_U ( - PVOID Environment, - PUNICODE_STRING Name, - PUNICODE_STRING Value - ); - - NTSTATUS STDCALL RtlCreateUserThread ( diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index ae2b58d8f9a..49bd75a591a 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -1,4 +1,4 @@ -; $Id: ntdll.def,v 1.38 2000/01/27 08:56:48 dwelch Exp $ +; $Id: ntdll.def,v 1.39 2000/02/05 16:07:10 ekohl Exp $ ; ; ReactOS Operating System ; @@ -432,6 +432,7 @@ ZwWriteRequestData@24 ZwWriteVirtualMemory@20 ZwW32Call@20 ZwYieldExecution@0 +RtlAbsoluteToSelfRelativeSD@12 RtlAcquirePebLock@0 RtlAllocateHeap@12 RtlAnsiCharToUnicodeChar@4 @@ -445,6 +446,7 @@ RtlCharToInteger@12 RtlCreateEnvironment@8 RtlCreateHeap@24 RtlCreateProcessParameters@40 +RtlCreateSecurityDescriptor@8 RtlCreateUnicodeString@8 RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess@40 @@ -469,6 +471,7 @@ RtlEnlargedUnsignedMultiply@8 RtlEqualString@12 RtlEqualUnicodeString@12 RtlEraseUnicodeString@4 +RtlExpandEnvironmentStrings_U@16 RtlExtendedIntegerMultiply@12 RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide@20 @@ -477,6 +480,10 @@ RtlFreeAnsiString@4 RtlFreeHeap@12 RtlFreeOemString@4 RtlFreeUnicodeString@4 +RtlGetCurrentDirectory_U@8 +RtlGetDaclSecurityDescriptor@16 +RtlGetGroupSecurityDescriptor@12 +RtlGetOwnerSecurityDescriptor@12 RtlGetProcessHeap@0 RtlInitAnsiString@8 RtlInitializeContext@20 @@ -504,8 +511,12 @@ RtlOemToUnicodeN@20 RtlQueryEnvironmentVariable_U@12 RtlReAllocateHeap@16 RtlReleasePebLock@0 +RtlSetCurrentDirectory_U@4 RtlSetCurrentEnvironment@8 +RtlSetDaclSecurityDescriptor@16 RtlSetEnvironmentVariable@12 +RtlSetGroupSecurityDescriptor@12 +RtlSetOwnerSecurityDescriptor@12 RtlSizeHeap@12 RtlUnlockHeap@4 RtlUnicodeStringToAnsiSize@4 @@ -520,11 +531,13 @@ RtlUnwind@0 RtlUpcaseUnicodeChar@4 RtlUpcaseUnicodeString@12 RtlUpcaseUnicodeStringToAnsiString@12 +RtlUpcaseUnicodeStringToCountedOemString@12 RtlUpcaseUnicodeStringToOemString@12 RtlUpcaseUnicodeToMultiByteN@20 RtlUpcaseUnicodeToOemN@20 RtlUpperChar@4 RtlUpperString@8 +RtlValidSecurityDescriptor@4 RtlValidateHeap@12 RtlZeroMemory@8 RtlxAnsiStringToUnicodeSize@4 diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index 9334a6ce43b..cbf168a6be8 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.28 2000/01/27 08:56:48 dwelch Exp $ +; $Id: ntdll.edf,v 1.29 2000/02/05 16:07:10 ekohl Exp $ ; ; ReactOS Operating System ; @@ -431,6 +431,7 @@ ZwWriteRequestData=ZwWriteRequestData@24 ZwWriteVirtualMemory=ZwWriteVirtualMemory@20 ZwW32Call=ZwW32Call@20 ZwYieldExecution=ZwYieldExecution@0 +RtlAbsoluteToSelfRelativeSD=RtlAbsoluteToSelfRelativeSD@12 RtlAcquirePebLock=RtlAcquirePebLock@0 RtlAllocateHeap=RtlAllocateHeap@12 RtlAnsiCharToUnicodeChar=RtlAnsiCharToUnicodeChar@4 @@ -442,6 +443,7 @@ RtlCharToInteger=RtlCharToInteger@12 RtlCreateEnvironment=RtlCreateEnvironment@8 RtlCreateHeap=RtlCreateHeap@24 RtlCreateProcessParameters=RtlCreateProcessParameters@40 +RtlCreateSecurityDescriptor=RtlCreateSecurityDescriptor@8 RtlCreateUnicodeString=RtlCreateUnicodeString@8 RtlCreateUnicodeStringFromAsciiz=RtlCreateUnicodeStringFromAsciiz@8 RtlCreateUserProcess=RtlCreateUserProcess@40 @@ -464,6 +466,7 @@ RtlEnlargedUnsignedMultiply=RtlEnlargedUnsignedMultiply@8 RtlEqualString=RtlEqualString@12 RtlEqualUnicodeString=RtlEqualUnicodeString@12 RtlEraseUnicodeString=RtlEraseUnicodeString@4 +RtlExpandEnvironmentStrings_U=RtlExpandEnvironmentStrings_U@16 RtlExtendedIntegerMultiply=RtlExtendedIntegerMultiply@12 RtlExtendedLargeIntegerDivide=RtlExtendedLargeIntegerDivide@16 RtlExtendedMagicDivide=RtlExtendedMagicDivide@20 @@ -471,6 +474,10 @@ RtlFillMemory=RtlFillMemory@12 RtlFreeAnsiString=RtlFreeAnsiString@4 RtlFreeHeap=RtlFreeHeap@12 RtlFreeUnicodeString=RtlFreeUnicodeString@4 +RtlGetCurrentDirectory_U=RtlGetCurrentDirectory_U@8 +RtlGetDaclSecurityDescriptor=RtlGetDaclSecurityDescriptor@16 +RtlGetGroupSecurityDescriptor=RtlGetGroupSecurityDescriptor@12 +RtlGetOwnerSecurityDescriptor=RtlGetOwnerSecurityDescriptor@12 RtlGetProcessHeap=RtlGetProcessHeap@0 RtlInitAnsiString=RtlInitAnsiString@8 RtlInitializeContext=RtlInitializeContext@20 @@ -498,8 +505,12 @@ RtlOemToUnicodeN=RtlOemToUnicodeN@20 RtlQueryEnvironmentVariable_U=RtlQueryEnvironmentVariable_U@12 RtlReAllocateHeap=RtlReAllocateHeap@16 RtlReleasePebLock=RtlReleasePebLock@0 +RtlSetCurrentDirectory_U=RtlSetCurrentDirectory_U@4 RtlSetCurrentEnvironment=RtlSetCurrentEnvironment@8 +RtlSetDaclSecurityDescriptor=RtlSetDaclSecurityDescriptor@16 RtlSetEnvironmentVariable=RtlSetEnvironmentVariable@12 +RtlSetGroupSecurityDescriptor=RtlSetGroupSecurityDescriptor@12 +RtlSetOwnerSecurityDescriptor=RtlSetOwnerSecurityDescriptor@12 RtlSizeHeap=RtlSizeHeap@12 RtlUnlockHeap=RtlUnlockHeap@4 RtlUnicodeStringToAnsiSize=RtlUnicodeStringToAnsiSize@4 @@ -511,11 +522,13 @@ RtlUnwind=RtlUnwind@0 RtlUpcaseUnicodeChar=RtlUpcaseUnicodeChar@4 RtlUpcaseUnicodeString=RtlUpcaseUnicodeString@12 RtlUpcaseUnicodeStringToAnsiString=RtlUpcaseUnicodeStringToAnsiString@12 +RtlUpcaseUnicodeStringToCountedOemString=RtlUpcaseUnicodeStringToCountedOemString@12 RtlUpcaseUnicodeStringToOemString=RtlUpcaseUnicodeStringToOemString@12 RtlUpcaseUnicodeToMultiByteN=RtlUpcaseUnicodeToMultiByteN@20 RtlUpcaseUnicodeToOemN=RtlUpcaseUnicodeToOemN@20 RtlUpperChar=RtlUpperChar@4 RtlUpperString=RtlUpperString@8 +RtlValidSecurityDescriptor=RtlValidSecurityDescriptor@4 RtlValidateHeap=RtlValidateHeap@12 RtlZeroMemory=RtlZeroMemory@8 RtlxAnsiStringToUnicodeSize=RtlxAnsiStringToUnicodeSize@4 diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index a94c678c8b9..8f82f26e483 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.16 2000/01/27 08:56:48 dwelch Exp $ +/* $Id: startup.c,v 1.17 2000/02/05 16:07:44 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -77,6 +77,9 @@ VOID LdrStartup(PPEB Peb, STATUS_UNSUCCESSFUL); } + /* normalize process parameters */ + RtlNormalizeProcessParams (Peb->ProcessParameters); + NTHeaders = (PIMAGE_NT_HEADERS)(ImageBase + PEDosHeader->e_lfanew); __ProcessHeap = RtlCreateHeap(0, (PVOID)HEAP_BASE, diff --git a/reactos/lib/ntdll/makefile b/reactos/lib/ntdll/makefile index e0652bfe06a..c22bfe7fd1d 100644 --- a/reactos/lib/ntdll/makefile +++ b/reactos/lib/ntdll/makefile @@ -1,4 +1,4 @@ -# $Id: makefile,v 1.36 2000/01/23 08:16:20 phreak Exp $ +# $Id: makefile,v 1.37 2000/02/05 16:06:52 ekohl Exp $ # # ReactOS Operating System # @@ -29,8 +29,8 @@ CSR_OBJECTS = csr/api.o DBG_OBJECTS = dbg/brkpoint.o dbg/print.o RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \ - rtl/math.o rtl/mem.o rtl/nls.o rtl/process.o rtl/security.o \ - rtl/thread.o rtl/unicode.o rtl/env.o + rtl/math.o rtl/mem.o rtl/nls.o rtl/process.o rtl/sd.o \ + rtl/thread.o rtl/unicode.o rtl/env.o rtl/path.o STDIO_OBJECTS = stdio/sprintf.o stdio/swprintf.o diff --git a/reactos/lib/ntdll/rtl/env.c b/reactos/lib/ntdll/rtl/env.c index 9448bd7fe37..41d1448e494 100644 --- a/reactos/lib/ntdll/rtl/env.c +++ b/reactos/lib/ntdll/rtl/env.c @@ -1,4 +1,4 @@ -/* $Id: env.c,v 1.4 2000/01/11 17:28:57 ekohl Exp $ +/* $Id: env.c,v 1.5 2000/02/05 16:08:49 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -107,6 +107,84 @@ RtlDestroyEnvironment ( } +NTSTATUS +STDCALL +RtlExpandEnvironmentStrings_U ( + PVOID Environment, + PUNICODE_STRING src, + PUNICODE_STRING dst, + PULONG Length + ) +{ + UNICODE_STRING var,val; + int src_len, dst_max, tail; + WCHAR *s,*d,*w; + BOOLEAN flag = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + + src_len = src->Length / 2; + s = src->Buffer; + dst_max = dst->MaximumLength / 2; + d = dst->Buffer; + + while( src_len ) + { + if( *s == L'%' ) + { + if( flag ) + { + flag = FALSE; + goto copy; + } + w = s + 1; tail = src_len - 1; + while( *w != L'%' && tail ) + { + w++; + tail--; + } + if( !tail ) + goto copy; + + var.Length = ( w - ( s + 1 ) ) * 2; + var.MaximumLength = var.Length; + var.Buffer = s + 1; + + val.Length = 0; + val.MaximumLength = dst_max * 2; + val.Buffer = d; + Status = RtlQueryEnvironmentVariable_U (Environment, &var, &val ); + if( Status >= 0 ) + { + d += val.Length / 2; + dst_max -= val.Length / 2; + s = w + 1; + src_len = tail - 1; + continue; + } + /* variable not found or buffer too small, just copy %var% */ + flag = TRUE; + } +copy:; + if( !dst_max ) + { + Status = STATUS_BUFFER_TOO_SMALL; + break; + } + + *d++ = *s++; + dst_max--; + src_len--; + } + dst->Length = ( d - dst->Buffer ) * 2; + if (Length) + *Length = dst->Length; + if( dst_max ) + dst->Buffer[ dst->Length / 2 ] = 0; + + return Status; +} + + VOID STDCALL RtlSetCurrentEnvironment ( @@ -130,7 +208,7 @@ RtlSetCurrentEnvironment ( RtlReleasePebLock (); } - +#if 0 NTSTATUS STDCALL RtlSetEnvironmentVariable ( @@ -140,30 +218,262 @@ RtlSetEnvironmentVariable ( ) { NTSTATUS Status; + PWSTR EnvPtr; + PWSTR EndPtr; + ULONG EnvLength; Status = STATUS_VARIABLE_NOT_FOUND; - /* FIXME: add missing stuff */ + if (Environment != NULL) + { + EnvPtr = *Environment + } + else + { + RtlAcquirePebLock (); + EnvPtr = NtCurrentPeb()->ProcessParameters->Environment; + } + if (EnvPtr != NULL) + { + /* get environment length */ + EndPtr = EnvPtr; + while (*EndPtr) + { + while (*EndPtr++) + ; + EndPtr++; + } + EnvLen = EndPtr - EnvPtr; + + /* FIXME: add missing stuff */ + + } + + if (EnvPtr != *Environment) + RtlReleasePebLock (); return Status; } +#endif + + +NTSTATUS +WINAPI +RtlSetEnvironmentVariable ( + PVOID *Environment, + UNICODE_STRING *varname, + UNICODE_STRING *value) +{ + UNICODE_STRING var; + MEMORY_BASIC_INFORMATION mbi; + int hole_len, new_len, env_len = 0; + WCHAR *new_env = 0, *env_end = 0, *wcs, *env, *val = 0, *tail = 0, *hole = 0; + ULONG size = 0, new_size; + LONG f = 1; + NTSTATUS Status = STATUS_SUCCESS; + + if (Environment) + { + env = *Environment; + } + else + { + RtlAcquirePebLock(); + env = NtCurrentPeb()->ProcessParameters->Environment; + } + + if( env ) + { + /* get environment length */ + wcs = env_end = env; + while( *env_end ) while( *env_end++ ); env_end++; + env_len = env_end - env; + + /* find where to insert */ + while( *wcs ) + { + for (var.Buffer = wcs++; *wcs && *wcs != L'='; wcs++); + if( *wcs ) + { + var.Length = ( wcs - var.Buffer ) * 2; + var.MaximumLength = var.Length; + for ( val = ++wcs; *wcs; wcs++); + f = RtlCompareUnicodeString( &var, varname, TRUE ); + if( f >= 0 ) + { + if( f ) /* Insert before found */ + { + hole = tail = var.Buffer; + } + else /* Exact match */ + { + tail = ++wcs; + hole = val; + } + goto found; + } + } + wcs++; + } + hole = tail = wcs; /* Append to environment */ + } + +found:; + if( value ) + { + hole_len = tail - hole; + /* calculate new environment size */ + new_size = value->Length + 2; + if( f ) + new_size += varname->Length + 2; /* adding new variable */ + new_len = new_size / 2; + if (hole_len < new_len) + { + /* we must enlarge environment size, let's check the size of available + * memory */ + new_size += ( env_len - hole_len ) * 2; + mbi.RegionSize = 0; + + if (env) + { + Status = NtQueryVirtualMemory( (HANDLE)-1, env, 0, &mbi, sizeof(mbi), NULL ); + if (!NT_SUCCESS(Status)) + { + RtlReleasePebLock (); + return Status; + } + } + + if (new_size > mbi.RegionSize) + { + /* reallocate memory area */ + Status = NtAllocateVirtualMemory( (HANDLE)-1, (VOID**)&new_env, 0, &new_size, MEM_COMMIT, PAGE_READWRITE ); + if (!NT_SUCCESS(Status)) + { + RtlReleasePebLock (); + return Status; + } + + if (env) + { + memmove( new_env, env, ( hole - env ) * 2 ); + hole = new_env + ( hole - env ); + } + else + { + /* absolutely new environment */ + tail = hole = new_env; + *hole = 0; + env_end = hole + 1; + } + } + } + + /* move tail */ + memmove ( hole + new_len, tail, ( env_end - tail ) * 2 ); + if( new_env ) + { + /* we reallocated environment, let's free the old one */ + if (Environment) + *Environment = new_env; + else + NtCurrentPeb()->ProcessParameters->Environment = new_env; + + if (env) + { + NtFreeVirtualMemory (NtCurrentProcess(), + (VOID**)&env, + &size, + MEM_RELEASE); + } + } + + /* and now copy given stuff */ + if( f ) + { + /* copy variable name and '=' sign */ + memmove (hole, varname->Buffer, varname->Length); + hole += varname->Length / 2; *hole++ = L'='; + } + + /* copy value */ + memmove( hole, value->Buffer, value->Length ); + hole += value->Length / 2; *hole = 0; + } + else + { + if (!f) + memmove (hole, tail, ( env_end - tail ) * 2 ); /* remove it */ + else + Status = STATUS_VARIABLE_NOT_FOUND; /* notingh to remove*/ + } + + RtlReleasePebLock (); + return Status; +} +//#endif NTSTATUS STDCALL RtlQueryEnvironmentVariable_U ( - PVOID Environment, - PUNICODE_STRING Name, - PUNICODE_STRING Value + PVOID env, + UNICODE_STRING *varname, + UNICODE_STRING *value ) { - NTSTATUS Status; + NTSTATUS Status = STATUS_VARIABLE_NOT_FOUND; + WCHAR *wcs,*var,*val; + int varlen, len; - Status = STATUS_VARIABLE_NOT_FOUND; + if (!env) + env = NtCurrentPeb()->ProcessParameters->Environment; - /* FIXME: add missing stuff */ + if (!env) + return Status; + value->Length = 0; + if (env == NtCurrentPeb()->ProcessParameters->Environment) + RtlAcquirePebLock(); + + wcs = env; + len = varname->Length / 2; + while( *wcs ) + { + for (var = wcs++; *wcs && *wcs != L'='; wcs++) + ; + + if (*wcs) + { + varlen = wcs - var; + for (val = ++wcs; *wcs; wcs++) + ; + if (varlen == len && + !_wcsnicmp (var, varname->Buffer, len)) + { + value->Length = (wcs - val) * sizeof(WCHAR); + if (value->Length < value->MaximumLength) + { + wcscpy (value->Buffer, val); + Status = STATUS_SUCCESS; + } + else + { + Status = STATUS_BUFFER_TOO_SMALL; + } + + if (env == NtCurrentPeb()->ProcessParameters->Environment) + RtlReleasePebLock (); + + return Status; + } + } + wcs++; + } + + if (env == NtCurrentPeb()->ProcessParameters->Environment) + RtlReleasePebLock (); return Status; } diff --git a/reactos/lib/ntdll/rtl/path.c b/reactos/lib/ntdll/rtl/path.c new file mode 100644 index 00000000000..81c783ff387 --- /dev/null +++ b/reactos/lib/ntdll/rtl/path.c @@ -0,0 +1,733 @@ +/* $Id: path.c,v 1.1 2000/02/05 16:08:49 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/ntdll/rtl/path.c + * PURPOSE: Path and current directory functions + * UPDATE HISTORY: + * Created 03/02/00 + */ + +/* INCLUDES ******************************************************************/ + +#include +#include +#include +#include +#include + +#define NDEBUG +#include + + +/* DEFINITONS and MACROS ******************************************************/ + +#define MAX_PFX_SIZE 16 + +#define IS_PATH_SEPARATOR(x) (((x)==L'\\')||((x)==L'/')) + + +/* FUNCTIONS *****************************************************************/ + +ULONG +STDCALL +RtlGetLongestNtPathLength (VOID) +{ + return (MAX_PATH + 9); +} + + +ULONG +STDCALL +RtlDetermineDosPathNameType_U ( + PWSTR Path + ) +{ + DPRINT ("RtlDetermineDosPathNameType_U %S\n", Path); + + if (Path == NULL) + return 0; + + if (IS_PATH_SEPARATOR(Path[0])) + { + if (!IS_PATH_SEPARATOR(Path[1])) + return 4; /* \xxx */ + + if (Path[2] != L'.') + return 1; /* \\xxx */ + + if (IS_PATH_SEPARATOR(Path[3])) + return 6; /* \\.\xxx */ + + if (Path[3]) + return 1; /* \\.xxxx */ + + return 7; /* \\. */ + } + else + { + if (Path[1] != L':') + return 5; /* xxx */ + + if (IS_PATH_SEPARATOR(Path[2])) + return 2; /* x:\xxx */ + + return 3; /* x:xxx */ + } +} + + +/* returns 0 if name is not valid DOS device name, or DWORD with + * offset in bytes to DOS device name from beginning of buffer in high word + * and size in bytes of DOS device name in low word */ +ULONG +STDCALL +RtlIsDosDeviceName_U ( + PWSTR DeviceName + ) +{ + ULONG Type; + ULONG Length = 0; + ULONG Offset; + PWCHAR wc; + + if (DeviceName == NULL) + return 0; + + while (DeviceName[Length]) + Length++; + + Type = RtlDetermineDosPathNameType_U (DeviceName); + if (Type <= 1) + return 0; + if (Type == 6) + { + if (Length == 7 && + !_wcsnicmp (DeviceName, L"\\\\.\\CON", 7)) + return 0x00080006; + return 0; + } + + /* name can end with ':' */ + if (Length && DeviceName[Length - 1 ] == L':') + Length--; + + /* there can be spaces or points at the end of name */ + wc = DeviceName + Length - 1; + while (Length && (*wc == L'.' || *wc == L' ')) + { + Length--; + wc--; + } + + /* let's find a beginning of name */ + wc = DeviceName + Length - 1; + while (wc > DeviceName && !IS_PATH_SEPARATOR(*(wc - 1))) + wc--; + Offset = wc - DeviceName; + Length -= Offset; + + /* check for LPTx or COMx */ + if (Length == 4 && wc[3] >= L'0' && wc[3] <= L'9') + { + if (wc[3] == L'0') + return 0; + if (!_wcsnicmp (wc, L"LPT", 3) || + !_wcsnicmp (wc, L"COM", 3)) + { + return ((Offset * 2) << 16 ) | 8; + } + return 0; + } + + /* check for PRN,AUX,NUL or CON */ + if (Length == 3 && + (!_wcsnicmp (wc, L"PRN", 3) || + !_wcsnicmp (wc, L"AUX", 3) || + !_wcsnicmp (wc, L"NUL", 3) || + !_wcsnicmp (wc, L"CON", 3))) + { + return ((Offset * 2) << 16) | 6; + } + + return 0; +} + + +ULONG +STDCALL +RtlGetCurrentDirectory_U ( + ULONG MaximumLength, + PWSTR Buffer + ) +{ + DWORD Length; + PCURDIR cd; + + DPRINT ("RtlGetCurrentDirectory %lu %p\n", MaximumLength, Buffer); + + cd = &(NtCurrentPeb ()->ProcessParameters->CurrentDirectory); + + RtlAcquirePebLock(); + Length = cd->DosPath.Length / sizeof(WCHAR); + if (cd->DosPath.Buffer[Length - 2] != L':') + Length--; + + DPRINT ("cd->DosPath.Buffer %S\n", cd->DosPath.Buffer); + + if (MaximumLength / sizeof(WCHAR) > Length) + { + memcpy (Buffer, + cd->DosPath.Buffer, + Length * sizeof(WCHAR)); + Buffer[Length] = 0; + } + else + { + Length++; + } + + RtlReleasePebLock (); + + DPRINT ("CurrentDirectory %S\n", Buffer); + + return (Length * sizeof(WCHAR)); +} + + +NTSTATUS +STDCALL +RtlSetCurrentDirectory_U ( + PUNICODE_STRING name + ) +{ + UNICODE_STRING full; + OBJECT_ATTRIBUTES obj; + IO_STATUS_BLOCK iosb; + PCURDIR cd; + NTSTATUS Status; + ULONG size; + HANDLE handle = NULL; + WCHAR *wcs,*buf = 0; + + DPRINT ("RtlSetCurrentDirectory %wZ\n", name); + + RtlAcquirePebLock (); + cd = &(NtCurrentPeb ()->ProcessParameters->CurrentDirectory); + size = cd->DosPath.MaximumLength; + + buf = RtlAllocateHeap (RtlGetProcessHeap(), + 0, + size); + if (buf == NULL) + { + RtlReleasePebLock (); + return STATUS_NO_MEMORY; + } + + size = RtlGetFullPathName_U (name->Buffer, size, buf, 0); + if (!size) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + buf); + RtlReleasePebLock (); + return STATUS_OBJECT_NAME_INVALID; + } + + if (!RtlDosPathNameToNtPathName_U (buf, &full, 0, 0)) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + buf); + RtlFreeHeap (RtlGetProcessHeap (), + 0, + full.Buffer); + RtlReleasePebLock (); + return STATUS_OBJECT_NAME_INVALID; + } + + obj.Length = sizeof(obj); + obj.RootDirectory = 0; + obj.ObjectName = &full; + obj.Attributes = OBJ_CASE_INSENSITIVE | OBJ_INHERIT; + obj.SecurityDescriptor = 0; + obj.SecurityQualityOfService = 0; + + Status = NtOpenFile (&handle, + SYNCHRONIZE | FILE_TRAVERSE, + &obj, + &iosb, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + buf); + RtlFreeHeap (RtlGetProcessHeap (), + 0, + full.Buffer); + RtlReleasePebLock (); + return Status; + } + + /* append backslash if missing */ + wcs = buf + size / sizeof(WCHAR) - 1; + if (*wcs != L'\\') + { + *(++wcs) = L'\\'; + *(++wcs) = 0; + size += sizeof(WCHAR); + } + + memmove (cd->DosPath.Buffer, + buf, + size + sizeof(WCHAR)); + cd->DosPath.Length = size; + + if (cd->Handle) + NtClose (cd->Handle); + cd->Handle = handle; + + RtlFreeHeap (RtlGetProcessHeap (), + 0, + buf); + + RtlFreeHeap (RtlGetProcessHeap (), + 0, + full.Buffer); + + RtlReleasePebLock(); + + return STATUS_SUCCESS; +} + + +ULONG +STDCALL +RtlGetFullPathName_U ( + WCHAR *dosname, + ULONG size, + WCHAR *buf, + WCHAR **shortname + ) +{ + WCHAR *wcs, var[4], drive; + int len; + DWORD offs, sz, type; + UNICODE_STRING usvar, pfx; + PCURDIR cd; + NTSTATUS status; + + DPRINT("RtlGetFullPathName_U %S %ld %p %p\n", + dosname, size, buf, shortname); + + if (!dosname || !*dosname) + return 0; + + len = wcslen (dosname); + + /* strip trailing spaces */ + while (len && dosname[len - 1] == L' ') + len--; + if (!len) + return 0; + + /* strip trailing path separator */ + if (IS_PATH_SEPARATOR(dosname[len - 1])) + len--; + if (!len) + return 0; + if (shortname) + *shortname = 0; + memset (buf, 0, size); + +CHECKPOINT; + /* check for DOS device name */ + sz = RtlIsDosDeviceName_U (dosname); + if (sz) + { + offs = sz >> 17; + sz &= 0x0000FFFF; + if (sz + 8 >= size) + return sz + 10; + wcscpy (buf, L"\\\\.\\"); + wcsncat (buf, dosname + offs, sz / 2); + return sz + 8; + } + +CHECKPOINT; + type = RtlDetermineDosPathNameType_U (dosname); + + RtlAcquirePebLock(); + + cd = &(NtCurrentPeb ()->ProcessParameters->CurrentDirectory); +DPRINT("type %ld\n", type); + switch (type) + { + case 1: /* \\xxx or \\.xxx */ + case 2: /* x:\xxx */ + case 6: /* \\.\xxx */ + break; + + case 3: /* x:xxx */ + drive = towupper (*dosname); + dosname += 2; + len -= 2; +CHECKPOINT; + if (drive == towupper (cd->DosPath.Buffer[0])) + { +CHECKPOINT; + wcscpy (buf, cd->DosPath.Buffer); + } + else + { +CHECKPOINT; + usvar.Length = 2 * swprintf( var, L"=%c:", drive ); + usvar.MaximumLength = 8; + usvar.Buffer = var; + pfx.Length = 0; + pfx.MaximumLength = size; + pfx.Buffer = buf; + status = RtlQueryEnvironmentVariable_U( 0, &usvar, &pfx ); +CHECKPOINT; + if (!NT_SUCCESS(status)) + { +CHECKPOINT; + if (status == STATUS_BUFFER_TOO_SMALL) + return pfx.Length + len * 2 + 2; + swprintf( buf, L"%c:\\", drive ); + } + else + { +CHECKPOINT; + if( pfx.Length > 6 ) + { +CHECKPOINT; + buf[ pfx.Length / 2 ] = L'\\'; + pfx.Length += 2; + } + } + } + break; + + case 4: /* \xxx */ + wcsncpy (buf, cd->DosPath.Buffer, 2); + break; + + case 5: /* xxx */ + wcscpy (buf, cd->DosPath.Buffer); + if (*dosname == L'.') + { + dosname += 2; + len -= 2; + } + break; + + case 7: /* \\. */ + wcscpy (buf, L"\\\\.\\"); + len = 0; + break; + + default: + return 0; + } + +CHECKPOINT; + /* add dosname to prefix */ + wcsncat (buf, dosname, len); + +CHECKPOINT; + /* replace slashes */ + for (wcs = buf; *wcs; wcs++ ) + if (*wcs == L'/') + *wcs = L'\\'; + + len = wcslen (buf); + + /* find shortname */ + if (shortname) + { + for (wcs = buf + len - 1; wcs >= buf; wcs--) + { + if (*wcs == L'\\') + { + *shortname = wcs + 1; + break; + } + } + } + + RtlReleasePebLock(); + + return len * sizeof(WCHAR); +} + + +BOOLEAN +STDCALL +RtlDosPathNameToNtPathName_U ( + PWSTR dosname, + PUNICODE_STRING ntname, + PWSTR *shortname, + PCURDIR nah + ) +{ + UNICODE_STRING us; + PCURDIR cd; + DWORD type, size; + WCHAR *buf = 0, fullname[517]; + int offs, len; + + RtlAcquirePebLock(); + + RtlInitUnicodeString( &us, dosname ); + if( us.Length > 8 ) + { + buf = us.Buffer; + /* check for "\\?\" - allows to use very long filenames ( up to 32k ) */ + if (buf[0] == L'\\' && buf[1] == L'\\' && buf[2] == L'?' && buf[3] == L'\\') + { +// if( f_77F68606( &us, ntname, shortname, nah ) ) +// goto out; + buf = 0; + goto fail; + } + } + + buf = RtlAllocateHeap (RtlGetProcessHeap (), + 0, + sizeof( fullname ) + MAX_PFX_SIZE ); + if (!buf) + goto fail; + + size = RtlGetFullPathName_U( dosname, sizeof( fullname ), fullname, shortname ); + if( !size || size > 0x208 ) + goto fail; + + /* Set NT prefix */ + offs = 0; + wcscpy (buf, L"\\??\\"); + + type = RtlDetermineDosPathNameType_U( fullname ); + switch (type) + { + case 1: + wcscat( buf, L"UNC\\" ); + offs = 2; + break; /* \\xxx */ + + case 6: + offs = 4; + break; /* \\.\xxx */ + } + wcscat( buf, fullname + offs ); + len = wcslen( buf ); + + /* Set NT filename */ + ntname->Length = len * 2; + ntname->MaximumLength = sizeof( fullname ) + MAX_PFX_SIZE; + ntname->Buffer = buf; + + /* Set shortname if possible */ + if( shortname && *shortname ) + *shortname = buf + len - wcslen( *shortname ); + + /* Set name and handle structure if possible */ + if( nah ) + { + memset( nah, 0, sizeof(CURDIR)); + cd = &(NtCurrentPeb ()->ProcessParameters->CurrentDirectory); + if (type == 5 && cd->Handle && + !_wcsnicmp (cd->DosPath.Buffer, fullname, cd->DosPath.Length / 2)) + { + len = (( cd->DosPath.Length / 2 ) - offs ) + ( ( type == 1 ) ? 8 : 4 ); + nah->DosPath.Buffer = buf + len; + nah->DosPath.Length = ntname->Length - ( len * 2 ); + nah->DosPath.MaximumLength = nah->DosPath.Length; + nah->Handle = cd->Handle; + } + } +/* out:; */ + RtlReleasePebLock(); + return TRUE; + +fail:; + if( buf ) + RtlFreeHeap (RtlGetProcessHeap (), 0, buf ); + RtlReleasePebLock(); + return FALSE; +} + + +ULONG +STDCALL +RtlDosSearchPath_U ( + WCHAR *sp, + WCHAR *name, + WCHAR *ext, + ULONG buf_sz, + WCHAR *buffer, + WCHAR **shortname + ) +{ + DWORD type; + ULONG len = 0; + WCHAR *full_name,*wcs,*path; + + type = RtlDetermineDosPathNameType_U( name ); + + if( type != 5 ) + { + if( RtlDoesFileExists_U( name ) ) + { + len = RtlGetFullPathName_U( name, buf_sz, buffer, shortname ); + } + } + else + { + len = wcslen( sp ); + len += wcslen( name ); + if( wcschr( name, L'.' ) ) ext = 0; + if( ext ) len += wcslen( ext ); + + full_name = (WCHAR*)RtlAllocateHeap (RtlGetProcessHeap (), 0, ( len + 1 ) * 2 ); + len = 0; + if( full_name ) + { + path = sp; + while( *path ) + { + wcs = full_name; + while( *path && *path != L';' ) *wcs++ = *path++; + if( *path ) path++; + if( wcs != full_name && *(wcs - 1) != L'\\' ) *wcs++ = L'\\'; + wcscpy( wcs, name ); + if( ext ) wcscat( wcs, ext ); + if( RtlDoesFileExists_U( full_name ) ) + { + len = RtlGetFullPathName_U( full_name, buf_sz, buffer, shortname ); + break; + } + } + RtlFreeHeap (RtlGetProcessHeap (), 0, full_name ); + } + } + return len; +} + + +BOOLEAN +STDCALL +RtlIsNameLegalDOS8Dot3 ( + PUNICODE_STRING us, + PANSI_STRING as, + PBOOLEAN pb + ) +{ + ANSI_STRING *name = as,as1; + char buf[12],*str; + NTSTATUS Status; + BOOLEAN have_space = FALSE; + BOOLEAN have_point = FALSE; + ULONG len,i; + + if (us->Length > 24) + return FALSE; /* name too long */ + + if (!name) + { + name = &as1; + name->Length = 0; + name->MaximumLength = 12; + name->Buffer = buf; + } + + Status = RtlUpcaseUnicodeStringToCountedOemString (name, + us, + FALSE); + if (!NT_SUCCESS(Status)) + return FALSE; + + len = name->Length; + str = name->Buffer; + + if (!(len == 1 && *str == '.') && + !(len == 2 && *(short*)(str) == 0x2E2E)) + { + for (i = 0; i < len; i++, str++) + { + switch (*str) + { + case ' ': + have_space = TRUE; + break; + + case '.': + if ((have_point) || /* two points */ + (!i) || /* point is first char */ + (i + 1 == len) || /* point is last char */ + (len - i > 4)) /* more than 3 chars of extension */ + return FALSE; + have_point = TRUE; + break; + } + } + } + + if (pb) + *pb = have_space; + + return TRUE; +} + + +BOOLEAN +STDCALL +RtlDoesFileExists_U ( + PWSTR FileName + ) +{ + UNICODE_STRING NtFileName; + OBJECT_ATTRIBUTES obj; + NTSTATUS Status; + CURDIR CurDir; + PWSTR Buffer; + + if (!RtlDosPathNameToNtPathName_U (FileName, + &NtFileName, + NULL, + &CurDir)) + return FALSE; + + /* don't forget to free it! */ + Buffer = NtFileName.Buffer; + + if (CurDir.DosPath.Length) + NtFileName = CurDir.DosPath; + else + CurDir.Handle = 0; + + obj.Length = sizeof(obj); + obj.RootDirectory = CurDir.Handle; + obj.ObjectName = &NtFileName; + obj.Attributes = OBJ_CASE_INSENSITIVE; + obj.SecurityDescriptor = 0; + obj.SecurityQualityOfService = 0; + + Status = NtQueryAttributesFile (&obj, NULL); + + RtlFreeHeap (RtlGetProcessHeap(), + 0, + Buffer); + + if (NT_SUCCESS(Status) || + Status == STATUS_SHARING_VIOLATION || + Status == STATUS_ACCESS_DENIED) + return TRUE; + + return FALSE; +} + +/* EOF */ diff --git a/reactos/lib/ntdll/rtl/process.c b/reactos/lib/ntdll/rtl/process.c index a9b53cb87f4..355097c05dd 100644 --- a/reactos/lib/ntdll/rtl/process.c +++ b/reactos/lib/ntdll/rtl/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.10 2000/01/27 08:56:48 dwelch Exp $ +/* $Id: process.c,v 1.11 2000/02/05 16:08:49 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -258,7 +258,7 @@ RtlpCreatePpbAndPeb ( Ppb, Ppb->TotalSize, &BytesWritten); - + /* create the PEB */ PebBase = (PVOID)PEB_BASE; PebSize = 0x1000; @@ -495,15 +495,13 @@ RtlCreateProcessParameters ( /* copy current directory */ Dest = (PWCHAR)(((PBYTE)Param) + - sizeof(RTL_USER_PROCESS_PARAMETERS) + - (256 * sizeof(WCHAR))); + sizeof(RTL_USER_PROCESS_PARAMETERS)); Param->CurrentDirectory.DosPath.Buffer = Dest; + Param->CurrentDirectory.DosPath.MaximumLength = MAX_PATH * sizeof(WCHAR); if (CurrentDirectory != NULL) { Param->CurrentDirectory.DosPath.Length = CurrentDirectory->Length; - Param->CurrentDirectory.DosPath.MaximumLength = - CurrentDirectory->Length + sizeof(WCHAR); memcpy(Dest, CurrentDirectory->Buffer, CurrentDirectory->Length); @@ -512,8 +510,8 @@ RtlCreateProcessParameters ( *Dest = 0; Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS) + - (256 * sizeof(WCHAR)) + (MAX_PATH * sizeof(WCHAR))); - + /* (256 * sizeof(WCHAR)) + */ (MAX_PATH * sizeof(WCHAR))); + /* copy library path */ Param->LibraryPath.Buffer = Dest; if (LibraryPath != NULL) diff --git a/reactos/lib/ntdll/rtl/sd.c b/reactos/lib/ntdll/rtl/sd.c new file mode 100644 index 00000000000..a26b7e5b123 --- /dev/null +++ b/reactos/lib/ntdll/rtl/sd.c @@ -0,0 +1,290 @@ +/* $Id: sd.c,v 1.1 2000/02/05 16:08:49 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Security descriptor functions + * FILE: lib/ntdll/rtl/sd.c + * PROGRAMER: David Welch + * REVISION HISTORY: + * 26/07/98: Added stubs for security functions + */ + +/* INCLUDES *****************************************************************/ + +#include + +#include + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS STDCALL RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + ULONG Revision) +{ + if (Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + SecurityDescriptor->Revision = 1; + SecurityDescriptor->Sbz1 = 0; + SecurityDescriptor->Control = 0; + SecurityDescriptor->Owner = NULL; + SecurityDescriptor->Group = NULL; + SecurityDescriptor->Sacl = NULL; + SecurityDescriptor->Dacl = NULL; + return(STATUS_SUCCESS); +} + +ULONG STDCALL RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + PSID Owner; + PSID Group; + ULONG Length; + PACL Dacl; + PACL Sacl; + + Length = sizeof(SECURITY_DESCRIPTOR); + + if (SecurityDescriptor->Owner != NULL) + { + Owner = SecurityDescriptor->Owner; + if (SecurityDescriptor->Control & 0x80) + { + Owner = (PSID)((ULONG)Owner + + (ULONG)SecurityDescriptor); + } + Length = Length + ((sizeof(SID) + (Owner->SubAuthorityCount - 1) * + sizeof(ULONG) + 3) & 0xfc); + } + if (SecurityDescriptor->Group != NULL) + { + Group = SecurityDescriptor->Group; + if (SecurityDescriptor->Control & 0x8000) + { + Group = (PSID)((ULONG)Group + (ULONG)SecurityDescriptor); + } + Length = Length + ((sizeof(SID) + (Group->SubAuthorityCount - 1) * + sizeof(ULONG) + 3) & 0xfc); + } + if (SecurityDescriptor->Control & 0x4 && + SecurityDescriptor->Dacl != NULL) + { + Dacl = SecurityDescriptor->Dacl; + if (SecurityDescriptor->Control & 0x8000) + { + Dacl = (PACL)((ULONG)Dacl + (PVOID)SecurityDescriptor); + } + Length = Length + ((Dacl->AclSize + 3) & 0xfc); + } + if (SecurityDescriptor->Control & 0x10 && + SecurityDescriptor->Sacl != NULL) + { + Sacl = SecurityDescriptor->Sacl; + if (SecurityDescriptor->Control & 0x8000) + { + Sacl = (PACL)((ULONG)Sacl + (PVOID)SecurityDescriptor); + } + Length = Length + ((Sacl->AclSize + 3) & 0xfc); + } + return(Length); +} + +NTSTATUS STDCALL RtlGetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + PBOOLEAN DaclPresent, + PACL* Dacl, + PBOOLEAN DaclDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (!(SecurityDescriptor->Control & 0x4)) + { + *DaclPresent = 0; + return(STATUS_SUCCESS); + } + *DaclPresent = 1; + if (SecurityDescriptor->Dacl == NULL) + { + *Dacl = NULL; + } + else + { + if (SecurityDescriptor->Control & 0x8000) + { + *Dacl = (PACL)((ULONG)SecurityDescriptor->Dacl + + (PVOID)SecurityDescriptor); + } + else + { + *Dacl = SecurityDescriptor->Dacl; + } + } + if (SecurityDescriptor->Control & 0x8) + { + *DaclDefaulted = 1; + } + else + { + *DaclDefaulted = 0; + } + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL RtlSetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + BOOLEAN DaclPresent, + PACL Dacl, + BOOLEAN DaclDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Control & 0x8000) + { + return(STATUS_UNSUCCESSFUL); + } + if (!DaclPresent) + { + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(0x4); + return(STATUS_SUCCESS); + } + SecurityDescriptor->Control = SecurityDescriptor->Control | 0x4; + SecurityDescriptor->Dacl = Dacl; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(0x8); + if (DaclDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | 0x80; + } + return(STATUS_SUCCESS); +} + +BOOLEAN STDCALL RtlValidSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + UNIMPLEMENTED; +} + +NTSTATUS STDCALL RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID Owner, + BOOLEAN OwnerDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Control & 0x8000) + { + return(STATUS_UNSUCCESSFUL); + } + SecurityDescriptor->Owner = Owner; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(0x1); + if (OwnerDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | 0x1; + } + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL RtlGetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID* Owner, + PBOOLEAN OwnerDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Owner != NULL) + { + if (SecurityDescriptor->Control & 0x8000) + { + *Owner = (PSID)((ULONG)SecurityDescriptor->Owner + + (PVOID)SecurityDescriptor); + } + else + { + *Owner = SecurityDescriptor->Owner; + } + } + else + { + *Owner = NULL; + } + if (SecurityDescriptor->Control & 0x1) + { + *OwnerDefaulted = 1; + } + else + { + *OwnerDefaulted = 0; + } + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID Group, + BOOLEAN GroupDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Control & 0x8000) + { + return(STATUS_UNSUCCESSFUL); + } + SecurityDescriptor->Group = Group; + SecurityDescriptor->Control = SecurityDescriptor->Control & ~(0x2); + if (GroupDefaulted) + { + SecurityDescriptor->Control = SecurityDescriptor->Control | 0x2; + } + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL RtlGetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR SecurityDescriptor, + PSID* Group, + PBOOLEAN GroupDefaulted) +{ + if (SecurityDescriptor->Revision != 1) + { + return(STATUS_UNSUCCESSFUL); + } + if (SecurityDescriptor->Group != NULL) + { + if (SecurityDescriptor->Control & 0x8000) + { + *Group = (PSID)((ULONG)SecurityDescriptor->Group + + (PVOID)SecurityDescriptor); + } + else + { + *Group = SecurityDescriptor->Group; + } + } + else + { + *Group = NULL; + } + if (SecurityDescriptor->Control & 0x2) + { + *GroupDefaulted = 1; + } + else + { + *GroupDefaulted = 0; + } + return(STATUS_SUCCESS); +} + +NTSTATUS STDCALL RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR AbsSD, + PSECURITY_DESCRIPTOR RelSD, + PULONG BufferLength) +{ + if (AbsSD->Control & 0x8000) + { + return(STATUS_UNSUCCESSFUL); + } + UNIMPLEMENTED; +} + + +/* EOF */ diff --git a/reactos/lib/ntdll/rtl/security.c b/reactos/lib/ntdll/rtl/security.c deleted file mode 100644 index bcd48a727b6..00000000000 --- a/reactos/lib/ntdll/rtl/security.c +++ /dev/null @@ -1,28 +0,0 @@ -/* $Id: security.c,v 1.2 1999/12/27 15:06:00 ekohl Exp $ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * PURPOSE: Rtl security functions - * FILE: lib/ntdll/rtl/security.c - * PROGRAMER: Eric Kohl - * REVISION HISTORY: - * 22/07/99: Added RtlLengthSecurityDescriptor stub - */ - -/* INCLUDES *****************************************************************/ - -#include - -#include - -/* FUNCTIONS ***************************************************************/ - -ULONG -STDCALL -RtlLengthSecurityDescriptor ( - PSECURITY_DESCRIPTOR SecurityDescriptor - ) -{ - UNIMPLEMENTED; -} - diff --git a/reactos/lib/ntdll/rtl/unicode.c b/reactos/lib/ntdll/rtl/unicode.c index 03139c59969..ab952de58ff 100644 --- a/reactos/lib/ntdll/rtl/unicode.c +++ b/reactos/lib/ntdll/rtl/unicode.c @@ -1,4 +1,4 @@ -/* $Id: unicode.c,v 1.12 2000/01/10 20:30:51 ekohl Exp $ +/* $Id: unicode.c,v 1.13 2000/02/05 16:08:49 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -22,7 +22,7 @@ WCHAR STDCALL RtlAnsiCharToUnicodeChar ( - CHAR AnsiChar + IN CHAR AnsiChar ) { ULONG Size; @@ -46,7 +46,7 @@ RtlAnsiCharToUnicodeChar ( ULONG STDCALL RtlAnsiStringToUnicodeSize ( - IN PANSI_STRING AnsiString + IN PANSI_STRING AnsiString ) { ULONG Size; @@ -62,9 +62,9 @@ RtlAnsiStringToUnicodeSize ( NTSTATUS STDCALL RtlAnsiStringToUnicodeString( - IN OUT PUNICODE_STRING DestinationString, - IN PANSI_STRING SourceString, - IN BOOLEAN AllocateDestinationString + IN OUT PUNICODE_STRING DestinationString, + IN PANSI_STRING SourceString, + IN BOOLEAN AllocateDestinationString ) { NTSTATUS Status; @@ -123,8 +123,8 @@ RtlAnsiStringToUnicodeString( NTSTATUS STDCALL RtlAppendAsciizToString ( - IN OUT PSTRING Destination, - IN PCSZ Source + IN OUT PSTRING Destination, + IN PCSZ Source ) { ULONG Length; @@ -153,8 +153,8 @@ RtlAppendAsciizToString ( NTSTATUS STDCALL RtlAppendStringToString ( - PSTRING Destination, - PSTRING Source + IN OUT PSTRING Destination, + IN PSTRING Source ) { PCHAR Ptr; @@ -181,8 +181,8 @@ RtlAppendStringToString ( NTSTATUS STDCALL RtlAppendUnicodeStringToString ( - IN OUT PUNICODE_STRING Destination, - IN PUNICODE_STRING Source + IN OUT PUNICODE_STRING Destination, + IN PUNICODE_STRING Source ) { PWCHAR Src; @@ -211,8 +211,8 @@ RtlAppendUnicodeStringToString ( NTSTATUS STDCALL RtlAppendUnicodeToString ( - IN OUT PUNICODE_STRING Destination, - IN PWSTR Source + IN OUT PUNICODE_STRING Destination, + IN PWSTR Source ) { PWCHAR Src; @@ -286,9 +286,9 @@ RtlCharToInteger ( LONG STDCALL RtlCompareString ( - PSTRING String1, - PSTRING String2, - BOOLEAN CaseInsensitive + IN PSTRING String1, + IN PSTRING String2, + IN BOOLEAN CaseInsensitive ) { ULONG i; @@ -328,9 +328,9 @@ RtlCompareString ( LONG STDCALL RtlCompareUnicodeString ( - PUNICODE_STRING String1, - PUNICODE_STRING String2, - BOOLEAN CaseInsensitive + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInsensitive ) { ULONG i; @@ -436,8 +436,8 @@ RtlCopyUnicodeString ( BOOLEAN STDCALL RtlCreateUnicodeString ( - PUNICODE_STRING Destination, - PWSTR Source + IN OUT PUNICODE_STRING Destination, + IN PWSTR Source ) { ULONG Length; @@ -537,9 +537,9 @@ RtlDowncaseUnicodeString ( BOOLEAN STDCALL RtlEqualString ( - PSTRING String1, - PSTRING String2, - BOOLEAN CaseInsensitive + IN PSTRING String1, + IN PSTRING String2, + IN BOOLEAN CaseInsensitive ) { ULONG i; @@ -578,9 +578,9 @@ RtlEqualString ( BOOLEAN STDCALL RtlEqualUnicodeString ( - PUNICODE_STRING String1, - PUNICODE_STRING String2, - BOOLEAN CaseInsensitive + IN PUNICODE_STRING String1, + IN PUNICODE_STRING String2, + IN BOOLEAN CaseInsensitive ) { ULONG i; @@ -697,8 +697,8 @@ RtlFreeUnicodeString ( VOID STDCALL RtlInitAnsiString ( - IN OUT PANSI_STRING DestinationString, - IN PCSZ SourceString + IN OUT PANSI_STRING DestinationString, + IN PCSZ SourceString ) { ULONG DestSize; @@ -745,8 +745,8 @@ RtlInitString ( VOID STDCALL RtlInitUnicodeString ( - IN OUT PUNICODE_STRING DestinationString, - IN PCWSTR SourceString + IN OUT PUNICODE_STRING DestinationString, + IN PCWSTR SourceString ) { ULONG DestSize; @@ -818,7 +818,7 @@ NTSTATUS STDCALL RtlIntegerToUnicodeString ( IN ULONG Value, - IN ULONG Base, /* optional */ + IN ULONG Base, /* optional */ IN OUT PUNICODE_STRING String ) { @@ -848,7 +848,7 @@ RtlIntegerToUnicodeString ( ULONG STDCALL RtlOemStringToUnicodeSize ( - IN POEM_STRING OemString + IN POEM_STRING OemString ) { ULONG Size; @@ -864,9 +864,9 @@ RtlOemStringToUnicodeSize ( NTSTATUS STDCALL RtlOemStringToUnicodeString ( - PUNICODE_STRING DestinationString, - POEM_STRING SourceString, - BOOLEAN AllocateDestinationString + IN OUT PUNICODE_STRING DestinationString, + IN POEM_STRING SourceString, + IN BOOLEAN AllocateDestinationString ) { NTSTATUS Status; @@ -925,7 +925,7 @@ RtlOemStringToUnicodeString ( ULONG STDCALL RtlUnicodeStringToAnsiSize ( - IN PUNICODE_STRING UnicodeString + IN PUNICODE_STRING UnicodeString ) { ULONG Size; @@ -941,9 +941,9 @@ RtlUnicodeStringToAnsiSize ( NTSTATUS STDCALL RtlUnicodeStringToAnsiString ( - IN OUT PANSI_STRING DestinationString, - IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString + IN OUT PANSI_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString ) { NTSTATUS Status; @@ -1089,7 +1089,7 @@ RtlUnicodeStringToInteger ( ULONG STDCALL RtlUnicodeStringToOemSize ( - IN PUNICODE_STRING UnicodeString + IN PUNICODE_STRING UnicodeString ) { ULONG Size; @@ -1104,43 +1104,52 @@ RtlUnicodeStringToOemSize ( NTSTATUS STDCALL -RtlUnicodeStringToOemString ( - IN OUT POEM_STRING DestinationString, - IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString +RtlUnicodeStringToCountedOemString ( + IN OUT POEM_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString ) { NTSTATUS Status; ULONG Length; + ULONG Size; if (NlsMbOemCodePageTag == TRUE) - Length = RtlUnicodeStringToAnsiSize (SourceString); + Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; else - Length = SourceString->Length / sizeof(WCHAR); + Length = SourceString->Length / sizeof(WCHAR) + 1; - if (AllocateDestinationString == TRUE) + if (Length > 0x0000FFFF) + return STATUS_INVALID_PARAMETER_2; + + DestinationString->Length = (WORD)(Length - 1); + + if (AllocateDestinationString) { - DestinationString->MaximumLength = Length + sizeof(CHAR); - DestinationString->Buffer = - RtlAllocateHeap (RtlGetProcessHeap (), - 0, - DestinationString->MaximumLength); + DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (), + 0, + Length); if (DestinationString->Buffer == NULL) return STATUS_NO_MEMORY; + + RtlZeroMemory (DestinationString->Buffer, + Length); + DestinationString->MaximumLength = (WORD)Length; } else { - if (Length >= DestinationString->MaximumLength) - return STATUS_BUFFER_TOO_SMALL; + if (Length > DestinationString->MaximumLength) + { + if (DestinationString->MaximumLength == 0) + return STATUS_BUFFER_OVERFLOW; + DestinationString->Length = + DestinationString->MaximumLength - 1; + } } - DestinationString->Length = Length; - - RtlZeroMemory (DestinationString->Buffer, - DestinationString->Length); Status = RtlUnicodeToOemN (DestinationString->Buffer, DestinationString->Length, - NULL, + &Size, SourceString->Buffer, SourceString->Length); if (!NT_SUCCESS(Status)) @@ -1154,7 +1163,74 @@ RtlUnicodeStringToOemString ( return Status; } - DestinationString->Buffer[Length] = 0; + DestinationString->Buffer[Size] = 0; + + return STATUS_SUCCESS; +} + + +NTSTATUS +STDCALL +RtlUnicodeStringToOemString ( + IN OUT POEM_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ) +{ + NTSTATUS Status; + ULONG Length; + ULONG Size; + + if (NlsMbOemCodePageTag == TRUE) + Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; + else + Length = SourceString->Length / sizeof(WCHAR) + 1; + + if (Length > 0x0000FFFF) + return STATUS_INVALID_PARAMETER_2; + + DestinationString->Length = (WORD)(Length - 1); + + if (AllocateDestinationString) + { + DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (), + 0, + Length); + if (DestinationString->Buffer == NULL) + return STATUS_NO_MEMORY; + + RtlZeroMemory (DestinationString->Buffer, + Length); + DestinationString->MaximumLength = (WORD)Length; + } + else + { + if (Length > DestinationString->MaximumLength) + { + if (DestinationString->MaximumLength == 0) + return STATUS_BUFFER_OVERFLOW; + DestinationString->Length = + DestinationString->MaximumLength - 1; + } + } + + Status = RtlUnicodeToOemN (DestinationString->Buffer, + DestinationString->Length, + &Size, + SourceString->Buffer, + SourceString->Length); + if (!NT_SUCCESS(Status)) + { + if (AllocateDestinationString) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + DestinationString->Buffer); + } + return Status; + } + + DestinationString->Buffer[Size] = 0; return STATUS_SUCCESS; } @@ -1163,7 +1239,7 @@ RtlUnicodeStringToOemString ( WCHAR STDCALL RtlUpcaseUnicodeChar ( - WCHAR Source + IN WCHAR Source ) { if (Source < L'a') @@ -1181,9 +1257,9 @@ RtlUpcaseUnicodeChar ( NTSTATUS STDCALL RtlUpcaseUnicodeString ( - IN OUT PUNICODE_STRING DestinationString, - IN PUNICODE_STRING SourceString, - IN BOOLEAN AllocateDestinationString + IN OUT PUNICODE_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString ) { ULONG i; @@ -1229,34 +1305,44 @@ RtlUpcaseUnicodeStringToAnsiString ( { NTSTATUS Status; ULONG Length; + ULONG Size; if (NlsMbCodePageTag == TRUE) - Length = RtlUnicodeStringToAnsiSize (SourceString); + Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; else - Length = SourceString->Length / sizeof(WCHAR); + Length = SourceString->Length / sizeof(WCHAR) + 1; + + if (Length > 0x0000FFFF) + return STATUS_INVALID_PARAMETER_2; + + DestinationString->Length = (WORD)(Length - 1); if (AllocateDestinationString == TRUE) { - DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, DestinationString->MaximumLength); if (DestinationString->Buffer == NULL) return STATUS_NO_MEMORY; + + RtlZeroMemory (DestinationString->Buffer, + Length); + DestinationString->MaximumLength = (WORD)Length; } else { - if (Length >= DestinationString->MaximumLength) - return STATUS_BUFFER_TOO_SMALL; + if (Length > DestinationString->MaximumLength) + { + if (!DestinationString->MaximumLength) + return STATUS_BUFFER_OVERFLOW; + DestinationString->Length = + DestinationString->MaximumLength - 1; + } } - DestinationString->Length = Length; - - RtlZeroMemory (DestinationString->Buffer, - DestinationString->Length); Status = RtlUpcaseUnicodeToMultiByteN (DestinationString->Buffer, DestinationString->Length, - NULL, + &Size, SourceString->Buffer, SourceString->Length); if (!NT_SUCCESS(Status)) @@ -1270,20 +1356,15 @@ RtlUpcaseUnicodeStringToAnsiString ( return Status; } - DestinationString->Buffer[Length] = 0; + DestinationString->Buffer[Size] = 0; return STATUS_SUCCESS; } -/* -RtlUpcaseUnicodeStringToCountedOemString -*/ - - NTSTATUS STDCALL -RtlUpcaseUnicodeStringToOemString ( +RtlUpcaseUnicodeStringToCountedOemString ( IN OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString @@ -1291,34 +1372,44 @@ RtlUpcaseUnicodeStringToOemString ( { NTSTATUS Status; ULONG Length; + ULONG Size; - if (NlsMbOemCodePageTag == TRUE) - Length = RtlUnicodeStringToAnsiSize (SourceString); + if (NlsMbCodePageTag == TRUE) + Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; else - Length = SourceString->Length / sizeof(WCHAR); + Length = SourceString->Length / sizeof(WCHAR) + 1; + + if (Length > 0x0000FFFF) + return STATUS_INVALID_PARAMETER_2; + + DestinationString->Length = (WORD)(Length - 1); if (AllocateDestinationString == TRUE) { - DestinationString->MaximumLength = Length + sizeof(CHAR); DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (), 0, - DestinationString->MaximumLength); + Length); if (DestinationString->Buffer == NULL) return STATUS_NO_MEMORY; + + RtlZeroMemory (DestinationString->Buffer, + Length); + DestinationString->MaximumLength = (WORD)Length; } else { - if (Length >= DestinationString->MaximumLength) - return STATUS_BUFFER_TOO_SMALL; + if (Length > DestinationString->MaximumLength) + { + if (DestinationString->MaximumLength == 0) + return STATUS_BUFFER_OVERFLOW; + DestinationString->Length = + DestinationString->MaximumLength - 1; + } } - DestinationString->Length = Length; - - RtlZeroMemory (DestinationString->Buffer, - DestinationString->Length); Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer, DestinationString->Length, - NULL, + &Size, SourceString->Buffer, SourceString->Length); if (!NT_SUCCESS(Status)) @@ -1332,21 +1423,83 @@ RtlUpcaseUnicodeStringToOemString ( return Status; } - DestinationString->Buffer[Length] = 0; + DestinationString->Buffer[Size] = 0; return STATUS_SUCCESS; } -/* -RtlUpcaseUnicodeToCustomCP -*/ +NTSTATUS +STDCALL +RtlUpcaseUnicodeStringToOemString ( + IN OUT POEM_STRING DestinationString, + IN PUNICODE_STRING SourceString, + IN BOOLEAN AllocateDestinationString + ) +{ + NTSTATUS Status; + ULONG Length; + ULONG Size; + + if (NlsMbOemCodePageTag == TRUE) + Length = RtlUnicodeStringToAnsiSize (SourceString) + 1; + else + Length = SourceString->Length / sizeof(WCHAR) + 1; + + if (Length > 0x0000FFFF) + return STATUS_INVALID_PARAMETER_2; + + DestinationString->Length = (WORD)(Length - 1); + + if (AllocateDestinationString == TRUE) + { + DestinationString->Buffer = RtlAllocateHeap (RtlGetProcessHeap (), + 0, + Length); + if (DestinationString->Buffer == NULL) + return STATUS_NO_MEMORY; + + RtlZeroMemory (DestinationString->Buffer, + Length); + DestinationString->MaximumLength = (WORD)Length; + } + else + { + if (Length > DestinationString->MaximumLength) + { + if (DestinationString->MaximumLength == 0) + return STATUS_BUFFER_OVERFLOW; + DestinationString->Length = + DestinationString->MaximumLength - 1; + } + } + + Status = RtlUpcaseUnicodeToOemN (DestinationString->Buffer, + DestinationString->Length, + &Size, + SourceString->Buffer, + SourceString->Length); + if (!NT_SUCCESS(Status)) + { + if (AllocateDestinationString) + { + RtlFreeHeap (RtlGetProcessHeap (), + 0, + DestinationString->Buffer); + } + return Status; + } + + DestinationString->Buffer[Size] = 0; + + return STATUS_SUCCESS; +} CHAR STDCALL RtlUpperChar ( - CHAR Source + IN CHAR Source ) { WCHAR Unicode; @@ -1384,8 +1537,8 @@ RtlUpperChar ( VOID STDCALL RtlUpperString ( - PSTRING DestinationString, - PSTRING SourceString + IN OUT PSTRING DestinationString, + IN PSTRING SourceString ) { ULONG Length;