ntdll / kernel32: #46

Eric Pouech pouech-eric at wanadoo.fr
Wed Feb 4 14:55:34 CST 2004


Moved file opening to ntdll
- implementation of NtCreateFile
- modification of server protocol:
   + create_file now uses NtCreateFile parameters (not CreateFile's)
     as well as NT path names
   + create_named_pipe also uses NT path names
- NtCreateFile can also open directory handles (CreateFile couldn't)
- CreateFile now calls NtCreateFile
- misc. cleanups
-------------- next part --------------
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel45/kernel_private.h dlls/kernel/kernel_private.h
--- dlls/kernel45/kernel_private.h	2004-01-18 19:13:01.000000000 +0100
+++ dlls/kernel/kernel_private.h	2004-01-19 22:42:21.000000000 +0100
@@ -47,6 +47,7 @@
 /* Size of per-process table of DOS handles */
 #define DOS_TABLE_SIZE 256
 extern HANDLE dos_handles[DOS_TABLE_SIZE];
+#define MAX_PATHNAME_LEN   1024
 void FILE_ConvertOFMode( INT mode, DWORD *access, DWORD *sharing );
 void FILE_SetDosError(void);
 
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel45/process.c dlls/kernel/process.c
--- dlls/kernel45/process.c	2004-01-23 22:32:11.000000000 +0100
+++ dlls/kernel/process.c	2004-01-23 22:35:53.000000000 +0100
@@ -740,7 +740,7 @@
         IMAGE_NT_HEADERS *nt;
         LPTHREAD_START_ROUTINE entry;
 
-        LdrInitializeThunk( main_exe_file, CreateFileW, 0, 0 );
+        LdrInitializeThunk( main_exe_file, 0, 0, 0 );
 
         nt = RtlImageNtHeader( peb->ImageBaseAddress );
         entry = (LPTHREAD_START_ROUTINE)((char *)peb->ImageBaseAddress +
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/kernel45/sync.c dlls/kernel/sync.c
--- dlls/kernel45/sync.c	2004-01-01 09:53:31.000000000 +0100
+++ dlls/kernel/sync.c	2004-01-19 22:48:17.000000000 +0100
@@ -45,7 +45,6 @@
 #include "wine/unicode.h"
 #include "wine/winbase16.h"
 #include "kernel_private.h"
-#include "file.h"
 
 #include "wine/debug.h"
 
@@ -1027,44 +1026,43 @@
                                 DWORD nOutBufferSize, DWORD nInBufferSize,
                                 DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr )
 {
-    HANDLE ret;
-    DWORD len;
-    static const WCHAR leadin[] = {'\\','\\','.','\\','P','I','P','E','\\'};
+    HANDLE ret = INVALID_HANDLE_VALUE;
+    UNICODE_STRING ustr;
+    static const WCHAR leadin[] = {'\\','?','?','\\','P','I','P','E','\\'};
 
     TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p)\n",
           debugstr_w(name), dwOpenMode, dwPipeMode, nMaxInstances,
           nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr );
 
-    if (!name)
-    {
-        SetLastError( ERROR_PATH_NOT_FOUND );
-        return INVALID_HANDLE_VALUE;
-    }
-    len = strlenW(name);
-    if (len >= MAX_PATH)
-    {
+    if (!name) SetLastError( ERROR_PATH_NOT_FOUND );
+    else if (strlenW(name) >= MAX_PATH) 
         SetLastError( ERROR_FILENAME_EXCED_RANGE );
-        return INVALID_HANDLE_VALUE;
-    }
-    if (strncmpiW(name, leadin, sizeof(leadin)/sizeof(leadin[0])))
-    {
-        SetLastError( ERROR_INVALID_NAME );
-        return INVALID_HANDLE_VALUE;
-    }
-    SERVER_START_REQ( create_named_pipe )
-    {
-        req->openmode = dwOpenMode;
-        req->pipemode = dwPipeMode;
-        req->maxinstances = nMaxInstances;
-        req->outsize = nOutBufferSize;
-        req->insize = nInBufferSize;
-        req->timeout = nDefaultTimeOut;
-        wine_server_add_data( req, name, len * sizeof(WCHAR) );
-        SetLastError(0);
-        if (!wine_server_call_err( req )) ret = reply->handle;
-        else ret = INVALID_HANDLE_VALUE;
+    else if (!RtlDosPathNameToNtPathName_U(name, &ustr, NULL, NULL))
+        SetLastError( ERROR_PATH_NOT_FOUND );
+    else
+    {       
+        if (strncmpiW(ustr.Buffer, leadin, sizeof(leadin)/sizeof(leadin[0])))
+            SetLastError( ERROR_INVALID_NAME );
+        else
+        {
+            /* FIXME: this code should be moved into ntdll.CreateNamedPipeFile */
+            SERVER_START_REQ( create_named_pipe )
+            {
+                req->openmode = dwOpenMode;
+                req->pipemode = dwPipeMode;
+                req->maxinstances = nMaxInstances;
+                req->outsize = nOutBufferSize;
+                req->insize = nInBufferSize;
+                req->timeout = nDefaultTimeOut;
+                wine_server_add_data( req, ustr.Buffer, ustr.Length );
+                SetLastError(0);
+                if (!wine_server_call_err( req )) ret = reply->handle;
+            }
+            SERVER_END_REQ;
+        }
+        RtlFreeUnicodeString(&ustr);
     }
-    SERVER_END_REQ;
+
     return ret;
 }
 
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll45/file.c dlls/ntdll/file.c
--- dlls/ntdll45/file.c	2004-01-23 22:32:12.000000000 +0100
+++ dlls/ntdll/file.c	2004-02-01 17:25:50.000000000 +0100
@@ -1,5 +1,6 @@
 /*
  * Copyright 1999, 2000 Juergen Schmied
+ *           2003 Eric Pouech
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,6 +37,7 @@
 #include "wine/unicode.h"
 #include "wine/debug.h"
 #include "wine/server.h"
+#include "wine/library.h"
 #include "async.h"
 #include "ntdll_misc.h"
 
@@ -62,41 +64,11 @@
  *  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 phndl, ACCESS_MASK access, POBJECT_ATTRIBUTES oa,
+                           PIO_STATUS_BLOCK iosb, ULONG share, 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(phndl, access, oa, iosb, NULL, 0, 
+                        share, FILE_OPEN, options, NULL, 0);
 }
 
 /**************************************************************************
@@ -123,25 +95,232 @@
  *  Success: 0. FileHandle and IoStatusBlock 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)
-{
-	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;
+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)
+{
+    static const WCHAR  pipeW[] = {'P','I','P','E','\\',0};
+    static const WCHAR  dosdevW[] = {'\\','?','?','\\',0};
+    static const WCHAR  uncW[] = {'U','N','C','\\',0};
+    char                buffer[2048]; /* FIXME */
+    UNICODE_STRING      ntstr;
+    struct nt_to_unix_path      paths;
+    BOOL                check_last, unix_path = FALSE;
+
+    TRACE("(%p,0x%08lx,%p,%p,%p,0x%08lx,0x%08lx,0x%08lx,0x%08lx,%p,0x%08lx)\n",
+          FileHandle,DesiredAccess,ObjectAttributes,
+          IoStatusBlock,AllocateSize,FileAttributes,
+          ShareAccess,CreateDisposition,CreateOptions,EaBuffer,EaLength);
+    dump_ObjectAttributes (ObjectAttributes);
+
+#define SUPPORTED_CO (FILE_DIRECTORY_FILE|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DELETE_ON_CLOSE|FILE_SYNCHRONOUS_IO_ALERT|FILE_RANDOM_ACCESS)
+    if (AllocateSize || (CreateOptions & ~SUPPORTED_CO) || EaBuffer || EaLength)
+    {
+        FIXME("Unsupported parameter\n");
+        return IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED;
+    }
+#undef SUPPORTED_CO
+    if (DesiredAccess & (FILE_LIST_DIRECTORY|FILE_TRAVERSE))
+        FIXME("ListDir & Traverse options not properly handled\n");
+    if (ObjectAttributes->RootDirectory)
+    {
+        FIXME("Cannot handle non-absolute file names yet\n");
+        return IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED;
+    }
+    /* FIXME, the string is perhaps not null terminated */
+    if (ObjectAttributes->ObjectName->Buffer[ObjectAttributes->ObjectName->Length / sizeof(WCHAR)] != '\0')
+        FIXME("Non terminated object attribute string\n");
+
+    paths.unix_str.Buffer = buffer;
+    paths.unix_str.Length = 0;
+    paths.unix_str.MaximumLength = sizeof(buffer);
+
+    if (ObjectAttributes->ObjectName->Buffer[0] == '/')
+    {
+        IoStatusBlock->u.Status = FILE_MapUnixToDos(ObjectAttributes->ObjectName, &paths);
+        unix_path = (IoStatusBlock->u.Status == STATUS_SUCCESS);
+    }
+
+    if (!unix_path)
+    {
+        int i;
+        char* ptr;
+
+        if (!RtlDosPathNameToNtPathName_U(ObjectAttributes->ObjectName->Buffer,
+                                          &ntstr, NULL, NULL))
+        {
+            return IoStatusBlock->u.Status = STATUS_OBJECT_NAME_INVALID;
+        }
+
+        switch (CreateDisposition)
+        {
+        case FILE_SUPERSEDE:
+        case FILE_CREATE:
+        case FILE_OPEN_IF:
+        case FILE_OVERWRITE_IF:
+            check_last = FALSE;
+            break;
+        case FILE_OPEN:
+        case FILE_OVERWRITE:
+            check_last = TRUE;
+            break;
+        default:
+            FIXME("----%lx\n", CreateDisposition);
+            return STATUS_INVALID_PARAMETER;
+        }
+        TRACE("===> %s\n", debugstr_w(ntstr.Buffer));
+
+        if (strncmpW(ntstr.Buffer, dosdevW, 4))
+        {
+            FIXME("How come, should get a NT path name starting with \\??\\\nbut got %s !!!!\n", debugstr_w(ntstr.Buffer));
+            return IoStatusBlock->u.Status = STATUS_OBJECT_PATH_NOT_FOUND;
+        }
+        if (!strncmpiW(ntstr.Buffer + 4, uncW, 4))
+	{
+            FIXME("UNC filenames: unsupported yet (%s)\n", debugstr_w(ntstr.Buffer));
+            return IoStatusBlock->u.Status = STATUS_OBJECT_PATH_NOT_FOUND;
+	}
+        if (!strncmpiW(ntstr.Buffer + 4, pipeW, 5))
+        {
+            TRACE("Opening a pipe: %s\n", debugstr_w(ntstr.Buffer));
+
+            if (ntstr.Length / sizeof(WCHAR) > MAX_PATH)
+                IoStatusBlock->u.Status = STATUS_NAME_TOO_LONG;
+            else
+            {
+                if (CreateDisposition != FILE_OPEN)
+                    FIXME("Should this be supported (%lu) ??\n", CreateDisposition);
+
+                SERVER_START_REQ( open_named_pipe )
+                {
+                    req->access = DesiredAccess;
+                    req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+                    wine_server_add_data( req, ntstr.Buffer, ntstr.Length );
+                    IoStatusBlock->u.Status = wine_server_call( req );
+                    *FileHandle = reply->handle;
+                }
+                SERVER_END_REQ;
+                if (IoStatusBlock->u.Status == STATUS_SUCCESS)
+                    IoStatusBlock->Information = FILE_OPENED;
+                else
+                    IoStatusBlock->Information = FILE_DOES_NOT_EXIST;
+            }
+            return IoStatusBlock->u.Status;
+        }
+
+        ptr = buffer + sprintf(buffer, "%s/dosdevices/", wine_get_config_dir());
+        i = ntdll_wcstoumbs(0, &ntstr.Buffer[4], 
+                            ntstr.Length / sizeof(WCHAR) - 4,
+                            ptr, sizeof(buffer) - (ptr - buffer), NULL, NULL);
+        ptr[i] = '\0';
+        TRACE("Handling %s\n", buffer);
+        IoStatusBlock->u.Status = FILE_GetUnixName(&ntstr, &paths);
+        if (IoStatusBlock->u.Status == STATUS_SUCCESS && check_last && !paths.last_exists)
+            IoStatusBlock->u.Status = STATUS_OBJECT_NAME_NOT_FOUND;
+    }
+
+    if (IoStatusBlock->u.Status != STATUS_SUCCESS) goto done;
+
+    if (paths.is_device)
+    {
+        LPCSTR p = strrchr(paths.unix_str.Buffer, '/');
+        if (p && !strncasecmp(p + 1, "SERIAL", 6) && isdigit(p[7]) && !p[8])
+        {
+            SERVER_START_REQ( create_serial )
+            {
+                req->access  = DesiredAccess;
+                req->inherit = ObjectAttributes->Attributes & OBJ_INHERIT;
+                req->attributes = FileAttributes;
+                req->sharing = ShareAccess; /* FIXME was forced to FILE_SHARE_READ|FILE_SHARE_WRITE */
+                wine_server_add_data( req, paths.unix_str.Buffer, paths.unix_str.Length );
+                IoStatusBlock->u.Status = wine_server_call( req );
+                *FileHandle = reply->handle;
+            }
+            SERVER_END_REQ;
+            goto done;
+        }
+    }
+    if (paths.unix_str.Buffer[0] == '/')
+    {
+    again:
+        SERVER_START_REQ( create_file )
+        {
+            req->access     = DesiredAccess;
+            req->inherit    = ObjectAttributes->Attributes & OBJ_INHERIT;
+            req->sharing    = ShareAccess;
+            req->create_disp= CreateDisposition;
+            req->create_opt = CreateOptions;
+            req->attrs      = FileAttributes;
+            req->removable  = paths.is_removable;
+            wine_server_add_data( req, paths.unix_str.Buffer, paths.unix_str.Length );
+            IoStatusBlock->u.Status = wine_server_call( req );
+            *FileHandle = reply->handle;
+        }
+        SERVER_END_REQ;
+
+        if (((IoStatusBlock->u.Status == STATUS_MEDIA_WRITE_PROTECTED) || 
+             (IoStatusBlock->u.Status == STATUS_ACCESS_DENIED)) &&
+/* EPP: no longer supported !(paths.flags & VOLUME_FAIL_READ_ONLY) && */
+            !(FileAttributes & FILE_ATTRIBUTE_READONLY) &&
+            (DesiredAccess & GENERIC_WRITE))
+        {
+            TRACE("Write access failed for file '%s', "
+                  "trying without write access\n", 
+                  debugstr_an(paths.unix_str.Buffer, paths.unix_str.Length));
+            /* FIXME: should do the VOLUME_FAIL_READ_ONLY option from the volume definition */
+            DesiredAccess &= ~GENERIC_WRITE;
+            goto again;
+        }
+    }
+    else
+    {
+        FIXME("What the heck\n");
+        IoStatusBlock->u.Status = STATUS_NOT_IMPLEMENTED; /* device */
+    }
+
+ done:
+    if (!unix_path) RtlFreeUnicodeString(&ntstr);
+    else paths.last_exists = TRUE;
+
+    IoStatusBlock->Information = -1; /* just to keep valgrind happy */
+    switch (CreateDisposition)
+    {
+    case FILE_SUPERSEDE:
+        if (IoStatusBlock->u.Status == STATUS_SUCCESS)
+            IoStatusBlock->Information = paths.last_exists ? FILE_SUPERSEDED : FILE_CREATED;
+        /* else ??? */
+        break;
+    case FILE_CREATE:
+        IoStatusBlock->Information = (IoStatusBlock->u.Status == STATUS_SUCCESS) ? FILE_CREATED : FILE_EXISTS;
+        break;
+    case FILE_OPEN_IF:
+        if (IoStatusBlock->u.Status == STATUS_SUCCESS)
+            IoStatusBlock->Information = paths.last_exists ? FILE_OPENED : FILE_CREATED;
+        /* else ??? */
+        break;
+    case FILE_OVERWRITE_IF:
+        if (IoStatusBlock->u.Status == STATUS_SUCCESS)
+            IoStatusBlock->Information = paths.last_exists ? FILE_OVERWRITTEN : FILE_CREATED;
+        /* else ??? */
+        break;
+    case FILE_OPEN:
+        IoStatusBlock->Information = (IoStatusBlock->u.Status == STATUS_SUCCESS) ? FILE_OPENED : FILE_DOES_NOT_EXIST;
+        break;
+    case FILE_OVERWRITE:
+        IoStatusBlock->Information = (IoStatusBlock->u.Status == STATUS_SUCCESS) ? FILE_OVERWRITTEN : FILE_DOES_NOT_EXIST;
+        break;
+    }
+    
+    TRACE("Returning status=%lx info=%lx\n", IoStatusBlock->u.Status, IoStatusBlock->Information);
+    return IoStatusBlock->u.Status;
 }
 
 /***********************************************************************
@@ -220,13 +399,15 @@
     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;
     case EINVAL:
     case ENOTEMPTY:    nt = STATUS_DIRECTORY_NOT_EMPTY;     break;
     case EPIPE:        nt = STATUS_PIPE_BROKEN;             break;
+    case ENOTDIR:      nt = STATUS_NOT_A_DIRECTORY;         break;
+    case ENOMEDIUM:    nt = STATUS_NO_MEDIA_IN_DEVICE;      break;
     case EIO:          nt = STATUS_DISK_CORRUPT_ERROR;      break;
     case ENOEXEC:      /* ?? */
     case ESPIPE:       /* ?? */
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll45/loader.c dlls/ntdll/loader.c
--- dlls/ntdll45/loader.c	2004-01-14 22:29:57.000000000 +0100
+++ dlls/ntdll/loader.c	2004-01-19 22:20:22.000000000 +0100
@@ -25,6 +25,8 @@
 #include <assert.h>
 #include <stdarg.h>
 
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winbase.h"
 #include "winnt.h"
