func ReadTable(reader io.ReadSeeker, SectorSize uint64) (table Table, err error) {
	table.SectorSize = SectorSize
	table.Header, err = readHeader(reader, SectorSize)
	if err != nil {
		return
	}
	if seekDest, ok := mul(int64(SectorSize), int64(table.Header.PartitionsTableStartLBA)); ok {
		reader.Seek(seekDest, 0)
	} else {
		err = fmt.Errorf("Seek overflow when read partition tables")
		return
	}
	for i := uint32(0); i < table.Header.PartitionsArrLen; i++ {
		var p Partition
		p, err = readPartition(reader, table.Header.PartitionEntrySize)
		if err != nil {
			return
		}
		table.Partitions = append(table.Partitions, p)
	}
	if table.Header.PartitionsCRC != table.calcPartitionsCRC() {
		err = fmt.Errorf("Bad partitions crc")
		return
	}
	return
}
////////////////////////////////////////////
//////////////// TABLE /////////////////////
////////////////////////////////////////////
Read GPT partition
Have to set to first byte of GPT Header (usually start of second sector on disk)
package gpt
import (
	"bytes"
	"encoding/binary"
	"fmt"
	"hash/crc32"
	"io"
	"unicode/utf16"
)
const standardHeaderSize = 92           
const standardPartitionEntrySize = 128  
type Flags [8]byte
type Guid [16]byte
func (this Guid) String() string {
	return guidToString(this)
}
type PartType Guid
func (this PartType) String() string {
	return guidToString(this)
}
var (
	GUID_LVM = PartType([16]byte{0x79, 0xd3, 0xd6, 0xe6, 0x7, 0xf5, 0xc2, 0x44, 0xa2, 0x3c, 0x23, 0x8f, 0x2a, 0x3d, 0xf9, 0x28})  
)
type Header struct {
	Signature               [8]byte  
	Revision                uint32   
	Size                    uint32   
	CRC                     uint32   
	Reserved                uint32   
	HeaderStartLBA          uint64   
	HeaderCopyStartLBA      uint64   
	FirstUsableLBA          uint64   
	LastUsableLBA           uint64   
	DiskGUID                Guid     
	PartitionsTableStartLBA uint64   
	PartitionsArrLen        uint32   
	PartitionEntrySize      uint32   
	PartitionsCRC           uint32   
	TrailingBytes           []byte   
}
type Partition struct {
	Type          PartType  
	Id            Guid      
	FirstLBA      uint64    
	LastLBA       uint64    
	Flags         Flags     
	PartNameUTF16 [72]byte  
	TrailingBytes []byte    
}
type Table struct {
	SectorSize uint64  
	Header     Header
	Partitions []Partition
}
func readHeader(reader io.Reader, sectorSize uint64) (res Header, err error) {
	read := func(data interface{}) {
		if err == nil {
			err = binary.Read(reader, binary.LittleEndian, data)
		}
	}
	read(&res.Signature)
	read(&res.Revision)
	read(&res.Size)
	read(&res.CRC)
	read(&res.Reserved)
	read(&res.HeaderStartLBA)
	read(&res.HeaderCopyStartLBA)
	read(&res.FirstUsableLBA)
	read(&res.LastUsableLBA)
	read(&res.DiskGUID)
	read(&res.PartitionsTableStartLBA)
	read(&res.PartitionsArrLen)
	read(&res.PartitionEntrySize)
	read(&res.PartitionsCRC)
	if err != nil {
		return
	}
	if string(res.Signature[:]) != "EFI PART" {
		return res, fmt.Errorf("Bad GPT signature")
	}
	trailingBytes := make([]byte, sectorSize-uint64(standardHeaderSize))
	reader.Read(trailingBytes)
	res.TrailingBytes = trailingBytes
	if res.calcCRC() != res.CRC {
		return res, fmt.Errorf("BAD GPT Header CRC")
	}
	return
}
func (this *Header) calcCRC() uint32 {
	buf := &bytes.Buffer{}
	this.write(buf, false)
	return crc32.ChecksumIEEE(buf.Bytes()[:this.Size])
}
func (this *Header) write(writer io.Writer, saveCRC bool) (err error) {
	write := func(data interface{}) {
		if err == nil {
			err = binary.Write(writer, binary.LittleEndian, data)
		}
	}
	write(&this.Signature)
	write(&this.Revision)
	write(&this.Size)
	if saveCRC {
		this.CRC = this.calcCRC()
		write(&this.CRC)
	} else {
		write(uint32(0))
	}
	write(&this.Reserved)
	write(&this.HeaderStartLBA)
	write(&this.HeaderCopyStartLBA)
	write(&this.FirstUsableLBA)
	write(&this.LastUsableLBA)
	write(&this.DiskGUID)
	write(&this.PartitionsTableStartLBA)
	write(&this.PartitionsArrLen)
	write(&this.PartitionEntrySize)
	write(&this.PartitionsCRC)
	if err != nil {
		return
	}
	write(this.TrailingBytes)
	return
}
func readPartition(reader io.Reader, size uint32) (p Partition, err error) {
	read := func(data interface{}) {
		if err == nil {
			err = binary.Read(reader, binary.LittleEndian, data)
		}
	}
	p.TrailingBytes = make([]byte, size-standardPartitionEntrySize)
	read(&p.Type)
	read(&p.Id)
	read(&p.FirstLBA)
	read(&p.LastLBA)
	read(&p.Flags)
	read(&p.PartNameUTF16)
	read(&p.TrailingBytes)
	return
}
func (this Partition) write(writer io.Writer, size uint32) (err error) {
	write := func(data interface{}) {
		if err == nil {
			err = binary.Write(writer, binary.LittleEndian, data)
		}
	}
	if size != uint32(standardPartitionEntrySize+len(this.TrailingBytes)) {
		return fmt.Errorf("Entry size(%v) != real entry size(%v)", size, standardPartitionEntrySize+len(this.TrailingBytes))
	}
	write(this.Type)
	write(this.Id)
	write(this.FirstLBA)
	write(this.LastLBA)
	write(this.Flags)
	write(this.PartNameUTF16)
	write(this.TrailingBytes)
	return
}
func (this Partition) IsEmpty() bool {
	return this.Type == [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}
func (this Partition) Name() string {
	chars := make([]uint16, 0, 36)
	for i := 0; i < len(this.PartNameUTF16); i += 2 {
		chars = append(chars, uint16(this.PartNameUTF16[i])+uint16(this.PartNameUTF16[i+1])<<8)
	}
	runes := utf16.Decode(chars)
	return string(runes)
}