Hacked server-side device support

Added user APCs support.
Many changes to the xterm console to make use of the server (not
finished yet).
Moved some other small stuff to the server.
This commit is contained in:
Alexandre Julliard 1999-01-19 17:48:23 +00:00
parent 9120c0ad3d
commit 62a8b43301
33 changed files with 1760 additions and 910 deletions

View File

@ -18,40 +18,12 @@
#include "server.h"
#include "debug.h"
static void CHANGE_Destroy( K32OBJ *obj );
const K32OBJ_OPS CHANGE_Ops =
{
CHANGE_Destroy /* destroy */
};
/* The change notification object */
typedef struct
{
K32OBJ header;
LPSTR lpPathName;
BOOL32 bWatchSubtree;
DWORD dwNotifyFilter;
BOOL32 notify;
} CHANGE_OBJECT;
/****************************************************************************
* CHANGE_Destroy
*/
static void CHANGE_Destroy( K32OBJ *obj )
{
CHANGE_OBJECT *change = (CHANGE_OBJECT *)obj;
assert( obj->type == K32OBJ_CHANGE );
if ( change->lpPathName )
{
HeapFree( SystemHeap, 0, change->lpPathName );
change->lpPathName = NULL;
}
obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, change );
}
/****************************************************************************
* FindFirstChangeNotification32A (KERNEL32.248)
@ -76,15 +48,8 @@ HANDLE32 WINAPI FindFirstChangeNotification32A( LPCSTR lpPathName,
CLIENT_CloseHandle( reply.handle );
return INVALID_HANDLE_VALUE32;
}
change->header.type = K32OBJ_CHANGE;
change->header.refcount = 1;
change->lpPathName = HEAP_strdupA( SystemHeap, 0, lpPathName );
change->bWatchSubtree = bWatchSubtree;
change->dwNotifyFilter = dwNotifyFilter;
change->notify = FALSE;
return HANDLE_Alloc( PROCESS_Current(), &change->header,
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE /*FIXME*/,
FALSE, reply.handle );
@ -109,20 +74,10 @@ HANDLE32 WINAPI FindFirstChangeNotification32W( LPCWSTR lpPathName,
*/
BOOL32 WINAPI FindNextChangeNotification( HANDLE32 handle )
{
CHANGE_OBJECT *change;
SYSTEM_LOCK();
if (!(change = (CHANGE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(),
handle, K32OBJ_CHANGE,
0 /*FIXME*/, NULL )) )
{
SYSTEM_UNLOCK();
if (HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_FILE, 0 ) == -1)
return FALSE;
}
change->notify = FALSE;
K32OBJ_DecCount( &change->header );
SYSTEM_UNLOCK();
/* FIXME: do something */
return TRUE;
}

View File

@ -26,6 +26,8 @@
#include "heap.h"
#include "msdos.h"
#include "syslevel.h"
#include "server.h"
#include "process.h"
#include "debug.h"
/* Define the VFAT ioctl to get both short and long file names */
@ -602,6 +604,30 @@ const DOS_DEVICE *DOSFS_GetDevice( const char *name )
return NULL;
}
/***********************************************************************
* DOSFS_GetDeviceByHandle
*/
const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE32 hFile )
{
struct get_file_info_request req;
struct get_file_info_reply reply;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hFile,
K32OBJ_FILE, 0 )) == -1)
return NULL;
CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) &&
(reply.type == FILE_TYPE_UNKNOWN))
{
if ((reply.attr >= 0) &&
(reply.attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0])))
return &DOSFS_Devices[reply.attr];
}
return NULL;
}
/***********************************************************************
* DOSFS_OpenDevice
*
@ -651,10 +677,7 @@ HFILE32 DOSFS_OpenDevice( const char *name, DWORD access )
if (!strcmp(DOSFS_Devices[i].name,"SCSIMGR$") ||
!strcmp(DOSFS_Devices[i].name,"HPSCAN"))
{
/* FIXME: should keep the name somewhere */
return FILE_CreateFile( "/dev/null", access,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, -1 );
return FILE_CreateDevice( i, access, NULL );
}
FIXME(dosfs,"device open %s not supported (yet)\n",DOSFS_Devices[i].name);
return HFILE_ERROR32;

View File

@ -46,74 +46,17 @@
#define MAP_ANON MAP_ANONYMOUS
#endif
static void FILE_Destroy( K32OBJ *obj );
const K32OBJ_OPS FILE_Ops =
/* The file object */
typedef struct
{
FILE_Destroy /* destroy */
};
K32OBJ header;
} FILE_OBJECT;
struct DOS_FILE_LOCK {
struct DOS_FILE_LOCK * next;
DWORD base;
DWORD len;
DWORD processId;
FILE_OBJECT * dos_file;
char * unix_name;
};
typedef struct DOS_FILE_LOCK DOS_FILE_LOCK;
static DOS_FILE_LOCK *locks = NULL;
static void DOS_RemoveFileLocks(FILE_OBJECT *file);
/* Size of per-process table of DOS handles */
#define DOS_TABLE_SIZE 256
/***********************************************************************
* FILE_Destroy
*
* Destroy a DOS file.
*/
static void FILE_Destroy( K32OBJ *ptr )
{
FILE_OBJECT *file = (FILE_OBJECT *)ptr;
assert( ptr->type == K32OBJ_FILE );
DOS_RemoveFileLocks(file);
if (file->unix_name) HeapFree( SystemHeap, 0, file->unix_name );
ptr->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, file );
}
/***********************************************************************
* FILE_GetFile
*
* 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, DWORD access, int *server_handle )
{
return (FILE_OBJECT *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
K32OBJ_FILE, access,
server_handle );
}
/***********************************************************************
* FILE_ReleaseFile
*
* Release a DOS file obtained with FILE_GetFile.
*/
void FILE_ReleaseFile( FILE_OBJECT *file )
{
K32OBJ_DecCount( &file->header );
}
/***********************************************************************
* FILE_ConvertOFMode
*
@ -391,7 +334,6 @@ HFILE32 FILE_DupUnixHandle( int fd, DWORD access )
}
file->header.type = K32OBJ_FILE;
file->header.refcount = 0;
file->unix_name = NULL;
return HANDLE_Alloc( PROCESS_Current(), &file->header, req.access,
req.inherit, reply.handle );
}
@ -448,7 +390,39 @@ HFILE32 FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
}
file->header.type = K32OBJ_FILE;
file->header.refcount = 0;
file->unix_name = HEAP_strdupA( SystemHeap, 0, filename );
return HANDLE_Alloc( PROCESS_Current(), &file->header, req.access,
req.inherit, reply.handle );
}
/***********************************************************************
* FILE_CreateDevice
*
* Same as FILE_CreateFile but for a device
*/
HFILE32 FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
FILE_OBJECT *file;
struct create_device_request req;
struct create_device_reply reply;
req.access = access;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
req.id = client_id;
CLIENT_SendRequest( REQ_CREATE_DEVICE, -1, 1, &req, sizeof(req) );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return INVALID_HANDLE_VALUE32;
/* Now build the FILE_OBJECT */
if (!(file = HeapAlloc( SystemHeap, 0, sizeof(FILE_OBJECT) )))
{
SetLastError( ERROR_OUTOFMEMORY );
CLIENT_CloseHandle( reply.handle );
return (HFILE32)INVALID_HANDLE_VALUE32;
}
file->header.type = K32OBJ_FILE;
file->header.refcount = 0;
return HANDLE_Alloc( PROCESS_Current(), &file->header, req.access,
req.inherit, reply.handle );
}
@ -487,7 +461,6 @@ HFILE32 WINAPI CreateFile32A( LPCSTR filename, DWORD access, DWORD sharing,
DWORD attributes, HANDLE32 template )
{
DOS_FULL_NAME full_name;
HANDLE32 to_dup = HFILE_ERROR32;
if (!filename)
{
@ -507,7 +480,8 @@ HFILE32 WINAPI CreateFile32A( LPCSTR filename, DWORD access, DWORD sharing,
}
}
if (!strncmp(filename, "\\\\.\\", 4)) return DEVICE_Open( filename+4 );
if (!strncmp(filename, "\\\\.\\", 4))
return DEVICE_Open( filename+4, access, sa );
/* If the name still starts with '\\', it's a UNC name. */
if (!strncmp(filename, "\\\\", 2))
@ -517,23 +491,9 @@ HFILE32 WINAPI CreateFile32A( LPCSTR filename, DWORD access, DWORD sharing,
return HFILE_ERROR32;
}
/* If the name is either CONIN$ or CONOUT$, give them duplicated stdin
* or stdout, respectively. The lower case version is also allowed. Most likely
* this should be a case ignore string compare.
*/
if(!strcasecmp(filename, "CONIN$"))
to_dup = GetStdHandle( STD_INPUT_HANDLE );
else if(!strcasecmp(filename, "CONOUT$"))
to_dup = GetStdHandle( STD_OUTPUT_HANDLE );
if(to_dup != HFILE_ERROR32)
{
HFILE32 handle;
if (!DuplicateHandle( GetCurrentProcess(), to_dup, GetCurrentProcess(),
&handle, access, FALSE, 0 ))
handle = HFILE_ERROR32;
return handle;
}
/* Open a console for CONIN$ or CONOUT$ */
if (!lstrcmpi32A(filename, "CONIN$")) return CONSOLE_OpenHandle( FALSE, access, sa );
if (!lstrcmpi32A(filename, "CONOUT$")) return CONSOLE_OpenHandle( TRUE, access, sa );
if (DOSFS_GetDevice( filename ))
{
@ -1979,6 +1939,64 @@ BOOL32 WINAPI SetFileTime( HFILE32 hFile,
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
/**************************************************************************
* LockFile (KERNEL32.511)
*/
BOOL32 WINAPI LockFile( HFILE32 hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh )
{
struct lock_file_request req;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hFile,
K32OBJ_FILE, 0 )) == -1)
return FALSE;
req.offset_low = dwFileOffsetLow;
req.offset_high = dwFileOffsetHigh;
req.count_low = nNumberOfBytesToLockLow;
req.count_high = nNumberOfBytesToLockHigh;
CLIENT_SendRequest( REQ_LOCK_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
/**************************************************************************
* UnlockFile (KERNEL32.703)
*/
BOOL32 WINAPI UnlockFile( HFILE32 hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh )
{
struct unlock_file_request req;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hFile,
K32OBJ_FILE, 0 )) == -1)
return FALSE;
req.offset_low = dwFileOffsetLow;
req.offset_high = dwFileOffsetHigh;
req.count_low = nNumberOfBytesToUnlockLow;
req.count_high = nNumberOfBytesToUnlockHigh;
CLIENT_SendRequest( REQ_UNLOCK_FILE, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
#if 0
struct DOS_FILE_LOCK {
struct DOS_FILE_LOCK * next;
DWORD base;
DWORD len;
DWORD processId;
FILE_OBJECT * dos_file;
/* char * unix_name;*/
};
typedef struct DOS_FILE_LOCK DOS_FILE_LOCK;
static DOS_FILE_LOCK *locks = NULL;
static void DOS_RemoveFileLocks(FILE_OBJECT *file);
/* Locks need to be mirrored because unix file locking is based
* on the pid. Inside of wine there can be multiple WINE processes
* that share the same unix pid.
@ -1994,6 +2012,7 @@ static BOOL32 DOS_AddLock(FILE_OBJECT *file, struct flock *f)
processId = GetCurrentProcessId();
/* check if lock overlaps a current lock for the same file */
#if 0
for (curr = locks; curr; curr = curr->next) {
if (strcmp(curr->unix_name, file->unix_name) == 0) {
if ((f->l_start == curr->base) && (f->l_len == curr->len))
@ -2005,12 +2024,13 @@ static BOOL32 DOS_AddLock(FILE_OBJECT *file, struct flock *f)
}
}
}
#endif
curr = HeapAlloc( SystemHeap, 0, sizeof(DOS_FILE_LOCK) );
curr->processId = GetCurrentProcessId();
curr->base = f->l_start;
curr->len = f->l_len;
curr->unix_name = HEAP_strdupA( SystemHeap, 0, file->unix_name);
/* curr->unix_name = HEAP_strdupA( SystemHeap, 0, file->unix_name);*/
curr->next = locks;
curr->dos_file = file;
locks = curr;
@ -2029,7 +2049,7 @@ static void DOS_RemoveFileLocks(FILE_OBJECT *file)
if ((*curr)->dos_file == file) {
rem = *curr;
*curr = (*curr)->next;
HeapFree( SystemHeap, 0, rem->unix_name );
/* HeapFree( SystemHeap, 0, rem->unix_name );*/
HeapFree( SystemHeap, 0, rem );
}
else
@ -2052,7 +2072,7 @@ static BOOL32 DOS_RemoveLock(FILE_OBJECT *file, struct flock *f)
/* this is the same lock */
rem = *curr;
*curr = (*curr)->next;
HeapFree( SystemHeap, 0, rem->unix_name );
/* HeapFree( SystemHeap, 0, rem->unix_name );*/
HeapFree( SystemHeap, 0, rem );
return TRUE;
}
@ -2151,6 +2171,7 @@ BOOL32 WINAPI UnlockFile(
#endif
return TRUE;
}
#endif
/**************************************************************************
* GetFileAttributesEx32A [KERNEL32.874]

View File

@ -1,4 +1,5 @@
#ifndef __WINE_DEVICE_H
#define __WINE_DEVICE_H
extern HANDLE32 DEVICE_Open( LPCSTR name);
extern HANDLE32 DEVICE_Open( LPCSTR filename, DWORD access,
LPSECURITY_ATTRIBUTES sa );
#endif

View File

@ -13,13 +13,6 @@
#define MAX_PATHNAME_LEN 1024
/* The file object */
typedef struct
{
K32OBJ header;
char *unix_name;
} FILE_OBJECT;
/* Definition of a full DOS file name */
typedef struct
{
@ -39,9 +32,6 @@ typedef struct
/* files/file.c */
extern FILE_OBJECT *FILE_GetFile( HFILE32 handle, DWORD access,
int *server_handle );
extern void FILE_ReleaseFile( FILE_OBJECT *file );
extern void FILE_SetDosError(void);
extern HFILE32 FILE_DupUnixHandle( int fd, DWORD access );
extern BOOL32 FILE_Stat( LPCSTR unixName, BY_HANDLE_FILE_INFORMATION *info );
@ -49,6 +39,8 @@ extern HFILE16 FILE_Dup2( HFILE16 hFile1, HFILE16 hFile2 );
extern HFILE32 FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE32 template );
extern HFILE32 FILE_CreateDevice( int client_id, DWORD access,
LPSECURITY_ATTRIBUTES sa );
extern LPVOID FILE_dommap( int unix_handle, LPVOID start,
DWORD size_high, DWORD size_low,
DWORD offset_high, DWORD offset_low,
@ -71,6 +63,7 @@ extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft,
extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder );
extern BOOL32 DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer );
extern const DOS_DEVICE *DOSFS_GetDevice( const char *name );
extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE32 hFile );
extern HFILE32 DOSFS_OpenDevice( const char *name, DWORD access );
extern BOOL32 DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf,
INT32 long_len, LPSTR short_buf,

View File

@ -139,8 +139,6 @@ extern K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
int *server_handle );
extern int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
K32OBJ_TYPE type, DWORD access );
extern BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle,
K32OBJ *ptr, DWORD access );
extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr );
/* Global handle macros */
@ -153,6 +151,7 @@ extern void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *ptr );
/* scheduler/process.c */
extern BOOL32 PROCESS_Init( void );
extern PDB32 *PROCESS_Current(void);
extern BOOL32 PROCESS_IsCurrent( HANDLE32 handle );
extern PDB32 *PROCESS_Initial(void);
extern PDB32 *PROCESS_GetPtr( HANDLE32 handle, DWORD access, int *server_handle );
extern PDB32 *PROCESS_IdToPDB( DWORD id );

View File