@@ -1304,6 +1306,17 @@
     WCHAR *file_part, *ext;
     ULONG len;
 
+    IO_STATUS_BLOCK iosb;
+    OBJECT_ATTRIBUTES oa;
+    UNICODE_STRING ustr;
+
+    oa.Length = sizeof(oa);
+    oa.ObjectName = &ustr;
+    oa.RootDirectory = 0;
+    oa.SecurityDescriptor = NULL;
+    oa.SecurityQualityOfService = NULL;
+    oa.Attributes = 0;
+
     if (RtlDetermineDosPathNameType_U( libname ) == RELATIVE_PATH)
     {
         /* we need to search for it */
@@ -1336,9 +1349,11 @@
             {
                 if ((*pwm = find_basename_module( file_part )) != NULL) return STATUS_SUCCESS;
             }
-            *handle = pCreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-            return STATUS_SUCCESS;
-        }
+            RtlInitUnicodeString(&ustr, filename);
+            NtCreateFile(handle, GENERIC_READ, &oa, &iosb, NULL, 0, 
+                         FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_ALERT, NULL, 0);
+            return iosb.u.Status;
+         }
 
         /* not found */
 
@@ -1371,8 +1386,10 @@
         strcatW( file_part, dllW );
     }
     if ((*pwm = find_fullname_module( filename )) != NULL) return STATUS_SUCCESS;
