|
|
/******************************************************************************
Copyright(c) Microsoft Corporation
Module Name:
BootCfg64.cpp
Abstract:
This file is intended to have the functionality for configuring, displaying, changing and deleting boot.ini settings for the local host for a 64 bit system.
Author:
J.S.Vasu 17/1/2001 .
Revision History:
J.S.Vasu 17/1/2001 Created it. SanthoshM.B 10/2/2001 Modified it.
J.S.Vasu 15/2/2001 Modified it.
******************************************************************************/
#include "pch.h"
#include "resource.h"
#include "BootCfg.h"
#include "BootCfg64.h"
//Global Linked lists for storing the boot entries
LIST_ENTRY BootEntries; LIST_ENTRY ActiveUnorderedBootEntries; LIST_ENTRY InactiveUnorderedBootEntries;
// ***************************************************************************
//
// Name : InitializeEfi
//
// Synopsis : This routine initializes the EFI environment required
// Initializes the function pointers for the
// NT Boot Entry Management API's
//
// Parameters : None
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
// LIST_ENTRY ActiveUnorderedBootEntries;
// LIST_ENTRY InactiveUnorderedBootEntries;
//
// ***************************************************************************
DWORD InitializeEFI(void) { DWORD error; NTSTATUS status; BOOLEAN wasEnabled; HMODULE hModule; PBOOT_ENTRY_LIST ntBootEntries = NULL; PMY_BOOT_ENTRY bootEntry; PLIST_ENTRY listEntry; PULONG BootEntryOrder; ULONG BootEntryOrderCount; PULONG OriginalBootEntryOrder; ULONG OriginalBootEntryOrderCount; ULONG length, i, myId;
TCHAR dllName[MAX_PATH]; // Enable the privilege that is necessary to query/set NVRAM.
status = RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &wasEnabled ); if (!NT_SUCCESS(status)) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE( stderr, GetResString(IDS_INSUFF_PRIV));
} // Load ntdll.dll from the system directory. This is used to get the
// function addresses for the various NT Boot Entry Management API's used by
// this tool.
if(!GetSystemDirectory( dllName, MAX_PATH )) { DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); return FALSE; }
lstrcat(dllName, _T("\\ntdll.dll"));
hModule = LoadLibrary( dllName ); if ( hModule == NULL ) { DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); return FALSE; } // Get the system boot order list.
length = 0; status = NtQueryBootEntryOrder( NULL, &length ); if ( status != STATUS_BUFFER_TOO_SMALL ) { if ( status == STATUS_SUCCESS ) { length = 0; } else { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) );
return FALSE; } } if ( length != 0 ) { BootEntryOrder = (PULONG)malloc( length * sizeof(ULONG) ); if(BootEntryOrder == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); return FALSE;
} status = NtQueryBootEntryOrder( BootEntryOrder, &length ); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) ); if(BootEntryOrder) free(BootEntryOrder); return FALSE; } } BootEntryOrderCount = length; //Enumerate all the boot entries
status = BootCfg_EnumerateBootEntries(&ntBootEntries); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); //free the ntBootEntries list
if(ntBootEntries) free(ntBootEntries); if(BootEntryOrder) free(BootEntryOrder); return FALSE; }
//Initialize the various head pointers
InitializeListHead( &BootEntries ); InitializeListHead( &ActiveUnorderedBootEntries ); InitializeListHead( &InactiveUnorderedBootEntries );
//Convert the bootentries into our know format -- MY_BOOT_ENTRIES.
if(ConvertBootEntries( ntBootEntries ) == EXIT_FAILURE) { if(ntBootEntries) free(ntBootEntries); if(BootEntryOrder) free(BootEntryOrder); return FALSE; } //free the memory allocated for the enumeration
if(ntBootEntries) free(ntBootEntries);
// Build the ordered boot entry list.
myId = 1;
for ( i = 0; i < BootEntryOrderCount; i++ ) { ULONG id = BootEntryOrder[i]; for ( listEntry = ActiveUnorderedBootEntries.Flink; listEntry != &ActiveUnorderedBootEntries; listEntry = listEntry->Flink ) { bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if ( bootEntry->Id == id ) { //Mark this entry as "Ordered" as the ordered id is found
bootEntry->Ordered = 1; //Assign the internal ID
bootEntry->myId = myId++; listEntry = listEntry->Blink; RemoveEntryList( &bootEntry->ListEntry ); InsertTailList( &BootEntries, &bootEntry->ListEntry ); bootEntry->ListHead = &BootEntries; } } for ( listEntry = InactiveUnorderedBootEntries.Flink; listEntry != &InactiveUnorderedBootEntries; listEntry = listEntry->Flink ) { bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if ( bootEntry->Id == id ) { //Mark this entry as ordered as the ordered id is found
bootEntry->Ordered = 1; //Assign the internal ID
bootEntry->myId = myId++; listEntry = listEntry->Blink; RemoveEntryList( &bootEntry->ListEntry ); InsertTailList( &BootEntries, &bootEntry->ListEntry ); bootEntry->ListHead = &BootEntries; } } } //Now add the boot entries that are not a part of the ordered list
for (listEntry = ActiveUnorderedBootEntries.Flink; listEntry != &ActiveUnorderedBootEntries; listEntry = listEntry->Flink ) { bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if ( bootEntry->Ordered != 1 ) { //Assign the internal ID
bootEntry->myId = myId++; listEntry = listEntry->Blink; RemoveEntryList( &bootEntry->ListEntry ); InsertTailList( &BootEntries, &bootEntry->ListEntry ); bootEntry->ListHead = &BootEntries; } } for (listEntry = InactiveUnorderedBootEntries.Flink; listEntry != &InactiveUnorderedBootEntries; listEntry = listEntry->Flink) { bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if ( bootEntry->Id != 1 ) { //Assign the internal ID
bootEntry->myId = myId++; listEntry = listEntry->Blink; RemoveEntryList( &bootEntry->ListEntry ); InsertTailList( &BootEntries, &bootEntry->ListEntry ); bootEntry->ListHead = &BootEntries; } } if(BootEntryOrder) free(BootEntryOrder); return TRUE; }
// ***************************************************************************
//
// Name : QueryBootIniSettings_IA64
//
// Synopsis : This routine is displays the boot entries and their settings
// for an EFI based machine
//
// Parameters : None
//
// Return Type : VOID
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
BOOL QueryBootIniSettings_IA64(void) {
if(DisplayBootOptions() == EXIT_FAILURE) return EXIT_FAILURE;
DisplayBootEntry();
//Remember to free the memory for the linked lists here
return EXIT_SUCCESS; }
// ***************************************************************************
//
// Name : BootCfg_EnumerateBootEntries
//
// Synopsis : This routine enumerates the boot entries and fills the
// BootEntryList
// This routine will fill in the Boot entry list. The caller
// of this function needs to free the memory for ntBootEntries.
//
// Parameters : Pointer to the BOOT_ENTRY_LIST structure
//
// Return Type : NTSTATUS
//
// Global Variables: None
//
// ***************************************************************************
NTSTATUS BootCfg_EnumerateBootEntries(PBOOT_ENTRY_LIST *ntBootEntries) { DWORD error; NTSTATUS status; ULONG length = 0;
// Query all existing boot entries.
status = NtEnumerateBootEntries( NULL, &length ); if ( status != STATUS_BUFFER_TOO_SMALL ) { if ( status == STATUS_SUCCESS ) { length = 0; } else { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ENUM_BOOTENTRY) ); } } if ( length != 0 ) { *ntBootEntries = (PBOOT_ENTRY_LIST)malloc( length ); if(*ntBootEntries == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); return STATUS_UNSUCCESSFUL; } status = NtEnumerateBootEntries( *ntBootEntries, &length ); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ENUM_BOOTENTRY) ); } }
return status; }
// ***************************************************************************
//
// Name : BootCfg_QueryBootOptions
//
// Synopsis : This routine enumerates the boot options and fills the
// BOOT_OPTIONS
// The caller of this function needs to free the memory for
// BOOT_OPTIONS.
//
// Parameters : Pointer to the BOOT_ENTRY_LIST structure
//
// Return Type : NTSTATUS
//
// Global Variables: NONE
//
// ***************************************************************************
NTSTATUS BootCfg_QueryBootOptions(PBOOT_OPTIONS *ppBootOptions) { DWORD error; NTSTATUS status; ULONG length = 0;
//Querying the Boot options
status = NtQueryBootOptions( NULL, &length ); if ( status == STATUS_NOT_IMPLEMENTED ) { DISPLAY_MESSAGE( stderr,GetResString(IDS_NO_EFINVRAM) ); } if ( status != STATUS_BUFFER_TOO_SMALL ) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTOPTIONS) ); } *ppBootOptions = (PBOOT_OPTIONS)malloc(length); if(*ppBootOptions == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); return STATUS_UNSUCCESSFUL; } status = NtQueryBootOptions( *ppBootOptions, &length ); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTOPTIONS) ); } return status; }
// ***************************************************************************
//
// Name : RawStringOsOptions_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// as a raw string at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD RawStringOsOptions_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bUsage = FALSE ; BOOL bRaw = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; STRING256 szRawString = NULL_STRING ; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING; BOOL bAppendFlag = FALSE ;
STRING256 szAppendString = NULL_STRING ; PWINDOWS_OS_OPTIONS pWindowsOptions;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_RAW, CP_MAIN_OPTION, 1, 0,&bRaw, NULL_STRING, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY | CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, { CMDOPTION_DEFAULT, CP_DEFAULT | CP_TYPE_TEXT | CP_MANDATORY, 1, 0, &szRawString,NULL_STRING, NULL, NULL }, { CMDOPTION_APPEND , 0, 1, 0, &bAppendFlag,NULL_STRING, NULL, NULL } };
// Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return (dwExitCode); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayRawUsage_IA64(); return (EXIT_SUCCESS); }
// error checking in case the
// raw string does not start with a "/" .
if(*szRawString != _T('/')) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_FWDSLASH)); return (EXIT_FAILURE); } //Trim any leading or trailing spaces
if(szRawString) StrTrim(szRawString, _T(" ")); //Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry; //Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; }
pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions; if(bAppendFlag == TRUE ) { lstrcpy(szAppendString,pWindowsOptions->OsLoadOptions); lstrcat(szAppendString,TOKEN_EMPTYSPACE); lstrcat(szAppendString,szRawString); } else { lstrcpy(szAppendString,szRawString); }
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szAppendString) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
//
//Change the OS load options.
//Pass NULL to friendly name as we are not changing the same
//szAppendString is the Os load options specified by the user
//to be appended or to be overwritten over the existing options
//
dwExitCode = ChangeBootEntry(bootEntry, NULL, szAppendString); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
//Remember to free memory allocated for the linked lists
return (dwExitCode);
}
// ***************************************************************************
//
// Name : ChangeBootEntry
//
// Synopsis : This routine is used to change the FriendlyName and the
// OS Options for a boot entry.
//
// Parameters : PBOOT_ENTRY bootEntry (in) - Pointer to a BootEntry structure
// for which the changes needs to be made
// LPTSTR lpNewFriendlyName (in) - String specifying the new friendly name.
// LPTSTR lpOSLoadOptions (in) - String specifying the OS load options.
//
// Return Type : DWORD -- ERROR_SUCCESS on success
// -- ERROR_FAILURE on failure
//
// Global Variables : None
//
// ***************************************************************************
DWORD ChangeBootEntry(PBOOT_ENTRY bootEntry, LPTSTR lpNewFriendlyName, LPTSTR lpOSLoadOptions) { PBOOT_ENTRY_LIST bootEntryList; PBOOT_ENTRY bootEntryCopy; PMY_BOOT_ENTRY myBootEntry; PWINDOWS_OS_OPTIONS osOptions; ULONG length; PMY_BOOT_ENTRY myChBootEntry; NTSTATUS status; DWORD error, dwErrorCode = ERROR_SUCCESS; // Calculate the length of our internal structure. This includes
// the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
//
length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length; myBootEntry = (PMY_BOOT_ENTRY)malloc(length); if(myBootEntry == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwErrorCode = EXIT_FAILURE; return dwErrorCode; } RtlZeroMemory(myBootEntry, length); //
// Copy the NT BOOT_ENTRY into the allocated buffer.
//
bootEntryCopy = &myBootEntry->NtBootEntry; memcpy(bootEntryCopy, bootEntry, bootEntry->Length); myBootEntry->Id = bootEntry->Id; myBootEntry->Attributes = bootEntry->Attributes; //Change the friendly name if lpNewFriendlyName is not NULL
if(lpNewFriendlyName) { myBootEntry->FriendlyName = lpNewFriendlyName; myBootEntry->FriendlyNameLength = ((ULONG)wcslen(lpNewFriendlyName) + 1) * sizeof(WCHAR); } else { myBootEntry->FriendlyName = (PWSTR)ADD_OFFSET(bootEntryCopy, FriendlyNameOffset); myBootEntry->FriendlyNameLength = ((ULONG)wcslen(myBootEntry->FriendlyName) + 1) * sizeof(WCHAR); }
myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset); // If this is an NT boot entry, capture the NT-specific information in
// the OsOptions.
osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions; if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) && (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0)) { MBE_SET_IS_NT( myBootEntry ); //To change the OS Load options
if(lpOSLoadOptions) { myBootEntry->OsLoadOptions = lpOSLoadOptions; myBootEntry->OsLoadOptionsLength = ((ULONG)wcslen(lpOSLoadOptions) + 1) * sizeof(WCHAR); } else { myBootEntry->OsLoadOptions = osOptions->OsLoadOptions; myBootEntry->OsLoadOptionsLength = ((ULONG)wcslen(myBootEntry->OsLoadOptions) + 1) * sizeof(WCHAR); }
myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset); } else { // Foreign boot entry. Just capture whatever OS options exist.
//
myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions; myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength; } myChBootEntry = CreateBootEntryFromBootEntry(myBootEntry); if(myChBootEntry == NULL) { dwErrorCode = EXIT_FAILURE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE(stderr, ERROR_TAG); ShowLastError(stderr); //free the memory
if(myBootEntry) free(myBootEntry); return dwErrorCode; } //Call the modify API
status = NtModifyBootEntry(&myChBootEntry->NtBootEntry); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); dwErrorCode = error; DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_BOOTENTRY) ); }
//free the memory
if(myChBootEntry) free(myChBootEntry); if(myBootEntry) free(myBootEntry); return dwErrorCode; }
// ***************************************************************************
//
// Name : CreateBootEntryFromBootEntry
//
// Synopsis : This routine is used to create a new MY_BOOT_ENTRY struct.
// The caller of this function needs to free the memory allocated
// for the MY_BOOT_ENTRY struct.
//
// Parameters : PBOOT_ENTRY bootEntry (in) - Pointer to a BootEntry structure
// for which the changes needs to be made
// LPTSTR lpNewFriendlyName (in) - String specifying the new friendly name.
// LPTSTR lpOSLoadOptions (in) - String specifying the OS load options.
//
// Return Type : PMY_BOOT_ENTRY - Pointer to the new MY_BOOT_ENTRY strucure.
// NULL on failure
//
//
// Global Variables : None
//
// ***************************************************************************
PMY_BOOT_ENTRY CreateBootEntryFromBootEntry (IN PMY_BOOT_ENTRY OldBootEntry) { ULONG requiredLength; ULONG osOptionsOffset; ULONG osLoadOptionsLength; ULONG osLoadPathOffset; ULONG osLoadPathLength; ULONG osOptionsLength; ULONG friendlyNameOffset; ULONG friendlyNameLength; ULONG bootPathOffset; ULONG bootPathLength; PMY_BOOT_ENTRY newBootEntry; PBOOT_ENTRY ntBootEntry; PWINDOWS_OS_OPTIONS osOptions; PFILE_PATH osLoadPath; PWSTR friendlyName; PFILE_PATH bootPath; // Calculate how long the internal boot entry needs to be. This includes
// our internal structure, plus the BOOT_ENTRY structure that the NT APIs
// use.
//
// Our structure:
//
requiredLength = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry); // Base part of NT structure:
//
requiredLength += FIELD_OFFSET(BOOT_ENTRY, OsOptions); // Save offset to BOOT_ENTRY.OsOptions. Add in base part of
// WINDOWS_OS_OPTIONS. Calculate length in bytes of OsLoadOptions
// and add that in.
//
osOptionsOffset = requiredLength; if ( MBE_IS_NT( OldBootEntry ) ) {
// Add in base part of WINDOWS_OS_OPTIONS. Calculate length in
// bytes of OsLoadOptions and add that in.
//
requiredLength += FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions); osLoadOptionsLength = OldBootEntry->OsLoadOptionsLength; requiredLength += osLoadOptionsLength; // Round up to a ULONG boundary for the OS FILE_PATH in the
// WINDOWS_OS_OPTIONS. Save offset to OS FILE_PATH. Calculate length
// in bytes of FILE_PATH and add that in. Calculate total length of
// WINDOWS_OS_OPTIONS.
//
requiredLength = ALIGN_UP(requiredLength, ULONG); osLoadPathOffset = requiredLength; requiredLength += OldBootEntry->OsFilePath->Length; osLoadPathLength = requiredLength - osLoadPathOffset; } else { // Add in length of foreign OS options.
//
requiredLength += OldBootEntry->ForeignOsOptionsLength; osLoadOptionsLength = 0; osLoadPathOffset = 0; osLoadPathLength = 0; } osOptionsLength = requiredLength - osOptionsOffset; // Round up to a ULONG boundary for the friendly name in the BOOT_ENTRY.
// Save offset to friendly name. Calculate length in bytes of friendly name
// and add that in.
//
requiredLength = ALIGN_UP(requiredLength, ULONG); friendlyNameOffset = requiredLength; friendlyNameLength = OldBootEntry->FriendlyNameLength; requiredLength += friendlyNameLength; // Round up to a ULONG boundary for the boot FILE_PATH in the BOOT_ENTRY.
// Save offset to boot FILE_PATH. Calculate length in bytes of FILE_PATH
// and add that in.
//
requiredLength = ALIGN_UP(requiredLength, ULONG); bootPathOffset = requiredLength; requiredLength += OldBootEntry->BootFilePath->Length; bootPathLength = requiredLength - bootPathOffset; // Allocate memory for the boot entry.
//
newBootEntry = (PMY_BOOT_ENTRY)malloc(requiredLength); if(newBootEntry == NULL) return NULL; RtlZeroMemory(newBootEntry, requiredLength); // Calculate addresses of various substructures using the saved offsets.
//
ntBootEntry = &newBootEntry->NtBootEntry; osOptions = (PWINDOWS_OS_OPTIONS)ntBootEntry->OsOptions; osLoadPath = (PFILE_PATH)((PUCHAR)newBootEntry + osLoadPathOffset); friendlyName = (PWSTR)((PUCHAR)newBootEntry + friendlyNameOffset); bootPath = (PFILE_PATH)((PUCHAR)newBootEntry + bootPathOffset); // Fill in the internal-format structure.
//
// newBootEntry->AllocationEnd = (PUCHAR)newBootEntry + requiredLength;
newBootEntry->Status = OldBootEntry->Status & MBE_STATUS_IS_NT; newBootEntry->Attributes = OldBootEntry->Attributes; newBootEntry->Id = OldBootEntry->Id; newBootEntry->FriendlyName = friendlyName; newBootEntry->FriendlyNameLength = friendlyNameLength; newBootEntry->BootFilePath = bootPath; if ( MBE_IS_NT( OldBootEntry ) ) { newBootEntry->OsLoadOptions = osOptions->OsLoadOptions; newBootEntry->OsLoadOptionsLength = osLoadOptionsLength; newBootEntry->OsFilePath = osLoadPath; } // Fill in the base part of the NT boot entry.
//
ntBootEntry->Version = BOOT_ENTRY_VERSION; ntBootEntry->Length = requiredLength - FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry); ntBootEntry->Attributes = OldBootEntry->Attributes; ntBootEntry->Id = OldBootEntry->Id; ntBootEntry->FriendlyNameOffset = (ULONG)((PUCHAR)friendlyName - (PUCHAR)ntBootEntry); ntBootEntry->BootFilePathOffset = (ULONG)((PUCHAR)bootPath - (PUCHAR)ntBootEntry); ntBootEntry->OsOptionsLength = osOptionsLength; if ( MBE_IS_NT( OldBootEntry ) ) { // Fill in the base part of the WINDOWS_OS_OPTIONS, including the
// OsLoadOptions.
//
strcpy((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE); osOptions->Version = WINDOWS_OS_OPTIONS_VERSION; osOptions->Length = osOptionsLength; osOptions->OsLoadPathOffset = (ULONG)((PUCHAR)osLoadPath - (PUCHAR)osOptions); wcscpy(osOptions->OsLoadOptions, OldBootEntry->OsLoadOptions); // Copy the OS FILE_PATH.
//
memcpy( osLoadPath, OldBootEntry->OsFilePath, osLoadPathLength ); } else { // Copy the foreign OS options.
memcpy( osOptions, OldBootEntry->ForeignOsOptions, osOptionsLength ); } // Copy the friendly name.
wcscpy(friendlyName, OldBootEntry->FriendlyName); // Copy the boot FILE_PATH.
memcpy( bootPath, OldBootEntry->BootFilePath, bootPathLength ); return newBootEntry; } // CreateBootEntryFromBootEntry
// ***************************************************************************
//
// Name : DeleteBootIniSettings_IA64
//
// Synopsis : This routine deletes an existing boot entry from an EFI
// based machine
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD DeleteBootIniSettings_IA64( DWORD argc, LPCTSTR argv[] ) { BOOL bDelete = FALSE ; BOOL bUsage = FALSE; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS; NTSTATUS status; PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry;
TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_DELETE, CP_MAIN_OPTION, 1, 0, &bDelete, NULL_STRING, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY | CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL } }; // Parsing the delete option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return dwExitCode; } // Displaying delete usage if user specified -? with -delete option
if( bUsage ) { displayDeleteUsage_IA64(); return EXIT_SUCCESS; } //Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //
//display an error message if there is only 1 boot entry saying
//that it cannot be deleted.
//
if (listEntry->Flink == NULL) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ONLY_ONE_OS)); dwExitCode = EXIT_FAILURE; break ;
} //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; //Delete the boot entry specified by the user.
status = NtDeleteBootEntry(mybootEntry->Id); if(status == STATUS_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_DELETE_SUCCESS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_DELETE_FAILURE),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; } //Remember to free the memory allocated to the linked lists
return (dwExitCode); }
// ***************************************************************************
//
// Name : IsBootEntryWindows
//
// Synopsis : Checks whether the boot entry is a Windows or a foreign one
//
// Parameters : PBOOT_ENTRY bootEntry: Boot entry structure describing the
// boot entry.
//
// Return Type : BOOL
//
// Global Variables: None
//
// ***************************************************************************
BOOL IsBootEntryWindows(PBOOT_ENTRY bootEntry) {
PWINDOWS_OS_OPTIONS osOptions;
osOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions; if ((bootEntry->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) && (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0)) { return TRUE; }
return FALSE; }
// ***************************************************************************
//
// Name : GetNtNameForFilePath
//
// Synopsis : Converts the FilePath into a NT file path.
//
// Parameters : PFILE_PATH FilePath: The File path.
//
// Return Type : PWSTR: The NT file path.
//
// Global Variables: None
//
// ***************************************************************************
PWSTR GetNtNameForFilePath(IN PFILE_PATH FilePath) { NTSTATUS status; ULONG length; PFILE_PATH ntPath; PWSTR osDeviceNtName; PWSTR osDirectoryNtName; PWSTR fullNtName; DWORD dwDeviceLength = 0;
length = 0; status = NtTranslateFilePath( FilePath, FILE_PATH_TYPE_NT, NULL, &length ); if ( status != STATUS_BUFFER_TOO_SMALL ) {
return NULL; }
ntPath = (PFILE_PATH)malloc( length ); if(ntPath == NULL) return NULL; status = NtTranslateFilePath( FilePath, FILE_PATH_TYPE_NT, ntPath, &length ); if ( !NT_SUCCESS(status) ) { if(ntPath) free(ntPath); return NULL; }
osDeviceNtName = (PWSTR)ntPath->FilePath;
osDirectoryNtName = osDeviceNtName + wcslen(osDeviceNtName) + 1;
length = (ULONG)(wcslen(osDeviceNtName) + wcslen(osDirectoryNtName) + 1) * sizeof(WCHAR); fullNtName = (PWSTR)malloc( length ); if(fullNtName == NULL) { if(ntPath) free(ntPath); return NULL; }
wcscpy( fullNtName, osDeviceNtName ); wcscat( fullNtName, osDirectoryNtName );
if(ntPath) free( ntPath );
return fullNtName;
} // GetNtNameForFilePath
// ***************************************************************************
//
// Name : CopyBootIniSettings_IA64
//
// Synopsis : This routine copies and existing boot entry for an EFI
// based machine. The user can then add the various OS load
// options.
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD CopyBootIniSettings_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bCopy = FALSE ; BOOL bUsage = FALSE; DWORD dwExitCode = EXIT_SUCCESS; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry;
TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING; STRING256 szDescription = NULL_STRING;
// Builiding the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_COPY, CP_MAIN_OPTION, 1, 0, &bCopy, NULL_STRING, NULL, NULL }, { SWITCH_DESCRIPTION, CP_TYPE_TEXT | CP_VALUE_MANDATORY, 1, 0, &szDescription, NULL_STRING, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, 0, 0 }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY | CP_MANDATORY,1, 0, &dwBootID, NULL_STRING, NULL, NULL } }; // Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return dwExitCode; }
// Displaying copy usage if user specified -? with -copy option
if( bUsage ) { displayCopyUsage_IA64(); dwExitCode = EXIT_SUCCESS; return dwExitCode; }
//Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry; //Copy the boot entry specified by the user.
dwExitCode = CopyBootEntry(bootEntry, szDescription); if(dwExitCode == EXIT_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_COPY_SUCCESS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_COPY_ERROR),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; return EXIT_FAILURE ; } //Remember to free the memory allocated for the linked lists
return EXIT_SUCCESS; }
// ***************************************************************************
//
// Name : CopyBootEntry
//
// Synopsis : This routine is used to add / copy a boot entry.
//
// Parameters : PBOOT_ENTRY bootEntry (in) - Pointer to a BootEntry structure
// for which the changes needs to be made
// LPTSTR lpNewFriendlyName (in) - String specifying the new friendly name.
//
// Return Type : DWORD -- ERROR_SUCCESS on success
// -- EXIT_FAILURE on failure
//
// Global Variables : None
//
// ***************************************************************************
DWORD CopyBootEntry(PBOOT_ENTRY bootEntry, LPTSTR lpNewFriendlyName) { PBOOT_ENTRY bootEntryCopy; PMY_BOOT_ENTRY myBootEntry; PWINDOWS_OS_OPTIONS osOptions; ULONG length, Id; PMY_BOOT_ENTRY myChBootEntry; NTSTATUS status; DWORD error, dwErrorCode = ERROR_SUCCESS;
PULONG BootEntryOrder, NewBootEntryOrder, NewTempBootEntryOrder; // Calculate the length of our internal structure. This includes
// the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
//
length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length; myBootEntry = (PMY_BOOT_ENTRY)malloc(length); if(myBootEntry == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwErrorCode = EXIT_FAILURE; return dwErrorCode; } RtlZeroMemory(myBootEntry, length); //
// Copy the NT BOOT_ENTRY into the allocated buffer.
//
bootEntryCopy = &myBootEntry->NtBootEntry; memcpy(bootEntryCopy, bootEntry, bootEntry->Length); myBootEntry->Id = bootEntry->Id; myBootEntry->Attributes = bootEntry->Attributes; //Change the friendly name if lpNewFriendlyName is not NULL
if(lpNewFriendlyName && (lstrlen(lpNewFriendlyName) != 0)) { myBootEntry->FriendlyName = lpNewFriendlyName; myBootEntry->FriendlyNameLength = ((ULONG)wcslen(lpNewFriendlyName) + 1) * sizeof(WCHAR); } else { myBootEntry->FriendlyName = NULL_STRING; myBootEntry->FriendlyNameLength = 0;
}
myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset); // If this is an NT boot entry, capture the NT-specific information in
// the OsOptions.
osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions; if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) && (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0)) { MBE_SET_IS_NT( myBootEntry ); //To change the OS Load options
myBootEntry->OsLoadOptions = osOptions->OsLoadOptions; myBootEntry->OsLoadOptionsLength = ((ULONG)wcslen(myBootEntry->OsLoadOptions) + 1) * sizeof(WCHAR); myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset); } else { // Foreign boot entry. Just capture whatever OS options exist.
//
myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions; myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength; } myChBootEntry = CreateBootEntryFromBootEntry(myBootEntry); if(myChBootEntry == NULL) { dwErrorCode = EXIT_FAILURE; SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE(stderr, ERROR_TAG); if(myBootEntry) free(myBootEntry); ShowLastError(stderr); return dwErrorCode; }
//Call the NtAddBootEntry API
status = NtAddBootEntry(&myChBootEntry->NtBootEntry, &Id); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); dwErrorCode = error; DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_UNEXPECTED) ); }
// Get the system boot order list.
length = 0; status = NtQueryBootEntryOrder( NULL, &length ); if ( status != STATUS_BUFFER_TOO_SMALL ) { if ( status == STATUS_SUCCESS ) { length = 0; } else { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) ); if(myBootEntry) free(myBootEntry); if(myChBootEntry) free(myChBootEntry); return FALSE; } } if ( length != 0 ) { BootEntryOrder = (PULONG)malloc( length * sizeof(ULONG) ); if(BootEntryOrder == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwErrorCode = EXIT_FAILURE; if(myBootEntry) free(myBootEntry); if(myChBootEntry) free(myChBootEntry); return dwErrorCode;
} status = NtQueryBootEntryOrder( BootEntryOrder, &length ); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY)); dwErrorCode = error; if(myBootEntry) free(myBootEntry); if(BootEntryOrder) free(BootEntryOrder); if(myChBootEntry) free(myChBootEntry); return dwErrorCode; } } //Allocate memory for the new boot entry order.
NewBootEntryOrder = (PULONG)malloc((length+1) * sizeof(ULONG)); if(NewBootEntryOrder == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwErrorCode = EXIT_FAILURE; if(myBootEntry) free(myBootEntry); if(BootEntryOrder) free(BootEntryOrder); if(myChBootEntry) free(myChBootEntry); return dwErrorCode; }
NewTempBootEntryOrder = NewBootEntryOrder; memcpy(NewTempBootEntryOrder,BootEntryOrder,length*sizeof(ULONG)); NewTempBootEntryOrder = NewTempBootEntryOrder + length; *NewTempBootEntryOrder = Id;
status = NtSetBootEntryOrder(NewBootEntryOrder, length+1); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); dwErrorCode = error; DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_SET_BOOTENTRY)); }
//free the memory
if(NewBootEntryOrder) free(NewBootEntryOrder);
if(BootEntryOrder) free(BootEntryOrder);
if(myBootEntry) free(myBootEntry);
if(myChBootEntry) free(myChBootEntry); return dwErrorCode; }
// ***************************************************************************
//
// Name : ChangeTimeOut_IA64
//
// Synopsis : This routine chnages the Timeout value in the system
// global boot options.
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DOWRD
//
// Global Variables: None
//
// ***************************************************************************
DWORD ChangeTimeOut_IA64( DWORD argc, LPCTSTR argv[]) {
BOOL bTimeOut = FALSE ; DWORD dwTimeOut = 0; DWORD dwExitCode = EXIT_SUCCESS; ULONG Flag = 0;
TCMDPARSER cmdOptions[] = { { CMDOPTION_TIMEOUT, CP_MAIN_OPTION | CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY, 1, 0,&dwTimeOut,NULL_STRING, NULL, NULL} };
if( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return dwExitCode ; }
//Check for the limit of Timeout value entered by the user.
if(dwTimeOut > TIMEOUT_MAX) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,GetResString(IDS_TIMEOUT_RANGE)); return dwExitCode; }
//Call the ModifyBootOptions function with the BOOT_OPTIONS_FIELD_COUNTDOWN
Flag |= BOOT_OPTIONS_FIELD_COUNTDOWN;
dwExitCode = ModifyBootOptions(dwTimeOut, NULL, 0, Flag); return dwExitCode; }
// ***************************************************************************
//
// Name : ModifyBootOptions
//
// Synopsis : This routine Modifies the Boot options
// - Timeout
// - NextBootEntryID
// - HeadlessRedirection
//
// Parameters : ULONG Timeout (in) - The new Timeout value
// LPTSTR pHeadlessRedirection (in) - The Headless redirection string
// ULONG NextBootEntryID (in) - The NextBootEntryID
// ULONG Flag - The Flags indicating what fields that needs to be changed
// BOOT_OPTIONS_FIELD_COUNTDOWN
// BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID
// BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION
// Return Type : DOWRD
//
// Global Variables: None
//
// ***************************************************************************
DWORD ModifyBootOptions(ULONG Timeout, LPTSTR pHeadlessRedirection, ULONG NextBootEntryID, ULONG Flag) { DWORD dwExitCode = EXIT_SUCCESS; DWORD error; NTSTATUS status; ULONG length, i;
ULONG newlength=0;
PBOOT_OPTIONS pBootOptions, pModifiedBootOptions;
//Query the existing Boot options and modify based on the Flag value
status = BootCfg_QueryBootOptions(&pBootOptions); if(status != STATUS_SUCCESS) { error = RtlNtStatusToDosError( status ); //free the ntBootEntries list
if(pBootOptions) free(pBootOptions); dwExitCode = EXIT_FAILURE; return dwExitCode;
}
//Calculate the new length of the BOOT_OPTIONS struct based on the fields that needs to be changed.
newlength = FIELD_OFFSET(BOOT_OPTIONS, HeadlessRedirection);
if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION)) { newlength = FIELD_OFFSET(BOOT_OPTIONS, HeadlessRedirection); newlength += lstrlen(pHeadlessRedirection); newlength = ALIGN_UP(newlength, ULONG); } else newlength = pBootOptions->Length;
//Also allocate the memory for a new Boot option struct
pModifiedBootOptions = (PBOOT_OPTIONS)malloc(newlength); if(pModifiedBootOptions == NULL) { dwExitCode = EXIT_FAILURE; //free the memory for the pBootOptions allocated by the
//BootCfg_QueryBootOptions function
if(pBootOptions) free(pBootOptions); return dwExitCode; }
//Fill in the new boot options struct
pModifiedBootOptions->Version = BOOT_OPTIONS_VERSION; pModifiedBootOptions->Length = newlength;
if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN)) pModifiedBootOptions->Timeout = Timeout; else pModifiedBootOptions->Timeout = pBootOptions->Timeout;
//Cannot change the CurrentBootEntryId.So just pass what u got.
pModifiedBootOptions->CurrentBootEntryId = pBootOptions->CurrentBootEntryId;
if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID)) pModifiedBootOptions->NextBootEntryId = pBootOptions->NextBootEntryId; else pModifiedBootOptions->NextBootEntryId = pBootOptions->NextBootEntryId;
if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION)) { wcscpy(pModifiedBootOptions->HeadlessRedirection, pBootOptions->HeadlessRedirection); } else wcscpy(pModifiedBootOptions->HeadlessRedirection, pBootOptions->HeadlessRedirection); //Set the boot options in the NVRAM
status = NtSetBootOptions(pModifiedBootOptions, Flag);
if(status != STATUS_SUCCESS) { dwExitCode = EXIT_SUCCESS; if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN)) DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_TIMEOUT)); if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID)) DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_NEXTBOOTID)); if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION)) DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_HEADLESS)); } else { dwExitCode = EXIT_SUCCESS; if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN)) DISPLAY_MESSAGE(stdout,GetResString(IDS_SUCCESS_MODIFY_TIMEOUT)); if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID)) DISPLAY_MESSAGE(stdout,GetResString(IDS_SUCCESS_MODIFY_NEXTBOOTID)); if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION)) DISPLAY_MESSAGE(stdout,GetResString(IDS_SUCCESS_MODIFY_HEADLESS));
}
//free the memory
if(pModifiedBootOptions) free(pModifiedBootOptions); if(pBootOptions) free(pBootOptions);
return dwExitCode;
}
// ***************************************************************************
//
// Name : ConvertBootEntries
//
// Synopsis : Convert boot entries read from EFI NVRAM into our internal format.
//
// Parameters : PBOOT_ENTRY_LIST NtBootEntries - The boot entry list given by the enumeration
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
// LIST_ENTRY ActiveUnorderedBootEntries;
// LIST_ENTRY InactiveUnorderedBootEntries;
//
// ***************************************************************************
DWORD ConvertBootEntries (PBOOT_ENTRY_LIST NtBootEntries) { PBOOT_ENTRY_LIST bootEntryList; PBOOT_ENTRY bootEntry; PBOOT_ENTRY bootEntryCopy; PMY_BOOT_ENTRY myBootEntry; PWINDOWS_OS_OPTIONS osOptions; ULONG length; DWORD dwErrorCode = EXIT_SUCCESS;
bootEntryList = NtBootEntries;
while (TRUE) {
bootEntry = &bootEntryList->BootEntry;
//
// Calculate the length of our internal structure. This includes
// the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
//
length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length; //Remember to check for the NULL pointer
myBootEntry = (PMY_BOOT_ENTRY)malloc(length); if(myBootEntry == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwErrorCode = EXIT_FAILURE; return dwErrorCode; }
RtlZeroMemory(myBootEntry, length);
//
// Link the new entry into the list.
//
if ( (bootEntry->Attributes & BOOT_ENTRY_ATTRIBUTE_ACTIVE) != 0 ) { InsertTailList( &ActiveUnorderedBootEntries, &myBootEntry->ListEntry ); myBootEntry->ListHead = &ActiveUnorderedBootEntries; } else { InsertTailList( &InactiveUnorderedBootEntries, &myBootEntry->ListEntry ); myBootEntry->ListHead = &InactiveUnorderedBootEntries; }
//
// Copy the NT BOOT_ENTRY into the allocated buffer.
//
bootEntryCopy = &myBootEntry->NtBootEntry; memcpy(bootEntryCopy, bootEntry, bootEntry->Length);
//
// Fill in the base part of the structure.
//
myBootEntry->AllocationEnd = (PUCHAR)myBootEntry + length - 1; myBootEntry->Id = bootEntry->Id; //Assign 0 to the Ordered field currently so that
//once the boot order is known, we can assign 1 if this entry is a part of the ordered list.
myBootEntry->Ordered = 0; myBootEntry->Attributes = bootEntry->Attributes; myBootEntry->FriendlyName = (PWSTR)ADD_OFFSET(bootEntryCopy, FriendlyNameOffset); myBootEntry->FriendlyNameLength = ((ULONG)wcslen(myBootEntry->FriendlyName) + 1) * sizeof(WCHAR); myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset);
//
// If this is an NT boot entry, capture the NT-specific information in
// the OsOptions.
//
osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions;
if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) && (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0)) {
MBE_SET_IS_NT( myBootEntry ); myBootEntry->OsLoadOptions = osOptions->OsLoadOptions; myBootEntry->OsLoadOptionsLength = ((ULONG)wcslen(myBootEntry->OsLoadOptions) + 1) * sizeof(WCHAR); myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset);
} else {
//
// Foreign boot entry. Just capture whatever OS options exist.
//
myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions; myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength; }
//
// Move to the next entry in the enumeration list, if any.
//
if (bootEntryList->NextEntryOffset == 0) { break; } bootEntryList = (PBOOT_ENTRY_LIST)ADD_OFFSET(bootEntryList, NextEntryOffset); }
return dwErrorCode;
} // ConvertBootEntries
// ***************************************************************************
//
// Name : DisplayBootOptions
//
// Synopsis : Display the boot options
//
// Parameters : NONE
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD DisplayBootOptions() { DWORD error; NTSTATUS status; PBOOT_OPTIONS pBootOptions; TCHAR szDisplay[MAX_RES_STRING] = NULL_STRING;
//Query the boot options
status = BootCfg_QueryBootOptions(&pBootOptions); if(status != STATUS_SUCCESS) { error = RtlNtStatusToDosError( status ); //free the ntBootEntries list
if(pBootOptions) free(pBootOptions); return FALSE;
}
//Printout the boot options
_tprintf(_T("\n")); DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64A)); DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64B)); _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64C), pBootOptions->Timeout); DISPLAY_MESSAGE(stdout,szDisplay); //Get the CurrentBootEntryId from the actual Id present in the boot options
_stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64D), GetCurrentBootEntryID(pBootOptions->CurrentBootEntryId)); DISPLAY_MESSAGE(stdout,szDisplay);
#if 0
if(lstrlen(pBootOptions->HeadlessRedirection) == 0) { DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64E)); } else { _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64F), pBootOptions->HeadlessRedirection); DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64F)); } #endif //Commenting out the display of the Headless redirection
//as we cannot query the same through API (its Firmware controlled)
if(pBootOptions) free(pBootOptions);
return EXIT_SUCCESS; }
// ***************************************************************************
//
// Name : DisplayBootEntry
//
// Synopsis : Display the boot entries (in an order)
//
// Parameters : NONE
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
VOID DisplayBootEntry() { PLIST_ENTRY listEntry; PMY_BOOT_ENTRY bootEntry; PFILE_PATH OsLoadPath, BootFilePath; PWSTR NtFilePath; TCHAR szDisplay[MAX_RES_STRING] = NULL_STRING ;
//Printout the boot entires
DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64G)); DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64H));
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64I), bootEntry->myId); DISPLAY_MESSAGE(stdout,szDisplay);
//friendly name
if(lstrlen(bootEntry->FriendlyName)!=0) { _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64J), bootEntry->FriendlyName); DISPLAY_MESSAGE(stdout,szDisplay); } else { DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64K)); } if(MBE_IS_NT(bootEntry)) { //the OS load options
if(lstrlen(bootEntry->OsLoadOptions)!=0) { _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64L), bootEntry->OsLoadOptions); DISPLAY_MESSAGE(stdout,szDisplay); } else { DISPLAY_MESSAGE(stdout,GetResString(IDS_OUTPUT_IA64M)); } //Get the BootFilePath
NtFilePath = GetNtNameForFilePath(bootEntry->BootFilePath); _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64N), NtFilePath); DISPLAY_MESSAGE(stdout,szDisplay); //free the memory
if(NtFilePath) free(NtFilePath); //Get the OS load path
NtFilePath = GetNtNameForFilePath(bootEntry->OsFilePath); _stprintf(szDisplay,GetResString(IDS_OUTPUT_IA64O), NtFilePath); DISPLAY_MESSAGE(stdout,szDisplay);
//free the memory
if(NtFilePath) free(NtFilePath); } else { _tprintf(_T("\n")); }
} }
// ***************************************************************************
//
// Name : GetCurrentBootEntryID
//
// Synopsis : Gets the Boot entry ID generated by us from the BootId given by the NVRAM
//
// Parameters : DWORD Id -- The current boot id (BootId given by the NVRAM)
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD GetCurrentBootEntryID(DWORD Id) { PLIST_ENTRY listEntry; PMY_BOOT_ENTRY bootEntry; for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(bootEntry->Id == Id) { return bootEntry->myId; } }
return 0; }
// ***************************************************************************
//
// Name : ChangeDefaultBootEntry_IA64
//
// Synopsis : This routine is to change the Default boot entry in the NVRAM
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables : None
//
// ***************************************************************************
DWORD ChangeDefaultBootEntry_IA64(DWORD argc,LPCTSTR argv[]) {
DWORD dwBootID = 0; BOOL bDefaultOs = FALSE ; DWORD dwExitCode = ERROR_SUCCESS; BOOL bBootIdFound = FALSE, bIdFoundInBootOrderList = FALSE;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; ULONG length, i, j, defaultId=0; NTSTATUS status; DWORD error;
PULONG BootEntryOrder, NewBootEntryOrder, NewTempBootEntryOrder; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
TCMDPARSER cmdOptions[] = { { CMDOPTION_DEFAULTOS, CP_MAIN_OPTION, 1, 0,&bDefaultOs, NULL_STRING, NULL, NULL }, { SWITCH_ID,CP_TYPE_NUMERIC | CP_VALUE_MANDATORY| CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL } };
if( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); dwExitCode = EXIT_FAILURE; return dwExitCode ; }
//Check whether the boot entry entered bu the user is a valid boot entry id or not.
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; //store the default ID
defaultId = mybootEntry->Id; break; } }
if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; return dwExitCode; }
// Get the system boot order list.
length = 0; status = NtQueryBootEntryOrder( NULL, &length ); if ( status != STATUS_BUFFER_TOO_SMALL ) { if ( status == STATUS_SUCCESS ) { length = 0; } else { error = RtlNtStatusToDosError( status ); _stprintf(szMsgBuffer, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); dwExitCode = EXIT_FAILURE; return dwExitCode; } } if ( length != 0 ) { BootEntryOrder = (PULONG)malloc( length * sizeof(ULONG) ); if(BootEntryOrder == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwExitCode = EXIT_FAILURE; return dwExitCode; } status = NtQueryBootEntryOrder( BootEntryOrder, &length ); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); _stprintf(szMsgBuffer, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); dwExitCode = error; if(BootEntryOrder) free(BootEntryOrder); return dwExitCode; } }
//Check if the boot id entered by the user is a part of the Boot entry order.
//If not for the time being do not make it the default.
for(i=0;i<length;i++) { if(*(BootEntryOrder+i) == defaultId) { bIdFoundInBootOrderList = TRUE; break; } }
if(bIdFoundInBootOrderList == FALSE) { dwExitCode = EXIT_FAILURE; if(BootEntryOrder) free(BootEntryOrder); _stprintf(szMsgBuffer, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); return dwExitCode; }
//Allocate memory for storing the new boot entry order.
NewBootEntryOrder = (PULONG)malloc((length) * sizeof(ULONG)); if(NewBootEntryOrder == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); DISPLAY_MESSAGE( stderr, ERROR_TAG); ShowLastError(stderr); dwExitCode = EXIT_FAILURE; if(BootEntryOrder) free(BootEntryOrder); return dwExitCode; }
*NewBootEntryOrder = defaultId; j=0; for(i=0;i<length;i++) { if(*(BootEntryOrder+i) == defaultId) continue; *(NewBootEntryOrder+(j+1)) = *(BootEntryOrder+i); j++; }
status = NtSetBootEntryOrder(NewBootEntryOrder, length); if ( status != STATUS_SUCCESS ) { error = RtlNtStatusToDosError( status ); dwExitCode = error; _stprintf(szMsgBuffer, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer);
} else { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_DEFAULT_ENTRY),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); }
//free the memory
if(NewBootEntryOrder) free(NewBootEntryOrder); if(BootEntryOrder) free(BootEntryOrder); return dwExitCode; }
// ***************************************************************************
//
// Name : ProcessDebugSwitch_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// as a debug string at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessDebugSwitch_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bUsage = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; STRING100 szRawString = NULL_STRING ; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING ; TCHAR szPort[MAX_RES_STRING] = NULL_STRING ; TCHAR szBaudRate[MAX_RES_STRING] = NULL_STRING ; TCHAR szDebug[MAX_RES_STRING] = NULL_STRING ; BOOL bDebug = FALSE ; DWORD dwId = 0; PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; TCHAR szTemp[MAX_RES_STRING] = NULL_STRING ; TCHAR szTmpBuffer[MAX_RES_STRING] = NULL_STRING ;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_DEBUG, CP_MAIN_OPTION | CP_TYPE_TEXT | CP_MODE_VALUES | CP_VALUE_OPTIONAL, 1, 0,&szDebug, CMDOPTION_DEBUG_VALUES, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY | CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, { SWITCH_PORT, CP_TYPE_TEXT | CP_VALUE_MANDATORY|CP_MODE_VALUES,1,0,&szPort,COM_PORT_RANGE,NULL,NULL}, { SWITCH_BAUD, CP_TYPE_TEXT | CP_VALUE_MANDATORY |CP_MODE_VALUES,1,0,&szBaudRate,BAUD_RATE_VALUES_DEBUG,NULL,NULL}, };
// Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return (dwExitCode); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayDebugUsage_IA64(); return (ERROR_SUCCESS); }
//Trim any leading or trailing spaces
if(szDebug) StrTrim(szDebug, _T(" "));
if( !( ( lstrcmpi(szDebug,VALUE_ON)== 0) || (lstrcmpi(szDebug,VALUE_OFF)== 0 ) ||(lstrcmpi(szDebug,EDIT_STRING)== 0) ) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG)); return EXIT_FAILURE;
} //Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry;
//Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; } //Change the OS load options. Pass NULL to friendly name as we are not changing the same
//szRawString is the Os load options specified by the user
pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
// copy the existing OS Loadoptions into a string.
lstrcpy(szOsLoadOptions,pWindowsOptions->OsLoadOptions); //check if the user has entered On option
if( lstrcmpi(szDebug,VALUE_ON)== 0) { //display an error message
if ( (_tcsstr(szOsLoadOptions,DEBUG_SWITCH) != 0 )&& (lstrlen(szPort)==0) &&(lstrlen(szBaudRate)==0) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_DEBUG)); dwExitCode = EXIT_FAILURE; break; }
//display a error message and exit if the 1394 port is already present.
if(_tcsstr(szOsLoadOptions,DEBUGPORT_1394) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_1394_ALREADY_PRESENT)); dwExitCode = EXIT_FAILURE; break; } if( (lstrlen(szPort)==0) &&(lstrlen(szBaudRate)!=0) ) { if( (_tcsstr(szOsLoadOptions,TOKEN_DEBUGPORT) == 0 ) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_CANNOT_ADD_BAUDRATE)); dwExitCode = EXIT_FAILURE; break; }
} //
//display an duplicate entry error message if substring is already present.
//
if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_SUCCESS ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPLICATE_ENTRY)); return EXIT_FAILURE ; }
if(lstrlen(szTemp)!=0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPLICATE_ENTRY)); dwExitCode = EXIT_FAILURE; break; }
//check if the Os load options already contains
// debug switch
if(_tcsstr(szOsLoadOptions,DEBUG_SWITCH) == 0 ) { lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,DEBUG_SWITCH);
}
if(lstrlen(szPort)!= 0) { lstrcat(szTmpBuffer,TOKEN_EMPTYSPACE); lstrcat(szTmpBuffer,TOKEN_DEBUGPORT) ; lstrcat(szTmpBuffer,TOKEN_EQUAL) ; CharUpper(szPort); lstrcat(szTmpBuffer,szPort); lstrcat(szOsLoadOptions,szTmpBuffer); } //Check if the OS Load Options contains the baud rate already specified.
if(lstrlen(szBaudRate)!=0) { GetBaudRateVal(szOsLoadOptions,szTemp) ; if(lstrlen(szTemp)!=0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPLICATE_BAUD_RATE)); dwExitCode = EXIT_FAILURE; break; } else { lstrcpy(szTemp,BAUD_RATE); lstrcat(szTemp,TOKEN_EQUAL); lstrcat(szTemp,szBaudRate); } } //append the string containing the modified port value to the string
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,szTemp); } //check if the user has entered OFF option
if( lstrcmpi(szDebug,VALUE_OFF)== 0) { // If the user enters either com port or baud rate then display error message and exit.
if ((lstrlen(szPort)!=0) ||(lstrlen(szBaudRate)!=0)) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG)); dwExitCode = EXIT_FAILURE; break; }
// If the user enters either com port or baud rate then display error message and exit.
if (_tcsstr(szOsLoadOptions,DEBUG_SWITCH) == 0 ) {
DISPLAY_MESSAGE(stderr,GetResString(IDS_DEBUG_ABSENT)); dwExitCode = EXIT_FAILURE; break; }
//remove the debug switch from the OSLoad Options
removeSubString(szOsLoadOptions,DEBUG_SWITCH); if(_tcsstr(szOsLoadOptions,DEBUGPORT_1394) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_1394_REMOVE)); dwExitCode = EXIT_FAILURE; break; }
//display an error message if debug port doee not exist.
if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_FAILURE) {
DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_DEBUGPORT)); return EXIT_FAILURE ; }
if(lstrlen(szTemp)!=0) { // remove the /debugport=comport switch if it is present from the Boot Entry
removeSubString(szOsLoadOptions,szTemp); } lstrcpy(szTemp , NULL_STRING ); //remove the baud rate switch if it is present.
GetBaudRateVal(szOsLoadOptions,szTemp) ; // if the OSLoadOptions contains baudrate then delete it.
if (lstrlen(szTemp )!= 0) { removeSubString(szOsLoadOptions,szTemp); }
}
//if the user selected the edit option .
if( lstrcmpi(szDebug,EDIT_STRING)== 0) { //check if the debug switch is present in the Osload options else display error message.
if (_tcsstr(szOsLoadOptions,DEBUG_SWITCH) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DEBUG_ABSENT)); dwExitCode = EXIT_FAILURE; break; }
if( _tcsstr(szOsLoadOptions,DEBUGPORT_1394) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_EDIT_1394_SWITCH)); dwExitCode = EXIT_FAILURE; break; }
//check if the user enters COM port or baud rate else display error message.
if((lstrlen(szPort)==0)&&(lstrlen(szBaudRate)==0)) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG)); dwExitCode = EXIT_FAILURE; break;
} if( lstrlen(szPort)!=0 ) { if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_FAILURE) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_DEBUGPORT)); return EXIT_FAILURE ; } if(lstrlen(szTemp)!=0) { //remove the existing entry from the OsLoadOptions String.
removeSubString(szOsLoadOptions,szTemp); } //Add the port entry specified by user into the OsLoadOptions String.
lstrcat(szTmpBuffer,TOKEN_EMPTYSPACE); lstrcat(szTmpBuffer,TOKEN_DEBUGPORT) ; lstrcat(szTmpBuffer,TOKEN_EQUAL) ; CharUpper(szPort); lstrcat(szTmpBuffer,szPort); lstrcat(szOsLoadOptions,szTmpBuffer);
} //Check if the OS Load Options contains the baud rate already specified.
if(lstrlen(szBaudRate)!=0) { if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_FAILURE) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_DEBUGPORT)); return EXIT_FAILURE ; } if(lstrlen(szTemp)==0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_DEBUGPORT)); return EXIT_FAILURE ; }
lstrcpy(szTemp,NULL_STRING); GetBaudRateVal(szOsLoadOptions,szTemp) ; if(lstrlen(szTemp)!=0) { removeSubString(szOsLoadOptions,szTemp); } lstrcpy(szTemp,BAUD_RATE); lstrcat(szTemp,TOKEN_EQUAL); lstrcat(szTemp,szBaudRate); lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,szTemp); } }
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szOsLoadOptions) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
// modify the Boot Entry with the modified OsLoad Options.
dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
//Remember to free memory allocated for the linked lists
return (dwExitCode);
}
// ***************************************************************************
//
// Name : GetComPortType_IA64
//
// Synopsis : Get the Type of Com Port present in Boot Entry
//
// Parameters : szString : The String which is to be searched.
// szTemp : String which will get the com port type
// Return Type : VOID
//
// Global Variables : None
//
// ***************************************************************************
VOID GetComPortType_IA64( LPTSTR szString,LPTSTR szTemp ) { if(_tcsstr(szString,PORT_COM1A)!=0) { lstrcpy(szTemp,PORT_COM1A); } else if(_tcsstr(szString,PORT_COM2A)!=0) { lstrcpy(szTemp,PORT_COM2A); } else if(_tcsstr(szString,PORT_COM3A)!=0) { lstrcpy(szTemp,PORT_COM3A); } else if(_tcsstr(szString,PORT_COM4A)!=0) { lstrcpy(szTemp,PORT_COM4A); } else if(_tcsstr(szString,PORT_1394A)!=0) { lstrcpy(szTemp,PORT_1394A); } }
// ***************************************************************************
//
// Name : ProcessEmsSwitch_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// as a debug string at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessEmsSwitch_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bUsage = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING ; TCHAR szEms[MAX_RES_STRING] = NULL_STRING ; BOOL bEms = FALSE ; PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; // Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_EMS, CP_MAIN_OPTION | CP_TYPE_TEXT | CP_MODE_VALUES | CP_VALUE_OPTIONAL, 1, 0,&szEms,CMDOPTION_EMS_VALUES_IA64, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY | CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, };
// Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return (dwExitCode); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayEmsUsage_IA64(); return (EXIT_SUCCESS); }
//display error message if the user enters any other string other that on/off.
if( !((lstrcmpi(szEms,VALUE_ON)== 0) || (lstrcmpi(szEms,VALUE_OFF)== 0))) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_EMS)); return EXIT_FAILURE ; } //Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry;
//Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; } pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
// copy the existing OS Loadoptions into a string.
lstrcpy(szOsLoadOptions,pWindowsOptions->OsLoadOptions); //check if the user has entered On option
if( lstrcmpi(szEms,VALUE_ON)== 0) { if (_tcsstr(szOsLoadOptions,REDIRECT_SWITCH) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_REDIRECT)); dwExitCode = EXIT_FAILURE; break; } // add the redirect switch to the OS Load Options string.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,REDIRECT_SWITCH); } //check if the user has entered OFF option
if( lstrcmpi(szEms,VALUE_OFF)== 0) { // If the user enters either com port or baud rate then display error message and exit.
if (_tcsstr(szOsLoadOptions,REDIRECT_SWITCH) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_REDIRECT_ABSENT)); dwExitCode = EXIT_FAILURE; break; }
//remove the debug switch from the OSLoad Options
removeSubString(szOsLoadOptions,REDIRECT_SWITCH); }
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szOsLoadOptions) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
// modify the Boot Entry with the modified OsLoad Options.
dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
return (dwExitCode);
}
// ***************************************************************************
//
// Name : ProcessAddSwSwitch_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessAddSwSwitch_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bUsage = FALSE ; BOOL bAddSw = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
BOOL bBaseVideo = FALSE ; BOOL bNoGui = FALSE ; BOOL bSos = FALSE ; DWORD dwMaxmem = 0 ;
PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; TCHAR szMaxmem[MAX_RES_STRING] = NULL_STRING ;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_ADDSW, CP_MAIN_OPTION, 1, 0,&bAddSw, NULL_STRING, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY|CP_MANDATORY , 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, { SWITCH_MAXMEM, CP_TYPE_UNUMERIC | CP_VALUE_MANDATORY,1,0,&dwMaxmem,NULL_STRING,NULL,NULL}, { SWITCH_BASEVIDEO, 0,1,0,&bBaseVideo,NULL_STRING,NULL,NULL}, { SWITCH_NOGUIBOOT, 0,1,0,&bNoGui,NULL_STRING,NULL,NULL}, { SWITCH_SOS, 0,1,0,&bSos,NULL_STRING,NULL,NULL}, };
// Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return (dwExitCode); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayAddSwUsage_IA64(); return (EXIT_SUCCESS); }
if((dwMaxmem==0)&&(cmdOptions[3].dwActuals!=0)) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MAXMEM_VALUES)); return EXIT_FAILURE ; }
//display an error mesage if none of the options are specified.
if((!bSos)&&(!bBaseVideo)&&(!bNoGui)&&(dwMaxmem==0)) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_ADDSW)); return EXIT_FAILURE ; }
//Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry; //Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; }
pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
// copy the existing OS Loadoptions into a string.
lstrcpy(szOsLoadOptions,pWindowsOptions->OsLoadOptions);
//check if the user has entered -basevideo option
if(bBaseVideo) { if (_tcsstr(szOsLoadOptions,BASEVIDEO_VALUE) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_BASEVIDEO_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // add the redirect switch to the OS Load Options string.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,BASEVIDEO_VALUE); } } if(bSos) { if (_tcsstr(szOsLoadOptions,SOS_VALUE) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_SOS_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // add the redirect switch to the OS Load Options string.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,SOS_VALUE); } }
if(bNoGui) { if (_tcsstr(szOsLoadOptions,NOGUI_VALUE) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_NOGUI_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // add the redirect switch to the OS Load Options string.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,NOGUI_VALUE); } }
if(dwMaxmem!=0) { // check if the maxmem value is in the valid range.
if( (dwMaxmem < 32) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MAXMEM_VALUES)); dwExitCode = EXIT_FAILURE; break;
} if (_tcsstr(szOsLoadOptions,MAXMEM_VALUE1) != 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPL_MAXMEM_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // add the redirect switch to the OS Load Options string.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,MAXMEM_VALUE1); lstrcat(szOsLoadOptions,TOKEN_EQUAL); _ltow(dwMaxmem,szMaxmem,10); lstrcat(szOsLoadOptions,szMaxmem); }
}
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szOsLoadOptions) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
//Change the OS load options. Pass NULL to friendly name as we are not changing the same
//szRawString is the Os load options specified by the user
dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
//Remember to free memory allocated for the linked lists
return (dwExitCode);
}
// ***************************************************************************
//
// Name : ProcessRmSwSwitch_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessRmSwSwitch_IA64( DWORD argc, LPCTSTR argv[] ) {
BOOL bUsage = FALSE ; BOOL bRmSw = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
BOOL bBaseVideo = FALSE ; BOOL bNoGui = FALSE ; BOOL bSos = FALSE ; BOOL bMaxmem = FALSE ;
PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; TCHAR szMaxmem[MAX_RES_STRING] = NULL_STRING ;
TCHAR szTemp[MAX_RES_STRING] = NULL_STRING ;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_RMSW, CP_MAIN_OPTION, 1, 0,&bRmSw, NULL_STRING, NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY|CP_MANDATORY, 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, { SWITCH_MAXMEM, 0,1,0,&bMaxmem,NULL_STRING,NULL,NULL}, { SWITCH_BASEVIDEO, 0,1,0,&bBaseVideo,NULL_STRING,NULL,NULL}, { SWITCH_NOGUIBOOT, 0,1,0,&bNoGui,NULL_STRING,NULL,NULL}, { SWITCH_SOS, 0,1,0,&bSos,NULL_STRING,NULL,NULL}, };
// Parsing the copy option switches
if ( ! DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) { dwExitCode = EXIT_FAILURE; DISPLAY_MESSAGE(stderr,ERROR_TAG); ShowMessage(stderr,GetReason()); return (dwExitCode); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) {
displayRmSwUsage_IA64(); return (EXIT_SUCCESS); }
//display an error mesage if none of the options are specified.
if((!bSos)&&(!bBaseVideo)&&(!bNoGui)&&(!bMaxmem)) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_RMSW)); return EXIT_FAILURE; }
//Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry; //Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; }
pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
// copy the existing OS Loadoptions into a string.
lstrcpy(szOsLoadOptions,pWindowsOptions->OsLoadOptions);
//check if the user has entered -basevideo option
if(bBaseVideo) { if (_tcsstr(szOsLoadOptions,BASEVIDEO_VALUE) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_BV_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // remove the basevideo switch from the OS Load Options string.
removeSubString(szOsLoadOptions,BASEVIDEO_VALUE); } } if(bSos) { if (_tcsstr(szOsLoadOptions,SOS_VALUE) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_SOS_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // remove the /sos switch from the Load Options string.
removeSubString(szOsLoadOptions,SOS_VALUE); } }
if(bNoGui) { if (_tcsstr(szOsLoadOptions,NOGUI_VALUE) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_NOGUI_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // remove the noguiboot switch to the OS Load Options string.
removeSubString(szOsLoadOptions,NOGUI_VALUE); } }
if(bMaxmem) {
if (_tcsstr(szOsLoadOptions,MAXMEM_VALUE1) == 0 ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_MAXMEM_SWITCH)); dwExitCode = EXIT_FAILURE; break; } else { // add the redirect switch to the OS Load Options string.
//for, a temporary string of form /maxmem=xx so that it
//can be checked in the Os load options,
if ( GetSubString(szOsLoadOptions,MAXMEM_VALUE1,szTemp) == EXIT_FAILURE) { return EXIT_FAILURE ; }
removeSubString(szOsLoadOptions,szTemp); if(_tcsstr(szOsLoadOptions,MAXMEM_VALUE1)!=0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_MAXMEM) ); return EXIT_FAILURE ; } }
}
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szOsLoadOptions) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
//Change the OS load options. Pass NULL to friendly name as we are not changing the same
//szRawString is the Os load options specified by the user
dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
return (dwExitCode);
}
// ***************************************************************************
//
// Name : ProcessDbg1394Switch_IA64
//
// Synopsis : Allows the user to add the OS load options specifed
// at the cmdline to the boot
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessDbg1394Switch_IA64( DWORD argc, LPCTSTR argv[] ) { BOOL bUsage = FALSE ; BOOL bDbg1394 = FALSE ; DWORD dwBootID = 0; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
BOOL bBaseVideo = FALSE ; BOOL bNoGui = FALSE ; BOOL bSos = FALSE ; BOOL bMaxmem = FALSE ;
PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; TCHAR szMaxmem[MAX_RES_STRING] = NULL_STRING ;
TCHAR szTemp[MAX_RES_STRING] = NULL_STRING ;
TCHAR szChannel[MAX_RES_STRING] = NULL_STRING ;
TCHAR szDefault[MAX_RES_STRING] = NULL_STRING ; DWORD dwChannel = 0 ; DWORD dwCode = 0 ;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_DBG1394, CP_MAIN_OPTION, 1, 0,&bDbg1394,NULL_STRING , NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY , 1, 0, &dwBootID, NULL_STRING, NULL, NULL }, { CMDOPTION_CHANNEL, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY,1,0,&dwChannel,NULL_STRING,NULL,NULL}, { CMDOPTION_DEFAULT, CP_DEFAULT|CP_TYPE_TEXT , 1, 0, &szDefault,NULL_STRING, NULL, NULL } };
// Parsing the copy option switches
if ( !(DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) ) { DISPLAY_MESSAGE(stderr,ERROR_TAG) ; ShowMessage(stderr,GetReason()) ; return (EXIT_FAILURE); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayDbg1394Usage_IA64() ; return (EXIT_SUCCESS); }
if((cmdOptions[2].dwActuals == 0) &&(dwBootID == 0 )) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ID_MISSING)); DISPLAY_MESSAGE(stderr,GetResString(IDS_1394_HELP)); return (EXIT_FAILURE); }
//
//display error message if user enters a value
// other than on or off
//
if( ( lstrcmpi(szDefault,OFF_STRING)!=0 ) && (lstrcmpi(szDefault,ON_STRING)!=0 ) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_DEFAULT_MISSING)); DISPLAY_MESSAGE(stderr,GetResString(IDS_1394_HELP)); return (EXIT_FAILURE); }
if(( lstrcmpi(szDefault,OFF_STRING)==0 ) &&(dwChannel != 0) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_SYNTAX_DBG1394)); return (EXIT_FAILURE); }
if(( lstrcmpi(szDefault,ON_STRING)==0 ) && (cmdOptions[3].dwActuals != 0) &&( (dwChannel < 1) || (dwChannel > 64 ) ) ) { DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_CH_RANGE)); return (EXIT_FAILURE); } //Query the boot entries till u get the BootID specified by the user
for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink) { //Get the boot entry
mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry ); if(mybootEntry->myId == dwBootID) { bBootIdFound = TRUE; bootEntry = &mybootEntry->NtBootEntry; //Check whether the bootEntry is a Windows one or not.
//The OS load options can be added only to a Windows boot entry.
if(!IsBootEntryWindows(bootEntry)) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr,szMsgBuffer); DISPLAY_MESSAGE(stderr, GetResString(IDS_INFO_NOTWINDOWS)); dwExitCode = EXIT_FAILURE; break; }
pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
// copy the existing OS Loadoptions into a string.
lstrcpy(szOsLoadOptions,pWindowsOptions->OsLoadOptions);
//check if the user has entered on option
if(lstrcmpi(szDefault,ON_STRING)==0 ) {
if(_tcsstr(szOsLoadOptions,DEBUGPORT) != 0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_DUPLICATE_ENTRY)); dwExitCode = EXIT_FAILURE; break; }
if( _tcsstr(szOsLoadOptions,DEBUG_SWITCH)== 0) { lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,DEBUG_SWITCH); }
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,DEBUGPORT_1394) ; if(dwChannel!=0) {
//frame the string and concatenate to the Os Load options.
lstrcat(szOsLoadOptions,TOKEN_EMPTYSPACE); lstrcat(szOsLoadOptions,TOKEN_CHANNEL); lstrcat(szOsLoadOptions,TOKEN_EQUAL); _ltow(dwChannel,szChannel,10); lstrcat(szOsLoadOptions,szChannel); }
}
if(lstrcmpi(szDefault,OFF_STRING)==0 ) { if(_tcsstr(szOsLoadOptions,DEBUGPORT_1394) == 0) { DISPLAY_MESSAGE(stderr,GetResString(IDS_NO_1394_SWITCH)); dwExitCode = EXIT_FAILURE; break; }
//
//remove the port from the Os Load options string.
//
removeSubString(szOsLoadOptions,DEBUGPORT_1394);
// check if the string contains the channel token
// and if present remove that also.
//
if(_tcsstr(szOsLoadOptions,TOKEN_CHANNEL)!=0) { lstrcpy(szTemp,NULL_STRING); dwCode = GetSubString(szOsLoadOptions,TOKEN_CHANNEL,szTemp); if(dwCode == EXIT_SUCCESS) { //
//Remove the channel token if present.
//
if(lstrlen(szTemp)!= 0) { removeSubString(szOsLoadOptions,szTemp); removeSubString(szOsLoadOptions,DEBUG_SWITCH); } } } removeSubString(szOsLoadOptions,DEBUG_SWITCH);
}
//display error message if Os Load options is more than 254
// characters.
if(lstrlen(szOsLoadOptions) >= MAX_RES_STRING) { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING); DISPLAY_MESSAGE(stderr,szMsgBuffer); break ;
}
//Change the OS load options. Pass NULL to friendly name as we are not changing the same
//szRawString is the Os load options specified by the user
dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions); if(dwExitCode == ERROR_SUCCESS) { _stprintf(szMsgBuffer, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stdout,szMsgBuffer); } else { _stprintf(szMsgBuffer, GetResString(IDS_ERROR_OSOPTIONS),dwBootID); DISPLAY_MESSAGE(stderr, szMsgBuffer); } break; } } if(bBootIdFound == FALSE) { //Could not find the BootID specified by the user so output the message and return failure
DISPLAY_MESSAGE(stderr,GetResString(IDS_INVALID_BOOTID)); dwExitCode = EXIT_FAILURE; }
return (dwExitCode);
}
// ***************************************************************************
//
// Synopsis : Allows the user to add the OS load options specifed
// based on the mirror plex
//
// Parameters : DWORD argc (in) - Number of command line arguments
// LPCTSTR argv (in) - Array containing command line arguments
//
// Return Type : DWORD
//
// Global Variables: Global Linked lists for storing the boot entries
// LIST_ENTRY BootEntries;
//
// ***************************************************************************
DWORD ProcessMirrorSwitch_IA64( DWORD argc, LPCTSTR argv[] ) { BOOL bUsage = FALSE ; BOOL bDbg1394 = FALSE ; DWORD dwBootID = 1; BOOL bBootIdFound = FALSE; DWORD dwExitCode = ERROR_SUCCESS;
PMY_BOOT_ENTRY mybootEntry; PLIST_ENTRY listEntry; PBOOT_ENTRY bootEntry; PBOOT_ENTRY ModbootEntry;
TCHAR szMsgBuffer[MAX_RES_STRING] = NULL_STRING;
BOOL bBaseVideo = FALSE ; BOOL bNoGui = FALSE ; BOOL bSos = FALSE ; BOOL bMaxmem = FALSE ;
PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ; TCHAR szOsLoadOptions[MAX_RES_STRING] = NULL_STRING ; TCHAR szMaxmem[MAX_RES_STRING] = NULL_STRING ;
TCHAR szTemp[MAX_RES_STRING] = NULL_STRING ;
TCHAR szChannel[MAX_RES_STRING] = NULL_STRING ;
TCHAR szAdd[MAX_RES_STRING] = NULL_STRING ; TCHAR szDefault[MAX_RES_STRING] = NULL_STRING ; TCHAR szUpdate[MAX_RES_STRING] = NULL_STRING ; DWORD dwChannel = 0 ; DWORD dwCode = 0 ; BOOL bMirror = FALSE ; DWORD dwList = 0 ; DWORD dwCnt = 0 ; TCHAR szArcPath[MAX_RES_STRING] = NULL_STRING ; TCHAR szBootPath[MAX_RES_STRING] = NULL_STRING ; TCHAR szLdrString[MAX_RES_STRING] = NULL_STRING ;
ULONG length = 0 ; DWORD Id = 0 ; NTSTATUS status ; DWORD error = 0 ; LONG lRetVal = 0 ;
WCHAR pwszLoaderPath[] = L"signature({09de56a0-a122-01c0-507b-9e5f8078f531})\\EFI\\Microsoft\\WINNT50.1\\ia64ldr.efi" ; WCHAR pwszArcString[] = L"signature(fd0611c0a12101c0a1f404622fd5ec6d)\\WINDOWS=";
WCHAR pwszArcString1[] = L"\"Boot Mirror x: - secondary plex\"";
WCHAR pwszFinalArcString[1024] ;
// Building the TCMDPARSER structure
TCMDPARSER cmdOptions[] = { { CMDOPTION_MIRROR, CP_MAIN_OPTION, 1, 0,&bMirror,NULL_STRING , NULL, NULL }, { CMDOPTION_USAGE, CP_USAGE, 1, 0, &bUsage, NULL_STRING, NULL, NULL }, { CMDOPTION_LIST, CP_VALUE_OPTIONAL|CP_TYPE_UNUMERIC,1,0,&dwList,NULL_STRING,NULL,NULL}, { CMDOPTION_ADD, CP_TYPE_TEXT|CP_VALUE_MANDATORY , 1, 0, &szAdd,NULL_STRING, NULL, NULL } , { CMDOPTION_UPDATE, CP_TYPE_TEXT|CP_VALUE_MANDATORY, 1, 0, &szUpdate,NULL_STRING, NULL, NULL }, { SWITCH_ID, CP_TYPE_NUMERIC | CP_VALUE_MANDATORY , 1, 0, &dwBootID, NULL_STRING, NULL, NULL } };
// Parsing the copy option switches
if ( !(DoParseParam( argc, argv, SIZE_OF_ARRAY(cmdOptions ), cmdOptions ) ) ) { DISPLAY_MESSAGE(stderr,ERROR_TAG) ; ShowMessage(stderr,GetReason()) ; return (EXIT_FAILURE); }
// Displaying query usage if user specified -? with -query option
if( bUsage ) { displayMirrorUsage_IA64() ; return (EXIT_SUCCESS); }
if((cmdOptions[2].dwActuals ==0)&&(cmdOptions[3].dwActuals ==0)&&(cmdOptions[4].dwActuals ==0) ) { DISPLAY_MESSAGE(stdout,GetResString(IDS_MIRROR_SYNTAX)); return (EXIT_FAILURE);
}
if((cmdOptions[2].dwActuals !=0)) { if(dwList > 0) { //ScanGPT(dwList) ;
_tprintf(_T("To be implemented.\n")); return (EXIT_SUCCESS); } else { dwList = 0 ; //ScanGPT(dwList) ;
_tprintf(_T("To be implemented.\n")); return (EXIT_SUCCESS); } }
if(lstrlen(szAdd) !=0) { _tprintf(_T("To be implemented.\n"));
}
if(lstrlen(szUpdate) !=0) { _tprintf(_T("To be implemented.\n"));
}
return EXIT_SUCCESS ; }
|