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);
* Open a file.
*
* PARAMS
* FileHandle [O] Variable that receives the file handle on return
* DesiredAccess [I] Access desired by the caller to the file
* ObjectAttributes [I] Structue describing the file to be opened
* IoStatusBlock [O] Receives details about the result of the operation
* ShareAccess [I] Type of shared access the caller requires
* OpenOptions [I] Options for the file open
* handle [O] Variable that receives the file handle on return
* access [I] Access desired by the caller to the file
* attr [I] Structue describing the file to be opened
* io [O] Receives details about the result of the operation
* sharing [I] Type of shared access the caller requires
* options [I] Options for the file open
*
* RETURNS
* Success: 0. FileHandle and IoStatusBlock are updated.
* Failure: An NTSTATUS error code describing the error.
*/
NTSTATUS WINAPI NtOpenFile(
OUT PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions)
NTSTATUS WINAPI NtOpenFile( PHANDLE handle, ACCESS_MASK access,
POBJECT_ATTRIBUTES attr, PIO_STATUS_BLOCK io,
ULONG sharing, ULONG options )
{
LPWSTR filename;
static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',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;
return NtCreateFile( handle, access, attr, io, NULL, 0,
sharing, FILE_OPEN, options, NULL, 0 );
}
/**************************************************************************
......@@ -127,41 +98,63 @@ NTSTATUS WINAPI NtOpenFile(
* directory or volume.
*
* PARAMS
* FileHandle [O] Points to a variable which receives the file handle on return
* DesiredAccess [I] Desired access to the file
* ObjectAttributes [I] Structure describing the file
* IoStatusBlock [O] Receives information about the operation on return
* AllocationSize [I] Initial size of the file in bytes
* FileAttributes [I] Attributes to create the file with
* ShareAccess [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
* CreateOptions [I] Options for creating a new file
* EaBuffer [I] Undocumented
* EaLength [I] Undocumented
* handle [O] Points to a variable which receives the file handle on return
* access [I] Desired access to the file
* attr [I] Structure describing the file
* io [O] Receives information about the operation on return
* alloc_size [I] Initial size of the file in bytes
* attributes [I] Attributes to create the file with
* sharing [I] Type of shared access the caller would like to the file
* disposition [I] Specifies what to do, depending on whether the file already exists
* options [I] Options for creating a new file
* ea_buffer [I] Undocumented
* ea_length [I] Undocumented
*
* RETURNS
* Success: 0. FileHandle and IoStatusBlock are updated.
* Success: 0. handle and io are updated.
* Failure: An NTSTATUS error code describing the error.
*/
NTSTATUS WINAPI NtCreateFile(
OUT PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocateSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
PVOID EaBuffer,
ULONG EaLength)
NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIBUTES attr,
PIO_STATUS_BLOCK io, PLARGE_INTEGER alloc_size,
ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, PVOID ea_buffer, ULONG ea_length )
{
FIXME("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx) stub\n",
FileHandle,DesiredAccess,ObjectAttributes,
IoStatusBlock,AllocateSize,FileAttributes,
ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
dump_ObjectAttributes (ObjectAttributes);
return 0;
ANSI_STRING unix_name;
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",
handle, access, debugstr_us(attr->ObjectName), attr->Attributes,
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)
case EPERM:
case EROFS:
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 EMFILE:
case ENFILE: nt = STATUS_NO_MORE_FILES; break;
......
......@@ -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,
WCHAR *filename, ULONG *size, WINE_MODREF **pwm, HANDLE *handle )
{
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
UNICODE_STRING nt_name;
WCHAR *file_part, *ext;
ULONG len;
nt_name.Buffer = NULL;
if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
{
/* we need to search for it */
......@@ -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;
}
*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;
}
......@@ -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 */
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;
memcpy( filename, nt_name.Buffer + 4, len + sizeof(WCHAR) );
if (file_part && !strchrW( file_part, '.' ))
{
len += sizeof(dllW) - sizeof(WCHAR);
if (len >= *size) goto overflow;
strcatW( file_part, dllW );
strcatW( filename, dllW );
}
if ((*pwm = find_fullname_module( filename )) != NULL) return STATUS_SUCCESS;
*handle = pCreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
if (!(*pwm = find_fullname_module( filename )))
{
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;
overflow:
RtlFreeUnicodeString( &nt_name );
*size = len + sizeof(WCHAR);
return STATUS_BUFFER_TOO_SMALL;
}
......@@ -1427,7 +1455,7 @@ static NTSTATUS load_dll( LPCWSTR load_path, LPCWSTR libname, DWORD flags, WINE_
ULONG size;
const char *filetype = "";
WINE_MODREF *main_exe;
HANDLE handle = INVALID_HANDLE_VALUE;
HANDLE handle = 0;
NTSTATUS nts;
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_
{
case LOADORDER_DLL:
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 );
filetype = "native";
break;
......@@ -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 */
/* decrement the dependencies through the MODULE_FreeLibrary call. */
(*pwm)->ldr.LoadCount = 1;
if (handle != INVALID_HANDLE_VALUE) NtClose( handle );
if (handle) NtClose( handle );
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
return nts;
}
......@@ -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);
if (handle != INVALID_HANDLE_VALUE) NtClose( handle );
if (handle) NtClose( handle );
if (filename != buffer) RtlFreeHeap( GetProcessHeap(), 0, filename );
return nts;
}
......@@ -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 );
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();
}
......@@ -73,11 +73,6 @@ extern void SNOOP_SetupDLL( HMODULE hmod );
#define GetCurrentProcessId() ((DWORD)NtCurrentTeb()->ClientId.UniqueProcess)
#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 */
extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine,
......@@ -89,6 +84,8 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
/* file I/O */
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 */
typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
......
......@@ -40,11 +40,6 @@ static const WCHAR DeviceRootW[] = {'\\','\\','.','\\',0};
static const WCHAR NTDosPrefixW[] = {'\\','?','?','\\',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 MAX_DOS_DRIVES 26
......@@ -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.@)
*
......
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