-    *handle = pCreateFileW( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
-    return STATUS_SUCCESS;
+    RtlInitUnicodeString(&ustr, filename);
+    NtCreateFile(handle, GENERIC_READ, &oa, &iosb, NULL, 0, 
+                 FILE_SHARE_READ, FILE_OPEN, 0, NULL, 0);
+    return iosb.u.Status;
 
 overflow:
     *size = len + sizeof(WCHAR);
@@ -1801,7 +1818,7 @@
  *
  * FIXME: the arguments are not correct, main_file and CreateFileW_ptr are Wine inventions.
  */
-void WINAPI LdrInitializeThunk( HANDLE main_file, void *CreateFileW_ptr, ULONG unknown3, ULONG unknown4 )
+void WINAPI LdrInitializeThunk( HANDLE main_file, ULONG unknown2, ULONG unknown3, ULONG unknown4 )
 {
     NTSTATUS status;
     WINE_MODREF *wm;
@@ -1810,7 +1827,6 @@
     UNICODE_STRING *main_exe_name = &peb->ProcessParameters->ImagePathName;
     IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
 
-    pCreateFileW = CreateFileW_ptr;
     init_system_dir();
 
     /* allocate the modref for the main exe */
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll45/ntdll_misc.h dlls/ntdll/ntdll_misc.h
--- dlls/ntdll45/ntdll_misc.h	2004-02-01 17:27:34.000000000 +0100
+++ dlls/ntdll/ntdll_misc.h	2004-02-01 17:27:18.000000000 +0100
@@ -82,11 +82,6 @@
     return NtCurrentTeb()->Peb->ProcessParameters;
 }
 
-/* hack: upcall to kernel */
-extern HANDLE (WINAPI *pCreateFileW)( LPCWSTR filename, DWORD access, DWORD sharing,
-                                      LPSECURITY_ATTRIBUTES sa, DWORD creation,
-                                      DWORD attributes, HANDLE template );
-
 /* File IO */
 
 #define MAX_PATHNAME_LEN   1024
diff -u -N -r -x '*~' -x '.#*' -x CVS dlls/ntdll45/path.c dlls/ntdll/path.c
--- dlls/ntdll45/path.c	2004-01-23 22:32:54.000000000 +0100
+++ dlls/ntdll/path.c	2004-01-23 22:36:16.000000000 +0100
@@ -469,6 +469,7 @@
         reqsize += deplen + sizeof(WCHAR);
         goto done;
     }
