Source code of Windows XP (NT5)
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.

316 lines
6.8 KiB

  1. /*
  2. Module Name:
  3. MakeScript - The "MAKE" command's built in scrips for DiskPart
  4. Abstract:
  5. Revision History
  6. */
  7. #include "DiskPart.h"
  8. #include "scripthelpmsg.h"
  9. BOOLEAN ScriptMicrosoft(CHAR16 **Token);
  10. BOOLEAN ScriptTest(CHAR16 **Token);
  11. UINT64 ComputeDefaultEspSize(EFI_HANDLE DiskHandle);
  12. //
  13. // The parse/command table
  14. //
  15. SCRIPT_ENTRY ScriptTable[] = {
  16. { SCRIPT_LIST, ScriptList, MSG_SCR_LIST },
  17. { SCRIPT_MSFT, ScriptMicrosoft, MSG_SCR_MSFT },
  18. { SCRIPT_TEST, ScriptTest, MSG_SCR_TEST },
  19. { NULL, NULL, NULL }
  20. };
  21. BOOLEAN
  22. ScriptList(
  23. CHAR16 **Token
  24. )
  25. {
  26. UINTN i;
  27. for (i = 0; ScriptTable[i].Name != NULL; i++) {
  28. Print(L"%s %s\n", ScriptTable[i].Name, ScriptTable[i].HelpSummary);
  29. }
  30. return FALSE;
  31. }
  32. BOOLEAN
  33. ScriptMicrosoft(
  34. CHAR16 **Token
  35. )
  36. /*
  37. ScriptMicrosoft - a compiled make script, invoked via MSFT
  38. make msft [boot] [size=s1] [name=n1] [ressize=s2] [espsize=s3] [espname=n2]
  39. espsize -> boot
  40. espname -> boot
  41. See help text for syntax
  42. SPECIAL NOTES:
  43. This routine just assumes there is enough space for a
  44. correct MS Reserved and EFI System partitions. This will
  45. always be true with a clean disk of any likely size.
  46. We don't test for clean though...
  47. (And adding MSRES and ESP partitions to a non-clean disk is a little weird.)
  48. */
  49. {
  50. UINTN i;
  51. BOOLEAN CreateEsp = FALSE;
  52. UINT64 EspSize = 0;
  53. UINT64 ResSize = 0;
  54. UINT64 DataSize = 0;
  55. UINT64 DefaultEsp;
  56. CHAR16 *EspName = NULL;
  57. CHAR16 *DataName = NULL;
  58. EFI_HANDLE DiskHandle;
  59. CHAR16 *WorkToken[TOKEN_COUNT_MAX];
  60. CHAR16 CommandLine[COMMAND_LINE_MAX];
  61. //
  62. // require selected disk, copy from CmdInspect
  63. //
  64. if (SelectedDisk == -1) {
  65. Print(MSG_INSPECT01);
  66. return FALSE;
  67. }
  68. Print(MSG_SELECT02, SelectedDisk);
  69. DiskHandle = DiskHandleList[SelectedDisk];
  70. //
  71. // parse
  72. //
  73. if ( (Token[1] == NULL) ||
  74. (StrCmp(Token[1], STR_HELP) == 0) )
  75. {
  76. PrintHelp(ScriptMicrosoftHelp);
  77. return FALSE;
  78. }
  79. for (i = 1; Token[i]; i++) {
  80. if (StrCmp(Token[i], STR_BOOT) == 0) {
  81. CreateEsp = TRUE;
  82. } else if (StrCmp(Token[i], STR_ESPSIZE) == 0) {
  83. if (Token[i+1] == NULL) goto ParseError;
  84. EspSize = Atoi64(Token[i+1]);
  85. CreateEsp = TRUE;
  86. i++;
  87. } else if (StrCmp(Token[i], STR_ESPNAME) == 0) {
  88. if (Token[i+1] == NULL) goto ParseError;
  89. EspName = Token[i+1];
  90. CreateEsp = TRUE;
  91. i++;
  92. } else if (StrCmp(Token[i], STR_RESSIZE) == 0) {
  93. if (Token[i+1] == NULL) goto ParseError;
  94. ResSize = Atoi64(Token[i+1]);
  95. i++;
  96. } else if (StrCmp(Token[i], STR_NAME) == 0) {
  97. if (Token[i+1] == NULL) goto ParseError;
  98. DataName = Token[i+1];
  99. i++;
  100. } else if (StrCmp(Token[i], STR_SIZE) == 0) {
  101. if (Token[i+1] == NULL) goto ParseError;
  102. DataSize = Atoi64(Token[i+1]);
  103. i++;
  104. } else {
  105. goto ParseError;
  106. }
  107. }
  108. //
  109. // Adjust EspSize (if relevent) ResSize, DataSize
  110. //
  111. if (ResSize < DEFAULT_RES_SIZE) {
  112. ResSize = DEFAULT_RES_SIZE;
  113. }
  114. DefaultEsp = ComputeDefaultEspSize(DiskHandle);
  115. if (EspSize < DefaultEsp) {
  116. EspSize = DefaultEsp;
  117. }
  118. //
  119. // Adjust names...
  120. //
  121. if (EspName == NULL) {
  122. EspName = STR_ESP_DEFAULT;
  123. }
  124. if (DataName == NULL) {
  125. DataName = STR_DATA_DEFAULT;
  126. }
  127. //
  128. // Start the create sequence. We build up a Token list
  129. // and then give it to CmdCreate to parse and execute normally...
  130. //
  131. //
  132. // The reserved partition
  133. //
  134. SPrint(
  135. CommandLine,
  136. COMMAND_LINE_MAX,
  137. L"%s %s=\"%s\" %s=%s %s=%ld",
  138. STR_CREATE,
  139. STR_NAME,
  140. STR_MSRES_NAME,
  141. STR_TYPE,
  142. STR_MSRES,
  143. STR_SIZE,
  144. ResSize
  145. );
  146. if (DebugLevel >= DEBUG_ARGPRINT) {
  147. Print(L"%s\n", CommandLine);
  148. }
  149. Tokenize(CommandLine, WorkToken);
  150. CmdCreate(WorkToken);
  151. //
  152. // The ESP
  153. //
  154. if (CreateEsp) {
  155. SPrint(
  156. CommandLine,
  157. COMMAND_LINE_MAX,
  158. L"%s %s=\"%s\" %s=%s %s=%ld",
  159. STR_CREATE,
  160. STR_NAME,
  161. EspName,
  162. STR_TYPE,
  163. STR_ESP,
  164. STR_SIZE,
  165. EspSize
  166. );
  167. if (DebugLevel >= DEBUG_ARGPRINT) {
  168. Print(L"%s\n", CommandLine);
  169. }
  170. Tokenize(CommandLine, WorkToken);
  171. CmdCreate(WorkToken);
  172. }
  173. //
  174. // MSDATA
  175. //
  176. SPrint(
  177. CommandLine,
  178. COMMAND_LINE_MAX,
  179. L"%s %s=\"%s\" %s=%s %s=%ld",
  180. STR_CREATE,
  181. STR_NAME,
  182. DataName,
  183. STR_TYPE,
  184. STR_MSDATA,
  185. STR_SIZE,
  186. DataSize
  187. );
  188. if (DebugLevel >= DEBUG_ARGPRINT) {
  189. Print(L"%s\n", CommandLine);
  190. }
  191. Tokenize(CommandLine, WorkToken);
  192. CmdCreate(WorkToken);
  193. return FALSE;
  194. ParseError:
  195. status = EFI_INVALID_PARAMETER;
  196. PrintHelp(ScriptMicrosoftHelp);
  197. return FALSE;
  198. }
  199. UINT64
  200. ComputeDefaultEspSize(
  201. EFI_HANDLE DiskHandle
  202. )
  203. /*
  204. ComputeDefaultEspSize ...
  205. Returns an answer in MEGABYTES
  206. */
  207. {
  208. UINT64 DiskSize;
  209. UINT64 DiskSizeBytes;
  210. UINT32 OnePercent;
  211. //
  212. // Note, if DiskSize is so large that 1 % is more than 4G,
  213. // OnePercent below will overflow, but it will be OK because
  214. // we'll set a MAX_ESP_SIZE in the code below
  215. //
  216. DiskSize = GetDiskSize(DiskHandle); // In Blocks
  217. OnePercent = (UINT32)(DivU64x32(DiskSize, 100, NULL)); // In Blocks
  218. DiskSizeBytes = MultU64x32(OnePercent, GetBlockSize(DiskHandle));
  219. if (DiskSizeBytes < MIN_ESP_SIZE) {
  220. DiskSizeBytes = MIN_ESP_SIZE;
  221. }
  222. if (DiskSizeBytes > MAX_ESP_SIZE) {
  223. DiskSizeBytes = MAX_ESP_SIZE;
  224. }
  225. DiskSizeBytes = RShiftU64(DiskSizeBytes, 20); // 20 bits == 1 mb
  226. return DiskSizeBytes;
  227. }
  228. CHAR16 NumStr[32];
  229. CHAR16 *TestToken[] = {
  230. L"CREATE",
  231. L"NAME",
  232. NumStr,
  233. L"TYPE",
  234. L"MSDATA",
  235. L"SIZE",
  236. L"1",
  237. NULL
  238. };
  239. BOOLEAN
  240. ScriptTest(
  241. CHAR16 **Token
  242. )
  243. {
  244. CHAR16 Buf[2];
  245. UINTN i, j;
  246. //
  247. // for this to work, a disk of > 128mb will be needed
  248. //
  249. for (i = 0; i < 128; i++) {
  250. SPrint(NumStr, 32, L"PART#%03d", i);
  251. Print(L"Token for Create = \n");
  252. for (j = 0; TestToken[j] != NULL; j++) {
  253. Print(L"'%s' ", TestToken[j]);
  254. }
  255. Print(L"\n");
  256. CmdCreate(TestToken);
  257. if (((i+1) % 4) == 0) {
  258. Input(L"MORE>", Buf, 2);
  259. Print(L"\n");
  260. }
  261. }
  262. return FALSE;
  263. }