[WIN32K:NTUSER]
[reactos.git] / reactos / win32ss / user / ntuser / misc.c
index 7a8d238..0cb5fd1 100644 (file)
@@ -2,13 +2,55 @@
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS Win32k subsystem
  * PURPOSE:          Miscellaneous User functions
- * FILE:             subsystems/win32/win32k/ntuser/misc.c
+ * FILE:             win32ss/user/ntuser/misc.c
  * PROGRAMER:        Ge van Geldorp (ge@gse.nl)
  */
 
 #include <win32k.h>
 DBG_DEFAULT_CHANNEL(UserMisc);
 
+/*
+ * Test the Thread to verify and validate it. Hard to the core tests are required.
+ */
+PTHREADINFO
+FASTCALL
+IntTID2PTI(HANDLE id)
+{
+   NTSTATUS Status;
+   PETHREAD Thread;
+   PTHREADINFO pti;
+   Status = PsLookupThreadByThreadId(id, &Thread);
+   if (!NT_SUCCESS(Status))
+   {
+      return NULL;
+   }
+   if (PsIsThreadTerminating(Thread))
+   {
+      ObDereferenceObject(Thread);
+      return NULL;
+   }
+   pti = PsGetThreadWin32Thread(Thread);
+   if (!pti)
+   {
+      ObDereferenceObject(Thread);
+      return NULL;
+   }
+   // Validate and verify!
+   _SEH2_TRY
+   {
+      if (pti->TIF_flags & TIF_INCLEANUP) pti = NULL;
+      if (pti && !(pti->TIF_flags & TIF_GUITHREADINITIALIZED)) pti = NULL;
+      if (PsGetThreadId(Thread) != id) pti = NULL;
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      pti = NULL;
+   }
+   _SEH2_END
+   ObDereferenceObject(Thread);
+   return pti;
+}
+
 SHORT
 FASTCALL
 UserGetLanguageID(VOID)
@@ -16,7 +58,7 @@ 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;
@@ -25,10 +67,10 @@ UserGetLanguageID(VOID)
     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)))
   {
@@ -45,7 +87,10 @@ UserGetLanguageID(VOID)
                                              &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);
     }
@@ -181,14 +226,14 @@ NtUserGetThreadState(
          break;
       case THREADSTATE_INSENDMESSAGE:
          {
-           PUSER_SENT_MESSAGE Message = 
+           PUSER_SENT_MESSAGE Message =
                 ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->pusmCurrent;
            ERR("THREADSTATE_INSENDMESSAGE\n");
 
            ret = ISMEX_NOSEND;
            if (Message)
            {
-             if (Message->SenderQueue)
+             if (Message->ptiSender)
                 ret = ISMEX_SEND;
              else
              {
@@ -201,7 +246,7 @@ NtUserGetThreadState(
              if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED;
            }
 
-           break;         
+           break;
          }
       case THREADSTATE_GETMESSAGETIME:
          ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast;
@@ -213,7 +258,7 @@ NtUserGetThreadState(
            LARGE_INTEGER LargeTickCount;
            pti = PsGetCurrentThreadWin32Thread();
            KeQueryTickCount(&LargeTickCount);
-           pti->MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
+           pti->timeLast = LargeTickCount.u.LowPart;
            pti->pcti->tickLastMsgChecked = LargeTickCount.u.LowPart;
          }
          break;
@@ -229,9 +274,12 @@ NtUserGetThreadState(
          ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ?
                             UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0);
          break;
+      case THREADSTATE_GETMESSAGEEXTRAINFO:
+         ret = (DWORD_PTR)MsqGetMessageExtraInfo();
+        break;
    }
 
-   TRACE("Leave NtUserGetThreadState, ret=%i\n", ret);
+   TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);
    UserLeave();
 
    return ret;
@@ -247,7 +295,7 @@ NtUserSetThreadState(
    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)
@@ -276,7 +324,7 @@ NtUserGetDoubleClickTime(VOID)
    // FIXME: Check if this works on non-interactive winsta
    Result = gspv.iDblClickTime;
 
-   TRACE("Leave NtUserGetDoubleClickTime, ret=%i\n", Result);
+   TRACE("Leave NtUserGetDoubleClickTime, ret=%u\n", Result);
    UserLeave();
    return Result;
 }
@@ -346,9 +394,31 @@ NtUserGetGUIThreadInfo(
       if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue;
    }
 
-   CaretInfo = MsgQueue->CaretInfo;
+   CaretInfo = &MsgQueue->CaretInfo;
 
    SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
+/*
+   if (W32Thread->pMenuState->pGlobalPopupMenu)
+   {
+       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;
+       }
+   }
+ */
+   SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
 
    if (MsgQueue->MenuOwner)
       SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
@@ -361,7 +431,6 @@ NtUserGetGUIThreadInfo(
    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;
 
@@ -383,7 +452,7 @@ NtUserGetGUIThreadInfo(
    RETURN( TRUE);
 
 CLEANUP:
-   TRACE("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_);
+   TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -406,7 +475,7 @@ NtUserGetGuiResources(
 
    Status = ObReferenceObjectByHandle(hProcess,
                                       PROCESS_QUERY_INFORMATION,
-                                      PsProcessType,
+                                      *PsProcessType,
                                       ExGetPreviousMode(),
                                       (PVOID*)&Process,
                                       NULL);
@@ -449,7 +518,7 @@ NtUserGetGuiResources(
    RETURN( Ret);
 
 CLEANUP:
-   TRACE("Leave NtUserGetGuiResources, ret=%i\n",_ret_);
+   TRACE("Leave NtUserGetGuiResources, ret=%lu\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -614,14 +683,19 @@ void UserDbgAssertThreadInfo(BOOL showCaller)
     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);
 
     /*too bad we still get this assertion*/
+
+    // Why? Not all flags are passed to the user and doing so could crash the system........
+
     /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */
-    if(pci->dwTIFlags != pti->TIF_flags)
+/*    if(pci->dwTIFlags != pti->TIF_flags)
     {
         ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags);
         if(showCaller)
@@ -631,6 +705,7 @@ void UserDbgAssertThreadInfo(BOOL showCaller)
         }
         pci->dwTIFlags = pti->TIF_flags;
     }
+*/
 }
 
 void
@@ -646,7 +721,7 @@ UserDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult)
 {
     /* Make sure that the first syscall is NtUserInitialize */
     /* too bad this fails */
-    //ASSERT(gbInitialized);
+    // ASSERT(gpepCSRSS);
 
     UserDbgAssertThreadInfo(TRUE);