Implemented NtCreatelFile using the new symlink scheme.

Use NtCreateFile in the loader, and get rid of the CreateFileW upcall
hack.
This commit is contained in:
Alexandre Julliard 2004-04-12 23:31:09 +00:00
parent 2392a36370
commit e792fb74ba
5 changed files with 403 additions and 111 deletions

View File

@ -53,6 +53,7 @@
#include "ntdll_misc.h"
#include "wine/unicode.h"
#include "wine/server.h"
#include "wine/library.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(file);
@ -71,11 +72,16 @@ typedef struct
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, KERNEL_DIRENT [2] )
#ifndef O_DIRECTORY
# define O_DIRECTORY 0200000 /* must be directory */
#endif
#else /* linux */
#undef VFAT_IOCTL_READDIR_BOTH /* just in case... */
#endif /* linux */
#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
#define INVALID_DOS_CHARS '*','?','<','>','|','"','+','=',',',';','[',']',' ','\345'
@ -572,3 +578,297 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
TRACE( "=> %lx (%ld)\n", io->u.Status, io->Information );
return io->u.Status;
}
/***********************************************************************
* find_file_in_dir
*
* Find a file in a directory the hard way, by doing a case-insensitive search.
* The file found is appended to unix_name at pos.
* There must be at least MAX_DIR_ENTRY_LEN+2 chars available at pos.
*/
static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, int length,
int is_last, int check_last, int check_case )
{
WCHAR buffer[MAX_DIR_ENTRY_LEN];
UNICODE_STRING str;
BOOLEAN spaces;
DIR *dir;
struct dirent *de;
struct stat st;
int ret, used_default, is_name_8_dot_3;
/* try a shortcut for this directory */
unix_name[pos++] = '/';
ret = ntdll_wcstoumbs( 0, name, length, unix_name + pos, MAX_DIR_ENTRY_LEN,
NULL, &used_default );
/* if we used the default char, the Unix name won't round trip properly back to Unicode */
/* so it cannot match the file we are looking for */
if (ret >= 0 && !used_default)
{
unix_name[pos + ret] = 0;
if (!stat( unix_name, &st )) return STATUS_SUCCESS;
}
if (check_case) goto not_found; /* we want an exact match */
if (pos > 1) unix_name[pos - 1] = 0;
else unix_name[1] = 0; /* keep the initial slash */
/* check if it fits in 8.3 so that we don't look for short names if we won't need them */
str.Buffer = (WCHAR *)name;
str.Length = length * sizeof(WCHAR);
str.MaximumLength = str.Length;
is_name_8_dot_3 = RtlIsNameLegalDOS8Dot3( &str, NULL, &spaces ) && !spaces;
/* now look for it through the directory */
#ifdef VFAT_IOCTL_READDIR_BOTH
if (is_name_8_dot_3)
{
int fd = open( unix_name, O_RDONLY | O_DIRECTORY );
if (fd != -1)
{
KERNEL_DIRENT de[2];
if (ioctl( fd, VFAT_IOCTL_READDIR_BOTH, (long)de ) != -1)
{
unix_name[pos - 1] = '/';
for (;;)
{
if (!de[0].d_reclen) break;
if (de[1].d_name[0])
{
ret = ntdll_umbstowcs( 0, de[1].d_name, strlen(de[1].d_name),
buffer, MAX_DIR_ENTRY_LEN );
if (ret == length && !memicmpW( buffer, name, length))
{
strcpy( unix_name + pos, de[1].d_name );
close( fd );
return STATUS_SUCCESS;
}
}
ret = ntdll_umbstowcs( 0, de[0].d_name, strlen(de[0].d_name),
buffer, MAX_DIR_ENTRY_LEN );
if (ret == length && !memicmpW( buffer, name, length))
{
strcpy( unix_name + pos,
de[1].d_name[0] ? de[1].d_name : de[0].d_name );
close( fd );
return STATUS_SUCCESS;
}
if (ioctl( fd, VFAT_IOCTL_READDIR_BOTH, (long)de ) == -1)
{
close( fd );
goto not_found;
}
}
}
close( fd );
}
/* fall through to normal handling */
}
#endif /* VFAT_IOCTL_READDIR_BOTH */
if (!(dir = opendir( unix_name ))) return FILE_GetNtStatus();
unix_name[pos - 1] = '/';
str.Buffer = buffer;
str.MaximumLength = sizeof(buffer);
while ((de = readdir( dir )))
{
ret = ntdll_umbstowcs( 0, de->d_name, strlen(de->d_name), buffer, MAX_DIR_ENTRY_LEN );
if (ret == length && !memicmpW( buffer, name, length ))
{
strcpy( unix_name + pos, de->d_name );
closedir( dir );
return STATUS_SUCCESS;
}
if (!is_name_8_dot_3) continue;
str.Length = ret * sizeof(WCHAR);
if (!RtlIsNameLegalDOS8Dot3( &str, NULL, &spaces ) || spaces)
{
WCHAR short_nameW[12];
ret = hash_short_file_name( &str, short_nameW );
if (ret == length && !memicmpW( short_nameW, name, length ))
{
strcpy( unix_name + pos, de->d_name );
closedir( dir );
return STATUS_SUCCESS;
}
}
}
closedir( dir );
goto not_found; /* avoid warning */
not_found:
if (is_last && !check_last) /* return the name anyway */
{
int used_default;
ret = ntdll_wcstoumbs( 0, name, length, unix_name + pos,
MAX_DIR_ENTRY_LEN, NULL, &used_default );
if (ret > 0 && !used_default)
{
unix_name[pos + ret] = 0;
return STATUS_SUCCESS;
}
}
unix_name[pos - 1] = 0;
return is_last ? STATUS_NO_SUCH_FILE : STATUS_OBJECT_PATH_NOT_FOUND;
}
/* return the length of the DOS namespace prefix if any */
static inline int get_dos_prefix_len( const UNICODE_STRING *name )
{
static const WCHAR nt_prefixW[] = {'\\','?','?','\\'};
static const WCHAR dosdev_prefixW[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\'};
if (name->Length > sizeof(nt_prefixW) &&
!memcmp( name->Buffer, nt_prefixW, sizeof(nt_prefixW) ))
return sizeof(nt_prefixW) / sizeof(WCHAR);
if (name->Length > sizeof(dosdev_prefixW) &&
!memicmpW( name->Buffer, dosdev_prefixW, sizeof(dosdev_prefixW)/sizeof(WCHAR) ))
return sizeof(dosdev_prefixW) / sizeof(WCHAR);
return 0;
}
/******************************************************************************
* DIR_nt_to_unix
*
* Convert a file name from NT namespace to Unix namespace.
*/
NTSTATUS DIR_nt_to_unix( const UNICODE_STRING *nameW, ANSI_STRING *unix_name_ret,
int check_last, int check_case )
{
NTSTATUS status = STATUS_NO_SUCH_FILE;
const char *config_dir = wine_get_config_dir();
const WCHAR *end, *name;
struct stat st;
char *unix_name;
int pos, ret, name_len, unix_len, used_default;
name = nameW->Buffer;
name_len = nameW->Length / sizeof(WCHAR);
if ((pos = get_dos_prefix_len( nameW )))
{
name += pos;
name_len -= pos;
if (name_len < 3 || !isalphaW(name[0]) || name[1] != ':' || !IS_SEPARATOR(name[2]))
return STATUS_NO_SUCH_FILE;
name += 2; /* skip drive letter */
name_len -= 2;
unix_len = ntdll_wcstoumbs( 0, name, name_len, NULL, 0, NULL, NULL );
unix_len += MAX_DIR_ENTRY_LEN + 3;
unix_len += strlen(config_dir) + sizeof("/dosdevices/a:");
if (!(unix_name = RtlAllocateHeap( GetProcessHeap(), 0, unix_len )))
return STATUS_NO_MEMORY;
strcpy( unix_name, config_dir );
strcat( unix_name, "/dosdevices/a:" );
pos = strlen(unix_name);
unix_name[pos - 2] = tolowerW( name[-2] );
}
else /* no DOS prefix, assume NT native name, map directly to Unix */
{
if (!name_len || !IS_SEPARATOR(name[0])) return STATUS_NO_SUCH_FILE;
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;
pos = 0;
}
/* try a shortcut first */
ret = ntdll_wcstoumbs( 0, name, name_len, unix_name + pos, unix_len - pos - 1,
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;
}
if (check_case && check_last)
{
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return STATUS_NO_SUCH_FILE;
}
/* now do it component by component */
for (;;)
{
while (name_len && IS_SEPARATOR(*name))
{
name++;
name_len--;
}
if (!name_len) break;
end = name;
while (end < name + name_len && !IS_SEPARATOR(*end)) end++;
/* grow the buffer if needed */
if (unix_len - pos < MAX_DIR_ENTRY_LEN + 2)
{
char *new_name;
unix_len += 2 * MAX_DIR_ENTRY_LEN;
if (!(new_name = RtlReAllocateHeap( GetProcessHeap(), 0, unix_name, unix_len )))
{
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return STATUS_NO_MEMORY;
}
unix_name = new_name;
}
status = find_file_in_dir( unix_name, pos, name, end - name,
(end - name == name_len), check_last, check_case );
if (status != STATUS_SUCCESS)
{
/* couldn't find it at all, fail */
WARN( "%s not found in %s\n", debugstr_w(name), unix_name );
RtlFreeHeap( GetProcessHeap(), 0, unix_name );
return status;
}
pos += strlen( unix_name + pos );
name_len -= end - name;
name = end;
}
WARN( "%s -> %s required a case-insensitive search\n",
debugstr_us(nameW), debugstr_a(unix_name) );
done:
TRACE( "%s -> %s\n", debugstr_us(nameW), debugstr_a(unix_name) );
unix_name_ret->Buffer = unix_name;
unix_name_ret->Length = strlen(unix_name);
unix_name_ret->MaximumLength = unix_len;
return STATUS_SUCCESS;
}
/******************************************************************
* RtlDoesFileExists_U (NTDLL.@)
*/
BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
{
UNICODE_STRING nt_name;
ANSI_STRING unix_name;
BOOLEAN ret;
if (!RtlDosPathNameToNtPathName_U( file_name, &nt_name, NULL, NULL )) return FALSE;
ret = (DIR_nt_to_unix( &nt_name, &unix_name, TRUE, FALSE ) == STATUS_SUCCESS);
if (ret) RtlFreeAnsiString( &unix_name );
RtlFreeUnicodeString( &nt_name );
return ret;
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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.@)
*