Skip to content

Commit 66a1249

Browse files
committed
Added full create function for window stations.
1 parent d5a6b63 commit 66a1249

1 file changed

Lines changed: 52 additions & 13 deletions

File tree

NtApiDotNet/NtWindowStation.cs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)