Example #1
0
bool CServerSession::OnRunImage( CNcpMessage* pMsg, int nSize )
{
    char path[MAXPATH];

    //parse the parameters
    bool bSync = (bool)pMsg->GetRet();
    string strImageName = (char*)(pMsg->GetData());

    if( !IsAbsDir( strImageName.c_str() ) ) {
        strcpy( path, m_strCurDir.c_str() );
        CatDir( path, strImageName.c_str(), path, ELEMENTS(path) );
    } else {
        strcpy( path, strImageName.c_str() );
    }

    BOOL bOk;
    int nPriority = m_pServApp->GetPriority();
    DWORD dwExitCode = 0;
    if( bSync ) {	//synchronize running, register the handle and wait the process
        HANDLE hProcess;
        //bOk = CreateProcess( path, m_strCurDir.c_str(), nPriority, &hProcess );
        bOk = CreateProcess( path, m_strCurDir.c_str(), &hProcess );
        SetProcessPriority( hProcess, nPriority );

        m_pServApp->RegistProc( hProcess );
        WaitForProcess( hProcess, &dwExitCode );
        m_pServApp->UnregistProc( hProcess );

        //CloseProcessHandle( hProcess );
        CloseHandle( hProcess );
    } else {			//just run the process and return.
        bOk = CreateProcess( path, m_strCurDir.c_str(), NULL );
        //bOk = CreateProcess( path, m_strCurDir.c_str(), nPriority, NULL );
        //SetProcessPriority( hProcess, nPriority );
    }


#ifdef _WIN32
    printf( "windows process exit code:%d\n", dwExitCode );
#else
    int status = dwExitCode;
    if( WIFEXITED(status) )printf( "normal termination, exit status=%d\n", WEXITSTATUS(status) );
    else if( WIFSIGNALED(status) )printf( "abnormal termination, signal number=%d\n", WTERMSIG(status) );
    else if( WIFSTOPPED(status) )printf( "child stopped, signal number=%d\n", WSTOPSIG(status) );
#endif

    //send back the return code.
    pMsg->Init( CM_ACK );
    if( !bOk ) {
        pMsg->SetRet( E_NOEXEC );
    } else {
        pMsg->SetRet( dwExitCode );
    }
    pMsg->Send( m_sock );

    return bOk;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    /*
     * Gather the parameters of the real installer program.
     */

    SetLastError(NO_ERROR);
    WCHAR wszCurDir[_MAX_PATH] = { 0 };
    DWORD cchCurDir = GetCurrentDirectoryW(sizeof(wszCurDir), wszCurDir);
    if (cchCurDir == 0 || cchCurDir >= sizeof(wszCurDir))
    {
        fwprintf(stderr, L"ERROR: GetCurrentDirectoryW failed: %u (ret %u)\n", GetLastError(), cchCurDir);
        return 12;
    }

    SetLastError(NO_ERROR);
    WCHAR wszModule[_MAX_PATH] = { 0 };
    DWORD cchModule = GetModuleFileNameW(NULL, wszModule, sizeof(wszModule));
    if (cchModule == 0 || cchModule >= sizeof(wszModule))
    {
        fwprintf(stderr, L"ERROR: GetModuleFileNameW failed: %u (ret %u)\n", GetLastError(), cchModule);
        return 13;
    }

    /* Strip the extension off the module name and construct the arch specific
       one of the real installer program. */
    DWORD off = cchModule - 1;
    while (   off > 0
           && (   wszModule[off] != '/'
               && wszModule[off] != '\\'
               && wszModule[off] != ':'))
    {
        if (wszModule[off] == '.')
        {
            wszModule[off] = '\0';
            cchModule = off;
            break;
        }
        off--;
    }

    WCHAR const  *pwszSuff = IsWow64() ? L"-amd64.exe" : L"-x86.exe";
    size_t        cchSuff  = wcslen(pwszSuff);
    if (cchSuff + cchModule >= sizeof(wszModule))
    {
        fwprintf(stderr, L"ERROR: Real installer name is too long (%u chars)\n", cchSuff + cchModule);
        return 14;
    }
    wcscpy(&wszModule[cchModule], pwszSuff);
    cchModule += cchSuff;

    /* Replace the first argument of the argument list. */
    PWCHAR  pwszNewCmdLine = NULL;
    LPCWSTR pwszOrgCmdLine = GetCommandLineW();
    if (pwszOrgCmdLine) /* Dunno if this can be NULL, but whatever. */
    {
        /* Skip the first argument in the original. */
        /** @todo Is there some ISBLANK or ISSPACE macro/function in Win32 that we could
         *        use here, if it's correct wrt. command line conventions? */
        WCHAR wch;
        while ((wch = *pwszOrgCmdLine) == L' ' || wch == L'\t')
            pwszOrgCmdLine++;
        if (wch == L'"')
        {
            pwszOrgCmdLine++;
            while ((wch = *pwszOrgCmdLine) != L'\0')
            {
                pwszOrgCmdLine++;
                if (wch == L'"')
                    break;
            }
        }
        else
        {
            while ((wch = *pwszOrgCmdLine) != L'\0')
            {
                pwszOrgCmdLine++;
                if (wch == L' ' || wch == L'\t')
                    break;
            }
        }
        while ((wch = *pwszOrgCmdLine) == L' ' || wch == L'\t')
            pwszOrgCmdLine++;

        /* Join up "szModule" with the remainder of the original command line. */
        size_t cchOrgCmdLine = wcslen(pwszOrgCmdLine);
        size_t cchNewCmdLine = 1 + cchModule + 1 + 1 + cchOrgCmdLine + 1;
        PWCHAR pwsz = pwszNewCmdLine = (PWCHAR)LocalAlloc(LPTR, cchNewCmdLine * sizeof(WCHAR));
        if (!pwsz)
        {
            fwprintf(stderr, L"ERROR: Out of memory (%u bytes)\n", cchNewCmdLine);
            return 15;
        }
        *pwsz++ = L'"';
        wcscpy(pwsz, wszModule);
        pwsz += cchModule;
        *pwsz++ = L'"';
        if (cchOrgCmdLine)
        {
            *pwsz++ = L' ';
            wcscpy(pwsz, pwszOrgCmdLine);
        }
        else
        {
            *pwsz = L'\0';
            pwszOrgCmdLine = NULL;
        }
    }

    /*
     * Start the process.
     */
    int iRet = 0;
    STARTUPINFOW        StartupInfo = { sizeof(StartupInfo), 0 };
    PROCESS_INFORMATION ProcInfo = { 0 };
    SetLastError(740);
    BOOL fOk = CreateProcessW(wszModule,
                              pwszNewCmdLine,
                              NULL /*pProcessAttributes*/,
                              NULL /*pThreadAttributes*/,
                              TRUE /*fInheritHandles*/,
                              0    /*dwCreationFlags*/,
                              NULL /*pEnvironment*/,
                              NULL /*pCurrentDirectory*/,
                              &StartupInfo,
                              &ProcInfo);
    if (fOk)
    {
        /* Wait for the process to finish. */
        CloseHandle(ProcInfo.hThread);
        WaitForProcess(ProcInfo.hProcess, &iRet);
        CloseHandle(ProcInfo.hProcess);
    }
    else if (GetLastError() == ERROR_ELEVATION_REQUIRED)
    {
        /*
         * Elevation is required. That can be accomplished via ShellExecuteEx
         * and the runas atom.
         */
        MSG Msg;
        PeekMessage(&Msg, NULL, 0, 0, PM_NOREMOVE);
        CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);

        SHELLEXECUTEINFOW ShExecInfo = { 0 };
        ShExecInfo.cbSize       = sizeof(SHELLEXECUTEINFOW);
        ShExecInfo.fMask        = SEE_MASK_NOCLOSEPROCESS;
        ShExecInfo.hwnd         = NULL;
        ShExecInfo.lpVerb       = L"runas" ;
        ShExecInfo.lpFile       = wszModule;
        ShExecInfo.lpParameters = pwszOrgCmdLine; /* pass only args here!!! */
        ShExecInfo.lpDirectory  = wszCurDir;
        ShExecInfo.nShow        = SW_NORMAL;
        ShExecInfo.hProcess     = INVALID_HANDLE_VALUE;
        if (ShellExecuteExW(&ShExecInfo))
        {
            if (ShExecInfo.hProcess != INVALID_HANDLE_VALUE)
            {
                WaitForProcess2(ShExecInfo.hProcess, &iRet);
                CloseHandle(ShExecInfo.hProcess);
            }
            else
            {
                fwprintf(stderr, L"ERROR: ShellExecuteExW did not return a valid process handle!\n");
                iRet = 1;
            }
        }
        else
        {
            fwprintf(stderr, L"ERROR: Failed to execute '%ws' via ShellExecuteExW: %u\n", wszModule, GetLastError());
            iRet = 9;
        }
    }
    else
    {
        fwprintf(stderr, L"ERROR: Failed to execute '%ws' via CreateProcessW: %u\n", wszModule, GetLastError());
        iRet = 8;
    }

    if (pwszNewCmdLine)
        LocalFree(pwszNewCmdLine);

