WinObjEx64/Source/WinObjAdv/findDlg.c

478 lines
11 KiB
C

/*******************************************************************************
*
* (C) COPYRIGHT AUTHORS, 2015
*
* TITLE: FINDDLG.C
*
* VERSION: 1.00
*
* DATE: 17 Feb 2015
*
* 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 "findDlg.h"
static HWND FindDlgList;
static LONG sizes_init = 0, dx1, dx2, dx3, dx4, dx5, dx6, dx7, dx8, dx9, dx10, dx11, dx12, dx13;
//local FindDlg variable controlling sorting direction
BOOL bFindDlgSortInverse = FALSE;
static LONG FindDlgSortColumn = 0;
/*
* FindDlgCompareFunc
*
* Purpose:
*
* FindDlg listview comparer function.
*
*/
INT CALLBACK FindDlgCompareFunc(
_In_ LPARAM lParam1,
_In_ LPARAM lParam2,
_In_ LPARAM lParamSort
)
{
LPWSTR lpItem1, lpItem2;
INT nResult;
lpItem1 = supGetItemText(FindDlgList, (INT)lParam1, (INT)lParamSort, NULL);
if (lpItem1 == NULL)
return 0;
lpItem2 = supGetItemText(FindDlgList, (INT)lParam2, (INT)lParamSort, NULL);
if (lpItem2 == NULL)
return 0;
if (bFindDlgSortInverse)
nResult = _strcmpi(lpItem2, lpItem1);
else
nResult = _strcmpi(lpItem1, lpItem2);
HeapFree(GetProcessHeap(), 0, lpItem1);
HeapFree(GetProcessHeap(), 0, lpItem2);
return nResult;
}
/*
* FindDlgAddListItem
*
* Purpose:
*
* Add item to listview.
*
*/
VOID FindDlgAddListItem(
_In_ HWND hList,
_In_ LPWSTR ObjectName,
_In_ LPWSTR TypeName
)
{
LVITEMW lvitem;
int index;
RtlSecureZeroMemory(&lvitem, sizeof(lvitem));
lvitem.mask = LVIF_TEXT | LVIF_IMAGE;
lvitem.iSubItem = 0;
lvitem.pszText = ObjectName;
lvitem.iItem = 0;
lvitem.iImage = supGetObjectIndexByTypeName(TypeName);
index = ListView_InsertItem(hList, &lvitem);
lvitem.mask = LVIF_TEXT;
lvitem.iSubItem = 1;
lvitem.pszText = TypeName;
lvitem.iItem = index;
ListView_SetItem(hList, &lvitem);
}
/*
* FindDlgResize
*
* Purpose:
*
* FindDlg WM_SIZE handler, remember control position and move them according new window coordinates.
*
*/
VOID FindDlgResize(
HWND hwndDlg
)
{
RECT r1, r2;
HWND hwnd;
POINT p0;
GetClientRect(hwndDlg, &r2);
if (sizes_init == 0) {
sizes_init = 1;
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_GROUPBOXOPTIONS), &r1);
dx1 = r2.right - (r1.right - r1.left);
dx2 = r1.bottom - r1.top;
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_GROUPBOX), &r1);
dx3 = r2.bottom - (r1.bottom - r1.top);
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_LIST), &r1);
dx4 = r2.right - (r1.right - r1.left);
dx5 = r2.bottom - (r1.bottom - r1.top);
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_NAME), &r1);
dx6 = r2.right - (r1.right - r1.left);
dx7 = r1.bottom - r1.top;
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_TYPE), &r1);
p0.x = r1.left;
p0.y = r1.top;
ScreenToClient(hwndDlg, &p0);
dx8 = r2.right - p0.x;
dx9 = p0.y;
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_FIND), &r1);
p0.x = r1.left;
p0.y = r1.top;
ScreenToClient(hwndDlg, &p0);
dx10 = r2.right - p0.x;
dx11 = p0.y;
RtlSecureZeroMemory(&r1, sizeof(r1));
GetWindowRect(GetDlgItem(hwndDlg, ID_SEARCH_TYPELABEL), &r1);
p0.x = r1.left;
p0.y = r1.top;
ScreenToClient(hwndDlg, &p0);
dx12 = r2.right - p0.x;
dx13 = p0.y;
}
//resize groupbox search options
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_GROUPBOXOPTIONS);
if (hwnd) {
SetWindowPos(hwnd, 0, 0, 0, r2.right - dx1, dx2, SWP_NOMOVE | SWP_NOZORDER);
}
//resize groupbox results
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_GROUPBOX);
if (hwnd) {
SetWindowPos(hwnd, 0, 0, 0, r2.right - dx1, r2.bottom - dx3, SWP_NOMOVE | SWP_NOZORDER);
}
//resize listview
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_LIST);
if (hwnd) {
SetWindowPos(hwnd, 0, 0, 0, r2.right - dx4, r2.bottom - dx5, SWP_NOMOVE | SWP_NOZORDER);
}
//resize edit
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_NAME);
if (hwnd) {
SetWindowPos(hwnd, 0, 0, 0, r2.right - dx6, dx7, SWP_NOMOVE | SWP_NOZORDER);
}
//resize combobox
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_TYPE);
if (hwnd) {
SetWindowPos(hwnd, 0, r2.right - dx8, dx9, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_FIND);
if (hwnd) {
SetWindowPos(hwnd, 0, r2.right - dx10, dx11, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
//resize Type label
hwnd = GetDlgItem(hwndDlg, ID_SEARCH_TYPELABEL);
if (hwnd) {
SetWindowPos(hwnd, 0, r2.right - dx12, dx13, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}
RedrawWindow(hwndDlg, NULL, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ERASENOW);
}
/*
* FindDlgHandleNotify
*
* Purpose:
*
* WM_NOTIFY processing for FindDlg listview.
*
*/
VOID FindDlgHandleNotify(
LPNMLISTVIEW nhdr
)
{
LPWSTR lpItemText;
LVCOLUMNW col;
INT c, k;
if (nhdr == NULL)
return;
if (nhdr->hdr.idFrom != ID_SEARCH_LIST)
return;
switch (nhdr->hdr.code) {
case LVN_ITEMCHANGED:
if (!(nhdr->uNewState & LVIS_SELECTED))
break;
lpItemText = supGetItemText(nhdr->hdr.hwndFrom, nhdr->iItem, 0, NULL);
if (lpItemText) {
ListToObject(lpItemText);
HeapFree(GetProcessHeap(), 0, lpItemText);
}
break;
case LVN_COLUMNCLICK:
bFindDlgSortInverse = !bFindDlgSortInverse;
FindDlgSortColumn = ((NMLISTVIEW *)nhdr)->iSubItem;
ListView_SortItemsEx(FindDlgList, &FindDlgCompareFunc, FindDlgSortColumn);
RtlSecureZeroMemory(&col, sizeof(col));
col.mask = LVCF_IMAGE;
col.iImage = -1;
for (c = 0; c < 2; c++)
ListView_SetColumn(FindDlgList, c, &col);
k = ImageList_GetImageCount(ListViewImages);
if (bFindDlgSortInverse)
col.iImage = k - 2;
else
col.iImage = k - 1;
ListView_SetColumn(FindDlgList, ((NMLISTVIEW *)nhdr)->iSubItem, &col);
break;
default:
break;
}
}
/*
* FindDlgProc
*
* Purpose:
*
* Find Dialog window procedure.
*
*/
INT_PTR CALLBACK FindDlgProc(
_In_ HWND hwndDlg,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
WCHAR search_string[MAX_PATH + 1], type_name[MAX_PATH + 1];
LPWSTR pnamestr = (LPWSTR)search_string, ptypestr = (LPWSTR)type_name;
PFO_LIST_ITEM flist, plist;
ULONG cci;
HANDLE hIcon = NULL;
LPNMLISTVIEW nhdr = (LPNMLISTVIEW)lParam;
switch (uMsg) {
case WM_NOTIFY:
FindDlgHandleNotify(nhdr);
break;
case WM_GETMINMAXINFO:
if (lParam) {
((PMINMAXINFO)lParam)->ptMinTrackSize.x = 548;
((PMINMAXINFO)lParam)->ptMinTrackSize.y = 230;
}
break;
case WM_INITDIALOG:
supCenterWindow(hwndDlg);
FindDlgResize(hwndDlg);
hIcon = LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_MAIN), IMAGE_ICON, 0, 0, LR_SHARED);
if (hIcon) {
SetClassLongPtr(hwndDlg, GCLP_HICON, (LONG_PTR)hIcon);
DestroyIcon(hIcon);
}
break;
case WM_SIZE:
FindDlgResize(hwndDlg);
break;
case WM_CLOSE:
DestroyWindow(hwndDlg);
FindDialog = NULL;
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDCANCEL) {
DestroyWindow(hwndDlg);
FindDialog = NULL;
return TRUE;
}
if (LOWORD(wParam) == ID_SEARCH_FIND) {
supSetWaitCursor(TRUE);
EnableWindow(GetDlgItem(hwndDlg, ID_SEARCH_FIND), FALSE);
ListView_DeleteAllItems(FindDlgList);
RtlSecureZeroMemory(&search_string, sizeof(search_string));
RtlSecureZeroMemory(&type_name, sizeof(type_name));
SendMessageW(GetDlgItem(hwndDlg, ID_SEARCH_NAME), WM_GETTEXT, MAX_PATH, (LPARAM)&search_string);
SendMessageW(GetDlgItem(hwndDlg, ID_SEARCH_TYPE), WM_GETTEXT, MAX_PATH, (LPARAM)&type_name);
flist = NULL;
if (search_string[0] == 0)
pnamestr = NULL;
if (type_name[0] == '*')
ptypestr = 0;
FindObject(L"\\", pnamestr, ptypestr, &flist);
cci = 0;
while (flist != NULL) {
FindDlgAddListItem(FindDlgList, flist->ObjectName, flist->ObjectType);
plist = flist->Prev;
HeapFree(GetProcessHeap(), 0, flist);
flist = plist;
cci++;
}
ultostrW(cci, search_string);
_strcatW(search_string, L" Object(s) found");
SendMessageW(GetDlgItem(hwndDlg, ID_SEARCH_GROUPBOX), WM_SETTEXT, 0, (LPARAM)search_string);
ListView_SortItemsEx(FindDlgList, &FindDlgCompareFunc, FindDlgSortColumn);
supSetWaitCursor(FALSE);
EnableWindow(GetDlgItem(hwndDlg, ID_SEARCH_FIND), TRUE);
}
break;
}
return FALSE;
}
/*
* FindDlgAddTypes
*
* Purpose:
*
* Enumerate object types and fill combobox with them.
*
* Elevation required.
*
*/
VOID FindDlgAddTypes(
HWND hwnd
)
{
OBJECT_ATTRIBUTES objattr;
UNICODE_STRING objname;
HANDLE hDirectory = NULL;
NTSTATUS status;
ULONG ctx, rlen;
BOOL cond = TRUE;
POBJECT_DIRECTORY_INFORMATION objinf;
HWND hComboBox = GetDlgItem(hwnd, ID_SEARCH_TYPE);
if (hComboBox) {
SendMessage(hComboBox, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0);
RtlSecureZeroMemory(&objname, sizeof(objname));
RtlInitUnicodeString(&objname, L"\\ObjectTypes");
InitializeObjectAttributes(&objattr, &objname, OBJ_CASE_INSENSITIVE, NULL, NULL);
status = NtOpenDirectoryObject(&hDirectory, FILE_LIST_DIRECTORY, &objattr);
if (NT_SUCCESS(status)) {
ctx = 0;
do {
rlen = 0;
status = NtQueryDirectoryObject(hDirectory, NULL, 0, TRUE, FALSE, &ctx, &rlen);
if (status != STATUS_BUFFER_TOO_SMALL)
break;
objinf = HeapAlloc(GetProcessHeap(), 0, rlen);
if (objinf == NULL)
break;
RtlSecureZeroMemory(objinf, rlen);
status = NtQueryDirectoryObject(hDirectory, objinf, rlen, TRUE, FALSE, &ctx, &rlen);
if (!NT_SUCCESS(status)) {
HeapFree(GetProcessHeap(), 0, objinf);
break;
}
SendMessage(hComboBox, CB_ADDSTRING, (WPARAM)0, (LPARAM)objinf->Name.Buffer);
HeapFree(GetProcessHeap(), 0, objinf);
} while (cond);
NtClose(hDirectory);
}
SendMessage(hComboBox, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"*");
SendMessage(hComboBox, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
}
}
/*
* FindDlgInit
*
* Purpose:
*
* Initialize Find Dialog.
*
*/
VOID FindDlgInit(
VOID
)
{
LVCOLUMNW col;
//do not allow second copy
if (FindDialog)
return;
FindDialog = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_SEARCH), MainWindow, &FindDlgProc, 0);
if (FindDialog == NULL)
return;
FindDlgList = GetDlgItem(FindDialog, ID_SEARCH_LIST);
if (FindDlgList) {
bFindDlgSortInverse = FALSE;
ListView_SetImageList(FindDlgList, ListViewImages, LVSIL_SMALL);
ListView_SetExtendedListViewStyle(FindDlgList, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_GRIDLINES | LVS_EX_LABELTIP);
RtlSecureZeroMemory(&col, sizeof(col));
col.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_FMT | LVCF_WIDTH | LVCF_ORDER | LVCF_IMAGE;
col.iSubItem = 1;
col.pszText = L"Name";
col.fmt = LVCFMT_LEFT | LVCFMT_BITMAP_ON_RIGHT;
col.iOrder = 0;
col.iImage = ImageList_GetImageCount(ListViewImages) - 1;
col.cx = 300;
ListView_InsertColumn(FindDlgList, 1, &col);
col.iSubItem = 2;
col.pszText = L"Type";
col.iOrder = 1;
col.iImage = -1;
col.cx = 100;
ListView_InsertColumn(FindDlgList, 2, &col);
}
FindDlgAddTypes(FindDialog);
}