mharj-diskinfo 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,17 +3,31 @@
3
3
  read disk partition and filesystem information with NodeJS
4
4
  Requires: NodeJS 10.4 as using Bigint
5
5
 
6
+ ### Installation
7
+
6
8
  ```bash
7
9
  npm install mharj-diskinfo --save
8
10
  ```
9
11
 
12
+ ### Magic usage
13
+
14
+ ```typescript
15
+ import {open} from 'node:fs/promises';
16
+ import {Magic} from 'mharj-diskinfo';
17
+ const handle = await open('\\\\.\\PHYSICALDRIVE0', 'rs+');
18
+ const magic = new Magic(handle);
19
+ console.log(magic.haveNtfs(0)); // true if NTFS magic found at offset 0
20
+ ```
21
+
22
+ ### Partition scan usage
23
+
10
24
  ```javascript
11
- const fs = require('fs');
25
+ const fsp = require('fs/promises');
12
26
  const scan = require('mharj-diskinfo').scan;
13
27
  const device = '\\\\.\\PHYSICALDRIVE0';
14
28
  //const device = '/dev/sda';
15
- const fd = fs.openSync(device, 'rs+');
16
- let data = await scan(fd);
29
+ const handle = await fsp.open(device, 'rs+');
30
+ let data = await scan(handle);
17
31
  console.log(data);
18
32
  ```
19
33
 
