static Errcode read_strip_offsets(Tiff_file *tf, long offset, int type, int strip_count) /***************************************************************************** * allocate the strip_data array and load strip offsets into it. * note that we allocate one extra Strip_data slot in the array, in case we * have to calculate strip bytecounts from the offsets later. ****************************************************************************/ { int counter; Strip_data *curstrip; Onum readbuf; tf->strips_per_image = strip_count; if (NULL != tf->strip_data) /* somehow got strip offset data twice */ return Err_format; if (NULL == (tf->strip_data = malloc((strip_count+1) * sizeof(Strip_data)))) return Err_no_memory; curstrip = tf->strip_data; if (strip_count == 1 && type == TYPE_LONG) /* 1 longword is easy */ { curstrip->offset = offset; } else if (strip_count == 2 && type == TYPE_SHORT)/* 2 shorts is tricky */ { convert.dword = offset; curstrip->offset = convert.words.word1; ++curstrip; curstrip->offset = convert.words.word2; } else /* else we have to read */ { if (Success != fseek(tf->file, offset, SEEK_SET)) return pj_errno_errcode(); counter = strip_count; while (counter--) { if (type == TYPE_SHORT) { if (1 != fread(&readbuf, sizeof(short), 1, tf->file)) return Err_truncated; SWAPW(&readbuf.word); curstrip->offset = readbuf.uword; } else { if (1 != fread(&curstrip->offset, sizeof(long), 1, tf->file)) return Err_truncated; SWAPD(&curstrip->offset); } ++curstrip; } } return Success; }
Errcode read_filehdr(Tiff_file *tf) /***************************************************************************** * read tiff file header, validate magic numbers. ****************************************************************************/ { Tifhdr tifhdr; if (Success != fseek(tf->file, 0, SEEK_SET)) return pj_errno_errcode(); if (1 != fread(&tifhdr, sizeof(tifhdr), 1, tf->file)) return Err_truncated; if (tifhdr.machine == MOTOROLA) tf->swap_bytes = TRUE; else if (tifhdr.machine == INTEL) tf->swap_bytes = FALSE; else return Err_bad_magic; SWAPW(&tifhdr.version); SWAPD(&tifhdr.firstifd); if (tifhdr.version < 42 || tifhdr.version > 59) /* we do tiff versions */ return Err_bad_magic; /* 4.x and 5.x only. */ if (tifhdr.firstifd < 8) return Err_bad_magic; tf->off_ifd_next = tifhdr.firstifd; return Success; }
static Errcode read_strip_bytecounts(Tiff_file *tf, long offset, int type, int strip_count) /***************************************************************************** * load strip bytecounts into strip_data array, also remember biggest value. ****************************************************************************/ { int counter; long highcount = 0; Onum readbuf; Strip_data *curstrip = tf->strip_data; if (NULL == curstrip) /* we need to have offset data already or we die */ return Err_format; if (strip_count != tf->strips_per_image) /* must have same # of byte */ return Err_format; /* counts as we had offsets */ if (strip_count == 1 && type == TYPE_LONG) /* 1 long is easy */ { curstrip->size = highcount = offset; } else if (strip_count == 2 && type == TYPE_SHORT) /* 2 shorts is tricky */ { convert.dword = offset; curstrip->offset = convert.words.word1; ++curstrip; curstrip->offset = convert.words.word2; } else { if (Success != fseek(tf->file, offset, SEEK_SET)) return pj_errno_errcode(); counter = strip_count; while (counter--) { if (type == TYPE_SHORT) { if (1 != fread(&readbuf, sizeof(short), 1, tf->file)) return Err_truncated; SWAPW(&readbuf); curstrip->size = readbuf.uword; } else { if (1 != fread(&curstrip->size, sizeof(long), 1, tf->file)) return Err_truncated; SWAPD(&curstrip->size); } if (curstrip->size > highcount) highcount = curstrip->size; ++curstrip; } } tf->longest_strip = highcount; return Success; }
int LUfactor(Matrix A, int *indexarray) { int dim = A->dim, i, j, k, i_max, k_max; Vector scale; double mx, tmp; scale = new_vector(dim); for (i = 0; i < dim; i++) indexarray[i] = i; for (i = 0; i < dim; i++) { mx = 0.; for (j = 0; j < dim; j++) { tmp = fabs(M_VAL(A, i, j)); if (mx < tmp) mx = tmp; } scale->ve[i] = mx; } k_max = dim - 1; for (k = 0; k < k_max; k++) { mx = 0.; i_max = -1; for (i = k; i < dim; i++) { if (fabs(scale->ve[i]) >= Tiny * fabs(M_VAL(A, i, k))) { tmp = fabs(M_VAL(A, i, k)) / scale->ve[i]; if (mx < tmp) { mx = tmp; i_max = i; } } } if (i_max == -1) { M_VAL(A, k, k) = 0.; continue; } if (i_max != k) { SWAPI(indexarray[i_max], indexarray[k]); for (j = 0; j < dim; j++) SWAPD(M_VAL(A, i_max, j), M_VAL(A, k, j)); } for (i = k + 1; i < dim; i++) { tmp = M_VAL(A, i, k) = M_VAL(A, i, k) / M_VAL(A, k, k); for (j = k + 1; j < dim; j++) M_VAL(A, i, j) -= tmp * M_VAL(A, k, j); } } return 0; }
Errcode read_tiftags(Tiff_file *tf) /***************************************************************************** * load all the tags in an ifd, save the data we care about along the way. * after reading everything in the ifd, this routine attempts to fudge in * any data that was missing (eg, strip offsets, strip bytecounts). it also * verifies that the required fields were present (our idea of required * fields, not tiff's idea. we require image width and height; we can fake * just about anything else.) ****************************************************************************/ { Errcode err; short entry_count; Dirent entry; int bps_count; /* * plug in default values for things we care about... */ tf->width = 0; tf->height = 0; tf->longest_strip = 0; tf->strips_per_image = 0; tf->planar_configuration = 1; tf->rows_per_strip = 0x7fffffff; tf->samples_per_pixel = 1; tf->bits_per_sample[0] = 1; tf->bits_per_sample[1] = 0; tf->bits_per_sample[2] = 0; tf->compression = CMPRS_NONE; tf->photometric = PHMET_GREY_0ISBLACK; tf->min_sample_value = 0; tf->max_sample_value = 0; /* default will be calc'd later if needed */ /* * the saved offset of the next ifd becomes the offset to the current * ifd. we seek to that location (just in case), and load the count * of entries in the ifd, which will be used as a loop counter. */ tf->off_ifd_start = tf->off_ifd_cur = tf->off_ifd_next; if (Success != fseek(tf->file, tf->off_ifd_cur, SEEK_SET)) return pj_errno_errcode(); if (1 != fread(&entry_count, sizeof(entry_count), 1, tf->file)) return pj_errno_errcode(); SWAPW(&entry_count); tf->off_ifd_cur += sizeof(entry_count); /* * loop through all the entries (tags) in the ifd, storing off the data * we care about into our own structure as we go. */ while (entry_count--) { if (Success != (err = read_next_dirent(tf, &entry))) return err; switch (entry.tag) { case TAG_IMAGE_WIDTH: tf->width = entry.value.word; break; case TAG_IMAGE_LENGTH: tf->height = entry.value.word; break; case TAG_BITS_PER_SAMPLE: bps_count = entry.count; switch (entry.count) { case 1: tf->bits_per_sample[0] = entry.value.word; if (tf->bits_per_sample[0] > 8) return Err_wrong_type; break; case 3: if (Success != fseek(tf->file, entry.value.offset, SEEK_SET)) return pj_errno_errcode(); if (3 != fread(tf->bits_per_sample, sizeof(short), 3, tf->file)) return Err_truncated; if (tf->swap_bytes) { swapw(&tf->bits_per_sample[0]); swapw(&tf->bits_per_sample[1]); swapw(&tf->bits_per_sample[2]); } if (tf->bits_per_sample[0] != 8 || tf->bits_per_sample[1] != 8 || tf->bits_per_sample[2] != 8 ) return Err_wrong_type; break; default: return Err_wrong_type; } break; case TAG_COMPRESSION: tf->compression = entry.value.uword; break; case TAG_PHOTOMETRIC_INTERP: tf->photometric = entry.value.word; break; case TAG_STRIP_OFFSETS: case TAG_SHORT_STRIP_OFFSETS: /* Aldus private tag 32768 */ if (Success != (err = read_strip_offsets(tf, entry.value.offset, entry.type, entry.count))) return err; break; case TAG_SAMPLES_PER_PIXEL: tf->samples_per_pixel = entry.value.word; switch (tf->samples_per_pixel) { case 1: if (tf->photometric == PHMET_RGB) return Err_format; break; case 3: tf->photometric = PHMET_RGB; /* force RGB interp */ break; default: return Err_wrong_type; } break; case TAG_ROWS_PER_STRIP: tf->rows_per_strip = (entry.type == TYPE_SHORT) ? entry.value.word : entry.value.dword; break; case TAG_STRIP_BYTE_COUNTS: if (Success != (err = read_strip_bytecounts(tf, entry.value.offset, entry.type, entry.count))) return err; break; case TAG_MIN_SAMPLE_VALUE: case TAG_MAX_SAMPLE_VALUE: /* we ignore these fields and calc values below. * we use the min/max values to calculate greyscale * pallete entries, but on the advice of of the TIFF 5.0 * doc ('these values should not affect the visual display * of the data, they are for statistical purposes only'), * we use 2**bits_per_sample instead of max_sample_value. */ break; case TAG_PLANAR_CONFIG: tf->planar_configuration = entry.value.word; break; case TAG_COLORMAP: if (Success != (err = read_color_map(tf, entry.value.offset, entry.count))) return err; break; default: break; } tf->off_ifd_cur += sizeof(entry); } /* * read the offset to the next ifd; we may need it for multi-image file */ if (Success != fseek(tf->file, tf->off_ifd_cur, SEEK_SET)) return pj_errno_errcode(); if (1 != fread(&tf->off_ifd_next, sizeof(tf->off_ifd_next), 1, tf->file)) return Err_truncated; SWAPD(&tf->off_ifd_next); /* * if we have RGB data but we only got one bits_per_sample value, * propogate it to the other two entries in the array. * calculate the total pixel depth. */ if (tf->photometric == PHMET_RGB && bps_count != 3) { tf->bits_per_sample[1] = tf->bits_per_sample[0]; tf->bits_per_sample[2] = tf->bits_per_sample[0]; } tf->pixel_depth = tf->bits_per_sample[0] + tf->bits_per_sample[1] + tf->bits_per_sample[2]; /* * calculate max_sample_value as (2**bits_per_sample)-1... */ if (tf->max_sample_value == 0) tf->max_sample_value = (0x01 << tf->bits_per_sample[0]) - 1; /* * hmmm. it seems some tif files don't have strip bytecount entries. * we'll see symptoms of that here if the longest strip size is zero * after reading all the tags. when this occurs, we call a routine * to calculate the byte counts. the routine does some sanity checking * and will return an error if the counts look totally unreasonable. */ if (tf->longest_strip == 0) if (Success != (err = calc_strip_bytecounts(tf))) return err; /* * all entries in this ifd have been dealt with, make sure we have * the minimum required data to run the rest of the program... * checking strips_per_image ensures that we got strip offsets. * checking longest_strip ensures we got (or calc'd) strip bytecounts. */ if (tf->width == 0 || tf->height == 0 || tf->strips_per_image == 0 || tf->longest_strip == 0) return Err_format; return Success; }
void VariationalBayes::optimize(bool verbose,OPT_TYPE method,long maxIter,double ftol, double gtol){//{{{ bool usedSteepest; long iteration=0,i,r; double boundOld,bound,squareNorm,squareNormOld=1,valBeta=0,valBetaDiv,natGrad_i,gradGamma_i,phiGradPhiSum_r; double *gradPhi,*natGrad,*gradGamma,*searchDir,*tmpD,*phiOld; gradPhi=natGrad=gradGamma=searchDir=tmpD=phiOld=NULL; MyTimer timer; // allocate stuff {{{ //SimpleSparse *phiGradPhi=new SimpleSparse(beta); gradPhi = new double[T]; // phiOld = new double[T]; will use gradPhi memory for this phiOld = NULL; natGrad = new double[T]; if(method == OPTT_HS) gradGamma = new double[T]; searchDir = new double[T]; //searchDirOld = new double[T]; //phiGradPhi_sum = new double[N]; // }}} #ifdef LOG_CONV ofstream logF(logFileName.c_str()); logF.precision(15); logF<<"# iter bound squareNorm time(m) [M*means M*vars]"<<endl; if(logTimer)logTimer->setQuiet(); #ifdef LONG_LOG vector<double> dirAlpha(M); #endif #endif boundOld=getBound(); timer.start(); while(true){ negGradient(gradPhi); // "yuck" //setVal(phiGradPhi,i,phi->val[i]*gradPhi[i]); //phiGradPhi->sumRows(phiGradPhi_sum); // removed need for phiGradPhi matrix: // removed need for phiGradPhi_sum /*for(r=0;r<N;r++){ phiGradPhi_sum[r] = 0; for(i=phi->rowStart[r];i<phi->rowStart[r+1];i++) phiGradPhi_sum[r] += phi->val[i] * gradPhi[i]; }*/ // set natGrad & gradGamma squareNorm=0; valBeta = 0; valBetaDiv = 0; #pragma omp parallel for private(i,phiGradPhiSum_r,natGrad_i,gradGamma_i) reduction(+:squareNorm,valBeta,valBetaDiv) for(r=0;r<N;r++){ phiGradPhiSum_r = 0; for(i = phi->rowStart[r]; i < phi->rowStart[r+1]; i++) phiGradPhiSum_r += phi->val[i] * gradPhi[i]; for(i = phi->rowStart[r]; i < phi->rowStart[r+1]; i++){ natGrad_i = gradPhi[i] - phiGradPhiSum_r; gradGamma_i = natGrad_i * phi->val[i]; squareNorm += natGrad_i * gradGamma_i; if(method==OPTT_PR){ valBeta += (natGrad_i - natGrad[i])*gradGamma_i; } if(method==OPTT_HS){ valBeta += (natGrad_i-natGrad[i])*gradGamma_i; valBetaDiv += (natGrad_i-natGrad[i])*gradGamma[i]; gradGamma[i] = gradGamma_i; } natGrad[i] = natGrad_i; } } if((method==OPTT_STEEPEST) || (iteration % (N*M)==0)){ valBeta=0; }else if(method==OPTT_PR ){ // already computed: // valBeta=0; // for(i=0;i<T;i++)valBeta+= (natGrad[i]-natGradOld[i])*gradGamma[i]; valBeta /= squareNormOld; }else if(method==OPTT_FR ){ valBeta = squareNorm / squareNormOld; }else if(method==OPTT_HS ){ // already computed: //valBeta=div=0; //for(i=0;i<T;i++){ // valBeta += (natGrad[i]-natGradOld[i])*gradGamma[i]; // div += (natGrad[i]-natGradOld[i])*gradGammaOld[i]; //} if(valBetaDiv!=0)valBeta /= valBetaDiv; else valBeta = 0; } if(valBeta>0){ usedSteepest = false; //for(i=0;i<T;i++)searchDir[i]= -natGrad[i] + valBeta*searchDirOld[i]; // removed need for searchDirOld: #pragma omp parallel for for(i=0;i<T;i++) searchDir[i]= -natGrad[i] + valBeta*searchDir[i]; }else{ usedSteepest = true; #pragma omp parallel for for(i=0;i<T;i++) searchDir[i]= -natGrad[i]; } //try conjugate step SWAPD(gradPhi,phiOld); memcpy(phiOld,phi_sm->val,T*sizeof(double)); // memcpy(phiOld,pack(),T*sizeof(double)); unpack(phiOld,searchDir); bound = getBound(); iteration++; // make sure there is an increase in L, else revert to steepest if((bound<boundOld) && (valBeta>0)){ usedSteepest = true; #pragma omp parallel for for(i=0;i<T;i++) searchDir[i]= -natGrad[i]; unpack(phiOld,searchDir); bound = getBound(); // this should not be increased: iteration++; } if(bound<boundOld) { // If bound decreased even after using steepest, step back and quit. unpack(phiOld); } SWAPD(gradPhi,phiOld); if(verbose){ #ifdef SHOW_FIXED messageF("iter(%c): %5.ld bound: %.3lf grad: %.7lf beta: %.7lf fixed: %ld\n",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta,phi->countAboveDelta(0.999)); #else messageF("iter(%c)[%5.lds]: %5.ld bound: %.3lf grad: %.7lf beta: %.7lf\n",(usedSteepest?'s':'o'),(long)timer.getTime(),iteration,bound,squareNorm,valBeta); #endif }else if(!quiet){ messageF("\riter(%c): %5.ld bound: %.3lf grad: %.7lf beta: %.7lf ",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta); } #ifdef LOG_CONV if((iteration%100==0) || ((iteration<500) && (iteration%50==0)) || ((iteration<150) && (iteration%10==0)) || ((iteration<50) && (iteration%5==0))){ logF<<iteration<<" "<<bound<<" "<<squareNorm; if(logTimer)logF<<" "<<logTimer->current(0,'m'); #ifdef LONG_LOG double alphaSum = 0, alphaVarNorm; // True 'alpha' - Dirichlet parameter is alpha+phiHat. for(i=1;i<M;i++){ dirAlpha[i] = alpha[i] + phiHat[i]; alphaSum += dirAlpha[i]; } for(i=1;i<M;i++)logF<< " " << dirAlpha[i] / alphaSum; alphaVarNorm = alphaSum*alphaSum*(alphaSum+1); for(i=1;i<M;i++)logF<<" "<<dirAlpha[i]*(alphaSum-dirAlpha[i])/alphaVarNorm; #endif logF<<endl; } #endif // convergence check {{{ if(bound<boundOld){ message("\nEnd: bound decrease\n"); break; } if(abs(bound-boundOld)<=ftol){ message("\nEnd: converged (ftol)\n"); break; } if(squareNorm<=gtol){ message("\nEnd: converged (gtol)\n"); break; } if(iteration>=maxIter){ message("\nEnd: maxIter exceeded\n"); break; } // }}} // store essentials {{{ squareNormOld=squareNorm; boundOld=bound; // }}} R_INTERUPT; } if(quiet){ messageF("iter(%c): %5.ld bound: %.3lf grad: %.7lf beta: %.7lf\n",(usedSteepest?'s':'o'),iteration,bound,squareNorm,valBeta); } #ifdef LOG_CONV logF<<iteration<<" "<<bound<<" "<<squareNorm; if(logTimer)logF<<" "<<logTimer->current(0,'m'); #ifdef LONG_LOG double alphaSum = 0, alphaVarNorm; // True 'alpha' - Dirichlet parameter is alpha+phiHat. for(i=1;i<M;i++){ dirAlpha[i] = alpha[i] + phiHat[i]; alphaSum += dirAlpha[i]; } for(i=1;i<M;i++)logF<< " " << dirAlpha[i] / alphaSum; alphaVarNorm = alphaSum*alphaSum*(alphaSum+1); for(i=1;i<M;i++)logF<<" "<<dirAlpha[i]*(alphaSum-dirAlpha[i])/alphaVarNorm; #endif logF<<endl; if(logTimer)logTimer->setVerbose(); logF.close(); #endif // free memory {{{ //delete phiGradPhi; delete[] gradPhi; delete[] natGrad; if(method == OPTT_HS) delete[] gradGamma; delete[] searchDir; //delete[] searchDirOld; //delete[] phiGradPhi_sum; // }}} }//}}}
/* * FatGetFatEntry() * returns the Fat entry for a given cluster number */ BOOLEAN FatGetFatEntry(PFAT_VOLUME_INFO Volume, ULONG Cluster, ULONG* ClusterPointer) { ULONG fat = 0; UINT32 FatOffset; UINT32 ThisFatSecNum; UINT32 ThisFatEntOffset; //TRACE("FatGetFatEntry() Retrieving FAT entry for cluster %d.\n", Cluster); switch(Volume->FatType) { case FAT12: FatOffset = Cluster + (Cluster / 2); ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector); ThisFatEntOffset = (FatOffset % Volume->BytesPerSector); TRACE("FatOffset: %d\n", FatOffset); TRACE("ThisFatSecNum: %d\n", ThisFatSecNum); TRACE("ThisFatEntOffset: %d\n", ThisFatEntOffset); if (ThisFatEntOffset == (Volume->BytesPerSector - 1)) { if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 2, (PVOID)FILESYSBUFFER)) { return FALSE; } } else { if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER)) { return FALSE; } } fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset)); fat = SWAPW(fat); if (Cluster & 0x0001) fat = fat >> 4; /* Cluster number is ODD */ else fat = fat & 0x0FFF; /* Cluster number is EVEN */ break; case FAT16: case FATX16: FatOffset = (Cluster * 2); ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector); ThisFatEntOffset = (FatOffset % Volume->BytesPerSector); if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER)) { return FALSE; } fat = *((USHORT *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset)); fat = SWAPW(fat); break; case FAT32: case FATX32: FatOffset = (Cluster * 4); ThisFatSecNum = Volume->ActiveFatSectorStart + (FatOffset / Volume->BytesPerSector); ThisFatEntOffset = (FatOffset % Volume->BytesPerSector); if (!FatReadVolumeSectors(Volume, ThisFatSecNum, 1, (PVOID)FILESYSBUFFER)) { return FALSE; } // Get the fat entry fat = (*((ULONG *) ((ULONG_PTR)FILESYSBUFFER + ThisFatEntOffset))) & 0x0FFFFFFF; fat = SWAPD(fat); break; default: TRACE("Unknown FAT type %d\n", Volume->FatType); return FALSE; }
ULONG FatDetermineFatType(PFAT_BOOTSECTOR FatBootSector, ULONGLONG PartitionSectorCount) { ULONG RootDirSectors; ULONG DataSectorCount; ULONG SectorsPerFat; ULONG TotalSectors; ULONG CountOfClusters; PFAT32_BOOTSECTOR Fat32BootSector = (PFAT32_BOOTSECTOR)FatBootSector; PFATX_BOOTSECTOR FatXBootSector = (PFATX_BOOTSECTOR)FatBootSector; if (0 == strncmp(FatXBootSector->FileSystemType, "FATX", 4)) { CountOfClusters = (ULONG)(PartitionSectorCount / FatXBootSector->SectorsPerCluster); if (CountOfClusters < 65525) { /* Volume is FATX16 */ return FATX16; } else { /* Volume is FAT32 */ return FATX32; } } else { RootDirSectors = ((SWAPW(FatBootSector->RootDirEntries) * 32) + (SWAPW(FatBootSector->BytesPerSector) - 1)) / SWAPW(FatBootSector->BytesPerSector); SectorsPerFat = SWAPW(FatBootSector->SectorsPerFat) ? SWAPW(FatBootSector->SectorsPerFat) : SWAPD(Fat32BootSector->SectorsPerFatBig); TotalSectors = SWAPW(FatBootSector->TotalSectors) ? SWAPW(FatBootSector->TotalSectors) : SWAPD(FatBootSector->TotalSectorsBig); DataSectorCount = TotalSectors - (SWAPW(FatBootSector->ReservedSectors) + (FatBootSector->NumberOfFats * SectorsPerFat) + RootDirSectors); //mjl if (FatBootSector->SectorsPerCluster == 0) CountOfClusters = 0; else CountOfClusters = DataSectorCount / FatBootSector->SectorsPerCluster; if (CountOfClusters < 4085) { /* Volume is FAT12 */ return FAT12; } else if (CountOfClusters < 65525) { /* Volume is FAT16 */ return FAT16; } else { /* Volume is FAT32 */ return FAT32; } } }
BOOLEAN FatOpenVolume(PFAT_VOLUME_INFO Volume, PFAT_BOOTSECTOR BootSector, ULONGLONG PartitionSectorCount) { char ErrMsg[80]; ULONG FatSize; PFAT_BOOTSECTOR FatVolumeBootSector; PFAT32_BOOTSECTOR Fat32VolumeBootSector; PFATX_BOOTSECTOR FatXVolumeBootSector; TRACE("FatOpenVolume() DeviceId = %d\n", Volume->DeviceId); // // Allocate the memory to hold the boot sector // FatVolumeBootSector = (PFAT_BOOTSECTOR)BootSector; Fat32VolumeBootSector = (PFAT32_BOOTSECTOR)BootSector; FatXVolumeBootSector = (PFATX_BOOTSECTOR)BootSector; // Get the FAT type Volume->FatType = FatDetermineFatType(FatVolumeBootSector, PartitionSectorCount); // Dump boot sector (and swap it for big endian systems) TRACE("Dumping boot sector:\n"); if (ISFATX(Volume->FatType)) { FatSwapFatXBootSector(FatXVolumeBootSector); TRACE("sizeof(FATX_BOOTSECTOR) = 0x%x.\n", sizeof(FATX_BOOTSECTOR)); TRACE("FileSystemType: %c%c%c%c.\n", FatXVolumeBootSector->FileSystemType[0], FatXVolumeBootSector->FileSystemType[1], FatXVolumeBootSector->FileSystemType[2], FatXVolumeBootSector->FileSystemType[3]); TRACE("VolumeSerialNumber: 0x%x\n", FatXVolumeBootSector->VolumeSerialNumber); TRACE("SectorsPerCluster: %d\n", FatXVolumeBootSector->SectorsPerCluster); TRACE("NumberOfFats: %d\n", FatXVolumeBootSector->NumberOfFats); TRACE("Unknown: 0x%x\n", FatXVolumeBootSector->Unknown); TRACE("FatType %s\n", Volume->FatType == FATX16 ? "FATX16" : "FATX32"); } else if (Volume->FatType == FAT32) { FatSwapFat32BootSector(Fat32VolumeBootSector); TRACE("sizeof(FAT32_BOOTSECTOR) = 0x%x.\n", sizeof(FAT32_BOOTSECTOR)); TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", Fat32VolumeBootSector->JumpBoot[0], Fat32VolumeBootSector->JumpBoot[1], Fat32VolumeBootSector->JumpBoot[2]); TRACE("OemName: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->OemName[0], Fat32VolumeBootSector->OemName[1], Fat32VolumeBootSector->OemName[2], Fat32VolumeBootSector->OemName[3], Fat32VolumeBootSector->OemName[4], Fat32VolumeBootSector->OemName[5], Fat32VolumeBootSector->OemName[6], Fat32VolumeBootSector->OemName[7]); TRACE("BytesPerSector: %d\n", Fat32VolumeBootSector->BytesPerSector); TRACE("SectorsPerCluster: %d\n", Fat32VolumeBootSector->SectorsPerCluster); TRACE("ReservedSectors: %d\n", Fat32VolumeBootSector->ReservedSectors); TRACE("NumberOfFats: %d\n", Fat32VolumeBootSector->NumberOfFats); TRACE("RootDirEntries: %d\n", Fat32VolumeBootSector->RootDirEntries); TRACE("TotalSectors: %d\n", Fat32VolumeBootSector->TotalSectors); TRACE("MediaDescriptor: 0x%x\n", Fat32VolumeBootSector->MediaDescriptor); TRACE("SectorsPerFat: %d\n", Fat32VolumeBootSector->SectorsPerFat); TRACE("SectorsPerTrack: %d\n", Fat32VolumeBootSector->SectorsPerTrack); TRACE("NumberOfHeads: %d\n", Fat32VolumeBootSector->NumberOfHeads); TRACE("HiddenSectors: %d\n", Fat32VolumeBootSector->HiddenSectors); TRACE("TotalSectorsBig: %d\n", Fat32VolumeBootSector->TotalSectorsBig); TRACE("SectorsPerFatBig: %d\n", Fat32VolumeBootSector->SectorsPerFatBig); TRACE("ExtendedFlags: 0x%x\n", Fat32VolumeBootSector->ExtendedFlags); TRACE("FileSystemVersion: 0x%x\n", Fat32VolumeBootSector->FileSystemVersion); TRACE("RootDirStartCluster: %d\n", Fat32VolumeBootSector->RootDirStartCluster); TRACE("FsInfo: %d\n", Fat32VolumeBootSector->FsInfo); TRACE("BackupBootSector: %d\n", Fat32VolumeBootSector->BackupBootSector); TRACE("Reserved: 0x%x\n", Fat32VolumeBootSector->Reserved); TRACE("DriveNumber: 0x%x\n", Fat32VolumeBootSector->DriveNumber); TRACE("Reserved1: 0x%x\n", Fat32VolumeBootSector->Reserved1); TRACE("BootSignature: 0x%x\n", Fat32VolumeBootSector->BootSignature); TRACE("VolumeSerialNumber: 0x%x\n", Fat32VolumeBootSector->VolumeSerialNumber); TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->VolumeLabel[0], Fat32VolumeBootSector->VolumeLabel[1], Fat32VolumeBootSector->VolumeLabel[2], Fat32VolumeBootSector->VolumeLabel[3], Fat32VolumeBootSector->VolumeLabel[4], Fat32VolumeBootSector->VolumeLabel[5], Fat32VolumeBootSector->VolumeLabel[6], Fat32VolumeBootSector->VolumeLabel[7], Fat32VolumeBootSector->VolumeLabel[8], Fat32VolumeBootSector->VolumeLabel[9], Fat32VolumeBootSector->VolumeLabel[10]); TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", Fat32VolumeBootSector->FileSystemType[0], Fat32VolumeBootSector->FileSystemType[1], Fat32VolumeBootSector->FileSystemType[2], Fat32VolumeBootSector->FileSystemType[3], Fat32VolumeBootSector->FileSystemType[4], Fat32VolumeBootSector->FileSystemType[5], Fat32VolumeBootSector->FileSystemType[6], Fat32VolumeBootSector->FileSystemType[7]); TRACE("BootSectorMagic: 0x%x\n", Fat32VolumeBootSector->BootSectorMagic); } else { FatSwapFatBootSector(FatVolumeBootSector); TRACE("sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR)); TRACE("JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2]); TRACE("OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->OemName[0], FatVolumeBootSector->OemName[1], FatVolumeBootSector->OemName[2], FatVolumeBootSector->OemName[3], FatVolumeBootSector->OemName[4], FatVolumeBootSector->OemName[5], FatVolumeBootSector->OemName[6], FatVolumeBootSector->OemName[7]); TRACE("BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector); TRACE("SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster); TRACE("ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors); TRACE("NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats); TRACE("RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries); TRACE("TotalSectors: %d\n", FatVolumeBootSector->TotalSectors); TRACE("MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor); TRACE("SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat); TRACE("SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack); TRACE("NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads); TRACE("HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors); TRACE("TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig); TRACE("DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber); TRACE("Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1); TRACE("BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature); TRACE("VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber); TRACE("VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->VolumeLabel[0], FatVolumeBootSector->VolumeLabel[1], FatVolumeBootSector->VolumeLabel[2], FatVolumeBootSector->VolumeLabel[3], FatVolumeBootSector->VolumeLabel[4], FatVolumeBootSector->VolumeLabel[5], FatVolumeBootSector->VolumeLabel[6], FatVolumeBootSector->VolumeLabel[7], FatVolumeBootSector->VolumeLabel[8], FatVolumeBootSector->VolumeLabel[9], FatVolumeBootSector->VolumeLabel[10]); TRACE("FileSystemType: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->FileSystemType[0], FatVolumeBootSector->FileSystemType[1], FatVolumeBootSector->FileSystemType[2], FatVolumeBootSector->FileSystemType[3], FatVolumeBootSector->FileSystemType[4], FatVolumeBootSector->FileSystemType[5], FatVolumeBootSector->FileSystemType[6], FatVolumeBootSector->FileSystemType[7]); TRACE("BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic); } // // Check the boot sector magic // if (! ISFATX(Volume->FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55) { sprintf(ErrMsg, "Invalid boot sector magic (expected 0xaa55 found 0x%x)", FatVolumeBootSector->BootSectorMagic); FileSystemError(ErrMsg); return FALSE; } // // Check the FAT cluster size // We do not support clusters bigger than 64k // if ((ISFATX(Volume->FatType) && 64 * 1024 < FatXVolumeBootSector->SectorsPerCluster * 512) || (! ISFATX(Volume->FatType) && 64 * 1024 < FatVolumeBootSector->SectorsPerCluster * FatVolumeBootSector->BytesPerSector)) { FileSystemError("This file system has cluster sizes bigger than 64k.\nFreeLoader does not support this."); return FALSE; } // // Get the sectors per FAT, // root directory starting sector, // and data sector start // if (ISFATX(Volume->FatType)) { Volume->BytesPerSector = 512; Volume->SectorsPerCluster = SWAPD(FatXVolumeBootSector->SectorsPerCluster); Volume->FatSectorStart = (4096 / Volume->BytesPerSector); Volume->ActiveFatSectorStart = Volume->FatSectorStart; Volume->NumberOfFats = 1; FatSize = (ULONG)(PartitionSectorCount / Volume->SectorsPerCluster * (Volume->FatType == FATX16 ? 2 : 4)); Volume->SectorsPerFat = (((FatSize + 4095) / 4096) * 4096) / Volume->BytesPerSector; Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat; Volume->RootDirSectors = FatXVolumeBootSector->SectorsPerCluster; Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors; } else if (Volume->FatType != FAT32) { Volume->BytesPerSector = FatVolumeBootSector->BytesPerSector; Volume->SectorsPerCluster = FatVolumeBootSector->SectorsPerCluster; Volume->FatSectorStart = FatVolumeBootSector->ReservedSectors; Volume->ActiveFatSectorStart = Volume->FatSectorStart; Volume->NumberOfFats = FatVolumeBootSector->NumberOfFats; Volume->SectorsPerFat = FatVolumeBootSector->SectorsPerFat; Volume->RootDirSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat; Volume->RootDirSectors = ((FatVolumeBootSector->RootDirEntries * 32) + (Volume->BytesPerSector - 1)) / Volume->BytesPerSector; Volume->DataSectorStart = Volume->RootDirSectorStart + Volume->RootDirSectors; } else { Volume->BytesPerSector = Fat32VolumeBootSector->BytesPerSector; Volume->SectorsPerCluster = Fat32VolumeBootSector->SectorsPerCluster; Volume->FatSectorStart = Fat32VolumeBootSector->ReservedSectors; Volume->ActiveFatSectorStart = Volume->FatSectorStart + ((Fat32VolumeBootSector->ExtendedFlags & 0x80) ? ((Fat32VolumeBootSector->ExtendedFlags & 0x0f) * Fat32VolumeBootSector->SectorsPerFatBig) : 0); Volume->NumberOfFats = Fat32VolumeBootSector->NumberOfFats; Volume->SectorsPerFat = Fat32VolumeBootSector->SectorsPerFatBig; Volume->RootDirStartCluster = Fat32VolumeBootSector->RootDirStartCluster; Volume->DataSectorStart = Volume->FatSectorStart + Volume->NumberOfFats * Volume->SectorsPerFat; // // Check version // we only work with version 0 // if (Fat32VolumeBootSector->FileSystemVersion != 0) { FileSystemError("FreeLoader is too old to work with this FAT32 filesystem.\nPlease update FreeLoader."); return FALSE; } } return TRUE; }
void ENCONCAT(stack& s) { SWAPD(s); CONS(s); CONCAT(s); }