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.

401 lines
9.0 KiB

  1. //------------------------------------------------------------------------------
  2. //
  3. // File: dllentry.cpp
  4. // Copyright (C) 1995-1997 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // Purpose:
  8. // Defines the initialization routines for the DLL.
  9. //
  10. // This file needs minor changes, as marked by TODO comments. However, the
  11. // functions herein are only called by the system, Espresso, or the framework,
  12. // and you should not need to look at them extensively.
  13. //
  14. // Owner:
  15. //
  16. //------------------------------------------------------------------------------
  17. #include "stdafx.h"
  18. #include "clasfact.h"
  19. #include "win32sub.h"
  20. #include "impbin.h"
  21. #include "misc.h"
  22. #include "resource.h"
  23. #define __DLLENTRY_CPP
  24. #include "dllvars.h"
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char BASED_CODE THIS_FILE[] = __FILE__;
  28. #endif
  29. #define new DEBUG_NEW
  30. LONG g_lActiveClasses = 0; //Glbal count of active class in the DLL
  31. static AFX_EXTENSION_MODULE g_parseDLL = { NULL, NULL };
  32. CItemSetException g_SetException(FALSE);
  33. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  34. //
  35. // DLL Main entry
  36. //
  37. //------------------------------------------------------------------------------
  38. extern "C" int APIENTRY
  39. DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
  40. {
  41. UNREFERENCED_PARAMETER(lpReserved);
  42. int nRet = 1; //OK
  43. if (dwReason == DLL_PROCESS_ATTACH)
  44. {
  45. LTTRACE("BMOF.DLL Initializing!\n"); //TODO - change name
  46. // Extension DLL one-time initialization
  47. AfxInitExtensionModule(g_parseDLL, hInstance);
  48. // Insert this DLL into the resource chain
  49. new CDynLinkLibrary(g_parseDLL);
  50. g_hDll = hInstance;
  51. }
  52. else if (dwReason == DLL_PROCESS_DETACH)
  53. {
  54. LTTRACE("BMOF.DLL Terminating!\n"); //TODO - change name
  55. // Remove this DLL from MFC's list of extensions
  56. AfxTermExtensionModule(g_parseDLL);
  57. //
  58. // If there are active classes, they WILL explode badly once the
  59. // DLL is unloaded...
  60. //
  61. LTASSERT(DllCanUnloadNow() == S_OK);
  62. AfxTermExtensionModule(g_parseDLL);
  63. }
  64. return nRet;
  65. }
  66. // TODO: Use GUIDGEN.EXE to replace this class ID with a unique one.
  67. // GUIDGEN is supplied with MSDEV (VC++ 4.0) as part of the OLE support stuff.
  68. // Run it and you'll get a little dialog box. Pick radio button 3, "static
  69. // const struct GUID = {...}". Click on the "New GUID" button, then the "Copy"
  70. // button, which puts the result in the clipboard. From there, you can just
  71. // paste it into here. Just remember to change the type to CLSID!
  72. // {8B75CD76-DFC1-4356-AC04-AF088B448AB3}
  73. static const CLSID ciImpParserCLSID =
  74. { 0x8b75cd76, 0xdfc1, 0x4356, { 0xac, 0x4, 0xaf, 0x8, 0x8b, 0x44, 0x8a, 0xb3 } };
  75. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  76. //
  77. // Return the CLSID of the parser
  78. //
  79. //------------------------------------------------------------------------------
  80. STDAPI_(void)
  81. DllGetParserCLSID(
  82. CLSID &ciParserCLSID)
  83. {
  84. ciParserCLSID = ciImpParserCLSID;
  85. }
  86. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  87. //
  88. // Entry point to register this parser. Calls base implementation in ESPUTIL.
  89. //------------------------------------------------------------------------------
  90. STDAPI
  91. DllRegisterParser()
  92. {
  93. LTASSERT(g_hDll != NULL);
  94. HRESULT hr = ResultFromScode(E_UNEXPECTED);
  95. try
  96. {
  97. hr = RegisterParser(g_hDll);
  98. }
  99. catch (CException* pE)
  100. {
  101. pE->Delete();
  102. }
  103. catch (...)
  104. {
  105. }
  106. return ResultFromScode(hr);
  107. }
  108. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  109. //
  110. // Entry point to unregister this parser. Calls the base implementation in
  111. // ESPUTIL.
  112. //------------------------------------------------------------------------------
  113. STDAPI
  114. DllUnregisterParser()
  115. {
  116. LTASSERT(g_hDll != NULL);
  117. HRESULT hr = ResultFromScode(E_UNEXPECTED);
  118. try
  119. {
  120. //TODO**: Change pidBMOF to real sub parser ID
  121. hr = UnregisterParser(pidBMOF, pidWin32);
  122. }
  123. catch (CException* pE)
  124. {
  125. pE->Delete();
  126. }
  127. catch (...)
  128. {
  129. }
  130. return ResultFromScode(hr);
  131. }
  132. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  133. //
  134. // Return the class factory for the requested class ID
  135. //
  136. //------------------------------------------------------------------------------
  137. STDAPI
  138. DllGetClassObject(
  139. REFCLSID cidRequestedClass,
  140. REFIID iid,
  141. LPVOID *ppClassFactory)
  142. {
  143. SCODE sc = E_UNEXPECTED;
  144. *ppClassFactory = NULL;
  145. if (cidRequestedClass != ciImpParserCLSID)
  146. {
  147. sc = CLASS_E_CLASSNOTAVAILABLE;
  148. }
  149. else
  150. {
  151. try
  152. {
  153. CLocImpClassFactory *pClassFactory;
  154. pClassFactory = new CLocImpClassFactory;
  155. sc = pClassFactory->QueryInterface(iid, ppClassFactory);
  156. pClassFactory->Release();
  157. }
  158. catch (CMemoryException *pMem)
  159. {
  160. sc = E_OUTOFMEMORY;
  161. pMem->Delete();
  162. }
  163. catch (CException* pE)
  164. {
  165. sc = E_UNEXPECTED;
  166. pE->Delete();
  167. }
  168. catch (...)
  169. {
  170. sc = E_UNEXPECTED;
  171. }
  172. }
  173. return ResultFromScode(sc);
  174. }
  175. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  176. //
  177. // Return true if the parser can be unloaded
  178. //
  179. //------------------------------------------------------------------------------
  180. STDAPI
  181. DllCanUnloadNow(void)
  182. {
  183. SCODE sc = (g_lActiveClasses == 0) ? S_OK : S_FALSE;
  184. return ResultFromScode(sc);
  185. }
  186. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  187. //
  188. // Increment the global count of active classes
  189. //
  190. //------------------------------------------------------------------------------
  191. void
  192. IncrementClassCount(void)
  193. {
  194. InterlockedIncrement(&g_lActiveClasses);
  195. }
  196. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  197. //
  198. // Decrement the global count of active classes
  199. //
  200. //------------------------------------------------------------------------------
  201. void
  202. DecrementClassCount(void)
  203. {
  204. LTASSERT(g_lActiveClasses != 0);
  205. InterlockedDecrement(&g_lActiveClasses);
  206. }
  207. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  208. //
  209. // Throw a item set exception
  210. //
  211. //------------------------------------------------------------------------------
  212. void
  213. ThrowItemSetException()
  214. {
  215. throw &g_SetException;
  216. }
  217. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  218. //
  219. // Report a error through the reporter. This function will never
  220. // fail or throw an exception out of the function.
  221. //
  222. //------------------------------------------------------------------------------
  223. void
  224. ReportException(
  225. CException* pExcep, //May be null
  226. C32File* p32File, //May be null
  227. CLocItem* pItem, //May be null
  228. CReporter* pReporter)
  229. {
  230. LTASSERT(NULL != pReporter);
  231. //Don't let this function throw an exception since it is normally called
  232. //within exception catch blocks
  233. try
  234. {
  235. CLString strContext;
  236. if (NULL != p32File)
  237. {
  238. strContext = p32File->GetFile()->GetFilePath();
  239. }
  240. else
  241. {
  242. LTVERIFY(strContext.LoadString(g_hDll, IDS_IMP_DESC));
  243. }
  244. CLString strExcep;
  245. BOOL bErrorFormatted = FALSE;
  246. if (NULL != pExcep)
  247. {
  248. bErrorFormatted =
  249. pExcep->GetErrorMessage(strExcep.GetBuffer(512), 512);
  250. strExcep.ReleaseBuffer();
  251. }
  252. if (!bErrorFormatted || NULL == pExcep)
  253. {
  254. LTVERIFY(strExcep.LoadString(g_hDll, IDS_IMP_UNKNOWN_ERROR));
  255. }
  256. CLString strResId;
  257. if (NULL != pItem)
  258. {
  259. CPascalString pasResId;
  260. pItem->GetUniqueId().GetResId().GetDisplayableId(pasResId);
  261. pasResId.ConvertToCLString(strResId, CP_ACP);
  262. }
  263. CLString strMsg;
  264. strMsg.Format(g_hDll, IDS_ERR_EXCEPTION, (LPCTSTR)strResId,
  265. (LPCTSTR)strExcep);
  266. CContext ctx(strContext, pItem->GetMyDatabaseId(), otResource, vProjWindow);
  267. pReporter->IssueMessage(esError, ctx, strMsg);
  268. }
  269. catch(CException* pE)
  270. {
  271. LTASSERT(0 && _T("Could not issue a exception message"));
  272. pE->Delete();
  273. }
  274. catch(...)
  275. {
  276. LTASSERT(0 && _T("Could not issue a exception message"));
  277. }
  278. }
  279. ////////////////////////////////////////////////////////////////////////////////
  280. // CItemSetException
  281. //
  282. IMPLEMENT_DYNAMIC(CItemSetException, CException)
  283. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  284. //
  285. // Default contructor
  286. //
  287. //------------------------------------------------------------------------------
  288. CItemSetException::CItemSetException()
  289. {
  290. }
  291. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  292. //
  293. // Constructor
  294. //
  295. //------------------------------------------------------------------------------
  296. CItemSetException::CItemSetException(BOOL bAutoDelete)
  297. :CException(bAutoDelete)
  298. {
  299. }
  300. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  301. //
  302. // Fill passed buffer with a error message for this exception.
  303. // The message is cached and only retrieved 1 time.
  304. //
  305. //------------------------------------------------------------------------------
  306. BOOL
  307. CItemSetException::GetErrorMessage(LPTSTR lpszError, UINT nMaxError,
  308. PUINT pnHelpContext)
  309. {
  310. LTASSERT(lpszError != NULL && AfxIsValidString(lpszError, nMaxError));
  311. if (NULL != pnHelpContext)
  312. {
  313. *pnHelpContext = 0; //unused
  314. }
  315. if (m_strMsg.IsEmpty())
  316. {
  317. LTVERIFY(m_strMsg.LoadString(g_hDll, IDS_EXCEP_ITEMSET));
  318. }
  319. int nMax = min(nMaxError, (UINT)m_strMsg.GetLength() + 1);
  320. _tcsncpy(lpszError, m_strMsg, nMax - 1);
  321. lpszError[nMax] = _T('\0');
  322. return TRUE;
  323. }