package/dist/index.cjs ADDED
@@ -0,0 +1,273 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+ //#endregion
24
+ let node_fs = require("node:fs");
25
+ node_fs = __toESM(node_fs);
26
+ //#region \0@oxc-project+runtime@0.129.0/helpers/checkPrivateRedeclaration.js
27
+ function _checkPrivateRedeclaration(e, t) {
28
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
29
+ }
30
+ //#endregion
31
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldInitSpec.js
32
+ function _classPrivateFieldInitSpec(e, t, a) {
33
+ _checkPrivateRedeclaration(e, t), t.set(e, a);
34
+ }
35
+ //#endregion
36
+ //#region \0@oxc-project+runtime@0.129.0/helpers/assertClassBrand.js
37
+ function _assertClassBrand(e, t, n) {
38
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
39
+ throw new TypeError("Private element is not present on this object");
40
+ }
41
+ //#endregion
42
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldSet2.js
43
+ function _classPrivateFieldSet2(s, a, r) {
44
+ return s.set(_assertClassBrand(s, a), r), r;
45
+ }
46
+ //#endregion
47
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldGet2.js
48
+ function _classPrivateFieldGet2(s, a) {
49
+ return s.get(_assertClassBrand(s, a));
50
+ }
51
+ //#endregion
52
+ //#region src/Magic.ts
53
+ var _handle = /* @__PURE__ */ new WeakMap();
54
+ /**
55
+ * Class to check for magic numbers of various filesystems at given offsets.
56
+ * @example
57
+ * const fh = await fsp.open(device, 'rs+');
58
+ * const magic = new Magic(fh);
59
+ * console.log(magic.haveExt(0)); // check for EXT at offset 0
60
+ */
61
+ var Magic = class {
62
+ constructor(fileHandle) {
63
+ _classPrivateFieldInitSpec(this, _handle, void 0);
64
+ _classPrivateFieldSet2(_handle, this, fileHandle);
65
+ }
66
+ haveExt(offset) {
67
+ const data = Buffer.allocUnsafe(2048);
68
+ node_fs.default.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
69
+ return data.readInt16BE(1080) === 21487;
70
+ }
71
+ haveNtfs(offset) {
72
+ const data = Buffer.allocUnsafe(512);
73
+ node_fs.default.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
74
+ return data.readInt32BE(3) === 1314145875;
75
+ }
76
+ haveLvm2(offset) {
77
+ const data = Buffer.allocUnsafe(1024);
78
+ node_fs.default.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
79
+ return data.readInt32BE(536) === 1280724274;
80
+ }
81
+ };
82
+ //#endregion
83
+ //#region src/gptPart.ts
84
+ const EFI_PART = Buffer.from([
85
+ 69,
86
+ 70,
87
+ 73,
88
+ 32,
89
+ 80,
90
+ 65,
91
+ 82,
92
+ 84
93
+ ]);
94
+ const gptPartTypes = Object.freeze({
95
+ EMPTY: "00000000-0000-0000-0000-000000000000",
96
+ MBR: "024dee41-33e7-11d3-9d69-0008c781f39f",
97
+ EFI: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
98
+ LINUX: "0fc63daf-8483-4772-8e79-3d69d8477de4",
99
+ LINUX_SWAP: "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f",
100
+ LINUX_LVM: "e6d6d379-f507-44c2-a23c-238f2a3df928",
101
+ LINUX_RAID: "a19d880f-05fc-4d3b-a006-743f0f84911e",
102
+ MSR: "e3c9e316-0b5c-4db8-817d-f92df00215ae",
103
+ BASIC_DATA: "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7",
104
+ getName: function(val) {
105
+ return Object.entries(this).reduce((acc, [k, v]) => {
106
+ if (typeof v === "string" && v === val) return k;
107
+ return acc;
108
+ }, "Unknown");
109
+ }
110
+ });
111
+ function readUuidBytes(buf, pos) {
112
+ return Buffer.from([
113
+ buf[pos + 3],
114
+ buf[pos + 2],
115
+ buf[pos + 1],
116
+ buf[pos + 0],
117
+ buf[pos + 5],
118
+ buf[pos + 4],
119
+ buf[pos + 7],
120
+ buf[pos + 6],
121
+ buf[pos + 8],
122
+ buf[pos + 9],
123
+ buf[pos + 10],
124
+ buf[pos + 11],
125
+ buf[pos + 12],
126
+ buf[pos + 13],
127
+ buf[pos + 14],
128
+ buf[pos + 15]
129
+ ]);
130
+ }
131
+ function readUuidAsString(buf, pos) {
132
+ const uuid = readUuidBytes(buf, pos).toString("hex");
133
+ return `${uuid.slice(0, 8)}-${uuid.slice(8, 12)}-${uuid.slice(12, 16)}-${uuid.slice(16, 20)}-${uuid.slice(20, 32)}`;
134
+ }
135
+ function parseGPTable(buf) {
136
+ const typeId = readUuidAsString(buf, 0);
137
+ const uuid = readUuidAsString(buf, 16);
138
+ const startLBA = buf.readBigUInt64LE(32);
139
+ const endLBA = buf.readBigUInt64LE(40);
140
+ return {
141
+ typeId,
142
+ type: gptPartTypes.getName(typeId),
143
+ uuid,
144
+ active: uuid !== gptPartTypes.EMPTY,
145
+ startLBA,
146
+ endLBA,
147
+ partitionSize: endLBA - startLBA + 1n,
148
+ attributes: buf.readBigUInt64BE(48),
149
+ label: buf.subarray(56, 128).toString("utf16le").split("\0", 1)[0]
150
+ };
151
+ }
152
+ function parseGPT(buf) {
153
+ if (buf.indexOf(EFI_PART) !== 0) throw Error("not GTP entry");
154
+ return {
155
+ revision: `${buf[8]}.${buf[9]}.${buf[10]}.${buf[11]}`,
156
+ headerSize: buf.readUInt32LE(12),
157
+ headerCRC32: buf.readUInt32LE(16),
158
+ currentLBA: buf.readBigUInt64LE(24),
159
+ backupLBA: buf.readBigUInt64LE(32),
160
+ firstUsableLBA: buf.readBigUInt64LE(40),
161
+ lastUsableLBA: buf.readBigUInt64LE(48),
162
+ uuid: readUuidAsString(buf, 56),
163
+ tableLBA: buf.readBigUInt64LE(72),
164
+ partitions: buf.readUInt32LE(80),
165
+ partitionSize: buf.readUInt32LE(84),
166
+ partitionCRC32: buf.readUInt32LE(88)
167
+ };
168
+ }
169
+ //#endregion
170
+ //#region src/mbrPart.ts
171
+ const partTypes = Object.freeze({
172
+ EMPTY: 0,
173
+ EXTENDED: 5,
174
+ NTFS: 7,
175
+ LINUX_SWAP: 130,
176
+ LINUX: 131,
177
+ LINUX_EXTENDED: 133,
178
+ LINUX_LVM: 142,
179
+ GPT: 238,
180
+ EFI: 239,
181
+ LINUX_RAID: 253,
182
+ getName: function(val) {
183
+ return Object.entries(this).reduce((acc, [k, v]) => {
184
+ if (typeof v === "number" && v === val) return k;
185
+ return acc;
186
+ }, "Unknown");
187
+ }
188
+ });
189
+ function parseMBR(mbr) {
190
+ if (mbr.length < 512 || mbr[510] !== 85 || mbr[511] !== 170) throw Error("no MBR signature or buffer is less than 512 bytes");
191
+ const ret = {
192
+ copyProtected: !!(mbr[444] === 90 && mbr[444] === 90),
193
+ uuid: Buffer.from([
194
+ mbr[443],
195
+ mbr[442],
196
+ mbr[441],
197
+ mbr[440]
198
+ ]).toString("hex"),
199
+ partitions: [],
200
+ type: "MBR"
201
+ };
202
+ for (let i = 446; i <= 508; i += 16) ret.partitions.push(parseMBRPartition(mbr.subarray(i, i + 16)));
203
+ return ret;
204
+ }
205
+ function parseMBRPartition(part) {
206
+ const startLBA = part.readUInt32LE(8);
207
+ const partitionSize = part.readUInt32LE(12);
208
+ return {
209
+ active: part.readUInt8(0) === 128,
210
+ type: part.readUInt8(4),
211
+ startLBA,
212
+ partitionSize,
213
+ endLBA: startLBA + partitionSize
214
+ };
215
+ }
216
+ function isMbrPartition(part) {
217
+ return typeof part.type === "number";
218
+ }
219
+ //#endregion
220
+ //#region src/scan.ts
221
+ async function getMbrPartitions(handle, startLBA) {
222
+ const buffer = Buffer.allocUnsafe(512);
223
+ await handle.read(buffer, 0, 512, 512);
224
+ const output = [];
225
+ const extparts = parseMBR(buffer);
226
+ for (const extpart of extparts.partitions) {
227
+ if (!isMbrPartition(extpart)) throw TypeError("we did get GPT partition as extended");
228
+ if (extpart.type !== partTypes.EMPTY) {
229
+ extpart.startLBA = extpart.startLBA + startLBA;
230
+ output.push(extpart);
231
+ }
232
+ }
233
+ return output;
234
+ }
235
+ async function getGptPartitions(handle) {
236
+ const buffer = Buffer.allocUnsafe(512);
237
+ await handle.read(buffer, 0, 512, 512);
238
+ const gpt = parseGPT(buffer);
239
+ const gBuff = Buffer.allocUnsafe(gpt.partitions * gpt.partitionSize);
240
+ const partitions = [];
241
+ for (let i = 0; i < gpt.partitions * gpt.partitionSize; i += gpt.partitionSize) {
242
+ const table = parseGPTable(gBuff.subarray(i, i + gpt.partitionSize));
243
+ if (table.typeId !== gptPartTypes.EMPTY) partitions.push(table);
244
+ }
245
+ return {
246
+ uuid: gpt.uuid,
247
+ partitions
248
+ };
249
+ }
250
+ function isGptPartition(root, part) {
251
+ return part.type === partTypes.GPT;
252
+ }
253
+ function isExtendedPartition(part) {
254
+ return part.type === partTypes.EXTENDED;
255
+ }
256
+ async function scan(handle) {
257
+ const buffer = Buffer.allocUnsafe(512);
258
+ await handle.read(buffer, 0, 512, 0);
259
+ const rootMbr = parseMBR(buffer);
260
+ for (const p of rootMbr.partitions) {
261
+ if (isExtendedPartition(p)) rootMbr.partitions.push(...await getMbrPartitions(handle, p.startLBA));
262
+ if (isGptPartition(rootMbr, p)) {
263
+ const { partitions, uuid } = await getGptPartitions(handle);
264
+ rootMbr.type = "GPT";
265
+ rootMbr.partitions = partitions;
266
+ rootMbr.uuid = uuid;
267
+ }
268
+ }
269
+ return rootMbr;
270
+ }
271
+ //#endregion
272
+ exports.Magic = Magic;
273
+ exports.scan = scan;
@@ -0,0 +1,57 @@
1
+ import { FileHandle } from "node:fs/promises";
2
+
3
+ //#region src/Magic.d.ts
4
+ /**
5
+ * Class to check for magic numbers of various filesystems at given offsets.
6
+ * @example
7
+ * const fh = await fsp.open(device, 'rs+');
8
+ * const magic = new Magic(fh);
9
+ * console.log(magic.haveExt(0)); // check for EXT at offset 0
10
+ */
11
+ declare class Magic {
12
+ #private;
13
+ constructor(fileHandle: FileHandle);
14
+ haveExt(offset: number): boolean;
15
+ haveNtfs(offset: number): boolean;
16
+ haveLvm2(offset: number): boolean;
17
+ }
18
+ //#endregion
19
+ //#region src/types.d.ts
20
+ type MBRPartition = {
21
+ active: boolean;
22
+ type: number;
23
+ startLBA: number;
24
+ partitionSize: number;
25
+ endLBA: number;
26
+ };
27
+ type GPTPartition = {
28
+ typeId: string;
29
+ type: string;
30
+ uuid: string;
31
+ active: boolean;
32
+ startLBA: bigint;
33
+ endLBA: bigint;
34
+ partitionSize: bigint;
35
+ attributes: bigint;
36
+ label: string;
37
+ };
38
+ //#endregion
39
+ //#region src/mbrPart.d.ts
40
+ type GptData = {
41
+ copyProtected: boolean;
42
+ uuid: string;
43
+ type: "GPT";
44
+ partitions: GPTPartition[];
45
+ };
46
+ type MbrData = {
47
+ copyProtected: boolean;
48
+ uuid: string;
49
+ type: "MBR";
50
+ partitions: MBRPartition[];
51
+ };
52
+ type IMbrData = MbrData | GptData;
53
+ //#endregion
54
+ //#region src/scan.d.ts
55
+ declare function scan(handle: FileHandle): Promise<IMbrData>;
56
+ //#endregion
57
+ export { Magic, scan };
@@ -0,0 +1,57 @@
1
+ import { FileHandle } from "node:fs/promises";
2
+
3
+ //#region src/Magic.d.ts
4
+ /**
5
+ * Class to check for magic numbers of various filesystems at given offsets.
6
+ * @example
7
+ * const fh = await fsp.open(device, 'rs+');
8
+ * const magic = new Magic(fh);
9
+ * console.log(magic.haveExt(0)); // check for EXT at offset 0
10
+ */
11
+ declare class Magic {
12
+ #private;
13
+ constructor(fileHandle: FileHandle);
14
+ haveExt(offset: number): boolean;
15
+ haveNtfs(offset: number): boolean;
16
+ haveLvm2(offset: number): boolean;
17
+ }
18
+ //#endregion
19
+ //#region src/types.d.ts
20
+ type MBRPartition = {
21
+ active: boolean;
22
+ type: number;
23
+ startLBA: number;
24
+ partitionSize: number;
25
+ endLBA: number;
26
+ };
27
+ type GPTPartition = {
28
+ typeId: string;
29
+ type: string;
30
+ uuid: string;
31
+ active: boolean;
32
+ startLBA: bigint;
33
+ endLBA: bigint;
34
+ partitionSize: bigint;
35
+ attributes: bigint;
36
+ label: string;
37
+ };
38
+ //#endregion
39
+ //#region src/mbrPart.d.ts
40
+ type GptData = {
41
+ copyProtected: boolean;
42
+ uuid: string;
43
+ type: "GPT";
44
+ partitions: GPTPartition[];
45
+ };
46
+ type MbrData = {
47
+ copyProtected: boolean;
48
+ uuid: string;
49
+ type: "MBR";
50
+ partitions: MBRPartition[];
51
+ };
52
+ type IMbrData = MbrData | GptData;
53
+ //#endregion
54
+ //#region src/scan.d.ts
55
+ declare function scan(handle: FileHandle): Promise<IMbrData>;
56
+ //#endregion
57
+ export { Magic, scan };
package/dist/index.mjs ADDED
@@ -0,0 +1,248 @@
1
+ import fs from "node:fs";
2
+ //#region \0@oxc-project+runtime@0.129.0/helpers/checkPrivateRedeclaration.js
3
+ function _checkPrivateRedeclaration(e, t) {
4
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
5
+ }
6
+ //#endregion
7
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldInitSpec.js
8
+ function _classPrivateFieldInitSpec(e, t, a) {
9
+ _checkPrivateRedeclaration(e, t), t.set(e, a);
10
+ }
11
+ //#endregion
12
+ //#region \0@oxc-project+runtime@0.129.0/helpers/assertClassBrand.js
13
+ function _assertClassBrand(e, t, n) {
14
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
15
+ throw new TypeError("Private element is not present on this object");
16
+ }
17
+ //#endregion
18
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldSet2.js
19
+ function _classPrivateFieldSet2(s, a, r) {
20
+ return s.set(_assertClassBrand(s, a), r), r;
21
+ }
22
+ //#endregion
23
+ //#region \0@oxc-project+runtime@0.129.0/helpers/classPrivateFieldGet2.js
24
+ function _classPrivateFieldGet2(s, a) {
25
+ return s.get(_assertClassBrand(s, a));
26
+ }
27
+ //#endregion
28
+ //#region src/Magic.ts
29
+ var _handle = /* @__PURE__ */ new WeakMap();
30
+ /**
31
+ * Class to check for magic numbers of various filesystems at given offsets.
32
+ * @example
33
+ * const fh = await fsp.open(device, 'rs+');
34
+ * const magic = new Magic(fh);
35
+ * console.log(magic.haveExt(0)); // check for EXT at offset 0
36
+ */
37
+ var Magic = class {
38
+ constructor(fileHandle) {
39
+ _classPrivateFieldInitSpec(this, _handle, void 0);
40
+ _classPrivateFieldSet2(_handle, this, fileHandle);
41
+ }
42
+ haveExt(offset) {
43
+ const data = Buffer.allocUnsafe(2048);
44
+ fs.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
45
+ return data.readInt16BE(1080) === 21487;
46
+ }
47
+ haveNtfs(offset) {
48
+ const data = Buffer.allocUnsafe(512);
49
+ fs.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
50
+ return data.readInt32BE(3) === 1314145875;
51
+ }
52
+ haveLvm2(offset) {
53
+ const data = Buffer.allocUnsafe(1024);
54
+ fs.readSync(_classPrivateFieldGet2(_handle, this).fd, data, 0, data.length, 512 * offset);
55
+ return data.readInt32BE(536) === 1280724274;
56
+ }
57
+ };
58
+ //#endregion
59
+ //#region src/gptPart.ts
60
+ const EFI_PART = Buffer.from([
61
+ 69,
62
+ 70,
63
+ 73,
64
+ 32,
65
+ 80,
66
+ 65,
67
+ 82,
68
+ 84
69
+ ]);
70
+ const gptPartTypes = Object.freeze({
71
+ EMPTY: "00000000-0000-0000-0000-000000000000",
72
+ MBR: "024dee41-33e7-11d3-9d69-0008c781f39f",
73
+ EFI: "c12a7328-f81f-11d2-ba4b-00a0c93ec93b",
74
+ LINUX: "0fc63daf-8483-4772-8e79-3d69d8477de4",
75
+ LINUX_SWAP: "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f",
76
+ LINUX_LVM: "e6d6d379-f507-44c2-a23c-238f2a3df928",
77
+ LINUX_RAID: "a19d880f-05fc-4d3b-a006-743f0f84911e",
78
+ MSR: "e3c9e316-0b5c-4db8-817d-f92df00215ae",
79
+ BASIC_DATA: "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7",
80
+ getName: function(val) {
81
+ return Object.entries(this).reduce((acc, [k, v]) => {
82
+ if (typeof v === "string" && v === val) return k;
83
+ return acc;
84
+ }, "Unknown");
85
+ }
86
+ });
87
+ function readUuidBytes(buf, pos) {
88
+ return Buffer.from([
89
+ buf[pos + 3],
90
+ buf[pos + 2],
91
+ buf[pos + 1],
92
+ buf[pos + 0],
93
+ buf[pos + 5],
94
+ buf[pos + 4],
95
+ buf[pos + 7],
96
+ buf[pos + 6],
97
+ buf[pos + 8],
98
+ buf[pos + 9],
99
+ buf[pos + 10],
100
+ buf[pos + 11],
101
+ buf[pos + 12],
102
+ buf[pos + 13],
103
+ buf[pos + 14],
104
+ buf[pos + 15]
105
+ ]);
106
+ }
107
+ function readUuidAsString(buf, pos) {
108
+ const uuid = readUuidBytes(buf, pos).toString("hex");
109
+ return `${uuid.slice(0, 8)}-${uuid.slice(8, 12)}-${uuid.slice(12, 16)}-${uuid.slice(16, 20)}-${uuid.slice(20, 32)}`;
110
+ }
111
+ function parseGPTable(buf) {
112
+ const typeId = readUuidAsString(buf, 0);
113
+ const uuid = readUuidAsString(buf, 16);
114
+ const startLBA = buf.readBigUInt64LE(32);
115
+ const endLBA = buf.readBigUInt64LE(40);
116
+ return {
117
+ typeId,
118
+ type: gptPartTypes.getName(typeId),
119
+ uuid,
120
+ active: uuid !== gptPartTypes.EMPTY,
121
+ startLBA,
122
+ endLBA,
123
+ partitionSize: endLBA - startLBA + 1n,
124
+ attributes: buf.readBigUInt64BE(48),
125
+ label: buf.subarray(56, 128).toString("utf16le").split("\0", 1)[0]
126
+ };
127
+ }
128
+ function parseGPT(buf) {
129
+ if (buf.indexOf(EFI_PART) !== 0) throw Error("not GTP entry");
130
+ return {
131
+ revision: `${buf[8]}.${buf[9]}.${buf[10]}.${buf[11]}`,
132
+ headerSize: buf.readUInt32LE(12),
133
+ headerCRC32: buf.readUInt32LE(16),
134
+ currentLBA: buf.readBigUInt64LE(24),
135
+ backupLBA: buf.readBigUInt64LE(32),
136
+ firstUsableLBA: buf.readBigUInt64LE(40),
137
+ lastUsableLBA: buf.readBigUInt64LE(48),
138
+ uuid: readUuidAsString(buf, 56),
139
+ tableLBA: buf.readBigUInt64LE(72),
140
+ partitions: buf.readUInt32LE(80),
141
+ partitionSize: buf.readUInt32LE(84),
142
+ partitionCRC32: buf.readUInt32LE(88)
143
+ };
144
+ }
145
+ //#endregion
146
+ //#region src/mbrPart.ts
147
+ const partTypes = Object.freeze({
148
+ EMPTY: 0,
149
+ EXTENDED: 5,
150
+ NTFS: 7,
151
+ LINUX_SWAP: 130,
152
+ LINUX: 131,
153
+ LINUX_EXTENDED: 133,
154
+ LINUX_LVM: 142,
155
+ GPT: 238,
156
+ EFI: 239,
157
+ LINUX_RAID: 253,
158
+ getName: function(val) {
159
+ return Object.entries(this).reduce((acc, [k, v]) => {
160
+ if (typeof v === "number" && v === val) return k;
161
+ return acc;
162
+ }, "Unknown");
163
+ }
164
+ });
165
+ function parseMBR(mbr) {
166
+ if (mbr.length < 512 || mbr[510] !== 85 || mbr[511] !== 170) throw Error("no MBR signature or buffer is less than 512 bytes");
167
+ const ret = {
168
+ copyProtected: !!(mbr[444] === 90 && mbr[444] === 90),
169
+ uuid: Buffer.from([
170
+ mbr[443],
171
+ mbr[442],
172
+ mbr[441],
173
+ mbr[440]
174
+ ]).toString("hex"),
175
+ partitions: [],
176
+ type: "MBR"
177
+ };
178
+ for (let i = 446; i <= 508; i += 16) ret.partitions.push(parseMBRPartition(mbr.subarray(i, i + 16)));
179
+ return ret;
180
+ }
181
+ function parseMBRPartition(part) {
182
+ const startLBA = part.readUInt32LE(8);
183
+ const partitionSize = part.readUInt32LE(12);
184
+ return {
185
+ active: part.readUInt8(0) === 128,
186
+ type: part.readUInt8(4),
187
+ startLBA,
188
+ partitionSize,
189
+ endLBA: startLBA + partitionSize
190
+ };
191
+ }
192
+ function isMbrPartition(part) {
193
+ return typeof part.type === "number";
194
+ }
195
+ //#endregion
196
+ //#region src/scan.ts
197
+ async function getMbrPartitions(handle, startLBA) {
198
+ const buffer = Buffer.allocUnsafe(512);
199
+ await handle.read(buffer, 0, 512, 512);
200
+ const output = [];
201
+ const extparts = parseMBR(buffer);
202
+ for (const extpart of extparts.partitions) {
203
+ if (!isMbrPartition(extpart)) throw TypeError("we did get GPT partition as extended");
204
+ if (extpart.type !== partTypes.EMPTY) {
205
+ extpart.startLBA = extpart.startLBA + startLBA;
206
+ output.push(extpart);
207
+ }
208
+ }
209
+ return output;
210
+ }
211
+ async function getGptPartitions(handle) {
212
+ const buffer = Buffer.allocUnsafe(512);
213
+ await handle.read(buffer, 0, 512, 512);
214
+ const gpt = parseGPT(buffer);
215
+ const gBuff = Buffer.allocUnsafe(gpt.partitions * gpt.partitionSize);
216
+ const partitions = [];
217
+ for (let i = 0; i < gpt.partitions * gpt.partitionSize; i += gpt.partitionSize) {
218
+ const table = parseGPTable(gBuff.subarray(i, i + gpt.partitionSize));
219
+ if (table.typeId !== gptPartTypes.EMPTY) partitions.push(table);
220
+ }
221
+ return {
222
+ uuid: gpt.uuid,
223
+ partitions
224
+ };
225
+ }
226
+ function isGptPartition(root, part) {
227
+ return part.type === partTypes.GPT;
228
+ }
229
+ function isExtendedPartition(part) {
230
+ return part.type === partTypes.EXTENDED;
231
+ }
232
+ async function scan(handle) {
233
+ const buffer = Buffer.allocUnsafe(512);
234
+ await handle.read(buffer, 0, 512, 0);
235
+ const rootMbr = parseMBR(buffer);
236
+ for (const p of rootMbr.partitions) {
237
+ if (isExtendedPartition(p)) rootMbr.partitions.push(...await getMbrPartitions(handle, p.startLBA));
238
+ if (isGptPartition(rootMbr, p)) {
239
+ const { partitions, uuid } = await getGptPartitions(handle);
240
+ rootMbr.type = "GPT";
241
+ rootMbr.partitions = partitions;
242
+ rootMbr.uuid = uuid;
243
+ }
244
+ }
245
+ return rootMbr;
246
+ }
247
+ //#endregion
248
+ export { Magic, scan };
package/package.json CHANGED
@@ -1,62 +1,58 @@
1
1
  {
2
- "name": "mharj-diskinfo",
3
- "version": "0.1.0",
4
- "description": "",
5
- "main": "./dist/index.js",
6
- "scripts": {
7
- "build": "tsc",
8
- "prepublishOnly": "npm run build",
9
- "test": "mocha"
10
- },
11
- "mocha": {
12
- "exit": true,
13
- "extension": [
14
- "ts",
15
- "js"
16
- ],
17
- "recursive": true,
18
- "require": [
19
- "ts-node/register",
20
- "source-map-support/register"
21
- ],
22
- "reporters": [
23
- "spec",
24
- "mocha-junit-reporter"
25
- ]
26
- },
27
- "repository": {
28
- "type": "git",
29
- "url": "git+https://github.com/mharj/diskinfo.git"
30
- },
31
- "files": [
32
- "dist"
33
- ],
34
- "engines": {
35
- "node": ">=10.4.0"
36
- },
37
- "author": "mharj",
38
- "license": "LGPL",
39
- "bugs": {
40
- "url": "https://github.com/mharj/diskinfo/issues"
41
- },
42
- "homepage": "https://github.com/mharj/diskinfo#readme",
43
- "devDependencies": {
44
- "@types/buffer-crc32": "^0.2.0",
45
- "@types/chai": "^4.2.21",
46
- "@types/mocha": "^9.0.0",
47
- "@types/node": "^16.7.1",
48
- "@types/uuid-parse": "^1.0.0",
49
- "buffer-crc32": "^0.2.13",
50
- "chai": "^4.0.2",
51
- "eslint": "^7.32.0",
52
- "eslint-config-google": "^0.14.0",
53
- "mocha": "^9.1.0",
54
- "source-map-support": "^0.5.19",
55
- "ts-node": "^10.2.1",
56
- "typescript": "^4.3.5"
57
- },
58
- "dependencies": {
59
- "iconv-lite": "^0.6.3",
60
- "uuid-parse": "^1.0.0"
61
- }
2
+ "name": "mharj-diskinfo",
3
+ "version": "0.2.1",
4
+ "description": "Node.js library to parse MBR and GPT partition information from disk images or devices.",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.mts",
8
+ "exports": {
9
+ "import": {
10
+ "types": "./dist/index.d.mts",
11
+ "default": "./dist/index.mjs"
12
+ },
13
+ "require": {
14
+ "types": "./dist/index.d.cts",
15
+ "default": "./dist/index.cjs"
16
+ },
17
+ "default": "./dist/index.mjs"
18
+ },
19
+ "scripts": {
20
+ "prepare": "lefthook install",
21
+ "build": "tsdown src/index.ts --format cjs,esm --dts --clean -c tsconfig.build.json",
22
+ "prepublishOnly": "npm run build",
23
+ "test": "vitest test --typecheck --run --no-isolate --coverage",
24
+ "coverage": "vitest test --run --no-isolate --reporter=dot --coverage --coverage.reporter=lcov",
25
+ "lint": "biome check",
26
+ "validate": "tsgo --noEmit"
27
+ },
28
+ "repository": "github:mharj/diskinfo",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "engines": {
33
+ "node": ">=10.4.0"
34
+ },
35
+ "author": "mharj",
36
+ "license": "LGPL",
37
+ "bugs": {
38
+ "url": "https://github.com/mharj/diskinfo/issues"
39
+ },
40
+ "homepage": "https://github.com/mharj/diskinfo#readme",
41
+ "devDependencies": {
42
+ "@biomejs/biome": "^2.4.15",
43
+ "@tsconfig/node16": "^16.1.8",
44
+ "@types/buffer-crc32": "^0.2.0",
45
+ "@types/node": "^22.19.1",
46
+ "@typescript/native-preview": "7.0.0-dev.20260421.2",
47
+ "@vitest/coverage-v8": "^4.1.6",
48
+ "buffer-crc32": "^0.2.13",
49
+ "c8": "^11.0.0",
50
+ "lefthook": "^2.1.6",
51
+ "tsdown": "^0.22.0",
52
+ "tslib": "^2.8.1",
53
+ "typescript": "^6.0.3",
54
+ "vite": "^8.0.12",
55
+ "vitest": "^4.1.6"
56
+ },
57
+ "packageManager": "pnpm@10.33.4+sha512.1c67b3b359b2d408119ba1ed289f34b8fc3c6873412bec6fd264fbdc82489e510fcbecb9ce9d22dae7f3b76269d8441046014bdca53b9979cd7a561ad631b800"
62
58
  }
package/dist/gptPart.d.ts DELETED
@@ -1,31 +0,0 @@
1
- /// <reference types="node" />
2
- import { GPTPartition, MBRPartition } from './types';
3
- export declare const gptPartTypes: Readonly<{
4
- EMPTY: string;
5
- MBR: string;
6
- EFI: string;
7
- LINUX: string;
8
- LINUX_SWAP: string;
9
- LINUX_LVM: string;
10
- LINUX_RAID: string;
11
- MSR: string;
12
- BASIC_DATA: string;
13
- getName: (val: string) => string;
14
- }>;
15
- export interface IGtpData {
16
- revision: string;
17
- headerSize: number;
18
- headerCRC32: number;
19
- currentLBA: bigint;
20
- backupLBA: bigint;
21
- firstUsableLBA: bigint;
22
- lastUsableLBA: bigint;
23
- uuid: string;
24
- tableLBA: bigint;
25
- partitions: number;
26
- partitionSize: number;
27
- partitionCRC32: number;
28
- }
29
- export declare function parseGPTable(buf: Buffer): GPTPartition;
30
- export declare function parseGPT(buf: Buffer): IGtpData;
31
- export declare function isGptPartition(part: MBRPartition | GPTPartition): part is GPTPartition;
package/dist/gptPart.js DELETED
@@ -1,91 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isGptPartition = exports.parseGPT = exports.parseGPTable = exports.gptPartTypes = void 0;
4
- const uuidParse = require("uuid-parse");
5
- const iconv = require("iconv-lite");
6
- const EFI_PART = Buffer.from([0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54]);
7
- exports.gptPartTypes = Object.freeze({
8
- EMPTY: '00000000-0000-0000-0000-000000000000',
9
- MBR: '024dee41-33e7-11d3-9d69-0008c781f39f',
10
- EFI: 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b',
11
- LINUX: '0fc63daf-8483-4772-8e79-3d69d8477de4',
12
- LINUX_SWAP: '0657fd6d-a4ab-43c4-84e5-0933c84b4f4f',
13
- LINUX_LVM: 'e6d6d379-f507-44c2-a23c-238f2a3df928',
14
- LINUX_RAID: 'a19d880f-05fc-4d3b-a006-743f0f84911e',
15
- MSR: 'e3c9e316-0b5c-4db8-817d-f92df00215ae',
16
- BASIC_DATA: 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7',
17
- getName: function (val) {
18
- // print names for values
19
- for (let k in exports.gptPartTypes) {
20
- if (exports.gptPartTypes[k] === val) {
21
- return k;
22
- }
23
- }
24
- return 'Unknown';
25
- },
26
- });
27
- function readUuidBytes(buf, pos) {
28
- return Buffer.from([
29
- buf[pos + 3],
30
- buf[pos + 2],
31
- buf[pos + 1],
32
- buf[pos + 0],
33
- buf[pos + 5],
34
- buf[pos + 4],
35
- buf[pos + 7],
36
- buf[pos + 6],
37
- buf[pos + 8],
38
- buf[pos + 9],
39
- buf[pos + 10],
40
- buf[pos + 11],
41
- buf[pos + 12],
42
- buf[pos + 13],
43
- buf[pos + 14],
44
- buf[pos + 15],
45
- ]);
46
- }
47
- function parseGPTable(buf) {
48
- const typeId = uuidParse.unparse(readUuidBytes(buf, 0));
49
- const uuid = uuidParse.unparse(readUuidBytes(buf, 16));
50
- const startLBA = buf.readBigUInt64LE(32);
51
- const endLBA = buf.readBigUInt64LE(40);
52
- return {
53
- typeId,
54
- type: exports.gptPartTypes.getName(typeId),
55
- uuid,
56
- active: uuid == exports.gptPartTypes.EMPTY ? false : true,
57
- startLBA,
58
- endLBA,
59
- partitionSize: endLBA - startLBA + 1n,
60
- attributes: buf.readBigUInt64BE(48),
61
- label: iconv.decode(buf.slice(56, 128), 'utf16le').split('\u0000')[0], // bit hack in here
62
- };
63
- }
64
- exports.parseGPTable = parseGPTable;
65
- function parseGPT(buf) {
66
- // https://en.wikipedia.org/wiki/GUID_Partition_Table
67
- if (buf.indexOf(EFI_PART) != 0) {
68
- throw Error('not GTP entry');
69
- }
70
- return {
71
- revision: buf[8] + '.' + buf[9] + '.' + buf[10] + '.' + buf[11],
72
- headerSize: buf.readUInt32LE(12),
73
- headerCRC32: buf.readUInt32LE(16),
74
- // buf.readUInt32LE(20); // reserved; must be zero
75
- currentLBA: buf.readBigUInt64LE(24),
76
- backupLBA: buf.readBigUInt64LE(32),
77
- firstUsableLBA: buf.readBigUInt64LE(40),
78
- lastUsableLBA: buf.readBigUInt64LE(48),
79
- uuid: uuidParse.unparse(readUuidBytes(buf, 56)),
80
- tableLBA: buf.readBigUInt64LE(72),
81
- partitions: buf.readUInt32LE(80),
82
- partitionSize: buf.readUInt32LE(84),
83
- partitionCRC32: buf.readUInt32LE(88),
84
- };
85
- }
86
- exports.parseGPT = parseGPT;
87
- function isGptPartition(part) {
88
- return typeof part.type === 'string';
89
- }
90
- exports.isGptPartition = isGptPartition;
91
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3B0UGFydC5qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbImdwdFBhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsd0NBQXdDO0FBQ3hDLG9DQUFvQztBQUdwQyxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7QUFFbEUsUUFBQSxZQUFZLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN6QyxLQUFLLEVBQUUsc0NBQXNDO0lBQzdDLEdBQUcsRUFBRSxzQ0FBc0M7SUFDM0MsR0FBRyxFQUFFLHNDQUFzQztJQUMzQyxLQUFLLEVBQUUsc0NBQXNDO0lBQzdDLFVBQVUsRUFBRSxzQ0FBc0M7SUFDbEQsU0FBUyxFQUFFLHNDQUFzQztJQUNqRCxVQUFVLEVBQUUsc0NBQXNDO0lBQ2xELEdBQUcsRUFBRSxzQ0FBc0M7SUFDM0MsVUFBVSxFQUFFLHNDQUFzQztJQUNsRCxPQUFPLEVBQUUsVUFBVSxHQUFXO1FBQzdCLHlCQUF5QjtRQUN6QixLQUFLLElBQUksQ0FBQyxJQUFJLG9CQUFZLEVBQUU7WUFDM0IsSUFBSSxvQkFBWSxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtnQkFDNUIsT0FBTyxDQUFDLENBQUM7YUFDVDtTQUNEO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbEIsQ0FBQztDQUNELENBQUMsQ0FBQztBQWlCSCxTQUFTLGFBQWEsQ0FBQyxHQUFXLEVBQUUsR0FBVztJQUM5QyxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUM7UUFDbEIsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDWixHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUNaLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osR0FBRyxD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QUFFLFNBQVMsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMvQyxRQUFRLEVBQUUsR0FBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDakMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQ2hDLGFBQWEsRUFBRSxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUNuQyxjQUFjLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7S0FDcEMsQ0FBQztBQUNILENBQUM7QUFwQkQsNEJBb0JDO0FBRUQsU0FBZ0IsY0FBYyxDQUFDLElBQWlDO0lBQy9ELE9BQU8sT0FBTyxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztBQUN0QyxDQUFDO0FBRkQsd0NBRUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyB1dWlkUGFyc2UgZnJvbSAndXVpZC1wYXJzZSc7XG5pbXBvcnQgKiBhcyBpY29udiBmcm9tICdpY29udi1saXRlJztcbmltcG9ydCB7R1BUUGFydGl0aW9uLCBNQlJQYXJ0aXRpb259IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBFRklfUEFSVCA9IEJ1ZmZlci5mcm9tKFsweDQ1LCAweDQ2LCAweDQ5LCAweDIwLCAweDUwLCAweDQxLCAweDUyLCAweDU0XSk7XG5cbmV4cG9ydCBjb25zdCBncHRQYXJ0VHlwZXMgPSBPYmplY3QuZnJlZXplKHtcblx0RU1QVFk6ICcwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDAnLFxuXHRNQlI6ICcwMjRkZWU0MS0zM2U3LTExZDMtOWQ2OS0wMDA4Yzc4MWYzOWYnLFxuXHRFRkk6ICdjMTJhNzMyOC1mODFmLTExZDItYmE0Yi0wMGEwYzkzZWM5M2InLFxuXHRMSU5VWDogJzBmYzYzZGFmLTg0ODMtNDc3Mi04ZTc5LTNkNjlkODQ3N2RlNCcsXG5cdExJTlVYX1NXQVA6ICcwNjU3ZmQ2ZC1hNGFiLTQzYzQtODRlNS0wOTMzYzg0YjRmNGYnLFxuXHRMSU5VWF9MVk06ICdlNmQ2ZDM3OS1mNTA3LTQ0YzItYTIzYy0yMzhmMmEzZGY5MjgnLFxuXHRMSU5VWF9SQUlEOiAnYTE5ZDg4MGYtMDVmYy00ZDNiLWEwMDYtNzQzZjBmODQ5MTFlJyxcblx0TVNSOiAnZTNjOWUzMTYtMGI1Yy00ZGI4LTgxN2QtZjkyZGYwMDIxNWFlJyxcblx0QkFTSUNfREFUQTogJ2ViZDBhMGEyLWI5ZTUtNDQzMy04N2MwLTY4YjZiNzI2OTljNycsXG5cdGdldE5hbWU6IGZ1bmN0aW9uICh2YWw6IHN0cmluZyk6IHN0cmluZyB7XG5cdFx0Ly8gcHJpbnQgbmFtZXMgZm9yIHZhbHVlc1xuXHRcdGZvciAobGV0IGsgaW4gZ3B0UGFydFR5cGVzKSB7XG5cdFx0XHRpZiAoZ3B0UGFydFR5cGVzW2tdID09PSB2YWwpIHtcblx0XHRcdFx0cmV0dXJuIGs7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAnVW5rbm93bic7XG5cdH0sXG59KTtcblxuZXhwb3J0IGludGVyZmFjZSBJR3RwRGF0YSB7XG5cdHJldmlzaW9uOiBzdHJpbmc7XG5cdGhlYWRlclNpemU6IG51bWJlcjtcblx0aGVhZGVyQ1JDMzI6IG51bWJlcjtcblx0Y3VycmVudExCQTogYmlnaW50O1xuXHRiYWNrdXBMQkE6IGJpZ2ludDtcblx0Zmlyc3RVc2FibGVMQkE6IGJpZ2ludDtcblx0bGFzdFVzYWJsZUxCQTogYmlnaW50O1xuXHR1dWlkOiBzdHJpbmc7XG5cdHRhYmxlTEJBOiBiaWdpbnQ7XG5cdHBhcnRpdGlvbnM6IG51bWJlcjtcblx0cGFydGl0aW9uU2l6ZTogbnVtYmVyO1xuXHRwYXJ0aXRpb25DUkMzMjogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiByZWFkVXVpZEJ5dGVzKGJ1ZjogQnVmZmVyLCBwb3M6IG51bWJlcikge1xuXHRyZXR1cm4gQnVmZmVyLmZyb20oW1xuXHRcdGJ1Zltwb3MgKyAzXSxcblx0XHRidWZbcG9zICsgMl0sXG5cdFx0YnVmW3BvcyArIDFdLFxuXHRcdGJ1Zltwb3MgKyAwXSxcblx0XHRidWZbcG9zICsgNV0sXG5cdFx0YnVmW3BvcyArIDRdLFxuXHRcdGJ1Zltwb3MgKyA3XSxcblx0XHRidWZbcG9zICsgNl0sXG5cdFx0YnVmW3BvcyArIDhdLFxuXHRcdGJ1Zltwb3MgKyA5XSxcblx0XHRidWZbcG9zICsgMTBdLFxuXHRcdGJ1Zltwb3MgKyAxMV0sXG5cdFx0YnVmW3BvcyArIDEyXSxcblx0XHRidWZbcG9zICsgMTNdLFxuXHRcdGJ1Zltwb3MgKyAxNF0sXG5cdFx0YnVmW3BvcyArIDE1XSxcblx0XSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUdQVGFibGUoYnVmOiBCdWZmZXIpOiBHUFRQYXJ0aXRpb24ge1xuXHRjb25zdCB0eXBlSWQgPSB1dWlkUGFyc2UudW5wYXJzZShyZWFkVXVpZEJ5dGVzKGJ1ZiwgMCkpO1xuXHRjb25zdCB1dWlkID0gdXVpZFBhcnNlLnVucGFyc2UocmVhZFV1aWRCeXRlcyhidWYsIDE2KSk7XG5cdGNvbnN0IHN0YXJ0TEJBID0gYnVmLnJlYWRCaWdVSW50NjRMRSgzMik7XG5cdGNvbnN0IGVuZExCQSA9IGJ1Zi5yZWFkQmlnVUludDY0TEUoNDApO1xuXHRyZXR1cm4ge1xuXHRcdHR5cGVJZCxcblx0XHR0eXBlOiBncHRQYXJ0VHlwZXMuZ2V0TmFtZSh0eXBlSWQpLFxuXHRcdHV1aWQsXG5cdFx0YWN0aXZlOiB1dWlkID09IGdwdFBhcnRUeXBlcy5FTVBUWSA/IGZhbHNlIDogdHJ1ZSxcblx0XHRzdGFydExCQSxcblx0XHRlbmRMQkEsXG5cdFx0cGFydGl0aW9uU2l6ZTogZW5kTEJBIC0gc3RhcnRMQkEgKyAxbiwgLy8gKzE/XG5cdFx0YXR0cmlidXRlczogYnVmLnJlYWRCaWdVSW50NjRCRSg0OCksXG5cdFx0bGFiZWw6IGljb252LmRlY29kZShidWYuc2xpY2UoNTYsIDEyOCksICd1dGYxNmxlJykuc3BsaXQoJ1xcdTAwMDAnKVswXSwgLy8gYml0IGhhY2sgaW4gaGVyZVxuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VHUFQoYnVmOiBCdWZmZXIpOiBJR3RwRGF0YSB7XG5cdC8vIGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0dVSURfUGFydGl0aW9uX1RhYmxlXG5cdGlmIChidWYuaW5kZXhPZihFRklfUEFSVCkgIT0gMCkge1xuXHRcdHRocm93IEVycm9yKCdub3QgR1RQIGVudHJ5Jyk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRyZXZpc2lvbjogYnVmWzhdICsgJy4nICsgYnVmWzldICsgJy4nICsgYnVmWzEwXSArICcuJyArIGJ1ZlsxMV0sXG5cdFx0aGVhZGVyU2l6ZTogYnVmLnJlYWRVSW50MzJMRSgxMiksXG5cdFx0aGVhZGVyQ1JDMzI6IGJ1Zi5yZWFkVUludDMyTEUoMTYpLFxuXHRcdC8vIGJ1Zi5yZWFkVUludDMyTEUoMjApOyAvLyByZXNlcnZlZDsgbXVzdCBiZSB6ZXJvXG5cdFx0Y3VycmVudExCQTogYnVmLnJlYWRCaWdVSW50NjRMRSgyNCksXG5cdFx0YmFja3VwTEJBOiBidWYucmVhZEJpZ1VJbnQ2NExFKDMyKSxcblx0XHRmaXJzdFVzYWJsZUxCQTogYnVmLnJlYWRCaWdVSW50NjRMRSg0MCksXG5cdFx0bGFzdFVzYWJsZUxCQTogYnVmLnJlYWRCaWdVSW50NjRMRSg0OCksXG5cdFx0dXVpZDogdXVpZFBhcnNlLnVucGFyc2UocmVhZFV1aWRCeXRlcyhidWYsIDU2KSksXG5cdFx0dGFibGVMQkE6IGJ1Zi5yZWFkQmlnVUludDY0TEUoNzIpLFxuXHRcdHBhcnRpdGlvbnM6IGJ1Zi5yZWFkVUludDMyTEUoODApLFxuXHRcdHBhcnRpdGlvblNpemU6IGJ1Zi5yZWFkVUludDMyTEUoODQpLFxuXHRcdHBhcnRpdGlvbkNSQzMyOiBidWYucmVhZFVJbnQzMkxFKDg4KSxcblx0fTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzR3B0UGFydGl0aW9uKHBhcnQ6IE1CUlBhcnRpdGlvbiB8IEdQVFBhcnRpdGlvbik6IHBhcnQgaXMgR1BUUGFydGl0aW9uIHtcblx0cmV0dXJuIHR5cGVvZiBwYXJ0LnR5cGUgPT09ICdzdHJpbmcnO1xufVxuIl19
package/dist/index.d.ts DELETED
@@ -1,9 +0,0 @@
1
- import { IMbrData } from './mbrPart';
2
- export declare function scan(fd: number): Promise<IMbrData>;
3
- export declare class Magic {
4
- private fd;
5
- constructor(fd: number);
6
- haveExt(offset: number): boolean;
7
- haveNtfs(offset: number): boolean;
8
- haveLvm2(offset: number): boolean;
9
- }
package/dist/index.js DELETED
@@ -1,69 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Magic = exports.scan = void 0;
4
- const fs = require("fs");
5
- const gptPart_1 = require("./gptPart");
6
- const mbrPart_1 = require("./mbrPart");
7
- const util_1 = require("./util");
8
- async function scan(fd) {
9
- const buffer = await util_1.readFile(fd, 0, 512, 0);
10
- let rootMbr = mbrPart_1.parseMBR(buffer);
11
- rootMbr.partitions.forEach(async function (p) {
12
- if (p.type == mbrPart_1.partTypes.EXTENDED) {
13
- // Extended partition reading
14
- if (!mbrPart_1.isMbrPartition(p)) {
15
- throw TypeError('we did get GPT partition as extended');
16
- }
17
- let extparts = mbrPart_1.parseMBR(await util_1.readFile(fd, 0, 512, 512));
18
- extparts.partitions.forEach(function (extpart) {
19
- if (!mbrPart_1.isMbrPartition(extpart)) {
20
- throw TypeError('we did get GPT partition as extended');
21
- }
22
- if (extpart.type != mbrPart_1.partTypes.EMPTY) {
23
- extpart.startLBA = extpart.startLBA + p.startLBA;
24
- rootMbr.partitions.push(extpart);
25
- }
26
- });
27
- }
28
- if (p.type == mbrPart_1.partTypes.GPT) {
29
- rootMbr.type = 'GPT';
30
- // GPT partition table reading
31
- let gpt = gptPart_1.parseGPT(await util_1.readFile(fd, 0, 512, 512));
32
- rootMbr.uuid = gpt.uuid;
33
- let gBuff = Buffer.allocUnsafe(gpt.partitions * gpt.partitionSize);
34
- fs.readSync(fd, gBuff, 0, gBuff.length, Number(gpt.tableLBA) * 512);
35
- let partitions = [];
36
- for (let i = 0; i < gpt.partitions * gpt.partitionSize; i += gpt.partitionSize) {
37
- let table = gptPart_1.parseGPTable(gBuff.slice(i, i + gpt.partitionSize));
38
- if (table.typeId != gptPart_1.gptPartTypes.EMPTY) {
39
- partitions.push(table);
40
- }
41
- }
42
- rootMbr.partitions = partitions;
43
- }
44
- });
45
- return rootMbr;
46
- }
47
- exports.scan = scan;
48
- class Magic {
49
- constructor(fd) {
50
- this.fd = fd;
51
- }
52
- haveExt(offset) {
53
- let data = Buffer.allocUnsafe(2048);
54
- fs.readSync(this.fd, data, 0, data.length, 512 * offset);
55
- return data.readInt16BE(1080) == 0x53ef;
56
- }
57
- haveNtfs(offset) {
58
- let data = Buffer.allocUnsafe(512);
59
- fs.readSync(this.fd, data, 0, data.length, 512 * offset);
60
- return data.readInt32BE(3) == 0x4e544653;
61
- }
62
- haveLvm2(offset) {
63
- let data = Buffer.allocUnsafe(1024);
64
- fs.readSync(this.fd, data, 0, data.length, 512 * offset);
65
- return data.readInt32BE(536) == 0x4c564d32;
66
- }
67
- }
68
- exports.Magic = Magic;
69
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5QkFBeUI7QUFDekIsdUNBQStEO0FBQy9ELHVDQUF3RTtBQUV4RSxpQ0FBZ0M7QUFFekIsS0FBSyxVQUFVLElBQUksQ0FBQyxFQUFVO0lBQ3BDLE1BQU0sTUFBTSxHQUFHLE1BQU0sZUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzdDLElBQUksT0FBTyxHQUFHLGtCQUFRLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsT0FBTyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxXQUFXLENBQUM7UUFDM0MsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLG1CQUFTLENBQUMsUUFBUSxFQUFFO1lBQ2pDLDZCQUE2QjtZQUM3QixJQUFJLENBQUMsd0JBQWMsQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDdkIsTUFBTSxTQUFTLENBQUMsc0NBQXNDLENBQUMsQ0FBQzthQUN4RDtZQUNELElBQUksUUFBUSxHQUFHLGtCQUFRLENBQUMsTUFBTSxlQUFRLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUN6RCxRQUFRLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLE9BQU87Z0JBQzVDLElBQUksQ0FBQyx3QkFBYyxDQUFDLE9BQU8sQ0FBQyxFQUFFO29CQUM3QixNQUFNLFNBQVMsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO2lCQUN4RDtnQkFDRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksbUJBQVMsQ0FBQyxLQUFLLEVBQUU7b0JBQ3BDLE9BQU8sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDO29CQUNqRCxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDakM7WUFDRixDQUFDLENBQUMsQ0FBQztTQUNIO1FBQ0QsSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLG1CQUFTLENBQUMsR0FBRyxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBQ3JCLDhCQUE4QjtZQUM5QixJQUFJLEdBQUcsR0FBRyxrQkFBUSxDQUFDLE1BQU0sZUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDcEQsT0FBTyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDO1lBQ3hCLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDbkUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDcEUsSUFBSSxVQUFVLEdBQW1CLEVBQUUsQ0FBQztZQUNwQyxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUMsSUFBSSxHQUFHLENBQUMsYUFBYSxFQUFFO2dCQUMvRSxJQUFJLEtBQUssR0FBRyxzQkFBWSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDaEUsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLHNCQUFZLENBQUMsS0FBSyxFQUFFO29CQUN2QyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUN2QjthQUNEO1lBQ0QsT0FBTyxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7U0FDaEM7SUFDRixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sT0FBTyxDQUFDO0FBQ2hCLENBQUM7QUF0Q0Qsb0JBc0NDO0FBRUQsTUFBYSxLQUFLO0lBRWpCLFlBQVksRUFBVTtRQUNyQixJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNkLENBQUM7SUFDTSxPQUFPLENBQUMsTUFBYztRQUM1QixJQUFJLElBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxHQUFHLE1BQU0sQ0FBQyxDQUFDO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUM7SUFDekMsQ0FBQztJQUNNLFFBQVEsQ0FBQyxNQUFjO1FBQzdCLElBQUksSUFBSSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsTUFBTSxDQUFDLENBQUM7UUFDekQsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsQ0FBQztJQUMxQyxDQUFDO0lBQ00sUUFBUSxDQUFDLE1BQWM7UUFDN0IsSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsR0FBRyxNQUFNLENBQUMsQ0FBQztRQUN6RCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLElBQUksVUFBVSxDQUFDO0lBQzVDLENBQUM7Q0FDRDtBQXBCRCxzQkFvQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQge2dwdFBhcnRUeXBlcywgcGFyc2VHUFQsIHBhcnNlR1BUYWJsZX0gZnJvbSAnLi9ncHRQYXJ0JztcbmltcG9ydCB7SU1ickRhdGEsIGlzTWJyUGFydGl0aW9uLCBwYXJzZU1CUiwgcGFydFR5cGVzfSBmcm9tICcuL21iclBhcnQnO1xuaW1wb3J0IHtHUFRQYXJ0aXRpb259IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHtyZWFkRmlsZX0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNjYW4oZmQ6IG51bWJlcik6IFByb21pc2U8SU1ickRhdGE+IHtcblx0Y29uc3QgYnVmZmVyID0gYXdhaXQgcmVhZEZpbGUoZmQsIDAsIDUxMiwgMCk7XG5cdGxldCByb290TWJyID0gcGFyc2VNQlIoYnVmZmVyKTtcblx0cm9vdE1ici5wYXJ0aXRpb25zLmZvckVhY2goYXN5bmMgZnVuY3Rpb24gKHApIHtcblx0XHRpZiAocC50eXBlID09IHBhcnRUeXBlcy5FWFRFTkRFRCkge1xuXHRcdFx0Ly8gRXh0ZW5kZWQgcGFydGl0aW9uIHJlYWRpbmdcblx0XHRcdGlmICghaXNNYnJQYXJ0aXRpb24ocCkpIHtcblx0XHRcdFx0dGhyb3cgVHlwZUVycm9yKCd3ZSBkaWQgZ2V0IEdQVCBwYXJ0aXRpb24gYXMgZXh0ZW5kZWQnKTtcblx0XHRcdH1cblx0XHRcdGxldCBleHRwYXJ0cyA9IHBhcnNlTUJSKGF3YWl0IHJlYWRGaWxlKGZkLCAwLCA1MTIsIDUxMikpO1xuXHRcdFx0ZXh0cGFydHMucGFydGl0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uIChleHRwYXJ0KSB7XG5cdFx0XHRcdGlmICghaXNNYnJQYXJ0aXRpb24oZXh0cGFydCkpIHtcblx0XHRcdFx0XHR0aHJvdyBUeXBlRXJyb3IoJ3dlIGRpZCBnZXQgR1BUIHBhcnRpdGlvbiBhcyBleHRlbmRlZCcpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChleHRwYXJ0LnR5cGUgIT0gcGFydFR5cGVzLkVNUFRZKSB7XG5cdFx0XHRcdFx0ZXh0cGFydC5zdGFydExCQSA9IGV4dHBhcnQuc3RhcnRMQkEgKyBwLnN0YXJ0TEJBO1xuXHRcdFx0XHRcdHJvb3RNYnIucGFydGl0aW9ucy5wdXNoKGV4dHBhcnQpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdFx0aWYgKHAudHlwZSA9PSBwYXJ0VHlwZXMuR1BUKSB7XG5cdFx0XHRyb290TWJyLnR5cGUgPSAnR1BUJztcblx0XHRcdC8vIEdQVCBwYXJ0aXRpb24gdGFibGUgcmVhZGluZ1xuXHRcdFx0bGV0IGdwdCA9IHBhcnNlR1BUKGF3YWl0IHJlYWRGaWxlKGZkLCAwLCA1MTIsIDUxMikpO1xuXHRcdFx0cm9vdE1ici51dWlkID0gZ3B0LnV1aWQ7XG5cdFx0XHRsZXQgZ0J1ZmYgPSBCdWZmZXIuYWxsb2NVbnNhZmUoZ3B0LnBhcnRpdGlvbnMgKiBncHQucGFydGl0aW9uU2l6ZSk7XG5cdFx0XHRmcy5yZWFkU3luYyhmZCwgZ0J1ZmYsIDAsIGdCdWZmLmxlbmd0aCwgTnVtYmVyKGdwdC50YWJsZUxCQSkgKiA1MTIpO1xuXHRcdFx0bGV0IHBhcnRpdGlvbnM6IEdQVFBhcnRpdGlvbltdID0gW107XG5cdFx0XHRmb3IgKGxldCBpID0gMDsgaSA8IGdwdC5wYXJ0aXRpb25zICogZ3B0LnBhcnRpdGlvblNpemU7IGkgKz0gZ3B0LnBhcnRpdGlvblNpemUpIHtcblx0XHRcdFx0bGV0IHRhYmxlID0gcGFyc2VHUFRhYmxlKGdCdWZmLnNsaWNlKGksIGkgKyBncHQucGFydGl0aW9uU2l6ZSkpO1xuXHRcdFx0XHRpZiAodGFibGUudHlwZUlkICE9IGdwdFBhcnRUeXBlcy5FTVBUWSkge1xuXHRcdFx0XHRcdHBhcnRpdGlvbnMucHVzaCh0YWJsZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJvb3RNYnIucGFydGl0aW9ucyA9IHBhcnRpdGlvbnM7XG5cdFx0fVxuXHR9KTtcblx0cmV0dXJuIHJvb3RNYnI7XG59XG5cbmV4cG9ydCBjbGFzcyBNYWdpYyB7XG5cdHByaXZhdGUgZmQ6IG51bWJlcjtcblx0Y29uc3RydWN0b3IoZmQ6IG51bWJlcikge1xuXHRcdHRoaXMuZmQgPSBmZDtcblx0fVxuXHRwdWJsaWMgaGF2ZUV4dChvZmZzZXQ6IG51bWJlcikge1xuXHRcdGxldCBkYXRhID0gQnVmZmVyLmFsbG9jVW5zYWZlKDIwNDgpO1xuXHRcdGZzLnJlYWRTeW5jKHRoaXMuZmQsIGRhdGEsIDAsIGRhdGEubGVuZ3RoLCA1MTIgKiBvZmZzZXQpO1xuXHRcdHJldHVybiBkYXRhLnJlYWRJbnQxNkJFKDEwODApID09IDB4NTNlZjtcblx0fVxuXHRwdWJsaWMgaGF2ZU50ZnMob2Zmc2V0OiBudW1iZXIpIHtcblx0XHRsZXQgZGF0YSA9IEJ1ZmZlci5hbGxvY1Vuc2FmZSg1MTIpO1xuXHRcdGZzLnJlYWRTeW5jKHRoaXMuZmQsIGRhdGEsIDAsIGRhdGEubGVuZ3RoLCA1MTIgKiBvZmZzZXQpO1xuXHRcdHJldHVybiBkYXRhLnJlYWRJbnQzMkJFKDMpID09IDB4NGU1NDQ2NTM7XG5cdH1cblx0cHVibGljIGhhdmVMdm0yKG9mZnNldDogbnVtYmVyKSB7XG5cdFx0bGV0IGRhdGEgPSBCdWZmZXIuYWxsb2NVbnNhZmUoMTAyNCk7XG5cdFx0ZnMucmVhZFN5bmModGhpcy5mZCwgZGF0YSwgMCwgZGF0YS5sZW5ndGgsIDUxMiAqIG9mZnNldCk7XG5cdFx0cmV0dXJuIGRhdGEucmVhZEludDMyQkUoNTM2KSA9PSAweDRjNTY0ZDMyO1xuXHR9XG59XG4iXX0=
package/dist/mbrPart.d.ts DELETED
@@ -1,23 +0,0 @@
1
- /// <reference types="node" />
2
- import { GPTPartition, MBRPartition } from './types';
3
- export declare const partTypes: {
4
- EMPTY: number;
5
- EXTENDED: number;
6
- NTFS: number;
7
- LINUX_SWAP: number;
8
- LINUX: number;
9
- LINUX_EXTENDED: number;
10
- LINUX_LVM: number;
11
- GPT: number;
12
- EFI: number;
13
- LINUX_RAID: number;
14
- getName: (val: number) => string;
15
- };
16
- export interface IMbrData {
17
- copyProtected: boolean;
18
- uuid: string;
19
- type: 'MBR' | 'GPT';
20
- partitions: (MBRPartition | GPTPartition)[];
21
- }
22
- export declare function parseMBR(mbr: Buffer): IMbrData;
23
- export declare function isMbrPartition(part: MBRPartition | GPTPartition): part is MBRPartition;
package/dist/mbrPart.js DELETED
@@ -1,58 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isMbrPartition = exports.parseMBR = exports.partTypes = void 0;
4
- exports.partTypes = {
5
- EMPTY: 0x00,
6
- EXTENDED: 0x05,
7
- NTFS: 0x07,
8
- LINUX_SWAP: 0x82,
9
- LINUX: 0x83,
10
- LINUX_EXTENDED: 0x85,
11
- LINUX_LVM: 0x8e,
12
- GPT: 0xee,
13
- EFI: 0xef,
14
- LINUX_RAID: 0xfd,
15
- getName: function (val) {
16
- // print names for values
17
- for (let k in exports.partTypes) {
18
- if (exports.partTypes[k] === val) {
19
- return k;
20
- }
21
- }
22
- return 'Unknown';
23
- },
24
- };
25
- function parseMBR(mbr) {
26
- if (mbr.length < 512 || mbr[0x1fe] != 85 || mbr[0x1ff] != 170) {
27
- // MBR signature
28
- throw Error('no MBR signature or buffer is less than 512 bytes');
29
- }
30
- let ret = {
31
- copyProtected: mbr[0x1bc] == 90 && mbr[0x1bc] == 90 ? true : false,
32
- uuid: Buffer.from([mbr[0x1bb], mbr[0x1ba], mbr[0x1b9], mbr[0x1b8]]).toString('hex'),
33
- partitions: [],
34
- type: 'MBR', // as default
35
- };
36
- for (let i = 446; i <= 508; i += 16) {
37
- // MBR table blocks
38
- ret.partitions.push(parseMBRPartition(mbr.slice(i, i + 16)));
39
- }
40
- return ret;
41
- }
42
- exports.parseMBR = parseMBR;
43
- function parseMBRPartition(part) {
44
- const startLBA = part.readUInt32LE(8);
45
- const partitionSize = part.readUInt32LE(12);
46
- return {
47
- active: part.readUInt8(0) == 0x80 ? true : false,
48
- type: part.readUInt8(4),
49
- startLBA,
50
- partitionSize,
51
- endLBA: startLBA + partitionSize,
52
- };
53
- }
54
- function isMbrPartition(part) {
55
- return typeof part.type === 'number';
56
- }
57
- exports.isMbrPartition = isMbrPartition;
58
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWJyUGFydC5qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbIm1iclBhcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRWEsUUFBQSxTQUFTLEdBQUc7SUFDeEIsS0FBSyxFQUFFLElBQUk7SUFDWCxRQUFRLEVBQUUsSUFBSTtJQUNkLElBQUksRUFBRSxJQUFJO0lBQ1YsVUFBVSxFQUFFLElBQUk7SUFDaEIsS0FBSyxFQUFFLElBQUk7SUFDWCxjQUFjLEVBQUUsSUFBSTtJQUNwQixTQUFTLEVBQUUsSUFBSTtJQUNmLEdBQUcsRUFBRSxJQUFJO0lBQ1QsR0FBRyxFQUFFLElBQUk7SUFDVCxVQUFVLEVBQUUsSUFBSTtJQUNoQixPQUFPLEVBQUUsVUFBVSxHQUFXO1FBQzdCLHlCQUF5QjtRQUN6QixLQUFLLElBQUksQ0FBQyxJQUFJLGlCQUFTLEVBQUU7WUFDeEIsSUFBSSxpQkFBUyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsRUFBRTtnQkFDekIsT0FBTyxDQUFDLENBQUM7YUFDVDtTQUNEO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbEIsQ0FBQztDQUNELENBQUM7QUFTRixTQUFnQixRQUFRLENBQUMsR0FBVztJQUNuQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsRUFBRTtRQUM5RCxnQkFBZ0I7UUFDaEIsTUFBTSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQztLQUNqRTtJQUNELElBQUksR0FBRyxHQUFhO1FBQ25CLGFBQWEsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSztRQUNsRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUNuRixVQUFVLEVBQUUsRUFBRTtRQUNkLElBQUksRUFBRSxLQUFLLEVBQUUsYUFBYTtLQUMxQixDQUFDO0lBQ0YsS0FBSyxJQUFJLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFO1FBQ3BDLG1CQUFtQjtRQUNuQixHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzdEO0lBQ0QsT0FBTyxHQUFHLENBQUM7QUFDWixDQUFDO0FBaEJELDRCQWdCQztBQUVELFNBQVMsaUJBQWlCLENBQUMsSUFBWTtJQUN0QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUMsT0FBTztRQUNOLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLO1FBQ2hELElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN2QixRQUFRO1FBQ1IsYUFBYTtRQUNiLE1BQU0sRUFBRSxRQUFRLEdBQUcsYUFBYTtLQUNoQyxDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxJQUFpQztJQUMvRCxPQUFPLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxRQUFRLENBQUM7QUFDdEMsQ0FBQztBQUZELHdDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtHUFRQYXJ0aXRpb24sIE1CUlBhcnRpdGlvbn0gZnJvbSAnLi90eXBlcyc7XG5cbmV4cG9ydCBjb25zdCBwYXJ0VHlwZXMgPSB7XG5cdEVNUFRZOiAweDAwLFxuXHRFWFRFTkRFRDogMHgwNSxcblx0TlRGUzogMHgwNyxcblx0TElOVVhfU1dBUDogMHg4Mixcblx0TElOVVg6IDB4ODMsXG5cdExJTlVYX0VYVEVOREVEOiAweDg1LFxuXHRMSU5VWF9MVk06IDB4OGUsXG5cdEdQVDogMHhlZSxcblx0RUZJOiAweGVmLFxuXHRMSU5VWF9SQUlEOiAweGZkLFxuXHRnZXROYW1lOiBmdW5jdGlvbiAodmFsOiBudW1iZXIpOiBzdHJpbmcge1xuXHRcdC8vIHByaW50IG5hbWVzIGZvciB2YWx1ZXNcblx0XHRmb3IgKGxldCBrIGluIHBhcnRUeXBlcykge1xuXHRcdFx0aWYgKHBhcnRUeXBlc1trXSA9PT0gdmFsKSB7XG5cdFx0XHRcdHJldHVybiBrO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gJ1Vua25vd24nO1xuXHR9LFxufTtcblxuZXhwb3J0IGludGVyZmFjZSBJTWJyRGF0YSB7XG5cdGNvcHlQcm90ZWN0ZWQ6IGJvb2xlYW47XG5cdHV1aWQ6IHN0cmluZztcblx0dHlwZTogJ01CUicgfCAnR1BUJztcblx0cGFydGl0aW9uczogKE1CUlBhcnRpdGlvbiB8IEdQVFBhcnRpdGlvbilbXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlTUJSKG1icjogQnVmZmVyKTogSU1ickRhdGEge1xuXHRpZiAobWJyLmxlbmd0aCA8IDUxMiB8fCBtYnJbMHgxZmVdICE9IDg1IHx8IG1iclsweDFmZl0gIT0gMTcwKSB7XG5cdFx0Ly8gTUJSIHNpZ25hdHVyZVxuXHRcdHRocm93IEVycm9yKCdubyBNQlIgc2lnbmF0dXJlIG9yIGJ1ZmZlciBpcyBsZXNzIHRoYW4gNTEyIGJ5dGVzJyk7XG5cdH1cblx0bGV0IHJldDogSU1ickRhdGEgPSB7XG5cdFx0Y29weVByb3RlY3RlZDogbWJyWzB4MWJjXSA9PSA5MCAmJiBtYnJbMHgxYmNdID09IDkwID8gdHJ1ZSA6IGZhbHNlLFxuXHRcdHV1aWQ6IEJ1ZmZlci5mcm9tKFttYnJbMHgxYmJdLCBtYnJbMHgxYmFdLCBtYnJbMHgxYjldLCBtYnJbMHgxYjhdXSkudG9TdHJpbmcoJ2hleCcpLCAvLyBEaXNrSUQ6IDFCOCAoaGV4KSB0aHJvdWdoIDFCRSAoaGV4KSAobG9va3MgbGlrZSByZXZlcnNlKVxuXHRcdHBhcnRpdGlvbnM6IFtdLFxuXHRcdHR5cGU6ICdNQlInLCAvLyBhcyBkZWZhdWx0XG5cdH07XG5cdGZvciAobGV0IGkgPSA0NDY7IGkgPD0gNTA4OyBpICs9IDE2KSB7XG5cdFx0Ly8gTUJSIHRhYmxlIGJsb2Nrc1xuXHRcdHJldC5wYXJ0aXRpb25zLnB1c2gocGFyc2VNQlJQYXJ0aXRpb24obWJyLnNsaWNlKGksIGkgKyAxNikpKTtcblx0fVxuXHRyZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBwYXJzZU1CUlBhcnRpdGlvbihwYXJ0OiBCdWZmZXIpOiBNQlJQYXJ0aXRpb24ge1xuXHRjb25zdCBzdGFydExCQSA9IHBhcnQucmVhZFVJbnQzMkxFKDgpO1xuXHRjb25zdCBwYXJ0aXRpb25TaXplID0gcGFydC5yZWFkVUludDMyTEUoMTIpO1xuXHRyZXR1cm4ge1xuXHRcdGFjdGl2ZTogcGFydC5yZWFkVUludDgoMCkgPT0gMHg4MCA/IHRydWUgOiBmYWxzZSxcblx0XHR0eXBlOiBwYXJ0LnJlYWRVSW50OCg0KSxcblx0XHRzdGFydExCQSxcblx0XHRwYXJ0aXRpb25TaXplLFxuXHRcdGVuZExCQTogc3RhcnRMQkEgKyBwYXJ0aXRpb25TaXplLFxuXHR9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNNYnJQYXJ0aXRpb24ocGFydDogTUJSUGFydGl0aW9uIHwgR1BUUGFydGl0aW9uKTogcGFydCBpcyBNQlJQYXJ0aXRpb24ge1xuXHRyZXR1cm4gdHlwZW9mIHBhcnQudHlwZSA9PT0gJ251bWJlcic7XG59XG4iXX0=
package/dist/types.d.ts DELETED
@@ -1,18 +0,0 @@
1
- export declare type MBRPartition = {
2
- active: boolean;
3
- type: number;
4
- startLBA: number;
5
- partitionSize: number;
6
- endLBA: number;
7
- };
8
- export declare type GPTPartition = {
9
- typeId: string;
10
- type: string;
11
- uuid: string;
12
- active: boolean;
13
- startLBA: bigint;
14
- endLBA: bigint;
15
- partitionSize: bigint;
16
- attributes: bigint;
17
- label: string;
18
- };
package/dist/types.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiLi9zcmMvIiwic291cmNlcyI6WyJ0eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHR5cGUgTUJSUGFydGl0aW9uID0ge1xuXHRhY3RpdmU6IGJvb2xlYW47XG5cdHR5cGU6IG51bWJlcjtcblx0c3RhcnRMQkE6IG51bWJlcjtcblx0cGFydGl0aW9uU2l6ZTogbnVtYmVyO1xuXHRlbmRMQkE6IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEdQVFBhcnRpdGlvbiA9IHtcblx0dHlwZUlkOiBzdHJpbmc7XG5cdHR5cGU6IHN0cmluZztcblx0dXVpZDogc3RyaW5nO1xuXHRhY3RpdmU6IGJvb2xlYW47XG5cdHN0YXJ0TEJBOiBiaWdpbnQ7XG5cdGVuZExCQTogYmlnaW50O1xuXHRwYXJ0aXRpb25TaXplOiBiaWdpbnQ7XG5cdGF0dHJpYnV0ZXM6IGJpZ2ludDtcblx0bGFiZWw6IHN0cmluZztcbn07XG4iXX0=
package/dist/util.d.ts DELETED
@@ -1,3 +0,0 @@
1
- /// <reference types="node" />
2
- import * as fs from 'fs';
3
- export declare function readFile(fd: number, offset: number, length: number, position: fs.ReadPosition | null): Promise<Buffer>;
package/dist/util.js DELETED
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readFile = void 0;
4
- const fs = require("fs");
5
- function readFile(fd, offset, length, position) {
6
- return new Promise((resolve, reject) => {
7
- const buffer = Buffer.allocUnsafe(length);
8
- fs.read(fd, buffer, offset, buffer.length, position, (err) => {
9
- if (err) {
10
- reject(err);
11
- }
12
- else {
13
- resolve(buffer);
14
- }
15
- });
16
- });
17
- }
18
- exports.readFile = readFile;
19
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUJBQXlCO0FBQ3pCLFNBQWdCLFFBQVEsQ0FBQyxFQUFVLEVBQUUsTUFBYyxFQUFFLE1BQWMsRUFBRSxRQUFnQztJQUNwRyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO1lBQzVELElBQUksR0FBRyxFQUFFO2dCQUNSLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNaO2lCQUFNO2dCQUNOLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQzthQUNoQjtRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7QUFDSixDQUFDO0FBWEQsNEJBV0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5leHBvcnQgZnVuY3Rpb24gcmVhZEZpbGUoZmQ6IG51bWJlciwgb2Zmc2V0OiBudW1iZXIsIGxlbmd0aDogbnVtYmVyLCBwb3NpdGlvbjogZnMuUmVhZFBvc2l0aW9uIHwgbnVsbCk6IFByb21pc2U8QnVmZmVyPiB7XG5cdHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG5cdFx0Y29uc3QgYnVmZmVyID0gQnVmZmVyLmFsbG9jVW5zYWZlKGxlbmd0aCk7XG5cdFx0ZnMucmVhZChmZCwgYnVmZmVyLCBvZmZzZXQsIGJ1ZmZlci5sZW5ndGgsIHBvc2l0aW9uLCAoZXJyKSA9PiB7XG5cdFx0XHRpZiAoZXJyKSB7XG5cdFx0XHRcdHJlamVjdChlcnIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmVzb2x2ZShidWZmZXIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcbn1cbiJdfQ==