Version 0.7.0

This commit is contained in:
srs5694
2011-03-12 01:23:12 -05:00
parent 96312236d7
commit bf8950cad0
27 changed files with 1529 additions and 1091 deletions

364
Makefile
View File

@@ -3,13 +3,15 @@ CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64 CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
LDFLAGS+= LDFLAGS+=
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
LIB_SRCS=$(NAMES:=.cc) MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o) LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h) LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CXXFLAGS) DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -luuid -o gdisk $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -luuid -o gdisk
@@ -17,11 +19,14 @@ gdisk: $(LIB_OBJS) gdisk.o gpttext.o
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -luuid -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts
lint: #no pre-reqs lint: #no pre-reqs
lint $(SRCS) lint $(SRCS)
clean: #no pre-reqs clean: #no pre-reqs
rm -f core *.o *~ gdisk sgdisk rm -f core *.o *~ gdisk sgdisk fixparts
# what are the source dependencies # what are the source dependencies
depend: $(SRCS) depend: $(SRCS)
@@ -32,354 +37,3 @@ $(OBJS):
# DO NOT DELETE # DO NOT DELETE
attributes.o: /usr/include/stdint.h /usr/include/features.h
attributes.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
attributes.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
attributes.o: /usr/include/bits/wchar.h /usr/include/stdio.h
attributes.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
attributes.o: /usr/include/libio.h /usr/include/_G_config.h
attributes.o: /usr/include/wchar.h /usr/include/bits/stdio_lim.h
attributes.o: /usr/include/bits/sys_errlist.h attributes.h support.h
attributes.o: /usr/include/stdlib.h /usr/include/sys/types.h
attributes.o: /usr/include/time.h /usr/include/endian.h
attributes.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
attributes.o: /usr/include/sys/select.h /usr/include/bits/select.h
attributes.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
attributes.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
attributes.o: /usr/include/alloca.h
bsd.o: /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h
bsd.o: /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h
bsd.o: /usr/include/gnu/stubs-64.h /usr/include/bits/types.h
bsd.o: /usr/include/bits/typesizes.h /usr/include/libio.h
bsd.o: /usr/include/_G_config.h /usr/include/wchar.h
bsd.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
bsd.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h
bsd.o: /usr/include/endian.h /usr/include/bits/endian.h
bsd.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
bsd.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
bsd.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
bsd.o: /usr/include/bits/pthreadtypes.h /usr/include/alloca.h
bsd.o: /usr/include/stdint.h /usr/include/bits/wchar.h /usr/include/fcntl.h
bsd.o: /usr/include/bits/fcntl.h /usr/include/sys/stat.h
bsd.o: /usr/include/bits/stat.h /usr/include/errno.h
bsd.o: /usr/include/bits/errno.h /usr/include/linux/errno.h
bsd.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h
bsd.o: /usr/include/asm-generic/errno-base.h support.h bsd.h gptpart.h
bsd.o: parttypes.h guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h
bsd.o: attributes.h diskio.h /usr/include/sys/ioctl.h
bsd.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
bsd.o: /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h
bsd.o: /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h
bsd.o: /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h
crc32.o: /usr/include/stdio.h /usr/include/features.h
crc32.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
crc32.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
crc32.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
crc32.o: /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h
crc32.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
crc32.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h
crc32.o: /usr/include/endian.h /usr/include/bits/endian.h
crc32.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
crc32.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
crc32.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
crc32.o: /usr/include/bits/pthreadtypes.h /usr/include/alloca.h crc32.h
crc32.o: /usr/include/stdint.h /usr/include/bits/wchar.h
diskio.o: /usr/include/sys/ioctl.h /usr/include/features.h
diskio.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
diskio.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
diskio.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
diskio.o: /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h
diskio.o: /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h
diskio.o: /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h
diskio.o: /usr/include/stdint.h /usr/include/bits/wchar.h
diskio.o: /usr/include/errno.h /usr/include/bits/errno.h
diskio.o: /usr/include/linux/errno.h /usr/include/asm/errno.h
diskio.o: /usr/include/asm-generic/errno.h
diskio.o: /usr/include/asm-generic/errno-base.h /usr/include/fcntl.h
diskio.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
diskio.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
diskio.o: /usr/include/time.h /usr/include/endian.h
diskio.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
diskio.o: /usr/include/sys/select.h /usr/include/bits/select.h
diskio.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
diskio.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
diskio.o: /usr/include/sys/stat.h /usr/include/bits/stat.h support.h
diskio.o: /usr/include/stdlib.h /usr/include/alloca.h diskio.h parttypes.h
diskio.o: guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h gpt.h
diskio.o: gptpart.h attributes.h mbr.h partnotes.h bsd.h
diskio-unix.o: /usr/include/sys/ioctl.h /usr/include/features.h
diskio-unix.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
diskio-unix.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
diskio-unix.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
diskio-unix.o: /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h
diskio-unix.o: /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h
diskio-unix.o: /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h
diskio-unix.o: /usr/include/string.h /usr/include/xlocale.h
diskio-unix.o: /usr/include/stdint.h /usr/include/bits/wchar.h
diskio-unix.o: /usr/include/errno.h /usr/include/bits/errno.h
diskio-unix.o: /usr/include/linux/errno.h /usr/include/asm/errno.h
diskio-unix.o: /usr/include/asm-generic/errno.h
diskio-unix.o: /usr/include/asm-generic/errno-base.h /usr/include/fcntl.h
diskio-unix.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
diskio-unix.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
diskio-unix.o: /usr/include/time.h /usr/include/endian.h
diskio-unix.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
diskio-unix.o: /usr/include/sys/select.h /usr/include/bits/select.h
diskio-unix.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
diskio-unix.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
diskio-unix.o: /usr/include/sys/stat.h /usr/include/bits/stat.h diskio.h
diskio-unix.o: support.h /usr/include/stdlib.h /usr/include/alloca.h
diskio-unix.o: parttypes.h guid.h /usr/include/uuid/uuid.h
diskio-unix.o: /usr/include/sys/time.h
diskio-windows.o: /usr/include/stdio.h /usr/include/features.h
diskio-windows.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
diskio-windows.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
diskio-windows.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
diskio-windows.o: /usr/include/libio.h /usr/include/_G_config.h
diskio-windows.o: /usr/include/wchar.h /usr/include/bits/stdio_lim.h
diskio-windows.o: /usr/include/bits/sys_errlist.h /usr/include/stdint.h
diskio-windows.o: /usr/include/bits/wchar.h /usr/include/errno.h
diskio-windows.o: /usr/include/bits/errno.h /usr/include/linux/errno.h
diskio-windows.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h
diskio-windows.o: /usr/include/asm-generic/errno-base.h /usr/include/fcntl.h
diskio-windows.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
diskio-windows.o: /usr/include/time.h /usr/include/endian.h
diskio-windows.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
diskio-windows.o: /usr/include/sys/select.h /usr/include/bits/select.h
diskio-windows.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
diskio-windows.o: /usr/include/sys/sysmacros.h
diskio-windows.o: /usr/include/bits/pthreadtypes.h /usr/include/sys/stat.h
diskio-windows.o: /usr/include/bits/stat.h support.h /usr/include/stdlib.h
diskio-windows.o: /usr/include/alloca.h diskio.h /usr/include/sys/ioctl.h
diskio-windows.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
diskio-windows.o: /usr/include/asm-generic/ioctls.h
diskio-windows.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h
diskio-windows.o: /usr/include/asm-generic/ioctl.h
diskio-windows.o: /usr/include/bits/ioctl-types.h
diskio-windows.o: /usr/include/sys/ttydefaults.h parttypes.h guid.h
diskio-windows.o: /usr/include/uuid/uuid.h /usr/include/sys/time.h
gdisk.o: /usr/include/stdio.h /usr/include/features.h
gdisk.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
gdisk.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
gdisk.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
gdisk.o: /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h
gdisk.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
gdisk.o: /usr/include/string.h /usr/include/xlocale.h mbr.h
gdisk.o: /usr/include/stdint.h /usr/include/bits/wchar.h
gdisk.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h
gdisk.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
gdisk.o: /usr/include/sys/select.h /usr/include/bits/select.h
gdisk.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
gdisk.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
gdisk.o: gptpart.h support.h /usr/include/stdlib.h /usr/include/alloca.h
gdisk.o: parttypes.h guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h
gdisk.o: attributes.h partnotes.h gpt.h bsd.h diskio.h
gdisk.o: /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h
gdisk.o: /usr/include/asm/ioctls.h /usr/include/asm-generic/ioctls.h
gdisk.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h
gdisk.o: /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h
gdisk.o: /usr/include/sys/ttydefaults.h gpttext.h
gpt.o: /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h
gpt.o: /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h
gpt.o: /usr/include/gnu/stubs-64.h /usr/include/bits/types.h
gpt.o: /usr/include/bits/typesizes.h /usr/include/libio.h
gpt.o: /usr/include/_G_config.h /usr/include/wchar.h
gpt.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
gpt.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h
gpt.o: /usr/include/endian.h /usr/include/bits/endian.h
gpt.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
gpt.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
gpt.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
gpt.o: /usr/include/bits/pthreadtypes.h /usr/include/alloca.h
gpt.o: /usr/include/stdint.h /usr/include/bits/wchar.h /usr/include/fcntl.h
gpt.o: /usr/include/bits/fcntl.h /usr/include/string.h /usr/include/xlocale.h
gpt.o: /usr/include/math.h /usr/include/bits/huge_val.h
gpt.o: /usr/include/bits/huge_valf.h /usr/include/bits/huge_vall.h
gpt.o: /usr/include/bits/inf.h /usr/include/bits/nan.h
gpt.o: /usr/include/bits/mathdef.h /usr/include/bits/mathcalls.h
gpt.o: /usr/include/sys/stat.h /usr/include/bits/stat.h /usr/include/errno.h
gpt.o: /usr/include/bits/errno.h /usr/include/linux/errno.h
gpt.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h
gpt.o: /usr/include/asm-generic/errno-base.h crc32.h gpt.h gptpart.h
gpt.o: support.h parttypes.h guid.h /usr/include/uuid/uuid.h
gpt.o: /usr/include/sys/time.h attributes.h mbr.h partnotes.h diskio.h
gpt.o: /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h
gpt.o: /usr/include/asm/ioctls.h /usr/include/asm-generic/ioctls.h
gpt.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h
gpt.o: /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h
gpt.o: /usr/include/sys/ttydefaults.h bsd.h
gptpart.o: /usr/include/string.h /usr/include/features.h
gptpart.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
gptpart.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
gptpart.o: /usr/include/xlocale.h /usr/include/stdio.h
gptpart.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
gptpart.o: /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h
gptpart.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
gptpart.o: gptpart.h /usr/include/stdint.h /usr/include/bits/wchar.h
gptpart.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h
gptpart.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
gptpart.o: /usr/include/sys/select.h /usr/include/bits/select.h
gptpart.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
gptpart.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
gptpart.o: support.h /usr/include/stdlib.h /usr/include/alloca.h parttypes.h
gptpart.o: guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h
gptpart.o: attributes.h
gpttext.o: /usr/include/string.h /usr/include/features.h
gpttext.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
gpttext.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
gpttext.o: /usr/include/xlocale.h /usr/include/errno.h
gpttext.o: /usr/include/bits/errno.h /usr/include/linux/errno.h
gpttext.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h
gpttext.o: /usr/include/asm-generic/errno-base.h /usr/include/stdint.h
gpttext.o: /usr/include/bits/wchar.h /usr/include/limits.h
gpttext.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h
gpttext.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h
gpttext.o: attributes.h gpttext.h gpt.h /usr/include/sys/types.h
gpttext.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
gpttext.o: /usr/include/time.h /usr/include/endian.h
gpttext.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
gpttext.o: /usr/include/sys/select.h /usr/include/bits/select.h
gpttext.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
gpttext.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
gpttext.o: gptpart.h support.h /usr/include/stdlib.h /usr/include/alloca.h
gpttext.o: parttypes.h guid.h /usr/include/uuid/uuid.h
gpttext.o: /usr/include/sys/time.h mbr.h partnotes.h diskio.h
gpttext.o: /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h
gpttext.o: /usr/include/asm/ioctls.h /usr/include/asm-generic/ioctls.h
gpttext.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h
gpttext.o: /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h
gpttext.o: /usr/include/sys/ttydefaults.h bsd.h
guid.o: /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h
guid.o: /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h
guid.o: /usr/include/gnu/stubs-64.h /usr/include/bits/types.h
guid.o: /usr/include/bits/typesizes.h /usr/include/libio.h
guid.o: /usr/include/_G_config.h /usr/include/wchar.h
guid.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
guid.o: /usr/include/time.h guid.h /usr/include/stdint.h
guid.o: /usr/include/bits/wchar.h /usr/include/uuid/uuid.h
guid.o: /usr/include/sys/types.h /usr/include/endian.h
guid.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
guid.o: /usr/include/sys/select.h /usr/include/bits/select.h
guid.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
guid.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
guid.o: /usr/include/sys/time.h support.h /usr/include/stdlib.h
guid.o: /usr/include/alloca.h
mbr.o: /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h
mbr.o: /usr/include/bits/wordsize.h /usr/include/gnu/stubs.h
mbr.o: /usr/include/gnu/stubs-64.h /usr/include/bits/types.h
mbr.o: /usr/include/bits/typesizes.h /usr/include/libio.h
mbr.o: /usr/include/_G_config.h /usr/include/wchar.h
mbr.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
mbr.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h
mbr.o: /usr/include/endian.h /usr/include/bits/endian.h
mbr.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
mbr.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
mbr.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
mbr.o: /usr/include/bits/pthreadtypes.h /usr/include/alloca.h
mbr.o: /usr/include/stdint.h /usr/include/bits/wchar.h /usr/include/fcntl.h
mbr.o: /usr/include/bits/fcntl.h /usr/include/string.h /usr/include/xlocale.h
mbr.o: /usr/include/sys/stat.h /usr/include/bits/stat.h /usr/include/errno.h
mbr.o: /usr/include/bits/errno.h /usr/include/linux/errno.h
mbr.o: /usr/include/asm/errno.h /usr/include/asm-generic/errno.h
mbr.o: /usr/include/asm-generic/errno-base.h mbr.h gptpart.h support.h
mbr.o: parttypes.h guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h
mbr.o: attributes.h partnotes.h gpt.h bsd.h diskio.h /usr/include/sys/ioctl.h
mbr.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
mbr.o: /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h
mbr.o: /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h
mbr.o: /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h
partnotes.o: /usr/include/stdio.h /usr/include/features.h
partnotes.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
partnotes.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
partnotes.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
partnotes.o: /usr/include/libio.h /usr/include/_G_config.h
partnotes.o: /usr/include/wchar.h /usr/include/bits/stdio_lim.h
partnotes.o: /usr/include/bits/sys_errlist.h partnotes.h gpt.h
partnotes.o: /usr/include/stdint.h /usr/include/bits/wchar.h
partnotes.o: /usr/include/sys/types.h /usr/include/time.h
partnotes.o: /usr/include/endian.h /usr/include/bits/endian.h
partnotes.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
partnotes.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
partnotes.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
partnotes.o: /usr/include/bits/pthreadtypes.h gptpart.h support.h
partnotes.o: /usr/include/stdlib.h /usr/include/alloca.h parttypes.h guid.h
partnotes.o: /usr/include/uuid/uuid.h /usr/include/sys/time.h attributes.h
partnotes.o: mbr.h diskio.h /usr/include/sys/ioctl.h
partnotes.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h
partnotes.o: /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h
partnotes.o: /usr/include/asm/ioctl.h /usr/include/asm-generic/ioctl.h
partnotes.o: /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h
partnotes.o: bsd.h
parttypes.o: /usr/include/string.h /usr/include/features.h
parttypes.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
parttypes.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
parttypes.o: /usr/include/xlocale.h /usr/include/stdint.h
parttypes.o: /usr/include/bits/wchar.h /usr/include/stdio.h
parttypes.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
parttypes.o: /usr/include/libio.h /usr/include/_G_config.h
parttypes.o: /usr/include/wchar.h /usr/include/bits/stdio_lim.h
parttypes.o: /usr/include/bits/sys_errlist.h parttypes.h
parttypes.o: /usr/include/stdlib.h /usr/include/sys/types.h
parttypes.o: /usr/include/time.h /usr/include/endian.h
parttypes.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
parttypes.o: /usr/include/sys/select.h /usr/include/bits/select.h
parttypes.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
parttypes.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
parttypes.o: /usr/include/alloca.h support.h guid.h /usr/include/uuid/uuid.h
parttypes.o: /usr/include/sys/time.h
sgdisk.o: /usr/include/stdio.h /usr/include/features.h
sgdisk.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
sgdisk.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
sgdisk.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
sgdisk.o: /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h
sgdisk.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
sgdisk.o: /usr/include/popt.h /usr/include/errno.h /usr/include/bits/errno.h
sgdisk.o: /usr/include/linux/errno.h /usr/include/asm/errno.h
sgdisk.o: /usr/include/asm-generic/errno.h
sgdisk.o: /usr/include/asm-generic/errno-base.h /usr/include/stdint.h
sgdisk.o: /usr/include/bits/wchar.h mbr.h /usr/include/sys/types.h
sgdisk.o: /usr/include/time.h /usr/include/endian.h
sgdisk.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
sgdisk.o: /usr/include/sys/select.h /usr/include/bits/select.h
sgdisk.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
sgdisk.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
sgdisk.o: gptpart.h support.h /usr/include/stdlib.h /usr/include/alloca.h
sgdisk.o: parttypes.h guid.h /usr/include/uuid/uuid.h /usr/include/sys/time.h
sgdisk.o: attributes.h partnotes.h gpt.h bsd.h diskio.h
sgdisk.o: /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h
sgdisk.o: /usr/include/asm/ioctls.h /usr/include/asm-generic/ioctls.h
sgdisk.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h
sgdisk.o: /usr/include/asm-generic/ioctl.h /usr/include/bits/ioctl-types.h
sgdisk.o: /usr/include/sys/ttydefaults.h
support.o: /usr/include/stdio.h /usr/include/features.h
support.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
support.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
support.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h
support.o: /usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h
support.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
support.o: /usr/include/stdint.h /usr/include/bits/wchar.h
support.o: /usr/include/errno.h /usr/include/bits/errno.h
support.o: /usr/include/linux/errno.h /usr/include/asm/errno.h
support.o: /usr/include/asm-generic/errno.h
support.o: /usr/include/asm-generic/errno-base.h /usr/include/fcntl.h
support.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h
support.o: /usr/include/time.h /usr/include/endian.h
support.o: /usr/include/bits/endian.h /usr/include/bits/byteswap.h
support.o: /usr/include/sys/select.h /usr/include/bits/select.h
support.o: /usr/include/bits/sigset.h /usr/include/bits/time.h
support.o: /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h
support.o: /usr/include/string.h /usr/include/xlocale.h
support.o: /usr/include/sys/stat.h /usr/include/bits/stat.h support.h
support.o: /usr/include/stdlib.h /usr/include/alloca.h
testguid.o: guid.h /usr/include/stdint.h /usr/include/features.h
testguid.o: /usr/include/sys/cdefs.h /usr/include/bits/wordsize.h
testguid.o: /usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h
testguid.o: /usr/include/bits/wchar.h /usr/include/uuid/uuid.h
testguid.o: /usr/include/sys/types.h /usr/include/bits/types.h
testguid.o: /usr/include/bits/typesizes.h /usr/include/time.h
testguid.o: /usr/include/endian.h /usr/include/bits/endian.h
testguid.o: /usr/include/bits/byteswap.h /usr/include/sys/select.h
testguid.o: /usr/include/bits/select.h /usr/include/bits/sigset.h
testguid.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h
testguid.o: /usr/include/bits/pthreadtypes.h /usr/include/sys/time.h
testguid.o: parttypes.h /usr/include/stdlib.h /usr/include/alloca.h support.h

