├── .gitattributes
├── .gitignore
├── AdvApi32_ffi.lua
├── BCrypt.lua
├── BCryptUtils.lua
├── FileSystem.lua
├── GDI32.lua
├── Kernel32.lua
├── LICENSE.txt
├── NCryptUtils.lua
├── NativeSocket.lua
├── NetStream.lua
├── README.md
├── SocketUtils.lua
├── StopWatch.lua
├── TimedLoop.lua
├── User32.lua
├── User32Window.lua
├── WTypes.lua
├── WinBase.lua
├── WinCrypt.lua
├── WinError.lua
├── WinNT.lua
├── WinSock_Utils.lua
├── WindowStation.lua
├── dbghelp_ffi.lua
├── gdi32_ffi.lua
├── kernel32_ffi.lua
├── ncrypt.lua
├── sslprovider.lua
├── sspi.lua
├── stringutils.lua
├── tests
├── DaytimeClient.lua
├── DaytimeServer.lua
├── TcpServer.lua
├── test_BCrypt.lua
├── test_DaytimeClient.lua
├── test_DaytimeServer.lua
├── test_DbgHelp.lua
├── test_NCrypt.lua
├── test_TcpServer.lua
├── test_library_load.lua
├── test_sslprovider.lua
├── test_tcp_socket.lua
├── test_timedloop.lua
└── test_timers-raw.lua
├── user32_ffi.lua
└── win_socket.lua
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #################
2 | ## Eclipse
3 | #################
4 |
5 | *.pydevproject
6 | .project
7 | .metadata
8 | bin/
9 | tmp/
10 | *.tmp
11 | *.bak
12 | *.swp
13 | *~.nib
14 | local.properties
15 | .classpath
16 | .settings/
17 | .loadpath
18 |
19 | # External tool builders
20 | .externalToolBuilders/
21 |
22 | # Locally stored "Eclipse launch configurations"
23 | *.launch
24 |
25 | # CDT-specific
26 | .cproject
27 |
28 | # PDT-specific
29 | .buildpath
30 |
31 |
32 | #################
33 | ## Visual Studio
34 | #################
35 |
36 | ## Ignore Visual Studio temporary files, build results, and
37 | ## files generated by popular Visual Studio add-ons.
38 |
39 | # User-specific files
40 | *.suo
41 | *.user
42 | *.sln.docstates
43 |
44 | # Build results
45 | [Dd]ebug/
46 | [Rr]elease/
47 | *_i.c
48 | *_p.c
49 | *.ilk
50 | *.meta
51 | *.obj
52 | *.pch
53 | *.pdb
54 | *.pgc
55 | *.pgd
56 | *.rsp
57 | *.sbr
58 | *.tlb
59 | *.tli
60 | *.tlh
61 | *.tmp
62 | *.vspscc
63 | .builds
64 | *.dotCover
65 |
66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this
67 | #packages/
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 |
76 | # Visual Studio profiler
77 | *.psess
78 | *.vsp
79 |
80 | # ReSharper is a .NET coding add-in
81 | _ReSharper*
82 |
83 | # Installshield output folder
84 | [Ee]xpress
85 |
86 | # DocProject is a documentation generator add-in
87 | DocProject/buildhelp/
88 | DocProject/Help/*.HxT
89 | DocProject/Help/*.HxC
90 | DocProject/Help/*.hhc
91 | DocProject/Help/*.hhk
92 | DocProject/Help/*.hhp
93 | DocProject/Help/Html2
94 | DocProject/Help/html
95 |
96 | # Click-Once directory
97 | publish
98 |
99 | # Others
100 | [Bb]in
101 | [Oo]bj
102 | sql
103 | TestResults
104 | *.Cache
105 | ClientBin
106 | stylecop.*
107 | ~$*
108 | *.dbmdl
109 | Generated_Code #added for RIA/Silverlight projects
110 |
111 | # Backup & report files from converting an old project file to a newer
112 | # Visual Studio version. Backup files are not needed, because we have git ;-)
113 | _UpgradeReport_Files/
114 | Backup*/
115 | UpgradeLog*.XML
116 |
117 |
118 |
119 | ############
120 | ## Windows
121 | ############
122 |
123 | # Windows image file caches
124 | Thumbs.db
125 |
126 | # Folder config file
127 | Desktop.ini
128 |
129 |
130 | #############
131 | ## Python
132 | #############
133 |
134 | *.py[co]
135 |
136 | # Packages
137 | *.egg
138 | *.egg-info
139 | dist
140 | build
141 | eggs
142 | parts
143 | bin
144 | var
145 | sdist
146 | develop-eggs
147 | .installed.cfg
148 |
149 | # Installer logs
150 | pip-log.txt
151 |
152 | # Unit test / coverage reports
153 | .coverage
154 | .tox
155 |
156 | #Translations
157 | *.mo
158 |
159 | #Mr Developer
160 | .mr.developer.cfg
161 |
162 | # Mac crap
163 | .DS_Store
164 |
--------------------------------------------------------------------------------
/AdvApi32_ffi.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require ("ffi");
3 |
4 | require ("WinBase")
5 |
6 | ffi.cdef[[
7 | typedef struct _SID_IDENTIFIER_AUTHORITY {
8 | BYTE Value[6];
9 | } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
10 | ]]
11 |
12 | ffi.cdef[[
13 | BOOL AllocateAndInitializeSid(
14 | PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
15 | BYTE nSubAuthorityCount,
16 | DWORD dwSubAuthority0,
17 | DWORD dwSubAuthority1,
18 | DWORD dwSubAuthority2,
19 | DWORD dwSubAuthority3,
20 | DWORD dwSubAuthority4,
21 | DWORD dwSubAuthority5,
22 | DWORD dwSubAuthority6,
23 | DWORD dwSubAuthority7,
24 | PSID *pSid
25 | );
26 |
27 | BOOL ConvertSidToStringSid(PSID Sid, LPTSTR *StringSid);
28 |
29 | BOOL ConvertStringSidToSid(LPCTSTR StringSid, PSID *Sid);
30 |
31 | BOOL CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid);
32 |
33 | BOOL CreateProcessAsUser(
34 | HANDLE hToken,
35 | LPCTSTR lpApplicationName,
36 | LPTSTR lpCommandLine,
37 | LPSECURITY_ATTRIBUTES lpProcessAttributes,
38 | LPSECURITY_ATTRIBUTES lpThreadAttributes,
39 | BOOL bInheritHandles,
40 | DWORD dwCreationFlags,
41 | LPVOID lpEnvironment,
42 | LPCTSTR lpCurrentDirectory,
43 | LPSTARTUPINFO lpStartupInfo,
44 | LPPROCESS_INFORMATION lpProcessInformation
45 | );
46 |
47 | BOOL CreateProcessWithLogonW(
48 | LPCWSTR lpUsername,
49 | LPCWSTR lpDomain,
50 | LPCWSTR lpPassword,
51 | DWORD dwLogonFlags,
52 | LPCWSTR lpApplicationName,
53 | LPWSTR lpCommandLine,
54 | DWORD dwCreationFlags,
55 | LPVOID lpEnvironment,
56 | LPCWSTR lpCurrentDirectory,
57 | LPSTARTUPINFOW lpStartupInfo,
58 | LPPROCESS_INFORMATION lpProcessInfo);
59 |
60 | BOOL EqualSid(PSID pSid1, PSID pSid2);
61 |
62 | PVOID FreeSid(PSID pSid);
63 |
64 | DWORD GetLengthSid(PSID pSid);
65 |
66 | PSID_IDENTIFIER_AUTHORITY GetSidIdentifierAuthority(PSID pSid);
67 |
68 | DWORD GetSidLengthRequired(UCHAR nSubAuthorityCount);
69 |
70 | PDWORD GetSidSubAuthority(PSID pSid, DWORD nSubAuthority);
71 |
72 | PUCHAR GetSidSubAuthorityCount(PSID pSid);
73 |
74 | BOOL InitializeSid(PSID Sid, PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, BYTE nSubAuthorityCount);
75 |
76 | BOOL IsValidSid(PSID pSid);
77 |
78 | BOOL LogonUser(
79 | LPTSTR lpszUsername,
80 | LPTSTR lpszDomain,
81 | LPTSTR lpszPassword,
82 | DWORD dwLogonType,
83 | DWORD dwLogonProvider,
84 | PHANDLE phToken);
85 |
86 | BOOL LookupAccountName(LPCTSTR lpSystemName,
87 | LPCTSTR lpAccountName,
88 | PSID Sid,
89 | LPDWORD cbSid,
90 | LPTSTR ReferencedDomainName,
91 | LPDWORD cchReferencedDomainName,
92 | PSID_NAME_USE peUse);
93 |
94 | BOOL LookupAccountSid(LPCTSTR lpSystemName,
95 | PSID lpSid,
96 | LPTSTR lpName,
97 | LPDWORD cchName,
98 | LPTSTR lpReferencedDomainName,
99 | LPDWORD cchReferencedDomainName,
100 | PSID_NAME_USE peUse);
101 | ]]
102 |
--------------------------------------------------------------------------------
/BCryptUtils.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 |
3 | local BCrypt = require "BCrypt"
4 | local stringutils = require("stringutils")
5 |
6 |
7 |
8 |
9 | BCryptKey = ffi.typeof("BCryptKey");
10 | BCryptKey_mt = {
11 | __gc = function(self)
12 | local status = BCrypt.Lib.BCryptDestroyKey(self.Handle)
13 | end,
14 |
15 | __index = {
16 | FinalizeKeyPair = function(self)
17 | local status = BCrypt.Lib.BCryptFinalizeKeyPair(self.Handle);
18 |
19 | return status == 0 or nil, status
20 | end,
21 | },
22 | }
23 | BCryptKey = ffi.metatype(BCryptKey, BCryptKey_mt);
24 |
25 |
26 | BCryptHash = ffi.typeof("BCryptHash");
27 | BCryptHash_mt = {
28 | __gc = function(self)
29 | local status = BCrypt.Lib.BCryptDestroyHash(self.Handle);
30 | end,
31 |
32 | __new = function(ct, algorithm)
33 | local phHash = ffi.new("BCRYPT_HASH_HANDLE[1]");
34 | local pbHashObject = nil
35 | local cbHashObject = 0
36 | local pbSecret = nil
37 | local cbSecret = 0
38 | local flags = 0
39 |
40 | local status = BCrypt.Lib.BCryptCreateHash(algorithm.Handle,
41 | phHash,
42 | pbHashObject,
43 | cbHashObject,
44 | pbSecret,
45 | cbSecret,
46 | flags);
47 |
48 | if status ~= 0 then
49 | return nil, status
50 | end
51 |
52 | return ffi.new(ct, phHash[0]);
53 | end,
54 |
55 | __index = {
56 | GetProperty = function(self, name, buffer, size)
57 | local pcbResult = ffi.new("uint32_t[1]")
58 | local buffptr = ffi.cast("uint8_t *", buffer)
59 | local status = BCrypt.Lib.BCryptGetProperty(self.Handle,
60 | name,
61 | buffptr, size,
62 | pcbResult,
63 | 0);
64 |
65 | if status ~= 0 then
66 | print("GetProperty, Error status: ", status);
67 | return nil, status
68 | end
69 |
70 | -- got the result back
71 | -- return it to the user
72 | return buffptr, pcbResult[0]
73 | end,
74 |
75 | GetPropertyBuffer = function(self, name)
76 | local pcbResult = ffi.new("uint32_t[1]")
77 | local status = BCrypt.Lib.BCryptGetProperty(self.Handle,
78 | name,
79 | nil, 0,
80 | pcbResult,
81 | 0);
82 |
83 | if status ~= 0 then
84 | return nil, status
85 | end
86 |
87 | local bytesneeded = pcbResult[0]
88 | local pbOutput = ffi.new("uint8_t[?]", pcbResult[0]);
89 |
90 | return pbOutput, bytesneeded
91 | end,
92 |
93 | GetHashDigestLength = function(self)
94 | local size = ffi.sizeof("int32_t");
95 | local buff = ffi.new("int[1]")
96 | local outbuff, byteswritten = self:GetProperty(BCrypt.BCRYPT_HASH_LENGTH, buff, size)
97 |
98 | --print("GetHashLength: ", outbuff, byteswritten);
99 |
100 | if not outbuff then
101 | return nil, byteswritten
102 | end
103 |
104 | return buff[0];
105 | end,
106 |
107 | Clone = function(self)
108 | local phNewHash = ffi.new("BCRYPT_HASH_HANDLE[1]");
109 | local pbHashObject = nil
110 | local cbHashObject = 0
111 | local pbSecret = nil
112 | local cbSecret = 0
113 | local flags = 0
114 |
115 | local status = BCrypt.Lib.BCryptDuplicateHash(self.Handle,
116 | phNewHash,
117 | pbHashObject,
118 | cbHashObject,
119 | flags);
120 |
121 | if status ~= 0 then
122 | return nil, status
123 | end
124 |
125 | return ffi.new("BCryptHash", phNewHash[0]);
126 | end,
127 |
128 | HashMore = function(self, chunk, chunksize)
129 | local pbInput = chunk
130 | local cbInput
131 | local flags = 0
132 |
133 | if type(chunk) == "string" then
134 | pbInput = ffi.cast("const uint8_t *", chunk);
135 | if not chunksize then
136 | cbInput = #chunk
137 | end
138 | else
139 | cbInput = cbInput or 0
140 | end
141 |
142 | local status = BCrypt.Lib.BCryptHashData(self.Handle,
143 | pbInput,
144 | cbInput,
145 | flags);
146 |
147 | return status == 0 or nil, status
148 | end,
149 |
150 | Finish = function(self, pbOutput, cbOutput)
151 | local flags = 0
152 | local status = BCrypt.Lib.BCryptFinishHash(self.Handle,
153 | pbOutput,
154 | cbOutput,
155 | flags);
156 |
157 | return status == 0 or nil, status
158 | end,
159 |
160 | CreateDigest = function(self, input, inputLength)
161 | local outlen = self:GetHashDigestLength();
162 | local outbuff = ffi.new("uint8_t[?]", outlen);
163 |
164 | self:HashMore(input);
165 | self:Finish(outbuff, outlen);
166 |
167 | local hex = stringutils.bintohex(outbuff, outlen);
168 |
169 | return hex
170 | end,
171 |
172 | },
173 | }
174 |
175 | BCryptHash = ffi.metatype(BCryptHash, BCryptHash_mt);
176 |
177 |
178 | local BCryptAlgorithm = ffi.typeof("struct BCryptAlgorithm")
179 | local BCryptAlgorithm_mt = {
180 | __gc = function(self)
181 | --print("BCryptAlgorithm: GC")
182 | if self.Handle ~= nil then
183 | BCrypt.Lib.BCryptCloseAlgorithmProvider(self.Handle, 0)
184 | end
185 | end;
186 |
187 | __new = function(ctype, ...)
188 | --print("BCryptAlgorithm: NEW");
189 | local params = {...}
190 | local algoid = params[1]
191 | local impl = params[2]
192 |
193 | if not algoid then
194 | return nil
195 | end
196 |
197 | local lphAlgo = ffi.new("BCRYPT_ALG_HANDLE[1]")
198 | local algoidptr = ffi.cast("const uint16_t *", algoid)
199 | local status = BCrypt.Lib.BCryptOpenAlgorithmProvider(lphAlgo, algoidptr, impl, 0);
200 |
201 | if not BCrypt.BCRYPT_SUCCESS(status) then
202 | print("BCryptAlgorithm(), status: ", status);
203 | return nil
204 | end
205 |
206 | local newone = ffi.new("struct BCryptAlgorithm", lphAlgo[0])
207 | return newone;
208 | end;
209 |
210 | __index = {
211 | -- CreateHash
212 | CreateHash = function(self)
213 | return BCryptHash(self);
214 | end,
215 |
216 | CreateKeyPair = function(self, length, flags)
217 | length = length or 384
218 | flags = flags or 0
219 | local fullKey = ffi.new("BCRYPT_KEY_HANDLE[1]");
220 | local status = BCrypt.Lib.BCryptGenerateKeyPair(self.Handle,
221 | fullKey, length, flags);
222 |
223 | if status ~= 0 then
224 | return nil, status
225 | end
226 |
227 | -- create the key pair
228 | local fullKey = fullKey[0];
229 |
230 | end,
231 | }
232 | };
233 | BCryptAlgorithm = ffi.metatype(BCryptAlgorithm, BCryptAlgorithm_mt);
234 |
235 | CryptUtils = {
236 | BCryptKey = BCryptKey,
237 | BCryptHash = BCryptHash,
238 | BCryptAlgorithm = BCryptAlgorithm,
239 | }
240 |
241 | --[[
242 | Pre allocated Algorithm objects
243 | --]]
244 |
245 | -- Hash Algorithms
246 | CryptUtils.MD2Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_MD2_ALGORITHM);
247 | CryptUtils.MD4Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_MD4_ALGORITHM);
248 | CryptUtils.MD5Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_MD5_ALGORITHM);
249 |
250 | CryptUtils.SHA1Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_SHA1_ALGORITHM);
251 | CryptUtils.SHA256Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_SHA256_ALGORITHM);
252 | CryptUtils.SHA384Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_SHA384_ALGORITHM);
253 | CryptUtils.SHA512Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_SHA512_ALGORITHM);
254 |
255 | -- Random Number Generators
256 | CryptUtils.RNGAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RNG_ALGORITHM);
257 | CryptUtils.RNGFIPS186DSAAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RNG_FIPS186_DSA_ALGORITHM);
258 | CryptUtils.RNGDUALECAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RNG_DUAL_EC_ALGORITHM);
259 |
260 |
261 |
262 | CryptUtils.RSAAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RSA_ALGORITHM);
263 | CryptUtils.RSASignAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RSA_SIGN_ALGORITHM);
264 |
265 | CryptUtils.DHAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_DH_ALGORITHM);
266 | CryptUtils.DSAAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_DSA_ALGORITHM);
267 | CryptUtils.RC2Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RC2_ALGORITHM);
268 | CryptUtils.RC4Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_RC4_ALGORITHM);
269 |
270 | CryptUtils.AESAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_AES_ALGORITHM);
271 | CryptUtils.AESGMACAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_AES_GMAC_ALGORITHM);
272 |
273 | CryptUtils.DESAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_DES_ALGORITHM);
274 | CryptUtils.DESXAlgorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_DESX_ALGORITHM);
275 | CryptUtils.DES3Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_3DES_ALGORITHM);
276 | CryptUtils.DES3_112Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_3DES_112_ALGORITHM);
277 |
278 |
279 | CryptUtils.ECDSA_P256Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDSA_P256_ALGORITHM);
280 | CryptUtils.ECDSA_P384Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDSA_P384_ALGORITHM);
281 | CryptUtils.ECDSA_P521Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDSA_P521_ALGORITHM);
282 | CryptUtils.ECDH_P256Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDH_P256_ALGORITHM);
283 | CryptUtils.ECDH_P384Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDH_P384_ALGORITHM);
284 | CryptUtils.ECDH_P521Algorithm = CryptUtils.BCryptAlgorithm(BCrypt.BCRYPT_ECDH_P521_ALGORITHM);
285 |
286 |
287 |
288 | --[[
289 | Hash Functions
290 | --]]
291 | CryptUtils.Hashes = {
292 | MD2 = CryptUtils.MD2Algorithm:CreateHash();
293 | MD4 = CryptUtils.MD4Algorithm:CreateHash();
294 | MD5 = CryptUtils.MD5Algorithm:CreateHash();
295 |
296 | SHA1 = CryptUtils.SHA1Algorithm:CreateHash();
297 | SHA256 = CryptUtils.SHA256Algorithm:CreateHash();
298 | SHA384 = CryptUtils.SHA384Algorithm:CreateHash();
299 | SHA512 = CryptUtils.SHA512Algorithm:CreateHash();
300 | }
301 |
302 | CryptUtils.MD2 = function(content, len)
303 | return CryptUtils.Hashes.MD2:CreateDigest(content, len);
304 | end
305 |
306 | CryptUtils.MD4 = function(content, len)
307 | return CryptUtils.Hashes.MD4:CreateDigest(content, len);
308 | end
309 |
310 | CryptUtils.MD5 = function(content, len)
311 | return CryptUtils.Hashes.MD5:CreateDigest(content, len);
312 | end
313 |
314 |
315 |
316 | CryptUtils.SHA1 = function(content, len)
317 | return CryptUtils.Hashes.SHA1:CreateDigest(content, len);
318 | end
319 |
320 | CryptUtils.SHA256 = function(content, len)
321 | return CryptUtils.Hashes.SHA256:CreateDigest(content, len);
322 | end
323 |
324 | CryptUtils.SHA384 = function(content, len)
325 | return CryptUtils.Hashes.SHA384:CreateDigest(content, len);
326 | end
327 |
328 | CryptUtils.SHA512 = function(content, len)
329 | return CryptUtils.Hashes.SHA512:CreateDigest(content, len);
330 | end
331 |
332 |
333 |
334 | --[[
335 | Convenience Functions
336 | --]]
337 |
338 | CryptUtils.GetRandomBytes = function(howmany)
339 | howmany = howmany or 4
340 |
341 | local rngBuff = ffi.new("uint8_t[?]", howmany)
342 |
343 | local status = BCrypt.Lib.BCryptGenRandom(nil, rngBuff, howmany, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
344 | if status >= 0 then
345 | return rngBuff, howmany
346 | end
347 |
348 | return nil, status
349 | end
350 |
351 | return CryptUtils
352 |
--------------------------------------------------------------------------------
/FileSystem.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 | require "WTypes"
4 | require "WinBase"
5 | local Kernel32 = require "Kernel32"
6 |
7 | ffi.cdef[[
8 | struct IODevice {
9 | HANDLE Handle;
10 | };
11 | ]]
12 |
13 | local IODevice = ffi.typeof("struct IODevice")
14 | local IODevice_mt = {
15 | __gc = function(self)
16 |
17 | end,
18 |
19 | __index = {
20 | CancelIo = function(self)
21 | end,
22 |
23 | Lock = function(self)
24 | end,
25 |
26 | },
27 | }
28 | ffi.metatype(IODevice, IODevice_mt);
29 |
30 | local modes = {
31 | ["r"] = GENERIC_READ,
32 | ["r+"] = bor(GENERIC_READ, GENERIC_WRITE),
33 | ["w"] = GENERIC_WRITE,
34 | ["w+"] = bor(GENERIC_WRITE, GENERIC_READ),
35 | ["a"] = bor(APPEND, CREAT, GENERIC_WRITE),
36 | ["a+"] = APPEND
37 | }
38 |
39 | local function string_to_access(mode)
40 | return modes[mode] or bor(GENERIC_READ, GENERIC_WRITE);
41 | --[[
42 | if (strcmp(string, "w") == 0)
43 | return O_CREAT | O_TRUNC | O_WRONLY;
44 | if (strcmp(string, "w+") == 0)
45 | return O_CREAT | O_TRUNC | O_RDWR;
46 | if (strcmp(string, "a") == 0)
47 | return O_APPEND | O_CREAT | O_WRONLY;
48 | if (strcmp(string, "a+") == 0)
49 | return O_APPEND | O_CREAT | O_RDWR;
50 | #ifndef _WIN32
51 | if (strcmp(string, "rs") == 0)
52 | return O_RDONLY | O_SYNC;
53 | if (strcmp(string, "rs+") == 0)
54 | return O_RDWR | O_SYNC;
55 | #endif
56 | --]]
57 | end
58 |
59 |
60 | local FileSystem = {
61 | CopyFile = function(src, dest, progress)
62 | end,
63 |
64 | CreateFile = function(filename, access)
65 | local access, mode = string_to_access(access)
66 |
67 | local handle, err = Kernel32.CreateFile(filename,
68 | _In_ DWORD dwDesiredAccess,
69 | _In_ DWORD dwShareMode,
70 | _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
71 | _In_ DWORD dwCreationDisposition,
72 | _In_ DWORD dwFlagsAndAttributes,
73 | _In_opt_ HANDLE hTemplateFile
74 | );
75 | end,
76 |
77 | }
78 |
79 | -- mode_t
80 |
81 | function open()
82 | end
83 |
84 | function close()
85 | end
86 |
87 | function read()
88 | end
89 |
90 | function write()
91 | end
92 |
93 |
94 |
95 | int luv_fs_mkdir(lua_State* L);
96 | int luv_fs_rmdir(lua_State* L);
97 | int luv_fs_readdir(lua_State* L);
98 |
99 | int luv_fs_stat(lua_State* L);
100 | int luv_fs_fstat(lua_State* L);
101 | int luv_fs_lstat(lua_State* L);
102 |
103 | int luv_fs_rename(lua_State* L);
104 | int luv_fs_fsync(lua_State* L);
105 | int luv_fs_fdatasync(lua_State* L);
106 | int luv_fs_ftruncate(lua_State* L);
107 | int luv_fs_sendfile(lua_State* L);
108 |
109 | int luv_fs_chmod(lua_State* L);
110 | int luv_fs_fchmod(lua_State* L);
111 |
112 | int luv_fs_utime(lua_State* L);
113 | int luv_fs_futime(lua_State* L);
114 |
115 | int luv_fs_symlink(lua_State* L);
116 | int luv_fs_readlink(lua_State* L);
117 | int luv_fs_chown(lua_State* L);
118 | int luv_fs_fchown(lua_State* L);
119 |
120 | int luv_fs_link(lua_State* L);
121 | int luv_fs_unlink(lua_State* L);
122 |
--------------------------------------------------------------------------------
/GDI32.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 |
3 |
4 | local GDILib = ffi.load("gdi32");
5 | local gdi32_ffi = require "gdi32_ffi"
6 |
7 |
8 | ffi.cdef[[
9 | typedef struct {
10 | HDC Handle;
11 | } DeviceContext;
12 |
13 | ]]
14 |
15 | DeviceContext = ffi.typeof("DeviceContext");
16 |
17 |
18 |
19 | local GDI32 = {
20 | FFI = gdi32_ffi,
21 |
22 | CreateDC = function(lpszDriver, lpszDevice, lpszOutput, lpInitData)
23 | return DeviceContext(GDILib.CreateDCA(lpszDriver, lpszDevice, lpszOutput, lpInitData));
24 | end,
25 |
26 | CreateCompatibleDC = function(hdc)
27 | return DeviceContext(GDILib.CreateCompatibleDC(hdc));
28 | end,
29 |
30 | CreateDCForDefaultDisplay = function(self)
31 | return DeviceContext(GDILib.CreateDCA("DISPLAY", nil, nil, nil));
32 | end,
33 |
34 | CreateDCForMemory = function()
35 | local displayDC = GDILib.CreateDCA("DISPLAY", nil, nil, nil)
36 | return GDIContext(GDILib.CreateCompatibleDC(displayDC))
37 | end,
38 |
39 | GetDC = function(hWnd)
40 | return DeviceContext(GDILib.GetDC(hWnd));
41 | end,
42 |
43 | SaveDC = function(hdc)
44 | return GDILib.SaveDC(hdc);
45 | end,
46 |
47 | RestoreDC = function(hdc, nSaveDC)
48 | return GDILib.RestoreDC(hdc, nSavedDC);
49 | end,
50 |
51 |
52 | -- Object Management
53 | GetObject = function(hgdiobj, cbBuffer, lpvObject)
54 | return GDILib.GetObjectA(hgdiobj, cbBuffer, lpvObject);
55 | end,
56 |
57 | GetStockObject = function(fnObject)
58 | return GDILib.GetStockObject(fnObject);
59 | end,
60 |
61 |
62 | -- Bitmaps
63 | CreateCompatibleBitmap = function(hdc, nWidth, nHeight)
64 | return GDILib.CreateCompatibleBitmap(hdc, nWidth, nHeight);
65 | end,
66 |
67 | CreateDIBSection = function(hdc, pbmi, iUsage, ppvBits, hSection, dwOffset)
68 | return GDILib.CreateDIBSection(hdc, pbmi, iUsage, ppvBits, hSection, dwOffset);
69 | end,
70 |
71 | }
72 |
73 |
74 |
75 |
76 |
77 | DeviceContext_mt = {
78 | __tostring = function(self)
79 | return string.format("DeviceContext(0x%s)", tostring(self.Handle))
80 | end,
81 |
82 | __index = {
83 | TypeName = "DeviceContext",
84 |
85 | Size = ffi.sizeof("DeviceContext"),
86 |
87 |
88 | CreateCompatibleDC = function(self)
89 | return DeviceContext(GDILib.CreateCompatibleDC(self.Handle))
90 | end,
91 |
92 | CreateCompatibleBitmap = function(self, width, height)
93 | local bm = GDIBitmap(GDILib.CreateCompatibleBitmap(self.Handle,width,height));
94 | bm:Init(self.Handle)
95 |
96 | return bm
97 | end,
98 |
99 |
100 | -- Device Context State
101 | Flush = function(self)
102 | return GDILib.GdiFlush()
103 | end,
104 |
105 | -- Object Management
106 | SelectObject = function(self, gdiobj)
107 | GDILib.SelectObject(self.Handle, gdiobj.Handle)
108 | end,
109 |
110 | SelectStockObject = function(self, objectIndex)
111 | -- First get a handle on the object
112 | local objHandle = GDILib.GetStockObject(objectIndex);
113 |
114 | -- Then select it into the device context
115 | return GDILib.SelectObject(self.Handle, objHandle);
116 | end,
117 |
118 |
119 | -- Drawing Attributes
120 | UseDCBrush = function(self)
121 | self:SelectStockObject(gdi_ffi.DC_BRUSH)
122 | end,
123 |
124 | UseDCPen = function(self)
125 | self:SelectStockObject(gdi_ffi.DC_PEN)
126 | end,
127 |
128 | SetDCBrushColor = function(self, color)
129 | return GDILib.SetDCBrushColor(self.Handle, color)
130 | end,
131 |
132 | SetDCPenColor = function(self, color)
133 | return GDILib.SetDCPenColor(self.Handle, color)
134 | end,
135 |
136 |
137 | -- Drawing routines
138 | MoveTo = function(self, x, y)
139 | local result = GDILib.MoveToEx(self.Handle, x, y, nil);
140 | return result
141 | end,
142 |
143 | MoveToEx = function(self, x, y, lpPoint)
144 | return GDILib.MoveToEx(self.Handle, X, Y, lpPoint);
145 | end,
146 |
147 | SetPixel = function(self, x, y, color)
148 | return GDILib.SetPixel(self.Handle, x, y, color);
149 | end,
150 |
151 | SetPixelV = function(self, x, y, crColor)
152 | return GDILib.SetPixelV(self.Handle, X, Y, crColor);
153 | end,
154 |
155 | LineTo = function(self, xend, yend)
156 | local result = GDILib.LineTo(self.Handle, xend, yend);
157 | return result
158 | end,
159 |
160 | Ellipse = function(self, nLeftRect, nTopRect, nRightRect, nBottomRect)
161 | return GDILib.Ellipse(self.Handle,nLeftRect,nTopRect,nRightRect,nBottomRect);
162 | end,
163 |
164 | Rectangle = function(self, left, top, right, bottom)
165 | return GDILib.Rectangle(self.Handle, left, top, right, bottom);
166 | end,
167 |
168 | RoundRect = function(self, left, top, right, bottom, width, height)
169 | return GDILib.RoundRect(self.Handle, left, top, right, bottom, width, height);
170 | end,
171 |
172 | -- Text Drawing
173 | Text = function(self, txt, x, y)
174 | x = x or 0
175 | y = y or 0
176 | return C.TextOutA(self.Handle, x, y, txt, string.len(txt));
177 | end,
178 |
179 | -- Bitmap drawing
180 | BitBlt = function(self, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, dwRop)
181 | return GDILib.BitBlt(self.Handle,nXDest,nYDest,nWidth,nHeight,hdcSrc,nXSrc,nYSrc,dwRop);
182 | end,
183 |
184 | StretchDIBits = function(self, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc, nSrcWidth, nSrcHeight, lpBits, lpBitsInfo, iUsage, dwRop)
185 | XDest = XDest or 0
186 | YDest = YDest or 0
187 | iUsage = iUsage or 0
188 | dwRop = dwRop or gdi32_ffi.SRCCOPY;
189 |
190 | return GDILib.StretchDIBits(hdc,XDest,YDest,nDestWidth,nDestHeight,XSrc,YSrc,nSrcWidth,nSrcHeight,lpBits,lpBitsInfo,iUsage,dwRop);
191 | end,
192 |
193 | GetDIBits = function(self, hbmp, uStartScan, cScanLines, lpvBits, lpbi, uUsage)
194 | return GDILib.GetDIBits(self.Handle,hbmp,uStartScan,cScanLines,lpvBits,lpbi,uUsage);
195 | end,
196 |
197 | StretchBlt = function(self, img, XDest, YDest,DestWidth,DestHeight)
198 | XDest = XDest or 0
199 | YDest = YDest or 0
200 | DestWidth = DestWidth or img.Width
201 | DestHeight = DestHeight or img.Height
202 |
203 | -- Draw a pixel buffer
204 | local bmInfo = BITMAPINFO();
205 | bmInfo.bmiHeader.biWidth = img.Width;
206 | bmInfo.bmiHeader.biHeight = img.Height;
207 | bmInfo.bmiHeader.biPlanes = 1;
208 | bmInfo.bmiHeader.biBitCount = img.BitsPerElement;
209 | bmInfo.bmiHeader.biClrImportant = 0;
210 | bmInfo.bmiHeader.biClrUsed = 0;
211 | bmInfo.bmiHeader.biCompression = 0;
212 |
213 | self:StretchDIBits(XDest,YDest,DestWidth,DestHeight,
214 | 0,0,img.Width, img.Height,
215 | img.Data,
216 | bmInfo);
217 | end,
218 | }
219 | }
220 | DeviceContext = ffi.metatype(DeviceContext, DeviceContext_mt)
221 |
222 |
223 | ffi.cdef[[
224 |
225 |
226 | typedef struct {
227 | void * Handle;
228 | BITMAP Bitmap;
229 | unsigned char * Pixels;
230 | } GDIBitmap;
231 |
232 |
233 | ]]
234 |
235 |
236 | -- For Color
237 | -- 0x00bbggrr
238 | function RGB(byRed, byGreen, byBlue)
239 | local acolor = lshift(byBlue,16) + lshift(byGreen,8) + byRed;
240 | return acolor;
241 | end
242 |
243 | function GetRValue(c)
244 | return band(c, 0xff)
245 | end
246 |
247 | function GetGValue(c)
248 | return band(rshift(c,8), 0xff)
249 | end
250 |
251 | function GetBValue(c)
252 | return band(rshift(c,16), 0xff)
253 | end
254 |
255 | --
256 | -- This function answers the question:
257 | -- Given:
258 | -- We know the size of the byte boundary we want
259 | -- to align to.
260 | -- Question:
261 | -- How many bytes need to be allocated to ensure we
262 | -- will align to that boundary.
263 | -- Discussion:
264 | -- This comes up in cases where you're allocating a bitmap image
265 | -- for example. It may be a 24-bit image, but you need to ensure
266 | -- that each row can align to a 32-bit boundary. So, we need to
267 | -- essentially scale up the number of bits to match the alignment.
268 | --
269 | local function GetAlignedByteCount(width, bitsperpixel, alignment)
270 |
271 | local bytesperpixel = bitsperpixel / 8;
272 | local stride = band((width * bytesperpixel + (alignment - 1)), bnot(alignment - 1));
273 |
274 | return stride;
275 | end
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 | BITMAP = ffi.typeof("BITMAP")
287 |
288 | GDIBitmap = nil
289 | GDIBitmap_mt = {
290 | __tostring = function(self) return string.format("GDIBitmap(0x%s)", tostring(self.Handle)) end,
291 | __index = {
292 | TypeName = "BITMAP",
293 | Size = ffi.sizeof("GDIBitmap"),
294 | Init = function(self, hdc)
295 | local bmap = ffi.new("BITMAP[1]")
296 | local bmapsize = ffi.sizeof("BITMAP");
297 | C.GetObjectA(self.Handle, bmapsize, bmap)
298 | self.Bitmap = bmap[0]
299 |
300 | end,
301 |
302 | Print = function(self)
303 | print(string.format("Bitmap"))
304 | print(string.format(" type: %d", self.Bitmap.bmType))
305 | print(string.format(" width: %d", self.Bitmap.bmWidth))
306 | print(string.format(" height: %d", self.Bitmap.bmHeight))
307 | print(string.format(" Width Bytes: %d", self.Bitmap.bmWidthBytes))
308 | print(string.format(" Planes: %d", self.Bitmap.bmPlanes))
309 | print(string.format("BitsPerPixel: %d", self.Bitmap.bmBitsPixel));
310 |
311 | end,
312 | }
313 | }
314 | GDIBitmap = ffi.metatype("GDIBitmap", GDIBitmap_mt)
315 |
316 | --
317 | -- GDIDIBSection_mt
318 | --
319 | ffi.cdef[[
320 | typedef struct {
321 | void *Handle;
322 | DeviceContext hDC;
323 | int Width;
324 | int Height;
325 | int BitsPerPixel;
326 | char * Pixels;
327 | BITMAPINFO Info;
328 | } GDIDIBSection;
329 | ]]
330 |
331 | GDIDIBSection = nil
332 | GDIDIBSection_mt = {
333 | __index = {
334 | TypeName = "GDIDIBSection",
335 | Size = ffi.sizeof("GDIDIBSection"),
336 | Init = function(self, width, height, bitsperpixel, alignment)
337 | alignment = alignment or 2
338 | bitsperpixel = bitsperpixel or 32
339 |
340 | self.Width = width
341 | self.Height = height
342 | self.BitsPerPixel = bitsperpixel
343 |
344 |
345 | -- Need to construct a BITMAPINFO structure
346 | -- to describe the image we'll be creating
347 | local bytesPerRow = GetAlignedByteCount(width, bitsperpixel, alignment)
348 | local info = BITMAPINFO();
349 | info.bmiHeader.biWidth = width
350 | info.bmiHeader.biHeight = height
351 | info.bmiHeader.biPlanes = 1
352 | info.bmiHeader.biBitCount = bitsperpixel
353 | info.bmiHeader.biSizeImage = bytesPerRow * height
354 | info.bmiHeader.biClrImportant = 0
355 | info.bmiHeader.biClrUsed = 0
356 | info.bmiHeader.biCompression = 0 -- GDI32.BI_RGB
357 | self.Info = info
358 |
359 | -- Create the DIBSection, using the screen as
360 | -- the source DC
361 | local ddc = GDIContext():CreateForDefaultDisplay().Handle
362 | local DIB_RGB_COLORS = 0
363 | local pixelP = ffi.new("uint8_t *[1]")
364 | self.Handle = GDILib.CreateDIBSection(ddc,
365 | info,
366 | DIB_RGB_COLORS,
367 | pixelP,
368 | nil,
369 | 0);
370 | --print("GDIDIBSection Handle: ", self.Handle)
371 | --self.Pixels = ffi.cast("Ppixel_BGRA_b", pixelP[0])
372 | self.Pixels = pixelP[0]
373 |
374 | -- Create a memory device context
375 | -- and select the DIBSecton handle into it
376 | self.hDC = GDIContext():CreateForMemory()
377 | local selected = GDILib.SelectObject(self.hDC.Handle, self.Handle)
378 |
379 | return self
380 | end,
381 |
382 | Print = function(self)
383 | print("Bits Per Pixel: ", self.BitsPerPixel)
384 | print("Size: ", self.Width, self.Height)
385 | print("Pixels: ", self.Pixels)
386 | end,
387 | }
388 | }
389 | GDIDIBSection = ffi.metatype("GDIDIBSection", GDIDIBSection_mt)
390 |
391 |
392 |
393 | --[[
394 | Function Implementations
395 | --]]
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 | return GDI32
404 |
--------------------------------------------------------------------------------
/Kernel32.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 |
3 | local kernel32_ffi = require"kernel32_ffi"
4 | local Lib = ffi.load("kernel32")
5 |
6 | function GetPerformanceFrequency()
7 | local anum = ffi.new("__int64[1]")
8 | local success = Lib.QueryPerformanceFrequency(anum)
9 | if success == 0 then
10 | return nil
11 | end
12 |
13 | return tonumber(anum[0])
14 | end
15 |
16 | function GetPerformanceCounter()
17 | local anum = ffi.new("__int64[1]")
18 | local success = Lib.QueryPerformanceCounter(anum)
19 | if success == 0 then
20 | return nil
21 | end
22 |
23 | return tonumber(anum[0])
24 | end
25 |
26 | function GetCurrentTickTime()
27 | local frequency = 1/GetPerformanceFrequency();
28 | local currentCount = GetPerformanceCounter();
29 | local seconds = currentCount * frequency;
30 |
31 | return seconds;
32 | end
33 |
34 |
35 | function GetProcAddress(library, funcname)
36 | if not library or not funcname then return nil end
37 |
38 | local lib = ffi.load(library)
39 | local paddr = Lib.GetProcAddress(Lib.GetModuleHandleA(library), funcname)
40 |
41 | if paddr ~= nil then
42 | return paddr
43 | end
44 |
45 | return false, Lib.GetLastError();
46 | end
47 |
48 | function GetCurrentDirectory()
49 | local buffsize = 1024;
50 | local buff = ffi.new("char[1024]");
51 | local err = Lib.GetCurrentDirectoryA(buffsize, buff);
52 |
53 | if err == 0 then
54 | return nil
55 | end
56 |
57 | return ffi.string(buff);
58 | end
59 |
60 | --[[
61 | local function AnsiToUnicode16L(in_Src)
62 | local nsrcBytes = #in_Src
63 |
64 | -- find out how many characters needed
65 | local charsneeded = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, nil, 0);
66 |
67 | if charsneeded < 0 then
68 | return nil;
69 | end
70 |
71 |
72 | local buff = ffi.new("uint16_t[?]", charsneeded+1)
73 |
74 | local charswritten = kernel32.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, buff, charsneeded)
75 | buff[charswritten] = 0
76 |
77 | return ffi.string(buff, (charswritten*2)+1);
78 | end
79 | --]]
80 |
81 | local function AnsiToUnicode16L(in_Src, nsrcBytes)
82 | nsrcBytes = nsrcBytes or #in_Src
83 |
84 | -- find out how many characters needed
85 | local charsneeded = Lib.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, nil, 0);
86 |
87 | if charsneeded < 0 then
88 | return nil;
89 | end
90 |
91 | local buff = ffi.new("uint16_t[?]", charsneeded+1)
92 |
93 | local charswritten = Lib.MultiByteToWideChar(CP_ACP, 0, in_Src, nsrcBytes, buff, charsneeded)
94 | buff[charswritten] = 0
95 |
96 | return buff;
97 | end
98 |
99 | local function Unicode16ToAnsi(in_Src, nsrcBytes)
100 | nsrcBytes = nsrcBytes
101 | local srcShorts = ffi.cast("const uint16_t *", in_Src)
102 |
103 | -- find out how many characters needed
104 | local bytesneeded = Lib.WideCharToMultiByte(CP_ACP, 0, srcShorts, -1, nil, 0, nil, nil);
105 | print("bytesneeded: ", bytesneeded);
106 |
107 | if bytesneeded <= 0 then
108 | return nil;
109 | end
110 |
111 | local buff = ffi.new("uint8_t[?]", bytesneeded+1)
112 | local byteswritten = Lib.WideCharToMultiByte(CP_ACP, 0, srcShorts, -1, buff, bytesneeded, nil, nil);
113 | buff[byteswritten] = 0
114 |
115 | --print("charswritten: ", byteswritten)
116 |
117 | return ffi.string(buff, byteswritten-1);
118 | end
119 |
120 |
121 |
122 | return {
123 | NativeCall = Lib,
124 | GetPerformanceFrequency = GetPerformanceFrequency,
125 | GetPerformanceCounter = GetPerformanceCounter,
126 | GetCurrentTickTime = GetCurrentTickTime,
127 | GetProcAddress = GetProcAddress,
128 | GetCurrentDirectory = GetCurrentDirectoryA,
129 |
130 | AnsiToUnicode16 = AnsiToUnicode16L,
131 | Unicode16ToAnsi = Unicode16ToAnsi,
132 |
133 | }
134 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 William A Adams
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the "Software"),
5 | to deal in the Software without restriction, including without limitation
6 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 | and/or sell copies of the Software, and to permit persons to whom the Software
8 | is furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
15 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
16 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
18 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/NCryptUtils.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | local bit = require "bit"
3 | local bor = bit.bor
4 |
5 | local WinError = require "WinError"
6 |
7 | local NCrypt = require "ncrypt"
8 | local NCLib = ffi.load("ncrypt")
9 | local k32 = require "Kernel32"
10 |
11 | local L = k32.AnsiToUnicode16
12 | local A = k32.Unicode16ToAnsi
13 |
14 | NCryptKeyName = ffi.typeof("NCryptKeyName");
15 | NCryptKeyName_mt = {
16 | __gc = function(self)
17 | NCLib.NCryptFreeBuffer(self);
18 | end,
19 |
20 | }
21 | NCryptKeyName = ffi.metatype(NCryptKeyName, NCryptKeyName_mt);
22 |
23 | ffi.cdef[[
24 | typedef struct {
25 | NCRYPT_PROV_HANDLE Handle;
26 | } NCryptStorageProvider;
27 | ]]
28 |
29 | NCryptStorageProvider = ffi.typeof("NCryptStorageProvider")
30 | NCryptStorageProvider_mt = {
31 | __gc = function(self)
32 | NCLib.NCryptFreeObject(self.Handle);
33 | end,
34 |
35 | __new = function(ct, pszProviderName)
36 | local phProvider = ffi.new("NCRYPT_PROV_HANDLE[1]");
37 | local pszProviderName = nil;
38 |
39 | local status = NCLib.NCryptOpenStorageProvider(phProvider,
40 | pszProviderName, 0);
41 |
42 | if status ~= 0 then
43 | return nil, status
44 | end
45 |
46 | local obj = ffi.new("NCryptStorageProvider", phProvider[0]);
47 |
48 | return obj;
49 | end,
50 |
51 | __index = {
52 | EnumerateAlgorithms = function(self, whichones)
53 | whichones = whichones or bor(
54 | NCrypt.NCRYPT_CIPHER_OPERATION,
55 | NCrypt.NCRYPT_HASH_OPERATION,
56 | NCrypt.NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION,
57 | NCrypt.NCRYPT_SECRET_AGREEMENT_OPERATION,
58 | NCrypt.NCRYPT_SIGNATURE_OPERATION);
59 |
60 | local pdwAlgCount = ffi.new("uint32_t[1]");
61 | local ppAlgList = ffi.new("PNCryptAlgorithmName[1]");
62 |
63 | local status = NCLib.NCryptEnumAlgorithms(self.Handle,
64 | whichones,
65 | pdwAlgCount,
66 | ppAlgList,
67 | 0);
68 |
69 | if status ~= 0 then
70 | return nil, status
71 | end
72 |
73 | -- Create a list with the algoritm
74 | -- names in it
75 | local res = {}
76 | local AlgList = ppAlgList[0];
77 | for i=0,pdwAlgCount[0]-1 do
78 | local entry = {
79 | name = A(AlgList[i].pszName),
80 | class = AlgList[i].dwClass,
81 | operations = AlgList[i].dwAlgOperations,
82 | }
83 | table.insert(res, entry);
84 | end
85 | return res
86 | end,
87 |
88 | IsAlgorithmSupported = function(self, algoname)
89 | end,
90 |
91 | GetAllKeys = function(self, flags)
92 | flags = flags or 0
93 |
94 | local res = {}
95 | local ppKeyName = ffi.new("PNCryptKeyName[1]");
96 | local ppEnumState = ffi.new("PVOID[1]");
97 | local status
98 | local dwFlags = flags;
99 |
100 | repeat
101 | local pszScope = nil
102 | status = NCLib.NCryptEnumKeys(self.Handle,
103 | pszScope,ppKeyName,ppEnumState,dwFlags);
104 |
105 | if status == 0 then
106 | local pKeyName = ppKeyName[0]
107 | local entry = {
108 | name = A(pKeyName.pszName),
109 | algoid = A(pKeyName.pszAlgid),
110 | }
111 |
112 | table.insert(res, entry);
113 | end
114 | until status ~= 0
115 |
116 | print(string.format("0x%x", status))
117 | print(string.format("Status: 0x%x 0x%x 0x%x", HRESULT_PARTS(status)))
118 |
119 | return res;
120 | end,
121 |
122 | },
123 |
124 | }
125 | NCryptStorageProvider = ffi.metatype(NCryptStorageProvider, NCryptStorageProvider_mt);
126 |
127 |
128 |
129 | return {
130 | NCryptStorageProvider = NCryptStorageProvider,
131 | }
132 |
--------------------------------------------------------------------------------
/NativeSocket.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 |
4 | local WinSock = require "WinSock_Utils"
5 | local wsock = require "win_socket"
6 | local SocketType = wsock.SocketType
7 | local Protocol = wsock.Protocol
8 |
9 | ffi.cdef[[
10 | typedef struct {
11 | SOCKET Handle;
12 | int id;
13 | } Socket_Win32;
14 | ]]
15 |
16 |
17 | local NativeSocket = ffi.typeof("Socket_Win32");
18 | local NativeSocket_mt = {
19 | __gc = function(self)
20 | -- Force close on socket
21 | -- To ensure it's really closed
22 | print("GC: NativeSocket: ", self.id);
23 | self:ForceClose();
24 | end,
25 |
26 | __new = function(ct, handle, family, socktype, protocol, flags)
27 | family = family or AF_INET;
28 | socktype = socktype or SocketType.SOCK_STREAM;
29 | protocol = protocol or 0;
30 | flags = flags or WSA_FLAG_OVERLAPPED;
31 |
32 | if not handle then
33 | handle, err = WinSock.WSASocket(family, socktype, protocol, nil, 0, WSA_FLAG_OVERLAPPED);
34 | if not handle then
35 | return nil, err
36 | end
37 | end
38 |
39 | return ffi.new(ct, handle);
40 | end,
41 |
42 | __index = {
43 | --[[
44 | Setting various options
45 | --]]
46 | SetKeepAlive = function(self, keepalive, delay)
47 | local oneint = ffi.new("int[1]");
48 | if keepalive then
49 | oneint[0] = 1
50 | end
51 |
52 | local success, err = WinSock.setsockopt(self.Handle, SOL_SOCKET, SO_KEEPALIVE, oneint, ffi.sizeof(oneint))
53 | if not success then
54 | return false, err
55 | end
56 |
57 | if keepalive and delay then
58 | oneint[0] = delay
59 | success, err = WinSock.setsockopt(self.Handle, Protocol.IPPROTO_TCP, TCP_KEEPALIVE, oneint, ffi.sizeof(oneint))
60 | end
61 |
62 | return success, err
63 | end,
64 |
65 | SetNoDelay = function(self, nodelay)
66 | local oneint = ffi.new("int[1]");
67 | if nodelay then
68 | oneint[0] = 1
69 | end
70 |
71 | return WinSock.setsockopt(self.Handle, Protocol.IPPROTO_TCP, TCP_NODELAY, oneint, ffi.sizeof(oneint))
72 | end,
73 |
74 | SetNonBlocking = function(self, nonblocking)
75 | local oneint = ffi.new("int[1]");
76 | if nonblocking then
77 | oneint[0] = 1
78 | end
79 |
80 | return WinSock.ioctlsocket(self.Handle, FIONBIO, oneint);
81 | end,
82 |
83 | SetReuseAddress = function(self, reuse)
84 | local oneint = ffi.new("int[1]");
85 | if reuse then
86 | oneint[0] = 1
87 | end
88 |
89 | return WinSock.setsockopt(self.Handle, SOL_SOCKET, SO_REUSEADDR, oneint, ffi.sizeof(oneint))
90 | end,
91 |
92 |
93 |
94 | --[[
95 | Connection Management
96 | --]]
97 | CloseDown = function(self)
98 | local success, err = WinSock.shutdown(self.Handle, SD_SEND)
99 | if not success then
100 | return false, err
101 | end
102 |
103 | return WinSock.closesocket(self.Handle);
104 | end,
105 |
106 | ForceClose = function(self)
107 | return WinSock.closesocket(self.Handle);
108 | end,
109 |
110 | Shutdown = function(self, how)
111 | how = how or SD_SEND
112 |
113 | return WinSock.shutdown(self.Handle, how)
114 | end,
115 |
116 | ShutdownReceive = function(self)
117 | return WinSock.shutdown(self.Handle, SD_RECEIVE)
118 | end,
119 |
120 | ShutdownSend = function(self)
121 | return WinSock.shutdown(self.Handle, SD_SEND)
122 | end,
123 |
124 | --[[
125 | Client Socket Routines
126 | --]]
127 | ConnectTo = function(self, address)
128 | local name = ffi.cast("const struct sockaddr *", address)
129 | local namelen = ffi.sizeof(address)
130 | return WinSock.connect(self.Handle, name, namelen);
131 | end,
132 |
133 | --[[
134 | Server socket routines
135 | --]]
136 | MakePassive = function(self, backlog)
137 | backlog = backlog or 5
138 | return WinSock.listen(self.Handle, backlog)
139 | end,
140 |
141 | Accept = function(self)
142 | local handle, err = WinSock.accept(self.Handle, nil, nil);
143 |
144 | if not handle then
145 | return false, err
146 | end
147 |
148 | return NativeSocket(handle)
149 | end,
150 |
151 | Bind = function(self, addr, addrlen)
152 | return WinSock.bind(self.Handle, addr, addrlen)
153 | end,
154 |
155 | --[[
156 | Data Transport
157 | --]]
158 | CanReadWithoutBlocking = function(self)
159 | local fdarray = WSAPOLLFD()
160 | fdarray.fd = self.Handle;
161 | fdarray.events = POLLRDNORM;
162 |
163 | -- wait up to 15 milliseconds to see if there's
164 | -- anything waiting
165 | local success, err = WinSock.WSAPoll(fdarray, 1, 15);
166 |
167 | if not success then
168 | return false, err
169 | end
170 |
171 | if success > 0 then
172 | return true;
173 | end
174 |
175 | return false, "wouldblock";
176 | end,
177 |
178 | CanWriteWithoutBlocking = function(self)
179 | local fdarray = WSAPOLLFD()
180 | fdarray.fd = self.Handle;
181 | fdarray.events = POLLWRNORM;
182 |
183 | local success, err = WinSock.WSAPoll(fdarray, 1, 15);
184 | if not success then
185 | return false, err
186 | end
187 |
188 | if ret == 0 then
189 | return false, "wouldblock"
190 | end
191 |
192 | return true
193 | end,
194 |
195 | Send = function(self, buff, bufflen)
196 | bufflen = bufflen or #buff
197 |
198 | return WinSock.send(self.Handle, buff, bufflen);
199 | end,
200 |
201 | Receive = function(self, buff, bufflen)
202 | return WinSock.recv(self.Handle, buff, bufflen);
203 | end,
204 | },
205 | }
206 | NativeSocket = ffi.metatype(NativeSocket, NativeSocket_mt);
207 |
208 |
209 | return NativeSocket;
--------------------------------------------------------------------------------
/NetStream.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 | local Stream = require "stream"
4 |
5 | local MemoryStream = require "MemoryStream"
6 |
7 | local NativeSocket = require "NativeSocket"
8 | local SocketUtils = require "SocketUtils"
9 |
10 | local StopWatch = require "StopWatch"
11 |
12 | local strutils = require "stringzutils"
13 | local typeutils = require "typeutils"
14 |
15 | local NetStream = {}
16 | local NetStream_mt = {
17 | __index = NetStream,
18 | }
19 |
20 | local activityTimeout = 60 * 5 -- 5 minutes
21 |
22 | function NetStream.new(socket)
23 | if not socket then
24 | return nil
25 | end
26 |
27 | local obj = {
28 | Socket = socket,
29 | CanSeek = false,
30 |
31 | ReadTimer = StopWatch.new(),
32 | ReadTimeout = nil,
33 |
34 | WriteTimer = StopWatch.new(),
35 | WriteTimeout = nil,
36 | }
37 |
38 | setmetatable(obj, NetStream_mt)
39 |
40 | return obj;
41 | end
42 |
43 | function NetStream.Open(hostname, port)
44 | local socket, err = CreateTcpClientSocket(hostname, port)
45 |
46 | if not socket then
47 | return nil, err
48 | end
49 |
50 | return NetStream.new(socket)
51 | end
52 |
53 |
54 |
55 | --[[
56 | IsIdle()
57 | When called, this routine will compare the last
58 | read and write activity times. If the time is beyond
59 | the respective timeout periods, then it will return 'true'.
60 |
61 | All other cases will return false.
62 | --]]
63 | function NetStream:IsIdle()
64 | --print("NetStream: IsIdle()");
65 |
66 | -- First condition of expiration
67 | -- both timeouts exist
68 | if self.ReadTimeout and self.WriteTimeout then
69 | if self.ReadTimer:Seconds() > self.ReadTimeout and
70 | self.WriteTimer:Seconds() > self.WriteTimeout then
71 |
72 | return true;
73 | end
74 | elseif self.ReadTimeout then
75 | if self.ReadTimer:Seconds() > self.ReadTimeout then
76 | return true;
77 | end
78 | elseif self.WriteTimeout then
79 | if self.WriteTimer:Seconds() > self.WriteTimeout then
80 | return true;
81 | end
82 | end
83 |
84 | return false
85 | end
86 |
87 | --[[
88 | Cycle()
89 | Can be called at any time. If the stream
90 | is idle, then force a close.
91 | --]]
92 |
93 | function NetStream:Cycle()
94 | --print("NetStream: Cycle");
95 |
96 | if self:IsIdle() then
97 | self:CloseDown();
98 | --self:ForceClose();
99 | end
100 | end
101 |
102 | -- Set the timeout for inactivity
103 | -- After the specified amount of time off
104 | -- inactivity, timeout, and forcefully close the stream
105 | function NetStream:SetIdleInterval(seconds)
106 | self:SetReadTimeout(seconds);
107 | self:SetWriteTimeout(seconds);
108 | end
109 |
110 | function NetStream:SetReadTimeout(seconds)
111 | self.ReadTimeout = seconds
112 | end
113 |
114 | function NetStream:SetWriteTimeout(seconds)
115 | self.WriteTimeout = seconds;
116 | end
117 |
118 | function NetStream:ForceClose()
119 | self.Socket:ForceClose();
120 | end
121 |
122 |
123 | -- Controlled shutdown
124 | function NetStream:ShutdownReceive()
125 | return self.Socket:ShutdownReceive()
126 | end
127 |
128 | function NetStream:ShutdownSend()
129 | return self.Socket:ShutdownSend()
130 | end
131 |
132 | function NetStream:CloseDown()
133 | self.Socket:CloseDown();
134 | end
135 |
136 | function NetStream:GetLength()
137 | return 0 -- or math.huge
138 | end
139 |
140 | function NetStream:GetPosition()
141 | return self.Consumed -- or number of bytes consumed so far
142 | end
143 |
144 | function NetStream:IsConnected()
145 | return self.Socket:IsCurrentlyConnected()
146 | end
147 |
148 | function NetStream:SetNonBlocking(nonblocking)
149 | return self.Socket:SetNonBlocking(nonblocking)
150 | end
151 |
152 | --[[
153 | READING
154 | --]]
155 | function NetStream:CanRead()
156 | return self.Socket:CanReadWithoutBlocking();
157 | end
158 |
159 | --[=[
160 | function NetStream:HasBytesReadyToRead()
161 | --[[
162 | -- There are bytes in the ReadingBuffer
163 | local bytesready = self.ReadingBuffer:BytesReadyToBeRead()
164 | if bytesready > 0 then
165 | return bytesready
166 | end
167 | --]]
168 | -- If the socket is no longer connected, then
169 | -- return nil, and 'disconnected'
170 | if not self:IsConnected() then
171 | return nil, "disconnected"
172 | end
173 |
174 | -- If there are bytes sitting in the socket's queue
175 | -- then return true
176 | local pending, err = self.Socket:GetBytesPendingReceive()
177 | --print("NS:HBRTR - ",pending, err)
178 |
179 | return pending, err
180 | end
181 |
182 |
183 | function NetStream:BytesReadyToBeRead()
184 | local pending, err = self.Socket:GetBytesPendingReceive()
185 |
186 | if pending then
187 | return pending
188 | end
189 |
190 | if err == WSAEWOULDBLOCK then
191 | return nil, "wouldblock"
192 | end
193 |
194 | return nil, err
195 | end
196 | --]=]
197 |
198 |
199 | --[[
200 | function NetStream:RefillReadingBuffer()
201 | print("NetStream:RefillReadingBuffer()");
202 |
203 | -- Use the buffer of the memory stream to
204 | -- read in a bunch of bytes
205 | local err
206 | local bytesread
207 |
208 | repeat
209 | bytesread, err = self.Socket:Receive(self.ReadingBuffer.Buffer, self.ReadingBuffer.Length)
210 |
211 | -- if we already got bytes, then return them immediately
212 | if bytesread then
213 | print("-- LOADED BYTES: ", bytesread);
214 |
215 | if bytesread == 0 then
216 | return nil, "eof"
217 | end
218 |
219 | self.ReadingBuffer:Reset()
220 | self.ReadingBuffer.BytesWritten = bytesread
221 | return bytesread, nil
222 | end
223 |
224 | if err ~= WSAEWOULDBLOCK then
225 | print("-- NetStream:RefillReadingBuffer(), ERROR: ", err)
226 | return nil, err
227 | end
228 |
229 | print("REPEAT");
230 | until bytesread
231 |
232 | return bytesread
233 | end
234 | --]]
235 |
236 | --[[
237 | Read a byte.
238 | Return the single byte read, or nil
239 | --]]
240 | local rb_onebyte = typeutils.uint8_tv(1)
241 |
242 | function NetStream:ReadByte()
243 | local abyte
244 | local err
245 | local res
246 |
247 | self.ReadTimer:Reset();
248 |
249 | --print("ReadByte Available: ", self.Socket:GetBytesPendingReceive())
250 |
251 | repeat
252 | abyte, err = self.Socket:Receive(rb_onebyte, 1)
253 | --print(abyte, err)
254 | if abyte then
255 | if abyte == 0 then
256 | return nil, "eof"
257 | end
258 |
259 | return rb_onebyte[0]
260 | end
261 |
262 | if err ~= WSAEWOULDBLOCK then
263 | print("-- NetStream:ReadByte() - Err: ", err);
264 | return nil, err
265 | end
266 | until abyte
267 |
268 | return abyte
269 |
270 | --[[
271 | -- First see if we can get a byte out of the
272 | -- Reading buffer
273 | abyte,err = self.ReadingBuffer:ReadByte()
274 |
275 | if abyte then
276 | return abyte
277 | end
278 |
279 | repeat
280 | -- If we did not get a byte out of the reading buffer
281 | -- try refilling the buffer, and try again
282 | local bytesread, err = self:RefillReadingBuffer()
283 |
284 | if bytesread then
285 | abyte, err = self.ReadingBuffer:ReadByte()
286 | return abyte, err
287 | else
288 | -- If there was an error
289 | -- then return that error immediately
290 | print("-- NetStream:ReadByte, ERROR: ", err)
291 | return nil, err
292 | end
293 | until false
294 | --]]
295 | end
296 |
297 |
298 | -- The Bytes() function acs as an iterator on bytes
299 | -- from the stream. In the case of a nonblocking stream
300 | -- this will in fact block, waiting for a character,
301 | -- only returning when a character is found, or there is an
302 | -- error other than WOULDBLOCK
303 | --[[
304 | function NetStream:Bytes(maxbytes)
305 | maxbytes = maxbytes or math.huge
306 | local bytesleft = maxbytes
307 |
308 | --print("NetStream:Bytes() BYTES LEFT: ", bytesleft);
309 |
310 | local function f()
311 | --print("-- NetStream:Bytes(), REMAINING: ", bytesleft)
312 | -- if we've read the maximum number of bytes
313 | -- then just return nil to indicate finished
314 | if bytesleft == 0 then
315 | return
316 | end
317 |
318 | local abyte
319 | local err
320 | local res
321 |
322 | while (true) do
323 | -- try to read a byte
324 | -- if we're a blocking socket, we'll just wait
325 | -- here forever, or until a system specified timeout
326 | local abyte, err = self:ReadByte()
327 |
328 | -- The return of Socket:Read() is the number of
329 | -- bytes read if successful, nil on failure
330 | if abyte then
331 | bytesleft = bytesleft-1
332 | return abyte
333 | end
334 |
335 | -- If there was an error other than wouldblock
336 | -- then return that error immediately
337 | if err ~= WSAEWOULDBLOCK then
338 | bytesleft = 0
339 | --print("-- NetStream:Bytes ERROR: ", err)
340 | return nil, err
341 | end
342 | end
343 | end
344 |
345 | return f
346 | end
347 | --]]
348 |
349 | function NetStream:ReadBytes(buffer, len, offset)
350 | offset = offset or 0
351 | --print("NetStream:ReadBytes()", buffer, len, offset);
352 |
353 | -- Reset the stopwatch
354 | self.ReadTimer:Reset();
355 |
356 | assert(buffer, "NetStream:ReadBytes(), buffer is NULL");
357 |
358 | local bytesread, err = SocketUtils.ReadN(self.Socket, buffer, len)
359 |
360 | return bytesread, err
361 | --[[
362 | local bytesread, err = self.Socket:Receive(buffer, len, offset)
363 |
364 | if bytesread then
365 | if bytesread == 0 then
366 | return nil, "eof"
367 | end
368 |
369 | return bytesread
370 | end
371 |
372 |
373 | if err == WSAEWOULDBLOCK then
374 | return nil, "wouldblock"
375 | end
376 |
377 | return nil, err
378 | --]]
379 | end
380 |
381 | local array = ffi.typeof("uint8_t[?]")
382 |
383 | function NetStream:ReadString(bufflen)
384 | bufflen = bufflen or 8192
385 |
386 | --print(string.format("-- NetStream:ReadString(), count: 0x%x", bufflen));
387 |
388 | local buff = array(bufflen);
389 | assert(buff, "NetStream:ReadString() - buffer not allocated")
390 |
391 | self.ReadTimer:Reset();
392 |
393 | local bytesread, err = SocketUtils.ReadN(self.Socket, buff, bufflen);
394 | --local bytesread, err = self:ReadBytes(buff, bufflen, 0)
395 | --print("NetStream:ReadString() - Bytes Read: ", bytesread, err)
396 |
397 | if bytesread and bytesread > 0 then
398 | return ffi.string(buff, bytesread)
399 | end
400 |
401 | return nil, err
402 | end
403 |
404 | -- Read characters from a stream until the specified
405 | -- ending is found, or until the stream runs out of bytes
406 | local CR = string.byte("\r")
407 | local LF = string.byte("\n")
408 |
409 | function NetStream:ReadLine(maxbytes)
410 | maxbytes = maxbytes or 1024
411 | local buff = array(maxbytes)
412 |
413 | assert(buff,"NetStream:ReadLine(), buffer not allocated")
414 |
415 | self.ReadTimer:Reset();
416 |
417 | local bytesread, err = SocketUtils.ReadLine(self.Socket, buff, maxbytes)
418 |
419 | -- print("-- NetStream:ReadLine() - bytesread, err:", bytesread, err);
420 |
421 | if bytesread then
422 | return ffi.string(buff, bytesread)
423 | end
424 |
425 | return nil, err
426 |
427 | --[[
428 | -- use the stream's byte iterator
429 | local haveCR = false
430 | for abyte, err in self:Bytes(maxbytes) do
431 | if abyte == CR then
432 | haveCR = true
433 | elseif abyte == LF then
434 | break
435 | else
436 | table.insert(chartable, string.char(abyte))
437 | end
438 | end
439 |
440 | local str = table.concat(chartable)
441 |
442 | return str
443 | --]]
444 | end
445 |
446 | --[[
447 | WRITING
448 | --]]
449 |
450 | function NetStream:CanWrite()
451 | return self.Socket:CanWriteWithoutBlocking();
452 | end
453 |
454 | function NetStream:WriteByte(value)
455 | local wb_buff = array(1, value)
456 | local byteswritten, err
457 |
458 | byteswritten, err = WriteN(self.Socket, wb_buff, 1);
459 |
460 | self.WriteTimer:Reset();
461 |
462 | return byteswritten, err
463 | end
464 |
465 | function NetStream:WriteBytes(buffer, len, offset)
466 | len = len or 0
467 | offset = offset or 0
468 | local ptr = buffer;
469 |
470 | if type(buffer) == "string" then
471 | ptr = ffi.cast("const uint8_t *", buffer)
472 | len = len or #buffer
473 | end
474 |
475 | local byteswritten, err
476 | local totalwritten = 0
477 | local idx = 0
478 |
479 | --print("NetStream:WriteBytes(), BEGIN")
480 |
481 | byteswritten, err = SocketUtils.WriteN(self.Socket, ptr, len)
482 |
483 | -- reset the write timer
484 | self.WriteTimer:Reset();
485 |
486 | --print("NetStream:WriteBytes(), END: ", byteswritten, err)
487 |
488 | return byteswritten, err
489 | end
490 |
491 | function NetStream:WriteString(str, count, offset)
492 | count = count or #str
493 | offset = offset or 0
494 |
495 | --print("NetStream:WriteString(): ", str);
496 |
497 | local byteswritten, err = self:WriteBytes(str, count, offset)
498 |
499 | return byteswritten, err
500 | end
501 |
502 | local lineEnd = "\r\n"
503 | local lineEnding = strdup(lineEnd)
504 |
505 | function NetStream:WriteLine(line)
506 | --print("-- NetStream:WriteLine(): ",line)
507 |
508 | local status, err
509 | if line then
510 | status, err = self:WriteString(line)
511 | --print("-- NetStream:WriteLine(), Line:", status, err)
512 | if err then
513 | return nil, err
514 | end
515 | end
516 |
517 | -- write the terminator
518 | status, err = self:WriteString(lineEnd);
519 | --status, err = self:WriteBytes(lineEnding, 2, 0)
520 |
521 | --print("-- Terminator: ", status, err);
522 |
523 | return status, err
524 | end
525 |
526 | function NetStream:WriteStream(stream, size)
527 | local count = 0
528 | local abyte = stream:ReadByte()
529 | while abyte and count < size do
530 | self:WriteByte(abyte)
531 | count = count + 1
532 | abyte = stream:ReadByte()
533 | end
534 |
535 | return count
536 | end
537 |
538 | return NetStream;
539 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | **LJIT2Win32**
2 |
3 | A collection of LuaJIT FFI interfaces and utilities for programming in the Windows environment.
4 |
5 | If you are interested in LuaJIT bindings for Win32, I strongly encourage you to take
6 | a look at TINN:
7 | http://github.com/wiladams/TINN
8 |
9 | There are a lot more bindings, to a much broader set of Windows routines, and they're kept
10 | more up to date.
11 |
12 | Even more recent, and more faithful to Win32 API is lj2win32
13 |
14 | https://github.com/Wiladams/lj2win32
15 |
--------------------------------------------------------------------------------
/SocketUtils.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 | local bit = require "bit"
4 | local band = bit.band
5 |
6 | local WinSock = require "WinSock_Utils"
7 | local SocketType = WinSock.FFI.SocketType;
8 | local Family = WinSock.FFI.Family;
9 |
10 | local NativeSocket = require "NativeSocket"
11 |
12 | -- pass in a sockaddr
13 | -- get out a more specific sockaddr_in or sockaddr_in6
14 | function newSocketAddress(name, namelen)
15 | local sockaddrptr = ffi.cast("struct sockaddr *", name)
16 | local newone
17 |
18 | if sockaddrptr.sa_family == Family.AF_INET then
19 | newone = sockaddr_in()
20 | elseif sockaddrptr.sa_family == Family.AF_INET6 then
21 | newone = sockaddr_in6()
22 | end
23 | ffi.copy(newone, sockaddrptr, namelen)
24 |
25 | return newone
26 | end
27 |
28 |
29 | local function host_serv(hostname, servicename, family, sockttype, isnumericstring)
30 | hostname = hostname or "localhost"
31 | family = family or Family.AF_UNSPEC;
32 | socktype = socktype or SocketType.SOCK_STREAM;
33 |
34 | local err;
35 | local hints = WinSock.addrinfo();
36 | local res = ffi.new("PADDRINFOA[1]")
37 |
38 | --hints.ai_flags = AI_CANONNAME; -- return canonical name
39 | hints.ai_family = family;
40 | hints.ai_socktype = socktype;
41 | if isnumericstring then
42 | hints.ai_flags = AI_NUMERICHOST
43 | end
44 |
45 | err = WinSock.Lib.getaddrinfo(hostname, servicename, hints, res)
46 | --print("host_serv, err: ", err);
47 | if err ~= 0 then
48 | -- error condition
49 | return nil, err
50 | end
51 |
52 | return res[0]
53 | end
54 |
55 |
56 | function CreateIPV4WildcardAddress(family, port)
57 | local inetaddr = sockaddr_in()
58 | inetaddr.sin_family = family;
59 | inetaddr.sin_addr.S_addr = WinSock.Lib.htonl(INADDR_ANY);
60 | inetaddr.sin_port = WinSock.Lib.htons(port);
61 |
62 | return inetaddr
63 | end
64 |
65 | function CreateSocketAddress(hostname, port, family, socktype)
66 | family = family or Family.AF_INET
67 | socktype = socktype or SocketType.SOCK_STREAM
68 |
69 | --print("CreateSocketAddress(): ", hostname, port);
70 |
71 | local hostportoffset = hostname:find(':')
72 | if hostportoffset then
73 | port = tonumber(hostname:sub(hostportoffset+1))
74 | hostname = hostname:sub(1,hostportoffset-1)
75 | print("CreateSocketAddress() - Modified: ", hostname, port)
76 | end
77 |
78 | local addressinfo, err = host_serv(hostname, nil, family, socktype)
79 |
80 | if not addressinfo then
81 | return nil, err
82 | end
83 |
84 | -- clone one of the addresses
85 | local oneaddress = newSocketAddress(addressinfo.ai_addr, addressinfo.ai_addrlen)
86 | oneaddress:SetPort(port)
87 |
88 | -- free the addrinfos structure
89 | err = WinSock.Lib.freeaddrinfo(addressinfo)
90 |
91 | return oneaddress;
92 | end
93 |
94 | local function ReadChunk(sock, buff, size)
95 | local nread, err = sock:Receive(buff, size)
96 |
97 | return nread, err
98 | end
99 |
100 | local function ReadN(sock, buff, size)
101 | local nleft = size;
102 | local nread = 0;
103 | local err
104 | local ptr = buff
105 |
106 | while nleft > 0 do
107 | nread, err = sock:Receive(ptr, nleft)
108 | --coroutine.yield();
109 | if nread then
110 | if nread == 0 then
111 | break
112 | end
113 |
114 | nleft = nleft - nread
115 | ptr = ptr + nread
116 | elseif err and err ~= WSAEWOULDBLOCK then
117 | break
118 | end
119 | end
120 |
121 | local bytesread = size - nleft
122 |
123 | if bytesread == 0 then
124 | return nil, "eof"
125 | end
126 |
127 | return bytesread
128 | end
129 |
130 | local function WriteN(sock, buff, size)
131 | local nleft = size;
132 | local nwritten = 0;
133 | local err
134 | local ptr = ffi.cast("const uint8_t *", buff)
135 |
136 | while nleft > 0 do
137 | nwritten, err = sock:Send(ptr, nleft)
138 | if not nwritten then
139 | if err ~= WSAEWOULDBLOCK then
140 | return nil, err
141 | end
142 | err = nil
143 | else
144 | if nwritten == 0 then
145 | break
146 | end
147 | nleft = nleft - nwritten
148 | ptr = ptr + nwritten
149 | end
150 | end
151 |
152 | return size - nleft
153 | end
154 |
155 |
156 | local CR = string.byte("\r")
157 | local LF = string.byte("\n")
158 |
159 | local function ReadLine(sock, buff, maxlen)
160 | --print("ReadLine(), Begin: ", maxlen)
161 |
162 | assert(buff)
163 |
164 | local nchars = 0;
165 | local ptr = buff
166 | local err
167 | local bytesread
168 |
169 | for n=1, maxlen do
170 | bytesread, err = ReadN(sock, ptr, 1)
171 | if not bytesread then
172 | --print("-- ReadLine(), Error: ", err);
173 | if err ~= "wouldblock" then
174 | break
175 | end
176 | end
177 |
178 | if ptr[0] == LF then
179 | break
180 | elseif ptr[0] ~= CR then
181 | ptr = ptr + 1
182 | nchars = nchars+1
183 | end
184 | end
185 |
186 | if err and err ~= "eof" then
187 | return nil, err
188 | end
189 |
190 | if nchars == 0 then
191 | return nil, "eof"
192 | end
193 |
194 | return nchars
195 | end
196 |
197 |
198 | --[[
199 | Helper Functions
200 | --]]
201 |
202 | function CreateTcpServerSocket(params)
203 | params = params or {port = 80, backlog = 15, nonblocking=false, nodelay = false}
204 | params.backlog = params.backlog or 15
205 | params.port = params.port or 80
206 |
207 | local sock, err = NativeSocket()
208 | if not sock then
209 | return nil, err
210 | end
211 |
212 | local success
213 | success, err = sock:SetNoDelay(params.nodelay)
214 | success, err = sock:SetReuseAddress(true);
215 |
216 | local addr = WinSock.sockaddr_in(params.port);
217 | local addrlen = ffi.sizeof("struct sockaddr_in")
218 |
219 | success, err = sock:Bind(addr,addrlen)
220 | if not success then
221 | return nil, err
222 | end
223 |
224 | success, err = sock:MakePassive(params.backlog)
225 | if not success then
226 | return nil, err
227 | end
228 |
229 | success, err = sock:SetNonBlocking(params.nonblocking);
230 | if not success then
231 | print("SetNonBlocking: ", err);
232 | end
233 |
234 | return sock
235 | end
236 |
237 | function CreateTcpClientSocket(hostname, port)
238 | --print("CreateTcpClientSocket: ", hostname, port)
239 |
240 | local addr, err = CreateSocketAddress(hostname, port)
241 |
242 | if not addr then
243 | print("-- CreateTcpClientSocket() - could not create address: ", hostname, port)
244 | return nil, err
245 | end
246 |
247 | --print("CreateTcpClientSocket(): ", addr);
248 |
249 | local sock
250 | sock, err = NativeSocket();
251 |
252 | if not sock then
253 | return nil, err
254 | end
255 |
256 | -- Disable delay by default on all sockets
257 | err = sock:SetNoDelay(true)
258 |
259 | -- Connect to the host
260 | local success
261 | success, err = sock:ConnectTo(addr)
262 | if not success then
263 | return nil, err
264 | end
265 |
266 | return sock
267 | end
268 |
269 |
270 | return {
271 | ReadByte = ReadByte,
272 | ReadLine = ReadLine,
273 | ReadN = ReadN,
274 | WriteN = WriteN,
275 | host_serv = host_serv,
276 |
277 | CreateTcpServerSocket = CreateTcpServerSocket,
278 | CreateTcpClientSocket = CreateTcpClientSocket,
279 | }
280 |
--------------------------------------------------------------------------------
/StopWatch.lua:
--------------------------------------------------------------------------------
1 | local ffi = require"ffi"
2 | local Kernel32 = require "Kernel32"
3 |
4 |
5 |
6 | StopWatch = {}
7 | StopWatch_mt = {
8 | __index = StopWatch;
9 | }
10 |
11 | StopWatch.new = function()
12 | local obj = {
13 | Frequency = 0;
14 | StartCount = 0;
15 | }
16 |
17 | setmetatable(obj, StopWatch_mt);
18 |
19 | StopWatch.Reset(obj);
20 |
21 | return obj
22 | end
23 |
24 | function StopWatch:__tostring()
25 | return string.format("Frequency: %d Count: %d", self.Frequency, self.StartCount)
26 | end
27 |
28 |
29 |
30 | --[[
31 | ///
32 | /// Reset the startCount, which is the current tick count.
33 | /// This will reset the elapsed time because elapsed time is the
34 | /// difference between the current tick count, and the one that
35 | /// was set here in the Reset() call.
36 | ///
37 | --]]
38 |
39 | function StopWatch:Reset()
40 | self.Frequency = 1/Kernel32.GetPerformanceFrequency();
41 | self.StartCount = Kernel32.GetPerformanceCounter();
42 | end
43 |
44 | --
45 | -- Return the number of seconds that elapsed since Reset() was called.
46 | --
47 | -- The number of elapsed seconds.
48 |
49 | function StopWatch:Seconds()
50 | local ellapsed = Kernel32.GetPerformanceCounter() - self.StartCount
51 | local seconds = ellapsed * self.Frequency;
52 |
53 | return seconds
54 | end
55 |
56 | function StopWatch:Milliseconds()
57 | return self:Seconds() * 1000
58 | end
59 |
60 |
61 |
--------------------------------------------------------------------------------
/TimedLoop.lua:
--------------------------------------------------------------------------------
1 | local bit = require "bit"
2 | local bor = bit.bor
3 |
4 | local ffi = require "ffi"
5 | local C = ffi.C
6 |
7 | local U32 = require "User32"
8 |
9 | require "kernel32"
10 | require "StopWatch"
11 |
12 |
13 | jit.off(Loop)
14 | function TimedLoop(callback, frequency, params)
15 | local timerEvent = C.CreateEventA(nil, false, false, nil)
16 | -- If the timer event was not created
17 | -- just return
18 | if timerEvent == nil then
19 | error("unable to create timer")
20 | return
21 | end
22 |
23 | local handleCount = 1
24 | local handles = ffi.new('void*[1]', {timerEvent})
25 |
26 | local sw = StopWatch.new()
27 | local tickCount = 1
28 | local timeleft = 0
29 | local lastTime = sw:Milliseconds()
30 | local interval = 1/frequency;
31 | local nextTime = lastTime + interval * 1000
32 |
33 | local dwFlags = bor(U32.FFI.MWMO_ALERTABLE,U32.FFI.MWMO_INPUTAVAILABLE)
34 |
35 | while (true) do
36 | timeleft = nextTime - sw:Milliseconds();
37 | if (timeleft <= 0.001) then
38 | callback(tickCount, params);
39 | tickCount = tickCount + 1
40 | nextTime = nextTime + interval * 1000
41 | timeleft = nextTime - sw:Milliseconds();
42 | end
43 |
44 | if timeleft < 0 then
45 | timeleft = 0
46 | end
47 |
48 | -- use an alertable wait
49 | C.MsgWaitForMultipleObjectsEx(handleCount, handles, timeleft, U32.FFI.QS_ALLEVENTS, dwFlags)
50 | end
51 | end
52 |
53 | return TimedLoop;
54 |
--------------------------------------------------------------------------------
/User32.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 |
4 | local user32_ffi = require ("user32_ffi");
5 |
6 | local User32Lib = ffi.load("User32");
7 |
8 | --[=[
9 | ffi.cdef[[
10 | typedef struct _WindowClass {
11 | WNDPROC MessageProc;
12 | ATOM Registration;
13 | HINSTANCE AppInstance;
14 | char * ClassName;
15 | int X;
16 | int Y;
17 | int Width;
18 | int Height;
19 | char *Title;
20 | } User32WindowClass;
21 | ]]
22 | --]=]
23 |
24 | ffi.cdef[[
25 | typedef struct _User32Window {
26 | HWND Handle;
27 | } NativeWindow, *PNativeWindow;
28 | ]]
29 |
30 | NativeWindow = ffi.typeof("NativeWindow")
31 | NativeWindow_mt = {
32 | __index = {
33 | Show = function(self)
34 | User32Lib.ShowWindow(self.Handle, C.SW_SHOW)
35 | end,
36 |
37 | Update = function(self)
38 | User32Lib.UpdateWindow(self.Handle)
39 | end,
40 |
41 | GetTitle = function(self)
42 | local buf = ffi.new("char[?]", 256)
43 | local lbuf = ffi.cast("intptr_t", buf)
44 | if User32Lib.SendMessageA(self.WindowHandle, C.WM_GETTEXT, 255, lbuf) ~= 0 then
45 | return ffi.string(buf)
46 | end
47 | end,
48 |
49 | OnCreate = function(self)
50 | print("User32Window:OnCreate")
51 | return 0
52 | end,
53 | }
54 | }
55 | NativeWindow = ffi.metatype(NativeWindow, NativeWindow_mt)
56 |
57 |
58 |
59 |
60 | function User32_MsgProc(hwnd, msg, wparam, lparam)
61 | --print("User32_MsgProc: ", msg)
62 | if (msg == C.WM_CREATE) then
63 | --print("WM_CREATE")
64 |
65 | local crstruct = ffi.cast("LPCREATESTRUCTA", lparam)
66 |
67 | --print(crstruct.lpCreateParams)
68 | local win = ffi.cast("PUser32Window", crstruct.lpCreateParams)
69 | return win:OnCreate()
70 | elseif (msg == C.WM_DESTROY) then
71 | --print("WM_DESTROY")
72 | C.PostQuitMessage(0)
73 | return 0
74 | end
75 |
76 | local retValue = User32Lib.DefWindowProcA(hwnd, msg, wparam, lparam)
77 |
78 | return retValue;
79 | end
80 |
81 |
82 | User32MSGHandler = {}
83 | User32MSGHandler_mt = {
84 | __index = User32MSGHandler,
85 | }
86 |
87 |
88 |
89 | User32MSGHandler.new = function(classname, msgproc, classStyle)
90 | local appInstance = kernel32.GetModuleHandleA(nil)
91 | msgproc = msgproc or User32_MsgProc
92 | classStyle = classStyle or bit.bor(user32_ffi.CS_HREDRAW, user32_ffi.CS_VREDRAW, user32_ffi.CS_OWNDC);
93 |
94 | local self = {}
95 | self.AppInstance = appInstance
96 | self.ClassName = ffi.cast("const char *", classname)
97 | self.MessageProc = msgproc
98 |
99 | setmetatable(self, User32MSGHandler_mt);
100 |
101 | local winClass = ffi.new('WNDCLASSEXA', {
102 | cbSize = ffi.sizeof("WNDCLASSEXA");
103 | style = classStyle;
104 | lpfnWndProc = self.MessageProc;
105 | cbClsExtra = 0;
106 | cbWndExtra = 0;
107 | hInstance = self.AppInstance;
108 | hIcon = nil;
109 | hCursor = nil;
110 | hbrBackground = nil;
111 | lpszMenuName = nil;
112 | lpszClassName = self.ClassName;
113 | hIconSm = nil;
114 | })
115 |
116 | self.Registration = User32Lib.RegisterClassExA(winClass)
117 |
118 | if (self.Registration == 0) then
119 | print("Registration error")
120 | --print(C.GetLastError())
121 | end
122 |
123 | return self
124 | end
125 |
126 | User32MSGHandler.CreateHandler = function(self, title, x, y, width, height, windowStyle)
127 | x = x or 10
128 | y = y or 10
129 | width = width or 320
130 | height = height or 240
131 | windowStyle = windowStyle or C.WS_OVERLAPPEDWINDOW
132 |
133 | self.Title = ffi.cast("const char *", title)
134 |
135 | local dwExStyle = bit.bor(user32_ffi.WS_EX_APPWINDOW, user32_ffi.WS_EX_WINDOWEDGE)
136 |
137 |
138 | local win = ffi.new("NativeWindow")
139 |
140 | local hWnd = User32Lib.CreateWindowExA(
141 | 0,
142 | self.ClassName,
143 | self.Title,
144 | windowStyle,
145 | x,
146 | y,
147 | width,
148 | height,
149 | nil,
150 | nil,
151 | self.AppInstance,
152 | win)
153 |
154 | if hWnd == nil then
155 | print("unable to create window")
156 | else
157 | win.Handle = hWnd
158 | end
159 |
160 | return win
161 | end
162 |
163 | ffi.cdef[[
164 | typedef struct {
165 | HWINSTA Handle;
166 | } WindowStation;
167 | ]]
168 |
169 | local WindowStation = ffi.typeof("WindowStation");
170 | local WindowStation_mt = {
171 | __gc = function(self)
172 | end,
173 |
174 | __new = function(ct, params)
175 | end,
176 |
177 | __index = {
178 | Close = function(self)
179 | return (User32Lib.CloseWindowStation(self.Handle) ~= 0) or false, User32Lib.GetLastError();
180 | end,
181 |
182 | },
183 | }
184 | ffi.metatype(WindowStation, WindowStation_mt);
185 |
186 |
187 | --[[
188 | Some functions, reflecting what's in the ffi interface
189 |
190 |
191 | --]]
192 |
193 | local SendInput = function(nInputs, pInputs, cbSize)
194 | local res = User32Lib.SendInput(nInputs,pInputs,cbSize);
195 |
196 | -- If the number of events inserted was zero,
197 | -- then there was an error
198 | if res == 0 then
199 | return nil, User32Lib.GetLastError();
200 | end
201 |
202 | -- return the number of events that were inserted
203 | return res
204 | end
205 |
206 | return {
207 | FFI = user32_ffi,
208 | Lib = User32Lib,
209 |
210 | User32MSGHandler = User32MSGHandler,
211 | NativeWindow = NativeWindow,
212 |
213 | SendInput = SendInput,
214 | }
215 |
--------------------------------------------------------------------------------
/User32Window.lua:
--------------------------------------------------------------------------------
1 | --
2 | -- User32Window.lua
3 | --
4 |
5 |
6 | local bit = require "bit"
7 | local bor = bit.bor
8 |
9 | local ffi = require "ffi"
10 | local C = ffi.C
11 |
12 |
13 | require "win_gdi32"
14 | require "win_user32"
15 | require "win_kernel32"
16 | require "StopWatch"
17 |
18 | local user32 = ffi.load("User32")
19 | local kernel32 = ffi.load("Kernel32")
20 | local gdi32 = ffi.load("gdi32")
21 |
22 | local User32Window = {
23 | WindowMap = {},
24 | Defaults = {
25 | ClassName = "User32Window",
26 | Title = "Window",
27 | Origin = {10,10},
28 | Extent = {320, 240},
29 | FrameRate = 30,
30 | },
31 | }
32 | local User32Window_mt = {
33 | __index = User32Window,
34 | }
35 |
36 |
37 | function User32Window.new(params)
38 | params = params or User32Window.Defaults
39 |
40 | params.ClassName = params.ClassName or User32Window.Defaults.ClassName
41 | params.Title = params.Title or User32Window.Defaults.Title
42 | params.Origin = params.Origin or User32Window.Defaults.Origin
43 | params.Extent = params.Extent or User32Window.Defaults.Extent
44 | params.FrameRate = params.FrameRate or User32Window.Defaults.FrameRate
45 |
46 | local self = {
47 | Registration = nil;
48 | IsReady = false;
49 | IsValid = false;
50 | IsRunning = false;
51 |
52 | MessageDelegate = params.MessageDelegate;
53 | OnSetFocusDelegate = params.OnSetFocusDelegate;
54 | OnTickDelegate = params.OnTickDelegate;
55 |
56 | -- Interactor routines
57 | KeyboardInteractor = params.KeyboardInteractor;
58 | MouseInteractor = params.MouseInteractor;
59 | GestureInteractor = params.GestureInteractor;
60 | }
61 | self.FrameRate = params.FrameRate
62 | self.Interval =1/ self.FrameRate
63 |
64 | setmetatable(self, User32Window_mt);
65 |
66 | self:Register(params)
67 | self:CreateWindow(params)
68 |
69 | return self;
70 | end
71 |
72 | function User32Window:GetClientSize()
73 | local csize = ffi.new( "RECT[1]" )
74 | user32.GetClientRect(self.WindowHandle, csize);
75 | csize = csize[0]
76 | local width = csize.right-csize.left
77 | local height = csize.bottom-csize.top
78 |
79 | return width, height
80 | end
81 |
82 |
83 | function User32Window:SetFrameRate(rate)
84 | self.FrameRate = rate
85 | self.Interval = 1/self.FrameRate
86 | end
87 |
88 |
89 |
90 |
91 |
92 |
93 | function User32Window:Register(params)
94 | self.AppInstance = kernel32.GetModuleHandleA(nil)
95 | self.ClassName = params.ClassName
96 |
97 | local classStyle = bit.bor(C.CS_HREDRAW, C.CS_VREDRAW, C.CS_OWNDC);
98 |
99 | local aClass = ffi.new('WNDCLASSEXA', {
100 | cbSize = ffi.sizeof("WNDCLASSEXA");
101 | style = classStyle;
102 | lpfnWndProc = WindowProc;
103 | cbClsExtra = 0;
104 | cbWndExtra = 0;
105 | hInstance = self.AppInstance;
106 | hIcon = nil;
107 | hCursor = nil;
108 | hbrBackground = nil;
109 | lpszMenuName = nil;
110 | lpszClassName = self.ClassName;
111 | hIconSm = nil;
112 | })
113 |
114 | self.Registration = user32.RegisterClassExA(aClass)
115 |
116 | assert(self.Registration ~= 0, "Registration error"..tostring(C.GetLastError()))
117 | end
118 |
119 |
120 |
121 | function User32Window:CreateWindow(params)
122 | self.ClassName = params.ClassName
123 | self.Title = params.Title
124 | self.Width = params.Extent[1]
125 | self.Height = params.Extent[2]
126 |
127 | local dwExStyle = bit.bor(C.WS_EX_APPWINDOW, C.WS_EX_WINDOWEDGE)
128 | local dwStyle = bit.bor(C.WS_SYSMENU, C.WS_VISIBLE, C.WS_POPUP)
129 |
130 | --print("User32Window:CreateWindow - 1.0")
131 | local hwnd = user32.CreateWindowExA(
132 | 0,
133 | self.ClassName,
134 | self.Title,
135 | C.WS_OVERLAPPEDWINDOW,
136 | C.CW_USEDEFAULT,
137 | C.CW_USEDEFAULT,
138 | params.Extent[1], params.Extent[2],
139 | nil,
140 | nil,
141 | self.AppInstance,
142 | nil)
143 | --print("User32Window:CreateWindow - 2.0")
144 |
145 | assert(hwnd,"unable to create window"..tostring(C.GetLastError()))
146 |
147 | self:OnCreated(hwnd)
148 | end
149 |
150 |
151 | function User32Window:Show()
152 | user32.ShowWindow(self.WindowHandle, C.SW_SHOW)
153 | end
154 |
155 | function User32Window:Hide()
156 | end
157 |
158 | function User32Window:Update()
159 | user32.UpdateWindow(self.WindowHandle)
160 | end
161 |
162 |
163 | function User32Window:SwapBuffers()
164 | gdi32.SwapBuffers(self.GDIContext.Handle);
165 | end
166 |
167 |
168 | User32Window.GetHandle = function(self)
169 | return self.WindowHandle;
170 | end
171 |
172 | function User32Window:OnCreated(hwnd)
173 | --print("User32Window:OnCreated")
174 |
175 | local winptr = ffi.cast("intptr_t", hwnd)
176 | local winnum = tonumber(winptr)
177 |
178 | self.WindowHandle = hwnd
179 | User32Window.WindowMap[winnum] = self
180 |
181 | local hdc = C.GetDC(self.WindowHandle)
182 |
183 |
184 | self.GDIContext = GDIContext(hdc)
185 | self.GDIContext:UseDCPen()
186 | self.GDIContext:UseDCBrush()
187 |
188 | self.IsValid = true
189 | end
190 |
191 | function User32Window:OnDestroy()
192 | -- print("User32Window:OnDestroy")
193 |
194 | C.PostQuitMessage(0)
195 |
196 | return 0
197 | end
198 |
199 | function User32Window:OnQuit()
200 | --print("User32Window:OnQuit")
201 | self.IsRunning = false
202 |
203 | -- delete glcontext
204 | if self.GLContext then
205 | self.GLContext:Destroy()
206 | end
207 | end
208 |
209 | function User32Window:OnTick(tickCount)
210 | if (self.OnTickDelegate) then
211 | self.OnTickDelegate(self, tickCount)
212 | end
213 | end
214 |
215 | function User32Window:OnFocusMessage(msg)
216 | --print("OnFocusMessage")
217 | if (self.OnSetFocusDelegate) then
218 | self.OnSetFocusDelegate(self, msg)
219 | end
220 | end
221 |
222 | function User32Window:OnKeyboardMessage(msg)
223 | if self.KeyboardInteractor then
224 | self.KeyboardInteractor(msg)
225 | end
226 | end
227 |
228 | function User32Window:OnMouseMessage(msg)
229 | if self.MouseInteractor then
230 | self.MouseInteractor(msg)
231 | end
232 | end
233 |
234 | --[[
235 | for window creation, we should see the
236 | following sequence
237 | WM_GETMINMAXINFO = 0x0024
238 | WM_NCCREATE = 0x0081
239 | WM_NCCALCSIZE = 0x0083
240 | WM_CREATE = 0x0001
241 |
242 | Then, after ShowWindow is called
243 | WM_SHOWWINDOW = 0x0018,
244 | WM_WINDOWPOSCHANGING = 0x0046,
245 | WM_ACTIVATEAPP = 0x001C,
246 |
247 | Closing Sequence
248 | WM_CLOSE = 0x0010,
249 | ...
250 | WM_ACTIVATEAPP = 0x001C,
251 | WM_KILLFOCUS = 0x0008,
252 | WM_IME_SETCONTEXT = 0x0281,
253 | WM_IME_NOTIFY = 0x0282,
254 | WM_DESTROY = 0x0002,
255 | WM_NCDESTROY = 0x0082,
256 | --]]
257 |
258 | function WindowProc(hwnd, msg, wparam, lparam)
259 | -- lookup which window object is associated with the
260 | -- window handle
261 | local winptr = ffi.cast("intptr_t", hwnd)
262 | local winnum = tonumber(winptr)
263 |
264 | local self = User32Window.WindowMap[winnum]
265 |
266 | --print(string.format("WindowProc: 0x%x, Window: 0x%x, self: %s", msg, winnum, tostring(self)))
267 |
268 | -- if we have a self, then the window is capable
269 | -- of handling the message
270 | if self then
271 | if (self.MessageDelegate) then
272 | result = self.MessageDelegate(hwnd, msg, wparam, lparam)
273 | return result
274 | end
275 |
276 | if (msg == C.WM_DESTROY) then
277 | return self:OnDestroy()
278 | end
279 |
280 | if (msg >= C.WM_MOUSEFIRST and msg <= C.WM_MOUSELAST) or
281 | (msg >= C.WM_NCMOUSEMOVE and msg <= C.WM_NCMBUTTONDBLCLK) then
282 | self:OnMouseMessage(msg, wparam, lparam)
283 | end
284 |
285 | if (msg >= C.WM_KEYDOWN and msg <= C.WM_SYSCOMMAND) then
286 | self:OnKeyboardMessage(msg, wparam, lparam)
287 | end
288 | end
289 |
290 | -- otherwise, it's not associated with a window that we know
291 | -- so do default processing
292 | return user32.DefWindowProcA(hwnd, msg, wparam, lparam);
293 |
294 | end
295 |
296 | function User32Window:Run()
297 | if not self.IsValid then
298 | print('Window Handle is NULL')
299 | return
300 | end
301 |
302 | self.IsRunning = true
303 |
304 | self:Show()
305 | self:Update()
306 |
307 | return Loop(self)
308 | end
309 |
310 | -- The following 'jit.off(Loop)' is here because LuaJit
311 | -- can't quite fix-up the case where a callback is being
312 | -- called from LuaJit'd code
313 | -- http://lua-users.org/lists/lua-l/2011-12/msg00712.html
314 | --
315 | -- I found the proper way to do this is to put the jit.off
316 | -- call before the function body.
317 | --
318 | jit.off(Loop)
319 | function Loop(win)
320 | local timerEvent = C.CreateEventA(nil, false, false, nil)
321 | -- If the timer event was not created
322 | -- just return
323 | if timerEvent == nil then
324 | error("unable to create timer")
325 | return
326 | end
327 |
328 | local handleCount = 1
329 | local handles = ffi.new('void*[1]', {timerEvent})
330 |
331 | local msg = ffi.new("MSG")
332 | local sw = StopWatch.new()
333 | local tickCount = 1
334 | local timeleft = 0
335 | local lastTime = sw:Milliseconds()
336 | local nextTime = lastTime + win.Interval * 1000
337 |
338 | local dwFlags = bor(C.MWMO_ALERTABLE,C.MWMO_INPUTAVAILABLE)
339 |
340 | while (win.IsRunning) do
341 | while (user32.PeekMessageA(msg, nil, 0, 0, C.PM_REMOVE) ~= 0) do
342 | user32.TranslateMessage(msg)
343 | user32.DispatchMessageA(msg)
344 |
345 | if msg.message == C.WM_QUIT then
346 | return win:OnQuit()
347 | end
348 |
349 | end
350 |
351 | timeleft = nextTime - sw:Milliseconds();
352 | if (timeleft <= 0) then
353 | win:OnTick(tickCount);
354 | tickCount = tickCount + 1
355 | nextTime = nextTime + win.Interval * 1000
356 | timeleft = nextTime - sw:Milliseconds();
357 | end
358 |
359 | if timeleft < 0 then timeleft = 0 end
360 |
361 | -- use an alertable wait
362 | C.MsgWaitForMultipleObjectsEx(handleCount, handles, timeleft, C.QS_ALLEVENTS, dwFlags)
363 | end
364 | end
365 |
366 |
367 | return User32Window
368 |
369 |
--------------------------------------------------------------------------------
/WTypes.lua:
--------------------------------------------------------------------------------
1 | local ffi = require"ffi"
2 | local bit = require"bit"
3 |
4 | local bnot = bit.bnot
5 | local band = bit.band
6 | local bor = bit.bor
7 | local lshift = bit.lshift
8 | local rshift = bit.rshift
9 |
10 | ffi.cdef[[
11 | typedef char * PCHAR;
12 |
13 | typedef char * PSTR;
14 | typedef const char * PCSTR;
15 | typedef const short * PCWSTR;
16 |
17 | typedef uint32_t * PDWORD;
18 | typedef long * PLONG;
19 | typedef uint64_t ULONGLONG;
20 | typedef uint64_t ULONG64;
21 | typedef uint64_t * PULONG64;
22 | typedef uint64_t DWORD64;
23 | typedef uint64_t * PDWORD64;
24 | ]]
25 |
26 | ffi.cdef[[
27 |
28 | // Basic Data types
29 | typedef unsigned char BYTE;
30 | typedef long BOOL;
31 | typedef BYTE BOOLEAN;
32 | typedef char CHAR;
33 | typedef wchar_t WCHAR;
34 | typedef uint16_t WORD;
35 | typedef unsigned long DWORD;
36 | typedef uint32_t DWORD32;
37 | typedef int INT;
38 | typedef int32_t INT32;
39 | typedef int64_t INT64;
40 | typedef float FLOAT;
41 | typedef long LONG;
42 | typedef signed int LONG32;
43 | typedef int64_t LONGLONG;
44 | typedef size_t SIZE_T;
45 |
46 | typedef uint8_t BCHAR;
47 | typedef unsigned char UCHAR;
48 | typedef unsigned int UINT;
49 | typedef unsigned int UINT32;
50 | typedef unsigned long ULONG;
51 | typedef unsigned int ULONG32;
52 | typedef unsigned short USHORT;
53 | typedef uint64_t ULONGLONG;
54 |
55 |
56 | // Some pointer types
57 | typedef uint8_t * PBYTE;
58 |
59 | typedef unsigned char *PUCHAR;
60 | typedef const unsigned char *PCUCHAR;
61 | typedef unsigned int *PUINT;
62 | typedef unsigned int *PUINT32;
63 | typedef unsigned long *PULONG;
64 | typedef unsigned int *PULONG32;
65 | typedef unsigned short *PUSHORT;
66 | typedef LONGLONG *PLONGLONG;
67 | typedef ULONGLONG *PULONGLONG;
68 |
69 |
70 | typedef void * PVOID;
71 | typedef DWORD * DWORD_PTR;
72 | typedef intptr_t LONG_PTR;
73 | typedef uintptr_t UINT_PTR;
74 | typedef uintptr_t ULONG_PTR;
75 | typedef ULONG_PTR * PULONG_PTR;
76 |
77 |
78 | typedef DWORD * LPCOLORREF;
79 |
80 | typedef BOOL * LPBOOL;
81 | typedef char * LPSTR;
82 | typedef short * LPWSTR;
83 | typedef short * PWSTR;
84 | typedef const short * LPCWSTR;
85 | typedef LPSTR LPTSTR;
86 |
87 | typedef DWORD * LPDWORD;
88 | typedef void * LPVOID;
89 | typedef WORD * LPWORD;
90 |
91 | typedef const char * LPCSTR;
92 | typedef LPCSTR LPCTSTR;
93 | typedef const void * LPCVOID;
94 |
95 |
96 | typedef LONG_PTR LRESULT;
97 |
98 | typedef LONG_PTR LPARAM;
99 | typedef UINT_PTR WPARAM;
100 |
101 |
102 | typedef unsigned char TBYTE;
103 | typedef char TCHAR;
104 |
105 | typedef USHORT COLOR16;
106 | typedef DWORD COLORREF;
107 |
108 | // Special types
109 | typedef WORD ATOM;
110 | typedef DWORD LCID;
111 | typedef USHORT LANGID;
112 |
113 | // Various Handles
114 | typedef void * HANDLE;
115 | typedef HANDLE *PHANDLE;
116 | typedef HANDLE LPHANDLE;
117 | typedef void * HBITMAP;
118 | typedef void * HBRUSH;
119 | typedef void * HICON;
120 | typedef HICON HCURSOR;
121 | typedef HANDLE HDC;
122 | typedef void * HDESK;
123 | typedef HANDLE HDROP;
124 | typedef HANDLE HDWP;
125 | typedef HANDLE HENHMETAFILE;
126 | typedef INT HFILE;
127 | typedef HANDLE HFONT;
128 | typedef void * HGDIOBJ;
129 | typedef HANDLE HGLOBAL;
130 | typedef HANDLE HGLRC;
131 | typedef HANDLE HHOOK;
132 | typedef void * HINSTANCE;
133 | typedef void * HKEY;
134 | typedef void * HKL;
135 | typedef HANDLE HLOCAL;
136 | typedef void * HMEMF;
137 | typedef HANDLE HMENU;
138 | typedef HANDLE HMETAFILE;
139 | typedef void HMF;
140 | typedef HINSTANCE HMODULE;
141 | typedef HANDLE HMONITOR;
142 | typedef HANDLE HPALETTE;
143 | typedef void * HPEN;
144 | typedef LONG HRESULT;
145 | typedef HANDLE HRGN;
146 | typedef void * HRSRC;
147 | typedef void * HSTR;
148 | typedef HANDLE HSZ;
149 | typedef void * HTASK;
150 | typedef void * HWINSTA;
151 | typedef HANDLE HWND;
152 |
153 | // Ole Automation
154 | typedef WCHAR OLECHAR;
155 | typedef OLECHAR *LPOLESTR;
156 | typedef const OLECHAR *LPCOLESTR;
157 |
158 | //typedef char OLECHAR;
159 | //typedef LPSTR LPOLESTR;
160 | //typedef LPCSTR LPCOLESTR;
161 |
162 | typedef OLECHAR *BSTR;
163 | typedef BSTR *LPBSTR;
164 |
165 |
166 |
167 | typedef DWORD ACCESS_MASK;
168 | typedef ACCESS_MASK* PACCESS_MASK;
169 |
170 |
171 | typedef LONG FXPT16DOT16, *LPFXPT16DOT16;
172 | typedef LONG FXPT2DOT30, *LPFXPT2DOT30;
173 |
174 | typedef int NTSTATUS;
175 |
176 | ]]
177 |
178 |
179 | --[[
180 | From guiddef
181 | --]]
182 |
183 | ffi.cdef[[
184 | typedef struct {
185 | unsigned long Data1;
186 | unsigned short Data2;
187 | unsigned short Data3;
188 | unsigned char Data4[8];
189 | } GUID, UUID, *LPGUID;
190 | ]]
191 |
192 | ffi.cdef[[
193 | typedef const GUID * LPCGUID;
194 | typedef const GUID * REFGUID;
195 |
196 | typedef GUID IID;
197 | typedef IID * LPIID;
198 | typedef const IID * REFIID;
199 |
200 | typedef GUID CLSID;
201 | typedef CLSID * LPCLSID;
202 | typedef const GUID * REFCLSID;
203 | ]]
204 |
205 |
206 | local function bytecompare(a, b, n)
207 | local res = true
208 | for i=0,n-1 do
209 | if a[i] ~= b[i] then
210 | return false
211 | end
212 | end
213 | return res
214 | end
215 |
216 | GUID = nil
217 | GUID_mt = {
218 | __tostring = function(self)
219 | local res = string.format("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
220 | self.Data1, self.Data2, self.Data3,
221 | self.Data4[0], self.Data4[1],
222 | self.Data4[2], self.Data4[3], self.Data4[4],
223 | self.Data4[5], self.Data4[6], self.Data4[7])
224 | return res
225 | end,
226 |
227 | __eq = function(a, b)
228 | return (a.Data1 == b.Data1) and
229 | (a.Data2 == b.Data2) and
230 | (a.Data3 == b.Data3) and
231 | bytecompare(a.Data4, b.Data4, 4)
232 | end,
233 |
234 | __index = {
235 | Define = function(self, name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8 )
236 | return GUID({ l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }), name
237 | end,
238 |
239 | DefineOle = function(self, name, l, w1, w2)
240 | return GUID({ l, w1, w2, { 0xC0,0,0,0,0,0,0,0x46 } }), name
241 | end,
242 | },
243 | }
244 | GUID = ffi.metatype("GUID", GUID_mt)
245 |
246 | --require "CGuid"
247 |
248 | GUID_NULL = GUID()
249 | IID_NULL = GUID_NULL
250 | CLSID_NULL = GUID_NULL
251 | FMTID_NULL = GUID_NULL
252 |
253 |
254 | function DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
255 | return GUID():Define(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
256 | end
257 |
258 | DEFINE_UUID = DEFINE_GUID
259 |
260 | function DEFINE_OLEGUID(name, l, w1, w2)
261 | return GUID():DefineOle(name, l, w1, w2)
262 | end
263 |
264 | --[[
265 | Useful routines
266 | --]]
267 |
268 | function IsEqualIID(riid1, riid2)
269 | return riid1 == riid2
270 | end
271 |
272 | function IsEqualCLSID(rclsid1, rclsid2)
273 | return rclsid1 == rclsid2
274 | end
275 |
276 | function IsEqualFMTID(rfmtid1, rfmtid2)
277 | return rfmtid1 == rfmtid2
278 | end
279 |
280 |
281 |
282 |
283 | -- From Rpcrt4.h
284 |
285 | Rpcrt4 = ffi.load("Rpcrt4")
286 |
287 | ffi.cdef[[
288 | int UuidCreate(UUID * Uuid);
289 |
290 | int UuidFromStringA(const char * StringUuid, UUID * Uuid);
291 |
292 | int UuidToStringA(UUID * Uuid , char ** StringUuid);
293 | ]]
294 |
295 |
296 | -- Helpful function for constructing a UUID/GUID
297 | -- from a string
298 | function UUIDFromString(stringid)
299 | local id = ffi.new("UUID[1]")
300 | Rpcrt4.UuidFromStringA(stringid, id)
301 | id = id[0]
302 |
303 | return id
304 | end
305 |
306 |
307 |
308 |
309 |
310 |
311 | ffi.cdef[[
312 | typedef union _LARGE_INTEGER {
313 | struct {
314 | DWORD LowPart;
315 | LONG HighPart;
316 | };
317 | struct {
318 | DWORD LowPart;
319 | LONG HighPart;
320 | } u;
321 | LONGLONG QuadPart;
322 | } LARGE_INTEGER, *PLARGE_INTEGER;
323 |
324 | typedef struct _ULARGE_INTEGER
325 | {
326 | ULONGLONG QuadPart;
327 | } ULARGE_INTEGER;
328 |
329 |
330 | typedef struct _FILETIME
331 | {
332 | DWORD dwLowDateTime;
333 | DWORD dwHighDateTime;
334 | } FILETIME;
335 |
336 | typedef struct _FILETIME *PFILETIME;
337 |
338 | typedef struct _FILETIME *LPFILETIME;
339 |
340 |
341 | typedef struct _SYSTEMTIME
342 | {
343 | WORD wYear;
344 | WORD wMonth;
345 | WORD wDayOfWeek;
346 | WORD wDay;
347 | WORD wHour;
348 | WORD wMinute;
349 | WORD wSecond;
350 | WORD wMilliseconds;
351 | } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
352 |
353 |
354 | typedef struct _SECURITY_ATTRIBUTES {
355 | DWORD nLength;
356 | LPVOID lpSecurityDescriptor;
357 | BOOL bInheritHandle;
358 | } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
359 |
360 |
361 | typedef USHORT SECURITY_DESCRIPTOR_CONTROL;
362 |
363 | typedef USHORT *PSECURITY_DESCRIPTOR_CONTROL;
364 |
365 | typedef PVOID PSID;
366 |
367 | typedef struct _ACL
368 | {
369 | UCHAR AclRevision;
370 | UCHAR Sbz1;
371 | USHORT AclSize;
372 | USHORT AceCount;
373 | USHORT Sbz2;
374 | } ACL, *PACL;
375 |
376 |
377 | typedef struct _SECURITY_DESCRIPTOR
378 | {
379 | UCHAR Revision;
380 | UCHAR Sbz1;
381 | SECURITY_DESCRIPTOR_CONTROL Control;
382 | PSID Owner;
383 | PSID Group;
384 | PACL Sacl;
385 | PACL Dacl;
386 | } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
387 |
388 | typedef struct _COAUTHIDENTITY
389 | {
390 | USHORT *User;
391 | ULONG UserLength;
392 | USHORT *Domain;
393 | ULONG DomainLength;
394 | USHORT *Password;
395 | ULONG PasswordLength;
396 | ULONG Flags;
397 | } COAUTHIDENTITY;
398 |
399 | typedef struct _COAUTHINFO
400 | {
401 | DWORD dwAuthnSvc;
402 | DWORD dwAuthzSvc;
403 | LPWSTR pwszServerPrincName;
404 | DWORD dwAuthnLevel;
405 | DWORD dwImpersonationLevel;
406 | COAUTHIDENTITY *pAuthIdentityData;
407 | DWORD dwCapabilities;
408 | } COAUTHINFO;
409 |
410 | typedef LONG SCODE;
411 |
412 | typedef SCODE *PSCODE;
413 |
414 |
415 | typedef
416 | enum tagMEMCTX {
417 | MEMCTX_TASK = 1,
418 | MEMCTX_SHARED = 2,
419 | MEMCTX_MACSYSTEM = 3,
420 | MEMCTX_UNKNOWN = -1,
421 | MEMCTX_SAME = -2
422 | } MEMCTX;
423 |
424 |
425 |
426 |
427 | typedef
428 | enum tagMSHLFLAGS
429 | { MSHLFLAGS_NORMAL = 0,
430 | MSHLFLAGS_TABLESTRONG = 1,
431 | MSHLFLAGS_TABLEWEAK = 2,
432 | MSHLFLAGS_NOPING = 4,
433 | MSHLFLAGS_RESERVED1 = 8,
434 | MSHLFLAGS_RESERVED2 = 16,
435 | MSHLFLAGS_RESERVED3 = 32,
436 | MSHLFLAGS_RESERVED4 = 64
437 | } MSHLFLAGS;
438 |
439 | typedef
440 | enum tagMSHCTX
441 | { MSHCTX_LOCAL = 0,
442 | MSHCTX_NOSHAREDMEM = 1,
443 | MSHCTX_DIFFERENTMACHINE = 2,
444 | MSHCTX_INPROC = 3,
445 | MSHCTX_CROSSCTX = 4
446 | } MSHCTX;
447 |
448 | typedef
449 | enum tagDVASPECT
450 | { DVASPECT_CONTENT = 1,
451 | DVASPECT_THUMBNAIL = 2,
452 | DVASPECT_ICON = 4,
453 | DVASPECT_DOCPRINT = 8
454 | } DVASPECT;
455 |
456 | typedef
457 | enum tagSTGC
458 | { STGC_DEFAULT = 0,
459 | STGC_OVERWRITE = 1,
460 | STGC_ONLYIFCURRENT = 2,
461 | STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4,
462 | STGC_CONSOLIDATE = 8
463 | } STGC;
464 |
465 | typedef
466 | enum tagSTGMOVE
467 | { STGMOVE_MOVE = 0,
468 | STGMOVE_COPY = 1,
469 | STGMOVE_SHALLOWCOPY = 2
470 | } STGMOVE;
471 |
472 | typedef
473 | enum tagSTATFLAG
474 | { STATFLAG_DEFAULT = 0,
475 | STATFLAG_NONAME = 1,
476 | STATFLAG_NOOPEN = 2
477 | } STATFLAG;
478 |
479 | typedef void *HCONTEXT;
480 |
481 | typedef struct _BYTE_BLOB
482 | {
483 | unsigned long clSize;
484 | uint8_t abData[ 1 ];
485 | } BYTE_BLOB;
486 |
487 | typedef struct _WORD_BLOB
488 | {
489 | unsigned long clSize;
490 | unsigned short asData[ 1 ];
491 | } WORD_BLOB;
492 |
493 | typedef struct _DWORD_BLOB
494 | {
495 | unsigned long clSize;
496 | unsigned long alData[ 1 ];
497 | } DWORD_BLOB;
498 |
499 | typedef struct _FLAGGED_BYTE_BLOB
500 | {
501 | unsigned long fFlags;
502 | unsigned long clSize;
503 | uint8_t abData[ 1 ];
504 | } FLAGGED_BYTE_BLOB;
505 |
506 | typedef struct _FLAGGED_WORD_BLOB
507 | {
508 | unsigned long fFlags;
509 | unsigned long clSize;
510 | unsigned short asData[ 1 ];
511 | } FLAGGED_WORD_BLOB;
512 |
513 | typedef struct _BYTE_SIZEDARR
514 | {
515 | unsigned long clSize;
516 | uint8_t *pData;
517 | } BYTE_SIZEDARR;
518 |
519 | typedef struct _SHORT_SIZEDARR
520 | {
521 | unsigned long clSize;
522 | unsigned short *pData;
523 | } WORD_SIZEDARR;
524 |
525 | typedef struct _LONG_SIZEDARR
526 | {
527 | unsigned long clSize;
528 | unsigned long *pData;
529 | } DWORD_SIZEDARR;
530 |
531 |
532 | ]]
533 |
534 | --typedef enum tagCLSCTX {
535 | CLSCTX_INPROC_SERVER = 0x1
536 | CLSCTX_INPROC_HANDLER = 0x2
537 | CLSCTX_LOCAL_SERVER = 0x4
538 | CLSCTX_INPROC_SERVER16 = 0x8
539 | CLSCTX_REMOTE_SERVER = 0x10
540 | CLSCTX_INPROC_HANDLER16 = 0x20
541 | CLSCTX_RESERVED1 = 0x40
542 | CLSCTX_RESERVED2 = 0x80
543 | CLSCTX_RESERVED3 = 0x100
544 | CLSCTX_RESERVED4 = 0x200
545 | CLSCTX_NO_CODE_DOWNLOAD = 0x400
546 | CLSCTX_RESERVED5 = 0x800
547 | CLSCTX_NO_CUSTOM_MARSHAL = 0x1000
548 | CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000
549 | CLSCTX_NO_FAILURE_LOG = 0x4000
550 | CLSCTX_DISABLE_AAA = 0x8000
551 | CLSCTX_ENABLE_AAA = 0x10000
552 | CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000
553 | CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
554 | CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
555 | CLSCTX_ENABLE_CLOAKING = 0x100000
556 | CLSCTX_PS_DLL = 0x80000000
557 | --} CLSCTX;
558 |
559 | CLSCTX_VALID_MASK = bor(
560 | CLSCTX_INPROC_SERVER ,
561 | CLSCTX_INPROC_HANDLER ,
562 | CLSCTX_LOCAL_SERVER ,
563 | CLSCTX_INPROC_SERVER16 ,
564 | CLSCTX_REMOTE_SERVER ,
565 | CLSCTX_NO_CODE_DOWNLOAD ,
566 | CLSCTX_NO_CUSTOM_MARSHAL ,
567 | CLSCTX_ENABLE_CODE_DOWNLOAD ,
568 | CLSCTX_NO_FAILURE_LOG ,
569 | CLSCTX_DISABLE_AAA ,
570 | CLSCTX_ENABLE_AAA ,
571 | CLSCTX_FROM_DEFAULT_CONTEXT ,
572 | CLSCTX_ACTIVATE_32_BIT_SERVER ,
573 | CLSCTX_ACTIVATE_64_BIT_SERVER ,
574 | CLSCTX_ENABLE_CLOAKING ,
575 | CLSCTX_PS_DLL)
576 |
577 | WDT_INPROC_CALL =( 0x48746457 )
578 |
579 | WDT_REMOTE_CALL =( 0x52746457 )
580 |
581 | WDT_INPROC64_CALL = ( 0x50746457 )
582 |
583 |
584 | --[[
585 | ffi.cdef[[
586 | enum {
587 | MAXSHORT = 32767,
588 | MINSHORT = -32768,
589 |
590 | MAXINT = 2147483647,
591 | MININT = -2147483648,
592 |
593 | MAXLONGLONG = 9223372036854775807LL,
594 | MINLONGLONG = -9223372036854775807LL,
595 | };
596 |
597 | ]]
598 | --]]
599 |
600 | ffi.cdef[[
601 |
602 | typedef struct tagSIZE {
603 | LONG cx;
604 | LONG cy;
605 | } SIZE, *PSIZE;
606 |
607 | typedef struct tagPOINT {
608 | int32_t x;
609 | int32_t y;
610 | } POINT, *PPOINT;
611 |
612 | typedef struct _POINTL {
613 | LONG x;
614 | LONG y;
615 | } POINTL, *PPOINTL;
616 |
617 | typedef struct tagRECT {
618 | int32_t left;
619 | int32_t top;
620 | int32_t right;
621 | int32_t bottom;
622 | } RECT, *PRECT;
623 | ]]
624 |
625 | RECT = nil
626 | RECT_mt = {
627 | __tostring = function(self)
628 | local str = string.format("%d %d %d %d", self.left, self.top, self.right, self.bottom)
629 | return str
630 | end,
631 |
632 | __index = {
633 | }
634 | }
635 | RECT = ffi.metatype("RECT", RECT_mt)
636 |
637 | ffi.cdef[[
638 | typedef struct _TRIVERTEX {
639 | LONG x;
640 | LONG y;
641 | COLOR16 Red;
642 | COLOR16 Green;
643 | COLOR16 Blue;
644 | COLOR16 Alpha;
645 | }TRIVERTEX, *PTRIVERTEX;
646 |
647 | typedef struct _GRADIENT_TRIANGLE {
648 | ULONG Vertex1;
649 | ULONG Vertex2;
650 | ULONG Vertex3;
651 | }GRADIENT_TRIANGLE, *PGRADIENT_TRIANGLE;
652 |
653 | typedef struct _GRADIENT_RECT {
654 | ULONG UpperLeft;
655 | ULONG LowerRight;
656 | }GRADIENT_RECT, *PGRADIENT_RECT;
657 |
658 |
659 |
660 |
661 |
662 | typedef struct tagRGBQUAD {
663 | BYTE rgbBlue;
664 | BYTE rgbGreen;
665 | BYTE rgbRed;
666 | BYTE rgbReserved;
667 | } RGBQUAD;
668 |
669 | typedef struct tagRGBTRIPLE {
670 | BYTE rgbtBlue;
671 | BYTE rgbtGreen;
672 | BYTE rgbtRed;
673 | } RGBTRIPLE;
674 |
675 |
676 |
677 |
678 | typedef struct tagBITMAP {
679 | LONG bmType;
680 | LONG bmWidth;
681 | LONG bmHeight;
682 | LONG bmWidthBytes;
683 | WORD bmPlanes;
684 | WORD bmBitsPixel;
685 | LPVOID bmBits;
686 | } BITMAP, *PBITMAP;
687 |
688 | typedef struct tagBITMAPCOREHEADER {
689 | DWORD bcSize;
690 | WORD bcWidth;
691 | WORD bcHeight;
692 | WORD bcPlanes;
693 | WORD bcBitCount;
694 | } BITMAPCOREHEADER, *PBITMAPCOREHEADER;
695 |
696 | typedef struct tagBITMAPINFOHEADER{
697 | DWORD biSize;
698 | LONG biWidth;
699 | LONG biHeight;
700 | WORD biPlanes;
701 | WORD biBitCount;
702 | DWORD biCompression;
703 | DWORD biSizeImage;
704 | LONG biXPelsPerMeter;
705 | LONG biYPelsPerMeter;
706 | DWORD biClrUsed;
707 | DWORD biClrImportant;
708 | } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
709 |
710 |
711 | typedef struct tagBITMAPINFO {
712 | BITMAPINFOHEADER bmiHeader;
713 | RGBQUAD bmiColors[1];
714 | } BITMAPINFO, *PBITMAPINFO;
715 |
716 |
717 | typedef struct tagCIEXYZ {
718 | FXPT2DOT30 ciexyzX;
719 | FXPT2DOT30 ciexyzY;
720 | FXPT2DOT30 ciexyzZ;
721 | } CIEXYZ, * PCIEXYZ;
722 |
723 |
724 | typedef struct tagCIEXYZTRIPLE {
725 | CIEXYZ ciexyzRed;
726 | CIEXYZ ciexyzGreen;
727 | CIEXYZ ciexyzBlue;
728 | } CIEXYZTRIPLE, *PCIEXYZTRIPLE;
729 |
730 |
731 |
732 | typedef struct {
733 | DWORD bV4Size;
734 | LONG bV4Width;
735 | LONG bV4Height;
736 | WORD bV4Planes;
737 | WORD bV4BitCount;
738 | DWORD bV4V4Compression;
739 | DWORD bV4SizeImage;
740 | LONG bV4XPelsPerMeter;
741 | LONG bV4YPelsPerMeter;
742 | DWORD bV4ClrUsed;
743 | DWORD bV4ClrImportant;
744 | DWORD bV4RedMask;
745 | DWORD bV4GreenMask;
746 | DWORD bV4BlueMask;
747 | DWORD bV4AlphaMask;
748 | DWORD bV4CSType;
749 | CIEXYZTRIPLE bV4Endpoints;
750 | DWORD bV4GammaRed;
751 | DWORD bV4GammaGreen;
752 | DWORD bV4GammaBlue;
753 | } BITMAPV4HEADER, *PBITMAPV4HEADER;
754 |
755 | typedef struct {
756 | DWORD bV5Size;
757 | LONG bV5Width;
758 | LONG bV5Height;
759 | WORD bV5Planes;
760 | WORD bV5BitCount;
761 | DWORD bV5Compression;
762 | DWORD bV5SizeImage;
763 | LONG bV5XPelsPerMeter;
764 | LONG bV5YPelsPerMeter;
765 | DWORD bV5ClrUsed;
766 | DWORD bV5ClrImportant;
767 | DWORD bV5RedMask;
768 | DWORD bV5GreenMask;
769 | DWORD bV5BlueMask;
770 | DWORD bV5AlphaMask;
771 | DWORD bV5CSType;
772 | CIEXYZTRIPLE bV5Endpoints;
773 | DWORD bV5GammaRed;
774 | DWORD bV5GammaGreen;
775 | DWORD bV5GammaBlue;
776 | DWORD bV5Intent;
777 | DWORD bV5ProfileData;
778 | DWORD bV5ProfileSize;
779 | DWORD bV5Reserved;
780 | } BITMAPV5HEADER, *PBITMAPV5HEADER;
781 |
782 | ]]
783 |
784 |
785 | BITMAPINFOHEADER = nil
786 | BITMAPINFOHEADER_mt = {
787 | __new = function(ct)
788 | print("BITMAPINFOHEADER: new()");
789 | return ffi.new(ct, ffi.sizeof(ct))
790 | end,
791 |
792 | __index = {
793 | Init = function(self)
794 | print("BITMAPINFOHEADER:Init()");
795 | self.biSize = ffi.sizeof("BITMAPINFOHEADER")
796 | end,
797 | }
798 | }
799 | BITMAPINFOHEADER = ffi.metatype("BITMAPINFOHEADER", BITMAPINFOHEADER_mt)
800 |
801 |
802 | BITMAPINFO = nil
803 | BITMAPINFO_mt = {
804 | __new = function(ct)
805 | local obj = ffi.new(ct)
806 | obj.bmiHeader:Init();
807 | return obj;
808 | end,
809 |
810 |
811 | }
812 | BITMAPINFO = ffi.metatype("BITMAPINFO", BITMAPINFO_mt)
813 |
814 |
815 |
--------------------------------------------------------------------------------
/WinBase.lua:
--------------------------------------------------------------------------------
1 | -- WinBase.lua
2 | -- From WinBase.h
3 | local ffi = require "ffi"
4 | local bit = require "bit"
5 | local bor = bit.bor
6 | local lshift = bit.lshift
7 | local rshift = bit.rshift
8 |
9 | require "WTypes"
10 |
11 |
12 | INVALID_HANDLE_VALUE = ffi.cast("intptr_t", -1)
13 | INVALID_FILE_SIZE = (0xFFFFFFFF);
14 | INVALID_SET_FILE_POINTER = (-1);
15 | INVALID_FILE_ATTRIBUTES = (-1);
16 |
17 | WAIT_TIMEOUT = 0X102;
18 | WAIT_OBJECT_0 = 0;
19 |
20 |
21 | function MAKEWORD(low,high)
22 | return bor(low , lshift(high , 8))
23 | end
24 |
25 | function LOWBYTE(word)
26 | return band(word, 0xff)
27 | end
28 |
29 | function HIGHBYTE(word)
30 | return band(rshift(word,8), 0xff)
31 | end
32 |
33 |
34 |
35 |
36 | OPEN_ALWAYS = 4;
37 | OPEN_EXISTING = 3;
38 |
39 | GENERIC_READ = 0x80000000;
40 | GENERIC_WRITE = 0x40000000;
41 | GENERIC_EXECUTE = 0x20000000;
42 | GENERIC_ALL = 0x10000000;
43 |
44 | PURGE_TXABORT = 0x01;
45 | PURGE_RXABORT = 0x02;
46 | PURGE_TXCLEAR = 0x04;
47 | PURGE_RXCLEAR = 0x08;
48 |
49 |
50 | ERROR_IO_PENDING = 0x03E5; -- 997
51 |
52 | INFINITE = 0xFFFFFFFF;
53 |
54 |
55 | -- Access Rights
56 | DELETE = 0x00010000
57 | READ_CONTROL = 0x00020000
58 | WRITE_DAC = 0x00040000
59 | WRITE_OWNER = 0x00080000
60 | SYNCHRONIZE = 0x00100000
61 |
62 | STANDARD_RIGHTS_REQUIRED = 0x000F0000
63 |
64 | STANDARD_RIGHTS_READ = READ_CONTROL
65 | STANDARD_RIGHTS_WRITE = READ_CONTROL
66 | STANDARD_RIGHTS_EXECUTE = READ_CONTROL
67 |
68 | STANDARD_RIGHTS_ALL = 0x001F0000
69 | SPECIFIC_RIGHTS_ALL = 0x0000FFFF
70 |
71 |
72 | -- File access rights
73 | FILE_FLAG_OVERLAPPED = 0X40000000;
74 |
75 | FILE_READ_DATA = 0x0001; -- file & pipe
76 | FILE_WRITE_DATA = 0x0002; -- file & pipe
77 | FILE_APPEND_DATA = 0x0004; -- file
78 | FILE_READ_EA = 0x0008; -- file & directory
79 | FILE_WRITE_EA = 0x0010; -- file & directory
80 | FILE_EXECUTE = 0x0020; -- file
81 | FILE_READ_ATTRIBUTES = 0x0080; -- all
82 | FILE_WRITE_ATTRIBUTES = 0x0100; -- all
83 |
84 |
85 | FILE_ALL_ACCESS = bor(STANDARD_RIGHTS_REQUIRED, SYNCHRONIZE, 0x1FF);
86 | FILE_GENERIC_READ = bor(STANDARD_RIGHTS_READ,FILE_READ_DATA,FILE_READ_ATTRIBUTES,FILE_READ_EA,SYNCHRONIZE);
87 | FILE_GENERIC_WRITE = bor(STANDARD_RIGHTS_WRITE ,FILE_WRITE_DATA,FILE_WRITE_ATTRIBUTES,FILE_WRITE_EA,FILE_APPEND_DATA,SYNCHRONIZE);
88 | FILE_GENERIC_EXECUTE = bor(STANDARD_RIGHTS_EXECUTE, FILE_READ_ATTRIBUTES, FILE_EXECUTE, SYNCHRONIZE);
89 |
90 | -- CreateFile()
91 | -- dwDesiredAccess
92 |
93 | -- dwShareMode
94 | FILE_SHARE_READ = 0x00000001;
95 | FILE_SHARE_WRITE = 0x00000002;
96 | FILE_SHARE_DELETE = 0x00000004;
97 |
98 | -- dwCreationDisposition
99 | CREATE_NEW = 1;
100 | CREATE_ALWAYS = 2;
101 | OPEN_EXISTING = 3;
102 | OPEN_ALWAYS = 4;
103 | TRUNCATE_EXISTING = 5;
104 |
105 |
106 |
107 | --THREAD_ALL_ACCESS
108 | THREAD_TERMINATE = 0x0001
109 | THREAD_SUSPEND_RESUME = 0x0002
110 | THREAD_GET_CONTEXT = 0x0008
111 | THREAD_SET_CONTEXT = 0x0010
112 | THREAD_SET_INFORMATION = 0x0020
113 | THREAD_QUERY_INFORMATION = 0x0040
114 | THREAD_SET_THREAD_TOKEN = 0x0080
115 | THREAD_IMPERSONATE = 0x0100
116 | THREAD_DIRECT_IMPERSONATION = 0x0200
117 | THREAD_SET_LIMITED_INFORMATION = 0x0400
118 | THREAD_QUERY_LIMITED_INFORMATION = 0x0800
119 |
120 | -- Process dwCreationFlag values
121 |
122 | DEBUG_PROCESS = 0x00000001
123 | DEBUG_ONLY_THIS_PROCESS = 0x00000002
124 | CREATE_SUSPENDED = 0x00000004
125 | DETACHED_PROCESS = 0x00000008
126 |
127 | CREATE_NEW_CONSOLE = 0x00000010
128 | NORMAL_PRIORITY_CLASS = 0x00000020
129 | IDLE_PRIORITY_CLASS = 0x00000040
130 | HIGH_PRIORITY_CLASS = 0x00000080
131 |
132 | REALTIME_PRIORITY_CLASS = 0x00000100
133 | CREATE_NEW_PROCESS_GROUP = 0x00000200
134 | CREATE_UNICODE_ENVIRONMENT = 0x00000400
135 | CREATE_SEPARATE_WOW_VDM = 0x00000800
136 |
137 | CREATE_SHARED_WOW_VDM = 0x00001000
138 | CREATE_FORCEDOS = 0x00002000
139 | BELOW_NORMAL_PRIORITY_CLASS= 0x00004000
140 | ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000
141 |
142 | INHERIT_PARENT_AFFINITY = 0x00010000
143 | CREATE_PROTECTED_PROCESS = 0x00040000
144 | EXTENDED_STARTUPINFO_PRESENT = 0x00080000
145 |
146 | PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000
147 | PROCESS_MODE_BACKGROUND_END = 0x00200000
148 |
149 | CREATE_BREAKAWAY_FROM_JOB = 0x01000000
150 | CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000
151 | CREATE_DEFAULT_ERROR_MODE = 0x04000000
152 | CREATE_NO_WINDOW = 0x08000000
153 |
154 | PROFILE_USER = 0x10000000
155 | PROFILE_KERNEL = 0x20000000
156 | PROFILE_SERVER = 0x40000000
157 | CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000
158 |
159 |
160 | STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000 -- Threads only
161 |
162 | --
163 | -- Priority flags
164 | --
165 | --[[
166 | THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN
167 | THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1)
168 | THREAD_PRIORITY_NORMAL 0
169 | THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX
170 | THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1)
171 | THREAD_PRIORITY_ERROR_RETURN (MAXLONG)
172 |
173 | THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
174 | THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE
175 |
176 | THREAD_MODE_BACKGROUND_BEGIN 0x00010000
177 | THREAD_MODE_BACKGROUND_END 0x00020000
178 | --]]
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 | ffi.cdef[[
192 |
193 |
194 |
195 | typedef struct _BY_HANDLE_FILE_INFORMATION {
196 | DWORD dwFileAttributes;
197 | FILETIME ftCreationTime;
198 | FILETIME ftLastAccessTime;
199 | FILETIME ftLastWriteTime;
200 | DWORD dwVolumeSerialNumber;
201 | DWORD nFileSizeHigh;
202 | DWORD nFileSizeLow;
203 | DWORD nNumberOfLinks;
204 | DWORD nFileIndexHigh;
205 | DWORD nFileIndexLow;
206 | } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION, *LPBY_HANDLE_FILE_INFORMATION;
207 | ]]
208 |
209 | ffi.cdef[[
210 | typedef struct _STARTUPINFO {
211 | DWORD cb;
212 | LPTSTR lpReserved;
213 | LPTSTR lpDesktop;
214 | LPTSTR lpTitle;
215 | DWORD dwX;
216 | DWORD dwY;
217 | DWORD dwXSize;
218 | DWORD dwYSize;
219 | DWORD dwXCountChars;
220 | DWORD dwYCountChars;
221 | DWORD dwFillAttribute;
222 | DWORD dwFlags;
223 | WORD wShowWindow;
224 | WORD cbReserved2;
225 | LPBYTE lpReserved2;
226 | HANDLE hStdInput;
227 | HANDLE hStdOutput;
228 | HANDLE hStdError;
229 | } STARTUPINFO, *LPSTARTUPINFO;
230 | ]]
231 | --
232 | -- GetOverlappedResult()
233 | --
234 | function HasOverlappedIoCompleted(lpOverlapped)
235 | return (lpOverlapped.Internal ~= STATUS_PENDING)
236 | end
237 |
--------------------------------------------------------------------------------
/WinCrypt.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | require "WTypes"
3 |
4 | ffi.cdef[[
5 | typedef void *HCERTSTORE;
6 | ]]
7 |
8 | ffi.cdef[[
9 | //+-------------------------------------------------------------------------
10 | // CRYPTOAPI BLOB definitions
11 | //--------------------------------------------------------------------------
12 |
13 | typedef struct _CRYPTOAPI_BLOB {
14 | DWORD cbData;
15 | BYTE *pbData;
16 | } CRYPT_INTEGER_BLOB, *PCRYPT_INTEGER_BLOB,
17 | CRYPT_UINT_BLOB, *PCRYPT_UINT_BLOB,
18 | CRYPT_OBJID_BLOB, *PCRYPT_OBJID_BLOB,
19 | CERT_NAME_BLOB, *PCERT_NAME_BLOB,
20 | CERT_RDN_VALUE_BLOB, *PCERT_RDN_VALUE_BLOB,
21 | CERT_BLOB, *PCERT_BLOB,
22 | CRL_BLOB, *PCRL_BLOB,
23 | DATA_BLOB, *PDATA_BLOB,
24 | CRYPT_DATA_BLOB, *PCRYPT_DATA_BLOB,
25 | CRYPT_HASH_BLOB, *PCRYPT_HASH_BLOB,
26 | CRYPT_DIGEST_BLOB, *PCRYPT_DIGEST_BLOB,
27 | CRYPT_DER_BLOB, *PCRYPT_DER_BLOB,
28 | CRYPT_ATTR_BLOB, *PCRYPT_ATTR_BLOB;
29 |
30 | //+-------------------------------------------------------------------------
31 | // In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the
32 | // overall bit length is cbData * 8 - cUnusedBits.
33 | //--------------------------------------------------------------------------
34 | // certenrolls_begin -- CERT_CONTEXT
35 | typedef struct _CRYPT_BIT_BLOB {
36 | DWORD cbData;
37 | BYTE *pbData;
38 | DWORD cUnusedBits;
39 | } CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;
40 | ]]
41 |
42 | ffi.cdef[[
43 | //+-------------------------------------------------------------------------
44 | // Type used for any algorithm
45 | //
46 | // Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most
47 | // algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0).
48 | //--------------------------------------------------------------------------
49 | typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
50 | LPSTR pszObjId;
51 | CRYPT_OBJID_BLOB Parameters;
52 | } CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;
53 | // certenrolls_end
54 | ]]
55 |
56 |
57 | ffi.cdef[[
58 | //+-------------------------------------------------------------------------
59 | // Public Key Info
60 | //
61 | // The PublicKey is the encoded representation of the information as it is
62 | // stored in the bit string
63 | //--------------------------------------------------------------------------
64 | // certenrolls_begin -- CERT_CONTEXT
65 | typedef struct _CERT_PUBLIC_KEY_INFO {
66 | CRYPT_ALGORITHM_IDENTIFIER Algorithm;
67 | CRYPT_BIT_BLOB PublicKey;
68 | } CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;
69 | // certenrolls_end
70 | ]]
71 |
72 | ffi.cdef[[
73 | //+-------------------------------------------------------------------------
74 | // Type used for an extension to an encoded content
75 | //
76 | // Where the Value's CRYPT_OBJID_BLOB is in its encoded representation.
77 | //--------------------------------------------------------------------------
78 | // certenrolls_begin -- CERT_CONTEXT
79 | typedef struct _CERT_EXTENSION {
80 | LPSTR pszObjId;
81 | BOOL fCritical;
82 | CRYPT_OBJID_BLOB Value;
83 | } CERT_EXTENSION, *PCERT_EXTENSION;
84 | typedef const CERT_EXTENSION* PCCERT_EXTENSION;
85 | // certenrolls_end
86 |
87 |
88 | //+-------------------------------------------------------------------------
89 | // Information stored in a certificate
90 | //
91 | // The Issuer, Subject, Algorithm, PublicKey and Extension BLOBs are the
92 | // encoded representation of the information.
93 | //--------------------------------------------------------------------------
94 | // certenrolls_begin -- CERT_CONTEXT
95 | typedef struct _CERT_INFO {
96 | DWORD dwVersion;
97 | CRYPT_INTEGER_BLOB SerialNumber;
98 | CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm;
99 | CERT_NAME_BLOB Issuer;
100 | FILETIME NotBefore;
101 | FILETIME NotAfter;
102 | CERT_NAME_BLOB Subject;
103 | CERT_PUBLIC_KEY_INFO SubjectPublicKeyInfo;
104 | CRYPT_BIT_BLOB IssuerUniqueId;
105 | CRYPT_BIT_BLOB SubjectUniqueId;
106 | DWORD cExtension;
107 | PCERT_EXTENSION rgExtension;
108 | } CERT_INFO, *PCERT_INFO;
109 | // certenrolls_end
110 | ]]
111 |
112 | ffi.cdef[[
113 | //+-------------------------------------------------------------------------
114 | // Certificate context.
115 | //
116 | // A certificate context contains both the encoded and decoded representation
117 | // of a certificate. A certificate context returned by a cert store function
118 | // must be freed by calling the CertFreeCertificateContext function. The
119 | // CertDuplicateCertificateContext function can be called to make a duplicate
120 | // copy (which also must be freed by calling CertFreeCertificateContext).
121 | //--------------------------------------------------------------------------
122 | // certenrolls_begin -- CERT_CONTEXT
123 | typedef struct _CERT_CONTEXT {
124 | DWORD dwCertEncodingType;
125 | BYTE *pbCertEncoded;
126 | DWORD cbCertEncoded;
127 | PCERT_INFO pCertInfo;
128 | HCERTSTORE hCertStore;
129 | } CERT_CONTEXT, *PCERT_CONTEXT;
130 | typedef const CERT_CONTEXT *PCCERT_CONTEXT;
131 | // certenrolls_end
132 | ]]
133 |
--------------------------------------------------------------------------------
/WinError.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | local bit = require "bit"
3 | local band = bit.band
4 | local bor = bit.bor
5 | local rshift = bit.rshift
6 | local lshift = bit.lshift
7 |
8 |
9 |
10 | --[[
11 | //
12 | // The return value of COM functions and methods is an HRESULT.
13 | // This is not a handle to anything, but is merely a 32-bit value
14 | // with several fields encoded in the value. The parts of an
15 | // HRESULT are shown below.
16 | //
17 | // Many of the macros and functions below were orginally defined to
18 | // operate on SCODEs. SCODEs are no longer used. The macros are
19 | // still present for compatibility and easy porting of Win16 code.
20 | // Newly written code should use the HRESULT macros and functions.
21 | //
22 |
23 | //
24 | // HRESULTs are 32 bit values layed out as follows:
25 | //
26 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
27 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
28 | // +-+-+-+-+-+---------------------+-------------------------------+
29 | // |S|R|C|N|r| Facility | Code |
30 | // +-+-+-+-+-+---------------------+-------------------------------+
31 | //
32 | // where
33 | //
34 | // S - Severity - indicates success/fail
35 | //
36 | // 0 - Success
37 | // 1 - Fail (COERROR)
38 | //
39 | // R - reserved portion of the facility code, corresponds to NT's
40 | // second severity bit.
41 | //
42 | // C - reserved portion of the facility code, corresponds to NT's
43 | // C field.
44 | //
45 | // N - reserved portion of the facility code. Used to indicate a
46 | // mapped NT status value.
47 | //
48 | // r - reserved portion of the facility code. Reserved for internal
49 | // use. Used to indicate HRESULT values that are not status
50 | // values, but are instead message ids for display strings.
51 | //
52 | // Facility - is the facility code
53 | //
54 | // Code - is the facility's status code
55 | //
56 | --]]
57 |
58 | --
59 | -- Define the facility codes
60 | --
61 |
62 | FACILITY_NULL = 0
63 | FACILITY_RPC = 1
64 | FACILITY_DISPATCH = 2
65 | FACILITY_STORAGE = 3
66 | FACILITY_ITF = 4
67 | FACILITY_WIN32 = 7
68 | FACILITY_NTWIN32 = 7
69 | FACILITY_WINDOWS = 8
70 | FACILITY_SSPI = 9
71 | FACILITY_SECURITY = 9
72 |
73 | FACILITY_CONTROL = 10
74 | FACILITY_CERT = 11
75 | FACILITY_INTERNET = 12
76 | FACILITY_MEDIASERVER = 13
77 | FACILITY_MSMQ = 14
78 | FACILITY_SETUPAPI = 15
79 | FACILITY_SCARD = 16
80 | FACILITY_COMPLUS = 17
81 | FACILITY_AAF = 18
82 | FACILITY_URT = 19
83 |
84 | FACILITY_ACS = 20
85 | FACILITY_DPLAY = 21
86 | FACILITY_UMI = 22
87 | FACILITY_SXS = 23
88 | FACILITY_WINDOWS_CE = 24
89 | FACILITY_HTTP = 25
90 | FACILITY_USERMODE_COMMONLOG = 26
91 |
92 | FACILITY_USERMODE_FILTER_MANAGER = 31
93 | FACILITY_BACKGROUNDCOPY = 32
94 | FACILITY_CONFIGURATION = 33
95 | FACILITY_STATE_MANAGEMENT = 34
96 | FACILITY_METADIRECTORY = 35
97 | FACILITY_WINDOWSUPDATE = 36
98 | FACILITY_DIRECTORYSERVICE = 37
99 | FACILITY_GRAPHICS = 38
100 | FACILITY_SHELL = 39
101 |
102 | FACILITY_TPM_SERVICES = 40
103 | FACILITY_TPM_SOFTWARE = 41
104 | FACILITY_UI = 42
105 | FACILITY_PLA = 48
106 | FACILITY_FVE = 49
107 |
108 | FACILITY_FWP = 50
109 | FACILITY_WINRM = 51
110 | FACILITY_NDIS = 52
111 | FACILITY_USERMODE_HYPERVISOR = 53
112 | FACILITY_CMI = 54
113 | FACILITY_USERMODE_VIRTUALIZATION = 55
114 | FACILITY_USERMODE_VOLMGR = 56
115 | FACILITY_BCD = 57
116 | FACILITY_USERMODE_VHD = 58
117 |
118 | FACILITY_SDIAG = 60
119 | FACILITY_WEBSERVICES = 61
120 |
121 | FACILITY_WINDOWS_DEFENDER = 80
122 | FACILITY_OPC = 81
123 | FACILITY_XPS = 82
124 | FACILITY_RAS = 83
125 | FACILITY_MBN = 84
126 |
127 | --
128 | -- MessageId: ERROR_SUCCESS
129 | --
130 | -- MessageText:
131 | --
132 | -- The operation completed successfully.
133 | --
134 | ERROR_SUCCESS = 0
135 |
136 | NO_ERROR = 0
137 | SEC_E_OK = 0x00000000
138 |
139 | -- for KINECT
140 |
141 | ERROR_DEVICE_NOT_CONNECTED = 1167
142 | ERROR_NOT_READY = 21
143 | ERROR_ALREADY_INITIALIZED = 1247
144 | ERROR_NO_MORE_ITEMS = 259
145 |
146 | E_POINTER = (0x80004003) -- Invalid pointer
147 |
148 | --[[
149 | #define ERROR_INVALID_FUNCTION 1L // dderror
150 | #define ERROR_FILE_NOT_FOUND 2L
151 | #define ERROR_PATH_NOT_FOUND 3L
152 | #define ERROR_TOO_MANY_OPEN_FILES 4L
153 | #define ERROR_ACCESS_DENIED 5L
154 | #define ERROR_INVALID_HANDLE 6L
155 | #define ERROR_ARENA_TRASHED 7L
156 | #define ERROR_NOT_ENOUGH_MEMORY 8L // dderror
157 | #define ERROR_INVALID_BLOCK 9L
158 | #define ERROR_BAD_ENVIRONMENT 10L
159 | #define ERROR_BAD_FORMAT 11L
160 | #define ERROR_INVALID_ACCESS 12L
161 | #define ERROR_INVALID_DATA 13L
162 | #define ERROR_OUTOFMEMORY 14L
163 | #define ERROR_INVALID_DRIVE 15L
164 | #define ERROR_CURRENT_DIRECTORY 16L
165 | #define ERROR_NOT_SAME_DEVICE 17L
166 | #define ERROR_NO_MORE_FILES 18L
167 | #define ERROR_WRITE_PROTECT 19L
168 | #define ERROR_BAD_UNIT 20L
169 | #define ERROR_NOT_READY 21L
170 | #define ERROR_BAD_COMMAND 22L
171 | #define ERROR_CRC 23L
172 | #define ERROR_BAD_LENGTH 24L
173 | #define ERROR_SEEK 25L
174 | #define ERROR_NOT_DOS_DISK 26L
175 | #define ERROR_SECTOR_NOT_FOUND 27L
176 | #define ERROR_OUT_OF_PAPER 28L
177 | #define ERROR_WRITE_FAULT 29L
178 | #define ERROR_READ_FAULT 30L
179 | #define ERROR_GEN_FAILURE 31L
180 | #define ERROR_SHARING_VIOLATION 32L
181 | #define ERROR_LOCK_VIOLATION 33L
182 | #define ERROR_WRONG_DISK 34L
183 | #define ERROR_SHARING_BUFFER_EXCEEDED 36L
184 | #define ERROR_HANDLE_EOF 38L
185 | #define ERROR_HANDLE_DISK_FULL 39L
186 | #define ERROR_NOT_SUPPORTED 50L
187 | #define ERROR_REM_NOT_LIST 51L
188 | #define ERROR_DUP_NAME 52L
189 | #define ERROR_BAD_NETPATH 53L
190 | #define ERROR_NETWORK_BUSY 54L
191 | #define ERROR_DEV_NOT_EXIST 55L // dderror
192 | #define ERROR_TOO_MANY_CMDS 56L
193 | #define ERROR_ADAP_HDW_ERR 57L
194 | #define ERROR_BAD_NET_RESP 58L
195 | #define ERROR_UNEXP_NET_ERR 59L
196 | #define ERROR_BAD_REM_ADAP 60L
197 | #define ERROR_PRINTQ_FULL 61L
198 | #define ERROR_NO_SPOOL_SPACE 62L
199 | #define ERROR_PRINT_CANCELLED 63L
200 | #define ERROR_NETNAME_DELETED 64L
201 | #define ERROR_NETWORK_ACCESS_DENIED 65L
202 | #define ERROR_BAD_DEV_TYPE 66L
203 | #define ERROR_BAD_NET_NAME 67L
204 | #define ERROR_TOO_MANY_NAMES 68L
205 | #define ERROR_TOO_MANY_SESS 69L
206 | #define ERROR_SHARING_PAUSED 70L
207 | #define ERROR_REQ_NOT_ACCEP 71L
208 | #define ERROR_REDIR_PAUSED 72L
209 | #define ERROR_FILE_EXISTS 80L
210 | #define ERROR_CANNOT_MAKE 82L
211 | #define ERROR_FAIL_I24 83L
212 | #define ERROR_OUT_OF_STRUCTURES 84L
213 | #define ERROR_ALREADY_ASSIGNED 85L
214 | #define ERROR_INVALID_PASSWORD 86L
215 | #define ERROR_INVALID_PARAMETER 87L // dderror
216 | #define ERROR_NET_WRITE_FAULT 88L
217 | #define ERROR_NO_PROC_SLOTS 89L
218 | #define ERROR_TOO_MANY_SEMAPHORES 100L
219 | #define ERROR_EXCL_SEM_ALREADY_OWNED 101L
220 | --]]
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 | --
237 | -- Severity values
238 | --
239 |
240 | SEVERITY_SUCCESS = 0
241 | SEVERITY_ERROR = 1
242 |
243 | function NT_SUCCESS(status)
244 | return status >= 0
245 | end
246 |
247 | --
248 | -- Generic test for success on any status value (non-negative numbers
249 | -- indicate success).
250 | --
251 |
252 | function SUCCEEDED(hr)
253 | return hr >= 0
254 | end
255 |
256 | --
257 | -- and the inverse
258 | --
259 |
260 | function FAILED(hr)
261 | return hr < 0
262 | end
263 |
264 |
265 | --
266 | -- Generic test for error on any status value.
267 | --
268 |
269 | function IS_ERROR(Status)
270 | return rshift(Status, 31) == SEVERITY_ERROR
271 | end
272 |
273 | --
274 | -- Return the code
275 | --
276 |
277 | function HRESULT_CODE(hr)
278 | return band(hr, 0xFFFF)
279 | end
280 |
281 | --
282 | -- Return the facility
283 | --
284 |
285 | function HRESULT_FACILITY(hr)
286 | return band(rshift(hr, 16), 0x1fff)
287 | end
288 |
289 | --
290 | -- Return the severity
291 | --
292 |
293 | function HRESULT_SEVERITY(hr)
294 | return band(rshift(hr, 31), 0x1)
295 | end
296 |
297 | function HRESULT_PARTS(hr)
298 | return HRESULT_SEVERITY(hr), HRESULT_FACILITY(hr), HRESULT_CODE(hr)
299 | end
300 |
301 | --
302 | -- Create an HRESULT value from component pieces
303 | --
304 |
305 | function MAKE_HRESULT(severity,facility,code)
306 | return bor(lshift(severity,31) , lshift(facility,16) , code)
307 | end
308 |
309 |
310 | --
311 | -- HRESULT_FROM_WIN32(x) used to be a macro, however we now run it as an inline function
312 | -- to prevent double evaluation of 'x'. If you still need the macro, you can use __HRESULT_FROM_WIN32(x)
313 | --
314 | function HRESULT_FROM_WIN32(x)
315 | if x <= 0 then
316 | return x
317 | end
318 |
319 | return bor(band(x, 0x0000FFFF), lshift(FACILITY_WIN32, 16), 0x80000000)
320 | end
321 |
322 |
323 | -- This is not the NTSTATUS_FROM_WIN32 that the DDK provides,
324 | -- because the DDK got it wrong!
325 | local ERROR_SEVERITY_WARNING = 0x80000000
326 |
327 | function NTSTATUS_FROM_WIN32(err)
328 | if err <= 0 then
329 | return err
330 | end
331 |
332 | return bor(band(err, 0x0000FFFF), lshift(FACILITY_NTWIN32, 16), ERROR_SEVERITY_WARNING);
333 | end
334 |
335 | NTE_BAD_FLAGS = 0x80090009;
336 | NTE_INVALID_HANDLE = 0x80090026;
337 | NTE_INVALID_PARAMETER = 0x80090027;
338 | NTE_NO_MEMORY = 0x8009000E;
339 |
340 | NTE_NO_MORE_ITEMS = 0x8009002A;
341 | NTE_SILENT_CONTEXT = 0x80090022;
342 |
--------------------------------------------------------------------------------
/WinNT.lua:
--------------------------------------------------------------------------------
1 | local ffi = require("ffi")
2 |
3 | local _WIN64 = ffi.os == "Windows" and ffi.abi("64bit");
4 |
5 |
6 |
7 |
8 | ffi.cdef[[
9 | static const int IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16;
10 |
11 | static const int MAX_PATH = 260;
12 |
13 | typedef struct _IMAGE_FILE_HEADER {
14 | WORD Machine;
15 | WORD NumberOfSections;
16 | DWORD TimeDateStamp;
17 | DWORD PointerToSymbolTable;
18 | DWORD NumberOfSymbols;
19 | WORD SizeOfOptionalHeader;
20 | WORD Characteristics;
21 | } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
22 |
23 | typedef struct _IMAGE_DATA_DIRECTORY {
24 | DWORD VirtualAddress;
25 | DWORD Size;
26 | } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
27 |
28 | //
29 | // Optional header format.
30 | //
31 |
32 | typedef struct _IMAGE_OPTIONAL_HEADER {
33 | //
34 | // Standard fields.
35 | //
36 |
37 | WORD Magic;
38 | BYTE MajorLinkerVersion;
39 | BYTE MinorLinkerVersion;
40 | DWORD SizeOfCode;
41 | DWORD SizeOfInitializedData;
42 | DWORD SizeOfUninitializedData;
43 | DWORD AddressOfEntryPoint;
44 | DWORD BaseOfCode;
45 | DWORD BaseOfData;
46 |
47 | //
48 | // NT additional fields.
49 | //
50 |
51 | DWORD ImageBase;
52 | DWORD SectionAlignment;
53 | DWORD FileAlignment;
54 | WORD MajorOperatingSystemVersion;
55 | WORD MinorOperatingSystemVersion;
56 | WORD MajorImageVersion;
57 | WORD MinorImageVersion;
58 | WORD MajorSubsystemVersion;
59 | WORD MinorSubsystemVersion;
60 | DWORD Win32VersionValue;
61 | DWORD SizeOfImage;
62 | DWORD SizeOfHeaders;
63 | DWORD CheckSum;
64 | WORD Subsystem;
65 | WORD DllCharacteristics;
66 | DWORD SizeOfStackReserve;
67 | DWORD SizeOfStackCommit;
68 | DWORD SizeOfHeapReserve;
69 | DWORD SizeOfHeapCommit;
70 | DWORD LoaderFlags;
71 | DWORD NumberOfRvaAndSizes;
72 | IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
73 | } IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
74 |
75 |
76 | typedef struct _IMAGE_OPTIONAL_HEADER64 {
77 | WORD Magic;
78 | BYTE MajorLinkerVersion;
79 | BYTE MinorLinkerVersion;
80 | DWORD SizeOfCode;
81 | DWORD SizeOfInitializedData;
82 | DWORD SizeOfUninitializedData;
83 | DWORD AddressOfEntryPoint;
84 | DWORD BaseOfCode;
85 | ULONGLONG ImageBase;
86 | DWORD SectionAlignment;
87 | DWORD FileAlignment;
88 | WORD MajorOperatingSystemVersion;
89 | WORD MinorOperatingSystemVersion;
90 | WORD MajorImageVersion;
91 | WORD MinorImageVersion;
92 | WORD MajorSubsystemVersion;
93 | WORD MinorSubsystemVersion;
94 | DWORD Win32VersionValue;
95 | DWORD SizeOfImage;
96 | DWORD SizeOfHeaders;
97 | DWORD CheckSum;
98 | WORD Subsystem;
99 | WORD DllCharacteristics;
100 | ULONGLONG SizeOfStackReserve;
101 | ULONGLONG SizeOfStackCommit;
102 | ULONGLONG SizeOfHeapReserve;
103 | ULONGLONG SizeOfHeapCommit;
104 | DWORD LoaderFlags;
105 | DWORD NumberOfRvaAndSizes;
106 | IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
107 | } IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
108 |
109 |
110 | typedef struct _IMAGE_NT_HEADERS64 {
111 | DWORD Signature;
112 | IMAGE_FILE_HEADER FileHeader;
113 | IMAGE_OPTIONAL_HEADER64 OptionalHeader;
114 | } IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
115 |
116 | typedef struct _IMAGE_NT_HEADERS {
117 | DWORD Signature;
118 | IMAGE_FILE_HEADER FileHeader;
119 | IMAGE_OPTIONAL_HEADER32 OptionalHeader;
120 | } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
121 | ]]
122 |
123 | if _WIN64 then
124 | ffi.cdef[[
125 | typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
126 | typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
127 | ]]
128 | else
129 | ffi.cdef[[
130 | typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
131 | typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
132 | ]]
133 | end
134 |
135 | ffi.cdef[[
136 | //
137 | // Section header format.
138 | //
139 |
140 | static const int IMAGE_SIZEOF_SHORT_NAME = 8;
141 |
142 | typedef struct _IMAGE_SECTION_HEADER {
143 | BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
144 | union {
145 | DWORD PhysicalAddress;
146 | DWORD VirtualSize;
147 | } Misc;
148 | DWORD VirtualAddress;
149 | DWORD SizeOfRawData;
150 | DWORD PointerToRawData;
151 | DWORD PointerToRelocations;
152 | DWORD PointerToLinenumbers;
153 | WORD NumberOfRelocations;
154 | WORD NumberOfLinenumbers;
155 | DWORD Characteristics;
156 | } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
157 |
158 | ]]
159 |
160 | ffi.cdef[[
161 | //
162 | // Doubly linked list structure. Can be used as either a list head, or
163 | // as link words.
164 | //
165 |
166 | typedef struct _LIST_ENTRY {
167 | struct _LIST_ENTRY *Flink;
168 | struct _LIST_ENTRY *Blink;
169 | } LIST_ENTRY, *PLIST_ENTRY, * PRLIST_ENTRY;
170 | ]]
--------------------------------------------------------------------------------
/WinSock_Utils.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require "ffi"
3 |
4 | local wsock = require "win_socket"
5 | local SocketType = wsock.SocketType
6 | local Protocol = wsock.Protocol
7 | local Family = wsock.Family
8 |
9 | -- Startup windows sockets
10 | local SocketLib = ffi.load("ws2_32")
11 |
12 | --[[
13 | Casual Macros
14 | --]]
15 |
16 | function IN4_CLASSA(i)
17 | return (band(i, 0x00000080) == 0)
18 | end
19 |
20 | function IN4_CLASSB(i)
21 | return (band(i, 0x000000c0) == 0x00000080)
22 | end
23 |
24 | function IN4_CLASSC(i)
25 | return (band(i, 0x000000e0) == 0x000000c0)
26 | end
27 |
28 | function IN4_CLASSD(i)
29 | return (band(i, 0x000000f0) == 0x000000e0)
30 | end
31 |
32 | IN4_MULTICAST = IN4_CLASSD
33 |
34 |
35 | --[[
36 | Data Structures
37 | --]]
38 |
39 | IN_ADDR = ffi.typeof("struct in_addr");
40 | IN_ADDR_mt = {
41 | __gc = function (self)
42 | print("-- IN_ADDR: GC");
43 | end,
44 |
45 | __tostring = function(self)
46 | local res = SocketLib.inet_ntoa(self)
47 | if res then
48 | return ffi.string(res)
49 | end
50 |
51 | return nil
52 | end,
53 |
54 | __index = {
55 | Assign = function(self, rhs)
56 | --print("IN_ADDR Assign: ", rhs.s_addr)
57 | self.S_addr = rhs.S_addr
58 | return self
59 | end,
60 |
61 | Clone = function(self)
62 | local obj = IN_ADDR(self.S_addr)
63 | return obj
64 | end,
65 |
66 | --[[
67 | SetFromString = function(self, src)
68 | local tmpptr = ffi.new("struct in_addr[1]")
69 | wsock.inet_pton(AF_INET, src, tmpptr);
70 | self:Assign(tmpptr[0])
71 |
72 | return self
73 | end,
74 | --]]
75 | },
76 | }
77 | IN_ADDR = ffi.metatype(IN_ADDR, IN_ADDR_mt)
78 |
79 |
80 | local families = {
81 | [Family.AF_INET] = "AF_INET",
82 | [Family.AF_INET6] = "AF_INET6",
83 | }
84 |
85 | local socktypes = {
86 | [SocketType.SOCK_STREAM] = "SOCK_STREAM",
87 | [SocketType.SOCK_DGRAM] = "SOCK_DGRAM",
88 | }
89 |
90 | local protocols = {
91 | [Protocol.IPPROTO_IP] = "IPPROTO_IP",
92 | [Protocol.IPPROTO_TCP] = "IPPROTO_TCP",
93 | [Protocol.IPPROTO_UDP] = "IPPROTO_UDP",
94 | }
95 |
96 |
97 | sockaddr_in = ffi.typeof("struct sockaddr_in")
98 | sockaddr_in_mt = {
99 | __gc = function (self)
100 | --print("GC: sockaddr_in");
101 | end,
102 |
103 | __new = function(ct, port, family)
104 | port = port or 80
105 | family = family or Family.AF_INET;
106 |
107 | local obj = ffi.new(ct)
108 | obj.sin_family = family;
109 | obj.sin_addr.S_addr = SocketLib.htonl(INADDR_ANY);
110 | obj.sin_port = SocketLib.htons(port);
111 |
112 | return obj
113 | end,
114 |
115 | __tostring = function(self)
116 | return string.format("Family: %s Port: %d Address: %s",
117 | families[self.sin_family], SocketLib.ntohs(self.sin_port), tostring(self.sin_addr));
118 | end,
119 |
120 | __index = {
121 | SetPort = function(self, port)
122 | self.sin_port = SocketLib.htons(port);
123 | end,
124 | },
125 | }
126 | sockaddr_in = ffi.metatype(sockaddr_in, sockaddr_in_mt);
127 |
128 | sockaddr_in6 = ffi.typeof("struct sockaddr_in6")
129 | sockaddr_in6_mt = {
130 | __gc = function (self)
131 | print("-- sockaddr_in6: GC");
132 | end,
133 |
134 | __tostring = function(self)
135 | return string.format("Family: %s Port: %d Address: %s",
136 | families[self.sin6_family], self.sin6_port, tostring(self.sin6_addr));
137 | end,
138 |
139 | __index = {
140 | SetPort = function(self, port)
141 | self.sin6_port = SocketLib.htons(port);
142 | end,
143 | },
144 | }
145 | sockaddr_in6 = ffi.metatype(sockaddr_in6, sockaddr_in6_mt);
146 |
147 |
148 | sockaddr = ffi.typeof("struct sockaddr")
149 | sockaddr_mt = {
150 | __index = {
151 | }
152 | }
153 | sockaddr = ffi.metatype(sockaddr, sockaddr_mt);
154 |
155 |
156 | addrinfo = nil
157 | addrinfo_mt = {
158 | __tostring = function(self)
159 | local family = families[self.ai_family]
160 | local socktype = socktypes[self.ai_socktype]
161 | local protocol = protocols[self.ai_protocol]
162 |
163 | --local family = self.ai_family
164 | local socktype = self.ai_socktype
165 | local protocol = self.ai_protocol
166 |
167 |
168 | local str = string.format("Socket Type: %s, Protocol: %s, %s", socktype, protocol, tostring(self.ai_addr));
169 |
170 | return str
171 | end,
172 |
173 | __index = {
174 | Print = function(self)
175 | print("-- AddrInfo ==")
176 | print("Flags: ", self.ai_flags);
177 | print("Family: ", families[self.ai_family])
178 | print("Sock Type: ", socktypes[self.ai_socktype]);
179 | print("Protocol: ", protocols[self.ai_protocol]);
180 | print("Canon Name: ", self.ai_canonname);
181 | --print("Addr Len: ", self.ai_addrlen);
182 | --print("Address: ", self.ai_addr);
183 | --print("Address Family: ", self.ai_addr.sa_family);
184 | local addr
185 | if self.ai_addr.sa_family == Family.AF_INET then
186 | addr = ffi.cast("struct sockaddr_in *", self.ai_addr)
187 | elseif self.ai_addr.sa_family == Family.AF_INET6 then
188 | addr = ffi.cast("struct sockaddr_in6 *", self.ai_addr)
189 | end
190 | print(addr);
191 |
192 | if self.ai_next ~= nil then
193 | self.ai_next:Print();
194 | end
195 | end,
196 | },
197 | }
198 | addrinfo = ffi.metatype("struct addrinfo", addrinfo_mt)
199 |
200 |
201 |
202 |
203 | --[[
204 | BSD Style functions
205 | --]]
206 | local accept = function(s, addr, addrlen)
207 | local socket = SocketLib.accept(s,addr,addrlen);
208 | if socket == INVALID_SOCKET then
209 | return false, SocketLib.WSAGetLastError();
210 | end
211 |
212 | return socket;
213 | end
214 |
215 | local bind = function(s, name, namelen)
216 | if 0 == SocketLib.bind(s, ffi.cast("const struct sockaddr *",name), namelen) then
217 | return true;
218 | end
219 |
220 | return false, WinSock.WSAGetLastError();
221 | end
222 |
223 | local connect = function(s, name, namelen)
224 | if 0 == SocketLib.connect(s, ffi.cast("const struct sockaddr *", name), namelen) then
225 | return true
226 | end
227 |
228 | return false, SocketLib.WSAGetLastError();
229 | end
230 |
231 | local closesocket = function(s)
232 | if 0 == SocketLib.closesocket(s) then
233 | return true
234 | end
235 |
236 | return false, SocketLib.WSAGetLastError();
237 | end
238 |
239 | local ioctlsocket = function(s, cmd, argp)
240 | if 0 == SocketLib.ioctlsocket(s, cmd, argp) then
241 | return true
242 | end
243 |
244 | return false, SocketLib.WSAGetLastError();
245 | end
246 |
247 | local listen = function(s, backlog)
248 | if 0 == SocketLib.listen(s, backlog) then
249 | return true
250 | end
251 |
252 | return false, SocketLib.WSAGetLastError();
253 | end
254 |
255 | local recv = function(s, buf, len, flags)
256 | len = len or #buf;
257 | flags = flags or 0;
258 |
259 | local bytesreceived = SocketLib.recv(s, ffi.cast("char*", buf), len, flags);
260 |
261 | if bytesreceived == SOCKET_ERROR then
262 | return false, SocketLib.WSAGetLastError();
263 | end
264 |
265 | return bytesreceived;
266 | end
267 |
268 | local send = function(s, buf, len, flags)
269 | len = len or #buf;
270 | flags = flags or 0;
271 |
272 | local bytessent = SocketLib.send(s, ffi.cast("const char*", buf), len, flags);
273 |
274 | if bytessent == SOCKET_ERROR then
275 | return false, SocketLib.WSAGetLastError();
276 | end
277 |
278 | return bytessent;
279 | end
280 |
281 | local setsockopt = function(s, optlevel, optname, optval, optlen)
282 | if 0 == SocketLib.setsockopt(s, optlevel, optname, ffi.cast("const uint8_t *", optval), optlen) then
283 | return true
284 | end
285 |
286 | return false, SocketLib.WSAGetLastError();
287 | end
288 |
289 | local shutdown = function(s, how)
290 | how = how or SD_BOTH
291 |
292 | if 0 == SocketLib.shutdown(s, how) then
293 | return true
294 | end
295 |
296 | return false, SocketLib.WSAGetLastError();
297 | end
298 |
299 | local socket = function(af, socktype, protocol)
300 | af = af or Family.AF_INET
301 | socktype = socktype or SocketType.SOCK_STREAM
302 | protocol = protocol or Protocol.IPPROTO_TCP
303 |
304 | local sock = SocketLib.socket(af, socktype, protocol);
305 | if sock == INVALID_SOCKET then
306 | return false, SocketLib.WSAGetLastError();
307 | end
308 |
309 | return sock;
310 | end
311 |
312 | --[[
313 | Windows Specific Socket routines
314 | --]]
315 | local WSAIoctl = function(s,dwIoControlCode,lpvInBuffer,cbInBuffer,lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,
316 | lpOverlapped,lpCompletionRoutine)
317 |
318 | local res = SocketLib.WSAIoctl(s, dwIoControlCode,
319 | lpvInBuffer, cbInBuffer,
320 | lpvOutBuffer, cbOutBuffer,
321 | lpcbBytesReturned,
322 | lpOverlapped, lpCompletionRoutine);
323 |
324 | if res ~= 0 then
325 | return false, SocketLib.WSAGetLastError();
326 | end
327 |
328 | return res
329 | end
330 |
331 | local WSAPoll = function(fdArray, fds, timeout)
332 | local res = SocketLib.WSAPoll(fdArray, fds, timeout)
333 |
334 | if SOCKET_ERROR == res then
335 | return false, SocketLib.WSAGetLastError();
336 | end
337 |
338 | return res
339 | end
340 |
341 | local WSASocket = function(af, socktype, protocol, lpProtocolInfo, g, dwFlags)
342 | af = af or Family.AF_INET;
343 | socktype = ocktype or SocketType.SOCK_STREAM;
344 | protocol = protocol or 0;
345 | lpProtocolInfo = lpProtocolInfo or nil;
346 | g = g or 0;
347 | dwFlags = dwFlags or WSA_FLAG_OVERLAPPED;
348 |
349 | local socket = SocketLib.WSASocketA(af, socktype, protocol, lpProtocolInfo, g, dwFlags);
350 |
351 | if socket == INVALID_SOCKET then
352 | return false, SocketLib.WSAGetLastError();
353 | end
354 |
355 | return socket;
356 | end
357 |
358 | --[[
359 | Retrieves the pointer to a winsock extension function.
360 | --]]
361 |
362 | local GetExtensionFunction = function(sock, gwid)
363 | local target = ffi.new("void *[1]");
364 | local pbytes = ffi.new("int32_t[1]");
365 |
366 | local result, err = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
367 | gwid,
368 | ffi.sizeof(gwid),
369 | target,
370 | ffi.sizeof(target[0]),
371 | pbytes,
372 | nil,
373 | nil);
374 |
375 |
376 | if not result then
377 | return false, err
378 | end
379 |
380 | local bytes = pbytes[0];
381 |
382 | end
383 |
384 |
385 | --[[
386 | Real convenience functions
387 | --]]
388 |
389 | local SocketErrors = {
390 | [0] = {0, "SUCCESS",},
391 | [WSAEFAULT] = {10014, "WSAEFAULT", "Bad Address"},
392 | [WSAEINVAL] = {10022, "WSAEINVAL", },
393 | [WSAEWOULDBLOCK] = {10035, "WSAEWOULDBLOCK", },
394 | [WSAEINPROGRES] = {10036, "WSAEINPROGRES", },
395 | [WSAEALREADY] = {10037, "WSAEALREADY", },
396 | [WSAENOTSOCK] = {10038, "WSAENOTSOCK", },
397 | [WSAEAFNOSUPPORT] = {10047, "WSAEAFNOSUPPORT", },
398 | [WSAECONNABORTED] = {10053, "WSAECONNABORTED", },
399 | [WSAECONNRESET] = {10054, "WSAECONNRESET", },
400 | [WSAENOBUFS] = {10055, "WSAENOBUFS", },
401 | [WSAEISCONN] = {10056, "WSAEISCONN", },
402 | [WSAENOTCONN] = {10057, "WSAENOTCONN", },
403 | [WSAESHUTDOWN] = {10058, "WSAESHUTDOWN", },
404 | [WSAETOOMANYREFS] = {10059, "WSAETOOMANYREFS", },
405 | [WSAETIMEDOUT] = {10060, "WSAETIMEDOUT", },
406 | [WSAECONNREFUSED] = {10061, "WSAECONNREFUSED", },
407 | [WSAHOST_NOT_FOUND] = {11001, "WSAHOST_NOT_FOUND", },
408 | }
409 |
410 | function GetSocketErrorString(err)
411 | if SocketErrors[err] then
412 | return SocketErrors[err][2];
413 | end
414 | return tostring(err)
415 | end
416 |
417 |
418 | local function GetLocalHostName()
419 | local name = ffi.new("char[255]")
420 | local err = SocketLib.gethostname(name, 255);
421 |
422 | return ffi.string(name)
423 | end
424 |
425 | --[[
426 | This startup routine must be called before any other functions
427 | within the library are utilized.
428 | --]]
429 |
430 | function WinsockStartup()
431 | local wVersionRequested = MAKEWORD( 2, 2 );
432 |
433 | local dataarrayname = string.format("%s[1]", wsock.wsadata_typename)
434 | local wsadata = ffi.new(dataarrayname)
435 | local retValue = SocketLib.WSAStartup(wVersionRequested, wsadata);
436 | wsadata = wsadata[0]
437 |
438 | return retValue, wsadata
439 | end
440 |
441 | local err, wsadata = WinsockStartup()
442 |
443 |
444 |
445 |
446 | return {
447 | WSAData = wsadata,
448 |
449 | Lib = SocketLib,
450 | FFI = wsock,
451 |
452 | -- Data Structures
453 | IN_ADDR = IN_ADDR,
454 | sockaddr = sockaddr,
455 | sockaddr_in = sockaddr_in,
456 | sockaddr_in6 = sockaddr_in6,
457 | addrinfo = addrinfo,
458 |
459 | -- Library Functions
460 | accept = accept,
461 | bind = bind,
462 | connect = connect,
463 | closesocket = closesocket,
464 | ioctlsocket = ioctlsocket,
465 | listen = listen,
466 | recv = recv,
467 | send = send,
468 | setsockopt = setsockopt,
469 | shutdown = shutdown,
470 | socket = socket,
471 |
472 | WSAIoctl = WSAIoctl,
473 | WSAPoll = WSAPoll,
474 | WSASocket = WSASocket,
475 |
476 | -- Helper functions
477 | GetLocalHostName = GetLocalHostName,
478 | GetSocketErrorString = GetSocketErrorString,
479 | GetExtensionFunction = GetExtensionFunction,
480 | }
481 |
482 |
483 |
484 | --[[
485 | BONE YARD
486 | --]]
487 |
488 | --[[
489 | SOCKADDR_STORAGE = nil
490 | SOCKADDR_STORAGE_mt = {
491 | __tostring = function(self)
492 | if self.ss_family == Family.AF_INET then
493 | return string.format("AF_INET, %s, %d", self:GetAddressString(), self:GetPort())
494 | end
495 |
496 | if self.ss_family == AF_INET6 then
497 | return string.format("AF_INET6, %s, %d", self:GetAddressString(), self:GetPort())
498 | end
499 |
500 | return ""
501 | end,
502 |
503 | __index={
504 | Assign = function(self, rhs)
505 | if rhs.ss_family == Family.AF_INET then
506 | local selfptr = ffi.cast("struct sockaddr_in *", self)
507 | local rhsptr = ffi.cast("struct sockaddr_in *", rhs)
508 | local len = ffi.sizeof("struct sockaddr_in")
509 |
510 | memcpy(selfptr, rhs, len)
511 | return self
512 | elseif rhs.ss_family == Family.AF_INET6 then
513 | local selfptr = ffi.cast("struct sockaddr_in6 *", self)
514 | local rhsptr = ffi.cast("struct sockaddr_in6 *", rhs)
515 | local len = ffi.sizeof("struct sockaddr_in6")
516 |
517 | memcpy(selfptr, rhs, len)
518 | return self
519 | end
520 |
521 | return self
522 | end,
523 |
524 | Family = function(self)
525 | return self.ss_family, families[self.ss_family]
526 | end,
527 |
528 | Size = function(self)
529 | if self.ss_family == Family.AF_INET then
530 | local len = ffi.sizeof("struct sockaddr_in")
531 | return len
532 | elseif self.ss_family == Family.AF_INET6 then
533 | local len = ffi.sizeof("struct sockaddr_in6")
534 | return len
535 | end
536 |
537 | return 0
538 | end,
539 |
540 | Clone = function(self)
541 | local newone = SOCKADDR_STORAGE()
542 | memcpy(newone, self, ffi.sizeof("SOCKADDR_STORAGE"))
543 |
544 | return newone
545 | end,
546 |
547 | Equal = function(self, rhs)
548 | if self.ss_family ~= rhs.ss_family then return false end
549 |
550 | if self.sa_family == Family.AF_INET then
551 | local len = ffi.sizeof("struct sockaddr_in")
552 | return memcmp(self, rhs, len)
553 | else
554 | local len = ffi.sizeof("struct sockaddr_in6")
555 | return memcmp(self, rhs, len)
556 | end
557 |
558 | return false
559 | end,
560 |
561 | GetAddressString = function(self)
562 | if self.ss_family == Family.AF_INET then
563 | local selfptr = ffi.cast("struct sockaddr_in *", self)
564 | return selfptr.sin_addr:GetAsString()
565 | elseif self.ss_family == AF_INET6 then
566 | local selfptr = ffi.cast("struct sockaddr_in6 *", self)
567 | local addroffset = ffi.offsetof("struct sockaddr_in6", "sin6_addr")
568 | local in_addr6ptr = selfptr+addroffset
569 |
570 | local buf = ffi.new("char[?]", (INET6_ADDRSTRLEN+1))
571 | local bufptr = ffi.cast("intptr_t", buf)
572 |
573 | SocketLib.inet_ntop(AF_INET6, in_addr6ptr, bufptr, (INET6_ADDRSTRLEN));
574 | local ipstr = ffi.string(buf)
575 | --print(ipstr)
576 | return ipstr
577 | end
578 |
579 | return nil
580 | end,
581 |
582 | SetAddressFromString = function(self, src)
583 | if self.ss_family == AF_INET then
584 | local selfptr = ffi.cast("struct sockaddr_in *", self)
585 | selfptr.sin_addr:SetFromString(src)
586 |
587 | return self
588 | elseif self.ss_family == AF_INET6 then
589 | local selfptr = ffi.cast("struct sockaddr_in6 *", self)
590 | local addroffset = ffi.offsetof("struct sockaddr_in6", "sin6_addr")
591 | local in_addrptr = selfptr+addroffset
592 |
593 | wsock.inet_pton(AF_INET6, src, in_addrptr);
594 |
595 | return self
596 | end
597 |
598 | return nil
599 | end,
600 |
601 | EqualPort = function(self, rhs)
602 | return self:GetPort() == rhs:GetPort()
603 | end,
604 |
605 | GetPort = function(self)
606 | if self.ss_family == AF_INET then
607 | local selfptr = ffi.cast("struct sockaddr_in *", self)
608 | return wsock.ntohs(selfptr.sin_port)
609 | elseif self.ss_family == AF_INET6 then
610 | local selfptr = ffi.cast("struct sockaddr_in6 *", self)
611 | return wsock.ntohs(selfptr.sin6_port)
612 | end
613 |
614 | return nil
615 | end,
616 |
617 | SetPort = function(self, port)
618 | port = tonumber(port)
619 | if self.ss_family == AF_INET then
620 | local selfptr = ffi.cast("struct sockaddr_in *", self)
621 | selfptr.sin_port = wsock.htons(port);
622 | return self
623 | elseif self.ss_family == AF_INET6 then
624 | local selfptr = ffi.cast("struct sockaddr_in6 *", self)
625 | selfptr.sin6_port = wsock.htons(port);
626 | return self
627 | end
628 |
629 | return nil
630 | end,
631 |
632 |
633 | },
634 | }
635 | SOCKADDR_STORAGE = ffi.metatype("SOCKADDR_STORAGE", SOCKADDR_STORAGE_mt)
636 | --]]
637 |
638 |
639 |
--------------------------------------------------------------------------------
/WindowStation.lua:
--------------------------------------------------------------------------------
1 |
2 | local ffi = require ("ffi");
3 | require ("WTypes");
4 |
5 | ffi.cdef[[
6 | BOOL WINAPI CloseWindowStation(
7 | _In_ HWINSTA hWinSta
8 | );
9 |
10 | HWINSTA WINAPI CreateWindowStation(
11 | _In_opt_ LPCTSTR lpwinsta,
12 | DWORD dwFlags,
13 | _In_ ACCESS_MASK dwDesiredAccess,
14 | _In_opt_ LPSECURITY_ATTRIBUTES lpsa
15 | );
16 |
17 | BOOL WINAPI EnumWindowStations(
18 | _In_ WINSTAENUMPROC lpEnumFunc,
19 | _In_ LPARAM lParam
20 | );
21 |
22 | HWINSTA WINAPI GetProcessWindowStation(void);
23 |
24 | BOOL WINAPI GetUserObjectInformation(
25 | _In_ HANDLE hObj,
26 | _In_ int nIndex,
27 | _Out_opt_ PVOID pvInfo,
28 | _In_ DWORD nLength,
29 | _Out_opt_ LPDWORD lpnLengthNeeded
30 | );
31 |
32 | BOOL WINAPI GetUserObjectSecurity(
33 | _In_ HANDLE hObj,
34 | _In_ PSECURITY_INFORMATION pSIRequested,
35 | _Inout_opt_ PSECURITY_DESCRIPTOR pSD,
36 | _In_ DWORD nLength,
37 | _Out_ LPDWORD lpnLengthNeeded
38 | );
39 |
40 | HWINSTA WINAPI OpenWindowStation(
41 | _In_ LPTSTR lpszWinSta,
42 | _In_ BOOL fInherit,
43 | _In_ ACCESS_MASK dwDesiredAccess
44 | );
45 |
46 | BOOL WINAPI SetProcessWindowStation(
47 | _In_ HWINSTA hWinSta
48 | );
49 |
50 | BOOL WINAPI SetUserObjectInformation(
51 | _In_ HANDLE hObj,
52 | _In_ int nIndex,
53 | _In_ PVOID pvInfo,
54 | _In_ DWORD nLength
55 | );
56 |
57 | BOOL WINAPI SetUserObjectSecurity(
58 | _In_ HANDLE hObj,
59 | _In_ PSECURITY_INFORMATION pSIRequested,
60 | _In_ PSECURITY_DESCRIPTOR pSID
61 | );
62 | ]]
63 |
64 |
65 |
--------------------------------------------------------------------------------
/gdi32_ffi.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | local C = ffi.C
3 | local bit = require "bit"
4 | local lshift = bit.lshift
5 | local rshift = bit.rshift
6 |
7 | local band = bit.band -- &
8 | local bor = bit.bor -- |
9 | local bnot = bit.bnot -- ~
10 |
11 | require "WTypes"
12 |
13 | local gdi32_ffi = {
14 | -- Pixel Types
15 | PFD_TYPE_RGBA = 0,
16 | ColorIndex = 1,
17 |
18 | -- Layer Types
19 | PFD_MAIN_PLANE = 0,
20 | Overlay = 1,
21 | Underlay = (-1),
22 |
23 | --PIXELFORMATDESCRIPTOR flags
24 | PFD_DOUBLEBUFFER = 0x00000001,
25 | Stereo = 0x00000002,
26 | PFD_DRAW_TO_WINDOW = 0x00000004,
27 | DrawToBitmap = 0x00000008,
28 | SupportGDI = 0x00000010,
29 | PFD_SUPPORT_OPENGL = 0x00000020,
30 | GenericFormat = 0x00000040,
31 | NeedPalette = 0x00000080,
32 | NeedSystemPalette = 0x00000100,
33 | SwapExchange = 0x00000200,
34 | SwapCopy = 0x00000400,
35 | SwapLayerBuffers = 0x00000800,
36 | GenericAccelerated = 0x00001000,
37 | SupportDirectDraw = 0x00002000,
38 | Direct3DAccelerated = 0x00004000,
39 | SupportComposition = 0x00008000,
40 |
41 | -- PIXELFORMATDESCRIPTOR flags for use in ChoosePixelFormat only
42 | PFD_DEPTH_DONTCARE = 0x20000000,
43 | PFD_DOUBLEBUFFER_DONTCARE = 0x40000000,
44 | PFD_STEREO_DONTCARE = 0x80000000,
45 |
46 |
47 | SRCCOPY = 0x00CC0020,
48 | SRCPAINT = 0x00EE0086,
49 | SRCERASE = 0x00440328,
50 | BLACKNESS = 0x00000042,
51 | WHITENESS = 0x00FF0062,
52 |
53 | -- Stock Object Index
54 | WHITE_BRUSH = 0,
55 | LTGRAY_BRUSH = 1,
56 | GRAY_BRUSH = 2,
57 | DKGRAY_BRUSH = 3,
58 | BLACK_BRUSH = 4,
59 | NULL_BRUSH = 5,
60 | --HOLLOW_BRUSH = NULL_BRUSH,
61 | WHITE_PEN = 6,
62 | BLACK_PEN = 7,
63 | NULL_PEN = 8,
64 | OEM_FIXED_FONT = 10,
65 | ANSI_FIXED_FONT = 11,
66 | ANSI_VAR_FONT = 12,
67 | SYSTEM_FONT = 13,
68 | DEVICE_DEFAULT_FONT = 14,
69 | DEFAULT_PALETTE = 15,
70 | SYSTEM_FIXED_FONT = 16,
71 | DEFAULT_GUI_FONT = 17,
72 | DC_BRUSH = 18,
73 | DC_PEN = 19,
74 |
75 | }
76 |
77 |
78 |
79 | -- GDI32
80 | ffi.cdef[[
81 |
82 | typedef struct _POINTFLOAT {
83 | FLOAT x;
84 | FLOAT y;
85 | } POINTFLOAT;
86 |
87 | typedef struct _GLYPHMETRICSFLOAT {
88 | FLOAT gmfBlackBoxX;
89 | FLOAT gmfBlackBoxY;
90 | POINTFLOAT gmfptGlyphOrigin;
91 | FLOAT gmfCellIncX;
92 | FLOAT gmfCellIncY;
93 | } GLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT;
94 |
95 | typedef struct tagPIXELFORMATDESCRIPTOR {
96 | WORD nSize;
97 | WORD nVersion;
98 | DWORD dwFlags;
99 | BYTE iPixelType;
100 | BYTE cColorBits;
101 | BYTE cRedBits;
102 | BYTE cRedShift;
103 | BYTE cGreenBits;
104 | BYTE cGreenShift;
105 | BYTE cBlueBits;
106 | BYTE cBlueShift;
107 | BYTE cAlphaBits;
108 | BYTE cAlphaShift;
109 | BYTE cAccumBits;
110 | BYTE cAccumRedBits;
111 | BYTE cAccumGreenBits;
112 | BYTE cAccumBlueBits;
113 | BYTE cAccumAlphaBits;
114 | BYTE cDepthBits;
115 | BYTE cStencilBits;
116 | BYTE cAuxBuffers;
117 | BYTE iLayerType;
118 | BYTE bReserved;
119 | DWORD dwLayerMask;
120 | DWORD dwVisibleMask;
121 | DWORD dwDamageMask;
122 | } PIXELFORMATDESCRIPTOR;
123 |
124 |
125 | typedef struct tagLAYERPLANEDESCRIPTOR {
126 | WORD nSize;
127 | WORD nVersion;
128 | DWORD dwFlags;
129 | BYTE iPixelType;
130 | BYTE cColorBits;
131 | BYTE cRedBits;
132 | BYTE cRedShift;
133 | BYTE cGreenBits;
134 | BYTE cGreenShift;
135 | BYTE cBlueBits;
136 | BYTE cBlueShift;
137 | BYTE cAlphaBits;
138 | BYTE cAlphaShift;
139 | BYTE cAccumBits;
140 | BYTE cAccumRedBits;
141 | BYTE cAccumGreenBits;
142 | BYTE cAccumBlueBits;
143 | BYTE cAccumAlphaBits;
144 | BYTE cDepthBits;
145 | BYTE cStencilBits;
146 | BYTE cAuxBuffers;
147 | BYTE iLayerPlane;
148 | BYTE bReserved;
149 | COLORREF crTransparent;
150 | } LAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR;
151 |
152 | ]]
153 |
154 |
155 | --[[
156 | Old Style OpenGL Support
157 | --]]
158 |
159 | ffi.cdef[[
160 |
161 | // For OpenGL
162 | typedef int (* PFNCHOOSEPIXELFORMAT)(HDC hdc, const PIXELFORMATDESCRIPTOR * ppfd);
163 | typedef int (* PFNDESCRIBEPIXELFORMAT)(HDC hdc, int iPixelFormat, unsigned int nBytes, PIXELFORMATDESCRIPTOR * ppfd);
164 | typedef BOOL (* PFNSETPIXELFORMAT)(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR * ppfd);
165 | typedef int (* PFNSWAPBUFFERS)(HDC hdc);
166 |
167 |
168 | int ChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR * ppfd);
169 | int DescribePixelFormat(HDC hdc, int iPixelFormat, unsigned int nBytes, PIXELFORMATDESCRIPTOR * ppfd);
170 | BOOL SetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR * ppfd);
171 | int SwapBuffers(HDC hdc);
172 | ]]
173 |
174 | ffi.cdef[[
175 | HDC CreateDCA(LPCSTR lpszDriver,LPCSTR lpszDevice,LPCSTR lpszOutput,const void * lpInitData);
176 | HDC CreateCompatibleDC(HDC hdc);
177 | HDC GetDC(HWND hWnd);
178 |
179 | int SaveDC(void *hdc);
180 | bool RestoreDC(void *hdc, int nSavedDC);
181 |
182 | COLORREF SetDCPenColor(HDC hdc, COLORREF crColor);
183 | COLORREF SetDCBrushColor(HDC hdc, COLORREF crColor);
184 |
185 | HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj);
186 | int GetObjectA(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
187 | HGDIOBJ GetStockObject(int fnObject);
188 |
189 | bool GdiFlush();
190 |
191 | // Drawing
192 | uint32_t SetPixel(HDC hdc, int x, int y, uint32_t color);
193 | BOOL SetPixelV(HDC hdc, int X, int Y, uint32_t crColor);
194 |
195 | int MoveToEx(HDC hdc, int X, int Y, void *lpPoint);
196 |
197 | int LineTo(HDC hdc, int nXEnd, int nYEnd);
198 |
199 | bool Rectangle(HDC hdc, int left, int top, int right, int bottom);
200 |
201 | bool RoundRect(HDC hdc, int left, int top, int right, int bottom,
202 | int width, int height);
203 |
204 |
205 | BOOL Ellipse(HDC hdc,
206 | int nLeftRect,
207 | int nTopRect,
208 | int nRightRect,
209 | int nBottomRect);
210 |
211 |
212 |
213 | int GetDIBits(HDC hdc,
214 | HBITMAP hbmp,
215 | UINT uStartScan,
216 | UINT cScanLines,
217 | LPVOID lpvBits,
218 | PBITMAPINFO lpbi,
219 | UINT uUsage);
220 |
221 | BOOL BitBlt( HDC hdcDest,
222 | int nXDest,
223 | int nYDest,
224 | int nWidth,
225 | int nHeight,
226 | HDC hdcSrc,
227 | int nXSrc,
228 | int nYSrc,
229 | DWORD dwRop);
230 |
231 | int StretchDIBits(HDC hdc,
232 | int XDest,
233 | int YDest,
234 | int nDestWidth,
235 | int nDestHeight,
236 | int XSrc,
237 | int YSrc,
238 | int nSrcWidth,
239 | int nSrcHeight,
240 | const void *lpBits,
241 | const BITMAPINFO *lpBitsInfo,
242 | UINT iUsage,
243 | DWORD dwRop);
244 |
245 | // Text
246 | BOOL TextOutA(HDC hdc, int nXStart, int nYStart, LPCSTR lpString, int cbString);
247 |
248 | HBITMAP CreateCompatibleBitmap(HDC hdc,
249 | int nWidth,
250 | int nHeight);
251 |
252 | HBITMAP CreateDIBSection(HDC hdc,
253 | const BITMAPINFO *pbmi,
254 | UINT iUsage,
255 | void **ppvBits,
256 | HANDLE hSection,
257 | DWORD dwOffset);
258 | ]]
259 |
260 |
261 |
262 | return gdi32_ffi
263 |
--------------------------------------------------------------------------------
/kernel32_ffi.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | local C = ffi.C
3 |
4 | require "WinBase"
5 | local kernel32 = ffi.load("kernel32");
6 |
7 | local kernel32_ffi = {
8 | PROCESS_HEAP_REGION =0x0001;
9 | PROCESS_HEAP_UNCOMMITTED_RANGE =0x0002;
10 | PROCESS_HEAP_ENTRY_BUSY =0x0004;
11 | PROCESS_HEAP_ENTRY_MOVEABLE =0x0010;
12 | PROCESS_HEAP_ENTRY_DDESHARE =0x0020;
13 |
14 | HEAP_NO_SERIALIZE = 0x00000001;
15 | HEAP_GENERATE_EXCEPTIONS = 0x00000004;
16 | HEAP_ZERO_MEMORY = 0x00000008;
17 | HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
18 | HEAP_CREATE_ENABLE_EXECUTE = 0x00040000;
19 | }
20 |
21 | --[[
22 | BOOL HeapSetInformation (HANDLE HeapHandle,
23 | HEAP_INFORMATION_CLASS HeapInformationClass,
24 | PVOID HeapInformation,
25 | SIZE_T HeapInformationLength);
26 |
27 | BOOL HeapQueryInformation (HANDLE HeapHandle,
28 | HEAP_INFORMATION_CLASS HeapInformationClass,
29 | __out_bcount_part_opt(HeapInformationLength, *ReturnLength) PVOID HeapInformation,
30 | SIZE_T HeapInformationLength,
31 | __out_opt PSIZE_T ReturnLength
32 | );
33 | --]]
34 |
35 | ffi.cdef[[
36 | typedef struct _OVERLAPPED {
37 | ULONG_PTR Internal;
38 | ULONG_PTR InternalHigh;
39 | union {
40 | struct {
41 | DWORD Offset;
42 | DWORD OffsetHigh;
43 | };
44 |
45 | PVOID Pointer;
46 | };
47 |
48 | HANDLE hEvent;
49 | } OVERLAPPED, *LPOVERLAPPED;
50 |
51 | // Taken from WinNT.h
52 | typedef struct _RTL_SRWLOCK
53 | {
54 | PVOID Ptr;
55 | } RTL_SRWLOCK, *PRTL_SRWLOCK;
56 |
57 | // Taken from WinBase.h
58 | typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
59 | ]]
60 |
61 | ffi.cdef[[
62 |
63 |
64 | typedef struct _PROCESS_HEAP_ENTRY {
65 | PVOID lpData;
66 | DWORD cbData;
67 | BYTE cbOverhead;
68 | BYTE iRegionIndex;
69 | WORD wFlags;
70 | union {
71 | struct {
72 | HANDLE hMem;
73 | DWORD dwReserved[ 3 ];
74 | } Block;
75 | struct {
76 | DWORD dwCommittedSize;
77 | DWORD dwUnCommittedSize;
78 | LPVOID lpFirstBlock;
79 | LPVOID lpLastBlock;
80 | } Region;
81 | } DUMMYUNIONNAME;
82 | } PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY, *PPROCESS_HEAP_ENTRY;
83 |
84 |
85 | HANDLE HeapCreate(DWORD flOptions,
86 | SIZE_T dwInitialSize,
87 | SIZE_T dwMaximumSize);
88 |
89 |
90 | BOOL HeapDestroy(HANDLE hHeap);
91 |
92 |
93 | LPVOID HeapAlloc(
94 | HANDLE hHeap,
95 | DWORD dwFlags,
96 | SIZE_T dwBytes);
97 |
98 |
99 | LPVOID HeapReAlloc(HANDLE hHeap,
100 | DWORD dwFlags,
101 | LPVOID lpMem,
102 | SIZE_T dwBytes);
103 |
104 | BOOL HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
105 |
106 | SIZE_T HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
107 |
108 | BOOL HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
109 |
110 | SIZE_T HeapCompact(HANDLE hHeap, DWORD dwFlags);
111 |
112 | HANDLE GetProcessHeap( void );
113 |
114 | DWORD GetProcessHeaps(DWORD NumberOfHeaps, PHANDLE ProcessHeaps);
115 |
116 | BOOL HeapLock(HANDLE hHeap);
117 |
118 | BOOL HeapUnlock(HANDLE hHeap);
119 |
120 | BOOL HeapWalk(HANDLE hHeap, PROCESS_HEAP_ENTRY * lpEntry);
121 |
122 | ]]
123 |
124 |
125 | -- File System Calls
126 | --
127 | ffi.cdef[[
128 | DWORD GetCurrentDirectoryA(DWORD nBufferLength, LPTSTR lpBuffer);
129 |
130 | HANDLE CreateFileA(LPCTSTR lpFileName,
131 | DWORD dwDesiredAccess,
132 | DWORD dwShareMode,
133 | LPSECURITY_ATTRIBUTES lpSecurityAttributes,
134 | DWORD dwCreationDisposition,
135 | DWORD dwFlagsAndAttributes,
136 | HANDLE hTemplateFile
137 | );
138 |
139 | BOOL GetFileInformationByHandle(HANDLE hFile,
140 | PBY_HANDLE_FILE_INFORMATION lpFileInformation);
141 |
142 | BOOL GetFileTime(HANDLE hFile,
143 | LPFILETIME lpCreationTime,
144 | LPFILETIME lpLastAccessTime,
145 | LPFILETIME lpLastWriteTime);
146 |
147 | BOOL FileTimeToSystemTime(const FILETIME* lpFileTime, LPSYSTEMTIME lpSystemTime);
148 |
149 | BOOL DeleteFileW(LPCTSTR lpFileName);
150 |
151 | BOOL MoveFileW(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName);
152 |
153 | /*
154 | HFILE WINAPI OpenFile(LPCSTR lpFileName,
155 | LPOFSTRUCT lpReOpenBuff,
156 | UINT uStyle);
157 | */
158 | ]]
159 |
160 | ffi.cdef[[
161 | typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID lpParameter);
162 | ]]
163 |
164 |
165 |
166 | ffi.cdef[[
167 |
168 | DWORD GetLastError();
169 |
170 | HMODULE GetModuleHandleA(LPCSTR lpModuleName);
171 |
172 | BOOL CloseHandle(HANDLE hObject);
173 |
174 | HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,
175 | BOOL bManualReset, BOOL bInitialState, LPCSTR lpName);
176 |
177 |
178 | HANDLE CreateIoCompletionPort(HANDLE FileHandle,
179 | HANDLE ExistingCompletionPort,
180 | ULONG_PTR CompletionKey,
181 | DWORD NumberOfConcurrentThreads);
182 |
183 | BOOL GetQueuedCompletionStatus(
184 | HANDLE CompletionPort,
185 | LPDWORD lpNumberOfBytesTransferred,
186 | PULONG_PTR lpCompletionKey,
187 | LPOVERLAPPED *lpOverlapped,
188 | DWORD dwMilliseconds
189 | );
190 |
191 | BOOL PostQueuedCompletionStatus(
192 | HANDLE CompletionPort,
193 | DWORD dwNumberOfBytesTransferred,
194 | ULONG_PTR dwCompletionKey,
195 | LPOVERLAPPED lpOverlapped
196 | );
197 |
198 |
199 | HANDLE CreateThread(
200 | LPSECURITY_ATTRIBUTES lpThreadAttributes,
201 | size_t dwStackSize,
202 | LPTHREAD_START_ROUTINE lpStartAddress,
203 | LPVOID lpParameter,
204 | DWORD dwCreationFlags,
205 | LPDWORD lpThreadId);
206 |
207 |
208 | DWORD GetCurrentThreadId(void);
209 | DWORD ResumeThread(HANDLE hThread);
210 | BOOL SwitchToThread(void);
211 | DWORD SuspendThread(HANDLE hThread);
212 |
213 |
214 | void * GetProcAddress(HMODULE hModule, LPCSTR lpProcName);
215 |
216 | BOOL QueryPerformanceFrequency(int64_t *lpFrequency);
217 | BOOL QueryPerformanceCounter(int64_t *lpPerformanceCount);
218 |
219 | // DWORD QueueUserAPC(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR dwData);
220 |
221 | void Sleep(DWORD dwMilliseconds);
222 |
223 | DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable);
224 | ]]
225 |
226 |
227 |
228 |
229 | --[[
230 | WinNls.h
231 |
232 | Defined in Kernel32
233 | --]]
234 |
235 | CP_ACP = 0 -- default to ANSI code page
236 | CP_OEMCP = 1 -- default to OEM code page
237 | CP_MACCP = 2 -- default to MAC code page
238 | CP_THREAD_ACP = 3 -- current thread's ANSI code page
239 | CP_SYMBOL = 42 -- SYMBOL translations
240 |
241 | ffi.cdef[[
242 | int MultiByteToWideChar(UINT CodePage,
243 | DWORD dwFlags,
244 | LPCSTR lpMultiByteStr, int cbMultiByte,
245 | LPWSTR lpWideCharStr, int cchWideChar);
246 |
247 |
248 | int WideCharToMultiByte(UINT CodePage,
249 | DWORD dwFlags,
250 | LPCWSTR lpWideCharStr, int cchWideChar,
251 | LPSTR lpMultiByteStr, int cbMultiByte,
252 | LPCSTR lpDefaultChar,
253 | LPBOOL lpUsedDefaultChar);
254 | ]]
255 |
256 |
257 | return kernel32_ffi
258 |
259 |
--------------------------------------------------------------------------------
/ncrypt.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | require "WTypes"
3 |
4 | local k32 = require "Kernel32"
5 |
6 | local L = k32.AnsiToUnicode16
7 |
8 | ffi.cdef[[
9 | typedef LONG SECURITY_STATUS;
10 | ]]
11 |
12 | local BCrypt = require "bcrypt"
13 |
14 | local NCrypt = {
15 | MS_KEY_STORAGE_PROVIDER = L"Microsoft Software Key Storage Provider";
16 | MS_SMART_CARD_KEY_STORAGE_PROVIDER = L"Microsoft Smart Card Key Storage Provider";
17 |
18 | --
19 | -- Common algorithm identifiers.
20 | --
21 |
22 | NCRYPT_RSA_ALGORITHM = BCrypt.BCRYPT_RSA_ALGORITHM;
23 | NCRYPT_RSA_SIGN_ALGORITHM = BCrypt.BCRYPT_RSA_SIGN_ALGORITHM;
24 | NCRYPT_DH_ALGORITHM = BCrypt.BCRYPT_DH_ALGORITHM;
25 | NCRYPT_DSA_ALGORITHM = BCrypt.BCRYPT_DSA_ALGORITHM;
26 | NCRYPT_MD2_ALGORITHM = BCrypt.BCRYPT_MD2_ALGORITHM;
27 | NCRYPT_MD4_ALGORITHM = BCrypt.BCRYPT_MD4_ALGORITHM;
28 | NCRYPT_MD5_ALGORITHM = BCrypt.BCRYPT_MD5_ALGORITHM;
29 | NCRYPT_SHA1_ALGORITHM = BCrypt.BCRYPT_SHA1_ALGORITHM;
30 | NCRYPT_SHA256_ALGORITHM = BCrypt.BCRYPT_SHA256_ALGORITHM;
31 | NCRYPT_SHA384_ALGORITHM = BCrypt.BCRYPT_SHA384_ALGORITHM;
32 | NCRYPT_SHA512_ALGORITHM = BCrypt.BCRYPT_SHA512_ALGORITHM;
33 | NCRYPT_ECDSA_P256_ALGORITHM = BCrypt.BCRYPT_ECDSA_P256_ALGORITHM;
34 | NCRYPT_ECDSA_P384_ALGORITHM = BCrypt.BCRYPT_ECDSA_P384_ALGORITHM;
35 | NCRYPT_ECDSA_P521_ALGORITHM = BCrypt.BCRYPT_ECDSA_P521_ALGORITHM;
36 | NCRYPT_ECDH_P256_ALGORITHM = BCrypt.BCRYPT_ECDH_P256_ALGORITHM;
37 | NCRYPT_ECDH_P384_ALGORITHM = BCrypt.BCRYPT_ECDH_P384_ALGORITHM;
38 | NCRYPT_ECDH_P521_ALGORITHM = BCrypt.BCRYPT_ECDH_P521_ALGORITHM;
39 |
40 | NCRYPT_KEY_STORAGE_ALGORITHM = L"KEY_STORAGE";
41 |
42 |
43 | --
44 | -- Interfaces
45 | --
46 |
47 | NCRYPT_HASH_INTERFACE = BCrypt.BCRYPT_HASH_INTERFACE;
48 | NCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE = BCrypt.BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE;
49 |
50 | NCRYPT_SECRET_AGREEMENT_INTERFACE = BCrypt.BCRYPT_SECRET_AGREEMENT_INTERFACE;
51 |
52 | NCRYPT_SIGNATURE_INTERFACE = BCrypt.BCRYPT_SIGNATURE_INTERFACE;
53 |
54 | NCRYPT_KEY_STORAGE_INTERFACE = 0x00010001;
55 | NCRYPT_SCHANNEL_INTERFACE = 0x00010002;
56 | NCRYPT_SCHANNEL_SIGNATURE_INTERFACE = 0x00010003;
57 |
58 | --
59 | -- algorithm groups.
60 | --
61 |
62 | --NCRYPT_RSA_ALGORITHM_GROUP = NCRYPT_RSA_ALGORITHM;
63 | --NCRYPT_DH_ALGORITHM_GROUP = NCRYPT_DH_ALGORITHM;
64 | --NCRYPT_DSA_ALGORITHM_GROUP = NCRYPT_DSA_ALGORITHM;
65 | NCRYPT_ECDSA_ALGORITHM_GROUP = L"ECDSA";
66 | NCRYPT_ECDH_ALGORITHM_GROUP = L"ECDH";
67 |
68 |
69 | -- NCrypt generic memory descriptors
70 |
71 |
72 | NCRYPTBUFFER_VERSION = 0;
73 |
74 | NCRYPTBUFFER_EMPTY = 0;
75 | NCRYPTBUFFER_DATA = 1;
76 | NCRYPTBUFFER_SSL_CLIENT_RANDOM = 20;
77 | NCRYPTBUFFER_SSL_SERVER_RANDOM = 21;
78 | NCRYPTBUFFER_SSL_HIGHEST_VERSION = 22;
79 | NCRYPTBUFFER_SSL_CLEAR_KEY = 23;
80 | NCRYPTBUFFER_SSL_KEY_ARG_DATA = 24;
81 |
82 | NCRYPTBUFFER_PKCS_OID = 40;
83 | NCRYPTBUFFER_PKCS_ALG_OID = 41;
84 | NCRYPTBUFFER_PKCS_ALG_PARAM = 42;
85 | NCRYPTBUFFER_PKCS_ALG_ID = 43;
86 | NCRYPTBUFFER_PKCS_ATTRS = 44;
87 | NCRYPTBUFFER_PKCS_KEY_NAME = 45;
88 | NCRYPTBUFFER_PKCS_SECRET = 46;
89 |
90 | NCRYPTBUFFER_CERT_BLOB = 47;
91 |
92 | --
93 | -- NCrypt API Flags
94 | --
95 |
96 | NCRYPT_NO_PADDING_FLAG = BCrypt.BCRYPT_PAD_NONE;
97 | NCRYPT_PAD_PKCS1_FLAG = BCrypt.BCRYPT_PAD_PKCS1; -- NCryptEncrypt/Decrypt NCryptSignHash/VerifySignature
98 | NCRYPT_PAD_OAEP_FLAG = BCrypt.BCRYPT_PAD_OAEP; -- BCryptEncrypt/Decrypt
99 | NCRYPT_PAD_PSS_FLAG = BCrypt.BCRYPT_PAD_PSS; -- BCryptSignHash/VerifySignature
100 | NCRYPT_NO_KEY_VALIDATION = BCrypt.BCRYPT_NO_KEY_VALIDATION;
101 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020; -- same as CAPI CRYPT_MACHINE_KEYSET
102 | NCRYPT_SILENT_FLAG = 0x00000040; -- same as CAPI CRYPT_SILENT
103 | NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080;
104 | NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG = 0x00000200;
105 | NCRYPT_DO_NOT_FINALIZE_FLAG = 0x00000400;
106 | NCRYPT_PERSIST_ONLY_FLAG = 0x40000000;
107 | NCRYPT_PERSIST_FLAG = 0x80000000;
108 | NCRYPT_REGISTER_NOTIFY_FLAG = 0x00000001;
109 | NCRYPT_UNREGISTER_NOTIFY_FLAG = 0x00000002;
110 |
111 | -- AlgOperations flags for use with NCryptEnumAlgorithms()
112 | NCRYPT_CIPHER_OPERATION = BCrypt.BCRYPT_CIPHER_OPERATION;
113 | NCRYPT_HASH_OPERATION = BCrypt.BCRYPT_HASH_OPERATION;
114 | NCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION = BCrypt.BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION;
115 | NCRYPT_SECRET_AGREEMENT_OPERATION = BCrypt.BCRYPT_SECRET_AGREEMENT_OPERATION;
116 | NCRYPT_SIGNATURE_OPERATION = BCrypt.BCRYPT_SIGNATURE_OPERATION;
117 | NCRYPT_RNG_OPERATION = BCrypt.BCRYPT_RNG_OPERATION;
118 |
119 | -- NCryptEnumKeys flags
120 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020;
121 |
122 | -- NCryptOpenKey flags
123 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020;
124 | NCRYPT_SILENT_FLAG = 0x00000040;
125 |
126 | -- NCryptCreatePersistedKey flags
127 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020;
128 | NCRYPT_OVERWRITE_KEY_FLAG = 0x00000080;
129 |
130 | -- Standard property names.
131 | NCRYPT_NAME_PROPERTY = L"Name";
132 | NCRYPT_UNIQUE_NAME_PROPERTY = L"Unique Name";
133 | NCRYPT_ALGORITHM_PROPERTY = L"Algorithm Name";
134 | NCRYPT_LENGTH_PROPERTY = L"Length";
135 | NCRYPT_LENGTHS_PROPERTY = L"Lengths";
136 | NCRYPT_BLOCK_LENGTH_PROPERTY = L"Block Length";
137 | NCRYPT_UI_POLICY_PROPERTY = L"UI Policy";
138 | NCRYPT_EXPORT_POLICY_PROPERTY = L"Export Policy";
139 | NCRYPT_WINDOW_HANDLE_PROPERTY = L"HWND Handle";
140 | NCRYPT_USE_CONTEXT_PROPERTY = L"Use Context";
141 | NCRYPT_IMPL_TYPE_PROPERTY = L"Impl Type";
142 | NCRYPT_KEY_USAGE_PROPERTY = L"Key Usage";
143 | NCRYPT_KEY_TYPE_PROPERTY = L"Key Type";
144 | NCRYPT_VERSION_PROPERTY = L"Version";
145 | NCRYPT_SECURITY_DESCR_SUPPORT_PROPERTY = L"Security Descr Support";
146 | NCRYPT_SECURITY_DESCR_PROPERTY = L"Security Descr";
147 | NCRYPT_USE_COUNT_ENABLED_PROPERTY = L"Enabled Use Count";
148 | NCRYPT_USE_COUNT_PROPERTY = L"Use Count";
149 | NCRYPT_LAST_MODIFIED_PROPERTY = L"Modified";
150 | NCRYPT_MAX_NAME_LENGTH_PROPERTY = L"Max Name Length";
151 | NCRYPT_ALGORITHM_GROUP_PROPERTY = L"Algorithm Group";
152 | NCRYPT_DH_PARAMETERS_PROPERTY = BCrypt.BCRYPT_DH_PARAMETERS;
153 | NCRYPT_PROVIDER_HANDLE_PROPERTY = L"Provider Handle";
154 | NCRYPT_PIN_PROPERTY = L"SmartCardPin";
155 | NCRYPT_READER_PROPERTY = L"SmartCardReader";
156 | NCRYPT_SMARTCARD_GUID_PROPERTY = L"SmartCardGuid";
157 | NCRYPT_CERTIFICATE_PROPERTY = L"SmartCardKeyCertificate";
158 | NCRYPT_PIN_PROMPT_PROPERTY = L"SmartCardPinPrompt";
159 | NCRYPT_USER_CERTSTORE_PROPERTY = L"SmartCardUserCertStore";
160 | NCRYPT_ROOT_CERTSTORE_PROPERTY = L"SmartcardRootCertStore";
161 | NCRYPT_SECURE_PIN_PROPERTY = L"SmartCardSecurePin";
162 | NCRYPT_ASSOCIATED_ECDH_KEY = L"SmartCardAssociatedECDHKey";
163 | NCRYPT_SCARD_PIN_ID = L"SmartCardPinId";
164 | NCRYPT_SCARD_PIN_INFO = L"SmartCardPinInfo";
165 |
166 | -- Maximum length of property name (in characters)
167 | NCRYPT_MAX_PROPERTY_NAME = 64;
168 |
169 | -- Maximum length of property data (in bytes)
170 | NCRYPT_MAX_PROPERTY_DATA = 0x100000;
171 |
172 | -- NCRYPT_EXPORT_POLICY_PROPERTY property flags.
173 | NCRYPT_ALLOW_EXPORT_FLAG = 0x00000001;
174 | NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG = 0x00000002;
175 | NCRYPT_ALLOW_ARCHIVING_FLAG = 0x00000004;
176 | NCRYPT_ALLOW_PLAINTEXT_ARCHIVING_FLAG = 0x00000008;
177 |
178 | -- NCRYPT_IMPL_TYPE_PROPERTY property flags.
179 | NCRYPT_IMPL_HARDWARE_FLAG = 0x00000001;
180 | NCRYPT_IMPL_SOFTWARE_FLAG = 0x00000002;
181 | NCRYPT_IMPL_REMOVABLE_FLAG = 0x00000008;
182 | NCRYPT_IMPL_HARDWARE_RNG_FLAG = 0x00000010;
183 |
184 | -- NCRYPT_KEY_USAGE_PROPERTY property flags.
185 | NCRYPT_ALLOW_DECRYPT_FLAG = 0x00000001;
186 | NCRYPT_ALLOW_SIGNING_FLAG = 0x00000002;
187 | NCRYPT_ALLOW_KEY_AGREEMENT_FLAG = 0x00000004;
188 | NCRYPT_ALLOW_ALL_USAGES = 0x00ffffff;
189 |
190 | -- NCRYPT_UI_POLICY_PROPERTY property flags and structure
191 | NCRYPT_UI_PROTECT_KEY_FLAG = 0x00000001;
192 | NCRYPT_UI_FORCE_HIGH_PROTECTION_FLAG = 0x00000002;
193 |
194 |
195 | -- NCryptGetProperty flags
196 | NCRYPT_PERSIST_ONLY_FLAG = 0x40000000;
197 |
198 | -- NCryptSetProperty flags
199 | NCRYPT_PERSIST_FLAG = 0x80000000;
200 | NCRYPT_PERSIST_ONLY_FLAG = 0x40000000;
201 |
202 | NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG = 0x00000200;
203 |
204 | NCRYPT_PKCS7_ENVELOPE_BLOB = L"PKCS7_ENVELOPE";
205 | NCRYPT_PKCS8_PRIVATE_KEY_BLOB = L"PKCS8_PRIVATEKEY";
206 | NCRYPT_OPAQUETRANSPORT_BLOB = L"OpaqueTransport";
207 |
208 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020;
209 | NCRYPT_DO_NOT_FINALIZE_FLAG = 0x00000400;
210 | NCRYPT_EXPORT_LEGACY_FLAG = 0x00000800;
211 |
212 | -- NCryptNotifyChangeKey flags
213 | NCRYPT_REGISTER_NOTIFY_FLAG = 0x00000001;
214 | NCRYPT_UNREGISTER_NOTIFY_FLAG = 0x00000002;
215 | NCRYPT_MACHINE_KEY_FLAG = 0x00000020;
216 |
217 | -- NCRYPT_KEY_STORAGE_INTERFACE_VERSION = BCrypt.BCRYPT_MAKE_INTERFACE_VERSION(1,0);
218 |
219 | }
220 |
221 |
222 | ffi.cdef[[
223 | // NCRYPT shares the same BCRYPT definitions
224 | typedef BCryptBuffer NCryptBuffer;
225 | typedef BCryptBuffer* PNCryptBuffer;
226 | typedef BCryptBufferDesc NCryptBufferDesc;
227 | typedef BCryptBufferDesc* PNCryptBufferDesc;
228 | ]]
229 |
230 |
231 | ffi.cdef[[
232 | typedef HANDLE HCRYPTPROV;
233 | typedef HANDLE HCRYPTKEY;
234 |
235 | typedef ULONG_PTR NCRYPT_HANDLE;
236 | typedef ULONG_PTR NCRYPT_PROV_HANDLE;
237 | typedef ULONG_PTR NCRYPT_KEY_HANDLE;
238 | typedef ULONG_PTR NCRYPT_HASH_HANDLE;
239 | typedef ULONG_PTR NCRYPT_SECRET_HANDLE;
240 | ]]
241 |
242 | ffi.cdef[[
243 | // USE EXTREME CAUTION: editing comments that contain "certenrolls_*" tokens
244 | // could break building CertEnroll idl files:
245 | // certenrolls_begin -- NCryptAlgorithmName
246 | typedef struct _NCryptAlgorithmName
247 | {
248 | LPWSTR pszName;
249 | DWORD dwClass; // the CNG interface that supports this algorithm
250 | DWORD dwAlgOperations; // the types of operations supported by this algorithm
251 | DWORD dwFlags;
252 | } NCryptAlgorithmName, *PNCryptAlgorithmName;
253 | // certenrolls_end
254 | ]]
255 |
256 | ffi.cdef[[
257 | typedef struct NCryptKeyName
258 | {
259 | LPWSTR pszName;
260 | LPWSTR pszAlgid;
261 | DWORD dwLegacyKeySpec;
262 | DWORD dwFlags;
263 | } NCryptKeyName, *PNCryptKeyName;
264 | ]]
265 |
266 |
267 | ffi.cdef[[
268 | typedef struct NCryptProviderName
269 | {
270 | LPWSTR pszName;
271 | LPWSTR pszComment;
272 | } NCryptProviderName, *PNCryptProviderName;
273 | ]]
274 |
275 | ffi.cdef[[
276 | typedef struct __NCRYPT_UI_POLICY_BLOB
277 | {
278 | DWORD dwVersion;
279 | DWORD dwFlags;
280 | DWORD cbCreationTitle;
281 | DWORD cbFriendlyName;
282 | DWORD cbDescription;
283 | // creation title string
284 | // friendly name string
285 | // description string
286 | } NCRYPT_UI_POLICY_BLOB;
287 |
288 | typedef struct __NCRYPT_UI_POLICY
289 | {
290 | DWORD dwVersion;
291 | DWORD dwFlags;
292 | LPCWSTR pszCreationTitle;
293 | LPCWSTR pszFriendlyName;
294 | LPCWSTR pszDescription;
295 | } NCRYPT_UI_POLICY;
296 |
297 |
298 | // NCRYPT_LENGTHS_PROPERTY property structure.
299 | typedef struct __NCRYPT_SUPPORTED_LENGTHS
300 | {
301 | DWORD dwMinLength;
302 | DWORD dwMaxLength;
303 | DWORD dwIncrement;
304 | DWORD dwDefaultLength;
305 | } NCRYPT_SUPPORTED_LENGTHS;
306 | ]]
307 |
308 | ffi.cdef[[
309 | //
310 | // Functions used to manage persisted keys.
311 | //
312 |
313 | SECURITY_STATUS
314 | NCryptOpenStorageProvider(
315 | NCRYPT_PROV_HANDLE *phProvider,
316 | LPCWSTR pszProviderName,
317 | DWORD dwFlags);
318 | ]]
319 |
320 | ffi.cdef[[
321 |
322 | SECURITY_STATUS
323 |
324 | NCryptEnumAlgorithms(
325 | NCRYPT_PROV_HANDLE hProvider,
326 | DWORD dwAlgOperations,
327 | DWORD * pdwAlgCount,
328 | NCryptAlgorithmName **ppAlgList,
329 | DWORD dwFlags);
330 |
331 | SECURITY_STATUS
332 | NCryptIsAlgSupported(
333 | NCRYPT_PROV_HANDLE hProvider,
334 | LPCWSTR pszAlgId,
335 | DWORD dwFlags);
336 | ]]
337 |
338 |
339 | ffi.cdef[[
340 |
341 | SECURITY_STATUS
342 | NCryptEnumKeys(
343 | NCRYPT_PROV_HANDLE hProvider,
344 | LPCWSTR pszScope,
345 | NCryptKeyName **ppKeyName,
346 | PVOID * ppEnumState,
347 | DWORD dwFlags);
348 | ]]
349 |
350 |
351 | ffi.cdef[[
352 |
353 | SECURITY_STATUS
354 | NCryptEnumStorageProviders(DWORD * pdwProviderCount,
355 | NCryptProviderName **ppProviderList,
356 | DWORD dwFlags);
357 | ]]
358 |
359 |
360 | ffi.cdef[[
361 | SECURITY_STATUS NCryptFreeBuffer(PVOID pvInput);
362 | ]]
363 |
364 | ffi.cdef[[
365 |
366 | SECURITY_STATUS
367 | NCryptOpenKey(
368 | NCRYPT_PROV_HANDLE hProvider,
369 | NCRYPT_KEY_HANDLE *phKey,
370 | LPCWSTR pszKeyName,
371 | DWORD dwLegacyKeySpec,
372 | DWORD dwFlags);
373 | ]]
374 |
375 | ffi.cdef[[
376 |
377 | SECURITY_STATUS
378 | NCryptCreatePersistedKey(
379 | NCRYPT_PROV_HANDLE hProvider,
380 | NCRYPT_KEY_HANDLE *phKey,
381 | LPCWSTR pszAlgId,
382 | LPCWSTR pszKeyName,
383 | DWORD dwLegacyKeySpec,
384 | DWORD dwFlags);
385 | ]]
386 |
387 | ffi.cdef[[
388 |
389 | SECURITY_STATUS
390 | NCryptGetProperty(
391 | NCRYPT_HANDLE hObject,
392 | LPCWSTR pszProperty,
393 | PBYTE pbOutput,
394 | DWORD cbOutput,
395 | DWORD * pcbResult,
396 | DWORD dwFlags);
397 | ]]
398 |
399 | ffi.cdef[[
400 |
401 | SECURITY_STATUS
402 | NCryptSetProperty(
403 | NCRYPT_HANDLE hObject,
404 | LPCWSTR pszProperty,
405 | PBYTE pbInput,
406 | DWORD cbInput,
407 | DWORD dwFlags);
408 | ]]
409 |
410 | ffi.cdef[[
411 |
412 | SECURITY_STATUS NCryptFinalizeKey(NCRYPT_KEY_HANDLE hKey, DWORD dwFlags);
413 | ]]
414 |
415 | ffi.cdef[[
416 |
417 | SECURITY_STATUS
418 | NCryptEncrypt(
419 | NCRYPT_KEY_HANDLE hKey,
420 | PBYTE pbInput,
421 | DWORD cbInput,
422 | void *pPaddingInfo,
423 | PBYTE pbOutput,
424 | DWORD cbOutput,
425 | DWORD * pcbResult,
426 | DWORD dwFlags);
427 |
428 |
429 | SECURITY_STATUS
430 | NCryptDecrypt(
431 | NCRYPT_KEY_HANDLE hKey,
432 | PBYTE pbInput,
433 | DWORD cbInput,
434 | void *pPaddingInfo,
435 | PBYTE pbOutput,
436 | DWORD cbOutput,
437 | DWORD * pcbResult,
438 | DWORD dwFlags);
439 | ]]
440 |
441 | ffi.cdef[[
442 |
443 | SECURITY_STATUS
444 | NCryptImportKey(
445 | NCRYPT_PROV_HANDLE hProvider,
446 | NCRYPT_KEY_HANDLE hImportKey,
447 | LPCWSTR pszBlobType,
448 | NCryptBufferDesc *pParameterList,
449 | NCRYPT_KEY_HANDLE *phKey,
450 | PBYTE pbData,
451 | DWORD cbData,
452 | DWORD dwFlags);
453 |
454 |
455 |
456 |
457 | SECURITY_STATUS
458 | NCryptExportKey(
459 | NCRYPT_KEY_HANDLE hKey,
460 | NCRYPT_KEY_HANDLE hExportKey,
461 | LPCWSTR pszBlobType,
462 | NCryptBufferDesc *pParameterList,
463 | PBYTE pbOutput,
464 | DWORD cbOutput,
465 | DWORD * pcbResult,
466 | DWORD dwFlags);
467 | ]]
468 |
469 |
470 | ffi.cdef[[
471 |
472 | SECURITY_STATUS
473 | NCryptSignHash(
474 | NCRYPT_KEY_HANDLE hKey,
475 | void *pPaddingInfo,
476 | PBYTE pbHashValue,
477 | DWORD cbHashValue,
478 | PBYTE pbSignature,
479 | DWORD cbSignature,
480 | DWORD * pcbResult,
481 | DWORD dwFlags);
482 |
483 | SECURITY_STATUS
484 | NCryptVerifySignature(
485 | NCRYPT_KEY_HANDLE hKey,
486 | void *pPaddingInfo,
487 | PBYTE pbHashValue,
488 | DWORD cbHashValue,
489 | PBYTE pbSignature,
490 | DWORD cbSignature,
491 | DWORD dwFlags);
492 | ]]
493 |
494 | ffi.cdef[[
495 | SECURITY_STATUS
496 | NCryptDeleteKey(NCRYPT_KEY_HANDLE hKey, DWORD dwFlags);
497 |
498 | SECURITY_STATUS NCryptFreeObject(NCRYPT_HANDLE hObject);
499 |
500 | BOOL NCryptIsKeyHandle(NCRYPT_KEY_HANDLE hKey);
501 |
502 | SECURITY_STATUS NCryptTranslateHandle(
503 | NCRYPT_PROV_HANDLE *phProvider,
504 | NCRYPT_KEY_HANDLE *phKey,
505 | HCRYPTPROV hLegacyProv,
506 | HCRYPTKEY hLegacyKey,
507 | DWORD dwLegacyKeySpec,
508 | DWORD dwFlags);
509 | ]]
510 |
511 | ffi.cdef[[
512 |
513 | SECURITY_STATUS
514 | NCryptNotifyChangeKey(
515 | NCRYPT_PROV_HANDLE hProvider,
516 | HANDLE *phEvent,
517 | DWORD dwFlags);
518 |
519 | SECURITY_STATUS
520 | NCryptSecretAgreement(
521 | NCRYPT_KEY_HANDLE hPrivKey,
522 | NCRYPT_KEY_HANDLE hPubKey,
523 | NCRYPT_SECRET_HANDLE *phAgreedSecret,
524 | DWORD dwFlags);
525 |
526 | SECURITY_STATUS
527 | NCryptDeriveKey(
528 | NCRYPT_SECRET_HANDLE hSharedSecret,
529 | LPCWSTR pwszKDF,
530 | NCryptBufferDesc *pParameterList,
531 | PBYTE pbDerivedKey,
532 | DWORD cbDerivedKey,
533 | DWORD *pcbResult,
534 | ULONG dwFlags);
535 | ]]
536 |
537 | return NCrypt
538 |
--------------------------------------------------------------------------------
/stringutils.lua:
--------------------------------------------------------------------------------
1 | local function bintohex(bytes, len)
2 | local str = ffi.string(bytes, len)
3 |
4 | return (str:gsub('(.)', function(c)
5 | return string.format('%02x', string.byte(c))
6 | end))
7 | end
8 |
--------------------------------------------------------------------------------
/tests/DaytimeClient.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 |
3 | local NativeSocket = require "NativeSocket"
4 | local SocketUtils = require "SocketUtils"
5 |
6 | local daytimeport = 9091
7 |
8 | DaytimeClient = {}
9 | DaytimeClient_mt = {
10 | __index = DaytimeClient,
11 | }
12 |
13 | function DaytimeClient.new(hostname, port)
14 | hostname = hostname or "localhost";
15 | port = port or daytimeport;
16 |
17 | local self = {}
18 | self.Socket, err = CreateTcpClientSocket(hostname, port);
19 |
20 | if not self.Socket then
21 | print("DaytimeClient.new(), error: ", err);
22 | return false, err;
23 | end
24 |
25 | self.Socket:SetNonBlocking(false);
26 | setmetatable(self, DaytimeClient_mt)
27 |
28 | return self;
29 | end
30 |
31 | function DaytimeClient:Run()
32 | local bufflen = 256
33 | local buff = ffi.new("char [256]")
34 |
35 | print("client about to receive");
36 | n, err = self.Socket:Receive(buff, bufflen)
37 | print("client received: ", n);
38 | while (n > 0) do
39 | buff[n] = 0 -- null terminated
40 | print(ffi.string(buff))
41 |
42 | n = self.Socket:Receive(buff, bufflen)
43 | end
44 | end
45 |
46 | return DaytimeClient
47 |
--------------------------------------------------------------------------------
/tests/DaytimeServer.lua:
--------------------------------------------------------------------------------
1 |
2 | local SocketUtils = require "SocketUtils"
3 |
4 |
5 | local function Run(config)
6 | local port = config.port or 13
7 | local ServerSocket, err = SocketUtils.CreateTcpServerSocket({port = port, backlog = 15, nonblocking=false, nodelay = false});
8 |
9 | if not ServerSocket then
10 | return false, err
11 | end
12 |
13 | print("Daytime Server Running")
14 | local acceptedsock = nil
15 | while (true) do
16 | acceptedsock, err = ServerSocket:Accept()
17 |
18 | if acceptedsock then
19 | --print("Accepted: ", acceptedsock);
20 | acceptedsock:Send(os.date("%c"));
21 | acceptedsock:Send("\r\n");
22 |
23 | -- close down the socket
24 | -- or the client won't know when to stop reading
25 | acceptedsock:CloseDown()
26 |
27 | acceptedsock = nil
28 | else
29 | print("No SOCKET");
30 | end
31 | end
32 | end
33 |
34 | return {
35 | Startup = Run,
36 | }
37 |
--------------------------------------------------------------------------------
/tests/TcpServer.lua:
--------------------------------------------------------------------------------
1 |
2 | local SocketUtils = require "SocketUtils"
3 |
4 |
5 | local function Run(config, acceptcallback, idlecallback)
6 | local nonblocking = config.nonblocking
7 | local nodelay = config.nodelay
8 |
9 | local ServerSocket, err = SocketUtils.CreateTcpServerSocket({port = config.port or 80, backlog = config.backlock or 15, nonblocking=nonblocking, nodelay = nodelay});
10 |
11 | if not ServerSocket or not acceptcallback then
12 | return false, err
13 | end
14 |
15 | print("Server Running")
16 | local acceptedsock = nil
17 | while (true) do
18 | acceptedsock, err = ServerSocket:Accept()
19 |
20 | if acceptedsock then
21 | acceptcallback(acceptedsock)
22 | elseif idlecallback then
23 | idlecallback();
24 | end
25 | end
26 | end
27 |
28 | return {
29 | Startup = Run,
30 | }
31 |
--------------------------------------------------------------------------------
/tests/test_BCrypt.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";../?.lua"
2 |
3 | local ffi = require "ffi"
4 |
5 | local BCrypt = require "BCryptUtils"
6 |
7 |
8 | function test_RngAlgorithm()
9 | local rngalgo = BCrypt.BCryptAlgorithm(BCrypt.BCRYPT_RNG_ALGORITHM)
10 |
11 | print("Algo: ",rngalgo);
12 | end
13 |
14 |
15 | function test_RandomBytes()
16 | for j=1,5 do
17 | local rngBuff, err = BCrypt.GetRandomBytes()
18 |
19 | print("Status: ", rngBuff, status);
20 |
21 | local buffLen = ffi.sizeof(rngBuff)
22 |
23 | for i=0,buffLen do
24 | print(rngBuff[i])
25 | end
26 | print("--");
27 | end
28 | end
29 |
30 |
31 |
32 | function test_digests()
33 |
34 | local content = "Take this as the first input to be hashed"
35 |
36 | print("SHA1: ", BCrypt.SHA1(content));
37 | print("SHA256: ", BCrypt.SHA256(content));
38 | print("SHA384: ", BCrypt.SHA384(content));
39 | print("SHA512: ", BCrypt.SHA512(content));
40 |
41 | print("MD2: ", BCrypt.MD2(content));
42 | print("MD4: ", BCrypt.MD4(content));
43 | print("MD5: ", BCrypt.MD5(content));
44 |
45 | end
46 |
47 |
48 | --test_RandomBytes();
49 |
50 | test_digests();
51 |
--------------------------------------------------------------------------------
/tests/test_DaytimeClient.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\?.lua";
2 |
3 | local DaytimeClient = require "DaytimeClient"
4 |
5 | for i=1, 500 do
6 | local dtc = DaytimeClient.new("localhost")
7 | dtc:Run()
8 | end
9 |
--------------------------------------------------------------------------------
/tests/test_DaytimeServer.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\Bhut\\?.lua;..\\Bhut\\core\\?.lua";
2 |
3 | local Server = require "DaytimeServer"
4 |
5 | Server.Startup({port = 9091});
6 |
7 |
--------------------------------------------------------------------------------
/tests/test_DbgHelp.lua:
--------------------------------------------------------------------------------
1 | -- test_DbgHelp.lua
2 |
3 | package.path = package.path..";../?.lua"
4 |
5 | local ffi = require("ffi");
6 |
7 | local dbg = require("dbghelp_ffi")
8 |
9 |
10 | local test_Demangle = function(MangledNames)
11 | local UnDecoratedLength = 255;
12 | local UnDecoratedName = ffi.new("char[?]", UnDecoratedLength);
13 |
14 | for _,name in ipairs(MangledNames) do
15 | local result = dbg.Lib.UnDecorateSymbolName(name,UnDecoratedName, UnDecoratedLength,0);
16 |
17 | if result > 0 then
18 | print(string.format('{mangled="%s", demangled="%s"},', name, ffi.string(UnDecoratedName, result)));
19 | else
20 | print(string.format'{mangled="%s"},', name);
21 | end
22 | end
23 | end
24 |
25 |
26 | local manglednames = {
27 | "??0Foo@Leap@@QAE@ABV01@@Z",
28 | "??0Foo@Leap@@QAE@H@Z",
29 | "??0Foo@Leap@@QAE@XZ",
30 | "??0FooBase@Leap@@QAE@ABV01@@Z",
31 | "??0FooBase@Leap@@QAE@XZ",
32 | "??1Foo@Leap@@UAE@XZ",
33 | "??1FooBase@Leap@@UAE@XZ",
34 | "??4Foo@Leap@@QAEAAV01@ABV01@@Z",
35 | "??4FooBase@Leap@@QAEAAV01@ABV01@@Z",
36 | "??_7Foo@Leap@@6B@",
37 | "??_7FooBase@Leap@@6B@",
38 | "?get@Foo@Leap@@QAEHXZ",
39 | }
40 |
41 | test_Demangle(manglednames);
42 |
--------------------------------------------------------------------------------
/tests/test_NCrypt.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";../?.lua"
2 |
3 | local ncr = require "ncrypt"
4 | local NCrypt = require "NCryptUtils"
5 |
6 | local provider = NCryptStorageProvider();
7 | print(provider);
8 |
9 | function test_EnumAlgorithms(provider)
10 | local algos = provider:EnumerateAlgorithms();
11 |
12 | for i, algo in ipairs(algos) do
13 | print(algo.name, algo.class);
14 | end
15 | end
16 |
17 | function test_GetAllKeys(provider)
18 | local keys = provider:GetAllKeys(ncr.NCRYPT_MACHINE_KEY_FLAG);
19 | -- local keys = provider:GetAllKeys();
20 |
21 | print(keys, #keys);
22 |
23 | for i,key in ipairs(keys) do
24 | print(key.name, key.algoid);
25 | end
26 | end
27 |
28 | --test_EnumAlgorithms(provider);
29 |
30 | test_GetAllKeys(provider);
31 |
--------------------------------------------------------------------------------
/tests/test_TcpServer.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\?.lua;..\\core\\?.lua";
2 |
3 | local port = 9091
4 |
5 | server = require "TcpServer"
6 |
7 | local cnt = 1
8 |
9 | local acceptcallback = function(acceptedsock)
10 | acceptedsock.id = cnt
11 | cnt = cnt + 1
12 | acceptedsock:Send(os.date("%c"));
13 | acceptedsock:Send("\r\n");
14 |
15 | acceptedsock:CloseDown()
16 | end
17 |
18 | local idlecnt = 1;
19 | local idlecallback = function()
20 | -- call the GC for every 500 connections
21 | if cnt >= 500 then
22 | print("Calling GC: ", idlecnt);
23 | collectgarbage();
24 | cnt = 0
25 | end
26 | idlecnt = idlecnt + 1
27 | end
28 |
29 | server.Startup({port = 9091, nonblocking=true, nodelay=false}, acceptcallback, idlecallback);
30 |
--------------------------------------------------------------------------------
/tests/test_library_load.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";../?.lua"
2 |
3 | local ffi = require "ffi"
4 | --require "kernel32_ffi"
5 |
6 | ffi.C.Sleep(3000);
7 |
--------------------------------------------------------------------------------
/tests/test_sslprovider.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";../?.lua"
2 |
3 | local ffi = require "ffi"
4 |
5 | local SSL = require "sslprovider"
6 | local k32 = require "Kernel32"
7 |
8 | A = k32.Unicode16ToAnsi
9 |
10 | function test_SslEnumProtocolProviders()
11 | local pdwProviderCount = ffi.new("uint32_t[1]");
12 | local ppProviderList = ffi.new("PNCryptProviderName[1]");
13 | local dwFlags = 0;
14 |
15 | local status = SSL.Lib.SslEnumProtocolProviders(pdwProviderCount, ppProviderList, dwFlags);
16 |
17 | if status ~= 0 then
18 | print("FAIL: ", status)
19 | return
20 | end
21 |
22 | local count = pdwProviderCount[0];
23 |
24 | print("Provider Count: ", count);
25 |
26 |
27 | for i=0,count-1 do
28 | local pName = ppProviderList[i];
29 | local name = A(pName.pszName);
30 | local comment = A(pName.pszComment);
31 |
32 | print("Protocol Provider: ", name, comment);
33 | end
34 |
35 | end
36 |
37 | SSLFactory = {}
38 | SSLFactory_mt = {
39 | __index = SSLFactory,
40 | }
41 |
42 | SSLFactory.GetInterface = function(providerName)
43 | providerName = providerName or SSL.MS_SCHANNEL_PROVIDER
44 | local ppFunctionTable = ffi.new("PNCRYPT_SSL_FUNCTION_TABLE[1]");
45 | local dwFlags = 0;
46 |
47 | local status = SSL.Lib.GetSChannelInterface(SSL.MS_SCHANNEL_PROVIDER, ppFunctionTable, dwFlags);
48 |
49 | if status ~= 0 then
50 | return nil
51 | end
52 |
53 | local functionTable = ppFunctionTable[0]
54 |
55 | local obj = {
56 | VTable = functionTable;
57 | ProviderName = providerName
58 | }
59 | setmetatable(obj, SSLFactory_mt);
60 |
61 | return obj
62 | end
63 |
64 | function SSLFactory:OpenProvider()
65 | local phSslProvider = ffi.new("NCRYPT_PROV_HANDLE[1]");
66 | local dwFlags = 0;
67 |
68 | local status = self.VTable.SslOpenProvider(phSslProvider, self.ProviderName, dwFlags);
69 |
70 | if status ~= 0 then
71 | return nil, status
72 | end
73 |
74 | return SSLProvider(phSslProvider[0])
75 | end
76 |
77 |
78 | function test_GetInterface()
79 | local sslI = SSLFactory.GetInterface()
80 |
81 | if not sslI then
82 | print("FAIL");
83 | return
84 | end
85 |
86 | local provider, err = sslI:OpenProvider()
87 |
88 | if not provider then
89 | print("FAIL");
90 | end
91 |
92 |
93 | end
94 |
95 | --test_SslEnumProtocolProviders();
96 |
97 | test_GetInterface();
98 |
--------------------------------------------------------------------------------
/tests/test_tcp_socket.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\?.lua;..\\core\\?.lua";
2 |
3 | local ffi = require "ffi"
4 |
5 | local WinSock = require "WinSock_Utils"
6 | local SocketUtils = require "SocketUtils"
7 | local NativeSocket = require "NativeSocket"
8 |
9 | function pathFromResource(resource)
10 | print("pathFromResource: ", resource)
11 |
12 | local urloffset = resource:find("//", 1, true)
13 | print("urloffset: ", urloffset)
14 | if not urloffset then
15 | return nil
16 | end
17 |
18 | local url = resource:sub(urloffset+2)
19 | print("URL:",url);
20 |
21 | local pathoffset = url:find("//", 1, true)
22 | if not pathoffset then
23 | return "/", url
24 | end
25 |
26 | local path = url:sub(pathoffset+2)
27 |
28 | return path, url
29 | end
30 |
31 | function test_bytes_ready()
32 | local socket = CreateTcpSocket()
33 | --socket:SetNonBlocking(false)
34 |
35 | print(socket:GetBytesPendingReceive())
36 | end
37 |
38 | function test_path_parsing()
39 | local path, url = pathFromResource("/connect/browser/jakljdfkjjasdfl//http://www.adafruit.com/index.html")
40 |
41 | print("PATH:",path)
42 | print("URL:",url)
43 | end
44 |
45 | function sockerr(err)
46 | local anerror = WinSock.SocketErrors[err]
47 |
48 | if anerror then return anerror[2] end
49 |
50 | return tostring(err)
51 | end
52 |
53 | function test_receive_zero()
54 | -- create a socket
55 | --local sock = CreateTcpSocket()
56 | -- see if it's connected
57 | --print("Sock Currently Connected: ", sock:IsCurrentlyConnected());
58 |
59 | -- try to ready 0 bytes from it
60 | local buff = ffi.new("uint8_t[1024]")
61 |
62 |
63 | -- Try the same thing with a connected socket
64 | local gsock, err = SocketUtils.CreateTcpClientSocket("www.google.com", 80)
65 | --gsock:SetNonBlocking(true)
66 | print("GSocket Creation: ", gsock, "Error: ", err);
67 |
68 | if err then
69 | print("GSock Connected: ", WinSock.GetSocketErrorString(err));
70 | end
71 |
72 | -- try to receive blank
73 | nbytes, err = gsock:Receive(buff, 0, 0)
74 | print(" GSock Send:",WinSock.GetSocketErrorString(err), nbytes);
75 | end
76 |
77 | function test_send_zero()
78 | -- create a simple buffer
79 | local buff = ffi.new("uint8_t[1024]")
80 |
81 | -- Create a connected socket
82 | local gsock, err = SocketUtils.CreateTcpClientSocket("www.google.com", 80)
83 | gsock:SetNonBlocking(true)
84 | print("GSocket Creation: ", gsock, "Error: ", err);
85 |
86 | if err then
87 | print("GSock Connected: ", WinSock.GetSocketErrorString(err));
88 | end
89 |
90 | -- try to send blank
91 | local nbytes, err = gsock:Send(buff, 0, 0)
92 | print("Send Connected:",WinSock.GetSocketErrorString(err), "Bytes: ", nbytes);
93 | end
94 |
95 | --test_receive_zero();
96 | test_send_zero();
97 |
--------------------------------------------------------------------------------
/tests/test_timedloop.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\?.lua;..\\core\\?.lua";
2 |
3 | local TimedLoop = require "TimedLoop"
4 | require "StopWatch"
5 |
6 | local sw = StopWatch.new()
7 |
8 | function callback(tickCount, params)
9 | print("callback: ", tickCount, tickCount/sw:Seconds())
10 |
11 | --[[
12 | local msg = ffi.new("MSG")
13 |
14 | while (user32.PeekMessageA(msg, nil, 0, 0, C.PM_REMOVE) ~= 0) do
15 | user32.TranslateMessage(msg)
16 | user32.DispatchMessageA(msg)
17 |
18 | if msg.message == C.WM_QUIT then
19 | return win:OnQuit()
20 | end
21 | end
22 | --]]
23 | end
24 |
25 |
26 | local fps = arg[1] or 1
27 |
28 |
29 | local looper = TimedLoop(callback, fps);
30 |
--------------------------------------------------------------------------------
/tests/test_timers-raw.lua:
--------------------------------------------------------------------------------
1 | package.path = package.path..";..\\?.lua;..\\core\\?.lua";
2 |
3 | local Timer = require "TimedLoop"
4 |
5 | local timer = Timer:new()
6 | local timer2 = Timer:new()
7 |
8 | timer:start(2000, 0, function (...)
9 | p("on_timeout", ...)
10 | timer2:stop()
11 | timer:stop()
12 | timer:close(p)
13 | timer2:close(p)
14 | end)
15 |
16 | timer2:start(333, 333, function (...)
17 | p("on_interval", ...)
18 | local period = timer2:getRepeat()
19 | p("period", period)
20 | timer2:setRepeat(period / 1.2 + 1);
21 | end)
22 |
23 | p(timer, timer2)
--------------------------------------------------------------------------------
/user32_ffi.lua:
--------------------------------------------------------------------------------
1 | local ffi = require "ffi"
2 | local C = ffi.C
3 |
4 | require "WTypes"
5 |
6 | -- Winnt.h
7 | MAXIMUM_WAIT_OBJECTS = 64 -- Maximum number of wait objects
8 |
9 | local user32_ffi = {
10 | CW_USEDEFAULT = 0x80000000,
11 |
12 | CS_VREDRAW = 0x0001,
13 | CS_HREDRAW = 0x0002,
14 | CS_DBLCLKS = 0x0008,
15 | CS_OWNDC = 0x0020,
16 | CS_CLASSDC = 0x0040,
17 | CS_NOCLOSE = 0x0200,
18 | CS_SAVEBITS = 0x0800,
19 | CS_BYTEALIGNCLIENT = 0x1000,
20 | CS_BYTEALIGNWINDOW = 0x2000,
21 | CS_GLOBALCLASS = 0x4000,
22 | CS_DROPSHADOW = 0x00020000,
23 |
24 |
25 | WS_POPUP = 0x80000000,
26 | WS_MAXIMIZEBOX = 0x00010000,
27 | WS_SIZEBOX = 0x00040000,
28 | WS_SYSMENU = 0x00080000,
29 | WS_HSCROLL = 0x00100000,
30 | WS_VSCROLL = 0x00200000,
31 | WS_OVERLAPPEDWINDOW = 0x00CF0000,
32 | WS_MAXIMIZE = 0x01000000,
33 | WS_VISIBLE = 0x10000000,
34 | WS_MINIMIZE = 0x20000000,
35 |
36 | WS_EX_WINDOWEDGE = 0x00000100,
37 | WS_EX_APPWINDOW = 0x00040000,
38 |
39 | -- Standard User32 Messages
40 | WM_CREATE = 0x0001,
41 | WM_DESTROY = 0x0002,
42 | WM_ACTIVATE = 0x0006,
43 | WM_SETFOCUS = 0x0007,
44 | WM_KILLFOCUS = 0x0008,
45 | WM_ENABLE = 0x000A,
46 | WM_SETTEXT = 0x000C,
47 | WM_GETTEXT = 0x000D,
48 | WM_PAINT = 0x000F,
49 | WM_CLOSE = 0x0010,
50 | WM_QUIT = 0x0012,
51 | WM_ACTIVATEAPP = 0x001C,
52 |
53 | WM_SETCURSOR = 0x0020,
54 | WM_GETMINMAXINFO = 0x0024,
55 | WM_WINDOWPOSCHANGING = 0x0046,
56 | WM_WINDOWPOSCHANGED = 0x0047,
57 | WM_NCCREATE = 0x0081,
58 | WM_NCDESTROY = 0x0082,
59 | WM_NCCALCSIZE = 0x0083,
60 | WM_NCHITTEST = 0x0084,
61 | WM_NCPAINT = 0x0085,
62 | WM_NCACTIVATE = 0x0086,
63 |
64 | -- Non Client (NC) mouse activity
65 | WM_NCMOUSEMOVE = 0x00A0,
66 | WM_NCLBUTTONDOWN = 0x00A1,
67 | WM_NCLBUTTONUP = 0x00A2,
68 | WM_NCLBUTTONDBLCLK = 0x00A3,
69 | WM_NCRBUTTONDOWN = 0x00A4,
70 | WM_NCRBUTTONUP = 0x00A5,
71 | WM_NCRBUTTONDBLCLK = 0x00A6,
72 | WM_NCMBUTTONDOWN = 0x00A7,
73 | WM_NCMBUTTONUP = 0x00A8,
74 | WM_NCMBUTTONDBLCLK = 0x00A9,
75 |
76 | WM_INPUT_DEVICE_CHANGE = 0x00FE,
77 | WM_INPUT = 0x00FF,
78 |
79 | -- Keyboard Activity
80 | WM_KEYDOWN = 0x0100,
81 | WM_KEYUP = 0x0101,
82 | WM_CHAR = 0x0102,
83 | WM_DEADCHAR = 0x0103,
84 | WM_SYSKEYDOWN = 0x0104,
85 | WM_SYSKEYUP = 0x0105,
86 | WM_SYSCHAR = 0x0106,
87 | WM_SYSDEADCHAR = 0x0107,
88 | WM_COMMAND = 0x0111,
89 | WM_SYSCOMMAND = 0x0112,
90 |
91 |
92 | WM_TIMER = 0x0113,
93 |
94 | -- client area mouse activity
95 | WM_MOUSEFIRST = 0x0200,
96 | WM_MOUSEMOVE = 0x0200,
97 | WM_LBUTTONDOWN = 0x0201,
98 | WM_LBUTTONUP = 0x0202,
99 | WM_LBUTTONDBLCLK = 0x0203,
100 | WM_RBUTTONDOWN = 0x0204,
101 | WM_RBUTTONUP = 0x0205,
102 | WM_RBUTTONDBLCLK = 0x0206,
103 | WM_MBUTTONDOWN = 0x0207,
104 | WM_MBUTTONUP = 0x0208,
105 | WM_MBUTTONDBLCLK = 0x0209,
106 | WM_MOUSEWHEEL = 0x020A,
107 | WM_XBUTTONDOWN = 0x020B,
108 | WM_XBUTTONUP = 0x020C,
109 | WM_XBUTTONDBLCLK = 0x020D,
110 | WM_MOUSELAST = 0x020D,
111 |
112 | WM_SIZING = 0x0214,
113 | WM_CAPTURECHANGED = 0x0215,
114 | WM_MOVING = 0x0216,
115 | WM_DEVICECHANGE = 0x0219,
116 |
117 | WM_ENTERSIZEMOVE = 0x0231,
118 | WM_EXITSIZEMOVE = 0x0232,
119 | WM_DROPFILES = 0x0233,
120 |
121 | WM_IME_SETCONTEXT = 0x0281,
122 | WM_IME_NOTIFY = 0x0282,
123 |
124 | WM_NCMOUSEHOVER = 0x02A0,
125 | WM_MOUSEHOVER = 0x02A1,
126 | WM_NCMOUSELEAVE = 0x02A2,
127 | WM_MOUSELEAVE = 0x02A3,
128 |
129 | WM_PRINT = 0x0317,
130 |
131 | WM_DWMCOMPOSITIONCHANGED = 0x031E,
132 | WM_DWMNCRENDERINGCHANGED = 0x031F,
133 | WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320,
134 | WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
135 |
136 |
137 | SW_SHOW = 5,
138 |
139 | PM_REMOVE = 0x0001,
140 | PM_NOYIELD = 0x0002,
141 |
142 | -- dwWakeMask of MsgWaitForMultipleObjectsEx()
143 | QS_KEY = 0x0001,
144 | QS_MOUSEMOVE = 0x0002,
145 | QS_MOUSEBUTTON = 0x0004,
146 | QS_MOUSE = 0x0006,
147 | QS_POSTMESSAGE = 0x0008,
148 | QS_TIMER = 0x0010,
149 | QS_PAINT = 0x0020,
150 | QS_SENDMESSAGE = 0x0040,
151 | QS_HOTKEY = 0x0080,
152 | QS_ALLPOSTMESSAGE = 0x0100,
153 | QS_RAWINPUT = 0x0400,
154 | QS_INPUT = 0x0407,
155 | QS_ALLEVENTS = 0x04BF,
156 | QS_ALLINPUT = 0x04FF,
157 |
158 | -- dwFlags of MsgWaitForMultipleObjectsEx()
159 | MWMO_WAITALL = 0x0001,
160 | MWMO_ALERTABLE = 0x0002,
161 | MWMO_INPUTAVAILABLE = 0x0004,
162 |
163 | WAIT_OBJECT_0 = 0x00000000,
164 | INFINITE = 0xFFFFFFFF,
165 |
166 | HWND_DESKTOP = 0x0000,
167 | HWND_BROADCAST = 0xffff,
168 | HWND_TOP = (0),
169 | HWND_BOTTOM = (1),
170 | HWND_TOPMOST = (-1),
171 | HWND_NOTOPMOST = (-2),
172 | HWND_MESSAGE = (-3),
173 |
174 |
175 | -- Used for GetSystemMetrics
176 | CXSCREEN = 0,
177 | CYSCREEN = 1,
178 | CXVSCROLL = 2,
179 | CYHSCROLL = 3,
180 | CYCAPTION = 4,
181 | CXBORDER = 5,
182 | CYBORDER = 6,
183 | CXDLGFRAME = 7,
184 | CXFIXEDFRAME = 7,
185 | CYDLGFRAME = 8,
186 | CYFIXEDFRAME = 8,
187 | CYVTHUMB = 9,
188 | CXHTHUMB = 10,
189 | CXICON = 11,
190 | CYICON = 12,
191 | CXCURSOR = 13,
192 | CYCURSOR = 14,
193 | CYMENU = 15,
194 | CXFULLSCREEN = 16,
195 | CYFULLSCREEN = 17,
196 | CYKANJIWINDOW = 18,
197 | MOUSEPRESENT = 19,
198 | CYVSCROLL = 20,
199 | CXHSCROLL = 21,
200 | DEBUG = 22,
201 | SWAPBUTTON = 23,
202 | RESERVED1 = 24,
203 | RESERVED2 = 25,
204 | RESERVED3 = 26,
205 | RESERVED4 = 27,
206 | CXMIN = 28,
207 | CYMIN = 29,
208 | CXSIZE = 30,
209 | CYSIZE = 31,
210 | CXSIZEFRAME = 32,
211 | CXFRAME = 32,
212 | CYFRAME = 33,
213 | CYSIZEFRAME = 33,
214 | CXMINTRACK = 34,
215 | CYMINTRACK = 35,
216 | CXDOUBLECLK = 36,
217 | CYDOUBLECLK = 37,
218 | CXICONSPACING = 38,
219 | CYICONSPACING = 39,
220 | MENUDROPALIGNMENT = 40,
221 | PENWINDOWS = 41,
222 | DBCSENABLED = 42,
223 | CMOUSEBUTTONS = 43,
224 | SECURE = 44,
225 | CXEDGE = 45,
226 | CYEDGE = 46,
227 | CXMINSPACING = 47,
228 | CYMINSPACING = 48,
229 | CXSMICON = 49,
230 | CYSMICON = 50,
231 | CYSMCAPTION = 51,
232 | CXSMSIZE = 52,
233 | CYSMSIZE = 53,
234 | CXMENUSIZE = 54,
235 | CYMENUSIZE = 55,
236 | ARRANGE = 56,
237 | CXMINIMIZED = 57,
238 | CYMINIMIZED = 58,
239 | CXMAXTRACK = 59,
240 | CYMAXTRACK = 60,
241 | CXMAXIMIZED = 61,
242 | CYMAXIMIZED = 62,
243 | NETWORK = 63,
244 | CLEANBOOT = 67,
245 | CXDRAG = 68,
246 | CYDRAG = 69,
247 | SHOWSOUNDS = 70,
248 | CXMENUCHECK = 71,
249 | CYMENUCHECK = 72,
250 | SLOWMACHINE = 73,
251 | MIDEASTENABLED = 74,
252 | MOUSEWHEELPRESENT = 75,
253 | XVIRTUALSCREEN = 76,
254 | YVIRTUALSCREEN = 77,
255 | CXVIRTUALSCREEN = 78,
256 | CYVIRTUALSCREEN = 79,
257 | CMONITORS = 80,
258 | SAMEDISPLAYFORMAT = 81,
259 | CMETRICS = 83,
260 |
261 |
262 | }
263 |
264 | -- Input handling
265 | ffi.cdef[[
266 | typedef struct tagMOUSEINPUT {
267 | LONG dx;
268 | LONG dy;
269 | DWORD mouseData;
270 | DWORD dwFlags;
271 | DWORD time;
272 | ULONG_PTR dwExtraInfo;
273 | } MOUSEINPUT, *PMOUSEINPUT;
274 |
275 | typedef struct tagKEYBDINPUT {
276 | WORD wVk;
277 | WORD wScan;
278 | DWORD dwFlags;
279 | DWORD time;
280 | ULONG_PTR dwExtraInfo;
281 | } KEYBDINPUT, *PKEYBDINPUT;
282 |
283 | typedef struct tagHARDWAREINPUT {
284 | DWORD uMsg;
285 | WORD wParamL;
286 | WORD wParamH;
287 | } HARDWAREINPUT, *PHARDWAREINPUT;
288 |
289 |
290 | static const int INPUT_MOUSE = 0;
291 | static const int INPUT_KEYBOARD = 1;
292 | static const int INPUT_HARDWARE = 2;
293 |
294 | typedef struct tagINPUT {
295 | DWORD type;
296 | union {
297 | MOUSEINPUT mi;
298 | KEYBDINPUT ki;
299 | HARDWAREINPUT hi;
300 | };
301 | } INPUT, *PINPUT;
302 |
303 | UINT SendInput(
304 | UINT nInputs,
305 | PINPUT pInputs,
306 | int cbSize
307 | );
308 | ]]
309 |
310 |
311 | -- WINDOW CONSTRUCTION
312 | ffi.cdef[[
313 | typedef LRESULT (__stdcall *WNDPROC) (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
314 | typedef LRESULT (__stdcall *MsgProc) (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
315 |
316 | typedef struct {
317 | HWND hwnd;
318 | UINT message;
319 | WPARAM wParam;
320 | LPARAM lParam;
321 | DWORD time;
322 | POINT pt;
323 | } MSG, *PMSG;
324 |
325 | typedef struct {
326 | UINT style;
327 | WNDPROC lpfnWndProc;
328 | int cbClsExtra;
329 | int cbWndExtra;
330 | HINSTANCE hInstance;
331 | HICON hIcon;
332 | HCURSOR hCursor;
333 | HBRUSH hbrBackground;
334 | LPCSTR lpszMenuName;
335 | LPCSTR lpszClassName;
336 | } WNDCLASSA, *PWNDCLASSA;
337 |
338 | typedef struct {
339 | UINT cbSize;
340 | UINT style;
341 | WNDPROC lpfnWndProc;
342 | int cbClsExtra;
343 | int cbWndExtra;
344 | HINSTANCE hInstance;
345 | HICON hIcon;
346 | HCURSOR hCursor;
347 | HBRUSH hbrBackground;
348 | LPCSTR lpszMenuName;
349 | LPCSTR lpszClassName;
350 | HICON hIconSm;
351 | } WNDCLASSEXA, *PWNDCLASSEXA;
352 |
353 |
354 |
355 | typedef struct tagCREATESTRUCT {
356 | LPVOID lpCreateParams;
357 | HINSTANCE hInstance;
358 | HMENU hMenu;
359 | HWND hwndParent;
360 | int cy;
361 | int cx;
362 | int y;
363 | int x;
364 | LONG style;
365 | LPCSTR lpszName;
366 | LPCSTR lpszClass;
367 | DWORD dwExStyle;
368 | } CREATESTRUCTA, *LPCREATESTRUCTA;
369 |
370 | typedef struct {
371 | POINT ptReserved;
372 | POINT ptMaxSize;
373 | POINT ptMaxPosition;
374 | POINT ptMinTrackSize;
375 | POINT ptMaxTrackSize;
376 | } MINMAXINFO, *PMINMAXINFO;
377 |
378 |
379 |
380 | static const int CCHDEVICENAME = 32;
381 | static const int CCHFORMNAME = 32;
382 |
383 |
384 | typedef struct _devicemode {
385 | BCHAR dmDeviceName[CCHDEVICENAME];
386 | WORD dmSpecVersion;
387 | WORD dmDriverVersion;
388 | WORD dmSize;
389 | WORD dmDriverExtra;
390 | DWORD dmFields;
391 | union {
392 | struct {
393 | short dmOrientation;
394 | short dmPaperSize;
395 | short dmPaperLength;
396 | short dmPaperWidth;
397 | short dmScale;
398 | short dmCopies;
399 | short dmDefaultSource;
400 | short dmPrintQuality;
401 | };
402 | POINTL dmPosition;
403 | DWORD dmDisplayOrientation;
404 | DWORD dmDisplayFixedOutput;
405 | };
406 |
407 | short dmColor;
408 | short dmDuplex;
409 | short dmYResolution;
410 | short dmTTOption;
411 | short dmCollate;
412 | BYTE dmFormName[CCHFORMNAME];
413 | WORD dmLogPixels;
414 | DWORD dmBitsPerPel;
415 | DWORD dmPelsWidth;
416 | DWORD dmPelsHeight;
417 | union {
418 | DWORD dmDisplayFlags;
419 | DWORD dmNup;
420 | };
421 | DWORD dmDisplayFrequency;
422 | DWORD dmICMMethod;
423 | DWORD dmICMIntent;
424 | DWORD dmMediaType;
425 | DWORD dmDitherType;
426 | DWORD dmReserved1;
427 | DWORD dmReserved2;
428 | DWORD dmPanningWidth;
429 | DWORD dmPanningHeight;
430 | } DEVMODE, *PDEVMODE;
431 |
432 |
433 |
434 | ]]
435 |
436 |
437 |
438 |
439 | -- Windows functions
440 | ffi.cdef[[
441 |
442 | DWORD MsgWaitForMultipleObjects(
443 | DWORD nCount,
444 | const HANDLE* pHandles,
445 | BOOL bWaitAll,
446 | DWORD dwMilliseconds);
447 |
448 | DWORD MsgWaitForMultipleObjectsEx(
449 | DWORD nCount,
450 | const HANDLE* pHandles,
451 | DWORD dwMilliseconds,
452 | DWORD dwWakeMask,
453 | DWORD dwFlags
454 | );
455 |
456 | // PostMessage
457 | BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
458 |
459 | // PostQuitMessage
460 | void PostQuitMessage(int nExitCode);
461 |
462 | // PostThreadMessage
463 | BOOL PostThreadMessageA(DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam);
464 |
465 | // SendMessage
466 | int SendMessageA(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
467 |
468 | //int SendMessageW([In] IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
469 |
470 | // TranslateMessage
471 | BOOL TranslateMessage(const MSG *lpMsg);
472 |
473 | // DispatchMessage
474 | LRESULT DispatchMessageA(const MSG *lpmsg);
475 |
476 | // GetMessage
477 | BOOL GetMessageA(PMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);
478 |
479 | // GetMessageExtraInfo
480 | LPARAM GetMessageExtraInfo(void);
481 |
482 | // PeekMessage
483 | BOOL PeekMessageA(PMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg);
484 |
485 | // WaitMessage
486 | BOOL WaitMessage(void);
487 | ]]
488 |
489 | ffi.cdef[[
490 |
491 | LRESULT CallWindowProc(WNDPROC lpPrevWndFunc, HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
492 |
493 | LRESULT DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
494 |
495 |
496 | ATOM RegisterClassExA(const WNDCLASSEXA *lpwcx);
497 | ATOM RegisterClassA(const WNDCLASSA *lpWndClass);
498 |
499 | HWND CreateWindow(
500 | LPCSTR lpClassName,
501 | LPCSTR lpWindowName,
502 | DWORD dwStyle,
503 | int x,
504 | int y,
505 | int nWidth,
506 | int nHeight,
507 | HWND hWndParent,
508 | HMENU hMenu,
509 | HINSTANCE hInstance,
510 | LPVOID lpParam);
511 |
512 | HWND CreateWindowExA(
513 | DWORD dwExStyle,
514 | const LPCSTR lpClassName,
515 | const LPCSTR lpWindowName,
516 | DWORD dwStyle,
517 | int x,
518 | int y,
519 | int nWidth,
520 | int nHeight,
521 | HWND hWndParent,
522 | HMENU hMenu,
523 | HINSTANCE hInstance,
524 | LPVOID lpParam
525 | );
526 |
527 |
528 |
529 | BOOL ShowWindow(HWND hWnd, int nCmdShow);
530 |
531 | BOOL UpdateWindow(HWND hWnd);
532 |
533 | HICON LoadIconA(HINSTANCE hInstance, LPCSTR lpIconName);
534 |
535 | HCURSOR LoadCursorA(HINSTANCE hInstance, LPCSTR lpCursorName);
536 |
537 | int GetClientRect(HWND hWnd, RECT *rect);
538 |
539 |
540 | ]]
541 |
542 | -- System related calls
543 | ffi.cdef[[
544 | int GetSystemMetrics(int nIndex);
545 | ]]
546 |
547 |
548 | -- WINDOW DRAWING
549 | ffi.cdef[[
550 | HDC GetWindowDC(HWND hWnd);
551 | BOOL InvalidateRect(HWND hWnd, const RECT* lpRect, BOOL bErase);
552 |
553 |
554 | // WINDOW UTILITIES
555 |
556 |
557 | typedef BOOL (*WNDENUMPROC)(HWND hwnd, LPARAM l);
558 |
559 | int EnumWindows(WNDENUMPROC func, LPARAM l);
560 |
561 | HWND GetForegroundWindow(void);
562 |
563 | BOOL MessageBeep(UINT type);
564 |
565 | int MessageBoxA(HWND hWnd,
566 | LPCTSTR lpText,
567 | LPCTSTR lpCaption,
568 | UINT uType
569 | );
570 | ]]
571 |
572 | -- Window Station
573 | ffi.cdef[[
574 | BOOL CloseWindowStation(HWINSTA hWinSta);
575 |
576 | HWINSTA CreateWindowStation(
577 | LPCTSTR lpwinsta,
578 | DWORD dwFlags,
579 | ACCESS_MASK dwDesiredAccess,
580 | LPSECURITY_ATTRIBUTES lpsa
581 | );
582 |
583 |
584 | // Callback function for EnumWindowStations
585 | typedef BOOL (__stdcall *WINSTAENUMPROC) (LPTSTR lpszWindowStation,LPARAM lParam);
586 |
587 | BOOL EnumWindowStations(WINSTAENUMPROC lpEnumFunc, LPARAM lParam);
588 |
589 | HWINSTA GetProcessWindowStation(void);
590 |
591 | HWINSTA OpenWindowStationA(LPTSTR lpszWinSta, BOOL fInherit, ACCESS_MASK dwDesiredAccess);
592 | HWINSTA OpenWindowStationW(LPTSTR lpszWinSta, BOOL fInherit, ACCESS_MASK dwDesiredAccess);
593 |
594 | BOOL SetProcessWindowStation(HWINSTA hWinSta);
595 |
596 | BOOL GetUserObjectInformation(HANDLE hObj,
597 | int nIndex,
598 | PVOID pvInfo,
599 | DWORD nLength,
600 | LPDWORD lpnLengthNeeded
601 | );
602 |
603 | /*
604 | BOOL GetUserObjectSecurity(HANDLE hObj,
605 | PSECURITY_INFORMATION pSIRequested,
606 | PSECURITY_DESCRIPTOR pSD,
607 | DWORD nLength,
608 | LPDWORD lpnLengthNeeded
609 | );
610 |
611 |
612 | BOOL SetUserObjectInformation(HANDLE hObj,
613 | int nIndex,
614 | PVOID pvInfo,
615 | DWORD nLength
616 | );
617 |
618 | BOOL SetUserObjectSecurity(HANDLE hObj,
619 | PSECURITY_INFORMATION pSIRequested,
620 | PSECURITY_DESCRIPTOR pSID
621 | );
622 | */
623 | ]]
624 |
625 |
626 | return user32_ffi
627 |
--------------------------------------------------------------------------------