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.

716 lines
18 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. A51Exp.cpp
  5. Abstract:
  6. Exports the repository into a interchange format that can easily be re-imported.
  7. Database has to be opened and available to us at the point we are called, and we
  8. enumerate recursively writing all classes and instances to the interchange
  9. file.
  10. The import may well have to deal with changing system classes, and so all old
  11. system classes have to be written to the file format.
  12. The format of the interchange file is as follows:
  13. File Header Block:
  14. BYTE wszFileHeader[8] = A51_EXPORT_FILE_START_TAG ("a51exp1")
  15. Namespace Block:
  16. DWORD dwObjectType = A51_EXPORT_NAMESPACE_TAG (0x00000001)
  17. DWORD dwNamespaceNameSize
  18. BYTE wszNamespaceName[dwNamespaceNameSize] = Full namespace name
  19. (\root\default\fred)
  20. Class Block:
  21. DWORD dwObjectType = A51_EXPORT_CLASS_TAG (0x00000002)
  22. DWORD dwClassNameSize
  23. BYTE wszClassName[dwClassNameSize] = Class name (my_class_name)
  24. DWORD dwClassObjectSize
  25. BYTE adwClassObject[dwClassObjectSize]
  26. Instance Block - key of type string
  27. DWORD dwObjectType = A51_EXPORT_INST_TAG (0x00000003)
  28. DWORD dwInstanceKeySize
  29. BYTE dwInstanceKey[dwInstanceKeySize] = Instance key (MyKeyValue)
  30. DWORD dwInstanceObjectSize
  31. BYTE adwInstanceObject[dwInstanceObjectSize]
  32. End of class block
  33. DWORD dwObjectType = A51_EXPORT_CLASS_END_TAG (0x00000005)
  34. End of namespace block
  35. DWORD dwObjectType = A51_EXPORT_NAMESPACE_END_TAG (0x00000006)
  36. End of file block
  37. DWORD dwObjectType = A51_EXPORT_FILE_END_TAG (0xFFFFFFFF)
  38. Ordering:
  39. File Header Block
  40. (one or more)
  41. Namespace Block
  42. (zero or more)
  43. {
  44. Namespace Block
  45. etc...
  46. End namespace block
  47. (or)
  48. Class Block
  49. (zero or more)
  50. {
  51. Instance Block
  52. (or)
  53. Class Block
  54. etc...
  55. End class block
  56. }
  57. End class block
  58. }
  59. End namespace block
  60. End of file block
  61. History:
  62. 08-Dec-2000 paulall Created.
  63. --*/
  64. #include <windows.h>
  65. #include <ql.h>
  66. #include "A51Rep.h"
  67. #include "A51Exp.h"
  68. /*=============================================================================
  69. *
  70. * A51Export::A51Export
  71. *
  72. *=============================================================================
  73. */
  74. A51Export::A51Export(CLifeControl* pControl)
  75. : m_hFile(INVALID_HANDLE_VALUE), m_pControl(pControl)
  76. {
  77. }
  78. /*=============================================================================
  79. *
  80. * A51Export::~A51Export
  81. *
  82. *=============================================================================
  83. */
  84. A51Export::~A51Export()
  85. {
  86. }
  87. /*=============================================================================
  88. *
  89. * A51Export::Export
  90. *
  91. *=============================================================================
  92. */
  93. HRESULT A51Export::Export(const wchar_t *wszFilename, DWORD dwFlags, CRepository *pRepository)
  94. {
  95. HRESULT hRes = WBEM_S_NO_ERROR;
  96. m_pRepository = pRepository;
  97. m_hFile = CreateFileW(wszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  98. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  99. NULL);
  100. if (m_hFile == INVALID_HANDLE_VALUE)
  101. hRes = WBEM_E_FAILED;
  102. try
  103. {
  104. if (SUCCEEDED(hRes))
  105. hRes = ExportHeader();
  106. if (SUCCEEDED(hRes))
  107. hRes = ExportNamespace(L"root");
  108. if (SUCCEEDED(hRes))
  109. hRes = WriteObjectType(A51_EXPORT_FILE_END_TAG);
  110. }
  111. catch (...)
  112. {
  113. hRes = WBEM_E_CRITICAL_ERROR;
  114. }
  115. if (m_hFile)
  116. {
  117. CloseHandle(m_hFile);
  118. m_hFile = INVALID_HANDLE_VALUE;
  119. }
  120. m_hFile = INVALID_HANDLE_VALUE;
  121. return hRes;
  122. }
  123. /*=============================================================================
  124. *
  125. * A51Export::ExportHeader
  126. *
  127. * File Header Block:
  128. * BYTE wszFileHeader[8] = A51_EXPORT_FILE_START_TAG ("a51exp1")
  129. *
  130. *=============================================================================
  131. */
  132. HRESULT A51Export::ExportHeader()
  133. {
  134. HRESULT hRes = WBEM_S_NO_ERROR;
  135. char *pszHeader = A51_EXPORT_FILE_START_TAG;
  136. DWORD dwSize = sizeof(A51_EXPORT_FILE_START_TAG);
  137. if ((!WriteFile(m_hFile, pszHeader, dwSize, &dwSize, NULL)) || (dwSize != sizeof(A51_EXPORT_FILE_START_TAG)))
  138. hRes = WBEM_E_FAILED;
  139. return hRes;
  140. }
  141. /*=============================================================================
  142. *
  143. * A51Export::ExportNamespace
  144. *
  145. * Namespace Block:
  146. * DWORD dwObjectType = A51_EXPORT_NAMESPACE_TAG (0x00000001)
  147. * DWORD dwNamespaceNameSize
  148. * BYTE wszNamespaceName[dwNamespaceNameSize] = Full namespace name
  149. *
  150. * [classes]
  151. * [child namespaces]
  152. *
  153. * End of namespace block
  154. * DWORD dwObjectType = A51_EXPORT_NAMESPACE_END_TAG (0x00000006)
  155. *
  156. *=============================================================================
  157. */
  158. HRESULT A51Export::ExportNamespace(const wchar_t *wszNamespace)
  159. {
  160. DEBUGTRACE((LOG_WBEMCORE, "Namespace export for namespace <%S>\n", wszNamespace));
  161. HRESULT hRes = WBEM_S_NO_ERROR;
  162. DWORD dwSize = 0;
  163. // First, we need to write the namespace header
  164. //--------------------------------------------
  165. hRes = WriteObjectType(A51_EXPORT_NAMESPACE_TAG);
  166. if (SUCCEEDED(hRes))
  167. {
  168. DWORD dwNamespaceNameSize = (lstrlenW(wszNamespace) + 1) * sizeof(wchar_t);
  169. hRes = WriteBufferWithLength(dwNamespaceNameSize, (void*)wszNamespace);
  170. }
  171. //Second, we need to attach to the namespace so we can process it
  172. //---------------------------------------------------------------
  173. CNamespaceHandle *pNs = NULL;
  174. if (SUCCEEDED(hRes))
  175. pNs = new CNamespaceHandle(m_pControl, m_pRepository);
  176. CReleaseMe rm1(pNs);
  177. if (pNs == NULL)
  178. hRes = WBEM_E_OUT_OF_MEMORY;
  179. if (SUCCEEDED(hRes))
  180. {
  181. pNs->AddRef();
  182. hRes = pNs->Initialize(wszNamespace);
  183. }
  184. //Third, we need to enumerate all the base classes and process them
  185. //-----------------------------------------------------------------
  186. if (SUCCEEDED(hRes))
  187. hRes = ExportClass(pNs, L"", NULL);
  188. //Fourth, we need to enumerate all the child namespaces and process them
  189. //--------------------------------------------------------------------
  190. if (SUCCEEDED(hRes))
  191. hRes = ExportChildNamespaces(pNs, wszNamespace);
  192. //Finally, we need to write the namespace terminator tag for this namespace
  193. //-------------------------------------------------------------------------
  194. if (SUCCEEDED(hRes))
  195. {
  196. hRes = WriteObjectType(A51_EXPORT_NAMESPACE_END_TAG);
  197. }
  198. if (FAILED(hRes))
  199. {
  200. ERRORTRACE((LOG_WBEMCORE, "Namespace export failed for namespace <%S>, error <0x%X>\n", wszNamespace, hRes));
  201. }
  202. return hRes;
  203. }
  204. /*=============================================================================
  205. *
  206. * A51Export::ExportClass
  207. *
  208. * Class Block:
  209. * DWORD dwObjectType = A51_EXPORT_CLASS_TAG (0x00000002)
  210. * DWORD dwClassNameSize
  211. * BYTE wszClassName[dwClassNameSize] = Class name (my_class_name)
  212. * DWORD dwClassObjectSize
  213. * BYTE adwClassObject[dwClassObjectSize]
  214. *
  215. * [instances of this class]
  216. * [child classes of this class]
  217. *
  218. * End of class block
  219. * DWORD dwObjectType = A51_EXPORT_CLASS_END_TAG (0x00000005)
  220. *
  221. *=============================================================================
  222. */
  223. HRESULT A51Export::ExportClass(CNamespaceHandle *pNs, const wchar_t *wszClass, _IWmiObject *pClass)
  224. {
  225. DEBUGTRACE((LOG_WBEMCORE, "Class export for class <%S>\n", wszClass));
  226. HRESULT hRes = WBEM_S_NO_ERROR;
  227. if (pClass)
  228. {
  229. //Write this class to the file
  230. //----------------------------
  231. //Write tag header
  232. hRes = WriteObjectType(A51_EXPORT_CLASS_TAG);
  233. //Write class name length
  234. if (SUCCEEDED(hRes))
  235. {
  236. DWORD dwClassNameSize = (lstrlenW(wszClass) + 1) * sizeof(wchar_t);
  237. hRes = WriteBufferWithLength(dwClassNameSize, (void*)wszClass);
  238. }
  239. //Write the class object
  240. if (SUCCEEDED(hRes))
  241. {
  242. hRes = WriteObjectBlob(pClass);
  243. }
  244. //Enumerate all instances of this class and write them
  245. //----------------------------------------------------
  246. if (SUCCEEDED(hRes))
  247. {
  248. hRes = ExportClassInstances(pNs, wszClass);
  249. }
  250. }
  251. //Enumerate all child classes of this class and write them
  252. //--------------------------------------------------------
  253. if (SUCCEEDED(hRes))
  254. {
  255. hRes = ExportChildClasses(pNs, wszClass);
  256. }
  257. if (pClass && SUCCEEDED(hRes))
  258. {
  259. //Write the class trailer object
  260. //------------------------------
  261. hRes = WriteObjectType(A51_EXPORT_CLASS_END_TAG);
  262. }
  263. if (FAILED(hRes))
  264. {
  265. ERRORTRACE((LOG_WBEMCORE, "Class export failed for class <%S>, error <0x%X>\n", wszClass, hRes));
  266. }
  267. return hRes;
  268. }
  269. /*=============================================================================
  270. *
  271. * A51Export::ExportInstance
  272. *
  273. * Instance Block - key of type string
  274. * DWORD dwObjectType = A51_EXPORT_INST_TAG (0x00000003)
  275. * DWORD dwInstanceKeySize
  276. * BYTE dwInstanceKey[dwInstanceKeySize] = Instance key (MyKeyValue)
  277. * DWORD dwInstanceObjectSize
  278. * BYTE adwInstanceObject[dwInstanceObjectSize]
  279. *=============================================================================
  280. */
  281. HRESULT A51Export::ExportInstance(_IWmiObject *pInstance)
  282. {
  283. HRESULT hRes;
  284. //Get the key
  285. BSTR bstrKeyString = NULL;
  286. hRes = pInstance->GetKeyString(0, &bstrKeyString);
  287. CSysFreeMe sfm1(bstrKeyString);
  288. if (SUCCEEDED(hRes))
  289. {
  290. DEBUGTRACE((LOG_WBEMCORE, "Instance export for key<%S>\n", bstrKeyString));
  291. }
  292. //Write tag header
  293. if (SUCCEEDED(hRes))
  294. {
  295. hRes = WriteObjectType(A51_EXPORT_INST_TAG);
  296. }
  297. //Write key and length
  298. if (SUCCEEDED(hRes))
  299. {
  300. DWORD dwInstanceKeySize = (lstrlenW(bstrKeyString) + 1) * sizeof(wchar_t);
  301. hRes = WriteBufferWithLength(dwInstanceKeySize, bstrKeyString);
  302. }
  303. //Write the instance object
  304. if (SUCCEEDED(hRes))
  305. {
  306. hRes = WriteObjectBlob(pInstance);
  307. }
  308. if (FAILED(hRes))
  309. {
  310. ERRORTRACE((LOG_WBEMCORE, "Instance export fail for instance <%S>, error <0x%X>\n", bstrKeyString, hRes));
  311. }
  312. return hRes;
  313. }
  314. /*=============================================================================
  315. *
  316. * A51Export::ExportChildNamespaces
  317. *
  318. *=============================================================================
  319. */
  320. HRESULT A51Export::ExportChildNamespaces(CNamespaceHandle *pNs, const wchar_t *wszNamespace)
  321. {
  322. DEBUGTRACE((LOG_WBEMCORE, "Child namespace export for namespace <%S>\n", wszNamespace));
  323. HRESULT hRes = 0;
  324. IWbemQuery *pQuery = NULL;
  325. IWmiDbIterator *pIterator = NULL;
  326. hRes = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery);
  327. CReleaseMe rm1(pQuery);
  328. //Do the query
  329. try
  330. {
  331. if (SUCCEEDED(hRes))
  332. {
  333. hRes = pQuery->Parse(L"SQL", L"select * from __namespace", 0);
  334. }
  335. if (SUCCEEDED(hRes))
  336. hRes = pNs->ExecQuery(pQuery, WBEM_FLAG_DEEP, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIterator);
  337. }
  338. catch(...)
  339. {
  340. hRes = WBEM_E_CRITICAL_ERROR;
  341. }
  342. CReleaseMe rm2(pIterator);
  343. //Iterate through the results and process each namespace
  344. REFIID riid = IID__IWmiObject;
  345. DWORD dwObjects = 0;
  346. while (SUCCEEDED(hRes))
  347. {
  348. _IWmiObject *pInst = 0;
  349. DWORD dwReturned = 0;
  350. hRes = pIterator->NextBatch(1, 5, 0, WMIDB_HANDLE_TYPE_COOKIE, riid, &dwReturned, (LPVOID *) &pInst);
  351. CReleaseMe rm3(pInst);
  352. //TODO: HACK: Find out why this is happening!!!!
  353. if (hRes == WBEM_E_NOT_FOUND)
  354. {
  355. hRes = WBEM_S_NO_ERROR;
  356. break;
  357. }
  358. if (dwReturned == 0 || pInst == 0 || FAILED(hRes))
  359. break;
  360. BSTR bstrKeyString = NULL;
  361. hRes = pInst->GetKeyString(0, &bstrKeyString);
  362. CSysFreeMe sfm1(bstrKeyString);
  363. wchar_t *wszFullNamespace = new wchar_t[lstrlenW(wszNamespace) + lstrlenW(bstrKeyString) + lstrlenW(L"\\") + 1];
  364. CVectorDeleteMe<wchar_t> vdm2(wszFullNamespace);
  365. if (wszFullNamespace == NULL)
  366. {
  367. hRes = WBEM_E_OUT_OF_MEMORY;
  368. break;
  369. }
  370. lstrcpyW(wszFullNamespace, wszNamespace);
  371. lstrcatW(wszFullNamespace, L"\\");
  372. lstrcatW(wszFullNamespace, bstrKeyString);
  373. hRes = ExportNamespace(wszFullNamespace);
  374. }
  375. if (SUCCEEDED(hRes))
  376. hRes = WBEM_S_NO_ERROR;
  377. if (FAILED(hRes))
  378. {
  379. ERRORTRACE((LOG_WBEMCORE, "Child namespaces export failed for namespace <%S>, error <0x%X>\n", wszNamespace, hRes));
  380. }
  381. return hRes;
  382. }
  383. /*=============================================================================
  384. *
  385. * A51Export::ExportChildClasses
  386. *
  387. *=============================================================================
  388. */
  389. HRESULT A51Export::ExportChildClasses(CNamespaceHandle *pNs, const wchar_t *wszClassName)
  390. {
  391. DEBUGTRACE((LOG_WBEMCORE, "Child classes export for class <%S>\n", wszClassName));
  392. HRESULT hRes = 0;
  393. IWbemQuery *pQuery = NULL;
  394. IWmiDbIterator *pIterator = NULL;
  395. //Build up the instance query
  396. wchar_t *wszQuery = new wchar_t[lstrlenW(wszClassName) + lstrlenW(L"select * from meta_class where __SUPERCLASS = \"\"") + 1];
  397. if (wszQuery == NULL)
  398. hRes = WBEM_E_OUT_OF_MEMORY;
  399. CVectorDeleteMe<wchar_t> vdm1(wszQuery);
  400. if (SUCCEEDED(hRes))
  401. {
  402. lstrcpyW(wszQuery, L"select * from meta_class where __SUPERCLASS = \"");
  403. lstrcatW(wszQuery, wszClassName);
  404. lstrcatW(wszQuery, L"\"");
  405. }
  406. if (SUCCEEDED(hRes))
  407. hRes = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery);
  408. CReleaseMe rm1(pQuery);
  409. try
  410. {
  411. if (SUCCEEDED(hRes))
  412. {
  413. hRes = pQuery->Parse(L"SQL", wszQuery, 0);
  414. }
  415. if (SUCCEEDED(hRes))
  416. hRes = pNs->ExecQuery(pQuery, 0, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIterator);
  417. }
  418. catch(...)
  419. {
  420. hRes = WBEM_E_CRITICAL_ERROR;
  421. }
  422. CReleaseMe rm2(pIterator);
  423. // If here, there are results, I guess.
  424. // ====================================
  425. REFIID riid = IID__IWmiObject;
  426. DWORD dwObjects = 0;
  427. while (SUCCEEDED(hRes))
  428. {
  429. _IWmiObject *pClass = 0;
  430. DWORD dwReturned = 0;
  431. hRes = pIterator->NextBatch(1, 5, 0, WMIDB_HANDLE_TYPE_COOKIE, riid, &dwReturned, (LPVOID *) &pClass);
  432. CReleaseMe rm3(pClass);
  433. //TODO: HACK: Find out why this is happening!!!!
  434. if (hRes == WBEM_E_NOT_FOUND)
  435. {
  436. hRes = WBEM_S_NO_ERROR;
  437. break;
  438. }
  439. if (dwReturned == 0 || pClass == 0 || FAILED(hRes))
  440. break;
  441. VARIANT var;
  442. VariantInit(&var);
  443. hRes = pClass->Get(L"__class", 0, &var, NULL, NULL);
  444. if (SUCCEEDED(hRes))
  445. hRes = ExportClass(pNs, V_BSTR(&var), pClass);
  446. VariantClear(&var);
  447. }
  448. if (SUCCEEDED(hRes))
  449. hRes = WBEM_S_NO_ERROR;
  450. if (FAILED(hRes))
  451. {
  452. ERRORTRACE((LOG_WBEMCORE, "Child classes export failed for class <%S>, error <0x%X>\n", wszClassName, hRes));
  453. }
  454. return hRes;
  455. }
  456. /*=============================================================================
  457. *
  458. * A51Export::ExportClassInstances
  459. *
  460. *=============================================================================
  461. */
  462. HRESULT A51Export::ExportClassInstances(CNamespaceHandle *pNs, const wchar_t *wszClassName)
  463. {
  464. DEBUGTRACE((LOG_WBEMCORE, "Class instances export for class <%S>\n", wszClassName));
  465. HRESULT hRes = 0;
  466. IWbemQuery *pQuery = NULL;
  467. IWmiDbIterator *pIterator = NULL;
  468. //Build up the instance query
  469. wchar_t *wszQuery = new wchar_t[lstrlenW(wszClassName) + lstrlenW(L"select * from ") + 1];
  470. if (wszQuery == NULL)
  471. hRes = WBEM_E_OUT_OF_MEMORY;
  472. CVectorDeleteMe<wchar_t> vdm1(wszQuery);
  473. if (SUCCEEDED(hRes))
  474. {
  475. lstrcpyW(wszQuery, L"select * from ");
  476. lstrcatW(wszQuery, wszClassName);
  477. }
  478. if (SUCCEEDED(hRes))
  479. hRes = CoCreateInstance(CLSID_WbemQuery, NULL, CLSCTX_INPROC_SERVER, IID_IWbemQuery, (void **)&pQuery);
  480. CReleaseMe rm1(pQuery);
  481. try
  482. {
  483. if (SUCCEEDED(hRes))
  484. {
  485. hRes = pQuery->Parse(L"SQL", wszQuery, 0);
  486. }
  487. if (SUCCEEDED(hRes))
  488. hRes = pNs->ExecQuery(pQuery, WBEM_FLAG_SHALLOW, WMIDB_HANDLE_TYPE_COOKIE, NULL, &pIterator);
  489. }
  490. catch(...)
  491. {
  492. hRes = WBEM_E_CRITICAL_ERROR;
  493. }
  494. CReleaseMe rm2(pIterator);
  495. // If here, there are results, I guess.
  496. // ====================================
  497. REFIID riid = IID__IWmiObject;
  498. DWORD dwObjects = 0;
  499. while (SUCCEEDED(hRes))
  500. {
  501. _IWmiObject *pInst = 0;
  502. DWORD dwReturned = 0;
  503. hRes = pIterator->NextBatch(1, 5, 0, WMIDB_HANDLE_TYPE_COOKIE, riid, &dwReturned, (LPVOID *) &pInst);
  504. CReleaseMe rm3(pInst);
  505. //TODO: HACK: Find out why this is happening!!!!
  506. if (hRes == WBEM_E_NOT_FOUND)
  507. {
  508. hRes = WBEM_S_NO_ERROR;
  509. break;
  510. }
  511. if (dwReturned == 0 || pInst == 0 || FAILED(hRes))
  512. break;
  513. hRes = ExportInstance(pInst);
  514. }
  515. if (SUCCEEDED(hRes))
  516. hRes = WBEM_S_NO_ERROR;
  517. if (FAILED(hRes))
  518. {
  519. ERRORTRACE((LOG_WBEMCORE, "Child class instances export failed for class <%S>, error <0x%X>\n", wszClassName, hRes));
  520. }
  521. return hRes;
  522. }
  523. /*=============================================================================
  524. *
  525. * A51Export::WriteBufferWithLength
  526. *
  527. *=============================================================================
  528. */
  529. HRESULT A51Export::WriteBufferWithLength(DWORD dwBufferSize, void *pBuffer)
  530. {
  531. HRESULT hRes = WBEM_S_NO_ERROR;
  532. DWORD dwSize;
  533. //Write buffer length
  534. if (!WriteFile(m_hFile, &dwBufferSize, sizeof(DWORD), &dwSize, NULL) || (dwSize != sizeof(DWORD)))
  535. {
  536. hRes = WBEM_E_FAILED;
  537. }
  538. //Write buffer
  539. if (SUCCEEDED(hRes) &&
  540. (!WriteFile(m_hFile, pBuffer, dwBufferSize, &dwSize, NULL) || (dwBufferSize != dwSize)))
  541. {
  542. hRes = WBEM_E_FAILED;
  543. }
  544. return hRes;
  545. }
  546. /*=============================================================================
  547. *
  548. * A51Export::WriteObjectType
  549. *
  550. *=============================================================================
  551. */
  552. HRESULT A51Export::WriteObjectType(DWORD dwObjectType)
  553. {
  554. HRESULT hRes = WBEM_S_NO_ERROR;
  555. DWORD dwSize;
  556. if (!WriteFile(m_hFile, &dwObjectType, sizeof(DWORD), &dwSize, NULL) || (dwSize != sizeof(DWORD)))
  557. {
  558. hRes = WBEM_E_FAILED;
  559. }
  560. return hRes;
  561. }
  562. /*=============================================================================
  563. *
  564. * A51Export::WriteObjectBlob
  565. *
  566. *=============================================================================
  567. */
  568. HRESULT A51Export::WriteObjectBlob(_IWmiObject *pObject)
  569. {
  570. HRESULT hRes;
  571. DWORD dwObjPartLen = 0;
  572. BYTE *pObjPart = NULL;
  573. //Get the size of the object
  574. hRes = pObject->Unmerge(0, 0, &dwObjPartLen, 0);
  575. //Allocate the size of the object
  576. if (hRes == WBEM_E_BUFFER_TOO_SMALL)
  577. {
  578. hRes = WBEM_S_NO_ERROR;
  579. pObjPart = new BYTE[dwObjPartLen];
  580. if (pObjPart == NULL)
  581. hRes = WBEM_E_OUT_OF_MEMORY;
  582. }
  583. CVectorDeleteMe<BYTE> vdm1(pObjPart);
  584. //retrieve the object blob
  585. if (SUCCEEDED(hRes))
  586. {
  587. DWORD dwLen;
  588. hRes = pObject->Unmerge(0, dwObjPartLen, &dwLen, pObjPart);
  589. }
  590. //Write object blob and length
  591. if (SUCCEEDED(hRes))
  592. {
  593. hRes = WriteBufferWithLength(dwObjPartLen, pObjPart);
  594. }
  595. return hRes;
  596. }