/* * IDEHDD.CPP - Contains IDE Hard Disk functions. * Copyright (C) 1998, 1999 Prashant TR * * Thanks to Ralf Brown. * * This program 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 2 of the License, or * (at your option) any later version. * * See the file COPYING.TR for more details. */ // ID for this file. #define _IDEHDD_CC_ #include "idehdd.h" int errflag = 0; FILE *fp; char cmdline[20]; char output[256]; char idename[256]; unsigned long hdd_info; // Write any string to the file and check for successfulness. void writestring(const char *string) { if (fprintf(fp, "%s", string) == EOF) { errflag = 2; checkerrors(); } } void writehddinfo() { int i, temp; unsigned char *ptr = (unsigned char *)MK_FP(FP_SEG(&idehdd_info_block), FP_OFF(&idehdd_info_block)); unsigned short *bufptr; unsigned short cylinders, heads, sectors, precomp, lbacylinders, lbaheads, ref, href; unsigned long logsects, size; // Write a newline to indicate new IDE HDD. writestring("\n"); // Convert the reverse order names. for(i = 0x14; i < 0x5d; i += 2) { temp = ptr[i + 1]; ptr[i + 1] = ptr[i]; ptr[i] = temp; } // Write information only if IDE HDD is installed. for(i = 0x36; i <= 0x5d; i++) idename[i - 0x36] = ptr[i]; idename[i - 0x36] = 0; sprintf(output, "\tIDE Hard Disk Name : %s\n", idename); writestring(output); // Get serial number. for(i = 0x14; i <= 0x26; i++) idename[i - 0x14] = ptr[i]; idename[i - 0x14] = 0; sprintf(output, "\tHardware Serial Number : %s\n", idename); writestring(output); // Get revision. idename[0] = ptr[0x2e]; idename[1] = ptr[0x2f]; idename[2] = ptr[0x30]; idename[3] = ptr[0x31]; idename[4] = 0; sprintf(output, "\tHardware Revision : %s\n", idename); writestring(output); // Write out CHS information. bufptr = (unsigned short *)&ptr[2]; cylinders = *bufptr; heads = bufptr[2]; precomp = bufptr[4] - 1; sectors = bufptr[5]; logsects = 1L * cylinders * heads * sectors; size = (logsects * 512.0) / 1000000; // Normal Mode. writestring("\n"); writestring("\tIDE HDD (CHS / NORMAL MODE) :\n"); writestring("\n"); sprintf(output, "\tCylinders : %u\n", cylinders); writestring(output); sprintf(output, "\tNumber of Heads : %u\n", heads); writestring(output); sprintf(output, "\tWrite PRECOMP : %u\n", precomp); writestring(output); sprintf(output, "\tNumber of Sectors per Cylinder : %u\n", sectors); writestring(output); sprintf(output, "\tLanding Zone : %u\n", cylinders - 1); writestring(output); sprintf(output, "\tTotal logical sectors on disk : %lu\n", logsects); writestring(output); sprintf(output, "\tSize of hard disk : %luMB\n", size); writestring(output); // Large Mode. writestring("\n"); writestring("\tIDE HDD (ECHS / LARGE MODE) :\n"); writestring("\n"); sprintf(output, "\tCylinders : %u\n", cylinders / 2); writestring(output); sprintf(output, "\tNumber of Heads : %u\n", heads * 2); writestring(output); writestring("\tWrite PRECOMP : 0\n"); sprintf(output, "\tNumber of Sectors per Cylinder : %u\n", sectors); writestring(output); sprintf(output, "\tLanding Zone : %u\n", cylinders - 1); writestring(output); size = 1.0 * (cylinders / 2) * (heads * 2) * sectors * 512 / 1000000; sprintf(output, "\tTotal logical sectors on disk : %lu\n", (unsigned long)(1.0 * (cylinders / 2) * (heads * 2) * sectors)); writestring(output); sprintf(output, "\tSize of hard disk : %luMB\n", size); writestring(output); // LBA Mode. writestring("\n"); writestring("\tIDE HDD (LBA MODE) :\n"); writestring("\n"); ref = 1; do { ref <<= 1; } while (heads * 1.0 / ref > 1); href = ref; do { href <<= 1; } while ((cylinders / (href / ref)) >= 1024); lbaheads = href - (ref - heads); lbacylinders = cylinders / (href / heads); size = 1.0 * lbacylinders * lbaheads * sectors * 512.0 / 1000000; sprintf(output, "\tCylinders : %u\n", lbacylinders); writestring(output); sprintf(output, "\tNumber of Heads : %u\n", lbaheads); writestring(output); writestring("\tWrite PRECOMP : 0\n"); sprintf(output, "\tNumber of Sectors per Cylinder : %u\n", sectors); writestring(output); sprintf(output, "\tLanding Zone : %u\n", cylinders - 1); writestring(output); sprintf(output, "\tTotal logical sectors on disk : %lu\n", (unsigned long)(1.0 * lbacylinders * lbaheads * sectors)); writestring(output); sprintf(output, "\tSize of hard disk : %luMB\n", size); writestring(output); writestring("\n"); } int sysinfo() { // Create output file. if ((fp = fopen("idehdd.txt", "w")) == NULL) { errflag = 1; checkerrors(); } // Get IDE HDD information. writestring("\nIDE HARD DRIVE(S) INFORMATION :\n\n"); // Write to file. memset(&idehdd_info_block, 0, 256); hdd_info = get_ide_hdd_info(0x1f0, 0xa0); sprintf(output, "\tIDE HDD installed at Primary Master : %s\n", (hdd_info) ? "Yes" : "No"); writestring(output); if (hdd_info) writehddinfo(); memset(&idehdd_info_block, 0, 256); hdd_info = get_ide_hdd_info(0x1f0, 0xb0); sprintf(output, "\tIDE HDD installed at Primary Slave : %s\n", (hdd_info) ? "Yes" : "No"); writestring(output); if (hdd_info) writehddinfo(); memset(&idehdd_info_block, 0, 256); hdd_info = get_ide_hdd_info(0x170, 0xa0); sprintf(output, "\tIDE HDD installed at Secondary Master : %s\n", (hdd_info) ? "Yes" : "No"); writestring(output); if (hdd_info) writehddinfo(); memset(&idehdd_info_block, 0, 256); hdd_info = get_ide_hdd_info(0x170, 0xb0); sprintf(output, "\tIDE HDD installed at Secondary Slave : %s\n", (hdd_info) ? "Yes" : "No"); writestring(output); if (hdd_info) writehddinfo(); fclose(fp); return 0; } void open_stderr() { fclose(stdout); fclose(&_streams[2]); if (fopen("nul", "wb") == NULL) exit(0x7f); if (fopen("nul", "wb") == NULL) exit(0x7f); if ((stderr = fopen("errors.$$$", "ab")) == NULL) exit(0x7f); } void get_cmdline() { if ((fp = fopen("cmdline.$$$", "rb")) == NULL) exit (0x7f); if (fscanf(fp, "%s", cmdline) != 1) { fclose(fp); exit (0x7f); } fclose(fp); unlink("cmdline.$$$"); } #pragma argsused int main(int argc, char **argv) { open_stderr(); get_cmdline(); if (!strcmp(cmdline, "sysinfo")) return (sysinfo()); return 0; }