Not sure if it's something in my code or how I'm handling launching the process but in the code below, if I turn on the boolean outputToFile TRUE, the program will happily output the standard output from UWFMGR to the out.log file and it is readable and looks as it does when executed from the cmd line.
If I turn that boolean off and try to use the standard output I read from the pipe it is garbage... Something like "U A n yzna...a/". buf, csTemp, and m_csOutput all have the off characters. If I run the same program with other programs like ipconfig, netsh, ect instead of uwfmgr it works perfectly. I have even used this code in the past with ewfmgr and it worked fine. I'm not sure what's different with uwfmgr but it breaks this code. The other odd thing that must be a clue is the WaitForSingleObject works fine with everything but uwfmgr, when I am running uwfmgr that WaitForSingleObject will never return and waits forever.
Another thing to note is the call to uwfmgr works correctly, for example "uwfmgr filter enable" will enable the filter on system reboot even though the std output is unreadable.
Any ideas? Thanks!
String csExecute;
csExecute = "uwfmgr get-config";
bool outputToFile = FALSE;
SECURITY_ATTRIBUTES secattr;
ZeroMemory(&secattr, sizeof(secattr));
secattr.nLength = sizeof(secattr);
secattr.bInheritHandle = TRUE;
secattr.lpSecurityDescriptor = NULL;
HANDLE rPipe = NULL;
HANDLE wPipe = NULL;
//For test use....File works and captures output correctly
HANDLE h = CreateFile(_T("out.log"),
FILE_APPEND_DATA,
FILE_SHARE_WRITE | FILE_SHARE_READ,
&secattr,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
// Create pipes to write and read data
//if(outputToFile)
//{
// CreatePipe(&rPipe, &h, &secattr, 0);
//}else
//{
CreatePipe(&rPipe, &wPipe, &secattr, 0);
//}
STARTUPINFOW sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo, sizeof(STARTUPINFOW));
ZeroMemory(&pInfo, sizeof(PROCESS_INFORMATION));
sInfo.cb = sizeof(STARTUPINFOW);
sInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
sInfo.wShowWindow = SW_HIDE;
sInfo.hStdInput = NULL;
if(outputToFile)
{
sInfo.hStdOutput = h;
sInfo.hStdError = h;
}else
{
sInfo.hStdOutput = wPipe;
sInfo.hStdError = wPipe;
}
char command[1024];
wcstombs(command, csExecute.c_str(), sizeof(command));
ShowMessage(csExecute);
CreateProcessWithLogonW(L"username", L"PCDOMAIN", L"password",
LOGON_NETCREDENTIALS_ONLY, NULL, csExecute.w_str(),
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL,
&sInfo, &pInfo);
//Never returns with UWFMGR, works fine on other processes like ipconfig, netsh, ect
//WaitForSingleObject(pInfo.hThread, Infinite);
if(outputToFile)
{
CloseHandle(h);
}else
{
CloseHandle(wPipe);
}
//returns 0 and works fine (actual call to uwfmgr succeeded, for example uwfmgr filter enable turns the filter on even though the output is garbage unless outputted to a file
ShowMessage(GetLastError());
// now read the output pipe here.
#define BUFSIZE 100
BOOL res = FALSE;
String m_csOutput = "";
for(;;)
{
char buf[BUFSIZE+1] = "";
DWORD reDword;
if(!::ReadFile(rPipe, buf, BUFSIZE, &reDword, 0))
{
DWORD error = ::GetLastError();
ShowMessage("Error #....");
ShowMessage(error);
break;
}
if(reDword == 0)
{
break;
}
buf[reDword] = '\0';
ShowMessage(buf);
String csTemp = buf;
ShowMessage(csTemp);
m_csOutput += csTemp;//.SubString(1, reDword);
ShowMessage(m_csOutput);
}
For anyone that is trying to use UWFMGR in a batch file (i.e. check if the filter is enabled) You can use
to sanitize your output down to ascii from UTF-16
this command prints out any line in the file found that DOES NOT match "" (nothing)
therefore, it prints everything out in the file. Find output happens to be pure ascii for me (need to test to see if its code page dependent)
example: