Commit e792fb74 authored by Alexandre Julliard's avatar Alexandre Julliard

Implemented NtCreatelFile using the new symlink scheme.

Use NtCreateFile in the loader, and get rid of the CreateFileW upcall hack.
parent 2392a363
...@@ -71,52 +71,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll); ...@@ -71,52 +71,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
* Open a file. * Open a file.
* *
* PARAMS * PARAMS
* FileHandle [O] Variable that receives the file handle on return * handle [O] Variable that receives the file handle on return
* DesiredAccess [I] Access desired by the caller to the file * access [I] Access desired by the caller to the file
* ObjectAttributes [I] Structue describing the file to be opened * attr [I] Structue describing the file to be opened
* IoStatusBlock [O] Receives details about the result of the operation * io [O] Receives details about the result of the operation
* ShareAccess [I] Type of shared access the caller requires * sharing [I] Type of shared access the caller requires
* OpenOptions [I] Options for the file open * options [I] Options for the file open
* *
* RETURNS * RETURNS
* Success: 0. FileHandle and IoStatusBlock are updated. * Success: 0. FileHandle and IoStatusBlock are updated.
* Failure: An NTSTATUS error code describing the error. * Failure: An NTSTATUS error code describing the error.
*/ */
NTSTATUS WINAPI NtOpenFile( NTSTATUS WINAPI NtOpenFile( PHANDLE handle, ACCESS_MASK access,
OUT PHANDLE FileHandle, POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
ACCESS_MASK DesiredAccess, ULONG sharing, ULONG options )
POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions)
{ {
LPWSTR filename; return NtCreateFile( handle, access, attr, io, NULL, 0,
static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0}; sharing, FILE_OPEN, options, NULL, 0 );
FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) partial stub\n",
FileHandle, DesiredAccess, ObjectAttributes,
IoStatusBlock, ShareAccess, OpenOptions);
dump_ObjectAttributes (ObjectAttributes);
if(ObjectAttributes->RootDirectory)
{
FIXME("Object root directory unknown %p\n",
ObjectAttributes->RootDirectory);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
filename = ObjectAttributes->ObjectName->Buffer;
/* FIXME: DOSFS stuff should call here, not vice-versa */
if(strncmpW(filename, szDosDevices, strlenW(szDosDevices)))
return STATUS_OBJECT_NAME_NOT_FOUND;
/* FIXME: this calls SetLastError() -> bad */
*FileHandle = pCreateFileW( &filename[strlenW(szDosDevices)], DesiredAccess, ShareAccess,
NULL, OPEN_EXISTING, 0, 0 );
if (*FileHandle == INVALID_HANDLE_VALUE) return STATUS_OBJECT_NAME_NOT_FOUND;
return STATUS_SUCCESS;
} }
/************************************************************************** /**************************************************************************
...@@ -127,41 +98,63 @@ NTSTATUS WINAPI NtOpenFile( ...@@ -127,41 +98,63 @@ NTSTATUS WINAPI NtOpenFile(
* directory or volume. * directory or volume.
* *
* PARAMS * PARAMS
* FileHandle [O] Points to a variable which receives the file handle on return * handle [O] Points to a variable which receives the file handle on return
* DesiredAccess [I] Desired access to the file * access [I] Desired access to the file
* ObjectAttributes [I] Structure describing the file * attr [I] Structure describing the file
* IoStatusBlock [O] Receives information about the operation on return * io [O] Receives information about the operation on return
* AllocationSize [I] Initial size of the file in bytes * alloc_size [I] Initial size of the file in bytes
* FileAttributes [I] Attributes to create the file with * attributes [I] Attributes to create the file with
* ShareAccess [I] Type of shared access the caller would like to the file * sharing [I] Type of shared access the caller would like to the file
* CreateDisposition [I] Specifies what to do, depending on whether the file already exists * disposition [I] Specifies what to do, depending on whether the file already exists
* CreateOptions [I] Options for creating a new file * options [I] Options for creating a new file
* EaBuffer [I] Undocumented * ea_buffer [I] Undocumented
* EaLength [I] Undocumented * ea_length [I] Undocumented
* *
* RETURNS * RETURNS
* Success: 0. FileHandle and IoStatusBlock are updated. * Success: 0. handle and io are updated.
* Failure: An NTSTATUS error code describing the error. * Failure: An NTSTATUS error code describing the error.
*/ */
NTSTATUS WINAPI NtCreateFile( NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIBUTES attr,
OUT PHANDLE FileHandle, PIO_STATUS_BLOCK io, PLARGE_INTEGER alloc_size,
ACCESS_MASK DesiredAccess, ULONG attributes, ULONG sharing, ULONG disposition,
POBJECT_ATTRIBUTES ObjectAttributes, ULONG options, PVOID ea_buffer, ULONG ea_length )
OUT PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocateSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength)
{ {
FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n", ANSI_STRING unix_name;
FileHandle,DesiredAccess,ObjectAttributes,
IoStatusBlock,AllocateSize,FileAttributes, TRACE("handle=%p access=%08lx name=%s objattr=%08lx root=%p sec=%p io=%p alloc_size=%p\n"
ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength); "attr=%08lx sharing=%08lx disp=%ld options=%08lx ea=%p.0x%08lx\n",
dump_ObjectAttributes (ObjectAttributes); handle, access, debugstr_us(attr->ObjectName), attr->Attributes,
return 0; attr->RootDirectory, attr->SecurityDescriptor, io, alloc_size,
attributes, sharing, disposition, options, ea_buffer, ea_length );
if (attr->RootDirectory)
{
FIXME( "RootDirectory %p not supported\n", attr->RootDirectory );
return STATUS_OBJECT_NAME_NOT_FOUND;
}
if (alloc_size) FIXME( "alloc_size not supported\n" );
if (!(io->u.Status = DIR_nt_to_unix( attr->ObjectName, &unix_name,
(disposition == FILE_OPEN || disposition == FILE_OVERWRITE),
!(attr->Attributes & OBJ_CASE_INSENSITIVE) )))
{
SERVER_START_REQ( create_file )
{
req->access = access;
req->inherit = (attr->Attributes & OBJ_INHERIT) != 0;
req->sharing = sharing;
req->create = disposition;
req->options = options;
req->attrs = attributes;
wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
io->u.Status = wine_server_call( req );
*handle = reply->handle;
}
SERVER_END_REQ;
RtlFreeAnsiString( &unix_name );
}
else WARN("%s not found (%lx)\n", debugstr_us(attr->ObjectName), io->u.Status );
return io->u.Status;
} }
/*********************************************************************** /***********************************************************************
...@@ -240,7 +233,7 @@ NTSTATUS FILE_GetNtStatus(void) ...@@ -240,7 +233,7 @@ NTSTATUS FILE_GetNtStatus(void)
case EPERM: case EPERM:
case EROFS: case EROFS:
case EACCES: nt = STATUS_ACCESS_DENIED; break; case EACCES: nt = STATUS_ACCESS_DENIED; break;
case ENOENT: nt = STATUS_SHARING_VIOLATION; break; case ENOENT: nt = STATUS_OBJECT_NAME_NOT_FOUND; break;
case EISDIR: nt = STATUS_FILE_IS_A_DIRECTORY; break; case EISDIR: nt = STATUS_FILE_IS_A_DIRECTORY; break;
case EMFILE: case EMFILE:
case ENFILE: nt = STATUS_NO_MORE_FILES; break; case ENFILE: nt = STATUS_NO_MORE_FILES; break;
......
...@@ -1333,9 +1333,13 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags, ...@@ -1333,9 +1333,13 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, LPCWSTR path, DWORD flags,
static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
WCHAR *filename, ULONG *size, WINE_MODREF **pwm, HANDLE *handle ) WCHAR *filename, ULONG *size, WINE_MODREF **pwm, HANDLE *handle )
{ {
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
UNICODE_STRING nt_name;
WCHAR *file_part, *ext; WCHAR *file_part, *ext;
ULONG len; ULONG len;
nt_name.Buffer = NULL;
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH) if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
{ {
/* we need to search for it */ /* we need to search for it */
...@@ -1368,7 +1372,17 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, ...@@ -1368,7 +1372,17 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
{ {
if ((*pwm = find_basename_module( file_part )) != NULL) return STATUS_SUCCESS; if ((*pwm = find_basename_module( file_part )) != NULL) return STATUS_SUCCESS;
} }
*handle = pCreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); if (!RtlDosPathNameToNtPathName_U( filename, &nt_name, NULL, NULL ))
return STATUS_NO_MEMORY;
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ, 0 )) *handle = 0;
RtlFreeUnicodeString( &nt_name );
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
...@@ -1394,19 +1408,33 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname, ...@@ -1394,19 +1408,33 @@ static NTSTATUS find_dll_file( const WCHAR *load_path, const WCHAR *libname,
/* absolute path name, or relative path name but not found above */ /* absolute path name, or relative path name but not found above */
len = RtlGetFullPathName_U( libname, *size, filename, &file_part ); if (!RtlDosPathNameToNtPathName_U( libname, &nt_name, &file_part, NULL ))
return STATUS_NO_MEMORY;
len = nt_name.Length - 4*sizeof(WCHAR); /* for \??\ prefix */
if (len >= *size) goto overflow; if (len >= *size) goto overflow;
memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) );
if (file_part && !strchrW( file_part, '.' )) if (file_part && !strchrW( file_part, '.' ))
{ {
len += sizeof(dllW) - sizeof(WCHAR); len += sizeof(dllW) - sizeof(WCHAR);
if (len >= *size) goto overflow; if (len >= *size) goto overflow;
strcatW( file_part, dllW ); strcatW( filename, dllW );
} }
if ((*pwm = find_fullname_module( filename )) != NULL) return STATUS_SUCCESS; if (!(*pwm = find_fullname_module( filename )))
*handle = pCreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); {
attr.Length = sizeof(attr);
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.ObjectName = &nt_name;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
if (NtOpenFile( handle, GENERIC_READ, &attr, &io, FILE_SHARE_READ, 0 )) *handle = 0;
}
RtlFreeUnicodeString( &nt_name );
return STATUS_SUCCESS; return STATUS_SUCCESS;
overflow: overflow:
RtlFreeUnicodeString( &nt_name );
*size = len + sizeof(WCHAR); *size = len + sizeof(WCHAR);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
...@@ -1427,7 +1455,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ ...@@ -1427,7 +1455,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
ULONG size; ULONG size;
const char *filetype = ""; const char *filetype = "";
WINE_MODREF *main_exe; WINE_MODREF *main_exe;
HANDLE handle = INVALID_HANDLE_VALUE; HANDLE handle = 0;
NTSTATUS nts; NTSTATUS nts;
TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) ); TRACE( "looking for %s in %s\n", debugstr_w(libname), debugstr_w(load_path) );
...@@ -1473,7 +1501,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ ...@@ -1473,7 +1501,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
{ {
case LOADORDER_DLL: case LOADORDER_DLL:
TRACE("Trying native dll %s\n", debugstr_w(filename)); TRACE("Trying native dll %s\n", debugstr_w(filename));
if (handle == INVALID_HANDLE_VALUE) continue; /* it cannot possibly be loaded */ if (!handle) continue; /* it cannot possibly be loaded */
nts = load_native_dll( load_path, filename, handle, flags, pwm ); nts = load_native_dll( load_path, filename, handle, flags, pwm );
filetype = "native"; filetype = "native";
break; break;
...@@ -1497,7 +1525,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ ...@@ -1497,7 +1525,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
/* Set the ldr.LoadCount here so that an attach failure will */ /* Set the ldr.LoadCount here so that an attach failure will */
/* decrement the dependencies through the MODULE_FreeLibrary call. */ /* decrement the dependencies through the MODULE_FreeLibrary call. */
(*pwm)->ldr.LoadCount = 1; (*pwm)->ldr.LoadCount = 1;
if (handle != INVALID_HANDLE_VALUE) NtClose( handle ); if (handle) NtClose( handle );
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
return nts; return nts;
} }
...@@ -1505,7 +1533,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_ ...@@ -1505,7 +1533,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
} }
WARN("Failed to load module %s; status=%lx\n", debugstr_w(libname), nts); WARN("Failed to load module %s; status=%lx\n", debugstr_w(libname), nts);
if (handle != INVALID_HANDLE_VALUE) NtClose( handle ); if (handle) NtClose( handle );
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename ); if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
return nts; return nts;
} }
...@@ -2007,12 +2035,5 @@ void __wine_process_init( int argc, char *argv[] ) ...@@ -2007,12 +2035,5 @@ void __wine_process_init( int argc, char *argv[] )
MESSAGE( "wine: could not find __wine_kernel_init in kernel32.dll, status %lx\n", status ); MESSAGE( "wine: could not find __wine_kernel_init in kernel32.dll, status %lx\n", status );
exit(1); exit(1);
} }
RtlInitAnsiString( &func_name, "CreateFileW" );
if ((status = LdrGetProcedureAddress( wm->ldr.BaseAddress, &func_name,
0, (void **)&pCreateFileW )) != STATUS_SUCCESS)
{
MESSAGE( "wine: could not find CreateFileW in kernel32.dll, status %lx\n", status );
exit(1);
}
init_func(); init_func();
} }
...@@ -73,11 +73,6 @@ extern void SNOOP_SetupDLL( HMODULE hmod ); ...@@ -73,11 +73,6 @@ extern void SNOOP_SetupDLL( HMODULE hmod );
#define GetCurrentProcessId() ((DWORD)NtCurrentTeb()->ClientId.UniqueProcess) #define GetCurrentProcessId() ((DWORD)NtCurrentTeb()->ClientId.UniqueProcess)
#define GetCurrentThreadId() ((DWORD)NtCurrentTeb()->ClientId.UniqueThread) #define GetCurrentThreadId() ((DWORD)NtCurrentTeb()->ClientId.UniqueThread)
/* hack: upcall to kernel */
extern HANDLE (WINAPI *pCreateFileW)( LPCWSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template );
/* Device IO */ /* Device IO */
extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice, extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine, HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine,
...@@ -89,6 +84,8 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice, ...@@ -89,6 +84,8 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
/* file I/O */ /* file I/O */
extern NTSTATUS FILE_GetNtStatus(void); extern NTSTATUS FILE_GetNtStatus(void);
extern NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
int check_last, int check_case );
/* virtual memory */ /* virtual memory */
typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID); typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
......
...@@ -40,11 +40,6 @@ static const WCHAR DeviceRootW[] = {'\\','\\','.','\\',0}; ...@@ -40,11 +40,6 @@ static const WCHAR DeviceRootW[] = {'\\','\\','.','\\',0};
static const WCHAR NTDosPrefixW[] = {'\\','?','?','\\',0}; static const WCHAR NTDosPrefixW[] = {'\\','?','?','\\',0};
static const WCHAR UncPfxW[] = {'U','N','C','\\',0}; static const WCHAR UncPfxW[] = {'U','N','C','\\',0};
/* FIXME: hack! */
HANDLE (WINAPI *pCreateFileW)( LPCWSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template );
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/') #define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
#define MAX_DOS_DRIVES 26 #define MAX_DOS_DRIVES 26
...@@ -210,20 +205,6 @@ DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path ) ...@@ -210,20 +205,6 @@ DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path )
} }
} }
/******************************************************************
* RtlDoesFileExists_U
*
* FIXME: should not use CreateFileW
*/
BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
{
HANDLE handle = pCreateFileW( file_name, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0 );
if (handle == INVALID_HANDLE_VALUE) return FALSE;
NtClose( handle );
return TRUE;
}
/*********************************************************************** /***********************************************************************
* RtlIsDosDeviceName_U (NTDLL.@) * RtlIsDosDeviceName_U (NTDLL.@)
* *
......
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