Unicodify the create_file server call
Mike McCormack
mikem at codeweavers.com
Wed Jun 19 20:48:24 CDT 2002
This patch makes the server interface for opening files unicode. It also
intentionally breaks NtOpenFile, since the implemenation was a bad hack.
Mike
License: LGPL
ChangeLog:
* unicodify the create_file server call
* use unicode for filenames inside the server
-------------- next part --------------
Index: dlls/ntdll/file.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/file.c,v
retrieving revision 1.14
diff -u -r1.14 file.c
--- dlls/ntdll/file.c 14 Jun 2002 00:36:20 -0000 1.14
+++ dlls/ntdll/file.c 19 Jun 2002 17:23:09 -0000
@@ -30,7 +30,6 @@
#include "wine/debug.h"
#include "wine/server.h"
#include "ntdll_misc.h"
-#include "file.h" /* FIXME */
#include "ntddk.h"
#include "winioctl.h"
@@ -58,12 +57,8 @@
ULONG ShareAccess,
ULONG OpenOptions)
{
- ULONG len = 0;
- PSTR filename;
- CHAR szDosDevices[] = "\\DosDevices\\";
- DOS_FULL_NAME full_name;
NTSTATUS r;
-
+
FIXME("(%p,0x%08lx,%p,%p,0x%08lx,0x%08lx) partial stub\n",
FileHandle, DesiredAccess, ObjectAttributes,
IoStatusBlock, ShareAccess, OpenOptions);
@@ -77,24 +72,7 @@
return STATUS_OBJECT_NAME_NOT_FOUND;
}
- /* create an ascii string from the unicode filename */
- RtlUnicodeToMultiByteSize( &len, ObjectAttributes->ObjectName->Buffer,
- ObjectAttributes->ObjectName->Length );
- filename = RtlAllocateHeap( GetProcessHeap(), 0, len + 1);
- RtlUnicodeToMultiByteN(filename, len, NULL, ObjectAttributes->ObjectName->Buffer,
- ObjectAttributes->ObjectName->Length );
- filename[len]=0;
-
- /* FIXME: DOSFS stuff should call here, not vice-versa */
- if(strncmp(filename, szDosDevices, strlen(szDosDevices)))
- return STATUS_OBJECT_NAME_NOT_FOUND;
-
- /* FIXME: this calls SetLastError() -> bad */
- if(!DOSFS_GetFullName(&filename[strlen(szDosDevices)], TRUE,
- &full_name))
- return STATUS_OBJECT_NAME_NOT_FOUND;
-
- /* FIXME: modify server protocol so
+ /* FIXME: modify server protocol so
create file takes an OBJECT_ATTRIBUTES structure */
SERVER_START_REQ( create_file )
{
@@ -103,9 +81,8 @@
req->sharing = ShareAccess;
req->create = OPEN_EXISTING;
req->attrs = 0;
- req->drive_type = GetDriveTypeA( full_name.short_name );
- wine_server_add_data( req, full_name.long_name, strlen(full_name.long_name) );
- SetLastError(0);
+ req->drive_type = -1;
+ wine_server_add_data( req, ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length );
r = wine_server_call( req );
*FileHandle = reply->handle;
}
Index: files/file.c
===================================================================
RCS file: /home/wine/wine/files/file.c,v
retrieving revision 1.149
diff -u -r1.149 file.c
--- files/file.c 5 Jun 2002 00:47:38 -0000 1.149
+++ files/file.c 19 Jun 2002 17:23:11 -0000
@@ -378,6 +378,8 @@
{
unsigned int err;
HANDLE ret;
+ WCHAR name[MAX_PATH];
+ int len = MultiByteToWideChar(CP_ACP,0,filename,-1,name,MAX_PATH);
for (;;)
{
@@ -389,7 +391,7 @@
req->create = creation;
req->attrs = attributes;
req->drive_type = drive_type;
- wine_server_add_data( req, filename, strlen(filename) );
+ wine_server_add_data( req, name, len*sizeof(WCHAR) );
SetLastError(0);
err = wine_server_call( req );
ret = reply->handle;
@@ -403,7 +405,7 @@
if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED))
{
TRACE("Write access failed for file '%s', trying without "
- "write access\n", filename);
+ "write access\n", debugstr_w(name));
access &= ~GENERIC_WRITE;
continue;
}
@@ -411,7 +413,7 @@
if (err) SetLastError( RtlNtStatusToDosError(err) );
- if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError());
+ if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", debugstr_wn(name,len), GetLastError());
return ret;
}
}
Index: server/file.c
===================================================================
RCS file: /home/wine/wine/server/file.c,v
retrieving revision 1.58
diff -u -r1.58 file.c
--- server/file.c 30 May 2002 20:12:58 -0000 1.58
+++ server/file.c 19 Jun 2002 17:23:11 -0000
@@ -44,12 +44,13 @@
#include "thread.h"
#include "request.h"
#include "async.h"
+#include "unicode.h"
struct file
{
struct object obj; /* object header */
struct file *next; /* next file in hashing list */
- char *name; /* file name */
+ WCHAR *name; /* file name */
unsigned int access; /* file access (GENERIC_READ/WRITE) */
unsigned int flags; /* flags (FILE_FLAG_*) */
unsigned int sharing; /* file sharing mode */
@@ -89,16 +90,16 @@
};
-static int get_name_hash( const char *name )
+static int get_name_hash( const WCHAR *name )
{
int hash = 0;
- while (*name) hash ^= (unsigned char)*name++;
+ while (*name) hash ^= (unsigned short)*name++;
return hash % NAME_HASH_SIZE;
}
/* check if the desired access is possible without violating */
/* the sharing mode of other opens of the same file */
-static int check_sharing( const char *name, int hash, unsigned int access,
+static int check_sharing( const WCHAR *name, int hash, unsigned int access,
unsigned int sharing )
{
struct file *file;
@@ -107,7 +108,7 @@
for (file = file_hash[hash]; file; file = file->next)
{
- if (strcmp( file->name, name )) continue;
+ if (strcmpW( file->name, name )) continue;
existing_sharing &= file->sharing;
existing_access |= file->access;
}
@@ -144,20 +145,19 @@
return file;
}
-
-static struct file *create_file( const char *nameptr, size_t len, unsigned int access,
+struct object *create_file( const WCHAR *nameptr, size_t len, unsigned int access,
unsigned int sharing, int create, unsigned int attrs,
int drive_type )
{
struct file *file;
int hash, flags;
struct stat st;
- char *name;
+ WCHAR *name, szwCom[] = {'.','c','o','m',0 }, szwExe[] = {'.','e','x','e',0 };
int fd = -1;
mode_t mode;
- if (!(name = mem_alloc( len + 1 ))) return NULL;
- memcpy( name, nameptr, len );
+ if (!(name = mem_alloc( (len+1)*sizeof (WCHAR) ))) return NULL;
+ memcpy( name, nameptr, len*sizeof (WCHAR) );
name[len] = 0;
/* check sharing mode */
@@ -183,11 +183,11 @@
mode = (attrs & FILE_ATTRIBUTE_READONLY) ? 0444 : 0666;
if (len >= 4 &&
- (!strcasecmp( name + len - 4, ".exe" ) || !strcasecmp( name + len - 4, ".com" )))
+ (!strcmpiW( name + len - 4, szwExe ) || !strcmpiW( name + len - 4, szwCom )))
mode |= 0111;
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
- if ((fd = open( name, flags | O_NONBLOCK | O_LARGEFILE, mode )) == -1 )
+ if ((fd = openw( name, flags | O_NONBLOCK | O_LARGEFILE, mode )) == -1 )
goto file_error;
/* refuse to open a directory */
if (fstat( fd, &st ) == -1) goto file_error;
@@ -205,7 +205,7 @@
file->name = name;
file->next = file_hash[hash];
file_hash[hash] = file;
- return file;
+ return &file->obj;
file_error:
file_set_error();
@@ -218,7 +218,7 @@
/* check if two file objects point to the same file */
int is_same_file( struct file *file1, struct file *file2 )
{
- return !strcmp( file1->name, file2->name );
+ return !strcmpW( file1->name, file2->name );
}
/* get the type of drive the file is on */
@@ -264,7 +264,9 @@
{
struct file *file = (struct file *)obj;
assert( obj->ops == &file_ops );
- fprintf( stderr, "File fd=%d flags=%08x name='%s'\n", file->obj.fd, file->flags, file->name );
+ fprintf( stderr, "File fd=%d flags=%08x name=", file->obj.fd, file->flags );
+ dump_strW(file->name,strlenW(file->name),stderr,"[]");
+ fprintf( stderr, "\n" );
}
static int file_get_poll_events( struct object *obj )
@@ -427,7 +429,7 @@
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->flags & FILE_FLAG_DELETE_ON_CLOSE) unlinkw( file->name );
free( file->name );
}
if (file->flags & FILE_FLAG_OVERLAPPED)
@@ -564,13 +566,13 @@
if (!access_time || !write_time)
{
struct stat st;
- if (stat( file->name, &st ) == -1) goto error;
+ if (statw( file->name, &st ) == -1) goto error;
if (!access_time) access_time = st.st_atime;
if (!write_time) write_time = st.st_mtime;
}
utimbuf.actime = access_time;
utimbuf.modtime = write_time;
- if (utime( file->name, &utimbuf ) == -1) goto error;
+ if (utimew( file->name, &utimbuf ) == -1) goto error;
release_object( file );
return 1;
error:
@@ -596,11 +598,24 @@
/* create a file */
DECL_HANDLER(create_file)
{
- struct file *file;
+ struct object *file = NULL;
+ const WCHAR *name = get_req_data();
+ int len = get_req_data_size()/sizeof (WCHAR);
reply->handle = 0;
- if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
- req->sharing, req->create, req->attrs, req->drive_type )))
+
+ if(len && (name[0]!='/')) /* nt path name */
+ {
+ /* FIXME: open an NT path here */
+ set_error(STATUS_ACCESS_DENIED);
+ }
+ else
+ {
+ file = create_file( name, len, req->access,
+ req->sharing, req->create, req->attrs, req->drive_type );
+ }
+
+ if (file)
{
reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
release_object( file );
Index: server/protocol.def
===================================================================
RCS file: /home/wine/wine/server/protocol.def,v
retrieving revision 1.39
diff -u -r1.39 protocol.def
--- server/protocol.def 2 Jun 2002 21:22:22 -0000 1.39
+++ server/protocol.def 19 Jun 2002 17:23:12 -0000
@@ -572,7 +572,7 @@
int create; /* file create action */
unsigned int attrs; /* file attributes for creation */
int drive_type; /* type of drive the file is on */
- VARARG(filename,string); /* file name */
+ VARARG(filename,unicode_str); /* file name */
@REPLY
obj_handle_t handle; /* handle to the file */
@END
Index: server/unicode.c
===================================================================
RCS file: /home/wine/wine/server/unicode.c,v
retrieving revision 1.4
diff -u -r1.4 unicode.c
--- server/unicode.c 26 Apr 2002 19:05:18 -0000 1.4
+++ server/unicode.c 19 Jun 2002 17:23:12 -0000
@@ -24,8 +24,18 @@
#include <ctype.h>
#include <stdio.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
+#include "thread.h"
#include "unicode.h"
+static const union cptable *ansi_cptable;
+
+
/* dump a Unicode string with proper escaping */
int dump_strW( const WCHAR *str, size_t len, FILE *f, char escape[2] )
{
@@ -68,3 +78,85 @@
count += pos - buffer;
return count;
}
+
+int strcasecmpnW(const WCHAR *x, const WCHAR *y, int n)
+{
+ int i;
+ for(i=0; i<n; i++)
+ {
+ if((x[i]&~0x20)>(y[i]&~0x20))
+ return 1;
+ if((x[i]&~0x20)<(y[i]&~0x20))
+ return -1;
+ }
+ return 0;
+}
+
+/* FIXME: hardcoded to ANSI for the time being */
+
+int file_unicode_to_apath(const WCHAR *path_w, char *path_a, int len)
+{
+ if(!ansi_cptable)
+ ansi_cptable = cp_get_table( 1252 );
+ return cp_wcstombs( ansi_cptable, 0, path_w, -1, path_a, len, NULL, NULL);
+}
+
+int file_apath_to_unicode(const char *path_a, WCHAR *path_w, int len)
+{
+ if(!ansi_cptable)
+ ansi_cptable = cp_get_table( 1252 );
+ return cp_mbstowcs( ansi_cptable, 0, path_a, -1, path_w, len);
+}
+
+int openw(const WCHAR *name, int access, int mode)
+{
+ char name_a[MAX_PATH];
+ name_a[0]=0;
+ file_unicode_to_apath(name,name_a,MAX_PATH);
+ return open(name_a,access,mode);
+}
+
+int unlinkw(const WCHAR *name)
+{
+ char name_a[MAX_PATH];
+ name_a[0]=0;
+ file_unicode_to_apath(name,name_a,MAX_PATH);
+ return unlink(name_a);
+}
+
+int statw(const WCHAR *name, struct stat *st)
+{
+ char name_a[MAX_PATH];
+ name_a[0]=0;
+ file_unicode_to_apath(name,name_a,MAX_PATH);
+ return stat(name_a,st);
+}
+
+int utimew(const WCHAR *name, struct utimbuf *utimbuf)
+{
+ char name_a[MAX_PATH];
+ name_a[0]=0;
+ file_unicode_to_apath(name,name_a,MAX_PATH);
+ return utime(name_a,utimbuf);
+}
+
+DIR *opendirw(const WCHAR *name)
+{
+ char name_a[MAX_PATH];
+ name_a[0]=0;
+ file_unicode_to_apath(name,name_a,MAX_PATH);
+ return opendir(name_a);
+}
+
+static struct direntw g_de;
+
+struct direntw *readdirw(DIR *dir)
+{
+ struct dirent *de = readdir(dir);
+ if(!de)
+ return NULL;
+ g_de.d_name[0]=0;
+ file_apath_to_unicode(de->d_name, g_de.d_name, sizeof(g_de.d_name)/sizeof(WCHAR));
+ return &g_de;
+}
+
Index: server/unicode.h
===================================================================
RCS file: /home/wine/wine/server/unicode.h,v
retrieving revision 1.8
diff -u -r1.8 unicode.h
--- server/unicode.h 10 Mar 2002 00:18:36 -0000 1.8
+++ server/unicode.h 19 Jun 2002 17:23:12 -0000
@@ -22,6 +22,9 @@
#define __WINE_SERVER_UNICODE_H
#include <stdio.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <utime.h>
#include "windef.h"
#include "wine/unicode.h"
@@ -35,4 +38,20 @@
extern int dump_strW( const WCHAR *str, size_t len, FILE *f, char escape[2] );
+extern int strcasecmpnW(const WCHAR *x, const WCHAR *y, int n);
+
+extern int openw(const WCHAR *name, int access, int mode);
+extern int unlinkw(const WCHAR *name);
+extern int statw(const WCHAR *name, struct stat *st);
+extern int utimew(const WCHAR *name, struct utimbuf *utimbuf);
+
+struct direntw
+{
+ WCHAR d_name[NAME_MAX+1];
+};
+
+extern DIR *opendirw(const WCHAR *name);
+extern struct direntw *readdirw(DIR *dir);
+
#endif /* __WINE_SERVER_UNICODE_H */
+
More information about the wine-patches
mailing list