ffu2img.py WIN10IOT FFU镜像转IMG
本文地址:http://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代码控制打印标签