UNPKG

18.9 kBSource Map (JSON)View Raw
1{"version":3,"file":"vmdk-read.js","names":["_assert","_interopRequireDefault","require","_zlib","_definitions","_virtualBuffer","obj","__esModule","default","SECTOR_SIZE","HEADER_SIZE","VERSION_OFFSET","parseDescriptor","descriptorSlice","descriptorText","toString","replace","descriptorDict","extentList","lines","split","filter","line","trim","length","defLine","indexOf","items","push","access","sizeSectors","size","type","name","offset","descriptor","extents","readGrain","offsetSectors","buffer","compressed","readUInt32LE","grainBuffer","slice","grainContent","zlib","inflateSync","lba","parseU64b","lbaBytes","grain","grainSize","byteLength","parseMarker","value","alignSectors","number","Math","ceil","VMDKDirectParser","constructor","readStream","grainLogicalAddressList","grainFileOffsetList","gzipped","unzipStream","createGunzip","pipe","virtualBuffer","VirtualBuffer","header","_length","_readL1","position","l1entries","floor","capacitySectors","l1EntrySectors","sectorAlignedL1Bytes","l1Buffer","readChunk","l2Start","l2IsContiguous","i","l1Entry","previousL1Entry","l1L2FreeSpace","l2entries","grainSizeSectors","l2ByteSize","numGTEsPerGT","l2Buffer","firstGrain","l2Entry","freeSpace","readHeader","headerBuffer","magicString","Error","version","unpackHeader","descriptorLength","descriptorSizeSectors","descriptorBuffer","l1PositionBytes","grainDirectoryOffsetSectors","endOfDescriptor","parseMarkedGrain","expectedLogicalAddress","sector","marker","grainDiskSize","alignedGrainDiskSize","remainOfBufferSize","remainderOfGrainBuffer","Buffer","concat","grainObject","compressionMethod","compressionDeflate","flags","compressedGrains","assert","strictEqual","blockIterator","tableIndex","grainPosition","grainSizeBytes","hasMarkers","logicalAddressBytes","data","undefined","min","exports"],"sources":["../src/vmdk-read.js"],"sourcesContent":["import assert from 'assert'\nimport zlib from 'zlib'\n\nimport { compressionDeflate, unpackHeader, parseU64b } from './definitions'\nimport { VirtualBuffer } from './virtual-buffer'\n\nconst SECTOR_SIZE = 512\nconst HEADER_SIZE = 512\nconst VERSION_OFFSET = 4\n\nfunction parseDescriptor(descriptorSlice) {\n const descriptorText = descriptorSlice.toString('ascii').replace(/\\x00+$/, '') // eslint-disable-line no-control-regex\n const descriptorDict = {}\n const extentList = []\n const lines = descriptorText.split(/\\r?\\n/).filter(line => {\n return line.trim().length > 0 && line[0] !== '#'\n })\n for (const line of lines) {\n const defLine = line.split('=')\n // the wonky quote test is to avoid having an equal sign in the name of an extent\n if (defLine.length === 2 && defLine[0].indexOf('\"') === -1) {\n descriptorDict[defLine[0]] = defLine[1].replace(/['\"]+/g, '')\n } else {\n const items = line.split(' ')\n extentList.push({\n access: items[0],\n sizeSectors: items[1],\n size: items[1] * 512,\n type: items[2],\n name: items[3],\n offset: items.length > 4 ? items[4] : 0,\n })\n }\n }\n return { descriptor: descriptorDict, extents: extentList }\n}\n\nfunction readGrain(offsetSectors, buffer, compressed) {\n const offset = offsetSectors * SECTOR_SIZE\n const size = buffer.readUInt32LE(offset + 8)\n const grainBuffer = buffer.slice(offset + 12, offset + 12 + size)\n const grainContent = compressed ? zlib.inflateSync(grainBuffer) : grainBuffer\n const lba = parseU64b(buffer, offset, 'l2Lba')\n return {\n offsetSectors,\n offset,\n lba,\n lbaBytes: lba * SECTOR_SIZE,\n size,\n buffer: grainBuffer,\n grain: grainContent,\n grainSize: grainContent.byteLength,\n }\n}\n\nfunction parseMarker(buffer) {\n const value = buffer.readUInt32LE(0)\n const size = buffer.readUInt32LE(8)\n const type = buffer.readUInt32LE(12)\n return { value, size, type }\n}\n\nfunction alignSectors(number) {\n return Math.ceil(number / SECTOR_SIZE) * SECTOR_SIZE\n}\n\nexport default class VMDKDirectParser {\n constructor(readStream, grainLogicalAddressList, grainFileOffsetList, gzipped = false, length) {\n if (gzipped) {\n const unzipStream = zlib.createGunzip()\n readStream.pipe(unzipStream)\n readStream = unzipStream\n }\n this.grainLogicalAddressList = grainLogicalAddressList\n this.grainFileOffsetList = grainFileOffsetList\n this.virtualBuffer = new VirtualBuffer(readStream)\n this.header = null\n this._length = length\n }\n\n // I found a VMDK file whose L1 and L2 table did not have a marker, but they were at the top\n // I detect this case and eat those tables first then let the normal loop go over the grains.\n async _readL1() {\n const position = this.virtualBuffer.position\n const l1entries = Math.floor(\n (this.header.capacitySectors + this.header.l1EntrySectors - 1) / this.header.l1EntrySectors\n )\n const sectorAlignedL1Bytes = alignSectors(l1entries * 4)\n const l1Buffer = await this.virtualBuffer.readChunk(sectorAlignedL1Bytes, 'L1 table ' + position)\n let l2Start = 0\n let l2IsContiguous = true\n for (let i = 0; i < l1entries; i++) {\n const l1Entry = l1Buffer.readUInt32LE(i * 4)\n if (i > 0) {\n const previousL1Entry = l1Buffer.readUInt32LE((i - 1) * 4)\n l2IsContiguous = l2IsContiguous && l1Entry - previousL1Entry === 4\n } else {\n l2IsContiguous =\n l1Entry * SECTOR_SIZE === this.virtualBuffer.position ||\n l1Entry * SECTOR_SIZE === this.virtualBuffer.position + SECTOR_SIZE\n l2Start = l1Entry * SECTOR_SIZE\n }\n }\n if (!l2IsContiguous) {\n return null\n }\n const l1L2FreeSpace = l2Start - this.virtualBuffer.position\n if (l1L2FreeSpace > 0) {\n await this.virtualBuffer.readChunk(l1L2FreeSpace, 'freeSpace between L1 and L2')\n }\n const l2entries = Math.ceil(this.header.capacitySectors / this.header.grainSizeSectors)\n const l2ByteSize = alignSectors(l1entries * this.header.numGTEsPerGT * 4)\n const l2Buffer = await this.virtualBuffer.readChunk(l2ByteSize, 'L2 table ' + position)\n let firstGrain = null\n for (let i = 0; i < l2entries; i++) {\n const l2Entry = l2Buffer.readUInt32LE(i * 4)\n if (firstGrain === null) {\n firstGrain = l2Entry\n }\n }\n const freeSpace = firstGrain * SECTOR_SIZE - this.virtualBuffer.position\n if (freeSpace > 0) {\n await this.virtualBuffer.readChunk(freeSpace, 'freeSpace after L2')\n }\n }\n\n async readHeader() {\n const headerBuffer = await this.virtualBuffer.readChunk(HEADER_SIZE, 'readHeader')\n const magicString = headerBuffer.slice(0, 4).toString('ascii')\n if (magicString !== 'KDMV') {\n throw new Error('not a VMDK file')\n }\n const version = headerBuffer.readUInt32LE(VERSION_OFFSET)\n if (version !== 1 && version !== 3) {\n throw new Error('unsupported VMDK version ' + version + ', only version 1 and 3 are supported')\n }\n this.header = unpackHeader(headerBuffer)\n // I think the multiplications are OK, because the descriptor is always at the beginning of the file\n const descriptorLength = this.header.descriptorSizeSectors * SECTOR_SIZE\n const descriptorBuffer = await this.virtualBuffer.readChunk(descriptorLength, 'descriptor')\n this.descriptor = parseDescriptor(descriptorBuffer)\n let l1PositionBytes = null\n if (this.header.grainDirectoryOffsetSectors !== -1 && this.header.grainDirectoryOffsetSectors !== 0) {\n l1PositionBytes = this.header.grainDirectoryOffsetSectors * SECTOR_SIZE\n }\n const endOfDescriptor = this.virtualBuffer.position\n if (\n l1PositionBytes !== null &&\n (l1PositionBytes === endOfDescriptor || l1PositionBytes === endOfDescriptor + SECTOR_SIZE)\n ) {\n if (l1PositionBytes === endOfDescriptor + SECTOR_SIZE) {\n await this.virtualBuffer.readChunk(SECTOR_SIZE, 'skipping L1 marker')\n }\n await this._readL1()\n }\n return this.header\n }\n\n async parseMarkedGrain(expectedLogicalAddress) {\n const position = this.virtualBuffer.position\n const sector = await this.virtualBuffer.readChunk(SECTOR_SIZE, `marker starting at ${position}`)\n const marker = parseMarker(sector)\n if (marker.size === 0) {\n throw new Error(`expected grain marker, received ${marker}`)\n } else if (marker.size > 10) {\n const grainDiskSize = marker.size + 12\n const alignedGrainDiskSize = alignSectors(grainDiskSize)\n const remainOfBufferSize = alignedGrainDiskSize - SECTOR_SIZE\n const remainderOfGrainBuffer = await this.virtualBuffer.readChunk(\n remainOfBufferSize,\n `grain remainder ${this.virtualBuffer.position} -> ${this.virtualBuffer.position + remainOfBufferSize}`\n )\n const grainBuffer = Buffer.concat([sector, remainderOfGrainBuffer])\n const grainObject = readGrain(\n 0,\n grainBuffer,\n this.header.compressionMethod === compressionDeflate && this.header.flags.compressedGrains\n )\n assert.strictEqual(grainObject.lba * SECTOR_SIZE, expectedLogicalAddress)\n return grainObject.grain\n }\n }\n\n async *blockIterator() {\n for (let tableIndex = 0; tableIndex < this.grainFileOffsetList.length; tableIndex++) {\n const position = this.virtualBuffer.position\n const grainPosition = this.grainFileOffsetList[tableIndex] * SECTOR_SIZE\n const grainSizeBytes = this.header.grainSizeSectors * SECTOR_SIZE\n const lba = this.grainLogicalAddressList[tableIndex] * grainSizeBytes\n assert.strictEqual(\n grainPosition >= position,\n true,\n `Grain position ${grainPosition} must be after current position ${position}`\n )\n await this.virtualBuffer.readChunk(grainPosition - position, `blank from ${position} to ${grainPosition}`)\n let grain\n if (this.header.flags.hasMarkers) {\n grain = await this.parseMarkedGrain(lba)\n } else {\n grain = await this.virtualBuffer.readChunk(grainSizeBytes, 'grain ' + this.virtualBuffer.position)\n }\n yield { logicalAddressBytes: lba, data: grain }\n }\n // drain remaining\n // stream.resume does not seems to be enough to consume completly the stream\n // especially when this stream is part of a tar ( ova) , potentially gzipped\n if (this._length !== undefined) {\n while (this.virtualBuffer.position < this._length) {\n await this.virtualBuffer.readChunk(\n Math.min(this._length - this.virtualBuffer.position, 1024 * 1024),\n 'draining'\n )\n }\n }\n }\n}\n"],"mappings":"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"}
\No newline at end of file