ffu2img.py WIN10IOT FFU镜像转IMG
本文地址:http://dsyn.tongxinmao.com/Article/Detail/id/275
#!/usr/bin/env python
# MIT License, Copyright 2015 t0x0
# Full text in 'LICENSE' file
# May not work for any FFU files other than the Raspberry Pi 2 Windows 10 Insider Preview image.
# Tested on the 2015-05-12 release image with Python 2.7.9
# Use at your own risk, and let me know if it fails for your situation. me@t0x0.com
import sys, os.path, struct, string
from collections import namedtuple
if len(sys.argv) < 2:
	sys.exit("Error: no filenames provided. Usage: ffu2img.py input.ffu [output.img]\nWarning, will overwrite output file without prior permission.")
ffupath = sys.argv[1]
if len(sys.argv) == 3:
	imgpath = sys.argv[2]
else:
	imgpath = string.rsplit(ffupath, '.', 1)[0] + '.img'
print 'Input File: ' + ffupath
print 'Output File: ' + imgpath
SecurityHeader = namedtuple("SecurityHeader", "cbSize signature dwChunkSizeInKb dwAlgId dwCatalogSize dwHashTableSize")
ImageHeader = namedtuple("ImageHeader", "cbSize signature ManifestLength dwChunkSize")
StoreHeader = namedtuple("StoreHeader", "dwUpdateType MajorVersion MinorVersion FullFlashMajorVersion FullFlashMinorVersion szPlatformId dwBlockSizeInBytes dwWriteDescriptorCount dwWriteDescriptorLength dwValidateDescriptorCount dwValidateDescriptorLength dwInitialTableIndex dwInitialTableCount dwFlashOnlyTableIndex dwFlashOnlyTableCount dwFinalTableIndex dwFinalTableCount")
BlockDataEntry = namedtuple("BlockDataEntry", "dwDiskAccessMethod dwBlockIndex dwLocationCount dwBlockCount")
ffufp = open(ffupath, 'rb')
imgfp = open(imgpath, 'wb')
logfp = open('ffu2img.log', 'w')
def readsecheader():
	(cbSize, signature, dwChunkSizeInKb, dwAlgId, dwCatalogSize, dwHashTableSize) = struct.unpack("<L12sLLLL", ffufp.read(32))
	if signature != 'SignedImage ':
		logfp.write('Exiting, incorrect signature: "' + signature + '"')
		sys.exit("Error: security header signature incorrect: " + str(signature))
	return SecurityHeader(cbSize, signature, dwChunkSizeInKb, dwAlgId, dwCatalogSize, dwHashTableSize)
def readimgheader():
	(cbSize, signature, ManifestLength, dwChunkSize) = struct.unpack("<L12sLL", ffufp.read(24))
	if signature != 'ImageFlash  ':
		logfp.write('Exiting, incorrect signature: "' + signature + '"')
		sys.exit("Error: image header signature incorrect." + str(signature))
	return ImageHeader(cbSize, signature, ManifestLength, dwChunkSize)
def readstoreheader():
	(dwUpdateType, MajorVersion, MinorVersion, FullFlashMajorVersion, FullFlashMinorVersion, szPlatformId, dwBlockSizeInBytes, dwWriteDescriptorCount, dwWriteDescriptorLength, dwValidateDescriptorCount, dwValidateDescriptorLength, dwInitialTableIndex, dwInitialTableCount, dwFlashOnlyTableIndex, dwFlashOnlyTableCount, dwFinalTableIndex, dwFinalTableCount) = struct.unpack("<LHHHH192sLLLLLLLLLLL", ffufp.read(248))
	return StoreHeader(dwUpdateType, MajorVersion, MinorVersion, FullFlashMajorVersion, FullFlashMinorVersion, szPlatformId, dwBlockSizeInBytes, dwWriteDescriptorCount, dwWriteDescriptorLength, dwValidateDescriptorCount, dwValidateDescriptorLength, dwInitialTableIndex, dwInitialTableCount, dwFlashOnlyTableIndex, dwFlashOnlyTableCount, dwFinalTableIndex, dwFinalTableCount)
def readblockdataentry():
	(dwLocationCount, dwBlockCount, dwDiskAccessMethod, dwBlockIndex) = struct.unpack("<LLLL", ffufp.read(16))
	return BlockDataEntry(dwLocationCount, dwBlockCount, dwDiskAccessMethod, dwBlockIndex)
