diff --git a/sys/fdkrncfg.c b/sys/fdkrncfg.c new file mode 100644 index 0000000..a68d5e5 --- /dev/null +++ b/sys/fdkrncfg.c @@ -0,0 +1,335 @@ +/*************************************************************************** +* * +* FDKRNCFG.C - FreeDOS Kernel Configuration * +* This is a simple little program that merely displays and/or changes * +* the configuration options specified within the CONFIG section of * +* the FreeDOS Kernel (if supported) * +* * +* Initially Written by Kenneth J. Davis Oct 11, 2001 (public domain) * +* Future versions may contain copyrighted portions, if so the * +* copyright holders should be listed after this line. * +* Initial release - public domain * +* * +* merged into SYS by tom ehlert * +***************************************************************************/ + +/* This source compiled & tested with Borland C/C++ 3.1 + TC 2.01*/ + + +char VERSION[] = "v1.00"; +char PROGRAM[] = "SYS CONFIG"; +char KERNEL[] = "KERNEL.SYS"; + + +#include +#include +#include +#include +#include + +#define FAR far +#include "kconfig.h" + +KernelConfig cfg = {0}; + + +typedef unsigned char byte; +typedef unsigned short word; +typedef unsigned long dword; + + +/* These structures need to be byte packed, if your compiler + does not do this by default, add the appropriate command, + such as #pragma pack(1) here, protected with #ifdefs of course. +*/ + + + +/* Displays command line syntax */ +void showUsage(void) +{ + + printf("FreeDOS Kernel Configuration %s\n", VERSION); + printf("Usage: \n" + " %s \n" + " %s [/help | /?]\n" + " %s [ [drive:][path]%s] [option=value ...] \n", + PROGRAM, PROGRAM, PROGRAM, KERNEL); + printf("\n"); + printf(" If no options are given, the current values are shown.\n"); + printf(" %/help or ? displays this usage information.\n" + " [drive:][path]KERNEL.SYS specifies the kernel file to\n" + " modify, if not given defaults to \\%s\n", + KERNEL); + printf("\n"); + printf(" option=value ... specifies one or more options and the values\n" + " to set each to. If an option is given multiple times,\n" + " the value set will be the rightmost one.\n"); + printf(" Current Options are: DLASORT=0|1, SHOWDRIVEASSIGNMENT=0|1\n"); +} + + + +/* simply reads in current configuration values, exiting program + with an error message and error code unable to, otherwise + cfg & kfile are valid on return. +*/ + + +/* Reads in the current kernel configuration settings, + return 0 on success, nonzero on error. If there was + an actual error the return value is positive, if there + were no errors, but the CONFIG section was not found + then a negative value is returned. cfg is only altered + if the return value is 0 (ie successfully found and + read in the config section). The position of the file + pointer on input does not matter, the file position + upon return may be anywhere. The memory allocated for + cfg should be freed to prevent memory leakage (it should + not point to allocated memory on entry, as that memory + will not be used, and will likely not be freed as a result). +*/ +int readConfigSettings(int kfile, char *kfilename, KernelConfig *cfg) +{ + int ch; + int configBlkFound; + word cfgSize; + + + /* Seek to start of kernel file */ + if (lseek(kfile, 2, SEEK_SET) != 2) + printf("can't seek to offset 2\n"),exit(1); + + if (read(kfile,cfg,sizeof(KernelConfig)) != sizeof(KernelConfig)) + printf("can't read %u bytes\n",sizeof(KernelConfig)),exit(1); + + if (memcmp(cfg->CONFIG, "CONFIG", 6) != 0) + { + printf("Error: no CONFIG section found in kernel file <%s>\n", kfilename); + printf("Only FreeDOS kernels after 2025 contain a CONFIG section!\n"); + exit(1); + } + + return 1; +} + + +/* Writes config values out to file. + Returns 0 on success, nonzero on error. +*/ +int writeConfigSettings(int kfile, KernelConfig *cfg) +{ + + /* Seek to CONFIG section at start of options of kernel file */ + if (lseek(kfile, 2, SEEK_SET) != 2) + return 1; + + /* Write just the config option information out */ + if (write(kfile, cfg, sizeof(KernelConfig)) != sizeof(KernelConfig)) + return 1; + + /* successfully wrote out kernel config data */ + return 0; +} + + +/* Displays kernel configuration information */ +void displayConfigSettings(KernelConfig *cfg) +{ + /* print known options and current value - only if available */ + + if (cfg->ConfigSize >= 1) + { + printf("DLASORT=0x%02X Sort disks by drive order: *0=no, 1=yes\n", + cfg->DLASortByDriveNo); + } + + if (cfg->ConfigSize >= 2) + { + printf("SHOWDRIVEASSIGNMENT=0x%02X Show how drives assigned: *1=yes 0=no\n", + cfg->InitDiskShowDriveAssignment); + } + + if (cfg->ConfigSize >= 3) + { + printf("SKIPCONFIGSECONDS=%-2d time to wait for F5/F8 : *2 sec\n", + cfg->SkipConfigSeconds); + } + +#if 0 /* we assume that SYS is as current as the kernel */ + + /* Print value any options added that are unknown as hex dump */ + if (cfg->configHdr.configSize > sizeof(ConfigData)) + { + printf("Additional options are available, they are not currently\n" + "supported by this tool. The current extra values are (in Hex):\n"); + for (i = 0; i < (cfg->configSize-sizeof(ConfigData)); i++) + { + if ((i%32) == 0) printf("\n"); + else if ((i%4) == 0) printf(" "); + printf("%02X", (unsigned int)cfg->extra[i]); + } + printf("\n"); + } +#endif + printf("\n"); +} + + + + +/* Sets the given location to a byte value if different, + displays warning if values exceeds max +*/ +void setByteOption(byte *option, char *value, word max, int *updated, char *name) +{ + int optionValue; + + optionValue = atoi(value); + if (optionValue > max) + { + printf("Warning: Option %s: Value <0x%02X> may be invalid!\n", + name, (unsigned int)((byte)optionValue)); + } + /* Don't bother updating if same value */ + if ((byte)optionValue != *option) + { + *option = (byte)optionValue; + *updated = 1; + } +} + + +/* Main, processes command line options and calls above + functions as required. +*/ +int FDKrnConfigMain(int argc,char **argv) +{ + char *kfilename = KERNEL; + int kfile; + int updates = 0; /* flag used to indicate if we need to update kernel */ + int argstart,i; + char *cptr; + char *argptr; + + printf("FreeDOS System configurator %s \n", VERSION); + + + /* 1st go through and just process arguments (help/filename/etc) */ + for (i = 2; i < argc; i++) + { + argptr = argv[i]; + + /* is it an argument or an option specifier */ + if (argptr[0] == '-' || argptr[0] == '/') + { + switch(argptr[1]) + { + case 'H': + case 'h': + case '?': + showUsage(); + exit(0); + + default: + printf("Invalid argument found <%s>.\nUse %s /help for usage.\n", + argptr, PROGRAM); + exit(1); + } + } + } + + argstart = 2; + + argptr = argv[argstart]; + + cptr = strchr(argptr, '='); + + if (argptr == 0) + { + showUsage(); + exit(1); + } + /* the first argument may be the kernel name */ + if (strchr(argptr, '=') == NULL) + { + kfilename = argptr; + argstart++; + } + + + kfile = open(kfilename, O_RDWR | O_BINARY); + + if (kfile < 0) + printf("Error: unable to open kernel file <%s>\n", kfilename),exit(1); + + + /* now that we know the filename (default or given) get config info */ + readConfigSettings(kfile, kfilename, &cfg); + + for (i = argstart; i < argc; i++) + { + argptr = argv[i]; + + if ((cptr = strchr(argptr,'=')) == NULL) + goto illegal_arg; + + /* split argptr into 2 pieces and make cptr point to 2nd one */ + *cptr = '\0'; + cptr++; + + /* allow 3 valid characters */ + if (memicmp(argptr, "DLASORT",3) == 0) + { + setByteOption(&(cfg.DLASortByDriveNo), + cptr, 1, &updates, "DLASORT"); + } + else if (memicmp(argptr, "SHOWDRIVEASSIGNMENT",3) == 0) + { + setByteOption(&(cfg.InitDiskShowDriveAssignment), + cptr, 1, &updates, "SHOWDRIVEASSIGNMENT"); + } + else if (memicmp(argptr, "SKIPCONFIGSECONDS",3) == 0) + { + setByteOption(&(cfg.SkipConfigSeconds), + cptr, 1, &updates, "SKIPCONFIGSECONDS"); + updates++; + } + else + { +illegal_arg: + printf("Unknown option found <%s>.\nUse %s /help for usage.\n", + argptr, PROGRAM); + exit(1); + } + } + + /* write out new config values if modified */ + if (updates) + { + /* update it */ + if (writeConfigSettings(kfile, &cfg)) + { + printf("Error: Unable to write configuration changes to kernel!\n"); + printf(" <%s>\n", kfilename); + close(kfile); + exit(1); + } + + + /* display new settings */ + printf("\nUpdated Kernel settings.\n"); + } + else + printf("Current Kernel settings.\n"); + + + /* display current settings */ + displayConfigSettings(&cfg); + + /* and done */ + close(kfile); + + return 0; +} +