node-ctypes 0.1.5 → 1.0.0
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.
Potentially problematic release.
This version of node-ctypes might be problematic. Click here for more details.
- package/README.md +14 -9
- package/build/Release/ctypes-darwin-arm64.node +0 -0
- package/build/Release/ctypes-darwin-x64.node +0 -0
- package/build/Release/ctypes-linux-arm64.node +0 -0
- package/build/Release/ctypes-linux-x64.node +0 -0
- package/build/Release/ctypes-win32-arm64.node +0 -0
- package/build/Release/ctypes-win32-x64.node +0 -0
- package/lib/core/Library.js +312 -0
- package/lib/core/callback.js +275 -0
- package/lib/core/types.js +140 -0
- package/lib/index.d.ts +71 -124
- package/lib/index.js +215 -3096
- package/lib/memory/buffer.js +404 -0
- package/lib/memory/operations.js +295 -0
- package/lib/memory/pointer.js +358 -0
- package/lib/platform/constants.js +110 -0
- package/lib/platform/errors.js +403 -0
- package/lib/structures/Structure.js +414 -0
- package/lib/structures/Union.js +102 -0
- package/lib/structures/helpers/array.js +261 -0
- package/lib/structures/helpers/bitfield.js +147 -0
- package/lib/structures/helpers/common.js +129 -0
- package/lib/structures/helpers/struct.js +925 -0
- package/lib/structures/helpers/union.js +465 -0
- package/lib/types/SimpleCData.js +193 -0
- package/lib/types/primitives.js +392 -0
- package/lib/utils/cache.js +142 -0
- package/package.json +1 -1
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file errors.js
|
|
3
|
+
* @module platform/errors
|
|
4
|
+
* @description Platform-specific error handling for errno and Windows errors.
|
|
5
|
+
*
|
|
6
|
+
* This module provides Python ctypes-compatible error handling functions for both
|
|
7
|
+
* Unix-like systems (errno) and Windows (GetLastError/FormatError).
|
|
8
|
+
*
|
|
9
|
+
* **Python ctypes Compatibility**:
|
|
10
|
+
* - `get_errno()` / `set_errno()` ≈ Python's `ctypes.get_errno()` / `set_errno()`
|
|
11
|
+
* - `GetLastError()` / `SetLastError()` ≈ Python's `ctypes.GetLastError()` / `SetLastError()`
|
|
12
|
+
* - `FormatError()` ≈ Python's `ctypes.FormatError()`
|
|
13
|
+
* - `WinError()` ≈ Python's `ctypes.WinError()`
|
|
14
|
+
*
|
|
15
|
+
* @example Unix errno
|
|
16
|
+
* ```javascript
|
|
17
|
+
* import { get_errno, set_errno } from 'node-ctypes';
|
|
18
|
+
*
|
|
19
|
+
* // Call C function that might set errno
|
|
20
|
+
* const result = some_c_function();
|
|
21
|
+
* if (result === -1) {
|
|
22
|
+
* const err = get_errno();
|
|
23
|
+
* console.log(`errno: ${err}`);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @example Windows errors
|
|
28
|
+
* ```javascript
|
|
29
|
+
* import { GetLastError, WinError } from 'node-ctypes';
|
|
30
|
+
*
|
|
31
|
+
* // Call Windows API that might fail
|
|
32
|
+
* const result = some_win_api();
|
|
33
|
+
* if (!result) {
|
|
34
|
+
* throw WinError(); // Creates Error with formatted message
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// Lazy-loaded errno and Windows error functions
|
|
40
|
+
let _errno_funcs = null;
|
|
41
|
+
let _win_error_funcs = null;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Initializes errno functions (lazy loading).
|
|
45
|
+
*
|
|
46
|
+
* **Platform-Specific Behavior**:
|
|
47
|
+
* - **Windows**: Uses msvcrt.dll `_get_errno()` / `_set_errno()`
|
|
48
|
+
* - **macOS**: Uses `__error()` function (returns pointer to errno)
|
|
49
|
+
* - **Linux**: Uses `__errno_location()` function (returns pointer to errno)
|
|
50
|
+
*
|
|
51
|
+
* @param {Function} CDLL - CDLL class reference
|
|
52
|
+
* @param {Object} c_int32 - c_int32 type reference
|
|
53
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
54
|
+
* @returns {Object} Errno functions object
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
function _initErrno(CDLL, c_int32, c_void_p) {
|
|
58
|
+
if (_errno_funcs) return _errno_funcs;
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
if (process.platform === "win32") {
|
|
62
|
+
const msvcrt = new CDLL("msvcrt.dll");
|
|
63
|
+
_errno_funcs = {
|
|
64
|
+
_get: msvcrt.func("_get_errno", c_int32, [c_void_p]),
|
|
65
|
+
_set: msvcrt.func("_set_errno", c_int32, [c_int32]),
|
|
66
|
+
_lib: msvcrt,
|
|
67
|
+
};
|
|
68
|
+
} else if (process.platform === "darwin") {
|
|
69
|
+
// macOS uses __error instead of __errno_location
|
|
70
|
+
const libc = new CDLL(null);
|
|
71
|
+
_errno_funcs = {
|
|
72
|
+
_location: libc.func("__error", c_void_p, []),
|
|
73
|
+
_lib: libc,
|
|
74
|
+
};
|
|
75
|
+
} else {
|
|
76
|
+
// Linux and other Unix systems use __errno_location
|
|
77
|
+
const libc = new CDLL(null);
|
|
78
|
+
_errno_funcs = {
|
|
79
|
+
_location: libc.func("__errno_location", c_void_p, []),
|
|
80
|
+
_lib: libc,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
_errno_funcs = { error: e.message };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return _errno_funcs;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Gets the current value of errno.
|
|
92
|
+
*
|
|
93
|
+
* **Platform-Specific Behavior**:
|
|
94
|
+
* - **Windows**: Calls msvcrt `_get_errno()`
|
|
95
|
+
* - **Unix**: Reads from errno location pointer
|
|
96
|
+
*
|
|
97
|
+
* **Python ctypes Compatibility**:
|
|
98
|
+
* Direct equivalent to Python's `ctypes.get_errno()`.
|
|
99
|
+
*
|
|
100
|
+
* @param {Function} CDLL - CDLL class reference
|
|
101
|
+
* @param {Function} alloc - alloc function reference
|
|
102
|
+
* @param {Function} readValue - readValue function reference
|
|
103
|
+
* @param {Object} c_int32 - c_int32 type reference
|
|
104
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
105
|
+
* @returns {number} Current errno value
|
|
106
|
+
* @throws {Error} If errno is not available on this platform
|
|
107
|
+
*
|
|
108
|
+
* @example Get errno after failed system call
|
|
109
|
+
* ```javascript
|
|
110
|
+
* import { CDLL, get_errno, c_int } from 'node-ctypes';
|
|
111
|
+
*
|
|
112
|
+
* const libc = new CDLL(null);
|
|
113
|
+
* const open = libc.func('open', c_int, [c_char_p, c_int]);
|
|
114
|
+
*
|
|
115
|
+
* const fd = open('/nonexistent/file', 0);
|
|
116
|
+
* if (fd === -1) {
|
|
117
|
+
* const err = get_errno();
|
|
118
|
+
* console.log(`Error code: ${err}`); // e.g., 2 (ENOENT)
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
export function get_errno(CDLL, alloc, readValue, c_int32, c_void_p) {
|
|
123
|
+
const funcs = _initErrno(CDLL, c_int32, c_void_p);
|
|
124
|
+
if (funcs.error) {
|
|
125
|
+
throw new Error("errno not available: " + funcs.error);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (process.platform === "win32") {
|
|
129
|
+
const buf = alloc(4);
|
|
130
|
+
funcs._get(buf);
|
|
131
|
+
return readValue(buf, c_int32);
|
|
132
|
+
} else {
|
|
133
|
+
const ptr = funcs._location();
|
|
134
|
+
return readValue(ptr, c_int32);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Sets the value of errno.
|
|
140
|
+
*
|
|
141
|
+
* **Platform-Specific Behavior**:
|
|
142
|
+
* - **Windows**: Calls msvcrt `_set_errno()`
|
|
143
|
+
* - **Unix**: Writes to errno location pointer
|
|
144
|
+
*
|
|
145
|
+
* **Python ctypes Compatibility**:
|
|
146
|
+
* Direct equivalent to Python's `ctypes.set_errno()`.
|
|
147
|
+
*
|
|
148
|
+
* @param {number} value - New errno value
|
|
149
|
+
* @param {Function} CDLL - CDLL class reference
|
|
150
|
+
* @param {Function} writeValue - writeValue function reference
|
|
151
|
+
* @param {Object} c_int32 - c_int32 type reference
|
|
152
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
153
|
+
* @throws {Error} If errno is not available on this platform
|
|
154
|
+
*
|
|
155
|
+
* @example Set errno before calling function
|
|
156
|
+
* ```javascript
|
|
157
|
+
* import { set_errno } from 'node-ctypes';
|
|
158
|
+
*
|
|
159
|
+
* // Clear errno before call
|
|
160
|
+
* set_errno(0);
|
|
161
|
+
* const result = some_c_function();
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export function set_errno(value, CDLL, writeValue, c_int32, c_void_p) {
|
|
165
|
+
const funcs = _initErrno(CDLL, c_int32, c_void_p);
|
|
166
|
+
if (funcs.error) {
|
|
167
|
+
throw new Error("errno not available: " + funcs.error);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (process.platform === "win32") {
|
|
171
|
+
funcs._set(value);
|
|
172
|
+
} else {
|
|
173
|
+
const ptr = funcs._location();
|
|
174
|
+
writeValue(ptr, c_int32, value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Initializes Windows error functions (lazy loading).
|
|
180
|
+
*
|
|
181
|
+
* Loads kernel32.dll functions for Windows error handling.
|
|
182
|
+
* Only available on Windows platform.
|
|
183
|
+
*
|
|
184
|
+
* @param {Function} WinDLL - WinDLL class reference
|
|
185
|
+
* @param {Object} c_uint32 - c_uint32 type reference
|
|
186
|
+
* @param {Object} c_void - c_void type reference
|
|
187
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
188
|
+
* @returns {Object} Windows error functions object
|
|
189
|
+
* @private
|
|
190
|
+
*/
|
|
191
|
+
function _initWinError(WinDLL, c_uint32, c_void, c_void_p) {
|
|
192
|
+
if (_win_error_funcs) return _win_error_funcs;
|
|
193
|
+
|
|
194
|
+
if (process.platform !== "win32") {
|
|
195
|
+
_win_error_funcs = { error: "Windows only" };
|
|
196
|
+
return _win_error_funcs;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
const kernel32 = new WinDLL("kernel32.dll");
|
|
201
|
+
_win_error_funcs = {
|
|
202
|
+
GetLastError: kernel32.func("GetLastError", c_uint32, []),
|
|
203
|
+
SetLastError: kernel32.func("SetLastError", c_void, [c_uint32]),
|
|
204
|
+
FormatMessageW: kernel32.func("FormatMessageW", c_uint32, [c_uint32, c_void_p, c_uint32, c_uint32, c_void_p, c_uint32, c_void_p]),
|
|
205
|
+
_lib: kernel32,
|
|
206
|
+
};
|
|
207
|
+
} catch (e) {
|
|
208
|
+
_win_error_funcs = { error: e.message };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return _win_error_funcs;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Gets the last Windows error code (GetLastError).
|
|
216
|
+
*
|
|
217
|
+
* **Windows Only**: This function is only available on Windows.
|
|
218
|
+
*
|
|
219
|
+
* **Python ctypes Compatibility**:
|
|
220
|
+
* Direct equivalent to Python's `ctypes.GetLastError()`.
|
|
221
|
+
*
|
|
222
|
+
* @param {Function} WinDLL - WinDLL class reference
|
|
223
|
+
* @param {Object} c_uint32 - c_uint32 type reference
|
|
224
|
+
* @param {Object} c_void - c_void type reference
|
|
225
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
226
|
+
* @returns {number} Windows error code
|
|
227
|
+
* @throws {Error} If not on Windows or kernel32.dll unavailable
|
|
228
|
+
*
|
|
229
|
+
* @example Get Windows error after failed API call
|
|
230
|
+
* ```javascript
|
|
231
|
+
* import { WinDLL, GetLastError } from 'node-ctypes';
|
|
232
|
+
*
|
|
233
|
+
* const kernel32 = new WinDLL('kernel32.dll');
|
|
234
|
+
* const CreateFileW = kernel32.func('CreateFileW', ...);
|
|
235
|
+
*
|
|
236
|
+
* const handle = CreateFileW(...);
|
|
237
|
+
* if (handle === -1) {
|
|
238
|
+
* const err = GetLastError();
|
|
239
|
+
* console.log(`Windows error code: ${err}`);
|
|
240
|
+
* }
|
|
241
|
+
* ```
|
|
242
|
+
*/
|
|
243
|
+
export function GetLastError(WinDLL, c_uint32, c_void, c_void_p) {
|
|
244
|
+
const funcs = _initWinError(WinDLL, c_uint32, c_void, c_void_p);
|
|
245
|
+
if (funcs.error) {
|
|
246
|
+
throw new Error("GetLastError not available: " + funcs.error);
|
|
247
|
+
}
|
|
248
|
+
return funcs.GetLastError();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Sets the last Windows error code (SetLastError).
|
|
253
|
+
*
|
|
254
|
+
* **Windows Only**: This function is only available on Windows.
|
|
255
|
+
*
|
|
256
|
+
* **Python ctypes Compatibility**:
|
|
257
|
+
* Direct equivalent to Python's `ctypes.SetLastError()`.
|
|
258
|
+
*
|
|
259
|
+
* @param {number} code - Error code to set
|
|
260
|
+
* @param {Function} WinDLL - WinDLL class reference
|
|
261
|
+
* @param {Object} c_uint32 - c_uint32 type reference
|
|
262
|
+
* @param {Object} c_void - c_void type reference
|
|
263
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
264
|
+
* @throws {Error} If not on Windows or kernel32.dll unavailable
|
|
265
|
+
*
|
|
266
|
+
* @example Clear Windows error before call
|
|
267
|
+
* ```javascript
|
|
268
|
+
* import { SetLastError } from 'node-ctypes';
|
|
269
|
+
*
|
|
270
|
+
* // Clear error before Windows API call
|
|
271
|
+
* SetLastError(0);
|
|
272
|
+
* const result = some_win_api();
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
export function SetLastError(code, WinDLL, c_uint32, c_void, c_void_p) {
|
|
276
|
+
const funcs = _initWinError(WinDLL, c_uint32, c_void, c_void_p);
|
|
277
|
+
if (funcs.error) {
|
|
278
|
+
throw new Error("SetLastError not available: " + funcs.error);
|
|
279
|
+
}
|
|
280
|
+
funcs.SetLastError(code);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Formats a Windows error code into a human-readable message.
|
|
285
|
+
*
|
|
286
|
+
* **Windows Only**: This function is only available on Windows.
|
|
287
|
+
*
|
|
288
|
+
* **Python ctypes Compatibility**:
|
|
289
|
+
* Direct equivalent to Python's `ctypes.FormatError()`.
|
|
290
|
+
*
|
|
291
|
+
* @param {number} [code] - Error code (default: GetLastError())
|
|
292
|
+
* @param {Function} WinDLL - WinDLL class reference
|
|
293
|
+
* @param {Function} alloc - alloc function reference
|
|
294
|
+
* @param {Object} c_uint32 - c_uint32 type reference
|
|
295
|
+
* @param {Object} c_void - c_void type reference
|
|
296
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
297
|
+
* @returns {string} Formatted error message
|
|
298
|
+
* @throws {Error} If not on Windows or kernel32.dll unavailable
|
|
299
|
+
*
|
|
300
|
+
* @example Format current Windows error
|
|
301
|
+
* ```javascript
|
|
302
|
+
* import { FormatError } from 'node-ctypes';
|
|
303
|
+
*
|
|
304
|
+
* const result = some_win_api();
|
|
305
|
+
* if (!result) {
|
|
306
|
+
* const message = FormatError();
|
|
307
|
+
* console.log(`Error: ${message}`);
|
|
308
|
+
* }
|
|
309
|
+
* ```
|
|
310
|
+
*
|
|
311
|
+
* @example Format specific error code
|
|
312
|
+
* ```javascript
|
|
313
|
+
* const message = FormatError(5); // Access denied
|
|
314
|
+
* console.log(message); // "Access is denied."
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
export function FormatError(code, WinDLL, alloc, c_uint32, c_void, c_void_p) {
|
|
318
|
+
const funcs = _initWinError(WinDLL, c_uint32, c_void, c_void_p);
|
|
319
|
+
if (funcs.error) {
|
|
320
|
+
throw new Error("FormatError not available: " + funcs.error);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (code === undefined) {
|
|
324
|
+
code = funcs.GetLastError();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
|
|
328
|
+
const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
|
|
329
|
+
|
|
330
|
+
const bufSize = 512;
|
|
331
|
+
const buf = alloc(bufSize * 2); // Wide chars
|
|
332
|
+
|
|
333
|
+
const len = funcs.FormatMessageW(
|
|
334
|
+
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
335
|
+
null,
|
|
336
|
+
code,
|
|
337
|
+
0, // Default language
|
|
338
|
+
buf,
|
|
339
|
+
bufSize,
|
|
340
|
+
null,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
if (len === 0) {
|
|
344
|
+
return `Unknown error ${code}`;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Convert from UTF-16LE to string
|
|
348
|
+
return buf.toString("utf16le", 0, len * 2).replace(/\r?\n$/, "");
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Creates an Error object from a Windows error code.
|
|
353
|
+
*
|
|
354
|
+
* **Windows Only**: This function is only available on Windows.
|
|
355
|
+
*
|
|
356
|
+
* The returned Error object has an additional `winerror` property containing
|
|
357
|
+
* the numeric error code.
|
|
358
|
+
*
|
|
359
|
+
* **Python ctypes Compatibility**:
|
|
360
|
+
* Direct equivalent to Python's `ctypes.WinError()`.
|
|
361
|
+
*
|
|
362
|
+
* @param {number} [code] - Error code (default: GetLastError())
|
|
363
|
+
* @param {Function} WinDLL - WinDLL class reference
|
|
364
|
+
* @param {Function} alloc - alloc function reference
|
|
365
|
+
* @param {Object} c_uint32 - c_uint32 type reference
|
|
366
|
+
* @param {Object} c_void - c_void type reference
|
|
367
|
+
* @param {Object} c_void_p - c_void_p type reference
|
|
368
|
+
* @returns {Error} Error object with formatted message and winerror property
|
|
369
|
+
*
|
|
370
|
+
* @example Throw WinError on failure
|
|
371
|
+
* ```javascript
|
|
372
|
+
* import { WinDLL, WinError } from 'node-ctypes';
|
|
373
|
+
*
|
|
374
|
+
* const kernel32 = new WinDLL('kernel32.dll');
|
|
375
|
+
* const CreateFileW = kernel32.func('CreateFileW', ...);
|
|
376
|
+
*
|
|
377
|
+
* const handle = CreateFileW(...);
|
|
378
|
+
* if (handle === -1) {
|
|
379
|
+
* throw WinError(); // Throws Error with formatted message
|
|
380
|
+
* }
|
|
381
|
+
* ```
|
|
382
|
+
*
|
|
383
|
+
* @example Check specific error code
|
|
384
|
+
* ```javascript
|
|
385
|
+
* try {
|
|
386
|
+
* const result = some_win_api();
|
|
387
|
+
* if (!result) throw WinError();
|
|
388
|
+
* } catch (err) {
|
|
389
|
+
* if (err.winerror === 5) {
|
|
390
|
+
* console.log('Access denied');
|
|
391
|
+
* }
|
|
392
|
+
* }
|
|
393
|
+
* ```
|
|
394
|
+
*/
|
|
395
|
+
export function WinError(code, WinDLL, alloc, c_uint32, c_void, c_void_p) {
|
|
396
|
+
if (code === undefined) {
|
|
397
|
+
code = GetLastError(WinDLL, c_uint32, c_void, c_void_p);
|
|
398
|
+
}
|
|
399
|
+
const msg = FormatError(code, WinDLL, alloc, c_uint32, c_void, c_void_p);
|
|
400
|
+
const err = new Error(`[WinError ${code}] ${msg}`);
|
|
401
|
+
err.winerror = code;
|
|
402
|
+
return err;
|
|
403
|
+
}
|