def gotoendofchunk(chunksizeinkb, position):
	remainderofchunk = position%int(chunksizeinkb*1024)
	distancetochunkend = (chunksizeinkb*1024) - remainderofchunk
	ffufp.seek(distancetochunkend, 1)
	return distancetochunkend
logfp.write('FFUSecHeader begin: ' + str(hex(ffufp.tell())) + '\n')
FFUSecHeader = readsecheader()
for key, val in FFUSecHeader._asdict().iteritems():
	logfp.write(key + ' = ' + str(val) + '\n')
ffufp.seek(FFUSecHeader.dwCatalogSize, 1)
ffufp.seek(FFUSecHeader.dwHashTableSize, 1)
gotoendofchunk(FFUSecHeader.dwChunkSizeInKb, ffufp.tell())
logfp.write('FFUImgHeader begin: ' + str(hex(ffufp.tell())) + '\n')
FFUImgHeader = readimgheader()
for key, val in FFUImgHeader._asdict().iteritems():
	logfp.write(key + ' = ' + str(val) + '\n')
ffufp.seek(FFUImgHeader.ManifestLength, 1)
gotoendofchunk(FFUSecHeader.dwChunkSizeInKb, ffufp.tell())
logfp.write('FFUStoreHeader begin: ' + str(hex(ffufp.tell())) + '\n')
FFUStoreHeader = readstoreheader()
for key, val in FFUStoreHeader._asdict().iteritems():
	logfp.write(key + ' = ' + str(val) + '\n')
ffufp.seek(FFUStoreHeader.dwValidateDescriptorLength, 1)
print 'Block data entries begin: ' + str(hex(ffufp.tell()))
logfp.write('Block data entries begin: ' + str(hex(ffufp.tell())) + '\n')
print 'Block data entries end: ' + str(hex(ffufp.tell() + FFUStoreHeader.dwWriteDescriptorLength))
logfp.write('Block data entries end: ' + str(hex(ffufp.tell() + FFUStoreHeader.dwWriteDescriptorLength)) + '\n')
blockdataaddress = ffufp.tell() + FFUStoreHeader.dwWriteDescriptorLength
blockdataaddress = blockdataaddress + (FFUSecHeader.dwChunkSizeInKb*1024)-(blockdataaddress%int((FFUSecHeader.dwChunkSizeInKb*1024)))
logfp.write('Block data chunks begin: ' + str(hex(blockdataaddress)) + '\n')
print 'Block data chunks begin: ' + str(hex(blockdataaddress))
iBlock = 0
oldblockcount = 0
while iBlock < FFUStoreHeader.dwWriteDescriptorCount:
	print('\r' + str(iBlock) + ' blocks, ' + str((iBlock*FFUStoreHeader.dwBlockSizeInBytes)/1024) + 'kb written                                '),
	logfp.write('Block data entry from: ' + str(hex(ffufp.tell())) + '\n')
	CurrentBlockDataEntry = readblockdataentry()
	if abs(CurrentBlockDataEntry.dwBlockCount-oldblockcount) > 1:
		print('\r' + str(iBlock) + ' blocks, ' + str((iBlock*FFUStoreHeader.dwBlockSizeInBytes)/1024) + 'kb written - Delay expected. Please wait.'),
	oldblockcount = CurrentBlockDataEntry.dwBlockCount
	for key, val in CurrentBlockDataEntry._asdict().iteritems():
		logfp.write(key + ' = ' + str(val) + '\n')
	curraddress = ffufp.tell()
	ffufp.seek(blockdataaddress+(iBlock*FFUStoreHeader.dwBlockSizeInBytes))
	imgfp.seek(CurrentBlockDataEntry.dwBlockCount*FFUStoreHeader.dwBlockSizeInBytes)
	imgfp.write(ffufp.read(FFUStoreHeader.dwBlockSizeInBytes))
	ffufp.seek(curraddress)
	iBlock = iBlock + 1
print '\nWrite complete.'
imgfp.close()
ffufp.close()
logfp.close()上一篇:JAVA 热敏打印驱动框架、实现、DEMO
下一篇:Zebra斑马打印机通过VB编程实现ZPL代码控制打印标签