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.

468 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998
  5. //
  6. // File: DataObj.cxx
  7. //
  8. // Contents: Data object
  9. //
  10. // History: 26-Nov-1996 KyleP Created
  11. // 7/1/98 mohamedn extend comp. mgmt
  12. //
  13. //--------------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include <classid.hxx>
  17. #include <dataobj.hxx>
  18. #include <catalog.hxx>
  19. #include <prop.hxx>
  20. //
  21. // Global variables
  22. //
  23. extern long gulcInstances;
  24. //
  25. // Static member initialization
  26. //
  27. unsigned int CCIAdminDO::_cfNodeType = RegisterClipboardFormat(CCF_NODETYPE);
  28. unsigned int CCIAdminDO::_cfNodeTypeString = RegisterClipboardFormat(CCF_SZNODETYPE);
  29. unsigned int CCIAdminDO::_cfDisplayName = RegisterClipboardFormat(CCF_DISPLAY_NAME);
  30. unsigned int CCIAdminDO::_cfClassId = RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  31. unsigned int CCIAdminDO::_cfInternal = RegisterClipboardFormat(L"IS_SNAPIN_INTERNAL");
  32. unsigned int CCIAdminDO::_cfMachineName = RegisterClipboardFormat(MMC_MACHINE_NAME_CF);
  33. //+-------------------------------------------------------------------------
  34. //
  35. // Method: CCIAdminDO::QueryInterface
  36. //
  37. // Synopsis: Rebind to other interface
  38. //
  39. // Arguments: [riid] -- IID of new interface
  40. // [ppvObject] -- New interface * returned here
  41. //
  42. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  43. //
  44. // History: 26-Nov-1996 KyleP Created
  45. //
  46. //--------------------------------------------------------------------------
  47. SCODE STDMETHODCALLTYPE CCIAdminDO::QueryInterface( REFIID riid,
  48. void ** ppvObject )
  49. {
  50. SCODE sc = S_OK;
  51. if ( 0 == ppvObject )
  52. return E_INVALIDARG;
  53. if ( IID_IDataObject == riid )
  54. *ppvObject = (IUnknown *)(IDataObject *) this;
  55. else if ( IID_IUnknown == riid )
  56. *ppvObject = (IUnknown *) this;
  57. else
  58. sc = E_NOINTERFACE;
  59. if ( SUCCEEDED( sc ) )
  60. AddRef();
  61. return sc;
  62. } //QueryInterface
  63. //+-------------------------------------------------------------------------
  64. //
  65. // Method: CCIAdminDO::AddRef
  66. //
  67. // Synopsis: Increments refcount
  68. //
  69. // History: 26-Nov-1996 KyleP Created
  70. //
  71. //--------------------------------------------------------------------------
  72. ULONG STDMETHODCALLTYPE CCIAdminDO::AddRef()
  73. {
  74. //ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::AddRef\n" ));
  75. return InterlockedIncrement( &_uRefs );
  76. }
  77. //+-------------------------------------------------------------------------
  78. //
  79. // Method: CCIAdminDO::Release
  80. //
  81. // Synopsis: Decrement refcount. Delete if necessary.
  82. //
  83. // History: 26-Nov-1996 KyleP Created
  84. //
  85. //--------------------------------------------------------------------------
  86. ULONG STDMETHODCALLTYPE CCIAdminDO::Release()
  87. {
  88. //ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::Release\n" ));
  89. unsigned long uTmp = InterlockedDecrement( &_uRefs );
  90. if ( 0 == uTmp )
  91. delete this;
  92. return uTmp;
  93. }
  94. //+-------------------------------------------------------------------------
  95. //
  96. // Method: CCIAdminDO::Create
  97. //
  98. // Synopsis: CDataObject creation
  99. //
  100. // Arguments: [pBuffer] -- buffer
  101. // [len] -- buffer length
  102. // [lpMedium] -- medium
  103. //
  104. // Returns: HRESULT upon success or failure.
  105. //
  106. // History: 7/1/98 mohamedn created
  107. //
  108. //--------------------------------------------------------------------------
  109. HRESULT CCIAdminDO::Create(const void* pBuffer, int len, LPSTGMEDIUM lpMedium)
  110. {
  111. //ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::Create\n" ));
  112. HRESULT hr = DV_E_TYMED;
  113. // Do some simple validation
  114. if (pBuffer == NULL || lpMedium == NULL)
  115. return E_POINTER;
  116. // Make sure the type medium is HGLOBAL
  117. if (lpMedium->tymed == TYMED_HGLOBAL)
  118. {
  119. // Create the stream on the hGlobal passed in
  120. LPSTREAM lpStream;
  121. hr = CreateStreamOnHGlobal(lpMedium->hGlobal, FALSE, &lpStream);
  122. if (SUCCEEDED(hr))
  123. {
  124. // Because we told CreateStreamOnHGlobal with 'FALSE',
  125. // only the stream is released here.
  126. // Note - the caller (i.e. snap-in, object) will free the HGLOBAL
  127. // at the correct time. This is according to the IDataObject specification.
  128. // store in smart pointer to release when we're out of scope
  129. XInterface<IStream> xStream(lpStream);
  130. // Write to the stream the number of bytes
  131. unsigned long written;
  132. hr = lpStream->Write(pBuffer, len, &written);
  133. }
  134. }
  135. return hr;
  136. }
  137. //+-------------------------------------------------------------------------
  138. //
  139. // Method: CCIAdminDO::CreateNodeTypeData
  140. //
  141. // Synopsis: NodeType creation
  142. //
  143. // Arguments: [lpMedium] -- medium
  144. //
  145. // Returns: HRESULT upon success or failure.
  146. //
  147. // History: 7/1/98 mohamedn created
  148. //
  149. //--------------------------------------------------------------------------
  150. HRESULT CCIAdminDO::CreateNodeTypeData(LPSTGMEDIUM lpMedium)
  151. {
  152. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::CreateNodeTypeData\n" ));
  153. return Create(&guidCIRootNode, sizeof(GUID), lpMedium);
  154. }
  155. //+-------------------------------------------------------------------------
  156. //
  157. // Method: CCIAdminDO::CreateNodeTypeStringData
  158. //
  159. // Synopsis: NodeType creation
  160. //
  161. // Arguments: [lpMedium] -- medium
  162. //
  163. // Returns: HRESULT upon success or failure.
  164. //
  165. // History: 7/1/98 mohamedn created
  166. //
  167. //--------------------------------------------------------------------------
  168. HRESULT CCIAdminDO::CreateNodeTypeStringData(LPSTGMEDIUM lpMedium)
  169. {
  170. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::CreateNodeTypeStringData\n" ));
  171. return Create(wszCIRootNode, (wcslen(wszCIRootNode)+1) * sizeof (WCHAR) , lpMedium);
  172. }
  173. //+-------------------------------------------------------------------------
  174. //
  175. // Method: CCIAdminDO::CreateDisplayName
  176. //
  177. // Synopsis: CreateDisplayName
  178. //
  179. // Arguments: [lpMedium] -- medium
  180. //
  181. // Returns: HRESULT upon success or failure.
  182. //
  183. // History: 7/1/98 mohamedn created
  184. //
  185. //--------------------------------------------------------------------------
  186. HRESULT CCIAdminDO::CreateDisplayName(LPSTGMEDIUM lpMedium)
  187. {
  188. unsigned cc;
  189. XGrowable<WCHAR> xwcsTitle;
  190. if ( 0 == _pwcsMachine )
  191. {
  192. cc = wcslen( STRINGRESOURCE(srIndexServerCmpManage) ) + 1;
  193. xwcsTitle.SetSize(cc);
  194. wcscpy( xwcsTitle.Get(), STRINGRESOURCE(srIndexServerCmpManage) );
  195. }
  196. else
  197. {
  198. cc = wcslen( STRINGRESOURCE(srIndexServer) ) + 1;
  199. xwcsTitle.SetSize(cc);
  200. wcscpy( xwcsTitle.Get(), STRINGRESOURCE(srIndexServer) );
  201. if ( _pwcsMachine[0] == L'.' )
  202. {
  203. cc += wcslen( STRINGRESOURCE(srLM) );
  204. xwcsTitle.SetSize( cc );
  205. wcscat( xwcsTitle.Get(), STRINGRESOURCE(srLM) );
  206. }
  207. else
  208. {
  209. cc += wcslen( _pwcsMachine );
  210. cc += 2; // the UNC slashes
  211. xwcsTitle.SetSize( cc );
  212. wcscat( xwcsTitle.Get(), L"\\\\" );
  213. wcscat( xwcsTitle.Get(), _pwcsMachine );
  214. }
  215. }
  216. return Create( xwcsTitle.Get(), cc * sizeof(WCHAR), lpMedium);
  217. }
  218. //+-------------------------------------------------------------------------
  219. //
  220. // Method: CCIAdminDO::CreateCoClassID
  221. //
  222. // Synopsis: CreateCoClassID
  223. //
  224. // Arguments: [lpMedium] -- medium
  225. //
  226. // Returns: HRESULT upon success or failure.
  227. //
  228. // History: 7/1/98 mohamedn created
  229. //
  230. //--------------------------------------------------------------------------
  231. HRESULT CCIAdminDO::CreateCoClassID(LPSTGMEDIUM lpMedium)
  232. {
  233. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::CreateCoClassID\n" ));
  234. const CLSID & clsid = guidCISnapin;
  235. return Create(&clsid, sizeof(CLSID), lpMedium);
  236. }
  237. //+-------------------------------------------------------------------------
  238. //
  239. // Method: CCIAdminDO::CreateInternal
  240. //
  241. // Synopsis: CreateInternal
  242. //
  243. // Arguments: [lpMedium] -- medium
  244. //
  245. // Returns: HRESULT upon success or failure.
  246. //
  247. // History: 7/1/98 mohamedn created
  248. //
  249. //--------------------------------------------------------------------------
  250. HRESULT CCIAdminDO::CreateInternal(LPSTGMEDIUM lpMedium)
  251. {
  252. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::CreateInternal\n" ));
  253. void * pThis = this;
  254. return Create(&pThis, sizeof (DWORD), lpMedium );
  255. }
  256. //+-------------------------------------------------------------------------
  257. //
  258. // Method: CCIAdminDO::GetData
  259. //
  260. // Synopsis: Retrieves requested data type
  261. //
  262. // Arguments: [lpFormatetcIn] -- Requested data format
  263. // [lpMedium] -- Describes storage format
  264. //
  265. // History: 26-Nov-1996 KyleP Created
  266. //
  267. //--------------------------------------------------------------------------
  268. SCODE STDMETHODCALLTYPE CCIAdminDO::GetData( FORMATETC * lpFormatetcIn,
  269. STGMEDIUM * lpMedium )
  270. {
  271. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::GetData\n" ));
  272. return E_NOTIMPL;
  273. }
  274. //+-------------------------------------------------------------------------
  275. //
  276. // Method: CCIAdminDO::GetDataHere
  277. //
  278. // Synopsis: Retrieves requested data type. Caller allocated storage.
  279. //
  280. // Arguments: [lpFormatetcIn] -- Requested data format
  281. // [lpMedium] -- Describes storage format
  282. //
  283. // History: 26-Nov-1996 KyleP Created
  284. //
  285. //--------------------------------------------------------------------------
  286. STDMETHODIMP CCIAdminDO::GetDataHere( FORMATETC * lpFormatetc,
  287. STGMEDIUM * lpMedium )
  288. {
  289. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::GetDataHere\n" ));
  290. //
  291. // Simple parameter checking.
  292. //
  293. if ( 0 == lpFormatetc || 0 == lpMedium )
  294. return E_POINTER;
  295. HRESULT hr = DV_E_CLIPFORMAT;
  296. // Based on the CLIPFORMAT write data to the stream
  297. const CLIPFORMAT cf = lpFormatetc->cfFormat;
  298. if (cf == _cfNodeType)
  299. {
  300. hr = CreateNodeTypeData(lpMedium);
  301. }
  302. else if (cf == _cfClassId)
  303. {
  304. hr = CreateCoClassID(lpMedium);
  305. }
  306. else if (cf == _cfNodeTypeString)
  307. {
  308. hr = CreateNodeTypeStringData(lpMedium);
  309. }
  310. else if (cf == _cfDisplayName)
  311. {
  312. hr = CreateDisplayName(lpMedium);
  313. }
  314. else if (cf == _cfInternal)
  315. {
  316. hr = CreateInternal(lpMedium);
  317. }
  318. return hr;
  319. }
  320. //+-------------------------------------------------------------------------
  321. //
  322. // Method: CCIAdminDO::EnumFormatEtc
  323. //
  324. // Synopsis: Enumerate available format types
  325. //
  326. // Arguments: [dwDirection] -- Get vs. Set formats
  327. // [ppEnumFormatEtc] -- Format(s) returned here
  328. //
  329. // History: 26-Nov-1996 KyleP Created
  330. //
  331. //--------------------------------------------------------------------------
  332. SCODE STDMETHODCALLTYPE CCIAdminDO::EnumFormatEtc( DWORD dwDirection,
  333. IEnumFORMATETC ** ppEnumFormatEtc )
  334. {
  335. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::EnumFormatEtc\n" ));
  336. return E_NOTIMPL;
  337. }
  338. //+-------------------------------------------------------------------------
  339. //
  340. // Method: CCIAdminDO::CCIAdminDO
  341. //
  342. // Synopsis: Constructor
  343. //
  344. // Arguments: [cookie] -- Cookie (assigned by MMC)
  345. // [type] -- Where data object is used (scope, result, ...)
  346. // [pwcsMachine] -- Name of computer
  347. //
  348. // History: 26-Nov-1996 KyleP Created
  349. //
  350. //--------------------------------------------------------------------------
  351. CCIAdminDO::CCIAdminDO( MMC_COOKIE cookie, DATA_OBJECT_TYPES type, WCHAR const * pwcsMachine )
  352. : _cookie( cookie ),
  353. _type( type ),
  354. _pwcsMachine( pwcsMachine ),
  355. _uRefs( 1 )
  356. {
  357. // ciaDebugOut(( DEB_ITRACE, "CCIAdminDO::CCIAdminDO, New data object: cookie = 0x%x, type = 0x%x\n",
  358. // _cookie, _type ));
  359. InterlockedIncrement( &gulcInstances );
  360. }
  361. //+-------------------------------------------------------------------------
  362. //
  363. // Method: CCIAdminDO::~CCIAdminDO
  364. //
  365. // Synopsis: Destructor
  366. //
  367. // History: 26-Nov-1996 KyleP Created
  368. //
  369. //--------------------------------------------------------------------------
  370. CCIAdminDO::~CCIAdminDO()
  371. {
  372. // ciaDebugOut(( DEB_ITRACE, "Delete data object: cookie = 0x%x, type = 0x%x\n",
  373. // _cookie, _type ));
  374. InterlockedDecrement( &gulcInstances );
  375. }
  376. CCatalog * CCIAdminDO::GetCatalog()
  377. {
  378. if ( IsACatalog() )
  379. return (CCatalog *)_cookie;
  380. else if ( IsADirectoryIntermediate() || IsAPropertyIntermediate() )
  381. return &((CIntermediate *)_cookie)->GetCatalog();
  382. else if ( IsAProperty() )
  383. return &((CCachedProperty *)_cookie)->GetCatalog();
  384. else
  385. return 0;
  386. }