Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
6.8 KiB

  1. /*
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. DelayDllInit.cpp
  5. Abstract:
  6. This Shim delays the DllInit of given DLLs on the command line until at
  7. SHIM_STATIC_DLLS_INITIALIZED
  8. One problem was: Autodesk 3D Studio Mask does the bad thing of creating windows
  9. during their Splash!DllInit. This is not allowed but works on previous OSes. It
  10. also works fine on regular US install. But if you enable Far East language
  11. support, then the IME creates a window on top of the main window and we get in a
  12. situation where ADVAPI32 is called before it initialized. Solution is simple:
  13. delay SPLASH.
  14. There is a better way to do this, but we would need a callback in NTDLL right after
  15. it loads KERNEL32.
  16. History:
  17. 06/11/2001 pierreys Created
  18. */
  19. #include "precomp.h"
  20. IMPLEMENT_SHIM_BEGIN(DelayDllInit)
  21. #include "ShimHookMacro.h"
  22. APIHOOK_ENUM_BEGIN
  23. APIHOOK_ENUM_END
  24. #pragma pack(push)
  25. #pragma pack(1)
  26. typedef struct _ENTRYPATCH {
  27. BYTE bJmp;
  28. DWORD dwRelativeAddress;
  29. } ENTRYPATCH, *PENTRYPATCH;
  30. #pragma pack(pop)
  31. typedef struct _DLLPATCH {
  32. struct _DLLPATCH *Next;
  33. HMODULE hModule;
  34. DWORD dwOldProtection;
  35. ENTRYPATCH epSave;
  36. PENTRYPATCH pepFix;
  37. } DLLPATCH, *PDLLPATCH;
  38. PDLLPATCH pDllPatchHead=NULL;
  39. BOOL WINAPI
  40. PatchedDllMain(
  41. HINSTANCE hinstDll,
  42. DWORD fdwReason,
  43. LPVOID lpvReserved
  44. )
  45. {
  46. if (fdwReason != DLL_PROCESS_ATTACH)
  47. LOGN(eDbgLevelError, "PatchDllMain invalidely called");
  48. return(TRUE);
  49. }
  50. BOOL
  51. NOTIFY_FUNCTION(
  52. DWORD fdwReason
  53. )
  54. {
  55. PIMAGE_NT_HEADERS pImageNTHeaders;
  56. DWORD dwUnused;
  57. PDLLPATCH pDllPatch;
  58. switch (fdwReason)
  59. {
  60. case DLL_PROCESS_ATTACH:
  61. CSTRING_TRY
  62. {
  63. int i, iDllCount;
  64. CString *csArguments;
  65. CString csCl(COMMAND_LINE);
  66. CStringParser csParser(csCl, L";");
  67. iDllCount = csParser.GetCount();
  68. csArguments = csParser.ReleaseArgv();
  69. for (i=0; i<iDllCount; i++)
  70. {
  71. pDllPatch=(PDLLPATCH)LocalAlloc(LMEM_FIXED, sizeof(*pDllPatch));
  72. if (pDllPatch)
  73. {
  74. pDllPatch->hModule=GetModuleHandle(csArguments[i].Get());
  75. if (pDllPatch->hModule)
  76. {
  77. pImageNTHeaders=RtlImageNtHeader(pDllPatch->hModule);
  78. if (pImageNTHeaders)
  79. {
  80. pDllPatch->pepFix=(PENTRYPATCH)((DWORD)(pImageNTHeaders->OptionalHeader.AddressOfEntryPoint)+(DWORD)(pDllPatch->hModule));
  81. if (pDllPatch->pepFix)
  82. {
  83. if (VirtualProtect(pDllPatch->pepFix, sizeof(*(pDllPatch->pepFix)), PAGE_READWRITE, &(pDllPatch->dwOldProtection)))
  84. {
  85. memcpy(&(pDllPatch->epSave), pDllPatch->pepFix, sizeof(pDllPatch->epSave));
  86. //
  87. // Warning: this is X86 only.
  88. //
  89. pDllPatch->pepFix->bJmp=0xE9; // 32-bit near relative jump
  90. pDllPatch->pepFix->dwRelativeAddress=(DWORD)PatchedDllMain-(DWORD)(pDllPatch->pepFix)-sizeof(*(pDllPatch->pepFix));
  91. pDllPatch->Next=pDllPatchHead;
  92. pDllPatchHead=pDllPatch;
  93. }
  94. else
  95. {
  96. LOGN(eDbgLevelError, "Failed to make the DllMain of %S writable", csArguments[i].Get());
  97. return FALSE;
  98. }
  99. }
  100. else
  101. {
  102. LOGN(eDbgLevelError, "Failed to get the DllMain of %S", csArguments[i].Get());
  103. return FALSE;
  104. }
  105. }
  106. else
  107. {
  108. LOGN(eDbgLevelError, "Failed to get the header of %S", csArguments[i].Get());
  109. return FALSE;
  110. }
  111. }
  112. else
  113. {
  114. LOGN(eDbgLevelError, "Failed to get the %S Dll", csArguments[i].Get());
  115. return FALSE;
  116. }
  117. }
  118. else
  119. {
  120. LOGN(eDbgLevelError, "Failed to allocate memory for %S", csArguments[i].Get());
  121. return FALSE;
  122. }
  123. }
  124. }
  125. CSTRING_CATCH
  126. {
  127. return FALSE;
  128. }
  129. break;
  130. case SHIM_STATIC_DLLS_INITIALIZED:
  131. if (pDllPatchHead)
  132. {
  133. PDLLPATCH pNextDllPatch;
  134. for (pDllPatch=pDllPatchHead; pDllPatch; pDllPatch=pNextDllPatch)
  135. {
  136. memcpy(pDllPatch->pepFix, &(pDllPatch->epSave), sizeof(*(pDllPatch->pepFix)));
  137. if (!VirtualProtect(pDllPatch->pepFix, sizeof(*(pDllPatch->pepFix)), pDllPatch->dwOldProtection, &dwUnused))
  138. {
  139. LOGN(eDbgLevelWarning, "Failed to reprotect Dll at %08X", pDllPatch->hModule);
  140. }
  141. if (!((PDLL_INIT_ROUTINE)(pDllPatch->pepFix))(pDllPatch->hModule, DLL_PROCESS_ATTACH, (PCONTEXT)1))
  142. {
  143. LOGN(eDbgLevelError, "Failed to initialize Dll at %08X", pDllPatch->hModule);
  144. return(FALSE);
  145. }
  146. pNextDllPatch=pDllPatch->Next;
  147. if (!LocalFree(pDllPatch))
  148. {
  149. LOGN(eDbgLevelWarning, "Failed to free memory Dll at %08X", pDllPatch->hModule);
  150. }
  151. }
  152. }
  153. else
  154. {
  155. LOGN(eDbgLevelError, "Failed to get Dll list");
  156. return FALSE;
  157. }
  158. break;
  159. }
  160. return TRUE;
  161. }
  162. HOOK_BEGIN
  163. CALL_NOTIFY_FUNCTION
  164. HOOK_END
  165. IMPLEMENT_SHIM_END