Ejemplo n.º 1
0
enum procerr
procRun(unsigned xnargs, char * const xargs[], int * rc)
{
	STARTUPINFOW si;
	PROCESS_INFORMATION pi;
	enum procerr err = ERR_PROC_OK;
	DWORD drc = 0;
	WCHAR args[MAXCMD];
	LPWSTR cl = GetCommandLineW();
	int argc;
	LPWSTR * wargv = CommandLineToArgvW(cl, &argc);
	argvToCommandLine(args, argc-4, wargv+4);
	LocalFree(wargv);
	memset(&si, 0, sizeof(si));
	si.cb = sizeof(si);
	CHK(ERR_PROC_FORK, !CreateProcessW(0, args, 0, 0, 0, CREATE_SUSPENDED, 0, 0, &si, &pi));
	if (err == ERR_PROC_OK)
		injectProcess(pi.hProcess);
	CHK(ERR_PROC_EXEC, -1 == ResumeThread(pi.hThread));
	CHK(ERR_PROC_WAIT, WAIT_OBJECT_0 != WaitForSingleObject(pi.hThread, INFINITE));
	CHK(ERR_PROC_WAIT, WAIT_OBJECT_0 != WaitForSingleObject(pi.hProcess, INFINITE));	
	CHK(ERR_PROC_WAIT, !GetExitCodeProcess(pi.hProcess, &drc));
	CHK(ERR_PROC_FORK, !CloseHandle(pi.hThread));	
	CHK(ERR_PROC_FORK, !CloseHandle(pi.hProcess));
	if (err == ERR_PROC_OK)
		*rc = drc;
	return err;
}
Ejemplo n.º 2
0
    cProcess(WCHAR* szAppName, WCHAR* szCommLine, BOOL Inherit,
	      DWORD CreateFlags, WCHAR* szCurrDir)
    {
	STARTUPINFOW st;
	PROCESS_INFORMATION	procinfo;

	st.lpReserved=NULL;
	st.cb = sizeof(STARTUPINFO);
	st.lpDesktop = NULL;
	st.lpTitle = NULL;
	st.dwFlags = 0;
	st.cbReserved2 = 0;
	st.lpReserved2 = NULL;
	ph = NULL;
	th = NULL;

	bRetVal = CreateProcessW(szAppName,szCommLine,NULL,NULL,
				 Inherit,CreateFlags,NULL,szCurrDir,
				 &st,&procinfo);

	if (bRetVal) {
	    ph = procinfo.hProcess;
	    th = procinfo.hThread;
	    pid = procinfo.dwProcessId;
	}

	pSetProcessAffinityMask = NULL;
	hLib = LoadLibrary("kernel32.dll");
	if (hLib != NULL)
		pSetProcessAffinityMask = (LPSetProcessAffinityMask)GetProcAddress(hLib, "SetProcessAffinityMask");
    }
Ejemplo n.º 3
0
//Called before StarCraft is completely loaded
extern "C" __declspec(dllexport) bool ApplyPatchSuspended(HANDLE, DWORD)
{
	if (GetFileAttributesW(WLAUNCHER) == 0xFFFFFFFF)
	{
		MessageBoxW(NULL, L"wLauncher.exe not found!", L"wDetector Plugin", MB_OK | MB_ICONERROR);
		return false;
	}

	if (GetFileAttributesW(WDETECTOR) == 0xFFFFFFFF)
	{
		MessageBoxW(NULL, L"wDetector.w not found!", L"wDetector Plugin", MB_OK | MB_ICONERROR);
		return false;
	}

	if (wcscmp(FileVersion(WDETECTOR), L"3.37") != 0)
	{
		MessageBoxW(NULL, L"wDetector's version is incorrect!", L"wDetector Plugin", MB_OK | MB_ICONERROR);
		return false;
	}

	STARTUPINFOW info = { sizeof(info) };

	if (!CreateProcessW(WLAUNCHER, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &info, &processInfo))
	{
		MessageBoxW(NULL, L"Failed to start wLauncher.exe!", L"wDetector Plugin", MB_OK | MB_ICONERROR);
		return false;
	}

	return true;
}
Ejemplo n.º 4
0
/**
 * This function runs the specified command in the specified dir.
 * [in,out] cmdline - the command line to run. The function may change the passed buffer.
 * [in] dir - the dir to run the command in. If it is NULL, then the current dir is used.
 * [in] wait - whether to wait for the run program to finish before returning.
 * [in] minimized - Whether to ask the program to run minimized.
 *
 * Returns:
 * If running the process failed, returns INVALID_RUNCMD_RETURN. Use GetLastError to get the error code.
 * If wait is FALSE - returns 0 if successful.
 * If wait is TRUE - returns the program's return value.
 */
