Rob Shearman : server: Add get_token_statistics server call and use it to implement the TokenStatistics and TokenType levels for NtQueryInformationToken .

Alexandre Julliard julliard at winehq.org
Fri Sep 14 10:16:00 CDT 2007


Module: wine
Branch: master
Commit: 3f431a0646c6bfb333971afcfe0dfeab71a90d3b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=3f431a0646c6bfb333971afcfe0dfeab71a90d3b

Author: Rob Shearman <rob at codeweavers.com>
Date:   Thu Sep 13 16:47:56 2007 +0100

server: Add get_token_statistics server call and use it to implement the TokenStatistics and TokenType levels for NtQueryInformationToken.

---

 dlls/kernel32/tests/pipe.c     |    1 -
 dlls/ntdll/nt.c                |   44 ++++++++++++++++++++++++++++++++++++++-
 include/wine/server_protocol.h |   23 ++++++++++++++++++++-
 server/protocol.def            |   13 +++++++++++
 server/request.h               |    2 +
 server/token.c                 |   19 +++++++++++++++++
 server/trace.c                 |   23 ++++++++++++++++++++
 7 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c
index 09f406e..9150e50 100644
--- a/dlls/kernel32/tests/pipe.c
+++ b/dlls/kernel32/tests/pipe.c
@@ -1048,7 +1048,6 @@ static DWORD get_privilege_count(HANDLE hToken)
     BOOL ret;
 
     ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size);
-    todo_wine
     ok(ret, "GetTokenInformation(TokenStatistics)\n");
     if (!ret) return -1;
 
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 27a18ef..8354fee 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -230,9 +230,9 @@ NTSTATUS WINAPI NtQueryInformationToken(
     case TokenImpersonationLevel:
         len = sizeof(SECURITY_IMPERSONATION_LEVEL);
         break;
-#if 0
     case TokenStatistics:
-#endif /* 0 */
+        len = sizeof(TOKEN_STATISTICS);
+        break;
     default:
         len = 0;
     }
@@ -375,6 +375,46 @@ NTSTATUS WINAPI NtQueryInformationToken(
         }
         SERVER_END_REQ;
         break;
+    case TokenStatistics:
+        SERVER_START_REQ( get_token_statistics )
+        {
+            TOKEN_STATISTICS *statistics = tokeninfo;
+            req->handle = token;
+            status = wine_server_call( req );
+            if (status == STATUS_SUCCESS)
+            {
+                statistics->TokenId.LowPart  = reply->token_id.low_part;
+                statistics->TokenId.HighPart = reply->token_id.high_part;
+                statistics->AuthenticationId.LowPart  = 0; /* FIXME */
+                statistics->AuthenticationId.HighPart = 0; /* FIXME */
+                statistics->ExpirationTime.HighPart = 0x7fffffff;
+                statistics->ExpirationTime.LowPart  = 0xffffffff;
+                statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
+                statistics->ImpersonationLevel = reply->impersonation_level;
+
+                /* kernel information not relevant to us */
+                statistics->DynamicCharged = 0;
+                statistics->DynamicAvailable = 0;
+
+                statistics->GroupCount = reply->group_count;
+                statistics->PrivilegeCount = reply->privilege_count;
+                statistics->ModifiedId.LowPart  = reply->modified_id.low_part;
+                statistics->ModifiedId.HighPart = reply->modified_id.high_part;
+            }
+        }
+        SERVER_END_REQ;
+        break;
+    case TokenType:
+        SERVER_START_REQ( get_token_statistics )
+        {
+            TOKEN_TYPE *token_type = tokeninfo;
+            req->handle = token;
+            status = wine_server_call( req );
+            if (status == STATUS_SUCCESS)
+                *token_type = reply->primary ? TokenPrimary : TokenImpersonation;
+        }
+        SERVER_END_REQ;
+        break;
     default:
         {
             ERR("Unhandled Token Information class %d!\n", tokeninfoclass);
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index b1f48cb..b79fda4 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4060,6 +4060,24 @@ struct make_process_system_reply
 };
 
 
+
+struct get_token_statistics_request
+{
+    struct request_header __header;
+    obj_handle_t   handle;
+};
+struct get_token_statistics_reply
+{
+    struct reply_header __header;
+    luid_t         token_id;
+    luid_t         modified_id;
+    int            primary;
+    int            impersonation_level;
+    int            group_count;
+    int            privilege_count;
+};
+
+
 enum request
 {
     REQ_new_process,
@@ -4281,6 +4299,7 @@ enum request
     REQ_delete_device,
     REQ_get_next_device_request,
     REQ_make_process_system,
+    REQ_get_token_statistics,
     REQ_NB_REQUESTS
 };
 
@@ -4507,6 +4526,7 @@ union generic_request
     struct delete_device_request delete_device_request;
     struct get_next_device_request_request get_next_device_request_request;
     struct make_process_system_request make_process_system_request;
