Guest User

Wrapper

a guest
Feb 11th, 2015
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.25 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include <conio.h>
  5. #include <string.h>
  6. #include <sstream>
  7. #include <consoleapi.h>
  8. #include <Shlwapi.h>
  9. #include <atlstr.h>
  10. #pragma hdrstop
  11.  
  12. void ErrorMessage(wchar_t *str)  //display detailed error info
  13. {
  14.     LPVOID msg;
  15.     FormatMessageW(
  16.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  17.         NULL,
  18.         GetLastError(),
  19.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  20.         (LPTSTR)&msg,
  21.         0,
  22.         NULL
  23.         );
  24.     wprintf_s(L"pcLog=\"%s: %s\";\n", str, msg);
  25.     LocalFree(msg);
  26. }
  27.  
  28. int _tmain(int argc, _TCHAR** argv)
  29. {
  30.     if (argc < 3)
  31.     {
  32.         wprintf_s(L"pcLog=\"Too few arguments specified.\";\n");
  33.         return 2;
  34.     }
  35.     wchar_t* username = argv[1];
  36.     wchar_t* password = argv[2];
  37.     wchar_t* executable = argv[3];
  38.  
  39.     //Before we bother with anything else, let's make sure we can log on as the specified user.
  40.     HANDLE logonToken;
  41.     if (!LogonUserExW(username, NULL, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_WINNT50, &logonToken, NULL, NULL, NULL, NULL))
  42.     {
  43.         wprintf_s(L"pcLog=\"Failed to log in as user %s.\";\n", username);
  44.         return 2;
  45.     }
  46.     wprintf_s(L"pcLog=\"Logged in as user %s.\";\n", username);
  47.     CloseHandle(logonToken);
  48.  
  49.     //Make argument string to pass to new process, without our username and password.
  50.     std::wstringstream ss;
  51.     ss << executable;
  52.     for (int i = 4; i < argc; i++)
  53.     {
  54.         ss << " " << argv[i];
  55.     }
  56.     std::wstring str = ss.str();
  57.     LPWSTR cmdLine = const_cast<LPWSTR>(str.c_str());
  58.  
  59.     PROCESS_INFORMATION pi;
  60.     HANDLE newstdin, newstdout, read_stdout, write_stdin;  //pipe handles
  61.    
  62.     SECURITY_ATTRIBUTES sa;
  63.     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  64.     sa.lpSecurityDescriptor = NULL;
  65.     sa.bInheritHandle = TRUE;
  66.  
  67.     if (!CreatePipe(&newstdin, &write_stdin, &sa, 0))   //create stdin pipe
  68.     {
  69.         ErrorMessage(L"CreatePipe");
  70.         return 2;
  71.     }
  72.     if (!CreatePipe(&read_stdout, &newstdout, &sa, 0))  //create stdout pipe
  73.     {
  74.         ErrorMessage(L"CreatePipe");
  75.         CloseHandle(newstdin);
  76.         CloseHandle(write_stdin);
  77.         return 2;
  78.     }
  79.  
  80.     STARTUPINFO si;
  81.     // Set up the startup info struct.
  82.     ZeroMemory(&si, sizeof(STARTUPINFO));
  83.     si.cb = sizeof(STARTUPINFO);
  84.     si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  85.     si.hStdOutput = newstdout;
  86.     si.hStdInput = newstdin;
  87.     si.hStdError = newstdout;
  88.     si.wShowWindow = SW_HIDE;
  89.  
  90.     ATL::CStringW currentPath(argv[3]);
  91.     wprintf_s(L"pcLog=\"Executable:%s\";\n", currentPath.GetString());
  92.  
  93.     wchar_t* wd = const_cast<LPWSTR>(currentPath.GetString());
  94.     PathRemoveFileSpecW(wd);
  95.  
  96.     ATL::CStringW wdWithSlash(wd);
  97.     wdWithSlash += L"\\";
  98.  
  99.     wprintf_s(L"pcLog=\"Working Directory:%s\";\n", wdWithSlash.GetString());
  100.  
  101.     //spawn the child process as the specified user
  102.     wprintf_s(L"pcLog=\"Starting %s as '%s' with arguments: %s\";\n", executable, username, cmdLine);
  103.     if (!CreateProcessWithLogonW(username, NULL, password, LOGON_WITH_PROFILE, executable, cmdLine, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT, NULL, wdWithSlash, &si, &pi))
  104.     {
  105.         DWORD err = GetLastError();
  106.         wprintf_s(L"pcLog=\"Unable to launch application. Error %d\";\n", err);
  107.         CloseHandle(newstdin);
  108.         CloseHandle(newstdout);
  109.         CloseHandle(read_stdout);
  110.         CloseHandle(write_stdin);
  111.         return 2;
  112.     }
  113.  
  114.     unsigned long exit = 0;  //process exit code
  115.     unsigned long bread;   //bytes read
  116.     unsigned long avail;   //bytes available
  117.  
  118.     _TCHAR buf[1024];
  119.     SecureZeroMemory(buf,sizeof(buf));
  120.     for (;;)      //main program loop
  121.     {
  122.         GetExitCodeProcess(pi.hProcess, &exit);
  123.         //Basically, block this thread until the child exits.
  124.         if (exit != STILL_ACTIVE)
  125.             break;
  126.  
  127.         PeekNamedPipe(read_stdout, buf, 1024, &bread, &avail, NULL);
  128.  
  129.         if (bread != 0)
  130.         {
  131.             SecureZeroMemory(buf,sizeof(buf));
  132.             if (avail > 1024)
  133.             {
  134.                 while (bread >= 1024)
  135.                 {
  136.                     ReadFile(read_stdout, buf, 1024, &bread, NULL);  //read the stdout pipe
  137.                     wprintf_s(L"%s", buf);
  138.                     SecureZeroMemory(buf, sizeof(buf));
  139.                 }
  140.             }
  141.             else {
  142.                 ReadFile(read_stdout, buf, 1024, &bread, NULL);
  143.                 wprintf_s(L"%s", buf);
  144.             }
  145.         }
  146.     }
  147.     CloseHandle(pi.hThread);
  148.     CloseHandle(pi.hProcess);
  149.     CloseHandle(newstdin);
  150.     CloseHandle(newstdout);
  151.     CloseHandle(read_stdout);
  152.     CloseHandle(write_stdin);
  153.  
  154.     wprintf_s(L"pcLog=\"Process exit code: %u\";\n", exit);
  155.     return 1; //Because reasons
  156. }
Advertisement
Add Comment
Please, Sign In to add comment