#include <w32k.h>
-//#define NDEBUG
-#undef NDEBUG
+#define NDEBUG
#include <debug.h>
/* registered Logon process */
PW32PROCESS LogonProcess = NULL;
-VOID W32kRegisterPrimitiveMessageQueue(VOID)
-{
- extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
- if( !pmPrimitiveMessageQueue )
- {
- PW32THREAD pThread;
- pThread = PsGetWin32Thread();
- if( pThread && pThread->MessageQueue )
- {
- pmPrimitiveMessageQueue = pThread->MessageQueue;
- IntReferenceMessageQueue(pmPrimitiveMessageQueue);
- DPRINT( "Installed primitive input queue.\n" );
- }
- }
- else
- {
- DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
- }
-}
-
-VOID W32kUnregisterPrimitiveMessageQueue(VOID)
-{
- extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
- IntDereferenceMessageQueue(pmPrimitiveMessageQueue);
- pmPrimitiveMessageQueue = NULL;
-}
-
-PUSER_MESSAGE_QUEUE W32kGetPrimitiveMessageQueue()
-{
- extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue;
- return pmPrimitiveMessageQueue;
-}
-
BOOL FASTCALL
co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
{
switch(Routine)
{
- case NOPARAM_ROUTINE_REGISTER_PRIMITIVE:
- W32kRegisterPrimitiveMessageQueue();
- Result = (DWORD)TRUE;
- break;
-
case NOPARAM_ROUTINE_DESTROY_CARET:
Result = (DWORD)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
break;
if (Routine == ONEPARAM_ROUTINE_SHOWCURSOR)
{
- PWINSTATION_OBJECT WinSta = PsGetWin32Thread()->Desktop->WindowStation;
+ PWINSTATION_OBJECT WinSta = PsGetCurrentThreadWin32Thread()->Desktop->WindowStation;
PSYSTEM_CURSORINFO CurInfo;
HDC Screen;
case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
{
BOOL Enable;
- PW32PROCESS Process = PsGetWin32Process();
+ PW32PROCESS Process = PsGetCurrentProcessWin32Process();
if(Process != NULL)
{
{
DWORD Ret;
RECT rcRect;
- PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
+ Window = UserGetWindowObject((HWND)Param1);
if (!Window) RETURN(ERROR);
Ret = (DWORD)IntGetWindowRgnBox(Window, &rcRect);
}
case TWOPARAM_ROUTINE_GETWINDOWRGN:
{
- PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
+ Window = UserGetWindowObject((HWND)Param1);
if (!Window) RETURN(ERROR);
RETURN( (DWORD)IntGetWindowRgn(Window, (HRGN)Param2));
case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
{
- PWINDOW_OBJECT Window = UserGetWindowObject((HWND)Param1);
+ Window = UserGetWindowObject((HWND)Param1);
if (!Window) RETURN(0);
RETURN( (DWORD)IntShowOwnedPopups(Window, (BOOL) Param2));
case TWOPARAM_ROUTINE_ROS_SHOWWINDOW:
{
#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
- PWINDOW_OBJECT Window;
DPRINT1("ROS_SHOWWINDOW\n");
if (!(Window = UserGetWindowObject((HWND)Param1)))
{
- RETURN( FALSE);
+ RETURN( 1 );
}
if (Param2)
{
if (!(Window->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP))
{
- RETURN( TRUE);
+ RETURN( -1 );
}
Window->Flags &= ~WIN_NEEDS_SHOW_OWNEDPOPUP;
}
Window->Flags |= WIN_NEEDS_SHOW_OWNEDPOPUP;
DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window->Flags);
- RETURN( TRUE);
+ RETURN( 0 );
}
+
case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
UNIMPLEMENTED
RETURN( 0);
switch (Routine)
{
case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
- /*
- * FIXME
- * Nothing too hard...validate the hWnd and save it in the Desktop Info
- */
- DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
+ GetW32ThreadInfo()->Desktop->hProgmanWindow = Param;
break;
case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
- /*
- * FIXME
- * Nothing too hard...validate the hWnd and save it in the Desktop Info
- */
- DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
+ GetW32ThreadInfo()->Desktop->hTaskManWindow = Param;
break;
}
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetThreadState\n");
- UserEnterShared();
+ if (Routine != THREADSTATE_GETTHREADINFO)
+ {
+ UserEnterShared();
+ }
+ else
+ {
+ UserEnterExclusive();
+ }
switch (Routine)
{
- case 0:
+ case THREADSTATE_GETTHREADINFO:
+ GetW32ThreadInfo();
+ RETURN(0);
+
+ case THREADSTATE_FOCUSWINDOW:
RETURN( (DWORD)IntGetThreadFocusWindow());
+ case THREADSTATE_PROGMANWINDOW:
+ RETURN( (DWORD)GetW32ThreadInfo()->Desktop->hProgmanWindow);
+ case THREADSTATE_TASKMANWINDOW:
+ RETURN( (DWORD)GetW32ThreadInfo()->Desktop->hTaskManWindow);
}
RETURN( 0);
static LOGFONTW DefaultFont = {
-11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
0, 0, DEFAULT_QUALITY, VARIABLE_PITCH | FF_SWISS,
- L"Bitstream Vera Sans"
+ L"MS Sans Serif"
};
RtlZeroMemory(&QueryTable, sizeof(QueryTable));
{
PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status;
+ BOOL bChanged = FALSE;
static BOOL bInitialized = FALSE;
static LOGFONTW IconFont;
static NONCLIENTMETRICSW pMetrics;
+ static MINIMIZEDMETRICS MinimizedMetrics;
static BOOL GradientCaptions = TRUE;
static UINT FocusBorderHeight = 1;
static UINT FocusBorderWidth = 1;
pMetrics.iMenuHeight = UserGetSystemMetrics(SM_CYMENUSIZE);
pMetrics.cbSize = sizeof(NONCLIENTMETRICSW);
+ MinimizedMetrics.cbSize = sizeof(MINIMIZEDMETRICS);
+ MinimizedMetrics.iWidth = UserGetSystemMetrics(SM_CXMINIMIZED);
+ MinimizedMetrics.iHorzGap = UserGetSystemMetrics(SM_CXMINSPACING);
+ MinimizedMetrics.iVertGap = UserGetSystemMetrics(SM_CYMINSPACING);
+ MinimizedMetrics.iArrange = ARW_HIDE;
+
bInitialized = TRUE;
}
case SPI_SETDOUBLECLKHEIGHT:
case SPI_SETDOUBLECLICKTIME:
case SPI_SETDESKWALLPAPER:
+ case SPI_SETSCREENSAVERRUNNING:
+ case SPI_SETSCREENSAVETIMEOUT:
+ case SPI_SETFLATMENU:
+ /* We will change something, so set the flag here */
+ bChanged = TRUE;
case SPI_GETDESKWALLPAPER:
+ case SPI_GETWHEELSCROLLLINES:
+ case SPI_GETWHEELSCROLLCHARS:
+ case SPI_GETSCREENSAVERRUNNING:
+ case SPI_GETSCREENSAVETIMEOUT:
+ case SPI_GETSCREENSAVEACTIVE:
+ case SPI_GETFLATMENU:
{
PSYSTEM_CURSORINFO CurInfo;
switch(uiAction)
{
+ case SPI_GETFLATMENU:
+ ASSERT(pvParam);
+ *((UINT*)pvParam) = WinStaObject->FlatMenu;
+ break;
+ case SPI_SETFLATMENU:
+ WinStaObject->FlatMenu = uiParam;
+ break;
+ case SPI_GETSCREENSAVETIMEOUT:
+ ASSERT(pvParam);
+ *((UINT*)pvParam) = WinStaObject->ScreenSaverTimeOut;
+ break;
+ case SPI_SETSCREENSAVETIMEOUT:
+ WinStaObject->ScreenSaverTimeOut = uiParam;
+ break;
+ case SPI_GETSCREENSAVERRUNNING:
+ if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning;
+ break;
+ case SPI_SETSCREENSAVERRUNNING:
+ if (pvParam != NULL) *((BOOL*)pvParam) = WinStaObject->ScreenSaverRunning;
+ WinStaObject->ScreenSaverRunning = uiParam;
+ break;
+ case SPI_GETSCREENSAVEACTIVE:
+ /* FIXME: how to disable the screensaver? */
+ ASSERT(pvParam);
+ *((BOOL*)pvParam) = TRUE;
+ break;
+ case SPI_GETWHEELSCROLLLINES:
+ ASSERT(pvParam);
+ CurInfo = IntGetSysCursorInfo(WinStaObject);
+ *((UINT*)pvParam) = CurInfo->WheelScroLines;
+ /* FIXME add this value to scroll list as scroll value ?? */
+ break;
+ case SPI_GETWHEELSCROLLCHARS:
+ ASSERT(pvParam);
+ CurInfo = IntGetSysCursorInfo(WinStaObject);
+ *((UINT*)pvParam) = CurInfo->WheelScroChars;
+ // FIXME add this value to scroll list as scroll value ??
+ break;
case SPI_SETDOUBLECLKWIDTH:
CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME limit the maximum value? */
BITMAPOBJ_UnlockBitmap(bmp);
/* change the bitmap's ownership */
- GDIOBJ_SetOwnership(hNewBitmap, NULL);
+ GDIOBJ_SetOwnership(GdiHandleTable, hNewBitmap, NULL);
}
hOldBitmap = (HBITMAP)InterlockedExchange((LONG*)&WinStaObject->hbmWallpaper, (LONG)hNewBitmap);
if(hOldBitmap != NULL)
if(!KeyValuePartialInfo)
{
NtClose(KeyHandle);
- return 0;
+ return FALSE;
}
Status = ZwQueryValueKey(KeyHandle, &Tile, KeyValuePartialInformation,
{
ZwClose(KeyHandle);
ExFreePool(KeyValuePartialInfo);
- return 0;
+ return FALSE;
}
Tile.Length = KeyValuePartialInfo->DataLength;
if(!KeyValuePartialInfo)
{
ZwClose(KeyHandle);
- return 0;
+ return FALSE;
}
Status = ZwQueryValueKey(KeyHandle, &Style, KeyValuePartialInformation,
{
ZwClose(KeyHandle);
ExFreePool(KeyValuePartialInfo);
- return 0;
+ return FALSE;
}
Style.Length = KeyValuePartialInfo->DataLength;
/* FIXME save the value to the registry */
ObDereferenceObject(WinStaObject);
- return TRUE;
+ break;
}
case SPI_SETWORKAREA:
{
RECT *rc;
- PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+ PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
if(!Desktop)
{
ASSERT(pvParam);
rc = (RECT*)pvParam;
Desktop->WorkArea = *rc;
+ bChanged = TRUE;
- return TRUE;
+ break;
}
case SPI_GETWORKAREA:
{
- PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop;
+ PDESKTOP_OBJECT Desktop = PsGetCurrentThreadWin32Thread()->Desktop;
if(!Desktop)
{
ASSERT(pvParam);
IntGetDesktopWorkArea(Desktop, (PRECT)pvParam);
- return TRUE;
+ break;
}
case SPI_SETGRADIENTCAPTIONS:
{
GradientCaptions = (pvParam != NULL);
/* FIXME - should be checked if the color depth is higher than 8bpp? */
- return TRUE;
+ bChanged = TRUE;
+ break;
}
case SPI_GETGRADIENTCAPTIONS:
{
BOOL Ret = GradientCaptions;
hDC = IntGetScreenDC();
- if(hDC)
+ if(!hDC)
{
+ return FALSE;
+ }
Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && Ret;
ASSERT(pvParam);
*((PBOOL)pvParam) = Ret;
- return TRUE;
+ break;
}
- return FALSE;
- }
case SPI_SETFONTSMOOTHING:
{
IntEnableFontRendering(uiParam != 0);
- return TRUE;
+ bChanged = TRUE;
+ break;
}
case SPI_GETFONTSMOOTHING:
{
ASSERT(pvParam);
*((BOOL*)pvParam) = IntIsFontRenderingEnabled();
- return TRUE;
+ break;
}
case SPI_GETICONTITLELOGFONT:
{
ASSERT(pvParam);
*((LOGFONTW*)pvParam) = IconFont;
- return TRUE;
+ break;
}
case SPI_GETNONCLIENTMETRICS:
{
ASSERT(pvParam);
*((NONCLIENTMETRICSW*)pvParam) = pMetrics;
- return TRUE;
+ break;
+ }
+ case SPI_SETNONCLIENTMETRICS:
+ {
+ ASSERT(pvParam);
+ pMetrics = *((NONCLIENTMETRICSW*)pvParam);
+ bChanged = TRUE;
+ break;
+ }
+ case SPI_GETMINIMIZEDMETRICS:
+ {
+ ASSERT(pvParam);
+ *((MINIMIZEDMETRICS*)pvParam) = MinimizedMetrics;
+ break;
+ }
+ case SPI_SETMINIMIZEDMETRICS:
+ {
+ ASSERT(pvParam);
+ MinimizedMetrics = *((MINIMIZEDMETRICS*)pvParam);
+ bChanged = TRUE;
+ break;
}
case SPI_GETFOCUSBORDERHEIGHT:
{
ASSERT(pvParam);
*((UINT*)pvParam) = FocusBorderHeight;
- return TRUE;
+ break;
}
case SPI_GETFOCUSBORDERWIDTH:
{
ASSERT(pvParam);
*((UINT*)pvParam) = FocusBorderWidth;
- return TRUE;
+ break;
}
case SPI_SETFOCUSBORDERHEIGHT:
{
FocusBorderHeight = (UINT)pvParam;
- return TRUE;
+ bChanged = TRUE;
+ break;
}
case SPI_SETFOCUSBORDERWIDTH:
{
FocusBorderWidth = (UINT)pvParam;
- return TRUE;
+ bChanged = TRUE;
+ break;
}
default:
return FALSE;
}
}
- return FALSE;
+ /* Did we change something ? */
+ if (bChanged)
+ {
+ /* Shall we send a WM_SETTINGCHANGE message ? */
+ if (fWinIni & (SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
+ {
+ /* Broadcast WM_SETTINGCHANGE to all toplevel windows */
+ /* FIXME: lParam should be pointer to a string containing the reg key */
+ UserPostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, (WPARAM)uiAction, 0);
+}
+ }
+ return TRUE;
}
/*
case SPI_GETGRADIENTCAPTIONS:
case SPI_GETFOCUSBORDERHEIGHT:
case SPI_GETFOCUSBORDERWIDTH:
+ case SPI_GETWHEELSCROLLLINES:
+ case SPI_GETWHEELSCROLLCHARS:
+ case SPI_GETSCREENSAVERRUNNING:
+ case SPI_SETSCREENSAVERRUNNING:
+ case SPI_GETSCREENSAVETIMEOUT:
+ case SPI_SETSCREENSAVETIMEOUT:
+ case SPI_GETSCREENSAVEACTIVE:
+ case SPI_GETFLATMENU:
+ case SPI_SETFLATMENU:
{
BOOL Ret;
return( TRUE);
}
case SPI_GETNONCLIENTMETRICS:
+ case SPI_SETNONCLIENTMETRICS:
{
NONCLIENTMETRICSW metrics;
- Status = MmCopyFromCaller(&metrics.cbSize, pvParam, sizeof(UINT));
+ Status = MmCopyFromCaller(&metrics, pvParam, sizeof(NONCLIENTMETRICSW));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return( FALSE);
}
- Status = MmCopyToCaller(pvParam, &metrics.cbSize, sizeof(NONCLIENTMETRICSW));
+ Status = MmCopyToCaller(pvParam, &metrics, sizeof(NONCLIENTMETRICSW));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return( FALSE);
+ }
+ return( TRUE);
+ }
+ case SPI_GETMINIMIZEDMETRICS:
+ case SPI_SETMINIMIZEDMETRICS:
+ {
+ MINIMIZEDMETRICS minimetrics;
+
+ Status = MmCopyFromCaller(&minimetrics, pvParam, sizeof(MINIMIZEDMETRICS));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return( FALSE);
+ }
+ if(minimetrics.cbSize != sizeof(MINIMIZEDMETRICS))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return( FALSE);
+ }
+ if(!IntSystemParametersInfo(uiAction, uiParam, &minimetrics, fWinIni))
+ {
+ return( FALSE);
+ }
+
+ Status = MmCopyToCaller(pvParam, &minimetrics, sizeof(MINIMIZEDMETRICS));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
}
return( TRUE);
}
+ default :
+ {
+ DPRINT1("FIXME: UNIMPLEMENTED SPI Code: %lx \n",uiAction );
+ break;
+ }
}
return( FALSE);
}
END_CLEANUP;
}
+PW32PROCESSINFO
+GetW32ProcessInfo(VOID)
+{
+ PW32PROCESSINFO pi;
+ PW32PROCESS W32Process = PsGetCurrentProcessWin32Process();
+
+ if (W32Process == NULL)
+ {
+ /* FIXME - temporary hack for system threads... */
+ return NULL;
+ }
+
+ if (W32Process->ProcessInfo == NULL)
+ {
+ pi = UserHeapAlloc(sizeof(W32PROCESSINFO));
+ if (pi != NULL)
+ {
+ RtlZeroMemory(pi,
+ sizeof(W32PROCESSINFO));
+
+ /* initialize it */
+ pi->UserHandleTable = gHandleTable;
+
+ if (InterlockedCompareExchangePointer(&W32Process->ProcessInfo,
+ pi,
+ NULL) != NULL)
+ {
+ UserHeapFree(pi);
+ }
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ return W32Process->ProcessInfo;
+}
+
+PW32THREADINFO
+GetW32ThreadInfo(VOID)
+{
+ PTEB Teb;
+ PW32THREADINFO ti;
+ PW32THREAD W32Thread = PsGetCurrentThreadWin32Thread();
+
+ if (W32Thread == NULL)
+ {
+ /* FIXME - temporary hack for system threads... */
+ return NULL;
+ }
+
+ /* allocate a W32THREAD structure if neccessary */
+ if (W32Thread->ThreadInfo == NULL)
+ {
+ ti = UserHeapAlloc(sizeof(W32THREADINFO));
+ if (ti != NULL)
+ {
+ RtlZeroMemory(ti,
+ sizeof(W32THREADINFO));
+
+ /* initialize it */
+ ti->kpi = GetW32ProcessInfo();
+ ti->pi = UserHeapAddressToUser(ti->kpi);
+ if (W32Thread->Desktop != NULL)
+ {
+ ti->Desktop = W32Thread->Desktop->DesktopInfo;
+ ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
+ }
+ else
+ {
+ ti->Desktop = NULL;
+ ti->DesktopHeapDelta = 0;
+ }
+
+ W32Thread->ThreadInfo = ti;
+ /* update the TEB */
+ Teb = NtCurrentTeb();
+ _SEH_TRY
+ {
+ ProbeForWrite(Teb,
+ sizeof(TEB),
+ sizeof(ULONG));
+
+ Teb->Win32ThreadInfo = UserHeapAddressToUser(W32Thread->ThreadInfo);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ return W32Thread->ThreadInfo;
+}
+
+
/* EOF */