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.

521 lines
19 KiB

  1. /*++
  2. Copyright (C) 2000-2001 Microsoft Corporation
  3. --*/
  4. #ifndef __A51PROV__H_
  5. #define __A51PROV__H_
  6. #include <windows.h>
  7. #include <wbemidl.h>
  8. #include <unk.h>
  9. #include <wbemcomn.h>
  10. #include <sync.h>
  11. #include <reposit.h>
  12. #include <wmiutils.h>
  13. #include <objpath.h>
  14. #include <filecach.h>
  15. #include <hiecache.h>
  16. #include <corex.h>
  17. #include "a51fib.h"
  18. #include "creposit.h"
  19. class CDbIterator;
  20. class CRepEvent
  21. {
  22. public:
  23. DWORD m_dwType;
  24. LPWSTR m_wszArg1;
  25. LPWSTR m_wszNamespace;
  26. _IWmiObject* m_pObj1;
  27. _IWmiObject* m_pObj2;
  28. CRepEvent(DWORD dwType, LPCWSTR wszNamespace, LPCWSTR wszArg1,
  29. _IWmiObject* pObj1, _IWmiObject* pObj2);
  30. ~CRepEvent();
  31. void* operator new(size_t) {return TempAlloc(sizeof(CRepEvent));}
  32. void operator delete(void* p) {return TempFree(p, sizeof(CRepEvent));}
  33. };
  34. class CEventCollector
  35. {
  36. protected:
  37. CUniquePointerArray<CRepEvent> m_apEvents;
  38. bool m_bNamespaceOnly;
  39. CRITICAL_SECTION m_csLock;
  40. public:
  41. CEventCollector() : m_bNamespaceOnly(false){ InitializeCriticalSection(&m_csLock);}
  42. ~CEventCollector() { DeleteCriticalSection(&m_csLock); }
  43. bool AddEvent(CRepEvent* pEvent);
  44. void SetNamespaceOnly(bool bNamespaceOnly)
  45. {m_bNamespaceOnly = bNamespaceOnly;}
  46. bool IsNamespaceOnly() {return m_bNamespaceOnly;}
  47. HRESULT SendEvents(_IWmiCoreServices* pCore);
  48. void DeleteAllEvents();
  49. void TransferEvents(CEventCollector &aEventsToTransfer);
  50. int GetSize() { return m_apEvents.GetSize(); }
  51. };
  52. class CSession : public CUnkBase<IWmiDbSessionEx, &IID_IWmiDbSessionEx>
  53. {
  54. private:
  55. CEventCollector m_aTransactedEvents;
  56. bool m_bInWriteTransaction;
  57. public:
  58. CSession(CLifeControl* pControl = NULL) : TUnkBase(pControl), m_bInWriteTransaction(false) {}
  59. virtual ~CSession();
  60. ULONG STDMETHODCALLTYPE Release();
  61. HRESULT STDMETHODCALLTYPE GetObject(
  62. IWmiDbHandle *pScope,
  63. IWbemPath *pPath,
  64. DWORD dwFlags,
  65. DWORD dwRequestedHandleType,
  66. IWmiDbHandle **ppResult
  67. );
  68. HRESULT STDMETHODCALLTYPE GetObjectDirect(
  69. IWmiDbHandle *pScope,
  70. IWbemPath *pPath,
  71. DWORD dwFlags,
  72. REFIID riid,
  73. LPVOID *pObj
  74. );
  75. HRESULT STDMETHODCALLTYPE PutObject(
  76. IWmiDbHandle *pScope,
  77. REFIID riid,
  78. LPVOID pObj,
  79. DWORD dwFlags,
  80. DWORD dwRequestedHandleType,
  81. IWmiDbHandle **ppResult
  82. );
  83. HRESULT STDMETHODCALLTYPE DeleteObject(
  84. IWmiDbHandle *pScope,
  85. DWORD dwFlags,
  86. REFIID riid,
  87. LPVOID pObj
  88. );
  89. HRESULT STDMETHODCALLTYPE ExecQuery(
  90. IWmiDbHandle *pScope,
  91. IWbemQuery *pQuery,
  92. DWORD dwFlags,
  93. DWORD dwRequestedHandleType,
  94. DWORD *dwMessageFlags,
  95. IWmiDbIterator **ppQueryResult
  96. );
  97. HRESULT STDMETHODCALLTYPE RenameObject(
  98. IWbemPath *pOldPath,
  99. IWbemPath *pNewPath,
  100. DWORD dwFlags,
  101. DWORD dwRequestedHandleType,
  102. IWmiDbHandle **ppResult
  103. );
  104. HRESULT STDMETHODCALLTYPE Enumerate(
  105. IWmiDbHandle *pScope,
  106. DWORD dwFlags,
  107. DWORD dwRequestedHandleType,
  108. IWmiDbIterator **ppQueryResult
  109. );
  110. HRESULT STDMETHODCALLTYPE AddObject(
  111. IWmiDbHandle *pScope,
  112. IWbemPath *pPath,
  113. DWORD dwFlags,
  114. DWORD dwRequestedHandleType,
  115. IWmiDbHandle **ppResult
  116. );
  117. HRESULT STDMETHODCALLTYPE RemoveObject (
  118. IWmiDbHandle *pScope,
  119. IWbemPath *pPath,
  120. DWORD dwFlags
  121. );
  122. HRESULT STDMETHODCALLTYPE SetDecoration(
  123. LPWSTR lpMachineName,
  124. LPWSTR lpNamespacePath
  125. );
  126. HRESULT STDMETHODCALLTYPE SupportsQueries(
  127. DWORD *dwQuerySupportLevel
  128. ) {return WBEM_E_FAILED;};
  129. HRESULT STDMETHODCALLTYPE GetObjectByPath(
  130. IWmiDbHandle *pScope,
  131. LPCWSTR wszPath,
  132. DWORD dwFlags,
  133. REFIID riid,
  134. LPVOID *pObj
  135. );
  136. HRESULT STDMETHODCALLTYPE DeleteObjectByPath(
  137. IWmiDbHandle *pScope,
  138. LPCWSTR wszObjectPath,
  139. DWORD dwFlags
  140. );
  141. HRESULT STDMETHODCALLTYPE ExecQuerySink(
  142. IWmiDbHandle *pScope,
  143. IWbemQuery *pQuery,
  144. DWORD dwFlags,
  145. DWORD dwRequestedHandleType,
  146. IWbemObjectSink* pSink,
  147. DWORD *dwMessageFlags
  148. );
  149. HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv);
  150. HRESULT STDMETHODCALLTYPE BeginWriteTransaction(DWORD dwFlags);
  151. HRESULT STDMETHODCALLTYPE BeginReadTransaction(DWORD dwFlags);
  152. HRESULT STDMETHODCALLTYPE CommitTransaction(DWORD dwFlags);
  153. HRESULT STDMETHODCALLTYPE AbortTransaction(DWORD dwFlags);
  154. protected:
  155. HRESULT InternalBeginTransaction(bool bWriteOperation);
  156. HRESULT InternalAbortTransaction(bool bWriteOperation);
  157. HRESULT InternalCommitTransaction(bool bWriteOperation);
  158. };
  159. class CNamespaceHandle : public CUnkBase<IWmiDbHandle, &IID_IWmiDbHandle>
  160. {
  161. protected:
  162. static long s_lActiveRepNs;
  163. CRepository * m_pRepository;
  164. WString m_wsNamespace;
  165. WString m_wsScope;
  166. WString m_wsFullNamespace;
  167. WCHAR m_wszMachineName[MAX_COMPUTERNAME_LENGTH+1];
  168. WCHAR m_wszClassRootDir[MAX_PATH];
  169. long m_lClassRootDirLen;
  170. WCHAR m_wszInstanceRootDir[MAX_PATH];
  171. long m_lInstanceRootDirLen;
  172. CHierarchyCache* m_pClassCache;
  173. CForestCache* m_ForestCache;
  174. _IWmiObject* m_pNullClass;
  175. bool m_bCached;
  176. bool m_bUseIteratorLock;
  177. public:
  178. CNamespaceHandle(CLifeControl* pControl, CRepository * pRepository);
  179. ~CNamespaceHandle();
  180. STDMETHOD(GetHandleType)(DWORD* pdwType) {*pdwType = 0; return S_OK;}
  181. CHR Initialize(LPCWSTR wszNamespace, LPCWSTR wszScope = NULL);
  182. CHR GetObject(
  183. IWbemPath *pPath,
  184. DWORD dwFlags,
  185. DWORD dwRequestedHandleType,
  186. IWmiDbHandle **ppResult
  187. );
  188. CHR GetObjectDirect(
  189. IWbemPath *pPath,
  190. DWORD dwFlags,
  191. REFIID riid,
  192. LPVOID *pObj
  193. );
  194. CHR PutObject(
  195. REFIID riid,
  196. LPVOID pObj,
  197. DWORD dwFlags,
  198. DWORD dwRequestedHandleType,
  199. IWmiDbHandle **ppResult,
  200. CEventCollector &aEvents
  201. );
  202. CHR DeleteObject(
  203. DWORD dwFlags,
  204. REFIID riid,
  205. LPVOID pObj,
  206. CEventCollector &aEvents
  207. );
  208. CHR ExecQuery(
  209. IWbemQuery *pQuery,
  210. DWORD dwFlags,
  211. DWORD dwRequestedHandleType,
  212. DWORD *dwMessageFlags,
  213. IWmiDbIterator **ppQueryResult
  214. );
  215. CHR GetObjectByPath(
  216. LPWSTR wszPath,
  217. DWORD dwFlags,
  218. REFIID riid,
  219. LPVOID *pObj
  220. );
  221. CHR ExecQuerySink(
  222. IWbemQuery *pQuery,
  223. DWORD dwFlags,
  224. DWORD dwRequestedHandleType,
  225. IWbemObjectSink* pSink,
  226. DWORD *dwMessageFlags
  227. );
  228. CHR DeleteObjectByPath(DWORD dwFlags, LPWSTR wszPath, CEventCollector &aEvents);
  229. HRESULT SendEvents(CEventCollector &aEvents);
  230. CHR GetErrorStatus();
  231. void SetErrorStatus(HRESULT hres);
  232. HRESULT CreateSystemClasses(CFlexArray &aSystemClasses);
  233. void TellIteratorNotToLock() { m_bUseIteratorLock = false; }
  234. protected:
  235. CHR GetObjectHandleByPath(LPWSTR wszBuffer, DWORD dwFlags,
  236. DWORD dwRequestedHandleType, IWmiDbHandle **ppResult);
  237. CHR PutInstance(_IWmiObject* pInst, DWORD dwFlags, CEventCollector &aEvents);
  238. CHR PutClass(_IWmiObject* pClass, DWORD dwFlags, CEventCollector &aEvents);
  239. CHR ConstructClassRelationshipsDir(LPCWSTR wszClassName,
  240. LPWSTR wszDirPath);
  241. CHR WriteParentChildRelationship(LPCWSTR wszChildFileName,
  242. LPCWSTR wszParentName);
  243. CHR WriteClassReferences(_IWmiObject* pClass, LPCWSTR wszFileName);
  244. CHR ExecClassQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  245. IWbemObjectSink* pSink, DWORD dwFlags);
  246. CHR ExecInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  247. LPCWSTR wszClassName, bool bDeep,
  248. IWbemObjectSink* pSink);
  249. CHR GetClassDirect(LPCWSTR wszClassName, REFIID riid, void** ppObj,
  250. bool bClone, __int64* pnTime,
  251. bool* pbRead, bool *pbSystemClass);
  252. CHR GetInstanceDirect(ParsedObjectPath* pPath,
  253. REFIID riid, void** ppObj);
  254. CHR DeleteInstance(LPCWSTR wszClassName, LPCWSTR wszKey, CEventCollector &aEvents);
  255. CHR DeleteInstanceByFile(LPCWSTR wszFilePath, _IWmiObject* pClass,
  256. bool bClassDeletion, CEventCollector &aEvents);
  257. CHR DeleteClass(LPCWSTR wszClassName, CEventCollector &aEvents);
  258. CHR DeleteClassInstances(LPCWSTR wszClassName, _IWmiObject* pClass, CEventCollector &aEvents);
  259. CHR FileToSystemClass(LPCWSTR wszFileName, _IWmiObject** ppClass,
  260. bool bClone, __int64* pnTime = NULL);
  261. CHR FileToClass(LPCWSTR wszFileName, _IWmiObject** ppClass,
  262. bool bClone, __int64* pnTime,
  263. bool *pbSystemClass);
  264. CHR FileToInstance(_IWmiObject* pClass,
  265. LPCWSTR wszFileName,
  266. BYTE *pRetrievedBlob,
  267. DWORD dwSize,
  268. _IWmiObject** ppInstance,
  269. bool bMustBeThere = false);
  270. CHR WriteInstanceReferences(_IWmiObject* pInst, LPCWSTR wszClassName,
  271. LPCWSTR wszFilePath);
  272. CHR WriteInstanceReference(LPCWSTR wszReferringFile,
  273. LPCWSTR wszReferringClass,
  274. LPCWSTR wszReferringProp, LPWSTR wszReference);
  275. CHR CalculateInstanceFileBase(LPCWSTR wszInstancePath,
  276. LPWSTR wszFilePath);
  277. CHR ExecClassRefQuery(LPCWSTR wszQuery, LPCWSTR wszClassName,
  278. IWbemObjectSink* pSink);
  279. CHR ExecReferencesQuery(LPCWSTR wszQuery, IWbemObjectSink* pSink);
  280. CHR ExecInstanceRefQuery(LPCWSTR wszQuery, LPCWSTR wszClassName,
  281. LPCWSTR wszKey, IWbemObjectSink* pSink);
  282. CHR GetReferrerFromFile(LPCWSTR wszReferenceFile,
  283. LPWSTR wszReferrerRelFile,
  284. LPWSTR* pwszReferrerNamespace,
  285. LPWSTR* pwszReferrerClass,
  286. LPWSTR* pwszReferrerProp);
  287. CHR DeleteInstanceReference(LPCWSTR wszOurFilePath,
  288. LPWSTR wszReference);
  289. CHR DeleteInstanceReferences(_IWmiObject* pInst, LPCWSTR wszFilePath);
  290. CHR EnumerateClasses(IWbemObjectSink* pSink,
  291. LPCWSTR wszSuperClass, LPCWSTR wszAncestor,
  292. bool bClone, bool bDontIncludeAncestorInResultSet);
  293. CHR ListToEnum(CWStringArray& wsClasses,
  294. IWbemObjectSink* pSink, bool bClone);
  295. bool Hash(LPCWSTR wszName, LPWSTR wszHash);
  296. CHR InstanceToFile(IWbemClassObject* pInst, LPCWSTR wszClassName,
  297. LPCWSTR wszFileName1, LPCWSTR wszFileName2,
  298. __int64 nClassTime);
  299. CHR ConstructInstanceDefName(LPWSTR wszInstanceDefName, LPCWSTR wszKey);
  300. CHR ClassToFile(_IWmiObject* pSuperClass, _IWmiObject* pClass,
  301. LPCWSTR wszFileName, __int64 nFakeUpdateTime = 0);
  302. CHR ConstructClassName(LPCWSTR wszClassName,
  303. LPWSTR wszFileName);
  304. CHR TryGetShortcut(LPWSTR wszPath, DWORD dwFlags, REFIID riid,
  305. LPVOID *pObj);
  306. CHR ComputeKeyFromPath(LPWSTR wszPath, LPWSTR wszKey,
  307. LPWSTR* pwszClassName, bool* pbIsClass,
  308. LPWSTR* pwszNamespace = NULL);
  309. CHR ParseKey(LPWSTR wszKeyStart, LPWSTR* pwcRealStart,
  310. LPWSTR* pwcNextKey);
  311. CHR GetInstanceByKey(LPCWSTR wszClassName, LPCWSTR wszKey,
  312. REFIID riid, void** ppObj);
  313. CHR WriteClassRelationships(_IWmiObject* pClass, LPCWSTR wszFileName);
  314. CHR ConstructParentChildFileName(LPCWSTR wszChildFileName,
  315. LPCWSTR wszParentName,
  316. LPWSTR wszParentChildFileName);
  317. CHR DeleteDerivedClasses(LPCWSTR wszClassName, CEventCollector &aEvents);
  318. CHR EraseParentChildRelationship(LPCWSTR wszChildFileName,
  319. LPCWSTR wszParentName);
  320. CHR EraseClassRelationships(LPCWSTR wszClassName,
  321. _IWmiObject* pClass, LPCWSTR wszFileName);
  322. CHR GetClassByHash(LPCWSTR wszHash, bool bClone, _IWmiObject** ppClass,
  323. __int64* pnTime, bool* pbRead,
  324. bool *pbSystemClass);
  325. CHR DeleteClassByHash(LPCWSTR wszHash, CEventCollector &aEvents);
  326. CHR DeleteClassInternal(LPCWSTR wszClassName, _IWmiObject* pClass,
  327. LPCWSTR wszFileName, CEventCollector &aEvents,
  328. bool bSystemClass);
  329. CHR GetChildHashes(LPCWSTR wszClassName, CWStringArray& wsChildHashes);
  330. CHR GetChildDefs(LPCWSTR wszClassName, bool bRecursive,
  331. IWbemObjectSink* pSink, bool bClone);
  332. CHR ConstructClassDefFileName(LPCWSTR wszClassName, LPWSTR wszFileName);
  333. CHR ConstructClassDefFileNameFromHash(LPCWSTR wszHash,
  334. LPWSTR wszFileName);
  335. CHR ConstructClassRelationshipsDirFromHash(LPCWSTR wszHash,
  336. LPWSTR wszDirPath);
  337. CHR GetChildHashesByHash(LPCWSTR wszHash, CWStringArray& wsChildHashes);
  338. CHR GetChildDefsByHash(LPCWSTR wszHash, bool bRecursive,
  339. IWbemObjectSink* pSink, bool bClone);
  340. CHR FireEvent(CEventCollector &aEvents, DWORD dwType, LPCWSTR wszArg1, _IWmiObject* pObj1,
  341. _IWmiObject* pObj2 = NULL);
  342. CHR DeleteSelf(CEventCollector &aEvents);
  343. CHR DeleteInstanceAsScope(_IWmiObject* pInst, CEventCollector &aEvents);
  344. CHR DeleteInstanceSelf(LPCWSTR wszFilePath, _IWmiObject* pInst,
  345. bool bClassDeletion);
  346. CHR ConstructReferenceDir(LPWSTR wszTargetPath, LPWSTR wszDir);
  347. CHR ConstructReferenceDirFromKey(LPCWSTR wszClassName,
  348. LPCWSTR wszKey, LPWSTR wszReferenceDir);
  349. CHR ConstructReferenceFileName(LPWSTR wszReference,
  350. LPCWSTR wszReferringFile, LPWSTR wszReferenceFile);
  351. CHR ConstructKeyRootDirFromClass(LPWSTR wszDir, LPCWSTR wszClassName);
  352. CHR ConstructKeyRootDirFromKeyRoot(LPWSTR wszDir,
  353. LPCWSTR wszKeyRootClass);
  354. CHR ConstructLinkDirFromClass(LPWSTR wszDir, LPCWSTR wszClassName);
  355. CHR DeleteInstanceLink(_IWmiObject* pInst,
  356. LPCWSTR wszInstanceDefFilePath);
  357. CHR GetKeyRoot(LPCWSTR wszClass,
  358. TEMPFREE_ME LPWSTR* pwszKeyRootClass);
  359. CHR ConstructInstDefNameFromLinkName(LPWSTR wszInstanceDefName,
  360. LPCWSTR wszInstanceLinkName);
  361. CHR ExecDeepInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  362. LPCWSTR wszClassHash,
  363. IWbemObjectSink* pSink);
  364. CHR ExecShallowInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  365. LPCWSTR wszClassHash,
  366. IWbemObjectSink* pSink);
  367. CHR GetKeyRootByHash(LPCWSTR wszClassHash,
  368. TEMPFREE_ME LPWSTR* pwszKeyRootClass);
  369. CHR ConstructKeyRootDirFromClassHash(LPWSTR wszDir,
  370. LPCWSTR wszClassHash);
  371. CHR ConstructLinkDirFromClassHash(LPWSTR wszDir, LPCWSTR wszClassHash);
  372. CHR ConstructClassReferenceFileName(LPCWSTR wszReferredToClass,
  373. LPCWSTR wszReferringFile,
  374. LPCWSTR wszReferringProp,
  375. LPWSTR wszFieName);
  376. CHR WriteClassReference(_IWmiObject* pReferringClass,
  377. LPCWSTR wszReferringFile,
  378. LPCWSTR wszReferringProp);
  379. CHR EraseClassReference(_IWmiObject* pReferringClass,
  380. LPCWSTR wszReferringFile,
  381. LPCWSTR wszReferringProp);
  382. //CFileCache* GetFileCache();
  383. CHR CanClassBeUpdatedCompatible(DWORD dwFlags, LPCWSTR wszClassName,
  384. _IWmiObject *pOldClass, _IWmiObject *pNewClass);
  385. CHR DeleteInstanceBackReferences(LPCWSTR wszFilePath);
  386. CHR ConstructReferenceDirFromFilePath(LPCWSTR wszFilePath,
  387. LPWSTR wszReferenceDir);
  388. CHR ClassHasChildren(LPCWSTR wszClassName);
  389. CHR ClassHasInstances(LPCWSTR wszClassName);
  390. CHR ClassHasInstancesFromClassHash(LPCWSTR wszClassHash);
  391. CHR ClassHasInstancesInScopeFromClassHash(
  392. LPCWSTR wszInstanceRootDir, LPCWSTR wszClassHash);
  393. CHR UpdateClassCompatible(_IWmiObject* pSuperClass,
  394. LPCWSTR wszClassName, _IWmiObject *pNewClass,
  395. _IWmiObject *pOldClass, __int64 nFakeUpdateTime = 0);
  396. CHR UpdateClassCompatibleHash(_IWmiObject* pSuperClass,
  397. LPCWSTR wszClassHash, _IWmiObject *pClass,
  398. _IWmiObject *pOldClass, __int64 nFakeUpdateTime = 0);
  399. CHR UpdateClassSafeForce(_IWmiObject* pSuperClass, DWORD dwFlags,
  400. LPCWSTR wcsClassName, _IWmiObject *pOldClass,
  401. _IWmiObject *pNewClass, CEventCollector &aEvents);
  402. CHR UpdateClassAggressively(_IWmiObject* pSuperClass, DWORD dwFlags,
  403. LPCWSTR wszClassName, _IWmiObject *pNewClass,
  404. _IWmiObject *pOldClass,
  405. CEventCollector &aEvents);
  406. CHR UpdateChildClassAggressively(DWORD dwFlags, LPCWSTR wszClassHash,
  407. _IWmiObject *pNewClass,
  408. CEventCollector &aEvents);
  409. };
  410. class CDbIterator : public CUnkBase2<IWmiDbIterator, &IID_IWmiDbIterator,
  411. IWbemObjectSink, &IID_IWbemObjectSink>
  412. {
  413. protected:
  414. CCritSec m_cs;
  415. CRefedPointerQueue<IWbemClassObject> m_qObjects;
  416. long m_lCurrentIndex;
  417. void* m_pExecFiber;
  418. CFiberTask* m_pExecReq;
  419. HRESULT m_hresStatus;
  420. void* m_pMainFiber;
  421. DWORD m_dwNumRequested;
  422. HRESULT m_hresCancellationStatus;
  423. bool m_bExecFiberRunning;
  424. bool m_bUseLock;
  425. public:
  426. CDbIterator(CLifeControl* pControl, bool bUseLock);
  427. ~CDbIterator();
  428. STDMETHOD(Cancel) (DWORD dwFlags, void* pFiber);
  429. STDMETHOD(NextBatch)(
  430. DWORD dwNumRequested,
  431. DWORD dwTimeOutSeconds,
  432. DWORD dwFlags,
  433. DWORD dwRequestedHandleType,
  434. REFIID riid,
  435. void* pFiber,
  436. DWORD *pdwNumReturned,
  437. LPVOID *ppObjects
  438. );
  439. void SetExecFiber(void* pFiber, CFiberTask* pReq);
  440. STDMETHOD(Indicate)(long lNumObjects, IWbemClassObject** apObjects);
  441. STDMETHOD(SetStatus)(long lFlags, HRESULT hresResult,
  442. BSTR, IWbemClassObject*);
  443. };
  444. #endif