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

Last change on this file since 44 was 35, checked in by Ben Rietbroek, 13 years ago

Corrected CRC calculations in installers and setaboot [2012-01-21]

Fixes

o Corrected CRC calculations on AiR-BOOT configuration in the

installers and setaboot. They are now v1.07 compatible again.

Note

This commit and all following commits upto and including the RC3
commit [2012-09-09] are delayed commits from a local repository.
Also, the RC (Release Candidate) naming of the corresponding commits
is a bit misleading. One would label a revision with RC when near to
a final release. Since many things have changed between RC1,RC2 & RC3,
these RC's should be interpreted as mile-stones.

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 ABOVE COMMITS!!

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