From e792fb74ba3e34b3356677478848b1faaecc257b Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 12 Apr 2004 23:31:09 +0000 Subject: [PATCH] Implemented NtCreatelFile using the new symlink scheme. Use NtCreateFile in the loader, and get rid of the CreateFileW upcall hack. --- dlls/ntdll/directory.c | 300 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/file.c | 135 +++++++++--------- dlls/ntdll/loader.c | 53 ++++--- dlls/ntdll/ntdll_misc.h | 7 +- dlls/ntdll/path.c | 19 --- 5 files changed, 403 insertions(+), 111 deletions(-) diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c index 0d668832879..f2c3dfbe2a5 100644 --- a/dlls/ntdll/directory.c +++ b/dlls/ntdll/directory.c @@ -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; +} diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c index b207170c2e2..f37fb640d4e 100644 --- a/dlls/ntdll/file.c +++ b/dlls/ntdll/file.c @@ -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; diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 01704c37f58..e136d5237e4 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -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(); } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index ce0efeb0a53..66c854c10d7 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -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); diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index 52d1335c683..408662e4547 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -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.@) *