Commit 9db147e5 authored by Alexandre Julliard's avatar Alexandre Julliard

Make DIR_nt_to_unix return STATUS_NO_SUCH_FILE instead of

STATUS_OBJECT_NAME_NOT_FOUND to indicate that the last component didn't exist to allow distinguishing it from legitimate errors. Export it from ntdll, renamed to wine_nt_to_unix_file_name.
parent eb1711bf
......@@ -1154,7 +1154,7 @@
@ varargs __wine_call_from_16_regs()
# Unix files
@ cdecl wine_get_unix_file_name(wstr) ntdll.wine_get_unix_file_name
@ cdecl wine_get_unix_file_name(wstr)
# Init code
@ cdecl __wine_kernel_init()
......
......@@ -999,3 +999,23 @@ BOOL WINAPI MoveFileA( LPCSTR source, LPCSTR dest )
{
return MoveFileExA( source, dest, MOVEFILE_COPY_ALLOWED );
}
/***********************************************************************
* wine_get_unix_file_name (KERNEL32.@) Not a Windows API
*
* Return the full Unix file name for a given path.
* Returned buffer must be freed by caller.
*/
char *wine_get_unix_file_name( LPCWSTR dosW )
{
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
NTSTATUS status;
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL;
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FALSE, FALSE );
RtlFreeUnicodeString( &nt_name );
if (status && status != STATUS_NO_SUCH_FILE) return NULL;
return unix_name.Buffer;
}
......@@ -795,16 +795,16 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name )
/******************************************************************************
* DIR_nt_to_unix
* wine_nt_to_unix_file_name (NTDLL.@) Not a Windows API
*
* Convert a file name from NT namespace to Unix namespace.
*
* If check_last is 0, the last path element doesn't have to exist;
* in that case STATUS_OBJECT_NAME_NOT_FOUND is returned, but the
* in that case STATUS_NO_SUCH_FILE is returned, but the
* unix name is still filled in properly.
*/
NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
int check_last, int check_case )
NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
BOOLEAN check_last, BOOLEAN check_case )
{
static const WCHAR uncW[] = {'U','N','C','\\'};
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
......@@ -931,6 +931,7 @@ NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret
{
unix_name[pos] = '/';
unix_name[pos + 1 + ret] = 0;
status = STATUS_NO_SUCH_FILE;
break;
}
}
......@@ -960,26 +961,6 @@ done:
}
/***********************************************************************
* wine_get_unix_file_name (NTDLL.@) Not a Windows API
*
* Return the full Unix file name for a given path.
* Returned buffer must be freed by caller.
*/
char *wine_get_unix_file_name( LPCWSTR dosW )
{
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
NTSTATUS status;
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL;
status = DIR_nt_to_unix( &nt_name, &unix_name, FALSE, FALSE );
RtlFreeUnicodeString( &nt_name );
if (status && status != STATUS_OBJECT_NAME_NOT_FOUND) return NULL;
return unix_name.Buffer;
}
/******************************************************************
* RtlDoesFileExists_U (NTDLL.@)
*/
......@@ -990,7 +971,7 @@ BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
BOOLEAN ret;
if (!RtlDosPathNameToNtPathName_U( file_name, &nt_name, NULL, NULL )) return FALSE;
ret = (DIR_nt_to_unix( &nt_name, &unix_name, TRUE, FALSE ) == STATUS_SUCCESS);
ret = (wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, FALSE ) == STATUS_SUCCESS);
if (ret) RtlFreeAnsiString( &unix_name );
RtlFreeUnicodeString( &nt_name );
return ret;
......
......@@ -148,10 +148,10 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
check_last = (disposition == FILE_OPEN || disposition == FILE_OVERWRITE);
io->u.Status = DIR_nt_to_unix( attr->ObjectName, &unix_name, check_last,
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, check_last,
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
if (!check_last && io->u.Status == STATUS_OBJECT_NAME_NOT_FOUND)
if (!check_last && io->u.Status == STATUS_NO_SUCH_FILE)
{
created = TRUE;
io->u.Status = STATUS_SUCCESS;
......@@ -1025,8 +1025,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
ANSI_STRING unix_name;
NTSTATUS status;
if (!(status = DIR_nt_to_unix( attr->ObjectName, &unix_name,
TRUE, !(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
if (!(status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name,
TRUE, !(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
{
struct stat st;
......
......@@ -1124,7 +1124,7 @@
@ cdecl __wine_set_signal_handler(long ptr)
# Filesystem
@ cdecl wine_get_unix_file_name(wstr)
@ cdecl wine_nt_to_unix_file_name(ptr ptr long long)
################################################################
# Wine dll separation hacks, these will go away, don't use them
......
......@@ -85,8 +85,6 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
/* file I/O */
extern NTSTATUS FILE_GetNtStatus(void);
extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
extern NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
int check_last, int check_case );
/* virtual memory */
typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
......
......@@ -1511,6 +1511,11 @@ NTSTATUS WINAPI RtlWalkHeap(HANDLE,PVOID);
NTSTATUS WINAPI RtlpWaitForCriticalSection(RTL_CRITICAL_SECTION *);
NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *);
/* Wine internal functions */
extern NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
BOOLEAN check_last, BOOLEAN check_case );
/***********************************************************************
* Inline functions
*/
......
......@@ -64,7 +64,7 @@ static int running_under_wine ()
HMODULE module = GetModuleHandleA("ntdll.dll");
if (!module) return 0;
return (GetProcAddress(module, "wine_get_unix_file_name") != NULL);
return (GetProcAddress(module, "wine_server_call") != NULL);
}
void print_version ()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment