// AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz
//
// This file is part of AiR-BOOT
//
// AiR-BOOT is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// AiR-BOOT. If not, see .
//
/*
// Rousseau: 2011-02-05
// - Made volumes compare case insensitive so fs-label matches volume-name on command-line. (around line 510)
// This means bootable volumes cannot not have the same and only differ in case.
*/
#include "setaboot.h"
#define INCL_BASE
#define INCL_WINSHELLDATA
#define INCL_DOS
#define INCL_DOSDEVIOCTL
#include
#include
#include
#include
#include
#include
#include
#include "msghelp.c"
// Msg-IDs from OSO001.msg
#define TXT_QUERY_TimeLimit_None 860
#define TXT_QUERY_TimeLimit_Show 861
#define TXT_QUERY_Mode_Extended 863
#define TXT_QUERY_Mode_Normal 864
#define TXT_SYNTAX_Show 867
#define TXT_ERROR_DuringAccessHDD 868
#define TXT_ERROR_NoValueFor 870
#define TXT_ERROR_NeedsValueFor 871
#define TXT_ERROR_BadParameter 872
#define TXT_ERROR_BadValueFor 873
#define TXT_ERROR_NoBootManager 874
#pragma pack(1)
// This structure needs NOT to get optimized, otherwise it will screw up...
typedef struct _AiRBOOTCODESIG {
CHAR Identifier[7];
UCHAR DayOfRelease;
UCHAR MonthOfRelease;
USHORT YearOfRelease;
UCHAR MajorVersion;
UCHAR MinorVersion;
CHAR ReleaseLanguage;
UCHAR TotalCodeSectors;
USHORT CheckSumOfCode;
} AiRBOOTCODESIG;
typedef AiRBOOTCODESIG *PAiRBOOTCODESIG;
typedef struct _AiRBOOTCONFIG {
CHAR Identifier[13]; // Rousseau: INVISIBLE CHAR AT END !
UCHAR MajorVersion;
UCHAR MinorVersion;
CHAR ReleaseLanguage;
ULONG EditCounter;
USHORT CheckSumOfConfig;
UCHAR Partitions;
UCHAR Meaningless1;
UCHAR DefaultPartition;
UCHAR LastPartition;
UCHAR TimedBoot;
UCHAR TimedSeconds;
USHORT Meaningless2;
UCHAR TimedBootLast;
UCHAR RememberBoot;
UCHAR RememberTimed;
UCHAR IncludeFloppy;
UCHAR BootMenuActive;
UCHAR PartitionsDetect;
UCHAR PasswordedSetup;
UCHAR PasswordedSystem;
UCHAR PasswordedChangeBoot;
UCHAR ProtectMBRTSR;
UCHAR ProtectMBRignore;
UCHAR FloppyGetName;
UCHAR DetectVirus;
UCHAR DetectStealth;
UCHAR DetectVIBR;
UCHAR AutoEnterSetup;
UCHAR MasterPassword[8];
UCHAR BootPassword[8];
UCHAR Meaningless3;
UCHAR LinuxPartition;
UCHAR TimedKeyHandling;
UCHAR MakeSound;
UCHAR FloppyGetTimer;
UCHAR ResumeBIOSbootSeq;
UCHAR CooperBars;
CHAR LinuxCommandLine[75];
UCHAR LinuxKernelPartition;
CHAR LinuxDefaultKernel[11];
UCHAR LinuxKernelNameEnd;
CHAR LinuxLastKernel[11];
UCHAR LinuxKernelNameEnd2;
UCHAR ExtPartitionMShack;
UCHAR AutomaticBoot;
UCHAR AutomaticPartition;
UCHAR ForceLBAUsage;
UCHAR IgnoreLVM;
UCHAR Reserved[82];
CHAR InstallVolume[12];
} AiRBOOTCONFIG;
typedef AiRBOOTCONFIG *PAiRBOOTCONFIG;
typedef struct _AiRBOOTIPENTRY {
ULONG SerialNumber;
CHAR PartitionName[11];
UCHAR Drive;
UCHAR PartitionID;
UCHAR Flags;
USHORT CheckSum;
UCHAR LocationBegin[3];
UCHAR LocationPartTab[3];
ULONG AbsoluteBegin;
ULONG AbsolutePartTab;
} AiRBOOTIPENTRY;
typedef AiRBOOTIPENTRY *PAiRBOOTIPENTRY;
#pragma pack()
#define AiRBOOTIPENTRY_Flags_BootAble 0x01
CHAR Track0[62*512]; // Space for Track-0
PAiRBOOTCODESIG AiRBOOT_CodeSig = 0;
PAiRBOOTCONFIG AiRBOOT_Config = 0;
PAiRBOOTIPENTRY AiRBOOT_IPT = 0;
USHORT AiRBOOT_ConfigCheckSum = 0;
UCHAR AiRBOOT_IPTCount = 0;
/* Executables to search for */
PCHAR classic_setboots[] = {
"SETBM.EXE",
NULL
};
/*
// ProtoTypes.
*/
BOOL Track0DetectAirBoot (BOOL* ab_bad);
BOOL Track0WriteAiRBOOTConfig (void);
USHORT CountHarddrives (void) {
USHORT NumDrives = 0;
if (DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &NumDrives, sizeof(NumDrives),NULL, 0) != 0)
return 0;
return NumDrives;
}
USHORT OS2_GetIOCTLHandle () {
USHORT IOCTLHandle = 0;
if (DosPhysicalDisk(INFO_GETIOCTLHANDLE, &IOCTLHandle, sizeof(IOCTLHandle),"1:" , 3) != 0)
return 0;
return IOCTLHandle;
}
void OS2_FreeIOCTLHandle (USHORT IOCTLHandle) {
DosPhysicalDisk(INFO_FREEIOCTLHANDLE, NULL, 0, &IOCTLHandle, sizeof(IOCTLHandle));
return;
}
BOOL Track0Load (void) {
USHORT IOCTLHandle;
ULONG TrackLayoutLen = sizeof(TRACKLAYOUT)+sizeof(ULONG)*(62-1);
TRACKLAYOUT *TrackLayoutPtr = malloc(TrackLayoutLen);
ULONG cbParms = sizeof(TrackLayoutPtr);
ULONG cbData = 512;
int i;
BOOL Success = FALSE;
IOCTLHandle = OS2_GetIOCTLHandle();
TrackLayoutPtr->bCommand = 0x01;
TrackLayoutPtr->usHead = 0;
TrackLayoutPtr->usCylinder = 0;
TrackLayoutPtr->usFirstSector = 0;
TrackLayoutPtr->cSectors = 62;
for (i=0; i<62; i++) {
TrackLayoutPtr->TrackTable[i].usSectorNumber = i+1;
TrackLayoutPtr->TrackTable[i].usSectorSize = 512;
}
if (!DosDevIOCtl(IOCTLHandle, IOCTL_PHYSICALDISK, PDSK_READPHYSTRACK,
TrackLayoutPtr, cbParms, &cbParms, &Track0, cbData, &cbData))
Success = TRUE;
OS2_FreeIOCTLHandle (IOCTLHandle);
free (TrackLayoutPtr);
return Success;
}
BOOL Track0Write (void) {
USHORT IOCTLHandle;
ULONG TrackLayoutLen = sizeof(TRACKLAYOUT)+sizeof(ULONG)*(62-1);
TRACKLAYOUT *TrackLayoutPtr = malloc(TrackLayoutLen);
ULONG cbParms = sizeof(TrackLayoutPtr);
ULONG cbData = 512;
INT i;
BOOL Success = FALSE;
IOCTLHandle = OS2_GetIOCTLHandle();
TrackLayoutPtr->bCommand = 0x01;
TrackLayoutPtr->usHead = 0;
TrackLayoutPtr->usCylinder = 0;
TrackLayoutPtr->usFirstSector = 0;
TrackLayoutPtr->cSectors = 62;
for (i=0; i<62; i++) {
TrackLayoutPtr->TrackTable[i].usSectorNumber = i+1;
TrackLayoutPtr->TrackTable[i].usSectorSize = 512;
}
if (!DosDevIOCtl(IOCTLHandle, IOCTL_PHYSICALDISK, PDSK_WRITEPHYSTRACK,
TrackLayoutPtr, cbParms, &cbParms, &Track0, cbData, &cbData))
Success = TRUE;
OS2_FreeIOCTLHandle (IOCTLHandle);
free (TrackLayoutPtr);
return Success;
}
#define CATEGORY_DOSSYS 0xD5
#define FUNCTION_REBOOT 0xAB
void RebootSystem (void) {
HFILE DosHandle;
ULONG DosOpenAction;
DosSleep (2000);
if (!DosOpen("DOS$", &DosHandle, &DosOpenAction, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE, NULL)) {
DosDevIOCtl(DosHandle, CATEGORY_DOSSYS, FUNCTION_REBOOT, NULL, 0, NULL, NULL, 0, NULL);
DosSleep (60000);
}
DosClose(DosHandle);
}
APIRET QueryBootDrive(char *bootdrv)
{
ULONG aulSysInfo[QSV_MAX] = {0}; // System Information Data Buffer
APIRET rc = NO_ERROR; // Return code
if(bootdrv==0) return 1;
rc = DosQuerySysInfo(1L, // Request all available system
QSV_MAX , // information
(PVOID)aulSysInfo, // Pointer to buffer
sizeof(ULONG)*QSV_MAX); // Size of the buffer
if (rc != NO_ERROR) {
return 1;
}
else {
//printf("Bootable drive: %c:\n",
// aulSysInfo[QSV_BOOT_DRIVE-1]+'A'-1); /* Max length of path name */
bootdrv[0]=aulSysInfo[QSV_BOOT_DRIVE-1]+'A'-1;
/*
printf("Total physical memory is %u bytes.\n",
aulSysInfo[QSV_TOTPHYSMEM-1]);
*/
return 0;
}
}
USHORT GetChecksumOfSector (USHORT BaseCheck, USHORT SectorNo) {
PUSHORT CurPos = (PUSHORT)((ULONG)&Track0+(SectorNo-1)*512);
USHORT LengthLeft = 256;
while (LengthLeft-->0)
BaseCheck ^= (*CurPos++ ^ 0x0BABE);
if (BaseCheck==0) BaseCheck = 1;
return BaseCheck;
}
/*
// If AiR-BOOT is not installed, the user probably meant to control OS/2 BM with this utility.
// Since the functionality of this utility is for AiR-BOOT only, we will pass the request to
// the OS/2 BM SETBOOT utility which is called SETBM.EXE as of eCS 2.1.
// In this case also the return-value of SETBM.EXE is returned.
*/
int DoClassicActions(int argc, char **argv) {
APIRET rc = -1;
RESULTCODES crc = {-1,-1};
// PTIB ptib = NULL;
// PPIB ppib = NULL;
char buffer[256] = "\0";
char cmdline[256] = "\0";
PSZ path = NULL;
char sresult[256] = "\0";
char bootdrive = '?';
char* p = NULL;
int i = 0;
//printf("\nCLASSIC ACTIONS !! (%d)\n", argc);
rc = QueryBootDrive(&bootdrive);
rc = DosScanEnv("PATH", &path);
rc = DosSearchPath(SEARCH_CUR_DIRECTORY | SEARCH_IGNORENETERRS,
path,
classic_setboots[0],
sresult,
sizeof(sresult));
//printf("SRESULT: rc=%d, %s\n", rc, sresult);
if (rc) {
printf("\n");
printf("ERROR: SETBOOT (AiR-BOOT version)\n");
printf("Since the AiR-BOOT Boot Manager is not installed,\n");
printf("this program (SETBOOT.EXE), funcions as a wrapper\n");
printf("to %s that should be used to control IBM Boot Manager.\n", classic_setboots[0]);
printf("However, %s could not be found in the PATH, the error-code is: %d\n", classic_setboots[0], rc);
printf("You can resolve this situation by renaming a valid SETBOOT.EXE to %s\n", classic_setboots[0]);
printf("and put it in your %c:\\OS2 directory.", bootdrive);
printf("\n");
exit(rc);
}
memset(cmdline, 0, sizeof(cmdline)); // Clear the command-line buffer.
p = cmdline; // Temporary pointer to insert arguments.
strcpy(p, sresult); // Copy the program-name.
p += strlen(sresult)+1; // Advance to point for space separated parameters.
/*
// Process all the arguments,
// inserting the separated by a space.
*/
for (i=1; ipib_hmte, sizeof(buffer), buffer);
printf("MODULE: %s\n", buffer);
printf("CMDLINE: %s\n", ppib->pib_pchcmd);
*/
return crc.codeResult;
}
/*
// This funtion is invoked when AiR-BOOT is installed.
// It mimics the behavior of the original SETBOOT.EXE utility,
// but operates on AiR-BOOT.
*/
int DoAirBootActions(int argc, char **argv, BOOL ab_detected, BOOL ab_bad) {
ULONG CurArgument = 0;
ULONG ArgumentLen = 0;
PCHAR StartPos = 0;
PCHAR EndPos = 0;
PCHAR CurPos = 0;
CHAR CurChar = 0;
BOOL DoXWPSupport = FALSE;
BOOL DoQuery = FALSE;
BOOL DoSetTimer = FALSE;
SHORT SetTimerValue = 0;
BOOL DoSetBootMenu = FALSE;
BOOL BootMenuDetailed = FALSE;
BOOL DoDirectBoot = FALSE;
BOOL DisableDirectBoot= FALSE;
UCHAR DirectBootPart = 0;
BOOL DoReboot = FALSE;
BOOL AiRBOOTDetected = FALSE;
BOOL AiRBOOTChanged = FALSE;
BOOL BadParm = FALSE;
BOOL BadValue = FALSE;
UCHAR CurPartitionNo = 0;
PAiRBOOTIPENTRY CurIPTEntry = 0;
CHAR TempBuffer[10];
ULONG XWPStringSize = 0;
PCHAR XWPOrgStringPtr = 0;
ULONG WriteLeft = 0;
ULONG TmpLength = 0;
ULONG TmpLength2 = 0;
ULONG XWPBootCount = 0;
CHAR XWPBootName[30][12];
CHAR XWPBootCommand[30][28]; // 'setaboot /IBA:""' (16 chars)
BOOL XWPEntryFound = FALSE;
BOOL CDBoot = FALSE; // TRUE if booted from CD; New System will be added when using /4:"LABEL"
// BOOL Track0Loaded = FALSE; // Assume track0 did not load correctly.
BOOL AiRBOOTBad = FALSE;
//printf("\nAiR-BOOT ACTIONS !!\n");
AiRBOOTDetected = ab_detected;
AiRBOOTBad = ab_bad;
if (AiRBOOTBad)
return 1;
// Use OSO001.MSG, so we safe us the trouble of translating :)
if (!MSG_Init("OSO001.MSG"))
return 1;
/*
// Rousseau: changed version to be the same as the AiR-BOOT is accompanies.
*/
//puts ("SETABOOT - AiR-BOOT Configuration Utility (OS/2) - (c) 2004-2009 by M. Kiewitz");
//puts ("SETABOOT v1.07a - AiR-BOOT Configuration Utility - (c) 2004-2011 by M. Kiewitz");
puts ("SETABOOT v"
BLDLVL_MAJOR_VERSION"."
BLDLVL_MIDDLE_VERSION"."
BLDLVL_MINOR_VERSION" - AiR-BOOT Configuration Utility - (c) 2004-"
BLDLVL_YEAR
" by M. Kiewitz");
//return 0;
/*
// Rousseau:
// Log some debug stuff to (virtual) flop.
*/
/*
{
char buf[512]="\0";
FILE* fp = NULL;
int i = 0;
fp = fopen("A:\\SETBOOT.TXT", "a");
sprintf(buf, "Bliep");
fprintf(fp,"Program: %s\n", argv[0]);
fprintf(fp,"Arguments: %d\n", argc);
for (i=0; i0) {
if (Track0Load()) {
// Rousseau: Track0DetectAirBoot() will init globals.
if (Track0DetectAirBoot()) // REPLACE WITH BOOL
AiRBOOTDetected = TRUE;
}
else {
MSG_Print (TXT_ERROR_DuringAccessHDD);
}
}
else {
MSG_Print (TXT_ERROR_DuringAccessHDD);
}
*/
CurArgument = 1;
while (CurArgument1)) {
StartPos++; ArgumentLen--;
CurChar = toupper(*StartPos++);
switch (CurChar) {
case '?':
MSG_Print (TXT_SYNTAX_Show);
return 1;
case 'B':
if (ArgumentLen==1) DoReboot = TRUE;
else BadParm = TRUE;
break;
case 'Q':
if (ArgumentLen==1) DoQuery = TRUE;
else BadParm = TRUE;
break;
case 'T':
DoSetTimer = TRUE;
if ((ArgumentLen>2) && (*StartPos==':')) {
*StartPos = 0; StartPos++;
CurPos = StartPos;
while (*CurPos!=0) {
if ((*CurPos<'0') || (*CurPos>'9')) {
BadValue = TRUE;
break;
}
CurPos++;
}
if (!BadValue) {
SetTimerValue = atoi(StartPos);
if ((SetTimerValue<0) || (SetTimerValue>255))
BadValue = TRUE;
} else {
if ((ArgumentLen==4) && (toupper(*CurPos)=='N') && (toupper(*(CurPos+1))=='O')) {
BadValue = FALSE;
SetTimerValue = -1; // Disable Timer
}
}
} else BadParm = TRUE;
break;
case 'M':
DoSetBootMenu = TRUE;
if ((ArgumentLen>2) && (*StartPos==':')) {
*StartPos = 0; StartPos++;
CurChar = toupper(*StartPos);
switch (CurChar) {
case 'N':
BootMenuDetailed = FALSE;
break;
case 'A':
BootMenuDetailed = TRUE;
break;
default:
BadValue = TRUE;
break;
}
if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x91)) {
puts ("SETABOOT: AiR-BOOT v0.91 required for this feature.");
BadValue = TRUE;
}
} else BadParm = TRUE;
break;
case 'I':
case '4':
DoDirectBoot = TRUE;
if (CurChar=='I') {
if ((ArgumentLen>4) && (ArgumentLen<16) && (toupper(*StartPos++)=='B') && (toupper(*StartPos++)=='A') && (*StartPos==':')) {
DoReboot = TRUE; // IBA: requires us to reboot
ArgumentLen -= 4;
} else {
BadParm = TRUE;
break;
}
} else {
if ((ArgumentLen>1) && (ArgumentLen<33) && (*StartPos==':')) {
ArgumentLen -= 2;
} else {
BadParm = TRUE;
break;
}
}
*StartPos = 0; StartPos++;
// Search that partition in IPT of AiR-BOOT...
if ((CurChar=='4') && (ArgumentLen==0)) {
// '4:' and no partition name means disable automatic boot
DoDirectBoot = FALSE;
DisableDirectBoot = TRUE;
break;
}
if (ArgumentLen>11)
ArgumentLen = 11;
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
/*
// Rousseau:
// Insert label of newly installed system in AiR-BOOT configuration.
// Note that it is changed to uppercase because AiR-BOOT uses the FS-label when
// scanning partitions and LVM-info is not found. (Otherwise PART-label)
// The auto-boot flag is not set in this case as this is handled by the AiR-BOOT loader.
*/
if (CDBoot) {
strncpy(AiRBOOT_Config->InstallVolume, _strupr(StartPos), ArgumentLen);
AiRBOOT_Config->InstallVolume[ArgumentLen] = '\0';
printf("Writing Install Volume: %s to AiR-BOOT configuration.\n", AiRBOOT_Config->InstallVolume);
Track0WriteAiRBOOTConfig();
return 0;
}
BadValue = TRUE;
CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
while (CurPartitionNoPartitions) {
/*
// Rousseau: Changed below to case-insensitive compare.
// This solves the part/vol-label (mixed-case) v.s. fs-label (upper-case) issue.
*/
/*if (strncmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {*/
if (strnicmp(CurIPTEntry->PartitionName, StartPos, ArgumentLen)==0) {
if (ArgumentLen==11) {
BadValue = FALSE;
break;
} else {
CurPos = CurIPTEntry->PartitionName+ArgumentLen;
EndPos = CurIPTEntry->PartitionName+11;
while ((CurPosFlags & AiRBOOTIPENTRY_Flags_BootAble) {
DirectBootPart = CurPartitionNo;
if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
BadValue = TRUE;
} else if ((AiRBOOT_Config->PasswordedSystem) || (AiRBOOT_Config->PasswordedChangeBoot)) {
puts ("SETABOOT: This feature needs password protection to be off.");
BadValue = TRUE;
}
} else {
BadValue = TRUE;
puts ("SETABOOT: Partition not set bootable.");
}
}
break;
case 'X':
if ((ArgumentLen==3) && (toupper(*StartPos++)=='W') && (toupper(*StartPos++)=='P')) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
if ((AiRBOOT_CodeSig->MajorVersion==0x00) && (AiRBOOT_CodeSig->MinorVersion<0x94)) {
puts ("SETABOOT: AiR-BOOT v0.94 required for this feature.");
BadValue = TRUE;
} else DoXWPSupport = TRUE;
break;
}
case 'N':
puts ("SETABOOT: No support for this option.");
default:
BadParm = TRUE;
}
} else BadParm = TRUE;
if (BadParm) {
MSG_SetInsertViaPSZ (1, argv[CurArgument]);
MSG_Print (TXT_ERROR_BadParameter);
return 1;
}
if (BadValue) {
MSG_SetInsertViaPSZ (1, StartPos);
MSG_SetInsertViaPSZ (2, argv[CurArgument]);
MSG_Print (TXT_ERROR_BadValueFor);
return 1;
}
CurArgument++;
}
if (DoXWPSupport) {
if ((!PrfQueryProfileSize(HINI_USERPROFILE, "XWorkplace", "XShutdown", &XWPStringSize))) {
puts ("SETABOOT: /XWP needs XWorkPlace.");
return 1;
}
// First, get the current string...
CurPos = XWPOrgStringPtr = malloc(65536);
WriteLeft = XWPStringSize = 65536;
if (!PrfQueryProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, &XWPStringSize))
XWPStringSize = 0;
EndPos = CurPos+XWPStringSize;
CurPartitionNo = 0; CurIPTEntry = AiRBOOT_IPT;
while (CurPartitionNoPartitions) {
if (CurIPTEntry->Flags & AiRBOOTIPENTRY_Flags_BootAble) {
strncpy (XWPBootName[XWPBootCount], CurIPTEntry->PartitionName, 11);
XWPBootName[XWPBootCount][11] = 0;
sprintf (XWPBootCommand[XWPBootCount], "setaboot /IBA:\"%s\"", XWPBootName[XWPBootCount]);
XWPBootCount++;
}
CurPartitionNo++; CurIPTEntry++;
}
while ((CurPos11+27) {
TmpLength = strlen(XWPBootName[CurPartitionNo])+1;
TmpLength2 = strlen(XWPBootCommand[CurPartitionNo])+1;
strcpy (CurPos, XWPBootName[CurPartitionNo]);
CurPos += TmpLength;
strcpy (CurPos, XWPBootCommand[CurPartitionNo]);
CurPos += TmpLength2;
WriteLeft += TmpLength+TmpLength2;
}
}
}
*CurPos = 0; CurPos++;
XWPStringSize = CurPos-XWPOrgStringPtr;
PrfWriteProfileData (HINI_USERPROFILE, "XWorkplace", "RebootTo", XWPOrgStringPtr, XWPStringSize);
free(XWPOrgStringPtr);
puts ("SETABOOT: XWorkPlace updated.");
return 0;
}
if (DoQuery) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
printf("SETABOOT: AiR-BOOT %X.%02X detected.\n\n", AiRBOOT_CodeSig->MajorVersion, AiRBOOT_CodeSig->MinorVersion);
//printf("DEBUG: InstallVolume: %s\n", AiRBOOT_Config->InstallVolume);
if (AiRBOOT_Config->BootMenuActive) {
if (AiRBOOT_Config->TimedBoot) {
itoa (AiRBOOT_Config->TimedSeconds, (PCHAR)&TempBuffer, 10);
MSG_SetInsertViaPSZ (1, TempBuffer);
MSG_Print (TXT_QUERY_TimeLimit_Show);
} else {
MSG_Print (TXT_QUERY_TimeLimit_None);
}
if (AiRBOOT_Config->BootMenuActive>1)
MSG_Print (TXT_QUERY_Mode_Extended);
else
MSG_Print (TXT_QUERY_Mode_Normal);
} else {
MSG_SetInsertViaPSZ (1, "0");
MSG_Print (TXT_QUERY_TimeLimit_Show);
MSG_Print (TXT_QUERY_Mode_Normal);
}
return 0;
}
if (DoSetTimer) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
// Set Timer to "SetTimerValue" (1-255 -> seconds, -1 -> disable)
// 0 is a special case, which will disable the BootMenu
if (SetTimerValue==0) {
// 0 is a special case, that will disable the bootmenu
AiRBOOT_Config->BootMenuActive = 0; // Switches off Boot-Menu
} else if (SetTimerValue==-1) {
// -1 will disable Timed-Boot
if (AiRBOOT_Config->BootMenuActive==0)
AiRBOOT_Config->BootMenuActive = 1;
AiRBOOT_Config->TimedBoot = 0; // Switches off Timed-Boot
} else {
if (AiRBOOT_Config->BootMenuActive==0)
AiRBOOT_Config->BootMenuActive = 1;
AiRBOOT_Config->TimedBoot = 1; // Switches on Timed-Boot
AiRBOOT_Config->TimedSeconds = SetTimerValue;
}
AiRBOOTChanged = TRUE;
}
if (DoSetBootMenu) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
// Sets type of Boot-menu
// Switches BootMenu between Enabled and Detailed state...
if (BootMenuDetailed)
AiRBOOT_Config->BootMenuActive = 2; // Switch to Detailed mode
else
AiRBOOT_Config->BootMenuActive = 1; // Switch to Enabled (Normal)
AiRBOOTChanged = TRUE;
}
if (DoDirectBoot) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
// Sets Automatic-Booting to "DirectBootPart" (IPT-Entry)
AiRBOOT_Config->AutomaticBoot = 1; // Switches on Automatic-Boot
AiRBOOT_Config->AutomaticPartition = DirectBootPart;
AiRBOOTChanged = TRUE;
puts ("SETABOOT: Automatic boot enabled.");
}
if (DisableDirectBoot) {
if (!AiRBOOTDetected) {
MSG_Print (TXT_ERROR_NoBootManager);
return 1;
}
AiRBOOT_Config->AutomaticBoot = 0; // Switches off Automatic-Boot
AiRBOOT_Config->AutomaticPartition = 0;
AiRBOOTChanged = TRUE;
puts ("SETABOOT: Automatic boot disabled.");
}
if (AiRBOOTChanged) {
if (!Track0WriteAiRBOOTConfig())
return 1;
}
if (DoReboot) {
puts ("SETABOOT: Now rebooting system...");
RebootSystem();
}
return 0;
}
/*
// Rousseau:
// Global pointers will be initialized here !
*/
BOOL Track0DetectAirBoot (BOOL* ab_bad) {
USHORT ResultCheck;
USHORT CurSectorNo = 0;
/* Globals that get initialized */
AiRBOOT_CodeSig = (PAiRBOOTCODESIG)&Track0[2];
AiRBOOT_Config = (PAiRBOOTCONFIG)&Track0[(55-1)*512];
AiRBOOT_IPT = (PAiRBOOTIPENTRY)&Track0[(56-1)*512];
if (strncmp(AiRBOOT_CodeSig->Identifier, "AiRBOOT", 7)!=0) {
*ab_bad = FALSE;
return FALSE;
}
if ((AiRBOOT_CodeSig->TotalCodeSectors)>53) {
puts ("SETABOOT: AiR-BOOT Code damaged!");
*ab_bad = TRUE;
return TRUE;
}
ResultCheck = 0; CurSectorNo = 0;
while (CurSectorNoTotalCodeSectors) {
ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo+2);
CurSectorNo++;
}
if (ResultCheck!=AiRBOOT_CodeSig->CheckSumOfCode) {
puts ("SETABOOT: AiR-BOOT Code damaged!");
*ab_bad = TRUE;
return TRUE;
}
if (strncmp(AiRBOOT_Config->Identifier, "AiRCFG-TABLE\xad", 13)!=0) {
puts ("SETABOOT: AiR-BOOT Config damaged!");
*ab_bad = TRUE;
return TRUE;
}
// Set Config-CheckSum to 0
AiRBOOT_ConfigCheckSum = AiRBOOT_Config->CheckSumOfConfig;
AiRBOOT_Config->CheckSumOfConfig = 0;
// Calculate CheckSum...
// Rousseau: Only check 5 sectors for v1.07 compatibility.
ResultCheck = 0; CurSectorNo = 55;
while (CurSectorNo<60) {
ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
CurSectorNo++;
}
if (ResultCheck!=AiRBOOT_ConfigCheckSum) {
puts ("SETABOOT: AiR-BOOT Config damaged!");
*ab_bad = TRUE;
return TRUE;
}
*ab_bad = FALSE;
return TRUE;
}
BOOL Track0WriteAiRBOOTConfig (void) {
USHORT ResultCheck;
USHORT CurSectorNo = 0;
// Update Edit-Counter...
AiRBOOT_Config->EditCounter++;
AiRBOOT_Config->CheckSumOfConfig = 0;
// Calculate CheckSum...
ResultCheck = 0; CurSectorNo = 55;
/*
// Rousseau: # Keep compatible with v1.07 CRC #
// AB v1.07 had bugs in writing the wrong number of AB config sectors.
// This is fixed in v1.0.8+ but the CRC has to be calculated the "v1.07 way"
// otherwise v1.07 SET(A)BOOT and INSTALL2.EXE will think the AB config
// is corrupted.
// So the CRC is calculated over 5 sectors instead of 7.
*/
while (CurSectorNo<60) {
ResultCheck = GetChecksumOfSector(ResultCheck, CurSectorNo);
CurSectorNo++;
}
AiRBOOT_Config->CheckSumOfConfig = ResultCheck;
if (!Track0Write())
return FALSE;
return TRUE;
}
/*
// Rousseau: # This is the main entry-point #
// Special behavior if OS/2 is booted from CDROM and phase 1 called this program.
// In that case, the name of the newly installed system is put in the AiR-BOOT configuration.
// This will cause AiR-BOOT to boot through after phase 1.
*/
int main (int argc, char **argv) {
BOOL AiRBOOTDetected = FALSE;
BOOL Track0Loaded = FALSE; // Assume track0 did not load correctly.
BOOL AiRBOOTBad = FALSE;
int rc = -1;
/*
// Rousseau: ## Changed order to first check for AiR-BOOT existance ##
// If AiR-BOOT is not installed, all action is passed-thru to IBM SETBOOT (SETBM.EXE).
*/
/*
// Try to load track zero.
// We don't care if no harddisk is present, since we first want to know if AiR-BOOT is
// installed to adjust our behaviour.
// If it's not installed, or a loading error occurs, all actions will be deferred to
// IBM SETBOOT (SETBM.EXE).
// This means we also let IBM SETBOOT handle the situation in which no HD's are present.
*/
Track0Loaded = Track0Load();
/*
// Now see if AiR-BOOT is present.
// If there was a loading error, no AiR-BOOT signature will be present, so
// we pass-thru to IBM SETBOOT.
*/
AiRBOOTDetected = Track0DetectAirBoot(&AiRBOOTBad);
if (AiRBOOTDetected) {
rc = DoAirBootActions(argc, argv, AiRBOOTDetected, AiRBOOTBad);
}
else {
rc = DoClassicActions(argc, argv);
}
return rc;
}