diff options
Diffstat (limited to 'contrib/syslinux/latest/win/syslinux.c')
-rw-r--r-- | contrib/syslinux/latest/win/syslinux.c | 507 |
1 files changed, 0 insertions, 507 deletions
diff --git a/contrib/syslinux/latest/win/syslinux.c b/contrib/syslinux/latest/win/syslinux.c deleted file mode 100644 index 0e833d8..0000000 --- a/contrib/syslinux/latest/win/syslinux.c +++ /dev/null @@ -1,507 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2003 Lars Munch Christensen - All Rights Reserved - * Copyright 1998-2008 H. Peter Anvin - All Rights Reserved - * - * Based on the Linux installer program for SYSLINUX by H. Peter Anvin - * - * 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, Inc., 53 Temple Place Ste 330, - * Boston MA 02111-1307, USA; either version 2 of the License, or - * (at your option) any later version; incorporated herein by reference. - * - * ----------------------------------------------------------------------- */ - -/* - * syslinux-mingw.c - Win2k/WinXP installer program for SYSLINUX - */ - -#include <windows.h> -#include <stdio.h> -#include <ctype.h> -#include <getopt.h> - -#include "syslinux.h" -#include "libfat.h" -#include "setadv.h" -#include "sysexits.h" -#include "syslxopt.h" - -#ifdef __GNUC__ -# define noreturn void __attribute__((noreturn)) -#else -# define noreturn void -#endif - -void error(char *msg); - -/* Begin stuff for MBR code */ - -#include <winioctl.h> - -#define PART_TABLE 0x1be -#define PART_SIZE 0x10 -#define PART_COUNT 4 -#define PART_ACTIVE 0x80 - -// The following struct should be in the ntddstor.h file, but I didn't have it. -// mingw32 has <ddk/ntddstor.h>, but including that file causes all kinds -// of other failures. mingw64 has it in <winioctl.h>. -#ifndef __x86_64__ -typedef struct _STORAGE_DEVICE_NUMBER { - DEVICE_TYPE DeviceType; - ULONG DeviceNumber; - ULONG PartitionNumber; -} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER; -#endif - -BOOL GetStorageDeviceNumberByHandle(HANDLE handle, - const STORAGE_DEVICE_NUMBER * sdn) -{ - BOOL result = FALSE; - DWORD count; - - if (DeviceIoControl(handle, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, - 0, (LPVOID) sdn, sizeof(*sdn), &count, NULL)) { - result = TRUE; - } else { - error("GetDriveNumber: DeviceIoControl failed"); - } - - return (result); -} - -int GetBytesPerSector(HANDLE drive) -{ - int result = 0; - DISK_GEOMETRY g; - DWORD count; - - if (DeviceIoControl(drive, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, - &g, sizeof(g), &count, NULL)) { - result = g.BytesPerSector; - } - - return (result); -} - -BOOL FixMBR(int driveNum, int partitionNum, int write_mbr, int set_active) -{ - BOOL result = TRUE; - HANDLE drive; - - char driveName[128]; - - sprintf(driveName, "\\\\.\\PHYSICALDRIVE%d", driveNum); - - drive = CreateFile(driveName, - GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_WRITE | FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, NULL); - - if (drive == INVALID_HANDLE_VALUE) { - error("Accessing physical drive"); - result = FALSE; - } - - if (result) { - unsigned char sector[SECTOR_SIZE]; - DWORD howMany; - - if (GetBytesPerSector(drive) != SECTOR_SIZE) { - fprintf(stderr, - "Error: Sector size of this drive is %d; must be %d\n", - GetBytesPerSector(drive), SECTOR_SIZE); - result = FALSE; - } - - if (result) { - if (ReadFile(drive, sector, sizeof(sector), &howMany, NULL) == 0) { - error("Reading raw drive"); - result = FALSE; - } else if (howMany != sizeof(sector)) { - fprintf(stderr, - "Error: ReadFile on drive only got %d of %d bytes\n", - (int)howMany, sizeof(sector)); - result = FALSE; - } - } - // Copy over the MBR code if specified (-m) - if (write_mbr) { - if (result) { - if (syslinux_mbr_len >= PART_TABLE) { - fprintf(stderr, "Error: MBR will not fit; not writing\n"); - result = FALSE; - } else { - memcpy(sector, syslinux_mbr, syslinux_mbr_len); - } - } - } - // Check that our partition is active if specified (-a) - if (set_active) { - if (sector[PART_TABLE + (PART_SIZE * (partitionNum - 1))] != 0x80) { - int p; - for (p = 0; p < PART_COUNT; p++) - sector[PART_TABLE + (PART_SIZE * p)] = - (p == partitionNum - 1 ? 0x80 : 0); - } - } - - if (result) { - SetFilePointer(drive, 0, NULL, FILE_BEGIN); - - if (WriteFile(drive, sector, sizeof(sector), &howMany, NULL) == 0) { - error("Writing MBR"); - result = FALSE; - } else if (howMany != sizeof(sector)) { - fprintf(stderr, - "Error: WriteFile on drive only wrote %d of %d bytes\n", - (int)howMany, sizeof(sector)); - result = FALSE; - } - } - - if (!CloseHandle(drive)) { - error("CloseFile on drive"); - result = FALSE; - } - } - - return (result); -} - -/* End stuff for MBR code */ - -const char *program; /* Name of program */ - -/* - * Check Windows version. - * - * On Windows Me/98/95 you cannot open a directory, physical disk, or - * volume using CreateFile. - */ -int checkver(void) -{ - OSVERSIONINFO osvi; - - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osvi); - - return (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) && - ((osvi.dwMajorVersion > 4) || - ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0))); -} - -/* - * Windows error function - */ -void error(char *msg) -{ - LPVOID lpMsgBuf; - - /* Format the Windows error message */ - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) & lpMsgBuf, 0, NULL); - - /* Print it */ - fprintf(stderr, "%s: %s", msg, (char *)lpMsgBuf); - - /* Free the buffer */ - LocalFree(lpMsgBuf); -} - -/* - * Wrapper for ReadFile suitable for libfat - */ -int libfat_readfile(intptr_t pp, void *buf, size_t secsize, - libfat_sector_t sector) -{ - uint64_t offset = (uint64_t) sector * secsize; - LONG loword = (LONG) offset; - LONG hiword = (LONG) (offset >> 32); - LONG hiwordx = hiword; - DWORD bytes_read; - - if (SetFilePointer((HANDLE) pp, loword, &hiwordx, FILE_BEGIN) != loword || - hiword != hiwordx || - !ReadFile((HANDLE) pp, buf, secsize, &bytes_read, NULL) || - bytes_read != secsize) { - fprintf(stderr, "Cannot read sector %u\n", sector); - exit(1); - } - - return secsize; -} - -int main(int argc, char *argv[]) -{ - HANDLE f_handle, d_handle; - DWORD bytes_read; - DWORD bytes_written; - DWORD drives; - UINT drive_type; - - static unsigned char sectbuf[SECTOR_SIZE]; - char **argp; - static char drive_name[] = "\\\\.\\?:"; - static char drive_root[] = "?:\\"; - static char ldlinux_name[] = "?:\\ldlinux.sys"; - const char *errmsg; - struct libfat_filesystem *fs; - libfat_sector_t s, *secp; - libfat_sector_t *sectors; - int ldlinux_sectors; - uint32_t ldlinux_cluster; - int nsectors; - - if (!checkver()) { - fprintf(stderr, - "You need to be running at least Windows NT; use syslinux.com instead.\n"); - exit(1); - } - - program = argv[0]; - - parse_options(argc, argv, MODE_SYSLINUX_DOSWIN); - - if (!opt.device || !isalpha(opt.device[0]) || opt.device[1] != ':' - || opt.device[2]) - usage(EX_USAGE, MODE_SYSLINUX_DOSWIN); - - if (opt.sectors || opt.heads || opt.reset_adv || opt.set_once - || (opt.update_only > 0) || opt.menu_save || opt.offset) { - fprintf(stderr, - "At least one specified option not yet implemented" - " for this installer.\n"); - exit(1); - } - - /* Test if drive exists */ - drives = GetLogicalDrives(); - if (!(drives & (1 << (tolower(opt.device[0]) - 'a')))) { - fprintf(stderr, "No such drive %c:\n", opt.device[0]); - exit(1); - } - - /* Determines the drive type */ - drive_name[4] = opt.device[0]; - ldlinux_name[0] = opt.device[0]; - drive_root[0] = opt.device[0]; - drive_type = GetDriveType(drive_root); - - /* Test for removeable media */ - if ((drive_type == DRIVE_FIXED) && (opt.force == 0)) { - fprintf(stderr, "Not a removable drive (use -f to override) \n"); - exit(1); - } - - /* Test for unsupported media */ - if ((drive_type != DRIVE_FIXED) && (drive_type != DRIVE_REMOVABLE)) { - fprintf(stderr, "Unsupported media\n"); - exit(1); - } - - /* - * First open the drive - */ - d_handle = CreateFile(drive_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, NULL); - - if (d_handle == INVALID_HANDLE_VALUE) { - error("Could not open drive"); - exit(1); - } - - /* - * Make sure we can read the boot sector - */ - if (!ReadFile(d_handle, sectbuf, SECTOR_SIZE, &bytes_read, NULL)) { - error("Reading boot sector"); - exit(1); - } - if (bytes_read != SECTOR_SIZE) { - fprintf(stderr, "Could not read the whole boot sector\n"); - exit(1); - } - - /* Check to see that what we got was indeed an MS-DOS boot sector/superblock */ - if ((errmsg = syslinux_check_bootsect(sectbuf))) { - fprintf(stderr, "%s\n", errmsg); - exit(1); - } - - /* Change to normal attributes to enable deletion */ - /* Just ignore error if the file do not exists */ - SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_NORMAL); - - /* Delete the file */ - /* Just ignore error if the file do not exists */ - DeleteFile(ldlinux_name); - - /* Initialize the ADV -- this should be smarter */ - syslinux_reset_adv(syslinux_adv); - - /* Create ldlinux.sys file */ - f_handle = CreateFile(ldlinux_name, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN, NULL); - - if (f_handle == INVALID_HANDLE_VALUE) { - error("Unable to create ldlinux.sys"); - exit(1); - } - - /* Write ldlinux.sys file */ - if (!WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len, - &bytes_written, NULL) || - bytes_written != syslinux_ldlinux_len) { - error("Could not write ldlinux.sys"); - exit(1); - } - if (!WriteFile(f_handle, syslinux_adv, 2 * ADV_SIZE, - &bytes_written, NULL) || - bytes_written != 2 * ADV_SIZE) { - error("Could not write ADV to ldlinux.sys"); - exit(1); - } - - /* Now flush the media */ - if (!FlushFileBuffers(f_handle)) { - error("FlushFileBuffers failed"); - exit(1); - } - - /* Map the file (is there a better way to do this?) */ - ldlinux_sectors = (syslinux_ldlinux_len + 2 * ADV_SIZE + SECTOR_SIZE - 1) - >> SECTOR_SHIFT; - sectors = calloc(ldlinux_sectors, sizeof *sectors); - fs = libfat_open(libfat_readfile, (intptr_t) d_handle); - ldlinux_cluster = libfat_searchdir(fs, 0, "LDLINUX SYS", NULL); - secp = sectors; - nsectors = 0; - s = libfat_clustertosector(fs, ldlinux_cluster); - while (s && nsectors < ldlinux_sectors) { - *secp++ = s; - nsectors++; - s = libfat_nextsector(fs, s); - } - libfat_close(fs); - - /* - * Patch ldlinux.sys and the boot sector - */ - syslinux_patch(sectors, nsectors, opt.stupid_mode, opt.raid_mode, opt.directory, NULL); - - /* - * Rewrite the file - */ - if (SetFilePointer(f_handle, 0, NULL, FILE_BEGIN) != 0 || - !WriteFile(f_handle, syslinux_ldlinux, syslinux_ldlinux_len, - &bytes_written, NULL) - || bytes_written != syslinux_ldlinux_len) { - error("Could not write ldlinux.sys"); - exit(1); - } - - /* If desired, fix the MBR */ - if (opt.install_mbr || opt.activate_partition) { - STORAGE_DEVICE_NUMBER sdn; - if (GetStorageDeviceNumberByHandle(d_handle, &sdn)) { - if (!FixMBR(sdn.DeviceNumber, sdn.PartitionNumber, opt.install_mbr, opt.activate_partition)) { - fprintf(stderr, - "Did not successfully update the MBR; continuing...\n"); - } - } else { - fprintf(stderr, - "Could not find device number for updating MBR; continuing...\n"); - } - } - - /* Close file */ - CloseHandle(f_handle); - - /* Move the file to the desired location */ - if (opt.directory) { - char new_ldlinux_name[strlen(opt.directory) + 16]; - char *cp = new_ldlinux_name + 3; - const char *sd; - int slash = 1; - - new_ldlinux_name[0] = opt.device[0]; - new_ldlinux_name[1] = ':'; - new_ldlinux_name[2] = '\\'; - - for (sd = opt.directory; *sd; sd++) { - char c = *sd; - - if (c == '/' || c == '\\') { - if (slash) - continue; - c = '\\'; - slash = 1; - } else { - slash = 0; - } - - *cp++ = c; - } - - /* Skip if subdirectory == root */ - if (cp > new_ldlinux_name + 3) { - if (!slash) - *cp++ = '\\'; - - memcpy(cp, "ldlinux.sys", 12); - - /* Delete any previous file */ - SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_NORMAL); - DeleteFile(new_ldlinux_name); - if (!MoveFile(ldlinux_name, new_ldlinux_name)) - SetFileAttributes(ldlinux_name, FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN); - else - SetFileAttributes(new_ldlinux_name, FILE_ATTRIBUTE_READONLY | - FILE_ATTRIBUTE_SYSTEM | - FILE_ATTRIBUTE_HIDDEN); - } - } - - /* Make the syslinux boot sector */ - syslinux_make_bootsect(sectbuf); - - /* Write the syslinux boot sector into the boot sector */ - if (opt.bootsecfile) { - f_handle = CreateFile(opt.bootsecfile, GENERIC_READ | GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, - FILE_ATTRIBUTE_ARCHIVE, NULL); - if (f_handle == INVALID_HANDLE_VALUE) { - error("Unable to create bootsector file"); - exit(1); - } - if (!WriteFile(f_handle, sectbuf, SECTOR_SIZE, &bytes_written, NULL)) { - error("Could not write boot sector file"); - exit(1); - } - CloseHandle(f_handle); - } else { - SetFilePointer(d_handle, 0, NULL, FILE_BEGIN); - WriteFile(d_handle, sectbuf, SECTOR_SIZE, &bytes_written, NULL); - } - - if (bytes_written != SECTOR_SIZE) { - fprintf(stderr, "Could not write the whole boot sector\n"); - exit(1); - } - - /* Close file */ - CloseHandle(d_handle); - - /* Done! */ - return 0; -} |