// // 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 #include #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 &newnodes, CArray &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;iBNodeSetCurrent(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;iBNodeSetCurrent(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;jCInt() && !bEnd) { // have rec CArray 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;iBNodeSetCurrent(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 &nodes, CArray &states) { m_oldnodes.Copy(nodes); int count = (int)nodes.GetSize(); if (!count) return; LogOut(_T("\nSetNodes:")); for (int j=0;jBNodeSetCurrent(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;jnodestringcount;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;jnodestringcount;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;juName[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;juRec[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; }