winlean.nim 43 KB

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