From 338e757d0890df63da1f87e2fe79e769ba3a5bd1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 27 Dec 1998 15:28:54 +0000 Subject: [PATCH] Added beginnings of server-side file handling. Added -debugmsg +server support. Better server request dumping for varargs requests. --- files/dos_fs.c | 4 +- files/file.c | 215 ++++++++++++++++++------------- include/debug.h | 324 +++++++++++++++++++++++------------------------ include/debugdefs.h | 16 +-- include/file.h | 9 +- include/server.h | 54 +++++++- include/server/object.h | 7 + include/server/request.h | 12 ++ loader/main.c | 5 + memory/virtual.c | 12 +- misc/crtdll.c | 11 +- msdos/int21.c | 4 +- scheduler/client.c | 12 ++ scheduler/k32obj.c | 8 +- server/Makefile.in | 1 + server/event.c | 12 +- server/file.c | 195 ++++++++++++++++++++++++++++ server/mutex.c | 12 +- server/process.c | 12 +- server/request.c | 43 +++++++ server/semaphore.c | 12 +- server/trace.c | 249 +++++++++++++++++++++++------------- tools/make_requests | 43 ++++--- 23 files changed, 854 insertions(+), 418 deletions(-) rewrite include/debug.h (91%) create mode 100644 server/file.c diff --git a/files/dos_fs.c b/files/dos_fs.c index 0919d0306c5..2120131f670 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -649,7 +649,7 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode ) return handle; } if (!strcmp(DOSFS_Devices[i].name,"SCSIMGR$")) { - if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32) + if ((handle = FILE_Alloc( &file, -1 )) == INVALID_HANDLE_VALUE32) return HFILE_ERROR32; else { file->unix_name = HEAP_strdupA( SystemHeap, 0, name ); @@ -657,7 +657,7 @@ HFILE32 DOSFS_OpenDevice( const char *name, int unixmode ) } } if (!strcmp(DOSFS_Devices[i].name,"HPSCAN")) { - if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32) + if ((handle = FILE_Alloc( &file, -1 )) == INVALID_HANDLE_VALUE32) return HFILE_ERROR32; else { file->unix_name = HEAP_strdupA( SystemHeap, 0, name ); diff --git a/files/file.c b/files/file.c index 6a5cac09813..779c41b1165 100644 --- a/files/file.c +++ b/files/file.c @@ -38,6 +38,9 @@ #include "async.h" #include "debug.h" +#include "server/request.h" +#include "server.h" + #if defined(MAP_ANONYMOUS) && !defined(MAP_ANON) #define MAP_ANON MAP_ANONYMOUS #endif @@ -80,29 +83,42 @@ static void DOS_RemoveFileLocks(FILE_OBJECT *file); /*********************************************************************** * FILE_Alloc * - * Allocate a file. + * Allocate a file. The unix_handle is closed. */ -HFILE32 FILE_Alloc( FILE_OBJECT **file ) +HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle ) { HFILE32 handle; + struct create_file_request req; + struct create_file_reply reply; + int len; + int fd = dup(unix_handle); + + req.access = FILE_ALL_ACCESS | GENERIC_READ | + GENERIC_WRITE | GENERIC_EXECUTE; /* FIXME */ + req.inherit = 1; /* FIXME */ + CLIENT_SendRequest( REQ_CREATE_FILE, unix_handle, 1, &req, sizeof(req) ); + CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); + CHECK_LEN( len, sizeof(reply) ); + if (reply.handle == -1) return INVALID_HANDLE_VALUE32; + *file = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) ); if (!*file) { DOS_ERROR( ER_TooManyOpenFiles, EC_ProgramError, SA_Abort, EL_Disk ); + CLIENT_CloseHandle( reply.handle ); return (HFILE32)NULL; } (*file)->header.type = K32OBJ_FILE; (*file)->header.refcount = 0; - (*file)->unix_handle = -1; (*file)->unix_name = NULL; + (*file)->unix_handle = fd; (*file)->type = FILE_TYPE_DISK; (*file)->pos = 0; (*file)->mode = 0; (*file)->wait_queue = NULL; - handle = HANDLE_Alloc( PROCESS_Current(), &(*file)->header, - FILE_ALL_ACCESS | GENERIC_READ | - GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, TRUE, -1 ); + handle = HANDLE_Alloc( PROCESS_Current(), &(*file)->header, req.access, + req.inherit, reply.handle ); /* If the allocation failed, the object is already destroyed */ if (handle == INVALID_HANDLE_VALUE32) *file = NULL; return handle; @@ -111,6 +127,7 @@ HFILE32 FILE_Alloc( FILE_OBJECT **file ) /*********************************************************************** * FILE_async_handler [internal] */ +#if 1 static void FILE_async_handler(int unixfd,void *private) { FILE_OBJECT *file = (FILE_OBJECT*)private; @@ -157,6 +174,7 @@ static BOOL32 FILE_Satisfied(K32OBJ *ptr, DWORD thread_id) { return FALSE; /* not abandoned. Hmm? */ } +#endif /* FIXME: lpOverlapped is ignored */ static BOOL32 FILE_Read(K32OBJ *ptr, LPVOID lpBuffer, DWORD nNumberOfChars, @@ -241,7 +259,6 @@ static void FILE_Destroy( K32OBJ *ptr ) DOS_RemoveFileLocks(file); - if (file->unix_handle != -1) close( file->unix_handle ); if (file->unix_name) HeapFree( SystemHeap, 0, file->unix_name ); ptr->type = K32OBJ_UNKNOWN; HeapFree( SystemHeap, 0, file ); @@ -254,10 +271,11 @@ static void FILE_Destroy( K32OBJ *ptr ) * Return the DOS file associated to a task file handle. FILE_ReleaseFile must * be called to release the file. */ -FILE_OBJECT *FILE_GetFile( HFILE32 handle ) +FILE_OBJECT *FILE_GetFile( HFILE32 handle, DWORD access, int *server_handle ) { return (FILE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), handle, - K32OBJ_FILE, 0 /*FIXME*/, NULL ); + K32OBJ_FILE, access, + server_handle ); } @@ -276,16 +294,22 @@ void FILE_ReleaseFile( FILE_OBJECT *file ) * FILE_GetUnixHandle * * Return the Unix handle associated to a file handle. + * The Unix handle must be closed after use. */ -int FILE_GetUnixHandle( HFILE32 hFile ) +int FILE_GetUnixHandle( HFILE32 hFile, DWORD access ) { FILE_OBJECT *file; - int ret; - - if (!(file = FILE_GetFile( hFile ))) return -1; - ret = file->unix_handle; - FILE_ReleaseFile( file ); - return ret; + int unix_handle; + struct get_unix_handle_request req; + + file = (FILE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), hFile, + K32OBJ_FILE, access, &req.handle ); + if (!file) return -1; + req.access = access; + CLIENT_SendRequest( REQ_GET_UNIX_HANDLE, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( NULL, &unix_handle, 0 ); + K32OBJ_DecCount( &file->header ); + return unix_handle; } /*********************************************************************** @@ -526,7 +550,7 @@ static BOOL32 FILE_InUse(char * name, int * mode) if (!pdb) return 0; for (i=0;inbFiles;i++) { - file =FILE_GetFile( (HFILE32) i); + file =FILE_GetFile( (HFILE32)i, 0, NULL ); if(file) { if(file->unix_name) @@ -610,19 +634,15 @@ void FILE_SetDosError(void) */ HFILE32 FILE_DupUnixHandle( int fd ) { - HFILE32 handle; + int unix_handle; FILE_OBJECT *file; - if ((handle = FILE_Alloc( &file )) != INVALID_HANDLE_VALUE32) + if ((unix_handle = dup(fd)) == -1) { - if ((file->unix_handle = dup(fd)) == -1) - { - FILE_SetDosError(); - CloseHandle( handle ); - return INVALID_HANDLE_VALUE32; - } + FILE_SetDosError(); + return INVALID_HANDLE_VALUE32; } - return handle; + return FILE_Alloc( &file, unix_handle ); } @@ -632,32 +652,31 @@ HFILE32 FILE_DupUnixHandle( int fd ) HFILE32 FILE_OpenUnixFile( const char *name, int mode ) { HFILE32 handle; + int unix_handle; FILE_OBJECT *file; struct stat st; - if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32) - return INVALID_HANDLE_VALUE32; - - if ((file->unix_handle = open( name, mode, 0666 )) == -1) + if ((unix_handle = open( name, mode, 0666 )) == -1) { if (!Options.failReadOnly && (mode == O_RDWR)) - file->unix_handle = open( name, O_RDONLY ); + unix_handle = open( name, O_RDONLY ); } - if ((file->unix_handle == -1) || (fstat( file->unix_handle, &st ) == -1)) + if ((unix_handle == -1) || (fstat( unix_handle, &st ) == -1)) { FILE_SetDosError(); - CloseHandle( handle ); return INVALID_HANDLE_VALUE32; } if (S_ISDIR(st.st_mode)) { DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk ); - CloseHandle( handle ); + close( unix_handle ); return INVALID_HANDLE_VALUE32; } /* File opened OK, now fill the FILE_OBJECT */ + if ((handle = FILE_Alloc( &file, unix_handle )) == INVALID_HANDLE_VALUE32) + return INVALID_HANDLE_VALUE32; file->unix_name = HEAP_strdupA( SystemHeap, 0, name ); return handle; } @@ -716,7 +735,7 @@ HFILE32 FILE_Open( LPCSTR path, INT32 mode, INT32 shareMode ) } hFileRet = FILE_OpenUnixFile( unixName, mode ); /* we need to save the mode, but only if it is not in use yet*/ - if ((hFileRet) && (!fileInUse) && ((file =FILE_GetFile(hFileRet)))) + if ((hFileRet) && (!fileInUse) && ((file =FILE_GetFile(hFileRet, 0, NULL)))) { file->mode=dosMode; FILE_ReleaseFile(file); @@ -732,6 +751,7 @@ HFILE32 FILE_Open( LPCSTR path, INT32 mode, INT32 shareMode ) static HFILE32 FILE_Create( LPCSTR path, int mode, int unique ) { HFILE32 handle; + int unix_handle; FILE_OBJECT *file; DOS_FULL_NAME full_name; BOOL32 fileInUse = FALSE; @@ -749,14 +769,7 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique ) return INVALID_HANDLE_VALUE32; } - if ((handle = FILE_Alloc( &file )) == INVALID_HANDLE_VALUE32) - return INVALID_HANDLE_VALUE32; - - if (!DOSFS_GetFullName( path, FALSE, &full_name )) - { - CloseHandle( handle ); - return INVALID_HANDLE_VALUE32; - } + if (!DOSFS_GetFullName( path, FALSE, &full_name )) return INVALID_HANDLE_VALUE32; dosMode = FILE_UnixToDosMode(mode); fileInUse = FILE_InUse(full_name.long_name,&oldMode); @@ -766,17 +779,18 @@ static HFILE32 FILE_Create( LPCSTR path, int mode, int unique ) if (FILE_ShareDeny(dosMode,oldMode)) return INVALID_HANDLE_VALUE32; } - if ((file->unix_handle = open( full_name.long_name, + if ((unix_handle = open( full_name.long_name, O_CREAT | O_TRUNC | O_RDWR | (unique ? O_EXCL : 0), mode )) == -1) { FILE_SetDosError(); - CloseHandle( handle ); return INVALID_HANDLE_VALUE32; } /* File created OK, now fill the FILE_OBJECT */ + if ((handle = FILE_Alloc( &file, unix_handle )) == INVALID_HANDLE_VALUE32) + return INVALID_HANDLE_VALUE32; file->unix_name = HEAP_strdupA( SystemHeap, 0, full_name.long_name ); file->mode = dosMode; return handle; @@ -838,20 +852,28 @@ DWORD WINAPI GetFileInformationByHandle( HFILE32 hFile, BY_HANDLE_FILE_INFORMATION *info ) { FILE_OBJECT *file; - DWORD ret = 0; - struct stat st; + struct get_file_info_request req; + struct get_file_info_reply reply; + int len; if (!info) return 0; - - if (!(file = FILE_GetFile( hFile ))) return 0; - if (fstat( file->unix_handle, &st ) == -1) FILE_SetDosError(); - else - { - FILE_FillInfo( &st, info ); - ret = 1; - } + if (!(file = FILE_GetFile( hFile, 0, &req.handle ))) return 0; + CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) ); + CLIENT_WaitReply( &len, NULL, 1, &reply, sizeof(reply) ); + CHECK_LEN( len, sizeof(reply) ); FILE_ReleaseFile( file ); - return ret; + + DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftCreationTime, 0 ); + DOSFS_UnixTimeToFileTime( reply.write_time, &info->ftLastWriteTime, 0 ); + DOSFS_UnixTimeToFileTime( reply.access_time, &info->ftLastAccessTime, 0 ); + info->dwFileAttributes = reply.attr; + info->dwVolumeSerialNumber = reply.serial; + info->nFileSizeHigh = reply.size_high; + info->nFileSizeLow = reply.size_low; + info->nNumberOfLinks = reply.links; + info->nFileIndexHigh = reply.index_high; + info->nFileIndexLow = reply.index_low; + return 1; } @@ -966,7 +988,7 @@ HFILE32 FILE_Dup2( HFILE32 hFile1, HFILE32 hFile2 ) TRACE(file, "FILE_Dup2 for handle %d\n", hFile1 ); /* FIXME: should use DuplicateHandle */ - if (!(file = FILE_GetFile( hFile1 ))) return HFILE_ERROR32; + if (!(file = FILE_GetFile( hFile1, 0, NULL ))) return HFILE_ERROR32; if (!HANDLE_SetObjPtr( PROCESS_Current(), hFile2, &file->header, 0 )) hFile2 = HFILE_ERROR32; FILE_ReleaseFile( file ); @@ -1207,7 +1229,7 @@ found: hFileRet = FILE_OpenUnixFile( full_name.long_name, unixMode ); if (hFileRet == HFILE_ERROR32) goto not_found; /* we need to save the mode, but only if it is not in use yet*/ - if( (!fileInUse) &&(file =FILE_GetFile(hFileRet))) + if( (!fileInUse) &&(file =FILE_GetFile(hFileRet,0,NULL))) { file->mode=mode; FILE_ReleaseFile(file); @@ -1382,6 +1404,7 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, { FILE_OBJECT *file; DWORD result = 0xffffffff; + int unix_handle; if (highword && *highword) { @@ -1392,8 +1415,12 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, TRACE(file, "handle %d offset %ld origin %ld\n", hFile, distance, method ); - if (!(file = FILE_GetFile( hFile ))) return 0xffffffff; - + if (!(file = FILE_GetFile( hFile, 0, NULL ))) return 0xffffffff; + if ((unix_handle = FILE_GetUnixHandle( hFile, 0 )) == -1) + { + FILE_ReleaseFile( file ); + return 0xffffffff; + } /* the pointer may be positioned before the start of the file; no error is returned in that case, @@ -1405,7 +1432,7 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, case FILE_CURRENT: distance += file->pos; /* fall through */ case FILE_BEGIN: - if ((result = lseek(file->unix_handle, distance, SEEK_SET)) == -1) + if ((result = lseek(unix_handle, distance, SEEK_SET)) == -1) { if ((INT32)distance < 0) file->pos = result = distance; @@ -1414,15 +1441,15 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, file->pos = result; break; case FILE_END: - if ((result = lseek(file->unix_handle, distance, SEEK_END)) == -1) + if ((result = lseek(unix_handle, distance, SEEK_END)) == -1) { if ((INT32)distance < 0) { /* get EOF */ - result = lseek(file->unix_handle, 0, SEEK_END); + result = lseek(unix_handle, 0, SEEK_END); /* return to the old pos, as the first lseek failed */ - lseek(file->unix_handle, file->pos, SEEK_END); + lseek(unix_handle, file->pos, SEEK_END); file->pos = (result += distance); } @@ -1438,6 +1465,7 @@ DWORD WINAPI SetFilePointer( HFILE32 hFile, LONG distance, LONG *highword, if (result == -1) FILE_SetDosError(); + close( unix_handle ); FILE_ReleaseFile( file ); return result; } @@ -1547,15 +1575,16 @@ LONG WINAPI _hwrite32( HFILE32 handle, LPCSTR buffer, LONG count ) TRACE(file, "%d %p %ld\n", handle, buffer, count ); if (count == 0) { /* Expand or truncate at current position */ - FILE_OBJECT *file = FILE_GetFile(handle); - - if ( ftruncate(file->unix_handle, - lseek( file->unix_handle, 0, SEEK_CUR)) == 0 ) { - FILE_ReleaseFile(file); + int unix_handle = FILE_GetUnixHandle( handle, GENERIC_WRITE ); + if ((unix_handle != -1) && + (ftruncate(unix_handle, + lseek( unix_handle, 0, SEEK_CUR)) == 0 )) + { + close( unix_handle ); return 0; } else { FILE_SetDosError(); - FILE_ReleaseFile(file); + close( unix_handle ); return HFILE_ERROR32; } } @@ -1637,18 +1666,18 @@ UINT32 WINAPI SetHandleCount32( UINT32 count ) */ BOOL32 WINAPI FlushFileBuffers( HFILE32 hFile ) { - FILE_OBJECT *file; + int unix_handle; BOOL32 ret; TRACE(file, "(%d)\n", hFile ); - if (!(file = FILE_GetFile( hFile ))) return FALSE; - if (fsync( file->unix_handle ) != -1) ret = TRUE; + if ((unix_handle = FILE_GetUnixHandle( hFile, 0)) == -1) return FALSE; + if (fsync( unix_handle ) != -1) ret = TRUE; else { FILE_SetDosError(); ret = FALSE; } - FILE_ReleaseFile( file ); + close( unix_handle ); return ret; } @@ -1658,18 +1687,18 @@ BOOL32 WINAPI FlushFileBuffers( HFILE32 hFile ) */ BOOL32 WINAPI SetEndOfFile( HFILE32 hFile ) { - FILE_OBJECT *file; + int unix_handle; BOOL32 ret = TRUE; TRACE(file, "(%d)\n", hFile ); - if (!(file = FILE_GetFile( hFile ))) return FALSE; - if (ftruncate( file->unix_handle, - lseek( file->unix_handle, 0, SEEK_CUR ) )) + if ((unix_handle = FILE_GetUnixHandle( hFile, GENERIC_WRITE )) == -1) return FALSE; + if (ftruncate( unix_handle, + lseek( unix_handle, 0, SEEK_CUR ) )) { FILE_SetDosError(); ret = FALSE; } - FILE_ReleaseFile( file ); + close( unix_handle ); return ret; } @@ -1726,7 +1755,7 @@ BOOL32 WINAPI DeleteFile32W( LPCWSTR path ) */ BOOL32 FILE_SetFileType( HFILE32 hFile, DWORD type ) { - FILE_OBJECT *file = FILE_GetFile( hFile ); + FILE_OBJECT *file = FILE_GetFile( hFile, 0, NULL ); if (!file) return FALSE; file->type = type; FILE_ReleaseFile( file ); @@ -1743,10 +1772,16 @@ LPVOID FILE_mmap( HFILE32 hFile, LPVOID start, int prot, int flags ) { LPVOID ret; - FILE_OBJECT *file = FILE_GetFile( hFile ); + int unix_handle; + FILE_OBJECT *file = FILE_GetFile( hFile, 0, NULL ); if (!file) return (LPVOID)-1; - ret = FILE_dommap( file, start, size_high, size_low, - offset_high, offset_low, prot, flags ); + if ((unix_handle = FILE_GetUnixHandle( hFile, 0 )) == -1) ret = (LPVOID)-1; + else + { + ret = FILE_dommap( file, unix_handle, start, size_high, size_low, + offset_high, offset_low, prot, flags ); + close( unix_handle ); + } FILE_ReleaseFile( file ); return ret; } @@ -1755,7 +1790,7 @@ LPVOID FILE_mmap( HFILE32 hFile, LPVOID start, /*********************************************************************** * FILE_dommap */ -LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start, +LPVOID FILE_dommap( FILE_OBJECT *file, int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ) @@ -1792,7 +1827,7 @@ LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start, flags |= MAP_PRIVATE; #endif } - else fd = file->unix_handle; + else fd = unix_handle; if ((ret = mmap( start, size_low, prot, flags, fd, offset_low )) != (LPVOID)-1) @@ -1816,7 +1851,7 @@ LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start, } /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ /* Reserve the memory with an anonymous mmap */ - ret = FILE_dommap( NULL, start, size_high, size_low, 0, 0, + ret = FILE_dommap( NULL, -1, start, size_high, size_low, 0, 0, PROT_READ | PROT_WRITE, flags ); if (ret == (LPVOID)-1) return ret; /* Now read in the file */ @@ -1848,7 +1883,7 @@ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) */ DWORD WINAPI GetFileType( HFILE32 hFile ) { - FILE_OBJECT *file = FILE_GetFile(hFile); + FILE_OBJECT *file = FILE_GetFile(hFile, 0, NULL); if (!file) return FILE_TYPE_UNKNOWN; /* FIXME: correct? */ FILE_ReleaseFile( file ); return file->type; @@ -2126,7 +2161,7 @@ BOOL32 WINAPI SetFileTime( HFILE32 hFile, const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime ) { - FILE_OBJECT *file = FILE_GetFile(hFile); + FILE_OBJECT *file = FILE_GetFile(hFile, 0, NULL); struct utimbuf utimbuf; if (!file) return FILE_TYPE_UNKNOWN; /* FIXME: correct? */ @@ -2263,7 +2298,7 @@ BOOL32 WINAPI LockFile( f.l_pid = 0; f.l_type = F_WRLCK; - if (!(file = FILE_GetFile(hFile))) return FALSE; + if (!(file = FILE_GetFile(hFile,0,NULL))) return FALSE; /* shadow locks internally */ if (!DOS_AddLock(file, &f)) { @@ -2314,7 +2349,7 @@ BOOL32 WINAPI UnlockFile( f.l_pid = 0; f.l_type = F_UNLCK; - if (!(file = FILE_GetFile(hFile))) return FALSE; + if (!(file = FILE_GetFile(hFile,0,NULL))) return FALSE; DOS_RemoveLock(file, &f); /* ok if fails - may be another wine */ diff --git a/include/debug.h b/include/debug.h dissimilarity index 91% index 15a66ad62c1..f5e6447cf9b 100644 --- a/include/debug.h +++ b/include/debug.h @@ -1,165 +1,159 @@ -/* Do not modify this file -- it is automatically generated! */ - -#ifndef __WINE_DEBUGTOOLS_H -#include "debugtools.h" -#endif - -/* Definitions for channels identifiers */ -#define dbch_1 0 -#define dbch_2 1 -#define dbch_3 2 -#define dbch_4 3 -#define dbch_5 4 -#define dbch_6 5 -#define dbch_accel 6 -#define dbch_advapi 7 -#define dbch_animate 8 -#define dbch_aspi 9 -#define dbch_atom 10 -#define dbch_bitblt 11 -#define dbch_bitmap 12 -#define dbch_caret 13 -#define dbch_cdaudio 14 -#define dbch_class 15 -#define dbch_clipboard 16 -#define dbch_clipping 17 -#define dbch_combo 18 -#define dbch_comboex 19 -#define dbch_comm 20 -#define dbch_commctrl 21 -#define dbch_commdlg 22 -#define dbch_console 23 -#define dbch_crtdll 24 -#define dbch_cursor 25 -#define dbch_datetime 26 -#define dbch_dc 27 -#define dbch_dde 28 -#define dbch_ddeml 29 -#define dbch_ddraw 30 -#define dbch_debug 31 -#define dbch_dialog 32 -#define dbch_dinput 33 -#define dbch_dll 34 -#define dbch_dosfs 35 -#define dbch_dosmem 36 -#define dbch_dplay 37 -#define dbch_driver 38 -#define dbch_dsound 39 -#define dbch_edit 40 -#define dbch_event 41 -#define dbch_exec 42 -#define dbch_file 43 -#define dbch_fixup 44 -#define dbch_font 45 -#define dbch_gdi 46 -#define dbch_global 47 -#define dbch_graphics 48 -#define dbch_header 49 -#define dbch_heap 50 -#define dbch_hook 51 -#define dbch_hotkey 52 -#define dbch_icon 53 -#define dbch_imagehlp 54 -#define dbch_imagelist 55 -#define dbch_imm 56 -#define dbch_int 57 -#define dbch_int10 58 -#define dbch_int16 59 -#define dbch_int17 60 -#define dbch_int19 61 -#define dbch_int21 62 -#define dbch_int31 63 -#define dbch_io 64 -#define dbch_ipaddress 65 -#define dbch_key 66 -#define dbch_keyboard 67 -#define dbch_ldt 68 -#define dbch_listbox 69 -#define dbch_listview 70 -#define dbch_local 71 -#define dbch_mci 72 -#define dbch_mcianim 73 -#define dbch_mcimidi 74 -#define dbch_mciwave 75 -#define dbch_mdi 76 -#define dbch_menu 77 -#define dbch_message 78 -#define dbch_metafile 79 -#define dbch_midi 80 -#define dbch_mmaux 81 -#define dbch_mmio 82 -#define dbch_mmsys 83 -#define dbch_mmtime 84 -#define dbch_module 85 -#define dbch_monthcal 86 -#define dbch_mpr 87 -#define dbch_msacm 88 -#define dbch_msg 89 -#define dbch_nativefont 90 -#define dbch_nonclient 91 -#define dbch_ntdll 92 -#define dbch_ole 93 -#define dbch_pager 94 -#define dbch_palette 95 -#define dbch_pidl 96 -#define dbch_print 97 -#define dbch_process 98 -#define dbch_profile 99 -#define dbch_progress 100 -#define dbch_prop 101 -#define dbch_psapi 102 -#define dbch_psdrv 103 -#define dbch_ras 104 -#define dbch_rebar 105 -#define dbch_reg 106 -#define dbch_region 107 -#define dbch_relay 108 -#define dbch_resource 109 -#define dbch_s 110 -#define dbch_scroll 111 -#define dbch_security 112 -#define dbch_segment 113 -#define dbch_selector 114 -#define dbch_sem 115 -#define dbch_sendmsg 116 -#define dbch_shell 117 -#define dbch_shm 118 -#define dbch_snoop 119 -#define dbch_sound 120 -#define dbch_static 121 -#define dbch_statusbar 122 -#define dbch_stress 123 -#define dbch_string 124 -#define dbch_syscolor 125 -#define dbch_system 126 -#define dbch_tab 127 -#define dbch_task 128 -#define dbch_text 129 -#define dbch_thread 130 -#define dbch_thunk 131 -#define dbch_timer 132 -#define dbch_toolbar 133 -#define dbch_toolhelp 134 -#define dbch_tooltips 135 -#define dbch_trackbar 136 -#define dbch_treeview 137 -#define dbch_tweak 138 -#define dbch_uitools 139 -#define dbch_updown 140 -#define dbch_ver 141 -#define dbch_virtual 142 -#define dbch_vxd 143 -#define dbch_wave 144 -#define dbch_win 145 -#define dbch_win16drv 146 -#define dbch_win32 147 -#define dbch_wing 148 -#define dbch_winsock 149 -#define dbch_wnet 150 -#define dbch_x11 151 -#define dbch_x11drv 152 -/* Definitions for classes identifiers */ -#define dbcl_fixme 0 -#define dbcl_err 1 -#define dbcl_warn 2 -#define dbcl_trace 3 +/* Do not modify this file -- it is automatically generated! */ + +#ifndef __WINE_DEBUGTOOLS_H +#include "debugtools.h" +#endif + +/* Definitions for channels identifiers */ +#define dbch_accel 0 +#define dbch_advapi 1 +#define dbch_animate 2 +#define dbch_aspi 3 +#define dbch_atom 4 +#define dbch_bitblt 5 +#define dbch_bitmap 6 +#define dbch_caret 7 +#define dbch_cdaudio 8 +#define dbch_class 9 +#define dbch_clipboard 10 +#define dbch_clipping 11 +#define dbch_combo 12 +#define dbch_comboex 13 +#define dbch_comm 14 +#define dbch_commctrl 15 +#define dbch_commdlg 16 +#define dbch_console 17 +#define dbch_crtdll 18 +#define dbch_cursor 19 +#define dbch_datetime 20 +#define dbch_dc 21 +#define dbch_dde 22 +#define dbch_ddeml 23 +#define dbch_ddraw 24 +#define dbch_debug 25 +#define dbch_dialog 26 +#define dbch_dinput 27 +#define dbch_dll 28 +#define dbch_dosfs 29 +#define dbch_dosmem 30 +#define dbch_dplay 31 +#define dbch_driver 32 +#define dbch_dsound 33 +#define dbch_edit 34 +#define dbch_event 35 +#define dbch_exec 36 +#define dbch_file 37 +#define dbch_fixup 38 +#define dbch_font 39 +#define dbch_gdi 40 +#define dbch_global 41 +#define dbch_graphics 42 +#define dbch_header 43 +#define dbch_heap 44 +#define dbch_hook 45 +#define dbch_hotkey 46 +#define dbch_icon 47 +#define dbch_imagehlp 48 +#define dbch_imagelist 49 +#define dbch_imm 50 +#define dbch_int 51 +#define dbch_int10 52 +#define dbch_int16 53 +#define dbch_int17 54 +#define dbch_int19 55 +#define dbch_int21 56 +#define dbch_int31 57 +#define dbch_io 58 +#define dbch_ipaddress 59 +#define dbch_key 60 +#define dbch_keyboard 61 +#define dbch_ldt 62 +#define dbch_listbox 63 +#define dbch_listview 64 +#define dbch_local 65 +#define dbch_mci 66 +#define dbch_mcianim 67 +#define dbch_mcimidi 68 +#define dbch_mciwave 69 +#define dbch_mdi 70 +#define dbch_menu 71 +#define dbch_message 72 +#define dbch_metafile 73 +#define dbch_midi 74 +#define dbch_mmaux 75 +#define dbch_mmio 76 +#define dbch_mmsys 77 +#define dbch_mmtime 78 +#define dbch_module 79 +#define dbch_monthcal 80 +#define dbch_mpr 81 +#define dbch_msacm 82 +#define dbch_msg 83 +#define dbch_nativefont 84 +#define dbch_nonclient 85 +#define dbch_ntdll 86 +#define dbch_ole 87 +#define dbch_pager 88 +#define dbch_palette 89 +#define dbch_pidl 90 +#define dbch_print 91 +#define dbch_process 92 +#define dbch_profile 93 +#define dbch_progress 94 +#define dbch_prop 95 +#define dbch_psapi 96 +#define dbch_psdrv 97 +#define dbch_ras 98 +#define dbch_rebar 99 +#define dbch_reg 100 +#define dbch_region 101 +#define dbch_relay 102 +#define dbch_resource 103 +#define dbch_scroll 104 +#define dbch_security 105 +#define dbch_segment 106 +#define dbch_selector 107 +#define dbch_sem 108 +#define dbch_sendmsg 109 +#define dbch_server 110 +#define dbch_shell 111 +#define dbch_shm 112 +#define dbch_snoop 113 +#define dbch_sound 114 +#define dbch_static 115 +#define dbch_statusbar 116 +#define dbch_stress 117 +#define dbch_string 118 +#define dbch_syscolor 119 +#define dbch_system 120 +#define dbch_tab 121 +#define dbch_task 122 +#define dbch_text 123 +#define dbch_thread 124 +#define dbch_thunk 125 +#define dbch_timer 126 +#define dbch_toolbar 127 +#define dbch_toolhelp 128 +#define dbch_tooltips 129 +#define dbch_trackbar 130 +#define dbch_treeview 131 +#define dbch_tweak 132 +#define dbch_uitools 133 +#define dbch_updown 134 +#define dbch_ver 135 +#define dbch_virtual 136 +#define dbch_vxd 137 +#define dbch_wave 138 +#define dbch_win 139 +#define dbch_win16drv 140 +#define dbch_win32 141 +#define dbch_wing 142 +#define dbch_winsock 143 +#define dbch_wnet 144 +#define dbch_x11 145 +#define dbch_x11drv 146 +/* Definitions for classes identifiers */ +#define dbcl_fixme 0 +#define dbcl_err 1 +#define dbcl_warn 2 +#define dbcl_trace 3 diff --git a/include/debugdefs.h b/include/debugdefs.h index b30c3156743..ea469b5625c 100644 --- a/include/debugdefs.h +++ b/include/debugdefs.h @@ -4,7 +4,7 @@ #include "debugtools.h" #endif -#define DEBUG_CHANNEL_COUNT 153 +#define DEBUG_CHANNEL_COUNT 147 #ifdef DEBUG_RUNTIME short debug_msg_enabled[][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, @@ -154,20 +154,8 @@ short debug_msg_enabled[][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, {1, 1, 0, 0}, {1, 1, 0, 0}, -{1, 1, 0, 0}, -{1, 1, 0, 0}, -{1, 1, 0, 0}, -{1, 1, 0, 0}, -{1, 1, 0, 0}, -{1, 1, 0, 0}, }; const char* debug_ch_name[] = { -"1", -"2", -"3", -"4", -"5", -"6", "accel", "advapi", "animate", @@ -272,13 +260,13 @@ const char* debug_ch_name[] = { "region", "relay", "resource", -"s", "scroll", "security", "segment", "selector", "sem", "sendmsg", +"server", "shell", "shm", "snoop", diff --git a/include/file.h b/include/file.h index e7827243ddb..b70ae647058 100644 --- a/include/file.h +++ b/include/file.h @@ -62,11 +62,12 @@ typedef struct /* files/file.c */ -extern FILE_OBJECT *FILE_GetFile( HFILE32 handle ); +extern FILE_OBJECT *FILE_GetFile( HFILE32 handle, DWORD access, + int *server_handle ); extern void FILE_ReleaseFile( FILE_OBJECT *file ); -extern HFILE32 FILE_Alloc( FILE_OBJECT **file ); +extern HFILE32 FILE_Alloc( FILE_OBJECT **file, int unix_handle ); extern void FILE_SetDosError(void); -extern int FILE_GetUnixHandle( HFILE32 hFile ); +extern int FILE_GetUnixHandle( HFILE32 hFile, DWORD access ); extern HFILE32 FILE_DupUnixHandle( int fd ); extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info ); extern HFILE32 FILE_Dup( HFILE32 hFile ); @@ -78,7 +79,7 @@ extern LPVOID FILE_mmap( HFILE32 hFile, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ); -extern LPVOID FILE_dommap( FILE_OBJECT *file, LPVOID start, +extern LPVOID FILE_dommap( FILE_OBJECT *file, int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ); diff --git a/include/server.h b/include/server.h index e93cea74c2a..d81ac718d85 100644 --- a/include/server.h +++ b/include/server.h @@ -7,6 +7,9 @@ #ifndef __WINE_SERVER_H #define __WINE_SERVER_H +#include +#include + /* message header as sent on the wire */ struct header { @@ -51,10 +54,18 @@ struct new_thread_reply }; +/* Set the server debug level */ +struct set_debug_request +{ + int level; /* New debug level */ +}; + + /* Initialize a thread; called from the child after fork()/clone() */ struct init_thread_request { int unix_pid; /* Unix pid of new thread */ + char cmd_line[0]; /* Thread command line */ }; @@ -159,7 +170,7 @@ struct create_event_request int manual_reset; /* manual reset event */ int initial_state; /* initial state of the event */ int inherit; /* inherit flag */ - /* char name[] */ + char name[0]; /* event name */ }; struct create_event_reply { @@ -180,7 +191,7 @@ struct create_mutex_request { int owned; /* initially owned? */ int inherit; /* inherit flag */ - /* char name[] */ + char name[0]; /* mutex name */ }; struct create_mutex_reply { @@ -220,6 +231,7 @@ struct release_semaphore_reply unsigned int prev_count; /* previous semaphore count */ }; + /* Open a named object (event, mutex, semaphore) */ struct open_named_obj_request { @@ -236,6 +248,43 @@ struct open_named_obj_reply }; +/* Create a file */ +struct create_file_request +{ + unsigned int access; /* wanted access rights */ + int inherit; /* inherit flag */ +}; +struct create_file_reply +{ + int handle; /* handle to the file */ +}; + + +/* Get a Unix handle to a file */ +struct get_unix_handle_request +{ + int handle; /* handle to the file */ + unsigned int access; /* desired access */ +}; + + +struct get_file_info_request +{ + int handle; /* handle to the file */ +}; +struct get_file_info_reply +{ + int attr; /* file attributes */ + time_t access_time; /* last access time */ + time_t write_time; /* last write time */ + int size_high; /* file size */ + int size_low; /* file size */ + int links; /* number of links */ + int index_high; /* unique index */ + int index_low; /* unique index */ + unsigned int serial; /* volume serial number */ +}; + /* client-side functions */ #ifndef __WINE_SERVER__ @@ -253,6 +302,7 @@ extern unsigned int CLIENT_WaitReply( int *len, int *passed_fd, struct _THDB; extern int CLIENT_NewThread( struct _THDB *thdb, int *thandle, int *phandle ); +extern int CLIENT_SetDebug( int level ); extern int CLIENT_InitThread(void); extern int CLIENT_TerminateProcess( int handle, int exit_code ); extern int CLIENT_TerminateThread( int handle, int exit_code ); diff --git a/include/server/object.h b/include/server/object.h index c00fbc00e5d..d55b810109e 100644 --- a/include/server/object.h +++ b/include/server/object.h @@ -156,6 +156,13 @@ extern struct object *create_semaphore( const char *name, unsigned int initial, extern int open_semaphore( unsigned int access, int inherit, const char *name ); extern int release_semaphore( int handle, unsigned int count, unsigned int *prev_count ); + +/* file functions */ + +extern struct object *create_file( int fd ); +extern int file_get_unix_handle( int handle, unsigned int access ); +extern int get_file_info( int handle, struct get_file_info_reply *reply ); + extern int debug_level; #endif /* __WINE_SERVER_OBJECT_H */ diff --git a/include/server/request.h b/include/server/request.h index 2dc80a564ab..b647223c360 100644 --- a/include/server/request.h +++ b/include/server/request.h @@ -6,6 +6,7 @@ enum request { REQ_NEW_THREAD, + REQ_SET_DEBUG, REQ_INIT_THREAD, REQ_TERMINATE_PROCESS, REQ_TERMINATE_THREAD, @@ -22,6 +23,9 @@ enum request REQ_CREATE_SEMAPHORE, REQ_RELEASE_SEMAPHORE, REQ_OPEN_NAMED_OBJ, + REQ_CREATE_FILE, + REQ_GET_UNIX_HANDLE, + REQ_GET_FILE_INFO, REQ_NB_REQUESTS }; @@ -31,6 +35,7 @@ enum request static void req_##name( struct name##_request *req, void *data, int len, int fd ) DECL_HANDLER(new_thread); +DECL_HANDLER(set_debug); DECL_HANDLER(init_thread); DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_thread); @@ -47,12 +52,16 @@ DECL_HANDLER(release_mutex); DECL_HANDLER(create_semaphore); DECL_HANDLER(release_semaphore); DECL_HANDLER(open_named_obj); +DECL_HANDLER(create_file); +DECL_HANDLER(get_unix_handle); +DECL_HANDLER(get_file_info); static const struct handler { void (*handler)(); unsigned int min_size; } req_handlers[REQ_NB_REQUESTS] = { { (void(*)())req_new_thread, sizeof(struct new_thread_request) }, + { (void(*)())req_set_debug, sizeof(struct set_debug_request) }, { (void(*)())req_init_thread, sizeof(struct init_thread_request) }, { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) }, { (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) }, @@ -69,6 +78,9 @@ static const struct handler { { (void(*)())req_create_semaphore, sizeof(struct create_semaphore_request) }, { (void(*)())req_release_semaphore, sizeof(struct release_semaphore_request) }, { (void(*)())req_open_named_obj, sizeof(struct open_named_obj_request) }, + { (void(*)())req_create_file, sizeof(struct create_file_request) }, + { (void(*)())req_get_unix_handle, sizeof(struct get_unix_handle_request) }, + { (void(*)())req_get_file_info, sizeof(struct get_file_info_request) }, }; #endif /* WANT_REQUEST_HANDLERS */ diff --git a/loader/main.c b/loader/main.c index 4c2d6677e32..002f29d7bfa 100644 --- a/loader/main.c +++ b/loader/main.c @@ -42,6 +42,7 @@ #include "task.h" #include "debug.h" #include "psdrv.h" +#include "server.h" int __winelib = 1; /* Winelib run-time flag */ @@ -50,6 +51,10 @@ int __winelib = 1; /* Winelib run-time flag */ */ BOOL32 MAIN_MainInit(void) { + /* Set server debug level */ + /* To fool make_debug: TRACE(server) */ + CLIENT_SetDebug( TRACE_ON(server) ); + /* Initialize syslevel handling */ SYSLEVEL_Init(); diff --git a/memory/virtual.c b/memory/virtual.c index 5d90f73d626..7493022ba8b 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -33,6 +33,7 @@ typedef struct DWORD size_high; DWORD size_low; FILE_OBJECT *file; + int unix_handle; BYTE protect; } FILE_MAPPING; @@ -604,7 +605,7 @@ LPVOID WINAPI VirtualAlloc( if ((type & MEM_RESERVE) || !base) { view_size = size + (base ? 0 : granularity_mask + 1); - ptr = (UINT32)FILE_dommap( NULL, (LPVOID)base, 0, view_size, 0, 0, + ptr = (UINT32)FILE_dommap( NULL, -1, (LPVOID)base, 0, view_size, 0, 0, VIRTUAL_GetUnixProt( vprot ), MAP_PRIVATE ); if (ptr == (UINT32)-1) { @@ -1086,6 +1087,7 @@ HANDLE32 WINAPI CreateFileMapping32A( LPCSTR name /* [in] Name of file-mapping object */ ) { FILE_MAPPING *mapping = NULL; + int unix_handle = -1; HANDLE32 handle; BYTE vprot; BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); @@ -1172,7 +1174,7 @@ HANDLE32 WINAPI CreateFileMapping32A( if (!(obj = HANDLE_GetObjPtr( PROCESS_Current(), hFile, K32OBJ_FILE, access, NULL ))) goto error; - + if ((unix_handle = FILE_GetUnixHandle( hFile, access )) == -1) goto error; if (!GetFileInformationByHandle( hFile, &info )) goto error; if (!size_high && !size_low) { @@ -1199,6 +1201,7 @@ HANDLE32 WINAPI CreateFileMapping32A( mapping->size_high = size_high; mapping->size_low = ROUND_SIZE( 0, size_low ); mapping->file = (FILE_OBJECT *)obj; + mapping->unix_handle = unix_handle; if (!K32OBJ_AddName( &mapping->header, name )) handle = 0; else handle = HANDLE_Alloc( PROCESS_Current(), &mapping->header, @@ -1209,6 +1212,7 @@ HANDLE32 WINAPI CreateFileMapping32A( error: if (obj) K32OBJ_DecCount( obj ); + if (unix_handle != -1) close( unix_handle ); if (mapping) HeapFree( SystemHeap, 0, mapping ); return 0; } @@ -1280,6 +1284,7 @@ static void VIRTUAL_DestroyMapping( K32OBJ *ptr ) assert( ptr->type == K32OBJ_MEM_MAPPED_FILE ); if (mapping->file) K32OBJ_DecCount( &mapping->file->header ); + if (mapping->unix_handle != -1) close( mapping->unix_handle ); ptr->type = K32OBJ_UNKNOWN; HeapFree( SystemHeap, 0, mapping ); } @@ -1380,7 +1385,8 @@ LPVOID WINAPI MapViewOfFileEx( TRACE(virtual, "handle=%x size=%x offset=%lx\n", handle, size, offset_low ); - ptr = (UINT32)FILE_dommap( mapping->file, addr, 0, size, 0, offset_low, + ptr = (UINT32)FILE_dommap( mapping->file, mapping->unix_handle, + addr, 0, size, 0, offset_low, VIRTUAL_GetUnixProt( mapping->protect ), flags ); if (ptr == (UINT32)-1) { diff --git a/misc/crtdll.c b/misc/crtdll.c index 9994674e57e..c142b7efbf4 100644 --- a/misc/crtdll.c +++ b/misc/crtdll.c @@ -50,8 +50,6 @@ Unresolved issues Uwe Bonnes 970904: #include "options.h" #include "winnls.h" -extern int FILE_GetUnixHandle( HFILE32 ); - static DOS_FULL_NAME CRTDLL_tmpname; UINT32 CRTDLL_argc_dll; /* CRTDLL.23 */ @@ -310,7 +308,7 @@ DWORD __cdecl CRTDLL_fopen(LPCSTR path, LPCSTR mode) TRACE(crtdll, "%s in BINARY mode\n",path); dos_fildes=FILE_Open(path, flagmode,0); - unix_fildes=FILE_GetUnixHandle(dos_fildes); + unix_fildes=FILE_GetUnixHandle(dos_fildes,0); file = fdopen(unix_fildes,mode); TRACE(crtdll, "file %s mode %s got ufh %d dfh %d file %p\n", @@ -1100,7 +1098,12 @@ INT32 __cdecl CRTDLL_fclose( FILE *stream ) if (unix_handle<4) ret= fclose(stream); else { - while(FILE_GetUnixHandle(dos_handle) != unix_handle) dos_handle++; + int h; + while((h = FILE_GetUnixHandle(dos_handle,0)) != unix_handle) + { + close(h); + dos_handle++; + } fclose(stream); ret = _lclose32( dos_handle); } diff --git a/msdos/int21.c b/msdos/int21.c index cc5ec8a73a3..da1402004f7 100644 --- a/msdos/int21.c +++ b/msdos/int21.c @@ -223,7 +223,7 @@ static void ioctlGetDeviceInfo( CONTEXT *context ) RESET_CFLAG(context); /* DOS device ? */ - if ((file = FILE_GetFile( HFILE16_TO_HFILE32(BX_reg(context)) ))) + if ((file = FILE_GetFile( HFILE16_TO_HFILE32(BX_reg(context)), 0, NULL ))) { const DOS_DEVICE *dev = DOSFS_GetDevice( file->unix_name ); FILE_ReleaseFile( file ); @@ -1520,7 +1520,7 @@ void WINAPI DOS3Call( CONTEXT *context ) break; case 0x02:{ FILE_OBJECT *file; - file = FILE_GetFile(HFILE16_TO_HFILE32(BX_reg(context))); + file = FILE_GetFile(HFILE16_TO_HFILE32(BX_reg(context)),0,NULL); if (!strcasecmp(file->unix_name, "SCSIMGR$")) ASPI_DOS_HandleInt(context); FILE_ReleaseFile( file ); diff --git a/scheduler/client.c b/scheduler/client.c index 5f819cf5670..47670a4c421 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -247,6 +247,7 @@ int CLIENT_NewThread( THDB *thdb, int *thandle, int *phandle ) case 0: /* child */ close( tmpfd[0] ); sprintf( buffer, "%d", tmpfd[1] ); +/*#define EXEC_SERVER*/ #ifdef EXEC_SERVER execlp( "wineserver", "wineserver", buffer, NULL ); execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL ); @@ -316,6 +317,17 @@ int CLIENT_InitThread(void) /*********************************************************************** + * CLIENT_SetDebug + * + * Send a set debug level request. Return 0 if OK. + */ +int CLIENT_SetDebug( int level ) +{ + CLIENT_SendRequest( REQ_SET_DEBUG, -1, 1, &level, sizeof(level) ); + return CLIENT_WaitReply( NULL, NULL, 0 ); +} + +/*********************************************************************** * CLIENT_TerminateProcess * * Send a terminate process request. Return 0 if OK. diff --git a/scheduler/k32obj.c b/scheduler/k32obj.c index f6543bf1ddc..d191c122697 100644 --- a/scheduler/k32obj.c +++ b/scheduler/k32obj.c @@ -12,9 +12,6 @@ /* The declarations are here to avoid including a lot of unnecessary files */ -extern const K32OBJ_OPS SEMAPHORE_Ops; -extern const K32OBJ_OPS EVENT_Ops; -extern const K32OBJ_OPS MUTEX_Ops; extern const K32OBJ_OPS CRITICAL_SECTION_Ops; extern const K32OBJ_OPS PROCESS_Ops; extern const K32OBJ_OPS THREAD_Ops; @@ -25,6 +22,11 @@ extern const K32OBJ_OPS DEVICE_Ops; extern const K32OBJ_OPS CONSOLE_Ops; extern const K32OBJ_OPS SNAPSHOT_Ops; +/* The following are fully implemented in the server and could be removed */ +extern const K32OBJ_OPS SEMAPHORE_Ops; +extern const K32OBJ_OPS EVENT_Ops; +extern const K32OBJ_OPS MUTEX_Ops; + static const K32OBJ_OPS K32OBJ_NullOps = { NULL, /* signaled */ diff --git a/server/Makefile.in b/server/Makefile.in index 1dfd55d5cdc..e1f28df9e30 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -7,6 +7,7 @@ MODULE = server C_SRCS = \ event.c \ + file.c \ mutex.c \ object.c \ process.c \ diff --git a/server/event.c b/server/event.c index 2483002e670..f1da91fd77d 100644 --- a/server/event.c +++ b/server/event.c @@ -19,19 +19,19 @@ struct event int signaled; /* event has been signaled */ }; -static void dump_event( struct object *obj, int verbose ); +static void event_dump( struct object *obj, int verbose ); static int event_signaled( struct object *obj, struct thread *thread ); static int event_satisfied( struct object *obj, struct thread *thread ); -static void destroy_event( struct object *obj ); +static void event_destroy( struct object *obj ); static const struct object_ops event_ops = { - dump_event, + event_dump, add_queue, remove_queue, event_signaled, event_satisfied, - destroy_event + event_destroy }; @@ -96,7 +96,7 @@ int reset_event( int handle ) return 1; } -static void dump_event( struct object *obj, int verbose ) +static void event_dump( struct object *obj, int verbose ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); @@ -119,7 +119,7 @@ static int event_satisfied( struct object *obj, struct thread *thread ) return 0; /* Not abandoned */ } -static void destroy_event( struct object *obj ) +static void event_destroy( struct object *obj ) { struct event *event = (struct event *)obj; assert( obj->ops == &event_ops ); diff --git a/server/file.c b/server/file.c new file mode 100644 index 00000000000..82319f329a6 --- /dev/null +++ b/server/file.c @@ -0,0 +1,195 @@ +/* + * Server-side file management + * + * Copyright (C) 1998 Alexandre Julliard + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "winerror.h" +#include "winnt.h" +#include "server/thread.h" + +struct file +{ + struct object obj; /* object header */ + int fd; /* Unix file descriptor */ + int event; /* possible events on this file */ +}; + +static void file_dump( struct object *obj, int verbose ); +static void file_add_queue( struct object *obj, struct wait_queue_entry *entry ); +static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry ); +static int file_signaled( struct object *obj, struct thread *thread ); +static int file_satisfied( struct object *obj, struct thread *thread ); +static void file_destroy( struct object *obj ); + +static const struct object_ops file_ops = +{ + file_dump, + file_add_queue, + file_remove_queue, + file_signaled, + file_satisfied, + file_destroy +}; + +static void file_event( int fd, int event, void *private ); +static void file_timeout( int fd, void *private ); + +static const struct select_ops select_ops = +{ + file_event, + file_timeout +}; + +struct object *create_file( int fd ) +{ + struct file *file; + int flags; + + if ((flags = fcntl( fd, F_GETFL )) == -1) + { + perror( "fcntl" ); + return NULL; + } + if (!(file = mem_alloc( sizeof(*file) ))) return NULL; + init_object( &file->obj, &file_ops, NULL ); + file->fd = fd; + switch(flags & 3) + { + case O_RDONLY: + file->event = READ_EVENT; + break; + case O_WRONLY: + file->event = WRITE_EVENT; + break; + case O_RDWR: + file->event = READ_EVENT | WRITE_EVENT; + break; + } + CLEAR_ERROR(); + return &file->obj; +} + +static void file_dump( struct object *obj, int verbose ) +{ + struct file *file = (struct file *)obj; + assert( obj->ops == &file_ops ); + printf( "File fd=%d\n", file->fd ); +} + +static void file_add_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + struct file *file = (struct file *)obj; + assert( obj->ops == &file_ops ); + if (!obj->head) /* first on the queue */ + add_select_user( file->fd, READ_EVENT | WRITE_EVENT, &select_ops, file ); + add_queue( obj, entry ); +} + +static void file_remove_queue( struct object *obj, struct wait_queue_entry *entry ) +{ + struct file *file = (struct file *)grab_object(obj); + assert( obj->ops == &file_ops ); + + remove_queue( obj, entry ); + if (!obj->head) /* last on the queue is gone */ + remove_select_user( file->fd ); + release_object( obj ); +} + +static int file_signaled( struct object *obj, struct thread *thread ) +{ + fd_set read_fds, write_fds; + struct timeval tv = { 0, 0 }; + + struct file *file = (struct file *)obj; + assert( obj->ops == &file_ops ); + + FD_ZERO( &read_fds ); + FD_ZERO( &write_fds ); + if (file->event & READ_EVENT) FD_SET( file->fd, &read_fds ); + if (file->event & WRITE_EVENT) FD_SET( file->fd, &write_fds ); + return select( file->fd + 1, &read_fds, &write_fds, NULL, &tv ) > 0; +} + +static int file_satisfied( struct object *obj, struct thread *thread ) +{ + /* Nothing to do */ + return 0; /* Not abandoned */ +} + +static void file_destroy( struct object *obj ) +{ + struct file *file = (struct file *)obj; + assert( obj->ops == &file_ops ); + close( file->fd ); + free( file ); +} + +static void file_event( int fd, int event, void *private ) +{ + struct file *file = (struct file *)private; + assert( file ); + + wake_up( &file->obj, 0 ); +} + +static void file_timeout( int fd, void *private ) +{ + /* we never set a timeout on a file */ + assert( 0 ); +} + +int file_get_unix_handle( int handle, unsigned int access ) +{ + struct file *file; + int unix_handle; + + if (!(file = (struct file *)get_handle_obj( current->process, handle, + access, &file_ops ))) + return -1; + unix_handle = dup( file->fd ); + release_object( file ); + return unix_handle; +} + +int get_file_info( int handle, struct get_file_info_reply *reply ) +{ + struct file *file; + struct stat st; + + if (!(file = (struct file *)get_handle_obj( current->process, handle, + 0, &file_ops ))) + return 0; + if (fstat( file->fd, &st ) == -1) + { + /* file_set_error(); */ + release_object( file ); + return 0; + } + if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY; + else reply->attr = FILE_ATTRIBUTE_ARCHIVE; + if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY; + reply->access_time = st.st_atime; + reply->write_time = st.st_mtime; + reply->size_high = 0; + reply->size_low = S_ISDIR(st.st_mode) ? 0 : st.st_size; + reply->links = st.st_nlink; + reply->index_high = st.st_dev; + reply->index_low = st.st_ino; + reply->serial = 0; /* FIXME */ + + release_object( file ); + return 1; +} diff --git a/server/mutex.c b/server/mutex.c index aee0771ba4d..375294f2814 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -22,19 +22,19 @@ struct mutex struct mutex *prev; }; -static void dump_mutex( struct object *obj, int verbose ); +static void mutex_dump( struct object *obj, int verbose ); static int mutex_signaled( struct object *obj, struct thread *thread ); static int mutex_satisfied( struct object *obj, struct thread *thread ); -static void destroy_mutex( struct object *obj ); +static void mutex_destroy( struct object *obj ); static const struct object_ops mutex_ops = { - dump_mutex, + mutex_dump, add_queue, remove_queue, mutex_signaled, mutex_satisfied, - destroy_mutex + mutex_destroy }; @@ -103,7 +103,7 @@ void abandon_mutexes( struct thread *thread ) } } -static void dump_mutex( struct object *obj, int verbose ) +static void mutex_dump( struct object *obj, int verbose ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); @@ -136,7 +136,7 @@ static int mutex_satisfied( struct object *obj, struct thread *thread ) return 1; } -static void destroy_mutex( struct object *obj ) +static void mutex_destroy( struct object *obj ) { struct mutex *mutex = (struct mutex *)obj; assert( obj->ops == &mutex_ops ); diff --git a/server/process.c b/server/process.c index 79b38331ea5..da3f06c523c 100644 --- a/server/process.c +++ b/server/process.c @@ -54,21 +54,21 @@ static struct process *first_process; /* process operations */ -static void dump_process( struct object *obj, int verbose ); +static void process_dump( struct object *obj, int verbose ); static int process_signaled( struct object *obj, struct thread *thread ); static int process_satisfied( struct object *obj, struct thread *thread ); -static void destroy_process( struct object *obj ); +static void process_destroy( struct object *obj ); static void free_handles( struct process *process ); static int copy_handle_table( struct process *process, struct process *parent ); static const struct object_ops process_ops = { - dump_process, + process_dump, add_queue, remove_queue, process_signaled, process_satisfied, - destroy_process + process_destroy }; /* create a new process */ @@ -100,7 +100,7 @@ struct process *create_process(void) } /* destroy a process when its refcount is 0 */ -static void destroy_process( struct object *obj ) +static void process_destroy( struct object *obj ) { struct process *process = (struct process *)obj; assert( obj->ops == &process_ops ); @@ -116,7 +116,7 @@ static void destroy_process( struct object *obj ) } /* dump a process on stdout for debugging purposes */ -static void dump_process( struct object *obj, int verbose ) +static void process_dump( struct object *obj, int verbose ) { struct process *process = (struct process *)obj; assert( obj->ops == &process_ops ); diff --git a/server/request.c b/server/request.c index 6ce5b35e6ed..4c14c48c47b 100644 --- a/server/request.c +++ b/server/request.c @@ -152,6 +152,14 @@ DECL_HANDLER(init_thread) send_reply( current, -1, 0 ); } +/* set the debug level */ +DECL_HANDLER(set_debug) +{ + debug_level = req->level; + CLEAR_ERROR(); + send_reply( current, -1, 0 ); +} + /* terminate a process */ DECL_HANDLER(terminate_process) { @@ -372,3 +380,38 @@ DECL_HANDLER(open_named_obj) send_reply( current, -1, 1, &reply, sizeof(reply) ); } +/* create a file */ +DECL_HANDLER(create_file) +{ + struct create_file_reply reply = { -1 }; + struct object *obj; + int new_fd; + + if ((new_fd = dup(fd)) == -1) + { + 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 ); + release_object( obj ); + } + done: + send_reply( current, -1, 1, &reply, sizeof(reply) ); +} + +/* get a Unix handle to a file */ +DECL_HANDLER(get_unix_handle) +{ + int handle = file_get_unix_handle( req->handle, req->access ); + send_reply( current, handle, 0 ); +} + +/* get a file information */ +DECL_HANDLER(get_file_info) +{ + struct get_file_info_reply reply; + get_file_info( req->handle, &reply ); + send_reply( current, -1, 1, &reply, sizeof(reply) ); +} diff --git a/server/semaphore.c b/server/semaphore.c index 2753d96ad9a..cd77d166b20 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -19,19 +19,19 @@ struct semaphore unsigned int max; /* maximum possible count */ }; -static void dump_semaphore( struct object *obj, int verbose ); +static void semaphore_dump( struct object *obj, int verbose ); static int semaphore_signaled( struct object *obj, struct thread *thread ); static int semaphore_satisfied( struct object *obj, struct thread *thread ); -static void destroy_semaphore( struct object *obj ); +static void semaphore_destroy( struct object *obj ); static const struct object_ops semaphore_ops = { - dump_semaphore, + semaphore_dump, add_queue, remove_queue, semaphore_signaled, semaphore_satisfied, - destroy_semaphore + semaphore_destroy }; @@ -89,7 +89,7 @@ int release_semaphore( int handle, unsigned int count, unsigned int *prev_count return 1; } -static void dump_semaphore( struct object *obj, int verbose ) +static void semaphore_dump( struct object *obj, int verbose ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); @@ -112,7 +112,7 @@ static int semaphore_satisfied( struct object *obj, struct thread *thread ) return 0; /* not abandoned */ } -static void destroy_semaphore( struct object *obj ) +static void semaphore_destroy( struct object *obj ) { struct semaphore *sem = (struct semaphore *)obj; assert( obj->ops == &semaphore_ops ); diff --git a/server/trace.c b/server/trace.c index 0850fd5a4ae..1dc815c3783 100644 --- a/server/trace.c +++ b/server/trace.c @@ -6,64 +6,81 @@ #include "server.h" #include "server/thread.h" -static void dump_new_thread_request( struct new_thread_request *req ) +static int dump_new_thread_request( struct new_thread_request *req, int len ) { printf( " pid=%p", req->pid ); + return (int)sizeof(*req); } -static void dump_new_thread_reply( struct new_thread_reply *req ) +static int dump_new_thread_reply( struct new_thread_reply *req, int len ) { printf( " tid=%p,", req->tid ); printf( " thandle=%d,", req->thandle ); printf( " pid=%p,", req->pid ); printf( " phandle=%d", req->phandle ); + return (int)sizeof(*req); } -static void dump_init_thread_request( struct init_thread_request *req ) +static int dump_set_debug_request( struct set_debug_request *req, int len ) { - printf( " unix_pid=%d", req->unix_pid ); + printf( " level=%d", req->level ); + return (int)sizeof(*req); } -static void dump_terminate_process_request( struct terminate_process_request *req ) +static int dump_init_thread_request( struct init_thread_request *req, int len ) +{ + printf( " unix_pid=%d,", req->unix_pid ); + printf( " cmd_line=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) ); + return len; +} + +static int dump_terminate_process_request( struct terminate_process_request *req, int len ) { printf( " handle=%d,", req->handle ); printf( " exit_code=%d", req->exit_code ); + return (int)sizeof(*req); } -static void dump_terminate_thread_request( struct terminate_thread_request *req ) +static int dump_terminate_thread_request( struct terminate_thread_request *req, int len ) { printf( " handle=%d,", req->handle ); printf( " exit_code=%d", req->exit_code ); + return (int)sizeof(*req); } -static void dump_get_process_info_request( struct get_process_info_request *req ) +static int dump_get_process_info_request( struct get_process_info_request *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_get_process_info_reply( struct get_process_info_reply *req ) +static int dump_get_process_info_reply( struct get_process_info_reply *req, int len ) { printf( " pid=%p,", req->pid ); printf( " exit_code=%d", req->exit_code ); + return (int)sizeof(*req); } -static void dump_get_thread_info_request( struct get_thread_info_request *req ) +static int dump_get_thread_info_request( struct get_thread_info_request *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_get_thread_info_reply( struct get_thread_info_reply *req ) +static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len ) { printf( " pid=%p,", req->pid ); printf( " exit_code=%d", req->exit_code ); + return (int)sizeof(*req); } -static void dump_close_handle_request( struct close_handle_request *req ) +static int dump_close_handle_request( struct close_handle_request *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_dup_handle_request( struct dup_handle_request *req ) +static int dump_dup_handle_request( struct dup_handle_request *req, int len ) { printf( " src_process=%d,", req->src_process ); printf( " src_handle=%d,", req->src_handle ); @@ -72,171 +89,222 @@ static void dump_dup_handle_request( struct dup_handle_request *req ) printf( " access=%08x,", req->access ); printf( " inherit=%d,", req->inherit ); printf( " options=%d", req->options ); + return (int)sizeof(*req); } -static void dump_dup_handle_reply( struct dup_handle_reply *req ) +static int dump_dup_handle_reply( struct dup_handle_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_open_process_request( struct open_process_request *req ) +static int dump_open_process_request( struct open_process_request *req, int len ) { printf( " pid=%p,", req->pid ); printf( " access=%08x,", req->access ); printf( " inherit=%d", req->inherit ); + return (int)sizeof(*req); } -static void dump_open_process_reply( struct open_process_reply *req ) +static int dump_open_process_reply( struct open_process_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_select_request( struct select_request *req ) +static int dump_select_request( struct select_request *req, int len ) { printf( " count=%d,", req->count ); printf( " flags=%d,", req->flags ); printf( " timeout=%d", req->timeout ); + return (int)sizeof(*req); } -static void dump_select_reply( struct select_reply *req ) +static int dump_select_reply( struct select_reply *req, int len ) { printf( " signaled=%d", req->signaled ); + return (int)sizeof(*req); } -static void dump_create_event_request( struct create_event_request *req ) +static int dump_create_event_request( struct create_event_request *req, int len ) { printf( " manual_reset=%d,", req->manual_reset ); printf( " initial_state=%d,", req->initial_state ); - printf( " inherit=%d", req->inherit ); + printf( " inherit=%d,", req->inherit ); + printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) ); + return len; } -static void dump_create_event_reply( struct create_event_reply *req ) +static int dump_create_event_reply( struct create_event_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_event_op_request( struct event_op_request *req ) +static int dump_event_op_request( struct event_op_request *req, int len ) { printf( " handle=%d,", req->handle ); printf( " op=%d", req->op ); + return (int)sizeof(*req); } -static void dump_create_mutex_request( struct create_mutex_request *req ) +static int dump_create_mutex_request( struct create_mutex_request *req, int len ) { printf( " owned=%d,", req->owned ); - printf( " inherit=%d", req->inherit ); + printf( " inherit=%d,", req->inherit ); + printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) ); + return len; } -static void dump_create_mutex_reply( struct create_mutex_reply *req ) +static int dump_create_mutex_reply( struct create_mutex_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_release_mutex_request( struct release_mutex_request *req ) +static int dump_release_mutex_request( struct release_mutex_request *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_create_semaphore_request( struct create_semaphore_request *req ) +static int dump_create_semaphore_request( struct create_semaphore_request *req, int len ) { printf( " initial=%08x,", req->initial ); printf( " max=%08x,", req->max ); printf( " inherit=%d", req->inherit ); + return (int)sizeof(*req); } -static void dump_create_semaphore_reply( struct create_semaphore_reply *req ) +static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); } -static void dump_release_semaphore_request( struct release_semaphore_request *req ) +static int dump_release_semaphore_request( struct release_semaphore_request *req, int len ) { printf( " handle=%d,", req->handle ); printf( " count=%08x", req->count ); + return (int)sizeof(*req); } -static void dump_release_semaphore_reply( struct release_semaphore_reply *req ) +static int dump_release_semaphore_reply( struct release_semaphore_reply *req, int len ) { printf( " prev_count=%08x", req->prev_count ); + return (int)sizeof(*req); } -static void dump_open_named_obj_request( struct open_named_obj_request *req ) +static int dump_open_named_obj_request( struct open_named_obj_request *req, int len ) { printf( " type=%d,", req->type ); printf( " access=%08x,", req->access ); printf( " inherit=%d", req->inherit ); + return (int)sizeof(*req); } -static void dump_open_named_obj_reply( struct open_named_obj_reply *req ) +static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len ) { printf( " handle=%d", req->handle ); + return (int)sizeof(*req); +} + +static int dump_create_file_request( struct create_file_request *req, int len ) +{ + printf( " access=%08x,", req->access ); + printf( " inherit=%d", req->inherit ); + return (int)sizeof(*req); +} + +static int dump_create_file_reply( struct create_file_reply *req, int len ) +{ + printf( " handle=%d", req->handle ); + return (int)sizeof(*req); +} + +static int dump_get_unix_handle_request( struct get_unix_handle_request *req, int len ) +{ + printf( " handle=%d,", req->handle ); + printf( " access=%08x", req->access ); + return (int)sizeof(*req); +} + +static int dump_get_file_info_request( struct get_file_info_request *req, int len ) +{ + printf( " handle=%d", req->handle ); + return (int)sizeof(*req); +} + +static int dump_get_file_info_reply( struct get_file_info_reply *req, int len ) +{ + printf( " attr=%d,", req->attr ); + printf( " access_time=%ld,", req->access_time ); + printf( " write_time=%ld,", req->write_time ); + printf( " size_high=%d,", req->size_high ); + printf( " size_low=%d,", req->size_low ); + printf( " links=%d,", req->links ); + printf( " index_high=%d,", req->index_high ); + printf( " index_low=%d,", req->index_low ); + printf( " serial=%08x", req->serial ); + return (int)sizeof(*req); } struct dumper { - void (*dump_req)(); - void (*dump_reply)(); - unsigned int size; + int (*dump_req)( void *data, int len ); + void (*dump_reply)( void *data ); }; static const struct dumper dumpers[REQ_NB_REQUESTS] = { - { (void(*)())dump_new_thread_request, - (void(*)())dump_new_thread_reply, - sizeof(struct new_thread_request) }, - { (void(*)())dump_init_thread_request, - (void(*)())0, - sizeof(struct init_thread_request) }, - { (void(*)())dump_terminate_process_request, - (void(*)())0, - sizeof(struct terminate_process_request) }, - { (void(*)())dump_terminate_thread_request, - (void(*)())0, - sizeof(struct terminate_thread_request) }, - { (void(*)())dump_get_process_info_request, - (void(*)())dump_get_process_info_reply, - sizeof(struct get_process_info_request) }, - { (void(*)())dump_get_thread_info_request, - (void(*)())dump_get_thread_info_reply, - sizeof(struct get_thread_info_request) }, - { (void(*)())dump_close_handle_request, - (void(*)())0, - sizeof(struct close_handle_request) }, - { (void(*)())dump_dup_handle_request, - (void(*)())dump_dup_handle_reply, - sizeof(struct dup_handle_request) }, - { (void(*)())dump_open_process_request, - (void(*)())dump_open_process_reply, - sizeof(struct open_process_request) }, - { (void(*)())dump_select_request, - (void(*)())dump_select_reply, - sizeof(struct select_request) }, - { (void(*)())dump_create_event_request, - (void(*)())dump_create_event_reply, - sizeof(struct create_event_request) }, - { (void(*)())dump_event_op_request, - (void(*)())0, - sizeof(struct event_op_request) }, - { (void(*)())dump_create_mutex_request, - (void(*)())dump_create_mutex_reply, - sizeof(struct create_mutex_request) }, - { (void(*)())dump_release_mutex_request, - (void(*)())0, - sizeof(struct release_mutex_request) }, - { (void(*)())dump_create_semaphore_request, - (void(*)())dump_create_semaphore_reply, - sizeof(struct create_semaphore_request) }, - { (void(*)())dump_release_semaphore_request, - (void(*)())dump_release_semaphore_reply, - sizeof(struct release_semaphore_request) }, - { (void(*)())dump_open_named_obj_request, - (void(*)())dump_open_named_obj_reply, - sizeof(struct open_named_obj_request) }, + { (int(*)(void *,int))dump_new_thread_request, + (void(*)())dump_new_thread_reply }, + { (int(*)(void *,int))dump_set_debug_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_init_thread_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_terminate_process_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_terminate_thread_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_get_process_info_request, + (void(*)())dump_get_process_info_reply }, + { (int(*)(void *,int))dump_get_thread_info_request, + (void(*)())dump_get_thread_info_reply }, + { (int(*)(void *,int))dump_close_handle_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_dup_handle_request, + (void(*)())dump_dup_handle_reply }, + { (int(*)(void *,int))dump_open_process_request, + (void(*)())dump_open_process_reply }, + { (int(*)(void *,int))dump_select_request, + (void(*)())dump_select_reply }, + { (int(*)(void *,int))dump_create_event_request, + (void(*)())dump_create_event_reply }, + { (int(*)(void *,int))dump_event_op_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_create_mutex_request, + (void(*)())dump_create_mutex_reply }, + { (int(*)(void *,int))dump_release_mutex_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_create_semaphore_request, + (void(*)())dump_create_semaphore_reply }, + { (int(*)(void *,int))dump_release_semaphore_request, + (void(*)())dump_release_semaphore_reply }, + { (int(*)(void *,int))dump_open_named_obj_request, + (void(*)())dump_open_named_obj_reply }, + { (int(*)(void *,int))dump_create_file_request, + (void(*)())dump_create_file_reply }, + { (int(*)(void *,int))dump_get_unix_handle_request, + (void(*)())0 }, + { (int(*)(void *,int))dump_get_file_info_request, + (void(*)())dump_get_file_info_reply }, }; static const char * const req_names[REQ_NB_REQUESTS] = { "new_thread", + "set_debug", "init_thread", "terminate_process", "terminate_thread", @@ -253,17 +321,20 @@ static const char * const req_names[REQ_NB_REQUESTS] = "create_semaphore", "release_semaphore", "open_named_obj", + "create_file", + "get_unix_handle", + "get_file_info", }; void trace_request( enum request req, void *data, int len, int fd ) { + int size; current->last_req = req; printf( "%08x: %s(", (unsigned int)current, req_names[req] ); - dumpers[req].dump_req( data ); - if (len > dumpers[req].size) + size = dumpers[req].dump_req( data, len ); + if ((len -= size) > 0) { - unsigned char *ptr = (unsigned char *)data + dumpers[req].size; - len -= dumpers[req].size; + unsigned char *ptr = (unsigned char *)data + size; while (len--) printf( ", %02x", *ptr++ ); } if (fd != -1) printf( " ) fd=%d\n", fd ); diff --git a/tools/make_requests b/tools/make_requests index f02bd43f604..5c80ecf2277 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -9,8 +9,11 @@ %formats = ( "int" => "%d", + "char" => "%c", + "char[0]" => "\\\"%.*s\\\"", "unsigned int" => "%08x", - "void*" => "%p" + "void*" => "%p", + "time_t" => "%ld" ); my @requests = (); @@ -46,9 +49,8 @@ print TRACE<last_req = req; printf( "%08x: %s(", (unsigned int)current, req_names[req] ); - dumpers[req].dump_req( data ); - if (len > dumpers[req].size) + size = dumpers[req].dump_req( data, len ); + if ((len -= size) > 0) { - unsigned char *ptr = (unsigned char *)data + dumpers[req].size; - len -= dumpers[req].size; + unsigned char *ptr = (unsigned char *)data + size; while (len--) printf( ", %02x", *ptr++ ); } if (fd != -1) printf( " ) fd=%d\\n", fd ); @@ -196,8 +197,8 @@ sub DO_REQUEST next if /^{$/; s!/\*.*\*/!!g; next if /^\s*$/; - / *(\w+\**( +\w+\**)*) +(\w+);/ or die "Unrecognized syntax $_"; - my $type = $1; + / *(\w+\**( +\w+\**)*) +(\w+)(\[0\])?;/ or die "Unrecognized syntax $_"; + my $type = $1 . ($4 || ""); my $var = $3; die "Unrecognized type $type" unless defined($formats{$type}); push @struct, $type, $var; @@ -232,15 +233,25 @@ sub DO_REPLY sub DO_DUMP_FUNC { + my $vararg = 0; my $name = shift; - print TRACE "\nstatic void dump_$name( struct $name *req )\n{\n"; + print TRACE "\nstatic int dump_$name( struct $name *req, int len )\n{\n"; while ($#_ >= 0) { my $type = shift; my $var = shift; print TRACE " printf( \" $var=$formats{$type}"; print TRACE "," if ($#_ > 0); - print TRACE "\", req->$var );\n"; + print TRACE "\", "; + if ($type =~ s/\[0\]$//g) # vararg type? + { + $vararg = 1; + print TRACE "len - (int)sizeof(*req), ($type *)(req+1) );\n"; + } + else + { + print TRACE "req->$var );\n"; + } } - print TRACE "}\n"; + print TRACE " return ", $vararg ? "len" : "(int)sizeof(*req)", ";\n}\n"; } -- 2.11.4.GIT