static BOOLEAN PathMatchesPh( _In_ PPH_STRING Path ) { BOOLEAN match = FALSE; if (PhEqualString(OldTaskMgrDebugger, PhApplicationFileName, TRUE)) { match = TRUE; } // Allow for a quoted value. else if ( OldTaskMgrDebugger->Length == PhApplicationFileName->Length + sizeof(WCHAR) * 2 && OldTaskMgrDebugger->Buffer[0] == '"' && OldTaskMgrDebugger->Buffer[OldTaskMgrDebugger->Length / sizeof(WCHAR) - 1] == '"' ) { PH_STRINGREF partInside; partInside.Buffer = &OldTaskMgrDebugger->Buffer[1]; partInside.Length = OldTaskMgrDebugger->Length - sizeof(WCHAR) * 2; if (PhEqualStringRef(&partInside, &PhApplicationFileName->sr, TRUE)) match = TRUE; } return match; }
BOOLEAN EquivalentDiskId( _In_ PDV_DISK_ID Id1, _In_ PDV_DISK_ID Id2 ) { return PhEqualString(Id1->DevicePath, Id2->DevicePath, TRUE); }
PVIRUSTOTAL_FILE_HASH_ENTRY VirusTotalGetCachedResultFromHash( _In_ PPH_STRING FileHash ) { ULONG i; BOOLEAN found = FALSE; PhAcquireQueuedLockExclusive(&ProcessListLock); for (i = 0; i < VirusTotalList->Count; i++) { PVIRUSTOTAL_FILE_HASH_ENTRY extension = VirusTotalList->Items[i]; if (PhIsNullOrEmptyString(extension->FileHash)) continue; if (PhEqualString(extension->FileHash, FileHash, TRUE)) { PhReleaseQueuedLockExclusive(&ProcessListLock); return extension; } } PhReleaseQueuedLockExclusive(&ProcessListLock); return NULL; }
BOOLEAN NTAPI EtpDiskHashtableCompareFunction( __in PVOID Entry1, __in PVOID Entry2 ) { PET_DISK_ITEM diskItem1 = *(PET_DISK_ITEM *)Entry1; PET_DISK_ITEM diskItem2 = *(PET_DISK_ITEM *)Entry2; return diskItem1->ProcessId == diskItem2->ProcessId && PhEqualString(diskItem1->FileName, diskItem2->FileName, TRUE); }
VOID PhSaveSettingsColumnSet( _In_ PWSTR SettingName, _In_ PPH_STRING ColumnSetName, _In_ PPH_STRING TreeListSettings, _In_ PPH_STRING TreeSortSettings ) { ULONG index; BOOLEAN found = FALSE; PPH_LIST columnSetList; columnSetList = PhInitializeColumnSetList(SettingName); for (index = 0; index < columnSetList->Count; index++) { PPH_COLUMN_SET_ENTRY entry = columnSetList->Items[index]; if (PhEqualString(entry->Name, ColumnSetName, FALSE)) { PhReferenceObject(TreeListSettings); PhReferenceObject(TreeSortSettings); PhMoveReference(&entry->Setting, TreeListSettings); PhMoveReference(&entry->Sorting, TreeSortSettings); found = TRUE; break; } } if (!found) { PPH_COLUMN_SET_ENTRY entry; PhReferenceObject(ColumnSetName); PhReferenceObject(TreeListSettings); PhReferenceObject(TreeSortSettings); entry = PhAllocate(sizeof(PH_COLUMN_SET_ENTRY)); entry->Name = ColumnSetName; entry->Setting = TreeListSettings; entry->Sorting = TreeSortSettings; PhAddItemList(columnSetList, entry); } PhSaveSettingsColumnList(SettingName, columnSetList); PhDeleteColumnSetList(columnSetList); }
static VOID ReadCurrentUserRun( VOID ) { HANDLE keyHandle; PPH_STRING value; CurrentUserRunPresent = FALSE; CurrentUserRunStartHidden = FALSE; if (NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_CURRENT_USER, &CurrentUserRunKeyName, 0 ))) { if (value = PhQueryRegistryString(keyHandle, L"Process Hacker 2")) { PH_STRINGREF fileName; PH_STRINGREF arguments; PPH_STRING fullFileName; PH_AUTO(value); if (PhParseCommandLineFuzzy(&value->sr, &fileName, &arguments, &fullFileName)) { PH_AUTO(fullFileName); if (fullFileName && PhEqualString(fullFileName, PhApplicationFileName, TRUE)) { CurrentUserRunPresent = TRUE; CurrentUserRunStartHidden = PhEqualStringRef2(&arguments, L"-hide", FALSE); } } } NtClose(keyHandle); } }
VOID AddFilterType( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ FILTER_BY_TYPE Type, _In_ HANDLE ProcessID, _In_ PPH_STRING ProcessName ) { PDBG_FILTER_TYPE newFilterEntry; newFilterEntry = PhAllocate(sizeof(DBG_FILTER_TYPE)); newFilterEntry->Type = Type; newFilterEntry->ProcessId = ProcessID; newFilterEntry->ProcessName = ProcessName; PhAddItemList(Context->ExcludeList, newFilterEntry); // Remove any existing entries... for (ULONG i = 0; i < Context->LogMessageList->Count; i++) { PDEBUG_LOG_ENTRY listEntry = Context->LogMessageList->Items[i]; if (Type == FilterByName) { if (PhEqualString(listEntry->ProcessName, newFilterEntry->ProcessName, TRUE)) { PhRemoveItemList(Context->LogMessageList, i); i--; } } else if (Type == FilterByPid) { if (listEntry->ProcessId == ProcessID) { PhRemoveItemList(Context->LogMessageList, i); i--; } } } }
static VOID DbgProcessLogMessageEntry( _Inout_ PPH_DBGEVENTS_CONTEXT Context, _In_ BOOLEAN GlobalEvents ) { NTSTATUS status; PDBWIN_PAGE_BUFFER debugMessageBuffer; PDEBUG_LOG_ENTRY entry = NULL; HANDLE processHandle = NULL; PPH_STRING fileName = NULL; HICON icon = NULL; debugMessageBuffer = GlobalEvents ? Context->GlobalDebugBuffer : Context->LocalDebugBuffer; entry = PhAllocate(sizeof(DEBUG_LOG_ENTRY)); memset(entry, 0, sizeof(DEBUG_LOG_ENTRY)); PhQuerySystemTime(&entry->Time); entry->ProcessId = UlongToHandle(debugMessageBuffer->ProcessId); entry->Message = PhConvertMultiByteToUtf16(debugMessageBuffer->Buffer); if (WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID) { status = PhGetProcessImageFileNameByProcessId(entry->ProcessId, &fileName); } else { if (NT_SUCCESS(status = PhOpenProcess(&processHandle, ProcessQueryAccess, entry->ProcessId))) { status = PhGetProcessImageFileName(processHandle, &fileName); NtClose(processHandle); } } if (!NT_SUCCESS(status)) fileName = PhGetKernelFileName(); PhSwapReference2(&fileName, PhGetFileName(fileName)); icon = PhGetFileShellIcon(PhGetString(fileName), L".exe", TRUE); if (icon) { entry->ImageIndex = ImageList_AddIcon(Context->ListViewImageList, icon); DestroyIcon(icon); } entry->FilePath = fileName; entry->ProcessName = PhGetBaseName(fileName); // Drop event if it matches a filter for (ULONG i = 0; i < Context->ExcludeList->Count; i++) { PDBG_FILTER_TYPE filterEntry = Context->ExcludeList->Items[i]; if (filterEntry->Type == FilterByName) { if (PhEqualString(filterEntry->ProcessName, entry->ProcessName, TRUE)) { DbgFreeLogEntry(entry); return; } } else if (filterEntry->Type == FilterByPid) { if (filterEntry->ProcessId == entry->ProcessId) { DbgFreeLogEntry(entry); return; } } } DbgAddLogEntry(Context, entry); }
static NTSTATUS DownloadUpdateThreadStart( __in PVOID Parameter ) { PPH_STRING downloadUrlPath = NULL; HANDLE tempFileHandle = NULL; HINTERNET hInitialize = NULL, hConnection = NULL, hRequest = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; HWND hwndDlg = (HWND)Parameter; Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), FALSE); SetDlgItemText(hwndDlg, IDC_STATUS, L"Initializing"); // Reset the progress state on Vista and above. if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_NORMAL, 0L); if (!ConnectionAvailable()) return status; __try { // Get temp dir. WCHAR tempPathString[MAX_PATH]; DWORD tempPathLength = GetTempPath(MAX_PATH, tempPathString); if (tempPathLength == 0 || tempPathLength > MAX_PATH) { LogEvent(hwndDlg, PhFormatString(L"CreateFile failed (%d)", GetLastError())); __leave; } // create the download path string. downloadUrlPath = PhFormatString( L"/projects/processhacker/files/processhacker2/processhacker-%u.%u-setup.exe/download?use_mirror=autoselect", /* ?use_mirror=waix" */ UpdateData.MajorVersion, UpdateData.MinorVersion ); // Append the tempath to our string: %TEMP%processhacker-%u.%u-setup.exe // Example: C:\\Users\\dmex\\AppData\\Temp\\processhacker-2.10-setup.exe SetupFilePath = PhFormatString( L"%sprocesshacker-%u.%u-setup.exe", tempPathString, UpdateData.MajorVersion, UpdateData.MinorVersion ); // Create output file status = PhCreateFileWin32( &tempFileHandle, SetupFilePath->Buffer, FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_ATTRIBUTE_TEMPORARY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) { LogEvent(hwndDlg, PhFormatString(L"PhCreateFileWin32 failed (%s)", ((PPH_STRING)PHA_DEREFERENCE(PhGetNtMessage(status)))->Buffer)); __leave; } { // Create a user agent string. PPH_STRING phVersion = PhGetPhVersion(); PPH_STRING userAgent = PhConcatStrings2(L"PH Updater v", phVersion->Buffer); // Initialize the wininet library. if (!(hInitialize = InternetOpen( userAgent->Buffer, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 ))) { LogEvent(hwndDlg, PhFormatString(L"Updater: (InitializeConnection) InternetOpen failed (%d)", GetLastError())); PhDereferenceObject(userAgent); PhDereferenceObject(phVersion); __leave; } PhDereferenceObject(userAgent); PhDereferenceObject(phVersion); } // Connect to the server. if (!(hConnection = InternetConnect( hInitialize, L"sourceforge.net", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0))) { LogEvent(hwndDlg, PhFormatString(L"InternetConnect failed (%d)", GetLastError())); __leave; } // Open the HTTP request. if (!(hRequest = HttpOpenRequest( hConnection, NULL, downloadUrlPath->Buffer, NULL, NULL, NULL, INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RESYNCHRONIZE, 0 ))) { LogEvent(hwndDlg, PhFormatString(L"HttpOpenRequest failed (%d)", GetLastError())); __leave; } SetDlgItemText(hwndDlg, IDC_STATUS, L"Connecting"); // Send the HTTP request. if (!HttpSendRequest(hRequest, NULL, 0, NULL, 0)) { LogEvent(hwndDlg, PhFormatString(L"HttpSendRequest failed (%d)", GetLastError())); // Enable the 'Retry' button. Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); SetDlgItemText(hwndDlg, IDC_DOWNLOAD, L"Retry"); // Reset the state and let user retry the download. PhUpdaterState = Download; } else { BYTE hashBuffer[20]; DWORD contentLengthSize = sizeof(DWORD); PH_HASH_CONTEXT hashContext; // Initialize hash algorithm. PhInitializeHash(&hashContext, Sha1HashAlgorithm); if (!HttpQueryInfoW(hRequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &contentLengthSize, 0)) { // No content length...impossible to calculate % complete... // we can read the data, BUT in this instance Sourceforge always returns the content length // so instead we'll exit here instead of downloading the file. LogEvent(hwndDlg, PhFormatString(L"HttpQueryInfo failed (%d)", GetLastError())); __leave; } else { BYTE buffer[PAGE_SIZE]; DWORD bytesRead = 0, startTick = 0; IO_STATUS_BLOCK isb; // Zero the buffer. ZeroMemory(buffer, PAGE_SIZE); // Reset the counters. bytesDownloaded = 0, timeTransferred = 0, LastUpdateTime = 0; IsUpdating = FALSE; // Start the clock. startTick = GetTickCount(); timeTransferred = startTick; // Download the data. while (InternetReadFile(hRequest, buffer, PAGE_SIZE, &bytesRead)) { // If we get zero bytes, the file was uploaded or there was an error. if (bytesRead == 0) break; // If window closed and thread handle was closed, just dispose and exit. // (This also skips error checking/prompts and updating the disposed UI) if (!DownloadThreadHandle) __leave; // Update the hash of bytes we downloaded. PhUpdateHash(&hashContext, buffer, bytesRead); // Write the downloaded bytes to disk. status = NtWriteFile( tempFileHandle, NULL, NULL, NULL, &isb, buffer, bytesRead, NULL, NULL ); if (!NT_SUCCESS(status)) { PPH_STRING message = PhGetNtMessage(status); LogEvent(hwndDlg, PhFormatString(L"NtWriteFile failed (%s)", message->Buffer)); PhDereferenceObject(message); break; } // Check dwBytesRead are the same dwBytesWritten length returned by WriteFile. if (bytesRead != isb.Information) { PPH_STRING message = PhGetNtMessage(status); LogEvent(hwndDlg, PhFormatString(L"NtWriteFile failed (%s)", message->Buffer)); PhDereferenceObject(message); break; } // Update our total bytes downloaded PhAcquireQueuedLockExclusive(&Lock); bytesDownloaded += (DWORD)isb.Information; PhReleaseQueuedLockExclusive(&Lock); AsyncUpdate(); } // Check if we downloaded the entire file. assert(bytesDownloaded == contentLength); // Compute our hash result. if (PhFinalHash(&hashContext, &hashBuffer, 20, NULL)) { // Allocate our hash string, hex the final hash result in our hashBuffer. PPH_STRING hexString = PhBufferToHexString(hashBuffer, 20); if (PhEqualString(hexString, UpdateData.Hash, TRUE)) { // If PH is not elevated, set the UAC shield for the install button as the setup requires elevation. if (!PhElevated) SendMessage(GetDlgItem(hwndDlg, IDC_DOWNLOAD), BCM_SETSHIELD, 0, TRUE); // Set the download result, don't include hash status since it succeeded. //SetDlgItemText(hwndDlg, IDC_STATUS, L"Download Complete"); // Set button text for next action Button_SetText(GetDlgItem(hwndDlg, IDC_DOWNLOAD), L"Install"); // Enable the Install button Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); // Hash succeeded, set state as ready to install. PhUpdaterState = Install; } else { if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_ERROR, 0L); SetDlgItemText(hwndDlg, IDC_STATUS, L"Download complete, SHA1 Hash failed."); // Set button text for next action Button_SetText(GetDlgItem(hwndDlg, IDC_DOWNLOAD), L"Retry"); // Enable the Install button Button_Enable(GetDlgItem(hwndDlg, IDC_DOWNLOAD), TRUE); // Hash failed, reset state to downloading so user can redownload the file. PhUpdaterState = Download; } PhDereferenceObject(hexString); } else { //SetDlgItemText(hwndDlg, IDC_STATUS, L"PhFinalHash failed"); // Show fancy Red progressbar if hash failed on Vista and above. if (WindowsVersion > WINDOWS_XP) SendDlgItemMessage(hwndDlg, IDC_PROGRESS, PBM_SETSTATE, PBST_ERROR, 0L); } } } status = STATUS_SUCCESS; } __finally { if (hInitialize) { InternetCloseHandle(hInitialize); hInitialize = NULL; } if (hConnection) { InternetCloseHandle(hConnection); hConnection = NULL; } if (hRequest) { InternetCloseHandle(hRequest); hRequest = NULL; } if (tempFileHandle) { NtClose(tempFileHandle); tempFileHandle = NULL; } if (downloadUrlPath) { PhDereferenceObject(downloadUrlPath); downloadUrlPath = NULL; } } return status; }
VOID PhSvcHandleConnectionRequest( _In_ PPORT_MESSAGE PortMessage ) { NTSTATUS status; PPHSVC_API_MSG message; PPHSVC_API_MSG64 message64; CLIENT_ID clientId; PPHSVC_CLIENT client; HANDLE portHandle; REMOTE_PORT_VIEW clientView; REMOTE_PORT_VIEW64 clientView64; PREMOTE_PORT_VIEW actualClientView; message = (PPHSVC_API_MSG)PortMessage; message64 = (PPHSVC_API_MSG64)PortMessage; if (PhIsExecutingInWow64()) { clientId.UniqueProcess = (HANDLE)message64->h.ClientId.UniqueProcess; clientId.UniqueThread = (HANDLE)message64->h.ClientId.UniqueThread; } else { PPH_STRING referenceFileName; PPH_STRING remoteFileName; clientId = message->h.ClientId; // Make sure that the remote process is Process Hacker itself and not some other program. referenceFileName = NULL; PhGetProcessImageFileNameByProcessId(NtCurrentProcessId(), &referenceFileName); PH_AUTO(referenceFileName); remoteFileName = NULL; PhGetProcessImageFileNameByProcessId(clientId.UniqueProcess, &remoteFileName); PH_AUTO(remoteFileName); if (!referenceFileName || !remoteFileName || !PhEqualString(referenceFileName, remoteFileName, TRUE)) { NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL); return; } } client = PhSvcCreateClient(&clientId); if (!client) { NtAcceptConnectPort(&portHandle, NULL, PortMessage, FALSE, NULL, NULL); return; } if (PhIsExecutingInWow64()) { message64->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId()); clientView64.Length = sizeof(REMOTE_PORT_VIEW64); clientView64.ViewSize = 0; clientView64.ViewBase = 0; actualClientView = (PREMOTE_PORT_VIEW)&clientView64; } else { message->p.ConnectInfo.ServerProcessId = HandleToUlong(NtCurrentProcessId()); clientView.Length = sizeof(REMOTE_PORT_VIEW); clientView.ViewSize = 0; clientView.ViewBase = NULL; actualClientView = &clientView; } status = NtAcceptConnectPort( &portHandle, client, PortMessage, TRUE, NULL, actualClientView ); if (!NT_SUCCESS(status)) { PhDereferenceObject(client); return; } // IMPORTANT: Since Vista, NtCompleteConnectPort does not do anything and simply returns STATUS_SUCCESS. // We will call it anyway (for completeness), but we need to use an event to ensure that other threads don't try // to process requests before we have finished setting up the client object. client->PortHandle = portHandle; if (PhIsExecutingInWow64()) { client->ClientViewBase = (PVOID)clientView64.ViewBase; client->ClientViewLimit = PTR_ADD_OFFSET(clientView64.ViewBase, clientView64.ViewSize); } else { client->ClientViewBase = clientView.ViewBase; client->ClientViewLimit = PTR_ADD_OFFSET(clientView.ViewBase, clientView.ViewSize); } NtCompleteConnectPort(portHandle); PhSetEvent(&client->ReadyEvent); if (_InterlockedIncrement(&PhSvcApiNumberOfClients) == 1) { NtSetEvent(PhSvcTimeoutCancelEventHandle, NULL); } }
BOOLEAN NvGpuDriverIsWHQL(VOID) { BOOLEAN nvGpuDriverIsWHQL = FALSE; HANDLE keyHandle = NULL; HANDLE keyServiceHandle = NULL; PWSTR deviceInterfaceList = NULL; ULONG deviceInterfaceListLength = 0; PWSTR deviceInterface; PPH_STRING keyPath = NULL; PPH_STRING matchingDeviceIdString; PPH_STRING keyServicePath; NvAPI_LongString nvNameAnsiString = ""; if (!NvAPI_GetDisplayDriverRegistryPath) goto CleanupExit; if (NvAPI_GetDisplayDriverRegistryPath(NvGpuDisplayHandleList->Items[0], nvNameAnsiString) != NVAPI_OK) goto CleanupExit; keyPath = PhConvertMultiByteToUtf16(nvNameAnsiString); if (!NT_SUCCESS(PhOpenKey( &keyHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyPath->sr, 0 ))) { goto CleanupExit; } matchingDeviceIdString = PhQueryRegistryString(keyHandle, L"MatchingDeviceId"); //keySettingsPath = PhConcatStrings2(keyPath->Buffer, L"\\VolatileSettings"); //if (NT_SUCCESS(PhOpenKey( // &keySettingsHandle, // KEY_READ, // PH_KEY_LOCAL_MACHINE, // &keySettingsPath->sr, // 0 // ))) //{ // GUID settingsKey = GUID_DEVINTERFACE_DISPLAY_ADAPTER; // PPH_STRING guidString = PhFormatGuid(&settingsKey); // // ULONG dwType = REG_BINARY; // LONG length = DOS_MAX_PATH_LENGTH; // // if (RegQueryValueEx( // keySettingsHandle, // guidString->Buffer, // 0, // &dwType, // (PBYTE)displayInstancePath, // &length // ) != ERROR_SUCCESS) // { // //__leave; // } // // NtClose(keySettingsHandle); // PhDereferenceObject(guidString); //} if (CM_Get_Device_Interface_List_Size( &deviceInterfaceListLength, (PGUID)&GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, CM_GET_DEVICE_INTERFACE_LIST_PRESENT ) != CR_SUCCESS) { return FALSE; } deviceInterfaceList = PhAllocate(deviceInterfaceListLength * sizeof(WCHAR)); memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR)); if (CM_Get_Device_Interface_List( (PGUID)&GUID_DEVINTERFACE_DISPLAY_ADAPTER, NULL, deviceInterfaceList, deviceInterfaceListLength, CM_GET_DEVICE_INTERFACE_LIST_PRESENT ) != CR_SUCCESS) { PhFree(deviceInterfaceList); return FALSE; } for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += PhCountStringZ(deviceInterface) + 1) { CONFIGRET result; PPH_STRING string; ULONG bufferSize; DEVPROPTYPE devicePropertyType; DEVINST deviceInstanceHandle; ULONG deviceInstanceIdLength = MAX_DEVICE_ID_LEN; WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_Interface_Property( deviceInterface, &DEVPKEY_Device_InstanceId, &devicePropertyType, (PBYTE)deviceInstanceId, &deviceInstanceIdLength, 0 ) != CR_SUCCESS) { continue; } if (CM_Locate_DevNode(&deviceInstanceHandle, deviceInstanceId, CM_LOCATE_DEVNODE_NORMAL)!= CR_SUCCESS) continue; bufferSize = 0x40; string = PhCreateStringEx(NULL, bufferSize); if ((result = CM_Get_DevNode_Property( deviceInstanceHandle, &DEVPKEY_Device_MatchingDeviceId, &devicePropertyType, (PBYTE)string->Buffer, &bufferSize, 0 )) != CR_SUCCESS) { PhDereferenceObject(string); string = PhCreateStringEx(NULL, bufferSize); result = CM_Get_DevNode_Property( deviceInstanceHandle, &DEVPKEY_Device_MatchingDeviceId, &devicePropertyType, (PBYTE)string->Buffer, &bufferSize, 0 ); } if (result != CR_SUCCESS) { PhDereferenceObject(string); continue; } PhTrimToNullTerminatorString(string); if (!PhEqualString(string, matchingDeviceIdString, TRUE)) { PhDereferenceObject(string); continue; } bufferSize = 0x40; PhDereferenceObject(string); string = PhCreateStringEx(NULL, bufferSize); if ((result = CM_Get_DevNode_Property( deviceInstanceHandle, &DEVPKEY_Device_Service, &devicePropertyType, (PBYTE)string->Buffer, &bufferSize, 0 )) != CR_SUCCESS) { PhDereferenceObject(string); string = PhCreateStringEx(NULL, bufferSize); result = CM_Get_DevNode_Property( deviceInstanceHandle, &DEVPKEY_Device_Service, &devicePropertyType, (PBYTE)string->Buffer, &bufferSize, 0 ); } if (result != CR_SUCCESS) { PhDereferenceObject(string); continue; } keyServicePath = PhConcatStrings2(L"System\\CurrentControlSet\\Services\\", string->Buffer); if (NT_SUCCESS(PhOpenKey( &keyServiceHandle, KEY_READ, PH_KEY_LOCAL_MACHINE, &keyServicePath->sr, 0 ))) { PPH_STRING driverNtPathString; PPH_STRING driverDosPathString = NULL; if (driverNtPathString = PhQueryRegistryString(keyServiceHandle, L"ImagePath")) { driverDosPathString = PhGetFileName(driverNtPathString); PhDereferenceObject(driverNtPathString); } if (driverDosPathString) { PPH_STRING fileSignerName = NULL; //PH_MAPPED_IMAGE fileMappedImage; // //if (NT_SUCCESS(PhLoadMappedImage(driverDosPathString->Buffer, NULL, TRUE, &fileMappedImage))) //{ // LARGE_INTEGER time; // SYSTEMTIME systemTime; // PPH_STRING string; // // RtlSecondsSince1970ToTime(fileMappedImage.NtHeaders->FileHeader.TimeDateStamp, &time); // PhLargeIntegerToLocalSystemTime(&systemTime, &time); // // string = PhFormatDateTime(&systemTime); // //SetDlgItemText(hwndDlg, IDC_TIMESTAMP, string->Buffer); // PhDereferenceObject(string); // // PhUnloadMappedImage(&fileMappedImage); //} if (PhVerifyFile(driverDosPathString->Buffer, &fileSignerName) == VrTrusted) { //if (PhEqualString2(fileSignerName, L"Microsoft Windows Hardware Compatibility Publisher", TRUE)) nvGpuDriverIsWHQL = TRUE; } if (fileSignerName) PhDereferenceObject(fileSignerName); PhDereferenceObject(driverDosPathString); } NtClose(keyServiceHandle); } } CleanupExit: if (keyHandle) { NtClose(keyHandle); } if (deviceInterfaceList) { PhFree(deviceInterfaceList); } if (keyPath) { PhDereferenceObject(keyPath); } return nvGpuDriverIsWHQL; }
INT_PTR CALLBACK PhpOptionsSymbolsDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PhpPageInit(hwndDlg); SetDlgItemText(hwndDlg, IDC_DBGHELPPATH, PhaGetStringSetting(L"DbgHelpPath")->Buffer); SetDlgItemText(hwndDlg, IDC_DBGHELPSEARCHPATH, PhaGetStringSetting(L"DbgHelpSearchPath")->Buffer); SetDlgItemCheckForSetting(hwndDlg, IDC_UNDECORATESYMBOLS, L"DbgHelpUndecorate"); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_BROWSE: { static PH_FILETYPE_FILTER filters[] = { { L"dbghelp.dll", L"dbghelp.dll" }, { L"All files (*.*)", L"*.*" } }; PVOID fileDialog; PPH_STRING fileName; fileDialog = PhCreateOpenFileDialog(); PhSetFileDialogFilter(fileDialog, filters, sizeof(filters) / sizeof(PH_FILETYPE_FILTER)); fileName = PH_AUTO(PhGetFileName(PhaGetDlgItemText(hwndDlg, IDC_DBGHELPPATH))); PhSetFileDialogFileName(fileDialog, fileName->Buffer); if (PhShowFileDialog(hwndDlg, fileDialog)) { fileName = PH_AUTO(PhGetFileDialogFileName(fileDialog)); SetDlgItemText(hwndDlg, IDC_DBGHELPPATH, fileName->Buffer); } PhFreeFileDialog(fileDialog); } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_APPLY: { PPH_STRING dbgHelpPath = PhaGetDlgItemText(hwndDlg, IDC_DBGHELPPATH); if (!PhEqualString(dbgHelpPath, PhaGetStringSetting(L"DbgHelpPath"), TRUE)) RestartRequired = TRUE; PhSetStringSetting2(L"DbgHelpPath", &dbgHelpPath->sr); PhSetStringSetting2(L"DbgHelpSearchPath", &(PhaGetDlgItemText(hwndDlg, IDC_DBGHELPSEARCHPATH)->sr)); SetSettingForDlgItemCheck(hwndDlg, IDC_UNDECORATESYMBOLS, L"DbgHelpUndecorate"); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); } return TRUE; } } break; } return FALSE; }
PPH_STRING FindNetworkDeviceInstance( _In_ PPH_STRING DevicePath ) { PPH_STRING deviceInstanceString = NULL; PWSTR deviceInterfaceList; ULONG deviceInterfaceListLength = 0; PWSTR deviceInterface; if (CM_Get_Device_Interface_List_Size( &deviceInterfaceListLength, (PGUID)&GUID_DEVINTERFACE_NET, NULL, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES ) != CR_SUCCESS) { return NULL; } deviceInterfaceList = PhAllocate(deviceInterfaceListLength * sizeof(WCHAR)); memset(deviceInterfaceList, 0, deviceInterfaceListLength * sizeof(WCHAR)); if (CM_Get_Device_Interface_List( (PGUID)&GUID_DEVINTERFACE_NET, NULL, deviceInterfaceList, deviceInterfaceListLength, CM_GET_DEVICE_INTERFACE_LIST_ALL_DEVICES ) != CR_SUCCESS) { PhFree(deviceInterfaceList); return NULL; } for (deviceInterface = deviceInterfaceList; *deviceInterface; deviceInterface += PhCountStringZ(deviceInterface) + 1) { HKEY keyHandle; DEVPROPTYPE devicePropertyType; DEVINST deviceInstanceHandle; ULONG deviceInstanceIdLength = MAX_DEVICE_ID_LEN; WCHAR deviceInstanceId[MAX_DEVICE_ID_LEN + 1] = L""; if (CM_Get_Device_Interface_Property( deviceInterface, &DEVPKEY_Device_InstanceId, &devicePropertyType, (PBYTE)deviceInstanceId, &deviceInstanceIdLength, 0 ) != CR_SUCCESS) { continue; } if (CM_Locate_DevNode( &deviceInstanceHandle, deviceInstanceId, CM_LOCATE_DEVNODE_PHANTOM ) != CR_SUCCESS) { continue; } if (CM_Open_DevInst_Key( deviceInstanceHandle, KEY_QUERY_VALUE, 0, RegDisposition_OpenExisting, &keyHandle, CM_REGISTRY_SOFTWARE ) == CR_SUCCESS) { PPH_STRING deviceGuid; if (deviceGuid = PhQueryRegistryString(keyHandle, L"NetCfgInstanceId")) { if (PhEqualString(deviceGuid, DevicePath, TRUE)) { deviceInstanceString = PhCreateString(deviceInstanceId); PhDereferenceObject(deviceGuid); NtClose(keyHandle); break; } PhDereferenceObject(deviceGuid); } NtClose(keyHandle); } } PhFree(deviceInterfaceList); return deviceInstanceString; }
INT_PTR CALLBACK PhpChoiceDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)lParam; ULONG type; SIZE_T i; HWND comboBoxHandle; HWND checkBoxHandle; RECT checkBoxRect; RECT rect; ULONG diff; SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)context); PhCenterWindow(hwndDlg, GetParent(hwndDlg)); SetWindowText(hwndDlg, context->Title); SetWindowText(GetDlgItem(hwndDlg, IDC_MESSAGE), context->Message); type = context->Flags & PH_CHOICE_DIALOG_TYPE_MASK; // Select the control to show, depending on the type. This is // because it is impossible to change the style of the combo box // after it is created. switch (type) { case PH_CHOICE_DIALOG_USER_CHOICE: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICEUSER); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICEUSER), SW_SHOW); break; case PH_CHOICE_DIALOG_PASSWORD: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICESIMPLE); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICESIMPLE), SW_SHOW); // Disable combo box features since it isn't a combo box. context->SavedChoicesSettingName = NULL; break; case PH_CHOICE_DIALOG_CHOICE: default: comboBoxHandle = GetDlgItem(hwndDlg, IDC_CHOICE); ShowWindow(GetDlgItem(hwndDlg, IDC_CHOICE), SW_SHOW); break; } context->ComboBoxHandle = comboBoxHandle; checkBoxHandle = GetDlgItem(hwndDlg, IDC_OPTION); if (type == PH_CHOICE_DIALOG_PASSWORD) { // Nothing } else if (type == PH_CHOICE_DIALOG_USER_CHOICE && context->SavedChoicesSettingName) { PPH_STRING savedChoices = PhGetStringSetting(context->SavedChoicesSettingName); ULONG_PTR indexOfDelim; PPH_STRING savedChoice; i = 0; // Split the saved choices using the delimiter. while (i < savedChoices->Length / 2) { // BUG BUG BUG - what if the user saves "\s"? indexOfDelim = PhFindStringInString(savedChoices, i, L"\\s"); if (indexOfDelim == -1) indexOfDelim = savedChoices->Length / 2; savedChoice = PhSubstring(savedChoices, i, indexOfDelim - i); if (savedChoice->Length != 0) { PPH_STRING unescaped; unescaped = PhUnescapeStringForDelimiter(savedChoice, '\\'); ComboBox_InsertString(comboBoxHandle, -1, unescaped->Buffer); PhDereferenceObject(unescaped); } PhDereferenceObject(savedChoice); i = indexOfDelim + 2; } PhDereferenceObject(savedChoices); } else { for (i = 0; i < context->NumberOfChoices; i++) { ComboBox_AddString(comboBoxHandle, context->Choices[i]); } context->SavedChoicesSettingName = NULL; // make sure we don't try to save the choices } if (type == PH_CHOICE_DIALOG_PASSWORD) { if (*context->SelectedChoice) SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer); Edit_SetSel(comboBoxHandle, 0, -1); } else if (type == PH_CHOICE_DIALOG_USER_CHOICE || type == PH_CHOICE_DIALOG_CHOICE) { // If we failed to choose a default choice based on what was specified, // select the first one if possible, or set the text directly. if (!(*context->SelectedChoice) || PhSelectComboBoxString( comboBoxHandle, (*context->SelectedChoice)->Buffer, FALSE) == CB_ERR) { if (type == PH_CHOICE_DIALOG_USER_CHOICE && *context->SelectedChoice) { SetWindowText(comboBoxHandle, (*context->SelectedChoice)->Buffer); } else if (type == PH_CHOICE_DIALOG_CHOICE && context->NumberOfChoices != 0) { ComboBox_SetCurSel(comboBoxHandle, 0); } } if (type == PH_CHOICE_DIALOG_USER_CHOICE) ComboBox_SetEditSel(comboBoxHandle, 0, -1); } if (context->Option) { SetWindowText(checkBoxHandle, context->Option); if (context->SelectedOption) Button_SetCheck(checkBoxHandle, *context->SelectedOption ? BST_CHECKED : BST_UNCHECKED); } else { // Hide the check box and move the buttons up. ShowWindow(checkBoxHandle, SW_HIDE); GetWindowRect(checkBoxHandle, &checkBoxRect); MapWindowPoints(NULL, hwndDlg, (POINT *)&checkBoxRect, 2); GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect); MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2); diff = rect.top - checkBoxRect.top; // OK rect.top -= diff; rect.bottom -= diff; SetWindowPos(GetDlgItem(hwndDlg, IDOK), NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); // Cancel GetWindowRect(GetDlgItem(hwndDlg, IDCANCEL), &rect); MapWindowPoints(NULL, hwndDlg, (POINT *)&rect, 2); rect.top -= diff; rect.bottom -= diff; SetWindowPos(GetDlgItem(hwndDlg, IDCANCEL), NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); // Window GetWindowRect(hwndDlg, &rect); rect.bottom -= diff; SetWindowPos(hwndDlg, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER); } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)comboBoxHandle, TRUE); } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { PCHOICE_DIALOG_CONTEXT context = (PCHOICE_DIALOG_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); PPH_STRING selectedChoice; if ((context->Flags & PH_CHOICE_DIALOG_TYPE_MASK) != PH_CHOICE_DIALOG_PASSWORD) { selectedChoice = PH_AUTO(PhGetWindowText(context->ComboBoxHandle)); *context->SelectedChoice = selectedChoice; } else { // Password values are never auto-dereferenced. selectedChoice = PhGetWindowText(context->ComboBoxHandle); *context->SelectedChoice = selectedChoice; } if (context->Option && context->SelectedOption) *context->SelectedOption = Button_GetCheck(GetDlgItem(hwndDlg, IDC_OPTION)) == BST_CHECKED; if (context->SavedChoicesSettingName) { PH_STRING_BUILDER savedChoices; ULONG i; ULONG choicesToSave = PH_CHOICE_DIALOG_SAVED_CHOICES; PPH_STRING choice; PPH_STRING escaped; PhInitializeStringBuilder(&savedChoices, 100); // Push the selected choice to the top, then save the others. if (selectedChoice->Length != 0) { escaped = PhEscapeStringForDelimiter(selectedChoice, '\\'); PhAppendStringBuilder(&savedChoices, &escaped->sr); PhDereferenceObject(escaped); PhAppendStringBuilder2(&savedChoices, L"\\s"); } for (i = 1; i < choicesToSave; i++) { choice = PhGetComboBoxString(context->ComboBoxHandle, i - 1); if (!choice) break; // Don't save the choice if it's the same as the one // entered by the user (since we already saved it above). if (PhEqualString(choice, selectedChoice, FALSE)) { PhDereferenceObject(choice); choicesToSave++; // useless for now, but may be needed in the future continue; } escaped = PhEscapeStringForDelimiter(choice, '\\'); PhAppendStringBuilder(&savedChoices, &escaped->sr); PhDereferenceObject(escaped); PhDereferenceObject(choice); PhAppendStringBuilder2(&savedChoices, L"\\s"); } if (PhEndsWithString2(savedChoices.String, L"\\s", FALSE)) PhRemoveEndStringBuilder(&savedChoices, 2); PhSetStringSetting2(context->SavedChoicesSettingName, &savedChoices.String->sr); PhDeleteStringBuilder(&savedChoices); } EndDialog(hwndDlg, IDOK); } break; } } break; } return FALSE; }
INT_PTR HandleCommonMessages( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam, _In_ HWND ListBox, _In_ PPH_LIST FilterList ) { switch (uMsg) { case WM_INITDIALOG: { SetWindowSubclass(GetDlgItem(hwndDlg, IDC_TEXT), TextBoxSubclassProc, 0, 0); Button_SetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE), BST_CHECKED); FixControlStates(hwndDlg, ListBox); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_LIST: { if (GET_WM_COMMAND_CMD(wParam, lParam) == LBN_SELCHANGE) { ULONG i; i = ListBox_GetCurSel(ListBox); if (i != LB_ERR) { PFILTER_ENTRY entry; entry = FilterList->Items[i]; SetDlgItemText(hwndDlg, IDC_TEXT, entry->Filter->Buffer); Button_SetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE), entry->Type == FilterInclude ? BST_CHECKED : BST_UNCHECKED); Button_SetCheck(GetDlgItem(hwndDlg, IDC_EXCLUDE), entry->Type == FilterExclude ? BST_CHECKED : BST_UNCHECKED); } FixControlStates(hwndDlg, ListBox); } } break; case IDC_ADD: case IDC_TEXT_RETURN: { ULONG i; PPH_STRING string; PFILTER_ENTRY entry = NULL; FILTER_TYPE type; PPH_STRING entryString; string = PhGetWindowText(GetDlgItem(hwndDlg, IDC_TEXT)); if (string->Length == 0) { PhDereferenceObject(string); return FALSE; } for (i = 0; i < FilterList->Count; i++) { entry = FilterList->Items[i]; if (PhEqualString(entry->Filter, string, TRUE)) break; } type = Button_GetCheck(GetDlgItem(hwndDlg, IDC_INCLUDE)) == BST_CHECKED ? FilterInclude : FilterExclude; if (i == FilterList->Count) { // No existing entry, so add a new one. entry = PhAllocate(sizeof(FILTER_ENTRY)); entry->Type = type; entry->Filter = string; PhInsertItemList(FilterList, 0, entry); entryString = FormatFilterEntry(entry); ListBox_InsertString(ListBox, 0, entryString->Buffer); PhDereferenceObject(entryString); ListBox_SetCurSel(ListBox, 0); } else { entry->Type = type; PhDereferenceObject(entry->Filter); entry->Filter = string; ListBox_DeleteString(ListBox, i); entryString = FormatFilterEntry(entry); ListBox_InsertString(ListBox, i, entryString->Buffer); PhDereferenceObject(entryString); ListBox_SetCurSel(ListBox, i); } SendMessage(hwndDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwndDlg, IDC_TEXT), TRUE); Edit_SetSel(GetDlgItem(hwndDlg, IDC_TEXT), 0, -1); FixControlStates(hwndDlg, ListBox); } break; case IDC_REMOVE: { ULONG i; PFILTER_ENTRY entry; i = ListBox_GetCurSel(ListBox); if (i != LB_ERR) { entry = FilterList->Items[i]; FreeFilterEntry(entry); PhRemoveItemList(FilterList, i); ListBox_DeleteString(ListBox, i); if (i >= FilterList->Count) i = FilterList->Count - 1; ListBox_SetCurSel(ListBox, i); FixControlStates(hwndDlg, ListBox); } } break; case IDC_MOVEUP: { ULONG i; PFILTER_ENTRY entry; PPH_STRING entryString; i = ListBox_GetCurSel(ListBox); if (i != LB_ERR && i != 0) { entry = FilterList->Items[i]; PhRemoveItemList(FilterList, i); PhInsertItemList(FilterList, i - 1, entry); ListBox_DeleteString(ListBox, i); entryString = FormatFilterEntry(entry); ListBox_InsertString(ListBox, i - 1, entryString->Buffer); PhDereferenceObject(entryString); i--; ListBox_SetCurSel(ListBox, i); FixControlStates(hwndDlg, ListBox); } } break; case IDC_MOVEDOWN: { ULONG i; PFILTER_ENTRY entry; PPH_STRING entryString; i = ListBox_GetCurSel(ListBox); if (i != LB_ERR && i != FilterList->Count - 1) { entry = FilterList->Items[i]; PhRemoveItemList(FilterList, i); PhInsertItemList(FilterList, i + 1, entry); ListBox_DeleteString(ListBox, i); entryString = FormatFilterEntry(entry); ListBox_InsertString(ListBox, i + 1, entryString->Buffer); PhDereferenceObject(entryString); i++; ListBox_SetCurSel(ListBox, i); FixControlStates(hwndDlg, ListBox); } } break; } } break; } return FALSE; }
INT_PTR CALLBACK WepWindowsPageProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWINDOWS_CONTEXT context; LPPROPSHEETPAGE propSheetPage; PPH_PROCESS_PROPPAGECONTEXT propPageContext; PPH_PROCESS_ITEM processItem; if (PhPropPageDlgProcHeader(hwndDlg, uMsg, lParam, &propSheetPage, &propPageContext, &processItem)) { context = propPageContext->Context; } else { return FALSE; } switch (uMsg) { case WM_INITDIALOG: { context->TreeNewHandle = GetDlgItem(hwndDlg, IDC_LIST); context->SearchBoxHandle = GetDlgItem(hwndDlg, IDC_SEARCHEDIT); PhCreateSearchControl(hwndDlg, context->SearchBoxHandle, L"Search Windows (Ctrl+K)"); WeInitializeWindowTree(hwndDlg, context->TreeNewHandle, &context->TreeContext); PhRegisterDialog(hwndDlg); PhInitializeLayoutManager(&context->LayoutManager, hwndDlg); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_SEARCHEDIT), NULL, PH_ANCHOR_TOP | PH_ANCHOR_RIGHT); PhAddLayoutItem(&context->LayoutManager, GetDlgItem(hwndDlg, IDC_LIST), NULL, PH_ANCHOR_ALL); WepRefreshWindows(context); } break; case WM_SHOWWINDOW: { if (PhBeginPropPageLayout(hwndDlg, propPageContext)) PhEndPropPageLayout(hwndDlg, propPageContext); } break; case WM_DESTROY: { PhDeleteLayoutManager(&context->LayoutManager); PhUnregisterDialog(hwndDlg); WeDeleteWindowTree(&context->TreeContext); WepDeleteWindowSelector(&context->Selector); PhFree(context); } break; case WM_COMMAND: { switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case EN_CHANGE: { PPH_STRING newSearchboxText; if (GET_WM_COMMAND_HWND(wParam, lParam) != context->SearchBoxHandle) break; newSearchboxText = PH_AUTO(PhGetWindowText(context->SearchBoxHandle)); if (!PhEqualString(context->TreeContext.SearchboxText, newSearchboxText, FALSE)) { PhSwapReference(&context->TreeContext.SearchboxText, newSearchboxText); if (!PhIsNullOrEmptyString(context->TreeContext.SearchboxText)) WeExpandAllWindowNodes(&context->TreeContext, TRUE); PhApplyTreeNewFilters(&context->TreeContext.FilterSupport); TreeNew_NodesStructured(context->TreeNewHandle); // PhInvokeCallback(&SearchChangedEvent, SearchboxText); } } break; } switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_REFRESH: WepRefreshWindows(context); break; case ID_SHOWCONTEXTMENU: { PPH_TREENEW_CONTEXT_MENU contextMenuEvent = (PPH_TREENEW_CONTEXT_MENU)lParam; PWE_WINDOW_NODE *windows; ULONG numberOfWindows; PPH_EMENU menu; PPH_EMENU selectedItem; WeGetSelectedWindowNodes( &context->TreeContext, &windows, &numberOfWindows ); if (numberOfWindows != 0) { menu = PhCreateEMenu(); PhLoadResourceEMenuItem(menu, PluginInstance->DllBase, MAKEINTRESOURCE(IDR_WINDOW), 0); PhInsertCopyCellEMenuItem(menu, ID_WINDOW_COPY, context->TreeNewHandle, contextMenuEvent->Column); PhSetFlagsEMenuItem(menu, ID_WINDOW_PROPERTIES, PH_EMENU_DEFAULT, PH_EMENU_DEFAULT); if (numberOfWindows == 1) { WINDOWPLACEMENT placement = { sizeof(placement) }; BYTE alpha; ULONG flags; ULONG i; ULONG id; // State GetWindowPlacement(windows[0]->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MINIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_MAXIMIZE) PhSetFlagsEMenuItem(menu, ID_WINDOW_MAXIMIZE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); else if (placement.showCmd == SW_NORMAL) PhSetFlagsEMenuItem(menu, ID_WINDOW_RESTORE, PH_EMENU_DISABLED, PH_EMENU_DISABLED); // Visible PhSetFlagsEMenuItem(menu, ID_WINDOW_VISIBLE, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_VISIBLE) ? PH_EMENU_CHECKED : 0); // Enabled PhSetFlagsEMenuItem(menu, ID_WINDOW_ENABLED, PH_EMENU_CHECKED, !(GetWindowLong(windows[0]->WindowHandle, GWL_STYLE) & WS_DISABLED) ? PH_EMENU_CHECKED : 0); // Always on Top PhSetFlagsEMenuItem(menu, ID_WINDOW_ALWAYSONTOP, PH_EMENU_CHECKED, (GetWindowLong(windows[0]->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST) ? PH_EMENU_CHECKED : 0); // Opacity if (GetLayeredWindowAttributes(windows[0]->WindowHandle, NULL, &alpha, &flags)) { if (!(flags & LWA_ALPHA)) alpha = 255; } else { alpha = 255; } if (alpha == 255) { id = ID_OPACITY_OPAQUE; } else { id = 0; // Due to integer division, we cannot use simple arithmetic to calculate which menu item to check. for (i = 0; i < 10; i++) { if (alpha == (BYTE)(255 * (i + 1) / 10)) { id = ID_OPACITY_10 + i; break; } } } if (id != 0) { PhSetFlagsEMenuItem(menu, id, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK, PH_EMENU_CHECKED | PH_EMENU_RADIOCHECK); } } else { PhSetFlagsAllEMenuItems(menu, PH_EMENU_DISABLED, PH_EMENU_DISABLED); PhSetFlagsEMenuItem(menu, ID_WINDOW_COPY, PH_EMENU_DISABLED, 0); } selectedItem = PhShowEMenu( menu, hwndDlg, PH_EMENU_SHOW_SEND_COMMAND | PH_EMENU_SHOW_LEFTRIGHT, PH_ALIGN_LEFT | PH_ALIGN_TOP, contextMenuEvent->Location.x, contextMenuEvent->Location.y ); if (selectedItem && selectedItem->Id != -1) { BOOLEAN handled = FALSE; handled = PhHandleCopyCellEMenuItem(selectedItem); } PhDestroyEMenu(menu); } } break; case ID_WINDOW_BRINGTOFRONT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { WINDOWPLACEMENT placement = { sizeof(placement) }; GetWindowPlacement(selectedNode->WindowHandle, &placement); if (placement.showCmd == SW_MINIMIZE) ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); else SetForegroundWindow(selectedNode->WindowHandle); } } break; case ID_WINDOW_RESTORE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_RESTORE); } } break; case ID_WINDOW_MINIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MINIMIZE); } } break; case ID_WINDOW_MAXIMIZE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ShowWindowAsync(selectedNode->WindowHandle, SW_MAXIMIZE); } } break; case ID_WINDOW_CLOSE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { PostMessage(selectedNode->WindowHandle, WM_CLOSE, 0, 0); } } break; case ID_WINDOW_VISIBLE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (IsWindowVisible(selectedNode->WindowHandle)) { selectedNode->WindowVisible = FALSE; ShowWindowAsync(selectedNode->WindowHandle, SW_HIDE); } else { selectedNode->WindowVisible = TRUE; ShowWindowAsync(selectedNode->WindowHandle, SW_SHOW); } PhInvalidateTreeNewNode(&selectedNode->Node, TN_CACHE_COLOR); TreeNew_InvalidateNode(context->TreeNewHandle, &selectedNode->Node); } } break; case ID_WINDOW_ENABLED: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { EnableWindow(selectedNode->WindowHandle, !IsWindowEnabled(selectedNode->WindowHandle)); } } break; case ID_WINDOW_ALWAYSONTOP: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { LOGICAL topMost; topMost = GetWindowLong(selectedNode->WindowHandle, GWL_EXSTYLE) & WS_EX_TOPMOST; SetWindowPos(selectedNode->WindowHandle, topMost ? HWND_NOTOPMOST : HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } } break; case ID_OPACITY_10: case ID_OPACITY_20: case ID_OPACITY_30: case ID_OPACITY_40: case ID_OPACITY_50: case ID_OPACITY_60: case ID_OPACITY_70: case ID_OPACITY_80: case ID_OPACITY_90: case ID_OPACITY_OPAQUE: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { ULONG opacity; opacity = ((ULONG)LOWORD(wParam) - ID_OPACITY_10) + 1; if (opacity == 10) { // Remove the WS_EX_LAYERED bit since it is not needed. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, 0); RedrawWindow(selectedNode->WindowHandle, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); } else { // Add the WS_EX_LAYERED bit so opacity will work. PhSetWindowExStyle(selectedNode->WindowHandle, WS_EX_LAYERED, WS_EX_LAYERED); SetLayeredWindowAttributes(selectedNode->WindowHandle, 0, (BYTE)(255 * opacity / 10), LWA_ALPHA); } } } break; case ID_WINDOW_HIGHLIGHT: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (context->HighlightingWindow) { if (context->HighlightingWindowCount & 1) WeInvertWindowBorder(context->HighlightingWindow); } context->HighlightingWindow = selectedNode->WindowHandle; context->HighlightingWindowCount = 10; SetTimer(hwndDlg, 9, 100, NULL); } } break; case ID_WINDOW_GOTOTHREAD: { PWE_WINDOW_NODE selectedNode; PPH_PROCESS_ITEM processItem; PPH_PROCESS_PROPCONTEXT propContext; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) { if (processItem = PhReferenceProcessItem(selectedNode->ClientId.UniqueProcess)) { if (propContext = PhCreateProcessPropContext(WE_PhMainWndHandle, processItem)) { PhSetSelectThreadIdProcessPropContext(propContext, selectedNode->ClientId.UniqueThread); PhShowProcessProperties(propContext); PhDereferenceObject(propContext); } PhDereferenceObject(processItem); } else { PhShowError(hwndDlg, L"The process does not exist."); } } } break; case ID_WINDOW_PROPERTIES: { PWE_WINDOW_NODE selectedNode; if (selectedNode = WeGetSelectedWindowNode(&context->TreeContext)) WeShowWindowProperties(hwndDlg, selectedNode->WindowHandle); } break; case ID_WINDOW_COPY: { PPH_STRING text; text = PhGetTreeNewText(context->TreeNewHandle, 0); PhSetClipboardString(hwndDlg, &text->sr); PhDereferenceObject(text); } break; } } break; case WM_TIMER: { switch (wParam) { case 9: { WeInvertWindowBorder(context->HighlightingWindow); if (--context->HighlightingWindowCount == 0) KillTimer(hwndDlg, 9); } break; } } break; case WM_SIZE: PhLayoutManagerLayout(&context->LayoutManager); break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_QUERYINITIALFOCUS: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LPARAM)GetDlgItem(hwndDlg, IDC_REFRESH)); return TRUE; } } break; } return FALSE; }
INT_PTR CALLBACK EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
VOID PhModuleProviderUpdate( _In_ PVOID Object ) { PPH_MODULE_PROVIDER moduleProvider = (PPH_MODULE_PROVIDER)Object; PPH_LIST modules; ULONG i; // If we didn't get a handle when we created the provider, // abort (unless this is the System process - in that case // we don't need a handle). if (!moduleProvider->ProcessHandle && moduleProvider->ProcessId != SYSTEM_PROCESS_ID) goto UpdateExit; modules = PhCreateList(20); moduleProvider->RunStatus = PhEnumGenericModules( moduleProvider->ProcessId, moduleProvider->ProcessHandle, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, modules ); // Look for removed modules. { PPH_LIST modulesToRemove = NULL; ULONG enumerationKey = 0; PPH_MODULE_ITEM *moduleItem; while (PhEnumHashtable(moduleProvider->ModuleHashtable, (PVOID *)&moduleItem, &enumerationKey)) { BOOLEAN found = FALSE; // Check if the module still exists. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; if ((*moduleItem)->BaseAddress == module->BaseAddress && PhEqualString((*moduleItem)->FileName, module->FileName, TRUE)) { found = TRUE; break; } } if (!found) { // Raise the module removed event. PhInvokeCallback(&moduleProvider->ModuleRemovedEvent, *moduleItem); if (!modulesToRemove) modulesToRemove = PhCreateList(2); PhAddItemList(modulesToRemove, *moduleItem); } } if (modulesToRemove) { PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); for (i = 0; i < modulesToRemove->Count; i++) { PhpRemoveModuleItem( moduleProvider, (PPH_MODULE_ITEM)modulesToRemove->Items[i] ); } PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhDereferenceObject(modulesToRemove); } } // Go through the queued thread query data. { PSLIST_ENTRY entry; PPH_MODULE_QUERY_DATA data; entry = RtlInterlockedFlushSList(&moduleProvider->QueryListHead); while (entry) { data = CONTAINING_RECORD(entry, PH_MODULE_QUERY_DATA, ListEntry); entry = entry->Next; data->ModuleItem->VerifyResult = data->VerifyResult; data->ModuleItem->VerifySignerName = data->VerifySignerName; data->ModuleItem->JustProcessed = TRUE; PhDereferenceObject(data->ModuleItem); PhFree(data); } } // Look for new modules. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PPH_MODULE_ITEM moduleItem; moduleItem = PhReferenceModuleItem(moduleProvider, module->BaseAddress); if (!moduleItem) { moduleItem = PhCreateModuleItem(); moduleItem->BaseAddress = module->BaseAddress; PhPrintPointer(moduleItem->BaseAddressString, moduleItem->BaseAddress); moduleItem->Size = module->Size; moduleItem->Flags = module->Flags; moduleItem->Type = module->Type; moduleItem->LoadReason = module->LoadReason; moduleItem->LoadCount = module->LoadCount; moduleItem->LoadTime = module->LoadTime; moduleItem->Name = module->Name; PhReferenceObject(moduleItem->Name); moduleItem->FileName = module->FileName; PhReferenceObject(moduleItem->FileName); PhInitializeImageVersionInfo( &moduleItem->VersionInfo, PhGetString(moduleItem->FileName) ); moduleItem->IsFirst = i == 0; // Fix up the load count. If this is not an ordinary DLL or kernel module, set the load count to 0. if (moduleItem->Type != PH_MODULE_TYPE_MODULE && moduleItem->Type != PH_MODULE_TYPE_WOW64_MODULE && moduleItem->Type != PH_MODULE_TYPE_KERNEL_MODULE) { moduleItem->LoadCount = 0; } if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { PH_REMOTE_MAPPED_IMAGE remoteMappedImage; // Note: // On Windows 7 the LDRP_IMAGE_NOT_AT_BASE flag doesn't appear to be used // anymore. Instead we'll check ImageBase in the image headers. We read this in // from the process' memory because: // // 1. It (should be) faster than opening the file and mapping it in, and // 2. It contains the correct original image base relocated by ASLR, if present. moduleItem->Flags &= ~LDRP_IMAGE_NOT_AT_BASE; if (NT_SUCCESS(PhLoadRemoteMappedImage(moduleProvider->ProcessHandle, moduleItem->BaseAddress, &remoteMappedImage))) { moduleItem->ImageTimeDateStamp = remoteMappedImage.NtHeaders->FileHeader.TimeDateStamp; moduleItem->ImageCharacteristics = remoteMappedImage.NtHeaders->FileHeader.Characteristics; if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } else if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } PhUnloadRemoteMappedImage(&remoteMappedImage); } } if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_KERNEL_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { // See if the file has already been verified; if not, queue for verification. moduleItem->VerifyResult = PhVerifyFileCached(moduleItem->FileName, NULL, &moduleItem->VerifySignerName, TRUE); if (moduleItem->VerifyResult == VrUnknown) PhpQueueModuleQuery(moduleProvider, moduleItem); } // Add the module item to the hashtable. PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhAddEntryHashtable(moduleProvider->ModuleHashtable, &moduleItem); PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); // Raise the module added event. PhInvokeCallback(&moduleProvider->ModuleAddedEvent, moduleItem); } else { BOOLEAN modified = FALSE; if (moduleItem->JustProcessed) modified = TRUE; moduleItem->JustProcessed = FALSE; if (modified) PhInvokeCallback(&moduleProvider->ModuleModifiedEvent, moduleItem); PhDereferenceObject(moduleItem); } } // Free the modules list. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PhDereferenceObject(module->Name); PhDereferenceObject(module->FileName); PhFree(module); } PhDereferenceObject(modules); UpdateExit: PhInvokeCallback(&moduleProvider->UpdatedEvent, NULL); }