Skip to content

Commit 92cdba5

Browse files
committed
Make Shut Down menu an option, backport Command Line column from Windows 7
1 parent 4322511 commit 92cdba5

7 files changed

+183
-10
lines changed

main.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ void COptions::SetDefaultValues()
387387
m_rcWindow.right = 10 + g_minWidth;
388388

389389
m_bShowAllProcess = (g_fIsTSEnabled && !g_fIsSingleUserTS && IsUserAdmin());
390+
m_bShutdownMenu = TRUE;
390391

391392
const COLUMNID *pcol = (g_fIsTSEnabled && !g_fIsSingleUserTS) ? g_aTSCols : g_aDefaultCols;
392393

@@ -537,6 +538,7 @@ void UpdateMenuStates()
537538

538539
CheckMenuItem(hMenu, IDM_ALWAYSONTOP, MF_BYCOMMAND | (g_Options.m_fAlwaysOnTop ? MF_CHECKED : MF_UNCHECKED));
539540
CheckMenuItem(hMenu, IDM_MINIMIZEONUSE, MF_BYCOMMAND | (g_Options.m_fMinimizeOnUse ? MF_CHECKED : MF_UNCHECKED));
541+
CheckMenuItem(hMenu, IDM_SHOWSHUTDOWN, MF_BYCOMMAND | (g_Options.m_bShutdownMenu ? MF_CHECKED : MF_UNCHECKED));
540542
CheckMenuItem(hMenu, IDM_KERNELTIMES, MF_BYCOMMAND | (g_Options.m_fKernelTimes ? MF_CHECKED : MF_UNCHECKED));
541543
CheckMenuItem(hMenu, IDM_NOTITLE, MF_BYCOMMAND | (g_Options.m_fNoTitle ? MF_CHECKED : MF_UNCHECKED));
542544
CheckMenuItem(hMenu, IDM_HIDEWHENMIN, MF_BYCOMMAND | (g_Options.m_fHideWhenMin ? MF_CHECKED : MF_UNCHECKED));
@@ -1376,7 +1378,7 @@ void LoadEjectFunction (void)
13761378
void AdjustMenuBar (HMENU hMenu)
13771379

13781380
{
1379-
if( !IsOS(OS_WELCOMELOGONUI))
1381+
if (!g_Options.m_bShutdownMenu)
13801382
{
13811383
//
13821384
// Classic GINA UI - Find the "shutdown" menu and remove it.
@@ -2023,6 +2025,11 @@ void MainWnd_OnCommand(HWND hwnd, int id)
20232025
UpdateMenuStates();
20242026
break;
20252027

2028+
case IDM_SHOWSHUTDOWN:
2029+
g_Options.m_bShutdownMenu = !g_Options.m_bShutdownMenu;
2030+
UpdateMenuStates();
2031+
break;
2032+
20262033
case IDM_NOTITLE:
20272034
g_Options.m_fNoTitle = !g_Options.m_fNoTitle;
20282035
UpdateMenuStates();

procpage.cpp

+52-3
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ const int g_aDlgColIDs[] =
9191
IDC_OTHEROPERCOUNT,
9292
IDC_READXFERCOUNT,
9393
IDC_WRITEXFERCOUNT,
94-
IDC_OTHERXFERCOUNT
94+
IDC_OTHERXFERCOUNT,
95+
IDC_COMMANDLINE
9596
};
9697

9798
//
@@ -136,7 +137,8 @@ struct
136137
{ LVCFMT_RIGHT, 70 }, // COL_OTHEROPERCOUNT
137138
{ LVCFMT_RIGHT, 70 }, // COL_READXFERCOUNT
138139
{ LVCFMT_RIGHT, 70 }, // COL_WRITEXFERCOUNT
139-
{ LVCFMT_RIGHT, 70 } // COL_OTHERXFERCOUNT
140+
{ LVCFMT_RIGHT, 70 }, // COL_OTHERXFERCOUNT
141+
{ LVCFMT_LEFT, 0x6B } // COL_COMMANDLINE
140142
};
141143

142144

