/* get HFS wrapper information */ static int getwrapper(const HFSMasterDirectoryBlock *mdbp, off_t *offset) { if ((SW16(mdbp->drSigWord) != kHFSSigWord) || (SW16(mdbp->drEmbedSigWord) != kHFSPlusSigWord)) { return(0); } *offset = SW16(mdbp->drAlBlSt) * 512; *offset += (u_int64_t)SW16(mdbp->drEmbedExtent.startBlock) * (u_int64_t)SW32(mdbp->drAlBlkSiz); return (1); }
void swap_endian_disklabel(struct disklabel *nlp, struct disklabel *olp) { int i; #define SW16(X) nlp->X = bswap16(olp->X) #define SW32(X) nlp->X = bswap32(olp->X) SW32(d_magic); SW16(d_type); SW16(d_subtype); /* no need to swap char strings */ memcpy(nlp->d_typename, olp->d_typename, sizeof(nlp->d_typename)); /* XXX What should we do for d_un (an union of char and pointers) ? */ memcpy(nlp->d_packname, olp->d_packname, sizeof(nlp->d_packname)); SW32(d_secsize); SW32(d_nsectors); SW32(d_ntracks); SW32(d_ncylinders); SW32(d_secpercyl); SW32(d_secperunit); SW16(d_sparespertrack); SW16(d_sparespercyl); SW32(d_acylinders); SW16(d_rpm); SW16(d_interleave); SW16(d_trackskew); /* sector 0 skew, per track */ SW16(d_cylskew); /* sector 0 skew, per cylinder */ SW32(d_headswitch); /* head switch time, usec */ SW32(d_trkseek); /* track-to-track seek, usec */ SW32(d_flags); /* generic flags */ for (i = 0; i < NDDATA; i++) SW32(d_drivedata[i]); /* drive-type specific information */ for (i = 0; i < NSPARE; i++) SW32(d_spare[i]); /* reserved for future use */ SW32(d_magic2); /* the magic number (again) */ SW16(d_checksum); /* xor of data incl. partitions */ /* filesystem and partition information: */ SW16(d_npartitions); /* number of partitions in following */ SW32(d_bbsize); /* size of boot area at sn0, bytes */ SW32(d_sbsize); /* max size of fs superblock, bytes */ for (i = 0; i < MAXPARTITIONS; i++) { SW32(d_partitions[i].p_size); SW32(d_partitions[i].p_offset); SW32(d_partitions[i].p_fsize); /* p_fstype and p_frag is uint8_t, so no need to swap */ nlp->d_partitions[i].p_fstype = olp->d_partitions[i].p_fstype; nlp->d_partitions[i].p_frag = olp->d_partitions[i].p_frag; SW16(d_partitions[i].p_cpg); } #undef SW32 #undef SW16 }
/* Check if the disk is HFS disk and return its subtypes */ bool is_hfs(char *devnode, int *fssubtype) { HFSPlusVolumeHeader *vhp; off_t offset = 0; char *buffer = NULL; int fd = 0; bool retval = false; /* default fssubtype to non-existing value */ *fssubtype = -1; buffer = (char *)malloc(MAX_HFS_BLOCK_READ); if (!buffer) { goto out; } /* open the device */ fd = open(devnode, O_RDONLY | O_NDELAY, 0); if (fd <= 0) { goto out; } /* read volume header (512 bytes, block 2) from the device */ if (getblk(fd, 2, MAX_HFS_BLOCK_READ, buffer) < MAX_HFS_BLOCK_READ) { goto out; } /* Check if it is a HFS volume */ if (getwrapper((HFSMasterDirectoryBlock *)buffer, &offset)) { if (getblk(fd, 2 + (offset/MAX_HFS_BLOCK_READ), MAX_HFS_BLOCK_READ, buffer) < MAX_HFS_BLOCK_READ) { goto out; } } vhp = (HFSPlusVolumeHeader *)buffer; /* Validate signature */ switch (SW16(vhp->signature)) { case kHFSPlusSigWord: { if (SW16(vhp->version) != kHFSPlusVersion) { goto out; } break; } case kHFSXSigWord: { if (SW16(vhp->version) != kHFSXVersion) { goto out; } break; } case kHFSSigWord: { /* HFS */ *fssubtype = kHFSSubType; retval = true; goto out; } default: { goto out; } }; if ((vhp->journalInfoBlock != 0) && (SW32(vhp->attributes) & kHFSVolumeJournaledMask)) { /* Journaled */ *fssubtype = kHFSJSubType; } if (SW16(vhp->signature) == kHFSXSigWord) { BTHeaderRec * bthp; off_t foffset; foffset = (off_t)SW32(vhp->catalogFile.extents[0].startBlock) * (off_t)SW32(vhp->blockSize); if (getblk(fd, (offset/MAX_HFS_BLOCK_READ) + (foffset/MAX_HFS_BLOCK_READ) , MAX_HFS_BLOCK_READ, buffer) < MAX_HFS_BLOCK_READ) { goto out; } bthp = (BTHeaderRec *)&buffer[sizeof(BTNodeDescriptor)]; if ((SW16(bthp->maxKeyLength) == kHFSPlusCatalogKeyMaximumLength) && (bthp->keyCompareType == kHFSBinaryCompare)) { /* HFSX */ if (*fssubtype == kHFSJSubType) { /* Journaled HFSX */ *fssubtype = kHFSXJSubType; } else { /* HFSX */ *fssubtype = kHFSXSubType; } } } if (*fssubtype < 0) { /* default HFS Plus */ *fssubtype = kHFSPlusSubType; } retval = true; out: if (buffer) { free(buffer); } if (fd > 0) { close(fd); } return retval; }
void swap_mmeye_disklabel(struct disklabel *nlp, struct disklabel *olp) { int i; uint16_t *np, *op; #if BYTE_ORDER == BIG_ENDIAN #define SW16(X) nlp->X = bswap16(olp->X) #define SW32(X) nlp->X = bswap32(olp->X) #else #define SW16(X) nlp->X = olp->X #define SW32(X) nlp->X = olp->X #endif SW32(d_magic); SW16(d_type); SW16(d_subtype); op = (uint16_t *)&olp->d_typename[0]; np = (uint16_t *)&nlp->d_typename[0]; for (i = 0; i < sizeof(olp->d_typename) / sizeof(uint16_t); i++) *np++ = bswap16(*op++); op = (uint16_t *)&olp->d_un.un_d_packname[0]; np = (uint16_t *)&nlp->d_un.un_d_packname[0]; for (i = 0; i < sizeof(olp->d_un) / sizeof(uint16_t); i++) *np++ = bswap16(*op++); SW32(d_secsize); SW32(d_nsectors); SW32(d_ntracks); SW32(d_ncylinders); SW32(d_secpercyl); SW32(d_secperunit); SW16(d_sparespertrack); SW16(d_sparespercyl); SW32(d_acylinders); SW16(d_rpm); SW16(d_interleave); SW16(d_trackskew); /* sector 0 skew, per track */ SW16(d_cylskew); /* sector 0 skew, per cylinder */ SW32(d_headswitch); /* head switch time, usec */ SW32(d_trkseek); /* track-to-track seek, usec */ SW32(d_flags); /* generic flags */ for (i = 0; i < NDDATA; i++) SW32(d_drivedata[i]); /* drive-type specific information */ for (i = 0; i < NSPARE; i++) SW32(d_spare[i]); /* reserved for future use */ SW32(d_magic2); /* the magic number (again) */ SW16(d_checksum); /* xor of data incl. partitions */ /* filesystem and partition information: */ SW16(d_npartitions); /* number of partitions in following */ SW32(d_bbsize); /* size of boot area at sn0, bytes */ SW32(d_sbsize); /* max size of fs superblock, bytes */ for (i = 0; i < MAXPARTITIONS; i++) { SW32(d_partitions[i].p_size); SW32(d_partitions[i].p_offset); SW32(d_partitions[i].p_fsize); nlp->d_partitions[i].p_fstype = olp->d_partitions[i].p_fstype; nlp->d_partitions[i].p_frag = olp->d_partitions[i].p_frag; SW16(d_partitions[i].p_cpg); } #undef SW32 #undef SW16 }