Author: hbelusca Date: Sun Oct 20 22:35:15 2013 New Revision: 60726
URL: http://svn.reactos.org/svn/reactos?rev=60726&view=rev Log: [CONSRV][WIN32K] - Fix console palette setting; introduce the ConsoleMakePalettePublic control code for NtUserConsoleControl API which is called by the SetConsolePalette to make the given palette handle public (indeed, the caller to SetConsoleHandle gives to this API a GDI palette handle which is aimed at being used by another process, i.e. by CSRSS.EXE; in normal operation this is impossible unless saying to GDI that the handle is meant to be public; that's what it's done there).
Thanks to Aleksander and David (who provided tests) and Timo (see revision 60725) for having helped me in understanding what happened exactly there.
- Remove now-unneeded DPRINT1s and the hacked palette that was introduced in revision 60629/60641.
Part 1/2
Modified: trunk/reactos/win32ss/include/ntuser.h trunk/reactos/win32ss/user/ntuser/ntstubs.c trunk/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c trunk/reactos/win32ss/user/winsrv/consrv/conoutput.c
Modified: trunk/reactos/win32ss/include/ntuser.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/include/ntuser.h?re... ============================================================================== --- trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/include/ntuser.h [iso-8859-1] Sun Oct 20 22:35:15 2013 @@ -1571,6 +1571,7 @@ typedef enum _CONSOLECONTROL { GuiConsoleWndClassAtom, + ConsoleMakePalettePublic = 5, ConsoleAcquireDisplayOwnership, } CONSOLECONTROL, *PCONSOLECONTROL;
@@ -1579,7 +1580,7 @@ NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength); + IN ULONG ConsoleCtrlInfoLength);
HANDLE NTAPI
Modified: trunk/reactos/win32ss/user/ntuser/ntstubs.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/ntstubs... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/ntstubs.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/ntstubs.c [iso-8859-1] Sun Oct 20 22:35:15 2013 @@ -546,7 +546,7 @@ NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength) + IN ULONG ConsoleCtrlInfoLength) { NTSTATUS Status = STATUS_SUCCESS;
@@ -562,8 +562,8 @@ { _SEH2_TRY { + ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM)); ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); - ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM)); gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -575,8 +575,33 @@ break; }
+ case ConsoleMakePalettePublic: + { + _SEH2_TRY + { + ASSERT(ConsoleCtrlInfoLength == sizeof(HPALETTE)); + ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); + /* + * Make the palette handle public - Use the extended + * function introduced by Timo in revision 60725. + */ + GreSetObjectOwnerEx(*(HPALETTE*)ConsoleCtrlInfo, + GDI_OBJ_HMGR_PUBLIC, + GDIOBJFLAG_IGNOREPID); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + break; + } + case ConsoleAcquireDisplayOwnership: { + ERR("NtUserConsoleControl - ConsoleAcquireDisplayOwnership is UNIMPLEMENTED\n"); + Status = STATUS_NOT_IMPLEMENTED; break; }
Modified: trunk/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv/... ============================================================================== --- trunk/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c [iso-8859-1] Sun Oct 20 22:35:15 2013 @@ -237,8 +237,6 @@ { BOOL Success;
- DPRINT1("ConDrvSetConsolePalette\n"); - /* * Parameters validation */ @@ -256,11 +254,9 @@ ASSERT(Console == Buffer->Header.Console);
/* Change the palette */ - DPRINT1("ConDrvSetConsolePalette calling TermSetPalette\n"); Success = TermSetPalette(Console, PaletteHandle, PaletteUsage); if (Success) { - DPRINT1("TermSetPalette succeeded\n"); /* Free the old palette handle if there was already one set */ if ( Buffer->PaletteHandle != NULL && Buffer->PaletteHandle != PaletteHandle ) @@ -271,10 +267,6 @@ /* Save the new palette in the screen buffer */ Buffer->PaletteHandle = PaletteHandle; Buffer->PaletteUsage = PaletteUsage; - } - else - { - DPRINT1("TermSetPalette failed\n"); }
return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
Modified: trunk/reactos/win32ss/user/winsrv/consrv/conoutput.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/winsrv/consrv/... ============================================================================== --- trunk/reactos/win32ss/user/winsrv/consrv/conoutput.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/winsrv/consrv/conoutput.c [iso-8859-1] Sun Oct 20 22:35:15 2013 @@ -63,38 +63,7 @@ // PGRAPHICS_SCREEN_BUFFER Buffer; PCONSOLE_SCREEN_BUFFER Buffer;
- -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -******************************************************************************/ - -#define PALETTESIZE 256 - - LPLOGPALETTE LogPalette; /* Pointer to logical palette */ - PALETTEENTRY MyPalette[] = - { {0, 0, 0x80,0} , // 1 - {0, 0x80,0, 0} , // 2 - {0, 0, 0, 0} , // 0 - {0, 0x80,0x80,0} , // 3 - {0x80,0, 0, 0} , // 4 - {0x80,0, 0x80,0} , // 5 - {0x80,0x80,0, 0} , // 6 - {0xC0,0xC0,0xC0,0} , // 7 - {0x80,0x80,0x80,0} , // 8 - {0, 0, 0xFF,0} , // 9 - {0, 0xFF,0, 0} , // 10 - {0, 0xFF,0xFF,0} , // 11 - {0xFF,0, 0, 0} , // 12 - {0xFF,0, 0xFF,0} , // 13 - {0xFF,0xFF,0, 0} , // 14 - {0xFF,0xFF,0xFF,0} }; // 15 - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -******************************************************************************/ - - - DPRINT1("SrvSetConsolePalette\n"); + DPRINT("SrvSetConsolePalette\n");
// NOTE: Tests show that this function is used only for graphics screen buffers // and otherwise it returns FALSE + sets last error to invalid handle. @@ -111,50 +80,20 @@ &Buffer, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status;
- -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -******************************************************************************/ - - DPRINT1("HACK: FIXME: SrvSetConsolePalette - Use hacked palette for testing purposes!!\n"); - - LogPalette = (LPLOGPALETTE)ConsoleAllocHeap(HEAP_ZERO_MEMORY, - (sizeof(LOGPALETTE) + - (sizeof(PALETTEENTRY) * PALETTESIZE))); - if (LogPalette) - { - UINT i; - - LogPalette->palVersion = 0x300; - LogPalette->palNumEntries = PALETTESIZE; - - for (i = 0 ; i < PALETTESIZE ; i++) - { - LogPalette->palPalEntry[i] = MyPalette[i % sizeof(MyPalette)/sizeof(MyPalette[0])]; - } - - SetPaletteRequest->PaletteHandle = CreatePalette(LogPalette); - SetPaletteRequest->Usage = SYSPAL_NOSTATIC256; - ConsoleFreeHeap(LogPalette); - } - else - { - DPRINT1("SrvSetConsolePalette - Hacked LogPalette is NULL\n"); - } - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -******************************************************************************/ - - - DPRINT1("ConDrvSetConsolePalette calling...\n"); + /* + * Make the palette handle public, so that it can be + * used by other threads calling GDI functions on it. + * Indeed, the palette handle comes from a console app + * calling ourselves, running in CSRSS. + */ + NtUserConsoleControl(ConsoleMakePalettePublic, + &SetPaletteRequest->PaletteHandle, + sizeof(SetPaletteRequest->PaletteHandle));
Status = ConDrvSetConsolePalette(Buffer->Header.Console, Buffer, SetPaletteRequest->PaletteHandle, SetPaletteRequest->Usage); - - DPRINT1("ConDrvSetConsolePalette returned Status 0x%08lx\n", Status);
ConSrvReleaseScreenBuffer(Buffer, TRUE); return Status;