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.

593 lines
11 KiB

  1. //
  2. // Copyright 1997 - Microsoft
  3. //
  4. //
  5. // CGROUP.CPP - Handles the computer object property pages.
  6. //
  7. #include "pch.h"
  8. #ifdef INTELLIMIRROR_GROUPS
  9. #include "cservice.h"
  10. #include "groups.h"
  11. #include "cgroup.h"
  12. //
  13. // Definitions
  14. //
  15. //
  16. // Begin Class Definitions
  17. //
  18. DEFINE_MODULE("IMADMUI")
  19. DEFINE_THISCLASS("CGroup")
  20. #define THISCLASS CGroup
  21. #define LPTHISCLASS LPGROUP
  22. // ************************************************************************
  23. //
  24. // Constructor / Destructor
  25. //
  26. // ************************************************************************
  27. //
  28. // CreateInstance()
  29. //
  30. LPVOID
  31. CGroup_CreateInstance( void )
  32. {
  33. TraceFunc( "CGroup_CreateInstance()\n" );
  34. LPTHISCLASS lpcc = new THISCLASS( );
  35. HRESULT hr = THR( lpcc->Init( ) );
  36. if ( hr )
  37. {
  38. delete lpcc;
  39. RETURN(NULL);
  40. }
  41. RETURN((LPVOID) lpcc);
  42. }
  43. //
  44. // Constructor
  45. //
  46. THISCLASS::THISCLASS( )
  47. {
  48. TraceClsFunc( "CGroup()\n" );
  49. InterlockIncrement( g_cObjects );
  50. TraceFuncExit();
  51. }
  52. //
  53. // Init()
  54. //
  55. STDMETHODIMP
  56. THISCLASS::Init( )
  57. {
  58. HRESULT hr = S_OK;
  59. TraceClsFunc( "Init()\n" );
  60. // IUnknown stuff
  61. BEGIN_QITABLE_IMP( CGroup, IShellExtInit );
  62. QITABLE_IMP( IShellExtInit );
  63. QITABLE_IMP( IShellPropSheetExt );
  64. QITABLE_IMP( IEnumSAPs );
  65. END_QITABLE_IMP( CGroup );
  66. Assert( _cRef == 0);
  67. AddRef( );
  68. hr = CheckClipboardFormats( );
  69. // Private Members
  70. Assert( !_penum );
  71. Assert( !_pDataObj );
  72. _uMode = MODE_SHELL; // default
  73. HRETURN(hr);
  74. }
  75. //
  76. // Destructor
  77. //
  78. THISCLASS::~THISCLASS( )
  79. {
  80. TraceClsFunc( "~CGroup()\n" );
  81. // Members
  82. if ( _penum )
  83. _penum->Release( );
  84. if ( _pDataObj )
  85. _pDataObj->Release( );
  86. InterlockDecrement( g_cObjects );
  87. TraceFuncExit();
  88. };
  89. // ************************************************************************
  90. //
  91. // IUnknown
  92. //
  93. // ************************************************************************
  94. //
  95. // QueryInterface()
  96. //
  97. STDMETHODIMP
  98. THISCLASS::QueryInterface(
  99. REFIID riid,
  100. LPVOID *ppv )
  101. {
  102. TraceClsFunc( "" );
  103. HRESULT hr = ::QueryInterface( this, _QITable, riid, ppv );
  104. QIRETURN( hr, riid );
  105. }
  106. //
  107. // AddRef()
  108. //
  109. STDMETHODIMP_(ULONG)
  110. THISCLASS::AddRef( void )
  111. {
  112. TraceClsFunc( "[IUnknown] AddRef( )\n" );
  113. InterlockIncrement( _cRef );
  114. RETURN(_cRef);
  115. }
  116. //
  117. // Release()
  118. //
  119. STDMETHODIMP_(ULONG)
  120. THISCLASS::Release( void )
  121. {
  122. TraceClsFunc( "[IUnknown] Release( )\n" );
  123. InterlockDecrement( _cRef );
  124. if ( _cRef )
  125. RETURN(_cRef);
  126. TraceDo( delete this );
  127. RETURN(0);
  128. }
  129. // ************************************************************************
  130. //
  131. // IShellExtInit
  132. //
  133. // ************************************************************************
  134. //
  135. // Initialize()
  136. //
  137. HRESULT
  138. THISCLASS::Initialize(
  139. LPCITEMIDLIST pidlFolder,
  140. LPDATAOBJECT lpdobj,
  141. HKEY hkeyProgID )
  142. {
  143. TraceClsFunc( "[IShellExtInit] Initialize( " );
  144. TraceMsg( TF_FUNC, " pidlFolder = 0x%08x, lpdobj = 0x%08x, hkeyProgID = 0x%08x )\n",
  145. pidlFolder, lpdobj, hkeyProgID );
  146. if ( !lpdobj )
  147. RETURN(E_INVALIDARG);
  148. HRESULT hr = S_OK;
  149. FORMATETC fmte;
  150. STGMEDIUM stg = { 0 };
  151. STGMEDIUM stgOptions = { 0 };
  152. LPWSTR pszObjectName;
  153. LPWSTR pszClassName;
  154. LPWSTR pszAttribPrefix;
  155. LPDSOBJECT pDsObject;
  156. LPDSOBJECTNAMES pDsObjectNames;
  157. LPDSDISPLAYSPECOPTIONS pDsDisplayOptions;
  158. IADsContainer *pads = NULL;
  159. VARIANT varFilter;
  160. VARIANT varAFilter;
  161. SAFEARRAY *psaFilter = NULL;
  162. SAFEARRAYBOUND sabFilterArray;
  163. BSTR bstr = NULL;
  164. LONG ix[ 1 ];
  165. VariantInit(&varAFilter);
  166. VariantInit(&varFilter );
  167. // Hang onto it
  168. _pDataObj = lpdobj;
  169. _pDataObj->AddRef( );
  170. //
  171. // Retrieve the Object Names
  172. //
  173. fmte.cfFormat = g_cfDsObjectNames;
  174. fmte.tymed = TYMED_HGLOBAL;
  175. fmte.dwAspect = DVASPECT_CONTENT;
  176. fmte.lindex = -1;
  177. fmte.ptd = 0;
  178. hr = THR( lpdobj->GetData( &fmte, &stg) );
  179. if ( hr )
  180. goto Cleanup;
  181. pDsObjectNames = (LPDSOBJECTNAMES) stg.hGlobal;
  182. Assert( stg.tymed == TYMED_HGLOBAL );
  183. TraceMsg( TF_ALWAYS, "Object's Namespace CLSID: " );
  184. TraceMsgGUID( TF_ALWAYS, pDsObjectNames->clsidNamespace );
  185. TraceMsg( TF_ALWAYS, "\tNumber of Objects: %u \n", pDsObjectNames->cItems );
  186. Assert( pDsObjectNames->cItems == 1 );
  187. pDsObject = (LPDSOBJECT) pDsObjectNames->aObjects;
  188. pszObjectName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetName );
  189. pszClassName = (LPWSTR) PtrToByteOffset( pDsObjectNames, pDsObject->offsetClass );
  190. TraceMsg( TF_ALWAYS, "Object Name (Class): %s (%s)\n", pszObjectName, pszClassName );
  191. //
  192. // This must be the correct classname.
  193. //
  194. if ( StrCmp( pszClassName, DSGROUPCLASSNAME ) )
  195. {
  196. hr = E_FAIL;
  197. goto Error;
  198. }
  199. //
  200. // Retrieve the Display Spec Options
  201. //
  202. fmte.cfFormat = g_cfDsDisplaySpecOptions;
  203. fmte.tymed = TYMED_HGLOBAL;
  204. fmte.dwAspect = DVASPECT_CONTENT;
  205. fmte.lindex = -1;
  206. fmte.ptd = 0;
  207. hr = THR( lpdobj->GetData( &fmte, &stgOptions ) );
  208. if ( hr )
  209. goto Cleanup;
  210. pDsDisplayOptions = (LPDSDISPLAYSPECOPTIONS) stgOptions.hGlobal;
  211. Assert( stgOptions.tymed == TYMED_HGLOBAL );
  212. Assert( pDsDisplayOptions->dwSize == sizeof(DSDISPLAYSPECOPTIONS) );
  213. pszAttribPrefix = (LPWSTR) PtrToByteOffset( pDsDisplayOptions, pDsDisplayOptions->offsetAttribPrefix );
  214. // TraceMsg( TF_ALWAYS, TEXT("Attribute Prefix: %s\n"), pszAttribPrefix );
  215. if ( StrCmpW( pszAttribPrefix, STRING_ADMIN ) == 0 )
  216. {
  217. _uMode = MODE_ADMIN;
  218. }
  219. // else default from Init()
  220. TraceMsg( TF_ALWAYS, TEXT("Mode: %s\n"), _uMode ? TEXT("Admin") : TEXT("Shell") );
  221. ReleaseStgMedium( &stgOptions );
  222. //
  223. // Bind to the group object in the DS as a container
  224. //
  225. hr = THR( ADsGetObject( pszObjectName, IID_IADsContainer, (void **)&pads ) );
  226. if (hr)
  227. goto Error;
  228. //
  229. // Build the filter variant
  230. //
  231. bstr = SysAllocString( DSIMSAPCLASSNAME );
  232. if (!bstr)
  233. {
  234. hr = THR(E_OUTOFMEMORY);
  235. goto Error;
  236. }
  237. sabFilterArray.cElements = 1;
  238. sabFilterArray.lLbound = 0;
  239. psaFilter = SafeArrayCreate( VT_VARIANT, 1, &sabFilterArray );
  240. if ( !psaFilter )
  241. {
  242. hr = THR( E_OUTOFMEMORY );
  243. goto Error;
  244. }
  245. V_VT(&varAFilter) = VT_BSTR;
  246. V_BSTR(&varAFilter) = bstr;
  247. bstr = NULL;
  248. ix[0] = 0;
  249. hr = THR( SafeArrayPutElement( psaFilter, ix, &varAFilter ) );
  250. if (hr)
  251. goto Error;
  252. V_VT(&varFilter) = VT_VARIANT | VT_ARRAY;
  253. V_ARRAY(&varFilter) = psaFilter;
  254. psaFilter = NULL;
  255. //
  256. // Apply filter
  257. //
  258. hr = THR( pads->put_Filter( varFilter ) );
  259. if (hr)
  260. goto Error;
  261. //
  262. // Get enumeration object
  263. //
  264. hr = THR( pads->get__NewEnum( (LPUNKNOWN*) &_penum ) );
  265. if (hr)
  266. goto Error;
  267. Cleanup:
  268. if ( pads )
  269. pads->Release( );
  270. if ( bstr )
  271. SysFreeString( bstr );
  272. if ( psaFilter )
  273. SafeArrayDestroy( psaFilter );
  274. VariantClear( &varAFilter );
  275. VariantClear( &varFilter );
  276. ReleaseStgMedium( &stg );
  277. HRETURN(hr);
  278. Error:
  279. switch (hr) {
  280. case S_OK:
  281. break;
  282. default:
  283. MessageBoxFromHResult( NULL, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hr );
  284. break;
  285. }
  286. goto Cleanup;
  287. }
  288. // ************************************************************************
  289. //
  290. // IShellPropSheetExt
  291. //
  292. // ************************************************************************
  293. //
  294. // AddPages()
  295. //
  296. HRESULT
  297. THISCLASS::AddPages(
  298. LPFNADDPROPSHEETPAGE lpfnAddPage,
  299. LPARAM lParam)
  300. {
  301. TraceClsFunc( "[IShellPropSheetExt] AddPages( )\n" );
  302. if ( !lpfnAddPage )
  303. RRETURN(E_POINTER);
  304. HRESULT hr = S_OK;
  305. BOOL fServer;
  306. //
  307. // Add the "IntelliMirror Group" tab
  308. //
  309. hr = THR( ::AddPagesEx( NULL,
  310. CGroupsTab_CreateInstance,
  311. lpfnAddPage,
  312. lParam,
  313. (LPUNKNOWN) (IShellExtInit*) this ) );
  314. if (hr)
  315. goto Error;
  316. Error:
  317. RRETURN(hr);
  318. }
  319. //
  320. // ReplacePage()
  321. //
  322. HRESULT
  323. THISCLASS::ReplacePage(
  324. UINT uPageID,
  325. LPFNADDPROPSHEETPAGE lpfnReplaceWith,
  326. LPARAM lParam )
  327. {
  328. TraceClsFunc( "[IShellPropSheetExt] ReplacePage( ) *** NOT_IMPLEMENTED ***\n" );
  329. RETURN(E_NOTIMPL);
  330. }
  331. // ************************************************************************
  332. //
  333. // IEnumSAPs
  334. //
  335. // ************************************************************************
  336. //
  337. // Next( )
  338. //
  339. HRESULT
  340. THISCLASS::Next(
  341. ULONG celt,
  342. LPSERVICE * rgelt,
  343. ULONG * pceltFetched )
  344. {
  345. TraceClsFunc( "[IEnumSAPs] Next( ... )\n" );
  346. if ( !rgelt )
  347. RRETURN(E_POINTER);
  348. if ( celt > 1 )
  349. RRETURN(E_INVALIDARG);
  350. *rgelt = NULL;
  351. HRESULT hr = S_OK;
  352. VARIANT var;
  353. ULONG cFetched;
  354. IADs * pads = NULL;
  355. IDispatch *pdisp; // don't ref count - "var" will hold it for us
  356. LPSERVICE pc = NULL;
  357. VariantInit( &var );
  358. if (pceltFetched)
  359. *pceltFetched = 0;
  360. if ( _penum == NULL )
  361. {
  362. hr = THR(ERROR_INVALID_DATA);
  363. goto Error;
  364. }
  365. //
  366. // Get the attribute vars
  367. //
  368. hr = THR( _penum->Next( celt, &var, &cFetched ) );
  369. if (hr)
  370. goto Error;
  371. if ( cFetched == 0 )
  372. {
  373. hr = S_FALSE;
  374. goto Error;
  375. }
  376. if ( V_VT( &var ) != VT_DISPATCH )
  377. {
  378. hr = THR( ERROR_INVALID_DATA );
  379. goto Error;
  380. }
  381. pdisp = V_DISPATCH( &var );
  382. Assert( pdisp != NULL );
  383. hr = THR( pdisp->QueryInterface( IID_IADs, (void**) &pads ) );
  384. if (hr)
  385. goto Error;
  386. pc = (LPSERVICE) CService_CreateInstance( );
  387. if ( !pc )
  388. {
  389. hr = THR( E_OUTOFMEMORY );
  390. goto Error;
  391. }
  392. hr = THR( pc->Init2( pads ) );
  393. if (hr)
  394. goto Error;
  395. *rgelt = pc;
  396. Cleanup:
  397. if ( pads )
  398. pads->Release( );
  399. VariantClear( &var );
  400. HRETURN(hr);
  401. Error:
  402. if ( pc )
  403. pc->Release( );
  404. switch (hr) {
  405. case S_OK:
  406. case S_FALSE:
  407. break;
  408. default:
  409. MessageBoxFromHResult( NULL, IDS_ERROR_WRITINGTOCOMPUTERACCOUNT, hr );
  410. break;
  411. }
  412. goto Cleanup;
  413. }
  414. //
  415. // Skip( )
  416. //
  417. HRESULT
  418. THISCLASS::Skip(
  419. ULONG celt )
  420. {
  421. TraceClsFunc( "[IEnumSAPs] Skip( ... )\n" );
  422. HRESULT hr;
  423. if ( _penum == NULL )
  424. {
  425. hr = THR(ERROR_INVALID_DATA);
  426. goto Error;
  427. }
  428. hr = THR( _penum->Skip( celt ) );
  429. if (hr)
  430. goto Error;
  431. Error:
  432. HRETURN(hr);
  433. }
  434. //
  435. // Reset( )
  436. //
  437. HRESULT
  438. THISCLASS::Reset( void )
  439. {
  440. TraceClsFunc( "[IEnumSAPs] Reset( ... )\n" );
  441. HRESULT hr;
  442. if ( _penum == NULL )
  443. {
  444. hr = THR(ERROR_INVALID_DATA);
  445. goto Error;
  446. }
  447. hr = THR( _penum->Reset( ) );
  448. if (hr)
  449. goto Error;
  450. Error:
  451. HRETURN(hr);
  452. }
  453. //
  454. // Clone( )
  455. //
  456. HRESULT
  457. THISCLASS::Clone(
  458. void ** ppenum )
  459. {
  460. TraceClsFunc( "[IEnumSAPs] Clone( ... ) **** NOT IMPLEMENTED ****\n" );
  461. HRESULT hr = THR( E_NOTIMPL );
  462. HRETURN(hr);
  463. }
  464. #endif