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.

369 lines
11 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. EventConsumerProvider.CPP
  5. Abstract:
  6. Contains DLL entry points. code that controls
  7. when the DLL can be unloaded by tracking the number of
  8. objects and locks as well as routines that support
  9. self registration.
  10. Author:
  11. Vasundhara .G
  12. Revision History:
  13. Vasundhara .G 9-oct-2k : Created It.
  14. --*/
  15. #include "pch.h"
  16. #include "EventConsumerProvider.h"
  17. #include "TriggerFactory.h"
  18. // constants / defines / enumerations
  19. #define THREAD_MODEL_BOTH _T( "Both" )
  20. #define THREAD_MODEL_APARTMENT _T( "Apartment" )
  21. #define RUNAS_INTERACTIVEUSER _T( "Interactive User" )
  22. #define FMT_CLS_ID _T( "CLSID\\%s" )
  23. #define FMT_APP_ID _T( "APPID\\%s" )
  24. #define PROVIDER_TITLE _T( "Command line Trigger Consumer" )
  25. #define KEY_INPROCSERVER32 _T( "InprocServer32" )
  26. #define KEY_THREADINGMODEL _T( "ThreadingModel" )
  27. #define KEY_CLSID _T( "CLSID" )
  28. #define KEY_APPID _T( "APPID" )
  29. #define KEY_RUNAS _T( "RunAs" )
  30. #define KAY_DLLSURROGATE _T( "DllSurrogate" )
  31. // global variables
  32. DWORD g_dwLocks = 0; // holds the active locks count
  33. DWORD g_dwInstances = 0; // holds the active instances of the component
  34. HMODULE g_hModule = NULL; // holds the current module handle
  35. CRITICAL_SECTION g_critical_sec; // critical section variable
  36. DWORD g_criticalsec_count = 0; // to keep tab on when to release critical section
  37. // {797EF3B3-127B-4283-8096-1E8084BF67A6}
  38. DEFINE_GUID( CLSID_EventTriggersConsumerProvider,
  39. 0x797ef3b3, 0x127b, 0x4283, 0x80, 0x96, 0x1e, 0x80, 0x84, 0xbf, 0x67, 0xa6 );
  40. // dll entry point
  41. BOOL
  42. WINAPI DllMain(
  43. IN HINSTANCE hModule,
  44. IN DWORD ul_reason_for_call,
  45. IN LPVOID lpReserved
  46. )
  47. /*++
  48. Routine Description:
  49. Entry point for dll.
  50. Arguments:
  51. [IN] hModule : Instance of the caller.
  52. [IN] ul_reason_for_call : Reason being called like process attach
  53. or process detach.
  54. [IN] lpReserved : reserved.
  55. Return Value:
  56. TRUE if loading is successful.
  57. FALSE if loading fails.
  58. --*/
  59. {
  60. // check the reason for this function call
  61. // if this going to be attached to a process, save the module handle
  62. if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
  63. {
  64. g_hModule = hModule;
  65. InitializeCriticalSection( &g_critical_sec );
  66. InterlockedIncrement( ( LPLONG ) &g_criticalsec_count );
  67. }
  68. else if ( DLL_PROCESS_DETACH == ul_reason_for_call )
  69. {
  70. if ( InterlockedDecrement( ( LPLONG ) &g_criticalsec_count ) == 0 )
  71. {
  72. DeleteCriticalSection( &g_critical_sec );
  73. }
  74. }
  75. // dll loaded successfully ... inform the same
  76. return TRUE;
  77. }
  78. // exported functions
  79. STDAPI
  80. DllCanUnloadNow(
  81. )
  82. /*++
  83. Routine Description:
  84. Called periodically by OLE in order to determine if the DLL can be freed.
  85. Arguments:
  86. none.
  87. Return Value:
  88. S_OK if there are no objects in use and the class factory isn't locked.
  89. S_FALSE if server locks or components still exsists.
  90. --*/
  91. {
  92. // the dll cannot be unloaded if there are any server locks or active instances
  93. if ( 0 == g_dwLocks && 0 == g_dwInstances )
  94. {
  95. return S_OK;
  96. }
  97. // dll cannot be unloaded ... server locks (or) components still alive
  98. return S_FALSE;
  99. }
  100. STDAPI
  101. DllGetClassObject(
  102. IN REFCLSID rclsid,
  103. IN REFIID riid,
  104. OUT LPVOID* ppv
  105. )
  106. /*++
  107. Routine Description:
  108. Called by OLE when some client wants a class factory.
  109. Return one only if it is the sort of class this DLL supports.
  110. Arguments:
  111. [IN] rclsid : CLSID for the class object.
  112. [IN] riid : Reference to the identifier of the interface
  113. that communicates with the class object.
  114. [OUT] ppv : Address of output variable that receives the
  115. interface pointer requested in riid.
  116. Return Value:
  117. returns status.
  118. --*/
  119. {
  120. // local variables
  121. HRESULT hr = S_OK;
  122. CTriggerFactory* pFactory = NULL;
  123. // check whether this module supports the requested class id
  124. if ( CLSID_EventTriggersConsumerProvider != rclsid )
  125. {
  126. return E_FAIL; // not supported by this module
  127. }
  128. // create the factory
  129. pFactory = new CTriggerFactory();
  130. if ( NULL == pFactory )
  131. {
  132. return E_OUTOFMEMORY; // insufficient memory
  133. }
  134. // get the requested interface
  135. hr = pFactory->QueryInterface( riid, ppv );
  136. if ( FAILED( hr ) )
  137. {
  138. delete pFactory; // error getting interface ... deallocate memory
  139. }
  140. // return the result (appropriate result)
  141. return hr;
  142. }
  143. STDAPI
  144. DllRegisterServer(
  145. )
  146. /*++
  147. Routine Description:
  148. Called during setup or by regsvr32.
  149. Arguments:
  150. none.
  151. Return Value:
  152. NOERROR.
  153. --*/
  154. {
  155. // local variables
  156. HKEY hkMain = NULL;
  157. HKEY hkDetails = NULL;
  158. TCHAR szID[ LENGTH_UUID ] = NULL_STRING;
  159. TCHAR szCLSID[ LENGTH_UUID ] = NULL_STRING;
  160. TCHAR szAppID[ LENGTH_UUID ] = NULL_STRING;
  161. TCHAR szModule[ MAX_PATH ] = NULL_STRING;
  162. TCHAR szTitle[ MAX_STRING_LENGTH ] = NULL_STRING;
  163. TCHAR szThreadingModel[ MAX_STRING_LENGTH ] = NULL_STRING;
  164. TCHAR szRunAs[ MAX_STRING_LENGTH ] = NULL_STRING;
  165. DWORD dwResult = 0;
  166. // kick off
  167. // Note:-
  168. // Normally we want to use "Both" as the threading model since
  169. // the DLL is free threaded, but NT 3.51 Ole doesnt work unless
  170. // the model is "Aparment"
  171. StringCopy( szTitle, PROVIDER_TITLE, SIZE_OF_ARRAY( szTitle ) ); // provider title
  172. GetModuleFileName( g_hModule, szModule, MAX_PATH ); // get the current module name
  173. StringCopy( szThreadingModel, THREAD_MODEL_BOTH, SIZE_OF_ARRAY( szThreadingModel ) );
  174. StringCopy( szRunAs, RUNAS_INTERACTIVEUSER, SIZE_OF_ARRAY( szRunAs ) );
  175. // create the class id path
  176. // get the GUID in the string format
  177. StringFromGUID2( CLSID_EventTriggersConsumerProvider, szID, LENGTH_UUID );
  178. // finally form the class id path
  179. StringCchPrintf( szCLSID, SIZE_OF_ARRAY( szCLSID ), FMT_CLS_ID, szID );
  180. StringCchPrintf( szAppID, SIZE_OF_ARRAY( szAppID ), FMT_APP_ID, szID );
  181. // now, create the entries in registry under CLSID branch
  182. // create / save / put class id information
  183. dwResult = RegCreateKey( HKEY_CLASSES_ROOT, szCLSID, &hkMain );
  184. if( ERROR_SUCCESS != dwResult )
  185. {
  186. return dwResult; // failed in opening the key.
  187. }
  188. dwResult = RegSetValueEx( hkMain, NULL, 0, REG_SZ,
  189. ( LPBYTE ) szTitle, ( StringLength( szTitle, 0 ) + 1 ) * sizeof( TCHAR ) );
  190. if( ERROR_SUCCESS != dwResult )
  191. {
  192. RegCloseKey( hkMain );
  193. return dwResult; // failed to set key value.
  194. }
  195. // now create the server information
  196. dwResult = RegCreateKey( hkMain, KEY_INPROCSERVER32, &hkDetails );
  197. if( ERROR_SUCCESS != dwResult )
  198. {
  199. RegCloseKey( hkMain );
  200. return dwResult; // failed in opening the key.
  201. }
  202. dwResult = RegSetValueEx( hkDetails, NULL, 0, REG_SZ,
  203. ( LPBYTE ) szModule, ( StringLength( szModule, 0 ) + 1 ) * sizeof( TCHAR ) );
  204. if( ERROR_SUCCESS != dwResult )
  205. {
  206. RegCloseKey( hkMain );
  207. RegCloseKey( hkDetails );
  208. return dwResult; // failed to set key value.
  209. }
  210. // set the threading model we support
  211. dwResult = RegSetValueEx( hkDetails, KEY_THREADINGMODEL, 0, REG_SZ,
  212. ( LPBYTE ) szThreadingModel, ( StringLength( szThreadingModel, 0 ) + 1 ) * sizeof( TCHAR ) );
  213. if( ERROR_SUCCESS != dwResult )
  214. {
  215. RegCloseKey( hkMain );
  216. RegCloseKey( hkDetails );
  217. return dwResult; // failed to set key value.
  218. }
  219. // close the open register keys
  220. RegCloseKey( hkMain );
  221. RegCloseKey( hkDetails );
  222. //
  223. // now, create the entries in registry under AppID branch
  224. // create / save / put class id information
  225. dwResult = RegCreateKey( HKEY_CLASSES_ROOT, szAppID, &hkMain );
  226. if( ERROR_SUCCESS != dwResult )
  227. {
  228. return dwResult;
  229. }
  230. dwResult = RegSetValueEx( hkMain, NULL, 0, REG_SZ,
  231. ( LPBYTE ) szTitle, ( StringLength( szTitle, 0 ) + 1 ) * sizeof( TCHAR ) );
  232. if( ERROR_SUCCESS != dwResult )
  233. {
  234. RegCloseKey( hkMain );
  235. return dwResult;
  236. }
  237. // now set run as information
  238. dwResult = RegSetValueEx( hkMain, KEY_RUNAS, 0, REG_SZ,
  239. ( LPBYTE ) szRunAs, ( StringLength( szRunAs, 0 ) + 1 ) * sizeof( TCHAR ) );
  240. if( ERROR_SUCCESS != dwResult )
  241. {
  242. RegCloseKey( hkMain );
  243. return dwResult;
  244. }
  245. // close the open register keys
  246. RegCloseKey( hkMain );
  247. // registration is successfull ... inform the same
  248. return NOERROR;
  249. }
  250. STDAPI
  251. DllUnregisterServer(
  252. )
  253. /*++
  254. Routine Description:
  255. Called when it is time to remove the registry entries.
  256. Arguments:
  257. none.
  258. Return Value:
  259. NOERROR if unregistration successful.
  260. Otherwise error.
  261. --*/
  262. {
  263. // local variables
  264. HKEY hKey;
  265. DWORD dwResult = 0;
  266. TCHAR szID[ LENGTH_UUID ];
  267. TCHAR szCLSID[ LENGTH_UUID ];
  268. TCHAR szAppID[ LENGTH_UUID ] = NULL_STRING;
  269. // create the class id path
  270. StringFromGUID2( CLSID_EventTriggersConsumerProvider, szID, LENGTH_UUID );
  271. // finally form the class id path
  272. StringCchPrintf( szCLSID, SIZE_OF_ARRAY( szCLSID ), FMT_CLS_ID, szID );
  273. StringCchPrintf( szAppID, SIZE_OF_ARRAY( szAppID ), FMT_APP_ID, szID );
  274. // open the clsid
  275. dwResult = RegOpenKey( HKEY_CLASSES_ROOT, szCLSID, &hKey );
  276. if ( NO_ERROR != dwResult )
  277. {
  278. return dwResult; // failed in opening the key ... inform the same
  279. }
  280. // clsid opened ... first delete the InProcServer32
  281. RegDeleteKey( hKey, KEY_INPROCSERVER32 );
  282. // release the key
  283. RegCloseKey( hKey );
  284. //reset to NULL
  285. hKey = NULL ;
  286. // now delete the clsid
  287. dwResult = RegOpenKey( HKEY_CLASSES_ROOT, KEY_CLSID, &hKey );
  288. if ( NO_ERROR != dwResult )
  289. {
  290. return dwResult; // failed in opening the key ... inform the same
  291. }
  292. // delete the clsid also from the registry
  293. RegDeleteKey( hKey, szID );
  294. // release the key
  295. RegCloseKey( hKey );
  296. //reset to NULL
  297. hKey = NULL ;
  298. // now delete the appid
  299. dwResult = RegOpenKey( HKEY_CLASSES_ROOT, KEY_APPID, &hKey );
  300. if ( NO_ERROR != dwResult )
  301. {
  302. return dwResult; // failed in opening the key ... inform the same
  303. }
  304. // delete the cls id also from the registry
  305. RegDeleteKey( hKey, szID );
  306. // release the key
  307. RegCloseKey( hKey );
  308. //reset to NULL
  309. hKey = NULL ;
  310. // unregistration is successfull ... inform the same
  311. return NOERROR;
  312. }