ntdll: Implement NtQuerySemaphore/SemaphoreBasicInformation.

Dmitry Timoshkov dmitry at baikal.ru
Tue Dec 24 22:28:36 CST 2013


---
 dlls/ntdll/sync.c   | 35 ++++++++++++++++++++++++++---------
 include/winnt.h     |  1 +
 server/protocol.def |  6 ++++++
 server/semaphore.c  | 14 ++++++++++++++
 4 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
index af1dba9..b05bd19 100644
--- a/dlls/ntdll/sync.c
+++ b/dlls/ntdll/sync.c
@@ -211,16 +211,33 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle,
 /******************************************************************************
  *  NtQuerySemaphore (NTDLL.@)
  */
-NTSTATUS WINAPI NtQuerySemaphore(
-	HANDLE SemaphoreHandle,
-	SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
-	PVOID SemaphoreInformation,
-	ULONG Length,
-	PULONG ReturnLength)
+NTSTATUS WINAPI NtQuerySemaphore( HANDLE handle, SEMAPHORE_INFORMATION_CLASS class,
+                                  void *info, ULONG len, ULONG *ret_len )
 {
-	FIXME("(%p,%d,%p,0x%08x,%p) stub!\n",
-	SemaphoreHandle, SemaphoreInformationClass, SemaphoreInformation, Length, ReturnLength);
-	return STATUS_SUCCESS;
+    NTSTATUS ret;
+    SEMAPHORE_BASIC_INFORMATION *out = info;
+
+    if (class != SemaphoreBasicInformation)
+    {
+        FIXME("(%p,%d,%u) Unknown class\n", handle, class, len);
+        return STATUS_INVALID_INFO_CLASS;
+    }
+
+    if (len != sizeof(SEMAPHORE_BASIC_INFORMATION)) return STATUS_INFO_LENGTH_MISMATCH;
+
+    SERVER_START_REQ( query_semaphore )
+    {
+        req->handle = wine_server_obj_handle( handle );
+        if (!(ret = wine_server_call( req )))
+        {
+            out->CurrentCount = reply->current;
+            out->MaximumCount = reply->max;
+            if (ret_len) *ret_len = sizeof(SEMAPHORE_BASIC_INFORMATION);
+        }
+    }
+    SERVER_END_REQ;
+
+    return ret;
 }
 
 /******************************************************************************
diff --git a/include/winnt.h b/include/winnt.h
index f1751a5..f55f2fe 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -4512,6 +4512,7 @@ typedef enum tagSID_NAME_USE {
 #define EVENT_MODIFY_STATE         0x0002
 #define EVENT_ALL_ACCESS           (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
 
+#define SEMAPHORE_QUERY_STATE      0x0001
 #define SEMAPHORE_MODIFY_STATE     0x0002
 #define SEMAPHORE_ALL_ACCESS       (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
 
diff --git a/server/protocol.def b/server/protocol.def
index 8c5f953..fec5e75 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1072,6 +1072,12 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
     unsigned int prev_count;    /* previous semaphore count */
 @END
 
+ at REQ(query_semaphore)
+    obj_handle_t handle;       /* handle to the semaphore */
+ at REPLY
+    unsigned int current;      /* current count */
+    unsigned int max;          /* maximum count */
+ at END
 
 /* Open a semaphore */
 @REQ(open_semaphore)
diff --git a/server/semaphore.c b/server/semaphore.c
index 109eb9a..b2c6911 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -237,3 +237,17 @@ DECL_HANDLER(release_semaphore)
         release_object( sem );
     }
 }
+
+/* query details about the semaphore */
+DECL_HANDLER(query_semaphore)
+{
+    struct semaphore *sem;
+
+    if ((sem = get_handle_obj( current->process, req->handle,
+                               SEMAPHORE_QUERY_STATE, &semaphore_ops )))
+    {
+        reply->current = sem->count;
+        reply->max = sem->max;
+        release_object( sem );
+    }
+}
-- 
1.8.5.1




More information about the wine-patches mailing list