Implemented NtSignalAndWaitForSingleObject.

diff --git a/server/semaphore.c b/server/semaphore.c
index 27aba0d..7886842 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -41,6 +41,7 @@
 static void semaphore_dump( struct object *obj, int verbose );
 static int semaphore_signaled( struct object *obj, struct thread *thread );
 static int semaphore_satisfied( struct object *obj, struct thread *thread );
+static int semaphore_signal( struct object *obj, unsigned int access );
 
 static const struct object_ops semaphore_ops =
 {
@@ -50,6 +51,7 @@
     remove_queue,                  /* remove_queue */
     semaphore_signaled,            /* signaled */
     semaphore_satisfied,           /* satisfied */
+    semaphore_signal,              /* signal */
     no_get_fd,                     /* get_fd */
     no_destroy                     /* destroy */
 };
@@ -77,32 +79,26 @@
     return sem;
 }
 
-static unsigned int release_semaphore( obj_handle_t handle, unsigned int count )
+static int release_semaphore( struct semaphore *sem, unsigned int count,
+                              unsigned int *prev )
 {
-    struct semaphore *sem;
-    unsigned int prev = 0;
-
-    if ((sem = (struct semaphore *)get_handle_obj( current->process, handle,
-                                                   SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
+    if (prev) *prev = sem->count;
+    if (sem->count + count < sem->count || sem->count + count > sem->max)
     {
-        prev = sem->count;
-        if (sem->count + count < sem->count || sem->count + count > sem->max)
-        {
-            set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
-        }
-        else if (sem->count)
-        {
-            /* there cannot be any thread to wake up if the count is != 0 */
-            sem->count += count;
-        }
-        else
-        {
-            sem->count = count;
-            wake_up( &sem->obj, count );
-        }
-        release_object( sem );
+        set_error( STATUS_SEMAPHORE_LIMIT_EXCEEDED );
+        return 0;
     }
-    return prev;
+    else if (sem->count)
+    {
+        /* there cannot be any thread to wake up if the count is != 0 */
+        sem->count += count;
+    }
+    else
+    {
+        sem->count = count;
+        wake_up( &sem->obj, count );
+    }
+    return 1;
 }
 
 static void semaphore_dump( struct object *obj, int verbose )
@@ -130,6 +126,19 @@
     return 0;  /* not abandoned */
 }
 
+static int semaphore_signal( struct object *obj, unsigned int access )
+{
+    struct semaphore *sem = (struct semaphore *)obj;
+    assert( obj->ops == &semaphore_ops );
+
+    if (!(access & SEMAPHORE_MODIFY_STATE))
+    {
+        set_error( STATUS_ACCESS_DENIED );
+        return 0;
+    }
+    return release_semaphore( sem, 1, NULL );
+}
+
 /* create a semaphore */
 DECL_HANDLER(create_semaphore)
 {
@@ -154,5 +163,12 @@
 /* release a semaphore */
 DECL_HANDLER(release_semaphore)
 {
-    reply->prev_count = release_semaphore( req->handle, req->count );
+    struct semaphore *sem;
+
+    if ((sem = (struct semaphore *)get_handle_obj( current->process, req->handle,
+                                                   SEMAPHORE_MODIFY_STATE, &semaphore_ops )))
+    {
+        release_semaphore( sem, req->count, &reply->prev_count );
+        release_object( sem );
+    }
 }