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.

477 lines
11 KiB

  1. #include <objbase.h>
  2. #include <olectl.h>
  3. #include <initguid.h>
  4. #include "guids.h"
  5. #include "basesnap.h"
  6. #include "comp.h"
  7. #include "compdata.h"
  8. #include "about.h"
  9. #include "uddi.h"
  10. #include <assert.h>
  11. LONG UnRegisterServer( const CLSID& clsid );
  12. //
  13. // Globals Variables
  14. //
  15. HINSTANCE g_hinst;
  16. BOOL WINAPI DllMain( HINSTANCE hinst, DWORD fdwReason, void* lpvReserved )
  17. {
  18. if( DLL_PROCESS_ATTACH == fdwReason )
  19. {
  20. g_hinst = hinst;
  21. }
  22. return TRUE;
  23. }
  24. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
  25. {
  26. if( ( rclsid != CLSID_CUDDIServices ) && ( rclsid != CLSID_CSnapinAbout ) )
  27. return CLASS_E_CLASSNOTAVAILABLE;
  28. if( !ppvObj )
  29. return E_FAIL;
  30. *ppvObj = NULL;
  31. //
  32. // We can only hand out IUnknown and IClassFactory pointers. Fail
  33. // if they ask for anything else.
  34. //
  35. if( !IsEqualIID(riid, IID_IUnknown) && !IsEqualIID( riid, IID_IClassFactory ) )
  36. return E_NOINTERFACE;
  37. CClassFactory *pFactory = NULL;
  38. //
  39. // make the factory passing in the creation function for the type of object they want
  40. //
  41. if( CLSID_CUDDIServices == rclsid )
  42. pFactory = new CClassFactory( CClassFactory::COMPONENT );
  43. else if( CLSID_CSnapinAbout == rclsid )
  44. pFactory = new CClassFactory( CClassFactory::ABOUT );
  45. if( NULL == pFactory )
  46. return E_OUTOFMEMORY;
  47. HRESULT hr = pFactory->QueryInterface( riid, ppvObj );
  48. return hr;
  49. }
  50. STDAPI DllCanUnloadNow(void)
  51. {
  52. if( ( 0 == g_uObjects ) && ( 0 == g_uSrvLock ) )
  53. return S_OK;
  54. else
  55. return S_FALSE;
  56. }
  57. CClassFactory::CClassFactory(FACTORY_TYPE factoryType)
  58. : m_cref(0)
  59. , m_factoryType(factoryType)
  60. {
  61. OBJECT_CREATED
  62. }
  63. CClassFactory::~CClassFactory()
  64. {
  65. OBJECT_DESTROYED
  66. }
  67. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID *ppv)
  68. {
  69. if( !ppv )
  70. return E_FAIL;
  71. *ppv = NULL;
  72. if( IsEqualIID( riid, IID_IUnknown ) )
  73. *ppv = static_cast<IClassFactory *>(this);
  74. else
  75. if( IsEqualIID(riid, IID_IClassFactory ) )
  76. *ppv = static_cast<IClassFactory *>(this);
  77. if( *ppv )
  78. {
  79. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  80. return S_OK;
  81. }
  82. return E_NOINTERFACE;
  83. }
  84. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  85. {
  86. return InterlockedIncrement( (LONG*)&m_cref );
  87. }
  88. STDMETHODIMP_(ULONG) CClassFactory::Release()
  89. {
  90. if( 0 == InterlockedDecrement( (LONG *)&m_cref ) )
  91. {
  92. delete this;
  93. return 0;
  94. }
  95. return m_cref;
  96. }
  97. STDMETHODIMP CClassFactory::CreateInstance( LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
  98. {
  99. HRESULT hr;
  100. void* pObj;
  101. if( !ppvObj )
  102. return E_FAIL;
  103. *ppvObj = NULL;
  104. //
  105. // Our object does does not support aggregation, so we need to
  106. // fail if they ask us to do aggregation.
  107. //
  108. if( pUnkOuter )
  109. return CLASS_E_NOAGGREGATION;
  110. if( COMPONENT == m_factoryType )
  111. {
  112. pObj = new CComponentData();
  113. }
  114. else
  115. {
  116. pObj = new CSnapinAbout();
  117. }
  118. if( !pObj )
  119. return E_OUTOFMEMORY;
  120. //
  121. // QueryInterface will do the AddRef() for us, so we do not
  122. // do it in this function
  123. //
  124. hr = ( (LPUNKNOWN) pObj )->QueryInterface( riid, ppvObj );
  125. if( FAILED(hr) )
  126. delete pObj;
  127. return hr;
  128. }
  129. STDMETHODIMP CClassFactory::LockServer( BOOL fLock )
  130. {
  131. if( fLock )
  132. InterlockedIncrement( (LONG *) &g_uSrvLock );
  133. else
  134. InterlockedDecrement( (LONG *) &g_uSrvLock);
  135. return S_OK;
  136. }
  137. //
  138. // Register the component in the registry.
  139. //
  140. HRESULT RegisterServer( HMODULE hModule, // DLL module handle
  141. const CLSID& clsid, // Class ID
  142. const _TCHAR* szFriendlyName ) // IDs
  143. {
  144. LPOLESTR wszCLSID = NULL;
  145. try
  146. {
  147. //
  148. // Get server location.
  149. //
  150. _TCHAR szModule[ MAX_PATH + 1];
  151. DWORD dwResult =
  152. ::GetModuleFileName( hModule,
  153. szModule,
  154. sizeof(szModule)/sizeof(_TCHAR) );
  155. szModule[ MAX_PATH ] = NULL;
  156. assert( 0 != dwResult );
  157. //
  158. // Get CLSID
  159. //
  160. HRESULT hr = StringFromCLSID( clsid, &wszCLSID );
  161. if( FAILED(hr) || ( NULL == wszCLSID ) )
  162. {
  163. return hr;
  164. }
  165. //
  166. // Build the key CLSID\\{...}
  167. //
  168. tstring strKey( _T("CLSID\\") );
  169. strKey += wszCLSID;
  170. CUDDIRegistryKey::Create( HKEY_CLASSES_ROOT, strKey );
  171. CUDDIRegistryKey key( HKEY_CLASSES_ROOT, strKey );
  172. key.SetValue( _T(""), szFriendlyName );
  173. key.Close();
  174. strKey += _T( "\\InprocServer32" );
  175. CUDDIRegistryKey::Create( HKEY_CLASSES_ROOT, strKey );
  176. CUDDIRegistryKey keyInprocServer32( HKEY_CLASSES_ROOT, strKey );
  177. keyInprocServer32.SetValue( _T(""), szModule );
  178. keyInprocServer32.SetValue( _T("ThreadingModel"), _T("Apartment") );
  179. keyInprocServer32.Close();
  180. //
  181. // Free memory.
  182. //
  183. CoTaskMemFree( wszCLSID );
  184. return S_OK;
  185. }
  186. catch( ... )
  187. {
  188. CoTaskMemFree( wszCLSID );
  189. return E_OUTOFMEMORY;
  190. }
  191. }
  192. //////////////////////////////////////////////////////////
  193. //
  194. // Exported functions
  195. //
  196. //
  197. // Server registration
  198. //
  199. STDAPI DllRegisterServer()
  200. {
  201. try
  202. {
  203. HRESULT hr = S_OK;
  204. _TCHAR szName[ 256 ];
  205. _TCHAR szSnapInName[ 256 ];
  206. _TCHAR szAboutName[ 256 ];
  207. _TCHAR szProvider[ 256 ];
  208. //
  209. // TODO: Fix the version thing here
  210. //
  211. //_TCHAR szVersion[ 100 ];
  212. LoadString( g_hinst, IDS_UDDIMMC_NAME, szName, ARRAYLEN( szName ) );
  213. LoadString( g_hinst, IDS_UDDIMMC_SNAPINNAME, szSnapInName, ARRAYLEN( szSnapInName ) );
  214. LoadString( g_hinst, IDS_UDDIMMC_ABOUTNAME, szAboutName, ARRAYLEN( szAboutName ) );
  215. LoadString( g_hinst, IDS_UDDIMMC_PROVIDER, szProvider, ARRAYLEN( szProvider ) );
  216. //
  217. // TODO: Fix the version thing here
  218. //
  219. //LoadString( g_hinst, IDS_UDDIMMC_VERSION, szVersion, ARRAYLEN( szVersion ) );
  220. //
  221. // Register our Components
  222. //
  223. hr = RegisterServer( g_hinst, CLSID_CUDDIServices, szName );
  224. if( FAILED(hr) )
  225. return hr;
  226. hr = RegisterServer( g_hinst, CLSID_CSnapinAbout, szAboutName );
  227. if( FAILED(hr) )
  228. return hr;
  229. //
  230. // Create the primary snapin nodes
  231. //
  232. LPOLESTR wszCLSID = NULL;
  233. hr = StringFromCLSID( CLSID_CUDDIServices, &wszCLSID );
  234. if( FAILED(hr) )
  235. {
  236. return hr;
  237. }
  238. LPOLESTR wszCLSIDAbout = NULL;
  239. hr = StringFromCLSID( CLSID_CSnapinAbout, &wszCLSIDAbout );
  240. if( FAILED(hr) )
  241. {
  242. CoTaskMemFree( wszCLSID );
  243. return hr;
  244. }
  245. TCHAR szPath[ MAX_PATH + 1 ];
  246. GetModuleFileName( g_hinst, szPath, MAX_PATH );
  247. tstring strNameStringIndirect( _T("@") );
  248. strNameStringIndirect += szPath;
  249. strNameStringIndirect += _T(",-");
  250. _TCHAR szNameResourceIndex[ 10 ];
  251. strNameStringIndirect += _itot( IDS_UDDIMMC_NAME, szNameResourceIndex, 10 );
  252. tstring strMMCKey( g_szMMCBasePath );
  253. strMMCKey += _T("\\SnapIns\\");
  254. strMMCKey += wszCLSID;
  255. CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strMMCKey );
  256. CUDDIRegistryKey keyMMC( strMMCKey );
  257. keyMMC.SetValue( _T("About"), wszCLSIDAbout );
  258. keyMMC.SetValue( _T("NameString"), szName );
  259. keyMMC.SetValue( _T("NameStringIndirect"), strNameStringIndirect.c_str() );
  260. keyMMC.SetValue( _T("Provider"), szProvider );
  261. //
  262. // TODO: Fix the version thing here
  263. //
  264. keyMMC.SetValue( _T("Version" ), _T("1.0") );
  265. keyMMC.Close();
  266. tstring strStandAlone( strMMCKey );
  267. strStandAlone += _T("\\StandAlone");
  268. CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strStandAlone );
  269. tstring strNodeTypes( strMMCKey );
  270. strNodeTypes += _T("\\NodeTypes");
  271. CUDDIRegistryKey::Create( HKEY_LOCAL_MACHINE, strNodeTypes );
  272. //
  273. // No NodeTypes to register
  274. // We do not allow extensions of our nodes
  275. //
  276. //
  277. // Register as a dynamic extension to computer management
  278. //
  279. tstring strExtKey( g_szMMCBasePath );
  280. strExtKey += _T("\\NodeTypes\\");
  281. strExtKey += g_szServerAppsGuid;
  282. strExtKey += _T("\\Dynamic Extensions");
  283. CUDDIRegistryKey dynamicExtensions( strExtKey );
  284. dynamicExtensions.SetValue( wszCLSID, szSnapInName );
  285. dynamicExtensions.Close();
  286. //
  287. // Register as a namespace extension to computer management
  288. //
  289. tstring strNameSpaceExtensionKey( g_szMMCBasePath );
  290. strNameSpaceExtensionKey += _T("\\NodeTypes\\");
  291. strNameSpaceExtensionKey += g_szServerAppsGuid;
  292. strNameSpaceExtensionKey += _T("\\Extensions\\NameSpace");
  293. CUDDIRegistryKey hkeyNameSpace( strNameSpaceExtensionKey );
  294. hkeyNameSpace.SetValue( wszCLSID, szSnapInName );
  295. hkeyNameSpace.Close();
  296. CoTaskMemFree( wszCLSID );
  297. CoTaskMemFree( wszCLSIDAbout );
  298. return hr;
  299. }
  300. catch( ... )
  301. {
  302. return E_FAIL;
  303. }
  304. }
  305. STDAPI DllUnregisterServer()
  306. {
  307. LPOLESTR wszCLSID = NULL;
  308. try
  309. {
  310. HRESULT hr = S_OK;
  311. UnRegisterServer( CLSID_CUDDIServices );
  312. if( FAILED(hr) )
  313. return hr;
  314. UnRegisterServer( CLSID_CSnapinAbout );
  315. if( FAILED(hr) )
  316. return hr;
  317. //
  318. // Remove \\SnapIns\\ entry
  319. //
  320. hr = StringFromCLSID( CLSID_CUDDIServices, &wszCLSID );
  321. if( FAILED( hr) || ( NULL == wszCLSID ) )
  322. {
  323. return hr;
  324. }
  325. tstring strMMCKey( g_szMMCBasePath );
  326. strMMCKey += _T("\\SnapIns\\");
  327. strMMCKey += wszCLSID;
  328. CUDDIRegistryKey::DeleteKey( HKEY_LOCAL_MACHINE, strMMCKey );
  329. //
  330. // Remove \\Dynamic Extensions key
  331. //
  332. tstring strExtKey( g_szMMCBasePath );
  333. strExtKey += _T("\\NodeTypes\\");
  334. strExtKey += g_szServerAppsGuid;
  335. strExtKey += _T("\\Dynamic Extensions");
  336. CUDDIRegistryKey dynamicExtensions( strExtKey );
  337. dynamicExtensions.DeleteValue( wszCLSID );
  338. dynamicExtensions.Close();
  339. //
  340. // Delete \\NodeTypes\\...\\Extensions\\Namespace Value
  341. //
  342. tstring strNameSpaceExtensionKey( g_szMMCBasePath );
  343. strNameSpaceExtensionKey += _T("\\NodeTypes\\");
  344. strNameSpaceExtensionKey += g_szServerAppsGuid;
  345. strNameSpaceExtensionKey += _T("\\Extensions\\NameSpace");
  346. CUDDIRegistryKey hkeyNameSpace( strNameSpaceExtensionKey );
  347. hkeyNameSpace.DeleteValue( wszCLSID );
  348. hkeyNameSpace.Close();
  349. CoTaskMemFree( wszCLSID );
  350. return S_OK;
  351. }
  352. catch(...)
  353. {
  354. CoTaskMemFree( wszCLSID );
  355. return E_FAIL;
  356. }
  357. }
  358. //
  359. // Remove the component from the registry.
  360. //
  361. LONG UnRegisterServer( const CLSID& clsid )
  362. {
  363. LPOLESTR wszCLSID = NULL;
  364. try
  365. {
  366. //
  367. // Get CLSID
  368. //
  369. HRESULT hr = StringFromCLSID( clsid, &wszCLSID );
  370. if( FAILED(hr) || ( NULL == wszCLSID ) )
  371. {
  372. return hr;
  373. }
  374. //
  375. // Build the key CLSID\\{...}
  376. //
  377. wstring wstrKey( L"CLSID\\" );
  378. wstrKey += wszCLSID;
  379. //
  380. // Delete the CLSID Key - CLSID\{...}
  381. //
  382. CUDDIRegistryKey::DeleteKey( HKEY_CLASSES_ROOT, wstrKey );
  383. }
  384. catch( ... )
  385. {
  386. //
  387. // Free memory.
  388. //
  389. CoTaskMemFree( wszCLSID );
  390. return E_OUTOFMEMORY;
  391. }
  392. //
  393. // Free memory.
  394. //
  395. CoTaskMemFree( wszCLSID );
  396. return S_OK ;
  397. }