@bun-win32/core 1.0.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 +64 -0
- package/index.ts +6 -0
- package/package.json +50 -0
- package/runtime/extensions.ts +210 -0
- package/structs/Win32.ts +78 -0
- package/types/Win32.ts +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# @bun-win32/core
|
|
2
|
+
|
|
3
|
+
Shared base class, runtime extensions, and fundamental Win32 types for `@bun-win32` packages.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@bun-win32/core` provides the foundation that all `@bun-win32` DLL packages build on:
|
|
8
|
+
|
|
9
|
+
- **`Win32` base class** — Abstract class that handles lazy `dlopen` loading and symbol memoization. Every DLL package (`kernel32`, `user32`, etc.) extends this class.
|
|
10
|
+
- **Runtime extensions** — Installs a `.ptr` getter on all `ArrayBuffer`, `Buffer`, `DataView`, and typed array prototypes, giving direct access to native pointers for Bun FFI calls.
|
|
11
|
+
- **Win32 type aliases** — Strongly-typed aliases (`HANDLE`, `DWORD`, `LPVOID`, `BOOL`, etc.) that map Win32 C types to their TypeScript equivalents.
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- [Bun](https://bun.sh) runtime
|
|
16
|
+
- Windows 10 or later
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
bun add @bun-win32/core
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
> You typically do not need to install this directly — it is pulled in as a dependency of each DLL package.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
### Extending `Win32` for a new DLL
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { FFIType, type FFIFunction } from 'bun:ffi';
|
|
32
|
+
import { Win32 } from '@bun-win32/core';
|
|
33
|
+
|
|
34
|
+
class MyDll extends Win32 {
|
|
35
|
+
protected static override name = 'mydll.dll';
|
|
36
|
+
protected static override readonly Symbols = {
|
|
37
|
+
MyFunction: { args: [FFIType.u32], returns: FFIType.i32 },
|
|
38
|
+
} as const satisfies Record<string, FFIFunction>;
|
|
39
|
+
|
|
40
|
+
public static MyFunction(value: number): number {
|
|
41
|
+
return MyDll.Load('MyFunction')(value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Runtime pointer extensions
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import '@bun-win32/core';
|
|
50
|
+
|
|
51
|
+
const buffer = new Uint8Array([1, 2, 3]);
|
|
52
|
+
nativeFunction(buffer.ptr, buffer.length);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Win32 type aliases
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import type { DWORD, HANDLE, BOOL } from '@bun-win32/core';
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Notes
|
|
62
|
+
|
|
63
|
+
- This package is a dependency of all `@bun-win32` DLL packages.
|
|
64
|
+
- Windows only. Bun runtime required.
|
package/index.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Stev Peifer <stev@bell.net>",
|
|
3
|
+
"description": "Shared base class, runtime extensions, and fundamental Win32 types for @bun-win32 packages.",
|
|
4
|
+
"devDependencies": {
|
|
5
|
+
"@types/bun": "latest"
|
|
6
|
+
},
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.ts"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"module": "index.ts",
|
|
12
|
+
"name": "@bun-win32/core",
|
|
13
|
+
"peerDependencies": {
|
|
14
|
+
"typescript": "^5"
|
|
15
|
+
},
|
|
16
|
+
"private": false,
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/ObscuritySRL/bun-win32/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/ObscuritySRL/bun-win32#readme",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git://github.com/ObscuritySRL/bun-win32.git",
|
|
24
|
+
"directory": "packages/core"
|
|
25
|
+
},
|
|
26
|
+
"type": "module",
|
|
27
|
+
"version": "1.0.1",
|
|
28
|
+
"main": "./index.ts",
|
|
29
|
+
"keywords": [
|
|
30
|
+
"bun",
|
|
31
|
+
"ffi",
|
|
32
|
+
"win32",
|
|
33
|
+
"windows",
|
|
34
|
+
"bindings",
|
|
35
|
+
"typescript",
|
|
36
|
+
"dll",
|
|
37
|
+
"core"
|
|
38
|
+
],
|
|
39
|
+
"files": [
|
|
40
|
+
"index.ts",
|
|
41
|
+
"runtime/*.ts",
|
|
42
|
+
"structs/*.ts",
|
|
43
|
+
"types/*.ts",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"sideEffects": false,
|
|
47
|
+
"engines": {
|
|
48
|
+
"bun": ">=1.1.0"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { type Pointer, ptr } from 'bun:ffi';
|
|
2
|
+
|
|
3
|
+
declare global {
|
|
4
|
+
/**
|
|
5
|
+
* Adds a native pointer property to all ArrayBuffer, Buffer, DataView, and TypedArray types.
|
|
6
|
+
*
|
|
7
|
+
* The `ptr` property returns a native pointer usable with Bun FFI.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const arr = new Uint8Array([1, 2, 3]);
|
|
12
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
interface ArrayBuffer {
|
|
16
|
+
/**
|
|
17
|
+
* Native pointer to ArrayBuffer memory for Bun FFI.
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const buf = new ArrayBuffer(8);
|
|
21
|
+
* nativeFunction(buf.ptr, buf.byteLength);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
readonly ptr: Pointer;
|
|
25
|
+
}
|
|
26
|
+
interface BigInt64Array {
|
|
27
|
+
/**
|
|
28
|
+
* Native pointer to BigInt64Array memory for Bun FFI.
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* const arr = new BigInt64Array([1n, 2n]);
|
|
32
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
readonly ptr: Pointer;
|
|
36
|
+
}
|
|
37
|
+
interface BigUint64Array {
|
|
38
|
+
/**
|
|
39
|
+
* Native pointer to BigUint64Array memory for Bun FFI.
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* const arr = new BigUint64Array([1n, 2n]);
|
|
43
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
readonly ptr: Pointer;
|
|
47
|
+
}
|
|
48
|
+
interface Buffer {
|
|
49
|
+
/**
|
|
50
|
+
* Native pointer to Buffer memory for Bun FFI.
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const buf = Buffer.from([1, 2, 3]);
|
|
54
|
+
* nativeFunction(buf.ptr, buf.length);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
readonly ptr: Pointer;
|
|
58
|
+
}
|
|
59
|
+
interface DataView {
|
|
60
|
+
/**
|
|
61
|
+
* Native pointer to DataView memory for Bun FFI.
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* const view = new DataView(new ArrayBuffer(4));
|
|
65
|
+
* nativeFunction(view.ptr, view.byteLength);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
readonly ptr: Pointer;
|
|
69
|
+
}
|
|
70
|
+
interface Float32Array {
|
|
71
|
+
/**
|
|
72
|
+
* Native pointer to Float32Array memory for Bun FFI.
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const arr = new Float32Array([1, 2, 3]);
|
|
76
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
readonly ptr: Pointer;
|
|
80
|
+
}
|
|
81
|
+
interface Float64Array {
|
|
82
|
+
/**
|
|
83
|
+
* Native pointer to Float64Array memory for Bun FFI.
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* const arr = new Float64Array([1, 2, 3]);
|
|
87
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
readonly ptr: Pointer;
|
|
91
|
+
}
|
|
92
|
+
interface Int16Array {
|
|
93
|
+
/**
|
|
94
|
+
* Native pointer to Int16Array memory for Bun FFI.
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const arr = new Int16Array([1, 2, 3]);
|
|
98
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
readonly ptr: Pointer;
|
|
102
|
+
}
|
|
103
|
+
interface Int32Array {
|
|
104
|
+
/**
|
|
105
|
+
* Native pointer to Int32Array memory for Bun FFI.
|
|
106
|
+
* @example
|
|
107
|
+
* ```ts
|
|
108
|
+
* const arr = new Int32Array([1, 2, 3]);
|
|
109
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
readonly ptr: Pointer;
|
|
113
|
+
}
|
|
114
|
+
interface Int8Array {
|
|
115
|
+
/**
|
|
116
|
+
* Native pointer to Int8Array memory for Bun FFI.
|
|
117
|
+
* @example
|
|
118
|
+
* ```ts
|
|
119
|
+
* const arr = new Int8Array([1, 2, 3]);
|
|
120
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
readonly ptr: Pointer;
|
|
124
|
+
}
|
|
125
|
+
interface SharedArrayBuffer {
|
|
126
|
+
/**
|
|
127
|
+
* Native pointer to SharedArrayBuffer memory for Bun FFI.
|
|
128
|
+
* @example
|
|
129
|
+
* ```ts
|
|
130
|
+
* const buf = new SharedArrayBuffer(8);
|
|
131
|
+
* nativeFunction(buf.ptr, buf.byteLength);
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
readonly ptr: Pointer;
|
|
135
|
+
}
|
|
136
|
+
interface Uint16Array {
|
|
137
|
+
/**
|
|
138
|
+
* Native pointer to Uint16Array memory for Bun FFI.
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* const arr = new Uint16Array([1, 2, 3]);
|
|
142
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
readonly ptr: Pointer;
|
|
146
|
+
}
|
|
147
|
+
interface Uint32Array {
|
|
148
|
+
/**
|
|
149
|
+
* Native pointer to Uint32Array memory for Bun FFI.
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* const arr = new Uint32Array([1, 2, 3]);
|
|
153
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
readonly ptr: Pointer;
|
|
157
|
+
}
|
|
158
|
+
interface Uint8Array {
|
|
159
|
+
/**
|
|
160
|
+
* Native pointer to Uint8Array memory for Bun FFI.
|
|
161
|
+
* @example
|
|
162
|
+
* ```ts
|
|
163
|
+
* const arr = new Uint8Array([1, 2, 3]);
|
|
164
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
readonly ptr: Pointer;
|
|
168
|
+
}
|
|
169
|
+
interface Uint8ClampedArray {
|
|
170
|
+
/**
|
|
171
|
+
* Native pointer to Uint8ClampedArray memory for Bun FFI.
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* const arr = new Uint8ClampedArray([1, 2, 3]);
|
|
175
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
readonly ptr: Pointer;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Installs the `ptr` property on all supported binary view prototypes.
|
|
184
|
+
*
|
|
185
|
+
* The property is non-enumerable and non-configurable. The getter calls `ptr(this)`.
|
|
186
|
+
*/
|
|
187
|
+
const constructors = [ArrayBuffer, BigInt64Array, BigUint64Array, Buffer, DataView, Float32Array, Float64Array, Int16Array, Int32Array, Int8Array, SharedArrayBuffer, Uint16Array, Uint32Array, Uint8Array, Uint8ClampedArray] as const;
|
|
188
|
+
|
|
189
|
+
constructors.forEach(
|
|
190
|
+
({ prototype }) =>
|
|
191
|
+
!Object.getOwnPropertyDescriptor(prototype, 'ptr') &&
|
|
192
|
+
Object.defineProperty(prototype, 'ptr', {
|
|
193
|
+
configurable: false,
|
|
194
|
+
enumerable: false,
|
|
195
|
+
/**
|
|
196
|
+
* Returns a native pointer to the underlying memory.
|
|
197
|
+
* @returns Native pointer for Bun FFI.
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* const arr = new Uint8Array([1, 2, 3]);
|
|
201
|
+
* nativeFunction(arr.ptr, arr.length);
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
get(this): Pointer {
|
|
205
|
+
return ptr(this);
|
|
206
|
+
},
|
|
207
|
+
}),
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
export {};
|
package/structs/Win32.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { type FFIFunction, dlopen } from 'bun:ffi';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for lazy-loaded Win32 DLL FFI bindings.
|
|
5
|
+
*
|
|
6
|
+
* Subclasses set `name` and `Symbols`, then call `Load` in their public
|
|
7
|
+
* methods to bind individual exports on first use. For bulk, up-front binding
|
|
8
|
+
* use `Preload`.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* class Kernel32 extends Win32 {
|
|
13
|
+
* protected static override name = 'kernel32.dll';
|
|
14
|
+
* protected static override readonly Symbols = {
|
|
15
|
+
* GetTickCount64: { args: [], returns: FFIType.u64 },
|
|
16
|
+
* } as const satisfies Record<string, FFIFunction>;
|
|
17
|
+
*
|
|
18
|
+
* public static GetTickCount64(): bigint {
|
|
19
|
+
* return Kernel32.Load('GetTickCount64')();
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export class Win32 {
|
|
25
|
+
protected static readonly Symbols: Record<string, FFIFunction> = {};
|
|
26
|
+
protected static name: string;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Lazily binds a single DLL export and memoizes it on the subclass.
|
|
30
|
+
*
|
|
31
|
+
* If the symbol has already been bound (property is non-configurable), this is a no-op.
|
|
32
|
+
* Subsequent calls go directly through the memoized native function.
|
|
33
|
+
*
|
|
34
|
+
* @param method Exact export name from `Symbols`.
|
|
35
|
+
* @returns The bound native function.
|
|
36
|
+
*/
|
|
37
|
+
protected static Load(method: string) {
|
|
38
|
+
if (Object.getOwnPropertyDescriptor(this, method)?.configurable === false) {
|
|
39
|
+
return (this as any)[method];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const library = dlopen(this.name, { [method]: this.Symbols[method]! });
|
|
43
|
+
const propertyDescriptor = {
|
|
44
|
+
configurable: false,
|
|
45
|
+
value: library.symbols[method],
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(this, method, propertyDescriptor);
|
|
49
|
+
|
|
50
|
+
return (this as any)[method];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Eagerly binds multiple DLL exports at once.
|
|
55
|
+
*
|
|
56
|
+
* Pass a subset of method names to bind only what you need for hot paths; when omitted,
|
|
57
|
+
* all symbols declared in `Symbols` are bound. Already-bound symbols are skipped.
|
|
58
|
+
*
|
|
59
|
+
* @param methods Optional list of export names to bind.
|
|
60
|
+
*/
|
|
61
|
+
public static Preload(methods?: string[]): void {
|
|
62
|
+
methods ??= Object.keys(this.Symbols);
|
|
63
|
+
|
|
64
|
+
const symbols = Object.fromEntries(
|
|
65
|
+
methods.filter((method) => Object.getOwnPropertyDescriptor(this, method)?.configurable !== false).map((method) => [method, this.Symbols[method]!]), //
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const library = dlopen(this.name, symbols);
|
|
69
|
+
|
|
70
|
+
const propertyDescriptorMap = Object.fromEntries(
|
|
71
|
+
Object.entries(library.symbols).map(([key, value]) => [key, { configurable: false, value }]), //
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
Object.defineProperties(this, propertyDescriptorMap);
|
|
75
|
+
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
package/types/Win32.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Pointer } from 'bun:ffi';
|
|
2
|
+
|
|
3
|
+
// ── Scalar types (number) ───────────────────────────────────────────────────
|
|
4
|
+
|
|
5
|
+
export type ACCESS_MASK = number;
|
|
6
|
+
export type BOOL = number;
|
|
7
|
+
export type BOOLEAN = number;
|
|
8
|
+
export type BYTE = number;
|
|
9
|
+
export type CHAR = number;
|
|
10
|
+
export type DWORD = number;
|
|
11
|
+
export type HRESULT = LONG;
|
|
12
|
+
export type INT = number;
|
|
13
|
+
export type LONG = number;
|
|
14
|
+
export type SHORT = number;
|
|
15
|
+
export type UINT = number;
|
|
16
|
+
export type ULONG = number;
|
|
17
|
+
export type USHORT = number;
|
|
18
|
+
export type WCHAR = number;
|
|
19
|
+
export type WORD = number;
|
|
20
|
+
|
|
21
|
+
// ── 64-bit types (bigint) ───────────────────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
export type DWORD_PTR = bigint;
|
|
24
|
+
export type HANDLE = bigint;
|
|
25
|
+
export type HINSTANCE = bigint;
|
|
26
|
+
export type HMODULE = bigint;
|
|
27
|
+
export type HWND = bigint;
|
|
28
|
+
export type INT_PTR = bigint;
|
|
29
|
+
export type LONG_PTR = bigint;
|
|
30
|
+
export type SIZE_T = bigint;
|
|
31
|
+
export type UINT_PTR = bigint;
|
|
32
|
+
export type ULONG_PTR = bigint;
|
|
33
|
+
|
|
34
|
+
// ── Derived types ───────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
export type LPARAM = LONG_PTR;
|
|
37
|
+
export type LRESULT = LONG_PTR;
|
|
38
|
+
export type WPARAM = UINT_PTR;
|
|
39
|
+
|
|
40
|
+
// ── Common pointer types ────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
export type LPBOOL = Pointer;
|
|
43
|
+
export type LPBYTE = Pointer;
|
|
44
|
+
export type LPCSTR = Pointer;
|
|
45
|
+
export type LPCVOID = Pointer;
|
|
46
|
+
export type LPCWSTR = Pointer;
|
|
47
|
+
export type LPDWORD = Pointer;
|
|
48
|
+
export type LPHANDLE = Pointer;
|
|
49
|
+
export type LPSECURITY_ATTRIBUTES = Pointer;
|
|
50
|
+
export type LPSTR = Pointer;
|
|
51
|
+
export type LPVOID = Pointer;
|
|
52
|
+
export type LPWSTR = Pointer;
|
|
53
|
+
export type PBYTE = Pointer;
|
|
54
|
+
export type PDWORD = Pointer;
|
|
55
|
+
export type PHANDLE = Pointer;
|
|
56
|
+
export type PULONG = Pointer;
|
|
57
|
+
export type PVOID = Pointer;
|
|
58
|
+
|
|
59
|
+
// ── Special ─────────────────────────────────────────────────────────────────
|
|
60
|
+
|
|
61
|
+
export type NULL = null;
|
|
62
|
+
export type VOID = void;
|