Commit 0562539d authored by Alexandre Julliard's avatar Alexandre Julliard

Implemented file sharing checks in the server.

Added set file time server request. Overall clean up of the file handling (DOS device handling is now broken, should be redone).
parent 74304fc3
...@@ -607,12 +607,10 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name ) ...@@ -607,12 +607,10 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
* *
* Open a DOS device. This might not map 1:1 into the UNIX device concept. * Open a DOS device. This might not map 1:1 into the UNIX device concept.
*/ */
HFILE32 DOSFS_OpenDevice( const char *name, int unixmode ) HFILE32 DOSFS_OpenDevice( const char *name, DWORD access )
{ {
int i; int i;
const char *p; const char *p;
FILE_OBJECT *file;
HFILE32 handle;
if (!name) return (HFILE32)NULL; /* if FILE_DupUnixHandle was used */ if (!name) return (HFILE32)NULL; /* if FILE_DupUnixHandle was used */
if (name[0] && (name[1] == ':')) name += 2; if (name[0] && (name[1] == ':')) name += 2;
...@@ -627,15 +625,17 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode ) ...@@ -627,15 +625,17 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode )
if (!*p || (*p == '.')) { if (!*p || (*p == '.')) {
/* got it */ /* got it */
if (!strcmp(DOSFS_Devices[i].name,"NUL")) if (!strcmp(DOSFS_Devices[i].name,"NUL"))
return FILE_OpenUnixFile("/dev/null",unixmode); return FILE_CreateFile( "/dev/null", access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1 );
if (!strcmp(DOSFS_Devices[i].name,"CON")) { if (!strcmp(DOSFS_Devices[i].name,"CON")) {
HFILE32 to_dup; HFILE32 to_dup;
HFILE32 handle; HFILE32 handle;
switch (unixmode) { switch (access & (GENERIC_READ|GENERIC_WRITE)) {
case O_RDONLY: case GENERIC_READ:
to_dup = GetStdHandle( STD_INPUT_HANDLE ); to_dup = GetStdHandle( STD_INPUT_HANDLE );
break; break;
case O_WRONLY: case GENERIC_WRITE:
to_dup = GetStdHandle( STD_OUTPUT_HANDLE ); to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
break; break;
default: default:
...@@ -651,8 +651,10 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode ) ...@@ -651,8 +651,10 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode )
if (!strcmp(DOSFS_Devices[i].name,"SCSIMGR$") || if (!strcmp(DOSFS_Devices[i].name,"SCSIMGR$") ||
!strcmp(DOSFS_Devices[i].name,"HPSCAN")) !strcmp(DOSFS_Devices[i].name,"HPSCAN"))
{ {
int fd = open( "/dev/null", unixmode ); /* FIXME: should keep the name somewhere */
return FILE_Alloc( &file, fd, DOSFS_Devices[i].name ); return FILE_CreateFile( "/dev/null", access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1 );
} }
FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i].name); FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i].name);
return HFILE_ERROR32; return HFILE_ERROR32;
......
#ifndef __WINE_DEVICE_H #ifndef __WINE_DEVICE_H
#define __WINE_DEVICE_H #define __WINE_DEVICE_H
extern HANDLE32 DEVICE_Open( LPCSTR name, DWORD flags); extern HANDLE32 DEVICE_Open( LPCSTR name);
#endif #endif
...@@ -17,9 +17,7 @@ ...@@ -17,9 +17,7 @@
typedef struct typedef struct
{ {
K32OBJ header; K32OBJ header;
int mode;
char *unix_name; char *unix_name;
DWORD type; /* Type for win32 apps */
} FILE_OBJECT; } FILE_OBJECT;
/* Definition of a full DOS file name */ /* Definition of a full DOS file name */
...@@ -60,15 +58,13 @@ typedef struct ...@@ -60,15 +58,13 @@ typedef struct
extern FILE_OBJECT *FILE_GetFile( HFILE32 handle, DWORD access, extern FILE_OBJECT *FILE_GetFile( HFILE32 handle, DWORD access,
int *server_handle ); int *server_handle );
extern void FILE_ReleaseFile( FILE_OBJECT *file ); extern void FILE_ReleaseFile( FILE_OBJECT *file );
extern HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle, const char *unix_name );
extern void FILE_SetDosError(void); extern void FILE_SetDosError(void);
extern HFILE32 FILE_DupUnixHandle( int fd ); extern HFILE32 FILE_DupUnixHandle( int fd, DWORD access );
extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
extern HFILE32 FILE_Dup( HFILE32 hFile );
extern HFILE32 FILE_Dup2( HFILE32 hFile1, HFILE32 hFile2 ); extern HFILE32 FILE_Dup2( HFILE32 hFile1, HFILE32 hFile2 );
extern HFILE32 FILE_Open( LPCSTR path, INT32 mode ,INT32 sharemode); extern HFILE32 FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
extern HFILE32 FILE_OpenUnixFile( LPCSTR path, INT32 mode ); LPSECURITY_ATTRIBUTES sa, DWORD creation,
extern BOOL32 FILE_SetFileType( HFILE32 hFile, DWORD type ); DWORD attributes, HANDLE32 template );
extern LPVOID FILE_dommap( int unix_handle, LPVOID start, extern LPVOID FILE_dommap( int unix_handle, LPVOID start,
DWORD size_high, DWORD size_low, DWORD size_high, DWORD size_low,
DWORD offset_high, DWORD offset_low, DWORD offset_high, DWORD offset_low,
...@@ -89,7 +85,7 @@ extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft, ...@@ -89,7 +85,7 @@ extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft,
extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder ); extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder );
extern BOOL32 DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer ); extern BOOL32 DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer );
extern const DOS_DEVICE *DOSFS_GetDevice( const char *name ); extern const DOS_DEVICE *DOSFS_GetDevice( const char *name );
extern HFILE32 DOSFS_OpenDevice( const char *name, INT32 mode ); extern HFILE32 DOSFS_OpenDevice( const char *name, DWORD access );
extern BOOL32 DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf, extern BOOL32 DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf,
INT32 long_len, LPSTR short_buf, INT32 long_len, LPSTR short_buf,
BOOL32 ignore_case ); BOOL32 ignore_case );
......
...@@ -255,6 +255,10 @@ struct create_file_request ...@@ -255,6 +255,10 @@ struct create_file_request
{ {
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */ int inherit; /* inherit flag */
unsigned int sharing; /* sharing flags */
int create; /* file create action */
unsigned int attrs; /* file attributes for creation */
char name[0]; /* file name */
}; };
struct create_file_reply struct create_file_reply
{ {
...@@ -298,6 +302,15 @@ struct truncate_file_request ...@@ -298,6 +302,15 @@ struct truncate_file_request
}; };
/* Set a file access and modification times */
struct set_file_time_request
{
int handle; /* handle to the file */
time_t access_time; /* last access time */
time_t write_time; /* last write time */
};
/* Flush a file buffers */ /* Flush a file buffers */
struct flush_file_request struct flush_file_request
{ {
...@@ -312,6 +325,7 @@ struct get_file_info_request ...@@ -312,6 +325,7 @@ struct get_file_info_request
}; };
struct get_file_info_reply struct get_file_info_reply
{ {
int type; /* file type */
int attr; /* file attributes */ int attr; /* file attributes */
time_t access_time; /* last access time */ time_t access_time; /* last access time */
time_t write_time; /* last write time */ time_t write_time; /* last write time */
......
...@@ -23,6 +23,7 @@ struct thread; ...@@ -23,6 +23,7 @@ struct thread;
struct file; struct file;
struct wait_queue_entry; struct wait_queue_entry;
/* operations valid on all objects */
struct object_ops struct object_ops
{ {
/* dump the object (for debugging) */ /* dump the object (for debugging) */
...@@ -40,7 +41,9 @@ struct object_ops ...@@ -40,7 +41,9 @@ struct object_ops
/* return a Unix fd that can be used to write to the object */ /* return a Unix fd that can be used to write to the object */
int (*get_write_fd)(struct object *); int (*get_write_fd)(struct object *);
/* flush the object buffers */ /* flush the object buffers */
int (*flush)(struct object *); int (*flush)(struct object *);
/* get file information */
int (*get_file_info)(struct object *,struct get_file_info_reply *);
/* destroy on refcount == 0 */ /* destroy on refcount == 0 */
void (*destroy)(struct object *); void (*destroy)(struct object *);
}; };
...@@ -57,8 +60,8 @@ struct object ...@@ -57,8 +60,8 @@ struct object
extern void *mem_alloc( size_t size ); /* malloc wrapper */ extern void *mem_alloc( size_t size ); /* malloc wrapper */
extern struct object *create_named_object( const char *name, const struct object_ops *ops, extern struct object *create_named_object( const char *name, const struct object_ops *ops,
size_t size ); size_t size );
extern int init_object( struct object *obj, const struct object_ops *ops, extern int init_object( struct object *obj, const struct object_ops *ops, const char *name );
const char *name ); extern const char *get_object_name( struct object *obj );
/* grab/release_object can take any pointer, but you better make sure */ /* grab/release_object can take any pointer, but you better make sure */
/* that the thing pointed to starts with a struct object... */ /* that the thing pointed to starts with a struct object... */
extern struct object *grab_object( void *obj ); extern struct object *grab_object( void *obj );
...@@ -69,6 +72,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread ); ...@@ -69,6 +72,7 @@ extern int no_satisfied( struct object *obj, struct thread *thread );
extern int no_read_fd( struct object *obj ); extern int no_read_fd( struct object *obj );
extern int no_write_fd( struct object *obj ); extern int no_write_fd( struct object *obj );
extern int no_flush( struct object *obj ); extern int no_flush( struct object *obj );
extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info );
extern void default_select_event( int fd, int event, void *private ); extern void default_select_event( int fd, int event, void *private );
/* request handlers */ /* request handlers */
...@@ -172,13 +176,14 @@ extern int release_semaphore( int handle, unsigned int count, unsigned int *prev ...@@ -172,13 +176,14 @@ extern int release_semaphore( int handle, unsigned int count, unsigned int *prev
/* file functions */ /* file functions */
extern struct object *create_file( int fd ); extern struct object *create_file( int fd, const char *name, unsigned int access,
unsigned int sharing, int create, unsigned int attrs );
extern struct file *get_file_obj( struct process *process, int handle, extern struct file *get_file_obj( struct process *process, int handle,
unsigned int access ); unsigned int access );
extern int file_get_mmap_fd( struct file *file ); extern int file_get_mmap_fd( struct file *file );
extern int set_file_pointer( int handle, int *low, int *high, int whence ); extern int set_file_pointer( int handle, int *low, int *high, int whence );
extern int truncate_file( int handle ); extern int truncate_file( int handle );
extern int get_file_info( int handle, struct get_file_info_reply *reply ); extern int set_file_time( int handle, time_t access_time, time_t write_time );
extern void file_set_error(void); extern void file_set_error(void);
......
...@@ -28,6 +28,7 @@ enum request ...@@ -28,6 +28,7 @@ enum request
REQ_GET_WRITE_FD, REQ_GET_WRITE_FD,
REQ_SET_FILE_POINTER, REQ_SET_FILE_POINTER,
REQ_TRUNCATE_FILE, REQ_TRUNCATE_FILE,
REQ_SET_FILE_TIME,
REQ_FLUSH_FILE, REQ_FLUSH_FILE,
REQ_GET_FILE_INFO, REQ_GET_FILE_INFO,
REQ_CREATE_PIPE, REQ_CREATE_PIPE,
...@@ -67,6 +68,7 @@ DECL_HANDLER(get_read_fd); ...@@ -67,6 +68,7 @@ DECL_HANDLER(get_read_fd);
DECL_HANDLER(get_write_fd); DECL_HANDLER(get_write_fd);
DECL_HANDLER(set_file_pointer); DECL_HANDLER(set_file_pointer);
DECL_HANDLER(truncate_file); DECL_HANDLER(truncate_file);
DECL_HANDLER(set_file_time);
DECL_HANDLER(flush_file); DECL_HANDLER(flush_file);
DECL_HANDLER(get_file_info); DECL_HANDLER(get_file_info);
DECL_HANDLER(create_pipe); DECL_HANDLER(create_pipe);
...@@ -103,6 +105,7 @@ static const struct handler { ...@@ -103,6 +105,7 @@ static const struct handler {
{ (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) }, { (void(*)())req_get_write_fd, sizeof(struct get_write_fd_request) },
{ (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) }, { (void(*)())req_set_file_pointer, sizeof(struct set_file_pointer_request) },
{ (void(*)())req_truncate_file, sizeof(struct truncate_file_request) }, { (void(*)())req_truncate_file, sizeof(struct truncate_file_request) },
{ (void(*)())req_set_file_time, sizeof(struct set_file_time_request) },
{ (void(*)())req_flush_file, sizeof(struct flush_file_request) }, { (void(*)())req_flush_file, sizeof(struct flush_file_request) },
{ (void(*)())req_get_file_info, sizeof(struct get_file_info_request) }, { (void(*)())req_get_file_info, sizeof(struct get_file_info_request) },
{ (void(*)())req_create_pipe, sizeof(struct create_pipe_request) }, { (void(*)())req_create_pipe, sizeof(struct create_pipe_request) },
......
...@@ -397,7 +397,6 @@ BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset ) ...@@ -397,7 +397,6 @@ BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset )
*/ */
HANDLE32 NE_OpenFile( NE_MODULE *pModule ) HANDLE32 NE_OpenFile( NE_MODULE *pModule )
{ {
DOS_FULL_NAME full_name;
char *name; char *name;
static HANDLE32 cachedfd = -1; static HANDLE32 cachedfd = -1;
...@@ -408,8 +407,8 @@ HANDLE32 NE_OpenFile( NE_MODULE *pModule ) ...@@ -408,8 +407,8 @@ HANDLE32 NE_OpenFile( NE_MODULE *pModule )
CloseHandle( cachedfd ); CloseHandle( cachedfd );
pCachedModule = pModule; pCachedModule = pModule;
name = NE_MODULE_NAME( pModule ); name = NE_MODULE_NAME( pModule );
if (!DOSFS_GetFullName( name, TRUE, &full_name ) || if ((cachedfd = CreateFile32A( name, GENERIC_READ, FILE_SHARE_READ,
(cachedfd = FILE_OpenUnixFile( full_name.long_name, O_RDONLY )) == -1) NULL, OPEN_EXISTING, 0, -1 )) == -1)
MSG( "Can't open file '%s' for module %04x\n", name, pModule->self ); MSG( "Can't open file '%s' for module %04x\n", name, pModule->self );
else else
/* FIXME: should not be necessary */ /* FIXME: should not be necessary */
......
...@@ -475,7 +475,7 @@ static HMODULE32 PE_LoadImage( LPCSTR name, OFSTRUCT *ofs ) ...@@ -475,7 +475,7 @@ static HMODULE32 PE_LoadImage( LPCSTR name, OFSTRUCT *ofs )
if (!strchr( p, '.' )) strcat( dllname, ".DLL" ); if (!strchr( p, '.' )) strcat( dllname, ".DLL" );
/* Open PE file */ /* Open PE file */
hFile = OpenFile32( dllname, ofs, OF_READ ); hFile = OpenFile32( dllname, ofs, OF_READ | OF_SHARE_DENY_WRITE );
if ( hFile == HFILE_ERROR32 ) if ( hFile == HFILE_ERROR32 )
{ {
WARN( win32, "OpenFile error %ld\n", GetLastError() ); WARN( win32, "OpenFile error %ld\n", GetLastError() );
...@@ -868,7 +868,7 @@ HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line, ...@@ -868,7 +868,7 @@ HINSTANCE16 PE_CreateProcess( LPCSTR name, LPCSTR cmd_line,
if ((hModule32 = PE_LoadImage( name, &ofs )) < 32) if ((hModule32 = PE_LoadImage( name, &ofs )) < 32)
return hModule32; return hModule32;
if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL) if (PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
return 11; return 20; /* FIXME: not the right error code */
/* Create 16-bit dummy module */ /* Create 16-bit dummy module */
if ((hModule16 = MODULE_CreateDummyModule( &ofs )) < 32) return hModule16; if ((hModule16 = MODULE_CreateDummyModule( &ofs )) < 32) return hModule16;
......
...@@ -296,23 +296,37 @@ CRTDLL_FILE * __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode) ...@@ -296,23 +296,37 @@ CRTDLL_FILE * __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode)
file=fopen(full_name.long_name ,mode); file=fopen(full_name.long_name ,mode);
#endif #endif
INT32 flagmode=0; DWORD access = 0, creation = 0;
if ((strchr(mode,'r')&&strchr(mode,'a'))|| if ((strchr(mode,'r')&&strchr(mode,'a'))||
(strchr(mode,'r')&&strchr(mode,'w'))|| (strchr(mode,'r')&&strchr(mode,'w'))||
(strchr(mode,'w')&&strchr(mode,'a'))) (strchr(mode,'w')&&strchr(mode,'a')))
return NULL; return NULL;
if (strstr(mode,"r+")) flagmode=O_RDWR; if (mode[0] == 'r')
else if (strchr(mode,'r')) flagmode = O_RDONLY; {
else if (strstr(mode,"w+")) flagmode= O_RDWR | O_TRUNC | O_CREAT; access = GENERIC_READ;
else if (strchr(mode,'w')) flagmode = O_WRONLY | O_TRUNC | O_CREAT; creation = OPEN_EXISTING;
else if (strstr(mode,"a+")) flagmode= O_RDWR | O_CREAT | O_APPEND; if (mode[1] == '+') access |= GENERIC_WRITE;
else if (strchr(mode,'w')) flagmode = O_RDWR | O_CREAT | O_APPEND; }
else if (strchr(mode,'b')) else if (mode[0] == 'w')
TRACE(crtdll, "%s in BINARY mode\n",path); {
access = GENERIC_WRITE;
if ((handle = FILE_Open(path, flagmode,0)) != INVALID_HANDLE_VALUE32) creation = CREATE_ALWAYS;
if (mode[1] == '+') access |= GENERIC_READ;
}
else if (mode[0] == 'a')
{
/* FIXME: there is no O_APPEND in CreateFile, should emulate it */
access = GENERIC_WRITE;
creation = OPEN_ALWAYS;
if (mode[1] == '+') access |= GENERIC_READ;
}
/* FIXME: should handle text/binary mode */
if ((handle = CreateFile32A( path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, creation, FILE_ATTRIBUTE_NORMAL,
-1 )) != INVALID_HANDLE_VALUE32)
{ {
file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) ); file = HeapAlloc( GetProcessHeap(), 0, sizeof(*file) );
file->handle = handle; file->handle = handle;
...@@ -1181,8 +1195,8 @@ int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf) ...@@ -1181,8 +1195,8 @@ int __cdecl CRTDLL__stat(const char * filename, struct win_stat * buf)
*/ */
HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags) HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
{ {
HFILE32 ret=0; DWORD access = 0, creation = 0;
int wineflags=0; HFILE32 ret;
/* FIXME: /* FIXME:
the flags in lcc's header differ from the ones in Linux, e.g. the flags in lcc's header differ from the ones in Linux, e.g.
...@@ -1191,18 +1205,38 @@ HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags) ...@@ -1191,18 +1205,38 @@ HFILE32 __cdecl CRTDLL__open(LPCSTR path,INT32 flags)
so here a scheme to translate them so here a scheme to translate them
Probably lcc is wrong here, but at least a hack to get is going Probably lcc is wrong here, but at least a hack to get is going
*/ */
wineflags = (flags & 3); switch(flags & 3)
if (flags & 0x0008 ) wineflags |= O_APPEND; {
if (flags & 0x0100 ) wineflags |= O_CREAT; case O_RDONLY: access |= GENERIC_READ; break;
if (flags & 0x0200 ) wineflags |= O_TRUNC; case O_WRONLY: access |= GENERIC_WRITE; break;
if (flags & 0x0400 ) wineflags |= O_EXCL; case O_RDWR: access |= GENERIC_WRITE | GENERIC_READ; break;
if (flags & 0xf0f4 ) }
if (flags & 0x0100) /* O_CREAT */
{
if (flags & 0x0400) /* O_EXCL */
creation = CREATE_NEW;
else if (flags & 0x0200) /* O_TRUNC */
creation = CREATE_ALWAYS;
else
creation = OPEN_ALWAYS;
}
else /* no O_CREAT */
{
if (flags & 0x0200) /* O_TRUNC */
creation = TRUNCATE_EXISTING;
else
creation = OPEN_EXISTING;
}
if (flags & 0x0008) /* O_APPEND */
FIXME(crtdll, "O_APPEND not supported\n" );
if (flags & 0xf0f4)
TRACE(crtdll,"CRTDLL_open file unsupported flags 0x%04x\n",flags); TRACE(crtdll,"CRTDLL_open file unsupported flags 0x%04x\n",flags);
/* End Fixme */ /* End Fixme */
ret = FILE_Open(path,wineflags,0); ret = CreateFile32A( path, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
TRACE(crtdll,"CRTDLL_open file %s mode 0x%04x (lccmode 0x%04x) got dfh %d\n", NULL, creation, FILE_ATTRIBUTE_NORMAL, -1 );
path,wineflags,flags,ret); TRACE(crtdll,"CRTDLL_open file %s mode 0x%04x got handle %d\n", path,flags,ret);
return ret; return ret;
} }
......
...@@ -1635,9 +1635,18 @@ void WINAPI DOS3Call( CONTEXT *context ) ...@@ -1635,9 +1635,18 @@ void WINAPI DOS3Call( CONTEXT *context )
break; break;
case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */ case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
TRACE(int21,"DUP - DUPLICATE FILE HANDLE %d\n",BX_reg(context)); {
bSetDOSExtendedError = ((AX_reg(context) = HFILE32_TO_HFILE16(FILE_Dup(HFILE16_TO_HFILE32(BX_reg(context))))) == (WORD)HFILE_ERROR16); HANDLE32 handle;
break; TRACE(int21,"DUP - DUPLICATE FILE HANDLE %d\n",BX_reg(context));
if ((bSetDOSExtendedError = !DuplicateHandle( GetCurrentProcess(),
HFILE16_TO_HFILE32(BX_reg(context)),
GetCurrentProcess(), &handle,
0, TRUE, DUPLICATE_SAME_ACCESS )))
AX_reg(context) = HFILE_ERROR16;
else
AX_reg(context) = HFILE32_TO_HFILE16(handle);
break;
}
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */ case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
TRACE(int21,"FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n", TRACE(int21,"FORCEDUP - FORCE DUPLICATE FILE HANDLE %d to %d\n",
......
...@@ -687,7 +687,7 @@ void VXD_Win32s( CONTEXT *context ) ...@@ -687,7 +687,7 @@ void VXD_Win32s( CONTEXT *context )
IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr); IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr);
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr); IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr);
HFILE32 image = FILE_Open(module->pathName, O_RDONLY,0); HFILE32 image = _lopen32(module->pathName, OF_READ);
BOOL32 error = (image == INVALID_HANDLE_VALUE32); BOOL32 error = (image == INVALID_HANDLE_VALUE32);
UINT32 i; UINT32 i;
......
...@@ -1378,7 +1378,8 @@ HRESULT WINAPI IStorage16_fnCreateStream( ...@@ -1378,7 +1378,8 @@ HRESULT WINAPI IStorage16_fnCreateStream(
FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n"); FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm); _create_istream16(ppstm);
lpstr = (_IStream16*)PTR_SEG_TO_LIN(*ppstm); lpstr = (_IStream16*)PTR_SEG_TO_LIN(*ppstm);
lpstr->hf = FILE_Dup(this->hf); DuplicateHandle( GetCurrentProcess(), this->hf, GetCurrentProcess(),
&lpstr->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
lpstr->offset.LowPart = 0; lpstr->offset.LowPart = 0;
lpstr->offset.HighPart = 0; lpstr->offset.HighPart = 0;
...@@ -1430,7 +1431,8 @@ HRESULT WINAPI IStorage16_fnOpenStorage( ...@@ -1430,7 +1431,8 @@ HRESULT WINAPI IStorage16_fnOpenStorage(
FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n"); FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n");
_create_istorage16(ppstg); _create_istorage16(ppstg);
lpstg = (_IStream16*)PTR_SEG_TO_LIN(*ppstg); lpstg = (_IStream16*)PTR_SEG_TO_LIN(*ppstg);
lpstg->hf = FILE_Dup(this->hf); DuplicateHandle( GetCurrentProcess(), this->hf, GetCurrentProcess(),
&lpstg->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
lstrcpyAtoW(name,pwcsName); lstrcpyAtoW(name,pwcsName);
newpps = STORAGE_look_for_named_pps(lpstg->hf,this->stde.pps_dir,name); newpps = STORAGE_look_for_named_pps(lpstg->hf,this->stde.pps_dir,name);
if (newpps==-1) { if (newpps==-1) {
...@@ -1464,7 +1466,8 @@ HRESULT WINAPI IStorage16_fnOpenStream( ...@@ -1464,7 +1466,8 @@ HRESULT WINAPI IStorage16_fnOpenStream(
FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n"); FIXME(ole,"We do not support transacted Compound Storage. Using direct mode.\n");
_create_istream16(ppstm); _create_istream16(ppstm);
lpstr = (_IStream16*)PTR_SEG_TO_LIN(*ppstm); lpstr = (_IStream16*)PTR_SEG_TO_LIN(*ppstm);
lpstr->hf = FILE_Dup(this->hf); DuplicateHandle( GetCurrentProcess(), this->hf, GetCurrentProcess(),
&lpstr->hf, 0, TRUE, DUPLICATE_SAME_ACCESS );
lstrcpyAtoW(name,pwcsName); lstrcpyAtoW(name,pwcsName);
newpps = STORAGE_look_for_named_pps(lpstr->hf,this->stde.pps_dir,name); newpps = STORAGE_look_for_named_pps(lpstr->hf,this->stde.pps_dir,name);
if (newpps==-1) { if (newpps==-1) {
......
...@@ -108,12 +108,9 @@ static BOOL32 PROCESS_BuildEnvDB( PDB32 *pdb ) ...@@ -108,12 +108,9 @@ static BOOL32 PROCESS_BuildEnvDB( PDB32 *pdb )
/* Allocate the standard handles */ /* Allocate the standard handles */
pdb->env_db->hStdin = FILE_DupUnixHandle( 0 ); pdb->env_db->hStdin = FILE_DupUnixHandle( 0, GENERIC_READ );
pdb->env_db->hStdout = FILE_DupUnixHandle( 1 ); pdb->env_db->hStdout = FILE_DupUnixHandle( 1, GENERIC_WRITE );
pdb->env_db->hStderr = FILE_DupUnixHandle( 2 ); pdb->env_db->hStderr = FILE_DupUnixHandle( 2, GENERIC_WRITE );
FILE_SetFileType( pdb->env_db->hStdin, FILE_TYPE_CHAR );
FILE_SetFileType( pdb->env_db->hStdout, FILE_TYPE_CHAR );
FILE_SetFileType( pdb->env_db->hStderr, FILE_TYPE_CHAR );
/* Build the command-line */ /* Build the command-line */
...@@ -661,46 +658,19 @@ DWORD WINAPI GetPriorityClass(HANDLE32 hprocess) ...@@ -661,46 +658,19 @@ DWORD WINAPI GetPriorityClass(HANDLE32 hprocess)
/*********************************************************************** /***********************************************************************
* GetStdHandle (KERNEL32.276) * GetStdHandle (KERNEL32.276)
*
* FIXME: These should be allocated when a console is created, or inherited
* from the parent.
*/ */
HANDLE32 WINAPI GetStdHandle( DWORD std_handle ) HANDLE32 WINAPI GetStdHandle( DWORD std_handle )
{ {
HFILE32 hFile;
int fd;
PDB32 *pdb = PROCESS_Current(); PDB32 *pdb = PROCESS_Current();
switch(std_handle) switch(std_handle)
{ {
case STD_INPUT_HANDLE: case STD_INPUT_HANDLE: return pdb->env_db->hStdin;
if (pdb->env_db->hStdin) return pdb->env_db->hStdin; case STD_OUTPUT_HANDLE: return pdb->env_db->hStdout;
fd = 0; case STD_ERROR_HANDLE: return pdb->env_db->hStderr;
break;
case STD_OUTPUT_HANDLE:
if (pdb->env_db->hStdout) return pdb->env_db->hStdout;
fd = 1;
break;
case STD_ERROR_HANDLE:
if (pdb->env_db->hStderr) return pdb->env_db->hStderr;
fd = 2;
break;
default:
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_HANDLE_VALUE32;
}
hFile = FILE_DupUnixHandle( fd );
if (hFile != HFILE_ERROR32)
{
FILE_SetFileType( hFile, FILE_TYPE_CHAR );
switch(std_handle)
{
case STD_INPUT_HANDLE: pdb->env_db->hStdin = hFile; break;
case STD_OUTPUT_HANDLE: pdb->env_db->hStdout = hFile; break;
case STD_ERROR_HANDLE: pdb->env_db->hStderr = hFile; break;
}
} }
return hFile; SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_HANDLE_VALUE32;
} }
......
...@@ -33,6 +33,7 @@ static const struct object_ops change_ops = ...@@ -33,6 +33,7 @@ static const struct object_ops change_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
change_destroy change_destroy
}; };
...@@ -51,8 +52,8 @@ static void change_dump( struct object *obj, int verbose ) ...@@ -51,8 +52,8 @@ static void change_dump( struct object *obj, int verbose )
{ {
struct change *change = (struct change *)obj; struct change *change = (struct change *)obj;
assert( obj->ops == &change_ops ); assert( obj->ops == &change_ops );
printf( "Change notification sub=%d filter=%08x\n", fprintf( stderr, "Change notification sub=%d filter=%08x\n",
change->subtree, change->filter ); change->subtree, change->filter );
} }
static int change_signaled( struct object *obj, struct thread *thread ) static int change_signaled( struct object *obj, struct thread *thread )
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/errno.h> #include <sys/errno.h>
...@@ -35,6 +36,7 @@ static void console_remove_queue( struct object *obj, struct wait_queue_entry *e ...@@ -35,6 +36,7 @@ static void console_remove_queue( struct object *obj, struct wait_queue_entry *e
static int console_signaled( struct object *obj, struct thread *thread ); static int console_signaled( struct object *obj, struct thread *thread );
static int console_get_read_fd( struct object *obj ); static int console_get_read_fd( struct object *obj );
static int console_get_write_fd( struct object *obj ); static int console_get_write_fd( struct object *obj );
static int console_get_info( struct object *obj, struct get_file_info_reply *reply );
static void console_destroy( struct object *obj ); static void console_destroy( struct object *obj );
static const struct object_ops console_ops = static const struct object_ops console_ops =
...@@ -47,6 +49,7 @@ static const struct object_ops console_ops = ...@@ -47,6 +49,7 @@ static const struct object_ops console_ops =
console_get_read_fd, console_get_read_fd,
console_get_write_fd, console_get_write_fd,
no_flush, no_flush,
console_get_info,
console_destroy console_destroy
}; };
...@@ -120,8 +123,8 @@ static void console_dump( struct object *obj, int verbose ) ...@@ -120,8 +123,8 @@ static void console_dump( struct object *obj, int verbose )
{ {
struct console *console = (struct console *)obj; struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops ); assert( obj->ops == &console_ops );
printf( "Console %s fd=%d\n", fprintf( stderr, "Console %s fd=%d\n",
console->is_read ? "input" : "output", console->fd ); console->is_read ? "input" : "output", console->fd );
} }
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry ) static int console_add_queue( struct object *obj, struct wait_queue_entry *entry )
...@@ -194,6 +197,13 @@ static int console_get_write_fd( struct object *obj ) ...@@ -194,6 +197,13 @@ static int console_get_write_fd( struct object *obj )
return dup( console->fd ); return dup( console->fd );
} }
static int console_get_info( struct object *obj, struct get_file_info_reply *reply )
{
memset( reply, 0, sizeof(*reply) );
reply->type = FILE_TYPE_CHAR;
return 1;
}
static void console_destroy( struct object *obj ) static void console_destroy( struct object *obj )
{ {
struct console *console = (struct console *)obj; struct console *console = (struct console *)obj;
......
...@@ -34,6 +34,7 @@ static const struct object_ops event_ops = ...@@ -34,6 +34,7 @@ static const struct object_ops event_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
event_destroy event_destroy
}; };
...@@ -103,7 +104,9 @@ static void event_dump( struct object *obj, int verbose ) ...@@ -103,7 +104,9 @@ static void event_dump( struct object *obj, int verbose )
{ {
struct event *event = (struct event *)obj; struct event *event = (struct event *)obj;
assert( obj->ops == &event_ops ); assert( obj->ops == &event_ops );
printf( "Event manual=%d signaled=%d\n", event->manual_reset, event->signaled ); fprintf( stderr, "Event manual=%d signaled=%d name='%s'\n",
event->manual_reset, event->signaled,
get_object_name( &event->obj ) );
} }
static int event_signaled( struct object *obj, struct thread *thread ) static int event_signaled( struct object *obj, struct thread *thread )
......
...@@ -35,6 +35,7 @@ static const struct object_ops mapping_ops = ...@@ -35,6 +35,7 @@ static const struct object_ops mapping_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
mapping_destroy mapping_destroy
}; };
...@@ -93,8 +94,9 @@ static void mapping_dump( struct object *obj, int verbose ) ...@@ -93,8 +94,9 @@ static void mapping_dump( struct object *obj, int verbose )
{ {
struct mapping *mapping = (struct mapping *)obj; struct mapping *mapping = (struct mapping *)obj;
assert( obj->ops == &mapping_ops ); assert( obj->ops == &mapping_ops );
fprintf( stderr, "Mapping size=%08x%08x prot=%08x file=%p\n", fprintf( stderr, "Mapping size=%08x%08x prot=%08x file=%p name='%s'\n",
mapping->size_high, mapping->size_low, mapping->protect, mapping->file ); mapping->size_high, mapping->size_low, mapping->protect,
mapping->file, get_object_name( &mapping->obj ) );
} }
static void mapping_destroy( struct object *obj ) static void mapping_destroy( struct object *obj )
......
...@@ -37,6 +37,7 @@ static const struct object_ops mutex_ops = ...@@ -37,6 +37,7 @@ static const struct object_ops mutex_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
mutex_destroy mutex_destroy
}; };
...@@ -110,7 +111,8 @@ static void mutex_dump( struct object *obj, int verbose ) ...@@ -110,7 +111,8 @@ static void mutex_dump( struct object *obj, int verbose )
{ {
struct mutex *mutex = (struct mutex *)obj; struct mutex *mutex = (struct mutex *)obj;
assert( obj->ops == &mutex_ops ); assert( obj->ops == &mutex_ops );
printf( "Mutex count=%u owner=%p\n", mutex->count, mutex->owner ); printf( "Mutex count=%u owner=%p name='%s'\n",
mutex->count, mutex->owner, get_object_name( &mutex->obj) );
} }
static int mutex_signaled( struct object *obj, struct thread *thread ) static int mutex_signaled( struct object *obj, struct thread *thread )
......
...@@ -110,6 +110,13 @@ struct object *create_named_object( const char *name, const struct object_ops *o ...@@ -110,6 +110,13 @@ struct object *create_named_object( const char *name, const struct object_ops *o
return obj; return obj;
} }
/* return a pointer to the object name, or to an empty string */
const char *get_object_name( struct object *obj )
{
if (!obj->name) return "";
return obj->name->name;
}
/* grab an object (i.e. increment its refcount) and return the object */ /* grab an object (i.e. increment its refcount) and return the object */
struct object *grab_object( void *ptr ) struct object *grab_object( void *ptr )
{ {
...@@ -176,6 +183,12 @@ int no_flush( struct object *obj ) ...@@ -176,6 +183,12 @@ int no_flush( struct object *obj )
return 0; return 0;
} }
int no_get_file_info( struct object *obj, struct get_file_info_reply *info )
{
SET_ERROR( ERROR_INVALID_HANDLE );
return 0;
}
void default_select_event( int fd, int event, void *private ) void default_select_event( int fd, int event, void *private )
{ {
struct object *obj = (struct object *)private; struct object *obj = (struct object *)private;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <assert.h> #include <assert.h>
#include <fcntl.h> #include <fcntl.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/errno.h> #include <sys/errno.h>
...@@ -35,6 +36,7 @@ static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entr ...@@ -35,6 +36,7 @@ static void pipe_remove_queue( struct object *obj, struct wait_queue_entry *entr
static int pipe_signaled( struct object *obj, struct thread *thread ); static int pipe_signaled( struct object *obj, struct thread *thread );
static int pipe_get_read_fd( struct object *obj ); static int pipe_get_read_fd( struct object *obj );
static int pipe_get_write_fd( struct object *obj ); static int pipe_get_write_fd( struct object *obj );
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply );
static void pipe_destroy( struct object *obj ); static void pipe_destroy( struct object *obj );
static const struct object_ops pipe_ops = static const struct object_ops pipe_ops =
...@@ -47,6 +49,7 @@ static const struct object_ops pipe_ops = ...@@ -47,6 +49,7 @@ static const struct object_ops pipe_ops =
pipe_get_read_fd, pipe_get_read_fd,
pipe_get_write_fd, pipe_get_write_fd,
no_flush, no_flush,
pipe_get_info,
pipe_destroy pipe_destroy
}; };
...@@ -97,8 +100,8 @@ static void pipe_dump( struct object *obj, int verbose ) ...@@ -97,8 +100,8 @@ static void pipe_dump( struct object *obj, int verbose )
{ {
struct pipe *pipe = (struct pipe *)obj; struct pipe *pipe = (struct pipe *)obj;
assert( obj->ops == &pipe_ops ); assert( obj->ops == &pipe_ops );
printf( "Pipe %s-side fd=%d\n", fprintf( stderr, "Pipe %s-side fd=%d\n",
(pipe->side == READ_SIDE) ? "read" : "write", pipe->fd ); (pipe->side == READ_SIDE) ? "read" : "write", pipe->fd );
} }
static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry ) static int pipe_add_queue( struct object *obj, struct wait_queue_entry *entry )
...@@ -181,6 +184,13 @@ static int pipe_get_write_fd( struct object *obj ) ...@@ -181,6 +184,13 @@ static int pipe_get_write_fd( struct object *obj )
return dup( pipe->fd ); return dup( pipe->fd );
} }
static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply )
{
memset( reply, 0, sizeof(*reply) );
reply->type = FILE_TYPE_PIPE;
return 1;
}
static void pipe_destroy( struct object *obj ) static void pipe_destroy( struct object *obj )
{ {
struct pipe *pipe = (struct pipe *)obj; struct pipe *pipe = (struct pipe *)obj;
......
...@@ -77,6 +77,7 @@ static const struct object_ops process_ops = ...@@ -77,6 +77,7 @@ static const struct object_ops process_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
process_destroy process_destroy
}; };
......
...@@ -396,19 +396,16 @@ DECL_HANDLER(create_file) ...@@ -396,19 +396,16 @@ DECL_HANDLER(create_file)
{ {
struct create_file_reply reply = { -1 }; struct create_file_reply reply = { -1 };
struct object *obj; struct object *obj;
int new_fd; char *name = (char *)data;
if (!len) name = NULL;
else CHECK_STRING( "create_file", name, len );
if ((new_fd = dup(fd)) == -1) if ((obj = create_file( fd, name, req->access,
{ req->sharing, req->create, req->attrs )) != NULL)
SET_ERROR( ERROR_TOO_MANY_OPEN_FILES );
goto done;
}
if ((obj = create_file( new_fd )) != NULL)
{ {
reply.handle = alloc_handle( current->process, obj, req->access, req->inherit ); reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
release_object( obj ); release_object( obj );
} }
done:
send_reply( current, -1, 1, &reply, sizeof(reply) ); send_reply( current, -1, 1, &reply, sizeof(reply) );
} }
...@@ -470,11 +467,24 @@ DECL_HANDLER(flush_file) ...@@ -470,11 +467,24 @@ DECL_HANDLER(flush_file)
send_reply( current, -1, 0 ); send_reply( current, -1, 0 );
} }
/* set a file access and modification times */
DECL_HANDLER(set_file_time)
{
set_file_time( req->handle, req->access_time, req->write_time );
send_reply( current, -1, 0 );
}
/* get a file information */ /* get a file information */
DECL_HANDLER(get_file_info) DECL_HANDLER(get_file_info)
{ {
struct object *obj;
struct get_file_info_reply reply; struct get_file_info_reply reply;
get_file_info( req->handle, &reply );
if ((obj = get_handle_obj( current->process, req->handle, 0, NULL )))
{
obj->ops->get_file_info( obj, &reply );
release_object( obj );
}
send_reply( current, -1, 1, &reply, sizeof(reply) ); send_reply( current, -1, 1, &reply, sizeof(reply) );
} }
......
...@@ -34,6 +34,7 @@ static const struct object_ops semaphore_ops = ...@@ -34,6 +34,7 @@ static const struct object_ops semaphore_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
semaphore_destroy semaphore_destroy
}; };
...@@ -96,7 +97,8 @@ static void semaphore_dump( struct object *obj, int verbose ) ...@@ -96,7 +97,8 @@ static void semaphore_dump( struct object *obj, int verbose )
{ {
struct semaphore *sem = (struct semaphore *)obj; struct semaphore *sem = (struct semaphore *)obj;
assert( obj->ops == &semaphore_ops ); assert( obj->ops == &semaphore_ops );
printf( "Semaphore count=%d max=%d\n", sem->count, sem->max ); fprintf( stderr, "Semaphore count=%d max=%d name='%s'\n",
sem->count, sem->max, get_object_name( &sem->obj ) );
} }
static int semaphore_signaled( struct object *obj, struct thread *thread ) static int semaphore_signaled( struct object *obj, struct thread *thread )
......
...@@ -55,6 +55,7 @@ static const struct object_ops thread_ops = ...@@ -55,6 +55,7 @@ static const struct object_ops thread_ops =
no_read_fd, no_read_fd,
no_write_fd, no_write_fd,
no_flush, no_flush,
no_get_file_info,
destroy_thread destroy_thread
}; };
...@@ -145,8 +146,8 @@ static void dump_thread( struct object *obj, int verbose ) ...@@ -145,8 +146,8 @@ static void dump_thread( struct object *obj, int verbose )
struct thread *thread = (struct thread *)obj; struct thread *thread = (struct thread *)obj;
assert( obj->ops == &thread_ops ); assert( obj->ops == &thread_ops );
printf( "Thread pid=%d fd=%d name='%s'\n", fprintf( stderr, "Thread pid=%d fd=%d name='%s'\n",
thread->unix_pid, thread->client_fd, thread->name ); thread->unix_pid, thread->client_fd, thread->name );
} }
static int thread_signaled( struct object *obj, struct thread *thread ) static int thread_signaled( struct object *obj, struct thread *thread )
......
...@@ -214,8 +214,12 @@ static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len ...@@ -214,8 +214,12 @@ static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len
static int dump_create_file_request( struct create_file_request *req, int len ) static int dump_create_file_request( struct create_file_request *req, int len )
{ {
fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit ); fprintf( stderr, " inherit=%d,", req->inherit );
return (int)sizeof(*req); fprintf( stderr, " sharing=%08x,", req->sharing );
fprintf( stderr, " create=%d,", req->create );
fprintf( stderr, " attrs=%08x,", req->attrs );
fprintf( stderr, " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
return len;
} }
static int dump_create_file_reply( struct create_file_reply *req, int len ) static int dump_create_file_reply( struct create_file_reply *req, int len )
...@@ -258,6 +262,14 @@ static int dump_truncate_file_request( struct truncate_file_request *req, int le ...@@ -258,6 +262,14 @@ static int dump_truncate_file_request( struct truncate_file_request *req, int le
return (int)sizeof(*req); return (int)sizeof(*req);
} }
static int dump_set_file_time_request( struct set_file_time_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " access_time=%ld,", req->access_time );
fprintf( stderr, " write_time=%ld", req->write_time );
return (int)sizeof(*req);
}
static int dump_flush_file_request( struct flush_file_request *req, int len ) static int dump_flush_file_request( struct flush_file_request *req, int len )
{ {
fprintf( stderr, " handle=%d", req->handle ); fprintf( stderr, " handle=%d", req->handle );
...@@ -272,6 +284,7 @@ static int dump_get_file_info_request( struct get_file_info_request *req, int le ...@@ -272,6 +284,7 @@ static int dump_get_file_info_request( struct get_file_info_request *req, int le
static int dump_get_file_info_reply( struct get_file_info_reply *req, int len ) static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
{ {
fprintf( stderr, " type=%d,", req->type );
fprintf( stderr, " attr=%d,", req->attr ); fprintf( stderr, " attr=%d,", req->attr );
fprintf( stderr, " access_time=%ld,", req->access_time ); fprintf( stderr, " access_time=%ld,", req->access_time );
fprintf( stderr, " write_time=%ld,", req->write_time ); fprintf( stderr, " write_time=%ld,", req->write_time );
...@@ -413,6 +426,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] = ...@@ -413,6 +426,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(void(*)())dump_set_file_pointer_reply }, (void(*)())dump_set_file_pointer_reply },
{ (int(*)(void *,int))dump_truncate_file_request, { (int(*)(void *,int))dump_truncate_file_request,
(void(*)())0 }, (void(*)())0 },
{ (int(*)(void *,int))dump_set_file_time_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_flush_file_request, { (int(*)(void *,int))dump_flush_file_request,
(void(*)())0 }, (void(*)())0 },
{ (int(*)(void *,int))dump_get_file_info_request, { (int(*)(void *,int))dump_get_file_info_request,
...@@ -456,6 +471,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = ...@@ -456,6 +471,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"get_write_fd", "get_write_fd",
"set_file_pointer", "set_file_pointer",
"truncate_file", "truncate_file",
"set_file_time",
"flush_file", "flush_file",
"get_file_info", "get_file_info",
"create_pipe", "create_pipe",
......
...@@ -42,11 +42,7 @@ const K32OBJ_OPS DEVICE_Ops = ...@@ -42,11 +42,7 @@ const K32OBJ_OPS DEVICE_Ops =
typedef struct typedef struct
{ {
K32OBJ header; K32OBJ header;
struct VxDInfo *info; struct VxDInfo *info;
char *devname;
int mode;
} DEVICE_OBJECT; } DEVICE_OBJECT;
...@@ -270,7 +266,7 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] = ...@@ -270,7 +266,7 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
"<KERNEL32.101>" /* 0x0028 -- What does this do??? */ "<KERNEL32.101>" /* 0x0028 -- What does this do??? */
}; };
HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access) HANDLE32 DEVICE_Open(LPCSTR filename)
{ {
DEVICE_OBJECT *dev; DEVICE_OBJECT *dev;
HANDLE32 handle; HANDLE32 handle;
...@@ -281,8 +277,6 @@ HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access) ...@@ -281,8 +277,6 @@ HANDLE32 DEVICE_Open(LPCSTR filename, DWORD access)
dev->header.type = K32OBJ_DEVICE_IOCTL; dev->header.type = K32OBJ_DEVICE_IOCTL;
dev->header.refcount = 1; dev->header.refcount = 1;
dev->mode = access;
dev->devname = HEAP_strdupA(SystemHeap,0,filename);
dev->info = NULL; dev->info = NULL;
for (i = 0; VxDList[i].name; i++) for (i = 0; VxDList[i].name; i++)
...@@ -307,12 +301,6 @@ static void DEVICE_Destroy(K32OBJ *obj) ...@@ -307,12 +301,6 @@ static void DEVICE_Destroy(K32OBJ *obj)
DEVICE_OBJECT *dev = (DEVICE_OBJECT *)obj; DEVICE_OBJECT *dev = (DEVICE_OBJECT *)obj;
assert( obj->type == K32OBJ_DEVICE_IOCTL ); assert( obj->type == K32OBJ_DEVICE_IOCTL );
if ( dev->devname )
{
HeapFree( SystemHeap, 0, dev->devname );
dev->devname = NULL;
}
obj->type = K32OBJ_UNKNOWN; obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, dev ); HeapFree( SystemHeap, 0, dev );
} }
...@@ -360,7 +348,7 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode, ...@@ -360,7 +348,7 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
{ {
/* FIXME: Set appropriate error */ /* FIXME: Set appropriate error */
FIXME( win32, "Unimplemented control %ld for VxD device %s\n", FIXME( win32, "Unimplemented control %ld for VxD device %s\n",
dwIoControlCode, dev->devname ); dwIoControlCode, dev->info->name );
} }
} }
else else
......
...@@ -25,10 +25,6 @@ ...@@ -25,10 +25,6 @@
DWORD ErrnoToLastError(int errno_num); DWORD ErrnoToLastError(int errno_num);
static int TranslateCreationFlags(DWORD create_flags);
static int TranslateAccessFlags(DWORD access_flags);
static int TranslateShareFlags(DWORD share_flags);
/*********************************************************************** /***********************************************************************
* ReadFileEx (KERNEL32.) * ReadFileEx (KERNEL32.)
*/ */
...@@ -51,187 +47,6 @@ BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread, ...@@ -51,187 +47,6 @@ BOOL32 WINAPI ReadFileEx(HFILE32 hFile, LPVOID lpBuffer, DWORD numtoread,
return 0; return 0;
} }
/*************************************************************************
* CreateFile32A [KERNEL32.45] Creates or opens a file or other object
*
* Creates or opens an object, and returns a handle that can be used to
* access that object.
*
* PARAMS
*
* filename [I] pointer to filename to be accessed
* access [I] access mode requested
* sharing [I] share mode
* security [I] pointer to security attributes
* creation [I] ?
* attributes [I] ?
* template [I] handle to file with attributes to copy
*
* RETURNS
* Success: Open handle to specified file
* Failure: INVALID_HANDLE_VALUE
*
* NOTES
* Should call SetLastError() on failure.
*
* BUGS
*
* Doesn't support character devices, pipes, template files, or a
* lot of the 'attributes' flags yet.
*/
HFILE32 WINAPI CreateFile32A(LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES security, DWORD creation,
DWORD attributes, HANDLE32 template)
{
int access_flags, create_flags, share_flags;
HFILE32 to_dup = HFILE_ERROR32; /* handle to dup */
/* Translate the various flags to Unix-style.
*/
access_flags = TranslateAccessFlags(access);
create_flags = TranslateCreationFlags(creation);
share_flags = TranslateShareFlags(sharing);
if(template)
FIXME(file, "template handles not supported.\n");
if(!filename)
return HFILE_ERROR32;
/* If the name starts with '\\?\' or '\\.\', ignore the first 4 chars.
*/
if(!strncmp(filename, "\\\\?\\", 4) || !strncmp(filename, "\\\\.\\", 4))
{
if (filename[2] == '.')
return DEVICE_Open( filename+4, access_flags | create_flags );
filename += 4;
if (!strncmp(filename, "UNC", 3))
{
FIXME(file, "UNC name (%s) not supported.\n",filename);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return HFILE_ERROR32;
}
}
/* If the name still starts with '\\', it's a UNC name.
*/
if(!strncmp(filename, "\\\\", 2))
{
FIXME(file, "UNC names not supported.\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return HFILE_ERROR32;
}
/* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
* or stdout, respectively. The lower case version is also allowed. Most likely
* this should be a case ignore string compare.
*/
if(!strcasecmp(filename, "CONIN$"))
to_dup = GetStdHandle( STD_INPUT_HANDLE );
else if(!strcasecmp(filename, "CONOUT$"))
to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
if(to_dup != HFILE_ERROR32)
{
HFILE32 handle;
if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
&handle, access, FALSE, 0 ))
handle = HFILE_ERROR32;
return handle;
}
return FILE_Open( filename, access_flags | create_flags,share_flags );
}
/*************************************************************************
* CreateFile32W (KERNEL32.48)
*/
HFILE32 WINAPI CreateFile32W(LPCWSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES security, DWORD creation,
DWORD attributes, HANDLE32 template)
{
LPSTR afn = HEAP_strdupWtoA( GetProcessHeap(), 0, filename );
HFILE32 res = CreateFile32A( afn, access, sharing, security, creation,
attributes, template );
HeapFree( GetProcessHeap(), 0, afn );
return res;
}
static int TranslateAccessFlags(DWORD access_flags)
{
int rc = 0;
switch(access_flags)
{
case GENERIC_READ:
rc = O_RDONLY;
break;
case GENERIC_WRITE:
rc = O_WRONLY;
break;
case (GENERIC_READ | GENERIC_WRITE):
rc = O_RDWR;
break;
}
return rc;
}
static int TranslateCreationFlags(DWORD create_flags)
{
int rc = 0;
switch(create_flags)
{
case CREATE_NEW:
rc = O_CREAT | O_EXCL;
break;
case CREATE_ALWAYS:
rc = O_CREAT | O_TRUNC;
break;
case OPEN_EXISTING:
rc = 0;
break;
case OPEN_ALWAYS:
rc = O_CREAT;
break;
case TRUNCATE_EXISTING:
rc = O_TRUNC;
break;
}
return rc;
}
static int TranslateShareFlags(DWORD share_flags)
/*
OPEN_SHARE_DENYNONE FILE_SHARE_READ | FILE_SHARE_WRITE
OPEN_SHARE_DENYREAD FILE_SHARE_WRITE
OPEN_SHARE_DENYREADWRITE 0
OPEN_SHARE_DENYWRITE FILE_SHARE_READ
*/
{
switch(share_flags)
{
case FILE_SHARE_READ | FILE_SHARE_WRITE:
return OF_SHARE_DENY_NONE;
case FILE_SHARE_WRITE:
return OF_SHARE_DENY_READ;
case FILE_SHARE_READ:
return OF_SHARE_DENY_WRITE;
case 0:
return OF_SHARE_EXCLUSIVE;
default:
}
FIXME(file,"unknown sharing flags 0x%04lx\n",share_flags);
return OF_SHARE_EXCLUSIVE;
}
/************************************************************************** /**************************************************************************
* SetFileAttributes16 (KERNEL.421) * SetFileAttributes16 (KERNEL.421)
*/ */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment