/
ostypes_win.jsm
348 lines (318 loc) · 15.5 KB
/
ostypes_win.jsm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
var EXPORTED_SYMBOLS = ['ostypes'];
// no need to define core or import cutils as all the globals of the worker who importScripts'ed it are availble here
if (ctypes.voidptr_t.size == 4 /* 32-bit */) {
var is64bit = false;
} else if (ctypes.voidptr_t.size == 8 /* 64-bit */) {
var is64bit = true;
} else {
throw new Error('huh??? not 32 or 64 bit?!?!');
}
var ifdef_UNICODE = true;
var winTypes = function() {
// ABIs
if (is64bit) {
this.CALLBACK_ABI = ctypes.default_abi;
this.ABI = ctypes.default_abi;
} else {
this.CALLBACK_ABI = ctypes.stdcall_abi;
this.ABI = ctypes.winapi_abi;
}
// SIMPLE TYPES // based on ctypes.BLAH // as per WinNT.h etc
this.BOOL = ctypes.bool;
this.BYTE = ctypes.unsigned_char;
this.CHAR = ctypes.char;
this.DWORD = ctypes.unsigned_long; // IntSafe.h defines it as: // typedef unsigned long DWORD; // so maybe can change this to ctypes.unsigned_long // i was always using `ctypes.uint32_t`
this.INT = ctypes.int;
this.INT_PTR = is64bit ? ctypes.int64_t : ctypes.int;
this.LONG = ctypes.long;
this.LONG_PTR = is64bit ? ctypes.int64_t : ctypes.long; // i left it at what i copied pasted it as but i thought it would be `ctypes.intptr_t`
this.LPCVOID = ctypes.voidptr_t;
this.LPVOID = ctypes.voidptr_t;
this.NTSTATUS = ctypes.long; // https://msdn.microsoft.com/en-us/library/cc230357.aspx // typedef long NTSTATUS;
this.PVOID = ctypes.voidptr_t;
this.RM_APP_TYPE = ctypes.unsigned_int; // i dont know im just guessing, i cant find a typedef that makes sense to me: https://msdn.microsoft.com/en-us/library/windows/desktop/aa373670%28v=vs.85%29.aspx
this.UINT = ctypes.unsigned_int;
this.UINT_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
this.ULONG = ctypes.unsigned_long;
this.ULONG_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_long; // i left it at what i copied pasted it as, but i thought it was this: `ctypes.uintptr_t`
this.USHORT = ctypes.unsigned_short;
this.VARIANT_BOOL = ctypes.short;
this.VARTYPE = ctypes.unsigned_short;
this.VOID = ctypes.void_t;
this.WCHAR = ctypes.jschar;
this.WORD = ctypes.unsigned_short;
// ADVANCED TYPES // as per how it was defined in WinNT.h // defined by "simple types"
this.ATOM = this.WORD;
this.BOOLEAN = this.BYTE; // http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx
this.COLORREF = this.DWORD; // when i copied/pasted there was this comment next to this: // 0x00bbggrr
this.DWORD_PTR = this.ULONG_PTR;
this.HANDLE = this.PVOID;
this.HRESULT = this.LONG;
this.LPCSTR = this.CHAR.ptr; // typedef __nullterminated CONST CHAR *LPCSTR;
this.LPCWSTR = this.WCHAR.ptr;
this.LPARAM = this.LONG_PTR;
this.LPDWORD = this.DWORD.ptr;
this.LPSTR = this.CHAR.ptr;
this.LPWSTR = this.WCHAR.ptr;
this.LRESULT = this.LONG_PTR;
this.OLECHAR = this.WCHAR; // typedef WCHAR OLECHAR; // https://github.com/wine-mirror/wine/blob/bdeb761357c87d41247e0960f71e20d3f05e40e6/include/wtypes.idl#L286
this.PLONG = this.LONG.ptr;
this.PULONG = this.ULONG.ptr;
this.PCWSTR = this.WCHAR.ptr;
this.SIZE_T = this.ULONG_PTR;
this.SYSTEM_INFORMATION_CLASS = this.INT; // i think due to this search: http://stackoverflow.com/questions/28858849/where-is-system-information-class-defined
this.TCHAR = ifdef_UNICODE ? this.WCHAR : ctypes.char; // when i copied pasted this it was just ctypes.char and had this comment: // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t = jschar // in "advanced types" section even though second half is ctypes.char because it has something that is advanced, which is the first part, this.WCHAR
this.WPARAM = this.UINT_PTR;
// SUPER ADVANCED TYPES // defined by "advanced types"
this.HBITMAP = this.HANDLE;
this.HBRUSH = this.HANDLE;
this.HDC = this.HANDLE;
this.HFONT = this.HANDLE;
this.HGDIOBJ = this.HANDLE;
this.HHOOK = this.HANDLE;
this.HICON = this.HANDLE;
this.HINSTANCE = this.HANDLE;
this.HKEY = this.HANDLE;
this.HMENU = this.HANDLE;
this.HWND = this.HANDLE;
this.LPCOLESTR = this.OLECHAR.ptr; // typedef [string] const OLECHAR *LPCOLESTR; // https://github.com/wine-mirror/wine/blob/bdeb761357c87d41247e0960f71e20d3f05e40e6/include/wtypes.idl#L288
this.LPCTSTR = ifdef_UNICODE ? this.LPCWSTR : this.LPCSTR;
this.LPHANDLE = this.HANDLE.ptr;
this.LPOLESTR = this.OLECHAR.ptr; // typedef [string] OLECHAR *LPOLESTR; // https://github.com/wine-mirror/wine/blob/bdeb761357c87d41247e0960f71e20d3f05e40e6/include/wtypes.idl#L287 // http://stackoverflow.com/a/1607335/1828637 // LPOLESTR is usually to be allocated with CoTaskMemAlloc()
this.LPTSTR = ifdef_UNICODE ? this.LPWSTR : this.LPSTR;
// SUPER DUPER ADVANCED TYPES // defined by "super advanced types"
this.HCURSOR = this.HICON;
this.HMODULE = this.HINSTANCE;
this.WNDENUMPROC = ctypes.FunctionType(this.CALLBACK_ABI, this.BOOL, [this.HWND, this.LPARAM]); // "super advanced type" because its highest type is `this.HWND` which is "advanced type"
// inaccrurate types - i know these are something else but setting them to voidptr_t or something just works and all the extra work isnt needed
this.PCIDLIST_ABSOLUTE = ctypes.voidptr_t; // https://github.com/west-mt/ssbrowser/blob/452e21d728706945ad00f696f84c2f52e8638d08/chrome/content/modules/WindowsShortcutService.jsm#L115
this.PIDLIST_ABSOLUTE = ctypes.voidptr_t;
this.WIN32_FIND_DATA = ctypes.voidptr_t;
this.WINOLEAPI = ctypes.voidptr_t; // i guessed on this one
// STRUCTURES
// SIMPLE STRUCTS // based on any of the types above
this.FILE_NOTIFY_INFORMATION = ctypes.StructType('FILE_NOTIFY_INFORMATION', [
{ NextEntryOffset: this.DWORD },
{ Action: this.DWORD },
{ FileNameLength: this.DWORD },
{ FileName: ctypes.ArrayType(this.WCHAR, OS.Constants.Win.MAX_PATH) }, // not null terminated
]);
this.GUID = ctypes.StructType('GUID', [
{ 'Data1': this.ULONG },
{ 'Data2': this.USHORT },
{ 'Data3': this.USHORT },
{ 'Data4': this.BYTE.array(8) }
]);
this.OVERLAPPED = ctypes.StructType('_OVERLAPPED', [ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684342%28v=vs.85%29.aspx
{ Internal: this.ULONG_PTR },
{ InternalHigh: this.ULONG_PTR },
{ Pointer: this.PVOID }, // union { struct { DWORD Offset; DWORD OffsetHigh; }; PVOID Pointer; };
{ hEvent: this.HANDLE },
]);
this.PROPVARIANT = ctypes.StructType('PROPVARIANT', [ // http://msdn.microsoft.com/en-us/library/windows/desktop/bb773381%28v=vs.85%29.aspx
{ 'vt': this.VARTYPE }, // constants for this are available at MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072%28v=vs.85%29.aspx
{ 'wReserved1': this.WORD },
{ 'wReserved2': this.WORD },
{ 'wReserved3': this.WORD },
{ 'pwszVal': this.LPWSTR } // union, i just use pwszVal so I picked that one // for InitPropVariantFromString // when using this see notes on MSDN doc page chat of PROPVARIANT ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa380072%28v=vs.85%29.aspx )this guy says: "VT_LPWSTR must be allocated with CoTaskMemAlloc :: (Presumably this also applies to VT_LPSTR) VT_LPWSTR is described as being a string pointer with no information on how it is allocated. You might then assume that the PROPVARIANT doesn't own the string and just has a pointer to it, but you'd be wrong. In fact, the string stored in a VT_LPWSTR PROPVARIANT must be allocated using CoTaskMemAlloc and be freed using CoTaskMemFree. Evidence for this: Look at what the inline InitPropVariantFromString function does: It sets a VT_LPWSTR using SHStrDupW, which in turn allocates the string using CoTaskMemAlloc. Knowing that, it's obvious that PropVariantClear is expected to free the string using CoTaskMemFree. I can't find this explicitly documented anywhere, which is a shame, but step through this code in a debugger and you can confirm that the string is freed by PropVariantClear: ```#include <Propvarutil.h> int wmain(int argc, TCHAR *lpszArgv[]) { PROPVARIANT pv; InitPropVariantFromString(L"Moo", &pv); ::PropVariantClear(&pv); }``` If you put some other kind of string pointer into a VT_LPWSTR PROPVARIANT your program is probably going to crash."
]);
this.SECURITY_ATTRIBUTES = ctypes.StructType('_SECURITY_ATTRIBUTES', [ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa379560%28v=vs.85%29.aspx
{ 'nLength': this.DWORD },
{ 'lpSecurityDescriptor': this.LPVOID },
{ 'bInheritHandle': this.BOOL }
]);
// ADVANCED STRUCTS // based on "simple structs" to be defined first
this.CLSID = this.GUID;
this.PGUID = this.GUID.ptr;
this.IID = this.GUID;
this.LPOVERLAPPED = this.OVERLAPPED.ptr;
this.LPSECURITY_ATTRIBUTES = this.SECURITY_ATTRIBUTES.ptr;
// FUNCTION TYPES
this.FileIOCompletionRoutine = ctypes.FunctionType(this.CALLBACK_ABI, this.VOID, [this.DWORD, this.DWORD, this.LPOVERLAPPED]);
// STRUCTS USING FUNC TYPES
this.LPOVERLAPPED_COMPLETION_ROUTINE = this.FileIOCompletionRoutine.ptr;
}
var winInit = function() {
var self = this;
this.IS64BIT = is64bit;
this.TYPE = new winTypes();
// CONSTANTS
this.CONST = {
FILE_ACTION_ADDED: 0x00000001,
FILE_ACTION_REMOVED: 0x00000002,
FILE_ACTION_MODIFIED: 0x00000003,
FILE_ACTION_RENAMED_OLD_NAME: 0x00000004,
FILE_ACTION_RENAMED_NEW_NAME: 0x00000005,
FILE_FLAG_BACKUP_SEMANTICS: 33554432,
FILE_FLAG_OVERLAPPED: 0x40000000,
FILE_LIST_DIRECTORY: 0x0001,
FILE_NOTIFY_CHANGE_FILE_NAME: 0x00000001,
FILE_NOTIFY_CHANGE_DIR_NAME: 0x00000002,
FILE_NOTIFY_CHANGE_ATTRIBUTES: 0x00000004,
FILE_NOTIFY_CHANGE_SIZE: 0x00000008,
FILE_NOTIFY_CHANGE_LAST_WRITE: 0x00000010,
FILE_NOTIFY_CHANGE_LAST_ACCESS: 0x00000020,
FILE_NOTIFY_CHANGE_CREATION: 0x00000040,
FILE_NOTIFY_CHANGE_SECURITY: 0x00000100,
FILE_SHARE_DELETE: 4,
FILE_SHARE_READ: 1,
FILE_SHARE_WRITE: 2,
GENERIC_READ: 31, // from https://msdn.microsoft.com/en-us/library/windows/desktop/aa374892%28v=vs.85%29.aspx i have no idea where i got 0x80000000 from // 0x80000000,
INVALID_HANDLE_VALUE: -1,
MB_OK: 0,
OPEN_EXISTING: 3
};
var _lib = {}; // cache for lib
var lib = function(path) {
//ensures path is in lib, if its in lib then its open, if its not then it adds it to lib and opens it. returns lib
//path is path to open library
//returns lib so can use straight away
if (!(path in _lib)) {
//need to open the library
//default it opens the path, but some things are special like libc in mac is different then linux or like x11 needs to be located based on linux version
switch (path) {
default:
try {
_lib[path] = ctypes.open(path);
} catch (e) {
//console.error('Integration Level 1: Could not get open path:', path, 'e:' + e);
throw new Error('Integration Level 1: Could not get open path:"' + path + '" e: "' + e + '"');
}
}
}
return _lib[path];
};
// start - function declares
var _api = {};
this.API = function(declaration) { // it means ensureDeclared and return declare. if its not declared it declares it. else it returns the previously declared.
if (!(declaration in _api)) {
_api[declaration] = preDec[declaration](); //if declaration is not in preDec then dev messed up
}
return _api[declaration];
};
// start - predefine your declares here
var preDec = { //stands for pre-declare (so its just lazy stuff) //this must be pre-populated by dev // do it alphabateized by key so its ez to look through
CreateFile: function() {
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858%28v=vs.85%29.aspx
* HANDLE WINAPI CreateFile(
* __in_ LPCTSTR lpFileName,
* __in_ DWORD dwDesiredAccess,
* __in_ DWORD dwShareMode,
* __in_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
* __in_ DWORD dwCreationDisposition,
* __in_ DWORD dwFlagsAndAttributes,
* __in_opt_ HANDLE hTemplateFile
* );
*/
return lib('kernel32').declare('CreateFileW', self.TYPE.ABI,
self.TYPE.HANDLE, // return
self.TYPE.LPCTSTR, // lpFileName
self.TYPE.DWORD, // dwDesiredAccess
self.TYPE.DWORD, // dwShareMode
self.TYPE.LPSECURITY_ATTRIBUTES, // lpSecurityAttributes
self.TYPE.DWORD, // dwCreationDisposition
self.TYPE.DWORD, // dwFlagsAndAttributes
self.TYPE.HANDLE // hTemplateFile
);
},
CreateEvent: function() {
/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682396%28v=vs.85%29.aspx
* HANDLE WINAPI CreateEvent(
* __in_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
* __in_ BOOL bManualReset,
* __in_ BOOL bInitialState,
* __in_opt_ LPCTSTR lpName
* );
*/
return lib('kernel32').declare(ifdef_UNICODE ? 'CreateEventW' : 'CreateEventA', self.TYPE.ABI,
self.TYPE.HANDLE, // return
self.TYPE.LPSECURITY_ATTRIBUTES, // lpEventAttributes
self.TYPE.BOOL, // bManualReset
self.TYPE.BOOL, // bInitialState
self.TYPE.LPCTSTR // lpName
);
},
GetOverlappedResult: function() {
/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683209%28v=vs.85%29.aspx
* BOOL WINAPI GetOverlappedResult(
* __in_ HANDLE hFile,
* __in_ LPOVERLAPPED lpOverlapped,
* __out_ LPDWORD lpNumberOfBytesTransferred,
* __in_ BOOL bWait
* );
*/
return lib('kernel32').declare('GetOverlappedResult', self.TYPE.ABI,
self.TYPE.BOOL, // return
self.TYPE.HANDLE, // hFile
self.TYPE.LPOVERLAPPED, // lpOverlapped
self.TYPE.LPDWORD, // lpNumberOfBytesTransferred
self.TYPE.BOOL // bWait
);
},
MessageBox: function() {
/*
int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
);
*/
return lib('user32').declare('MessageBoxW', self.TYPE.ABI,
self.TYPE.INT, // return
self.TYPE.HWND, // hWnd
self.TYPE.LPCTSTR, // lpText
self.TYPE.LPCTSTR, // lpCaption
self.TYPE.UINT // uType
);
},
ReadDirectoryChanges: function() {
/* https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx
* BOOL WINAPI ReadDirectoryChangesW(
* __in_ HANDLE hDirectory,
* __out_ LPVOID lpBuffer,
* __in_ DWORD nBufferLength,
* __in_ BOOL bWatchSubtree,
* __in_ DWORD dwNotifyFilter,
* __out_opt_ LPDWORD lpBytesReturned,
* __inout_opt_ LPOVERLAPPED lpOverlapped,
* __in_opt_ LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
* );
*/
return lib('kernel32').declare('ReadDirectoryChangesW', self.TYPE.ABI,
self.TYPE.BOOL, // return
self.TYPE.HANDLE, // hDirectory,
self.TYPE.LPVOID, // lpBuffer,
self.TYPE.DWORD, // nBufferLength,
self.TYPE.BOOL, // bWatchSubtree,
self.TYPE.DWORD, // dwNotifyFilter,
self.TYPE.LPDWORD, // lpBytesReturned,
self.TYPE.LPOVERLAPPED, // lpOverlapped,
self.TYPE.LPOVERLAPPED_COMPLETION_ROUTINE // lpCompletionRoutine
);
}
};
// end - predefine your declares here
// end - function declares
this.HELPER = {
checkHRESULT: function(hr /*HRESULT*/, funcName /*jsStr*/) {
if(parseInt(cutils.jscGetDeepest(hr)) < 0) {
throw new Error('HRESULT ' + hr + ' returned from function ' + funcName);
}
},
CLSIDFromString: function(lpsz /*jsStr*/) {
// lpsz should look like: "886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99" no quotes
var GUID_or_IID = self.TYPE.GUID();
var pieces = lpsz.split('-');
GUID_or_IID.Data1 = parseInt(pieces[0], 16);
GUID_or_IID.Data2 = parseInt(pieces[1], 16);
GUID_or_IID.Data3 = parseInt(pieces[2], 16);
var piece34 = pieces[3] + '' + pieces[4];
for (var i=0; i<8; i++) {
GUID_or_IID.Data4[i] = parseInt(piece34.substr(i*2,2), 16);
};
return GUID_or_IID;
}
};
}
var ostypes = new winInit();