?? vdkpart.c
字號:
/* vdkpart.c Read partition table from virtual disk Copyright (C) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "vdkaccess.h"#include "vdkpart.h"//// Decide file system type from sector data//UCHAR VdkIdentifyFAT( PFAT16_PBR Pbr, PPARTITION_ITEM PartItem){ if (Pbr->signature == SIGNATURE_WORD && (Pbr->bpb.BytesPerSector == 512 || Pbr->bpb.BytesPerSector == 1024 || Pbr->bpb.BytesPerSector == 2048 || Pbr->bpb.BytesPerSector == 4096) && (Pbr->bpb.SectorsPerCluster == 1 || Pbr->bpb.SectorsPerCluster == 2 || Pbr->bpb.SectorsPerCluster == 4 || Pbr->bpb.SectorsPerCluster == 8 || Pbr->bpb.SectorsPerCluster == 16 || Pbr->bpb.SectorsPerCluster == 32 || Pbr->bpb.SectorsPerCluster == 64 || Pbr->bpb.SectorsPerCluster == 128) && Pbr->bpb.MediaDescriptor) { if (Pbr->bpb.NumberOfFATs == 0 && Pbr->bpb.RootEntries == 0 && Pbr->bpb.SmallSectors == 0 && Pbr->bpb.SectorsPerFAT == 0 && Pbr->bpb.LargeSectors == 0) { // // could be NTFS // if (VdkCmpNoCaseN(Pbr->oemid, "OS2", 3) == 0) { // // OS/2 filesystem // if (VdkCmpNoCaseN(Pbr->exbpb.FileSystemType, "HPFS", 4) == 0) { strncpy(PartItem->fsname, "OS2 HPFS", MAX_FSNAME_LEN); } else { strncpy(PartItem->fsname, "OS2 IFS", MAX_FSNAME_LEN); } } else if (VdkCmpNoCaseN(Pbr->oemid, "NTFS", 4) == 0) { // // NTFS // strncpy(PartItem->fsname, "NTFS", MAX_FSNAME_LEN); } return PART_NTFS_HPFS; } else if (Pbr->bpb.NumberOfFATs == 2) { // // FAT12/16/32 // if (Pbr->bpb.RootEntries == 0 && Pbr->bpb.SmallSectors == 0 && Pbr->bpb.SectorsPerFAT == 0 && Pbr->bpb.LargeSectors) { // // FAT32 // strcpy(PartItem->fsname, "FAT32"); strncpy( PartItem->label, ((PFAT32_PBR)Pbr)->exbpb.VolumeLabel, sizeof(((PFAT32_PBR)Pbr)->exbpb.VolumeLabel)); return PART_DOS_FAT32; } else if (Pbr->bpb.RootEntries && Pbr->bpb.SectorsPerFAT && ((Pbr->bpb.SmallSectors == 0 && Pbr->bpb.LargeSectors) || (Pbr->bpb.SmallSectors && Pbr->bpb.LargeSectors == 0))) { // // FAT12 or FAT16 // if (!strncmp(Pbr->exbpb.FileSystemType, "FAT", 3)) { strncpy( PartItem->fsname, Pbr->exbpb.FileSystemType, sizeof(Pbr->exbpb.FileSystemType)); } else { strcpy(PartItem->fsname, "FAT16"); } strncpy( PartItem->label, Pbr->exbpb.VolumeLabel, sizeof(Pbr->exbpb.VolumeLabel)); if (Pbr->bpb.LargeSectors) { return PART_DOS_HUGE; } else if (Pbr->bpb.SmallSectors >= MIN_FAT16_VOLUME) { return PART_DOS_FAT16; } else { return PART_DOS_FAT12; } } } } return PART_NONE;}UCHAR VdkIdentifyXFS( PXFS_SB Xfsb, PPARTITION_ITEM PartItem){ if (!strncmp(Xfsb->s_magic, XFS_SUPER_MAGIC, sizeof(Xfsb->s_magic))) { strncpy(PartItem->fsname, "xfs", MAX_FSNAME_LEN); strncpy( PartItem->label, Xfsb->s_fname, sizeof(Xfsb->s_fname)); return PART_LINUX; } return PART_NONE;}UCHAR VdkIdentifyEXT2( PEXT2_SB e2fsb, PPARTITION_ITEM PartItem){ if (e2fsb->s_magic == EXT2_SUPER_MAGIC) { if (e2fsb->s_feature & EXT3_HAS_JOURNAL) { strncpy(PartItem->fsname, "ext3fs", MAX_FSNAME_LEN); } else { strncpy(PartItem->fsname, "ext2fs", MAX_FSNAME_LEN); } strncpy( PartItem->label, e2fsb->s_volume_name, sizeof(e2fsb->s_volume_name)); return PART_LINUX; } return PART_NONE;}UCHAR VdkIdentifyRFS( PREISER_SB rfsb, PPARTITION_ITEM PartItem){ if (!strncmp(rfsb->s_magic, REISERFS_SUPER_MAGIC, strlen(REISERFS_SUPER_MAGIC)) || !strncmp(rfsb->s_magic, REISER2FS_SUPER_MAGIC, strlen(REISER2FS_SUPER_MAGIC))) { strncpy(PartItem->fsname, "reiserfs", MAX_FSNAME_LEN); return PART_LINUX; } return PART_NONE;}UCHAR VdkIdentifyFS( PVDK_DISK_INFO DiskInfo, HANDLE hFile, PPARTITION_ITEM PartItem){ UCHAR buf[1024]; UCHAR type; VDKSTAT ret; // // Read partition boot record // if (DiskInfo) { ret = VdkReadSector( DiskInfo, PartItem->offset, 1, buf); } else { ret = VdkReadFileAt( hFile, (INT64)PartItem->offset << VDK_BYTE_SHIFT_TO_SECTOR, buf, VDK_BYTES_PER_SECTOR, NULL); } if (ret != VDK_OK) { return PART_NONE; } type = VdkIdentifyFAT((PFAT16_PBR)buf, PartItem); if (type != PART_NONE) { return type; } type = VdkIdentifyXFS((PXFS_SB)buf, PartItem); if (type != PART_NONE) { return type; } if (DiskInfo) { ret = VdkReadSector( DiskInfo, PartItem->offset + 2, 1, buf); } else { ret = VdkReadFileAt( hFile, (INT64)(PartItem->offset + 2) << VDK_BYTE_SHIFT_TO_SECTOR, buf, VDK_BYTES_PER_SECTOR, NULL); } if (ret != VDK_OK) { return PART_NONE; } type = VdkIdentifyEXT2((PEXT2_SB)buf, PartItem); if (type != PART_NONE) { return type; } if (DiskInfo) { ret = VdkReadSector( DiskInfo, PartItem->offset + REISERFS_SUPER_OFFSET, 1, buf); } else { ret = VdkReadFileAt( hFile, (INT64)(PartItem->offset + REISERFS_SUPER_OFFSET) << VDK_BYTE_SHIFT_TO_SECTOR, buf, VDK_BYTES_PER_SECTOR, NULL); } if (ret != VDK_OK) { return PART_NONE; } type = VdkIdentifyRFS((PREISER_SB)buf, PartItem); return type;}//// Read partition table and build partition list//VDKSTAT VdkListPartitions( PVDK_DISK_INFO DiskInfo, HANDLE hFile, ULONG Capacity, PLIST_CALLBACK CallBack, PVOID Param){ PARTITION_TABLE ptable; PPARTITION_ENTRY pentry; PARTITION_ITEM pitem; ULONG ext_offset; int logical_num; int logical_offset; VDKSTAT ret; int idx; // // Read master boot record // if (DiskInfo) { Capacity = DiskInfo->Capacity; ret = VdkReadSector( DiskInfo, 0, 1, (PUCHAR)&ptable); } else { ret = VdkReadFileAt( hFile, 0, &ptable, VDK_BYTES_PER_SECTOR, NULL); } if (ret != VDK_OK) { return ret; } // // Check if the MBR contains a valid partition table // idx = 0; if (ptable.p.signature == SIGNATURE_WORD) { do { pentry = &(ptable.p.partition[idx]); if (pentry->type) { ULONG start, end; start = pentry->start_head * (pentry->start_sec & 0x3f) * (((pentry->start_sec & 0xc0) << 8) + pentry->start_cyl); end = pentry->end_head * (pentry->end_sec & 0x3f) * (((pentry->end_sec & 0xc0) << 8) + pentry->end_cyl); if (end <= start || pentry->lba_start >= Capacity || pentry->lba_length > Capacity || pentry->lba_start + pentry->lba_length > Capacity) { break; } } } while (++idx < 4); } VdkZeroMem(&pitem, sizeof(pitem)); pitem.length = Capacity; strcpy(pitem.fsname, "<disk>"); if (idx < 4) { pitem.type = VdkIdentifyFS(DiskInfo, hFile, &pitem); (*CallBack)(&pitem, Param); return VDK_OK; } // // callback for disk itself // (*CallBack)(&pitem, Param); // // Process primary partitions // ext_offset = 0; for (idx = 0; idx < 4; idx++) { pentry = &(ptable.p.partition[idx]); if (pentry->type) { if (IS_EXTENDED(pentry->type)) { ext_offset = pentry->lba_start; } else { pitem.idx++; pitem.num = idx + 1; pitem.type = pentry->type; pitem.offset = pentry->lba_start; pitem.length = pentry->lba_length; pitem.fsname[0] = '\0'; pitem.label[0] = '\0'; VdkIdentifyFS(DiskInfo, hFile, &pitem); (*CallBack)(&pitem, Param); } } } if (!ext_offset) { return VDK_OK; } // // Process extended partitions // logical_offset = 0; logical_num = 5; for (;;) { // // Read extended partition PBR // if (DiskInfo) { ret = VdkReadSector( DiskInfo, ext_offset + logical_offset, 1, (PUCHAR)&ptable); } else { ret = VdkReadFileAt( hFile, (INT64)(ext_offset + logical_offset) << VDK_BYTE_SHIFT_TO_SECTOR, &ptable, VDK_BYTES_PER_SECTOR, NULL); } if (ret != VDK_OK) { return ret; } if (ptable.p.signature != SIGNATURE_WORD) { return VDK_DATA; } // // Process logical partition // for (idx = 0; idx < 4; idx++) { pentry = &(ptable.p.partition[idx]); if (pentry->type && !IS_EXTENDED(pentry->type)) { pitem.idx++; pitem.num = logical_num++; pitem.type = pentry->type; pitem.offset = pentry->lba_start + ext_offset + logical_offset; pitem.length = pentry->lba_length; pitem.fsname[0] = '\0'; pitem.label[0] = '\0'; VdkIdentifyFS(DiskInfo, hFile, &pitem); (*CallBack)(&pitem, Param); break; } } // // Search next extended partition // for (idx = 0; idx < 4; idx++) { if (IS_EXTENDED(ptable.p.partition[idx].type)) { logical_offset = ptable.p.partition[idx].lba_start; break; } } if (idx >= 4) { // No more extended partition break; } } return VDK_OK;}static const struct _PARTITION_NAME { ULONG type; PCHAR name;}p_names[] = { { 0x00, "(none)" }, { 0x01, "FAT12" }, { 0x02, "XENIX root" }, { 0x03, "XENIX /usr" }, { 0x04, "FAT16" }, { 0x05, "Extended" }, { 0x06, "FAT16 HUGE" }, { 0x07, "HPFS/NTFS" }, { 0x08, "AIX boot" }, { 0x09, "AIX data" }, { 0x0a, "OS/2 Boot Manager" }, { 0x0b, "FAT32" }, { 0x0c, "FAT32 LBA" }, { 0x0e, "FAT16 LBA" }, { 0x0f, "Extended LBA" }, { 0x10, "OPUS" }, { 0x11, "FAT12 hidden" }, { 0x12, "Compaq Diag" }, { 0x13, "B-right/V" }, { 0x14, "FAT16 hidden" }, { 0x16, "FAT16 HUGE hidden" }, { 0x17, "HPFS/NTFS hidden" }, { 0x18, "AST SmartSleep" }, { 0x19, "Willowtech" }, { 0x1b, "FAT32 hidden" }, { 0x1c, "FAT32 LBA hidden" }, { 0x1e, "FAT16 LBA hidden" }, { 0x20, "Willowsoft OFS1" }, { 0x21, "FSo2" }, { 0x24, "NEC DOS 3.x" }, { 0x38, "Theos" }, { 0x39, "Plan 9" }, { 0x3c, "PartitionMagic" }, { 0x40, "Venix 80286" }, { 0x41, "PPC PReP boot" }, { 0x42, "Dynamic Disk" }, { 0x45, "EUMEL/Elan" }, { 0x46, "EUMEL/Elan" }, { 0x47, "EUMEL/Elan" }, { 0x48, "EUMEL/Elan" }, { 0x4d, "QNX4.x" }, { 0x4e, "QNX4.x 2nd" }, { 0x4f, "QNX4.x 3rd" }, { 0x50, "OnTrack DM" }, { 0x51, "OnTrack DM" }, { 0x52, "CP/M" }, { 0x53, "OnTrack DM" }, { 0x54, "OnTrack DM" }, { 0x55, "EZ-Drive" }, { 0x56, "GoldenBow" }, { 0x5c, "Priam Edisk" }, { 0x61, "SpeedStor" }, { 0x63, "GNU HURD" }, { 0x64, "Netware 286" }, { 0x65, "Netware 386" }, { 0x70, "DiskSecure" }, { 0x75, "PC/IX" }, { 0x7e, "F.I.X." }, { 0x80, "Old Minix" }, { 0x81, "Minix/Old Linux" }, { 0x82, "Linux swap" }, { 0x83, "Linux" }, { 0x84, "NTFT FAT16" }, { 0x85, "Linux Extended" }, { 0x86, "NTFT FAT16 HUGE" }, { 0x87, "NTFT NTFS" }, { 0x8b, "NTFT FAT32" }, { 0x8c, "NTFT FAT32X" }, { 0x8e, "NTFT FAT16X" }, { 0x93, "Amoeba" }, { 0x94, "Amoeba BBT" }, { 0x99, "Mylex EISA SCSI" }, { 0x9f, "BSD/OS" }, { 0xa0, "Suspend" }, { 0xa5, "FreeBSD" }, { 0xa6, "OpenBSD" }, { 0xa7, "NeXTSTEP" }, { 0xa9, "NetBSD" }, { 0xb7, "BSDI fs" }, { 0xb8, "BSDI swap" }, { 0xbb, "Boot Wizard (hid)" }, { 0xbe, "Solaris boot" }, { 0xc0, "Novell DOS/sec" }, { 0xc1, "DRDOS FAT12" }, { 0xc4, "DRDOS FAT16" }, { 0xc6, "DRDOS FAT16 HUGE" }, { 0xc7, "Syrinx" }, { 0xcb, "DRDOS FAT32" }, { 0xcc, "DRDOS FAT32X" }, { 0xce, "DRDOS FAT16X" }, { 0xd0, "MDOS FAT12" }, { 0xd1, "MDOS FAT12" }, { 0xd4, "MDOS FAT16" }, { 0xd5, "MDOS Extended" }, { 0xd6, "MDOS FAT16 HUGE" }, { 0xd8, "CP/M" }, { 0xda, "Non-FS data" }, { 0xdb, "CP/M" }, { 0xde, "Dell Utility" }, { 0xdf, "BootIt" }, { 0xe1, "DOS access" }, { 0xe2, "DOS R/O" }, { 0xe3, "DOS R/O" }, { 0xe4, "SpeedStor" }, { 0xeb, "BeOS BFS" }, { 0xee, "EFI GPT" }, { 0xef, "EFI FAT" }, { 0xf0, "PA-RISC boot" }, { 0xf1, "SpeedStor" }, { 0xf2, "DOS secondary" }, { 0xf4, "SpeedStor" }, { 0xf5, "Prologue" }, { 0xfd, "Linux RAID" }, { 0xfe, "LANstep" }, { 0xff, "Xenix BBT" }, { 0, 0 }};const PCHAR GetPartitionTypeName(ULONG type){ const struct _PARTITION_NAME *p = p_names; while (p->name && p->type != type) { p++; } return p->name;}#ifdef _WIN32//// Decide if a partition is mountable or not// NTFT partitions are not mountable because// VDK driver does not communicate with the// Windows Mount Manager//BOOL IsPartitionMountable(ULONG type, BOOL read_only){ switch (type) { case 0x01: // DOS FAT12 case 0x04: // DOS FAT16 case 0x06: // DOS FAT16 HUGE case 0x0e: // DOS FAT16X return TRUE; case 0x07: // HPFS, NTFS if (read_only) { OSVERSIONINFO os = { sizeof(os) }; if (GetVersionEx(&os)) { if (os.dwPlatformId == VER_PLATFORM_WIN32_NT && os.dwMajorVersion >= 5 && os.dwMinorVersion >= 1) { // XP and later can mount NTFS read-only. return TRUE; } } return FALSE; } else { return TRUE; } case 0x0b: // DOS FAT32 case 0x0c: // DOS FAT32X // Windows NT 4.0 usually cannot mount FAT32 partition return ((GetVersion() & 0xFF) >= 5); default: return FALSE; }}#endif // _WIN32
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -