Skip to content
Snippets Groups Projects
Commit 63cb0f8b authored by Alexandre Julliard's avatar Alexandre Julliard
Browse files

Added change notifications.

Added global handle support.
parent 748ff0f9
No related branches found
No related tags found
No related merge requests found
......@@ -127,6 +127,9 @@ struct dup_handle_request
int inherit; /* inherit flag */
int options; /* duplicate options (see below) */
};
#define DUP_HANDLE_CLOSE_SOURCE DUPLICATE_CLOSE_SOURCE
#define DUP_HANDLE_SAME_ACCESS DUPLICATE_SAME_ACCESS
#define DUP_HANDLE_MAKE_GLOBAL 0x80000000 /* Not a Windows flag */
struct dup_handle_reply
{
int handle; /* duplicated handle in dst process */
......@@ -212,7 +215,7 @@ struct create_semaphore_request
unsigned int initial; /* initial count */
unsigned int max; /* maximum count */
int inherit; /* inherit flag */
/* char name[] */
char name[0]; /* semaphore name */
};
struct create_semaphore_reply
{
......@@ -235,10 +238,10 @@ struct release_semaphore_reply
/* Open a named object (event, mutex, semaphore) */
struct open_named_obj_request
{
int type; /* object type (see below) */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
/* char name[] */
int type; /* object type (see below) */
unsigned int access; /* wanted access rights */
int inherit; /* inherit flag */
char name[0]; /* object name */
};
enum open_named_obj { OPEN_EVENT, OPEN_MUTEX, OPEN_SEMAPHORE };
......@@ -361,12 +364,25 @@ struct set_console_fd_request
};
/* Create a console */
struct create_change_notification_request
{
int subtree; /* watch all the subtree */
int filter; /* notification filter */
};
struct create_change_notification_reply
{
int handle; /* handle to the change notification */
};
/* client-side functions */
#ifndef __WINE_SERVER__
#include "server/request.h"
/* client communication functions */
enum request;
#define CHECK_LEN(len,wanted) \
if ((len) == (wanted)) ; \
else CLIENT_ProtocolError( __FUNCTION__ ": len %d != %d\n", (len), (wanted) );
......@@ -380,8 +396,6 @@ struct _THDB;
extern int CLIENT_NewThread( struct _THDB *thdb, int *thandle, int *phandle );
extern int CLIENT_SetDebug( int level );
extern int CLIENT_InitThread(void);
extern int CLIENT_TerminateProcess( int handle, int exit_code );
extern int CLIENT_TerminateThread( int handle, int exit_code );
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 );
......
......@@ -189,6 +189,11 @@ extern int create_console( int fd, struct object *obj[2] );
extern int set_console_fd( int handle, int fd );
/* change notification functions */
extern struct object *create_change_notification( int subtree, int filter );
extern int debug_level;
#endif /* __WINE_SERVER_OBJECT_H */
......@@ -34,6 +34,7 @@ enum request
REQ_CREATE_PIPE,
REQ_CREATE_CONSOLE,
REQ_SET_CONSOLE_FD,
REQ_CREATE_CHANGE_NOTIFICATION,
REQ_NB_REQUESTS
};
......@@ -71,6 +72,7 @@ DECL_HANDLER(get_file_info);
DECL_HANDLER(create_pipe);
DECL_HANDLER(create_console);
DECL_HANDLER(set_console_fd);
DECL_HANDLER(create_change_notification);
static const struct handler {
void (*handler)();
......@@ -105,6 +107,7 @@ static const struct handler {
{ (void(*)())req_create_pipe, sizeof(struct create_pipe_request) },
{ (void(*)())req_create_console, sizeof(struct create_console_request) },
{ (void(*)())req_set_console_fd, sizeof(struct set_console_fd_request) },
{ (void(*)())req_create_change_notification, sizeof(struct create_change_notification_request) },
};
#endif /* WANT_REQUEST_HANDLERS */
......
......@@ -6,6 +6,7 @@ VPATH = @srcdir@
MODULE = server
C_SRCS = \
change.c \
console.c \
event.c \
file.c \
......
/*
* Server-side change notification management
*
* Copyright (C) 1998 Alexandre Julliard
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "winerror.h"
#include "winnt.h"
#include "server/thread.h"
struct change
{
struct object obj; /* object header */
int subtree; /* watch all the subtree */
int filter; /* notification filter */
};
static void change_dump( struct object *obj, int verbose );
static int change_signaled( struct object *obj, struct thread *thread );
static void change_destroy( struct object *obj );
static const struct object_ops change_ops =
{
change_dump,
add_queue,
remove_queue,
change_signaled,
no_satisfied,
no_read_fd,
no_write_fd,
no_flush,
change_destroy
};
struct object *create_change_notification( int subtree, int filter )
{
struct change *change;
if (!(change = mem_alloc( sizeof(*change) ))) return NULL;
init_object( &change->obj, &change_ops, NULL );
change->subtree = subtree;
change->filter = filter;
return &change->obj;
}
static void change_dump( struct object *obj, int verbose )
{
struct change *change = (struct change *)obj;
assert( obj->ops == &change_ops );
printf( "Change notification sub=%d filter=%08x\n",
change->subtree, change->filter );
}
static int change_signaled( struct object *obj, struct thread *thread )
{
/* struct change *change = (struct change *)obj;*/
assert( obj->ops == &change_ops );
return 0; /* never signaled for now */
}
static void change_destroy( struct object *obj )
{
struct change *change = (struct change *)obj;
assert( obj->ops == &change_ops );
free( change );
}
......@@ -25,6 +25,12 @@
#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
#define RESERVED_ALL (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)
/* global handle macros */
#define HANDLE_OBFUSCATOR 0x544a4def
#define HANDLE_IS_GLOBAL(h) (((h) ^ HANDLE_OBFUSCATOR) < 0x10000)
#define HANDLE_LOCAL_TO_GLOBAL(h) ((h) ^ HANDLE_OBFUSCATOR)
#define HANDLE_GLOBAL_TO_LOCAL(h) ((h) ^ HANDLE_OBFUSCATOR)
struct handle_entry
{
struct object *ptr;
......@@ -49,6 +55,7 @@ struct process
};
static struct process *first_process;
static struct process *initial_process;
#define MIN_HANDLE_ENTRIES 32
......@@ -94,6 +101,11 @@ struct process *create_process(void)
if (first_process) first_process->prev = process;
first_process = process;
if (!initial_process)
{
initial_process = process;
grab_object( initial_process ); /* so that we never free it */
}
gettimeofday( &process->start_time, NULL );
/* alloc a handle for the process itself */
......@@ -106,6 +118,7 @@ static void process_destroy( struct object *obj )
{
struct process *process = (struct process *)obj;
assert( obj->ops == &process_ops );
assert( process != initial_process );
/* we can't have a thread remaining */
assert( !process->thread_list );
......@@ -288,6 +301,11 @@ static struct handle_entry *get_handle( struct process *process, int handle )
{
struct handle_entry *entry;
if (HANDLE_IS_GLOBAL(handle))
{
handle = HANDLE_GLOBAL_TO_LOCAL(handle);
process = initial_process;
}
handle--; /* handles start at 1 */
if ((handle < 0) || (handle > process->handle_last)) goto error;
entry = process->entries + handle;
......@@ -370,6 +388,11 @@ int close_handle( struct process *process, int handle )
struct handle_entry *entry;
struct object *obj;
if (HANDLE_IS_GLOBAL(handle))
{
handle = HANDLE_GLOBAL_TO_LOCAL(handle);
process = initial_process;
}
if (!(entry = get_handle( process, handle ))) return 0;
if (entry->access & RESERVED_CLOSE_PROTECT) return 0; /* FIXME: error code */
obj = entry->ptr;
......@@ -429,12 +452,16 @@ int set_handle_info( struct process *process, int handle, int mask, int flags )
int duplicate_handle( struct process *src, int src_handle, struct process *dst,
int dst_handle, unsigned int access, int inherit, int options )
{
int res;
struct handle_entry *entry = get_handle( src, src_handle );
if (!entry) return -1;
if (options & DUPLICATE_SAME_ACCESS) access = entry->access;
if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access;
if (options & DUP_HANDLE_MAKE_GLOBAL) dst = initial_process;
access &= ~RESERVED_ALL;
return alloc_specific_handle( dst, entry->ptr, dst_handle, access, inherit );
res = alloc_specific_handle( dst, entry->ptr, dst_handle, access, inherit );
if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res);
return res;
}
/* open a new handle to an existing object */
......
......@@ -204,14 +204,19 @@ DECL_HANDLER(dup_handle)
if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE )))
{
if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
if (req->options & DUP_HANDLE_MAKE_GLOBAL)
{
reply.handle = duplicate_handle( src, req->src_handle, NULL, -1,
req->access, req->inherit, req->options );
}
else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE )))
{
reply.handle = duplicate_handle( src, req->src_handle, dst, req->dst_handle,
req->access, req->inherit, req->options );
release_object( dst );
}
/* close the handle no matter what happened */
if (req->options & DUPLICATE_CLOSE_SOURCE)
if (req->options & DUP_HANDLE_CLOSE_SOURCE)
close_handle( src, req->src_handle );
release_object( src );
}
......@@ -531,3 +536,19 @@ DECL_HANDLER(set_console_fd)
set_console_fd( req->handle, fd );
send_reply( current, -1, 0 );
}
/* create a change notification */
DECL_HANDLER(create_change_notification)
{
struct object *obj;
struct create_change_notification_reply reply = { -1 };
if ((obj = create_change_notification( req->subtree, req->filter )))
{
reply.handle = alloc_handle( current->process, obj,
STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 );
release_object( obj );
}
send_reply( current, -1, 1, &reply, sizeof(reply) );
}
......@@ -172,8 +172,9 @@ static int dump_create_semaphore_request( struct create_semaphore_request *req,
{
printf( " initial=%08x,", req->initial );
printf( " max=%08x,", req->max );
printf( " inherit=%d", req->inherit );
return (int)sizeof(*req);
printf( " inherit=%d,", req->inherit );
printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
return len;
}
static int dump_create_semaphore_reply( struct create_semaphore_reply *req, int len )
......@@ -199,8 +200,9 @@ static int dump_open_named_obj_request( struct open_named_obj_request *req, int
{
printf( " type=%d,", req->type );
printf( " access=%08x,", req->access );
printf( " inherit=%d", req->inherit );
return (int)sizeof(*req);
printf( " inherit=%d,", req->inherit );
printf( " name=\"%.*s\"", len - (int)sizeof(*req), (char *)(req+1) );
return len;
}
static int dump_open_named_obj_reply( struct open_named_obj_reply *req, int len )
......@@ -321,6 +323,19 @@ static int dump_set_console_fd_request( struct set_console_fd_request *req, int
return (int)sizeof(*req);
}
static int dump_create_change_notification_request( struct create_change_notification_request *req, int len )
{
printf( " subtree=%d,", req->subtree );
printf( " filter=%d", req->filter );
return (int)sizeof(*req);
}
static int dump_create_change_notification_reply( struct create_change_notification_reply *req, int len )
{
printf( " handle=%d", req->handle );
return (int)sizeof(*req);
}
struct dumper
{
int (*dump_req)( void *data, int len );
......@@ -387,6 +402,8 @@ static const struct dumper dumpers[REQ_NB_REQUESTS] =
(void(*)())dump_create_console_reply },
{ (int(*)(void *,int))dump_set_console_fd_request,
(void(*)())0 },
{ (int(*)(void *,int))dump_create_change_notification_request,
(void(*)())dump_create_change_notification_reply },
};
static const char * const req_names[REQ_NB_REQUESTS] =
......@@ -420,6 +437,7 @@ static const char * const req_names[REQ_NB_REQUESTS] =
"create_pipe",
"create_console",
"set_console_fd",
"create_change_notification",
};
void trace_request( enum request req, void *data, int len, int fd )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment