fs.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include "include/fs.h"
  9. typedef int (*dfunc)(int);
  10. static unsigned short
  11. get_le_short(void *from)
  12. {
  13. unsigned char *p = from;
  14. return ((unsigned short)(p[1]) << 8) +
  15. (unsigned short)p[0];
  16. }
  17. static unsigned int get_le_long(void *from)
  18. {
  19. unsigned char *p = from;
  20. return ((unsigned int)(p[3]) << 24) +
  21. ((unsigned int)(p[2]) << 16) +
  22. ((unsigned int)(p[1]) << 8) +
  23. (unsigned int)p[0];
  24. }
  25. static unsigned short get_be_short(void *from)
  26. {
  27. unsigned char *p = from;
  28. return ((unsigned short)(p[0]) << 8) +
  29. (unsigned short)p[1];
  30. }
  31. static unsigned int get_be_long(void *from)
  32. {
  33. unsigned char *p = from;
  34. return ((unsigned int)(p[0]) << 24) +
  35. ((unsigned int)(p[1]) << 16) +
  36. ((unsigned int)(p[2]) << 8) +
  37. (unsigned int)p[3];
  38. }
  39. static int get_buffer(int fd, unsigned char *b, int offset, int len)
  40. {
  41. if(lseek(fd, offset, SEEK_SET) != offset)
  42. return -1;
  43. if(read(fd, b, len) != len)
  44. return -1;
  45. return 0;
  46. }
  47. #define MBR_BUF_SIZE 512
  48. static int detect_mbr(int fd)
  49. {
  50. int ret = NONE;
  51. unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE);
  52. if(get_buffer(fd, buffer, 0, MBR_BUF_SIZE) != 0)
  53. goto out;
  54. if((buffer[510] == 0x55) && (buffer[511] == 0xAA))
  55. ret = MBR;
  56. out:
  57. free(buffer);
  58. return ret;
  59. }
  60. #define EFI_BUF_OFFSET 512
  61. #define EFI_BUF_SIZE 512
  62. static int detect_efi(int fd)
  63. {
  64. int ret = NONE;
  65. unsigned char *buffer = (unsigned char*)malloc(EFI_BUF_SIZE);
  66. if(get_buffer(fd, buffer, EFI_BUF_OFFSET, EFI_BUF_SIZE) != 0)
  67. goto out;
  68. if(!memcmp(buffer, "EFI PART", 8))
  69. ret = EFI;
  70. out:
  71. free(buffer);
  72. return ret;
  73. }
  74. #define EXT2_BUF_SIZE 1024
  75. static int detect_ext23(int fd)
  76. {
  77. int ret = NONE;
  78. unsigned char *buffer = (unsigned char*)malloc(EXT2_BUF_SIZE);
  79. if(get_buffer(fd, buffer, 1024, EXT2_BUF_SIZE) != 0)
  80. goto out;
  81. if(get_le_short(buffer + 56) == 0xEF53)
  82. {
  83. if(get_le_long(buffer + 92) & 0x0004)
  84. {
  85. if ((get_le_long(buffer + 96) < 0x0000040)
  86. && (get_le_long(buffer + 100) < 0x0000008))
  87. ret = EXT3;
  88. else
  89. ret = EXT4;
  90. }
  91. else
  92. ret = EXT2;
  93. }
  94. out:
  95. free(buffer);
  96. return ret;
  97. }
  98. #define FAT_BUF_SIZE 512
  99. static int detect_fat(int fd)
  100. {
  101. int ret = NONE;
  102. unsigned char *buffer = (unsigned char*)malloc(FAT_BUF_SIZE);
  103. if(get_buffer(fd, buffer, 0, FAT_BUF_SIZE) != 0)
  104. goto out;
  105. if (((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9))
  106. && ((buffer[510] & 0xff) == 0x55) /*&& ((buffer[511] & 0xff == 0xAA))*/
  107. && (memcmp(buffer + 3, "NTFS ", 8)))
  108. ret = FAT;
  109. out:
  110. free(buffer);
  111. return ret;
  112. }
  113. static int detect_exfat(int fd)
  114. {
  115. int ret = NONE;
  116. unsigned char *buffer = (unsigned char*)malloc(FAT_BUF_SIZE);
  117. if(get_buffer(fd, buffer, 0, FAT_BUF_SIZE) != 0)
  118. goto out;
  119. if (!memcmp(buffer + 3, "EXFAT ", 7))
  120. ret = EXFAT;
  121. out:
  122. free(buffer);
  123. return ret;
  124. }
  125. #define HFSPLUS_VOL_JOURNALED (1 << 13)
  126. #define HFSPLUS_BUF_SIZE 512
  127. static int detect_hfsplus(int fd)
  128. {
  129. int ret = NONE;
  130. unsigned short magic;
  131. unsigned int journal;
  132. unsigned char *buffer = (unsigned char*)malloc(HFSPLUS_BUF_SIZE);
  133. if(get_buffer(fd, buffer, 1024, HFSPLUS_BUF_SIZE) != 0)
  134. goto out;
  135. magic = get_be_short(buffer);
  136. journal = get_be_long(buffer + 4) & HFSPLUS_VOL_JOURNALED;
  137. if(magic == 0x482B || magic == 0x4858)
  138. {
  139. if(!journal)
  140. ret = HFSPLUS;
  141. else
  142. ret = HFSPLUSJOURNAL;
  143. }
  144. out:
  145. free(buffer);
  146. return ret;
  147. }
  148. #define NTFS_BUF_SIZE 512
  149. static int detect_ntfs(int fd)
  150. {
  151. int ret = NONE;
  152. unsigned char *buffer = (unsigned char*)malloc(NTFS_BUF_SIZE);
  153. if(get_buffer(fd, buffer, 0, NTFS_BUF_SIZE) != 0)
  154. goto out;
  155. if(!memcmp(buffer + 3, "NTFS ", 8))
  156. ret = NTFS;
  157. out:
  158. free(buffer);
  159. return ret;
  160. }
  161. #define EXTENDED_BUF_SIZE 512
  162. static int detect_extended(int fd)
  163. {
  164. int ret = NONE;
  165. unsigned char *buffer = (unsigned char*)malloc(MBR_BUF_SIZE);
  166. if(get_buffer(fd, buffer, 0, 512) != 0)
  167. goto out;
  168. if((((buffer[0] & 0xff) == 0xEB) && ((buffer[2] & 0xff) == 0x90)) || ((buffer[0] & 0xff) == 0xE9))
  169. goto out;
  170. if(((buffer[510] & 0xff) == 0x55) && ((buffer[511] & 0xff) == 0xAA))
  171. ret = EXTENDED;
  172. out:
  173. free(buffer);
  174. return ret;
  175. }
  176. static dfunc funcs[] = {
  177. detect_ext23,
  178. detect_exfat,
  179. detect_fat,
  180. detect_ntfs,
  181. detect_hfsplus,
  182. detect_extended,
  183. detect_efi,
  184. detect_mbr,
  185. };
  186. int detect_fs(char *device)
  187. {
  188. int i = 0;
  189. int ret = NONE;
  190. int fd;
  191. fd = open(device, O_RDONLY);
  192. if(!fd)
  193. return NONE;
  194. while((i < 6) && (ret == NONE))
  195. ret = funcs[i++](fd);
  196. close(fd);
  197. return ret;
  198. }