1 /* fs_file.c - Access partition by a file it contains. */
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/disk.h>
22 #include <grub/file.h>
23 #include <grub/misc.h>
25 #include <grub/partition.h>
28 search_fs_file (const char *key
, unsigned long *count
)
30 char *filename
= NULL
;
31 grub_device_t ret
= NULL
;
34 auto int iterate_device (const char *name
);
35 int iterate_device (const char *name
)
42 len
= grub_strlen (name
) + 2 + grub_strlen (key
) + 1;
43 filename
= grub_realloc (filename
, len
);
47 grub_sprintf (filename
, "(%s)%s", name
, key
);
48 file
= grub_file_open (filename
);
51 grub_file_close (file
);
52 ret
= grub_device_open (name
);
56 grub_errno
= GRUB_ERR_NONE
;
60 grub_device_iterate (iterate_device
);
67 grub_fs_file_open (const char *name
, grub_disk_t disk
)
71 if (grub_strncmp (name
, "FILE=", sizeof ("FILE=") - 1))
72 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "not a FILE virtual volume");
74 dev
= search_fs_file (name
+ sizeof ("FILE=") - 1, &disk
->id
);
76 return grub_error (GRUB_ERR_UNKNOWN_DEVICE
, "no matching file found");
78 disk
->total_sectors
= dev
->disk
->total_sectors
;
79 disk
->has_partitions
= 0;
80 if (dev
->disk
->partition
)
82 disk
->partition
= grub_malloc (sizeof (*disk
->partition
));
84 grub_memcpy (disk
->partition
, dev
->disk
->partition
,
85 sizeof (*disk
->partition
));
88 disk
->partition
= NULL
;
96 grub_fs_file_close (grub_disk_t disk
)
98 grub_device_t parent
= disk
->data
;
99 grub_device_close (parent
);
103 grub_fs_file_read (grub_disk_t disk
, grub_disk_addr_t sector
,
104 grub_size_t size
, char *buf
)
106 grub_device_t parent
= disk
->data
;
107 return parent
->disk
->dev
->read (parent
->disk
, sector
, size
, buf
);
111 grub_fs_file_write (grub_disk_t disk
, grub_disk_addr_t sector
,
112 grub_size_t size
, const char *buf
)
114 grub_device_t parent
= disk
->data
;
115 return parent
->disk
->dev
->write (parent
->disk
, sector
, size
, buf
);
118 static struct grub_disk_dev grub_fs_file_dev
= {
120 .id
= GRUB_DISK_DEVICE_FILE_ID
,
121 .open
= grub_fs_file_open
,
122 .close
= grub_fs_file_close
,
123 .read
= grub_fs_file_read
,
124 .write
= grub_fs_file_write
,
128 GRUB_MOD_INIT (fs_file
)
130 grub_disk_dev_register (&grub_fs_file_dev
);
133 GRUB_MOD_FINI (fs_file
)
135 grub_disk_dev_unregister (&grub_fs_file_dev
);