VOID CheckHeap(VOID) { USHORT usSel; BYTE _huge * pHeapStart; BYTE _huge * pHeapEnd; BYTE _huge * pWork; USHORT rc; for (usSel = 0; usSel < MAX_SELECTORS; usSel++) { pHeapStart = rgpSegment[usSel]; if (!pHeapStart || pHeapStart == RESERVED_SEGMENT) continue; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE); if (rc) { CritMessage("FAT32: Protection VIOLATION in CheckHeap (SYS%d)", rc); Message("FAT32: Protection VIOLATION in CheckHeap (SYS%d)", rc); return; } pHeapEnd = pHeapStart + HEAP_SIZE; pWork = pHeapStart; while (pWork < pHeapEnd) pWork += BlockSize(pWork) + sizeof (ULONG); if (pWork != pHeapEnd) CritMessage("FAT32: Heap corruption found!"); } }
static BOOL RemoveVolume(PVOLINFO pVolInfo) { PVOLINFO pNext; USHORT rc; if (pGlobVolInfo == pVolInfo) { pGlobVolInfo = pVolInfo->pNextVolInfo; return TRUE; } pNext = (PVOLINFO)pGlobVolInfo; while (pNext) { rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pNext, sizeof (VOLINFO)); if (rc) { FatalMessage("FAT32: Protection VIOLATION in RemoveVolume!\n"); return FALSE; } if (pNext->pNextVolInfo == pVolInfo) { pNext->pNextVolInfo = pVolInfo->pNextVolInfo; return TRUE; } pNext = (PVOLINFO)pNext->pNextVolInfo; } return FALSE; }
USHORT GetLogBuffer(PBYTE pData, USHORT cbData, ULONG ulTimeOut) { USHORT rc; if (f32Parms.fInShutDown) return ERROR_ALREADY_SHUTDOWN; rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData); if (rc) { Message("FAT32: Protection VIOLATION in GetLogBuffer! (SYS%d)", rc); return rc; } _disable(); while (!fData && !f32Parms.fInShutDown) { rc = DevHelp_ProcBlock((ULONG)GetLogBuffer, ulTimeOut, WAIT_IS_INTERRUPTABLE); if (rc) { _enable(); return rc; } _disable(); } _enable(); if (f32Parms.fInShutDown) return ERROR_ALREADY_SHUTDOWN; strncpy(pData, szLogBuf, cbData); if (strlen(szLogBuf) > cbData) { memmove(szLogBuf, szLogBuf + cbData, strlen(szLogBuf + cbData) + 1); rc = ERROR_BUFFER_OVERFLOW; } else { *szLogBuf = 0; fData = FALSE; rc = 0; } return rc; }
/********************************************************************* * FindFreeSpace *********************************************************************/ void * FindFreeSpace(void * pStart, size_t tSize) { BYTE _huge * pHeapStart; BYTE _huge * pHeapEnd; BYTE _huge * pWork; BYTE _huge * pNext; USHORT rc; pHeapStart = pStart; pHeapEnd = pHeapStart + HEAP_SIZE; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE); if (rc) { CritMessage("FAT32: Protection VIOLATION in FindFreeSpace (SYS%d)", rc); Message("FAT32: Protection VIOLATION in FindFreeSpace (SYS%d)", rc); return NULL; } pWork = pHeapStart; while (pWork < pHeapEnd) { if (BlockSize(pWork) >= tSize && IsBlockFree(pWork)) { ULONG ulRemaining = BlockSize(pWork) - tSize; if (ulRemaining > sizeof (ULONG)) { pNext = pWork + sizeof (ULONG) + tSize; SetBlockSize(pNext, BlockSize(pWork) - tSize - sizeof (ULONG)); SetFree(pNext); SetBlockSize(pWork, tSize); } SetInUse(pWork); return pWork + sizeof (ULONG); } pWork += BlockSize(pWork) + sizeof (ULONG); } return NULL; }
int far pascal __loadds FS_FINDFIRST(struct cdfsi far * pcdfsi, /* pcdfsi */ struct cdfsd far * pcdfsd, /* pcdfsd */ char far * pName, /* pName */ unsigned short usCurDirEnd, /* iCurDirEnd */ unsigned short usAttr, /* attr */ struct fsfsi far * pfsfsi, /* pfsfsi */ struct fsfsd far * pfsfsd, /* pfsfsd */ char far * pData, /* pData */ unsigned short cbData, /* cbData */ unsigned short far * pcMatch, /* pcMatch */ unsigned short usLevel, /* level */ unsigned short usFlags) /* flags */ { PVOLINFO pVolInfo; PFINDINFO pFindInfo = (PFINDINFO)pfsfsd; USHORT rc; USHORT usIndex; USHORT usNeededLen; USHORT usNumClusters; ULONG ulCluster; ULONG ulDirCluster; PSZ pSearch; PFINFO pNext; ULONG ulNeededSpace; USHORT usEntriesWanted; EAOP EAOP; PROCINFO ProcInfo; if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDFIRST for %s attr %X, Level %d, cbData %u, MaxEntries %u", pName, usAttr, usLevel, cbData, *pcMatch); usEntriesWanted = *pcMatch; *pcMatch = 0; if (strlen(pName) > FAT32MAXPATH) { rc = ERROR_FILENAME_EXCED_RANGE; goto FS_FINDFIRSTEXIT; } memset(pfsfsd, 0, sizeof (struct fsfsd)); pVolInfo = GetVolInfo(pfsfsi->fsi_hVPB); if (IsDriveLocked(pVolInfo)) { rc = ERROR_DRIVE_LOCKED; goto FS_FINDFIRSTEXIT; } switch (usLevel) { case FIL_STANDARD : usNeededLen = sizeof (FILEFNDBUF) - CCHMAXPATHCOMP; break; case FIL_QUERYEASIZE : usNeededLen = sizeof (FILEFNDBUF2) - CCHMAXPATHCOMP; break; case FIL_QUERYEASFROMLIST : usNeededLen = sizeof (EAOP) + sizeof (FILEFNDBUF3) + sizeof (ULONG); break; default : rc = ERROR_NOT_SUPPORTED; goto FS_FINDFIRSTEXIT; } if (usFlags == FF_GETPOS) usNeededLen += sizeof (ULONG); if (cbData < usNeededLen) { rc = ERROR_BUFFER_OVERFLOW; goto FS_FINDFIRSTEXIT; } rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData); if (rc) { Message("FAT32: Protection VIOLATION in FS_FINDFIRST! (SYS%d)", rc); return rc; } if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(&EAOP, pData, sizeof (EAOP)); rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)EAOP.fpGEAList, (USHORT)EAOP.fpGEAList->cbList); if (rc) goto FS_FINDFIRSTEXIT; } memset(pData, 0, cbData); usNumClusters = 0; ulDirCluster = FindDirCluster(pVolInfo, pcdfsi, pcdfsd, pName, usCurDirEnd, RETURN_PARENT_DIR, &pSearch); if (ulDirCluster == FAT_EOF) { rc = ERROR_PATH_NOT_FOUND; goto FS_FINDFIRSTEXIT; } ulCluster = ulDirCluster; while (ulCluster && ulCluster != FAT_EOF) { usNumClusters++; ulCluster = GetNextCluster( pVolInfo, ulCluster); } ulNeededSpace = sizeof (FINFO) + (usNumClusters - 1) * sizeof (ULONG); ulNeededSpace += pVolInfo->usClusterSize; GetProcInfo(&ProcInfo, sizeof ProcInfo); pFindInfo->pInfo = (PFINFO)malloc((size_t)ulNeededSpace); if (!pFindInfo->pInfo) { rc = ERROR_NOT_ENOUGH_MEMORY; goto FS_FINDFIRSTEXIT; } memset(pFindInfo->pInfo, 0, (size_t)ulNeededSpace); if (!pVolInfo->pFindInfo) pVolInfo->pFindInfo = pFindInfo->pInfo; else { pNext = (PFINFO)pVolInfo->pFindInfo; while (pNext->pNextEntry) pNext = (PFINFO)pNext->pNextEntry; pNext->pNextEntry = pFindInfo->pInfo; } memcpy(&pFindInfo->pInfo->EAOP, &EAOP, sizeof (EAOP)); pFindInfo->usEntriesPerCluster = pVolInfo->usClusterSize / sizeof (DIRENTRY); pFindInfo->usClusterIndex = 0; pFindInfo->pInfo->rgClusters[0] = ulDirCluster; pFindInfo->usTotalClusters = usNumClusters; pFindInfo->pInfo->pDirEntries = (PDIRENTRY)(&pFindInfo->pInfo->rgClusters[usNumClusters]); if (f32Parms.fMessageActive & LOG_FIND) Message("pInfo at %lX, pDirEntries at %lX", pFindInfo->pInfo, pFindInfo->pInfo->pDirEntries); pFindInfo->pInfo->pNextEntry = NULL; memcpy(&pFindInfo->pInfo->ProcInfo, &ProcInfo, sizeof (PROCINFO)); strcpy(pFindInfo->pInfo->szSearch, pSearch); FSH_UPPERCASE(pFindInfo->pInfo->szSearch, sizeof pFindInfo->pInfo->szSearch, pFindInfo->pInfo->szSearch); pFindInfo->ulMaxEntry = ((ULONG)pVolInfo->usClusterSize / sizeof (DIRENTRY)) * usNumClusters; if (!GetCluster(pVolInfo, pFindInfo, 0)) { rc = ERROR_SYS_INTERNAL; goto FS_FINDFIRSTEXIT; } pFindInfo->ulCurEntry = 0; if (usAttr & 0x0040) { pFindInfo->fLongNames = TRUE; usAttr &= ~0x0040; } else pFindInfo->fLongNames = FALSE; pFindInfo->bMustAttr = (BYTE)(usAttr >> 8); usAttr |= (FILE_READONLY | FILE_ARCHIVED); usAttr &= (FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY | FILE_ARCHIVED); pFindInfo->bAttr = (BYTE)~usAttr; if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(pData, &pFindInfo->pInfo->EAOP, sizeof (EAOP)); pData += sizeof (EAOP); cbData -= sizeof (EAOP); } rc = 0; for (usIndex = 0; usIndex < usEntriesWanted; usIndex++) { PULONG pulOrdinal; if (usFlags == FF_GETPOS) { if (cbData < sizeof (ULONG)) { rc = ERROR_BUFFER_OVERFLOW; break; } pulOrdinal = (PULONG)pData; pData += sizeof (ULONG); cbData -= sizeof (ULONG); } rc = FillDirEntry(pVolInfo, &pData, &cbData, pFindInfo, usLevel); if (!rc || (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0)) { if (usFlags == FF_GETPOS) *pulOrdinal = pFindInfo->ulCurEntry - 1; } if (rc) break; } if ((rc == ERROR_NO_MORE_FILES || rc == ERROR_BUFFER_OVERFLOW || rc == ERROR_EAS_DIDNT_FIT) && usIndex > 0) rc = 0; if (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0) usIndex = 1; *pcMatch = usIndex; FS_FINDFIRSTEXIT: if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDFIRST returned %d (%d entries)", rc, *pcMatch); if (rc && rc != ERROR_EAS_DIDNT_FIT) { FS_FINDCLOSE(pfsfsi, pfsfsd); } return rc; }
int far pascal __loadds FS_FINDNEXT( struct fsfsi far * pfsfsi, /* pfsfsi */ struct fsfsd far * pfsfsd, /* pfsfsd */ char far * pData, /* pData */ unsigned short cbData, /* cbData */ unsigned short far * pcMatch, /* pcMatch */ unsigned short usLevel, /* level */ unsigned short usFlags /* flag */ ) { PVOLINFO pVolInfo; PFINDINFO pFindInfo = (PFINDINFO)pfsfsd; USHORT rc; USHORT usIndex; USHORT usNeededLen; USHORT usEntriesWanted; if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDNEXT, level %u, cbData %u, MaxEntries %u", usLevel, cbData, *pcMatch); usEntriesWanted = *pcMatch; *pcMatch = 0; pVolInfo = GetVolInfo(pfsfsi->fsi_hVPB); if (IsDriveLocked(pVolInfo)) { rc = ERROR_DRIVE_LOCKED; goto FS_FINDNEXTEXIT; } switch (usLevel) { case FIL_STANDARD : usNeededLen = sizeof (FILEFNDBUF) - CCHMAXPATHCOMP; break; case FIL_QUERYEASIZE : usNeededLen = sizeof (FILEFNDBUF2) - CCHMAXPATHCOMP; break; case FIL_QUERYEASFROMLIST : usNeededLen = sizeof (EAOP) + sizeof (FILEFNDBUF3) + sizeof (ULONG); break; default : rc = ERROR_NOT_SUPPORTED; goto FS_FINDNEXTEXIT; } if (usFlags == FF_GETPOS) usNeededLen += sizeof (ULONG); if (cbData < usNeededLen) { rc = ERROR_BUFFER_OVERFLOW; goto FS_FINDNEXTEXIT; } rc = MY_PROBEBUF(PB_OPWRITE, pData, cbData); if (rc) { Message("FAT32: Protection VIOLATION in FS_FINDNEXT!"); return rc; } if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(&pFindInfo->pInfo->EAOP, pData, sizeof (EAOP)); rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pFindInfo->pInfo->EAOP.fpGEAList, (USHORT)pFindInfo->pInfo->EAOP.fpGEAList->cbList); if (rc) goto FS_FINDNEXTEXIT; } memset(pData, 0, cbData); if (usLevel == FIL_QUERYEASFROMLIST) { memcpy(pData, &pFindInfo->pInfo->EAOP, sizeof (EAOP)); pData += sizeof (EAOP); cbData -= sizeof (EAOP); } rc = 0; for (usIndex = 0; usIndex < usEntriesWanted; usIndex++) { PULONG pulOrdinal = NULL; if (usFlags == FF_GETPOS) { if (cbData < sizeof (ULONG)) { rc = ERROR_BUFFER_OVERFLOW; break; } pulOrdinal = (PULONG)pData; pData += sizeof (ULONG); cbData -= sizeof (ULONG); } rc = FillDirEntry(pVolInfo, &pData, &cbData, pFindInfo, usLevel); if (!rc || (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0)) { if (usFlags == FF_GETPOS) *pulOrdinal = pFindInfo->ulCurEntry - 1; } if (rc) break; } if ((rc == ERROR_NO_MORE_FILES || rc == ERROR_BUFFER_OVERFLOW || rc == ERROR_EAS_DIDNT_FIT) && usIndex > 0) rc = 0; if (rc == ERROR_EAS_DIDNT_FIT && usIndex == 0) usIndex = 1; *pcMatch = usIndex; FS_FINDNEXTEXIT: if (f32Parms.fMessageActive & LOG_FS) Message("FS_FINDNEXT returned %d (%d entries)", rc, *pcMatch); return rc; }
void cdecl free(void * pntr) #endif { USHORT usSel; BYTE _huge * pHeapStart; BYTE _huge * pHeapEnd; BYTE _huge * pWork; BYTE _huge * pToFree = pntr; BYTE _huge * pPrev; BYTE _huge * pNext; USHORT rc; if (f32Parms.fMessageActive & LOG_MEM) Message("free %lX", pntr); // CheckHeap(); if (OFFSETOF(pntr) == 0) { freeseg(pntr); return; } GetMemAccess(); for (usSel = 0; usSel < MAX_SELECTORS; usSel++) { if (SELECTOROF(pntr) == SELECTOROF(rgpSegment[usSel])) break; } if (usSel == MAX_SELECTORS) { CritMessage("FAT32: %lX not found in free!", pntr); Message("FAT32: %lX not found in free!", pntr); ReleaseMemAccess(); return; } pHeapStart = rgpSegment[usSel]; pHeapEnd = pHeapStart + HEAP_SIZE; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE); if (rc) { CritMessage("FAT32: Protection VIOLATION in free (SYS%d)", rc); Message("FAT32: Protection VIOLATION in free (SYS%d)", rc); ReleaseMemAccess(); return; } pWork = pHeapStart; pPrev = NULL; while (pWork < pHeapEnd) { if (pWork + sizeof (ULONG) == pToFree) { if (pPrev && IsBlockFree(pPrev)) { SetBlockSize(pPrev, BlockSize(pPrev) + BlockSize(pWork) + sizeof (ULONG)); pWork = pPrev; } pNext = pWork + BlockSize(pWork) + sizeof (ULONG); if (pNext < pHeapEnd && IsBlockFree(pNext)) SetBlockSize(pWork, BlockSize(pWork) + BlockSize(pNext) + sizeof (ULONG)); SetFree(pWork); break; } else pPrev = pWork; pWork += BlockSize(pWork) + sizeof (ULONG); } if (pWork >= pHeapEnd) { CritMessage("FAT32: ERROR: Address not found in free"); Message("ERROR: Address not found in free"); ReleaseMemAccess(); return; } /* free selector if no longer needed */ if (usSel > 0 && BlockSize(rgpSegment[usSel]) == (HEAP_SIZE - sizeof (ULONG)) && IsBlockFree(rgpSegment[usSel])) { PBYTE p = rgpSegment[usSel]; rgpSegment[usSel] = NULL; freeseg(p); } ReleaseMemAccess(); }
USHORT usModifyEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP) { USHORT rc; PFEALIST pTarFeal; PFEALIST pSrcFeal; PBYTE pSrcMax; PFEA pSrcFea; PFEA pTarFea; if (f32Parms.fMessageActive & LOG_EAS) Message("usModifyEAS for %s", pszFileName); /* Do not allow ea's file files with no filename (root) */ if (!strlen(pszFileName)) return 284; rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP)); if (rc) { Message("Protection violation in usModifyEAS (1) at %lX", pEAOP); return rc; } pSrcFeal = pEAOP->fpFEAList; if (pSrcFeal->cbList > MAX_EA_SIZE) return ERROR_EA_LIST_TOO_LONG; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pSrcFeal, (USHORT)pSrcFeal->cbList); if (rc) { Message("Protection violation in usModifyEAS (2) at %lX", pSrcFeal); return rc; } if (pSrcFeal->cbList <= sizeof (ULONG)) return 0; rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pTarFeal, TRUE); if (rc) return rc; if (f32Parms.fMessageActive & LOG_EAS) Message("cbList before = %lu", pTarFeal->cbList); pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList; pSrcFea = pSrcFeal->list; while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax) { PBYTE pName; USHORT usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if ((PBYTE)pSrcFea + usNewSize > pSrcMax) { pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP; rc = ERROR_EA_LIST_INCONSISTENT; goto usStoreEASExit; } pName = (PBYTE)(pSrcFea + 1); rc = FSH_CHECKEANAME(0x0001, pSrcFea->cbName, pName); if (rc && pSrcFea->cbValue) { pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP; goto usStoreEASExit; } if (!pSrcFea->cbValue || !pSrcFea->cbName) usNewSize = 0; else usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; pTarFea = FindEA(pTarFeal, pName, pSrcFea->cbName); if (!pTarFea) { pTarFea = (PFEA)((PBYTE)pTarFeal + pTarFeal->cbList); if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)usNewSize) { rc = ERROR_EAS_DIDNT_FIT; goto usStoreEASExit; } memcpy(pTarFea, pSrcFea, usNewSize); pTarFeal->cbList += usNewSize; if (f32Parms.fMessageActive & LOG_EAS) Message("Inserting EA '%s' (%u,%u)", pName, pSrcFea->cbName, pSrcFea->cbValue); } else { USHORT usOldSize = sizeof (FEA) + (USHORT)pTarFea->cbName + 1 + pTarFea->cbValue; USHORT usMoveSize = (USHORT)pTarFeal->cbList - ((PBYTE)pTarFea - (PBYTE)pTarFeal); usMoveSize -= usOldSize; if (usOldSize < usNewSize) { if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)(usNewSize - usOldSize)) { rc = ERROR_EAS_DIDNT_FIT; goto usStoreEASExit; } } memmove((PBYTE)pTarFea + usNewSize, (PBYTE)pTarFea + usOldSize, usMoveSize); memcpy(pTarFea, pSrcFea, usNewSize); pTarFeal->cbList -= usOldSize; pTarFeal->cbList += usNewSize; if (f32Parms.fMessageActive & LOG_EAS) Message("Updating EA '%s' (%u,%u)", pName, pSrcFea->cbName, pSrcFea->cbValue); } usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; pSrcFea = (PFEA)((PBYTE)pSrcFea + usNewSize); } if (f32Parms.fMessageActive & LOG_EAS) Message("cbList after = %lu", pTarFeal->cbList); if (pTarFeal->cbList > 4) rc = usWriteEAS(pVolInfo, ulDirCluster, pszFileName, pTarFeal); else rc = usDeleteEAS(pVolInfo, ulDirCluster, pszFileName); usStoreEASExit: freeseg(pTarFeal); if (f32Parms.fMessageActive & LOG_EAS) Message("usModifyEAS for %s returned %d", pszFileName, rc); return rc; }
USHORT usGetEAS(PVOLINFO pVolInfo, USHORT usLevel, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP) { USHORT rc; PFEALIST pTarFeal; PFEALIST pSrcFeal; PFEA pSrcFea; PFEA pTarFea; PGEALIST pGeaList; USHORT usMaxSize; if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS for %s Level %d", pszFileName, usLevel); /* Checking all the arguments */ rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP)); if (rc) { Message("Protection violation in usGetEAS (1) at %lX", pEAOP); return rc; } pTarFeal = pEAOP->fpFEAList; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pTarFeal, sizeof (ULONG)); if (rc) { Message("Protection violation in usGetEAS (2) at %lX", pTarFeal); return rc; } if (pTarFeal->cbList > MAX_EA_SIZE) usMaxSize = (USHORT)MAX_EA_SIZE; else usMaxSize = (USHORT)pTarFeal->cbList; if (usMaxSize < sizeof (ULONG)) return ERROR_BUFFER_OVERFLOW; rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pTarFeal, (USHORT)usMaxSize); if (rc) return rc; if (usLevel == FIL_QUERYEASFROMLIST) { pGeaList = pEAOP->fpGEAList; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, sizeof (ULONG)); if (rc) return rc; if (pGeaList->cbList > MAX_EA_SIZE) return ERROR_EA_LIST_TOO_LONG; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, (USHORT)pGeaList->cbList); if (rc) return rc; } else pGeaList = NULL; /* Initialize the FEALIST */ memset(pTarFeal, 0, usMaxSize); pTarFeal->cbList = sizeof (ULONG); usMaxSize -= sizeof (ULONG); pTarFea = pTarFeal->list; /* Does the EA Exist? */ rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pSrcFeal, FALSE); if (rc) goto usGetEASExit; /* If not, return */ if (usLevel == FIL_QUERYEASFROMLIST) { PBYTE pGeaMax; PGEA pGea; pGeaMax = (PBYTE)pGeaList + pGeaList->cbList; pGea = pGeaList->list; while ((PBYTE)pGea + sizeof (GEA) < pGeaMax) { USHORT usGeaSize = sizeof (GEA) + (USHORT)pGea->cbName; USHORT usFeaSize; if (pGea->szName + (USHORT)pGea->cbName > pGeaMax) { rc = ERROR_EA_LIST_INCONSISTENT; goto usGetEASExit; } pSrcFea = FindEA(pSrcFeal, pGea->szName, pGea->cbName); if (pSrcFea) { usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; pTarFeal->cbList = pSrcFeal->cbList; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("Found %s", pSrcFea + 1); memcpy(pTarFea, pSrcFea, usFeaSize); } else { usFeaSize = sizeof (FEA) + (USHORT)pGea->cbName + 1; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; if (pSrcFeal) pTarFeal->cbList = pSrcFeal->cbList; else pTarFeal->cbList = 4; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS: %s not found!", pGea->szName); pTarFea->fEA = 0x00; pTarFea->cbName = pGea->cbName; pTarFea->cbValue = 0; strcpy((PBYTE)(pTarFea + 1), pGea->szName); } pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize); pTarFeal->cbList += usFeaSize; usMaxSize -= usFeaSize; pGea = (PGEA)((PBYTE)pGea + usGeaSize); } } else if (pSrcFeal) { PBYTE pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList; pSrcFea = pSrcFeal->list; while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax) { USHORT usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; pTarFeal->cbList = pSrcFeal->cbList; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("Found %s (%u,%u)", pSrcFea + 1, (USHORT)pSrcFea->cbName, pSrcFea->cbValue); memcpy(pTarFea, pSrcFea, usFeaSize); pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize); pTarFeal->cbList += usFeaSize; pSrcFea = (PFEA)((PBYTE)pSrcFea + usFeaSize); usMaxSize -= usFeaSize; } } rc = 0; usGetEASExit: if (pSrcFeal) freeseg(pSrcFeal); if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS for %s returned %d (%lu bytes in EAS)", pszFileName, rc, pTarFeal->cbList); return rc; }