/* * GRUB -- GRand Unified Bootloader * Copyright (C) 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char * grub_util_part_to_disk (const char *dev, struct stat *st __attribute__ ((unused)), int *is_part) { const char *dname; char *ret; struct DosList *dl; struct DeviceNode *dn; struct FileSysStartupMsg *fm; struct DosEnvec *envec; if (dev[0] != '/' || dev[1] != '/' || dev[2] != ':') return xstrdup (dev); dname = dev + 3; dl = LockDosList(LDF_READ); if (!dl) { return xstrdup (dev); } dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname, LDF_DEVICES); UnLockDosList (LDF_READ); if (!dn) return xstrdup (dev); fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup); envec = (struct DosEnvec *) fm->fssm_Environ; if (envec->de_LowCyl == 0) return xstrdup (dev); *is_part = 1; ret = xasprintf ("//:%s/%lx/%lx", fm->fssm_Device, fm->fssm_Unit, (unsigned long) fm->fssm_Flags); return ret; } enum grub_dev_abstraction_types grub_util_get_dev_abstraction_os (const char *os_dev __attribute__((unused))) { return GRUB_DEV_ABSTRACTION_NONE; } int grub_util_pull_device_os (const char *os_dev __attribute__ ((unused)), enum grub_dev_abstraction_types ab __attribute__ ((unused))) { return 0; } char * grub_util_get_grub_dev_os (const char *os_dev __attribute__ ((unused))) { return NULL; } grub_disk_addr_t grub_util_find_partition_start_os (const char *dev) { const char *dname; struct DosList *dl; struct DeviceNode *dn; struct FileSysStartupMsg *fm; struct DosEnvec *envec; if (dev[0] != '/' || dev[1] != '/' || dev[2] != ':') return 0; dname = dev + 3; dl = LockDosList(LDF_READ); if (!dl) { return 0; } dn = (struct DeviceNode *) FindDosEntry (dl, (unsigned char *) dname, LDF_DEVICES); UnLockDosList (LDF_READ); if (!dn) return 0; fm = (struct FileSysStartupMsg *) BADDR(dn->dn_Startup); envec = (struct DosEnvec *) fm->fssm_Environ; return (((grub_uint64_t) envec->de_Surfaces * (grub_uint64_t) envec->de_BlocksPerTrack * (grub_uint64_t) envec->de_LowCyl) * (grub_uint64_t) envec->de_SizeBlock) >> 7; } char * grub_make_system_path_relative_to_its_root (const char *path) { char *p; unsigned char *tmp; char *ret; BPTR lck; if (path[0] == '/' && path[1] == '/' && path[2] == ':') return xstrdup (path); tmp = xmalloc (2048); lck = Lock ((const unsigned char *) path, SHARED_LOCK); if (!lck || !NameFromLock (lck, tmp, 2040)) { free (tmp); tmp = (unsigned char *) xstrdup (path); } if (lck) UnLock (lck); p = strchr ((char *) tmp, ':'); if (!p) return (char *) tmp; if (p[1] == '/' || p[1] == '\0') { ret = xstrdup (p + 1); } else { ret = xmalloc (strlen (p + 1) + 2); ret[0] = '/'; strcpy (ret + 1, p + 1); } free (tmp); return ret; } char ** grub_guess_root_devices (const char *path) { char **os_dev = NULL; struct InfoData id; BPTR lck; struct DeviceList *dl; struct DosList *dl2; size_t sz; const char *nm; lck = Lock ((const unsigned char *) path, SHARED_LOCK); if (!lck) grub_util_info ("Lock(%s) failed", path); if (!lck || !Info (lck, &id)) { char *p; if (lck) UnLock (lck); grub_util_info ("Info(%s) failed", path); os_dev = xmalloc (2 * sizeof (os_dev[0])); sz = strlen (path); os_dev[0] = xmalloc (sz + 5); os_dev[0][0] = '/'; os_dev[0][1] = '/'; os_dev[0][2] = ':'; memcpy (os_dev[0] + 3, path, sz); os_dev[0][sz + 3] = ':'; os_dev[0][sz + 4] = '\0'; p = strchr (os_dev[0] + 3, ':'); *p = '\0'; os_dev[1] = NULL; return os_dev; } dl = BADDR (id.id_VolumeNode); if (!dl->dl_Task) grub_util_error ("unsupported device %s", dl->dl_Name); grub_util_info ("dl=%p, dl->dl_Name=%s, dl->dl_Task=%p", dl, dl->dl_Name, dl->dl_Task); for (dl2 = LockDosList(LDF_READ | LDF_DEVICES); dl2; dl2 = NextDosEntry (dl2, LDF_DEVICES)) { if (dl2->dol_Task == dl->dl_Task) break; } if (lck) UnLock (lck); if (dl2) nm = (char *) dl2->dol_Name; else nm = (char *) dl->dl_Name; grub_util_info ("dl2=%p, nm=%s", dl2, nm); os_dev = xmalloc (2 * sizeof (os_dev[0])); sz = strlen (nm); os_dev[0] = xmalloc (sz + 4); os_dev[0][0] = '/'; os_dev[0][1] = '/'; os_dev[0][2] = ':'; memcpy (os_dev[0] + 3, nm, sz); os_dev[0][sz+3] = '\0'; os_dev[1] = NULL; UnLockDosList (LDF_READ | LDF_DEVICES); return os_dev; } int grub_util_biosdisk_is_floppy (grub_disk_t disk) { const char *dname; dname = grub_util_biosdisk_get_osdev (disk); if (dname[0] != '/' || dname[1] != '/' || dname[2] != ':') return 0; dname += 3; if (strncmp (dname, TD_NAME, sizeof (TD_NAME) - 1) == 0 && (TD_NAME[sizeof (TD_NAME) - 1] == '/' || TD_NAME[sizeof (TD_NAME) - 1] == '\0')) return 1; return 0; }