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.

2038 lines
52 KiB

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