+    
     memmove(buffer + reqsize / sizeof(WCHAR), name + dep, deplen + sizeof(WCHAR));
     if (reqsize) memcpy(buffer, ins_str, reqsize);
     reqsize += deplen;
diff -u -N -r -x '*~' -x '.#*' -x CVS files45/file.c files/file.c
--- files45/file.c	2004-01-23 22:32:12.000000000 +0100
+++ files/file.c	2004-01-23 22:35:54.000000000 +0100
@@ -207,85 +207,77 @@
  * Implementation of CreateFile. Takes a Unix path name.
  * Returns 0 on failure.
  */
-HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
+HANDLE FILE_CreateFile( LPCWSTR filename, DWORD access, DWORD sharing,
                         LPSECURITY_ATTRIBUTES sa, DWORD creation,
-                        DWORD attributes, HANDLE template, BOOL fail_read_only,
-                        UINT drive_type )
+                        DWORD attributes, HANDLE template )
 {
-    unsigned int err;
-    HANDLE ret;
-
-    for (;;)
-    {
-        SERVER_START_REQ( create_file )
-        {
-            req->access     = access;
-            req->inherit    = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-            req->sharing    = sharing;
-            req->create     = creation;
-            req->attrs      = attributes;
-            req->removable  = (drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_CDROM);
-            wine_server_add_data( req, filename, strlen(filename) );
-            SetLastError(0);
-            err = wine_server_call( req );
-            ret = reply->handle;
-        }
-        SERVER_END_REQ;
-
-        /* If write access failed, retry without GENERIC_WRITE */
-
-        if (!ret && !fail_read_only && (access & GENERIC_WRITE))
-        {
-            if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED))
-            {
-                TRACE("Write access failed for file '%s', trying without "
-                      "write access\n", filename);
-                access &= ~GENERIC_WRITE;
-                continue;
-            }
-        }
-
-        if (err)
-        {
-            /* In the case file creation was rejected due to CREATE_NEW flag
-             * was specified and file with that name already exists, correct
-             * last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
-             * Note: RtlNtStatusToDosError is not the subject to blame here.
-             */
-            if (err == STATUS_OBJECT_NAME_COLLISION)
-                SetLastError( ERROR_FILE_EXISTS );
-            else
-                SetLastError( RtlNtStatusToDosError(err) );
-        }
-
-        if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError());
-        return ret;
+    HANDLE              hFile;
+    UNICODE_STRING      ustr;
+    OBJECT_ATTRIBUTES   oa;
+    IO_STATUS_BLOCK     iosb;
+    ULONG               disp, opt = 0;
+    
+#define FILE_ATTRIBUTE_MASK     0x1FFF
+#define FILE_ATTRIBUTE_SUPP     (FILE_ATTRIBUTE_MASK | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_RANDOM_ACCESS)
+
+    if (attributes & ~FILE_ATTRIBUTE_SUPP)
+    {
+        FIXME("Unsupported flag (%lx)\n", attributes & ~FILE_ATTRIBUTE_SUPP);
+        SetLastError(ERROR_NOT_SUPPORTED);
+        return NULL;
+    }
+
+    oa.Length = sizeof(oa);
+    oa.ObjectName = &ustr;
+    oa.RootDirectory = 0;
+    oa.SecurityDescriptor = NULL;
+    oa.SecurityQualityOfService = NULL;
+    oa.Attributes = 0;
+    if (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle) 
+        oa.Attributes |= OBJ_INHERIT;
+
+    RtlInitUnicodeString(&ustr, filename);
+
+    switch (creation)
+    {
+    case CREATE_ALWAYS:     disp = FILE_OVERWRITE_IF; break;
+    case CREATE_NEW:        disp = FILE_CREATE; break;
+    case OPEN_ALWAYS:       disp = FILE_OPEN_IF; break;
+    case OPEN_EXISTING:     disp = FILE_OPEN; break;
+    case TRUNCATE_EXISTING: disp = FILE_OVERWRITE; break;
+    default: FIXME("Unknown creation flag\n"); disp = FILE_OPEN;
+    }
+    if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
+        opt |= FILE_OPEN_FOR_BACKUP_INTENT;
+    if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
+        opt |= FILE_DELETE_ON_CLOSE;
+    if (!(attributes & FILE_FLAG_OVERLAPPED))
+        opt |= FILE_SYNCHRONOUS_IO_ALERT;
+    if (attributes & FILE_FLAG_RANDOM_ACCESS)
+        opt |= FILE_RANDOM_ACCESS;
+
+    NtCreateFile(&hFile, access, &oa, &iosb, NULL, attributes & FILE_ATTRIBUTE_MASK, 
+                 sharing, disp, opt, NULL, 0);
+#undef FILE_ATTRIBUTE_MASK
+#undef FILE_ATTRIBUTE_SUPP
+
+    if (iosb.u.Status)
+    {
+        /* In the case file creation was rejected due to CREATE_NEW flag
+         * was specified and file with that name already exists, correct
+         * last error is ERROR_FILE_EXISTS and not ERROR_ALREADY_EXISTS.
+         * Note: RtlNtStatusToDosError is not the subject to blame here.
+         */
+        if (iosb.u.Status == STATUS_OBJECT_NAME_COLLISION)
+            SetLastError( ERROR_FILE_EXISTS );
+        else
+            SetLastError( RtlNtStatusToDosError(iosb.u.Status) );
+        hFile = 0;
     }
