summary refs log tree commit diff stats
path: root/lib/windows
diff options
context:
space:
mode:
authorRoman Inflianskas <rominf@users.noreply.github.com>2021-03-07 23:40:16 +0200
committerGitHub <noreply@github.com>2021-03-07 22:40:16 +0100
commit31424b380827b4da0bc08d1cb213dbad4288e30f (patch)
tree0e67d4e52fe122b56385b70b735e3c7e89278b59 /lib/windows
parentd1e093207acdd10ad375705bd1732fc6f0db9f55 (diff)
downloadNim-31424b380827b4da0bc08d1cb213dbad4288e30f.tar.gz
stdlib/os: add isAdmin (#17012)
* stdlib/os: add isAdmin

* uint8 -> cuchar, assert isAdmin on Azure

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

* Update lib/pure/os.nim docs

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

* Address comments on #17012

* Raise on errors in #17012

* Check the result of FreeSid in #17012

* Change case in #17012

* Fix memory leak in #17012

* Address comments in #17012

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>

Co-authored-by: Timothee Cour <timothee.cour2@gmail.com>
Diffstat (limited to 'lib/windows')
-rw-r--r--lib/windows/winlean.nim44
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim
index 92055adbf..1cdb20fe7 100644
--- a/lib/windows/winlean.nim
+++ b/lib/windows/winlean.nim
@@ -25,6 +25,7 @@ when useWinUnicode:
 else:
   type WinChar* = char
 
+# See https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
 type
   Handle* = int
   LONG* = int32
@@ -33,6 +34,7 @@ type
   WINBOOL* = int32
     ## `WINBOOL` uses opposite convention as posix, !=0 meaning success.
     # xxx this should be distinct int32, distinct would make code less error prone
+  PBOOL* = ptr WINBOOL
   DWORD* = int32
   PDWORD* = ptr DWORD
   LPINT* = ptr int32
@@ -40,6 +42,7 @@ type
   PULONG_PTR* = ptr uint
   HDC* = Handle
   HGLRC* = Handle
+  BYTE* = cuchar
 
   SECURITY_ATTRIBUTES* {.final, pure.} = object
     nLength*: int32
@@ -136,6 +139,10 @@ const
 
   HANDLE_FLAG_INHERIT* = 0x00000001'i32
 
+proc isSuccess*(a: WINBOOL): bool {.inline.} =
+  ## Returns true if `a != 0`. Windows uses a different convention than POSIX,
+  ## where `a == 0` is commonly used on success.
+  a != 0
 proc getVersionExW*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.
     stdcall, dynlib: "kernel32", importc: "GetVersionExW", sideEffect.}
 proc getVersionExA*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.
@@ -1129,5 +1136,42 @@ proc setFileTime*(hFile: Handle, lpCreationTime: LPFILETIME,
                  lpLastAccessTime: LPFILETIME, lpLastWriteTime: LPFILETIME): WINBOOL
      {.stdcall, dynlib: "kernel32", importc: "SetFileTime".}
 
+type
+  # https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid_identifier_authority
+  SID_IDENTIFIER_AUTHORITY* {.importc, header: "<windows.h>".} = object
+    value* {.importc: "Value"}: array[6, BYTE]
+  # https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-sid
+  SID* {.importc, header: "<windows.h>".} = object
+    Revision: BYTE
+    SubAuthorityCount: BYTE
+    IdentifierAuthority: SID_IDENTIFIER_AUTHORITY
+    SubAuthority: ptr ptr DWORD
+  PSID* = ptr SID
+
+const
+  # https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-components
+  # https://github.com/mirror/mingw-w64/blob/84c950bdab7c999ace49fe8383856be77f88c4a8/mingw-w64-headers/include/winnt.h#L2994
+  SECURITY_NT_AUTHORITY* = [BYTE(0), BYTE(0), BYTE(0), BYTE(0), BYTE(0), BYTE(5)]
+  SECURITY_BUILTIN_DOMAIN_RID* = 32
+  DOMAIN_ALIAS_RID_ADMINS* = 544
+
+proc allocateAndInitializeSid*(pIdentifierAuthority: ptr SID_IDENTIFIER_AUTHORITY,
+                               nSubAuthorityCount: BYTE,
+                               nSubAuthority0: DWORD,
+                               nSubAuthority1: DWORD,
+                               nSubAuthority2: DWORD,
+                               nSubAuthority3: DWORD,
+                               nSubAuthority4: DWORD,
+                               nSubAuthority5: DWORD,
+                               nSubAuthority6: DWORD,
+                               nSubAuthority7: DWORD,
+                               pSid: ptr PSID): WINBOOL
+     {.stdcall, dynlib: "Advapi32", importc: "AllocateAndInitializeSid".}
+proc checkTokenMembership*(tokenHandle: Handle, sidToCheck: PSID,
+                           isMember: PBOOL): WINBOOL
+     {.stdcall, dynlib: "Advapi32", importc: "CheckTokenMembership".}
+proc freeSid*(pSid: PSID): PSID
+     {.stdcall, dynlib: "Advapi32", importc: "FreeSid".}
+
 when defined(nimHasStyleChecks):
   {.pop.} # {.push styleChecks: off.}