mirror of
https://github.com/reactos/wine.git
synced 2025-02-05 11:40:06 +00:00
ntdll: Add support for converting file names to Unix when a root directory is specified.
This commit is contained in:
parent
a420a207e3
commit
d97149b708
@ -2236,17 +2236,20 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
name_len--;
|
||||
}
|
||||
|
||||
if (ret > 0 && !used_default) /* if we used the default char the name didn't convert properly */
|
||||
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 ((!redirect || !strstr( unix_name, "/windows/")) && !stat( unix_name, &st ))
|
||||
if (!redirect || (!strstr( unix_name, "/windows/") && strncmp( unix_name, "windows/", 8 )))
|
||||
{
|
||||
/* 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;
|
||||
return STATUS_SUCCESS;
|
||||
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;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2325,6 +2328,80 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* nt_to_unix_file_name_attr
|
||||
*/
|
||||
NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
|
||||
UINT disposition )
|
||||
{
|
||||
static const WCHAR invalid_charsW[] = { INVALID_NT_CHARS, 0 };
|
||||
enum server_fd_type type;
|
||||
int old_cwd, root_fd, needs_close;
|
||||
const WCHAR *name, *p;
|
||||
char *unix_name;
|
||||
int name_len, unix_len;
|
||||
NTSTATUS status;
|
||||
BOOLEAN check_case = !(attr->Attributes & OBJ_CASE_INSENSITIVE);
|
||||
|
||||
if (!attr->RootDirectory) /* without root dir fall back to normal lookup */
|
||||
return wine_nt_to_unix_file_name( attr->ObjectName, unix_name_ret, disposition, check_case );
|
||||
|
||||
name = attr->ObjectName->Buffer;
|
||||
name_len = attr->ObjectName->Length / sizeof(WCHAR);
|
||||
|
||||
if (name_len && IS_SEPARATOR(name[0])) return STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||
|
||||
/* check for invalid characters */
|
||||
for (p = name; p < name + name_len; p++)
|
||||
if (*p < 32 || strchrW( invalid_charsW, *p )) return STATUS_OBJECT_NAME_INVALID;
|
||||
|
||||
unix_len = ntdll_wcstoumbs( 0, name, name_len, NULL, 0, NULL, NULL );
|
||||
unix_len += MAX_DIR_ENTRY_LEN + 3;
|
||||
if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len )))
|
||||
return STATUS_NO_MEMORY;
|
||||
unix_name[0] = '.';
|
||||
|
||||
if (!(status = server_get_unix_fd( attr->RootDirectory, FILE_READ_DATA, &root_fd,
|
||||
&needs_close, &type, NULL )))
|
||||
{
|
||||
if (type != FD_TYPE_DIR)
|
||||
{
|
||||
if (needs_close) close( root_fd );
|
||||
status = STATUS_BAD_DEVICE_TYPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
RtlEnterCriticalSection( &dir_section );
|
||||
if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1)
|
||||
{
|
||||
status = lookup_unix_name( name, name_len, &unix_name, unix_len, 1,
|
||||
disposition, check_case );
|
||||
if (fchdir( old_cwd ) == -1) chdir( "/" );
|
||||
}
|
||||
else status = FILE_GetNtStatus();
|
||||
RtlLeaveCriticalSection( &dir_section );
|
||||
if (old_cwd != -1) close( old_cwd );
|
||||
if (needs_close) close( root_fd );
|
||||
}
|
||||
}
|
||||
else if (status == STATUS_OBJECT_TYPE_MISMATCH) status = STATUS_BAD_DEVICE_TYPE;
|
||||
|
||||
if (status == STATUS_SUCCESS || status == STATUS_NO_SUCH_FILE)
|
||||
{
|
||||
TRACE( "%s -> %s\n", debugstr_us(attr->ObjectName), debugstr_a(unix_name) );
|
||||
unix_name_ret->Buffer = unix_name;
|
||||
unix_name_ret->Length = strlen(unix_name);
|
||||
unix_name_ret->MaximumLength = unix_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE( "%s not found in %s\n", debugstr_w(name), unix_name );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* wine_nt_to_unix_file_name (NTDLL.@) Not a Windows API
|
||||
*
|
||||
|
@ -115,9 +115,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
|
||||
|
||||
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
||||
|
||||
if (attr->RootDirectory ||
|
||||
(io->u.Status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, disposition,
|
||||
!(attr->Attributes & OBJ_CASE_INSENSITIVE) )) == STATUS_BAD_DEVICE_TYPE)
|
||||
if ((io->u.Status = nt_to_unix_file_name_attr( attr, &unix_name, disposition )) == STATUS_BAD_DEVICE_TYPE)
|
||||
{
|
||||
SERVER_START_REQ( open_file_object )
|
||||
{
|
||||
@ -147,7 +145,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
|
||||
struct security_descriptor *sd = NULL;
|
||||
struct object_attributes objattr;
|
||||
|
||||
objattr.rootdir = 0;
|
||||
objattr.rootdir = wine_server_obj_handle( attr->RootDirectory );
|
||||
objattr.sd_len = 0;
|
||||
objattr.name_len = 0;
|
||||
if (attr)
|
||||
@ -2117,8 +2115,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
|
||||
ANSI_STRING unix_name;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, FILE_OPEN,
|
||||
!(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
|
||||
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
@ -2160,8 +2157,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
|
||||
ANSI_STRING unix_name;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!(status = wine_nt_to_unix_file_name( attr->ObjectName, &unix_name, FILE_OPEN,
|
||||
!(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
|
||||
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
|
@ -147,6 +147,8 @@ extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
|
||||
extern NTSTATUS DIR_unmount_device( HANDLE handle );
|
||||
extern NTSTATUS DIR_get_unix_cwd( char **cwd );
|
||||
extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] );
|
||||
extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
|
||||
UINT disposition );
|
||||
|
||||
/* virtual memory */
|
||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info );
|
||||
|
Loading…
x
Reference in New Issue
Block a user