static int runCmd(LPWSTR cmdline, LPCWSTR dir, BOOL wait, BOOL minimized)
{
    STARTUPINFOW si;
    PROCESS_INFORMATION info;
    DWORD exit_code=0;

    memset(&si, 0, sizeof(si));
    si.cb=sizeof(si);
    if (minimized)
    {
        si.dwFlags=STARTF_USESHOWWINDOW;
        si.wShowWindow=SW_MINIMIZE;
    }
    memset(&info, 0, sizeof(info));

    if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, dir, &si, &info))
    {
        printf("Failed to run command (%ld)\n", GetLastError());

        return INVALID_RUNCMD_RETURN;
    }

    printf("Successfully ran command\n"); //%s - Created process handle %p\n",
               //wine_dbgstr_w(cmdline), info.hProcess);

    if (wait)
    {   /* wait for the process to exit */
        WaitForSingleObject(info.hProcess, INFINITE);
        GetExitCodeProcess(info.hProcess, &exit_code);
    }

    CloseHandle(info.hProcess);

    return exit_code;
}
Ejemplo n.º 5
0
static BOOL StartLinkProcessor(LPCOLESTR szLink)
{
    static const WCHAR szFormat[] = {
        'w','i','n','e','m','e','n','u','b','u','i','l','d','e','r','.','e','x','e',
        ' ','-','w',' ','-','u',' ','"','%','s','"',0 };
    LONG len;
    LPWSTR buffer;
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    BOOL ret;

    len = sizeof(szFormat) + lstrlenW( szLink ) * sizeof(WCHAR);
    buffer = heap_alloc( len );
    if( !buffer )
        return FALSE;

    wsprintfW( buffer, szFormat, szLink );

    TRACE("starting %s\n",debugstr_w(buffer));

    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);

    ret = CreateProcessW( NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );

    HeapFree( GetProcessHeap(), 0, buffer );

    if (ret)
    {
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }

    return ret;
}
Ejemplo n.º 6
0
static BOOL start_rpcss(void)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR cmd[MAX_PATH];
    static const WCHAR rpcss[] = {'\\','r','p','c','s','s','.','e','x','e',0};
    BOOL rslt;
    void *redir;

    TRACE("\n");

    ZeroMemory(&si, sizeof(STARTUPINFOA));
    si.cb = sizeof(STARTUPINFOA);
    GetSystemDirectoryW( cmd, MAX_PATH - sizeof(rpcss)/sizeof(WCHAR) );
    strcatW( cmd, rpcss );

    Wow64DisableWow64FsRedirection( &redir );
    rslt = CreateProcessW( cmd, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi );
    Wow64RevertWow64FsRedirection( redir );

    if (rslt)
    {
        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        Sleep(100);
    }

    return rslt;
}
Ejemplo n.º 7
0
/*
 * Attempt to simulate fork/execve on Windows
 */
int
openvpn_execve (const struct argv *a, const struct env_set *es, const unsigned int flags)
{
  int ret = -1;
  static bool exec_warn = false;

  if (a && a->argv[0])
    {
      if (openvpn_execve_allowed (flags))
	{
          struct gc_arena gc = gc_new ();
          STARTUPINFOW start_info;
          PROCESS_INFORMATION proc_info;

          char *env = env_block (es);
          WCHAR *cl = wide_cmd_line (a, &gc);
          WCHAR *cmd = wide_string (a->argv[0], &gc);

          CLEAR (start_info);
          CLEAR (proc_info);

          /* fill in STARTUPINFO struct */
          GetStartupInfoW(&start_info);
          start_info.cb = sizeof(start_info);
          start_info.dwFlags = STARTF_USESHOWWINDOW;
          start_info.wShowWindow = SW_HIDE;

          /* this allows console programs to run, and is ignored otherwise */
          DWORD proc_flags = CREATE_NO_WINDOW;

          if (CreateProcessW (cmd, cl, NULL, NULL, FALSE, proc_flags, env, NULL, &start_info, &proc_info))
            {
              DWORD exit_status = 0;
              CloseHandle (proc_info.hThread);
              WaitForSingleObject (proc_info.hProcess, INFINITE);
              if (GetExitCodeProcess (proc_info.hProcess, &exit_status))
                ret = (int)exit_status;
              else
                msg (M_WARN|M_ERRNO, "openvpn_execve: GetExitCodeProcess %S failed", cmd);
              CloseHandle (proc_info.hProcess);
            }
          else
            {
              msg (M_WARN|M_ERRNO, "openvpn_execve: CreateProcess %S failed", cmd);
            }
          free (env);
          gc_free (&gc);
        }
      else if (!exec_warn && (script_security < SSEC_SCRIPTS))
	{
	  msg (M_WARN, SCRIPT_SECURITY_WARNING);
          exec_warn = true;
	}
    }
  else
    {
      msg (M_WARN, "openvpn_execve: called with empty argv");
    }
  return ret;
}
Ejemplo n.º 8
0
static BOOL WINAPI
MyCreateProcessW(LPCWSTR lpApplicationName,
                 LPWSTR lpCommandLine,
                 LPSECURITY_ATTRIBUTES lpProcessAttributes,
                 LPSECURITY_ATTRIBUTES lpThreadAttributes,
                 BOOL bInheritHandles,
                 DWORD dwCreationFlags,
                 LPVOID lpEnvironment,
                 LPCWSTR lpCurrentDirectory,
                 LPSTARTUPINFOW lpStartupInfo,
                 LPPROCESS_INFORMATION lpProcessInformation)
{
    if (VERBOSITY >= 2) {
        debugPrintf("inject: intercepting %s(\"%S\", \"%S\", ...)\n",
                    __FUNCTION__,
                    lpApplicationName,
                    lpCommandLine);
    }

    BOOL bRet;
    bRet = CreateProcessW(lpApplicationName,
                          lpCommandLine,
                          lpProcessAttributes,
                          lpThreadAttributes,
                          bInheritHandles,
                          dwCreationFlags | CREATE_SUSPENDED,
                          lpEnvironment,
                          lpCurrentDirectory,
                          lpStartupInfo,
                          lpProcessInformation);

    MyCreateProcessCommon(bRet, dwCreationFlags, lpProcessInformation);

    return bRet;
}
Ejemplo n.º 9
0
void AutoUpdateChecker::TriggerUpdate(const AutoUpdateChecker::NewVersionInformation& info)
{
#ifdef _WIN32
  std::map<std::string, std::string> updater_flags;
  updater_flags["this-manifest-url"] = info.this_manifest_url;
  updater_flags["next-manifest-url"] = info.next_manifest_url;
  updater_flags["content-store-url"] = info.content_store_url;
  updater_flags["parent-pid"] = std::to_string(GetCurrentProcessId());
  updater_flags["install-base-path"] = File::GetExeDirectory();
  updater_flags["log-file"] = File::GetExeDirectory() + DIR_SEP + UPDATER_LOG_FILE;

  // Copy the updater so it can update itself if needed.
  std::string updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_FILENAME;
  std::string reloc_updater_path = File::GetExeDirectory() + DIR_SEP + UPDATER_RELOC_FILENAME;
  File::Copy(updater_path, reloc_updater_path);

  // Run the updater!
  std::wstring command_line = MakeUpdaterCommandLine(updater_flags);
  STARTUPINFO sinfo = {sizeof(info)};
  PROCESS_INFORMATION pinfo;
  INFO_LOG(COMMON, "Updater command line: %s", UTF16ToUTF8(command_line).c_str());
  if (!CreateProcessW(UTF8ToUTF16(reloc_updater_path).c_str(),
                      const_cast<wchar_t*>(command_line.c_str()), nullptr, nullptr, FALSE, 0,
                      nullptr, nullptr, &sinfo, &pinfo))
  {
    ERROR_LOG(COMMON, "Could not start updater process: error=%d", GetLastError());
  }
#endif
}
Ejemplo n.º 10
0
BOOL WINAPI MyCreateProcessW( LPCWSTR lpApplicationName,
			      LPWSTR lpCommandLine,
			      LPSECURITY_ATTRIBUTES lpThreadAttributes,
			      LPSECURITY_ATTRIBUTES lpProcessAttributes,
			      BOOL bInheritHandles,
			      DWORD dwCreationFlags,
			      LPVOID lpEnvironment,
			      LPCWSTR lpCurrentDirectory,
			      LPSTARTUPINFOW lpStartupInfo,
			      LPPROCESS_INFORMATION lpProcessInformation )
{
  PROCESS_INFORMATION pi;

  if (!CreateProcessW( lpApplicationName,
		       lpCommandLine,
		       lpThreadAttributes,
		       lpProcessAttributes,
		       bInheritHandles,
		       dwCreationFlags | CREATE_SUSPENDED,
		       lpEnvironment,
		       lpCurrentDirectory,
		       lpStartupInfo,
		       &pi ))
    return FALSE;

  DEBUGSTR( L"CreateProcessW: \"%s\", \"%s\"",
	    (lpApplicationName == NULL) ? L"" : lpApplicationName,
	    (lpCommandLine == NULL) ? L"" : lpCommandLine );
  Inject( &pi, lpProcessInformation, dwCreationFlags );

  return TRUE;
}
Ejemplo n.º 11
0
DWORD Exec(MSIHANDLE hModule,
           const WCHAR *pwszAppName, WCHAR *pwszCmdLine, const WCHAR *pwszWorkDir,
           DWORD *pdwExitCode)
{
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    DWORD rc = ERROR_SUCCESS;

    ZeroMemory(&si, sizeof(si));
    si.dwFlags = STARTF_USESHOWWINDOW;
#ifdef UNICODE
    si.dwFlags |= CREATE_UNICODE_ENVIRONMENT;
#endif
    si.wShowWindow = SW_HIDE; /* For debugging: SW_SHOW; */
    si.cb = sizeof(si);
    ZeroMemory(&pi, sizeof(pi));

    logStringW(hModule, L"Executing command line: %s %s (Working Dir: %s)",
               pwszAppName, pwszCmdLine, pwszWorkDir == NULL ? L"Current" : pwszWorkDir);

    SetLastError(0);
    if (!CreateProcessW(pwszAppName,  /* Module name. */
                        pwszCmdLine,  /* Command line. */
                        NULL,         /* Process handle not inheritable. */
                        NULL,         /* Thread handle not inheritable. */
                        FALSE,        /* Set handle inheritance to FALSE .*/
                        0,            /* No creation flags. */
                        NULL,         /* Use parent's environment block. */
                        pwszWorkDir,  /* Use parent's starting directory. */
                        &si,          /* Pointer to STARTUPINFO structure. */
                        &pi))         /* Pointer to PROCESS_INFORMATION structure. */
    {
        rc = GetLastError();
        logStringW(hModule, L"Executing command line: CreateProcess() failed! Error: %ld", rc);
        return rc;
    }

    /* Wait until child process exits. */
    if (WAIT_FAILED == WaitForSingleObject(pi.hProcess, 30 * 1000 /* Wait 30 secs max. */))
    {
        rc = GetLastError();
        logStringW(hModule, L"Executing command line: WaitForSingleObject() failed! Error: %u", rc);
    }
    else
    {
        if (!GetExitCodeProcess(pi.hProcess, pdwExitCode))
        {
            rc = GetLastError();
            logStringW(hModule, L"Executing command line: GetExitCodeProcess() failed! Error: %u", rc);
        }
    }

    /* Close process and thread handles. */
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);

    logStringW(hModule, L"Executing command returned: %u (exit code %u)", rc, *pdwExitCode);
    return rc;
}
Ejemplo n.º 12
0
/*
** Implementation of system() - requires wide char conversion
*/
RTEXP	int system( const char *command ) {
	wchar_t					wcmdline[BUFSIZ];
	BOOL					ret;
	PROCESS_INFORMATION		pi;
	MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, command, -1, wcmdline, BUFSIZ);
	ret = CreateProcessW(wcmdline, NULL, NULL, NULL, (BOOL)NULL, CREATE_NEW_CONSOLE, NULL, NULL, NULL, &pi);
	return(0);
}
Ejemplo n.º 13
0
void SessionProcess::exec(const Configuration& config,
			  boost::function<void (bool)> onReady)
{
#ifndef WT_WIN32
  std::string parentPortOption = std::string("--parent-port=")
    + boost::lexical_cast<std::string>(acceptor_->local_endpoint().port());
  const std::vector<std::string> &options = config.options();
  const char **c_options = new const char*[options.size() + 2];
  std::size_t i = 0;
  for (; i < options.size(); ++i) {
    c_options[i] = options[i].c_str();
  }
  c_options[i] = parentPortOption.c_str();
  ++i;
  c_options[i] = 0;

  pid_ = fork();
  if (pid_ < 0) {
    LOG_ERROR("failed to fork dedicated session process, error code: " << errno);
    stop();
    if (!onReady.empty()) {
      onReady(false);
    }
    return;
  } else if (pid_ == 0) {
#ifdef WT_THREADED
    sigset_t mask;
    sigfillset(&mask);
    pthread_sigmask(SIG_UNBLOCK, &mask, 0);
#endif // WT_THREADED

    execv(c_options[0], const_cast<char *const *>(c_options));
    // An error occurred, this should not be reached
    exit(1);
  }

  delete[] c_options;
#else // WT_WIN32
  STARTUPINFOW startupInfo;
  ZeroMemory(&startupInfo, sizeof(startupInfo));
  startupInfo.cb = sizeof(startupInfo);

  std::wstring commandLine = GetCommandLineW();
  commandLine += L" --parent-port=" + boost::lexical_cast<std::wstring>(acceptor_->local_endpoint().port());
  LPWSTR c_commandLine = new wchar_t[commandLine.size() + 1];
  wcscpy(c_commandLine, commandLine.c_str());

  if(!CreateProcessW(0, c_commandLine, 0, 0, true,
      0, 0, 0, &startupInfo, &processInfo_)) {
    LOG_ERROR("failed to start dedicated session process, error code: " << GetLastError());
    stop();
    if (!onReady.empty()) {
      onReady(false);
    }
  }
  delete c_commandLine;
#endif // WT_WIN32
}
Ejemplo n.º 14
0
static DWORD service_start_process(struct service_entry *service_entry, HANDLE *process)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    LPWSTR path = NULL;
    DWORD size;
    BOOL r;

    service_lock_exclusive(service_entry);

    if (service_entry->config.dwServiceType == SERVICE_KERNEL_DRIVER)
    {
        static const WCHAR winedeviceW[] = {'\\','w','i','n','e','d','e','v','i','c','e','.','e','x','e',' ',0};
        DWORD len = GetSystemDirectoryW( NULL, 0 ) + sizeof(winedeviceW)/sizeof(WCHAR) + strlenW(service_entry->name);

        if (!(path = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
            return ERROR_NOT_ENOUGH_SERVER_MEMORY;
        GetSystemDirectoryW( path, len );
        lstrcatW( path, winedeviceW );
        lstrcatW( path, service_entry->name );
    }
    else
    {
        size = ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,NULL,0);
        path = HeapAlloc(GetProcessHeap(),0,size*sizeof(WCHAR));
        if (!path)
            return ERROR_NOT_ENOUGH_SERVER_MEMORY;
        ExpandEnvironmentStringsW(service_entry->config.lpBinaryPathName,path,size);
    }

    ZeroMemory(&si, sizeof(STARTUPINFOW));
    si.cb = sizeof(STARTUPINFOW);
    if (!(service_entry->config.dwServiceType & SERVICE_INTERACTIVE_PROCESS))
    {
        static WCHAR desktopW[] = {'_','_','w','i','n','e','s','e','r','v','i','c','e','_','w','i','n','s','t','a','t','i','o','n','\\','D','e','f','a','u','l','t',0};
        si.lpDesktop = desktopW;
    }

    service_entry->status.dwCurrentState = SERVICE_START_PENDING;

    service_unlock(service_entry);

    r = CreateProcessW(NULL, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
    HeapFree(GetProcessHeap(),0,path);
    if (!r)
    {
        service_lock_exclusive(service_entry);
        service_entry->status.dwCurrentState = SERVICE_STOPPED;
        service_unlock(service_entry);
        return GetLastError();
    }

    service_entry->status.dwProcessId = pi.dwProcessId;
    *process = pi.hProcess;
    CloseHandle( pi.hThread );

    return ERROR_SUCCESS;
}
Ejemplo n.º 15
0
DWORD KCallInfocSend::_LaunchAppEx(LPCWSTR lpczApp, LPWSTR lpszCmdLine, BOOL bWait, PDWORD pdwExitCode/*=NULL*/, BOOL bShowWnd/*=TRUE*/)
{
	DWORD dwResult = -1;	

	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	ZeroMemory(&pi, sizeof(pi));

	si.dwFlags = STARTF_USESHOWWINDOW;
	if (bShowWnd == FALSE)
		si.wShowWindow = SW_HIDE;
	else
		si.wShowWindow = SW_SHOW;

	// Start the child process. 
	if	( !CreateProcessW( 
						lpczApp, 
						lpszCmdLine, 
						NULL,              
						NULL,             
						TRUE,           
						0,               
						NULL,            
						NULL,            
						&si,             
						&pi)
		)          
	{
		dwResult = GetLastError();
		OutputDebugString(L"_LaunchAppEx:error");
		goto Exit0;
	}

	if (bWait)
	{
		if (WaitForSingleObject(pi.hProcess, defMAXWAITPROCESSTIME) == WAIT_OBJECT_0)
			if (pdwExitCode)
				GetExitCodeProcess(pi.hProcess, pdwExitCode);	
	}

	dwResult = 0;
Exit0:
	if (pi.hProcess != NULL)
	{
		CloseHandle(pi.hProcess);
		pi.hProcess = NULL;
	}
	if (pi.hThread != NULL)
	{
		CloseHandle(pi.hThread);
		pi.hThread = NULL;
	}

	return dwResult;
}
Ejemplo n.º 16
0
bool CResourceCompilerHelper::InvokeResourceCompiler( const char *szSrcFile, const bool bWindow ) const
{
	bool bRet = true;

	// make command for execution

	wchar_t wMasterCDDir[512];
	GetCurrentDirectoryW(512,wMasterCDDir);

	SettingsManagerHelpers::CFixedString<wchar_t, 512> wRemoteCmdLine;
	SettingsManagerHelpers::CFixedString<wchar_t, 512> wDir;

	wRemoteCmdLine.appendAscii("Bin32/rc/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);
	wRemoteCmdLine.appendAscii(" \"");
	wRemoteCmdLine.append(wMasterCDDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szSrcFile);
	wRemoteCmdLine.appendAscii("\" /userdialog=0");

	wDir.append(wMasterCDDir);
	wDir.appendAscii("\\Bin32\\rc");

	STARTUPINFOW si;
	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory( &pi, sizeof(pi) );

	if (!CreateProcessW( 
		NULL,     // No module name (use command line). 
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line. 
		NULL,     // Process handle not inheritable. 
		NULL,     // Thread handle not inheritable. 
		FALSE,    // Set handle inheritance to FALSE. 
		bWindow?0:CREATE_NO_WINDOW,	// creation flags. 
		NULL,     // Use parent's environment block. 
		wDir.c_str(),  // Set starting directory. 
		&si,      // Pointer to STARTUPINFO structure.
		&pi))     // Pointer to PROCESS_INFORMATION structure.
	{
		bRet = false;
	}

	// Wait until child process exits.
	WaitForSingleObject( pi.hProcess, INFINITE );

	// Close process and thread handles. 
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	return bRet;
}
Ejemplo n.º 17
0
/**
 * Constructs a CProcess object and uses the CreateProcessW function to start the process immediately.
 *
 * @param CommandLine
 * A std::wstring containing the command line to run
 *
 * @param StartupInfo
 * Pointer to a STARTUPINFOW structure containing process startup information
 */
CProcess::CProcess(const wstring& CommandLine, LPSTARTUPINFOW StartupInfo)
{
    auto_array_ptr<WCHAR> CommandLinePtr(new WCHAR[CommandLine.size() + 1]);

    wcscpy(CommandLinePtr, CommandLine.c_str());

    if(!CreateProcessW(NULL, CommandLinePtr, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &m_ProcessInfo))
        TESTEXCEPTION("CreateProcessW failed\n");
}
Ejemplo n.º 18
0
static RVOID
    relaunchInPermanentLocation
    (

    )
{
    RPWCHAR bootstrapLocations[] = { _WCH( "%SYSTEMDRIVE%\\$Recycle.Bin\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%SYSTEMDRIVE%\\RECYCLER\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%windir%\\system32\\tasks\\MALWARE_DEMO_WINDOWS_1.exe" ),
                                     _WCH( "%USERPROFILE%\\MALWARE_DEMO_WINDOWS_1.exe" ) };
    RU32 i = 0;

    STARTUPINFOW startupInfo = {0};
    PROCESS_INFORMATION procInfo = {0};
    RPWCHAR expandedPath = NULL;

    for( i = 0; i < ARRAY_N_ELEM( bootstrapLocations ); i++ )
    {
        rpal_debug_info( "trying to move to bootstrap location %d...", i );
        rpal_file_delete( bootstrapLocations[ i ], FALSE );
        if( rpal_file_move( g_self_path, bootstrapLocations[ i ] ) )
        {
            rpal_debug_info( "successfully moved to bootstrap location!" );

            rpal_debug_info( "launching in new location (%ls)...", bootstrapLocations[ i ] );
            if( rpal_string_expand( bootstrapLocations[ i ], &expandedPath ) &&
                0 != CreateProcessW( expandedPath, 
                                     NULL, 
                                     NULL, 
                                     NULL, 
                                     FALSE, 
                                     CREATE_NO_WINDOW, 
                                     NULL, 
                                     NULL, 
                                     &startupInfo, 
                                     &procInfo ) )
            {
                rpal_debug_info( "successfully launched from new location." );
            }
            else
            {
                rpal_debug_error( "error launching from permanent location: %d.", GetLastError() );
            }

            if( NULL != expandedPath )
            {
                rpal_memory_free( expandedPath );
            }

            break;
        }
        else
        {
            rpal_debug_warning( "could not move to new bootstrap location, may not have permission..." );
        }
    }
}
Ejemplo n.º 19
0
void ProcessWin::ForkAndExec()
{
    nativeIn->CreateHandles();
    nativeOut->CreateHandles();
    nativeErr->CreateHandles();

    STARTUPINFO startupInfo;
    startupInfo.cb          = sizeof(STARTUPINFO);
    startupInfo.lpReserved  = NULL;
    startupInfo.lpDesktop   = NULL;
    startupInfo.lpTitle     = NULL;
    startupInfo.dwFlags     = STARTF_FORCEOFFFEEDBACK | STARTF_USESTDHANDLES;
    startupInfo.cbReserved2 = 0;
    startupInfo.lpReserved2 = NULL;
    //startupInfo.hStdInput = nativeIn->GetReadHandle();
    //startupInfo.hStdOutput = nativeOut->GetWriteHandle();
    //startupInfo.hStdError = nativeErr->GetWriteHandle();
    
    HANDLE hProc = GetCurrentProcess();
    nativeIn->DuplicateRead(hProc, &startupInfo.hStdInput);
    nativeOut->DuplicateWrite(hProc, &startupInfo.hStdOutput);
    nativeErr->DuplicateWrite(hProc, &startupInfo.hStdError);
    
    std::string commandLine(ArgListToString(args));
    std::wstring commandLineW(::UTF8ToWide(commandLine));
    logger->Debug("Launching: %s", commandLine.c_str());

    PROCESS_INFORMATION processInfo;
    BOOL rc = CreateProcessW(NULL,
        (wchar_t*) commandLineW.c_str(),
        NULL,
        NULL,
        TRUE,
        CREATE_NO_WINDOW, // If this is a console application,
           NULL,             // don't open a console window.
        NULL,
        &startupInfo,
        &processInfo);
    
    //CloseHandle(nativeIn->GetReadHandle());
    
    CloseHandle(startupInfo.hStdInput);
    CloseHandle(startupInfo.hStdOutput);
    CloseHandle(startupInfo.hStdError);
    
    if (!rc) {
        std::string message = "Error launching: " + commandLine;
        logger->Error(message);
        throw ValueException::FromString(message);
    }
    else {
        CloseHandle(processInfo.hThread);
        this->pid = processInfo.dwProcessId;
        this->process = processInfo.hProcess;
        this->running = true;
    }
}
Ejemplo n.º 20
0
unsigned WINAPI run_process(void * pParam)
{
    PROCESS_INFORMATION pi;
    STARTUPINFOW si;
    WCHAR wcmd[VALUE_LEN+1] = {0};
    WCHAR wdirectory[VALUE_LEN+1] = {0};
    DWORD dwCreat = 0;
    int flags = get_parameters(wdirectory, wcmd, VALUE_LEN);
    if (flags<0)
    {
        return (0);
    }
    /* 如果是预启动,直接返回 */
    if ( parse_shcommand() )
    {
        return (0);
    }
    if ( GetLastError() == ERROR_ALREADY_EXISTS )
    {
        return (0);
    }
    if ( wcslen(wcmd)>0  && !search_process(wcmd,0) )
    {
        fzero(&si,sizeof(si));
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_MINIMIZE;
        if (!flags)
        {
            si.wShowWindow = SW_HIDE;
            dwCreat |= CREATE_NEW_PROCESS_GROUP;
        }
        if(!CreateProcessW(NULL,
                           (LPWSTR)wcmd,
                           NULL,
                           NULL,
                           FALSE,
                           dwCreat,
                           NULL,
                           (LPCWSTR)wdirectory,
                           &si,&pi))
        {
#ifdef _LOGDEBUG
            logmsg("CreateProcessW error %lu\n",GetLastError());
#endif
            return (0);
        }
        g_handle[0] = pi.hProcess;
        CloseHandle(pi.hThread);
        if ( pi.dwProcessId >4 && (SleepEx(6000,FALSE) == 0) )
        {
            search_process(NULL, pi.dwProcessId);
        }
    }
    return (1);
}
Ejemplo n.º 21
0
DWORD WINAPI RunAndTrace()
{
	STARTUPINFO	siStartupInfo;
	CONTEXT	ctxMainThread;

	ZeroMemory(&siStartupInfo,sizeof(siStartupInfo));
	ZeroMemory(&piProcInfo,sizeof(piProcInfo));
	siStartupInfo.cb = sizeof(STARTUPINFO);
	ctxMainThread.ContextFlags = CONTEXT_FULL;

	if(CreateProcessW(tcNewFilePath,
		NULL,
		NULL,
		NULL,
		FALSE,
		CREATE_SUSPENDED | DEBUG_ONLY_THIS_PROCESS,
		NULL,
		NULL,
		&siStartupInfo,
		&piProcInfo))
	{
		if(!GetThreadContext(piProcInfo.hThread,&ctxMainThread))
		{
			TerminateProcess(piProcInfo.hProcess,-1);
			MessageBoxA(hwDlgMainFrame,"ERROR: Couldn´t read Thread Context!",szAppName,MB_OK);
			return 0;
		}

		ctxMainThread.EFlags |= 0x100;

		if(!SetThreadContext(piProcInfo.hThread,&ctxMainThread))
		{
			TerminateProcess(piProcInfo.hProcess,-1);
			MessageBoxA(hwDlgMainFrame,"ERROR: Couldn´t write Thread Context!",szAppName,MB_OK);
			return 0;
		}

		pSymbol = (PSYMBOL_INFO)malloc(sizeof(SYMBOL_INFO) + MAX_SYM_NAME);
		bDebugging = true;
		bCutDownLog = SendMessage(GetDlgItem(hwDlgMainFrame,IDC_CUTLOG),BM_GETCHECK,NULL,NULL) == BST_CHECKED ? true : false;
		bDisableNTDLLLogging = SendMessage(GetDlgItem(hwDlgMainFrame,IDC_NTLOGCHECK),BM_GETCHECK,NULL,NULL) == BST_CHECKED ? true : false;

		CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)UpdateStats,NULL,NULL,NULL);
		ResumeThread(piProcInfo.hThread);
		DebuggingLoop();
		CloseHandle(hLogFile);
		free(pSymbol);
	}
	else
	{
		MessageBoxA(hwDlgMainFrame,"ERROR: Unable to start process!",szAppName,MB_OK);
		SetDlgItemText(hwDlgMainFrame,IDC_STATE,L"State: ERROR!");
	}
	bTracing = false;
	return 1;
}
Ejemplo n.º 22
0
int execute_file(const boost::filesystem::wpath & path, const std::vector<std::wstring> & arguments, void ** handle)
{    
#if !BOOST_WINDOWS
    std::string fname = mstd::utf8fname(path);
    std::vector<std::string> args;
    args.reserve(arguments.size());
    std::vector<char*> argv;
    argv.reserve(arguments.size() + 2);
    argv.push_back(const_cast<char*>(fname.c_str()));
    for(std::vector<std::wstring>::const_iterator i = arguments.begin(), end = arguments.end(); i != end; ++i)
    {
        args.push_back(utf8(*i));
        argv.push_back(const_cast<char*>(args.back().c_str()));
    }
    argv.push_back(0);
    int result = vfork();
    if(!result)
    {
        execv(fname.c_str(), &argv[0]);
        _exit(0);
    }
    return result;
#else
    STARTUPINFOW si;
    PROCESS_INFORMATION pi;
    HANDLE ipipe = 0, opipe = 0;
    CreatePipe(&ipipe, &opipe, 0, 0);
    memset(&si, 0, sizeof(si));
    si.hStdInput = ipipe;
    si.hStdOutput = si.hStdError = opipe;
    memset(&pi, 0, sizeof(pi));
    si.cb = sizeof(si);
    boost::filesystem::wpath parent = path;
    parent.remove_filename();
    std::wstring command = escape(wfname(path));
    for(std::vector<std::wstring>::const_iterator i = arguments.begin(), end = arguments.end(); i != end; ++i)
    {
        command += L' ';
        command += escape(*i);
    }

    if(CreateProcessW(NULL, const_cast<wchar_t*>(command.c_str()), NULL, NULL, true, 0, NULL, wfname(parent).c_str(), &si, &pi))
    {
        if(handle)
            *handle = pi.hProcess;
        else
            CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
        return pi.dwProcessId;
    } else {
        if(handle)
            *handle = INVALID_HANDLE_VALUE;
        return -1;
    }
#endif
}
Ejemplo n.º 23
0
void run_proc(std::string command_line) {
	report_info("Running: " + command_line);
	// execute the process
	STARTUPINFO startup_info = { 0 };
	startup_info.cb = sizeof(startup_info);
	PROCESS_INFORMATION process_info = { 0 };
	CreateProcessW(NULL, const_cast<char16 *>(utf8::cvt<std::wstring>(command_line).c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &startup_info, &process_info);
	CloseHandle(process_info.hProcess);
	CloseHandle(process_info.hThread);
}
Ejemplo n.º 24
0
BOOL
WinLaunchChild(const PRUnichar *exePath, int argc, PRUnichar **argv, int needElevation)
{
  PRUnichar *cl;
  BOOL ok;
  if (needElevation > 0) {
    cl = MakeCommandLine(argc - 1, argv + 1);
    if (!cl)
      return FALSE;
    ok = ShellExecuteW(NULL, // no special UI window
                       NULL, // use default verb
                       exePath,
                       cl,
                       NULL, // use my current directory
                       SW_SHOWDEFAULT) > (HINSTANCE)32;
    free(cl);
    return ok;
  }

  cl = MakeCommandLine(argc, argv);
  if (!cl)
    return FALSE;

  if (needElevation < 0) {
    // try to launch as a normal user first
    ok = LaunchAsNormalUser(exePath, cl);
    // if it fails, fallback to normal launching
    if (!ok)
      needElevation = 0;
  }
  if (needElevation == 0) {
    STARTUPINFOW si = {sizeof(si), 0};
    PROCESS_INFORMATION pi = {0};

    ok = CreateProcessW(exePath,
                        cl,
                        NULL,  // no special security attributes
                        NULL,  // no special thread attributes
                        FALSE, // don't inherit filehandles
                        0,     // No special process creation flags
                        NULL,  // inherit my environment
                        NULL,  // use my current directory
                        &si,
                        &pi);

    if (ok) {
      CloseHandle(pi.hProcess);
      CloseHandle(pi.hThread);
    }
  }

  free(cl);

  return ok;
}
Ejemplo n.º 25
0
static BOOL RunHelper(const wchar_t *pEXEName)
{
	wchar_t *pFileName;
	BOOL good;
	STARTUPINFOW si;
	PROCESS_INFORMATION pi;

	{
		DWORD moduleFileNameSize=32768;
		wchar_t *pModuleFileName=LocalAlloc(0,moduleFileNameSize*sizeof *pModuleFileName);
		wchar_t *p;
		wchar_t *pLastSep=pModuleFileName;
		DWORD fileNameSize;

		GetModuleFileNameW(NULL,pModuleFileName,moduleFileNameSize);
		pModuleFileName[moduleFileNameSize-1]=0;

		for(p=pModuleFileName;*p!=0;p=CharNextW(p))
		{
			if(*p==L'\\'||*p==L'/')
				pLastSep=p;
		}

		*pLastSep=0;

		fileNameSize=lstrlenW(pModuleFileName)+1+lstrlenW(pEXEName)+1;
		pFileName=LocalAlloc(0,fileNameSize*sizeof pFileName);

		lstrcpyW(pFileName,pModuleFileName);
		lstrcatW(pFileName,L"\\");
		lstrcatW(pFileName,pEXEName);

		LocalFree(pModuleFileName);
		pModuleFileName=NULL;
	}

	si=SI_ZERO;
	si.cb=sizeof si;

	good=CreateProcessW(pFileName,NULL,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);
	if(!good)
	{
		DWORD err=GetLastError();
		wchar_t msg[500];

		FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM,NULL,err,0,msg,sizeof msg/sizeof msg[0],NULL);

		MessageBoxW(NULL,msg,pFileName,MB_OK|MB_ICONERROR);
	}

	LocalFree(pFileName);
	pFileName=NULL;

	return good;
}
Ejemplo n.º 26
0
int pyi_utils_create_child(const char *thisfile, const int argc, char *const argv[])
{
	SECURITY_ATTRIBUTES sa;
	STARTUPINFOW si;
	PROCESS_INFORMATION pi;
	int rc = 0;
    wchar_t buffer[PATH_MAX];

    // TODO is there a replacement for this conversion or just use wchar_t everywhere?
    /* Convert file name to wchar_t from utf8. */
    pyi_win32_utils_from_utf8(buffer, thisfile, PATH_MAX);

	// the parent process should ignore all signals it can
	signal(SIGABRT, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGBREAK, SIG_IGN);

	VS("LOADER: Setting up to run child\n");
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	GetStartupInfoW(&si);
	si.lpReserved = NULL;
	si.lpDesktop = NULL;
	si.lpTitle = NULL;
	si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_NORMAL;
	si.hStdInput = (void*)_get_osfhandle(fileno(stdin));
	si.hStdOutput = (void*)_get_osfhandle(fileno(stdout));
	si.hStdError = (void*)_get_osfhandle(fileno(stderr));

	VS("LOADER: Creating child process\n");
	if (CreateProcessW( 
			buffer,  // Pointer to name of executable module.
			GetCommandLineW(),  // pointer to command line string 
			&sa,  // pointer to process security attributes 
			NULL,  // pointer to thread security attributes 
			TRUE,  // handle inheritance flag 
			0,  // creation flags 
			NULL,  // pointer to new environment block 
			NULL,  // pointer to current directory name 
			&si,  // pointer to STARTUPINFO 
			&pi  // pointer to PROCESS_INFORMATION 
			)) {
		VS("LOADER: Waiting for child process to finish...\n");
		WaitForSingleObject(pi.hProcess, INFINITE);
		GetExitCodeProcess(pi.hProcess, (unsigned long *)&rc);
	} else {
		FATALERROR("Error creating child process!\n");
		rc = -1;
	}
	return rc;
}
Ejemplo n.º 27
0
WRes CProcess::Create(LPCWSTR imageName, const UString &params, LPCWSTR curDir)
{
  Close();
  const UString params2 =
      #ifndef UNDER_CE
      GetQuotedString(imageName) + L' ' +
      #endif
      params;
  #ifdef UNDER_CE
  curDir = 0;
  #else
  imageName = 0;
  #endif
  PROCESS_INFORMATION pi;
  BOOL result;
  #ifndef _UNICODE
  if (!g_IsNT)
  {
    STARTUPINFOA si;
    si.cb = sizeof(si);
    si.lpReserved = 0;
    si.lpDesktop = 0;
    si.lpTitle = 0;
    si.dwFlags = 0;
    si.cbReserved2 = 0;
    si.lpReserved2 = 0;
    
    CSysString curDirA;
    if (curDir != 0)
      curDirA = GetSystemString(curDir);
    result = ::CreateProcessA(NULL, (LPSTR)(LPCSTR)GetSystemString(params2),
        NULL, NULL, FALSE, 0, NULL, ((curDir != 0) ? (LPCSTR)curDirA: 0), &si, &pi);
  }
  else
  #endif
  {
    STARTUPINFOW si;
    si.cb = sizeof(si);
    si.lpReserved = 0;
    si.lpDesktop = 0;
    si.lpTitle = 0;
    si.dwFlags = 0;
    si.cbReserved2 = 0;
    si.lpReserved2 = 0;
    
    result = CreateProcessW(imageName, (LPWSTR)(LPCWSTR)params2,
        NULL, NULL, FALSE, 0, NULL, (LPWSTR)curDir, &si, &pi);
  }
  if (result == 0)
    return ::GetLastError();
  ::CloseHandle(pi.hThread);
  _handle = pi.hProcess;
  return 0;
}
Ejemplo n.º 28
0
ErrorCode ProcessSpawner::run(std::function<bool()> preExecAction) {
  std::vector<WCHAR> commandLine;
  std::vector<WCHAR> environment;
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;

  commandLine.push_back(L'"');
  std::wstring wideExecutablePath =
      Platform::NarrowToWideString(_executablePath);
  commandLine.insert(commandLine.end(), wideExecutablePath.begin(),
                     wideExecutablePath.end());
  commandLine.push_back(L'"');
  for (auto const &arg : _arguments) {
    commandLine.push_back(L' ');
    commandLine.push_back(L'"');
    std::wstring wideArg = Platform::NarrowToWideString(arg);
    for (auto const &ch : wideArg) {
      if (ch == L'"')
        commandLine.push_back(L'\\');
      commandLine.push_back(ch);
    }
    commandLine.push_back(L'"');
  }
  commandLine.push_back(L'\0');

  for (auto const &env : _environment) {
    std::wstring wideKey = Platform::NarrowToWideString(env.first);
    std::wstring wideValue = Platform::NarrowToWideString(env.second);
    environment.insert(environment.end(), wideKey.begin(), wideKey.end());
    environment.push_back(L'=');
    environment.insert(environment.end(), wideValue.begin(), wideValue.end());
    environment.push_back(L'\0');
  }
  environment.push_back(L'\0');

  memset(&si, 0, sizeof si);
  si.cb = sizeof si;

  // Note(sas): Not sure if we want DEBUG_ONLY_THIS_PROCESS here. Will need to
  // check back later.
  std::wstring wideWorkingDirectory =
      Platform::NarrowToWideString(_workingDirectory);
  BOOL result = CreateProcessW(
      nullptr, commandLine.data(), nullptr, nullptr, false,
      DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_UNICODE_ENVIRONMENT,
      environment.data(),
      wideWorkingDirectory.empty() ? nullptr : wideWorkingDirectory.c_str(),
      &si, &pi);

  _processHandle = pi.hProcess;
  _pid = pi.dwProcessId;

  return result ? kSuccess : kErrorUnknown;
}
Ejemplo n.º 29
0
bool InitPhysX()
{
    bool physXInstalled = false;
    while (!physXInstalled)
    {
        plSimulationMgr::Init();
        if (!plSimulationMgr::GetInstance())
        {
            int ret = hsMessageBox("PhysX is not installed, or an older version is installed.\nInstall new version? (Game will exit if you click \"No\")",
                "Missing PhysX", hsMessageBoxYesNo);
            if (ret == hsMBoxNo) // exit if no
                return false;

            // launch the PhysX installer
            STARTUPINFOW startupInfo;
            PROCESS_INFORMATION processInfo; 
            memset(&startupInfo, 0, sizeof(startupInfo));
            memset(&processInfo, 0, sizeof(processInfo));
            startupInfo.cb = sizeof(startupInfo);
            if(!CreateProcessW(NULL, s_physXSetupExeName, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo))
            {
                hsMessageBox("Failed to launch PhysX installer.\nPlease re-run URU to ensure you have the latest version.", "Error", hsMessageBoxNormal);
                return false;
            }

            // let the user know what's going on
            HWND waitingDialog = ::CreateDialog(gHInst, MAKEINTRESOURCE(IDD_LOADING), NULL, WaitingForPhysXDialogProc);

            // run a loop to wait for it to quit, pumping the windows message queue intermittently
            DWORD waitRet = WaitForSingleObject(processInfo.hProcess, 100);
            MSG msg;
            while (waitRet == WAIT_TIMEOUT)
            {
                if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                waitRet = WaitForSingleObject(processInfo.hProcess, 100);
            }

            // cleanup
            CloseHandle(processInfo.hThread);
            CloseHandle(processInfo.hProcess);
            ::DestroyWindow(waitingDialog);
        }
        else
        {
            plSimulationMgr::GetInstance()->Suspend();
            physXInstalled = true;
        }
    }
    return true;
}
Ejemplo n.º 30
0
BOOL assignDriveLetter(PCWSTR share)
{
    DWORD driveMap;
    char drive;
    wchar_t cmdLine[MAX_PATH];
    STARTUPINFOW startupInfo;
    PROCESS_INFORMATION processInformation;
    BOOL ok = FALSE;

    driveMap = GetLogicalDrives();

    for (drive = _MRX_MAX_DRIVE_LETTERS - 1; drive >= 0; ++drive)
    {
        if (!(driveMap & (1 << drive)))
        {
            break;
        }
    }

    if (drive < 0)
    {
        wprintf(L"Failed finding an appropriate drive for shared folder\n");
        return 1;
    }

    drive += 'A';

    wsprintf(cmdLine, L"hackssign_client.exe assign %c %s", drive, share);
    RtlZeroMemory(&startupInfo, sizeof(startupInfo));
    startupInfo.cb = sizeof(STARTUPINFOW);

    if (!CreateProcessW(NULL,
                        (PVOID)cmdLine,
                        NULL,
                        NULL,
                        FALSE,
                        0,
                        NULL,
                        NULL,
                        &startupInfo,
                        &processInformation))
    {
        wprintf(L"Failed starting hackssign_client.exe\n");
        return 1;
    }

    ok = (WaitForSingleObject(processInformation.hProcess, -1) == WAIT_OBJECT_0);
    CloseHandle(processInformation.hProcess);
    CloseHandle(processInformation.hThread);

    wprintf(L"%c assigned to %s\n", drive, share);

    return ok;
}