From 35d5d06ac987a4ea52da780ca7729e0503f0e5b2 Mon Sep 17 00:00:00 2001 From: Eric Pouech Date: Thu, 15 May 2003 04:20:42 +0000 Subject: [PATCH] Implemented RtlDosPathNameToNtPathName_U, RtlGetCurrentDirectory_U, RtlGetFullPathName_U and RtlSetCurrentDirectory_U (the last one partially as we can't test whether a path exists or not). --- dlls/ntdll/ntdll.spec | 12 +- dlls/ntdll/path.c | 487 +++++++++++++++++++++++++++++++++++++++++- dlls/ntdll/rtl.c | 66 ------ include/winternl.h | 11 +- scheduler/process.c | 11 + 5 files changed, 513 insertions(+), 74 deletions(-) diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index c163bd7a307..5919aafddc1 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -348,9 +348,9 @@ @ stub RtlDestroyProcessParameters @ stub RtlDestroyQueryDebugBuffer @ stdcall RtlDetermineDosPathNameType_U(wstr) -@ stub RtlDoesFileExists_U -@ stdcall RtlDosPathNameToNtPathName_U(ptr ptr long long) -@ stub RtlDosSearchPath_U +@ stub RtlDoesFileExists_U #(wstr) +@ stdcall RtlDosPathNameToNtPathName_U(wstr ptr ptr ptr) +@ stub RtlDosSearchPath_U #(wstr wstr wstr long ptr ptr) @ stdcall RtlDowncaseUnicodeChar(long) @ stdcall RtlDowncaseUnicodeString(ptr ptr long) @ stdcall RtlDumpResource(ptr) @@ -408,10 +408,10 @@ @ stub RtlGetCallersAddress @ stub RtlGetCompressionWorkSpaceSize @ stdcall RtlGetControlSecurityDescriptor(ptr ptr ptr) -@ stub RtlGetCurrentDirectory_U +@ stdcall RtlGetCurrentDirectory_U(long ptr) @ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr) @ stub RtlGetElementGenericTable -@ stub RtlGetFullPathName_U +@ stdcall RtlGetFullPathName_U(wstr long ptr ptr) @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) @ stdcall RtlGetLongestNtPathLength() @ stub RtlGetNtGlobalFlags @@ -511,7 +511,7 @@ @ stub RtlSelfRelativeToAbsoluteSD @ stdcall RtlSetAllBits(ptr) @ stdcall RtlSetBits(ptr long long) -@ stub RtlSetCurrentDirectory_U +@ stdcall RtlSetCurrentDirectory_U(ptr) @ stdcall RtlSetCurrentEnvironment(wstr ptr) @ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long) @ stdcall RtlSetEnvironmentVariable(ptr ptr ptr) diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index 535ba636580..08be65fc289 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -24,9 +24,14 @@ #include "winternl.h" #include "wine/unicode.h" #include "wine/debug.h" +#include "ntdll_misc.h" WINE_DEFAULT_DEBUG_CHANNEL(file); +static const WCHAR DeviceRootW[] = {'\\','\\','.','\\',0}; +static const WCHAR NTDosPrefixW[] = {'\\','?','?','\\',0}; +static const WCHAR UncPfxW[] = {'U','N','C','\\',0}; + #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/') /*********************************************************************** @@ -50,7 +55,6 @@ DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path ) } } - /*********************************************************************** * RtlIsDosDeviceName_U (NTDLL.@) * @@ -129,6 +133,370 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name ) } +/************************************************************************** + * RtlDosPathNameToNtPathName_U [NTDLL.@] + * + * dos_path: a DOS path name (fully qualified or not) + * ntpath: pointer to a UNICODE_STRING to hold the converted + * path name + * file_part:will point (in ntpath) to the file part in the path + * cd: directory reference (optional) + * + * FIXME: + * + fill the cd structure + */ +BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PWSTR dos_path, + PUNICODE_STRING ntpath, + PWSTR* file_part, + CURDIR* cd) +{ + static const WCHAR LongFileNamePfxW[4] = {'\\','\\','?','\\'}; + ULONG sz, ptr_sz, offset; + WCHAR local[MAX_PATH]; + LPWSTR ptr; + + TRACE("(%s,%p,%p,%p)\n", + debugstr_w(dos_path), ntpath, file_part, cd); + + if (cd) + { + FIXME("Unsupported parameter\n"); + memset(cd, 0, sizeof(*cd)); + } + + if (!dos_path || !*dos_path) return FALSE; + + if (!memcmp(dos_path, LongFileNamePfxW, sizeof(LongFileNamePfxW))) + { + dos_path += sizeof(LongFileNamePfxW) / sizeof(WCHAR); + ptr = NULL; + ptr_sz = 0; + } + else + { + ptr = local; + ptr_sz = sizeof(local); + } + sz = RtlGetFullPathName_U(dos_path, ptr_sz, ptr, file_part); + if (sz == 0) return FALSE; + if (sz > ptr_sz) + { + ptr = RtlAllocateHeap(ntdll_get_process_heap(), 0, sz); + sz = RtlGetFullPathName_U(dos_path, sz, ptr, file_part); + } + + ntpath->MaximumLength = sz + (4 /* unc\ */ + 4 /* \??\ */) * sizeof(WCHAR); + ntpath->Buffer = RtlAllocateHeap(ntdll_get_process_heap(), 0, ntpath->MaximumLength); + if (!ntpath->Buffer) + { + if (ptr != local) RtlFreeHeap(ntdll_get_process_heap(), 0, ptr); + return FALSE; + } + + strcpyW(ntpath->Buffer, NTDosPrefixW); + offset = 0; + switch (RtlDetermineDosPathNameType_U(ptr)) + { + case UNC_PATH: /* \\foo */ + if (ptr[2] != '?') + { + offset = 2; + strcatW(ntpath->Buffer, UncPfxW); + } + break; + case DEVICE_PATH: /* \\.\foo */ + offset = 4; + break; + default: break; /* needed to keep gcc quiet */ + } + + strcatW(ntpath->Buffer, ptr + offset); + ntpath->Length = strlenW(ntpath->Buffer) * sizeof(WCHAR); + + if (file_part && *file_part) + *file_part = ntpath->Buffer + ntpath->Length / sizeof(WCHAR) - lstrlenW(*file_part); + + /* FIXME: cd filling */ + + if (ptr != local) RtlFreeHeap(ntdll_get_process_heap(), 0, ptr); + return TRUE; +} + +/****************************************************************** + * get_full_path_helper + * + * Helper for RtlGetFullPathName_U + */ +static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) +{ + ULONG reqsize, mark = 0; + DOS_PATHNAME_TYPE type; + LPWSTR ptr; + UNICODE_STRING* cd; + + reqsize = sizeof(WCHAR); /* '\0' at the end */ + + RtlAcquirePebLock(); + cd = &ntdll_get_process_pmts()->CurrentDirectoryName; + + switch (type = RtlDetermineDosPathNameType_U(name)) + { + case UNC_PATH: /* \\foo */ + case DEVICE_PATH: /* \\.\foo */ + if (reqsize <= size) buffer[0] = '\0'; + break; + + case ABSOLUTE_DRIVE_PATH: /* c:\foo */ + reqsize += sizeof(WCHAR); + if (reqsize <= size) + { + buffer[0] = toupperW(name[0]); + buffer[1] = '\0'; + } + name++; + break; + + case RELATIVE_DRIVE_PATH: /* c:foo */ + if (toupperW(name[0]) != toupperW(cd->Buffer[0]) || cd->Buffer[1] != ':') + { + WCHAR drive[4]; + UNICODE_STRING var, val; + + drive[0] = '='; + drive[1] = name[0]; + drive[2] = ':'; + drive[3] = '\0'; + var.Length = 6; + var.MaximumLength = 8; + var.Buffer = drive; + val.Length = 0; + val.MaximumLength = size; + val.Buffer = buffer; + + name += 2; + + switch (RtlQueryEnvironmentVariable_U(NULL, &var, &val)) + { + case STATUS_SUCCESS: + /* FIXME: Win2k seems to check that the environment variable actually points + * to an existing directory. If not, root of the drive is used + * (this seems also to be the only spot in RtlGetFullPathName that the + * existence of a part of a path is checked) + */ + /* fall thru */ + case STATUS_BUFFER_TOO_SMALL: + reqsize += val.Length; + /* append trailing \\ */ + reqsize += sizeof(WCHAR); + if (reqsize <= size) + { + buffer[reqsize / sizeof(WCHAR) - 2] = '\\'; + buffer[reqsize / sizeof(WCHAR) - 1] = '\0'; + } + break; + case STATUS_VARIABLE_NOT_FOUND: + reqsize += 3 * sizeof(WCHAR); + if (reqsize <= size) + { + buffer[0] = drive[1]; + buffer[1] = ':'; + buffer[2] = '\\'; + buffer[3] = '\0'; + } + break; + default: + ERR("Unsupported status code\n"); + break; + } + break; + } + name += 2; + /* fall through */ + + case RELATIVE_PATH: /* foo */ + reqsize += cd->Length; + mark = cd->Length / sizeof(WCHAR); + if (reqsize <= size) + strcpyW(buffer, cd->Buffer); + break; + + case ABSOLUTE_PATH: /* \xxx */ + if (cd->Buffer[1] == ':') + { + reqsize += 2 * sizeof(WCHAR); + if (reqsize <= size) + { + buffer[0] = cd->Buffer[0]; + buffer[1] = ':'; + buffer[2] = '\0'; + } + } + else + { + unsigned len; + + ptr = strchrW(cd->Buffer + 2, '\\'); + if (ptr) ptr = strchrW(ptr + 1, '\\'); + if (!ptr) ptr = cd->Buffer + strlenW(cd->Buffer); + len = (ptr - cd->Buffer) * sizeof(WCHAR); + reqsize += len; + mark = len / sizeof(WCHAR); + if (reqsize <= size) + { + memcpy(buffer, cd->Buffer, len); + buffer[len / sizeof(WCHAR)] = '\0'; + } + else + buffer[0] = '\0'; + } + break; + + case UNC_DOT_PATH: /* \\. */ + reqsize += 4 * sizeof(WCHAR); + name += 3; + if (reqsize <= size) + { + buffer[0] = '\\'; + buffer[1] = '\\'; + buffer[2] = '.'; + buffer[3] = '\\'; + buffer[4] = '\0'; + } + break; + + case INVALID_PATH: + reqsize = 0; + goto done; + } + + reqsize += strlenW(name) * sizeof(WCHAR); + if (reqsize > size) goto done; + + strcatW(buffer, name); + + /* convert every / into a \ */ + for (ptr = buffer; ptr < buffer + size / sizeof(WCHAR); ptr++) + if (*ptr == '/') *ptr = '\\'; + + reqsize -= sizeof(WCHAR); /* don't count trailing \0 */ + + /* mark is non NULL for UNC names, so start path collapsing after server & share name + * otherwise, it's a fully qualified DOS name, so start after the drive designation + */ + for (ptr = buffer + (mark ? mark : 2); ptr < buffer + reqsize / sizeof(WCHAR); ) + { + WCHAR* p = strchrW(ptr, '\\'); + if (!p) break; + + p++; + if (p[0] == '.') + { + switch (p[1]) + { + case '.': + switch (p[2]) + { + case '\\': + { + WCHAR* prev = p - 2; + while (prev >= buffer + mark && *prev != '\\') prev--; + /* either collapse \foo\.. into \ or \.. into \ */ + if (prev < buffer + mark) prev = p - 1; + reqsize -= (p + 2 - prev) * sizeof(WCHAR); + memmove(prev, p + 2, buffer + reqsize - prev + sizeof(WCHAR)); + } + break; + case '\0': + reqsize -= 2 * sizeof(WCHAR); + *p = 0; + break; + } + break; + case '\\': + reqsize -= 2 * sizeof(WCHAR); + memmove(ptr + 2, ptr, buffer + reqsize - ptr + sizeof(WCHAR)); + break; + } + } + ptr = p; + } + +done: + RtlReleasePebLock(); + return reqsize; +} + +/****************************************************************** + * RtlGetFullPathName_U (NTDLL.@) + * + * Returns the number of bytes written to buffer (not including the + * terminating NULL) if the function succeeds, or the required number of bytes + * (including the terminating NULL) if the buffer is to small. + * + * file_part will point to the filename part inside buffer (except if we use + * DOS device name, in which case file_in_buf is NULL) + * + */ +DWORD WINAPI RtlGetFullPathName_U(const WCHAR* name, ULONG size, WCHAR* buffer, + WCHAR** file_part) +{ + DWORD dosdev; + DWORD reqsize; + + TRACE("(%s %lu %p %p)\n", debugstr_w(name), size, buffer, file_part); + + if (!name || !*name) return 0; + + if (file_part) *file_part = NULL; + + /* check for DOS device name */ + dosdev = RtlIsDosDeviceName_U(name); + if (dosdev) + { + DWORD offset = HIWORD(dosdev) / sizeof(WCHAR); /* get it in WCHARs, not bytes */ + DWORD sz = LOWORD(dosdev); /* in bytes */ + + if (8 + sz + 2 > size) return sz + 10; + strcpyW(buffer, DeviceRootW); + memmove(buffer + 4, name + offset, sz); + buffer[4 + sz / sizeof(WCHAR)] = '\0'; + /* file_part isn't set in this case */ + return sz + 8; + } + + reqsize = get_full_path_helper(name, buffer, size); + if (reqsize > size) + { + LPWSTR tmp = RtlAllocateHeap(ntdll_get_process_heap(), 0, reqsize); + reqsize = get_full_path_helper(name, tmp, reqsize) + sizeof(WCHAR); + RtlFreeHeap(ntdll_get_process_heap(), 0, tmp); + } + else + { + WCHAR* ptr; + /* find file part */ + if (file_part && (ptr = strrchrW(buffer, '\\')) != NULL && ptr >= buffer + 2 && *++ptr) + *file_part = ptr; + } + return reqsize; +} + +/************************************************************************* + * RtlGetLongestNtPathLength [NTDLL.@] + * + * Get the longest allowed path length + * + * PARAMS + * None. + * + * RETURNS + * The longest allowed path length (277 characters under Win2k). + */ +DWORD WINAPI RtlGetLongestNtPathLength(void) +{ + return 277; +} + /****************************************************************** * RtlIsNameLegalDOS8Dot3 (NTDLL.@) * @@ -197,3 +565,120 @@ BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode, if (spaces) *spaces = got_space; return TRUE; } + +/****************************************************************** + * RtlGetCurrentDirectory_U (NTDLL.@) + * + */ +NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG buflen, LPWSTR buf) +{ + UNICODE_STRING* us; + ULONG len; + + TRACE("(%lu %p)\n", buflen, buf); + + RtlAcquirePebLock(); + + us = &ntdll_get_process_pmts()->CurrentDirectoryName; + len = us->Length / sizeof(WCHAR); + if (us->Buffer[len - 1] == '\\' && us->Buffer[len - 2] != ':') + len--; + + if (buflen / sizeof(WCHAR) > len) + { + memcpy(buf, us->Buffer, len * sizeof(WCHAR)); + buf[len] = '\0'; + } + else + { + len++; + } + + RtlReleasePebLock(); + + return len * sizeof(WCHAR); +} + +/****************************************************************** + * RtlSetCurrentDirectory_U (NTDLL.@) + * + */ +NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING* dir) +{ + UNICODE_STRING* curdir; + NTSTATUS nts = STATUS_SUCCESS; + ULONG size; + PWSTR buf = NULL; + + TRACE("(%s)\n", debugstr_w(dir->Buffer)); + + RtlAcquirePebLock(); + + curdir = &ntdll_get_process_pmts()->CurrentDirectoryName; + size = curdir->MaximumLength; + + buf = RtlAllocateHeap(ntdll_get_process_heap(), 0, size); + if (buf == NULL) + { + nts = STATUS_NO_MEMORY; + goto out; + } + + size = RtlGetFullPathName_U(dir->Buffer, size, buf, 0); + if (!size) + { + nts = STATUS_OBJECT_NAME_INVALID; + goto out; + } + + switch (RtlDetermineDosPathNameType_U(buf)) + { + case ABSOLUTE_DRIVE_PATH: + case UNC_PATH: + break; + default: + FIXME("Don't support those cases yes\n"); + nts = STATUS_NOT_IMPLEMENTED; + goto out; + } + + /* FIXME: should check that the directory actually exists, + * and fill CurrentDirectoryHandle accordingly + */ + + /* append trailing \ if missing */ + if (buf[size / sizeof(WCHAR) - 1] != '\\') + { + buf[size / sizeof(WCHAR)] = '\\'; + buf[size / sizeof(WCHAR) + 1] = '\0'; + size += sizeof(WCHAR); + } + + memmove(curdir->Buffer, buf, size + sizeof(WCHAR)); + curdir->Length = size; + +#if 0 + if (curdir->Buffer[1] == ':') + { + UNICODE_STRING env; + WCHAR var[4]; + + var[0] = '='; + var[1] = curdir->Buffer[0]; + var[2] = ':'; + var[3] = 0; + env.Length = 3 * sizeof(WCHAR); + env.MaximumLength = 4 * sizeof(WCHAR); + env.Buffer = var; + + RtlSetEnvironmentVariable(NULL, &env, curdir); + } +#endif + + out: + if (buf) RtlFreeHeap(ntdll_get_process_heap(), 0, buf); + + RtlReleasePebLock(); + + return nts; +} diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index b73fec5583b..76eb823147b 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -370,55 +370,6 @@ void WINAPI NTDLL_alloca_probe( CONTEXT86 *context ) context->Esp -= context->Eax; } -/************************************************************************** - * RtlDosPathNameToNtPathName_U [NTDLL.@] - * - * szwDosPath: a fully qualified DOS path name - * ntpath: pointer to a UNICODE_STRING to hold the converted - * path name - * - * FIXME: Should we not allocate the ntpath buffer under some - * circumstances? - * Are the conversions static? (always prepend '\??\' ?) - * Not really sure about the last two arguments. - */ -BOOLEAN WINAPI RtlDosPathNameToNtPathName_U( - LPWSTR szwDosPath,PUNICODE_STRING ntpath, - DWORD x2,DWORD x3) -{ - ULONG length; - UNICODE_STRING pathprefix; - WCHAR szPrefix[] = { '\\', '?', '?', '\\', 0 }; - - FIXME("(%s,%p,%08lx,%08lx) partial stub\n", - debugstr_w(szwDosPath),ntpath,x2,x3); - - if ( !szwDosPath ) - return FALSE; - - if ( !szwDosPath[0] ) - return FALSE; - - if ( szwDosPath[1]!= ':' ) - return FALSE; - - length = strlenW(szwDosPath) * sizeof (WCHAR) + sizeof szPrefix; - - ntpath->Buffer = RtlAllocateHeap(ntdll_get_process_heap(), 0, length); - ntpath->Length = 0; - ntpath->MaximumLength = length; - - if ( !ntpath->Buffer ) - return FALSE; - - RtlInitUnicodeString( &pathprefix, szPrefix ); - RtlCopyUnicodeString( ntpath, &pathprefix ); - RtlAppendUnicodeToString( ntpath, szwDosPath ); - - return TRUE; -} - - /****************************************************************************** * RtlInitializeGenericTable [NTDLL.@] */ @@ -606,23 +557,6 @@ VOID WINAPI RtlFillMemoryUlong(ULONG* lpDest, ULONG ulCount, ULONG ulValue) *lpDest++ = ulValue; } -/************************************************************************* - * RtlGetLongestNtPathLength [NTDLL.@] - * - * Get the longest allowed path length - * - * PARAMS - * None. - * - * RETURNS - * The longest allowed path length (277 characters under Win2k). - */ -DWORD WINAPI RtlGetLongestNtPathLength(void) -{ - TRACE("()\n"); - return 277; -} - /********************************************************************* * RtlComputeCrc32 [NTDLL.@] * diff --git a/include/winternl.h b/include/winternl.h index 9b80c5e8e57..1f01f185612 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -95,6 +95,12 @@ typedef struct _CLIENT_ID HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; + PVOID Handle; +} CURDIR, *PCURDIR; + /*********************************************************************** * Enums */ @@ -965,7 +971,7 @@ DWORD WINAPI RtlDeleteSecurityObject(DWORD); NTSTATUS WINAPI RtlDestroyEnvironment(PWSTR); HANDLE WINAPI RtlDestroyHeap(HANDLE); DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U(PCWSTR); -BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,DWORD,DWORD); +BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR); NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN); void WINAPI RtlDumpResource(LPRTL_RWLOCK); @@ -1014,9 +1020,11 @@ void WINAPI RtlFreeUnicodeString(PUNICODE_STRING); DWORD WINAPI RtlGetAce(PACL,DWORD,LPVOID *); NTSTATUS WINAPI RtlGetControlSecurityDescriptor(PSECURITY_DESCRIPTOR, PSECURITY_DESCRIPTOR_CONTROL,LPDWORD); +NTSTATUS WINAPI RtlGetCurrentDirectory_U(ULONG, LPWSTR); NTSTATUS WINAPI RtlGetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,PBOOLEAN,PACL *,PBOOLEAN); ULONG WINAPI RtlGetFullPathName_U(PCWSTR,ULONG,PWSTR,PWSTR*); NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN); +DWORD WINAPI RtlGetLongestNtPathLength(void); BOOLEAN WINAPI RtlGetNtProductType(LPDWORD); NTSTATUS WINAPI RtlGetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN); ULONG WINAPI RtlGetProcessHeaps(ULONG,HANDLE*); @@ -1093,6 +1101,7 @@ void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSetAllBits(PRTL_BITMAP); void WINAPI RtlSetBits(PRTL_BITMAP,ULONG,ULONG); +NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING*); void WINAPI RtlSetCurrentEnvironment(PWSTR, PWSTR*); NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN); NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING); diff --git a/scheduler/process.c b/scheduler/process.c index 410a6ffb26c..ed4828b82b1 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -471,6 +471,17 @@ static BOOL process_init( char *argv[] ) /* Parse command line arguments */ OPTIONS_ParseOptions( !info_size ? argv : NULL ); + /* */ + build_initial_environment(); + process_pmts.CurrentDirectoryName.Length = 3 * sizeof(WCHAR); + process_pmts.CurrentDirectoryName.MaximumLength = RtlGetLongestNtPathLength() * sizeof(WCHAR); + process_pmts.CurrentDirectoryName.Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, process_pmts.CurrentDirectoryName.MaximumLength); + process_pmts.CurrentDirectoryName.Buffer[0] = 'C'; + process_pmts.CurrentDirectoryName.Buffer[1] = ':'; + process_pmts.CurrentDirectoryName.Buffer[2] = '\\'; + process_pmts.CurrentDirectoryName.Buffer[3] = '\0'; + /* */ + ret = MAIN_MainInit(); if (TRACE_ON(relay) || TRACE_ON(snoop)) RELAY_InitDebugLists();