#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserMisc);
+
+/*
+ * NOTE: _scwprintf() is NOT exported by ntoskrnl.exe,
+ * only _vscwprintf() is, so we need to implement it here.
+ * Code comes from sdk/lib/crt/printf/_scwprintf.c .
+ * See also win32ss/user/winsrv/usersrv/harderror.c .
+ */
+int
+__cdecl
+_scwprintf(
+ const wchar_t *format,
+ ...)
+{
+ int len;
+ va_list args;
+
+ va_start(args, format);
+ len = _vscwprintf(format, args);
+ va_end(args);
+
+ return len;
+}
+
+
/*
* Test the Thread to verify and validate it. Hard to the core tests are required.
*/
return pti;
}
+DWORD
+FASTCALL
+UserGetLanguageToggle(VOID)
+{
+ NTSTATUS Status;
+ DWORD dwValue = 0;
+
+ Status = RegReadUserSetting(L"Keyboard Layout\\Toggle", L"Layout Hotkey", REG_SZ, &dwValue, sizeof(dwValue));
+ if (NT_SUCCESS(Status))
+ {
+ dwValue = atoi((char *)&dwValue);
+ TRACE("Layout Hotkey %d\n",dwValue);
+ }
+ return dwValue;
+}
+
SHORT
FASTCALL
UserGetLanguageID(VOID)
HANDLE KeyHandle;
OBJECT_ATTRIBUTES ObAttr;
// http://support.microsoft.com/kb/324097
- ULONG Ret = 0x409; // English
+ ULONG Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo;
ULONG Size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH*sizeof(WCHAR);
UNICODE_STRING Language;
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
InitializeObjectAttributes( &ObAttr,
- &Language,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
+ &Language,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
if ( NT_SUCCESS(ZwOpenKey(&KeyHandle, KEY_READ, &ObAttr)))
{
&Size)) )
{
RtlInitUnicodeString(&Language, (PWSTR)pKeyInfo->Data);
- RtlUnicodeStringToInteger(&Language, 16, &Ret);
+ if (!NT_SUCCESS(RtlUnicodeStringToInteger(&Language, 16, &Ret)))
+ {
+ Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
+ }
}
ExFreePoolWithTag(pKeyInfo, TAG_STRING);
}
break;
case THREADSTATE_INSENDMESSAGE:
{
- PUSER_SENT_MESSAGE Message =
+ PUSER_SENT_MESSAGE Message =
((PTHREADINFO)PsGetCurrentThreadWin32Thread())->pusmCurrent;
- ERR("THREADSTATE_INSENDMESSAGE\n");
+ TRACE("THREADSTATE_INSENDMESSAGE\n");
ret = ISMEX_NOSEND;
if (Message)
if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED;
}
- break;
+ break;
}
case THREADSTATE_GETMESSAGETIME:
ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast;
ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ?
UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0);
break;
+ case THREADSTATE_GETMESSAGEEXTRAINFO:
+ ret = (DWORD_PTR)MsqGetMessageExtraInfo();
+ break;
}
TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);
DWORD Ret = 0;
// Test the only flags user can change.
if (Set & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0;
- if (Flags & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0;
+ if (Flags & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0;
UserEnterExclusive();
pti = PsGetCurrentThreadWin32Thread();
if (pti->MessageQueue)
}
W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
Desktop = W32Thread->rpdesk;
+
+ if (!Thread || !Desktop )
+ {
+ if(Thread)
+ ObDereferenceObject(Thread);
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ RETURN( FALSE);
+ }
+
+ if ( W32Thread->MessageQueue )
+ MsgQueue = W32Thread->MessageQueue;
+ else
+ {
+ if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
+ }
}
else
{ /* Get the foreground thread */
- Thread = PsGetCurrentThread();
- W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread;
- Desktop = W32Thread->rpdesk;
+ /* FIXME: Handle NULL queue properly? */
+ MsgQueue = IntGetFocusMessageQueue();
+ if(!MsgQueue)
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ RETURN( FALSE);
+ }
}
- if (!Thread || !Desktop )
- {
- if(idThread && Thread)
- ObDereferenceObject(Thread);
- EngSetLastError(ERROR_ACCESS_DENIED);
- RETURN( FALSE);
- }
+ CaretInfo = &MsgQueue->CaretInfo;
- if ( W32Thread->MessageQueue )
- MsgQueue = W32Thread->MessageQueue;
- else
+ SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
+/*
+ if (W32Thread->pMenuState->pGlobalPopupMenu)
{
- if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
+ SafeGui.flags |= GUI_INMENUMODE;
+
+ if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify)
+ SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify);
+
+ if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar)
+ {
+ if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu)
+ {
+ SafeGui.flags |= GUI_SYSTEMMENUMODE;
+ }
+ }
+ else
+ {
+ SafeGui.flags |= GUI_POPUPMENUMODE;
+ }
}
-
- CaretInfo = MsgQueue->CaretInfo;
-
- SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
+ */
+ SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
if (MsgQueue->MenuOwner)
SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0;
SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0;
SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0;
- SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
SafeGui.hwndMoveSize = MsgQueue->MoveSize;
SafeGui.hwndCaret = CaretInfo->hWnd;
Status = ObReferenceObjectByHandle(hProcess,
PROCESS_QUERY_INFORMATION,
- PsProcessType,
+ *PsProcessType,
ExGetPreviousMode(),
(PVOID*)&Process,
NULL);
ASSERT(pci->ulClientDelta == DesktopHeapGetUserDelta());
if (pti->pcti && pci->pDeskInfo)
ASSERT(pci->pClientThreadInfo == (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta));
- if (pti->KeyboardLayout)
+ if (pti->pcti && IsListEmpty(&pti->SentMessagesListHead))
+ ASSERT((pti->pcti->fsChangeBits & QS_SENDMESSAGE) == 0);
+ if (pti->KeyboardLayout)
ASSERT(pci->hKL == pti->KeyboardLayout->hkl);
if(pti->rpdesk != NULL)
ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo);
{
/* Make sure that the first syscall is NtUserInitialize */
/* too bad this fails */
- //ASSERT(gbInitialized);
+ // ASSERT(gpepCSRSS);
UserDbgAssertThreadInfo(TRUE);
return (PTHREADINFO)PsGetCurrentThreadWin32Thread();
}
+
+NTSTATUS
+GetProcessLuid(
+ IN PETHREAD Thread OPTIONAL,
+ IN PEPROCESS Process OPTIONAL,
+ OUT PLUID Luid)
+{
+ NTSTATUS Status;
+ PACCESS_TOKEN Token = NULL;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ BOOLEAN CopyOnOpen, EffectiveOnly;
+
+ if (Thread && Process)
+ return STATUS_INVALID_PARAMETER;
+
+ /* If nothing has been specified, use the current thread */
+ if (!Thread && !Process)
+ Thread = PsGetCurrentThread();
+
+ if (Thread)
+ {
+ /* Use a thread token */
+ ASSERT(!Process);
+ Token = PsReferenceImpersonationToken(Thread,
+ &CopyOnOpen,
+ &EffectiveOnly,
+ &ImpersonationLevel);
+
+ /* If we don't have a thread token, use a process token */
+ if (!Token)
+ Process = PsGetThreadProcess(Thread);
+ }
+ if (!Token && Process)
+ {
+ /* Use a process token */
+ Token = PsReferencePrimaryToken(Process);
+
+ /* If we don't have a token, fail */
+ if (!Token)
+ return STATUS_NO_TOKEN;
+ }
+ ASSERT(Token);
+
+ /* Query the LUID */
+ Status = SeQueryAuthenticationIdToken(Token, Luid);
+
+ /* Get rid of the token and return */
+ ObDereferenceObject(Token);
+ return Status;
+}
+
/* EOF */