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.

514 lines
13 KiB

  1. /************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name :
  4. basesnap.cpp
  5. Abstract :
  6. Handles low level COM functions.
  7. Author :
  8. Revision History :
  9. ***********************************************************************/
  10. #include "precomp.h"
  11. // our globals
  12. HINSTANCE g_hinst;
  13. ULONG g_uObjects = 0;
  14. ULONG g_uSrvLock = 0;
  15. class CClassFactory : public IClassFactory
  16. {
  17. private:
  18. ULONG m_cref;
  19. public:
  20. enum FACTORY_TYPE {CONTEXTEXTENSION = 0, ABOUT = 1, ADSI = 2, ADSIFACTORY = 3};
  21. CClassFactory(FACTORY_TYPE factoryType);
  22. ~CClassFactory();
  23. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  24. STDMETHODIMP_(ULONG) AddRef();
  25. STDMETHODIMP_(ULONG) Release();
  26. STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID *);
  27. STDMETHODIMP LockServer(BOOL);
  28. private:
  29. FACTORY_TYPE m_factoryType;
  30. };
  31. BOOL WINAPI DllMain(HINSTANCE hinstDLL,
  32. DWORD fdwReason,
  33. void* lpvReserved)
  34. {
  35. if (fdwReason == DLL_PROCESS_ATTACH) {
  36. g_hinst = hinstDLL;
  37. DisableThreadLibraryCalls( g_hinst );
  38. }
  39. return TRUE;
  40. }
  41. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppvObj)
  42. {
  43. if ((rclsid != CLSID_CPropSheetExtension) && (rclsid != CLSID_CSnapinAbout) && (rclsid != CLSID_CBITSExtensionSetup) &&
  44. (rclsid != __uuidof(BITSExtensionSetupFactory) ) )
  45. return CLASS_E_CLASSNOTAVAILABLE;
  46. if (!ppvObj)
  47. return E_FAIL;
  48. *ppvObj = NULL;
  49. // We can only hand out IUnknown and IClassFactory pointers. Fail
  50. // if they ask for anything else.
  51. if (!IsEqualIID(riid, IID_IUnknown) && !IsEqualIID(riid, IID_IClassFactory))
  52. return E_NOINTERFACE;
  53. CClassFactory *pFactory = NULL;
  54. // make the factory passing in the creation function for the type of object they want
  55. if (rclsid == CLSID_CPropSheetExtension)
  56. pFactory = new CClassFactory(CClassFactory::CONTEXTEXTENSION);
  57. else if (rclsid == CLSID_CSnapinAbout)
  58. pFactory = new CClassFactory(CClassFactory::ABOUT);
  59. else if (rclsid == CLSID_CBITSExtensionSetup)
  60. pFactory = new CClassFactory(CClassFactory::ADSI);
  61. else if (rclsid == __uuidof(BITSExtensionSetupFactory) )
  62. pFactory = new CClassFactory( CClassFactory::ADSIFACTORY );
  63. if (NULL == pFactory)
  64. return E_OUTOFMEMORY;
  65. HRESULT hr = pFactory->QueryInterface(riid, ppvObj);
  66. return hr;
  67. }
  68. STDAPI DllCanUnloadNow(void)
  69. {
  70. if (g_uObjects == 0 && g_uSrvLock == 0)
  71. return S_OK;
  72. else
  73. return S_FALSE;
  74. }
  75. CClassFactory::CClassFactory(FACTORY_TYPE factoryType)
  76. : m_cref(0), m_factoryType(factoryType)
  77. {
  78. OBJECT_CREATED
  79. }
  80. CClassFactory::~CClassFactory()
  81. {
  82. OBJECT_DESTROYED
  83. }
  84. STDMETHODIMP CClassFactory::QueryInterface(REFIID riid, LPVOID *ppv)
  85. {
  86. if (!ppv)
  87. return E_FAIL;
  88. *ppv = NULL;
  89. if (IsEqualIID(riid, IID_IUnknown))
  90. *ppv = static_cast<IClassFactory *>(this);
  91. else
  92. if (IsEqualIID(riid, IID_IClassFactory))
  93. *ppv = static_cast<IClassFactory *>(this);
  94. if (*ppv)
  95. {
  96. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  97. return S_OK;
  98. }
  99. return E_NOINTERFACE;
  100. }
  101. STDMETHODIMP_(ULONG) CClassFactory::AddRef()
  102. {
  103. return InterlockedIncrement((LONG *)&m_cref);
  104. }
  105. STDMETHODIMP_(ULONG) CClassFactory::Release()
  106. {
  107. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  108. {
  109. delete this;
  110. return 0;
  111. }
  112. return m_cref;
  113. }
  114. STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID * ppvObj )
  115. {
  116. HRESULT hr;
  117. void* pObj;
  118. if (!ppvObj)
  119. return E_FAIL;
  120. *ppvObj = NULL;
  121. if ( ADSI == m_factoryType )
  122. {
  123. if ( !pUnkOuter )
  124. return E_FAIL;
  125. if ( pUnkOuter && ( riid != __uuidof(IUnknown) ) )
  126. return CLASS_E_NOAGGREGATION;
  127. pObj = new CBITSExtensionSetup( pUnkOuter, NULL );
  128. if (!pObj)
  129. return E_OUTOFMEMORY;
  130. if ( pUnkOuter )
  131. {
  132. *ppvObj = ((CBITSExtensionSetup*)pObj)->GetNonDelegationIUknown();
  133. return S_OK;
  134. }
  135. }
  136. else
  137. {
  138. // Our object does does not support aggregation, so we need to
  139. // fail if they ask us to do aggregation.
  140. if (pUnkOuter)
  141. return CLASS_E_NOAGGREGATION;
  142. if (CONTEXTEXTENSION == m_factoryType ) {
  143. hr = CPropSheetExtension::InitializeStatic();
  144. if ( FAILED( hr ) )
  145. return hr;
  146. pObj = new CPropSheetExtension();
  147. } else if ( ADSIFACTORY == m_factoryType )
  148. {
  149. pObj = new CBITSExtensionSetupFactory();
  150. }
  151. else {
  152. pObj = new CSnapinAbout();
  153. }
  154. }
  155. if (!pObj)
  156. return E_OUTOFMEMORY;
  157. // QueryInterface will do the AddRef() for us, so we do not
  158. // do it in this function
  159. hr = ((LPUNKNOWN)pObj)->QueryInterface(riid, ppvObj);
  160. ((LPUNKNOWN)pObj)->Release();
  161. if (FAILED(hr))
  162. delete pObj;
  163. return hr;
  164. }
  165. STDMETHODIMP CClassFactory::LockServer(BOOL fLock)
  166. {
  167. if (fLock)
  168. InterlockedIncrement((LONG *)&g_uSrvLock);
  169. else
  170. InterlockedDecrement((LONG *)&g_uSrvLock);
  171. return S_OK;
  172. }
  173. HRESULT
  174. RegisterADSIExtension()
  175. {
  176. HRESULT Hr;
  177. HKEY hKey = NULL;
  178. DWORD dwDisposition;
  179. // Register the class.
  180. LONG Result = RegCreateKeyEx(
  181. HKEY_LOCAL_MACHINE,
  182. _T("SOFTWARE\\Microsoft\\ADs\\Providers\\IIS\\Extensions\\IIsApp\\{A55E7D7F-D51C-4859-8D2D-E308625D908E}"),
  183. 0,
  184. NULL,
  185. REG_OPTION_NON_VOLATILE,
  186. KEY_WRITE,
  187. NULL,
  188. &hKey,
  189. &dwDisposition );
  190. if ( ERROR_SUCCESS != Result )
  191. return HRESULT_FROM_WIN32( GetLastError() );
  192. // Register the Interface.
  193. const TCHAR szIf[] = _T("{29cfbbf7-09e4-4b97-b0bc-f2287e3d8eb3}");
  194. Result = RegSetValueEx( hKey, _T("Interfaces"), 0, REG_MULTI_SZ, (const BYTE *) szIf, sizeof(szIf) );
  195. if ( ERROR_SUCCESS != Result )
  196. return HRESULT_FROM_WIN32( GetLastError() );
  197. RegCloseKey(hKey);
  198. return S_OK;
  199. }
  200. HRESULT
  201. UnregisterADSIExtension()
  202. {
  203. LONG Result =
  204. RegDeleteKey(
  205. HKEY_LOCAL_MACHINE,
  206. _T("SOFTWARE\\Microsoft\\ADs\\Providers\\IIS\\Extensions\\IIsApp\\{A55E7D7F-D51C-4859-8D2D-E308625D908E}") );
  207. if ( ERROR_SUCCESS != Result )
  208. return HRESULT_FROM_WIN32( GetLastError() );
  209. return S_OK;
  210. }
  211. HRESULT
  212. RegisterEventLog()
  213. {
  214. HKEY EventLogKey = NULL;
  215. DWORD Disposition;
  216. LONG Result =
  217. RegCreateKeyEx(
  218. HKEY_LOCAL_MACHINE, // handle to open key
  219. EVENT_LOG_KEY_NAME, // subkey name
  220. 0, // reserved
  221. NULL, // class string
  222. 0, // special options
  223. KEY_ALL_ACCESS, // desired security access
  224. NULL, // inheritance
  225. &EventLogKey, // key handle
  226. &Disposition // disposition value buffer
  227. );
  228. if ( Result )
  229. return HRESULT_FROM_WIN32( Result );
  230. DWORD Value = 1;
  231. Result =
  232. RegSetValueEx(
  233. EventLogKey, // handle to key
  234. L"CategoryCount", // value name
  235. 0, // reserved
  236. REG_DWORD, // value type
  237. (BYTE*)&Value, // value data
  238. sizeof(Value) // size of value data
  239. );
  240. if ( Result )
  241. goto error;
  242. const WCHAR MessageFileName[] = L"%SystemRoot%\\system32\\bitsmgr.dll";
  243. const DWORD MessageFileNameSize = sizeof( MessageFileName );
  244. Result =
  245. RegSetValueEx(
  246. EventLogKey, // handle to key
  247. L"CategoryMessageFile", // value name
  248. 0, // reserved
  249. REG_EXPAND_SZ, // value type
  250. (const BYTE*)MessageFileName, // value data
  251. MessageFileNameSize // size of value data
  252. );
  253. if ( Result )
  254. goto error;
  255. Result =
  256. RegSetValueEx(
  257. EventLogKey, // handle to key
  258. L"EventMessageFile", // value name
  259. 0, // reserved
  260. REG_EXPAND_SZ, // value type
  261. (const BYTE*)MessageFileName, // value data
  262. MessageFileNameSize // size of value data
  263. );
  264. if ( Result )
  265. goto error;
  266. Value = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
  267. Result =
  268. RegSetValueEx(
  269. EventLogKey, // handle to key
  270. L"TypesSupported", // value name
  271. 0, // reserved
  272. REG_DWORD, // value type
  273. (BYTE*)&Value, // value data
  274. sizeof(Value) // size of value data
  275. );
  276. if ( Result )
  277. goto error;
  278. RegCloseKey( EventLogKey );
  279. EventLogKey = NULL;
  280. return S_OK;
  281. error:
  282. if ( EventLogKey )
  283. {
  284. RegCloseKey( EventLogKey );
  285. EventLogKey = NULL;
  286. }
  287. if ( REG_CREATED_NEW_KEY == Disposition )
  288. {
  289. RegDeleteKey(
  290. HKEY_LOCAL_MACHINE,
  291. EVENT_LOG_KEY_NAME );
  292. }
  293. return HRESULT_FROM_WIN32( Result );
  294. }
  295. HRESULT
  296. UnRegisterEventLog()
  297. {
  298. RegDeleteKey(
  299. HKEY_LOCAL_MACHINE,
  300. EVENT_LOG_KEY_NAME );
  301. return S_OK;
  302. }
  303. //////////////////////////////////////////////////////////
  304. //
  305. // Exported functions
  306. //
  307. //
  308. // Server registration
  309. //
  310. STDAPI DllRegisterServer()
  311. {
  312. DWORD Result;
  313. HRESULT hr = S_OK;
  314. _TCHAR szName[256];
  315. _TCHAR szSnapInName[256];
  316. LoadString(g_hinst, IDS_NAME, szName, sizeof(szName) / sizeof(*szName) );
  317. LoadString(g_hinst, IDS_SNAPINNAME, szSnapInName,
  318. sizeof(szSnapInName) / sizeof(*szSnapInName) );
  319. _TCHAR szAboutName[256];
  320. LoadString(g_hinst, IDS_ABOUTNAME, szAboutName,
  321. sizeof(szAboutName) / sizeof(*szAboutName) );
  322. _TCHAR DllName[ MAX_PATH ];
  323. Result =
  324. GetModuleFileName(
  325. (HMODULE)g_hinst,
  326. DllName,
  327. MAX_PATH - 1 );
  328. if ( !Result )
  329. hr = HRESULT_FROM_WIN32( GetLastError() );
  330. ITypeLib* TypeLib = NULL;
  331. if (SUCCEEDED(hr))
  332. hr = LoadTypeLibEx(
  333. DllName, // DllName,
  334. REGKIND_REGISTER,
  335. &TypeLib );
  336. TypeLib->Release();
  337. TypeLib = NULL;
  338. // register our CoClasses
  339. if (SUCCEEDED(hr))
  340. hr = RegisterServer(g_hinst,
  341. CLSID_CPropSheetExtension,
  342. szName);
  343. if SUCCEEDED(hr)
  344. hr = RegisterServer(g_hinst,
  345. CLSID_CSnapinAbout,
  346. szAboutName);
  347. if SUCCEEDED(hr)
  348. hr = RegisterServer(g_hinst,
  349. CLSID_CBITSExtensionSetup,
  350. _T("BITS server setup ADSI extension"),
  351. _T("Both"));
  352. if (SUCCEEDED(hr))
  353. hr = RegisterServer(g_hinst,
  354. __uuidof(BITSExtensionSetupFactory),
  355. _T("BITS server setup ADSI extension factory"),
  356. _T("Apartment"),
  357. true,
  358. _T("O:SYG:BAD:(A;;CC;;;SY)(A;;CC;;;BA)S:") );
  359. if SUCCEEDED(hr)
  360. hr = RegisterADSIExtension();
  361. // place the registry information for SnapIns
  362. if SUCCEEDED(hr)
  363. hr = RegisterSnapin(CLSID_CPropSheetExtension, szSnapInName, CLSID_CSnapinAbout);
  364. if SUCCEEDED(hr)
  365. hr = RegisterEventLog();
  366. return hr;
  367. }
  368. // {B0937B9C-D66D-4d9b-B741-49C6D66A1CD5}
  369. DEFINE_GUID(LIBID_BITSExtensionSetup,
  370. 0xb0937b9c, 0xd66d, 0x4d9b, 0xb7, 0x41, 0x49, 0xc6, 0xd6, 0x6a, 0x1c, 0xd5);
  371. STDAPI DllUnregisterServer()
  372. {
  373. DWORD Result;
  374. if ( !( ( UnregisterServer(CLSID_CPropSheetExtension) == S_OK ) &&
  375. ( UnregisterSnapin(CLSID_CPropSheetExtension) == S_OK ) &&
  376. ( UnregisterServer(CLSID_CSnapinAbout) == S_OK ) &&
  377. ( UnregisterServer(CLSID_CBITSExtensionSetup) == S_OK ) &&
  378. ( UnregisterServer(__uuidof(BITSExtensionSetupFactory)) == S_OK ) &&
  379. ( UnregisterADSIExtension() == S_OK ) &&
  380. ( UnRegisterTypeLib( LIBID_BITSExtensionSetup, 1, 0, LANG_NEUTRAL, SYS_WIN32) == S_OK ) &&
  381. ( UnRegisterEventLog( ) == S_OK ) ) )
  382. return E_FAIL;
  383. else
  384. return S_OK;
  385. }