diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 50f4acf5926..95581ec6fad 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -560,6 +560,7 @@ @ stdcall RtlDoesFileExists_U(wstr) # @ stub RtlDosApplyFileIsolationRedirection_Ustr @ stdcall RtlDosPathNameToNtPathName_U(wstr ptr ptr ptr) +@ stdcall RtlDosPathNameToNtPathName_U_WithStatus(wstr ptr ptr ptr) @ stdcall RtlDosSearchPath_U(wstr wstr wstr long ptr ptr) # @ stub RtlDosSearchPath_Ustr @ stdcall RtlDowncaseUnicodeChar(long) diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index e76ce3f5945..f3dc93fc1f7 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -325,9 +325,8 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name ) return 0; } - /************************************************************************** - * RtlDosPathNameToNtPathName_U [NTDLL.@] + * RtlDosPathNameToNtPathName_U_WithStatus [NTDLL.@] * * dos_path: a DOS path name (fully qualified or not) * ntpath: pointer to a UNICODE_STRING to hold the converted @@ -338,18 +337,15 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name ) * FIXME: * + fill the cd structure */ -BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, - PUNICODE_STRING ntpath, - PWSTR* file_part, - CURDIR* cd) +NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, UNICODE_STRING *ntpath, + WCHAR **file_part, CURDIR *cd) { static const WCHAR LongFileNamePfxW[] = {'\\','\\','?','\\'}; ULONG sz, offset; WCHAR local[MAX_PATH]; LPWSTR ptr; - TRACE("(%s,%p,%p,%p)\n", - debugstr_w(dos_path), ntpath, file_part, cd); + TRACE("(%s,%p,%p,%p)\n", debugstr_w(dos_path), ntpath, file_part, cd); if (cd) { @@ -357,14 +353,15 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, memset(cd, 0, sizeof(*cd)); } - if (!dos_path || !*dos_path) return FALSE; + if (!dos_path || !*dos_path) + return STATUS_OBJECT_NAME_INVALID; if (!strncmpW(dos_path, LongFileNamePfxW, 4)) { ntpath->Length = strlenW(dos_path) * sizeof(WCHAR); ntpath->MaximumLength = ntpath->Length + sizeof(WCHAR); ntpath->Buffer = RtlAllocateHeap(GetProcessHeap(), 0, ntpath->MaximumLength); - if (!ntpath->Buffer) return FALSE; + if (!ntpath->Buffer) return STATUS_NO_MEMORY; memcpy( ntpath->Buffer, dos_path, ntpath->MaximumLength ); ntpath->Buffer[1] = '?'; /* change \\?\ to \??\ */ if (file_part) @@ -372,22 +369,23 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, if ((ptr = strrchrW( ntpath->Buffer, '\\' )) && ptr[1]) *file_part = ptr + 1; else *file_part = NULL; } - return TRUE; + return STATUS_SUCCESS; } ptr = local; sz = RtlGetFullPathName_U(dos_path, sizeof(local), ptr, file_part); - if (sz == 0) return FALSE; + if (sz == 0) return STATUS_OBJECT_NAME_INVALID; + if (sz > sizeof(local)) { - if (!(ptr = RtlAllocateHeap(GetProcessHeap(), 0, sz))) return FALSE; + if (!(ptr = RtlAllocateHeap(GetProcessHeap(), 0, sz))) return STATUS_NO_MEMORY; sz = RtlGetFullPathName_U(dos_path, sz, ptr, file_part); } sz += (1 /* NUL */ + 4 /* unc\ */ + 4 /* \??\ */) * sizeof(WCHAR); if (sz > MAXWORD) { if (ptr != local) RtlFreeHeap(GetProcessHeap(), 0, ptr); - return FALSE; + return STATUS_OBJECT_NAME_INVALID; } ntpath->MaximumLength = sz; @@ -395,7 +393,7 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, if (!ntpath->Buffer) { if (ptr != local) RtlFreeHeap(GetProcessHeap(), 0, ptr); - return FALSE; + return STATUS_NO_MEMORY; } strcpyW(ntpath->Buffer, NTDosPrefixW); @@ -422,7 +420,20 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, /* FIXME: cd filling */ if (ptr != local) RtlFreeHeap(GetProcessHeap(), 0, ptr); - return TRUE; + return STATUS_SUCCESS; +} + +/************************************************************************** + * RtlDosPathNameToNtPathName_U [NTDLL.@] + * + * See RtlDosPathNameToNtPathName_U_WithStatus + */ +BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(PCWSTR dos_path, + PUNICODE_STRING ntpath, + PWSTR* file_part, + CURDIR* cd) +{ + return RtlDosPathNameToNtPathName_U_WithStatus(dos_path, ntpath, file_part, cd) == STATUS_SUCCESS; } /****************************************************************** diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c index c19189d007b..9369e1c4285 100644 --- a/dlls/ntdll/tests/path.c +++ b/dlls/ntdll/tests/path.c @@ -28,7 +28,7 @@ static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name ); static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN ); static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN); static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**); - +static NTSTATUS (WINAPI *pRtlDosPathNameToNtPathName_U_WithStatus)(const WCHAR*, UNICODE_STRING*, WCHAR**, CURDIR*); static void test_RtlDetermineDosPathNameType_U(void) { @@ -343,6 +343,35 @@ static void test_RtlGetFullPathName_U(void) } } +static void test_RtlDosPathNameToNtPathName_U_WithStatus(void) +{ + static const WCHAR emptyW[] = { 0 }; + WCHAR path[MAX_PATH]; + UNICODE_STRING nameW; + NTSTATUS status; + + if (!pRtlDosPathNameToNtPathName_U_WithStatus) + { + win_skip("RtlDosPathNameToNtPathName_U_WithStatus() is not supported.\n"); + return; + } + + GetCurrentDirectoryW( MAX_PATH, path ); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( path, &nameW, NULL, NULL ); + ok(!status, "Failed convert to nt path, %#x.\n", status); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( NULL, &nameW, NULL, NULL ); + ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */, + "Unexpected status %#x.\n", status); + + status = pRtlDosPathNameToNtPathName_U_WithStatus( emptyW, &nameW, NULL, NULL ); + ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */, + "Unexpected status %#x.\n", status); + + RtlFreeUnicodeString( &nameW ); +} + START_TEST(path) { HMODULE mod = GetModuleHandleA("ntdll.dll"); @@ -359,9 +388,11 @@ START_TEST(path) pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString"); pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3"); pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U"); + pRtlDosPathNameToNtPathName_U_WithStatus = (void *)GetProcAddress(mod, "RtlDosPathNameToNtPathName_U_WithStatus"); test_RtlDetermineDosPathNameType_U(); test_RtlIsDosDeviceName_U(); test_RtlIsNameLegalDOS8Dot3(); test_RtlGetFullPathName_U(); + test_RtlDosPathNameToNtPathName_U_WithStatus(); } diff --git a/include/winternl.h b/include/winternl.h index ec8b3874714..571296fe509 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2508,6 +2508,7 @@ NTSYSAPI DOS_PATHNAME_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*); +NTSYSAPI NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(PCWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); NTSYSAPI ULONG WINAPI RtlDosSearchPath_U(LPCWSTR, LPCWSTR, LPCWSTR, ULONG, LPWSTR, LPWSTR*); NTSYSAPI WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR); NTSYSAPI NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);