How to find the parent exe of a dll from inside the dll?
Asked Answered
N

3

8

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)

Nidus answered 9/6, 2011 at 0:51 Comment(1)
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.Brachial
T
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.

Tade answered 16/12, 2013 at 15:35 Comment(2)
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;Invigorate
@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.Tade
C
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.

Camporee answered 17/8, 2015 at 5:44 Comment(3)
Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Randirandie
Hope this will be useful and easy to understandCamporee
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() or PathStripPath().Invigorate
B
0

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

Broddie answered 9/6, 2011 at 1:30 Comment(3)
@Richard MAX_PATH+1 changes nothing :( and I am working in vc++Nidus
I edited my original post. I narrowed it down to a more specific error. Thank you.Nidus
As I said its fileName. Try this char filename[MAX_PATH+1];Broddie

© 2022 - 2024 — McMap. All rights reserved.