__override
VOID
IN_PROCESS_APPLICATION::ShutDown(
    VOID
)
{
    HRESULT hr = S_OK;
    CHandle  hThread;
    DWORD    dwThreadStatus = 0;
    DWORD    dwTimeout = m_pConfig->QueryShutdownTimeLimitInMS();

    if (IsDebuggerPresent())
    {
        dwTimeout = INFINITE;
    }

    hThread.Attach(CreateThread(
        NULL,       // default security attributes
        0,          // default stack size
        (LPTHREAD_START_ROUTINE)DoShutDown,
        this,       // thread function arguments
        0,          // default creation flags
        NULL));      // receive thread identifier

    if ((HANDLE)hThread == NULL)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto Finished;
    }

    if (WaitForSingleObject(hThread, dwTimeout) != WAIT_OBJECT_0)
    {
        // if the thread is still running, we need kill it first before exit to avoid AV
        if (GetExitCodeThread(m_hThread, &dwThreadStatus) != 0 && dwThreadStatus == STILL_ACTIVE)
        {
            // Calling back into managed at this point is prone to have AVs
            // Calling terminate thread here may be our best solution.
            TerminateThread(hThread, STATUS_CONTROL_C_EXIT);
            hr = HRESULT_FROM_WIN32(ERROR_TIMEOUT);
        }
    }

Finished:

    if (FAILED(hr))
    {
        UTILITY::LogEventF(g_hEventLog,
            EVENTLOG_WARNING_TYPE,
            ASPNETCORE_EVENT_GRACEFUL_SHUTDOWN_FAILURE,
            ASPNETCORE_EVENT_APP_SHUTDOWN_FAILURE_MSG,
            m_pConfig->QueryConfigPath()->QueryStr());

        //
        // Managed layer may block the shutdown and lead to shutdown timeout
        // Assumption: only one inprocess application is hosted.
        // Call process exit to force shutdown
        //
        exit(hr);
    }
}
    void ShowInitialProgressWindow(bool wasAssert)
    {
        if (m_serviceMode)
            return;

        CloseProgressWindow();
        m_progressWindowThread.Attach(CreateThread(NULL, 0, wasAssert ? SendAssertReportDlgThread : SendReportDlgThread, this, 0, NULL));
        if (!m_progressWindowThread)
            throw runtime_error("Failed to create thread");
    }
    void ShowFullDumpUploadProgressWindow()
    {
        if (m_serviceMode)
            return;

        CloseProgressWindow();
        m_progressWindowThread.Attach(CreateThread(NULL, 0, SendFullDumpDlgThread, this, 0, NULL));
        if (!m_progressWindowThread)
            throw runtime_error("Failed to create thread");
        Sleep(100); // Give time to draw a dialog before writing a dump (it will freeze a dialog for unknown reasons)
    }