-}
-
 
-static HANDLE FILE_OpenPipe(LPCWSTR name, DWORD access, LPSECURITY_ATTRIBUTES sa )
-{
-    HANDLE ret;
-    DWORD len = 0;
-
-    if (name && (len = strlenW(name)) > MAX_PATH)
-    {
-        SetLastError( ERROR_FILENAME_EXCED_RANGE );
-        return 0;
-    }
-    SERVER_START_REQ( open_named_pipe )
-    {
-        req->access = access;
-        req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-        SetLastError(0);
-        wine_server_add_data( req, name, len * sizeof(WCHAR) );
-        wine_server_call_err( req );
-        ret = reply->handle;
-    }
-    SERVER_END_REQ;
-    TRACE("Returned %p\n",ret);
-    return ret;
+    if (!hFile) WARN("Unable to create file '%s' (GLE %ld)\n", 
+                     debugstr_w(filename), GetLastError());
+    return hFile;
 }
 
 /*************************************************************************
@@ -317,16 +309,17 @@
  * lot of the 'attributes' flags yet.
  */
 HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
-                              LPSECURITY_ATTRIBUTES sa, DWORD creation,
-                              DWORD attributes, HANDLE template )
+                           LPSECURITY_ATTRIBUTES sa, DWORD creation,
+                           DWORD attributes, HANDLE template )
 {
-    DOS_FULL_NAME full_name;
     HANDLE ret;
     static const WCHAR bkslashes_with_question_markW[] = {'\\','\\','?','\\',0};
     static const WCHAR bkslashes_with_dotW[] = {'\\','\\','.','\\',0};
     static const WCHAR bkslashesW[] = {'\\','\\',0};
     static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
     static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
+    static const WCHAR conW[] = {'C','O','N',0};
+    ULONG dd;
 
     if (!filename)
     {
@@ -361,28 +354,9 @@
 
     if (!strncmpW(filename, bkslashes_with_dotW, 4))
     {
-        static const WCHAR pipeW[] = {'P','I','P','E','\\',0};
-        if(!strncmpiW(filename + 4, pipeW, 5))
-        {
-            TRACE("Opening a pipe: %s\n", debugstr_w(filename));
-            ret = FILE_OpenPipe( filename, access, sa );
-            goto done;
-        }
-        filename += 4;
-    }
-
-    /* If the name still starts with '\\', it's a UNC name. */
-    if (!strncmpW(filename, bkslashesW, 2))
-    {
-        ret = SMB_CreateFileW(filename, access, sharing, sa, creation, attributes, template );
-        goto done;
-    }
-
-    /* If the name contains a DOS wild card (* or ?), do no create a file */
-    if(strchrW(filename, '*') || strchrW(filename, '?'))
-    {
-        SetLastError(ERROR_BAD_PATHNAME);
-        return INVALID_HANDLE_VALUE;
+       ret = FILE_CreateFile( filename, access, sharing,
+                               sa, creation, attributes, template );
+       goto done;
     }
 
     /* Open a console for CONIN$ or CONOUT$ */
@@ -392,69 +366,51 @@
         goto done;
     }
 
-    if ((isalphaW(filename[0]) && filename[1] == ':' && !filename[2]) ||
-        RtlIsDosDeviceName_U( filename ))
+    if ((dd = RtlIsDosDeviceName_U(filename)))
     {
-        char    buffer[MAX_PATH];
-        char    tmp[MAX_PATH], *ptr;
-        LPWSTR  p;
-        TRACE("opening device %s\n", debugstr_w(filename) );
-
-        if (isalphaW(filename[0]) && (filename[1] == ':') && filename[2]) filename += 2;
-        if ((p = strrchrW( filename, '/' ))) filename = p + 1;
-        if ((p = strrchrW( filename, '\\' ))) filename = p + 1;
-
-        WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, tmp, sizeof(tmp), NULL, NULL);
-        for (ptr = tmp; *ptr; ptr++) *ptr = tolower(*ptr);
-
-        sprintf(buffer, "%s/device/%s/device", wine_get_config_dir(), tmp);
-        if (tmp[0] == 'c' && tmp[1] == 'o' && tmp[2] == 'm' && isdigit(tmp[3]) &&
-            !tmp[4])
+        if (!strcmpiW(filename + LOWORD(dd), conW))
         {
-            SERVER_START_REQ( create_serial )
+            HANDLE to_dup;
+            switch (access & (GENERIC_READ|GENERIC_WRITE)) 
             {
-                req->access  = access;
-                req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
-                req->attributes = attributes;
-                req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
-                wine_server_add_data( req, buffer, strlen(buffer) );
-                SetLastError(0);
-                wine_server_call_err( req );
-                ret = reply->handle;
+            case GENERIC_READ:
+                to_dup = GetStdHandle( STD_INPUT_HANDLE );
+                break;
+            case GENERIC_WRITE:
+                to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
+                break;
+            default:
+                FIXME("can't open CON read/write\n");
+                return 0;
             }
-            SERVER_END_REQ;
-
-            if (!ret)
-                ERR("Couldn't open device '%s' ! (check permissions)\n", buffer);
-            else
-                TRACE("return %p\n", ret );
-        }
-        else
-        {
-            ret = FILE_CreateFile( buffer, access, sharing,
-                                   sa, creation, attributes, template,
-                                   FALSE, DRIVE_UNKNOWN );
+            if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
+                                  &ret, 0,
+                                  sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle,
+                                  DUPLICATE_SAME_ACCESS ))
+                ret = 0;
+            goto done;
         }
+    }
+
+    /* If the name still starts with '\\', it's a UNC name. */
+    if (!strncmpW(filename, bkslashesW, 2))
+    {
+        ret = SMB_CreateFileW(filename, access, sharing, sa, creation, attributes, template );
         goto done;
     }
 
-    /* check for filename, don't check for last entry if creating */
-    if (!DOSFS_GetFullName( filename,
-			    (creation == OPEN_EXISTING) ||
-			    (creation == TRUNCATE_EXISTING),
-			    &full_name )) {
-	WARN("Unable to get full filename from %s (GLE %ld)\n",
-	     debugstr_w(filename), GetLastError());
+    /* If the name contains a DOS wild card (* or ?), do no create a file */
+    if (strchrW(filename, '*') || strchrW(filename, '?'))
+    {
+        SetLastError(ERROR_BAD_PATHNAME);
         return INVALID_HANDLE_VALUE;
     }
 
-    ret = FILE_CreateFile( full_name.long_name, access, sharing,
-                           sa, creation, attributes, template,
-                           DRIVE_GetFlags(full_name.drive) & DRIVE_FAIL_READ_ONLY,
-                           GetDriveTypeW( full_name.short_name ) );
+    ret = FILE_CreateFile( filename, access, sharing,
+                           sa, creation, attributes, template );
  done:
     if (!ret) ret = INVALID_HANDLE_VALUE;
-    TRACE("returning %p\n", ret);
+
     return ret;
 }
 
