1

Background

I've read Dynamic-Link Library Best Practices and understood what I can and can't do in DllMain.

Now, say I have a visual studio 2013 solution containing many projects. each project generates different binaries/lib files.

Say I have some utility project, generating a lib file, used by all projects.

Now, this utility project, may define some generic functions that calls, for example, LoadLibrary function which based on the link above is something that: never perform the following tasks from within DllMain

Question

  1. How can I implement a generic function, that "knows" that it can't use certain API because it is being called withing the scope of DllMain function?

  2. Is it possible to access windows loader lock and by that disable certain calls or change function's algorithm if it is locked?

Example

Project Utility

wstring GetUserName() // just an example!
{
   // do something including LoadLibrary call
}

Project A

BOOL WINAPI DllMain(
  _In_  HINSTANCE hinstDLL,
  _In_  DWORD fdwReason,
  _In_  LPVOID lpvReserved
)
{
   // calls Utility - GetUserName()
}

Project B

int _tmain(int argc, _TCHAR* argv[])
{
   // calls Utility - GetUserName()
}

While the call to function GetUserName() is perfectly fine in Project B, it is prohibited in Project A

I want to make mu solution smart in such way that I avoid such cases.

Theoretical approach

wstring GetUserName() // just an example!
{
   if( IsLoaderLocked() )
      // do something excluding LoadLibrary call
   else
      // do something including LoadLibrary call
}

the if( IsLoaderLocked() ) is not a real code, of course. Just an example of a condition I'd like to evaluate before calling "dangerous" API.

idanshmu
  • 5,061
  • 6
  • 46
  • 92
  • I have a feeling, that you messed things up. First of all, your 'utility' project generates `lib` file. Static libraries do not have anything like `DllMain()`. Also, `DllMain()` is not even required in DLLs. It is a very Windows-specific thing. Please, explain more about structure of your project and relationship between its components. – Mateusz Grzejek Apr 05 '15 at 14:34
  • @MateuszGrzejek I've added an example. – idanshmu Apr 06 '15 at 05:36
  • It is possible to call `LoadLibrary` within `DllMain`. There is no problem as long as there is a well-understood dependency in order of DLL initialization. The matter with `LoaderLock` is that it is held implicitly, so if you also use your own locks - this may lead to deadlock. For instance, a typical mistake is to create a thread in a `DllMain` and wait for it, whereas that thread calls some API that implicitly calls `LoadLibrary` as well. – valdo Apr 06 '15 at 05:57
  • @valdo The above example is just an example :). whether or not _It is possible to call `LoadLibrary` within `DllMain`_ is not the **real** issue. eventually There are some operations, taking place in `Project Utility`, that are not allowed whiting `DllMain`. I'm trying to bulletproof my code to any deadlock that **may** occur. – idanshmu Apr 06 '15 at 06:29
  • Don't really understand why this question is flagged as "too broad". there must be a best practice approach to this generic issue. – idanshmu Apr 06 '15 at 06:33
  • If there is a best practice, it's 'don't create complex DllMain initializations. If you think you need one, think some more.' – bmargulies Apr 06 '15 at 22:07
  • @bmargulies. I 100% agree with _ 'don't create complex `DllMain`_ and I do think that this is the right thing to do. **However, the question still remains**. So, instead of bypassing the issue I'm trying to solve it, in the most elegant and robust way there is. – idanshmu Apr 07 '15 at 06:02

0 Answers0