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; } }
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; }
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; }
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; }
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; }