@@ -144,40 +144,79 @@ public static NtWindowStation Open(string winsta_name)
144144 [ UnmanagedFunctionPointer ( CallingConvention . StdCall ) ]
145145 private delegate IntPtr GetKbdLayout ( ) ;
146146
147+ private static IntPtr GetKdbLayoutOffset ( SafeLoadLibraryHandle lib , int ordinal )
148+ {
149+ var proc = lib . GetProcAddress ( new IntPtr ( ordinal ) ) ;
150+ if ( proc != IntPtr . Zero )
151+ {
152+ GetKbdLayout kbdLayout = ( GetKbdLayout ) Marshal . GetDelegateForFunctionPointer ( proc , typeof ( GetKbdLayout ) ) ;
153+ var layout = kbdLayout ( ) ;
154+ return new IntPtr ( layout . ToInt64 ( ) - lib . DangerousGetHandle ( ) . ToInt64 ( ) ) ;
155+ }
156+ return IntPtr . Zero ;
157+ }
158+
147159 /// <summary>
148160 /// Create a Window Station by name.
149161 /// </summary>
150- /// <param name="winsta_name">The name of the Window Station.</param>
162+ /// <param name="object_attributes">Object attributes for the Window Station.</param>
163+ /// <param name="desired_access">Desired access for the Window Station.</param>
164+ /// <param name="kbd_dll_path">Path to Keyboard DLL e.g. kbusa.dll.</param>
165+ /// <param name="keyboard_locale">Locale ID, e.g. 0x4090409.</param>
166+ /// <param name="language_id">Language ID e.g. 0x409.</param>
167+ /// <param name="throw_on_error">True to throw on error.</param>
151168 /// <returns>The Window Station.</returns>
152- public static NtWindowStation Create ( string winsta_name )
169+ public static NtResult < NtWindowStation > Create ( ObjectAttributes object_attributes , WindowStationAccessRights desired_access , string kbd_dll_path ,
170+ int language_id , int keyboard_locale , bool throw_on_error )
153171 {
154172 string dll_path ;
155173 IntPtr layout_offset ;
156- using ( var kbd_dll = SafeLoadLibraryHandle . LoadLibrary ( @"kbdus.dll" ) )
174+ IntPtr nls_offset ;
175+ using ( var kbd_dll = SafeLoadLibraryHandle . LoadLibrary ( kbd_dll_path , LoadLibraryFlags . None , throw_on_error ) )
157176 {
158- dll_path = kbd_dll . FullPath ;
159- var proc = kbd_dll . GetProcAddress ( new IntPtr ( 1 ) ) ;
160- GetKbdLayout kbdLayout = ( GetKbdLayout ) Marshal . GetDelegateForFunctionPointer ( proc , typeof ( GetKbdLayout ) ) ;
161- var layout = kbdLayout ( ) ;
162- layout_offset = new IntPtr ( layout . ToInt64 ( ) - kbd_dll . DangerousGetHandle ( ) . ToInt64 ( ) ) ;
177+ if ( ! kbd_dll . IsSuccess )
178+ {
179+ return kbd_dll . Cast < NtWindowStation > ( ) ;
180+ }
181+ dll_path = kbd_dll . Result . FullPath ;
182+ layout_offset = GetKdbLayoutOffset ( kbd_dll . Result , 1 ) ;
183+ nls_offset = GetKdbLayoutOffset ( kbd_dll . Result , 2 ) ;
163184 }
164185
165186 using ( var buffer = new SafeHGlobalBuffer ( 0x318 ) )
166187 {
167188 BufferUtils . FillBuffer ( buffer , 0 ) ;
168189 using ( var file = NtFile . Open ( NtFileUtils . DosFileNameToNt ( dll_path ) , null ,
169- FileAccessRights . GenericRead | FileAccessRights . Synchronize , FileShareMode . Read | FileShareMode . Delete ,
170- FileOpenOptions . NonDirectoryFile | FileOpenOptions . SynchronousIoNonAlert ) )
190+ FileAccessRights . GenericRead | FileAccessRights . Synchronize , FileShareMode . Read | FileShareMode . Delete ,
191+ FileOpenOptions . NonDirectoryFile | FileOpenOptions . SynchronousIoNonAlert , throw_on_error ) )
171192 {
172- using ( var obja = new ObjectAttributes ( winsta_name , AttributeFlags . CaseInsensitive ) )
193+ if ( ! file . IsSuccess )
173194 {
174- return new NtWindowStation ( NtSystemCalls . NtUserCreateWindowStation ( obja , WindowStationAccessRights . MaximumAllowed , file . Handle ,
175- layout_offset , IntPtr . Zero , buffer , new UnicodeString ( "00000409" ) , 0x04090409 ) ) ;
195+ return file . Cast < NtWindowStation > ( ) ;
176196 }
197+ var handle = NtSystemCalls . NtUserCreateWindowStation ( object_attributes , desired_access , file . Result . Handle ,
198+ layout_offset , nls_offset , buffer , new UnicodeString ( $ "{ language_id : X08} ") , keyboard_locale ) ;
199+ if ( handle . IsInvalid )
200+ return NtObjectUtils . CreateResultFromDosError < NtWindowStation > ( throw_on_error ) ;
201+ return new NtWindowStation ( handle ) . CreateResult ( ) ;
177202 }
178203 }
179204 }
180205
206+ /// <summary>
207+ /// Create a Window Station by name.
208+ /// </summary>
209+ /// <param name="winsta_name">The name of the Window Station.</param>
210+ /// <returns>The Window Station.</returns>
211+ public static NtWindowStation Create ( string winsta_name )
212+ {
213+ using ( var obja = new ObjectAttributes ( winsta_name , AttributeFlags . CaseInsensitive ) )
214+ {
215+ return Create ( obja , WindowStationAccessRights . MaximumAllowed ,
216+ "kbdus.dll" , 0x409 , 0x4090409 , true ) . Result ;
217+ }
218+ }
219+
181220 /// <summary>
182221 /// Get a list of desktops for this Window Station.
183222 /// </summary>
0 commit comments