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.

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