Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

727 lines
21 KiB

4 years ago
  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. partit.c
  5. Abstract:
  6. This module contains entry points to perform the
  7. 'configure system partition' and 'create OS loader'
  8. options of the ARC installer.
  9. Author:
  10. Ted Miller (tedm) Nov-1991
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. PCHAR
  16. AlGetNextArcNamToken (
  17. IN PCHAR TokenString,
  18. OUT PCHAR OutputToken,
  19. OUT PULONG UnitNumber
  20. );
  21. #define STATUS_ROW_TOP 13
  22. #define STATUS_ROW_BOTTOM 17
  23. char NOMEMMSG[] = "Insufficient memory";
  24. char NOCNFMSG[] = "Unable to determine disk configuration (ARC status = %u)";
  25. char NOFMTMSG[] = "Format failed (ARC status = %u)";
  26. char DSKFLMSG[] = "Disk is full";
  27. char NOCREMSG[] = "Could not create partition (ARC status = %u)";
  28. char NODELMSG[] = "Could not delete partition (ARC status = %u)";
  29. char ALREAMSG[] = "Partition is already a system partition";
  30. char NOFILMSG[] = "Unable to determine filesystem on partition (ARC status = %u)";
  31. char NOENVMSG[] = "Error (ARC status = %u) determining environment";
  32. char NOEVAMSG[] = "Could not add partition to environment (ARC status = %u)";
  33. char NOEVDMSG[] = "Could not remove partition from environment (ARC status = %u)";
  34. char NOSYSMSG[] = "No system partitions defined";
  35. char NOPARMSG[] = "No partitions on this disk";
  36. char SYSPARTVAR[] = "SYSTEMPARTITION";
  37. char OSLOADERVAR[] = "OSLOADER";
  38. char OSLOADPARTVAR[] = "OSLOADPARTITION";
  39. #define MsgNoMem() AlStatusMsg(STATUS_ROW_TOP,STATUS_ROW_BOTTOM,TRUE,NOMEMMSG);
  40. PCHAR SysPartMenu[] = { "Create System Partition",
  41. "Delete Partition",
  42. "Make Existing Partition into System Partition",
  43. "Exit"
  44. };
  45. #define SYSPARTMENU_CREATE 0
  46. #define SYSPARTMENU_DELETE 1
  47. #define SYSPARTMENU_ADD 2
  48. #define SYSPARTMENU_EXIT 3
  49. #define MENU_ROW 4
  50. char sprintfBuffer[256];
  51. BOOLEAN
  52. Confirm(
  53. PCHAR Warning
  54. )
  55. {
  56. char c;
  57. ULONG Count;
  58. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  59. AlPrint("%s%s (y/n)?",MSGMARGIN,Warning);
  60. ArcRead(ARC_CONSOLE_INPUT,&c,1,&Count);
  61. while((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N') && (c != ASCI_ESC)) {
  62. ArcRead(ARC_CONSOLE_INPUT,&c,1,&Count);
  63. }
  64. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  65. return((BOOLEAN)((c == 'y') || (c == 'Y')));
  66. }
  67. VOID
  68. PrintErrorMsg(
  69. PCHAR FormatString,
  70. ...
  71. )
  72. {
  73. va_list ArgList;
  74. va_start(ArgList,FormatString);
  75. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  76. vAlStatusMsg(STATUS_ROW_TOP,TRUE,FormatString,ArgList);
  77. AlWaitKey(NULL);
  78. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  79. }
  80. VOID
  81. PrintMsg(
  82. PCHAR FormatString,
  83. ...
  84. )
  85. {
  86. va_list ArgList;
  87. va_start(ArgList,FormatString);
  88. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  89. vAlStatusMsg(STATUS_ROW_TOP,FALSE,FormatString,ArgList);
  90. AlWaitKey(NULL);
  91. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  92. }
  93. BOOLEAN
  94. IsBootSelectionPartition(
  95. PCHAR Variable,
  96. ULONG Disk,
  97. ULONG Partition,
  98. PULONG MatchNumber OPTIONAL
  99. )
  100. {
  101. char text[256];
  102. PCHAR Var = ArcGetEnvironmentVariable(Variable);
  103. if (Var == NULL) {
  104. return(FALSE);
  105. }
  106. sprintf(text,"%spartition(%u)",GetDiskName(Disk),Partition);
  107. return(AlFindNextMatchComponent(Var,text,0,MatchNumber));
  108. }
  109. LONG
  110. ChooseDisk(
  111. VOID
  112. )
  113. {
  114. ULONG DiskCount = GetDiskCount();
  115. PVOID MenuID;
  116. LONG Disk;
  117. ULONG ChosenDisk;
  118. PCHAR DiskName,TempDiskName;
  119. ULONG UnitNumber,ScsiNumber,ScsiId,DiskNumber;
  120. CHAR Token[32];
  121. if (DiskCount == 1) {
  122. return(0);
  123. }
  124. if (!AlNewMenu(&MenuID)) {
  125. MsgNoMem();
  126. return(-1);
  127. }
  128. for(Disk = DiskCount - 1; Disk >= 0; Disk--) {
  129. DiskName = GetDiskName(Disk);
  130. if ((strstr(DiskName, "scsi") != NULL) &&
  131. (strstr(DiskName, "disk") != NULL) ) {
  132. ScsiNumber = ScsiId = DiskNumber = 0;
  133. TempDiskName = DiskName;
  134. while (TempDiskName != NULL) {
  135. TempDiskName = AlGetNextArcNamToken(TempDiskName,
  136. Token,
  137. &UnitNumber);
  138. if (strcmp(Token,"scsi") == 0) {
  139. ScsiNumber = UnitNumber;
  140. }
  141. if (strcmp(Token,"disk") == 0) {
  142. ScsiId = UnitNumber;
  143. }
  144. if (strcmp(Token,"rdisk") == 0) {
  145. DiskNumber = UnitNumber;
  146. }
  147. }
  148. sprintf(sprintfBuffer,
  149. "Scsi bus %d, Identifier %d, Disk %d (%s)",
  150. ScsiNumber,
  151. ScsiId,
  152. DiskNumber,
  153. GetDiskName(Disk));
  154. } else {
  155. sprintf(sprintfBuffer,"Disk %d (%s)",Disk,GetDiskName(Disk));
  156. }
  157. if (!AlAddMenuItem(MenuID,sprintfBuffer,Disk,0)) {
  158. MsgNoMem();
  159. return(-1);
  160. }
  161. }
  162. if (!AlDisplayMenu(MenuID,FALSE,0,&ChosenDisk,MENU_ROW,"Select Disk")) {
  163. return(-1);
  164. } else {
  165. return(ChosenDisk);
  166. }
  167. }
  168. BOOLEAN // true if partition was created
  169. DoPartitionCreate(
  170. OUT PULONG DiskNo,
  171. OUT PULONG PartitionNo
  172. )
  173. {
  174. ULONG Disk,i;
  175. PREGION_DESCRIPTOR Regions;
  176. ULONG RegionCount,Choice;
  177. ULONG ChosenSize;
  178. ARC_STATUS status;
  179. BOOLEAN xAny,xP,xE,xL,PrimaryExists;
  180. PVOID MenuID;
  181. ULONG PartitionNumber;
  182. char PartitionPath[256];
  183. if ((Disk = ChooseDisk()) == -1) {
  184. return(FALSE);
  185. }
  186. if ((status = DoesAnyPrimaryExist(Disk,&PrimaryExists)) != ESUCCESS) {
  187. PrintErrorMsg(NOCNFMSG,status);
  188. return(FALSE);
  189. }
  190. if ((status = IsAnyCreationAllowed(Disk,
  191. TRUE,
  192. &xAny,
  193. &xP,
  194. &xE,
  195. &xL
  196. )
  197. )
  198. != ESUCCESS)
  199. {
  200. PrintErrorMsg(NOCNFMSG,status);
  201. return(FALSE);
  202. }
  203. // in order for a creation to be allowed there must be
  204. // - free space on the disk and a free mbr entry OR
  205. // - free space in an existing extended partition.
  206. if (!xAny) {
  207. PrintErrorMsg(DSKFLMSG);
  208. return(FALSE);
  209. }
  210. if ((status = GetFreeDiskRegions(Disk,&Regions,&RegionCount)) != ESUCCESS) {
  211. PrintErrorMsg(NOCNFMSG,status);
  212. return(FALSE);
  213. }
  214. if (!AlNewMenu(&MenuID)) {
  215. MsgNoMem();
  216. FreeRegionArray(Regions,RegionCount);
  217. return(FALSE);
  218. }
  219. // Present the user with a list of the free spaces
  220. // on the disk (and within the extended partition, if it
  221. // exists).
  222. if (RegionCount > 1) {
  223. for(i=0; i<RegionCount; i++) {
  224. sprintf(sprintfBuffer,"%u MB space",Regions[i].SizeMB);
  225. if (Regions[i].RegionType == REGION_LOGICAL) {
  226. strcat(sprintfBuffer," (in extended partition)");
  227. }
  228. if (!AlAddMenuItem(MenuID,sprintfBuffer,i,0)) {
  229. MsgNoMem();
  230. AlFreeMenu(MenuID);
  231. FreeRegionArray(Regions,RegionCount);
  232. return(FALSE);
  233. }
  234. }
  235. if (!AlDisplayMenu(MenuID,FALSE,0,&Choice,MENU_ROW,"Available Free Spaces")) {
  236. // user escaped
  237. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  238. AlFreeMenu(MenuID);
  239. FreeRegionArray(Regions,RegionCount);
  240. return(FALSE);
  241. }
  242. } else {
  243. Choice = 0;
  244. }
  245. AlFreeMenu(MenuID);
  246. // now ask the user for the size of the partition to create in the chosen space.
  247. do {
  248. AlClearStatusArea(STATUS_ROW_TOP,STATUS_ROW_BOTTOM);
  249. AlPrint("%sEnter size in MB (1-%u): ",MSGMARGIN,Regions[Choice].SizeMB);
  250. if (!AlGetString(sprintfBuffer,sizeof(sprintfBuffer))) {
  251. FreeRegionArray(Regions,RegionCount);
  252. return(FALSE);
  253. }
  254. ChosenSize = atoi(sprintfBuffer);
  255. if (!ChosenSize || (ChosenSize > Regions[Choice].SizeMB)) {
  256. PrintErrorMsg("Invalid size.");
  257. } else {
  258. break;
  259. }
  260. } while(1);
  261. // The chosen space is either in the extended partition or not.
  262. // If it is, just create the requested partition.
  263. if (Regions[Choice].RegionType == REGION_LOGICAL) {
  264. status = CreatePartition(&Regions[Choice],ChosenSize,REGION_LOGICAL);
  265. PartitionNumber = Regions[Choice].PartitionNumber;
  266. } else {
  267. // The chosen space is not in an extended partition.
  268. // If there's already a primary and we can create
  269. // an extended partition, then first create an
  270. // extended partition spanning the entire space chosen
  271. // by the user, and then a logical volume within it of
  272. // size entered by the user. Otherwise [ie, there's no primary
  273. // or we're not allowed to create an extended partition]
  274. // create a primary of the size entered by the user.
  275. if (PrimaryExists && xE) {
  276. // create extended partition first.
  277. status = CreatePartition(&Regions[Choice],Regions[Choice].SizeMB,REGION_EXTENDED);
  278. FreeRegionArray(Regions,RegionCount);
  279. if ((status = GetFreeLogicalDiskRegions(Disk,&Regions,&RegionCount)) != ESUCCESS) {
  280. PrintErrorMsg(NOCNFMSG,status);
  281. return(FALSE);
  282. }
  283. // since we just created the extended partition, there will be one free
  284. // region in it.
  285. status = CreatePartition(Regions,ChosenSize,REGION_LOGICAL);
  286. PartitionNumber = Regions[0].PartitionNumber;
  287. } else {
  288. status = CreatePartition(&Regions[Choice],ChosenSize,REGION_PRIMARY);
  289. PartitionNumber = Regions[Choice].PartitionNumber;
  290. }
  291. }
  292. FreeRegionArray(Regions,RegionCount);
  293. if ( (status == ESUCCESS)
  294. && ((status = CommitPartitionChanges(Disk)) == ESUCCESS))
  295. {
  296. PrintMsg("Partition successfully created.");
  297. #if 0
  298. //
  299. // This is bogus since this routine is called in the code path where
  300. // the user is creating a system partition.
  301. //
  302. if (ArcGetEnvironmentVariable(SYSPARTVAR) == NULL) {
  303. if (Confirm("Do you want to make this the system partition")) {
  304. sprintf(PartitionPath,"%spartition(%u)",GetDiskName(Disk),PartitionNumber);
  305. if ((status = ArcSetEnvironmentVariable(SYSPARTVAR,PartitionPath)) != ESUCCESS) {
  306. PrintErrorMsg(NOEVAMSG,status);
  307. }
  308. }
  309. }
  310. #endif
  311. *DiskNo = Disk;
  312. *PartitionNo = PartitionNumber;
  313. return(TRUE);
  314. } else {
  315. PrintErrorMsg(NOCREMSG,status);
  316. return(FALSE);
  317. }
  318. }
  319. VOID
  320. DoPartitionDelete(
  321. VOID
  322. )
  323. {
  324. BOOLEAN xAny,xPrimary,xExtended,xLogical;
  325. ARC_STATUS status;
  326. PVOID MenuID;
  327. ULONG i,RegionCount,Choice;
  328. ULONG MatchNumber,Index;
  329. LONG Disk;
  330. PREGION_DESCRIPTOR Regions;
  331. BOOLEAN err,Confirmation;
  332. if ((Disk = ChooseDisk()) == -1) {
  333. return;
  334. }
  335. if ((status = DoesAnyPartitionExist(Disk,&xAny,&xPrimary,&xExtended,&xLogical)) != ESUCCESS) {
  336. PrintErrorMsg(NOCNFMSG,status);
  337. return;
  338. }
  339. if (xAny) {
  340. if (!AlNewMenu(&MenuID)) {
  341. MsgNoMem();
  342. return;
  343. }
  344. if ((status = GetUsedDiskRegions(Disk,&Regions,&RegionCount)) != ESUCCESS) {
  345. PrintErrorMsg(NOCNFMSG,status);
  346. } else {
  347. err = FALSE;
  348. for(i=0; i<RegionCount; i++) {
  349. sprintf(sprintfBuffer,"%s%u MB ",Regions[i].RegionType == REGION_LOGICAL ? " " : "",Regions[i].SizeMB);
  350. strcat(sprintfBuffer,GetSysIDName(Regions[i].SysID));
  351. strcat(sprintfBuffer,Regions[i].RegionType == REGION_LOGICAL ? " Logical Volume" : " Partition");
  352. if (IsExtended(Regions[i].SysID) && xLogical) {
  353. strcat(sprintfBuffer,", also resulting in the deletion of:");
  354. }
  355. if (!AlAddMenuItem(MenuID,sprintfBuffer,i,0)) {
  356. MsgNoMem();
  357. err = TRUE;
  358. break;
  359. }
  360. }
  361. if (!err) {
  362. if (AlDisplayMenu(MenuID,FALSE,0,&Choice,MENU_ROW,"Select Partition to Delete")) {
  363. if (IsBootSelectionPartition(SYSPARTVAR,Disk,Regions[Choice].PartitionNumber,NULL)) {
  364. Confirmation = Confirm("The selected partition is (or contains) a system partition.\r\n Are you sure you want to delete it");
  365. } else {
  366. if (IsBootSelectionPartition(OSLOADPARTVAR,Disk,Regions[Choice].PartitionNumber,NULL)) {
  367. Confirmation = Confirm("The selected partition contains an operating system.\r\n Are you sure you want to delete it");
  368. } else {
  369. Confirmation = Confirm("Are you sure");
  370. }
  371. }
  372. if (Confirmation) {
  373. if (((status = DeletePartition(&Regions[Choice])) != ESUCCESS)
  374. || ((status = CommitPartitionChanges(Disk)) != ESUCCESS))
  375. {
  376. PrintErrorMsg(NODELMSG,status);
  377. } else {
  378. PrintMsg("Partition deleted successfully.");
  379. sprintf(sprintfBuffer,
  380. "%spartition(%u)",
  381. GetDiskName(Disk),
  382. Regions[Choice].PartitionNumber
  383. );
  384. //
  385. // If there are any boot selections and the deleted partition
  386. // was used, ask if the associated boot selections should be
  387. // deleted.
  388. //
  389. if (ArcGetEnvironmentVariable(OSLOADPARTVAR) != NULL) {
  390. if ((IsBootSelectionPartition(SYSPARTVAR,Disk,Regions[Choice].PartitionNumber,NULL) ||
  391. IsBootSelectionPartition(OSLOADPARTVAR,Disk,Regions[Choice].PartitionNumber,NULL)) &&
  392. Confirm("Do you want to delete the boot selection(s) associated\r\n with the deleted partition?")) {
  393. while (IsBootSelectionPartition(SYSPARTVAR,Disk,Regions[Choice].PartitionNumber,&MatchNumber)) {
  394. for ( Index = 0 ; Index < MaximumBootVariable ; Index++ ) {
  395. JzDeleteVariableSegment(BootString[Index],MatchNumber);
  396. }
  397. }
  398. while (IsBootSelectionPartition(OSLOADPARTVAR,Disk,Regions[Choice].PartitionNumber,&MatchNumber)) {
  399. for ( Index = 0 ; Index < MaximumBootVariable ; Index++ ) {
  400. JzDeleteVariableSegment(BootString[Index],MatchNumber);
  401. }
  402. }
  403. }
  404. } else {
  405. //
  406. // There are no boot selections but delete all segments
  407. // of the SystemPartition variable that pointed to the
  408. // deleted partition.
  409. //
  410. while (IsBootSelectionPartition(SYSPARTVAR,Disk,Regions[Choice].PartitionNumber,&MatchNumber)) {
  411. JzDeleteVariableSegment(BootString[SystemPartitionVariable],MatchNumber);
  412. }
  413. }
  414. }
  415. }
  416. }
  417. }
  418. FreeRegionArray(Regions,RegionCount);
  419. }
  420. AlFreeMenu(MenuID);
  421. } else {
  422. PrintErrorMsg("No partitions on this disk");
  423. }
  424. }
  425. VOID
  426. DoSystemPartitionCreate(
  427. VOID
  428. )
  429. {
  430. ULONG DiskNo,PartitionNo;
  431. ARC_STATUS status;
  432. if (DoPartitionCreate(&DiskNo,&PartitionNo)) {
  433. sprintf(sprintfBuffer,"%spartition(%u)",GetDiskName(DiskNo),PartitionNo);
  434. // add the partition to the SYSTEMPARTITION NVRAM environment variable
  435. if ((status = AlAddSystemPartition(sprintfBuffer)) != ESUCCESS) {
  436. PrintErrorMsg(NOEVAMSG,status);
  437. return;
  438. }
  439. AlStatusMsgNoWait(STATUS_ROW_TOP,STATUS_ROW_BOTTOM,FALSE,"Formatting %s",sprintfBuffer);
  440. status = FmtFatFormat(sprintfBuffer,GetHiddenSectorCount(DiskNo,PartitionNo));
  441. if (status == ESUCCESS) {
  442. SetSysID(DiskNo,PartitionNo,SYSID_BIGFAT);
  443. PrintMsg("Partition formatted successfully.");
  444. } else {
  445. PrintErrorMsg(NOFMTMSG,status);
  446. }
  447. }
  448. }
  449. VOID
  450. DoMakePartitionSystemPartition(
  451. VOID
  452. )
  453. {
  454. BOOLEAN f,IsFAT;
  455. ULONG Disk,i,Choice;
  456. PVOID MenuID;
  457. PREGION_DESCRIPTOR Regions;
  458. ULONG RegionCount;
  459. ARC_STATUS status;
  460. char PartitionPath[256];
  461. ULONG PartitionNumber;
  462. // take an existing partition and add it to the
  463. // list of system partitions. Also make sure it's
  464. // formatted as FAT.
  465. if ((Disk = ChooseDisk()) == -1) {
  466. return;
  467. }
  468. status = GetUsedDiskRegions(Disk,&Regions,&RegionCount);
  469. if (status != ESUCCESS) {
  470. PrintErrorMsg(NOCNFMSG,status);
  471. return;
  472. }
  473. if (!RegionCount) {
  474. FreeRegionArray(Regions,RegionCount);
  475. PrintErrorMsg(NOPARMSG);
  476. return;
  477. }
  478. if (!AlNewMenu(&MenuID)) {
  479. FreeRegionArray(Regions,RegionCount);
  480. MsgNoMem();
  481. return;
  482. }
  483. for(i=0; i<RegionCount; i++) {
  484. if (!IsExtended(Regions[i].SysID)) {
  485. sprintf(sprintfBuffer,
  486. "Partition %u (%u MB %s)",
  487. Regions[i].PartitionNumber,
  488. Regions[i].SizeMB,
  489. GetSysIDName(Regions[i].SysID)
  490. );
  491. if (!AlAddMenuItem(MenuID,sprintfBuffer,i,0)) {
  492. MsgNoMem();
  493. AlFreeMenu(MenuID);
  494. FreeRegionArray(Regions,RegionCount);
  495. return;
  496. }
  497. }
  498. }
  499. f = AlDisplayMenu(MenuID,FALSE,0,&Choice,MENU_ROW,"Choose Partition");
  500. AlFreeMenu(MenuID);
  501. if (!f) { // user escaped
  502. FreeRegionArray(Regions,RegionCount);
  503. return;
  504. }
  505. PartitionNumber = Regions[Choice].PartitionNumber;
  506. sprintf(PartitionPath,"%spartition(%u)",GetDiskName(Disk),PartitionNumber);
  507. FreeRegionArray(Regions,RegionCount);
  508. if(IsBootSelectionPartition(SYSPARTVAR,Disk,PartitionNumber,NULL)) {
  509. PrintErrorMsg(ALREAMSG);
  510. return;
  511. }
  512. status = FmtIsFat(PartitionPath,&IsFAT);
  513. if (status != ESUCCESS) {
  514. PrintErrorMsg(NOFILMSG,status);
  515. return;
  516. }
  517. if (!IsFAT) {
  518. if (Confirm("System partitions must be formatted with the FAT filesystem.\r\n Do you wish to format the chosen partition")
  519. && Confirm("All existing data will be lost. Are you sure"))
  520. {
  521. status = FmtFatFormat(PartitionPath,GetHiddenSectorCount(Disk,PartitionNumber));
  522. if (status != ESUCCESS) {
  523. PrintErrorMsg(NOFMTMSG,status);
  524. return;
  525. }
  526. SetSysID(Disk,PartitionNumber,SYSID_BIGFAT);
  527. } else {
  528. return;
  529. }
  530. }
  531. //
  532. // Add to list of system partitions.
  533. //
  534. if ((status = AlAddSystemPartition(PartitionPath)) == ESUCCESS) {
  535. PrintMsg("Partition added successfully.");
  536. } else {
  537. PrintErrorMsg(NOEVAMSG,status);
  538. }
  539. }
  540. VOID
  541. ConfigureSystemPartitions(
  542. VOID
  543. )
  544. {
  545. ULONG Choice=0,DiskCount=GetDiskCount();
  546. PVOID MenuID;
  547. if (!AlNewMenu(&MenuID)) {
  548. MsgNoMem();
  549. return;
  550. }
  551. if (!AlAddMenuItems(MenuID,SysPartMenu,sizeof(SysPartMenu)/sizeof(PCHAR))) {
  552. MsgNoMem();
  553. AlFreeMenu(MenuID);
  554. return;
  555. }
  556. while(1) {
  557. if ((!AlDisplayMenu(MenuID,FALSE,Choice,&Choice,MENU_ROW,"Configure System Partitions"))
  558. || (Choice == SYSPARTMENU_EXIT))
  559. {
  560. break;
  561. }
  562. switch(Choice) {
  563. case SYSPARTMENU_CREATE:
  564. // create system partition.
  565. DoSystemPartitionCreate();
  566. break;
  567. case SYSPARTMENU_DELETE:
  568. // delete partition
  569. DoPartitionDelete();
  570. break;
  571. case SYSPARTMENU_ADD:
  572. // make existing into a system partition
  573. DoMakePartitionSystemPartition();
  574. break;
  575. }
  576. }
  577. AlFreeMenu(MenuID);
  578. }