source: trunk/tools/os2/setaboot/setaboot.c@ 67

Last change on this file since 67 was 67, checked in by Ben Rietbroek, 9 years ago

Replaced some 'eCS' references with generic 'OS/2' [v1.1.1-testing]

With the upcoming ArcaOS, see: https://www.arcanoae.com, eComStation
ain't the only game in OS/2-town anymore. So, some references have been
changed to the more generic term 'OS/2' to prevent misinterpretation.

CAUTION:
This is a testbuild !
AirBoot uses the BIOS to access disks and a small coding error can trash
partition tables or other vital disk structures. You are advised to make
backups of TRACK0 and EBRs before using this testbuild. More info at:
https://rousseaux.github.io/netlabs.air-boot/pdf/AirBoot-v1.1.0-manual.pdf

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 OS/2 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.