@@ -187,6 +189,7 @@ class CProcInfo
187189
LONGLONG m_IoWriteXferCount;
188190
LONGLONG m_IoOtherXferCount;
189191
LPWSTR m_pszImageName;
192+
LPWSTR m_pszCommandLine;
190193
CProcInfo * m_pWowParentProcInfo; // non-NULL for WOW tasks
191194
WORD m_htaskWow; // non-zero for WOW tasks
192195
BOOL m_fWowProcess:1; // TRUE for real WOW process
@@ -231,6 +234,7 @@ class CProcInfo
231234
DWORD m_fDirty_COL_READXFERCOUNT :1;
232235
DWORD m_fDirty_COL_WRITEXFERCOUNT :1;
233236
DWORD m_fDirty_COL_OTHERXFERCOUNT :1;
237+
DWORD m_fDirty_COL_COMMANDLINE :1;
234238
};
235239
#pragma warning(default:4201) // Nameless struct or union
236240
};
@@ -269,6 +273,11 @@ class CProcInfo
269273
{
270274
LocalFree( m_pszUserName );
271275
}
276+
277+
if (m_pszCommandLine)
278+
{
279+
LocalFree(m_pszCommandLine);
280+
}
272281
}
273282

274283
BOOL OkToShowThisProcess ()
@@ -618,7 +627,8 @@ static const int _aIDColNames[NUM_COLUMN] =
618627
IDS_COL_OTHEROPERCOUNT,
619628
IDS_COL_READXFERCOUNT,
620629
IDS_COL_WRITEXFERCOUNT,
621-
IDS_COL_OTHERXFERCOUNT
630+
IDS_COL_OTHERXFERCOUNT,
631+
IDS_COL_COMMANDLINE
622632
};
623633

624634
HRESULT CProcPage::SetupColumns()
@@ -909,6 +919,10 @@ INT CProcInfo::Compare(CProcInfo * pOther)
909919
iRet = Compare64(pMyThis->m_IoOtherXferCount, pMyOther->m_IoOtherXferCount);
910920
break;
911921

922+
case COL_COMMANDLINE:
923+
iRet = lstrcmpi(pMyThis->m_pszCommandLine, pMyOther->m_pszCommandLine);
924+
break;
925+
912926
default:
913927
ASSERT(FALSE);
914928
iRet = 0;
@@ -1912,6 +1926,36 @@ HRESULT CProcInfo::SetData(__int64 TotalTime,
19121926
{
19131927
SetProcessUsername(LPFILETIME(&(pInfo->CreateTime)));
19141928
}
1929+
1930+
m_fDirty_COL_COMMANDLINE = TRUE;
1931+
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, m_UniqueProcessId);
1932+
if (hProcess)
1933+
{
1934+
PROCESS_BASIC_INFORMATION pbi;
1935+
if (NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), nullptr)))
1936+
{
1937+
PRTL_USER_PROCESS_PARAMETERS params = nullptr;
1938+
if (ReadProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters, &params, sizeof(params), nullptr))
1939+
{
1940+
UNICODE_STRING temp;
1941+
if (ReadProcessMemory(hProcess, &params->CommandLine, &temp, sizeof(UNICODE_STRING), nullptr))
1942+
{
1943+
m_pszCommandLine = (LPWSTR)LocalAlloc(LPTR, temp.Length * sizeof(WCHAR));
1944+
if (!ReadProcessMemory(hProcess, temp.Buffer, m_pszCommandLine, temp.Length * sizeof(WCHAR), nullptr))
1945+
{
1946+
LocalFree(m_pszCommandLine);
1947+
m_pszCommandLine = nullptr;
1948+
}
1949+
}
1950+
}
1951+
}
1952+
}
1953+
1954+
if (!m_pszCommandLine)
1955+
{
1956+
m_pszCommandLine = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR));
1957+
*m_pszCommandLine = L'\0';
1958+
}
19151959
}
19161960

19171961
//
@@ -2980,6 +3024,11 @@ INT CProcPage::HandleProcPageNotify(LPNMHDR pnmhdr)
29803024
Int64ToCommaSepString(pProcInfo->m_IoOtherXferCount, plvitem->pszText, plvitem->cchTextMax);
29813025
break;
29823026

3027+
case COL_COMMANDLINE:
3028+
// don't care if it truncates - UI only
3029+
StringCchCopy(plvitem->pszText, plvitem->cchTextMax, pProcInfo->m_pszCommandLine);
3030+
break;
3031+
29833032
default:
29843033
Assert( 0 && "Unknown listview subitem" );
29853034
break;

