|
|
/*++
Copyright (C) 1996-1999 Microsoft Corporation
Module Name:
WMILFILE.CPP
Abstract:
Implementation of CWmiLocFile, the MOF parser for Localization Studio
History:
--*/ #include "precomp.h"
#include "stdafx.h"
#include <buildnum.h>
#include <helpids.h>
#include "WMIparse.h"
#include "resource.h"
#include "WMIlprs.h"
#include "WMIlfile.h"
#include <malloc.h>
//*****************************************************************************
//
// CWMILocFile::CWMILocFile
//
//*****************************************************************************
CWMILocFile::CWMILocFile( ILocParser *pParentClass) { //
// C.O.M. initialization
//
m_pParentClass = pParentClass; m_sCurrentNamespace = ""; m_ulRefCount = 0;
//
// WMI file initialization
//
m_uiLineNumber = 0; m_pOpenSourceFile = NULL; m_pOpenTargetFile = NULL;
AddRef(); IncrementClassCount(); }
//*****************************************************************************
//
// CWMILocFile::GetFileDescriptions
//
//*****************************************************************************
void CWMILocFile::GetFileDescriptions( CEnumCallback &cb) { EnumInfo eiFileInfo; CLString strDesc; eiFileInfo.szAbbreviation = NULL;
LTVERIFY(strDesc.LoadString(g_hDll, IDS_WMI_DESC));
eiFileInfo.szDescription = (const TCHAR *)strDesc; eiFileInfo.ulValue = ftWMIFileType;
cb.ProcessEnum(eiFileInfo); }
//*****************************************************************************
//
// CWMILocFile::AddRef
//
//*****************************************************************************
ULONG CWMILocFile::AddRef(void) { if (m_pParentClass != NULL) { m_pParentClass->AddRef(); } return m_ulRefCount++; }
//*****************************************************************************
//
// CWMILocFile::Release
//
//*****************************************************************************
ULONG CWMILocFile::Release(void) { LTASSERT(m_ulRefCount != 0);
if (m_pParentClass != NULL) { m_pParentClass->Release(); }
m_ulRefCount--; if (m_ulRefCount == 0) { delete this; return 0; } return m_ulRefCount; }
//*****************************************************************************
//
// CWMILocFile::QueryInterface
//
//*****************************************************************************
HRESULT CWMILocFile::QueryInterface( REFIID iid, LPVOID *ppvObj) { if (m_pParentClass != NULL) { return m_pParentClass->QueryInterface(iid, ppvObj); } else { SCODE scRetVal = E_NOINTERFACE;
*ppvObj = NULL; if (iid == IID_IUnknown) { *ppvObj = (IUnknown *)this; scRetVal = S_OK; } else if (iid == IID_ILocFile) { *ppvObj = (ILocFile *)this; scRetVal = S_OK; }
if (scRetVal == S_OK) { AddRef(); } return ResultFromScode(scRetVal); } }
//*****************************************************************************
//
// CWMILocFile::AssertValidInterface
//
//*****************************************************************************
void CWMILocFile::AssertValidInterface(void) const { AssertValid(); }
//*****************************************************************************
//
// CWMILocFile::OpenFile
//
//*****************************************************************************
BOOL CWMILocFile::OpenFile( const CFileSpec &fsFile, CReporter &Reporter) { LTTRACEPOINT("OpenFile()"); BOOL fRetCode; LTASSERT(m_pOpenTargetFile == NULL); fRetCode = FALSE;
m_didFileId = fsFile.GetFileId(); m_pstrFileName = fsFile.GetFileName(); if (m_pOpenSourceFile != NULL) { fclose(m_pOpenSourceFile); m_pOpenSourceFile = NULL; }
// We are just going to open the file.
// and save the handle.
// ===================================
try {
m_pOpenSourceFile = fopen(_T(m_pstrFileName), "rb");
if (!m_pOpenSourceFile) { fclose(m_pOpenSourceFile); m_pOpenSourceFile = NULL; } else { fRetCode = TRUE; }
} catch (CMemoryException *pMemoryException) { CLString strContext;
strContext.LoadString(g_hDll, IDS_WMI_GENERIC_LOCATION); Reporter.IssueMessage(esError, strContext, g_hDll, IDS_WMI_NO_MEMORY, g_locNull);
pMemoryException->Delete(); } return fRetCode; }
//*****************************************************************************
//
// CWMILocFile::GetFileType
//
//*****************************************************************************
FileType CWMILocFile::GetFileType(void) const { //
// Just return some number that isn't ftUnknown...
//
return ftWMIFileType; }
//*****************************************************************************
//
// CWMILocFile::GetFileTypeDescription
//
//*****************************************************************************
void CWMILocFile::GetFileTypeDescription( CLString &strDesc) const { LTVERIFY(strDesc.LoadString(g_hDll, IDS_WMI_DESC)); return; }
//*****************************************************************************
//
// CWMILocFile::GetAssociatedFiles
//
//*****************************************************************************
BOOL CWMILocFile::GetAssociatedFiles( CStringList &lstFiles) const { LTASSERT(lstFiles.GetCount() == 0); lstFiles.RemoveAll(); return FALSE; }
//*****************************************************************************
//
// CWMILocFile::EnumerateFile
//
//*****************************************************************************
BOOL CWMILocFile::EnumerateFile( CLocItemHandler &ihItemHandler, const CLocLangId &lid, const DBID &dbidFileId) { BOOL bRet = TRUE; DBID dbidThisId = dbidFileId;
LTTRACEPOINT("EnumerateFile()"); if (m_pOpenSourceFile == NULL) { return FALSE; }
// Enumerate file will need to:
// * Parse the MOF.
// * Walk through all qualifiers. For each "Amended" qualifier,
// send back a CLocItem whose key is namespace, class, property and qualifier name.
// * Fail if the language ID does not match that of LocaleID.
// * Parent objects are namespaces, classes
// =============================================================
m_cpSource = lid.GetCodePage(cpAnsi); m_wSourceId = lid.GetLanguageId();
ihItemHandler.SetProgressIndicator(0);
bRet = ReadLines(ihItemHandler, dbidFileId, FALSE);
return bRet; }
//*****************************************************************************
//
// CWMILocFile::GenerateFile
//
//*****************************************************************************
BOOL CWMILocFile::GenerateFile( const CPascalString &pstrTargetFile, CLocItemHandler &ihItemHandler, const CLocLangId &lidSource, const CLocLangId &lidTarget, const DBID &dbidParent) { LTASSERT(m_pOpenTargetFile == NULL); BOOL fRetVal = TRUE;
if (m_pOpenSourceFile== NULL) { return FALSE; } // Generate File needs to:
// * Parse the MOF.
// * Walk through all qualifiers. For each "Amended" qualifier,
// send back a CLocItem whose key is namespace, class, property and qualifier name.
// * Replace all Amended qualifiers with localized text
// * Replace all occurrences of the locale ID in namespaces and qualifiers
// with the new one.
// =================================================================================
m_cpSource = lidSource.GetCodePage(cpAnsi); m_cpTarget = lidTarget.GetCodePage(cpAnsi);
m_wSourceId = lidSource.GetLanguageId(); m_wTargetId = lidTarget.GetLanguageId(); try { CFileException excFile; fRetVal = FALSE; if (m_pOpenTargetFile != NULL) { fclose(m_pOpenTargetFile); m_pOpenTargetFile = NULL; }
char FileName[255]; strcpy(FileName, _bstr_t(_T(pstrTargetFile)));
// This file must be in Unicode.
HANDLE hFile = CreateFile(FileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if(hFile != INVALID_HANDLE_VALUE) { unsigned char cUnicodeHeader[2] = {0xff, 0xfe}; DWORD dwWrite; WriteFile(hFile, cUnicodeHeader, 2, &dwWrite, NULL); CloseHandle(hFile); } m_pOpenTargetFile = fopen(FileName, "ab");
if (!m_pOpenTargetFile) { fclose(m_pOpenTargetFile); m_pOpenTargetFile = NULL; } else { fRetVal = TRUE; } } catch (CMemoryException *pMemoryException) { CLString strContext; GetFullContext(strContext); ihItemHandler.IssueMessage(esError, strContext, g_hDll, IDS_WMI_NO_MEMORY, g_locNull);
pMemoryException->Delete(); } catch (CFileException *pFileException) { fclose(m_pOpenTargetFile); fRetVal = FALSE;
ReportFileError((const WCHAR *)pstrTargetFile, m_didFileId, pFileException, ihItemHandler);
pFileException->Delete(); }
if (!fRetVal) { return fRetVal; } fRetVal = ReadLines(ihItemHandler, dbidParent, TRUE); fclose(m_pOpenTargetFile);
if (!fRetVal) { DeleteFileW (pstrTargetFile); }
return fRetVal; }
//*****************************************************************************
//
// CWMILocFile::GenerateItem
//
//*****************************************************************************
BOOL CWMILocFile::GenerateItem( CLocItemHandler &ihItemHandler, CLocItemSet &isItemSet, wchar_t **pOutBuffer, UINT &uiStartingPos) {
BOOL fRetVal = TRUE; UINT uiLength;
wchar_t *pTemp = *pOutBuffer;
_bstr_t sQualifierValue;
// If nothing has changed, we can just
// ignore this line.
fRetVal = GetQualifierValue(pTemp, uiStartingPos, sQualifierValue, uiLength); if (fRetVal) { fRetVal = ihItemHandler.HandleItemSet(isItemSet); if (fRetVal) { sQualifierValue = ""; for (int i = 0; i < isItemSet.GetSize(); i++) { CVC::ValidationCode vcRetVal; CLocItem *pLocItem = isItemSet[i]; CLString strContext; CLocation loc; GetFullContext(strContext); loc.SetGlobalId( CGlobalId(pLocItem->GetMyDatabaseId(), otResource)); loc.SetView(vTransTab); CPascalString pstrId, pstrText; pLocItem->GetUniqueId().GetResId().GetId(pstrId); pstrText = pLocItem->GetLocString().GetString(); if (i > 0) sQualifierValue += L"\",\"";
sQualifierValue += (const wchar_t *)pstrText; }
// Set it live in the buffer. We are not going to
// write it to the file until the very end.
fRetVal = SetQualifierValue(pTemp, pOutBuffer, uiStartingPos, sQualifierValue, uiLength); pTemp = *pOutBuffer;
}
} return fRetVal; }
//*****************************************************************************
//
// CWMILocFile::EnumerateItem
//
//*****************************************************************************
BOOL CWMILocFile::EnumerateItem( CLocItemHandler &ihItemHandler, CLocItemSet &isItemSet) { BOOL fRetVal; if (isItemSet.GetSize() != 0) { fRetVal = ihItemHandler.HandleItemSet(isItemSet); } else { fRetVal = TRUE; }
return fRetVal; }
#ifdef _DEBUG
//*****************************************************************************
//
// CWMILocFile::AssertValid
//
//*****************************************************************************
void CWMILocFile::AssertValid(void) const { CLObject::AssertValid(); }
//*****************************************************************************
//
// CWMILocFile::Dump
//
//*****************************************************************************
void CWMILocFile::Dump( CDumpContext &dc) const { CLObject::Dump(dc); }
#endif
//*****************************************************************************
//
// CWMILocFile::~CWMILocFile
//
//*****************************************************************************
CWMILocFile::~CWMILocFile() { DEBUGONLY(AssertValid());
if (m_pOpenSourceFile != NULL) { fclose(m_pOpenSourceFile); m_pOpenSourceFile = NULL; }
DecrementClassCount(); }
//*****************************************************************************
//
// CWMILocFile::SetFlags
//
//*****************************************************************************
void CWMILocFile::SetFlags( CLocItem *pItem, CLocString &lsString) const { ULONG ulItemType;
pItem->SetFDevLock(FALSE); pItem->SetFUsrLock(FALSE); pItem->SetFExpandable(FALSE); LTVERIFY(pItem->GetUniqueId().GetTypeId().GetId(ulItemType)); switch (ulItemType) { case wltNamespaceName: pItem->SetFDisplayable(TRUE); pItem->SetFNoResTable(TRUE); break;
case wltClassName: case wltPropertyName: pItem->SetFDisplayable(FALSE); pItem->SetFNoResTable(FALSE); lsString.SetCodePageType(cpAnsi); lsString.SetStringType(CST::Text); break;
default: LTASSERT(FALSE && "Unexpected item type!"); } }
//*****************************************************************************
//
// CWMILocFile::ReadLines
//
//*****************************************************************************
BOOL CWMILocFile::ReadLines( CLocItemHandler &ihItemHandler, const DBID &dbidFileId, BOOL fGenerating) { DBID dbidSectionId; BOOL fRetVal = TRUE; wchar_t *pstrNamespaceName; _bstr_t pstrClassName; UINT uiStartPos = 0;
UINT uiCommentNum; UINT uiReadingOrder;
dbidSectionId = dbidFileId; m_uiLineNumber = 0; BOOL bPendingObj = FALSE;
try { UINT uiOldPercentage = 0, uiNewPercentage = 0; UINT uiBytesRead, uiCurrPos = 1;
ihItemHandler.SetProgressIndicator(uiOldPercentage); fseek(m_pOpenSourceFile, 0, SEEK_END); long lSize = ftell(m_pOpenSourceFile) + 6; fseek(m_pOpenSourceFile, 0, SEEK_SET);
// Check for UNICODE source file.
// ==============================
BYTE UnicodeSignature[2]; BOOL bUnicode = FALSE;
if (fread(UnicodeSignature, sizeof(BYTE), 2, m_pOpenSourceFile) != 2) { fRetVal = FALSE; return fRetVal; } if ((UnicodeSignature[0] == 0xFF && UnicodeSignature[1] == 0xFE) || (UnicodeSignature[0] == 0xFE && UnicodeSignature[1] == 0xFF)) { bUnicode = TRUE; lSize *= 2; } if (!bUnicode) fseek(m_pOpenSourceFile, 0, SEEK_SET);
wchar_t *pBuff = (wchar_t *)new wchar_t[lSize+1]; if (!pBuff) { fRetVal = FALSE; return fRetVal; } memset(pBuff,0,lSize*sizeof(wchar_t));
// If this is not a Unicode file,
// we need to perform a conversion.
// =====================================
if (bUnicode) uiBytesRead = fread(pBuff, sizeof(wchar_t), lSize, m_pOpenSourceFile); else { char *pCharBuff = new char[lSize+1]; if (pCharBuff) { uiBytesRead = fread(pCharBuff, sizeof(char), lSize, m_pOpenSourceFile); pCharBuff[lSize] = '\0'; swprintf(pBuff, L"%S", pCharBuff); delete pCharBuff; } } pBuff[lSize] = '\0';
if (uiBytesRead != 0) { wchar_t *pOutBuffer = NULL; uiCurrPos += uiBytesRead; fRetVal = TRUE; pstrNamespaceName = NULL; m_sCurrentNamespace = L""; pstrClassName = L"";
uiCommentNum = 0; uiReadingOrder = 1; WMIFileError wmiRet; CLocItemSet isItemSet; UINT uiTemp = 0; DWORD dwCount = 0; // If we are generating a file, make a copy
// of the outbound buffer.
if (fGenerating) pOutBuffer = pBuff;
while (GetNextQualifierPos(L"amended", pBuff, uiTemp, uiTemp) && !bPendingObj) { // If we have found the "amended" keyword,
// we want to find the namespace,
// class, and property if applicable, and
// generate the object as appropriate.
// ======================================
pstrNamespaceName = GetCurrentNamespace(pBuff, uiTemp); if (!pstrNamespaceName || !wcslen(pstrNamespaceName)) { delete pBuff; return FALSE; } if (wcscmp(pstrNamespaceName, m_sCurrentNamespace)) { // We need to generate this object,
// and set it up as the current parent.
// ====================================
CLocItem *pNewItem = new CLocItem; CPascalString sId;
if (pNewItem) {
CLocUniqueId uid; sId = (const WCHAR *)pstrNamespaceName;
uid.GetResId().SetId(sId); uid.GetTypeId().SetId(wltNamespaceName); uid.SetParentId(dbidFileId); pNewItem->SetUniqueId(uid); CLocString lsString; pNewItem->SetIconType(CIT::String); CPascalString pstrComment, pstrText; pNewItem->SetInstructions(pstrComment); lsString.SetString(pstrText);
SetFlags(pNewItem, lsString); pNewItem->SetLocString(lsString); isItemSet.Add(pNewItem);
uiReadingOrder = (uiReadingOrder + 999)/1000*1000; isItemSet[0]->SetDisplayOrder(uiReadingOrder); uiReadingOrder++;
fRetVal = EnumerateItem(ihItemHandler, isItemSet);
dbidSectionId.Clear(); dbidSectionId = isItemSet[0]->GetMyDatabaseId(); isItemSet.ClearItemSet(); uiTemp += 1;
}
m_sCurrentNamespace = pstrNamespaceName; delete pstrNamespaceName;
}
// For the class name, this is trickier.
// If there are one or more qualifiers
// on the class itself, we need to read ahead
// to find the class name, and then
// generate all the qualifier objects at once.
// ==========================================
wmiRet = GetNextItemSet(dwCount, pBuff, isItemSet, dbidSectionId, uiStartPos); while (wmiRet == WMINoError) { // For each item, we want to set its key,
// and push it or write it as appropriate.
// ========================================
dwCount++; ULONG ulItemType; CLocUniqueId &rUid = isItemSet[0]->GetUniqueId(); rUid.GetTypeId().GetId(ulItemType); //if (ulItemType == wltClassName)
//{
// uiCommentNum = 0;
// uiReadingOrder = (uiReadingOrder + 999)/1000*1000;
//}
for (int i = 0; i < isItemSet.GetSize(); i++) { isItemSet[i]->SetDisplayOrder(uiReadingOrder); uiReadingOrder++; }
if (fGenerating) { fRetVal = GenerateItem(ihItemHandler, isItemSet, &pOutBuffer, uiStartPos);
if (pBuff != pOutBuffer) { delete pBuff; pBuff = NULL; pBuff = pOutBuffer; // The old memory has already been deleted.
} else { fRetVal = FALSE; } } else { fRetVal = EnumerateItem(ihItemHandler, isItemSet); }
isItemSet.ClearItemSet(); uiTemp += 1;
if (!fRetVal) { fRetVal = TRUE; break; }
wmiRet = GetNextItemSet(dwCount, pBuff, isItemSet, dbidSectionId, uiStartPos); if (uiStartPos > uiTemp) uiTemp = uiStartPos;
if (dwCount%20 == 0) { if (uiNewPercentage < 100) uiNewPercentage++; ihItemHandler.SetProgressIndicator(uiNewPercentage); } }
// If we were generating the file,
// we're done.
// ==============================
if (fGenerating) break;
if (uiNewPercentage < 100) uiNewPercentage++; ihItemHandler.SetProgressIndicator(uiNewPercentage); } uiTemp = 0;
// Now, we get to search and replace the locale IDs,
// and actually write out the file.
// =================================================
if (fRetVal && fGenerating) { fRetVal = WriteNewFile(pOutBuffer); }
}
if (pBuff) delete pBuff;
ihItemHandler.SetProgressIndicator(100);
} catch (CFileException *pFileException) { fRetVal = FALSE;
ReportFileError(m_pstrFileName, m_didFileId, pFileException, ihItemHandler);
pFileException->Delete(); } catch (CUnicodeException *pUnicodeException) { CLocation loc;
loc.SetGlobalId(CGlobalId(m_didFileId, otFile)); loc.SetView(vProjWindow); ReportUnicodeError(pUnicodeException, ihItemHandler, loc);
pUnicodeException->Delete(); fRetVal = FALSE; } catch (CMemoryException *pMemoryException) { CLString strContext; ihItemHandler.IssueMessage(esError, strContext, g_hDll, IDS_WMI_NO_MEMORY, g_locNull); fRetVal = FALSE;
pMemoryException->Delete(); } catch (CException *pException) { CLocation loc;
loc.SetGlobalId(CGlobalId(m_didFileId, otFile)); loc.SetView(vProjWindow); ReportException(pException, ihItemHandler, loc);
pException->Delete(); fRetVal = FALSE; } return fRetVal; }
//*****************************************************************************
//
// CWMILocFile::WriteWaterMark
//
//*****************************************************************************
void CWMILocFile::WriteWaterMark() { LTASSERT(NULL != m_pOpenTargetFile);
LTASSERT(NULL != m_pOpenSourceFile);
// Do we need to support this?
}
//*****************************************************************************
//
// CWMILocFile::GetNextQualifierPos
//
//*****************************************************************************
BOOL CWMILocFile::GetNextQualifierPos(const wchar_t *wTmp, const wchar_t *pBuff, UINT &uiNewPos, UINT uiStartingPos) { BOOL bRet = FALSE; UINT uiPos = uiStartingPos; BOOL bComment = FALSE;
if (pBuff && wcslen(pBuff) < uiStartingPos) return FALSE;
wchar_t *pTemp = (wchar_t *)pBuff; pTemp += uiStartingPos;
while (TRUE) { wchar_t *pszTest2 = NULL;
pszTest2 = wcsstr(pTemp, L":"); if (pszTest2) { uiPos = pszTest2 - pBuff + 1;
// Look for the "amended" keyword.
// ==============================
WCHAR temp = pszTest2[0]; while(temp == L' ' || temp == L'\0' || temp == L':') { pszTest2++; temp = pszTest2[0]; }
if (temp != L'\0') { wchar_t wTmp2[8]; wcsncpy(wTmp2, pszTest2, 7); wTmp2[7] = '\0'; if (!_wcsicmp(wTmp2, wTmp)) { bRet = TRUE; } }
// If here, we found a non-match, so try again.
// ============================================
if (!bRet) pTemp = pszTest2 + 1; else break; } else { break; } } if (bRet) uiNewPos = uiPos;
return bRet;
}
//*****************************************************************************
//
// CWMILocFile::GetCurrentNamespace
//
//*****************************************************************************
wchar_t *CWMILocFile::GetCurrentNamespace(wchar_t *pstr, UINT uPos) { wchar_t *pTemp = pstr; _bstr_t pstrNamespace = m_sCurrentNamespace; UINT uiCurrPos = 0; BOOL bComment = FALSE; wchar_t wTmp[] = L"#pragma namespace"; int iHCLen = wcslen(wTmp);
// Find the first occurrence of the namespace
// before the current position.
if (pstrNamespace.length() > 0) pTemp = wcsstr(pTemp, pstrNamespace); // Jump directly to the existing one.
while (uiCurrPos < uPos) { wchar_t *pszTest2 = NULL;
pszTest2 = wcsstr(pTemp, L"#"); if (pszTest2) { // First, go back and make sure this isn't a comment line.
// =======================================================
bComment = FALSE;
wchar_t *pComment = pszTest2; while (pComment > pstr) { if (pComment[0] == L'\n' || pComment[0] == L'\r') { if (pComment[1] == L'/' && pComment[2] == L'/') { bComment = TRUE; } else { bComment = FALSE; } break; } pComment--; }
if (!bComment) {
wchar_t wTmp2[100]; wcsncpy(wTmp2, pszTest2, 17); wTmp2[17] = '\0'; if (!_wcsicmp(wTmp2, wTmp)) { uiCurrPos += (pszTest2 - pTemp); wchar_t *pszTest3 = wcschr(pszTest2, L')');
int iLen = (pszTest3 - pszTest2); wchar_t *pszTmpNS = new wchar_t[iLen*2+1]; if (pszTmpNS) { pszTest2 += iHCLen + 2; // skip quote and open parent.
wcsncpy(pszTmpNS, pszTest2, iLen - 2); // strip quotes.
pszTmpNS[iLen-iHCLen-3] = '\0'; pstrNamespace = pszTmpNS;
pTemp = pszTest2 + 1; delete pszTmpNS; } } else { pTemp = pszTest2 + 1; } } else { pTemp = pszTest2 + 1; } } else { break; } }
int iLen = wcslen(pstrNamespace) ;
wchar_t *pNew = new wchar_t[iLen*2+1]; if (pNew) { wcsncpy(pNew, (const wchar_t *)pstrNamespace, iLen); pNew[iLen] = '\0'; }
return pNew;
}
//*****************************************************************************
//
// CWMILocFile::GetNextItemSet
//
//*****************************************************************************
CWMILocFile::WMIFileError CWMILocFile::GetNextItemSet( DWORD dwCurrPos, const _bstr_t &pstrCurrentLine, CLocItemSet &aNewItem, const DBID &dbidSection, UINT &uiStartPos) {
// In this function, we know there is an
// "amended" keyword in here somewhere.
// We want to know to which class and/or
// property does it belong? If we don't
// have enough data to figure it out,
// we need to send back a WMIIncompleteObj
// code.
// ======================================
UINT uiCurrPos = 0; WMIFileError feRetCode = WMINoError; _bstr_t sQualifierName, sRawValue, sPropName, sClassName; BOOL bClass = FALSE; int iLen = pstrCurrentLine.length() + 1; iLen *= 2;
// Get the position of the keyword
// "amended" in this chunk of text.
wchar_t *wTemp = new wchar_t[iLen+1]; if (!wTemp) { feRetCode = WMIOOM; return feRetCode; }
if (GetNextQualifierPos(L"amended", pstrCurrentLine, uiCurrPos, uiStartPos)) { BOOL bArray = FALSE;
uiStartPos = uiCurrPos; // Find the qualifier name and value.
// wTemp = Top of File
// wTmp2 = "Amended" keyword
// wQfrVal = Opening bracket
// wBkwd = floating pointer.
wchar_t *wTmp2 = NULL, *wBkwd = NULL, *wQfrVal = NULL;
wcscpy(wTemp, pstrCurrentLine); wTemp[iLen] = '\0';
wTmp2 = wTemp; wTmp2 += (uiCurrPos - 1); // the "Amended" keyword.
wQfrVal = FindTop(wTmp2, wTemp, bArray);
if (!wQfrVal) // Make sure we had an open parenth
{ feRetCode = WMISyntaxError; delete wTemp; return feRetCode; }
// Find the beginning of the qualifier name.
wBkwd = wQfrVal;
while (wBkwd[0] != L',' && wBkwd[0] != L'[' && wBkwd >= wTemp) { wBkwd--; }
if (wBkwd[0] != L',' && wBkwd[0] != L'[') // Make sure we had a valid qualifier name.
{ feRetCode = WMISyntaxError; delete wTemp; return feRetCode; }
WCHAR *token; UINT uiLen;
wBkwd += 1; wchar_t wTmpBuff[256]; wcsncpy(wTmpBuff, wBkwd, wQfrVal - wBkwd); wTmpBuff[wQfrVal - wBkwd] = '\0'; sQualifierName = wTmpBuff;
GetQualifierValue(wTemp, uiStartPos, sRawValue, uiLen);
// Finally, populate the CLocItem.
// ===============================
LTASSERT(aNewItem.GetSize() == 0); if (feRetCode == WMINoError) { CLocItem *pNewItem; try { // Now we have a value, but it may be an
// array. If so, we need to add one CLocItem
// for each value in the array.
VectorString arrValues; if (bArray) ParseArray(sRawValue, arrValues); else arrValues.push_back(sRawValue);
for (int i = 0; i < arrValues.size(); i++) { wchar_t szTmp[20]; swprintf(szTmp, L"%ld", dwCurrPos);
_bstr_t sValue = arrValues.at(i);
pNewItem = new CLocItem;
CLocUniqueId uid;
CPascalString sTempString;
sTempString = sQualifierName; sTempString += szTmp; uid.GetResId().SetId(sTempString) ;
if (bClass) uid.GetTypeId().SetId(wltClassName); else uid.GetTypeId().SetId(wltPropertyName);
uid.SetParentId(dbidSection); pNewItem->SetUniqueId(uid); CLocString lsString; CPascalString pstrComment, pstrText;
pstrText = sValue; pNewItem->SetIconType(CIT::String); pNewItem->SetInstructions(pstrComment); lsString.SetString(pstrText); SetFlags(pNewItem, lsString); pNewItem->SetLocString(lsString); aNewItem.Add(pNewItem); }
} catch (CMemoryException *pMemoryException) { feRetCode = WMIOOM; pMemoryException->Delete(); } } else { LTTRACE("Unable to process line '%ls'", (const WCHAR *)pstrCurrentLine); } } else { feRetCode = WMINoMore; } uiStartPos = uiCurrPos;
delete wTemp; return feRetCode; }
const UINT WMI_MAX_CONTEXT = 256;
//*****************************************************************************
//
// CWMILocFile::GetFullContext
//
//*****************************************************************************
void CWMILocFile::GetFullContext( CLString &strContext) const { CLString strFormat;
strFormat.LoadString(g_hDll, IDS_WMI_FULL_CONTEXT);
strContext.Empty();
_sntprintf(strContext.GetBuffer(WMI_MAX_CONTEXT), WMI_MAX_CONTEXT, (const TCHAR *)strFormat, (const WCHAR *)m_pstrFileName, (UINT)m_uiLineNumber); strContext.ReleaseBuffer(); }
//*****************************************************************************
//
// CWMILocFile::ReportFileError
//
//*****************************************************************************
void CWMILocFile::ReportFileError( const _bstr_t &pstrFileName, const DBID &didFileId, CFileException *pFileException, CReporter &Reporter) const { CLString strContext; CLString strMessage; const UINT MAX_MESSAGE = 256; TCHAR szFileErrorMessage[MAX_MESSAGE]; CLocation loc; pFileException->GetErrorMessage(szFileErrorMessage, MAX_MESSAGE); strMessage.Format(g_hDll, IDS_WMI_BAD_FILE, (const WCHAR *)pstrFileName, szFileErrorMessage);
GetFullContext(strContext); loc.SetGlobalId(CGlobalId(didFileId, otFile)); loc.SetView(vProjWindow); Reporter.IssueMessage(esError, strContext, strMessage, loc); }
//*****************************************************************************
//
// CWMILocFile::ReportUnicodeError
//
//*****************************************************************************
void CWMILocFile::ReportUnicodeError( CUnicodeException *pUnicodeException, CReporter &Reporter, const CLocation &Location) const { CLString strContext; CLString strMessage; const UINT MAX_MESSAGE = 256; TCHAR szUnicodeErrorMessage[MAX_MESSAGE]; CLocation loc; pUnicodeException->GetErrorMessage(szUnicodeErrorMessage, MAX_MESSAGE); strMessage.Format(g_hDll, IDS_WMI_UNICODE_ERROR, szUnicodeErrorMessage); GetFullContext(strContext); Reporter.IssueMessage(esError, strContext, strMessage, Location, IDH_UNICODE_CONV); }
//*****************************************************************************
//
// CWMILocFile::ReportException
//
//*****************************************************************************
void CWMILocFile::ReportException( CException *pException, CReporter &Reporter, const CLocation &Location) const { CLString strContext; CLString strMessage; const UINT MAX_MESSAGE = 256; TCHAR szErrorMessage[MAX_MESSAGE]; pException->GetErrorMessage(szErrorMessage, MAX_MESSAGE); strMessage.Format(g_hDll, IDS_WMI_EXCEPTION, szErrorMessage); GetFullContext(strContext);
Reporter.IssueMessage(esError, strContext, strMessage, Location); }
//
// This function estimates the size of a buffer
// required to hold a string up to something like __"}__ or __")__
// invalid combinations are \"} and \") (there is the escape)
// but double \\"} or \\") are valid
//
//
//
// we will consider \\ and \" as special
// white spaces are \r \n \t \x20
// array of strings { "" , "" }
// ("")
// states of the FSA modelling the parser
#define BEFORE_PAREN 0
#define AFTER_PAREN 1
#define OPEN_QUOTE 2
#define CLOSE_QUOTE 3
#define COMMA 4
#define CLOSE_PAREN 5
#define BAD 6
#define LAST_STATE 7
// classes of characters
#define QUOTE 0
#define PAREN_OPEN 1
#define SPACES 2
#define PAREN_CLOSE 3
#define COMMA_CHAR 4
#define OTHER 5
#define LAST_CLASS 6
DWORD g_pTable[LAST_STATE][LAST_CLASS] = { /* BEFORE_PAREN */ {BAD , AFTER_PAREN, BEFORE_PAREN, BAD, BAD, BAD }, /* AFTER_PAREN */ {OPEN_QUOTE , BAD, AFTER_PAREN, BAD, BAD, BAD }, /* OPEN_QUOTE */ {CLOSE_QUOTE, OPEN_QUOTE, OPEN_QUOTE, OPEN_QUOTE, OPEN_QUOTE, OPEN_QUOTE }, /* CLOSE_QUOTE */ {BAD, BAD, CLOSE_QUOTE, CLOSE_PAREN, COMMA, BAD }, /* COMMA */ {OPEN_QUOTE , BAD, COMMA, BAD, BAD, BAD}, /* CLOSE_PAREN */ {BAD, BAD,BAD,BAD,BAD,BAD }, /* BAD */ {BAD, BAD,BAD,BAD,BAD,BAD }, };
ULONG_PTR Estimate(WCHAR * pBuff,BOOL * pbOK, DWORD InitState) { DWORD State = InitState;
ULONG_PTR i=0;
while (pBuff[i]) { switch(pBuff[i]) { case L'{': case L'(': State = g_pTable[State][PAREN_OPEN]; break; case L'}': case L')': State = g_pTable[State][PAREN_CLOSE]; break; case L'\t': case L'\r': case L'\n': case L' ': State = g_pTable[State][SPACES]; break; case L'\"': State = g_pTable[State][QUOTE]; break; case L',': State = g_pTable[State][COMMA_CHAR]; break; case L'\\': if ((pBuff[i+1] == L'\"' || pBuff[i+1] == L'\\' || pBuff[i+1] == L'r' || pBuff[i+1] == L'n' || pBuff[i+1] == L't' ) && (State == OPEN_QUOTE)){ i++; }; State = g_pTable[State][OTHER]; break; default: State = g_pTable[State][OTHER]; }; i++; if (State == CLOSE_PAREN){ *pbOK = TRUE; break; } if (State == BAD) { *pbOK = FALSE; //
// get the next ) or }, and take the most far
//
ULONG_PTR NextClose1 = (ULONG_PTR)wcschr(&pBuff[i],L'}'); ULONG_PTR NextClose2 = (ULONG_PTR)wcschr(&pBuff[i],L')'); ULONG_PTR Res = (NextClose1<NextClose2)?NextClose2:NextClose1; if (Res){ i = 1+(Res-(ULONG_PTR)pBuff); i /= sizeof(WCHAR); } break; } }
/*
{ char pBuffDbg[64]; wsprintfA(pBuffDbg,"pBuff %p Size %d\n",pBuff,(DWORD)i); OutputDebugStringA(pBuffDbg); } */
return i+4; }
//*****************************************************************************
//
// CWMILocFile::GetQualifierValue
//
//*****************************************************************************
BOOL CWMILocFile::GetQualifierValue(wchar_t *pBuffer, UINT &uiPos, _bstr_t &sValue, UINT &uiPhysLen) {
// This needs to read up the text of the qualifier,
// strip out the quotes and carriage returns, and
// return it and its *physical* length-in-file.
BOOL fRetVal = FALSE; BOOL bArray = FALSE;
wchar_t *pTemp = pBuffer;
pTemp += uiPos;
pTemp = FindTop(pTemp, pBuffer, bArray); if (pTemp) {
BOOL bOK = FALSE; ULONG_PTR dwSize = Estimate(pTemp,&bOK,BEFORE_PAREN); wchar_t * tempBuff = new WCHAR[dwSize+1];
if (tempBuff == NULL){ return FALSE; } int iCount = 0;
pTemp++; // Step past this character.
uiPhysLen = 0;
WCHAR *token = pTemp; BOOL bEnd = FALSE; while (!bEnd) { uiPhysLen++; // Count every character.
WCHAR *Test;
switch(*token) { case L'\0': bEnd = TRUE; break; case L'\n': case L'\r': case L'\t': break; case L'\"': if (!iCount) break; case L')': case L'}': Test = token - 1; while (TRUE) { if (*Test == L' ' || *Test == L'\r' || *Test == L'\n' || *Test == L'\t') { Test--; continue; } if (*Test == L'\"') { Test--; if (*Test != L'\\') { bEnd = TRUE; break; } else { Test--; if (*Test == L'\\') { bEnd = TRUE; break; } } } tempBuff[iCount] = *token; iCount++; break; } break; default: tempBuff[iCount] = *token; iCount++; break;
} token++; } if (tempBuff[iCount-1] == L'\"') tempBuff[iCount-1] = '\0'; else tempBuff[iCount] = '\0'; sValue = tempBuff;
delete [] tempBuff; fRetVal = TRUE; } uiPhysLen -= 1; // We want to keep the closing parenth.
return fRetVal;
}
//*****************************************************************************
//
// CWMILocFile::SetQualifierValue
//
//*****************************************************************************
BOOL CWMILocFile::SetQualifierValue(wchar_t *pIn, wchar_t **pOut, UINT &uiPos, _bstr_t &sValue, UINT &uiLen, BOOL bQuotes) { // This needs to write the localized qualifier value
// and erase *uiLen* characters.
// uiPos will need to be updated with the *new*
// position of this qualifier.
BOOL fRetVal = FALSE; wchar_t *pStart = pIn + uiPos; BOOL bArray = FALSE;
pStart = FindTop(pStart, pIn, bArray); if (pStart) { int iNewLen = wcslen(sValue); int iLen = wcslen(pIn) + 3; if (iNewLen > uiLen) // The length of the new buffer
iLen += (iNewLen - uiLen); // If the new value is longer, add it.
pStart++; // jump past the '(' character. uiLen starts now.
int iPos = pStart-pIn; // The current position.
iLen *= 2; wchar_t *pNew = new wchar_t[iLen+3];
if (pNew) { int iTempPos = 0;
wcsncpy(pNew, pIn, iPos); // Copy the initial part of the file.
if (bQuotes) pNew[iPos] = '\"'; pNew[iPos+1] = '\0'; // Null terminate
wcscat(pNew, sValue); // Add the new value.
iPos += 1 + wcslen(sValue); // Jump past the value
if (bQuotes) pNew[iPos] = '\"'; pNew[iPos+1] = '\0'; // Null terminate the value.
pStart += uiLen; // Jump past the current value.
iTempPos = iPos; iPos = wcslen(pIn) - (pStart-pIn); // Calculate the length of the rest of the file.
wcsncat(pNew, pStart, iPos); // Append the rest of the file to the new buffer.
pStart = pNew + iLen; pStart = FindPrevious(pStart, L";", pNew); pStart[1] = L'\r'; pStart[2] = L'\n'; pStart[3] = L'\0'; *pOut = pNew;
fRetVal = TRUE; } }
// Adjust the position.
int iNewLen = wcslen(sValue); if (iNewLen < uiLen) uiPos -= (uiLen - iNewLen); else uiPos += (iNewLen - uiLen); uiPos += 3;
return fRetVal; }
//*****************************************************************************
//
// CWMILocFile::WriteNewFile
//
//*****************************************************************************
BOOL CWMILocFile::WriteNewFile(wchar_t *pBuffer) { // This needs to seek and replace all instances of the
// original Locale with the new one.
// ===================================================
BOOL fRetVal = FALSE, fSuccess = TRUE; UINT uiPos = 0, uiStartingPos = 0; int uiLen = wcslen(pBuffer);
_bstr_t sThisLocale, sTargetLocale; wchar_t wOldCodePage[30], wNewCodePage[30]; swprintf(wOldCodePage, L"_%X", m_wSourceId ); swprintf(wNewCodePage, L"_%X", m_wTargetId );
if (m_wSourceId != m_wTargetId) {
wchar_t *pLocale = wcsstr(pBuffer, wOldCodePage); while (pLocale != NULL) { for (int i = 0; i < wcslen(wOldCodePage); i++) { pLocale[i] = wNewCodePage[i]; } pLocale = wcsstr(pLocale, wOldCodePage); }
// Now look for the locale if
// it was converted to a decimal.
// ==============================
swprintf(wOldCodePage, L"(0x%X)", m_wSourceId ); swprintf(wNewCodePage, L"(0x%X)", m_wTargetId );
pLocale = wcsstr(pBuffer, wOldCodePage); while (pLocale != NULL) { for (int i = 0; i < wcslen(wOldCodePage); i++) { pLocale[i] = wNewCodePage[i]; } pLocale = wcsstr(pLocale, wOldCodePage); }
// Now look for the locale if
// it was converted to a decimal.
// ==============================
swprintf(wOldCodePage, L"(%ld)", m_wSourceId ); swprintf(wNewCodePage, L"(%ld)", m_wTargetId );
pLocale = wcsstr(pBuffer, wOldCodePage); while (pLocale != NULL) { for (int i = 0; i < wcslen(wOldCodePage); i++) { pLocale[i] = wNewCodePage[i]; } pLocale = wcsstr(pLocale, wOldCodePage); } }
if (fSuccess) { fRetVal = TRUE;
// Finally, write out the buffer to a brand new file
// =================================================
while (uiLen >= 0) { if (fwrite(pBuffer, sizeof(wchar_t), (uiLen > 4096) ? 4096: uiLen, m_pOpenTargetFile) < 0) { fRetVal = FALSE; break; } else { fRetVal = TRUE; pBuffer += 4096; uiLen -= 4096; }
fflush(m_pOpenTargetFile); } }
return fRetVal;
}
//*****************************************************************************
//
// CWMILocFile::FindPrevious
//
//*****************************************************************************
wchar_t *CWMILocFile::FindPrevious(wchar_t *pBuffer, const wchar_t *pFind, const wchar_t *pTop) {
wchar_t *pRet = NULL; WCHAR t1, t2; int iLen = wcslen(pFind); BOOL bFound = FALSE;
pRet = pBuffer; while (pRet >= pTop) { t2 = pRet[0]; for (int i = 0; i < iLen; i++) { t1 = pFind[i];
if (t1 == t2) { bFound = TRUE; break; } } if (bFound) break;
pRet--; }
if (pRet <= pTop) pRet = NULL;
return pRet; }
//*****************************************************************************
//
// CWMILocFile::FindTop
//
//*****************************************************************************
wchar_t *CWMILocFile::FindTop(wchar_t *wTmp2, wchar_t *wTop, BOOL &bArray) {
wchar_t *wQfrVal = FindPrevious(wTmp2, L"({", wTop);
while (wQfrVal) { WCHAR *pQT = wQfrVal + 1; BOOL bFound = FALSE;
while (TRUE) { if (*pQT != L' ' && *pQT != L'\t' && *pQT != L'\r' && *pQT != L'\n') { if (*pQT == L'\"') { bFound = TRUE; } break; } pQT++; } if (!bFound) { wQfrVal --; wQfrVal = FindPrevious(wQfrVal, L"({", wTop); } else break; }
if (wQfrVal) { if (wQfrVal[0] == L'{') bArray = TRUE; }
return wQfrVal;
}
//*****************************************************************************
//
// CWMILocFile::ParseArray
//
//*****************************************************************************
void CWMILocFile::ParseArray(wchar_t *pIn, VectorString &arrOut) { wchar_t *pLast = pIn; if (*pLast == L'\"') pLast++;
BOOL bOK = FALSE; BOOL bAlloc = FALSE; ULONG_PTR qwSize = Estimate(pLast,&bOK,OPEN_QUOTE);
wchar_t * Buff = new WCHAR[(DWORD)qwSize];
if(Buff == NULL){ Buff = (WCHAR *)_alloca((DWORD)qwSize); } else { bAlloc = TRUE; } wchar_t *pFind = wcsstr(pIn, L"\",");
arrOut.clear();
while (pFind) { wchar_t temp = pFind[-1]; if (temp == '\\') { pFind++; pFind = wcsstr(pFind, L"\","); continue; }
wcsncpy(Buff, pLast, pFind-pLast); Buff[pFind-pLast] = '\0';
arrOut.push_back(_bstr_t(Buff));
// Now move pFind to the next valid char.
while (pFind[0] == L'\n' || pFind[0] == L'\r' || pFind[0] == L' ' || pFind[0] == L',' || pFind[0] == L'\"' ) pFind++;
pLast = pFind ; pFind = wcsstr(pFind, L"\","); }
wcscpy(Buff, pLast); if (Buff[wcslen(Buff)-1] == L'\"') Buff[wcslen(Buff)-1] = L'\0'; // strip off that trailing quote.
else Buff[wcslen(Buff)] = L'\0'; // strip off that trailing quote.
arrOut.push_back(_bstr_t(Buff));
if (bAlloc) { delete [] Buff; } return; }
//*****************************************************************************
//
// CVC::ValidateString
//
//*****************************************************************************
CVC::ValidationCode ValidateString( const CLocTypeId &, const CLocString &clsOutputLine, CReporter &repReporter, const CLocation &loc, const CLString &strContext) { CVC::ValidationCode vcRetVal = CVC::NoError; CLString strMyContext = strContext;
if (strMyContext.GetLength() == 0) { strMyContext.LoadString(g_hDll, IDS_WMI_GENERIC_LOCATION); }
loc; repReporter; clsOutputLine; /*
if (clsOutputLine.HasHotKey()) { vcRetVal = CVC::UpgradeValue(vcRetVal, CVC::Warning); repReporter.IssueMessage(esWarning, strMyContext, g_hDll, IDS_WMI_VAL_HOTKEY, loc); } _bstr_t pstrBadChars; UINT uiBadPos;
pstrBadChars.SetString(L"\n\ra", (UINT)3); if (pstrOutput.FindOneOf(pstrBadChars, 0, uiBadPos)) { vcRetVal = CVC::UpgradeValue(vcRetVal, CVC::Error);
repReporter.IssueMessage(esError, strMyContext, g_hDll, IDS_WMI_VAL_BAD_CHARS, loc); } */ return vcRetVal; }
|