mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Added some string functions
Added security descriptor functions Implemented environment functions Implemented current directory functions svn path=/trunk/; revision=980
This commit is contained in:
parent
18c0c85dd8
commit
326a3cd58b
12 changed files with 1750 additions and 164 deletions
|
@ -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 (
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
733
reactos/lib/ntdll/rtl/path.c
Normal file
733
reactos/lib/ntdll/rtl/path.c
Normal file
|
@ -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 <ddk/ntddk.h>
|
||||
#include <ntdll/rtl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
|
||||
/* 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 */
|
|
@ -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
|
||||
|
@ -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,7 +510,7 @@ 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;
|
||||
|
|
290
reactos/lib/ntdll/rtl/sd.c
Normal file
290
reactos/lib/ntdll/rtl/sd.c
Normal file
|
@ -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 <welch@cwcom.net>
|
||||
* REVISION HISTORY:
|
||||
* 26/07/98: Added stubs for security functions
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
/* 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 */
|
|
@ -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 <ddk/ntddk.h>
|
||||
|
||||
#include <ntdll/ntdll.h>
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
RtlLengthSecurityDescriptor (
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue