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
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
LDFLAGS+=
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
LIB_SRCS=$(NAMES:=.cc)
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk
all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(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
$(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 $(SRCS)
clean: #no pre-reqs
rm -f core *.o *~ gdisk sgdisk
rm -f core *.o *~ gdisk sgdisk fixparts
# what are the source dependencies
depend: $(SRCS)
@@ -32,354 +37,3 @@ $(OBJS):
# 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++
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
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
LIB_SRCS=$(NAMES:=.cc)
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CFLAGS)
all: gdisk sgdisk
all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gpttext.o gdisk.o
$(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
$(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
$(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
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
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_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h)
DEPEND= makedepend $(CFLAGS)
all: gdisk
all: gdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -luuid -static-libgcc -o gdisk.exe
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 $(SRCS)
@@ -25,7 +30,7 @@ clean: #no pre-reqs
rm -f core *.o *~ gdisk.exe sgdisk.exe
strip: #no pre-reqs
$(STRIP) gdisk.exe
$(STRIP) gdisk.exe fixparts.exe
# what are the source dependencies
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
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
@@ -15,11 +32,10 @@
- Changed largest drive that's not given a minimum 4 KiB alignment even
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.
- Implemented a number of code cleanups provided by an anonymous
contributor.
- Implemented a number of code cleanups provided by Florian Zumbiehl.
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
Introduction
------------
This software is intended as a (somewhat) fdisk-workalike program for
GPT-partitioned disks. 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:
This binary archive includes the source code for three related disk
partitioning programs:
- gdisk -- This program is modeled after Linux fdisk, but it operates on
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,
without losing data
@@ -16,10 +51,10 @@ sgdisk include:
* The ability to convert BSD disklabels in-place to create GPT
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
GNU Parted tends to corrupt (particularly for FAT partitions)
GNU Parted tends to corrupt
* Clear identification of the number of unallocated sectors on a
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
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
----------
To compile GPT fdisk, you must have appropriate development tools
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
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)
directories or library directories by setting the CXXFLAGS environment
variable or by editing the Makefile. The result should be program files
called gdisk and sgdisk. Typing "make gdisk" or "make sgdisk" will compile
only the requested programs. You can use these programs in place or copy
the files to a suitable directory, such as /usr/local/sbin. You can copy
the man pages (gdisk.8 and sgdisk.8) to /usr/local/man/man8 to make them
available.
called gdisk, sgdisk, and fixparts. Typing "make gdisk", "make sgdisk", or
"make fixparts" will compile only the requested programs. You can use these
programs in place or copy the files to a suitable directory, such as
/usr/local/sbin. You can copy the man pages (gdisk.8, sgdisk.8, and
fixparts.8) to /usr/local/man/man8 to make them available.
Caveats
-------
@@ -85,19 +189,17 @@ Caveats
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
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
I know full well that the odds of my missing something are high. This is
particularly true for large drives; my only direct testing with such disks
is with virtual QEMU disks. I've received user reports of success with
RAID arrays over 2TiB in size, though.
the QEMU and VirtualBox environments. Many others have now used the
software on their computers, as well. I believe all data-corruption bugs to
be squashed, but I know full well that the odds of my missing something are
high. This is particularly true for large drives; my only direct testing
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
Gentoo Linux (previously Ubuntu 8.04). I've also tested on 64-bit OpenSuSE,
32-bit Fedora 10, 32-bit Fedora 11, 32-bit Ubuntu 6.10, 64-bit Ubunut 9.10,
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. Problems relating to 64-bit integers on
the 32-bit Linux have been common during development and may crop up in the
future.
Gentoo Linux (previously Ubuntu 8.04). I've also tested on several other
32- and 64-bit Linux distributions Intel-based Mac OS X 10.5 and 10.6,
64-bit FreeBSD 7.1, and Windows 7.
Redistribution
--------------
@@ -122,3 +224,9 @@ Additional code contributors include:
- Yves Blusseau (1otnwmz02@sneakemail.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
******************************** IMPORTANT ********************************
Most versions of Windows cannot boot from a GPT disk, and most varieties
prior to Vista cannot read GPT disks. GPT fdisk is a partition editor for
GPT disks, and it will *AUTOMATICALLY CONVERT* MBR disks to GPT form.
Therefore, you should **NOT** use GPT fdisk on a Windows system unless you
fully understand what you're doing! If you accidentally use GPT fdisk on
your boot disk, or perhaps even on a data disk, you may find recovery to be
very difficult!
Most versions of Windows cannot boot from a GPT disk on BIOS-based
computers, and most varieties prior to Vista cannot read GPT disks. GPT
fdisk is a partition editor for GPT disks, and it will *AUTOMATICALLY
CONVERT* MBR disks to GPT form. Therefore, you should **NOT** use GPT fdisk
on a Windows system unless you fully understand what you're doing! If you
accidentally use GPT fdisk on your boot disk, or perhaps even on a data
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
the gdisk.html document (the Linux man page converted to HTML format) for
detailed use information. My GPT fdisk Web page,
the gdisk.html or fixparts.html documents (the Linux man pages converted to
HTML format) for detailed use information. My GPT fdisk Web page,
http://www.rodsbooks.com/gdisk/, provides a more tutorial introduction to
the software. I originally wrote GPT fdisk on Linux, and some Linux- and
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
for Windows.
To install the program, copy the gdisk.exe program file 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.
The FixParts program (fixparts.txt) is new with GPT fdisk 0.7.0. As
described in the main README file, this program fixes certain partition
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
"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
@@ -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
device name to change the disk edited.
If you pass the "-l" option in addition to the disk identifier, the program
displays the current partition table information and then exits. This use
entails no risk to MBR disks, since the program never writes data back to
the disk when used in this way.
If you pass the "-l" option to gdisk.exe in addition to the disk
identifier, the program displays the current partition table information
and then exits. This use entails no risk to MBR disks, since the program
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
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
The GUIDs generated by the program to uniquely identify disks and
partitions aren't "proper" GUIDs; they're purely random numbers. In
practice, this has caused me no problems; however, it's conceivable that
some disk utility will complain. The Unix versions of GPT fdisk generate
proper GUIDs, as of version 0.6.3. Note that this limitation applies ONLY
to the unique GUIDs for disks and partitions, not to the GUIDs used to
identify partition type codes; those are standardized and are handled
correctly by all versions of GPT fdisk.
The GUIDs generated by gdisk to uniquely identify disks and partitions
aren't "proper" GUIDs; they're purely random numbers. In practice, this has
caused me no problems; however, it's conceivable that some disk utility
will complain. The Unix versions of GPT fdisk generate proper GUIDs, as of
version 0.6.3. Note that this limitation applies ONLY to the unique GUIDs
for disks and partitions, not to the GUIDs used to identify partition type
codes; those are standardized and are handled correctly by all versions of
GPT fdisk.
Source Code and Compilation Issues
----------------------------------
@@ -98,7 +106,8 @@ compilers:
third-party stdint.h file (I used the one from
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
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
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 <sys/types.h>
#include "partnotes.h"
#include "diskio.h"
#include "mbrpart.h"
#ifndef __BASICMBRSTRUCTS
#define __BASICMBRSTRUCTS
#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
#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
// go. Also used when loading logical partitions.
#pragma pack(1)
@@ -68,19 +48,19 @@ protected:
uint16_t nulls;
// MAX_MBR_PARTS defaults to 128. This array holds both the primary and
// the logical partitions, to simplify data retrieval for GPT conversions.
struct MBRRecord partitions[MAX_MBR_PARTS];
MBRPart partitions[MAX_MBR_PARTS];
uint16_t MBRSignature;
// Above are basic MBR data; now add more stuff....
uint32_t blockSize; // block size (usually 512)
uint64_t diskSize; // size in blocks
uint64_t numHeads; // number of heads, in CHS scheme
uint64_t numSecspTrack; // number of sectors per track, in CHS scheme
uint32_t numHeads; // number of heads, in CHS scheme
uint32_t numSecspTrack; // number of sectors per track, in CHS scheme
DiskIO* myDisk;
int canDeleteMyDisk;
string device;
MBRValidity state;
struct MBRRecord* GetPartition(int i); // Return primary or logical partition
MBRPart* GetPartition(int i); // Return primary or logical partition
public:
BasicMBRData(void);
BasicMBRData(string deviceFilename);
@@ -92,51 +72,90 @@ public:
int ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
// ReadLogicalPart() returns last partition # read to logicals[] array,
// 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 WriteMBRData(void);
int WriteMBRData(DiskIO *theDisk);
int WriteMBRData(const string & deviceFilename);
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...
void DisplayMBRData(int maxParts = 4);
void DisplayMBRData(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.)
void SetDiskSize(uint64_t ds) {diskSize = ds;}
void SetBlockSize(uint32_t bs) {blockSize = bs;}
MBRValidity GetValidity(void) {return state;}
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 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
// Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
void EmptyMBR(int clearBootloader = 1);
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 SetPartType(int num, int type);
int SetPartBootable(int num, int bootable = 1);
int MakeBiggestPart(int i, int type); // Make partition filling most space
void DeletePartition(int i);
int SetInclusionwChecks(int num, int inclStatus);
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....
uint32_t FindFirstAvailable(uint32_t start = 1);
uint32_t FindLastInFree(uint32_t start);
uint32_t FindFirstInFree(uint32_t start);
int IsFree(uint32_t sector);
uint64_t FindFirstAvailable(uint64_t start = 1);
uint64_t FindLastInFree(uint64_t start);
uint64_t FindFirstInFree(uint64_t start);
// 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....
uint8_t GetStatus(int i);
uint8_t GetType(int i);
uint32_t GetFirstSector(int i);
uint32_t GetLength(int i);
uint64_t GetFirstSector(int i);
uint64_t GetLength(int i);
// User interaction functions....
int DoMenu(const string& prompt = "\nMBR command (? for help): ");
void ShowCommands(void);
}; // struct BasicMBRData
#endif

View File

@@ -1,14 +1,29 @@
Summary: An fdisk-like partitioning tool for GPT disks
Name: gdisk
Version: 0.6.14
Summary: GPT partitioning and MBR repair software
Name: gptfdisk
Version: 0.7.0
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
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)
%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
fdisk features a command-line interface, fairly direct
manipulation of partition table structures, recovery
@@ -26,19 +41,41 @@ rm -rf $RPM_BUILD_ROOT
mkdir -p $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 fixparts $RPM_BUILD_ROOT/usr/sbin
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 fixparts.8 $RPM_BUILD_ROOT/%{_mandir}/man8/fixparts.8
%clean
rm -rf $RPM_BUILD_ROOT
%files
%files -n gdisk
%defattr(-,root,root -)
%doc NEWS COPYING README
/usr/sbin/gdisk
/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
* Sat Jan 8 2011 R Smith <rodsmith@rodsbooks.com> - 0.6.14
- Created spec file for 0.6.14 release
* Fri Mar 11 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.0
- Created spec file for 0.7.0 release

View File

@@ -22,6 +22,11 @@
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifdef __linux__
#include "linux/hdreg.h"
#endif
#include <iostream>
#include "diskio.h"
@@ -160,6 +165,42 @@ int DiskIO::GetBlockSize(void) {
return (blockSize);
} // 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
// a lot from one OS to another.
void DiskIO::DiskSync(void) {

View File

@@ -143,6 +143,18 @@ int DiskIO::GetBlockSize(void) {
return (blockSize);
} // 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
// a lot from one OS to another.
void DiskIO::DiskSync(void) {

View File

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

View File

@@ -31,7 +31,7 @@
#endif
#include "support.h"
#include "parttypes.h"
//#include "parttypes.h"
using namespace std;
@@ -67,6 +67,8 @@ class DiskIO {
int Write(void* buffer, int numBytes);
void DiskSync(void); // resync disk caches to use new partitions
int GetBlockSize(void);
uint32_t GetNumHeads(void);
uint32_t GetNumSecsPerTrack(void);
int IsOpen(void) {return isOpen;}
int IsOpenForWrite(void) {return openForWrite;}
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
.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"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -561,7 +561,7 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely.
.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:
.TP
@@ -600,7 +600,7 @@ preserved when loading and saving partitions.
The program can load only up to 128 partitions (4 primary partitions and
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
\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
of 128 partitions was chosen because that number equals the 128 partitions
supported by the most common partition table size.)
@@ -674,6 +674,7 @@ Contributors:
\fBparted (8)\fR,
\fBsfdisk (8)\fR
\fBsgdisk (8)\fR
\fBfixparts (8)\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. */
#include <stdio.h>
//#include <getopt.h>
#include <string.h>
#include <string>
#include <iostream>
@@ -42,10 +41,7 @@ int main(int argc, char* argv[]) {
WinWarning();
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
if (!fgets(device, 255, stdin)) {
cerr << "Critical error! Failed fgets() in main()!\n";
exit(1);
} // if
ReadCString(device, 255);
i = strlen(device);
if (i && device[i - 1] == '\n')
device[i - 1] = '\0';
@@ -88,19 +84,13 @@ void MainMenu(string filename, GPTDataTextUI* theGPT) {
do {
cout << "\nCommand (? for help): ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
exit(1);
} // if
ReadCString(line, 255);
switch (*line) {
case '\n':
break;
case 'b': case 'B':
cout << "Enter backup filename to save: ";
if (!fgets(line, 255, stdin)) {
exit(1);
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
} // if
ReadCString(line, 255);
sscanf(line, "%s", buFile);
theGPT->SaveGPTBackup(buFile);
break;
@@ -188,15 +178,12 @@ void ShowCommands(void) {
// issues an exit command, such as 'w' or 'q'.
void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
char line[255], buFile[255];
uint32_t temp1, numParts;
int goOn = 1;
uint32_t numParts;
int goOn = 1, temp1;
do {
cout << "\nRecovery/transformation command (? for help): ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
exit(1);
} // if
ReadCString(line, 255);
switch (*line) {
case '\n':
break;
@@ -232,17 +219,17 @@ void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
case 'g': case 'G':
numParts = theGPT->GetNumParts();
temp1 = theGPT->XFormToMBR();
if (temp1 > 0) {
if (temp1 > 0)
cout << "\nConverted " << temp1 << " partitions. Finalize and exit? ";
if (GetYN() == 'Y') {
if ((theGPT->DestroyGPT() > 0) && (theGPT->SaveMBR()))
goOn = 0;
} else {
theGPT->MakeProtectiveMBR();
theGPT->SetGPTSize(numParts);
cout << "Note: New protective MBR created\n\n";
} // if/else
} // if
if ((temp1 > 0) && (GetYN() == 'Y')) {
if ((theGPT->DestroyGPT() > 0) && (theGPT->SaveMBR())) {
goOn = 0;
} // if
} else {
theGPT->MakeProtectiveMBR();
theGPT->SetGPTSize(numParts);
cout << "Note: New protective MBR created\n\n";
} // if/else
break;
case 'h': case 'H':
theGPT->MakeHybrid();
@@ -252,10 +239,7 @@ void RecoveryMenu(string filename, GPTDataTextUI* theGPT) {
break;
case 'l': case 'L':
cout << "Enter backup filename to load: ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
exit(1);
} // if
ReadCString(line, 255);
sscanf(line, "%s", buFile);
theGPT->LoadGPTBackup(buFile);
break;
@@ -329,10 +313,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
do {
cout << "\nExpert command (? for help): ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
ReadCString(line, 255);
switch (*line) {
case '\n':
break;
@@ -346,10 +327,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
if (theGPT->GetPartRange(&temp1, &temp2) > 0) {
pn = theGPT->GetPartNum();
cout << "Enter the partition's new unique GUID ('R' to randomize): ";
if (!fgets(guidStr, 255, stdin)) {
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
ReadCString(guidStr, 255);
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetPartitionGUID(pn, (GUIDData) guidStr);
cout << "New GUID is " << theGPT->operator[](pn).GetUniqueGUID() << "\n";
@@ -371,10 +349,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
break;
case 'g': case 'G':
cout << "Enter the disk's unique GUID ('R' to randomize): ";
if (!fgets(guidStr, 255, stdin)) {
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
ReadCString(guidStr, 255);
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetDiskGUID((GUIDData) guidStr);
cout << "The new disk GUID is " << theGPT->GetDiskGUID() << "\n";
@@ -423,16 +398,13 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
case 'u': case 'U':
cout << "Type device filename, or press <Enter> to exit: ";
device = new char[255];
if (!fgets(device, 255, stdin)) {
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
exit(1);
} // if
ReadCString(device, 255);
i = strlen(device);
if (i && device[i - 1] == '\n')
device[i - 1] = '\0';
if (*device && strlen(device) > 0) {
secondDevice = *theGPT;
secondDevice.SetFile(device);
secondDevice.SetDisk(device);
secondDevice.SaveGPTData(0);
} // if
delete[] device;

62
gpt.cc
View File

@@ -26,7 +26,7 @@
#include "parttypes.h"
#include "attributes.h"
#include "diskio.h"
#include "partnotes.h"
//#include "partnotes.h"
using namespace std;
@@ -61,7 +61,6 @@ GPTData::GPTData(void) {
sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0;
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0;
numParts = 0;
SetGPTSize(NUM_GPT_ENTRIES);
@@ -84,7 +83,6 @@ GPTData::GPTData(string filename) {
sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0;
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
mainHeader.numParts = 0;
numParts = 0;
if (!LoadPartitions(filename))
@@ -609,7 +607,7 @@ int GPTData::FindInsanePartitions(void) {
// Change the filename associated with the GPT. Used for duplicating
// the partition table to a new disk and saving backups.
// Returns 1 on success, 0 on failure.
int GPTData::SetFile(const string & deviceFilename) {
int GPTData::SetDisk(const string & deviceFilename) {
int err, allOK = 1;
device = deviceFilename;
@@ -622,7 +620,7 @@ int GPTData::SetFile(const string & deviceFilename) {
protectiveMBR.SetDiskSize(diskSize);
protectiveMBR.SetBlockSize(blockSize);
return allOK;
} // GPTData::SetFile()
} // GPTData::SetDisk()
// Scan for partition data. This function loads the MBR data (regular MBR or
// protective MBR) and loads BSD disklabel data (which is probably invalid).
@@ -991,7 +989,7 @@ int GPTData::SaveGPTData(int quiet) {
if ((allOK) && (!quiet)) {
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();
if (answer == 'Y') {
cout << "OK; writing new GUID partition table (GPT).\n";
@@ -1554,58 +1552,6 @@ int GPTData::OnePartToMBR(uint32_t gptPart, int mbrPart) {
return allOK;
} // 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 "bsd.h"
#include "gptpart.h"
#include "gptpartnotes.h"
#ifndef __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
#define DEFAULT_ALIGNMENT 2048
#define MAX_ALIGNMENT 65536
@@ -113,13 +104,14 @@ public:
void RecomputeCRCs(void);
void RebuildMainHeader(void);
void RebuildSecondHeader(void);
int VerifyMBR(void) {return protectiveMBR.Verify();}
int VerifyMBR(void) {return protectiveMBR.FindOverlaps();}
int FindHybridMismatches(void);
int FindOverlaps(void);
int FindInsanePartitions(void);
// 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 WriteProtectiveMBR(void) {return protectiveMBR.WriteMBRData(&myDisk);}
void PartitionScan(void);
@@ -169,6 +161,7 @@ public:
int Align(uint64_t* sector);
// Return data about the GPT structures....
void SetProtectiveMBR(BasicMBRData & newMBR) {protectiveMBR = newMBR;}
int GetPartRange(uint32_t* low, uint32_t* high);
int FindFirstFreePart(void);
uint32_t GetNumParts(void) {return mainHeader.numParts;}

View File

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

View File

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

View File

@@ -29,7 +29,7 @@
#include <cstdio>
#include "attributes.h"
#include "gpttext.h"
#include "gptpartnotes.h"
//#include "gptpartnotes.h"
#include "support.h"
using namespace std;
@@ -235,7 +235,10 @@ void GPTDataTextUI::CreatePartition(void) {
partitions[partNum].ChangeType();
partitions[partNum].SetDefaultDescription();
} 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
} // GPTDataTextUI::CreatePartition()
@@ -353,24 +356,22 @@ void GPTDataTextUI::ShowDetails(void) {
void GPTDataTextUI::MakeHybrid(void) {
uint32_t partNums[3];
char line[255];
int numPartsToCvt, i, j, mbrNum, bootable = 0;
int numPartsToCvt, i, j, mbrNum = 0;
unsigned int hexCode = 0;
struct PartInfo *newNote;
PartNotes notes;
MBRPart hybridPart;
MBRData hybridMBR;
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"
<< "just hit the Enter key at the below prompt and your MBR partition table will\n"
<< "be untouched.\n\n\a";
hybridMBR.SetDisk(&myDisk);
// Now get the numbers of up to three partitions to add to the
// hybrid MBR....
cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
<< "added to the hybrid MBR, in sequence: ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in GPTDataTextUI::MakeHybrid()!\n";
exit(1);
} // if
ReadCString(line, 255);
numPartsToCvt = sscanf(line, "%d %d %d", &partNums[0], &partNums[1], &partNums[2]);
if (numPartsToCvt > 0) {
@@ -379,148 +380,64 @@ void GPTDataTextUI::MakeHybrid(void) {
} // if
for (i = 0; i < numPartsToCvt; i++) {
newNote = new struct PartInfo;
j = newNote->origPartNum = partNums[i] - 1;
j = partNums[i] - 1;
if (partitions[j].IsUsed()) {
mbrNum = i + (eeFirst == 'Y');
cout << "\nCreating entry for GPT partition #" << j + 1
<< " (MBR partition #" << mbrNum + 1 << ")\n";
newNote->hexCode = GetMBRTypeCode(partitions[j].GetHexType() / 256);
newNote->firstLBA = partitions[j].GetFirstLBA();
newNote->lastLBA = partitions[j].GetLastLBA();
newNote->type = PRIMARY;
hybridPart.SetType(GetMBRTypeCode(partitions[j].GetHexType() / 256));
hybridPart.SetLocation(partitions[j].GetFirstLBA(), partitions[j].GetLengthLBA());
hybridPart.SetInclusion(PRIMARY);
cout << "Set the bootable flag? ";
if (GetYN() == 'Y')
newNote->active = 1;
hybridPart.SetStatus(1);
else
newNote->active = 0;
notes.AddToEnd(newNote);
hybridPart.SetStatus(0);
hybridPart.SetInclusion(PRIMARY);
} else {
delete newNote;
cerr << "\nGPT partition #" << j + 1 << " does not exist; skipping.\n";
} // if/else
hybridMBR.AddPart(mbrNum, hybridPart);
} // for
if (numPartsToCvt > 0) { // User opted to create a hybrid MBR....
// Create EFI protective partition that covers the start of the disk.
// If this location (covering the main GPT data structures) is omitted,
// Linux won't find any partitions on the disk.
newNote = new struct PartInfo;
newNote->origPartNum = MBR_EFI_GPT;
newNote->firstLBA = 1;
newNote->active = 0;
newNote->hexCode = 0xEE;
newNote->type = PRIMARY;
hybridPart.SetLocation(1, hybridMBR.FindLastInFree(1));
hybridPart.SetStatus(0);
hybridPart.SetType(0xEE);
hybridPart.SetInclusion(PRIMARY);
// newNote firstLBA and lastLBA are computed later...
if (eeFirst == 'Y') {
notes.AddToStart(newNote);
hybridMBR.AddPart(0, hybridPart);
} else {
notes.AddToEnd(newNote);
hybridMBR.AddPart(3, hybridPart);
} // else
protectiveMBR.SetHybrid();
hybridMBR.SetHybrid();
// ... and for good measure, if there are any partition spaces left,
// optionally create another protective EFI partition to cover as much
// 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? ";
if (GetYN() == 'Y') {
while ((hexCode <= 0) || (hexCode > 255)) {
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
// 0xEE MBR partition as MBR disks, not as GPT disks.
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in GPTDataTextUI::MakeHybrid()\n";
exit(1);
} // if
ReadCString(line, 255);
sscanf(line, "%x", &hexCode);
if (line[0] == '\n')
hexCode = 0x00;
} // while
newNote = new struct PartInfo;
newNote->origPartNum = MBR_EFI_GPT;
newNote->active = 0;
newNote->hexCode = hexCode;
newNote->type = PRIMARY;
// newNote firstLBA and lastLBA are computed later...
notes.AddToEnd(newNote);
hybridMBR.MakeBiggestPart(3, 0xEE);
} // if (GetYN() == 'Y')
} // if unused entry
PartsToMBR(&notes);
if (bootable > 0)
protectiveMBR.SetPartBootable(bootable);
protectiveMBR = hybridMBR;
} // if (numPartsToCvt > 0)
} // 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
// variable. This function is necessarily limited; it may not be able to
// 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
// the GPT data, call SaveMBR() to save the MBR, and then exit.
int GPTDataTextUI::XFormToMBR(void) {
int numToConvert, numReallyConverted = 0;
int origNumParts;
GptPartNotes notes;
GPTPart *tempGptParts;
uint32_t i;
// Back up partition array, since we'll be sorting it and we want to
// be able to restore it in case the user aborts....
origNumParts = numParts;
tempGptParts = new GPTPart[numParts];
for (i = 0; i < numParts; i++)
tempGptParts[i] = partitions[i];
notes.MakeItLegal();
numToConvert = AssignPrimaryOrLogical(notes);
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;
protectiveMBR.EmptyMBR();
for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed()) {
protectiveMBR.MakePart(i, partitions[i].GetFirstLBA(),
partitions[i].GetLengthLBA(),
partitions[i].GetHexType() / 0x0100, 0);
} // if
} // for
protectiveMBR.MakeItLegal();
return protectiveMBR.DoMenu();
} // GPTDataTextUI::XFormToMBR()
/*********************************************************************
@@ -589,10 +480,7 @@ int GetMBRTypeCode(int defType) {
cout << "Enter an MBR hex code (default " << hex;
cout.width(2);
cout << defType << "): " << dec;
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in GetMBRTypeCode()\n";
exit(1);
} // if
ReadCString(line, 255);
if (line[0] == '\n')
typeCode = defType;
else

View File

@@ -50,7 +50,6 @@ class GPTDataTextUI : public GPTData {
int DestroyGPTwPrompt(void); // Returns 1 if user proceeds
void ShowDetails(void);
void MakeHybrid(void);
int AssignPrimaryOrLogical(GptPartNotes& notes);
int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
}; // 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) {
BasicMBRData::operator=(orig);
return *this;
} // 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 *
@@ -50,15 +56,15 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
MBRSignature = MBR_SIGNATURE;
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].firstLBA = UINT32_C(1);
partitions[0].SetType(UINT8_C(0xEE));
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...
partitions[0].lengthLBA = UINT32_MAX;
partitions[0].SetLocation(UINT32_C(1), UINT32_MAX);
} // if/else
partitions[0].SetInclusion(PRIMARY);
// 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
@@ -66,9 +72,9 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
// although normal MBR disks max out at 0xfeffff. FWIW, both GNU Parted
// and Apple's Disk Utility use 0xfeffff, and the latter puts that
// 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)
partitions[0].lastSector[0] = 0xFF;
partitions[0].lastSector[0] = 0xFF; */
state = gpt;
} // MBRData::MakeProtectiveMBR()
@@ -76,27 +82,27 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
// Optimizes the size of the 0xEE (EFI GPT) partition
void MBRData::OptimizeEESize(void) {
int i, typeFlag = 0;
uint32_t after;
uint64_t after;
for (i = 0; i < 4; i++) {
// 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++;
if (partitions[i].partitionType == 0xEE) {
if (partitions[i].GetType() == 0xEE) {
// Blank space before this partition; fill it....
if (IsFree(partitions[i].firstLBA - 1)) {
partitions[i].firstLBA = FindFirstInFree(partitions[i].firstLBA - 1);
if (SectorUsedAs(partitions[i].GetStartLBA() - 1, 4) == NONE) {
partitions[i].SetStartLBA(FindFirstInFree(partitions[i].GetStartLBA() - 1));
} // if
// Blank space after this partition; fill it....
after = partitions[i].firstLBA + partitions[i].lengthLBA;
if (IsFree(after)) {
partitions[i].lengthLBA = FindLastInFree(after) - partitions[i].firstLBA + 1;
after = partitions[i].GetStartLBA() + partitions[i].GetLengthLBA();
if (SectorUsedAs(after, 4) == NONE) {
partitions[i].SetLengthLBA(FindLastInFree(after) - partitions[i].GetStartLBA() + 1);
} // if free space after
if (after > diskSize) {
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...
partitions[0].lengthLBA = UINT32_MAX - partitions[i].firstLBA;
partitions[i].SetLengthLBA(UINT32_MAX - partitions[i].GetStartLBA());
} // if/else
} // if protective partition is too big
RecomputeCHS(i);
@@ -118,8 +124,8 @@ int MBRData::DeleteByLocation(uint64_t start64, uint64_t length64) {
start32 = (uint32_t) start64;
length32 = (uint32_t) length64;
for (i = 0; i < MAX_MBR_PARTS; i++) {
if ((partitions[i].firstLBA == start32) && (partitions[i].lengthLBA == length32) &&
(partitions[i].partitionType != 0xEE)) {
if ((partitions[i].GetType() != 0xEE) && (partitions[i].GetStartLBA() == start32)
&& (partitions[i].GetLengthLBA() == length32)) {
DeletePartition(i);
if (state == hybrid)
OptimizeEESize();
@@ -138,7 +144,7 @@ int MBRData::DeleteByLocation(uint64_t start64, uint64_t length64) {
// Return the MBR data as a GPT partition....
GPTPart MBRData::AsGPT(int i) {
MBRRecord* origPart;
MBRPart* origPart;
GPTPart newPart;
uint8_t origType;
uint64_t firstSector, lastSector;
@@ -146,7 +152,7 @@ GPTPart MBRData::AsGPT(int i) {
newPart.BlankPartition();
origPart = GetPartition(i);
if (origPart != NULL) {
origType = origPart->partitionType;
origType = origPart->GetType();
// don't convert extended, hybrid protective, or null (non-existent)
// partitions (Note similar protection is in GPTData::XFormPartitions(),
@@ -154,10 +160,9 @@ GPTPart MBRData::AsGPT(int i) {
// context in the future....)
if ((origType != 0x05) && (origType != 0x0f) && (origType != 0x85) &&
(origType != 0x00) && (origType != 0xEE)) {
firstSector = (uint64_t) origPart->firstLBA;
firstSector = (uint64_t) origPart->GetStartLBA();
newPart.SetFirstLBA(firstSector);
lastSector = firstSector + (uint64_t) origPart->lengthLBA;
if (lastSector > 0) lastSector--;
lastSector = (uint64_t) origPart->GetLastLBA();
newPart.SetLastLBA(lastSector);
newPart.SetType(((uint16_t) origType) * 0x0100);
newPart.RandomizeUniqueGUID();

4
mbr.h
View File

@@ -26,11 +26,11 @@ using namespace std;
// Full data in tweaked MBR format
class MBRData : public BasicMBRData {
protected:
int foo;
public:
MBRData(void) {}
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
// 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
.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"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
@@ -470,7 +470,7 @@ Non\-GPT disk detected and no \fI\-g\fR option
.B 4
An error prevented saving changes
.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:
.TP
@@ -506,7 +506,7 @@ preserved when loading and saving partitions.
The program can load only up to 128 partitions (4 primary partitions and
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
\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
of 128 partitions was chosen because that number equals the 128 partitions
supported by the most common partition table size.)
@@ -580,6 +580,7 @@ Contributors:
\fBmkfs (8)\fR,
\fBparted (8)\fR,
\fBsfdisk (8)\fR
\fBfixparts (8)\fR
\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR

View File

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

View File

@@ -31,6 +31,14 @@
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).
// Keeps looping until the user enters a value within that range.
// If user provides no input, def (default value) is returned.
@@ -66,10 +74,7 @@ char GetYN(void) {
do {
cout << "(Y/N): ";
if (!fgets(line, 255, stdin)) {
cerr << "Critical error! Failed fgets() in GetYN()\n";
exit(1);
} // if
ReadCString(line, 255);
sscanf(line, "%c", &response);
if (response == 'y')
response = 'Y';
@@ -316,7 +321,7 @@ uint64_t GetInt(const string & argument, int itemNum) {
} // GetInt()
// 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;
while (itemNum-- > 0) {

View File

@@ -8,6 +8,8 @@
#ifndef __GPTSUPPORT
#define __GPTSUPPORT
#define GPTFDISK_VERSION "0.7.0"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64
// This used to use __DARWIN_UNIX03 rather than __APPLE__, but __APPLE__
@@ -22,6 +24,13 @@
#include <linux/fs.h>
#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
#define SECTOR_SIZE UINT32_C(512)
@@ -47,6 +56,7 @@
using namespace std;
char* ReadCString(char *inStr, int numchars);
int GetNumber(int low, int high, int def, const string & prompt);
char GetYN(void);
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....
uint64_t GetInt(const string & argument, int itemNum);
string GetString(const string & Info, int itemNum);
string GetString(string argument, int itemNum);
#endif