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.

1854 lines
46 KiB

  1. //=============================================================================
  2. //
  3. // File: WMIlFile.cpp
  4. // Copyright (c) 1994-2001 Microsoft Corporation, All Rights Reserved
  5. // All rights reserved.
  6. //
  7. //=============================================================================
  8. #include "stdafx.h"
  9. #include <buildnum.h>
  10. #include <helpids.h>
  11. #include "WMIparse.h"
  12. #include "resource.h"
  13. #include "WMIlprs.h"
  14. #include "WMIlfile.h"
  15. //*****************************************************************************
  16. //
  17. // CWMILocFile::CWMILocFile
  18. //
  19. //*****************************************************************************
  20. CWMILocFile::CWMILocFile(
  21. ILocParser *pParentClass)
  22. {
  23. //
  24. // C.O.M. initialization
  25. //
  26. m_pParentClass = pParentClass;
  27. m_sCurrentNamespace = "";
  28. m_ulRefCount = 0;
  29. //
  30. // WMI file initialization
  31. //
  32. m_uiLineNumber = 0;
  33. m_pOpenSourceFile = NULL;
  34. m_pOpenTargetFile = NULL;
  35. AddRef();
  36. IncrementClassCount();
  37. }
  38. //*****************************************************************************
  39. //
  40. // CWMILocFile::GetFileDescriptions
  41. //
  42. //*****************************************************************************
  43. void CWMILocFile::GetFileDescriptions(
  44. CEnumCallback &cb)
  45. {
  46. EnumInfo eiFileInfo;
  47. CLString strDesc;
  48. eiFileInfo.szAbbreviation = NULL;
  49. LTVERIFY(strDesc.LoadString(g_hDll, IDS_WMI_DESC));
  50. eiFileInfo.szDescription = (const TCHAR *)strDesc;
  51. eiFileInfo.ulValue = ftWMIFileType;
  52. cb.ProcessEnum(eiFileInfo);
  53. }
  54. //*****************************************************************************
  55. //
  56. // CWMILocFile::AddRef
  57. //
  58. //*****************************************************************************
  59. ULONG CWMILocFile::AddRef(void)
  60. {
  61. if (m_pParentClass != NULL)
  62. {
  63. m_pParentClass->AddRef();
  64. }
  65. return m_ulRefCount++;
  66. }
  67. //*****************************************************************************
  68. //
  69. // CWMILocFile::Release
  70. //
  71. //*****************************************************************************
  72. ULONG CWMILocFile::Release(void)
  73. {
  74. LTASSERT(m_ulRefCount != 0);
  75. if (m_pParentClass != NULL)
  76. {
  77. m_pParentClass->Release();
  78. }
  79. m_ulRefCount--;
  80. if (m_ulRefCount == 0)
  81. {
  82. delete this;
  83. return 0;
  84. }
  85. return m_ulRefCount;
  86. }
  87. //*****************************************************************************
  88. //
  89. // CWMILocFile::QueryInterface
  90. //
  91. //*****************************************************************************
  92. HRESULT CWMILocFile::QueryInterface(
  93. REFIID iid,
  94. LPVOID *ppvObj)
  95. {
  96. if (m_pParentClass != NULL)
  97. {
  98. return m_pParentClass->QueryInterface(iid, ppvObj);
  99. }
  100. else
  101. {
  102. SCODE scRetVal = E_NOINTERFACE;
  103. *ppvObj = NULL;
  104. if (iid == IID_IUnknown)
  105. {
  106. *ppvObj = (IUnknown *)this;
  107. scRetVal = S_OK;
  108. }
  109. else if (iid == IID_ILocFile)
  110. {
  111. *ppvObj = (ILocFile *)this;
  112. scRetVal = S_OK;
  113. }
  114. if (scRetVal == S_OK)
  115. {
  116. AddRef();
  117. }
  118. return ResultFromScode(scRetVal);
  119. }
  120. }
  121. //*****************************************************************************
  122. //
  123. // CWMILocFile::AssertValidInterface
  124. //
  125. //*****************************************************************************
  126. void CWMILocFile::AssertValidInterface(void)
  127. const
  128. {
  129. AssertValid();
  130. }
  131. //*****************************************************************************
  132. //
  133. // CWMILocFile::OpenFile
  134. //
  135. //*****************************************************************************
  136. BOOL CWMILocFile::OpenFile(
  137. const CFileSpec &fsFile,
  138. CReporter &Reporter)
  139. {
  140. LTTRACEPOINT("OpenFile()");
  141. BOOL fRetCode;
  142. LTASSERT(m_pOpenTargetFile == NULL);
  143. fRetCode = FALSE;
  144. m_didFileId = fsFile.GetFileId();
  145. m_pstrFileName = fsFile.GetFileName();
  146. if (m_pOpenSourceFile != NULL)
  147. {
  148. fclose(m_pOpenSourceFile);
  149. m_pOpenSourceFile = NULL;
  150. }
  151. // We are just going to open the file.
  152. // and save the handle.
  153. // ===================================
  154. try
  155. {
  156. m_pOpenSourceFile = fopen(_T(m_pstrFileName), "rb");
  157. if (!m_pOpenSourceFile)
  158. {
  159. fclose(m_pOpenSourceFile);
  160. m_pOpenSourceFile = NULL;
  161. }
  162. else
  163. {
  164. fRetCode = TRUE;
  165. }
  166. }
  167. catch (CMemoryException *pMemoryException)
  168. {
  169. CLString strContext;
  170. strContext.LoadString(g_hDll, IDS_WMI_GENERIC_LOCATION);
  171. Reporter.IssueMessage(esError, strContext, g_hDll, IDS_WMI_NO_MEMORY,
  172. g_locNull);
  173. pMemoryException->Delete();
  174. }
  175. return fRetCode;
  176. }
  177. //*****************************************************************************
  178. //
  179. // CWMILocFile::GetFileType
  180. //
  181. //*****************************************************************************
  182. FileType CWMILocFile::GetFileType(void)
  183. const
  184. {
  185. //
  186. // Just return some number that isn't ftUnknown...
  187. //
  188. return ftWMIFileType;
  189. }
  190. //*****************************************************************************
  191. //
  192. // CWMILocFile::GetFileTypeDescription
  193. //
  194. //*****************************************************************************
  195. void CWMILocFile::GetFileTypeDescription(
  196. CLString &strDesc)
  197. const
  198. {
  199. LTVERIFY(strDesc.LoadString(g_hDll, IDS_WMI_DESC));
  200. return;
  201. }
  202. //*****************************************************************************
  203. //
  204. // CWMILocFile::GetAssociatedFiles
  205. //
  206. //*****************************************************************************
  207. BOOL CWMILocFile::GetAssociatedFiles(
  208. CStringList &lstFiles)
  209. const
  210. {
  211. LTASSERT(lstFiles.GetCount() == 0);
  212. lstFiles.RemoveAll();
  213. return FALSE;
  214. }
  215. //*****************************************************************************
  216. //
  217. // CWMILocFile::EnumerateFile
  218. //
  219. //*****************************************************************************
  220. BOOL CWMILocFile::EnumerateFile(
  221. CLocItemHandler &ihItemHandler,
  222. const CLocLangId &lid,
  223. const DBID &dbidFileId)
  224. {
  225. BOOL bRet = TRUE;
  226. DBID dbidThisId = dbidFileId;
  227. LTTRACEPOINT("EnumerateFile()");
  228. if (m_pOpenSourceFile == NULL)
  229. {
  230. return FALSE;
  231. }
  232. // Enumerate file will need to:
  233. // * Parse the MOF.
  234. // * Walk through all qualifiers. For each "Amended" qualifier,
  235. // send back a CLocItem whose key is namespace, class, property and qualifier name.
  236. // * Fail if the language ID does not match that of LocaleID.
  237. // * Parent objects are namespaces, classes
  238. // =============================================================
  239. m_cpSource = lid.GetCodePage(cpAnsi);
  240. m_wSourceId = lid.GetLanguageId();
  241. ihItemHandler.SetProgressIndicator(0);
  242. bRet = ReadLines(ihItemHandler, dbidFileId, FALSE);
  243. return bRet;
  244. }
  245. //*****************************************************************************
  246. //
  247. // CWMILocFile::GenerateFile
  248. //
  249. //*****************************************************************************
  250. BOOL CWMILocFile::GenerateFile(
  251. const CPascalString &pstrTargetFile,
  252. CLocItemHandler &ihItemHandler,
  253. const CLocLangId &lidSource,
  254. const CLocLangId &lidTarget,
  255. const DBID &dbidParent)
  256. {
  257. LTASSERT(m_pOpenTargetFile == NULL);
  258. BOOL fRetVal = TRUE;
  259. if (m_pOpenSourceFile== NULL)
  260. {
  261. return FALSE;
  262. }
  263. // Generate File needs to:
  264. // * Parse the MOF.
  265. // * Walk through all qualifiers. For each "Amended" qualifier,
  266. // send back a CLocItem whose key is namespace, class, property and qualifier name.
  267. // * Replace all Amended qualifiers with localized text
  268. // * Replace all occurrences of the locale ID in namespaces and qualifiers
  269. // with the new one.
  270. // =================================================================================
  271. m_cpSource = lidSource.GetCodePage(cpAnsi);
  272. m_cpTarget = lidTarget.GetCodePage(cpAnsi);
  273. m_wSourceId = lidSource.GetLanguageId();
  274. m_wTargetId = lidTarget.GetLanguageId();
  275. try
  276. {
  277. CFileException excFile;
  278. fRetVal = FALSE;
  279. if (m_pOpenTargetFile != NULL)
  280. {
  281. fclose(m_pOpenTargetFile);
  282. m_pOpenTargetFile = NULL;
  283. }
  284. char FileName[255];
  285. strcpy(FileName, _bstr_t(_T(pstrTargetFile)));
  286. // This file must be in Unicode.
  287. HANDLE hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL,
  288. CREATE_ALWAYS, 0, NULL);
  289. if(hFile != INVALID_HANDLE_VALUE)
  290. {
  291. char cUnicodeHeader[2] = {0xff, 0xfe};
  292. DWORD dwWrite;
  293. WriteFile(hFile, cUnicodeHeader, 2, &dwWrite, NULL);
  294. CloseHandle(hFile);
  295. }
  296. m_pOpenTargetFile = fopen(FileName, "ab");
  297. if (!m_pOpenTargetFile)
  298. {
  299. fclose(m_pOpenTargetFile);
  300. m_pOpenTargetFile = NULL;
  301. }
  302. else
  303. {
  304. fRetVal = TRUE;
  305. }
  306. }
  307. catch (CMemoryException *pMemoryException)
  308. {
  309. CLString strContext;
  310. GetFullContext(strContext);
  311. ihItemHandler.IssueMessage(esError, strContext, g_hDll, IDS_WMI_NO_MEMORY,
  312. g_locNull);
  313. pMemoryException->Delete();
  314. }
  315. catch (CFileException *pFileException)
  316. {
  317. fclose(m_pOpenTargetFile);
  318. fRetVal = FALSE;
  319. ReportFileError((const WCHAR *)pstrTargetFile, m_didFileId, pFileException, ihItemHandler);
  320. pFileException->Delete();
  321. }
  322. if (!fRetVal)
  323. {
  324. return fRetVal;
  325. }
  326. if (!GetParserOptionBool(g_puid, OPT_DISABLE_WATERMARKING))
  327. {
  328. WriteWaterMark();
  329. }
  330. fRetVal = ReadLines(ihItemHandler, dbidParent, TRUE);
  331. fclose(m_pOpenTargetFile);
  332. if (!fRetVal)
  333. {
  334. CLFile::Remove(pstrTargetFile);
  335. }
  336. return fRetVal;
  337. }
  338. //*****************************************************************************
  339. //
  340. // CWMILocFile::GenerateItem
  341. //
  342. //*****************************************************************************
  343. BOOL CWMILocFile::GenerateItem(
  344. CLocItemHandler &ihItemHandler,
  345. CLocItemSet &isItemSet,
  346. wchar_t **pOutBuffer,
  347. UINT &uiStartingPos)
  348. {
  349. BOOL fRetVal = TRUE;
  350. UINT uiLength;
  351. wchar_t *pTemp = *pOutBuffer;
  352. _bstr_t sQualifierValue;
  353. // If nothing has changed, we can just
  354. // ignore this line.
  355. fRetVal = GetQualifierValue(pTemp, uiStartingPos, sQualifierValue, uiLength);
  356. if (fRetVal)
  357. {
  358. fRetVal = ihItemHandler.HandleItemSet(isItemSet);
  359. if (fRetVal)
  360. {
  361. sQualifierValue = "";
  362. for (int i = 0; i < isItemSet.GetSize(); i++)
  363. {
  364. CVC::ValidationCode vcRetVal;
  365. CLocItem *pLocItem = isItemSet[i];
  366. CLString strContext;
  367. CLocation loc;
  368. GetFullContext(strContext);
  369. loc.SetGlobalId(
  370. CGlobalId(pLocItem->GetMyDatabaseId(), otResource));
  371. loc.SetView(vTransTab);
  372. CPascalString pstrId, pstrText;
  373. pLocItem->GetUniqueId().GetResId().GetId(pstrId);
  374. pstrText = pLocItem->GetLocString().GetString();
  375. if (i > 0)
  376. sQualifierValue += L"\",\"";
  377. sQualifierValue += (const wchar_t *)pstrText;
  378. }
  379. // Set it live in the buffer. We are not going to
  380. // write it to the file until the very end.
  381. fRetVal = SetQualifierValue(pTemp, pOutBuffer, uiStartingPos, sQualifierValue, uiLength);
  382. pTemp = *pOutBuffer;
  383. }
  384. }
  385. return fRetVal;
  386. }
  387. //*****************************************************************************
  388. //
  389. // CWMILocFile::EnumerateItem
  390. //
  391. //*****************************************************************************
  392. BOOL CWMILocFile::EnumerateItem(
  393. CLocItemHandler &ihItemHandler,
  394. CLocItemSet &isItemSet)
  395. {
  396. BOOL fRetVal;
  397. if (isItemSet.GetSize() != 0)
  398. {
  399. fRetVal = ihItemHandler.HandleItemSet(isItemSet);
  400. }
  401. else
  402. {
  403. fRetVal = TRUE;
  404. }
  405. return fRetVal;
  406. }
  407. #ifdef _DEBUG
  408. //*****************************************************************************
  409. //
  410. // CWMILocFile::AssertValid
  411. //
  412. //*****************************************************************************
  413. void CWMILocFile::AssertValid(void)
  414. const
  415. {
  416. CLObject::AssertValid();
  417. }
  418. //*****************************************************************************
  419. //
  420. // CWMILocFile::Dump
  421. //
  422. //*****************************************************************************
  423. void CWMILocFile::Dump(
  424. CDumpContext &dc)
  425. const
  426. {
  427. CLObject::Dump(dc);
  428. }
  429. #endif
  430. //*****************************************************************************
  431. //
  432. // CWMILocFile::~CWMILocFile
  433. //
  434. //*****************************************************************************
  435. CWMILocFile::~CWMILocFile()
  436. {
  437. DEBUGONLY(AssertValid());
  438. if (m_pOpenSourceFile != NULL)
  439. {
  440. fclose(m_pOpenSourceFile);
  441. m_pOpenSourceFile = NULL;
  442. }
  443. DecrementClassCount();
  444. }
  445. //*****************************************************************************
  446. //
  447. // CWMILocFile::SetFlags
  448. //
  449. //*****************************************************************************
  450. void CWMILocFile::SetFlags(
  451. CLocItem *pItem,
  452. CLocString &lsString)
  453. const
  454. {
  455. ULONG ulItemType;
  456. pItem->SetFDevLock(FALSE);
  457. pItem->SetFUsrLock(FALSE);
  458. pItem->SetFExpandable(FALSE);
  459. LTVERIFY(pItem->GetUniqueId().GetTypeId().GetId(ulItemType));
  460. switch (ulItemType)
  461. {
  462. case wltNamespaceName:
  463. pItem->SetFDisplayable(TRUE);
  464. pItem->SetFNoResTable(TRUE);
  465. break;
  466. case wltClassName:
  467. case wltPropertyName:
  468. pItem->SetFDisplayable(FALSE);
  469. pItem->SetFNoResTable(FALSE);
  470. lsString.SetCodePageType(cpAnsi);
  471. lsString.SetStringType(CST::Text);
  472. break;
  473. default:
  474. LTASSERT(FALSE && "Unexpected item type!");
  475. }
  476. }
  477. //*****************************************************************************
  478. //
  479. // CWMILocFile::ReadLines
  480. //
  481. //*****************************************************************************
  482. BOOL CWMILocFile::ReadLines(
  483. CLocItemHandler &ihItemHandler,
  484. const DBID &dbidFileId,
  485. BOOL fGenerating)
  486. {
  487. DBID dbidSectionId;
  488. BOOL fRetVal = TRUE;
  489. wchar_t *pstrNamespaceName;
  490. _bstr_t pstrClassName;
  491. UINT uiStartPos = 0;
  492. UINT uiCommentNum;
  493. UINT uiReadingOrder;
  494. dbidSectionId = dbidFileId;
  495. m_uiLineNumber = 0;
  496. BOOL bPendingObj = FALSE;
  497. try
  498. {
  499. UINT uiOldPercentage = 0, uiNewPercentage = 0;
  500. UINT uiBytesRead, uiCurrPos = 1;
  501. ihItemHandler.SetProgressIndicator(uiOldPercentage);
  502. fseek(m_pOpenSourceFile, 0, SEEK_END);
  503. long lSize = ftell(m_pOpenSourceFile) + 6;
  504. fseek(m_pOpenSourceFile, 0, SEEK_SET);
  505. // Check for UNICODE source file.
  506. // ==============================
  507. BYTE UnicodeSignature[2];
  508. BOOL bUnicode = FALSE;
  509. if (fread(UnicodeSignature, sizeof(BYTE), 2, m_pOpenSourceFile) != 2)
  510. {
  511. fRetVal = FALSE;
  512. return fRetVal;
  513. }
  514. if ((UnicodeSignature[0] == 0xFF && UnicodeSignature[1] == 0xFE) ||
  515. (UnicodeSignature[0] == 0xFE && UnicodeSignature[1] == 0xFF))
  516. {
  517. bUnicode = TRUE;
  518. lSize *= 2;
  519. }
  520. if (!bUnicode)
  521. fseek(m_pOpenSourceFile, 0, SEEK_SET);
  522. wchar_t *pBuff = (wchar_t *)new wchar_t[lSize+1];
  523. if (!pBuff)
  524. {
  525. fRetVal = FALSE;
  526. return fRetVal;
  527. }
  528. memset(pBuff,0,lSize*sizeof(wchar_t));
  529. // If this is not a Unicode file,
  530. // we need to perform a conversion.
  531. // =====================================
  532. if (bUnicode)
  533. uiBytesRead = fread(pBuff, sizeof(wchar_t), lSize, m_pOpenSourceFile);
  534. else
  535. {
  536. char *pCharBuff = new char[lSize+1];
  537. if (pCharBuff)
  538. {
  539. uiBytesRead = fread(pCharBuff, sizeof(char), lSize, m_pOpenSourceFile);
  540. pCharBuff[lSize] = '\0';
  541. swprintf(pBuff, L"%S", pCharBuff);
  542. delete pCharBuff;
  543. }
  544. }
  545. pBuff[lSize] = '\0';
  546. if (uiBytesRead != 0)
  547. {
  548. wchar_t *pOutBuffer = NULL;
  549. uiCurrPos += uiBytesRead;
  550. fRetVal = TRUE;
  551. pstrNamespaceName = NULL;
  552. m_sCurrentNamespace = L"";
  553. pstrClassName = L"";
  554. uiCommentNum = 0;
  555. uiReadingOrder = 1;
  556. WMIFileError wmiRet;
  557. CLocItemSet isItemSet;
  558. UINT uiTemp = 0;
  559. DWORD dwCount = 0;
  560. // If we are generating a file, make a copy
  561. // of the outbound buffer.
  562. if (fGenerating)
  563. pOutBuffer = pBuff;
  564. while (GetNextQualifierPos(L"amended", pBuff, uiTemp, uiTemp) && !bPendingObj)
  565. {
  566. // If we have found the "amended" keyword,
  567. // we want to find the namespace,
  568. // class, and property if applicable, and
  569. // generate the object as appropriate.
  570. // ======================================
  571. pstrNamespaceName = GetCurrentNamespace(pBuff, uiTemp);
  572. if (!pstrNamespaceName || !wcslen(pstrNamespaceName))
  573. {
  574. delete pBuff;
  575. return FALSE;
  576. }
  577. if (wcscmp(pstrNamespaceName, m_sCurrentNamespace))
  578. {
  579. // We need to generate this object,
  580. // and set it up as the current parent.
  581. // ====================================
  582. CLocItem *pNewItem = new CLocItem;
  583. CPascalString sId;
  584. if (pNewItem)
  585. {
  586. CLocUniqueId uid;
  587. sId = (const WCHAR *)pstrNamespaceName;
  588. uid.GetResId().SetId(sId);
  589. uid.GetTypeId().SetId(wltNamespaceName);
  590. uid.SetParentId(dbidFileId);
  591. pNewItem->SetUniqueId(uid);
  592. CLocString lsString;
  593. pNewItem->SetIconType(CIT::String);
  594. CPascalString pstrComment, pstrText;
  595. pNewItem->SetInstructions(pstrComment);
  596. lsString.SetString(pstrText);
  597. SetFlags(pNewItem, lsString);
  598. pNewItem->SetLocString(lsString);
  599. isItemSet.Add(pNewItem);
  600. uiReadingOrder = (uiReadingOrder + 999)/1000*1000;
  601. isItemSet[0]->SetDisplayOrder(uiReadingOrder);
  602. uiReadingOrder++;
  603. fRetVal = EnumerateItem(ihItemHandler,
  604. isItemSet);
  605. dbidSectionId.Clear();
  606. dbidSectionId = isItemSet[0]->GetMyDatabaseId();
  607. isItemSet.ClearItemSet();
  608. uiTemp += 1;
  609. }
  610. m_sCurrentNamespace = pstrNamespaceName;
  611. delete pstrNamespaceName;
  612. }
  613. // For the class name, this is trickier.
  614. // If there are one or more qualifiers
  615. // on the class itself, we need to read ahead
  616. // to find the class name, and then
  617. // generate all the qualifier objects at once.
  618. // ==========================================
  619. wmiRet = GetNextItemSet(dwCount, pBuff, isItemSet, dbidSectionId, uiStartPos);
  620. while (wmiRet == WMINoError)
  621. {
  622. // For each item, we want to set its key,
  623. // and push it or write it as appropriate.
  624. // ========================================
  625. dwCount++;
  626. ULONG ulItemType;
  627. CLocUniqueId &rUid = isItemSet[0]->GetUniqueId();
  628. rUid.GetTypeId().GetId(ulItemType);
  629. //if (ulItemType == wltClassName)
  630. //{
  631. // uiCommentNum = 0;
  632. // uiReadingOrder = (uiReadingOrder + 999)/1000*1000;
  633. //}
  634. for (int i = 0; i < isItemSet.GetSize(); i++)
  635. {
  636. isItemSet[i]->SetDisplayOrder(uiReadingOrder);
  637. uiReadingOrder++;
  638. }
  639. if (fGenerating)
  640. {
  641. fRetVal = GenerateItem(ihItemHandler,
  642. isItemSet, &pOutBuffer, uiStartPos);
  643. if (pBuff != pOutBuffer)
  644. {
  645. delete pBuff;
  646. pBuff = NULL;
  647. pBuff = pOutBuffer; // The old memory has already been deleted.
  648. }
  649. else
  650. {
  651. fRetVal = FALSE;
  652. }
  653. }
  654. else
  655. {
  656. fRetVal = EnumerateItem(ihItemHandler,
  657. isItemSet);
  658. }
  659. isItemSet.ClearItemSet();
  660. uiTemp += 1;
  661. if (!fRetVal)
  662. {
  663. fRetVal = TRUE;
  664. break;
  665. }
  666. wmiRet = GetNextItemSet(dwCount, pBuff, isItemSet, dbidSectionId, uiStartPos);
  667. if (uiStartPos > uiTemp)
  668. uiTemp = uiStartPos;
  669. if (dwCount%20 == 0)
  670. {
  671. if (uiNewPercentage < 100)
  672. uiNewPercentage++;
  673. ihItemHandler.SetProgressIndicator(uiNewPercentage);
  674. }
  675. }
  676. // If we were generating the file,
  677. // we're done.
  678. // ==============================
  679. if (fGenerating)
  680. break;
  681. if (uiNewPercentage < 100)
  682. uiNewPercentage++;
  683. ihItemHandler.SetProgressIndicator(uiNewPercentage);
  684. }
  685. uiTemp = 0;
  686. // Now, we get to search and replace the locale IDs,
  687. // and actually write out the file.
  688. // =================================================
  689. if (fRetVal && fGenerating)
  690. {
  691. fRetVal = WriteNewFile(pOutBuffer);
  692. }
  693. }
  694. if (pBuff)
  695. delete pBuff;
  696. ihItemHandler.SetProgressIndicator(100);
  697. }
  698. catch (CFileException *pFileException)
  699. {
  700. fRetVal = FALSE;
  701. ReportFileError(m_pstrFileName, m_didFileId, pFileException, ihItemHandler);
  702. pFileException->Delete();
  703. }
  704. catch (CUnicodeException *pUnicodeException)
  705. {
  706. CLocation loc;
  707. loc.SetGlobalId(CGlobalId(m_didFileId, otFile));
  708. loc.SetView(vProjWindow);
  709. ReportUnicodeError(pUnicodeException, ihItemHandler, loc);
  710. pUnicodeException->Delete();
  711. fRetVal = FALSE;
  712. }
  713. catch (CMemoryException *pMemoryException)
  714. {
  715. CLString strContext;
  716. ihItemHandler.IssueMessage(esError, strContext,
  717. g_hDll, IDS_WMI_NO_MEMORY, g_locNull);
  718. fRetVal = FALSE;
  719. pMemoryException->Delete();
  720. }
  721. catch (CException *pException)
  722. {
  723. CLocation loc;
  724. loc.SetGlobalId(CGlobalId(m_didFileId, otFile));
  725. loc.SetView(vProjWindow);
  726. ReportException(pException, ihItemHandler, loc);
  727. pException->Delete();
  728. fRetVal = FALSE;
  729. }
  730. return fRetVal;
  731. }
  732. //*****************************************************************************
  733. //
  734. // CWMILocFile::WriteWaterMark
  735. //
  736. //*****************************************************************************
  737. void CWMILocFile::WriteWaterMark()
  738. {
  739. LTASSERT(NULL != m_pOpenTargetFile);
  740. LTASSERT(NULL != m_pOpenSourceFile);
  741. // Do we need to support this?
  742. }
  743. //*****************************************************************************
  744. //
  745. // CWMILocFile::GetNextQualifierPos
  746. //
  747. //*****************************************************************************
  748. BOOL CWMILocFile::GetNextQualifierPos(const wchar_t *wTmp, const wchar_t *pBuff, UINT &uiNewPos, UINT uiStartingPos)
  749. {
  750. BOOL bRet = FALSE;
  751. UINT uiPos = uiStartingPos;
  752. BOOL bComment = FALSE;
  753. if (pBuff && wcslen(pBuff) < uiStartingPos)
  754. return FALSE;
  755. wchar_t *pTemp = (wchar_t *)pBuff;
  756. pTemp += uiStartingPos;
  757. while (TRUE)
  758. {
  759. wchar_t *pszTest2 = NULL;
  760. pszTest2 = wcsstr(pTemp, L":");
  761. if (pszTest2)
  762. {
  763. uiPos = pszTest2 - pBuff + 1;
  764. // Look for the "amended" keyword.
  765. // ==============================
  766. WCHAR temp = pszTest2[0];
  767. while(temp == L' ' || temp == L'\0' || temp == L':')
  768. {
  769. pszTest2++;
  770. temp = pszTest2[0];
  771. }
  772. if (temp != L'\0')
  773. {
  774. wchar_t wTmp2[8];
  775. wcsncpy(wTmp2, pszTest2, 7);
  776. wTmp2[7] = '\0';
  777. if (!wcsicmp(wTmp2, wTmp))
  778. {
  779. bRet = TRUE;
  780. }
  781. }
  782. // If here, we found a non-match, so try again.
  783. // ============================================
  784. if (!bRet)
  785. pTemp = pszTest2 + 1;
  786. else
  787. break;
  788. }
  789. else
  790. {
  791. break;
  792. }
  793. }
  794. if (bRet)
  795. uiNewPos = uiPos;
  796. return bRet;
  797. }
  798. //*****************************************************************************
  799. //
  800. // CWMILocFile::GetCurrentNamespace
  801. //
  802. //*****************************************************************************
  803. wchar_t *CWMILocFile::GetCurrentNamespace(wchar_t *pstr, UINT uPos)
  804. {
  805. wchar_t *pTemp = pstr;
  806. _bstr_t pstrNamespace = m_sCurrentNamespace;
  807. UINT uiCurrPos = 0;
  808. BOOL bComment = FALSE;
  809. wchar_t wTmp[] = L"#pragma namespace";
  810. int iHCLen = wcslen(wTmp);
  811. // Find the first occurrence of the namespace
  812. // before the current position.
  813. if (pstrNamespace.length() > 0)
  814. pTemp = wcsstr(pTemp, pstrNamespace); // Jump directly to the existing one.
  815. while (uiCurrPos < uPos)
  816. {
  817. wchar_t *pszTest2 = NULL;
  818. pszTest2 = wcsstr(pTemp, L"#");
  819. if (pszTest2)
  820. {
  821. // First, go back and make sure this isn't a comment line.
  822. // =======================================================
  823. bComment = FALSE;
  824. wchar_t *pComment = pszTest2;
  825. while (pComment > pstr)
  826. {
  827. if (pComment[0] == L'\n' || pComment[0] == L'\r')
  828. {
  829. if (pComment[1] == L'/' && pComment[2] == L'/')
  830. {
  831. bComment = TRUE;
  832. }
  833. else
  834. {
  835. bComment = FALSE;
  836. }
  837. break;
  838. }
  839. pComment--;
  840. }
  841. if (!bComment)
  842. {
  843. wchar_t wTmp2[100];
  844. wcsncpy(wTmp2, pszTest2, 17);
  845. wTmp2[17] = '\0';
  846. if (!wcsicmp(wTmp2, wTmp))
  847. {
  848. uiCurrPos += (pszTest2 - pTemp);
  849. wchar_t *pszTest3 = wcschr(pszTest2, L')');
  850. int iLen = (pszTest3 - pszTest2);
  851. wchar_t *pszTmpNS = new wchar_t[iLen*2+1];
  852. if (pszTmpNS)
  853. {
  854. pszTest2 += iHCLen + 2; // skip quote and open parent.
  855. wcsncpy(pszTmpNS, pszTest2, iLen - 2); // strip quotes.
  856. pszTmpNS[iLen-iHCLen-3] = '\0';
  857. pstrNamespace = pszTmpNS;
  858. pTemp = pszTest2 + 1;
  859. delete pszTmpNS;
  860. }
  861. }
  862. else
  863. {
  864. pTemp = pszTest2 + 1;
  865. }
  866. }
  867. else
  868. {
  869. pTemp = pszTest2 + 1;
  870. }
  871. }
  872. else
  873. {
  874. break;
  875. }
  876. }
  877. int iLen = wcslen(pstrNamespace) ;
  878. wchar_t *pNew = new wchar_t[iLen*2+1];
  879. if (pNew)
  880. {
  881. wcsncpy(pNew, (const wchar_t *)pstrNamespace, iLen);
  882. pNew[iLen] = '\0';
  883. }
  884. return pNew;
  885. }
  886. //*****************************************************************************
  887. //
  888. // CWMILocFile::GetNextItemSet
  889. //
  890. //*****************************************************************************
  891. CWMILocFile::WMIFileError CWMILocFile::GetNextItemSet(
  892. DWORD dwCurrPos,
  893. const _bstr_t &pstrCurrentLine,
  894. CLocItemSet &aNewItem,
  895. const DBID &dbidSection,
  896. UINT &uiStartPos)
  897. {
  898. // In this function, we know there is an
  899. // "amended" keyword in here somewhere.
  900. // We want to know to which class and/or
  901. // property does it belong? If we don't
  902. // have enough data to figure it out,
  903. // we need to send back a WMIIncompleteObj
  904. // code.
  905. // ======================================
  906. UINT uiCurrPos = 0;
  907. WMIFileError feRetCode = WMINoError;
  908. _bstr_t sQualifierName, sRawValue, sPropName, sClassName;
  909. BOOL bClass = FALSE;
  910. int iLen = pstrCurrentLine.length() + 1;
  911. iLen *= 2;
  912. // Get the position of the keyword
  913. // "amended" in this chunk of text.
  914. wchar_t *wTemp = new wchar_t[iLen+1];
  915. if (!wTemp)
  916. {
  917. feRetCode = WMIOOM;
  918. return feRetCode;
  919. }
  920. if (GetNextQualifierPos(L"amended", pstrCurrentLine, uiCurrPos, uiStartPos))
  921. {
  922. BOOL bArray = FALSE;
  923. uiStartPos = uiCurrPos;
  924. // Find the qualifier name and value.
  925. // wTemp = Top of File
  926. // wTmp2 = "Amended" keyword
  927. // wQfrVal = Opening bracket
  928. // wBkwd = floating pointer.
  929. wchar_t *wTmp2 = NULL, *wBkwd = NULL, *wQfrVal = NULL;
  930. wcscpy(wTemp, pstrCurrentLine);
  931. wTemp[iLen] = '\0';
  932. wTmp2 = wTemp;
  933. wTmp2 += (uiCurrPos - 1); // the "Amended" keyword.
  934. wQfrVal = FindTop(wTmp2, wTemp, bArray);
  935. if (!wQfrVal) // Make sure we had an open parenth
  936. {
  937. feRetCode = WMISyntaxError;
  938. delete wTemp;
  939. return feRetCode;
  940. }
  941. // Find the beginning of the qualifier name.
  942. wBkwd = wQfrVal;
  943. while (wBkwd[0] != L',' && wBkwd[0] != L'[' && wBkwd >= wTemp)
  944. {
  945. wBkwd--;
  946. }
  947. if (wBkwd[0] != L',' && wBkwd[0] != L'[') // Make sure we had a valid qualifier name.
  948. {
  949. feRetCode = WMISyntaxError;
  950. delete wTemp;
  951. return feRetCode;
  952. }
  953. WCHAR *token;
  954. UINT uiLen;
  955. wBkwd += 1;
  956. wchar_t wTmpBuff[256];
  957. wcsncpy(wTmpBuff, wBkwd, wQfrVal - wBkwd);
  958. wTmpBuff[wQfrVal - wBkwd] = '\0';
  959. sQualifierName = wTmpBuff;
  960. GetQualifierValue(wTemp, uiStartPos, sRawValue, uiLen);
  961. // Finally, populate the CLocItem.
  962. // ===============================
  963. LTASSERT(aNewItem.GetSize() == 0);
  964. if (feRetCode == WMINoError)
  965. {
  966. CLocItem *pNewItem;
  967. try
  968. {
  969. // Now we have a value, but it may be an
  970. // array. If so, we need to add one CLocItem
  971. // for each value in the array.
  972. VectorString arrValues;
  973. if (bArray)
  974. ParseArray(sRawValue, arrValues);
  975. else
  976. arrValues.push_back(sRawValue);
  977. for (int i = 0; i < arrValues.size(); i++)
  978. {
  979. wchar_t szTmp[20];
  980. swprintf(szTmp, L"%ld", dwCurrPos);
  981. _bstr_t sValue = arrValues.at(i);
  982. pNewItem = new CLocItem;
  983. CLocUniqueId uid;
  984. CPascalString sTempString;
  985. sTempString = sQualifierName;
  986. sTempString += szTmp;
  987. uid.GetResId().SetId(sTempString) ;
  988. if (bClass)
  989. uid.GetTypeId().SetId(wltClassName);
  990. else
  991. uid.GetTypeId().SetId(wltPropertyName);
  992. uid.SetParentId(dbidSection);
  993. pNewItem->SetUniqueId(uid);
  994. CLocString lsString;
  995. CPascalString pstrComment, pstrText;
  996. pstrText = sValue;
  997. pNewItem->SetIconType(CIT::String);
  998. pNewItem->SetInstructions(pstrComment);
  999. lsString.SetString(pstrText);
  1000. SetFlags(pNewItem, lsString);
  1001. pNewItem->SetLocString(lsString);
  1002. aNewItem.Add(pNewItem);
  1003. }
  1004. }
  1005. catch (CMemoryException *pMemoryException)
  1006. {
  1007. feRetCode = WMIOOM;
  1008. pMemoryException->Delete();
  1009. }
  1010. }
  1011. else
  1012. {
  1013. LTTRACE("Unable to process line '%ls'",
  1014. (const WCHAR *)pstrCurrentLine);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. feRetCode = WMINoMore;
  1020. }
  1021. uiStartPos = uiCurrPos;
  1022. delete wTemp;
  1023. return feRetCode;
  1024. }
  1025. const UINT WMI_MAX_CONTEXT = 256;
  1026. //*****************************************************************************
  1027. //
  1028. // CWMILocFile::GetFullContext
  1029. //
  1030. //*****************************************************************************
  1031. void CWMILocFile::GetFullContext(
  1032. CLString &strContext)
  1033. const
  1034. {
  1035. CLString strFormat;
  1036. strFormat.LoadString(g_hDll, IDS_WMI_FULL_CONTEXT);
  1037. strContext.Empty();
  1038. _sntprintf(strContext.GetBuffer(WMI_MAX_CONTEXT), WMI_MAX_CONTEXT,
  1039. (const TCHAR *)strFormat,
  1040. (const WCHAR *)m_pstrFileName, (UINT)m_uiLineNumber);
  1041. strContext.ReleaseBuffer();
  1042. }
  1043. //*****************************************************************************
  1044. //
  1045. // CWMILocFile::ReportFileError
  1046. //
  1047. //*****************************************************************************
  1048. void CWMILocFile::ReportFileError(
  1049. const _bstr_t &pstrFileName,
  1050. const DBID &didFileId,
  1051. CFileException *pFileException,
  1052. CReporter &Reporter)
  1053. const
  1054. {
  1055. CLString strContext;
  1056. CLString strMessage;
  1057. const UINT MAX_MESSAGE = 256;
  1058. TCHAR szFileErrorMessage[MAX_MESSAGE];
  1059. CLocation loc;
  1060. pFileException->GetErrorMessage(szFileErrorMessage, MAX_MESSAGE);
  1061. strMessage.Format(g_hDll, IDS_WMI_BAD_FILE, (const WCHAR *)pstrFileName,
  1062. szFileErrorMessage);
  1063. GetFullContext(strContext);
  1064. loc.SetGlobalId(CGlobalId(didFileId, otFile));
  1065. loc.SetView(vProjWindow);
  1066. Reporter.IssueMessage(esError, strContext, strMessage, loc);
  1067. }
  1068. //*****************************************************************************
  1069. //
  1070. // CWMILocFile::ReportUnicodeError
  1071. //
  1072. //*****************************************************************************
  1073. void CWMILocFile::ReportUnicodeError(
  1074. CUnicodeException *pUnicodeException,
  1075. CReporter &Reporter,
  1076. const CLocation &Location)
  1077. const
  1078. {
  1079. CLString strContext;
  1080. CLString strMessage;
  1081. const UINT MAX_MESSAGE = 256;
  1082. TCHAR szUnicodeErrorMessage[MAX_MESSAGE];
  1083. CLocation loc;
  1084. pUnicodeException->GetErrorMessage(szUnicodeErrorMessage, MAX_MESSAGE);
  1085. strMessage.Format(g_hDll, IDS_WMI_UNICODE_ERROR, szUnicodeErrorMessage);
  1086. GetFullContext(strContext);
  1087. Reporter.IssueMessage(esError, strContext, strMessage, Location,
  1088. IDH_UNICODE_CONV);
  1089. }
  1090. //*****************************************************************************
  1091. //
  1092. // CWMILocFile::ReportException
  1093. //
  1094. //*****************************************************************************
  1095. void CWMILocFile::ReportException(
  1096. CException *pException,
  1097. CReporter &Reporter,
  1098. const CLocation &Location)
  1099. const
  1100. {
  1101. CLString strContext;
  1102. CLString strMessage;
  1103. const UINT MAX_MESSAGE = 256;
  1104. TCHAR szErrorMessage[MAX_MESSAGE];
  1105. pException->GetErrorMessage(szErrorMessage, MAX_MESSAGE);
  1106. strMessage.Format(g_hDll, IDS_WMI_EXCEPTION, szErrorMessage);
  1107. GetFullContext(strContext);
  1108. Reporter.IssueMessage(esError, strContext, strMessage, Location);
  1109. }
  1110. //*****************************************************************************
  1111. //
  1112. // CWMILocFile::GetQualifierValue
  1113. //
  1114. //*****************************************************************************
  1115. BOOL CWMILocFile::GetQualifierValue(wchar_t *pBuffer, UINT &uiPos, _bstr_t &sValue, UINT &uiPhysLen)
  1116. {
  1117. // This needs to read up the text of the qualifier,
  1118. // strip out the quotes and carriage returns, and
  1119. // return it and its *physical* length-in-file.
  1120. BOOL fRetVal = FALSE;
  1121. BOOL bArray = FALSE;
  1122. wchar_t *pTemp = pBuffer;
  1123. pTemp += uiPos;
  1124. pTemp = FindTop(pTemp, pBuffer, bArray);
  1125. if (pTemp)
  1126. {
  1127. wchar_t tempBuff[4096];
  1128. int iCount = 0;
  1129. pTemp++; // Step past this character.
  1130. uiPhysLen = 0;
  1131. WCHAR *token = pTemp;
  1132. BOOL bEnd = FALSE;
  1133. while (!bEnd)
  1134. {
  1135. uiPhysLen++; // Count every character.
  1136. WCHAR *Test;
  1137. switch(*token)
  1138. {
  1139. case L'\0':
  1140. bEnd = TRUE;
  1141. break;
  1142. case L'\n':
  1143. case L'\r':
  1144. case L'\t':
  1145. break;
  1146. case L'\"':
  1147. if (!iCount)
  1148. break;
  1149. case L')':
  1150. case L'}':
  1151. Test = token - 1;
  1152. while (TRUE)
  1153. {
  1154. if (*Test == L' ' || *Test == L'\r' || *Test == L'\n' || *Test == L'\t')
  1155. {
  1156. Test--;
  1157. continue;
  1158. }
  1159. if (*Test == L'\"')
  1160. {
  1161. bEnd = TRUE;
  1162. }
  1163. else
  1164. {
  1165. tempBuff[iCount] = *token;
  1166. iCount++;
  1167. }
  1168. break;
  1169. }
  1170. break;
  1171. default:
  1172. tempBuff[iCount] = *token;
  1173. iCount++;
  1174. break;
  1175. }
  1176. token++;
  1177. }
  1178. if (tempBuff[iCount-1] == L'\"')
  1179. tempBuff[iCount-1] = '\0';
  1180. else
  1181. tempBuff[iCount] = '\0';
  1182. sValue = tempBuff;
  1183. fRetVal = TRUE;
  1184. }
  1185. uiPhysLen -= 1; // We want to keep the closing parenth.
  1186. return fRetVal;
  1187. }
  1188. //*****************************************************************************
  1189. //
  1190. // CWMILocFile::SetQualifierValue
  1191. //
  1192. //*****************************************************************************
  1193. BOOL CWMILocFile::SetQualifierValue(wchar_t *pIn, wchar_t **pOut, UINT &uiPos, _bstr_t &sValue, UINT &uiLen, BOOL bQuotes)
  1194. {
  1195. // This needs to write the localized qualifier value
  1196. // and erase *uiLen* characters.
  1197. // uiPos will need to be updated with the *new*
  1198. // position of this qualifier.
  1199. BOOL fRetVal = FALSE;
  1200. wchar_t *pStart = pIn + uiPos;
  1201. BOOL bArray = FALSE;
  1202. pStart = FindTop(pStart, pIn, bArray);
  1203. if (pStart)
  1204. {
  1205. int iNewLen = wcslen(sValue);
  1206. int iLen = wcslen(pIn) + 3;
  1207. if (iNewLen > uiLen) // The length of the new buffer
  1208. iLen += (iNewLen - uiLen); // If the new value is longer, add it.
  1209. pStart++; // jump past the '(' character. uiLen starts now.
  1210. int iPos = pStart-pIn; // The current position.
  1211. iLen *= 2;
  1212. wchar_t *pNew = new wchar_t[iLen+3];
  1213. if (pNew)
  1214. {
  1215. int iTempPos = 0;
  1216. wcsncpy(pNew, pIn, iPos); // Copy the initial part of the file.
  1217. if (bQuotes)
  1218. pNew[iPos] = '\"';
  1219. pNew[iPos+1] = '\0'; // Null terminate
  1220. wcscat(pNew, sValue); // Add the new value.
  1221. iPos += 1 + wcslen(sValue); // Jump past the value
  1222. if (bQuotes)
  1223. pNew[iPos] = '\"';
  1224. pNew[iPos+1] = '\0'; // Null terminate the value.
  1225. pStart += uiLen; // Jump past the current value.
  1226. iTempPos = iPos;
  1227. iPos = wcslen(pIn) - (pStart-pIn); // Calculate the length of the rest of the file.
  1228. wcsncat(pNew, pStart, iPos); // Append the rest of the file to the new buffer.
  1229. pStart = pNew + iLen;
  1230. pStart = FindPrevious(pStart, L";", pNew);
  1231. pStart[1] = L'\r';
  1232. pStart[2] = L'\n';
  1233. pStart[3] = L'\0';
  1234. *pOut = pNew;
  1235. fRetVal = TRUE;
  1236. }
  1237. }
  1238. // Adjust the position.
  1239. int iNewLen = wcslen(sValue);
  1240. if (iNewLen < uiLen)
  1241. uiPos -= (uiLen - iNewLen);
  1242. else
  1243. uiPos += (iNewLen - uiLen);
  1244. uiPos += 3;
  1245. return fRetVal;
  1246. }
  1247. //*****************************************************************************
  1248. //
  1249. // CWMILocFile::WriteNewFile
  1250. //
  1251. //*****************************************************************************
  1252. BOOL CWMILocFile::WriteNewFile(wchar_t *pBuffer)
  1253. {
  1254. // This needs to seek and replace all instances of the
  1255. // original Locale with the new one.
  1256. // ===================================================
  1257. BOOL fRetVal = FALSE, fSuccess = TRUE;
  1258. UINT uiPos = 0, uiStartingPos = 0;
  1259. int uiLen = wcslen(pBuffer);
  1260. _bstr_t sThisLocale, sTargetLocale;
  1261. wchar_t wOldCodePage[30], wNewCodePage[30];
  1262. swprintf(wOldCodePage, L"_%X", m_wSourceId );
  1263. swprintf(wNewCodePage, L"_%X", m_wTargetId );
  1264. if (m_wSourceId != m_wTargetId)
  1265. {
  1266. wchar_t *pLocale = wcsstr(pBuffer, wOldCodePage);
  1267. while (pLocale != NULL)
  1268. {
  1269. for (int i = 0; i < wcslen(wOldCodePage); i++)
  1270. {
  1271. pLocale[i] = wNewCodePage[i];
  1272. }
  1273. pLocale = wcsstr(pLocale, wOldCodePage);
  1274. }
  1275. // Now look for the locale if
  1276. // it was converted to a decimal.
  1277. // ==============================
  1278. swprintf(wOldCodePage, L"(%ld)", m_wSourceId );
  1279. swprintf(wNewCodePage, L"(%ld)", m_wTargetId );
  1280. pLocale = wcsstr(pBuffer, wOldCodePage);
  1281. while (pLocale != NULL)
  1282. {
  1283. for (int i = 0; i < wcslen(wOldCodePage); i++)
  1284. {
  1285. pLocale[i] = wNewCodePage[i];
  1286. }
  1287. pLocale = wcsstr(pLocale, wOldCodePage);
  1288. }
  1289. }
  1290. if (fSuccess)
  1291. {
  1292. fRetVal = TRUE;
  1293. // Finally, write out the buffer to a brand new file
  1294. // =================================================
  1295. while (uiLen >= 0)
  1296. {
  1297. if (fwrite(pBuffer, sizeof(wchar_t), (uiLen > 4096) ? 4096: uiLen, m_pOpenTargetFile) < 0)
  1298. {
  1299. fRetVal = FALSE;
  1300. break;
  1301. }
  1302. else
  1303. {
  1304. fRetVal = TRUE;
  1305. pBuffer += 4096;
  1306. uiLen -= 4096;
  1307. }
  1308. fflush(m_pOpenTargetFile);
  1309. }
  1310. }
  1311. return fRetVal;
  1312. }
  1313. //*****************************************************************************
  1314. //
  1315. // CWMILocFile::FindPrevious
  1316. //
  1317. //*****************************************************************************
  1318. wchar_t *CWMILocFile::FindPrevious(wchar_t *pBuffer, const wchar_t *pFind, const wchar_t *pTop)
  1319. {
  1320. wchar_t *pRet = NULL;
  1321. WCHAR t1, t2;
  1322. int iLen = wcslen(pFind);
  1323. BOOL bFound = FALSE;
  1324. pRet = pBuffer;
  1325. while (pRet >= pTop)
  1326. {
  1327. t2 = pRet[0];
  1328. for (int i = 0; i < iLen; i++)
  1329. {
  1330. t1 = pFind[i];
  1331. if (t1 == t2)
  1332. {
  1333. bFound = TRUE;
  1334. break;
  1335. }
  1336. }
  1337. if (bFound)
  1338. break;
  1339. pRet--;
  1340. }
  1341. if (pRet <= pTop)
  1342. pRet = NULL;
  1343. return pRet;
  1344. }
  1345. //*****************************************************************************
  1346. //
  1347. // CWMILocFile::FindTop
  1348. //
  1349. //*****************************************************************************
  1350. wchar_t *CWMILocFile::FindTop(wchar_t *wTmp2, wchar_t *wTop, BOOL &bArray)
  1351. {
  1352. wchar_t *wQfrVal = FindPrevious(wTmp2, L"({", wTop);
  1353. while (wQfrVal)
  1354. {
  1355. WCHAR *pQT = wQfrVal + 1;
  1356. BOOL bFound = FALSE;
  1357. while (TRUE)
  1358. {
  1359. if (*pQT != L' ' && *pQT != L'\t' && *pQT != L'\r' && *pQT != L'\n')
  1360. {
  1361. if (*pQT == L'\"')
  1362. {
  1363. bFound = TRUE;
  1364. }
  1365. break;
  1366. }
  1367. pQT++;
  1368. }
  1369. if (!bFound)
  1370. {
  1371. wQfrVal --;
  1372. wQfrVal = FindPrevious(wQfrVal, L"({", wTop);
  1373. }
  1374. else
  1375. break;
  1376. }
  1377. if (wQfrVal)
  1378. {
  1379. if (wQfrVal[0] == L'{')
  1380. bArray = TRUE;
  1381. }
  1382. return wQfrVal;
  1383. }
  1384. //*****************************************************************************
  1385. //
  1386. // CWMILocFile::ParseArray
  1387. //
  1388. //*****************************************************************************
  1389. void CWMILocFile::ParseArray(wchar_t *pIn, VectorString &arrOut)
  1390. {
  1391. wchar_t Buff[4096];
  1392. wchar_t *pLast = pIn;
  1393. if (*pLast == L'\"')
  1394. pLast++;
  1395. wchar_t *pFind = wcsstr(pIn, L"\",");
  1396. arrOut.clear();
  1397. while (pFind)
  1398. {
  1399. wchar_t temp = pFind[-1];
  1400. if (temp == '\\')
  1401. {
  1402. pFind++;
  1403. pFind = wcsstr(pFind, L"\",");
  1404. continue;
  1405. }
  1406. wcsncpy(Buff, pLast, pFind-pLast);
  1407. Buff[pFind-pLast] = '\0';
  1408. arrOut.push_back(_bstr_t(Buff));
  1409. // Now move pFind to the next valid char.
  1410. while (pFind[0] == L'\n' ||
  1411. pFind[0] == L'\r' ||
  1412. pFind[0] == L' ' ||
  1413. pFind[0] == L',' ||
  1414. pFind[0] == L'\"' )
  1415. pFind++;
  1416. pLast = pFind ;
  1417. pFind = wcsstr(pFind, L"\",");
  1418. }
  1419. wcscpy(Buff, pLast);
  1420. if (Buff[wcslen(Buff)-1] == L'\"')
  1421. Buff[wcslen(Buff)-1] = L'\0'; // strip off that trailing quote.
  1422. else
  1423. Buff[wcslen(Buff)] = L'\0'; // strip off that trailing quote.
  1424. arrOut.push_back(_bstr_t(Buff));
  1425. return;
  1426. }
  1427. //*****************************************************************************
  1428. //
  1429. // CVC::ValidateString
  1430. //
  1431. //*****************************************************************************
  1432. CVC::ValidationCode ValidateString(
  1433. const CLocTypeId &,
  1434. const CLocString &clsOutputLine,
  1435. CReporter &repReporter,
  1436. const CLocation &loc,
  1437. const CLString &strContext)
  1438. {
  1439. CVC::ValidationCode vcRetVal = CVC::NoError;
  1440. CLString strMyContext = strContext;
  1441. if (strMyContext.GetLength() == 0)
  1442. {
  1443. strMyContext.LoadString(g_hDll, IDS_WMI_GENERIC_LOCATION);
  1444. }
  1445. loc; repReporter; clsOutputLine;
  1446. /*
  1447. if (clsOutputLine.HasHotKey())
  1448. {
  1449. vcRetVal = CVC::UpgradeValue(vcRetVal, CVC::Warning);
  1450. repReporter.IssueMessage(esWarning, strMyContext, g_hDll,
  1451. IDS_WMI_VAL_HOTKEY, loc);
  1452. }
  1453. _bstr_t pstrBadChars;
  1454. UINT uiBadPos;
  1455. pstrBadChars.SetString(L"\n\ra", (UINT)3);
  1456. if (pstrOutput.FindOneOf(pstrBadChars, 0, uiBadPos))
  1457. {
  1458. vcRetVal = CVC::UpgradeValue(vcRetVal, CVC::Error);
  1459. repReporter.IssueMessage(esError, strMyContext, g_hDll,
  1460. IDS_WMI_VAL_BAD_CHARS, loc);
  1461. }
  1462. */
  1463. return vcRetVal;
  1464. }