Pass the creation disposition to wine_nt_to_unix_file_name so that it
can return the correct error code in all cases. Changed MoveFileExW to use wine_nt_to_unix_file_name to avoid computing the NT name twice. Fixed crash in GetDriveTypeW with a NULL root.
This commit is contained in:
parent
1c279bfd89
commit
cf67839bc4
|
@ -826,7 +826,7 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
HANDLE source_handle = 0, dest_handle;
|
HANDLE source_handle = 0, dest_handle;
|
||||||
char *source_unix = NULL, *dest_unix = NULL;
|
ANSI_STRING source_unix, dest_unix;
|
||||||
|
|
||||||
TRACE("(%s,%s,%04lx)\n", debugstr_w(source), debugstr_w(dest), flag);
|
TRACE("(%s,%s,%04lx)\n", debugstr_w(source), debugstr_w(dest), flag);
|
||||||
|
|
||||||
|
@ -843,6 +843,8 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
SetLastError( ERROR_PATH_NOT_FOUND );
|
SetLastError( ERROR_PATH_NOT_FOUND );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
source_unix.Buffer = NULL;
|
||||||
|
dest_unix.Buffer = NULL;
|
||||||
attr.Length = sizeof(attr);
|
attr.Length = sizeof(attr);
|
||||||
attr.RootDirectory = 0;
|
attr.RootDirectory = 0;
|
||||||
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
attr.Attributes = OBJ_CASE_INSENSITIVE;
|
||||||
|
@ -851,6 +853,8 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
attr.SecurityQualityOfService = NULL;
|
attr.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
status = NtOpenFile( &source_handle, 0, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
status = NtOpenFile( &source_handle, 0, &attr, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
|
status = wine_nt_to_unix_file_name( &nt_name, &source_unix, FILE_OPEN, FALSE );
|
||||||
RtlFreeUnicodeString( &nt_name );
|
RtlFreeUnicodeString( &nt_name );
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -864,12 +868,6 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(source_unix = wine_get_unix_file_name( source ))) /* should not happen */
|
|
||||||
{
|
|
||||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
{
|
{
|
||||||
if (flag & MOVEFILE_REPLACE_EXISTING) /* cannot replace directory */
|
if (flag & MOVEFILE_REPLACE_EXISTING) /* cannot replace directory */
|
||||||
|
@ -889,41 +887,45 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
}
|
}
|
||||||
status = NtOpenFile( &dest_handle, GENERIC_READ | GENERIC_WRITE, &attr, &io, 0,
|
status = NtOpenFile( &dest_handle, GENERIC_READ | GENERIC_WRITE, &attr, &io, 0,
|
||||||
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT );
|
||||||
RtlFreeUnicodeString( &nt_name );
|
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
NtClose( dest_handle );
|
NtClose( dest_handle );
|
||||||
if (!(flag & MOVEFILE_REPLACE_EXISTING))
|
if (!(flag & MOVEFILE_REPLACE_EXISTING))
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_ALREADY_EXISTS );
|
SetLastError( ERROR_ALREADY_EXISTS );
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (status != STATUS_OBJECT_NAME_NOT_FOUND)
|
else if (status != STATUS_OBJECT_NAME_NOT_FOUND)
|
||||||
{
|
{
|
||||||
SetLastError( RtlNtStatusToDosError(status) );
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!(dest_unix = wine_get_unix_file_name( dest ))) /* should not happen */
|
|
||||||
|
status = wine_nt_to_unix_file_name( &nt_name, &dest_unix, FILE_OPEN_IF, FALSE );
|
||||||
|
RtlFreeUnicodeString( &nt_name );
|
||||||
|
if (status != STATUS_SUCCESS && status != STATUS_NO_SUCH_FILE)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_FILE_NOT_FOUND );
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now perform the rename */
|
/* now perform the rename */
|
||||||
|
|
||||||
if (rename( source_unix, dest_unix ) == -1)
|
if (rename( source_unix.Buffer, dest_unix.Buffer ) == -1)
|
||||||
{
|
{
|
||||||
if (errno == EXDEV && (flag & MOVEFILE_COPY_ALLOWED))
|
if (errno == EXDEV && (flag & MOVEFILE_COPY_ALLOWED))
|
||||||
{
|
{
|
||||||
NtClose( source_handle );
|
NtClose( source_handle );
|
||||||
HeapFree( GetProcessHeap(), 0, source_unix );
|
RtlFreeAnsiString( &source_unix );
|
||||||
HeapFree( GetProcessHeap(), 0, dest_unix );
|
RtlFreeAnsiString( &dest_unix );
|
||||||
return (CopyFileW( source, dest, TRUE ) && DeleteFileW( source ));
|
return (CopyFileW( source, dest, TRUE ) && DeleteFileW( source ));
|
||||||
}
|
}
|
||||||
FILE_SetDosError();
|
FILE_SetDosError();
|
||||||
/* if we created the destination, remove it */
|
/* if we created the destination, remove it */
|
||||||
if (io.Information == FILE_CREATED) unlink( dest_unix );
|
if (io.Information == FILE_CREATED) unlink( dest_unix.Buffer );
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,26 +934,26 @@ BOOL WINAPI MoveFileExW( LPCWSTR source, LPCWSTR dest, DWORD flag )
|
||||||
if (is_executable( source ) != is_executable( dest ))
|
if (is_executable( source ) != is_executable( dest ))
|
||||||
{
|
{
|
||||||
struct stat fstat;
|
struct stat fstat;
|
||||||
if (stat( dest_unix, &fstat ) != -1)
|
if (stat( dest_unix.Buffer, &fstat ) != -1)
|
||||||
{
|
{
|
||||||
if (is_executable( dest ))
|
if (is_executable( dest ))
|
||||||
/* set executable bit where read bit is set */
|
/* set executable bit where read bit is set */
|
||||||
fstat.st_mode |= (fstat.st_mode & 0444) >> 2;
|
fstat.st_mode |= (fstat.st_mode & 0444) >> 2;
|
||||||
else
|
else
|
||||||
fstat.st_mode &= ~0111;
|
fstat.st_mode &= ~0111;
|
||||||
chmod( dest_unix, fstat.st_mode );
|
chmod( dest_unix.Buffer, fstat.st_mode );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NtClose( source_handle );
|
NtClose( source_handle );
|
||||||
HeapFree( GetProcessHeap(), 0, source_unix );
|
RtlFreeAnsiString( &source_unix );
|
||||||
HeapFree( GetProcessHeap(), 0, dest_unix );
|
RtlFreeAnsiString( &dest_unix );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
if (source_handle) NtClose( source_handle );
|
if (source_handle) NtClose( source_handle );
|
||||||
if (source_unix) HeapFree( GetProcessHeap(), 0, source_unix );
|
RtlFreeAnsiString( &source_unix );
|
||||||
if (dest_unix) HeapFree( GetProcessHeap(), 0, dest_unix );
|
RtlFreeAnsiString( &dest_unix );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1014,7 +1016,7 @@ char *wine_get_unix_file_name( LPCWSTR dosW )
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL;
|
if (!RtlDosPathNameToNtPathName_U( dosW, &nt_name, NULL, NULL )) return NULL;
|
||||||
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FALSE, FALSE );
|
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN_IF, FALSE );
|
||||||
RtlFreeUnicodeString( &nt_name );
|
RtlFreeUnicodeString( &nt_name );
|
||||||
if (status && status != STATUS_NO_SUCH_FILE) return NULL;
|
if (status && status != STATUS_NO_SUCH_FILE) return NULL;
|
||||||
return unix_name.Buffer;
|
return unix_name.Buffer;
|
||||||
|
|
|
@ -165,7 +165,7 @@ static BOOL open_device_root( LPCWSTR root, HANDLE *handle )
|
||||||
|
|
||||||
|
|
||||||
/* fetch the type of a drive from the registry */
|
/* fetch the type of a drive from the registry */
|
||||||
static UINT get_registry_drive_type( int drive )
|
static UINT get_registry_drive_type( const WCHAR *root )
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
UNICODE_STRING nameW;
|
UNICODE_STRING nameW;
|
||||||
|
@ -173,11 +173,18 @@ static UINT get_registry_drive_type( int drive )
|
||||||
DWORD dummy;
|
DWORD dummy;
|
||||||
UINT ret = DRIVE_UNKNOWN;
|
UINT ret = DRIVE_UNKNOWN;
|
||||||
char tmp[32 + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
|
char tmp[32 + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
|
||||||
|
WCHAR path[MAX_PATH];
|
||||||
WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\',
|
WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\',
|
||||||
'W','i','n','e','\\','W','i','n','e','\\',
|
'W','i','n','e','\\','W','i','n','e','\\',
|
||||||
'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0};
|
'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0};
|
||||||
static const WCHAR TypeW[] = {'T','y','p','e',0};
|
static const WCHAR TypeW[] = {'T','y','p','e',0};
|
||||||
|
|
||||||
|
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
GetCurrentDirectoryW( MAX_PATH, path );
|
||||||
|
root = path;
|
||||||
|
}
|
||||||
attr.Length = sizeof(attr);
|
attr.Length = sizeof(attr);
|
||||||
attr.RootDirectory = 0;
|
attr.RootDirectory = 0;
|
||||||
attr.ObjectName = &nameW;
|
attr.ObjectName = &nameW;
|
||||||
|
@ -185,7 +192,7 @@ static UINT get_registry_drive_type( int drive )
|
||||||
attr.SecurityDescriptor = NULL;
|
attr.SecurityDescriptor = NULL;
|
||||||
attr.SecurityQualityOfService = NULL;
|
attr.SecurityQualityOfService = NULL;
|
||||||
RtlInitUnicodeString( &nameW, driveW );
|
RtlInitUnicodeString( &nameW, driveW );
|
||||||
nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + drive;
|
nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = root[0];
|
||||||
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return DRIVE_UNKNOWN;
|
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) return DRIVE_UNKNOWN;
|
||||||
|
|
||||||
RtlInitUnicodeString( &nameW, TypeW );
|
RtlInitUnicodeString( &nameW, TypeW );
|
||||||
|
@ -1091,7 +1098,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
|
||||||
nt_buffer[3] = '\\';
|
nt_buffer[3] = '\\';
|
||||||
strcpyW( nt_buffer + 4, name );
|
strcpyW( nt_buffer + 4, name );
|
||||||
RtlInitUnicodeString( &nt_name, nt_buffer );
|
RtlInitUnicodeString( &nt_name, nt_buffer );
|
||||||
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, TRUE );
|
status = wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, TRUE );
|
||||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1132,7 +1139,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
|
||||||
for (i = 1; i <= 9; i++)
|
for (i = 1; i <= 9; i++)
|
||||||
{
|
{
|
||||||
nt_buffer[7] = '0' + i;
|
nt_buffer[7] = '0' + i;
|
||||||
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, TRUE ))
|
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, TRUE ))
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString( &unix_name );
|
RtlFreeAnsiString( &unix_name );
|
||||||
if (p + 5 >= target + bufsize)
|
if (p + 5 >= target + bufsize)
|
||||||
|
@ -1150,7 +1157,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
|
||||||
for (i = 1; i <= 9; i++)
|
for (i = 1; i <= 9; i++)
|
||||||
{
|
{
|
||||||
nt_buffer[7] = '0' + i;
|
nt_buffer[7] = '0' + i;
|
||||||
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, TRUE ))
|
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, TRUE ))
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString( &unix_name );
|
RtlFreeAnsiString( &unix_name );
|
||||||
if (p + 5 >= target + bufsize)
|
if (p + 5 >= target + bufsize)
|
||||||
|
@ -1171,7 +1178,7 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
|
||||||
for (i = 0; i < 26; i++)
|
for (i = 0; i < 26; i++)
|
||||||
{
|
{
|
||||||
nt_buffer[4] = 'a' + i;
|
nt_buffer[4] = 'a' + i;
|
||||||
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, TRUE ))
|
if (!wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, TRUE ))
|
||||||
{
|
{
|
||||||
RtlFreeAnsiString( &unix_name );
|
RtlFreeAnsiString( &unix_name );
|
||||||
if (p + 3 >= target + bufsize)
|
if (p + 3 >= target + bufsize)
|
||||||
|
@ -1337,7 +1344,7 @@ UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
|
||||||
SetLastError( RtlNtStatusToDosError(status) );
|
SetLastError( RtlNtStatusToDosError(status) );
|
||||||
ret = DRIVE_UNKNOWN;
|
ret = DRIVE_UNKNOWN;
|
||||||
}
|
}
|
||||||
else if ((ret = get_registry_drive_type( toupperW(root[0]) - 'A' )) == DRIVE_UNKNOWN)
|
else if ((ret = get_registry_drive_type( root )) == DRIVE_UNKNOWN)
|
||||||
{
|
{
|
||||||
switch (info.DeviceType)
|
switch (info.DeviceType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -938,12 +938,12 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name )
|
||||||
*
|
*
|
||||||
* Convert a file name from NT namespace to Unix namespace.
|
* Convert a file name from NT namespace to Unix namespace.
|
||||||
*
|
*
|
||||||
* If check_last is 0, the last path element doesn't have to exist;
|
* If disposition is not FILE_OPEN or FILE_OVERWRITTE, the last path
|
||||||
* in that case STATUS_NO_SUCH_FILE is returned, but the
|
* element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is
|
||||||
* unix name is still filled in properly.
|
* returned, but the unix name is still filled in properly.
|
||||||
*/
|
*/
|
||||||
NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
||||||
BOOLEAN check_last, BOOLEAN check_case )
|
UINT disposition, BOOLEAN check_case )
|
||||||
{
|
{
|
||||||
static const WCHAR uncW[] = {'U','N','C','\\'};
|
static const WCHAR uncW[] = {'U','N','C','\\'};
|
||||||
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
|
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
|
||||||
|
@ -1010,25 +1010,33 @@ NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *un
|
||||||
|
|
||||||
ret = ntdll_wcstoumbs( 0, name, name_len, unix_name + pos, unix_len - pos - 1,
|
ret = ntdll_wcstoumbs( 0, name, name_len, unix_name + pos, unix_len - pos - 1,
|
||||||
NULL, &used_default );
|
NULL, &used_default );
|
||||||
if (ret > 0 && !used_default) /* if we used the default char the name didn't convert properly */
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
unix_name[pos + ret] = 0;
|
|
||||||
for (p = unix_name + pos ; *p; p++) if (*p == '\\') *p = '/';
|
|
||||||
if (!stat( unix_name, &st )) goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (name_len && IS_SEPARATOR(*name))
|
while (name_len && IS_SEPARATOR(*name))
|
||||||
{
|
{
|
||||||
name++;
|
name++;
|
||||||
name_len--;
|
name_len--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret > 0 && !used_default) /* if we used the default char the name didn't convert properly */
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
unix_name[pos + ret] = 0;
|
||||||
|
for (p = unix_name + pos ; *p; p++) if (*p == '\\') *p = '/';
|
||||||
|
if (!stat( unix_name, &st ))
|
||||||
|
{
|
||||||
|
/* creation fails with STATUS_ACCESS_DENIED for the root of the drive */
|
||||||
|
if (disposition == FILE_CREATE)
|
||||||
|
return name_len ? STATUS_OBJECT_NAME_COLLISION : STATUS_ACCESS_DENIED;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!name_len) /* empty name -> drive root doesn't exist */
|
if (!name_len) /* empty name -> drive root doesn't exist */
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
||||||
return STATUS_OBJECT_PATH_NOT_FOUND;
|
return STATUS_OBJECT_PATH_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if (check_case && check_last)
|
if (check_case && (disposition == FILE_OPEN || disposition == FILE_OVERWRITE))
|
||||||
{
|
{
|
||||||
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
||||||
return STATUS_OBJECT_NAME_NOT_FOUND;
|
return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
@ -1063,21 +1071,28 @@ NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *un
|
||||||
status = find_file_in_dir( unix_name, pos, name, end - name, check_case );
|
status = find_file_in_dir( unix_name, pos, name, end - name, check_case );
|
||||||
|
|
||||||
/* if this is the last element, not finding it is not necessarily fatal */
|
/* if this is the last element, not finding it is not necessarily fatal */
|
||||||
if (!name_len && status == STATUS_OBJECT_PATH_NOT_FOUND)
|
if (!name_len)
|
||||||
{
|
{
|
||||||
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
if (status == STATUS_OBJECT_PATH_NOT_FOUND)
|
||||||
if (!check_last)
|
|
||||||
{
|
{
|
||||||
ret = ntdll_wcstoumbs( 0, name, end - name, unix_name + pos + 1,
|
status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
MAX_DIR_ENTRY_LEN, NULL, &used_default );
|
if (disposition != FILE_OPEN && disposition != FILE_OVERWRITE)
|
||||||
if (ret > 0 && !used_default)
|
|
||||||
{
|
{
|
||||||
unix_name[pos] = '/';
|
ret = ntdll_wcstoumbs( 0, name, end - name, unix_name + pos + 1,
|
||||||
unix_name[pos + 1 + ret] = 0;
|
MAX_DIR_ENTRY_LEN, NULL, &used_default );
|
||||||
status = STATUS_NO_SUCH_FILE;
|
if (ret > 0 && !used_default)
|
||||||
break;
|
{
|
||||||
|
unix_name[pos] = '/';
|
||||||
|
unix_name[pos + 1 + ret] = 0;
|
||||||
|
status = STATUS_NO_SUCH_FILE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (status == STATUS_SUCCESS && disposition == FILE_CREATE)
|
||||||
|
{
|
||||||
|
status = STATUS_OBJECT_NAME_COLLISION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status != STATUS_SUCCESS)
|
if (status != STATUS_SUCCESS)
|
||||||
|
@ -1114,7 +1129,7 @@ BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
|
||||||
BOOLEAN ret;
|
BOOLEAN ret;
|
||||||
|
|
||||||
if (!RtlDosPathNameToNtPathName_U( file_name, &nt_name, NULL, NULL )) return FALSE;
|
if (!RtlDosPathNameToNtPathName_U( file_name, &nt_name, NULL, NULL )) return FALSE;
|
||||||
ret = (wine_nt_to_unix_file_name( &nt_name, &unix_name, TRUE, FALSE ) == STATUS_SUCCESS);
|
ret = (wine_nt_to_unix_file_name( &nt_name, &unix_name, FILE_OPEN, FALSE ) == STATUS_SUCCESS);
|
||||||
if (ret) RtlFreeAnsiString( &unix_name );
|
if (ret) RtlFreeAnsiString( &unix_name );
|
||||||
RtlFreeUnicodeString( &nt_name );
|
RtlFreeUnicodeString( &nt_name );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -131,7 +131,7 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
ULONG options, PVOID ea_buffer, ULONG ea_length )
|
ULONG options, PVOID ea_buffer, ULONG ea_length )
|
||||||
{
|
{
|
||||||
ANSI_STRING unix_name;
|
ANSI_STRING unix_name;
|
||||||
int check_last, created = FALSE;
|
int created = FALSE;
|
||||||
|
|
||||||
TRACE("handle=%p access=%08lx name=%s objattr=%08lx root=%p sec=%p io=%p alloc_size=%p\n"
|
TRACE("handle=%p access=%08lx name=%s objattr=%08lx root=%p sec=%p io=%p alloc_size=%p\n"
|
||||||
"attr=%08lx sharing=%08lx disp=%ld options=%08lx ea=%p.0x%08lx\n",
|
"attr=%08lx sharing=%08lx disp=%ld options=%08lx ea=%p.0x%08lx\n",
|
||||||
|
@ -146,12 +146,11 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB
|
||||||
}
|
}
|
||||||
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
||||||
|
|
||||||
check_last = (disposition == FILE_OPEN || disposition == FILE_OVERWRITE);
|
io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, disposition,
|
||||||
|
|
||||||
io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, check_last,
|
|
||||||
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
|
!(attr->Attributes & OBJ_CASE_INSENSITIVE) );
|
||||||
|
|
||||||
if (!check_last && io->u.Status == STATUS_NO_SUCH_FILE)
|
if (io->u.Status == STATUS_NO_SUCH_FILE &&
|
||||||
|
disposition != FILE_OPEN && disposition != FILE_OVERWRITE)
|
||||||
{
|
{
|
||||||
created = TRUE;
|
created = TRUE;
|
||||||
io->u.Status = STATUS_SUCCESS;
|
io->u.Status = STATUS_SUCCESS;
|
||||||
|
@ -1025,8 +1024,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
|
||||||
ANSI_STRING unix_name;
|
ANSI_STRING unix_name;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
|
||||||
if (!(status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name,
|
if (!(status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, FILE_OPEN,
|
||||||
TRUE, !(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
|
!(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
|
|
@ -1514,7 +1514,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection(RTL_CRITICAL_SECTION *);
|
||||||
/* Wine internal functions */
|
/* Wine internal functions */
|
||||||
|
|
||||||
extern NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
extern NTSTATUS wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
|
||||||
BOOLEAN check_last, BOOLEAN check_case );
|
UINT disposition, BOOLEAN check_case );
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Inline functions
|
* Inline functions
|
||||||
|
|
Loading…
Reference in New Issue