From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/kernel32/profile.c | 2 +- dlls/kernelbase/file.c | 2 +- dlls/ntdll/actctx.c | 2 +- dlls/ntdll/loader.c | 8 +++--- dlls/ntdll/path.c | 52 ++++++++++++++++++------------------ dlls/ntoskrnl.exe/ntoskrnl.c | 2 +- include/winternl.h | 23 ++++++++-------- 7 files changed, 45 insertions(+), 46 deletions(-)
diff --git a/dlls/kernel32/profile.c b/dlls/kernel32/profile.c index 032802a42e0..5293c533efb 100644 --- a/dlls/kernel32/profile.c +++ b/dlls/kernel32/profile.c @@ -738,7 +738,7 @@ static BOOL PROFILE_Open( LPCWSTR filename, BOOL write_access ) if (!filename) filename = L"win.ini";
- if ((RtlDetermineDosPathNameType_U(filename) == RELATIVE_PATH) && + if ((RtlDetermineDosPathNameType_U(filename) == RtlPathTypeRelative) && !wcschr(filename, '\') && !wcschr(filename, '/')) { WCHAR windirW[MAX_PATH]; diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index f0dedfe3b14..99cff87c706 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -101,7 +101,7 @@ static const WCHAR *get_machine_wow64_dir( WORD machine ) */ static inline BOOL contains_path( const WCHAR *name ) { - if (RtlDetermineDosPathNameType_U( name ) != RELATIVE_PATH) return TRUE; + if (RtlDetermineDosPathNameType_U( name ) != RtlPathTypeRelative) return TRUE; if (name[0] != '.') return FALSE; if (name[1] == '/' || name[1] == '\') return TRUE; return (name[1] == '.' && (name[2] == '/' || name[2] == '\')); diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index fcb7f4e218e..c6a4c46308c 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -5336,7 +5336,7 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr ) BOOLEAN ret;
if (pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID && - RtlDetermineDosPathNameType_U(pActCtx->lpSource) == RELATIVE_PATH) + RtlDetermineDosPathNameType_U(pActCtx->lpSource) == RtlPathTypeRelative) { DWORD dir_len, source_len;
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 5e746803a50..74eb1b7f500 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -2614,7 +2614,7 @@ static NTSTATUS get_dll_load_path_search_flags( LPCWSTR module, DWORD flags, WCH if (flags & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) { DWORD type = RtlDetermineDosPathNameType_U( module ); - if (type != ABSOLUTE_DRIVE_PATH && type != ABSOLUTE_PATH && type != DEVICE_PATH && type != UNC_PATH) + if (type != RtlPathTypeDriveAbsolute && type != RtlPathTypeRooted && type != RtlPathTypeLocalDevice && type != RtlPathTypeUncAbsolute) return STATUS_INVALID_PARAMETER; mod_end = get_module_path_end( module ); len += (mod_end - module) + 1; @@ -3264,7 +3264,7 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, UNI } }
- if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH) + if (RtlDetermineDosPathNameType_U( libname ) == RtlPathTypeRelative) { status = search_dll_file( load_path, libname, nt_name, pwm, mapping, image_info, id ); if (status == STATUS_DLL_NOT_FOUND) @@ -4658,9 +4658,9 @@ NTSTATUS WINAPI LdrAddDllDirectory( const UNICODE_STRING *dir, void **cookie ) OBJECT_ATTRIBUTES attr; DWORD len; struct dll_dir_entry *ptr; - DOS_PATHNAME_TYPE type = RtlDetermineDosPathNameType_U( dir->Buffer ); + RTL_PATH_TYPE type = RtlDetermineDosPathNameType_U( dir->Buffer );
- if (type != ABSOLUTE_PATH && type != ABSOLUTE_DRIVE_PATH && type != UNC_PATH) + if (type != RtlPathTypeRooted && type != RtlPathTypeDriveAbsolute && type != RtlPathTypeUncAbsolute) return STATUS_INVALID_PARAMETER;
status = RtlDosPathNameToNtPathName_U_WithStatus( dir->Buffer, &nt_name, NULL, NULL ); diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index 8956ff07f6c..e96597ab429 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -36,21 +36,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(file); /*********************************************************************** * RtlDetermineDosPathNameType_U (NTDLL.@) */ -DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path ) +RTL_PATH_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path ) { if (IS_SEPARATOR(path[0])) { - if (!IS_SEPARATOR(path[1])) return ABSOLUTE_PATH; /* "/foo" */ - if (path[2] != '.' && path[2] != '?') return UNC_PATH; /* "//foo" */ - if (IS_SEPARATOR(path[3])) return DEVICE_PATH; /* "//./foo" or "//?/foo" */ - if (path[3]) return UNC_PATH; /* "//.foo" or "//?foo" */ - return UNC_DOT_PATH; /* "//." or "//?" */ + if (!IS_SEPARATOR(path[1])) return RtlPathTypeRooted; /* "/foo" */ + if (path[2] != '.' && path[2] != '?') return RtlPathTypeUncAbsolute; /* "//foo" */ + if (IS_SEPARATOR(path[3])) return RtlPathTypeLocalDevice; /* "//./foo" or "//?/foo" */ + if (path[3]) return RtlPathTypeUncAbsolute; /* "//.foo" or "//?foo" */ + return RtlPathTypeRootLocalDevice; /* "//." or "//?" */ } else { - if (!path[0] || path[1] != ':') return RELATIVE_PATH; /* "foo" */ - if (IS_SEPARATOR(path[2])) return ABSOLUTE_DRIVE_PATH; /* "c:/foo" */ - return RELATIVE_DRIVE_PATH; /* "c:foo" */ + if (!path[0] || path[1] != ':') return RtlPathTypeRelative; /* "foo" */ + if (IS_SEPARATOR(path[2])) return RtlPathTypeDriveAbsolute; /* "c:/foo" */ + return RtlPathTypeDriveRelative; /* "c:foo" */ } }
@@ -78,15 +78,15 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name )
switch(RtlDetermineDosPathNameType_U( dos_name )) { - case INVALID_PATH: - case UNC_PATH: + case RtlPathTypeUnknown: + case RtlPathTypeUncAbsolute: return 0; - case DEVICE_PATH: + case RtlPathTypeLocalDevice: if (!wcsicmp( dos_name, L"\\.\CON" )) return MAKELONG( sizeof(conW), 4 * sizeof(WCHAR) ); /* 4 is length of \.\ prefix */ return 0; - case ABSOLUTE_DRIVE_PATH: - case RELATIVE_DRIVE_PATH: + case RtlPathTypeDriveAbsolute: + case RtlPathTypeDriveRelative: start = dos_name + 2; /* skip drive letter */ break; default: @@ -271,11 +271,11 @@ NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, U wcscpy(ntpath->Buffer, L"\??\"); switch (RtlDetermineDosPathNameType_U(ptr)) { - case UNC_PATH: /* \foo */ + case RtlPathTypeUncAbsolute: /* \foo */ offset = 2; wcscat(ntpath->Buffer, L"UNC\"); break; - case DEVICE_PATH: /* \.\foo */ + case RtlPathTypeLocalDevice: /* \.\foo */ offset = 4; break; default: @@ -361,10 +361,10 @@ ULONG WINAPI RtlDosSearchPath_U(LPCWSTR paths, LPCWSTR search, LPCWSTR ext, ULONG buffer_size, LPWSTR buffer, LPWSTR* file_part) { - DOS_PATHNAME_TYPE type = RtlDetermineDosPathNameType_U(search); + RTL_PATH_TYPE type = RtlDetermineDosPathNameType_U(search); ULONG len = 0;
- if (type == RELATIVE_PATH) + if (type == RtlPathTypeRelative) { ULONG allocated = 0, needed, filelen; WCHAR *name = NULL; @@ -535,16 +535,16 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size)
switch (RtlDetermineDosPathNameType_U(name)) { - case UNC_PATH: /* \foo */ + case RtlPathTypeUncAbsolute: /* \foo */ ptr = skip_unc_prefix( name ); mark = (ptr - name); break;
- case DEVICE_PATH: /* \.\foo */ + case RtlPathTypeLocalDevice: /* \.\foo */ mark = 4; break;
- case ABSOLUTE_DRIVE_PATH: /* c:\foo */ + case RtlPathTypeDriveAbsolute: /* c:\foo */ reqsize = sizeof(WCHAR); tmp[0] = name[0]; ins_str = tmp; @@ -552,7 +552,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) mark = 3; break;
- case RELATIVE_DRIVE_PATH: /* c:foo */ + case RtlPathTypeDriveRelative: /* c:foo */ dep = 2; if (wcsnicmp( name, cd->Buffer, 2 )) { @@ -601,7 +601,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) } /* fall through */
- case RELATIVE_PATH: /* foo */ + case RtlPathTypeRelative: /* foo */ reqsize = cd->Length; ins_str = cd->Buffer; if (cd->Buffer[1] != ':') @@ -612,7 +612,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) else mark = 3; break;
- case ABSOLUTE_PATH: /* \xxx */ + case RtlPathTypeRooted: /* \xxx */ if (name[0] == '/') /* may be a Unix path */ { char *unix_name; @@ -667,7 +667,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) } break;
- case UNC_DOT_PATH: /* \. */ + case RtlPathTypeRootLocalDevice: /* \. */ reqsize = 4 * sizeof(WCHAR); dep = 3; tmp[0] = '\'; @@ -678,7 +678,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) mark = 4; break;
- case INVALID_PATH: + case RtlPathTypeUnknown: goto done; }
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 7d08ed06444..4f2127eb281 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -3968,7 +3968,7 @@ static HMODULE load_driver( const WCHAR *driver_name, const UNICODE_STRING *keyn HeapFree( GetProcessHeap(), 0, path ); path = str; } - else if (RtlDetermineDosPathNameType_U( path ) == RELATIVE_PATH) + else if (RtlDetermineDosPathNameType_U( path ) == RtlPathTypeRelative) { str = get_windir_path( path ); HeapFree( GetProcessHeap(), 0, path ); diff --git a/include/winternl.h b/include/winternl.h index d6fe4171fd5..6107035dcf7 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2409,18 +2409,17 @@ typedef struct _MEMORY_RANGE_ENTRY } MEMORY_RANGE_ENTRY, *PMEMORY_RANGE_ENTRY;
-/* return type of RtlDetermineDosPathNameType_U (FIXME: not the correct names) */ -typedef enum +typedef enum _RTL_PATH_TYPE { - INVALID_PATH = 0, - UNC_PATH, /* "//foo" */ - ABSOLUTE_DRIVE_PATH, /* "c:/foo" */ - RELATIVE_DRIVE_PATH, /* "c:foo" */ - ABSOLUTE_PATH, /* "/foo" */ - RELATIVE_PATH, /* "foo" */ - DEVICE_PATH, /* "//./foo" */ - UNC_DOT_PATH /* "//." */ -} DOS_PATHNAME_TYPE; + RtlPathTypeUnknown = 0, + RtlPathTypeUncAbsolute, /* "//foo" */ + RtlPathTypeDriveAbsolute, /* "c:/foo" */ + RtlPathTypeDriveRelative, /* "c:foo" */ + RtlPathTypeRooted, /* "/foo" */ + RtlPathTypeRelative, /* "foo" */ + RtlPathTypeLocalDevice, /* "//./foo" */ + RtlPathTypeRootLocalDevice /* "//." */ +} RTL_PATH_TYPE;
/*********************************************************************** @@ -4853,7 +4852,7 @@ NTSYSAPI NTSTATUS WINAPI RtlDestroyHandleTable(RTL_HANDLE_TABLE *); NTSYSAPI HANDLE WINAPI RtlDestroyHeap(HANDLE); NTSYSAPI void WINAPI RtlDestroyProcessParameters(RTL_USER_PROCESS_PARAMETERS*); NTSYSAPI NTSTATUS WINAPI RtlDestroyQueryDebugBuffer(PDEBUG_BUFFER); -NTSYSAPI DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U(PCWSTR); +NTSYSAPI RTL_PATH_TYPE WINAPI RtlDetermineDosPathNameType_U(PCWSTR); NTSYSAPI BOOLEAN WINAPI RtlDllShutdownInProgress(void); NTSYSAPI BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR); NTSYSAPI BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*);
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/ntdll/ntdll.spec | 1 + dlls/ntdll/path.c | 49 ++++++++++++++++++++++++++++++++++--------- include/winternl.h | 1 + 3 files changed, 41 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 83589a47ac8..a51cab8263f 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -750,6 +750,7 @@ # @ stub RtlGetFirstRange @ stdcall RtlGetFrame() @ stdcall RtlGetFullPathName_U(wstr long ptr ptr) +@ stdcall RtlGetFullPathName_UEx(wstr long ptr ptr ptr) @ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr) @ stdcall RtlGetLastNtStatus() @ stdcall RtlGetLastWin32Error() diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index e96597ab429..0efd35093ef 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -420,7 +420,7 @@ ULONG WINAPI RtlDosSearchPath_U(LPCWSTR paths, LPCWSTR search, LPCWSTR ext, /****************************************************************** * collapse_path * - * Helper for RtlGetFullPathName_U. + * Helper for RtlGetFullPathName_UEx. * Get rid of . and .. components in the path. */ static inline void collapse_path( WCHAR *path, UINT mark ) @@ -511,10 +511,10 @@ static const WCHAR *skip_unc_prefix( const WCHAR *ptr ) /****************************************************************** * get_full_path_helper * - * Helper for RtlGetFullPathName_U + * Helper for RtlGetFullPathName_UEx. * Note: name and buffer are allowed to point to the same memory spot */ -static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) +static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size, RTL_PATH_TYPE type) { ULONG reqsize = 0, mark = 0, dep = 0, deplen; LPWSTR ins_str = NULL; @@ -533,7 +533,7 @@ static ULONG get_full_path_helper(LPCWSTR name, LPWSTR buffer, ULONG size) else cd = &NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.DosPath;
- switch (RtlDetermineDosPathNameType_U(name)) + switch (type) { case RtlPathTypeUncAbsolute: /* \foo */ ptr = skip_unc_prefix( name ); @@ -705,6 +705,7 @@ done: return reqsize; }
+ /****************************************************************** * RtlGetFullPathName_U (NTDLL.@) * @@ -719,16 +720,43 @@ done: DWORD WINAPI RtlGetFullPathName_U(const WCHAR* name, ULONG size, WCHAR* buffer, WCHAR** file_part) { - WCHAR* ptr; - DWORD dosdev; - DWORD reqsize; - TRACE("(%s %lu %p %p)\n", debugstr_w(name), size, buffer, file_part);
+ return RtlGetFullPathName_UEx(name, size, buffer, file_part, NULL); +} + + +/****************************************************************** + * RtlGetFullPathName_UEx (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 too 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) + * + * type is an optional parameter that will receive the type of the path + * + */ +ULONG WINAPI RtlGetFullPathName_UEx(const WCHAR* name, ULONG size, WCHAR* buffer, + WCHAR** file_part, RTL_PATH_TYPE* type) +{ + WCHAR* ptr; + DWORD dosdev; + DWORD reqsize; + RTL_PATH_TYPE path_type; + + TRACE("(%s %lu %p %p %p %p)\n", debugstr_w(name), size, buffer, file_part, type); + if (!name || !*name) return 0;
if (file_part) *file_part = NULL;
+ path_type = RtlDetermineDosPathNameType_U(name); + + if (type) *type = path_type; + /* check for DOS device name */ dosdev = RtlIsDosDeviceName_U(name); if (dosdev) @@ -744,12 +772,12 @@ DWORD WINAPI RtlGetFullPathName_U(const WCHAR* name, ULONG size, WCHAR* buffer, return sz + 8; }
- reqsize = get_full_path_helper(name, buffer, size); + reqsize = get_full_path_helper(name, buffer, size, path_type); if (!reqsize) return 0; if (reqsize > size) { LPWSTR tmp = RtlAllocateHeap(GetProcessHeap(), 0, reqsize); - reqsize = get_full_path_helper(name, tmp, reqsize); + reqsize = get_full_path_helper(name, tmp, reqsize, path_type); if (reqsize + sizeof(WCHAR) > size) /* it may have worked the second time */ { RtlFreeHeap(GetProcessHeap(), 0, tmp); @@ -765,6 +793,7 @@ DWORD WINAPI RtlGetFullPathName_U(const WCHAR* name, ULONG size, WCHAR* buffer, return reqsize; }
+ /************************************************************************* * RtlGetLongestNtPathLength [NTDLL.@] * diff --git a/include/winternl.h b/include/winternl.h index 6107035dcf7..2b1e3d029ed 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -4933,6 +4933,7 @@ NTSYSAPI NTSTATUS WINAPI RtlGetExtendedContextLength2(ULONG,ULONG*,ULONG64); NTSYSAPI ULONG64 WINAPI RtlGetExtendedFeaturesMask(CONTEXT_EX*); NTSYSAPI TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void); NTSYSAPI ULONG WINAPI RtlGetFullPathName_U(PCWSTR,ULONG,PWSTR,PWSTR*); +NTSYSAPI ULONG WINAPI RtlGetFullPathName_UEx(PCWSTR,ULONG,PWSTR,PWSTR*,RTL_PATH_TYPE*); NTSYSAPI NTSTATUS WINAPI RtlGetGroupSecurityDescriptor(PSECURITY_DESCRIPTOR,PSID *,PBOOLEAN); NTSYSAPI NTSTATUS WINAPI RtlGetLastNtStatus(void); NTSYSAPI DWORD WINAPI RtlGetLastWin32Error(void);
With this [System Informer](https://systeminformer.sourceforge.io) no longer crashes on startup due to unimplemented `RtlGetFullPathName_UEx`.