void SwapBitfieldBits(char* bitfield, unsigned long bitpos1, unsigned long bitpos2) { int bit1, bit2; assert(bitfield); bit1 = GetBitfieldBit(bitfield, bitpos1); bit2 = GetBitfieldBit(bitfield, bitpos2); if (bit1) SetBitfieldBit(bitfield, bitpos2); else ClearBitfieldBit(bitfield, bitpos2); if (bit2) SetBitfieldBit(bitfield, bitpos1); else ClearBitfieldBit(bitfield, bitpos1); }
static BOOL HasSectorChanged(RDWRHandle handle, SECTOR sector, unsigned long sectorsperfat) { /* Notice that we have already checked wether there were any changes and that this function is only called if not the entire FAT needs to be copied. */ unsigned long sectorsperbit; unsigned long bit; if (handle->FatChangeField) { sectorsperbit = (sectorsperfat >> 16) + 1; bit = sector / sectorsperbit; return GetBitfieldBit(handle->FatChangeField, bit); }
static BOOL DirSizeGetter(RDWRHandle handle, struct DirectoryPosition* pos, void** structure) { BOOL InRoot; unsigned long **dirsize = (unsigned long**) structure; unsigned char sectorspercluster; CLUSTER label; pos = pos, handle = handle; /* Check for loops in the directory structure */ InRoot = IsRootDirPosition(handle, pos); if (InRoot == -1) return FAIL; if (!InRoot && (pos->offset == 0)) { sectorspercluster = GetSectorsPerCluster(handle); if (!sectorspercluster) return FAIL; if ((pos->sector % sectorspercluster) == 0) { label = DataSectorToCluster(handle, pos->sector); if (!label) return FAIL; if (GetBitfieldBit(fatmap, label)) { return FALSE; } SetBitfieldBit(fatmap, label); } } **dirsize += sizeof(struct DirectoryEntry); return TRUE; }
BOOL ScanFileChain(RDWRHandle handle, CLUSTER firstcluster, struct DirectoryPosition* pos, struct DirectoryEntry* entry, char* filename, BOOL fixit) { char* bitfield; unsigned long labelsinfat; BOOL breakoff = FALSE; CLUSTER current = firstcluster, label, breakingcluster, lengthBreakingCluster=0; unsigned long length = 0, calculatedsize, bytespercluster; static char tempbuf[255]; BOOL retVal = TRUE; /* If it is a root directory that we have to scan see wether it is a FAT32 volume and if it is get the root cluster */ if (!firstcluster) { switch (GetFatLabelSize(handle)) { case FAT12: case FAT16: return TRUE; case FAT32: current = GetFAT32RootCluster(handle); break; default: return FAIL; } } else { bytespercluster = GetSectorsPerCluster(handle) * BYTESPERSECTOR; if (!bytespercluster) return FAIL; calculatedsize = (entry->filesize / bytespercluster) + ((entry->filesize % bytespercluster) > 0); } labelsinfat = GetLabelsInFat(handle); if (!labelsinfat) return FAIL; bitfield = CreateBitField(labelsinfat); if (!bitfield) { DestroyBitfield(bitfield); return FAIL; } SetBitfieldBit(bitfield, current); /* Initialise the checks on the directory entries */ if (entry->attribute & FA_DIREC) { InitClusterEntryChecking(handle, current, filename); switch (PreProcessClusterEntryChecking(handle, current, filename, fixit)) { case FALSE: retVal = FALSE; break; case FAIL: DestroyBitfield(bitfield); DestroyClusterEntryChecking(handle, current, filename); return FAIL; } } while (TRUE) { length++; if (!GetNthCluster(handle, current, &label)) { DestroyBitfield(bitfield); if (entry->attribute & FA_DIREC) DestroyClusterEntryChecking(handle, current, filename); return FAIL; } /* Check the read cluster: */ /* the last cluster */ if (FAT_LAST(label)) { if (entry->attribute & FA_DIREC) /* Here the current cluster is valid */ { switch (CheckEntriesInCluster(handle, current, filename, fixit)) { case FALSE: retVal = FALSE; break; case FAIL: DestroyBitfield(bitfield); if (entry->attribute & FA_DIREC) DestroyClusterEntryChecking(handle, current, filename); return FAIL; } } break; } /* Check wether it is in range */ if (FAT_NORMAL(label) && !IsLabelValid(handle, label)) { if (firstcluster) { ShowFileNameViolation(handle, filename, "%s contains an invalid cluster"); } else { ShowFileNameViolation(handle, filename, "The root directory contains an invalid cluster"); } breakoff = TRUE; breakingcluster = current; retVal = FALSE; } /* bad cluster */ if (FAT_BAD(label)) { if (firstcluster) { ShowFileNameViolation(handle, filename, "%s contains a bad cluster"); } else { ShowFileNameViolation(handle, filename, "The root directory contains a bad cluster"); } breakingcluster = current; breakoff = TRUE; retVal = FALSE; } if (FAT_FREE(label)) { if (firstcluster) { ShowFileNameViolation(handle, filename, "%s contains a free cluster"); } else { ShowFileNameViolation(handle, filename, "The root directory contains a free cluster"); } breakoff = TRUE; breakingcluster = current; retVal = FALSE; } /* Check wether there is a loop */ if (!breakoff && GetBitfieldBit(bitfield, label)) { if (firstcluster) { ShowFileNameViolation(handle, filename, "%s contains a loop"); } else { ShowFileNameViolation(handle, filename, "The root directory contains a loop"); } breakoff = TRUE; breakingcluster = current; retVal = FALSE; } /* if ((firstcluster && ((entry->attribute & FA_DIREC) == 0)) && (length > calculatedsize) && (lengthBreakingCluster == 0)) { lengthBreakingCluster = current; } */ if (breakoff) { if (fixit) { if (!WriteFatLabel(handle, breakingcluster, FAT_LAST_LABEL)) { DestroyBitfield(bitfield); if (entry->attribute & FA_DIREC) DestroyClusterEntryChecking(handle, current, filename); return FAIL; } } break; } SetBitfieldBit(bitfield, label); if (entry->attribute & FA_DIREC) /* Here the current cluster is valid */ { switch (CheckEntriesInCluster(handle, current, filename, fixit)) { case FALSE: retVal = FALSE; break; case FAIL: DestroyBitfield(bitfield); if (entry->attribute & FA_DIREC) DestroyClusterEntryChecking(handle, current, filename); return FAIL; } } current = label; } /* Check the length of the file */ if (firstcluster) { /* if (((entry->attribute & FA_DIREC) == 0) && (length > calculatedsize)) { sprintf(tempbuf, "%%s has an invalid size, the size should be about %lu, but the entry says it's %lu", length * bytespercluster, entry->filesize); ShowFileNameViolation(handle, filename, tempbuf); if (fixit && !WriteFatLabel(handle, lengthBreakingCluster, FAT_LAST_LABEL)) { DestroyBitfield(bitfield); if (entry->attribute & FA_DIREC) DestroyClusterEntryChecking(handle, current, filename); return FAIL; } retVal = FALSE; } */ if (((entry->attribute & FA_DIREC) == 0) && (length != calculatedsize)) { sprintf(tempbuf, "%%s has an invalid size, the size should be about %lu, but the entry says it's %lu", length * bytespercluster, entry->filesize); ShowFileNameViolation(handle, filename, tempbuf); if (fixit) { /* Notice that we are modifying the filesize of the same entry in chkentrs.c, the entry shall be written to disk there. */ entry->filesize = length * bytespercluster; } retVal = FALSE; } } /* Destroy the checks on the directory entries */ if (entry->attribute & FA_DIREC) { switch (PostProcessClusterEntryChecking(handle, current, filename, fixit)) { case FALSE: retVal = FALSE; break; case FAIL: retVal = FAIL; } DestroyClusterEntryChecking(handle, current, filename); } DestroyBitfield(bitfield); return retVal; }
int main(int argc, char** argv) { unsigned long bit, i; char* bitfield = CreateBitField(100); randomize(); for (i=0; i<20; i++) { do { bit = random(100); } while (GetBitfieldBit(bitfield, bit)); SetBitfieldBit(bitfield, bit); printf("%d\n", bit); } printf("De getallen gesorteerd:\n"); for (i=0; i<100; i++) { if (GetBitfieldBit(bitfield, i)) printf("%d\n", i); } DestroyBitfield(bitfield); printf("---------------------------------\n"); bitfield = CreateBitField(100); for (i=0; i<20; i++) { do { bit = random(50); } while (GetBitfieldBit(bitfield, bit)); SetBitfieldBit(bitfield, bit); printf("%d\n", bit+50); } //printf("/////////////////////////////////\n"); for (i=0; i<50; i++) { if (GetBitfieldBit(bitfield, i)) { // printf("%lu::%lu\n", i, (i+50)); SwapBitfieldBits(bitfield, i, (i+50)); } } //printf("/////////////////////////////////\n"); printf("De getallen gesorteerd:\n"); for (i=0; i<100; i++) { if (GetBitfieldBit(bitfield, i)) printf("%d\n", i); } DestroyBitfield(bitfield); }