CreateProcess application not found in cache c++ MFC - c++

i am writing a simple program which calls CreateProcess thousands of times, so its taking a while to run. in my output windows i'm seeing this message each time
application "whatever.exe" not found in cache
i call CreateProcess like this
BOOL result = CreateProcess(NULL, g_minicapcmd,
NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &startupInfo, &processInformation);
if (!result) {
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
CString strError = (LPTSTR) lpMsgBuf;
TRACE(_T("::executeCommandLine() failed at CreateProcess()\nCommand=%s\nMessage=%s\n\n"), g_minicapcmd, strError);
LocalFree(lpMsgBuf);
return false;
} else {
// Successfully created the process. Wait for it to finish.
WaitForSingleObject( processInformation.hProcess, INFINITE );
// Close the handles.
CloseHandle( processInformation.hProcess );
CloseHandle( processInformation.hThread );
}
is there a way to get it to cache or some way to make it faster? i already tried putting the .exe its loading on ramdisk and that helped a bit

Related

C++ multi threaded scheduling application issues

Background
I am maintaining a Windows MFC C++ multi threaded job scheduling application. Users will schedule tasks to run from their local computer. Inactive users will automatically transfer their tasks to active users.
Issues
Some jobs are failing to run. It is usually the same jobs, but not always the same jobs. There are two jobs that very often fail. They have varying expected run times. They are both scheduled to run on non-overlapping time intervals with one another.
Method for creating processes:
The location of the job is fed into the following function:
int VirtualGridDriver::RunApplicationAsProcessWithExitCode(CString cmdLine)
{
PROCESS_INFORMATION processInformation = {0};
STARTUPINFO startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
int nStrBuffer = cmdLine.GetLength() + 50;
//Create the process
BOOL result = CreateProcess(NULL, cmdLine.GetBuffer(nStrBuffer),
NULL, NULL, FALSE,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL, NULL, &startupInfo, &processInformation);
cmdLine.ReleaseBuffer();
if (!result)
{
//CreateProcess() failed
//Get the error from the system
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
//Display the error
CString strError = (LPTSTR) lpMsgBuf;
//Free resources created by the system
LocalFree(lpMsgBuf);
//We failed.
return 1;
}
else
{
//Successfully created the process. Wait for it to finish.
WaitForSingleObject( processInformation.hProcess, INFINITE );
DWORD B;
GetExitCodeProcess (processInformation.hProcess, &B);
//Close the handles.
CloseHandle( processInformation.hProcess );
CloseHandle( processInformation.hThread );
int ret = int(B);
//We succeeded.
return ret;
}
}
The failed jobs return with exit code 1. Can anyone identify possible issues? If not, can someone provide some issues I may consider looking more deeply into? Could this be a multithreaded issue?

C++ MiniDumpWriteDump failed

I am trying to create a simple C++ console app which dump the memory space of a given process (e.g. calc.exe) So I use MiniDumpWriteDump function
Here is the code :
DWORD procID = 1150;
char* procName = "calc.exe";
// opens the dump file
HANDLE hFile = CreateFile( "calc.dmp", GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if(hFile)
{
// opens the process
HANDLE hProcToDump = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, procID);
if(hProcToDump)
{
// dumps via the API
BOOL rv = MiniDumpWriteDump(hProcToDump, GetProcessId(hProcToDump), hFile, MiniDumpNormal, NULL, NULL, NULL);
HRESULT hr = GetLastError();
if( !rv )
printf("MiniDumpWriteDump failed.");
else
printf("Minidump OK!");
CloseHandle( hFile );
CloseHandle( hProcToDump );
}
}
But I get the error :
GetLastError() = hresult 0x8007012b Only part of a ReadProcessMemory or WriteProcessMemory request was completed
Why ?
Note : I am admin on Win 7 x64.
Thank you for your help.
Try this, which is similar to your example. Usage of MiniDumpWriteDump.

Win32 API : User Impersonation technique to run a process as some other user?

