be nearer to original
[grub2/phcoder.git] / parttool / pcpart.c
blob6876d0d58de0a72ea6a048d30972373f6f6ef6f5
1 /* pcpart.c - manipulate fdisk partitions */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * This program 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 2 of the License, or
9 * (at your option) any later version.
11 * This program 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 this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include <grub/types.h>
22 #include <grub/misc.h>
23 #include <grub/mm.h>
24 #include <grub/err.h>
25 #include <grub/pc_partition.h>
26 #include <grub/device.h>
27 #include <grub/disk.h>
28 #include <grub/partition.h>
29 #include <grub/parttool.h>
31 static int activate_table_handle = -1;
32 static int type_table_handle = -1;
34 static struct grub_parttool_argdesc grub_pcpart_bootargs[] =
36 {"boot", "Make partition active", GRUB_PARTTOOL_ARG_BOOL},
37 {0, 0, 0}
40 static grub_err_t grub_pcpart_boot (const grub_device_t dev,
41 const struct grub_parttool_args *args)
43 int i, index;
44 grub_partition_t part;
45 struct grub_pc_partition_mbr mbr;
47 if (dev->disk->partition->offset)
48 return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a primary partition");
50 index = dev->disk->partition->index;
51 part = dev->disk->partition;
52 dev->disk->partition = 0;
54 /* Read the MBR. */
55 if (grub_disk_read (dev->disk, 0, 0, sizeof (mbr), &mbr))
57 dev->disk->partition = part;
58 return grub_errno;
61 if (args[0].set && args[0].bool)
63 for (i = 0; i < 4; i++)
64 mbr.entries[i].flag = 0x0;
65 mbr.entries[index].flag = 0x80;
66 grub_printf ("Partition %d is active now. \n", index);
68 else
70 mbr.entries[index].flag = 0x0;
71 grub_printf ("Cleared active flag on %d. \n", index);
74 /* Write the MBR. */
75 grub_disk_write (dev->disk, 0, 0, sizeof (mbr), &mbr);
77 dev->disk->partition = part;
79 return GRUB_ERR_NONE;
82 static struct grub_parttool_argdesc grub_pcpart_typeargs[] =
84 {"type", "Change partition type", GRUB_PARTTOOL_ARG_VAL},
85 {"hidden", "Make partition hidden", GRUB_PARTTOOL_ARG_BOOL},
86 {0, 0, 0}
89 static grub_err_t grub_pcpart_type (const grub_device_t dev,
90 const struct grub_parttool_args *args)
92 int index;
93 grub_uint8_t type;
94 grub_partition_t part;
95 struct grub_pc_partition_mbr mbr;
97 index = dev->disk->partition->index;
98 part = dev->disk->partition;
99 dev->disk->partition = 0;
101 /* Read the parttable. */
102 if (grub_disk_read (dev->disk, part->offset, 0,
103 sizeof (mbr), &mbr))
105 dev->disk->partition = part;
106 return grub_errno;
109 if (args[0].set)
110 type = grub_strtoul (args[0].str, 0, 0);
111 else
112 type = mbr.entries[index].type;
114 if (args[1].set)
116 if (args[1].bool)
117 type |= GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
118 else
119 type &= ~GRUB_PC_PARTITION_TYPE_HIDDEN_FLAG;
122 if (grub_pc_partition_is_empty (type)
123 || grub_pc_partition_is_extended (type))
125 dev->disk->partition = part;
126 return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid type");
129 mbr.entries[index].type = type;
130 grub_printf ("Setting partition type to 0x%x\n", type);
132 /* Write the parttable. */
133 grub_disk_write (dev->disk, part->offset, 0,
134 sizeof (mbr), &mbr);
136 dev->disk->partition = part;
138 return GRUB_ERR_NONE;
141 GRUB_MOD_INIT (pcpart)
143 activate_table_handle = grub_parttool_register ("pc_partition_map",
144 grub_pcpart_boot,
145 grub_pcpart_bootargs);
146 type_table_handle = grub_parttool_register ("pc_partition_map",
147 grub_pcpart_type,
148 grub_pcpart_typeargs);
151 GRUB_MOD_FINI(pcpart)
153 grub_parttool_unregister (activate_table_handle);
154 grub_parttool_unregister (type_table_handle);