Example #4
0
void CHFServer::CloseHFProcess(LPCSTR szProcessName)
{
	std::string sProcessName =  utils::upcase(std::string(szProcessName));
	DWORD dwID = 0;
	CHandle hProcess = GetProcessId(sProcessName, dwID);
	long iCount = 0;
	if(hProcess == NULL)
		EgLib::CEgLibTraceManager::Trace(LogFaults, __FUNCTION__ , _T("No %s module found"), sProcessName.c_str());	

	while( hProcess != NULL)
	{
		EgLib::CEgLibTraceManager::Trace(LogFaults, __FUNCTION__ , _T("Terminating %s module"), sProcessName.c_str());	
		

		if(!TerminateProcess(hProcess, 0)  )
		{
			DWORD dwError = GetLastError();

			if(dwID)
			{
				if(!Kill(dwID))
					EgLib::CEgLibTraceManager::Trace(LogFaults, __FUNCTION__ , _T("Kill Process %s Failed with error %d and terminate with error %d"), sProcessName.c_str(), GetLastError() , dwError);	
			}  
			else
				EgLib::CEgLibTraceManager::Trace(LogFaults, __FUNCTION__ , _T("Unable to terminate %s module %d"), sProcessName.c_str(), dwError);	
		}

		if(++iCount > 10)
		{
			EgLib::CEgLibTraceManager::Trace(LogFaults, __FUNCTION__ , _T("Too many %s process to terminate %d"), sProcessName.c_str(), GetLastError());	
			break;
		}
		hProcess.Close();
		hProcess.Attach(GetProcessId(sProcessName, dwID));
	}
}
void CRemoteGraphForm::OnRefreshClick()
{
	// let's load objects from ROT
	CComPtr<IRunningObjectTable>	rot;
	HRESULT							hr;

	graphs.RemoveAll();
    list_graphs.DeleteAllItems();
    sel_graph = RemoteGraph();

	hr = GetRunningObjectTable(0, &rot);
	if (FAILED(hr)) return ;

	// scan through running objects
	CComPtr<IEnumMoniker>			emon;
	CComPtr<IMoniker>				moniker;
	CComPtr<IBindCtx>				bindctx;
	ULONG							f;

	hr = CreateBindCtx(0, &bindctx);
	if (FAILED(hr)) {
		return ;
	}

    CAtlRegExp<> regex;
    REParseError status = regex.Parse(_T("^\\!FilterGraph {[0-9A-F]+} pid {[0-9A-F]+}(; process\\: {.+?}, time\\: {[0-9]+\\-[0-9]+\\-[0-9]+})?"), FALSE);

	rot->EnumRunning(&emon);
	emon->Reset();
	while (emon->Next(1, &moniker, &f) == NOERROR) {
		
		// is this a graph object ?
		LPOLESTR	displayname;
		moniker->GetDisplayName(bindctx, NULL, &displayname);

		CString		name(displayname);
		if (name.Find(_T("!FilterGraph")) == 0 && !GraphStudio::DisplayGraph::IsOwnRotGraph(name)) {
            RemoteGraph	gr = {0};

            CAtlREMatchContext<> mc;
            gr.name = name;
			gr.moniker = moniker;
            gr.pid = 0;
            gr.instance = 0;
            gr.processIsWOW64 = FALSE;

            if (regex.Match(name, &mc))
            {
                const CAtlREMatchContext<>::RECHAR* szStart = 0;
                const CAtlREMatchContext<>::RECHAR* szEnd = 0;
                mc.GetMatch(0, &szStart, &szEnd);
                int nLength = (int) (szEnd - szStart);
                const CString textInstance(szStart, nLength);
                StrToInt64ExW(CStringW(L"0x") + textInstance, STIF_SUPPORT_HEX, &reinterpret_cast<LONGLONG&>(gr.instance));

                mc.GetMatch(1, &szStart, &szEnd);
                nLength = (int) (szEnd - szStart);
                const CString textPID(szStart, nLength);
				CString nameSuffix(szEnd ? szEnd : _T(""));
				nameSuffix.Trim();

			    if (StrToIntExW(CStringW(L"0x") + textPID, STIF_SUPPORT_HEX, &reinterpret_cast<INT&>(gr.pid)))
                {
                    CHandle process;
					process.Attach(OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, gr.pid));
					if (process)
                    {
                        TCHAR pszPath[MAX_PATH] = { 0 };
					    if (GetModuleFileNameEx(process, NULL, pszPath, sizeof(pszPath)))
                        {
                            gr.processImagePath = pszPath;

                            // Extract filename
                            int fileNamePos = gr.processImagePath.FindFileName();
                            if (fileNamePos >= 0)
                                gr.processImageFileName = CString(gr.processImagePath).Mid(fileNamePos);
                        }
                        else
                        {
                            // a 32Bit process can't list the modules of a 64Bit process, so try to get the processImageFileName from the ROT-Name (works only for FilterGraphSpy-Entries)
                            mc.GetMatch(2, &szStart, &szEnd);
                            nLength = (int) (szEnd - szStart);
                            if (nLength > 0)
                            {
                                CString textFileName(szStart, nLength);
                                gr.processImageFileName = textFileName;
                            }
							else if (nameSuffix.GetLength() > 0)
							{
								gr.processImageFileName = nameSuffix;		// as a last resort add any suffix information from the ROT name rather than leaving blank
#ifndef _WIN64
								gr.processImageFileName += _T(" *64");		// If we're 32bit, assume that we can't get process name because remote process is 64bit and show this on the dialog
#endif
							}
                        }

                        IsWow64Process(process, &gr.processIsWOW64);
                    }
                }

                mc.GetMatch(3, &szStart, &szEnd);
                nLength = (int) (szEnd - szStart);
                if (nLength > 0)
                {
                    CString textTime(szStart, nLength);
                    textTime.Replace(_T("-"), _T(":"));
                    gr.time = textTime;
                }
            }
            graphs.Add(gr);

            CString entryName = gr.name;
            if (gr.pid > 0)
                entryName.Format(_T("%d (0x%08lX)"), gr.pid, gr.pid);
			int nIndex = list_graphs.InsertItem(list_graphs.GetItemCount(), entryName);
            
            if (gr.processIsWOW64)
            {
                CString val = gr.processImageFileName;
                val.Append(_T(" *32"));
                list_graphs.SetItemText(nIndex, 1, val);
            }
            else
                list_graphs.SetItemText(nIndex, 1, gr.processImageFileName);

            if (gr.instance > 0)
            {
                CString val;
                val.Format(_T("0x%I64d"), gr.instance);
                list_graphs.SetItemText(nIndex, 2, val);
            }

            list_graphs.SetItemText(nIndex, 3, gr.time);
            list_graphs.SetItemText(nIndex, 4, gr.processImagePath);

			if (graphs.GetCount() == 1) {
                list_graphs.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
                list_graphs.SetSelectionMark(0);
			}
		}

		if (displayname) {
			CComPtr<IMalloc>	alloc;
			if (SUCCEEDED(CoGetMalloc(0, &alloc))) {
				alloc->Free(displayname);
			}
		}
		moniker = NULL;
	}

	// Set column width automatically to fit contents refreshed above
	for (int n=0; n<=4; n++) {
		list_graphs.SetColumnWidth(n, LVSCW_AUTOSIZE_USEHEADER);
	}
}
int wmain(int argc, wchar_t* argv[])
{
    // Initialize COM and deinitialize when we go out of scope
    HRESULT hrCoInit = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
    shared_ptr<HRESULT> spCoInit(&hrCoInit, [](const HRESULT* hrCom) -> void { if (SUCCEEDED(*hrCom)) { ::CoUninitialize(); } });
    {
        // Set a close handler to shutdown the chrome instance we launch
        ::SetConsoleCtrlHandler(OnClose, TRUE);

        // Launch chrome
        {
            CString chromePath;

            // Find the chrome install location via the registry
            CString keyPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe";

            CRegKey regKey;

            // First see if we can find where Chrome is installed from the registry. This will only succeed if Chrome is installed for all users
            if (regKey.Open(HKEY_LOCAL_MACHINE, keyPath, KEY_READ) == ERROR_SUCCESS)
            {
                ULONG bufferSize = MAX_PATH;
                CString path;
                LRESULT result = regKey.QueryStringValue(nullptr, path.GetBufferSetLength(bufferSize), &bufferSize);
                path.ReleaseBufferSetLength(bufferSize);
                if (result == ERROR_SUCCESS)
                {
                    chromePath = path;
                }
            }

            if (chromePath.GetLength() == 0)
            {
                // If Chrome is only installed for the current user, look in \AppData\Local\Google\Chrome\Application\ for Chrome.exe
                CString appPath;
                ::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appPath.GetBuffer(MAX_PATH + 1));
                appPath.ReleaseBuffer();
                chromePath = appPath + L"\\Google\\Chrome\\Application\\chrome.exe";
            }

            // Get a temp location
            CString temp;
            Helpers::ExpandEnvironmentString(L"%Temp%", temp);

            // Set arguments for the chrome that we launch
            CString arguments;
            arguments.Format(L"about:blank --remote-debugging-port=9223 --window-size=0,0 --silent-launch --no-first-run --no-default-browser-check --user-data-dir=\"%s\"", temp);

            // Launch the process
            STARTUPINFO si = { 0 };
            PROCESS_INFORMATION pi = { 0 };
            si.cb = sizeof(si);
            si.wShowWindow = SW_MINIMIZE;

            BOOL result = ::CreateProcess(
                chromePath,
                arguments.GetBuffer(),
                nullptr,
                nullptr,
                FALSE,
                0,
                nullptr,
                temp,
                &si,
                &pi);
            arguments.ReleaseBuffer();

            if (result)
            {
                // Store the handles
                CHandle hThread(pi.hThread);
                hChromeProcess.Attach(pi.hProcess);
                DWORD waitResult = ::WaitForInputIdle(hChromeProcess, 30000);
            }
            else
            {
                std::cerr << "Could not open Chrome. Please ensure that Chrome is installed." << std::endl;
                system("pause");
                return -1;
            }
        }
        
        // Get the current path that we are running from
        CString fullPath;
        DWORD count = ::GetModuleFileName(nullptr, fullPath.GetBuffer(MAX_PATH), MAX_PATH);
        fullPath.ReleaseBufferSetLength(count);

        LPWSTR buffer = fullPath.GetBuffer();
        LPWSTR newPath = ::PathFindFileName(buffer);
        if (newPath && newPath != buffer)
        {
            fullPath.ReleaseBufferSetLength((newPath - buffer));
        }
        else
        {
            fullPath.ReleaseBuffer();
        }

        // Load the proxy server
        IEDiagnosticsAdapter proxy(fullPath);

        // Create a message pump
        MSG msg;
        ::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

        // Thread message loop
        BOOL getMessageRet;
        while ((getMessageRet = ::GetMessage(&msg, NULL, 0, 0)) != 0)
        {
            if (getMessageRet != -1)
            {
                ::TranslateMessage(&msg);
                ::DispatchMessage(&msg);
            }
        }

        // Leave the window open so we can read the log file
        wcout << endl << L"Press [ENTER] to exit." << endl;
        cin.ignore();
    }

    return 0;
}
int wmain(int argc, wchar_t* argv[])
{
	//::MessageBox(NULL, L"Stop here", L"STOP!", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON3);

	std:cout << "Edge Diagnostics Adapter" << std::endl;

	po::options_description desc("Allowed options");
	desc.add_options()
		("help,h", "Prints this help text.")
		("launch,l", po::value<string>(), "Launches Edge. Optionally at the URL specified in the value")
		("killall,k", "Kills all running Edge processes.")
		("chrome,c", "Launches Crhome in the background to serve the Chrome Developer Tools frontend.")
		("port,p", po::value<string>(), "The port number to listen on. Default is 9222.");

	po::variables_map vm;
	try
	{
		po::store(po::parse_command_line(argc, argv, desc), vm);
	}
	catch (po::error& e)
	{
		std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
		std::cerr << desc << std::endl;
		return E_FAIL;
	}

	if (vm.count("help"))
	{
		std::cout << desc << std::endl;
		return S_OK;
	}


	// Initialize COM and deinitialize when we go out of scope
	HRESULT hrCoInit = ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

	shared_ptr<HRESULT> spCoInit(&hrCoInit, [](const HRESULT* hrCom) -> void { if (SUCCEEDED(*hrCom)) { ::CoUninitialize(); } });
	{
		// Set a close handler to shutdown the chrome instance we launch
		::SetConsoleCtrlHandler(OnClose, TRUE);

		// Launch chrome
		if (vm.count("chrome"))
		{
			CString chromePath;

			// Find the chrome install location via the registry
			CString keyPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe";

			CRegKey regKey;

			// First see if we can find where Chrome is installed from the registry. This will only succeed if Chrome is installed for all users
			if (regKey.Open(HKEY_LOCAL_MACHINE, keyPath, KEY_READ) == ERROR_SUCCESS)
			{
				ULONG bufferSize = MAX_PATH;
				CString path;
				LRESULT result = regKey.QueryStringValue(nullptr, path.GetBufferSetLength(bufferSize), &bufferSize);
				path.ReleaseBufferSetLength(bufferSize);
				if (result == ERROR_SUCCESS)
				{
					chromePath = path;
				}
			}

			if (chromePath.GetLength() == 0)
			{
				// If Chrome is only installed for the current user, look in \AppData\Local\Google\Chrome\Application\ for Chrome.exe
				CString appPath;
				::SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appPath.GetBuffer(MAX_PATH + 1));
				appPath.ReleaseBuffer();
				chromePath = appPath + L"\\Google\\Chrome\\Application\\chrome.exe";
			}

			// Get a temp location
			CString temp;
			Helpers::ExpandEnvironmentString(L"%Temp%", temp);

			// Set arguments for the chrome that we launch
			CString arguments;
			arguments.Format(L"about:blank --remote-debugging-port=9223 --window-size=0,0 --silent-launch --no-first-run --no-default-browser-check --user-data-dir=\"%s\"", temp);

			// Launch the process
			STARTUPINFO si = { 0 };
			PROCESS_INFORMATION pi = { 0 };
			si.cb = sizeof(si);
			si.wShowWindow = SW_MINIMIZE;

			BOOL result = ::CreateProcess(
				chromePath,
				arguments.GetBuffer(),
				nullptr,
				nullptr,
				FALSE,
				0,
				nullptr,
				temp,
				&si,
				&pi);
			arguments.ReleaseBuffer();

			if (result)
			{
				// Store the handles
				CHandle hThread(pi.hThread);
				hChromeProcess.Attach(pi.hProcess);
				DWORD waitResult = ::WaitForInputIdle(hChromeProcess, 30000);
			}
			else
			{
				std::cerr << "Could not open Chrome. Please ensure that Chrome is installed." << std::endl;
				system("pause");
				return -1;
			}
		}

		// Kill all Edge instances if their is an aegument /killall
		if (vm.count("killall"))
		{
			//killAllProcessByExe(L"MicrosoftEdgeCP.exe");
			Helpers::KillAllProcessByExe(L"MicrosoftEdge.exe");
		}

		// Launch Edge if their is an argument set /launch:<url>
		if (vm.count("launch"))
		{
			CString url(vm["launch"].as<string>().c_str());
			if (url.GetLength() == 0)
			{
				url = L"https://www.bing.com";
			}

			HRESULT hr = Helpers::OpenUrlInMicrosoftEdge(url);

			if (FAILED(hr))
			{
				std::cout << L"Failed to launch Microsoft Edge";
			}
		}

		string port = EdgeDiagnosticsAdapter::s_Default_Port;
		if (vm.count("port"))
		{
			port = vm["port"].as<string>();
		}

		// We don't care if this fails as the developer can set it manually.
		setSecurityACLs();

		// We don't care if this fails or not as maybe the developer wants to do something that won't hit the PLM. In case errors went to the console.
		setEdgeForDebugging(true);

		// Load the proxy server
		EdgeDiagnosticsAdapter proxy(getPathToCurrentExeContainer(), port);

		if (proxy.IsServerRunning)
		{

			// Create a message pump
			MSG msg;
			::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

			// Thread message loop
			BOOL getMessageRet;
			while ((getMessageRet = ::GetMessage(&msg, NULL, 0, 0)) != 0)
			{
				if (getMessageRet != -1)
				{
					::TranslateMessage(&msg);
					::DispatchMessage(&msg);
				}
			}

			// Leave the window open so we can read the log file
			wcout << endl << L"Press [ENTER] to exit." << endl;
			cin.ignore();
		}
		else
		{
			wcout << L"Error starting. Quiting.";
			return E_FAIL;
		}
	}

	return S_OK;
}