windows-nt/Source/XPSP1/NT/enduser/troubleshoot/control/cachegen.cpp
2020-09-26 16:20:57 +08:00

874 lines
16 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// MODULE: CACHEGEN.CPP
//
// PURPOSE: Cache File Generator and Reader for BN Networks
//
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
//
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 support@saltmine.com
//
// AUTHOR: Roman Mach
//
// ORIGINAL DATE: 8/7/97
//
// NOTES:
// 1.
//
// Version Date By Comments
//--------------------------------------------------------------------
// V0.2 8/7/97 RM Local Version for Memphis
// V0.3 04/09/98 JM/OK+ Local Version for NT5
//
#include "stdafx.h"
#include <afxwin.h>
#include <afxtempl.h>
#include "apgts.h"
#include "bnts.h"
#include "cachegen.h"
#include "BackupInfo.h"
#include "apgtsinf.h"
#include "ChmRead.h"
int nodecomp(const void *elem1, const void *elem2);
//
//
GTSCacheGenerator::GTSCacheGenerator(BOOL bScanAll, const char *szLogFile, const char *szBNTSLogFile)
{
m_fp = NULL;
m_bScanAll = bScanAll;
m_szBNTSLogFile = szBNTSLogFile;
if (szLogFile != NULL)
m_fp = fopen(szLogFile, "w");
m_nCount = 0;
m_nItemCount = 0;
m_headposition = 0;
m_filedata = NULL;
m_netstartoffset = 0;
m_nodeorder = NULL;
}
//
//
GTSCacheGenerator::~GTSCacheGenerator()
{
if (m_fp)
fclose(m_fp);
if (m_filedata)
free(m_filedata);
if (m_nodeorder)
free(m_nodeorder);
}
bool GTSCacheGenerator::TcharToChar(char szOut[], LPCTSTR szIn, int &OutLen)
{
int x = 0;
while(NULL != szIn[x] && x < OutLen)
{
szOut[x] = (char) szIn[x];
x++;
}
if (x < OutLen)
szOut[x] = NULL;
return x < OutLen;
}
//
//
/*
void GTSCacheGenerator::LogOut(TCHAR *szcFormat, ...)
{
va_list ptr;
if (!m_fp)
return;
if (!szcFormat)
return;
va_start(ptr, szcFormat);
vfprintf(m_fp, szcFormat, ptr);
va_end(ptr);
}
*/
#ifdef _DEBUG
#define LogOut ::AfxTrace
//#define LogOut 1 ? (void)0 : ::AfxTrace
#else
#define LogOut 1 ? (void)0 : ::AfxTrace
#endif
//
//
int nodecomp(const void *elem1, const void *elem2)
{
return (((GTS_NODE_ORDER *)elem1)->depth - ((GTS_NODE_ORDER *)elem2)->depth);
}
//
//
void GTSCacheGenerator::SaveNetItem(CPtrList *nsp, BNTS *bp, FILE *fp, LPCSTR name)
{
GTS_NODE_ITEM *ni;
if (!bp->BNetPropItemStr( name, 0 ))
return;
ni = new GTS_NODE_ITEM(name);
int j = 0;
while (bp->BNetPropItemStr( name, j++ ))
{
CString sTemp = bp->SzcResult();
ni->sStringArr.Add(sTemp);
}
nsp->AddTail(ni);
}
//
//
BOOL GTSCacheGenerator::NodeTraverse( FILE *fp,
BNTS *bp,
int depth,
CArray<int,int> &newnodes,
CArray<int,int> &newstates,
int currnode,
int currstate)
{
BOOL bEnd = FALSE;
int i, j;
if (depth > 30)
{
LogOut(_T("Depth Exceeded\n"));
return FALSE;
}
// uninstantiate
UninstantiateAll(bp);
newnodes.Add(currnode);
newstates.Add(currstate);
depth++;
for (i=0;i<newnodes.GetSize();i++)
{
if (bp->BNodeSetCurrent(newnodes[i]))
{
bp->NodeSymName();
CString sTemp = bp->SzcResult();
LogOut(_T("%s"), sTemp);
ESTDLBL albl = bp->ELblNode();
if (albl == ESTDLBL_problem)
{
LogOut(_T("(prob)"));
}
else if (albl == ESTDLBL_info)
{
LogOut(_T("(info)"));
}
else if (albl == ESTDLBL_fixobs ||
albl == ESTDLBL_fixunobs ||
albl == ESTDLBL_unfix)
{
LogOut(_T("(fix)"));
}
else
{
LogOut(_T("(?)"));
}
}
LogOut(_T("(%d=%d) "), newnodes[i], newstates[i]);
}
SetNodes( bp, newnodes, newstates );
BOOL bRec = FALSE;
if (!bp->BGetRecommendations())
{
bRec = TRUE;
}
else
{
}
const int *rg = bp->RgInt();
i = 0;
if (bRec)
{
if (bp->BImpossible())
{
LogOut(_T("IMPOSSIBLE\n"));
}
else
{
LogOut(_T("RECOMMENDATION ERROR\n"));
}
}
else
{
if (bp->BImpossible())
{
LogOut(_T("IMPOSSIBLE (Have Rec)\n"));
}
else
{
int reccount = bp->CInt();
if (reccount)
{
int nodecount = (int)newstates.GetSize();
if (nodecount)
{
BOOL bFound = FALSE;
for (i=0;i<reccount;i++)
{
bFound = FALSE;
for (j=0;j<nodecount;j++)
{
if (newnodes[j] == rg[i])
{
bFound = TRUE;
break;
}
}
if (!bFound)
break;
}
if (!bFound)
{
LogOut(_T("RECOMMENDATION: "));
if (bp->BNodeSetCurrent(rg[i]))
{
CString sTemp1 = "Error";
CString sTemp2 = "Error";
if (bp->BNodePropItemStr( "HNodeHd", 0 ))
sTemp1 = bp->SzcResult();
bp->NodeSymName();
sTemp2 = bp->SzcResult();
LogOut(_T("%s (%s) (Node: %d)"), sTemp1, sTemp2, rg[i]);
if (m_nodeorder)
{
if (m_nodeorder[rg[i]].depth > depth)
m_nodeorder[rg[i]].depth = depth;
}
UINT realcount = 0;
for (j=0;j<nodecount;j++)
if (newstates[j] != STATE_UNKNOWN)
realcount++;
fwrite(&realcount, sizeof (UINT), 1, fp);
for (j=0;j<nodecount;j++)
if (newstates[j] != STATE_UNKNOWN)
{
GTS_CACHE_NODE cnode;
cnode.node = newnodes[j];
cnode.state = newstates[j];
fwrite(&cnode, sizeof (cnode), 1, fp);
}
// write to cache out file
UINT ucount = reccount;
fwrite(&ucount, sizeof (UINT), 1, fp);
for (j=0;j<reccount;j++)
{
UINT rgval = rg[j];
fwrite(&rgval, sizeof (UINT), 1, fp);
}
m_nCount++;
}
LogOut(_T("\n"));
}
else
{
LogOut(_T("NO RECOMMENDATIONS - ALL AVAILABLE MARKED AS UNKNOWN\n"));
bEnd = TRUE;
}
}
else
LogOut(_T("STATE COUNT 0 - INTERNAL ERROR\n"));
}
else
LogOut(_T("NO RECOMMENDATIONS\n"));
}
}
LogOut(_T("\n"));
// recommendations - let's figure out what to do with them
// the first rec in the returned array will be array[1] in the set array
// so we have to watch for that
if (bp->CInt() && !bEnd)
{
// have rec
CArray<int,int> states;
int node = rg[i];
if (bp->BNodeSetCurrent(node))
{
ESTDLBL albl = bp->ELblNode();
if (albl == ESTDLBL_info)
{
states.Add(0);
states.Add(1);
if (m_bScanAll)
states.Add(STATE_UNKNOWN);
}
else if (albl == ESTDLBL_fixobs ||
albl == ESTDLBL_fixunobs ||
albl == ESTDLBL_unfix)
{
states.Add(0);
if (m_bScanAll)
states.Add(STATE_UNKNOWN);
}
else
{
LogOut(_T("Unexpected Node Type\n"));
}
}
else
LogOut(_T("Can't set node current\n"));
int count = (int)states.GetSize();
for (i=0;i<count;i++)
{
if (!NodeTraverse( fp, bp, depth, newnodes, newstates, node, states[i] ))
return FALSE;
}
}
// done, remove references to our current node
newnodes.RemoveAt(depth - 1);
newstates.RemoveAt(depth - 1);
return TRUE;
}
//
//
void GTSCacheGenerator::UninstantiateAll(BNTS *bp)
{
int count = (int)m_oldnodes.GetSize();
// uninstantiate all nodes
if (!count)
return;
for (int j=0;j<count;j++)
{
if (bp->BNodeSetCurrent(m_oldnodes[j]))
{
if (bp->BNodeSet(-1))
{
}
else
{
LogOut(_T("Can't uninstantiate node\n"));
}
}
else
{
LogOut(_T("Can't set node %d to uninstantiate\n"), m_oldnodes[j]);
}
}
}
//
//
void GTSCacheGenerator::SetNodes(BNTS *bp, CArray<int,int> &nodes, CArray<int,int> &states)
{
m_oldnodes.Copy(nodes);
int count = (int)nodes.GetSize();
if (!count)
return;
LogOut(_T("\nSetNodes:"));
for (int j=0;j<count;j++)
{
if (bp->BNodeSetCurrent(nodes[j]))
{
if (states[j] != STATE_UNKNOWN)
{
LogOut(_T("(%d=%d)"), nodes[j], states[j]);
if (bp->BNodeSet(states[j], false))
{
}
else
{
LogOut(_T("Can't set node\n"));
}
}
else
LogOut(_T("(%d=X)"), nodes[j]);
}
else
LogOut(_T("Can't set node %d\n"), nodes[j]);
}
LogOut(_T("\n"));
}
//
//
BOOL GTSCacheGenerator::ReadCacheFileHeader(CString &sCacheFilename, const CString& strCacheFileWithinCHM)
{
GTS_CACHE_FILE_HEADER header;
bool bUseCHM = strCacheFileWithinCHM.GetLength() != 0;
if (bUseCHM)
{
DWORD size =0;
if (S_OK != ::ReadChmFile(sCacheFilename, strCacheFileWithinCHM, (void**)&m_filedata, &size))
{
return FALSE;
}
}
else
{
UINT size;
// must be binary
FILE *cfp = _tfopen(sCacheFilename, _T("rb"));
if (cfp==NULL)
{
LogOut(_T("Error opening cache file for reading\n"));
return FALSE;
}
// get file size
if (fseek(cfp, 0, SEEK_END))
{
LogOut(_T("Can't set pos to end of file\n"));
fclose(cfp);
return FALSE;
}
fpos_t position;
if (fgetpos(cfp, &position))
{
LogOut(_T("Can't get pos at end of file\n"));
fclose(cfp);
return FALSE;
}
size = (UINT) position;
rewind(cfp);
// allocate space for file
m_filedata = (char *) malloc(size);
if (m_filedata == NULL)
{
LogOut(_T("Error allocating memory\n"));
fclose(cfp);
return FALSE;
}
if (fread(m_filedata, size, 1, cfp) != 1)
{
LogOut(_T("Error reading file into memory\n"));
fclose(cfp);
return FALSE;
}
fclose(cfp);
}
memcpy(&header, m_filedata, sizeof(header));
if (memcmp(header.signature, GTS_CACHE_SIG, sizeof (header.signature)) != 0)
{
LogOut(_T("Bad file signature!\n"));
return FALSE;
}
if (!header.count)
{
LogOut(_T("No items in file!\n"));
return FALSE;
}
m_netstartoffset = header.netoffset;
LogOut(_T("ItemCount: %d\n"), header.count);
m_nItemCount = header.count;
m_cachepos = (GTS_CACHE_FILE_SETDATA *) (m_filedata + sizeof (GTS_CACHE_FILE_HEADER));
return TRUE;
}
//
//
BOOL GTSCacheGenerator::FindNetworkProperty(LPCSTR szName, CString &sResult, int index)
{
if (m_filedata == NULL)
return FALSE;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
GTS_CACHE_PROP_STR_BLK *netstrblk =
(GTS_CACHE_PROP_STR_BLK *) (m_filedata + netstart->netpropoffset);
for (UINT i = 0; i < netstart->netpropcount; i++, netstrblk++)
{
LPCSTR szItem = (LPCSTR) (m_filedata + netstrblk->nameoffset);
if (!strcmp(szName, szItem))
{
if (!index)
{
sResult = (LPCSTR) (m_filedata + netstrblk->stringoffset);
return TRUE;
}
else
{
LPCSTR szStrArrItem = (LPCSTR) (m_filedata + netstrblk->stringoffset);
int len = strlen(szStrArrItem);
for (int j=0;(j < index) && len ;j++)
{
szStrArrItem += len + 1;
len = strlen(szStrArrItem);
}
if (!len)
return FALSE;
sResult = szStrArrItem;
return TRUE;
}
}
}
return FALSE;
}
//
//
BOOL GTSCacheGenerator::FindNodeProperty(UINT nodeid, LPCSTR szName, CString &sResult, int index)
{
if (m_filedata == NULL)
return FALSE;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
GTS_CACHE_PROP_NODEOFF_BLK *nodeblk =
(GTS_CACHE_PROP_NODEOFF_BLK *) (m_filedata + m_netstartoffset + sizeof (GTS_CACHE_PROP_NETSTART_BLK));
for (UINT i = 0; i < netstart->nodecountfile; i++, nodeblk++)
{
if (nodeid == nodeblk->nodeid)
{
GTS_CACHE_PROP_NODESTART_BLK *nodestart =
(GTS_CACHE_PROP_NODESTART_BLK *)(m_filedata + nodeblk->nodeoffset);
GTS_CACHE_PROP_STR_BLK *nodestr =
(GTS_CACHE_PROP_STR_BLK *)(m_filedata + nodeblk->nodeoffset + sizeof (GTS_CACHE_PROP_NODESTART_BLK));
// now try to find string
for (UINT j=0;j<nodestart->nodestringcount;j++, nodestr++)
{
LPCSTR szItem = (LPCSTR) (m_filedata + nodestr->nameoffset);
if (!strcmp(szName, szItem))
{
if (!index)
{
sResult = (LPCSTR) (m_filedata + nodestr->stringoffset);
return TRUE;
}
else
{
LPCSTR szStrArrItem = (LPCSTR) (m_filedata + nodestr->stringoffset);
int len = strlen(szStrArrItem);
for (int j=0;(j < index) && len ;j++)
{
szStrArrItem += len + 1;
len = strlen(szStrArrItem);
}
if (!len)
return FALSE;
sResult = szStrArrItem;
return TRUE;
}
}
}
return FALSE;
}
}
return FALSE;
}
//
//
BOOL GTSCacheGenerator::IsNodePresent(UINT nodeid)
{
if (m_filedata == NULL)
return FALSE;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
GTS_CACHE_PROP_NODEOFF_BLK *nodeblk =
(GTS_CACHE_PROP_NODEOFF_BLK *) (m_filedata + m_netstartoffset + sizeof (GTS_CACHE_PROP_NETSTART_BLK));
for (UINT i = 0; i < netstart->nodecountfile; i++, nodeblk++)
{
if (nodeid == nodeblk->nodeid)
return TRUE;
}
return FALSE;
}
// returns the node count for the network, not what's in the file
//
int GTSCacheGenerator::GetNodeCount()
{
if (m_filedata == NULL)
return 0;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
return netstart->nodecountnetwork;
}
//
//
BOOL GTSCacheGenerator::GetNodeIDFromSymName(LPCTSTR szSymName, UINT &nodeid)
{
char sznSymName[MAX_SYM_NAME_BUF_LEN];
int nSymLen = MAX_SYM_NAME_BUF_LEN;
if (m_filedata == NULL)
return FALSE;
if (!TcharToChar(sznSymName, szSymName, nSymLen))
return FALSE;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
GTS_CACHE_PROP_NODEOFF_BLK *nodeblk =
(GTS_CACHE_PROP_NODEOFF_BLK *) (m_filedata + m_netstartoffset + sizeof (GTS_CACHE_PROP_NETSTART_BLK));
for (UINT i = 0; i < netstart->nodecountfile; i++, nodeblk++)
{
GTS_CACHE_PROP_NODESTART_BLK *nodestart =
(GTS_CACHE_PROP_NODESTART_BLK *)(m_filedata + nodeblk->nodeoffset);
GTS_CACHE_PROP_STR_BLK *nodestr =
(GTS_CACHE_PROP_STR_BLK *)(m_filedata + nodeblk->nodeoffset + sizeof (GTS_CACHE_PROP_NODESTART_BLK));
// now try to find string
for (UINT j=0;j<nodestart->nodestringcount;j++, nodestr++)
{
LPCSTR szItem = (LPCSTR) (m_filedata + nodestr->nameoffset);
if (!strcmp(G_SYMBOLIC_NAME, szItem))
{
if (!strcmp(sznSymName, (LPCSTR) (m_filedata + nodestr->stringoffset)))
{
nodeid = nodeblk->nodeid;
return TRUE;
}
break;
}
}
}
return FALSE;
}
//
//
BOOL GTSCacheGenerator::GetLabelOfNode(UINT nodeid, UINT &lbl)
{
if (m_filedata == NULL)
return FALSE;
GTS_CACHE_PROP_NETSTART_BLK *netstart =
(GTS_CACHE_PROP_NETSTART_BLK *)(m_filedata + m_netstartoffset);
GTS_CACHE_PROP_NODEOFF_BLK *nodeblk =
(GTS_CACHE_PROP_NODEOFF_BLK *) (m_filedata + m_netstartoffset + sizeof (GTS_CACHE_PROP_NETSTART_BLK));
for (UINT i = 0; i < netstart->nodecountfile; i++, nodeblk++)
{
if (nodeid == nodeblk->nodeid)
{
GTS_CACHE_PROP_NODESTART_BLK *nodestart =
(GTS_CACHE_PROP_NODESTART_BLK *)(m_filedata + nodeblk->nodeoffset);
lbl = nodestart->labelnode;
return TRUE;
}
}
return FALSE;
}
//
//
BOOL GTSCacheGenerator::GetNextCacheEntryFromFile(BOOL &bErr, CBNCache *pCache)
{
BOOL bStat = FALSE;
bErr = TRUE;
if (m_filedata == NULL)
return FALSE;
if (!m_nItemCount)
{
bErr = FALSE;
return FALSE;
}
m_nItemCount--;
BN_CACHE_ITEM CacheItem;
// initialize
CacheItem.uNodeCount = 0;
CacheItem.uRecCount = 0;
CacheItem.uName = NULL;
CacheItem.uValue = NULL;
CacheItem.uRec = NULL;
bStat = GetNCEFF(&CacheItem, pCache);
// free allocated space as necessary
if (CacheItem.uName)
free(CacheItem.uName);
if (CacheItem.uValue)
free(CacheItem.uValue);
if (CacheItem.uRec)
free(CacheItem.uRec);
if (!bStat)
{
bErr = TRUE;
return FALSE;
}
bErr = FALSE;
return TRUE;
}
//
//
BOOL GTSCacheGenerator::GetNCEFF(BN_CACHE_ITEM *pCacheItem, CBNCache *pCache)
{
UINT j;
UINT setcount;
UINT reccount;
GTS_CACHE_FILE_SETDATA *setp = m_cachepos;
setcount = setp->count;
if (!setcount || setcount > 1000)
{
LogOut(_T("Set Count out of bounds: %d\n"), setcount);
return FALSE;
}
// initialize
pCacheItem->uNodeCount = setcount;
pCacheItem->uName = (UINT *)malloc(setcount * sizeof (UINT));
pCacheItem->uValue = (UINT *)malloc(setcount * sizeof (UINT));
LogOut(_T("Count: %d\n"), setcount);
GTS_CACHE_NODE *cachenode = &setp->item[0];
// second, read in node = state pairs
for (j=0;j<setcount;j++, cachenode++)
{
pCacheItem->uName[j] = cachenode->node;
pCacheItem->uValue[j] = cachenode->state;
LogOut(_T("(%d,%d)"), cachenode->node, cachenode->state);
}
LogOut(_T("\n"));
GTS_CACHE_FILE_RECDATA *recp = (GTS_CACHE_FILE_RECDATA *) cachenode;
reccount = recp->count;
if (!reccount || reccount > 1000)
{
LogOut(_T("Rec Count out of bounds: %d\n"), reccount);
return FALSE;
}
pCacheItem->uRecCount = reccount;
pCacheItem->uRec = (UINT *)malloc(reccount * sizeof (UINT));
UINT *uitem = &recp->item[0];
for (j=0;j<reccount;j++, uitem++)
{
pCacheItem->uRec[j] = *uitem;
LogOut(_T("(%d)"), *uitem);
}
LogOut(_T("\n"));
if (!pCache->AddCacheItem(pCacheItem))
{
LogOut(_T("Error Adding Item To Cache\n"));
return FALSE;
}
m_cachepos = (GTS_CACHE_FILE_SETDATA *) uitem;
// success!
return TRUE;
}