@@ -1079,9 +1035,8 @@
 
     if (mode & OF_DELETE)
     {
-        handle = FILE_CreateFile( full_name.long_name, GENERIC_READ|GENERIC_WRITE, 0,
-                                 NULL, OPEN_EXISTING, 0, 0, TRUE,
-                                 GetDriveTypeW( full_name.short_name ) );
+        handle = FILE_CreateFile( nameW, GENERIC_READ|GENERIC_WRITE, 0,
+                                  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0 );
         if (!handle) goto error;
         CloseHandle( handle );
         if (unlink( full_name.long_name ) == -1) goto not_found;
@@ -1089,10 +1044,8 @@
         return 1;
     }
 
-    handle = FILE_CreateFile( full_name.long_name, access, sharing,
-                                NULL, OPEN_EXISTING, 0, 0,
-                                DRIVE_GetFlags(full_name.drive) & DRIVE_FAIL_READ_ONLY,
-                                GetDriveTypeW( full_name.short_name ) );
+    handle = FILE_CreateFile( nameW, access, sharing,
+                              NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0 );
     if (!handle) goto not_found;
 
     GetFileTime( handle, NULL, NULL, &filetime );
@@ -1417,9 +1370,8 @@
     if (!DOSFS_GetFullName( path, TRUE, &full_name )) return FALSE;
 
     /* check if we are allowed to delete the source */
-    hFile = FILE_CreateFile( full_name.long_name, GENERIC_READ|GENERIC_WRITE, 0,
-                             NULL, OPEN_EXISTING, 0, 0, TRUE,
-                             GetDriveTypeW( full_name.short_name ) );
+    hFile = FILE_CreateFile( path, GENERIC_READ|GENERIC_WRITE, 0,
+                             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, 0 );
     if (!hFile) return FALSE;
 
     if (unlink( full_name.long_name ) == -1)
@@ -1700,9 +1652,9 @@
         if ( attr == INVALID_FILE_ATTRIBUTES ) return FALSE;
 
         /* check if we are allowed to rename the source */
-        hFile = FILE_CreateFile( full_name1.long_name, 0, 0,
-                                 NULL, OPEN_EXISTING, 0, 0, TRUE,
-                                 GetDriveTypeW( full_name1.short_name ) );
+        hFile = FILE_CreateFile( fn1, 0, 0,
+                                 NULL, OPEN_EXISTING,
+                                 FILE_ATTRIBUTE_READONLY|FILE_FLAG_BACKUP_SEMANTICS, 0 );
         if (!hFile)
         {
             if (GetLastError() != ERROR_ACCESS_DENIED) return FALSE;
@@ -1713,9 +1665,9 @@
 
         /* check, if we are allowed to delete the destination,
         **     (but the file not being there is fine) */
-        hFile = FILE_CreateFile( full_name2.long_name, GENERIC_READ|GENERIC_WRITE, 0,
-                                 NULL, OPEN_EXISTING, 0, 0, TRUE,
-                                 GetDriveTypeW( full_name2.short_name ) );
+        hFile = FILE_CreateFile( fn2, GENERIC_READ|GENERIC_WRITE, 0,
+                                 NULL, OPEN_EXISTING, 
+                                 FILE_ATTRIBUTE_READONLY|FILE_FLAG_BACKUP_SEMANTICS, 0);
         if(!hFile && GetLastError() != ERROR_FILE_NOT_FOUND) return FALSE;
         CloseHandle(hFile);
 
diff -u -N -r -x '*~' -x '.#*' -x CVS include45/file.h include/file.h
--- include45/file.h	2004-01-18 22:29:49.000000000 +0100
+++ include/file.h	2004-01-19 22:40:11.000000000 +0100
@@ -63,10 +63,6 @@
 extern int FILE_strncasecmp( const char *str1, const char *str2, int len );
 extern void FILE_SetDosError(void);
 extern BOOL FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info, BOOL *is_symlink );
-extern HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
-                               LPSECURITY_ATTRIBUTES sa, DWORD creation,
-                               DWORD attributes, HANDLE template, BOOL fail_read_only,
-                               UINT drive_type );
 
 extern LONG WINAPI WIN16_hread(HFILE16,SEGPTR,LONG);
 
diff -u -N -r -x '*~' -x '.#*' -x CVS include45/winternl.h include/winternl.h
--- include45/winternl.h	2004-01-21 21:27:09.000000000 +0100
+++ include/winternl.h	2004-01-21 21:37:39.000000000 +0100
@@ -900,14 +900,30 @@
  */
 
 /* flags for NtCreateFile and NtOpenFile */
-#define FILE_DIRECTORY_FLAG  0x00000001
-#define FILE_WRITE_THROUGH   0x00000002
-#define FILE_SEQUENTIAL_ONLY 0x00000004
-#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
-#define FILE_SYNCHRONOUS_IO_ALERT    0x00000010
-#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
-#define FILE_NON_DIRECTORY_FILE      0x00000040
-#define FILE_CREATE_TREE_CONNECTION  0x00000080
+#define FILE_DIRECTORY_FILE                     0x00000001
+#define FILE_WRITE_THROUGH                      0x00000002
+#define FILE_SEQUENTIAL_ONLY                    0x00000004
+#define FILE_NO_INTERMEDIATE_BUFFERING          0x00000008
+#define FILE_SYNCHRONOUS_IO_ALERT               0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT            0x00000020
+#define FILE_NON_DIRECTORY_FILE                 0x00000040
+#define FILE_CREATE_TREE_CONNECTION             0x00000080
+#define FILE_COMPLETE_IF_OPLOCKED               0x00000100
+#define FILE_NO_EA_KNOWLEDGE                    0x00000200
+#define FILE_OPEN_FOR_RECOVERY                  0x00000400
+#define FILE_RANDOM_ACCESS                      0x00000800
+#define FILE_DELETE_ON_CLOSE                    0x00001000
+#define FILE_OPEN_BY_FILE_ID                    0x00002000
+#define FILE_OPEN_FOR_BACKUP_INTENT             0x00004000
+#define FILE_NO_COMPRESSION                     0x00008000
+#define FILE_RESERVE_OPFILTER                   0x00100000
+#define FILE_TRANSACTED_MODE                    0x00200000
+#define FILE_OPEN_OFFLINE_FILE                  0x00400000
+
+#define FILE_VALID_OPTION_FLAGS                 0x007fffff
+#define FILE_VALID_PIPE_OPTION_FLAGS            0x00000032
+#define FILE_VALID_MAILSLOT_OPTION_FLAGS        0x00000032
+#define FILE_VALID_SET_FLAGS                    0x00001036
 
 /* status for NtCreateFile or NtOpenFile */
 #define FILE_SUPERSEDED  0x00000000
