VOID ReBarLoadLayoutSettings( VOID ) { UINT index = 0; UINT count = 0; PPH_STRING settingsString; PH_STRINGREF remaining; settingsString = PhGetStringSetting(SETTING_NAME_REBAR_CONFIG); remaining = settingsString->sr; if (remaining.Length == 0) return; count = (UINT)SendMessage(RebarHandle, RB_GETBANDCOUNT, 0, 0); for (index = 0; index < count; index++) { PH_STRINGREF idPart; PH_STRINGREF cxPart; PH_STRINGREF stylePart; ULONG64 idInteger; ULONG64 cxInteger; ULONG64 styleInteger; UINT oldBandIndex; REBARBANDINFO rebarBandInfo = { sizeof(REBARBANDINFO), RBBIM_STYLE | RBBIM_SIZE }; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '|', &idPart, &remaining); PhSplitStringRefAtChar(&remaining, '|', &cxPart, &remaining); PhSplitStringRefAtChar(&remaining, '|', &stylePart, &remaining); PhStringToInteger64(&idPart, 10, &idInteger); PhStringToInteger64(&cxPart, 10, &cxInteger); PhStringToInteger64(&stylePart, 10, &styleInteger); if ((oldBandIndex = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (UINT)idInteger, 0)) == UINT_MAX) continue; if (oldBandIndex != index) { SendMessage(RebarHandle, RB_MOVEBAND, oldBandIndex, index); } if (SendMessage(RebarHandle, RB_GETBANDINFO, index, (LPARAM)&rebarBandInfo)) { rebarBandInfo.cx = (UINT)cxInteger; rebarBandInfo.fStyle |= (UINT)styleInteger; SendMessage(RebarHandle, RB_SETBANDINFO, index, (LPARAM)&rebarBandInfo); } } }
VOID StatusBarLoadSettings( VOID ) { ULONG64 buttonCount = 0; PPH_STRING settingsString; PH_STRINGREF remaining; PH_STRINGREF part; settingsString = PhaGetStringSetting(SETTING_NAME_STATUSBAR_CONFIG); remaining = settingsString->sr; if (remaining.Length == 0) { // Load default settings StatusBarLoadDefault(); return; } // Query the number of buttons to insert if (!PhSplitStringRefAtChar(&remaining, '|', &part, &remaining)) { // Load default settings StatusBarLoadDefault(); return; } if (!PhStringToInteger64(&part, 10, &buttonCount)) { // Load default settings StatusBarLoadDefault(); return; } StatusBarItemList = PhCreateList((ULONG)buttonCount); for (ULONG i = 0; i < (ULONG)buttonCount; i++) { PH_STRINGREF idPart; ULONG64 idInteger; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '|', &idPart, &remaining); if (PhStringToInteger64(&idPart, 10, &idInteger)) { PSTATUSBAR_ITEM statusItem; statusItem = PhAllocate(sizeof(STATUSBAR_ITEM)); memset(statusItem, 0, sizeof(STATUSBAR_ITEM)); statusItem->Id = (ULONG)idInteger; PhInsertItemList(StatusBarItemList, i, statusItem); } } }
PPH_LIST PhInitializeColumnSetList( _In_ PWSTR SettingName ) { PPH_LIST columnSetList; PPH_STRING settingsString; ULONG64 count; ULONG64 index; PH_STRINGREF remaining; PH_STRINGREF part; columnSetList = PhCreateList(10); settingsString = PhaGetStringSetting(SettingName); remaining = settingsString->sr; if (remaining.Length == 0) goto CleanupExit; if (!PhSplitStringRefAtChar(&remaining, '-', &part, &remaining)) goto CleanupExit; if (!PhStringToInteger64(&part, 10, &count)) goto CleanupExit; for (index = 0; index < count; index++) { PH_STRINGREF columnSetNamePart; PH_STRINGREF columnSetSettingPart; PH_STRINGREF columnSetSortPart; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '-', &columnSetNamePart, &remaining); PhSplitStringRefAtChar(&remaining, '-', &columnSetSettingPart, &remaining); PhSplitStringRefAtChar(&remaining, '-', &columnSetSortPart, &remaining); { PPH_COLUMN_SET_ENTRY entry; entry = PhAllocate(sizeof(PH_COLUMN_SET_ENTRY)); entry->Name = PhCreateString2(&columnSetNamePart); entry->Setting = PhCreateString2(&columnSetSettingPart); entry->Sorting = PhCreateString2(&columnSetSortPart); PhAddItemList(columnSetList, entry); } } CleanupExit: return columnSetList; }
VOID PhpAddDisabledPlugins( VOID ) { PPH_STRING disabled; PH_STRINGREF remainingPart; PH_STRINGREF part; PPH_PLUGIN disabledPlugin; PPH_STRING displayText; INT lvItemIndex; disabled = PhGetStringSetting(L"DisabledPlugins"); remainingPart = disabled->sr; while (remainingPart.Length != 0) { PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart); if (part.Length != 0) { if (!PhpIsPluginLoadedByBaseName(&part)) { disabledPlugin = PhpCreateDisabledPlugin(&part); PhAddItemList(DisabledPluginInstances, disabledPlugin); PhAddItemSimpleHashtable(DisabledPluginLookup, disabledPlugin, NULL); displayText = PhCreateString2(&part); lvItemIndex = PhAddListViewItem(PluginsLv, MAXINT, displayText->Buffer, disabledPlugin); PhDereferenceObject(displayText); } } } PhDereferenceObject(disabled); }
/** * Parses an application name and sub-ID pair. * * \param CompoundId The compound identifier. * \param AppName A variable which receives the application name. * \param SubId A variable which receives the sub-ID. */ BOOLEAN PhEmParseCompoundId( _In_ PPH_STRINGREF CompoundId, _Out_ PPH_STRINGREF AppName, _Out_ PULONG SubId ) { PH_STRINGREF firstPart; PH_STRINGREF secondPart; ULONG64 integer; firstPart = *CompoundId; if (firstPart.Length == 0) return FALSE; if (firstPart.Buffer[0] != '+') return FALSE; PhSkipStringRef(&firstPart, sizeof(WCHAR)); PhSplitStringRefAtChar(&firstPart, '+', &firstPart, &secondPart); if (firstPart.Length == 0 || secondPart.Length == 0) return FALSE; if (!PhStringToInteger64(&secondPart, 10, &integer)) return FALSE; *AppName = firstPart; *SubId = (ULONG)integer; return TRUE; }
BOOLEAN PhpLocateDisabledPlugin( _In_ PPH_STRING List, _In_ PPH_STRINGREF BaseName, _Out_opt_ PULONG FoundIndex ) { PH_STRINGREF namePart; PH_STRINGREF remainingPart; remainingPart = List->sr; while (remainingPart.Length != 0) { PhSplitStringRefAtChar(&remainingPart, '|', &namePart, &remainingPart); if (PhEqualStringRef(&namePart, BaseName, TRUE)) { if (FoundIndex) *FoundIndex = (ULONG)(namePart.Buffer - List->Buffer); return TRUE; } } return FALSE; }
VOID DiskDrivesLoadList( VOID ) { PPH_STRING settingsString; PH_STRINGREF remaining; settingsString = PhaGetStringSetting(SETTING_NAME_DISK_LIST); remaining = settingsString->sr; while (remaining.Length != 0) { PH_STRINGREF part; DV_DISK_ID id; PDV_DISK_ENTRY entry; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, ',', &part, &remaining); InitializeDiskId(&id, PhCreateString2(&part)); entry = CreateDiskEntry(&id); DeleteDiskId(&id); entry->UserReference = TRUE; } }
static BOOLEAN NTAPI PhpPreviousInstancesCallback( _In_ PPH_STRINGREF Name, _In_ PPH_STRINGREF TypeName, _In_opt_ PVOID Context ) { ULONG64 processId64; PH_STRINGREF firstPart; PH_STRINGREF secondPart; if ( PhStartsWithStringRef2(Name, L"PhMutant_", TRUE) && PhSplitStringRefAtChar(Name, L'_', &firstPart, &secondPart) && PhStringToInteger64(&secondPart, 10, &processId64) ) { HANDLE processHandle; if (NT_SUCCESS(PhOpenProcess( &processHandle, SYNCHRONIZE | PROCESS_TERMINATE, ULongToHandle((ULONG)processId64) ))) { NtTerminateProcess(processHandle, 1); NtClose(processHandle); } } return TRUE; }
static BOOLEAN ParseVersionString( _Inout_ PPH_UPDATER_CONTEXT Context ) { PH_STRINGREF sr, majorPart, minorPart, revisionPart; ULONG64 majorInteger = 0, minorInteger = 0, revisionInteger = 0; PhInitializeStringRef(&sr, Context->Version->Buffer); PhInitializeStringRef(&revisionPart, Context->RevVersion->Buffer); if (PhSplitStringRefAtChar(&sr, '.', &majorPart, &minorPart)) { PhStringToInteger64(&majorPart, 10, &majorInteger); PhStringToInteger64(&minorPart, 10, &minorInteger); PhStringToInteger64(&revisionPart, 10, &revisionInteger); Context->MajorVersion = (ULONG)majorInteger; Context->MinorVersion = (ULONG)minorInteger; Context->RevisionVersion = (ULONG)revisionInteger; return TRUE; } return FALSE; }
PPH_STRING PhpGetX500Value( _In_ PPH_STRINGREF String, _In_ PPH_STRINGREF KeyName ) { WCHAR keyNamePlusEqualsBuffer[10]; PH_STRINGREF keyNamePlusEquals; SIZE_T keyNameLength; PH_STRINGREF firstPart; PH_STRINGREF remainingPart; keyNameLength = KeyName->Length / sizeof(WCHAR); assert(!(keyNameLength > sizeof(keyNamePlusEquals) / sizeof(WCHAR) - 1)); keyNamePlusEquals.Buffer = keyNamePlusEqualsBuffer; keyNamePlusEquals.Length = (keyNameLength + 1) * sizeof(WCHAR); memcpy(keyNamePlusEquals.Buffer, KeyName->Buffer, KeyName->Length); keyNamePlusEquals.Buffer[keyNameLength] = '='; // Find "Key=". if (!PhSplitStringRefAtString(String, &keyNamePlusEquals, FALSE, &firstPart, &remainingPart)) return NULL; if (remainingPart.Length == 0) return NULL; // Is the value quoted? If so, return the part inside the quotes. if (remainingPart.Buffer[0] == '"') { PhSkipStringRef(&remainingPart, sizeof(WCHAR)); if (!PhSplitStringRefAtChar(&remainingPart, '"', &firstPart, &remainingPart)) return NULL; return PhCreateString2(&firstPart); } else { PhSplitStringRefAtChar(&remainingPart, ',', &firstPart, &remainingPart); return PhCreateString2(&firstPart); } }
VOID PhpExecuteCallbackForAllPlugins( _In_ PH_PLUGIN_CALLBACK Callback, _In_ BOOLEAN StartupParameters ) { PPH_AVL_LINKS links; links = PhMinimumElementAvlTree(&PhPluginsByName); while (links) { PPH_PLUGIN plugin = CONTAINING_RECORD(links, PH_PLUGIN, Links); PPH_LIST parameters = NULL; // Find relevant startup parameters for this plugin. if (StartupParameters && PhStartupParameters.PluginParameters) { ULONG i; for (i = 0; i < PhStartupParameters.PluginParameters->Count; i++) { PPH_STRING string = PhStartupParameters.PluginParameters->Items[i]; PH_STRINGREF pluginName; PH_STRINGREF parameter; if (PhSplitStringRefAtChar(&string->sr, ':', &pluginName, ¶meter) && PhEqualStringRef(&pluginName, &plugin->Name, FALSE) && parameter.Length != 0) { if (!parameters) parameters = PhCreateList(3); PhAddItemList(parameters, PhCreateString2(¶meter)); } } } PhInvokeCallback(PhGetPluginCallback(plugin, Callback), parameters); if (parameters) { ULONG i; for (i = 0; i < parameters->Count; i++) PhDereferenceObject(parameters->Items[i]); PhDereferenceObject(parameters); } links = PhSuccessorElementAvlTree(links); } }
VOID NetAdaptersLoadList( VOID ) { PPH_STRING settingsString; PH_STRINGREF remaining; settingsString = PhaGetStringSetting(SETTING_NAME_INTERFACE_LIST); remaining = settingsString->sr; while (remaining.Length != 0) { ULONG64 ifindex; ULONG64 luid64; PH_STRINGREF part1; PH_STRINGREF part2; PH_STRINGREF part3; IF_LUID ifLuid; DV_NETADAPTER_ID id; PDV_NETADAPTER_ENTRY entry; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, ',', &part1, &remaining); PhSplitStringRefAtChar(&remaining, ',', &part2, &remaining); PhSplitStringRefAtChar(&remaining, ',', &part3, &remaining); PhStringToInteger64(&part1, 10, &ifindex); PhStringToInteger64(&part2, 10, &luid64); ifLuid.Value = luid64; InitializeNetAdapterId(&id, (IF_INDEX)ifindex, ifLuid, PhCreateString2(&part3)); entry = CreateNetAdapterEntry(&id); DeleteNetAdapterId(&id); entry->UserReference = TRUE; } }
ULONG64 ParseVersionString( _Inout_ PPH_STRING VersionString ) { PH_STRINGREF remaining, majorPart, minorPart, revisionPart; ULONG64 majorInteger = 0, minorInteger = 0, revisionInteger = 0; PhInitializeStringRef(&remaining, PhGetString(VersionString)); PhSplitStringRefAtChar(&remaining, '.', &majorPart, &remaining); PhSplitStringRefAtChar(&remaining, '.', &minorPart, &remaining); PhSplitStringRefAtChar(&remaining, '.', &revisionPart, &remaining); PhStringToInteger64(&majorPart, 10, &majorInteger); PhStringToInteger64(&minorPart, 10, &minorInteger); PhStringToInteger64(&revisionPart, 10, &revisionInteger); return MAKE_VERSION_ULONGLONG( (ULONG)majorInteger, (ULONG)minorInteger, (ULONG)revisionInteger, 0 ); }
VOID LoadCounterList( _Inout_ PPH_LIST FilterList, _In_ PPH_STRING String ) { PH_STRING_BUILDER stringBuilder; PPH_PERFMON_ENTRY entry = NULL; PH_STRINGREF part; PH_STRINGREF remaining = String->sr; while (remaining.Length != 0) { entry = (PPH_PERFMON_ENTRY)PhAllocate(sizeof(PH_PERFMON_ENTRY)); memset(entry, 0, sizeof(PH_PERFMON_ENTRY)); PhInitializeStringBuilder(&stringBuilder, 20); PhSplitStringRefAtChar(&remaining, ',', &part, &remaining); for (SIZE_T i = 0; i < part.Length / sizeof(WCHAR); i++) { if (part.Buffer[i] == '\\') { if (i != part.Length - 1) { i++; PhAppendCharStringBuilder(&stringBuilder, part.Buffer[i]); } else { // Unescape backslashes - Just ignore chars. break; } } else { PhAppendCharStringBuilder(&stringBuilder, part.Buffer[i]); } } entry->Name = PhCreateString(stringBuilder.String->Buffer); PhDeleteStringBuilder(&stringBuilder); PhAddItemList(FilterList, entry); } }
BOOLEAN WordMatchStringRef( _In_ PPH_STRINGREF Text ) { PH_STRINGREF part; PH_STRINGREF remainingPart; remainingPart = SearchboxText->sr; while (remainingPart.Length) { PhSplitStringRefAtChar(&remainingPart, '|', &part, &remainingPart); if (part.Length) { if (PhFindStringInStringRef(Text, &part, TRUE) != -1) return TRUE; } } return FALSE; }
static VOID PhpSplitUserName( _In_ PWSTR UserName, _Out_ PPH_STRING *DomainPart, _Out_ PPH_STRING *UserPart ) { PH_STRINGREF userName; PH_STRINGREF domainPart; PH_STRINGREF userPart; PhInitializeStringRefLongHint(&userName, UserName); if (PhSplitStringRefAtChar(&userName, '\\', &domainPart, &userPart)) { *DomainPart = PhCreateString2(&domainPart); *UserPart = PhCreateString2(&userPart); } else { *DomainPart = NULL; *UserPart = PhCreateString2(&userName); } }
BOOLEAN PhLoadSettingsColumnSet( _In_ PWSTR SettingName, _In_ PPH_STRING ColumnSetName, _Out_ PPH_STRING *TreeListSettings, _Out_ PPH_STRING *TreeSortSettings ) { PPH_STRING treeSettings = NULL; PPH_STRING sortSettings = NULL; PPH_STRING settingsString; ULONG64 count; ULONG64 index; PH_STRINGREF remaining; PH_STRINGREF part; settingsString = PhaGetStringSetting(SettingName); remaining = settingsString->sr; if (remaining.Length == 0) return FALSE; if (!PhSplitStringRefAtChar(&remaining, '-', &part, &remaining)) return FALSE; if (!PhStringToInteger64(&part, 10, &count)) return FALSE; for (index = 0; index < count; index++) { PH_STRINGREF columnSetNamePart; PH_STRINGREF columnSetSettingPart; PH_STRINGREF columnSetSortPart; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '-', &columnSetNamePart, &remaining); PhSplitStringRefAtChar(&remaining, '-', &columnSetSettingPart, &remaining); PhSplitStringRefAtChar(&remaining, '-', &columnSetSortPart, &remaining); if (PhEqualStringRef(&columnSetNamePart, &ColumnSetName->sr, FALSE)) { treeSettings = PhCreateString2(&columnSetSettingPart); sortSettings = PhCreateString2(&columnSetSortPart); break; } } if (!PhIsNullOrEmptyString(treeSettings) && !PhIsNullOrEmptyString(sortSettings)) { *TreeListSettings = treeSettings; *TreeSortSettings = sortSettings; return TRUE; } else { if (treeSettings) PhDereferenceObject(treeSettings); if (sortSettings) PhDereferenceObject(sortSettings); return FALSE; } }
VOID LoadNetworkAdapterImages( _In_ PDV_NETADAPTER_CONTEXT Context ) { HICON smallIcon; CONFIGRET result; ULONG deviceIconPathLength; DEVPROPTYPE deviceIconPathPropertyType; PPH_STRING deviceIconPath; deviceIconPathLength = 0x40; deviceIconPath = PhCreateStringEx(NULL, deviceIconPathLength); if ((result = CM_Get_Class_Property( &GUID_DEVCLASS_NET, &DEVPKEY_DeviceClass_IconPath, &deviceIconPathPropertyType, (PBYTE)deviceIconPath->Buffer, &deviceIconPathLength, 0 )) != CR_SUCCESS) { PhDereferenceObject(deviceIconPath); deviceIconPath = PhCreateStringEx(NULL, deviceIconPathLength); result = CM_Get_Class_Property( &GUID_DEVCLASS_NET, &DEVPKEY_DeviceClass_IconPath, &deviceIconPathPropertyType, (PBYTE)deviceIconPath->Buffer, &deviceIconPathLength, 0 ); } if (result != CR_SUCCESS) { PhDereferenceObject(deviceIconPath); return; } PhTrimToNullTerminatorString(deviceIconPath); { PPH_STRING dllIconPath; PH_STRINGREF dllPartSr; PH_STRINGREF indexPartSr; ULONG64 index = 0; if ( PhSplitStringRefAtChar(&deviceIconPath->sr, ',', &dllPartSr, &indexPartSr) && PhStringToInteger64(&indexPartSr, 10, &index) ) { if (dllIconPath = PhExpandEnvironmentStrings(&dllPartSr)) { if (PhExtractIconEx(dllIconPath->Buffer, (INT)index, &smallIcon, NULL)) { Context->ImageList = ImageList_Create( GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), ILC_COLOR32, 1, 1 ); ImageList_AddIcon(Context->ImageList, smallIcon); ListView_SetImageList(Context->ListViewHandle, Context->ImageList, LVSIL_SMALL); DestroyIcon(smallIcon); } PhDereferenceObject(dllIconPath); } } } PhDereferenceObject(deviceIconPath); }
static BOOL QueryXmlData( VOID ) { PCHAR data = NULL; BOOL isSuccess = FALSE; HINTERNET netInitialize = NULL, netConnection = NULL, netRequest = NULL; mxml_node_t *xmlDoc = NULL, *xmlNodeVer = NULL, *xmlNodeRelDate = NULL, *xmlNodeSize = NULL, *xmlNodeHash = NULL; // Create a user agent string. PPH_STRING phVersion = PhGetPhVersion(); PPH_STRING userAgent = PhConcatStrings2(L"PH Updater v", phVersion->Buffer); __try { // Initialize the wininet library. if (!(netInitialize = InternetOpen( userAgent->Buffer, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ))) { LogEvent(NULL, PhFormatString(L"Updater: (InitializeConnection) InternetOpen failed (%d)", GetLastError())); __leave; } // Connect to the server. if (!(netConnection = InternetConnect( netInitialize, UPDATE_URL, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ))) { LogEvent(NULL, PhFormatString(L"Updater: (InitializeConnection) InternetConnect failed (%d)", GetLastError())); __leave; } // Open the HTTP request. if (!(netRequest = HttpOpenRequest( netConnection, L"GET", UPDATE_FILE, NULL, NULL, NULL, // wj32: do NOT cache --------------------------- Old - "Always cache the update xml, it can be cleared by deleting IE history, we configured the file to cache locally for two days." INTERNET_FLAG_RELOAD, 0 ))) { LogEvent(NULL, PhFormatString(L"Updater: (InitializeConnection) HttpOpenRequest failed (%d)", GetLastError())); __leave; } // Send the HTTP request. if (!HttpSendRequest(netRequest, NULL, 0, NULL, 0)) { LogEvent(NULL, PhFormatString(L"HttpSendRequest failed (%d)", GetLastError())); __leave; } // Read the resulting xml into our buffer. if (!ReadRequestString(netRequest, &data, NULL)) { // We don't need to log this. __leave; } // Load our XML. xmlDoc = mxmlLoadString(NULL, data, QueryXmlDataCallback); // Check our XML. if (xmlDoc == NULL || xmlDoc->type != MXML_ELEMENT) { LogEvent(NULL, PhCreateString(L"Updater: (WorkerThreadStart) mxmlLoadString failed.")); __leave; } // Find the ver node. xmlNodeVer = mxmlFindElement(xmlDoc, xmlDoc, "ver", NULL, NULL, MXML_DESCEND); // Find the reldate node. xmlNodeRelDate = mxmlFindElement(xmlDoc, xmlDoc, "reldate", NULL, NULL, MXML_DESCEND); // Find the size node. xmlNodeSize = mxmlFindElement(xmlDoc, xmlDoc, "size", NULL, NULL, MXML_DESCEND); // Find the hash node. xmlNodeHash = mxmlFindElement(xmlDoc, xmlDoc, "sha1", NULL, NULL, MXML_DESCEND); // Format strings into unicode PPH_STRING's UpdateData.Version = PhGetOpaqueXmlNodeText(xmlNodeVer); UpdateData.RelDate = PhGetOpaqueXmlNodeText(xmlNodeRelDate); UpdateData.Size = PhGetOpaqueXmlNodeText(xmlNodeSize); UpdateData.Hash = PhGetOpaqueXmlNodeText(xmlNodeHash); // parse and check string //if (!ParseVersionString(XmlData->Version->Buffer, &XmlData->MajorVersion, &XmlData->MinorVersion)) // __leave; if (!PhIsNullOrEmptyString(UpdateData.Version)) { PH_STRINGREF sr, majorPart, minorPart; ULONG64 majorInteger = 0, minorInteger = 0; PhInitializeStringRef(&sr, UpdateData.Version->Buffer); if (PhSplitStringRefAtChar(&sr, '.', &majorPart, &minorPart)) { PhStringToInteger64(&majorPart, 10, &majorInteger); PhStringToInteger64(&minorPart, 10, &minorInteger); UpdateData.MajorVersion = (ULONG)majorInteger; UpdateData.MinorVersion = (ULONG)minorInteger; isSuccess = TRUE; } } } __finally { if (xmlDoc) { mxmlDelete(xmlDoc); xmlDoc = NULL; } if (netInitialize) { InternetCloseHandle(netInitialize); netInitialize = NULL; } if (netConnection) { InternetCloseHandle(netConnection); netConnection = NULL; } if (netRequest) { InternetCloseHandle(netRequest); netRequest = NULL; } if (userAgent) { PhDereferenceObject(userAgent); userAgent = NULL; } if (phVersion) { PhDereferenceObject(phVersion); phVersion = NULL; } } return isSuccess; }
static BOOLEAN PhpSettingFromString( _In_ PH_SETTING_TYPE Type, _In_ PPH_STRINGREF StringRef, _In_opt_ PPH_STRING String, _Inout_ PPH_SETTING Setting ) { switch (Type) { case StringSettingType: { if (String) { PhSetReference(&Setting->u.Pointer, String); } else { Setting->u.Pointer = PhCreateString2(StringRef); } return TRUE; } case IntegerSettingType: { ULONG64 integer; if (PhStringToInteger64(StringRef, 16, &integer)) { Setting->u.Integer = (ULONG)integer; return TRUE; } else { return FALSE; } } case IntegerPairSettingType: { LONG64 x; LONG64 y; PH_STRINGREF xString; PH_STRINGREF yString; if (!PhSplitStringRefAtChar(StringRef, ',', &xString, &yString)) return FALSE; if (PhStringToInteger64(&xString, 10, &x) && PhStringToInteger64(&yString, 10, &y)) { Setting->u.IntegerPair.X = (LONG)x; Setting->u.IntegerPair.Y = (LONG)y; return TRUE; } else { return FALSE; } } case ScalableIntegerPairSettingType: { ULONG64 scale; LONG64 x; LONG64 y; PH_STRINGREF stringRef; PH_STRINGREF firstPart; PH_STRINGREF secondPart; PPH_SCALABLE_INTEGER_PAIR scalableIntegerPair; stringRef = *StringRef; if (stringRef.Length != 0 && stringRef.Buffer[0] == '@') { PhSkipStringRef(&stringRef, sizeof(WCHAR)); if (!PhSplitStringRefAtChar(&stringRef, '|', &firstPart, &stringRef)) return FALSE; if (!PhStringToInteger64(&firstPart, 10, &scale)) return FALSE; } else { scale = PhpGetCurrentScale(); } if (!PhSplitStringRefAtChar(&stringRef, ',', &firstPart, &secondPart)) return FALSE; if (PhStringToInteger64(&firstPart, 10, &x) && PhStringToInteger64(&secondPart, 10, &y)) { scalableIntegerPair = PhAllocate(sizeof(PH_SCALABLE_INTEGER_PAIR)); scalableIntegerPair->X = (LONG)x; scalableIntegerPair->Y = (LONG)y; scalableIntegerPair->Scale = (ULONG)scale; Setting->u.Pointer = scalableIntegerPair; return TRUE; } else { return FALSE; } } } return FALSE; }
BOOLEAN PhLoadListViewColumnSettings( _In_ HWND ListViewHandle, _In_ PPH_STRING Settings ) { #define ORDER_LIMIT 50 PH_STRINGREF remainingPart; ULONG columnIndex; ULONG orderArray[ORDER_LIMIT]; // HACK, but reasonable limit ULONG maxOrder; ULONG scale; if (Settings->Length == 0) return FALSE; remainingPart = Settings->sr; columnIndex = 0; memset(orderArray, 0, sizeof(orderArray)); maxOrder = 0; if (remainingPart.Length != 0 && remainingPart.Buffer[0] == '@') { PH_STRINGREF scalePart; ULONG64 integer; PhSkipStringRef(&remainingPart, sizeof(WCHAR)); PhSplitStringRefAtChar(&remainingPart, '|', &scalePart, &remainingPart); if (scalePart.Length == 0 || !PhStringToInteger64(&scalePart, 10, &integer)) return FALSE; scale = (ULONG)integer; } else { scale = PhGlobalDpi; } while (remainingPart.Length != 0) { PH_STRINGREF columnPart; PH_STRINGREF orderPart; PH_STRINGREF widthPart; ULONG64 integer; ULONG order; ULONG width; LVCOLUMN lvColumn; PhSplitStringRefAtChar(&remainingPart, '|', &columnPart, &remainingPart); if (columnPart.Length == 0) return FALSE; PhSplitStringRefAtChar(&columnPart, ',', &orderPart, &widthPart); if (orderPart.Length == 0 || widthPart.Length == 0) return FALSE; // Order if (!PhStringToInteger64(&orderPart, 10, &integer)) return FALSE; order = (ULONG)integer; if (order < ORDER_LIMIT) { orderArray[order] = columnIndex; if (maxOrder < order + 1) maxOrder = order + 1; } // Width if (!PhStringToInteger64(&widthPart, 10, &integer)) return FALSE; width = (ULONG)integer; if (scale != PhGlobalDpi && scale != 0) width = PhMultiplyDivide(width, PhGlobalDpi, scale); lvColumn.mask = LVCF_WIDTH; lvColumn.cx = width; ListView_SetColumn(ListViewHandle, columnIndex, &lvColumn); columnIndex++; } ListView_SetColumnOrderArray(ListViewHandle, maxOrder, orderArray); return TRUE; }
VOID NTAPI DotNetEventCallback( _In_ PEVENT_RECORD EventRecord ) { PASMPAGE_QUERY_CONTEXT context = EventRecord->UserContext; PEVENT_HEADER eventHeader = &EventRecord->EventHeader; PEVENT_DESCRIPTOR eventDescriptor = &eventHeader->EventDescriptor; if (UlongToHandle(eventHeader->ProcessId) == context->ProcessId) { // .NET 4.0+ switch (eventDescriptor->Id) { case RuntimeInformationDCStart: { PRuntimeInformationRundown data = EventRecord->UserData; PDNA_NODE node; PPH_STRING startupFlagsString; PPH_STRING startupModeString; // Check for duplicates. if (FindClrNode(context, data->ClrInstanceID)) break; node = AddNode(context); node->Type = DNA_TYPE_CLR; node->u.Clr.ClrInstanceID = data->ClrInstanceID; node->u.Clr.DisplayName = PhFormatString(L"CLR v%u.%u.%u.%u", data->VMMajorVersion, data->VMMinorVersion, data->VMBuildNumber, data->VMQfeNumber); node->StructureText = node->u.Clr.DisplayName->sr; node->IdText = PhFormatString(L"%u", data->ClrInstanceID); startupFlagsString = FlagsToString(data->StartupFlags, StartupFlagsMap, sizeof(StartupFlagsMap)); startupModeString = FlagsToString(data->StartupMode, StartupModeMap, sizeof(StartupModeMap)); if (startupFlagsString->Length != 0 && startupModeString->Length != 0) { node->FlagsText = PhConcatStrings(3, startupFlagsString->Buffer, L", ", startupModeString->Buffer); PhDereferenceObject(startupFlagsString); PhDereferenceObject(startupModeString); } else if (startupFlagsString->Length != 0) { node->FlagsText = startupFlagsString; PhDereferenceObject(startupModeString); } else if (startupModeString->Length != 0) { node->FlagsText = startupModeString; PhDereferenceObject(startupFlagsString); } if (data->CommandLine[0]) node->PathText = PhCreateString(data->CommandLine); PhAddItemList(context->NodeRootList, node); } break; case AppDomainDCStart_V1: { PAppDomainLoadUnloadRundown_V1 data = EventRecord->UserData; SIZE_T appDomainNameLength; USHORT clrInstanceID; PDNA_NODE parentNode; PDNA_NODE node; appDomainNameLength = PhCountStringZ(data->AppDomainName) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)data + FIELD_OFFSET(AppDomainLoadUnloadRundown_V1, AppDomainName) + appDomainNameLength + sizeof(WCHAR) + sizeof(ULONG)); // Find the CLR node to add the AppDomain node to. parentNode = FindClrNode(context, clrInstanceID); if (parentNode) { // Check for duplicates. if (FindAppDomainNode(parentNode, data->AppDomainID)) break; node = AddNode(context); node->Type = DNA_TYPE_APPDOMAIN; node->u.AppDomain.AppDomainID = data->AppDomainID; node->u.AppDomain.DisplayName = PhConcatStrings2(L"AppDomain: ", data->AppDomainName); node->StructureText = node->u.AppDomain.DisplayName->sr; node->IdText = PhFormatString(L"%I64u", data->AppDomainID); node->FlagsText = FlagsToString(data->AppDomainFlags, AppDomainFlagsMap, sizeof(AppDomainFlagsMap)); PhAddItemList(parentNode->Children, node); } } break; case AssemblyDCStart_V1: { PAssemblyLoadUnloadRundown_V1 data = EventRecord->UserData; SIZE_T fullyQualifiedAssemblyNameLength; USHORT clrInstanceID; PDNA_NODE parentNode; PDNA_NODE node; PH_STRINGREF remainingPart; fullyQualifiedAssemblyNameLength = PhCountStringZ(data->FullyQualifiedAssemblyName) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)data + FIELD_OFFSET(AssemblyLoadUnloadRundown_V1, FullyQualifiedAssemblyName) + fullyQualifiedAssemblyNameLength + sizeof(WCHAR)); // Find the AppDomain node to add the Assembly node to. parentNode = FindClrNode(context, clrInstanceID); if (parentNode) parentNode = FindAppDomainNode(parentNode, data->AppDomainID); if (parentNode) { // Check for duplicates. if (FindAssemblyNode(parentNode, data->AssemblyID)) break; node = AddNode(context); node->Type = DNA_TYPE_ASSEMBLY; node->u.Assembly.AssemblyID = data->AssemblyID; node->u.Assembly.FullyQualifiedAssemblyName = PhCreateStringEx(data->FullyQualifiedAssemblyName, fullyQualifiedAssemblyNameLength); // Display only the assembly name, not the whole fully qualified name. if (!PhSplitStringRefAtChar(&node->u.Assembly.FullyQualifiedAssemblyName->sr, ',', &node->StructureText, &remainingPart)) node->StructureText = node->u.Assembly.FullyQualifiedAssemblyName->sr; node->IdText = PhFormatString(L"%I64u", data->AssemblyID); node->FlagsText = FlagsToString(data->AssemblyFlags, AssemblyFlagsMap, sizeof(AssemblyFlagsMap)); PhAddItemList(parentNode->Children, node); } } break; case ModuleDCStart_V1: { PModuleLoadUnloadRundown_V1 data = EventRecord->UserData; PWSTR moduleILPath; SIZE_T moduleILPathLength; PWSTR moduleNativePath; SIZE_T moduleNativePathLength; USHORT clrInstanceID; PDNA_NODE node; moduleILPath = data->ModuleILPath; moduleILPathLength = PhCountStringZ(moduleILPath) * sizeof(WCHAR); moduleNativePath = (PWSTR)((PCHAR)moduleILPath + moduleILPathLength + sizeof(WCHAR)); moduleNativePathLength = PhCountStringZ(moduleNativePath) * sizeof(WCHAR); clrInstanceID = *(PUSHORT)((PCHAR)moduleNativePath + moduleNativePathLength + sizeof(WCHAR)); // Find the Assembly node to set the path on. node = FindClrNode(context, clrInstanceID); if (node) node = FindAssemblyNode2(node, data->AssemblyID); if (node) { PhMoveReference(&node->PathText, PhCreateStringEx(moduleILPath, moduleILPathLength)); if (moduleNativePathLength != 0) PhMoveReference(&node->NativePathText, PhCreateStringEx(moduleNativePath, moduleNativePathLength)); } } break; case DCStartComplete_V1: { if (_InterlockedExchange(&context->TraceHandleActive, 0) == 1) { CloseTrace(context->TraceHandle); } } break; } // .NET 2.0 if (eventDescriptor->Id == 0) { switch (eventDescriptor->Opcode) { case CLR_MODULEDCSTART_OPCODE: { PModuleLoadUnloadRundown_V1 data = EventRecord->UserData; PWSTR moduleILPath; SIZE_T moduleILPathLength; PWSTR moduleNativePath; SIZE_T moduleNativePathLength; PDNA_NODE node; ULONG_PTR indexOfBackslash; ULONG_PTR indexOfLastDot; moduleILPath = data->ModuleILPath; moduleILPathLength = PhCountStringZ(moduleILPath) * sizeof(WCHAR); moduleNativePath = (PWSTR)((PCHAR)moduleILPath + moduleILPathLength + sizeof(WCHAR)); moduleNativePathLength = PhCountStringZ(moduleNativePath) * sizeof(WCHAR); if (context->ClrV2Node && (moduleILPathLength != 0 || moduleNativePathLength != 0)) { node = AddNode(context); node->Type = DNA_TYPE_ASSEMBLY; node->FlagsText = FlagsToString(data->ModuleFlags, ModuleFlagsMap, sizeof(ModuleFlagsMap)); node->PathText = PhCreateStringEx(moduleILPath, moduleILPathLength); if (moduleNativePathLength != 0) node->NativePathText = PhCreateStringEx(moduleNativePath, moduleNativePathLength); // Use the name between the last backslash and the last dot for the structure column text. // (E.g. C:\...\AcmeSoft.BigLib.dll -> AcmeSoft.BigLib) indexOfBackslash = PhFindLastCharInString(node->PathText, 0, '\\'); indexOfLastDot = PhFindLastCharInString(node->PathText, 0, '.'); if (indexOfBackslash != -1) { node->StructureText.Buffer = node->PathText->Buffer + indexOfBackslash + 1; if (indexOfLastDot != -1 && indexOfLastDot > indexOfBackslash) { node->StructureText.Length = (indexOfLastDot - indexOfBackslash - 1) * sizeof(WCHAR); } else { node->StructureText.Length = node->PathText->Length - indexOfBackslash * sizeof(WCHAR) - sizeof(WCHAR); } } else { node->StructureText = node->PathText->sr; } PhAddItemList(context->ClrV2Node->Children, node); } } break; case CLR_METHODDC_DCSTARTCOMPLETE_OPCODE: { if (_InterlockedExchange(&context->TraceHandleActive, 0) == 1) { CloseTrace(context->TraceHandle); } } break; } } } }
BOOLEAN NTAPI PhpCommandLineOptionCallback( _In_opt_ PPH_COMMAND_LINE_OPTION Option, _In_opt_ PPH_STRING Value, _In_opt_ PVOID Context ) { ULONG64 integer; if (Option) { switch (Option->Id) { case PH_ARG_SETTINGS: PhSwapReference(&PhStartupParameters.SettingsFileName, Value); break; case PH_ARG_NOSETTINGS: PhStartupParameters.NoSettings = TRUE; break; case PH_ARG_SHOWVISIBLE: PhStartupParameters.ShowVisible = TRUE; break; case PH_ARG_SHOWHIDDEN: PhStartupParameters.ShowHidden = TRUE; break; case PH_ARG_COMMANDMODE: PhStartupParameters.CommandMode = TRUE; break; case PH_ARG_COMMANDTYPE: PhSwapReference(&PhStartupParameters.CommandType, Value); break; case PH_ARG_COMMANDOBJECT: PhSwapReference(&PhStartupParameters.CommandObject, Value); break; case PH_ARG_COMMANDACTION: PhSwapReference(&PhStartupParameters.CommandAction, Value); break; case PH_ARG_COMMANDVALUE: PhSwapReference(&PhStartupParameters.CommandValue, Value); break; case PH_ARG_RUNASSERVICEMODE: PhSwapReference(&PhStartupParameters.RunAsServiceMode, Value); break; case PH_ARG_NOKPH: PhStartupParameters.NoKph = TRUE; break; case PH_ARG_INSTALLKPH: PhStartupParameters.InstallKph = TRUE; break; case PH_ARG_UNINSTALLKPH: PhStartupParameters.UninstallKph = TRUE; break; case PH_ARG_DEBUG: PhStartupParameters.Debug = TRUE; break; case PH_ARG_HWND: if (PhStringToInteger64(&Value->sr, 16, &integer)) PhStartupParameters.WindowHandle = (HWND)(ULONG_PTR)integer; break; case PH_ARG_POINT: { PH_STRINGREF xString; PH_STRINGREF yString; if (PhSplitStringRefAtChar(&Value->sr, ',', &xString, &yString)) { LONG64 x; LONG64 y; if (PhStringToInteger64(&xString, 10, &x) && PhStringToInteger64(&yString, 10, &y)) { PhStartupParameters.Point.x = (LONG)x; PhStartupParameters.Point.y = (LONG)y; } } } break; case PH_ARG_SHOWOPTIONS: PhStartupParameters.ShowOptions = TRUE; break; case PH_ARG_PHSVC: PhStartupParameters.PhSvc = TRUE; break; case PH_ARG_NOPLUGINS: PhStartupParameters.NoPlugins = TRUE; break; case PH_ARG_NEWINSTANCE: PhStartupParameters.NewInstance = TRUE; break; case PH_ARG_ELEVATE: PhStartupParameters.Elevate = TRUE; break; case PH_ARG_SILENT: PhStartupParameters.Silent = TRUE; break; case PH_ARG_HELP: PhStartupParameters.Help = TRUE; break; case PH_ARG_SELECTPID: if (PhStringToInteger64(&Value->sr, 0, &integer)) PhStartupParameters.SelectPid = (ULONG)integer; break; case PH_ARG_PRIORITY: if (PhEqualString2(Value, L"r", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_REALTIME; else if (PhEqualString2(Value, L"h", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_HIGH; else if (PhEqualString2(Value, L"n", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_NORMAL; else if (PhEqualString2(Value, L"l", TRUE)) PhStartupParameters.PriorityClass = PROCESS_PRIORITY_CLASS_IDLE; break; case PH_ARG_PLUGIN: if (!PhStartupParameters.PluginParameters) PhStartupParameters.PluginParameters = PhCreateList(3); PhReferenceObject(Value); PhAddItemList(PhStartupParameters.PluginParameters, Value); break; case PH_ARG_SELECTTAB: PhSwapReference(&PhStartupParameters.SelectTab, Value); break; } } else { PPH_STRING upperValue; upperValue = PhDuplicateString(Value); _wcsupr(upperValue->Buffer); if (PhFindStringInString(upperValue, 0, L"TASKMGR.EXE") != -1) { // User probably has Process Hacker replacing Task Manager. Force // the main window to start visible. PhStartupParameters.ShowVisible = TRUE; } PhDereferenceObject(upperValue); } return TRUE; }
BOOLEAN PhLoadListViewColumnSettings( _In_ HWND ListViewHandle, _In_ PPH_STRING Settings ) { #define ORDER_LIMIT 50 PH_STRINGREF remainingPart; ULONG columnIndex; ULONG orderArray[ORDER_LIMIT]; // HACK, but reasonable limit ULONG maxOrder; if (Settings->Length == 0) return FALSE; remainingPart = Settings->sr; columnIndex = 0; memset(orderArray, 0, sizeof(orderArray)); maxOrder = 0; while (remainingPart.Length != 0) { PH_STRINGREF columnPart; PH_STRINGREF orderPart; PH_STRINGREF widthPart; ULONG64 integer; ULONG order; LVCOLUMN lvColumn; PhSplitStringRefAtChar(&remainingPart, '|', &columnPart, &remainingPart); if (columnPart.Length == 0) return FALSE; PhSplitStringRefAtChar(&columnPart, ',', &orderPart, &widthPart); if (orderPart.Length == 0 || widthPart.Length == 0) return FALSE; // Order if (!PhStringToInteger64(&orderPart, 10, &integer)) return FALSE; order = (ULONG)integer; if (order < ORDER_LIMIT) { orderArray[order] = columnIndex; if (maxOrder < order + 1) maxOrder = order + 1; } // Width if (!PhStringToInteger64(&widthPart, 10, &integer)) return FALSE; lvColumn.mask = LVCF_WIDTH; lvColumn.cx = (ULONG)integer; ListView_SetColumn(ListViewHandle, columnIndex, &lvColumn); columnIndex++; } ListView_SetColumnOrderArray(ListViewHandle, maxOrder, orderArray); return TRUE; }
VOID ToolbarLoadButtonSettings( VOID ) { INT buttonCount; ULONG64 countInteger; PPH_STRING settingsString; PTBBUTTON buttonArray; PH_STRINGREF remaining; PH_STRINGREF part; settingsString = PhaGetStringSetting(SETTING_NAME_TOOLBAR_CONFIG); remaining = settingsString->sr; if (remaining.Length == 0) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } // Query the number of buttons to insert if (!PhSplitStringRefAtChar(&remaining, '|', &part, &remaining)) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } if (!PhStringToInteger64(&part, 10, &countInteger)) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } buttonCount = (INT)countInteger; // Allocate the button array buttonArray = PhAllocate(buttonCount * sizeof(TBBUTTON)); memset(buttonArray, 0, buttonCount * sizeof(TBBUTTON)); for (INT index = 0; index < buttonCount; index++) { ULONG64 commandInteger; PH_STRINGREF commandIdPart; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '|', &commandIdPart, &remaining); PhStringToInteger64(&commandIdPart, 10, &commandInteger); buttonArray[index].idCommand = (INT)commandInteger; buttonArray[index].iBitmap = I_IMAGECALLBACK; buttonArray[index].fsState = TBSTATE_ENABLED; if (commandInteger) { buttonArray[index].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; } else { buttonArray[index].fsStyle = BTNS_SEP; } } SendMessage(ToolBarHandle, TB_ADDBUTTONS, buttonCount, (LPARAM)buttonArray); PhFree(buttonArray); }
INT_PTR CALLBACK PhpMemoryEditorDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PMEMORY_EDITOR_CONTEXT context; if (uMsg != WM_INITDIALOG) { context = GetProp(hwndDlg, PhMakeContextAtom()); } else { context = (PMEMORY_EDITOR_CONTEXT)lParam; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; if (context->Title) { SetWindowText(hwndDlg, context->Title->Buffer); } else { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(context->ProcessId)) { SetWindowText(hwndDlg, PhaFormatString(L"%s (%u) (0x%Ix - 0x%Ix)", processItem->ProcessName->Buffer, HandleToUlong(context->ProcessId), context->BaseAddress, (ULONG_PTR)context->BaseAddress + context->RegionSize)->Buffer); PhDereferenceObject(processItem); } } PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); if (context->RegionSize > 1024 * 1024 * 1024) // 1 GB { PhShowError(NULL, L"Unable to edit the memory region because it is too large."); return TRUE; } if (!NT_SUCCESS(status = PhOpenProcess( &context->ProcessHandle, PROCESS_VM_READ, context->ProcessId ))) { PhShowStatus(NULL, L"Unable to open the process", status, 0); return TRUE; } context->Buffer = PhAllocatePage(context->RegionSize, NULL); if (!context->Buffer) { PhShowError(NULL, L"Unable to allocate memory for the buffer."); return TRUE; } if (!NT_SUCCESS(status = PhReadVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(PhMainWndHandle, L"Unable to read memory", status, 0); return TRUE; } PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_BYTESPERROW), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_GOTO), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_WRITE), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_REREAD), NULL, PH_ANCHOR_BOTTOM | PH_ANCHOR_LEFT); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 290; rect.bottom = 140; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } context->HexEditHandle = GetDlgItem(hwndDlg, IDC_MEMORY); PhAddLayoutItem(&context->LayoutManager, context->HexEditHandle, NULL, PH_ANCHOR_ALL); HexEdit_SetBuffer(context->HexEditHandle, context->Buffer, (ULONG)context->RegionSize); { PH_RECTANGLE windowRectangle; windowRectangle.Position = PhGetIntegerPairSetting(L"MemEditPosition"); windowRectangle.Size = PhGetScalableIntegerPairSetting(L"MemEditSize", TRUE).Pair; PhAdjustRectangleToWorkingArea(NULL, &windowRectangle); MoveWindow(hwndDlg, windowRectangle.Left, windowRectangle.Top, windowRectangle.Width, windowRectangle.Height, FALSE); // Implement cascading by saving an offsetted rectangle. windowRectangle.Left += 20; windowRectangle.Top += 20; PhSetIntegerPairSetting(L"MemEditPosition", windowRectangle.Position); PhSetScalableIntegerPairSetting2(L"MemEditSize", windowRectangle.Size); } { PWSTR bytesPerRowStrings[7]; ULONG i; ULONG bytesPerRow; for (i = 0; i < sizeof(bytesPerRowStrings) / sizeof(PWSTR); i++) bytesPerRowStrings[i] = PhaFormatString(L"%u bytes per row", 1 << (2 + i))->Buffer; PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_BYTESPERROW), bytesPerRowStrings, sizeof(bytesPerRowStrings) / sizeof(PWSTR)); bytesPerRow = PhGetIntegerSetting(L"MemEditBytesPerRow"); if (bytesPerRow >= 4) { HexEdit_SetBytesPerRow(context->HexEditHandle, bytesPerRow); PhSelectComboBoxString(GetDlgItem(hwndDlg, IDC_BYTESPERROW), PhaFormatString(L"%u bytes per row", bytesPerRow)->Buffer, FALSE); } } context->LoadCompleted = TRUE; } break; case WM_DESTROY: { if (context->LoadCompleted) { PhSaveWindowPlacementToSetting(L"MemEditPosition", L"MemEditSize", hwndDlg); PhRemoveElementAvlTree(&PhMemoryEditorSet, &context->Links); PhUnregisterDialog(hwndDlg); } RemoveProp(hwndDlg, PhMakeContextAtom()); PhDeleteLayoutManager(&context->LayoutManager); if (context->Buffer) PhFreePage(context->Buffer); if (context->ProcessHandle) NtClose(context->ProcessHandle); PhClearReference(&context->Title); if ((context->Flags & PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION) && context->ProcessId == NtCurrentProcessId()) NtUnmapViewOfSection(NtCurrentProcess(), context->BaseAddress); PhFree(context); } break; case WM_SHOWWINDOW: { SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: DestroyWindow(hwndDlg); break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Binary files (*.bin)", L"*.bin" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_PROCESS_ITEM processItem; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); if (!context->Title && (processItem = PhReferenceProcessItem(context->ProcessId))) { PhSetFileDialogFileName(fileDialog, PhaFormatString(L"%s_0x%Ix-0x%Ix.bin", processItem->ProcessName->Buffer, context->BaseAddress, context->RegionSize)->Buffer); PhDereferenceObject(processItem); } else { PhSetFileDialogFileName(fileDialog, L"Memory.bin"); } if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog)); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { status = PhWriteFileStream(fileStream, context->Buffer, (ULONG)context->RegionSize); PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; case IDC_GOTO: { PPH_STRING selectedChoice = NULL; while (PhaChoiceDialog( hwndDlg, L"Go to Offset", L"Enter an offset:", NULL, 0, NULL, PH_CHOICE_DIALOG_USER_CHOICE, &selectedChoice, NULL, L"MemEditGotoChoices" )) { ULONG64 offset; if (selectedChoice->Length == 0) continue; if (PhStringToInteger64(&selectedChoice->sr, 0, &offset)) { if (offset >= context->RegionSize) { PhShowError(hwndDlg, L"The offset is too large."); continue; } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); HexEdit_SetSel(context->HexEditHandle, (LONG)offset, (LONG)offset); break; } } } break; case IDC_WRITE: { NTSTATUS status; if (!context->WriteAccess) { HANDLE processHandle; if (!NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_VM_READ | PROCESS_VM_WRITE, context->ProcessId ))) { PhShowStatus(hwndDlg, L"Unable to open the process", status, 0); break; } if (context->ProcessHandle) NtClose(context->ProcessHandle); context->ProcessHandle = processHandle; context->WriteAccess = TRUE; } if (!NT_SUCCESS(status = PhWriteVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(hwndDlg, L"Unable to write memory", status, 0); } } break; case IDC_REREAD: { NTSTATUS status; if (!NT_SUCCESS(status = PhReadVirtualMemory( context->ProcessHandle, context->BaseAddress, context->Buffer, context->RegionSize, NULL ))) { PhShowStatus(hwndDlg, L"Unable to read memory", status, 0); } InvalidateRect(context->HexEditHandle, NULL, TRUE); } break; case IDC_BYTESPERROW: if (HIWORD(wParam) == CBN_SELCHANGE) { PPH_STRING bytesPerRowString = PhaGetDlgItemText(hwndDlg, IDC_BYTESPERROW); PH_STRINGREF firstPart; PH_STRINGREF secondPart; ULONG64 bytesPerRow64; if (PhSplitStringRefAtChar(&bytesPerRowString->sr, ' ', &firstPart, &secondPart)) { if (PhStringToInteger64(&firstPart, 10, &bytesPerRow64)) { PhSetIntegerSetting(L"MemEditBytesPerRow", (ULONG)bytesPerRow64); HexEdit_SetBytesPerRow(context->HexEditHandle, (ULONG)bytesPerRow64); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)context->HexEditHandle, TRUE); } } } break; } } break; case WM_SIZE: { PhLayoutManagerLayout(&context->LayoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; case WM_PH_SELECT_OFFSET: { HexEdit_SetEditMode(context->HexEditHandle, EDIT_ASCII); HexEdit_SetSel(context->HexEditHandle, (ULONG)wParam, (ULONG)wParam + (ULONG)lParam); } break; } return FALSE; }
VOID ReBarLoadLayoutSettings( VOID ) { UINT bandIndex = 0; UINT bandCount = 0; PPH_STRING settingsString; PH_STRINGREF remaining; settingsString = PhGetStringSetting(SETTING_NAME_REBAR_CONFIG); remaining = settingsString->sr; if (remaining.Length == 0) return; bandCount = (UINT)SendMessage(RebarHandle, RB_GETBANDCOUNT, 0, 0); for (bandIndex = 0; bandIndex < bandCount; bandIndex++) { PH_STRINGREF idPart; PH_STRINGREF cxPart; PH_STRINGREF stylePart; ULONG64 idInteger; ULONG64 cxInteger; ULONG64 styleInteger; UINT oldBandIndex; REBARBANDINFO rebarBandInfo = { REBARBANDINFO_V6_SIZE, RBBIM_STYLE | RBBIM_SIZE }; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '|', &idPart, &remaining); PhSplitStringRefAtChar(&remaining, '|', &cxPart, &remaining); PhSplitStringRefAtChar(&remaining, '|', &stylePart, &remaining); PhStringToInteger64(&idPart, 10, &idInteger); PhStringToInteger64(&cxPart, 10, &cxInteger); PhStringToInteger64(&stylePart, 10, &styleInteger); if ((oldBandIndex = (UINT)SendMessage(RebarHandle, RB_IDTOINDEX, (UINT)idInteger, 0)) == -1) break; if (oldBandIndex != bandIndex) { SendMessage(RebarHandle, RB_MOVEBAND, oldBandIndex, bandIndex); } if (SendMessage(RebarHandle, RB_GETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo)) { if (idInteger == REBAR_BAND_ID_SEARCHBOX) { rebarBandInfo.fStyle |= RBBS_FIXEDSIZE; } rebarBandInfo.cx = (UINT)cxInteger; rebarBandInfo.fStyle |= (UINT)styleInteger; SendMessage(RebarHandle, RB_SETBANDINFO, bandIndex, (LPARAM)&rebarBandInfo); } } }
BOOLEAN PhCmLoadSettingsEx( _In_ HWND TreeNewHandle, _In_opt_ PPH_CM_MANAGER Manager, _In_ ULONG Flags, _In_ PPH_STRINGREF Settings, _In_opt_ PPH_STRINGREF SortSettings ) { BOOLEAN result = FALSE; PH_STRINGREF columnPart; PH_STRINGREF remainingColumnPart; PH_STRINGREF valuePart; PH_STRINGREF subPart; ULONG64 integer; ULONG total; BOOLEAN hasFixedColumn; ULONG count; ULONG i; PPH_HASHTABLE columnHashtable; PH_HASHTABLE_ENUM_CONTEXT enumContext; PPH_KEY_VALUE_PAIR pair; LONG orderArray[PH_CM_ORDER_LIMIT]; LONG maxOrder; if (Settings->Length != 0) { columnHashtable = PhCreateSimpleHashtable(20); remainingColumnPart = *Settings; while (remainingColumnPart.Length != 0) { PPH_TREENEW_COLUMN column; ULONG id; ULONG displayIndex; ULONG width; PhSplitStringRefAtChar(&remainingColumnPart, '|', &columnPart, &remainingColumnPart); if (columnPart.Length != 0) { // Id PhSplitStringRefAtChar(&columnPart, ',', &valuePart, &columnPart); if (valuePart.Length == 0) goto CleanupExit; if (valuePart.Buffer[0] == '+') { PH_STRINGREF pluginName; ULONG subId; PPH_CM_COLUMN cmColumn; // This is a plugin-owned column. if (!Manager) continue; if (!PhEmParseCompoundId(&valuePart, &pluginName, &subId)) continue; cmColumn = PhCmFindColumn(Manager, &pluginName, subId); if (!cmColumn) continue; // can't find the column, skip this part id = cmColumn->Id; } else { if (!PhStringToInteger64(&valuePart, 10, &integer)) goto CleanupExit; id = (ULONG)integer; } // Display Index PhSplitStringRefAtChar(&columnPart, ',', &valuePart, &columnPart); if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY)) { if (valuePart.Length == 0 || !PhStringToInteger64(&valuePart, 10, &integer)) goto CleanupExit; displayIndex = (ULONG)integer; } else { if (valuePart.Length != 0) goto CleanupExit; displayIndex = -1; } // Width if (columnPart.Length == 0 || !PhStringToInteger64(&columnPart, 10, &integer)) goto CleanupExit; width = (ULONG)integer; column = PhAllocate(sizeof(PH_TREENEW_COLUMN)); column->Id = id; column->DisplayIndex = displayIndex; column->Width = width; PhAddItemSimpleHashtable(columnHashtable, (PVOID)column->Id, column); } } TreeNew_SetRedraw(TreeNewHandle, FALSE); // Set visibility and width. i = 0; count = 0; total = TreeNew_GetColumnCount(TreeNewHandle); hasFixedColumn = !!TreeNew_GetFixedColumn(TreeNewHandle); memset(orderArray, 0, sizeof(orderArray)); maxOrder = 0; while (count < total) { PH_TREENEW_COLUMN setColumn; PPH_TREENEW_COLUMN *columnPtr; if (TreeNew_GetColumn(TreeNewHandle, i, &setColumn)) { columnPtr = (PPH_TREENEW_COLUMN *)PhFindItemSimpleHashtable(columnHashtable, (PVOID)i); if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY)) { if (columnPtr) { setColumn.Visible = TRUE; setColumn.Width = (*columnPtr)->Width; TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_FLAG_VISIBLE | TN_COLUMN_WIDTH, &setColumn); if (!setColumn.Fixed) { // For compatibility reasons, normal columns have their display indicies stored // one higher than usual (so they start from 1, not 0). Fix that here. if (hasFixedColumn && (*columnPtr)->DisplayIndex != 0) (*columnPtr)->DisplayIndex--; if ((*columnPtr)->DisplayIndex < PH_CM_ORDER_LIMIT) { orderArray[(*columnPtr)->DisplayIndex] = i; if ((ULONG)maxOrder < (*columnPtr)->DisplayIndex + 1) maxOrder = (*columnPtr)->DisplayIndex + 1; } } } else if (!setColumn.Fixed) // never hide the fixed column { setColumn.Visible = FALSE; TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_FLAG_VISIBLE, &setColumn); } } else { if (columnPtr) { setColumn.Width = (*columnPtr)->Width; TreeNew_SetColumn(TreeNewHandle, TN_COLUMN_WIDTH, &setColumn); } } count++; } i++; } if (!(Flags & PH_CM_COLUMN_WIDTHS_ONLY)) { // Set the order array. TreeNew_SetColumnOrderArray(TreeNewHandle, maxOrder, orderArray); } TreeNew_SetRedraw(TreeNewHandle, TRUE); result = TRUE; CleanupExit: PhBeginEnumHashtable(columnHashtable, &enumContext); while (pair = PhNextEnumHashtable(&enumContext)) PhFree(pair->Value); PhDereferenceObject(columnHashtable); } // Load sort settings. if (SortSettings && SortSettings->Length != 0) { PhSplitStringRefAtChar(SortSettings, ',', &valuePart, &subPart); if (valuePart.Length != 0 && subPart.Length != 0) { ULONG sortColumn; PH_SORT_ORDER sortOrder; sortColumn = -1; if (valuePart.Buffer[0] == '+') { PH_STRINGREF pluginName; ULONG subId; PPH_CM_COLUMN cmColumn; if ( Manager && PhEmParseCompoundId(&valuePart, &pluginName, &subId) && (cmColumn = PhCmFindColumn(Manager, &pluginName, subId)) ) { sortColumn = cmColumn->Id; } } else { PhStringToInteger64(&valuePart, 10, &integer); sortColumn = (ULONG)integer; } PhStringToInteger64(&subPart, 10, &integer); sortOrder = (PH_SORT_ORDER)integer; if (sortColumn != -1 && sortOrder <= DescendingSortOrder) { TreeNew_SetSort(TreeNewHandle, sortColumn, sortOrder); } } } return result; }
VOID ToolbarLoadButtonSettings( VOID ) { INT count; ULONG64 countInteger; PPH_STRING settingsString; PTBBUTTON buttonArray; PH_STRINGREF remaining; PH_STRINGREF part; settingsString = PhaGetStringSetting(SETTING_NAME_TOOLBAR_CONFIG); remaining = settingsString->sr; if (remaining.Length == 0) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } // Query the number of buttons to insert if (!PhSplitStringRefAtChar(&remaining, '|', &part, &remaining)) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } if (!PhStringToInteger64(&part, 10, &countInteger)) { // Load default settings SendMessage(ToolBarHandle, TB_ADDBUTTONS, MAX_DEFAULT_TOOLBAR_ITEMS, (LPARAM)ToolbarButtons); return; } count = (INT)countInteger; // Allocate the button array buttonArray = PhAllocate(count * sizeof(TBBUTTON)); memset(buttonArray, 0, count * sizeof(TBBUTTON)); for (INT index = 0; index < count; index++) { ULONG64 commandInteger; PH_STRINGREF commandIdPart; if (remaining.Length == 0) break; PhSplitStringRefAtChar(&remaining, '|', &commandIdPart, &remaining); PhStringToInteger64(&commandIdPart, 10, &commandInteger); buttonArray[index].idCommand = (INT)commandInteger; //buttonArray[index].iBitmap = I_IMAGECALLBACK; buttonArray[index].fsState = TBSTATE_ENABLED; if (commandInteger) { buttonArray[index].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE; } else { buttonArray[index].fsStyle = BTNS_SEP; } // Pre-cache the image in the Toolbar array on startup. for (INT i = 0; i < ARRAYSIZE(ToolbarButtons); i++) { if (ToolbarButtons[i].idCommand == buttonArray[index].idCommand) { HBITMAP bitmap; bitmap = ToolbarGetImage(ToolbarButtons[i].idCommand); // Add the image, cache the value in the ToolbarButtons array, set the bitmap index. buttonArray[index].iBitmap = ToolbarButtons[i].iBitmap = ImageList_Add( ToolBarImageList, bitmap, NULL ); DeleteObject(bitmap); break; } } } SendMessage(ToolBarHandle, TB_ADDBUTTONS, count, (LPARAM)buttonArray); PhFree(buttonArray); }
VOID PhpFillUmdfDrivers( _In_ PPH_PROCESS_ITEM Process, _Inout_ PPH_STRING_BUILDER Drivers ) { static PH_STRINGREF activeDevices = PH_STRINGREF_INIT(L"ACTIVE_DEVICES"); static PH_STRINGREF currentControlSetEnum = PH_STRINGREF_INIT(L"System\\CurrentControlSet\\Enum\\"); HANDLE processHandle; ULONG flags = 0; PVOID environment; ULONG environmentLength; ULONG enumerationKey; PH_ENVIRONMENT_VARIABLE variable; if (!NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, Process->ProcessId ))) return; #ifdef _WIN64 // Just in case. if (Process->IsWow64) flags |= PH_GET_PROCESS_ENVIRONMENT_WOW64; #endif if (NT_SUCCESS(PhGetProcessEnvironment( processHandle, flags, &environment, &environmentLength ))) { enumerationKey = 0; while (PhEnumProcessEnvironmentVariables(environment, environmentLength, &enumerationKey, &variable)) { PH_STRINGREF part; PH_STRINGREF remainingPart; if (!PhEqualStringRef(&variable.Name, &activeDevices, TRUE)) continue; remainingPart = variable.Value; while (remainingPart.Length != 0) { PhSplitStringRefAtChar(&remainingPart, ';', &part, &remainingPart); if (part.Length != 0) { HANDLE driverKeyHandle; PPH_STRING driverKeyPath; driverKeyPath = PhConcatStringRef2(¤tControlSetEnum, &part); if (NT_SUCCESS(PhOpenKey( &driverKeyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &driverKeyPath->sr, 0 ))) { PPH_STRING deviceDesc; PH_STRINGREF deviceName; PPH_STRING hardwareId; if (deviceDesc = PhQueryRegistryString(driverKeyHandle, L"DeviceDesc")) { PH_STRINGREF firstPart; PH_STRINGREF secondPart; if (PhSplitStringRefAtLastChar(&deviceDesc->sr, ';', &firstPart, &secondPart)) deviceName = secondPart; else deviceName = deviceDesc->sr; } else { PhInitializeStringRef(&deviceName, L"Unknown Device"); } hardwareId = PhQueryRegistryString(driverKeyHandle, L"HardwareID"); PhAppendStringBuilder(Drivers, &StandardIndent); PhAppendStringBuilder(Drivers, &deviceName); if (hardwareId) { PhTrimToNullTerminatorString(hardwareId); if (hardwareId->Length != 0) { PhAppendStringBuilder2(Drivers, L" ("); PhAppendStringBuilder(Drivers, &hardwareId->sr); PhAppendCharStringBuilder(Drivers, ')'); } } PhAppendCharStringBuilder(Drivers, '\n'); PhClearReference(&hardwareId); PhClearReference(&deviceDesc); NtClose(driverKeyHandle); } PhDereferenceObject(driverKeyPath); } } } PhFreePage(environment); } NtClose(processHandle); }