@ohos-ports/drivelist 12.0.2-beta.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.
@@ -0,0 +1,188 @@
1
+ /*
2
+ * Copyright 2018 Balena.io
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { getPartitionTableType } from '.';
18
+ import { Drive, Mountpoint } from '..';
19
+
20
+ interface Dict<T> {
21
+ [K: string]: T;
22
+ }
23
+
24
+ function parseLsblkLine(line: string): Dict<string> {
25
+ const data: Dict<string> = {};
26
+ let offset = 0;
27
+ let key = '';
28
+ let value = '';
29
+
30
+ const keyChar = /[^"=]/;
31
+ const whitespace = /\s+/;
32
+ const escape = '\\';
33
+ let state = 'key';
34
+
35
+ while (offset < line.length) {
36
+ if (state === 'key') {
37
+ while (keyChar.test(line[offset])) {
38
+ key += line[offset];
39
+ offset += 1;
40
+ }
41
+ if (line[offset] === '=') {
42
+ state = 'value';
43
+ offset += 1;
44
+ }
45
+ } else if (state === 'value') {
46
+ if (line[offset] !== '"') {
47
+ throw new Error(`Expected '"', saw "${line[offset]}"`);
48
+ }
49
+ offset += 1;
50
+ while (
51
+ line[offset - 1] === escape ||
52
+ (line[offset - 1] !== escape && line[offset] !== '"')
53
+ ) {
54
+ value += line[offset];
55
+ offset += 1;
56
+ }
57
+ if (line[offset] !== '"') {
58
+ throw new Error(`Expected '"', saw "${line[offset]}"`);
59
+ }
60
+ offset += 1;
61
+ data[key.toLowerCase()] = value.trim();
62
+ key = '';
63
+ value = '';
64
+ state = 'space';
65
+ } else if (state === 'space') {
66
+ while (whitespace.test(line[offset])) {
67
+ offset += 1;
68
+ }
69
+ state = 'key';
70
+ } else {
71
+ throw new Error(`Undefined state "${state}"`);
72
+ }
73
+ }
74
+
75
+ return data;
76
+ }
77
+
78
+ function parseLsblk(output: string): Array<Dict<string>> {
79
+ return output.trim().split(/\r?\n/g).map(parseLsblkLine);
80
+ }
81
+
82
+ function consolidate(
83
+ devices: Array<Dict<string>>,
84
+ ): Array<Dict<string> & { mountpoints: Mountpoint[] }> {
85
+ const primaries = devices.filter((device) => {
86
+ return (
87
+ device.type === 'disk' &&
88
+ !device.name.startsWith('ram') &&
89
+ !device.name.startsWith('sr')
90
+ );
91
+ });
92
+
93
+ return primaries.map((device) => {
94
+ const children = devices.filter((child) => {
95
+ return (
96
+ ['disk', 'part'].includes(child.type) &&
97
+ child.name.startsWith(device.name)
98
+ );
99
+ });
100
+ return Object.assign({}, device, {
101
+ mountpoints: children
102
+ .filter((child) => child.mountpoint)
103
+ .map(
104
+ (child): Mountpoint => {
105
+ return {
106
+ path: child.mountpoint,
107
+ label: child.label,
108
+ };
109
+ },
110
+ ),
111
+ });
112
+ });
113
+ }
114
+
115
+ function getDescription(
116
+ device: Dict<string> & { mountpoints: Mountpoint[] },
117
+ ): string {
118
+ const description = [
119
+ device.label || '',
120
+ device.vendor || '',
121
+ device.model || '',
122
+ ];
123
+ if (device.mountpoints.length) {
124
+ let subLabels = device.mountpoints
125
+ .filter((c) => {
126
+ return (c.label && c.label !== device.label) || c.path;
127
+ })
128
+ .map((c) => {
129
+ return c.label || c.path;
130
+ });
131
+ subLabels = Array.from(new Set(subLabels));
132
+ if (subLabels.length) {
133
+ description.push(`(${subLabels.join(', ')})`);
134
+ }
135
+ }
136
+ return description.join(' ').replace(/\s+/g, ' ').trim();
137
+ }
138
+
139
+ export function parse(stdout: string): Drive[] {
140
+ const devices = consolidate(parseLsblk(stdout));
141
+
142
+ return devices.map(
143
+ (
144
+ device: Dict<string> & {
145
+ mountpoints: Mountpoint[];
146
+ },
147
+ ): Drive => {
148
+ const isVirtual = device.subsystems
149
+ ? /^block$/i.test(device.subsystems)
150
+ : null;
151
+ const isSCSI = device.tran
152
+ ? /^(?:sata|scsi|ata|ide|pci)$/i.test(device.tran)
153
+ : null;
154
+ const isUSB = device.tran ? /^usb$/i.test(device.tran) : null;
155
+ const isReadOnly = Number(device.ro) === 1;
156
+ const isRemovable =
157
+ Number(device.rm) === 1 ||
158
+ Number(device.hotplug) === 1 ||
159
+ Boolean(isVirtual);
160
+
161
+ return {
162
+ enumerator: 'lsblk:pairs',
163
+ busType: (device.tran || 'UNKNOWN').toUpperCase(),
164
+ busVersion: null,
165
+ device: '/dev/' + device.name,
166
+ devicePath: null,
167
+ raw: '/dev/' + device.name,
168
+ description: getDescription(device) || device.name,
169
+ error: null,
170
+ size: Number(device.size) || null,
171
+ blockSize: Number(device['phy-sec']) || 512,
172
+ logicalBlockSize: Number(device['log-sec']) || 512,
173
+ mountpoints: device.mountpoints,
174
+ isReadOnly,
175
+ isSystem: !isRemovable && !isVirtual,
176
+ isVirtual,
177
+ isRemovable,
178
+ isCard: null,
179
+ isSCSI,
180
+ isUSB,
181
+ isUAS: null,
182
+ partitionTableType: getPartitionTableType(
183
+ device.pttype as 'gpt' | 'dos' | undefined,
184
+ ),
185
+ };
186
+ },
187
+ );
188
+ }
package/package.json ADDED
@@ -0,0 +1,84 @@
1
+ {
2
+ "name": "@ohos-ports/drivelist",
3
+ "version": "12.0.2-beta.1",
4
+ "description": "List all connected drives in your computer, in all major operating systems (OpenHarmony port)",
5
+ "main": "js/index.js",
6
+ "homepage": "https://github.com/balena-io-modules/drivelist",
7
+ "gypfile": true,
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/ohos-ports/ohos-ports.git",
11
+ "directory": "ports/drivelist/12.0.2"
12
+ },
13
+ "keywords": [
14
+ "disk",
15
+ "cross",
16
+ "platform",
17
+ "physical",
18
+ "drive",
19
+ "list"
20
+ ],
21
+ "directories": {
22
+ "test": "tests"
23
+ },
24
+ "scripts": {
25
+ "test": "mocha -r ts-node/register tests/**/*.spec.ts -R spec",
26
+ "lint": "npm run lint-cpp && npm run lint-ts",
27
+ "lint-cpp": "cpplint --recursive src",
28
+ "lint-ts": "balena-lint --typescript lib tests",
29
+ "prettier": "balena-lint --typescript --fix lib tests",
30
+ "readme": "jsdoc2md --template doc/README.hbs js/index.js > README.md",
31
+ "build": "node-gyp rebuild && tsc",
32
+ "build-ts": "tsc",
33
+ "prepublishOnly": "npm run build-ts && npm run readme",
34
+ "install": "prebuild-install --runtime napi || node-gyp rebuild",
35
+ "rebuild": "node-gyp rebuild"
36
+ },
37
+ "author": "Juan Cruz Viotti <juan@balena.io>",
38
+ "license": "Apache-2.0",
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "devDependencies": {
43
+ "@balena/lint": "^6.2.1",
44
+ "@types/bindings": "^1.5.1",
45
+ "@types/chai": "^4.3.4",
46
+ "@types/mocha": "^10.0.1",
47
+ "@types/sinon": "^10.0.13",
48
+ "chai": "^4.3.7",
49
+ "eslint": "^8.31.0",
50
+ "jsdoc-to-markdown": "^8.0.0",
51
+ "mocha": "^10.2.0",
52
+ "node-gyp": "^10.0.1",
53
+ "prebuild": "^11.0.4",
54
+ "sinon": "^15.0.1",
55
+ "ts-node": "^10.9.1",
56
+ "typescript": "^4.9.4"
57
+ },
58
+ "dependencies": {
59
+ "bindings": "^1.5.0",
60
+ "debug": "^4.3.4",
61
+ "node-addon-api": "^8.0.0",
62
+ "prebuild-install": "^7.1.1"
63
+ },
64
+ "binary": {
65
+ "napi_versions": [
66
+ 8
67
+ ]
68
+ },
69
+ "versionist": {
70
+ "publishedAt": "2024-04-08T15:45:36.490Z"
71
+ },
72
+ "bugs": {
73
+ "url": "https://github.com/ohos-ports/ohos-ports/issues"
74
+ },
75
+ "files": [
76
+ "js/",
77
+ "lib/",
78
+ "src/",
79
+ "build/Release/*.node",
80
+ "README.md",
81
+ "LICENSE",
82
+ "CHANGELOG.md"
83
+ ]
84
+ }
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Copyright 2019 balena.io
3
+ * Copyright 2018 Robin Andersson <me@robinwassen.com>
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #ifndef SRC_DARWIN_REDISKLIST_H_
19
+ #define SRC_DARWIN_REDISKLIST_H_
20
+
21
+ #import <Foundation/Foundation.h>
22
+
23
+ /**
24
+ * Class to return a list of disks synchronously
25
+ * To use the class, just init an instance of it and
26
+ * it will populate the disks property with NSStrings
27
+ *
28
+ * @author Robin Andersson
29
+ */
30
+ @interface REDiskList : NSObject
31
+
32
+ /**
33
+ * NSArray of disks and partitions
34
+ * Disks are in the format disk0, disk1 etc
35
+ * Partitions are in the format disk0s1, disk1s1 etc
36
+ */
37
+ @property(readonly) NSArray *disks;
38
+
39
+ @end
40
+
41
+ #endif // SRC_DARWIN_REDISKLIST_H_
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright 2019 balena.io
3
+ * Copyright 2018 Robin Andersson <me@robinwassen.com>
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #import "REDiskList.h"
19
+ #import <DiskArbitration/DiskArbitration.h>
20
+
21
+ @implementation REDiskList
22
+
23
+ - (id)init {
24
+ self = [super init];
25
+
26
+ if (self) {
27
+ _disks = [[NSMutableArray alloc] init];
28
+ [self populateDisksBlocking];
29
+ [_disks sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
30
+ }
31
+
32
+ return self;
33
+ }
34
+
35
+ -(void)dealloc {
36
+ [_disks release];
37
+ [super dealloc];
38
+ }
39
+
40
+ void appendDisk(DADiskRef disk, void *context) {
41
+ NSMutableArray *_disks = (__bridge NSMutableArray*)context;
42
+ const char *bsdName = DADiskGetBSDName(disk);
43
+ if (bsdName != nil) {
44
+ [_disks addObject:[NSString stringWithUTF8String:bsdName]];
45
+ }
46
+ }
47
+
48
+ - (void)populateDisksBlocking {
49
+ DASessionRef session = DASessionCreate(kCFAllocatorDefault);
50
+ if (session) {
51
+ DARegisterDiskAppearedCallback(session, NULL, appendDisk, (void*)_disks);
52
+ CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
53
+ DASessionScheduleWithRunLoop(session, runLoop, kCFRunLoopDefaultMode);
54
+ CFRunLoopStop(runLoop);
55
+ CFRunLoopRunInMode((CFStringRef)NSDefaultRunLoopMode, 0.05, NO);
56
+ DAUnregisterCallback(session, appendDisk, (void*)_disks);
57
+ CFRelease(session);
58
+ }
59
+ }
60
+
61
+ @end
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright 2019 balena.io
3
+ * Copyright 2018 Robin Andersson <me@robinwassen.com>
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include <napi.h>
19
+ #include "../drivelist.hpp"
20
+
21
+ #import "REDiskList.h"
22
+ #import <Cocoa/Cocoa.h>
23
+ #import <DiskArbitration/DiskArbitration.h>
24
+
25
+ namespace Drivelist {
26
+ bool IsDiskPartition(NSString *disk) {
27
+ NSPredicate *partitionRegEx = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"disk\\d+s\\d+"];
28
+ return [partitionRegEx evaluateWithObject:disk];
29
+ }
30
+
31
+ bool IsCard(CFDictionaryRef diskDescription) {
32
+ CFDictionaryRef mediaIconDict = (CFDictionaryRef)CFDictionaryGetValue(
33
+ diskDescription,
34
+ kDADiskDescriptionMediaIconKey
35
+ );
36
+ if (mediaIconDict == nil) {
37
+ return false;
38
+ }
39
+
40
+ CFStringRef iconFileNameKeyRef = CFStringCreateWithCString(NULL, "IOBundleResourceFile", kCFStringEncodingUTF8);
41
+ CFStringRef iconFileNameRef = (CFStringRef)CFDictionaryGetValue(mediaIconDict, iconFileNameKeyRef);
42
+ CFRelease(iconFileNameKeyRef);
43
+
44
+ if (iconFileNameRef == nil) {
45
+ return false;
46
+ }
47
+
48
+ // macOS 10.14.3 - External SD card reader provides `Removable.icns`, not `SD.icns`.
49
+ // But we can't use it to detect SD card, because external drive has `Removable.icns` as well.
50
+ return [(NSString *)iconFileNameRef isEqualToString:@"SD.icns"];
51
+ }
52
+
53
+ NSNumber *DictionaryGetNumber(CFDictionaryRef dict, const void *key) {
54
+ return (NSNumber*)CFDictionaryGetValue(dict, key);
55
+ }
56
+
57
+ DeviceDescriptor CreateDeviceDescriptorFromDiskDescription(std::string diskBsdName, CFDictionaryRef diskDescription) {
58
+ NSString *deviceProtocol = (NSString*)CFDictionaryGetValue(diskDescription, kDADiskDescriptionDeviceProtocolKey);
59
+ NSNumber *blockSize = DictionaryGetNumber(diskDescription, kDADiskDescriptionMediaBlockSizeKey);
60
+ bool isInternal = [DictionaryGetNumber(diskDescription, kDADiskDescriptionDeviceInternalKey) boolValue];
61
+ bool isRemovable = [DictionaryGetNumber(diskDescription, kDADiskDescriptionMediaRemovableKey) boolValue];
62
+ bool isEjectable = [DictionaryGetNumber(diskDescription, kDADiskDescriptionMediaEjectableKey) boolValue];
63
+
64
+ DeviceDescriptor device = DeviceDescriptor();
65
+ NSString *mediaContent = (NSString*)CFDictionaryGetValue(diskDescription, kDADiskDescriptionMediaContentKey);
66
+ if ([mediaContent isEqualToString:@"GUID_partition_scheme"]) {
67
+ device.partitionTableType = "gpt";
68
+ } else if ([mediaContent isEqualToString:@"FDisk_partition_scheme"]) {
69
+ device.partitionTableType = "mbr";
70
+ }
71
+ device.enumerator = "DiskArbitration";
72
+ device.busType = (deviceProtocol != nil) ? [deviceProtocol UTF8String] : "";
73
+ device.busVersion = "";
74
+ device.busVersionNull = true;
75
+ device.device = "/dev/" + diskBsdName;
76
+ NSString *devicePath = (NSString*)CFDictionaryGetValue(diskDescription, kDADiskDescriptionBusPathKey);
77
+ device.devicePath = (devicePath != nil) ? [devicePath UTF8String] : "";
78
+ device.raw = "/dev/r" + diskBsdName;
79
+ NSString *description = (NSString*)CFDictionaryGetValue(diskDescription, kDADiskDescriptionMediaNameKey);
80
+ device.description = (description != nil) ? [description UTF8String] : "";
81
+ device.error = "";
82
+ // NOTE: Not sure if kDADiskDescriptionMediaBlockSizeKey returns
83
+ // the physical or logical block size since both values are equal
84
+ // on my machine
85
+ //
86
+ // The can be checked with the following command:
87
+ // diskutil info / | grep "Block Size"
88
+ device.blockSize = [blockSize unsignedIntValue];
89
+ device.logicalBlockSize = [blockSize unsignedIntValue];
90
+ device.size = [DictionaryGetNumber(diskDescription, kDADiskDescriptionMediaSizeKey) unsignedLongValue];
91
+ device.isReadOnly = ![DictionaryGetNumber(diskDescription, kDADiskDescriptionMediaWritableKey) boolValue];
92
+ device.isSystem = isInternal && !isRemovable;
93
+ device.isVirtual = ((deviceProtocol != nil) && [deviceProtocol isEqualToString:@"Virtual Interface"]);
94
+ device.isRemovable = isRemovable || isEjectable;
95
+ device.isCard = IsCard(diskDescription);
96
+ // NOTE(robin): Not convinced that these bus types should result
97
+ // in device.isSCSI = true, it is rather "not usb or sd drive" bool
98
+ // But the old implementation was like this so kept it this way
99
+ NSArray *scsiTypes = [NSArray arrayWithObjects:@"SATA", @"SCSI", @"ATA", @"IDE", @"PCI", nil];
100
+ device.isSCSI = ((deviceProtocol != nil) && [scsiTypes containsObject:deviceProtocol]);
101
+ device.isUSB = ((deviceProtocol != nil) && [deviceProtocol isEqualToString:@"USB"]);
102
+ device.isUAS = false;
103
+ device.isUASNull = true;
104
+
105
+ return device;
106
+ }
107
+
108
+ std::vector<DeviceDescriptor> ListStorageDevices() {
109
+ std::vector<DeviceDescriptor> deviceList;
110
+
111
+ DASessionRef session = DASessionCreate(kCFAllocatorDefault);
112
+ if (session == nil) {
113
+ return deviceList;
114
+ }
115
+
116
+ REDiskList *dl = [[REDiskList alloc] init];
117
+ for (NSString* diskBsdName in dl.disks) {
118
+ if (IsDiskPartition(diskBsdName)) {
119
+ continue;
120
+ }
121
+
122
+ std::string diskBsdNameStr = [diskBsdName UTF8String];
123
+ DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, diskBsdNameStr.c_str());
124
+ if (disk == nil) {
125
+ continue;
126
+ }
127
+
128
+ CFDictionaryRef diskDescription = DADiskCopyDescription(disk);
129
+ if (diskDescription == nil) {
130
+ CFRelease(disk);
131
+ continue;
132
+ }
133
+
134
+ DeviceDescriptor device = CreateDeviceDescriptorFromDiskDescription(diskBsdNameStr, diskDescription);
135
+ deviceList.push_back(device);
136
+
137
+ CFRelease(diskDescription);
138
+ CFRelease(disk);
139
+ }
140
+ [dl release];
141
+
142
+ // Add mount points
143
+ NSArray *volumeKeys = [NSArray arrayWithObjects:NSURLVolumeNameKey, NSURLVolumeLocalizedNameKey, nil];
144
+ NSArray *volumePaths = [
145
+ [NSFileManager defaultManager]
146
+ mountedVolumeURLsIncludingResourceValuesForKeys:volumeKeys
147
+ options:0
148
+ ];
149
+
150
+ for (NSURL *path in volumePaths) {
151
+ DADiskRef disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, (__bridge CFURLRef)path);
152
+ if (disk == nil) {
153
+ continue;
154
+ }
155
+
156
+ const char *bsdnameChar = DADiskGetBSDName(disk);
157
+ if (bsdnameChar == nil) {
158
+ CFRelease(disk);
159
+ continue;
160
+ }
161
+
162
+ NSString *volumeName;
163
+ [path getResourceValue:&volumeName forKey:NSURLVolumeLocalizedNameKey error:nil];
164
+
165
+ std::string partitionBsdName = std::string(bsdnameChar);
166
+ std::string diskBsdName = partitionBsdName.substr(0, partitionBsdName.find("s", 5));
167
+
168
+ for(std::vector<int>::size_type i = 0; i != deviceList.size(); i++) {
169
+ DeviceDescriptor *dd = &deviceList[i];
170
+
171
+ if (dd->device == "/dev/" + diskBsdName) {
172
+ dd->mountpoints.push_back([[path path] UTF8String]);
173
+ dd->mountpointLabels.push_back([volumeName UTF8String]);
174
+ break;
175
+ }
176
+ }
177
+
178
+ CFRelease(disk);
179
+ }
180
+ CFRelease(session);
181
+
182
+ return deviceList;
183
+ }
184
+
185
+ } // namespace Drivelist
@@ -0,0 +1,125 @@
1
+ /*
2
+ * Copyright 2017 balena.io
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #include <napi.h>
18
+
19
+ #include "drivelist.hpp"
20
+
21
+ using Napi::Boolean;
22
+ using Napi::Number;
23
+ using Napi::String;
24
+ using Napi::Value;
25
+
26
+ namespace Drivelist {
27
+
28
+ Napi::Object PackDriveDescriptor(Napi::Env env,
29
+ const DeviceDescriptor *instance) {
30
+ Napi::Object object = Napi::Object::New(env);
31
+
32
+ object.Set(String::New(env, "enumerator"),
33
+ String::New(env, instance->enumerator));
34
+
35
+ object.Set(String::New(env, "busType"), String::New(env, instance->busType));
36
+
37
+ Napi::Value busVersion =
38
+ instance->busVersionNull
39
+ ? (Napi::Value)env.Null()
40
+ : (Napi::Value)String::New(env, instance->busVersion);
41
+
42
+ object.Set(String::New(env, "busVersion"), busVersion);
43
+
44
+ object.Set(String::New(env, "device"), String::New(env, instance->device));
45
+
46
+ Napi::Value devicePath =
47
+ instance->devicePathNull
48
+ ? (Napi::Value)env.Null()
49
+ : (Napi::Value)String::New(env, instance->devicePath);
50
+
51
+ object.Set(String::New(env, "devicePath"), devicePath);
52
+
53
+ object.Set(String::New(env, "raw"), String::New(env, instance->raw));
54
+
55
+ object.Set(String::New(env, "description"),
56
+ String::New(env, instance->description));
57
+
58
+ if (instance->partitionTableType != "") {
59
+ object.Set(String::New(env, "partitionTableType"),
60
+ String::New(env, instance->partitionTableType));
61
+ } else {
62
+ object.Set(String::New(env, "partitionTableType"), env.Null());
63
+ }
64
+
65
+ if (instance->error != "") {
66
+ object.Set(String::New(env, "error"), String::New(env, instance->error));
67
+ } else {
68
+ object.Set(String::New(env, "error"), env.Null());
69
+ }
70
+
71
+ object.Set(String::New(env, "size"),
72
+ Number::New(env, static_cast<double>(instance->size)));
73
+
74
+ object.Set(String::New(env, "blockSize"),
75
+ Number::New(env, static_cast<double>(instance->blockSize)));
76
+
77
+ object.Set(String::New(env, "logicalBlockSize"),
78
+ Number::New(env, static_cast<double>(instance->logicalBlockSize)));
79
+
80
+ Napi::Object mountpoints = Napi::Array::New(env);
81
+
82
+ uint32_t index = 0;
83
+ for (std::string mountpointPath : instance->mountpoints) {
84
+ Napi::Object mountpoint = Napi::Object::New(env);
85
+ mountpoint.Set(String::New(env, "path"), String::New(env, mountpointPath));
86
+
87
+ if (index < instance->mountpointLabels.size()) {
88
+ mountpoint.Set(String::New(env, "label"),
89
+ String::New(env, instance->mountpointLabels[index]));
90
+ }
91
+
92
+ mountpoints.Set(index, mountpoint);
93
+ index++;
94
+ }
95
+
96
+ object.Set(String::New(env, "mountpoints"), mountpoints);
97
+
98
+ object.Set(String::New(env, "isReadOnly"),
99
+ Boolean::New(env, instance->isReadOnly));
100
+
101
+ object.Set(String::New(env, "isSystem"),
102
+ Boolean::New(env, instance->isSystem));
103
+
104
+ object.Set(String::New(env, "isVirtual"),
105
+ Boolean::New(env, instance->isVirtual));
106
+
107
+ object.Set(String::New(env, "isRemovable"),
108
+ Boolean::New(env, instance->isRemovable));
109
+
110
+ object.Set(String::New(env, "isCard"), Boolean::New(env, instance->isCard));
111
+
112
+ object.Set(String::New(env, "isSCSI"), Boolean::New(env, instance->isSCSI));
113
+
114
+ object.Set(String::New(env, "isUSB"), Boolean::New(env, instance->isUSB));
115
+
116
+ Napi::Value isUAS = instance->isUASNull
117
+ ? (Napi::Value)env.Null()
118
+ : (Napi::Value)Boolean::New(env, instance->isUAS);
119
+
120
+ object.Set(String::New(env, "isUAS"), isUAS);
121
+
122
+ return object;
123
+ }
124
+
125
+ } // namespace Drivelist