Files
hfiref0x 754d18e71e Integration of WinDepends support
Integrate optional "View With WinDepends" support for viewing dependencies of drivers (Drivers dialog, SSDT/Shadow SSDT dialogs). This feature requires WinDepends installed somewhere on system and .sys file is associated with it through WinDepends file association configuration.
2026-03-09 17:56:50 +07:00

1923 lines
49 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2016 - 2026
*
* TITLE: EXTRASDRIVERS.C
*
* VERSION: 2.10
*
* DATE: 07 Mar 2026
*
* 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 "extras.h"
#define DUMP_PROP L"dumpProp"
BOOLEAN DrvDlgShimsEnabled = FALSE;
#define ID_DRVLIST_REFRESH ID_VIEW_REFRESH
#define ID_DRVLIST_PROP ID_OBJECT_PROPERTIES
#define ID_DRVLIST_DUMP 40105
#define ID_DRVLIST_DUMPFIXED 40106
#define ID_DRVLIST_SAVE 40107
#define ID_DRVLIST_VIEW_WDX 40108
#define ID_CALC_HASH_MD5 6000
#define ID_CALC_HASH_SHA1 6001
#define ID_CALC_HASH_SHA256 6002
#define ID_CALC_HASH_SHA384 6003
#define ID_CALC_HASH_SHA512 6004
#define ID_CALC_HASH_PAGE_SHA1 6005
#define ID_CALC_HASH_PAGE_SHA256 6006
#define COLUMN_DRVLIST_LOAD_ORDER 0
#define COLUMN_DRVLIST_DRIVER_NAME 1
#define COLUMN_DRVLIST_DRIVER_ADDRESS 2
#define COLUMN_DRVLIST_SIZE 3
#define COLUMN_DRVLIST_MODULE_NAME 4
#define COLUMN_DRVLIST_SHIMMED 5
#define COLUMN_DRVLIST_UNLOADED_DRIVER_NAME 0
#define COLUMN_DRVLIST_UNLOADED_START_ADDRESS 1
#define COLUMN_DRVLIST_UNLOADED_END_ADDRESS 2
#define COLUMN_DRVLIST_UNLOADED_CURRENT_TIME 3
#define T_DUMPDRIVER L"Dump Driver (Raw)"
#define T_DUMPDRIVER_FIXED L"Dump Driver (Fix Sections)"
#define DRVLISTDLG_TRACKSIZE_MIN_X 640
#define DRVLISTDLG_TRACKSIZE_MIN_Y 480
static EXTRASCONTEXT DrvDlgContext[DrvModeMax];
static HANDLE DrvDlgThreadHandles[DrvModeMax] = { NULL, NULL };
static FAST_EVENT DrvDlgInitializedEvents[DrvModeMax] = { FAST_EVENT_INIT, FAST_EVENT_INIT };
static LIST_ENTRY g_DrvFilterListHead;
static ULONG g_cDrvShimmed = 0;
static ULONG g_cDrvFilters = 0;
WNDPROC g_OriginalListViewProc = NULL;
LPCWSTR CryptAlgoIdRef[] = {
BCRYPT_MD5_ALGORITHM,
BCRYPT_SHA1_ALGORITHM,
BCRYPT_SHA256_ALGORITHM,
BCRYPT_SHA384_ALGORITHM,
BCRYPT_SHA512_ALGORITHM
};
VOID DrvTooltipFreeBuffer(
_In_ EXTRASCONTEXT* Context
)
{
if (Context == NULL)
return;
if (Context->TooltipBuffer) {
supHeapFree(Context->TooltipBuffer);
Context->TooltipBuffer = NULL;
}
}
/*
* DrvListCopyHash
*
* Purpose:
*
* Copy hash menu handler.
*
*/
VOID DrvListCopyHash(
_In_ EXTRASCONTEXT* Context,
_In_ UINT MenuId
)
{
INT mark;
NTSTATUS ntStatus;
LPWSTR lpItem, lpszHash = NULL, lpWin32Name;
FILE_VIEW_INFO fvi;
if (ListView_GetSelectedCount(Context->ListView) == 0)
return;
mark = ListView_GetSelectionMark(Context->ListView);
if (mark < 0)
return;
lpItem = supGetItemText(Context->ListView, mark,
COLUMN_DRVLIST_MODULE_NAME, NULL);
if (lpItem == NULL)
return;
lpWin32Name = supGetWin32FileName(lpItem);
if (lpWin32Name) {
RtlSecureZeroMemory(&fvi, sizeof(fvi));
fvi.FileName = lpWin32Name;
ntStatus = HashLoadFile(&fvi, FALSE);
if (NT_SUCCESS(ntStatus)) {
if (MenuId >= ID_CALC_HASH_PAGE_SHA1 && MenuId <= ID_CALC_HASH_PAGE_SHA256) {
lpszHash = ComputeHashForFile(&fvi,
(MenuId == ID_CALC_HASH_PAGE_SHA1) ? BCRYPT_SHA1_ALGORITHM : BCRYPT_SHA256_ALGORITHM,
PAGE_SIZE,
g_obexHeap,
TRUE);
}
else if (MenuId >= ID_CALC_HASH_MD5 && MenuId <= ID_CALC_HASH_SHA512) {
lpszHash = ComputeHashForFile(&fvi,
CryptAlgoIdRef[MenuId - ID_CALC_HASH_MD5],
PAGE_SIZE,
g_obexHeap,
FALSE);
}
HashUnloadFile(&fvi);
}
else {
supShowNtStatus(Context->hwndDlg, TEXT("Error loading file, NTSTATUS: "), ntStatus);
}
supHeapFree(lpWin32Name);
}
supHeapFree(lpItem);
if (lpszHash) {
supClipboardCopy(lpszHash, _strlen(lpszHash) * sizeof(WCHAR));
supHeapFree(lpszHash);
}
}
/*
* DrvUpdateStatusBar
*
* Purpose:
*
* Update status bar information.
*
*/
VOID DrvUpdateStatusBar(
_In_ EXTRASCONTEXT* Context,
_In_ INT iItem)
{
INT iSubItem;
INT sbParts[] = { 100, -1 };
WCHAR szBuffer[MAX_PATH];
_strcpy(szBuffer, TEXT("Total: "));
ultostr(ListView_GetItemCount(Context->ListView), _strend(szBuffer));
//
// Add "shimmed" drivers count for normal dialog mode.
//
if (Context->DialogMode == DrvModeNormal) {
if (g_cDrvShimmed) {
_strcat(szBuffer, TEXT(", Shimmed: "));
ultostr(g_cDrvShimmed, _strend(szBuffer));
sbParts[0] = 240;
}
}
SendMessage(Context->StatusBar, SB_SETPARTS, 2, (LPARAM)&sbParts);
supStatusBarSetText(Context->StatusBar, 0, (LPWSTR)&szBuffer);
if (iItem >= 0) {
if (Context->DialogMode == DrvModeNormal)
iSubItem = COLUMN_DRVLIST_DRIVER_NAME;
else
iSubItem = COLUMN_DRVLIST_UNLOADED_DRIVER_NAME;
supGetItemText2(
Context->ListView,
iItem,
iSubItem,
szBuffer,
MAX_PATH);
supStatusBarSetText(Context->StatusBar, 1, (LPWSTR)&szBuffer);
}
else {
supStatusBarSetText(Context->StatusBar, 1, (LPWSTR)T_EmptyString);
}
}
/*
* DrvHandlePopupMenu
*
* Purpose:
*
* Table list popup construction.
*
*/
VOID DrvHandlePopupMenu(
_In_ HWND hwndDlg,
_In_ LPPOINT lpPoint,
_In_ PVOID lpUserParam
)
{
HMENU hMenu;
UINT uPos = 0, i;
EXTRASCONTEXT* Context = (EXTRASCONTEXT*)lpUserParam;
WCHAR szMenuText[MAX_PATH + 1];
hMenu = CreatePopupMenu();
if (hMenu) {
if (supListViewAddCopyValueItem(hMenu,
Context->ListView,
ID_OBJECT_COPY,
uPos,
lpPoint,
&Context->lvItemHit,
&Context->lvColumnHit))
{
InsertMenu(hMenu, ++uPos, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
}
if (Context->DialogMode == DrvModeNormal) {
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_PROP, T_PROPERTIES);
InsertMenu(hMenu, ++uPos, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
if (kdConnectDriver()) {
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_DUMP, T_DUMPDRIVER);
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_DUMPFIXED, T_DUMPDRIVER_FIXED);
}
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_JUMPTOFILE, T_JUMPTOFILE);
}
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_SAVE, T_EXPORTTOFILE);
InsertMenu(hMenu, ++uPos, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_REFRESH, T_VIEW_REFRESH);
if (Context->DialogMode == DrvModeNormal) {
//
// Hashes.
//
InsertMenu(hMenu, ++uPos, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
for (i = ID_CALC_HASH_MD5; i < ID_CALC_HASH_PAGE_SHA1; i++) {
RtlStringCchPrintfSecure(szMenuText,
MAX_PATH,
TEXT("Copy Authenticode %ws hash"),
CryptAlgoIdRef[i - ID_CALC_HASH_MD5]);
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, i, szMenuText);
}
InsertMenu(hMenu, ++uPos, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
RtlStringCchPrintfSecure(szMenuText,
MAX_PATH,
TEXT("Copy %ws page hash"),
BCRYPT_SHA1_ALGORITHM);
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_CALC_HASH_PAGE_SHA1, szMenuText);
RtlStringCchPrintfSecure(szMenuText,
MAX_PATH,
TEXT("Copy %ws page hash"),
BCRYPT_SHA256_ALGORITHM);
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_CALC_HASH_PAGE_SHA256, szMenuText);
//
// View With WinDepends
//
if (g_WinObj.WinDependsPresent)
InsertMenu(hMenu, ++uPos, MF_BYCOMMAND, ID_DRVLIST_VIEW_WDX, T_VIEWWITH_WDX);
}
//
// Track.
//
TrackPopupMenu(hMenu,
TPM_RIGHTBUTTON | TPM_LEFTALIGN,
lpPoint->x,
lpPoint->y,
0,
hwndDlg,
NULL);
DestroyMenu(hMenu);
}
}
/*
* DrvListViewProperties
*
* Purpose:
*
* View selected driver file properties.
*
*/
VOID DrvListViewProperties(
_In_ EXTRASCONTEXT* Context
)
{
LPWSTR lpItem, lpWin32Name;
INT mark;
if (ListView_GetSelectedCount(Context->ListView)) {
mark = ListView_GetSelectionMark(Context->ListView);
if (mark >= 0) {
lpItem = supGetItemText(Context->ListView, mark,
COLUMN_DRVLIST_MODULE_NAME, NULL);
if (lpItem) {
lpWin32Name = supGetWin32FileName(lpItem);
if (lpWin32Name) {
supShowProperties(Context->hwndDlg, lpWin32Name);
supHeapFree(lpWin32Name);
}
supHeapFree(lpItem);
}
}
}
}
static HANDLE DumpDialogThreadHandle = NULL;
static FAST_EVENT DumpDialogInitializedEvent = FAST_EVENT_INIT;
HWND DumpWorkerWindow = NULL;
typedef struct _OBEX_DRVDUMP {
_In_ BOOL FixSections;
_In_ ULONG DumpSize;
_In_ ULONG_PTR DumpAddress;
_In_ PBYTE Buffer;
_In_ HWND ParentWindow;
_Out_ volatile LONGLONG ReadSize;
_Out_ NTSTATUS DumpStatus;
_In_ HANDLE hCancelEvent;
_In_ HANDLE hWorkerThread;
_In_ WCHAR FileName[MAX_PATH * 2];
} OBEX_DRVDUMP, * POBEX_DRVDUMP;
/*
* DrvDumpThread
*
* Purpose:
*
* Dumper thread worker.
*
*/
DWORD DrvDumpThread(
_In_ PVOID Parameter
)
{
OBEX_DRVDUMP* dumpInfo = (POBEX_DRVDUMP)Parameter;
PBYTE buffer;
ULONG_PTR dumpAddress;
ULONG totalSize;
unsigned long long readBytes = 0;
ULONG i;
ULONG remainingBytes;
ULONG memIO = 0;
LONGLONG prev;
if (dumpInfo == NULL)
return ERROR_INVALID_PARAMETER;
totalSize = dumpInfo->DumpSize;
for (i = 0,
buffer = dumpInfo->Buffer,
dumpAddress = dumpInfo->DumpAddress;
(i < (totalSize / PAGE_SIZE));
i++,
dumpAddress += PAGE_SIZE,
buffer = (PBYTE)RtlOffsetToPointer(buffer, PAGE_SIZE))
{
if (dumpInfo->hCancelEvent && WaitForSingleObject(dumpInfo->hCancelEvent, 0) == WAIT_OBJECT_0) {
dumpInfo->DumpStatus = STATUS_CANCELLED;
PostMessage(dumpInfo->ParentWindow, WM_CLOSE, (WPARAM)0, (LPARAM)0);
return ERROR_CANCELLED;
}
kdReadSystemMemoryEx(dumpAddress, buffer, PAGE_SIZE, &memIO); // ignore read errors
prev = InterlockedExchangeAdd64(&dumpInfo->ReadSize, (LONGLONG)memIO);
readBytes = (unsigned long long)(prev + (LONGLONG)memIO);
}
remainingBytes = totalSize % PAGE_SIZE;
if (remainingBytes) {
if (dumpInfo->hCancelEvent && WaitForSingleObject(dumpInfo->hCancelEvent, 0) == WAIT_OBJECT_0) {
dumpInfo->DumpStatus = STATUS_CANCELLED;
PostMessage(dumpInfo->ParentWindow, WM_CLOSE, (WPARAM)0, (LPARAM)0);
return ERROR_CANCELLED;
}
kdReadSystemMemoryEx(dumpAddress, buffer, remainingBytes, &memIO);
prev = InterlockedExchangeAdd64(&dumpInfo->ReadSize, (LONGLONG)memIO);
readBytes = (unsigned long long)(prev + (LONGLONG)memIO);
}
if (readBytes == 0) {
dumpInfo->DumpStatus = STATUS_UNSUCCESSFUL;
}
else if (readBytes != totalSize) {
dumpInfo->DumpStatus = STATUS_PARTIAL_COPY;
}
else {
dumpInfo->DumpStatus = STATUS_SUCCESS;
}
//
// Signal dialog to close and let dialog-thread perform cleanup.
//
PostMessage(dumpInfo->ParentWindow, WM_CLOSE, (WPARAM)0, (LPARAM)0);
return ERROR_SUCCESS;
}
/*
* DumpTerminateWorker
*
* Purpose:
*
* Request worker cancellation and wait for worker thread to exit.
*
*/
VOID DumpTerminateWorker(
_In_ HWND hwndDlg
)
{
OBEX_DRVDUMP* dumpInfo;
if (hwndDlg == NULL)
return;
dumpInfo = (OBEX_DRVDUMP*)GetProp(hwndDlg, DUMP_PROP);
if (dumpInfo == NULL)
return;
if (dumpInfo->hWorkerThread) {
//
// Request cancellation.
//
if (dumpInfo->hCancelEvent)
SetEvent(dumpInfo->hCancelEvent);
WaitForSingleObject(dumpInfo->hWorkerThread, 20 * 1000);
CloseHandle(dumpInfo->hWorkerThread);
dumpInfo->hWorkerThread = NULL;
}
}
/*
* DumpUpdateTimerProc
*
* Purpose:
*
* Timer proc handler displaying dump progress.
*
*/
VOID DumpUpdateTimerProc(
HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime)
{
UNREFERENCED_PARAMETER(uMsg);
UNREFERENCED_PARAMETER(idEvent);
UNREFERENCED_PARAMETER(dwTime);
OBEX_DRVDUMP* dumpInfo;
HWND hwndProgress = GetDlgItem(hwnd, IDC_PROGRESS);
WCHAR szBuffer[100];
dumpInfo = (OBEX_DRVDUMP*)GetProp(hwnd, DUMP_PROP);
if (dumpInfo) {
szBuffer[0] = 0;
RtlStringCchPrintfSecure(szBuffer,
RTL_NUMBER_OF(szBuffer),
TEXT("Reading %llu (%llu Kb) of %lu (%lu Kb)"),
(ULONGLONG)dumpInfo->ReadSize,
(ULONGLONG)(dumpInfo->ReadSize / 1024),
dumpInfo->DumpSize,
dumpInfo->DumpSize / 1024);
SetWindowText(hwndProgress, szBuffer);
}
}
/*
* DrvDumpProgressDialogProc
*
* Purpose:
*
* Driver dumping progress dialog proc.
*
*/
INT_PTR CALLBACK DrvDumpProgressDialogProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
OBEX_DRVDUMP* dumpInfo;
switch (uMsg) {
case WM_INITDIALOG:
dumpInfo = (POBEX_DRVDUMP)lParam;
if (dumpInfo) {
SetProp(hwndDlg, DUMP_PROP, (HANDLE)dumpInfo);
supCenterWindowSpecifyParent(hwndDlg, dumpInfo->ParentWindow);
dumpInfo->ParentWindow = hwndDlg;
_InterlockedExchange64(&dumpInfo->ReadSize, 0);
dumpInfo->hCancelEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
dumpInfo->hWorkerThread = supCreateThread(DrvDumpThread, (PVOID)dumpInfo, 0);
SetTimer(hwndDlg, 1, 300, DumpUpdateTimerProc);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDCANCEL:
DumpTerminateWorker(hwndDlg);
RemoveProp(hwndDlg, DUMP_PROP);
KillTimer(hwndDlg, 1);
return DestroyWindow(hwndDlg);
}
}
return 0;
}
/*
* DumpDialogWorkerThread
*
* Purpose:
*
* Driver dumping dialog proc.
*
*/
DWORD DumpDialogWorkerThread(
_In_ PVOID Parameter
)
{
BOOL bResult;
MSG message;
OBEX_DRVDUMP* dumpInfo = (POBEX_DRVDUMP)Parameter;
HWND hwndDlg, hwndParent = dumpInfo->ParentWindow;
HANDLE prev;
SIZE_T bytesIO;
WCHAR szBuffer[100];
hwndDlg = CreateDialogParam(g_WinObj.hInstance,
MAKEINTRESOURCE(IDD_DIALOG_PROGRESS),
0,
(DLGPROC)&DrvDumpProgressDialogProc,
(LPARAM)dumpInfo);
DumpWorkerWindow = hwndDlg;
SetWindowText(hwndDlg, TEXT("Driver dump"));
supSetFastEvent(&DumpDialogInitializedEvent);
if (hwndDlg) {
do {
bResult = GetMessage(&message, NULL, 0, 0);
if (bResult == -1)
break;
if (!IsDialogMessage(hwndDlg, &message)) {
TranslateMessage(&message);
DispatchMessage(&message);
}
} while (bResult != 0);
}
if (dumpInfo->hWorkerThread) {
WaitForSingleObject(dumpInfo->hWorkerThread, INFINITE);
CloseHandle(dumpInfo->hWorkerThread);
dumpInfo->hWorkerThread = NULL;
}
if ((NT_SUCCESS(dumpInfo->DumpStatus)
|| dumpInfo->DumpStatus == STATUS_PARTIAL_COPY)
&& (dumpInfo->Buffer != NULL))
{
if (dumpInfo->FixSections)
supImageFixSections(dumpInfo->Buffer);
bytesIO = supWriteBufferToFile(dumpInfo->FileName, dumpInfo->Buffer,
(SIZE_T)dumpInfo->DumpSize, FALSE, FALSE, NULL);
RtlStringCchPrintfSecure(szBuffer, RTL_NUMBER_OF(szBuffer),
TEXT("Read %llu (%llu Kb), Write %llu (%llu Kb), Requested %lu (%lu Kb)"),
(ULONGLONG)dumpInfo->ReadSize,
(ULONGLONG)(dumpInfo->ReadSize / 1024),
(ULONGLONG)bytesIO,
(ULONGLONG)(bytesIO / 1024),
dumpInfo->DumpSize,
dumpInfo->DumpSize / 1024);
}
else if (dumpInfo->DumpStatus == STATUS_CANCELLED) {
_strcpy(szBuffer, TEXT("Operation cancelled by user"));
}
else {
_strcpy(szBuffer, TEXT("Error while dumping memory"));
}
supStatusBarSetText(
GetDlgItem(hwndParent, ID_EXTRASLIST_STATUSBAR),
1,
szBuffer);
if (dumpInfo->hCancelEvent) {
CloseHandle(dumpInfo->hCancelEvent);
dumpInfo->hCancelEvent = NULL;
}
if (dumpInfo->Buffer) {
supHeapFree(dumpInfo->Buffer);
}
supHeapFree(dumpInfo);
supResetFastEvent(&DumpDialogInitializedEvent);
prev = InterlockedExchangePointer((PVOID*)&DumpDialogThreadHandle, NULL);
if (prev) CloseHandle(prev);
return 0;
}
/*
* DrvDumpDriver
*
* Purpose:
*
* Read driver from memory and write to disk, ignore read errors
*
*/
VOID DrvDumpDriver(
_In_ EXTRASCONTEXT* Context,
_In_ BOOL FixSections
)
{
INT nSelected;
SIZE_T sz;
LPWSTR lpDriverName = NULL;
WCHAR szBuffer[MAX_PATH * 2], szDriverDumpInfo[MAX_TEXT_CONVERSION_ULONG64];
OBEX_DRVDUMP* DumpInfo;
ULONG_PTR dumpAddress;
ULONG dumpSize;
if (DumpDialogThreadHandle) {
return;
}
do {
//
// Remember selected index.
//
nSelected = ListView_GetNextItem(Context->ListView, -1, LVNI_SELECTED);
if (nSelected < 0)
break;
//
// Query selected driver name.
//
sz = 0;
lpDriverName = supGetItemText(Context->ListView, nSelected, 1, &sz);
if (lpDriverName == NULL)
break;
RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
_strncpy(szBuffer, MAX_PATH, lpDriverName, sz / sizeof(WCHAR));
//
// Run Save As Dialog.
//
if (!supSaveDialogExecute(Context->hwndDlg, szBuffer, TEXT("All files\0*.*\0\0")))
break;
//
// Query driver address from listview.
//
RtlSecureZeroMemory(szDriverDumpInfo, sizeof(szDriverDumpInfo));
supGetItemText2(
Context->ListView,
nSelected,
COLUMN_DRVLIST_DRIVER_ADDRESS,
szDriverDumpInfo,
MAX_TEXT_CONVERSION_ULONG64);
if (!(szDriverDumpInfo[0] == L'0' && (szDriverDumpInfo[1] == L'x')))
break;
dumpAddress = hextou64(&szDriverDumpInfo[2]);
if (dumpAddress < g_kdctx.SystemRangeStart)
break;
//
// Query driver size from listview.
//
RtlSecureZeroMemory(szDriverDumpInfo, sizeof(szDriverDumpInfo));
supGetItemText2(
Context->ListView,
nSelected,
COLUMN_DRVLIST_SIZE,
szDriverDumpInfo,
MAX_TEXT_CONVERSION_ULONG64);
dumpSize = _strtoul(szDriverDumpInfo);
if (dumpSize == 0)
break;
// 1 GB cap.
if (dumpSize > 0x40000000) {
supStatusBarSetText(Context->StatusBar, 1, TEXT("Dump size too large"));
break;
}
DumpInfo = (OBEX_DRVDUMP*)supHeapAlloc(sizeof(OBEX_DRVDUMP));
if (DumpInfo == NULL)
break;
DumpInfo->Buffer = (PBYTE)supHeapAlloc(dumpSize);
if (DumpInfo->Buffer == NULL) {
supHeapFree(DumpInfo);
break;
}
DumpInfo->FixSections = FixSections;
_strcpy(DumpInfo->FileName, szBuffer);
DumpInfo->DumpAddress = dumpAddress;
DumpInfo->DumpSize = dumpSize;
DumpInfo->ParentWindow = Context->hwndDlg;
DumpInfo->ReadSize = 0;
DumpInfo->DumpStatus = STATUS_UNSUCCESSFUL;
DumpInfo->hCancelEvent = NULL;
DumpInfo->hWorkerThread = NULL;
DumpDialogThreadHandle = supCreateThread(DumpDialogWorkerThread, (PVOID)DumpInfo, 0);
if (DumpDialogThreadHandle == NULL) {
if (DumpInfo->Buffer) supHeapFree(DumpInfo->Buffer);
supHeapFree(DumpInfo);
break;
}
supWaitForFastEvent(&DumpDialogInitializedEvent, NULL);
} while (FALSE);
if (lpDriverName) supHeapFree(lpDriverName);
}
/*
* DrvDlgCompareFunc
*
* Purpose:
*
* Drivers Dialog listview comparer function.
*
*/
INT CALLBACK DrvDlgCompareFunc(
_In_ LPARAM lParam1,
_In_ LPARAM lParam2,
_In_ LPARAM lParamSort
)
{
EXTRASCONTEXT* pDlgContext = (EXTRASCONTEXT*)lParamSort;
if (pDlgContext == NULL)
return 0;
if (pDlgContext->DialogMode == DrvModeNormal) {
switch (pDlgContext->lvColumnToSort) {
case COLUMN_DRVLIST_LOAD_ORDER: //Load Order
case COLUMN_DRVLIST_SIZE: //Size
return supGetMaxOfTwoULongFromString(
pDlgContext->ListView,
lParam1,
lParam2,
pDlgContext->lvColumnToSort,
pDlgContext->bInverseSort);
case COLUMN_DRVLIST_DRIVER_ADDRESS: //Address
return supGetMaxOfTwoU64FromHex(
pDlgContext->ListView,
lParam1,
lParam2,
pDlgContext->lvColumnToSort,
pDlgContext->bInverseSort);
case COLUMN_DRVLIST_DRIVER_NAME: //Name
case COLUMN_DRVLIST_MODULE_NAME: //Module
case COLUMN_DRVLIST_SHIMMED: //Shimmed
return supGetMaxCompareTwoFixedStrings(
pDlgContext->ListView,
lParam1,
lParam2,
pDlgContext->lvColumnToSort,
pDlgContext->bInverseSort);
}
}
else {
switch (pDlgContext->lvColumnToSort) {
case COLUMN_DRVLIST_UNLOADED_DRIVER_NAME: //Name
case COLUMN_DRVLIST_UNLOADED_CURRENT_TIME: //CurrentTime
return supGetMaxCompareTwoFixedStrings(
pDlgContext->ListView,
lParam1,
lParam2,
pDlgContext->lvColumnToSort,
pDlgContext->bInverseSort);
case COLUMN_DRVLIST_UNLOADED_START_ADDRESS: //StartAddress
case COLUMN_DRVLIST_UNLOADED_END_ADDRESS: //EndAddress
return supGetMaxOfTwoU64FromHex(
pDlgContext->ListView,
lParam1,
lParam2,
pDlgContext->lvColumnToSort,
pDlgContext->bInverseSort);
}
}
return 0;
}
/*
* DrvListCbEnumerateUnloadedDrivers
*
* Purpose:
*
* Unloaded drivers enumeration callback.
*
*/
BOOL DrvListCbEnumerateUnloadedDrivers(
_In_ PUNLOADED_DRIVERS Entry,
_In_ EXTRASCONTEXT* Context
)
{
INT lvItemIndex;
LPWSTR lpName;
HWND hwndList;
LVITEM lvitem;
WCHAR szBuffer[100];
hwndList = Context->ListView;
if (Entry->StartAddress && Entry->EndAddress) {
if (!NT_SUCCESS(ObIsValidUnicodeString(&Entry->Name)))
lpName = T_Unknown;
else
lpName = Entry->Name.Buffer;
RtlSecureZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_TEXT | LVIF_IMAGE;
lvitem.iItem = MAXINT;
lvitem.iImage = g_TypeDriver.ImageIndex;
lvitem.pszText = lpName;
lvItemIndex = ListView_InsertItem(hwndList, &lvitem);
if (lvItemIndex >= 0) {
lvitem.pszText = szBuffer;
//StartAddress
szBuffer[0] = L'0';
szBuffer[1] = L'x';
szBuffer[2] = 0;
u64tohex((ULONG_PTR)Entry->StartAddress, &szBuffer[2]);
lvitem.iSubItem = 1;
lvitem.iItem = lvItemIndex;
ListView_SetItem(hwndList, &lvitem);
//EndAddress
szBuffer[0] = L'0';
szBuffer[1] = L'x';
szBuffer[2] = 0;
u64tohex((ULONG_PTR)Entry->EndAddress, &szBuffer[2]);
lvitem.iSubItem = 2;
ListView_SetItem(hwndList, &lvitem);
//CurrentTime
szBuffer[0] = 0;
supPrintTimeConverted(&Entry->CurrentTime, szBuffer, RTL_NUMBER_OF(szBuffer));
lvitem.iSubItem = 3;
ListView_SetItem(hwndList, &lvitem);
}
}
return FALSE;
}
/*
* DrvListUnloadedDrivers
*
* Purpose:
*
* Unloaded drivers query and list routine.
*
*/
VOID DrvListUnloadedDrivers(
_In_ EXTRASCONTEXT* Context,
_In_ BOOLEAN bRefresh
)
{
HWND hwndList = Context->ListView;
WCHAR szBuffer[100];
if (bRefresh) {
ListView_DeleteAllItems(hwndList);
}
supDisableRedraw(hwndList);
if (!kdEnumerateMmUnloadedDrivers(
(PENUMERATE_UNLOADED_DRIVERS_CALLBACK)DrvListCbEnumerateUnloadedDrivers,
(PVOID)Context))
{
_strcpy(szBuffer, TEXT("Could not resolve MmUnloadedDrivers"));
supStatusBarSetText(Context->StatusBar, 0, (LPWSTR)&szBuffer);
return;
}
DrvUpdateStatusBar(Context, -1);
ListView_SortItemsEx(hwndList,
&DrvDlgCompareFunc,
(LPARAM)Context);
supEnableRedraw(hwndList);
}
/*
* DrvListDrivers
*
* Purpose:
*
* Drivers query and list routine.
*
*/
VOID DrvListDrivers(
_In_ EXTRASCONTEXT* Context,
_In_ BOOLEAN bRefresh
)
{
INT lvItemIndex;
ULONG i;
PCHAR lpDriverName;
HWND hwndList = Context->ListView;
LVITEM lvitem;
WCHAR szBuffer[MAX_PATH * 2];
GUID shimGUID;
SUP_SHIM_INFO* shimInfo;
RTL_PROCESS_MODULES* pModulesList = NULL;
PRTL_PROCESS_MODULE_INFORMATION pModule;
g_cDrvShimmed = 0;
if (bRefresh) {
ListView_DeleteAllItems(hwndList);
kdQueryKernelShims(&g_kdctx, TRUE);
}
pModulesList = (PRTL_PROCESS_MODULES)supGetLoadedModulesList(NULL);
if (pModulesList == NULL)
return;
if (g_cDrvFilters) {
supFilterDestroyList(&g_DrvFilterListHead);
}
else {
InitializeListHead(&g_DrvFilterListHead);
}
g_cDrvFilters = supFilterCreateList(&g_DrvFilterListHead);
supDisableRedraw(hwndList);
for (i = 0; i < pModulesList->NumberOfModules; i++) {
pModule = &pModulesList->Modules[i];
if ((ULONG_PTR)pModule->ImageBase < g_kdctx.SystemRangeStart)
continue;
RtlSecureZeroMemory(&lvitem, sizeof(lvitem));
//LoadOrder
szBuffer[0] = 0;
ultostr(pModule->LoadOrderIndex, szBuffer);
lvitem.mask = LVIF_TEXT | LVIF_IMAGE;
lvitem.iItem = MAXINT;
lvitem.iImage = g_TypeDriver.ImageIndex;
lvitem.pszText = szBuffer;
lvItemIndex = ListView_InsertItem(hwndList, &lvitem);
if (lvItemIndex == -1)
continue;
//Name
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
//
// Handle malformed result.
//
if (pModule->OffsetToFileName > RTL_NUMBER_OF(pModule->FullPathName)) {
_strcpy(szBuffer, T_Unknown);
}
else {
lpDriverName = (PCHAR)&pModule->FullPathName[pModule->OffsetToFileName];
if (*lpDriverName == 0)
{
_strcpy(szBuffer, T_Unknown);
}
else {
MultiByteToWideChar(
CP_ACP, 0,
(LPCSTR)lpDriverName,
-1,
szBuffer,
MAX_PATH);
}
}
lvitem.mask = LVIF_TEXT;
lvitem.iSubItem = 1;
lvitem.pszText = szBuffer;
lvitem.iItem = lvItemIndex;
ListView_SetItem(hwndList, &lvitem);
//Address
szBuffer[0] = L'0';
szBuffer[1] = L'x';
szBuffer[2] = 0;
u64tohex((ULONG_PTR)pModule->ImageBase, &szBuffer[2]);
lvitem.iSubItem = 2;
ListView_SetItem(hwndList, &lvitem);
//Size
szBuffer[0] = 0;
ultostr(pModule->ImageSize, szBuffer);
lvitem.iSubItem = 3;
ListView_SetItem(hwndList, &lvitem);
//FullName
RtlSecureZeroMemory(szBuffer, sizeof(szBuffer));
MultiByteToWideChar(
CP_ACP,
0,
(LPCSTR)&pModule->FullPathName,
-1,
szBuffer,
MAX_PATH);
lvitem.iSubItem = 4;
ListView_SetItem(hwndList, &lvitem);
//Shimmed
if (DrvDlgShimsEnabled) {
szBuffer[0] = 0;
if (supIsDriverShimmed(
&g_kdctx.Data->KseEngineDump,
pModule->ImageBase,
&shimGUID))
{
g_cDrvShimmed += 1;
shimInfo = supGetDriverShimInformation(shimGUID);
if (shimInfo) {
RtlStringCchPrintfSecure(szBuffer,
RTL_NUMBER_OF(szBuffer),
L"%ws: %ws",
shimInfo->KseShimName,
shimInfo->OwnerModule);
}
else {
_strcpy(szBuffer, TEXT("Yes"));
}
}
lvitem.iSubItem = 5;
ListView_SetItem(hwndList, &lvitem);
}
}
supHeapFree(pModulesList);
DrvUpdateStatusBar(Context, -1);
ListView_SortItemsEx(hwndList,
&DrvDlgCompareFunc,
(LPARAM)Context);
supEnableRedraw(hwndList);
}
/*
* DrvDlgHandleNotify
*
* Purpose:
*
* WM_NOTIFY processing for Driver list dialogs.
*
*/
BOOL CALLBACK DrvDlgHandleNotify(
_In_ EXTRASCONTEXT* Context,
_In_ LPARAM lParam
)
{
INT nImageIndex;
LPNMLISTVIEW NMListView = (LPNMLISTVIEW)lParam;
if (NMListView->hdr.idFrom != ID_EXTRASLIST)
return FALSE;
switch (NMListView->hdr.code) {
case LVN_COLUMNCLICK:
Context->bInverseSort = (~Context->bInverseSort) & 1;
Context->lvColumnToSort = NMListView->iSubItem;
ListView_SortItemsEx(Context->ListView,
DrvDlgCompareFunc,
Context);
nImageIndex = ImageList_GetImageCount(g_ListViewImages);
if (Context->bInverseSort)
nImageIndex -= 2; //sort down/up images are always at the end of g_ListViewImages
else
nImageIndex -= 1;
supUpdateLvColumnHeaderImage(
Context->ListView,
Context->lvColumnCount,
Context->lvColumnToSort,
nImageIndex);
break;
case NM_DBLCLK:
DrvListViewProperties(Context);
break;
case NM_CLICK:
DrvUpdateStatusBar(Context, NMListView->iItem);
break;
case LVN_ITEMCHANGED:
if ((NMListView->uNewState & LVIS_SELECTED) &&
!(NMListView->uOldState & LVIS_SELECTED))
{
DrvUpdateStatusBar(Context, NMListView->iItem);
}
break;
default:
return FALSE;
}
return TRUE;
}
/*
* DrvDlgHandleWMCommand
*
* Purpose:
*
* WM_COMMAND handler.
*
*/
VOID DrvDlgHandleWMCommand(
_In_ HWND hwndDlg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
EXTRASCONTEXT* pDlgContext = (EXTRASCONTEXT*)GetProp(hwndDlg, T_DLGCONTEXT);
LPWSTR lpFileName;
UNREFERENCED_PARAMETER(lParam);
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case ID_OBJECT_COPY:
if (pDlgContext) {
supListViewCopyItemValueToClipboard(pDlgContext->ListView,
pDlgContext->lvItemHit,
pDlgContext->lvColumnHit);
}
break;
case IDCANCEL:
SendMessage(hwndDlg, WM_CLOSE, 0, 0);
break;
case ID_DRVLIST_DUMP:
DrvDumpDriver(pDlgContext, FALSE);
break;
case ID_DRVLIST_DUMPFIXED:
DrvDumpDriver(pDlgContext, TRUE);
break;
case ID_JUMPTOFILE:
if (pDlgContext) {
supJumpToFileListView(pDlgContext->ListView, COLUMN_DRVLIST_MODULE_NAME);
}
break;
case ID_DRVLIST_SAVE:
if (pDlgContext) {
if (pDlgContext->DialogMode == DrvModeNormal)
lpFileName = TEXT("Drivers.csv");
else
lpFileName = TEXT("UnloadedDrivers.csv");
if (supListViewExportToFile(
lpFileName,
hwndDlg,
pDlgContext->ListView))
{
supStatusBarSetText(pDlgContext->StatusBar, 1, T_LIST_EXPORT_SUCCESS);
}
}
break;
case ID_DRVLIST_VIEW_WDX:
extrasViewWithWinDepends(pDlgContext, COLUMN_DRVLIST_MODULE_NAME);
break;
case ID_DRVLIST_PROP:
if (pDlgContext) {
DrvListViewProperties(pDlgContext);
}
break;
case ID_DRVLIST_REFRESH:
if (pDlgContext) {
if (pDlgContext->DialogMode == DrvModeNormal) {
DrvListDrivers(pDlgContext, TRUE);
}
else {
DrvListUnloadedDrivers(pDlgContext, TRUE);
}
}
break;
case ID_CALC_HASH_MD5:
case ID_CALC_HASH_SHA1:
case ID_CALC_HASH_SHA256:
case ID_CALC_HASH_SHA384:
case ID_CALC_HASH_SHA512:
case ID_CALC_HASH_PAGE_SHA1:
case ID_CALC_HASH_PAGE_SHA256:
DrvListCopyHash(pDlgContext, LOWORD(wParam));
break;
}
}
/*
* DrvListSetTooltip
*
* Purpose:
*
* Collect all information for tooltip and set it.
*
*/
VOID DrvListSetTooltip(
_In_ EXTRASCONTEXT* Context,
_In_ HWND ListViewHandle,
_In_ INT iItem
)
{
ULONG_PTR drvBase;
BOOL bShimmed;
GUID shimGUID;
SUP_SHIM_INFO* shimInfo;
SIZE_T cchText;
SIZE_T cchRemaining;
SIZE_T cchWritten;
int charsWritten;
WCHAR* lpText;
WCHAR szBuffer[MAX_PATH];
WCHAR szNameWithoutExt[MAX_PATH];
if (Context == NULL)
return;
DrvTooltipFreeBuffer(Context);
cchText = 4096;
lpText = (WCHAR*)supHeapAlloc(cchText * sizeof(WCHAR));
if (lpText == NULL)
return;
lpText[0] = 0;
cchWritten = 0;
//
// Name
//
RtlSecureZeroMemory(&szBuffer, sizeof(szBuffer));
supGetItemText2(ListViewHandle, iItem,
COLUMN_DRVLIST_DRIVER_NAME, szBuffer, MAX_PATH);
charsWritten = RtlStringCchPrintfSecure(&lpText[cchWritten],
cchText,
TEXT("%ws"),
szBuffer);
if (charsWritten > 0) {
cchWritten += charsWritten;
}
szNameWithoutExt[0] = 0;
_filename_noext(szNameWithoutExt, szBuffer);
//
// Base
//
szBuffer[0] = 0;
supGetItemText2(ListViewHandle, iItem,
COLUMN_DRVLIST_DRIVER_ADDRESS, szBuffer, 32);
cchRemaining = cchText - cchWritten;
if (cchRemaining) {
charsWritten = RtlStringCchPrintfSecure(&lpText[cchWritten],
cchRemaining,
TEXT("\n%ws\n"),
szBuffer);
if (charsWritten > 0) {
cchWritten += charsWritten;
}
}
drvBase = hextou64(&szBuffer[2]);
//
// Module name
//
szBuffer[0] = 0;
supGetItemText2(ListViewHandle, iItem,
COLUMN_DRVLIST_MODULE_NAME, szBuffer, MAX_PATH);
cchRemaining = cchText - cchWritten;
if (cchRemaining) {
charsWritten = RtlStringCchPrintfSecure(&lpText[cchWritten],
cchRemaining,
TEXT("%ws"),
szBuffer);
if (charsWritten > 0) {
cchWritten += charsWritten;
}
}
//
// Filter driver mark
//
if (supFilterFindByName(&g_DrvFilterListHead, szNameWithoutExt)) {
cchRemaining = cchText - cchWritten;
if (cchRemaining) {
charsWritten = RtlStringCchPrintfSecure(&lpText[cchWritten],
cchRemaining,
TEXT("\nRegistered as filter"));
if (charsWritten > 0) {
cchWritten += charsWritten;
}
}
}
//
// Shim desc
//
szBuffer[0] = 0;
supGetItemText2(ListViewHandle, iItem,
COLUMN_DRVLIST_SHIMMED, szBuffer, MAX_PATH);
if (szBuffer[0]) {
bShimmed = supIsDriverShimmed(&g_kdctx.Data->KseEngineDump, (PVOID)drvBase, &shimGUID);
if (bShimmed) {
shimInfo = supGetDriverShimInformation(shimGUID);
if (shimInfo) {
cchRemaining = cchText - cchWritten;
if (cchRemaining) {
charsWritten = RtlStringCchPrintfSecure(&lpText[cchWritten],
cchRemaining,
L"\n\n%ws\n%ws",
shimInfo->KseShimName,
shimInfo->Description);
if (charsWritten > 0) {
cchWritten += charsWritten;
}
}
}
}
}
Context->TooltipBuffer = lpText;
}
/*
* DrvListViewHookProc
*
* Purpose:
*
* Drivers Dialog listview hook handler.
*
*/
LRESULT CALLBACK DrvListViewHookProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
HWND hwndTT;
LVHITTESTINFO ht;
TOOLINFO toolInfo;
BOOL bCheckPass = FALSE;
static int oldX = -1, oldY = -1;
static int lastItem = -1;
INT currentItem;
hwndTT = (HWND)DrvDlgContext[DrvModeNormal].TooltipInfo;
switch (uMsg) {
case WM_MOUSEMOVE:
RtlSecureZeroMemory(&ht, sizeof(ht));
ht.pt.x = GET_X_LPARAM(lParam);
ht.pt.y = GET_Y_LPARAM(lParam);
if (ChildWindowFromPoint(hwnd, ht.pt) == hwnd) {
if (ListView_SubItemHitTest(hwnd, &ht) != -1) {
bCheckPass = (ht.iSubItem == COLUMN_DRVLIST_DRIVER_NAME);
}
}
//
// If tooltip window is not available, skip tooltip actions.
//
if (hwndTT == NULL || !IsWindow(hwndTT)) {
lastItem = -1;
oldX = oldY = -1;
break;
}
//
// Deactivate tooltip if not on the name column or no item.
//
if (!bCheckPass || !(ht.flags & LVHT_ONITEM)) {
if (lastItem != -1) {
RtlSecureZeroMemory(&toolInfo, sizeof(toolInfo));
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = DrvDlgContext[DrvModeNormal].hwndDlg;
toolInfo.uFlags = TTF_TRACK | TTF_ABSOLUTE | TTF_IDISHWND;
toolInfo.uId = (UINT_PTR)hwnd;
SendMessage(hwndTT, TTM_TRACKACTIVATE, FALSE, (LPARAM)&toolInfo);
}
lastItem = -1;
oldX = oldY = -1;
break;
}
//
// At this point we are over a name subitem on an item.
// Only update tooltip when the hovered item changed or cursor moved sufficiently.
//
currentItem = ht.iItem;
if ((currentItem != lastItem) || (ht.pt.x != oldX) || (ht.pt.y != oldY)) {
oldX = ht.pt.x;
oldY = ht.pt.y;
DrvListSetTooltip(&DrvDlgContext[DrvModeNormal], hwnd, currentItem);
RtlSecureZeroMemory(&toolInfo, sizeof(toolInfo));
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.hwnd = DrvDlgContext[DrvModeNormal].hwndDlg;
toolInfo.uFlags = TTF_TRACK | TTF_ABSOLUTE | TTF_IDISHWND;
toolInfo.uId = (UINT_PTR)hwnd;
GetCursorPos(&ht.pt);
SendMessage(hwndTT, TTM_TRACKACTIVATE, (WPARAM)TRUE, (LPARAM)&toolInfo);
ht.pt.x += 20;
ht.pt.y += 20;
SendMessage(hwndTT, TTM_TRACKPOSITION, 0, (LPARAM)MAKELONG(ht.pt.x, ht.pt.y));
SendMessage(hwndTT, TTM_UPDATE, 0, 0);
lastItem = currentItem;
}
break;
}
return CallWindowProc(g_OriginalListViewProc, hwnd, uMsg, wParam, lParam);
}
/*
* DrvDlgOnInit
*
* Purpose:
*
* Drivers Dialog WM_INITDIALOG handler.
*
*/
VOID DrvDlgOnInit(
_In_ HWND hwndDlg,
_In_ LPARAM lParam
)
{
INT iImage = ImageList_GetImageCount(g_ListViewImages) - 1, iColumn;
EXTRASCONTEXT* pDlgContext = (EXTRASCONTEXT*)lParam;
LVCOLUMNS_DATA* pvColumnsData;
ULONG columnsCount;
LPWSTR lpCaption;
LVCOLUMNS_DATA columnDataDrvList[] =
{
{ L"LoadOrder", 100, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, iImage },
{ L"Name", 150, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE },
{ L"Address", 130, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE },
{ L"Size", 80, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE },
{ L"Image Path", 280, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE }
};
LVCOLUMNS_DATA columnsDataUnloadedDrvList[] = {
{ L"Name", 150, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, iImage },
{ L"StartAddress", 140, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE },
{ L"EndAddress", 140, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE },
{ L"CurrentTime", 140, LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT, I_IMAGENONE }
};
SetProp(hwndDlg, T_DLGCONTEXT, (HANDLE)lParam);
supCenterWindowSpecifyParent(hwndDlg, g_hwndMain);
pDlgContext->hwndDlg = hwndDlg;
pDlgContext->lvColumnHit = -1;
pDlgContext->lvItemHit = -1;
switch (pDlgContext->DialogMode) {
case DrvModeUnloaded:
lpCaption = TEXT("Unloaded Drivers");
pvColumnsData = columnsDataUnloadedDrvList;
columnsCount = RTL_NUMBER_OF(columnsDataUnloadedDrvList);
break;
default:
lpCaption = TEXT("Drivers");
pvColumnsData = columnDataDrvList;
columnsCount = RTL_NUMBER_OF(columnDataDrvList);
break;
}
SetWindowText(hwndDlg, lpCaption);
pDlgContext->TooltipBuffer = NULL;
pDlgContext->StatusBar = GetDlgItem(hwndDlg, ID_EXTRASLIST_STATUSBAR);
extrasSetDlgIcon(pDlgContext);
pDlgContext->ListView = GetDlgItem(hwndDlg, ID_EXTRASLIST);
if (pDlgContext->ListView) {
pDlgContext->lvColumnHit = -1;
pDlgContext->lvItemHit = -1;
//
// Set listview imagelist, style flags and theme.
//
supSetListViewSettings(pDlgContext->ListView,
LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP | LVS_EX_LABELTIP,
FALSE,
TRUE,
g_ListViewImages,
LVSIL_SMALL);
if (pDlgContext->DialogMode == DrvModeNormal) {
pDlgContext->TooltipInfo = (PVOID)supCreateTrackingToolTip(ID_EXTRASLIST, hwndDlg);
if (pDlgContext->TooltipInfo) {
g_OriginalListViewProc = (WNDPROC)SetWindowLongPtr(pDlgContext->ListView,
GWLP_WNDPROC,
(LONG_PTR)&DrvListViewHookProc);
}
}
//
// And columns and remember their count.
//
iColumn = supAddLVColumnsFromArray(
pDlgContext->ListView,
pvColumnsData,
columnsCount);
pDlgContext->lvColumnCount = iColumn;
if (pDlgContext->DialogMode == DrvModeNormal) {
//
// Add "Shimmed" column on supported Windows version.
//
if (g_NtBuildNumber >= NT_WIN10_THRESHOLD1) {
if (kdQueryKernelShims(&g_kdctx, FALSE)) {
supAddListViewColumn(pDlgContext->ListView,
iColumn,
iColumn,
iColumn,
I_IMAGENONE,
LVCFMT_CENTER | LVCFMT_BITMAP_ON_RIGHT,
TEXT("Shimmed"), 100);
DrvDlgShimsEnabled = TRUE;
pDlgContext->lvColumnCount += 1;
}
}
DrvListDrivers(pDlgContext, FALSE);
}
else {
DrvListUnloadedDrivers(pDlgContext, FALSE);
}
SendMessage(hwndDlg, WM_SIZE, 0, 0);
SetFocus(pDlgContext->ListView);
}
}
/*
* DrvDlgProc
*
* Purpose:
*
* Drivers Dialog window procedure.
*
*/
INT_PTR CALLBACK DrvDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
EXTRASCONTEXT* pDlgContext;
if (uMsg == g_WinObj.SettingsChangeMessage) {
pDlgContext = (EXTRASCONTEXT*)GetProp(hwndDlg, T_DLGCONTEXT);
if (pDlgContext) {
extrasHandleSettingsChange(pDlgContext);
return TRUE;
}
}
switch (uMsg) {
case WM_INITDIALOG:
DrvDlgOnInit(hwndDlg, lParam);
break;
case WM_GETMINMAXINFO:
if (lParam) {
supSetMinMaxTrackSize((PMINMAXINFO)lParam,
DRVLISTDLG_TRACKSIZE_MIN_X,
DRVLISTDLG_TRACKSIZE_MIN_Y,
TRUE);
}
break;
case WM_NOTIFY:
pDlgContext = (EXTRASCONTEXT*)GetProp(hwndDlg, T_DLGCONTEXT);
if (pDlgContext) {
DrvDlgHandleNotify(
pDlgContext,
lParam);
#pragma warning(push)
#pragma warning(disable: 26454)
if (((LPNMHDR)lParam)->code == TTN_GETDISPINFO) {
#pragma warning(pop)
LPNMTTDISPINFO lpnmtt;
lpnmtt = (LPNMTTDISPINFO)lParam;
if (pDlgContext->DialogMode == DrvModeNormal) {
if (pDlgContext->TooltipInfo &&
lpnmtt->hdr.hwndFrom == (HWND)pDlgContext->TooltipInfo)
{
if ((HWND)lpnmtt->hdr.idFrom == pDlgContext->ListView) {
lpnmtt->lpszText = pDlgContext->TooltipBuffer;
}
}
}
}
}
break;
case WM_SIZE:
extrasSimpleListResize(hwndDlg);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_CLOSE:
pDlgContext = (EXTRASCONTEXT*)RemoveProp(hwndDlg, T_DLGCONTEXT);
if (pDlgContext) {
if (pDlgContext->TooltipInfo)
DestroyWindow((HWND)pDlgContext->TooltipInfo);
DrvTooltipFreeBuffer(pDlgContext);
extrasRemoveDlgIcon(pDlgContext);
if (pDlgContext->DialogMode == DrvModeNormal) {
kdDestroyShimmedDriversList(&g_kdctx.Data->KseEngineDump);
supFilterDestroyList(&g_DrvFilterListHead);
g_cDrvFilters = 0;
}
}
if (DumpWorkerWindow) {
SendMessage(DumpWorkerWindow, WM_CLOSE, 0, 0);
DumpWorkerWindow = NULL;
}
DestroyWindow(hwndDlg);
break;
case WM_COMMAND:
DrvDlgHandleWMCommand(hwndDlg, wParam, lParam);
break;
case WM_CONTEXTMENU:
pDlgContext = (EXTRASCONTEXT*)GetProp(hwndDlg, T_DLGCONTEXT);
if (pDlgContext) {
supHandleContextMenuMsgForListView(hwndDlg,
wParam,
lParam,
pDlgContext->ListView,
(pfnPopupMenuHandler)DrvHandlePopupMenu,
pDlgContext);
}
break;
default:
return FALSE;
}
return TRUE;
}
/*
* extrasDrvDlgWorkerThread
*
* Purpose:
*
* Drivers Dialog worker thread.
*
*/
DWORD extrasDrvDlgWorkerThread(
_In_ PVOID Parameter
)
{
BOOL bResult;
HWND hwndDlg;
HACCEL acceleratorTable;
HANDLE prev;
EXTRASCONTEXT* pDlgContext = (EXTRASCONTEXT*)Parameter;
MSG message;
FAST_EVENT fastEvent;
hwndDlg = CreateDialogParam(g_WinObj.hInstance,
MAKEINTRESOURCE(IDD_DIALOG_EXTRASLIST),
0,
&DrvDlgProc,
(LPARAM)pDlgContext);
fastEvent = DrvDlgInitializedEvents[pDlgContext->DialogMode];
supSetFastEvent(&fastEvent);
acceleratorTable = LoadAccelerators(g_WinObj.hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
if (hwndDlg) {
do {
bResult = GetMessage(&message, NULL, 0, 0);
if (bResult == -1)
break;
if (IsDialogMessage(hwndDlg, &message)) {
TranslateAccelerator(hwndDlg, acceleratorTable, &message);
}
else {
TranslateMessage(&message);
DispatchMessage(&message);
}
} while (bResult != 0);
}
supResetFastEvent(&fastEvent);
if (acceleratorTable)
DestroyAcceleratorTable(acceleratorTable);
prev = InterlockedExchangePointer((PVOID*)&DrvDlgThreadHandles[pDlgContext->DialogMode], NULL);
if (prev) CloseHandle(prev);
return 0;
}
/*
* extrasCreateDriversDialog
*
* Purpose:
*
* Run Drivers Dialog worker thread.
*
*/
VOID extrasCreateDriversDialog(
_In_ DRIVERS_DLG_MODE Mode
)
{
if (Mode < 0 || Mode >= DrvModeMax)
return;
if (!DrvDlgThreadHandles[Mode]) {
RtlSecureZeroMemory(&DrvDlgContext[Mode], sizeof(EXTRASCONTEXT));
DrvDlgContext[Mode].DialogMode = Mode;
DrvDlgThreadHandles[Mode] = supCreateDialogWorkerThread(extrasDrvDlgWorkerThread, (PVOID)&DrvDlgContext[Mode], 0);
if (DrvDlgThreadHandles[Mode])
supWaitForFastEvent(&DrvDlgInitializedEvents[Mode], NULL);
}
}