@@ -917,6 +933,24 @@
 #define FILE_EXISTS      0x00000004
 #define FILE_DOES_NOT_EXIST 0x00000005
 
+/* disposition for NtCreateFile */
+#define FILE_SUPERSEDE                  0x0000
+#define FILE_OPEN                       0x0001
+#define FILE_CREATE                     0x0002
+#define FILE_OPEN_IF                    0x0003
+#define FILE_OVERWRITE                  0x0004
+#define FILE_OVERWRITE_IF               0x0005
+#define FILE_MAXIMUM_DISPOSITION        0x0005
+
+/* Characteristics of a File System */
+#define FILE_REMOVABLE_MEDIA            0x00000001
+#define FILE_READ_ONLY_DEVICE           0x00000002
+#define FILE_FLOPPY_DISKETTE            0x00000004
+#define FILE_WRITE_ONE_MEDIA            0x00000008
+#define FILE_REMOTE_DEVICE              0x00000010
+#define FILE_DEVICE_IS_MOUNTED          0x00000020
+#define FILE_VIRTUAL_VOLUME             0x00000040
+
 /* Characteristics of a File System */
 #define FILE_REMOVABLE_MEDIA            0x00000001
 #define FILE_READ_ONLY_DEVICE           0x00000002
@@ -967,7 +1001,7 @@
 NTSTATUS  WINAPI LdrFindResource_U(HMODULE,const LDR_RESOURCE_INFO*,ULONG,const IMAGE_RESOURCE_DATA_ENTRY**);
 NTSTATUS  WINAPI LdrGetDllHandle(ULONG, ULONG, const UNICODE_STRING*, HMODULE*);
 NTSTATUS  WINAPI LdrGetProcedureAddress(HMODULE, const ANSI_STRING*, ULONG, void**);
-void      WINAPI LdrInitializeThunk(HANDLE,LPVOID,ULONG,ULONG);
+void      WINAPI LdrInitializeThunk(HANDLE,ULONG,ULONG,ULONG);
 NTSTATUS  WINAPI LdrLoadDll(LPCWSTR, DWORD, const UNICODE_STRING*, HMODULE*);
 void      WINAPI LdrShutdownProcess(void);
 void      WINAPI LdrShutdownThread(void);
diff -u -N -r -x '*~' -x '.#*' -x CVS misc45/registry.c misc/registry.c
--- misc45/registry.c	2004-01-23 22:32:13.000000000 +0100
+++ misc/registry.c	2004-01-23 22:35:55.000000000 +0100
@@ -57,12 +57,13 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
+#include "winreg.h"
 
 #include "wine/winbase16.h"
 #include "wine/library.h"
 #include "wine/server.h"
 #include "wine/unicode.h"
-#include "file.h"
+#include "kernel_private.h"
 
 #include "wine/debug.h"
 
@@ -1182,26 +1183,24 @@
     /* test %windir%/system32/config/system --> winnt */
     strcpyW(tmp, windir);
     strcatW(tmp, nt_reg_pathW);
-    if(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES)
-      ret = REG_WINNT;
+    if (RtlDoesFileExists_U(tmp)) ret = REG_WINNT;
     else
     {
        /* test %windir%/system.dat --> win95 */
       strcpyW(tmp, windir);
       strcatW(tmp, win9x_reg_pathW);
-      if(GetFileAttributesW(tmp) != INVALID_FILE_ATTRIBUTES)
-        ret = REG_WIN95;
+      if (RtlDoesFileExists_U(tmp)) ret = REG_WIN95;
     }
 
     return ret;
 }
 
 /* load the registry file in wine format [Internal] */
