Saveliy Tretiakov wrote:
Sylvain Petreolle пишет:
beeing a hack or nope, his implementation works.
My implementation works too, and it works correct.
Yes, It's correct. When the keyboard was loaded at init or just another one added. The name was already saved for the user.
BOOL STDCALL NtUserGetKeyboardLayoutName( LPWSTR lpszName) { BOOL ret = FALSE; PKBL pKbl;
UserEnterShared();
_SEH_TRY { ProbeForWrite(lpszName, 9*sizeof(WCHAR), 1); pKbl = PsGetCurrentThreadWin32Thread()->KeyboardLayout; RtlCopyMemory(lpszName, pKbl->Name, 9*sizeof(WCHAR)); ret = TRUE; } _SEH_HANDLE { SetLastNtError(_SEH_GetExceptionCode()); ret = FALSE; } _SEH_END;
UserLeave(); return ret; }
Okay,,,, We have to assume the current thread active keyboard (KLF_ACTIVATE) is thread->KeyboardLayout.
Remember this is a multi-threaded thingy too. If we unload a keyboard, it will need to sweep all the threads under that winstation. I think the current thread holds the winstation. So,, it would be easy to sweep for a specific group of threads.
WinStation0 WinStation1 /=======================\ /===========\ | | | | | [Display1] [Display2] | | [Disply3] | | | | | =======================/ ===========/ ^ ^ ps/2 usb | | | | [Ru kb0 ] [Ru kb1 ] __________________________/ | One kbdru.dll
(Note, assume ps/2 mouse associated with WinSta0 and usb mouse for WinSta1)
In this example we may need to add another item to the KBL structure or bring back the previouse KBL structure for each thread again.
Thanks, James