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