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