facter 2.4.6-x64-mingw32 → 2.5.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,41 @@
1
+ require 'facter/util/windows'
2
+ require 'ffi'
3
+
4
+ module Facter::Util::Windows::Dir
5
+ extend FFI::Library
6
+
7
+ COMMON_APPDATA = 0x0023
8
+ S_OK = 0x0
9
+ MAX_PATH = 260;
10
+
11
+ def get_common_appdata
12
+ common_appdata = ''
13
+
14
+ # this pointer actually points to a :lpwstr (pointer) since we're letting Windows allocate for us
15
+ FFI::MemoryPointer.new(:pointer, ((MAX_PATH + 1) * 2)) do |buffer_ptr|
16
+ # hwndOwner, nFolder, hToken, dwFlags, pszPath
17
+ if SHGetFolderPathW(0, COMMON_APPDATA, 0, 0, buffer_ptr) != S_OK
18
+ raise Facter::Util::Windows::Error.new("Could not find COMMON_APPDATA path")
19
+ end
20
+
21
+ common_appdata = buffer_ptr.read_arbitrary_wide_string_up_to(MAX_PATH + 1)
22
+ end
23
+
24
+ common_appdata
25
+ end
26
+ module_function :get_common_appdata
27
+
28
+ ffi_convention :stdcall
29
+
30
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/bb762181(v=vs.85).aspx
31
+ # HRESULT SHGetFolderPath(
32
+ # _In_ HWND hwndOwner,
33
+ # _In_ int nFolder,
34
+ # _In_ HANDLE hToken,
35
+ # _In_ DWORD dwFlags,
36
+ # _Out_ LPTSTR pszPath
37
+ # );
38
+ ffi_lib :shell32
39
+ attach_function_private :SHGetFolderPathW,
40
+ [:handle, :int32, :handle, :dword, :lpwstr], :hresult
41
+ end
@@ -0,0 +1,85 @@
1
+ require 'facter/util/windows'
2
+
3
+ # represents an error resulting from a Win32 error code
4
+ class Facter::Util::Windows::Error < RuntimeError
5
+ require 'ffi'
6
+ extend FFI::Library
7
+
8
+ attr_reader :code
9
+ attr_reader :original
10
+
11
+ # NOTE: FFI.errno only works properly when prior Win32 calls have been made
12
+ # through FFI bindings. Calls made through Win32API do not have their error
13
+ # codes captured by FFI.errno
14
+ def initialize(message, code = FFI.errno, original = nil)
15
+ @original = original
16
+ super(message + ": #{self.class.format_error_code(code)}")
17
+
18
+ @code = code
19
+ end
20
+
21
+ # Helper method that wraps FormatMessage that returns a human readable string.
22
+ def self.format_error_code(code)
23
+ # specifying 0 will look for LANGID in the following order
24
+ # 1.Language neutral
25
+ # 2.Thread LANGID, based on the thread's locale value
26
+ # 3.User default LANGID, based on the user's default locale value
27
+ # 4.System default LANGID, based on the system default locale value
28
+ # 5.US English
29
+ dwLanguageId = 0
30
+ flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
31
+ FORMAT_MESSAGE_FROM_SYSTEM |
32
+ FORMAT_MESSAGE_ARGUMENT_ARRAY |
33
+ FORMAT_MESSAGE_IGNORE_INSERTS |
34
+ FORMAT_MESSAGE_MAX_WIDTH_MASK
35
+ error_string = ''
36
+
37
+ # this pointer actually points to a :lpwstr (pointer) since we're letting Windows allocate for us
38
+ FFI::MemoryPointer.new(:pointer, 1) do |buffer_ptr|
39
+ length = FormatMessageW(flags, FFI::Pointer::NULL, code, dwLanguageId,
40
+ buffer_ptr, 0, FFI::Pointer::NULL)
41
+
42
+ if length == FFI::WIN32_FALSE
43
+ # can't raise same error type here or potentially recurse infinitely
44
+ raise Facter::Error.new("FormatMessageW could not format code #{code}")
45
+ end
46
+
47
+ # returns an FFI::Pointer with autorelease set to false, which is what we want
48
+ buffer_ptr.read_win32_local_pointer do |wide_string_ptr|
49
+ if wide_string_ptr.null?
50
+ raise Facter::Error.new("FormatMessageW failed to allocate buffer for code #{code}")
51
+ end
52
+
53
+ error_string = wide_string_ptr.read_wide_string(length)
54
+ end
55
+ end
56
+
57
+ error_string
58
+ end
59
+
60
+ ERROR_FILE_NOT_FOUND = 2
61
+ ERROR_ACCESS_DENIED = 5
62
+
63
+ FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100
64
+ FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
65
+ FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
66
+ FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
67
+ FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF
68
+
69
+ ffi_convention :stdcall
70
+
71
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms679351(v=vs.85).aspx
72
+ # DWORD WINAPI FormatMessage(
73
+ # _In_ DWORD dwFlags,
74
+ # _In_opt_ LPCVOID lpSource,
75
+ # _In_ DWORD dwMessageId,
76
+ # _In_ DWORD dwLanguageId,
77
+ # _Out_ LPTSTR lpBuffer,
78
+ # _In_ DWORD nSize,
79
+ # _In_opt_ va_list *Arguments
80
+ # );
81
+ # NOTE: since we're not preallocating the buffer, use a :pointer for lpBuffer
82
+ ffi_lib :kernel32
83
+ attach_function_private :FormatMessageW,
84
+ [:dword, :lpcvoid, :dword, :dword, :pointer, :dword, :pointer], :dword
85
+ end
@@ -0,0 +1,285 @@
1
+ require 'facter/util/windows'
2
+ require 'ffi'
3
+
4
+ module Facter::Util::Windows::Process
5
+ extend FFI::Library
6
+
7
+ def get_current_process
8
+ # this pseudo-handle does not require closing per MSDN docs
9
+ GetCurrentProcess()
10
+ end
11
+ module_function :get_current_process
12
+
13
+ def open_process_token(handle, desired_access, &block)
14
+ token_handle = nil
15
+ begin
16
+ FFI::MemoryPointer.new(:handle, 1) do |token_handle_ptr|
17
+ result = OpenProcessToken(handle, desired_access, token_handle_ptr)
18
+ if result == FFI::WIN32_FALSE
19
+ raise Facter::Util::Windows::Error.new(
20
+ "OpenProcessToken(#{handle}, #{desired_access.to_s(8)}, #{token_handle_ptr})")
21
+ end
22
+
23
+ yield token_handle = token_handle_ptr.read_handle
24
+ end
25
+
26
+ token_handle
27
+ ensure
28
+ FFI::WIN32.CloseHandle(token_handle) if token_handle
29
+ end
30
+
31
+ # token_handle has had CloseHandle called against it, so nothing to return
32
+ nil
33
+ end
34
+ module_function :open_process_token
35
+
36
+ def get_token_information(token_handle, token_information, &block)
37
+ # to determine buffer size
38
+ FFI::MemoryPointer.new(:dword, 1) do |return_length_ptr|
39
+ result = GetTokenInformation(token_handle, token_information, nil, 0, return_length_ptr)
40
+ return_length = return_length_ptr.read_dword
41
+
42
+ if return_length <= 0
43
+ raise Facter::Util::Windows::Error.new(
44
+ "GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})")
45
+ end
46
+
47
+ # re-call API with properly sized buffer for all results
48
+ FFI::MemoryPointer.new(return_length) do |token_information_buf|
49
+ result = GetTokenInformation(token_handle, token_information,
50
+ token_information_buf, return_length, return_length_ptr)
51
+
52
+ if result == FFI::WIN32_FALSE
53
+ raise Facter::Util::Windows::Error.new(
54
+ "GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " +
55
+ "#{return_length}, #{return_length_ptr})")
56
+ end
57
+
58
+ yield token_information_buf
59
+ end
60
+ end
61
+
62
+ # GetTokenInformation buffer has been cleaned up by this point, nothing to return
63
+ nil
64
+ end
65
+ module_function :get_token_information
66
+
67
+ def parse_token_information_as_token_elevation(token_information_buf)
68
+ TOKEN_ELEVATION.new(token_information_buf)
69
+ end
70
+ module_function :parse_token_information_as_token_elevation
71
+
72
+ TOKEN_QUERY = 0x0008
73
+ # Returns whether or not the owner of the current process is running
74
+ # with elevated security privileges.
75
+ #
76
+ # Only supported on Windows Vista or later.
77
+ #
78
+ def elevated_security?
79
+ # default / pre-Vista
80
+ elevated = false
81
+ handle = nil
82
+
83
+ begin
84
+ handle = get_current_process
85
+ open_process_token(handle, TOKEN_QUERY) do |token_handle|
86
+ get_token_information(token_handle, :TokenElevation) do |token_info|
87
+ token_elevation = parse_token_information_as_token_elevation(token_info)
88
+ # TokenIsElevated member of the TOKEN_ELEVATION struct
89
+ elevated = token_elevation[:TokenIsElevated] != 0
90
+ end
91
+ end
92
+
93
+ elevated
94
+ rescue Facter::Util::Windows::Error => e
95
+ raise e if e.code != ERROR_NO_SUCH_PRIVILEGE
96
+ ensure
97
+ FFI::WIN32.CloseHandle(handle) if handle
98
+ end
99
+ end
100
+ module_function :elevated_security?
101
+
102
+ STATUS_SUCCESS = 0
103
+
104
+ def os_version(&block)
105
+ FFI::MemoryPointer.new(OSVERSIONINFOEX.size) do |ver_ptr|
106
+ ver = OSVERSIONINFOEX.new(ver_ptr)
107
+ ver[:dwOSVersionInfoSize] = OSVERSIONINFOEX.size
108
+
109
+ result = RtlGetVersion(ver_ptr)
110
+
111
+ if result != STATUS_SUCCESS
112
+ raise RuntimeError, 'Calling Windows RtlGetVersion failed'
113
+ end
114
+
115
+ yield ver
116
+ end
117
+
118
+ # ver_ptr has already had free called, so nothing to return
119
+ nil
120
+ end
121
+ module_function :os_version
122
+
123
+ def windows_major_version
124
+ ver = 0
125
+
126
+ self.os_version do |version|
127
+ ver = version[:dwMajorVersion]
128
+ end
129
+
130
+ ver
131
+ end
132
+ module_function :windows_major_version
133
+
134
+ def os_version_string
135
+ ver = ''
136
+ self.os_version do |version|
137
+ ver = "#{version[:dwMajorVersion]}.#{version[:dwMinorVersion]}.#{version[:dwBuildNumber]}"
138
+ end
139
+
140
+ ver
141
+ end
142
+ module_function :os_version_string
143
+
144
+
145
+ SM_SERVERR2 = 89
146
+
147
+ def is_2003_r2?
148
+ # Peculiar API from user32 - the docs for SM_SERVER2 indicate
149
+ # The build number if the system is Windows Server 2003 R2; otherwise, 0.
150
+ GetSystemMetrics(SM_SERVERR2) != 0
151
+ end
152
+ module_function :is_2003_r2?
153
+
154
+ def supports_elevated_security?
155
+ windows_major_version >= 6
156
+ end
157
+ module_function :supports_elevated_security?
158
+
159
+ ffi_convention :stdcall
160
+
161
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ms683179(v=vs.85).aspx
162
+ # HANDLE WINAPI GetCurrentProcess(void);
163
+ ffi_lib :kernel32
164
+ attach_function_private :GetCurrentProcess, [], :handle
165
+
166
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx
167
+ # BOOL WINAPI OpenProcessToken(
168
+ # _In_ HANDLE ProcessHandle,
169
+ # _In_ DWORD DesiredAccess,
170
+ # _Out_ PHANDLE TokenHandle
171
+ # );
172
+ ffi_lib :advapi32
173
+ attach_function_private :OpenProcessToken,
174
+ [:handle, :dword, :phandle], :win32_bool
175
+
176
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx
177
+ TOKEN_INFORMATION_CLASS = enum(
178
+ :TokenUser, 1,
179
+ :TokenGroups,
180
+ :TokenPrivileges,
181
+ :TokenOwner,
182
+ :TokenPrimaryGroup,
183
+ :TokenDefaultDacl,
184
+ :TokenSource,
185
+ :TokenType,
186
+ :TokenImpersonationLevel,
187
+ :TokenStatistics,
188
+ :TokenRestrictedSids,
189
+ :TokenSessionId,
190
+ :TokenGroupsAndPrivileges,
191
+ :TokenSessionReference,
192
+ :TokenSandBoxInert,
193
+ :TokenAuditPolicy,
194
+ :TokenOrigin,
195
+ :TokenElevationType,
196
+ :TokenLinkedToken,
197
+ :TokenElevation,
198
+ :TokenHasRestrictions,
199
+ :TokenAccessInformation,
200
+ :TokenVirtualizationAllowed,
201
+ :TokenVirtualizationEnabled,
202
+ :TokenIntegrityLevel,
203
+ :TokenUIAccess,
204
+ :TokenMandatoryPolicy,
205
+ :TokenLogonSid,
206
+ :TokenIsAppContainer,
207
+ :TokenCapabilities,
208
+ :TokenAppContainerSid,
209
+ :TokenAppContainerNumber,
210
+ :TokenUserClaimAttributes,
211
+ :TokenDeviceClaimAttributes,
212
+ :TokenRestrictedUserClaimAttributes,
213
+ :TokenRestrictedDeviceClaimAttributes,
214
+ :TokenDeviceGroups,
215
+ :TokenRestrictedDeviceGroups,
216
+ :TokenSecurityAttributes,
217
+ :TokenIsRestricted,
218
+ :MaxTokenInfoClass
219
+ )
220
+
221
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/bb530717(v=vs.85).aspx
222
+ # typedef struct _TOKEN_ELEVATION {
223
+ # DWORD TokenIsElevated;
224
+ # } TOKEN_ELEVATION, *PTOKEN_ELEVATION;
225
+ class TOKEN_ELEVATION < FFI::Struct
226
+ layout :TokenIsElevated, :dword
227
+ end
228
+
229
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
230
+ # BOOL WINAPI GetTokenInformation(
231
+ # _In_ HANDLE TokenHandle,
232
+ # _In_ TOKEN_INFORMATION_CLASS TokenInformationClass,
233
+ # _Out_opt_ LPVOID TokenInformation,
234
+ # _In_ DWORD TokenInformationLength,
235
+ # _Out_ PDWORD ReturnLength
236
+ # );
237
+ ffi_lib :advapi32
238
+ attach_function_private :GetTokenInformation,
239
+ [:handle, TOKEN_INFORMATION_CLASS, :lpvoid, :dword, :pdword ], :win32_bool
240
+
241
+ # https://msdn.microsoft.com/en-us/library/windows/hardware/ff563620(v=vs.85).aspx
242
+ # typedef struct _OSVERSIONINFOEXW {
243
+ # ULONG dwOSVersionInfoSize;
244
+ # ULONG dwMajorVersion;
245
+ # ULONG dwMinorVersion;
246
+ # ULONG dwBuildNumber;
247
+ # ULONG dwPlatformId;
248
+ # WCHAR szCSDVersion[128];
249
+ # USHORT wServicePackMajor;
250
+ # USHORT wServicePackMinor;
251
+ # USHORT wSuiteMask;
252
+ # UCHAR wProductType;
253
+ # UCHAR wReserved;
254
+ # } RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;
255
+ class OSVERSIONINFOEX < FFI::Struct
256
+ layout(
257
+ :dwOSVersionInfoSize, :win32_ulong,
258
+ :dwMajorVersion, :win32_ulong,
259
+ :dwMinorVersion, :win32_ulong,
260
+ :dwBuildNumber, :win32_ulong,
261
+ :dwPlatformId, :win32_ulong,
262
+ :szCSDVersion, [:wchar, 128],
263
+ :wServicePackMajor, :ushort,
264
+ :wServicePackMinor, :ushort,
265
+ :wSuiteMask, :ushort,
266
+ :wProductType, :uchar,
267
+ :wReserved, :uchar,
268
+ )
269
+ end
270
+
271
+ # NTSTATUS -> :int32 (defined in winerror.h / ntstatus.h)
272
+ # https://msdn.microsoft.com/en-us/library/windows/hardware/ff561910(v=vs.85).aspx
273
+ # NTSTATUS RtlGetVersion(
274
+ # _Out_ PRTL_OSVERSIONINFOW lpVersionInformation
275
+ # );
276
+ ffi_lib [FFI::CURRENT_PROCESS, :ntdll]
277
+ attach_function :RtlGetVersion, [:pointer], :int32
278
+
279
+ # C++ int is a signed 32-bit integer
280
+ # int WINAPI GetSystemMetrics(
281
+ # _In_ int nIndex
282
+ # );
283
+ ffi_lib :user32
284
+ attach_function :GetSystemMetrics, [:int32], :int32
285
+ end
@@ -0,0 +1,180 @@
1
+ require 'facter/util/windows'
2
+ require 'ffi'
3
+
4
+ module Facter::Util::Windows::User
5
+ extend FFI::Library
6
+
7
+ def admin?
8
+ elevated_supported = Facter::Util::Windows::Process.supports_elevated_security?
9
+
10
+ # if Vista or later, check for unrestricted process token
11
+ return Facter::Util::Windows::Process.elevated_security? if elevated_supported
12
+
13
+ # otherwise 2003 or less
14
+ check_token_membership
15
+ end
16
+ module_function :admin?
17
+
18
+
19
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/ee207397(v=vs.85).aspx
20
+ SECURITY_MAX_SID_SIZE = 68
21
+
22
+ def check_token_membership
23
+ is_admin = false
24
+ FFI::MemoryPointer.new(:byte, SECURITY_MAX_SID_SIZE) do |sid_pointer|
25
+ FFI::MemoryPointer.new(:dword, 1) do |size_pointer|
26
+ size_pointer.write_uint32(SECURITY_MAX_SID_SIZE)
27
+
28
+ if CreateWellKnownSid(:WinBuiltinAdministratorsSid, FFI::Pointer::NULL, sid_pointer, size_pointer) == FFI::WIN32_FALSE
29
+ raise Facter::Util::Windows::Error.new("Failed to create administrators SID")
30
+ end
31
+ end
32
+
33
+ if IsValidSid(sid_pointer) == FFI::WIN32_FALSE
34
+ raise RuntimeError,"Invalid SID"
35
+ end
36
+
37
+ FFI::MemoryPointer.new(:win32_bool, 1) do |ismember_pointer|
38
+ if CheckTokenMembership(FFI::Pointer::NULL_HANDLE, sid_pointer, ismember_pointer) == FFI::WIN32_FALSE
39
+ raise Facter::Util::Windows::Error.new("Failed to check membership")
40
+ end
41
+
42
+ # Is administrators SID enabled in calling thread's access token?
43
+ is_admin = ismember_pointer.read_win32_bool
44
+ end
45
+ end
46
+
47
+ is_admin
48
+ end
49
+ module_function :check_token_membership
50
+
51
+ ffi_convention :stdcall
52
+
53
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa376389(v=vs.85).aspx
54
+ # BOOL WINAPI CheckTokenMembership(
55
+ # _In_opt_ HANDLE TokenHandle,
56
+ # _In_ PSID SidToCheck,
57
+ # _Out_ PBOOL IsMember
58
+ # );
59
+ ffi_lib :advapi32
60
+ attach_function_private :CheckTokenMembership,
61
+ [:handle, :pointer, :pbool], :win32_bool
62
+
63
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379650(v=vs.85).aspx
64
+ WELL_KNOWN_SID_TYPE = enum(
65
+ :WinNullSid , 0,
66
+ :WinWorldSid , 1,
67
+ :WinLocalSid , 2,
68
+ :WinCreatorOwnerSid , 3,
69
+ :WinCreatorGroupSid , 4,
70
+ :WinCreatorOwnerServerSid , 5,
71
+ :WinCreatorGroupServerSid , 6,
72
+ :WinNtAuthoritySid , 7,
73
+ :WinDialupSid , 8,
74
+ :WinNetworkSid , 9,
75
+ :WinBatchSid , 10,
76
+ :WinInteractiveSid , 11,
77
+ :WinServiceSid , 12,
78
+ :WinAnonymousSid , 13,
79
+ :WinProxySid , 14,
80
+ :WinEnterpriseControllersSid , 15,
81
+ :WinSelfSid , 16,
82
+ :WinAuthenticatedUserSid , 17,
83
+ :WinRestrictedCodeSid , 18,
84
+ :WinTerminalServerSid , 19,
85
+ :WinRemoteLogonIdSid , 20,
86
+ :WinLogonIdsSid , 21,
87
+ :WinLocalSystemSid , 22,
88
+ :WinLocalServiceSid , 23,
89
+ :WinNetworkServiceSid , 24,
90
+ :WinBuiltinDomainSid , 25,
91
+ :WinBuiltinAdministratorsSid , 26,
92
+ :WinBuiltinUsersSid , 27,
93
+ :WinBuiltinGuestsSid , 28,
94
+ :WinBuiltinPowerUsersSid , 29,
95
+ :WinBuiltinAccountOperatorsSid , 30,
96
+ :WinBuiltinSystemOperatorsSid , 31,
97
+ :WinBuiltinPrintOperatorsSid , 32,
98
+ :WinBuiltinBackupOperatorsSid , 33,
99
+ :WinBuiltinReplicatorSid , 34,
100
+ :WinBuiltinPreWindows2000CompatibleAccessSid , 35,
101
+ :WinBuiltinRemoteDesktopUsersSid , 36,
102
+ :WinBuiltinNetworkConfigurationOperatorsSid , 37,
103
+ :WinAccountAdministratorSid , 38,
104
+ :WinAccountGuestSid , 39,
105
+ :WinAccountKrbtgtSid , 40,
106
+ :WinAccountDomainAdminsSid , 41,
107
+ :WinAccountDomainUsersSid , 42,
108
+ :WinAccountDomainGuestsSid , 43,
109
+ :WinAccountComputersSid , 44,
110
+ :WinAccountControllersSid , 45,
111
+ :WinAccountCertAdminsSid , 46,
112
+ :WinAccountSchemaAdminsSid , 47,
113
+ :WinAccountEnterpriseAdminsSid , 48,
114
+ :WinAccountPolicyAdminsSid , 49,
115
+ :WinAccountRasAndIasServersSid , 50,
116
+ :WinNTLMAuthenticationSid , 51,
117
+ :WinDigestAuthenticationSid , 52,
118
+ :WinSChannelAuthenticationSid , 53,
119
+ :WinThisOrganizationSid , 54,
120
+ :WinOtherOrganizationSid , 55,
121
+ :WinBuiltinIncomingForestTrustBuildersSid , 56,
122
+ :WinBuiltinPerfMonitoringUsersSid , 57,
123
+ :WinBuiltinPerfLoggingUsersSid , 58,
124
+ :WinBuiltinAuthorizationAccessSid , 59,
125
+ :WinBuiltinTerminalServerLicenseServersSid , 60,
126
+ :WinBuiltinDCOMUsersSid , 61,
127
+ :WinBuiltinIUsersSid , 62,
128
+ :WinIUserSid , 63,
129
+ :WinBuiltinCryptoOperatorsSid , 64,
130
+ :WinUntrustedLabelSid , 65,
131
+ :WinLowLabelSid , 66,
132
+ :WinMediumLabelSid , 67,
133
+ :WinHighLabelSid , 68,
134
+ :WinSystemLabelSid , 69,
135
+ :WinWriteRestrictedCodeSid , 70,
136
+ :WinCreatorOwnerRightsSid , 71,
137
+ :WinCacheablePrincipalsGroupSid , 72,
138
+ :WinNonCacheablePrincipalsGroupSid , 73,
139
+ :WinEnterpriseReadonlyControllersSid , 74,
140
+ :WinAccountReadonlyControllersSid , 75,
141
+ :WinBuiltinEventLogReadersGroup , 76,
142
+ :WinNewEnterpriseReadonlyControllersSid , 77,
143
+ :WinBuiltinCertSvcDComAccessGroup , 78,
144
+ :WinMediumPlusLabelSid , 79,
145
+ :WinLocalLogonSid , 80,
146
+ :WinConsoleLogonSid , 81,
147
+ :WinThisOrganizationCertificateSid , 82,
148
+ :WinApplicationPackageAuthoritySid , 83,
149
+ :WinBuiltinAnyPackageSid , 84,
150
+ :WinCapabilityInternetClientSid , 85,
151
+ :WinCapabilityInternetClientServerSid , 86,
152
+ :WinCapabilityPrivateNetworkClientServerSid , 87,
153
+ :WinCapabilityPicturesLibrarySid , 88,
154
+ :WinCapabilityVideosLibrarySid , 89,
155
+ :WinCapabilityMusicLibrarySid , 90,
156
+ :WinCapabilityDocumentsLibrarySid , 91,
157
+ :WinCapabilitySharedUserCertificatesSid , 92,
158
+ :WinCapabilityEnterpriseAuthenticationSid , 93,
159
+ :WinCapabilityRemovableStorageSid , 94
160
+ )
161
+
162
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa446585(v=vs.85).aspx
163
+ # BOOL WINAPI CreateWellKnownSid(
164
+ # _In_ WELL_KNOWN_SID_TYPE WellKnownSidType,
165
+ # _In_opt_ PSID DomainSid,
166
+ # _Out_opt_ PSID pSid,
167
+ # _Inout_ DWORD *cbSid
168
+ # );
169
+ ffi_lib :advapi32
170
+ attach_function_private :CreateWellKnownSid,
171
+ [WELL_KNOWN_SID_TYPE, :pointer, :pointer, :lpdword], :win32_bool
172
+
173
+ # https://msdn.microsoft.com/en-us/library/windows/desktop/aa379151(v=vs.85).aspx
174
+ # BOOL WINAPI IsValidSid(
175
+ # _In_ PSID pSid
176
+ # );
177
+ ffi_lib :advapi32
178
+ attach_function_private :IsValidSid,
179
+ [:pointer], :win32_bool
180
+ end