|
|
/************************************************************************
* @doc SHROOM EXTERNAL API * * TITLE: CIMAIN.CPP * * OWNER: johnrush (John C. Rush) * * DATE CREATED: January 29, 1997 * * DESCRIPTION: * This is the main file for the Command Interpreter. * *********************************************************************/ #include <mvopsys.h>
// Global debug variable
#ifdef _DEBUG
static char s_aszModule[] = __FILE__; #endif
// Include Files
#include <windows.h>
#include <orkin.h>
#include <common.h>
#include <itdb.h>
#include "cmdint.h"
#include "ciutil.h"
#include "cierror.h"
CITCmdInt::~CITCmdInt () { Dispose(); }
/************************************************************************
* @method HRESULT WINAPI | IITCmdInt | Initiate | * Initializes the command interpreter. Should be called before any other * methods for this class. * * @parm IITSvMgr | *piitsv | Pointer to the instance of the service manager. * * @rvalue E_OUTOFMEMORY | Resources for command interpreter couldn't be allocated. * @rvalue S_OK | Command interpreter was successfull initialized * * @xref <om.Dispose> ************************************************************************/ HRESULT WINAPI CITCmdInt::Initiate (IITSvMgr *piitsv) { if (m_fInit) return E_ALREADYINIT;
HRESULT hr; (m_piitsv = piitsv)->AddRef(); if (SUCCEEDED(hr = piitsv->GetBuildObject (L"", IID_IITDatabase, (void **)&m_piitdb)) && SUCCEEDED(hr = (NULL == (m_pBlockMgr = BlockInitiate ((DWORD)65500, 0, 0, 0)) ? E_OUTOFMEMORY : S_OK)) ) { MEMSET(m_wstrHelper, 0, sizeof(m_wstrHelper)); m_dwMaxInstance = 0; m_fInit = TRUE; } return hr; } /* CITCmdInt::Initiate */
/************************************************************************
* @method HRESULT WINAPI | IITCmdInt | Dispose | * Frees any resources allocated by the command interpreter. Should be * the last method called. * * * @rvalue S_OK | All resources were freed successfully * * @xref <om.Initiate> ************************************************************************/ HRESULT WINAPI CITCmdInt::Dispose (void) { if (FALSE == m_fInit) return E_NOTINIT;
m_piitsv->Release(); m_piitdb->Release(); BlockFree(m_pBlockMgr); m_fInit = FALSE; return S_OK; } /* CITCmdInt::Dispose */
/************************************************************************
* @method HRESULT WINAPI | IITCmdInt | LoadFromStream | * Loads and parses the build configuration information from the given input * stream. * * @rvalue S_OK | The configuration stream was loaded successfully * @rvalue E_OUTOFMEMORY | Not enough memory was available to parse the stream * @rvalue Other | Another I/O condition prevents the processing of the stream * * @xref <om.Initiate> * * @comm During the parsing of the stream, various warnings may occur as a result * of authoring error, and these are written to the log file. In this case, the * method still returns S_OK if none of the errors was fatal. ************************************************************************/ HRESULT WINAPI CITCmdInt::LoadFromStream (IStream *pStream, //@parm Pointer to the input <p IStream>
IStream *pLogStream) //@parm Pointer to the log stream <p IStream>
{ HRESULT hr;
if (FALSE == m_fInit) return E_NOTINIT;
m_piistmLog = pLogStream;
m_errc.iLine = 0; m_errc.ep = epLine; m_ConfigParser.SetStream(pStream);
hr = ParseConfigStream(); m_piistmLog = NULL;
return hr; } /* CITCmdInt::LoadFromStream */
HRESULT WINAPI CITCmdInt::ParseBogusSz(LPWSTR) { return S_OK; }
HRESULT WINAPI CITCmdInt::ParseIndexSz(LPWSTR wstrLine) { ITASSERT(wstrLine);
KEYVAL *pKeyValue; HRESULT hr = ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); if (FAILED(hr)) return hr;
// Verify the format
if (!pKeyValue->vaValue.dwArgc) // TODO: Issue warning message
return E_INVALIDARG;
CLSID clsid; hr = CLSIDFromProgID((LPCWSTR)pKeyValue->vaValue.Argv[0], &clsid); IITBuildCollect *pInterface = NULL;
if (SUCCEEDED(hr) && SUCCEEDED (hr = m_piitsv->CreateBuildObject(pKeyValue->pwstrKey, clsid))) { if(FAILED(hr = m_piitsv->GetBuildObject (pKeyValue->pwstrKey, IID_IITBuildCollect, (void**)&pInterface))) { ITASSERT(0); } }
if(SUCCEEDED(hr)) { // Skip the first 2 (required params)
DWORD dwArgc = pKeyValue->vaValue.dwArgc; if((int)(dwArgc -= 2) < 0) dwArgc = 0; VARARG vaNew = {0}; vaNew.dwArgc = dwArgc; LPWSTR *ppwstr = (LPWSTR *)pKeyValue->vaValue.Argv + 2; for(DWORD loop = 0; loop < dwArgc; ++loop, ++ppwstr) { *(vaNew.Argv + loop) = *ppwstr; } hr = pInterface->SetConfigInfo(m_piitdb, vaNew); }
if(SUCCEEDED(hr) && (LPWSTR)pKeyValue->vaValue.Argv[1] && *(LPWSTR)pKeyValue->vaValue.Argv[1]) { for(DWORD loop = 0; loop <= m_dwMaxInstance; ++loop) { if((m_wstrHelper + loop)->pwstrName && !WSTRCMP ((m_wstrHelper+loop)->pwstrName, (LPWSTR)pKeyValue->vaValue.Argv[1])) { tagHELPERSTUFF *pInfo = (m_wstrHelper + loop);
hr = pInterface->InitHelperInstance (loop, m_piitdb, pInfo->dwCodePage, pInfo->lcid, pInfo->kvDword, pInfo->kvString); break; } } }
if(pInterface) pInterface->Release(); return hr; }
HRESULT WINAPI CITCmdInt::ParseHelperSz(LPWSTR wstrLine) { int iLineCount; KEYVAL *pKeyValue, *pkvDword, *pkvString; CLSID clsid; DWORD dwCodePage; LCID lcid;
// The +3 skips to 'HO:' prefix
HRESULT hr = ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); if (FAILED(hr)) return hr;
if (!WSTRICMP(L"VIProgId", pKeyValue->pwstrKey)) { if(pKeyValue->vaValue.dwArgc != 1) return SetErrReturn(E_INVALIDARG); hr = CLSIDFromProgID((LPCWSTR)pKeyValue->vaValue.Argv[0], &clsid); } else hr = E_FAIL;
if (SUCCEEDED(hr)) { m_ConfigParser.GetLogicalLine(&wstrLine, &iLineCount); m_errc.iLine += iLineCount; hr = ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); if (!WSTRICMP(L"CodePage", pKeyValue->pwstrKey)) { if(pKeyValue->vaValue.dwArgc != 1) return E_INVALIDARG; dwCodePage = _wtol((LPWSTR)pKeyValue->vaValue.Argv[0]); } else hr = E_FAIL; }
if (SUCCEEDED(hr)) { m_ConfigParser.GetLogicalLine(&wstrLine, &iLineCount); m_errc.iLine += iLineCount; hr = ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); if (!WSTRICMP(L"Locale", pKeyValue->pwstrKey)) { if(pKeyValue->vaValue.dwArgc != 1) return E_INVALIDARG; lcid = _wtol((LPWSTR)pKeyValue->vaValue.Argv[0]); } else hr = E_FAIL; }
if (SUCCEEDED(hr)) { m_ConfigParser.GetLogicalLine(&wstrLine, &iLineCount); m_errc.iLine += iLineCount; hr = ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); if (SUCCEEDED(hr) && !WSTRICMP(L"DWORD", pKeyValue->pwstrKey)) { pkvDword = pKeyValue;
LPWSTR *ppwstr = (LPWSTR *)pKeyValue->vaValue.Argv; DWORD *pdwCur = (DWORD *)ppwstr; for (DWORD loop = 0; loop < pKeyValue->vaValue.dwArgc; ++loop) { *pdwCur++ = _wtol(*ppwstr++); }
m_ConfigParser.GetLogicalLine(&wstrLine, &iLineCount); m_errc.iLine += iLineCount; (void)ParseKeyAndValue(m_pBlockMgr, wstrLine, &pKeyValue); } if (SUCCEEDED(hr) && !WSTRICMP(L"String", pKeyValue->pwstrKey)) { pkvString = pKeyValue; } }
DWORD dwInstance; if (SUCCEEDED(hr) && SUCCEEDED(hr = m_piitdb->CreateObject(clsid, &dwInstance))) { ITASSERT(dwInstance <= MAX_HELPER_INSTANCE);
if(dwInstance > m_dwMaxInstance) m_dwMaxInstance = dwInstance;
if(NULL == (m_wstrHelper[dwInstance].pwstrName = (LPWSTR)BlockCopy(m_pBlockMgr, (LPB)(m_wstrSection + 3), (DWORD) WSTRCB(m_wstrSection + 3), 0))) { SetErrCode(&hr, E_OUTOFMEMORY); } m_wstrHelper[dwInstance].dwCodePage = dwCodePage; m_wstrHelper[dwInstance].lcid = lcid; m_wstrHelper[dwInstance].kvDword = pkvDword->vaValue; m_wstrHelper[dwInstance].kvString = pkvString->vaValue; } return hr; } /* ParseHelperSz */
HRESULT WINAPI CITCmdInt::ParseConfigStream(void) { LPWSTR pwstrLine; BOOL fParsingHelper = TRUE; PFPARSE2 pfparse; int iLineCount;
for(;;) { if (S_OK != m_ConfigParser.GetLogicalLine (&pwstrLine, &iLineCount)) { if (fParsingHelper) { m_ConfigParser.Reset(); m_errc.iLine = 0; fParsingHelper = FALSE; continue; } else break; } m_errc.iLine += iLineCount;
if(S_OK == IsSectionHeading(pwstrLine)) { (void)GetFunctionFromSection(pwstrLine + 1, (void **)&pfparse); WSTRCPY(m_wstrSection, pwstrLine + 1); continue; }
if (fParsingHelper) { if (ParseHelperSz == pfparse) (void)ParseHelperSz(pwstrLine); } else if(ParseIndexSz == pfparse) (void)ParseIndexSz(pwstrLine); }
return S_OK; } /* ParseConfigStream */
struct tagSection { LPCWSTR szName; PFPARSE2 pfparse; };
HRESULT WINAPI CITCmdInt::GetFunctionFromSection (LPWSTR pwstrSection, void **ppvoid) { ITASSERT(pwstrSection && ppvoid); PFPARSE2 *ppfparse = (PFPARSE2 *)ppvoid;
const int NUM_RECOGNIZED_SECTIONS = 3; const tagSection rgSection[NUM_RECOGNIZED_SECTIONS] = { { L"OPTIONS", CITCmdInt::ParseBogusSz }, { L"INDEX", CITCmdInt::ParseIndexSz }, { L"HO:", CITCmdInt::ParseHelperSz }, };
*ppfparse = NULL; for (int loop = 0; loop < NUM_RECOGNIZED_SECTIONS; ++loop) { if (!WSTRNICMP (rgSection[loop].szName, pwstrSection, WSTRLEN(rgSection[loop].szName))) { *ppfparse = rgSection[loop].pfparse; break; } }
if (NULL == *ppfparse) *ppfparse = ParseBogusSz;
return S_OK; } /* GetFunctionFromSection */
HRESULT WINAPI CITCmdInt::IsSectionHeading(LPWSTR pwstrLine) { ITASSERT(pwstrLine); HRESULT hr = S_FALSE;
if (*pwstrLine == '[') { LPWSTR pch = pwstrLine + WSTRLEN(pwstrLine) - 1;
/*****************************************************
* IS SECTION HEADING TERMINATED WITH CLOSING BRACKET? *****************************************************/ if (*pch != ']') // *** NO! ***
{ m_errc.errCode = CIERR_SectionHeadingSyntax; ReportError (m_piistmLog, m_errc); } else { // *** YES! ***
*pch = '\0'; pch = pwstrLine + 1; pch = SkipWhitespace(pch); StripTrailingBlanks(pch); hr = S_OK; } } return hr; } /* IsSectionHeading */
|