|
|
//
// MODULE: APGTSDTG.CPP
//
// PURPOSE: Wrapper for inference api
//
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
//
// COMPANY: Saltmine Creative, Inc. (206)-633-4743 [email protected]
//
// AUTHOR: Roman Mach
//
// ORIGINAL DATE: 8-2-96
//
// NOTES:
// 1. Based on Print Troubleshooter DLL
//
// Version Date By Comments
//--------------------------------------------------------------------
// V0.1 - RM Original
// V0.2 6/4/97 RWM Local Version for Memphis
// V0.3 04/09/98 JM/OK+ Local Version for NT5
//
//#include "windows.h"
#include "stdafx.h"
#include "time.h"
#include "apgts.h"
#include "ErrorEnums.h"
#include "bnts.h"
#include "BackupInfo.h"
#include "cachegen.h"
#include "apgtsinf.h"
#include "apgtscmd.h"
#include "apgtshtx.h"
#include "apgtscls.h"
#include <string.h>
#include <memory.h>
#include "CabUnCompress.h"
#include "crc.h"
#include "sniff.h"
#include "chmread.h"
BCache::BCache(TCHAR *binfile, TCHAR *tagstr, TCHAR *szResourcePath, const CString& strFile) : GTSAPI(binfile, tagstr, szResourcePath), CSniffedNodeContainer(), m_NodeState(30), m_strFile(strFile) { SetBNTS(this); m_bNeedModel = TRUE; // TRUE -> Need to read the model before querying the bnts library.
m_bModelRead = FALSE; m_bDeleteModelFile = FALSE; m_strModelFile = _T("");
m_CurNode = 0;
m_pHttpQuery = NULL;
m_strResult = _T("");
m_NodeState.InitHashTable(47);
m_bReverse = false;
m_bRunWithKnownProblem = false;
return; }
BCache::~BCache() { m_NodeState.RemoveAll(); if (m_bDeleteModelFile) { DeleteFile((LPCTSTR) m_strModelFile); m_bDeleteModelFile = FALSE; } return; }
//
//
GTSAPI::GTSAPI(TCHAR *binfile, TCHAR *tagstr, TCHAR *szResourcePath) : m_CacheGen(TRUE, NULL, NULL) { // InitializeCriticalSection( &m_csAPI );
m_cnid = 0; m_dwErr = 0; m_pchHtml = NULL; m_currid = 0; m_pCache = NULL;
_tcscpy(m_binfile,binfile);// full path
_tcscpy(m_tagstr,tagstr); _tcscpy(m_szResourcePath,szResourcePath); }
//
//
GTSAPI::~GTSAPI() { Destroy(); }
void WideToMB(const WCHAR *szIn, CHAR *szOut) { VERIFY(WideCharToMultiByte(CP_ACP, NULL, szIn, -1, szOut, MAXBUF, NULL, NULL)); return; } #ifdef _UNICODE
// Temporary BNTS wrappers for unicode build with non unicode bnts.dll
BOOL GTSAPI::BMultiByteReadModel(LPCTSTR szcFn, LPCSTR szFnError) { CHAR szFn[MAXBUF]; WideToMB(szcFn, szFn); return BNTS::BReadModel(szFn, szFnError); }
BOOL GTSAPI::BMultiByteNodePropItemStr(LPCTSTR szcPropType, int index) { CHAR szPropType[MAXBUF]; WideToMB(szcPropType, szPropType); return BNTS::BNodePropItemStr(szPropType, index); }
BOOL GTSAPI::BMultiByteNetPropItemStr(LPCTSTR szcPropType, int index) { CHAR szPropType[MAXBUF]; WideToMB(szcPropType, szPropType); return BNTS::BNetPropItemStr(szPropType, index); }
const WCHAR * GTSAPI::SzcMultiByteResult() { int len = strlen(BNTS::SzcResult()); int size = MultiByteToWideChar(CP_ACP, NULL, BNTS::SzcResult(), len, NULL, 0); MultiByteToWideChar(CP_ACP, NULL, BNTS::SzcResult(), len + 1, m_strResult.GetBufferSetLength(size), size); m_strResult.ReleaseBuffer(); return (LPCTSTR) m_strResult; }
int GTSAPI::IMultiByteNode(LPCTSTR szSymName) { CHAR szMBSymName[MAXBUF]; WideToMB(szSymName, szMBSymName); return BNTS::INode(szMBSymName); }
#endif // _UNICODE
void BCache::ReadTheDscModel(int From) { if (m_bNeedModel) { if (!BReadModel((LPCTSTR) m_strModelFile #ifdef _DEBUG
, "BNTSError.log" #endif
)) ReportError((DLSTATTYPES) From); // Add the nodes that are already instantiated.
if (m_pHttpQuery) m_pHttpQuery->AddNodes(this); m_bNeedModel = FALSE;
if (m_bDeleteModelFile) { DeleteFile((LPCTSTR) m_strModelFile); m_bDeleteModelFile = FALSE; } } }
VOID BCache::AddToCache(CString &strCacheFile, const CString& strCacheFileWithinCHM) { if (m_CacheGen.ReadCacheFileHeader(strCacheFile, strCacheFileWithinCHM)) { BOOL bErr; ASSERT(m_pCache); while (m_CacheGen.GetNextCacheEntryFromFile(bErr, m_pCache)) ; if (bErr) { delete m_pCache; m_pCache = new CBNCache(); TRACE(_T("Errors occured while reading the cache file.\n")); ReadTheDscModel(TSERR_ENGINE_BNTS_READ_NCAB); } } return; }
DWORD BCache::ReadModel() { BOOL bDelete = FALSE;
// this should be fixed eventually to not require a string compare
// but maybe a flag check that gets passed in
CString sFilename = m_binfile; CString strCacheFile; CString strCacheFileWithinCHM;
if (m_strFile.GetLength()) { // form Cache file path here assuming it is NOT in chm file
strCacheFile = m_binfile; strCacheFileWithinCHM = m_strFile.Left(m_strFile.GetLength() - 4); strCacheFileWithinCHM += SZ_CACHE_NAME; } else { strCacheFile = sFilename.Left(sFilename.GetLength() - 4); strCacheFile += SZ_CACHE_NAME; } if (m_strFile.GetLength() || !sFilename.Right(4).CompareNoCase(DSC_COMPRESSED)) { CCabUnCompress cab; CString strDirBuf; if (!GetTempPath( MAX_PATH , strDirBuf.GetBufferSetLength(MAX_PATH + 1))) { strDirBuf.ReleaseBuffer(); strDirBuf = m_szResourcePath; } else { strDirBuf.ReleaseBuffer(); } if (!cab.ExtractCab(sFilename, strDirBuf, m_strFile)) { if (NOT_A_CAB == cab.m_nError) { // The file may be uncompressed already.
bDelete = FALSE; } else { ReportError(TSERR_ENGINE_EXTRACT); } } else { // Normal cab file expanded successfully.
sFilename = strDirBuf; sFilename += cab.GetLastFile(); DWORD dwAttribs = GetFileAttributes((LPCTSTR) sFilename); dwAttribs = dwAttribs & ~FILE_ATTRIBUTE_READONLY; SetFileAttributes((LPCTSTR) sFilename, dwAttribs); bDelete = TRUE; } } /*
if (!BReadModel(sFilename #ifdef _DEBUG
, "BNTSError.log" #endif
)) ReportError(TSERR_ENGINE); */ m_strModelFile = sFilename; m_bDeleteModelFile = bDelete; // Compare the crc value in the cache file with the crc of the dsc file.
// If they match, fill the cache.
CCRC crc; try { if (crc.Decode(sFilename, strCacheFile, strCacheFileWithinCHM)) AddToCache(strCacheFile, strCacheFileWithinCHM); else ReadTheDscModel(TSERR_ENGINE_BNTS_READ_CACH); } catch(CGenException *p) { delete p; ReadTheDscModel(TSERR_ENGINE_BNTS_READ_GEN); }
// if (bDelete)
// DeleteFile(sFilename);
m_probask = idhFirst + CNode(); m_bModelRead = TRUE; return m_dwErr; }
// Number of nodes whose states were set at program startup by TSLaunchServ.
UINT BCache::StatesFromServ() { return m_pHttpQuery ? m_pHttpQuery->StatesFromServ() : 0; }
// Number of nodes whose states are now set
UINT BCache::StatesNowSet() { return (UINT)m_NodeState.GetCount(); }
//
//
DWORD BCache::Initialize(/*CWordList *pWXList*/) {
if (NULL != m_pCache) delete m_pCache; m_pCache = new CBNCache(); if (!m_pCache) m_dwErr = EV_GTS_ERROR_IDX_ALLOC_CACHE;
ResetNodes();
if (!BValidNet()) ReadModel(); return m_dwErr; }
// override the default function
//
// look for possible returns in the header file
//
int BCache::GTSGetRecommendations(CNID& cnid, NID rgnid[], bool bSniffed) { BN_CACHE_ITEM SetupItem; SetupItem.uNodeCount = m_cnid; SetupItem.uName = m_rgnid; SetupItem.uValue = m_rgist; int state = SNIFF_INVALID_STATE; int label = SNIFF_INVALID_NODE_LABEL;
//AfxDebugBreak();
// set initial non-sniffed value in array of sniffed states
if (!bSniffed && !IsReverse()) m_rgsniff[m_cnid-1] = 0;
// flush array of sniffed nodes recently traversed
if (!bSniffed) m_arrNidLastSniffed.RemoveAll(); if (m_pCache->FindCacheItem(&SetupItem, cnid, rgnid)) { if (GetState(*rgnid, &state)) // sniffer has this information and can answer what state this node has
{ if (NodeSet(*rgnid, state, false)) // set sniffed node current and set its state
{ SetAdditionalDataOnNodeSet(*rgnid); return GTSGetRecommendations(cnid, rgnid, true); // recursive call - hope BNTS will not recommend a node which is set
} } else { return RECOMMEND_SUCCESS; } } if (m_bNeedModel) { ReadTheDscModel(TSERR_ENGINE_BNTS_REC); }
if (BGetRecommendations()) { cnid = CInt(); if (cnid > 0) { const int *pInt = RgInt(); memcpy(rgnid, pInt, cnid * sizeof(pInt[0])); SetupItem.uNodeCount = m_cnid; SetupItem.uName = m_rgnid; SetupItem.uValue = m_rgist; SetupItem.uRecCount = cnid; SetupItem.uRec = rgnid;
m_pCache->AddCacheItem(&SetupItem); if (GetState(*rgnid, &state)) // sniffer has this information and can answer what state this node has
{ if (NodeSet(*rgnid, state, false)) // set sniffed node current and set its state
{ SetAdditionalDataOnNodeSet(*rgnid); return GTSGetRecommendations(cnid, rgnid, true); // recursive call - hope BNTS will not recommend a node which is set
} } return RECOMMEND_SUCCESS; } else { rgnid[0] = nidService; cnid = 1; return RECOMMEND_NO_MORE_DATA; } } else { // the last node was sniffed and its state was set
// after that we received FALSE from BGetRecommendation;
// we unset this node (in order to be able to use BGetRecommendation later on);
// we return value indicating that BNTS cannot give us any recommendations
NodeSet(m_rgnid[m_cnid-1], -1, false); return RECOMMEND_NO_MORE_DATA; }
return RECOMMEND_FAIL; }
void BCache::SetAdditionalDataOnNodeSet(NID nid) { m_rgsniff[m_cnid-1] = 1; m_arrNidLastSniffed.Add(nid); }
BOOL InArray(UINT num, UINT aNums[], UINT max) { UINT x = max; BOOL bRes = FALSE; for (UINT y = 0; y < x; y++) { if (aNums[y] == num) { bRes = TRUE; break; } } return bRes; }
// RemoveRecommendations is called for nodes whos' state is less than 100.
void BCache::RemoveRecommendation(int Nid) { VERIFY(BNodeSetCurrent(Nid)); BNodeSet(-1, false); if (m_cnid) m_cnid--; return; }
//
//
UINT GTSAPI::GetNodeList(NID **pNid, IST **pIst) { *pNid = m_rgnid; *pIst = m_rgist; return m_cnid; }
BOOL GTSAPI::BNodeSetCurrent(int node) { return BNTS::BNodeSetCurrent(node); }
//
//
BOOL BCache::NodeSet(NID nid, IST ist, bool bPrevious) { BOOL bRes = FALSE;
// shouldn't happen...but to be safe
if (m_cnid >= MAX_NID) return FALSE;
m_rgnid[m_cnid] = nid; m_rgist[m_cnid] = ist;
if (false == bPrevious) { VERIFY(BNodeSetCurrent(nid)); bRes = BNodeSet(ist, false); if (bRes && // bnts worked successfully
-1 == GetIndexNodeInCache(nid) // this nid is not present in the cache
) m_cnid++; } else { bRes = TRUE; } return bRes; }
//
//
int BCache::GetIndexNodeInCache(NID nid) { for (unsigned int i = 0; i < m_cnid; i++) if (m_rgnid[i] == nid) return i; return -1; }
//
//
VOID BCache::ResetNodes() { for (UINT inid = 0; inid < m_cnid; inid++) { VERIFY(BNodeSetCurrent(m_rgnid[inid])); BNodeSet(-1, false); // Nil value
} m_cnid = 0; }
//
//
DWORD GTSAPI::GetStatus() { return m_dwErr; }
//
//
VOID GTSAPI::Destroy() { if (m_pchHtml) { delete [] m_pchHtml; m_pchHtml = NULL; }
/*
if (m_pWNList) { if (!m_dwErr) m_dwErr = m_pWNList->GetStatus(); delete m_pWNList; m_pWNList = NULL; } */ if (m_pCache) { if (!m_dwErr) m_dwErr = m_pCache->GetStatus(); delete m_pCache; m_pCache = NULL; } }
//
//
UINT GTSAPI::GetProblemArray(IDH **idh) { *idh = m_idstore; return m_currid; }
//
//
IDH GTSAPI::GetProblemAsk() { return m_probask; }
void GTSAPI::AddValue(int value) { ASSERT(m_currid < MAXPROBID); m_idstore[m_currid++] = value; return; }
BOOL BCache::CheckNode(int Node) { BOOL bCached = m_CacheGen.IsNodePresent(Node); if (!bCached && m_bNeedModel) { ReadTheDscModel(TSERR_ENGINE_BNTS_CHECK); } return bCached; }
//-------------------------------------------------------------
// BNTS Overrides to replace the dsc file with our cache.
// Need to override everything but BReadModel and BGetRecommendations.
int BCache::CNode() { int cNodes; if (FALSE == m_bNeedModel) cNodes = GTSAPI::CNode(); else cNodes = m_CacheGen.GetNodeCount(); return cNodes; }
BOOL BCache::BImpossible() { BOOL bImpossible = FALSE; if (FALSE == m_bNeedModel) bImpossible = GTSAPI::BImpossible(); return bImpossible; }
BOOL BCache::BNetPropItemStr(LPCTSTR szPropType, int index) { BOOL bGoodIndex = FALSE; char sznPropType[MAX_SYM_NAME_BUF_LEN]; int nPropLen = MAX_SYM_NAME_BUF_LEN; if (!GTSCacheGenerator::TcharToChar(sznPropType, szPropType, nPropLen)) return FALSE; if (CheckNode(m_CurNode)) { bGoodIndex = m_CacheGen.FindNetworkProperty(sznPropType, m_strResult, index); if (!bGoodIndex && !m_bNeedModel) { bGoodIndex = GTSAPI::BNetPropItemStr(szPropType, index); m_strResult = GTSAPI::SzcResult(); } } else { bGoodIndex = GTSAPI::BNetPropItemStr(szPropType, index); m_strResult = GTSAPI::SzcResult(); } return bGoodIndex; }
BOOL BCache::BNodeSetCurrent(int node) { BOOL bNodeSet = TRUE; if (CheckNode(node) && TRUE == m_bNeedModel) { m_CurNode = node; } else { bNodeSet = GTSAPI::BNodeSetCurrent(node); m_CurNode = node; } return bNodeSet; }
int BCache::INode(LPCTSTR szNodeSymName) { UINT index = 0; if (FALSE == m_bNeedModel) index = GTSAPI::INode(szNodeSymName); else if (!m_CacheGen.GetNodeIDFromSymName(szNodeSymName, index)) { // Have to have BNTS load the network and the the symbolic name.
ReadTheDscModel(TSERR_ENGINE_CACHE_LOW); index = GTSAPI::INode(szNodeSymName); } return (signed int) index; }
ESTDLBL BCache::ELblNode() { UINT NodeLable; ESTDLBL Lable; if (FALSE == m_bNeedModel) { Lable = GTSAPI::ELblNode(); } else { VERIFY(m_CacheGen.GetLabelOfNode(m_CurNode, NodeLable)); Lable = (ESTDLBL) NodeLable; } return Lable; }
int BCache::INodeCst() { int cStates = 2;
return cStates; }
BOOL GTSAPI::BNodeSet(int state, bool bset) { return BNTS::BNodeSet(state, bset); }
BOOL BCache::BNodeSet(int istate, bool bSet) { BOOL bNodeWasSet = TRUE; if (FALSE == m_bNeedModel) bNodeWasSet = GTSAPI::BNodeSet(istate, bSet); if (bNodeWasSet) { if (-1 != istate) m_NodeState.SetAt(m_CurNode, istate); else m_NodeState.RemoveKey(m_CurNode); } return bNodeWasSet; }
int BCache::INodeState() { // This is ok. See BNodeSet.
int state; if (!m_NodeState.Lookup(m_CurNode, state)) state = 0; return state; }
void BCache::NodeStateName(int istate) { if (FALSE == m_bNeedModel) { GTSAPI::NodeStateName(istate); m_strResult = GTSAPI::SzcResult(); } else { BOOL bFound; switch(istate) { case 0: bFound = m_CacheGen.FindNodeProperty(m_CurNode, G_S0_NAME, m_strResult, 0); break; case 1: bFound = m_CacheGen.FindNodeProperty(m_CurNode, G_S1_NAME, m_strResult, 0); break; default: bFound = FALSE; } if (!bFound) { ASSERT(FALSE); m_strResult = _T(""); } } return; }
void BCache::NodeSymName() { if (FALSE == m_bNeedModel) { GTSAPI::NodeSymName(); m_strResult = GTSAPI::SzcResult(); } else if (CheckNode(m_CurNode)) { VERIFY(m_CacheGen.FindNodeProperty(m_CurNode, G_SYMBOLIC_NAME, m_strResult, 0)); } return; }
void BCache::NodeFullName() { if (FALSE == m_bNeedModel) { GTSAPI::NodeFullName(); m_strResult = GTSAPI::SzcResult(); } else { VERIFY(m_CacheGen.FindNodeProperty(m_CurNode, G_FULL_NAME, m_strResult, 0)); } return; }
BOOL BCache::BNodePropItemStr(LPCTSTR szPropType, int index) { BOOL bGoodIndex = FALSE; char sznPropType[MAX_SYM_NAME_BUF_LEN]; int nPropTypeLen = MAX_SYM_NAME_BUF_LEN; if (!GTSCacheGenerator::TcharToChar(sznPropType, szPropType, nPropTypeLen)) return FALSE; if (FALSE == m_bNeedModel) { bGoodIndex = GTSAPI::BNodePropItemStr(szPropType, index); m_strResult = GTSAPI::SzcResult(); } else { bGoodIndex = m_CacheGen.FindNodeProperty(m_CurNode, sznPropType, m_strResult, index); } return bGoodIndex; }
bool BCache::BValidNet() { bool bValidNet; if (FALSE == m_bModelRead) // Set to true in BCache::ReadModel.
bValidNet = false; // Causes the readmodel function to be called.
else if (FALSE == m_bNeedModel) bValidNet = GTSAPI::BValidNet(); else bValidNet = true; return bValidNet; }
LPCTSTR BCache::SzcResult() const { return (LPCTSTR) m_strResult; }
const CArray<int, int>& BCache::GetArrLastSniffed() { return m_arrNidLastSniffed; }
int BCache::GetCountRecommendedNodes() { return m_cnid; }
int BCache::GetCountSniffedRecommendedNodes() { for (unsigned int i = 0, j = 0; i < m_cnid; i++) if (m_rgsniff[i] == 1) j++; return j; }
bool BCache::IsReverse() { return m_bReverse; }
void BCache::SetReverse(bool reverse) { m_bReverse = reverse; }
void BCache::SetRunWithKnownProblem(bool yes) { m_bRunWithKnownProblem = yes; }
bool BCache::IsRunWithKnownProblem() { return m_bRunWithKnownProblem; }
|