@ -92,11 +92,26 @@ struct get_process_info_request
};
struct get_process_info_reply
{
void* pid; /* server process id */
int exit_code; /* process exit code */
void* pid; /* server process id */
int exit_code; /* process exit code */
int priority; /* priority class */
int process_affinity; /* process affinity mask */
int system_affinity; /* system affinity mask */
};
/* Set a process informations */
struct set_process_info_request
{
int handle; /* process handle */
int mask; /* setting mask (see below) */
int priority; /* priority class */
int affinity; /* affinity mask */
};
#define SET_PROCESS_INFO_PRIORITY 0x01
#define SET_PROCESS_INFO_AFFINITY 0x02
/* Retrieve information about a thread */
struct get_thread_info_request
{
@ -106,6 +121,50 @@ struct get_thread_info_reply
{
void* pid; /* server thread id */
int exit_code; /* thread exit code */
int priority; /* thread priority level */
};
/* Set a thread informations */
struct set_thread_info_request
{
int handle; /* thread handle */
int mask; /* setting mask (see below) */
int priority; /* priority class */
int affinity; /* affinity mask */
};
#define SET_THREAD_INFO_PRIORITY 0x01
#define SET_THREAD_INFO_AFFINITY 0x02
/* Suspend a thread */
struct suspend_thread_request
{
int handle; /* thread handle */
};
struct suspend_thread_reply
{
int count; /* new suspend count */
};
/* Resume a thread */
struct resume_thread_request
{
int handle; /* thread handle */
};
struct resume_thread_reply
{
int count; /* new suspend count */
};
/* Queue an APC for a thread */
struct queue_apc_request
{
int handle; /* thread handle */
void* func; /* function to call */
void* param; /* param for function to call */
};
@ -160,6 +219,7 @@ struct select_request
struct select_reply
{
int signaled; /* signaled handle */
/* void* apcs[]; */ /* async procedures to call */
};
#define SELECT_ALL 1
#define SELECT_ALERTABLE 2
@ -338,6 +398,28 @@ struct get_file_info_reply
};
/* Lock a region of a file */
struct lock_file_request
{
int handle; /* handle to the file */
unsigned int offset_low; /* offset of start of lock */
unsigned int offset_high; /* offset of start of lock */
unsigned int count_low; /* count of bytes to lock */
unsigned int count_high; /* count of bytes to lock */
};
/* Unlock a region of a file */
struct unlock_file_request
{
int handle; /* handle to the file */
unsigned int offset_low; /* offset of start of unlock */
unsigned int offset_high; /* offset of start of unlock */
unsigned int count_low; /* count of bytes to unlock */
unsigned int count_high; /* count of bytes to unlock */
};
/* Create an anonymous pipe */
struct create_pipe_request
{
@ -350,15 +432,28 @@ struct create_pipe_reply
};
/* Create a console */
struct create_console_request
/* Allocate a console for the current process */
struct alloc_console_request
{
};
/* Free the console of the current process */
struct free_console_request
{
};
/* Open a handle to the process console */
struct open_console_request
{
int output; /* input or output? */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
};
struct create_console_reply
struct open_console_reply
{
int handle_read; /* handle to read from the console */
int handle_write; /* handle to write to the console */
int handle; /* handle to the console */
};
@ -366,6 +461,52 @@ struct create_console_reply
struct set_console_fd_request
{
int handle; /* handle to the console */
int pid; /* pid of xterm (hack) */
};
/* Get a console mode (input or output) */
struct get_console_mode_request
{
int handle; /* handle to the console */
};
struct get_console_mode_reply
{
int mode; /* console mode */
};
/* Set a console mode (input or output) */
struct set_console_mode_request
{
int handle; /* handle to the console */
int mode; /* console mode */
};
/* Set info about a console (output only) */
struct set_console_info_request
{
int handle; /* handle to the console */
int mask; /* setting mask (see below) */
int cursor_size; /* size of cursor (percentage filled) */
int cursor_visible;/* cursor visibility flag */
char title[0]; /* console title */
};
#define SET_CONSOLE_INFO_CURSOR 0x01
#define SET_CONSOLE_INFO_TITLE 0x02
/* Get info about a console (output only) */
struct get_console_info_request
{
int handle; /* handle to the console */
};
struct get_console_info_reply
{
int cursor_size; /* size of cursor (percentage filled) */
int cursor_visible;/* cursor visibility flag */
int pid; /* pid of xterm (hack) */
/* char title[0]; */ /* console title */
};
@ -417,6 +558,19 @@ struct get_mapping_info_reply
};
/* Create a device */
struct create_device_request
{
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
int id; /* client private id */
};
struct create_device_reply
{
int handle; /* handle to the device */
};
/* client-side functions */
#ifndef __WINE_SERVER__
@ -438,7 +592,6 @@ extern int CLIENT_CloseHandle( int handle );
extern int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process,
int dst_handle, DWORD access, BOOL32 inherit, DWORD options );
extern int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit );
extern int CLIENT_Select( int count, int *handles, int flags, int timeout );
#endif /* __WINE_SERVER__ */
#endif /* __WINE_SERVER_H */

View File

@ -133,6 +133,11 @@ extern void remove_process_thread( struct process *process,
extern void kill_process( struct process *process, int exit_code );
extern void get_process_info( struct process *process,
struct get_process_info_reply *reply );
extern void set_process_info( struct process *process,
struct set_process_info_request *req );
extern int alloc_console( struct process *process );
extern int free_console( struct process *process );
extern struct object *get_console( struct process *process, int output );
/* handle functions */
@ -184,6 +189,10 @@ extern int file_get_mmap_fd( struct file *file );
extern int set_file_pointer( int handle, int *low, int *high, int whence );
extern int truncate_file( int handle );
extern int set_file_time( int handle, time_t access_time, time_t write_time );
extern int file_lock( struct file *file, int offset_high, int offset_low,
int count_high, int count_low );
extern int file_unlock( struct file *file, int offset_high, int offset_low,
int count_high, int count_low );
extern void file_set_error(void);
@ -195,7 +204,13 @@ extern int create_pipe( struct object *obj[2] );
/* console functions */
extern int create_console( int fd, struct object *obj[2] );
extern int set_console_fd( int handle, int fd );
extern int set_console_fd( int handle, int fd, int pid );
extern int get_console_mode( int handle, int *mode );
extern int set_console_mode( int handle, int mode );
extern int set_console_info( int handle, struct set_console_info_request *req,
const char *title );
extern int get_console_info( int handle, struct get_console_info_reply *reply,
const char **title );
/* change notification functions */
@ -210,6 +225,10 @@ extern int open_mapping( unsigned int access, int inherit, const char *name );
extern int get_mapping_info( int handle, struct get_mapping_info_reply *reply );
/* device functions */
extern struct object *create_device( int id );
extern int debug_level;
#endif /* __WINE_SERVER_OBJECT_H */

View File

@ -11,7 +11,12 @@ enum request
REQ_TERMINATE_PROCESS,
REQ_TERMINATE_THREAD,
REQ_GET_PROCESS_INFO,
REQ_SET_PROCESS_INFO,
REQ_GET_THREAD_INFO,
REQ_SET_THREAD_INFO,
REQ_SUSPEND_THREAD,
REQ_RESUME_THREAD,
REQ_QUEUE_APC,
REQ_CLOSE_HANDLE,
REQ_DUP_HANDLE,
REQ_OPEN_PROCESS,
@ -31,12 +36,21 @@ enum request
REQ_SET_FILE_TIME,
REQ_FLUSH_FILE,
REQ_GET_FILE_INFO,
REQ_LOCK_FILE,
REQ_UNLOCK_FILE,
REQ_CREATE_PIPE,
REQ_CREATE_CONSOLE,
REQ_ALLOC_CONSOLE,
REQ_FREE_CONSOLE,
REQ_OPEN_CONSOLE,
REQ_SET_CONSOLE_FD,
REQ_GET_CONSOLE_MODE,
REQ_SET_CONSOLE_MODE,
REQ_SET_CONSOLE_INFO,
REQ_GET_CONSOLE_INFO,
REQ_CREATE_CHANGE_NOTIFICATION,
REQ_CREATE_MAPPING,
REQ_GET_MAPPING_INFO,
REQ_CREATE_DEVICE,
REQ_NB_REQUESTS
};
@ -51,7 +65,12 @@ DECL_HANDLER(init_thread);
DECL_HANDLER(terminate_process);
DECL_HANDLER(terminate_thread);
DECL_HANDLER(get_process_info);
DECL_HANDLER(set_process_info);
DECL_HANDLER(get_thread_info);
DECL_HANDLER(set_thread_info);
DECL_HANDLER(suspend_thread);
DECL_HANDLER(resume_thread);
DECL_HANDLER(queue_apc);
DECL_HANDLER(close_handle);
DECL_HANDLER(dup_handle);
DECL_HANDLER(open_process);
@ -71,12 +90,21 @@ DECL_HANDLER(truncate_file);
DECL_HANDLER(set_file_time);
DECL_HANDLER(flush_file);
DECL_HANDLER(get_file_info);
DECL_HANDLER(lock_file);
DECL_HANDLER(unlock_file);
DECL_HANDLER(create_pipe);
DECL_HANDLER(create_console);
DECL_HANDLER(alloc_console);
DECL_HANDLER(free_console);
DECL_HANDLER(open_console);
DECL_HANDLER(set_console_fd);
DECL_HANDLER(get_console_mode);
DECL_HANDLER(set_console_mode);
DECL_HANDLER(set_console_info);
DECL_HANDLER(get_console_info);
DECL_HANDLER(create_change_notification);
DECL_HANDLER(create_mapping);
DECL_HANDLER(get_mapping_info);
DECL_HANDLER(create_device);
static const struct handler {
void (*handler)();
@ -88,7 +116,12 @@ static const struct handler {
{ (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },
{ (void(*)())req_terminate_thread, sizeof(struct terminate_thread_request) },
{ (void(*)())req_get_process_info, sizeof(struct get_process_info_request) },
{ (void(*)())req_set_process_info, sizeof(struct set_process_info_request) },
{ (void(*)())req_get_thread_info, sizeof(struct get_thread_info_request) },
{ (void(*)())req_set_thread_info, sizeof(struct set_thread_info_request) },
{ (void(*)())req_suspend_thread, sizeof(struct suspend_thread_request) },
{ (void(*)())req_resume_thread, sizeof(struct resume_thread_request) },
{ (void(*)())req_queue_apc, sizeof(struct queue_apc_request) },
{ (void(*)())req_close_handle, sizeof(struct close_handle_request) },
{ (void(*)())req_dup_handle, sizeof(struct dup_handle_request) },
{ (void(*)())req_open_process, sizeof(struct open_process_request) },
@ -108,12 +141,21 @@ static const struct handler {
{ (void(*)())req_set_file_time, sizeof(struct set_file_time_request) },
{ (void(*)())req_flush_file, sizeof(struct flush_file_request) },
{ (void(*)())req_get_file_info, sizeof(struct get_file_info_request) },
{ (void(*)())req_lock_file, sizeof(struct lock_file_request) },
{ (void(*)())req_unlock_file, sizeof(struct unlock_file_request) },
{ (void(*)())req_create_pipe, sizeof(struct create_pipe_request) },
{ (void(*)())req_create_console, sizeof(struct create_console_request) },
{ (void(*)())req_alloc_console, sizeof(struct alloc_console_request) },
{ (void(*)())req_free_console, sizeof(struct free_console_request) },
{ (void(*)())req_open_console, sizeof(struct open_console_request) },
{ (void(*)())req_set_console_fd, sizeof(struct set_console_fd_request) },
{ (void(*)())req_get_console_mode, sizeof(struct get_console_mode_request) },
{ (void(*)())req_set_console_mode, sizeof(struct set_console_mode_request) },
{ (void(*)())req_set_console_info, sizeof(struct set_console_info_request) },
{ (void(*)())req_get_console_info, sizeof(struct get_console_info_request) },
{ (void(*)())req_create_change_notification, sizeof(struct create_change_notification_request) },
{ (void(*)())req_create_mapping, sizeof(struct create_mapping_request) },
{ (void(*)())req_get_mapping_info, sizeof(struct get_mapping_info_request) },
{ (void(*)())req_create_device, sizeof(struct create_device_request) },
};
#endif /* WANT_REQUEST_HANDLERS */

View File

@ -17,6 +17,7 @@
struct process;
struct thread_wait;
struct thread_apc;
struct mutex;
enum run_state { STARTING, RUNNING, TERMINATED };
@ -31,11 +32,16 @@ struct thread
struct process *process;
struct mutex *mutex; /* list of currently owned mutexes */
struct thread_wait *wait; /* current wait condition if sleeping */
struct thread_apc *apc; /* list of async procedure calls */
int apc_count; /* number of outstanding APCs */
int error; /* current error code */
enum run_state state; /* running state */
int exit_code; /* thread exit code */
int client_fd; /* client fd for socket communications */
int unix_pid; /* Unix pid of client */
int priority; /* priority level */
int affinity; /* affinity mask */
int suspend; /* suspend count */
enum request last_req; /* last request received (for debugging) */
char *name;
};
@ -50,10 +56,15 @@ extern struct thread *get_thread_from_id( void *id );
extern struct thread *get_thread_from_handle( int handle, unsigned int access );
extern void get_thread_info( struct thread *thread,
struct get_thread_info_reply *reply );
extern void set_thread_info( struct thread *thread,
struct set_thread_info_request *req );
extern int suspend_thread( struct thread *thread );
extern int resume_thread( struct thread *thread );
extern int send_reply( struct thread *thread, int pass_fd,
int n, ... /* arg_1, len_1, ..., arg_n, len_n */ );
extern int add_queue( struct object *obj, struct wait_queue_entry *entry );
extern void remove_queue( struct object *obj, struct wait_queue_entry *entry );
extern int thread_queue_apc( struct thread *thread, void *func, void *param );
extern void kill_thread( struct thread *thread, int exit_code );
extern void thread_killed( struct thread *thread, int exit_code );
extern void thread_timeout(void);

View File

@ -61,7 +61,6 @@ typedef struct _TEB
typedef struct
{
DWORD count; /* Count of valid objects */
DWORD signaled; /* Index of signaled object (or WAIT_FAILED)*/
BOOL32 wait_all; /* Wait for all objects flag */
K32OBJ *objs[MAXIMUM_WAIT_OBJECTS]; /* Object pointers */
int server[MAXIMUM_WAIT_OBJECTS]; /* Server handles */
@ -110,8 +109,7 @@ typedef struct _THDB
CRITICAL_SECTION *sys_mutex[4];/* 1e8 Syslevel mutex pointers */
DWORD unknown6[2]; /* 1f8 Unknown */
/* The following are Wine-specific fields */
CONTEXT context; /* 200 Thread context */
WAIT_STRUCT wait_struct; /* Event wait structure */
WAIT_STRUCT wait_struct; /* 200 Event wait structure */
int socket; /* Socket for server communication */
unsigned int seq; /* Server sequence number */
void *server_tid; /* Server id for this thread */
@ -155,7 +153,6 @@ extern THDB *THREAD_Current(void);
extern BOOL32 THREAD_IsWin16( THDB *thdb );
extern THDB *THREAD_IdToTHDB( DWORD id );
extern void THREAD_Start( THDB *thdb );
extern THDB *THREAD_GetPtr( HANDLE32 handle, DWORD access, int *server_handle );
extern void THREAD_AddQueue( THREAD_QUEUE *queue, THDB *thread );
extern void THREAD_RemoveQueue( THREAD_QUEUE *queue, THDB *thread );
extern DWORD THREAD_TlsAlloc( THDB *thread );

View File

@ -273,6 +273,8 @@ typedef struct tagCOMMTIMEOUTS {
#pragma pack(4)
typedef VOID (CALLBACK *PAPCFUNC)(ULONG_PTR);
BOOL32 WINAPI ClearCommError(INT32,LPDWORD,LPCOMSTAT);
BOOL32 WINAPI BuildCommDCB32A(LPCSTR,LPDCB32);
BOOL32 WINAPI BuildCommDCB32W(LPCWSTR,LPDCB32);
@ -305,8 +307,9 @@ void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit);
void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit);
HANDLE32 WINAPI OpenProcess(DWORD access, BOOL32 inherit, DWORD id);
BOOL32 WINAPI GetProcessWorkingSetSize(HANDLE32,LPDWORD,LPDWORD);
BOOL32 WINAPI SetProcessWorkingSetSize(HANDLE32,DWORD,DWORD);
DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE32,ULONG_PTR);
void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD);
BOOL32 WINAPI SetProcessWorkingSetSize(HANDLE32,DWORD,DWORD);
BOOL32 WINAPI TerminateProcess(HANDLE32,DWORD);
BOOL32 WINAPI TerminateThread(HANDLE32,DWORD);

View File

@ -4186,6 +4186,7 @@ BOOL32 WINAPI SetPriorityClass(HANDLE32,DWORD);
BOOL32 WINAPI SetStdHandle(DWORD,HANDLE32);
BOOL32 WINAPI SetSystemPowerState(BOOL32,BOOL32);
BOOL32 WINAPI SetSystemTime(const SYSTEMTIME*);
DWORD WINAPI SetThreadAffinityMask(HANDLE32,DWORD);
BOOL32 WINAPI SetThreadPriority(HANDLE32,INT32);
BOOL32 WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
VOID WINAPI Sleep(DWORD);

View File

@ -89,6 +89,8 @@ typedef unsigned short WCHAR;
typedef unsigned short BOOL16;
typedef int BOOL32;
typedef double DATE;
typedef long LONG_PTR;
typedef unsigned long ULONG_PTR;
#ifdef __i386__
typedef double LONGLONG;
typedef double ULONGLONG;

View File

@ -31,7 +31,7 @@
typedef struct
{
K32OBJ header;
FILE_OBJECT *file;
K32OBJ *file;
} FILE_MAPPING;
/* File view */
@ -810,20 +810,12 @@ BOOL32 WINAPI VirtualProtectEx(
LPVOID addr, /* [in] Address of region of committed pages */
DWORD size, /* [in] Size of region */
DWORD new_prot, /* [in] Desired access protection */
LPDWORD old_prot /* [out] Address of variable to get old protection */
) {
BOOL32 ret = FALSE;
PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_VM_OPERATION, NULL );
if (pdb)
{
if (pdb == PROCESS_Current())
ret = VirtualProtect( addr, size, new_prot, old_prot );
else
ERR(virtual,"Unsupported on other process\n");
K32OBJ_DecCount( &pdb->header );
}
return ret;
LPDWORD old_prot /* [out] Address of variable to get old protection */ )
{
if (PROCESS_IsCurrent( handle ))
return VirtualProtect( addr, size, new_prot, old_prot );
ERR(virtual,"Unsupported on other process\n");
return FALSE;
}
@ -907,20 +899,12 @@ DWORD WINAPI VirtualQueryEx(
HANDLE32 handle, /* [in] Handle of process */
LPCVOID addr, /* [in] Address of region */
LPMEMORY_BASIC_INFORMATION info, /* [out] Address of info buffer */
DWORD len /* [in] Size of buffer */
) {
DWORD ret = len;
PDB32 *pdb = PROCESS_GetPtr( handle, PROCESS_QUERY_INFORMATION, NULL );
if (pdb)
{
if (pdb == PROCESS_Current())
ret = VirtualQuery( addr, info, len );
else
ERR(virtual,"Unsupported on other process\n");
K32OBJ_DecCount( &pdb->header );
}
return ret;
DWORD len /* [in] Size of buffer */ )
{
if (PROCESS_IsCurrent( handle ))
return VirtualQuery( addr, info, len );
ERR(virtual,"Unsupported on other process\n");
return 0;
}
@ -1079,7 +1063,7 @@ HANDLE32 WINAPI CreateFileMapping32A(
LPCSTR name /* [in] Name of file-mapping object */ )
{
FILE_MAPPING *mapping = NULL;
FILE_OBJECT *file;
K32OBJ *file;
struct create_mapping_request req;
struct create_mapping_reply reply = { -1 };
HANDLE32 handle;
@ -1172,7 +1156,9 @@ HANDLE32 WINAPI CreateFileMapping32A(
((protect & 0xff) == PAGE_EXECUTE_READWRITE) ||
((protect & 0xff) == PAGE_EXECUTE_WRITECOPY))
access |= GENERIC_WRITE;
if (!(file = FILE_GetFile( hFile, access, &req.handle ))) goto error;
if (!(file = HANDLE_GetObjPtr( PROCESS_Current(), hFile, K32OBJ_FILE,
access, &req.handle ))) goto error;
if (!GetFileInformationByHandle( hFile, &info )) goto error;
if (!size_high && !size_low)
{
@ -1218,7 +1204,7 @@ HANDLE32 WINAPI CreateFileMapping32A(
error:
if (reply.handle != -1) CLIENT_CloseHandle( reply.handle );
if (file) K32OBJ_DecCount( &file->header );
if (file) K32OBJ_DecCount( file );
if (mapping) HeapFree( SystemHeap, 0, mapping );
return 0;
}
@ -1305,7 +1291,7 @@ static void VIRTUAL_DestroyMapping( K32OBJ *ptr )
FILE_MAPPING *mapping = (FILE_MAPPING *)ptr;
assert( ptr->type == K32OBJ_MEM_MAPPED_FILE );
if (mapping->file) K32OBJ_DecCount( &mapping->file->header );
if (mapping->file) K32OBJ_DecCount( mapping->file );
ptr->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, mapping );
}
@ -1347,7 +1333,6 @@ LPVOID WINAPI MapViewOfFileEx(
DWORD count, /* [in] Number of bytes to map */
LPVOID addr /* [in] Suggested starting address for mapped view */
) {
FILE_MAPPING *mapping;
FILE_VIEW *view;
UINT32 ptr = (UINT32)-1, size = 0;
int flags = MAP_PRIVATE;
@ -1364,12 +1349,8 @@ LPVOID WINAPI MapViewOfFileEx(
return NULL;
}
if (!(mapping = (FILE_MAPPING *)HANDLE_GetObjPtr( PROCESS_Current(),
handle,
K32OBJ_MEM_MAPPED_FILE,
0 /* FIXME */, &req.handle )))
return NULL;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_MEM_MAPPED_FILE, 0 /* FIXME */ );
CLIENT_SendRequest( REQ_GET_MAPPING_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &info, sizeof(info), &unix_handle ))
goto error;
@ -1438,13 +1419,11 @@ LPVOID WINAPI MapViewOfFileEx(
goto error;
}
if (unix_handle != -1) close( unix_handle );
K32OBJ_DecCount( &mapping->header );
return (LPVOID)ptr;
error:
if (unix_handle != -1) close( unix_handle );
if (ptr != (UINT32)-1) FILE_munmap( (void *)ptr, 0, size );
K32OBJ_DecCount( &mapping->header );
return NULL;
}

View File

@ -218,22 +218,17 @@ static void GetDrivePB( CONTEXT *context, int drive )
static void ioctlGetDeviceInfo( CONTEXT *context )
{
int curr_drive;
FILE_OBJECT *file;
const DOS_DEVICE *dev;
TRACE(int21, "(%d)\n", BX_reg(context));
RESET_CFLAG(context);
/* DOS device ? */
if ((file = FILE_GetFile( FILE_GetHandle32(BX_reg(context)), 0, NULL )))
if ((dev = DOSFS_GetDeviceByHandle( FILE_GetHandle32(BX_reg(context)) )))
{
const DOS_DEVICE *dev = DOSFS_GetDevice( file->unix_name );
FILE_ReleaseFile( file );
if (dev)
{
DX_reg(context) = dev->flags;
return;
}
DX_reg(context) = dev->flags;
return;
}
/* it seems to be a file */
@ -1559,12 +1554,13 @@ void WINAPI DOS3Call( CONTEXT *context )
case 0x01:
break;
case 0x02:{
FILE_OBJECT *file;
file = FILE_GetFile(FILE_GetHandle32(BX_reg(context)),0,NULL);
if (!strcasecmp(file->unix_name, "SCSIMGR$"))
ASPI_DOS_HandleInt(context);
FILE_ReleaseFile( file );
break;
const DOS_DEVICE *dev;
if ((dev = DOSFS_GetDeviceByHandle( FILE_GetHandle32(BX_reg(context)) )) &&
!strcasecmp( dev->name, "SCSIMGR$" ))
{
ASPI_DOS_HandleInt(context);
}
break;
}
case 0x05:{ /* IOCTL - WRITE TO BLOCK DEVICE CONTROL CHANNEL */
/*BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, DS_reg(context),EDX_reg(context));*/

View File

@ -1123,12 +1123,13 @@ void VXD_Win32s( CONTEXT *context )
{
DWORD *stack = (DWORD *)W32S_APP2WINE(EDX_reg(context), W32S_OFFSET);
HANDLE32 handle = stack[0];
HANDLE32 new_handle;
TRACE(vxd, "NtDupSection(%lx)\n", (DWORD)handle);
/* Handle is 'duplicated' by incrementing RefCount */
HANDLE_GetObjPtr(PROCESS_Current(), handle, K32OBJ_MEM_MAPPED_FILE, 0,NULL);
DuplicateHandle( GetCurrentProcess(), handle,
GetCurrentProcess(), &new_handle,
0, FALSE, DUPLICATE_SAME_ACCESS );
EAX_reg(context) = STATUS_SUCCESS;
}
break;

View File

@ -581,7 +581,7 @@ init MAIN_KernelInit
563 stub QueryOldestEventLogRecord
564 stdcall QueryPerformanceCounter(ptr) QueryPerformanceCounter
565 stdcall QueryPerformanceFrequency(ptr) QueryPerformanceFrequency
566 stub QueueUserAPC
566 stdcall QueueUserAPC(ptr long long) QueueUserAPC
567 register RaiseException() RaiseException
568 stdcall ReadConsoleA(long ptr long ptr ptr) ReadConsole32A
569 stdcall ReadConsoleInputA(long ptr long ptr) ReadConsoleInput32A

View File

@ -6,6 +6,7 @@
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
@ -267,7 +268,7 @@ int CLIENT_NewThread( THDB *thdb, int *thandle, int *phandle )
case 0: /* child */
close( tmpfd[0] );
sprintf( buffer, "%d", tmpfd[1] );
/*#define EXEC_SERVER*/
#define EXEC_SERVER
#ifdef EXEC_SERVER
execlp( "wineserver", "wineserver", buffer, NULL );
execl( "/usr/local/bin/wineserver", "wineserver", buffer, NULL );
@ -299,6 +300,7 @@ int CLIENT_NewThread( THDB *thdb, int *thandle, int *phandle )
if (thdb->socket != -1) close( thdb->socket );
thdb->socket = fd[0];
thdb->seq = 0; /* reset the sequence number for the new fd */
fcntl( fd[0], F_SETFD, 1 ); /* set close on exec flag */
if (thandle) *thandle = reply.thandle;
else if (reply.thandle != -1) CLIENT_CloseHandle( reply.thandle );
@ -365,7 +367,6 @@ int CLIENT_DuplicateHandle( int src_process, int src_handle, int dst_process, in
{
struct dup_handle_request req;
struct dup_handle_reply reply;
int len;
req.src_process = src_process;
req.src_handle = src_handle;
@ -399,24 +400,3 @@ int CLIENT_OpenProcess( void *pid, DWORD access, BOOL32 inherit )
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
return reply.handle;
}
/***********************************************************************
* CLIENT_Select
*/
int CLIENT_Select( int count, int *handles, int flags, int timeout )
{
struct select_request req;
struct select_reply reply;
int len;
req.count = count;
req.flags = flags;
req.timeout = timeout;
CLIENT_SendRequest( REQ_SELECT, -1, 2,
&req, sizeof(req),
handles, count * sizeof(int) );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
return reply.signaled;
}

View File

@ -212,34 +212,6 @@ int HANDLE_GetServerHandle( PDB32 *pdb, HANDLE32 handle,
}
/***********************************************************************
* HANDLE_SetObjPtr
*
* Change the object pointer of a handle, and increment the refcount.
* Use with caution!
*/
BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ *ptr,
DWORD access )
{
BOOL32 ret = FALSE;
SYSTEM_LOCK();
if ((handle > 0) && (handle < pdb->handle_table->count))
{
HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
K32OBJ *old_ptr = entry->ptr;
K32OBJ_IncCount( ptr );
entry->access = access;
entry->ptr = ptr;
if (old_ptr) K32OBJ_DecCount( old_ptr );
ret = TRUE;
}
SYSTEM_UNLOCK();
if (!ret) SetLastError( ERROR_INVALID_HANDLE );
return ret;
}
/*********************************************************************
* HANDLE_GetAccess
*/

View File

@ -15,10 +15,7 @@
/* The declarations are here to avoid including a lot of unnecessary files */
extern const K32OBJ_OPS PROCESS_Ops;
extern const K32OBJ_OPS THREAD_Ops;
extern const K32OBJ_OPS FILE_Ops;
extern const K32OBJ_OPS CHANGE_Ops;
extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
extern const K32OBJ_OPS DEVICE_Ops;
extern const K32OBJ_OPS CONSOLE_Ops;
extern const K32OBJ_OPS SNAPSHOT_Ops;
@ -44,13 +41,13 @@ const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
&K32OBJ_NullOps, /* K32OBJ_CRITICAL_SECTION */
&PROCESS_Ops, /* K32OBJ_PROCESS */
&THREAD_Ops, /* K32OBJ_THREAD */
&FILE_Ops, /* K32OBJ_FILE */
&CHANGE_Ops, /* K32OBJ_CHANGE */
&K32OBJ_DefaultOps, /* K32OBJ_FILE */
&K32OBJ_DefaultOps, /* K32OBJ_CHANGE */
&CONSOLE_Ops, /* K32OBJ_CONSOLE */
&K32OBJ_NullOps, /* K32OBJ_SCREEN_BUFFER */
&MEM_MAPPED_FILE_Ops, /* K32OBJ_MEM_MAPPED_FILE */
&K32OBJ_NullOps, /* K32OBJ_SERIAL */
&DEVICE_Ops, /* K32OBJ_DEVICE_IOCTL */
&K32OBJ_NullOps, /* K32OBJ_DEVICE_IOCTL */
&K32OBJ_DefaultOps, /* K32OBJ_PIPE */
&K32OBJ_NullOps, /* K32OBJ_MAILSLOT */
&K32OBJ_NullOps, /* K32OBJ_TOOLHELP_SNAPSHOT */

View File

@ -66,6 +66,33 @@ PDB32 *PROCESS_GetPtr( HANDLE32 handle, DWORD access, int *server_handle )
K32OBJ_PROCESS, access, server_handle );
}
/***********************************************************************
* PROCESS_QueryInfo
*
* Retrieve information about a process
*/
static BOOL32 PROCESS_QueryInfo( HANDLE32 handle,
struct get_process_info_reply *reply )
{
struct get_process_info_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_PROCESS, PROCESS_QUERY_INFORMATION );
CLIENT_SendRequest( REQ_GET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitSimpleReply( reply, sizeof(*reply), NULL );
}
/***********************************************************************
* PROCESS_IsCurrent
*
* Check if a handle is to the current process
*/
BOOL32 PROCESS_IsCurrent( HANDLE32 handle )
{
struct get_process_info_reply reply;
return (PROCESS_QueryInfo( handle, &reply ) &&
(reply.pid == PROCESS_Current()->server_pid));
}
/***********************************************************************
* PROCESS_IdToPDB
@ -599,28 +626,14 @@ LCID WINAPI GetThreadLocale(void)
*/
BOOL32 WINAPI SetPriorityClass( HANDLE32 hprocess, DWORD priorityclass )
{
PDB32 *pdb = PROCESS_GetPtr( hprocess, PROCESS_SET_INFORMATION, NULL );
if (!pdb) return FALSE;
switch (priorityclass)
{
case NORMAL_PRIORITY_CLASS:
pdb->priority = 0x00000008;
break;
case IDLE_PRIORITY_CLASS:
pdb->priority = 0x00000004;
break;
case HIGH_PRIORITY_CLASS:
pdb->priority = 0x0000000d;
break;
case REALTIME_PRIORITY_CLASS:
pdb->priority = 0x00000018;
break;
default:
WARN(process,"Unknown priority class %ld\n",priorityclass);
break;
}
K32OBJ_DecCount( &pdb->header );
return TRUE;
struct set_process_info_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hprocess,
K32OBJ_PROCESS, PROCESS_SET_INFORMATION );
if (req.handle == -1) return FALSE;
req.priority = priorityclass;
req.mask = SET_PROCESS_INFO_PRIORITY;
CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
@ -629,30 +642,39 @@ BOOL32 WINAPI SetPriorityClass( HANDLE32 hprocess, DWORD priorityclass )
*/
DWORD WINAPI GetPriorityClass(HANDLE32 hprocess)
{
PDB32 *pdb = PROCESS_GetPtr( hprocess, PROCESS_QUERY_INFORMATION, NULL );
DWORD ret = 0;
if (pdb)
{
switch (pdb->priority)
{
case 0x00000008:
ret = NORMAL_PRIORITY_CLASS;
break;
case 0x00000004:
ret = IDLE_PRIORITY_CLASS;
break;
case 0x0000000d:
ret = HIGH_PRIORITY_CLASS;
break;
case 0x00000018:
ret = REALTIME_PRIORITY_CLASS;
break;
default:
WARN(process,"Unknown priority %ld\n",pdb->priority);
}
K32OBJ_DecCount( &pdb->header );
}
return ret;
struct get_process_info_reply reply;
if (!PROCESS_QueryInfo( hprocess, &reply )) return 0;
return reply.priority;
}
/***********************************************************************
* SetProcessAffinityMask (KERNEL32.662)
*/
BOOL32 WINAPI SetProcessAffinityMask( HANDLE32 hProcess, DWORD affmask )
{
struct set_process_info_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hProcess,
K32OBJ_PROCESS, PROCESS_SET_INFORMATION );
if (req.handle == -1) return FALSE;
req.affinity = affmask;
req.mask = SET_PROCESS_INFO_AFFINITY;
CLIENT_SendRequest( REQ_SET_PROCESS_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
/**********************************************************************
* GetProcessAffinityMask (KERNEL32.373)
*/
BOOL32 WINAPI GetProcessAffinityMask( HANDLE32 hProcess,
LPDWORD lpProcessAffinityMask,
LPDWORD lpSystemAffinityMask )
{
struct get_process_info_reply reply;
if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
if (lpProcessAffinityMask) *lpProcessAffinityMask = reply.process_affinity;
if (lpSystemAffinityMask) *lpSystemAffinityMask = reply.system_affinity;
return TRUE;
}
@ -720,15 +742,6 @@ DWORD WINAPI GetProcessFlags( DWORD processid )
return pdb->flags;
}
/***********************************************************************
* SetProcessAffinityMask [KERNEL32.662]
*/
BOOL32 WINAPI SetProcessAffinityMask(HANDLE32 hProcess,DWORD affmask)
{
FIXME(process,"(0x%08x,%ld), stub - harmless\n",hProcess,affmask);
return TRUE;
}
/***********************************************************************
* SetProcessWorkingSetSize [KERNEL32.662]
* Sets the min/max working set sizes for a specified process.
@ -867,15 +880,12 @@ BOOL32 WINAPI GetExitCodeProcess(
LPDWORD lpExitCode) /* [O] address to receive termination status */
{
struct get_process_info_reply reply;
int handle = HANDLE_GetServerHandle( PROCESS_Current(), hProcess,
K32OBJ_PROCESS, PROCESS_QUERY_INFORMATION );
CLIENT_SendRequest( REQ_GET_PROCESS_INFO, -1, 1, &handle, sizeof(handle) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (!PROCESS_QueryInfo( hProcess, &reply )) return FALSE;
if (lpExitCode) *lpExitCode = reply.exit_code;
return TRUE;
}
/***********************************************************************
* GetProcessHeaps [KERNEL32.376]
*/

View File

@ -28,7 +28,6 @@ static BOOL32 SYNC_BuildWaitStruct( DWORD count, const HANDLE32 *handles,
SYSTEM_LOCK();
wait->count = count;
wait->signaled = WAIT_FAILED;
wait->wait_all = wait_all;
for (i = 0, ptr = wait->objs; i < count; i++, ptr++)
{
@ -67,44 +66,12 @@ static void SYNC_FreeWaitStruct( WAIT_STRUCT *wait )
SYSTEM_UNLOCK();
}
/***********************************************************************
* SYNC_DoWait
*/
static DWORD SYNC_DoWait( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout, BOOL32 alertable )
{
WAIT_STRUCT *wait = &THREAD_Current()->wait_struct;
if (count > MAXIMUM_WAIT_OBJECTS)
{
SetLastError( ERROR_INVALID_PARAMETER );
return WAIT_FAILED;
}
if (alertable)
FIXME(win32, "alertable not implemented\n" );
if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait ))
wait->signaled = WAIT_FAILED;
else
{
int flags = 0;
if (wait_all) flags |= SELECT_ALL;
if (alertable) flags |= SELECT_ALERTABLE;
if (timeout != INFINITE32) flags |= SELECT_TIMEOUT;
wait->signaled = CLIENT_Select( count, wait->server, flags, timeout );
SYNC_FreeWaitStruct( wait );
}
return wait->signaled;
}
/***********************************************************************
* Sleep (KERNEL32.679)
*/
VOID WINAPI Sleep( DWORD timeout )
{
SYNC_DoWait( 0, NULL, FALSE, timeout, FALSE );
WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, FALSE );
}
/******************************************************************************
@ -112,7 +79,7 @@ VOID WINAPI Sleep( DWORD timeout )
*/
DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
{
DWORD ret = SYNC_DoWait( 0, NULL, FALSE, timeout, alertable );
DWORD ret = WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, alertable );
if (ret != WAIT_IO_COMPLETION) ret = 0;
return ret;
}
@ -123,7 +90,7 @@ DWORD WINAPI SleepEx( DWORD timeout, BOOL32 alertable )
*/
DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
{
return SYNC_DoWait( 1, &handle, FALSE, timeout, FALSE );
return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, FALSE );
}
@ -133,7 +100,7 @@ DWORD WINAPI WaitForSingleObject( HANDLE32 handle, DWORD timeout )
DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
BOOL32 alertable )
{
return SYNC_DoWait( 1, &handle, FALSE, timeout, alertable );
return WaitForMultipleObjectsEx( 1, &handle, FALSE, timeout, alertable );
}
@ -143,7 +110,7 @@ DWORD WINAPI WaitForSingleObjectEx( HANDLE32 handle, DWORD timeout,
DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout )
{
return SYNC_DoWait( count, handles, wait_all, timeout, FALSE );
return WaitForMultipleObjectsEx( count, handles, wait_all, timeout, FALSE );
}
@ -154,7 +121,46 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE32 *handles,
BOOL32 wait_all, DWORD timeout,
BOOL32 alertable )
{
return SYNC_DoWait( count, handles, wait_all, timeout, alertable );
WAIT_STRUCT *wait = &THREAD_Current()->wait_struct;
struct select_request req;
struct select_reply reply;
void *apc[32];
int len;
if (count > MAXIMUM_WAIT_OBJECTS)
{
SetLastError( ERROR_INVALID_PARAMETER );
return WAIT_FAILED;
}
if (!SYNC_BuildWaitStruct( count, handles, wait_all, wait ))
return WAIT_FAILED;
req.count = count;
req.flags = 0;
req.timeout = timeout;
if (wait_all) req.flags |= SELECT_ALL;
if (alertable) req.flags |= SELECT_ALERTABLE;
if (timeout != INFINITE32) req.flags |= SELECT_TIMEOUT;
CLIENT_SendRequest( REQ_SELECT, -1, 2,
&req, sizeof(req),
wait->server, count * sizeof(int) );
CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply),
apc, sizeof(apc) );
if ((reply.signaled == STATUS_USER_APC) && (len > sizeof(reply)))
{
int i;
len -= sizeof(reply);
for (i = 0; i < len / sizeof(void*); i += 2)
{
PAPCFUNC func = (PAPCFUNC)apc[i];
func( (ULONG_PTR)apc[i+1] );
}
}
SYNC_FreeWaitStruct( wait );
return reply.signaled;
}

View File

@ -35,18 +35,6 @@ const K32OBJ_OPS THREAD_Ops =
/* Is threading code initialized? */
BOOL32 THREAD_InitDone = FALSE;
/**********************************************************************
* THREAD_GetPtr
*
* Return a pointer to a thread object. The object count must be decremented
* when no longer used.
*/
THDB *THREAD_GetPtr( HANDLE32 handle, DWORD access, int *server_handle )
{
return (THDB *)HANDLE_GetObjPtr( PROCESS_Current(), handle,
K32OBJ_THREAD, access, server_handle );
}
/***********************************************************************
* THREAD_Current
@ -161,7 +149,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
LPTHREAD_START_ROUTINE start_addr, LPVOID param )
{
DWORD old_prot;
WORD cs, ds;
THDB *thdb = HeapAlloc( SystemHeap, HEAP_ZERO_MEMORY, sizeof(THDB) );
if (!thdb) return NULL;
@ -236,19 +223,6 @@ THDB *THREAD_Create( PDB32 *pdb, DWORD stack_size, BOOL32 alloc_stack16,
if (!(thdb->event = CreateEvent32A( NULL, FALSE, FALSE, NULL ))) goto error;
thdb->event = ConvertToGlobalHandle( thdb->event );
/* Initialize the thread context */
GET_CS(cs);
GET_DS(ds);
thdb->pcontext = &thdb->context;
thdb->context.SegCs = cs;
thdb->context.SegDs = ds;
thdb->context.SegEs = ds;
thdb->context.SegGs = ds;
thdb->context.SegSs = ds;
thdb->context.SegFs = thdb->teb_sel;
thdb->context.Eip = (DWORD)start_addr;
thdb->context.Esp = (DWORD)thdb->teb.stack_top;
PE_InitTls( thdb );
return thdb;
@ -588,10 +562,7 @@ BOOL32 WINAPI SetThreadContext(
HANDLE32 handle, /* [in] Handle to thread with context */
CONTEXT *context) /* [out] Address of context structure */
{
THDB *thread = THREAD_GetPtr( handle, THREAD_GET_CONTEXT, NULL );
if (!thread) return FALSE;
*context = thread->context;
K32OBJ_DecCount( &thread->header );
FIXME( thread, "not implemented\n" );
return TRUE;
}
@ -606,10 +577,19 @@ BOOL32 WINAPI GetThreadContext(
HANDLE32 handle, /* [in] Handle to thread with context */
CONTEXT *context) /* [out] Address of context structure */
{
THDB *thread = THREAD_GetPtr( handle, THREAD_GET_CONTEXT, NULL );
if (!thread) return FALSE;
*context = thread->context;
K32OBJ_DecCount( &thread->header );
WORD cs, ds;
FIXME( thread, "returning dummy info\n" );
/* make up some plausible values for segment registers */
GET_CS(cs);
GET_DS(ds);
context->SegCs = cs;
context->SegDs = ds;
context->SegEs = ds;
context->SegGs = ds;
context->SegSs = ds;
context->SegFs = ds;
return TRUE;
}
@ -624,14 +604,14 @@ BOOL32 WINAPI GetThreadContext(
INT32 WINAPI GetThreadPriority(
HANDLE32 hthread) /* [in] Handle to thread */
{
THDB *thread;
INT32 ret;
if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, NULL )))
struct get_thread_info_request req;
struct get_thread_info_reply reply;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ))
return THREAD_PRIORITY_ERROR_RETURN;
ret = thread->delta_priority;
K32OBJ_DecCount( &thread->header );
return ret;
return reply.priority;
}
@ -646,13 +626,31 @@ BOOL32 WINAPI SetThreadPriority(
HANDLE32 hthread, /* [in] Handle to thread */
INT32 priority) /* [in] Thread priority level */
{
THDB *thread;
if (!(thread = THREAD_GetPtr( hthread, THREAD_SET_INFORMATION, NULL )))
return FALSE;
thread->delta_priority = priority;
K32OBJ_DecCount( &thread->header );
return TRUE;
struct set_thread_info_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_SET_INFORMATION );
if (req.handle == -1) return FALSE;
req.priority = priority;
req.mask = SET_THREAD_INFO_PRIORITY;
CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
/**********************************************************************
* SetThreadAffinityMask (KERNEL32.669)
*/
DWORD WINAPI SetThreadAffinityMask( HANDLE32 hThread, DWORD dwThreadAffinityMask )
{
struct set_thread_info_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hThread,
K32OBJ_THREAD, THREAD_SET_INFORMATION );
if (req.handle == -1) return FALSE;
req.affinity = dwThreadAffinityMask;
req.mask = SET_THREAD_INFO_AFFINITY;
CLIENT_SendRequest( REQ_SET_THREAD_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitReply( NULL, NULL, 0 )) return 0;
return 1; /* FIXME: should return previous value */
}
@ -688,10 +686,11 @@ BOOL32 WINAPI GetExitCodeThread(
HANDLE32 hthread, /* [in] Handle to thread */
LPDWORD exitcode) /* [out] Address to receive termination status */
{
struct get_thread_info_request req;
struct get_thread_info_reply reply;
int handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_QUERY_INFORMATION );
CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &handle, sizeof(handle) );
CLIENT_SendRequest( REQ_GET_THREAD_INFO, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
if (exitcode) *exitcode = reply.exit_code;
return TRUE;
@ -710,33 +709,15 @@ BOOL32 WINAPI GetExitCodeThread(
* Already running: 0
*/
DWORD WINAPI ResumeThread(
HANDLE32 hthread) /* [in] Indentifies thread to restart */
HANDLE32 hthread) /* [in] Identifies thread to restart */
{
THDB *thread;
DWORD oldcount;
SYSTEM_LOCK();
if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, NULL )))
{
SYSTEM_UNLOCK();
WARN(thread, "Invalid thread handle\n");
return 0xFFFFFFFF;
}
if ((oldcount = thread->suspend_count) != 0)
{
if (!--thread->suspend_count)
{
if (kill(thread->unix_pid, SIGCONT))
{
WARN(thread, "Unable to CONTinue pid: %04x\n",
thread->unix_pid);
oldcount = 0xFFFFFFFF;
}
}
}
K32OBJ_DecCount(&thread->header);
SYSTEM_UNLOCK();
return oldcount;
struct resume_thread_request req;
struct resume_thread_reply reply;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_SUSPEND_RESUME );
CLIENT_SendRequest( REQ_RESUME_THREAD, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
return reply.count;
}
@ -750,37 +731,28 @@ DWORD WINAPI ResumeThread(
DWORD WINAPI SuspendThread(
HANDLE32 hthread) /* [in] Handle to the thread */
{
THDB *thread;
DWORD oldcount;
struct suspend_thread_request req;
struct suspend_thread_reply reply;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_SUSPEND_RESUME );
CLIENT_SendRequest( REQ_SUSPEND_THREAD, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return 0xffffffff;
return reply.count;
}
SYSTEM_LOCK();
if (!(thread = THREAD_GetPtr( hthread, THREAD_QUERY_INFORMATION, NULL )))
{
SYSTEM_UNLOCK();
WARN(thread, "Invalid thread handle\n");
return 0xFFFFFFFF;
}
if (!(oldcount = thread->suspend_count))
{
if (thread->unix_pid == getpid())
WARN(thread, "Attempting to suspend myself\n" );
else
{
if (kill(thread->unix_pid, SIGSTOP))
{
WARN(thread, "Unable to STOP pid: %04x\n",
thread->unix_pid);
oldcount = 0xFFFFFFFF;
}
else thread->suspend_count++;
}
}
else thread->suspend_count++;
K32OBJ_DecCount( &thread->header );
SYSTEM_UNLOCK();
return oldcount;
/***********************************************************************
* QueueUserAPC (KERNEL32.566)
*/
DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE32 hthread, ULONG_PTR data )
{
struct queue_apc_request req;
req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hthread,
K32OBJ_THREAD, THREAD_SET_CONTEXT );
req.func = func;
req.param = (void *)data;
CLIENT_SendRequest( REQ_QUEUE_APC, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}

View File

