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.

288 lines
7.9 KiB

  1. //=================================================================
  2. //
  3. // DllWrapperBase.cpp
  4. //
  5. // Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  6. //
  7. //=================================================================
  8. #include "precomp.h"
  9. #include <cominit.h>
  10. #include "DllWrapperBase.h"
  11. #include <..\..\framework\provexpt\include\provexpt.h>
  12. /******************************************************************************
  13. * Constructor
  14. ******************************************************************************/
  15. CDllWrapperBase::CDllWrapperBase(LPCTSTR a_tstrWrappedDllName)
  16. : m_tstrWrappedDllName(a_tstrWrappedDllName),
  17. m_hDll(NULL)
  18. {
  19. }
  20. /******************************************************************************
  21. * Destructor
  22. ******************************************************************************/
  23. CDllWrapperBase::~CDllWrapperBase()
  24. {
  25. if(m_hDll != NULL)
  26. {
  27. FreeLibrary(m_hDll);
  28. }
  29. }
  30. /******************************************************************************
  31. * Initialization function to load the dll, obtain function addresses, and
  32. * check that we obtained function addresses.
  33. * Init should fail only if the minimum set of functions was not available;
  34. * functions added in later versions may or may not be present - it is the
  35. * client's responsibility in such cases to check, in their code, for the
  36. * version of the dll before trying to call such functions. Not doing so
  37. * when the function is not present will result in an AV.
  38. ******************************************************************************/
  39. // bool CDllWrapperBase::Init()
  40. // << PURE VIRTUAL FUNCTION -> DERIVED CLASSES MUST OVERLOAD.
  41. /******************************************************************************
  42. * Helper for loading the dll that hides the implementation. Returns true
  43. * if we succeeded in obtaining a handle to the dll.
  44. ******************************************************************************/
  45. bool CDllWrapperBase::LoadLibrary()
  46. {
  47. bool t_fRet = false;
  48. if(m_hDll != NULL)
  49. {
  50. FreeLibrary(m_hDll);
  51. }
  52. if((m_hDll = ::LoadLibrary(m_tstrWrappedDllName)) != NULL)
  53. {
  54. t_fRet = true;
  55. }
  56. else
  57. {
  58. // this is possible to be neccessary in the future !!!
  59. // resource manager may start to care about error from load library
  60. //
  61. // let resource manager know load failed
  62. //
  63. m_bValid = FALSE;
  64. m_dwCreationError = ::GetLastError ();
  65. LogErrorMessage2(L"Failed to load library: %s", m_tstrWrappedDllName);
  66. }
  67. return t_fRet;
  68. }
  69. /******************************************************************************
  70. * Helper for getting proc addresses that hides the implementation.
  71. ******************************************************************************/
  72. FARPROC CDllWrapperBase::GetProcAddress(LPCSTR a_strProcName)
  73. {
  74. FARPROC t_fpProc = NULL;
  75. if(m_hDll != NULL)
  76. {
  77. t_fpProc = ::GetProcAddress(m_hDll, a_strProcName);
  78. }
  79. return t_fpProc;
  80. }
  81. /******************************************************************************
  82. * Helper for retrieving the version of the dll wrapped by this class.
  83. ******************************************************************************/
  84. BOOL CDllWrapperBase::GetDllVersion(CHString& a_chstrVersion)
  85. {
  86. return (GetVarFromVersionInfo(
  87. m_tstrWrappedDllName, // Name of file to get ver info about
  88. _T("ProductVersion"), // String identifying resource of interest
  89. a_chstrVersion)); // Buffer to hold version string
  90. }
  91. /******************************************************************************
  92. * Member functions wrapping Kernel32 api functions. Add new functions here
  93. * as required.
  94. ******************************************************************************/
  95. // << Section empty in base class only. >>
  96. /******************************************************************************
  97. * Private parts.
  98. ******************************************************************************/
  99. BOOL CDllWrapperBase::GetVarFromVersionInfo
  100. (
  101. LPCTSTR a_szFile,
  102. LPCTSTR a_szVar,
  103. CHString &a_strValue
  104. )
  105. {
  106. BOOL t_fRc = FALSE;
  107. DWORD t_dwTemp;
  108. DWORD t_dwBlockSize = 0L;
  109. LPVOID t_pInfo = NULL;
  110. // Use of delay loaded function requires exception handler.
  111. SetStructuredExceptionHandler seh;
  112. try
  113. {
  114. t_dwBlockSize = ::GetFileVersionInfoSize((LPTSTR) a_szFile, &t_dwTemp);
  115. if (t_dwBlockSize)
  116. {
  117. t_pInfo = (LPVOID) new BYTE[t_dwBlockSize + 4];
  118. if ( !t_pInfo )
  119. {
  120. throw CHeap_Exception( CHeap_Exception::E_ALLOCATION_ERROR ) ;
  121. }
  122. UINT t_len;
  123. memset( t_pInfo, NULL, t_dwBlockSize + 4);
  124. if (::GetFileVersionInfo((LPTSTR) a_szFile, 0, t_dwBlockSize, t_pInfo))
  125. {
  126. WORD wLang = 0;
  127. WORD wCodePage = 0;
  128. if(!GetVersionLanguage(t_pInfo, &wLang, &wCodePage) )
  129. {
  130. // on failure: default to English
  131. // this returns a pointer to an array of WORDs
  132. WORD *pArray;
  133. bool fGotTranslation = false;
  134. fGotTranslation = ::VerQueryValue(
  135. t_pInfo, _T("\\VarFileInfo\\Translation"),
  136. (void **)(&pArray),
  137. &t_len);
  138. if(fGotTranslation)
  139. {
  140. t_len = t_len / sizeof(WORD);
  141. // find the english one...
  142. for (int i = 0; i < t_len; i += 2)
  143. {
  144. if( pArray[i] == 0x0409 ) {
  145. wLang = pArray[i];
  146. wCodePage = pArray[i + 1];
  147. break;
  148. }
  149. }
  150. }
  151. }
  152. TCHAR *pMfg, szTemp[256];
  153. StringCchPrintf(szTemp,LENGTH_OF(szTemp), _T("\\StringFileInfo\\%04X%04X\\%s"), wLang, wCodePage, a_szVar);
  154. bool fGotCodePageInfo = false;
  155. fGotCodePageInfo = ::VerQueryValue(
  156. t_pInfo,
  157. szTemp, (void **)
  158. (&pMfg),
  159. &t_len);
  160. if(fGotCodePageInfo)
  161. {
  162. a_strValue = pMfg;
  163. t_fRc = TRUE;
  164. }
  165. }
  166. delete t_pInfo;
  167. t_pInfo = NULL ;
  168. }
  169. }
  170. catch(Structured_Exception se)
  171. {
  172. DelayLoadDllExceptionFilter(se.GetExtendedInfo());
  173. if (t_pInfo)
  174. {
  175. delete t_pInfo ;
  176. }
  177. t_fRc = FALSE;
  178. }
  179. catch(...)
  180. {
  181. if (t_pInfo)
  182. {
  183. delete t_pInfo ;
  184. }
  185. throw ;
  186. }
  187. return t_fRc;
  188. }
  189. BOOL CDllWrapperBase::GetVersionLanguage
  190. (
  191. void *a_vpInfo,
  192. WORD *a_wpLang,
  193. WORD *a_wpCodePage
  194. )
  195. {
  196. WORD *t_wpTemp;
  197. WORD t_wLength;
  198. WCHAR *t_wcpTemp;
  199. char *t_cpTemp;
  200. BOOL t_bRet = FALSE;
  201. t_wpTemp = (WORD *) a_vpInfo;
  202. t_cpTemp = (char *) a_vpInfo;
  203. t_wpTemp++; // jump past buffer length.
  204. t_wLength = *t_wpTemp; // capture value length.
  205. t_wpTemp++; // skip past value length to what should be type code in new format
  206. if (*t_wpTemp == 0 || *t_wpTemp == 1) // new format expect unicode strings.
  207. {
  208. t_cpTemp = t_cpTemp + 38 + t_wLength + 8;
  209. t_wcpTemp = (WCHAR *) t_cpTemp;
  210. if (wcscmp(L"StringFileInfo", t_wcpTemp) == 0) // OK! were aligned properly.
  211. {
  212. t_bRet = TRUE;
  213. t_cpTemp += 30; // skip over "StringFileInfo"
  214. while ((DWORD_PTR) t_cpTemp % 4 > 0) // 32 bit align
  215. t_cpTemp++;
  216. t_cpTemp += 6; // skip over length and type fields.
  217. t_wcpTemp = (WCHAR *) t_cpTemp;
  218. swscanf(t_wcpTemp, L"%4x%4x", a_wpLang, a_wpCodePage);
  219. }
  220. }
  221. else // old format, expect single byte character strings.
  222. {
  223. t_cpTemp += 20 + t_wLength + 4;
  224. if (strcmp("StringFileInfo", t_cpTemp) == 0) // OK! were aligned properly.
  225. {
  226. t_bRet = TRUE;
  227. t_cpTemp += 20; // skip over length fields.
  228. sscanf(t_cpTemp, "%4x%4x", a_wpLang, a_wpCodePage);
  229. }
  230. }
  231. return (t_bRet);
  232. }