I'm writing an application which runs a third-party executable as some less privileged user
on Windows. I used following Win32 API functions for this:
LogonUser(L"UserName", L"Domain", NULL, LOGON32_LOGON_SERVICE, LOGON32_PROVIDER_DEFAULT, &hToken)
then calling
CreateProcessAsUser()
using hToken I've got to run the process. My actual program which launches this executable is running as Administrator. My doubts here are:
If UAC(User Account Control) is enabled. Will this work??
I need to create the processes many times. Can I use the hToken by
saving it somewhere.
Does
CreateProcessAsUser() works with different combinations of
Domain\User i.e .\Administrator or \Administrator or
Domain\UserName etc..??
The MSDN says: "Generally, it is best to use CreateProcessWithLogonW to create a process with alternate credentials." The following example demonstrates how to call this function.
#include <windows.h>
#include <stdio.h>
#include <userenv.h>
void DisplayError(LPWSTR pszAPI)
{
LPVOID lpvMessageBuffer;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&lpvMessageBuffer, 0, NULL);
//
//... now display this string
//
wprintf(L"ERROR: API = %s.\n", pszAPI);
wprintf(L" error code = %d.\n", GetLastError());
wprintf(L" message = %s.\n", (LPWSTR)lpvMessageBuffer);
//
// Free the buffer allocated by the system
//
LocalFree(lpvMessageBuffer);
ExitProcess(GetLastError());
}
void wmain(int argc, WCHAR *argv[])
{
DWORD dwSize;
HANDLE hToken;
LPVOID lpvEnv;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
WCHAR szUserProfile[256] = L"";
si.cb = sizeof(STARTUPINFO);
if (argc != 4)
{
wprintf(L"Usage: %s [user#domain] [password] [cmd]", argv[0]);
wprintf(L"\n\n");
return;
}
//
// TO DO: change NULL to '.' to use local account database
//
if (!LogonUser(argv[1], NULL, argv[2], LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, &hToken))
DisplayError(L"LogonUser");
if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE))
DisplayError(L"CreateEnvironmentBlock");
dwSize = sizeof(szUserProfile)/sizeof(WCHAR);
if (!GetUserProfileDirectory(hToken, szUserProfile, &dwSize))
DisplayError(L"GetUserProfileDirectory");
//
// TO DO: change NULL to '.' to use local account database
//
if (!CreateProcessWithLogonW(argv[1], NULL, argv[2],
LOGON_WITH_PROFILE, NULL, argv[3],
CREATE_UNICODE_ENVIRONMENT, lpvEnv, szUserProfile,
&si, &pi))
DisplayError(L"CreateProcessWithLogonW");
if (!DestroyEnvironmentBlock(lpvEnv))
DisplayError(L"DestroyEnvironmentBlock");
CloseHandle(hToken);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}

Small issue with creating a process ( CreateProcess or ShellExecuteEx) with parameters

Related question: CreateProcess doesn't pass command line arguments.
Is there a difference between passing an argument vs. passing a parameter to an EXE when using CreateProcess (and/or ShellExecuteEx)?
I'm trying to call something like:
myExe.exe /myparam
with the code like :
TCHAR Buffer[MAX_PATH];
DWORD dwRet;
dwRet = GetCurrentDirectory(MAX_PATH, Buffer);
CString sCmd;
sCmd.Format ( "%s\\%s", Buffer, command);
CString sParam( "/myparam" );
sCmd += " " + sParam;
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );
if (CreateProcess( NULL, sCmd.GetBuffer() , NULL, NULL, TRUE, 0, NULL, Buffer, &si, &pi))
{
::WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
LPVOID lpMsgBuf = NULL;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
CString msg;
msg.Format("Failed to start command line (error: %s) : %s\n",lpMsgBuf,sCmd);
AfxMessageBox(msg);
LocalFree(lpMsgBuf);
}
From what I understand from the other thread and MSDN is that it should be working properly and call the EXE with the parameter; doing the above code without adding the "/myparam" works like it should.
I've tried the EXE from the command line and from Explorer (by creating a shortcut and adding /myparam to the target name) and it's working alright.
Try this in case there are spaces in the path:
CString sCmd;
sCmd.Format ( "\"%s\\%s\"", Buffer, command);
Or else pass the parameters via the parameters argument.

install driver using c++

I'm trying to install driver behind the user:
I've create DLL which call SetupCopyOEMInf using c++ then i call it from VB application:
C++ code:
PBOOL bRebootRequired = false;
PCTSTR szInfFileName = (PCTSTR) "c:\\temp\\ttt\\Driver\\slabvcp.inf";
if(!SetupCopyOEMInf(szInfFileName,NULL, SPOST_PATH, SP_COPY_REPLACEONLY, NULL, 0, NULL, NULL)){;
DWORD dw = GetLastError();
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,0, NULL );
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
}
And when i call this function i receiving error "The system cannot find the file specified."
But the path to my file is correct.
PCTSTR szInfFileName = (PCTSTR) "c:\\temp\\ttt\\Driver\\slabvcp.inf";
A cast is not going to work, it will turn your 8-bit character string into Chinese. Fix:
PCTSTR szInfFileName = _T("c:\\temp\\ttt\\Driver\\slabvcp.inf");