windows-nt/Source/XPSP1/NT/base/efiutil/diskpart/makescript.c
2020-09-26 16:20:57 +08:00

317 lines
6.8 KiB
C

/*
Module Name:
MakeScript - The "MAKE" command's built in scrips for DiskPart
Abstract:
Revision History
*/
#include "DiskPart.h"
#include "scripthelpmsg.h"
BOOLEAN ScriptMicrosoft(CHAR16 **Token);
BOOLEAN ScriptTest(CHAR16 **Token);
UINT64 ComputeDefaultEspSize(EFI_HANDLE DiskHandle);
//
// The parse/command table
//
SCRIPT_ENTRY ScriptTable[] = {
{ SCRIPT_LIST, ScriptList, MSG_SCR_LIST },
{ SCRIPT_MSFT, ScriptMicrosoft, MSG_SCR_MSFT },
{ SCRIPT_TEST, ScriptTest, MSG_SCR_TEST },
{ NULL, NULL, NULL }
};
BOOLEAN
ScriptList(
CHAR16 **Token
)
{
UINTN i;
for (i = 0; ScriptTable[i].Name != NULL; i++) {
Print(L"%s %s\n", ScriptTable[i].Name, ScriptTable[i].HelpSummary);
}
return FALSE;
}
BOOLEAN
ScriptMicrosoft(
CHAR16 **Token
)
/*
ScriptMicrosoft - a compiled make script, invoked via MSFT
make msft [boot] [size=s1] [name=n1] [ressize=s2] [espsize=s3] [espname=n2]
espsize -> boot
espname -> boot
See help text for syntax
SPECIAL NOTES:
This routine just assumes there is enough space for a
correct MS Reserved and EFI System partitions. This will
always be true with a clean disk of any likely size.
We don't test for clean though...
(And adding MSRES and ESP partitions to a non-clean disk is a little weird.)
*/
{
UINTN i;
BOOLEAN CreateEsp = FALSE;
UINT64 EspSize = 0;
UINT64 ResSize = 0;
UINT64 DataSize = 0;
UINT64 DefaultEsp;
CHAR16 *EspName = NULL;
CHAR16 *DataName = NULL;
EFI_HANDLE DiskHandle;
CHAR16 *WorkToken[TOKEN_COUNT_MAX];
CHAR16 CommandLine[COMMAND_LINE_MAX];
//
// require selected disk, copy from CmdInspect
//
if (SelectedDisk == -1) {
Print(MSG_INSPECT01);
return FALSE;
}
Print(MSG_SELECT02, SelectedDisk);
DiskHandle = DiskHandleList[SelectedDisk];
//
// parse
//
if ( (Token[1] == NULL) ||
(StrCmp(Token[1], STR_HELP) == 0) )
{
PrintHelp(ScriptMicrosoftHelp);
return FALSE;
}
for (i = 1; Token[i]; i++) {
if (StrCmp(Token[i], STR_BOOT) == 0) {
CreateEsp = TRUE;
} else if (StrCmp(Token[i], STR_ESPSIZE) == 0) {
if (Token[i+1] == NULL) goto ParseError;
EspSize = Atoi64(Token[i+1]);
CreateEsp = TRUE;
i++;
} else if (StrCmp(Token[i], STR_ESPNAME) == 0) {
if (Token[i+1] == NULL) goto ParseError;
EspName = Token[i+1];
CreateEsp = TRUE;
i++;
} else if (StrCmp(Token[i], STR_RESSIZE) == 0) {
if (Token[i+1] == NULL) goto ParseError;
ResSize = Atoi64(Token[i+1]);
i++;
} else if (StrCmp(Token[i], STR_NAME) == 0) {
if (Token[i+1] == NULL) goto ParseError;
DataName = Token[i+1];
i++;
} else if (StrCmp(Token[i], STR_SIZE) == 0) {
if (Token[i+1] == NULL) goto ParseError;
DataSize = Atoi64(Token[i+1]);
i++;
} else {
goto ParseError;
}
}
//
// Adjust EspSize (if relevent) ResSize, DataSize
//
if (ResSize < DEFAULT_RES_SIZE) {
ResSize = DEFAULT_RES_SIZE;
}
DefaultEsp = ComputeDefaultEspSize(DiskHandle);
if (EspSize < DefaultEsp) {
EspSize = DefaultEsp;
}
//
// Adjust names...
//
if (EspName == NULL) {
EspName = STR_ESP_DEFAULT;
}
if (DataName == NULL) {
DataName = STR_DATA_DEFAULT;
}
//
// Start the create sequence. We build up a Token list
// and then give it to CmdCreate to parse and execute normally...
//
//
// The reserved partition
//
SPrint(
CommandLine,
COMMAND_LINE_MAX,
L"%s %s=\"%s\" %s=%s %s=%ld",
STR_CREATE,
STR_NAME,
STR_MSRES_NAME,
STR_TYPE,
STR_MSRES,
STR_SIZE,
ResSize
);
if (DebugLevel >= DEBUG_ARGPRINT) {
Print(L"%s\n", CommandLine);
}
Tokenize(CommandLine, WorkToken);
CmdCreate(WorkToken);
//
// The ESP
//
if (CreateEsp) {
SPrint(
CommandLine,
COMMAND_LINE_MAX,
L"%s %s=\"%s\" %s=%s %s=%ld",
STR_CREATE,
STR_NAME,
EspName,
STR_TYPE,
STR_ESP,
STR_SIZE,
EspSize
);
if (DebugLevel >= DEBUG_ARGPRINT) {
Print(L"%s\n", CommandLine);
}
Tokenize(CommandLine, WorkToken);
CmdCreate(WorkToken);
}
//
// MSDATA
//
SPrint(
CommandLine,
COMMAND_LINE_MAX,
L"%s %s=\"%s\" %s=%s %s=%ld",
STR_CREATE,
STR_NAME,
DataName,
STR_TYPE,
STR_MSDATA,
STR_SIZE,
DataSize
);
if (DebugLevel >= DEBUG_ARGPRINT) {
Print(L"%s\n", CommandLine);
}
Tokenize(CommandLine, WorkToken);
CmdCreate(WorkToken);
return FALSE;
ParseError:
status = EFI_INVALID_PARAMETER;
PrintHelp(ScriptMicrosoftHelp);
return FALSE;
}
UINT64
ComputeDefaultEspSize(
EFI_HANDLE DiskHandle
)
/*
ComputeDefaultEspSize ...
Returns an answer in MEGABYTES
*/
{
UINT64 DiskSize;
UINT64 DiskSizeBytes;
UINT32 OnePercent;
//
// Note, if DiskSize is so large that 1 % is more than 4G,
// OnePercent below will overflow, but it will be OK because
// we'll set a MAX_ESP_SIZE in the code below
//
DiskSize = GetDiskSize(DiskHandle); // In Blocks
OnePercent = (UINT32)(DivU64x32(DiskSize, 100, NULL)); // In Blocks
DiskSizeBytes = MultU64x32(OnePercent, GetBlockSize(DiskHandle));
if (DiskSizeBytes < MIN_ESP_SIZE) {
DiskSizeBytes = MIN_ESP_SIZE;
}
if (DiskSizeBytes > MAX_ESP_SIZE) {
DiskSizeBytes = MAX_ESP_SIZE;
}
DiskSizeBytes = RShiftU64(DiskSizeBytes, 20); // 20 bits == 1 mb
return DiskSizeBytes;
}
CHAR16 NumStr[32];
CHAR16 *TestToken[] = {
L"CREATE",
L"NAME",
NumStr,
L"TYPE",
L"MSDATA",
L"SIZE",
L"1",
NULL
};
BOOLEAN
ScriptTest(
CHAR16 **Token
)
{
CHAR16 Buf[2];
UINTN i, j;
//
// for this to work, a disk of > 128mb will be needed
//
for (i = 0; i < 128; i++) {
SPrint(NumStr, 32, L"PART#%03d", i);
Print(L"Token for Create = \n");
for (j = 0; TestToken[j] != NULL; j++) {
Print(L"'%s' ", TestToken[j]);
}
Print(L"\n");
CmdCreate(TestToken);
if (((i+1) % 4) == 0) {
Input(L"MORE>", Buf, 2);
Print(L"\n");
}
}
return FALSE;
}