koffi 2.6.8 → 2.6.10

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/CHANGELOG.md CHANGED
@@ -4,13 +4,21 @@
4
4
 
5
5
  ### Koffi 2.6
6
6
 
7
- #### Koffi 2.6.8 (2023-11-24)
7
+ #### Koffi 2.6.10 (2023-11-29)
8
+
9
+ - Protect GetLastError() value from Node.js and V8 on Windows
10
+
11
+ #### Koffi 2.6.9 (2023-11-25)
8
12
 
9
13
  - Search in DLL directory for additional dependencies on Windows
10
14
  - Ignore prototype properties when making structs or unions
11
15
  - Show detected version of Node when not adequate
12
16
  - Minor documentation fixes
13
17
 
18
+ ```{warning}
19
+ Loading Win32 system libraries can fail in Koffi 2.6.8, skip this version.
20
+ ```
21
+
14
22
  #### Koffi 2.6.6 (2023-10-28)
15
23
 
16
24
  - Better handle errors while making struct or union types
@@ -280,7 +288,7 @@ Pre-built binaries don't work correctly in Koffi 2.5.13 to 2.5.15, skip those ve
280
288
  - Avoid CNoke dependency
281
289
  - Clear out development dependencies from package.json
282
290
 
283
- #### Koffi 2.3.1 (2023-01-3O)
291
+ #### Koffi 2.3.1 (2023-01-30)
284
292
 
285
293
  - Error out when trying to use ambiguous `void *` arguments (input and/or output)
