diff --git a/config.h.in b/config.h.in index e2dd41f..044e81e 100644 --- a/config.h.in +++ b/config.h.in @@ -25,6 +25,9 @@ /* Define if C symbols get an underscore after compilation */ #undef HAVE_ASM_USCORE +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H diff --git a/configure.ac b/configure.ac index f561b8b..73cf23a 100644 --- a/configure.ac +++ b/configure.ac @@ -183,7 +183,7 @@ if test "$target_cpu"-"$platform" = i386-pc; then fi # Check for functions. -AC_CHECK_FUNCS(posix_memalign memalign) +AC_CHECK_FUNCS(posix_memalign memalign asprintf) # # Check for target programs. diff --git a/include/grub/symbol.h b/include/grub/symbol.h index e951490..c662c14 100644 --- a/include/grub/symbol.h +++ b/include/grub/symbol.h @@ -28,7 +28,7 @@ # define EXT_C(sym) sym #endif -#ifndef __CYGWIN__ +#if ! defined (__CYGWIN__) && ! defined (__MINGW32__) #define FUNCTION(x) .globl EXT_C(x) ; .type EXT_C(x), "function" ; EXT_C(x): #define VARIABLE(x) .globl EXT_C(x) ; .type EXT_C(x), "object" ; EXT_C(x): #else diff --git a/include/grub/util/misc.h b/include/grub/util/misc.h index c9a8528..3f145e8 100644 --- a/include/grub/util/misc.h +++ b/include/grub/util/misc.h @@ -24,6 +24,9 @@ #include #include +#include +#include + #ifdef __NetBSD__ /* NetBSD uses /boot for its boot block. */ # define DEFAULT_DIRECTORY "/grub" @@ -55,4 +58,22 @@ void grub_util_write_image_at (const void *img, size_t size, off_t offset, FILE *out); char *grub_util_get_disk_name (int disk, char *name); +#ifndef HAVE_ASPRINTF + +int asprintf (char **buf, const char *fmt, ...); + +#endif + +#ifdef __MINGW32__ + +#define fseeko fseeko64 +#define ftello ftello64 + +void sync (void); +void sleep(int s); + +grub_int64_t grub_util_get_disk_size (char *name); + +#endif + #endif /* ! GRUB_UTIL_MISC_HEADER */ diff --git a/util/biosdisk.c b/util/biosdisk.c index 1137e98..bdede12 100644 --- a/util/biosdisk.c +++ b/util/biosdisk.c @@ -157,7 +157,22 @@ grub_util_biosdisk_open (const char *name, grub_disk_t disk) disk->id = drive; /* Get the size. */ -#if defined(__linux__) || defined(__CYGWIN__) +#if defined(__MINGW32__) + { + grub_uint64_t size; + + size = grub_util_get_disk_size (map[drive].device); + + if (size % 512) + grub_util_error ("unaligned device size"); + + disk->total_sectors = size >> 9; + + grub_util_info ("the size of %s is %llu", name, disk->total_sectors); + + return GRUB_ERR_NONE; + } +#elif defined(__linux__) || defined(__CYGWIN__) { unsigned long long nr; int fd; @@ -275,6 +290,9 @@ open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags) #ifdef O_FSYNC flags |= O_FSYNC; #endif +#ifdef O_BINARY + flags |= O_BINARY; +#endif #ifdef __linux__ /* Linux has a bug that the disk cache for a whole disk is not consistent diff --git a/util/getroot.c b/util/getroot.c index 826092b..77b534a 100644 --- a/util/getroot.c +++ b/util/getroot.c @@ -169,7 +169,16 @@ grub_get_prefix (const char *dir) return prefix; } -#ifndef __CYGWIN__ +#ifdef __MINGW32__ + +static char * +find_root_device (const char *dir __attribute__ ((unused)), + dev_t dev __attribute__ ((unused))) +{ + return 0; +} + +#elif ! defined(__CYGWIN__) static char * find_root_device (const char *dir, dev_t dev) diff --git a/util/grub-mkdevicemap.c b/util/grub-mkdevicemap.c index 5b89437..6b8ebd7 100644 --- a/util/grub-mkdevicemap.c +++ b/util/grub-mkdevicemap.c @@ -169,6 +169,9 @@ get_floppy_disk_name (char *name, int unit) #elif defined(__CYGWIN__) /* Cygwin */ sprintf (name, "/dev/fd%d", unit); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; #else # warning "BIOS floppy drives cannot be guessed in your operating system." /* Set NAME to a bogus string. */ @@ -214,6 +217,8 @@ get_ide_disk_name (char *name, int unit) /* Cygwin emulates all disks as /dev/sdX. */ (void) unit; *name = 0; +#elif defined(__MINGW32__) + sprintf (name, "//./PHYSICALDRIVE%d", unit); #else # warning "BIOS IDE drives cannot be guessed in your operating system." /* Set NAME to a bogus string. */ @@ -258,6 +263,9 @@ get_scsi_disk_name (char *name, int unit) #elif defined(__CYGWIN__) /* Cygwin emulates all disks as /dev/sdX. */ sprintf (name, "/dev/sd%c", unit + 'a'); +#elif defined(__MINGW32__) + (void) unit; + *name = 0; #else # warning "BIOS SCSI drives cannot be guessed in your operating system." /* Set NAME to a bogus string. */ diff --git a/util/hostfs.c b/util/hostfs.c index b74fbd3..8773c1c 100644 --- a/util/hostfs.c +++ b/util/hostfs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -95,15 +96,19 @@ grub_hostfs_open (struct grub_file *file, const char *name) { FILE *f; - f = fopen (name, "r"); + f = fopen (name, "rb"); if (! f) return grub_error (GRUB_ERR_BAD_FILENAME, "can't open `%s'", name); file->data = f; +#ifdef __MINGW32__ + file->size = grub_util_get_disk_size (name); +#else fseeko (f, 0, SEEK_END); file->size = ftello (f); fseeko (f, 0, SEEK_SET); +#endif return GRUB_ERR_NONE; } diff --git a/util/misc.c b/util/misc.c index 7d877cc..4f20ff4 100644 --- a/util/misc.c +++ b/util/misc.c @@ -259,6 +259,8 @@ grub_memalign (grub_size_t align, grub_size_t size) #elif defined(HAVE_MEMALIGN) p = memalign (align, size); #else + (void) align; + (void) size; grub_util_error ("grub_memalign is not supported"); #endif @@ -313,3 +315,85 @@ grub_arch_sync_caches (void *address __attribute__ ((unused)), grub_size_t len __attribute__ ((unused))) { } + +#ifndef HAVE_ASPRINTF + +int +asprintf (char **buf, const char *fmt, ...) +{ + int status; + va_list ap; + + /* Should be large enough. */ + *buf = xmalloc (512); + + va_start (ap, fmt); + status = vsprintf (*buf, fmt, ap); + va_end (ap); + + return status; +} + +#endif + +#ifdef __MINGW32__ + +#include +#include +#include + +void sync (void) +{ +} + +void sleep (int s) +{ + Sleep (s * 1000); +} + +grub_int64_t +grub_util_get_disk_size (char *name) +{ + char new_name[strlen (name) + 1], *p; + HANDLE hd; + grub_int64_t size = -1LL; + + strcpy (new_name, name); + for (p = new_name; *p; p++) + if (*p == '/') + *p = '\\'; + + hd = CreateFile (new_name, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, 0, 0); + + if (hd == INVALID_HANDLE_VALUE) + return size; + + if (! strncmp (new_name, "\\\\.\\", 4)) + { + DWORD nr; + DISK_GEOMETRY g; + + if (! DeviceIoControl (hd, IOCTL_DISK_GET_DRIVE_GEOMETRY, + 0, 0, &g, sizeof (g), &nr, 0)) + goto fail; + + size = g.Cylinders.QuadPart; + size *= g.TracksPerCylinder * g.SectorsPerTrack * g.BytesPerSector; + } + else + { + LARGE_INTEGER s; + + s.LowPart = GetFileSize (hd, &s.HighPart); + size = s.QuadPart; + } + +fail: + + CloseHandle (hd); + + return size; +} + +#endif