View File

@@ -2,13 +2,15 @@ CC=gcc
CXX=g++ CXX=g++
CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g
CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
LIB_SRCS=$(NAMES:=.cc) MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o) LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h) LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CFLAGS) DEPEND= makedepend $(CFLAGS)
all: gdisk sgdisk all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gpttext.o gdisk.o gdisk: $(LIB_OBJS) gpttext.o gdisk.o
$(CXX) $(LIB_OBJS) gpttext.o gdisk.o -o gdisk $(CXX) $(LIB_OBJS) gpttext.o gdisk.o -o gdisk
@@ -16,6 +18,9 @@ gdisk: $(LIB_OBJS) gpttext.o gdisk.o
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -lpopt -o sgdisk $(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts
testguid: $(LIB_OBJS) testguid.o testguid: $(LIB_OBJS) testguid.o
$(CXX) $(LIB_OBJS) testguid.o -o testguid $(CXX) $(LIB_OBJS) testguid.o -o testguid

View File

@@ -4,19 +4,24 @@ STRIP=/usr/bin/i686-pc-mingw32-strip
CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g
CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -g CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -g
#CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g #CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
LIB_NAMES=guid gptpart bsd parttypes partnotes gptpartnotes attributes crc32 basicmbr mbr gpt support diskio diskio-windows LIB_NAMES=guid gptpart bsd parttypes attributes crc32 mbrpart basicmbr mbr gpt support diskio diskio-windows
MBR_LIBS=support diskio diskio-windows basicmbr mbrpart
LIB_SRCS=$(NAMES:=.cc) LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o) LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h) LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CFLAGS) DEPEND= makedepend $(CFLAGS)
all: gdisk all: gdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -luuid -static-libgcc -o gdisk.exe $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -luuid -static-libgcc -o gdisk.exe
sgdisk: $(LIB_OBJS) sgdisk.o sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -lpopt -o sgdisk.exe $(CXX) $(LIB_OBJS) sgdisk.o -lpopt -static-libgcc -o sgdisk.exe
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -static-libgcc -o fixparts.exe
lint: #no pre-reqs lint: #no pre-reqs
lint $(SRCS) lint $(SRCS)
@@ -25,7 +30,7 @@ clean: #no pre-reqs
rm -f core *.o *~ gdisk.exe sgdisk.exe rm -f core *.o *~ gdisk.exe sgdisk.exe
strip: #no pre-reqs strip: #no pre-reqs
$(STRIP) gdisk.exe $(STRIP) gdisk.exe fixparts.exe
# what are the source dependencies # what are the source dependencies
depend: $(SRCS) depend: $(SRCS)

24
NEWS
View File

@@ -1,6 +1,23 @@
0.6.15 (?/?/2011): 0.7.0 (3/11/2011):
------------------ ------------------
- Fixed bug that caused some types of logical partitions to be misread.
- Created FixParts program, to fix problems on MBR-partitioned disks.
Although this program is part of the GPT fdisk family, it is NOT used on
GPT disks.
- Completely redid the GPT-to-MBR code, used both for converting to MBR
form and for creating hybrid MBRs.
- Fixed a bug that caused gdisk to "forget" some partitions if there were
numbering gaps when a conversion to MBR was aborted.
- Improved CHS value creation on small (<~8GB) disks for protective MBR
and when creating hybrid MBRs or converting to MBR format. Linux-only,
for the moment; other platforms still produce bad CHS values on sub-~8GB
disks (but few OSes care these days).
- Enhanced disk replication features ('u' on the experts' menu in gdisk; -R - Enhanced disk replication features ('u' on the experts' menu in gdisk; -R
or --replicate in sgdisk). It's now possible to replicate the partition or --replicate in sgdisk). It's now possible to replicate the partition
table from a larger to a smaller disk, so long as all the partitions fit table from a larger to a smaller disk, so long as all the partitions fit
@@ -15,11 +32,10 @@
- Changed largest drive that's not given a minimum 4 KiB alignment even - Changed largest drive that's not given a minimum 4 KiB alignment even
when smaller alignment is detected on the disk to 300 GB. when smaller alignment is detected on the disk to 300 GB.
- Fixed bug that preventing a partition table backup ('u' on the - Fixed bug that prevented aborting a partition table backup ('u' on the
experts' menu) by hitting the Enter key for the device filename. experts' menu) by hitting the Enter key for the device filename.
- Implemented a number of code cleanups provided by an anonymous - Implemented a number of code cleanups provided by Florian Zumbiehl.
contributor.
0.6.14 (1/8/2011): 0.6.14 (1/8/2011):
------------------ ------------------

158
README
View File

@@ -1,14 +1,49 @@
GPT fdisk (aka gdisk) GPT fdisk (aka gdisk and sgdisk) and FixParts
by Roderick W. Smith, rodsmith@rodsbooks.com by Roderick W. Smith, rodsmith@rodsbooks.com
Introduction Introduction
------------ ------------
This software is intended as a (somewhat) fdisk-workalike program for This binary archive includes the source code for three related disk
GPT-partitioned disks. Although libparted and programs that use it (GNU partitioning programs:
Parted, gparted, etc.) provide the ability to handle GPT disks, they have
certain limitations that gdisk overcomes. Specific advantages of gdisk and - gdisk -- This program is modeled after Linux fdisk, but it operates on
sgdisk include: GUID Partition Table (GPT) disks rather than the Master Boot Record (MBR)
disks that fdisk modifies. As such, gdisk is an interactive text-mode
tool for manipulating partitions, but it does nothing to the contents of
those partitions (usually filesystems, but sometimes swap space or other
data).
- sgdisk -- This program is conceptually similar to the Linux sfdisk and
FreeBSD gpt programs, but its operational details differ. It enables
manipulation of GPT disks using command-line options, so it's suitable
for use in scripts or by experts to perform specific tasks that might
take several commands in gdisk to accomplish.
- fixparts -- This program, unlike the preceding two, operates on MBR
disks. It's intended to fix certain problems that can be created by
various utilities. Specifically, it can fix mis-sized extended partitions
and primary partitions located in the middle of extended partitions. It
also enables changing primary vs. logical partition status (within limits
of what's legal in the MBR scheme) and making a few other minor changes.
It does NOT support creating new partitions; for that, you should use
fdisk, parted, or some other tool.
More details about the abilities of these tools follows.
All three programs rely on the same set of underlying code base; they
differ only in their control interfaces (defined in gdisk.cc, sgdisk.cc,
and fixparts.cc, respectively) and in which support code they use.
GPT fdisk (gdisk and sgdisk) Details
------------------------------------
The gdisk program is intended as a (somewhat) fdisk-workalike program for
GPT-partitioned disks, and sgdisk provides most of gdisk's functionality in
a more script-friendly program. Although libparted and programs that use it
(GNU Parted, gparted, etc.) provide the ability to handle GPT disks, they
have certain limitations that gdisk overcomes. Specific advantages of gdisk
and sgdisk include:
* The ability to convert MBR-partitioned disks in-place to GPT format, * The ability to convert MBR-partitioned disks in-place to GPT format,
without losing data without losing data
@@ -16,10 +51,10 @@ sgdisk include:
* The ability to convert BSD disklabels in-place to create GPT * The ability to convert BSD disklabels in-place to create GPT
partitions, without losing data partitions, without losing data
* The ability to specify sector-exact partition sizes * The ability to convert from GPT format to MBR format without data loss
* More flexible specification of filesystem type code GUIDs, which * More flexible specification of filesystem type code GUIDs, which
GNU Parted tends to corrupt (particularly for FAT partitions) GNU Parted tends to corrupt
* Clear identification of the number of unallocated sectors on a * Clear identification of the number of unallocated sectors on a
disk disk
@@ -45,12 +80,81 @@ manually partitioning disks or changing partitioning details; the latter is
intended for use in scripts to help automate tasks such as disk cloning or intended for use in scripts to help automate tasks such as disk cloning or
preparing multiple disks for Linux installation. preparing multiple disks for Linux installation.
FixParts Details
----------------
This program's creation was motivated by cries for help I've seen in online
forums from users who have found their partition tables to be corrupted by
various buggy partitioning tools. Although most OSes can handle the
afflicted disks fine, libparted-based tools (GParted, parted, most Linux
installers, etc.) tend to flake out when presented with these disks.
Typically, the symptom is a disk that appears to hold no partitions;
however, sometimes the libparted tool presents partitions other than those
that the OS sees.
I've observed four causes of these symptoms, three of which FixParts can
correct:
- Old GPT data -- If a disk is used as a GPT disk and then re-used as an
MBR disk, the GPT data may be incompletely erased. This happens if the
disk is repartitioned with fdisk or the Microsoft Windows installer, for
instance. (Tools based on libparted correctly remove the old GPT data
when converting from GPT to MBR format.) FixParts checks for this problem
when it starts and offers to correct it. If you opt to erase the GPT
data, this erasure occurs immediately, unlike other changes the program
makes.
- Mis-sized extended partitions -- Some tools create an extended partition
that's too large, typically ending after the last sector of the disk.
FixParts automatically corrects this problem (if you use the 'w' option
to save the partition table).
- Primary partitions inside an extended partition -- Some utilities create
or move primary partitions to within the range covered by the extended
partition. FixParts can usually correct this problem by turning the
primary partition into a logical partition or by changing one or more
other logical partitions into primaries. Such corrections aren't always
possible, though, at least not without deleting or resizing other
partitions.
- Leftover RAID data -- If a disk is used in a RAID array and then re-used
as a non-RAID disk, some utilities can become confused and fail to see
the disk. FixParts can NOT correct this problem. You must destroy the old
RAID data, or possibly remove the dmraid package from the system, to fix
this problem.
When run, FixParts presents an fdisk-like interface, enabling you to adjust
partition types (primary, logical, or omitted), change type codes, change
the bootable flag, and so on. Although you can delete a partition (by
omitting it), you can't create new partitions with the program. If you're
used to partitioning disks, particularly with Linux fdisk, two unusual
features of FixParts require elaboration:
- No extended partitions -- Internally, FixParts reads the partition table
and discards data on any extended partition(s) it finds. When you save
the partition table, the program generates a new extended partition. This
design means that the program automatically corrects many problems
related to the extended partition. It also means that you'll see no
evidence of extended partitions in the FixParts user interface, although
it keeps track of the requirements and prevents you from creating illegal
layouts, such as a primary between two logicals.
- Partition numbering -- In most Linux tools, partitions 1-4 are primaries
and partitions 5 and up are logicals. Although a legal partition table
loaded into FixParts will initially conform to this convention, some
types of damaged table might not, and various changes you make can also
cause deviations. When FixParts writes the partition table, its numbering
will be altered to conform to the standard MBR conventions, but you
should use the explicit labeling of partitions as primary or logical
rather than the partition numbers to determine a partition's status.
Installing Installing
---------- ----------
To compile GPT fdisk, you must have appropriate development tools To compile GPT fdisk, you must have appropriate development tools
installed, most notably the GNU Compiler Collection (GCC) and its g++ installed, most notably the GNU Compiler Collection (GCC) and its g++
compiler for C++. In addition, note these requirements: compiler for C++. (Under Windows, Microsoft Visual C++ 2008 can also be
used.) In addition, note these requirements:
* On Linux, FreeBSD, and OS X, libuuid must be installed. This is the * On Linux, FreeBSD, and OS X, libuuid must be installed. This is the
standard for Linux and OS X, although you may need to install a package standard for Linux and OS X, although you may need to install a package
@@ -73,11 +177,11 @@ X, "make -f Makefile.freebsd" on FreeBSD, or "make -f Makefile.mingw" to
compile using MinGW for Windows.) You may also need to add header (include) compile using MinGW for Windows.) You may also need to add header (include)
directories or library directories by setting the CXXFLAGS environment directories or library directories by setting the CXXFLAGS environment
variable or by editing the Makefile. The result should be program files variable or by editing the Makefile. The result should be program files
called gdisk and sgdisk. Typing "make gdisk" or "make sgdisk" will compile called gdisk, sgdisk, and fixparts. Typing "make gdisk", "make sgdisk", or
only the requested programs. You can use these programs in place or copy "make fixparts" will compile only the requested programs. You can use these
the files to a suitable directory, such as /usr/local/sbin. You can copy programs in place or copy the files to a suitable directory, such as
the man pages (gdisk.8 and sgdisk.8) to /usr/local/man/man8 to make them /usr/local/sbin. You can copy the man pages (gdisk.8, sgdisk.8, and
available. fixparts.8) to /usr/local/man/man8 to make them available.
Caveats Caveats
------- -------
@@ -85,19 +189,17 @@ Caveats
THIS SOFTWARE IS BETA SOFTWARE! IF IT WIPES OUT YOUR HARD DISK OR EATS YOUR THIS SOFTWARE IS BETA SOFTWARE! IF IT WIPES OUT YOUR HARD DISK OR EATS YOUR
CAT, DON'T BLAME ME! To date, I've tested the software on several USB flash CAT, DON'T BLAME ME! To date, I've tested the software on several USB flash
drives, a handful of PATA and SATA hard disks, and several virtual disks in drives, a handful of PATA and SATA hard disks, and several virtual disks in
a QEMU environment. I believe all data-corruption bugs to be squashed, but the QEMU and VirtualBox environments. Many others have now used the
I know full well that the odds of my missing something are high. This is software on their computers, as well. I believe all data-corruption bugs to
particularly true for large drives; my only direct testing with such disks be squashed, but I know full well that the odds of my missing something are
is with virtual QEMU disks. I've received user reports of success with high. This is particularly true for large drives; my only direct testing
RAID arrays over 2TiB in size, though. with such disks is with virtual QEMU disks. I've received user reports of
success with RAID arrays over 2TiB in size, though.
My main development platform is a system running the 64-bit version of My main development platform is a system running the 64-bit version of
Gentoo Linux (previously Ubuntu 8.04). I've also tested on 64-bit OpenSuSE, Gentoo Linux (previously Ubuntu 8.04). I've also tested on several other
32-bit Fedora 10, 32-bit Fedora 11, 32-bit Ubuntu 6.10, 64-bit Ubunut 9.10, 32- and 64-bit Linux distributions Intel-based Mac OS X 10.5 and 10.6,
32-bit PowerPC Debian Linux, 32-bit Intel-based Mac OS X 10.5 and 10.6, 64-bit FreeBSD 7.1, and Windows 7.
64-bit FreeBSD 7.1, and Windows 7. Problems relating to 64-bit integers on
the 32-bit Linux have been common during development and may crop up in the
future.
Redistribution Redistribution
-------------- --------------
@@ -122,3 +224,9 @@ Additional code contributors include:
- Yves Blusseau (1otnwmz02@sneakemail.com) - Yves Blusseau (1otnwmz02@sneakemail.com)
- David Hubbard (david.c.hubbard@gmail.com) - David Hubbard (david.c.hubbard@gmail.com)
- Justin Maggard (justin.maggard@netgear.com)
- Dwight Schauer (dschauer@ti.com)
- Florian Zumbiehl (florz@florz.de)

View File

