diff --git a/diskpart/lib/diskpart.lua b/diskpart/lib/diskpart.lua index 7fe3d9d..29f1aff 100644 --- a/diskpart/lib/diskpart.lua +++ b/diskpart/lib/diskpart.lua @@ -1,4 +1,24 @@ -local partition = {types={"mtpt","osdi","openupt"}} +local partition = {} + +local eformat = "c20c4>I4>I4" +function partition.parse(s) + local rt = {} + for i = 1, s:len(), 32 do + local n, t, start, length = string.unpack(eformat, s, i) + n = n:gsub("\0", "") + if n ~= "" then + rt[#rt+1] = {n,t,start,length} + end + end + return rt +end +function partition.generate(pt) + local ps = "" + for k,v in ipairs(pt) do + ps = ps .. string.pack(eformat, table.unpack(v)) + end + return ps +end local function getProxy(addr) if type(addr) == "string" then @@ -6,89 +26,37 @@ local function getProxy(addr) end return addr end -local function aop(td,n,mn,...) - local rts = td.seek(-math.huge) - td.seek(n) - local rv = {td[mn](...)} - td.seek(-math.huge) - td.seek(rts) - return table.unpack(rv) -end - -local function rf() - return false -end -local function getlib(f) - local drop = package.loaded["part/"..f] == nil - local w,r = pcall(require,"part/"..f) - if drop then package.loaded["part/"..f] = nil end - return w and r or {getPartitions=rf, setPartitions=rf} -end function partition.getPartitions(drive) drive = getProxy(drive) - for _, t in ipairs(partition.types) do - local pt = getlib(t).getPartitions(drive) - if pt then - return pt, t - end - end - return {}, partition.types[1] + local rv = partition.parse(drive.readSector(drive.getCapacity() / drive.getSectorSize())) + return rv[1][2] == "mtpt" and rv or {} end function partition.setPartitions(drive, pt, name) drive = getProxy(drive) - local _, ptt = partition.getPartitions(drive) - return getlib(ptt or partition.types[1]).setPartitions(drive, pt, name) + name = name or "" + if pt[1][2] ~= "mtpt" then table.insert(pt, 1, {name, "mtpt", 0, 0}) end + local ns = partition.generate(pt) + return drive.writeSector(drive.getCapacity() / drive.getSectorSize(), ns .. ("\0"):rep(drive.getSectorSize() - #ns)) end function partition.proxyPartition(drive, index) drive = getProxy(drive) local part = partition.getPartitions(drive)[index] local sectorOffset, byteOffset, finish = part[3] - 1, (part[3]-1) * drive.getSectorSize() - local proxy = {label=part[1],ptype=part[2],type="partition",address=string.format("%s/%i",drive.address,index)} + local proxy = {label=part[1],ptype=part[2]} + function proxy.getCapacity() + return drive.getSectorSize() * part[4] + end function proxy.getLabel() return part[1] end function proxy.setLabel() return false end - if drive.type == "tape_drive" then - local function checkBounds(n) - assert(n >= 0 and n <= len*bs, "invalid offset, not in a usable sector") - if n < 0 or n > len * bs then - error("invalid offset, not in a usable sector") - end - return (start * bs) + n - end - function proxy.readSector(n) - return aop(td, checkBounds((n-1) * bs), "read", bs) - end - function proxy.writeSector(n,d) - return aop(td, checkBounds((n-1) * bs), "write", d .. ("\0"):rep(512-#d)) - end - function proxy.readByte(n) - return aop(td, checkBounds(n-1), "read") - end - function proxy.writeByte(n,d) - return aop(td, checkBounds(n-1), "write",d) - end - - function proxy.getSectorSize() - return bs - end - function proxy.getCapacity() - return len * 512 - end - return proxy - end - - function proxy.getCapacity() - return drive.getSectorSize() * part[4] - end local function offsetSector(sector) - assert(sector > 0 and sector <= part[4], "invalid offset, not in a usable sector") if sector < 1 or sector > part[4] then error("invalid offset, not in a usable sector") end return sectorOffset + sector end diff --git a/diskpart/lib/part/mtpt.lua b/diskpart/lib/part/mtpt.lua deleted file mode 100644 index 41a9388..0000000 --- a/diskpart/lib/part/mtpt.lua +++ /dev/null @@ -1,56 +0,0 @@ -local mtpt = {} - -local eformat = "c20c4>I4>I4" - -local function aop(td,n,mn,...) - local rts = td.seek(-math.huge) - td.seek(n) - local rv = {td[mn](...)} - td.seek(-math.huge) - td.seek(rts) - return table.unpack(rv) -end - -function mtpt.parse(s) - local rt = {} - for i = 1, s:len(), 32 do - local n, t, start, length = string.unpack(eformat, s, i) - n = n:gsub("\0", "") - if n ~= "" then - rt[#rt+1] = {n,t,start,length} - end - end - return rt -end -function mtpt.generate(pt) - local ps = "" - for k,v in ipairs(pt) do - ps = ps .. string.pack(eformat, table.unpack(v)) - end - return ps -end - -function mtpt.getPartitions(drive) - local rv - if drive.type == "tape_drive" then - local ts = drive.getSize() - local lso = (math.floor(ts / 512) - 1) * 512 - rv = mtpt.parse(aop(drive, lso, "read", ts - lso)) - else - rv = mtpt.parse(drive.readSector(drive.getCapacity() / drive.getSectorSize())) - end - return rv[1][2] == "mtpt" and rv -end -function mtpt.setPartitions(drive, pt, name) - name = name or "" - if pt[1][2] ~= "mtpt" then table.insert(pt, 1, {name, "mtpt", 0, 0}) end - local ns = mtpt.generate(pt) - if drive.type == "tape_drive" then - local ts = drive.getSize() - local lso = (math.floor(ts / 512) - 1) * 512 - return aop(drive, lso, "write", ns .. ("\0"):rep(ts - lso - #ns)) - end - return drive.writeSector(drive.getCapacity() / drive.getSectorSize(), ns .. ("\0"):rep(drive.getSectorSize() - #ns)) -end - -return mtpt