resource.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
#define IDC_READXFERCOUNT 2035
180180
#define IDC_WRITEXFERCOUNT 2036
181181
#define IDC_OTHERXFERCOUNT 2037
182+
#define IDC_COMMANDLINE 2038
182183

183184
#define IDR_MAINMENU_NET 2400
184185
#define IDM_BYTESSENT 2401
@@ -334,9 +335,10 @@
334335
#define IDS_COL_READXFERCOUNT 21008
335336
#define IDS_COL_WRITEXFERCOUNT 21009
336337
#define IDS_COL_OTHERXFERCOUNT 21010
337-
#define IDS_G 21011
338-
#define IDS_M 21012
339-
#define IDS_ZERO 21013
338+
#define IDS_COL_COMMANDLINE 21011
339+
#define IDS_G 21012
340+
#define IDS_M 21013
341+
#define IDS_ZERO 21014
340342
#define IDS_BITSPERSEC 21015
341343
#define IDS_SCALEFONT 21016
342344
#define IDS_PERCENT 21017
@@ -441,6 +443,7 @@
441443
#define IDM_HIDE 40063
442444
#define IDM_RESTORETASKMAN 40064
443445
#define IDM_HIDEWHENMIN 40065
446+
#define IDM_SHOWSHUTDOWN 40066
444447
#define IDM_TRAYMENU 40069
445448
#define IDM_SHOW16BIT 40098
446449
#define IDM_NOTITLE 40099

shundoc.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,14 @@ VOID (NTAPI *RtlTimeToElapsedTimeFields)(
9595

9696
NTSTATUS (NTAPI *RtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation) = nullptr;
9797

98+
NTSTATUS (NTAPI *NtQueryInformationProcess)(
99+
IN HANDLE ProcessHandle,
100+
IN PROCESSINFOCLASS ProcessInformationClass,
101+
OUT PVOID ProcessInformation,
102+
IN ULONG ProcessInformationLength,
103+
OUT PULONG ReturnLength OPTIONAL
104+
);
105+
98106
BOOL (WINAPI *EndTask)(HWND hWnd, BOOL fShutDown, BOOL fForce) = nullptr;
99107

100108
//
@@ -135,6 +143,7 @@ bool SHUndocInit(void)
135143
LOAD_FUNCTION(ntdll, NtClose);
136144
LOAD_FUNCTION(ntdll, RtlTimeToElapsedTimeFields);
137145
LOAD_FUNCTION(ntdll, RtlGetVersion);
146+
LOAD_FUNCTION(ntdll, NtQueryInformationProcess);
138147

139148
LOAD_MODULE(winsta);
140149
LOAD_FUNCTION(winsta, WinStationGetProcessSid);

shundoc.h

+96
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,56 @@ typedef enum _WINSTATIONINFOCLASS
550550
WinStationIsAdminLoggedOn // Is the currently logged on user an administrator ?
551551
} WINSTATIONINFOCLASS;
552552

