Example #1
0
void diskdrive_add_drive(disk_interface_t* disk)
{
	unsigned char drive = get_drive_number(disk->volume.lvn);

	if(drive < DISKDRIVE_NUM_DRIVES && !disks[drive])
	{
		disks[drive] = disk;
	}
}
Example #2
0
static grub_err_t
grub_efidisk_open (const char *name, struct grub_disk *disk)
{
  int num;
  struct grub_efidisk_data *d = 0;
  grub_efi_block_io_media_t *m;

  grub_dprintf ("efidisk", "opening %s\n", name);

  num = get_drive_number (name);
  if (num < 0)
    return grub_errno;

  switch (name[0])
    {
    case 'f':
      d = get_device (fd_devices, num);
      break;
    case 'c':
      d = get_device (cd_devices, num);
      break;
    case 'h':
      d = get_device (hd_devices, num);
      break;
    default:
      /* Never reach here.  */
      break;
    }

  if (! d)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");

  disk->id = ((num << GRUB_CHAR_BIT) | name[0]);
  m = d->block_io->media;
  /* FIXME: Probably it is better to store the block size in the disk,
     and total sectors should be replaced with total blocks.  */
  grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
		m, (unsigned long long) m->last_block, m->block_size);
  disk->total_sectors = m->last_block + 1;
  if (m->block_size & (m->block_size - 1) || !m->block_size)
    return grub_error (GRUB_ERR_IO, "invalid sector size %d",
		       m->block_size);
  for (disk->log_sector_size = 0;
       (1U << disk->log_sector_size) < m->block_size;
       disk->log_sector_size++);
  disk->data = d;

  grub_dprintf ("efidisk", "opening %s succeeded\n", name);

  return GRUB_ERR_NONE;
}
Example #3
0
static grub_err_t
grub_efidisk_open (const char *name, struct grub_disk *disk)
{
  int num;
  struct grub_efidisk_data *d = 0;
  grub_efi_block_io_media_t *m;

  grub_dprintf ("efidisk", "opening %s\n", name);
  
  num = get_drive_number (name);
  if (num < 0)
    return grub_errno;

  switch (name[0])
    {
    case 'f':
      disk->has_partitions = 0;
      d = get_device (fd_devices, num);
      break;
    case 'c':
      /* FIXME: a CDROM should have partitions, but not implemented yet.  */
      disk->has_partitions = 0;
      d = get_device (cd_devices, num);
      break;
    case 'h':
      disk->has_partitions = 1;
      d = get_device (hd_devices, num);
      break;
    default:
      /* Never reach here.  */
      break;
    }

  if (! d)
    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no such device");

  disk->id = ((num << 8) | name[0]);
  m = d->block_io->media;
  /* FIXME: Probably it is better to store the block size in the disk,
     and total sectors should be replaced with total blocks.  */
  grub_dprintf ("efidisk", "m = %p, last block = %llx, block size = %x\n",
		m, (unsigned long long) m->last_block, m->block_size);
  disk->total_sectors = (m->last_block
			 * (m->block_size >> GRUB_DISK_SECTOR_BITS));
  disk->data = d;

  grub_dprintf ("efidisk", "opening %s succeeded\n", name);

  return GRUB_ERR_NONE;
}
Example #4
0
int diskdrive_chdrive(const char* lvn)
{
	unsigned char drive = get_drive_number(lvn);
	disk_interface_t* disk = diskdrive_get_disk(drive);

	if(disk)
	{
		if(f_chdrive(disk->volume.lvn) == FR_OK)
		{
			current_drive = drive;
			return 0;
		}
	}
	return -1;
}
Example #5
0
posix_errno_t efile_read_info(const efile_path_t *path, int follow_links, efile_fileinfo_t *result) {
    BY_HANDLE_FILE_INFORMATION native_file_info;
    DWORD attributes;
    int is_link;

    sys_memset(&native_file_info, 0, sizeof(native_file_info));
    is_link = 0;

    attributes = GetFileAttributesW((WCHAR*)path->data);

    if(attributes == INVALID_FILE_ATTRIBUTES) {
        DWORD last_error = GetLastError();

        /* Querying a network share root fails with ERROR_BAD_NETPATH, so we'll
         * fake it as a directory just like local roots. */
        if(!is_path_root(path) || last_error != ERROR_BAD_NETPATH) {
            return windows_to_posix_errno(last_error);
        }

        attributes = FILE_ATTRIBUTE_DIRECTORY;
    } else if(is_path_root(path)) {
        /* Local (or mounted) roots can be queried with GetFileAttributesW but
         * lack support for GetFileInformationByHandle, so we'll skip that
         * part. */
    } else {
        HANDLE handle;

        if(attributes & FILE_ATTRIBUTE_REPARSE_POINT) {
            is_link = is_name_surrogate(path);
        }

        if(follow_links && is_link) {
            posix_errno_t posix_errno;
            efile_path_t resolved_path;

            posix_errno = internal_read_link(path, &resolved_path);

            if(posix_errno != 0) {
                return posix_errno;
            }

            return efile_read_info(&resolved_path, 0, result);
        }

        handle = CreateFileW((const WCHAR*)path->data, GENERIC_READ,
            FILE_SHARE_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
            NULL);

        /* The old driver never cared whether this succeeded. */
        if(handle != INVALID_HANDLE_VALUE) {
            GetFileInformationByHandle(handle, &native_file_info);
            CloseHandle(handle);
        }

        FILETIME_TO_EPOCH(result->m_time, native_file_info.ftLastWriteTime);
        FILETIME_TO_EPOCH(result->a_time, native_file_info.ftLastAccessTime);
        FILETIME_TO_EPOCH(result->c_time, native_file_info.ftCreationTime);

        if(result->m_time == -EPOCH_DIFFERENCE) {
            /* Default to 1970 just like the old driver. */
            result->m_time = 0;
        }

        if(result->a_time == -EPOCH_DIFFERENCE) {
            result->a_time = result->m_time;
        }

        if(result->c_time == -EPOCH_DIFFERENCE) {
            result->c_time = result->m_time;
        }
    }

    if(is_link) {
        result->type = EFILE_FILETYPE_SYMLINK;
        /* This should be _S_IFLNK, but the old driver always set
         * non-directories to _S_IFREG. */
        result->mode |= _S_IFREG;
    } else if(attributes & FILE_ATTRIBUTE_DIRECTORY) {
        result->type = EFILE_FILETYPE_DIRECTORY;
        result->mode |= _S_IFDIR | _S_IEXEC;
    } else {
        if(is_executable_file(path)) {
            result->mode |= _S_IEXEC;
        }

        result->type = EFILE_FILETYPE_REGULAR;
        result->mode |= _S_IFREG;
    }

    if(!(attributes & FILE_ATTRIBUTE_READONLY)) {
        result->access = EFILE_ACCESS_READ | EFILE_ACCESS_WRITE;
        result->mode |= _S_IREAD | _S_IWRITE;
    } else {
        result->access = EFILE_ACCESS_READ;
        result->mode |= _S_IREAD;
    }

    /* Propagate user mode-bits to group/other fields */
    result->mode |= (result->mode & 0700) >> 3;
    result->mode |= (result->mode & 0700) >> 6;

    result->size =
        ((Uint64)native_file_info.nFileSizeHigh << 32ull) |
        (Uint64)native_file_info.nFileSizeLow;

    result->links = MAX(1, native_file_info.nNumberOfLinks);

    result->major_device = get_drive_number(path);
    result->minor_device = 0;
    result->inode = 0;
    result->uid = 0;
    result->gid = 0;

    return 0;
}