Implement NtQueryTimer.

diff --git a/server/protocol.def b/server/protocol.def
index 5423b7c..0cfd8c5 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1378,6 +1378,14 @@
      int         signaled;      /* was the timer signaled before this calltime ? */
 @END
 
+/* Get information on a waitable timer */
+@REQ(get_timer_info)
+    obj_handle_t handle;        /* handle to the timer */
+@REPLY
+    abs_time_t   when;          /* absolute time when the timer next expires */
+    int          signaled;      /* is the timer signaled? */
+@END
+
 
 /* Retrieve the current context of a thread */
 @REQ(get_thread_context)
diff --git a/server/request.h b/server/request.h
index d4ceb24..0a2319f 100644
--- a/server/request.h
+++ b/server/request.h
@@ -209,6 +209,7 @@
 DECL_HANDLER(open_timer);
 DECL_HANDLER(set_timer);
 DECL_HANDLER(cancel_timer);
+DECL_HANDLER(get_timer_info);
 DECL_HANDLER(get_thread_context);
 DECL_HANDLER(set_thread_context);
 DECL_HANDLER(get_selector_entry);
@@ -393,6 +394,7 @@
     (req_handler)req_open_timer,
     (req_handler)req_set_timer,
     (req_handler)req_cancel_timer,
+    (req_handler)req_get_timer_info,
     (req_handler)req_get_thread_context,
     (req_handler)req_set_thread_context,
     (req_handler)req_get_selector_entry,
diff --git a/server/timer.c b/server/timer.c
index ef07f2a..1903ba7 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -241,3 +241,18 @@
         release_object( timer );
     }
 }
+
+/* Get information on a waitable timer */
+DECL_HANDLER(get_timer_info)
+{
+    struct timer *timer;
+
+    if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
+                                                 TIMER_QUERY_STATE, &timer_ops )))
+    {
+        reply->when.sec  = timer->when.tv_sec;
+        reply->when.usec = timer->when.tv_usec;
+        reply->signaled  = timer->signaled;
+        release_object( timer );
+    }
+}
diff --git a/server/trace.c b/server/trace.c
index daafbf5..bcba1d1 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1692,6 +1692,19 @@
     fprintf( stderr, " signaled=%d", req->signaled );
 }
 
+static void dump_get_timer_info_request( const struct get_timer_info_request *req )
+{
+    fprintf( stderr, " handle=%p", req->handle );
+}
+
+static void dump_get_timer_info_reply( const struct get_timer_info_reply *req )
+{
+    fprintf( stderr, " when=" );
+    dump_abs_time( &req->when );
+    fprintf( stderr, "," );
+    fprintf( stderr, " signaled=%d", req->signaled );
+}
+
 static void dump_get_thread_context_request( const struct get_thread_context_request *req )
 {
     fprintf( stderr, " handle=%p,", req->handle );
@@ -2695,6 +2708,7 @@
     (dump_func)dump_open_timer_request,
     (dump_func)dump_set_timer_request,
     (dump_func)dump_cancel_timer_request,
+    (dump_func)dump_get_timer_info_request,
     (dump_func)dump_get_thread_context_request,
     (dump_func)dump_set_thread_context_request,
     (dump_func)dump_get_selector_entry_request,
@@ -2876,6 +2890,7 @@
     (dump_func)dump_open_timer_reply,
     (dump_func)dump_set_timer_reply,
     (dump_func)dump_cancel_timer_reply,
+    (dump_func)dump_get_timer_info_reply,
     (dump_func)dump_get_thread_context_reply,
     (dump_func)0,
     (dump_func)dump_get_selector_entry_reply,
@@ -3057,6 +3072,7 @@
     "open_timer",
     "set_timer",
     "cancel_timer",
+    "get_timer_info",
     "get_thread_context",
     "set_thread_context",
     "get_selector_entry",