USHORT FillDirEntry(PVOLINFO pVolInfo, PBYTE * ppData, PUSHORT pcbData, PFINDINFO pFindInfo, USHORT usLevel) { BYTE szLongName[FAT32MAXPATHCOMP]; BYTE szUpperName[FAT32MAXPATHCOMP]; BYTE szShortName[14]; PBYTE pStart = *ppData; USHORT rc; DIRENTRY _huge * pDir; BYTE bCheck1; USHORT usClusterIndex; memset(szLongName, 0, sizeof szLongName); pDir = &pFindInfo->pInfo->pDirEntries[pFindInfo->ulCurEntry % pFindInfo->usEntriesPerCluster]; bCheck1 = 0; while (pFindInfo->ulCurEntry < pFindInfo->ulMaxEntry) { memset(szShortName, 0, sizeof(szShortName)); // vs usClusterIndex = (USHORT)(pFindInfo->ulCurEntry / pFindInfo->usEntriesPerCluster); if (usClusterIndex != pFindInfo->usClusterIndex) { if (!GetCluster(pVolInfo, pFindInfo, usClusterIndex)) return ERROR_SYS_INTERNAL; pDir = &pFindInfo->pInfo->pDirEntries[pFindInfo->ulCurEntry % pFindInfo->usEntriesPerCluster]; } if (pDir->bFileName[0] && pDir->bFileName[0] != DELETED_ENTRY) { if (pDir->bAttr == FILE_LONGNAME) { fGetLongName(pDir, szLongName, sizeof szLongName, &bCheck1); } else if ((pDir->bAttr & FILE_VOLID) != FILE_VOLID) { if (!(pDir->bAttr & pFindInfo->bAttr)) { BYTE bCheck2 = GetVFATCheckSum(pDir); MakeName(pDir, szShortName, sizeof szShortName); FSH_UPPERCASE(szShortName, sizeof szShortName, szShortName); rc = 0; if (f32Parms.fEAS && bCheck2 == bCheck1 && strlen(szLongName)) if (IsEASFile(szLongName)) rc = 1; if (f32Parms.fMessageActive & LOG_FIND) { if (bCheck2 != bCheck1 && strlen(szLongName)) Message("Invalid LFN entry found: %s", szLongName); } if (bCheck2 != bCheck1 || !strlen(szLongName)) { strcpy(szLongName, szShortName); /* support for the FAT32 variation of WinNT family */ if( HAS_WINNT_EXT( pDir->fEAS )) { PBYTE pDot = strchr( szLongName, '.' );; if( HAS_WINNT_EXT_NAME( pDir->fEAS )) /* name part is lower case */ { if( pDot ) *pDot = 0; strlwr( szLongName ); if( pDot ) *pDot = '.'; } if( pDot && HAS_WINNT_EXT_EXT( pDir->fEAS )) /* ext part is lower case */ strlwr( pDot + 1 ); } } if (f32Parms.fEAS && IsEASFile(szLongName)) rc = 1; strcpy(szUpperName, szLongName); FSH_UPPERCASE(szUpperName, sizeof szUpperName, szUpperName); if( !pFindInfo->fLongNames ) strcpy( szLongName, szShortName ); /* Check for MUST HAVE attributes */ if (!rc && pFindInfo->bMustAttr) { if ((pDir->bAttr & pFindInfo->bMustAttr) != pFindInfo->bMustAttr) rc = 1; } if (!rc && strlen(pFindInfo->pInfo->szSearch)) { rc = FSH_WILDMATCH(pFindInfo->pInfo->szSearch, szUpperName); if (rc && stricmp(szShortName, szUpperName)) rc = FSH_WILDMATCH(pFindInfo->pInfo->szSearch, szShortName); } if (!rc && f32Parms.fMessageActive & LOG_FIND) Message("%lu : %s, %s", pFindInfo->ulCurEntry, szLongName, szShortName ); if (!rc && usLevel == FIL_STANDARD) { PFILEFNDBUF pfFind = (PFILEFNDBUF)*ppData; if (*pcbData < sizeof (FILEFNDBUF) - CCHMAXPATHCOMP + strlen(szLongName) + 1) return ERROR_BUFFER_OVERFLOW; pfFind->fdateCreation = pDir->wCreateDate; pfFind->ftimeCreation = pDir->wCreateTime; pfFind->fdateLastAccess = pDir->wAccessDate; pfFind->fdateLastWrite = pDir->wLastWriteDate; pfFind->ftimeLastWrite = pDir->wLastWriteTime; pfFind->cbFile = pDir->ulFileSize; pfFind->cbFileAlloc = (pfFind->cbFile / pVolInfo->usClusterSize) * pVolInfo->usClusterSize + (pfFind->cbFile % pVolInfo->usClusterSize ? pVolInfo->usClusterSize : 0); pfFind->attrFile = (USHORT)pDir->bAttr; pfFind->cchName = (BYTE)strlen(szLongName); strcpy(pfFind->achName, szLongName); *ppData = pfFind->achName + pfFind->cchName + 1; (*pcbData) -= *ppData - pStart; pFindInfo->ulCurEntry++; return 0; } else if (!rc && usLevel == FIL_QUERYEASIZE) { PFILEFNDBUF2 pfFind = (PFILEFNDBUF2)*ppData; if (*pcbData < sizeof (FILEFNDBUF2) - CCHMAXPATHCOMP + strlen(szLongName) + 1) return ERROR_BUFFER_OVERFLOW; pfFind->fdateCreation = pDir->wCreateDate; pfFind->ftimeCreation = pDir->wCreateTime; pfFind->fdateLastAccess = pDir->wAccessDate; pfFind->fdateLastWrite = pDir->wLastWriteDate; pfFind->ftimeLastWrite = pDir->wLastWriteTime; pfFind->cbFile = pDir->ulFileSize; pfFind->cbFileAlloc = (pfFind->cbFile / pVolInfo->usClusterSize) + (pfFind->cbFile % pVolInfo->usClusterSize ? 1 : 0); if (!f32Parms.fEAS || !HAS_EAS( pDir->fEAS )) pfFind->cbList = sizeof pfFind->cbList; else { rc = usGetEASize(pVolInfo, pFindInfo->pInfo->rgClusters[0], szLongName, &pfFind->cbList); if (rc) pfFind->cbList = 4; rc = 0; } pfFind->attrFile = (USHORT)pDir->bAttr; pfFind->cchName = (BYTE)strlen(szLongName); strcpy(pfFind->achName, szLongName); *ppData = pfFind->achName + pfFind->cchName + 1; (*pcbData) -= *ppData - pStart; pFindInfo->ulCurEntry++; return 0; } else if (!rc && usLevel == FIL_QUERYEASFROMLIST) { PFILEFNDBUF3 pfFind = (PFILEFNDBUF3)*ppData; ULONG ulFeaSize; if (*pcbData < sizeof (FILEFNDBUF3) + sizeof (ULONG) + strlen(szLongName) + 2) return ERROR_BUFFER_OVERFLOW; pfFind->fdateCreation = pDir->wCreateDate; pfFind->ftimeCreation = pDir->wCreateTime; pfFind->fdateLastAccess = pDir->wAccessDate; pfFind->fdateLastWrite = pDir->wLastWriteDate; pfFind->ftimeLastWrite = pDir->wLastWriteTime; pfFind->cbFile = pDir->ulFileSize; pfFind->cbFileAlloc = (pfFind->cbFile / pVolInfo->usClusterSize) * pVolInfo->usClusterSize + (pfFind->cbFile % pVolInfo->usClusterSize ? pVolInfo->usClusterSize : 0); pfFind->attrFile = (USHORT)pDir->bAttr; *ppData = (PBYTE)(pfFind + 1); (*pcbData) -= *ppData - pStart; if (f32Parms.fEAS && HAS_EAS( pDir->fEAS )) { pFindInfo->pInfo->EAOP.fpFEAList = (PFEALIST)*ppData; pFindInfo->pInfo->EAOP.fpFEAList->cbList = *pcbData - (strlen(szLongName) + 2); rc = usGetEAS(pVolInfo, FIL_QUERYEASFROMLIST, pFindInfo->pInfo->rgClusters[0], szLongName, &pFindInfo->pInfo->EAOP); if (rc && rc != ERROR_BUFFER_OVERFLOW) return rc; if (rc) { rc = ERROR_EAS_DIDNT_FIT; ulFeaSize = sizeof (ULONG); } else ulFeaSize = pFindInfo->pInfo->EAOP.fpFEAList->cbList; } else { pFindInfo->pInfo->EAOP.fpFEAList = (PFEALIST)*ppData; pFindInfo->pInfo->EAOP.fpFEAList->cbList = *pcbData - (strlen(szLongName) + 2); rc = usGetEmptyEAS(szLongName,&pFindInfo->pInfo->EAOP); if (rc && (rc != ERROR_EAS_DIDNT_FIT)) return rc; else if (rc == ERROR_EAS_DIDNT_FIT) ulFeaSize = sizeof(pFindInfo->pInfo->EAOP.fpFEAList->cbList); else ulFeaSize = pFindInfo->pInfo->EAOP.fpFEAList->cbList; } (*ppData) += ulFeaSize; (*pcbData) -= ulFeaSize; /* Length and longname */ *(*ppData)++ = (BYTE)strlen(szLongName); (*pcbData)--; strcpy(*ppData, szLongName); (*ppData) += strlen(szLongName) + 1; (*pcbData) -= (strlen(szLongName) + 1); pFindInfo->ulCurEntry++; return rc; } } memset(szLongName, 0, sizeof szLongName); } } pFindInfo->ulCurEntry++; pDir++; } return ERROR_NO_MORE_FILES; }
BOOL DumpDirectory(PDRIVEINFO pDrive, ULONG ulDirCluster, PSZ pszPath) { static BYTE szLongName[512]; int iIndex; PDIRENTRY pDir; PBYTE pbCluster; PBYTE pbPath; USHORT usClusters; ULONG ulCluster; ULONG ulBytesNeeded; BYTE _huge * p; PDIRENTRY pEnd; BYTE bCheckSum, bCheck; ULONG ulClustersNeeded; ULONG ulClustersUsed; ULONG ulEntries; static BYTE szShortName[13]; if (!ulDirCluster) { printf("ERROR: Cluster for %s is 0!\n", pszPath); return TRUE; } if (ulDirCluster == pDrive->bpb.RootDirStrtClus) { PULONG pulCluster; ReadFATSector(pDrive, 0); pulCluster = (PULONG)pDrive->pbFATSector; printf("MEDIA BYTES in FAT: %8.8lX\n", *pulCluster); pulCluster = (PULONG)pDrive->pbFATSector + 1; printf("DiskStatus: %8.8lX\n", *pulCluster); // vDumpSector(pDrive->pbFATSector); } //pDrive->ulTotalDirs++; pbPath = malloc(512); usClusters = GetClusterCount(pDrive, ulDirCluster); ulTotalClusters += usClusters; if (fDetailed > 2) printf("\n\nDirectory of %s (%u clusters)\n\n", pszPath, usClusters); ulBytesNeeded = (ULONG)pDrive->bpb.SectorsPerCluster * (ULONG)pDrive->bpb.BytesPerSector * usClusters; pbCluster = calloc(usClusters, pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector); if (!pbCluster) { printf("ERROR:Not enough memory!\n"); return FALSE; } ulCluster = ulDirCluster; p = pbCluster; while (ulCluster != FAT_EOF) { ReadCluster(pDrive, ulCluster); memcpy(p, pDrive->pbCluster, pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector); ulCluster = GetNextCluster(pDrive, ulCluster); p += pDrive->bpb.SectorsPerCluster * pDrive->bpb.BytesPerSector; } memset(szLongName, 0, sizeof szLongName); pDir = (PDIRENTRY)pbCluster; pEnd = (PDIRENTRY)(pbCluster + ulBytesNeeded - sizeof (DIRENTRY)); ulEntries = 0; bCheck = 0; while (pDir <= pEnd) { if (fDetailed > 3) { ULONG ulOffset = (PBYTE)pDir - pbCluster; if (ulOffset && !(ulOffset % 4096)) printf("-------- NEXT CLUSTER ----------\n"); } if (pDir->bFileName[0] && pDir->bFileName[0] != 0xE5) { if (pDir->bAttr == FILE_LONGNAME) { if (fDetailed > 3) { printf("(longname)\n"); vDumpDirEntry(pDir); } if (strlen(szLongName) && bCheck != pDir->bReserved) { printf("A lost long filename was found: %s\n", szLongName); memset(szLongName, 0, sizeof szLongName); } bCheck = pDir->bReserved; fGetLongName(pDir, szLongName, sizeof szLongName); } else { bCheckSum = 0; for (iIndex = 0; iIndex < 11; iIndex++) { if (bCheckSum & 0x01) { bCheckSum >>=1; bCheckSum |= 0x80; } else bCheckSum >>=1; bCheckSum += pDir->bFileName[iIndex]; } if (strlen(szLongName) && bCheck != bCheckSum) { printf("The longname %s does not belong to %s\\%s\n", szLongName, pszPath, MakeName(pDir, szShortName, sizeof szShortName)); memset(szLongName, 0, sizeof szLongName); } if (fDetailed > 2) { printf("%-8.8s.%-3.3s %2.2X ", pDir->bFileName, pDir->bExtention, pDir->bAttr); if (pDir->bAttr & FILE_DIRECTORY) printf("<DIR> "); else printf("%10lu ", pDir->ulFileSize); printf("%8.8lX ", MAKEP(pDir->wClusterHigh, pDir->wCluster)); if (pDir->fEAS) printf("%2.2X ", pDir->fEAS); else printf(" "); printf("%s\n", szLongName); } if (!(pDir->bAttr & FILE_DIRECTORY)) { ulClustersNeeded = pDir->ulFileSize / pDrive->usClusterSize + (pDir->ulFileSize % pDrive->usClusterSize ? 1:0); ulClustersUsed = GetClusterCount(pDrive,(ULONG)pDir->wClusterHigh * 0x10000 + pDir->wCluster); ulTotalClusters += ulClustersUsed; if (ulClustersNeeded != ulClustersUsed) { printf("File allocation error detected for %s\\%s\n", pszPath, MakeName(pDir, szShortName, sizeof szShortName)); printf("%lu clusters needed, %lu clusters allocated\n", ulClustersNeeded, ulClustersUsed); } } memset(szLongName, 0, sizeof szLongName); } ulEntries++; }