Similar to C++ Windows - How to get process path from its PID but the reverse: How can I get a pid from a given path?
I am trying to write an update tool, and I want to see if the exe is in use. Then if it is in use, I want to wait for the process to exit. Therefore, I want to get the process PID belonging to the file.
Here is a quick and simple way to do what you are looking for. By using the QueryFullProcessImageName, you can do a quick check.
Things that can cause the following code not to work as desired:
If you do not have permissions to view a process, you will not be
able to see the information.
If the process is 64bit and you are running your application as 32 bit, you will see the process ID, but you can not open a process handle to it.
Example:
BOOL GetProcessName(LPTSTR szFilename, DWORD dwSize, DWORD dwProcID)
{
BOOLEAN retVal = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcID);
DWORD dwPathSize = dwSize;
if (hProcess == 0)
return retVal; // You should check for error code, if you are concerned about this
retVal = QueryFullProcessImageName(hProcess, 0, szFilename, &dwPathSize);
CloseHandle(hProcess);
return retVal;
}
BOOL IsProcessInUse(LPCTSTR process_name)
{
DWORD* pProcs = NULL;
DWORD dwSize = 0;
DWORD dwRealSize = 0;
TCHAR szCompareName[MAX_PATH + 1];
int nCount = 0;
int nResult = 0;
dwSize = 1024;
pProcs = new DWORD[dwSize];
EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
dwSize = dwRealSize / sizeof(DWORD);
for (DWORD nCount = 0; nCount < dwSize; nCount++)
{
ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
{
if (_tcscmp(process_name, szCompareName) == 0)
{
delete[] pProcs;
return true;
}
}
}
delete[] pProcs;
return FALSE;
}
You would then use something simple like the following to test it:
if (IsProcessInUse(your_file))
AfxMessageBox(_T("The process is still running"));
else
AfxMessageBox(_T("The process has been closed"));
The above answers your indirect question. To answer your literal question, you would change the IsProcessInUse as follows:
DWORD GetNamedProcessID(LPCTSTR process_name)
{
DWORD* pProcs = NULL;
DWORD retVal = 0;
DWORD dwSize = 0;
DWORD dwRealSize = 0;
TCHAR szCompareName[MAX_PATH + 1];
int nCount = 0;
int nResult = 0;
dwSize = 1024;
pProcs = new DWORD[dwSize];
EnumProcesses(pProcs, dwSize*sizeof(DWORD), &dwRealSize);
dwSize = dwRealSize / sizeof(DWORD);
for (DWORD nCount = 0; nCount < dwSize; nCount++)
{
ZeroMemory(szCompareName, MAX_PATH + 1 * (sizeof(TCHAR)));
if (GetProcessName(szCompareName, MAX_PATH, pProcs[nCount]))
{
if (_tcscmp(process_name, szCompareName) == 0)
{
retVal = pProcs[nCount];
delete[] pProcs;
return retVal;
}
}
}
delete[] pProcs;
return 0;
}
One last important thing to note is the fact that this will only return a single instance (or PID) for a file, and this does not look for Modules that are used by process (so any DLL in use by process will not be identified, however, from the link you provided, you can see ways of utilizing that to get that level of functionality.
Related
I have been in doubt about what should be a better approach:
To cache the registry and use it later (I won't be doing it multiple times).
To run this function when needed (if it is fast)
How can I measure the speed of this function?
int ReadUACRegistryKey(LPCWSTR key)
{
LPCWSTR pszSubKey, pszValue = key;
const std::wstring sPath = L"XXXXXXXXXXX";
pszSubKey = sSearchPattern.c_str();
DWORD dwType = 0;
DWORD dwValue = 0;
DWORD dwValueSize = sizeof(dwValue);
int retval = SHGetValue(HKEY_LOCAL_MACHINE, pszSubKey, key, &dwType, &dwValue, &dwValueSize);
if (retval != ERROR_SUCCESS)
{
Trace(TRACE_ERROR, _T("ERROR: Failed to retrieve Registry setting and check Input_Image format."));
}
return dwValue;
}
I am trying to get total number of modules of a running process by passing process ID
This is function that return total number of modules in a process
int size(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
// Print the process identifier.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
// Get a list of all the modules in this process.
EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded);
int j = (cbNeeded / sizeof(HMODULE));
return j;
// Release the handle to the process.
}
this is main
int main()
{
DWORD aProcesses[1024];
DWORD cbNeeded;
DWORD cProcesses;
unsigned int i;
// Get the list of process identifiers.
if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
return 1;
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the names of the modules for each process.
for (int i = 0; i <= cProcesses; i++) {
int a = size(aProcesses[1]);
//std::string* g = PrintModules(aProcesses[1], a);
cout << a << endl;
}
system("pause");
return 0;
}
when i compile & run this code output is 855987977 etc
I tried multiple ways but all in vain...
Use the standard method of EnumprocessModules, the output argument is the size in bytes of the array:
lpcbNeeded = The number of bytes required to store all module handles in the lphModule array.
Divide it by the size of the element type (HMODULE) and that will yield the number of modules.
int GetNumberOfModules(DWORD processID)
{
HMODULE hMods[1024];
HANDLE hProcess;
DWORD cbNeeded;
unsigned int i;
// Print the process identifier.
printf("\nProcess ID: %u\n", processID);
// Get a handle to the process.
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID);
if (NULL == hProcess)
return 1;
// Get a list of all the modules in this process.
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
//return number of modules by dividing size of array by element size
return cbNeeded / sizeof(HMODULE);
}
// Release the handle to the process.
CloseHandle(hProcess);
return 0;
}
Im trying to read a registry using the winapi and c++.
The code runs, but the result is not the contents of the registry
After a hexdump is just 0xCD repeated over and over. (So, as if the data hasnt been modified by RegQueryValueEx, and is just the result of the malloc)
I tried running as admin too, with no luck.
This is the code im using:
HKEY hKey;
if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\Shell\\Bags\\1\\Desktop", 0, KEY_ALL_ACCESS, &hKey) != ERROR_SUCCESS)
return;
//Read & save
DWORD BufferSize = TOTALBYTES;
DWORD cbData;
DWORD dwRet;
LPBYTE data = (LPBYTE)malloc(BufferSize);
cbData = BufferSize;
DWORD type = REG_BINARY;
dwRet = RegQueryValueEx(hKey, "IconLayouts", NULL, &type, data, &cbData);
while (dwRet == ERROR_MORE_DATA) {
BufferSize += BYTEINCREMENT;
data = (LPBYTE)realloc(data, BufferSize);
cbData = BufferSize;
dwRet = RegQueryValueEx(hKey, "IconLayouts", NULL, &type, data, &cbData);
}
if (dwRet == ERROR_SUCCESS)
{
//Write current registry to a file
std::ofstream currentRegistryFile(DIRECTORY + currentDesktop + ".bin");
if (!currentRegistryFile) {
log(currentDesktop + " file couldn't be opened.");
return;
}
for (int i = 0; i < cbData; i++)
currentRegistryFile << (data)[cbData];
}
else
log("Couldnt read registry");
//Close registry
RegCloseKey(hKey);
Your saving code is the problem. It’s actually accessing the array out of bounds:
for (int i = 0; i < cbData; i++)
currentRegistryFile << (data)[cbData];
Note you’re indexing data with constant value of cbData and not loop variable i. Change that.
im new to c++ and im trying to byte pattern scann a remote process, but somehow it doesnt work for me.
the program just crashes when it executes the pattern finding function.
this is the scanning function im using:
bool VerifyAddress(HANDLE hProcess, DWORD dwAddress, PBYTE bMask, char *szMask)
{
PBYTE *pTemp = { 0 };
for (int i = 0; *szMask; ++szMask, ++bMask, ++i)
{
if (!ReadProcessMemory(hProcess, reinterpret_cast<LPCVOID>(dwAddress + i), &pTemp, 2048, 0))
return false;
if (*szMask == 'x' && reinterpret_cast<char*>(pTemp) != reinterpret_cast<char*>(*bMask))
return false;
}
return true;
}
DWORD ExternalFindPattern(HANDLE hProcess, PBYTE bMask, char *szMask)
{
for (DWORD dwCurrentAddress = 0x401000; dwCurrentAddress < 0x7FFFFFF; dwCurrentAddress++)
if (VerifyAddress(hProcess, dwCurrentAddress, bMask, szMask))
return dwCurrentAddress;
return -1;
}
and these are my parameters:
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
char* Pattern = "\x65\x6E\x64\x6D\x69\x73\x73\x69\x6F\x6E\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0B\x00\x00\x00\x65\x6E\x64\x4D\x69\x73\x73\x69\x6F\x6E";
char* Mask = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
DWORD signAdress = ExternalFindPattern(hProc, (PBYTE)Pattern, Mask);
im sorry if this is a obvious nooby question, but im stuck for hours now and i just cant get it to work
I have the following in my CPP code which adds the current program into startup. I'm trying to modify the code to add a different program to startup, say I want to add a key so that "C:\mytime.exe" runs on startup. Could you please help me modify the code?
TCHAR szPath[MAX_PATH];
DWORD pathLen = 0;
pathLen = GetModuleFileName(NULL, szPath, MAX_PATH);
if (pathLen == 0)
{
return -1;
}
HKEY newValue;
if (RegOpenKey(HKEY_CURRENT_USER,
TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Run"),
&newValue) != ERROR_SUCCESS)
{
return -1;
}
DWORD pathLenInBytes = pathLen * sizeof(*szPath);
if (RegSetValueEx(newValue,
TEXT("My Program"),
0,
REG_SZ,
(LPBYTE)szPath,
pathLenInBytes) != ERROR_SUCCESS)
{
RegCloseKey(newValue);
return -1;
}
RegCloseKey(newValue);
return TRUE;
Simply replace this chunk of code:
pathLen = GetModuleFileName(NULL, szPath, MAX_PATH);
if (pathLen == 0)
{
return -1;
}
With this:
/* of course, use your own executable - make sure to not overflow the buffer! */
_tcscpy(szPath, _T("C:\\stackoverflow.exe"));
pathLen = _tcslen(szPath);