ntdll: Add support for the FILE_OPEN_BY_FILE_ID flag in NtCreateFile.
This commit is contained in:
parent
6677565f34
commit
9c789f4025
|
@ -2217,6 +2217,86 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* file_id_to_unix_file_name
|
||||||
|
*
|
||||||
|
* Lookup a file from its file id instead of its name.
|
||||||
|
*/
|
||||||
|
NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret )
|
||||||
|
{
|
||||||
|
enum server_fd_type type;
|
||||||
|
int old_cwd, root_fd, needs_close;
|
||||||
|
char *unix_name;
|
||||||
|
int unix_len;
|
||||||
|
NTSTATUS status;
|
||||||
|
ULONGLONG file_id;
|
||||||
|
struct stat st, root_st;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *de;
|
||||||
|
|
||||||
|
if (attr->ObjectName->Length != sizeof(ULONGLONG)) return STATUS_OBJECT_PATH_SYNTAX_BAD;
|
||||||
|
if (!attr->RootDirectory) return STATUS_INVALID_PARAMETER;
|
||||||
|
memcpy( &file_id, attr->ObjectName->Buffer, sizeof(file_id) );
|
||||||
|
|
||||||
|
unix_len = MAX_DIR_ENTRY_LEN + 1;
|
||||||
|
if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len )))
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
unix_name[0] = 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_OBJECT_TYPE_MISMATCH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fstat( root_fd, &root_st );
|
||||||
|
RtlEnterCriticalSection( &dir_section );
|
||||||
|
if ((old_cwd = open( ".", O_RDONLY )) != -1 && fchdir( root_fd ) != -1)
|
||||||
|
{
|
||||||
|
if (!(dir = opendir( "." ))) status = FILE_GetNtStatus();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((de = readdir( dir )))
|
||||||
|
{
|
||||||
|
if (stat( de->d_name, &st ) == -1) continue;
|
||||||
|
if (st.st_dev == root_st.st_dev && st.st_ino == file_id)
|
||||||
|
{
|
||||||
|
strcpy( unix_name, de->d_name );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir( dir );
|
||||||
|
if (!unix_name[0]) status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||||
|
}
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
TRACE( "%s -> %s\n", wine_dbgstr_longlong(file_id), 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", wine_dbgstr_longlong(file_id), unix_name );
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* lookup_unix_name
|
* lookup_unix_name
|
||||||
*
|
*
|
||||||
|
|
|
@ -115,7 +115,12 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
|
||||||
|
|
||||||
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
if (alloc_size) FIXME( "alloc_size not supported\n" );
|
||||||
|
|
||||||
if ((io->u.Status = nt_to_unix_file_name_attr( attr, &unix_name, disposition )) == STATUS_BAD_DEVICE_TYPE)
|
if (options & FILE_OPEN_BY_FILE_ID)
|
||||||
|
io->u.Status = file_id_to_unix_file_name( attr, &unix_name );
|
||||||
|
else
|
||||||
|
io->u.Status = nt_to_unix_file_name_attr( attr, &unix_name, disposition );
|
||||||
|
|
||||||
|
if (io->u.Status == STATUS_BAD_DEVICE_TYPE)
|
||||||
{
|
{
|
||||||
SERVER_START_REQ( open_file_object )
|
SERVER_START_REQ( open_file_object )
|
||||||
{
|
{
|
||||||
|
|
|
@ -147,6 +147,7 @@ extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name );
|
||||||
extern NTSTATUS DIR_unmount_device( HANDLE handle );
|
extern NTSTATUS DIR_unmount_device( HANDLE handle );
|
||||||
extern NTSTATUS DIR_get_unix_cwd( char **cwd );
|
extern NTSTATUS DIR_get_unix_cwd( char **cwd );
|
||||||
extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] );
|
extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] );
|
||||||
|
extern NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret );
|
||||||
extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
|
extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_STRING *unix_name_ret,
|
||||||
UINT disposition );
|
UINT disposition );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue