Piszę IDE i właśnie wpadłem na zwariowany pomysł - możliwość uruchamiania kompilatora jako inny użytkownik (w razie braku zaufania do danego exe). Ale pojawił się mały problem - funkcja CreateProcessWithLogonW nie ma parametru InheritHandles tak jak jest w CreateProcess.

Pierwszy problem jaki mnie spotkał, to błąd InvalidHandle - process nie uruchamiał się wcale - musiałem usunąć STARTF_USESTDHANDLES ze struktury STARTUPINFO.

Drugi problem - jak podmienić stdout takiego procesu - proste, DuplicateHandle i kilka operacji read/write memory symulujących zdalne wywołanie SetStdHandle. Zrobiłem tak i faktycznie mój uchwyt pojawił się w stdout i stderror procesu.
Ale tuż po ResumeThread proces kończy z exitcode=1. Pomyślałem że to brak uprawnień, więc ręcznie dodałem usera do 'folderu' z pełnymi uprawnieniami (XP). Pomyślałem też, że w jakiś sposób dany process nie jest w stanie zapisać do pliku który jest w moim profilu, w /temp - kopia jego uchwytu jest wpisana jako stdout tego procesu z identycznym ACCESS_MASK (DuplicateHandle). Zmieniłem ścieżkę tego pliku żeby był w bardziej dostępnym miejscu, ale to nie pomogło, nic nie wychodzi na stdout (plik jest pusty). Gdy używam CreateProcess to wszystko działa jak trzeba.

To jest kawałeczek mojego kodu - jeżeli UserName i Password zostaną odczytane, to odpalam proces przez CreateProcessWithLogonW, else przez CreateProcess

DWORD dwCreationFlags = 0;
// dwCreationFlags = CREATE_SUSPENDED; - w razie potrzeby wepchania plugina
// cd     : struct COMPILERDATA
// cd.data: strukturka dla kazdego MDI
// szTemp : working dir
// si     : zainicjowane STARTUPINFO; .hStdOutput zawiera uchwyt pliku

// odczytaj username i hasło z XML kompilatora
BSTR bstrUserName = NULL;
BSTR bstrPasword  = NULL;
BOOL withLogon = FALSE;
if (cd.compiler->FindChild(L"Logon", TRUE, Logon))
{
  Logon.GetAttributeHere(L"UserName", &bstrUserName, 0);
  Logon.GetAttributeHere(L"Password", &bstrPasword, 0);
}

// uruchomienie kompilatora
if (bstrUserName && bstrPasword)
{
  withLogon = TRUE;
  dwCreationFlags |= CREATE_SUSPENDED;
  si.dwFlags    = STARTF_USESHOWWINDOW; // usuń STARTF_USESTDHANDLES
  ProcessCreated = CreateProcessWithLogonW(bstrUserName, L".", bstrPasword, LOGON_WITH_PROFILE, NULL, cd.bstrCommandLine, dwCreationFlags, 0, szTemp, &si, &pi);
}
else
{
  ProcessCreated = CreateProcess(0, cd.bstrCommandLine, 0, 0, TRUE, dwCreationFlags, NULL, szTemp, &si, &pi);
}

DWORD LastError = GetLastError();
MySysFreeString(&bstrUserName);
MySysFreeString(&bstrPasword);

if (!ProcessCreated)
{
  FormatMessage(0x000010FF, 0, LastError, 0, szTemp, MAX_PATH, 0);
  BuildAddStringEx(cd.data, TEXT("Failed to execute %s : error %d (%s)"), cd.bstrCompilerPath, LastError, szTemp);
}
else
{
  if (dwCreationFlags & CREATE_SUSPENDED)
  {
    if (withLogon)
    {
      // zapisz si.hStdOutput w PEB->ProcessParameters->StdOutputHandle i StdErrorHandle
      HANDLE hTargetHandle;
      if (DuplicateHandle(GetCurrentProcess(), si.hStdOutput, pi.hProcess, &hTargetHandle, 0, TRUE, DUPLICATE_SAME_ACCESS))
      {
        CONTEXT ctx;
        LDT_ENTRY sel;
        ctx.ContextFlags = CONTEXT_SEGMENTS;

        if (GetThreadContext(pi.hThread, &ctx))
        {
          if (GetThreadSelectorEntry(pi.hThread, ctx.SegFs, &sel))
          {
            DWORD fsbase = (sel.HighWord.Bytes.BaseHi << 8 | sel.HighWord.Bytes.BaseMid) << 16 | sel.BaseLow;
            PEB *pPeb;
            RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
            if (ReadProcessMemory(pi.hProcess, fsbase + 0x30, &pPeb, 4, NULL))
            {
              if (ReadProcessMemory(pi.hProcess, &pPeb->ProcessParameters, &ProcessParameters, 4, NULL))
              {
                if (WriteProcessMemory(pi.hProcess, &ProcessParameters->StdOutputHandle, &hTargetHandle, 4, NULL))
                  WriteProcessMemory(pi.hProcess, &ProcessParameters->StdErrorHandle, &hTargetHandle, 4, NULL);
              }
            }
          }
        }
      }
    }
    // wepchanie plugina na siłę - zmiana EP na kod z LoadLibrary...
    if (nRedirCount | nPluginCount)
      InjectRedirectorDllToProcess(pi.hProcess, pi.hThread, nRedirCount, nPluginCount);

    ResumeThread(pi.hThread);
  }
  // standardowe czekanie z MsgWaitForMultipleObjectsEx
  compilerWaitForProcess(pi.hProcess);
  GetExitCodeProcess(pi.hProcess, &pcd->dwExitCode);
  CloseHandle(pi.hProcess);
  CloseHandle(pi.hThread);
  compilerReadLogFromFile(cd.data, si.hStdOutput); // ładuje stdout do listboxa
  CloseHandle(si.hStdOutput);
}

Wszystkie kroki po "if (withLogon)" wykonują się poprawnie, w każdym IF/else mam print'a z informacją, tylko nie wiem czego mi brakuje?

Jedno jest pewne - proces (nasm 2.07) odczytuje podany mu plik .asm, tworzy plik .lst, ale nic więcej mi nie wiadomo.
screen: http://i46.tinypic.com/xaur6s.png