winlean.nim 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2012 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements a small wrapper for some needed Win API procedures,
  10. ## so that the Nim compiler does not depend on the huge Windows module.
  11. {.deadCodeElim:on.}
  12. import dynlib
  13. when defined(vcc):
  14. {.passC: "-DWIN32_LEAN_AND_MEAN".}
  15. const
  16. useWinUnicode* = not defined(useWinAnsi)
  17. when useWinUnicode:
  18. type WinChar* = Utf16Char
  19. {.deprecated: [TWinChar: WinChar].}
  20. else:
  21. type WinChar* = char
  22. {.deprecated: [TWinChar: WinChar].}
  23. type
  24. Handle* = int
  25. LONG* = int32
  26. ULONG* = int32
  27. PULONG* = ptr int
  28. WINBOOL* = int32
  29. DWORD* = int32
  30. PDWORD* = ptr DWORD
  31. LPINT* = ptr int32
  32. ULONG_PTR* = uint
  33. PULONG_PTR* = ptr uint
  34. HDC* = Handle
  35. HGLRC* = Handle
  36. SECURITY_ATTRIBUTES* {.final, pure.} = object
  37. nLength*: int32
  38. lpSecurityDescriptor*: pointer
  39. bInheritHandle*: WINBOOL
  40. STARTUPINFO* {.final, pure.} = object
  41. cb*: int32
  42. lpReserved*: cstring
  43. lpDesktop*: cstring
  44. lpTitle*: cstring
  45. dwX*: int32
  46. dwY*: int32
  47. dwXSize*: int32
  48. dwYSize*: int32
  49. dwXCountChars*: int32
  50. dwYCountChars*: int32
  51. dwFillAttribute*: int32
  52. dwFlags*: int32
  53. wShowWindow*: int16
  54. cbReserved2*: int16
  55. lpReserved2*: pointer
  56. hStdInput*: Handle
  57. hStdOutput*: Handle
  58. hStdError*: Handle
  59. PROCESS_INFORMATION* {.final, pure.} = object
  60. hProcess*: Handle
  61. hThread*: Handle
  62. dwProcessId*: int32
  63. dwThreadId*: int32
  64. FILETIME* {.final, pure.} = object ## CANNOT BE int64 BECAUSE OF ALIGNMENT
  65. dwLowDateTime*: DWORD
  66. dwHighDateTime*: DWORD
  67. BY_HANDLE_FILE_INFORMATION* {.final, pure.} = object
  68. dwFileAttributes*: DWORD
  69. ftCreationTime*: FILETIME
  70. ftLastAccessTime*: FILETIME
  71. ftLastWriteTime*: FILETIME
  72. dwVolumeSerialNumber*: DWORD
  73. nFileSizeHigh*: DWORD
  74. nFileSizeLow*: DWORD
  75. nNumberOfLinks*: DWORD
  76. nFileIndexHigh*: DWORD
  77. nFileIndexLow*: DWORD
  78. OSVERSIONINFO* {.final, pure.} = object
  79. dwOSVersionInfoSize*: DWORD
  80. dwMajorVersion*: DWORD
  81. dwMinorVersion*: DWORD
  82. dwBuildNumber*: DWORD
  83. dwPlatformId*: DWORD
  84. szCSDVersion*: array[0..127, WinChar]
  85. {.deprecated: [THandle: Handle, TSECURITY_ATTRIBUTES: SECURITY_ATTRIBUTES,
  86. TSTARTUPINFO: STARTUPINFO, TPROCESS_INFORMATION: PROCESS_INFORMATION,
  87. TFILETIME: FILETIME, TBY_HANDLE_FILE_INFORMATION: BY_HANDLE_FILE_INFORMATION].}
  88. const
  89. STARTF_USESHOWWINDOW* = 1'i32
  90. STARTF_USESTDHANDLES* = 256'i32
  91. HIGH_PRIORITY_CLASS* = 128'i32
  92. IDLE_PRIORITY_CLASS* = 64'i32
  93. NORMAL_PRIORITY_CLASS* = 32'i32
  94. REALTIME_PRIORITY_CLASS* = 256'i32
  95. WAIT_OBJECT_0* = 0'i32
  96. WAIT_TIMEOUT* = 0x00000102'i32
  97. WAIT_FAILED* = 0xFFFFFFFF'i32
  98. INFINITE* = -1'i32
  99. STD_INPUT_HANDLE* = -10'i32
  100. STD_OUTPUT_HANDLE* = -11'i32
  101. STD_ERROR_HANDLE* = -12'i32
  102. DETACHED_PROCESS* = 8'i32
  103. SW_SHOWNORMAL* = 1'i32
  104. INVALID_HANDLE_VALUE* = Handle(-1)
  105. CREATE_UNICODE_ENVIRONMENT* = 1024'i32
  106. PIPE_ACCESS_DUPLEX* = 0x00000003'i32
  107. PIPE_ACCESS_INBOUND* = 1'i32
  108. PIPE_ACCESS_OUTBOUND* = 2'i32
  109. PIPE_NOWAIT* = 0x00000001'i32
  110. SYNCHRONIZE* = 0x00100000'i32
  111. FILE_FLAG_WRITE_THROUGH* = 0x80000000'i32
  112. CREATE_NO_WINDOW* = 0x08000000'i32
  113. when useWinUnicode:
  114. proc getVersionExW*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExW".}
  115. else:
  116. proc getVersionExA*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExA".}
  117. proc getVersion*(): DWORD {.stdcall, dynlib: "kernel32", importc: "GetVersion".}
  118. proc closeHandle*(hObject: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
  119. importc: "CloseHandle".}
  120. proc readFile*(hFile: Handle, Buffer: pointer, nNumberOfBytesToRead: int32,
  121. lpNumberOfBytesRead: ptr int32, lpOverlapped: pointer): WINBOOL{.
  122. stdcall, dynlib: "kernel32", importc: "ReadFile".}
  123. proc writeFile*(hFile: Handle, Buffer: pointer, nNumberOfBytesToWrite: int32,
  124. lpNumberOfBytesWritten: ptr int32,
  125. lpOverlapped: pointer): WINBOOL{.
  126. stdcall, dynlib: "kernel32", importc: "WriteFile".}
  127. proc createPipe*(hReadPipe, hWritePipe: var Handle,
  128. lpPipeAttributes: var SECURITY_ATTRIBUTES,
  129. nSize: int32): WINBOOL{.
  130. stdcall, dynlib: "kernel32", importc: "CreatePipe".}
  131. proc createNamedPipe*(lpName: WideCString,
  132. dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize,
  133. nInBufferSize, nDefaultTimeOut: int32,
  134. lpSecurityAttributes: ptr SECURITY_ATTRIBUTES): Handle {.
  135. stdcall, dynlib: "kernel32", importc: "CreateNamedPipeW".}
  136. proc peekNamedPipe*(hNamedPipe: Handle, lpBuffer: pointer=nil,
  137. nBufferSize: int32 = 0,
  138. lpBytesRead: ptr int32 = nil,
  139. lpTotalBytesAvail: ptr int32 = nil,
  140. lpBytesLeftThisMessage: ptr int32 = nil): bool {.
  141. stdcall, dynlib: "kernel32", importc: "PeekNamedPipe".}
  142. when useWinUnicode:
  143. proc createProcessW*(lpApplicationName, lpCommandLine: WideCString,
  144. lpProcessAttributes: ptr SECURITY_ATTRIBUTES,
  145. lpThreadAttributes: ptr SECURITY_ATTRIBUTES,
  146. bInheritHandles: WINBOOL, dwCreationFlags: int32,
  147. lpEnvironment, lpCurrentDirectory: WideCString,
  148. lpStartupInfo: var STARTUPINFO,
  149. lpProcessInformation: var PROCESS_INFORMATION): WINBOOL{.
  150. stdcall, dynlib: "kernel32", importc: "CreateProcessW".}
  151. else:
  152. proc createProcessA*(lpApplicationName, lpCommandLine: cstring,
  153. lpProcessAttributes: ptr SECURITY_ATTRIBUTES,
  154. lpThreadAttributes: ptr SECURITY_ATTRIBUTES,
  155. bInheritHandles: WINBOOL, dwCreationFlags: int32,
  156. lpEnvironment: pointer, lpCurrentDirectory: cstring,
  157. lpStartupInfo: var STARTUPINFO,
  158. lpProcessInformation: var PROCESS_INFORMATION): WINBOOL{.
  159. stdcall, dynlib: "kernel32", importc: "CreateProcessA".}
  160. proc suspendThread*(hThread: Handle): int32 {.stdcall, dynlib: "kernel32",
  161. importc: "SuspendThread".}
  162. proc resumeThread*(hThread: Handle): int32 {.stdcall, dynlib: "kernel32",
  163. importc: "ResumeThread".}
  164. proc waitForSingleObject*(hHandle: Handle, dwMilliseconds: int32): int32 {.
  165. stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
  166. proc terminateProcess*(hProcess: Handle, uExitCode: int): WINBOOL {.stdcall,
  167. dynlib: "kernel32", importc: "TerminateProcess".}
  168. proc getExitCodeProcess*(hProcess: Handle, lpExitCode: var int32): WINBOOL {.
  169. stdcall, dynlib: "kernel32", importc: "GetExitCodeProcess".}
  170. proc getStdHandle*(nStdHandle: int32): Handle {.stdcall, dynlib: "kernel32",
  171. importc: "GetStdHandle".}
  172. proc setStdHandle*(nStdHandle: int32, hHandle: Handle): WINBOOL {.stdcall,
  173. dynlib: "kernel32", importc: "SetStdHandle".}
  174. proc flushFileBuffers*(hFile: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
  175. importc: "FlushFileBuffers".}
  176. proc getLastError*(): int32 {.importc: "GetLastError",
  177. stdcall, dynlib: "kernel32".}
  178. proc setLastError*(error: int32) {.importc: "SetLastError",
  179. stdcall, dynlib: "kernel32".}
  180. when useWinUnicode:
  181. proc formatMessageW*(dwFlags: int32, lpSource: pointer,
  182. dwMessageId, dwLanguageId: int32,
  183. lpBuffer: pointer, nSize: int32,
  184. Arguments: pointer): int32 {.
  185. importc: "FormatMessageW", stdcall, dynlib: "kernel32".}
  186. else:
  187. proc formatMessageA*(dwFlags: int32, lpSource: pointer,
  188. dwMessageId, dwLanguageId: int32,
  189. lpBuffer: pointer, nSize: int32,
  190. Arguments: pointer): int32 {.
  191. importc: "FormatMessageA", stdcall, dynlib: "kernel32".}
  192. proc localFree*(p: pointer) {.
  193. importc: "LocalFree", stdcall, dynlib: "kernel32".}
  194. when useWinUnicode:
  195. proc getCurrentDirectoryW*(nBufferLength: int32,
  196. lpBuffer: WideCString): int32 {.
  197. importc: "GetCurrentDirectoryW", dynlib: "kernel32", stdcall.}
  198. proc setCurrentDirectoryW*(lpPathName: WideCString): int32 {.
  199. importc: "SetCurrentDirectoryW", dynlib: "kernel32", stdcall.}
  200. proc createDirectoryW*(pathName: WideCString, security: pointer=nil): int32 {.
  201. importc: "CreateDirectoryW", dynlib: "kernel32", stdcall.}
  202. proc removeDirectoryW*(lpPathName: WideCString): int32 {.
  203. importc: "RemoveDirectoryW", dynlib: "kernel32", stdcall.}
  204. proc setEnvironmentVariableW*(lpName, lpValue: WideCString): int32 {.
  205. stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableW".}
  206. proc getModuleFileNameW*(handle: Handle, buf: WideCString,
  207. size: int32): int32 {.importc: "GetModuleFileNameW",
  208. dynlib: "kernel32", stdcall.}
  209. else:
  210. proc getCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {.
  211. importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.}
  212. proc setCurrentDirectoryA*(lpPathName: cstring): int32 {.
  213. importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.}
  214. proc createDirectoryA*(pathName: cstring, security: pointer=nil): int32 {.
  215. importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.}
  216. proc removeDirectoryA*(lpPathName: cstring): int32 {.
  217. importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.}
  218. proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {.
  219. stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".}
  220. proc getModuleFileNameA*(handle: Handle, buf: cstring, size: int32): int32 {.
  221. importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.}
  222. when useWinUnicode:
  223. proc createSymbolicLinkW*(lpSymlinkFileName, lpTargetFileName: WideCString,
  224. flags: DWORD): int32 {.
  225. importc:"CreateSymbolicLinkW", dynlib: "kernel32", stdcall.}
  226. proc createHardLinkW*(lpFileName, lpExistingFileName: WideCString,
  227. security: pointer=nil): int32 {.
  228. importc:"CreateHardLinkW", dynlib: "kernel32", stdcall.}
  229. else:
  230. proc createSymbolicLinkA*(lpSymlinkFileName, lpTargetFileName: cstring,
  231. flags: DWORD): int32 {.
  232. importc:"CreateSymbolicLinkA", dynlib: "kernel32", stdcall.}
  233. proc createHardLinkA*(lpFileName, lpExistingFileName: cstring,
  234. security: pointer=nil): int32 {.
  235. importc:"CreateHardLinkA", dynlib: "kernel32", stdcall.}
  236. const
  237. FILE_ATTRIBUTE_ARCHIVE* = 32'i32
  238. FILE_ATTRIBUTE_COMPRESSED* = 2048'i32
  239. FILE_ATTRIBUTE_NORMAL* = 128'i32
  240. FILE_ATTRIBUTE_DIRECTORY* = 16'i32
  241. FILE_ATTRIBUTE_HIDDEN* = 2'i32
  242. FILE_ATTRIBUTE_READONLY* = 1'i32
  243. FILE_ATTRIBUTE_REPARSE_POINT* = 1024'i32
  244. FILE_ATTRIBUTE_SYSTEM* = 4'i32
  245. FILE_ATTRIBUTE_TEMPORARY* = 256'i32
  246. MAX_PATH* = 260
  247. MOVEFILE_COPY_ALLOWED* = 0x2'i32
  248. MOVEFILE_CREATE_HARDLINK* = 0x10'i32
  249. MOVEFILE_DELAY_UNTIL_REBOOT* = 0x4'i32
  250. MOVEFILE_FAIL_IF_NOT_TRACKABLE* = 0x20'i32
  251. MOVEFILE_REPLACE_EXISTING* = 0x1'i32
  252. MOVEFILE_WRITE_THROUGH* = 0x8'i32
  253. type
  254. WIN32_FIND_DATA* {.pure.} = object
  255. dwFileAttributes*: int32
  256. ftCreationTime*: FILETIME
  257. ftLastAccessTime*: FILETIME
  258. ftLastWriteTime*: FILETIME
  259. nFileSizeHigh*: int32
  260. nFileSizeLow*: int32
  261. dwReserved0: int32
  262. dwReserved1: int32
  263. cFileName*: array[0..(MAX_PATH) - 1, WinChar]
  264. cAlternateFileName*: array[0..13, WinChar]
  265. {.deprecated: [TWIN32_FIND_DATA: WIN32_FIND_DATA].}
  266. when useWinUnicode:
  267. proc findFirstFileW*(lpFileName: WideCString,
  268. lpFindFileData: var WIN32_FIND_DATA): Handle {.
  269. stdcall, dynlib: "kernel32", importc: "FindFirstFileW".}
  270. proc findNextFileW*(hFindFile: Handle,
  271. lpFindFileData: var WIN32_FIND_DATA): int32 {.
  272. stdcall, dynlib: "kernel32", importc: "FindNextFileW".}
  273. else:
  274. proc findFirstFileA*(lpFileName: cstring,
  275. lpFindFileData: var WIN32_FIND_DATA): Handle {.
  276. stdcall, dynlib: "kernel32", importc: "FindFirstFileA".}
  277. proc findNextFileA*(hFindFile: Handle,
  278. lpFindFileData: var WIN32_FIND_DATA): int32 {.
  279. stdcall, dynlib: "kernel32", importc: "FindNextFileA".}
  280. proc findClose*(hFindFile: Handle) {.stdcall, dynlib: "kernel32",
  281. importc: "FindClose".}
  282. when useWinUnicode:
  283. proc getFullPathNameW*(lpFileName: WideCString, nBufferLength: int32,
  284. lpBuffer: WideCString,
  285. lpFilePart: var WideCString): int32 {.
  286. stdcall, dynlib: "kernel32",
  287. importc: "GetFullPathNameW".}
  288. proc getFileAttributesW*(lpFileName: WideCString): int32 {.
  289. stdcall, dynlib: "kernel32",
  290. importc: "GetFileAttributesW".}
  291. proc setFileAttributesW*(lpFileName: WideCString,
  292. dwFileAttributes: int32): WINBOOL {.
  293. stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".}
  294. proc copyFileW*(lpExistingFileName, lpNewFileName: WideCString,
  295. bFailIfExists: WINBOOL): WINBOOL {.
  296. importc: "CopyFileW", stdcall, dynlib: "kernel32".}
  297. proc moveFileW*(lpExistingFileName, lpNewFileName: WideCString): WINBOOL {.
  298. importc: "MoveFileW", stdcall, dynlib: "kernel32".}
  299. proc moveFileExW*(lpExistingFileName, lpNewFileName: WideCString,
  300. flags: DWORD): WINBOOL {.
  301. importc: "MoveFileExW", stdcall, dynlib: "kernel32".}
  302. proc getEnvironmentStringsW*(): WideCString {.
  303. stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".}
  304. proc freeEnvironmentStringsW*(para1: WideCString): int32 {.
  305. stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsW".}
  306. proc getCommandLineW*(): WideCString {.importc: "GetCommandLineW",
  307. stdcall, dynlib: "kernel32".}
  308. else:
  309. proc getFullPathNameA*(lpFileName: cstring, nBufferLength: int32,
  310. lpBuffer: cstring, lpFilePart: var cstring): int32 {.
  311. stdcall, dynlib: "kernel32",
  312. importc: "GetFullPathNameA".}
  313. proc getFileAttributesA*(lpFileName: cstring): int32 {.
  314. stdcall, dynlib: "kernel32",
  315. importc: "GetFileAttributesA".}
  316. proc setFileAttributesA*(lpFileName: cstring,
  317. dwFileAttributes: int32): WINBOOL {.
  318. stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".}
  319. proc copyFileA*(lpExistingFileName, lpNewFileName: cstring,
  320. bFailIfExists: cint): cint {.
  321. importc: "CopyFileA", stdcall, dynlib: "kernel32".}
  322. proc moveFileA*(lpExistingFileName, lpNewFileName: cstring): WINBOOL {.
  323. importc: "MoveFileA", stdcall, dynlib: "kernel32".}
  324. proc moveFileExA*(lpExistingFileName, lpNewFileName: WideCString,
  325. flags: DWORD): WINBOOL {.
  326. importc: "MoveFileExA", stdcall, dynlib: "kernel32".}
  327. proc getEnvironmentStringsA*(): cstring {.
  328. stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".}
  329. proc freeEnvironmentStringsA*(para1: cstring): int32 {.
  330. stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsA".}
  331. proc getCommandLineA*(): cstring {.
  332. importc: "GetCommandLineA", stdcall, dynlib: "kernel32".}
  333. proc rdFileTime*(f: FILETIME): int64 =
  334. result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
  335. proc rdFileSize*(f: WIN32_FIND_DATA): int64 =
  336. result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
  337. proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var FILETIME) {.
  338. importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.}
  339. proc sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32",
  340. importc: "Sleep".}
  341. when useWinUnicode:
  342. proc shellExecuteW*(HWND: Handle, lpOperation, lpFile,
  343. lpParameters, lpDirectory: WideCString,
  344. nShowCmd: int32): Handle{.
  345. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".}
  346. else:
  347. proc shellExecuteA*(HWND: Handle, lpOperation, lpFile,
  348. lpParameters, lpDirectory: cstring,
  349. nShowCmd: int32): Handle{.
  350. stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
  351. proc getFileInformationByHandle*(hFile: Handle,
  352. lpFileInformation: ptr BY_HANDLE_FILE_INFORMATION): WINBOOL{.
  353. stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".}
  354. const
  355. WSADESCRIPTION_LEN* = 256
  356. WSASYS_STATUS_LEN* = 128
  357. FD_SETSIZE* = 64
  358. MSG_PEEK* = 2
  359. INADDR_ANY* = 0'u32
  360. INADDR_LOOPBACK* = 0x7F000001
  361. INADDR_BROADCAST* = -1
  362. INADDR_NONE* = -1
  363. ws2dll = "Ws2_32.dll"
  364. proc wsaGetLastError*(): cint {.importc: "WSAGetLastError", dynlib: ws2dll.}
  365. type
  366. SocketHandle* = distinct int
  367. {.deprecated: [TSocketHandle: SocketHandle].}
  368. type
  369. WSAData* {.importc: "WSADATA", header: "winsock2.h".} = object
  370. wVersion, wHighVersion: int16
  371. szDescription: array[0..WSADESCRIPTION_LEN, char]
  372. szSystemStatus: array[0..WSASYS_STATUS_LEN, char]
  373. iMaxSockets, iMaxUdpDg: int16
  374. lpVendorInfo: cstring
  375. SockAddr* {.importc: "SOCKADDR", header: "winsock2.h".} = object
  376. sa_family*: int16 # unsigned
  377. sa_data*: array[0..13, char]
  378. PSockAddr = ptr SockAddr
  379. InAddr* {.importc: "IN_ADDR", header: "winsock2.h".} = object
  380. s_addr*: uint32 # IP address
  381. Sockaddr_in* {.importc: "SOCKADDR_IN",
  382. header: "winsock2.h".} = object
  383. sin_family*: int16
  384. sin_port*: uint16
  385. sin_addr*: InAddr
  386. sin_zero*: array[0..7, char]
  387. In6_addr* {.importc: "IN6_ADDR", header: "winsock2.h".} = object
  388. bytes* {.importc: "u.Byte".}: array[0..15, char]
  389. Sockaddr_in6* {.importc: "SOCKADDR_IN6",
  390. header: "ws2tcpip.h".} = object
  391. sin6_family*: int16
  392. sin6_port*: uint16
  393. sin6_flowinfo*: int32 # unsigned
  394. sin6_addr*: In6_addr
  395. sin6_scope_id*: int32 # unsigned
  396. Sockaddr_in6_old* = object
  397. sin6_family*: int16
  398. sin6_port*: int16 # unsigned
  399. sin6_flowinfo*: int32 # unsigned
  400. sin6_addr*: In6_addr
  401. Servent* = object
  402. s_name*: cstring
  403. s_aliases*: cstringArray
  404. when defined(cpu64):
  405. s_proto*: cstring
  406. s_port*: int16
  407. else:
  408. s_port*: int16
  409. s_proto*: cstring
  410. Hostent* = object
  411. h_name*: cstring
  412. h_aliases*: cstringArray
  413. h_addrtype*: int16
  414. h_length*: int16
  415. h_addr_list*: cstringArray
  416. TFdSet* = object
  417. fd_count*: cint # unsigned
  418. fd_array*: array[0..FD_SETSIZE-1, SocketHandle]
  419. Timeval* = object
  420. tv_sec*, tv_usec*: int32
  421. AddrInfo* = object
  422. ai_flags*: cint ## Input flags.
  423. ai_family*: cint ## Address family of socket.
  424. ai_socktype*: cint ## Socket type.
  425. ai_protocol*: cint ## Protocol of socket.
  426. ai_addrlen*: csize ## Length of socket address.
  427. ai_canonname*: cstring ## Canonical name of service location.
  428. ai_addr*: ptr SockAddr ## Socket address of socket.
  429. ai_next*: ptr AddrInfo ## Pointer to next in list.
  430. SockLen* = cuint
  431. {.deprecated: [TSockaddr_in: Sockaddr_in, TAddrinfo: AddrInfo,
  432. TSockAddr: SockAddr, TSockLen: SockLen, TTimeval: Timeval,
  433. TWSADATA: WSADATA, Thostent: Hostent, TServent: Servent,
  434. TInAddr: InAddr, Tin6_addr: In6_addr, Tsockaddr_in6: Sockaddr_in6,
  435. Tsockaddr_in6_old: Sockaddr_in6_old].}
  436. var
  437. SOMAXCONN* {.importc, header: "winsock2.h".}: cint
  438. INVALID_SOCKET* {.importc, header: "winsock2.h".}: SocketHandle
  439. SOL_SOCKET* {.importc, header: "winsock2.h".}: cint
  440. SO_DEBUG* {.importc, header: "winsock2.h".}: cint ## turn on debugging info recording
  441. SO_ACCEPTCONN* {.importc, header: "winsock2.h".}: cint # socket has had listen()
  442. SO_REUSEADDR* {.importc, header: "winsock2.h".}: cint # allow local address reuse
  443. SO_REUSEPORT* {.importc: "SO_REUSEADDR", header: "winsock2.h".}: cint # allow port reuse. Since Windows does not really support it, mapped to SO_REUSEADDR. This shouldn't cause problems.
  444. SO_KEEPALIVE* {.importc, header: "winsock2.h".}: cint # keep connections alive
  445. SO_DONTROUTE* {.importc, header: "winsock2.h".}: cint # just use interface addresses
  446. SO_BROADCAST* {.importc, header: "winsock2.h".}: cint # permit sending of broadcast msgs
  447. SO_USELOOPBACK* {.importc, header: "winsock2.h".}: cint # bypass hardware when possible
  448. SO_LINGER* {.importc, header: "winsock2.h".}: cint # linger on close if data present
  449. SO_OOBINLINE* {.importc, header: "winsock2.h".}: cint # leave received OOB data in line
  450. SO_DONTLINGER* {.importc, header: "winsock2.h".}: cint
  451. SO_EXCLUSIVEADDRUSE* {.importc, header: "winsock2.h".}: cint # disallow local address reuse
  452. SO_ERROR* {.importc, header: "winsock2.h".}: cint
  453. proc `==`*(x, y: SocketHandle): bool {.borrow.}
  454. proc getservbyname*(name, proto: cstring): ptr Servent {.
  455. stdcall, importc: "getservbyname", dynlib: ws2dll.}
  456. proc getservbyport*(port: cint, proto: cstring): ptr Servent {.
  457. stdcall, importc: "getservbyport", dynlib: ws2dll.}
  458. proc gethostbyaddr*(ip: ptr InAddr, len: cuint, theType: cint): ptr Hostent {.
  459. stdcall, importc: "gethostbyaddr", dynlib: ws2dll.}
  460. proc gethostbyname*(name: cstring): ptr Hostent {.
  461. stdcall, importc: "gethostbyname", dynlib: ws2dll.}
  462. proc gethostname*(hostname: cstring, len: cint): cint {.
  463. stdcall, importc: "gethostname", dynlib: ws2dll.}
  464. proc socket*(af, typ, protocol: cint): SocketHandle {.
  465. stdcall, importc: "socket", dynlib: ws2dll.}
  466. proc closesocket*(s: SocketHandle): cint {.
  467. stdcall, importc: "closesocket", dynlib: ws2dll.}
  468. proc accept*(s: SocketHandle, a: ptr SockAddr, addrlen: ptr SockLen): SocketHandle {.
  469. stdcall, importc: "accept", dynlib: ws2dll.}
  470. proc bindSocket*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
  471. stdcall, importc: "bind", dynlib: ws2dll.}
  472. proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
  473. stdcall, importc: "connect", dynlib: ws2dll.}
  474. proc getsockname*(s: SocketHandle, name: ptr SockAddr,
  475. namelen: ptr SockLen): cint {.
  476. stdcall, importc: "getsockname", dynlib: ws2dll.}
  477. proc getpeername*(s: SocketHandle, name: ptr SockAddr,
  478. namelen: ptr SockLen): cint {.
  479. stdcall, importc, dynlib: ws2dll.}
  480. proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
  481. optlen: ptr SockLen): cint {.
  482. stdcall, importc: "getsockopt", dynlib: ws2dll.}
  483. proc setsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
  484. optlen: SockLen): cint {.
  485. stdcall, importc: "setsockopt", dynlib: ws2dll.}
  486. proc listen*(s: SocketHandle, backlog: cint): cint {.
  487. stdcall, importc: "listen", dynlib: ws2dll.}
  488. proc recv*(s: SocketHandle, buf: pointer, len, flags: cint): cint {.
  489. stdcall, importc: "recv", dynlib: ws2dll.}
  490. proc recvfrom*(s: SocketHandle, buf: cstring, len, flags: cint,
  491. fromm: ptr SockAddr, fromlen: ptr SockLen): cint {.
  492. stdcall, importc: "recvfrom", dynlib: ws2dll.}
  493. proc select*(nfds: cint, readfds, writefds, exceptfds: ptr TFdSet,
  494. timeout: ptr Timeval): cint {.
  495. stdcall, importc: "select", dynlib: ws2dll.}
  496. proc send*(s: SocketHandle, buf: pointer, len, flags: cint): cint {.
  497. stdcall, importc: "send", dynlib: ws2dll.}
  498. proc sendto*(s: SocketHandle, buf: pointer, len, flags: cint,
  499. to: ptr SockAddr, tolen: SockLen): cint {.
  500. stdcall, importc: "sendto", dynlib: ws2dll.}
  501. proc shutdown*(s: SocketHandle, how: cint): cint {.
  502. stdcall, importc: "shutdown", dynlib: ws2dll.}
  503. proc getnameinfo*(a1: ptr SockAddr, a2: SockLen,
  504. a3: cstring, a4: SockLen, a5: cstring,
  505. a6: SockLen, a7: cint): cint {.
  506. stdcall, importc: "getnameinfo", dynlib: ws2dll.}
  507. proc inet_addr*(cp: cstring): uint32 {.
  508. stdcall, importc: "inet_addr", dynlib: ws2dll.}
  509. proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.
  510. stdcall, importc: "__WSAFDIsSet", dynlib: ws2dll, noSideEffect.}
  511. proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint =
  512. result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32
  513. proc FD_SET*(socket: SocketHandle, s: var TFdSet) =
  514. if s.fd_count < FD_SETSIZE:
  515. s.fd_array[int(s.fd_count)] = socket
  516. inc(s.fd_count)
  517. proc FD_ZERO*(s: var TFdSet) =
  518. s.fd_count = 0
  519. proc wsaStartup*(wVersionRequired: int16, WSData: ptr WSAData): cint {.
  520. stdcall, importc: "WSAStartup", dynlib: ws2dll.}
  521. proc getaddrinfo*(nodename, servname: cstring, hints: ptr AddrInfo,
  522. res: var ptr AddrInfo): cint {.
  523. stdcall, importc: "getaddrinfo", dynlib: ws2dll.}
  524. proc freeaddrinfo*(ai: ptr AddrInfo) {.
  525. stdcall, importc: "freeaddrinfo", dynlib: ws2dll.}
  526. proc inet_ntoa*(i: InAddr): cstring {.
  527. stdcall, importc, dynlib: ws2dll.}
  528. const
  529. MAXIMUM_WAIT_OBJECTS* = 0x00000040
  530. type
  531. WOHandleArray* = array[0..MAXIMUM_WAIT_OBJECTS - 1, Handle]
  532. PWOHandleArray* = ptr WOHandleArray
  533. {.deprecated: [TWOHandleArray: WOHandleArray].}
  534. proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray,
  535. bWaitAll: WINBOOL, dwMilliseconds: DWORD): DWORD{.
  536. stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".}
  537. # for memfiles.nim:
  538. const
  539. GENERIC_READ* = 0x80000000'i32
  540. GENERIC_WRITE* = 0x40000000'i32
  541. GENERIC_ALL* = 0x10000000'i32
  542. FILE_SHARE_READ* = 1'i32
  543. FILE_SHARE_DELETE* = 4'i32
  544. FILE_SHARE_WRITE* = 2'i32
  545. CREATE_ALWAYS* = 2'i32
  546. CREATE_NEW* = 1'i32
  547. OPEN_EXISTING* = 3'i32
  548. FILE_BEGIN* = 0'i32
  549. INVALID_SET_FILE_POINTER* = -1'i32
  550. NO_ERROR* = 0'i32
  551. PAGE_READONLY* = 2'i32
  552. PAGE_READWRITE* = 4'i32
  553. FILE_MAP_READ* = 4'i32
  554. FILE_MAP_WRITE* = 2'i32
  555. INVALID_FILE_SIZE* = -1'i32
  556. FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
  557. FILE_FLAG_OPEN_REPARSE_POINT* = 0x00200000'i32
  558. DUPLICATE_SAME_ACCESS* = 2
  559. FILE_READ_DATA* = 0x00000001 # file & pipe
  560. FILE_WRITE_DATA* = 0x00000002 # file & pipe
  561. # Error Constants
  562. const
  563. ERROR_FILE_NOT_FOUND* = 2
  564. ERROR_PATH_NOT_FOUND* = 3
  565. ERROR_ACCESS_DENIED* = 5
  566. ERROR_HANDLE_EOF* = 38
  567. ERROR_BAD_ARGUMENTS* = 165
  568. proc duplicateHandle*(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
  569. hTargetProcessHandle: HANDLE,
  570. lpTargetHandle: ptr HANDLE,
  571. dwDesiredAccess: DWORD, bInheritHandle: WINBOOL,
  572. dwOptions: DWORD): WINBOOL{.stdcall, dynlib: "kernel32",
  573. importc: "DuplicateHandle".}
  574. proc getCurrentProcess*(): HANDLE{.stdcall, dynlib: "kernel32",
  575. importc: "GetCurrentProcess".}
  576. when useWinUnicode:
  577. proc createFileW*(lpFileName: WideCString, dwDesiredAccess, dwShareMode: DWORD,
  578. lpSecurityAttributes: pointer,
  579. dwCreationDisposition, dwFlagsAndAttributes: DWORD,
  580. hTemplateFile: Handle): Handle {.
  581. stdcall, dynlib: "kernel32", importc: "CreateFileW".}
  582. proc deleteFileW*(pathName: WideCString): int32 {.
  583. importc: "DeleteFileW", dynlib: "kernel32", stdcall.}
  584. else:
  585. proc createFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
  586. lpSecurityAttributes: pointer,
  587. dwCreationDisposition, dwFlagsAndAttributes: DWORD,
  588. hTemplateFile: Handle): Handle {.
  589. stdcall, dynlib: "kernel32", importc: "CreateFileA".}
  590. proc deleteFileA*(pathName: cstring): int32 {.
  591. importc: "DeleteFileA", dynlib: "kernel32", stdcall.}
  592. proc setEndOfFile*(hFile: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
  593. importc: "SetEndOfFile".}
  594. proc setFilePointer*(hFile: Handle, lDistanceToMove: LONG,
  595. lpDistanceToMoveHigh: ptr LONG,
  596. dwMoveMethod: DWORD): DWORD {.
  597. stdcall, dynlib: "kernel32", importc: "SetFilePointer".}
  598. proc getFileSize*(hFile: Handle, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall,
  599. dynlib: "kernel32", importc: "GetFileSize".}
  600. proc mapViewOfFileEx*(hFileMappingObject: Handle, dwDesiredAccess: DWORD,
  601. dwFileOffsetHigh, dwFileOffsetLow: DWORD,
  602. dwNumberOfBytesToMap: DWORD,
  603. lpBaseAddress: pointer): pointer{.
  604. stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".}
  605. proc createFileMappingW*(hFile: Handle,
  606. lpFileMappingAttributes: pointer,
  607. flProtect, dwMaximumSizeHigh: DWORD,
  608. dwMaximumSizeLow: DWORD,
  609. lpName: pointer): Handle {.
  610. stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".}
  611. when not useWinUnicode:
  612. proc createFileMappingA*(hFile: Handle,
  613. lpFileMappingAttributes: pointer,
  614. flProtect, dwMaximumSizeHigh: DWORD,
  615. dwMaximumSizeLow: DWORD, lpName: cstring): Handle {.
  616. stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".}
  617. proc unmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall,
  618. dynlib: "kernel32", importc: "UnmapViewOfFile".}
  619. type
  620. OVERLAPPED* {.pure, inheritable.} = object
  621. internal*: PULONG
  622. internalHigh*: PULONG
  623. offset*: DWORD
  624. offsetHigh*: DWORD
  625. hEvent*: Handle
  626. POVERLAPPED* = ptr OVERLAPPED
  627. POVERLAPPED_COMPLETION_ROUTINE* = proc (para1: DWORD, para2: DWORD,
  628. para3: POVERLAPPED){.stdcall.}
  629. GUID* {.final, pure.} = object
  630. D1*: int32
  631. D2*: int16
  632. D3*: int16
  633. D4*: array[0..7, int8]
  634. {.deprecated: [TOVERLAPPED: OVERLAPPED, TGUID: GUID].}
  635. const
  636. ERROR_IO_PENDING* = 997 # a.k.a WSA_IO_PENDING
  637. FILE_FLAG_OVERLAPPED* = 1073741824
  638. WSAECONNABORTED* = 10053
  639. WSAEADDRINUSE* = 10048
  640. WSAECONNRESET* = 10054
  641. WSAEDISCON* = 10101
  642. WSAENETRESET* = 10052
  643. WSAETIMEDOUT* = 10060
  644. WSANOTINITIALISED* = 10093
  645. WSAENOTSOCK* = 10038
  646. WSAEINPROGRESS* = 10036
  647. WSAEINTR* = 10004
  648. WSAEWOULDBLOCK* = 10035
  649. ERROR_NETNAME_DELETED* = 64
  650. STATUS_PENDING* = 0x103
  651. proc createIoCompletionPort*(FileHandle: Handle, ExistingCompletionPort: Handle,
  652. CompletionKey: ULONG_PTR,
  653. NumberOfConcurrentThreads: DWORD): Handle{.stdcall,
  654. dynlib: "kernel32", importc: "CreateIoCompletionPort".}
  655. proc getQueuedCompletionStatus*(CompletionPort: Handle,
  656. lpNumberOfBytesTransferred: PDWORD, lpCompletionKey: PULONG_PTR,
  657. lpOverlapped: ptr POVERLAPPED,
  658. dwMilliseconds: DWORD): WINBOOL{.stdcall,
  659. dynlib: "kernel32", importc: "GetQueuedCompletionStatus".}
  660. proc getOverlappedResult*(hFile: Handle, lpOverlapped: POVERLAPPED,
  661. lpNumberOfBytesTransferred: var DWORD, bWait: WINBOOL): WINBOOL{.
  662. stdcall, dynlib: "kernel32", importc: "GetOverlappedResult".}
  663. # this is copy of HasOverlappedIoCompleted() macro from <winbase.h>
  664. # because we have declared own OVERLAPPED structure with member names not
  665. # compatible with original names.
  666. template hasOverlappedIoCompleted*(lpOverlapped): bool =
  667. (cast[uint](lpOverlapped.internal) != STATUS_PENDING)
  668. const
  669. IOC_OUT* = 0x40000000
  670. IOC_IN* = 0x80000000
  671. IOC_WS2* = 0x08000000
  672. IOC_INOUT* = IOC_IN or IOC_OUT
  673. template WSAIORW*(x,y): untyped = (IOC_INOUT or x or y)
  674. const
  675. SIO_GET_EXTENSION_FUNCTION_POINTER* = WSAIORW(IOC_WS2,6).DWORD
  676. SO_UPDATE_ACCEPT_CONTEXT* = 0x700B
  677. AI_V4MAPPED* = 0x0008
  678. AF_UNSPEC* = 0
  679. AF_INET* = 2
  680. AF_INET6* = 23
  681. var
  682. WSAID_CONNECTEX*: GUID = GUID(D1: 0x25a207b9, D2: 0xddf3'i16, D3: 0x4660, D4: [
  683. 0x8e'i8, 0xe9'i8, 0x76'i8, 0xe5'i8, 0x8c'i8, 0x74'i8, 0x06'i8, 0x3e'i8])
  684. WSAID_ACCEPTEX*: GUID = GUID(D1: 0xb5367df1'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [
  685. 0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8])
  686. WSAID_GETACCEPTEXSOCKADDRS*: GUID = GUID(D1: 0xb5367df2'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [
  687. 0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8])
  688. proc WSAIoctl*(s: SocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer,
  689. cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD,
  690. lpcbBytesReturned: PDWORD, lpOverlapped: POVERLAPPED,
  691. lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint
  692. {.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".}
  693. type
  694. TWSABuf* {.importc: "WSABUF", header: "winsock2.h".} = object
  695. len*: ULONG
  696. buf*: cstring
  697. proc WSARecv*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
  698. bytesReceived, flags: PDWORD, lpOverlapped: POVERLAPPED,
  699. completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
  700. stdcall, importc: "WSARecv", dynlib: "Ws2_32.dll".}
  701. proc WSARecvFrom*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
  702. bytesReceived: PDWORD, flags: PDWORD, name: ptr SockAddr,
  703. namelen: ptr cint, lpOverlapped: POVERLAPPED,
  704. completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
  705. stdcall, importc: "WSARecvFrom", dynlib: "Ws2_32.dll".}
  706. proc WSASend*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
  707. bytesSent: PDWORD, flags: DWORD, lpOverlapped: POVERLAPPED,
  708. completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
  709. stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".}
  710. proc WSASendTo*(s: SocketHandle, buf: ptr TWSABuf, bufCount: DWORD,
  711. bytesSent: PDWORD, flags: DWORD, name: ptr SockAddr,
  712. namelen: cint, lpOverlapped: POVERLAPPED,
  713. completionProc: POVERLAPPED_COMPLETION_ROUTINE): cint {.
  714. stdcall, importc: "WSASendTo", dynlib: "Ws2_32.dll".}
  715. proc get_osfhandle*(fd:FileHandle): Handle {.
  716. importc: "_get_osfhandle", header:"<io.h>".}
  717. proc getSystemTimes*(lpIdleTime, lpKernelTime,
  718. lpUserTime: var FILETIME): WINBOOL {.stdcall,
  719. dynlib: "kernel32", importc: "GetSystemTimes".}
  720. proc getProcessTimes*(hProcess: Handle; lpCreationTime, lpExitTime,
  721. lpKernelTime, lpUserTime: var FILETIME): WINBOOL {.stdcall,
  722. dynlib: "kernel32", importc: "GetProcessTimes".}
  723. type inet_ntop_proc = proc(family: cint, paddr: pointer, pStringBuffer: cstring,
  724. stringBufSize: int32): cstring {.gcsafe, stdcall.}
  725. var inet_ntop_real: inet_ntop_proc = nil
  726. let ws2 = loadLib(ws2dll)
  727. if ws2 != nil:
  728. inet_ntop_real = cast[inet_ntop_proc](symAddr(ws2, "inet_ntop"))
  729. proc WSAAddressToStringA(pAddr: ptr SockAddr, addrSize: DWORD, unused: pointer, pBuff: cstring, pBuffSize: ptr DWORD): cint {.stdcall, importc, dynlib: ws2dll.}
  730. proc inet_ntop_emulated(family: cint, paddr: pointer, pStringBuffer: cstring,
  731. stringBufSize: int32): cstring {.stdcall.} =
  732. case family
  733. of AF_INET:
  734. var sa: Sockaddr_in
  735. sa.sin_family = AF_INET
  736. sa.sin_addr = cast[ptr InAddr](paddr)[]
  737. var bs = stringBufSize.DWORD
  738. let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
  739. if r != 0:
  740. result = nil
  741. else:
  742. result = pStringBuffer
  743. of AF_INET6:
  744. var sa: Sockaddr_in6
  745. sa.sin6_family = AF_INET6
  746. sa.sin6_addr = cast[ptr In6_addr](paddr)[]
  747. var bs = stringBufSize.DWORD
  748. let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
  749. if r != 0:
  750. result = nil
  751. else:
  752. result = pStringBuffer
  753. else:
  754. setLastError(ERROR_BAD_ARGUMENTS)
  755. result = nil
  756. proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
  757. stringBufSize: int32): cstring {.stdcall.} =
  758. var ver: OSVERSIONINFO
  759. ver.dwOSVersionInfoSize = sizeof(ver).DWORD
  760. let res = when useWinUnicode: getVersionExW(ver.addr) else: getVersionExA(ver.addr)
  761. if res == 0:
  762. result = nil
  763. elif ver.dwMajorVersion >= 6:
  764. if inet_ntop_real == nil:
  765. quit("Can't load inet_ntop proc from " & ws2dll)
  766. result = inet_ntop_real(family, paddr, pStringBuffer, stringBufSize)
  767. else:
  768. result = inet_ntop_emulated(family, paddr, pStringBuffer, stringBufSize)
  769. type
  770. WSAPROC_ACCEPTEX* = proc (sListenSocket: SocketHandle,
  771. sAcceptSocket: SocketHandle,
  772. lpOutputBuffer: pointer, dwReceiveDataLength: DWORD,
  773. dwLocalAddressLength: DWORD,
  774. dwRemoteAddressLength: DWORD,
  775. lpdwBytesReceived: ptr DWORD,
  776. lpOverlapped: POVERLAPPED): bool {.
  777. stdcall,gcsafe.}
  778. WSAPROC_CONNECTEX* = proc (s: SocketHandle, name: ptr SockAddr, namelen: cint,
  779. lpSendBuffer: pointer, dwSendDataLength: DWORD,
  780. lpdwBytesSent: ptr DWORD,
  781. lpOverlapped: POVERLAPPED): bool {.
  782. stdcall,gcsafe.}
  783. WSAPROC_GETACCEPTEXSOCKADDRS* = proc(lpOutputBuffer: pointer,
  784. dwReceiveDataLength: DWORD,
  785. dwLocalAddressLength: DWORD,
  786. dwRemoteAddressLength: DWORD,
  787. LocalSockaddr: ptr PSockAddr,
  788. LocalSockaddrLength: ptr cint,
  789. RemoteSockaddr: ptr PSockAddr,
  790. RemoteSockaddrLength: ptr cint) {.
  791. stdcall,gcsafe.}
  792. const
  793. WT_EXECUTEDEFAULT* = 0x00000000'i32
  794. WT_EXECUTEINIOTHREAD* = 0x00000001'i32
  795. WT_EXECUTEINUITHREAD* = 0x00000002'i32
  796. WT_EXECUTEINWAITTHREAD* = 0x00000004'i32
  797. WT_EXECUTEONLYONCE* = 0x00000008'i32
  798. WT_EXECUTELONGFUNCTION* = 0x00000010'i32
  799. WT_EXECUTEINTIMERTHREAD* = 0x00000020'i32
  800. WT_EXECUTEINPERSISTENTIOTHREAD* = 0x00000040'i32
  801. WT_EXECUTEINPERSISTENTTHREAD* = 0x00000080'i32
  802. WT_TRANSFER_IMPERSONATION* = 0x00000100'i32
  803. PROCESS_TERMINATE* = 0x00000001'i32
  804. PROCESS_CREATE_THREAD* = 0x00000002'i32
  805. PROCESS_SET_SESSIONID* = 0x00000004'i32
  806. PROCESS_VM_OPERATION* = 0x00000008'i32
  807. PROCESS_VM_READ* = 0x00000010'i32
  808. PROCESS_VM_WRITE* = 0x00000020'i32
  809. PROCESS_DUP_HANDLE* = 0x00000040'i32
  810. PROCESS_CREATE_PROCESS* = 0x00000080'i32
  811. PROCESS_SET_QUOTA* = 0x00000100'i32
  812. PROCESS_SET_INFORMATION* = 0x00000200'i32
  813. PROCESS_QUERY_INFORMATION* = 0x00000400'i32
  814. PROCESS_SUSPEND_RESUME* = 0x00000800'i32
  815. PROCESS_QUERY_LIMITED_INFORMATION* = 0x00001000'i32
  816. PROCESS_SET_LIMITED_INFORMATION* = 0x00002000'i32
  817. type
  818. WAITORTIMERCALLBACK* = proc(para1: pointer, para2: int32): void {.stdcall.}
  819. proc postQueuedCompletionStatus*(CompletionPort: HANDLE,
  820. dwNumberOfBytesTransferred: DWORD,
  821. dwCompletionKey: ULONG_PTR,
  822. lpOverlapped: pointer): bool
  823. {.stdcall, dynlib: "kernel32", importc: "PostQueuedCompletionStatus".}
  824. proc registerWaitForSingleObject*(phNewWaitObject: ptr Handle, hObject: Handle,
  825. Callback: WAITORTIMERCALLBACK,
  826. Context: pointer,
  827. dwMilliseconds: ULONG,
  828. dwFlags: ULONG): bool
  829. {.stdcall, dynlib: "kernel32", importc: "RegisterWaitForSingleObject".}
  830. proc unregisterWait*(WaitHandle: HANDLE): DWORD
  831. {.stdcall, dynlib: "kernel32", importc: "UnregisterWait".}
  832. proc openProcess*(dwDesiredAccess: DWORD, bInheritHandle: WINBOOL,
  833. dwProcessId: DWORD): Handle
  834. {.stdcall, dynlib: "kernel32", importc: "OpenProcess".}
  835. when defined(useWinAnsi):
  836. proc createEvent*(lpEventAttributes: ptr SECURITY_ATTRIBUTES,
  837. bManualReset: DWORD, bInitialState: DWORD,
  838. lpName: cstring): Handle
  839. {.stdcall, dynlib: "kernel32", importc: "CreateEventA".}
  840. else:
  841. proc createEvent*(lpEventAttributes: ptr SECURITY_ATTRIBUTES,
  842. bManualReset: DWORD, bInitialState: DWORD,
  843. lpName: ptr Utf16Char): Handle
  844. {.stdcall, dynlib: "kernel32", importc: "CreateEventW".}
  845. proc setEvent*(hEvent: Handle): cint
  846. {.stdcall, dynlib: "kernel32", importc: "SetEvent".}
  847. const
  848. FD_READ* = 0x00000001'i32
  849. FD_WRITE* = 0x00000002'i32
  850. FD_OOB* = 0x00000004'i32
  851. FD_ACCEPT* = 0x00000008'i32
  852. FD_CONNECT* = 0x00000010'i32
  853. FD_CLOSE* = 0x00000020'i32
  854. FD_QQS* = 0x00000040'i32
  855. FD_GROUP_QQS* = 0x00000080'i32
  856. FD_ROUTING_INTERFACE_CHANGE* = 0x00000100'i32
  857. FD_ADDRESS_LIST_CHANGE* = 0x00000200'i32
  858. FD_ALL_EVENTS* = 0x000003FF'i32
  859. proc wsaEventSelect*(s: SocketHandle, hEventObject: Handle,
  860. lNetworkEvents: clong): cint
  861. {.stdcall, importc: "WSAEventSelect", dynlib: "ws2_32.dll".}
  862. proc wsaCreateEvent*(): Handle
  863. {.stdcall, importc: "WSACreateEvent", dynlib: "ws2_32.dll".}
  864. proc wsaCloseEvent*(hEvent: Handle): bool
  865. {.stdcall, importc: "WSACloseEvent", dynlib: "ws2_32.dll".}
  866. proc wsaResetEvent*(hEvent: Handle): bool
  867. {.stdcall, importc: "WSAResetEvent", dynlib: "ws2_32.dll".}
  868. type
  869. KEY_EVENT_RECORD* {.final, pure.} = object
  870. eventType*: int16
  871. bKeyDown*: WINBOOL
  872. wRepeatCount*: int16
  873. wVirtualKeyCode*: int16
  874. wVirtualScanCode*: int16
  875. uChar*: int16
  876. dwControlKeyState*: DWORD
  877. when defined(useWinAnsi):
  878. proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint,
  879. lpNumberOfEventsRead: ptr cint): cint
  880. {.stdcall, dynlib: "kernel32", importc: "ReadConsoleInputA".}
  881. else:
  882. proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint,
  883. lpNumberOfEventsRead: ptr cint): cint
  884. {.stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".}
  885. type
  886. LPFIBER_START_ROUTINE* = proc (param: pointer): void {.stdcall.}
  887. const
  888. FIBER_FLAG_FLOAT_SWITCH* = 0x01
  889. proc CreateFiber*(stackSize: int, fn: LPFIBER_START_ROUTINE, param: pointer): pointer {.stdcall, discardable, dynlib: "kernel32", importc.}
  890. proc CreateFiberEx*(stkCommit: int, stkReserve: int, flags: int32, fn: LPFIBER_START_ROUTINE, param: pointer): pointer {.stdcall, discardable, dynlib: "kernel32", importc.}
  891. proc ConvertThreadToFiber*(param: pointer): pointer {.stdcall, discardable, dynlib: "kernel32", importc.}
  892. proc ConvertThreadToFiberEx*(param: pointer, flags: int32): pointer {.stdcall, discardable, dynlib: "kernel32", importc.}
  893. proc DeleteFiber*(fiber: pointer): void {.stdcall, discardable, dynlib: "kernel32", importc.}
  894. proc SwitchToFiber*(fiber: pointer): void {.stdcall, discardable, dynlib: "kernel32", importc.}
  895. proc GetCurrentFiber*(): pointer {.stdcall, importc, header: "Windows.h".}