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 PhGetSignerNameFromCertificate( _In_ PCERT_CONTEXT Certificate ) { PCERT_INFO certInfo; PH_STRINGREF keyName; PPH_STRING name; PPH_STRING value; // Cert context -> Cert info certInfo = Certificate->pCertInfo; if (!certInfo) return NULL; // Cert info subject -> Subject X.500 string name = PhpGetCertNameString(&certInfo->Subject); // Subject X.500 string -> CN or OU value PhInitializeStringRef(&keyName, L"CN"); value = PhpGetX500Value(&name->sr, &keyName); if (!value) { PhInitializeStringRef(&keyName, L"OU"); value = PhpGetX500Value(&name->sr, &keyName); } PhDereferenceObject(name); return value; }
_May_raise_ PH_INTEGER_PAIR PhGetIntegerPairSetting( _In_ PWSTR Name ) { PPH_SETTING setting; PH_STRINGREF name; PH_INTEGER_PAIR value; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockShared(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == IntegerPairSettingType) { value = setting->u.IntegerPair; } else { setting = NULL; } PhReleaseQueuedLockShared(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); return value; }
_May_raise_ VOID PhSetScalableIntegerPairSetting( _In_ PWSTR Name, _In_ PH_SCALABLE_INTEGER_PAIR Value ) { PPH_SETTING setting; PH_STRINGREF name; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockExclusive(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == ScalableIntegerPairSettingType) { PhpFreeSettingValue(ScalableIntegerPairSettingType, setting); setting->u.Pointer = PhAllocateCopy(&Value, sizeof(PH_SCALABLE_INTEGER_PAIR)); } PhReleaseQueuedLockExclusive(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); }
_May_raise_ VOID PhSetStringSetting2( _In_ PWSTR Name, _In_ PPH_STRINGREF Value ) { PPH_SETTING setting; PH_STRINGREF name; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockExclusive(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == StringSettingType) { PhpFreeSettingValue(StringSettingType, setting); setting->u.Pointer = PhCreateString2(Value); } PhReleaseQueuedLockExclusive(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); }
VOID TreeNewMessageCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; switch (message->Message) { case TreeNewGetCellText: { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; PPH_PROCESS_NODE node; node = (PPH_PROCESS_NODE)getCellText->Node; switch (message->SubId) { case PIDHEX_COLUMN_ID: { if (!PH_IS_FAKE_PROCESS_ID(node->ProcessId)) { PPROCESS_EXTENSION extension; extension = PhPluginGetObjectExtension(PluginInstance, node->ProcessItem, EmProcessItemType); PhInitializeStringRef(&getCellText->Text, extension->PidHexText); } } break; } } break; } }
BOOLEAN WordMatchStringZ( _In_ PWSTR Text ) { PH_STRINGREF text; PhInitializeStringRef(&text, Text); return WordMatchStringRef(&text); }
VOID EtGpuSystemInformationInitializing( __in PPH_PLUGIN_SYSINFO_POINTERS Pointers ) { PH_SYSINFO_SECTION section; memset(§ion, 0, sizeof(PH_SYSINFO_SECTION)); PhInitializeStringRef(§ion.Name, L"GPU"); section.Flags = 0; section.Callback = EtpGpuSectionCallback; GpuSection = Pointers->CreateSection(§ion); }
/** * Registers a plugin with the host. * * \param Name A unique identifier for the plugin. The function fails * if another plugin has already been registered with the same name. The * name must only contain alphanumeric characters, spaces, dots and * underscores. * \param DllBase The base address of the plugin DLL. This is passed * to the DllMain function. * \param Information A variable which receives a pointer to the * plugin's additional information block. This should be filled in after * the function returns. * * \return A pointer to the plugin instance structure, or NULL if the * function failed. */ PPH_PLUGIN PhRegisterPlugin( _In_ PWSTR Name, _In_ PVOID DllBase, _Out_opt_ PPH_PLUGIN_INFORMATION *Information ) { PPH_PLUGIN plugin; PH_STRINGREF pluginName; PPH_AVL_LINKS existingLinks; ULONG i; PPH_STRING fileName; PhInitializeStringRef(&pluginName, Name); if (!PhpValidatePluginName(&pluginName)) return NULL; fileName = PhGetDllFileName(DllBase, NULL); if (!fileName) return NULL; plugin = PhAllocate(sizeof(PH_PLUGIN)); memset(plugin, 0, sizeof(PH_PLUGIN)); plugin->Name = Name; plugin->DllBase = DllBase; plugin->FileName = fileName; existingLinks = PhAddElementAvlTree(&PhPluginsByName, &plugin->Links); if (existingLinks) { // Another plugin has already been registered with the same name. PhFree(plugin); return NULL; } for (i = 0; i < PluginCallbackMaximum; i++) PhInitializeCallback(&plugin->Callbacks[i]); PhEmInitializeAppContext(&plugin->AppContext, &pluginName); if (Information) *Information = &plugin->Information; return plugin; }
PVOID LoadMscordacwks( __in BOOLEAN IsClrV4 ) { PVOID dllBase; PH_STRINGREF systemRootString; PH_STRINGREF mscordacwksPathString; PPH_STRING mscordacwksFileName; LoadLibrary(L"mscoree.dll"); PhGetSystemRoot(&systemRootString); if (IsClrV4) { #ifdef _M_X64 PhInitializeStringRef(&mscordacwksPathString, L"\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll"); #else PhInitializeStringRef(&mscordacwksPathString, L"\\Microsoft.NET\\Framework\\v4.0.30319\\mscordacwks.dll"); #endif } else { #ifdef _M_X64 PhInitializeStringRef(&mscordacwksPathString, L"\\Microsoft.NET\\Framework64\\v2.0.50727\\mscordacwks.dll"); #else PhInitializeStringRef(&mscordacwksPathString, L"\\Microsoft.NET\\Framework\\v2.0.50727\\mscordacwks.dll"); #endif } mscordacwksFileName = PhConcatStringRef2(&systemRootString, &mscordacwksPathString); dllBase = LoadLibrary(mscordacwksFileName->Buffer); PhDereferenceObject(mscordacwksFileName); return dllBase; }
_May_raise_ PH_SCALABLE_INTEGER_PAIR PhGetScalableIntegerPairSetting( _In_ PWSTR Name, _In_ BOOLEAN ScaleToCurrent ) { PPH_SETTING setting; PH_STRINGREF name; PH_SCALABLE_INTEGER_PAIR value; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockShared(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == ScalableIntegerPairSettingType) { value = *(PPH_SCALABLE_INTEGER_PAIR)setting->u.Pointer; } else { setting = NULL; } PhReleaseQueuedLockShared(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); if (ScaleToCurrent) { ULONG currentScale; currentScale = PhpGetCurrentScale(); if (value.Scale != currentScale && value.Scale != 0) { value.X = PhMultiplyDivideSigned(value.X, currentScale, value.Scale); value.Y = PhMultiplyDivideSigned(value.Y, currentScale, value.Scale); value.Scale = currentScale; } } return value; }
PDNA_NODE AddFakeClrNode( _In_ PASMPAGE_QUERY_CONTEXT Context, _In_ PWSTR DisplayName ) { PDNA_NODE node; node = AddNode(Context); node->Type = DNA_TYPE_CLR; node->IsFakeClr = TRUE; node->u.Clr.ClrInstanceID = 0; node->u.Clr.DisplayName = NULL; PhInitializeStringRef(&node->StructureText, DisplayName); PhAddItemList(Context->NodeRootList, node); return node; }
VOID PerfCounterSysInfoInitializing( _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers, _In_ PPH_STRING CounterName ) { PH_SYSINFO_SECTION section; PPH_PERFMON_SYSINFO_CONTEXT context; context = (PPH_PERFMON_SYSINFO_CONTEXT)PhAllocate(sizeof(PH_PERFMON_SYSINFO_CONTEXT)); memset(context, 0, sizeof(PH_PERFMON_SYSINFO_CONTEXT)); memset(§ion, 0, sizeof(PH_SYSINFO_SECTION)); section.Context = context; section.Callback = PerfCounterSectionCallback; PhInitializeStringRef(§ion.Name, CounterName->Buffer); context->SysinfoSection = Pointers->CreateSection(§ion); }
VOID NvGpuSysInfoInitializing( _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers ) { PH_SYSINFO_SECTION section; PPH_NVGPU_SYSINFO_CONTEXT context; context = (PPH_NVGPU_SYSINFO_CONTEXT)PhAllocate(sizeof(PH_NVGPU_SYSINFO_CONTEXT)); memset(context, 0, sizeof(PH_NVGPU_SYSINFO_CONTEXT)); memset(§ion, 0, sizeof(PH_SYSINFO_SECTION)); section.Context = context; section.Callback = NvGpuSectionCallback; context->GpuName = NvGpuQueryName(); PhInitializeStringRef(§ion.Name, context->GpuName->Buffer); context->Section = Pointers->CreateSection(§ion); }
_May_raise_ PPH_STRING PhGetStringSetting( _In_ PWSTR Name ) { PPH_SETTING setting; PH_STRINGREF name; PPH_STRING value; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockShared(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == StringSettingType) { if (setting->u.Pointer) { PhSetReference(&value, setting->u.Pointer); } else { // Set to NULL, create an empty string // outside of the lock. value = NULL; } } else { setting = NULL; } PhReleaseQueuedLockShared(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); if (!value) value = PhReferenceEmptyString(); return value; }
VOID NvGpuSysInfoInitializing( _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers ) { PH_SYSINFO_SECTION section; if (!PhGetIntegerSetting(SETTING_NAME_ENABLE_GPU)) return; if (!NvApiInitialized) return; memset(§ion, 0, sizeof(PH_SYSINFO_SECTION)); section.Callback = NvGpuSectionCallback; GpuName = NvGpuQueryName(); PhInitializeStringRef(§ion.Name, GpuName->Buffer); Section = Pointers->CreateSection(§ion); }
VOID NetAdapterSysInfoInitializing( _In_ PPH_PLUGIN_SYSINFO_POINTERS Pointers, _In_ PPH_NETADAPTER_ENTRY AdapterEntry ) { PH_SYSINFO_SECTION section; PPH_NETADAPTER_SYSINFO_CONTEXT context; context = (PPH_NETADAPTER_SYSINFO_CONTEXT)PhAllocate(sizeof(PH_NETADAPTER_SYSINFO_CONTEXT)); memset(context, 0, sizeof(PH_NETADAPTER_SYSINFO_CONTEXT)); memset(§ion, 0, sizeof(PH_SYSINFO_SECTION)); context->AdapterEntry = AdapterEntry; section.Context = context; section.Callback = NetAdapterSectionCallback; PhInitializeStringRef(§ion.Name, L""); context->SysinfoSection = Pointers->CreateSection(§ion); }
PPH_SERVICE_ITEM PhReferenceServiceItem( _In_ PWSTR Name ) { PPH_SERVICE_ITEM serviceItem; PH_STRINGREF key; // Construct a temporary service item for the lookup. PhInitializeStringRef(&key, Name); PhAcquireQueuedLockShared(&PhServiceHashtableLock); serviceItem = PhpLookupServiceItem(&key); if (serviceItem) PhReferenceObject(serviceItem); PhReleaseQueuedLockShared(&PhServiceHashtableLock); return serviceItem; }
ULONG64 QueryRegistryUlong64( _In_ HANDLE KeyHandle, _In_ PWSTR ValueName ) { ULONG64 value = 0; PH_STRINGREF valueName; PKEY_VALUE_PARTIAL_INFORMATION buffer; PhInitializeStringRef(&valueName, ValueName); if (NT_SUCCESS(PhQueryValueKey(KeyHandle, &valueName, KeyValuePartialInformation, &buffer))) { if (buffer->Type == REG_DWORD || buffer->Type == REG_QWORD) { value = *(ULONG64*)buffer->Data; } PhFree(buffer); } return value; }
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 ); }
_May_raise_ VOID PhSetIntegerPairSetting( _In_ PWSTR Name, _In_ PH_INTEGER_PAIR Value ) { PPH_SETTING setting; PH_STRINGREF name; PhInitializeStringRef(&name, Name); PhAcquireQueuedLockExclusive(&PhSettingsLock); setting = PhpLookupSetting(&name); if (setting && setting->Type == IntegerPairSettingType) { setting->u.IntegerPair = Value; } PhReleaseQueuedLockExclusive(&PhSettingsLock); if (!setting) PhRaiseStatus(STATUS_NOT_FOUND); }
VOID NTAPI EtpRundownEtwEventCallback( _In_ PEVENT_RECORD EventRecord ) { // TODO: Find a way to call CloseTrace when the enumeration finishes so we can // stop the trace cleanly. if (memcmp(&EventRecord->EventHeader.ProviderId, &FileIoGuid_I, sizeof(GUID)) == 0) { // FileIo ET_ETW_FILE_EVENT fileEvent; memset(&fileEvent, 0, sizeof(ET_ETW_FILE_EVENT)); fileEvent.Type = -1; switch (EventRecord->EventHeader.EventDescriptor.Opcode) { case 36: // FileRundown fileEvent.Type = EtEtwFileRundownType; break; default: break; } if (fileEvent.Type != -1) { FileIo_Name *data = EventRecord->UserData; fileEvent.FileObject = (PVOID)data->FileObject; PhInitializeStringRef(&fileEvent.FileName, data->FileName); EtDiskProcessFileEvent(&fileEvent); } } }
VOID TreeNewMessageCallback( __in_opt PVOID Parameter, __in_opt PVOID Context ) { PPH_PLUGIN_TREENEW_MESSAGE message = Parameter; switch (message->Message) { case TreeNewGetCellText: { PPH_TREENEW_GET_CELL_TEXT getCellText = message->Parameter1; PPH_PROCESS_NODE node; PPROCESS_EXTENSION extension; node = (PPH_PROCESS_NODE)getCellText->Node; extension = PhPluginGetObjectExtension(PluginInstance, node->ProcessItem, EmProcessItemType); switch (message->SubId) { case COLUMN_ID_AVGCPU10: case COLUMN_ID_AVGCPU60: { FLOAT cpuUsage; PWCHAR buffer; if (message->SubId == COLUMN_ID_AVGCPU10) { cpuUsage = extension->Avg10CpuUsage * 100; buffer = extension->Avg10CpuUsageText; } else { cpuUsage = extension->Avg60CpuUsage * 100; buffer = extension->Avg60CpuUsageText; } if (cpuUsage >= 0.01) { PH_FORMAT format; SIZE_T returnLength; PhInitFormatF(&format, cpuUsage, 2); if (PhFormatToBuffer(&format, 1, buffer, PH_INT32_STR_LEN_1 * sizeof(WCHAR), &returnLength)) { getCellText->Text.Buffer = buffer; getCellText->Text.Length = (USHORT)(returnLength - sizeof(WCHAR)); // minus null terminator } } else if (cpuUsage != 0 && PhGetIntegerSetting(L"ShowCpuBelow001")) { PhInitializeStringRef(&getCellText->Text, L"< 0.01"); } } break; } } break; } }
VOID NTAPI EtpEtwEventCallback( _In_ PEVENT_RECORD EventRecord ) { if (memcmp(&EventRecord->EventHeader.ProviderId, &DiskIoGuid_I, sizeof(GUID)) == 0) { // DiskIo ET_ETW_DISK_EVENT diskEvent; memset(&diskEvent, 0, sizeof(ET_ETW_DISK_EVENT)); diskEvent.Type = -1; switch (EventRecord->EventHeader.EventDescriptor.Opcode) { case EVENT_TRACE_TYPE_IO_READ: diskEvent.Type = EtEtwDiskReadType; break; case EVENT_TRACE_TYPE_IO_WRITE: diskEvent.Type = EtEtwDiskWriteType; break; default: break; } if (diskEvent.Type != -1) { DiskIo_TypeGroup1 *data = EventRecord->UserData; if (WindowsVersion >= WINDOWS_8) { diskEvent.ClientId.UniqueThread = UlongToHandle(data->IssuingThreadId); diskEvent.ClientId.UniqueProcess = EtThreadIdToProcessId(diskEvent.ClientId.UniqueThread); } else { if (EventRecord->EventHeader.ProcessId != -1) { diskEvent.ClientId.UniqueProcess = UlongToHandle(EventRecord->EventHeader.ProcessId); diskEvent.ClientId.UniqueThread = UlongToHandle(EventRecord->EventHeader.ThreadId); } } diskEvent.IrpFlags = data->IrpFlags; diskEvent.TransferSize = data->TransferSize; diskEvent.FileObject = (PVOID)data->FileObject; diskEvent.HighResResponseTime = data->HighResResponseTime; EtProcessDiskEvent(&diskEvent); EtDiskProcessDiskEvent(&diskEvent); } } else if (memcmp(&EventRecord->EventHeader.ProviderId, &FileIoGuid_I, sizeof(GUID)) == 0) { // FileIo ET_ETW_FILE_EVENT fileEvent; memset(&fileEvent, 0, sizeof(ET_ETW_FILE_EVENT)); fileEvent.Type = -1; switch (EventRecord->EventHeader.EventDescriptor.Opcode) { case 0: // Name fileEvent.Type = EtEtwFileNameType; break; case 32: // FileCreate fileEvent.Type = EtEtwFileCreateType; break; case 35: // FileDelete fileEvent.Type = EtEtwFileDeleteType; break; default: break; } if (fileEvent.Type != -1) { FileIo_Name *data = EventRecord->UserData; fileEvent.FileObject = (PVOID)data->FileObject; PhInitializeStringRef(&fileEvent.FileName, data->FileName); EtDiskProcessFileEvent(&fileEvent); } } else if ( memcmp(&EventRecord->EventHeader.ProviderId, &TcpIpGuid_I, sizeof(GUID)) == 0 || memcmp(&EventRecord->EventHeader.ProviderId, &UdpIpGuid_I, sizeof(GUID)) == 0 ) { // TcpIp/UdpIp ET_ETW_NETWORK_EVENT networkEvent; memset(&networkEvent, 0, sizeof(ET_ETW_NETWORK_EVENT)); networkEvent.Type = -1; switch (EventRecord->EventHeader.EventDescriptor.Opcode) { case EVENT_TRACE_TYPE_SEND: // send networkEvent.Type = EtEtwNetworkSendType; networkEvent.ProtocolType = PH_IPV4_NETWORK_TYPE; break; case EVENT_TRACE_TYPE_RECEIVE: // receive networkEvent.Type = EtEtwNetworkReceiveType; networkEvent.ProtocolType = PH_IPV4_NETWORK_TYPE; break; case EVENT_TRACE_TYPE_SEND + 16: // send ipv6 networkEvent.Type = EtEtwNetworkSendType; networkEvent.ProtocolType = PH_IPV6_NETWORK_TYPE; break; case EVENT_TRACE_TYPE_RECEIVE + 16: // receive ipv6 networkEvent.Type = EtEtwNetworkReceiveType; networkEvent.ProtocolType = PH_IPV6_NETWORK_TYPE; break; } if (memcmp(&EventRecord->EventHeader.ProviderId, &TcpIpGuid_I, sizeof(GUID)) == 0) networkEvent.ProtocolType |= PH_TCP_PROTOCOL_TYPE; else networkEvent.ProtocolType |= PH_UDP_PROTOCOL_TYPE; if (networkEvent.Type != -1) { PH_IP_ENDPOINT source; PH_IP_ENDPOINT destination; if (networkEvent.ProtocolType & PH_IPV4_NETWORK_TYPE) { TcpIpOrUdpIp_IPV4_Header *data = EventRecord->UserData; networkEvent.ClientId.UniqueProcess = UlongToHandle(data->PID); networkEvent.TransferSize = data->size; source.Address.Type = PH_IPV4_NETWORK_TYPE; source.Address.Ipv4 = data->saddr; source.Port = _byteswap_ushort(data->sport); destination.Address.Type = PH_IPV4_NETWORK_TYPE; destination.Address.Ipv4 = data->daddr; destination.Port = _byteswap_ushort(data->dport); } else if (networkEvent.ProtocolType & PH_IPV6_NETWORK_TYPE) { TcpIpOrUdpIp_IPV6_Header *data = EventRecord->UserData; networkEvent.ClientId.UniqueProcess = UlongToHandle(data->PID); networkEvent.TransferSize = data->size; source.Address.Type = PH_IPV6_NETWORK_TYPE; source.Address.In6Addr = data->saddr; source.Port = _byteswap_ushort(data->sport); destination.Address.Type = PH_IPV6_NETWORK_TYPE; destination.Address.In6Addr = data->daddr; destination.Port = _byteswap_ushort(data->dport); } networkEvent.LocalEndpoint = source; if (networkEvent.ProtocolType & PH_TCP_PROTOCOL_TYPE) networkEvent.RemoteEndpoint = destination; EtProcessNetworkEvent(&networkEvent); } } }
INT_PTR CALLBACK PhpPluginsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PPH_AVL_LINKS links; PhCenterWindow(hwndDlg, PhMainWndHandle); PluginsLv = GetDlgItem(hwndDlg, IDC_LIST); PhSetListViewStyle(PluginsLv, FALSE, TRUE); PhSetControlTheme(PluginsLv, L"explorer"); PhAddListViewColumn(PluginsLv, 0, 0, 0, LVCFMT_LEFT, 280, L"Name"); PhAddListViewColumn(PluginsLv, 1, 1, 1, LVCFMT_LEFT, 100, L"Author"); PhSetExtendedListView(PluginsLv); ExtendedListView_SetItemColorFunction(PluginsLv, PhpPluginColorFunction); DisabledPluginLookup = PhCreateSimpleHashtable(10); for (links = PhMinimumElementAvlTree(&PhPluginsByName); links; links = PhSuccessorElementAvlTree(links)) { PPH_PLUGIN plugin = CONTAINING_RECORD(links, PH_PLUGIN, Links); INT lvItemIndex; PH_STRINGREF baseNameSr; lvItemIndex = PhAddListViewItem(PluginsLv, MAXINT, plugin->Information.DisplayName ? plugin->Information.DisplayName : plugin->Name.Buffer, plugin); if (plugin->Information.Author) PhSetListViewSubItem(PluginsLv, lvItemIndex, 1, plugin->Information.Author); PhInitializeStringRefLongHint(&baseNameSr, PhpGetPluginBaseName(plugin)); if (PhIsPluginDisabled(&baseNameSr)) PhAddItemSimpleHashtable(DisabledPluginLookup, plugin, NULL); } DisabledPluginInstances = PhCreateList(10); PhpAddDisabledPlugins(); ExtendedListView_SortItems(PluginsLv); SelectedPlugin = NULL; PhpRefreshPluginDetails(hwndDlg); } break; case WM_DESTROY: { ULONG i; for (i = 0; i < DisabledPluginInstances->Count; i++) PhpFreeDisabledPlugin(DisabledPluginInstances->Items[i]); PhDereferenceObject(DisabledPluginInstances); PhDereferenceObject(DisabledPluginLookup); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_DISABLE: { if (SelectedPlugin) { PWSTR baseName; PH_STRINGREF baseNameRef; BOOLEAN newDisabledState; baseName = PhpGetPluginBaseName(SelectedPlugin); PhInitializeStringRef(&baseNameRef, baseName); newDisabledState = !PhIsPluginDisabled(&baseNameRef); PhSetPluginDisabled(&baseNameRef, newDisabledState); PhpUpdateDisabledPlugin(hwndDlg, PhFindListViewItemByFlags(PluginsLv, -1, LVNI_SELECTED), SelectedPlugin, newDisabledState); SetDlgItemText(hwndDlg, IDC_DISABLE, PhpGetPluginDisableButtonText(baseName)); } } break; case IDC_OPTIONS: { if (SelectedPlugin && IS_PLUGIN_LOADED(SelectedPlugin)) { PhInvokeCallback(PhGetPluginCallback(SelectedPlugin, PluginCallbackShowOptions), hwndDlg); } } break; case IDC_CLEANUP: { if (PhShowMessage(hwndDlg, MB_ICONQUESTION | MB_YESNO, L"Do you want to clean up unused plugin settings?") == IDYES) { PhClearIgnoredSettings(); } } break; case IDC_OPENURL: { NOTHING; } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case LVN_ITEMCHANGED: { if (header->hwndFrom == PluginsLv) { if (ListView_GetSelectedCount(PluginsLv) == 1) SelectedPlugin = PhGetSelectedListViewItemParam(PluginsLv); else SelectedPlugin = NULL; PhpRefreshPluginDetails(hwndDlg); } } break; case NM_CLICK: { if (header->hwndFrom == GetDlgItem(hwndDlg, IDC_OPENURL)) { if (SelectedPlugin && IS_PLUGIN_LOADED(SelectedPlugin)) PhShellExecute(hwndDlg, SelectedPlugin->Information.Url, NULL); } } break; case NM_DBLCLK: { if (header->hwndFrom == PluginsLv) { if (SelectedPlugin && IS_PLUGIN_LOADED(SelectedPlugin)) { PhInvokeCallback(PhGetPluginCallback(SelectedPlugin, PluginCallbackShowOptions), hwndDlg); } } } break; } } break; } REFLECT_MESSAGE_DLG(hwndDlg, PluginsLv, uMsg, wParam, lParam); return FALSE; }
static INT_PTR CALLBACK PhpInformationDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PWSTR string = (PWSTR)lParam; PPH_LAYOUT_MANAGER layoutManager; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); SetDlgItemText(hwndDlg, IDC_TEXT, string); layoutManager = PhAllocate(sizeof(PH_LAYOUT_MANAGER)); PhInitializeLayoutManager(layoutManager, hwndDlg); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_TEXT), NULL, PH_ANCHOR_ALL); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDOK), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_COPY), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); PhAddLayoutItem(layoutManager, GetDlgItem(hwndDlg, IDC_SAVE), NULL, PH_ANCHOR_RIGHT | PH_ANCHOR_BOTTOM); if (MinimumSize.left == -1) { RECT rect; rect.left = 0; rect.top = 0; rect.right = 200; rect.bottom = 140; MapDialogRect(hwndDlg, &rect); MinimumSize = rect; MinimumSize.left = 0; } SetProp(hwndDlg, L"LayoutManager", (HANDLE)layoutManager); SetProp(hwndDlg, L"String", (HANDLE)string); } break; case WM_DESTROY: { PPH_LAYOUT_MANAGER layoutManager; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhDeleteLayoutManager(layoutManager); PhFree(layoutManager); RemoveProp(hwndDlg, L"String"); RemoveProp(hwndDlg, L"LayoutManager"); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_COPY: { HWND editControl; LONG selStart; LONG selEnd; PWSTR buffer; PH_STRINGREF string; editControl = GetDlgItem(hwndDlg, IDC_TEXT); SendMessage(editControl, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd); buffer = (PWSTR)GetProp(hwndDlg, L"String"); if (selStart == selEnd) { // Select and copy the entire string. PhInitializeStringRefLongHint(&string, buffer); Edit_SetSel(editControl, 0, -1); } else { string.Buffer = buffer + selStart; string.Length = (selEnd - selStart) * 2; } PhSetClipboardString(hwndDlg, &string); SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)editControl, TRUE); } break; case IDC_SAVE: { static PH_FILETYPE_FILTER filters[] = { { L"Text files (*.txt)", L"*.txt" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; fileDialog = PhCreateSaveFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); PhSetFileDialogFileName(fileDialog, L"Information.txt"); if (PhShowFileDialog(hwndDlg, fileDialog)) { NTSTATUS status; PPH_STRING fileName; PPH_FILE_STREAM fileStream; fileName = PhGetFileDialogFileName(fileDialog); PhAutoDereferenceObject(fileName); if (NT_SUCCESS(status = PhCreateFileStream( &fileStream, fileName->Buffer, FILE_GENERIC_WRITE, FILE_SHARE_READ, FILE_OVERWRITE_IF, 0 ))) { PH_STRINGREF string; PhWriteStringAsUtf8FileStream(fileStream, &PhUnicodeByteOrderMark); PhInitializeStringRef(&string, (PWSTR)GetProp(hwndDlg, L"String")); PhWriteStringAsUtf8FileStream(fileStream, &string); PhDereferenceObject(fileStream); } if (!NT_SUCCESS(status)) PhShowStatus(hwndDlg, L"Unable to create the file", status, 0); } PhFreeFileDialog(fileDialog); } break; } } break; case WM_SIZE: { PPH_LAYOUT_MANAGER layoutManager; layoutManager = (PPH_LAYOUT_MANAGER)GetProp(hwndDlg, L"LayoutManager"); PhLayoutManagerLayout(layoutManager); } break; case WM_SIZING: { PhResizingMinimumSize((PRECT)lParam, wParam, MinimumSize.right, MinimumSize.bottom); } break; } return FALSE; }
VOID PhShellExecuteUserString( __in HWND hWnd, __in PWSTR Setting, __in PWSTR String, __in BOOLEAN UseShellExecute, __in_opt PWSTR ErrorMessage ) { static PH_STRINGREF replacementToken = PH_STRINGREF_INIT(L"%s"); PPH_STRING executeString; PH_STRINGREF stringBefore; PH_STRINGREF stringMiddle; PH_STRINGREF stringAfter; PPH_STRING newString; PPH_STRING ntMessage; executeString = PhGetStringSetting(Setting); // Make sure the user executable string is absolute. // We can't use RtlDetermineDosPathNameType_U here because the string // may be a URL. if (PhFindCharInString(executeString, 0, ':') == -1) { newString = PhConcatStringRef2(&PhApplicationDirectory->sr, &executeString->sr); PhDereferenceObject(executeString); executeString = newString; } // Replace "%s" with the string, or use the original string if "%s" is not present. if (PhSplitStringRefAtString(&executeString->sr, &replacementToken, FALSE, &stringBefore, &stringAfter)) { PhInitializeStringRef(&stringMiddle, String); newString = PhConcatStringRef3(&stringBefore, &stringMiddle, &stringAfter); } else { newString = executeString; PhReferenceObject(newString); } PhDereferenceObject(executeString); if (UseShellExecute) { PhShellExecute(hWnd, newString->Buffer, NULL); } else { NTSTATUS status; status = PhCreateProcessWin32(NULL, newString->Buffer, NULL, NULL, 0, NULL, NULL, NULL); if (!NT_SUCCESS(status)) { if (ErrorMessage) { ntMessage = PhGetNtMessage(status); PhShowError(hWnd, L"Unable to execute the command: %s\n%s", PhGetStringOrDefault(ntMessage, L"An unknown error occurred."), ErrorMessage); PhDereferenceObject(ntMessage); } else { PhShowStatus(hWnd, L"Unable to execute the command", status, 0); } } } PhDereferenceObject(newString); }
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; }
/** * Finds a child menu item. * * \param Item The parent menu item. * \param Flags A combination of the following: * \li \c PH_EMENU_FIND_DESCEND Searches recursively within child * menu items. * \li \c PH_EMENU_FIND_STARTSWITH Performs a partial text search * instead of an exact search. * \li \c PH_EMENU_FIND_LITERAL Performs a literal search instead of * ignoring prefix characters (ampersands). * \param Text The text of the menu item to find. If NULL, the text * is ignored. * \param Id The identifier of the menu item to find. If 0, the * identifier is ignored. * * \return The found menu item, or NULL if the menu item could not * be found. */ PPH_EMENU_ITEM PhFindEMenuItem( __in PPH_EMENU_ITEM Item, __in ULONG Flags, __in_opt PWSTR Text, __in_opt ULONG Id ) { ULONG i; PH_STRINGREF searchText; if (!Item->Items) return NULL; if (Text && (Flags & PH_EMENU_FIND_LITERAL)) PhInitializeStringRef(&searchText, Text); for (i = 0; i < Item->Items->Count; i++) { PPH_EMENU_ITEM item; item = Item->Items->Items[i]; if (Text) { if (Flags & PH_EMENU_FIND_LITERAL) { PH_STRINGREF text; PhInitializeStringRef(&text, item->Text); if (Flags & PH_EMENU_FIND_STARTSWITH) { if (PhStartsWithStringRef(&text, &searchText, TRUE)) return item; } else { if (PhEqualStringRef(&text, &searchText, TRUE)) return item; } } else { if (PhCompareUnicodeStringZIgnoreMenuPrefix(Text, item->Text, TRUE, !!(Flags & PH_EMENU_FIND_STARTSWITH)) == 0) return item; } } if (Id && item->Id == Id) return item; if (Flags & PH_EMENU_FIND_DESCEND) { PPH_EMENU_ITEM foundItem; foundItem = PhFindEMenuItem(item, Flags, Text, Id); if (foundItem) return foundItem; } } return NULL; }
PPH_STRING PhpGetSignerNameFromStateData( __in HANDLE StateData ) { PCRYPT_PROVIDER_DATA provData; PCRYPT_PROVIDER_SGNR sgnr; PCRYPT_PROVIDER_CERT cert; PCCERT_CONTEXT certContext; PCERT_INFO certInfo; PH_STRINGREF keyName; PPH_STRING name; PPH_STRING value; // 1. State data -> provider data. provData = WTHelperProvDataFromStateData_I(StateData); if (!provData) return NULL; // 2. Provider data -> Provider signer sgnr = WTHelperGetProvSignerFromChain_I(provData, 0, FALSE, 0); if (!sgnr) return NULL; if (!sgnr->pasCertChain) return NULL; if (sgnr->csCertChain == 0) return NULL; // 3. Provider signer -> Provider cert cert = &sgnr->pasCertChain[0]; // 4. Provider cert -> Cert context certContext = cert->pCert; if (!certContext) return NULL; // 5. Cert context -> Cert info certInfo = certContext->pCertInfo; if (!certInfo) return NULL; // 6. Cert info subject -> Subject X.500 string name = PhpGetCertNameString(&certInfo->Subject); // 7. Subject X.500 string -> CN or OU value PhInitializeStringRef(&keyName, L"CN"); value = PhpGetX500Value(name, &keyName); if (!value) { PhInitializeStringRef(&keyName, L"OU"); value = PhpGetX500Value(name, &keyName); } PhDereferenceObject(name); return value; }