Move OS-dependent files to grub-core/osdep and document it.
This commit is contained in:
parent
a5b0365ab2
commit
672fa55e81
30 changed files with 39 additions and 30 deletions
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
# include <sys/disk.h>
|
||||
|
||||
grub_uint64_t
|
||||
grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
unsigned long long nr;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
if (ioctl (fd, DKIOCGETBLOCKCOUNT, &nr))
|
||||
return -1;
|
||||
|
||||
if (ioctl (fd, DKIOCGETBLOCKSIZE, §or_size))
|
||||
return -1;
|
||||
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
return nr << log_sector_size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,506 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <dos/dos.h>
|
||||
#include <dos/filesystem.h>
|
||||
#include <dos/exall.h>
|
||||
#include <proto/dos.h>
|
||||
#include <devices/hardblocks.h>
|
||||
#include <devices/newstyle.h>
|
||||
#include <proto/exec.h>
|
||||
#include <proto/utility.h>
|
||||
#include <proto/partition.h>
|
||||
#include <devices/trackdisk.h>
|
||||
#include <exec/errors.h>
|
||||
|
||||
#define BOUNCE_SIZE 1048576
|
||||
|
||||
static ULONG *bounce;
|
||||
|
||||
char *
|
||||
canonicalize_file_name (const char *path)
|
||||
{
|
||||
char *ret;
|
||||
BPTR lck;
|
||||
const char *p;
|
||||
|
||||
p = strchr (path, ':');
|
||||
if (p && !p[1])
|
||||
return xstrdup (path);
|
||||
|
||||
ret = xmalloc (2048);
|
||||
lck = Lock ((const unsigned char *) path, SHARED_LOCK);
|
||||
|
||||
if (!lck || !NameFromLock (lck, (unsigned char *) ret, 2040))
|
||||
{
|
||||
free (ret);
|
||||
ret = xstrdup (path);
|
||||
}
|
||||
if (lck)
|
||||
UnLock (lck);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
grub_util_get_fd_size_volume (grub_util_fd_t fd __attribute__ ((unused)),
|
||||
const char *dev,
|
||||
unsigned *log_secsize)
|
||||
{
|
||||
struct DriveGeometry *geo;
|
||||
LONG err;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
if (!bounce)
|
||||
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
|
||||
if (!bounce)
|
||||
grub_util_error ("out of memory");
|
||||
|
||||
fd->ioreq->iotd_Req.io_Command = TD_GETGEOMETRY;
|
||||
fd->ioreq->iotd_Req.io_Length = sizeof (*geo);
|
||||
fd->ioreq->iotd_Req.io_Data = bounce;
|
||||
fd->ioreq->iotd_Req.io_Offset = 0;
|
||||
fd->ioreq->iotd_Req.io_Actual = 0;
|
||||
err = DoIO ((struct IORequest *) fd->ioreq);
|
||||
if (err)
|
||||
{
|
||||
grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
|
||||
return -1;
|
||||
}
|
||||
|
||||
geo = (struct DriveGeometry *) bounce;
|
||||
|
||||
sector_size = geo->dg_SectorSize;
|
||||
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
return (grub_uint64_t) geo->dg_TotalSectors * (grub_uint64_t) geo->dg_SectorSize;
|
||||
}
|
||||
|
||||
static grub_uint64_t
|
||||
grub_util_get_fd_size_file (grub_util_fd_t fd,
|
||||
const char *dev __attribute__ ((unused)),
|
||||
unsigned *log_secsize)
|
||||
{
|
||||
off_t oo, ro;
|
||||
*log_secsize = 9;
|
||||
/* FIXME: support 64-bit offsets. */
|
||||
oo = lseek (fd->fd, 0, SEEK_CUR);
|
||||
ro = lseek (fd->fd, 0, SEEK_END);
|
||||
lseek (fd->fd, oo, SEEK_SET);
|
||||
return ro;
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
if (lseek (fd->fd, 0, SEEK_SET) == (off_t) -1)
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
|
||||
name, strerror (errno));
|
||||
fd->off = off;
|
||||
return 0;
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
fd->off = off;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_util_fd_t
|
||||
grub_util_fd_open (const char *dev, int flg)
|
||||
{
|
||||
grub_util_fd_t ret = xmalloc (sizeof (*ret));
|
||||
const char *p, *p1, *p2;
|
||||
char *tmp;
|
||||
IPTR unit = 0;
|
||||
ULONG flags = 0;
|
||||
|
||||
ret->off = 0;
|
||||
|
||||
if (dev[0] == '\0')
|
||||
{
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p = strchr (dev, ':');
|
||||
|
||||
if (!p || p[1])
|
||||
{
|
||||
ret->type = GRUB_UTIL_FD_FILE;
|
||||
ret->fd = open (dev, flg);
|
||||
if (ret->fd < 0)
|
||||
{
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
p1 = strchr (dev, '/');
|
||||
if (!p1)
|
||||
p1 = p;
|
||||
else
|
||||
{
|
||||
unit = grub_strtoul (p1 + 1, (char **) &p2, 16);
|
||||
if (p2 && *p2 == '/')
|
||||
flags = grub_strtoul (p2 + 1, 0, 16);
|
||||
}
|
||||
|
||||
ret->mp = CreateMsgPort();
|
||||
if (!ret->mp)
|
||||
{
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->ioreq = (struct IOExtTD *) CreateIORequest(ret->mp,
|
||||
sizeof(struct IOExtTD));
|
||||
if (!ret->ioreq)
|
||||
{
|
||||
free (ret);
|
||||
DeleteMsgPort (ret->mp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tmp = xmalloc (p1 - dev + 1);
|
||||
memcpy (tmp, dev, p1 - dev);
|
||||
tmp[p1 - dev] = '\0';
|
||||
ret->type = GRUB_UTIL_FD_DISK;
|
||||
|
||||
ret->is_floppy = (strcmp (tmp, TD_NAME) == 0);
|
||||
ret->is_64 = 1;
|
||||
|
||||
if (OpenDevice ((unsigned char *) tmp, unit, (struct IORequest *) ret->ioreq, flags))
|
||||
{
|
||||
free (tmp);
|
||||
free (ret);
|
||||
DeleteMsgPort (ret->mp);
|
||||
return NULL;
|
||||
}
|
||||
free (tmp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
grub_util_fd_read_file (grub_util_fd_t fd, char *buf, size_t len)
|
||||
{
|
||||
ssize_t size = len;
|
||||
|
||||
while (len)
|
||||
{
|
||||
ssize_t ret = read (fd->fd, buf, len);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd->off += ret;
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
|
||||
error occurs, otherwise return LEN. */
|
||||
static ssize_t
|
||||
grub_util_fd_write_file (grub_util_fd_t fd, const char *buf, size_t len)
|
||||
{
|
||||
ssize_t size = len;
|
||||
|
||||
while (len)
|
||||
{
|
||||
ssize_t ret = write (fd->fd, buf, len);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd->off += ret;
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
stop_motor (grub_util_fd_t fd)
|
||||
{
|
||||
if (!fd->is_floppy)
|
||||
return;
|
||||
fd->ioreq->iotd_Req.io_Command = TD_MOTOR;
|
||||
fd->ioreq->iotd_Req.io_Length = 0;
|
||||
fd->ioreq->iotd_Req.io_Data = 0;
|
||||
fd->ioreq->iotd_Req.io_Offset = 0;
|
||||
fd->ioreq->iotd_Req.io_Actual = 0;
|
||||
DoIO ((struct IORequest *) fd->ioreq);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
grub_util_fd_read_volume (grub_util_fd_t fd, char *buf, size_t len)
|
||||
{
|
||||
grub_uint64_t adj = 0;
|
||||
|
||||
if (!bounce)
|
||||
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
|
||||
if (!bounce)
|
||||
grub_util_error ("out of memory");
|
||||
|
||||
while (len)
|
||||
{
|
||||
size_t cr = len;
|
||||
LONG err;
|
||||
if (cr > BOUNCE_SIZE)
|
||||
cr = BOUNCE_SIZE;
|
||||
retry:
|
||||
if (fd->is_64)
|
||||
fd->ioreq->iotd_Req.io_Command = NSCMD_TD_READ64;
|
||||
else
|
||||
fd->ioreq->iotd_Req.io_Command = CMD_READ;
|
||||
fd->ioreq->iotd_Req.io_Length = cr;
|
||||
fd->ioreq->iotd_Req.io_Data = bounce;
|
||||
fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
|
||||
fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
|
||||
err = DoIO ((struct IORequest *) fd->ioreq);
|
||||
if (err == IOERR_NOCMD && fd->is_64)
|
||||
{
|
||||
fd->is_64 = 0;
|
||||
goto retry;
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
grub_util_info ("I/O failed with error %d, IoErr=%d", (int)err, (int) IoErr ());
|
||||
stop_motor (fd);
|
||||
return -1;
|
||||
}
|
||||
memcpy (buf, bounce, cr);
|
||||
adj += cr;
|
||||
len -= cr;
|
||||
buf += cr;
|
||||
}
|
||||
|
||||
fd->off += adj;
|
||||
stop_motor (fd);
|
||||
return adj;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
grub_util_fd_write_volume (grub_util_fd_t fd, const char *buf, size_t len)
|
||||
{
|
||||
grub_uint64_t adj = 0;
|
||||
if (!bounce)
|
||||
bounce = AllocVec (BOUNCE_SIZE, MEMF_PUBLIC | MEMF_CLEAR);
|
||||
if (!bounce)
|
||||
grub_util_error ("out of memory");
|
||||
|
||||
while (len)
|
||||
{
|
||||
size_t cr = len;
|
||||
LONG err;
|
||||
if (cr > BOUNCE_SIZE)
|
||||
cr = BOUNCE_SIZE;
|
||||
retry:
|
||||
if (fd->is_64)
|
||||
fd->ioreq->iotd_Req.io_Command = NSCMD_TD_WRITE64;
|
||||
else
|
||||
fd->ioreq->iotd_Req.io_Command = CMD_WRITE;
|
||||
fd->ioreq->iotd_Req.io_Length = cr;
|
||||
fd->ioreq->iotd_Req.io_Data = bounce;
|
||||
fd->ioreq->iotd_Req.io_Offset = fd->off & 0xFFFFFFFF;
|
||||
fd->ioreq->iotd_Req.io_Actual = fd->off >> 32;
|
||||
memcpy (bounce, buf, cr);
|
||||
err = DoIO ((struct IORequest *) fd->ioreq);
|
||||
if (err == IOERR_NOCMD && fd->is_64)
|
||||
{
|
||||
fd->is_64 = 0;
|
||||
goto retry;
|
||||
}
|
||||
if (err)
|
||||
{
|
||||
grub_util_info ("I/O failed with error %d", err);
|
||||
stop_motor (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
adj += cr;
|
||||
len -= cr;
|
||||
buf += cr;
|
||||
}
|
||||
|
||||
fd->off += adj;
|
||||
stop_motor (fd);
|
||||
return adj;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
return grub_util_fd_read_file (fd, buf, len);
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
return grub_util_fd_read_volume (fd, buf, len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
return grub_util_fd_write_file (fd, buf, len);
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
return grub_util_fd_write_volume (fd, buf, len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
grub_uint64_t
|
||||
grub_util_get_fd_size (grub_util_fd_t fd,
|
||||
const char *dev,
|
||||
unsigned *log_secsize)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
return grub_util_get_fd_size_file (fd, dev, log_secsize);
|
||||
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
return grub_util_get_fd_size_volume (fd, dev, log_secsize);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_close (grub_util_fd_t fd)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
close (fd->fd);
|
||||
return;
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
CloseDevice ((struct IORequest *) fd->ioreq);
|
||||
DeleteIORequest((struct IORequest *) fd->ioreq);
|
||||
DeleteMsgPort (fd->mp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
grub_util_fd_sync_volume (grub_util_fd_t fd)
|
||||
{
|
||||
fd->ioreq->iotd_Req.io_Command = CMD_UPDATE;
|
||||
fd->ioreq->iotd_Req.io_Length = 0;
|
||||
fd->ioreq->iotd_Req.io_Data = 0;
|
||||
fd->ioreq->iotd_Req.io_Offset = 0;
|
||||
fd->ioreq->iotd_Req.io_Actual = 0;
|
||||
DoIO ((struct IORequest *) fd->ioreq);
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_sync (grub_util_fd_t fd)
|
||||
{
|
||||
switch (fd->type)
|
||||
{
|
||||
case GRUB_UTIL_FD_FILE:
|
||||
fsync (fd->fd);
|
||||
return;
|
||||
case GRUB_UTIL_FD_DISK:
|
||||
grub_util_fd_sync_volume (fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
grub_util_fd_strerror (void)
|
||||
{
|
||||
static char buf[201];
|
||||
LONG err = IoErr ();
|
||||
if (!err)
|
||||
return _("Success");
|
||||
memset (buf, '\0', sizeof (buf));
|
||||
Fault (err, (const unsigned char *) "", (STRPTR) buf, sizeof (buf));
|
||||
if (buf[0] == ':')
|
||||
return buf + 1;
|
||||
return buf;
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd __attribute__ ((unused)),
|
||||
const char *name __attribute__ ((unused)),
|
||||
unsigned *log_secsize __attribute__ ((unused)))
|
||||
{
|
||||
# warning "No special routine to get the size of a block device is implemented for your OS. This is not possibly fatal."
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/disklabel.h> /* struct disklabel */
|
||||
# include <sys/disk.h> /* struct dkwedge_info */
|
||||
# ifdef HAVE_GETRAWPARTITION
|
||||
# include <util.h> /* getrawpartition */
|
||||
# endif /* HAVE_GETRAWPARTITION */
|
||||
# if defined(__NetBSD__)
|
||||
# include <sys/fdio.h>
|
||||
# endif
|
||||
# if defined(__OpenBSD__)
|
||||
# include <sys/dkio.h>
|
||||
# endif
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
/* Adjust device driver parameters. This function should be called just
|
||||
after successfully opening the device. For now, it simply prevents the
|
||||
floppy driver from retrying operations on failure, as otherwise the
|
||||
driver takes a while to abort when there is no floppy in the drive. */
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (fstat (fd, &st) < 0 || ! S_ISCHR (st.st_mode))
|
||||
return;
|
||||
if (major(st.st_rdev) == RAW_FLOPPY_MAJOR)
|
||||
{
|
||||
int floppy_opts;
|
||||
|
||||
if (ioctl (fd, FDIOCGETOPTS, &floppy_opts) == -1)
|
||||
return;
|
||||
floppy_opts |= FDOPT_NORETRY;
|
||||
if (ioctl (fd, FDIOCSETOPTS, &floppy_opts) == -1)
|
||||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
struct disklabel label;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
grub_hostdisk_configure_device_driver (fd);
|
||||
|
||||
if (ioctl (fd, DIOCGDINFO, &label) == -1)
|
||||
return -1;
|
||||
|
||||
sector_size = label.d_secsize;
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
return (grub_uint64_t) label.d_secperunit << log_sector_size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,194 +0,0 @@
|
|||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#ifdef HAVE_DEVICE_MAPPER
|
||||
# include <libdevmapper.h>
|
||||
|
||||
static void device_mapper_null_log (int level __attribute__ ((unused)),
|
||||
const char *file __attribute__ ((unused)),
|
||||
int line __attribute__ ((unused)),
|
||||
int dm_errno __attribute__ ((unused)),
|
||||
const char *f __attribute__ ((unused)),
|
||||
...)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
grub_device_mapper_supported (void)
|
||||
{
|
||||
static int supported = -1;
|
||||
|
||||
if (supported == -1)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
|
||||
/* Suppress annoying log messages. */
|
||||
dm_log_with_errno_init (&device_mapper_null_log);
|
||||
|
||||
dmt = dm_task_create (DM_DEVICE_VERSION);
|
||||
supported = (dmt != NULL);
|
||||
if (dmt)
|
||||
dm_task_destroy (dmt);
|
||||
|
||||
/* Restore the original logger. */
|
||||
dm_log_with_errno_init (NULL);
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_device_is_mapped (const char *dev)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
if (!grub_device_mapper_supported ())
|
||||
return 0;
|
||||
|
||||
if (stat (dev, &st) < 0)
|
||||
return 0;
|
||||
|
||||
return dm_is_dm_major (major (st.st_rdev));
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_get_dm_node_linear_info (const char *dev,
|
||||
int *maj, int *min,
|
||||
grub_disk_addr_t *st)
|
||||
{
|
||||
struct dm_task *dmt;
|
||||
void *next = NULL;
|
||||
uint64_t length, start;
|
||||
char *target, *params;
|
||||
char *ptr;
|
||||
int major = 0, minor = 0;
|
||||
int first = 1;
|
||||
grub_disk_addr_t partstart = 0;
|
||||
const char *node_uuid;
|
||||
|
||||
while (1)
|
||||
{
|
||||
dmt = dm_task_create(DM_DEVICE_TABLE);
|
||||
if (!dmt)
|
||||
break;
|
||||
|
||||
if (! (first ? dm_task_set_name (dmt, dev)
|
||||
: dm_task_set_major_minor (dmt, major, minor, 0)))
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
}
|
||||
dm_task_no_open_count(dmt);
|
||||
if (!dm_task_run(dmt))
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
}
|
||||
node_uuid = dm_task_get_uuid (dmt);
|
||||
if (node_uuid && (strncmp (node_uuid, "LVM-", 4) == 0
|
||||
|| strncmp (node_uuid, "mpath-", 6) == 0
|
||||
|| strncmp (node_uuid, "DMRAID-", 7) == 0))
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
}
|
||||
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&target, ¶ms);
|
||||
if (grub_strcmp (target, "linear") != 0)
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
break;
|
||||
}
|
||||
major = grub_strtoul (params, &ptr, 10);
|
||||
if (grub_errno)
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
return 0;
|
||||
}
|
||||
if (*ptr != ':')
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
return 0;
|
||||
}
|
||||
ptr++;
|
||||
minor = grub_strtoul (ptr, &ptr, 10);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
dm_task_destroy (dmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*ptr != ' ')
|
||||
{
|
||||
dm_task_destroy (dmt);
|
||||
return 0;
|
||||
}
|
||||
ptr++;
|
||||
partstart += grub_strtoull (ptr, &ptr, 10);
|
||||
if (grub_errno)
|
||||
{
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
dm_task_destroy (dmt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_task_destroy (dmt);
|
||||
first = 0;
|
||||
if (!dm_is_dm_major (major))
|
||||
break;
|
||||
}
|
||||
if (first)
|
||||
return 0;
|
||||
if (maj)
|
||||
*maj = major;
|
||||
if (min)
|
||||
*min = minor;
|
||||
if (st)
|
||||
*st = partstart;
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
|
||||
int
|
||||
grub_util_device_is_mapped (const char *dev __attribute__ ((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_get_dm_node_linear_info (const char *dev __attribute__ ((unused)),
|
||||
int *maj __attribute__ ((unused)),
|
||||
int *min __attribute__ ((unused)),
|
||||
grub_disk_addr_t *st __attribute__ ((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
# include <sys/disk.h> /* DIOCGMEDIASIZE */
|
||||
# include <sys/param.h>
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/mount.h>
|
||||
# include <libgeom.h>
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
unsigned long long nr;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
if (ioctl (fd, DIOCGMEDIASIZE, &nr))
|
||||
return -1;
|
||||
|
||||
if (ioctl (fd, DIOCGSECTORSIZE, §or_size))
|
||||
return -1;
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
if (nr & (sector_size - 1))
|
||||
grub_util_error ("%s", _("unaligned device size"));
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <hurd.h>
|
||||
#include <hurd/lookup.h>
|
||||
#include <hurd/fs.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_hurd_get_disk_info (const char *dev, grub_uint32_t *secsize, grub_disk_addr_t *offset,
|
||||
grub_disk_addr_t *size, char **parent)
|
||||
{
|
||||
file_t file;
|
||||
mach_port_t *ports;
|
||||
int *ints;
|
||||
loff_t *offsets;
|
||||
char *data;
|
||||
error_t err;
|
||||
mach_msg_type_number_t num_ports = 0, num_ints = 0, num_offsets = 0, data_len = 0;
|
||||
|
||||
file = file_name_lookup (dev, 0, 0);
|
||||
if (file == MACH_PORT_NULL)
|
||||
return 0;
|
||||
|
||||
err = file_get_storage_info (file,
|
||||
&ports, &num_ports,
|
||||
&ints, &num_ints,
|
||||
&offsets, &num_offsets,
|
||||
&data, &data_len);
|
||||
|
||||
if (num_ints < 1)
|
||||
grub_util_error (_("Storage info for `%s' does not include type"), dev);
|
||||
if (ints[0] != STORAGE_DEVICE)
|
||||
grub_util_error (_("`%s' is not a local disk"), dev);
|
||||
|
||||
if (num_offsets != 2)
|
||||
grub_util_error (_("Storage info for `%s' does indicate neither plain partition nor plain disk"), dev);
|
||||
if (parent)
|
||||
{
|
||||
*parent = NULL;
|
||||
if (num_ints >= 5)
|
||||
{
|
||||
size_t len = ints[4];
|
||||
if (len > data_len)
|
||||
len = data_len;
|
||||
*parent = xmalloc (len+1);
|
||||
memcpy (*parent, data, len);
|
||||
(*parent)[len] = '\0';
|
||||
}
|
||||
}
|
||||
if (offset)
|
||||
*offset = offsets[0];
|
||||
if (size)
|
||||
*size = offsets[1];
|
||||
if (secsize)
|
||||
*secsize = ints[2];
|
||||
if (ports && num_ports > 0)
|
||||
{
|
||||
mach_msg_type_number_t i;
|
||||
for (i = 0; i < num_ports; i++)
|
||||
{
|
||||
mach_port_t port = ports[i];
|
||||
if (port != MACH_PORT_NULL)
|
||||
mach_port_deallocate (mach_task_self(), port);
|
||||
}
|
||||
munmap ((caddr_t) ports, num_ports * sizeof (*ports));
|
||||
}
|
||||
|
||||
if (ints && num_ints > 0)
|
||||
munmap ((caddr_t) ints, num_ints * sizeof (*ints));
|
||||
if (offsets && num_offsets > 0)
|
||||
munmap ((caddr_t) offsets, num_offsets * sizeof (*offsets));
|
||||
if (data && data_len > 0)
|
||||
munmap (data, data_len);
|
||||
mach_port_deallocate (mach_task_self (), file);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
grub_uint32_t sector_size;
|
||||
grub_disk_addr_t size;
|
||||
unsigned log_sector_size;
|
||||
|
||||
if (!grub_util_hurd_get_disk_info (name, §or_size, NULL, &size, NULL))
|
||||
return -1;
|
||||
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
return size << log_sector_size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,362 +0,0 @@
|
|||
/* hostdisk.c - emulate biosdisk */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# include <sys/mount.h>
|
||||
# ifndef BLKFLSBUF
|
||||
# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */
|
||||
# endif /* ! BLKFLSBUF */
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# ifndef HDIO_GETGEO
|
||||
# define HDIO_GETGEO 0x0301 /* get device geometry */
|
||||
/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
|
||||
defined. */
|
||||
struct hd_geometry
|
||||
{
|
||||
unsigned char heads;
|
||||
unsigned char sectors;
|
||||
unsigned short cylinders;
|
||||
unsigned long start;
|
||||
};
|
||||
# endif /* ! HDIO_GETGEO */
|
||||
# ifndef BLKGETSIZE64
|
||||
# define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size */
|
||||
# endif /* ! BLKGETSIZE64 */
|
||||
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
unsigned long long nr;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
if (ioctl (fd, BLKGETSIZE64, &nr))
|
||||
return -1;
|
||||
|
||||
if (ioctl (fd, BLKSSZGET, §or_size))
|
||||
return -1;
|
||||
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
if (nr & ((1 << log_sector_size) - 1))
|
||||
grub_util_error ("%s", _("unaligned device size"));
|
||||
|
||||
return nr;
|
||||
}
|
||||
|
||||
grub_disk_addr_t
|
||||
grub_util_find_partition_start_os (const char *dev)
|
||||
{
|
||||
grub_util_fd_t fd;
|
||||
struct hd_geometry hdg;
|
||||
|
||||
fd = open (dev, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"),
|
||||
dev, strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl (fd, HDIO_GETGEO, &hdg))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
"cannot get disk geometry of `%s'", dev);
|
||||
close (fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
||||
return hdg.start;
|
||||
}
|
||||
|
||||
/* Cache of partition start sectors for each disk. */
|
||||
struct linux_partition_cache
|
||||
{
|
||||
struct linux_partition_cache *next;
|
||||
struct linux_partition_cache **prev;
|
||||
char *dev;
|
||||
unsigned long start;
|
||||
int partno;
|
||||
};
|
||||
|
||||
struct linux_partition_cache *linux_partition_cache_list;
|
||||
|
||||
/* Check if we have devfs support. */
|
||||
static int
|
||||
have_devfs (void)
|
||||
{
|
||||
static int dev_devfsd_exists = -1;
|
||||
|
||||
if (dev_devfsd_exists < 0)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
|
||||
}
|
||||
|
||||
return dev_devfsd_exists;
|
||||
}
|
||||
|
||||
int
|
||||
grub_hostdisk_linux_find_partition (char *dev, grub_disk_addr_t sector)
|
||||
{
|
||||
size_t len = strlen (dev);
|
||||
const char *format;
|
||||
char *p;
|
||||
int i;
|
||||
char real_dev[PATH_MAX];
|
||||
struct linux_partition_cache *cache;
|
||||
int missing = 0;
|
||||
|
||||
strcpy(real_dev, dev);
|
||||
|
||||
if (have_devfs () && strcmp (real_dev + len - 5, "/disc") == 0)
|
||||
{
|
||||
p = real_dev + len - 4;
|
||||
format = "part%d";
|
||||
}
|
||||
else if (strncmp (real_dev, "/dev/disk/by-id/",
|
||||
sizeof ("/dev/disk/by-id/") - 1) == 0)
|
||||
{
|
||||
p = real_dev + len;
|
||||
format = "-part%d";
|
||||
}
|
||||
else if (real_dev[len - 1] >= '0' && real_dev[len - 1] <= '9')
|
||||
{
|
||||
p = real_dev + len;
|
||||
format = "p%d";
|
||||
}
|
||||
else
|
||||
{
|
||||
p = real_dev + len;
|
||||
format = "%d";
|
||||
}
|
||||
|
||||
for (cache = linux_partition_cache_list; cache; cache = cache->next)
|
||||
{
|
||||
if (strcmp (cache->dev, dev) == 0 && cache->start == sector)
|
||||
{
|
||||
sprintf (p, format, cache->partno);
|
||||
strcpy (dev, real_dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i < 10000; i++)
|
||||
{
|
||||
grub_util_fd_t fd;
|
||||
grub_disk_addr_t start;
|
||||
|
||||
sprintf (p, format, i);
|
||||
|
||||
fd = open (real_dev, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (missing++ < 10)
|
||||
continue;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
missing = 0;
|
||||
close (fd);
|
||||
|
||||
if (!grub_util_device_is_mapped (real_dev)
|
||||
|| !grub_util_get_dm_node_linear_info (real_dev, 0, 0, &start))
|
||||
start = grub_util_find_partition_start_os (real_dev);
|
||||
/* We don't care about errors here. */
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
if (start == sector)
|
||||
{
|
||||
struct linux_partition_cache *new_cache_item;
|
||||
|
||||
new_cache_item = xmalloc (sizeof *new_cache_item);
|
||||
new_cache_item->dev = xstrdup (dev);
|
||||
new_cache_item->start = start;
|
||||
new_cache_item->partno = i;
|
||||
grub_list_push (GRUB_AS_LIST_P (&linux_partition_cache_list),
|
||||
GRUB_AS_LIST (new_cache_item));
|
||||
|
||||
strcpy (dev, real_dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev)
|
||||
{
|
||||
grub_util_fd_t fd;
|
||||
struct stat st;
|
||||
|
||||
fd = open (os_dev, O_RDONLY);
|
||||
if (fd >= 0 && fstat (fd, &st) >= 0 && S_ISBLK (st.st_mode))
|
||||
ioctl (fd, BLKFLSBUF, 0);
|
||||
if (fd >= 0)
|
||||
close (fd);
|
||||
}
|
||||
|
||||
int
|
||||
grub_util_fd_open_device (const grub_disk_t disk, grub_disk_addr_t sector, int flags,
|
||||
grub_disk_addr_t *max)
|
||||
{
|
||||
grub_util_fd_t fd;
|
||||
struct grub_util_hostdisk_data *data = disk->data;
|
||||
|
||||
*max = ~0ULL;
|
||||
|
||||
#ifdef O_LARGEFILE
|
||||
flags |= O_LARGEFILE;
|
||||
#endif
|
||||
#ifdef O_SYNC
|
||||
flags |= O_SYNC;
|
||||
#endif
|
||||
#ifdef O_FSYNC
|
||||
flags |= O_FSYNC;
|
||||
#endif
|
||||
#ifdef O_BINARY
|
||||
flags |= O_BINARY;
|
||||
#endif
|
||||
|
||||
/* Linux has a bug that the disk cache for a whole disk is not consistent
|
||||
with the one for a partition of the disk. */
|
||||
{
|
||||
int is_partition = 0;
|
||||
char dev[PATH_MAX];
|
||||
grub_disk_addr_t part_start = 0;
|
||||
|
||||
part_start = grub_partition_get_start (disk->partition);
|
||||
|
||||
strcpy (dev, grub_util_biosdisk_get_osdev (disk));
|
||||
if (disk->partition
|
||||
&& strncmp (dev, "/dev/", 5) == 0)
|
||||
{
|
||||
if (sector >= part_start)
|
||||
is_partition = grub_hostdisk_linux_find_partition (dev, part_start);
|
||||
else
|
||||
*max = part_start - sector;
|
||||
}
|
||||
|
||||
reopen:
|
||||
|
||||
if (data->dev && strcmp (data->dev, dev) == 0 &&
|
||||
data->access_mode == (flags & O_ACCMODE))
|
||||
{
|
||||
grub_dprintf ("hostdisk", "reusing open device `%s'\n", dev);
|
||||
fd = data->fd;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (data->dev);
|
||||
data->dev = 0;
|
||||
if (data->fd != -1)
|
||||
{
|
||||
if (data->access_mode == O_RDWR || data->access_mode == O_WRONLY)
|
||||
{
|
||||
fsync (data->fd);
|
||||
if (data->is_disk)
|
||||
ioctl (data->fd, BLKFLSBUF, 0);
|
||||
}
|
||||
|
||||
close (data->fd);
|
||||
data->fd = -1;
|
||||
}
|
||||
|
||||
/* Open the partition. */
|
||||
grub_dprintf ("hostdisk", "opening the device `%s' in open_device()\n", dev);
|
||||
fd = open (dev, flags);
|
||||
if (fd < 0)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot open `%s': %s"),
|
||||
dev, strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->dev = xstrdup (dev);
|
||||
data->access_mode = (flags & O_ACCMODE);
|
||||
data->fd = fd;
|
||||
|
||||
if (data->is_disk)
|
||||
ioctl (data->fd, BLKFLSBUF, 0);
|
||||
}
|
||||
|
||||
if (is_partition)
|
||||
{
|
||||
*max = grub_util_get_fd_size (fd, dev, 0);
|
||||
*max >>= disk->log_sector_size;
|
||||
if (sector - part_start >= *max)
|
||||
{
|
||||
*max = disk->partition->len - (sector - part_start);
|
||||
if (*max == 0)
|
||||
*max = ~0ULL;
|
||||
is_partition = 0;
|
||||
strcpy (dev, grub_util_biosdisk_get_osdev (disk));
|
||||
goto reopen;
|
||||
}
|
||||
sector -= part_start;
|
||||
*max -= sector;
|
||||
}
|
||||
}
|
||||
|
||||
if (grub_util_fd_seek (fd, grub_util_biosdisk_get_osdev (disk),
|
||||
sector << disk->log_sector_size))
|
||||
{
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#ifdef __linux__
|
||||
#include "hostdisk_linux.c"
|
||||
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
#include "hostdisk_freebsd.c"
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include "hostdisk_bsd.c"
|
||||
#elif defined(__APPLE__)
|
||||
#include "hostdisk_apple.c"
|
||||
#elif defined(__sun__)
|
||||
#include "hostdisk_sun.c"
|
||||
#elif defined(__GNU__)
|
||||
#include "hostdisk_hurd.c"
|
||||
#elif defined(__CYGWIN__) || defined(__MINGW32__)
|
||||
#include "hostdisk_windows.c"
|
||||
#elif defined(__AROS__)
|
||||
#include "hostdisk_aros.c"
|
||||
#else
|
||||
# warning "No hostdisk OS-specific functions is available for your system. Device detection may not work properly."
|
||||
#include "hostdisk_basic.c"
|
||||
#endif
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
# include <sys/dkio.h>
|
||||
|
||||
grub_int64_t
|
||||
grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
struct dk_minfo minfo;
|
||||
unsigned sector_size, log_sector_size;
|
||||
|
||||
if (!ioctl (fd, DKIOCGMEDIAINFO, &minfo))
|
||||
return -1;
|
||||
|
||||
sector_size = minfo.dki_lbsize;
|
||||
|
||||
if (sector_size & (sector_size - 1) || !sector_size)
|
||||
return -1;
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < sector_size;
|
||||
log_sector_size++);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
return minfo.dki_capacity << log_sector_size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/* hostdisk.c - emulate biosdisk */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if !defined (__CYGWIN__) && !defined (__MINGW32__) && !defined (__AROS__)
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/ioctl.h> /* ioctl */
|
||||
# include <sys/mount.h>
|
||||
# if !defined(__GLIBC__) || \
|
||||
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
|
||||
/* Maybe libc doesn't have large file support. */
|
||||
# include <linux/unistd.h> /* _llseek */
|
||||
# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
|
||||
# ifndef BLKFLSBUF
|
||||
# define BLKFLSBUF _IO (0x12,97) /* flush buffer cache */
|
||||
# endif /* ! BLKFLSBUF */
|
||||
#endif /* __linux__ */
|
||||
|
||||
grub_uint64_t
|
||||
grub_util_get_fd_size (grub_util_fd_t fd, const char *name, unsigned *log_secsize)
|
||||
{
|
||||
struct stat st;
|
||||
grub_int64_t ret = -1;
|
||||
|
||||
if (fstat (fd, &st) < 0)
|
||||
/* TRANSLATORS: "stat" comes from the name of POSIX function. */
|
||||
grub_util_error (_("cannot stat `%s': %s"), name, strerror (errno));
|
||||
#if GRUB_DISK_DEVS_ARE_CHAR
|
||||
if (S_ISCHR (st.st_mode))
|
||||
#else
|
||||
if (S_ISBLK (st.st_mode))
|
||||
#endif
|
||||
ret = grub_util_get_fd_size_os (fd, name, log_secsize);
|
||||
if (ret != -1LL)
|
||||
return ret;
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = 9;
|
||||
|
||||
return st.st_size;
|
||||
}
|
||||
|
||||
#if defined(__linux__) && (!defined(__GLIBC__) || \
|
||||
((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
|
||||
/* Maybe libc doesn't have large file support. */
|
||||
grub_err_t
|
||||
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
|
||||
{
|
||||
loff_t offset, result;
|
||||
static int _llseek (uint filedes, ulong hi, ulong lo,
|
||||
loff_t *res, uint wh);
|
||||
_syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
|
||||
loff_t *, res, uint, wh);
|
||||
|
||||
offset = (loff_t) off;
|
||||
if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
|
||||
name, strerror (errno));
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
#else
|
||||
grub_err_t
|
||||
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
|
||||
{
|
||||
off_t offset = (off_t) off;
|
||||
|
||||
if (lseek (fd, offset, SEEK_SET) != offset)
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
|
||||
name, strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
|
||||
error occurs, otherwise return LEN. */
|
||||
ssize_t
|
||||
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
|
||||
{
|
||||
ssize_t size = len;
|
||||
|
||||
while (len)
|
||||
{
|
||||
ssize_t ret = read (fd, buf, len);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
|
||||
error occurs, otherwise return LEN. */
|
||||
ssize_t
|
||||
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
|
||||
{
|
||||
ssize_t size = len;
|
||||
|
||||
while (len)
|
||||
{
|
||||
ssize_t ret = write (fd, buf, len);
|
||||
|
||||
if (ret <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
len -= ret;
|
||||
buf += ret;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
grub_util_fd_t
|
||||
grub_util_fd_open (const char *os_dev, int flags)
|
||||
{
|
||||
return open (os_dev, flags);
|
||||
}
|
||||
|
||||
const char *
|
||||
grub_util_fd_strerror (void)
|
||||
{
|
||||
return strerror (errno);
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_sync (grub_util_fd_t fd)
|
||||
{
|
||||
fsync (fd);
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_close (grub_util_fd_t fd)
|
||||
{
|
||||
close (fd);
|
||||
}
|
||||
|
||||
char *
|
||||
canonicalize_file_name (const char *path)
|
||||
{
|
||||
#if defined (PATH_MAX)
|
||||
char *ret;
|
||||
|
||||
ret = xmalloc (PATH_MAX);
|
||||
if (!realpath (path, ret))
|
||||
return NULL;
|
||||
return ret;
|
||||
#else
|
||||
return realpath (path, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,257 +0,0 @@
|
|||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB 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.
|
||||
*
|
||||
* GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config-util.h>
|
||||
|
||||
#include <grub/disk.h>
|
||||
#include <grub/partition.h>
|
||||
#include <grub/msdos_partition.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
#include <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/emu/getroot.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/list.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <grub/util/windows.h>
|
||||
#include <grub/charset.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
LPTSTR
|
||||
grub_util_get_windows_path (const char *path)
|
||||
{
|
||||
LPTSTR winpath;
|
||||
winpath = xmalloc (sizeof (winpath[0]) * PATH_MAX);
|
||||
if (cygwin_conv_path ((sizeof (winpath[0]) == 1 ? CCP_POSIX_TO_WIN_A
|
||||
: CCP_POSIX_TO_WIN_W) | CCP_ABSOLUTE, path, winpath,
|
||||
sizeof (winpath[0]) * PATH_MAX))
|
||||
grub_util_error ("%s", _("cygwin_conv_path() failed"));
|
||||
return winpath;
|
||||
}
|
||||
#else
|
||||
LPTSTR
|
||||
grub_util_get_windows_path (const char *path)
|
||||
{
|
||||
char *fpa;
|
||||
const char *fp;
|
||||
LPTSTR ret;
|
||||
|
||||
fp = fpa = xmalloc (PATH_MAX);
|
||||
if (!_fullpath (fpa, path, PATH_MAX))
|
||||
fp = path;
|
||||
#if SIZEOF_TCHAR == 1
|
||||
ret = xstrdup (fp);
|
||||
#elif SIZEOF_TCHAR == 2
|
||||
size_t ssz = strlen (fp);
|
||||
size_t tsz = 2 * (GRUB_MAX_UTF16_PER_UTF8 * ssz + 1);
|
||||
ret = xmalloc (tsz);
|
||||
tsz = grub_utf8_to_utf16 (ret, tsz, (const grub_uint8_t *) fp, ssz, NULL);
|
||||
ret[tsz] = 0;
|
||||
#else
|
||||
#error SIZEOF_TCHAR
|
||||
#error "Unsupported TCHAR size"
|
||||
#endif
|
||||
|
||||
free (fpa);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
grub_uint64_t
|
||||
grub_util_get_fd_size (grub_util_fd_t hd, const char *name_in,
|
||||
unsigned *log_secsize)
|
||||
{
|
||||
grub_int64_t size = -1LL;
|
||||
int log_sector_size = 9;
|
||||
LPTSTR name = grub_util_get_windows_path (name_in);
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
if (((name[0] == '/') || (name[0] == '\\')) &&
|
||||
((name[1] == '/') || (name[1] == '\\')) &&
|
||||
((name[2] == '.') || (name[2] == '?')) &&
|
||||
((name[3] == '/') || (name[3] == '\\')))
|
||||
{
|
||||
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;
|
||||
|
||||
for (log_sector_size = 0;
|
||||
(1 << log_sector_size) < g.BytesPerSector;
|
||||
log_sector_size++);
|
||||
}
|
||||
else
|
||||
{
|
||||
ULARGE_INTEGER s;
|
||||
|
||||
s.LowPart = GetFileSize (hd, &s.HighPart);
|
||||
size = s.QuadPart;
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
if (log_secsize)
|
||||
*log_secsize = log_sector_size;
|
||||
|
||||
free (name);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_configure_device_driver (grub_util_fd_t fd __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
grub_hostdisk_flush_initial_buffer (const char *os_dev __attribute__ ((unused)))
|
||||
{
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
grub_util_fd_seek (grub_util_fd_t fd, const char *name, grub_uint64_t off)
|
||||
{
|
||||
LARGE_INTEGER offset;
|
||||
offset.QuadPart = off;
|
||||
|
||||
if (!SetFilePointerEx (fd, offset, NULL, FILE_BEGIN))
|
||||
return grub_error (GRUB_ERR_BAD_DEVICE, N_("cannot seek `%s': %s"),
|
||||
name, strerror (errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_util_fd_t
|
||||
grub_util_fd_open (const char *os_dev, int flags)
|
||||
{
|
||||
DWORD flg = 0;
|
||||
LPTSTR dev = grub_util_get_windows_path (os_dev);
|
||||
grub_util_fd_t ret;
|
||||
|
||||
if (flags & O_WRONLY)
|
||||
flg |= GENERIC_WRITE;
|
||||
if (flags & O_RDONLY)
|
||||
flg |= GENERIC_READ;
|
||||
flg = GENERIC_READ;
|
||||
ret = CreateFile (dev, flg, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0, OPEN_EXISTING, 0, 0);
|
||||
free (dev);
|
||||
grub_util_info ("handle = %p", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
grub_util_fd_read (grub_util_fd_t fd, char *buf, size_t len)
|
||||
{
|
||||
DWORD real_read;
|
||||
if (!ReadFile(fd, buf, len, &real_read, NULL))
|
||||
{
|
||||
grub_util_info ("read err %x", (int) GetLastError ());
|
||||
return -1;
|
||||
}
|
||||
grub_util_info ("successful read");
|
||||
return real_read;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
grub_util_fd_write (grub_util_fd_t fd, const char *buf, size_t len)
|
||||
{
|
||||
DWORD real_read;
|
||||
if (!WriteFile(fd, buf, len, &real_read, NULL))
|
||||
{
|
||||
grub_util_info ("write err %x", (int) GetLastError ());
|
||||
return -1;
|
||||
}
|
||||
|
||||
grub_util_info ("successful write");
|
||||
return real_read;
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_sync (grub_util_fd_t fd)
|
||||
{
|
||||
FlushFileBuffers (fd);
|
||||
}
|
||||
|
||||
void
|
||||
grub_util_fd_close (grub_util_fd_t fd)
|
||||
{
|
||||
CloseHandle (fd);
|
||||
}
|
||||
|
||||
const char *
|
||||
grub_util_fd_strerror (void)
|
||||
{
|
||||
DWORD err;
|
||||
static TCHAR tbuf[1024];
|
||||
err = GetLastError ();
|
||||
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, err,
|
||||
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
tbuf, ARRAY_SIZE (tbuf), NULL);
|
||||
|
||||
#if SIZEOF_TCHAR == 1
|
||||
return (char *) tbuf;
|
||||
#elif SIZEOF_TCHAR == 2
|
||||
static grub_uint8_t buf[ARRAY_SIZE (tbuf) * GRUB_MAX_UTF8_PER_UTF16 + 1];
|
||||
*grub_utf16_to_utf8 (buf, tbuf, ARRAY_SIZE (tbuf)) = '\0';
|
||||
return (char *) buf;
|
||||
#else
|
||||
#error "Unsupported TCHAR size"
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
canonicalize_file_name (const char *path)
|
||||
{
|
||||
char *ret;
|
||||
ret = xmalloc (PATH_MAX);
|
||||
|
||||
#ifndef __CYGWIN__
|
||||
if (!_fullpath (ret, path, PATH_MAX))
|
||||
return NULL;
|
||||
#else
|
||||
if (!realpath (path, ret))
|
||||
return NULL;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue