Commit 338e757d authored by Alexandre Julliard's avatar Alexandre Julliard

Added beginnings of server-side file handling.

Added -debugmsg +server support. Better server request dumping for varargs requests.
parent 6842064f
......@@ -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 );
......
......@@ -5,159 +5,153 @@
#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
#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
......
......@@ -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",
......
......@@ -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 );
......
......@@ -7,6 +7,9 @@
#ifndef __WINE_SERVER_H
#define __WINE_SERVER_H
#include <stdlib.h>
#include <time.h>
/* 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 );
......
......@@ -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 */
......@@ -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 */
......
......@@ -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();
......
......@@ -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) {
......
......@@ -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);
}
......
......@@ -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 );
......
......@@ -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.
......
......@@ -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 */
......
......@@ -7,6 +7,7 @@ MODULE = server
C_SRCS = \
event.c \
file.c \
mutex.c \
object.c \
process.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 );
......
/*
* Server-side file management
*
* Copyright (C) 1998 Alexandre Julliard
*/
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#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;
}
......@@ -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 );
......
......@@ -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 );
......
......@@ -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) );
}
......@@ -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 );
......
......@@ -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<<EOF;
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] =
......@@ -59,9 +61,8 @@ foreach $req (@requests)
{
$request = $req . "_request";
$reply = $replies{$req} ? "dump_${req}_reply" : "0";
print TRACE " { (void(*)())dump_$request,\n";
print TRACE " (void(*)())$reply,\n";
print TRACE " sizeof(struct $request) },\n";
print TRACE " { (int(*)(void *,int))dump_$request,\n";
print TRACE " (void(*)())$reply },\n";
}
print TRACE <<EOF;
......@@ -82,13 +83,13 @@ print TRACE <<EOF;
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 );
......@@ -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";
}
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