@ -9,6 +9,7 @@
#include <assert.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -21,36 +22,75 @@
#include "winerror.h"
#include "winnt.h"
#include "wincon.h"
#include "server/thread.h"
struct console
struct screen_buffer;
struct console_input
{
struct object obj; /* object header */
int fd; /* Unix file descriptor */
int is_read; /* is this the read or write part? */
struct object obj; /* object header */
int fd; /* Unix file descriptor */
int mode; /* input mode */
struct screen_buffer *output; /* associated screen buffer */
};
static void console_dump( struct object *obj, int verbose );
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry );
static void console_remove_queue( struct object *obj, struct wait_queue_entry *entry );
static int console_signaled( struct object *obj, struct thread *thread );
static int console_get_read_fd( struct object *obj );
static int console_get_write_fd( struct object *obj );
static int console_get_info( struct object *obj, struct get_file_info_reply *reply );
static void console_destroy( struct object *obj );
static const struct object_ops console_ops =
struct screen_buffer
{
console_dump,
console_add_queue,
console_remove_queue,
console_signaled,
struct object obj; /* object header */
int fd; /* Unix file descriptor */
int mode; /* output mode */
struct console_input *input; /* associated console input */
int cursor_size; /* size of cursor (percentage filled) */
int cursor_visible;/* cursor visibility flag */
int pid; /* xterm pid (hack) */
char *title; /* console title */
};
static void console_input_dump( struct object *obj, int verbose );
static int console_input_add_queue( struct object *obj, struct wait_queue_entry *entry );
static void console_input_remove_queue( struct object *obj, struct wait_queue_entry *entry );
static int console_input_signaled( struct object *obj, struct thread *thread );
static int console_input_get_read_fd( struct object *obj );
static void console_input_destroy( struct object *obj );
static void screen_buffer_dump( struct object *obj, int verbose );
static int screen_buffer_add_queue( struct object *obj, struct wait_queue_entry *entry );
static void screen_buffer_remove_queue( struct object *obj, struct wait_queue_entry *entry );
static int screen_buffer_signaled( struct object *obj, struct thread *thread );
static int screen_buffer_get_write_fd( struct object *obj );
static void screen_buffer_destroy( struct object *obj );
/* common routine */
static int console_get_info( struct object *obj, struct get_file_info_reply *reply );
static const struct object_ops console_input_ops =
{
console_input_dump,
console_input_add_queue,
console_input_remove_queue,
console_input_signaled,
no_satisfied,
console_get_read_fd,
console_get_write_fd,
console_input_get_read_fd,
no_write_fd,
no_flush,
console_get_info,
console_destroy
console_input_destroy
};
static const struct object_ops screen_buffer_ops =
{
screen_buffer_dump,
screen_buffer_add_queue,
screen_buffer_remove_queue,
screen_buffer_signaled,
no_satisfied,
no_read_fd,
screen_buffer_get_write_fd,
no_flush,
console_get_info,
screen_buffer_destroy
};
static const struct select_ops select_ops =
@ -61,7 +101,8 @@ static const struct select_ops select_ops =
int create_console( int fd, struct object *obj[2] )
{
struct console *console_read, *console_write;
struct console_input *console_input;
struct screen_buffer *screen_buffer;
int read_fd, write_fd;
if ((read_fd = (fd != -1) ? dup(fd) : dup(0)) == -1)
@ -75,67 +116,185 @@ int create_console( int fd, struct object *obj[2] )
close( read_fd );
return 0;
}
if (!(console_read = mem_alloc( sizeof(struct console) )))
if (!(console_input = mem_alloc( sizeof(struct console_input) )))
{
close( read_fd );
close( write_fd );
return 0;
}
if (!(console_write = mem_alloc( sizeof(struct console) )))
if (!(screen_buffer = mem_alloc( sizeof(struct screen_buffer) )))
{
close( read_fd );
close( write_fd );
free( console_read );
free( console_input );
return 0;
}
init_object( &console_read->obj, &console_ops, NULL );
init_object( &console_write->obj, &console_ops, NULL );
console_read->fd = read_fd;
console_read->is_read = 1;
console_write->fd = write_fd;
console_write->is_read = 0;
init_object( &console_input->obj, &console_input_ops, NULL );
init_object( &screen_buffer->obj, &screen_buffer_ops, NULL );
console_input->fd = read_fd;
console_input->mode = ENABLE_PROCESSED_INPUT | ENABLE_LINE_INPUT |
ENABLE_ECHO_INPUT | ENABLE_MOUSE_INPUT;
console_input->output = screen_buffer;
screen_buffer->fd = write_fd;
screen_buffer->mode = ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
screen_buffer->input = console_input;
screen_buffer->cursor_size = 100;
screen_buffer->cursor_visible = 1;
screen_buffer->pid = 0;
screen_buffer->title = strdup( "Wine console" );
CLEAR_ERROR();
obj[0] = &console_read->obj;
obj[1] = &console_write->obj;
obj[0] = &console_input->obj;
obj[1] = &screen_buffer->obj;
return 1;
}
int set_console_fd( int handle, int fd )
int set_console_fd( int handle, int fd, int pid )
{
struct console *console;
struct console_input *input;
struct screen_buffer *output;
struct object *obj;
int fd_in, fd_out;
if (!(console = (struct console *)get_handle_obj( current->process, handle,
0, &console_ops )))
if (!(obj = get_handle_obj( current->process, handle, 0, NULL )))
return 0;
if ((fd = dup(fd)) == -1)
if (obj->ops == &console_input_ops)
{
file_set_error();
release_object( console );
input = (struct console_input *)obj;
output = input->output;
grab_object( output );
}
else if (obj->ops == &screen_buffer_ops)
{
output = (struct screen_buffer *)obj;
input = output->input;
grab_object( input );
}
else
{
SET_ERROR( ERROR_INVALID_HANDLE );
release_object( obj );
return 0;
}
close( console->fd );
console->fd = fd;
if ((fd_in = dup(fd)) == -1)
{
file_set_error();
release_object( input );
release_object( output );
return 0;
}
if ((fd_out = dup(fd)) == -1)
{
file_set_error();
close( fd_in );
release_object( input );
release_object( output );
return 0;
}
close( input->fd );
close( output->fd );
input->fd = fd_in;
output->fd = fd_out;
output->pid = pid;
release_object( input );
release_object( output );
return 1;
}
int get_console_mode( int handle, int *mode )
{
struct object *obj;
int ret = 0;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
return 0;
if (obj->ops == &console_input_ops)
{
*mode = ((struct console_input *)obj)->mode;
ret = 1;
}
else if (obj->ops == &screen_buffer_ops)
{
*mode = ((struct screen_buffer *)obj)->mode;
ret = 1;
}
else SET_ERROR( ERROR_INVALID_HANDLE );
release_object( obj );
return ret;
}
int set_console_mode( int handle, int mode )
{
struct object *obj;
int ret = 0;
if (!(obj = get_handle_obj( current->process, handle, GENERIC_READ, NULL )))
return 0;
if (obj->ops == &console_input_ops)
{
((struct console_input *)obj)->mode = mode;
ret = 1;
}
else if (obj->ops == &screen_buffer_ops)
{
((struct screen_buffer *)obj)->mode = mode;
ret = 1;
}
else SET_ERROR( ERROR_INVALID_HANDLE );
release_object( obj );
return ret;
}
/* set misc console information (output handle only) */
int set_console_info( int handle, struct set_console_info_request *req, const char *title )
{
struct screen_buffer *console;
if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle,
GENERIC_WRITE, &screen_buffer_ops )))
return 0;
if (req->mask & SET_CONSOLE_INFO_CURSOR)
{
console->cursor_size = req->cursor_size;
console->cursor_visible = req->cursor_visible;
}
if (req->mask & SET_CONSOLE_INFO_TITLE)
{
if (console->title) free( console->title );
console->title = strdup( title );
}
release_object( console );
return 1;
}
static void console_dump( struct object *obj, int verbose )
/* get misc console information (output handle only) */
int get_console_info( int handle, struct get_console_info_reply *reply, const char **title )
{
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
fprintf( stderr, "Console %s fd=%d\n",
console->is_read ? "input" : "output", console->fd );
struct screen_buffer *console;
if (!(console = (struct screen_buffer *)get_handle_obj( current->process, handle,
GENERIC_READ, &screen_buffer_ops )))
return 0;
reply->cursor_size = console->cursor_size;
reply->cursor_visible = console->cursor_visible;
reply->pid = console->pid;
*title = console->title;
release_object( console );
return 1;
}
static int console_add_queue( struct object *obj, struct wait_queue_entry *entry )
static void console_input_dump( struct object *obj, int verbose )
{
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
fprintf( stderr, "Console input fd=%d\n", console->fd );
}
static int console_input_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
if (!obj->head) /* first on the queue */
{
if (!add_select_user( console->fd,
console->is_read ? READ_EVENT : WRITE_EVENT,
&select_ops, console ))
if (!add_select_user( console->fd, READ_EVENT, &select_ops, console ))
{
SET_ERROR( ERROR_OUTOFMEMORY );
return 0;
@ -145,10 +304,10 @@ static int console_add_queue( struct object *obj, struct wait_queue_entry *entry
return 1;
}
static void console_remove_queue( struct object *obj, struct wait_queue_entry *entry )
static void console_input_remove_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct console *console = (struct console *)grab_object(obj);
assert( obj->ops == &console_ops );
struct console_input *console = (struct console_input *)grab_object(obj);
assert( obj->ops == &console_input_ops );
remove_queue( obj, entry );
if (!obj->head) /* last on the queue is gone */
@ -156,44 +315,22 @@ static void console_remove_queue( struct object *obj, struct wait_queue_entry *e
release_object( obj );
}
static int console_signaled( struct object *obj, struct thread *thread )
static int console_input_signaled( struct object *obj, struct thread *thread )
{
fd_set fds;
struct timeval tv = { 0, 0 };
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
FD_ZERO( &fds );
FD_SET( console->fd, &fds );
if (console->is_read)
return select( console->fd + 1, &fds, NULL, NULL, &tv ) > 0;
else
return select( console->fd + 1, NULL, &fds, NULL, &tv ) > 0;
return select( console->fd + 1, &fds, NULL, NULL, &tv ) > 0;
}
static int console_get_read_fd( struct object *obj )
static int console_input_get_read_fd( struct object *obj )
{
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
if (!console->is_read)
{
SET_ERROR( ERROR_ACCESS_DENIED );
return -1;
}
return dup( console->fd );
}
static int console_get_write_fd( struct object *obj )
{
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
if (console->is_read)
{
SET_ERROR( ERROR_ACCESS_DENIED );
return -1;
}
struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
return dup( console->fd );
}
@ -204,10 +341,75 @@ static int console_get_info( struct object *obj, struct get_file_info_reply *rep
return 1;
}
static void console_destroy( struct object *obj )
static void console_input_destroy( struct object *obj )
{
struct console *console = (struct console *)obj;
assert( obj->ops == &console_ops );
struct console_input *console = (struct console_input *)obj;
assert( obj->ops == &console_input_ops );
close( console->fd );
if (console->output) console->output->input = NULL;
free( console );
}
static void screen_buffer_dump( struct object *obj, int verbose )
{
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
fprintf( stderr, "Console screen buffer fd=%d\n", console->fd );
}
static int screen_buffer_add_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
if (!obj->head) /* first on the queue */
{
if (!add_select_user( console->fd, WRITE_EVENT, &select_ops, console ))
{
SET_ERROR( ERROR_OUTOFMEMORY );
return 0;
}
}
add_queue( obj, entry );
return 1;
}
static void screen_buffer_remove_queue( struct object *obj, struct wait_queue_entry *entry )
{
struct screen_buffer *console = (struct screen_buffer *)grab_object(obj);
assert( obj->ops == &screen_buffer_ops );
remove_queue( obj, entry );
if (!obj->head) /* last on the queue is gone */
remove_select_user( console->fd );
release_object( obj );
}
static int screen_buffer_signaled( struct object *obj, struct thread *thread )
{
fd_set fds;
struct timeval tv = { 0, 0 };
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
FD_ZERO( &fds );
FD_SET( console->fd, &fds );
return select( console->fd + 1, NULL, &fds, NULL, &tv ) > 0;
}
static int screen_buffer_get_write_fd( struct object *obj )
{
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
return dup( console->fd );
}
static void screen_buffer_destroy( struct object *obj )
{
struct screen_buffer *console = (struct screen_buffer *)obj;
assert( obj->ops == &screen_buffer_ops );
close( console->fd );
if (console->input) console->input->output = NULL;
if (console->pid) kill( console->pid, SIGTERM );
if (console->title) free( console->title );
free( console );
}

View File

@ -423,3 +423,17 @@ int set_file_time( int handle, time_t access_time, time_t write_time )
return 1;
}
int file_lock( struct file *file, int offset_high, int offset_low,
int count_high, int count_low )
{
/* FIXME: implement this */
return 1;
}
int file_unlock( struct file *file, int offset_high, int offset_low,
int count_high, int count_low )
{
/* FIXME: implement this */
return 1;
}

View File

