typedef struct { PCNRITEM pci; PSZ pszFileName; BOOL bAllocated; } PCIHIST, *PPCIHIST; #define PciMaint(a, b) PciMaint2(a, b, pszSrcFile, __LINE__) void PciMaint2(PCNRITEM pci, BOOL bPciAllocation, PSZ pszSource, int iLine) { #define HIST_COUNT 1000 static HMTX hmtxPciTable = NULLHANDLE; static PPCIHIST pHistory = NULL; static USHORT usAllocations = 1; ULONG ulNumStructs = usAllocations * HIST_COUNT; UINT i, i2; APIRET rc; char szFile[CCHMAXPATH]; if (!hmtxPciTable) { rc = DosCreateMutexSem(NULL, &hmtxPciTable, 0L, TRUE); if (rc) { fprintf(stderr, "Unable to create pcitable mutex: %d\n", rc); fflush(stderr); return; } pHistory = xmalloc(HIST_COUNT * usAllocations * sizeof(PCIHIST), pszSrcFile, __LINE__); memset((void *)pHistory, 0, HIST_COUNT * sizeof(PCIHIST)); } else { rc = DosRequestMutexSem(hmtxPciTable, SEM_INDEFINITE_WAIT); if (rc) { fprintf(stderr, "Error requesting mutex: %d\n", rc); fflush(stderr); return; } } strcpy(szFile, ((pci->pszFileName && *pci->pszFileName) ? pci->pszFileName : "N/A")); fprintf(stderr, "PciMaint entry. pci: %08x New: %c Line: %d src: %s file: %s\n", pci, (bPciAllocation ? 'Y' : 'N'), iLine, pszSource, szFile); if (!pci) { DosReleaseMutexSem(hmtxPciTable); fflush(stderr); return; } for (i = 0; i < ulNumStructs; i++) { if (!pHistory[i].pci || pHistory[i].pci == pci) break; } if (i == ulNumStructs) { fprintf(stderr, "PciMaint history reallocation: %d\n", usAllocations++); ulNumStructs += HIST_COUNT; pHistory = xrealloc(pHistory, usAllocations * HIST_COUNT * sizeof(PCIHIST), pszSrcFile, __LINE__); usAllocations++; for (i2 = i; i2 < i + HIST_COUNT; i2++) { pHistory[i2].pci = NULL; } } if (bPciAllocation) { if (!pHistory[i].pci) { fprintf(stderr, "PciMaint using new slot %d\n", i); pHistory[i].pci = pci; pHistory[i].bAllocated = TRUE; if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } else { if (pHistory[i].bAllocated) { // Error: repeat allocation w/o intervening dealloc strcpy(szFile, (pHistory[i].pszFileName ? pHistory[i].pszFileName : "N/A")); fprintf(stderr, "PciMaint error: Missed dealloc or repeat alloc for pci: %08x slot: %d prev file: %s\n", pci, i, szFile); pHistory[i].pci = pci; pHistory[i].bAllocated = TRUE; if (pHistory[i].pszFileName && (pHistory[i].pszFileName != NullStr)) free(pHistory[i].pszFileName); if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } else { // OK, realloc deallocated pci fprintf(stderr, "PciMaint re-using slot %d\n", i); pHistory[i].bAllocated = TRUE; if (pHistory[i].pszFileName && (pHistory[i].pszFileName != NullStr)) free(pHistory[i].pszFileName); if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } } } else { // Deallocation if (!pHistory[i].pci) { // Error: not previously allocated fprintf(stderr, "PCiMaint error: Missed alloc or dealloc before alloc for pci: %08x slot %d\n", pci, i); if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } else { if (pHistory[i].bAllocated) { fprintf(stderr, "PciMaint deallocating slot %d\n", i); pHistory[i].bAllocated = FALSE; if (pHistory[i].pszFileName && (pHistory[i].pszFileName != NullStr)) free(pHistory[i].pszFileName); if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } else { // Error: 2x free fprintf(stderr, "PCiMaint error: Missed alloc or repeat dealloc pci: %08x slot: %d prev. file: %s\n", pci, i); if (pHistory[i].pszFileName && (pHistory[i].pszFileName != NullStr)) free(pHistory[i].pszFileName); if (pci->pszFileName && *pci->pszFileName) { pHistory[i].pszFileName = xstrdup(pci->pszFileName, pszSrcFile, __LINE__); } else { pHistory[i].pszFileName = NULL; } } } } DosReleaseMutexSem(hmtxPciTable); fflush(stderr); return; }