Read file data of root directory entries
This commit is contained in:
parent
442253b953
commit
a6503ae65b
@ -46,6 +46,8 @@ export interface IStandardDirEntry {
|
|||||||
attributes: IAttributes
|
attributes: IAttributes
|
||||||
size: number
|
size: number
|
||||||
firstCluster: number
|
firstCluster: number
|
||||||
|
clusterChain: number[]
|
||||||
|
data: ArrayBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILongFileNameDirEntry {
|
export interface ILongFileNameDirEntry {
|
||||||
@ -84,7 +86,45 @@ export class FloppyDisk {
|
|||||||
new DataView(this._buffer, this.rootDirOffset, this.rootDirSize),
|
new DataView(this._buffer, this.rootDirOffset, this.rootDirSize),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._rootDirEntries === null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of this._rootDirEntries) {
|
||||||
|
if (entry.type === 'standard-entry' && (entry.size > 0 || entry.attributes.directory)) {
|
||||||
|
entry.clusterChain = this.clusterChain(entry.firstCluster)
|
||||||
|
|
||||||
|
const dataSize = entry.clusterChain.length * this.bytesPerCluster
|
||||||
|
if (dataSize === 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = new Uint8Array(dataSize)
|
||||||
|
for (let i = 0; i < entry.clusterChain.length; i++) {
|
||||||
|
const offset = (entry.clusterChain[i] - 2) * this.bytesPerCluster
|
||||||
|
const view = new Uint8Array(
|
||||||
|
this._buffer,
|
||||||
|
this.dataOffset + offset,
|
||||||
|
this.bytesPerCluster,
|
||||||
|
)
|
||||||
|
data.set(view, i * this.bytesPerCluster)
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
entry.name.trim() + (entry.extension.trim() ? '.' + entry.extension.trim() : ''),
|
||||||
|
)
|
||||||
|
entry.data = data.slice(0, entry.size > 0 ? entry.size : data.byteLength)
|
||||||
|
if (
|
||||||
|
!entry.attributes.directory &&
|
||||||
|
(['BAT', 'TXT', 'BAS'].includes(entry.extension) || entry.name.trim() === 'LICENSE')
|
||||||
|
) {
|
||||||
|
const decoder = new TextDecoder()
|
||||||
|
console.log(decoder.decode(entry.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._rootDirEntries
|
return this._rootDirEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +156,14 @@ export class FloppyDisk {
|
|||||||
return this.bootSectorInfo?.biosParameterBlock?.bytesPerSector ?? 0
|
return this.bootSectorInfo?.biosParameterBlock?.bytesPerSector ?? 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get sectorsPerCluster() {
|
||||||
|
return this.bootSectorInfo?.biosParameterBlock?.sectorsPerCluster ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
get bytesPerCluster() {
|
||||||
|
return this.bytesPerSector * this.sectorsPerCluster
|
||||||
|
}
|
||||||
|
|
||||||
get rootDirSectors() {
|
get rootDirSectors() {
|
||||||
if (this.bytesPerSector === 0) {
|
if (this.bytesPerSector === 0) {
|
||||||
return 0
|
return 0
|
||||||
@ -143,6 +191,34 @@ export class FloppyDisk {
|
|||||||
get rootDirSize() {
|
get rootDirSize() {
|
||||||
return this.rootDirSectors * this.bytesPerSector
|
return this.rootDirSectors * this.bytesPerSector
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextCluster(current: number): number {
|
||||||
|
const tableOffset = Math.floor(current + current / 2)
|
||||||
|
const tableSector = Math.floor(this.reservedSectorCount + tableOffset / this.bytesPerSector)
|
||||||
|
const entityOffset = tableOffset % this.bytesPerSector
|
||||||
|
|
||||||
|
const table = new DataView(
|
||||||
|
this._buffer,
|
||||||
|
tableSector * this.bytesPerSector,
|
||||||
|
2 * this.bytesPerSector,
|
||||||
|
)
|
||||||
|
|
||||||
|
const value = table.getUint16(entityOffset, true)
|
||||||
|
|
||||||
|
return current & 1 ? value >> 4 : value & 0x0fff
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterChain(start: number): number[] {
|
||||||
|
const chain = [start]
|
||||||
|
|
||||||
|
let next = this.nextCluster(start)
|
||||||
|
while (next > 1 && next < 0xff7) {
|
||||||
|
chain.push(next)
|
||||||
|
next = this.nextCluster(next)
|
||||||
|
}
|
||||||
|
|
||||||
|
return chain
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function decodeBootSector(data: DataView): IBootSectorInfo | null {
|
function decodeBootSector(data: DataView): IBootSectorInfo | null {
|
||||||
@ -262,6 +338,8 @@ function decodeDirectoryEntry(data: DataView): DirEntry | null {
|
|||||||
extension,
|
extension,
|
||||||
attributes,
|
attributes,
|
||||||
firstCluster,
|
firstCluster,
|
||||||
|
clusterChain: [],
|
||||||
|
data: new ArrayBuffer(0),
|
||||||
size,
|
size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user