@@ -1,20 +1,21 @@
GPT fdisk (aka gdisk) GPT fdisk (aka gdisk) and FixParts
by Roderick W. Smith, rodsmith@rodsbooks.com by Roderick W. Smith, rodsmith@rodsbooks.com
******************************** IMPORTANT ******************************** ******************************** IMPORTANT ********************************
Most versions of Windows cannot boot from a GPT disk, and most varieties Most versions of Windows cannot boot from a GPT disk on BIOS-based
prior to Vista cannot read GPT disks. GPT fdisk is a partition editor for computers, and most varieties prior to Vista cannot read GPT disks. GPT
GPT disks, and it will *AUTOMATICALLY CONVERT* MBR disks to GPT form. fdisk is a partition editor for GPT disks, and it will *AUTOMATICALLY
Therefore, you should **NOT** use GPT fdisk on a Windows system unless you CONVERT* MBR disks to GPT form. Therefore, you should **NOT** use GPT fdisk
fully understand what you're doing! If you accidentally use GPT fdisk on on a Windows system unless you fully understand what you're doing! If you
your boot disk, or perhaps even on a data disk, you may find recovery to be accidentally use GPT fdisk on your boot disk, or perhaps even on a data
very difficult! disk, you may find recovery to be very difficult! This caveat does not
apply to FixParts, though; that tool works only on MBR disks.
*************************************************************************** ***************************************************************************
Read the main README file for general information on the program, and read Read the main README file for general information on the program, and read
the gdisk.html document (the Linux man page converted to HTML format) for the gdisk.html or fixparts.html documents (the Linux man pages converted to
detailed use information. My GPT fdisk Web page, HTML format) for detailed use information. My GPT fdisk Web page,
http://www.rodsbooks.com/gdisk/, provides a more tutorial introduction to http://www.rodsbooks.com/gdisk/, provides a more tutorial introduction to
the software. I originally wrote GPT fdisk on Linux, and some Linux- and the software. I originally wrote GPT fdisk on Linux, and some Linux- and
Unix-centric language remains in the documentation. Unix-centric language remains in the documentation.
@@ -31,11 +32,18 @@ attempted to do this myself, though. If you care to try, check
http://gnuwin32.sourceforge.net/packages/popt.htm for information on popt http://gnuwin32.sourceforge.net/packages/popt.htm for information on popt
for Windows. for Windows.
To install the program, copy the gdisk.exe program file to any directory on The FixParts program (fixparts.txt) is new with GPT fdisk 0.7.0. As
your path, such as C:\Windows. Alternatively, you can change to the described in the main README file, this program fixes certain partition
program's directory or type its complete path whenever you use it. table problems that can be created by buggy partitioning software. Windows
seems to be unfazed by most such problems, but I've not done an extensive
survey of Windows partitioning tools on this score.
To use the program, first launch a Command Prompt as the Administrator. To To install the programs, copy the gdisk.exe and fixparts.exe program files
to any directory on your path, such as C:\Windows. Alternatively, you can
change to the program's directory or type its complete path whenever you
use it.
To use the programs, first launch a Command Prompt as the Administrator. To
do this, locate the Command Prompt program icon, right-click it, and select do this, locate the Command Prompt program icon, right-click it, and select
"Run as Administrator." If you use a non-Administrator Command Prompt, you "Run as Administrator." If you use a non-Administrator Command Prompt, you
won't be able to edit hard disk partition tables, although you will be able won't be able to edit hard disk partition tables, although you will be able
@@ -57,10 +65,10 @@ This command is equivalent to the earlier one -- it edits the partition
table on the first physical disk. Change the number at the end of the table on the first physical disk. Change the number at the end of the
device name to change the disk edited. device name to change the disk edited.
If you pass the "-l" option in addition to the disk identifier, the program If you pass the "-l" option to gdisk.exe in addition to the disk
displays the current partition table information and then exits. This use identifier, the program displays the current partition table information
entails no risk to MBR disks, since the program never writes data back to and then exits. This use entails no risk to MBR disks, since the program
the disk when used in this way. never writes data back to the disk when used in this way.
As noted above, editing the first disk with GPT fdisk is usually a Bad As noted above, editing the first disk with GPT fdisk is usually a Bad
Idea. An exception would be if your system uses an Extensible Firmware Idea. An exception would be if your system uses an Extensible Firmware
@@ -71,14 +79,14 @@ support of GPT, see Microsoft's Web page on the topic:
http://www.microsoft.com/whdc/device/storage/GPT_FAQ.mspx http://www.microsoft.com/whdc/device/storage/GPT_FAQ.mspx
The GUIDs generated by the program to uniquely identify disks and The GUIDs generated by gdisk to uniquely identify disks and partitions
partitions aren't "proper" GUIDs; they're purely random numbers. In aren't "proper" GUIDs; they're purely random numbers. In practice, this has
practice, this has caused me no problems; however, it's conceivable that caused me no problems; however, it's conceivable that some disk utility
some disk utility will complain. The Unix versions of GPT fdisk generate will complain. The Unix versions of GPT fdisk generate proper GUIDs, as of
proper GUIDs, as of version 0.6.3. Note that this limitation applies ONLY version 0.6.3. Note that this limitation applies ONLY to the unique GUIDs
to the unique GUIDs for disks and partitions, not to the GUIDs used to for disks and partitions, not to the GUIDs used to identify partition type
identify partition type codes; those are standardized and are handled codes; those are standardized and are handled correctly by all versions of
correctly by all versions of GPT fdisk. GPT fdisk.
Source Code and Compilation Issues Source Code and Compilation Issues
---------------------------------- ----------------------------------
@@ -98,7 +106,8 @@ compilers:
third-party stdint.h file (I used the one from third-party stdint.h file (I used the one from
http://msinttypes.googlecode.com/svn/trunk/stdint.h), but it otherwise http://msinttypes.googlecode.com/svn/trunk/stdint.h), but it otherwise
works fine. A project is easily created by adding all the *.h files and works fine. A project is easily created by adding all the *.h files and
all the *.cc files except diskio-unix.cc and sgdisk.cc. all the *.cc files except diskio-unix.cc, sgdisk.cc, and whichever
program file you intend to NOT build (gdisk.cc or fixparts.cc).
The MinGW compiler produces much larger executables than does the MS The MinGW compiler produces much larger executables than does the MS
compiler. The resulting binaries seem to work equally well, but my testing compiler. The resulting binaries seem to work equally well, but my testing

File diff suppressed because it is too large Load Diff

View File

@@ -5,16 +5,13 @@
#include <stdint.h> #include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include "partnotes.h"
#include "diskio.h" #include "diskio.h"
#include "mbrpart.h"
#ifndef __BASICMBRSTRUCTS #ifndef __BASICMBRSTRUCTS
#define __BASICMBRSTRUCTS #define __BASICMBRSTRUCTS
#define MBR_SIGNATURE UINT16_C(0xAA55) #define MBR_SIGNATURE UINT16_C(0xAA55)
#define MAX_HEADS 255 /* numbered 0 - 254 */
#define MAX_SECSPERTRACK 63 /* numbered 1 - 63 */
#define MAX_CYLINDERS 1024 /* numbered 0 - 1023 */
// Maximum number of MBR partitions // Maximum number of MBR partitions
#define MAX_MBR_PARTS 128 #define MAX_MBR_PARTS 128
@@ -29,23 +26,6 @@ class PartNotes;
* * * *
****************************************/ ****************************************/
// Data for a single MBR partition record
// Note that firstSector and lastSector are in CHS addressing, which
// splits the bits up in a weird way.
// On read or write of MBR entries, firstLBA is an absolute disk sector.
// On read of logical entries, it's relative to the EBR record for that
// partition. When writing EBR records, it's relative to the extended
// partition's start.
#pragma pack(1)
struct MBRRecord {
uint8_t status;
uint8_t firstSector[3];
uint8_t partitionType;
uint8_t lastSector[3];
uint32_t firstLBA; // see above
uint32_t lengthLBA;
}; // struct MBRRecord
// A 512-byte data structure into which the MBR can be loaded in one // A 512-byte data structure into which the MBR can be loaded in one
// go. Also used when loading logical partitions. // go. Also used when loading logical partitions.
#pragma pack(1) #pragma pack(1)
@@ -68,19 +48,19 @@ protected:
uint16_t nulls; uint16_t nulls;
// MAX_MBR_PARTS defaults to 128. This array holds both the primary and // MAX_MBR_PARTS defaults to 128. This array holds both the primary and
// the logical partitions, to simplify data retrieval for GPT conversions. // the logical partitions, to simplify data retrieval for GPT conversions.
struct MBRRecord partitions[MAX_MBR_PARTS]; MBRPart partitions[MAX_MBR_PARTS];
uint16_t MBRSignature; uint16_t MBRSignature;
// Above are basic MBR data; now add more stuff.... // Above are basic MBR data; now add more stuff....
uint32_t blockSize; // block size (usually 512) uint32_t blockSize; // block size (usually 512)
uint64_t diskSize; // size in blocks uint64_t diskSize; // size in blocks
uint64_t numHeads; // number of heads, in CHS scheme uint32_t numHeads; // number of heads, in CHS scheme
uint64_t numSecspTrack; // number of sectors per track, in CHS scheme uint32_t numSecspTrack; // number of sectors per track, in CHS scheme
DiskIO* myDisk; DiskIO* myDisk;
int canDeleteMyDisk; int canDeleteMyDisk;
string device; string device;
MBRValidity state; MBRValidity state;
struct MBRRecord* GetPartition(int i); // Return primary or logical partition MBRPart* GetPartition(int i); // Return primary or logical partition
public: public:
BasicMBRData(void); BasicMBRData(void);
BasicMBRData(string deviceFilename); BasicMBRData(string deviceFilename);
@@ -92,51 +72,90 @@ public:
int ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1); int ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
// ReadLogicalPart() returns last partition # read to logicals[] array, // ReadLogicalPart() returns last partition # read to logicals[] array,
// or -1 if there was a problem.... // or -1 if there was a problem....
int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset, int ReadLogicalPart(uint64_t extendedStart, uint64_t diskOffset,
int partNum); int partNum);
int WriteMBRData(void); int WriteMBRData(void);
int WriteMBRData(DiskIO *theDisk); int WriteMBRData(DiskIO *theDisk);
int WriteMBRData(const string & deviceFilename); int WriteMBRData(const string & deviceFilename);
int WriteMBRData(struct TempMBR & mbr, DiskIO *theDisk, uint64_t sector); int WriteMBRData(struct TempMBR & mbr, DiskIO *theDisk, uint64_t sector);
void SetDisk(DiskIO *theDisk) {myDisk = theDisk; canDeleteMyDisk = 0;} void DiskSync(void) {myDisk->DiskSync();}
void SetDisk(DiskIO *theDisk);
// Display data for user... // Display data for user...
void DisplayMBRData(int maxParts = 4); void DisplayMBRData(void);
void ShowState(void); void ShowState(void);
// GPT checks and fixes...
int CheckForGPT(void);
int BlankGPTData(void);
// Functions that set or get disk metadata (size, CHS geometry, etc.) // Functions that set or get disk metadata (size, CHS geometry, etc.)
void SetDiskSize(uint64_t ds) {diskSize = ds;} void SetDiskSize(uint64_t ds) {diskSize = ds;}
void SetBlockSize(uint32_t bs) {blockSize = bs;} void SetBlockSize(uint32_t bs) {blockSize = bs;}
MBRValidity GetValidity(void) {return state;} MBRValidity GetValidity(void) {return state;}
void SetHybrid(void) {state = hybrid;} // Set hybrid flag void SetHybrid(void) {state = hybrid;} // Set hybrid flag
void SetCHSGeom(uint32_t h, uint32_t s); void ReadCHSGeom(void);
int GetPartRange(uint32_t* low, uint32_t* high);
int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS
int Verify(void); int FindOverlaps(void);
int NumPrimaries(void);
int NumLogicals(void);
int CountParts(void);
void UpdateCanBeLogical(void);
uint64_t FirstLogicalLBA(void);
uint64_t LastLogicalLBA(void);
int AreLogicalsContiguous(void);
int DoTheyFit(void);
int SpaceBeforeAllLogicals(void);
int IsLegal(void);
int FindNextInUse(int start);
// Functions to create, delete, or change partitions // Functions to create, delete, or change partitions
// Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact // Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
void EmptyMBR(int clearBootloader = 1); void EmptyMBR(int clearBootloader = 1);
void EmptyBootloader(void); void EmptyBootloader(void);
void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07, void AddPart(int num, const MBRPart& newPart);
void MakePart(int num, uint64_t startLBA, uint64_t lengthLBA, int type = 0x07,
int bootable = 0); int bootable = 0);
int SetPartType(int num, int type); int SetPartType(int num, int type);
int SetPartBootable(int num, int bootable = 1); int SetPartBootable(int num, int bootable = 1);
int MakeBiggestPart(int i, int type); // Make partition filling most space int MakeBiggestPart(int i, int type); // Make partition filling most space
void DeletePartition(int i); void DeletePartition(int i);
int SetInclusionwChecks(int num, int inclStatus);
void RecomputeCHS(int partNum); void RecomputeCHS(int partNum);
int CreateLogicals(PartNotes * notes); int SwapPartitions(uint32_t partNum1, uint32_t partNum2);
void SortMBR(int start = 0);
void QuickSortMBR(int start, int finish);
int DeleteOversizedParts();
int DeleteExtendedParts();
void OmitOverlaps(void);
// void OmitAll(void);
void MaximizeLogicals();
void MaximizePrimaries();
void TrimPrimaries();
void MakeLogicalsContiguous(void);
void MakeItLegal(void);
int RemoveLogicalsFromFirstFour(void);
int MovePrimariesToFirstFour(void);
int CreateExtended(void);
// Functions to find information on free space.... // Functions to find information on free space....
uint32_t FindFirstAvailable(uint32_t start = 1); uint64_t FindFirstAvailable(uint64_t start = 1);
uint32_t FindLastInFree(uint32_t start); uint64_t FindLastInFree(uint64_t start);
uint32_t FindFirstInFree(uint32_t start); uint64_t FindFirstInFree(uint64_t start);
int IsFree(uint32_t sector); // int IsFree(uint64_t sector, int topPartNum = MAX_MBR_PARTS);
int SectorUsedAs(uint64_t sector, int topPartNum = MAX_MBR_PARTS);
// Functions to extract data on specific partitions.... // Functions to extract data on specific partitions....
uint8_t GetStatus(int i); uint8_t GetStatus(int i);
uint8_t GetType(int i); uint8_t GetType(int i);
uint32_t GetFirstSector(int i); uint64_t GetFirstSector(int i);
uint32_t GetLength(int i); uint64_t GetLength(int i);
// User interaction functions....
int DoMenu(const string& prompt = "\nMBR command (? for help): ");
void ShowCommands(void);
}; // struct BasicMBRData }; // struct BasicMBRData
#endif #endif

View File

@@ -1,14 +1,29 @@
Summary: An fdisk-like partitioning tool for GPT disks Summary: GPT partitioning and MBR repair software
Name: gdisk Name: gptfdisk
Version: 0.6.14 Version: 0.7.0
Release: 1%{?dist} Release: 1%{?dist}
License: GPLv2 License: GPLv2
URL: http://www.rodsbooks.com/gdisk URL: http://www.rodsbooks.com/gdisk
Group: Applications/System Group: Applications/System
Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.14.tgz Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.7.0.tgz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description %description
Partitioning software for GPT disks and to repair MBR
disks. The gdisk and sgdisk utilities (in the gdisk
package) are GPT-enabled partitioning tools; the
fixparts utility (in the fixparts package) fixes some
problems with MBR disks that can be created by buggy
partitioning software.
%package -n gdisk
Group: Applications/System
Summary: An fdisk-like partitioning tool for GPT disks
%description -n gdisk
An fdisk-like partitioning tool for GPT disks. GPT An fdisk-like partitioning tool for GPT disks. GPT
fdisk features a command-line interface, fairly direct fdisk features a command-line interface, fairly direct
manipulation of partition table structures, recovery manipulation of partition table structures, recovery
@@ -26,19 +41,41 @@ rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT/usr/sbin mkdir -p $RPM_BUILD_ROOT/usr/sbin
install -Dp -m0755 gdisk $RPM_BUILD_ROOT/usr/sbin install -Dp -m0755 gdisk $RPM_BUILD_ROOT/usr/sbin
install -Dp -m0755 sgdisk $RPM_BUILD_ROOT/usr/sbin install -Dp -m0755 sgdisk $RPM_BUILD_ROOT/usr/sbin
install -Dp -m0755 fixparts $RPM_BUILD_ROOT/usr/sbin
install -Dp -m0644 gdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/gdisk.8 install -Dp -m0644 gdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/gdisk.8
install -Dp -m0644 sgdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/sgdisk.8 install -Dp -m0644 sgdisk.8 $RPM_BUILD_ROOT/%{_mandir}/man8/sgdisk.8
install -Dp -m0644 fixparts.8 $RPM_BUILD_ROOT/%{_mandir}/man8/fixparts.8
%clean %clean
rm -rf $RPM_BUILD_ROOT rm -rf $RPM_BUILD_ROOT
%files %files -n gdisk
%defattr(-,root,root -) %defattr(-,root,root -)
%doc NEWS COPYING README %doc NEWS COPYING README
/usr/sbin/gdisk /usr/sbin/gdisk
/usr/sbin/sgdisk /usr/sbin/sgdisk
%doc %{_mandir}/man8* %doc %{_mandir}/man8/gdisk.8*
%doc %{_mandir}/man8/sgdisk.8*
%package -n fixparts
Group: Applications/System
Summary: A tool for repairing certain types of damage to MBR disks
%description -n fixparts
A program that corrects errors that can creep into MBR-partitioned
disks. Removes stray GPT data, fixes mis-sized extended partitions,
and enables changing primary vs. logical partition status. Also
provides a few additional partition manipulation features.
%files -n fixparts
%defattr(-,root,root -)
%doc NEWS COPYING README
/usr/sbin/fixparts
%doc %{_mandir}/man8/fixparts.8*
%changelog %changelog
* Sat Jan 8 2011 R Smith <rodsmith@rodsbooks.com> - 0.6.14 * Fri Mar 11 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.0
- Created spec file for 0.6.14 release - Created spec file for 0.7.0 release

View File

