Misc. bug fixes & restructuring.
This commit is contained in:
354
Makefile
354
Makefile
@@ -3,7 +3,7 @@ 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 gptpart mbr gpt bsd parttypes attributes diskio diskio-unix
|
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
|
||||||
LIB_SRCS=$(NAMES:=.cc)
|
LIB_SRCS=$(NAMES:=.cc)
|
||||||
LIB_OBJS=$(LIB_NAMES:=.o)
|
LIB_OBJS=$(LIB_NAMES:=.o)
|
||||||
LIB_HEADERS=$(LIB_NAMES:=.h)
|
LIB_HEADERS=$(LIB_NAMES:=.h)
|
||||||
@@ -31,3 +31,355 @@ $(OBJS):
|
|||||||
$(CRITICAL_CXX_FLAGS)
|
$(CRITICAL_CXX_FLAGS)
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ 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 gptpart mbr gpt bsd parttypes attributes diskio diskio-unix
|
LIB_NAMES=crc32 support guid partnotes gptpartnotes gptpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
|
||||||
LIB_SRCS=$(NAMES:=.cc)
|
LIB_SRCS=$(NAMES:=.cc)
|
||||||
LIB_OBJS=$(LIB_NAMES:=.o)
|
LIB_OBJS=$(LIB_NAMES:=.o)
|
||||||
LIB_HEADERS=$(LIB_NAMES:=.h)
|
LIB_HEADERS=$(LIB_NAMES:=.h)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
CC=/usr/bin/i586-mingw32msvc-gcc
|
CC=/usr/bin/i686-pc-mingw32-gcc
|
||||||
CXX=/usr/bin/i586-mingw32msvc-g++
|
CXX=/usr/bin/i686-pc-mingw32-g++
|
||||||
STRIP=/usr/bin/i586-mingw32msvc-strip
|
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 partnotes bsd parttypes attributes crc32 mbr gpt support diskio diskio-windows
|
LIB_NAMES=guid gptpart bsd parttypes partnotes gptpartnotes attributes crc32 basicmbr mbr gpt support diskio diskio-windows
|
||||||
LIB_SRCS=$(NAMES:=.cc)
|
LIB_SRCS=$(NAMES:=.cc)
|
||||||
LIB_OBJS=$(LIB_NAMES:=.o)
|
LIB_OBJS=$(LIB_NAMES:=.o)
|
||||||
LIB_HEADERS=$(LIB_NAMES:=.h)
|
LIB_HEADERS=$(LIB_NAMES:=.h)
|
||||||
@@ -12,8 +12,8 @@ DEPEND= makedepend $(CFLAGS)
|
|||||||
|
|
||||||
all: gdisk
|
all: gdisk
|
||||||
|
|
||||||
gdisk: $(LIB_OBJS) gpttext.o gdisk.o
|
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
|
||||||
$(CXX) $(LIB_OBJS) gpttext.o gdisk.o -luuid -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 -o sgdisk.exe
|
||||||
|
|||||||
23
NEWS
23
NEWS
@@ -1,3 +1,26 @@
|
|||||||
|
0.6.15 (?/?/2011):
|
||||||
|
------------------
|
||||||
|
|
||||||
|
- 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
|
||||||
|
on the smaller disk. In sgdisk, the secondary GPT data are moved
|
||||||
|
automatically if disk sizes don't match. In gdisk, the secondary GPT data
|
||||||
|
are moved automatically if the target disk is smaller than the source
|
||||||
|
disk; if the target disk is larger than the source disk, the user is
|
||||||
|
given the option of making this adjustment.
|
||||||
|
|
||||||
|
- Fixed --load-backup (-l) option to sgdisk, which was broken.
|
||||||
|
|
||||||
|
- 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
|
||||||
|
experts' menu) by hitting the Enter key for the device filename.
|
||||||
|
|
||||||
|
- Implemented a number of code cleanups provided by an anonymous
|
||||||
|
contributor.
|
||||||
|
|
||||||
0.6.14 (1/8/2011):
|
0.6.14 (1/8/2011):
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
// attributes.cc
|
// attributes.cc
|
||||||
// Class to manage partition attribute codes. These are binary bit fields,
|
// Class to manage partition attribute codes. These are binary bit fields,
|
||||||
// of which only three are currently (2/2009) documented on Wikipedia.
|
// of which only four are currently (2/2011) documented on Wikipedia, and
|
||||||
|
// two others found from other sources.
|
||||||
|
|
||||||
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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 <stdint.h>
|
#include <stdint.h>
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ uint64_t DiskIO::DiskSize(int *err) {
|
|||||||
if (*err) {
|
if (*err) {
|
||||||
sectors = sz = 0;
|
sectors = sz = 0;
|
||||||
} // if
|
} // if
|
||||||
if ((errno == EFBIG) || (!*err)) {
|
if ((!*err) || (errno == EFBIG)) {
|
||||||
*err = ioctl(fd, BLKGETSIZE64, &b);
|
*err = ioctl(fd, BLKGETSIZE64, &b);
|
||||||
if (*err || b == 0 || b == sz)
|
if (*err || b == 0 || b == sz)
|
||||||
sectors = sz;
|
sectors = sz;
|
||||||
|
|||||||
2
diskio.h
2
diskio.h
@@ -69,7 +69,7 @@ class DiskIO {
|
|||||||
int GetBlockSize(void);
|
int GetBlockSize(void);
|
||||||
int IsOpen(void) {return isOpen;}
|
int IsOpen(void) {return isOpen;}
|
||||||
int IsOpenForWrite(void) {return openForWrite;}
|
int IsOpenForWrite(void) {return openForWrite;}
|
||||||
string GetName(void) {return realFilename;}
|
string GetName(void) const {return realFilename;}
|
||||||
|
|
||||||
uint64_t DiskSize(int* err);
|
uint64_t DiskSize(int* err);
|
||||||
}; // struct GPTPart
|
}; // struct GPTPart
|
||||||
|
|||||||
11
gdisk.8
11
gdisk.8
@@ -471,10 +471,11 @@ physical sectors (such as some Western Digital models introduced in
|
|||||||
December of 2009) and some RAID configurations can suffer performance
|
December of 2009) and some RAID configurations can suffer performance
|
||||||
problems if partitions are not aligned properly for their internal data
|
problems if partitions are not aligned properly for their internal data
|
||||||
structures. On new disks, GPT fdisk attempts to align partitions on
|
structures. On new disks, GPT fdisk attempts to align partitions on
|
||||||
2048\-sector (1MiB) boundaries by default, which optimizes performance
|
2048\-sector (1MiB) boundaries by default, which optimizes performance for
|
||||||
for both of these disk types. On pre\-partitioned disks, GPT fdisk
|
both of these disk types. On pre\-partitioned disks, GPT fdisk attempts to
|
||||||
attempts to identify the alignment value used on that disk. In either
|
identify the alignment value used on that disk, but will set 8-sector
|
||||||
case, it can be changed by using this option.
|
alignment on disks larger than 300 GB even if lesser alignment values are
|
||||||
|
detected. In either case, it can be changed by using this option.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B m
|
.B m
|
||||||
@@ -663,6 +664,8 @@ Contributors:
|
|||||||
|
|
||||||
* Dwight Schauer (dschauer@ti.com)
|
* Dwight Schauer (dschauer@ti.com)
|
||||||
|
|
||||||
|
* Florian Zumbiehl (florz@florz.de)
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
\fBcfdisk (8)\fR,
|
\fBcfdisk (8)\fR,
|
||||||
|
|||||||
122
gdisk.cc
122
gdisk.cc
@@ -4,7 +4,7 @@
|
|||||||
//
|
//
|
||||||
// by Rod Smith, project began February 2009
|
// by Rod Smith, project began February 2009
|
||||||
|
|
||||||
/* This program is copyright (c) 2009, 2010 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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>
|
||||||
@@ -29,8 +29,8 @@ void WinWarning(void);
|
|||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
GPTDataTextUI theGPT;
|
GPTDataTextUI theGPT;
|
||||||
int doMore = 1, i;
|
size_t i;
|
||||||
char *device = NULL, *junk;
|
char *device = NULL;
|
||||||
|
|
||||||
cout << "GPT fdisk (gdisk) version " << GPTFDISK_VERSION << "\n\n";
|
cout << "GPT fdisk (gdisk) version " << GPTFDISK_VERSION << "\n\n";
|
||||||
|
|
||||||
@@ -42,25 +42,21 @@ 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];
|
||||||
junk = fgets(device, 255, stdin);
|
if (!fgets(device, 255, stdin)) {
|
||||||
if (device[0] != '\n') {
|
cerr << "Critical error! Failed fgets() in main()!\n";
|
||||||
i = (int) strlen(device);
|
exit(1);
|
||||||
if (i > 0)
|
|
||||||
if (device[i - 1] == '\n')
|
|
||||||
device[i - 1] = '\0';
|
|
||||||
doMore = theGPT.LoadPartitions(device);
|
|
||||||
if (doMore) {
|
|
||||||
MainMenu(device, &theGPT);
|
|
||||||
} // if (doMore)
|
|
||||||
} // if
|
} // if
|
||||||
|
i = strlen(device);
|
||||||
|
if (i && device[i - 1] == '\n')
|
||||||
|
device[i - 1] = '\0';
|
||||||
|
if (*device && theGPT.LoadPartitions(device))
|
||||||
|
MainMenu(device, &theGPT);
|
||||||
delete[] device;
|
delete[] device;
|
||||||
break;
|
break;
|
||||||
case 2: // basic usage
|
case 2: // basic usage
|
||||||
WinWarning();
|
WinWarning();
|
||||||
doMore = theGPT.LoadPartitions(argv[1]);
|
if (theGPT.LoadPartitions(argv[1]))
|
||||||
if (doMore) {
|
|
||||||
MainMenu(argv[1], &theGPT);
|
MainMenu(argv[1], &theGPT);
|
||||||
} // if (doMore)
|
|
||||||
break;
|
break;
|
||||||
case 3: // usage with "-l" option
|
case 3: // usage with "-l" option
|
||||||
if (strcmp(argv[1], "-l") == 0) {
|
if (strcmp(argv[1], "-l") == 0) {
|
||||||
@@ -72,8 +68,8 @@ int main(int argc, char* argv[]) {
|
|||||||
} // if/elseif/else
|
} // if/elseif/else
|
||||||
if (device != NULL) {
|
if (device != NULL) {
|
||||||
theGPT.JustLooking();
|
theGPT.JustLooking();
|
||||||
doMore = theGPT.LoadPartitions((string) device);
|
if (theGPT.LoadPartitions((string) device))
|
||||||
if (doMore) theGPT.DisplayGPTData();
|
theGPT.DisplayGPTData();
|
||||||
} // if
|
} // if
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -85,23 +81,27 @@ int main(int argc, char* argv[]) {
|
|||||||
// Accept a command and execute it. Returns only when the user
|
// Accept a command and execute it. Returns only when the user
|
||||||
// wants to exit (such as after a 'w' or 'q' command).
|
// wants to exit (such as after a 'w' or 'q' command).
|
||||||
void MainMenu(string filename, GPTDataTextUI* theGPT) {
|
void MainMenu(string filename, GPTDataTextUI* theGPT) {
|
||||||
char command, line[255], buFile[255];
|
char line[255], buFile[255];
|
||||||
char* junk;
|
|
||||||
int goOn = 1;
|
int goOn = 1;
|
||||||
PartType typeHelper;
|
PartType typeHelper;
|
||||||
uint32_t temp1, temp2;
|
uint32_t temp1, temp2;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cout << "\nCommand (? for help): ";
|
cout << "\nCommand (? for help): ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
sscanf(line, "%c", &command);
|
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
|
||||||
switch (command) {
|
exit(1);
|
||||||
|
} // if
|
||||||
|
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: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
sscanf(line, "%s", (char*) &buFile);
|
exit(1);
|
||||||
|
cerr << "Critical error! Failed fgets() in MainMenu()!\n";
|
||||||
|
} // if
|
||||||
|
sscanf(line, "%s", buFile);
|
||||||
theGPT->SaveGPTBackup(buFile);
|
theGPT->SaveGPTBackup(buFile);
|
||||||
break;
|
break;
|
||||||
case 'c': case 'C':
|
case 'c': case 'C':
|
||||||
@@ -187,16 +187,17 @@ void ShowCommands(void) {
|
|||||||
// Accept a recovery & transformation menu command. Returns only when the user
|
// Accept a recovery & transformation menu command. Returns only when the user
|
||||||
// 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 command, line[255], buFile[255];
|
char line[255], buFile[255];
|
||||||
char* junk;
|
|
||||||
uint32_t temp1, numParts;
|
uint32_t temp1, numParts;
|
||||||
int goOn = 1;
|
int goOn = 1;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cout << "\nRecovery/transformation command (? for help): ";
|
cout << "\nRecovery/transformation command (? for help): ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
sscanf(line, "%c", &command);
|
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
|
||||||
switch (command) {
|
exit(1);
|
||||||
|
} // if
|
||||||
|
switch (*line) {
|
||||||
case '\n':
|
case '\n':
|
||||||
break;
|
break;
|
||||||
case 'b': case 'B':
|
case 'b': case 'B':
|
||||||
@@ -251,8 +252,11 @@ 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: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
sscanf(line, "%s", (char*) &buFile);
|
cerr << "Critical error! Failed fgets() in RecoveryMenu()!\n";
|
||||||
|
exit(1);
|
||||||
|
} // if
|
||||||
|
sscanf(line, "%s", buFile);
|
||||||
theGPT->LoadGPTBackup(buFile);
|
theGPT->LoadGPTBackup(buFile);
|
||||||
break;
|
break;
|
||||||
case 'm': case 'M':
|
case 'm': case 'M':
|
||||||
@@ -314,19 +318,22 @@ void ShowRecoveryCommands(void) {
|
|||||||
// Accept an experts' menu command. Returns only after the user
|
// Accept an experts' menu command. Returns only after the user
|
||||||
// selects an exit command, such as 'w' or 'q'.
|
// selects an exit command, such as 'w' or 'q'.
|
||||||
void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
||||||
char command, line[255], *device;
|
GPTData secondDevice;
|
||||||
char* junk;
|
char line[255], *device;
|
||||||
uint32_t pn, temp1, temp2;
|
uint32_t pn, temp1, temp2;
|
||||||
int goOn = 1, i;
|
int goOn = 1;
|
||||||
|
size_t i;
|
||||||
char guidStr[255];
|
char guidStr[255];
|
||||||
GUIDData aGUID;
|
GUIDData aGUID;
|
||||||
ostringstream prompt;
|
ostringstream prompt;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cout << "\nExpert command (? for help): ";
|
cout << "\nExpert command (? for help): ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
sscanf(line, "%c", &command);
|
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
|
||||||
switch (command) {
|
exit(1);
|
||||||
|
} // if
|
||||||
|
switch (*line) {
|
||||||
case '\n':
|
case '\n':
|
||||||
break;
|
break;
|
||||||
case 'a': case 'A':
|
case 'a': case 'A':
|
||||||
@@ -339,7 +346,10 @@ 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): ";
|
||||||
junk = fgets(guidStr, 255, stdin);
|
if (!fgets(guidStr, 255, stdin)) {
|
||||||
|
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";
|
||||||
@@ -361,7 +371,10 @@ 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): ";
|
||||||
junk = fgets(guidStr, 255, stdin);
|
if (!fgets(guidStr, 255, stdin)) {
|
||||||
|
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";
|
||||||
@@ -395,8 +408,8 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
|||||||
theGPT->DisplayGPTData();
|
theGPT->DisplayGPTData();
|
||||||
break;
|
break;
|
||||||
case 'q': case 'Q':
|
case 'q': case 'Q':
|
||||||
goOn = 0;
|
goOn = 0;
|
||||||
break;
|
break;
|
||||||
case 'r': case 'R':
|
case 'r': case 'R':
|
||||||
RecoveryMenu(filename, theGPT);
|
RecoveryMenu(filename, theGPT);
|
||||||
goOn = 0;
|
goOn = 0;
|
||||||
@@ -404,21 +417,24 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
|||||||
case 's': case 'S':
|
case 's': case 'S':
|
||||||
theGPT->ResizePartitionTable();
|
theGPT->ResizePartitionTable();
|
||||||
break;
|
break;
|
||||||
case 't': case 'T':
|
case 't': case 'T':
|
||||||
theGPT->SwapPartitions();
|
theGPT->SwapPartitions();
|
||||||
break;
|
break;
|
||||||
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];
|
||||||
junk = fgets(device, 255, stdin);
|
if (!fgets(device, 255, stdin)) {
|
||||||
if (device[0] != '\n') {
|
cerr << "Critical error! Failed fgets() in ExpertsMenu()!\n";
|
||||||
i = (int) strlen(device);
|
exit(1);
|
||||||
if (i > 0)
|
} // if
|
||||||
if (device[i - 1] == '\n')
|
i = strlen(device);
|
||||||
device[i - 1] = '\0';
|
if (i && device[i - 1] == '\n')
|
||||||
|
device[i - 1] = '\0';
|
||||||
|
if (*device && strlen(device) > 0) {
|
||||||
|
secondDevice = *theGPT;
|
||||||
|
secondDevice.SetFile(device);
|
||||||
|
secondDevice.SaveGPTData(0);
|
||||||
} // if
|
} // if
|
||||||
if (strlen(device) > 0)
|
|
||||||
theGPT->SaveGPTData(0, device);
|
|
||||||
delete[] device;
|
delete[] device;
|
||||||
break;
|
break;
|
||||||
case 'v': case 'V':
|
case 'v': case 'V':
|
||||||
|
|||||||
143
gpt.cc
143
gpt.cc
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
/* By Rod Smith, initial coding January to February, 2009 */
|
/* By Rod Smith, initial coding January to February, 2009 */
|
||||||
|
|
||||||
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
@@ -96,6 +96,45 @@ GPTData::~GPTData(void) {
|
|||||||
delete[] partitions;
|
delete[] partitions;
|
||||||
} // GPTData destructor
|
} // GPTData destructor
|
||||||
|
|
||||||
|
// Assignment operator
|
||||||
|
GPTData & GPTData::operator=(const GPTData & orig) {
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
mainHeader = orig.mainHeader;
|
||||||
|
numParts = orig.numParts;
|
||||||
|
secondHeader = orig.secondHeader;
|
||||||
|
protectiveMBR = orig.protectiveMBR;
|
||||||
|
device = orig.device;
|
||||||
|
blockSize = orig.blockSize;
|
||||||
|
diskSize = orig.diskSize;
|
||||||
|
state = orig.state;
|
||||||
|
justLooking = orig.justLooking;
|
||||||
|
mainCrcOk = orig.mainCrcOk;
|
||||||
|
secondCrcOk = orig.secondCrcOk;
|
||||||
|
mainPartsCrcOk = orig.mainPartsCrcOk;
|
||||||
|
secondPartsCrcOk = orig.secondPartsCrcOk;
|
||||||
|
apmFound = orig.apmFound;
|
||||||
|
bsdFound = orig.bsdFound;
|
||||||
|
sectorAlignment = orig.sectorAlignment;
|
||||||
|
beQuiet = orig.beQuiet;
|
||||||
|
whichWasUsed = orig.whichWasUsed;
|
||||||
|
|
||||||
|
myDisk.OpenForRead(orig.myDisk.GetName());
|
||||||
|
|
||||||
|
delete[] partitions;
|
||||||
|
partitions = new GPTPart [numParts * sizeof (GPTPart)];
|
||||||
|
if (partitions != NULL) {
|
||||||
|
for (i = 0; i < numParts; i++) {
|
||||||
|
partitions[i] = orig.partitions[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
numParts = 0;
|
||||||
|
cerr << "Error! Could not allocate memory for partitions in GPTData::operator=()!\n"
|
||||||
|
<< "Continuing, but strange problems may occur!\n";
|
||||||
|
} // if/else
|
||||||
|
return *this;
|
||||||
|
} // GPTData::operator=()
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* *
|
* *
|
||||||
* Begin functions that verify data, or that adjust the verification *
|
* Begin functions that verify data, or that adjust the verification *
|
||||||
@@ -107,7 +146,7 @@ GPTData::~GPTData(void) {
|
|||||||
// do *NOT* recover from these problems. Returns the total number of
|
// do *NOT* recover from these problems. Returns the total number of
|
||||||
// problems identified.
|
// problems identified.
|
||||||
int GPTData::Verify(void) {
|
int GPTData::Verify(void) {
|
||||||
int problems = 0;
|
int problems = 0, alignProbs = 0;
|
||||||
uint32_t i, numSegments;
|
uint32_t i, numSegments;
|
||||||
uint64_t totalFree, largestSegment;
|
uint64_t totalFree, largestSegment;
|
||||||
|
|
||||||
@@ -210,11 +249,11 @@ int GPTData::Verify(void) {
|
|||||||
|
|
||||||
// Now check for a few other miscellaneous problems...
|
// Now check for a few other miscellaneous problems...
|
||||||
// Check that the disk size will hold the data...
|
// Check that the disk size will hold the data...
|
||||||
if (mainHeader.backupLBA > diskSize) {
|
if (mainHeader.backupLBA >= diskSize) {
|
||||||
problems++;
|
problems++;
|
||||||
cout << "\nProblem: Disk is too small to hold all the data!\n"
|
cout << "\nProblem: Disk is too small to hold all the data!\n"
|
||||||
<< "(Disk size is " << diskSize << " sectors, needs to be "
|
<< "(Disk size is " << diskSize << " sectors, needs to be "
|
||||||
<< mainHeader.backupLBA << " sectors.)\n"
|
<< mainHeader.backupLBA + UINT64_C(1) << " sectors.)\n"
|
||||||
<< "The 'e' option on the experts' menu may fix this problem.\n";
|
<< "The 'e' option on the experts' menu may fix this problem.\n";
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
@@ -240,14 +279,18 @@ int GPTData::Verify(void) {
|
|||||||
cout << "\nCaution: Partition " << i + 1 << " doesn't begin on a "
|
cout << "\nCaution: Partition " << i + 1 << " doesn't begin on a "
|
||||||
<< sectorAlignment << "-sector boundary. This may\nresult "
|
<< sectorAlignment << "-sector boundary. This may\nresult "
|
||||||
<< "in degraded performance on some modern (2009 and later) hard disks.\n";
|
<< "in degraded performance on some modern (2009 and later) hard disks.\n";
|
||||||
|
alignProbs++;
|
||||||
} // if
|
} // if
|
||||||
} // for
|
} // for
|
||||||
|
if (alignProbs > 0)
|
||||||
|
cout << "\nConsult http://www.ibm.com/developerworks/linux/library/l-4kb-sector-disks/\n"
|
||||||
|
<< "for information on disk alignment.\n";
|
||||||
|
|
||||||
// Now compute available space, but only if no problems found, since
|
// Now compute available space, but only if no problems found, since
|
||||||
// problems could affect the results
|
// problems could affect the results
|
||||||
if (problems == 0) {
|
if (problems == 0) {
|
||||||
totalFree = FindFreeBlocks(&numSegments, &largestSegment);
|
totalFree = FindFreeBlocks(&numSegments, &largestSegment);
|
||||||
cout << "No problems found. " << totalFree << " free sectors ("
|
cout << "\nNo problems found. " << totalFree << " free sectors ("
|
||||||
<< BytesToSI(totalFree, blockSize) << ") available in "
|
<< BytesToSI(totalFree, blockSize) << ") available in "
|
||||||
<< numSegments << "\nsegments, the largest of which is "
|
<< numSegments << "\nsegments, the largest of which is "
|
||||||
<< largestSegment << " (" << BytesToSI(largestSegment, blockSize)
|
<< largestSegment << " (" << BytesToSI(largestSegment, blockSize)
|
||||||
@@ -563,6 +606,24 @@ 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 err, allOK = 1;
|
||||||
|
|
||||||
|
device = deviceFilename;
|
||||||
|
if (allOK && myDisk.OpenForRead(deviceFilename)) {
|
||||||
|
// store disk information....
|
||||||
|
diskSize = myDisk.DiskSize(&err);
|
||||||
|
blockSize = (uint32_t) myDisk.GetBlockSize();
|
||||||
|
} // if
|
||||||
|
protectiveMBR.SetDisk(&myDisk);
|
||||||
|
protectiveMBR.SetDiskSize(diskSize);
|
||||||
|
protectiveMBR.SetBlockSize(blockSize);
|
||||||
|
return allOK;
|
||||||
|
} // GPTData::SetFile()
|
||||||
|
|
||||||
// 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).
|
||||||
// It also looks for APM data, forces a load of GPT data, and summarizes
|
// It also looks for APM data, forces a load of GPT data, and summarizes
|
||||||
@@ -869,20 +930,15 @@ int GPTData::CheckTable(struct GPTHeader *header) {
|
|||||||
return newCrcOk;
|
return newCrcOk;
|
||||||
} // GPTData::CheckTable()
|
} // GPTData::CheckTable()
|
||||||
|
|
||||||
// Writes GPT (and protective MBR) to disk. Returns 1 on successful
|
// Writes GPT (and protective MBR) to disk. If quiet==1,
|
||||||
|
// Returns 1 on successful
|
||||||
// write, 0 if there was a problem.
|
// write, 0 if there was a problem.
|
||||||
int GPTData::SaveGPTData(int quiet, string filename) {
|
int GPTData::SaveGPTData(int quiet) {
|
||||||
int allOK = 1, littleEndian;
|
int allOK = 1, littleEndian;
|
||||||
char answer;
|
char answer;
|
||||||
|
|
||||||
littleEndian = IsLittleEndian();
|
littleEndian = IsLittleEndian();
|
||||||
|
|
||||||
if (filename == "")
|
|
||||||
filename = device;
|
|
||||||
if (filename == "") {
|
|
||||||
cerr << "Device not defined.\n";
|
|
||||||
} // if
|
|
||||||
|
|
||||||
// First do some final sanity checks....
|
// First do some final sanity checks....
|
||||||
|
|
||||||
// This test should only fail on read-only disks....
|
// This test should only fail on read-only disks....
|
||||||
@@ -891,30 +947,34 @@ int GPTData::SaveGPTData(int quiet, string filename) {
|
|||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
|
// Check that disk is really big enough to handle the second header...
|
||||||
|
if (mainHeader.backupLBA >= diskSize) {
|
||||||
|
cerr << "Caution! Secondary header was placed beyond the disk's limits! Moving the\n"
|
||||||
|
<< "header, but other problems may occur!\n";
|
||||||
|
MoveSecondHeaderToEnd();
|
||||||
|
} // if
|
||||||
|
|
||||||
// Is there enough space to hold the GPT headers and partition tables,
|
// Is there enough space to hold the GPT headers and partition tables,
|
||||||
// given the partition sizes?
|
// given the partition sizes?
|
||||||
if (CheckGPTSize() > 0) {
|
if (CheckGPTSize() > 0) {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
// Check that disk is really big enough to handle this...
|
|
||||||
if (mainHeader.backupLBA > diskSize) {
|
|
||||||
cerr << "Error! Disk is too small! The 'e' option on the experts' menu might fix the\n"
|
|
||||||
<< "problem (or it might not). Aborting!\n(Disk size is "
|
|
||||||
<< diskSize << " sectors, needs to be " << mainHeader.backupLBA << " sectors.)\n";
|
|
||||||
allOK = 0;
|
|
||||||
} // if
|
|
||||||
// Check that second header is properly placed. Warn and ask if this should
|
// Check that second header is properly placed. Warn and ask if this should
|
||||||
// be corrected if the test fails....
|
// be corrected if the test fails....
|
||||||
if ((mainHeader.backupLBA < (diskSize - UINT64_C(1))) && (quiet == 0)) {
|
if (mainHeader.backupLBA < (diskSize - UINT64_C(1))) {
|
||||||
cout << "Warning! Secondary header is placed too early on the disk! Do you want to\n"
|
if (quiet == 0) {
|
||||||
<< "correct this problem? ";
|
cout << "Warning! Secondary header is placed too early on the disk! Do you want to\n"
|
||||||
if (GetYN() == 'Y') {
|
<< "correct this problem? ";
|
||||||
|
if (GetYN() == 'Y') {
|
||||||
|
MoveSecondHeaderToEnd();
|
||||||
|
cout << "Have moved second header and partition table to correct location.\n";
|
||||||
|
} else {
|
||||||
|
cout << "Have not corrected the problem. Strange problems may occur in the future!\n";
|
||||||
|
} // if correction requested
|
||||||
|
} else { // Go ahead and do correction automatically
|
||||||
MoveSecondHeaderToEnd();
|
MoveSecondHeaderToEnd();
|
||||||
cout << "Have moved second header and partition table to correct location.\n";
|
} // if/else quiet
|
||||||
} else {
|
|
||||||
cout << "Have not corrected the problem. Strange problems may occur in the future!\n";
|
|
||||||
} // if correction requested
|
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
// Check for overlapping or insane partitions....
|
// Check for overlapping or insane partitions....
|
||||||
@@ -942,7 +1002,7 @@ int GPTData::SaveGPTData(int quiet, string filename) {
|
|||||||
|
|
||||||
// Do it!
|
// Do it!
|
||||||
if (allOK) {
|
if (allOK) {
|
||||||
if (myDisk.OpenForWrite(filename)) {
|
if (myDisk.OpenForWrite()) {
|
||||||
// As per UEFI specs, write the secondary table and GPT first....
|
// As per UEFI specs, write the secondary table and GPT first....
|
||||||
allOK = SavePartitionTable(myDisk, secondHeader.partitionEntriesLBA);
|
allOK = SavePartitionTable(myDisk, secondHeader.partitionEntriesLBA);
|
||||||
if (!allOK)
|
if (!allOK)
|
||||||
@@ -975,7 +1035,7 @@ int GPTData::SaveGPTData(int quiet, string filename) {
|
|||||||
|
|
||||||
myDisk.Close();
|
myDisk.Close();
|
||||||
} else {
|
} else {
|
||||||
cerr << "Unable to open device " << filename << " for writing! Errno is "
|
cerr << "Unable to open device " << myDisk.GetName() << " for writing! Errno is "
|
||||||
<< errno << "! Aborting write!\n";
|
<< errno << "! Aborting write!\n";
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if/else
|
} // if/else
|
||||||
@@ -1513,24 +1573,24 @@ int GPTData::PartsToMBR(PartNotes * notes) {
|
|||||||
notes->MakeItLegal();
|
notes->MakeItLegal();
|
||||||
notes->Rewind();
|
notes->Rewind();
|
||||||
while (notes->GetNextInfo(&convInfo) >= 0) {
|
while (notes->GetNextInfo(&convInfo) >= 0) {
|
||||||
if ((convInfo.gptPartNum >= 0) && (convInfo.type == PRIMARY)) {
|
if ((convInfo.origPartNum >= 0) && (convInfo.type == PRIMARY)) {
|
||||||
numConverted += OnePartToMBR((uint32_t) convInfo.gptPartNum, mbrNum);
|
numConverted += OnePartToMBR((uint32_t) convInfo.origPartNum, mbrNum);
|
||||||
if (convInfo.hexCode != 0)
|
if (convInfo.hexCode != 0)
|
||||||
protectiveMBR.SetPartType(mbrNum, convInfo.hexCode);
|
protectiveMBR.SetPartType(mbrNum, convInfo.hexCode);
|
||||||
if (convInfo.active)
|
if (convInfo.active)
|
||||||
protectiveMBR.SetPartBootable(mbrNum);
|
protectiveMBR.SetPartBootable(mbrNum);
|
||||||
mbrNum++;
|
mbrNum++;
|
||||||
} // if
|
} // if
|
||||||
if (convInfo.gptPartNum == MBR_EFI_GPT)
|
if (convInfo.origPartNum == MBR_EFI_GPT)
|
||||||
mbrNum++;
|
mbrNum++;
|
||||||
} // for
|
} // for
|
||||||
// Now go through and set sizes for MBR_EFI_GPT partitions....
|
// Now go through and set sizes for MBR_EFI_GPT partitions....
|
||||||
notes->Rewind();
|
notes->Rewind();
|
||||||
mbrNum = 0;
|
mbrNum = 0;
|
||||||
while (notes->GetNextInfo(&convInfo) >= 0) {
|
while (notes->GetNextInfo(&convInfo) >= 0) {
|
||||||
if ((convInfo.gptPartNum >= 0) && (convInfo.type == PRIMARY))
|
if ((convInfo.origPartNum >= 0) && (convInfo.type == PRIMARY))
|
||||||
mbrNum++;
|
mbrNum++;
|
||||||
if (convInfo.gptPartNum == MBR_EFI_GPT) {
|
if (convInfo.origPartNum == MBR_EFI_GPT) {
|
||||||
if (protectiveMBR.FindFirstAvailable() == UINT32_C(1)) {
|
if (protectiveMBR.FindFirstAvailable() == UINT32_C(1)) {
|
||||||
protectiveMBR.MakePart(mbrNum, 1, protectiveMBR.FindLastInFree(1), convInfo.hexCode);
|
protectiveMBR.MakePart(mbrNum, 1, protectiveMBR.FindLastInFree(1), convInfo.hexCode);
|
||||||
protectiveMBR.SetHybrid();
|
protectiveMBR.SetHybrid();
|
||||||
@@ -1803,11 +1863,22 @@ int GPTData::ClearGPTData(void) {
|
|||||||
} // GPTData::ClearGPTData()
|
} // GPTData::ClearGPTData()
|
||||||
|
|
||||||
// Set the location of the second GPT header data to the end of the disk.
|
// Set the location of the second GPT header data to the end of the disk.
|
||||||
|
// If the disk size has actually changed, this also adjusts the protective
|
||||||
|
// entry in the MBR, since it's probably no longer correct.
|
||||||
// Used internally and called by the 'e' option on the recovery &
|
// Used internally and called by the 'e' option on the recovery &
|
||||||
// transformation menu, to help users of RAID arrays who add disk space
|
// transformation menu, to help users of RAID arrays who add disk space
|
||||||
// to their arrays.
|
// to their arrays or to adjust data structures in restore operations
|
||||||
|
// involving unequal-sized disks.
|
||||||
void GPTData::MoveSecondHeaderToEnd() {
|
void GPTData::MoveSecondHeaderToEnd() {
|
||||||
mainHeader.backupLBA = secondHeader.currentLBA = diskSize - UINT64_C(1);
|
mainHeader.backupLBA = secondHeader.currentLBA = diskSize - UINT64_C(1);
|
||||||
|
if (mainHeader.lastUsableLBA != diskSize - mainHeader.firstUsableLBA) {
|
||||||
|
if (protectiveMBR.GetValidity() == hybrid) {
|
||||||
|
protectiveMBR.OptimizeEESize();
|
||||||
|
RecomputeCHS();
|
||||||
|
} // if
|
||||||
|
if (protectiveMBR.GetValidity() == gpt)
|
||||||
|
MakeProtectiveMBR();
|
||||||
|
} // if
|
||||||
mainHeader.lastUsableLBA = secondHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA;
|
mainHeader.lastUsableLBA = secondHeader.lastUsableLBA = diskSize - mainHeader.firstUsableLBA;
|
||||||
secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
|
secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
|
||||||
} // GPTData::FixSecondHeaderLocation()
|
} // GPTData::FixSecondHeaderLocation()
|
||||||
|
|||||||
16
gpt.h
16
gpt.h
@@ -1,7 +1,7 @@
|
|||||||
/* gpt.h -- GPT and data structure definitions, types, and
|
/* gpt.h -- GPT and data structure definitions, types, and
|
||||||
functions */
|
functions */
|
||||||
|
|
||||||
/* This program is copyright (c) 2009, 2010 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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 <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -11,12 +11,12 @@
|
|||||||
#include "mbr.h"
|
#include "mbr.h"
|
||||||
#include "bsd.h"
|
#include "bsd.h"
|
||||||
#include "gptpart.h"
|
#include "gptpart.h"
|
||||||
#include "partnotes.h"
|
#include "gptpartnotes.h"
|
||||||
|
|
||||||
#ifndef __GPTSTRUCTS
|
#ifndef __GPTSTRUCTS
|
||||||
#define __GPTSTRUCTS
|
#define __GPTSTRUCTS
|
||||||
|
|
||||||
#define GPTFDISK_VERSION "0.6.14"
|
#define GPTFDISK_VERSION "0.6.15-pre1"
|
||||||
|
|
||||||
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
|
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
|
||||||
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
#define MAX_ALIGNMENT 65536
|
#define MAX_ALIGNMENT 65536
|
||||||
#define MIN_AF_ALIGNMENT 8
|
#define MIN_AF_ALIGNMENT 8
|
||||||
|
|
||||||
// Below constant corresponds to a ~596GiB (640MB) disk, since WD has
|
// Below constant corresponds to a ~279GiB (300GB) disk, since the
|
||||||
// introduced a smaller Advanced Format drive
|
// smallest Advanced Format drive I know of is 320GB in size
|
||||||
#define SMALLEST_ADVANCED_FORMAT UINT64_C(1250263728)
|
#define SMALLEST_ADVANCED_FORMAT UINT64_C(585937500)
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
GPTData(void);
|
GPTData(void);
|
||||||
GPTData(string deviceFilename);
|
GPTData(string deviceFilename);
|
||||||
virtual ~GPTData(void);
|
virtual ~GPTData(void);
|
||||||
|
GPTData & operator=(const GPTData & orig);
|
||||||
|
|
||||||
// Verify (or update) data integrity
|
// Verify (or update) data integrity
|
||||||
int Verify(void);
|
int Verify(void);
|
||||||
@@ -118,6 +119,7 @@ public:
|
|||||||
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 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);
|
||||||
@@ -125,7 +127,7 @@ public:
|
|||||||
int ForceLoadGPTData(void);
|
int ForceLoadGPTData(void);
|
||||||
int LoadMainTable(void);
|
int LoadMainTable(void);
|
||||||
int LoadSecondTableAsMain(void);
|
int LoadSecondTableAsMain(void);
|
||||||
int SaveGPTData(int quiet = 0, string filename = "");
|
int SaveGPTData(int quiet = 0);
|
||||||
int SaveGPTBackup(const string & filename);
|
int SaveGPTBackup(const string & filename);
|
||||||
int LoadGPTBackup(const string & filename);
|
int LoadGPTBackup(const string & filename);
|
||||||
int SaveMBR(void);
|
int SaveMBR(void);
|
||||||
|
|||||||
74
gptpart.cc
74
gptpart.cc
@@ -24,16 +24,12 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
GPTPart::GPTPart(void) {
|
GPTPart::GPTPart(void) {
|
||||||
int i;
|
|
||||||
|
|
||||||
partitionType.Zero();
|
partitionType.Zero();
|
||||||
uniqueGUID.Zero();
|
uniqueGUID.Zero();
|
||||||
firstLBA = 0;
|
firstLBA = 0;
|
||||||
lastLBA = 0;
|
lastLBA = 0;
|
||||||
attributes = 0;
|
attributes = 0;
|
||||||
|
memset(name, 0, NAME_SIZE);
|
||||||
for (i = 0; i < NAME_SIZE; i++)
|
|
||||||
name[i] = '\0';
|
|
||||||
} // Default constructor
|
} // Default constructor
|
||||||
|
|
||||||
GPTPart::~GPTPart(void) {
|
GPTPart::~GPTPart(void) {
|
||||||
@@ -94,35 +90,32 @@ void GPTPart::SetType(PartType t) {
|
|||||||
// string. This function creates a simple-minded copy for this.
|
// string. This function creates a simple-minded copy for this.
|
||||||
void GPTPart::SetName(const string & theName) {
|
void GPTPart::SetName(const string & theName) {
|
||||||
char newName[NAME_SIZE];
|
char newName[NAME_SIZE];
|
||||||
char *junk;
|
size_t i;
|
||||||
int i;
|
|
||||||
|
|
||||||
// Blank out new name string, just to be on the safe side....
|
// Blank out new name string, so that it will terminate in a null
|
||||||
for (i = 0; i < NAME_SIZE; i++)
|
// when data are copied to it....
|
||||||
newName[i] = '\0';
|
memset(newName, 0, NAME_SIZE);
|
||||||
|
|
||||||
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: ";
|
||||||
junk = fgets(newName, NAME_SIZE / 2, stdin);
|
if (!fgets(newName, NAME_SIZE / 2 + 1, stdin)) {
|
||||||
|
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 = (int) strlen(newName);
|
i = strlen(newName);
|
||||||
if ((i > 0) && (i <= NAME_SIZE))
|
if (i && newName[i - 1] == '\n')
|
||||||
if (newName[i - 1] == '\n')
|
newName[i - 1] = '\0';
|
||||||
newName[i - 1] = '\0';
|
|
||||||
} else {
|
} else {
|
||||||
strcpy(newName, theName.substr(0, NAME_SIZE / 2).c_str());
|
strcpy(newName, theName.substr(0, NAME_SIZE / 2).c_str());
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
// Copy the C-style ASCII string from newName into a form that the GPT
|
// Copy the C-style ASCII string from newName into a form that the GPT
|
||||||
// table will accept....
|
// table will accept....
|
||||||
for (i = 0; i < NAME_SIZE; i++) {
|
memset(name, 0, NAME_SIZE);
|
||||||
if ((i % 2) == 0) {
|
for (i = 0; i < NAME_SIZE / 2; i++)
|
||||||
name[i] = newName[(i / 2)];
|
name[i * 2] = newName[i];
|
||||||
} else {
|
|
||||||
name[i] = '\0';
|
|
||||||
} // if/else
|
|
||||||
} // for
|
|
||||||
} // GPTPart::SetName()
|
} // GPTPart::SetName()
|
||||||
|
|
||||||
// Set the name for the partition based on the current GUID partition type
|
// Set the name for the partition based on the current GUID partition type
|
||||||
@@ -132,22 +125,19 @@ void GPTPart::SetDefaultDescription(void) {
|
|||||||
} // GPTPart::SetDefaultDescription()
|
} // GPTPart::SetDefaultDescription()
|
||||||
|
|
||||||
GPTPart & GPTPart::operator=(const GPTPart & orig) {
|
GPTPart & GPTPart::operator=(const GPTPart & orig) {
|
||||||
int i;
|
|
||||||
|
|
||||||
partitionType = orig.partitionType;
|
partitionType = orig.partitionType;
|
||||||
uniqueGUID = orig.uniqueGUID;
|
uniqueGUID = orig.uniqueGUID;
|
||||||
firstLBA = orig.firstLBA;
|
firstLBA = orig.firstLBA;
|
||||||
lastLBA = orig.lastLBA;
|
lastLBA = orig.lastLBA;
|
||||||
attributes = orig.attributes;
|
attributes = orig.attributes;
|
||||||
for (i = 0; i < NAME_SIZE; i++)
|
memcpy(name, orig.name, NAME_SIZE);
|
||||||
name[i] = orig.name[i];
|
|
||||||
return *this;
|
return *this;
|
||||||
} // assignment operator
|
} // assignment operator
|
||||||
|
|
||||||
// Display summary information; does nothing if the partition is empty.
|
// Display summary information; does nothing if the partition is empty.
|
||||||
void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
|
void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
|
||||||
string sizeInSI;
|
string sizeInSI;
|
||||||
int i;
|
size_t i;
|
||||||
|
|
||||||
if (firstLBA != 0) {
|
if (firstLBA != 0) {
|
||||||
sizeInSI = BytesToSI(lastLBA - firstLBA + 1, blockSize);
|
sizeInSI = BytesToSI(lastLBA - firstLBA + 1, blockSize);
|
||||||
@@ -159,7 +149,7 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
|
|||||||
cout.width(14);
|
cout.width(14);
|
||||||
cout << lastLBA << " ";
|
cout << lastLBA << " ";
|
||||||
cout << BytesToSI(lastLBA - firstLBA + 1, blockSize) << " ";
|
cout << BytesToSI(lastLBA - firstLBA + 1, blockSize) << " ";
|
||||||
for (i = 0; i < 10 - (int) sizeInSI.length(); i++)
|
for (i = 0; i < 10 - sizeInSI.length(); i++)
|
||||||
cout << " ";
|
cout << " ";
|
||||||
cout.fill('0');
|
cout.fill('0');
|
||||||
cout.width(4);
|
cout.width(4);
|
||||||
@@ -201,30 +191,21 @@ void GPTPart::ShowDetails(uint32_t blockSize) {
|
|||||||
|
|
||||||
// Blank (delete) a single partition
|
// Blank (delete) a single partition
|
||||||
void GPTPart::BlankPartition(void) {
|
void GPTPart::BlankPartition(void) {
|
||||||
int j;
|
|
||||||
|
|
||||||
uniqueGUID.Zero();
|
uniqueGUID.Zero();
|
||||||
partitionType.Zero();
|
partitionType.Zero();
|
||||||
firstLBA = 0;
|
firstLBA = 0;
|
||||||
lastLBA = 0;
|
lastLBA = 0;
|
||||||
attributes = 0;
|
attributes = 0;
|
||||||
for (j = 0; j < NAME_SIZE; j++)
|
memset(name, 0, NAME_SIZE);
|
||||||
name[j] = '\0';
|
|
||||||
} // GPTPart::BlankPartition
|
} // GPTPart::BlankPartition
|
||||||
|
|
||||||
// Returns 1 if the two partitions overlap, 0 if they don't
|
// Returns 1 if the two partitions overlap, 0 if they don't
|
||||||
int GPTPart::DoTheyOverlap(const GPTPart & other) {
|
int GPTPart::DoTheyOverlap(const GPTPart & other) {
|
||||||
int theyDo = 0;
|
|
||||||
|
|
||||||
// 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)
|
||||||
if ((firstLBA != 0) && (other.firstLBA != 0)) {
|
// cout << "Entering GPTPart::DoTheyOverlap()\n";
|
||||||
if ((firstLBA < other.lastLBA) && (lastLBA >= other.firstLBA))
|
return firstLBA && other.firstLBA &&
|
||||||
theyDo = 1;
|
(firstLBA <= other.lastLBA) != (lastLBA < other.firstLBA);
|
||||||
if ((other.firstLBA < lastLBA) && (other.lastLBA >= firstLBA))
|
|
||||||
theyDo = 1;
|
|
||||||
} // if
|
|
||||||
return (theyDo);
|
|
||||||
} // GPTPart::DoTheyOverlap()
|
} // GPTPart::DoTheyOverlap()
|
||||||
|
|
||||||
// Reverse the bytes of integral data types; used on big-endian systems.
|
// Reverse the bytes of integral data types; used on big-endian systems.
|
||||||
@@ -242,17 +223,18 @@ void GPTPart::ReversePartBytes(void) {
|
|||||||
// name is the generic one for the partition type.
|
// name is the generic one for the partition type.
|
||||||
void GPTPart::ChangeType(void) {
|
void GPTPart::ChangeType(void) {
|
||||||
char line[255];
|
char line[255];
|
||||||
char* junk;
|
int changeName;
|
||||||
unsigned int changeName = 0;
|
|
||||||
PartType tempType = (GUIDData) "00000000-0000-0000-0000-000000000000";
|
PartType tempType = (GUIDData) "00000000-0000-0000-0000-000000000000";
|
||||||
|
|
||||||
if (GetDescription() == GetTypeName())
|
changeName = (GetDescription() == GetTypeName());
|
||||||
changeName = UINT16_C(1);
|
|
||||||
|
|
||||||
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): ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, sizeof(line), stdin)) {
|
||||||
|
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 {
|
||||||
|
|||||||
29
gpttext.cc
29
gpttext.cc
@@ -29,7 +29,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "attributes.h"
|
#include "attributes.h"
|
||||||
#include "gpttext.h"
|
#include "gpttext.h"
|
||||||
#include "partnotes.h"
|
#include "gptpartnotes.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -353,7 +353,6 @@ 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];
|
||||||
char* junk;
|
|
||||||
int numPartsToCvt, i, j, mbrNum, bootable = 0;
|
int numPartsToCvt, i, j, mbrNum, bootable = 0;
|
||||||
unsigned int hexCode = 0;
|
unsigned int hexCode = 0;
|
||||||
struct PartInfo *newNote;
|
struct PartInfo *newNote;
|
||||||
@@ -368,7 +367,10 @@ void GPTDataTextUI::MakeHybrid(void) {
|
|||||||
// 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: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
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) {
|
||||||
@@ -378,7 +380,7 @@ void GPTDataTextUI::MakeHybrid(void) {
|
|||||||
|
|
||||||
for (i = 0; i < numPartsToCvt; i++) {
|
for (i = 0; i < numPartsToCvt; i++) {
|
||||||
newNote = new struct PartInfo;
|
newNote = new struct PartInfo;
|
||||||
j = newNote->gptPartNum = 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
|
||||||
@@ -404,7 +406,7 @@ void GPTDataTextUI::MakeHybrid(void) {
|
|||||||
// 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;
|
newNote = new struct PartInfo;
|
||||||
newNote->gptPartNum = MBR_EFI_GPT;
|
newNote->origPartNum = MBR_EFI_GPT;
|
||||||
newNote->firstLBA = 1;
|
newNote->firstLBA = 1;
|
||||||
newNote->active = 0;
|
newNote->active = 0;
|
||||||
newNote->hexCode = 0xEE;
|
newNote->hexCode = 0xEE;
|
||||||
@@ -427,13 +429,16 @@ void GPTDataTextUI::MakeHybrid(void) {
|
|||||||
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.
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
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;
|
newNote = new struct PartInfo;
|
||||||
newNote->gptPartNum = MBR_EFI_GPT;
|
newNote->origPartNum = MBR_EFI_GPT;
|
||||||
newNote->active = 0;
|
newNote->active = 0;
|
||||||
newNote->hexCode = hexCode;
|
newNote->hexCode = hexCode;
|
||||||
newNote->type = PRIMARY;
|
newNote->type = PRIMARY;
|
||||||
@@ -452,7 +457,7 @@ void GPTDataTextUI::MakeHybrid(void) {
|
|||||||
// possible, but gives the user the option to override this suggestion.
|
// possible, but gives the user the option to override this suggestion.
|
||||||
// Returns the number of partitions assigned (0 if problems or if the
|
// Returns the number of partitions assigned (0 if problems or if the
|
||||||
// user aborts)
|
// user aborts)
|
||||||
int GPTDataTextUI::AssignPrimaryOrLogical(PartNotes & notes) {
|
int GPTDataTextUI::AssignPrimaryOrLogical(GptPartNotes& notes) {
|
||||||
int i, partNum, allOK = 1, changesWanted = 1, countedParts, numPrimary = 0, numLogical = 0;
|
int i, partNum, allOK = 1, changesWanted = 1, countedParts, numPrimary = 0, numLogical = 0;
|
||||||
int newNumParts; // size of GPT table
|
int newNumParts; // size of GPT table
|
||||||
|
|
||||||
@@ -527,7 +532,7 @@ int GPTDataTextUI::AssignPrimaryOrLogical(PartNotes & notes) {
|
|||||||
int GPTDataTextUI::XFormToMBR(void) {
|
int GPTDataTextUI::XFormToMBR(void) {
|
||||||
int numToConvert, numReallyConverted = 0;
|
int numToConvert, numReallyConverted = 0;
|
||||||
int origNumParts;
|
int origNumParts;
|
||||||
PartNotes notes;
|
GptPartNotes notes;
|
||||||
GPTPart *tempGptParts;
|
GPTPart *tempGptParts;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
@@ -576,7 +581,6 @@ int GPTDataTextUI::XFormToMBR(void) {
|
|||||||
// Get an MBR type code from the user and return it
|
// Get an MBR type code from the user and return it
|
||||||
int GetMBRTypeCode(int defType) {
|
int GetMBRTypeCode(int defType) {
|
||||||
char line[255];
|
char line[255];
|
||||||
char* junk;
|
|
||||||
int typeCode;
|
int typeCode;
|
||||||
|
|
||||||
cout.setf(ios::uppercase);
|
cout.setf(ios::uppercase);
|
||||||
@@ -585,7 +589,10 @@ 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;
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
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
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ 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(PartNotes& notes);
|
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
|
||||||
|
|
||||||
|
|||||||
26
guid.cc
26
guid.cc
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <string.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "guid.h"
|
#include "guid.h"
|
||||||
@@ -29,10 +30,7 @@ GUIDData::GUIDData(void) {
|
|||||||
} // constructor
|
} // constructor
|
||||||
|
|
||||||
GUIDData::GUIDData(const GUIDData & orig) {
|
GUIDData::GUIDData(const GUIDData & orig) {
|
||||||
int i;
|
memcpy(uuidData, orig.uuidData, sizeof(uuidData));
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
uuidData[i] = orig.uuidData[i];
|
|
||||||
} // copy constructor
|
} // copy constructor
|
||||||
|
|
||||||
GUIDData::GUIDData(const char * orig) {
|
GUIDData::GUIDData(const char * orig) {
|
||||||
@@ -43,10 +41,7 @@ GUIDData::~GUIDData(void) {
|
|||||||
} // destructor
|
} // destructor
|
||||||
|
|
||||||
GUIDData & GUIDData::operator=(const GUIDData & orig) {
|
GUIDData & GUIDData::operator=(const GUIDData & orig) {
|
||||||
int i;
|
memcpy(uuidData, orig.uuidData, sizeof(uuidData));
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
uuidData[i] = orig.uuidData[i];
|
|
||||||
return *this;
|
return *this;
|
||||||
} // GUIDData::operator=(const GUIDData & orig)
|
} // GUIDData::operator=(const GUIDData & orig)
|
||||||
|
|
||||||
@@ -123,11 +118,7 @@ GUIDData & GUIDData::operator=(const char * orig) {
|
|||||||
|
|
||||||
// Erase the contents of the GUID
|
// Erase the contents of the GUID
|
||||||
void GUIDData::Zero(void) {
|
void GUIDData::Zero(void) {
|
||||||
int i;
|
memset(uuidData, 0, sizeof(uuidData));
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) {
|
|
||||||
uuidData[i] = 0;
|
|
||||||
} // for
|
|
||||||
} // GUIDData::Zero()
|
} // GUIDData::Zero()
|
||||||
|
|
||||||
// Set a completely random GUID value....
|
// Set a completely random GUID value....
|
||||||
@@ -151,14 +142,7 @@ void GUIDData::Randomize(void) {
|
|||||||
|
|
||||||
// Equality operator; returns 1 if the GUIDs are equal, 0 if they're unequal
|
// Equality operator; returns 1 if the GUIDs are equal, 0 if they're unequal
|
||||||
int GUIDData::operator==(const GUIDData & orig) const {
|
int GUIDData::operator==(const GUIDData & orig) const {
|
||||||
int retval = 1; // assume they're equal
|
return !memcmp(uuidData, orig.uuidData, sizeof(uuidData));
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
if (uuidData[i] != orig.uuidData[i])
|
|
||||||
retval = 0;
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
} // GUIDData::operator==
|
} // GUIDData::operator==
|
||||||
|
|
||||||
// Inequality operator; returns 1 if the GUIDs are unequal, 0 if they're equal
|
// Inequality operator; returns 1 if the GUIDs are unequal, 0 if they're equal
|
||||||
|
|||||||
2
guid.h
2
guid.h
@@ -22,7 +22,7 @@
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
typedef unsigned char my_uuid_t[16];
|
typedef unsigned char my_uuid_t[16];
|
||||||
#else
|
#else
|
||||||
#include </usr/include/uuid/uuid.h>
|
#include <uuid/uuid.h>
|
||||||
typedef uuid_t my_uuid_t;
|
typedef uuid_t my_uuid_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
118
mbr.h
118
mbr.h
@@ -6,23 +6,16 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "gptpart.h"
|
#include "gptpart.h"
|
||||||
#include "partnotes.h"
|
//#include "partnotes.h"
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
#include "basicmbr.h"
|
||||||
|
|
||||||
#ifndef __MBRSTRUCTS
|
#ifndef __MBRSTRUCTS
|
||||||
#define __MBRSTRUCTS
|
#define __MBRSTRUCTS
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class PartNotes;
|
// class PartNotes;
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
* *
|
* *
|
||||||
@@ -30,115 +23,22 @@ 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)
|
|
||||||
struct TempMBR {
|
|
||||||
uint8_t code[440];
|
|
||||||
uint32_t diskSignature;
|
|
||||||
uint16_t nulls;
|
|
||||||
struct MBRRecord partitions[4];
|
|
||||||
uint16_t MBRSignature;
|
|
||||||
}; // struct TempMBR
|
|
||||||
|
|
||||||
// Possible states of the MBR
|
|
||||||
enum MBRValidity {invalid, gpt, hybrid, mbr};
|
|
||||||
|
|
||||||
// Full data in tweaked MBR format
|
// Full data in tweaked MBR format
|
||||||
class MBRData {
|
class MBRData : public BasicMBRData {
|
||||||
protected:
|
protected:
|
||||||
uint8_t code[440];
|
int foo;
|
||||||
uint32_t diskSignature;
|
|
||||||
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];
|
|
||||||
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
|
|
||||||
DiskIO* myDisk;
|
|
||||||
int canDeleteMyDisk;
|
|
||||||
string device;
|
|
||||||
MBRValidity state;
|
|
||||||
struct MBRRecord* GetPartition(int i); // Return primary or logical partition
|
|
||||||
public:
|
public:
|
||||||
MBRData(void);
|
MBRData(void) {}
|
||||||
MBRData(string deviceFilename);
|
MBRData(string deviceFilename) : BasicMBRData(deviceFilename) {}
|
||||||
~MBRData(void);
|
MBRData & operator=(const MBRData & orig);
|
||||||
|
|
||||||
// File I/O functions...
|
|
||||||
int ReadMBRData(const string & deviceFilename);
|
|
||||||
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 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;}
|
|
||||||
|
|
||||||
// Display data for user...
|
|
||||||
void DisplayMBRData(int maxParts = 4);
|
|
||||||
void ShowState(void);
|
|
||||||
|
|
||||||
// Functions that set or get disk metadata (size, CHS geometry, etc.)
|
|
||||||
void SetDiskSize(uint64_t ds) {diskSize = ds;}
|
|
||||||
MBRValidity GetValidity(void) {return state;}
|
|
||||||
void SetHybrid(void) {state = hybrid;} // Set hybrid flag
|
|
||||||
void SetCHSGeom(uint32_t h, uint32_t s);
|
|
||||||
int LBAtoCHS(uint64_t lba, uint8_t * chs); // Convert LBA to CHS
|
|
||||||
int Verify(void);
|
|
||||||
|
|
||||||
// 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 EmptyBootloader(void);
|
|
||||||
void MakeProtectiveMBR(int clearBoot = 0);
|
void MakeProtectiveMBR(int clearBoot = 0);
|
||||||
void MakePart(int num, uint32_t startLBA, uint32_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 DeleteByLocation(uint64_t start64, uint64_t length64);
|
|
||||||
void OptimizeEESize(void);
|
void OptimizeEESize(void);
|
||||||
void RecomputeCHS(int partNum);
|
int DeleteByLocation(uint64_t start64, uint64_t length64);
|
||||||
int CreateLogicals(PartNotes * notes);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Functions to extract data on specific partitions....
|
// 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);
|
|
||||||
GPTPart AsGPT(int i);
|
GPTPart AsGPT(int i);
|
||||||
}; // struct MBRData
|
}; // struct MBRData
|
||||||
|
|
||||||
|
|||||||
162
partnotes.cc
162
partnotes.cc
@@ -29,21 +29,16 @@ PartNotes::PartNotes() {
|
|||||||
notes = NULL;
|
notes = NULL;
|
||||||
currentNote = NULL;
|
currentNote = NULL;
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
gptParts = NULL;
|
origTableSize = 0;
|
||||||
gptTableSize = 0;
|
|
||||||
blockSize = 512;
|
blockSize = 512;
|
||||||
dummyNote.active = 0;
|
dummyNote.active = 0;
|
||||||
dummyNote.gptPartNum = MBR_EMPTY;
|
dummyNote.origPartNum = MBR_EMPTY;
|
||||||
dummyNote.hexCode = 0xEE;
|
dummyNote.hexCode = 0xEE;
|
||||||
dummyNote.next = NULL;
|
dummyNote.next = NULL;
|
||||||
dummyNote.spaceBefore = 0;
|
dummyNote.spaceBefore = 0;
|
||||||
dummyNote.type = WILL_NOT_CONVERT;
|
dummyNote.type = WILL_NOT_CONVERT;
|
||||||
} // PartNotes constructor
|
} // PartNotes constructor
|
||||||
|
|
||||||
PartNotes::PartNotes(GPTPart *parts, GPTData *gpt, int num, int s) {
|
|
||||||
PassPartitions(parts, gpt, num, s);
|
|
||||||
} // PartNotes constructor passing partition information
|
|
||||||
|
|
||||||
// Destructor. Note that we do NOT delete the gptParts array, since we just
|
// Destructor. Note that we do NOT delete the gptParts array, since we just
|
||||||
// store a pointer to an array that's allocated by the calling function.
|
// store a pointer to an array that's allocated by the calling function.
|
||||||
PartNotes::~PartNotes() {
|
PartNotes::~PartNotes() {
|
||||||
@@ -71,59 +66,6 @@ void PartNotes::DeleteNotes(void) {
|
|||||||
* *
|
* *
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
// Creates the notes linked list with as many entries as there are
|
|
||||||
// in-use GPT partitions. Note that the parts array must be pre-sorted!
|
|
||||||
// If not, this function will reject the partition table.
|
|
||||||
// Returns the number of partitions -- normally identical to num,
|
|
||||||
// unless there were problems, in which case it returns 0.
|
|
||||||
int PartNotes::PassPartitions(GPTPart *parts, GPTData *gpt, int num, int s) {
|
|
||||||
int i;
|
|
||||||
struct PartInfo *tempNote = NULL, *lastNote = NULL;
|
|
||||||
|
|
||||||
if ((parts != NULL) && (num > 0)) {
|
|
||||||
blockSize = s;
|
|
||||||
gptParts = parts;
|
|
||||||
gptTableSize = num;
|
|
||||||
if (notes != NULL)
|
|
||||||
DeleteNotes();
|
|
||||||
for (i = 0; i < num; i++) {
|
|
||||||
if (gptParts[i].IsUsed()){
|
|
||||||
tempNote = new struct PartInfo;
|
|
||||||
tempNote->next = NULL;
|
|
||||||
tempNote->firstLBA = gptParts[i].GetFirstLBA();
|
|
||||||
tempNote->lastLBA = gptParts[i].GetLastLBA();
|
|
||||||
if (gpt->IsFree(gptParts[i].GetFirstLBA() - 1)) {
|
|
||||||
tempNote->spaceBefore = 1;
|
|
||||||
tempNote->type = LOGICAL;
|
|
||||||
} else {
|
|
||||||
tempNote->spaceBefore = 0;
|
|
||||||
tempNote->type = PRIMARY;
|
|
||||||
} // if/else
|
|
||||||
tempNote->gptPartNum = i;
|
|
||||||
tempNote->active = 0;
|
|
||||||
if (lastNote == NULL) {
|
|
||||||
lastNote = tempNote;
|
|
||||||
notes = tempNote;
|
|
||||||
} else {
|
|
||||||
lastNote->next = tempNote;
|
|
||||||
lastNote = tempNote;
|
|
||||||
} // if/else
|
|
||||||
} // if GPT partition in use
|
|
||||||
} // for
|
|
||||||
if (!IsSorted()) {
|
|
||||||
DeleteNotes();
|
|
||||||
gptParts = NULL;
|
|
||||||
gptTableSize = 0;
|
|
||||||
cerr << "The partition table must be sorted before calling PartNotes::PassPartitions()!\n";
|
|
||||||
} // if
|
|
||||||
} else {
|
|
||||||
notes = NULL;
|
|
||||||
gptParts = NULL;
|
|
||||||
gptTableSize = 0;
|
|
||||||
} // if/else
|
|
||||||
return gptTableSize;
|
|
||||||
} // PartNotes::PassPartitions
|
|
||||||
|
|
||||||
// Add a single partition to the end of the linked list.
|
// Add a single partition to the end of the linked list.
|
||||||
// Returns 1 on success, 0 on failures.
|
// Returns 1 on success, 0 on failures.
|
||||||
int PartNotes::AddToEnd(struct PartInfo *newOne) {
|
int PartNotes::AddToEnd(struct PartInfo *newOne) {
|
||||||
@@ -344,10 +286,10 @@ uint8_t PartNotes::GetMbrHexType(int partNum) {
|
|||||||
} // if/else
|
} // if/else
|
||||||
} // PartNotes::GetMBRHexType()
|
} // PartNotes::GetMBRHexType()
|
||||||
|
|
||||||
// Return the GPT partition number associated with this note, -1 if
|
// Return the original partition number associated with this note, -1 if
|
||||||
// the notes list is empty, or the GPT partition number of the last
|
// the notes list is empty, or the original partition number of the last
|
||||||
// partition if partNum is too high.
|
// partition if partNum is too high.
|
||||||
int PartNotes::GetGptNum(int partNum) {
|
int PartNotes::GetOrigNum(int partNum) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
struct PartInfo *theNote;
|
struct PartInfo *theNote;
|
||||||
|
|
||||||
@@ -355,11 +297,11 @@ int PartNotes::GetGptNum(int partNum) {
|
|||||||
if (theNote != NULL) {
|
if (theNote != NULL) {
|
||||||
while ((count++ < partNum) && (theNote->next != NULL))
|
while ((count++ < partNum) && (theNote->next != NULL))
|
||||||
theNote = theNote->next;
|
theNote = theNote->next;
|
||||||
return theNote->gptPartNum;
|
return theNote->origPartNum;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
} // if/else
|
} // if/else
|
||||||
} // PartNotes::GetGptNum()
|
} // PartNotes::GetOrigNum()
|
||||||
|
|
||||||
// Return whether or not the partition is flagged as active (bootable)
|
// Return whether or not the partition is flagged as active (bootable)
|
||||||
int PartNotes::GetActiveStatus(int partNum) {
|
int PartNotes::GetActiveStatus(int partNum) {
|
||||||
@@ -417,23 +359,6 @@ int PartNotes::FindExtended(int &start) {
|
|||||||
return length;
|
return length;
|
||||||
} // PartNotes::FindExtended()
|
} // PartNotes::FindExtended()
|
||||||
|
|
||||||
// Returns 1 if the GPT partition table is sorted, 0 if not (or if the
|
|
||||||
// pointer is NULL)
|
|
||||||
int PartNotes::IsSorted(void) {
|
|
||||||
int i, sorted = 1;
|
|
||||||
uint64_t lastStartLBA = 0;
|
|
||||||
|
|
||||||
if (gptParts == NULL) {
|
|
||||||
sorted = 0;
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < gptTableSize; i++) {
|
|
||||||
if (lastStartLBA > gptParts[i].GetFirstLBA())
|
|
||||||
sorted = 0;
|
|
||||||
} // for
|
|
||||||
} // if/else
|
|
||||||
return sorted;
|
|
||||||
} // PartNotes::IsSorted()
|
|
||||||
|
|
||||||
// Returns 1 if the set as a whole makes a legal MBR partition table
|
// Returns 1 if the set as a whole makes a legal MBR partition table
|
||||||
// (possibly with logicals), 0 if not
|
// (possibly with logicals), 0 if not
|
||||||
int PartNotes::IsLegal(void) {
|
int PartNotes::IsLegal(void) {
|
||||||
@@ -557,7 +482,7 @@ void PartNotes::TrimSmallestExtended() {
|
|||||||
} // for
|
} // for
|
||||||
|
|
||||||
// Find the smallest extended partition....
|
// Find the smallest extended partition....
|
||||||
shortestNum = gptTableSize + 1;
|
shortestNum = origTableSize + 1;
|
||||||
for (i = 0; i < numExtended; i++) {
|
for (i = 0; i < numExtended; i++) {
|
||||||
if (extendeds[i].numLogicals < shortestNum) {
|
if (extendeds[i].numLogicals < shortestNum) {
|
||||||
shortestNum = extendeds[i].numLogicals;
|
shortestNum = extendeds[i].numLogicals;
|
||||||
@@ -593,57 +518,8 @@ void PartNotes::TrimSmallestExtended() {
|
|||||||
|
|
||||||
// Display summary information for the user
|
// Display summary information for the user
|
||||||
void PartNotes::ShowSummary(void) {
|
void PartNotes::ShowSummary(void) {
|
||||||
int j;
|
cerr << "Program is calling PartNotes::ShowSummary(); this is a virtual base function,\n"
|
||||||
string sizeInSI;
|
<< "and should never be called.\n";
|
||||||
struct PartInfo *theNote;
|
|
||||||
|
|
||||||
if ((gptParts != NULL) && (notes != NULL)) {
|
|
||||||
theNote = notes;
|
|
||||||
cout << "Sorted GPT partitions and their current conversion status:\n";
|
|
||||||
cout << " Can Be\n";
|
|
||||||
cout << "Number Boot Size Status Logical Code GPT Name\n";
|
|
||||||
while (theNote != NULL) {
|
|
||||||
if (gptParts[theNote->gptPartNum].IsUsed()) {
|
|
||||||
cout.fill(' ');
|
|
||||||
cout.width(4);
|
|
||||||
cout << theNote->gptPartNum + 1 << " ";
|
|
||||||
if (theNote->active)
|
|
||||||
cout << " * ";
|
|
||||||
else
|
|
||||||
cout << " ";
|
|
||||||
sizeInSI = BytesToSI((gptParts[theNote->gptPartNum].GetLastLBA() -
|
|
||||||
gptParts[theNote->gptPartNum].GetFirstLBA() + 1), blockSize);
|
|
||||||
cout << " " << sizeInSI;
|
|
||||||
for (j = 0; j < 12 - (int) sizeInSI.length(); j++)
|
|
||||||
cout << " ";
|
|
||||||
switch (theNote->type) {
|
|
||||||
case PRIMARY:
|
|
||||||
cout << "primary ";
|
|
||||||
break;
|
|
||||||
case LOGICAL:
|
|
||||||
cout << "logical ";
|
|
||||||
break;
|
|
||||||
case WILL_NOT_CONVERT:
|
|
||||||
cout << "OMITTED ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cout << "**ERROR** ";
|
|
||||||
break;
|
|
||||||
} // switch
|
|
||||||
if (theNote->spaceBefore)
|
|
||||||
cout << "Y ";
|
|
||||||
else
|
|
||||||
cout << "- ";
|
|
||||||
cout.fill('0');
|
|
||||||
cout.width(2);
|
|
||||||
cout.setf(ios::uppercase);
|
|
||||||
cout << hex << (int) theNote->hexCode << " " << dec;
|
|
||||||
cout.fill(' ');
|
|
||||||
cout << gptParts[theNote->gptPartNum].GetDescription().substr(0, 25) << "\n";
|
|
||||||
} // if
|
|
||||||
theNote = theNote->next;
|
|
||||||
} // for
|
|
||||||
} // if
|
|
||||||
} // PartNotes::ShowSummary()
|
} // PartNotes::ShowSummary()
|
||||||
|
|
||||||
// Interact with the user to create a change in the specified
|
// Interact with the user to create a change in the specified
|
||||||
@@ -654,7 +530,6 @@ void PartNotes::ShowSummary(void) {
|
|||||||
int PartNotes::MakeChange(int partNum) {
|
int PartNotes::MakeChange(int partNum) {
|
||||||
int allOK = 1;
|
int allOK = 1;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
char *junk;
|
|
||||||
char line[255], command;
|
char line[255], command;
|
||||||
|
|
||||||
if (notes != NULL) {
|
if (notes != NULL) {
|
||||||
@@ -676,7 +551,10 @@ int PartNotes::MakeChange(int partNum) {
|
|||||||
} // switch
|
} // switch
|
||||||
cout << " t - change MBR type code\n";
|
cout << " t - change MBR type code\n";
|
||||||
cout << "Action: ";
|
cout << "Action: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
cerr << "Critical error! Failed fgets() in PartNotes::MakeChange()!\n";
|
||||||
|
exit(1);
|
||||||
|
} // if
|
||||||
sscanf(line, "%c", &command);
|
sscanf(line, "%c", &command);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case 'a': case 'A':
|
case 'a': case 'A':
|
||||||
@@ -694,7 +572,10 @@ int PartNotes::MakeChange(int partNum) {
|
|||||||
case 't': case 'T':
|
case 't': case 'T':
|
||||||
while (type == 0) {
|
while (type == 0) {
|
||||||
cout << "Enter a 2-byte hexadecimal MBR type code: ";
|
cout << "Enter a 2-byte hexadecimal MBR type code: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
cerr << "Critical error! Failed fgets() in PartNotes::MakeChange()\n";
|
||||||
|
exit(1);
|
||||||
|
} // if
|
||||||
sscanf(line, "%x", &type);
|
sscanf(line, "%x", &type);
|
||||||
} // while
|
} // while
|
||||||
SetMbrHexType(partNum, (uint8_t) type);
|
SetMbrHexType(partNum, (uint8_t) type);
|
||||||
@@ -711,7 +592,7 @@ int PartNotes::MakeChange(int partNum) {
|
|||||||
// Returns 1 unless there's a dire bug.
|
// Returns 1 unless there's a dire bug.
|
||||||
int PartNotes::ChangeType(int partNum, int newType) {
|
int PartNotes::ChangeType(int partNum, int newType) {
|
||||||
int origType, allOK = 1;
|
int origType, allOK = 1;
|
||||||
char *junk, line[255];
|
char line[255];
|
||||||
|
|
||||||
if ((notes != NULL) && IsLegal()) {
|
if ((notes != NULL) && IsLegal()) {
|
||||||
origType = GetType(partNum);
|
origType = GetType(partNum);
|
||||||
@@ -733,7 +614,10 @@ int PartNotes::ChangeType(int partNum, int newType) {
|
|||||||
<< "another\norder, such as deleting partitions before changing others' "
|
<< "another\norder, such as deleting partitions before changing others' "
|
||||||
<< "types.\n";
|
<< "types.\n";
|
||||||
cout << "\nReverting change.\nPress <Enter> to continue: ";
|
cout << "\nReverting change.\nPress <Enter> to continue: ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
cerr << "Critical error! Failed fgets() in PartNotes::ChangeType()\n";
|
||||||
|
exit(1);
|
||||||
|
} // if
|
||||||
SetType(partNum, origType);
|
SetType(partNum, origType);
|
||||||
} // if
|
} // if
|
||||||
} else allOK = 0; // if
|
} else allOK = 0; // if
|
||||||
|
|||||||
24
partnotes.h
24
partnotes.h
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
partnotes.h -- Class that takes notes on GPT partitions for purpose of MBR conversion
|
partnotes.h -- Class that takes notes on GPT partitions for purpose of MBR conversion
|
||||||
Copyright (C) 2010 Roderick W. Smith
|
Copyright (C) 2010-2011 Roderick W. Smith
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
#ifndef __PARTNOTES_H
|
#ifndef __PARTNOTES_H
|
||||||
#define __PARTNOTES_H
|
#define __PARTNOTES_H
|
||||||
|
|
||||||
#include "gpt.h"
|
#include <stdint.h>
|
||||||
#include "gptpart.h"
|
#include <sys/types.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ using namespace std;
|
|||||||
// Data structure used in GPT-to-MBR conversions; holds pointer to GPT
|
// Data structure used in GPT-to-MBR conversions; holds pointer to GPT
|
||||||
// partition number, start and end sectors, and a few MBR-specific details
|
// partition number, start and end sectors, and a few MBR-specific details
|
||||||
struct PartInfo {
|
struct PartInfo {
|
||||||
int gptPartNum;
|
int origPartNum;
|
||||||
int spaceBefore; // boolean; if 1, can theoretically become a logical part.
|
int spaceBefore; // boolean; if 1, can theoretically become a logical part.
|
||||||
int active; // boolean
|
int active; // boolean
|
||||||
int type; // WILL_NOT_CONVERT, PRIMARY, or LOGICAL
|
int type; // WILL_NOT_CONVERT, PRIMARY, or LOGICAL
|
||||||
@@ -54,22 +54,21 @@ class PartNotes {
|
|||||||
struct PartInfo *notes;
|
struct PartInfo *notes;
|
||||||
struct PartInfo *currentNote;
|
struct PartInfo *currentNote;
|
||||||
int currentIndex;
|
int currentIndex;
|
||||||
GPTPart *gptParts;
|
|
||||||
int gptTableSize;
|
|
||||||
int blockSize;
|
int blockSize;
|
||||||
|
int origTableSize;
|
||||||
|
|
||||||
void DeleteNotes(void);
|
void DeleteNotes(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PartNotes();
|
PartNotes();
|
||||||
PartNotes(GPTPart *parts, GPTData *gpt, int num, int blockSize);
|
|
||||||
~PartNotes();
|
~PartNotes();
|
||||||
|
|
||||||
// Add partition notes (little or no error checking)
|
// Add partition notes (little or no error checking)
|
||||||
int PassPartitions(GPTPart *parts, GPTData *gpt, int num, int blockSize);
|
// int PassPartitions(GPTPart *parts, GPTData *gpt, int num, int blockSize);
|
||||||
int AddToEnd(struct PartInfo* newOne);
|
int AddToEnd(struct PartInfo* newOne);
|
||||||
int AddToStart(struct PartInfo* newOne);
|
int AddToStart(struct PartInfo* newOne);
|
||||||
void SetType(int partNum, int type); // type is PRIMARY, LOGICAL, or WILL_NOT_CONVERT
|
void SetType(int partNum, int type); // type is PRIMARY, LOGICAL, or WILL_NOT_CONVERT
|
||||||
void SetMbrHexType(int i, uint8_t type);
|
void SetMbrHexType(int partNum, uint8_t type);
|
||||||
void ToggleActiveStatus(int partNum);
|
void ToggleActiveStatus(int partNum);
|
||||||
|
|
||||||
// Retrieve data or metadata
|
// Retrieve data or metadata
|
||||||
@@ -81,12 +80,11 @@ class PartNotes {
|
|||||||
int GetNumLogical();
|
int GetNumLogical();
|
||||||
int GetType(int partNum);
|
int GetType(int partNum);
|
||||||
uint8_t GetMbrHexType(int i);
|
uint8_t GetMbrHexType(int i);
|
||||||
int GetGptNum(int partNum);
|
int GetOrigNum(int partNum);
|
||||||
int GetActiveStatus(int partNum);
|
int GetActiveStatus(int partNum);
|
||||||
int CanBeLogical(int partNum); // returns boolean
|
int CanBeLogical(int partNum); // returns boolean
|
||||||
int FindExtended(int &start);
|
int FindExtended(int &start);
|
||||||
int IsSorted(void);
|
int IsLegal(void); // returns Boolean
|
||||||
int IsLegal(void); // returns boolean
|
|
||||||
|
|
||||||
// Manipulate data or metadata
|
// Manipulate data or metadata
|
||||||
void RemoveDuplicates(void);
|
void RemoveDuplicates(void);
|
||||||
@@ -94,7 +92,7 @@ class PartNotes {
|
|||||||
void TrimSmallestExtended(void);
|
void TrimSmallestExtended(void);
|
||||||
|
|
||||||
// Interact with users, possibly changing data with error handling
|
// Interact with users, possibly changing data with error handling
|
||||||
void ShowSummary(void);
|
virtual void ShowSummary(void);
|
||||||
int MakeChange(int partNum);
|
int MakeChange(int partNum);
|
||||||
int ChangeType(int partNum, int newType);
|
int ChangeType(int partNum, int newType);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Class to manage partition type codes -- a slight variant on MBR type
|
// Class to manage partition type codes -- a slight variant on MBR type
|
||||||
// codes, GUID type codes, and associated names.
|
// codes, GUID type codes, and associated names.
|
||||||
|
|
||||||
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
@@ -163,7 +163,7 @@ void PartType::AddAllTypes(void) {
|
|||||||
AddType(0xc002, "E2A1E728-32E3-11D6-A682-7B03A0000000", "HP-UX service");
|
AddType(0xc002, "E2A1E728-32E3-11D6-A682-7B03A0000000", "HP-UX service");
|
||||||
|
|
||||||
// EFI system and related partitions
|
// EFI system and related partitions
|
||||||
AddType(0xef00, "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", "EFI System"); // Parted marks Linux boot partitions as this
|
AddType(0xef00, "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", "EFI System"); // Parted identifies these as having the "boot flag" set
|
||||||
AddType(0xef01, "024DEE41-33E7-11D3-9D69-0008C781F39F", "MBR partition scheme"); // Used to nest MBR in GPT
|
AddType(0xef01, "024DEE41-33E7-11D3-9D69-0008C781F39F", "MBR partition scheme"); // Used to nest MBR in GPT
|
||||||
AddType(0xef02, "21686148-6449-6E6F-744E-656564454649", "BIOS boot partition"); // Boot loader
|
AddType(0xef02, "21686148-6449-6E6F-744E-656564454649", "BIOS boot partition"); // Boot loader
|
||||||
|
|
||||||
|
|||||||
2
sgdisk.8
2
sgdisk.8
@@ -570,6 +570,8 @@ Contributors:
|
|||||||
|
|
||||||
* Dwight Schauer (dschauer@ti.com)
|
* Dwight Schauer (dschauer@ti.com)
|
||||||
|
|
||||||
|
* Florian Zumbiehl (florz@florz.de)
|
||||||
|
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
\fBcfdisk (8)\fR,
|
\fBcfdisk (8)\fR,
|
||||||
|
|||||||
27
sgdisk.cc
27
sgdisk.cc
@@ -6,7 +6,7 @@
|
|||||||
//
|
//
|
||||||
// by Rod Smith, project began February 2009; sgdisk begun January 2010.
|
// by Rod Smith, project began February 2009; sgdisk begun January 2010.
|
||||||
|
|
||||||
/* This program is copyright (c) 2009, 2010 by Roderick W. Smith. It is distributed
|
/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
|
||||||
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>
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "gpt.h"
|
#include "gpt.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "parttypes.h"
|
#include "parttypes.h"
|
||||||
|
#include "gptpartnotes.h"
|
||||||
#include "attributes.h"
|
#include "attributes.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@@ -30,7 +31,7 @@ int BuildMBR(GPTData& theGPT, char* argument, int isHybrid);
|
|||||||
int CountColons(char* argument);
|
int CountColons(char* argument);
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
GPTData theGPT;
|
GPTData theGPT, secondDevice;
|
||||||
uint32_t sSize;
|
uint32_t sSize;
|
||||||
uint64_t low, high;
|
uint64_t low, high;
|
||||||
int opt, numOptions = 0, saveData = 0, neverSaveData = 0;
|
int opt, numOptions = 0, saveData = 0, neverSaveData = 0;
|
||||||
@@ -231,9 +232,10 @@ int main(int argc, char *argv[]) {
|
|||||||
theGPT.ShowPartDetails(infoPartNum - 1);
|
theGPT.ShowPartDetails(infoPartNum - 1);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (theGPT.LoadGPTBackup((string) backupFile) == 1)
|
if (theGPT.LoadGPTBackup((string) backupFile) == 1) {
|
||||||
|
theGPT.JustLooking(0);
|
||||||
saveData = 1;
|
saveData = 1;
|
||||||
else {
|
} else {
|
||||||
saveData = 0;
|
saveData = 0;
|
||||||
neverSaveData = 1;
|
neverSaveData = 1;
|
||||||
cerr << "Error loading backup file!\n";
|
cerr << "Error loading backup file!\n";
|
||||||
@@ -309,8 +311,11 @@ int main(int argc, char *argv[]) {
|
|||||||
} else saveData = 1;
|
} else saveData = 1;
|
||||||
break;
|
break;
|
||||||
case 'R':
|
case 'R':
|
||||||
theGPT.JustLooking(0);
|
secondDevice = theGPT;
|
||||||
theGPT.SaveGPTData(1, outDevice);
|
secondDevice.SetFile(outDevice);
|
||||||
|
secondDevice.JustLooking(0);
|
||||||
|
// secondDevice.FixupMBR();
|
||||||
|
secondDevice.SaveGPTData(1);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
theGPT.JustLooking(0);
|
theGPT.JustLooking(0);
|
||||||
@@ -424,7 +429,7 @@ 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;
|
||||||
PartNotes notes;
|
GptPartNotes notes;
|
||||||
struct PartInfo *newNote;
|
struct PartInfo *newNote;
|
||||||
|
|
||||||
if ((&theGPT != NULL) && (argument != NULL)) {
|
if ((&theGPT != NULL) && (argument != NULL)) {
|
||||||
@@ -432,17 +437,17 @@ int BuildMBR(GPTData & theGPT, char* argument, int isHybrid) {
|
|||||||
if (numParts <= (4 - isHybrid)) {
|
if (numParts <= (4 - isHybrid)) {
|
||||||
for (i = 0; i < numParts; i++) {
|
for (i = 0; i < numParts; i++) {
|
||||||
newNote = new struct PartInfo;
|
newNote = new struct PartInfo;
|
||||||
newNote->gptPartNum = GetInt(argument, i + 1) - 1;
|
newNote->origPartNum = GetInt(argument, i + 1) - 1;
|
||||||
newNote->active = 0;
|
newNote->active = 0;
|
||||||
newNote->hexCode = 0; // code to compute it from default
|
newNote->hexCode = 0; // code to compute it from default
|
||||||
newNote->type = PRIMARY;
|
newNote->type = PRIMARY;
|
||||||
newNote->firstLBA = theGPT[newNote->gptPartNum].GetFirstLBA();
|
newNote->firstLBA = theGPT[newNote->origPartNum].GetFirstLBA();
|
||||||
newNote->lastLBA = theGPT[newNote->gptPartNum].GetLastLBA();
|
newNote->lastLBA = theGPT[newNote->origPartNum].GetLastLBA();
|
||||||
notes.AddToEnd(newNote);
|
notes.AddToEnd(newNote);
|
||||||
} // for
|
} // for
|
||||||
if (isHybrid) {
|
if (isHybrid) {
|
||||||
newNote = new struct PartInfo;
|
newNote = new struct PartInfo;
|
||||||
newNote->gptPartNum = MBR_EFI_GPT;
|
newNote->origPartNum = MBR_EFI_GPT;
|
||||||
newNote->active = 0;
|
newNote->active = 0;
|
||||||
newNote->hexCode = 0xEE;
|
newNote->hexCode = 0xEE;
|
||||||
newNote->type = PRIMARY;
|
newNote->type = PRIMARY;
|
||||||
|
|||||||
27
support.cc
27
support.cc
@@ -63,11 +63,13 @@ int GetNumber(int low, int high, int def, const string & prompt) {
|
|||||||
char GetYN(void) {
|
char GetYN(void) {
|
||||||
char line[255];
|
char line[255];
|
||||||
char response;
|
char response;
|
||||||
char *junk;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cout << "(Y/N): ";
|
cout << "(Y/N): ";
|
||||||
junk = fgets(line, 255, stdin);
|
if (!fgets(line, 255, stdin)) {
|
||||||
|
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';
|
||||||
@@ -306,32 +308,23 @@ void ReverseBytes(void* theValue, int numBytes) {
|
|||||||
|
|
||||||
// Extract integer data from argument string, which should be colon-delimited
|
// Extract integer data from argument string, which should be colon-delimited
|
||||||
uint64_t GetInt(const string & argument, int itemNum) {
|
uint64_t GetInt(const string & argument, int itemNum) {
|
||||||
int startPos = -1, endPos = -1;
|
uint64_t retval;
|
||||||
uint64_t retval = 0;
|
|
||||||
|
|
||||||
while (itemNum-- > 0) {
|
istringstream inString(GetString(argument, itemNum));
|
||||||
startPos = endPos + 1;
|
|
||||||
endPos = (int) argument.find(':', startPos);
|
|
||||||
}
|
|
||||||
if (endPos == (int) string::npos)
|
|
||||||
endPos = (int) argument.length();
|
|
||||||
endPos--;
|
|
||||||
|
|
||||||
istringstream inString(argument.substr(startPos, endPos - startPos + 1));
|
|
||||||
inString >> retval;
|
inString >> retval;
|
||||||
return retval;
|
return retval;
|
||||||
} // 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(const string & argument, int itemNum) {
|
||||||
int startPos = -1, endPos = -1;
|
size_t startPos = -1, endPos = -1;
|
||||||
|
|
||||||
while (itemNum-- > 0) {
|
while (itemNum-- > 0) {
|
||||||
startPos = endPos + 1;
|
startPos = endPos + 1;
|
||||||
endPos = (int) argument.find(':', startPos);
|
endPos = argument.find(':', startPos);
|
||||||
}
|
}
|
||||||
if (endPos == (int) string::npos)
|
if (endPos == string::npos)
|
||||||
endPos = (int) argument.length();
|
endPos = argument.length();
|
||||||
endPos--;
|
endPos--;
|
||||||
|
|
||||||
return argument.substr(startPos, endPos - startPos + 1);
|
return argument.substr(startPos, endPos - startPos + 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user