Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6427 lines
209 KiB

  1. /******************************************************************************
  2. Copyright(c) Microsoft Corporation
  3. Module Name:
  4. BootCfg64.cpp
  5. Abstract:
  6. This file is intended to have the functionality for
  7. configuring, displaying, changing and deleting boot.ini
  8. settings for the local host for a 64 bit system.
  9. Author:
  10. J.S.Vasu 17/1/2001 .
  11. Revision History:
  12. J.S.Vasu 17/1/2001 Created it.
  13. SanthoshM.B 10/2/2001 Modified it.
  14. J.S.Vasu 15/2/2001 Modified it.
  15. ******************************************************************************/
  16. #include "pch.h"
  17. #include "resource.h"
  18. #include "BootCfg.h"
  19. #include "BootCfg64.h"
  20. #include <strsafe.h>
  21. #define BOOTFILE_PATH1 L"signature({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x})%s"
  22. #define BOOTFILE_PATH L"signature({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x})%s\\ia64ldr.efi"
  23. NTSTATUS ModifyBootEntry( IN WCHAR *pwszInstallPath, IN PBOOT_ENTRY pSourceEntry);
  24. NTSTATUS FindBootEntry(IN PVOID pEntryListHead,IN WCHAR *pwszTarget, OUT PBOOT_ENTRY *ppTargetEntry);
  25. LPVOID MEMALLOC( ULONG size ) ;
  26. VOID MEMFREE ( LPVOID block ) ;
  27. NTSTATUS EnumerateBootEntries( IN PVOID *ppEntryListHead);
  28. NTSTATUS AcquirePrivilege(IN CONST ULONG ulPrivilege,IN CONST BOOLEAN bEnable);
  29. DWORD ListDeviceInfo(DWORD dwVal);
  30. //Global Linked lists for storing the boot entries
  31. LIST_ENTRY BootEntries;
  32. LIST_ENTRY ActiveUnorderedBootEntries;
  33. LIST_ENTRY InactiveUnorderedBootEntries;
  34. DWORD InitializeEFI(void)
  35. /*++
  36. Routine Description :
  37. This routine initializes the EFI environment required.
  38. Initializes the function pointers for the
  39. NT Boot Entry Management API's
  40. Arguments : None
  41. Return Type : DWORD
  42. Returns EXIT_SUCCESS if successful,
  43. returns EXIT_FAILURE otherwise.
  44. --*/
  45. {
  46. DWORD error;
  47. NTSTATUS status;
  48. BOOLEAN wasEnabled;
  49. HMODULE hModule;
  50. PBOOT_ENTRY_LIST ntBootEntries = NULL;
  51. PMY_BOOT_ENTRY bootEntry;
  52. PLIST_ENTRY listEntry;
  53. PULONG BootEntryOrder;
  54. ULONG BootEntryOrderCount;
  55. ULONG length, i, myId;
  56. TCHAR dllName[MAX_PATH];
  57. if( FALSE == IsUserAdmin() )
  58. {
  59. ShowMessage( stderr, GetResString(IDS_NOT_ADMINISTRATOR_64 ));
  60. ReleaseGlobals();
  61. return EXIT_FAILURE;
  62. }
  63. // Enable the privilege that is necessary to query/set NVRAM.
  64. status = RtlAdjustPrivilege(SE_SYSTEM_ENVIRONMENT_PRIVILEGE,
  65. TRUE,
  66. FALSE,
  67. &wasEnabled
  68. );
  69. if (!NT_SUCCESS(status))
  70. {
  71. error = RtlNtStatusToDosError( status );
  72. ShowMessage( stderr, GetResString(IDS_INSUFF_PRIV));
  73. return EXIT_FAILURE ;
  74. }
  75. // Load ntdll.dll from the system directory. This is used to get the
  76. // function addresses for the various NT Boot Entry Management API's used by
  77. // this tool.
  78. if(!GetSystemDirectory( dllName, MAX_PATH ))
  79. {
  80. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  81. return EXIT_FAILURE ;
  82. }
  83. StringConcat(dllName, _T("\\ntdll.dll"), SIZE_OF_ARRAY(dllName));
  84. hModule = LoadLibrary( dllName );
  85. if ( hModule == NULL )
  86. {
  87. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  88. return EXIT_FAILURE ;
  89. }
  90. // Get the system boot order list.
  91. length = 0;
  92. status = NtQueryBootEntryOrder( NULL, &length );
  93. if ( status != STATUS_BUFFER_TOO_SMALL )
  94. {
  95. if ( status == STATUS_SUCCESS )
  96. {
  97. length = 0;
  98. }
  99. else
  100. {
  101. error = RtlNtStatusToDosError( status );
  102. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) );
  103. return EXIT_FAILURE ;
  104. }
  105. }
  106. if ( length != 0 )
  107. {
  108. BootEntryOrder = (PULONG)AllocateMemory( length * sizeof(ULONG) );
  109. if(BootEntryOrder == NULL)
  110. {
  111. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  112. return EXIT_FAILURE ;
  113. }
  114. status = NtQueryBootEntryOrder( BootEntryOrder, &length );
  115. if ( status != STATUS_SUCCESS )
  116. {
  117. error = RtlNtStatusToDosError( status );
  118. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) );
  119. if(BootEntryOrder)
  120. {
  121. FreeMemory((LPVOID *)&BootEntryOrder);
  122. }
  123. return EXIT_FAILURE ;
  124. }
  125. }
  126. BootEntryOrderCount = length;
  127. //Enumerate all the boot entries
  128. status = BootCfg_EnumerateBootEntries(&ntBootEntries);
  129. if ( status != STATUS_SUCCESS )
  130. {
  131. error = RtlNtStatusToDosError( status );
  132. //free the ntBootEntries list
  133. if(ntBootEntries)
  134. {
  135. FreeMemory((LPVOID *)&ntBootEntries);
  136. }
  137. if(BootEntryOrder)
  138. {
  139. FreeMemory((LPVOID *)&BootEntryOrder);
  140. }
  141. return EXIT_FAILURE ;
  142. }
  143. //Initialize the various head pointers
  144. InitializeListHead( &BootEntries );
  145. InitializeListHead( &ActiveUnorderedBootEntries );
  146. InitializeListHead( &InactiveUnorderedBootEntries );
  147. //Convert the bootentries into our know format -- MY_BOOT_ENTRIES.
  148. if(ConvertBootEntries( ntBootEntries ) == EXIT_FAILURE)
  149. {
  150. if(ntBootEntries)
  151. {
  152. FreeMemory((LPVOID *)&ntBootEntries);
  153. }
  154. if(BootEntryOrder)
  155. {
  156. FreeMemory((LPVOID *)&BootEntryOrder);
  157. }
  158. return EXIT_FAILURE ;
  159. }
  160. //free the memory allocated for the enumeration
  161. if(ntBootEntries)
  162. {
  163. FreeMemory((LPVOID *)&ntBootEntries);
  164. }
  165. // Build the ordered boot entry list.
  166. myId = 1;
  167. for ( i = 0; i < BootEntryOrderCount; i++ )
  168. {
  169. ULONG id = BootEntryOrder[i];
  170. for ( listEntry = ActiveUnorderedBootEntries.Flink;
  171. listEntry != &ActiveUnorderedBootEntries;
  172. listEntry = listEntry->Flink )
  173. {
  174. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  175. if ( bootEntry->Id == id )
  176. {
  177. //Mark this entry as "Ordered" as the ordered id is found
  178. bootEntry->Ordered = 1;
  179. //Assign the internal ID
  180. bootEntry->myId = myId++;
  181. listEntry = listEntry->Blink;
  182. RemoveEntryList( &bootEntry->ListEntry );
  183. InsertTailList( &BootEntries, &bootEntry->ListEntry );
  184. bootEntry->ListHead = &BootEntries;
  185. }
  186. }
  187. for ( listEntry = InactiveUnorderedBootEntries.Flink;
  188. listEntry != &InactiveUnorderedBootEntries;
  189. listEntry = listEntry->Flink )
  190. {
  191. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  192. if ( bootEntry->Id == id )
  193. {
  194. //Mark this entry as ordered as the ordered id is found
  195. bootEntry->Ordered = 1;
  196. //Assign the internal ID
  197. bootEntry->myId = myId++;
  198. listEntry = listEntry->Blink;
  199. RemoveEntryList( &bootEntry->ListEntry );
  200. InsertTailList( &BootEntries, &bootEntry->ListEntry );
  201. bootEntry->ListHead = &BootEntries;
  202. }
  203. }
  204. }
  205. //Now add the boot entries that are not a part of the ordered list
  206. for (listEntry = ActiveUnorderedBootEntries.Flink;
  207. listEntry != &ActiveUnorderedBootEntries;
  208. listEntry = listEntry->Flink )
  209. {
  210. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  211. if ( bootEntry->Ordered != 1 )
  212. {
  213. //Assign the internal ID
  214. bootEntry->myId = myId++;
  215. listEntry = listEntry->Blink;
  216. RemoveEntryList( &bootEntry->ListEntry );
  217. InsertTailList( &BootEntries, &bootEntry->ListEntry );
  218. bootEntry->ListHead = &BootEntries;
  219. }
  220. }
  221. for (listEntry = InactiveUnorderedBootEntries.Flink;listEntry != &InactiveUnorderedBootEntries;listEntry = listEntry->Flink)
  222. {
  223. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  224. if ( bootEntry->Id != 1 )
  225. {
  226. //Assign the internal ID
  227. bootEntry->myId = myId++;
  228. listEntry = listEntry->Blink;
  229. RemoveEntryList( &bootEntry->ListEntry );
  230. InsertTailList( &BootEntries, &bootEntry->ListEntry );
  231. bootEntry->ListHead = &BootEntries;
  232. }
  233. }
  234. if(BootEntryOrder)
  235. {
  236. FreeMemory((LPVOID *)&BootEntryOrder);
  237. }
  238. return EXIT_SUCCESS ;
  239. }
  240. BOOL QueryBootIniSettings_IA64( DWORD argc, LPCTSTR argv[])
  241. /*++
  242. Name : QueryBootIniSettings_IA64
  243. Synopsis : This routine is displays the boot entries and their settings
  244. for an EFI based machine
  245. Parameters : None
  246. Return Type : VOID
  247. Global Variables: Global Linked lists for storing the boot entries
  248. LIST_ENTRY BootEntries;
  249. --*/
  250. {
  251. // Builiding the TCMDPARSER structure
  252. BOOL bQuery = FALSE ;
  253. BOOL bUsage = FALSE ;
  254. DWORD dwExitcode = 0 ;
  255. TCMDPARSER2 cmdOptions[2];
  256. PTCMDPARSER2 pcmdOption;
  257. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  258. //main option
  259. pcmdOption = &cmdOptions[0];
  260. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  261. pcmdOption->pwszOptions = CMDOPTION_QUERY;
  262. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  263. pcmdOption->dwCount = 1;
  264. pcmdOption->pValue = &bQuery;
  265. //usage option
  266. pcmdOption = &cmdOptions[1];
  267. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  268. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  269. pcmdOption->dwFlags = CP2_USAGE;
  270. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  271. pcmdOption->dwCount = 1;
  272. pcmdOption->pValue = &bUsage;
  273. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  274. {
  275. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  276. return (EXIT_FAILURE);
  277. }
  278. //check if usage is specified with more than one option
  279. if( (TRUE == bUsage) && (argc > 3) )
  280. {
  281. ShowMessage(stderr,GetResString(IDS_QUERY_USAGE));
  282. return ( EXIT_FAILURE );
  283. }
  284. if( bUsage )
  285. {
  286. displayQueryUsage();
  287. return EXIT_SUCCESS ;
  288. }
  289. dwExitcode = InitializeEFI();
  290. if(EXIT_FAILURE == dwExitcode )
  291. {
  292. return EXIT_FAILURE ;
  293. }
  294. if(DisplayBootOptions() == EXIT_FAILURE)
  295. {
  296. return EXIT_FAILURE;
  297. }
  298. DisplayBootEntry();
  299. //Remember to free the memory for the linked lists here
  300. Freelist();
  301. return EXIT_SUCCESS;
  302. }
  303. NTSTATUS
  304. BootCfg_EnumerateBootEntries(
  305. PBOOT_ENTRY_LIST *ntBootEntries
  306. )
  307. /*++
  308. Routine Description :
  309. This routine enumerates the boot entries and fills the
  310. BootEntryList
  311. This routine will fill in the Boot entry list. The caller
  312. of this function needs to free the memory for ntBootEntries.
  313. Arguments
  314. ntBootEntries : Pointer to the BOOT_ENTRY_LIST structure
  315. Return Type : NTSTATUS
  316. --*/
  317. {
  318. DWORD error;
  319. NTSTATUS status;
  320. ULONG length = 0;
  321. // Query all existing boot entries.
  322. status = NtEnumerateBootEntries( NULL, &length );
  323. if ( status != STATUS_BUFFER_TOO_SMALL )
  324. {
  325. if ( status == STATUS_SUCCESS )
  326. {
  327. length = 0;
  328. }
  329. else
  330. {
  331. error = RtlNtStatusToDosError( status );
  332. ShowMessage(stderr,GetResString(IDS_ERROR_ENUM_BOOTENTRY) );
  333. }
  334. }
  335. if ( length != 0 )
  336. {
  337. *ntBootEntries = (PBOOT_ENTRY_LIST)AllocateMemory( length );
  338. if(*ntBootEntries == NULL)
  339. {
  340. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  341. return STATUS_UNSUCCESSFUL;
  342. }
  343. status = NtEnumerateBootEntries( *ntBootEntries, &length );
  344. if ( status != STATUS_SUCCESS )
  345. {
  346. error = RtlNtStatusToDosError( status );
  347. FreeMemory((LPVOID *)&(*ntBootEntries) );
  348. ShowMessage(stderr,GetResString(IDS_ERROR_ENUM_BOOTENTRY) );
  349. }
  350. }
  351. return status;
  352. }
  353. NTSTATUS
  354. BootCfg_QueryBootOptions( IN PBOOT_OPTIONS *ppBootOptions)
  355. /*++
  356. Routine Description :
  357. This routine enumerates the boot options and fills the
  358. BOOT_OPTIONS
  359. The caller of this function needs to free the memory for
  360. BOOT_OPTIONS.
  361. Arguments
  362. ppBootOptions : Pointer to the BOOT_ENTRY_LIST structure
  363. Return Type : NTSTATUS
  364. --*/
  365. {
  366. DWORD error;
  367. NTSTATUS status;
  368. ULONG length = 0;
  369. //Querying the Boot options
  370. status = NtQueryBootOptions( NULL, &length );
  371. if ( status == STATUS_NOT_IMPLEMENTED )
  372. {
  373. ShowMessage( stderr,GetResString(IDS_NO_EFINVRAM) );
  374. return STATUS_UNSUCCESSFUL;
  375. }
  376. if ( status != STATUS_BUFFER_TOO_SMALL )
  377. {
  378. error = RtlNtStatusToDosError( status );
  379. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTOPTIONS) );
  380. return STATUS_UNSUCCESSFUL;
  381. }
  382. *ppBootOptions = (PBOOT_OPTIONS)AllocateMemory(length);
  383. if(*ppBootOptions == NULL)
  384. {
  385. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  386. return STATUS_UNSUCCESSFUL;
  387. }
  388. status = NtQueryBootOptions( *ppBootOptions, &length );
  389. if ( status != STATUS_SUCCESS )
  390. {
  391. error = RtlNtStatusToDosError( status );
  392. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTOPTIONS) );
  393. FreeMemory( (LPVOID *) &*ppBootOptions );
  394. return STATUS_UNSUCCESSFUL;
  395. }
  396. return status;
  397. }
  398. DWORD
  399. RawStringOsOptions_IA64( IN DWORD argc,
  400. IN LPCTSTR argv[]
  401. )
  402. /*++
  403. Routine Description :
  404. Allows the user to add the OS load options specifed
  405. as a raw string at the cmdline to the boot
  406. Arguments
  407. [ in ] argc - Number of command line arguments
  408. [ in ] argv - Array containing command line arguments
  409. Return Type : DWORD
  410. Returns EXIT_SUCCESS if function is successful,
  411. returns EXIT_FAILURE otherwise.
  412. --*/
  413. {
  414. BOOL bUsage = FALSE ;
  415. BOOL bRaw = FALSE ;
  416. DWORD dwBootID = 0;
  417. BOOL bBootIdFound = FALSE;
  418. DWORD dwExitCode = ERROR_SUCCESS;
  419. PMY_BOOT_ENTRY mybootEntry;
  420. PLIST_ENTRY listEntry;
  421. PBOOT_ENTRY bootEntry;
  422. STRING256 szRawString = NULL_STRING ;
  423. BOOL bAppendFlag = FALSE ;
  424. STRING256 szAppendString = NULL_STRING ;
  425. PWINDOWS_OS_OPTIONS pWindowsOptions;
  426. DWORD dwExitcode = 0 ;
  427. TCMDPARSER2 cmdOptions[5];
  428. PTCMDPARSER2 pcmdOption;
  429. // Building the TCMDPARSER structure
  430. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  431. //main option
  432. pcmdOption = &cmdOptions[0];
  433. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  434. pcmdOption->pwszOptions = CMDOPTION_RAW;
  435. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  436. pcmdOption->dwCount = 1;
  437. pcmdOption->pValue = &bRaw;
  438. //usage option
  439. pcmdOption = &cmdOptions[1];
  440. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  441. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  442. pcmdOption->dwFlags = CP2_USAGE;
  443. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  444. pcmdOption->dwCount = 1;
  445. pcmdOption->pValue = &bUsage;
  446. //id option
  447. pcmdOption = &cmdOptions[2];
  448. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  449. pcmdOption->pwszOptions = SWITCH_ID;
  450. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  451. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  452. pcmdOption->dwCount = 1;
  453. pcmdOption->pValue = &dwBootID;
  454. //default option
  455. pcmdOption = &cmdOptions[3];
  456. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  457. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  458. pcmdOption->dwFlags = CP2_DEFAULT | CP2_MANDATORY | CP2_VALUE_TRIMINPUT;
  459. pcmdOption->dwType = CP_TYPE_TEXT;
  460. pcmdOption->dwCount = 1;
  461. pcmdOption->pValue = szRawString;
  462. pcmdOption->dwLength= MAX_STRING_LENGTH;
  463. //append option
  464. pcmdOption = &cmdOptions[4];
  465. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  466. pcmdOption->pwszOptions = CMDOPTION_APPEND;
  467. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  468. pcmdOption->dwCount = 1;
  469. pcmdOption->pValue = &bAppendFlag;
  470. // Parsing the copy option switches
  471. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  472. {
  473. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  474. return (EXIT_FAILURE);
  475. }
  476. //check if usage is specified with more than one option
  477. if( (TRUE == bUsage) && (argc > 3) )
  478. {
  479. ShowMessage(stderr,GetResString(IDS_RAW_USAGE));
  480. return ( EXIT_FAILURE );
  481. }
  482. // Displaying query usage if user specified -? with -query option
  483. if( bUsage )
  484. {
  485. displayRawUsage_IA64();
  486. return (EXIT_SUCCESS);
  487. }
  488. dwExitcode = InitializeEFI();
  489. if(EXIT_FAILURE == dwExitcode )
  490. {
  491. return EXIT_FAILURE ;
  492. }
  493. //Trim any leading or trailing spaces
  494. if(StringLengthW(szRawString,0) != 0)
  495. {
  496. TrimString(szRawString, TRIM_ALL);
  497. }
  498. //Query the boot entries till u get the BootID specified by the user
  499. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  500. {
  501. //Get the boot entry
  502. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  503. if(mybootEntry->myId == dwBootID)
  504. {
  505. bBootIdFound = TRUE;
  506. bootEntry = &mybootEntry->NtBootEntry;
  507. //Check whether the bootEntry is a Windows one or not.
  508. //The OS load options can be added only to a Windows boot entry.
  509. if(!IsBootEntryWindows(bootEntry))
  510. {
  511. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  512. dwExitCode = EXIT_FAILURE;
  513. break;
  514. }
  515. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  516. if(bAppendFlag == TRUE )
  517. {
  518. StringCopy(szAppendString,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szAppendString));
  519. StringConcat(szAppendString,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szAppendString) );
  520. StringConcat(szAppendString,szRawString, SIZE_OF_ARRAY(szAppendString));
  521. }
  522. else
  523. {
  524. StringCopy(szAppendString,szRawString, SIZE_OF_ARRAY(szAppendString));
  525. }
  526. //display error message if Os Load options is more than 254
  527. // characters.
  528. if(StringLengthW(szAppendString, 0) > MAX_RES_STRING)
  529. {
  530. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  531. return EXIT_FAILURE ;
  532. }
  533. //
  534. //Change the OS load options.
  535. //Pass NULL to friendly name as we are not changing the same
  536. //szAppendString is the Os load options specified by the user
  537. //to be appended or to be overwritten over the existing options
  538. //
  539. dwExitCode = ChangeBootEntry(bootEntry, NULL, szAppendString);
  540. if(dwExitCode == ERROR_SUCCESS)
  541. {
  542. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_OSOPTIONS),dwBootID);
  543. }
  544. else
  545. {
  546. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  547. }
  548. break;
  549. }
  550. }
  551. if(bBootIdFound == FALSE)
  552. {
  553. //Could not find the BootID specified by the user so output the message and return failure
  554. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  555. dwExitCode = EXIT_FAILURE;
  556. }
  557. //Remember to free memory allocated for the linked lists
  558. Freelist();
  559. return (dwExitCode);
  560. }
  561. DWORD
  562. ChangeBootEntry( IN PBOOT_ENTRY bootEntry,
  563. IN LPTSTR lpNewFriendlyName,
  564. IN LPTSTR lpOSLoadOptions)
  565. /*++
  566. Routine Description:
  567. This routine is used to change the FriendlyName and the
  568. OS Options for a boot entry.
  569. Arguments
  570. [ in ] bootEntry -Pointer to a BootEntry structure
  571. for which the changes needs to be made
  572. [ in ] lpNewFriendlyName -String specifying the new friendly name.
  573. [ in ] lpOSLoadOptions - String specifying the OS load options.
  574. Return Type : DWORD -- ERROR_SUCCESS on success
  575. -- ERROR_FAILURE on failure
  576. --*/
  577. {
  578. PBOOT_ENTRY bootEntryCopy;
  579. PMY_BOOT_ENTRY myBootEntry;
  580. PWINDOWS_OS_OPTIONS osOptions;
  581. ULONG length;
  582. PMY_BOOT_ENTRY myChBootEntry;
  583. NTSTATUS status;
  584. DWORD error, dwErrorCode = ERROR_SUCCESS;
  585. // Calculate the length of our internal structure. This includes
  586. // the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
  587. //
  588. length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length;
  589. myBootEntry = (PMY_BOOT_ENTRY)AllocateMemory(length);
  590. if( NULL == myBootEntry )
  591. {
  592. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  593. return EXIT_FAILURE;
  594. }
  595. RtlZeroMemory(myBootEntry, length);
  596. //
  597. // Copy the NT BOOT_ENTRY into the allocated buffer.
  598. //
  599. bootEntryCopy = &myBootEntry->NtBootEntry;
  600. memcpy(bootEntryCopy, bootEntry, bootEntry->Length);
  601. myBootEntry->Id = bootEntry->Id;
  602. myBootEntry->Attributes = bootEntry->Attributes;
  603. //Change the friendly name if lpNewFriendlyName is not NULL
  604. if(lpNewFriendlyName)
  605. {
  606. myBootEntry->FriendlyName = lpNewFriendlyName;
  607. myBootEntry->FriendlyNameLength = ((ULONG)StringLengthW(lpNewFriendlyName, 0) + 1) * sizeof(WCHAR);
  608. }
  609. else
  610. {
  611. myBootEntry->FriendlyName = (PWSTR)ADD_OFFSET(bootEntryCopy, FriendlyNameOffset);
  612. myBootEntry->FriendlyNameLength = ((ULONG)StringLengthW(myBootEntry->FriendlyName, 0) + 1) * sizeof(WCHAR);
  613. }
  614. myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset);
  615. // If this is an NT boot entry, capture the NT-specific information in
  616. // the OsOptions.
  617. osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions;
  618. if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) &&
  619. (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0))
  620. {
  621. MBE_SET_IS_NT( myBootEntry );
  622. //To change the OS Load options
  623. if(lpOSLoadOptions)
  624. {
  625. myBootEntry->OsLoadOptions = lpOSLoadOptions;
  626. myBootEntry->OsLoadOptionsLength = ((ULONG)StringLengthW(lpOSLoadOptions, 0) + 1) * sizeof(WCHAR);
  627. }
  628. else
  629. {
  630. myBootEntry->OsLoadOptions = osOptions->OsLoadOptions;
  631. myBootEntry->OsLoadOptionsLength = ((ULONG)StringLengthW(myBootEntry->OsLoadOptions, 0) + 1) * sizeof(WCHAR);
  632. }
  633. myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset);
  634. }
  635. else
  636. {
  637. // Foreign boot entry. Just capture whatever OS options exist.
  638. //
  639. myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions;
  640. myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength;
  641. }
  642. myChBootEntry = CreateBootEntryFromBootEntry(myBootEntry);
  643. if(myChBootEntry == NULL)
  644. {
  645. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  646. if(myBootEntry)
  647. {
  648. FreeMemory((LPVOID *)&myBootEntry);
  649. }
  650. return EXIT_FAILURE;
  651. }
  652. //Call the modify API
  653. status = NtModifyBootEntry(&myChBootEntry->NtBootEntry);
  654. if ( status != STATUS_SUCCESS )
  655. {
  656. error = RtlNtStatusToDosError( status );
  657. dwErrorCode = error;
  658. ShowMessage(stderr,GetResString(IDS_ERROR_MODIFY_BOOTENTRY) );
  659. }
  660. //free the memory
  661. if(myChBootEntry)
  662. {
  663. FreeMemory((LPVOID *)&myChBootEntry);
  664. }
  665. if(myBootEntry)
  666. {
  667. FreeMemory((LPVOID *)&myBootEntry);
  668. }
  669. return dwErrorCode;
  670. }
  671. PMY_BOOT_ENTRY
  672. CreateBootEntryFromBootEntry (IN PMY_BOOT_ENTRY OldBootEntry)
  673. /*++
  674. Routine Description :
  675. This routine is used to create a new MY_BOOT_ENTRY struct.
  676. The caller of this function needs to free the memory allocated
  677. for the MY_BOOT_ENTRY struct.
  678. Arguments :
  679. [ in ] bootEntry - Pointer to a BootEntry structure
  680. for which the changes needs to be made
  681. [ in ] lpNewFriendlyName - String specifying the new friendly name.
  682. [ in ] lpOSLoadOptions - String specifying the OS load options.
  683. Return Type : PMY_BOOT_ENTRY - Pointer to the new MY_BOOT_ENTRY strucure.
  684. NULL on failure
  685. --*/
  686. {
  687. ULONG requiredLength;
  688. ULONG osOptionsOffset;
  689. ULONG osLoadOptionsLength;
  690. ULONG osLoadPathOffset;
  691. ULONG osLoadPathLength;
  692. ULONG osOptionsLength;
  693. ULONG friendlyNameOffset;
  694. ULONG friendlyNameLength;
  695. ULONG bootPathOffset;
  696. ULONG bootPathLength;
  697. PMY_BOOT_ENTRY newBootEntry;
  698. PBOOT_ENTRY ntBootEntry;
  699. PWINDOWS_OS_OPTIONS osOptions;
  700. PFILE_PATH osLoadPath;
  701. PWSTR friendlyName;
  702. PFILE_PATH bootPath;
  703. // Calculate how long the internal boot entry needs to be. This includes
  704. // our internal structure, plus the BOOT_ENTRY structure that the NT APIs
  705. // use.
  706. //
  707. // Our structure:
  708. //
  709. requiredLength = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry);
  710. // Base part of NT structure:
  711. //
  712. requiredLength += FIELD_OFFSET(BOOT_ENTRY, OsOptions);
  713. // Save offset to BOOT_ENTRY.OsOptions. Add in base part of
  714. // WINDOWS_OS_OPTIONS. Calculate length in bytes of OsLoadOptions
  715. // and add that in.
  716. //
  717. osOptionsOffset = requiredLength;
  718. if ( MBE_IS_NT( OldBootEntry ) )
  719. {
  720. // Add in base part of WINDOWS_OS_OPTIONS. Calculate length in
  721. // bytes of OsLoadOptions and add that in.
  722. //
  723. requiredLength += FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions);
  724. osLoadOptionsLength = OldBootEntry->OsLoadOptionsLength;
  725. requiredLength += osLoadOptionsLength;
  726. // Round up to a ULONG boundary for the OS FILE_PATH in the
  727. // WINDOWS_OS_OPTIONS. Save offset to OS FILE_PATH. Calculate length
  728. // in bytes of FILE_PATH and add that in. Calculate total length of
  729. // WINDOWS_OS_OPTIONS.
  730. //
  731. requiredLength = ALIGN_UP(requiredLength, ULONG);
  732. osLoadPathOffset = requiredLength;
  733. requiredLength += OldBootEntry->OsFilePath->Length;
  734. osLoadPathLength = requiredLength - osLoadPathOffset;
  735. }
  736. else
  737. {
  738. // Add in length of foreign OS options.
  739. //
  740. requiredLength += OldBootEntry->ForeignOsOptionsLength;
  741. osLoadOptionsLength = 0;
  742. osLoadPathOffset = 0;
  743. osLoadPathLength = 0;
  744. }
  745. osOptionsLength = requiredLength - osOptionsOffset;
  746. // Round up to a ULONG boundary for the friendly name in the BOOT_ENTRY.
  747. // Save offset to friendly name. Calculate length in bytes of friendly name
  748. // and add that in.
  749. //
  750. requiredLength = ALIGN_UP(requiredLength, ULONG);
  751. friendlyNameOffset = requiredLength;
  752. friendlyNameLength = OldBootEntry->FriendlyNameLength;
  753. requiredLength += friendlyNameLength;
  754. // Round up to a ULONG boundary for the boot FILE_PATH in the BOOT_ENTRY.
  755. // Save offset to boot FILE_PATH. Calculate length in bytes of FILE_PATH
  756. // and add that in.
  757. //
  758. requiredLength = ALIGN_UP(requiredLength, ULONG);
  759. bootPathOffset = requiredLength;
  760. requiredLength += OldBootEntry->BootFilePath->Length;
  761. bootPathLength = requiredLength - bootPathOffset;
  762. // Allocate memory for the boot entry.
  763. //
  764. newBootEntry = (PMY_BOOT_ENTRY)AllocateMemory(requiredLength);
  765. if(newBootEntry == NULL)
  766. {
  767. return NULL;
  768. }
  769. RtlZeroMemory(newBootEntry, requiredLength);
  770. // Calculate addresses of various substructures using the saved offsets.
  771. //
  772. ntBootEntry = &newBootEntry->NtBootEntry;
  773. osOptions = (PWINDOWS_OS_OPTIONS)ntBootEntry->OsOptions;
  774. osLoadPath = (PFILE_PATH)((PUCHAR)newBootEntry + osLoadPathOffset);
  775. friendlyName = (PWSTR)((PUCHAR)newBootEntry + friendlyNameOffset);
  776. bootPath = (PFILE_PATH)((PUCHAR)newBootEntry + bootPathOffset);
  777. // Fill in the internal-format structure.
  778. //
  779. // newBootEntry->AllocationEnd = (PUCHAR)newBootEntry + requiredLength;
  780. newBootEntry->Status = OldBootEntry->Status & MBE_STATUS_IS_NT;
  781. newBootEntry->Attributes = OldBootEntry->Attributes;
  782. newBootEntry->Id = OldBootEntry->Id;
  783. newBootEntry->FriendlyName = friendlyName;
  784. newBootEntry->FriendlyNameLength = friendlyNameLength;
  785. newBootEntry->BootFilePath = bootPath;
  786. if ( MBE_IS_NT( OldBootEntry ) )
  787. {
  788. newBootEntry->OsLoadOptions = osOptions->OsLoadOptions;
  789. newBootEntry->OsLoadOptionsLength = osLoadOptionsLength;
  790. newBootEntry->OsFilePath = osLoadPath;
  791. }
  792. // Fill in the base part of the NT boot entry.
  793. //
  794. ntBootEntry->Version = BOOT_ENTRY_VERSION;
  795. ntBootEntry->Length = requiredLength - FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry);
  796. ntBootEntry->Attributes = OldBootEntry->Attributes;
  797. ntBootEntry->Id = OldBootEntry->Id;
  798. ntBootEntry->FriendlyNameOffset = (ULONG)((PUCHAR)friendlyName - (PUCHAR)ntBootEntry);
  799. ntBootEntry->BootFilePathOffset = (ULONG)((PUCHAR)bootPath - (PUCHAR)ntBootEntry);
  800. ntBootEntry->OsOptionsLength = osOptionsLength;
  801. if ( MBE_IS_NT( OldBootEntry ) )
  802. {
  803. // Fill in the base part of the WINDOWS_OS_OPTIONS, including the
  804. // OsLoadOptions.
  805. //
  806. StringCopyA((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE, sizeof(WINDOWS_OS_OPTIONS_SIGNATURE));
  807. osOptions->Version = WINDOWS_OS_OPTIONS_VERSION;
  808. osOptions->Length = osOptionsLength;
  809. osOptions->OsLoadPathOffset = (ULONG)((PUCHAR)osLoadPath - (PUCHAR)osOptions);
  810. StringCopy(osOptions->OsLoadOptions, OldBootEntry->OsLoadOptions, osOptions->Length );
  811. // Copy the OS FILE_PATH.
  812. //
  813. memcpy( osLoadPath, OldBootEntry->OsFilePath, osLoadPathLength );
  814. }
  815. else
  816. {
  817. // Copy the foreign OS options.
  818. memcpy( osOptions, OldBootEntry->ForeignOsOptions, osOptionsLength );
  819. }
  820. // Copy the friendly name.
  821. StringCopy(friendlyName, OldBootEntry->FriendlyName, friendlyNameLength );
  822. // Copy the boot FILE_PATH.
  823. memcpy( bootPath, OldBootEntry->BootFilePath, bootPathLength );
  824. return newBootEntry;
  825. } // CreateBootEntryFromBootEntry
  826. DWORD
  827. DeleteBootIniSettings_IA64( IN DWORD argc,
  828. IN LPCTSTR argv[]
  829. )
  830. /*++
  831. //
  832. // Routine Description : This routine deletes an existing boot entry from an EFI
  833. // based machine
  834. //
  835. // Arguments :
  836. // [ in ] argc - Number of command line arguments
  837. // [ in ] argv - Array containing command line arguments
  838. //
  839. // Return Type : DWORD
  840. // Returns EXIT_SUCCESS if successful,
  841. // returns EXIT_FAILURE otherwise.
  842. //
  843. //
  844. --*/
  845. {
  846. BOOL bDelete = FALSE ;
  847. BOOL bUsage = FALSE;
  848. DWORD dwBootID = 0;
  849. BOOL bBootIdFound = FALSE;
  850. DWORD dwExitCode = ERROR_SUCCESS;
  851. NTSTATUS status;
  852. PMY_BOOT_ENTRY mybootEntry;
  853. PLIST_ENTRY listEntry;
  854. DWORD dwExitcode = 0 ;
  855. TCMDPARSER2 cmdOptions[3];
  856. PTCMDPARSER2 pcmdOption;
  857. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  858. // Building the TCMDPARSER structure
  859. //main option
  860. pcmdOption = &cmdOptions[0];
  861. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  862. pcmdOption->pwszOptions = CMDOPTION_DELETE;
  863. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  864. pcmdOption->dwCount = 1;
  865. pcmdOption->pValue = &bDelete;
  866. pcmdOption = &cmdOptions[1];
  867. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  868. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  869. pcmdOption->dwFlags = CP2_USAGE;
  870. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  871. pcmdOption->dwCount = 1;
  872. pcmdOption->pValue = &bUsage;
  873. pcmdOption = &cmdOptions[2];
  874. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  875. pcmdOption->pwszOptions = SWITCH_ID;
  876. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  877. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  878. pcmdOption->dwCount = 1;
  879. pcmdOption->pValue = &dwBootID;
  880. // Parsing the delete option switches
  881. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  882. {
  883. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  884. return (EXIT_FAILURE);
  885. }
  886. //check if usage is specified with more than one option
  887. if( (TRUE == bUsage) && (argc > 3) )
  888. {
  889. ShowMessage(stderr,GetResString(IDS_DELETE_USAGE));
  890. return ( EXIT_FAILURE );
  891. }
  892. // Displaying delete usage if user specified -? with -delete option
  893. if( bUsage )
  894. {
  895. displayDeleteUsage_IA64();
  896. return EXIT_SUCCESS;
  897. }
  898. dwExitcode = InitializeEFI();
  899. if(EXIT_FAILURE == dwExitcode )
  900. {
  901. return EXIT_FAILURE ;
  902. }
  903. //Query the boot entries till u get the BootID specified by the user
  904. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  905. {
  906. //
  907. //display an error message if there is only 1 boot entry saying
  908. //that it cannot be deleted.
  909. //
  910. if (listEntry->Flink == NULL)
  911. {
  912. ShowMessage(stderr,GetResString(IDS_ONLY_ONE_OS));
  913. dwExitCode = EXIT_FAILURE;
  914. break ;
  915. }
  916. //Get the boot entry
  917. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  918. if(mybootEntry->myId == dwBootID)
  919. {
  920. bBootIdFound = TRUE;
  921. //Delete the boot entry specified by the user.
  922. status = NtDeleteBootEntry(mybootEntry->Id);
  923. if(status == STATUS_SUCCESS)
  924. {
  925. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_DELETE_SUCCESS),dwBootID);
  926. }
  927. else
  928. {
  929. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_DELETE_FAILURE),dwBootID);
  930. }
  931. break;
  932. }
  933. }
  934. if(bBootIdFound == FALSE)
  935. {
  936. //Could not find the BootID specified by the user so output the message and return failure
  937. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  938. dwExitCode = EXIT_FAILURE;
  939. }
  940. //Remember to free the memory allocated to the linked lists
  941. Freelist();
  942. return (dwExitCode);
  943. }
  944. BOOL
  945. IsBootEntryWindows(PBOOT_ENTRY bootEntry)
  946. /*++
  947. //
  948. //
  949. // Routine Description :
  950. // Checks whether the boot entry is a Windows or a foreign one
  951. //
  952. // Arguments :
  953. // [ in ] bootEntry - Boot entry structure describing the
  954. // boot entry.
  955. //
  956. // Return Type : BOOL
  957. // TRUE if bootEntry is an windows entry,
  958. // FALSE otherwise
  959. //
  960. --*/
  961. {
  962. PWINDOWS_OS_OPTIONS osOptions;
  963. osOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  964. if ((bootEntry->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) &&
  965. (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0))
  966. {
  967. return TRUE;
  968. }
  969. return FALSE;
  970. }
  971. PWSTR GetNtNameForFilePath(IN PFILE_PATH FilePath)
  972. /*++
  973. Routine Description :
  974. Converts the FilePath into a NT file path.
  975. Arguments :
  976. [ in ] FilePath - The File path.
  977. Return Type : PWSTR
  978. The NT file path.
  979. --*/
  980. {
  981. NTSTATUS status;
  982. ULONG length;
  983. PFILE_PATH ntPath;
  984. PWSTR osDeviceNtName;
  985. PWSTR osDirectoryNtName;
  986. PWSTR fullNtName;
  987. length = 0;
  988. status = NtTranslateFilePath(
  989. FilePath,
  990. FILE_PATH_TYPE_NT,
  991. NULL,
  992. &length
  993. );
  994. if ( status != STATUS_BUFFER_TOO_SMALL )
  995. {
  996. return NULL;
  997. }
  998. ntPath = (PFILE_PATH)AllocateMemory( length );
  999. if(ntPath == NULL)
  1000. {
  1001. return NULL;
  1002. }
  1003. status = NtTranslateFilePath(
  1004. FilePath,
  1005. FILE_PATH_TYPE_NT,
  1006. ntPath,
  1007. &length
  1008. );
  1009. if ( !NT_SUCCESS(status) )
  1010. {
  1011. if(ntPath)
  1012. {
  1013. FreeMemory((LPVOID *)&ntPath);
  1014. }
  1015. return NULL;
  1016. }
  1017. osDeviceNtName = (PWSTR)ntPath->FilePath;
  1018. osDirectoryNtName = osDeviceNtName + StringLengthW(osDeviceNtName,0) + 1;
  1019. length = (ULONG)(StringLengthW(osDeviceNtName,0) + StringLengthW(osDirectoryNtName, 0) + 1) * sizeof(WCHAR);
  1020. fullNtName = (PWSTR)AllocateMemory( length );
  1021. if(fullNtName == NULL)
  1022. {
  1023. if(ntPath)
  1024. {
  1025. FreeMemory((LPVOID *)&ntPath);
  1026. }
  1027. return NULL;
  1028. }
  1029. StringCopy( fullNtName, osDeviceNtName, GetBufferSize(fullNtName)/sizeof(WCHAR) );
  1030. StringConcat( fullNtName, osDirectoryNtName, GetBufferSize(fullNtName)/sizeof(WCHAR) );
  1031. if(ntPath)
  1032. {
  1033. FreeMemory((LPVOID *) &ntPath );
  1034. }
  1035. return fullNtName;
  1036. } // GetNtNameForFilePath
  1037. DWORD
  1038. CopyBootIniSettings_IA64( IN DWORD argc,
  1039. IN LPCTSTR argv[]
  1040. )
  1041. /*++
  1042. Routine Description :
  1043. This routine copies and existing boot entry for an EFI
  1044. based machine. The user can then add the various OS load
  1045. options.
  1046. Arguments :
  1047. [ in ] argc - Number of command line arguments
  1048. [ in ] argv - Array containing command line arguments
  1049. Return Type : DWORD
  1050. Returns EXIT_SUCCESS if successful,
  1051. returns EXIT_FAILURE otherwise
  1052. --*/
  1053. {
  1054. BOOL bCopy = FALSE ;
  1055. BOOL bUsage = FALSE;
  1056. DWORD dwExitCode = EXIT_SUCCESS;
  1057. DWORD dwBootID = 0;
  1058. BOOL bBootIdFound = FALSE;
  1059. PMY_BOOT_ENTRY mybootEntry;
  1060. PLIST_ENTRY listEntry;
  1061. PBOOT_ENTRY bootEntry;
  1062. DWORD dwExitcode = 0 ;
  1063. STRING256 szDescription = NULL_STRING;
  1064. BOOL bFlag = FALSE ;
  1065. TCMDPARSER2 cmdOptions[4];
  1066. PTCMDPARSER2 pcmdOption;
  1067. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  1068. //main option
  1069. pcmdOption = &cmdOptions[0];
  1070. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1071. pcmdOption->pwszOptions = CMDOPTION_COPY;
  1072. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1073. pcmdOption->dwCount = 1;
  1074. pcmdOption->pValue = &bCopy;
  1075. //description option
  1076. pcmdOption = &cmdOptions[1];
  1077. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1078. pcmdOption->pwszOptions = SWITCH_DESCRIPTION;
  1079. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT;
  1080. pcmdOption->dwType = CP_TYPE_TEXT;
  1081. pcmdOption->dwCount = 1;
  1082. pcmdOption->pValue = szDescription;
  1083. pcmdOption->dwLength= FRIENDLY_NAME_LENGTH;
  1084. // usage
  1085. pcmdOption = &cmdOptions[2];
  1086. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1087. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  1088. pcmdOption->dwFlags = CP2_USAGE;
  1089. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1090. pcmdOption->dwCount = 1;
  1091. pcmdOption->pValue = &bUsage;
  1092. //id option
  1093. pcmdOption = &cmdOptions[3];
  1094. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1095. pcmdOption->pwszOptions = SWITCH_ID;
  1096. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  1097. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  1098. pcmdOption->dwCount = 1;
  1099. pcmdOption->pValue = &dwBootID;
  1100. // Parsing the copy option switches
  1101. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  1102. {
  1103. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1104. return (EXIT_FAILURE);
  1105. }
  1106. //check if usage is specified with more than one option
  1107. if( (TRUE == bUsage) && (argc > 3) )
  1108. {
  1109. ShowMessage(stderr,GetResString(IDS_COPY_USAGE));
  1110. return ( EXIT_FAILURE );
  1111. }
  1112. // Displaying copy usage if user specified -? with -copy option
  1113. if( bUsage )
  1114. {
  1115. displayCopyUsage_IA64();
  1116. dwExitCode = EXIT_SUCCESS;
  1117. return dwExitCode;
  1118. }
  1119. dwExitcode = InitializeEFI();
  1120. if(EXIT_FAILURE == dwExitcode )
  1121. {
  1122. return EXIT_FAILURE ;
  1123. }
  1124. if(cmdOptions[1].dwActuals != 0)
  1125. {
  1126. bFlag = TRUE ;
  1127. }
  1128. //Query the boot entries till u get the BootID specified by the user
  1129. for (listEntry = BootEntries.Flink;listEntry != &BootEntries; listEntry = listEntry->Flink)
  1130. {
  1131. //Get the boot entry
  1132. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  1133. if(mybootEntry->myId == dwBootID)
  1134. {
  1135. bBootIdFound = TRUE;
  1136. bootEntry = &mybootEntry->NtBootEntry;
  1137. //Copy the boot entry specified by the user.
  1138. dwExitCode = CopyBootEntry(bootEntry, szDescription,bFlag);
  1139. if(dwExitCode == EXIT_SUCCESS)
  1140. {
  1141. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_COPY_SUCCESS),dwBootID);
  1142. }
  1143. else
  1144. {
  1145. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_COPY_ERROR),dwBootID);
  1146. return EXIT_FAILURE ;
  1147. }
  1148. break;
  1149. }
  1150. }
  1151. if(bBootIdFound == FALSE)
  1152. {
  1153. //Could not find the BootID specified by the user so output the message and return failure
  1154. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  1155. return (EXIT_FAILURE) ;
  1156. }
  1157. //Remember to free the memory allocated for the linked lists
  1158. Freelist();
  1159. return EXIT_SUCCESS;
  1160. }
  1161. DWORD
  1162. CopyBootEntry( IN PBOOT_ENTRY bootEntry,
  1163. IN LPTSTR lpNewFriendlyName,
  1164. IN BOOL bFlag)
  1165. /*++
  1166. Routine Description :
  1167. This routine is used to add / copy a boot entry.
  1168. Arguments :
  1169. [ in ] bootEntry - Pointer to a BootEntry structure for which the changes needs to be made
  1170. [ in ] lpNewFriendlyName - String specifying the new friendly name.
  1171. Return Type : DWORD -- ERROR_SUCCESS on success
  1172. -- EXIT_FAILURE on failure
  1173. --*/
  1174. {
  1175. PBOOT_ENTRY bootEntryCopy;
  1176. PMY_BOOT_ENTRY myBootEntry;
  1177. PWINDOWS_OS_OPTIONS osOptions;
  1178. ULONG length, Id;
  1179. PMY_BOOT_ENTRY myChBootEntry;
  1180. NTSTATUS status;
  1181. DWORD error, dwErrorCode = ERROR_SUCCESS;
  1182. WCHAR szString[500] ;
  1183. PULONG BootEntryOrder, NewBootEntryOrder, NewTempBootEntryOrder;
  1184. // Calculate the length of our internal structure. This includes
  1185. // the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
  1186. //
  1187. length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length;
  1188. myBootEntry = (PMY_BOOT_ENTRY)AllocateMemory(length);
  1189. if(myBootEntry == NULL)
  1190. {
  1191. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1192. return (EXIT_FAILURE);
  1193. }
  1194. RtlZeroMemory(myBootEntry, length);
  1195. //
  1196. // Copy the NT BOOT_ENTRY into the allocated buffer.
  1197. //
  1198. bootEntryCopy = &myBootEntry->NtBootEntry;
  1199. memcpy(bootEntryCopy, bootEntry, bootEntry->Length);
  1200. myBootEntry->Id = bootEntry->Id;
  1201. myBootEntry->Attributes = bootEntry->Attributes;
  1202. //Change the friendly name if lpNewFriendlyName is not NULL
  1203. //if(lpNewFriendlyName && (lstrlen(lpNewFriendlyName) != 0))
  1204. //if(( cmdOptions[4].dwActuals == 0) )
  1205. if(TRUE == bFlag)
  1206. //if(lstrlen(lpNewFriendlyName) != 0)
  1207. {
  1208. myBootEntry->FriendlyName = lpNewFriendlyName;
  1209. myBootEntry->FriendlyNameLength = ((ULONG)StringLengthW(lpNewFriendlyName,0) + 1) * sizeof(WCHAR);
  1210. }
  1211. else
  1212. {
  1213. StringCopy(szString,GetResString(IDS_COPY_OF), SIZE_OF_ARRAY(szString));
  1214. StringConcat(szString,(PWSTR)ADD_OFFSET(bootEntryCopy, FriendlyNameOffset), SIZE_OF_ARRAY(szString));
  1215. if(StringLengthW(szString, 0) >= 67)
  1216. {
  1217. StringCopy(szString,szString,67);
  1218. }
  1219. myBootEntry->FriendlyName = szString ;
  1220. myBootEntry->FriendlyNameLength = ((ULONG)StringLengthW(szString,0) + 1) * sizeof(WCHAR);
  1221. }
  1222. myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset);
  1223. // If this is an NT boot entry, capture the NT-specific information in
  1224. // the OsOptions.
  1225. osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions;
  1226. if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) &&
  1227. (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0))
  1228. {
  1229. MBE_SET_IS_NT( myBootEntry );
  1230. //To change the OS Load options
  1231. myBootEntry->OsLoadOptions = osOptions->OsLoadOptions;
  1232. myBootEntry->OsLoadOptionsLength = ((ULONG)StringLengthW(myBootEntry->OsLoadOptions, 0) + 1) * sizeof(WCHAR);
  1233. myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset);
  1234. }
  1235. else
  1236. {
  1237. // Foreign boot entry. Just capture whatever OS options exist.
  1238. //
  1239. myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions;
  1240. myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength;
  1241. }
  1242. myChBootEntry = CreateBootEntryFromBootEntry(myBootEntry);
  1243. if(myChBootEntry == NULL)
  1244. {
  1245. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1246. if(myBootEntry)
  1247. {
  1248. FreeMemory((LPVOID *)&myBootEntry);
  1249. }
  1250. ShowLastError(stderr);
  1251. return (EXIT_FAILURE);
  1252. }
  1253. //Call the NtAddBootEntry API
  1254. status = NtAddBootEntry(&myChBootEntry->NtBootEntry, &Id);
  1255. if ( status != STATUS_SUCCESS )
  1256. {
  1257. error = RtlNtStatusToDosError( status );
  1258. dwErrorCode = error;
  1259. ShowMessage(stderr,GetResString(IDS_ERROR_UNEXPECTED) );
  1260. }
  1261. // Get the system boot order list.
  1262. length = 0;
  1263. status = NtQueryBootEntryOrder( NULL, &length );
  1264. if ( status != STATUS_BUFFER_TOO_SMALL )
  1265. {
  1266. if ( status == STATUS_SUCCESS )
  1267. {
  1268. length = 0;
  1269. }
  1270. else
  1271. {
  1272. error = RtlNtStatusToDosError( status );
  1273. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY) );
  1274. if(myBootEntry)
  1275. {
  1276. FreeMemory((LPVOID *)&myBootEntry);
  1277. }
  1278. if(myChBootEntry)
  1279. {
  1280. FreeMemory((LPVOID *)&myChBootEntry);
  1281. }
  1282. return FALSE;
  1283. }
  1284. }
  1285. if ( length != 0 )
  1286. {
  1287. BootEntryOrder = (PULONG)AllocateMemory( length * sizeof(ULONG) );
  1288. if(BootEntryOrder == NULL)
  1289. {
  1290. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1291. if(myBootEntry)
  1292. {
  1293. FreeMemory((LPVOID *)&myBootEntry);
  1294. }
  1295. if(myChBootEntry)
  1296. {
  1297. FreeMemory((LPVOID *)&myChBootEntry);
  1298. }
  1299. return (EXIT_FAILURE);
  1300. }
  1301. status = NtQueryBootEntryOrder( BootEntryOrder, &length );
  1302. if ( status != STATUS_SUCCESS )
  1303. {
  1304. error = RtlNtStatusToDosError( status );
  1305. ShowMessage(stderr,GetResString(IDS_ERROR_QUERY_BOOTENTRY));
  1306. dwErrorCode = error;
  1307. FreeMemory((LPVOID *)&myBootEntry);
  1308. FreeMemory((LPVOID *)&BootEntryOrder);
  1309. FreeMemory((LPVOID *)&myChBootEntry);
  1310. return dwErrorCode;
  1311. }
  1312. }
  1313. //Allocate memory for the new boot entry order.
  1314. NewBootEntryOrder = (PULONG)AllocateMemory((length+1) * sizeof(ULONG));
  1315. if(NULL == NewBootEntryOrder )
  1316. {
  1317. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1318. FreeMemory((LPVOID *)&myBootEntry);
  1319. FreeMemory((LPVOID *)&BootEntryOrder);
  1320. FreeMemory((LPVOID *)&myChBootEntry);
  1321. return (EXIT_FAILURE);
  1322. }
  1323. NewTempBootEntryOrder = NewBootEntryOrder;
  1324. memcpy(NewTempBootEntryOrder,BootEntryOrder,length*sizeof(ULONG));
  1325. NewTempBootEntryOrder = NewTempBootEntryOrder + length;
  1326. *NewTempBootEntryOrder = Id;
  1327. status = NtSetBootEntryOrder(NewBootEntryOrder, length+1);
  1328. if ( status != STATUS_SUCCESS )
  1329. {
  1330. error = RtlNtStatusToDosError( status );
  1331. dwErrorCode = error;
  1332. ShowMessage(stderr,GetResString(IDS_ERROR_SET_BOOTENTRY));
  1333. }
  1334. //free the memory
  1335. FreeMemory((LPVOID *)&NewBootEntryOrder);
  1336. FreeMemory((LPVOID *)&myBootEntry);
  1337. FreeMemory((LPVOID *)&BootEntryOrder);
  1338. FreeMemory((LPVOID *)&myChBootEntry);
  1339. return dwErrorCode;
  1340. }
  1341. DWORD
  1342. ChangeTimeOut_IA64( IN DWORD argc,
  1343. IN LPCTSTR argv[]
  1344. )
  1345. /*++
  1346. Routine Description :
  1347. This routine chnages the Timeout value in the system
  1348. global boot options.
  1349. Arguments :
  1350. [ in ] argc - Number of command line arguments
  1351. [ in ] argv - Array containing command line arguments
  1352. Return Type : DOWRD
  1353. Returns EXIT_SUCCESS if it successfull,
  1354. returns EXIT_FAILURE otherwise.
  1355. --*/
  1356. {
  1357. DWORD dwTimeOut = 0;
  1358. DWORD dwExitCode = EXIT_SUCCESS;
  1359. ULONG Flag = 0;
  1360. DWORD dwExitcode = 0;
  1361. BOOL bTimeout = FALSE;
  1362. BOOL bUsage = FALSE;
  1363. TCMDPARSER2 cmdOptions[3];
  1364. PTCMDPARSER2 pcmdOption;
  1365. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  1366. //main option
  1367. pcmdOption = &cmdOptions[0];
  1368. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1369. pcmdOption->pwszOptions = CMDOPTION_TIMEOUT;
  1370. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1371. pcmdOption->dwCount = 1;
  1372. pcmdOption->pValue = &bTimeout;
  1373. //default timeout value
  1374. pcmdOption = &cmdOptions[1];
  1375. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1376. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  1377. pcmdOption->dwFlags = CP2_DEFAULT | CP2_MANDATORY;
  1378. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  1379. pcmdOption->dwCount = 1;
  1380. pcmdOption->pValue = &dwTimeOut;
  1381. //usage option
  1382. pcmdOption = &cmdOptions[2];
  1383. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1384. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  1385. pcmdOption->dwFlags = CP2_USAGE;
  1386. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1387. pcmdOption->dwCount = 1;
  1388. pcmdOption->pValue = &bUsage;
  1389. if( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  1390. {
  1391. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1392. return (EXIT_FAILURE);
  1393. }
  1394. //check if usage is specified with more than one option
  1395. if( (TRUE == bUsage) && (argc > 3) )
  1396. {
  1397. ShowMessage(stderr,GetResString(IDS_TIMEOUT_USAGE));
  1398. return ( EXIT_FAILURE );
  1399. }
  1400. if(bUsage)
  1401. {
  1402. displayTimeOutUsage_IA64();
  1403. return (EXIT_SUCCESS);
  1404. }
  1405. dwExitcode = InitializeEFI();
  1406. if(EXIT_FAILURE == dwExitcode )
  1407. {
  1408. return EXIT_FAILURE ;
  1409. }
  1410. //Check for the limit of Timeout value entered by the user.
  1411. if(dwTimeOut > TIMEOUT_MAX )
  1412. {
  1413. ShowMessage(stderr,GetResString(IDS_TIMEOUT_RANGE));
  1414. return (EXIT_FAILURE );
  1415. }
  1416. //Call the ModifyBootOptions function with the BOOT_OPTIONS_FIELD_COUNTDOWN
  1417. Flag |= BOOT_OPTIONS_FIELD_COUNTDOWN;
  1418. dwExitCode = ModifyBootOptions(dwTimeOut, NULL, 0, Flag);
  1419. return dwExitCode;
  1420. }
  1421. DWORD
  1422. ModifyBootOptions( IN ULONG Timeout,
  1423. IN LPTSTR pHeadlessRedirection,
  1424. IN ULONG NextBootEntryID,
  1425. IN ULONG Flag
  1426. )
  1427. /*++
  1428. Routine Description :
  1429. This routine Modifies the Boot options
  1430. -Timeout
  1431. -NextBootEntryID
  1432. -HeadlessRedirection
  1433. Arguments :
  1434. [ in ] Timeout - The new Timeout value
  1435. [ in ] pHeadlessRedirection - The Headless redirection string
  1436. [ in ] NextBootEntryID - The NextBootEntryID
  1437. [ in ] Flag - The Flags indicating what fields that needs to be changed
  1438. BOOT_OPTIONS_FIELD_COUNTDOWN
  1439. BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID
  1440. BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION
  1441. Return Type : DOWRD
  1442. Returns EXIT_SUCCESS if successful,
  1443. returns EXIT_FAILURE otherwise.
  1444. --*/
  1445. {
  1446. PBOOT_OPTIONS pBootOptions;
  1447. PBOOT_OPTIONS pModifiedBootOptions;
  1448. DWORD error;
  1449. NTSTATUS status;
  1450. ULONG newlength=0;
  1451. DWORD dwExitCode = EXIT_SUCCESS;
  1452. NextBootEntryID = 0;
  1453. //Query the existing Boot options and modify based on the Flag value
  1454. status = BootCfg_QueryBootOptions(&pBootOptions);
  1455. if(status != STATUS_SUCCESS)
  1456. {
  1457. error = RtlNtStatusToDosError( status );
  1458. FreeMemory((LPVOID *)&pBootOptions);
  1459. return (error);
  1460. }
  1461. //Calculate the new length of the BOOT_OPTIONS struct based on the fields that needs to be changed.
  1462. newlength = FIELD_OFFSET(BOOT_OPTIONS, HeadlessRedirection);
  1463. if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION))
  1464. {
  1465. newlength = FIELD_OFFSET(BOOT_OPTIONS, HeadlessRedirection);
  1466. newlength += StringLengthW(pHeadlessRedirection,0);
  1467. newlength = ALIGN_UP(newlength, ULONG);
  1468. }
  1469. else
  1470. {
  1471. newlength = pBootOptions->Length;
  1472. }
  1473. //Also allocate the memory for a new Boot option struct
  1474. pModifiedBootOptions = (PBOOT_OPTIONS)AllocateMemory(newlength);
  1475. if(pModifiedBootOptions == NULL)
  1476. {
  1477. FreeMemory((LPVOID *)&pBootOptions);
  1478. return (EXIT_FAILURE);
  1479. }
  1480. //Fill in the new boot options struct
  1481. pModifiedBootOptions->Version = BOOT_OPTIONS_VERSION;
  1482. pModifiedBootOptions->Length = newlength;
  1483. if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN))
  1484. {
  1485. pModifiedBootOptions->Timeout = Timeout;
  1486. }
  1487. else
  1488. {
  1489. pModifiedBootOptions->Timeout = pBootOptions->Timeout;
  1490. }
  1491. //Cannot change the CurrentBootEntryId.So just pass what u got.
  1492. pModifiedBootOptions->CurrentBootEntryId = pBootOptions->CurrentBootEntryId;
  1493. if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID))
  1494. {
  1495. pModifiedBootOptions->NextBootEntryId = pBootOptions->NextBootEntryId;
  1496. }
  1497. else
  1498. {
  1499. pModifiedBootOptions->NextBootEntryId = pBootOptions->NextBootEntryId;
  1500. }
  1501. if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION))
  1502. {
  1503. StringCopy(pModifiedBootOptions->HeadlessRedirection, pBootOptions->HeadlessRedirection, StringLengthW(pBootOptions->HeadlessRedirection,0));
  1504. }
  1505. else
  1506. {
  1507. StringCopy(pModifiedBootOptions->HeadlessRedirection, pBootOptions->HeadlessRedirection, StringLengthW(pBootOptions->HeadlessRedirection,0));
  1508. }
  1509. //Set the boot options in the NVRAM
  1510. status = NtSetBootOptions(pModifiedBootOptions, Flag);
  1511. if(status != STATUS_SUCCESS)
  1512. {
  1513. dwExitCode = EXIT_SUCCESS;
  1514. if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN))
  1515. {
  1516. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_TIMEOUT));
  1517. }
  1518. if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID))
  1519. {
  1520. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_NEXTBOOTID));
  1521. }
  1522. if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION))
  1523. {
  1524. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_MODIFY_HEADLESS));
  1525. }
  1526. }
  1527. else
  1528. {
  1529. dwExitCode = EXIT_SUCCESS;
  1530. if((Flag & BOOT_OPTIONS_FIELD_COUNTDOWN))
  1531. {
  1532. ShowMessage(stdout,GetResString(IDS_SUCCESS_MODIFY_TIMEOUT));
  1533. }
  1534. if((Flag & BOOT_OPTIONS_FIELD_NEXT_BOOT_ENTRY_ID))
  1535. {
  1536. ShowMessage(stdout,GetResString(IDS_SUCCESS_MODIFY_NEXTBOOTID));
  1537. }
  1538. if((Flag & BOOT_OPTIONS_FIELD_HEADLESS_REDIRECTION))
  1539. {
  1540. ShowMessage(stdout,GetResString(IDS_SUCCESS_MODIFY_HEADLESS));
  1541. }
  1542. }
  1543. //free the memory
  1544. FreeMemory((LPVOID *) &pModifiedBootOptions);
  1545. FreeMemory((LPVOID *) &pBootOptions);
  1546. return dwExitCode;
  1547. }
  1548. DWORD
  1549. ConvertBootEntries(PBOOT_ENTRY_LIST NtBootEntries)
  1550. /*++
  1551. Routine Description :
  1552. Convert boot entries read from EFI NVRAM into our internal format.
  1553. Arguments :
  1554. [ in ] NtBootEntries - The boot entry list given by the enumeration
  1555. Return Type : DWORD
  1556. --*/
  1557. {
  1558. PBOOT_ENTRY_LIST bootEntryList;
  1559. PBOOT_ENTRY bootEntry;
  1560. PBOOT_ENTRY bootEntryCopy;
  1561. PMY_BOOT_ENTRY myBootEntry;
  1562. PWINDOWS_OS_OPTIONS osOptions;
  1563. ULONG length = 0;
  1564. DWORD dwErrorCode = EXIT_SUCCESS;
  1565. BOOL bNoBreak = TRUE;
  1566. bootEntryList = NtBootEntries;
  1567. do
  1568. {
  1569. bootEntry = &bootEntryList->BootEntry;
  1570. //
  1571. // Calculate the length of our internal structure. This includes
  1572. // the base part of MY_BOOT_ENTRY plus the NT BOOT_ENTRY.
  1573. //
  1574. length = FIELD_OFFSET(MY_BOOT_ENTRY, NtBootEntry) + bootEntry->Length;
  1575. //Remember to check for the NULL pointer
  1576. myBootEntry = (PMY_BOOT_ENTRY)AllocateMemory(length);
  1577. if(myBootEntry == NULL)
  1578. {
  1579. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1580. return (EXIT_FAILURE);
  1581. }
  1582. RtlZeroMemory(myBootEntry, length);
  1583. //
  1584. // Link the new entry into the list.
  1585. //
  1586. if ( (bootEntry->Attributes & BOOT_ENTRY_ATTRIBUTE_ACTIVE) )
  1587. {
  1588. InsertTailList( &ActiveUnorderedBootEntries, &myBootEntry->ListEntry );
  1589. myBootEntry->ListHead = &ActiveUnorderedBootEntries;
  1590. }
  1591. else
  1592. {
  1593. InsertTailList( &InactiveUnorderedBootEntries, &myBootEntry->ListEntry );
  1594. myBootEntry->ListHead = &InactiveUnorderedBootEntries;
  1595. }
  1596. //
  1597. // Copy the NT BOOT_ENTRY into the allocated buffer.
  1598. //
  1599. bootEntryCopy = &myBootEntry->NtBootEntry;
  1600. memcpy(bootEntryCopy, bootEntry, bootEntry->Length);
  1601. //
  1602. // Fill in the base part of the structure.
  1603. //
  1604. myBootEntry->AllocationEnd = (PUCHAR)myBootEntry + length - 1;
  1605. myBootEntry->Id = bootEntry->Id;
  1606. //Assign 0 to the Ordered field currently so that
  1607. //once the boot order is known, we can assign 1 if this entry is a part of the ordered list.
  1608. myBootEntry->Ordered = 0;
  1609. myBootEntry->Attributes = bootEntry->Attributes;
  1610. myBootEntry->FriendlyName = (PWSTR)ADD_OFFSET(bootEntryCopy, FriendlyNameOffset);
  1611. myBootEntry->FriendlyNameLength =((ULONG)StringLengthW(myBootEntry->FriendlyName,0) + 1) * sizeof(WCHAR);
  1612. myBootEntry->BootFilePath = (PFILE_PATH)ADD_OFFSET(bootEntryCopy, BootFilePathOffset);
  1613. //
  1614. // If this is an NT boot entry, capture the NT-specific information in
  1615. // the OsOptions.
  1616. //
  1617. osOptions = (PWINDOWS_OS_OPTIONS)bootEntryCopy->OsOptions;
  1618. if ((bootEntryCopy->OsOptionsLength >= FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)) &&
  1619. (strcmp((char *)osOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE) == 0))
  1620. {
  1621. MBE_SET_IS_NT( myBootEntry );
  1622. myBootEntry->OsLoadOptions = osOptions->OsLoadOptions;
  1623. myBootEntry->OsLoadOptionsLength =((ULONG)StringLengthW(myBootEntry->OsLoadOptions,0) + 1) * sizeof(WCHAR);
  1624. myBootEntry->OsFilePath = (PFILE_PATH)ADD_OFFSET(osOptions, OsLoadPathOffset);
  1625. }
  1626. else
  1627. {
  1628. //
  1629. // Foreign boot entry. Just capture whatever OS options exist.
  1630. //
  1631. myBootEntry->ForeignOsOptions = bootEntryCopy->OsOptions;
  1632. myBootEntry->ForeignOsOptionsLength = bootEntryCopy->OsOptionsLength;
  1633. }
  1634. //
  1635. // Move to the next entry in the enumeration list, if any.
  1636. //
  1637. if (bootEntryList->NextEntryOffset == 0)
  1638. {
  1639. bNoBreak = FALSE;
  1640. break;
  1641. }
  1642. bootEntryList = (PBOOT_ENTRY_LIST)ADD_OFFSET(bootEntryList, NextEntryOffset);
  1643. } while ( TRUE == bNoBreak );
  1644. return dwErrorCode;
  1645. } // ConvertBootEntries
  1646. DWORD DisplayBootOptions()
  1647. /*++
  1648. Name : DisplayBootOptions
  1649. Synopsis : Display the boot options
  1650. Parameters : NONE
  1651. Return Type : DWORD
  1652. Global Variables: Global Linked lists for storing the boot entries
  1653. LIST_ENTRY BootEntries;
  1654. --*/
  1655. {
  1656. DWORD error;
  1657. NTSTATUS status;
  1658. PBOOT_OPTIONS pBootOptions;
  1659. TCHAR szDisplay[MAX_RES_STRING+1] = NULL_STRING;
  1660. //Query the boot options
  1661. status = BootCfg_QueryBootOptions(&pBootOptions);
  1662. if(status != STATUS_SUCCESS)
  1663. {
  1664. error = RtlNtStatusToDosError( status );
  1665. if(pBootOptions)
  1666. {
  1667. FreeMemory((LPVOID *)&pBootOptions);
  1668. }
  1669. return EXIT_FAILURE;
  1670. }
  1671. //Printout the boot options
  1672. ShowMessage(stdout,_T("\n"));
  1673. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64A));
  1674. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64B));
  1675. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64C), pBootOptions->Timeout);
  1676. //display default boot entry id
  1677. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64P), GetDefaultBootEntry());
  1678. //Get the CurrentBootEntryId from the actual Id present in the boot options
  1679. SecureZeroMemory( szDisplay, SIZE_OF_ARRAY(szDisplay) );
  1680. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64D), GetCurrentBootEntryID(pBootOptions->CurrentBootEntryId));
  1681. ShowMessage(stdout,L"\n");
  1682. #if 0
  1683. if(StringLengthW(pBootOptions->HeadlessRedirection) == 0)
  1684. {
  1685. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64E));
  1686. }
  1687. else
  1688. {
  1689. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64F), pBootOptions->HeadlessRedirection);
  1690. }
  1691. #endif //Commenting out the display of the Headless redirection
  1692. //as we cannot query the same through API (its Firmware controlled)
  1693. if(pBootOptions)
  1694. {
  1695. FreeMemory((LPVOID *)&pBootOptions);
  1696. }
  1697. return EXIT_SUCCESS;
  1698. }
  1699. VOID DisplayBootEntry()
  1700. /*++
  1701. Routine Description : Display the boot entries (in an order)
  1702. Parameters : NONE
  1703. Return Type : DWORD
  1704. --*/
  1705. {
  1706. PLIST_ENTRY listEntry;
  1707. PMY_BOOT_ENTRY bootEntry;
  1708. PWSTR NtFilePath;
  1709. //Printout the boot entires
  1710. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64G));
  1711. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64H));
  1712. for (listEntry = BootEntries.Flink;listEntry != &BootEntries; listEntry = listEntry->Flink)
  1713. {
  1714. //Get the boot entry
  1715. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  1716. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64I), bootEntry->myId);
  1717. //friendly name
  1718. if(StringLengthW(bootEntry->FriendlyName,0)!=0)
  1719. {
  1720. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64J), bootEntry->FriendlyName);
  1721. }
  1722. else
  1723. {
  1724. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64K));
  1725. }
  1726. if(MBE_IS_NT(bootEntry))
  1727. {
  1728. //the OS load options
  1729. if(StringLengthW(bootEntry->OsLoadOptions, 0)!=0)
  1730. {
  1731. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64L), bootEntry->OsLoadOptions);
  1732. }
  1733. else
  1734. {
  1735. ShowMessage(stdout,GetResString(IDS_OUTPUT_IA64M));
  1736. }
  1737. //Get the BootFilePath
  1738. NtFilePath = GetNtNameForFilePath(bootEntry->BootFilePath);
  1739. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64N), NtFilePath);
  1740. //free the memory
  1741. if(NtFilePath)
  1742. {
  1743. FreeMemory((LPVOID *)&NtFilePath);
  1744. }
  1745. //Get the OS load path
  1746. NtFilePath = GetNtNameForFilePath(bootEntry->OsFilePath);
  1747. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_OUTPUT_IA64O), NtFilePath);
  1748. //free the memory
  1749. if(NtFilePath)
  1750. {
  1751. FreeMemory((LPVOID *)&NtFilePath);
  1752. }
  1753. }
  1754. else
  1755. {
  1756. ShowMessage(stdout,_T("\n"));
  1757. }
  1758. }
  1759. }
  1760. DWORD GetCurrentBootEntryID(DWORD Id)
  1761. /*++
  1762. Routine Description :
  1763. Gets the Boot entry ID generated by us from the BootId given by the NVRAM
  1764. Arguments :
  1765. [ in ] Id - The current boot id (BootId given by the NVRAM)
  1766. Return Type : DWORD
  1767. Returns EXIT_SUCCESS if successful,
  1768. returns EXIT_FAILURE otherwise
  1769. --*/
  1770. {
  1771. PLIST_ENTRY listEntry;
  1772. PMY_BOOT_ENTRY bootEntry;
  1773. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  1774. {
  1775. //Get the boot entry
  1776. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  1777. if(bootEntry->Id == Id)
  1778. {
  1779. return bootEntry->myId;
  1780. }
  1781. }
  1782. return 0;
  1783. }
  1784. DWORD
  1785. ChangeDefaultBootEntry_IA64( IN DWORD argc,
  1786. IN LPCTSTR argv[]
  1787. )
  1788. /*++
  1789. Routine Description :
  1790. This routine is to change the Default boot entry in the NVRAM
  1791. Arguments :
  1792. [ in ] argc - Number of command line arguments
  1793. [ in ] argv - Array containing command line arguments
  1794. Return Type : DWORD
  1795. --*/
  1796. {
  1797. PMY_BOOT_ENTRY mybootEntry;
  1798. PLIST_ENTRY listEntry;
  1799. NTSTATUS status;
  1800. PULONG BootEntryOrder, NewBootEntryOrder;
  1801. DWORD dwBootID = 0;
  1802. BOOL bDefaultOs = FALSE ;
  1803. DWORD dwExitCode = ERROR_SUCCESS;
  1804. BOOL bBootIdFound = FALSE;
  1805. BOOL bIdFoundInBootOrderList = FALSE;
  1806. ULONG length, i, j, defaultId = 0;
  1807. DWORD error = 0;
  1808. DWORD dwExitcode = 0;
  1809. BOOL bUsage = FALSE;
  1810. TCMDPARSER2 cmdOptions[3];
  1811. PTCMDPARSER2 pcmdOption;
  1812. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  1813. //main option
  1814. pcmdOption = &cmdOptions[0];
  1815. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1816. pcmdOption->pwszOptions = CMDOPTION_DEFAULTOS;
  1817. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1818. pcmdOption->dwCount = 1;
  1819. pcmdOption->pValue = &bDefaultOs;
  1820. //id option
  1821. pcmdOption = &cmdOptions[1];
  1822. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1823. pcmdOption->pwszOptions = SWITCH_ID;
  1824. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  1825. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  1826. pcmdOption->dwCount = 1;
  1827. pcmdOption->pValue = &dwBootID;
  1828. //usage option
  1829. pcmdOption = &cmdOptions[2];
  1830. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1831. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  1832. pcmdOption->dwFlags = CP2_USAGE;
  1833. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  1834. pcmdOption->dwCount = 1;
  1835. pcmdOption->pValue = &bUsage;
  1836. if( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  1837. {
  1838. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1839. return (EXIT_FAILURE );
  1840. }
  1841. //check if usage is specified with more than one option
  1842. if( (TRUE == bUsage) && (argc > 3) )
  1843. {
  1844. ShowMessage(stderr,GetResString(IDS_DEFAULTOS_USAGE));
  1845. return ( EXIT_FAILURE );
  1846. }
  1847. if(bUsage)
  1848. {
  1849. displayDefaultEntryUsage_IA64();
  1850. return EXIT_SUCCESS;
  1851. }
  1852. dwExitcode = InitializeEFI();
  1853. if(EXIT_FAILURE == dwExitcode )
  1854. {
  1855. return EXIT_FAILURE ;
  1856. }
  1857. //Check whether the boot entry entered bu the user is a valid boot entry id or not.
  1858. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  1859. {
  1860. //Get the boot entry
  1861. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  1862. if(mybootEntry->myId == dwBootID)
  1863. {
  1864. bBootIdFound = TRUE;
  1865. //store the default ID
  1866. defaultId = mybootEntry->Id;
  1867. break;
  1868. }
  1869. }
  1870. if(bBootIdFound == FALSE)
  1871. {
  1872. //Could not find the BootID specified by the user so output the message and return failure
  1873. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  1874. return (EXIT_FAILURE);
  1875. }
  1876. // Get the system boot order list.
  1877. length = 0;
  1878. status = NtQueryBootEntryOrder( NULL, &length );
  1879. if ( status != STATUS_BUFFER_TOO_SMALL )
  1880. {
  1881. if ( status == STATUS_SUCCESS )
  1882. {
  1883. length = 0;
  1884. }
  1885. else
  1886. {
  1887. error = RtlNtStatusToDosError( status );
  1888. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID);
  1889. return (EXIT_FAILURE);
  1890. }
  1891. }
  1892. if ( length != 0 )
  1893. {
  1894. BootEntryOrder = (PULONG)AllocateMemory( length * sizeof(ULONG) );
  1895. if(BootEntryOrder == NULL)
  1896. {
  1897. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1898. return (EXIT_FAILURE);
  1899. }
  1900. status = NtQueryBootEntryOrder( BootEntryOrder, &length );
  1901. if ( status != STATUS_SUCCESS )
  1902. {
  1903. error = RtlNtStatusToDosError( status );
  1904. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID);
  1905. FreeMemory((LPVOID *)&BootEntryOrder);
  1906. return EXIT_FAILURE;
  1907. }
  1908. }
  1909. //Check if the boot id entered by the user is a part of the Boot entry order.
  1910. //If not for the time being do not make it the default.
  1911. for(i=0;i<length;i++)
  1912. {
  1913. if(*(BootEntryOrder+i) == defaultId)
  1914. {
  1915. bIdFoundInBootOrderList = TRUE;
  1916. break;
  1917. }
  1918. }
  1919. if(bIdFoundInBootOrderList == FALSE)
  1920. {
  1921. FreeMemory((LPVOID *)&BootEntryOrder);
  1922. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID);
  1923. return (EXIT_FAILURE);
  1924. }
  1925. //Allocate memory for storing the new boot entry order.
  1926. NewBootEntryOrder = (PULONG)AllocateMemory((length) * sizeof(ULONG));
  1927. if(NewBootEntryOrder == NULL)
  1928. {
  1929. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  1930. FreeMemory((LPVOID *)&BootEntryOrder);
  1931. return (EXIT_FAILURE);
  1932. }
  1933. *NewBootEntryOrder = defaultId;
  1934. j=0;
  1935. for(i=0;i<length;i++)
  1936. {
  1937. if(*(BootEntryOrder+i) == defaultId)
  1938. {
  1939. continue;
  1940. }
  1941. *(NewBootEntryOrder+(j+1)) = *(BootEntryOrder+i);
  1942. j++;
  1943. }
  1944. status = NtSetBootEntryOrder(NewBootEntryOrder, length);
  1945. if ( status != STATUS_SUCCESS )
  1946. {
  1947. error = RtlNtStatusToDosError( status );
  1948. dwExitCode = error;
  1949. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_DEFAULT_ENTRY),dwBootID);
  1950. }
  1951. else
  1952. {
  1953. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_DEFAULT_ENTRY),dwBootID);
  1954. }
  1955. //free the memory
  1956. FreeMemory((LPVOID *)&NewBootEntryOrder);
  1957. FreeMemory((LPVOID *)&BootEntryOrder);
  1958. return dwExitCode;
  1959. }
  1960. DWORD
  1961. ProcessDebugSwitch_IA64( IN DWORD argc,
  1962. IN LPCTSTR argv[]
  1963. )
  1964. /*++
  1965. Routine Description :
  1966. Allows the user to add the OS load options specifed
  1967. as a debug string at the cmdline to the boot
  1968. Arguments :
  1969. [ in ] argc - Number of command line arguments
  1970. [ in ] argv - Array containing command line arguments
  1971. Return Type : DWORD
  1972. Returns EXIT_SUCCESS if successful,
  1973. returns EXIT_FAILURE otherwise.
  1974. --*/
  1975. {
  1976. BOOL bUsage = FALSE ;
  1977. DWORD dwBootID = 0;
  1978. BOOL bBootIdFound = FALSE;
  1979. DWORD dwExitCode = ERROR_SUCCESS;
  1980. PMY_BOOT_ENTRY mybootEntry;
  1981. PLIST_ENTRY listEntry;
  1982. PBOOT_ENTRY bootEntry;
  1983. TCHAR szPort[MAX_RES_STRING+1] = NULL_STRING ;
  1984. TCHAR szBaudRate[MAX_RES_STRING+1] = NULL_STRING ;
  1985. TCHAR szDebug[MAX_RES_STRING+1] = NULL_STRING ;
  1986. BOOL bDebug = FALSE ;
  1987. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ;
  1988. TCHAR szOsLoadOptions[MAX_RES_STRING+1] = NULL_STRING ;
  1989. TCHAR szTemp[MAX_RES_STRING+1] = NULL_STRING ;
  1990. TCHAR szTmpBuffer[MAX_RES_STRING+1] = NULL_STRING ;
  1991. DWORD dwExitcode = 0 ;
  1992. TCMDPARSER2 cmdOptions[6];
  1993. PTCMDPARSER2 pcmdOption;
  1994. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  1995. //main option
  1996. pcmdOption = &cmdOptions[0];
  1997. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  1998. pcmdOption->pwszOptions = CMDOPTION_DEBUG;
  1999. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2000. pcmdOption->dwCount = 1;
  2001. pcmdOption->pValue = &bDebug;
  2002. //usage
  2003. pcmdOption = &cmdOptions[1];
  2004. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2005. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  2006. pcmdOption->dwFlags = CP2_USAGE;
  2007. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2008. pcmdOption->dwCount = 1;
  2009. pcmdOption->pValue = &bUsage;
  2010. //id option
  2011. pcmdOption = &cmdOptions[2];
  2012. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2013. pcmdOption->pwszOptions = SWITCH_ID;
  2014. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  2015. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  2016. pcmdOption->dwCount = 1;
  2017. pcmdOption->pValue = &dwBootID;
  2018. //port option
  2019. pcmdOption = &cmdOptions[3];
  2020. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2021. pcmdOption->pwszOptions = SWITCH_PORT;
  2022. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MODE_VALUES | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;;
  2023. pcmdOption->dwType = CP_TYPE_TEXT;
  2024. pcmdOption->dwCount = 1;
  2025. pcmdOption->pValue = szPort;
  2026. pcmdOption->pwszValues = COM_PORT_RANGE;
  2027. pcmdOption->dwLength= MAX_STRING_LENGTH;
  2028. //baud option
  2029. pcmdOption = &cmdOptions[4];
  2030. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2031. pcmdOption->pwszOptions = SWITCH_BAUD;
  2032. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MODE_VALUES | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;;
  2033. pcmdOption->dwType = CP_TYPE_TEXT;
  2034. pcmdOption->dwCount = 1;
  2035. pcmdOption->pValue = szBaudRate;
  2036. pcmdOption->pwszValues = BAUD_RATE_VALUES_DEBUG;
  2037. pcmdOption->dwLength= MAX_STRING_LENGTH;
  2038. //default on/off option
  2039. pcmdOption = &cmdOptions[5];
  2040. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2041. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  2042. pcmdOption->dwFlags = CP2_DEFAULT | CP2_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;;
  2043. pcmdOption->dwType = CP_TYPE_TEXT;
  2044. pcmdOption->dwCount = 1;
  2045. pcmdOption->pValue = szDebug;
  2046. pcmdOption->dwLength= MAX_STRING_LENGTH;
  2047. // Parsing the copy option switches
  2048. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  2049. {
  2050. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  2051. return (EXIT_FAILURE);
  2052. }
  2053. //check if usage is specified with more than one option
  2054. if( (TRUE == bUsage) && (argc > 3) )
  2055. {
  2056. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG));
  2057. return ( EXIT_FAILURE );
  2058. }
  2059. // Displaying query usage if user specified -? with -query option
  2060. if( bUsage )
  2061. {
  2062. displayDebugUsage_IA64();
  2063. return (ERROR_SUCCESS);
  2064. }
  2065. dwExitcode = InitializeEFI();
  2066. if(EXIT_FAILURE == dwExitcode )
  2067. {
  2068. return EXIT_FAILURE ;
  2069. }
  2070. //Trim any leading or trailing spaces
  2071. if(StringLengthW(szDebug, 0)!=0)
  2072. {
  2073. TrimString(szDebug, TRIM_ALL);
  2074. }
  2075. if( !( ( StringCompare(szDebug,VALUE_ON,TRUE,0)== 0) || (StringCompare(szDebug,VALUE_OFF,TRUE,0)== 0 ) ||(StringCompare(szDebug,EDIT_STRING,TRUE,0)== 0) ) )
  2076. {
  2077. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG));
  2078. return EXIT_FAILURE;
  2079. }
  2080. //Query the boot entries till u get the BootID specified by the user
  2081. for (listEntry = BootEntries.Flink;listEntry != &BootEntries; listEntry = listEntry->Flink)
  2082. {
  2083. //Get the boot entry
  2084. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  2085. if(mybootEntry->myId == dwBootID)
  2086. {
  2087. bBootIdFound = TRUE;
  2088. bootEntry = &mybootEntry->NtBootEntry;
  2089. //Check whether the bootEntry is a Windows one or not.
  2090. //The OS load options can be added only to a Windows boot entry.
  2091. if(!IsBootEntryWindows(bootEntry))
  2092. {
  2093. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  2094. dwExitCode = EXIT_FAILURE;
  2095. break;
  2096. }
  2097. //Change the OS load options. Pass NULL to friendly name as we are not changing the same
  2098. //szRawString is the Os load options specified by the user
  2099. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  2100. if(StringLengthW(pWindowsOptions->OsLoadOptions, 0) > MAX_RES_STRING)
  2101. {
  2102. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2103. return EXIT_FAILURE ;
  2104. }
  2105. // copy the existing OS Loadoptions into a string.
  2106. StringCopy(szOsLoadOptions,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szOsLoadOptions));
  2107. //check if the user has entered On option
  2108. if( StringCompare(szDebug,VALUE_ON,TRUE,0)== 0)
  2109. {
  2110. //display an error message
  2111. if ( (FindString(szOsLoadOptions,DEBUG_SWITCH, 0) != 0 )&& (StringLengthW(szPort, 0)==0) &&(StringLengthW(szBaudRate, 0)==0) )
  2112. {
  2113. ShowMessage(stderr,GetResString(IDS_DUPL_DEBUG));
  2114. dwExitCode = EXIT_FAILURE;
  2115. break;
  2116. }
  2117. //display a error message and exit if the 1394 port is already present.
  2118. if(FindString(szOsLoadOptions,DEBUGPORT_1394, 0) != 0 )
  2119. {
  2120. ShowMessage(stderr,GetResString(IDS_1394_ALREADY_PRESENT));
  2121. dwExitCode = EXIT_FAILURE;
  2122. break;
  2123. }
  2124. //
  2125. //display an duplicate entry error message if substring is already present.
  2126. //
  2127. if(StringLengthW(szBaudRate, 0)==0)
  2128. {
  2129. if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_SUCCESS )
  2130. {
  2131. ShowMessage(stderr,GetResString(IDS_DUPLICATE_ENTRY));
  2132. return EXIT_FAILURE ;
  2133. }
  2134. }
  2135. if(StringLengthW(szTemp, 0)!=0)
  2136. {
  2137. ShowMessage(stderr,GetResString(IDS_DUPLICATE_ENTRY));
  2138. dwExitCode = EXIT_FAILURE;
  2139. break;
  2140. }
  2141. //check if the Os load options already contains
  2142. // debug switch
  2143. if(FindString(szOsLoadOptions,DEBUG_SWITCH, 0) == 0 )
  2144. {
  2145. if(StringLengthW(szOsLoadOptions, 0)!=0)
  2146. {
  2147. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2148. StringConcat(szTmpBuffer,DEBUG_SWITCH, SIZE_OF_ARRAY(szOsLoadOptions) );
  2149. }
  2150. else
  2151. {
  2152. StringCopy(szTmpBuffer,DEBUG_SWITCH, SIZE_OF_ARRAY(szOsLoadOptions) );
  2153. }
  2154. }
  2155. if(StringLengthW(szPort, 0)!= 0)
  2156. {
  2157. if(StringLengthW(szTmpBuffer, 0)==0)
  2158. {
  2159. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2160. }
  2161. else
  2162. {
  2163. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2164. }
  2165. StringConcat(szTmpBuffer,TOKEN_DEBUGPORT, SIZE_OF_ARRAY(szTmpBuffer)) ;
  2166. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer)) ;
  2167. CharUpper(szPort);
  2168. StringConcat(szTmpBuffer,szPort, SIZE_OF_ARRAY(szTmpBuffer));
  2169. }
  2170. //Check if the OS Load Options contains the baud rate already specified.
  2171. if(StringLengthW(szBaudRate, 0)!=0)
  2172. {
  2173. StringCopy(szTemp,NULL_STRING, SIZE_OF_ARRAY(szTemp) );
  2174. GetBaudRateVal(szOsLoadOptions,szTemp) ;
  2175. if(StringLengthW(szTemp, 0)!=0)
  2176. {
  2177. ShowMessage(stderr,GetResString(IDS_DUPLICATE_BAUD_RATE));
  2178. dwExitCode = EXIT_FAILURE;
  2179. break;
  2180. }
  2181. else
  2182. {
  2183. if(StringLengthW(szTmpBuffer, 0)==0)
  2184. {
  2185. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2186. }
  2187. else
  2188. {
  2189. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2190. }
  2191. StringConcat(szTmpBuffer,BAUD_RATE, SIZE_OF_ARRAY(szTmpBuffer));
  2192. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer));
  2193. StringConcat(szTmpBuffer,szBaudRate, SIZE_OF_ARRAY(szTmpBuffer));
  2194. }
  2195. }
  2196. }
  2197. //check if the user has entered OFF option
  2198. if( StringCompare(szDebug,VALUE_OFF,TRUE,0)== 0)
  2199. {
  2200. // If the user enters either com port or baud rate then display error message and exit.
  2201. if ((StringLengthW(szPort, 0)!=0) ||(StringLengthW(szBaudRate, 0)!=0))
  2202. {
  2203. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG));
  2204. dwExitCode = EXIT_FAILURE;
  2205. break;
  2206. }
  2207. // if debug port is absent print message and exit.
  2208. if (FindString(szOsLoadOptions,DEBUG_SWITCH, 0) == 0 )
  2209. {
  2210. ShowMessage(stderr,GetResString(IDS_DEBUG_ABSENT));
  2211. dwExitCode = EXIT_FAILURE;
  2212. break;
  2213. }
  2214. //remove the debug switch from the OSLoad Options
  2215. removeSubString(szOsLoadOptions,DEBUG_SWITCH);
  2216. if(FindString(szOsLoadOptions,DEBUGPORT_1394, 0) != 0 )
  2217. {
  2218. ShowMessage(stderr,GetResString(IDS_ERROR_1394_REMOVE));
  2219. dwExitCode = EXIT_FAILURE;
  2220. break;
  2221. }
  2222. GetSubString(szOsLoadOptions, TOKEN_DEBUGPORT,szTemp);
  2223. if(StringLengthW(szTemp, 0)!=0)
  2224. {
  2225. // remove the /debugport=comport switch if it is present from the Boot Entry
  2226. removeSubString(szOsLoadOptions,szTemp);
  2227. }
  2228. StringCopy(szTemp , NULL_STRING, SIZE_OF_ARRAY(szTemp) );
  2229. //remove the baud rate switch if it is present.
  2230. GetBaudRateVal(szOsLoadOptions,szTemp) ;
  2231. // if the OSLoadOptions contains baudrate then delete it.
  2232. if (StringLengthW(szTemp, 0 )!= 0)
  2233. {
  2234. removeSubString(szOsLoadOptions,szTemp);
  2235. }
  2236. }
  2237. //if the user selected the edit option .
  2238. if( StringCompare(szDebug,EDIT_STRING,TRUE,0)== 0)
  2239. {
  2240. //check if the debug switch is present in the Osload options else display error message.
  2241. if (FindString(szOsLoadOptions,DEBUG_SWITCH, 0) == 0 )
  2242. {
  2243. ShowMessage(stderr,GetResString(IDS_DEBUG_ABSENT));
  2244. dwExitCode = EXIT_FAILURE;
  2245. break;
  2246. }
  2247. if( FindString(szOsLoadOptions,DEBUGPORT_1394, 0) != 0 )
  2248. {
  2249. ShowMessage(stderr,GetResString(IDS_ERROR_EDIT_1394_SWITCH));
  2250. dwExitCode = EXIT_FAILURE;
  2251. break;
  2252. }
  2253. //check if the user enters COM port or baud rate else display error message.
  2254. if((StringLengthW(szPort, 0)==0)&&(StringLengthW(szBaudRate, 0)==0))
  2255. {
  2256. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DEBUG));
  2257. dwExitCode = EXIT_FAILURE;
  2258. break;
  2259. }
  2260. if( StringLengthW(szPort, 0)!=0 )
  2261. {
  2262. if ( GetSubString(szOsLoadOptions,TOKEN_DEBUGPORT,szTemp) == EXIT_FAILURE)
  2263. {
  2264. ShowMessage(stderr,GetResString(IDS_NO_DEBUGPORT));
  2265. return EXIT_FAILURE ;
  2266. }
  2267. if(StringLengthW(szTemp, 0)!=0)
  2268. {
  2269. //remove the existing entry from the OsLoadOptions String.
  2270. removeSubString(szOsLoadOptions,szTemp);
  2271. }
  2272. //Add the port entry specified by user into the OsLoadOptions String.
  2273. if(StringLengthW(szTmpBuffer, 0)==0)
  2274. {
  2275. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2276. }
  2277. else
  2278. {
  2279. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2280. }
  2281. StringConcat(szTmpBuffer,TOKEN_DEBUGPORT, SIZE_OF_ARRAY(szTmpBuffer)) ;
  2282. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer)) ;
  2283. CharUpper(szPort);
  2284. StringConcat(szTmpBuffer,szPort, SIZE_OF_ARRAY(szTmpBuffer));
  2285. }
  2286. //Check if the OS Load Options contains the baud rate already specified.
  2287. if(StringLengthW(szBaudRate, 0)!=0)
  2288. {
  2289. StringCopy(szTemp,NULL_STRING, SIZE_OF_ARRAY(szTemp));
  2290. GetBaudRateVal(szOsLoadOptions,szTemp) ;
  2291. if(StringLengthW(szTemp, 0)!=0)
  2292. {
  2293. removeSubString(szOsLoadOptions,szTemp);
  2294. }
  2295. //add the baud rate value to boot entry
  2296. if(StringLengthW(szTmpBuffer, 0) == 0)
  2297. {
  2298. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2299. }
  2300. else
  2301. {
  2302. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2303. }
  2304. StringConcat(szTmpBuffer,BAUD_RATE, SIZE_OF_ARRAY(szTmpBuffer));
  2305. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer));
  2306. StringConcat(szTmpBuffer,szBaudRate, SIZE_OF_ARRAY(szTmpBuffer));
  2307. }
  2308. }
  2309. //display error message if Os Load options is more than 254
  2310. // characters.
  2311. if(StringLengthW(szOsLoadOptions, 0) + StringLengthW(szTmpBuffer,0)> MAX_RES_STRING)
  2312. {
  2313. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2314. return EXIT_FAILURE ;
  2315. }
  2316. else
  2317. {
  2318. StringConcat(szOsLoadOptions,szTmpBuffer, SIZE_OF_ARRAY(szOsLoadOptions));
  2319. }
  2320. // modify the Boot Entry with the modified OsLoad Options.
  2321. dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions);
  2322. if(dwExitCode == ERROR_SUCCESS)
  2323. {
  2324. ShowMessageEx(stdout,1,TRUE, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID);
  2325. }
  2326. else
  2327. {
  2328. ShowMessageEx(stderr,1,TRUE, GetResString(IDS_ERROR_CHANGE_OSOPTIONS),dwBootID);
  2329. }
  2330. break;
  2331. }
  2332. }
  2333. if(FALSE == bBootIdFound )
  2334. {
  2335. //Could not find the BootID specified by the user so output the message and return failure
  2336. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  2337. dwExitCode = EXIT_FAILURE;
  2338. }
  2339. //Remember to free memory allocated for the linked lists
  2340. Freelist();
  2341. return (dwExitCode);
  2342. }
  2343. VOID
  2344. GetComPortType_IA64( IN LPTSTR szString,
  2345. IN LPTSTR szTemp
  2346. )
  2347. /*++
  2348. Routine Description:
  2349. Get the Type of Com Port present in Boot Entry
  2350. Arguments :
  2351. [ in ] szString : The String which is to be searched.
  2352. [ in ] szTemp : String which will get the com port type
  2353. Return Type : VOID
  2354. --*/
  2355. {
  2356. if(FindString(szString,PORT_COM1A, 0)!=0)
  2357. {
  2358. StringCopy(szTemp,PORT_COM1A, MAX_RES_STRING);
  2359. }
  2360. else if(FindString(szString,PORT_COM2A,0)!=0)
  2361. {
  2362. StringCopy(szTemp,PORT_COM2A, MAX_RES_STRING);
  2363. }
  2364. else if(FindString(szString,PORT_COM3A,0)!=0)
  2365. {
  2366. StringCopy(szTemp,PORT_COM3A, MAX_RES_STRING);
  2367. }
  2368. else if(FindString(szString,PORT_COM4A,0)!=0)
  2369. {
  2370. StringCopy(szTemp,PORT_COM4A, MAX_RES_STRING);
  2371. }
  2372. else if(FindString(szString,PORT_1394A,0)!=0)
  2373. {
  2374. StringCopy(szTemp,PORT_1394A, MAX_RES_STRING);
  2375. }
  2376. }
  2377. DWORD
  2378. ProcessEmsSwitch_IA64( IN DWORD argc,
  2379. IN LPCTSTR argv[]
  2380. )
  2381. /*++
  2382. Routine Description :
  2383. Which process the ems switch.
  2384. Arguments :
  2385. [ in ] argc - Number of command line arguments
  2386. [ in ] argv - Array containing command line arguments
  2387. Return Type : DWORD
  2388. --*/
  2389. {
  2390. PMY_BOOT_ENTRY mybootEntry;
  2391. PLIST_ENTRY listEntry;
  2392. PBOOT_ENTRY bootEntry;
  2393. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ;
  2394. BOOL bUsage = FALSE ;
  2395. DWORD dwBootID = 0;
  2396. BOOL bBootIdFound = FALSE;
  2397. DWORD dwExitCode = ERROR_SUCCESS;
  2398. TCHAR szEms[MAX_STRING_LENGTH+1] = NULL_STRING ;
  2399. BOOL bEms = FALSE ;
  2400. TCHAR szOsLoadOptions[MAX_RES_STRING+1] = NULL_STRING ;
  2401. TCHAR szTmpBuffer[MAX_RES_STRING+1] = NULL_STRING ;
  2402. DWORD dwExitcode = 0 ;
  2403. TCMDPARSER2 cmdOptions[4];
  2404. PTCMDPARSER2 pcmdOption;
  2405. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  2406. //main option
  2407. pcmdOption = &cmdOptions[0];
  2408. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2409. pcmdOption->pwszOptions = CMDOPTION_EMS;
  2410. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2411. pcmdOption->dwCount = 1;
  2412. pcmdOption->pValue = &bEms;
  2413. //usage
  2414. pcmdOption = &cmdOptions[1];
  2415. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2416. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  2417. pcmdOption->dwFlags = CP2_USAGE;
  2418. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2419. pcmdOption->dwCount = 1;
  2420. pcmdOption->pValue = &bUsage;
  2421. //id option
  2422. pcmdOption = &cmdOptions[2];
  2423. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2424. pcmdOption->pwszOptions = SWITCH_ID;
  2425. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  2426. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  2427. pcmdOption->dwCount = 1;
  2428. pcmdOption->pValue = &dwBootID;
  2429. //default on/off option
  2430. pcmdOption = &cmdOptions[3];
  2431. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2432. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  2433. pcmdOption->dwFlags = CP2_DEFAULT | CP2_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;;
  2434. pcmdOption->dwType = CP_TYPE_TEXT;
  2435. pcmdOption->dwCount = 1;
  2436. pcmdOption->pValue = szEms;
  2437. pcmdOption->dwLength= MAX_STRING_LENGTH;
  2438. // Parsing the ems option switches
  2439. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  2440. {
  2441. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  2442. return (EXIT_FAILURE);
  2443. }
  2444. //check if usage is specified with more than one option
  2445. if( (TRUE == bUsage) && (argc > 3) )
  2446. {
  2447. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_EMS));
  2448. return ( EXIT_FAILURE );
  2449. }
  2450. // Displaying query usage if user specified -? with -query option
  2451. if( bUsage )
  2452. {
  2453. displayEmsUsage_IA64();
  2454. return (EXIT_SUCCESS);
  2455. }
  2456. dwExitcode = InitializeEFI();
  2457. if(EXIT_FAILURE == dwExitcode )
  2458. {
  2459. return EXIT_FAILURE ;
  2460. }
  2461. //display error message if the user enters any other string other that on/off.
  2462. if( !((StringCompare(szEms,VALUE_ON,TRUE,0)== 0) || (StringCompare(szEms,VALUE_OFF,TRUE,0)== 0)))
  2463. {
  2464. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_EMS));
  2465. return EXIT_FAILURE ;
  2466. }
  2467. //Query the boot entries till u get the BootID specified by the user
  2468. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  2469. {
  2470. //Get the boot entry
  2471. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  2472. if(mybootEntry->myId == dwBootID)
  2473. {
  2474. bBootIdFound = TRUE;
  2475. bootEntry = &mybootEntry->NtBootEntry;
  2476. //Check whether the bootEntry is a Windows one or not.
  2477. //The OS load options can be added only to a Windows boot entry.
  2478. if(!IsBootEntryWindows(bootEntry))
  2479. {
  2480. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  2481. dwExitCode = EXIT_FAILURE;
  2482. break;
  2483. }
  2484. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  2485. if(StringLengthW(pWindowsOptions->OsLoadOptions, 0) > MAX_RES_STRING)
  2486. {
  2487. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2488. return EXIT_FAILURE ;
  2489. }
  2490. // copy the existing OS Loadoptions into a string.
  2491. StringCopy(szOsLoadOptions,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szOsLoadOptions));
  2492. //check if the user has entered On option
  2493. if( StringCompare(szEms,VALUE_ON,TRUE,0)== 0)
  2494. {
  2495. if (FindString(szOsLoadOptions,REDIRECT_SWITCH, 0) != 0 )
  2496. {
  2497. ShowMessage(stderr,GetResString(IDS_DUPL_REDIRECT));
  2498. dwExitCode = EXIT_FAILURE;
  2499. break;
  2500. }
  2501. // add the redirect switch to the OS Load Options string.
  2502. if( StringLength(szOsLoadOptions,0) != 0 )
  2503. {
  2504. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2505. StringConcat(szTmpBuffer,REDIRECT_SWITCH, SIZE_OF_ARRAY(szTmpBuffer) );
  2506. }
  2507. else
  2508. {
  2509. StringCopy(szTmpBuffer,REDIRECT_SWITCH, SIZE_OF_ARRAY(szTmpBuffer) );
  2510. }
  2511. }
  2512. //check if the user has entered OFF option
  2513. if( StringCompare(szEms,VALUE_OFF,TRUE,0)== 0)
  2514. {
  2515. // If the user enters either com port or baud rate then display error message and exit.
  2516. if (FindString(szOsLoadOptions,REDIRECT_SWITCH, 0) == 0 )
  2517. {
  2518. ShowMessage(stderr,GetResString(IDS_REDIRECT_ABSENT));
  2519. dwExitCode = EXIT_FAILURE;
  2520. break;
  2521. }
  2522. //remove the debug switch from the OSLoad Options
  2523. removeSubString(szOsLoadOptions,REDIRECT_SWITCH);
  2524. }
  2525. //display error message if Os Load options is more than 254
  2526. // characters.
  2527. if(StringLengthW(szOsLoadOptions, 0)+StringLength(szTmpBuffer,0) > MAX_RES_STRING)
  2528. {
  2529. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2530. return EXIT_FAILURE ;
  2531. }
  2532. else
  2533. {
  2534. StringConcat( szOsLoadOptions, szTmpBuffer, SIZE_OF_ARRAY(szOsLoadOptions) );
  2535. }
  2536. // modify the Boot Entry with the modified OsLoad Options.
  2537. dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions);
  2538. if(dwExitCode == ERROR_SUCCESS)
  2539. {
  2540. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID);
  2541. }
  2542. else
  2543. {
  2544. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_CHANGE_OSOPTIONS),dwBootID);
  2545. }
  2546. break;
  2547. }
  2548. }
  2549. if(bBootIdFound == FALSE)
  2550. {
  2551. //Could not find the BootID specified by the user so output the message and return failure
  2552. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  2553. dwExitCode = EXIT_FAILURE;
  2554. }
  2555. //free the global linked lists
  2556. Freelist();
  2557. return (dwExitCode);
  2558. }
  2559. DWORD
  2560. ProcessAddSwSwitch_IA64( IN DWORD argc,
  2561. IN LPCTSTR argv[]
  2562. )
  2563. /*++
  2564. Routine Description :
  2565. Which implements the Addsw switch.
  2566. Arguments :
  2567. [ in ] argc - Number of command line arguments
  2568. [ in ] argv - Array containing command line arguments
  2569. Return Type : DWORD
  2570. Returns EXIT_SUCCESS if it is successful,
  2571. return EXIT_FAILURE otherwise.
  2572. --*/
  2573. {
  2574. BOOL bUsage = FALSE ;
  2575. BOOL bAddSw = FALSE ;
  2576. DWORD dwBootID = 0;
  2577. BOOL bBootIdFound = FALSE;
  2578. DWORD dwExitCode = ERROR_SUCCESS;
  2579. PMY_BOOT_ENTRY mybootEntry;
  2580. PLIST_ENTRY listEntry;
  2581. PBOOT_ENTRY bootEntry;
  2582. BOOL bBaseVideo = FALSE ;
  2583. BOOL bNoGui = FALSE ;
  2584. BOOL bSos = FALSE ;
  2585. DWORD dwMaxmem = 0 ;
  2586. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ;
  2587. TCHAR szOsLoadOptions[MAX_RES_STRING+1] = NULL_STRING ;
  2588. TCHAR szTmpBuffer[MAX_RES_STRING+1] = NULL_STRING ;
  2589. TCHAR szMaxmem[MAX_RES_STRING+1] = NULL_STRING ;
  2590. DWORD dwExitcode = 0 ;
  2591. TCMDPARSER2 cmdOptions[7];
  2592. PTCMDPARSER2 pcmdOption;
  2593. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  2594. //main option
  2595. pcmdOption = &cmdOptions[0];
  2596. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2597. pcmdOption->pwszOptions = CMDOPTION_ADDSW;
  2598. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2599. pcmdOption->dwCount = 1;
  2600. pcmdOption->pValue = &bAddSw;
  2601. // usage
  2602. pcmdOption = &cmdOptions[1];
  2603. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2604. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  2605. pcmdOption->dwFlags = CP2_USAGE;
  2606. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2607. pcmdOption->dwCount = 1;
  2608. pcmdOption->pValue = &bUsage;
  2609. //id option
  2610. pcmdOption = &cmdOptions[2];
  2611. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2612. pcmdOption->pwszOptions = SWITCH_ID;
  2613. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  2614. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  2615. pcmdOption->dwCount = 1;
  2616. pcmdOption->pValue = &dwBootID;
  2617. //maxmem option
  2618. pcmdOption = &cmdOptions[3];
  2619. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2620. pcmdOption->pwszOptions = SWITCH_MAXMEM;
  2621. pcmdOption->dwFlags = CP_VALUE_MANDATORY;
  2622. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  2623. pcmdOption->dwCount = 1;
  2624. pcmdOption->pValue = &dwMaxmem;
  2625. //basvideo option
  2626. pcmdOption = &cmdOptions[4];
  2627. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2628. pcmdOption->pwszOptions = SWITCH_BASEVIDEO;
  2629. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2630. pcmdOption->dwCount = 1;
  2631. pcmdOption->pValue = &bBaseVideo;
  2632. //nogui option
  2633. pcmdOption = &cmdOptions[5];
  2634. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2635. pcmdOption->pwszOptions = SWITCH_NOGUIBOOT;
  2636. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2637. pcmdOption->dwCount = 1;
  2638. pcmdOption->pValue = &bNoGui;
  2639. //nogui option
  2640. pcmdOption = &cmdOptions[6];
  2641. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2642. pcmdOption->pwszOptions = SWITCH_SOS;
  2643. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2644. pcmdOption->dwCount = 1;
  2645. pcmdOption->pValue = &bSos;
  2646. // Parsing the copy option switches
  2647. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  2648. {
  2649. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  2650. return (EXIT_FAILURE);
  2651. }
  2652. //check if usage is specified with more than one option
  2653. if( (TRUE == bUsage) && (argc > 3) )
  2654. {
  2655. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_ADDSW));
  2656. return ( EXIT_FAILURE );
  2657. }
  2658. // Displaying query usage if user specified -? with -query option
  2659. if( bUsage )
  2660. {
  2661. displayAddSwUsage_IA64();
  2662. return (EXIT_SUCCESS);
  2663. }
  2664. dwExitcode = InitializeEFI();
  2665. if(EXIT_FAILURE == dwExitcode )
  2666. {
  2667. return EXIT_FAILURE ;
  2668. }
  2669. if((0==dwMaxmem)&&(cmdOptions[3].dwActuals!=0))
  2670. {
  2671. ShowMessage(stderr,GetResString(IDS_ERROR_MAXMEM_VALUES));
  2672. return EXIT_FAILURE ;
  2673. }
  2674. //display an error mesage if none of the options are specified.
  2675. if((!bSos)&&(!bBaseVideo)&&(!bNoGui)&&(dwMaxmem==0))
  2676. {
  2677. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_ADDSW));
  2678. return EXIT_FAILURE ;
  2679. }
  2680. //Query the boot entries till u get the BootID specified by the user
  2681. for (listEntry = BootEntries.Flink;listEntry != &BootEntries; listEntry = listEntry->Flink)
  2682. {
  2683. //Get the boot entry
  2684. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  2685. if(mybootEntry->myId == dwBootID)
  2686. {
  2687. bBootIdFound = TRUE;
  2688. bootEntry = &mybootEntry->NtBootEntry;
  2689. //Check whether the bootEntry is a Windows one or not.
  2690. //The OS load options can be added only to a Windows boot entry.
  2691. if(!IsBootEntryWindows(bootEntry))
  2692. {
  2693. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  2694. dwExitCode = EXIT_FAILURE;
  2695. break;
  2696. }
  2697. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  2698. if(StringLengthW(pWindowsOptions->OsLoadOptions,0) > MAX_RES_STRING)
  2699. {
  2700. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2701. return EXIT_FAILURE ;
  2702. }
  2703. // copy the existing OS Loadoptions into a string.
  2704. StringCopy(szOsLoadOptions,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szOsLoadOptions));
  2705. //check if the user has entered -basevideo option
  2706. if(bBaseVideo)
  2707. {
  2708. if (FindString(szOsLoadOptions,BASEVIDEO_VALUE, 0) != 0 )
  2709. {
  2710. ShowMessage(stderr,GetResString(IDS_DUPL_BASEVIDEO_SWITCH));
  2711. dwExitCode = EXIT_FAILURE;
  2712. break;
  2713. }
  2714. else
  2715. {
  2716. StringCopy(szTmpBuffer,BASEVIDEO_VALUE, SIZE_OF_ARRAY(szTmpBuffer) );
  2717. }
  2718. }
  2719. if(bSos)
  2720. {
  2721. if (FindString(szOsLoadOptions,SOS_VALUE, 0) != 0 )
  2722. {
  2723. ShowMessage(stderr,GetResString(IDS_DUPL_SOS_SWITCH));
  2724. dwExitCode = EXIT_FAILURE;
  2725. break;
  2726. }
  2727. else
  2728. {
  2729. // add the sos switch to the OS Load Options string.
  2730. if(StringLengthW(szTmpBuffer, 0) != 0)
  2731. {
  2732. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2733. StringConcat(szTmpBuffer,SOS_VALUE, SIZE_OF_ARRAY(szTmpBuffer));
  2734. }
  2735. else
  2736. {
  2737. StringCopy(szTmpBuffer,SOS_VALUE, SIZE_OF_ARRAY(szTmpBuffer));
  2738. }
  2739. }
  2740. }
  2741. if(bNoGui)
  2742. {
  2743. if (FindString(szOsLoadOptions,NOGUI_VALUE, 0) != 0 )
  2744. {
  2745. ShowMessage(stderr,GetResString(IDS_DUPL_NOGUI_SWITCH));
  2746. dwExitCode = EXIT_FAILURE;
  2747. break;
  2748. }
  2749. else
  2750. {
  2751. // add the no gui switch to the OS Load Options string.
  2752. if(StringLengthW(szTmpBuffer, 0) != 0)
  2753. {
  2754. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2755. StringConcat(szTmpBuffer,NOGUI_VALUE, SIZE_OF_ARRAY(szTmpBuffer));
  2756. }
  2757. else
  2758. {
  2759. StringCopy(szTmpBuffer,NOGUI_VALUE, SIZE_OF_ARRAY(szTmpBuffer));
  2760. }
  2761. }
  2762. }
  2763. if(dwMaxmem!=0)
  2764. {
  2765. // check if the maxmem value is in the valid range.
  2766. if( (dwMaxmem < 32) )
  2767. {
  2768. ShowMessage(stderr,GetResString(IDS_ERROR_MAXMEM_VALUES));
  2769. dwExitCode = EXIT_FAILURE;
  2770. break;
  2771. }
  2772. if (FindString(szOsLoadOptions,MAXMEM_VALUE1, 0) != 0 )
  2773. {
  2774. ShowMessage(stderr,GetResString(IDS_DUPL_MAXMEM_SWITCH));
  2775. dwExitCode = EXIT_FAILURE;
  2776. break;
  2777. }
  2778. else
  2779. {
  2780. // add the maxmem switch to the OS Load Options string.
  2781. if(StringLengthW(szTmpBuffer, 0) != 0)
  2782. {
  2783. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  2784. StringConcat(szTmpBuffer,MAXMEM_VALUE1, SIZE_OF_ARRAY(szTmpBuffer));
  2785. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer));
  2786. _ltow(dwMaxmem,szMaxmem,10);
  2787. StringConcat(szTmpBuffer,szMaxmem, SIZE_OF_ARRAY(szTmpBuffer));
  2788. }
  2789. else
  2790. {
  2791. StringCopy(szTmpBuffer,MAXMEM_VALUE1, SIZE_OF_ARRAY(szTmpBuffer));
  2792. StringConcat(szTmpBuffer,TOKEN_EQUAL, SIZE_OF_ARRAY(szTmpBuffer));
  2793. _ltow(dwMaxmem,szMaxmem,10);
  2794. StringConcat(szTmpBuffer,szMaxmem, SIZE_OF_ARRAY(szTmpBuffer));
  2795. }
  2796. }
  2797. }
  2798. //display error message if Os Load options is more than 254
  2799. // characters.
  2800. if(StringLengthW(szOsLoadOptions, 0)+StringLength(szTmpBuffer,0) + StringLength(TOKEN_EMPTYSPACE,0)> MAX_RES_STRING)
  2801. {
  2802. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2803. return EXIT_FAILURE ;
  2804. }
  2805. else
  2806. {
  2807. if( StringLength(szOsLoadOptions,0) != 0 )
  2808. {
  2809. StringConcat(szOsLoadOptions,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szOsLoadOptions));
  2810. StringConcat(szOsLoadOptions,szTmpBuffer,SIZE_OF_ARRAY(szOsLoadOptions));
  2811. }
  2812. else
  2813. {
  2814. StringCopy(szOsLoadOptions,szTmpBuffer,SIZE_OF_ARRAY(szOsLoadOptions));
  2815. }
  2816. }
  2817. //Change the OS load options. Pass NULL to friendly name as we are not changing the same
  2818. //szRawString is the Os load options specified by the user
  2819. dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions);
  2820. if(dwExitCode == ERROR_SUCCESS)
  2821. {
  2822. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_OSOPTIONS),dwBootID);
  2823. }
  2824. else
  2825. {
  2826. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  2827. }
  2828. break;
  2829. }
  2830. }
  2831. if(bBootIdFound == FALSE)
  2832. {
  2833. //Could not find the BootID specified by the user so output the message and return failure
  2834. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  2835. dwExitCode = EXIT_FAILURE;
  2836. }
  2837. //Remember to free memory allocated for the linked lists
  2838. Freelist();
  2839. return (dwExitCode);
  2840. }
  2841. DWORD
  2842. ProcessRmSwSwitch_IA64( IN DWORD argc,
  2843. IN LPCTSTR argv[]
  2844. )
  2845. /*++
  2846. Routine Description :
  2847. Process the rmsw switch
  2848. Arguments :
  2849. [ in ] argc - Number of command line arguments
  2850. [ in ] argv - Array containing command line arguments
  2851. Return Type : DWORD
  2852. Returns EXIT_SUCCESS if it is successful,
  2853. returns EXIT_FAILURE otherwise.
  2854. --*/
  2855. {
  2856. BOOL bUsage = FALSE ;
  2857. BOOL bRmSw = FALSE ;
  2858. DWORD dwBootID = 0;
  2859. BOOL bBootIdFound = FALSE;
  2860. DWORD dwExitCode = ERROR_SUCCESS;
  2861. PMY_BOOT_ENTRY mybootEntry;
  2862. PLIST_ENTRY listEntry;
  2863. PBOOT_ENTRY bootEntry;
  2864. BOOL bBaseVideo = FALSE ;
  2865. BOOL bNoGui = FALSE ;
  2866. BOOL bSos = FALSE ;
  2867. BOOL bMaxmem = FALSE ;
  2868. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ;
  2869. TCHAR szOsLoadOptions[MAX_RES_STRING+1] = NULL_STRING ;
  2870. TCHAR szTemp[MAX_RES_STRING+1] = NULL_STRING ;
  2871. DWORD dwExitcode = 0 ;
  2872. TCMDPARSER2 cmdOptions[7];
  2873. PTCMDPARSER2 pcmdOption;
  2874. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  2875. //main option
  2876. pcmdOption = &cmdOptions[0];
  2877. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2878. pcmdOption->pwszOptions = CMDOPTION_RMSW;
  2879. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2880. pcmdOption->dwCount = 1;
  2881. pcmdOption->pValue = &bRmSw;
  2882. // usage
  2883. pcmdOption = &cmdOptions[1];
  2884. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2885. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  2886. pcmdOption->dwFlags = CP2_USAGE;
  2887. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2888. pcmdOption->dwCount = 1;
  2889. pcmdOption->pValue = &bUsage;
  2890. //id option
  2891. pcmdOption = &cmdOptions[2];
  2892. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2893. pcmdOption->pwszOptions = SWITCH_ID;
  2894. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  2895. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  2896. pcmdOption->dwCount = 1;
  2897. pcmdOption->pValue = &dwBootID;
  2898. //maxmem option
  2899. pcmdOption = &cmdOptions[3];
  2900. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2901. pcmdOption->pwszOptions = SWITCH_MAXMEM;
  2902. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2903. pcmdOption->dwCount = 1;
  2904. pcmdOption->pValue = &bMaxmem;
  2905. //basvideo option
  2906. pcmdOption = &cmdOptions[4];
  2907. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2908. pcmdOption->pwszOptions = SWITCH_BASEVIDEO;
  2909. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2910. pcmdOption->dwCount = 1;
  2911. pcmdOption->pValue = &bBaseVideo;
  2912. //nogui option
  2913. pcmdOption = &cmdOptions[5];
  2914. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2915. pcmdOption->pwszOptions = SWITCH_NOGUIBOOT;
  2916. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2917. pcmdOption->dwCount = 1;
  2918. pcmdOption->pValue = &bNoGui;
  2919. //sos option
  2920. pcmdOption = &cmdOptions[6];
  2921. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  2922. pcmdOption->pwszOptions = SWITCH_SOS;
  2923. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  2924. pcmdOption->dwCount = 1;
  2925. pcmdOption->pValue = &bSos;
  2926. // Parsing the copy option switches
  2927. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  2928. {
  2929. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  2930. return (EXIT_FAILURE);
  2931. }
  2932. //check if usage is specified with more than one option
  2933. if( (TRUE == bUsage) && (argc > 3) )
  2934. {
  2935. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_RMSW));
  2936. return ( EXIT_FAILURE );
  2937. }
  2938. // Displaying query usage if user specified -? with -query option
  2939. if( bUsage )
  2940. {
  2941. displayRmSwUsage_IA64();
  2942. return (EXIT_SUCCESS);
  2943. }
  2944. dwExitcode = InitializeEFI();
  2945. if(EXIT_FAILURE == dwExitcode )
  2946. {
  2947. return EXIT_FAILURE ;
  2948. }
  2949. //display an error mesage if none of the options are specified.
  2950. if((!bSos)&&(!bBaseVideo)&&(!bNoGui)&&(!bMaxmem))
  2951. {
  2952. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_RMSW));
  2953. return EXIT_FAILURE;
  2954. }
  2955. //Query the boot entries till u get the BootID specified by the user
  2956. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  2957. {
  2958. //Get the boot entry
  2959. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  2960. if(mybootEntry->myId == dwBootID)
  2961. {
  2962. bBootIdFound = TRUE;
  2963. bootEntry = &mybootEntry->NtBootEntry;
  2964. //Check whether the bootEntry is a Windows one or not.
  2965. //The OS load options can be added only to a Windows boot entry.
  2966. if(!IsBootEntryWindows(bootEntry))
  2967. {
  2968. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  2969. dwExitCode = EXIT_FAILURE;
  2970. break;
  2971. }
  2972. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  2973. if(StringLengthW(pWindowsOptions->OsLoadOptions, 0) > MAX_RES_STRING)
  2974. {
  2975. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  2976. return EXIT_FAILURE ;
  2977. }
  2978. // copy the existing OS Loadoptions into a string.
  2979. StringCopy(szOsLoadOptions,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szOsLoadOptions));
  2980. //check if the user has entered -basevideo option
  2981. if(bBaseVideo)
  2982. {
  2983. if (FindString(szOsLoadOptions,BASEVIDEO_VALUE, 0) == 0 )
  2984. {
  2985. ShowMessage(stderr,GetResString(IDS_NO_BV_SWITCH));
  2986. dwExitCode = EXIT_FAILURE;
  2987. break;
  2988. }
  2989. else
  2990. {
  2991. // remove the basevideo switch from the OS Load Options string.
  2992. removeSubString(szOsLoadOptions,BASEVIDEO_VALUE);
  2993. }
  2994. }
  2995. if(bSos)
  2996. {
  2997. if (FindString(szOsLoadOptions,SOS_VALUE, 0) == 0 )
  2998. {
  2999. ShowMessage(stderr,GetResString(IDS_NO_SOS_SWITCH));
  3000. dwExitCode = EXIT_FAILURE;
  3001. break;
  3002. }
  3003. else
  3004. {
  3005. // remove the /sos switch from the Load Options string.
  3006. removeSubString(szOsLoadOptions,SOS_VALUE);
  3007. }
  3008. }
  3009. if(bNoGui)
  3010. {
  3011. if (FindString(szOsLoadOptions,NOGUI_VALUE,0) == 0 )
  3012. {
  3013. ShowMessage(stderr,GetResString(IDS_NO_NOGUI_SWITCH));
  3014. dwExitCode = EXIT_FAILURE;
  3015. break;
  3016. }
  3017. else
  3018. {
  3019. // remove the noguiboot switch to the OS Load Options string.
  3020. removeSubString(szOsLoadOptions,NOGUI_VALUE);
  3021. }
  3022. }
  3023. if(bMaxmem)
  3024. {
  3025. if (FindString(szOsLoadOptions,MAXMEM_VALUE1,0) == 0 )
  3026. {
  3027. ShowMessage(stderr,GetResString(IDS_NO_MAXMEM_SWITCH));
  3028. dwExitCode = EXIT_FAILURE;
  3029. break;
  3030. }
  3031. else
  3032. {
  3033. // add the redirect switch to the OS Load Options string.
  3034. //for, a temporary string of form /maxmem=xx so that it
  3035. //can be checked in the Os load options,
  3036. if ( GetSubString(szOsLoadOptions,MAXMEM_VALUE1,szTemp) == EXIT_FAILURE)
  3037. {
  3038. return EXIT_FAILURE ;
  3039. }
  3040. removeSubString(szOsLoadOptions,szTemp);
  3041. if(FindString(szOsLoadOptions,MAXMEM_VALUE1,0)!=0)
  3042. {
  3043. ShowMessage(stderr,GetResString(IDS_NO_MAXMEM) );
  3044. return EXIT_FAILURE ;
  3045. }
  3046. }
  3047. }
  3048. //display error message if Os Load options is more than 254
  3049. // characters.
  3050. if(StringLengthW(szOsLoadOptions,0) > MAX_RES_STRING)
  3051. {
  3052. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  3053. return EXIT_FAILURE ;
  3054. }
  3055. //Change the OS load options. Pass NULL to friendly name as we are not changing the same
  3056. //szRawString is the Os load options specified by the user
  3057. dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions);
  3058. if(dwExitCode == ERROR_SUCCESS)
  3059. {
  3060. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID);
  3061. }
  3062. else
  3063. {
  3064. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  3065. }
  3066. break;
  3067. }
  3068. }
  3069. if(bBootIdFound == FALSE)
  3070. {
  3071. //Could not find the BootID specified by the user so output the message and return failure
  3072. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  3073. dwExitCode = EXIT_FAILURE;
  3074. }
  3075. Freelist();
  3076. return (dwExitCode);
  3077. }
  3078. DWORD
  3079. ProcessDbg1394Switch_IA64( IN DWORD argc,
  3080. IN LPCTSTR argv[]
  3081. )
  3082. /*++
  3083. Routine Description :
  3084. Which process the dbg1394 switch
  3085. Arguments :
  3086. [ in ] argc - Number of command line arguments
  3087. [ in ] argv - Array containing command line arguments
  3088. Return Type : DWORD
  3089. Returns EXIT_SUCCESS if it is successful,
  3090. returns EXIT_FAILURE otherwise.
  3091. --*/
  3092. {
  3093. BOOL bUsage = FALSE ;
  3094. BOOL bDbg1394 = FALSE ;
  3095. DWORD dwBootID = 0;
  3096. BOOL bBootIdFound = FALSE;
  3097. DWORD dwExitCode = ERROR_SUCCESS;
  3098. PMY_BOOT_ENTRY mybootEntry;
  3099. PLIST_ENTRY listEntry;
  3100. PBOOT_ENTRY bootEntry;
  3101. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL ;
  3102. TCHAR szOsLoadOptions[MAX_RES_STRING+1] = NULL_STRING ;
  3103. TCHAR szTemp[MAX_RES_STRING+1] = NULL_STRING ;
  3104. TCHAR szTmpBuffer[MAX_RES_STRING+1] = NULL_STRING ;
  3105. TCHAR szChannel[MAX_RES_STRING+1] = NULL_STRING ;
  3106. TCHAR szDefault[MAX_RES_STRING+1] = NULL_STRING ;
  3107. DWORD dwChannel = 0 ;
  3108. DWORD dwCode = 0 ;
  3109. DWORD dwExitcode = 0 ;
  3110. TCMDPARSER2 cmdOptions[5];
  3111. PTCMDPARSER2 pcmdOption;
  3112. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  3113. //main option
  3114. pcmdOption = &cmdOptions[0];
  3115. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3116. pcmdOption->pwszOptions = CMDOPTION_DBG1394;
  3117. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  3118. pcmdOption->dwCount = 1;
  3119. pcmdOption->pValue = &bDbg1394;
  3120. //id usage
  3121. pcmdOption = &cmdOptions[1];
  3122. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3123. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  3124. pcmdOption->dwFlags = CP2_USAGE;
  3125. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  3126. pcmdOption->dwCount = 1;
  3127. pcmdOption->pValue = &bUsage;
  3128. //default option
  3129. pcmdOption = &cmdOptions[2];
  3130. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3131. pcmdOption->pwszOptions = SWITCH_ID;
  3132. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_MANDATORY;
  3133. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  3134. pcmdOption->dwCount = 1;
  3135. pcmdOption->pValue = &dwBootID;
  3136. //id option
  3137. pcmdOption = &cmdOptions[3];
  3138. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3139. pcmdOption->pwszOptions = CMDOPTION_CHANNEL;
  3140. pcmdOption->dwFlags = CP_VALUE_MANDATORY;
  3141. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  3142. pcmdOption->dwCount = 1;
  3143. pcmdOption->pValue = &dwChannel;
  3144. //default option
  3145. pcmdOption = &cmdOptions[4];
  3146. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3147. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  3148. pcmdOption->dwFlags = CP2_DEFAULT | CP2_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL;;
  3149. pcmdOption->dwType = CP_TYPE_TEXT;
  3150. pcmdOption->dwCount = 1;
  3151. pcmdOption->pValue = szDefault;
  3152. pcmdOption->dwLength= MAX_STRING_LENGTH;
  3153. // Parsing the copy option switches
  3154. if ( !DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) )
  3155. {
  3156. ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3157. return (EXIT_FAILURE);
  3158. }
  3159. //check if usage is specified with more than one option
  3160. if( (TRUE == bUsage) && (argc > 3) )
  3161. {
  3162. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DBG1394));
  3163. return ( EXIT_FAILURE );
  3164. }
  3165. // Displaying query usage if user specified -? with -query option
  3166. if( bUsage )
  3167. {
  3168. displayDbg1394Usage_IA64() ;
  3169. return (EXIT_SUCCESS);
  3170. }
  3171. dwExitcode = InitializeEFI();
  3172. if(EXIT_FAILURE == dwExitcode )
  3173. {
  3174. return EXIT_FAILURE ;
  3175. }
  3176. if((cmdOptions[2].dwActuals == 0) &&(dwBootID == 0 ))
  3177. {
  3178. ShowMessage(stderr,GetResString(IDS_ERROR_ID_MISSING));
  3179. ShowMessage(stderr,GetResString(IDS_1394_HELP));
  3180. return (EXIT_FAILURE);
  3181. }
  3182. //
  3183. //display error message if user enters a value
  3184. // other than on or off
  3185. //
  3186. if( ( StringCompare(szDefault,OFF_STRING,TRUE,0)!=0 ) && (StringCompare(szDefault,ON_STRING,TRUE,0)!=0 ) )
  3187. {
  3188. ShowMessage(stderr,GetResString(IDS_ERROR_DEFAULT_MISSING));
  3189. ShowMessage(stderr,GetResString(IDS_1394_HELP));
  3190. return (EXIT_FAILURE);
  3191. }
  3192. if(( StringCompare(szDefault,OFF_STRING,TRUE,0)==0 ) && (cmdOptions[3].dwActuals != 0) )
  3193. {
  3194. ShowMessage(stderr,GetResString(IDS_INVALID_SYNTAX_DBG1394));
  3195. return (EXIT_FAILURE);
  3196. }
  3197. if(( StringCompare(szDefault,ON_STRING,TRUE,0)==0 ) && (cmdOptions[3].dwActuals == 0) )
  3198. {
  3199. ShowMessage(stderr,GetResString(IDS_MISSING_CHANNEL));
  3200. return (EXIT_FAILURE);
  3201. }
  3202. if(( StringCompare(szDefault,ON_STRING,TRUE,0)==0 ) && (cmdOptions[3].dwActuals != 0) &&( (dwChannel < 1) || (dwChannel > 64 ) ) )
  3203. {
  3204. ShowMessage(stderr,GetResString(IDS_INVALID_CH_RANGE));
  3205. return (EXIT_FAILURE);
  3206. }
  3207. //Query the boot entries till u get the BootID specified by the user
  3208. for (listEntry = BootEntries.Flink;listEntry != &BootEntries;listEntry = listEntry->Flink)
  3209. {
  3210. //Get the boot entry
  3211. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  3212. if(mybootEntry->myId == dwBootID)
  3213. {
  3214. bBootIdFound = TRUE;
  3215. bootEntry = &mybootEntry->NtBootEntry;
  3216. //Check whether the bootEntry is a Windows one or not.
  3217. //The OS load options can be added only to a Windows boot entry.
  3218. if(!IsBootEntryWindows(bootEntry))
  3219. {
  3220. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  3221. dwExitCode = EXIT_FAILURE;
  3222. break;
  3223. }
  3224. pWindowsOptions = (PWINDOWS_OS_OPTIONS)bootEntry->OsOptions;
  3225. if(StringLengthW(pWindowsOptions->OsLoadOptions,0) > MAX_RES_STRING)
  3226. {
  3227. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  3228. return EXIT_FAILURE ;
  3229. }
  3230. // copy the existing OS Loadoptions into a string.
  3231. StringCopy(szOsLoadOptions,pWindowsOptions->OsLoadOptions, SIZE_OF_ARRAY(szOsLoadOptions));
  3232. //check if the user has entered on option
  3233. if(StringCompare(szDefault,ON_STRING,TRUE,0)==0 )
  3234. {
  3235. if(FindString(szOsLoadOptions,DEBUGPORT,0) != 0)
  3236. {
  3237. ShowMessage(stderr,GetResString(IDS_DUPLICATE_ENTRY));
  3238. dwExitCode = EXIT_FAILURE;
  3239. break;
  3240. }
  3241. if(FindString(szOsLoadOptions,BAUD_TOKEN,0) != 0)
  3242. {
  3243. ShowMessage(stderr,GetResString(IDS_ERROR_BAUD_RATE));
  3244. dwExitCode = EXIT_FAILURE ;
  3245. break;
  3246. }
  3247. if( FindString(szOsLoadOptions,DEBUG_SWITCH,0)== 0)
  3248. {
  3249. if( StringLength(szOsLoadOptions,0) != 0 )
  3250. {
  3251. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  3252. StringConcat(szTmpBuffer,DEBUG_SWITCH, SIZE_OF_ARRAY(szOsLoadOptions));
  3253. }
  3254. else
  3255. {
  3256. StringCopy(szTmpBuffer,DEBUG_SWITCH, SIZE_OF_ARRAY(szOsLoadOptions));
  3257. }
  3258. }
  3259. if(StringLength(szTmpBuffer,0) == 0)
  3260. {
  3261. StringCopy(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  3262. }
  3263. else
  3264. {
  3265. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE, SIZE_OF_ARRAY(szTmpBuffer));
  3266. }
  3267. StringConcat(szTmpBuffer,DEBUGPORT_1394, SIZE_OF_ARRAY(szTmpBuffer)) ;
  3268. if(dwChannel!=0)
  3269. {
  3270. //frame the string and concatenate to the Os Load options.
  3271. StringConcat(szTmpBuffer,TOKEN_EMPTYSPACE,SIZE_OF_ARRAY(szTmpBuffer));
  3272. StringConcat(szTmpBuffer,TOKEN_CHANNEL,SIZE_OF_ARRAY(szTmpBuffer));
  3273. StringConcat(szTmpBuffer,TOKEN_EQUAL,SIZE_OF_ARRAY(szTmpBuffer));
  3274. _ltow(dwChannel,szChannel,10);
  3275. StringConcat(szTmpBuffer,szChannel,SIZE_OF_ARRAY(szTmpBuffer));
  3276. }
  3277. }
  3278. if(StringCompare(szDefault,OFF_STRING,TRUE,0)==0 )
  3279. {
  3280. if(FindString(szOsLoadOptions,DEBUGPORT_1394,0) == 0)
  3281. {
  3282. ShowMessage(stderr,GetResString(IDS_NO_1394_SWITCH));
  3283. dwExitCode = EXIT_FAILURE;
  3284. break;
  3285. }
  3286. //
  3287. //remove the port from the Os Load options string.
  3288. //
  3289. removeSubString(szOsLoadOptions,DEBUGPORT_1394);
  3290. // check if the string contains the channel token
  3291. // and if present remove that also.
  3292. //
  3293. if(FindString(szOsLoadOptions,TOKEN_CHANNEL,0)!=0)
  3294. {
  3295. StringCopy(szTemp,NULL_STRING, MAX_RES_STRING);
  3296. dwCode = GetSubString(szOsLoadOptions,TOKEN_CHANNEL,szTemp);
  3297. if(dwCode == EXIT_SUCCESS)
  3298. {
  3299. //
  3300. //Remove the channel token if present.
  3301. //
  3302. if(StringLengthW(szTemp,0)!= 0)
  3303. {
  3304. removeSubString(szOsLoadOptions,szTemp);
  3305. removeSubString(szOsLoadOptions,DEBUG_SWITCH);
  3306. }
  3307. }
  3308. }
  3309. removeSubString(szOsLoadOptions,DEBUG_SWITCH);
  3310. }
  3311. //display error message if Os Load options is more than 254
  3312. // characters.
  3313. if(StringLengthW(szOsLoadOptions,0)+StringLength(szTmpBuffer,0) > MAX_RES_STRING)
  3314. {
  3315. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_STRING_LENGTH1),MAX_RES_STRING);
  3316. return EXIT_FAILURE ;
  3317. }
  3318. else
  3319. {
  3320. StringConcat(szOsLoadOptions, szTmpBuffer, SIZE_OF_ARRAY(szOsLoadOptions) );
  3321. }
  3322. //Change the OS load options. Pass NULL to friendly name as we are not changing the same
  3323. //szRawString is the Os load options specified by the user
  3324. dwExitCode = ChangeBootEntry(bootEntry, NULL, szOsLoadOptions);
  3325. if(dwExitCode == ERROR_SUCCESS)
  3326. {
  3327. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_SUCCESS_CHANGE_OSOPTIONS),dwBootID);
  3328. }
  3329. else
  3330. {
  3331. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  3332. }
  3333. break;
  3334. }
  3335. }
  3336. if(bBootIdFound == FALSE)
  3337. {
  3338. //Could not find the BootID specified by the user so output the message and return failure
  3339. ShowMessage(stderr,GetResString(IDS_INVALID_BOOTID));
  3340. dwExitCode = EXIT_FAILURE;
  3341. }
  3342. Freelist();
  3343. return (dwExitCode);
  3344. }
  3345. DWORD
  3346. ProcessMirrorSwitch_IA64( IN DWORD argc,
  3347. IN LPCTSTR argv[]
  3348. )
  3349. /*++
  3350. Routine Description :
  3351. process the mirror switch
  3352. Arguments :
  3353. [ in ] argc - Number of command line arguments
  3354. [ in ] argv - Array containing command line arguments
  3355. Return Type : DWORD
  3356. Returns EXIT_SUCCESS if it is successful,
  3357. returns EXIT_FAILURE otherwise.
  3358. --*/
  3359. {
  3360. BOOL bUsage = FALSE ;
  3361. DWORD dwBootID = 0;
  3362. BOOL bBootIdFound = FALSE;
  3363. DWORD dwExitCode = ERROR_SUCCESS;
  3364. PMY_BOOT_ENTRY mybootEntry;
  3365. TCHAR szAdd[MAX_RES_STRING+1] = NULL_STRING ;
  3366. TCHAR szLoaderPath[MAX_RES_STRING+1] = NULL_STRING ;
  3367. BOOL bMirror = FALSE ;
  3368. NTSTATUS status ;
  3369. DWORD error = 0 ;
  3370. TCHAR szFinalStr[256] = NULL_STRING ;
  3371. TCHAR szResult[MAX_RES_STRING+1] = NULL_STRING ;
  3372. DWORD dwActuals = 0 ;
  3373. PBOOT_ENTRY_LIST ntBootEntries = NULL;
  3374. PBOOT_ENTRY pBootEntry = NULL ;
  3375. PFILE_PATH pFilePath = NULL ;
  3376. PWSTR NtFilePath ;
  3377. PTCHAR szPartition = NULL ;
  3378. TCHAR szOsLoaderPath[MAX_RES_STRING+1] = NULL_STRING ;
  3379. TCHAR szSystemPartition[MAX_RES_STRING+1] = NULL_STRING ;
  3380. TCHAR szBrackets[] = _T("{}");
  3381. PLIST_ENTRY listEntry;
  3382. BOOL bFlag = TRUE ;
  3383. TCHAR szFriendlyName[MAX_STRING_LENGTH] = NULL_STRING ;
  3384. DWORD dwExitcode = 0 ;
  3385. TCMDPARSER2 cmdOptions[5];
  3386. PTCMDPARSER2 pcmdOption;
  3387. BOOL bNobreak = TRUE;
  3388. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  3389. //main option
  3390. pcmdOption = &cmdOptions[0];
  3391. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3392. pcmdOption->pwszOptions = CMDOPTION_MIRROR;
  3393. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  3394. pcmdOption->dwCount = 1;
  3395. pcmdOption->pValue = &bMirror;
  3396. //id usage
  3397. pcmdOption = &cmdOptions[1];
  3398. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3399. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  3400. pcmdOption->dwFlags = CP2_USAGE;
  3401. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  3402. pcmdOption->dwCount = 1;
  3403. pcmdOption->pValue = &bUsage;
  3404. // add option
  3405. pcmdOption = &cmdOptions[2];
  3406. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3407. pcmdOption->pwszOptions = CMDOPTION_ADD;
  3408. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT | CP2_VALUE_NONULL | CP2_MANDATORY;
  3409. pcmdOption->dwType = CP_TYPE_TEXT;
  3410. pcmdOption->dwCount = 1;
  3411. pcmdOption->pValue = szAdd;
  3412. pcmdOption->dwLength= MAX_STRING_LENGTH;
  3413. //id option
  3414. pcmdOption = &cmdOptions[3];
  3415. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3416. pcmdOption->pwszOptions = SWITCH_ID;
  3417. pcmdOption->dwFlags = CP_VALUE_MANDATORY;
  3418. pcmdOption->dwType = CP_TYPE_UNUMERIC;
  3419. pcmdOption->dwCount = 1;
  3420. pcmdOption->pValue = &dwBootID;
  3421. // friendly option
  3422. pcmdOption = &cmdOptions[4];
  3423. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  3424. pcmdOption->pwszOptions = SWITCH_DESCRIPTION;
  3425. pcmdOption->dwFlags = CP_VALUE_MANDATORY | CP2_VALUE_TRIMINPUT;
  3426. pcmdOption->dwType = CP_TYPE_TEXT;
  3427. pcmdOption->dwCount = 1;
  3428. pcmdOption->pValue = szFriendlyName;
  3429. pcmdOption->dwLength= MAX_STRING_LENGTH;
  3430. // Parsing the copy option switches
  3431. if ( !(DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) ) )
  3432. {
  3433. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3434. return (EXIT_FAILURE);
  3435. }
  3436. //check if usage is specified with more than one option
  3437. if( (TRUE == bUsage) && (argc > 3) )
  3438. {
  3439. ShowMessage(stderr,GetResString(IDS_MIRROR_SYNTAX));
  3440. return ( EXIT_FAILURE );
  3441. }
  3442. // Displaying query usage if user specified -? with -query option
  3443. if( bUsage )
  3444. {
  3445. displayMirrorUsage_IA64() ;
  3446. return (EXIT_SUCCESS);
  3447. }
  3448. dwExitcode = InitializeEFI();
  3449. if(EXIT_FAILURE == dwExitcode )
  3450. {
  3451. return EXIT_FAILURE ;
  3452. }
  3453. // If the user enters empty string after add option then display an error
  3454. // message.
  3455. TrimString(szAdd,TRIM_ALL);
  3456. TrimString(szFriendlyName,TRIM_ALL);
  3457. //
  3458. //copy the default friendly name from resource file if no
  3459. //friendly name is specified.
  3460. //
  3461. if(cmdOptions[4].dwActuals == 0)
  3462. {
  3463. StringCopy(szFriendlyName,GetResString(IDS_MIRROR_NAME), SIZE_OF_ARRAY(szFriendlyName));
  3464. }
  3465. if(StringLengthW(szAdd,0) !=0)
  3466. {
  3467. //Trim of the Brackets which may be specified
  3468. //along with the GUID.
  3469. TrimString2(szAdd, szBrackets, TRIM_ALL);
  3470. dwActuals = 0 ;
  3471. //get the ARC signature path corresponding to the GUID specified.
  3472. if (GetDeviceInfo(szAdd,szFinalStr,0,dwActuals) == EXIT_FAILURE )
  3473. {
  3474. return EXIT_FAILURE ;
  3475. }
  3476. StringConcat(szFinalStr,_T("\\WINDOWS"), SIZE_OF_ARRAY(szFinalStr));
  3477. //
  3478. //if the user does specifies /id option
  3479. // then retreive the OS Load Path from the
  3480. // registry
  3481. //
  3482. if(cmdOptions[3].dwActuals == 0 )
  3483. {
  3484. //retreive the Os Loader Path from the registry.
  3485. if(GetBootPath(IDENTIFIER_VALUE2,szResult) != ERROR_SUCCESS )
  3486. {
  3487. ShowMessage(stderr,GetResString(IDS_ERROR_UNEXPECTED));
  3488. return EXIT_FAILURE ;
  3489. }
  3490. //retreive the Os Loader Path from the registry.
  3491. if( GetBootPath(IDENTIFIER_VALUE3,szLoaderPath)!= ERROR_SUCCESS )
  3492. {
  3493. ShowMessage(stderr,GetResString(IDS_ERROR_UNEXPECTED));
  3494. return EXIT_FAILURE ;
  3495. }
  3496. bFlag = TRUE ;
  3497. //call the function which adds the mirror plex.
  3498. if (AddMirrorPlex(szFinalStr,szLoaderPath,szResult,bFlag,szFriendlyName) == EXIT_FAILURE )
  3499. {
  3500. return EXIT_FAILURE ;
  3501. }
  3502. }
  3503. else
  3504. {
  3505. // query the information from the NVRAM .
  3506. status = BootCfg_EnumerateBootEntries(&ntBootEntries);
  3507. if( !NT_SUCCESS(status) )
  3508. {
  3509. error = RtlNtStatusToDosError( status );
  3510. return EXIT_FAILURE ;
  3511. }
  3512. for (listEntry = BootEntries.Flink; listEntry != &BootEntries; listEntry = listEntry->Flink)
  3513. {
  3514. //Get the boot entry
  3515. mybootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  3516. //check for the id specified by the user matches the
  3517. // id
  3518. if(mybootEntry->myId == dwBootID)
  3519. {
  3520. bBootIdFound = TRUE;
  3521. pBootEntry = &mybootEntry->NtBootEntry;
  3522. //Check whether the bootEntry is a Windows one or not.
  3523. //The OS load options can be added only to a Windows boot entry.
  3524. if(!IsBootEntryWindows(pBootEntry))
  3525. {
  3526. ShowMessageEx(stderr, 1, TRUE, GetResString(IDS_ERROR_OSOPTIONS),dwBootID);
  3527. dwExitCode = EXIT_FAILURE;
  3528. break;
  3529. }
  3530. }
  3531. }
  3532. // display an error
  3533. if (pBootEntry == NULL)
  3534. {
  3535. ShowMessage(stderr,GetResString(IDS_PARTITION_ERROR));
  3536. SAFEFREE(ntBootEntries);
  3537. return EXIT_FAILURE ;
  3538. }
  3539. //Get a pointer to the FILE_PATH structure.
  3540. pFilePath = (PFILE_PATH)ADD_OFFSET(pBootEntry, BootFilePathOffset);
  3541. //get the name of the .
  3542. NtFilePath = GetNtNameForFilePath(pFilePath );
  3543. if(NtFilePath == NULL)
  3544. {
  3545. ShowMessage(stderr,GetResString(IDS_ERROR_MIRROR));
  3546. SAFEFREE(ntBootEntries);
  3547. return EXIT_FAILURE ;
  3548. }
  3549. // split the path to get the SystemPartition path and the
  3550. // OsLoader Path .
  3551. szPartition = _tcstok(NtFilePath,_T("\\"));
  3552. //display error message and exit if szPartition is null.
  3553. if(szPartition == NULL)
  3554. {
  3555. ShowMessage(stderr,GetResString(IDS_TOKEN_ABSENT));
  3556. SAFEFREE(ntBootEntries);
  3557. return EXIT_FAILURE ;
  3558. }
  3559. //concatenate the "\" to frame the path .
  3560. StringConcat(szOsLoaderPath,_T("\\"), SIZE_OF_ARRAY(szOsLoaderPath));
  3561. StringConcat(szOsLoaderPath,szPartition, SIZE_OF_ARRAY(szOsLoaderPath) );
  3562. StringConcat(szOsLoaderPath,_T("\\"), SIZE_OF_ARRAY(szOsLoaderPath));
  3563. szPartition = _tcstok(NULL,_T("\\"));
  3564. //display error message and exit if szPartition is null.
  3565. if(NULL == szPartition )
  3566. {
  3567. ShowMessage(stderr,GetResString(IDS_TOKEN_ABSENT));
  3568. SAFEFREE(ntBootEntries);
  3569. return EXIT_FAILURE ;
  3570. }
  3571. StringConcat(szOsLoaderPath,szPartition, SIZE_OF_ARRAY(szOsLoaderPath));
  3572. //Framing the OsLoader Path
  3573. do
  3574. {
  3575. szPartition = _tcstok(NULL,_T("\\"));
  3576. if(szPartition == NULL)
  3577. {
  3578. break ;
  3579. bNobreak = FALSE;
  3580. }
  3581. StringConcat(szSystemPartition,_T("\\"), SIZE_OF_ARRAY(szSystemPartition));
  3582. StringConcat(szSystemPartition,szPartition, SIZE_OF_ARRAY(szSystemPartition));
  3583. }while(TRUE == bNobreak );
  3584. //This flag is for determining if the boot path should be BOOTFILE_PATH1
  3585. //or BOOTFILE_PATH
  3586. bFlag = FALSE ;
  3587. //call the function which adds the mirror plex.
  3588. if ( AddMirrorPlex(szFinalStr,szSystemPartition,szOsLoaderPath,bFlag,szFriendlyName) == EXIT_FAILURE )
  3589. {
  3590. return EXIT_FAILURE ;
  3591. }
  3592. }
  3593. }
  3594. SAFEFREE(ntBootEntries);
  3595. Freelist();
  3596. return EXIT_SUCCESS ;
  3597. }
  3598. NTSTATUS
  3599. FindBootEntry(IN PVOID pEntryListHead,
  3600. IN WCHAR *pwszTarget,
  3601. OUT PBOOT_ENTRY *ppTargetEntry
  3602. )
  3603. /*++
  3604. Routine description : Routine finds a boot entry in the list of all boot
  3605. entries and returns a pointer into the list for the found entry.
  3606. Arguments:
  3607. pEntryListHead - The address of a pointer to a BOOT_ENTRY_LIST struct.
  3608. pwszTarget - The OsLoadPath (install path) string.
  3609. "signature(<part GUID>-<part#>-<part_start>-<part_len>)"
  3610. OR
  3611. "signature(<part GUID>-<part#>-<part_start>-<part_len>)\\WINDOWS"
  3612. on input. If we find the entry in NVRAM, we copy the
  3613. full install path back to the input string so that it includes
  3614. the directory name.
  3615. ppTargetEntry - The address of a BOOT_ENTRY pointer, points to the
  3616. found entry at return.
  3617. Return Value : NT status
  3618. STATUS_INSUFFICIENT_RESOURCES
  3619. STATUS_ACCESS_VIOLATION
  3620. STATUS_UNSUPPORTED
  3621. STATUS_OBJECT_NAME_NOT_FOUND
  3622. STATUS_SUCCESS and *ppTargetEntry should be non-NULL for success.
  3623. --*/
  3624. {
  3625. LONG status = STATUS_SUCCESS;
  3626. PBOOT_ENTRY_LIST pEntryList = NULL;
  3627. PBOOT_ENTRY pEntry = NULL;
  3628. PWINDOWS_OS_OPTIONS pOsOptions = NULL;
  3629. PFILE_PATH pTransEntry = NULL;
  3630. DWORD dwTransSize = 0L;
  3631. DWORD i = 0L;
  3632. BOOL bFlag = FALSE ;
  3633. BOOL bNobreak = FALSE ;
  3634. DWORD dwCount = 0L ;
  3635. TCHAR szFinalStr[256] = NULL_STRING ;
  3636. DWORD dwFailCount = 0L;
  3637. DWORD dwSuccessCount = 0L;
  3638. if ( !pEntryListHead || !pwszTarget || !ppTargetEntry )
  3639. {
  3640. ShowMessage(stderr,GetResString(IDS_FIND_BOOT_ENTRY) );
  3641. return STATUS_INVALID_PARAMETER;
  3642. }
  3643. *ppTargetEntry = NULL;
  3644. pEntryList = (PBOOT_ENTRY_LIST) pEntryListHead;
  3645. //
  3646. // Iterate over all the entries returned looking for the target
  3647. // boot partition's entry. Convert the install path for each
  3648. // entry to the signature format, then compare to the
  3649. // input partition signature formatted path.
  3650. //
  3651. bNobreak = TRUE;
  3652. do
  3653. {
  3654. //
  3655. // Translate the entry's install path to signature format.
  3656. //
  3657. if ( pEntryList )
  3658. {
  3659. pEntry = &pEntryList->BootEntry;
  3660. }
  3661. else
  3662. {
  3663. ShowMessage(stderr,GetResString(IDS_FIND_BOOT_ENTRY_NULL));
  3664. status = STATUS_OBJECT_NAME_NOT_FOUND;
  3665. bNobreak = FALSE;
  3666. break;
  3667. }
  3668. //
  3669. // If this entry does not have the BOOT_ENTRY_ATTRIBUTE_WINDOWS
  3670. // attribute set, or, the attribute is set and this entry has
  3671. // an invalid OsOptions structure length, move to the next entry
  3672. // and continue searching and check the next boot entry
  3673. //
  3674. if ( !(pEntry->Attributes & BOOT_ENTRY_ATTRIBUTE_WINDOWS) || ( (pEntry->Attributes & BOOT_ENTRY_ATTRIBUTE_WINDOWS) && pEntry->OsOptionsLength < sizeof(WINDOWS_OS_OPTIONS) ) )
  3675. {
  3676. //exit from the loop if we have reached the last Boot Entry.
  3677. if ( !pEntryList->NextEntryOffset )
  3678. {
  3679. bNobreak = FALSE;
  3680. break;
  3681. }
  3682. //
  3683. // Continue with the next iteration
  3684. // after obtaining the pointer to the next entry.
  3685. //
  3686. pEntryList = (PBOOT_ENTRY_LIST)(((PBYTE)pEntryList) + pEntryList->NextEntryOffset);
  3687. continue;
  3688. }
  3689. //
  3690. // Use the entry's current length to start and resize
  3691. // if necessary.
  3692. //
  3693. dwTransSize = pEntry->Length;
  3694. for ( i = 1; i <= 2; i++ )
  3695. {
  3696. if ( pTransEntry )
  3697. {
  3698. MEMFREE(pTransEntry);
  3699. pTransEntry = NULL;
  3700. }
  3701. pTransEntry = (PFILE_PATH) MEMALLOC(dwTransSize);
  3702. if ( !pTransEntry )
  3703. {
  3704. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3705. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  3706. status = STATUS_NO_MEMORY;
  3707. SAFEMEMFREE(pTransEntry);
  3708. return status ;
  3709. }
  3710. pOsOptions = (WINDOWS_OS_OPTIONS *)&pEntry->OsOptions;
  3711. status = NtTranslateFilePath
  3712. (
  3713. (PFILE_PATH)( ((PBYTE) pOsOptions) + pOsOptions->OsLoadPathOffset ),
  3714. FILE_PATH_TYPE_ARC_SIGNATURE,
  3715. pTransEntry,
  3716. &dwTransSize
  3717. );
  3718. if ( STATUS_INSUFFICIENT_RESOURCES == status )
  3719. {
  3720. continue;
  3721. }
  3722. else
  3723. {
  3724. break;
  3725. }
  3726. }
  3727. //
  3728. // Ignore STATUS_OBJECT_NAME_NOT_FOUND
  3729. // We shouldn't get that error anyway, since we are using
  3730. // the long signature format.
  3731. //
  3732. if ( !NT_SUCCESS(status)&& STATUS_OBJECT_NAME_NOT_FOUND != status )
  3733. {
  3734. DISPLAY_MESSAGE( stderr,GetResString(IDS_TRANSLATE_FAIL));
  3735. SAFEMEMFREE(pTransEntry);
  3736. return status ;
  3737. }
  3738. //
  3739. // Compare this entry's install path to the current boot
  3740. // partition's signature formatted install path.
  3741. // If the input install path may not include the install
  3742. // directory name.
  3743. //
  3744. //
  3745. // Check if the GUID specified by the User matches with the set of GUID's
  3746. // already present
  3747. //
  3748. if ( NT_SUCCESS(status) && !(wcsncmp( (WCHAR*)&pTransEntry->FilePath, pwszTarget, 48 ) ) )
  3749. {
  3750. // Set the flag to true indicating that the
  3751. // specified GUID matches
  3752. //
  3753. bFlag = TRUE ;
  3754. //
  3755. // Check if the ARC Path specified by the User matches with the ARC Path
  3756. // of the entry already present and if so display an error message and exit.
  3757. //
  3758. if( !(StringCompare( (WCHAR*)&pTransEntry->FilePath, pwszTarget, TRUE, StringLengthW(pwszTarget,0) ) ) )
  3759. {
  3760. ShowMessage(stderr,GetResString(IDS_ALREADY_UPDATED));
  3761. SAFEMEMFREE(pTransEntry) ;
  3762. return STATUS_OBJECT_NAME_NOT_FOUND;
  3763. }
  3764. else
  3765. {
  3766. *ppTargetEntry = pEntry;
  3767. //concatenate the string "\WINDOWS" to the path formed.
  3768. StringCopy ( szFinalStr, NULL_STRING, SIZE_OF_ARRAY(szFinalStr));
  3769. StringConcat(szFinalStr,pwszTarget,SIZE_OF_ARRAY(szFinalStr));
  3770. StringConcat(szFinalStr,_T("\\WINDOWS"), SIZE_OF_ARRAY(szFinalStr));
  3771. //
  3772. //modify the Boot Entry with the Arc Signature path specified.
  3773. //
  3774. status = ModifyBootEntry(szFinalStr,*ppTargetEntry);
  3775. if ( !NT_SUCCESS(status) )
  3776. {
  3777. //If unsuccessful to update the Boot_Entry then increment the Failure
  3778. //count.
  3779. dwFailCount++ ;
  3780. }
  3781. else
  3782. {
  3783. //If successfully updated the Boot_Entry then increment the Success
  3784. //count.
  3785. dwSuccessCount++;
  3786. }
  3787. if ( !pEntryList->NextEntryOffset )
  3788. {
  3789. bNobreak = FALSE;
  3790. break;
  3791. }
  3792. else
  3793. {
  3794. pEntryList = (PBOOT_ENTRY_LIST)( ((PBYTE)pEntryList) + pEntryList->NextEntryOffset );
  3795. continue ;
  3796. }
  3797. }
  3798. }
  3799. else
  3800. {
  3801. if ( !pEntryList->NextEntryOffset )
  3802. {
  3803. bNobreak = FALSE;
  3804. break;
  3805. }
  3806. pEntryList = (PBOOT_ENTRY_LIST)( ((PBYTE)pEntryList) + pEntryList->NextEntryOffset );
  3807. }
  3808. }while(TRUE == bNobreak );
  3809. // Depending upon the number of entries successfully updated
  3810. // display appropriate messages.
  3811. if((0 != dwFailCount)&&(0 == dwSuccessCount))
  3812. {
  3813. ShowMessage(stdout,GetResString(IDS_MODIFY_FAIL));
  3814. }
  3815. if(( 0 != dwSuccessCount )&&(0 == dwFailCount))
  3816. {
  3817. ShowMessage(stdout,GetResString(IDS_GUID_MODIFIED));
  3818. }
  3819. else if( ( 0 != dwSuccessCount )&&(0 != dwFailCount))
  3820. {
  3821. ShowMessage(stdout,GetResString(IDS_PARTIAL_UPDATE));
  3822. }
  3823. //display an error message if the GUID specified does not match with the GUID's present.
  3824. if(FALSE == bFlag )
  3825. {
  3826. //ShowMessage(stderr,GetResString(IDS_FIND_FAIL));
  3827. SAFEMEMFREE(pTransEntry) ;
  3828. return STATUS_INVALID_PARAMETER;
  3829. }
  3830. SAFEMEMFREE(pTransEntry)
  3831. return status;
  3832. }
  3833. LPVOID
  3834. MEMALLOC( ULONG size )
  3835. /*++
  3836. Routine Description : Allocates the memory Block.
  3837. Arguments :
  3838. [ in ] block : Size of the block to be allocated.
  3839. Return Type : LPVOID
  3840. --*/
  3841. {
  3842. HANDLE hProcessHeap;
  3843. hProcessHeap = GetProcessHeap();
  3844. if (hProcessHeap == NULL ||
  3845. size > 0x7FFF8) {
  3846. return NULL;
  3847. }
  3848. else {
  3849. return HeapAlloc (hProcessHeap, HEAP_ZERO_MEMORY, size);
  3850. }
  3851. }
  3852. VOID MEMFREE ( LPVOID block ) {
  3853. /*++
  3854. Routine Description : Frees the memory Allocated.
  3855. Arguments :
  3856. [ in ] block : Block to be freed.
  3857. Return Type : VOID
  3858. --*/
  3859. HANDLE hProcessHeap;
  3860. hProcessHeap = GetProcessHeap();
  3861. if (hProcessHeap != NULL) {
  3862. HeapFree(hProcessHeap, 0, block);
  3863. }
  3864. }
  3865. NTSTATUS
  3866. ModifyBootEntry( IN WCHAR *pwszInstallPath,
  3867. IN PBOOT_ENTRY pSourceEntry
  3868. )
  3869. /*++
  3870. Routine description : This routine is used to modify a boot entry in the NVRAM.
  3871. Arguments:
  3872. pwszInstallPath - The new install path
  3873. pSourceEntry - Entry that we will modify
  3874. Return Value : NT status
  3875. --*/
  3876. {
  3877. LONG status = STATUS_SUCCESS;
  3878. PFILE_PATH pLoaderFile = NULL;
  3879. ULONG dwLoaderFileSize = 0L;
  3880. PFILE_PATH pInstallPath = NULL; // new install path
  3881. ULONG dwInstallPathSize = 0L; // new install path size
  3882. PWINDOWS_OS_OPTIONS pWinOpt = NULL;
  3883. ULONG dwWinOptSize = 0L;
  3884. PBOOT_ENTRY pSetEntry = 0L; // new, modified entry
  3885. ULONG dwSetEntrySize = 0L;
  3886. DWORD dwFriendlyNameSize = 0L;
  3887. DWORD dwAlign = 0L;
  3888. PWINDOWS_OS_OPTIONS pSourceWinOpt = NULL; // old, source entry options to be modified
  3889. PFILE_PATH pSourceInstallPath = NULL; // old, source entry install path to be modified
  3890. //
  3891. // Validate params.
  3892. //
  3893. if ( !pwszInstallPath
  3894. || !(StringLengthW(pwszInstallPath,0))
  3895. || !pSourceEntry )
  3896. {
  3897. return STATUS_INVALID_PARAMETER;
  3898. }
  3899. //
  3900. // Setup the BootFilePath member of the BOOT_ENTRY.
  3901. //
  3902. dwLoaderFileSize = ( (PFILE_PATH) (((PBYTE)pSourceEntry) + pSourceEntry->BootFilePathOffset) )->Length;
  3903. pLoaderFile = (PFILE_PATH)MEMALLOC(dwLoaderFileSize);
  3904. if ( NULL == pLoaderFile )
  3905. {
  3906. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3907. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3908. return STATUS_NO_MEMORY ;
  3909. }
  3910. RtlCopyMemory(pLoaderFile,((PBYTE)pSourceEntry) + pSourceEntry->BootFilePathOffset,
  3911. dwLoaderFileSize
  3912. );
  3913. //
  3914. // Setup the OsLoadPath member of the WINDOWS_OS_OPTIONS struct.
  3915. //
  3916. dwInstallPathSize = FIELD_OFFSET(FILE_PATH, FilePath) + ( (StringLengthW(pwszInstallPath,0)+1) * sizeof(WCHAR) );
  3917. pInstallPath = (PFILE_PATH)MEMALLOC(dwInstallPathSize);
  3918. if ( NULL == pInstallPath )
  3919. {
  3920. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3921. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3922. SAFEMEMFREE(pLoaderFile);
  3923. return STATUS_NO_MEMORY ;
  3924. }
  3925. pSourceWinOpt = (PWINDOWS_OS_OPTIONS) &pSourceEntry->OsOptions;
  3926. pSourceInstallPath = (PFILE_PATH)( ((PBYTE)pSourceWinOpt)+ pSourceWinOpt->OsLoadPathOffset );
  3927. pInstallPath->Version = pSourceInstallPath->Version;
  3928. pInstallPath->Length = dwInstallPathSize; // new install path size
  3929. pInstallPath->Type = FILE_PATH_TYPE_ARC_SIGNATURE;
  3930. RtlCopyMemory(pInstallPath->FilePath, // new path to the OS on the boot partition, "signature(partition_guid)\WINDOWS"
  3931. pwszInstallPath,
  3932. (StringLengthW(pwszInstallPath,0) + 1) * sizeof(WCHAR)
  3933. );
  3934. //
  3935. // Setup the OsOptions member of the BOOT_ENTRY
  3936. //
  3937. dwWinOptSize = FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)
  3938. + ( (StringLengthW(pSourceWinOpt->OsLoadOptions,0) + 1) * sizeof(WCHAR) ) // old OsLoadOptions
  3939. + dwInstallPathSize // new OsLoadPath
  3940. + sizeof(DWORD); // Need to align the FILE_PATH struct
  3941. pWinOpt = (PWINDOWS_OS_OPTIONS) MEMALLOC(dwWinOptSize);
  3942. if ( NULL == pWinOpt )
  3943. {
  3944. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3945. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3946. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3947. SAFEMEMFREE(pLoaderFile);
  3948. SAFEMEMFREE(pInstallPath);
  3949. return STATUS_NO_MEMORY ;
  3950. }
  3951. RtlCopyMemory( pWinOpt->Signature, pSourceWinOpt->Signature, sizeof(WINDOWS_OS_OPTIONS_SIGNATURE) );
  3952. pWinOpt->Version = pSourceWinOpt->Version;
  3953. pWinOpt->Length = dwWinOptSize;
  3954. pWinOpt->OsLoadPathOffset = FIELD_OFFSET(WINDOWS_OS_OPTIONS, OsLoadOptions)
  3955. + ((StringLengthW(pSourceWinOpt->OsLoadOptions,0) + 1) * sizeof(WCHAR));
  3956. //
  3957. // Need to align the OsLoadPathOffset on a 4 byte boundary.
  3958. //
  3959. dwAlign = ( pWinOpt->OsLoadPathOffset & (sizeof(DWORD) - 1) );
  3960. if ( dwAlign != 0 )
  3961. {
  3962. pWinOpt->OsLoadPathOffset += sizeof(DWORD) - dwAlign;
  3963. }
  3964. StringCopy(pWinOpt->OsLoadOptions, pSourceWinOpt->OsLoadOptions, (StringLengthW(pSourceWinOpt->OsLoadOptions,0)));
  3965. RtlCopyMemory( ((PBYTE)pWinOpt) + pWinOpt->OsLoadPathOffset, pInstallPath, dwInstallPathSize );
  3966. //
  3967. // Setup the BOOT_ENTRY struct.
  3968. //
  3969. dwFriendlyNameSize = ( StringLengthW( (WCHAR *)(((PBYTE)pSourceEntry) + pSourceEntry->FriendlyNameOffset), 0 ) + 1)*sizeof(WCHAR);
  3970. dwSetEntrySize = FIELD_OFFSET(BOOT_ENTRY, OsOptions)
  3971. + dwWinOptSize // OsOptions
  3972. + dwFriendlyNameSize // FriendlyName including the NULL terminator
  3973. + dwLoaderFileSize // BootFilePath
  3974. + sizeof(WCHAR) // Need to align the FriendlyName on WCHAR
  3975. + sizeof(DWORD); // Need to align the BootFilePath on DWORD
  3976. pSetEntry = (PBOOT_ENTRY) MEMALLOC(dwSetEntrySize);
  3977. if ( NULL == pSetEntry )
  3978. {
  3979. SAFEMEMFREE(pLoaderFile);
  3980. SAFEMEMFREE(pInstallPath);
  3981. SAFEMEMFREE(pWinOpt);
  3982. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3983. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  3984. return STATUS_NO_MEMORY;
  3985. }
  3986. pSetEntry->Version = pSourceEntry->Version;
  3987. pSetEntry->Length = dwSetEntrySize;
  3988. pSetEntry->Id = pSourceEntry->Id; // not used, output param
  3989. pSetEntry->Attributes = pSourceEntry->Attributes;
  3990. pSetEntry->FriendlyNameOffset = FIELD_OFFSET(BOOT_ENTRY, OsOptions)
  3991. + dwWinOptSize;
  3992. //
  3993. // Need to align the unicode string on a 2 byte boundary.
  3994. //
  3995. dwAlign = ( pSetEntry->FriendlyNameOffset & (sizeof(WCHAR) - 1) );
  3996. if ( dwAlign != 0 )
  3997. {
  3998. pSetEntry->FriendlyNameOffset += sizeof(WCHAR) - dwAlign;
  3999. }
  4000. pSetEntry->BootFilePathOffset = pSetEntry->FriendlyNameOffset + dwFriendlyNameSize;
  4001. //
  4002. // Need to align the FILE_PATH struct on a 4 byte boundary.
  4003. //
  4004. dwAlign = ( pSetEntry->BootFilePathOffset & (sizeof(DWORD) - 1) );
  4005. if ( dwAlign != 0 )
  4006. {
  4007. pSetEntry->BootFilePathOffset += sizeof(DWORD) - dwAlign;
  4008. }
  4009. pSetEntry->OsOptionsLength = dwWinOptSize;
  4010. RtlCopyMemory( pSetEntry->OsOptions, pWinOpt, dwWinOptSize );
  4011. RtlCopyMemory( ((PBYTE)pSetEntry) + pSetEntry->FriendlyNameOffset,
  4012. ((PBYTE)pSourceEntry) + pSourceEntry->FriendlyNameOffset,
  4013. dwFriendlyNameSize
  4014. );
  4015. RtlCopyMemory( ((PBYTE)pSetEntry) + pSetEntry->BootFilePathOffset,
  4016. pLoaderFile,
  4017. dwLoaderFileSize
  4018. );
  4019. status = NtModifyBootEntry( pSetEntry );
  4020. if(!NT_SUCCESS(status))
  4021. {
  4022. ShowMessage(stderr,GetResString(IDS_MODIFY_FAIL));
  4023. }
  4024. SAFEMEMFREE(pLoaderFile);
  4025. SAFEMEMFREE(pInstallPath);
  4026. SAFEMEMFREE(pWinOpt);
  4027. SAFEMEMFREE(pSetEntry);
  4028. return status;
  4029. }
  4030. DWORD
  4031. ListDeviceInfo(DWORD dwDriveNum)
  4032. /*++
  4033. Routine description : This routine is used to retrieve the list of device partitions.
  4034. Arguments:
  4035. szGUID : The address of a pointer to a BOOT_ENTRY_LIST struct.
  4036. szFinalStr : The String containing the final ARG signature path.
  4037. Return Value : DWORD
  4038. EXIT_SUCCESS if it is successful,
  4039. EXIT_FAILURE otherwise.
  4040. --*/
  4041. {
  4042. HRESULT hr = S_OK;
  4043. HANDLE hDevice ;
  4044. BOOL bResult = FALSE ;
  4045. PPARTITION_INFORMATION_EX pInfo=NULL ;
  4046. PDRIVE_LAYOUT_INFORMATION_EX Drive=NULL;
  4047. DWORD dwBytesCount = 0 ;
  4048. TCHAR szDriveName[MAX_RES_STRING+1] = NULL_STRING ;
  4049. DWORD dwStructSize = 0 ;
  4050. TCHAR szInstallPath[MAX_RES_STRING+1] = NULL_STRING;
  4051. TCHAR szWindowsDirectory[MAX_PATH*2] = NULL_STRING;
  4052. PTCHAR pszTok = NULL ;
  4053. PPARTITION_INFORMATION_GPT pGptPartition=NULL;
  4054. DWORD dwPartitionId = 0 ;
  4055. CHAR szTempBuffer[ 33 ] = "\0";
  4056. WCHAR wszOffsetStr[ 33 ] = L"\0";
  4057. CHAR szTempBuffer1[ 33 ] = "\0";
  4058. WCHAR wszPartitionStr[ 33 ] = L"\0";
  4059. WCHAR szOutputStr[MAX_RES_STRING+1] = NULL_STRING ;
  4060. NTSTATUS ntstatus;
  4061. SecureZeroMemory(szDriveName, SIZE_OF_ARRAY(szDriveName));
  4062. hr = StringCchPrintf(szDriveName, SIZE_OF_ARRAY(szDriveName), _T("\\\\.\\physicaldrive%d"),dwDriveNum);
  4063. //get a handle after opening the File.
  4064. hDevice = CreateFile(szDriveName,
  4065. GENERIC_READ|GENERIC_WRITE,
  4066. FILE_SHARE_READ|FILE_SHARE_WRITE,
  4067. NULL,
  4068. OPEN_EXISTING,
  4069. 0,
  4070. NULL);
  4071. if(hDevice == INVALID_HANDLE_VALUE)
  4072. {
  4073. ShowMessage(stderr,GetResString(IDS_INVALID_DISK));
  4074. return EXIT_FAILURE ;
  4075. }
  4076. Drive = (PDRIVE_LAYOUT_INFORMATION_EX)AllocateMemory(sizeof(DRIVE_LAYOUT_INFORMATION_EX) +5000) ;
  4077. if(NULL == Drive)
  4078. {
  4079. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  4080. CloseHandle(hDevice);
  4081. return EXIT_FAILURE ;
  4082. }
  4083. dwStructSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) ;
  4084. bResult = DeviceIoControl(
  4085. hDevice,
  4086. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
  4087. NULL,
  4088. 0,
  4089. Drive,
  4090. sizeof(DRIVE_LAYOUT_INFORMATION_EX)+5000,
  4091. &dwBytesCount,
  4092. NULL);
  4093. if(bResult ==0)
  4094. {
  4095. SAFEFREE(Drive);
  4096. DISPLAY_MESSAGE( stderr, ERROR_TAG);
  4097. ShowLastError(stderr);
  4098. CloseHandle(hDevice);
  4099. return EXIT_FAILURE ;
  4100. }
  4101. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_LIST0),dwDriveNum);
  4102. ShowMessage(stdout,GetResString(IDS_LIST1));
  4103. for(dwPartitionId = 0 ;dwPartitionId < Drive->PartitionCount ; dwPartitionId++)
  4104. {
  4105. //get a pointer to the corresponding partition.
  4106. pInfo = (PPARTITION_INFORMATION_EX)(&Drive->PartitionEntry[dwPartitionId] ) ;
  4107. ShowMessageEx(stdout,1, TRUE, GetResString(IDS_LIST2),dwPartitionId+1);
  4108. switch(Drive->PartitionStyle )
  4109. {
  4110. case PARTITION_STYLE_MBR :
  4111. ShowMessage(stdout,GetResString(IDS_LIST3));
  4112. break;
  4113. case PARTITION_STYLE_GPT :
  4114. ShowMessage(stdout,GetResString(IDS_LIST4));
  4115. break;
  4116. case PARTITION_STYLE_RAW :
  4117. ShowMessage(stdout,GetResString(IDS_LIST5));
  4118. break;
  4119. }
  4120. ntstatus = RtlLargeIntegerToChar( &pInfo->StartingOffset, 10, SIZE_OF_ARRAY( szTempBuffer ), szTempBuffer );
  4121. if ( ! NT_SUCCESS( ntstatus ) )
  4122. {
  4123. SAFEFREE(Drive);
  4124. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4125. CloseHandle(hDevice);
  4126. return EXIT_FAILURE ;
  4127. }
  4128. ntstatus = RtlLargeIntegerToChar( &pInfo->PartitionLength, 10, SIZE_OF_ARRAY( szTempBuffer1 ), szTempBuffer1 );
  4129. if ( ! NT_SUCCESS( ntstatus ) )
  4130. {
  4131. SAFEFREE(Drive);
  4132. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4133. CloseHandle(hDevice);
  4134. return EXIT_FAILURE ;
  4135. }
  4136. MultiByteToWideChar( _DEFAULT_CODEPAGE, 0, szTempBuffer, -1, wszOffsetStr, SIZE_OF_ARRAY(wszOffsetStr) );
  4137. if( ConvertintoLocale( wszOffsetStr,szOutputStr )== EXIT_FAILURE )
  4138. {
  4139. SAFEFREE(Drive);
  4140. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4141. CloseHandle(hDevice);
  4142. return EXIT_FAILURE ;
  4143. }
  4144. ShowMessage(stdout,GetResString(IDS_LIST6));
  4145. ShowMessage(stdout,_X3(szOutputStr));
  4146. ShowMessage(stdout,L"\n");
  4147. MultiByteToWideChar( _DEFAULT_CODEPAGE, 0, szTempBuffer1, -1, wszPartitionStr, SIZE_OF_ARRAY(wszOffsetStr) );
  4148. if( ConvertintoLocale( wszPartitionStr,szOutputStr )== EXIT_FAILURE )
  4149. {
  4150. SAFEFREE(Drive);
  4151. DISPLAY_MESSAGE( stderr, ERROR_TAG);
  4152. ShowLastError(stderr);
  4153. CloseHandle(hDevice);
  4154. return EXIT_FAILURE ;
  4155. }
  4156. ShowMessage(stdout,GetResString(IDS_LIST7));
  4157. ShowMessage(stdout,_X3(szOutputStr));
  4158. ShowMessage(stdout,L"\n");
  4159. //get a pointer to the PARTITION_INFORMATION_GPT structure.
  4160. pGptPartition = AllocateMemory( sizeof( PARTITION_INFORMATION_GPT));
  4161. if(NULL == pGptPartition )
  4162. {
  4163. SAFEFREE(Drive);
  4164. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  4165. CloseHandle(hDevice);
  4166. return EXIT_FAILURE ;
  4167. }
  4168. CopyMemory(pGptPartition,&pInfo->Gpt,sizeof(PARTITION_INFORMATION_GPT) );
  4169. ShowMessage(stdout, GetResString(IDS_LIST8));
  4170. ShowMessageEx(stdout, 11, TRUE, _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
  4171. pGptPartition->PartitionId.Data1,
  4172. pGptPartition->PartitionId.Data2,
  4173. pGptPartition->PartitionId.Data3,
  4174. pGptPartition->PartitionId.Data4[0],
  4175. pGptPartition->PartitionId.Data4[1],
  4176. pGptPartition->PartitionId.Data4[2],
  4177. pGptPartition->PartitionId.Data4[3],
  4178. pGptPartition->PartitionId.Data4[4],
  4179. pGptPartition->PartitionId.Data4[5],
  4180. pGptPartition->PartitionId.Data4[6],
  4181. pGptPartition->PartitionId.Data4[7] );
  4182. ShowMessage(stdout, GetResString(IDS_LIST9));
  4183. ShowMessageEx(stdout, 11, TRUE,
  4184. _T("{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}"),
  4185. pGptPartition->PartitionType.Data1,
  4186. pGptPartition->PartitionType.Data2,
  4187. pGptPartition->PartitionType.Data3,
  4188. pGptPartition->PartitionType.Data4[0],
  4189. pGptPartition->PartitionType.Data4[1],
  4190. pGptPartition->PartitionType.Data4[2],
  4191. pGptPartition->PartitionType.Data4[3],
  4192. pGptPartition->PartitionType.Data4[4],
  4193. pGptPartition->PartitionType.Data4[5],
  4194. pGptPartition->PartitionType.Data4[6],
  4195. pGptPartition->PartitionType.Data4[7] );
  4196. //partition name.
  4197. if(StringLengthW(pGptPartition->Name,0) != 0)
  4198. {
  4199. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_LIST10),pGptPartition->Name);
  4200. }
  4201. else
  4202. {
  4203. ShowMessageEx(stdout, 1, TRUE, GetResString(IDS_LIST10),_T("N/A"));
  4204. }
  4205. }
  4206. if( 0 == GetWindowsDirectory(szWindowsDirectory,MAX_PATH) )
  4207. {
  4208. SAFEFREE(Drive);
  4209. SAFEFREE(pGptPartition);
  4210. ShowMessage(stderr,GetResString(IDS_ERROR_DRIVE));
  4211. CloseHandle(hDevice);
  4212. return EXIT_FAILURE ;
  4213. }
  4214. StringConcat(szWindowsDirectory,_T("*"), SIZE_OF_ARRAY(szWindowsDirectory));
  4215. pszTok = _tcstok(szWindowsDirectory,_T("\\"));
  4216. if(pszTok == NULL)
  4217. {
  4218. SAFEFREE(Drive);
  4219. SAFEFREE(pGptPartition);
  4220. DISPLAY_MESSAGE(stderr,GetResString(IDS_TOKEN_ABSENT));
  4221. CloseHandle(hDevice);
  4222. return EXIT_FAILURE ;
  4223. }
  4224. pszTok = _tcstok(NULL,_T("*"));
  4225. if(pszTok == NULL)
  4226. {
  4227. SAFEFREE(Drive);
  4228. SAFEFREE(pGptPartition);
  4229. DISPLAY_MESSAGE(stderr,GetResString(IDS_TOKEN_ABSENT));
  4230. CloseHandle(hDevice);
  4231. return EXIT_FAILURE ;
  4232. }
  4233. SecureZeroMemory(szInstallPath, SIZE_OF_ARRAY(szInstallPath));
  4234. hr = StringCchPrintf( szInstallPath, SIZE_OF_ARRAY(szInstallPath),
  4235. _T("signature({%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}-%08x-%016I64x-%016I64x)"),
  4236. pGptPartition->PartitionId.Data1,
  4237. pGptPartition->PartitionId.Data2,
  4238. pGptPartition->PartitionId.Data3,
  4239. pGptPartition->PartitionId.Data4[0],
  4240. pGptPartition->PartitionId.Data4[1],
  4241. pGptPartition->PartitionId.Data4[2],
  4242. pGptPartition->PartitionId.Data4[3],
  4243. pGptPartition->PartitionId.Data4[4],
  4244. pGptPartition->PartitionId.Data4[5],
  4245. pGptPartition->PartitionId.Data4[6],
  4246. pGptPartition->PartitionId.Data4[7],
  4247. pInfo->PartitionNumber,
  4248. pInfo->StartingOffset,
  4249. pInfo->PartitionLength
  4250. );
  4251. SAFEFREE(Drive);
  4252. SAFEFREE(pGptPartition);
  4253. CloseHandle(hDevice);
  4254. return EXIT_SUCCESS ;
  4255. }
  4256. NTSTATUS
  4257. AcquirePrivilege( IN CONST ULONG ulPrivilege,
  4258. IN CONST BOOLEAN bEnable
  4259. )
  4260. /*++
  4261. Routine description : This routine is used to set or reset a privilege
  4262. on a process token.
  4263. Arguments:
  4264. ulPrivilege - The privilege t enable or disable.
  4265. bEnable - TRUE to enable the priviliege, FALSE to disable.
  4266. Return Value : NTSTATUS
  4267. --*/
  4268. {
  4269. NTSTATUS status;
  4270. BOOLEAN bPrevState;
  4271. if ( bEnable ) {
  4272. status = RtlAdjustPrivilege( ulPrivilege,
  4273. TRUE, // enable
  4274. FALSE, // adjust the process token
  4275. &bPrevState
  4276. );
  4277. }
  4278. else {
  4279. status = RtlAdjustPrivilege( ulPrivilege,
  4280. FALSE, // disable
  4281. FALSE, // adjust the process token
  4282. &bPrevState
  4283. );
  4284. }
  4285. return status;
  4286. }
  4287. NTSTATUS
  4288. EnumerateBootEntries( IN PVOID *ppEntryListHead)
  4289. /*++
  4290. Routine description : This routine is used to retrieve the list of boot entries.
  4291. Arguments:
  4292. ppEntryListHead - The address of a pointer to a BOOT_ENTRY_LIST struct.
  4293. Return Value : NTSTATUS
  4294. --*/
  4295. {
  4296. LONG status = STATUS_SUCCESS;
  4297. DWORD dwEntryListSize = 0x0001000; // 4k
  4298. BOOL bNobreak = TRUE;
  4299. if ( !ppEntryListHead )
  4300. {
  4301. ShowMessage(stderr,GetResString(IDS_ERROR_ENUMERATE));
  4302. return STATUS_INVALID_PARAMETER;
  4303. }
  4304. do
  4305. {
  4306. *ppEntryListHead = (PBOOT_ENTRY_LIST) MEMALLOC(dwEntryListSize);
  4307. if ( !*ppEntryListHead )
  4308. {
  4309. ShowMessage(stderr,GetResString(IDS_ERROR_ENUMERATE));
  4310. status = STATUS_NO_MEMORY;
  4311. bNobreak = FALSE;
  4312. break;
  4313. }
  4314. status = NtEnumerateBootEntries(
  4315. (PVOID) *ppEntryListHead,
  4316. &dwEntryListSize
  4317. );
  4318. if ( !NT_SUCCESS(status) )
  4319. {
  4320. if ( *ppEntryListHead ) {
  4321. MEMFREE(*ppEntryListHead);
  4322. *ppEntryListHead = NULL;
  4323. }
  4324. if ( STATUS_INSUFFICIENT_RESOURCES == status ) {
  4325. dwEntryListSize += 0x0001000;
  4326. continue;
  4327. }
  4328. else
  4329. {
  4330. ShowMessage(stderr,GetResString(IDS_ERROR_ENUMERATE));
  4331. bNobreak = FALSE;
  4332. break;
  4333. }
  4334. }
  4335. else {
  4336. break;
  4337. }
  4338. }while (TRUE==bNobreak);
  4339. return status;
  4340. }
  4341. DWORD
  4342. GetDeviceInfo( IN LPTSTR szGUID,
  4343. OUT LPTSTR szFinalStr,
  4344. IN DWORD dwDriveNum,
  4345. IN DWORD dwActuals)
  4346. /*++
  4347. Routine description : This routine is used to retrieve the list of boot entries.
  4348. Arguments:
  4349. [ in ] szGUID : The address of a pointer to a BOOT_ENTRY_LIST struct.
  4350. [ out ] szFinalStr : The String containing the final ARG signature path.
  4351. [ in ] dwDriveNum : Specifies the drive number
  4352. [ in ] dwActuals : Specifies
  4353. Return Value : DWORD
  4354. Returns EXIT_SUCCESS if it is successful,
  4355. returnS EXIT_FAILURE otherwise.
  4356. --*/
  4357. {
  4358. HRESULT hr = S_OK;
  4359. HANDLE hDevice ;
  4360. BOOL bResult = FALSE ;
  4361. PPARTITION_INFORMATION_EX pInfo ;
  4362. PDRIVE_LAYOUT_INFORMATION_EX Drive ;
  4363. DWORD dwBytesCount = 0 ;
  4364. TCHAR szDriveName[MAX_RES_STRING+1] = NULL_STRING ;
  4365. DWORD dwErrCode = 0 ;
  4366. DWORD dwStructSize = 0 ;
  4367. TCHAR szInstallPath[MAX_RES_STRING+1] = NULL_STRING;
  4368. TCHAR szInstallPath1[MAX_RES_STRING*2] = NULL_STRING;
  4369. TCHAR szWindowsDirectory[MAX_PATH*2] = NULL_STRING;
  4370. TCHAR szMessage[MAX_RES_STRING+1] = NULL_STRING;
  4371. PTCHAR pszTok = NULL ;
  4372. PPARTITION_INFORMATION_GPT pGptPartition ;
  4373. UUID MyGuid ;
  4374. DWORD dwPartitionId = 0 ;
  4375. BOOL bGuidFlag = FALSE ;
  4376. BOOL bFoundFlag = TRUE ;
  4377. DWORD dwReqdSize = 0 ;
  4378. if ( UuidFromString(szGUID,&MyGuid) != RPC_S_OK )
  4379. {
  4380. ShowMessage(stderr,GetResString(IDS_INVALID_GUID));
  4381. return EXIT_FAILURE ;
  4382. }
  4383. while(bFoundFlag == TRUE)
  4384. {
  4385. SecureZeroMemory(szDriveName, SIZE_OF_ARRAY(szDriveName));
  4386. hr = StringCchPrintf(szDriveName, SIZE_OF_ARRAY(szDriveName), _T("\\\\.\\physicaldrive%d"), dwDriveNum );
  4387. hDevice = CreateFile(szDriveName,
  4388. GENERIC_READ|GENERIC_WRITE,
  4389. FILE_SHARE_READ|FILE_SHARE_WRITE,
  4390. NULL,
  4391. OPEN_EXISTING,
  4392. 0,
  4393. NULL);
  4394. if(hDevice == INVALID_HANDLE_VALUE)
  4395. {
  4396. dwErrCode = GetLastError();
  4397. bFoundFlag =FALSE ;
  4398. // Display ann error message and exit if the user has mentioned
  4399. // any disk number.
  4400. if ( dwActuals == 1)
  4401. {
  4402. ShowMessage(stderr,GetResString(IDS_INVALID_DISK) );
  4403. return EXIT_FAILURE ;
  4404. }
  4405. else
  4406. {
  4407. break ;
  4408. }
  4409. }
  4410. //increase the drive number.
  4411. dwDriveNum++ ;
  4412. //Drive = (PDRIVE_LAYOUT_INFORMATION_EX)malloc(sizeof(DRIVE_LAYOUT_INFORMATION_EX) +5000) ;
  4413. dwReqdSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX)+ sizeof(PARTITION_INFORMATION)*50 ;
  4414. Drive = (PDRIVE_LAYOUT_INFORMATION_EX)AllocateMemory(sizeof(DRIVE_LAYOUT_INFORMATION_EX) + sizeof(PARTITION_INFORMATION)*50) ;
  4415. if(Drive == NULL)
  4416. {
  4417. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4418. CloseHandle(hDevice );
  4419. return EXIT_FAILURE ;
  4420. }
  4421. dwStructSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) ;
  4422. bResult = DeviceIoControl(
  4423. hDevice,
  4424. IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
  4425. NULL,
  4426. 0,
  4427. Drive,
  4428. dwReqdSize,
  4429. &dwBytesCount,
  4430. NULL);
  4431. //Drive = realloc(Drive,malloc(sizeof(DRIVE_LAYOUT_INFORMATION_EX) )+500 ) ;
  4432. if(bResult ==0)
  4433. {
  4434. SAFEFREE(Drive);
  4435. dwErrCode = GetLastError();
  4436. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4437. CloseHandle(hDevice );
  4438. return EXIT_FAILURE ;
  4439. }
  4440. //get a pointer to the PARTITION_INFORMATION_EX structure
  4441. for(dwPartitionId = 0 ;dwPartitionId < Drive->PartitionCount ; dwPartitionId++)
  4442. {
  4443. //get a pointer to the corresponding partition.
  4444. pInfo = (PPARTITION_INFORMATION_EX)(&Drive->PartitionEntry[dwPartitionId] ) ;
  4445. //get a pointer to the PARTITION_INFORMATION_GPT structure.
  4446. pGptPartition = AllocateMemory( sizeof( PARTITION_INFORMATION_GPT));
  4447. if(pGptPartition == NULL)
  4448. {
  4449. SAFEFREE(Drive);
  4450. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
  4451. CloseHandle(hDevice );
  4452. return EXIT_FAILURE ;
  4453. }
  4454. CopyMemory(pGptPartition,&pInfo->Gpt,sizeof(PARTITION_INFORMATION_GPT) );
  4455. if( ( MyGuid.Data1 == pGptPartition->PartitionId.Data1 ) &&
  4456. ( MyGuid.Data2 == pGptPartition->PartitionId.Data2 )
  4457. && (MyGuid.Data3 == pGptPartition->PartitionId.Data3)
  4458. && (MyGuid.Data4[0] == pGptPartition->PartitionId.Data4[0])
  4459. && (MyGuid.Data4[1] == pGptPartition->PartitionId.Data4[1])
  4460. && (MyGuid.Data4[2] == pGptPartition->PartitionId.Data4[2])
  4461. &&(MyGuid.Data4[3] == pGptPartition->PartitionId.Data4[3])
  4462. && (MyGuid.Data4[4]== pGptPartition->PartitionId.Data4[4] )
  4463. && (MyGuid.Data4[5]== pGptPartition->PartitionId.Data4[5] )
  4464. && (MyGuid.Data4[6]== pGptPartition->PartitionId.Data4[6] )
  4465. && (MyGuid.Data4[7]== pGptPartition->PartitionId.Data4[7] ) )
  4466. {
  4467. SecureZeroMemory(szMessage, SIZE_OF_ARRAY(szMessage));
  4468. hr = StringCchPrintf(szMessage, SIZE_OF_ARRAY(szMessage),GetResString(IDS_GUID_FOUND),dwPartitionId+1);
  4469. bGuidFlag = TRUE ;
  4470. bFoundFlag =FALSE ;
  4471. goto out ;
  4472. }
  4473. }
  4474. CloseHandle(hDevice );
  4475. }
  4476. if(bGuidFlag == FALSE )
  4477. {
  4478. SAFEFREE(Drive);
  4479. SAFEFREE(pGptPartition);
  4480. ShowMessage(stdout,GetResString(IDS_GUID_ABSENT));
  4481. CloseHandle(hDevice );
  4482. return EXIT_FAILURE ;
  4483. }
  4484. out: if( 0 == GetWindowsDirectory(szWindowsDirectory,MAX_PATH) )
  4485. {
  4486. SAFEFREE(Drive);
  4487. SAFEFREE(pGptPartition);
  4488. ShowMessage(stderr,GetResString(IDS_ERROR_DRIVE));
  4489. CloseHandle(hDevice );
  4490. return EXIT_FAILURE ;
  4491. }
  4492. StringConcat(szWindowsDirectory,_T("*"), SIZE_OF_ARRAY(szWindowsDirectory));
  4493. pszTok = _tcstok(szWindowsDirectory,_T("\\"));
  4494. if(pszTok == NULL)
  4495. { SAFEFREE(Drive);
  4496. SAFEFREE(pGptPartition);
  4497. ShowMessage(stderr,GetResString(IDS_TOKEN_ABSENT));
  4498. CloseHandle(hDevice );
  4499. return EXIT_FAILURE ;
  4500. }
  4501. pszTok = _tcstok(NULL,_T("*"));
  4502. if(pszTok == NULL)
  4503. {
  4504. SAFEFREE(Drive);
  4505. SAFEFREE(pGptPartition);
  4506. ShowMessage(stderr,GetResString(IDS_TOKEN_ABSENT));
  4507. CloseHandle(hDevice );
  4508. return EXIT_FAILURE ;
  4509. }
  4510. //prints the path into the string.
  4511. hr = StringCchPrintf( szInstallPath, SIZE_OF_ARRAY(szInstallPath),
  4512. ARC_SIGNATURE,
  4513. pGptPartition->PartitionId.Data1,
  4514. pGptPartition->PartitionId.Data2,
  4515. pGptPartition->PartitionId.Data3,
  4516. pGptPartition->PartitionId.Data4[0],
  4517. pGptPartition->PartitionId.Data4[1],
  4518. pGptPartition->PartitionId.Data4[2],
  4519. pGptPartition->PartitionId.Data4[3],
  4520. pGptPartition->PartitionId.Data4[4],
  4521. pGptPartition->PartitionId.Data4[5],
  4522. pGptPartition->PartitionId.Data4[6],
  4523. pGptPartition->PartitionId.Data4[7],
  4524. dwPartitionId + 1 ,
  4525. pInfo->StartingOffset,
  4526. pInfo->PartitionLength
  4527. );
  4528. SecureZeroMemory(szInstallPath1, SIZE_OF_ARRAY(szInstallPath1) );
  4529. hr = StringCchPrintf( szInstallPath1, SIZE_OF_ARRAY(szInstallPath1), _T("%s\\%s"), szInstallPath, pszTok);
  4530. StringCopy(szFinalStr,szInstallPath, MAX_RES_STRING+1 );
  4531. SAFEFREE(Drive);
  4532. SAFEFREE(pGptPartition);
  4533. CloseHandle(hDevice );
  4534. return EXIT_SUCCESS ;
  4535. }
  4536. DWORD
  4537. ProcessListSwitch_IA64( IN DWORD argc,
  4538. IN LPCTSTR argv[]
  4539. )
  4540. /*++
  4541. Routine description : This routine is used to retrieve and display the list of boot entries.
  4542. Arguments:
  4543. argc : command line arguments count.
  4544. argv :
  4545. Return Value : DWORD
  4546. Returns EXIT_SUCCESS if it is successful,
  4547. returns EXIT_FAILURE otherwise.
  4548. --*/
  4549. {
  4550. BOOL bUsage = FALSE ;
  4551. BOOL bList = FALSE;
  4552. DWORD dwExitCode = ERROR_SUCCESS;
  4553. DWORD dwList = 0 ;
  4554. TCHAR szList[MAX_STRING_LENGTH] = NULL_STRING ;
  4555. LPTSTR pszStopStr = NULL;
  4556. DWORD dwExitcode = 0 ;
  4557. TCMDPARSER2 cmdOptions[3];
  4558. PTCMDPARSER2 pcmdOption;
  4559. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  4560. //main option
  4561. pcmdOption = &cmdOptions[0];
  4562. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  4563. pcmdOption->pwszOptions = CMDOPTION_LIST;
  4564. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  4565. pcmdOption->pValue = &bList;
  4566. //main option
  4567. pcmdOption = &cmdOptions[1];
  4568. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  4569. pcmdOption->pwszOptions = CMDOPTION_DEFAULT;
  4570. pcmdOption->dwType = CP_TYPE_TEXT;
  4571. pcmdOption->dwFlags = CP2_DEFAULT;
  4572. pcmdOption->dwCount = 1;
  4573. pcmdOption->pValue = szList;
  4574. pcmdOption->dwLength = MAX_STRING_LENGTH;
  4575. //id usage
  4576. pcmdOption = &cmdOptions[2];
  4577. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  4578. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  4579. pcmdOption->dwFlags = CP2_USAGE;
  4580. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  4581. pcmdOption->dwCount = 1;
  4582. pcmdOption->pValue = &bUsage;
  4583. // Parsing the copy option switches
  4584. if ( !(DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) ) )
  4585. {
  4586. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  4587. return (EXIT_FAILURE);
  4588. }
  4589. //check if usage is specified with more than one option
  4590. if( (TRUE == bUsage) && (argc > 3) )
  4591. {
  4592. ShowMessage(stderr,GetResString(IDS_LIST_SYNTAX));
  4593. return ( EXIT_FAILURE );
  4594. }
  4595. // Displaying query usage if user specified -? with -query option
  4596. if( bUsage )
  4597. {
  4598. displayListUsage_IA64() ;
  4599. return (EXIT_SUCCESS);
  4600. }
  4601. TrimString(szList,TRIM_ALL);
  4602. dwExitcode = InitializeEFI();
  4603. if(EXIT_FAILURE == dwExitcode )
  4604. {
  4605. return EXIT_FAILURE ;
  4606. }
  4607. //if empty value is specified
  4608. if( cmdOptions[1].dwActuals != 0 && StringLength(szList,0) == 0 )
  4609. {
  4610. ShowMessage(stderr,GetResString(IDS_LIST_SYNTAX));
  4611. return ( EXIT_FAILURE );
  4612. }
  4613. dwList = _tcstoul(szList,&pszStopStr, 10);
  4614. if ( StringLengthW(pszStopStr,0) != 0 )
  4615. {
  4616. ShowMessage(stderr,GetResString(IDS_INVALID_LISTVALUE));
  4617. return EXIT_FAILURE;
  4618. }
  4619. if(dwList > 0)
  4620. {
  4621. dwExitCode= ListDeviceInfo(dwList );
  4622. return (dwExitCode);
  4623. }
  4624. else
  4625. {
  4626. dwList = 0 ;
  4627. dwExitCode = ListDeviceInfo(dwList);
  4628. return (dwExitCode);
  4629. }
  4630. return EXIT_SUCCESS ;
  4631. }
  4632. VOID
  4633. displayListUsage_IA64()
  4634. /*++
  4635. Routine Description : Display the help for the list option (IA64).
  4636. Arguments :
  4637. : NONE
  4638. Return Type : VOID
  4639. --*/
  4640. {
  4641. DWORD dwIndex = IDS_LIST_BEGIN_IA64 ;
  4642. for(;dwIndex <=IDS_LIST_END_IA64 ;dwIndex++)
  4643. {
  4644. ShowMessage(stdout,GetResString(dwIndex));
  4645. }
  4646. }
  4647. VOID
  4648. displayUpdateUsage_IA64()
  4649. /*++
  4650. Routine Description : Display the help for the update option (IA64).
  4651. Arguments :
  4652. : NONE
  4653. Return Type : VOID
  4654. --*/
  4655. {
  4656. DWORD dwIndex = IDS_UPDATE_BEGIN_IA64 ;
  4657. for(;dwIndex <=IDS_UPDATE_END_IA64 ;dwIndex++)
  4658. {
  4659. ShowMessage(stdout,GetResString(dwIndex));
  4660. }
  4661. }
  4662. DWORD
  4663. ProcessUpdateSwitch_IA64( IN DWORD argc,
  4664. IN LPCTSTR argv[]
  4665. )
  4666. /*++
  4667. Routine Description : Allows the user to update the OS load options specifed
  4668. based on the plex
  4669. Arguments :
  4670. [ in ] argc - Number of command line arguments
  4671. [ in ] argv - Array containing command line arguments
  4672. Return Type : DWORD
  4673. --*/
  4674. {
  4675. BOOL bUsage = FALSE ;
  4676. TCHAR szUpdate[MAX_RES_STRING+1] = NULL_STRING ;
  4677. DWORD dwList = 0 ;
  4678. NTSTATUS status ;
  4679. TCHAR szFinalStr[MAX_RES_STRING+1] = NULL_STRING ;
  4680. TCHAR szBrackets[] = _T("{}");
  4681. PBOOT_ENTRY_LIST pEntryListHead = NULL;
  4682. PBOOT_ENTRY pTargetEntry = NULL;
  4683. DWORD dwActuals = 0 ;
  4684. DWORD dwExitcode = 0 ;
  4685. TCMDPARSER2 cmdOptions[2];
  4686. PTCMDPARSER2 pcmdOption;
  4687. SecureZeroMemory(cmdOptions, SIZE_OF_ARRAY(cmdOptions)*sizeof(TCMDPARSER2) );
  4688. //main option
  4689. pcmdOption = &cmdOptions[0];
  4690. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  4691. pcmdOption->pwszOptions = CMDOPTION_UPDATE;
  4692. pcmdOption->dwType = CP_TYPE_TEXT;
  4693. pcmdOption->dwFlags= CP2_VALUE_OPTIONAL;
  4694. pcmdOption->dwCount = 1;
  4695. pcmdOption->pValue = szUpdate;
  4696. pcmdOption->dwLength = MAX_STRING_LENGTH;
  4697. //id usage
  4698. pcmdOption = &cmdOptions[1];
  4699. StringCopyA( pcmdOption->szSignature, "PARSER2", 8 );
  4700. pcmdOption->pwszOptions = CMDOPTION_USAGE;
  4701. pcmdOption->dwFlags = CP2_USAGE;
  4702. pcmdOption->dwType = CP_TYPE_BOOLEAN;
  4703. pcmdOption->dwCount = 1;
  4704. pcmdOption->pValue = &bUsage;
  4705. // Parsing the copy option switches
  4706. if ( !(DoParseParam2( argc, argv, 0, SIZE_OF_ARRAY(cmdOptions ), cmdOptions, 0 ) ) )
  4707. {
  4708. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  4709. return (EXIT_FAILURE);
  4710. }
  4711. //check if usage is specified with more than one option
  4712. if( (TRUE == bUsage) && (argc > 3) )
  4713. {
  4714. ShowMessage(stderr,GetResString(IDS_UPDATE_SYNTAX));
  4715. return ( EXIT_FAILURE );
  4716. }
  4717. // Displaying query usage if user specified -? with -query option
  4718. if( bUsage )
  4719. {
  4720. displayUpdateUsage_IA64() ;
  4721. return (EXIT_SUCCESS);
  4722. }
  4723. dwExitcode = InitializeEFI();
  4724. if(EXIT_FAILURE == dwExitcode )
  4725. {
  4726. return EXIT_FAILURE ;
  4727. }
  4728. if(!bUsage && (StringLengthW(szUpdate,0) ==0) )
  4729. {
  4730. ShowMessage(stderr,GetResString(IDS_UPDATE_SYNTAX));
  4731. return EXIT_FAILURE ;
  4732. }
  4733. if(StringLengthW(szUpdate,0) !=0)
  4734. {
  4735. //
  4736. // Pass the GUID specified by the User
  4737. // and convert that into the ARC signature Path.
  4738. //
  4739. //Trim the Leading and trailing brackets specified
  4740. // by the user.
  4741. StrTrim(szUpdate, szBrackets);
  4742. //dwActuals = cmdOptions[2].dwActuals ;
  4743. dwActuals = 0 ;
  4744. if (GetDeviceInfo(szUpdate,szFinalStr,dwList,dwActuals) == EXIT_FAILURE )
  4745. {
  4746. return EXIT_FAILURE ;
  4747. }
  4748. //acquire the necessary privilages for querying and manipulating the NV RAM.
  4749. status = AcquirePrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE );
  4750. if ( !NT_SUCCESS(status) )
  4751. {
  4752. ShowMessage(stderr,GetResString(IDS_INSUFF_PRIV));
  4753. return HRESULT_FROM_NT(status);
  4754. }
  4755. //Enumerate the list of Boot Entries in the NV Ram.
  4756. status = EnumerateBootEntries( (PVOID *) &pEntryListHead );
  4757. if ( !NT_SUCCESS(status) || !pEntryListHead )
  4758. {
  4759. if ( !pEntryListHead )
  4760. {
  4761. return EXIT_FAILURE ;
  4762. }
  4763. }
  4764. //
  4765. // Find The BootEntry corresponding to the ARC Signature path specified by the user.
  4766. //
  4767. //
  4768. status = FindBootEntry( pEntryListHead,szFinalStr,&pTargetEntry);
  4769. if ( !NT_SUCCESS(status) && STATUS_OBJECT_NAME_NOT_FOUND != status)
  4770. {
  4771. DISPLAY_MESSAGE(stderr,GetResString(IDS_FIND_FAIL) );
  4772. return EXIT_FAILURE ;
  4773. }
  4774. }
  4775. return EXIT_SUCCESS ;
  4776. }
  4777. DWORD
  4778. GetBootPath(IN LPTSTR szValue,
  4779. IN LPTSTR szResult
  4780. )
  4781. /*++
  4782. Routine Description : retreive the information from registry
  4783. Arguments :
  4784. [ in ] Keyname : System name
  4785. Return Type : DWORD
  4786. ERROR_SUCCESS : if successful in retreiving information.
  4787. ERROR_RETREIVE_REGISTRY : if error occurs while retreving information.
  4788. --*/
  4789. {
  4790. HKEY hKey1 = 0;
  4791. HKEY hRemoteKey = 0;
  4792. TCHAR szPath[MAX_STRING_LENGTH + 1] = SUBKEY1 ;
  4793. DWORD dwValueSize = MAX_STRING_LENGTH + 1;
  4794. DWORD dwRetCode = ERROR_SUCCESS;
  4795. DWORD dwError = 0;
  4796. TCHAR szTmpCompName[MAX_STRING_LENGTH+1] = NULL_STRING;
  4797. DWORD dwLength = MAX_STRING_LENGTH ;
  4798. LPTSTR szReturnValue = NULL ;
  4799. DWORD dwCode = 0 ;
  4800. szReturnValue = ( LPTSTR ) AllocateMemory( dwLength*sizeof( TCHAR ) );
  4801. if(szReturnValue == NULL)
  4802. {
  4803. return ERROR_RETREIVE_REGISTRY ;
  4804. }
  4805. // Get Remote computer local machine key
  4806. dwError = RegConnectRegistry(szTmpCompName,HKEY_LOCAL_MACHINE,&hRemoteKey);
  4807. if (dwError == ERROR_SUCCESS)
  4808. {
  4809. dwError = RegOpenKeyEx(hRemoteKey,szPath,0,KEY_READ,&hKey1);
  4810. if (dwError == ERROR_SUCCESS)
  4811. {
  4812. dwRetCode = RegQueryValueEx(hKey1, szValue, NULL, NULL,(LPBYTE) szReturnValue, &dwValueSize);
  4813. if (dwRetCode == ERROR_MORE_DATA)
  4814. {
  4815. if ( szReturnValue != NULL )
  4816. {
  4817. FreeMemory((LPVOID *) &szReturnValue );
  4818. szReturnValue = NULL;
  4819. }
  4820. szReturnValue = ( LPTSTR ) AllocateMemory( dwValueSize*sizeof( TCHAR ) );
  4821. if(szReturnValue == NULL)
  4822. {
  4823. RegCloseKey(hKey1);
  4824. RegCloseKey(hRemoteKey);
  4825. SAFEFREE(szReturnValue);
  4826. return ERROR_RETREIVE_REGISTRY ;
  4827. }
  4828. dwRetCode = RegQueryValueEx(hKey1, szValue, NULL, NULL,(LPBYTE) szReturnValue, &dwValueSize);
  4829. }
  4830. if(dwRetCode != ERROR_SUCCESS)
  4831. {
  4832. RegCloseKey(hKey1);
  4833. RegCloseKey(hRemoteKey);
  4834. SAFEFREE(szReturnValue);
  4835. return ERROR_RETREIVE_REGISTRY ;
  4836. }
  4837. }
  4838. else
  4839. {
  4840. RegCloseKey(hRemoteKey);
  4841. SAFEFREE(szReturnValue);
  4842. return ERROR_RETREIVE_REGISTRY ;
  4843. }
  4844. RegCloseKey(hKey1);
  4845. }
  4846. else
  4847. {
  4848. RegCloseKey(hRemoteKey);
  4849. SAFEFREE(szReturnValue);
  4850. return ERROR_RETREIVE_REGISTRY ;
  4851. }
  4852. RegCloseKey(hRemoteKey);
  4853. StringCopy(szResult,szReturnValue, MAX_RES_STRING+1);
  4854. SAFEFREE(szReturnValue);
  4855. return dwCode ;
  4856. }
  4857. NTSTATUS
  4858. LowGetPartitionInfo(
  4859. IN HANDLE handle,
  4860. OUT PARTITION_INFORMATION_EX *partitionData
  4861. )
  4862. /*++
  4863. Routine Description:
  4864. This routine gets the partition information given a handle to a partition.
  4865. Arguments:
  4866. handle - A handle to the partition.
  4867. partitionData - Returns a partition information structure.
  4868. Return Value:
  4869. Returns STATUS_SUCESS if successful, otherwise it returns the error code.
  4870. --*/
  4871. {
  4872. NTSTATUS status = STATUS_SUCCESS;
  4873. IO_STATUS_BLOCK statusBlock;
  4874. RtlZeroMemory( &statusBlock, sizeof(IO_STATUS_BLOCK) );
  4875. if ( (NULL == partitionData)
  4876. || (sizeof(*partitionData) < sizeof(PARTITION_INFORMATION_EX))
  4877. || (NULL == handle)
  4878. || (INVALID_HANDLE_VALUE == handle) )
  4879. {
  4880. return STATUS_INVALID_PARAMETER;
  4881. }
  4882. RtlZeroMemory( partitionData, sizeof(PARTITION_INFORMATION_EX) );
  4883. status = NtDeviceIoControlFile(handle,
  4884. 0,
  4885. NULL,
  4886. NULL,
  4887. &statusBlock,
  4888. IOCTL_DISK_GET_PARTITION_INFO_EX,
  4889. NULL,
  4890. 0,
  4891. partitionData,
  4892. sizeof(PARTITION_INFORMATION_EX)
  4893. );
  4894. return status;
  4895. }
  4896. LONG
  4897. DmCommonNtOpenFile(
  4898. IN PWSTR Name,
  4899. IN ULONG access,
  4900. IN PHANDLE Handle
  4901. )
  4902. /*++
  4903. Routine Description:
  4904. This is a routine to handle open requests.
  4905. Arguments:
  4906. Name - pointer to the NT name for the open.
  4907. Handle - pointer for the handle returned.
  4908. Return Value:
  4909. NT status
  4910. --*/
  4911. {
  4912. OBJECT_ATTRIBUTES oa;
  4913. NTSTATUS status;
  4914. IO_STATUS_BLOCK statusBlock;
  4915. UNICODE_STRING unicodeName;
  4916. int i = 0 ;
  4917. status = RtlCreateUnicodeString(&unicodeName, Name);
  4918. if (!NT_SUCCESS(status))
  4919. {
  4920. return status;
  4921. }
  4922. RtlZeroMemory(&statusBlock, sizeof(IO_STATUS_BLOCK));
  4923. RtlZeroMemory(&oa, sizeof(OBJECT_ATTRIBUTES));
  4924. oa.Length = sizeof(OBJECT_ATTRIBUTES);
  4925. oa.ObjectName = &unicodeName;
  4926. oa.Attributes = OBJ_CASE_INSENSITIVE;
  4927. // If a sharing violation occurs,retry it for
  4928. // max. 10 seconds
  4929. for (i = 0; i < 5; i++)
  4930. {
  4931. status = NtOpenFile(Handle,
  4932. SYNCHRONIZE | access,
  4933. &oa,
  4934. &statusBlock,
  4935. FILE_SHARE_READ | FILE_SHARE_WRITE,
  4936. FILE_SYNCHRONOUS_IO_ALERT
  4937. );
  4938. if (status == STATUS_SHARING_VIOLATION) {
  4939. Sleep(2000);
  4940. }
  4941. else {
  4942. break;
  4943. }
  4944. }
  4945. RtlFreeUnicodeString(&unicodeName);
  4946. return status;
  4947. }
  4948. DWORD
  4949. AddMirrorPlex( IN LPTSTR szOsLoadPath ,
  4950. IN LPTSTR szLoaderPath ,
  4951. IN LPTSTR szValue ,
  4952. IN BOOL bFlag,
  4953. IN LPTSTR szFriendlyName
  4954. )
  4955. /*++
  4956. Routine Description:
  4957. This is a routine to Add a new mirror Entry
  4958. Arguments:
  4959. Return Value:
  4960. DWORD.
  4961. --*/
  4962. {
  4963. // local variables
  4964. HRESULT hr = S_OK;
  4965. BOOLEAN wasEnabled = TRUE;
  4966. DWORD dwAlign = 0;
  4967. DWORD dwError = 0;
  4968. DWORD dwLength = 0;
  4969. DWORD dwBootEntrySize = 0;
  4970. DWORD dwBootFilePathSize = 0;
  4971. DWORD dwOsLoadPathSize = 0;
  4972. DWORD dwWindowsOptionsSize = 0;
  4973. PBOOT_ENTRY pBootEntry = NULL;
  4974. PWINDOWS_OS_OPTIONS pWindowsOptions = NULL;
  4975. PFILE_PATH pBootFilePath = NULL;
  4976. PFILE_PATH pOsLoadPath = NULL;
  4977. ULONG* pdwIdsArray = NULL;
  4978. ULONG ulId = 0;
  4979. ULONG ulIdCount = 0;
  4980. NTSTATUS status;
  4981. TCHAR pwszBootFilePath[MAX_RES_STRING+1] = NULL_STRING;
  4982. PFILE_PATH pFilePath = NULL;
  4983. HANDLE hPart = INVALID_HANDLE_VALUE;
  4984. GUID guid;
  4985. PARTITION_INFORMATION_EX PartitionInfo;
  4986. TCHAR szBootPath[MAX_RES_STRING+1] = NULL_STRING;
  4987. // enable the privilege that is necessary to query/set NVRAM.
  4988. status = RtlAdjustPrivilege( SE_SYSTEM_ENVIRONMENT_PRIVILEGE, TRUE, FALSE, &wasEnabled );
  4989. if ( !NT_SUCCESS( status ) )
  4990. {
  4991. dwError = RtlNtStatusToDosError( status );
  4992. DISPLAY_MESSAGE( stderr, GetResString(IDS_INSUFF_PRIV));
  4993. return EXIT_FAILURE;
  4994. }
  4995. //
  4996. // open the system device
  4997. //
  4998. status = DmCommonNtOpenFile( szValue, GENERIC_READ, &hPart );
  4999. if ( status || !hPart || INVALID_HANDLE_VALUE == hPart )
  5000. {
  5001. dwError = RtlNtStatusToDosError( status );
  5002. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ADD));
  5003. return EXIT_FAILURE;
  5004. }
  5005. //
  5006. // The structure is zero'ed in this call before retrieving the data.
  5007. //
  5008. status = LowGetPartitionInfo( hPart, &PartitionInfo );
  5009. if ( status )
  5010. {
  5011. dwError = RtlNtStatusToDosError( status );
  5012. DISPLAY_MESSAGE(stderr,GetResString(IDS_PARTITION_ERROR));
  5013. return EXIT_FAILURE;
  5014. }
  5015. if ( PARTITION_STYLE_GPT != PartitionInfo.PartitionStyle )
  5016. {
  5017. dwError = RtlNtStatusToDosError( status );
  5018. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_PARTITION_STYLE));
  5019. return EXIT_FAILURE;
  5020. }
  5021. //
  5022. // Setup the OSLoader file path.
  5023. //
  5024. guid = PartitionInfo.Gpt.PartitionId;
  5025. if (bFlag)
  5026. {
  5027. StringCopy(szBootPath,BOOTFILE_PATH, SIZE_OF_ARRAY(szBootPath));
  5028. }
  5029. else
  5030. {
  5031. StringCopy(szBootPath,BOOTFILE_PATH1, SIZE_OF_ARRAY(szBootPath) );
  5032. }
  5033. SecureZeroMemory(pwszBootFilePath, sizeof(pwszBootFilePath) );
  5034. hr = StringCchPrintf( pwszBootFilePath, SIZE_OF_ARRAY(pwszBootFilePath)-1,
  5035. szBootPath,
  5036. guid.Data1,
  5037. guid.Data2,
  5038. guid.Data3,
  5039. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
  5040. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7],
  5041. szLoaderPath);
  5042. //
  5043. // prepare the boot file path
  5044. //
  5045. //
  5046. // determine the length of the BOOTFILE_PATH
  5047. dwLength = StringLengthW( pwszBootFilePath,0) + 1;
  5048. // now determine the memory size that needs to be allocated for FILE_PATH structure
  5049. // and align up to the even memory bounday
  5050. dwBootFilePathSize = FIELD_OFFSET( FILE_PATH, FilePath ) + (dwLength * sizeof( WCHAR ));
  5051. // allocate the memory
  5052. pBootFilePath = (PFILE_PATH) AllocateMemory( sizeof( BYTE )*dwBootFilePathSize );
  5053. if ( NULL == pBootFilePath )
  5054. {
  5055. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL);
  5056. return EXIT_FAILURE;
  5057. }
  5058. // set the values now
  5059. SecureZeroMemory( pBootFilePath, dwBootFilePathSize ); // double init
  5060. pBootFilePath->Length = dwBootFilePathSize;
  5061. pBootFilePath->Type = FILE_PATH_TYPE_ARC_SIGNATURE;
  5062. pBootFilePath->Version = FILE_PATH_VERSION;
  5063. CopyMemory( pBootFilePath->FilePath, pwszBootFilePath, dwLength * sizeof( WCHAR ) );
  5064. //
  5065. // testing translating
  5066. //
  5067. pFilePath = (PFILE_PATH) AllocateMemory( sizeof( BYTE )* 1024 );
  5068. if(NULL == pFilePath )
  5069. {
  5070. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  5071. return EXIT_FAILURE;
  5072. }
  5073. ulId = 1024;
  5074. status = NtTranslateFilePath( pBootFilePath, FILE_PATH_TYPE_NT, pFilePath, &ulId );
  5075. if ( ! NT_SUCCESS( status ) )
  5076. {
  5077. dwError = RtlNtStatusToDosError( status );
  5078. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ADD));
  5079. SAFEFREE( pBootFilePath );
  5080. SAFEFREE( pFilePath );
  5081. return EXIT_FAILURE;
  5082. }
  5083. //
  5084. // determine the length of the OSLOAD PATH
  5085. //
  5086. dwLength = StringLengthW( szOsLoadPath,0 ) + 1;
  5087. // now determine the memory size that needs to be allocated for FILE_PATH structure
  5088. // and align up to the even memory bounday
  5089. dwOsLoadPathSize = FIELD_OFFSET( FILE_PATH, FilePath ) + (dwLength * sizeof( WCHAR ));
  5090. // allocate the memory
  5091. pOsLoadPath = (PFILE_PATH) AllocateMemory( sizeof( BYTE )*dwOsLoadPathSize );
  5092. if(pOsLoadPath == NULL)
  5093. {
  5094. SAFEFREE( pBootFilePath );
  5095. SAFEFREE( pFilePath);
  5096. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  5097. DISPLAY_MESSAGE( stderr, ERROR_TAG);
  5098. ShowLastError(stderr);
  5099. return EXIT_FAILURE;
  5100. }
  5101. // set the values now
  5102. SecureZeroMemory( pOsLoadPath, dwOsLoadPathSize ); // double init
  5103. pOsLoadPath->Length = dwOsLoadPathSize;
  5104. pOsLoadPath->Type = FILE_PATH_TYPE_ARC_SIGNATURE;
  5105. pOsLoadPath->Version = FILE_PATH_VERSION;
  5106. CopyMemory( pOsLoadPath->FilePath, szOsLoadPath, dwLength * sizeof( WCHAR ) );
  5107. //
  5108. // windows os options
  5109. //
  5110. // determine the size needed
  5111. dwLength = 1; // os load options is empty string
  5112. dwWindowsOptionsSize = sizeof(WINDOWS_OS_OPTIONS) +
  5113. dwOsLoadPathSize + sizeof(DWORD); // Need to align the FILE_PATH struct
  5114. // allocate the memory
  5115. pWindowsOptions = (PWINDOWS_OS_OPTIONS) AllocateMemory( dwWindowsOptionsSize*sizeof( BYTE ) );
  5116. if(pWindowsOptions == NULL)
  5117. {
  5118. SAFEFREE( pBootFilePath );
  5119. SAFEFREE( pFilePath);
  5120. SAFEFREE( pOsLoadPath);
  5121. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  5122. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL);
  5123. return EXIT_FAILURE;
  5124. }
  5125. // set the values now
  5126. SecureZeroMemory( pWindowsOptions, dwWindowsOptionsSize ); // double init
  5127. CopyMemory( (BYTE*) pWindowsOptions->Signature, WINDOWS_OS_OPTIONS_SIGNATURE, sizeof(WINDOWS_OS_OPTIONS_SIGNATURE) );
  5128. pWindowsOptions->Length = dwWindowsOptionsSize;
  5129. pWindowsOptions->Version = WINDOWS_OS_OPTIONS_VERSION;
  5130. pWindowsOptions->OsLoadPathOffset = sizeof( WINDOWS_OS_OPTIONS );
  5131. //
  5132. // Need to align the OsLoadPathOffset on a 4 byte boundary.
  5133. //
  5134. dwAlign = ( pWindowsOptions->OsLoadPathOffset & (sizeof(DWORD) - 1) );
  5135. if ( dwAlign != 0 )
  5136. {
  5137. pWindowsOptions->OsLoadPathOffset += sizeof(DWORD) - dwAlign;
  5138. }
  5139. StringCopy(pWindowsOptions->OsLoadOptions, L"", StringLengthW(L"",0) );
  5140. CopyMemory( ((BYTE*) pWindowsOptions) + pWindowsOptions->OsLoadPathOffset, pOsLoadPath, dwOsLoadPathSize );
  5141. //
  5142. // prepare the boot entry
  5143. //
  5144. // find the length of the friendly name
  5145. dwLength = StringLengthW( szFriendlyName, 0 ) + 1;
  5146. // determine the size of the structure
  5147. dwBootEntrySize = FIELD_OFFSET( BOOT_ENTRY, OsOptions ) +
  5148. dwWindowsOptionsSize +
  5149. ( dwLength * sizeof( WCHAR ) ) +
  5150. dwBootFilePathSize +
  5151. + sizeof(WCHAR) // Need to align the FriendlyName on WCHAR
  5152. + sizeof(DWORD); // Need to align the BootFilePath on DWORD
  5153. // allocate memory
  5154. pBootEntry = (PBOOT_ENTRY) AllocateMemory( sizeof( BYTE )*dwBootEntrySize );
  5155. if(pBootEntry == NULL)
  5156. {
  5157. SAFEFREE( pBootFilePath );
  5158. SAFEFREE( pFilePath);
  5159. SAFEFREE( pOsLoadPath);
  5160. SAFEFREE( pWindowsOptions);
  5161. ShowLastErrorEx(stderr, SLE_TYPE_ERROR|SLE_INTERNAL );
  5162. return EXIT_FAILURE;
  5163. }
  5164. // set the values now
  5165. SecureZeroMemory( pBootEntry, dwBootEntrySize );
  5166. pBootEntry->Version = BOOT_ENTRY_VERSION;
  5167. pBootEntry->Length = dwBootEntrySize;
  5168. pBootEntry->Id = 0L;
  5169. pBootEntry->Attributes = BOOT_ENTRY_ATTRIBUTE_ACTIVE;
  5170. pBootEntry->FriendlyNameOffset = FIELD_OFFSET(BOOT_ENTRY, OsOptions) + dwWindowsOptionsSize;
  5171. //
  5172. // Need to align the unicode string on a 2 byte boundary.
  5173. //
  5174. dwAlign = ( pBootEntry->FriendlyNameOffset & (sizeof(WCHAR) - 1) );
  5175. if ( dwAlign != 0 )
  5176. {
  5177. pBootEntry->FriendlyNameOffset += sizeof(WCHAR) - dwAlign;
  5178. }
  5179. pBootEntry->BootFilePathOffset = pBootEntry->FriendlyNameOffset + ( dwLength * sizeof(WCHAR) );
  5180. //
  5181. // Need to align the FILE_PATH struct on a 4 byte boundary.
  5182. //
  5183. dwAlign = ( pBootEntry->BootFilePathOffset & (sizeof(DWORD) - 1) );
  5184. if ( dwAlign != 0 )
  5185. {
  5186. pBootEntry->BootFilePathOffset += sizeof(DWORD) - dwAlign;
  5187. }
  5188. pBootEntry->OsOptionsLength = dwWindowsOptionsSize;
  5189. CopyMemory( pBootEntry->OsOptions, pWindowsOptions, dwWindowsOptionsSize );
  5190. CopyMemory( ((PBYTE) pBootEntry) + pBootEntry->FriendlyNameOffset, szFriendlyName, ( dwLength * sizeof(WCHAR) ) );
  5191. CopyMemory( ((PBYTE) pBootEntry) + pBootEntry->BootFilePathOffset, pBootFilePath, dwBootFilePathSize );
  5192. //
  5193. // add the prepared boot entry
  5194. //
  5195. status = NtAddBootEntry( pBootEntry, &ulId );
  5196. if ( ! NT_SUCCESS( status ) )
  5197. {
  5198. dwError = RtlNtStatusToDosError( status );
  5199. SAFEFREE( pBootFilePath );
  5200. SAFEFREE( pFilePath);
  5201. SAFEFREE( pOsLoadPath);
  5202. SAFEFREE( pWindowsOptions);
  5203. DISPLAY_MESSAGE(stderr,GetResString(IDS_ERROR_ADD));
  5204. return EXIT_FAILURE;
  5205. }
  5206. else
  5207. {
  5208. DISPLAY_MESSAGE(stdout,GetResString(IDS_MIRROR_ADDED));
  5209. }
  5210. //
  5211. // Add the entry to the boot order.
  5212. //
  5213. ulIdCount = 32L;
  5214. pdwIdsArray = (PULONG) AllocateMemory(ulIdCount * sizeof(ULONG));
  5215. if(!pdwIdsArray)
  5216. {
  5217. SAFEFREE( pBootFilePath );
  5218. SAFEFREE( pFilePath);
  5219. SAFEFREE( pOsLoadPath);
  5220. SAFEFREE( pWindowsOptions);
  5221. SAFEFREE( pBootEntry);
  5222. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  5223. return EXIT_FAILURE;
  5224. }
  5225. status = NtQueryBootEntryOrder( pdwIdsArray, &ulIdCount );
  5226. if (! NT_SUCCESS( status ) )
  5227. {
  5228. ShowMessage(stderr,GetResString(IDS_ERROR_SET_BOOTENTRY));
  5229. SAFEFREE( pBootFilePath );
  5230. SAFEFREE( pFilePath);
  5231. SAFEFREE( pOsLoadPath);
  5232. SAFEFREE( pWindowsOptions);
  5233. SAFEFREE( pBootEntry);
  5234. SAFEFREE( pdwIdsArray);
  5235. return EXIT_SUCCESS ;
  5236. }
  5237. //
  5238. // Need room in the buffer for the new entry.
  5239. //
  5240. if ( 31L < ulIdCount )
  5241. {
  5242. pdwIdsArray = (PULONG) AllocateMemory( (ulIdCount+1) * sizeof(ULONG));
  5243. if(!pdwIdsArray)
  5244. {
  5245. SAFEFREE( pBootFilePath );
  5246. SAFEFREE( pFilePath);
  5247. SAFEFREE( pOsLoadPath);
  5248. SAFEFREE( pWindowsOptions);
  5249. SAFEFREE( pBootEntry);
  5250. SAFEFREE( pdwIdsArray);
  5251. ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  5252. return EXIT_FAILURE;
  5253. }
  5254. status = NtQueryBootEntryOrder( pdwIdsArray, &ulIdCount );
  5255. }
  5256. if ( !NT_SUCCESS(status) )
  5257. {
  5258. SAFEFREE( pBootFilePath );
  5259. SAFEFREE( pFilePath);
  5260. SAFEFREE( pOsLoadPath);
  5261. SAFEFREE( pWindowsOptions);
  5262. SAFEFREE( pBootEntry);
  5263. SAFEFREE( pdwIdsArray);
  5264. dwError = RtlNtStatusToDosError( status );
  5265. ShowMessage(stderr,GetResString(IDS_ERROR_ADD));
  5266. return EXIT_FAILURE;
  5267. }
  5268. ulIdCount++;
  5269. *(pdwIdsArray + (ulIdCount - 1)) = ulId;
  5270. status = NtSetBootEntryOrder( pdwIdsArray, ulIdCount );
  5271. if ( !NT_SUCCESS(status) )
  5272. {
  5273. SAFEFREE( pBootFilePath );
  5274. SAFEFREE( pFilePath);
  5275. SAFEFREE( pOsLoadPath);
  5276. SAFEFREE( pWindowsOptions);
  5277. SAFEFREE( pBootEntry);
  5278. SAFEFREE( pdwIdsArray);
  5279. dwError = RtlNtStatusToDosError( status );
  5280. ShowMessage(stderr,GetResString(IDS_ERROR_ADD));
  5281. return EXIT_FAILURE;
  5282. }
  5283. //
  5284. // release the allocated memory
  5285. //
  5286. SAFEFREE( pBootFilePath );
  5287. SAFEFREE( pFilePath);
  5288. SAFEFREE( pOsLoadPath);
  5289. SAFEFREE( pWindowsOptions);
  5290. SAFEFREE( pBootEntry);
  5291. SAFEFREE( pdwIdsArray);
  5292. return EXIT_SUCCESS;
  5293. }
  5294. DWORD
  5295. ConvertintoLocale( IN LPWSTR szTempBuf,
  5296. OUT LPWSTR szOutputStr )
  5297. /*++
  5298. Routine Description:
  5299. Converts into Locale and Gets the Locale information
  5300. Arguments:
  5301. LPWSTR szTempBuf [in] -- Locale Information to get
  5302. LPWSTR szOutputStr [out] -- Locale value corresponding to the given
  5303. information
  5304. Return Value:
  5305. DWORD
  5306. --*/
  5307. {
  5308. NUMBERFMT numberfmt;
  5309. WCHAR szGrouping[MAX_RES_STRING+1] = NULL_STRING;
  5310. WCHAR szDecimalSep[MAX_RES_STRING+1] = NULL_STRING;
  5311. WCHAR szThousandSep[MAX_RES_STRING+1] = NULL_STRING;
  5312. WCHAR szTemp[MAX_RES_STRING+1] = NULL_STRING;
  5313. LPWSTR szTemp1 = NULL;
  5314. LPWSTR pszStoppedString = NULL;
  5315. DWORD dwStatus = 0;
  5316. DWORD dwGrouping = 0;
  5317. //make the fractional digits and leading zeros to nothing
  5318. numberfmt.NumDigits = 0;
  5319. numberfmt.LeadingZero = 0;
  5320. //get the decimal seperate character
  5321. if(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep, SIZE_OF_ARRAY(szDecimalSep) ) == 0)
  5322. {
  5323. return EXIT_FAILURE;
  5324. }
  5325. numberfmt.lpDecimalSep = szDecimalSep;
  5326. if(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandSep, SIZE_OF_ARRAY(szThousandSep) ) == 0)
  5327. {
  5328. return EXIT_FAILURE;
  5329. }
  5330. numberfmt.lpThousandSep = szThousandSep;
  5331. if(GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, szGrouping, SIZE_OF_ARRAY(szGrouping) ) == 0)
  5332. {
  5333. return EXIT_FAILURE;
  5334. }
  5335. szTemp1 = wcstok( szGrouping, L";");
  5336. do
  5337. {
  5338. StringConcat( szTemp, szTemp1, SIZE_OF_ARRAY(szTemp));
  5339. szTemp1 = wcstok( NULL, L";" );
  5340. }while( szTemp1 != NULL && StringCompare( szTemp1, L"0", TRUE, 0) != 0);
  5341. dwGrouping = wcstol( szTemp, &pszStoppedString, 10);
  5342. numberfmt.Grouping = (UINT)dwGrouping ;
  5343. numberfmt.NegativeOrder = 2;
  5344. dwStatus = GetNumberFormat( LOCALE_USER_DEFAULT, 0, szTempBuf, &numberfmt, szOutputStr, MAX_RES_STRING+1);
  5345. return(EXIT_SUCCESS);
  5346. }
  5347. void Freelist()
  5348. /*++
  5349. Routine Description : Function used to free the global linked list
  5350. Arguments:
  5351. Return Type :
  5352. --*/
  5353. {
  5354. PLIST_ENTRY listEntry;
  5355. PLIST_ENTRY listEntry1;
  5356. PMY_BOOT_ENTRY bootEntry;
  5357. listEntry = BootEntries.Flink;
  5358. while( listEntry != &BootEntries)
  5359. {
  5360. listEntry1 = listEntry;
  5361. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  5362. RemoveEntryList( &bootEntry->ListEntry );
  5363. listEntry = listEntry->Flink;
  5364. if( listEntry1 != NULL )
  5365. {
  5366. FreeMemory((LPVOID *) &listEntry1 );
  5367. }
  5368. }
  5369. }
  5370. PWSTR GetDefaultBootEntry()
  5371. /*++
  5372. Routine Description :
  5373. Gets the default Boot entry.
  5374. Arguments :
  5375. Return Type : PWSTR
  5376. Returns the first entry in the list.
  5377. --*/
  5378. {
  5379. PLIST_ENTRY listEntry;
  5380. PMY_BOOT_ENTRY bootEntry;
  5381. PWSTR NtFilePath=NULL;
  5382. listEntry = BootEntries.Flink;
  5383. bootEntry = CONTAINING_RECORD( listEntry, MY_BOOT_ENTRY, ListEntry );
  5384. NtFilePath = GetNtNameForFilePath(bootEntry->OsFilePath);
  5385. return (NtFilePath);
  5386. }