- RtlDosPathNameToNtPathName_U
- RtlGetCurrentDirectory_U
- RtlGetFullPathName_U
- RtlSetCurrentDirectory_U (partially as we can't test whether a path exists or not)
A+
-- Eric Pouech
Common subdirectories: dlls/ntdll20/CVS and dlls/ntdll/CVS diff -u -x '*~' -x '.#*' dlls/ntdll20/ntdll.spec dlls/ntdll/ntdll.spec --- dlls/ntdll20/ntdll.spec 2003-05-08 07:45:11.000000000 +0200 +++ dlls/ntdll/ntdll.spec 2003-05-08 08:32:13.000000000 +0200 @@ -347,10 +347,10 @@ @ stdcall RtlDestroyHeap(long) @ stub RtlDestroyProcessParameters @ stub RtlDestroyQueryDebugBuffer -@ stdcall RtlDetermineDosPathNameType_U(wstr) RtlDetermineDosPathNameType_U -@ stub RtlDoesFileExists_U -@ stdcall RtlDosPathNameToNtPathName_U(ptr ptr long long) -@ stub RtlDosSearchPath_U +@ stdcall RtlDetermineDosPathNameType_U(wstr) +@ 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 -u -x '*~' -x '.#*' dlls/ntdll20/path.c dlls/ntdll/path.c --- dlls/ntdll20/path.c 2003-05-07 19:34:50.000000000 +0200 +++ dlls/ntdll/path.c 2003-05-08 09:39:35.000000000 +0200 @@ -24,9 +24,15 @@ #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 LongFileNamePfxW[] = {'\\','\\','?','\\',0}; +static const WCHAR UncPfxW[] = {'U','N','C','\\',0}; + #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/') /*********************************************************************** @@ -50,7 +56,6 @@ } } - /*********************************************************************** * RtlIsDosDeviceName_U (NTDLL.@) * @@ -128,6 +133,368 @@ return 0; } +/************************************************************************** + * 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) +{ + 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 (!strcmpW(dos_path, LongFileNamePfxW)) + { + dos_path += 4; + 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; + + default: + ERR("Unrecognized type: %d\n", type); + return 0; + } + RtlReleasePebLock(); + + reqsize += strlenW(name) * sizeof(WCHAR); + if (reqsize > size) return reqsize; + + 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 + * other wise, 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; + } + return reqsize; +} + +/****************************************************************** + * RtlGetFullPathName_U + * + * 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 = dosdev >> 17; /* get it in WCHARs, not bytes */ + DWORD sz = dosdev & 0xFFFF; /* 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) +{ + TRACE("()\n"); + return 277; +} + /****************************************************************** * RtlIsNameLegalDOS8Dot3 (NTDLL.@) * @@ -196,3 +563,119 @@ 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(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"); + return STATUS_NOT_IMPLEMENTED; + } + + /* 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 -u -x '*~' -x '.#*' dlls/ntdll20/rtl.c dlls/ntdll/rtl.c --- dlls/ntdll20/rtl.c 2003-05-08 07:45:11.000000000 +0200 +++ dlls/ntdll/rtl.c 2003-05-08 08:32:43.000000000 +0200 @@ -370,55 +370,6 @@ 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 @@ *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.@] * Common subdirectories: dlls/ntdll20/tests and dlls/ntdll/tests Common subdirectories: files20/CVS and files/CVS Common subdirectories: include20/bitmaps and include/bitmaps Common subdirectories: include20/CVS and include/CVS Common subdirectories: include20/msvcrt and include/msvcrt Common subdirectories: include20/wine and include/wine diff -u -x '*~' -x '.#*' include20/winternl.h include/winternl.h --- include20/winternl.h 2003-05-08 07:45:24.000000000 +0200 +++ include/winternl.h 2003-05-08 10:13:58.000000000 +0200 @@ -95,6 +95,12 @@ HANDLE UniqueThread; } CLIENT_ID, *PCLIENT_ID; +typedef struct _CURDIR +{ + UNICODE_STRING DosPath; + PVOID Handle; +} CURDIR, *PCURDIR; + /*********************************************************************** * Enums */ @@ -965,7 +971,7 @@ 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); @@ -1013,9 +1019,11 @@ 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*); @@ -1092,6 +1100,7 @@ void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *); void WINAPI RtlSetAllBits(PRTL_BITMAP); void WINAPI RtlSetBits(PRTL_BITMAP,ULONG,ULONG); +NTSTATUS WINAPI RtlSetCurrentDirectory_U(UNICODE_STRING*); void WINAPI RtlSetCurrentEnvironment(PWSTR, PWSTR*); NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR,BOOLEAN,PACL,BOOLEAN); NTSTATUS WINAPI RtlSetEnvironmentVariable(PWSTR*,PUNICODE_STRING,PUNICODE_STRING); Common subdirectories: relay3220/CVS and relay32/CVS Common subdirectories: scheduler20/CVS and scheduler/CVS diff -u -x '*~' -x '.#*' scheduler20/process.c scheduler/process.c --- scheduler20/process.c 2003-05-08 07:45:31.000000000 +0200 +++ scheduler/process.c 2003-05-08 10:13:06.000000000 +0200 @@ -471,6 +471,17 @@ /* Parse command line arguments */ OPTIONS_ParseOptions( !info_size ? argv : NULL ); + /* <hack: to be changed later on> */ + 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'; + /* </hack: to be changed later on> */ + ret = MAIN_MainInit(); if (TRACE_ON(relay) || TRACE_ON(snoop)) RELAY_InitDebugLists();