unsigned CSoftUninstall::RegMonitor() { CRegKey reg; LONG ret = reg.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY); if(ret != ERROR_SUCCESS) return unsigned(-1); CRegKey reg2; ret = reg2.Open(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY); if(ret != ERROR_SUCCESS) return unsigned(-1); CRegKey reg3; if(Is64BitWindows()) { ret = reg3.Open(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall", KEY_NOTIFY | KEY_WOW64_64KEY); if(ret != ERROR_SUCCESS) return unsigned(-1); } HANDLE hEvents[2] = {0}; hEvents[0] = _regMonitorEvent; hEvents[1] = ::CreateEventW(NULL, FALSE, FALSE, NULL); do { ret = reg.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; ret = reg2.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; if(Is64BitWindows()) { ret = reg3.NotifyChangeKeyValue(TRUE, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET, hEvents[1]); if(ret != ERROR_SUCCESS) break; } DWORD res = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); if(res == WAIT_OBJECT_0 + 1) { // 等注册表稳定 ::Sleep(500); // 强制刷新 DataRefresh(TRUE); } else { // 退出 break; } } while(TRUE); ::CloseHandle(hEvents[1]); return 0; }
void CSettings::OnBnClickedCopysymboldlls() { // Attempt to deal with these problems: // https://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/ const wchar_t* fileNames[] = { L"dbghelp.dll", L"symsrv.dll", }; bool bIsWin64 = Is64BitWindows(); bool failed = false; std::wstring third_party = exeDir_ + L"..\\third_party\\"; for (size_t i = 0; i < ARRAYSIZE(fileNames); ++i) { std::wstring source = third_party + fileNames[i]; if (bIsWin64) source = third_party + L"x64\\" + fileNames[i]; std::wstring dest = wptDir_ + fileNames[i]; if (!CopyFile(source.c_str(), dest.c_str(), FALSE)) failed = true; } if (failed) AfxMessageBox(L"Failed to copy dbghelp.dll and symsrv.dll to the WPT directory. Is WPA running?"); else AfxMessageBox(L"Copied dbghelp.dll and symsrv.dll to the WPT directory. If this doesn't help " L"with symbol loading then consider deleting them to restore the previous state."); }
BOOL CSoftUninstall::RubbishRefresh() { if(Is64BitWindows()) return FALSE; if(0 >= _pDB->ExecuteScalar(L"select count(*) from rubbish_list")) { return StartTask(new CSoftRubbishRefreshTask(this)); } else { _pNotify->SoftRubbishEvent(UE_Refresh_Begin, NULL); // 从缓存中获取数据 SoftRubbish2List softRubbish2List; CComPtr<ISQLiteComResultSet3> pRs; HRESULT hr = _pDB->ExecuteQuery(L"select path,type from rubbish", &pRs); if(SUCCEEDED(hr)) { while(!pRs->IsEof()) { softRubbish2List.push_back(SoftRubbish2()); softRubbish2List.back()._data = pRs->GetAsString(L"path"); softRubbish2List.back()._type = (SoftItemAttri)pRs->GetInt(L"type"); pRs->NextRow(); } } CSoftRubbishEnum softRubbishEnum(softRubbish2List); _pNotify->SoftRubbishEvent(UE_Refresh_End, &softRubbishEnum); return TRUE; } }
void CWorkingSetMonitor::SetProcessFilter(const std::wstring& processes, bool bExpensiveWSMonitoring) { // A 32-bit process on 64-bit Windows will not be able to read the // full working set of 64-bit processes, so don't even try. if (Is64BitWindows() && !Is64BitBuild()) return; CSingleLock locker(&processesLock_); if (processes == L"*") { processAll_ = true; } else { processAll_ = false; processes_ = split(processes, ';'); } bExpensiveWSMonitoring_ = bExpensiveWSMonitoring; }
void CSettings::OnBnClickedCopysymboldlls() { // Attempt to deal with these problems: // https://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/ const wchar_t* fileNames[] = { L"dbghelp.dll", L"symsrv.dll", }; bool bIsWin64 = Is64BitWindows(); const std::wstring third_party = exeDir_ + L"..\\third_party\\"; std::vector<std::wstring> wptDirs; if (!wpt81Dir_.empty()) wptDirs.push_back(wpt81Dir_); wptDirs.push_back(wpt10Dir_); // Perform the operation twice, potentially, for WPT 8.1 and WPT 10 for (auto& wptDir : wptDirs) { bool failed = false; for (size_t i = 0; i < ARRAYSIZE(fileNames); ++i) { std::wstring source = third_party + fileNames[i]; if (bIsWin64) source = third_party + L"x64\\" + fileNames[i]; std::wstring dest = wptDir + fileNames[i]; if (!CopyFile(source.c_str(), dest.c_str(), FALSE)) failed = true; } std::wstring message; if (failed) message = stringPrintf(L"Failed to copy dbghelp.dll and symsrv.dll to %s. Is WPA running?", wptDir.c_str()); else message = stringPrintf(L"Copied dbghelp.dll and symsrv.dll to %s. If this doesn't help " L"with symbol loading then consider deleting them to restore the previous state.", wptDir.c_str()); AfxMessageBox(message.c_str()); } }
void GraphicsCaptureSource::AttemptCapture() { //Log(TEXT("attempting to capture..")); if (!bUseHotkey) hwndTarget = FindWindow(strWindowClass, NULL); else { hwndTarget = hwndNextTarget; hwndNextTarget = NULL; } if (hwndTarget) { GetWindowThreadProcessId(hwndTarget, &targetProcessID); if(!targetProcessID) { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; return; } } else { if (!bUseHotkey && !warningID) warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High); bCapturing = false; return; } if(warningID) { API->RemoveStreamInfo(warningID); warningID = 0; } //------------------------------------------- // see if we already hooked the process. if not, inject DLL char pOPStr[12]; mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated for (int i=0; i<11; i++) pOPStr[i] ^= i^1; OPPROC pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr); HANDLE hProcess = (*pOpenProcess)(PROCESS_ALL_ACCESS, FALSE, targetProcessID); if(hProcess) { //------------------------------------------- // load keepalive event hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << UINT(targetProcessID)); //------------------------------------------- hwndCapture = hwndTarget; hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID)); if(hSignalRestart) { SetEvent(hSignalRestart); bCapturing = true; captureWaitCount = 0; } else { BOOL bSameBit = TRUE; if(Is64BitWindows()) { BOOL bCurrentProcessWow64, bTargetProcessWow64; IsWow64Process(GetCurrentProcess(), &bCurrentProcessWow64); IsWow64Process(hProcess, &bTargetProcessWow64); bSameBit = (bCurrentProcessWow64 == bTargetProcessWow64); } if(bSameBit) { String strDLL; DWORD dwDirSize = GetCurrentDirectory(0, NULL); strDLL.SetLength(dwDirSize); GetCurrentDirectory(dwDirSize, strDLL); strDLL << TEXT("\\plugins\\GraphicsCapture\\GraphicsCaptureHook"); BOOL b32bit = TRUE; if(Is64BitWindows()) IsWow64Process(hProcess, &b32bit); if(!b32bit) strDLL << TEXT("64"); strDLL << TEXT(".dll"); if(InjectLibrary(hProcess, strDLL)) { captureWaitCount = 0; bCapturing = true; } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, GetLastError = %u"), GetLastError()); CloseHandle(hProcess); hProcess = NULL; bErrorAcquiring = true; } } else { String strDLLPath; DWORD dwDirSize = GetCurrentDirectory(0, NULL); strDLLPath.SetLength(dwDirSize); GetCurrentDirectory(dwDirSize, strDLLPath); strDLLPath << TEXT("\\plugins\\GraphicsCapture"); BOOL b32bit = TRUE; if(Is64BitWindows()) IsWow64Process(hProcess, &b32bit); String strHelper = strDLLPath; strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe")); String strCommandLine; strCommandLine << TEXT("\"") << strHelper << TEXT("\" ") << UIntString(targetProcessID); //--------------------------------------- PROCESS_INFORMATION pi; STARTUPINFO si; zero(&pi, sizeof(pi)); zero(&si, sizeof(si)); si.cb = sizeof(si); if(CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi)) { int exitCode = 0; WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); if(exitCode == 0) { captureWaitCount = 0; bCapturing = true; } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, error code = %d"), exitCode); bErrorAcquiring = true; } } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Could not create inject helper, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } } } CloseHandle(hProcess); hProcess = NULL; if (!bCapturing) { CloseHandle(hOBSIsAlive); hOBSIsAlive = NULL; } } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: OpenProcess failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } }
// Usually this returns C:\Program Files (x86)\Oculus\Support\oculus-runtime bool GetOVRRuntimePathW(wchar_t runtimePath[MAX_PATH]) { if (GetRegistryStringW(L"Software\\Oculus VR, LLC\\Oculus", L"Base", runtimePath, Is64BitWindows(), false)) { // At this point, runtimePath is usually "C:\Program Files (x86)\Oculus\", so append what we need to it. return (OVR_strlcat(runtimePath, L"Support\\oculus-runtime", MAX_PATH) < MAX_PATH); } runtimePath[0] = 0; return false; }
bool ErrorReport::GetMiscCrashInfo() { // Get crash time m_CrashDateTime = QDateTime::currentDateTime(); m_ProcessArchitecture = ARX_ARCH_NAME; #ifdef HAVE_WINAPI // Open parent process handle HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pCrashInfo->processId); if(hProcess != NULL) { // Get memory usage info PROCESS_MEMORY_COUNTERS meminfo; BOOL bGetMemInfo = GetProcessMemoryInfo(hProcess, &meminfo, sizeof(PROCESS_MEMORY_COUNTERS)); if(bGetMemInfo) m_ProcessMemoryUsage = meminfo.WorkingSetSize; // Determine the period of time the process is working. FILETIME CreationTime, ExitTime, KernelTime, UserTime; BOOL bGetTimes = GetProcessTimes(hProcess, &CreationTime, &ExitTime, &KernelTime, &UserTime); if(bGetTimes) { SYSTEMTIME AppStartTime; FileTimeToSystemTime(&CreationTime, &AppStartTime); SYSTEMTIME CurTime; GetSystemTime(&CurTime); ULONG64 uCurTime = ConvertSystemTimeToULONG64(CurTime); ULONG64 uStartTime = ConvertSystemTimeToULONG64(AppStartTime); // Check that the application works for at least one minute before crash. // This might help to avoid cyclic error report generation when the applciation // crashes on startup. m_RunningTimeSec = (double)(uCurTime-uStartTime)*10E-08; } } else { m_DetailedError = QString("Unable to obtain an handle to the crashed process (Error %1).").arg(QString::number(GetLastError())); return false; } // Get operating system friendly name from registry. char OSNameBuf[256]; if(!GetWindowsVersionName(OSNameBuf, 256)) { m_DetailedError = QString("A failure occured when obtaining Windows version name (Error %1).").arg(QString::number(GetLastError())); return false; } m_OSName = OSNameBuf; // Determine if Windows is 64-bit. m_OSArchitecture = Is64BitWindows() ? ARX_ARCH_NAME_X86_64 : ARX_ARCH_NAME_X86; if(m_pCrashInfo->exceptionCode != 0) { QString exceptionStr = GetExceptionString(m_pCrashInfo->exceptionCode).c_str(); if(!exceptionStr.isEmpty()) { m_ReportDescription += "\nException code:\n "; m_ReportDescription += exceptionStr; m_ReportDescription += "\n"; } } std::string callStack, callstackTop; u32 callstackCrc; bool bCallstack = GetCallStackInfo(hProcess, m_pCrashInfo->threadHandle, &m_pCrashInfo->contextRecord, callStack, callstackTop, callstackCrc); if(!bCallstack) { m_DetailedError = "A failure occured when obtaining information regarding the callstack."; return false; } m_ReportUniqueID = QString("[%1]").arg(QString::number(callstackCrc, 16).toUpper()); m_ReportDescription = m_pCrashInfo->detailedCrashInfo; m_ReportDescription += "\nCallstack:\n"; m_ReportDescription += callStack.c_str(); m_ReportTitle = QString("%1 %2").arg(m_ReportUniqueID, callstackTop.c_str()); QString registers(GetRegisters(&m_pCrashInfo->contextRecord).c_str()); if(!registers.isEmpty()) { m_ReportDescription += "\nRegisters:\n"; m_ReportDescription += registers; } CloseHandle(hProcess); m_ReportDescriptionText = m_ReportDescription; #else // !HAVE_WINAPI getResourceUsage(m_pCrashInfo->processId, m_ProcessMemoryUsage, m_RunningTimeSec); #ifdef HAVE_UNAME struct utsname buf; if(uname(&buf) == 0) { m_OSName = QString(buf.sysname) + " " + buf.release; m_OSArchitecture = buf.machine; } #endif m_OSDistribution = getLinuxDistribution(); #endif // !HAVE_WINAPI return true; }
BOOL CSettings::OnInitDialog() { CDialogEx::OnInitDialog(); SetDlgItemText(IDC_HEAPEXE, heapTracingExes_.c_str()); CheckDlgButton(IDC_CHROMEDEVELOPER, bChromeDeveloper_); CheckDlgButton(IDC_AUTOVIEWTRACES, bAutoViewTraces_); CheckDlgButton(IDC_HEAPSTACKS, bHeapStacks_); CheckDlgButton(IDC_VIRTUALALLOCSTACKS, bVirtualAllocStacks_); btExtraProviders_.EnableWindow(FALSE); btExtraStackwalks_.EnableWindow(FALSE); btBufferSizes_.EnableWindow(FALSE); // A 32-bit process on 64-bit Windows will not be able to read the // full working set of 64-bit processes, so don't even try. if (Is64BitWindows() && !Is64BitBuild()) btWSMonitoredProcesses_.EnableWindow(FALSE); else SetDlgItemText(IDC_WSMONITOREDPROCESSES, WSMonitoredProcesses_.c_str()); CheckDlgButton(IDC_EXPENSIVEWS, bExpensiveWSMonitoring_); if (toolTip_.Create(this)) { toolTip_.SetMaxTipWidth(400); toolTip_.Activate(TRUE); toolTip_.AddTool(&btHeapTracingExe_, L"Specify the file names of the exes to be heap traced, " L"separated by semi-colons. " L"Enter just the file parts (with the .exe extension) not a full path. For example, " L"'chrome.exe;notepad.exe'. This is for use with the heap-tracing-to-file mode."); toolTip_.AddTool(&btCopyStartupProfile_, L"Copies startup.wpaProfile files for WPA 8.1 and " L"10 to the appropriate destinations so that the next time WPA starts up it will have " L"reasonable analysis defaults."); toolTip_.AddTool(&btCopySymbolDLLs_, L"Copy dbghelp.dll and symsrv.dll to the xperf directory to " L"try to resolve slow or failed symbol loading in WPA. See " L"https://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/ " L"for details."); toolTip_.AddTool(&btChromeDeveloper_, L"Check this to enable Chrome specific behavior such as " L"setting the Chrome symbol server path, and preprocessing of Chrome symbols and " L"traces."); toolTip_.AddTool(&btAutoViewTraces_, L"Check this to have UIforETW launch the trace viewer " L"immediately after a trace is recorded."); toolTip_.AddTool(&btHeapStacks_, L"Check this to record call stacks on HeapAlloc, HeapRealloc, " L"and similar calls, when doing heap traces."); toolTip_.AddTool(&btWSMonitoredProcesses_, L"Names of processes whose working sets will be " L"monitored, separated by semi-colons. An empty string means no monitoring. A '*' means " L"that all processes will be monitored. For instance 'chrome.exe;notepad.exe'"); toolTip_.AddTool(&btExpensiveWSMonitoring_, L"Check this to have private working set and PSS " L"(proportional set size) calculated for monitored processes. This may consume " L"dozens or hundreds of ms each time. Without this checked only full working " L"set is calculated, which is cheap."); toolTip_.AddTool(&btVirtualAllocStacks_, L"Check this to record call stacks on VirtualAlloc on all " L"traces instead of just heap traces."); toolTip_.AddTool(&btChromeCategories_, L"Check the chrome tracing categories that you want Chrome " L"to emit ETW events for. This requires running Chrome version 45 or later, with " L"--trace-export-events-to-etw on the command-line."); } // Initialize the list of check boxes with all of the Chrome categories which // we can enable individually. btChromeCategories_.SetCheckStyle(BS_AUTOCHECKBOX); int index = 0; for (auto category : filtered_event_group_names) { btChromeCategories_.AddString(category); btChromeCategories_.SetCheck(index, (chromeKeywords_ & (1LL << index)) != 0); ++index; } // Manually add the two special Chrome category options. btChromeCategories_.AddString(other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & other_events_keyword_bit) != 0); ++index; btChromeCategories_.AddString(disabled_other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & disabled_other_events_keyword_bit) != 0); return TRUE; // return TRUE unless you set the focus to a control }
////////////////////////////////////////////////////////////////////////// // Load DLL and UnloadDLL functions // Manages 32 and 64-bit system, when running a 32-bit app BOOL CKLL::LoadDLL(char* sKeyboardDll ) { std::cout << "64bit\n"; //Unload if loaded... if(hHandle) this->UnloadDLL(); //Load the dll as usual //TRACE(L"Loading Keyboard DLL %ws\n", sKeyboardDll); hHandle = LoadLibraryA(sKeyboardDll); if (!hHandle) { //AfxMessageBox(L"Failed to load dll " + sKeyboardDll); this->UnloadDLL(); return FALSE; } //Get the Keyboard import function pfnKbdLayerDescriptor = (PFN_KBDLAYERDESCRIPTOR)GetProcAddress(hHandle, "KbdLayerDescriptor"); //Return if error if(!pfnKbdLayerDescriptor) { //AfxMessageBox(L"Could not load kbdLayerDescriptor, is it a real keyboard layout file?"); this->UnloadDLL(); return FALSE; } //Get the keyboard descriptor export and set table if(!Is64BitWindows()) //32-bit { //Init the tables KbdTables = (PKBDTABLES)pfnKbdLayerDescriptor(); //If not set, unload if(!KbdTables) { this->UnloadDLL(); return FALSE; } //Clear, then fill the array this->ClearVKChar(); this->Fill32(); } else //64-bit { //Init the tables KbdTables64 = (PKBDTABLES64)pfnKbdLayerDescriptor(); //If not set, unload if(!KbdTables64) { this->UnloadDLL(); return FALSE; } //Clear, then fill the array this->ClearVKChar(); this->Fill64(); } return TRUE; }
void RefreshWindowList(HWND hwndCombobox, ConfigDialogData &configData) { SendMessage(hwndCombobox, CB_RESETCONTENT, 0, 0); configData.ClearData(); BOOL bWindows64bit = Is64BitWindows(); BOOL bCurrentProcessIsWow64 = FALSE; IsWow64Process(GetCurrentProcess(), &bCurrentProcessIsWow64); HWND hwndCurrent = GetWindow(GetDesktopWindow(), GW_CHILD); do { if(IsWindowVisible(hwndCurrent)) { RECT clientRect; GetClientRect(hwndCurrent, &clientRect); HWND hwndParent = GetParent(hwndCurrent); DWORD exStyles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_EXSTYLE); DWORD styles = (DWORD)GetWindowLongPtr(hwndCurrent, GWL_STYLE); if( (exStyles & WS_EX_TOOLWINDOW) == 0 && (styles & WS_CHILD) == 0 /*&& hwndParent == NULL*/) { String strWindowName; strWindowName.SetLength(GetWindowTextLength(hwndCurrent)); GetWindowText(hwndCurrent, strWindowName, strWindowName.Length()+1); bool b64bit = false; //------- DWORD processID; GetWindowThreadProcessId(hwndCurrent, &processID); if(processID == GetCurrentProcessId()) continue; TCHAR fileName[MAX_PATH+1]; scpy(fileName, TEXT("unknown")); HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, processID); if(hProcess) { BOOL bTargetProcessIsWow64 = FALSE; IsWow64Process(hProcess, &bTargetProcessIsWow64); DWORD dwSize = MAX_PATH; QueryFullProcessImageName(hProcess, 0, fileName, &dwSize); StringList moduleList; OSGetLoadedModuleList(hProcess, moduleList); CloseHandle(hProcess); //todo: remove later if(bCurrentProcessIsWow64 != bTargetProcessIsWow64) { configData.opposingBitWindows << strWindowName; continue; } BOOL bFoundModule = FALSE; for(UINT i=0; i<moduleList.Num(); i++) { CTSTR moduleName = moduleList[i]; if (!scmp(moduleName, TEXT("d3d9.dll")) || !scmp(moduleName, TEXT("d3d10.dll")) || !scmp(moduleName, TEXT("d3d10_1.dll")) || !scmp(moduleName, TEXT("d3d11.dll")) || !scmp(moduleName, TEXT("opengl32.dll"))) { bFoundModule = true; break; } } if (!bFoundModule) continue; b64bit = (bWindows64bit && !bTargetProcessIsWow64); } else { hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processID); if(hProcess) { BOOL bTargetProcessIsWow64 = FALSE; IsWow64Process(hProcess, &bTargetProcessIsWow64); if(bCurrentProcessIsWow64 != bTargetProcessIsWow64) configData.opposingBitWindows << strWindowName; configData.adminWindows << strWindowName; CloseHandle(hProcess); } continue; } //------- String strFileName = fileName; strFileName.FindReplace(TEXT("\\"), TEXT("/")); String strText; strText << TEXT("[") << GetPathFileName(strFileName); strText << (b64bit ? TEXT("*64") : TEXT("*32")); strText << TEXT("]: ") << strWindowName; int id = (int)SendMessage(hwndCombobox, CB_ADDSTRING, 0, (LPARAM)strText.Array()); SendMessage(hwndCombobox, CB_SETITEMDATA, id, (LPARAM)hwndCurrent); String strClassName; strClassName.SetLength(256); GetClassName(hwndCurrent, strClassName.Array(), 255); strClassName.SetLength(slen(strClassName)); WindowInfo &info = *configData.windowData.CreateNew(); info.strClass = strClassName; info.b64bit = b64bit; info.bRequiresAdmin = false; //todo: add later } } } while (hwndCurrent = GetNextWindow(hwndCurrent, GW_HWNDNEXT)); }
BOOL CSettings::OnInitDialog() { CDialog::OnInitDialog(); SetDlgItemText(IDC_HEAPEXE, heapTracingExes_.c_str()); CheckDlgButton(IDC_CHROMEDEVELOPER, bChromeDeveloper_); CheckDlgButton(IDC_AUTOVIEWTRACES, bAutoViewTraces_); CheckDlgButton(IDC_HEAPSTACKS, bHeapStacks_); CheckDlgButton(IDC_VIRTUALALLOCSTACKS, bVirtualAllocStacks_); CheckDlgButton(IDC_CHECKFORNEWVERSIONS, bVersionChecks_); btBufferSizes_.EnableWindow(FALSE); if (IsWindows8Point1OrGreater()) { // The working set monitoring is not needed on Windows 8.1 and above because // of the Microsoft-Windows-Kernel-Memory provider. btWSMonitoredProcesses_.EnableWindow(FALSE); btExpensiveWSMonitoring_.EnableWindow(FALSE); GetDlgItem(IDC_WS_MONITOR_STATIC)->EnableWindow(FALSE); } else { // A 32-bit process on 64-bit Windows will not be able to read the // full working set of 64-bit processes, so don't even try. if (Is64BitWindows() && !Is64BitBuild()) btWSMonitoredProcesses_.EnableWindow(FALSE); else SetDlgItemText(IDC_WSMONITOREDPROCESSES, WSMonitoredProcesses_.c_str()); CheckDlgButton(IDC_EXPENSIVEWS, bExpensiveWSMonitoring_); } btExtraKernelFlags_.SetWindowTextW(extraKernelFlags_.c_str()); btExtraStackwalks_.SetWindowTextW(extraKernelStacks_.c_str()); if (toolTip_.Create(this)) { toolTip_.SetMaxTipWidth(400); toolTip_.Activate(TRUE); toolTip_.AddTool(&btHeapTracingExe_, L"Specify the file names of the exes to be heap traced, " L"separated by semi-colons. " L"Enter just the file parts (with the .exe extension) not a full path. For example, " L"'chrome.exe;notepad.exe'. This is for use with the heap-tracing-to-file mode."); toolTip_.AddTool(&btExtraKernelFlags_, L"Extra kernel flags, separated by '+', such as " L"\"REGISTRY+PERF_COUNTER\". See \"xperf -providers k\" for the full list. " L"Note that incorrect kernel flags will cause tracing to fail to start."); toolTip_.AddTool(&btExtraStackwalks_, L"List of extra stacks to collect from the kernel " L"kernel provider. For example, \"DiskReadInit+DiskWriteInit+DiskFlushInit\". " L"Run \"xperf -help stackwalk\" to see the full list. Note that incorrect stack " L"walk flags will cause tracing to fail to start. Note also that stack walk flags " L"are ignored if the corresponding kernel flag is not enabled."); toolTip_.AddTool(&btWSMonitoredProcesses_, L"Names of processes whose working sets will be " L"monitored, separated by semi-colons. An empty string means no monitoring. A '*' means " L"that all processes will be monitored. For instance 'chrome.exe;notepad.exe'"); toolTip_.AddTool(&btExpensiveWSMonitoring_, L"Check this to have private working set and PSS " L"(proportional set size) calculated for monitored processes. This may consume " L"dozens or hundreds of ms each time. Without this checked only full working " L"set is calculated, which is cheap."); toolTip_.AddTool(&btCopyStartupProfile_, L"Copies startup.wpaProfile files for WPA 8.1 and " L"10 to the appropriate destinations so that the next time WPA starts up it will have " L"reasonable analysis defaults."); toolTip_.AddTool(&btCopySymbolDLLs_, L"Copy dbghelp.dll and symsrv.dll to the xperf directory to " L"try to resolve slow or failed symbol loading in WPA. See " L"https://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/ " L"for details."); toolTip_.AddTool(&btChromeDeveloper_, L"Check this to enable Chrome specific behavior such as " L"setting the Chrome symbol server path, and preprocessing of Chrome symbols and " L"traces."); toolTip_.AddTool(&btAutoViewTraces_, L"Check this to have UIforETW launch the trace viewer " L"immediately after a trace is recorded."); toolTip_.AddTool(&btHeapStacks_, L"Check this to record call stacks on HeapAlloc, HeapRealloc, " L"and similar calls, when doing heap traces."); toolTip_.AddTool(&btVirtualAllocStacks_, L"Check this to record call stacks on VirtualAlloc on all " L"traces instead of just heap traces."); toolTip_.AddTool(&btVersionChecks_, L"Check this to have UIforETW check for new versions at startup."); toolTip_.AddTool(&btChromeCategories_, L"Check the chrome tracing categories that you want Chrome " L"to emit ETW events for. This requires running Chrome version 46 or later, and " L"using chrome://flags/ to \"Enable exporting of tracing events to ETW\" - search for " L"trace-export on the chrome://flags/ page."); } // Initialize the list of check boxes with all of the Chrome categories which // we can enable individually. btChromeCategories_.SetCheckStyle(BS_AUTOCHECKBOX); int index = 0; for (auto category : filtered_event_group_names) { btChromeCategories_.AddString(category); btChromeCategories_.SetCheck(index, (chromeKeywords_ & (1LL << index)) != 0); ++index; } // Manually add the two special Chrome category options. btChromeCategories_.AddString(other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & other_events_keyword_bit) != 0); ++index; btChromeCategories_.AddString(disabled_other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & disabled_other_events_keyword_bit) != 0); return TRUE; // return TRUE unless you set the focus to a control }
void GraphicsCaptureSource::AttemptCapture() { OSDebugOut(TEXT("attempting to capture..\n")); if (scmpi(strWindowClass, L"dwm") == 0) { hwndTarget = FindWindow(strWindowClass, NULL); } else { FindWindowData fwd; //FIXME: duplicated code, but we need OpenProcess here char pOPStr[12]; mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated for (int i = 0; i<11; i++) pOPStr[i] ^= i ^ 1; fwd.pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr); fwd.classname = strWindowClass; fwd.exename = strExecutable; fwd.hwnd = nullptr; EnumWindows(GraphicsCaptureFindWindow, (LPARAM)&fwd); hwndTarget = fwd.hwnd; } // use foregroundwindow as fallback (should be NULL if not using hotkey capture) if (!hwndTarget) hwndTarget = hwndNextTarget; hwndNextTarget = nullptr; OSDebugOut(L"Window: %s: ", strWindowClass.Array()); if (hwndTarget) { OSDebugOut(L"Valid window\n"); targetThreadID = GetWindowThreadProcessId(hwndTarget, &targetProcessID); if (!targetThreadID || !targetProcessID) { AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; return; } } else { OSDebugOut(L"Bad window\n"); if (!bUseHotkey && !warningID) { //Log(TEXT("GraphicsCaptureSource::AttemptCapture: Window '%s' [%s] not found."), strWindowClass.Array(), strExecutable.Array()); //warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High); } bCapturing = false; return; } if (injectHelperProcess && WaitForSingleObject(injectHelperProcess, 0) == WAIT_TIMEOUT) return; if(warningID) { //API->RemoveStreamInfo(warningID); warningID = 0; } //------------------------------------------- // see if we already hooked the process. if not, inject DLL char pOPStr[12]; mcpy(pOPStr, "NpflUvhel{x", 12); //OpenProcess obfuscated for (int i=0; i<11; i++) pOPStr[i] ^= i^1; OPPROC pOpenProcess = (OPPROC)GetProcAddress(GetModuleHandle(TEXT("KERNEL32")), pOPStr); DWORD permission = useSafeHook ? (PROCESS_QUERY_INFORMATION | PROCESS_VM_READ) : (PROCESS_ALL_ACCESS); HANDLE hProcess = (*pOpenProcess)(permission, FALSE, targetProcessID); if(hProcess) { DWORD dwSize = MAX_PATH; wchar_t processName[MAX_PATH]; memset(processName, 0, sizeof(processName)); QueryFullProcessImageName(hProcess, 0, processName, &dwSize); if (dwSize != 0 && scmpi(processName, lastProcessName) != 0) { if (processName[0]) { wchar_t *fileName = srchr(processName, '\\'); Log(L"Trying to hook process: %s", (fileName ? fileName+1 : processName)); } scpy_n(lastProcessName, processName, MAX_PATH-1); } //------------------------------------------- // load keepalive event hOBSIsAlive = CreateEvent(NULL, FALSE, FALSE, String() << OBS_KEEPALIVE_EVENT << UINT(targetProcessID)); //------------------------------------------- hwndCapture = hwndTarget; hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << UINT(targetProcessID)); if(hSignalRestart) { OSDebugOut(L"Setting signal for process ID %u\n", targetProcessID); SetEvent(hSignalRestart); bCapturing = true; captureWaitCount = 0; } else { BOOL bSameBit = TRUE; BOOL b32bit = TRUE; if (Is64BitWindows()) { BOOL bCurrentProcessWow64, bTargetProcessWow64; IsWow64Process(GetCurrentProcess(), &bCurrentProcessWow64); IsWow64Process(hProcess, &bTargetProcessWow64); bSameBit = (bCurrentProcessWow64 == bTargetProcessWow64); } if(Is64BitWindows()) IsWow64Process(hProcess, &b32bit); //verify the hook DLL is accessible String strDLL; DWORD dwDirSize = GetCurrentDirectory(0, NULL); strDLL.SetLength(dwDirSize); GetCurrentDirectory(dwDirSize, strDLL); strDLL << TEXT("\\plugins\\GraphicsCapture\\GraphicsCaptureHook"); if (!b32bit) strDLL << TEXT("64"); strDLL << TEXT(".dll"); if (!CheckFileIntegrity(strDLL.Array())) { OSDebugOut(L"Error acquiring\n"); bErrorAcquiring = true; } else { if (bSameBit && !useSafeHook) { if (InjectLibrary(hProcess, strDLL)) { captureWaitCount = 0; OSDebugOut(L"Inject successful\n"); bCapturing = true; } else { AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Failed to inject library, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } } else { String strDLLPath; DWORD dwDirSize = GetCurrentDirectory(0, NULL); strDLLPath.SetLength(dwDirSize); GetCurrentDirectory(dwDirSize, strDLLPath); strDLLPath << TEXT("\\plugins\\GraphicsCapture"); String strHelper = strDLLPath; strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe")); if (!CheckFileIntegrity(strHelper.Array())) { bErrorAcquiring = true; } else { String strCommandLine; strCommandLine << TEXT("\"") << strHelper << TEXT("\" "); if (useSafeHook) strCommandLine << UIntString(targetThreadID) << " 1"; else strCommandLine << UIntString(targetProcessID) << " 0"; //--------------------------------------- PROCESS_INFORMATION pi; STARTUPINFO si; zero(&pi, sizeof(pi)); zero(&si, sizeof(si)); si.cb = sizeof(si); if (CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi)) { int exitCode = 0; CloseHandle(pi.hThread); if (!useSafeHook) { WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode); CloseHandle(pi.hProcess); } else { injectHelperProcess = pi.hProcess; } if (exitCode == 0) { captureWaitCount = 0; bCapturing = true; } else { AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Failed to inject library, error code = %d"), exitCode); bErrorAcquiring = true; } } else { AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: Could not create inject helper, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } } } } } //save a copy of the process handle which we injected into, this lets us check for process exit in Tick() if (!hTargetProcess) { if (!DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hTargetProcess, 0, FALSE, DUPLICATE_SAME_ACCESS)) { Log(TEXT("Warning: Couldn't DuplicateHandle, %d"), GetLastError()); } } CloseHandle(hProcess); if (!bCapturing) { CloseHandle(hOBSIsAlive); hOBSIsAlive = NULL; } } else { AppWarning(TEXT("GraphicsCaptureSource::AttemptCapture: OpenProcess failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } }
void GraphicsCaptureSource::AttemptCapture() { hwndTarget = FindWindow(strWindowClass, NULL); if(hwndTarget) { GetWindowThreadProcessId(hwndTarget, &targetProcessID); if(!targetProcessID) { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: GetWindowThreadProcessId failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; return; } } else { if(!warningID) warningID = API->AddStreamInfo(Str("Sources.SoftwareCaptureSource.WindowNotFound"), StreamInfoPriority_High); bCapturing = false; return; } if(warningID) { API->RemoveStreamInfo(warningID); warningID = 0; } //------------------------------------------- // see if we already hooked the process. if not, inject DLL HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcessID); if(hProcess) { hwndCapture = hwndTarget; hSignalRestart = OpenEvent(EVENT_ALL_ACCESS, FALSE, String() << RESTART_CAPTURE_EVENT << int(targetProcessID)); if(hSignalRestart) { SetEvent(hSignalRestart); bCapturing = true; captureWaitCount = 0; } else { String strDLLPath; DWORD dwDirSize = GetCurrentDirectory(0, NULL); strDLLPath.SetLength(dwDirSize); GetCurrentDirectory(dwDirSize, strDLLPath); strDLLPath << TEXT("\\plugins\\GraphicsCapture"); BOOL b32bit = TRUE; if(Is64BitWindows()) IsWow64Process(hProcess, &b32bit); String strHelper = strDLLPath; strHelper << ((b32bit) ? TEXT("\\injectHelper.exe") : TEXT("\\injectHelper64.exe")); String strCommandLine; strCommandLine << TEXT("\"") << strHelper << TEXT("\" ") << UIntString(targetProcessID); //--------------------------------------- PROCESS_INFORMATION pi; STARTUPINFO si; zero(&pi, sizeof(pi)); zero(&si, sizeof(si)); si.cb = sizeof(si); if(CreateProcess(strHelper, strCommandLine, NULL, NULL, FALSE, 0, NULL, strDLLPath, &si, &pi)) { int exitCode = 0; WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, (DWORD*)&exitCode); CloseHandle(pi.hThread); CloseHandle(pi.hProcess); if(exitCode == 0) { captureWaitCount = 0; bCapturing = true; } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Failed to inject library, error code = %d"), exitCode); bErrorAcquiring = true; } } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: Could not create inject helper, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } } CloseHandle(hProcess); hProcess = NULL; } else { AppWarning(TEXT("GraphicsCaptureSource::BeginScene: OpenProcess failed, GetLastError = %u"), GetLastError()); bErrorAcquiring = true; } }
BOOL CSettings::OnInitDialog() { CDialog::OnInitDialog(); SetDlgItemText(IDC_HEAPEXE, heapTracingExes_.c_str()); CheckDlgButton(IDC_USE_OTHER_KERNEL_LOGGER, bUseOtherKernelLogger_); CheckDlgButton(IDC_BACKGROUND_MONITORING, bBackgroundTracing_); CheckDlgButton(IDC_CHROMEDEVELOPER, bChromeDeveloper_); CheckDlgButton(IDC_IDENTIFY_CHROME_CPU, bIdentifyChromeProcessesCPU_); CheckDlgButton(IDC_AUTOVIEWTRACES, bAutoViewTraces_); CheckDlgButton(IDC_RECORD_PRE_TRACE, bRecordPreTrace_); CheckDlgButton(IDC_HEAPSTACKS, bHeapStacks_); CheckDlgButton(IDC_VIRTUALALLOCSTACKS, bVirtualAllocStacks_); CheckDlgButton(IDC_CHECKFORNEWVERSIONS, bVersionChecks_); btIdentifyChromeProcessesCPU_.EnableWindow(bChromeDeveloper_); if (IsWindows8Point1OrGreater()) { // The working set monitoring is not needed on Windows 8.1 and above because // of the Microsoft-Windows-Kernel-Memory provider. btWSMonitoredProcesses_.EnableWindow(FALSE); btExpensiveWSMonitoring_.EnableWindow(FALSE); GetDlgItem(IDC_WS_MONITOR_STATIC)->EnableWindow(FALSE); } else { // A 32-bit process on 64-bit Windows will not be able to read the // full working set of 64-bit processes, so don't even try. if (Is64BitWindows() && !Is64BitBuild()) btWSMonitoredProcesses_.EnableWindow(FALSE); else SetDlgItemText(IDC_WSMONITOREDPROCESSES, WSMonitoredProcesses_.c_str()); CheckDlgButton(IDC_EXPENSIVEWS, bExpensiveWSMonitoring_); } btExtraKernelFlags_.SetWindowTextW(extraKernelFlags_.c_str()); btExtraStackwalks_.SetWindowTextW(extraKernelStacks_.c_str()); btExtraUserProviders_.SetWindowTextW(extraUserProviders_.c_str()); btPerfCounters_.SetWindowTextW(perfCounters_.c_str()); if (toolTip_.Create(this)) { toolTip_.SetMaxTipWidth(400); toolTip_.Activate(TRUE); toolTip_.AddTool(&btHeapTracingExe_, L"Specify which processes to heap trace when using " L"heap-tracing-to-file mode. Three different methods can be used to specify the processes:\n" L"1) A semi-colon separated list of process names, such as 'chrome.exe;notepad.exe'. " L"The processes must be launched after this is set and heap-tracing-to-file is selected.\n" L"2) A semi-colon separated list of process IDs (PIDs) - maximum of two - such as '1234;5678'.\n" L"3) A fully specified path to an executable that will be launched by ETW when heap tracing is " L"started."); toolTip_.AddTool(&btExtraKernelFlags_, L"Extra kernel flags, separated by '+', such as " L"\"REGISTRY+PERF_COUNTER\". See \"xperf -providers k\" for the full list. " L"Note that incorrect kernel flags will cause tracing to fail to start."); toolTip_.AddTool(&btExtraStackwalks_, L"List of extra stacks to collect from the kernel " L"kernel provider. For example, \n\"DiskReadInit+DiskWriteInit+DiskFlushInit\". " L"Run \"xperf -help stackwalk\" to see the full list. Note that incorrect stack " L"walk flags will cause tracing to fail to start. Note also that stack walk flags " L"are ignored if the corresponding kernel flag is not enabled."); toolTip_.AddTool(&btExtraUserProviders_, L"Extra user providers, separated by '+', such as " L"\n\"Microsoft-Windows-Audio+Microsoft-Windows-HttpLog\". See \"xperf -providers\" " L"for the full list. " L"TraceLogging and EventSource providers must be prefixed by '*'. " L"Note that incorrect user providers will cause tracing to fail to start."); toolTip_.AddTool(&btPerfCounters_, L"Arbitrary performance counters to be logged occasionally."); toolTip_.AddTool(&btWSMonitoredProcesses_, L"Names of processes whose working sets will be " L"monitored, separated by semi-colons. An empty string means no monitoring. A '*' means " L"that all processes will be monitored. For instance 'chrome.exe;notepad.exe'"); toolTip_.AddTool(&btExpensiveWSMonitoring_, L"Check this to have private working set and PSS " L"(proportional set size) calculated for monitored processes. This may consume " L"dozens or hundreds of ms each time. Without this checked only full working " L"set is calculated, which is cheap."); toolTip_.AddTool(&btCopyStartupProfile_, L"Copies startup.wpaProfile files for WPA 8.1 and " L"10 to the appropriate destinations so that the next time WPA starts up it will have " L"reasonable analysis defaults."); toolTip_.AddTool(&btUseOtherKernelLogger_, L"Check this to have UIforETW use the alternate kernel " L"logger. This is needed on some machines where the main kernel logger is in use."); toolTip_.AddTool(&btChromeDeveloper_, L"Check this to enable Chrome specific behavior such as " L"setting the Chrome symbol server path, and identifying Chrome processes."); toolTip_.AddTool(&btAutoViewTraces_, L"Check this to have UIforETW launch the trace viewer " L"immediately after a trace is recorded."); toolTip_.AddTool(&btRecordPreTrace_, L"Check this to enable recording of a startup trace " L"to grab a snapshot of module version and symbol information. This allows analyzing " L"traces across upgrades, such as chrome restart upgrades."); toolTip_.AddTool(&btHeapStacks_, L"Check this to record call stacks on HeapAlloc, HeapRealloc, " L"and similar calls, when doing heap traces."); toolTip_.AddTool(&btVirtualAllocStacks_, L"Check this to record call stacks on VirtualAlloc on all " L"traces instead of just heap traces."); toolTip_.AddTool(&btVersionChecks_, L"Check this to have UIforETW check for new versions at startup."); toolTip_.AddTool(&btChromeCategories_, L"Check the chrome tracing categories that you want Chrome " L"to emit ETW events for. This requires running Chrome version 46 or later, and " L"using chrome://flags/ to \"Enable exporting of tracing events to ETW\" - search for " L"trace-export on the chrome://flags/ page."); toolTip_.AddTool(&btIdentifyChromeProcessesCPU_, L"If this is checked and \"Chrome developer\" is " L"checked then CPU usage details of Chrome processes will be added to the trace information " L"file when traces are recorded. Calculating the CPU usage details can take a while."); toolTip_.AddTool(&btBackgroundMonitoring_, L"When this is checked background threads will periodically " L"(a few times per second) record information about system performance to the trace being " L"recorded. This can be helpful in understanding performance problems but may affect " L"power consumption."); } // Initialize the list of check boxes with all of the Chrome categories which // we can enable individually. btChromeCategories_.SetCheckStyle(BS_AUTOCHECKBOX); int index = 0; for (auto category : filtered_event_group_names) { btChromeCategories_.AddString(category); btChromeCategories_.SetCheck(index, (chromeKeywords_ & (1LL << index)) != 0); ++index; } // Manually add the two special Chrome category options. btChromeCategories_.AddString(other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & other_events_keyword_bit) != 0); ++index; btChromeCategories_.AddString(disabled_other_events_group_name); btChromeCategories_.SetCheck(index, (chromeKeywords_ & disabled_other_events_keyword_bit) != 0); return TRUE; // return TRUE unless you set the focus to a control }
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, char *CmdLine, int CmdShow) { bool uninstall_mode = false; char exe_name[MAX_PATH]; char exe_dir[MAX_PATH]; UINT os_ver = GetWindowsVersion(); CoInitialize(NULL); DisableWow64FsRedirection(); if (SeStartWith(CmdLine, "/uninstall")) { uninstall_mode = true; } GetModuleFileNameA(hInst, exe_name, sizeof(exe_name)); SeGetDirNameFromFilePath(exe_dir, sizeof(exe_dir), exe_name); if (uninstall_mode == false) { char driver_inf_filename[MAX_PATH] = {0}; bool install_driver = false; // Check the Windows version if (os_ver == OS_UNKNOWN) { MessageBoxA(NULL, "This operating system is not supported by Win10Pcap.\r\n\r\n" "Win10Pcap requires Windows 7, Server 2008 R2, Windows 8, Windows 8.1, Windows Server 2012, Windows Server 2012 R2 or Windows 10.", INSTALLER_TITLE, MB_ICONSTOP | MB_SYSTEMMODAL); return -1; } SeStrCpy(driver_inf_filename, sizeof(driver_inf_filename), exe_dir); if (os_ver == OS_WIN10) { SeStrCat(driver_inf_filename, sizeof(driver_inf_filename), "\\drivers\\win10"); } else { SeStrCat(driver_inf_filename, sizeof(driver_inf_filename), "\\drivers\\win78"); } SeStrCat(driver_inf_filename, sizeof(driver_inf_filename), "\\Win10Pcap.inf"); // Install the device driver if (Is64BitCode()) { // x64 install_driver = true; } else if (IsWow64() == false) { // x86 install_driver = true; } else { // Do nothing. } if (install_driver) { LABEL_RETRY_INSTALL_DRIVER: if (InstallNdisProtocolDriver(driver_inf_filename, L"Win10Pcap", 60 * 1000) == false) { if (MessageBoxA(NULL, "The install process of the Win10Pcap NDIS device driver failed.", INSTALLER_TITLE, MB_ICONEXCLAMATION | MB_SYSTEMMODAL | MB_RETRYCANCEL) == IDRETRY) { goto LABEL_RETRY_INSTALL_DRIVER; } else { return -1; } } MsStartService("Win10Pcap"); } if (InstallDllToSystem32(exe_dir, "Packet.dll", "Packet.dll") == false || InstallDllToSystem32(exe_dir, "wpcap.dll", "wpcap.dll") == false) { return -1; } if (Is64BitCode() == false && Is64BitWindows()) { // Run x64 char x64_exe[MAX_PATH]; wsprintfA(x64_exe, "%s\\..\\x64\\Installer.exe", exe_dir); Win32RunAndWaitProcess(x64_exe, CmdLine, false, false, INFINITE); } } else { bool uninstall_driver = false; UninstallDllFromSystem32("Packet.dll"); UninstallDllFromSystem32("wpcap.dll"); // Install the device driver if (Is64BitCode()) { // x64 uninstall_driver = true; } else if (IsWow64() == false) { // x86 uninstall_driver = true; } else { // Do nothing. } if (uninstall_driver) { LABEL_RETRY_UNINSTALL_DRIVER: if (UninstallNdisProtocolDriver(L"Win10Pcap", 60 * 1000) == false) { if (MessageBoxA(NULL, "The uninstall process of the Win10Pcap NDIS device driver failed.", INSTALLER_TITLE, MB_ICONEXCLAMATION | MB_SYSTEMMODAL | MB_RETRYCANCEL) == IDRETRY) { goto LABEL_RETRY_UNINSTALL_DRIVER; } } } if (Is64BitCode() == false && Is64BitWindows()) { // Run x64 char x64_exe[MAX_PATH]; wsprintfA(x64_exe, "%s\\..\\x64\\Installer.exe", exe_dir); Win32RunAndWaitProcess(x64_exe, CmdLine, false, false, INFINITE); } } CoUninitialize(); return 0; }