@ -52,6 +52,10 @@ struct process
int running_threads; /* number of threads running in this process */
struct timeval start_time; /* absolute time at process start */
struct timeval end_time; /* absolute time at process end */
int priority; /* priority class */
int affinity; /* process affinity mask */
struct object *console_in; /* console input */
struct object *console_out; /* console output */
};
static struct process *first_process;
@ -84,11 +88,12 @@ static const struct object_ops process_ops =
/* create a new process */
struct process *create_process(void)
{
struct process *process;
struct process *process, *parent;
if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
if (!copy_handle_table( process, current ? current->process : NULL ))
parent = current ? current->process : NULL;
if (!copy_handle_table( process, parent ))
{
free( process );
return NULL;
@ -99,6 +104,15 @@ struct process *create_process(void)
process->thread_list = NULL;
process->exit_code = 0x103; /* STILL_ACTIVE */
process->running_threads = 0;
process->priority = NORMAL_PRIORITY_CLASS;
process->affinity = 1;
process->console_in = NULL;
process->console_out = NULL;
if (parent)
{
if (parent->console_in) process->console_in = grab_object( parent->console_in );
if (parent->console_out) process->console_out = grab_object( parent->console_out );
}
if (first_process) first_process->prev = process;
first_process = process;
@ -126,6 +140,7 @@ static void process_destroy( struct object *obj )
if (process->next) process->next->prev = process->prev;
if (process->prev) process->prev->next = process->next;
else first_process = process->next;
free_console( process );
free_handles( process );
if (debug_level) memset( process, 0xbb, sizeof(process) ); /* catch errors */
free( process );
@ -506,6 +521,55 @@ void kill_process( struct process *process, int exit_code )
void get_process_info( struct process *process,
struct get_process_info_reply *reply )
{
reply->pid = process;
reply->exit_code = process->exit_code;
reply->pid = process;
reply->exit_code = process->exit_code;
reply->priority = process->priority;
reply->process_affinity = process->affinity;
reply->system_affinity = 1;
}
/* set all information about a process */
void set_process_info( struct process *process,
struct set_process_info_request *req )
{
if (req->mask & SET_PROCESS_INFO_PRIORITY)
process->priority = req->priority;
if (req->mask & SET_PROCESS_INFO_AFFINITY)
{
if (req->affinity != 1) SET_ERROR( ERROR_INVALID_PARAMETER );
else process->affinity = req->affinity;
}
}
/* allocate a console for this process */
int alloc_console( struct process *process )
{
struct object *obj[2];
if (process->console_in || process->console_out)
{
SET_ERROR( ERROR_ACCESS_DENIED );
return 0;
}
if (!create_console( -1, obj )) return 0;
process->console_in = obj[0];
process->console_out = obj[1];
return 1;
}
/* free the console for this process */
int free_console( struct process *process )
{
if (process->console_in) release_object( process->console_in );
if (process->console_out) release_object( process->console_out );
process->console_in = process->console_out = NULL;
return 1;
}
/* get the process console */
struct object *get_console( struct process *process, int output )
{
struct object *obj;
if (!(obj = output ? process->console_out : process->console_in))
return NULL;
return grab_object( obj );
}

View File

@ -227,7 +227,7 @@ DECL_HANDLER(dup_handle)
DECL_HANDLER(get_process_info)
{
struct process *process;
struct get_process_info_reply reply = { 0, 0 };
struct get_process_info_reply reply = { 0, 0, 0 };
if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
{
@ -237,6 +237,19 @@ DECL_HANDLER(get_process_info)
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* set information about a process */
DECL_HANDLER(set_process_info)
{
struct process *process;
if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
{
set_process_info( process, req );
release_object( process );
}
send_reply( current, -1, 0 );
}
/* fetch information about a thread */
DECL_HANDLER(get_thread_info)
{
@ -251,6 +264,59 @@ DECL_HANDLER(get_thread_info)
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* set information about a thread */
DECL_HANDLER(set_thread_info)
{
struct thread *thread;
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_INFORMATION )))
{
set_thread_info( thread, req );
release_object( thread );
}
send_reply( current, -1, 0 );
}
/* suspend a thread */
DECL_HANDLER(suspend_thread)
{
struct thread *thread;
struct suspend_thread_reply reply = { -1 };
if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
{
reply.count = suspend_thread( thread );
release_object( thread );
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* resume a thread */
DECL_HANDLER(resume_thread)
{
struct thread *thread;
struct resume_thread_reply reply = { -1 };
if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME )))
{
reply.count = resume_thread( thread );
release_object( thread );
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* queue an APC for a thread */
DECL_HANDLER(queue_apc)
{
struct thread *thread;
if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
{
thread_queue_apc( thread, req->func, req->param );
release_object( thread );
}
send_reply( current, -1, 0 );
}
/* open a handle to a process */
DECL_HANDLER(open_process)
{
@ -488,6 +554,36 @@ DECL_HANDLER(get_file_info)
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* lock a region of a file */
DECL_HANDLER(lock_file)
{
struct file *file;
if ((file = get_file_obj( current->process, req->handle, 0 )))
{
file_lock( file, req->offset_high, req->offset_low,
req->count_high, req->count_low );
release_object( file );
}
send_reply( current, -1, 0 );
}
/* unlock a region of a file */
DECL_HANDLER(unlock_file)
{
struct file *file;
if ((file = get_file_obj( current->process, req->handle, 0 )))
{
file_unlock( file, req->offset_high, req->offset_low,
req->count_high, req->count_low );
release_object( file );
}
send_reply( current, -1, 0 );
}
/* create an anonymous pipe */
DECL_HANDLER(create_pipe)
{
@ -512,34 +608,72 @@ DECL_HANDLER(create_pipe)
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* create a console */
DECL_HANDLER(create_console)
/* allocate a console for the current process */
DECL_HANDLER(alloc_console)
{
struct create_console_reply reply = { -1, -1 };
struct object *obj[2];
if (create_console( fd, obj ))
alloc_console( current->process );
send_reply( current, -1, 0 );
}
/* free the console of the current process */
DECL_HANDLER(free_console)
{
free_console( current->process );
send_reply( current, -1, 0 );
}
/* open a handle to the process console */
DECL_HANDLER(open_console)
{
struct object *obj;
struct open_console_reply reply = { -1 };
if ((obj = get_console( current->process, req->output )))
{
reply.handle_read = alloc_handle( current->process, obj[0],
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_READ,
req->inherit );
if (reply.handle_read != -1)
{
reply.handle_write = alloc_handle( current->process, obj[1],
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|GENERIC_WRITE,
req->inherit );
if (reply.handle_write == -1)
close_handle( current->process, reply.handle_read );
}
release_object( obj[0] );
release_object( obj[1] );
reply.handle = alloc_handle( current->process, obj, req->access, req->inherit );
release_object( obj );
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* set info about a console (output only) */
DECL_HANDLER(set_console_info)
{
char *name = (char *)data;
if (!len) name = NULL;
else CHECK_STRING( "set_console_info", name, len );
set_console_info( req->handle, req, name );
send_reply( current, -1, 0 );
}
/* get info about a console (output only) */
DECL_HANDLER(get_console_info)
{
struct get_console_info_reply reply;
const char *title;
get_console_info( req->handle, &reply, &title );
send_reply( current, -1, 2, &reply, sizeof(reply),
title, title ? strlen(title)+1 : 0 );
}
/* set a console fd */
DECL_HANDLER(set_console_fd)
{
set_console_fd( req->handle, fd );
set_console_fd( req->handle, fd, req->pid );
send_reply( current, -1, 0 );
}
/* get a console mode (input or output) */
DECL_HANDLER(get_console_mode)
{
struct get_console_mode_reply reply;
get_console_mode( req->handle, &reply.mode );
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
/* set a console mode (input or output) */
DECL_HANDLER(set_console_mode)
{
set_console_mode( req->handle, req->mode );
send_reply( current, -1, 0 );
}
@ -585,3 +719,18 @@ DECL_HANDLER(get_mapping_info)
int map_fd = get_mapping_info( req->handle, &reply );
send_reply( current, map_fd, 1, &reply, sizeof(reply) );
}
/* create a device */
DECL_HANDLER(create_device)
{
struct object *obj;
struct create_device_reply reply = { -1 };
if ((obj = create_device( req->id )))
{
reply.handle = alloc_handle( current->process, obj,
req->access, req->inherit );
release_object( obj );
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}

View File

@ -38,6 +38,15 @@ struct thread_wait
struct wait_queue_entry queues[1];
};
/* asynchronous procedure calls */
struct thread_apc
{
void *func; /* function to call in client */
void *param; /* function param */
};
#define MAX_THREAD_APC 16 /* Max outstanding APCs for a thread */
/* thread operations */
@ -86,11 +95,16 @@ struct thread *create_thread( int fd, void *pid, int *thread_handle,
thread->name = NULL;
thread->mutex = NULL;
thread->wait = NULL;
thread->apc = NULL;
thread->apc_count = 0;
thread->error = 0;
thread->state = STARTING;
thread->exit_code = 0x103; /* STILL_ACTIVE */
thread->next = first_thread;
thread->prev = NULL;
thread->priority = THREAD_PRIORITY_NORMAL;
thread->affinity = 1;
thread->suspend = 0;
if (first_thread) first_thread->prev = thread;
first_thread = thread;
@ -136,6 +150,7 @@ static void destroy_thread( struct object *obj )
if (thread->prev) thread->prev->next = thread->next;
else first_thread = thread->next;
if (thread->name) free( thread->name );
if (thread->apc) free( thread->apc );
if (debug_level) memset( thread, 0xaa, sizeof(thread) ); /* catch errors */
free( thread );
}
@ -178,6 +193,49 @@ void get_thread_info( struct thread *thread,
{
reply->pid = thread;
reply->exit_code = thread->exit_code;
reply->priority = thread->priority;
}
/* set all information about a thread */
void set_thread_info( struct thread *thread,
struct set_thread_info_request *req )
{
if (req->mask & SET_THREAD_INFO_PRIORITY)
thread->priority = req->priority;
if (req->mask & SET_THREAD_INFO_AFFINITY)
{
if (req->affinity != 1) SET_ERROR( ERROR_INVALID_PARAMETER );
else thread->affinity = req->affinity;
}
}
/* suspend a thread */
int suspend_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend < MAXIMUM_SUSPEND_COUNT)
{
if (!thread->suspend++)
{
if (thread->unix_pid) kill( thread->unix_pid, SIGSTOP );
}
}
return old_count;
}
/* resume a thread */
int resume_thread( struct thread *thread )
{
int old_count = thread->suspend;
if (thread->suspend > 0)
{
if (!--thread->suspend)
{
if (thread->unix_pid) kill( thread->unix_pid, SIGCONT );
}
}
return old_count;
}
/* send a reply to a thread */
@ -297,13 +355,12 @@ static int check_wait( struct thread *thread, int *signaled )
int i;
struct thread_wait *wait = thread->wait;
struct wait_queue_entry *entry = wait->queues;
struct timeval now;
assert( wait );
if (wait->flags & SELECT_ALL)
{
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
if (!entry->obj->ops->signaled( entry->obj, thread )) goto check_timeout;
if (!entry->obj->ops->signaled( entry->obj, thread )) goto other_checks;
/* Wait satisfied: tell it to all objects */
*signaled = 0;
for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
@ -323,61 +380,82 @@ static int check_wait( struct thread *thread, int *signaled )
return 1;
}
}
check_timeout:
if (!(wait->flags & SELECT_TIMEOUT)) return 0;
gettimeofday( &now, NULL );
if ((now.tv_sec > wait->timeout.tv_sec) ||
((now.tv_sec == wait->timeout.tv_sec) &&
(now.tv_usec >= wait->timeout.tv_usec)))
other_checks:
if ((wait->flags & SELECT_ALERTABLE) && thread->apc)
{
*signaled = STATUS_TIMEOUT;
*signaled = STATUS_USER_APC;
return 1;
}
if (wait->flags & SELECT_TIMEOUT)
{
struct timeval now;
gettimeofday( &now, NULL );
if ((now.tv_sec > wait->timeout.tv_sec) ||
((now.tv_sec == wait->timeout.tv_sec) &&
(now.tv_usec >= wait->timeout.tv_usec)))
{
*signaled = STATUS_TIMEOUT;
return 1;
}
}
return 0;
}
/* sleep on a list of objects */
void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
/* send the select reply to wake up the client */
static void send_select_reply( struct thread *thread, int signaled )
{
struct select_reply reply;
assert( !thread->wait );
reply.signaled = -1;
if (!wait_on( thread, count, handles, flags, timeout )) goto done;
if (!check_wait( thread, &reply.signaled ))
reply.signaled = signaled;
if ((signaled == STATUS_USER_APC) && thread->apc)
{
/* we need to wait */
if (flags & SELECT_TIMEOUT)
set_select_timeout( thread->client_fd, &thread->wait->timeout );
return;
struct thread_apc *apc = thread->apc;
int len = thread->apc_count * sizeof(*apc);
thread->apc = NULL;
thread->apc_count = 0;
send_reply( thread, -1, 2, &reply, sizeof(reply),
apc, len );
free( apc );
}
end_wait( thread );
done:
send_reply( thread, -1, 1, &reply, sizeof(reply) );
else send_reply( thread, -1, 1, &reply, sizeof(reply) );
}
/* attempt to wake up a thread */
/* return 1 if OK, 0 if the wait condition is still not satisfied */
static int wake_thread( struct thread *thread )
{
struct select_reply reply;
int signaled;
if (!check_wait( thread, &reply.signaled )) return 0;
if (!check_wait( thread, &signaled )) return 0;
end_wait( thread );
send_reply( thread, -1, 1, &reply, sizeof(reply) );
send_select_reply( thread, signaled );
return 1;
}
/* sleep on a list of objects */
void sleep_on( struct thread *thread, int count, int *handles, int flags, int timeout )
{
assert( !thread->wait );
if (!wait_on( thread, count, handles, flags, timeout ))
{
/* return an error */
send_select_reply( thread, -1 );
return;
}
if (!wake_thread( thread ))
{
/* we need to wait */
if (flags & SELECT_TIMEOUT)
set_select_timeout( thread->client_fd, &thread->wait->timeout );
}
}
/* timeout for the current thread */
void thread_timeout(void)
{
struct select_reply reply;
assert( current->wait );
reply.signaled = STATUS_TIMEOUT;
end_wait( current );
send_reply( current, -1, 1, &reply, sizeof(reply) );
send_select_reply( current, STATUS_TIMEOUT );
}
/* attempt to wake threads sleeping on the object wait queue */
@ -396,6 +474,29 @@ void wake_up( struct object *obj, int max )
}
}
/* queue an async procedure call */
int thread_queue_apc( struct thread *thread, void *func, void *param )
{
struct thread_apc *apc;
if (!func)
{
SET_ERROR( ERROR_INVALID_PARAMETER );
return 0;
}
if (!thread->apc)
{
if (!(thread->apc = mem_alloc( MAX_THREAD_APC * sizeof(*apc) )))
return 0;
thread->apc_count = 0;
}
else if (thread->apc_count >= MAX_THREAD_APC) return 0;
thread->apc[thread->apc_count].func = func;
thread->apc[thread->apc_count].param = param;
thread->apc_count++;
wake_thread( thread );
return 1;
}
/* kill a thread on the spot */
void kill_thread( struct thread *thread, int exit_code )
{

View File

@ -57,7 +57,19 @@ static int dump_get_process_info_request( struct get_process_info_request *req,
static int dump_get_process_info_reply( struct get_process_info_reply *req, int len )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " exit_code=%d", req->exit_code );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " process_affinity=%d,", req->process_affinity );
fprintf( stderr, " system_affinity=%d", req->system_affinity );
return (int)sizeof(*req);
}
static int dump_set_process_info_request( struct set_process_info_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " affinity=%d", req->affinity );
return (int)sizeof(*req);
}
@ -70,7 +82,49 @@ static int dump_get_thread_info_request( struct get_thread_info_request *req, in
static int dump_get_thread_info_reply( struct get_thread_info_reply *req, int len )
{
fprintf( stderr, " pid=%p,", req->pid );
fprintf( stderr, " exit_code=%d", req->exit_code );
fprintf( stderr, " exit_code=%d,", req->exit_code );
fprintf( stderr, " priority=%d", req->priority );
return (int)sizeof(*req);
}
static int dump_set_thread_info_request( struct set_thread_info_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " priority=%d,", req->priority );
fprintf( stderr, " affinity=%d", req->affinity );
return (int)sizeof(*req);
}
static int dump_suspend_thread_request( struct suspend_thread_request *req, int len )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_suspend_thread_reply( struct suspend_thread_reply *req, int len )
{
fprintf( stderr, " count=%d", req->count );
return (int)sizeof(*req);
}
static int dump_resume_thread_request( struct resume_thread_request *req, int len )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_resume_thread_reply( struct resume_thread_reply *req, int len )
{
fprintf( stderr, " count=%d", req->count );
return (int)sizeof(*req);
}
static int dump_queue_apc_request( struct queue_apc_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " func=%p,", req->func );
fprintf( stderr, " param=%p", req->param );
return (int)sizeof(*req);
}
@ -297,6 +351,26 @@ static int dump_get_file_info_reply( struct get_file_info_reply *req, int len )
return (int)sizeof(*req);
}
static int dump_lock_file_request( struct lock_file_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " offset_low=%08x,", req->offset_low );
fprintf( stderr, " offset_high=%08x,", req->offset_high );
fprintf( stderr, " count_low=%08x,", req->count_low );
fprintf( stderr, " count_high=%08x", req->count_high );
return (int)sizeof(*req);
}
static int dump_unlock_file_request( struct unlock_file_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " offset_low=%08x,", req->offset_low );
fprintf( stderr, " offset_high=%08x,", req->offset_high );
fprintf( stderr, " count_low=%08x,", req->count_low );
fprintf( stderr, " count_high=%08x", req->count_high );
return (int)sizeof(*req);
}
static int dump_create_pipe_request( struct create_pipe_request *req, int len )
{
fprintf( stderr, " inherit=%d", req->inherit );
@ -310,25 +384,80 @@ static int dump_create_pipe_reply( struct create_pipe_reply *req, int len )
return (int)sizeof(*req);
}
static int dump_create_console_request( struct create_console_request *req, int len )
static int dump_alloc_console_request( struct alloc_console_request *req, int len )
{
return (int)sizeof(*req);
}
static int dump_free_console_request( struct free_console_request *req, int len )
{
return (int)sizeof(*req);
}
static int dump_open_console_request( struct open_console_request *req, int len )
{
fprintf( stderr, " output=%d,", req->output );
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d", req->inherit );
return (int)sizeof(*req);
}
static int dump_create_console_reply( struct create_console_reply *req, int len )
static int dump_open_console_reply( struct open_console_reply *req, int len )
{
fprintf( stderr, " handle_read=%d,", req->handle_read );
fprintf( stderr, " handle_write=%d", req->handle_write );
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_set_console_fd_request( struct set_console_fd_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " pid=%d", req->pid );
return (int)sizeof(*req);
}
static int dump_get_console_mode_request( struct get_console_mode_request *req, int len )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_console_mode_reply( struct get_console_mode_reply *req, int len )
{
fprintf( stderr, " mode=%d", req->mode );
return (int)sizeof(*req);
}
static int dump_set_console_mode_request( struct set_console_mode_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mode=%d", req->mode );
return (int)sizeof(*req);
}
static int dump_set_console_info_request( struct set_console_info_request *req, int len )
{
fprintf( stderr, " handle=%d,", req->handle );
fprintf( stderr, " mask=%d,", req->mask );
fprintf( stderr, " cursor_size=%d,", req->cursor_size );
fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
fprintf( stderr, " title=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
return len;
}
static int dump_get_console_info_request( struct get_console_info_request *req, int len )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
static int dump_get_console_info_reply( struct get_console_info_reply *req, int len )
{
fprintf( stderr, " cursor_size=%d,", req->cursor_size );
fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
fprintf( stderr, " pid=%d", req->pid );
return (int)sizeof(*req);
}
static int dump_create_change_notification_request( struct create_change_notification_request *req, int len )
{
fprintf( stderr, " subtree=%d,", req->subtree );
@ -372,6 +501,20 @@ static int dump_get_mapping_info_reply( struct get_mapping_info_reply *req, int
return (int)sizeof(*req);
}
static int dump_create_device_request( struct create_device_request *req, int len )
{
fprintf( stderr, " access=%08x,", req->access );
fprintf( stderr, " inherit=%d,", req->inherit );
fprintf( stderr, " id=%d", req->id );
return (int)sizeof(*req);
}
static int dump_create_device_reply( struct create_device_reply *req, int len )
{
fprintf( stderr, " handle=%d", req->handle );
return (int)sizeof(*req);
}
struct dumper
{
int (*dump_req)( void *data, int len );
@ -392,8 +535,18 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(void(*)())0 },
{ (int(*)(void *,int))dump_get_process_info_request,
(void(*)())dump_get_process_info_reply },
{ (int(*)(void *,int))dump_set_process_info_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_get_thread_info_request,
(void(*)())dump_get_thread_info_reply },
{ (int(*)(void *,int))dump_set_thread_info_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_suspend_thread_request,
(void(*)())dump_suspend_thread_reply },
{ (int(*)(void *,int))dump_resume_thread_request,
(void(*)())dump_resume_thread_reply },
{ (int(*)(void *,int))dump_queue_apc_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_close_handle_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_dup_handle_request,
@ -432,18 +585,36 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(void(*)())0 },
{ (int(*)(void *,int))dump_get_file_info_request,
(void(*)())dump_get_file_info_reply },
{ (int(*)(void *,int))dump_lock_file_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_unlock_file_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_create_pipe_request,
(void(*)())dump_create_pipe_reply },
{ (int(*)(void *,int))dump_create_console_request,
(void(*)())dump_create_console_reply },
{ (int(*)(void *,int))dump_alloc_console_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_free_console_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_open_console_request,
(void(*)())dump_open_console_reply },
{ (int(*)(void *,int))dump_set_console_fd_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_get_console_mode_request,
(void(*)())dump_get_console_mode_reply },
{ (int(*)(void *,int))dump_set_console_mode_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_set_console_info_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_get_console_info_request,
(void(*)())dump_get_console_info_reply },
{ (int(*)(void *,int))dump_create_change_notification_request,
(void(*)())dump_create_change_notification_reply },
{ (int(*)(void *,int))dump_create_mapping_request,
(void(*)())dump_create_mapping_reply },
{ (int(*)(void *,int))dump_get_mapping_info_request,
(void(*)())dump_get_mapping_info_reply },
{ (int(*)(void *,int))dump_create_device_request,
(void(*)())dump_create_device_reply },
};
static const char * const req_names[REQ_NB_REQUESTS] =
@ -454,7 +625,12 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"terminate_process",
"terminate_thread",
"get_process_info",
"set_process_info",
"get_thread_info",
"set_thread_info",
"suspend_thread",
"resume_thread",
"queue_apc",
"close_handle",
"dup_handle",
"open_process",
@ -474,12 +650,21 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"set_file_time",
"flush_file",
"get_file_info",
"lock_file",
"unlock_file",
"create_pipe",
"create_console",
"alloc_console",
"free_console",
"open_console",
"set_console_fd",
"get_console_mode",
"set_console_mode",
"set_console_info",
"get_console_info",
"create_change_notification",
"create_mapping",
"get_mapping_info",
"create_device",
};
void trace_request( enum request req, void *data, int len, int fd )