#if 0
    fwprintf(stderr, L"DEBUG: iRet=%d\n", iRet);
    fflush(stderr);
#endif
    return iRet;
}
Example #3
0
int main(int argc, char ** argv)
{
    --argc;
    ++argv;

    if (argc == 0) {
        printHelp();
        return 0;
    }

    int waitpid = -1;
    PresentMonArgs args;
    std::string title_string = "PresentMon";

    args.mTargetProcessName = "*";

    for (int i = 0; i < argc; ++i)
    {
        // 2-component arguments
        if (i + 1 < argc)
        {
            if (!strcmp(argv[i], "-waitpid"))
            {
                waitpid = atoi(argv[++i]);
                continue;
            }
            else if (!strcmp(argv[i], "-process_name"))
            {
                args.mTargetProcessName = argv[++i];
            }
            else if (!strcmp(argv[i], "-process_id"))
            {
                args.mTargetPid = atoi(argv[++i]);
            }
            else if (!strcmp(argv[i], "-output_file"))
            {
                args.mOutputFileName = argv[++i];
            }
            else if (!strcmp(argv[i], "-etl_file"))
            {
                args.mEtlFileName = argv[++i];
            }
            else if (!strcmp(argv[i], "-delay"))
            {
                args.mDelay = atoi(argv[++i]);
            }
            else if (!strcmp(argv[i], "-timed"))
            {
                args.mTimer = atoi(argv[++i]);
            }
        }
        // 1-component args
        {
            if (!strcmp(argv[i], "-no_csv"))
            {
                args.mOutputFileName = "*";
            }
            else if (!strcmp(argv[i], "-exclude_dropped"))
            {
                args.mExcludeDropped = true;
            }
            else if (!strcmp(argv[i], "-scroll_toggle"))
            {
                args.mScrollLockToggle = true;
            }
            else if (!strcmp(argv[i], "-?") || !strcmp(argv[i], "-help"))
            {
                printHelp();
                return 0;
            }
        }

        title_string += ' ';
        title_string += argv[i];
    }

    if (waitpid >= 0) {
        WaitForProcess(waitpid);
        if (!HaveAdministratorPrivileges()) {
            printf("Elevation process failed. Aborting.\n");
            return 0;
        }
    }

    if (!args.mEtlFileName && !HaveAdministratorPrivileges()) {
        printf("Process is not running as admin. Attempting to elevate.\n");
        RestartAsAdministrator(argc, argv);
        return 0;
    }

    SetConsoleCtrlHandler(HandlerRoutine, TRUE);
    SetConsoleTitleA(title_string.c_str());

    std::mutex exit_mutex;
    g_ExitMutex = &exit_mutex;

    // Run PM in a separate thread so we can join it in the CtrlHandler (can't join the main thread)
    std::thread pm(PresentMonEtw, args);
    g_PresentMonThread = &pm;
    while (!g_Quit)
    {
        Sleep(100);
    }

    // Wait for tracing to finish, to ensure the PM thread closes the session correctly
    // Prevent races on joining the PM thread between the control handler and the main thread
    std::lock_guard<std::mutex> lock(exit_mutex);
    if (g_PresentMonThread->joinable()) {
        g_PresentMonThread->join();
    }
    return 0;
}
/////////////////////////////////////////////////////////////////////////////
// ExecuteVerifyUpdate
//
DWORD ExecuteVerifyUpdate(LPCSTR szModuleFile, LPCSTR szUpdateCachePath)
{
    DWORD dwResult = 0;

    // build up CreateProcess structures
    STARTUPINFO          sui;
    PROCESS_INFORMATION  pi;

    memset((void*)&pi, 0x00, sizeof(PROCESS_INFORMATION));
    memset((void*)&sui, 0x00, sizeof(STARTUPINFO));
    sui.cb          = sizeof(STARTUPINFO);
    sui.dwFlags     = STARTF_USESHOWWINDOW;
    sui.wShowWindow = SW_SHOW;

    //
    // Build command line and specify delayreboot option to Update
    // The nine extra characters are required for the following:
    //      2 for the quotes enclosing the module path
    //      2 for /v
    //      2 for the spaces before and after /v
    //      2 for the quotes enclosing the Update path
    //      1 for the terminating null.
    //
    DWORD cchCommandLine = lstrlen(szModuleFile) + lstrlen(szUpdateCachePath) + 9;
    char *szCommandLine = new char[cchCommandLine];

    if (!szCommandLine)
    {
        dwResult = ERROR_OUTOFMEMORY;
        goto Return_ExecuteVerifyUpdate;
    }

    if (FAILED(StringCchCopy(szCommandLine, cchCommandLine, "\""))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, szModuleFile))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, "\""))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, " /v \""))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, szUpdateCachePath))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, "\"")))
    {
        dwResult = ERROR_INSTALL_FAILURE;
        goto Return_ExecuteVerifyUpdate;
    }
    
    //
    // Run the verification process. We use a copy of ourselves to do this.
    //
    if(!WIN::CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sui, &pi))
    {
        // failed to launch.
        dwResult = GetLastError();
        goto Return_ExecuteVerifyUpdate;
    }

    dwResult = WaitForProcess(pi.hProcess);
    if(ERROR_SUCCESS != dwResult)
        goto Return_ExecuteVerifyUpdate;

    WIN::GetExitCodeProcess(pi.hProcess, &dwResult);

Return_ExecuteVerifyUpdate:

    if (szCommandLine)
        delete [] szCommandLine;
    if (pi.hProcess)
        WIN::CloseHandle(pi.hProcess);
    if (pi.hThread)
        WIN::CloseHandle(pi.hThread);

    DebugMsg("[Info] Verification of Update returned %d\n", dwResult);

    return dwResult;
}
DWORD ExecuteUpgradeMsi(__in LPSTR szUpgradeMsi)
{
    DebugMsg("[Info] Running update package from --> %s\n", szUpgradeMsi);

    DWORD dwResult = 0;

    // build up CreateProcess structures
    STARTUPINFO          sui;
    PROCESS_INFORMATION  pi;

    memset((void*)&pi, 0x00, sizeof(PROCESS_INFORMATION));
    memset((void*)&sui, 0x00, sizeof(STARTUPINFO));
    sui.cb          = sizeof(STARTUPINFO);
    sui.dwFlags     = STARTF_USESHOWWINDOW;
    sui.wShowWindow = SW_SHOW;

    //
    // build command line and specify delayreboot option to Update
    //  three acounts for terminating null plus quotes for module
    DWORD cchCommandLine = lstrlen(szUpgradeMsi) + lstrlen(szDelayReboot) + 3;
    char *szCommandLine = new char[cchCommandLine];

    if (!szCommandLine)
    {
        dwResult = ERROR_OUTOFMEMORY;
        goto Return_ExecuteUpgradeMsi;
    }
    
    if (FAILED(StringCchCopy(szCommandLine, cchCommandLine, "\""))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, szUpgradeMsi))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, "\""))
        || FAILED(StringCchCat(szCommandLine, cchCommandLine, szDelayReboot)))
    {
        dwResult = ERROR_INSTALL_FAILURE;
        goto Return_ExecuteUpgradeMsi;
    }

    //
    // run update process
    if(!WIN::CreateProcess(NULL, szCommandLine, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sui, &pi))
    {
        // failed to launch.
        dwResult = GetLastError();
        goto Return_ExecuteUpgradeMsi;
    }

    dwResult = WaitForProcess(pi.hProcess);
    if(ERROR_SUCCESS != dwResult)
        goto Return_ExecuteUpgradeMsi;

    WIN::GetExitCodeProcess(pi.hProcess, &dwResult);

