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.

493 lines
12 KiB

  1. //***************************************************************************
  2. //
  3. // File:
  4. //
  5. // Module: MS SNMP Provider
  6. //
  7. // Purpose:
  8. //
  9. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #ifndef INITGUID
  13. #define INITGUID
  14. #endif
  15. #include <precomp.h>
  16. #include <initguid.h>
  17. #include "smir.h"
  18. #include "csmir.h"
  19. #include "handles.h"
  20. #include "classfac.h"
  21. #include "textdef.h"
  22. #include "thread.h"
  23. #include "helper.h"
  24. #include <scopeguard.h>
  25. BOOL SetKeyAndValue(wchar_t* pszKey, wchar_t* pszSubkey, wchar_t* pszValueName, wchar_t* pszValue);
  26. //Globals Bah!
  27. BOOL g_initialised = FALSE ;
  28. //OK we need this one
  29. HINSTANCE g_hInst;
  30. //and this is a thread safe speed up
  31. SmirClassFactoryHelper *g_pClassFactoryHelper=NULL;
  32. CSmirConnObject* CSmir::sm_ConnectionObjects = NULL;
  33. CRITICAL_SECTION g_CriticalSection ;
  34. //***************************************************************************
  35. //
  36. // LibMain32
  37. //
  38. // Purpose: Entry point for DLL. Good place for initialization.
  39. // Return: TRUE if OK.
  40. //***************************************************************************
  41. static bool g_csInitialized = false;
  42. BOOL APIENTRY DllMain (HINSTANCE hInstance, ULONG ulReason , LPVOID pvReserved)
  43. {
  44. BOOL status = TRUE;
  45. /*remember the instance handle to the dll so that we can use it in
  46. *register dll
  47. */
  48. g_hInst=hInstance;
  49. SetStructuredExceptionHandler seh;
  50. try
  51. {
  52. switch (ulReason)
  53. {
  54. case DLL_PROCESS_ATTACH:
  55. {
  56. g_csInitialized = InitializeCriticalSectionAndSpinCount ( & g_CriticalSection, 4000 ) != 0 ;
  57. DisableThreadLibraryCalls(hInstance);
  58. status = g_csInitialized == true;
  59. }
  60. break;
  61. case DLL_PROCESS_DETACH:
  62. {
  63. CThread :: ProcessDetach();
  64. if (g_csInitialized)
  65. {
  66. DeleteCriticalSection ( & g_CriticalSection ) ;
  67. }
  68. //release the helper
  69. }
  70. break;
  71. //if DisableThreadLibraryCalls() worked these will never be called
  72. case DLL_THREAD_DETACH:
  73. case DLL_THREAD_ATTACH:
  74. {
  75. }
  76. break;
  77. default:
  78. {
  79. status = FALSE;
  80. }
  81. break;
  82. }
  83. }
  84. catch(Structured_Exception e_SE)
  85. {
  86. status = FALSE;
  87. }
  88. catch(Heap_Exception e_HE)
  89. {
  90. status = FALSE;
  91. }
  92. catch(...)
  93. {
  94. status = FALSE;
  95. }
  96. return status ;
  97. }
  98. //***************************************************************************
  99. //
  100. // DllGetClassObject
  101. //
  102. // Purpose: Called by Ole when some client wants a class factory. Return
  103. // one only if it is the sort of class this DLL supports.
  104. //
  105. //***************************************************************************
  106. STDAPI DllGetClassObject (REFCLSID rclsid , REFIID riid, void **ppv)
  107. {
  108. HRESULT status = S_OK ;
  109. SetStructuredExceptionHandler seh;
  110. try
  111. {
  112. EnterCriticalSection ( & g_CriticalSection ) ;
  113. ON_BLOCK_EXIT(LeaveCriticalSection, &g_CriticalSection);
  114. if ( !g_initialised )
  115. {
  116. /*I don't do anything in thread attach and
  117. *detach so do give them to me
  118. */
  119. //BOOL bCallsDisabled;
  120. //bCallsDisabled=DisableThreadLibraryCalls(hInstance);
  121. //initialise the helper
  122. if (S_OK != CSmirAccess :: Init())
  123. {
  124. status = FALSE;
  125. }
  126. else
  127. {
  128. //allocate the cached class factory
  129. if(NULL == g_pClassFactoryHelper)
  130. g_pClassFactoryHelper= new SmirClassFactoryHelper;
  131. status = TRUE ;
  132. }
  133. g_initialised = TRUE ;
  134. }
  135. CSMIRGenericClassFactory *lpClassFac = NULL;
  136. if((CLSID_SMIR_Database==rclsid)||
  137. (IID_IConnectionPointContainer ==rclsid))
  138. {
  139. lpClassFac = new CSMIRClassFactory(rclsid) ;
  140. }
  141. else if(CLSID_SMIR_ModHandle==rclsid)
  142. {
  143. lpClassFac = new CModHandleClassFactory(rclsid) ;
  144. }
  145. else if(CLSID_SMIR_GroupHandle==rclsid)
  146. {
  147. lpClassFac = new CGroupHandleClassFactory(rclsid) ;
  148. }
  149. else if(CLSID_SMIR_ClassHandle==rclsid)
  150. {
  151. lpClassFac = new CClassHandleClassFactory(rclsid) ;
  152. }
  153. else if(CLSID_SMIR_NotificationClassHandle==rclsid)
  154. {
  155. lpClassFac = new CNotificationClassHandleClassFactory(rclsid) ;
  156. }
  157. else if(CLSID_SMIR_ExtNotificationClassHandle==rclsid)
  158. {
  159. lpClassFac = new CExtNotificationClassHandleClassFactory(rclsid) ;
  160. }
  161. else
  162. {
  163. //the caller has asked for an interface I don't support
  164. return(CLASS_E_CLASSNOTAVAILABLE);
  165. }
  166. if (NULL==lpClassFac)
  167. {
  168. return(E_OUTOFMEMORY);
  169. }
  170. status = lpClassFac->QueryInterface (riid , ppv) ;
  171. if (FAILED(status))
  172. {
  173. delete lpClassFac;
  174. }
  175. }
  176. catch(Structured_Exception e_SE)
  177. {
  178. return E_UNEXPECTED;
  179. }
  180. catch(Heap_Exception e_HE)
  181. {
  182. return E_OUTOFMEMORY;
  183. }
  184. catch(...)
  185. {
  186. return E_UNEXPECTED;
  187. }
  188. return status ;
  189. }
  190. //***************************************************************************
  191. //
  192. // DllCanUnloadNow
  193. //
  194. // Purpose: Called periodically by Ole in order to determine if the
  195. // DLL can be unloaded.
  196. // Return: TRUE if there are no objects in use and the class factory
  197. // isn't locked.
  198. //***************************************************************************
  199. STDAPI DllCanUnloadNow ()
  200. {
  201. SetStructuredExceptionHandler seh;
  202. try
  203. {
  204. EnterCriticalSection ( & g_CriticalSection ) ;
  205. ON_BLOCK_EXIT(LeaveCriticalSection, &g_CriticalSection);
  206. BOOL unload = (0 == CSMIRClassFactory :: locksInProgress) &&
  207. (0 == CSMIRClassFactory :: objectsInProgress) &&
  208. (0 == CModHandleClassFactory :: locksInProgress) &&
  209. (0 == CModHandleClassFactory :: objectsInProgress) &&
  210. (0 == CGroupHandleClassFactory :: locksInProgress) &&
  211. (0 == CGroupHandleClassFactory :: objectsInProgress) &&
  212. (0 == CClassHandleClassFactory :: locksInProgress) &&
  213. (0 == CClassHandleClassFactory :: objectsInProgress) &&
  214. (0 == CNotificationClassHandleClassFactory :: locksInProgress) &&
  215. (0 == CNotificationClassHandleClassFactory :: objectsInProgress) &&
  216. (0 == CExtNotificationClassHandleClassFactory :: locksInProgress) &&
  217. (0 == CExtNotificationClassHandleClassFactory :: objectsInProgress);
  218. if ( unload )
  219. CSmirAccess :: ShutDown();
  220. return ResultFromScode(unload?S_OK:S_FALSE);
  221. }
  222. catch(Structured_Exception e_SE)
  223. {
  224. return S_FALSE;
  225. }
  226. catch(Heap_Exception e_HE)
  227. {
  228. return S_FALSE;
  229. }
  230. catch(...)
  231. {
  232. return S_FALSE;
  233. }
  234. }
  235. /***************************************************************************
  236. * DllRegisterServer
  237. *
  238. * Purpose:
  239. * Instructs the server to create its own registry entries
  240. *
  241. * Parameters:
  242. * None
  243. *
  244. * Return Value:
  245. * HRESULT NOERROR if registration successful, error
  246. * otherwise.
  247. ***************************************************************************/
  248. STDAPI DllRegisterServer()
  249. {
  250. SetStructuredExceptionHandler seh;
  251. try
  252. {
  253. wchar_t szID[NUMBER_OF_SMIR_INTERFACES][128];
  254. LPTSTR szModule[512];
  255. /*life would be easier if I could create a pointer to a reference
  256. *but I can't so I have to hand create each root string before creating
  257. *the registry entries.
  258. */
  259. //Create some base key strings.
  260. //one for the interrogative interface
  261. int iRet = StringFromGUID2(CLSID_SMIR_Database,(wchar_t*)&szID[0], 128);
  262. //one for the module handle interface
  263. iRet = StringFromGUID2(CLSID_SMIR_ModHandle, (wchar_t*)&szID[1], 128);
  264. //one for the group handle interface
  265. iRet = StringFromGUID2(CLSID_SMIR_GroupHandle, (wchar_t*)&szID[2], 128);
  266. //one for the class handle interface
  267. iRet = StringFromGUID2(CLSID_SMIR_ClassHandle, (wchar_t*)&szID[3], 128);
  268. //one for the notificationclass handle interface
  269. iRet = StringFromGUID2(CLSID_SMIR_NotificationClassHandle, (wchar_t*)&szID[4], 128);
  270. //one for the extnotificationclass handle interface
  271. iRet = StringFromGUID2(CLSID_SMIR_ExtNotificationClassHandle, (wchar_t*)&szID[5], 128);
  272. for (int i=0;i<NUMBER_OF_SMIR_INTERFACES;i++)
  273. {
  274. wchar_t szCLSID[128];
  275. wcscpy((wchar_t*)szCLSID, CLSID_STR);
  276. wcscat((wchar_t*)szCLSID,(wchar_t*)&szID[i]);
  277. //Create entries under CLSID
  278. if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, NULL, NULL, SMIR_NAME_STR))
  279. return SELFREG_E_CLASS;
  280. if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, NOT_INTERT_STR, NULL, NULL))
  281. return SELFREG_E_CLASS;
  282. GetModuleFileName(g_hInst, (wchar_t*)szModule
  283. , sizeof(szModule)/sizeof(wchar_t));
  284. if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, INPROC32_STR, NULL,(wchar_t*) szModule))
  285. return SELFREG_E_CLASS;
  286. if (FALSE ==SetKeyAndValue((wchar_t*)szCLSID, INPROC32_STR,
  287. THREADING_MODULE_STR, APARTMENT_STR))
  288. return SELFREG_E_CLASS;
  289. }
  290. }
  291. catch(Structured_Exception e_SE)
  292. {
  293. return E_UNEXPECTED;
  294. }
  295. catch(Heap_Exception e_HE)
  296. {
  297. return E_OUTOFMEMORY;
  298. }
  299. catch(...)
  300. {
  301. return E_UNEXPECTED;
  302. }
  303. return S_OK;
  304. }
  305. /***************************************************************************
  306. * DllUnregisterServer
  307. *
  308. * Purpose:
  309. * Instructs the server to remove its own registry entries
  310. *
  311. * Parameters:
  312. * None
  313. *
  314. * Return Value:
  315. * HRESULT NOERROR if registration successful, error
  316. * otherwise.
  317. ***************************************************************************/
  318. STDAPI DllUnregisterServer(void)
  319. {
  320. SetStructuredExceptionHandler seh;
  321. try
  322. {
  323. wchar_t szID[128];
  324. wchar_t szCLSID[NUMBER_OF_SMIR_INTERFACES][128];
  325. wchar_t szTemp[256];
  326. //one for the smir interface
  327. int iRet = StringFromGUID2(CLSID_SMIR_Database, szID, 128);
  328. wcscpy((wchar_t*)szCLSID[0], CLSID_STR);
  329. wcscat((wchar_t*)szCLSID[0], szID);
  330. //one for the module handle interface
  331. iRet = StringFromGUID2(CLSID_SMIR_ModHandle, szID, 128);
  332. wcscpy((wchar_t*)szCLSID[1], CLSID_STR);
  333. wcscat((wchar_t*)szCLSID[1], szID);
  334. //one for the group handle interface
  335. iRet = StringFromGUID2(CLSID_SMIR_GroupHandle, szID, 128);
  336. wcscpy((wchar_t*)szCLSID[2], CLSID_STR);
  337. wcscat((wchar_t*)szCLSID[2], szID);
  338. //one for the class handle interface
  339. iRet = StringFromGUID2(CLSID_SMIR_ClassHandle, szID, 128);
  340. wcscpy((wchar_t*)szCLSID[3], CLSID_STR);
  341. wcscat((wchar_t*)szCLSID[3],szID);
  342. //one for the notificationclass handle interface
  343. iRet = StringFromGUID2(CLSID_SMIR_NotificationClassHandle, szID, 128);
  344. wcscpy((wchar_t*)szCLSID[4], CLSID_STR);
  345. wcscat((wchar_t*)szCLSID[4], szID);
  346. //one for the extnotificationclass handle interface
  347. iRet = StringFromGUID2(CLSID_SMIR_ExtNotificationClassHandle, szID, 128);
  348. wcscpy((wchar_t*)szCLSID[5], CLSID_STR);
  349. wcscat((wchar_t*)szCLSID[5], szID);
  350. for (int i=0;i<NUMBER_OF_SMIR_INTERFACES;i++)
  351. {
  352. wsprintf(szTemp, REG_FORMAT_STR, (wchar_t*)&szCLSID[i], NOT_INTERT_STR);
  353. RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp);
  354. wsprintf(szTemp, REG_FORMAT_STR, (wchar_t*)&szCLSID[i], INPROC32_STR);
  355. RegDeleteKey(HKEY_LOCAL_MACHINE, szTemp);
  356. RegDeleteKey(HKEY_LOCAL_MACHINE, (wchar_t*)&szCLSID[i]);
  357. }
  358. }
  359. catch(Structured_Exception e_SE)
  360. {
  361. return E_UNEXPECTED;
  362. }
  363. catch(Heap_Exception e_HE)
  364. {
  365. return E_OUTOFMEMORY;
  366. }
  367. catch(...)
  368. {
  369. return E_UNEXPECTED;
  370. }
  371. return S_OK;
  372. }
  373. /***************************************************************************
  374. * SetKeyAndValue
  375. *
  376. * Purpose:
  377. * Private helper function for DllRegisterServer that creates
  378. * a key, sets a value, and closes that key.
  379. *
  380. * Parameters:
  381. * pszKey LPTSTR to the ame of the key
  382. * pszSubkey LPTSTR ro the name of a subkey
  383. * pszValue LPTSTR to the value to store
  384. *
  385. * Return Value:
  386. * BOOL TRUE if successful, FALSE otherwise.
  387. ***************************************************************************/
  388. BOOL SetKeyAndValue(wchar_t* pszKey, wchar_t* pszSubkey, wchar_t* pszValueName, wchar_t* pszValue)
  389. {
  390. HKEY hKey;
  391. wchar_t szKey[256] = { L'\0' };
  392. wcscpy(szKey, pszKey);
  393. if (NULL!=pszSubkey)
  394. {
  395. wcscat(szKey, L"\\");
  396. wcscat(szKey, pszSubkey);
  397. }
  398. if (ERROR_SUCCESS!=RegCreateKeyEx(HKEY_LOCAL_MACHINE
  399. , szKey, 0, NULL, REG_OPTION_NON_VOLATILE
  400. , KEY_ALL_ACCESS, NULL, &hKey, NULL))
  401. return FALSE;
  402. if (NULL!=pszValue)
  403. {
  404. if (ERROR_SUCCESS != RegSetValueEx(hKey, pszValueName, 0, REG_SZ, (BYTE *)pszValue
  405. , (lstrlen(pszValue)+1)*sizeof(wchar_t))){
  406. RegCloseKey(hKey);
  407. return FALSE;
  408. }
  409. }
  410. RegCloseKey(hKey);
  411. return TRUE;
  412. }