View File

@ -50,14 +50,7 @@
/* The CONSOLE kernel32 Object */
typedef struct _CONSOLE {
K32OBJ header;
DWORD mode;
CONSOLE_CURSOR_INFO cinfo;
int master; /* xterm side of pty */
int infd,outfd;
int hread, hwrite; /* server handles (hack) */
int pid; /* xterm's pid, -1 if no xterm */
LPSTR title; /* title of console */
INPUT_RECORD *irs; /* buffered input records */
int nrofirs;/* nr of buffered input records */
} CONSOLE;
@ -79,16 +72,34 @@ static void CONSOLE_Destroy(K32OBJ *obj)
obj->type = K32OBJ_UNKNOWN;
if (console->title)
HeapFree( SystemHeap, 0, console->title );
console->title = NULL;
/* if there is a xterm, kill it. */
if (console->pid != -1)
kill(console->pid, SIGTERM);
HeapFree(SystemHeap, 0, console);
}
/***********************************************************************
* CONSOLE_GetPtr
*/
static CONSOLE *CONSOLE_GetPtr( HANDLE32 handle )
{
return (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), handle,
K32OBJ_CONSOLE, 0, NULL );
}
/****************************************************************************
* CONSOLE_GetInfo
*/
static BOOL32 CONSOLE_GetInfo( HANDLE32 handle, struct get_console_info_reply *reply )
{
struct get_console_info_request req;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_CONSOLE, GENERIC_READ )) == -1)
return FALSE;
CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitSimpleReply( reply, sizeof(*reply), NULL );
}
/****************************************************************************
* CONSOLE_add_input_record [internal]
*
@ -110,8 +121,7 @@ static void
CONSOLE_string_to_IR( HANDLE32 hConsoleInput,unsigned char *buf,int len) {
int j,k;
INPUT_RECORD ir;
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput,
K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hConsoleInput );
for (j=0;j<len;j++) {
unsigned char inchar = buf[j];
@ -489,8 +499,15 @@ BOOL32 WINAPI FreeConsole(VOID)
return FALSE;
}
HANDLE_CloseAll( pdb, &console->header );
CLIENT_SendRequest( REQ_FREE_CONSOLE, -1, 0 );
if (CLIENT_WaitReply( NULL, NULL, 0 ) != ERROR_SUCCESS)
{
K32OBJ_DecCount(&console->header);
SYSTEM_UNLOCK();
return FALSE;
}
HANDLE_CloseAll( pdb, &console->header );
K32OBJ_DecCount( &console->header );
pdb->console = NULL;
SYSTEM_UNLOCK();
@ -498,33 +515,43 @@ BOOL32 WINAPI FreeConsole(VOID)
}
/**
* It looks like the openpty that comes with glibc in RedHat 5.0
* is buggy (second call returns what looks like a dup of 0 and 1
* instead of a new pty), this is a generic replacement.
/*************************************************************************
* CONSOLE_OpenHandle
*
* Open a handle to the current process console.
*/
static int CONSOLE_openpty(CONSOLE *console, char *name,
struct termios *term, struct winsize *winsize)
HANDLE32 CONSOLE_OpenHandle( BOOL32 output, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
int temp, slave;
struct set_console_fd_request req;
struct open_console_request req;
struct open_console_reply reply;
CONSOLE *console;
HANDLE32 handle;
temp = wine_openpty(&console->master, &slave, name, term,
winsize);
console->infd = console->outfd = slave;
req.output = output;
req.access = access;
req.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) );
CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL );
if (reply.handle == -1) return INVALID_HANDLE_VALUE32;
req.handle = console->hread;
CLIENT_SendRequest(REQ_SET_CONSOLE_FD, dup(slave), 1,
&req, sizeof(req));
CLIENT_WaitReply( NULL, NULL, 0);
req.handle = console->hwrite;
CLIENT_SendRequest( REQ_SET_CONSOLE_FD, dup(slave), 1,
&req, sizeof(req));
CLIENT_WaitReply( NULL, NULL, 0);
return temp; /* The same result as the openpty call */
SYSTEM_LOCK();
if (!(console = (CONSOLE*)HeapAlloc( SystemHeap, 0, sizeof(*console))))
{
SYSTEM_UNLOCK();
return FALSE;
}
console->header.type = K32OBJ_CONSOLE;
console->header.refcount = 1;
console->nrofirs = 0;
console->irs = HeapAlloc(GetProcessHeap(),0,1);;
handle = HANDLE_Alloc( PROCESS_Current(), &console->header, req.access,
req.inherit, reply.handle );
SYSTEM_UNLOCK();
K32OBJ_DecCount(&console->header);
return handle;
}
/*************************************************************************
* CONSOLE_make_complex [internal]
*
@ -537,29 +564,37 @@ static int CONSOLE_openpty(CONSOLE *console, char *name,
*
* All other functions should work indedependend from this call.
*
* To test for complex console: pid == -1 -> simple, otherwise complex.
* To test for complex console: pid == 0 -> simple, otherwise complex.
*/
static BOOL32 CONSOLE_make_complex(HANDLE32 handle,CONSOLE *console)
static BOOL32 CONSOLE_make_complex(HANDLE32 handle)
{
struct set_console_fd_request req;
struct get_console_info_reply info;
struct termios term;
char buf[30],*title;
char buf[256];
char c = '\0';
int status = 0;
int i,xpid;
int i,xpid,master,slave;
DWORD xlen;
if (console->pid != -1)
return TRUE; /* already complex */
if (!CONSOLE_GetInfo( handle, &info )) return FALSE;
if (info.pid) return TRUE; /* already complex */
MSG("Console: Making console complex (creating an xterm)...\n");
if (tcgetattr(0, &term) < 0) return FALSE;
term.c_lflag = ~(ECHO|ICANON);
if (CONSOLE_openpty(console, NULL, &term, NULL) < 0) return FALSE;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_CONSOLE, 0 )) == -1)
return FALSE;
if (wine_openpty(&master, &slave, NULL, &term, NULL) < 0)
return FALSE;
if ((xpid=fork()) == 0) {
tcsetattr(console->infd, TCSADRAIN, &term);
sprintf(buf, "-Sxx%d", console->master);
tcsetattr(slave, TCSADRAIN, &term);
sprintf(buf, "-Sxx%d", master);
/* "-fn vga" for VGA font. Harmless if vga is not present:
* xterm: unable to open font "vga", trying "fixed"....
*/
@ -567,53 +602,39 @@ static BOOL32 CONSOLE_make_complex(HANDLE32 handle,CONSOLE *console)
ERR(console, "error creating AllocConsole xterm\n");
exit(1);
}
console->pid = xpid;
req.pid = xpid;
CLIENT_SendRequest( REQ_SET_CONSOLE_FD, dup(slave), 1, &req, sizeof(req) );
CLIENT_WaitReply( NULL, NULL, 0 );
/* most xterms like to print their window ID when used with -S;
* read it and continue before the user has a chance...
*/
for (i=0; c!='\n'; (status=read(console->infd, &c, 1)), i++) {
for (i=0; c!='\n'; (status=read(slave, &c, 1)), i++) {
if (status == -1 && c == '\0') {
/* wait for xterm to be created */
usleep(100);
}
if (i > 10000) {
ERR(console, "can't read xterm WID\n");
kill(console->pid, SIGKILL);
kill(xpid, SIGKILL);
return FALSE;
}
}
/* enable mouseclicks */
sprintf(buf,"%c[?1001s%c[?1000h",27,27);
WriteFile(handle,buf,strlen(buf),&xlen,NULL);
if (console->title) {
title = HeapAlloc(GetProcessHeap(),0,strlen("\033]2;\a")+1+strlen(console->title));
sprintf(title,"\033]2;%s\a",console->title);
WriteFile(handle,title,strlen(title),&xlen,NULL);
HeapFree(GetProcessHeap(),0,title);
if (GetConsoleTitle32A( buf, sizeof(buf) ))
{
WriteFile(handle,"\033]2;",4,&xlen,NULL);
WriteFile(handle,buf,strlen(buf),&xlen,NULL);
WriteFile(handle,"\a",1,&xlen,NULL);
}
return TRUE;
}
/***********************************************************************
* CONSOLE_GetConsoleHandle
* returns a 16-bit style console handle
* note: only called from _lopen
*/
HFILE32 CONSOLE_GetConsoleHandle(VOID)
{
PDB32 *pdb = PROCESS_Current();
HFILE32 handle = HFILE_ERROR32;
SYSTEM_LOCK();
if (pdb->console != NULL) {
CONSOLE *console = (CONSOLE *)pdb->console;
handle = (HFILE32)HANDLE_Alloc(pdb, &console->header, 0, TRUE, -1);
}
SYSTEM_UNLOCK();
return handle;
}
/***********************************************************************
* AllocConsole (KERNEL32.103)
@ -622,17 +643,14 @@ HFILE32 CONSOLE_GetConsoleHandle(VOID)
*/
BOOL32 WINAPI AllocConsole(VOID)
{
struct create_console_request req;
struct create_console_reply reply;
struct open_console_request req;
struct open_console_reply reply;
PDB32 *pdb = PROCESS_Current();
CONSOLE *console;
HANDLE32 hIn, hOut, hErr;
SYSTEM_LOCK(); /* FIXME: really only need to lock the process */
SetLastError(ERROR_CANNOT_MAKE); /* this might not be the right
error, but it's a good guess :) */
console = (CONSOLE *)pdb->console;
/* don't create a console if we already have one */
@ -650,39 +668,46 @@ BOOL32 WINAPI AllocConsole(VOID)
console->header.type = K32OBJ_CONSOLE;
console->header.refcount = 1;
console->pid = -1;
console->title = NULL;
console->nrofirs = 0;
console->irs = HeapAlloc(GetProcessHeap(),0,1);;
console->mode = ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT;
/* FIXME: we shouldn't probably use hardcoded UNIX values here. */
console->infd = 0;
console->outfd = 1;
console->hread = console->hwrite = -1;
CLIENT_SendRequest( REQ_CREATE_CONSOLE, -1, 1, &req, sizeof(req) );
CLIENT_SendRequest( REQ_ALLOC_CONSOLE, -1, 0 );
if (CLIENT_WaitReply( NULL, NULL, 0 ) != ERROR_SUCCESS)
{
K32OBJ_DecCount(&console->header);
SYSTEM_UNLOCK();
return FALSE;
}
req.output = 0;
req.access = GENERIC_READ | GENERIC_WRITE;
req.inherit = FALSE;
CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) != ERROR_SUCCESS)
{
K32OBJ_DecCount(&console->header);
SYSTEM_UNLOCK();
return FALSE;
}
console->hread = reply.handle_read;
console->hwrite = reply.handle_write;
if ((hIn = HANDLE_Alloc(pdb,&console->header, 0, TRUE,
reply.handle_read)) == INVALID_HANDLE_VALUE32)
if ((hIn = HANDLE_Alloc(pdb,&console->header, req.access,
FALSE, reply.handle)) == INVALID_HANDLE_VALUE32)
{
CLIENT_CloseHandle( reply.handle_write );
K32OBJ_DecCount(&console->header);
SYSTEM_UNLOCK();
return FALSE;
}
if ((hOut = HANDLE_Alloc(pdb,&console->header, 0, TRUE,
reply.handle_write)) == INVALID_HANDLE_VALUE32)
req.output = 1;
CLIENT_SendRequest( REQ_OPEN_CONSOLE, -1, 1, &req, sizeof(req) );
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) != ERROR_SUCCESS)
{
CloseHandle(hIn);
K32OBJ_DecCount(&console->header);
SYSTEM_UNLOCK();
return FALSE;
}
if ((hOut = HANDLE_Alloc(pdb,&console->header, req.access,
FALSE, reply.handle)) == INVALID_HANDLE_VALUE32)
{
CloseHandle(hIn);
K32OBJ_DecCount(&console->header);
@ -742,14 +767,15 @@ UINT32 WINAPI GetConsoleOutputCP(VOID)
*/
BOOL32 WINAPI GetConsoleMode(HANDLE32 hcon,LPDWORD mode)
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
struct get_console_mode_request req;
struct get_console_mode_reply reply;
if (!console) {
FIXME(console,"(%d,%p), no console handle passed!\n",hcon,mode);
return FALSE;
}
*mode = console->mode;
K32OBJ_DecCount(&console->header);
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hcon,
K32OBJ_CONSOLE, GENERIC_READ )) == -1)
return FALSE;
CLIENT_SendRequest( REQ_GET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return FALSE;
*mode = reply.mode;
return TRUE;
}
@ -767,16 +793,14 @@ BOOL32 WINAPI GetConsoleMode(HANDLE32 hcon,LPDWORD mode)
*/
BOOL32 WINAPI SetConsoleMode( HANDLE32 hcon, DWORD mode )
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
struct set_console_mode_request req;
if (!console) {
FIXME(console,"(%d,%ld), no console handle passed!\n",hcon,mode);
return FALSE;
}
FIXME(console,"(0x%08x,0x%08lx): stub\n",hcon,mode);
console->mode = mode;
K32OBJ_DecCount(&console->header);
return TRUE;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hcon,
K32OBJ_CONSOLE, GENERIC_READ )) == -1)
return FALSE;
req.mode = mode;
CLIENT_SendRequest( REQ_SET_CONSOLE_MODE, -1, 1, &req, sizeof(req));
return !CLIENT_WaitReply( NULL, NULL, 0 );
}
@ -785,14 +809,29 @@ BOOL32 WINAPI SetConsoleMode( HANDLE32 hcon, DWORD mode )
*/
DWORD WINAPI GetConsoleTitle32A(LPSTR title,DWORD size)
{
PDB32 *pdb = PROCESS_Current();
CONSOLE *console= (CONSOLE *)pdb->console;
struct get_console_info_request req;
struct get_console_info_reply reply;
int len;
DWORD ret = 0;
HANDLE32 hcon;
if(console && console->title) {
lstrcpyn32A(title,console->title,size);
return strlen(title);
if ((hcon = CreateFile32A( "CONOUT$", GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE32)
return 0;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hcon,
K32OBJ_CONSOLE, GENERIC_READ )) == -1)
{
CloseHandle( hcon );
return 0;
}
return 0;
CLIENT_SendRequest( REQ_GET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
if (!CLIENT_WaitReply( &len, NULL, 2, &reply, sizeof(reply), title, size ))
{
if (len > sizeof(reply)+size) title[size-1] = 0;
ret = strlen(title);
}
CloseHandle( hcon );
return ret;
}
@ -809,14 +848,14 @@ DWORD WINAPI GetConsoleTitle32A(LPSTR title,DWORD size)
*/
DWORD WINAPI GetConsoleTitle32W( LPWSTR title, DWORD size )
{
PDB32 *pdb = PROCESS_Current();
CONSOLE *console= (CONSOLE *)pdb->console;
if(console && console->title)
{
lstrcpynAtoW(title,console->title,size);
return (lstrlen32W(title));
}
return 0;
char *tmp;
DWORD ret;
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, size ))) return 0;
ret = GetConsoleTitle32A( tmp, size );
lstrcpyAtoW( title, tmp );
HeapFree( GetProcessHeap(), 0, tmp );
return ret;
}
@ -858,13 +897,7 @@ BOOL32 WINAPI WriteConsoleOutput32A( HANDLE32 hConsoleOutput,
0,4,2,6,
1,5,3,7,
};
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleOutput, K32OBJ_CONSOLE, 0, NULL);
if (!console) {
FIXME(console,"(%d,...): no console handle!\n",hConsoleOutput);
return FALSE;
}
CONSOLE_make_complex(hConsoleOutput,console);
CONSOLE_make_complex(hConsoleOutput);
buffer = HeapAlloc(GetProcessHeap(),0,100);;
curbufsize = 100;
@ -897,7 +930,6 @@ BOOL32 WINAPI WriteConsoleOutput32A( HANDLE32 hConsoleOutput,
sprintf(sbuf,"%c[0m",27);SADD(sbuf);
WriteFile(hConsoleOutput,buffer,bufused,&res,NULL);
HeapFree(GetProcessHeap(),0,buffer);
K32OBJ_DecCount(&console->header);
return TRUE;
}
@ -932,7 +964,7 @@ BOOL32 WINAPI ReadConsole32A( HANDLE32 hConsoleInput,
LPDWORD lpNumberOfCharsRead,
LPVOID lpReserved )
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput, K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hConsoleInput );
int i,charsread = 0;
LPSTR xbuf = (LPSTR)lpBuffer;
@ -1007,7 +1039,7 @@ BOOL32 WINAPI ReadConsoleInput32A(HANDLE32 hConsoleInput,
LPINPUT_RECORD lpBuffer,
DWORD nLength, LPDWORD lpNumberOfEventsRead)
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput, K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hConsoleInput );
TRACE(console, "(%d,%p,%ld,%p)\n",hConsoleInput, lpBuffer, nLength,
lpNumberOfEventsRead);
@ -1056,6 +1088,7 @@ BOOL32 WINAPI ReadConsoleInput32A(HANDLE32 hConsoleInput,
*/
BOOL32 WINAPI SetConsoleTitle32A(LPCSTR title)
{
#if 0
PDB32 *pdb = PROCESS_Current();
CONSOLE *console;
DWORD written;
@ -1079,6 +1112,7 @@ BOOL32 WINAPI SetConsoleTitle32A(LPCSTR title)
}
sprintf(titlestring,titleformat,title);
#if 0
/* only set title for complex console (own xterm) */
if (console->pid != -1) {
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),titlestring,strlen(titlestring),&written,NULL);
@ -1086,9 +1120,41 @@ BOOL32 WINAPI SetConsoleTitle32A(LPCSTR title)
ret =TRUE;
} else
ret = TRUE;
#endif
HeapFree( GetProcessHeap(), 0, titlestring );
K32OBJ_DecCount(&console->header);
return ret;
#endif
struct set_console_info_request req;
struct get_console_info_reply info;
HANDLE32 hcon;
DWORD written;
if ((hcon = CreateFile32A( "CONOUT$", GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0 )) == INVALID_HANDLE_VALUE32)
return FALSE;
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hcon,
K32OBJ_CONSOLE, GENERIC_WRITE )) == -1)
goto error;
req.mask = SET_CONSOLE_INFO_TITLE;
CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 2, &req, sizeof(req),
title, strlen(title)+1 );
if (CLIENT_WaitReply( NULL, NULL, 0 )) goto error;
if (CONSOLE_GetInfo( hcon, &info ) && info.pid)
{
/* only set title for complex console (own xterm) */
WriteFile( hcon, "\033]2;", 4, &written, NULL );
WriteFile( hcon, title, strlen(title), &written, NULL );
WriteFile( hcon, "\a", 1, &written, NULL );
}
return TRUE;
error:
CloseHandle( hcon );
return FALSE;
}
@ -1132,7 +1198,7 @@ BOOL32 WINAPI ReadConsoleInput32W(HANDLE32 hConsoleInput,
*/
BOOL32 WINAPI FlushConsoleInputBuffer(HANDLE32 hConsoleInput)
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput, K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hConsoleInput );
if (!console)
return FALSE;
@ -1156,19 +1222,13 @@ BOOL32 WINAPI SetConsoleCursorPosition( HANDLE32 hcon, COORD pos )
{
char xbuf[20];
DWORD xlen;
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
if (!console) {
FIXME(console,"(%d,...), no console handle!\n",hcon);
return FALSE;
}
CONSOLE_make_complex(hcon,console);
CONSOLE_make_complex(hcon);
TRACE(console, "%d (%dx%d)\n", hcon, pos.x , pos.y );
/* x are columns, y rows */
sprintf(xbuf,"%c[%d;%dH", 0x1B, pos.y+1, pos.x+1);
/* FIXME: store internal if we start using own console buffers */
WriteFile(hcon,xbuf,strlen(xbuf),&xlen,NULL);
K32OBJ_DecCount(&console->header);
return TRUE;
}
@ -1177,7 +1237,7 @@ BOOL32 WINAPI SetConsoleCursorPosition( HANDLE32 hcon, COORD pos )
*/
BOOL32 WINAPI GetNumberOfConsoleInputEvents(HANDLE32 hcon,LPDWORD nrofevents)
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hcon );
if (!console) {
FIXME(console,"(%d,%p), no console handle!\n",hcon,nrofevents);
@ -1211,7 +1271,7 @@ BOOL32 WINAPI PeekConsoleInput32A(HANDLE32 hConsoleInput,
DWORD cInRecords,
LPDWORD lpcRead)
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hConsoleInput, K32OBJ_CONSOLE, 0, NULL);
CONSOLE *console = CONSOLE_GetPtr( hConsoleInput );
if (!console) {
FIXME(console,"(%d,%p,%ld,%p), No console handle passed!\n",hConsoleInput, pirBuffer, cInRecords, lpcRead);
@ -1260,17 +1320,14 @@ BOOL32 WINAPI PeekConsoleInput32W(HANDLE32 hConsoleInput,
BOOL32 WINAPI GetConsoleCursorInfo32( HANDLE32 hcon,
LPCONSOLE_CURSOR_INFO cinfo )
{
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
struct get_console_info_reply reply;
if (!console) {
FIXME(console, "(%x,%p), no console handle!\n", hcon, cinfo);
return FALSE;
if (!CONSOLE_GetInfo( hcon, &reply )) return FALSE;
if (cinfo)
{
cinfo->dwSize = reply.cursor_size;
cinfo->bVisible = reply.cursor_visible;
}
TRACE(console, "(%x,%p)\n", hcon, cinfo);
if (!cinfo)
return FALSE;
*cinfo = console->cinfo;
K32OBJ_DecCount(&console->header);
return TRUE;
}
@ -1286,19 +1343,22 @@ BOOL32 WINAPI SetConsoleCursorInfo32(
HANDLE32 hcon, /* [in] Handle to console screen buffer */
LPCONSOLE_CURSOR_INFO cinfo) /* [in] Address of cursor information */
{
struct set_console_info_request req;
char buf[8];
DWORD xlen;
CONSOLE *console = (CONSOLE*)HANDLE_GetObjPtr( PROCESS_Current(), hcon, K32OBJ_CONSOLE, 0, NULL);
TRACE(console, "(%x,%ld,%i): stub\n", hcon,cinfo->dwSize,cinfo->bVisible);
if (!console)
return FALSE;
CONSOLE_make_complex(hcon,console);
sprintf(buf,"%c[?25%c",27,cinfo->bVisible?'h':'l');
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), hcon,
K32OBJ_CONSOLE, GENERIC_WRITE )) == -1)
return FALSE;
CONSOLE_make_complex(hcon);
sprintf(buf,"\033[?25%c",cinfo->bVisible?'h':'l');
WriteFile(hcon,buf,strlen(buf),&xlen,NULL);
console->cinfo = *cinfo;
K32OBJ_DecCount(&console->header);
return TRUE;
req.cursor_size = cinfo->dwSize;
req.cursor_visible = cinfo->bVisible;
req.mask = SET_CONSOLE_INFO_CURSOR;
CLIENT_SendRequest( REQ_SET_CONSOLE_INFO, -1, 1, &req, sizeof(req) );
return !CLIENT_WaitReply( NULL, NULL, 0 );
}

View File

@ -30,28 +30,15 @@
#include "winnt.h"
#include "msdos.h"
#include "miscemu.h"
static void DEVICE_Destroy(K32OBJ *dev);
const K32OBJ_OPS DEVICE_Ops =
{
DEVICE_Destroy /* destroy */
};
/* The device object */
typedef struct
{
K32OBJ header;
struct VxDInfo *info;
} DEVICE_OBJECT;
#include "server.h"
static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_VTDAPI(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPOVERLAPPED lpOverlapped);
static BOOL32 DeviceIo_MONODEBG(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_MONODEBG(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
@ -59,13 +46,13 @@ static BOOL32 DeviceIo_MONODEBG(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 VxDCall_VMM( DWORD *retv, DWORD service, CONTEXT *context );
static BOOL32 DeviceIo_IFSMgr(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_IFSMgr(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPOVERLAPPED lpOverlapped);
static BOOL32 DeviceIo_VWin32(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_VWin32(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
@ -80,10 +67,11 @@ struct VxDInfo
LPCSTR name;
WORD id;
BOOL32 (*vxdcall)(DWORD *, DWORD, CONTEXT *);
BOOL32 (*deviceio)(DEVICE_OBJECT *, DWORD, LPVOID, DWORD,
BOOL32 (*deviceio)(DWORD, LPVOID, DWORD,
LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
}
VxDList[] =
};
static const struct VxDInfo VxDList[] =
{
/* Standard VxD IDs */
{ "VMM", 0x0001, VxDCall_VMM, NULL },
@ -266,43 +254,39 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
"<KERNEL32.101>" /* 0x0028 -- What does this do??? */
};
HANDLE32 DEVICE_Open(LPCSTR filename)
HANDLE32 DEVICE_Open( LPCSTR filename, DWORD access,
LPSECURITY_ATTRIBUTES sa )
{
DEVICE_OBJECT *dev;
HANDLE32 handle;
int i;
const struct VxDInfo *info;
dev = HeapAlloc( SystemHeap, 0, sizeof(DEVICE_OBJECT) );
if (!dev) return INVALID_HANDLE_VALUE32;
for (info = VxDList; info->name; info++)
if (!lstrcmpi32A( info->name, filename ))
return FILE_CreateDevice( info->id | 0x10000, access, sa );
dev->header.type = K32OBJ_DEVICE_IOCTL;
dev->header.refcount = 1;
dev->info = NULL;
for (i = 0; VxDList[i].name; i++)
if (!lstrcmpi32A(VxDList[i].name, filename))
break;
if (VxDList[i].name)
dev->info = &VxDList[i];
else
FIXME(win32, "Unknown VxD %s\n", filename);
handle = HANDLE_Alloc( PROCESS_Current(), &(dev->header),
FILE_ALL_ACCESS | GENERIC_READ |
GENERIC_WRITE | GENERIC_EXECUTE /*FIXME*/, TRUE, -1 );
/* If the allocation failed, the object is already destroyed */
if (handle == INVALID_HANDLE_VALUE32) dev = NULL;
return handle;
FIXME(win32, "Unknown VxD %s\n", filename);
return FILE_CreateDevice( 0x10000, access, sa );
}
static void DEVICE_Destroy(K32OBJ *obj)
static const struct VxDInfo *DEVICE_GetInfo( HANDLE32 handle )
{
DEVICE_OBJECT *dev = (DEVICE_OBJECT *)obj;
assert( obj->type == K32OBJ_DEVICE_IOCTL );
struct get_file_info_request req;
struct get_file_info_reply reply;
obj->type = K32OBJ_UNKNOWN;
HeapFree( SystemHeap, 0, dev );
if ((req.handle = HANDLE_GetServerHandle( PROCESS_Current(), handle,
K32OBJ_FILE, 0 )) == -1)
return NULL;
CLIENT_SendRequest( REQ_GET_FILE_INFO, -1, 1, &req, sizeof(req) );
if (!CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL ) &&
(reply.type == FILE_TYPE_UNKNOWN) &&
(reply.attr & 0x10000))
{
const struct VxDInfo *info;
for (info = VxDList; info->name; info++)
if (info->id == LOWORD(reply.attr)) break;
return info;
}
return NULL;
}
/****************************************************************************
@ -320,15 +304,14 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
LPDWORD lpcbBytesReturned,
LPOVERLAPPED lpOverlapped)
{
DEVICE_OBJECT *dev = (DEVICE_OBJECT *)HANDLE_GetObjPtr(
PROCESS_Current(), hDevice, K32OBJ_DEVICE_IOCTL, 0 /*FIXME*/, NULL );
const struct VxDInfo *info;
TRACE(win32, "(%d,%ld,%p,%ld,%p,%ld,%p,%p)\n",
hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped
);
if (!dev)
if (!(info = DEVICE_GetInfo( hDevice )))
{
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
@ -337,9 +320,9 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
/* Check if this is a user defined control code for a VxD */
if( HIWORD( dwIoControlCode ) == 0 )
{
if ( dev->info && dev->info->deviceio )
if ( info->deviceio )
{
return dev->info->deviceio( dev, dwIoControlCode,
return info->deviceio( dwIoControlCode,
lpvInBuffer, cbInBuffer,
lpvOutBuffer, cbOutBuffer,
lpcbBytesReturned, lpOverlapped );
@ -348,7 +331,7 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
{
/* FIXME: Set appropriate error */
FIXME( win32, "Unimplemented control %ld for VxD device %s\n",
dwIoControlCode, dev->info ? dev->info->name : "???" );
dwIoControlCode, info->name ? info->name : "???" );
}
}
else
@ -403,8 +386,7 @@ BOOL32 WINAPI DeviceIoControl(HANDLE32 hDevice, DWORD dwIoControlCode,
/***********************************************************************
* DeviceIo_VTDAPI
*/
static BOOL32 DeviceIo_VTDAPI(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
static BOOL32 DeviceIo_VTDAPI(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPOVERLAPPED lpOverlapped)
@ -765,15 +747,14 @@ static void CONTEXT_2_win32apieq(CONTEXT *pCxt,struct win32apireq *pOut)
/* FIXME: pOut->ar_pad ignored */
}
static BOOL32 DeviceIo_IFSMgr(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
static BOOL32 DeviceIo_IFSMgr(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPOVERLAPPED lpOverlapped)
{
BOOL32 retv = TRUE;
TRACE(win32,"(%p,%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
dev,dwIoControlCode,
TRACE(win32,"(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
dwIoControlCode,
lpvInBuffer,cbInBuffer,
lpvOutBuffer,cbOutBuffer,
lpcbBytesReturned,
@ -866,7 +847,7 @@ static void CONTEXT_2_DIOCRegs( CONTEXT *pCxt, DIOC_REGISTERS *pOut )
}
static BOOL32 DeviceIo_VWin32(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_VWin32(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
@ -928,7 +909,7 @@ static BOOL32 DeviceIo_VWin32(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
/* this is used by some Origin games */
static BOOL32 DeviceIo_MONODEBG(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
static BOOL32 DeviceIo_MONODEBG(DWORD dwIoControlCode,
LPVOID lpvInBuffer, DWORD cbInBuffer,
LPVOID lpvOutBuffer, DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
@ -942,8 +923,8 @@ static BOOL32 DeviceIo_MONODEBG(DEVICE_OBJECT *dev, DWORD dwIoControlCode,
fprintf(stderr,"MONODEBG: %s\n",debugstr_a(lpvInBuffer));
break;
default:
FIXME(win32,"(%p,%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
dev,dwIoControlCode,
FIXME(win32,"(%ld,%p,%ld,%p,%ld,%p,%p): stub\n",
dwIoControlCode,
lpvInBuffer,cbInBuffer,
lpvOutBuffer,cbOutBuffer,
lpcbBytesReturned,

View File

@ -19,45 +19,6 @@
#include "debug.h"
/**********************************************************************
* GetProcessAffinityMask
*/
BOOL32 WINAPI GetProcessAffinityMask(HANDLE32 hProcess,
LPDWORD lpProcessAffinityMask,
LPDWORD lpSystemAffinityMask)
{
TRACE(task,"(%x,%lx,%lx)\n",
hProcess,(lpProcessAffinityMask?*lpProcessAffinityMask:0),
(lpSystemAffinityMask?*lpSystemAffinityMask:0));
/* It is definitely important for a process to know on what processor
it is running :-) */
if(lpProcessAffinityMask)
*lpProcessAffinityMask=1;
if(lpSystemAffinityMask)
*lpSystemAffinityMask=1;
return TRUE;
}
/**********************************************************************
* SetThreadAffinityMask
* Works now like the Windows95 (no MP support) version
*/
BOOL32 WINAPI SetThreadAffinityMask(HANDLE32 hThread, DWORD dwThreadAffinityMask)
{
THDB *thdb = THREAD_GetPtr( hThread, THREAD_SET_INFORMATION, NULL );
if (!thdb)
return FALSE;
if (dwThreadAffinityMask!=1) {
WARN(thread,"(%d,%ld): only 1 processor supported.\n",
(int)hThread,dwThreadAffinityMask);
K32OBJ_DecCount((K32OBJ*)thdb);
return FALSE;
}
K32OBJ_DecCount((K32OBJ*)thdb);
return TRUE;
}
/**********************************************************************
* ContinueDebugEvent [KERNEL32.146]
*/