source: trunk/TOOLS/OS2/SETABOOT/SETABOOT.C@ 47

Last change on this file since 47 was 46, checked in by Ben Rietbroek, 12 years ago

Various Changes [2012-04-14]

WARNING!!

All commits upto and including the commit of [2012-05-13] contain
a severe bug!! Building from these sources and then disabling
the 'force LBA' feature while also using the drive-letter feature or
editing the label can DESTROY THE MBR on ALL ATTACHED DISKS!!
DO NOT DISABLE 'FORCE LBA USAGE' WHEN BUILT FROM THE THESE COMMITS!!

Changes

o Added BLDLEVEL support
o Enhanced Master Make
o Sanitized sources
o Support for Wasm and Masm6 (experimental)
o Renamed MBR_PROT.ASM to MBR-PROT.ASM
o Merged bitfield code Into Installer
o First steps for cross platform Installer
o More...

File size: 34.4 KB
Line 
1// AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
2//
3// This file is part of AiR-BOOT
4//
5// AiR-BOOT is free software: you can redistribute it and/or modify it under
6// the terms of the GNU General Public License as published by the Free
7// Software Foundation, either version 3 of the License, or (at your option)
8// any later version.
9//
10// AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
11// WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
12// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13// details.
14//
15// You should have received a copy of the GNU General Public License along with
16// AiR-BOOT. If not, see <http://www.gnu.org/licenses/>.
17//
18
19/*
20// Rousseau: 2011-02-05
21// - Made volumes compare case insensitive so fs-label matches volume-name on command-line. (around line 510)
22// This means bootable volumes cannot not have the same and only differ in case.
23*/
24
25
26#include "SETABOOT.H"
27
28
29#define INCL_BASE
30#define INCL_WINSHELLDATA
31#define INCL_DOS
32#define INCL_DOSDEVIOCTL
33#include <os2.h>
34#include <malloc.h>
35
36#include <stdlib.h>
37#include <stdio.h>
38#include <ctype.h>
39#include <conio.h>
40#include <string.h>
41
42#include "MSGHELP.C"
43
44// Msg-IDs from OSO001.msg
45#define TXT_QUERY_TimeLimit_None 860
46#define TXT_QUERY_TimeLimit_Show 861
47#define TXT_QUERY_Mode_Extended 863
48#define TXT_QUERY_Mode_Normal 864
49#define TXT_SYNTAX_Show 867
50#define TXT_ERROR_DuringAccessHDD 868
51#define TXT_ERROR_NoValueFor 870
52#define TXT_ERROR_NeedsValueFor 871
53#define TXT_ERROR_BadParameter 872
54#define TXT_ERROR_BadValueFor 873
55#define TXT_ERROR_NoBootManager 874
56
57#pragma pack(1)
58
59// This structure needs NOT to get optimized, otherwise it will screw up...
60typedef struct _AiRBOOTCODESIG {
61 CHAR Identifier[7];
62 UCHAR DayOfRelease;
63 UCHAR MonthOfRelease;
64 USHORT YearOfRelease;
65 UCHAR MajorVersion;
66 UCHAR MinorVersion;
67 CHAR ReleaseLanguage;
68 UCHAR TotalCodeSectors;
69 USHORT CheckSumOfCode;
70 } AiRBOOTCODESIG;
71typedef AiRBOOTCODESIG *PAiRBOOTCODESIG;
72
73typedef struct _AiRBOOTCONFIG {
74 CHAR Identifier[13]; // Rousseau: INVISIBLE CHAR AT END !
75 UCHAR MajorVersion;
76 UCHAR MinorVersion;
77 CHAR ReleaseLanguage;
78 ULONG EditCounter;
79 USHORT CheckSumOfConfig;
80 UCHAR Partitions;
81 UCHAR Meaningless1;
82 UCHAR DefaultPartition;
83 UCHAR LastPartition;
84 UCHAR TimedBoot;
85 UCHAR TimedSeconds;
86 USHORT Meaningless2;
87 UCHAR TimedBootLast;
88 UCHAR RememberBoot;
89 UCHAR RememberTimed;
90 UCHAR IncludeFloppy;
91 UCHAR BootMenuActive;
92 UCHAR PartitionsDetect;
93 UCHAR PasswordedSetup;
94 UCHAR PasswordedSystem;
95 UCHAR PasswordedChangeBoot;
96 UCHAR ProtectMBRTSR;
97 UCHAR ProtectMBRignore;
98 UCHAR FloppyGetName;
99 UCHAR DetectVirus;
100 UCHAR DetectStealth;
101 UCHAR DetectVIBR;
102 UCHAR AutoEnterSetup;
103 UCHAR MasterPassword[8];
104 UCHAR BootPassword[8];
105 UCHAR Meaningless3;
106 UCHAR LinuxPartition;
107 UCHAR TimedKeyHandling;
108 UCHAR MakeSound;
109 UCHAR FloppyGetTimer;
110 UCHAR ResumeBIOSbootSeq;
111 UCHAR CooperBars;
112 CHAR LinuxCommandLine[75];
113 UCHAR LinuxKernelPartition;
114 CHAR LinuxDefaultKernel[11];
115 UCHAR LinuxKernelNameEnd;
116 CHAR LinuxLastKernel[11];
117 UCHAR LinuxKernelNameEnd2;
118 UCHAR ExtPartitionMShack;
119 UCHAR AutomaticBoot;
120 UCHAR AutomaticPartition;
121 UCHAR ForceLBAUsage;
122 UCHAR IgnoreLVM;
123 UCHAR Reserved[82];
124 CHAR InstallVolume[12];
125 } AiRBOOTCONFIG;
126typedef AiRBOOTCONFIG *PAiRBOOTCONFIG;
127
128
129
130typedef struct _AiRBOOTIPENTRY {
131 ULONG SerialNumber;
132 CHAR PartitionName[11];
133 UCHAR Drive;
134 UCHAR PartitionID;
135 UCHAR Flags;
136 USHORT CheckSum;
137 UCHAR LocationBegin[3];
138 UCHAR LocationPartTab[3];
139 ULONG AbsoluteBegin;
140 ULONG AbsolutePartTab;
141 } AiRBOOTIPENTRY;
142typedef AiRBOOTIPENTRY *PAiRBOOTIPENTRY;
143
144#pragma pack()
145
146#define AiRBOOTIPENTRY_Flags_BootAble 0x01
147
148CHAR Track0[62*512]; // Space for Track-0
149PAiRBOOTCODESIG AiRBOOT_CodeSig = 0;
150PAiRBOOTCONFIG AiRBOOT_Config = 0;
151PAiRBOOTIPENTRY AiRBOOT_IPT = 0;
152USHORT AiRBOOT_ConfigCheckSum = 0;
153UCHAR AiRBOOT_IPTCount = 0;
154
155
156/* Executables to search for */
157PCHAR classic_setboots[] = {
158 "SETBM.EXE",
159 NULL
160};
161
162
163/*
164// ProtoTypes.
165*/
166BOOL Track0DetectAirBoot (BOOL* ab_bad);
167BOOL Track0WriteAiRBOOTConfig (void);
168
169
170
171 USHORT CountHarddrives (void) {
172 USHORT NumDrives = 0;
173
174 if (DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &NumDrives, sizeof(NumDrives),NULL, 0) != 0)
175 return 0;
176 return NumDrives;
177 }
178
179 USHORT OS2_GetIOCTLHandle () {
180 USHORT IOCTLHandle = 0;
181
182 if (DosPhysicalDisk(INFO_GETIOCTLHANDLE, &IOCTLHandle, sizeof(IOCTLHandle),"1:" , 3) != 0)
183 return 0;
184 return IOCTLHandle;
185 }
186
187 void OS2_FreeIOCTLHandle (USHORT IOCTLHandle) {
188 DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &IOCTLHandle, sizeof(IOCTLHandle));
189 return;
190 }
191
192 BOOL Track0Load (void) {
193 USHORT IOCTLHandle;
194 ULONG TrackLayoutLen = sizeof(TRACKLAYOUT)+sizeof(ULONG)*(62-1);
195 TRACKLAYOUT *TrackLayoutPtr = malloc(TrackLayoutLen);
196 ULONG cbParms = sizeof(TrackLayoutPtr);
197 ULONG cbData = 512;
198 int i;
199 BOOL Success = FALSE;
200
201 IOCTLHandle = OS2_GetIOCTLHandle();
202
203 TrackLayoutPtr->bCommand = 0x01;
204 TrackLayoutPtr->usHead = 0;
205 TrackLayoutPtr->usCylinder = 0;
206 TrackLayoutPtr->usFirstSector = 0;
207 TrackLayoutPtr->cSectors = 62;
208
209 for (i=0; i<62; i++) {
210 TrackLayoutPtr->TrackTable[i].usSectorNumber = i+1;
211 TrackLayoutPtr->TrackTable[i].usSectorSize = 512;
212 }
213
214 if (!DosDevIOCtl(IOCTLHandle, IOCTL_PHYSICALDISK, PDSK_READPHYSTRACK,
215 TrackLayoutPtr, cbParms, &cbParms, &Track0, cbData, &cbData))
216 Success = TRUE;
217 OS2_FreeIOCTLHandle (IOCTLHandle);
218 free (TrackLayoutPtr);
219 return Success;
220 }
221
222 BOOL Track0Write (void) {
223 USHORT IOCTLHandle;
224 ULONG TrackLayoutLen = sizeof(TRACKLAYOUT)+sizeof(ULONG)*(62-1);
225 TRACKLAYOUT *TrackLayoutPtr = malloc(TrackLayoutLen);
226 ULONG cbParms = sizeof(TrackLayoutPtr);
227 ULONG cbData = 512;
228 INT i;
229 BOOL Success = FALSE;
230
231 IOCTLHandle = OS2_GetIOCTLHandle();
232
233
234 TrackLayoutPtr->bCommand = 0x01;
235 TrackLayoutPtr->usHead = 0;
236 TrackLayoutPtr->usCylinder = 0;
237 TrackLayoutPtr->usFirstSector = 0;
238 TrackLayoutPtr->cSectors = 62;
239
240 for (i=0; i<62; i++) {
241 TrackLayoutPtr->TrackTable[i].usSectorNumber = i+1;
242 TrackLayoutPtr->TrackTable[i].usSectorSize = 512;
243 }
244
245 if (!DosDevIOCtl(IOCTLHandle, IOCTL_PHYSICALDISK, PDSK_WRITEPHYSTRACK,
246 TrackLayoutPtr, cbParms, &cbParms, &Track0, cbData, &cbData))
247 Success = TRUE;
248 OS2_FreeIOCTLHandle (IOCTLHandle);
249 free (TrackLayoutPtr);
250 return Success;
251 }
252
253 #define CATEGORY_DOSSYS 0xD5
254 #define FUNCTION_REBOOT 0xAB
255
256 void RebootSystem (void) {
257 HFILE DosHandle;
258 ULONG DosOpenAction;
259
260 DosSleep (2000);
261 if (!DosOpen("DOS$", &DosHandle, &DosOpenAction, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE, NULL)) {
262 DosDevIOCtl(DosHandle, CATEGORY_DOSSYS, FUNCTION_REBOOT, NULL, 0, NULL, NULL, 0, NULL);
263 DosSleep (60000);
264 }
265 DosClose(DosHandle);
266 }
267
268
269APIRET QueryBootDrive(char *bootdrv)
270{
271 ULONG aulSysInfo[QSV_MAX] = {0}; // System Information Data Buffer
272 APIRET rc = NO_ERROR; // Return code
273
274 if(bootdrv==0) return 1;
275
276 rc = DosQuerySysInfo(1L, // Request all available system
277 QSV_MAX , // information
278 (PVOID)aulSysInfo, // Pointer to buffer
279 sizeof(ULONG)*QSV_MAX); // Size of the buffer
280
281 if (rc != NO_ERROR) {
282 return 1;
283 }
284 else {
285 //printf("Bootable drive: %c:\n",
286 // aulSysInfo[QSV_BOOT_DRIVE-1]+'A'-1); /* Max length of path name */
287 bootdrv[0]=aulSysInfo[QSV_BOOT_DRIVE-1]+'A'-1;
288
289 /*
290 printf("Total physical memory is %u bytes.\n",
291 aulSysInfo[QSV_TOTPHYSMEM-1]);
292 */
293
294 return 0;
295 }
296
297
298}
299
300USHORT GetChecksumOfSector (USHORT BaseCheck, USHORT SectorNo) {
301 PUSHORT CurPos = (PUSHORT)((ULONG)&Track0+(SectorNo-1)*512);
302 USHORT LengthLeft = 256;
303
304 while (LengthLeft-->0)
305 BaseCheck ^= (*CurPos++ ^ 0x0BABE);
306 if (BaseCheck==0) BaseCheck = 1;
307 return BaseCheck;
308 }
309
310
311
312
313/*
314// If AiR-BOOT is not installed, the user probably meant to control OS/2 BM with this utility.
315// Since the functionality of this utility is for AiR-BOOT only, we will pass the request to
316// the OS/2 BM SETBOOT utility which is called SETBM.EXE as of eCS 2.1.
317// In this case also the return-value of SETBM.EXE is returned.
318*/
319int DoClassicActions(int argc, char **argv) {
320 APIRET rc = -1;
321 RESULTCODES crc = {-1,-1};
322// PTIB ptib = NULL;
323// PPIB ppib = NULL;
324 char buffer[256] = "\0";
325 char cmdline[256] = "\0";
326 PSZ path = NULL;
327 char sresult[256] = "\0";
328 char bootdrive = '?';
329 char* p = NULL;
330 int i = 0;
331
332 //printf("\nCLASSIC ACTIONS !! (%d)\n", argc);
333
334 rc = QueryBootDrive(&bootdrive);
335
336 rc = DosScanEnv("PATH", &path);
337 rc = DosSearchPath(SEARCH_CUR_DIRECTORY | SEARCH_IGNORENETERRS,
338 path,
339 classic_setboots[0],
340 sresult,
341 sizeof(sresult));
342
343 //printf("SRESULT: rc=%d, %s\n", rc, sresult);
344
345 if (rc) {
346 printf("\n");
347 printf("ERROR: SETBOOT (AiR-BOOT version)\n");
348 printf("Since the AiR-BOOT Boot Manager is not installed,\n");
349 printf("this program (SETBOOT.EXE), funcions as a wrapper\n");
350 printf("to %s that should be used to control IBM Boot Manager.\n", classic_setboots[0]);
351 printf("However, %s could not be found in the PATH, the error-code is: %d\n", classic_setboots[0], rc);
352 printf("You can resolve this situation by renaming a valid SETBOOT.EXE to %s\n", classic_setboots[0]);
353 printf("and put it in your %c:\\OS2 directory.", bootdrive);
354 printf("\n");
355 exit(rc);
356 }
357
358
359
360
361 memset(cmdline, 0, sizeof(cmdline)); // Clear the command-line buffer.
362 p = cmdline; // Temporary pointer to insert arguments.
363 strcpy(p, sresult); // Copy the program-name.
364 p += strlen(sresult)+1; // Advance to point for space separated parameters.
365
366 /*
367 // Process all the arguments,
368 // inserting the separated by a space.
369 */
370 for (i=1; i<argc; i++) {
371 strcpy(p, argv[i]); // Copy the argument.
372 p += strlen(argv[i]); // Advance pointer past argument.
373 *p++ = ' '; // Space separation.
374 }
375
376 /*
377 for (i=0; i<100; i++) {
378 printf("%c", cmdline[i] ? cmdline[i] : '#');
379 }
380 printf("\n");
381 */
382
383 //printf("CMDLINE: %s\n", cmdline);
384 //printf("CMDLINE+: %s\n", cmdline+strlen(sresult)+1);
385
386 rc = DosExecPgm(buffer,
387 sizeof(buffer),
388 EXEC_SYNC,
389 cmdline,
390 NULL,
391 &crc,
392 sresult);
393
394 //rc = 3;
395 if (rc) {
396 printf("\n");
397 printf("ERROR: SETBOOT (AiR-BOOT version)\n");
398 printf("Since the AiR-BOOT Boot Manager is not installed,\n");
399 printf("this program (SETBOOT.EXE), funcions as a wrapper\n");
400 printf("to %s that should be used to control IBM Boot Manager.\n", classic_setboots[0]);
401 printf("However, something went wrong when executing %s.\n", classic_setboots[0]);
402 printf("The error-code is: %d and the termination-code is: %d\n", rc, crc.codeTerminate);
403 printf("\n");
404 exit(rc);
405 }
406
407
408 //printf("DosExecPgm: rc=%08X, codeterminate=%08X, coderesult=%08X\n", rc, crc.codeTerminate, crc.codeResult);
409
410 /*
411 rc = DosGetInfoBlocks(&ptib, &ppib);
412
413 rc = DosQueryModuleName(ppib->pib_hmte, sizeof(buffer), buffer);
414 printf("MODULE: %s\n", buffer);
415 printf("CMDLINE: %s\n", ppib->pib_pchcmd);
416 */
417
418 return crc.codeResult;
419}
420
421/*
422// This funtion is invoked when AiR-BOOT is installed.
423// It mimics the behavior of the original SETBOOT.EXE utility,
424// but operates on AiR-BOOT.
425*/
426int DoAirBootActions(int argc, char **argv, BOOL ab_detected, BOOL ab_bad) {
427 ULONG CurArgument = 0;
428 ULONG ArgumentLen = 0;
429 PCHAR StartPos = 0;
430 PCHAR EndPos = 0;
431 PCHAR CurPos = 0;
432 CHAR CurChar = 0;
433 BOOL DoXWPSupport = FALSE;
434 BOOL DoQuery = FALSE;
435 BOOL DoSetTimer = FALSE;
436 SHORT SetTimerValue = 0;
437 BOOL DoSetBootMenu = FALSE;
438 BOOL BootMenuDetailed = FALSE;
439 BOOL DoDirectBoot = FALSE;
440 BOOL DisableDirectBoot= FALSE;
441 UCHAR DirectBootPart = 0;
442 BOOL DoReboot = FALSE;
443 BOOL AiRBOOTDetected = FALSE;
444 BOOL AiRBOOTChanged = FALSE;
445 BOOL BadParm = FALSE;
446 BOOL BadValue = FALSE;
447 UCHAR CurPartitionNo = 0;
448 PAiRBOOTIPENTRY CurIPTEntry = 0;
449 CHAR TempBuffer[10];
450 ULONG XWPStringSize = 0;
451 PCHAR XWPOrgStringPtr = 0;
452 ULONG WriteLeft = 0;
453 ULONG TmpLength = 0;
454 ULONG TmpLength2 = 0;
455 ULONG XWPBootCount = 0;
456 CHAR XWPBootName[30][12];
457 CHAR XWPBootCommand[30][28]; // 'setaboot /IBA:""' (16 chars)
458 BOOL XWPEntryFound = FALSE;
459 BOOL CDBoot = FALSE; // TRUE if booted from CD; New System will be added when using /4:"LABEL"
460// BOOL Track0Loaded = FALSE; // Assume track0 did not load correctly.
461 BOOL AiRBOOTBad = FALSE;
462
463 //printf("\nAiR-BOOT ACTIONS !!\n");
464
465 AiRBOOTDetected = ab_detected;
466 AiRBOOTBad = ab_bad;
467
468 if (AiRBOOTBad)
469 return 1;
470
471 // Use OSO001.MSG, so we safe us the trouble of translating :)
472 if (!MSG_Init("OSO001.MSG"))
473 return 1;
474
475 /*
476 // Rousseau: changed version to be the same as the AiR-BOOT is accompanies.
477 */
478 //puts ("SETABOOT - AiR-BOOT Configuration Utility (OS/2) - (c) 2004-2009 by M. Kiewitz");
479 //puts ("SETABOOT v1.07a - AiR-BOOT Configuration Utility - (c) 2004-2011 by M. Kiewitz");
480 puts ("SETABOOT v1.0.8 - AiR-BOOT Configuration Utility - (c) 2004-2012 by M. Kiewitz");
481
482
483 //return 0;
484
485 /*
486 // Rousseau:
487 // Log some debug stuff to (virtual) flop.
488 */
489 /*
490 {
491 char buf[512]="\0";
492 FILE* fp = NULL;
493 int i = 0;
494
495 fp = fopen("A:\\SETBOOT.TXT", "a");
496 sprintf(buf, "Bliep");
497 fprintf(fp,"Program: %s\n", argv[0]);
498 fprintf(fp,"Arguments: %d\n", argc);
499 for (i=0; i<argc-1; i++) {
500 fprintf(fp, "Arg %d: %s\n", i+1, argv[i+1]);
501 }
502 fprintf(fp, "\n");
503 fclose(fp);
504 }
505 */
506
507
508
509 /*
510 // Rousseau: ## Enable boot-through when installing new system ##
511 // In the install-environment, the MEMDRIVE env-var is defined.
512 // This modifies the behavior after phase 1.
513 */
514 if (getenv("MEMDRIVE")) {
515 printf("CDBoot Environment.\n");
516 CDBoot = TRUE;
517 }
518
519
520 if (argc==1) {
521 MSG_Print (TXT_SYNTAX_Show);
522 return 1;
523 }
524
525
526
527
528 // Now we check for AiR-BOOT existance...
529 /*
530 if (CountHarddrives()>0) {
531 if (Track0Load()) {
532 // Rousseau: Track0DetectAirBoot() will init globals.
533 if (Track0DetectAirBoot()) // REPLACE WITH BOOL
534 AiRBOOTDetected = TRUE;
535 }
536 else {
537 MSG_Print (TXT_ERROR_DuringAccessHDD);
538 }
539 }
540 else {
541 MSG_Print (TXT_ERROR_DuringAccessHDD);
542 }
543 */
544
545 CurArgument = 1;
546 while (CurArgument<argc) {
547 StartPos = argv[CurArgument];
548 ArgumentLen = strlen(StartPos);
549
550 if ((*StartPos=='/') && (ArgumentLen>1)) {
551 StartPos++; ArgumentLen--;
552 CurChar = toupper(*StartPos++);
553
554 switch (CurChar) {
555 case '?':
556 MSG_Print (TXT_SYNTAX_Show);
557 return 1;
558 case 'B':
559 if (ArgumentLen==1) DoReboot = TRUE;
560 else BadParm = TRUE;
561 break;
562 case 'Q':
563 if (ArgumentLen==1) DoQuery = TRUE;
564 else BadParm = TRUE;
565 break;
566 case 'T':
567 DoSetTimer = TRUE;
568 if ((ArgumentLen>2) && (*StartPos==':')) {
569 *StartPos = 0; StartPos++;
570 CurPos = StartPos;
571 while (*CurPos!=0) {
572 if ((*CurPos<'0') || (*CurPos>'9')) {
573 BadValue = TRUE;
574 break;
575 }
576 CurPos++;
577 }
578 if (!BadValue) {
579 SetTimerValue = atoi(StartPos);
580 if ((SetTimerValue<0) || (SetTimerValue>255))
581 BadValue = TRUE;
582 } else {
583 if ((ArgumentLen==4) && (toupper(*CurPos)=='N') && (toupper(*(CurPos+1))=='O')) {
584 BadValue = FALSE;
585 SetTimerValue = -1; // Disable Timer
586 }
587 }
588 } else BadParm = TRUE;
589 break;
590 case 'M':
591 DoSetBootMenu = TRUE;
592 if ((ArgumentLen>2) && (*StartPos==':')) {
593 *StartPos = 0; StartPos++;
594 CurChar = toupper(*StartPos);
595 switch (CurChar) {
596 case 'N':
597 BootMenuDetailed = FALSE;
598 break;
599 case 'A':
600 BootMenuDetailed = TRUE;
601 break;
602 default:
603 BadValue = TRUE;
604 break;
605 }
606 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x91)) {
607 puts ("SETABOOT: AiR-BOOT v0.91 required for this feature.");
608 BadValue = TRUE;
609 }
610 } else BadParm = TRUE;
611 break;
612 case 'I':
613 case '4':
614 DoDirectBoot = TRUE;
615 if (CurChar=='I') {
616 if ((ArgumentLen>4) && (ArgumentLen<16) && (toupper(*StartPos++)=='B') && (toupper(*StartPos++)=='A') && (*StartPos==':')) {
617 DoReboot = TRUE; // IBA: requires us to reboot
618 ArgumentLen -= 4;
619 } else {
620 BadParm = TRUE;
621 break;
622 }
623 } else {
624 if ((ArgumentLen>1) && (ArgumentLen<33) && (*StartPos==':')) {
625 ArgumentLen -= 2;
626 } else {
627 BadParm = TRUE;
628 break;
629 }
630 }
631
632 *StartPos = 0; StartPos++;
633
634 // Search that partition in IPT of AiR-BOOT...
635 if ((CurChar=='4') && (ArgumentLen==0)) {
636 // '4:' and no partition name means disable automatic boot
637 DoDirectBoot = FALSE;
638 DisableDirectBoot = TRUE;
639 break;
640 }
641 if (ArgumentLen>11)
642 ArgumentLen = 11;
643
644 if (!AiRBOOTDetected) {
645 MSG_Print (TXT_ERROR_NoBootManager);
646 return 1;
647 }
648
649
650 /*
651 // Rousseau:
652 // Insert label of newly installed system in AiR-BOOT configuration.
653 // Note that it is changed to uppercase because AiR-BOOT uses the FS-label when
654 // scanning partitions and LVM-info is not found. (Otherwise PART-label)
655 // The auto-boot flag is not set in this case as this is handled by the AiR-BOOT loader.
656 */
657 if (CDBoot) {
658 strncpy(AiRBOOT_Config->InstallVolume, _strupr(StartPos), ArgumentLen);
659 AiRBOOT_Config->InstallVolume[ArgumentLen] = '\0';
660 printf("Writing Install Volume: %s to AiR-BOOT configuration.\n", AiRBOOT_Config->InstallVolume);
661 Track0WriteAiRBOOTConfig();
662 return 0;
663 }
664
665
666
667
668 BadValue = TRUE;
669 CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
670 while (CurPartitionNo<AiRBOOT_Config->Partitions) {
671 /*
672 // Rousseau: Changed below to case-insensitive compare.
673 // This solves the part/vol-label (mixed-case) v.s. fs-label (upper-case) issue.
674 */
675 /*if (strncmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {*/
676 if (strnicmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {
677 if (ArgumentLen==11) {
678 BadValue = FALSE;
679 break;
680 } else {
681 CurPos = CurIPTEntry->PartitionName+ArgumentLen;
682 EndPos = CurIPTEntry->PartitionName+11;
683 while ((CurPos<EndPos) && ((*CurPos==0x00) || (*CurPos==0x20)))
684 CurPos++;
685 if (CurPos==EndPos) {
686 BadValue = FALSE;
687 break;
688 }
689 }
690 }
691 CurPartitionNo++; CurIPTEntry++;
692 }
693
694
695 if (BadValue) {
696 puts ("SETABOOT: Partition not found in IPT.");
697 } else {
698 if (CurIPTEntry->Flags & AiRBOOTIPENTRY_Flags_BootAble) {
699 DirectBootPart = CurPartitionNo;
700 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
701 puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
702 BadValue = TRUE;
703 } else if ((AiRBOOT_Config->PasswordedSystem) || (AiRBOOT_Config->PasswordedChangeBoot)) {
704 puts ("SETABOOT: This feature needs password protection to be off.");
705 BadValue = TRUE;
706 }
707 } else {
708 BadValue = TRUE;
709 puts ("SETABOOT: Partition not set bootable.");
710 }
711 }
712 break;
713 case 'X':
714 if ((ArgumentLen==3) && (toupper(*StartPos++)=='W') && (toupper(*StartPos++)=='P')) {
715 if (!AiRBOOTDetected) {
716 MSG_Print (TXT_ERROR_NoBootManager);
717 return 1;
718 }
719 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
720 puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
721 BadValue = TRUE;
722 } else DoXWPSupport = TRUE;
723 break;
724 }
725 case 'N':
726 puts ("SETABOOT: No support for this option.");
727 default:
728 BadParm = TRUE;
729 }
730 } else BadParm = TRUE;
731
732 if (BadParm) {
733 MSG_SetInsertViaPSZ (1, argv[CurArgument]);
734 MSG_Print (TXT_ERROR_BadParameter);
735 return 1;
736 }
737 if (BadValue) {
738 MSG_SetInsertViaPSZ (1, StartPos);
739 MSG_SetInsertViaPSZ (2, argv[CurArgument]);
740 MSG_Print (TXT_ERROR_BadValueFor);
741 return 1;
742 }
743
744 CurArgument++;
745 }
746
747 if (DoXWPSupport) {
748 if ((!PrfQueryProfileSize(HINI_USERPROFILE, "XWorkplace", "XShutdown", &XWPStringSize))) {
749 puts ("SETABOOT: /XWP needs XWorkPlace.");
750 return 1;
751 }
752 // First, get the current string...
753 CurPos = XWPOrgStringPtr = malloc(65536);
754 WriteLeft = XWPStringSize = 65536;
755 if (!PrfQueryProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, &XWPStringSize))
756 XWPStringSize = 0;
757 EndPos = CurPos+XWPStringSize;
758
759 CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
760 while (CurPartitionNo<AiRBOOT_Config->Partitions) {
761 if (CurIPTEntry->Flags & AiRBOOTIPENTRY_Flags_BootAble) {
762 strncpy (XWPBootName[XWPBootCount], CurIPTEntry->PartitionName, 11);
763 XWPBootName[XWPBootCount][11] = 0;
764 sprintf (XWPBootCommand[XWPBootCount], "setaboot /IBA:\"%s\"", XWPBootName[XWPBootCount]);
765 XWPBootCount++;
766 }
767 CurPartitionNo++; CurIPTEntry++;
768 }
769
770 while ((CurPos<EndPos) && (*CurPos!=0)) {
771 StartPos = CurPos; TmpLength = strlen(CurPos)+1;
772 CurPos += TmpLength; TmpLength2 = strlen(CurPos)+1;
773
774 XWPEntryFound = FALSE;
775 for (CurPartitionNo=0; CurPartitionNo<XWPBootCount; CurPartitionNo++) {
776 if ((strcmp(StartPos, XWPBootName[CurPartitionNo])==0) && (strcmp(CurPos, XWPBootCommand[CurPartitionNo])==0))
777 XWPBootCommand[CurPartitionNo][0] = 0;
778 }
779 CurPos += TmpLength2;
780 WriteLeft -= TmpLength+TmpLength2;
781 }
782
783 for (CurPartitionNo=0; CurPartitionNo<XWPBootCount; CurPartitionNo++) {
784 if (XWPBootCommand[CurPartitionNo][0]!=0) {
785 if (WriteLeft>11+27) {
786 TmpLength = strlen(XWPBootName[CurPartitionNo])+1;
787 TmpLength2 = strlen(XWPBootCommand[CurPartitionNo])+1;
788 strcpy (CurPos, XWPBootName[CurPartitionNo]);
789 CurPos += TmpLength;
790 strcpy (CurPos, XWPBootCommand[CurPartitionNo]);
791 CurPos += TmpLength2;
792 WriteLeft += TmpLength+TmpLength2;
793 }
794 }
795 }
796 *CurPos = 0; CurPos++;
797 XWPStringSize = CurPos-XWPOrgStringPtr;
798
799 PrfWriteProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, XWPStringSize);
800 free(XWPOrgStringPtr);
801
802 puts ("SETABOOT: XWorkPlace updated.");
803 return 0;
804 }
805 if (DoQuery) {
806 if (!AiRBOOTDetected) {
807 MSG_Print (TXT_ERROR_NoBootManager);
808 return 1;
809 }
810 printf("SETABOOT: AiR-BOOT %X.%02X detected.\n\n", AiRBOOT_CodeSig->MajorVersion, AiRBOOT_CodeSig->MinorVersion);
811 //printf("DEBUG: InstallVolume: %s\n", AiRBOOT_Config->InstallVolume);
812 if (AiRBOOT_Config->BootMenuActive) {
813 if (AiRBOOT_Config->TimedBoot) {
814 itoa (AiRBOOT_Config->TimedSeconds, (PCHAR)&TempBuffer, 10);
815 MSG_SetInsertViaPSZ (1, TempBuffer);
816 MSG_Print (TXT_QUERY_TimeLimit_Show);
817 } else {
818 MSG_Print (TXT_QUERY_TimeLimit_None);
819 }
820 if (AiRBOOT_Config->BootMenuActive>1)
821 MSG_Print (TXT_QUERY_Mode_Extended);
822 else
823 MSG_Print (TXT_QUERY_Mode_Normal);
824 } else {
825 MSG_SetInsertViaPSZ (1, "0");
826 MSG_Print (TXT_QUERY_TimeLimit_Show);
827 MSG_Print (TXT_QUERY_Mode_Normal);
828 }
829 return 0;
830 }
831 if (DoSetTimer) {
832 if (!AiRBOOTDetected) {
833 MSG_Print (TXT_ERROR_NoBootManager);
834 return 1;
835 }
836 // Set Timer to "SetTimerValue" (1-255 -> seconds, -1 -> disable)
837 // 0 is a special case, which will disable the BootMenu
838 if (SetTimerValue==0) {
839 // 0 is a special case, that will disable the bootmenu
840 AiRBOOT_Config->BootMenuActive = 0; // Switches off Boot-Menu
841 } else if (SetTimerValue==-1) {
842 // -1 will disable Timed-Boot
843 if (AiRBOOT_Config->BootMenuActive==0)
844 AiRBOOT_Config->BootMenuActive = 1;
845 AiRBOOT_Config->TimedBoot = 0; // Switches off Timed-Boot
846 } else {
847 if (AiRBOOT_Config->BootMenuActive==0)
848 AiRBOOT_Config->BootMenuActive = 1;
849 AiRBOOT_Config->TimedBoot = 1; // Switches on Timed-Boot
850 AiRBOOT_Config->TimedSeconds = SetTimerValue;
851 }
852 AiRBOOTChanged = TRUE;
853 }
854 if (DoSetBootMenu) {
855 if (!AiRBOOTDetected) {
856 MSG_Print (TXT_ERROR_NoBootManager);
857 return 1;
858 }
859 // Sets type of Boot-menu
860 // Switches BootMenu between Enabled and Detailed state...
861 if (BootMenuDetailed)
862 AiRBOOT_Config->BootMenuActive = 2; // Switch to Detailed mode
863 else
864 AiRBOOT_Config->BootMenuActive = 1; // Switch to Enabled (Normal)
865 AiRBOOTChanged = TRUE;
866 }
867 if (DoDirectBoot) {
868 if (!AiRBOOTDetected) {
869 MSG_Print (TXT_ERROR_NoBootManager);
870 return 1;
871 }
872 // Sets Automatic-Booting to "DirectBootPart" (IPT-Entry)
873 AiRBOOT_Config->AutomaticBoot = 1; // Switches on Automatic-Boot
874 AiRBOOT_Config->AutomaticPartition = DirectBootPart;
875 AiRBOOTChanged = TRUE;
876 puts ("SETABOOT: Automatic boot enabled.");
877 }
878 if (DisableDirectBoot) {
879 if (!AiRBOOTDetected) {
880 MSG_Print (TXT_ERROR_NoBootManager);
881 return 1;
882 }
883 AiRBOOT_Config->AutomaticBoot = 0; // Switches off Automatic-Boot
884 AiRBOOT_Config->AutomaticPartition = 0;
885 AiRBOOTChanged = TRUE;
886 puts ("SETABOOT: Automatic boot disabled.");
887 }
888 if (AiRBOOTChanged) {
889 if (!Track0WriteAiRBOOTConfig())
890 return 1;
891 }
892 if (DoReboot) {
893 puts ("SETABOOT: Now rebooting system...");
894 RebootSystem();
895 }
896 return 0;
897
898
899
900}
901
902
903/*
904// Rousseau:
905// Global pointers will be initialized here !
906*/
907BOOL Track0DetectAirBoot (BOOL* ab_bad) {
908 USHORT ResultCheck;
909 USHORT CurSectorNo = 0;
910
911 /* Globals that get initialized */
912 AiRBOOT_CodeSig = (PAiRBOOTCODESIG)&Track0[2];
913 AiRBOOT_Config = (PAiRBOOTCONFIG)&Track0[(55-1)*512];
914 AiRBOOT_IPT = (PAiRBOOTIPENTRY)&Track0[(56-1)*512];
915
916 if (strncmp(AiRBOOT_CodeSig->Identifier, "AiRBOOT", 7)!=0) {
917 *ab_bad = FALSE;
918 return FALSE;
919 }
920
921 if ((AiRBOOT_CodeSig->TotalCodeSectors)>53) {
922 puts ("SETABOOT: AiR-BOOT Code damaged!");
923 *ab_bad = TRUE;
924 return TRUE;
925 }
926
927 ResultCheck = 0; CurSectorNo = 0;
928 while (CurSectorNo<AiRBOOT_CodeSig->TotalCodeSectors) {
929 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo+2);
930 CurSectorNo++;
931 }
932 if (ResultCheck!=AiRBOOT_CodeSig->CheckSumOfCode) {
933 puts ("SETABOOT: AiR-BOOT Code damaged!");
934 *ab_bad = TRUE;
935 return TRUE;
936 }
937
938 if (strncmp(AiRBOOT_Config->Identifier, "AiRCFG-TABLE­", 13)!=0) { // Rousseau: INVISIBLE CHAR HERE !
939 puts ("SETABOOT: AiR-BOOT Config damaged!");
940 *ab_bad = TRUE;
941 return TRUE;
942 }
943
944 // Set Config-CheckSum to 0
945 AiRBOOT_ConfigCheckSum = AiRBOOT_Config->CheckSumOfConfig;
946 AiRBOOT_Config->CheckSumOfConfig = 0;
947
948 // Calculate CheckSum...
949 // Rousseau: Only check 5 sectors for v1.07 compatibility.
950 ResultCheck = 0; CurSectorNo = 55;
951 while (CurSectorNo<60) {
952 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
953 CurSectorNo++;
954 }
955 if (ResultCheck!=AiRBOOT_ConfigCheckSum) {
956 puts ("SETABOOT: AiR-BOOT Config damaged!");
957 *ab_bad = TRUE;
958 return TRUE;
959 }
960 *ab_bad = FALSE;
961 return TRUE;
962 }
963
964BOOL Track0WriteAiRBOOTConfig (void) {
965 USHORT ResultCheck;
966 USHORT CurSectorNo = 0;
967
968 // Update Edit-Counter...
969 AiRBOOT_Config->EditCounter++;
970 AiRBOOT_Config->CheckSumOfConfig = 0;
971
972 // Calculate CheckSum...
973 ResultCheck = 0; CurSectorNo = 55;
974
975 /*
976 // Rousseau: # Keep compatible with v1.07 CRC #
977 // AB v1.07 had bugs in writing the wrong number of AB config sectors.
978 // This is fixed in v1.0.8 but the CRC has to be calculated the "v1.07 way"
979 // otherwise v1.07 SET(A)BOOT and INSTALL2.EXE will think the AB config
980 // is corrupted.
981 // So the CRC is calculated over 5 sectors instead of 7.
982 */
983 while (CurSectorNo<60) {
984 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
985 CurSectorNo++;
986 }
987 AiRBOOT_Config->CheckSumOfConfig = ResultCheck;
988
989 if (!Track0Write())
990 return FALSE;
991 return TRUE;
992 }
993
994
995/*
996// Rousseau: # This is the main entry-point #
997// Special behavior if eCS is booted from CDROM and phase 1 called this program.
998// In that case, the name of the newly installed system is put in the AiR-BOOT configuration.
999// This will cause AiR-BOOT to boot through after phase 1.
1000*/
1001int main (int argc, char **argv) {
1002 BOOL AiRBOOTDetected = FALSE;
1003 BOOL Track0Loaded = FALSE; // Assume track0 did not load correctly.
1004 BOOL AiRBOOTBad = FALSE;
1005 int rc = -1;
1006
1007
1008 /*
1009 // Rousseau: ## Changed order to first check for AiR-BOOT existance ##
1010 // If AiR-BOOT is not installed, all action is passed-thru to IBM SETBOOT (SETBM.EXE).
1011 */
1012
1013
1014 /*
1015 // Try to load track zero.
1016 // We don't care if no harddisk is present, since we first want to know if AiR-BOOT is
1017 // installed to adjust our behaviour.
1018 // If it's not installed, or a loading error occurs, all actions will be deferred to
1019 // IBM SETBOOT (SETBM.EXE).
1020 // This means we also let IBM SETBOOT handle the situation in which no HD's are present.
1021 */
1022 Track0Loaded = Track0Load();
1023
1024 /*
1025 // Now see if AiR-BOOT is present.
1026 // If there was a loading error, no AiR-BOOT signature will be present, so
1027 // we pass-thru to IBM SETBOOT.
1028 */
1029 AiRBOOTDetected = Track0DetectAirBoot(&AiRBOOTBad);
1030
1031 if (AiRBOOTDetected) {
1032 rc = DoAirBootActions(argc, argv, AiRBOOTDetected, AiRBOOTBad);
1033 }
1034 else {
1035 rc = DoClassicActions(argc, argv);
1036 }
1037
1038
1039 return rc;
1040 }
Note: See TracBrowser for help on using the repository browser.