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.

652 lines
20 KiB

  1. // persistmgr.h: interface for the SCE persistence related classes.
  2. // Copyright (c)1997-2001 Microsoft Corporation
  3. //
  4. //////////////////////////////////////////////////////////////////////
  5. #if _MSC_VER >= 1000
  6. #pragma once
  7. #endif // _MSC_VER >= 1000
  8. #include <ntsecapi.h>
  9. #include <secedit.h>
  10. #include "compkey.h"
  11. //
  12. // macro to save the similar code
  13. //
  14. #define SCE_PROV_IfErrorGotoCleanup(x) {if (FAILED(hr = (x))) goto CleanUp;}
  15. //
  16. // some helper functions
  17. //
  18. LPCWSTR EscSeekToChar(LPCWSTR pszSource, WCHAR wchChar, bool* pbEscaped, bool bEndIfNotFound);
  19. void TrimCopy(LPWSTR pDest, LPCWSTR pSource, int iLen);
  20. //
  21. // make them visible to all those who include this header
  22. //
  23. extern const WCHAR wchCookieSep;
  24. extern const WCHAR wchTypeValSep;
  25. extern const WCHAR wchTypeValLeft;
  26. extern const WCHAR wchTypeValRight;
  27. extern const WCHAR wchMethodLeft;
  28. extern const WCHAR wchMethodRight;
  29. extern const WCHAR wchMethodSep;
  30. extern const WCHAR wchParamSep;
  31. extern LPCWSTR pszListPrefix;
  32. extern LPCWSTR pszKeyPrefix;
  33. extern LPCWSTR pszNullKey;
  34. extern LPCWSTR pszAttachSectionValue;
  35. //
  36. // some constants
  37. //
  38. const int iFormatIntegral = 1;
  39. const int iFormatInt8 = 2;
  40. const int iFormatFloat = 3;
  41. const int iFormatCurrenty = 4;
  42. const int iFormatArray = 5;
  43. const int MAX_INT_LENGTH = 32;
  44. const int MAX_DOUBLE_LENGTH = 64;
  45. const int MAX_COOKIE_COUNT_PER_LINE = 10;
  46. const DWORD INVALID_COOKIE = 0;
  47. /*
  48. Class description
  49. Naming:
  50. CScePropertyMgr stands SCE wbem Property Manager.
  51. Base class:
  52. None.
  53. Purpose of class:
  54. (1) This class is used to access properties (both Put and Get). The main
  55. reason for having this function is that we can override many versions,
  56. one for each major data type the caller is expecting. Otherwise, it will
  57. be all variants.
  58. Design:
  59. (1) Trivial. Just some overrides of both Get and Put.
  60. (2) The class is attaching (Attach) to a particular wbem object. It can
  61. be freely re-attached by calling Attach multiple times. This is good
  62. inside a loop.
  63. Use:
  64. (1) Create an instance of this class.
  65. (2) Attach the wbem object to the manager.
  66. (3) Access (put or get) the properties as you wish.
  67. */
  68. class CScePropertyMgr
  69. {
  70. public:
  71. CScePropertyMgr();
  72. ~CScePropertyMgr();
  73. void Attach(IWbemClassObject *pObj);
  74. //
  75. //property Put methods:
  76. //
  77. HRESULT PutProperty(LPCWSTR pszProperty, VARIANT* pVar);
  78. HRESULT PutProperty(LPCWSTR pszProperty, LPCWSTR szValue);
  79. HRESULT PutProperty(LPCWSTR pszProperty, DWORD iValue);
  80. HRESULT PutProperty(LPCWSTR pszProperty, float fValue);
  81. HRESULT PutProperty(LPCWSTR pszProperty, double dValue);
  82. HRESULT PutProperty(LPCWSTR pszProperty, bool bValue);
  83. HRESULT PutProperty(LPCWSTR pszProperty, PSCE_NAME_LIST strList);
  84. //
  85. // property Get methods:
  86. //
  87. HRESULT GetProperty(LPCWSTR pszProperty, VARIANT* pVar);
  88. HRESULT GetProperty(LPCWSTR pszProperty, BSTR *pbstrValue);
  89. HRESULT GetProperty(LPCWSTR pszProperty, DWORD *piValue);
  90. HRESULT GetProperty(LPCWSTR pszProperty, bool *pbValue);
  91. HRESULT GetProperty(LPCWSTR szProperty, PSCE_NAME_LIST *strList);
  92. //
  93. // we can expand the the path as well.
  94. //
  95. HRESULT GetExpandedPath(LPCWSTR pszPathName, BSTR *pbstrValue, BOOL* pbIsDB);
  96. private:
  97. CComPtr<IWbemClassObject> m_srpClassObj;
  98. };
  99. /*
  100. Class description
  101. Naming:
  102. CSceStore stands SCE Store.
  103. Base class:
  104. None.
  105. Purpose of class:
  106. (1) This class is to encapulate the notation of persistence store for SCE. Almost
  107. everything we do with SCE provider (other than execute a function like Configure)
  108. is to put instances into a template store. That store can currently be a .INF file,
  109. or a database (.sdb). Our goal is to isolate this store from the rest of the
  110. code so that when we expand our store types (like XML), the code affected will
  111. be greatly reduced and thus improve code maintainability drastically.
  112. Design:
  113. (1) Move all SCE engine backend specific functionality here. This is a little bit
  114. confusing because there are so many. See the comments to locate these functions.
  115. (2) To support current property saving, we have SavePropertyToStore (several overrides)
  116. function.
  117. (3) To support current property saving, we have GetPropertyFromStore (several overrides)
  118. function. Both (2) and (3) maintain a high fidelity to the current .inf and .sdb APIs.
  119. (4) To ease the confusion that saving in a particular way means to delete, we also have
  120. DeletePropertyFromStore, DeleteSectionFromStore functions.
  121. (5) Ideally, we only need GetPropertyFromStore and SavePropertyToStore functions.
  122. (6) To allow future growth of maximum extensibility, we planned (not yet) to support IPersistStream.
  123. Use:
  124. (1) Create an instance of this class.
  125. (2) Specify the persistence properties (SetPersistPath and SetPersistProperties).
  126. (3) Call appropriate functions.
  127. */
  128. class CSceStore
  129. {
  130. public:
  131. CSceStore();
  132. ~CSceStore(){}
  133. HRESULT SetPersistProperties(IWbemClassObject* pClassObj, LPCWSTR lpszPathPropertyName);
  134. HRESULT SetPersistPath(LPCWSTR pszPath);
  135. HRESULT SetPersistStream(IPersistStream* pSceStream)
  136. {
  137. return WBEM_E_NOT_SUPPORTED; // not yet
  138. }
  139. HRESULT SavePropertyToStore(LPCWSTR pszSection, LPCWSTR pszKey, LPCWSTR pszValue)const;
  140. HRESULT SavePropertyToStore(LPCWSTR pszSection, LPCWSTR pszKey, DWORD Data)const;
  141. HRESULT SavePropertyToStore(LPCWSTR pszSection, LPCWSTR pszKey, DWORD Data, WCHAR delim, LPCWSTR pszValue)const;
  142. HRESULT GetPropertyFromStore(LPCWSTR pszSection, LPCWSTR pszKey, LPWSTR *ppszBuffer, DWORD* pdwRead)const;
  143. //
  144. // the following two methods are to stop our current semantics to let
  145. // deleting and saving share the same function. Callers be aware:
  146. // WritePrivateProfileString (which we ultimately use in inf file store) can't report
  147. // error when deleting a non existent key. So, don't rely on this return code to catch
  148. // the "deleting non-existent property" error.
  149. //
  150. HRESULT
  151. DeletePropertyFromStore (
  152. IN LPCWSTR pszSection,
  153. IN LPCWSTR pszKey
  154. )const
  155. {
  156. return SavePropertyToStore(pszSection, pszKey, (LPCWSTR)NULL);
  157. }
  158. HRESULT DeleteSectionFromStore (
  159. IN LPCWSTR pszSection
  160. )const;
  161. //
  162. // the following functions are designed for the maximum compability of the current INF file API and its
  163. // SCE backend support on reading/writing
  164. //
  165. HRESULT GetSecurityProfileInfo (
  166. AREA_INFORMATION Area,
  167. PSCE_PROFILE_INFO *ppInfoBuffer,
  168. PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  169. )const;
  170. HRESULT WriteSecurityProfileInfo (
  171. AREA_INFORMATION Area,
  172. PSCE_PROFILE_INFO ppInfoBuffer,
  173. PSCE_ERROR_LOG_INFO *Errlog,
  174. bool bAppend
  175. )const;
  176. void
  177. FreeSecurityProfileInfo (
  178. IN OUT PSCE_PROFILE_INFO pInfo
  179. )const
  180. {
  181. if (pInfo != NULL)
  182. {
  183. SceFreeProfileMemory(pInfo);
  184. }
  185. }
  186. HRESULT GetObjectSecurity (
  187. AREA_INFORMATION Area,
  188. LPCWSTR pszObjectName,
  189. PSCE_OBJECT_SECURITY *ppObjSecurity
  190. )const;
  191. void
  192. FreeObjectSecurity (
  193. IN OUT PSCE_OBJECT_SECURITY pObjSecurity
  194. )const
  195. {
  196. if (pObjSecurity)
  197. SceFreeMemory(pObjSecurity, SCE_STRUCT_OBJECT_SECURITY);
  198. }
  199. LPCWSTR
  200. GetExpandedPath ()const
  201. {
  202. return m_bstrExpandedPath;
  203. }
  204. SCE_STORE_TYPE
  205. GetStoreType ()const
  206. {
  207. return m_SceStoreType;
  208. }
  209. HRESULT WriteAttachmentSection (
  210. LPCWSTR pszKey,
  211. LPCWSTR pszData
  212. )const;
  213. private:
  214. HRESULT SavePropertyToDB (
  215. LPCWSTR pszSection,
  216. LPCWSTR pszKey,
  217. LPCWSTR pszData
  218. )const;
  219. HRESULT GetPropertyFromDB (
  220. LPCWSTR pszSection,
  221. LPCWSTR pszKey,
  222. LPWSTR *ppszBuffer,
  223. DWORD* pdwRead
  224. )const;
  225. CComBSTR m_bstrExpandedPath;
  226. CComPtr<IWbemClassObject> m_srpWbemClassObj;
  227. SCE_STORE_TYPE m_SceStoreType;
  228. };
  229. //==========================================================================
  230. //
  231. // some global parsing related functions:
  232. //
  233. HRESULT VariantFromFormattedString (
  234. LPCWSTR pszString, // [in]
  235. VARIANT* pVar // [out]
  236. );
  237. HRESULT FormatVariant (
  238. VARIANT* pVar,
  239. BSTR* pbstrData
  240. );
  241. HRESULT GetObjectPath (
  242. IWbemClassObject* pSpawn, // [in]
  243. LPCWSTR pszStorePath, // [in]
  244. LPCWSTR pszCompoundKey, // [in]
  245. BSTR* pbstrPath // [out]
  246. );
  247. HRESULT ParseCompoundKeyString (
  248. LPCWSTR pszCur,
  249. LPWSTR* ppszName,
  250. VARIANT* pVar,
  251. LPCWSTR* ppNext
  252. );
  253. HRESULT PopulateKeyProperties (
  254. LPCWSTR pszCompoundKey, // [in]
  255. CScePropertyMgr* pPropMgr // [in]
  256. );
  257. HRESULT CurrencyFromFormatString (
  258. LPCWSTR lpszFmtStr,
  259. VARIANT* pVar
  260. );
  261. HRESULT ArrayFromFormatString (
  262. LPCWSTR lpszFmtStr,
  263. VARTYPE vt,
  264. VARIANT* pVar
  265. );
  266. HRESULT FormatArray (
  267. VARIANT* pVar,
  268. BSTR* pbstrData
  269. );
  270. HRESULT GetStringPresentation (
  271. VARIANT* pVar,
  272. BSTR* pbstrValue
  273. );
  274. void* GetVoidPtrOfVariant (
  275. VARTYPE vt, // can't be VT_ARRAY, which is done separately
  276. VARIANT* pVar
  277. );
  278. HRESULT VariantFromStringValue (
  279. LPCWSTR szValue, // [in]
  280. VARTYPE vt, // [in]
  281. VARIANT* pVar // [out]
  282. );
  283. //==========================================================================
  284. /*
  285. Class description
  286. Naming:
  287. CScePersistMgr stands SCE Persistence Manager.
  288. Base class:
  289. (1) CComObjectRootEx<CComMultiThreadModel> for threading model and IUnknown
  290. (2) CComCoClass<CScePersistMgr, &CLSID_ScePersistMgr> for class factory support
  291. (3) IScePersistMgr, our custom interface
  292. Purpose of class:
  293. (1) This class is to encapulate the ultimate goal of persistence. This manager
  294. can persist any cooperating class (ISceClassObject). ISceClassObject is designed
  295. to supply a wbem object's (name, value) pairs together with its easy access to
  296. the information whether a property is a key property or not. All these are rather
  297. straight forward for any wbem object.
  298. (2) Make the persistence model extremely simple: Save, Load, Delete.
  299. (3) Current use of this persistence manager is intended for embedding classes. To adapt it
  300. for use of native classes, we need a lot more work. The reason is that native object's
  301. persistence is an intimate knowledge of SCE backend. It knows precisely how the instances
  302. are persisted. That kind of dependency ties both sides up. Unless the SCE backend modifies
  303. for a more object-oriented approach, any attempt for persisting native objects will fail.
  304. Design:
  305. (1) This is an IScePersistMgr.
  306. (2) This is not a directly instantiatable class. See the constructor and destructor, they are
  307. both protected. See Use section for creation steps.
  308. (3) maintain two vectors, one for key property values and one for non-key property values.
  309. We very often need to access key properties differently because they form the key to
  310. identify the object.
  311. (4) To quickly identify an instance and keep redundant data away from the store, an instance is
  312. identified by its cookie (just a unique DWORD number). For each cookie, the key properties
  313. should be conveniently available. For that purpose, we developed the notation of string
  314. format Compound Key. It is pretty much just an encoding of key property names and its
  315. values using a string. For example, if the key of the class has two properties CompanyName (string)
  316. and RegNumber (DWORD), then an instance of this class identified by:
  317. CompanyName = "ABCDEFG Inc.", RegNumber = 123456789
  318. will have its compound key in string format as follows:
  319. CompanyName<VT_BSTR : "ABCDEFG Inc.">RegNumber<VT_I4 : 123456789>
  320. Use:
  321. (1) Create an instance of this class. Since it's not a directly instantiatable class, you need
  322. to use CComObject<CScePersistMgr> for creation:
  323. CComObject<CScePersistMgr> *pPersistMgr = NULL;
  324. hr = CComObject<CScePersistMgr>::CreateInstance(&pPersistMgr);
  325. (2) Attach an ISceClassObject object to this instance by calling Attach.
  326. (3) Call appropriate functions.
  327. Notes:
  328. This class is not intended for derivation. It's a final class. The destructor is thus not virtual.
  329. */
  330. class ATL_NO_VTABLE CScePersistMgr
  331. : public CComObjectRootEx<CComMultiThreadModel>,
  332. public CComCoClass<CScePersistMgr, &CLSID_ScePersistMgr>,
  333. public IScePersistMgr
  334. {
  335. public:
  336. BEGIN_COM_MAP(CScePersistMgr)
  337. COM_INTERFACE_ENTRY(IScePersistMgr)
  338. END_COM_MAP()
  339. DECLARE_NOT_AGGREGATABLE( CScePersistMgr )
  340. DECLARE_REGISTRY_RESOURCEID(IDR_SceProv)
  341. protected:
  342. CScePersistMgr();
  343. ~CScePersistMgr();
  344. public:
  345. //
  346. // IScePersistMgr
  347. //
  348. STDMETHOD(Attach) (
  349. REFIID guid, // [in]
  350. IUnknown *pObj // [iid_is][in]
  351. );
  352. STDMETHOD(Save) ();
  353. STDMETHOD(Load) (
  354. BSTR bstrStorePath, // [in]
  355. IWbemObjectSink *pHandler //[in]
  356. );
  357. STDMETHOD(Delete) (
  358. BSTR bstrStorePath, // [in]
  359. IWbemObjectSink *pHandler //[in]
  360. );
  361. private:
  362. HRESULT GetCompoundKey (
  363. BSTR* pbstrKey // [out]
  364. );
  365. //
  366. // inline
  367. //
  368. HRESULT
  369. GetSectionName (
  370. OUT BSTR* pbstrSection
  371. )
  372. {
  373. return m_srpObject->GetClassName(pbstrSection);
  374. }
  375. //
  376. // inline
  377. //
  378. HRESULT
  379. GetClassName (
  380. OUT BSTR* pbstrClassName
  381. )
  382. {
  383. return m_srpObject->GetClassName(pbstrClassName);
  384. }
  385. HRESULT FormatNonKeyPropertyName (
  386. DWORD dwCookie, // [in]
  387. DWORD dwIndex, // [in]
  388. BSTR* pbstrStorePropName, // [out]
  389. BSTR* pbstrTrueName // [out]
  390. );
  391. HRESULT FormatPropertyValue (
  392. SceObjectPropertyType type, // [in]
  393. DWORD dwIndex, // [in]
  394. BSTR* pbstrProp // [out]
  395. );
  396. HRESULT LoadInstance (
  397. CSceStore* pSceStore,
  398. LPCWSTR pszSectionName,
  399. LPCWSTR pszCompoundKey,
  400. DWORD dwCookie,
  401. IWbemClassObject** ppNewObj
  402. );
  403. HRESULT SaveProperties (
  404. CSceStore* pSceStore,
  405. DWORD dwCookie,
  406. LPCWSTR pszSection
  407. );
  408. HRESULT DeleteAllNonKeyProperties (
  409. CSceStore* pSceStore,
  410. DWORD dwCookie,
  411. LPCWSTR pszSection
  412. );
  413. std::vector<LPWSTR>* GetKeyPropertyNames (
  414. IWbemServices* pNamespace,
  415. IWbemContext* pCtx
  416. );
  417. std::vector<CPropValuePair*> m_vecKeyValueList;
  418. std::vector<CPropValuePair*> m_vecPropValueList;
  419. CComPtr<ISceClassObject> m_srpObject;
  420. };
  421. //==========================================================================
  422. typedef struct tagVtTypeStruct
  423. {
  424. LPCWSTR pszVtTypeString;
  425. VARTYPE vt;
  426. } VtTypeStruct;
  427. //==========================================================================
  428. /*
  429. Class description
  430. Naming:
  431. CMapStringToVt stands for String to VT (VARTYPE) Map.
  432. Base class:
  433. None.
  434. Purpose of class:
  435. CMapStringToVt is a straight forward class wrapping up a map.
  436. Design:
  437. (1) GetType very efficiently returns the VARTYPE for the given string version of the vt.
  438. Use:
  439. (1) Create an instance of this class.
  440. (2) Call GetType to get the VARTYPE value for the given string version of the vt. For
  441. example, GetType(L"VT_BSTR") will return VT_BSTR;
  442. */
  443. class CMapStringToVt
  444. {
  445. public:
  446. CMapStringToVt (
  447. DWORD dwCount,
  448. VtTypeStruct* pInfoArray
  449. );
  450. VARTYPE GetType (
  451. LPCWSTR,
  452. VARTYPE* pSubType
  453. );
  454. private:
  455. typedef std::map<LPCWSTR, VARTYPE, strLessThan<LPCWSTR> > MapStringToVt;
  456. MapStringToVt m_Map;
  457. };
  458. //==========================================================================
  459. /*
  460. Class description
  461. Naming:
  462. CMapVtToString stands for VT (VARTYPE) to String Map.
  463. Base class:
  464. None.
  465. Purpose of class:
  466. CMapVtToString is a straight forward class wrapping up a map. It is the exact inverse
  467. version of CMapStringToVt
  468. Design:
  469. (1) GetTypeString very efficiently returns the string version of the given VARTYPE.
  470. (2) GetTypeString can also efficiently return the string version of the given VARTYPE
  471. plus the sub-VARTYPE if the given VARTYPE is VT_ARRAY.
  472. Use:
  473. (1) Create an instance of this class.
  474. (2) Call GetTypeString to get the string version of the given VARTYPE. For
  475. example, GetTypeString(VT_BSTR) will return L"VT_BSTR", and GetTypeString(VT_ARRAY, VT_BSTR)
  476. will return L"VT_ARRAY(VT_BSTR)"
  477. */
  478. class CMapVtToString
  479. {
  480. public:
  481. CMapVtToString(DWORD dwCount, VtTypeStruct* pInfoArray);
  482. LPCWSTR GetTypeString(VARTYPE vt, VARTYPE vtSub);
  483. LPCWSTR GetTypeString(VARTYPE vt);
  484. private:
  485. typedef std::map<VARTYPE, LPCWSTR> MapVtToString;
  486. MapVtToString m_Map;
  487. };