-static void load_wine_registry(HKEY hkey,LPCSTR fn)
+static void load_wine_registry(HKEY hkey, LPCSTR fn)
 {
     HANDLE file;
-    if ((file = FILE_CreateFile( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
-                                 FILE_ATTRIBUTE_NORMAL, 0, TRUE, DRIVE_UNKNOWN )))
+    if ((file = CreateFileA( fn, GENERIC_READ, 0, NULL, OPEN_EXISTING,
+                             FILE_ATTRIBUTE_NORMAL, 0 )))
     {
         SERVER_START_REQ( load_registry )
         {
@@ -1817,4 +1816,6 @@
     NtClose(hkey_users);
     NtClose(hkey_local_machine);
     NtClose(hkey_config);
+
+    return;
 }
diff -u -N -r -x '*~' -x '.#*' -x CVS server45/file.c server/file.c
--- server45/file.c	2004-01-14 22:29:59.000000000 +0100
+++ server/file.c	2004-01-19 22:15:05.000000000 +0100
@@ -43,6 +43,8 @@
 #include "winerror.h"
 #include "windef.h"
 #include "winbase.h"
+#include "winreg.h"
+#include "winternl.h"
 
 #include "file.h"
 #include "handle.h"
@@ -57,9 +59,9 @@
     struct file        *next;       /* next file in hashing list */
     char               *name;       /* file name */
     unsigned int        access;     /* file access (GENERIC_READ/WRITE) */
-    unsigned int        flags;      /* flags (FILE_FLAG_*) */
+    unsigned int        options;    /* options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
     unsigned int        sharing;    /* file sharing mode */
-    int                 removable;     /* is file on removable media? */
+    int                 removable;  /* is file on removable media ? */
     struct async_queue  read_q;
     struct async_queue  write_q;
 };
@@ -133,8 +135,7 @@
 
 /* create a file from a file descriptor */
 /* if the function fails the fd is closed */
-static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing,
-                                        unsigned int attrs, int removable )
+static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing)
 {
     struct file *file;
 
@@ -143,14 +144,9 @@
         file->name       = NULL;
         file->next       = NULL;
         file->access     = access;
-        file->flags      = attrs;
+        file->options    = FILE_SYNCHRONOUS_IO_NONALERT;
         file->sharing    = sharing;
-        file->removable  = removable;
-        if (file->flags & FILE_FLAG_OVERLAPPED)
-        {
-            init_async_queue (&file->read_q);
-            init_async_queue (&file->write_q);
-        }
+        file->removable  = FALSE;
         if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj )))
         {
             release_object( file );
@@ -162,8 +158,8 @@
 
 
 static struct file *create_file( const char *nameptr, size_t len, unsigned int access,
-                                 unsigned int sharing, int create, unsigned int attrs,
-                                 int removable )
+                                 unsigned int sharing, int createdisp, int createopt, 
+                                 unsigned int attrs, unsigned int removable )
 {
     struct file *file;
     int hash, flags;
@@ -178,16 +174,17 @@
     hash = get_name_hash( name );
     if (!check_sharing( name, hash, access, sharing )) goto error;
 
-    switch(create)
+    switch (createdisp)
     {
-    case CREATE_NEW:        flags = O_CREAT | O_EXCL; break;
-    case CREATE_ALWAYS:     flags = O_CREAT | O_TRUNC; break;
-    case OPEN_ALWAYS:       flags = O_CREAT; break;
-    case TRUNCATE_EXISTING: flags = O_TRUNC; break;
-    case OPEN_EXISTING:     flags = 0; break;
+    case FILE_CREATE:       flags = O_CREAT | O_EXCL; break;
+    case FILE_OVERWRITE_IF: /* FIXME: the difference is whether we trash existing attr or not */
+    case FILE_SUPERSEDE:    flags = O_CREAT | O_TRUNC; break;
+    case FILE_OPEN:         flags = 0; break;
+    case FILE_OPEN_IF:      flags = O_CREAT; break;
+    case FILE_OVERWRITE:    flags = O_TRUNC; break;
     default:                set_error( STATUS_INVALID_PARAMETER ); goto error;
     }
-    switch(access & (GENERIC_READ | GENERIC_WRITE))
+    switch (access & (GENERIC_READ | GENERIC_WRITE))
     {
     case 0: break;
     case GENERIC_READ:  flags |= O_RDONLY; break;
@@ -203,13 +200,13 @@
     if (!(file = alloc_object( &file_ops ))) goto error;
 
     file->access     = access;
-    file->flags      = attrs;
+    file->options    = createopt;
     file->sharing    = sharing;
     file->removable  = removable;
     file->name       = name;
     file->next       = file_hash[hash];
     file_hash[hash]  = file;
-    if (file->flags & FILE_FLAG_OVERLAPPED)
+    if (!(file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
     {
         init_async_queue (&file->read_q);
         init_async_queue (&file->write_q);
@@ -223,7 +220,7 @@
         return NULL;
     }
     /* refuse to open a directory */
-    if (S_ISDIR(mode) && !(file->flags & FILE_FLAG_BACKUP_SEMANTICS))
+    if (S_ISDIR(mode) && !(createopt & FILE_OPEN_FOR_BACKUP_INTENT))
     {
         set_error( STATUS_ACCESS_DENIED );
         release_object( file );
@@ -262,14 +259,15 @@
         return NULL;
     }
     unlink( tmpfn );
-    return create_file_for_fd( fd, access, 0, 0, FALSE );
+    return create_file_for_fd( fd, access, 0);
 }
 
 static void file_dump( struct object *obj, int verbose )
 {
     struct file *file = (struct file *)obj;
     assert( obj->ops == &file_ops );
-    fprintf( stderr, "File fd=%p flags=%08x name='%s'\n", file->fd, file->flags, file->name );
+    fprintf( stderr, "File fd=%p options=%08x name='%s'\n", 
+             file->fd, file->options, file->name );
 }
 
 static int file_get_poll_events( struct fd *fd )
@@ -286,7 +284,7 @@
 {
     struct file *file = get_fd_user( fd );
     assert( file->obj.ops == &file_ops );
-    if ( file->flags & FILE_FLAG_OVERLAPPED )
+    if (!(file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
     {
         if( IS_READY(file->read_q) && (POLLIN & event) )
         {
@@ -354,7 +352,8 @@
         reply->serial      = 0; /* FIXME */
     }
     *flags = 0;
-    if (file->flags & FILE_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED;
+    if (!(file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
+        *flags |= FD_FLAG_OVERLAPPED;
     return FD_TYPE_DEFAULT;
 }
 
@@ -366,7 +365,7 @@
 
     assert( file->obj.ops == &file_ops );
 
-    if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
+    if (file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT))
     {
         set_error ( STATUS_INVALID_HANDLE );
         return;
@@ -429,10 +428,10 @@
         while (*pptr && *pptr != file) pptr = &(*pptr)->next;
         assert( *pptr );
         *pptr = (*pptr)->next;
-        if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
+        if (file->options & FILE_DELETE_ON_CLOSE) unlink( file->name );
         free( file->name );
     }
-    if (file->flags & FILE_FLAG_OVERLAPPED)
+    if (!(file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)))
     {
         destroy_async_queue (&file->read_q);
         destroy_async_queue (&file->write_q);
@@ -462,6 +461,7 @@
     case ESPIPE:    set_win32_error( ERROR_SEEK ); break;
     case ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
     case EIO:       set_error( STATUS_ACCESS_VIOLATION ); break;
+    case ENOTDIR:   set_error( STATUS_NOT_A_DIRECTORY ); break;
 #ifdef EOVERFLOW
     case EOVERFLOW: set_error( STATUS_INVALID_PARAMETER ); break;
 #endif
@@ -600,7 +600,8 @@
 
     reply->handle = 0;
     if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
-                             req->sharing, req->create, req->attrs, req->removable )))
+                             req->sharing, req->create_disp, req->create_opt,
+                             req->attrs, req->removable )))
     {
         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
         release_object( file );
@@ -619,8 +620,7 @@
         set_error( STATUS_INVALID_HANDLE );
         return;
     }
-    if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                    0, FALSE )))
+    if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE )))
     {
         reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
         release_object( file );
@@ -665,7 +665,7 @@
     if ((file = get_file_obj( current->process, req->handle, 0 )))
     {
         reply->handle = lock_fd( file->fd, offset, count, req->shared, req->wait );
-        reply->overlapped = (file->flags & FILE_FLAG_OVERLAPPED) != 0;
+        reply->overlapped = (file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT)) == 0;
         release_object( file );
     }
 }
diff -u -N -r -x '*~' -x '.#*' -x CVS server45/protocol.def server/protocol.def
--- server45/protocol.def	2004-01-18 21:11:59.000000000 +0100
+++ server/protocol.def	2004-01-19 22:10:44.000000000 +0100
@@ -574,7 +574,8 @@
     unsigned int access;        /* wanted access rights */
     int          inherit;       /* inherit flag */
     unsigned int sharing;       /* sharing flags */
-    int          create;        /* file create action */
+    int          create_disp;   /* file create action */
+    int          create_opt;    /* file create options */
     unsigned int attrs;         /* file attributes for creation */
     int          removable;     /* is file on removable media? */
     VARARG(filename,string);    /* file name */


More information about the wine-patches mailing list