553+
typedef struct _PEB_LDR_DATA
554+
{
555+
BYTE Reserved1[8];
556+
PVOID Reserved2[3];
557+
LIST_ENTRY InMemoryOrderModuleList;
558+
} PEB_LDR_DATA, *PPEB_LDR_DATA;
559+
560+
typedef struct _RTL_USER_PROCESS_PARAMETERS
561+
{
562+
BYTE Reserved1[16];
563+
PVOID Reserved2[10];
564+
UNICODE_STRING ImagePathName;
565+
UNICODE_STRING CommandLine;
566+
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
567+
568+
typedef VOID(NTAPI *PPS_POST_PROCESS_INIT_ROUTINE)(VOID);
569+
570+
typedef struct _PEB
571+
{
572+
BYTE Reserved1[2];
573+
BYTE BeingDebugged;
574+
BYTE Reserved2[1];
575+
PVOID Reserved3[2];
576+
PPEB_LDR_DATA Ldr;
577+
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
578+
PVOID Reserved4[3];
579+
PVOID AtlThunkSListPtr;
580+
PVOID Reserved5;
581+
ULONG Reserved6;
582+
PVOID Reserved7;
583+
ULONG Reserved8;
584+
ULONG AtlThunkSListPtr32;
585+
PVOID Reserved9[45];
586+
BYTE Reserved10[96];
587+
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
588+
BYTE Reserved11[128];
589+
PVOID Reserved12[1];
590+
ULONG SessionId;
591+
} PEB, *PPEB;
592+
593+
typedef struct _PROCESS_BASIC_INFORMATION
594+
{
595+
NTSTATUS ExitStatus;
596+
PPEB PebBaseAddress;
597+
ULONG_PTR AffinityMask;
598+
KPRIORITY BasePriority;
599+
ULONG_PTR UniqueProcessId;
600+
ULONG_PTR InheritedFromUniqueProcessId;
601+
} PROCESS_BASIC_INFORMATION;
602+
553603
extern BOOLEAN (WINAPI *WinStationQueryInformationW)(
554604
HANDLE hServer,
555605
ULONG LogonId,
@@ -574,6 +624,52 @@ extern VOID (NTAPI *RtlTimeToElapsedTimeFields)(
574624

575625
extern NTSTATUS (NTAPI *RtlGetVersion)(PRTL_OSVERSIONINFOW lpVersionInformation);
576626

627+
typedef enum _PROCESSINFOCLASS
628+
{
629+
ProcessBasicInformation,
630+
ProcessQuotaLimits,
631+
ProcessIoCounters,
632+
ProcessVmCounters,
633+
ProcessTimes,
634+
ProcessBasePriority,
635+
ProcessRaisePriority,
636+
ProcessDebugPort,
637+
ProcessExceptionPort,
638+
ProcessAccessToken,
639+
ProcessLdtInformation,
640+
ProcessLdtSize,
641+
ProcessDefaultHardErrorMode,
642+
ProcessIoPortHandlers, // Note: this is kernel mode only
643+
ProcessPooledUsageAndLimits,
644+
ProcessWorkingSetWatch,
645+
ProcessUserModeIOPL,
646+
ProcessEnableAlignmentFaultFixup,
647+
ProcessPriorityClass,
648+
ProcessWx86Information,
649+
ProcessHandleCount,
650+
ProcessAffinityMask,
651+
ProcessPriorityBoost,
652+
ProcessDeviceMap,
653+
ProcessSessionInformation,
654+
ProcessForegroundInformation,
655+
ProcessWow64Information,
656+
ProcessImageFileName,
657+
ProcessLUIDDeviceMapsEnabled,
658+
ProcessBreakOnTermination,
659+
ProcessDebugObjectHandle,
660+
ProcessDebugFlags,
661+
ProcessHandleTracing,
662+
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
663+
} PROCESSINFOCLASS;
664+
665+
extern NTSTATUS (NTAPI *NtQueryInformationProcess)(
666+
IN HANDLE ProcessHandle,
667+
IN PROCESSINFOCLASS ProcessInformationClass,
668+
OUT PVOID ProcessInformation,
669+
IN ULONG ProcessInformationLength,
670+
OUT PULONG ReturnLength OPTIONAL
671+
);
672+
577673
extern BOOL (WINAPI *EndTask)(HWND hWnd, BOOL fShutDown, BOOL fForce);
578674

579675
extern void (WINAPI *CachedGetUserFromSid)(PSID pSid, PWCHAR pUserName, PULONG cbUserName);

taskmgr.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ typedef enum COLUMNID
7777
COL_OTHEROPERCOUNT = 21,
7878
COL_READXFERCOUNT = 22,
7979
COL_WRITEXFERCOUNT = 23,
80-
COL_OTHERXFERCOUNT = 24
80+
COL_OTHERXFERCOUNT = 24,
81+
COL_COMMANDLINE = 25
8182
};
8283

8384
typedef enum NETCOLUMNID
@@ -110,7 +111,7 @@ typedef enum NETCOLUMNID
110111
COL_NONUNICASTSTOTALPERINTER = 25
111112
};
112113

113-
#define MAX_COLUMN 24
114+
#define MAX_COLUMN 25
114115
#define NUM_COLUMN (MAX_COLUMN + 1)
115116
#define NUM_NETCOLUMN 26
116117

@@ -219,6 +220,7 @@ class COptions
219220
BOOL bUnused;
220221
BOOL bUnused2;
221222
BOOL m_bShowAllProcess;
223+
BOOL m_bShutdownMenu;
222224

223225
HRESULT Load();
224226
HRESULT Save();

0 commit comments

Comments
 (0)