+    struct get_token_statistics_request get_token_statistics_request;
 };
 union generic_reply
 {
@@ -4731,8 +4751,9 @@ union generic_reply
     struct delete_device_reply delete_device_reply;
     struct get_next_device_request_reply get_next_device_request_reply;
     struct make_process_system_reply make_process_system_reply;
+    struct get_token_statistics_reply get_token_statistics_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 312
+#define SERVER_PROTOCOL_VERSION 313
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def
index e210e43..784a9f9 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2918,3 +2918,16 @@ enum message_type
 @REPLY
     obj_handle_t event;           /* event signaled when all user processes have exited */
 @END
+
+
+/* Get detailed fixed-size information about a token */
+ at REQ(get_token_statistics)
+    obj_handle_t   handle;        /* handle to the object */
+ at REPLY
+    luid_t         token_id;      /* locally-unique identifier of the token */
+    luid_t         modified_id;   /* locally-unique identifier of the modified version of the token */
+    int            primary;       /* is the token primary or impersonation? */
+    int            impersonation_level; /* level of impersonation */
+    int            group_count;   /* the number of groups the token is a member of */
+    int            privilege_count; /* the number of privileges the token has */
+ at END
diff --git a/server/request.h b/server/request.h
index 12a7b9c..fe94d2e 100644
--- a/server/request.h
+++ b/server/request.h
@@ -329,6 +329,7 @@ DECL_HANDLER(create_device);
 DECL_HANDLER(delete_device);
 DECL_HANDLER(get_next_device_request);
 DECL_HANDLER(make_process_system);
+DECL_HANDLER(get_token_statistics);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -554,6 +555,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
     (req_handler)req_delete_device,
     (req_handler)req_get_next_device_request,
     (req_handler)req_make_process_system,
+    (req_handler)req_get_token_statistics,
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/token.c b/server/token.c
index a97fbde..655e597 100644
--- a/server/token.c
+++ b/server/token.c
@@ -1424,6 +1424,25 @@ DECL_HANDLER(get_token_impersonation_level)
     }
 }
 
+DECL_HANDLER(get_token_statistics)
+{
+    struct token *token;
+
+    if ((token = (struct token *)get_handle_obj( current->process, req->handle,
+                                                 TOKEN_QUERY,
+                                                 &token_ops )))
+    {
+        reply->token_id = token->token_id;
+        reply->modified_id = token->modified_id;
+        reply->primary = token->primary;
+        reply->impersonation_level = token->impersonation_level;
+        reply->group_count = list_count( &token->groups );
+        reply->privilege_count = list_count( &token->privileges );
+
+        release_object( token );
+    }
+}
+
 DECL_HANDLER(set_security_object)
 {
     data_size_t sd_size = get_req_data_size();
diff --git a/server/trace.c b/server/trace.c
index 49f4479..e6ff06d 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3548,6 +3548,25 @@ static void dump_make_process_system_reply( const struct make_process_system_rep
     fprintf( stderr, " event=%p", req->event );
 }
 
+static void dump_get_token_statistics_request( const struct get_token_statistics_request *req )
+{
+    fprintf( stderr, " handle=%p", req->handle );
+}
+
+static void dump_get_token_statistics_reply( const struct get_token_statistics_reply *req )
+{
+    fprintf( stderr, " token_id=" );
+    dump_luid( &req->token_id );
+    fprintf( stderr, "," );
+    fprintf( stderr, " modified_id=" );
+    dump_luid( &req->modified_id );
+    fprintf( stderr, "," );
+    fprintf( stderr, " primary=%d,", req->primary );
+    fprintf( stderr, " impersonation_level=%d,", req->impersonation_level );
+    fprintf( stderr, " group_count=%d,", req->group_count );
+    fprintf( stderr, " privilege_count=%d", req->privilege_count );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_get_new_process_info_request,
@@ -3768,6 +3787,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_delete_device_request,
     (dump_func)dump_get_next_device_request_request,
     (dump_func)dump_make_process_system_request,
+    (dump_func)dump_get_token_statistics_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -3990,6 +4010,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)0,
     (dump_func)dump_get_next_device_request_reply,
     (dump_func)dump_make_process_system_reply,
+    (dump_func)dump_get_token_statistics_reply,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -4212,6 +4233,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
     "delete_device",
     "get_next_device_request",
     "make_process_system",
+    "get_token_statistics",
 };
 
 static const struct
@@ -4233,6 +4255,7 @@ static const struct
     { "CANCELLED",                   STATUS_CANCELLED },
     { "CANT_OPEN_ANONYMOUS",         STATUS_CANT_OPEN_ANONYMOUS },
     { "CHILD_MUST_BE_VOLATILE",      STATUS_CHILD_MUST_BE_VOLATILE },
+    { "DEBUGGER_INACTIVE",           STATUS_DEBUGGER_INACTIVE },
     { "DEVICE_BUSY",                 STATUS_DEVICE_BUSY },
     { "DIRECTORY_NOT_EMPTY",         STATUS_DIRECTORY_NOT_EMPTY },
     { "DISK_FULL",                   STATUS_DISK_FULL },




More information about the wine-cvs mailing list