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.

610 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. // Tries to create a new SDO in the collection with the given name. Returns
  213. // null if the SDO can't be created due to licensing restrictions.
  214. Sdo tryCreate(BSTR name = NULL);
  215. // Find an SDO in the collection. Returns an empty Sdo if the item doesn't
  216. // exist.
  217. Sdo find(BSTR name);
  218. SdoEnum getNewEnum();
  219. bool isNameUnique(BSTR name);
  220. void reload();
  221. void remove(ISdo* sdo);
  222. void removeAll();
  223. typedef ISdoCollection Interface;
  224. private:
  225. mutable CComPtr<ISdoCollection> self;
  226. };
  227. ///////////////////////////////////////////////////////////////////////////////
  228. //
  229. // CLASS
  230. //
  231. // SdoDictionary
  232. //
  233. // DESCRIPTION
  234. //
  235. // Wraps ISdoDictionaryOld. Instances of this class may not be accessed from
  236. // multiple apartments. You can use the SdoStream<T> class to marshal the
  237. // wrapper across the apartment boundary, but it's often easier to pass an
  238. // SdoConnection reference instead and retrieve a new dictionary object in
  239. // the other apartment.
  240. //
  241. ///////////////////////////////////////////////////////////////////////////////
  242. class SdoDictionary
  243. {
  244. public:
  245. SdoDictionary() throw ()
  246. { }
  247. SdoDictionary(IUnknown* unk);
  248. SdoDictionary(ISdoDictionaryOld* p) throw ()
  249. : self(p) { }
  250. SdoDictionary(const SdoDictionary& s) throw ()
  251. : self(s.self) { }
  252. SdoDictionary& operator=(ISdoDictionaryOld* p) throw ()
  253. { self = p; return *this; }
  254. SdoDictionary& operator=(const SdoDictionary& s) throw ()
  255. { self = s.self; return *this; }
  256. operator ISdoDictionaryOld*() const throw ()
  257. { return self; }
  258. void release() throw ()
  259. { self.Release(); }
  260. // Struct representing an (id, name) pair.
  261. struct IdName
  262. {
  263. LONG id;
  264. CComBSTR name;
  265. };
  266. Sdo createAttribute(ATTRIBUTEID id) const;
  267. // The caller must delete[] the returned IdName array. The return value is
  268. // the number of elements in the array.
  269. ULONG enumAttributeValues(ATTRIBUTEID id, IdName*& values);
  270. typedef ISdoDictionaryOld Interface;
  271. private:
  272. mutable CComPtr<ISdoDictionaryOld> self;
  273. };
  274. ///////////////////////////////////////////////////////////////////////////////
  275. //
  276. // CLASS
  277. //
  278. // SdoMachine
  279. //
  280. // DESCRIPTION
  281. //
  282. // Wraps ISdoMachine. You should generally not use this class directly since
  283. // all the necessary machine functionality can be more easily accessed
  284. // through SdoConnection.
  285. //
  286. // Instances of this class may not be accessed from multiple apartments;
  287. // instead use the SdoStream<T> class to marshal the wrapper across the
  288. // apartment boundary.
  289. //
  290. ///////////////////////////////////////////////////////////////////////////////
  291. class SdoMachine
  292. {
  293. public:
  294. SdoMachine() throw ()
  295. { }
  296. SdoMachine(IUnknown* unk);
  297. SdoMachine(ISdoMachine* p) throw ()
  298. : self(p) { }
  299. SdoMachine(const SdoMachine& s) throw ()
  300. : self(s.self) { }
  301. SdoMachine& operator=(ISdoMachine* p) throw ()
  302. { self = p; return *this; }
  303. SdoMachine& operator=(const SdoMachine& s) throw ()
  304. { self = s.self; return *this; }
  305. operator ISdoMachine*() const throw ()
  306. { return self; }
  307. void release() throw ()
  308. { self.Release(); }
  309. // Attach to the designated machine. This will create the SDO first if
  310. // necessary.
  311. void attach(BSTR machineName = NULL);
  312. // Explicitly create the machine SDO.
  313. void create();
  314. // Get the IAS service SDO.
  315. Sdo getIAS();
  316. // Get the dictionary SDO.
  317. SdoDictionary getDictionary();
  318. typedef ISdoMachine Interface;
  319. private:
  320. mutable CComPtr<ISdoMachine> self;
  321. };
  322. ///////////////////////////////////////////////////////////////////////////////
  323. //
  324. // CLASS
  325. //
  326. // SdoConsumer
  327. //
  328. // DESCRIPTION
  329. //
  330. // Abstract interface implemented by consumers of an SdoConnection if they
  331. // need to receive refresh notifications.
  332. //
  333. ///////////////////////////////////////////////////////////////////////////////
  334. class SdoConsumer
  335. {
  336. public:
  337. // Called when a property changes.
  338. virtual void propertyChanged(SnapInView& view, IASPROPERTIES id);
  339. // Return true to allow the refresh, and false to block it.
  340. virtual bool queryRefresh(SnapInView& view);
  341. // Called after the refresh is complete.
  342. virtual void refreshComplete(SnapInView& view);
  343. };
  344. ///////////////////////////////////////////////////////////////////////////////
  345. //
  346. // CLASS
  347. //
  348. // SdoConnection
  349. //
  350. // DESCRIPTION
  351. //
  352. // Encapsulates the state associated with an SDO connection to a particular
  353. // machine. Unlike the other wrapper classes an instance of SdoConnection
  354. // may be freely shared across apartments without marshalling.
  355. //
  356. ///////////////////////////////////////////////////////////////////////////////
  357. class SdoConnection
  358. {
  359. public:
  360. SdoConnection() throw ();
  361. ~SdoConnection() throw ();
  362. BSTR getMachineName() const throw ()
  363. { return machineName; }
  364. bool isLocal() const throw ()
  365. { return !machineName || !machineName[0]; }
  366. // Methods for adding and removing consumers.
  367. void advise(SdoConsumer& obj);
  368. void unadvise(SdoConsumer& obj);
  369. // Retrieve various interesting SDOs.
  370. SdoDictionary getDictionary();
  371. SdoCollection getProxyPolicies();
  372. SdoCollection getProxyProfiles();
  373. SdoCollection getServerGroups();
  374. // Connect to a machine. If computerName is NULL, connects locally.
  375. void connect(PCWSTR computerName = NULL);
  376. // Dispatch a property changed notification to all consumers.
  377. void propertyChanged(SnapInView& view, IASPROPERTIES id);
  378. // Refresh the connection. Returns 'true' if allowed.
  379. bool refresh(SnapInView& view);
  380. // Resets the service being managed.
  381. void resetService();
  382. CIASAttrList* getCIASAttrList();
  383. // Prototype of an action to be executed in the MTA.
  384. typedef void (SdoConnection::*Action)();
  385. protected:
  386. // Retrieve the service SDO for the current apartment.
  387. Sdo getService();
  388. // Various actions that must be performed in the MTA.
  389. void mtaConnect();
  390. void mtaDisconnect();
  391. void mtaRefresh();
  392. // Schedule the specified action to be executed in the MTA.
  393. void executeInMTA(Action action);
  394. // Callback routine for MTA thread.
  395. static DWORD WINAPI actionRoutine(PVOID parameter) throw ();
  396. private:
  397. CComPtr<IGlobalInterfaceTable> git;
  398. CComBSTR machineName;
  399. SdoMachine machine; // Only accessed from MTA.
  400. DWORD dictionary; // GIT cookie for ISdoDictionaryOld.
  401. DWORD service; // GIT cookie for ISdo on the IAS service.
  402. DWORD control; // GIT cookie for ISdoServiceControl
  403. CPtrArray consumers;
  404. CIASAttrList* attrList;
  405. // Not implemented.
  406. SdoConnection(SdoConnection&);
  407. SdoConnection& operator=(SdoConnection&);
  408. };
  409. ///////////////////////////////////////////////////////////////////////////////
  410. //
  411. // CLASS
  412. //
  413. // SdoProfile
  414. //
  415. // DESCRIPTION
  416. //
  417. // Wraps an collection of profile attributes. This class is *not*
  418. // multithread safe. Furthermore, instances of this class may not be
  419. // accessed from multiple apartments; instead use the SdoStream<T> class to
  420. // marshal the wrapper across the apartment boundary.
  421. //
  422. ///////////////////////////////////////////////////////////////////////////////
  423. class SdoProfile
  424. {
  425. public:
  426. SdoProfile(SdoConnection& connection);
  427. SdoProfile(SdoConnection& connection, Sdo& profile);
  428. // Assign a new profile to the object. Note the connection can not be
  429. // changed after the object is constructed.
  430. SdoProfile& operator=(Sdo& profile);
  431. // These allow an SdoProfile to be stored in an SdoStream.
  432. SdoProfile& operator=(ISdoCollection* p);
  433. operator ISdoCollection*() const throw ()
  434. { return self; }
  435. // Removes all attributes from the profile.
  436. void clear();
  437. Sdo find(ATTRIBUTEID id) const;
  438. void clearValue(ATTRIBUTEID id);
  439. bool getValue(ATTRIBUTEID id, bool& value) const;
  440. bool getValue(ATTRIBUTEID id, LONG& value) const;
  441. bool getValue(ATTRIBUTEID id, CComBSTR& value) const;
  442. bool getValue(ATTRIBUTEID id, VARIANT& value) const;
  443. void setValue(ATTRIBUTEID id, bool value);
  444. void setValue(ATTRIBUTEID id, LONG value);
  445. void setValue(ATTRIBUTEID id, BSTR value);
  446. void setValue(ATTRIBUTEID id, const VARIANT& val);
  447. typedef ISdoCollection Interface;
  448. protected:
  449. ISdo* getAlways(ATTRIBUTEID id);
  450. ISdo* getExisting(ATTRIBUTEID id) const;
  451. typedef ObjectVector<ISdo> SdoVector;
  452. private:
  453. SdoConnection& cxn;
  454. SdoCollection self;
  455. SdoVector attrs;
  456. // Not implemented.
  457. SdoProfile(const SdoProfile&);
  458. SdoProfile& operator=(const SdoProfile&);
  459. };
  460. ///////////////////////////////////////////////////////////////////////////////
  461. //
  462. // CLASS
  463. //
  464. // InterfaceStream
  465. //
  466. // DESCRIPTION
  467. //
  468. // Helper class for storing an interface in a stream. This class is suitable
  469. // for standalone use; however, when marshalling the SDO wrapper classes,
  470. // you should use the type safe SdoStream instead.
  471. //
  472. ///////////////////////////////////////////////////////////////////////////////
  473. class InterfaceStream
  474. {
  475. public:
  476. InterfaceStream() throw ()
  477. : stream(NULL)
  478. { }
  479. ~InterfaceStream() throw ()
  480. { if (stream) { stream->Release(); } }
  481. // Marshal an interface into the stream.
  482. void marshal(REFIID riid, LPUNKNOWN pUnk);
  483. // Retrieve the marshalled interface.
  484. void get(REFIID riid, LPVOID* ppv);
  485. private:
  486. IStream* stream;
  487. // Not implemented.
  488. InterfaceStream(const InterfaceStream&);
  489. InterfaceStream& operator=(const InterfaceStream&);
  490. };
  491. ///////////////////////////////////////////////////////////////////////////////
  492. //
  493. // CLASS
  494. //
  495. // SdoStream
  496. //
  497. // DESCRIPTION
  498. //
  499. // Class for storing an SDO wrapper in a stream.
  500. //
  501. ///////////////////////////////////////////////////////////////////////////////
  502. template <class T>
  503. class SdoStream
  504. {
  505. public:
  506. SdoStream() throw ()
  507. { }
  508. SdoStream(T& s)
  509. { marshal(s); }
  510. void marshal(T& s)
  511. { stream.marshal(__uuidof(T::Interface), (T::Interface*)s); }
  512. void get(T& s)
  513. {
  514. CComPtr<T::Interface> p;
  515. stream.get(__uuidof(T::Interface), (PVOID*)&p);
  516. s = p;
  517. }
  518. private:
  519. InterfaceStream stream;
  520. // Not implemented.
  521. SdoStream(const SdoStream&);
  522. SdoStream& operator=(const SdoStream&);
  523. };
  524. #endif // SDOWRAP_H