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

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

Preparing for v1.1.0 [2013-04-05]

During v1.0.8 it was decided that odd minor numbers will be
test-versions. Since v1.0.8 was actually a test-version with several
test-releases but with an even minor number, it was decided to bump the
final release to v1.1.0.

Thus, v1.1.1 will be the next test-version after the upcoming official
v1.1.0 release. When such test-versions are published, for instance to
get feedback, or solve a particular issue, the build-date and BLDLEVEL
information will identify such a test-release. This information can be
viewed by pressing the TAB-key while the Main Menu is displayed. Such
test-releases will also have a slightly different visual appearance to
distinguish them from official releases.

Because all test-versions between official releases identify themselves
with the same version number, upgrading from one test-release to another
requires the /forcecode option on the Installer.

Following this scheme, v1.1.2 will be the next official release after
the upcoming v1.1.0 release.

It is possible however, that major changes break compatibility with
previous releases, in which case the middle number will be incremented
to reflect this.

Note that this commit still identifies as v1.0.8.

Changes

o Bumped version information to v1.1.0
o Updated version dependent code in the Installers and SETABOOT.EXE

File size: 34.5 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 v"
481 BLDLVL_MAJOR_VERSION"."
482 BLDLVL_MIDDLE_VERSION"."
483 BLDLVL_MINOR_VERSION" - AiR-BOOT Configuration Utility - (c) 2004-"
484 BLDLVL_YEAR
485 " by M. Kiewitz");
486
487
488 //return 0;
489
490 /*
491 // Rousseau:
492 // Log some debug stuff to (virtual) flop.
493 */
494 /*
495 {
496 char buf[512]="\0";
497 FILE* fp = NULL;
498 int i = 0;
499
500 fp = fopen("A:\\SETBOOT.TXT", "a");
501 sprintf(buf, "Bliep");
502 fprintf(fp,"Program: %s\n", argv[0]);
503 fprintf(fp,"Arguments: %d\n", argc);
504 for (i=0; i<argc-1; i++) {
505 fprintf(fp, "Arg %d: %s\n", i+1, argv[i+1]);
506 }
507 fprintf(fp, "\n");
508 fclose(fp);
509 }
510 */
511
512
513
514 /*
515 // Rousseau: ## Enable boot-through when installing new system ##
516 // In the install-environment, the MEMDRIVE env-var is defined.
517 // This modifies the behavior after phase 1.
518 */
519 if (getenv("MEMDRIVE")) {
520 printf("CDBoot Environment.\n");
521 CDBoot = TRUE;
522 }
523
524
525 if (argc==1) {
526 MSG_Print (TXT_SYNTAX_Show);
527 return 1;
528 }
529
530
531
532
533 // Now we check for AiR-BOOT existance...
534 /*
535 if (CountHarddrives()>0) {
536 if (Track0Load()) {
537 // Rousseau: Track0DetectAirBoot() will init globals.
538 if (Track0DetectAirBoot()) // REPLACE WITH BOOL
539 AiRBOOTDetected = TRUE;
540 }
541 else {
542 MSG_Print (TXT_ERROR_DuringAccessHDD);
543 }
544 }
545 else {
546 MSG_Print (TXT_ERROR_DuringAccessHDD);
547 }
548 */
549
550 CurArgument = 1;
551 while (CurArgument<argc) {
552 StartPos = argv[CurArgument];
553 ArgumentLen = strlen(StartPos);
554
555 if ((*StartPos=='/') && (ArgumentLen>1)) {
556 StartPos++; ArgumentLen--;
557 CurChar = toupper(*StartPos++);
558
559 switch (CurChar) {
560 case '?':
561 MSG_Print (TXT_SYNTAX_Show);
562 return 1;
563 case 'B':
564 if (ArgumentLen==1) DoReboot = TRUE;
565 else BadParm = TRUE;
566 break;
567 case 'Q':
568 if (ArgumentLen==1) DoQuery = TRUE;
569 else BadParm = TRUE;
570 break;
571 case 'T':
572 DoSetTimer = TRUE;
573 if ((ArgumentLen>2) && (*StartPos==':')) {
574 *StartPos = 0; StartPos++;
575 CurPos = StartPos;
576 while (*CurPos!=0) {
577 if ((*CurPos<'0') || (*CurPos>'9')) {
578 BadValue = TRUE;
579 break;
580 }
581 CurPos++;
582 }
583 if (!BadValue) {
584 SetTimerValue = atoi(StartPos);
585 if ((SetTimerValue<0) || (SetTimerValue>255))
586 BadValue = TRUE;
587 } else {
588 if ((ArgumentLen==4) && (toupper(*CurPos)=='N') && (toupper(*(CurPos+1))=='O')) {
589 BadValue = FALSE;
590 SetTimerValue = -1; // Disable Timer
591 }
592 }
593 } else BadParm = TRUE;
594 break;
595 case 'M':
596 DoSetBootMenu = TRUE;
597 if ((ArgumentLen>2) && (*StartPos==':')) {
598 *StartPos = 0; StartPos++;
599 CurChar = toupper(*StartPos);
600 switch (CurChar) {
601 case 'N':
602 BootMenuDetailed = FALSE;
603 break;
604 case 'A':
605 BootMenuDetailed = TRUE;
606 break;
607 default:
608 BadValue = TRUE;
609 break;
610 }
611 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x91)) {
612 puts ("SETABOOT: AiR-BOOT v0.91 required for this feature.");
613 BadValue = TRUE;
614 }
615 } else BadParm = TRUE;
616 break;
617 case 'I':
618 case '4':
619 DoDirectBoot = TRUE;
620 if (CurChar=='I') {
621 if ((ArgumentLen>4) && (ArgumentLen<16) && (toupper(*StartPos++)=='B') && (toupper(*StartPos++)=='A') && (*StartPos==':')) {
622 DoReboot = TRUE; // IBA: requires us to reboot
623 ArgumentLen -= 4;
624 } else {
625 BadParm = TRUE;
626 break;
627 }
628 } else {
629 if ((ArgumentLen>1) && (ArgumentLen<33) && (*StartPos==':')) {
630 ArgumentLen -= 2;
631 } else {
632 BadParm = TRUE;
633 break;
634 }
635 }
636
637 *StartPos = 0; StartPos++;
638
639 // Search that partition in IPT of AiR-BOOT...
640 if ((CurChar=='4') && (ArgumentLen==0)) {
641 // '4:' and no partition name means disable automatic boot
642 DoDirectBoot = FALSE;
643 DisableDirectBoot = TRUE;
644 break;
645 }
646 if (ArgumentLen>11)
647 ArgumentLen = 11;
648
649 if (!AiRBOOTDetected) {
650 MSG_Print (TXT_ERROR_NoBootManager);
651 return 1;
652 }
653
654
655 /*
656 // Rousseau:
657 // Insert label of newly installed system in AiR-BOOT configuration.
658 // Note that it is changed to uppercase because AiR-BOOT uses the FS-label when
659 // scanning partitions and LVM-info is not found. (Otherwise PART-label)
660 // The auto-boot flag is not set in this case as this is handled by the AiR-BOOT loader.
661 */
662 if (CDBoot) {
663 strncpy(AiRBOOT_Config->InstallVolume, _strupr(StartPos), ArgumentLen);
664 AiRBOOT_Config->InstallVolume[ArgumentLen] = '\0';
665 printf("Writing Install Volume: %s to AiR-BOOT configuration.\n", AiRBOOT_Config->InstallVolume);
666 Track0WriteAiRBOOTConfig();
667 return 0;
668 }
669
670
671
672
673 BadValue = TRUE;
674 CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
675 while (CurPartitionNo<AiRBOOT_Config->Partitions) {
676 /*
677 // Rousseau: Changed below to case-insensitive compare.
678 // This solves the part/vol-label (mixed-case) v.s. fs-label (upper-case) issue.
679 */
680 /*if (strncmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {*/
681 if (strnicmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {
682 if (ArgumentLen==11) {
683 BadValue = FALSE;
684 break;
685 } else {
686 CurPos = CurIPTEntry->PartitionName+ArgumentLen;
687 EndPos = CurIPTEntry->PartitionName+11;
688 while ((CurPos<EndPos) && ((*CurPos==0x00) || (*CurPos==0x20)))
689 CurPos++;
690 if (CurPos==EndPos) {
691 BadValue = FALSE;
692 break;
693 }
694 }
695 }
696 CurPartitionNo++; CurIPTEntry++;
697 }
698
699
700 if (BadValue) {
701 puts ("SETABOOT: Partition not found in IPT.");
702 } else {
703 if (CurIPTEntry->Flags & AiRBOOTIPENTRY_Flags_BootAble) {
704 DirectBootPart = CurPartitionNo;
705 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
706 puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
707 BadValue = TRUE;
708 } else if ((AiRBOOT_Config->PasswordedSystem) || (AiRBOOT_Config->PasswordedChangeBoot)) {
709 puts ("SETABOOT: This feature needs password protection to be off.");
710 BadValue = TRUE;
711 }
712 } else {
713 BadValue = TRUE;
714 puts ("SETABOOT: Partition not set bootable.");
715 }
716 }
717 break;
718 case 'X':
719 if ((ArgumentLen==3) && (toupper(*StartPos++)=='W') && (toupper(*StartPos++)=='P')) {
720 if (!AiRBOOTDetected) {
721 MSG_Print (TXT_ERROR_NoBootManager);
722 return 1;
723 }
724 if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
725 puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
726 BadValue = TRUE;
727 } else DoXWPSupport = TRUE;
728 break;
729 }
730 case 'N':
731 puts ("SETABOOT: No support for this option.");
732 default:
733 BadParm = TRUE;
734 }
735 } else BadParm = TRUE;
736
737 if (BadParm) {
738 MSG_SetInsertViaPSZ (1, argv[CurArgument]);
739 MSG_Print (TXT_ERROR_BadParameter);
740 return 1;
741 }
742 if (BadValue) {
743 MSG_SetInsertViaPSZ (1, StartPos);
744 MSG_SetInsertViaPSZ (2, argv[CurArgument]);
745 MSG_Print (TXT_ERROR_BadValueFor);
746 return 1;
747 }
748
749 CurArgument++;
750 }
751
752 if (DoXWPSupport) {
753 if ((!PrfQueryProfileSize(HINI_USERPROFILE, "XWorkplace", "XShutdown", &XWPStringSize))) {
754 puts ("SETABOOT: /XWP needs XWorkPlace.");
755 return 1;
756 }
757 // First, get the current string...
758 CurPos = XWPOrgStringPtr = malloc(65536);
759 WriteLeft = XWPStringSize = 65536;
760 if (!PrfQueryProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, &XWPStringSize))
761 XWPStringSize = 0;
762 EndPos = CurPos+XWPStringSize;
763
764 CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
765 while (CurPartitionNo<AiRBOOT_Config->Partitions) {
766 if (CurIPTEntry->Flags & AiRBOOTIPENTRY_Flags_BootAble) {
767 strncpy (XWPBootName[XWPBootCount], CurIPTEntry->PartitionName, 11);
768 XWPBootName[XWPBootCount][11] = 0;
769 sprintf (XWPBootCommand[XWPBootCount], "setaboot /IBA:\"%s\"", XWPBootName[XWPBootCount]);
770 XWPBootCount++;
771 }
772 CurPartitionNo++; CurIPTEntry++;
773 }
774
775 while ((CurPos<EndPos) && (*CurPos!=0)) {
776 StartPos = CurPos; TmpLength = strlen(CurPos)+1;
777 CurPos += TmpLength; TmpLength2 = strlen(CurPos)+1;
778
779 XWPEntryFound = FALSE;
780 for (CurPartitionNo=0; CurPartitionNo<XWPBootCount; CurPartitionNo++) {
781 if ((strcmp(StartPos, XWPBootName[CurPartitionNo])==0) && (strcmp(CurPos, XWPBootCommand[CurPartitionNo])==0))
782 XWPBootCommand[CurPartitionNo][0] = 0;
783 }
784 CurPos += TmpLength2;
785 WriteLeft -= TmpLength+TmpLength2;
786 }
787
788 for (CurPartitionNo=0; CurPartitionNo<XWPBootCount; CurPartitionNo++) {
789 if (XWPBootCommand[CurPartitionNo][0]!=0) {
790 if (WriteLeft>11+27) {
791 TmpLength = strlen(XWPBootName[CurPartitionNo])+1;
792 TmpLength2 = strlen(XWPBootCommand[CurPartitionNo])+1;
793 strcpy (CurPos, XWPBootName[CurPartitionNo]);
794 CurPos += TmpLength;
795 strcpy (CurPos, XWPBootCommand[CurPartitionNo]);
796 CurPos += TmpLength2;
797 WriteLeft += TmpLength+TmpLength2;
798 }
799 }
800 }
801 *CurPos = 0; CurPos++;
802 XWPStringSize = CurPos-XWPOrgStringPtr;
803
804 PrfWriteProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, XWPStringSize);
805 free(XWPOrgStringPtr);
806
807 puts ("SETABOOT: XWorkPlace updated.");
808 return 0;
809 }
810 if (DoQuery) {
811 if (!AiRBOOTDetected) {
812 MSG_Print (TXT_ERROR_NoBootManager);
813 return 1;
814 }
815 printf("SETABOOT: AiR-BOOT %X.%02X detected.\n\n", AiRBOOT_CodeSig->MajorVersion, AiRBOOT_CodeSig->MinorVersion);
816 //printf("DEBUG: InstallVolume: %s\n", AiRBOOT_Config->InstallVolume);
817 if (AiRBOOT_Config->BootMenuActive) {
818 if (AiRBOOT_Config->TimedBoot) {
819 itoa (AiRBOOT_Config->TimedSeconds, (PCHAR)&TempBuffer, 10);
820 MSG_SetInsertViaPSZ (1, TempBuffer);
821 MSG_Print (TXT_QUERY_TimeLimit_Show);
822 } else {
823 MSG_Print (TXT_QUERY_TimeLimit_None);
824 }
825 if (AiRBOOT_Config->BootMenuActive>1)
826 MSG_Print (TXT_QUERY_Mode_Extended);
827 else
828 MSG_Print (TXT_QUERY_Mode_Normal);
829 } else {
830 MSG_SetInsertViaPSZ (1, "0");
831 MSG_Print (TXT_QUERY_TimeLimit_Show);
832 MSG_Print (TXT_QUERY_Mode_Normal);
833 }
834 return 0;
835 }
836 if (DoSetTimer) {
837 if (!AiRBOOTDetected) {
838 MSG_Print (TXT_ERROR_NoBootManager);
839 return 1;
840 }
841 // Set Timer to "SetTimerValue" (1-255 -> seconds, -1 -> disable)
842 // 0 is a special case, which will disable the BootMenu
843 if (SetTimerValue==0) {
844 // 0 is a special case, that will disable the bootmenu
845 AiRBOOT_Config->BootMenuActive = 0; // Switches off Boot-Menu
846 } else if (SetTimerValue==-1) {
847 // -1 will disable Timed-Boot
848 if (AiRBOOT_Config->BootMenuActive==0)
849 AiRBOOT_Config->BootMenuActive = 1;
850 AiRBOOT_Config->TimedBoot = 0; // Switches off Timed-Boot
851 } else {
852 if (AiRBOOT_Config->BootMenuActive==0)
853 AiRBOOT_Config->BootMenuActive = 1;
854 AiRBOOT_Config->TimedBoot = 1; // Switches on Timed-Boot
855 AiRBOOT_Config->TimedSeconds = SetTimerValue;
856 }
857 AiRBOOTChanged = TRUE;
858 }
859 if (DoSetBootMenu) {
860 if (!AiRBOOTDetected) {
861 MSG_Print (TXT_ERROR_NoBootManager);
862 return 1;
863 }
864 // Sets type of Boot-menu
865 // Switches BootMenu between Enabled and Detailed state...
866 if (BootMenuDetailed)
867 AiRBOOT_Config->BootMenuActive = 2; // Switch to Detailed mode
868 else
869 AiRBOOT_Config->BootMenuActive = 1; // Switch to Enabled (Normal)
870 AiRBOOTChanged = TRUE;
871 }
872 if (DoDirectBoot) {
873 if (!AiRBOOTDetected) {
874 MSG_Print (TXT_ERROR_NoBootManager);
875 return 1;
876 }
877 // Sets Automatic-Booting to "DirectBootPart" (IPT-Entry)
878 AiRBOOT_Config->AutomaticBoot = 1; // Switches on Automatic-Boot
879 AiRBOOT_Config->AutomaticPartition = DirectBootPart;
880 AiRBOOTChanged = TRUE;
881 puts ("SETABOOT: Automatic boot enabled.");
882 }
883 if (DisableDirectBoot) {
884 if (!AiRBOOTDetected) {
885 MSG_Print (TXT_ERROR_NoBootManager);
886 return 1;
887 }
888 AiRBOOT_Config->AutomaticBoot = 0; // Switches off Automatic-Boot
889 AiRBOOT_Config->AutomaticPartition = 0;
890 AiRBOOTChanged = TRUE;
891 puts ("SETABOOT: Automatic boot disabled.");
892 }
893 if (AiRBOOTChanged) {
894 if (!Track0WriteAiRBOOTConfig())
895 return 1;
896 }
897 if (DoReboot) {
898 puts ("SETABOOT: Now rebooting system...");
899 RebootSystem();
900 }
901 return 0;
902
903
904
905}
906
907
908/*
909// Rousseau:
910// Global pointers will be initialized here !
911*/
912BOOL Track0DetectAirBoot (BOOL* ab_bad) {
913 USHORT ResultCheck;
914 USHORT CurSectorNo = 0;
915
916 /* Globals that get initialized */
917 AiRBOOT_CodeSig = (PAiRBOOTCODESIG)&Track0[2];
918 AiRBOOT_Config = (PAiRBOOTCONFIG)&Track0[(55-1)*512];
919 AiRBOOT_IPT = (PAiRBOOTIPENTRY)&Track0[(56-1)*512];
920
921 if (strncmp(AiRBOOT_CodeSig->Identifier, "AiRBOOT", 7)!=0) {
922 *ab_bad = FALSE;
923 return FALSE;
924 }
925
926 if ((AiRBOOT_CodeSig->TotalCodeSectors)>53) {
927 puts ("SETABOOT: AiR-BOOT Code damaged!");
928 *ab_bad = TRUE;
929 return TRUE;
930 }
931
932 ResultCheck = 0; CurSectorNo = 0;
933 while (CurSectorNo<AiRBOOT_CodeSig->TotalCodeSectors) {
934 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo+2);
935 CurSectorNo++;
936 }
937 if (ResultCheck!=AiRBOOT_CodeSig->CheckSumOfCode) {
938 puts ("SETABOOT: AiR-BOOT Code damaged!");
939 *ab_bad = TRUE;
940 return TRUE;
941 }
942
943 if (strncmp(AiRBOOT_Config->Identifier, "AiRCFG-TABLE­", 13)!=0) { // Rousseau: INVISIBLE CHAR HERE !
944 puts ("SETABOOT: AiR-BOOT Config damaged!");
945 *ab_bad = TRUE;
946 return TRUE;
947 }
948
949 // Set Config-CheckSum to 0
950 AiRBOOT_ConfigCheckSum = AiRBOOT_Config->CheckSumOfConfig;
951 AiRBOOT_Config->CheckSumOfConfig = 0;
952
953 // Calculate CheckSum...
954 // Rousseau: Only check 5 sectors for v1.07 compatibility.
955 ResultCheck = 0; CurSectorNo = 55;
956 while (CurSectorNo<60) {
957 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
958 CurSectorNo++;
959 }
960 if (ResultCheck!=AiRBOOT_ConfigCheckSum) {
961 puts ("SETABOOT: AiR-BOOT Config damaged!");
962 *ab_bad = TRUE;
963 return TRUE;
964 }
965 *ab_bad = FALSE;
966 return TRUE;
967 }
968
969BOOL Track0WriteAiRBOOTConfig (void) {
970 USHORT ResultCheck;
971 USHORT CurSectorNo = 0;
972
973 // Update Edit-Counter...
974 AiRBOOT_Config->EditCounter++;
975 AiRBOOT_Config->CheckSumOfConfig = 0;
976
977 // Calculate CheckSum...
978 ResultCheck = 0; CurSectorNo = 55;
979
980 /*
981 // Rousseau: # Keep compatible with v1.07 CRC #
982 // AB v1.07 had bugs in writing the wrong number of AB config sectors.
983 // This is fixed in v1.0.8+ but the CRC has to be calculated the "v1.07 way"
984 // otherwise v1.07 SET(A)BOOT and INSTALL2.EXE will think the AB config
985 // is corrupted.
986 // So the CRC is calculated over 5 sectors instead of 7.
987 */
988 while (CurSectorNo<60) {
989 ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
990 CurSectorNo++;
991 }
992 AiRBOOT_Config->CheckSumOfConfig = ResultCheck;
993
994 if (!Track0Write())
995 return FALSE;
996 return TRUE;
997 }
998
999
1000/*
1001// Rousseau: # This is the main entry-point #
1002// Special behavior if eCS is booted from CDROM and phase 1 called this program.
1003// In that case, the name of the newly installed system is put in the AiR-BOOT configuration.
1004// This will cause AiR-BOOT to boot through after phase 1.
1005*/
1006int main (int argc, char **argv) {
1007 BOOL AiRBOOTDetected = FALSE;
1008 BOOL Track0Loaded = FALSE; // Assume track0 did not load correctly.
1009 BOOL AiRBOOTBad = FALSE;
1010 int rc = -1;
1011
1012
1013 /*
1014 // Rousseau: ## Changed order to first check for AiR-BOOT existance ##
1015 // If AiR-BOOT is not installed, all action is passed-thru to IBM SETBOOT (SETBM.EXE).
1016 */
1017
1018
1019 /*
1020 // Try to load track zero.
1021 // We don't care if no harddisk is present, since we first want to know if AiR-BOOT is
1022 // installed to adjust our behaviour.
1023 // If it's not installed, or a loading error occurs, all actions will be deferred to
1024 // IBM SETBOOT (SETBM.EXE).
1025 // This means we also let IBM SETBOOT handle the situation in which no HD's are present.
1026 */
1027 Track0Loaded = Track0Load();
1028
1029 /*
1030 // Now see if AiR-BOOT is present.
1031 // If there was a loading error, no AiR-BOOT signature will be present, so
1032 // we pass-thru to IBM SETBOOT.
1033 */
1034 AiRBOOTDetected = Track0DetectAirBoot(&AiRBOOTBad);
1035
1036 if (AiRBOOTDetected) {
1037 rc = DoAirBootActions(argc, argv, AiRBOOTDetected, AiRBOOTBad);
1038 }
1039 else {
1040 rc = DoClassicActions(argc, argv);
1041 }
1042
1043
1044 return rc;
1045 }
Note: See TracBrowser for help on using the repository browser.