#include #include #include #include #include #include #include #include "include/fs.h" typedef int (*dfunc)(int); static unsigned short get_le_short(void *from) { unsigned char *p = from; return ((unsigned short)(p[1]) << 8) + (unsigned short)p[0]; } static unsigned int get_le_long(void *from) { unsigned char *p = from; return ((unsigned int)(p[3]) << 24) + ((unsigned int)(p[2]) << 16) + ((unsigned int)(p[1]) << 8) + (unsigned int)p[0]; } static unsigned short get_be_short(void *from) { unsigned char *p = from; return ((unsigned short)(p[0]) << 8) + (unsigned short)p[1]; } static unsigned int get_be_long(void *from) { unsigned char *p = from; return ((unsigned int)(p[0]) << 24) + ((unsigned int)(p[1]) << 16) + ((unsigned int)(p[2]) << 8) + (unsigned int)p[3]; } static int get_buffer(int fd, unsigned char *b, int offset, int len) { if(lseek(fd, offset, SEEK_SET) != offset) return -1; if(read(fd, b, len) != len) return -1; return 0; } #define MBR_BUF_SIZE 512 static int detect_mbr(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE); if(get_buffer(fd, buffer, 0, MBR_BUF_SIZE) != 0) goto out; if((buffer[510] == 0x55) && (buffer[511] == 0xAA)) ret = MBR; out: free(buffer); return ret; } #define EFI_BUF_OFFSET 512 #define EFI_BUF_SIZE 512 static int detect_efi(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(EFI_BUF_SIZE); if(get_buffer(fd, buffer, EFI_BUF_OFFSET, EFI_BUF_SIZE) != 0) goto out; if(!memcmp(buffer, "EFI PART", 8)) ret = EFI; out: free(buffer); return ret; } #define EXT2_BUF_SIZE 1024 static int detect_ext23(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(EXT2_BUF_SIZE); if(get_buffer(fd, buffer, 1024, EXT2_BUF_SIZE) != 0) goto out; if(get_le_short(buffer + 56) == 0xEF53) { if(get_le_long(buffer + 92) & 0x0004) { if ((get_le_long(buffer + 96) < 0x0000040) && (get_le_long(buffer + 100) < 0x0000008)) ret = EXT3; else ret = EXT4; } else ret = EXT2; } out: free(buffer); return ret; } #define FAT_BUF_SIZE 512 static int detect_fat(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(FAT_BUF_SIZE); if(get_buffer(fd, buffer, 0, FAT_BUF_SIZE) != 0) goto out; if (((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9)) && ((buffer[510] & 0xff) == 0x55) /*&& ((buffer[511] & 0xff == 0xAA))*/ && (memcmp(buffer + 3, "NTFS ", 8))) ret = FAT; out: free(buffer); return ret; } static int detect_exfat(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(FAT_BUF_SIZE); if(get_buffer(fd, buffer, 0, FAT_BUF_SIZE) != 0) goto out; if (!memcmp(buffer + 3, "EXFAT ", 7)) ret = EXFAT; out: free(buffer); return ret; } #define HFSPLUS_VOL_JOURNALED (1 << 13) #define HFSPLUS_BUF_SIZE 512 static int detect_hfsplus(int fd) { int ret = NONE; unsigned short magic; unsigned int journal; unsigned char *buffer = (unsigned char*)malloc(HFSPLUS_BUF_SIZE); if(get_buffer(fd, buffer, 1024, HFSPLUS_BUF_SIZE) != 0) goto out; magic = get_be_short(buffer); journal = get_be_long(buffer + 4) & HFSPLUS_VOL_JOURNALED; if(magic == 0x482B || magic == 0x4858) { if(!journal) ret = HFSPLUS; else ret = HFSPLUSJOURNAL; } out: free(buffer); return ret; } #define NTFS_BUF_SIZE 512 static int detect_ntfs(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(NTFS_BUF_SIZE); if(get_buffer(fd, buffer, 0, NTFS_BUF_SIZE) != 0) goto out; if(!memcmp(buffer + 3, "NTFS ", 8)) ret = NTFS; out: free(buffer); return ret; } #define EXTENDED_BUF_SIZE 512 static int detect_extended(int fd) { int ret = NONE; unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE); if(get_buffer(fd, buffer, 0, 512) != 0) goto out; if((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9)) goto out; if(((buffer[510] & 0xff) == 0x55) && ((buffer[511] & 0xff) == 0xAA)) ret = EXTENDED; out: free(buffer); return ret; } static dfunc funcs[] = { detect_ext23, detect_exfat, detect_fat, detect_ntfs, detect_hfsplus, detect_extended, detect_efi, detect_mbr, }; int detect_fs(char *device) { int i = 0; int ret = NONE; int fd; fd = open(device, O_RDONLY); if(!fd) return NONE; while((i < 6) && (ret == NONE)) ret = funcs[i++](fd); close(fd); return ret; }