part.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*++
  2. Copyright (c) 2016 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. part.c
  9. Abstract:
  10. This module implements partition support for the setup app on Minoca OS.
  11. Author:
  12. Evan Green 19-Jan-2016
  13. Environment:
  14. User
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include <assert.h>
  20. #include <errno.h>
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <sys/types.h>
  25. #include <time.h>
  26. #include "../setup.h"
  27. //
  28. // ---------------------------------------------------------------- Definitions
  29. //
  30. //
  31. // ------------------------------------------------------ Data Type Definitions
  32. //
  33. typedef struct _DISK_MAX_PARTITIONS {
  34. INT Major;
  35. INT Partitions;
  36. } DISK_MAX_PARTITIONS, *PDISK_MAX_PARTITIONS;
  37. //
  38. // ----------------------------------------------- Internal Function Prototypes
  39. //
  40. //
  41. // -------------------------------------------------------------------- Globals
  42. //
  43. //
  44. // For each of the defined Linux major numbers, define the maximum number of
  45. // partitions for that major number.
  46. //
  47. DISK_MAX_PARTITIONS SetupLinuxMaxPartitions[] = {
  48. {3, 64},
  49. {8, 16},
  50. {21, 64},
  51. {22, 64},
  52. {28, 16},
  53. {33, 64},
  54. {34, 64},
  55. {44, 16},
  56. {45, 16},
  57. {48, 8},
  58. {49, 8},
  59. {50, 8},
  60. {51, 8},
  61. {52, 8},
  62. {53, 8},
  63. {54, 8},
  64. {55, 8},
  65. {56, 64},
  66. {57, 64},
  67. {65, 16},
  68. {66, 16},
  69. {67, 16},
  70. {68, 16},
  71. {69, 16},
  72. {70, 16},
  73. {71, 16},
  74. {72, 16},
  75. {73, 16},
  76. {74, 16},
  77. {75, 16},
  78. {76, 16},
  79. {77, 16},
  80. {78, 16},
  81. {79, 16},
  82. {80, 16},
  83. {81, 16},
  84. {82, 16},
  85. {83, 16},
  86. {84, 16},
  87. {85, 16},
  88. {86, 16},
  89. {87, 16},
  90. {88, 64},
  91. {89, 64},
  92. {90, 64},
  93. {91, 64},
  94. {98, 16},
  95. {101, 16},
  96. {102, 16},
  97. {104, 16},
  98. {105, 16},
  99. {106, 16},
  100. {107, 16},
  101. {108, 16},
  102. {109, 16},
  103. {110, 16},
  104. {111, 16},
  105. {114, 16},
  106. {116, 16},
  107. {128, 16},
  108. {129, 16},
  109. {130, 16},
  110. {131, 16},
  111. {132, 16},
  112. {133, 16},
  113. {134, 16},
  114. {135, 16},
  115. {136, 8},
  116. {137, 8},
  117. {138, 8},
  118. {139, 8},
  119. {140, 8},
  120. {141, 8},
  121. {142, 8},
  122. {143, 8},
  123. {153, 16},
  124. {160, 32},
  125. {161, 32},
  126. {179, 8},
  127. {202, 16},
  128. {0, 0}
  129. };
  130. //
  131. // ------------------------------------------------------------------ Functions
  132. //
  133. INT
  134. SetupOsEnumerateDevices (
  135. PSETUP_PARTITION_DESCRIPTION *DeviceArray,
  136. PULONG DeviceCount
  137. )
  138. /*++
  139. Routine Description:
  140. This routine enumerates all the disks and partitions on the system.
  141. Arguments:
  142. DeviceArray - Supplies a pointer where an array of partition structures
  143. will be returned on success.
  144. DeviceCount - Supplies a pointer where the number of elements in the
  145. partition array will be returned on success.
  146. Return Value:
  147. 0 on success.
  148. Returns an error code on failure.
  149. --*/
  150. {
  151. LONGLONG Blocks;
  152. int Count;
  153. PSETUP_PARTITION_DESCRIPTION Description;
  154. SETUP_DESTINATION_TYPE DestinationType;
  155. CHAR Device[256];
  156. FILE *File;
  157. INTN Index;
  158. CHAR Line[256];
  159. int Major;
  160. PDISK_MAX_PARTITIONS MaxPartitions;
  161. int Minor;
  162. PVOID NewBuffer;
  163. CHAR Path[256];
  164. INTN ResultCapacity;
  165. INTN ResultCount;
  166. PSETUP_PARTITION_DESCRIPTION Results;
  167. INT Status;
  168. ResultCapacity = 0;
  169. ResultCount = 0;
  170. Results = NULL;
  171. File = fopen("/proc/partitions", "r");
  172. if (File == NULL) {
  173. Status = errno;
  174. fprintf(stderr,
  175. "Error: Failed to open /proc/partitions: %s.\n",
  176. strerror(Status));
  177. goto OsEnumerateDevicesEnd;
  178. }
  179. //
  180. // Skip the first line, which has the legend.
  181. //
  182. if (fgets(Line, sizeof(Line), File) == NULL) {
  183. Status = errno;
  184. goto OsEnumerateDevicesEnd;
  185. }
  186. //
  187. // Loop reading all the lines.
  188. //
  189. while (fgets(Line, sizeof(Line), File) != NULL) {
  190. if (Line[0] == '\n') {
  191. continue;
  192. }
  193. Line[sizeof(Line) - 1] = '\0';
  194. Count = sscanf(Line, "%d %d %lld %s", &Major, &Minor, &Blocks, Device);
  195. if (Count != 4) {
  196. fprintf(stderr,
  197. "Warning: Only scanned %d items in /proc/partitions.\n",
  198. Count);
  199. continue;
  200. }
  201. if (ResultCount >= ResultCapacity) {
  202. if (ResultCapacity == 0) {
  203. ResultCapacity = 16;
  204. } else {
  205. ResultCapacity *= 2;
  206. }
  207. NewBuffer = realloc(
  208. Results,
  209. ResultCapacity * sizeof(SETUP_PARTITION_DESCRIPTION));
  210. if (NewBuffer == NULL) {
  211. Status = errno;
  212. goto OsEnumerateDevicesEnd;
  213. }
  214. Results = NewBuffer;
  215. }
  216. Description = &(Results[ResultCount]);
  217. memset(Description, 0, sizeof(SETUP_PARTITION_DESCRIPTION));
  218. Status = snprintf(Path, sizeof(Path), "/dev/%s", Device);
  219. if (Status < 0) {
  220. Status = EINVAL;
  221. goto OsEnumerateDevicesEnd;
  222. }
  223. //
  224. // Figure out if this thing is a partition or a disk. If no entry is
  225. // found in the table, assume it's a disk.
  226. //
  227. DestinationType = SetupDestinationDisk;
  228. MaxPartitions = SetupLinuxMaxPartitions;
  229. while (MaxPartitions->Major != 0) {
  230. if (MaxPartitions->Major == Major) {
  231. if ((Minor % MaxPartitions->Partitions) != 0) {
  232. DestinationType = SetupDestinationPartition;
  233. Description->Partition.Number =
  234. Minor % MaxPartitions->Partitions;
  235. }
  236. break;
  237. }
  238. MaxPartitions += 1;
  239. }
  240. Description->Destination = SetupCreateDestination(DestinationType,
  241. Path,
  242. 0);
  243. if (Description->Destination == NULL) {
  244. Status = ENOMEM;
  245. goto OsEnumerateDevicesEnd;
  246. }
  247. Description->Partition.Version = PARTITION_DEVICE_INFORMATION_VERSION;
  248. //
  249. // Set the block size to 512. /proc/partitions reports things in 1k
  250. // blocks.
  251. //
  252. Description->Partition.BlockSize = 512;
  253. Description->Partition.LastBlock = (Blocks * 2) - 1;
  254. Description->Partition.PartitionType = PartitionTypeUnknown;
  255. if (DestinationType == SetupDestinationDisk) {
  256. Description->Partition.Flags |= PARTITION_FLAG_RAW_DISK;
  257. }
  258. ResultCount += 1;
  259. }
  260. if (ferror(File) != 0) {
  261. Status = errno;
  262. } else {
  263. Status = 0;
  264. }
  265. OsEnumerateDevicesEnd:
  266. if (File != NULL) {
  267. fclose(File);
  268. }
  269. if (Status != 0) {
  270. if (Results != NULL) {
  271. for (Index = 0; Index < ResultCount; Index += 1) {
  272. if (Results[Index].Destination != NULL) {
  273. SetupDestroyDestination(Results[Index].Destination);
  274. }
  275. }
  276. free(Results);
  277. Results = NULL;
  278. }
  279. ResultCount = 0;
  280. }
  281. *DeviceArray = Results;
  282. *DeviceCount = ResultCount;
  283. return Status;
  284. }
  285. INT
  286. SetupOsGetPartitionInformation (
  287. PSETUP_DESTINATION Destination,
  288. PPARTITION_DEVICE_INFORMATION Information
  289. )
  290. /*++
  291. Routine Description:
  292. This routine returns the partition information for the given destination.
  293. Arguments:
  294. Destination - Supplies a pointer to the partition to query.
  295. Information - Supplies a pointer where the information will be returned
  296. on success.
  297. Return Value:
  298. 0 on success.
  299. Returns an error code on failure.
  300. --*/
  301. {
  302. fprintf(stderr,
  303. "Partition information not currently implemented on this OS.\n");
  304. return ENOSYS;
  305. }
  306. PVOID
  307. SetupOsOpenBootVolume (
  308. PSETUP_CONTEXT Context
  309. )
  310. /*++
  311. Routine Description:
  312. This routine opens the boot volume on the current machine.
  313. Arguments:
  314. Context - Supplies a pointer to the application context.
  315. Return Value:
  316. Returns the open handle to the boot volume on success.
  317. NULL on failure.
  318. --*/
  319. {
  320. errno = ENOSYS;
  321. return NULL;
  322. }
  323. //
  324. // --------------------------------------------------------- Internal Functions
  325. //