Added beginnings of server-side file handling.
Added -debugmsg +server support. Better server request dumping for varargs requests.
This commit is contained in:
parent
6842064fd7
commit
338e757d08
|
@ -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 );
|
||||
|
|
213
files/file.c
213
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;
|
||||
int unix_handle;
|
||||
struct get_unix_handle_request req;
|
||||
|
||||
if (!(file = FILE_GetFile( hFile ))) return -1;
|
||||
ret = file->unix_handle;
|
||||
FILE_ReleaseFile( file );
|
||||
return ret;
|
||||
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;i<pdb->nbFiles;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 */
|
||||
|
||||
|
|
300
include/debug.h
300
include/debug.h
|
@ -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 );
|
||||
|
@ -315,6 +316,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
|
||||
*
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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 );
|
||||
|
|
249
server/trace.c
249
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 );
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue