dllload.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 8k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "priv.h"
  2. #include <wininet.h>
  3. #pragma warning(disable:4229)  // No warnings when modifiers used on data
  4. // Delay loading mechanism.  This allows you to write code as if you are
  5. // calling implicitly linked APIs, and yet have these APIs really be
  6. // explicitly linked.  You can reduce the initial number of DLLs that 
  7. // are loaded (load on demand) using this technique.
  8. //
  9. // Use the following macros to indicate which APIs/DLLs are delay-linked
  10. // and -loaded.
  11. //
  12. //      DELAY_LOAD
  13. //      DELAY_LOAD_HRESULT
  14. //      DELAY_LOAD_SAFEARRAY
  15. //      DELAY_LOAD_UINT
  16. //      DELAY_LOAD_INT
  17. //      DELAY_LOAD_VOID
  18. //
  19. // Use these macros for APIs that are exported by ordinal only.
  20. //
  21. //      DELAY_LOAD_ORD
  22. //      DELAY_LOAD_ORD_VOID     
  23. //
  24. // Use these macros for APIs that only exist on the integrated-shell
  25. // installations (i.e., a new shell32 is on the system).
  26. //
  27. //      DELAY_LOAD_SHELL
  28. //      DELAY_LOAD_SHELL_HRESULT
  29. //      DELAY_LOAD_SHELL_VOID     
  30. //
  31. // 
  32. /**********************************************************************/
  33. void _GetProcFromDLL(HINSTANCE* phinst, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc)
  34. {
  35. #ifdef DEBUG
  36.     CHAR szProcD[MAX_PATH];
  37.     if (HIWORD(pszProc)) {
  38.         lstrcpynA(szProcD, pszProc, ARRAYSIZE(szProcD));
  39.     } else {
  40.         wnsprintfA(szProcD, ARRAYSIZE(szProcD), "(ordinal %d)", LOWORD(pszProc));
  41.     }
  42. #endif // DEBUG
  43.     // If it's already loaded, return.
  44.     if (*ppfn) {
  45.     return;
  46.     }
  47.     if (*phinst == NULL) {
  48. #ifdef DEBUG
  49.     TraceMsg(TF_FTP_DLLLOADING, "DLLLOAD: Loading %hs for the first time for %hs", pszDLL, szProcD);
  50.     
  51. /*
  52.     if (g_dwBreakFlags & TF_FTP_DLLLOAD_BREAK)
  53.     {
  54.         DebugBreak();
  55.     }
  56. */
  57. #endif // DEBUG
  58.     *phinst = LoadLibraryA(pszDLL);
  59.     if (*phinst == NULL) {
  60.         return;
  61.     }
  62.     }
  63. #ifdef DEBUG
  64.     TraceMsg(TF_FTP_DLLLOADING, "DLLLOAD: GetProc'ing %hs from %hs for the first time", pszDLL, szProcD);
  65. #endif // DEBUG
  66.     *ppfn = GetProcAddress(*phinst, pszProc);
  67. }
  68. /*----------------------------------------------------------
  69. Purpose: Performs a loadlibrary on the DLL only if the machine
  70.      has the integrated shell installation.
  71. */
  72. void _SHGetProcFromDLL(HINSTANCE* phinst, LPCSTR pszDLL, FARPROC* ppfn, LPCSTR pszProc)
  73. {
  74.     _GetProcFromDLL(phinst, pszDLL, ppfn, pszProc);
  75. }
  76. #define DELAY_LOAD_MAP(_hinst, _dll, _ret, _fnpriv, _fn, _args, _nargs, _err) 
  77. _ret __stdcall _fnpriv _args                
  78. {                                       
  79.     static _ret (* __stdcall _pfn##_fn) _args = NULL;   
  80.     _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); 
  81.     if (_pfn##_fn)               
  82.     return _pfn##_fn _nargs; 
  83.     return (_ret)_err;           
  84. }
  85. #define DELAY_MAP_HRESULT(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, HRESULT, _fnpriv, _fn, _args, _nargs, E_FAIL)
  86. #define DELAY_MAP_DWORD(_hinst, _dll, _fnpriv, _fn, _args, _nargs) DELAY_LOAD_MAP(_hinst, _dll, DWORD, _fnpriv, _fn, _args, _nargs, 0)
  87. #define DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, _err)    DELAY_LOAD_MAP(_hinst, _dll, _ret, _fn, _fn, _args, _nargs, _err)
  88. #define DELAY_LOAD(_hinst, _dll, _ret, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, _ret, _fn, _args, _nargs, 0)
  89. #define DELAY_LOAD_HRESULT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, HRESULT, _fn, _args, _nargs, E_FAIL)
  90. #define DELAY_LOAD_SAFEARRAY(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, SAFEARRAY *, _fn, _args, _nargs, NULL)
  91. #define DELAY_LOAD_DWORD(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, DWORD, _fn, _args, _nargs, 0)
  92. #define DELAY_LOAD_UINT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, UINT, _fn, _args, _nargs, 0)
  93. #define DELAY_LOAD_INT(_hinst, _dll, _fn, _args, _nargs) DELAY_LOAD_ERR(_hinst, _dll, INT, _fn, _args, _nargs, 0)
  94. #define DELAY_LOAD_VOID(_hinst, _dll, _fn, _args, _nargs) 
  95. void __stdcall _fn _args                
  96. {                                       
  97.     static void (* __stdcall _pfn##_fn) _args = NULL;   
  98.     _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, #_fn); 
  99.     if (_pfn##_fn)              
  100.     _pfn##_fn _nargs;       
  101.     return;                     
  102. }
  103. //
  104. // For private entrypoints exported by ordinal.
  105. // 
  106. #define DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) 
  107. _ret __stdcall _fn _args                
  108. {                                       
  109.     static _ret (* __stdcall _pfn##_fn) _args = NULL;   
  110.     _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord);   
  111.     if (_pfn##_fn)               
  112.     return _pfn##_fn _nargs; 
  113.     return (_ret)_err;           
  114. }
  115.     
  116. #define DELAY_LOAD_ORD(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  117. #define DELAY_LOAD_ORD_HRESULT(_hinst, _dll, _fn, _ord, _args, _nargs) DELAY_LOAD_ORD(_hinst, _dll, HRESULT, _fn, _ord, _args, _nargs)
  118. #define DELAY_LOAD_ORD_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) 
  119. void __stdcall _fn _args                
  120. {                                       
  121.     static void (* __stdcall _pfn##_fn) _args = NULL;   
  122.     _GetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord);   
  123.     if (_pfn##_fn)              
  124.     _pfn##_fn _nargs;       
  125.     return;                     
  126. }
  127. //
  128. //  Private exports by ordinal for integrated-shell installs
  129. //
  130. #define DELAY_LOAD_SHELL_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, _err) 
  131. _ret __stdcall _fn _args                
  132. {                                       
  133.     static _ret (* __stdcall _pfn##_fn) _args = NULL;   
  134.     _SHGetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord);   
  135.     if (_pfn##_fn)               
  136.     return _pfn##_fn _nargs; 
  137.     return (_ret)_err;           
  138. }
  139.     
  140. #define DELAY_LOAD_SHELL(_hinst, _dll, _ret, _fn, _ord, _args, _nargs) DELAY_LOAD_SHELL_ERR(_hinst, _dll, _ret, _fn, _ord, _args, _nargs, 0)
  141. #define DELAY_LOAD_SHELL_HRESULT(_hinst, _dll, _fn, _ord, _args, _nargs) DELAY_LOAD_SHELL_ERR(_hinst, _dll, HRESULT, _fn, _ord, _args, _nargs, E_FAIL)
  142. #define DELAY_LOAD_SHELL_VOID(_hinst, _dll, _fn, _ord, _args, _nargs) 
  143. void __stdcall _fn _args                
  144. {                                       
  145.     static void (* __stdcall _pfn##_fn) _args = NULL;   
  146.     _SHGetProcFromDLL(&_hinst, #_dll, (FARPROC*)&_pfn##_fn, (LPCSTR)_ord); 
  147.     if (_pfn##_fn)              
  148.     _pfn##_fn _nargs;       
  149.     return;                     
  150. }
  151. /**********************************************************************/
  152. /**********************************************************************/
  153. // --------- MLANG.DLL ---------------
  154. HINSTANCE g_hinstMLANG = NULL;
  155. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, ConvertINetMultiByteToUnicode,
  156.             (LPDWORD lpdwMode, DWORD dwEncoding, LPCSTR lpSrcStr, LPINT lpnMultiCharCount, LPWSTR lpDstStr, LPINT lpnWideCharCount),
  157.             (lpdwMode, dwEncoding, lpSrcStr, lpnMultiCharCount, lpDstStr, lpnWideCharCount));
  158. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, ConvertINetUnicodeToMultiByte,
  159.             (LPDWORD lpdwMode, DWORD dwEncoding, LPCWSTR lpSrcStr, LPINT lpnWideCharCount, LPSTR lpDstStr, LPINT lpnMultiCharCount),
  160.             (lpdwMode, dwEncoding, lpSrcStr, lpnWideCharCount, lpDstStr, lpnMultiCharCount));
  161. DELAY_LOAD_HRESULT(g_hinstMLANG, MLANG.DLL, LcidToRfc1766W,
  162.             (LCID Locale, LPWSTR pszRfc1766, int nChar),
  163.             (Locale, pszRfc1766, nChar));
  164. // --------- MSHTML.DLL ---------------
  165. HINSTANCE g_hinstMSHTML = NULL;
  166. DELAY_LOAD_HRESULT(g_hinstMSHTML, MSHTML.DLL, ShowHTMLDialog,
  167.             (HWND hwnd, IMoniker * pmk, VARIANT * pvarArgIn, LPWSTR pchOptions, VARIANT * pvarArgOut),
  168.             (hwnd, pmk, pvarArgIn, pchOptions, pvarArgOut));
  169. // --------- SHELL32.DLL ---------------
  170. HINSTANCE g_hinstSHELL32 = NULL;
  171. DELAY_LOAD_ORD_HRESULT(g_hinstSHELL32, SHELL32.DLL, _SHCreateShellFolderView, SHCreateShellFolderViewORD,
  172.                  (const SFV_CREATE* pcsfv, LPSHELLVIEW FAR* ppsv),
  173.                  (pcsfv, ppsv));
  174. DELAY_MAP_HRESULT(g_hinstSHELL32, SHELL32.DLL, _SHPathPrepareForWriteW, SHPathPrepareForWriteW,
  175.                  (HWND hwnd, IUnknown *punkEnableModless, LPCWSTR pwzPath, DWORD dwFlags),
  176.                  (hwnd, punkEnableModless, pwzPath, dwFlags));
  177. #pragma warning(default:4229)