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.

607 lines
16 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // sdowrap.h
  8. //
  9. // SYNOPSIS
  10. //
  11. // Declares various wrapper classes for manipulating SDOs.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/10/2000 Original version.
  16. // 04/19/2000 Support for using wrappers across apartment boundaries.
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. #ifndef SDOWRAP_H
  20. #define SDOWRAP_H
  21. #if _MSC_VER >= 1000
  22. #pragma once
  23. #endif
  24. #include <sdoias.h>
  25. #include <objvec.h>
  26. class CIASAttrList;
  27. class SdoCollection;
  28. class SdoConnection;
  29. class SnapInView;
  30. //////////
  31. // Helper function to trim the whitespace from the beginning and end of a BSTR.
  32. // Useful when setting the SDO name.
  33. //////////
  34. VOID
  35. WINAPI
  36. SdoTrimBSTR(
  37. CComBSTR& bstr
  38. );
  39. ///////////////////////////////////////////////////////////////////////////////
  40. //
  41. // CLASS
  42. //
  43. // SdoException
  44. //
  45. // DESCRIPTION
  46. //
  47. // Extends COleException to indicate that this error specifically came from
  48. // a failure to access the datastore. If you use the wrapper classes, you
  49. // should never have to throw this exception yourself, but if you need to,
  50. // use the SdoThrowException function below.
  51. //
  52. ///////////////////////////////////////////////////////////////////////////////
  53. class SdoException : public COleException
  54. {
  55. public:
  56. enum Type
  57. {
  58. CONNECT_ERROR,
  59. READ_ERROR,
  60. WRITE_ERROR
  61. };
  62. Type getType() const throw ()
  63. { return type; }
  64. virtual BOOL GetErrorMessage(
  65. LPWSTR lpszError,
  66. UINT nMaxError,
  67. PUINT pnHelpContext = NULL
  68. );
  69. protected:
  70. friend VOID WINAPI SdoThrowException(HRESULT, Type);
  71. SdoException(HRESULT hr, Type errorType) throw ();
  72. private:
  73. Type type;
  74. };
  75. VOID
  76. WINAPI
  77. SdoThrowException(
  78. HRESULT hr,
  79. SdoException::Type errorType
  80. );
  81. ///////////////////////////////////////////////////////////////////////////////
  82. //
  83. // CLASS
  84. //
  85. // Sdo
  86. //
  87. // DESCRIPTION
  88. //
  89. // Wraps ISdo. Instances of this class may not be accessed from multiple
  90. // apartments; instead use the SdoStream<T> class to marshal the wrapper
  91. // across the apartment boundary.
  92. //
  93. ///////////////////////////////////////////////////////////////////////////////
  94. class Sdo
  95. {
  96. public:
  97. Sdo() throw ()
  98. { }
  99. Sdo(IUnknown* unk);
  100. Sdo(ISdo* p) throw ()
  101. : self(p) { }
  102. Sdo(const Sdo& s) throw ()
  103. : self(s.self) { }
  104. Sdo& operator=(ISdo* p) throw ()
  105. { self = p; return *this; }
  106. Sdo& operator=(const Sdo& s) throw ()
  107. { self = s.self; return *this; }
  108. operator ISdo*() const throw ()
  109. { return self; }
  110. void release() throw ()
  111. { self.Release(); }
  112. void getName(CComBSTR& value) const
  113. { getValue(PROPERTY_SDO_NAME, value); }
  114. // Sets the name of the SDO. Returns 'false' if the name is not unique.
  115. bool setName(BSTR value);
  116. void clearValue(LONG id);
  117. void getValue(LONG id, bool& value) const;
  118. void getValue(LONG id, bool& value, bool defVal) const;
  119. void getValue(LONG id, LONG& value) const;
  120. void getValue(LONG id, LONG& value, LONG defVal) const;
  121. void getValue(LONG id, CComBSTR& value) const;
  122. void getValue(LONG id, CComBSTR& value, PCWSTR defVal) const;
  123. void getValue(LONG id, VARIANT& value) const;
  124. void getValue(LONG id, SdoCollection& value) const;
  125. void setValue(LONG id, bool value);
  126. void setValue(LONG id, LONG value);
  127. void setValue(LONG id, BSTR value);
  128. void setValue(LONG id, const VARIANT& val);
  129. void apply();
  130. void restore();
  131. typedef ISdo Interface;
  132. protected:
  133. bool getValue(LONG id, VARTYPE vt, VARIANT* val, bool mandatory) const;
  134. friend class SdoConnection;
  135. private:
  136. mutable CComPtr<ISdo> self;
  137. };
  138. ///////////////////////////////////////////////////////////////////////////////
  139. //
  140. // CLASS
  141. //
  142. // SdoEnum
  143. //
  144. // DESCRIPTION
  145. //
  146. // Wraps an IEnumVARIANT that's being used to iterate through an SDO
  147. // collection. Instances of this class may not be accessed from multiple
  148. // apartments; instead use the SdoStream<T> class to marshal the wrapper
  149. // across the apartment boundary.
  150. //
  151. ///////////////////////////////////////////////////////////////////////////////
  152. class SdoEnum
  153. {
  154. public:
  155. SdoEnum() throw ()
  156. { }
  157. SdoEnum(IUnknown* unk);
  158. SdoEnum(IEnumVARIANT* p) throw ()
  159. : self(p) { }
  160. SdoEnum(const SdoEnum& s) throw ()
  161. : self(s.self) { }
  162. SdoEnum& operator=(IEnumVARIANT* p) throw ()
  163. { self = p; return *this; }
  164. SdoEnum& operator=(const SdoEnum& s) throw ()
  165. { self = s.self; return *this; }
  166. operator IEnumVARIANT*() const throw ()
  167. { return self; }
  168. void release() throw ()
  169. { self.Release(); }
  170. bool next(Sdo& s);
  171. void reset();
  172. typedef IEnumVARIANT Interface;
  173. private:
  174. mutable CComPtr<IEnumVARIANT> self;
  175. };
  176. ///////////////////////////////////////////////////////////////////////////////
  177. //
  178. // CLASS
  179. //
  180. // SdoCollection
  181. //
  182. // DESCRIPTION
  183. //
  184. // Wraps ISdoCollection. Instances of this class may not be accessed from
  185. // multiple apartments; instead use the SdoStream<T> class to marshal the
  186. // wrapper across the apartment boundary.
  187. //
  188. ///////////////////////////////////////////////////////////////////////////////
  189. class SdoCollection
  190. {
  191. public:
  192. SdoCollection() throw ()
  193. { }
  194. SdoCollection(IUnknown* unk);
  195. SdoCollection(ISdoCollection* p) throw ()
  196. : self(p) { }
  197. SdoCollection(const SdoCollection& s) throw ()
  198. : self(s.self) { }
  199. SdoCollection& operator=(ISdoCollection* p) throw ()
  200. { self = p; return *this; }
  201. SdoCollection& operator=(const SdoCollection& s) throw ()
  202. { self = s.self; return *this; }
  203. operator ISdoCollection*() const throw ()
  204. { return self; }
  205. void release() throw ()
  206. { self.Release(); }
  207. // Add an existing SDO to the collection.
  208. void add(ISdo* sdo);
  209. LONG count() throw ();
  210. // Create a new SDO in the collection with the given name.
  211. Sdo create(BSTR name = NULL);
  212. // Find an SDO in the collection. Returns an empty Sdo if the item doesn't
  213. // exist.
  214. Sdo find(BSTR name);
  215. SdoEnum getNewEnum();
  216. bool isNameUnique(BSTR name);
  217. void reload();
  218. void remove(ISdo* sdo);
  219. void removeAll();
  220. typedef ISdoCollection Interface;
  221. private:
  222. mutable CComPtr<ISdoCollection> self;
  223. };
  224. ///////////////////////////////////////////////////////////////////////////////
  225. //
  226. // CLASS
  227. //
  228. // SdoDictionary
  229. //
  230. // DESCRIPTION
  231. //
  232. // Wraps ISdoDictionaryOld. Instances of this class may not be accessed from
  233. // multiple apartments. You can use the SdoStream<T> class to marshal the
  234. // wrapper across the apartment boundary, but it's often easier to pass an
  235. // SdoConnection reference instead and retrieve a new dictionary object in
  236. // the other apartment.
  237. //
  238. ///////////////////////////////////////////////////////////////////////////////
  239. class SdoDictionary
  240. {
  241. public:
  242. SdoDictionary() throw ()
  243. { }
  244. SdoDictionary(IUnknown* unk);
  245. SdoDictionary(ISdoDictionaryOld* p) throw ()
  246. : self(p) { }
  247. SdoDictionary(const SdoDictionary& s) throw ()
  248. : self(s.self) { }
  249. SdoDictionary& operator=(ISdoDictionaryOld* p) throw ()
  250. { self = p; return *this; }
  251. SdoDictionary& operator=(const SdoDictionary& s) throw ()
  252. { self = s.self; return *this; }
  253. operator ISdoDictionaryOld*() const throw ()
  254. { return self; }
  255. void release() throw ()
  256. { self.Release(); }
  257. // Struct representing an (id, name) pair.
  258. struct IdName
  259. {
  260. LONG id;
  261. CComBSTR name;
  262. };
  263. Sdo createAttribute(ATTRIBUTEID id) const;
  264. // The caller must delete[] the returned IdName array. The return value is
  265. // the number of elements in the array.
  266. ULONG enumAttributeValues(ATTRIBUTEID id, IdName*& values);
  267. typedef ISdoDictionaryOld Interface;
  268. private:
  269. mutable CComPtr<ISdoDictionaryOld> self;
  270. };
  271. ///////////////////////////////////////////////////////////////////////////////
  272. //
  273. // CLASS
  274. //
  275. // SdoMachine
  276. //
  277. // DESCRIPTION
  278. //
  279. // Wraps ISdoMachine. You should generally not use this class directly since
  280. // all the necessary machine functionality can be more easily accessed
  281. // through SdoConnection.
  282. //
  283. // Instances of this class may not be accessed from multiple apartments;
  284. // instead use the SdoStream<T> class to marshal the wrapper across the
  285. // apartment boundary.
  286. //
  287. ///////////////////////////////////////////////////////////////////////////////
  288. class SdoMachine
  289. {
  290. public:
  291. SdoMachine() throw ()
  292. { }
  293. SdoMachine(IUnknown* unk);
  294. SdoMachine(ISdoMachine* p) throw ()
  295. : self(p) { }
  296. SdoMachine(const SdoMachine& s) throw ()
  297. : self(s.self) { }
  298. SdoMachine& operator=(ISdoMachine* p) throw ()
  299. { self = p; return *this; }
  300. SdoMachine& operator=(const SdoMachine& s) throw ()
  301. { self = s.self; return *this; }
  302. operator ISdoMachine*() const throw ()
  303. { return self; }
  304. void release() throw ()
  305. { self.Release(); }
  306. // Attach to the designated machine. This will create the SDO first if
  307. // necessary.
  308. void attach(BSTR machineName = NULL);
  309. // Explicitly create the machine SDO.
  310. void create();
  311. // Get the IAS service SDO.
  312. Sdo getIAS();
  313. // Get the dictionary SDO.
  314. SdoDictionary getDictionary();
  315. typedef ISdoMachine Interface;
  316. private:
  317. mutable CComPtr<ISdoMachine> self;
  318. };
  319. ///////////////////////////////////////////////////////////////////////////////
  320. //
  321. // CLASS
  322. //
  323. // SdoConsumer
  324. //
  325. // DESCRIPTION
  326. //
  327. // Abstract interface implemented by consumers of an SdoConnection if they
  328. // need to receive refresh notifications.
  329. //
  330. ///////////////////////////////////////////////////////////////////////////////
  331. class SdoConsumer
  332. {
  333. public:
  334. // Called when a property changes.
  335. virtual void propertyChanged(SnapInView& view, IASPROPERTIES id);
  336. // Return true to allow the refresh, and false to block it.
  337. virtual bool queryRefresh(SnapInView& view);
  338. // Called after the refresh is complete.
  339. virtual void refreshComplete(SnapInView& view);
  340. };
  341. ///////////////////////////////////////////////////////////////////////////////
  342. //
  343. // CLASS
  344. //
  345. // SdoConnection
  346. //
  347. // DESCRIPTION
  348. //
  349. // Encapsulates the state associated with an SDO connection to a particular
  350. // machine. Unlike the other wrapper classes an instance of SdoConnection
  351. // may be freely shared across apartments without marshalling.
  352. //
  353. ///////////////////////////////////////////////////////////////////////////////
  354. class SdoConnection
  355. {
  356. public:
  357. SdoConnection() throw ();
  358. ~SdoConnection() throw ();
  359. BSTR getMachineName() const throw ()
  360. { return machineName; }
  361. bool isLocal() const throw ()
  362. { return !machineName || !machineName[0]; }
  363. // Methods for adding and removing consumers.
  364. void advise(SdoConsumer& obj);
  365. void unadvise(SdoConsumer& obj);
  366. // Retrieve various interesting SDOs.
  367. SdoDictionary getDictionary();
  368. SdoCollection getProxyPolicies();
  369. SdoCollection getProxyProfiles();
  370. SdoCollection getServerGroups();
  371. // Connect to a machine. If computerName is NULL, connects locally.
  372. void connect(PCWSTR computerName = NULL);
  373. // Dispatch a property changed notification to all consumers.
  374. void propertyChanged(SnapInView& view, IASPROPERTIES id);
  375. // Refresh the connection. Returns 'true' if allowed.
  376. bool refresh(SnapInView& view);
  377. // Resets the service being managed.
  378. void resetService();
  379. CIASAttrList* getCIASAttrList();
  380. // Prototype of an action to be executed in the MTA.
  381. typedef void (SdoConnection::*Action)();
  382. protected:
  383. // Retrieve the service SDO for the current apartment.
  384. Sdo getService();
  385. // Various actions that must be performed in the MTA.
  386. void mtaConnect();
  387. void mtaDisconnect();
  388. void mtaRefresh();
  389. // Schedule the specified action to be executed in the MTA.
  390. void executeInMTA(Action action);
  391. // Callback routine for MTA thread.
  392. static DWORD WINAPI actionRoutine(PVOID parameter) throw ();
  393. private:
  394. CComPtr<IGlobalInterfaceTable> git;
  395. CComBSTR machineName;
  396. SdoMachine machine; // Only accessed from MTA.
  397. DWORD dictionary; // GIT cookie for ISdoDictionaryOld.
  398. DWORD service; // GIT cookie for ISdo on the IAS service.
  399. DWORD control; // GIT cookie for ISdoServiceControl
  400. CPtrArray consumers;
  401. CIASAttrList* attrList;
  402. // Not implemented.
  403. SdoConnection(SdoConnection&);
  404. SdoConnection& operator=(SdoConnection&);
  405. };
  406. ///////////////////////////////////////////////////////////////////////////////
  407. //
  408. // CLASS
  409. //
  410. // SdoProfile
  411. //
  412. // DESCRIPTION
  413. //
  414. // Wraps an collection of profile attributes. This class is *not*
  415. // multithread safe. Furthermore, instances of this class may not be
  416. // accessed from multiple apartments; instead use the SdoStream<T> class to
  417. // marshal the wrapper across the apartment boundary.
  418. //
  419. ///////////////////////////////////////////////////////////////////////////////
  420. class SdoProfile
  421. {
  422. public:
  423. SdoProfile(SdoConnection& connection);
  424. SdoProfile(SdoConnection& connection, Sdo& profile);
  425. // Assign a new profile to the object. Note the connection can not be
  426. // changed after the object is constructed.
  427. SdoProfile& operator=(Sdo& profile);
  428. // These allow an SdoProfile to be stored in an SdoStream.
  429. SdoProfile& operator=(ISdoCollection* p);
  430. operator ISdoCollection*() const throw ()
  431. { return self; }
  432. // Removes all attributes from the profile.
  433. void clear();
  434. Sdo find(ATTRIBUTEID id) const;
  435. void clearValue(ATTRIBUTEID id);
  436. bool getValue(ATTRIBUTEID id, bool& value) const;
  437. bool getValue(ATTRIBUTEID id, LONG& value) const;
  438. bool getValue(ATTRIBUTEID id, CComBSTR& value) const;
  439. bool getValue(ATTRIBUTEID id, VARIANT& value) const;
  440. void setValue(ATTRIBUTEID id, bool value);
  441. void setValue(ATTRIBUTEID id, LONG value);
  442. void setValue(ATTRIBUTEID id, BSTR value);
  443. void setValue(ATTRIBUTEID id, const VARIANT& val);
  444. typedef ISdoCollection Interface;
  445. protected:
  446. ISdo* getAlways(ATTRIBUTEID id);
  447. ISdo* getExisting(ATTRIBUTEID id) const;
  448. typedef ObjectVector<ISdo> SdoVector;
  449. private:
  450. SdoConnection& cxn;
  451. SdoCollection self;
  452. SdoVector attrs;
  453. // Not implemented.
  454. SdoProfile(const SdoProfile&);
  455. SdoProfile& operator=(const SdoProfile&);
  456. };
  457. ///////////////////////////////////////////////////////////////////////////////
  458. //
  459. // CLASS
  460. //
  461. // InterfaceStream
  462. //
  463. // DESCRIPTION
  464. //
  465. // Helper class for storing an interface in a stream. This class is suitable
  466. // for standalone use; however, when marshalling the SDO wrapper classes,
  467. // you should use the type safe SdoStream instead.
  468. //
  469. ///////////////////////////////////////////////////////////////////////////////
  470. class InterfaceStream
  471. {
  472. public:
  473. InterfaceStream() throw ()
  474. : stream(NULL)
  475. { }
  476. ~InterfaceStream() throw ()
  477. { if (stream) { stream->Release(); } }
  478. // Marshal an interface into the stream.
  479. void marshal(REFIID riid, LPUNKNOWN pUnk);
  480. // Retrieve the marshalled interface.
  481. void get(REFIID riid, LPVOID* ppv);
  482. private:
  483. IStream* stream;
  484. // Not implemented.
  485. InterfaceStream(const InterfaceStream&);
  486. InterfaceStream& operator=(const InterfaceStream&);
  487. };
  488. ///////////////////////////////////////////////////////////////////////////////
  489. //
  490. // CLASS
  491. //
  492. // SdoStream
  493. //
  494. // DESCRIPTION
  495. //
  496. // Class for storing an SDO wrapper in a stream.
  497. //
  498. ///////////////////////////////////////////////////////////////////////////////
  499. template <class T>
  500. class SdoStream
  501. {
  502. public:
  503. SdoStream() throw ()
  504. { }
  505. SdoStream(T& s)
  506. { marshal(s); }
  507. void marshal(T& s)
  508. { stream.marshal(__uuidof(T::Interface), (T::Interface*)s); }
  509. void get(T& s)
  510. {
  511. CComPtr<T::Interface> p;
  512. stream.get(__uuidof(T::Interface), (PVOID*)&p);
  513. s = p;
  514. }
  515. private:
  516. InterfaceStream stream;
  517. // Not implemented.
  518. SdoStream(const SdoStream&);
  519. SdoStream& operator=(const SdoStream&);
  520. };
  521. #endif // SDOWRAP_H