286
294
  - Adjust TypeScript definitions ([@insraq](https://github.com/insraq))
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/index.js CHANGED
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.6.8",
382
- stable: "2.6.8",
381
+ version: "2.6.10",
382
+ stable: "2.6.10",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
package/indirect.js CHANGED
@@ -378,8 +378,8 @@ var require_package = __commonJS({
378
378
  "build/dist/src/koffi/package.json"(exports2, module2) {
379
379
  module2.exports = {
380
380
  name: "koffi",
381
- version: "2.6.8",
382
- stable: "2.6.8",
381
+ version: "2.6.10",
382
+ stable: "2.6.10",
383
383
  description: "Fast and simple C FFI (foreign function interface) for Node.js",
384
384
  keywords: [
385
385
  "foreign",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koffi",
3
- "version": "2.6.8",
4
- "stable": "2.6.8",
3
+ "version": "2.6.10",
4
+ "stable": "2.6.10",
5
5
  "description": "Fast and simple C FFI (foreign function interface) for Node.js",
6
6
  "keywords": [
7
7
  "foreign",
@@ -577,6 +577,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
577
577
  teb->StackLimit = limit;
578
578
  teb->DeallocationStack = dealloc;
579
579
  teb->GuaranteedStackBytes = guaranteed;
580
+
581
+ instance->last_error = teb->LastErrorValue;
580
582
  };
581
583
 
582
584
  // Adjust stack limits so SEH works correctly
@@ -585,6 +587,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
585
587
  teb->StackLimit = mem->stack0.ptr;
586
588
  teb->DeallocationStack = mem->stack0.ptr;
587
589
  teb->GuaranteedStackBytes = 0;
590
+
591
+ teb->LastErrorValue = instance->last_error;
588
592
  #endif
589
593
 
590
594
  #define PERFORM_CALL(Suffix) \
@@ -239,6 +239,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
239
239
  teb->StackLimit = limit;
240
240
  teb->DeallocationStack = dealloc;
241
241
  teb->GuaranteedStackBytes = guaranteed;
242
+
243
+ instance->last_error = teb->LastErrorValue;
242
244
  };
243
245
 
244
246
  // Adjust stack limits so SEH works correctly
@@ -248,6 +250,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
248
250
  teb->DeallocationStack = mem->stack0.ptr;
249
251
  teb->GuaranteedStackBytes = 0;
250
252
 
253
+ teb->LastErrorValue = instance->last_error;
254
+
251
255
  #define PERFORM_CALL(Suffix) \
252
256
  ([&]() { \
253
257
  auto ret = (func->forward_fp ? ForwardCallX ## Suffix(native, new_sp, &old_sp) \
@@ -336,6 +336,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
336
336
  teb->StackLimit = limit;
337
337
  teb->DeallocationStack = dealloc;
338
338
  teb->GuaranteedStackBytes = guaranteed;
339
+
340
+ instance->last_error = teb->LastErrorValue;
339
341
  };
340
342
 
341
343
  // Adjust stack limits so SEH works correctly
@@ -344,6 +346,8 @@ void CallData::Execute(const FunctionInfo *func, void *native)
344
346
  teb->StackLimit = mem->stack0.ptr;
345
347
  teb->DeallocationStack = mem->stack0.ptr;
346
348
  teb->GuaranteedStackBytes = 0;
349
+
350
+ teb->LastErrorValue = instance->last_error;
347
351
  #endif
348
352
 
349
353
  #define PERFORM_CALL(Suffix) \
@@ -1639,42 +1639,6 @@ static Napi::Value UnloadLibrary(const Napi::CallbackInfo &info)
1639
1639
  return env.Undefined();
1640
1640
  }
1641
1641
 
1642
- #ifdef _WIN32
1643
- static HANDLE LoadWindowsLibrary(Napi::Env env, const char *path)
1644
- {
1645
- BlockAllocator temp_alloc;
1646
-
1647
- DWORD flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
1648
-
1649
- Span<const char> filename = NormalizePath(path, GetWorkingDirectory(), &temp_alloc);
1650
- Span<wchar_t> filename_w = AllocateSpan<wchar_t>(&temp_alloc, filename.len + 1);
1651
-
1652
- if (ConvertUtf8ToWin32Wide(filename, filename_w) < 0)
1653
- return nullptr;
1654
-
1655
- HMODULE module = LoadLibraryExW(filename_w.ptr, nullptr, flags);
1656
-
1657
- if (!module) {
1658
- if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
1659
- int process = GetSelfMachine();
1660
- int dll = GetDllMachine(filename_w.ptr);
1661
-
1662
- if (process >= 0 && dll >= 0 && dll != process) {
1663
- ThrowError<Napi::Error>(env, "Cannot load '%1' DLL in '%2' process",
1664
- WindowsMachineNames.FindValue(dll, "Unknown"),
1665
- WindowsMachineNames.FindValue(process, "Unknown"));
1666
- return nullptr;
1667
- }
1668
- }
1669
-
1670
- ThrowError<Napi::Error>(env, "Failed to load shared library: %1", GetWin32ErrorString());
1671
- return nullptr;
1672
- }
1673
-
1674
- return module;
1675
- }
1676
- #endif
1677
-
1678
1642
  static Napi::Value LoadSharedLibrary(const Napi::CallbackInfo &info)
1679
1643
  {
1680
1644
  Napi::Env env = info.Env();
@@ -286,6 +286,8 @@ struct InstanceData {
286
286
  #ifdef _WIN32
287
287
  void *main_stack_max;
288
288
  void *main_stack_min;
289
+
290
+ uint32_t last_error = 0;
289
291
  #endif
290
292
 
291
293
  BucketArray<BlockAllocator> encode_allocators;
@@ -67,6 +67,49 @@ const HashMap<int, const char *> WindowsMachineNames = {
67
67
  { 0x169, "MIPS little-endian WCE v2" }
68
68
  };
69
69
 
70
+ HANDLE LoadWindowsLibrary(Napi::Env env, Span<const char> path)
71
+ {
72
+ BlockAllocator temp_alloc;
73
+
74
+ Span<wchar_t> filename_w = AllocateSpan<wchar_t>(&temp_alloc, path.len + 1);
75
+
76
+ if (ConvertUtf8ToWin32Wide(path, filename_w) < 0)
77
+ return nullptr;
78
+
79
+ HMODULE module = LoadLibraryW(filename_w.ptr);
80
+
81
+ if (!module) {
82
+ DWORD flags = LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR;
83
+
84
+ Span<const char> filename = NormalizePath(path, GetWorkingDirectory(), &temp_alloc);
85
+ Span<wchar_t> filename_w = AllocateSpan<wchar_t>(&temp_alloc, filename.len + 1);
86
+
87
+ if (ConvertUtf8ToWin32Wide(filename, filename_w) < 0)
88
+ return nullptr;
89
+
90
+ module = LoadLibraryExW(filename_w.ptr, nullptr, flags);
91
+ }
92
+
93
+ if (!module) {
94
+ if (GetLastError() == ERROR_BAD_EXE_FORMAT) {
95
+ int process = GetSelfMachine();
96
+ int dll = GetDllMachine(filename_w.ptr);
97
+
98
+ if (process >= 0 && dll >= 0 && dll != process) {
99
+ ThrowError<Napi::Error>(env, "Cannot load '%1' DLL in '%2' process",
100
+ WindowsMachineNames.FindValue(dll, "Unknown"),
101
+ WindowsMachineNames.FindValue(process, "Unknown"));
102
+ return nullptr;
103
+ }
104
+ }
105
+
106
+ ThrowError<Napi::Error>(env, "Failed to load shared library: %1", GetWin32ErrorString());
107
+ return nullptr;
108
+ }
109
+
110
+ return module;
111
+ }
112
+
70
113
  // Fails silently on purpose
71
114
  static bool ReadAt(HANDLE h, int32_t offset, void *buf, int len)
72
115
  {
@@ -72,9 +72,11 @@ struct TEB {
72
72
  void *ExceptionList;
73
73
  void *StackBase;
74
74
  void *StackLimit;
75
- char _pad1[5216];
75
+ char _pad1[80];
76
+ unsigned long LastErrorValue;
77
+ char _pad2[5132];
76
78
  void *DeallocationStack;
77
- char _pad2[712];
79
+ char _pad3[712];
78
80
  uint32_t GuaranteedStackBytes;
79
81
  };
80
82
  static_assert(RG_OFFSET_OF(TEB, DeallocationStack) == 0x1478);
@@ -86,9 +88,11 @@ struct TEB {
86
88
  void *ExceptionList;
87
89
  void *StackBase;
88
90
  void *StackLimit;
89
- char _pad1[3584];
91
+ char _pad1[40];
92
+ unsigned long LastErrorValue;
93
+ char _pad2[3540];
90
94
  void *DeallocationStack;
91
- char _pad2[360];
95
+ char _pad3[360];
92
96
  uint32_t GuaranteedStackBytes;
93
97
  };
94
98
  static_assert(RG_OFFSET_OF(TEB, DeallocationStack) == 0xE0C);
@@ -111,6 +115,8 @@ static inline TEB *GetTEB()
111
115
 
112
116
  extern const HashMap<int, const char *> WindowsMachineNames;
113
117
 
118
+ void *LoadWindowsLibrary(Napi::Env env, Span<const char> path); // Returns HANDLE
119
+
114
120
  int GetSelfMachine();
115
121
  int GetDllMachine(const wchar_t *filename);
116
122