Return_ExecuteUpgradeMsi:

    if (szCommandLine)
        delete [] szCommandLine;
    if (pi.hProcess)
        WIN::CloseHandle(pi.hProcess);
    if (pi.hThread)
        WIN::CloseHandle(pi.hThread);

    return dwResult;
}
Example #6
0
int main(int argc, char ** argv)
{
    --argc;
    ++argv;

    if (argc == 0) {
        printf(
            "command line options:\n"
            " -captureall: record ALL processes (default).\n"
            " -process_name [exe name]: record specific process.\n"
            " -process_id [integer]: record specific process ID.\n"
            " -output_file [path]: override the default output path.\n"
            " -no_csv: do not create any output file.\n"
            );
        return 0;
    }

    int waitpid = -1;
    PresentMonArgs args;

    args.mTargetProcessName = "*";

    for (int i = 0; i < argc; ++i)
    {
        // 2-component arguments
        if (i + 1 < argc)
        {
            if (!strcmp(argv[i], "-waitpid"))
            {
                waitpid = atoi(argv[++i]);
            }
            else if (!strcmp(argv[i], "-process_name"))
            {
                args.mTargetProcessName = argv[++i];
            }
            else if (!strcmp(argv[i], "-process_id"))
            {
                args.mTargetPid = atoi(argv[++i]);
            }
            else if (!strcmp(argv[i], "-output_file"))
            {
                args.mOutputFileName = argv[++i];
            }
        }
        // 1-component args
        else
        {
            if (!strcmp(argv[i], "-no_csv"))
            {
                args.mOutputFileName = "*";
            }
        }
    }

    if (waitpid >= 0) {
        WaitForProcess(waitpid);
        if (!HaveAdministratorPrivilidges()) {
            printf("Elevation process failed. Aborting.\n");
            return 0;
        }
    }

    if (!HaveAdministratorPrivilidges()) {
        printf("Process is not running as admin. Attempting to elevate.\n");
        RestartAsAdministrator(argc, argv);
        return 0;
    }

    SetConsoleCtrlHandler(HandlerRoutine, TRUE);

    // Run PM in a separate thread so we can join it in the CtrlHandler (can't join the main thread)
    std::thread pm(PresentMonEtw, args);
    g_PresentMonThread = &pm;
    Sleep(INFINITE);
}