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.

528 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 CAutoTransaction;
  20. class CDbIterator;
  21. class CRepEvent
  22. {
  23. public:
  24. DWORD m_dwType;
  25. WString m_wszArg1;
  26. WString m_wszNamespace;
  27. _IWmiObject* m_pObj1;
  28. _IWmiObject* m_pObj2;
  29. CRepEvent(DWORD dwType, LPCWSTR wszNamespace, LPCWSTR wszArg1,
  30. _IWmiObject* pObj1, _IWmiObject* pObj2);
  31. virtual ~CRepEvent();
  32. };
  33. class CEventCollector
  34. {
  35. protected:
  36. CUniquePointerArray<CRepEvent> m_apEvents;
  37. bool m_bNamespaceOnly;
  38. CCritSec m_csLock;
  39. public:
  40. CEventCollector() : m_bNamespaceOnly(false){ }
  41. ~CEventCollector() { }
  42. bool AddEvent(CRepEvent* pEvent);
  43. void SetNamespaceOnly(bool bNamespaceOnly)
  44. {m_bNamespaceOnly = bNamespaceOnly;}
  45. bool IsNamespaceOnly() {return m_bNamespaceOnly;}
  46. HRESULT SendEvents(_IWmiCoreServices* pCore);
  47. void DeleteAllEvents();
  48. void TransferEvents(CEventCollector &aEventsToTransfer);
  49. int GetSize() { return m_apEvents.GetSize(); }
  50. };
  51. class CSession : public CUnkBase<IWmiDbSessionEx, &IID_IWmiDbSessionEx>
  52. {
  53. friend CAutoTransaction;
  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 CLocalizationUpgrade;
  160. class CNamespaceHandle : public CUnkBase<IWmiDbHandle, &IID_IWmiDbHandle>
  161. {
  162. friend CLocalizationUpgrade;
  163. protected:
  164. static long s_lActiveRepNs;
  165. CRepository * m_pRepository;
  166. WString m_wsNamespace;
  167. WString m_wsScope;
  168. WString m_wsFullNamespace;
  169. WCHAR m_wszMachineName[MAX_COMPUTERNAME_LENGTH+1];
  170. WCHAR m_wszClassRootDir[MAX_PATH];
  171. long m_lClassRootDirLen;
  172. WCHAR m_wszInstanceRootDir[MAX_PATH];
  173. long m_lInstanceRootDirLen;
  174. CHierarchyCache* m_pClassCache;
  175. _IWmiObject* m_pNullClass;
  176. bool m_bCached;
  177. bool m_bUseIteratorLock;
  178. public:
  179. CNamespaceHandle(CLifeControl* pControl, CRepository * pRepository);
  180. ~CNamespaceHandle();
  181. STDMETHOD(GetHandleType)(DWORD* pdwType) {*pdwType = 0; return S_OK;}
  182. HRESULT Initialize(LPCWSTR wszNamespace, LPCWSTR wszScope = NULL);
  183. HRESULT Initialize2(LPCWSTR wszNamespace, LPCWSTR wszNamespaceHash);
  184. HRESULT GetObject(
  185. IWbemPath *pPath,
  186. DWORD dwFlags,
  187. DWORD dwRequestedHandleType,
  188. IWmiDbHandle **ppResult
  189. );
  190. HRESULT GetObjectDirect(
  191. IWbemPath *pPath,
  192. DWORD dwFlags,
  193. REFIID riid,
  194. LPVOID *pObj
  195. );
  196. HRESULT PutObject(
  197. REFIID riid,
  198. LPVOID pObj,
  199. DWORD dwFlags,
  200. DWORD dwRequestedHandleType,
  201. IWmiDbHandle **ppResult,
  202. CEventCollector &aEvents
  203. );
  204. HRESULT DeleteObject(
  205. DWORD dwFlags,
  206. REFIID riid,
  207. LPVOID pObj,
  208. CEventCollector &aEvents
  209. );
  210. HRESULT ExecQuery(
  211. IWbemQuery *pQuery,
  212. DWORD dwFlags,
  213. DWORD dwRequestedHandleType,
  214. DWORD *dwMessageFlags,
  215. IWmiDbIterator **ppQueryResult
  216. );
  217. HRESULT GetObjectByPath(
  218. LPWSTR wszPath,
  219. DWORD dwFlags,
  220. REFIID riid,
  221. LPVOID *pObj
  222. );
  223. HRESULT ExecQuerySink(
  224. IWbemQuery *pQuery,
  225. DWORD dwFlags,
  226. DWORD dwRequestedHandleType,
  227. IWbemObjectSink* pSink,
  228. DWORD *dwMessageFlags
  229. );
  230. HRESULT DeleteObjectByPath(DWORD dwFlags, LPWSTR wszPath, CEventCollector &aEvents);
  231. HRESULT GetErrorStatus();
  232. void SetErrorStatus(HRESULT hres);
  233. HRESULT CreateSystemClasses(CFlexArray &aSystemClasses);
  234. void TellIteratorNotToLock() { m_bUseIteratorLock = false; }
  235. protected:
  236. HRESULT GetObjectHandleByPath(LPWSTR wszBuffer, DWORD dwFlags,
  237. DWORD dwRequestedHandleType, IWmiDbHandle **ppResult);
  238. HRESULT PutInstance(_IWmiObject* pInst, DWORD dwFlags, CEventCollector &aEvents);
  239. HRESULT PutClass(_IWmiObject* pClass, DWORD dwFlags, CEventCollector &aEvents);
  240. HRESULT ConstructClassRelationshipsDir(LPCWSTR wszClassName,
  241. CFileName& wszDirPath);
  242. HRESULT WriteParentChildRelationship(LPCWSTR wszChildFileName,
  243. LPCWSTR wszParentName);
  244. HRESULT ExecClassQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  245. IWbemObjectSink* pSink, DWORD dwFlags);
  246. HRESULT ExecInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  247. LPCWSTR wszClassName, bool bDeep,
  248. IWbemObjectSink* pSink);
  249. HRESULT GetClassDirect(LPCWSTR wszClassName, REFIID riid, void** ppObj,
  250. bool bClone, __int64* pnTime,
  251. bool* pbRead, bool *pbSystemClass);
  252. HRESULT DeleteInstance(LPCWSTR wszClassName, LPCWSTR wszKey, CEventCollector &aEvents);
  253. HRESULT DeleteInstanceByFile(LPCWSTR wszFilePath, _IWmiObject* pClass,
  254. bool bClassDeletion, CEventCollector &aEvents);
  255. HRESULT DeleteClass(LPCWSTR wszClassName, CEventCollector &aEvents,bool bDisableEvents);
  256. HRESULT DeleteClassInstances(LPCWSTR wszClassName, _IWmiObject* pClass, CEventCollector &aEvents);
  257. HRESULT FileToSystemClass(LPCWSTR wszFileName, _IWmiObject** ppClass,
  258. bool bClone, __int64* pnTime = NULL);
  259. HRESULT FileToClass(LPCWSTR wszFileName, _IWmiObject** ppClass,
  260. bool bClone, __int64* pnTime,
  261. bool *pbSystemClass);
  262. HRESULT FileToInstance(_IWmiObject* pClass,
  263. LPCWSTR wszFileName,
  264. BYTE *pRetrievedBlob,
  265. DWORD dwSize,
  266. _IWmiObject** ppInstance,
  267. bool bMustBeThere = false);
  268. HRESULT WriteInstanceReferences(_IWmiObject* pInst, LPCWSTR wszClassName,
  269. LPCWSTR wszFilePath);
  270. HRESULT WriteInstanceReference(LPCWSTR wszReferringFile,
  271. LPCWSTR wszReferringClass,
  272. LPCWSTR wszReferringProp, LPWSTR wszReference);
  273. HRESULT ExecClassRefQuery(LPCWSTR wszQuery, LPCWSTR wszClassName,
  274. IWbemObjectSink* pSink);
  275. HRESULT ExecReferencesQuery(LPCWSTR wszQuery, IWbemObjectSink* pSink);
  276. HRESULT ExecInstanceRefQuery(LPCWSTR wszQuery, LPCWSTR wszClassName,
  277. LPCWSTR wszKey, IWbemObjectSink* pSink);
  278. HRESULT GetReferrerFromFile(LPCWSTR wszReferenceFile,
  279. LPWSTR wszReferrerRelFile,
  280. LPWSTR* pwszReferrerNamespace,
  281. LPWSTR* pwszReferrerClass,
  282. LPWSTR* pwszReferrerProp);
  283. HRESULT DeleteInstanceReference(LPCWSTR wszOurFilePath,
  284. LPWSTR wszReference);
  285. HRESULT DeleteInstanceReferences(_IWmiObject* pInst, LPCWSTR wszFilePath);
  286. HRESULT EnumerateClasses(IWbemObjectSink* pSink,
  287. LPCWSTR wszSuperClass, LPCWSTR wszAncestor,
  288. bool bClone, bool bDontIncludeAncestorInResultSet);
  289. HRESULT ListToEnum(CWStringArray& wsClasses,
  290. IWbemObjectSink* pSink, bool bClone);
  291. bool Hash(LPCWSTR wszName, LPWSTR wszHash);
  292. HRESULT InstanceToFile(IWbemClassObject* pInst, LPCWSTR wszClassName,
  293. LPCWSTR wszFileName1, LPCWSTR wszFileName2,
  294. __int64 nClassTime);
  295. HRESULT ConstructInstanceDefName(CFileName& wszInstanceDefName, LPCWSTR wszKey);
  296. HRESULT ClassToFile(_IWmiObject* pSuperClass, _IWmiObject* pClass,
  297. LPCWSTR wszFileName, __int64 nFakeUpdateTime = 0);
  298. HRESULT ComputeKeyFromPath(LPWSTR wszPath, LPWSTR wszKey, size_t dwKeyLen,
  299. LPWSTR* pwszClassName, bool* pbIsClass,
  300. LPWSTR* pwszNamespace = NULL);
  301. HRESULT ParseKey(LPWSTR wszKeyStart, LPWSTR* pwcRealStart,
  302. LPWSTR* pwcNextKey);
  303. HRESULT GetInstanceByKey(LPCWSTR wszClassName, LPCWSTR wszKey,
  304. REFIID riid, void** ppObj);
  305. HRESULT WriteClassRelationships(_IWmiObject* pClass, LPCWSTR wszFileName);
  306. HRESULT ConstructParentChildFileName(LPCWSTR wszChildFileName,
  307. LPCWSTR wszParentName,
  308. CFileName& wszParentChildFileName);
  309. HRESULT DeleteDerivedClasses(LPCWSTR wszClassName, CEventCollector &aEvents, bool bDisableEvents);
  310. HRESULT EraseParentChildRelationship(LPCWSTR wszChildFileName,
  311. LPCWSTR wszParentName);
  312. HRESULT EraseClassRelationships(LPCWSTR wszClassName,
  313. _IWmiObject* pClass, LPCWSTR wszFileName);
  314. HRESULT GetClassByHash(LPCWSTR wszHash, bool bClone, _IWmiObject** ppClass,
  315. __int64* pnTime, bool* pbRead,
  316. bool *pbSystemClass);
  317. HRESULT DeleteClassByHash(LPCWSTR wszHash, CEventCollector &aEvents,bool bDisableEvents);
  318. HRESULT DeleteClassInternal(LPCWSTR wszClassName,
  319. _IWmiObject* pClass,
  320. LPCWSTR wszFileName,
  321. CEventCollector &aEvents,
  322. bool bSystemClass,
  323. bool bDisableEvents);
  324. HRESULT GetChildHashes(LPCWSTR wszClassName, CWStringArray& wsChildHashes);
  325. HRESULT GetChildDefs(LPCWSTR wszClassName, bool bRecursive,
  326. IWbemObjectSink* pSink, bool bClone);
  327. HRESULT ConstructClassDefFileName(LPCWSTR wszClassName, CFileName& wszFileName);
  328. HRESULT ConstructClassDefFileNameFromHash(LPCWSTR wszHash,
  329. CFileName& wszFileName);
  330. HRESULT ConstructClassRelationshipsDirFromHash(LPCWSTR wszHash,
  331. CFileName& wszDirPath);
  332. HRESULT GetChildHashesByHash(LPCWSTR wszHash, CWStringArray& wsChildHashes);
  333. HRESULT GetChildDefsByHash(LPCWSTR wszHash, bool bRecursive,
  334. IWbemObjectSink* pSink, bool bClone);
  335. HRESULT FireEvent(CEventCollector &aEvents, DWORD dwType, LPCWSTR wszArg1, _IWmiObject* pObj1,
  336. _IWmiObject* pObj2 = NULL);
  337. HRESULT DeleteInstanceAsScope(_IWmiObject* pInst, CEventCollector &aEvents);
  338. HRESULT EnumerateChildNamespaces(LPCWSTR wsRootNamespace,
  339. CWStringArray &aNamespaces,
  340. CEventCollector &aEvents);
  341. HRESULT DeleteInstanceSelf(LPCWSTR wszFilePath, _IWmiObject* pInst,
  342. bool bClassDeletion);
  343. HRESULT ConstructReferenceDir(LPWSTR wszTargetPath, CFileName& wszDir);
  344. HRESULT ConstructReferenceDirFromKey(LPCWSTR wszClassName,
  345. LPCWSTR wszKey, CFileName& wszReferenceDir);
  346. HRESULT ConstructReferenceFileName(LPWSTR wszReference,
  347. LPCWSTR wszReferringFile, CFileName& wszReferenceFile);
  348. HRESULT ConstructKeyRootDirFromClass(CFileName& wszDir, LPCWSTR wszClassName);
  349. HRESULT ConstructKeyRootDirFromKeyRoot(CFileName& wszDir,
  350. LPCWSTR wszKeyRootClass);
  351. HRESULT ConstructLinkDirFromClass(CFileName& wszDir, LPCWSTR wszClassName);
  352. HRESULT DeleteInstanceLink(_IWmiObject* pInst,
  353. LPCWSTR wszInstanceDefFilePath);
  354. HRESULT GetKeyRoot(LPCWSTR wszClass,
  355. TEMPFREE_ME LPWSTR* pwszKeyRootClass);
  356. HRESULT ConstructInstDefNameFromLinkName(CFileName& wszInstanceDefName,
  357. LPCWSTR wszInstanceLinkName);
  358. HRESULT ExecDeepInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  359. LPCWSTR wszClassHash,
  360. IWbemObjectSink* pSink);
  361. HRESULT ExecShallowInstanceQuery(QL_LEVEL_1_RPN_EXPRESSION* pQuery,
  362. LPCWSTR wszClassHash,
  363. IWbemObjectSink* pSink);
  364. HRESULT ConstructLinkDirFromClassHash(CFileName& wszDir, LPCWSTR wszClassHash);
  365. HRESULT ConstructClassReferenceFileName(LPCWSTR wszReferredToClass,
  366. LPCWSTR wszReferringFile,
  367. LPCWSTR wszReferringProp,
  368. CFileName& wszFieName);
  369. HRESULT WriteClassReference(_IWmiObject* pReferringClass,
  370. LPCWSTR wszReferringFile,
  371. LPCWSTR wszReferringProp);
  372. HRESULT EraseClassReference(_IWmiObject* pReferringClass,
  373. LPCWSTR wszReferringFile,
  374. LPCWSTR wszReferringProp);
  375. //CFileCache* GetFileCache();
  376. HRESULT CanClassBeUpdatedCompatible(DWORD dwFlags, LPCWSTR wszClassName,
  377. _IWmiObject *pOldClass, _IWmiObject *pNewClass);
  378. HRESULT DeleteInstanceBackReferences(LPCWSTR wszFilePath);
  379. HRESULT ConstructReferenceDirFromFilePath(LPCWSTR wszFilePath,
  380. CFileName& wszReferenceDir);
  381. HRESULT ClassHasChildren(LPCWSTR wszClassName);
  382. HRESULT ClassHasInstances(LPCWSTR wszClassName);
  383. HRESULT ClassHasInstancesFromClassHash(LPCWSTR wszClassHash);
  384. HRESULT ClassHasInstancesInScopeFromClassHash(
  385. LPCWSTR wszInstanceRootDir, LPCWSTR wszClassHash);
  386. HRESULT UpdateClassCompatible(_IWmiObject* pSuperClass,
  387. LPCWSTR wszClassName, _IWmiObject *pNewClass,
  388. _IWmiObject *pOldClass, __int64 nFakeUpdateTime = 0);
  389. HRESULT UpdateClassCompatibleHash(_IWmiObject* pSuperClass,
  390. LPCWSTR wszClassHash, _IWmiObject *pClass,
  391. _IWmiObject *pOldClass, __int64 nFakeUpdateTime = 0);
  392. HRESULT UpdateClassSafeForce(_IWmiObject* pSuperClass, DWORD dwFlags,
  393. LPCWSTR wcsClassName, _IWmiObject *pOldClass,
  394. _IWmiObject *pNewClass, CEventCollector &aEvents);
  395. HRESULT UpdateClassAggressively(_IWmiObject* pSuperClass, DWORD dwFlags,
  396. LPCWSTR wszClassName, _IWmiObject *pNewClass,
  397. _IWmiObject *pOldClass,
  398. CEventCollector &aEvents);
  399. HRESULT UpdateChildClassAggressively(DWORD dwFlags, LPCWSTR wszClassHash,
  400. _IWmiObject *pNewClass,
  401. CEventCollector &aEvents);
  402. };
  403. class CDbIterator : public CUnkBase2<IWmiDbIterator, &IID_IWmiDbIterator,
  404. IWbemObjectSink, &IID_IWbemObjectSink>
  405. {
  406. protected:
  407. CCritSec m_cs;
  408. CRefedPointerQueue<IWbemClassObject> m_qObjects;
  409. long m_lCurrentIndex;
  410. void* m_pExecFiber;
  411. CFiberTask* m_pExecReq;
  412. HRESULT m_hresStatus;
  413. void* m_pMainFiber;
  414. DWORD m_dwNumRequested;
  415. HRESULT m_hresCancellationStatus;
  416. bool m_bExecFiberRunning;
  417. bool m_bUseLock;
  418. public:
  419. CDbIterator(CLifeControl* pControl, bool bUseLock);
  420. ~CDbIterator();
  421. STDMETHOD(Cancel) (DWORD dwFlags, void* pFiber);
  422. STDMETHOD(NextBatch)(
  423. DWORD dwNumRequested,
  424. DWORD dwTimeOutSeconds,
  425. DWORD dwFlags,
  426. DWORD dwRequestedHandleType,
  427. REFIID riid,
  428. void* pFiber,
  429. DWORD *pdwNumReturned,
  430. LPVOID *ppObjects
  431. );
  432. void SetExecFiber(void* pFiber, CFiberTask* pReq);
  433. STDMETHOD(Indicate)(long lNumObjects, IWbemClassObject** apObjects);
  434. STDMETHOD(SetStatus)(long lFlags, HRESULT hresResult,
  435. BSTR, IWbemClassObject*);
  436. };
  437. //
  438. // implements swprintf(pDest,L"%s\\%s",Src1,pSrc2)
  439. //
  440. ///////////////////////////////////////////////////////////////////
  441. void inline Cat2Str(WCHAR * pDest, WCHAR * pSrc1, LPCWSTR pSrc2)
  442. {
  443. while(*pSrc1)
  444. *pDest++ = *pSrc1++;
  445. *pDest++ = L'\\';
  446. while(*pSrc2)
  447. *pDest++ = *pSrc2++;
  448. *pDest = 0;
  449. }
  450. #endif