Source code of Windows XP (NT5)
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.

169 lines
6.7 KiB

  1. #include "cabinet.h"
  2. #include <desktray.h>
  3. #include "uemapp.h"
  4. #pragma warning(disable:4229) // No warnings when modifiers used on data
  5. // Delay loading mechanism. This allows you to write code as if you are
  6. // calling implicitly linked APIs, and yet have these APIs really be
  7. // explicitly linked. You can reduce the initial number of DLLs that
  8. // are loaded (load on demand) using this technique.
  9. //
  10. // Use the following macros to indicate which APIs/DLLs are delay-linked
  11. // and -loaded.
  12. //
  13. // DELAY_LOAD
  14. // DELAY_LOAD_HRESULT
  15. // DELAY_LOAD_SAFEARRAY
  16. // DELAY_LOAD_UINT
  17. // DELAY_LOAD_INT
  18. // DELAY_LOAD_VOID
  19. //
  20. // Use these macros for APIs that are exported by ordinal only.
  21. //
  22. // DELAY_LOAD_ORD
  23. // DELAY_LOAD_ORD_VOID
  24. //
  25. // These macros produce code that looks like
  26. #if 0
  27. BOOL GetOpenFileNameA(LPOPENFILENAME pof)
  28. {
  29. static BOOL (*pfnGetOpenFileNameA)(LPOPENFILENAME pof);
  30. if (ENSURE_LOADED(g_hinstCOMDLG32, "COMDLG32.DLL"))
  31. {
  32. if (pfnGetOpenFileNameA == NULL)
  33. pfnGetOpenFileNameA = (BOOL (*)(LPOPENFILENAME))GetProcAddress(g_hinstCOMDLG32, "GetOpenFileNameA");
  34. if (pfnGetOpenFileNameA)
  35. return pfnGetOpenFileNameA(pof);
  36. }
  37. return -1;
  38. }
  39. #endif
  40. /**********************************************************************/
  41. #ifdef DEBUG
  42. void _DumpLoading(LPTSTR pszDLL, LPTSTR pszFunc)
  43. {
  44. if (g_dwDumpFlags & DF_DELAYLOADDLL)
  45. {
  46. TraceMsg(TF_ALWAYS, "DLLLOAD: Loading %s for the first time for %s",
  47. pszDLL, pszFunc);
  48. }
  49. }
  50. #define ENSURE_LOADED(_hinst, _dll, pszfn) (_hinst ? _hinst : (_DumpLoading(TEXT(#_dll), pszfn), _hinst = LoadLibrary(TEXT(#_dll))))
  51. #else
  52. #define ENSURE_LOADED(_hinst, _dll, pszfn) (_hinst ? _hinst : (_hinst = LoadLibrary(TEXT(#_dll))))
  53. #endif // DEBUG
  54. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err) \
  55. _ret __stdcall _fn _args \
  56. { \
  57. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  58. if (!ENSURE_LOADED(_hinst, _dll, TEXT(#_fn))) \
  59. { \
  60. /*ASSERT_MSG((BOOL)_hinst, "LoadLibrary failed on " ## #_dll);*/ \
  61. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  62. return (_ret)_err; \
  63. } \
  64. if (_pfn##_fn == NULL) \
  65. { \
  66. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  67. /*ASSERT_MSG(NULL != _pfn##_fn, "GetProcAddress failed on " ## #_fn);*/ \
  68. if (_pfn##_fn == NULL) \
  69. return (_ret)_err; \
  70. } \
  71. return _pfn##_fn _nargs; \
  72. }
  73. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  74. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  75. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  76. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  77. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  78. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  79. #define DELAY_LOAD_BOOL(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, BOOL, _fn, _args, _nargs, FALSE)
  80. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) \
  81. void __stdcall _fn _args \
  82. { \
  83. static void (* __stdcall _pfn##_fn) _args = NULL; \
  84. if (!ENSURE_LOADED(_hinst, _dll, TEXT(#_fn))) \
  85. { \
  86. /*AssertMsg((BOOL)_hinst, "LoadLibrary failed on " ## #_dll);*/ \
  87. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  88. return; \
  89. } \
  90. if (_pfn##_fn == NULL) \
  91. { \
  92. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, #_fn); \
  93. /*AssertMsg(NULL != _pfn##_fn, "GetProcAddress failed on " ## #_fn);*/ \
  94. if (_pfn##_fn == NULL) \
  95. return; \
  96. } \
  97. _pfn##_fn _nargs; \
  98. }
  99. //
  100. // For private entrypoints exported by ordinal.
  101. //
  102. #define DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) \
  103. _ret __stdcall _fn _args \
  104. { \
  105. static _ret (* __stdcall _pfn##_fn) _args = NULL; \
  106. if (!ENSURE_LOADED(_hinst, _dll, TEXT("(ordinal ") TEXT(#_ord) TEXT(")"))) \
  107. { \
  108. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  109. return (_ret)_err; \
  110. } \
  111. if (_pfn##_fn == NULL) \
  112. { \
  113. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR) _ord); \
  114. \
  115. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  116. But do the check anyways... */ \
  117. \
  118. if (_pfn##_fn == NULL) \
  119. return (_ret)_err; \
  120. } \
  121. return _pfn##_fn _nargs; \
  122. }
  123. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  124. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) \
  125. void __stdcall _fn _args \
  126. { \
  127. static void (* __stdcall _pfn##_fn) _args = NULL; \
  128. if (!ENSURE_LOADED(_hinst, _dll, TEXT("(ordinal ") TEXT(#_ord) TEXT(")"))) \
  129. { \
  130. TraceMsg(TF_ERROR, "LoadLibrary failed on " ## #_dll); \
  131. return; \
  132. } \
  133. if (_pfn##_fn == NULL) \
  134. { \
  135. *(FARPROC*)&(_pfn##_fn) = GetProcAddress(_hinst, (LPSTR)_ord); \
  136. \
  137. /* GetProcAddress always returns non-NULL, even for bad ordinals. \
  138. But do the check anyways... */ \
  139. \
  140. if (_pfn##_fn == NULL) \
  141. return; \
  142. } \
  143. _pfn##_fn _nargs; \
  144. }
  145. #pragma warning(default:4229)