Files
hfiref0x d8b2cc3d1b 2.0.9
Small fixes and internal rearrange
2025-08-22 18:18:06 +07:00

888 lines
25 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2019 - 2025
*
* TITLE: PROPTOKEN.C
*
* VERSION: 2.09
*
* DATE: 21 Aug 2025
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
* ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
* PARTICULAR PURPOSE.
*
*******************************************************************************/
#include "global.h"
#include "propDlg.h"
#define T_TOKEN_PROP_CID_PID TEXT("propTokenPid")
#define T_TOKEN_PROP_CID_TID TEXT("propTokenTid")
#define T_TOKEN_PROP_TYPE TEXT("propTokenType")
//
// Small context for this dialog.
//
typedef struct _TOKEN_PAGE_CONTEXT {
HWND hwndList;
INT lvSelectedItem;
INT lvColumnHit;
} TOKEN_PAGE_CONTEXT, * PTOKEN_PAGE_CONTEXT;
static PTOKEN_PAGE_CONTEXT TokenPageGetContext(
_In_ HWND hwndDlg
)
{
return (PTOKEN_PAGE_CONTEXT)GetProp(hwndDlg, T_DLGCONTEXT);
}
/*
* TokenPageShowError
*
* Purpose:
*
* Hide all windows for given hwnd and display error text with custom text if specified.
*
*/
VOID TokenPageShowError(
_In_ HWND hwndDlg,
_In_opt_ LPWSTR lpMessageText
)
{
ENUMCHILDWNDDATA ChildWndData;
if (GetWindowRect(hwndDlg, &ChildWndData.Rect)) {
ChildWndData.nCmdShow = SW_HIDE;
EnumChildWindows(hwndDlg, supCallbackShowChildWindow, (LPARAM)&ChildWndData);
}
if (lpMessageText) {
SetDlgItemText(hwndDlg, IDC_TOKEN_ERROR, lpMessageText);
}
ShowWindow(GetDlgItem(hwndDlg, IDC_TOKEN_ERROR), SW_SHOW);
}
/*
* TokenPageInitControls
*
* Purpose:
*
* Initialize page controls.
*
*/
VOID TokenPageInitControls(
_In_ HWND hwndDlg,
_In_ BOOLEAN IsAppContainer
)
{
LVGROUP lvg;
PTOKEN_PAGE_CONTEXT pCtx;
pCtx = TokenPageGetContext(hwndDlg);
if (pCtx == NULL) {
return;
}
pCtx->hwndList = GetDlgItem(hwndDlg, IDC_TOKEN_PRIVLIST);
pCtx->lvSelectedItem = -1;
pCtx->lvColumnHit = -1;
//
// Set listview style flags and theme.
//
supSetListViewSettings(pCtx->hwndList,
LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_LABELTIP,
FALSE,
TRUE,
NULL,
0);
SendMessage(pCtx->hwndList, LVM_ENABLEGROUPVIEW, 1, 0);
supAddListViewColumn(pCtx->hwndList, 0, 0, 0,
I_IMAGENONE,
LVCFMT_LEFT,
TEXT("Name"), 400);
supAddListViewColumn(pCtx->hwndList, 1, 1, 1,
I_IMAGENONE,
LVCFMT_LEFT,
TEXT("Status"), 150);
RtlSecureZeroMemory(&lvg, sizeof(lvg));
lvg.cbSize = sizeof(LVGROUP);
lvg.mask = LVGF_HEADER | LVGF_ALIGN | LVGF_GROUPID;
lvg.uAlign = LVGA_HEADER_LEFT;
lvg.pszHeader = TEXT("Privileges");
lvg.cchHeader = (INT)_strlen(lvg.pszHeader);
lvg.iGroupId = 0;
SendMessage(pCtx->hwndList, LVM_INSERTGROUP, (WPARAM)0, (LPARAM)&lvg);
lvg.pszHeader = TEXT("Groups");
lvg.cchHeader = (INT)_strlen(lvg.pszHeader);
lvg.iGroupId = 1;
SendMessage(pCtx->hwndList, LVM_INSERTGROUP, (WPARAM)1, (LPARAM)&lvg);
if (IsAppContainer) {
lvg.pszHeader = TEXT("Capabilities");
lvg.cchHeader = (INT)_strlen(lvg.pszHeader);
lvg.iGroupId = 2;
SendMessage(pCtx->hwndList, LVM_INSERTGROUP, (WPARAM)2, (LPARAM)&lvg);
}
SetDlgItemText(hwndDlg, IDC_TOKEN_USER, T_CannotQuery);
SetDlgItemText(hwndDlg, IDC_TOKEN_SID, T_CannotQuery);
SetDlgItemText(hwndDlg, IDC_TOKEN_APPCONTAINER, T_CannotQuery);
}
/*
* TokenPageListAdd
*
* Purpose:
*
* Add item to page listview.
*
*/
VOID TokenPageListAdd(
_In_ INT GroupIndex,
_In_ LPWSTR lpName,
_In_ LPWSTR lpStatus,
_In_ HWND hwndDlg
)
{
INT nIndex;
LVITEM lvitem;
PTOKEN_PAGE_CONTEXT pCtx;
pCtx = TokenPageGetContext(hwndDlg);
if (pCtx == NULL)
return;
RtlSecureZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_TEXT | LVIF_GROUPID;
lvitem.pszText = lpName;
lvitem.iItem = MAXINT;
lvitem.iGroupId = GroupIndex;
nIndex = ListView_InsertItem(pCtx->hwndList, &lvitem);
if (nIndex == -1) { // insertion failed
return;
}
lvitem.mask = LVIF_TEXT;
lvitem.iSubItem = 1;
lvitem.pszText = lpStatus;
lvitem.iItem = nIndex;
ListView_SetItem(pCtx->hwndList, &lvitem);
}
/*
* TokenPageListInfo
*
* Purpose:
*
* Query and list token information.
*
*/
VOID TokenPageListInfo(
_In_ PROP_OBJECT_INFO* Context,
_In_ HWND hwndDlg
)
{
BOOLEAN IsAppContainer = FALSE;
ULONG i, cchName, r;
NTSTATUS Status;
LPWSTR ErrMsg = NULL, ElementName, UserAndDomain, pString;
HANDLE ObjectHandle = NULL;
HANDLE TokenHandle = NULL, LinkedTokenHandle = NULL;
ACCESS_MASK DesiredAccessLv1, DesiredAccessLv2;
PTOKEN_PRIVILEGES pTokenPrivs;
PTOKEN_USER pTokenUser;
PTOKEN_MANDATORY_LABEL pTokenIntegrity;
PTOKEN_GROUPS pTokenGroups;
PTOKEN_APPCONTAINER_INFORMATION pTokenAppContainer;
TOKEN_ELEVATION TokenElv;
TOKEN_ELEVATION_TYPE TokenElevType;
TOKEN_STATISTICS TokenStats;
WCHAR szBuffer[MAX_PATH], szPrivName[MAX_PATH + 1];
if (Context->ObjectTypeIndex == ObjectTypeProcess) {
DesiredAccessLv1 = PROCESS_QUERY_INFORMATION;
DesiredAccessLv2 = PROCESS_QUERY_LIMITED_INFORMATION;
}
else {
DesiredAccessLv1 = THREAD_QUERY_INFORMATION;
DesiredAccessLv2 = THREAD_QUERY_LIMITED_INFORMATION;
}
if (!propOpenCurrentObject(Context, &ObjectHandle, MAXIMUM_ALLOWED)) {
if (!propOpenCurrentObject(Context, &ObjectHandle, DesiredAccessLv1)) {
propOpenCurrentObject(Context, &ObjectHandle, DesiredAccessLv2);
}
}
if (ObjectHandle == NULL) {
TokenPageShowError(hwndDlg, NULL);
return;
}
if (Context->ObjectTypeIndex == ObjectTypeProcess) {
Status = supOpenProcessTokenEx(ObjectHandle, &TokenHandle);
if (!NT_SUCCESS(Status))
Status = NtOpenProcessToken(ObjectHandle, TOKEN_QUERY, &TokenHandle);
}
else {
Status = NtOpenThreadToken(ObjectHandle, TOKEN_QUERY, TRUE, &TokenHandle);
}
if (NT_SUCCESS(Status) && TokenHandle != NULL) {
i = 0;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenIsAppContainer, (PVOID)&i, sizeof(ULONG), &r))) {
IsAppContainer = (i > 0);
}
TokenPageInitControls(hwndDlg, IsAppContainer);
//
// List token privileges.
//
pTokenPrivs = (PTOKEN_PRIVILEGES)supGetTokenInfo(TokenHandle, TokenPrivileges, NULL);
if (pTokenPrivs) {
for (i = 0; i < pTokenPrivs->PrivilegeCount; i++) {
//
// Output privilege flags like Process Explorer.
//
szPrivName[0] = 0;
cchName = MAX_PATH;
if (LookupPrivilegeName(NULL, &pTokenPrivs->Privileges[i].Luid,
szPrivName, &cchName))
{
ElementName = TEXT("Disabled");
if (pTokenPrivs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED) {
ElementName = TEXT("Enabled");
}
_strcpy(szBuffer, ElementName);
if (pTokenPrivs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT) {
_strcat(szBuffer, TEXT(", Default Enabled"));
}
TokenPageListAdd(0, szPrivName, szBuffer, hwndDlg);
}
}
supHeapFree(pTokenPrivs);
}
//
// List token groups.
//
pTokenGroups = (PTOKEN_GROUPS)supGetTokenInfo(TokenHandle, TokenGroups, NULL);
if (pTokenGroups) {
for (i = 0; i < pTokenGroups->GroupCount; i++) {
UserAndDomain = NULL;
if (supLookupSidUserAndDomain(pTokenGroups->Groups[i].Sid, &UserAndDomain)) {
r = pTokenGroups->Groups[i].Attributes;
pString = NULL;
szBuffer[0] = 0;
if (r & SE_GROUP_USE_FOR_DENY_ONLY)
pString = _strcpy(szBuffer, TEXT("Deny"));
if (r & SE_GROUP_RESOURCE) {
if (pString)
_strcat(szBuffer, TEXT(", "));
pString = _strcat(szBuffer, TEXT("Domain-Local"));
}
if ((r & SE_GROUP_MANDATORY) && (!(r & SE_GROUP_OWNER))) {
if (pString)
_strcat(szBuffer, TEXT(", "));
pString = _strcat(szBuffer, TEXT("Mandatory"));
}
if (r & SE_GROUP_OWNER) {
if (pString)
_strcat(szBuffer, TEXT(", "));
pString = _strcat(szBuffer, TEXT("Owner"));
}
if (r & SE_GROUP_INTEGRITY) {
if (pString)
_strcat(szBuffer, TEXT(", "));
ElementName = TEXT("Integrity");
if (!(r & SE_GROUP_INTEGRITY_ENABLED)) {
ElementName = TEXT("DesktopIntegrity");
}
_strcat(szBuffer, ElementName);
}
TokenPageListAdd(1, UserAndDomain, szBuffer, hwndDlg);
supHeapFree(UserAndDomain);
}
}
supHeapFree(pTokenGroups);
}
//
// Token elevated.
//
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenElevation,
(PVOID)&TokenElv, sizeof(TokenElv), &r)))
{
if (TokenElv.TokenIsElevated) {
_strcpy(szBuffer, TEXT("Yes"));
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenElevationType,
&TokenElevType, sizeof(TokenElevType), &r)))
{
switch (TokenElevType) {
case TokenElevationTypeDefault:
_strcat(szBuffer, TEXT(" (Default)")); // User is not using a split token, so they cannot elevate.
break;
case TokenElevationTypeFull: // User has a split token, and the process is running elevated.
_strcat(szBuffer, TEXT(" (Full)"));
break;
case TokenElevationTypeLimited: // User has a split token, but the process is not running elevated.
_strcat(szBuffer, TEXT(" (Limited)"));
break;
default:
_strcat(szBuffer, TEXT(" (Unknown)"));
break;
}
}
}
else
_strcpy(szBuffer, TEXT("No"));
SetDlgItemText(hwndDlg, IDC_TOKEN_ELEVATED, szBuffer);
}
//
// Token virtualization.
//
i = 0;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenVirtualizationAllowed,
(PVOID)&i, sizeof(i), &r)))
{
if (i > 0) {
i = 0;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenVirtualizationEnabled,
(PVOID)&i, sizeof(i), &r)))
{
ElementName = (i > 0) ? TEXT("Yes") : TEXT("No");
SetDlgItemText(hwndDlg, IDC_TOKEN_VIRTUALIZED, ElementName);
}
}
}
else {
SetDlgItemText(hwndDlg, IDC_TOKEN_VIRTUALIZED, TEXT("Not allowed"));
}
//
// Token integrity level.
//
pTokenIntegrity = (PTOKEN_MANDATORY_LABEL)supGetTokenInfo(TokenHandle, TokenIntegrityLevel, NULL);
if (pTokenIntegrity) {
i = *RtlSubAuthoritySid(pTokenIntegrity->Label.Sid,
(DWORD)(UCHAR)(*RtlSubAuthorityCountSid(pTokenIntegrity->Label.Sid) - 1));
ElementName = supIntegrityToString(i);
SetDlgItemText(hwndDlg, IDC_TOKEN_INTEGRITYLEVEL, ElementName);
supHeapFree(pTokenIntegrity);
}
//
// Token session id.
//
i = 0;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenSessionId,
(PVOID)&i, sizeof(i), &r)))
{
szBuffer[0] = 0;
ultostr(i, szBuffer);
SetDlgItemText(hwndDlg, IDC_TOKEN_SESSION, szBuffer);
}
//
// Token user.
//
pTokenUser = (PTOKEN_USER)supGetTokenInfo(TokenHandle, TokenUser, NULL);
if (pTokenUser) {
ElementName = NULL;
if (ConvertSidToStringSid(pTokenUser->User.Sid, &ElementName)) {
SetDlgItemText(hwndDlg, IDC_TOKEN_SID, ElementName);
LocalFree(ElementName);
}
ElementName = NULL;
if (supLookupSidUserAndDomain(pTokenUser->User.Sid, &ElementName)) {
SetDlgItemText(hwndDlg, IDC_TOKEN_USER, ElementName);
supHeapFree(ElementName);
}
supHeapFree(pTokenUser);
}
//
// AppContainer related.
//
if (IsAppContainer) {
//
// Token AppContainer SID.
//
pTokenAppContainer = (PTOKEN_APPCONTAINER_INFORMATION)supGetTokenInfo(TokenHandle, TokenAppContainerSid, NULL);
if (pTokenAppContainer) {
ElementName = NULL;
if (pTokenAppContainer->TokenAppContainer) {
if (ConvertSidToStringSid(pTokenAppContainer->TokenAppContainer, &ElementName)) {
SetDlgItemText(hwndDlg, IDC_TOKEN_APPCONTAINER, ElementName);
LocalFree(ElementName);
}
}
supHeapFree(pTokenAppContainer);
}
pTokenGroups = (PTOKEN_GROUPS)supGetTokenInfo(TokenHandle, TokenCapabilities, NULL);
if (pTokenGroups) {
for (i = 0; i < pTokenGroups->GroupCount; i++) {
if (pTokenGroups->Groups[i].Sid) {
ElementName = NULL;
if (ConvertSidToStringSid(pTokenGroups->Groups[i].Sid, &ElementName)) {
TokenPageListAdd(2, ElementName, TEXT("Capabilities"), hwndDlg);
LocalFree(ElementName);
}
}
}
supHeapFree(pTokenGroups);
}
}
//
// UIAccess
//
i = 0;
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenUIAccess,
(PVOID)&i, sizeof(i), &r)))
{
ElementName = (i > 0) ? TEXT("Yes") : TEXT("No");
SetDlgItemText(hwndDlg, IDC_TOKEN_UIACCESS, ElementName);
}
if (NT_SUCCESS(NtQueryInformationToken(TokenHandle, TokenStatistics,
(PVOID)&TokenStats, sizeof(TOKEN_STATISTICS), &r)))
{
szBuffer[0] = 0;
RtlStringCchPrintfSecure(szBuffer, MAX_PATH, L"0x%x-%x$",
TokenStats.AuthenticationId.HighPart,
TokenStats.AuthenticationId.LowPart);
SetDlgItemText(hwndDlg, IDC_TOKEN_AUTHID, szBuffer);
}
//
// Linked token.
//
Status = supOpenLinkedToken(TokenHandle, &LinkedTokenHandle);
if (NT_SUCCESS(Status)) NtClose(LinkedTokenHandle);
EnableWindow(GetDlgItem(hwndDlg, IDC_TOKEN_LINKED), NT_SUCCESS(Status));
NtClose(TokenHandle);
}
else {
if (Status == STATUS_NO_TOKEN)
ErrMsg = TEXT("Token doesn't exist, thread is not impersonating a client.");
TokenPageShowError(hwndDlg, ErrMsg);
}
NtClose(ObjectHandle);
}
/*
* TokenPageShowLinkedTokenProperties
*
* Purpose:
*
* Show properties of selected linked token object.
*
*/
VOID TokenPageShowLinkedTokenProperties(
_In_ HWND hwndDlg
)
{
NTSTATUS Status;
HANDLE TokenHandle, LinkedTokenHandle;
PROP_UNNAMED_OBJECT_INFO TokenObject, LinkedTokenObject;
OBJECT_ATTRIBUTES ObjectAttributes = RTL_INIT_OBJECT_ATTRIBUTES((PUNICODE_STRING)NULL, 0);
LPWSTR FormatStringLinkedTokenProcess = TEXT("Linked Token, PID:%llu");
UNICODE_STRING usObjectName;
PROP_CONFIG propConfig;
WCHAR szBuffer[MAX_PATH + 1];
RtlSecureZeroMemory(&TokenObject, sizeof(PROP_UNNAMED_OBJECT_INFO));
TokenObject.ClientId.UniqueProcess =
GetProp(hwndDlg, T_TOKEN_PROP_CID_PID);
TokenObject.ClientId.UniqueThread =
GetProp(hwndDlg, T_TOKEN_PROP_CID_TID);
TokenObject.IsThreadToken =
(BOOL)HandleToULong(GetProp(hwndDlg, T_TOKEN_PROP_TYPE));
Status = supOpenTokenByParam(&TokenObject.ClientId,
&ObjectAttributes,
TOKEN_QUERY,
TokenObject.IsThreadToken,
&TokenHandle);
if (NT_SUCCESS(Status)) {
Status = supOpenLinkedToken(TokenHandle, &LinkedTokenHandle);
if (NT_SUCCESS(Status)) {
RtlSecureZeroMemory(&LinkedTokenObject, sizeof(LinkedTokenObject));
LinkedTokenObject.ClientId = TokenObject.ClientId;
supQueryObjectFromHandle(LinkedTokenHandle, &LinkedTokenObject.ObjectAddress, NULL);
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
RtlStringCchPrintfSecure(szBuffer,
MAX_PATH,
FormatStringLinkedTokenProcess,
LinkedTokenObject.ClientId.UniqueProcess);
RtlInitUnicodeString(&usObjectName, szBuffer);
RtlSecureZeroMemory(&propConfig, sizeof(propConfig));
propConfig.hwndParent = hwndDlg;
propConfig.NtObjectName = &usObjectName;
propConfig.ObjectTypeIndex = ObjectTypeToken;
propConfig.ContextType = propUnnamed;
propConfig.u1.UnnamedObject = &LinkedTokenObject;
propCreateDialog(&propConfig);
NtClose(LinkedTokenHandle);
}
else {
RtlStringCchPrintfSecure(szBuffer, MAX_PATH, TEXT("Unable to open linked token, NTSTATUS: 0x%lX"), Status);
TokenPageShowError(hwndDlg, szBuffer);
}
NtClose(TokenHandle);
}
else {
RtlStringCchPrintfSecure(szBuffer, MAX_PATH, TEXT("Unable to open token, NTSTATUS: 0x%lX"), Status);
TokenPageShowError(hwndDlg, szBuffer);
}
}
/*
* TokenPageShowAdvancedProperties
*
* Purpose:
*
* Show properties of selected token object.
*
*/
VOID TokenPageShowAdvancedProperties(
_In_ HWND hwndDlg)
{
OBJECT_ATTRIBUTES ObjectAttributes = RTL_INIT_OBJECT_ATTRIBUTES((PUNICODE_STRING)NULL, 0);
PROP_UNNAMED_OBJECT_INFO TokenObject;
PROP_CONFIG propConfig;
LPWSTR FormatStringTokenProcess = TEXT("Process Token, PID:%llu");
LPWSTR FormatStringTokenThread = TEXT("Thread Token, PID:%llu, TID:%llu");
HANDLE TokenHandle = NULL;
WCHAR szFakeName[MAX_PATH + 1];
UNICODE_STRING usObjectName;
//
// Only one token properties dialog at the same time allowed.
//
supCloseKnownPropertiesDialog(propGetTokenWindow());
RtlSecureZeroMemory(&TokenObject, sizeof(PROP_UNNAMED_OBJECT_INFO));
TokenObject.ClientId.UniqueProcess =
GetProp(hwndDlg, T_TOKEN_PROP_CID_PID);
TokenObject.ClientId.UniqueThread =
GetProp(hwndDlg, T_TOKEN_PROP_CID_TID);
TokenObject.IsThreadToken =
(BOOL)HandleToULong(GetProp(hwndDlg, T_TOKEN_PROP_TYPE));
RtlSecureZeroMemory(szFakeName, sizeof(szFakeName));
if (NT_SUCCESS(supOpenTokenByParam(&TokenObject.ClientId,
&ObjectAttributes,
TOKEN_QUERY,
TokenObject.IsThreadToken,
&TokenHandle)))
{
supQueryObjectFromHandle(TokenHandle, &TokenObject.ObjectAddress, NULL);
NtClose(TokenHandle);
}
RtlSecureZeroMemory(&propConfig, sizeof(propConfig));
if (TokenObject.IsThreadToken) {
RtlStringCchPrintfSecure(szFakeName,
MAX_PATH,
FormatStringTokenThread,
TokenObject.ClientId.UniqueProcess,
TokenObject.ClientId.UniqueThread);
}
else {
RtlStringCchPrintfSecure(szFakeName,
MAX_PATH,
FormatStringTokenProcess,
TokenObject.ClientId.UniqueProcess);
}
RtlInitUnicodeString(&usObjectName, szFakeName);
propConfig.hwndParent = hwndDlg;
propConfig.NtObjectName = &usObjectName;
propConfig.ObjectTypeIndex = ObjectTypeToken;
propConfig.ContextType = propUnnamed;
propConfig.u1.UnnamedObject = &TokenObject;
propCreateDialog(&propConfig);
}
/*
* TokenPageHandlePopup
*
* Purpose:
*
* Token page list popup construction.
*
*/
VOID TokenPageHandlePopup(
_In_ HWND hwndDlg,
_In_ LPPOINT lpPoint,
_In_ PVOID lpUserParam
)
{
HMENU hMenu;
PTOKEN_PAGE_CONTEXT pCtx;
UNREFERENCED_PARAMETER(lpUserParam);
pCtx = TokenPageGetContext(hwndDlg);
if (pCtx == NULL)
return;
hMenu = CreatePopupMenu();
if (hMenu) {
if (supListViewAddCopyValueItem(hMenu,
pCtx->hwndList,
ID_OBJECT_COPY,
0,
lpPoint,
&pCtx->lvSelectedItem,
&pCtx->lvColumnHit))
{
TrackPopupMenu(hMenu,
TPM_RIGHTBUTTON | TPM_LEFTALIGN,
lpPoint->x,
lpPoint->y,
0,
hwndDlg,
NULL);
}
DestroyMenu(hMenu);
}
}
/*
* TokenPageDialogOnCommand
*
* Purpose:
*
* Token page WM_COMMAND handler.
*
*/
INT_PTR TokenPageDialogOnCommand(
_In_ HWND hwndDlg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
INT_PTR Result = 0;
PTOKEN_PAGE_CONTEXT pCtx;
UNREFERENCED_PARAMETER(lParam);
pCtx = TokenPageGetContext(hwndDlg);
if (pCtx == NULL)
return 0;
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case ID_OBJECT_COPY:
supListViewCopyItemValueToClipboard(pCtx->hwndList,
pCtx->lvSelectedItem,
pCtx->lvColumnHit);
Result = 1;
break;
case IDC_TOKEN_ADVANCED:
TokenPageShowAdvancedProperties(hwndDlg);
Result = 1;
break;
case IDC_TOKEN_LINKED:
TokenPageShowLinkedTokenProperties(hwndDlg);
Result = 1;
break;
}
return Result;
}
/*
* TokenPageDialogOnInit
*
* Purpose:
*
* Token page WM_INITDIALOG handler.
*
*/
INT_PTR TokenPageDialogOnInit(
_In_ HWND hwndDlg,
_In_ LPARAM lParam)
{
PROPSHEETPAGE* pSheet = NULL;
PROP_OBJECT_INFO* Context = NULL;
PTOKEN_PAGE_CONTEXT pCtx;
pSheet = (PROPSHEETPAGE*)lParam;
if (pSheet) {
Context = (PROP_OBJECT_INFO*)pSheet->lParam;
//
// Allocate and attach per-dialog context.
//
pCtx = (PTOKEN_PAGE_CONTEXT)supHeapAlloc(sizeof(TOKEN_PAGE_CONTEXT));
if (pCtx) {
pCtx->hwndList = NULL;
pCtx->lvSelectedItem = -1;
pCtx->lvColumnHit = -1;
SetProp(hwndDlg, T_DLGCONTEXT, (HANDLE)pCtx);
}
//
// Remember client id.
//
SetProp(hwndDlg,
T_TOKEN_PROP_CID_PID,
Context->u1.UnnamedObjectInfo.ClientId.UniqueProcess);
SetProp(hwndDlg,
T_TOKEN_PROP_CID_TID,
Context->u1.UnnamedObjectInfo.ClientId.UniqueThread);
SetProp(hwndDlg,
T_TOKEN_PROP_TYPE,
UlongToHandle((ULONG)(Context->TypeDescription->Index == ObjectTypeThread)));
//
// Show token summary information.
//
TokenPageListInfo(Context, hwndDlg);
}
return 1;
}
/*
* TokenPageDialogProc
*
* Purpose:
*
* Token page for Process/Thread object type.
*
* WM_INITDIALOG - Initialize listview, set window prop with context,
* collect token info and fill list.
*
*/
INT_PTR CALLBACK TokenPageDialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
PTOKEN_PAGE_CONTEXT pCtx;
switch (uMsg) {
case WM_CONTEXTMENU:
pCtx = TokenPageGetContext(hwndDlg);
if (pCtx) {
supHandleContextMenuMsgForListView(hwndDlg,
wParam,
lParam,
pCtx->hwndList,
(pfnPopupMenuHandler)TokenPageHandlePopup,
NULL);
}
break;
case WM_COMMAND:
return TokenPageDialogOnCommand(hwndDlg, wParam, lParam);
case WM_INITDIALOG:
return TokenPageDialogOnInit(hwndDlg, lParam);
case WM_DESTROY:
pCtx = (PTOKEN_PAGE_CONTEXT)RemoveProp(hwndDlg, T_DLGCONTEXT);
if (pCtx) {
supHeapFree(pCtx);
}
RemoveProp(hwndDlg, T_TOKEN_PROP_CID_PID);
RemoveProp(hwndDlg, T_TOKEN_PROP_CID_TID);
RemoveProp(hwndDlg, T_TOKEN_PROP_TYPE);
break;
default:
return FALSE;
}
return TRUE;
}