@@ -22,6 +22,11 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifdef __linux__
#include "linux/hdreg.h"
#endif
#include <iostream> #include <iostream>
#include "diskio.h" #include "diskio.h"
@@ -160,6 +165,42 @@ int DiskIO::GetBlockSize(void) {
return (blockSize); return (blockSize);
} // DiskIO::GetBlockSize() } // DiskIO::GetBlockSize()
// Returns the number of heads, according to the kernel, or 255 if the
// correct value can't be determined.
uint32_t DiskIO::GetNumHeads(void) {
uint32_t numHeads = 255;
#ifdef HDIO_GETGEO
struct hd_geometry geometry;
// If disk isn't open, try to open it....
if (!isOpen)
OpenForRead();
if (!ioctl(fd, HDIO_GETGEO, &geometry))
numHeads = (uint32_t) geometry.heads;
#endif
return numHeads;
} // DiskIO::GetNumHeads();
// Returns the number of sectors per track, according to the kernel, or 63
// if the correct value can't be determined.
uint32_t DiskIO::GetNumSecsPerTrack(void) {
uint32_t numSecs = 63;
#ifdef HDIO_GETGEO
struct hd_geometry geometry;
// If disk isn't open, try to open it....
if (!isOpen)
OpenForRead();
if (!ioctl(fd, HDIO_GETGEO, &geometry))
numSecs = (uint32_t) geometry.sectors;
#endif
return numSecs;
} // DiskIO::GetNumSecsPerTrack()
// Resync disk caches so the OS uses the new partition table. This code varies // Resync disk caches so the OS uses the new partition table. This code varies
// a lot from one OS to another. // a lot from one OS to another.
void DiskIO::DiskSync(void) { void DiskIO::DiskSync(void) {

View File

@@ -143,6 +143,18 @@ int DiskIO::GetBlockSize(void) {
return (blockSize); return (blockSize);
} // DiskIO::GetBlockSize() } // DiskIO::GetBlockSize()
// Returns the number of heads, according to the kernel, or 255 if the
// correct value can't be determined.
uint32_t DiskIO::GetNumHeads(void) {
return UINT32_C(255);
} // DiskIO::GetNumHeads();
// Returns the number of sectors per track, according to the kernel, or 63
// if the correct value can't be determined.
uint32_t DiskIO::GetNumSecsPerTrack(void) {
return UINT32_C(63);
} // DiskIO::GetNumSecsPerTrack()
// Resync disk caches so the OS uses the new partition table. This code varies // Resync disk caches so the OS uses the new partition table. This code varies
// a lot from one OS to another. // a lot from one OS to another.
void DiskIO::DiskSync(void) { void DiskIO::DiskSync(void) {

View File

@@ -34,7 +34,7 @@
#include "support.h" #include "support.h"
#include "diskio.h" #include "diskio.h"
#include "gpt.h" //#include "gpt.h"
using namespace std; using namespace std;

View File

@@ -31,7 +31,7 @@
#endif #endif
#include "support.h" #include "support.h"
#include "parttypes.h" //#include "parttypes.h"
using namespace std; using namespace std;
@@ -67,6 +67,8 @@ class DiskIO {
int Write(void* buffer, int numBytes); int Write(void* buffer, int numBytes);
void DiskSync(void); // resync disk caches to use new partitions void DiskSync(void); // resync disk caches to use new partitions
int GetBlockSize(void); int GetBlockSize(void);
uint32_t GetNumHeads(void);
uint32_t GetNumSecsPerTrack(void);
int IsOpen(void) {return isOpen;} int IsOpen(void) {return isOpen;}
int IsOpenForWrite(void) {return openForWrite;} int IsOpenForWrite(void) {return openForWrite;}
string GetName(void) const {return realFilename;} string GetName(void) const {return realFilename;}

View File

@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License .\" May be distributed under the GNU General Public License
.TH "GDISK" "8" "0.6.14" "Roderick W. Smith" "GPT fdisk Manual" .TH "GDISK" "8" "0.7.0" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME" .SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS" .SH "SYNOPSIS"
@@ -561,7 +561,7 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely. usually bypasses the prompt entirely.
.SH "BUGS" .SH "BUGS"
As of January 2011 (version 0.6.14), \fBgdisk\fR As of March 2011 (version 0.7.0), \fBgdisk\fR
should be considered beta software. Known bugs and limitations include: should be considered beta software. Known bugs and limitations include:
.TP .TP
@@ -600,7 +600,7 @@ preserved when loading and saving partitions.
The program can load only up to 128 partitions (4 primary partitions and The program can load only up to 128 partitions (4 primary partitions and
124 logical partitions) when converting from MBR format. This limit can 124 logical partitions) when converting from MBR format. This limit can
be raised by changing the \fI#define MAX_MBR_PARTS\fR line in the be raised by changing the \fI#define MAX_MBR_PARTS\fR line in the
\fImbr.h\fR source code file and recompiling; however, such a change \fIbasicmbr.h\fR source code file and recompiling; however, such a change
will require using a larger\-than\-normal partition table. (The limit will require using a larger\-than\-normal partition table. (The limit
of 128 partitions was chosen because that number equals the 128 partitions of 128 partitions was chosen because that number equals the 128 partitions
supported by the most common partition table size.) supported by the most common partition table size.)
@@ -674,6 +674,7 @@ Contributors:
\fBparted (8)\fR, \fBparted (8)\fR,
\fBsfdisk (8)\fR \fBsfdisk (8)\fR
\fBsgdisk (8)\fR \fBsgdisk (8)\fR
\fBfixparts (8)\fR
\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR \fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR

View File

@@ -8,7 +8,6 @@
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
#include <stdio.h> #include <stdio.h>
//#include <getopt.h>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
@@ -42,10 +41,7 @@ int main(int argc, char* argv[]) {
WinWarning(); WinWarning();
cout << "Type device filename, or press <Enter> to exit: "; cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255]; device = new char[255];
if (!fgets(device, 255, stdin)) { ReadCString(device, 255);
cerr << "Critical error! Failed fgets() in main()!\n";
exit(1);
} // if
i = strlen(device); i = strlen(device);
if (i && device[i - 1] == '\n') if (i && device[i - 1] == '\n')
device[i - 1] = '\0'; device[i - 1] = '\0';
@@ -88,19 +84,13 @@ void MainMenu(string filename, GPTDataTextUI* theGPT) {
do { do {
cout << "\nCommand (? for help): "; cout << "\nCommand (? for help): ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
exit(1);
} // if
switch (*line) { switch (*line) {
case '\n': case '\n':
break; break;
case 'b': case 'B': case 'b': case 'B':
cout << "Enter backup filename to save: "; cout << "Enter backup filename to save: ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
exit(1);
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
} // if
sscanf(line, "%s", buFile); sscanf(line, "%s", buFile);
theGPT->SaveGPTBackup(buFile); theGPT->SaveGPTBackup(buFile);
break; break;
@@ -188,15 +178,12 @@ void ShowCommands(void) {
// issues an exit command, such as 'w' or 'q'. // issues an exit command, such as 'w' or 'q'.
void RecoveryMenu(string filename, GPTDataTextUI* theGPT) { void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
char line[255], buFile[255]; char line[255], buFile[255];
uint32_t temp1, numParts; uint32_t numParts;
int goOn = 1; int goOn = 1, temp1;
do { do {
cout << "\nRecovery/transformation command (? for help): "; cout << "\nRecovery/transformation command (? for help): ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
exit(1);
} // if
switch (*line) { switch (*line) {
case '\n': case '\n':
break; break;
@@ -232,17 +219,17 @@ void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
case 'g': case 'G': case 'g': case 'G':
numParts = theGPT->GetNumParts(); numParts = theGPT->GetNumParts();
temp1 = theGPT->XFormToMBR(); temp1 = theGPT->XFormToMBR();
if (temp1 > 0) { if (temp1 > 0)
cout << "\nConverted " << temp1 << " partitions. Finalize and exit? "; cout << "\nConverted " << temp1 << " partitions. Finalize and exit? ";
if (GetYN() == 'Y') { if ((temp1 > 0) && (GetYN() == 'Y')) {
if ((theGPT->DestroyGPT() > 0) && (theGPT->SaveMBR())) if ((theGPT->DestroyGPT() > 0) && (theGPT->SaveMBR())) {
goOn = 0; goOn = 0;
} else { } // if
theGPT->MakeProtectiveMBR(); } else {
theGPT->SetGPTSize(numParts); theGPT->MakeProtectiveMBR();
cout << "Note: New protective MBR created\n\n"; theGPT->SetGPTSize(numParts);
} // if/else cout << "Note: New protective MBR created\n\n";
} // if } // if/else
break; break;
case 'h': case 'H': case 'h': case 'H':
theGPT->MakeHybrid(); theGPT->MakeHybrid();
@@ -252,10 +239,7 @@ void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
break; break;
case 'l': case 'L': case 'l': case 'L':
cout << "Enter backup filename to load: "; cout << "Enter backup filename to load: ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
exit(1);
} // if
sscanf(line, "%s", buFile); sscanf(line, "%s", buFile);
theGPT->LoadGPTBackup(buFile); theGPT->LoadGPTBackup(buFile);
break; break;
@@ -329,10 +313,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
do { do {
cout << "\nExpert command (? for help): "; cout << "\nExpert command (? for help): ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
switch (*line) { switch (*line) {
case '\n': case '\n':
break; break;
@@ -346,10 +327,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
if (theGPT->GetPartRange(&temp1, &temp2) > 0) { if (theGPT->GetPartRange(&temp1, &temp2) > 0) {
pn = theGPT->GetPartNum(); pn = theGPT->GetPartNum();
cout << "Enter the partition's new unique GUID ('R' to randomize): "; cout << "Enter the partition's new unique GUID ('R' to randomize): ";
if (!fgets(guidStr, 255, stdin)) { ReadCString(guidStr, 255);
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) { if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetPartitionGUID(pn, (GUIDData) guidStr); theGPT->SetPartitionGUID(pn, (GUIDData) guidStr);
cout << "New GUID is " << theGPT->operator[](pn).GetUniqueGUID() << "\n"; cout << "New GUID is " << theGPT->operator[](pn).GetUniqueGUID() << "\n";
@@ -371,10 +349,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
break; break;
case 'g': case 'G': case 'g': case 'G':
cout << "Enter the disk's unique GUID ('R' to randomize): "; cout << "Enter the disk's unique GUID ('R' to randomize): ";
if (!fgets(guidStr, 255, stdin)) { ReadCString(guidStr, 255);
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) { if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetDiskGUID((GUIDData) guidStr); theGPT->SetDiskGUID((GUIDData) guidStr);
cout << "The new disk GUID is " << theGPT->GetDiskGUID() << "\n"; cout << "The new disk GUID is " << theGPT->GetDiskGUID() << "\n";
@@ -423,16 +398,13 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
case 'u': case 'U': case 'u': case 'U':
cout << "Type device filename, or press <Enter> to exit: "; cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255]; device = new char[255];
if (!fgets(device, 255, stdin)) { ReadCString(device, 255);
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
i = strlen(device); i = strlen(device);
if (i && device[i - 1] == '\n') if (i && device[i - 1] == '\n')
device[i - 1] = '\0'; device[i - 1] = '\0';
if (*device && strlen(device) > 0) { if (*device && strlen(device) > 0) {
secondDevice = *theGPT; secondDevice = *theGPT;
secondDevice.SetFile(device); secondDevice.SetDisk(device);
secondDevice.SaveGPTData(0); secondDevice.SaveGPTData(0);
} // if } // if
delete[] device; delete[] device;

62
gpt.cc
View File

@@ -26,7 +26,7 @@
#include "parttypes.h" #include "parttypes.h"
#include "attributes.h" #include "attributes.h"
#include "diskio.h" #include "diskio.h"
#include "partnotes.h" //#include "partnotes.h"
using namespace std; using namespace std;
@@ -61,7 +61,6 @@ GPTData::GPTData(void) {
sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0; beQuiet = 0;
whichWasUsed = use_new; whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0; mainHeader.numParts = 0;
numParts = 0; numParts = 0;
SetGPTSize(NUM_GPT_ENTRIES); SetGPTSize(NUM_GPT_ENTRIES);
@@ -84,7 +83,6 @@ GPTData::GPTData(string filename) {
sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0; beQuiet = 0;
whichWasUsed = use_new; whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0; mainHeader.numParts = 0;
numParts = 0; numParts = 0;
if (!LoadPartitions(filename)) if (!LoadPartitions(filename))
@@ -609,7 +607,7 @@ int GPTData::FindInsanePartitions(void) {
// Change the filename associated with the GPT. Used for duplicating // Change the filename associated with the GPT. Used for duplicating
// the partition table to a new disk and saving backups. // the partition table to a new disk and saving backups.
// Returns 1 on success, 0 on failure. // Returns 1 on success, 0 on failure.
int GPTData::SetFile(const string & deviceFilename) { int GPTData::SetDisk(const string & deviceFilename) {
int err, allOK = 1; int err, allOK = 1;
device = deviceFilename; device = deviceFilename;
@@ -622,7 +620,7 @@ int GPTData::SetFile(const string & deviceFilename) {
protectiveMBR.SetDiskSize(diskSize); protectiveMBR.SetDiskSize(diskSize);
protectiveMBR.SetBlockSize(blockSize); protectiveMBR.SetBlockSize(blockSize);
return allOK; return allOK;
} // GPTData::SetFile() } // GPTData::SetDisk()
// Scan for partition data. This function loads the MBR data (regular MBR or // Scan for partition data. This function loads the MBR data (regular MBR or
// protective MBR) and loads BSD disklabel data (which is probably invalid). // protective MBR) and loads BSD disklabel data (which is probably invalid).
@@ -991,7 +989,7 @@ int GPTData::SaveGPTData(int quiet) {
if ((allOK) && (!quiet)) { if ((allOK) && (!quiet)) {
cout << "\nFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING\n" cout << "\nFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING\n"
<< "PARTITIONS!!\n\nDo you want to proceed, possibly destroying your data? "; << "PARTITIONS!!\n\nDo you want to proceed? ";
answer = GetYN(); answer = GetYN();
if (answer == 'Y') { if (answer == 'Y') {
cout << "OK; writing new GUID partition table (GPT).\n"; cout << "OK; writing new GUID partition table (GPT).\n";
@@ -1554,58 +1552,6 @@ int GPTData::OnePartToMBR(uint32_t gptPart, int mbrPart) {
return allOK; return allOK;
} // GPTData::OnePartToMBR() } // GPTData::OnePartToMBR()
// Convert partitions to MBR form (primary and logical) and return
// the number done. Partitions are specified in a PartNotes variable,
// which includes pointers to GPT partition numbers. A partition number
// of MBR_EFI_GPT means to place an EFI GPT protective partition in that
// location in the table, and MBR_EMPTY means not to create a partition
// in that table position. If the partition type entry for a partition
// is 0, a default entry is used, based on the GPT partition type code.
// Returns the number of partitions converted, NOT counting EFI GPT
// protective partitions or extended partitions.
int GPTData::PartsToMBR(PartNotes * notes) {
int mbrNum = 0, numConverted = 0;
struct PartInfo convInfo;
protectiveMBR.EmptyMBR(0);
protectiveMBR.SetDiskSize(diskSize);
if (!notes->IsLegal())
notes->MakeItLegal();
notes->Rewind();
while (notes->GetNextInfo(&convInfo) >= 0) {
if ((convInfo.origPartNum >= 0) && (convInfo.type == PRIMARY)) {
numConverted += OnePartToMBR((uint32_t) convInfo.origPartNum, mbrNum);
if (convInfo.hexCode != 0)
protectiveMBR.SetPartType(mbrNum, convInfo.hexCode);
if (convInfo.active)
protectiveMBR.SetPartBootable(mbrNum);
mbrNum++;
} // if
if (convInfo.origPartNum == MBR_EFI_GPT)
mbrNum++;
} // for
// Now go through and set sizes for MBR_EFI_GPT partitions....
notes->Rewind();
mbrNum = 0;
while (notes->GetNextInfo(&convInfo) >= 0) {
if ((convInfo.origPartNum >= 0) && (convInfo.type == PRIMARY))
mbrNum++;
if (convInfo.origPartNum == MBR_EFI_GPT) {
if (protectiveMBR.FindFirstAvailable() == UINT32_C(1)) {
protectiveMBR.MakePart(mbrNum, 1, protectiveMBR.FindLastInFree(1), convInfo.hexCode);
protectiveMBR.SetHybrid();
} else {
protectiveMBR.MakeBiggestPart(mbrNum, convInfo.hexCode);
} // if/else
mbrNum++;
} // if
} // while
// Now do logical partition(s)...
protectiveMBR.SetDisk(&myDisk);
numConverted += protectiveMBR.CreateLogicals(notes);
return numConverted;
} // GPTData::PartsToMBR()
/********************************************************************** /**********************************************************************
* * * *

15
gpt.h
View File

@@ -11,19 +11,10 @@
#include "mbr.h" #include "mbr.h"
#include "bsd.h" #include "bsd.h"
#include "gptpart.h" #include "gptpart.h"
#include "gptpartnotes.h"
#ifndef __GPTSTRUCTS #ifndef __GPTSTRUCTS
#define __GPTSTRUCTS #define __GPTSTRUCTS
#define GPTFDISK_VERSION "0.6.15-pre1"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
// of course.)
#define MBR_EFI_GPT -1
#define MBR_EMPTY -2
// Default values for sector alignment // Default values for sector alignment
#define DEFAULT_ALIGNMENT 2048 #define DEFAULT_ALIGNMENT 2048
#define MAX_ALIGNMENT 65536 #define MAX_ALIGNMENT 65536
@@ -113,13 +104,14 @@ public:
void RecomputeCRCs(void); void RecomputeCRCs(void);
void RebuildMainHeader(void); void RebuildMainHeader(void);
void RebuildSecondHeader(void); void RebuildSecondHeader(void);
int VerifyMBR(void) {return protectiveMBR.Verify();} int VerifyMBR(void) {return protectiveMBR.FindOverlaps();}
int FindHybridMismatches(void); int FindHybridMismatches(void);
int FindOverlaps(void); int FindOverlaps(void);
int FindInsanePartitions(void); int FindInsanePartitions(void);
// Load or save data from/to disk // Load or save data from/to disk
int SetFile(const string & deviceFilename); int SetDisk(const string & deviceFilename);
DiskIO* GetDisk(void) {return &myDisk;}
int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);} int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);}
int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);} int WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);}
void PartitionScan(void); void PartitionScan(void);
@@ -169,6 +161,7 @@ public:
int Align(uint64_t* sector); int Align(uint64_t* sector);
// Return data about the GPT structures.... // Return data about the GPT structures....
void SetProtectiveMBR(BasicMBRData & newMBR) {protectiveMBR = newMBR;}
int GetPartRange(uint32_t* low, uint32_t* high); int GetPartRange(uint32_t* low, uint32_t* high);
int FindFirstFreePart(void); int FindFirstFreePart(void);
uint32_t GetNumParts(void) {return mainHeader.numParts;} uint32_t GetNumParts(void) {return mainHeader.numParts;}

View File

@@ -36,7 +36,7 @@ GPTPart::~GPTPart(void) {
} // destructor } // destructor
// Return the gdisk-specific two-byte hex code for the partition // Return the gdisk-specific two-byte hex code for the partition
uint16_t GPTPart::GetHexType(void) { uint16_t GPTPart::GetHexType(void) const {
return partitionType.GetHexType(); return partitionType.GetHexType();
} // GPTPart::GetHexType() } // GPTPart::GetHexType()
@@ -48,7 +48,7 @@ string GPTPart::GetTypeName(void) {
// Compute and return the partition's length (or 0 if the end is incorrectly // Compute and return the partition's length (or 0 if the end is incorrectly
// set before the beginning). // set before the beginning).
uint64_t GPTPart::GetLengthLBA(void) { uint64_t GPTPart::GetLengthLBA(void) const {
uint64_t length = 0; uint64_t length = 0;
if (firstLBA <= lastLBA) if (firstLBA <= lastLBA)
@@ -98,10 +98,7 @@ void GPTPart::SetName(const string & theName) {
if (theName == "") { // No name specified, so get one from the user if (theName == "") { // No name specified, so get one from the user
cout << "Enter name: "; cout << "Enter name: ";
if (!fgets(newName, NAME_SIZE / 2 + 1, stdin)) { ReadCString(newName, NAME_SIZE / 2 + 1);
cerr << "Critical error! Failed fgets() in GPTPart::SetName()!\n";
exit(1);
}
// Input is likely to include a newline, so remove it.... // Input is likely to include a newline, so remove it....
i = strlen(newName); i = strlen(newName);
@@ -203,7 +200,6 @@ void GPTPart::BlankPartition(void) {
int GPTPart::DoTheyOverlap(const GPTPart & other) { int GPTPart::DoTheyOverlap(const GPTPart & other) {
// Don't bother checking unless these are defined (both start and end points // Don't bother checking unless these are defined (both start and end points
// are 0 for undefined partitions, so just check the start points) // are 0 for undefined partitions, so just check the start points)
// cout << "Entering GPTPart::DoTheyOverlap()\n";
return firstLBA && other.firstLBA && return firstLBA && other.firstLBA &&
(firstLBA <= other.lastLBA) != (lastLBA < other.firstLBA); (firstLBA <= other.lastLBA) != (lastLBA < other.firstLBA);
} // GPTPart::DoTheyOverlap() } // GPTPart::DoTheyOverlap()
@@ -231,10 +227,7 @@ void GPTPart::ChangeType(void) {
cout << "Current type is '" << GetTypeName() << "'\n"; cout << "Current type is '" << GetTypeName() << "'\n";
do { do {
cout << "Hex code or GUID (L to show codes, Enter = 0700): "; cout << "Hex code or GUID (L to show codes, Enter = 0700): ";
if (!fgets(line, sizeof(line), stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in GPTPart::ChangeType()!\n";
exit(1);
} // if
if ((line[0] == 'L') || (line[0] == 'l')) { if ((line[0] == 'L') || (line[0] == 'l')) {
partitionType.ShowAllTypes(); partitionType.ShowAllTypes();
} else { } else {

View File

@@ -53,12 +53,12 @@ class GPTPart {
// Simple data retrieval: // Simple data retrieval:
PartType & GetType(void) {return partitionType;} PartType & GetType(void) {return partitionType;}
uint16_t GetHexType(void); uint16_t GetHexType(void) const;
string GetTypeName(void); string GetTypeName(void);
const GUIDData GetUniqueGUID(void) const {return uniqueGUID;} const GUIDData GetUniqueGUID(void) const {return uniqueGUID;}
uint64_t GetFirstLBA(void) const {return firstLBA;} uint64_t GetFirstLBA(void) const {return firstLBA;}
uint64_t GetLastLBA(void) const {return lastLBA;} uint64_t GetLastLBA(void) const {return lastLBA;}
uint64_t GetLengthLBA(void); uint64_t GetLengthLBA(void) const;
Attributes GetAttributes(void) {return attributes;} Attributes GetAttributes(void) {return attributes;}
void ShowAttributes(uint32_t partNum) {attributes.ShowAttributes(partNum);} void ShowAttributes(uint32_t partNum) {attributes.ShowAttributes(partNum);}
string GetDescription(void); string GetDescription(void);

View File

@@ -29,7 +29,7 @@
#include <cstdio> #include <cstdio>
#include "attributes.h" #include "attributes.h"
#include "gpttext.h" #include "gpttext.h"
#include "gptpartnotes.h" //#include "gptpartnotes.h"
#include "support.h" #include "support.h"
using namespace std; using namespace std;
@@ -235,7 +235,10 @@ void GPTDataTextUI::CreatePartition(void) {
partitions[partNum].ChangeType(); partitions[partNum].ChangeType();
partitions[partNum].SetDefaultDescription(); partitions[partNum].SetDefaultDescription();
} else { } else {
cout << "No free sectors available\n"; if (firstFreePart >= numParts)
cout << "No table partition entries left\n";
else
cout << "No free sectors available\n";
} // if/else } // if/else
} // GPTDataTextUI::CreatePartition() } // GPTDataTextUI::CreatePartition()
@@ -353,24 +356,22 @@ void GPTDataTextUI::ShowDetails(void) {
void GPTDataTextUI::MakeHybrid(void) { void GPTDataTextUI::MakeHybrid(void) {
uint32_t partNums[3]; uint32_t partNums[3];
char line[255]; char line[255];
int numPartsToCvt, i, j, mbrNum, bootable = 0; int numPartsToCvt, i, j, mbrNum = 0;
unsigned int hexCode = 0; unsigned int hexCode = 0;
struct PartInfo *newNote; MBRPart hybridPart;
PartNotes notes; MBRData hybridMBR;
char eeFirst = 'Y'; // Whether EFI GPT (0xEE) partition comes first in table char eeFirst = 'Y'; // Whether EFI GPT (0xEE) partition comes first in table
cout << "\nWARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,\n" cout << "\nWARNING! Hybrid MBRs are flaky and dangerous! If you decide not to use one,\n"
<< "just hit the Enter key at the below prompt and your MBR partition table will\n" << "just hit the Enter key at the below prompt and your MBR partition table will\n"
<< "be untouched.\n\n\a"; << "be untouched.\n\n\a";
hybridMBR.SetDisk(&myDisk);
// Now get the numbers of up to three partitions to add to the // Now get the numbers of up to three partitions to add to the
// hybrid MBR.... // hybrid MBR....
cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n" cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
<< "added to the hybrid MBR, in sequence: "; << "added to the hybrid MBR, in sequence: ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in GPTDataTextUI::MakeHybrid()!\n";
exit(1);
} // if
numPartsToCvt = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]); numPartsToCvt = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
if (numPartsToCvt > 0) { if (numPartsToCvt > 0) {
@@ -379,148 +380,64 @@ void GPTDataTextUI::MakeHybrid(void) {
} // if } // if
for (i = 0; i < numPartsToCvt; i++) { for (i = 0; i < numPartsToCvt; i++) {
newNote = new struct PartInfo; j = partNums[i] - 1;
j = newNote->origPartNum = partNums[i] - 1;
if (partitions[j].IsUsed()) { if (partitions[j].IsUsed()) {
mbrNum = i + (eeFirst == 'Y'); mbrNum = i + (eeFirst == 'Y');
cout << "\nCreating entry for GPT partition #" << j + 1 cout << "\nCreating entry for GPT partition #" << j + 1
<< " (MBR partition #" << mbrNum + 1 << ")\n"; << " (MBR partition #" << mbrNum + 1 << ")\n";
newNote->hexCode = GetMBRTypeCode(partitions[j].GetHexType() / 256); hybridPart.SetType(GetMBRTypeCode(partitions[j].GetHexType() / 256));
newNote->firstLBA = partitions[j].GetFirstLBA(); hybridPart.SetLocation(partitions[j].GetFirstLBA(), partitions[j].GetLengthLBA());
newNote->lastLBA = partitions[j].GetLastLBA(); hybridPart.SetInclusion(PRIMARY);
newNote->type = PRIMARY;
cout << "Set the bootable flag? "; cout << "Set the bootable flag? ";
if (GetYN() == 'Y') if (GetYN() == 'Y')
newNote->active = 1; hybridPart.SetStatus(1);
else else
newNote->active = 0; hybridPart.SetStatus(0);
notes.AddToEnd(newNote); hybridPart.SetInclusion(PRIMARY);
} else { } else {
delete newNote;
cerr << "\nGPT partition #" << j + 1 << " does not exist; skipping.\n"; cerr << "\nGPT partition #" << j + 1 << " does not exist; skipping.\n";
} // if/else } // if/else
hybridMBR.AddPart(mbrNum, hybridPart);
} // for } // for
if (numPartsToCvt > 0) { // User opted to create a hybrid MBR.... if (numPartsToCvt > 0) { // User opted to create a hybrid MBR....
// Create EFI protective partition that covers the start of the disk. // Create EFI protective partition that covers the start of the disk.
// If this location (covering the main GPT data structures) is omitted, // If this location (covering the main GPT data structures) is omitted,
// Linux won't find any partitions on the disk. // Linux won't find any partitions on the disk.
newNote = new struct PartInfo; hybridPart.SetLocation(1, hybridMBR.FindLastInFree(1));
newNote->origPartNum = MBR_EFI_GPT; hybridPart.SetStatus(0);
newNote->firstLBA = 1; hybridPart.SetType(0xEE);
newNote->active = 0; hybridPart.SetInclusion(PRIMARY);
newNote->hexCode = 0xEE;
newNote->type = PRIMARY;
// newNote firstLBA and lastLBA are computed later... // newNote firstLBA and lastLBA are computed later...
if (eeFirst == 'Y') { if (eeFirst == 'Y') {
notes.AddToStart(newNote); hybridMBR.AddPart(0, hybridPart);
} else { } else {
notes.AddToEnd(newNote); hybridMBR.AddPart(3, hybridPart);
} // else } // else
protectiveMBR.SetHybrid(); hybridMBR.SetHybrid();
// ... and for good measure, if there are any partition spaces left, // ... and for good measure, if there are any partition spaces left,
// optionally create another protective EFI partition to cover as much // optionally create another protective EFI partition to cover as much
// space as possible.... // space as possible....
if (notes.GetNumPrimary() < 4) { // unused entry.... if (hybridMBR.CountParts() < 4) { // unused entry....
cout << "\nUnused partition space(s) found. Use one to protect more partitions? "; cout << "\nUnused partition space(s) found. Use one to protect more partitions? ";
if (GetYN() == 'Y') { if (GetYN() == 'Y') {
while ((hexCode <= 0) || (hexCode > 255)) { while ((hexCode <= 0) || (hexCode > 255)) {
cout << "Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): "; cout << "Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): ";
// Comment on above: Mac OS treats disks with more than one // Comment on above: Mac OS treats disks with more than one
// 0xEE MBR partition as MBR disks, not as GPT disks. // 0xEE MBR partition as MBR disks, not as GPT disks.
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in GPTDataTextUI::MakeHybrid()\n";
exit(1);
} // if
sscanf(line, "%x", &hexCode); sscanf(line, "%x", &hexCode);
if (line[0] == '\n') if (line[0] == '\n')
hexCode = 0x00; hexCode = 0x00;
} // while } // while
newNote = new struct PartInfo; hybridMBR.MakeBiggestPart(3, 0xEE);
newNote->origPartNum = MBR_EFI_GPT;
newNote->active = 0;
newNote->hexCode = hexCode;
newNote->type = PRIMARY;
// newNote firstLBA and lastLBA are computed later...
notes.AddToEnd(newNote);
} // if (GetYN() == 'Y') } // if (GetYN() == 'Y')
} // if unused entry } // if unused entry
PartsToMBR(&notes); protectiveMBR = hybridMBR;
if (bootable > 0)
protectiveMBR.SetPartBootable(bootable);
} // if (numPartsToCvt > 0) } // if (numPartsToCvt > 0)
} // GPTDataTextUI::MakeHybrid() } // GPTDataTextUI::MakeHybrid()
// Assign GPT partitions to primary or logical status for conversion. The
// function first presents a suggested layout with as many logicals as
// possible, but gives the user the option to override this suggestion.
// Returns the number of partitions assigned (0 if problems or if the
// user aborts)
int GPTDataTextUI::AssignPrimaryOrLogical(GptPartNotes& notes) {
int i, partNum, allOK = 1, changesWanted = 1, countedParts, numPrimary = 0, numLogical = 0;
int newNumParts; // size of GPT table
// Sort and resize the GPT table. Resized to clear the sector before the
// first available sector, if possible, so as to enable turning the
// first partition into a logical, should that be desirable/necessary.
SortGPT();
countedParts = newNumParts = CountParts();
i = blockSize / GPT_SIZE;
if ((newNumParts % i) != 0) {
newNumParts = ((newNumParts / i) + 1) * i;
} // if
SetGPTSize(newNumParts);
// Takes notes on existing partitions: Create an initial assignment as
// primary or logical, set default MBR types, and then make it legal
// (drop partitions as required to fit in the MBR and as logicals).
allOK = (notes.PassPartitions(partitions, this, numParts, blockSize) == (int) numParts);
for (i = 0; i < countedParts; i++)
notes.SetMbrHexType(i, partitions[i].GetHexType() / 255);
notes.MakeItLegal();
while (allOK && changesWanted) {
notes.ShowSummary();
cout << "\n";
partNum = GetNumber(-1, countedParts, -2,
"Type partition to change, 0 to accept, -1 to abort: ");
switch (partNum) {
case -1:
allOK = 0;
break;
case 0:
changesWanted = 0;
break;
default:
allOK = notes.MakeChange(partNum - 1);
break;
} // switch
} // while
i = 0;
if (allOK)
for (i = 0; i < countedParts; i++) {
switch (notes.GetType(i)) {
case PRIMARY:
numPrimary++;
break;
case LOGICAL:
numLogical++;
break;
} // switch
if (notes.GetActiveStatus(i))
protectiveMBR.SetPartBootable(i);
} // for
if (numPrimary > 4) {
cerr << "Warning! More than four primary partitions in "
<< "GPTDataTextUI::AssignPrimaryOrLogical()!\n";
allOK = 0;
} // if
return (allOK * (numPrimary + numLogical));
} // GPTDataTextUI::AssignPrimaryOrLogical()
// Convert the GPT to MBR form, storing partitions in the protectiveMBR // Convert the GPT to MBR form, storing partitions in the protectiveMBR
// variable. This function is necessarily limited; it may not be able to // variable. This function is necessarily limited; it may not be able to
// convert all partitions, depending on the disk size and available space // convert all partitions, depending on the disk size and available space
@@ -530,44 +447,18 @@ int GPTDataTextUI::AssignPrimaryOrLogical(GptPartNotes& notes) {
// is over 0, the calling function should call DestroyGPT() to destroy // is over 0, the calling function should call DestroyGPT() to destroy
// the GPT data, call SaveMBR() to save the MBR, and then exit. // the GPT data, call SaveMBR() to save the MBR, and then exit.
int GPTDataTextUI::XFormToMBR(void) { int GPTDataTextUI::XFormToMBR(void) {
int numToConvert, numReallyConverted = 0;
int origNumParts;
GptPartNotes notes;
GPTPart *tempGptParts;
uint32_t i; uint32_t i;
// Back up partition array, since we'll be sorting it and we want to protectiveMBR.EmptyMBR();
// be able to restore it in case the user aborts.... for (i = 0; i < numParts; i++) {
origNumParts = numParts; if (partitions[i].IsUsed()) {
tempGptParts = new GPTPart[numParts]; protectiveMBR.MakePart(i, partitions[i].GetFirstLBA(),
for (i = 0; i < numParts; i++) partitions[i].GetLengthLBA(),
tempGptParts[i] = partitions[i]; partitions[i].GetHexType() / 0x0100, 0);
} // if
notes.MakeItLegal(); } // for
numToConvert = AssignPrimaryOrLogical(notes); protectiveMBR.MakeItLegal();
return protectiveMBR.DoMenu();
if (numToConvert > 0) {
numReallyConverted = PartsToMBR(&notes);
if (numReallyConverted != numToConvert) {
cerr << "Error converting partitions to MBR; tried to convert "
<< numToConvert << " partitions,\nbut converted " << numReallyConverted
<< ". Aborting operation!\n";
numReallyConverted = 0;
protectiveMBR.MakeProtectiveMBR();
} // if/else
} // if
// A problem or the user aborted; restore backup of unsorted and
// original-sized partition table and delete the sorted and
// resized one; otherwise free the backup table's memory....
if (numReallyConverted == 0) {
delete[] partitions;
partitions = tempGptParts;
SetGPTSize(origNumParts);
} else {
delete[] tempGptParts;
} // if
return numReallyConverted;
} // GPTDataTextUI::XFormToMBR() } // GPTDataTextUI::XFormToMBR()
/********************************************************************* /*********************************************************************
@@ -589,10 +480,7 @@ int GetMBRTypeCode(int defType) {
cout << "Enter an MBR hex code (default " << hex; cout << "Enter an MBR hex code (default " << hex;
cout.width(2); cout.width(2);
cout << defType << "): " << dec; cout << defType << "): " << dec;
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in GetMBRTypeCode()\n";
exit(1);
} // if
if (line[0] == '\n') if (line[0] == '\n')
typeCode = defType; typeCode = defType;
else else

View File

@@ -50,7 +50,6 @@ class GPTDataTextUI : public GPTData {
int DestroyGPTwPrompt(void); // Returns 1 if user proceeds int DestroyGPTwPrompt(void); // Returns 1 if user proceeds
void ShowDetails(void); void ShowDetails(void);
void MakeHybrid(void); void MakeHybrid(void);
int AssignPrimaryOrLogical(GptPartNotes& notes);
int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
}; // class GPTDataTextUI }; // class GPTDataTextUI

55
mbr.cc
View File

@@ -28,12 +28,18 @@ using namespace std;
* * * *
****************************************/ ****************************************/
// Assignment operator -- copy entire set of MBR data. /* // Assignment operator -- copy entire set of MBR data.
MBRData & MBRData::operator=(const MBRData & orig) { MBRData & MBRData::operator=(const MBRData & orig) {
BasicMBRData::operator=(orig); BasicMBRData::operator=(orig);
return *this; return *this;
} // MBRData::operator=() */ } // MBRData::operator=() */
// Assignment operator -- copy entire set of MBR data.
MBRData & MBRData::operator=(const BasicMBRData & orig) {
BasicMBRData::operator=(orig);
return *this;
} // MBRData::operator=()
/***************************************************** /*****************************************************
* * * *
* Functions to create, delete, or change partitions * * Functions to create, delete, or change partitions *
@@ -50,15 +56,15 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
MBRSignature = MBR_SIGNATURE; MBRSignature = MBR_SIGNATURE;
diskSignature = UINT32_C(0); diskSignature = UINT32_C(0);
partitions[0].status = UINT8_C(0); // Flag the protective part. as unbootable partitions[0].SetStatus(0); // Flag the protective part. as unbootable
partitions[0].partitionType = UINT8_C(0xEE); partitions[0].SetType(UINT8_C(0xEE));
partitions[0].firstLBA = UINT32_C(1);
if (diskSize < UINT32_MAX) { // If the disk is under 2TiB if (diskSize < UINT32_MAX) { // If the disk is under 2TiB
partitions[0].lengthLBA = (uint32_t) diskSize - UINT32_C(1); partitions[0].SetLocation(UINT32_C(1), (uint32_t) diskSize - UINT32_C(1));
} else { // disk is too big to represent, so fake it... } else { // disk is too big to represent, so fake it...
partitions[0].lengthLBA = UINT32_MAX; partitions[0].SetLocation(UINT32_C(1), UINT32_MAX);
} // if/else } // if/else
partitions[0].SetInclusion(PRIMARY);
// Write CHS data. This maxes out the use of the disk, as much as // Write CHS data. This maxes out the use of the disk, as much as
// possible -- even to the point of exceeding the capacity of sub-8GB // possible -- even to the point of exceeding the capacity of sub-8GB
@@ -66,9 +72,9 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
// although normal MBR disks max out at 0xfeffff. FWIW, both GNU Parted // although normal MBR disks max out at 0xfeffff. FWIW, both GNU Parted
// and Apple's Disk Utility use 0xfeffff, and the latter puts that // and Apple's Disk Utility use 0xfeffff, and the latter puts that
// value in for the FIRST sector, too! // value in for the FIRST sector, too!
LBAtoCHS(1, partitions[0].firstSector); /* LBAtoCHS(1, partitions[0].firstSector);
if (LBAtoCHS(partitions[0].lengthLBA, partitions[0].lastSector) == 0) if (LBAtoCHS(partitions[0].lengthLBA, partitions[0].lastSector) == 0)
partitions[0].lastSector[0] = 0xFF; partitions[0].lastSector[0] = 0xFF; */
state = gpt; state = gpt;
} // MBRData::MakeProtectiveMBR() } // MBRData::MakeProtectiveMBR()
@@ -76,27 +82,27 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
// Optimizes the size of the 0xEE (EFI GPT) partition // Optimizes the size of the 0xEE (EFI GPT) partition
void MBRData::OptimizeEESize(void) { void MBRData::OptimizeEESize(void) {
int i, typeFlag = 0; int i, typeFlag = 0;
uint32_t after; uint64_t after;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
// Check for non-empty and non-0xEE partitions // Check for non-empty and non-0xEE partitions
if ((partitions[i].partitionType != 0xEE) && (partitions[i].partitionType != 0x00)) if ((partitions[i].GetType() != 0xEE) && (partitions[i].GetType() != 0x00))
typeFlag++; typeFlag++;
if (partitions[i].partitionType == 0xEE) { if (partitions[i].GetType() == 0xEE) {
// Blank space before this partition; fill it.... // Blank space before this partition; fill it....
if (IsFree(partitions[i].firstLBA - 1)) { if (SectorUsedAs(partitions[i].GetStartLBA() - 1, 4) == NONE) {
partitions[i].firstLBA = FindFirstInFree(partitions[i].firstLBA - 1); partitions[i].SetStartLBA(FindFirstInFree(partitions[i].GetStartLBA() - 1));
} // if } // if
// Blank space after this partition; fill it.... // Blank space after this partition; fill it....
after = partitions[i].firstLBA + partitions[i].lengthLBA; after = partitions[i].GetStartLBA() + partitions[i].GetLengthLBA();
if (IsFree(after)) { if (SectorUsedAs(after, 4) == NONE) {
partitions[i].lengthLBA = FindLastInFree(after) - partitions[i].firstLBA + 1; partitions[i].SetLengthLBA(FindLastInFree(after) - partitions[i].GetStartLBA() + 1);
} // if free space after } // if free space after
if (after > diskSize) { if (after > diskSize) {
if (diskSize < UINT32_MAX) { // If the disk is under 2TiB if (diskSize < UINT32_MAX) { // If the disk is under 2TiB
partitions[0].lengthLBA = (uint32_t) diskSize - partitions[i].firstLBA; partitions[i].SetLengthLBA((uint32_t) diskSize - partitions[i].GetStartLBA());
} else { // disk is too big to represent, so fake it... } else { // disk is too big to represent, so fake it...
partitions[0].lengthLBA = UINT32_MAX - partitions[i].firstLBA; partitions[i].SetLengthLBA(UINT32_MAX - partitions[i].GetStartLBA());
} // if/else } // if/else
} // if protective partition is too big } // if protective partition is too big
RecomputeCHS(i); RecomputeCHS(i);
@@ -118,8 +124,8 @@ int MBRData::DeleteByLocation(uint64_t start64, uint64_t length64) {
start32 = (uint32_t) start64; start32 = (uint32_t) start64;
length32 = (uint32_t) length64; length32 = (uint32_t) length64;
for (i = 0; i < MAX_MBR_PARTS; i++) { for (i = 0; i < MAX_MBR_PARTS; i++) {
if ((partitions[i].firstLBA == start32) && (partitions[i].lengthLBA == length32) && if ((partitions[i].GetType() != 0xEE) && (partitions[i].GetStartLBA() == start32)
(partitions[i].partitionType != 0xEE)) { && (partitions[i].GetLengthLBA() == length32)) {
DeletePartition(i); DeletePartition(i);
if (state == hybrid) if (state == hybrid)
OptimizeEESize(); OptimizeEESize();
@@ -138,7 +144,7 @@ int MBRData::DeleteByLocation(uint64_t start64, uint64_t length64) {
// Return the MBR data as a GPT partition.... // Return the MBR data as a GPT partition....
GPTPart MBRData::AsGPT(int i) { GPTPart MBRData::AsGPT(int i) {
MBRRecord* origPart; MBRPart* origPart;
GPTPart newPart; GPTPart newPart;
uint8_t origType; uint8_t origType;
uint64_t firstSector, lastSector; uint64_t firstSector, lastSector;
@@ -146,7 +152,7 @@ GPTPart MBRData::AsGPT(int i) {
newPart.BlankPartition(); newPart.BlankPartition();
origPart = GetPartition(i); origPart = GetPartition(i);
if (origPart != NULL) { if (origPart != NULL) {
origType = origPart->partitionType; origType = origPart->GetType();
// don't convert extended, hybrid protective, or null (non-existent) // don't convert extended, hybrid protective, or null (non-existent)
// partitions (Note similar protection is in GPTData::XFormPartitions(), // partitions (Note similar protection is in GPTData::XFormPartitions(),
@@ -154,10 +160,9 @@ GPTPart MBRData::AsGPT(int i) {
// context in the future....) // context in the future....)
if ((origType != 0x05) && (origType != 0x0f) && (origType != 0x85) && if ((origType != 0x05) && (origType != 0x0f) && (origType != 0x85) &&
(origType != 0x00) && (origType != 0xEE)) { (origType != 0x00) && (origType != 0xEE)) {
firstSector = (uint64_t) origPart->firstLBA; firstSector = (uint64_t) origPart->GetStartLBA();
newPart.SetFirstLBA(firstSector); newPart.SetFirstLBA(firstSector);
lastSector = firstSector + (uint64_t) origPart->lengthLBA; lastSector = (uint64_t) origPart->GetLastLBA();
if (lastSector > 0) lastSector--;
newPart.SetLastLBA(lastSector); newPart.SetLastLBA(lastSector);
newPart.SetType(((uint16_t) origType) * 0x0100); newPart.SetType(((uint16_t) origType) * 0x0100);
newPart.RandomizeUniqueGUID(); newPart.RandomizeUniqueGUID();

4
mbr.h
View File

@@ -26,11 +26,11 @@ using namespace std;
// Full data in tweaked MBR format // Full data in tweaked MBR format
class MBRData : public BasicMBRData { class MBRData : public BasicMBRData {
protected: protected:
int foo;
public: public:
MBRData(void) {} MBRData(void) {}
MBRData(string deviceFilename) : BasicMBRData(deviceFilename) {} MBRData(string deviceFilename) : BasicMBRData(deviceFilename) {}
MBRData & operator=(const MBRData & orig); MBRData & operator=(const BasicMBRData & orig);
// MBRData & operator=(const MBRData & orig);
// Functions to create, delete, or change partitions // Functions to create, delete, or change partitions
// Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact // Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact

View File

@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com) .\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License .\" May be distributed under the GNU General Public License
.TH "SGDISK" "8" "0.6.14" "Roderick W. Smith" "GPT fdisk Manual" .TH "SGDISK" "8" "0.7.0" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME" .SH "NAME"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS" .SH "SYNOPSIS"
@@ -470,7 +470,7 @@ Non\-GPT disk detected and no \fI\-g\fR option
.B 4 .B 4
An error prevented saving changes An error prevented saving changes
.SH "BUGS" .SH "BUGS"
As of January 2011 (version 0.6.14), \fBsgdisk\fR As of March 2011 (version 0.7.00), \fBsgdisk\fR
should be considered beta software. Known bugs and limitations include: should be considered beta software. Known bugs and limitations include:
.TP .TP
@@ -506,7 +506,7 @@ preserved when loading and saving partitions.
The program can load only up to 128 partitions (4 primary partitions and The program can load only up to 128 partitions (4 primary partitions and
124 logical partitions) when converting from MBR format. This limit can 124 logical partitions) when converting from MBR format. This limit can
be raised by changing the \fI#define MAX_MBR_PARTS\fR line in the be raised by changing the \fI#define MAX_MBR_PARTS\fR line in the
\fImbr.h\fR source code file and recompiling; however, such a change \fIbasicmbr.h\fR source code file and recompiling; however, such a change
will require using a larger\-than\-normal partition table. (The limit will require using a larger\-than\-normal partition table. (The limit
of 128 partitions was chosen because that number equals the 128 partitions of 128 partitions was chosen because that number equals the 128 partitions
supported by the most common partition table size.) supported by the most common partition table size.)
@@ -580,6 +580,7 @@ Contributors:
\fBmkfs (8)\fR, \fBmkfs (8)\fR,
\fBparted (8)\fR, \fBparted (8)\fR,
\fBsfdisk (8)\fR \fBsfdisk (8)\fR
\fBfixparts (8)\fR
\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR \fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR

View File

@@ -20,7 +20,7 @@
#include "gpt.h" #include "gpt.h"
#include "support.h" #include "support.h"
#include "parttypes.h" #include "parttypes.h"
#include "gptpartnotes.h" //#include "gptpartnotes.h"
#include "attributes.h" #include "attributes.h"
using namespace std; using namespace std;
@@ -248,12 +248,13 @@ int main(int argc, char *argv[]) {
theGPT.JustLooking(0); theGPT.JustLooking(0);
if (BuildMBR(theGPT, mbrParts, 0) == 1) { if (BuildMBR(theGPT, mbrParts, 0) == 1) {
if (!pretend) { if (!pretend) {
if (theGPT.SaveMBR()) if (theGPT.SaveMBR()) {
theGPT.DestroyGPT(); theGPT.DestroyGPT();
else } else
cerr << "Problem saving MBR!\n"; cerr << "Problem saving MBR!\n";
} // if } // if
saveNonGPT = 0; saveNonGPT = 0;
pretend = 1; // Not really, but works around problem if -g is used with this...
saveData = 0; saveData = 0;
} // if } // if
break; break;
@@ -312,7 +313,7 @@ int main(int argc, char *argv[]) {
break; break;
case 'R': case 'R':
secondDevice = theGPT; secondDevice = theGPT;
secondDevice.SetFile(outDevice); secondDevice.SetDisk(outDevice);
secondDevice.JustLooking(0); secondDevice.JustLooking(0);
// secondDevice.FixupMBR(); // secondDevice.FixupMBR();
secondDevice.SaveGPTData(1); secondDevice.SaveGPTData(1);
@@ -382,8 +383,9 @@ int main(int argc, char *argv[]) {
break; break;
} // switch } // switch
} // while } // while
if ((saveData) && (!neverSaveData) && (saveNonGPT) && (!pretend)) if ((saveData) && (!neverSaveData) && (saveNonGPT) && (!pretend)) {
theGPT.SaveGPTData(1); theGPT.SaveGPTData(1);
}
if (saveData && (!saveNonGPT)) { if (saveData && (!saveNonGPT)) {
cout << "Non-GPT disk; not saving changes. Use -g to override.\n"; cout << "Non-GPT disk; not saving changes. Use -g to override.\n";
retval = 3; retval = 3;
@@ -428,34 +430,33 @@ int main(int argc, char *argv[]) {
// Create a hybrid or regular MBR from GPT data structures // Create a hybrid or regular MBR from GPT data structures
int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) { int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) {
int numParts, allOK = 1, i; int numParts, allOK = 1, i, origPartNum;
GptPartNotes notes; // GptPartNotes notes;
struct PartInfo *newNote; // struct PartInfo *newNote;
MBRPart newPart;
BasicMBRData newMBR;
if ((&theGPT != NULL) && (argument != NULL)) { if ((&theGPT != NULL) && (argument != NULL)) {
numParts = CountColons(argument) + 1; numParts = CountColons(argument) + 1;
if (numParts <= (4 - isHybrid)) { if (numParts <= (4 - isHybrid)) {
newMBR.SetDisk(theGPT.GetDisk());
for (i = 0; i < numParts; i++) { for (i = 0; i < numParts; i++) {
newNote = new struct PartInfo; origPartNum = GetInt(argument, i + 1) - 1;
newNote->origPartNum = GetInt(argument, i + 1) - 1; newPart.SetInclusion(PRIMARY);
newNote->active = 0; newPart.SetLocation(theGPT[origPartNum].GetFirstLBA(),
newNote->hexCode = 0; // code to compute it from default theGPT[origPartNum].GetLengthLBA());
newNote->type = PRIMARY; newPart.SetStatus(0);
newNote->firstLBA = theGPT[newNote->origPartNum].GetFirstLBA(); newPart.SetType((uint8_t)(theGPT[origPartNum].GetHexType() / 0x0100));
newNote->lastLBA = theGPT[newNote->origPartNum].GetLastLBA(); newMBR.AddPart(i + isHybrid, newPart);
notes.AddToEnd(newNote);
} // for } // for
if (isHybrid) { if (isHybrid) {
newNote = new struct PartInfo; newPart.SetInclusion(PRIMARY);
newNote->origPartNum = MBR_EFI_GPT; newPart.SetLocation(1, newMBR.FindLastInFree(1));
newNote->active = 0; newPart.SetStatus(0);
newNote->hexCode = 0xEE; newPart.SetType(0xEE);
newNote->type = PRIMARY; newMBR.AddPart(0, newPart);
// newNote firstLBA and lastLBA are computed later...
notes.AddToStart(newNote);
} // if } // if
if (theGPT.PartsToMBR(&notes) != numParts) theGPT.SetProtectiveMBR(newMBR);
allOK = 0;
} else allOK = 0; } else allOK = 0;
} else allOK = 0; } else allOK = 0;
if (!allOK) if (!allOK)

View File

@@ -31,6 +31,14 @@
using namespace std; using namespace std;
char* ReadCString(char *inStr, int numchars) {
if (!fgets(inStr, 255, stdin)) {
cerr << "Critical error! Failed fgets() in ReadCString()\n";
exit(1);
} // if
return inStr;
} // ReadCString()
// Get a numeric value from the user, between low and high (inclusive). // Get a numeric value from the user, between low and high (inclusive).
// Keeps looping until the user enters a value within that range. // Keeps looping until the user enters a value within that range.
// If user provides no input, def (default value) is returned. // If user provides no input, def (default value) is returned.
@@ -66,10 +74,7 @@ char GetYN(void) {
do { do {
cout << "(Y/N): "; cout << "(Y/N): ";
if (!fgets(line, 255, stdin)) { ReadCString(line, 255);
cerr << "Critical error! Failed fgets() in GetYN()\n";
exit(1);
} // if
sscanf(line, "%c", &response); sscanf(line, "%c", &response);
if (response == 'y') if (response == 'y')
response = 'Y'; response = 'Y';
@@ -316,7 +321,7 @@ uint64_t GetInt(const string & argument, int itemNum) {
} // GetInt() } // GetInt()
// Extract string data from argument string, which should be colon-delimited // Extract string data from argument string, which should be colon-delimited
string GetString(const string & argument, int itemNum) { string GetString(string argument, int itemNum) {
size_t startPos = -1, endPos = -1; size_t startPos = -1, endPos = -1;
while (itemNum-- > 0) { while (itemNum-- > 0) {

View File

@@ -8,6 +8,8 @@
#ifndef __GPTSUPPORT #ifndef __GPTSUPPORT
#define __GPTSUPPORT #define __GPTSUPPORT
#define GPTFDISK_VERSION "0.7.0"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64 // Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64
// This used to use __DARWIN_UNIX03 rather than __APPLE__, but __APPLE__ // This used to use __DARWIN_UNIX03 rather than __APPLE__, but __APPLE__
@@ -22,6 +24,13 @@
#include <linux/fs.h> #include <linux/fs.h>
#endif #endif
// Microsoft Visual C++ only
#if defined (_MSC_VER)
#define sscanf sscanf_s
#define strcpy strcpy_s
#define sprintf sprintf_s
#endif
// Set this as a default // Set this as a default
#define SECTOR_SIZE UINT32_C(512) #define SECTOR_SIZE UINT32_C(512)
@@ -47,6 +56,7 @@
using namespace std; using namespace std;
char* ReadCString(char *inStr, int numchars);
int GetNumber(int low, int high, int def, const string & prompt); int GetNumber(int low, int high, int def, const string & prompt);
char GetYN(void); char GetYN(void);
uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize, const std::string& prompt); uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize, const std::string& prompt);
@@ -59,6 +69,6 @@ void ReverseBytes(void* theValue, int numBytes); // Reverses byte-order of theVa
// Extract colon-separated fields from a string.... // Extract colon-separated fields from a string....
uint64_t GetInt(const string & argument, int itemNum); uint64_t GetInt(const string & argument, int itemNum);
string GetString(const string & Info, int itemNum); string GetString(string argument, int itemNum);
#endif #endif