/****************************************************************************** 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;iFlink) { //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 ; }