首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用C++挂载vfat镜像win linux

使用C++挂载vfat镜像win linux
EN

Stack Overflow用户
提问于 2020-02-19 04:02:39
回答 3查看 501关注 0票数 2

我正在尝试使用.C从DOS挂载一个vfat磁盘映像

代码语言:javascript
复制
if( mount( "/mypath/disk.img", "/mypath/img/", "vfat", MS_DIRSYNC | MS_SYNCHRONOUS, "utf8" ) ) { 
  printf( "Error mount %s errno=%d %s\n", dst.c_str(), errno, strerror( errno ) );
}

我总是收到错误消息"Block device required“。我应该添加一些参数或标志吗?

注意:我可以从bash挂载相同目标中的相同文件,而不会出现任何错误。

更新:我使用这个函数挂载了一个ISO,获得了一些不错的结果。当我运行程序时,它仍然堆叠在调用ioctl(loop_device_fd, LOOP_CLR_FD, 0);上。当我退出程序(ctrl-c)时,将挂载映像。是否有必要使用LOOP_CLR_FD来完成所有步骤?此外,它是以只读方式挂载的,似乎不可能在读/写模式下更改它。

代码语言:javascript
复制
const auto loop_control = std::fopen( "/dev/loop-control", "r" );
const auto loop_control_fd = fileno(loop_control);
const auto devnr = ioctl(loop_control_fd, LOOP_CTL_GET_FREE);
std::stringstream loopname;
loopname << "/dev/loop" << devnr;
const auto loop_device_name = loopname.str();
const auto loop_device = std::fopen(loop_device_name.c_str(), "r");
const auto loop_device_fd = fileno(loop_device);
const auto image = std::fopen( dst.c_str(), "r" );
const auto image_fd = fileno(image);
//Associate the loop device with the open file whose file descriptor is passed as the (third) ioctl(2) argument.
ioctl(loop_device_fd, LOOP_SET_FD, image_fd);
const auto result = mount(loop_device_name.c_str(), dst_path_img.c_str(), "vfat", MS_RDONLY, NULL);
if( result ) {
printf( "Error mount %s errno=%d %s\n", dst.c_str(), errno, strerror( errno ) );
return;
}
ioctl(loop_device_fd, LOOP_CLR_FD, 0);
EN

回答 3

Stack Overflow用户

发布于 2020-02-20 04:51:13

来自上面链接的示例代码似乎可以很好地挂载您的镜像,只需稍作修改即可检索自由循环设备(我假设它是来自allbootdisks.com的Dos3.3磁盘镜像):

代码语言:javascript
复制
#include <sys/mount.h>
#include <linux/loop.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main()
{
    int control_fd, file_fd, device_fd;
    char loop_device[16];

    control_fd = open("/dev/loop-control", O_RDWR);
    if (control_fd < 0) {
        perror("open loop control device failed");
        return 1;
    }

    int loop_id = ioctl(control_fd, LOOP_CTL_GET_FREE);
    sprintf(loop_device, "/dev/loop%d", loop_id);
    close(control_fd);

    printf("using loop device: %s\n", loop_device);

    file_fd = open("./Dos3.3.img", O_RDWR);
    if (file_fd < 0) {
        perror("open backing file failed");
        return 1;
    }

    device_fd = open(loop_device, O_RDWR);
    if (device_fd < 0) {
        perror("open loop device failed");
        close(file_fd);
        return 1;
    }

    if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
        perror("ioctl LOOP_SET_FD failed");
        close(file_fd);
        close(device_fd);
        return 1;
    }

    close(file_fd);

    if (mount(loop_device, "./mnt/", "vfat", MS_DIRSYNC | MS_SYNCHRONOUS, "") < 0) {
        perror("mount failed");
    } else {
        printf("mount successful\n");
    }

    // always free loop device in the end
    ioctl(device_fd, LOOP_CLR_FD, 0);      
    close(device_fd);
}
票数 2
EN

Stack Overflow用户

发布于 2020-02-19 04:21:45

这里的问题是,您正在尝试挂载映像,就像您使用块设备所做的那样。与镜像文件相比,块设备与操作系统的绑定更多,因此您需要找到一种方法来解决这个问题。

尝试环回设备!环回设备可以为您提供对该镜像/mypath/disk.img作为块设备的操作系统引用。您可以在bash中创建环回设备,如下所示:

代码语言:javascript
复制
# set up a block device
losetup -fP /mypath/disk.img
# now list the loopback devices 
losetup -a

无论如何,这个解决方案是在bash中的,但是肯定有一个用于c的库。

票数 1
EN

Stack Overflow用户

发布于 2020-02-19 04:23:56

由于磁盘镜像不是真正的设备,因此无法直接挂载。您要做的是通过循环设备进行挂载。命令行的等价物是:mount /mypath/disk.img /mypath/img -t vfat -o loop

我不确定,但是尝试添加"loop, utf8"作为最后一个参数是否可以解决这个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60288602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档