[ros-diffs] [fireball] 42041: - Implement proper "wine server" invocations support, including variable data requests (both to and from the server). - Add global synch, so that our server deals only with one caller at a time.

fireball at svn.reactos.org fireball at svn.reactos.org
Sat Jul 18 14:35:59 CEST 2009


Author: fireball
Date: Sat Jul 18 14:35:59 2009
New Revision: 42041

URL: http://svn.reactos.org/svn/reactos?rev=42041&view=rev
Log:
- Implement proper "wine server" invocations support, including variable data requests (both to and from the server).
- Add global synch, so that our server deals only with one caller at a time.

Modified:
    branches/arwinss/reactos/subsystems/win32/win32k/wine/main.c

Modified: branches/arwinss/reactos/subsystems/win32/win32k/wine/main.c
URL: http://svn.reactos.org/svn/reactos/branches/arwinss/reactos/subsystems/win32/win32k/wine/main.c?rev=42041&r1=42040&r2=42041&view=diff
==============================================================================
--- branches/arwinss/reactos/subsystems/win32/win32k/wine/main.c [iso-8859-1] (original)
+++ branches/arwinss/reactos/subsystems/win32/win32k/wine/main.c [iso-8859-1] Sat Jul 18 14:35:59 2009
@@ -20,33 +20,166 @@
 #define NDEBUG
 #include <debug.h>
 
+ERESOURCE UserLock;
+
+PVOID RequestData;
+ULONG ReplySize;
+PVOID ReplyData;
+
 /* PRIVATE FUNCTIONS *********************************************************/
+
+VOID UserEnterExclusive(VOID)
+{
+    /* Acquire user resource exclusively */
+    KeEnterCriticalRegion();
+    ExAcquireResourceExclusiveLite(&UserLock, TRUE);
+}
+
+VOID UserLeave(VOID)
+{
+    /* Release user resource */
+    ExReleaseResourceLite(&UserLock);
+    KeLeaveCriticalRegion();
+}
+
+#if 0
+VOID UserCleanup(VOID)
+{
+   ExDeleteResourceLite(&UserLock);
+}
+#endif
+
+VOID UserInitialize(VOID)
+{
+    NTSTATUS Status;
+
+    /* Initialize user access resource */
+    Status = ExInitializeResourceLite(&UserLock);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failure initializing USER resource!\n");
+    }
+}
 
 UINT
 APIENTRY
 wine_server_call(void *req_ptr)
 {
     struct __server_request_info *reqinfo = req_ptr;
-    //struct type##_request * const req = &__req.u.req.type##_request;
-    //const struct type##_reply * const reply = &__req.u.reply.type##_reply;
-
     union generic_reply reply;
     enum request req = reqinfo->u.req.request_header.req;
+    UCHAR i;
+    ULONG DataWritten=0;
 
     DPRINT("WineServer call of type 0x%x\n", req);
 
+    /* Zero reply's memory area */
     memset( &reply, 0, sizeof(reply) );
 
-    //if (debug_level) trace_request();
+    /* Acquire lock */
+    UserEnterExclusive();
 
+    /* Clear error status */
+    set_error(0);
+
+    if (reqinfo->data_count > 1)
+    {
+        /* We need to make a contiguous data block from those */
+        DataWritten = 0;
+        for (i=0; i<reqinfo->data_count; i++)
+        {
+            DataWritten += reqinfo->data[i].size;
+        }
+
+        /* Allocate memory for it */
+        RequestData = ExAllocatePool(PagedPool, DataWritten);
+
+        /* Place them */
+        DataWritten = 0;
+        for (i=0; i<reqinfo->data_count; i++)
+        {
+            RtlCopyMemory(((UCHAR *)RequestData + DataWritten),
+                          reqinfo->data[i].ptr,
+                          reqinfo->data[i].size);
+
+            /* Advance to the next data block */
+            DataWritten += reqinfo->data[i].size;
+        }
+    }
+    else
+    {
+        RequestData = (PVOID)reqinfo->data[0].ptr;
+    }
+
+    ReplySize = 0;
+    ReplyData = NULL;
+
+    /* Perform the request */
     if (req < REQ_NB_REQUESTS)
+    {
+        /* Call request handler */
         req_handlers[req]( req_ptr, &reply );
+    }
     else
+    {
         DPRINT1("WineServer call of type 0x%x is not implemented!\n", req);
+    }
 
-    //reply.reply_header.error = current->error;
-    //reply.reply_header.reply_size = current->reply_size;
-    //if (debug_level) trace_reply( req, &reply );
+    /* Free the request data area if needed */
+    if (reqinfo->data_count > 1) ExFreePool(RequestData);
 
-    return 0;
+    /* Copy back the reply data if any */
+    if (ReplySize)
+    {
+        /* Copy it */
+        RtlCopyMemory(reqinfo->reply_data, ReplyData, ReplySize);
+
+        /* Free temp storage */
+        ExFreePool(ReplyData);
+    }
+
+    /* Set reply's error flag and size */
+    reply.reply_header.error = get_error();
+    reply.reply_header.reply_size = ReplySize;
+
+    /* Copy reply back */
+    memcpy (&reqinfo->u.reply, &reply, sizeof(reply));
+
+    /* Release lock */
+    UserLeave();
+
+    //if (reply.reply_header.error)
+    //    DPRINT1("returning error 0x%08X\n", reply.reply_header.error);
+
+    //if (reply.reply_header.error == 0x103 ||
+    //    reply.reply_header.error == STATUS_ACCESS_DENIED) DbgBreakPoint();
+
+    return reply.reply_header.error;
 }
+
+/* allocate the reply data */
+void *set_reply_data_size( void *req, data_size_t size )
+{
+    ASSERT( size <= get_reply_max_size(req) );
+
+    /* Allocate storage for reply data */
+    if (size && !(ReplyData = ExAllocatePool( PagedPool, size ))) size = 0;
+
+    /* Set reply size */
+    ReplySize = size;
+
+    /* Return a pointer to allocated storage */
+    return ReplyData;
+}
+
+/* set the reply data pointer directly (will be freed by request code) */
+void set_reply_data_ptr( void *req, void *data, data_size_t size )
+{
+    ASSERT( size < get_reply_max_size(req));
+
+    /* Just save them */
+    ReplySize = size;
+    ReplyData = data;
+}
+



More information about the Ros-diffs mailing list