7

I need to do some stuff in a dll based on which process has loaded it. So being relatively new to windows programming I need help figuring out how to find the exe which loaded the current dll. So far I have been hard coding the exe file name, which is the dumbest thing to do :D

1) Some one suggested using GetModuleFileName() function. But this seems to crash my app.(I used 0 as the module handle). I am doing nothing fancy. I used the following syntax

GetModuleFileName(0,&fileName,MAX_PATH)

EDIT: I understood from here that I cannot get the .exe name with this call as it returns only the dll name :(

2)Is it a good idea to do this in the DllMain ?? I know that DllMain is not the place to do complicated stuff. I also understand loader lock related issues.All I need is to find the name of the parent process.

I appreciate your time !

ADD: I tried to use GetProcessImageFileName after getting the parent process ID. I get an access violation error. When I tried to debug I noticed that the openProcess call leaves my result argument(image file path-LPTSTR) as a bad pointer.
Error code 87-INVALID PARAMETER is returned by the GetProcessImageFileName call.
But the current process id is a valid id.
Here is the code

LPTSTR fileName={0};  
HANDLE hP=OpenProcess(PROCESS_QUERY_INFORMATION ,FALSE, processes[i]) ;
GetProcessImageFileName(hP,fileName,(DWORD)MAX_PATH+1);

What Am I doing wrong??

Thanks

EDIT IMPORTANT:

I found out that I am trying to use openprocess on an idle process. (i.e) I forgot that my parent process could possibly be waiting idle for me since I sync it . So now I got the bad news that I cannot open an idle process using OpenProcess. How else can i get to look into the object of an Idle process?? (I know for sure its idle because I could not find it in the snapshot. I had to use enumerateprocess to locate its id; But i do use normal process enumeration from the snapshot to find the parent process id in the first place)

Himanshu
  • 4,327
  • 16
  • 31
  • 39
ash
  • 1,170
  • 1
  • 15
  • 24
  • What do you mean by "an idle process"? It you mean *the* idle process (to which Windows attributes unused CPU time), then this is expected to fail - that isn't a real process. – nobody Jul 30 '15 at 11:31

3 Answers3

3

If you have declared your fileName variable as something like char fileName or char fileName[MAX_PATH], you may receive an error because your parameter is incorrect: you use the address of the variable (though, you don't specify whether it is a compile time error or runtime error, you say it crashes your app, so I go with Richard here, you've not allocated your variable).

I tried the following code, which works both from within a DLL (it gets the name of the executable, not the DLL module) or from within the executable itself.
(Note: code updated based on Remy's comments below, thanks)

WCHAR exePath[MAX_PATH + 1];
DWORD len = GetModuleFileNameW(NULL, exePath, MAX_PATH);
if (len > 0) {
    wcout 
       << L"Exe path" 
       << (len == MAX_PATH) ? L" (truncated):" : L":" 
       << exePath 
       << endl;
} else {
    wcout 
       << L"Error getting exe path: " 
       << GetLastError() 
       << endl;
}

Note: if the buffer is not large enough, GetModuleFileName will truncate the result and return nSize.

More on handling filenames in Win32.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Abel
  • 56,041
  • 24
  • 146
  • 247
  • You are misusing `GetLastError()`. If `GetModuleFileName()` returns > 0, it successfully returned data. This is documented behavior. Don't use `GetLastError()` except when `GetModuleFileName()` returns 0. You are also mixing `TCHAR`, `char*` and `wcout` incorrectly. Try something like this instead: `WCHAR exePath[MAX_PATH + 1]; DWORD len = GetModuleFileNameW(NULL, exePath, MAX_PATH); if (len > 0) wcout << L"Exe path" << (len == MAX_PATH) ? L" (truncated):" : L":" << exePath << endl; else wcout << L"Error getting exe path: " << GetLastError() << endl;` – Remy Lebeau Aug 19 '15 at 14:48
  • @RemyLebeau, it's been a while and I'm sure you are right (I can't remember the circumstances when writing this code). I'll update the answer. – Abel Aug 20 '15 at 09:32
2

Refer the following link to know about the syntax and the detailed description about the GetModuleFileName()

Steps to do:

First get the full path of the executable file using the code:

TCHAR szEXEPath[2048];
char actualpath[2048];
GetModuleFileName ( NULL, szEXEPath, 2048 );
for(int j=0; szEXEPath[j]!=0; j++)
{
    actualpath[j]=szEXEPath[j];
}

From the full path of the executable file, split the string to get only the executable name using the built in function str.find_last_of()

std::string str (actualpath);
std::size_t found = str.find_last_of("/\\");
std::cout<< str.substr(found+1) << '\n';

Now you can get only the executable file name.

Cibin William
  • 303
  • 1
  • 3
  • 17
  • Whilst this may theoretically answer the question, [it would be preferable](//meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Rohit Gupta Aug 17 '15 at 06:06
  • Hope this will be useful and easy to understand – Cibin William Aug 19 '15 at 14:30
  • Don't mix `TCHAR[]` and `char[]` like this. If you want the filename in a `char[]`, get rid of the `TCHAR[]` and use `GetModuleFileNameA()` instead. Also have a look at [`splitpath()`](https://msdn.microsoft.com/en-us/library/e737s6tf.aspx) or [`PathStripPath()`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb773756.aspx). – Remy Lebeau Aug 19 '15 at 14:53
0

I assume you are coding in C. You most likely have not allocated MAX_PATH + 1 characters for filename.

Richard Schneider
  • 34,944
  • 9
  • 57
  • 73