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.

1017 lines
26 KiB

  1. /*++
  2. Copyright (C) 1999-2001 Microsoft Corporation
  3. Module Name:
  4. MOFOUT.CPP
  5. Abstract:
  6. Class and code used to output split files. This is used so that a
  7. single mof file can be split into a localized and non localized versions.
  8. History:
  9. 2/4/99 a-davj Compiles.
  10. --*/
  11. #include "precomp.h"
  12. #include <cominit.h>
  13. #include <wbemcli.h>
  14. #include "mofout.h"
  15. #include <genutils.h>
  16. #include <var.h>
  17. #include "mofprop.h"
  18. //***************************************************************************
  19. //
  20. // COutput::COutput
  21. //
  22. // DESCRIPTION:
  23. //
  24. // Constructor. This object is used to serialize output to a file
  25. //
  26. //***************************************************************************
  27. COutput::COutput(TCHAR * pName, OutputType ot, BOOL bUnicode, BOOL bAutoRecovery, long lLocale) : m_lLocale(lLocale)
  28. {
  29. m_bUnicode = true;
  30. m_Level = 0;
  31. m_lClassFlags = 0;
  32. m_lInstanceFlags = 0;
  33. m_bSplitting = false;
  34. if(ot == NEUTRAL)
  35. StringCchCopyW(m_wszNamespace, MAX_PATH+1, L"root\\default");
  36. else
  37. StringCchCopyW(m_wszNamespace, MAX_PATH+1, L"_?");
  38. m_hFile = CreateFile(pName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
  39. CREATE_ALWAYS, 0, NULL);
  40. if(bUnicode && m_hFile != INVALID_HANDLE_VALUE)
  41. {
  42. unsigned char cUnicodeHeader[2] = {0xff, 0xfe};
  43. DWORD dwWrite;
  44. WriteFile(m_hFile, cUnicodeHeader, 2, &dwWrite, NULL);
  45. }
  46. m_Type = ot;
  47. if(bAutoRecovery)
  48. WriteLPWSTR(L"#pragma autorecover\r\n");
  49. }
  50. //***************************************************************************
  51. //
  52. // COutput::~COutput()
  53. //
  54. // DESCRIPTION:
  55. //
  56. // Destructor.
  57. //
  58. //***************************************************************************
  59. COutput::~COutput()
  60. {
  61. if(m_hFile != INVALID_HANDLE_VALUE)
  62. CloseHandle(m_hFile);
  63. }
  64. //***************************************************************************
  65. //
  66. // COutput::WriteLPWSTR(WCHAR const * pOutput)
  67. //
  68. // DESCRIPTION:
  69. //
  70. // Writes a string to the file. If the original file was not unicode, then
  71. // this converts the text back into mbs.
  72. //
  73. //***************************************************************************
  74. bool COutput::WriteLPWSTR(WCHAR const * pOutput)
  75. {
  76. DWORD dwLen, dwWrite;
  77. if(pOutput == NULL || m_hFile == INVALID_HANDLE_VALUE)
  78. return false;
  79. if(m_bUnicode)
  80. {
  81. dwLen = 2 * (wcslen(pOutput));
  82. WriteFile(m_hFile, pOutput, dwLen, &dwWrite, NULL);
  83. }
  84. else
  85. {
  86. int iLen = 2 * (wcslen(pOutput) + 1);
  87. char * pTemp = new char[iLen];
  88. if(pTemp == NULL)
  89. return false;
  90. wcstombs(pTemp, pOutput, iLen);
  91. dwLen = strlen(pTemp);
  92. WriteFile(m_hFile, pTemp, dwLen, &dwWrite, NULL);
  93. delete [] pTemp;
  94. }
  95. if(dwWrite == dwLen)
  96. return true;
  97. else
  98. return false;
  99. }
  100. //***************************************************************************
  101. //
  102. // COutput::WriteVARIANT(VARIANT & varIn)
  103. //
  104. // DESCRIPTION:
  105. //
  106. // Serialized a variant out to the file. This relies on the CVar class so
  107. // as to be compatible with GetObjectText().
  108. //
  109. //***************************************************************************
  110. bool COutput::WriteVARIANT(VARIANT & varIn)
  111. {
  112. CVar X(&varIn);
  113. BSTR b = X.GetText(0,0);
  114. if(b)
  115. {
  116. WriteLPWSTR(b);
  117. SysFreeString(b);
  118. return true;
  119. }
  120. else
  121. return false;
  122. }
  123. //***************************************************************************
  124. //
  125. // bool COutput::NewLine(int iIndent)
  126. //
  127. // DESCRIPTION:
  128. //
  129. // Starts a new line. In addition to the cr\lf, this also indents based on
  130. // the argument and the level of subobject. I.e. if we are inside a
  131. // subobject to a subobject, we would indent 10 characters.
  132. //
  133. //***************************************************************************
  134. bool COutput::NewLine(int iIndent)
  135. {
  136. WriteLPWSTR(L"\r\n");
  137. int iExtra = iIndent + m_Level * 4;
  138. for (int i = 0; i < iExtra; i++)
  139. {
  140. WriteLPWSTR(L" ");
  141. }
  142. return true;
  143. }
  144. //***************************************************************************
  145. //
  146. // COutput::WritePragmasForAnyChanges()
  147. //
  148. // DESCRIPTION:
  149. //
  150. // This is called at the start of each class or instance object. If the
  151. // class flags, instance flags, or namespace have changed, then this outputs
  152. // the appropriate pragmas. The lLocale argument is used if we are
  153. // outputting to the localized file. In that case the lLocale is added to
  154. // the namespace path.
  155. //
  156. //***************************************************************************
  157. void COutput::WritePragmasForAnyChanges(long lClassFlags, long lInstanceFlags,
  158. LPWSTR pwsNamespace, long lLocale)
  159. {
  160. if(m_Level > 0)
  161. return; // ignore for embedded objects;
  162. if(lClassFlags != m_lClassFlags)
  163. {
  164. WCHAR wTemp[40];
  165. m_lClassFlags = lClassFlags;
  166. StringCchPrintfW(wTemp, 40, L"#pragma classflags(%d)\r\n", m_lClassFlags);
  167. WriteLPWSTR(wTemp);
  168. }
  169. if(lInstanceFlags != m_lInstanceFlags)
  170. {
  171. WCHAR wTemp[40];
  172. m_lInstanceFlags = lInstanceFlags;
  173. StringCchPrintfW(wTemp, 40, L"#pragma instanceflags(%d)\r\n", m_lInstanceFlags);
  174. WriteLPWSTR(wTemp);
  175. }
  176. if(wbem_wcsicmp(m_wszNamespace, pwsNamespace))
  177. {
  178. // copy the namespace into the buffer.
  179. wcsncpy(m_wszNamespace, pwsNamespace, MAX_PATH);
  180. m_wszNamespace[MAX_PATH] = 0;
  181. // before writting this out, each slash needs to be doubled up. Also,
  182. // the path may need the machine part.
  183. WCHAR wTemp[MAX_PATH*2];
  184. WCHAR * pTo = wTemp, * pFrom = pwsNamespace;
  185. if(pwsNamespace[0] != L'\\')
  186. {
  187. StringCchCopyW(pTo, MAX_PATH*2, L"\\\\\\\\.\\\\");
  188. pTo+= 7;
  189. }
  190. while(*pFrom)
  191. {
  192. if(*pFrom == L'\\')
  193. {
  194. *pTo = L'\\';
  195. pTo++;
  196. }
  197. *pTo = *pFrom;
  198. pTo++;
  199. pFrom++;
  200. }
  201. *pTo = 0;
  202. WriteLPWSTR(L"#pragma namespace(\"");
  203. WriteLPWSTR(wTemp);
  204. WriteLPWSTR(L"\")\r\n");
  205. // For localized, we need to create the namespace and then to modify the pragma
  206. // Example, if the namespace is root, we need to write
  207. // #pragma ("root")
  208. // instance of __namespace{name="ms_409";};
  209. // #pragma ("root\ms_409")
  210. if(m_Type == LOCALIZED)
  211. {
  212. WCHAR wMSLocale[10];
  213. StringCchPrintfW(wMSLocale, 10, L"ms_%x", lLocale);
  214. WriteLPWSTR(L"instance of __namespace{ name=\"");
  215. WriteLPWSTR(wMSLocale);
  216. WriteLPWSTR(L"\";};\r\n");
  217. WriteLPWSTR(L"#pragma namespace(\"");
  218. WriteLPWSTR(wTemp);
  219. WriteLPWSTR(L"\\\\");
  220. WriteLPWSTR(wMSLocale);
  221. WriteLPWSTR(L"\")\r\n");
  222. }
  223. }
  224. }
  225. //***************************************************************************
  226. //
  227. // CMoValue::Split(COutput &out)
  228. //
  229. // DESCRIPTION:
  230. //
  231. // Serialize a CMoValue. In general, the standard converted is used, but
  232. // we must special case alias values.
  233. //
  234. //***************************************************************************
  235. BOOL CMoValue::Split(COutput &out)
  236. {
  237. int iNumAlias = GetNumAliases();
  238. LPWSTR wszAlias = NULL; int nArrayIndex;
  239. // This is the normal case of all but references!!!!
  240. if(iNumAlias == 0)
  241. return out.WriteVARIANT(m_varValue);
  242. if(m_varValue.vt == VT_BSTR)
  243. {
  244. // simple case, single alias
  245. out.WriteLPWSTR(L"$");
  246. GetAlias(0, wszAlias, nArrayIndex);
  247. out.WriteLPWSTR(wszAlias);
  248. return TRUE;
  249. }
  250. else
  251. {
  252. out.WriteLPWSTR(L"{");
  253. // For each string from the safe array
  254. SAFEARRAY* psaSrc = V_ARRAY(&m_varValue);
  255. if(psaSrc == NULL)
  256. return FALSE;
  257. SAFEARRAYBOUND aBounds[1];
  258. long lLBound;
  259. SCODE sc = SafeArrayGetLBound(psaSrc, 1, &lLBound);
  260. long lUBound;
  261. sc |= SafeArrayGetUBound(psaSrc, 1, &lUBound);
  262. if(sc != S_OK)
  263. return FALSE;
  264. aBounds[0].cElements = lUBound - lLBound + 1;
  265. aBounds[0].lLbound = lLBound;
  266. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  267. {
  268. // Determine if this is an alias
  269. int iTest;
  270. for(iTest = 0; iTest < iNumAlias; iTest++)
  271. {
  272. if(GetAlias(iTest, wszAlias, nArrayIndex))
  273. if(nArrayIndex == lIndex)
  274. break;
  275. }
  276. // If so, the output the alias value
  277. if(iTest < iNumAlias)
  278. {
  279. out.WriteLPWSTR(L"$");
  280. out.WriteLPWSTR(wszAlias);
  281. }
  282. else
  283. {
  284. // else output the string
  285. BSTR bstr;
  286. if(S_OK == SafeArrayGetElement(psaSrc, &lIndex, &bstr))
  287. {
  288. out.WriteLPWSTR(L"\"");
  289. out.WriteLPWSTR(bstr);
  290. SysFreeString(bstr);
  291. out.WriteLPWSTR(L"\"");
  292. }
  293. }
  294. // possibly output a comma
  295. if(lUBound != lLBound && lIndex < lUBound)
  296. out.WriteLPWSTR(L",");
  297. }
  298. out.WriteLPWSTR(L"}");
  299. return TRUE;
  300. }
  301. }
  302. BOOL CMoActionPragma::Split(COutput & out)
  303. {
  304. // Write flags and namespace pragmas
  305. long lLocale = out.GetLocale();
  306. WCHAR * pwszNamespace = m_wszNamespace;
  307. out.WritePragmasForAnyChanges(m_lDefClassFlags, m_lDefInstanceFlags, pwszNamespace, lLocale);
  308. out.NewLine(0);
  309. if(m_bClass)
  310. out.WriteLPWSTR(L"#pragma deleteclass(");
  311. else
  312. out.WriteLPWSTR(L"#pragma deleteinstance(");
  313. // The class name may have embedded quotes etc. So convert to variant and
  314. // output that since that logic automatically puts in the needed escapes
  315. VARIANT var;
  316. var.vt = VT_BSTR;
  317. var.bstrVal = SysAllocString(m_wszClassName);
  318. if(var.bstrVal == NULL)
  319. return FALSE;
  320. out.WriteVARIANT(var);
  321. VariantClear(&var);
  322. out.WriteLPWSTR(L",");
  323. if(m_bFail)
  324. out.WriteLPWSTR(L"FAIL)");
  325. else
  326. out.WriteLPWSTR(L"NOFAIL)");
  327. out.NewLine(0);
  328. return TRUE;
  329. }
  330. //***************************************************************************
  331. //
  332. // CMObject::Split(COutput & out)
  333. //
  334. // DESCRIPTION:
  335. //
  336. // Serialize a Class of instance object.
  337. //
  338. //***************************************************************************
  339. BOOL CMObject::Split(COutput & out)
  340. {
  341. // If this is a top level object, figure out if it has a [locale] qualifier
  342. long lLocale = out.GetLocale();
  343. if(out.GetLevel() == 0)
  344. {
  345. bool bAmended = m_bAmended;
  346. if(out.GetType() == LOCALIZED)
  347. {
  348. // if this is the localized output and this object doesnt
  349. // have the locale.
  350. if(!bAmended)
  351. return TRUE;
  352. }
  353. else
  354. {
  355. // if this is the non localized version, then the object
  356. // may, or may not be split apart.
  357. out.SetSplitting(bAmended);
  358. }
  359. }
  360. WCHAR * pwszNamespace = m_wszNamespace;
  361. // Write flags and namespace pragmas
  362. out.WritePragmasForAnyChanges(m_lDefClassFlags, m_lDefInstanceFlags, pwszNamespace, lLocale);
  363. // Write the qualifiers
  364. if(GetQualifiers())
  365. {
  366. CMoQualifierArray * pqual = GetQualifiers();
  367. pqual->Split(out, OBJECT);
  368. }
  369. // Write the instance or class declaration
  370. out.NewLine(0);
  371. if(IsInstance())
  372. {
  373. out.WriteLPWSTR(L"Instance of ");
  374. out.WriteLPWSTR(GetClassName());
  375. CMoInstance * pInst = (CMoInstance *)this;
  376. if(pInst->GetAlias())
  377. {
  378. out.WriteLPWSTR(L" as $");
  379. out.WriteLPWSTR(GetAlias());
  380. }
  381. }
  382. else
  383. {
  384. out.WriteLPWSTR(L"class ");
  385. out.WriteLPWSTR(GetClassName());
  386. CMoClass * pClass = (CMoClass *)this;
  387. if(pClass->GetAlias())
  388. {
  389. out.WriteLPWSTR(L" as $");
  390. out.WriteLPWSTR(GetAlias());
  391. }
  392. if(pClass->GetParentName())
  393. {
  394. out.WriteLPWSTR(L" : ");
  395. out.WriteLPWSTR(pClass->GetParentName());
  396. }
  397. }
  398. out.NewLine(0);
  399. out.WriteLPWSTR(L"{");
  400. // Output the properties and methods
  401. for(int i = 0; i < GetNumProperties(); i++)
  402. {
  403. if(!GetProperty(i)->Split(out)) return FALSE;
  404. }
  405. out.NewLine(0);
  406. // if this is a top level object, add the semicolon and an extra
  407. if(out.GetLevel() == 0)
  408. {
  409. out.WriteLPWSTR(L"};");
  410. out.NewLine(0);
  411. }
  412. else
  413. out.WriteLPWSTR(L"}");
  414. return TRUE;
  415. }
  416. //***************************************************************************
  417. //
  418. // CValueProperty::Split(COutput & out)
  419. //
  420. // DESCRIPTION:
  421. //
  422. // Serializes value properties
  423. //
  424. //***************************************************************************
  425. BOOL CValueProperty::Split(COutput & out)
  426. {
  427. // Write the qualifiers
  428. if(GetQualifiers())
  429. {
  430. CMoQualifierArray * pqual = GetQualifiers();
  431. if(out.GetType() == LOCALIZED && !pqual->HasAmended() && !m_bIsArg)
  432. return TRUE;
  433. pqual->Split(out, (m_bIsArg) ? ARG : PROP);
  434. }
  435. else
  436. if(out.GetType() == LOCALIZED && !m_bIsArg)
  437. return TRUE;
  438. // determine if this is an array value
  439. VARTYPE vt = m_Value.GetType();
  440. BOOL bArray = vt & VT_ARRAY;
  441. if(m_bIsArg && bArray == FALSE && vt == 0)
  442. {
  443. VARTYPE vtInner = m_Value.GetVarType();
  444. bArray = vtInner & VT_ARRAY;
  445. }
  446. // Possibly output the type, such as "sint32"
  447. if(m_wszTypeTitle)
  448. {
  449. out.WriteLPWSTR(m_wszTypeTitle);
  450. VARTYPE vt = m_Value.GetType();
  451. vt = vt & (~CIM_FLAG_ARRAY);
  452. if(vt == CIM_REFERENCE)
  453. out.WriteLPWSTR(L" Ref");
  454. out.WriteLPWSTR(L" ");
  455. }
  456. // Output the property name
  457. out.WriteLPWSTR(m_wszName);
  458. if(bArray)
  459. out.WriteLPWSTR(L"[]");
  460. // In general, the value is output via CMoValue, but the
  461. // glaring exception is embedded objects and arrays of
  462. // embedded objects
  463. vt = m_Value.GetVarType();
  464. if(vt != VT_NULL && out.GetType() == NEUTRAL )
  465. {
  466. out.WriteLPWSTR(L" = ");
  467. if(vt == VT_UNKNOWN)
  468. {
  469. // got an embedded object
  470. VARIANT & var = m_Value.AccessVariant();
  471. CMObject * pObj = (CMObject *)var.punkVal;
  472. out.IncLevel(); // indicate embedding
  473. pObj->Split(out);
  474. out.DecLevel();
  475. }
  476. else if (vt == (VT_ARRAY | VT_UNKNOWN))
  477. {
  478. // got an embedded object array
  479. SCODE sc ;
  480. out.WriteLPWSTR(L"{");
  481. VARIANT & var = m_Value.AccessVariant();
  482. SAFEARRAY * psaSrc = var.parray;
  483. if(psaSrc == NULL)
  484. return FALSE;
  485. long lLBound, lUBound;
  486. sc = SafeArrayGetLBound(psaSrc, 1, &lLBound);
  487. sc |= SafeArrayGetUBound(psaSrc, 1, &lUBound);
  488. if(sc != S_OK)
  489. return FALSE;
  490. for(long lIndex = lLBound; lIndex <= lUBound; lIndex++)
  491. {
  492. CMObject * pObj = NULL;
  493. SCODE sc = SafeArrayGetElement(psaSrc, &lIndex, &pObj);
  494. if(sc == S_OK && pObj)
  495. {
  496. out.IncLevel(); // indicate embedding
  497. pObj->Split(out);
  498. out.DecLevel();
  499. }
  500. if(lLBound != lUBound && lIndex < lUBound)
  501. out.WriteLPWSTR(L",");
  502. }
  503. out.WriteLPWSTR(L"}");
  504. }
  505. else
  506. m_Value.Split(out); // !!! Typical case
  507. }
  508. // Note that property objects are used as argmuments in methods. If this
  509. // is one of these, then dont output a ';'
  510. if(!m_bIsArg)
  511. out.WriteLPWSTR(L";");
  512. return TRUE;
  513. }
  514. //***************************************************************************
  515. //
  516. // CMethodProperty::IsDisplayable(COutput & out)
  517. //
  518. // DESCRIPTION:
  519. //
  520. // Serializes methods
  521. //
  522. //***************************************************************************
  523. BOOL CMethodProperty::IsDisplayable(COutput & out)
  524. {
  525. // if we are neutral, then always.
  526. if(out.GetType() == NEUTRAL)
  527. return TRUE;
  528. // Write the qualifiers
  529. if(GetQualifiers())
  530. {
  531. CMoQualifierArray * pqual = GetQualifiers();
  532. if(pqual->HasAmended())
  533. return TRUE;
  534. }
  535. int iSize = m_Args.GetSize();
  536. for(int i = 0; i < iSize; i++)
  537. {
  538. CValueProperty * pProp = (CValueProperty *)m_Args.GetAt(i);
  539. if(pProp)
  540. {
  541. CMoQualifierArray * pqual = pProp->GetQualifiers();
  542. if(pqual->HasAmended())
  543. return TRUE;
  544. }
  545. }
  546. return FALSE;
  547. }
  548. //***************************************************************************
  549. //
  550. // CMethodProperty::Split(COutput & out)
  551. //
  552. // DESCRIPTION:
  553. //
  554. // Serializes methods
  555. //
  556. //***************************************************************************
  557. BOOL CMethodProperty::Split(COutput & out)
  558. {
  559. if(!IsDisplayable(out))
  560. return TRUE;
  561. // Write the qualifiers
  562. if(GetQualifiers())
  563. {
  564. CMoQualifierArray * pqual = GetQualifiers();
  565. pqual->Split(out, PROP);
  566. }
  567. // Output the method's return value type and name
  568. if(m_wszTypeTitle)
  569. {
  570. if(wbem_wcsicmp(L"NULL", m_wszTypeTitle))
  571. out.WriteLPWSTR(m_wszTypeTitle);
  572. else
  573. out.WriteLPWSTR(L"void");
  574. out.WriteLPWSTR(L" ");
  575. }
  576. out.WriteLPWSTR(m_wszName);
  577. // output the arguements between the parenthesis
  578. out.WriteLPWSTR(L"(");
  579. int iSize = m_Args.GetSize();
  580. for(int i = 0; i < iSize; i++)
  581. {
  582. CValueProperty * pProp = (CValueProperty *)m_Args.GetAt(i);
  583. if(pProp)
  584. {
  585. pProp->SetAsArg();
  586. pProp->Split(out);
  587. }
  588. if(iSize > 0 && i < (iSize-1))
  589. out.WriteLPWSTR(L",");
  590. }
  591. out.WriteLPWSTR(L");");
  592. return TRUE;
  593. }
  594. //***************************************************************************
  595. //
  596. // CMoQualifier::IsDisplayable(COutput & out, QualType qt)
  597. //
  598. // DESCRIPTION:
  599. //
  600. // Determines if a qualifier is to be written.
  601. //
  602. //***************************************************************************
  603. BOOL CMoQualifier::IsDisplayable(COutput & out, QualType qt)
  604. {
  605. if(!wbem_wcsicmp(L"cimtype", m_wszName)) // never!
  606. return FALSE;
  607. if(!wbem_wcsicmp(L"KEY", m_wszName)) // always!
  608. return TRUE;
  609. if(!wbem_wcsicmp(L"LOCALE", m_wszName) && qt == OBJECT)
  610. if(out.GetType() == LOCALIZED)
  611. return FALSE;
  612. else
  613. return TRUE;
  614. if(!wbem_wcsicmp(L"ID", m_wszName) && qt == ARG)
  615. return FALSE;
  616. if(!wbem_wcsicmp(L"IN", m_wszName) && qt == ARG)
  617. return TRUE;
  618. if(!wbem_wcsicmp(L"OUT", m_wszName) && qt == ARG)
  619. return TRUE;
  620. if(out.GetType() == LOCALIZED)
  621. {
  622. return (m_bAmended) ? TRUE : FALSE;
  623. }
  624. else
  625. {
  626. if(out.IsSplitting() == FALSE)
  627. return TRUE;
  628. if(m_bAmended == FALSE)
  629. return TRUE;
  630. return FALSE;
  631. }
  632. }
  633. //***************************************************************************
  634. //
  635. // PrintSeparator(COutput & out, bool bFirst)
  636. //
  637. // DESCRIPTION:
  638. //
  639. // Outputs space or colon when dumping flavors.
  640. //
  641. //***************************************************************************
  642. void PrintSeparator(COutput & out, bool bFirst)
  643. {
  644. if(bFirst)
  645. out.WriteLPWSTR(L" : ");
  646. else
  647. out.WriteLPWSTR(L" ");
  648. }
  649. //***************************************************************************
  650. //
  651. // CMoQualifier::Split(COutput & out)
  652. //
  653. // DESCRIPTION:
  654. //
  655. // Serializes CMoQualifiers.
  656. //
  657. //***************************************************************************
  658. BOOL CMoQualifier::Split(COutput & out)
  659. {
  660. // Always write the name
  661. out.WriteLPWSTR(m_wszName);
  662. VARIANT & var = m_Value.AccessVariant();
  663. // If the type is other than a true bool, dump it out
  664. if(var.vt != VT_BOOL || var.boolVal != VARIANT_TRUE)
  665. {
  666. VARTYPE vt = m_Value.GetVarType();
  667. // If this is an array, then the lower level dumping
  668. // code will enclose the values in {}
  669. if((vt & VT_ARRAY) == 0)
  670. out.WriteLPWSTR(L"(");
  671. m_Value.Split(out);
  672. if((vt & VT_ARRAY) == 0)
  673. out.WriteLPWSTR(L")");
  674. }
  675. return SplitFlavors( out );
  676. }
  677. //***************************************************************************
  678. //
  679. // CMoQualifier::Split(COutput & out)
  680. //
  681. // DESCRIPTION:
  682. //
  683. // Serializes CMoQualifiers Flavors
  684. //
  685. //***************************************************************************
  686. BOOL CMoQualifier::SplitFlavors(COutput & out)
  687. {
  688. // Dump out the flavors
  689. bool bFirst = true;
  690. if(m_bAmended)
  691. {
  692. PrintSeparator(out, bFirst);
  693. out.WriteLPWSTR(L"Amended");
  694. bFirst = false;
  695. }
  696. if(m_lFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE)
  697. {
  698. PrintSeparator(out, bFirst);
  699. out.WriteLPWSTR(L"ToInstance");
  700. bFirst = false;
  701. }
  702. if(m_lFlavor & WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS)
  703. {
  704. PrintSeparator(out, bFirst);
  705. out.WriteLPWSTR(L"ToSubclass");
  706. bFirst = false;
  707. }
  708. if(m_lFlavor & WBEM_FLAVOR_NOT_OVERRIDABLE)
  709. {
  710. PrintSeparator(out, bFirst);
  711. out.WriteLPWSTR(L"DisableOverride");
  712. bFirst = false;
  713. }
  714. return TRUE;
  715. }
  716. //***************************************************************************
  717. //
  718. // CMoQualifierArray::Split(COutput & out, QualType qt)
  719. //
  720. // DESCRIPTION:
  721. //
  722. // Serializes the qualifier array.
  723. //
  724. //***************************************************************************
  725. BOOL CMoQualifierArray::Split(COutput & out, QualType qt)
  726. {
  727. bool bTopLevelLocalizedObj = ( qt == OBJECT && out.GetType() == LOCALIZED &&
  728. out.GetLevel() == 0);
  729. // count the number that need to be serialized.
  730. int iNumOutput = 0, i;
  731. for(i = 0; i < GetSize(); i++)
  732. {
  733. CMoQualifier * pQual = GetAt(i);
  734. if(pQual && pQual->IsDisplayable(out, qt))
  735. iNumOutput++;
  736. }
  737. // If this is a top level object in a localized object, then the local is foced out
  738. // along with the amended qualifier
  739. if(bTopLevelLocalizedObj)
  740. iNumOutput += 2;
  741. // If this is for anything other than an argument, then
  742. // dump a new line. Note that properties get an extra
  743. // two characters of indent
  744. if(qt == PROP)
  745. out.NewLine(2);
  746. else if (qt == OBJECT && iNumOutput > 0)
  747. out.NewLine(0);
  748. if(iNumOutput == 0) // perfectly normal
  749. return TRUE;
  750. // We'll need to out put the flavors special for this in the
  751. // split off file
  752. CMoQualifier* pLocaleQual = NULL;
  753. // Serialize the individual qualifiers
  754. out.WriteLPWSTR(L"[");
  755. int iNumSoFar = 0;
  756. for(i = 0; i < GetSize(); i++)
  757. {
  758. CMoQualifier * pQual = GetAt(i);
  759. if(pQual == NULL || !pQual->IsDisplayable(out, qt))
  760. {
  761. if ( pQual->IsLocaleQual() )
  762. {
  763. pLocaleQual = pQual;
  764. }
  765. continue;
  766. }
  767. iNumSoFar++;
  768. pQual->Split(out);
  769. if(iNumSoFar < iNumOutput)
  770. out.WriteLPWSTR(L",");
  771. }
  772. // If this is a top level object in a localized object, then the local is foced out
  773. // along with the amended qualifier
  774. if(bTopLevelLocalizedObj)
  775. {
  776. WCHAR Buff[50];
  777. StringCchPrintfW(Buff, 50, L"AMENDMENT, LOCALE(0x%03x)", out.GetLocale());
  778. out.WriteLPWSTR(Buff);
  779. // If we have a locale qualifier in the array, then we should output
  780. // the flavors now.
  781. if ( NULL != pLocaleQual )
  782. {
  783. pLocaleQual->SplitFlavors( out );
  784. }
  785. }
  786. out.WriteLPWSTR(L"] ");
  787. return TRUE;
  788. }
  789. //***************************************************************************
  790. //
  791. // CMObject::CheckIfAmended()
  792. //
  793. // DESCRIPTION:
  794. //
  795. // returns true if the object has one or more Amended qualifiers.
  796. //
  797. //***************************************************************************
  798. bool CMObject::CheckIfAmended()
  799. {
  800. if(m_bAmended)
  801. return true;
  802. // true if this is a __namespace object
  803. if(IsInstance())
  804. {
  805. if(!wbem_wcsicmp(GetClassName(), L"__namespace"))
  806. return false;
  807. }
  808. // Deletes always get displayed
  809. if(IsDelete())
  810. return TRUE;
  811. // Check if the main qualifier list has an amended qualifier
  812. if(m_paQualifiers->HasAmended())
  813. return true;
  814. // check if any of the properties has an amended qualifier
  815. for(int i = 0; i < GetNumProperties(); i++)
  816. {
  817. CMoProperty * pProp = GetProperty(i);
  818. if(pProp)
  819. {
  820. CMoQualifierArray* pPropQualList = pProp->GetQualifiers();
  821. if(pPropQualList->HasAmended())
  822. return true;
  823. }
  824. }
  825. return false;
  826. }
  827. //***************************************************************************
  828. //
  829. // CMoQualifierArray::HasAmended()
  830. //
  831. // DESCRIPTION:
  832. //
  833. // Returns true if one of more of the qualifiers is amended.
  834. //
  835. //***************************************************************************
  836. bool CMoQualifierArray::HasAmended()
  837. {
  838. int iCnt, iSize = m_aQualifiers.GetSize();
  839. for(iCnt = 0; iCnt < iSize; iCnt++)
  840. {
  841. CMoQualifier * pQual = (CMoQualifier *)m_aQualifiers.GetAt(iCnt);
  842. if(pQual)
  843. if(pQual->IsAmended())
  844. return true;
  845. }
  846. return false;
  847. }