7171
7272include(" libopencl.jl" )
7373
74+ @static if Sys. iswindows()
75+ # Windows type aliases
76+ const BOOL = Int32
77+ const DWORD = UInt32
78+ const PDWORD = Ptr{DWORD}
79+ const HANDLE = Ptr{Cvoid}
80+ const PHANDLE = Ptr{HANDLE}
81+ const BYTE = UInt8
82+ const PBYTE = Ptr{BYTE}
83+ const PVOID = Ptr{Cvoid}
84+ const PSID = PVOID
85+ const PSID_AND_ATTRIBUTES = PVOID
86+ struct SID_AND_ATTRIBUTES
87+ Sid:: PSID
88+ Attributes:: DWORD
89+ end
90+ struct TOKEN_MANDATORY_LABEL
91+ Label:: SID_AND_ATTRIBUTES
92+ end
93+
94+ # Windows constants
95+ const TOKEN_QUERY = DWORD(0x0008 )
96+ const TOKEN_QUERY_SOURCE = DWORD(0x0010 )
97+ const SECURITY_MAX_SID_SIZE = 68
98+ const SECURITY_MANDATORY_MEDIUM_RID = DWORD(0x2000 )
99+ const TokenIntegrityLevel = 25 # TOKEN_INFORMATION_CLASS enum value
100+
101+ const kernel32 = " kernel32.dll"
102+ GetCurrentProcess() = @ccall kernel32. GetCurrentProcess():: HANDLE
103+ CloseHandle(hObject) = @ccall kernel32. CloseHandle(hObject:: HANDLE ):: BOOL
104+
105+ const advapi32 = " advapi32.dll"
106+ OpenProcessToken(ProcessHandle, DesiredAccess, TokenHandle) =
107+ @ccall advapi32. OpenProcessToken(ProcessHandle:: HANDLE , DesiredAccess:: DWORD , TokenHandle:: PHANDLE ):: BOOL
108+ GetTokenInformation(TokenHandle, TokenInformationClass, TokenInformation, TokenInformationLength, ReturnLength) =
109+ @ccall advapi32. GetTokenInformation(TokenHandle:: HANDLE , TokenInformationClass:: Int32 , TokenInformation:: PBYTE , TokenInformationLength:: DWORD , ReturnLength:: PDWORD ):: BOOL
110+ GetSidSubAuthorityCount(pSid) =
111+ @ccall advapi32. GetSidSubAuthorityCount(pSid:: PSID ):: PBYTE
112+ GetSidSubAuthority(pSid, nSubAuthority) =
113+ @ccall advapi32. GetSidSubAuthority(pSid:: PSID , nSubAuthority:: DWORD ):: PDWORD
114+
115+ # mimics `khrIcd_IsHighIntegrityLevel`, which determines if we can specify
116+ # drivers through environment variables
117+ function is_high_integrity_level():: Bool
118+ is_high_integrity = false
119+
120+ h_token = Ref{HANDLE}()
121+ if OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, h_token) != 0
122+ try
123+ # Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
124+ mandatory_label_buffer = zeros(BYTE, SECURITY_MAX_SID_SIZE + sizeof(DWORD))
125+ buffer_size = Ref{DWORD}()
126+ if GetTokenInformation(h_token[], TokenIntegrityLevel, mandatory_label_buffer, length(mandatory_label_buffer), buffer_size) != 0
127+ mandatory_label = unsafe_load(Ptr{TOKEN_MANDATORY_LABEL}(pointer(mandatory_label_buffer)))
128+ sub_auth_count = unsafe_load(GetSidSubAuthorityCount(mandatory_label. Label. Sid))
129+ integrity_level = unsafe_load(GetSidSubAuthority(mandatory_label. Label. Sid, sub_auth_count - 1 ))
130+
131+ return integrity_level > SECURITY_MANDATORY_MEDIUM_RID
132+ end
133+ finally
134+ CloseHandle(h_token[])
135+ end
136+ end
137+
138+ return is_high_integrity
139+ end
140+ end
141+
74142# lazy initialization
75143const initialized = Ref{Bool}(false )
76144@noinline function initialize()
77145 initialized[] = true
78146
79- if isempty(OpenCL_jll. drivers)
80- @warn """ No OpenCL driver JLLs were detected at the time of the first call into OpenCL.jl.
81- Only system drivers will be available."""
82- return
147+ @static if Sys. iswindows()
148+ if is_high_integrity_level()
149+ @warn """ Running at high integrity level, preventing OpenCL.jl from loading drivers from JLLs.
150+
151+ Only system drivers will be available. To enable JLL drivers, do not run Julia as an administrator."""
152+ end
83153 end
84154
85155 ocd_filenames = join(OpenCL_jll. drivers, ' :' )
@@ -92,6 +162,13 @@ const initialized = Ref{Bool}(false)
92162 @ccall libopencl. clGetPlatformIDs(
93163 0 :: cl_uint , C_NULL :: Ptr{cl_platform_id} ,
94164 num_platforms:: Ptr{cl_uint} ):: cl_int
165+
166+ if num_platforms[] == 0 && isempty(OpenCL_jll. drivers)
167+ @error """ No OpenCL drivers available, either system-wide or provided by a JLL.
168+
169+ Please install a system-wide OpenCL driver, or load one together with OpenCL.jl,
170+ e.g., by doing `using OpenCL, pocl_jll`."""
171+ end
95172 end
96173end
97174
0 commit comments