From c5b0cd477ff01e9b0a7d1670538a0134ab591252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 14 Oct 2013 20:17:17 +0000 Subject: [PATCH 01/36] [NTOS:HEADLESS]: Code formatting + s/tabs/spaces/ svn path=/trunk/; revision=60671 --- reactos/ntoskrnl/ex/hdlsterm.c | 217 +++++++++++++++++---------------- 1 file changed, 115 insertions(+), 102 deletions(-) diff --git a/reactos/ntoskrnl/ex/hdlsterm.c b/reactos/ntoskrnl/ex/hdlsterm.c index e47764c852b..d43a8515615 100644 --- a/reactos/ntoskrnl/ex/hdlsterm.c +++ b/reactos/ntoskrnl/ex/hdlsterm.c @@ -6,16 +6,16 @@ * PROGRAMMERS: ReactOS Portable Systems Group */ -/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/ #include #include -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ PHEADLESS_GLOBALS HeadlessGlobals; -/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/ FORCEINLINE KIRQL @@ -185,69 +185,69 @@ VOID NTAPI HdlspPutString(IN PUCHAR String) { - PUCHAR Dest = HeadlessGlobals->TmpBuffer; - UCHAR Char = 0; + PUCHAR Dest = HeadlessGlobals->TmpBuffer; + UCHAR Char = 0; - /* Scan each character */ - while (*String != ANSI_NULL) - { - /* Check for rotate, send existing buffer and restart from where we are */ - if (Dest >= &HeadlessGlobals->TmpBuffer[79]) - { - HeadlessGlobals->TmpBuffer[79] = ANSI_NULL; - HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); - Dest = HeadlessGlobals->TmpBuffer; - } - else - { - /* Get the current character and check for special graphical chars */ - Char = *String; - if (Char & 0x80) - { - switch (Char) - { - case 0xB0: case 0xB3: case 0xBA: - Char = '|'; - break; - case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF: - Char = '%'; - break; - case 0xB2: case 0xDB: - Char = '#'; - break; - case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF: - case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA: - Char = '+'; - break; - case 0xC4: - Char = '-'; - break; - case 0xCD: - Char = '='; - break; - } - } + /* Scan each character */ + while (*String != ANSI_NULL) + { + /* Check for rotate, send existing buffer and restart from where we are */ + if (Dest >= &HeadlessGlobals->TmpBuffer[79]) + { + HeadlessGlobals->TmpBuffer[79] = ANSI_NULL; + HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); + Dest = HeadlessGlobals->TmpBuffer; + } + else + { + /* Get the current character and check for special graphical chars */ + Char = *String; + if (Char & 0x80) + { + switch (Char) + { + case 0xB0: case 0xB3: case 0xBA: + Char = '|'; + break; + case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF: + Char = '%'; + break; + case 0xB2: case 0xDB: + Char = '#'; + break; + case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF: + case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA: + Char = '+'; + break; + case 0xC4: + Char = '-'; + break; + case 0xCD: + Char = '='; + break; + } + } - /* Anything else must be Unicode */ - if (Char & 0x80) - { - /* Can't do Unicode yet */ - UNIMPLEMENTED; - } - else - { - /* Add the modified char to the temporary buffer */ - *Dest++ = Char; - } - - /* Check the next char */ - String++; - } - } + /* Anything else must be Unicode */ + if (Char & 0x80) + { + /* Can't do Unicode yet */ + UNIMPLEMENTED; + } + else + { + /* Add the modified char to the temporary buffer */ + *Dest++ = Char; + } + + /* Check the next char */ + String++; + } + } - /* Finish and send */ - *Dest = ANSI_NULL; - HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); + /* Finish and send */ + *Dest = ANSI_NULL; + HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); } NTSTATUS @@ -265,7 +265,7 @@ HdlspDispatch(IN HEADLESS_CMD Command, PHEADLESS_RSP_GET_BYTE GetByte; NTSTATUS Status = STATUS_NOT_IMPLEMENTED; ASSERT(HeadlessGlobals != NULL); -// ASSERT(HeadlessGlobals->PageLockHandle != NULL); + // ASSERT(HeadlessGlobals->PageLockHandle != NULL); /* Ignore non-reentrant commands */ if ((Command != HeadlessCmdAddLogEntry) && @@ -290,7 +290,7 @@ HdlspDispatch(IN HEADLESS_CMD Command, switch (Command) { case HeadlessCmdEnableTerminal: - + { /* Make sure the caller passed valid data */ if (!(InputBuffer) || (InputBufferSize != sizeof(*EnableTerminal))) @@ -304,12 +304,13 @@ HdlspDispatch(IN HEADLESS_CMD Command, EnableTerminal = InputBuffer; Status = HdlspEnableTerminal(EnableTerminal->Enable); break; + } - case HeadlessCmdCheckForReboot: - break; - - case HeadlessCmdPutString: + case HeadlessCmdCheckForReboot: + break; + case HeadlessCmdPutString: + { /* Validate the existence of an input buffer */ if (!InputBuffer) { @@ -328,9 +329,10 @@ HdlspDispatch(IN HEADLESS_CMD Command, /* Return success either way */ Status = STATUS_SUCCESS; break; + } case HeadlessCmdClearDisplay: - + { /* Send the VT100 clear screen command if the terminal is enabled */ if (HeadlessGlobals->TerminalEnabled) { @@ -340,24 +342,25 @@ HdlspDispatch(IN HEADLESS_CMD Command, /* Return success either way */ Status = STATUS_SUCCESS; break; + } - case HeadlessCmdClearToEndOfDisplay: - break; - case HeadlessCmdClearToEndOfLine: - break; - case HeadlessCmdDisplayAttributesOff: - break; - case HeadlessCmdDisplayInverseVideo: - break; - case HeadlessCmdSetColor: - break; - case HeadlessCmdPositionCursor: - break; - case HeadlessCmdTerminalPoll: - break; + case HeadlessCmdClearToEndOfDisplay: + break; + case HeadlessCmdClearToEndOfLine: + break; + case HeadlessCmdDisplayAttributesOff: + break; + case HeadlessCmdDisplayInverseVideo: + break; + case HeadlessCmdSetColor: + break; + case HeadlessCmdPositionCursor: + break; + case HeadlessCmdTerminalPoll: + break; case HeadlessCmdGetByte: - + { /* Make sure the caller passed valid data */ if (!(OutputBuffer) || !(OutputBufferSize) || @@ -394,15 +397,17 @@ HdlspDispatch(IN HEADLESS_CMD Command, /* Return success either way */ Status = STATUS_SUCCESS; break; + } - case HeadlessCmdGetLine: - break; - case HeadlessCmdStartBugCheck: - break; - case HeadlessCmdDoBugCheckProcessing: - break; - case HeadlessCmdQueryInformation: + case HeadlessCmdGetLine: + break; + case HeadlessCmdStartBugCheck: + break; + case HeadlessCmdDoBugCheckProcessing: + break; + case HeadlessCmdQueryInformation: + { /* Make sure the caller passed valid data */ if (!(OutputBuffer) || !(OutputBufferSize) || @@ -441,12 +446,15 @@ HdlspDispatch(IN HEADLESS_CMD Command, /* All done */ Status = STATUS_SUCCESS; break; - case HeadlessCmdAddLogEntry: - break; - case HeadlessCmdDisplayLog: - break; - case HeadlessCmdSetBlueScreenData: + } + case HeadlessCmdAddLogEntry: + break; + case HeadlessCmdDisplayLog: + break; + + case HeadlessCmdSetBlueScreenData: + { /* Validate the existence of an input buffer */ if (!InputBuffer) { @@ -458,12 +466,15 @@ HdlspDispatch(IN HEADLESS_CMD Command, UNIMPLEMENTED; Status = STATUS_SUCCESS; break; - case HeadlessCmdSendBlueScreenData: - break; - case HeadlessCmdQueryGUID: - break; - case HeadlessCmdPutData: + } + case HeadlessCmdSendBlueScreenData: + break; + case HeadlessCmdQueryGUID: + break; + + case HeadlessCmdPutData: + { /* Validate the existence of an input buffer */ if (!(InputBuffer) || !(InputBufferSize)) { @@ -482,6 +493,7 @@ HdlspDispatch(IN HEADLESS_CMD Command, /* Return success either way */ Status = STATUS_SUCCESS; break; + } default: break; @@ -532,6 +544,7 @@ HeadlessDispatch(IN HEADLESS_CMD Command, RtlZeroMemory(OutputBuffer, *OutputBufferSize); } + return STATUS_SUCCESS; } From a0873a65ed61eb595e242aa74c7e202890f2ca78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 14 Oct 2013 20:38:02 +0000 Subject: [PATCH 02/36] [NTOS]: Moaaar s/tabs/spaces/ svn path=/trunk/; revision=60672 --- reactos/ntoskrnl/include/internal/hdl.h | 188 +++++++++++------------ reactos/ntoskrnl/include/internal/inbv.h | 22 +-- 2 files changed, 105 insertions(+), 105 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/hdl.h b/reactos/ntoskrnl/include/internal/hdl.h index 2bd0b2fe766..d6bd562c35f 100644 --- a/reactos/ntoskrnl/include/internal/hdl.h +++ b/reactos/ntoskrnl/include/internal/hdl.h @@ -12,12 +12,12 @@ // // Define this if you want debugging support // -#define _HDL_DEBUG_ 0x00 +#define _HDL_DEBUG_ 0x00 // // These define the Debug Masks Supported // -#define HDL_XXX_DEBUG 0x01 +#define HDL_XXX_DEBUG 0x01 // // Debug/Tracing support @@ -38,26 +38,26 @@ // typedef enum _HEADLESS_LOG_MESSAGE { - HeadlessLogDriverLoad = 1, - HeadlessLogDriverSuccess, - HeadlessLogDriverFailed, - HeadlessLogEventFailed, - HeadlessLogObjectFailed, - HeadlessLogDirectoryFailed, - HeadlessLogPnpFailed, - HeadlessLogPnpFailed2, - HeadlessLogBootDriversFailed, - HeadlessLogNtdllFailed, - HeadlessLogSystemDriversFailed, - HeadlessLogReassignSystemRootFailed, - HeadlessLogProtectSystemRootFailed, - HeadlessLogConvertSystemRootFailed, - HeadlessLogConvertDeviceNameFailed, - HeadlessLogGroupOrderListFailed, - HeadlessLogGroupTableFailed - // - // There are more, but not applicable to ReactOS, I believe - // + HeadlessLogDriverLoad = 1, + HeadlessLogDriverSuccess, + HeadlessLogDriverFailed, + HeadlessLogEventFailed, + HeadlessLogObjectFailed, + HeadlessLogDirectoryFailed, + HeadlessLogPnpFailed, + HeadlessLogPnpFailed2, + HeadlessLogBootDriversFailed, + HeadlessLogNtdllFailed, + HeadlessLogSystemDriversFailed, + HeadlessLogReassignSystemRootFailed, + HeadlessLogProtectSystemRootFailed, + HeadlessLogConvertSystemRootFailed, + HeadlessLogConvertDeviceNameFailed, + HeadlessLogGroupOrderListFailed, + HeadlessLogGroupTableFailed + // + // There are more, but not applicable to ReactOS, I believe + // } HEADLESS_LOG_MESSAGE; // @@ -65,8 +65,8 @@ typedef enum _HEADLESS_LOG_MESSAGE // typedef struct _HEADLESS_LOG_ENTRY { - SYSTEM_TIMEOFDAY_INFORMATION TimeOfEntry; - PWCHAR String; + SYSTEM_TIMEOFDAY_INFORMATION TimeOfEntry; + PWCHAR String; } HEADLESS_LOG_ENTRY, *PHEADLESS_LOG_ENTRY; // @@ -83,42 +83,42 @@ typedef struct _HEADLESS_CMD_SET_BLUE_SCREEN_DATA // typedef struct _HEADLESS_GLOBALS { - KSPIN_LOCK SpinLock; - HANDLE PageLockHandle; - PHEADLESS_LOG_ENTRY LogEntries; - PUCHAR TmpBuffer; - PUCHAR InputBuffer; + KSPIN_LOCK SpinLock; + HANDLE PageLockHandle; + PHEADLESS_LOG_ENTRY LogEntries; + PUCHAR TmpBuffer; + PUCHAR InputBuffer; PHEADLESS_CMD_SET_BLUE_SCREEN_DATA BlueScreenData; - union - { - struct - { - ULONG TerminalEnabled:1; - ULONG InBugCheck:1; - ULONG NewLogEntryAdded:1; - ULONG UsedBiosSettings:1; - ULONG InputProcessing:1; - ULONG InputLineDone:1; - ULONG ProcessingCmd:1; - ULONG TerminalParity:1; - ULONG TerminalStopBits:1; - ULONG TerminalPortNumber:3; - ULONG IsNonLegacyDevice:1; - }; - ULONG AllFlags; - }; - ULONG TerminalBaudRate; - ULONG TerminalPort; - PUCHAR TerminalPortAddress; - LARGE_INTEGER DelayTime; - ULONG MicroSecondsDelayTime; - UCHAR TerminalType; - SIZE_T InputBufferIndex; - USHORT LogEntryLast; - USHORT LogEntryStart; - GUID SystemGUID; - BOOLEAN IsMMIODevice; - BOOLEAN IsLastCharCR; + union + { + struct + { + ULONG TerminalEnabled:1; + ULONG InBugCheck:1; + ULONG NewLogEntryAdded:1; + ULONG UsedBiosSettings:1; + ULONG InputProcessing:1; + ULONG InputLineDone:1; + ULONG ProcessingCmd:1; + ULONG TerminalParity:1; + ULONG TerminalStopBits:1; + ULONG TerminalPortNumber:3; + ULONG IsNonLegacyDevice:1; + }; + ULONG AllFlags; + }; + ULONG TerminalBaudRate; + ULONG TerminalPort; + PUCHAR TerminalPortAddress; + LARGE_INTEGER DelayTime; + ULONG MicroSecondsDelayTime; + UCHAR TerminalType; + SIZE_T InputBufferIndex; + USHORT LogEntryLast; + USHORT LogEntryStart; + GUID SystemGUID; + BOOLEAN IsMMIODevice; + BOOLEAN IsLastCharCR; } HEADLESS_GLOBALS, *PHEADLESS_GLOBALS; // @@ -126,43 +126,43 @@ typedef struct _HEADLESS_GLOBALS // typedef enum _HEADLESS_CMD { - HeadlessCmdEnableTerminal = 1, - HeadlessCmdCheckForReboot, - HeadlessCmdPutString, - HeadlessCmdClearDisplay, - HeadlessCmdClearToEndOfDisplay, - HeadlessCmdClearToEndOfLine, - HeadlessCmdDisplayAttributesOff, - HeadlessCmdDisplayInverseVideo, - HeadlessCmdSetColor, - HeadlessCmdPositionCursor, - HeadlessCmdTerminalPoll, - HeadlessCmdGetByte, - HeadlessCmdGetLine, - HeadlessCmdStartBugCheck, - HeadlessCmdDoBugCheckProcessing, - HeadlessCmdQueryInformation, - HeadlessCmdAddLogEntry, - HeadlessCmdDisplayLog, - HeadlessCmdSetBlueScreenData, - HeadlessCmdSendBlueScreenData, - HeadlessCmdQueryGUID, - HeadlessCmdPutData + HeadlessCmdEnableTerminal = 1, + HeadlessCmdCheckForReboot, + HeadlessCmdPutString, + HeadlessCmdClearDisplay, + HeadlessCmdClearToEndOfDisplay, + HeadlessCmdClearToEndOfLine, + HeadlessCmdDisplayAttributesOff, + HeadlessCmdDisplayInverseVideo, + HeadlessCmdSetColor, + HeadlessCmdPositionCursor, + HeadlessCmdTerminalPoll, + HeadlessCmdGetByte, + HeadlessCmdGetLine, + HeadlessCmdStartBugCheck, + HeadlessCmdDoBugCheckProcessing, + HeadlessCmdQueryInformation, + HeadlessCmdAddLogEntry, + HeadlessCmdDisplayLog, + HeadlessCmdSetBlueScreenData, + HeadlessCmdSendBlueScreenData, + HeadlessCmdQueryGUID, + HeadlessCmdPutData } HEADLESS_CMD, *PHEADLESS_CMD; typedef enum _HEADLESS_TERM_PORT_TYPE { - HeadlessUndefinedPortType = 0, - HeadlessSerialPort + HeadlessUndefinedPortType = 0, + HeadlessSerialPort } HEADLESS_TERM_PORT_TYPE, *PHEADLESS_TERM_PORT_TYPE; typedef enum _HEADLESS_TERM_SERIAL_PORT { - SerialPortUndefined = 0, - ComPort1, - ComPort2, - ComPort3, - ComPort4 + SerialPortUndefined = 0, + ComPort1, + ComPort2, + ComPort3, + ComPort4 } HEADLESS_TERM_SERIAL_PORT, *PHEADLESS_TERM_SERIAL_PORT; typedef struct _HEADLESS_RSP_QUERY_INFO @@ -189,7 +189,7 @@ typedef struct _HEADLESS_CMD_ENABLE_TERMINAL typedef struct _HEADLESS_CMD_PUT_STRING { - UCHAR String[1]; + UCHAR String[1]; } HEADLESS_CMD_PUT_STRING, *PHEADLESS_CMD_PUT_STRING; typedef struct _HEADLESS_RSP_GET_BYTE @@ -200,11 +200,11 @@ typedef struct _HEADLESS_RSP_GET_BYTE NTSTATUS NTAPI HeadlessDispatch( - IN HEADLESS_CMD Command, - IN PVOID InputBuffer, - IN SIZE_T InputBufferSize, - OUT PVOID OutputBuffer, - OUT PSIZE_T OutputBufferSize + IN HEADLESS_CMD Command, + IN PVOID InputBuffer, + IN SIZE_T InputBufferSize, + OUT PVOID OutputBuffer, + OUT PSIZE_T OutputBufferSize ); // diff --git a/reactos/ntoskrnl/include/internal/inbv.h b/reactos/ntoskrnl/include/internal/inbv.h index 867c39d2103..140761045e1 100644 --- a/reactos/ntoskrnl/include/internal/inbv.h +++ b/reactos/ntoskrnl/include/internal/inbv.h @@ -76,35 +76,35 @@ NTAPI InbvIndicateProgress( VOID ); - + VOID NTAPI InbvPortEnableFifo( - IN ULONG PortId, - IN BOOLEAN Enable + IN ULONG PortId, + IN BOOLEAN Enable ); VOID NTAPI InbvPortPutByte( - IN ULONG PortId, - IN BOOLEAN Output + IN ULONG PortId, + IN BOOLEAN Output ); VOID NTAPI InbvPortTerminate( - IN ULONG PortId + IN ULONG PortId ); BOOLEAN NTAPI InbvPortInitialize( - IN ULONG BaudRate, - IN ULONG PortNumber, - IN PUCHAR PortAddress, - OUT PULONG PortId, - IN BOOLEAN IsMMIODevice + IN ULONG BaudRate, + IN ULONG PortNumber, + IN PUCHAR PortAddress, + OUT PULONG PortId, + IN BOOLEAN IsMMIODevice ); BOOLEAN From 11d262db2f19938f01c8d418ca462853549bdeca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 14 Oct 2013 20:47:04 +0000 Subject: [PATCH 03/36] [FREELDR:HEADLESS]: Code formatting only. svn path=/trunk/; revision=60673 --- .../boot/freeldr/freeldr/windows/headless.c | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/reactos/boot/freeldr/freeldr/windows/headless.c b/reactos/boot/freeldr/freeldr/windows/headless.c index 515593adf46..4c0c3bf6782 100644 --- a/reactos/boot/freeldr/freeldr/windows/headless.c +++ b/reactos/boot/freeldr/freeldr/windows/headless.c @@ -45,7 +45,7 @@ VOID WinLdrLoadGUID(OUT PGUID SystemGuid) { PSYSID_UUID_ENTRY CurrentAddress; - + CurrentAddress = (PSYSID_UUID_ENTRY)0xE0000; while (CurrentAddress < (PSYSID_UUID_ENTRY)0x100000) { @@ -56,7 +56,7 @@ WinLdrLoadGUID(OUT PGUID SystemGuid) } CurrentAddress = (PSYSID_UUID_ENTRY)((ULONG_PTR)CurrentAddress + 1); } - + RtlZeroMemory(SystemGuid, SYSID_UUID_DATA_SIZE); } @@ -78,7 +78,7 @@ WinLdrPortInitialize(IN ULONG BaudRate, { switch (PortNumber) { - case 1: + case 1: PortAddress = (PUCHAR)0x3F8; break; @@ -111,7 +111,7 @@ WinLdrPortInitialize(IN ULONG BaudRate, PortNumber = 1; } } - + /* Not yet supported */ ASSERT(LoaderRedirectionInformation.IsMMIODevice == FALSE); @@ -128,22 +128,22 @@ WinLdrPortInitialize(IN ULONG BaudRate, return TRUE; } } - + return FALSE; } VOID WinLdrPortPutByte(IN ULONG PortId, - IN UCHAR Data) + IN UCHAR Byte) { - CpPutByte(&Port[PortId], Data); + CpPutByte(&Port[PortId], Byte); } BOOLEAN -WinLdrPortGetByte(IN ULONG PortId, - OUT PUCHAR Data) +WinLdrPortGetByte(IN ULONG PortId, + OUT PUCHAR Byte) { - return CpGetByte(&Port[PortId], Data, TRUE, FALSE) == CP_GET_SUCCESS; + return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS; } BOOLEAN @@ -156,7 +156,7 @@ WinLdrPortPollOnly(IN ULONG PortId) VOID WinLdrEnableFifo(IN ULONG PortId, - IN BOOLEAN Enable) + IN BOOLEAN Enable) { CpEnableFifo(Port[PortId].Address, Enable); } @@ -168,11 +168,11 @@ WinLdrInitializeHeadlessPort(VOID) PUCHAR PortAddress; PCHAR AnsiReset = "\x1B[m"; ULONG i; - + PortNumber = LoaderRedirectionInformation.PortNumber; PortAddress = LoaderRedirectionInformation.PortAddress; BaudRate = LoaderRedirectionInformation.BaudRate; - + /* Pick a port address */ if (PortNumber) { @@ -204,7 +204,7 @@ WinLdrInitializeHeadlessPort(VOID) WinLdrTerminalConnected = FALSE; return; } - + /* Call arch code to initialize the port */ PortAddress = LoaderRedirectionInformation.PortAddress; WinLdrTerminalConnected = WinLdrPortInitialize( @@ -227,9 +227,9 @@ WinLdrInitializeHeadlessPort(VOID) BaudRate = 9600; LoaderRedirectionInformation.BaudRate = BaudRate; } - + WinLdrTerminalDelay = (10 * 1000 * 1000) / (BaudRate / 10) / 6; - + /* Sent an ANSI reset sequence to get the terminal up and running */ for (i = 0; i < strlen(AnsiReset); i++) { @@ -277,7 +277,7 @@ WinLdrSetupEms(IN PCHAR BootOptions) } } } - + /* Use a direction baudrate if one was given */ RedirectPort = strstr(BootOptions, "/redirectbaudrate="); if (RedirectPort) @@ -299,7 +299,7 @@ WinLdrSetupEms(IN PCHAR BootOptions) LoaderRedirectionInformation.BaudRate = 9600; } } - + /* Enable headless support if parameters were found */ if (LoaderRedirectionInformation.PortNumber) { @@ -307,7 +307,9 @@ WinLdrSetupEms(IN PCHAR BootOptions) { LoaderRedirectionInformation.BaudRate = 9600; } - + WinLdrInitializeHeadlessPort(); } } + +/* EOF */ From 6b16043963e2dfc1458c89a6c8c9bb27373e88a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 14 Oct 2013 20:50:44 +0000 Subject: [PATCH 04/36] [NTOS:INBV]: Fix parameter name and type. svn path=/trunk/; revision=60674 --- reactos/ntoskrnl/inbv/inbvport.c | 24 ++++++++++++------------ reactos/ntoskrnl/include/internal/inbv.h | 16 ++++++++-------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/reactos/ntoskrnl/inbv/inbvport.c b/reactos/ntoskrnl/inbv/inbvport.c index d0509becce3..e95e8256783 100644 --- a/reactos/ntoskrnl/inbv/inbvport.c +++ b/reactos/ntoskrnl/inbv/inbvport.c @@ -35,11 +35,20 @@ InbvPortPollOnly(IN ULONG PortId) BOOLEAN NTAPI -InbvPortGetByte(IN ULONG PortId, - OUT PUCHAR Char) +InbvPortGetByte(IN ULONG PortId, + OUT PUCHAR Byte) { /* Read a byte from the port */ - return CpGetByte(&Port[PortId], Char, TRUE, FALSE) == CP_GET_SUCCESS; + return CpGetByte(&Port[PortId], Byte, TRUE, FALSE) == CP_GET_SUCCESS; +} + +VOID +NTAPI +InbvPortPutByte(IN ULONG PortId, + IN UCHAR Byte) +{ + /* Send the byte */ + CpPutByte(&Port[PortId], Byte); } VOID @@ -51,15 +60,6 @@ InbvPortEnableFifo(IN ULONG PortId, CpEnableFifo(Port[PortId].Address, Enable); } -VOID -NTAPI -InbvPortPutByte(IN ULONG PortId, - IN BOOLEAN Output) -{ - /* Send the byte */ - CpPutByte(&Port[PortId], Output); -} - VOID NTAPI InbvPortTerminate(IN ULONG PortId) diff --git a/reactos/ntoskrnl/include/internal/inbv.h b/reactos/ntoskrnl/include/internal/inbv.h index 140761045e1..84d44ba03aa 100644 --- a/reactos/ntoskrnl/include/internal/inbv.h +++ b/reactos/ntoskrnl/include/internal/inbv.h @@ -84,11 +84,18 @@ InbvPortEnableFifo( IN BOOLEAN Enable ); +BOOLEAN +NTAPI +InbvPortGetByte( + IN ULONG PortId, + OUT PUCHAR Byte +); + VOID NTAPI InbvPortPutByte( IN ULONG PortId, - IN BOOLEAN Output + IN UCHAR Byte ); VOID @@ -113,11 +120,4 @@ InbvPortPollOnly( IN ULONG PortId ); -BOOLEAN -NTAPI -InbvPortGetByte( - IN ULONG PortId, - OUT PUCHAR Char -); - extern BOOLEAN InbvBootDriverInstalled; From 37d5eaa1f58c31ecfc12e3fe1709d43ebf5ac247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 14 Oct 2013 21:29:17 +0000 Subject: [PATCH 05/36] [NTOS:HEADLESS] - Fix the name of a function. - Fix HdlspSendStringAtBaud (we started displaying string at its second character) and fix HdlspPutData (data was sent erroneous, shifted by 1). Fix SAC display. svn path=/trunk/; revision=60675 --- reactos/ntoskrnl/ex/hdlsterm.c | 172 ++++++++++++++++----------------- 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/reactos/ntoskrnl/ex/hdlsterm.c b/reactos/ntoskrnl/ex/hdlsterm.c index d43a8515615..b1c0ff02a39 100644 --- a/reactos/ntoskrnl/ex/hdlsterm.c +++ b/reactos/ntoskrnl/ex/hdlsterm.c @@ -38,7 +38,7 @@ HdlspAcquireGlobalLock(VOID) FORCEINLINE VOID -HdlspReleaselobalLock(IN KIRQL OldIrql) +HdlspReleaseGlobalLock(IN KIRQL OldIrql) { /* Only release the lock if we aren't bugchecking */ if (OldIrql != 0xFF) @@ -56,12 +56,93 @@ NTAPI HdlspSendStringAtBaud(IN PUCHAR String) { /* Send every byte */ - while (*String++ != ANSI_NULL) + while (*String != ANSI_NULL) { - InbvPortPutByte(HeadlessGlobals->TerminalPort, *String); + InbvPortPutByte(HeadlessGlobals->TerminalPort, *String++); } } +VOID +NTAPI +HdlspPutData(IN PUCHAR Data, + IN ULONG DataSize) +{ + ULONG i; + for (i = 0; i < DataSize; i++) + { + InbvPortPutByte(HeadlessGlobals->TerminalPort, Data[i]); + } +} + +VOID +NTAPI +HdlspPutString(IN PUCHAR String) +{ + PUCHAR Dest = HeadlessGlobals->TmpBuffer; + UCHAR Char = 0; + + /* Scan each character */ + while (*String != ANSI_NULL) + { + /* Check for rotate, send existing buffer and restart from where we are */ + if (Dest >= &HeadlessGlobals->TmpBuffer[79]) + { + HeadlessGlobals->TmpBuffer[79] = ANSI_NULL; + HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); + Dest = HeadlessGlobals->TmpBuffer; + } + else + { + /* Get the current character and check for special graphical chars */ + Char = *String; + if (Char & 0x80) + { + switch (Char) + { + case 0xB0: case 0xB3: case 0xBA: + Char = '|'; + break; + case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF: + Char = '%'; + break; + case 0xB2: case 0xDB: + Char = '#'; + break; + case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF: + case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA: + Char = '+'; + break; + case 0xC4: + Char = '-'; + break; + case 0xCD: + Char = '='; + break; + } + } + + /* Anything else must be Unicode */ + if (Char & 0x80) + { + /* Can't do Unicode yet */ + UNIMPLEMENTED; + } + else + { + /* Add the modified char to the temporary buffer */ + *Dest++ = Char; + } + + /* Check the next char */ + String++; + } + } + + /* Finish and send */ + *Dest = ANSI_NULL; + HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); +} + NTSTATUS NTAPI HdlspEnableTerminal(IN BOOLEAN Enable) @@ -169,87 +250,6 @@ HeadlessInit(IN PLOADER_PARAMETER_BLOCK LoaderBlock) HdlspEnableTerminal(TRUE); } -VOID -NTAPI -HdlspPutData(IN PUCHAR Data, - IN ULONG DataSize) -{ - ULONG i; - for (i = 0; i < DataSize; i++) - { - InbvPortPutByte(HeadlessGlobals->TerminalPort, Data[i]++); - } -} - -VOID -NTAPI -HdlspPutString(IN PUCHAR String) -{ - PUCHAR Dest = HeadlessGlobals->TmpBuffer; - UCHAR Char = 0; - - /* Scan each character */ - while (*String != ANSI_NULL) - { - /* Check for rotate, send existing buffer and restart from where we are */ - if (Dest >= &HeadlessGlobals->TmpBuffer[79]) - { - HeadlessGlobals->TmpBuffer[79] = ANSI_NULL; - HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); - Dest = HeadlessGlobals->TmpBuffer; - } - else - { - /* Get the current character and check for special graphical chars */ - Char = *String; - if (Char & 0x80) - { - switch (Char) - { - case 0xB0: case 0xB3: case 0xBA: - Char = '|'; - break; - case 0xB1: case 0xDC: case 0xDD: case 0xDE: case 0xDF: - Char = '%'; - break; - case 0xB2: case 0xDB: - Char = '#'; - break; - case 0xA9: case 0xAA: case 0xBB: case 0xBC: case 0xBF: - case 0xC0: case 0xC8: case 0xC9: case 0xD9: case 0xDA: - Char = '+'; - break; - case 0xC4: - Char = '-'; - break; - case 0xCD: - Char = '='; - break; - } - } - - /* Anything else must be Unicode */ - if (Char & 0x80) - { - /* Can't do Unicode yet */ - UNIMPLEMENTED; - } - else - { - /* Add the modified char to the temporary buffer */ - *Dest++ = Char; - } - - /* Check the next char */ - String++; - } - } - - /* Finish and send */ - *Dest = ANSI_NULL; - HdlspSendStringAtBaud(HeadlessGlobals->TmpBuffer); -} - NTSTATUS NTAPI HdlspDispatch(IN HEADLESS_CMD Command, @@ -277,13 +277,13 @@ HdlspDispatch(IN HEADLESS_CMD Command, if (HeadlessGlobals->ProcessingCmd) { - HdlspReleaselobalLock(OldIrql); + HdlspReleaseGlobalLock(OldIrql); return STATUS_UNSUCCESSFUL; } /* Don't allow these commands next time */ HeadlessGlobals->ProcessingCmd = TRUE; - HdlspReleaselobalLock(OldIrql); + HdlspReleaseGlobalLock(OldIrql); } /* Handle each command */ From 1293634a0683513de5a88fc11c3f75aa4eedadfe Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 14 Oct 2013 21:51:07 +0000 Subject: [PATCH 06/36] - Return the right error if hot key registered outside of the thread. svn path=/trunk/; revision=60676 --- reactos/win32ss/user/ntuser/hotkey.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/win32ss/user/ntuser/hotkey.c b/reactos/win32ss/user/ntuser/hotkey.c index 0b881c81398..c23cf3810b0 100644 --- a/reactos/win32ss/user/ntuser/hotkey.c +++ b/reactos/win32ss/user/ntuser/hotkey.c @@ -512,6 +512,7 @@ NtUserRegisterHotKey(HWND hWnd, /* Fix wine msg "Window on another thread" test_hotkey */ if (pWnd->head.pti != gptiCurrent) { + EngSetLastError(ERROR_WINDOW_OF_OTHER_THREAD); WARN("Must be from the same Thread.\n"); goto cleanup; } From 5dc2b873948b9eda4e737aba1921a086f888ab7b Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 15 Oct 2013 07:05:17 +0000 Subject: [PATCH 07/36] [Win32k] - Fix more wine msg test_hotkey tests, down to seven. svn path=/trunk/; revision=60677 --- reactos/win32ss/user/ntuser/hotkey.c | 30 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/reactos/win32ss/user/ntuser/hotkey.c b/reactos/win32ss/user/ntuser/hotkey.c index c23cf3810b0..5b2ed36fa3c 100644 --- a/reactos/win32ss/user/ntuser/hotkey.c +++ b/reactos/win32ss/user/ntuser/hotkey.c @@ -195,7 +195,8 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) if (pHotKey) { - TRACE("Hot key Found\n"); + TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id); + /* FIXME: See comment about "UserDebuggerHotKey" on top of this file. */ if (pHotKey->id == IDHK_SHIFTF12 || pHotKey->id == IDHK_F12) { @@ -210,8 +211,6 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) /* Process hotkey if it is key up event */ if (!bIsDown) { - TRACE("Hot key pressed (pWnd %p, id %d)\n", pHotKey->pWnd, pHotKey->id); - /* WIN and F12 keys are not hardcoded here. See comments on top of this file. */ if (pHotKey->id == IDHK_WINKEY && bWinHotkeyActive == TRUE) { @@ -222,15 +221,27 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0); //ptiLastInput = pWnd->head.pti; bWinHotkeyActive = FALSE; - return TRUE; + return FALSE; } } + } + else + { /* The user pressed the win key */ + if (pHotKey->id == IDHK_WINKEY) + { + bWinHotkeyActive = TRUE; + return FALSE; + } + } + if (bIsDown) + { if (!pHotKey->pWnd) { TRACE("UPTM Hot key Id %d Key %d\n",pHotKey->id, wVk ); UserPostThreadMessage(pHotKey->pti, WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk)); //ptiLastInput = pHotKey->pti; + return TRUE; /* Don't send any message */ } else { @@ -248,23 +259,22 @@ co_UserProcessHotKeys(WORD wVk, BOOL bIsDown) pWnd = pHotKey->pWnd; } if (pWnd) - { - if (pWnd == pWnd->head.rpdesk->pDeskInfo->spwndShell && pHotKey->id == SC_TASKLIST) + { // pWnd->head.rpdesk->pDeskInfo->spwndShell needs testing. + if (pWnd == ValidateHwndNoErr(InputWindowStation->ShellWindow) && pHotKey->id == SC_TASKLIST) { ERR("Sending to shell window w/o IDHK_WINKEY..\n"); UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_TASKLIST, 0); } else { + TRACE("UPM Hot key Id %d Key %d\n",pHotKey->id, wVk ); UserPostMessage(UserHMGetHandle(pWnd), WM_HOTKEY, pHotKey->id, MAKELONG(fModifiers, wVk)); } //ptiLastInput = pWnd->head.pti; + return TRUE; /* Don't send any message */ } } - return TRUE; /* Don't send any message */ } - else /* The user pressed the win key */ - if (pHotKey->id == IDHK_WINKEY) bWinHotkeyActive = TRUE; } return FALSE; } @@ -558,7 +568,7 @@ NtUserUnregisterHotKey(HWND hWnd, int id) { PHOT_KEY pHotKey = gphkFirst, phkNext, *pLink = &gphkFirst; BOOL bRet = FALSE; - PWND pWnd; + PWND pWnd = NULL; TRACE("Enter NtUserUnregisterHotKey\n"); UserEnterExclusive(); From 4f2b6c67022f85ef62400133686da89f36a593ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Tue, 15 Oct 2013 16:45:52 +0000 Subject: [PATCH 08/36] [USETUP] - Fix translations of booloader installation menu (see rev.48703). ACHTUNG ACHTUNG!! Greek and Spanish people, please review the translation fix and provide patches if needed!! - Update French translation. CORE-7516 #resolve #comment Committed in revision r60678. svn path=/trunk/; revision=60678 --- reactos/base/setup/usetup/lang/el-GR.h | 4 ++-- reactos/base/setup/usetup/lang/es-ES.h | 4 ++-- reactos/base/setup/usetup/lang/fr-FR.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/reactos/base/setup/usetup/lang/el-GR.h b/reactos/base/setup/usetup/lang/el-GR.h index 19d387c9c6e..fd5cac13c73 100644 --- a/reactos/base/setup/usetup/lang/el-GR.h +++ b/reactos/base/setup/usetup/lang/el-GR.h @@ -1009,13 +1009,13 @@ static MUI_ENTRY elGRBootLoaderEntries[] = { 8, 12, - "Install bootloader on the harddisk (MBR and VBR).", + "„š¡˜«á©«˜©ž «¦¬ bootloader ©«¦ ©¡¢ž¨æ ›å©¡¦ (MBR and VBR).", TEXT_STYLE_NORMAL }, { 8, 13, - "Install bootloader on the harddisk (VBR only).", + "„š¡˜«á©«˜©ž «¦¬ bootloader ©«¦ ©¡¢ž¨æ ›å©¡¦ (VBR only).", TEXT_STYLE_NORMAL }, { diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index 5799f3d7dfc..930accac885 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -992,13 +992,13 @@ static MUI_ENTRY esESBootLoaderEntries[] = { 8, 12, - "Install bootloader on the harddisk (MBR and VBR).", + "Instalar cargador de arranque en el disco duro (MBR and VBR).", TEXT_STYLE_NORMAL }, { 8, 13, - "Install bootloader on the harddisk (VBR only).", + "Instalar cargador de arranque en el disco duro (VBR only).", TEXT_STYLE_NORMAL }, { diff --git a/reactos/base/setup/usetup/lang/fr-FR.h b/reactos/base/setup/usetup/lang/fr-FR.h index 2a1429108a7..7712bbe48e9 100644 --- a/reactos/base/setup/usetup/lang/fr-FR.h +++ b/reactos/base/setup/usetup/lang/fr-FR.h @@ -998,13 +998,13 @@ static MUI_ENTRY frFRBootLoaderEntries[] = { 8, 12, - "Installer le chargeur de d‚marrage sur le disque (MBR et VBR).", + "Installer le chargeur de d‚marrage sur le disque dur (MBR et VBR).", TEXT_STYLE_NORMAL }, { 8, 13, - "Installer le chargeur de d‚marrage sur le disque (VBR seulement).", + "Installer le chargeur de d‚marrage sur le disque dur (VBR seulement).", TEXT_STYLE_NORMAL }, { From 769ec79f16358778ae193658b664786f155e0675 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 15 Oct 2013 22:14:48 +0000 Subject: [PATCH 09/36] [Win32ss] - Prevent a potential kernel exception. svn path=/trunk/; revision=60682 --- reactos/win32ss/user/user32/windows/prop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/win32ss/user/user32/windows/prop.c b/reactos/win32ss/user/user32/windows/prop.c index 8f9b1b8c2c4..1b06d7f58bb 100644 --- a/reactos/win32ss/user/user32/windows/prop.c +++ b/reactos/win32ss/user/user32/windows/prop.c @@ -53,6 +53,7 @@ IntGetProp(HWND hWnd, ATOM Atom) for (i = 0; i < pWnd->PropListItems; i++ ) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); + if (!Property) break; if (Property->Atom == Atom) { return(Property); From 512ac8d32c566c83af01e3ee8c3eec300409f6e1 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 15 Oct 2013 22:16:31 +0000 Subject: [PATCH 10/36] [Win32ss] - Prevent a potential kernel exception. svn path=/trunk/; revision=60683 --- reactos/win32ss/user/ntuser/prop.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/win32ss/user/ntuser/prop.c b/reactos/win32ss/user/ntuser/prop.c index 5ffc7b74ec5..9b03ba45448 100644 --- a/reactos/win32ss/user/ntuser/prop.c +++ b/reactos/win32ss/user/ntuser/prop.c @@ -21,6 +21,7 @@ IntGetProp(PWND Window, ATOM Atom) while (ListEntry != &Window->PropListHead) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); + if (!Property) break; if (Property->Atom == Atom) { return(Property); From 1a21c35d0242c3f5d51c0ee9a3b1a67c413c3b4d Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 16 Oct 2013 00:11:23 +0000 Subject: [PATCH 11/36] - Properly remove window properties when destroying the window. svn path=/trunk/; revision=60684 --- reactos/win32ss/user/ntuser/prop.c | 23 +++++++++++++++++++++-- reactos/win32ss/user/ntuser/prop.h | 1 + reactos/win32ss/user/ntuser/window.c | 11 ++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/reactos/win32ss/user/ntuser/prop.c b/reactos/win32ss/user/ntuser/prop.c index 9b03ba45448..105aa8972e7 100644 --- a/reactos/win32ss/user/ntuser/prop.c +++ b/reactos/win32ss/user/ntuser/prop.c @@ -16,12 +16,12 @@ IntGetProp(PWND Window, ATOM Atom) { PLIST_ENTRY ListEntry; PPROPERTY Property; + int i; ListEntry = Window->PropListHead.Flink; - while (ListEntry != &Window->PropListHead) + for (i = 0; i < Window->PropListItems; i++ ) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); - if (!Property) break; if (Property->Atom == Atom) { return(Property); @@ -79,6 +79,25 @@ IntSetProp(PWND pWnd, ATOM Atom, HANDLE Data) return TRUE; } +VOID FASTCALL +IntRemoveWindowProp(PWND Window) +{ + PLIST_ENTRY ListEntry; + PPROPERTY Property; + int i, Count = Window->PropListItems; + + ListEntry = Window->PropListHead.Flink; + for (i = 0; i < Count; i++ ) + { + Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); + ListEntry = ListEntry->Flink; + RemoveEntryList(&Property->PropListEntry); + UserHeapFree(Property); + Window->PropListItems--; + } + return; +} + /* FUNCTIONS *****************************************************************/ NTSTATUS APIENTRY diff --git a/reactos/win32ss/user/ntuser/prop.h b/reactos/win32ss/user/ntuser/prop.h index 9ba3eaf0260..fdde50a5bea 100644 --- a/reactos/win32ss/user/ntuser/prop.h +++ b/reactos/win32ss/user/ntuser/prop.h @@ -4,3 +4,4 @@ PPROPERTY FASTCALL IntGetProp(PWND,ATOM); BOOL FASTCALL IntRemoveProp(PWND,ATOM); BOOL FASTCALL IntSetProp(PWND, ATOM, HANDLE); HANDLE FASTCALL UserGetProp(PWND, ATOM); +VOID FASTCALL IntRemoveWindowProp(PWND Window); diff --git a/reactos/win32ss/user/ntuser/window.c b/reactos/win32ss/user/ntuser/window.c index 5aa8ee92d6c..52255f3e438 100644 --- a/reactos/win32ss/user/ntuser/window.c +++ b/reactos/win32ss/user/ntuser/window.c @@ -426,8 +426,6 @@ static LRESULT co_UserFreeWindow(PWND Window, PWND Child; PMENU_OBJECT Menu; BOOLEAN BelongsToThreadData; - PLIST_ENTRY ListEntry; - PPROPERTY Property; ASSERT(Window); @@ -556,12 +554,11 @@ static LRESULT co_UserFreeWindow(PWND Window, IntUnlinkWindow(Window); - ListEntry = Window->PropListHead.Flink; - while (ListEntry != &Window->PropListHead) + if (Window->PropListItems) { - Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); - ListEntry = ListEntry->Flink; - IntRemoveProp(Window, Property->Atom); + IntRemoveWindowProp(Window); + TRACE("Window->PropListItems %d\n",Window->PropListItems); + ASSERT(Window->PropListItems==0); } UserReferenceObject(Window); From 3586cb163507b6e267ebb652caf078485df9dbd1 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Wed, 16 Oct 2013 19:13:49 +0000 Subject: [PATCH 12/36] [shell32] - Add an initial stub for CMenuBand that creates a menu bar and fills it with contents. However its still not functional svn path=/trunk/; revision=60690 --- reactos/dll/win32/shell32/CMenuBand.cpp | 383 +++++++++++++++++++++--- reactos/dll/win32/shell32/CMenuBand.h | 46 ++- reactos/dll/win32/shell32/precomp.h | 1 + 3 files changed, 378 insertions(+), 52 deletions(-) diff --git a/reactos/dll/win32/shell32/CMenuBand.cpp b/reactos/dll/win32/shell32/CMenuBand.cpp index 163aa87d137..bc3b18ff07d 100644 --- a/reactos/dll/win32/shell32/CMenuBand.cpp +++ b/reactos/dll/win32/shell32/CMenuBand.cpp @@ -7,57 +7,368 @@ */ #include "precomp.h" +#include WINE_DEFAULT_DEBUG_CHANNEL(CMenuBand); -HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi) + +BOOL +AllocAndGetMenuString(HMENU hMenu, UINT ItemIDByPosition, WCHAR** String) { - UNIMPLEMENTED; + int Length; + + Length = GetMenuStringW(hMenu, ItemIDByPosition, NULL, 0, MF_BYPOSITION); + + if(!Length) + return FALSE; + + /* Also allocate space for the terminating NULL character */ + ++Length; + *String = (PWSTR)HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR)); + + GetMenuStringW(hMenu, ItemIDByPosition, *String, Length, MF_BYPOSITION); + + return TRUE; +} + +CMenuStaticToolbar::CMenuStaticToolbar(CMenuBand *menuBand) +{ + m_menuBand = menuBand; + + + m_menuBand = NULL; + m_hwnd = NULL; + m_hmenu = NULL; + m_hwndOwner = NULL; + m_dwMenuFlags = NULL; +} + +HRESULT CMenuStaticToolbar::GetMenu( + HMENU *phmenu, + HWND *phwnd, + DWORD *pdwFlags) +{ + *phmenu = m_hmenu; + *phwnd = m_hwndOwner; + *pdwFlags = m_dwMenuFlags; + return S_OK; } -HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow) +HRESULT CMenuStaticToolbar::SetMenu( + HMENU hmenu, + HWND hwnd, + DWORD dwFlags) { - UNIMPLEMENTED; + if (!hwnd) + return E_FAIL; + + m_hmenu = hmenu; + m_hwndOwner = hwnd; + m_dwMenuFlags = dwFlags; + return S_OK; } +HRESULT CMenuStaticToolbar::ShowWindow(BOOL fShow) +{ + ::ShowWindow(m_hwnd, fShow ? SW_SHOW : SW_HIDE); + + return S_OK; +} + +HRESULT CMenuStaticToolbar::Close() +{ + DestroyWindow(m_hwnd); + m_hwnd = NULL; + return S_OK; +} + +HRESULT CMenuStaticToolbar::CreateToolbar(HWND hwndParent, DWORD dwFlags) +{ + HWND hwndToolbar; + hwndToolbar = CreateWindowEx(TBSTYLE_EX_DOUBLEBUFFER, TOOLBARCLASSNAMEW, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | + WS_CLIPCHILDREN | TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT | + CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP, 0, 0, 500, 20, m_hwndOwner, NULL, + _AtlBaseModule.GetModuleInstance(), 0); + if (hwndToolbar == NULL) + return E_FAIL; + + ::SetParent(hwndToolbar, hwndParent); + + m_hwnd = hwndToolbar; + + /* Identify the version of the used Common Controls DLL by sending the size of the TBBUTTON structure */ + SendMessageW(m_hwnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); + + if (dwFlags & SMINIT_TOPLEVEL) + { + /* Hide the placeholders for the button images */ + SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, 0); + } + + return S_OK; +} + +HRESULT CMenuStaticToolbar::FillToolbar() +{ + TBBUTTON tbb = {0}; + int i; + PWSTR MenuString; + + tbb.fsState = TBSTATE_ENABLED; + tbb.fsStyle = BTNS_DROPDOWN | BTNS_AUTOSIZE; + + for(i = 0; i < GetMenuItemCount(m_hmenu); i++) + { + if(!AllocAndGetMenuString(m_hmenu, i, &MenuString)) + return E_OUTOFMEMORY; + + tbb.idCommand = i; + tbb.iString = (INT_PTR)MenuString; + + SendMessageW(m_hwnd, TB_ADDBUTTONS, 1, (LPARAM)(LPTBBUTTON)&tbb); + HeapFree(GetProcessHeap(), 0, MenuString); + } + + return S_OK; +} + +HRESULT CMenuStaticToolbar::GetWindow(HWND *phwnd) +{ + if (!phwnd) + return E_FAIL; + + *phwnd = m_hwnd; + + return S_OK; +} + +CMenuBand::CMenuBand() +{ + m_site = NULL; + m_psmc = NULL; + m_staticToolbar = NULL; +} + +CMenuBand::~CMenuBand() +{ + if (m_site) + m_site->Release(); + + if (m_psmc) + m_psmc->Release(); + + if (m_staticToolbar) + delete m_staticToolbar; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::Initialize( + IShellMenuCallback *psmc, + UINT uId, + UINT uIdAncestor, + DWORD dwFlags) +{ + if(m_psmc) + m_psmc->Release(); + + m_psmc = psmc; + m_uId = uId; + m_uIdAncestor = uIdAncestor; + m_dwFlags = dwFlags; + + if (m_psmc) + m_psmc->AddRef(); + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo( + IShellMenuCallback **ppsmc, + UINT *puId, + UINT *puIdAncestor, + DWORD *pdwFlags) +{ + *ppsmc = m_psmc; + *puId = m_uId; + *puIdAncestor = m_uIdAncestor; + *pdwFlags = m_dwFlags; + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu( + HMENU hmenu, + HWND hwnd, + DWORD dwFlags) +{ + if (m_staticToolbar == NULL) + m_staticToolbar = new CMenuStaticToolbar(this); + + HRESULT hResult = m_staticToolbar->SetMenu(hmenu, hwnd, dwFlags); + if (FAILED(hResult)) + return hResult; + + if (m_site) + { + HWND hwndParent; + + hResult = m_site->GetWindow(&hwndParent); + if (FAILED(hResult)) + return hResult; + + hResult = m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags); + if (FAILED(hResult)) + return hResult; + + hResult = m_staticToolbar->FillToolbar(); + } + + return hResult; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu( + HMENU *phmenu, + HWND *phwnd, + DWORD *pdwFlags) +{ + if (m_staticToolbar == NULL) + return E_FAIL; + + return m_staticToolbar->GetMenu(phmenu, phwnd, pdwFlags); +} + +HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite) +{ + HWND hwndParent; + HRESULT hResult; + + if (m_site != NULL) + m_site->Release(); + + if (pUnkSite == NULL) + return S_OK; + + hwndParent = NULL; + hResult = pUnkSite->QueryInterface(IID_IOleWindow, reinterpret_cast(&m_site)); + if (SUCCEEDED(hResult)) + { + m_site->GetWindow(&hwndParent); + m_site->Release(); + } + if (!::IsWindow(hwndParent)) + return E_FAIL; + + if (m_staticToolbar != NULL) + { + m_staticToolbar->CreateToolbar(hwndParent, m_dwFlags); + m_staticToolbar->FillToolbar(); + } + + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite) +{ + if (m_site == NULL) + return E_FAIL; + + return m_site->QueryInterface(riid, ppvSite); +} + +HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow( + HWND *phwnd) +{ + if (m_staticToolbar != NULL) + return m_staticToolbar->GetWindow(phwnd); + + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE CMenuBand::GetBandInfo( + DWORD dwBandID, + DWORD dwViewMode, + DESKBANDINFO *pdbi) +{ + SIZE size; + HWND hwnd; + HRESULT hResult; + + /* FIXME */ + if (m_staticToolbar == NULL) + return E_FAIL; + hResult = m_staticToolbar->GetWindow(&hwnd); + if (FAILED(hResult)) + return hResult; + if (hwnd == NULL) + return E_FAIL; + + if (pdbi->dwMask & DBIM_MINSIZE) + { + SendMessageW( hwnd, TB_GETIDEALSIZE, TRUE, (LPARAM)&size); + + pdbi->ptMinSize.x = 0; + pdbi->ptMinSize.y = size.cy; + } + if (pdbi->dwMask & DBIM_MAXSIZE) + { + SendMessageW( hwnd, TB_GETMAXSIZE, 0, (LPARAM)&size); + + pdbi->ptMaxSize.x = size.cx; + pdbi->ptMaxSize.y = size.cy; + } + if (pdbi->dwMask & DBIM_INTEGRAL) + { + pdbi->ptIntegral.x = 0; + pdbi->ptIntegral.y = 0; + } + if (pdbi->dwMask & DBIM_ACTUAL) + { + SendMessageW( hwnd, TB_GETIDEALSIZE, TRUE, (LPARAM)&size); + SendMessageW( hwnd, TB_GETIDEALSIZE, FALSE, (LPARAM)&size); + + pdbi->ptActual.x = size.cx; + pdbi->ptActual.y = size.cy; + } + if (pdbi->dwMask & DBIM_TITLE) + wcscpy(pdbi->wszTitle, L""); + if (pdbi->dwMask & DBIM_MODEFLAGS) + pdbi->dwModeFlags = DBIMF_UNDELETEABLE; + if (pdbi->dwMask & DBIM_BKCOLOR) + pdbi->crBkgnd = 0; + return S_OK; +} + +/* IDockingWindow */ +HRESULT STDMETHODCALLTYPE CMenuBand::ShowDW(BOOL fShow) +{ + if (m_staticToolbar != NULL) + return m_staticToolbar->ShowWindow(fShow); + + return E_FAIL; +} + HRESULT STDMETHODCALLTYPE CMenuBand::CloseDW(DWORD dwReserved) { - UNIMPLEMENTED; + ShowDW(FALSE); + + if (m_staticToolbar != NULL) + return m_staticToolbar->Close(); + return S_OK; } - HRESULT STDMETHODCALLTYPE CMenuBand::ResizeBorderDW(LPCRECT prcBorder, IUnknown *punkToolbarSite, BOOL fReserved) { UNIMPLEMENTED; return S_OK; } -HRESULT STDMETHODCALLTYPE CMenuBand::GetWindow(HWND *phwnd) -{ - UNIMPLEMENTED; - return S_OK; -} - HRESULT STDMETHODCALLTYPE CMenuBand::ContextSensitiveHelp(BOOL fEnterMode) { UNIMPLEMENTED; return S_OK; } -HRESULT STDMETHODCALLTYPE CMenuBand::SetSite(IUnknown *pUnkSite) -{ - UNIMPLEMENTED; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CMenuBand::GetSite(REFIID riid, PVOID *ppvSite) -{ - UNIMPLEMENTED; - return S_OK; -} - HRESULT STDMETHODCALLTYPE CMenuBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg) { UNIMPLEMENTED; @@ -172,18 +483,6 @@ HRESULT STDMETHODCALLTYPE CMenuBand::TranslateMenuMessage(MSG *pmsg, LRESULT *pl return S_FALSE; } -HRESULT STDMETHODCALLTYPE CMenuBand::Initialize(IShellMenuCallback *psmc, UINT uId, UINT uIdAncestor,DWORD dwFlags) -{ - UNIMPLEMENTED; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CMenuBand::GetMenuInfo(IShellMenuCallback **ppsmc, UINT *puId, UINT *puIdAncestor, DWORD *pdwFlags) -{ - UNIMPLEMENTED; - return S_OK; -} - HRESULT STDMETHODCALLTYPE CMenuBand::SetShellFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, HKEY hKey, DWORD dwFlags) { UNIMPLEMENTED; @@ -196,18 +495,6 @@ HRESULT STDMETHODCALLTYPE CMenuBand::GetShellFolder(DWORD *pdwFlags, LPITEMIDLIS return S_OK; } -HRESULT STDMETHODCALLTYPE CMenuBand::SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags) -{ - UNIMPLEMENTED; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE CMenuBand::GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags) -{ - UNIMPLEMENTED; - return S_OK; -} - HRESULT STDMETHODCALLTYPE CMenuBand::InvalidateItem(LPSMDATA psmd, DWORD dwFlags) { UNIMPLEMENTED; diff --git a/reactos/dll/win32/shell32/CMenuBand.h b/reactos/dll/win32/shell32/CMenuBand.h index 11e19cb35a5..b0dae637d1c 100644 --- a/reactos/dll/win32/shell32/CMenuBand.h +++ b/reactos/dll/win32/shell32/CMenuBand.h @@ -1,4 +1,30 @@ +class CMenuBand; + +class CMenuStaticToolbar +{ +public: + CMenuStaticToolbar(CMenuBand *menuBand); + + HRESULT CreateToolbar(HWND hwndParent, DWORD dwFlags); + HRESULT FillToolbar(); + HRESULT GetWindow(HWND *phwnd); + HRESULT SetMenu(HMENU hmenu, HWND hwnd, DWORD dwFlags); + HRESULT GetMenu(HMENU *phmenu, HWND *phwnd, DWORD *pdwFlags); + HRESULT ShowWindow(BOOL fShow); + HRESULT Close(); + +private: + + static const UINT WM_USER_SHOWPOPUPMENU = WM_USER + 1; + + CMenuBand *m_menuBand; + HWND m_hwnd; + HMENU m_hmenu; + HWND m_hwndOwner; + DWORD m_dwMenuFlags; +}; + class CMenuBand : public CComCoClass, public CComObjectRootEx, @@ -14,6 +40,19 @@ class CMenuBand : public IWinEventHandler, public IShellMenuAcc { +public: + CMenuBand(); + ~CMenuBand(); + +private: + + IOleWindow *m_site; + CMenuStaticToolbar *m_staticToolbar; + + IShellMenuCallback *m_psmc; + UINT m_uId; + UINT m_uIdAncestor; + DWORD m_dwFlags; public : // *** IDeskBand methods *** @@ -103,19 +142,18 @@ DECLARE_NOT_AGGREGATABLE(CMenuBand) DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CMenuBand) - COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup) - COM_INTERFACE_ENTRY_IID(IID_IMenuBand, IMenuBand) + COM_INTERFACE_ENTRY_IID(IID_IDeskBar, IMenuPopup) COM_INTERFACE_ENTRY_IID(IID_IShellMenu, IShellMenu) COM_INTERFACE_ENTRY_IID(IID_IOleCommandTarget, IOleCommandTarget) COM_INTERFACE_ENTRY_IID(IID_IOleWindow, IDeskBand) COM_INTERFACE_ENTRY_IID(IID_IDockingWindow, IDockingWindow) - COM_INTERFACE_ENTRY_IID(IID_IDeskBar, IDeskBar) COM_INTERFACE_ENTRY_IID(IID_IDeskBand, IDeskBand) COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite) COM_INTERFACE_ENTRY_IID(IID_IInputObject, IInputObject) COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream) - COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist) + COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersistStream) COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider) + COM_INTERFACE_ENTRY_IID(IID_IMenuPopup, IMenuPopup) COM_INTERFACE_ENTRY_IID(IID_IMenuBand, IMenuBand) COM_INTERFACE_ENTRY_IID(IID_IShellMenu2, IShellMenu2) COM_INTERFACE_ENTRY_IID(IID_IWinEventHandler, IWinEventHandler) diff --git a/reactos/dll/win32/shell32/precomp.h b/reactos/dll/win32/shell32/precomp.h index 30a1900c825..b977194b79f 100644 --- a/reactos/dll/win32/shell32/precomp.h +++ b/reactos/dll/win32/shell32/precomp.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include From 7483a5ed77d0830e3130f9f93caf0e55af797f53 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 16 Oct 2013 19:17:09 +0000 Subject: [PATCH 13/36] [SAMSRV] Add query and set code of user private data and security descriptor attributes. svn path=/trunk/; revision=60691 --- reactos/dll/win32/samsrv/samrpc.c | 60 +++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index d5bcf5c4ba2..3e7780c272b 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -6793,7 +6793,14 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (InfoBuffer->All.WhichFields & USER_ALL_PRIVATEDATA) { - /* FIXME */ + Status = SampGetObjectAttributeString(UserObject, + L"PrivateData", + &InfoBuffer->All.PrivateData); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } } if (InfoBuffer->All.WhichFields & USER_ALL_PASSWORDEXPIRED) @@ -6803,7 +6810,32 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR) { - /* FIXME */ + Length = 0; + SampGetObjectAttribute(UserObject, + L"SecDesc", + NULL, + NULL, + &Length); + + if (Length > 0) + { + InfoBuffer->All.SecurityDescriptor.SecurityDescriptor = midl_user_allocate(Length); + if (InfoBuffer->All.SecurityDescriptor.SecurityDescriptor == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + InfoBuffer->All.SecurityDescriptor.Length = Length; + + Status = SampGetObjectAttribute(UserObject, + L"SecDesc", + NULL, + (PVOID)InfoBuffer->All.SecurityDescriptor.SecurityDescriptor, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + } } *Buffer = InfoBuffer; @@ -6852,6 +6884,12 @@ done: if (InfoBuffer->All.NtOwfPassword.Buffer != NULL) midl_user_free(InfoBuffer->All.NtOwfPassword.Buffer); + if (InfoBuffer->All.PrivateData.Buffer != NULL) + midl_user_free(InfoBuffer->All.PrivateData.Buffer); + + if (InfoBuffer->All.SecurityDescriptor.SecurityDescriptor != NULL) + midl_user_free(InfoBuffer->All.SecurityDescriptor.SecurityDescriptor); + midl_user_free(InfoBuffer); } } @@ -7539,6 +7577,15 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject, WriteFixedData = TRUE; } + if (WhichFields & USER_ALL_PRIVATEDATA) + { + Status = SampSetObjectAttributeString(UserObject, + L"PrivateData", + &Buffer->All.PrivateData); + if (!NT_SUCCESS(Status)) + goto done; + } + if (WhichFields & USER_ALL_PASSWORDEXPIRED) { if (Buffer->All.PasswordExpired) @@ -7558,6 +7605,15 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject, WriteFixedData = TRUE; } + if (WhichFields & USER_ALL_SECURITYDESCRIPTOR) + { + Status = SampSetObjectAttribute(UserObject, + L"SecDesc", + REG_BINARY, + Buffer->All.SecurityDescriptor.SecurityDescriptor, + Buffer->All.SecurityDescriptor.Length); + } + if (WriteFixedData == TRUE) { Status = SampSetObjectAttribute(UserObject, From 76e1afdbdac4815c947f9cf3d62da4054a607571 Mon Sep 17 00:00:00 2001 From: Benedikt Freisen Date: Sat, 19 Oct 2013 10:57:06 +0000 Subject: [PATCH 14/36] [PAINT] * Fix number typo introduced in revision 59955 svn path=/trunk/; revision=60700 --- reactos/base/applications/mspaint/drawing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/mspaint/drawing.c b/reactos/base/applications/mspaint/drawing.c index 9aad82a073f..7d1ba0aa980 100644 --- a/reactos/base/applications/mspaint/drawing.c +++ b/reactos/base/applications/mspaint/drawing.c @@ -195,7 +195,7 @@ Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style) case 10: case 11: { - POINT offsTop[] = {{4, 3}, {2, -2}, {0, 0}, + POINT offsTop[] = {{4, -3}, {2, -2}, {0, 0}, {-3, -3}, {-2, -2}, {-1, 0}}; POINT offsBtm[] = {{-3, 4}, {-2, 2}, {-1, 1}, {4, 4}, {2, 2}, {0, 1}}; From 6697ef7a17854c9afe3633fe1f8a93b784682641 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 19 Oct 2013 11:33:34 +0000 Subject: [PATCH 15/36] [NTOSKRNL] - Introduce a new and faster way to return to kernel mode from traps by using a ret 8 instruction instead of an iret. - Make use of KiUserTrap where appropriate - Remove some pointless toplevel volatile svn path=/trunk/; revision=60701 --- .../ntoskrnl/include/internal/i386/asmmacro.S | 25 +++++++++++---- reactos/ntoskrnl/include/internal/i386/ke.h | 4 +-- .../ntoskrnl/include/internal/i386/trap_x.h | 7 +++-- reactos/ntoskrnl/ke/i386/cpu.c | 2 +- reactos/ntoskrnl/ke/i386/exp.c | 31 ++++++++++++------- reactos/ntoskrnl/ke/i386/patpge.c | 10 +++--- reactos/ntoskrnl/ke/i386/trap.s | 1 + reactos/ntoskrnl/ke/i386/traphdlr.c | 18 +++++------ reactos/ntoskrnl/ke/i386/usercall.c | 4 +-- reactos/ntoskrnl/ke/time.c | 2 +- 10 files changed, 64 insertions(+), 40 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/asmmacro.S b/reactos/ntoskrnl/include/internal/i386/asmmacro.S index cf338d32338..2ab3bdfd6ff 100644 --- a/reactos/ntoskrnl/include/internal/i386/asmmacro.S +++ b/reactos/ntoskrnl/include/internal/i386/asmmacro.S @@ -241,6 +241,7 @@ ENDM #define KI_EXIT_RET HEX(080) #define KI_EXIT_IRET HEX(100) #define KI_EDITED_FRAME HEX(200) +#define KI_EXIT_RET8 HEX(400) #define KI_RESTORE_VOLATILES (KI_RESTORE_EAX OR KI_RESTORE_ECX_EDX) MACRO(KiTrapExitStub, Name, Flags) @@ -248,16 +249,16 @@ MACRO(KiTrapExitStub, Name, Flags) PUBLIC @&Name&@4 @&Name&@4: - if (Flags AND KI_RESTORE_EFLAGS) - - /* We will pop EFlags off the stack */ - OffsetEsp = KTRAP_FRAME_EFLAGS - - elseif (Flags AND KI_EXIT_IRET) + if (Flags AND KI_EXIT_RET8) OR (Flags AND KI_EXIT_IRET) /* This is the IRET frame */ OffsetEsp = KTRAP_FRAME_EIP + elseif (Flags AND KI_RESTORE_EFLAGS) + + /* We will pop EFlags off the stack */ + OffsetEsp = KTRAP_FRAME_EFLAGS + else OffsetEsp = 0 @@ -335,6 +336,13 @@ PUBLIC @&Name&@4 if (Flags AND KI_RESTORE_EFLAGS) + if (Flags AND KI_EXIT_RET8) + + /* We are at the IRET frame, so push EFLAGS first */ + push dword ptr [esp + 8] + + endif + /* Restore EFLAGS */ popfd @@ -357,6 +365,11 @@ PUBLIC @&Name&@4 /* Return to kernel mode with a jmp */ jmp edx + elseif (Flags AND KI_EXIT_RET8) + + /* Return to kernel mode with a ret 8 */ + ret 8 + elseif (Flags AND KI_EXIT_RET) /* Return to kernel mode with a ret */ diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 47da49fcea1..f0343c521a8 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -383,13 +383,13 @@ KeI386VdmInitialize( ULONG_PTR NTAPI Ki386EnableGlobalPage( - IN volatile ULONG_PTR Context + IN ULONG_PTR Context ); ULONG_PTR NTAPI Ki386EnableTargetLargePage( - IN volatile ULONG_PTR Context + IN ULONG_PTR Context ); BOOLEAN diff --git a/reactos/ntoskrnl/include/internal/i386/trap_x.h b/reactos/ntoskrnl/include/internal/i386/trap_x.h index d83276fb165..ec8f0ba914d 100644 --- a/reactos/ntoskrnl/include/internal/i386/trap_x.h +++ b/reactos/ntoskrnl/include/internal/i386/trap_x.h @@ -163,7 +163,7 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame, } /* Check DR values */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame) { /* Check for active debugging */ if (KeGetCurrentThread()->Header.DebugActive) @@ -244,6 +244,7 @@ DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame DECLSPEC_NORETURN VOID FASTCALL KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame); +DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegmentsRet8(IN PKTRAP_FRAME TrapFrame); typedef ATTRIB_NORETURN @@ -382,7 +383,7 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame) TrapFrame->Dr7 = 0; /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Check for active debugging */ @@ -411,7 +412,7 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame) TrapFrame->Dr7 = 0; /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Check for active debugging */ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 3b8f1fad176..2d741ab6144 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -1535,7 +1535,7 @@ KeFlushEntireTb(IN BOOLEAN Invalid, if (TargetAffinity) { /* Sanity check */ - ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb()); + ASSERT(Prcb == KeGetCurrentPrcb()); /* FIXME: TODO */ ASSERTMSG("Not yet implemented\n", FALSE); diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index eaacf4ea6a3..976d2ebddc7 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -137,7 +137,7 @@ NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame) { /* Check if this is user-mode or V86 */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Return it directly */ @@ -175,7 +175,7 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, Previous = KiEspFromTrapFrame(TrapFrame); /* Check if this is user-mode or V86 */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Write it directly */ @@ -225,7 +225,7 @@ KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame) /* Just return it */ return TrapFrame->HardwareSegSs; } - else if (TrapFrame->SegCs & MODE_MASK) + else if (KiUserTrap(TrapFrame)) { /* User mode, return the User SS */ return TrapFrame->HardwareSegSs | RPL_MASK; @@ -251,7 +251,7 @@ KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, /* Just write it */ TrapFrame->HardwareSegSs = Ss; } - else if (TrapFrame->SegCs & MODE_MASK) + else if (KiUserTrap(TrapFrame)) { /* Usermode, save the User SS */ TrapFrame->HardwareSegSs = Ss | RPL_MASK; @@ -398,7 +398,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, TrapFrame->V86Fs = Context->SegFs; TrapFrame->V86Gs = Context->SegGs; } - else if (!(TrapFrame->SegCs & MODE_MASK)) + else if (!KiUserTrap(TrapFrame)) { /* For kernel mode, write the standard values */ TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK; @@ -429,7 +429,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, /* Handle the extended registers */ if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) == - CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame)) { /* Get the FX Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -463,7 +463,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, /* Handle the floating point state */ if (((ContextFlags & CONTEXT_FLOATING_POINT) == - CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame)) { /* Get the FX Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -692,7 +692,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, /* Handle extended registers */ if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == - CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame)) { /* Get the FX Save Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -712,7 +712,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, /* Handle Floating Point */ if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) == - CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame)) { /* Get the FX Save Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -1045,6 +1045,13 @@ DispatchToUser: } } _SEH2_END; + + DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n", + PsGetCurrentProcess()->ImageFileName, + ExceptionRecord->ExceptionCode, + ExceptionRecord->ExceptionAddress, + ExceptionRecord->ExceptionInformation[0], + ExceptionRecord->ExceptionInformation[1]); } /* Try second chance */ @@ -1060,11 +1067,13 @@ DispatchToUser: } /* 3rd strike, kill the process */ - DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p\n", + DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n", PsGetCurrentProcess()->ImageFileName, ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress, - PsGetCurrentProcess()->SectionBaseAddress); + PsGetCurrentProcess()->SectionBaseAddress, + ExceptionRecord->ExceptionInformation[0], + ExceptionRecord->ExceptionInformation[1]); ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, diff --git a/reactos/ntoskrnl/ke/i386/patpge.c b/reactos/ntoskrnl/ke/i386/patpge.c index 41b474ae0e9..1e598ce355a 100644 --- a/reactos/ntoskrnl/ke/i386/patpge.c +++ b/reactos/ntoskrnl/ke/i386/patpge.c @@ -20,9 +20,9 @@ ULONG_PTR NTAPI INIT_FUNCTION -Ki386EnableGlobalPage(IN volatile ULONG_PTR Context) +Ki386EnableGlobalPage(IN ULONG_PTR Context) { - volatile PLONG Count = (PLONG)Context; + PLONG Count = (PLONG)Context; ULONG Cr4, Cr3; /* Disable interrupts */ @@ -144,7 +144,7 @@ Ki386IdentityMapMakeValid(PLARGE_IDENTITY_MAP IdentityMap, if (PageTable) *PageTable = (PHARDWARE_PTE)(Pde->PageFrameNumber << PAGE_SHIFT); } - + return TRUE; } @@ -172,7 +172,7 @@ Ki386MapAddress(PLARGE_IDENTITY_MAP IdentityMap, /* Get PTE of VirtualPtr, make it valid, and map PhysicalPtr there */ Pte = &PageTable[(VirtualPtr >> 12) & ((1 << PTE_BITS) - 1)]; Pte->Valid = 1; - Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT; + Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT); return TRUE; } @@ -189,7 +189,7 @@ Ki386ConvertPte(PHARDWARE_PTE Pte) PhysicalPtr = MmGetPhysicalAddress(VirtualPtr); /* Map its physical address in the page table provided by the caller */ - Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT; + Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT); } BOOLEAN diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 6817995ca35..272886d4891 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -166,6 +166,7 @@ KiTrapExitStub KiSystemCallTrapReturn, (KI_RESTORE_EAX OR KI_RESTORE_FS OR KI KiTrapExitStub KiEditedTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EDITED_FRAME OR KI_EXIT_RET) KiTrapExitStub KiTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_SEGMENTS OR KI_EXIT_IRET) KiTrapExitStub KiTrapReturnNoSegments, (KI_RESTORE_VOLATILES OR KI_EXIT_IRET) +KiTrapExitStub KiTrapReturnNoSegmentsRet8,(KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EXIT_RET8) #ifdef _MSC_VER EXTERN _PsConvertToGuiThread@0:PROC diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 46b925aab24..e761cd0d82a 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -100,7 +100,7 @@ KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode) if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0)) { /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Handle debug registers */ @@ -124,13 +124,13 @@ KiEoiHelper(IN PKTRAP_FRAME TrapFrame) if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame); /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame); + if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame); /* Check for edited frame */ if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame); /* Exit the trap to kernel mode */ - KiTrapReturnNoSegments(TrapFrame); + KiTrapReturnNoSegmentsRet8(TrapFrame); } DECLSPEC_NORETURN @@ -152,7 +152,7 @@ KiServiceExit(IN PKTRAP_FRAME TrapFrame, KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode; /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame)) { /* Check if we were single stepping */ if (TrapFrame->EFlags & EFLAGS_TF) @@ -186,13 +186,13 @@ KiServiceExit2(IN PKTRAP_FRAME TrapFrame) if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame); /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame); + if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame); /* Check for edited frame */ if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame); /* Exit the trap to kernel mode */ - KiTrapReturnNoSegments(TrapFrame); + KiTrapReturnNoSegmentsRet8(TrapFrame); } @@ -1250,10 +1250,10 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame) /* Call the access fault handler */ Status = MmAccessFault(TrapFrame->ErrCode & 1, (PVOID)Cr2, - TrapFrame->SegCs & MODE_MASK, + KiUserTrap(TrapFrame), TrapFrame); if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame); - + /* Check for syscall fault */ #if 0 if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) || @@ -1541,7 +1541,7 @@ KiSystemCall(IN PKTRAP_FRAME TrapFrame, TrapFrame->Dr7 = 0; /* Check if the frame was from user mode */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame)) { /* Check for active debugging */ if (KeGetCurrentThread()->Header.DebugActive & 0xFF) diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index 9363c6fed5f..91bd672ae4a 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -67,7 +67,7 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, _SEH2_TRY { /* Sanity check */ - ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); + ASSERT(KiUserTrap(TrapFrame)); /* Get the aligned size */ AlignedEsp = Context.Esp & ~3; @@ -210,7 +210,7 @@ KeUserModeCallback(IN ULONG RoutineIndex, } -/* +/* * Stack layout for KiUserModeCallout: * ---------------------------------- * KCALLOUT_FRAME.ResultLength <= 2nd Parameter to KiCallUserMode diff --git a/reactos/ntoskrnl/ke/time.c b/reactos/ntoskrnl/ke/time.c index 531cc85bb0f..e6bdd9ed4d9 100644 --- a/reactos/ntoskrnl/ke/time.c +++ b/reactos/ntoskrnl/ke/time.c @@ -153,7 +153,7 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame, /* Check if we came from user mode */ #ifndef _M_ARM - if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) #else if (TrapFrame->PreviousMode == UserMode) #endif From fc553a69683f84815ba660a50d127149d0e095a1 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 19 Oct 2013 11:40:00 +0000 Subject: [PATCH 16/36] [NTOSKRNL] Fix a typo I introduced in TRAP_DEBUG only code, spotted by Thomas svn path=/trunk/; revision=60702 --- reactos/ntoskrnl/include/internal/i386/trap_x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/i386/trap_x.h b/reactos/ntoskrnl/include/internal/i386/trap_x.h index ec8f0ba914d..d6081c20d12 100644 --- a/reactos/ntoskrnl/include/internal/i386/trap_x.h +++ b/reactos/ntoskrnl/include/internal/i386/trap_x.h @@ -163,7 +163,7 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame, } /* Check DR values */ - if (KiUserTrap(TrapFrame) + if (KiUserTrap(TrapFrame)) { /* Check for active debugging */ if (KeGetCurrentThread()->Header.DebugActive) From fec54daadda821f16f5afa8bb24d14bf3da7639d Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 19 Oct 2013 17:48:27 +0000 Subject: [PATCH 17/36] [RTL] - Implement Rtl MemoryStream functions. Patch by David Quintana. CORE-7492 svn path=/trunk/; revision=60705 --- reactos/dll/ntdll/CMakeLists.txt | 1 + reactos/dll/ntdll/def/ntdll.spec | 38 +-- reactos/include/ndk/rtlfuncs.h | 174 ++++++++++++ reactos/include/ndk/rtltypes.h | 38 +++ reactos/lib/rtl/CMakeLists.txt | 1 + reactos/lib/rtl/memstream.c | 469 +++++++++++++++++++++++++++++++ 6 files changed, 702 insertions(+), 19 deletions(-) create mode 100644 reactos/lib/rtl/memstream.c diff --git a/reactos/dll/ntdll/CMakeLists.txt b/reactos/dll/ntdll/CMakeLists.txt index 83e999970fd..9e51fc2ce7a 100644 --- a/reactos/dll/ntdll/CMakeLists.txt +++ b/reactos/dll/ntdll/CMakeLists.txt @@ -52,6 +52,7 @@ target_link_libraries(ntdll rtl ntdllsys libcntpr + uuid ${PSEH_LIB}) add_pch(ntdll include/ntdll.h) diff --git a/reactos/dll/ntdll/def/ntdll.spec b/reactos/dll/ntdll/def/ntdll.spec index a8c3d92b747..b45adaf0ec1 100644 --- a/reactos/dll/ntdll/def/ntdll.spec +++ b/reactos/dll/ntdll/def/ntdll.spec @@ -405,7 +405,7 @@ @ stdcall -arch=x86_64 RtlAddFunctionTable(ptr long long) ;@ stdcall RtlAddMandatoryAce(ptr long long long long ptr) @ stdcall RtlAddRefActivationContext(ptr) -;@ stdcall RtlAddRefMemoryStream +@ stdcall RtlAddRefMemoryStream(ptr) @ stdcall RtlAddVectoredContinueHandler(long ptr) @ stdcall RtlAddVectoredExceptionHandler(long ptr) ;@ stdcall RtlAddressInSectionTable @@ -440,8 +440,8 @@ @ stdcall RtlCheckRegistryKey(long ptr) @ stdcall RtlClearAllBits(ptr) @ stdcall RtlClearBits(ptr long long) -;@ stdcall RtlCloneMemoryStream -;@ stdcall RtlCommitMemoryStream +@ stdcall RtlCloneMemoryStream(ptr ptr) +@ stdcall RtlCommitMemoryStream(ptr long) @ stdcall RtlCompactHeap(long long) @ stdcall RtlCompareMemory(ptr ptr long) @ stdcall RtlCompareMemoryUlong(ptr long long) @@ -464,8 +464,8 @@ @ stdcall RtlCopyLuid(ptr ptr) @ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr) ;@ stdcall RtlCopyMappedMemory -;@ stdcall RtlCopyMemoryStreamTo -;@ stdcall RtlCopyOutOfProcessMemoryStreamTo +@ stdcall RtlCopyMemoryStreamTo(ptr ptr int64 ptr ptr) +@ stdcall RtlCopyOutOfProcessMemoryStreamTo(ptr ptr int64 ptr ptr) RtlCopyMemoryStreamTo ;@ stdcall RtlCopyRangeList ; 5.0 and 5.1 only @ stdcall RtlCopySecurityDescriptor(ptr ptr) @ stdcall RtlCopySid(long ptr ptr) @@ -571,7 +571,7 @@ @ stdcall -arch=win32 -ret64 RtlExtendedMagicDivide(double double long) @ stdcall RtlFillMemory(ptr long long) @ stdcall RtlFillMemoryUlong(ptr long long) -;@ stdcall RtlFinalReleaseOutOfProcessMemoryStream +@ stdcall RtlFinalReleaseOutOfProcessMemoryStream(ptr) @ stdcall RtlFindActivationContextSectionGuid(long ptr long ptr ptr) @ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr) @ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr) @@ -658,9 +658,9 @@ @ stdcall RtlInitAnsiString(ptr str) @ stdcall RtlInitAnsiStringEx(ptr str) @ stdcall RtlInitCodePageTable(ptr ptr) -;@ stdcall RtlInitMemoryStream +@ stdcall RtlInitMemoryStream(ptr) @ stdcall RtlInitNlsTables(ptr ptr ptr ptr) -;@ stdcall RtlInitOutOfProcessMemoryStream +@ stdcall RtlInitOutOfProcessMemoryStream(ptr) @ stdcall RtlInitString(ptr str) @ stdcall RtlInitUnicodeString(ptr wstr) @ stdcall RtlInitUnicodeStringEx(ptr wstr) @@ -735,7 +735,7 @@ @ stdcall RtlLocalTimeToSystemTime(ptr ptr) @ stdcall RtlLockBootStatusData(ptr) @ stdcall RtlLockHeap(long) -;@ stdcall RtlLockMemoryStreamRegion +@ stdcall RtlLockMemoryStreamRegion(ptr int64 int64 long) ;@ stdcall RtlLogStackBackTrace @ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr) @ stdcall RtlLookupElementGenericTable(ptr ptr) @@ -781,7 +781,7 @@ @ stdcall RtlQueryInformationAcl(ptr ptr long long) @ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr) @ stdcall RtlQueryInformationActiveActivationContext(long ptr long ptr) -;@ stdcall RtlQueryInterfaceMemoryStream +@ stdcall RtlQueryInterfaceMemoryStream(ptr ptr ptr) ;@ stdcall RtlQueryProcessBackTraceInformation @ stdcall RtlQueryProcessDebugInformation(long long ptr) ;@ stdcall RtlQueryProcessHeapInformation @@ -800,14 +800,14 @@ @ stdcall RtlRandom(ptr) @ stdcall RtlRandomEx(ptr) @ stdcall RtlReAllocateHeap(long long ptr long) -;@ stdcall RtlReadMemoryStream -;@ stdcall RtlReadOutOfProcessMemoryStream +@ stdcall RtlReadMemoryStream(ptr ptr long ptr) +@ stdcall RtlReadOutOfProcessMemoryStream(ptr ptr long ptr) @ stdcall RtlRealPredecessor(ptr) @ stdcall RtlRealSuccessor(ptr) @ stdcall RtlRegisterSecureMemoryCacheCallback(ptr) @ stdcall RtlRegisterWait(ptr ptr ptr ptr long long) @ stdcall RtlReleaseActivationContext(ptr) -;@ stdcall RtlReleaseMemoryStream +@ stdcall RtlReleaseMemoryStream(ptr) @ stdcall RtlReleasePebLock() @ stdcall RtlReleasePrivilege(ptr) @ stdcall RtlReleaseRelativeName(ptr) @@ -820,12 +820,12 @@ @ stdcall RtlResetRtlTranslations(ptr) @ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) @ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error -;@ stdcall RtlRevertMemoryStream +@ stdcall RtlRevertMemoryStream(ptr) @ stdcall RtlRunDecodeUnicodeString(long ptr) @ stdcall RtlRunEncodeUnicodeString(long ptr) @ stdcall RtlSecondsSince1970ToTime(long ptr) @ stdcall RtlSecondsSince1980ToTime(long ptr) -;@ stdcall RtlSeekMemoryStream +@ stdcall RtlSeekMemoryStream(ptr int64 long ptr) @ stdcall RtlSelfRelativeToAbsoluteSD2(ptr ptr) @ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlSetAllBits(ptr) @@ -844,7 +844,7 @@ @ stdcall RtlSetIoCompletionCallback(long ptr long) @ stdcall RtlSetLastWin32Error(long) @ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long) -;@ stdcall RtlSetMemoryStreamSize +@ stdcall RtlSetMemoryStreamSize(ptr int64) @ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long) @ stdcall RtlSetProcessIsCritical(long ptr long) ;@ stdcall RtlSetProperties ; RtlSetProperties @@ -869,7 +869,7 @@ @ stdcall RtlSleepConditionVariableSRW(ptr ptr ptr long) @ stdcall RtlSplay(ptr) ;@ stdcall RtlStartRXact -;@ stdcall RtlStatMemoryStream +@ stdcall RtlStatMemoryStream(ptr ptr long) @ stdcall RtlStringFromGUID(ptr ptr) @ stdcall RtlSubAuthorityCountSid(ptr) @ stdcall RtlSubAuthoritySid(ptr long) @@ -907,7 +907,7 @@ @ stdcall RtlUniform(ptr) @ stdcall RtlUnlockBootStatusData(ptr) @ stdcall RtlUnlockHeap(long) -;@ stdcall RtlUnlockMemoryStreamRegion +@ stdcall RtlUnlockMemoryStreamRegion(ptr int64 int64 long) @ stdcall -register RtlUnwind(ptr ptr ptr ptr) @ stdcall -arch=x86_64 RtlUnwindEx(long long ptr long ptr) @ stdcall RtlUpcaseUnicodeChar(long) @@ -938,7 +938,7 @@ @ stdcall RtlWow64EnableFsRedirectionEx(long ptr) @ stdcall RtlWakeAllConditionVariable(ptr) @ stdcall RtlWakeConditionVariable(ptr) -;@ stdcall RtlWriteMemoryStream +@ stdcall RtlWriteMemoryStream(ptr ptr long ptr) @ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long) @ stdcall RtlZeroHeap(ptr long) @ stdcall RtlZeroMemory(ptr long) diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index 3205fa1a7c8..0b1332923b9 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -4152,6 +4152,180 @@ RtlComputeImportTableHash( ); #endif +// +// MemoryStream functions +// +#ifdef NTOS_MODE_USER + +NTSYSAPI +VOID +NTAPI +RtlInitMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +VOID +NTAPI +RtlInitOutOfProcessMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +VOID +NTAPI +RtlFinalReleaseOutOfProcessMemoryStream( + _In_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +HRESULT +NTAPI +RtlQueryInterfaceMemoryStream( + _In_ struct IStream *This, + _In_ REFIID RequestedIid, + _Outptr_ PVOID *ResultObject +); + +NTSYSAPI +ULONG +NTAPI +RtlAddRefMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +ULONG +NTAPI +RtlReleaseMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +HRESULT +NTAPI +RtlReadMemoryStream( + _In_ struct IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead +); + +NTSYSAPI +HRESULT +NTAPI +RtlReadOutOfProcessMemoryStream( + _In_ struct IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead +); + +NTSYSAPI +HRESULT +NTAPI +RtlSeekMemoryStream( + _In_ struct IStream *This, + _In_ LARGE_INTEGER RelativeOffset, + _In_ ULONG Origin, + _Out_opt_ PULARGE_INTEGER ResultOffset +); + +NTSYSAPI +HRESULT +NTAPI +RtlCopyMemoryStreamTo( + _In_ struct IStream *This, + _In_ struct IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlCopyOutOfProcessMemoryStreamTo( + _In_ struct IStream *This, + _In_ struct IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlStatMemoryStream( + _In_ struct IStream *This, + _Out_ struct tagSTATSTG *Stats, + _In_ ULONG Flags +); + +// Dummy functions +NTSYSAPI +HRESULT +NTAPI +RtlWriteMemoryStream( + _In_ struct IStream *This, + _In_reads_bytes_(Length) CONST VOID *Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlSetMemoryStreamSize( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER NewSize +); + +NTSYSAPI +HRESULT +NTAPI +RtlCommitMemoryStream( + _In_ struct IStream *This, + _In_ ULONG CommitFlags +); + +NTSYSAPI +HRESULT +NTAPI +RtlRevertMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +HRESULT +NTAPI +RtlLockMemoryStreamRegion( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType +); + +NTSYSAPI +HRESULT +NTAPI +RtlUnlockMemoryStreamRegion( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType +); + +NTSYSAPI +HRESULT +NTAPI +RtlCloneMemoryStream( + _In_ struct IStream *This, + _Outptr_ struct IStream **ResultStream +); + +#endif // NTOS_MODE_USER + #ifdef __cplusplus } #endif diff --git a/reactos/include/ndk/rtltypes.h b/reactos/include/ndk/rtltypes.h index 825d62bc13f..7620c5c7f99 100644 --- a/reactos/include/ndk/rtltypes.h +++ b/reactos/include/ndk/rtltypes.h @@ -1559,6 +1559,44 @@ typedef struct _MESSAGE_RESOURCE_DATA #endif /* !NTOS_MODE_USER */ +#ifdef NTOS_MODE_USER + +// +// Memory Stream +// +#ifndef CONST_VTBL +#ifdef CONST_VTABLE +#define CONST_VTBL const +#else +#define CONST_VTBL +#endif +#endif + +struct IStreamVtbl; +struct IStream; +struct tagSTATSTG; + +typedef struct _RTL_MEMORY_STREAM RTL_MEMORY_STREAM, *PRTL_MEMORY_STREAM; + +typedef VOID +(NTAPI *PRTL_MEMORY_STREAM_FINAL_RELEASE_ROUTINE)( + _In_ PRTL_MEMORY_STREAM Stream +); + +struct _RTL_MEMORY_STREAM +{ + CONST_VTBL struct IStreamVtbl *Vtbl; + LONG RefCount; + ULONG Unk1; + PVOID Current; + PVOID Start; + PVOID End; + PRTL_MEMORY_STREAM_FINAL_RELEASE_ROUTINE FinalRelease; + HANDLE ProcessHandle; +}; + +#endif /* NTOS_MODE_USER */ + #ifdef __cplusplus } #endif diff --git a/reactos/lib/rtl/CMakeLists.txt b/reactos/lib/rtl/CMakeLists.txt index 56e698e14e4..e584c063a6e 100644 --- a/reactos/lib/rtl/CMakeLists.txt +++ b/reactos/lib/rtl/CMakeLists.txt @@ -33,6 +33,7 @@ list(APPEND SOURCE heapuser.c image.c interlck.c + memstream.c message.c largeint.c luid.c diff --git a/reactos/lib/rtl/memstream.c b/reactos/lib/rtl/memstream.c new file mode 100644 index 00000000000..776fbc64f77 --- /dev/null +++ b/reactos/lib/rtl/memstream.c @@ -0,0 +1,469 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/mem.c + * PURPOSE: MemoryStream functions + * PROGRAMMER: David Quintana (gigaherz@gmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#define COBJMACROS +#define CONST_VTABLE + +#include + +#define NDEBUG +#include + +/* VIRTUAL METHOD TABLES ******************************************************/ + +const struct IStreamVtbl RtlMemoryStreamVtbl = +{ + RtlQueryInterfaceMemoryStream, + RtlAddRefMemoryStream, + RtlReleaseMemoryStream, + RtlReadMemoryStream, + RtlWriteMemoryStream, + RtlSeekMemoryStream, + RtlSetMemoryStreamSize, + RtlCopyMemoryStreamTo, + RtlCommitMemoryStream, + RtlRevertMemoryStream, + RtlLockMemoryStreamRegion, + RtlUnlockMemoryStreamRegion, + RtlStatMemoryStream, + RtlCloneMemoryStream, +}; + +const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl = +{ + RtlQueryInterfaceMemoryStream, + RtlAddRefMemoryStream, + RtlReleaseMemoryStream, + RtlReadOutOfProcessMemoryStream, + RtlWriteMemoryStream, + RtlSeekMemoryStream, + RtlSetMemoryStreamSize, + RtlCopyMemoryStreamTo, + RtlCommitMemoryStream, + RtlRevertMemoryStream, + RtlLockMemoryStreamRegion, + RtlUnlockMemoryStreamRegion, + RtlStatMemoryStream, + RtlCloneMemoryStream, +}; + +/* FUNCTIONS ******************************************************************/ + +static +PRTL_MEMORY_STREAM +IStream_To_RTL_MEMORY_STREAM( + _In_ IStream *Interface) +{ + if (Interface == NULL) + return NULL; + + return CONTAINING_RECORD(Interface, RTL_MEMORY_STREAM, Vtbl); +} + +/* + * @implemented + */ +VOID +NTAPI +RtlInitMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream) +{ + RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); + Stream->Vtbl = &RtlMemoryStreamVtbl; +} + +/* + * @implemented + */ +VOID +NTAPI +RtlInitOutOfProcessMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream) +{ + RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); + Stream->Vtbl = &RtlOutOfProcessMemoryStreamVtbl; + Stream->FinalRelease = RtlFinalReleaseOutOfProcessMemoryStream; +} + +/* + * @unimplemented + */ +VOID +NTAPI +RtlFinalReleaseOutOfProcessMemoryStream( + _In_ PRTL_MEMORY_STREAM Stream) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlQueryInterfaceMemoryStream( + _In_ IStream *This, + _In_ REFIID RequestedIid, + _Outptr_ PVOID *ResultObject) +{ + if (IsEqualGUID(RequestedIid, &IID_IUnknown) || + IsEqualGUID(RequestedIid, &IID_ISequentialStream) || + IsEqualGUID(RequestedIid, &IID_IStream)) + { + IStream_AddRef(This); + *ResultObject = This; + return S_OK; + } + + *ResultObject = NULL; + return E_NOINTERFACE; +} + +/* + * @implemented + */ +ULONG +NTAPI +RtlAddRefMemoryStream( + _In_ IStream *This) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + return InterlockedIncrement(&Stream->RefCount); +} + +/* + * @implemented + */ +ULONG +NTAPI +RtlReleaseMemoryStream( + _In_ IStream *This) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + LONG Result; + + Result = InterlockedDecrement(&Stream->RefCount); + + if (Result == 0) + { + if (Stream->FinalRelease) + Stream->FinalRelease(Stream); + } + + return Result; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlReadMemoryStream( + _In_ IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead) +{ + ULONG CopyLength; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current; + + if (BytesRead) + *BytesRead = 0; + + if (!Length) + return S_OK; + + CopyLength = min(Available, Length); + + RtlMoveMemory(Buffer, Stream->Current, CopyLength); + + Stream->Current = (PUCHAR)Stream->Current + CopyLength; + + *BytesRead = CopyLength; + + return S_OK; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlReadOutOfProcessMemoryStream( + _In_ IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead) +{ + NTSTATUS Status; + ULONG CopyLength; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current; + + if (BytesRead) + *BytesRead = 0; + + if (!Length) + return S_OK; + + CopyLength = min(Available, Length); + + Status = NtReadVirtualMemory(Stream->ProcessHandle, + Stream->Current, + Buffer, + CopyLength, + BytesRead); + + if (NT_SUCCESS(Status)) + Stream->Current = (PUCHAR)Stream->Current + *BytesRead; + + return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status)); +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlSeekMemoryStream( + _In_ IStream *This, + _In_ LARGE_INTEGER RelativeOffset, + _In_ ULONG Origin, + _Out_opt_ PULARGE_INTEGER ResultOffset) +{ + PVOID NewPosition; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + switch (Origin) + { + case STREAM_SEEK_SET: + NewPosition = (PUCHAR)Stream->Start + RelativeOffset.QuadPart; + break; + + case STREAM_SEEK_CUR: + NewPosition = (PUCHAR)Stream->Current + RelativeOffset.QuadPart; + break; + + case STREAM_SEEK_END: + NewPosition = (PUCHAR)Stream->End - RelativeOffset.QuadPart; + break; + + default: + return E_INVALIDARG; + } + + if (NewPosition < Stream->Start || NewPosition > Stream->End) + return STG_E_INVALIDPOINTER; + + Stream->Current = NewPosition; + + if (ResultOffset) + ResultOffset->QuadPart = (PUCHAR)Stream->Current - (PUCHAR)Stream->Start; + + return S_OK; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCopyMemoryStreamTo( + _In_ IStream *This, + _In_ IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten) +{ + CHAR Buffer[1024]; + ULONGLONG TotalSize; + ULONG Left, Amount; + HRESULT Result; + + if (BytesRead) + BytesRead->QuadPart = 0; + if (BytesWritten) + BytesWritten->QuadPart = 0; + + if (!Target) + return S_OK; + + if (!Length.QuadPart) + return S_OK; + + /* Copy data */ + TotalSize = Length.QuadPart; + while (TotalSize) + { + Left = min(TotalSize, sizeof(Buffer)); + + /* Read */ + Result = IStream_Read(This, Buffer, Left, &Amount); + if (BytesRead) + BytesRead->QuadPart += Amount; + if (FAILED(Result) || Amount == 0) + break; + + Left = Amount; + + /* Write */ + Result = IStream_Write(Target, Buffer, Left, &Amount); + if (BytesWritten) + BytesWritten->QuadPart += Amount; + if (FAILED(Result) || Amount != Left) + break; + + TotalSize -= Left; + } + return Result; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlStatMemoryStream( + _In_ IStream *This, + _Out_ STATSTG *Stats, + _In_ ULONG Flags) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + if (!Stats) + return STG_E_INVALIDPOINTER; + + RtlZeroMemory(Stats, sizeof(STATSTG)); + Stats->type = STGTY_STREAM; + Stats->cbSize.QuadPart = (PUCHAR)Stream->End - (PUCHAR)Stream->Start; + + return S_OK; +} + +/* DUMMY FUNCTIONS ************************************************************/ +/* + * The following functions return E_NOTIMPL in Windows Server 2003. + */ + +/* + * @implemented + */ +HRESULT +NTAPI +RtlWriteMemoryStream( + _In_ IStream *This, + _In_reads_bytes_(Length) CONST VOID *Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesWritten) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Buffer); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(BytesWritten); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlSetMemoryStreamSize( + _In_ IStream *This, + _In_ ULARGE_INTEGER NewSize) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(NewSize); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCommitMemoryStream( + _In_ IStream *This, + _In_ ULONG CommitFlags) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(CommitFlags); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlRevertMemoryStream( + _In_ IStream *This) +{ + UNREFERENCED_PARAMETER(This); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlLockMemoryStreamRegion( + _In_ IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Offset); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(LockType); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlUnlockMemoryStreamRegion( + _In_ IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Offset); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(LockType); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCloneMemoryStream( + _In_ IStream *This, + _Outptr_ IStream **ResultStream) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(ResultStream); + + return E_NOTIMPL; +} From 3440678be4651c0b41699a9121951efbfb56ef9d Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sat, 19 Oct 2013 17:59:29 +0000 Subject: [PATCH 18/36] [NTDLL_APITEST] - Add test for Rtl MemoryStream functions. Patch by David Quintana. CORE-7492 svn path=/trunk/; revision=60707 --- rostests/apitests/ntdll/CMakeLists.txt | 3 +- rostests/apitests/ntdll/RtlMemoryStream.c | 525 ++++++++++++++++++++++ rostests/apitests/ntdll/testlist.c | 2 + 3 files changed, 529 insertions(+), 1 deletion(-) create mode 100644 rostests/apitests/ntdll/RtlMemoryStream.c diff --git a/rostests/apitests/ntdll/CMakeLists.txt b/rostests/apitests/ntdll/CMakeLists.txt index 4fb7da1ee99..9404d89918f 100644 --- a/rostests/apitests/ntdll/CMakeLists.txt +++ b/rostests/apitests/ntdll/CMakeLists.txt @@ -21,6 +21,7 @@ list(APPEND SOURCE RtlGetLengthWithoutTrailingPathSeperators.c RtlGetLongestNtPathLength.c RtlInitializeBitMap.c + RtlMemoryStream.c SystemInfo.c Timer.c testlist.c) @@ -30,7 +31,7 @@ if(ARCH STREQUAL "i386") endif() add_executable(ntdll_apitest ${SOURCE} ${ntdll_apitest_asm}) -target_link_libraries(ntdll_apitest wine ${PSEH_LIB}) +target_link_libraries(ntdll_apitest wine uuid ${PSEH_LIB}) set_module_type(ntdll_apitest win32cui) add_importlibs(ntdll_apitest msvcrt advapi32 kernel32 ntdll) diff --git a/rostests/apitests/ntdll/RtlMemoryStream.c b/rostests/apitests/ntdll/RtlMemoryStream.c new file mode 100644 index 00000000000..e2ae475d74c --- /dev/null +++ b/rostests/apitests/ntdll/RtlMemoryStream.c @@ -0,0 +1,525 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPLv2+ - See COPYING in the top level directory + * PURPOSE: Test for the Rtl*MemoryStream* series of functions + * PROGRAMMER: David Quintana + */ + +#define COBJMACROS + +#include +#include +#include +#include + +ULONG finalReleaseCallCount = 0; + +VOID +NTAPI +CustomFinalReleaseMemoryStream(PRTL_MEMORY_STREAM stream) +{ + finalReleaseCallCount++; + trace("FinalRelease CALLED.\n"); +} + +VOID +NTAPI +CustomFinalReleaseOutOfProcessMemoryStream(PRTL_MEMORY_STREAM stream) +{ + finalReleaseCallCount++; + trace("FinalRelease CALLED.\n"); + RtlFinalReleaseOutOfProcessMemoryStream(stream); +} + +BOOL CompareStructsAndSaveForLater(PRTL_MEMORY_STREAM pold, PRTL_MEMORY_STREAM pnew, PSTR at) +{ + BOOL equal = TRUE; + + // Compare + if (pold->Vtbl != pnew->Vtbl) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("Vtbl changed from %p to %p\n", pold->Vtbl, pnew->Vtbl);} + if (pold->RefCount != pnew->RefCount) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("RefCount changed from %p to %p\n", pold->RefCount, pnew->RefCount); } + if (pold->Unk1 != pnew->Unk1) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("Unk1 changed from %p to %p\n", pold->Unk1, pnew->Unk1); } + if (pold->Current != pnew->Current) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("Current changed from %p to %p\n", pold->Current, pnew->Current); } + if (pold->Start != pnew->Start) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("Start changed from %p to %p\n", pold->Start, pnew->Start); } + if (pold->End != pnew->End) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("End changed from %p to %p\n", pold->End, pnew->End); } + if (pold->FinalRelease != pnew->FinalRelease) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("FinalRelease changed from %p to %p\n", pold->FinalRelease, pnew->FinalRelease); } + if (pold->ProcessHandle != pnew->ProcessHandle) { if (equal) { trace("%s: \n", at); equal = FALSE; } trace("ProcessHandle changed from %p to %p\n", pold->ProcessHandle, pnew->ProcessHandle); } + + // Save + pold->Vtbl = pnew->Vtbl; + pold->RefCount = pnew->RefCount; + pold->Unk1 = pnew->Unk1; + pold->Current = pnew->Current; + pold->Start = pnew->Start; + pold->End = pnew->End; + pold->FinalRelease = pnew->FinalRelease; + pold->ProcessHandle = pnew->ProcessHandle; + + return equal; +} + +void test_InProcess() +{ + LARGE_INTEGER move; + ULARGE_INTEGER size; + HRESULT res; + ULONG i; + + RTL_MEMORY_STREAM stream; + RTL_MEMORY_STREAM previous; + + IStream * istream; + + UCHAR buffer[80]; + UCHAR buffer2[180]; + ULONG bytesRead; + + STATSTG stat; + + finalReleaseCallCount = 0; + + for (i = 0; i < sizeof(buffer2); i++) + { + buffer2[i] = i % UCHAR_MAX; + } + + memset(&stream, 0x90, sizeof(stream)); + memset(&previous, 0x00, sizeof(previous)); + + StartSeh() + RtlInitMemoryStream(NULL); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + RtlInitMemoryStream(&stream); + EndSeh(STATUS_SUCCESS); + + CompareStructsAndSaveForLater(&previous, &stream, "After init"); + + ok(stream.RefCount == 0, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 0); + + stream.Current = buffer2; + stream.Start = buffer2; + stream.End = buffer2 + sizeof(buffer2); + stream.FinalRelease = CustomFinalReleaseMemoryStream; + + CompareStructsAndSaveForLater(&previous, &stream, "After assigning"); + + StartSeh() + res = IStream_QueryInterface((struct IStream*)&stream, NULL, NULL); + ok(res == E_INVALIDARG, "QueryInterface to IStream returned wrong hResult: 0x%08x.\n", res); + ok(stream.RefCount == 0, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 2); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + res = IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, NULL); + ok(res == E_INVALIDARG, "QueryInterface to IStream returned wrong hResult: 0x%08x.\n", res); + ok(stream.RefCount == 1, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 2); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + res = IStream_QueryInterface((struct IStream*)&stream, NULL, (void**)&istream); + ok(res == E_INVALIDARG, "QueryInterface to IStream returned wrong hResult: 0x%08x.\n", res); + ok(stream.RefCount == 1, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 2); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + res = IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, (void**)&istream); + ok(res == S_OK, "QueryInterface to IStream returned wrong hResult: 0x%08x.\n", res); + ok(stream.RefCount == 2, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 2); + EndSeh(STATUS_SUCCESS); + + CompareStructsAndSaveForLater(&previous, &stream, "After QueryInterface"); + + StartSeh() + res = IStream_Stat(istream, NULL, 0); + ok(res == STG_E_INVALIDPOINTER, "Stat to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_Stat(istream, &stat, STATFLAG_NONAME); + ok(res == S_OK, "Stat to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_SUCCESS); + + ok(stream.Current == buffer2, + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + + ok(stat.cbSize.QuadPart == ((PUCHAR)stream.End - (PUCHAR)stream.Start), + "stat.cbSize has the wrong value %lld (expected %d)\n", + stat.cbSize.QuadPart, (PUCHAR)stream.End - (PUCHAR)stream.Start); + + CompareStructsAndSaveForLater(&previous, &stream, "After Stat"); + + StartSeh() + res = IStream_AddRef(istream); + ok(res == 3, "AddRef to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_AddRef(istream); + ok(res == 4, "AddRef to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_Release(istream); + ok(res == 3, "Release to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_AddRef(istream); + ok(res == 4, "AddRef to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_Release(istream); + ok(res == 3, "Release to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_Release(istream); + ok(res == 2, "Release to IStream returned wrong hResult: %d.\n", res); + EndSeh(STATUS_SUCCESS); + + CompareStructsAndSaveForLater(&previous, &stream, "After AddRef"); + + StartSeh() + res = IStream_Read(istream, NULL, 0, &bytesRead); + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_SUCCESS); + + StartSeh() + res = IStream_Read(istream, buffer, 40, NULL); + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_ACCESS_VIOLATION); + + StartSeh() + res = IStream_Read(istream, buffer + 40, 39, &bytesRead); + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_SUCCESS); + + if (SUCCEEDED(res)) + { + bytesRead += 40; + for (i = 0; i < bytesRead; i++) + { + ok(buffer[i] == i, "Buffer[%d] contains a wrong number %d (expected %d).\n", i, buffer[i], i); + } + } + + ok(stream.Current == buffer2 + 79, + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + + CompareStructsAndSaveForLater(&previous, &stream, "After Read 1"); + + size.QuadPart = 0x9090909090909090ull; + + StartSeh() + move.QuadPart = -1; + res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08x,0x%08x).\n", size.HighPart, size.LowPart); + EndSeh(STATUS_SUCCESS); + + StartSeh() + move.QuadPart = 0; + res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); + EndSeh(STATUS_SUCCESS); + + size.QuadPart = 0x9090909090909090ull; + + StartSeh() + move.QuadPart = 1; + res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start - 1, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); + EndSeh(STATUS_SUCCESS); + + size.QuadPart = 0x9090909090909090ull; + + StartSeh() + move.QuadPart = 2; + res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start - 2, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); + EndSeh(STATUS_SUCCESS); + + size.QuadPart = 0x9090909090909090ull; + + StartSeh() + move.QuadPart = -20; + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error.\n"); + EndSeh(STATUS_SUCCESS); + + StartSeh() + move.QuadPart = 4000; + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error.\n"); + EndSeh(STATUS_SUCCESS); + + StartSeh() + move.QuadPart = 0x100000000ull; + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); +#ifdef _WIN64 + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08x,0x%08x).\n", size.HighPart, size.LowPart); +#else + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); +#endif + EndSeh(STATUS_SUCCESS); + +#ifdef _WIN64 + StartSeh() + move.QuadPart = 0; + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); + EndSeh(STATUS_SUCCESS); +#endif + + size.QuadPart = 0x9090909090909090ull; + + StartSeh() + move.QuadPart = -20; + res = IStream_Seek(istream, move, STREAM_SEEK_CUR, &size); + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08x,0x%08x).\n", size.HighPart, size.LowPart); + EndSeh(STATUS_SUCCESS); + + StartSeh() + move.QuadPart = 0x100000000ull; + res = IStream_Seek(istream, move, STREAM_SEEK_CUR, &size); +#ifdef _WIN64 + ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08x,0x%08x).\n", size.HighPart, size.LowPart); +#else + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08x.\n", size.LowPart); +#endif + EndSeh(STATUS_SUCCESS); + + StartSeh() + move.QuadPart = 40; + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + EndSeh(STATUS_SUCCESS); + + ok(size.QuadPart == 40, + "Seek returned wrong offset %lld (expected %d)\n", + size.QuadPart, 40); + + ok(stream.Current == buffer2 + 40, + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + + CompareStructsAndSaveForLater(&previous, &stream, "After Seek"); + + res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); + + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + + if (SUCCEEDED(res)) + { + for (i = 0; i < bytesRead; i++) + { + ok(buffer[i] == (i + 40), "Buffer[%d] contains a wrong number %d (expected %d).\n", i, buffer[i], i + 40); + } + } + + ok(stream.Current == buffer2 + 40 + sizeof(buffer), + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + + CompareStructsAndSaveForLater(&previous, &stream, "After Read 2"); + + res = IStream_Release(istream); + + ok(res == 1, "Release to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(stream.RefCount == 1, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 1); + + res = IStream_Release(istream); + + ok(res == S_OK, "Release to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(stream.RefCount == 0, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 0); + + ok(finalReleaseCallCount == 1, "FinalRelease was called %d times instead of 1.\n", finalReleaseCallCount); +} + +void test_OutOfProcess() +{ + LARGE_INTEGER move; + ULARGE_INTEGER size; + HRESULT res; + HANDLE process; + ULONG i; + + RTL_MEMORY_STREAM stream; + RTL_MEMORY_STREAM previous; + + IStream * istream; + + UCHAR buffer[80]; + UCHAR buffer2[180]; + ULONG bytesRead; + + STATSTG stat; + + finalReleaseCallCount = 0; + + for (i = 0; i < sizeof(buffer2); i++) + { + buffer2[i] = i % UCHAR_MAX; + } + + memset(&stream, 0x90, sizeof(stream)); + memset(&previous, 0x00, sizeof(previous)); + + process = GetCurrentProcess(); + + RtlInitOutOfProcessMemoryStream(&stream); + + ok(stream.FinalRelease == RtlFinalReleaseOutOfProcessMemoryStream, + "stream.FinalRelease unexpected %p != %p.\n", + stream.FinalRelease, RtlFinalReleaseOutOfProcessMemoryStream); + + ok(stream.RefCount == 0, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 0); + + CompareStructsAndSaveForLater(&previous, &stream, "After init"); + + stream.Current = buffer2; + stream.Start = buffer2; + stream.End = buffer2 + sizeof(buffer2); + stream.ProcessHandle = process; + stream.FinalRelease = CustomFinalReleaseOutOfProcessMemoryStream; + + CompareStructsAndSaveForLater(&previous, &stream, "After assigning"); + + res = IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, (void**)&istream); + + ok(res == S_OK, "QueryInterface to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(stream.RefCount == 1, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 1); + + ok(stream.ProcessHandle == process, + "ProcessHandle changed unexpectedly: 0x%08x (expected 0x%p)\n", + stream.ProcessHandle, process); + + CompareStructsAndSaveForLater(&previous, &stream, "After QueryInterface"); + + res = IStream_Stat(istream, &stat, STATFLAG_NONAME); + + ok(res == S_OK, "Stat to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(stream.Current == buffer2, + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + ok(stream.ProcessHandle == process, + "ProcessHandle changed unexpectedly: 0x%08x (expected 0x%p)\n", + stream.ProcessHandle, process); + + ok(stat.cbSize.QuadPart == ((PUCHAR)stream.End - (PUCHAR)stream.Start), + "stat.cbSize has the wrong value %lld (expected %d)\n", + stat.cbSize.QuadPart, (PUCHAR)stream.End - (PUCHAR)stream.Start); + + CompareStructsAndSaveForLater(&previous, &stream, "After Stat"); + + res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); + + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + + if (SUCCEEDED(res)) + { + for (i = 0; i < bytesRead; i++) + { + ok(buffer[i] == i, "Buffer[%d] contains a wrong number %d (expected %d).\n", i, buffer[i], i); + } + } + + ok(stream.Current == buffer2 + sizeof(buffer), + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + ok(stream.ProcessHandle == process, + "ProcessHandle changed unexpectedly: 0x%08x (expected 0x%p)\n", + stream.ProcessHandle, process); + + CompareStructsAndSaveForLater(&previous, &stream, "After Read 1"); + + move.QuadPart = 40; + + res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); + + ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(size.QuadPart == 40, + "Seek returned wrong offset %lld (expected %d)\n", + size.QuadPart, 40); + + ok(stream.Current == buffer2 + 40, + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + ok(stream.ProcessHandle == process, + "ProcessHandle changed unexpectedly: 0x%08x (expected 0x%p)\n", + stream.ProcessHandle, process); + + CompareStructsAndSaveForLater(&previous, &stream, "After Seek"); + + res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); + + ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08x.\n", res); + + if (SUCCEEDED(res)) + { + for (i = 0; i < bytesRead; i++) + { + ok(buffer[i] == (i + 40), "Buffer[%d] contains a wrong number %d (expected %d).\n", i, buffer[i], i + 40); + } + } + + ok(stream.Current == buffer2 + 40 + sizeof(buffer), + "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", + stream.Current, buffer2); + ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); + ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); + ok(stream.ProcessHandle == process, + "ProcessHandle changed unexpectedly: 0x%08x (expected 0x%p)\n", + stream.ProcessHandle, process); + + CompareStructsAndSaveForLater(&previous, &stream, "After Read 2"); + + res = IStream_Release(istream); + + ok(res == S_OK, "Release to IStream returned wrong hResult: 0x%08x.\n", res); + + ok(stream.RefCount == 0, "RefCount has a wrong value: %d (expected %d).\n", stream.RefCount, 0); + + ok(finalReleaseCallCount == 1, "FinalRelease was called %d times instead of 1.\n", finalReleaseCallCount); +} + +START_TEST(RtlMemoryStream) +{ + test_InProcess(); + test_OutOfProcess(); +} diff --git a/rostests/apitests/ntdll/testlist.c b/rostests/apitests/ntdll/testlist.c index 8dfa718cee7..0f45d260e6b 100644 --- a/rostests/apitests/ntdll/testlist.c +++ b/rostests/apitests/ntdll/testlist.c @@ -25,6 +25,7 @@ extern void func_RtlGetFullPathName_UstrEx(void); extern void func_RtlGetLengthWithoutTrailingPathSeperators(void); extern void func_RtlGetLongestNtPathLength(void); extern void func_RtlInitializeBitMap(void); +extern void func_RtlMemoryStream(void); extern void func_TimerResolution(void); const struct test winetest_testlist[] = @@ -51,6 +52,7 @@ const struct test winetest_testlist[] = { "RtlGetLengthWithoutTrailingPathSeperators", func_RtlGetLengthWithoutTrailingPathSeperators }, { "RtlGetLongestNtPathLength", func_RtlGetLongestNtPathLength }, { "RtlInitializeBitMap", func_RtlInitializeBitMap }, + { "RtlMemoryStream", func_RtlMemoryStream }, { "TimerResolution", func_TimerResolution }, { 0, 0 } From 4385bb351df692d8b28c34d4acd5967640811629 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 19 Oct 2013 18:04:15 +0000 Subject: [PATCH 19/36] [NTOSKRNL] Rewrite NtCallbackReturn in C svn path=/trunk/; revision=60709 --- reactos/ntoskrnl/include/internal/ke.h | 8 ++ reactos/ntoskrnl/ke/i386/usercall.c | 135 ++++++++++++++++++ reactos/ntoskrnl/ke/i386/usercall_asm.S | 176 +----------------------- 3 files changed, 150 insertions(+), 169 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 78dfe6897e4..d90cf1b0eb8 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -1050,6 +1050,14 @@ KiCallUserMode( IN PULONG OutputLength ); +DECLSPEC_NORETURN +VOID +FASTCALL +KiCallbackReturn( + IN PVOID Stack, + IN NTSTATUS Status +); + VOID NTAPI KiInitMachineDependent(VOID); diff --git a/reactos/ntoskrnl/ke/i386/usercall.c b/reactos/ntoskrnl/ke/i386/usercall.c index 91bd672ae4a..8876da053aa 100644 --- a/reactos/ntoskrnl/ke/i386/usercall.c +++ b/reactos/ntoskrnl/ke/i386/usercall.c @@ -351,5 +351,140 @@ KiUserModeCallout(PKCALLOUT_FRAME CalloutFrame) KiServiceExit(CallbackTrapFrame, 0); } +/*++ + * @name NtCallbackReturn + * + * The NtCallbackReturn routine returns to kernel mode after a user-mode + * callback was done through KeUserModeCallback. It uses the callback frame + * which was setup in order to return the information, restores the stack, + * and resumes execution where it was left off. + * + * @param Result + * Pointer to a caller-allocated buffer where the return data + * from the user-mode function is located. + * + * @param ResultLength + * Size of the Output Buffer described above. + * + * @param CallbackStatus + * Status code of the callback operation. + * + * @return Status code of the callback operation. + * + * @remark This call MUST be paired with KeUserModeCallback. + * + *--*/ +NTSTATUS +NTAPI +NtCallbackReturn( + _In_ PVOID Result, + _In_ ULONG ResultLength, + _In_ NTSTATUS CallbackStatus) +{ + PKTHREAD CurrentThread; + PKCALLOUT_FRAME CalloutFrame; + PKTRAP_FRAME CallbackTrapFrame, TrapFrame; + PFX_SAVE_AREA FxSaveArea, CbFxSaveArea; + ULONG Size; + PKPCR Pcr; + PKTSS Tss; + + /* Get the current thread and make sure we have a callback stack */ + CurrentThread = KeGetCurrentThread(); + CalloutFrame = CurrentThread->CallbackStack; + if (CalloutFrame == NULL) + { + return STATUS_NO_CALLBACK_ACTIVE; + } + + /* Get the trap frame */ + CallbackTrapFrame = CurrentThread->TrapFrame; + + /* Restore the exception list */ + Pcr = KeGetPcr(); + Pcr->NtTib.ExceptionList = CallbackTrapFrame->ExceptionList; + + /* Store the results in the callback stack */ + *((PVOID*)CalloutFrame->Result) = Result; + *((ULONG*)CalloutFrame->ResultLength) = ResultLength; + + /* Disable interrupts for NPX save and stack switch */ + _disable(); + + /* Set desination and origin NPX Frames */ + CbFxSaveArea = (PVOID)((ULONG)CurrentThread->InitialStack - sizeof(FX_SAVE_AREA)); + FxSaveArea = (PVOID)(CalloutFrame->InitialStack - sizeof(FX_SAVE_AREA)); + + /* Now copy back NPX State */ + FxSaveArea->U.FnArea.ControlWord = CbFxSaveArea->U.FnArea.ControlWord; + FxSaveArea->U.FnArea.StatusWord = CbFxSaveArea->U.FnArea.StatusWord; + FxSaveArea->U.FnArea.TagWord = CbFxSaveArea->U.FnArea.TagWord; + FxSaveArea->U.FnArea.DataSelector = CbFxSaveArea->U.FnArea.DataSelector; + FxSaveArea->Cr0NpxState = CbFxSaveArea->Cr0NpxState; + + /* Get the previous trap frame */ + TrapFrame = (PKTRAP_FRAME)CalloutFrame->TrapFrame; + + /* Check if we failed in user mode */ + if (CallbackStatus == STATUS_CALLBACK_POP_STACK) + { + /* Check if we came from v86 mode */ + if (CallbackTrapFrame->EFlags & EFLAGS_V86_MASK) + { + Size = sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, SegFs); + } + else + { + Size = FIELD_OFFSET(KTRAP_FRAME, V86Es) - FIELD_OFFSET(KTRAP_FRAME, SegFs); + } + + /* Copy back part of the trap frame */ + RtlCopyMemory(&TrapFrame->SegFs, &CallbackTrapFrame->SegFs, Size); + } + + /* Clear DR7 */ + TrapFrame->Dr7 = 0; + + /* Check if debugging was active */ + if (CurrentThread->Header.DebugActive & 0xFF) + { + /* Copy debug registers data from it */ + TrapFrame->Dr0 = CallbackTrapFrame->Dr0; + TrapFrame->Dr1 = CallbackTrapFrame->Dr1; + TrapFrame->Dr2 = CallbackTrapFrame->Dr2; + TrapFrame->Dr3 = CallbackTrapFrame->Dr3; + TrapFrame->Dr6 = CallbackTrapFrame->Dr6; + TrapFrame->Dr7 = CallbackTrapFrame->Dr7; + } + + /* Get TSS */ + Tss = Pcr->TSS; + + /* Check for V86 mode */ + if (TrapFrame->EFlags & EFLAGS_V86_MASK) + { + /* Set new stack address in TSS (full trap frame) */ + Tss->Esp0 = (ULONG_PTR)(TrapFrame + 1); + } + else + { + /* Set new stack address in TSS (non-V86 trap frame) */ + Tss->Esp0 = (ULONG_PTR)&TrapFrame->V86Es; + } + + /* Get the initial stack and restore it */ + CurrentThread->InitialStack = (PVOID)CalloutFrame->InitialStack; + + /* Restore the trap frame and the previous callback stack */ + CurrentThread->TrapFrame = TrapFrame; + CurrentThread->CallbackStack = (PVOID)CalloutFrame->CallbackStack; + + /* Bring interrupts back */ + _enable(); + + /* Now switch back to the old stack */ + KiCallbackReturn(&CalloutFrame->Edi, CallbackStatus); +} + /* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/usercall_asm.S b/reactos/ntoskrnl/ke/i386/usercall_asm.S index 2a48a5f4f8d..5b2fbd07540 100644 --- a/reactos/ntoskrnl/ke/i386/usercall_asm.S +++ b/reactos/ntoskrnl/ke/i386/usercall_asm.S @@ -76,184 +76,22 @@ _KiCallUserMode@8: ret 8 -/*++ - * @name NtCallbackReturn - * - * The NtCallbackReturn routine returns to kernel mode after a user-mode - * callback was done through KeUserModeCallback. It uses the callback frame - * which was setup in order to return the information, restores the stack, - * and resumes execution where it was left off. - * - * @param Result - * Pointer to a caller-allocated buffer where the return data - * from the user-mode function is located. - * - * @param ResultLength - * Size of the Output Buffer described above. - * - * @param CallbackStatus - * Status code of the callback operation. - * - * @return Status code of the callback operation. - * - * @remark This call MUST be paired with KeUserModeCallback. - * - *--*/ -PUBLIC _NtCallbackReturn@12 -_NtCallbackReturn@12: - /* Get the current thread and make sure we have a callback stack */ - mov eax, fs:[KPCR_CURRENT_THREAD] - mov ecx, [eax+KTHREAD_CALLBACK_STACK] - test ecx, ecx - jz NoStack +PUBLIC @KiCallbackReturn@8 +@KiCallbackReturn@8: - /* Get the trap frame */ - mov ebx, [eax+KTHREAD_TRAP_FRAME] - - /* Restore the exception list */ - mov edx, [ebx+KTRAP_FRAME_EXCEPTION_LIST] - mov fs:[KPCR_EXCEPTION_LIST], edx - - /* Get the result, the result length and the status */ - mov edi, [esp+4] - mov esi, [esp+8] - mov ebp, [esp+12] - - /* Store the results in the callback stack */ - mov ebx, [ecx+CBSTACK_RESULT] - mov [ebx], edi - mov ebx, [ecx+CBSTACK_RESULT_LENGTH] - mov [ebx], esi - - /* Get the previous stack */ - mov ebx, [ecx] - - /* Disable interrupts for NPX save and stack switch */ - cli - - /* Get the initial stack and restore it */ - mov esi, [eax+KTHREAD_INITIAL_STACK] - mov [eax+KTHREAD_INITIAL_STACK], ebx - - /* Set desination and origin NPX Frames */ - sub esi, NPX_FRAME_LENGTH - sub ebx, NPX_FRAME_LENGTH - - /* Copy NPX Data */ - mov edx, [esi+FP_CONTROL_WORD] - mov [ebx+FP_CONTROL_WORD], edx - mov edx, [esi+FP_STATUS_WORD] - mov [ebx+FP_STATUS_WORD], edx - mov edx, [esi+FP_TAG_WORD] - mov [ebx+FP_TAG_WORD], edx - mov edx, [esi+FP_DATA_SELECTOR] - mov [ebx+FP_DATA_SELECTOR], edx - mov edx, [esi+FN_CR0_NPX_STATE] - mov [ebx+FN_CR0_NPX_STATE], edx - - /* Check if we failed in user mode */ - cmp ebp, STATUS_CALLBACK_POP_STACK - mov edi, [ecx+CBSTACK_TRAP_FRAME] - jz UserFault - -CheckDebug: - - /* Clear DR7 */ - and dword ptr [edi+KTRAP_FRAME_DR7], 0 - - /* Check if debugging was active */ - test byte ptr [eax+KTHREAD_DEBUG_ACTIVE], HEX(0FF) - jnz RestoreDebug - -RestoreStack: - - /* Get TSS */ - mov edx, fs:[KPCR_TSS] - - /* Restore stack pointer */ - lea esp, [ecx+CBSTACK_CALLBACK_STACK] - - /* Check if we were in V86 mode */ - test dword ptr [edi+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK - jnz V86Ret - sub ebx, 16 - -V86Ret: - /* Restore the ESP in TSS */ - mov [edx+KTSS_ESP0], ebx - - /* Restore the trap frame */ - mov [eax+KTHREAD_TRAP_FRAME], edi - - /* Bring interrupts back */ - sti - - /* Restore the callback stack*/ - pop [eax+KTHREAD_CALLBACK_STACK] + /* Restore the stack */ + mov esp, ecx /* Set status and return */ - mov eax, ebp + mov eax, edx pop edi pop esi pop ebx pop ebp - pop edx - /* Clean stack and jump back */ - add esp, 8 - jmp edx - -UserFault: - /* Set size to copy */ - mov ecx, (KTRAP_FRAME_V86_ES - KTRAP_FRAME_FS) / 4 - - /* Check if this was V86 mode */ - mov esi, [eax+KTHREAD_TRAP_FRAME] - test dword ptr [esi+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK - - /* Save EDI and load destination */ - mov edx, edi - lea edi, [edi+KTRAP_FRAME_FS] - jz NotV86 - add ecx, 16 / 4 - -NotV86: - /* Set source and copy */ - lea esi, [esi+KTRAP_FRAME_FS] - rep movsd - - /* Restore ECX and ECX */ - mov ecx, [eax+KTHREAD_CALLBACK_STACK] - mov edi, edx - jmp CheckDebug - -RestoreDebug: - /* Get a pointer to thread's trap frame */ - mov esi, [eax+KTHREAD_TRAP_FRAME] - - /* Copy debug registers data from it */ - mov edx, [esi+KTRAP_FRAME_DR0] - mov [edi+KTRAP_FRAME_DR0], edx - mov edx, [esi+KTRAP_FRAME_DR1] - mov [edi+KTRAP_FRAME_DR1], edx - mov edx, [esi+KTRAP_FRAME_DR2] - mov [edi+KTRAP_FRAME_DR2], edx - mov edx, [esi+KTRAP_FRAME_DR3] - mov [edi+KTRAP_FRAME_DR3], edx - mov edx, [esi+KTRAP_FRAME_DR6] - mov [edi+KTRAP_FRAME_DR6], edx - mov edx, [esi+KTRAP_FRAME_DR7] - mov [edi+KTRAP_FRAME_DR7], edx - - /* Jump back */ - jmp RestoreStack - -NoStack: - - /* Return failure */ - mov eax, STATUS_NO_CALLBACK_ACTIVE - ret 12 + /* Clean stack and return */ + ret 8 /*++ * @name KeSwitchKernelStack From ccfd05479b7f48e5694f60362999d2bc035c1362 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sat, 19 Oct 2013 19:08:41 +0000 Subject: [PATCH 20/36] - Remove a mislaid artifact. svn path=/trunk/; revision=60713 --- reactos/win32ss/user/user32/windows/prop.c | 1 - 1 file changed, 1 deletion(-) diff --git a/reactos/win32ss/user/user32/windows/prop.c b/reactos/win32ss/user/user32/windows/prop.c index 1b06d7f58bb..8f9b1b8c2c4 100644 --- a/reactos/win32ss/user/user32/windows/prop.c +++ b/reactos/win32ss/user/user32/windows/prop.c @@ -53,7 +53,6 @@ IntGetProp(HWND hWnd, ATOM Atom) for (i = 0; i < pWnd->PropListItems; i++ ) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); - if (!Property) break; if (Property->Atom == Atom) { return(Property); From d700b033fcc8330ad8d7ca9a057f9a4be5bf5931 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Oct 2013 05:16:52 +0000 Subject: [PATCH 21/36] [Win32k] - The (ATI) patch CORE-6551. Please oh please use this jira core issue for all bug reports and regressions. - Major rewrite to input message queue. It is now attachable between threads. After all the hubbub the only thing we pass are all the SetActive/Foreground/Parent/Window wine msg and win tests. But not the message sequence tests. - Pass all but one foreground API User32 ATI test when the message patch is installed. But w/o it, pass all but 8'ish. - Tested XP osk (On-Screen Keyboard) with CMD, it works but is quirky. Need to look into set to top window issues. - AHK issues work long as ATI is used and when it is not the some AHK tests fail. That was why all the hot key changes had been committed before. Still looking into this. - Please test everything and post to the appropriate jira issue reports. I do not have a lot of time anymore to focus hard on many issues, it will take months to do so with just one. svn path=/trunk/; revision=60718 --- reactos/win32ss/user/ntuser/desktop.c | 5 +- reactos/win32ss/user/ntuser/desktop.h | 3 +- reactos/win32ss/user/ntuser/focus.c | 271 +++++++++++++++++------ reactos/win32ss/user/ntuser/focus.h | 4 +- reactos/win32ss/user/ntuser/input.c | 175 ++++++++------- reactos/win32ss/user/ntuser/input.h | 2 +- reactos/win32ss/user/ntuser/keyboard.c | 36 ++-- reactos/win32ss/user/ntuser/main.c | 70 +++--- reactos/win32ss/user/ntuser/message.c | 77 ++++--- reactos/win32ss/user/ntuser/misc.c | 6 +- reactos/win32ss/user/ntuser/msgqueue.c | 45 ++-- reactos/win32ss/user/ntuser/msgqueue.h | 1 - reactos/win32ss/user/ntuser/object.c | 7 + reactos/win32ss/user/ntuser/object.h | 1 + reactos/win32ss/user/ntuser/window.c | 120 +++++++---- reactos/win32ss/user/ntuser/winpos.c | 288 +++++++++++++++++++------ 16 files changed, 769 insertions(+), 342 deletions(-) diff --git a/reactos/win32ss/user/ntuser/desktop.c b/reactos/win32ss/user/ntuser/desktop.c index e67ac78aee1..8b073dc0dcf 100644 --- a/reactos/win32ss/user/ntuser/desktop.c +++ b/reactos/win32ss/user/ntuser/desktop.c @@ -28,7 +28,7 @@ IntFreeDesktopHeap(IN PDESKTOP pdesk); /* Currently active desktop */ PDESKTOP gpdeskInputDesktop = NULL; HDC ScreenDeviceContext = NULL; -PTHREADINFO gptiDesktopThread; +PTHREADINFO gptiDesktopThread = NULL; HCURSOR gDesktopCursor = NULL; /* OBJECT CALLBACKS **********************************************************/ @@ -834,6 +834,9 @@ VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam) return; } + // Allow other devices have a shot at foreground. + if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL; + // FIXME: System Tray Support. HwndList = UserBuildShellHookHwndList(Desktop); diff --git a/reactos/win32ss/user/ntuser/desktop.h b/reactos/win32ss/user/ntuser/desktop.h index 25e1f9e331c..9d2fd2ef284 100644 --- a/reactos/win32ss/user/ntuser/desktop.h +++ b/reactos/win32ss/user/ntuser/desktop.h @@ -69,9 +69,10 @@ typedef struct _DESKTOP DESKTOP_SWITCHDESKTOP | \ DESKTOP_WRITEOBJECTS -extern PDESKTOP InputDesktop; +extern PDESKTOP gpdeskInputDesktop; extern PCLS DesktopWindowClass; extern HDC ScreenDeviceContext; +extern PTHREADINFO gptiForeground; extern PTHREADINFO gptiDesktopThread; typedef struct _SHELL_HOOK_WINDOW diff --git a/reactos/win32ss/user/ntuser/focus.c b/reactos/win32ss/user/ntuser/focus.c index 8902c129b84..cf79511c2d9 100644 --- a/reactos/win32ss/user/ntuser/focus.c +++ b/reactos/win32ss/user/ntuser/focus.c @@ -80,7 +80,7 @@ BOOL FASTCALL co_IntMakeWindowActive(PWND Window) { PWND spwndOwner; - if (Window) + if (VerifyWnd(Window)) { // Set last active for window and it's owner. spwndOwner = Window; while (spwndOwner->spwndOwner) @@ -132,6 +132,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO { UINT flags = SWP_NOSIZE | SWP_NOMOVE; if (Window == pwndTemp) flags |= SWP_NOACTIVATE; + //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground); co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags); } } @@ -156,8 +157,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO if ( OldTID ) { ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG; - ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags; - + // Note: Do not set pci flags, this does crash! for (phWnd = List; *phWnd; ++phWnd) { cWindow = ValidateHwndNoErr(*phWnd); @@ -168,13 +168,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO } } ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG; - ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags; } if ( NewTID ) { //// Prevents a resource crash due to reentrance! InAAPM = TRUE; pti->TIF_flags |= TIF_INACTIVATEAPPMSG; - pti->pClientInfo->dwTIFlags = pti->TIF_flags; //// for (phWnd = List; *phWnd; ++phWnd) { @@ -186,7 +184,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO } } } - ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + ExFreePool(List);//ExFreePoolWithTag(List, USERTAG_WINDOWLIST); } } if (WindowPrev) @@ -205,12 +203,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO co_IntMakeWindowActive(Window); - UserDerefObjectCo(Window); - /* FIXME: IntIsWindow */ + co_IntSendMessageNoWait( UserHMGetHandle(Window), WM_NCACTIVATE, - (WPARAM)(gpqForeground ? (Window == gpqForeground->spwndActive) : FALSE), + (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)), 0); //(LPARAM)hWndPrev); co_IntSendMessageNoWait( UserHMGetHandle(Window), @@ -226,6 +223,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO Window->state &= ~WNDS_NONCPAINT; + UserDerefObjectCo(Window); } return InAAPM; } @@ -294,7 +292,7 @@ IntFindChildWindowToOwner(PWND Root, PWND Owner) } VOID FASTCALL -FindRemoveAsyncMsg(PWND Wnd) +FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam) { PTHREADINFO pti; PUSER_SENT_MESSAGE Message; @@ -311,20 +309,60 @@ FindRemoveAsyncMsg(PWND Wnd) Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); do { + if (IsListEmpty(Entry)) return; + if (!Message) return; + Entry = Message->ListEntry.Flink; + if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW && Message->Msg.hwnd == UserHMGetHandle(Wnd) && - Message->Msg.wParam == 0 ) + Message->Msg.wParam == wParam ) { - TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd); - RemoveEntryList(Entry); // Purge the entry. + ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam); + RemoveEntryList(&Message->ListEntry); // Purge the entry. + ExFreePoolWithTag(Message, TAG_USRMSG); } - Entry = Message->ListEntry.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); } while (Entry != &pti->SentMessagesListHead); } } +BOOL FASTCALL +ToggleFGActivate(PTHREADINFO pti) +{ + BOOL Ret; + PPROCESSINFO ppi = pti->ppi; + + Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE); + if (Ret) + { + pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; + } + else + Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE); + + if (Ret) + ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE; + //ERR("ToggleFGActivate is %d\n",Ret); + return Ret; +} + +BOOL FASTCALL +IsAllowedFGActive(PTHREADINFO pti, PWND Wnd) +{ + // Not allowed if one or more,, + if (!ToggleFGActivate(pti) || // bits not set, + pti->rpdesk != gpdeskInputDesktop || // not current Desktop, + pti->MessageQueue == gpqForeground || // if already the queue foreground, + IsFGLocked() || // foreground is locked, + Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it. + { + return FALSE; + } + //ERR("IsAllowedFGActive is TRUE\n"); + return TRUE; +} + /* Can the system force foreground from one or more conditions. */ @@ -339,6 +377,7 @@ CanForceFG(PPROCESSINFO ppi) gppiInputProvider == ppi || !gpqForeground ) return TRUE; + //ERR("CanForceFG is FALSE\n"); return FALSE; } @@ -356,37 +395,35 @@ CanForceFG(PPROCESSINFO ppi) * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). * No menus are active. */ - -static BOOL FASTCALL +static +BOOL FASTCALL co_IntSetForegroundAndFocusWindow( _In_ PWND Wnd, _In_ BOOL MouseActivate) { - HWND hWnd; + HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL; HWND hWndPrev = NULL; + PWND pWndPrev = NULL; PUSER_MESSAGE_QUEUE PrevForegroundQueue; PTHREADINFO pti; BOOL fgRet = FALSE, Ret = FALSE; - ASSERT_REFS_CO(Wnd); - NT_ASSERT(Wnd != NULL); + if (Wnd) ASSERT_REFS_CO(Wnd); - hWnd = UserHMGetHandle(Wnd); - - TRACE("SetForegroundAndFocusWindow(%p, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); + //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop. pti = PsGetCurrentThreadWin32Thread(); if (PrevForegroundQueue) { // Same Window Q as foreground just do active. - //ERR("Same Window Q as foreground just do active.\n"); if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue) { + //ERR("Same Window Q as foreground just do active.\n"); if (pti->MessageQueue == PrevForegroundQueue) { // Same WQ and TQ go active. //ERR("Same WQ and TQ go active.\n"); - Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE); + Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { // Same WQ and it is active. @@ -396,13 +433,14 @@ co_IntSetForegroundAndFocusWindow( else { // Same WQ as FG but not the same TQ send active. //ERR("Same WQ as FG but not the same TQ send active.\n"); - co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); + co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } return Ret; } hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0; + pWndPrev = PrevForegroundQueue->spwndActive; } if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) && @@ -410,16 +448,29 @@ co_IntSetForegroundAndFocusWindow( pti->ppi == ppiScrnSaver ) { - IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); - gptiForeground = Wnd->head.pti; - TRACE("Set Foreground pti 0x%p Q 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue); + + //ToggleFGActivate(pti); // win.c line 2662 fail + if (Wnd) + { + IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); + gptiForeground = Wnd->head.pti; + //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h); + } + else + { + IntSetFocusMessageQueue(NULL); + gptiForeground = NULL; + //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n"); + } /* Henri Verbeet, What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the other thread after we already changed the foreground window back to our own window. */ - FindRemoveAsyncMsg(Wnd); // Do this to fix test_SFW todos! + //ERR("SFAFW: 1\n"); + FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos! + fgRet = TRUE; } @@ -428,34 +479,41 @@ co_IntSetForegroundAndFocusWindow( { if (PrevForegroundQueue && fgRet && - Wnd->head.pti->MessageQueue != PrevForegroundQueue && PrevForegroundQueue->spwndActive) { //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev); if (pti->MessageQueue == PrevForegroundQueue) { //ERR("SFGW: TI same as Prev TI\n"); - co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE, FALSE); + co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE); + } + else if (pWndPrev) + { + //ERR("SFGW Deactivate: TI not same as Prev TI\n"); + // No real reason to wait here. + co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); } - else - co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); } } + if (!Wnd) return FALSE; // Always return false. + if (pti->MessageQueue == Wnd->head.pti->MessageQueue) { - Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE); + //ERR("Same PQ and WQ go active.\n"); + Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { + //ERR("Same Active and Wnd.\n"); Ret = TRUE; } else { + //ERR("Activate Not same PQ and WQ and Wnd.\n"); co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } - return Ret && fgRet; } @@ -500,7 +558,7 @@ co_IntMouseActivateWindow(PWND Wnd) } BOOL FASTCALL -co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async) +co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; @@ -509,38 +567,83 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, HWND hWnd = 0; BOOL InAAPM; CBTACTIVATESTRUCT cbt; - + //ERR("co_IntSetActiveWindow 1\n"); if (Wnd) { ASSERT_REFS_CO(Wnd); hWnd = UserHMGetHandle(Wnd); if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if (Wnd == UserGetDesktopWindow()) return FALSE; + //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd); } + //ERR("co_IntSetActiveWindow 2\n"); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL; - if (Prev) *Prev = hWndPrev; - if (hWndPrev == hWnd) return TRUE; pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. - if (Wnd) + while (Wnd) { - if (ThreadQueue != Wnd->head.pti->MessageQueue) - { - PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); - // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... - if (!ForegroundQueue || ForegroundQueue == ThreadQueue) - { - return co_IntSetForegroundAndFocusWindow(Wnd, bMouse); - } - } + BOOL Ret, DoFG, AllowFG; if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE; + + if (ThreadQueue == Wnd->head.pti->MessageQueue) + { + if (IsAllowedFGActive(pti, Wnd)) + { + DoFG = TRUE; + } + else + { + //ERR("co_IntSetActiveWindow 3 Go Out!\n"); + break; + } + AllowFG = !pti->cVisWindows; // Nothing is visable. + //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + } + else //if (ThreadQueue != Wnd->head.pti->MessageQueue) + { + //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); + // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... + //if (!ForegroundQueue || ForegroundQueue == ThreadQueue) + if (!gpqForeground || gpqForeground == ThreadQueue) + { + DoFG = TRUE; + } + else + DoFG = FALSE; + if (DoFG) + { + if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows) + AllowFG = TRUE; + else + AllowFG = FALSE; + } + else + AllowFG = FALSE; + //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + } + Ret = FALSE; + if (DoFG) + { + pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + //ERR("co_IntSetActiveWindow 3c FG set\n"); + Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse); + if (AllowFG) + { + pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + } + else + { + pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; + } + } + return Ret; } /* Call CBT hook chain */ @@ -562,14 +665,16 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (WndPrev) { if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; - if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE; + if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE; } + WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active. + // While in calling message proc or hook: // Fail if a preemptive switch was made, current active not made previous, // focus window is dead or no longer the same thread queue. if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || - pWndChg != ThreadQueue->spwndActive || + pWndChg != WndPrev || (Wnd && !VerifyWnd(Wnd)) || ThreadQueue != pti->MessageQueue ) { @@ -582,6 +687,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED; IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + //// Breaks Atl-Esc/Tab via User32. + ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages. /* check if the specified window can be set in the input data of a given queue */ if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue) @@ -590,6 +697,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, ThreadQueue->spwndActive = Wnd; } + WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again. + InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); /* now change focus if necessary */ @@ -610,16 +719,40 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (InAAPM) { pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; - pti->pClientInfo->dwTIFlags = pti->TIF_flags; } // FIXME: Used in the menu loop!!! //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; + //ERR("co_IntSetActiveWindow Exit\n"); if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED; return (ThreadQueue->spwndActive == Wnd); } +BOOL FASTCALL +UserSetActiveWindow(PWND Wnd) +{ + if (Wnd) // Must have a window! + { + if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; + + return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE); + } + /* + Yes your eye are not deceiving you~! + + First part of wines Win.c test_SetActiveWindow: + + flush_events( TRUE ); + ShowWindow(hwnd, SW_HIDE); + SetFocus(0); + SetActiveWindow(0); + check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does! + + */ + return FALSE; +} + HWND FASTCALL co_UserSetFocus(PWND Window) { @@ -653,17 +786,10 @@ co_UserSetFocus(PWND Window) } /* Check if we can set the focus to this window */ - pwndTop = Window; - for (;;) + for (pwndTop = Window; pwndTop != NULL; pwndTop = pwndTop->spwndParent) { if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0; - if (!pwndTop->spwndParent || pwndTop->spwndParent == UserGetDesktopWindow()) - { - if ((pwndTop->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0; - break; - } - if (pwndTop->spwndParent == UserGetMessageWindow()) return 0; - pwndTop = pwndTop->spwndParent; + if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break; } if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) @@ -676,8 +802,13 @@ co_UserSetFocus(PWND Window) if (pwndTop != ThreadQueue->spwndActive) { PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop. - if (ThreadQueue != ForegroundQueue) // HACK see rule 2 & 3. + if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3. { + //ERR("SetFocus: Set Foreground!\n"); + if (!(pwndTop->style & WS_VISIBLE)) + { + pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; + } if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE)) { ERR("SetFocus: Set Foreground and Focus Failed!\n"); @@ -688,7 +819,8 @@ co_UserSetFocus(PWND Window) /* Set Active when it is needed. */ if (pwndTop != ThreadQueue->spwndActive) { - if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE, FALSE)) + //ERR("SetFocus: Set Active!\n"); + if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE)) { ERR("SetFocus: Set Active Failed!\n"); return 0; @@ -714,8 +846,6 @@ co_UserSetFocus(PWND Window) } else /* NULL hwnd passed in */ { -// if (!hWndPrev) return 0; /* nothing to do */ - if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) { ERR("SetFocus: 2 WH_CBT Call Hook return!\n"); @@ -857,7 +987,7 @@ IntReleaseCapture(VOID) BOOL FASTCALL co_IntSetForegroundWindow(PWND Window) { - ASSERT_REFS_CO(Window); + if (Window) ASSERT_REFS_CO(Window); return co_IntSetForegroundAndFocusWindow(Window, FALSE); } @@ -937,12 +1067,13 @@ IntAllowSetForegroundWindow(DWORD dwProcessId) } if (dwProcessId == ASFW_ANY) { // All processes will be enabled to set the foreground window. + //ERR("ptiLastInput is CLEARED!!\n"); ptiLastInput = NULL; } else { // Rule #3, last input event in force. - ERR("Fixme: ptiLastInput is SET!!\n"); - //ptiLastInput = ppi->ptiList; + ERR("ptiLastInput is SET!!\n"); + //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030. ObDereferenceObject(Process); } return TRUE; @@ -962,7 +1093,7 @@ NtUserGetForegroundWindow(VOID) RETURN( UserGetForegroundWindow()); CLEANUP: - TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", _ret_); + TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_); UserLeave(); END_CLEANUP; } @@ -993,7 +1124,7 @@ NtUserSetActiveWindow(HWND hWnd) { hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL; if (Window) UserRefObjectCo(Window, &Ref); - co_IntSetActiveWindow(Window, NULL, FALSE, TRUE, FALSE); + UserSetActiveWindow(Window); if (Window) UserDerefObjectCo(Window); RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 ); } diff --git a/reactos/win32ss/user/ntuser/focus.h b/reactos/win32ss/user/ntuser/focus.h index 48ac7efacd1..bc82c3bf5da 100644 --- a/reactos/win32ss/user/ntuser/focus.h +++ b/reactos/win32ss/user/ntuser/focus.h @@ -2,6 +2,7 @@ extern PUSER_MESSAGE_QUEUE gpqForeground; extern PUSER_MESSAGE_QUEUE gpqForegroundPrev; +extern PTHREADINFO ptiLastInput; /* * These functions take the window handles from current message queue. @@ -18,7 +19,8 @@ HWND APIENTRY IntGetCapture(VOID); HWND FASTCALL UserGetActiveWindow(VOID); BOOL FASTCALL co_IntMouseActivateWindow(PWND Window); BOOL FASTCALL co_IntSetForegroundWindow(PWND Window); -BOOL FASTCALL co_IntSetActiveWindow(PWND,HWND *,BOOL,BOOL,BOOL); BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window); +BOOL FASTCALL co_IntSetActiveWindow(PWND,BOOL,BOOL,BOOL); +BOOL FASTCALL UserSetActiveWindow(PWND Wnd); BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode); BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId); diff --git a/reactos/win32ss/user/ntuser/input.c b/reactos/win32ss/user/ntuser/input.c index 04382acac94..4223669256a 100644 --- a/reactos/win32ss/user/ntuser/input.c +++ b/reactos/win32ss/user/ntuser/input.c @@ -402,24 +402,47 @@ NtUserBlockInput( return ret; } -PTHREADINFO FASTCALL -IsThreadAttach(PTHREADINFO ptiTo) +BOOL +FASTCALL +IsRemoveAttachThread(PTHREADINFO pti) { + NTSTATUS Status; PATTACHINFO pai; + BOOL Ret = TRUE; + PTHREADINFO ptiFrom = NULL, ptiTo = NULL; - if (!gpai) return NULL; - - pai = gpai; do { - if (pai->pti2 == ptiTo) break; - pai = pai->paiNext; - } while (pai); + if (!gpai) return TRUE; + + pai = gpai; // Bottom of the list. - if (!pai) return NULL; + do + { + if (pai->pti2 == pti) + { + ptiFrom = pai->pti1; + ptiTo = pti; + break; + } + if (pai->pti1 == pti) + { + ptiFrom = pti; + ptiTo = pai->pti2; + break; + } + pai = pai->paiNext; + + } while (pai); - // Return ptiFrom. - return pai->pti1; + if (!pai && !ptiFrom && !ptiTo) break; + + Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE); + if (!NT_SUCCESS(Status)) Ret = FALSE; + + } while (Ret); + + return Ret; } NTSTATUS FASTCALL @@ -454,44 +477,52 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) paiCount++; ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount); - if (ptiTo->MessageQueue == ptiFrom->MessageQueue) + if (ptiTo->MessageQueue != ptiFrom->MessageQueue) + { + + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + + // FIXME: conditions? + if (ptiTo->MessageQueue == gpqForeground) + { + ERR("ptiTo is Foreground\n"); + } + else + { + ERR("ptiTo NOT Foreground\n"); + } + + if (ptiFrom->MessageQueue == gpqForeground) + { + ERR("ptiFrom is Foreground\n"); + ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive; + ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus; + ptiTo->MessageQueue->CursorObject = ptiFrom->MessageQueue->CursorObject; + ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture; + ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED); + ptiTo->MessageQueue->CaretInfo = ptiFrom->MessageQueue->CaretInfo; + IntSetFocusMessageQueue(NULL); + IntSetFocusMessageQueue(ptiTo->MessageQueue); + gptiForeground = ptiTo; + } + else + { + ERR("ptiFrom NOT Foreground\n"); + } + + MsqDestroyMessageQueue(ptiFrom); + + ptiFrom->MessageQueue = ptiTo->MessageQueue; + + ptiFrom->MessageQueue->cThreads++; + ERR("ptiTo S Share count %d\n", ptiFrom->MessageQueue->cThreads); + + IntReferenceMessageQueue(ptiTo->MessageQueue); + } + else { ERR("Attach Threads are already associated!\n"); } - - ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; - - /* Keep the original queue in pqAttach (ie do not trash it in a second attachment) */ - if (ptiFrom->pqAttach == NULL) - ptiFrom->pqAttach = ptiFrom->MessageQueue; - ptiFrom->MessageQueue = ptiTo->MessageQueue; - - ptiFrom->MessageQueue->cThreads++; - ERR("ptiTo S Share count %lu\n", ptiFrom->MessageQueue->cThreads); - - // FIXME: conditions? - if (ptiFrom->pqAttach == gpqForeground) - { - ERR("ptiFrom is Foreground\n"); - ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive; - ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus; - ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject; - ptiFrom->MessageQueue->spwndCapture = ptiFrom->pqAttach->spwndCapture; - ptiFrom->MessageQueue->QF_flags ^= ((ptiFrom->MessageQueue->QF_flags ^ ptiFrom->pqAttach->QF_flags) & QF_CAPTURELOCKED); - ptiFrom->MessageQueue->CaretInfo = ptiFrom->pqAttach->CaretInfo; - } - else - { - ERR("ptiFrom NOT Foreground\n"); - } - if (ptiTo->MessageQueue == gpqForeground) - { - ERR("ptiTo is Foreground\n"); - } - else - { - ERR("ptiTo NOT Foreground\n"); - } } else /* If clear, unlink and free it. */ { @@ -518,41 +549,31 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) } if (!Hit) return STATUS_INVALID_PARAMETER; - - ASSERT(ptiFrom->pqAttach); ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount); - - /* Search list and check if the thread is attached one more time */ - pai = gpai; - while(pai) + + if (ptiTo->MessageQueue == ptiFrom->MessageQueue) { - /* If the thread is attached again , we are done */ - if (pai->pti1 == ptiFrom) - { - ptiFrom->MessageQueue->cThreads--; - ERR("ptiTo L Share count %lu\n", ptiFrom->MessageQueue->cThreads); - /* Use the message queue of the last attachment */ - ptiFrom->MessageQueue = pai->pti2->MessageQueue; - ptiFrom->MessageQueue->CursorObject = NULL; - ptiFrom->MessageQueue->spwndActive = NULL; - ptiFrom->MessageQueue->spwndFocus = NULL; - ptiFrom->MessageQueue->spwndCapture = NULL; - return STATUS_SUCCESS; - } - pai = pai->paiNext; - } + if (gptiForeground == ptiFrom) + { + ERR("ptiTo is now pti FG.\n"); + // MessageQueue foreground is set so switch threads. + gptiForeground = ptiTo; + } + ptiTo->MessageQueue->cThreads--; + ERR("ptiTo E Share count %d\n", ptiTo->MessageQueue->cThreads); + ASSERT(ptiTo->MessageQueue->cThreads >= 1); - ptiFrom->MessageQueue->cThreads--; - ERR("ptiTo E Share count %lu\n", ptiFrom->MessageQueue->cThreads); - ptiFrom->MessageQueue = ptiFrom->pqAttach; - // FIXME: conditions? - ptiFrom->MessageQueue->CursorObject = NULL; - ptiFrom->MessageQueue->spwndActive = NULL; - ptiFrom->MessageQueue->spwndFocus = NULL; - ptiFrom->MessageQueue->spwndCapture = NULL; - ptiFrom->pqAttach = NULL; - ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + IntDereferenceMessageQueue(ptiTo->MessageQueue); + + ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom); + + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + } + else + { + ERR("Detaching Threads are not associated!\n"); + } } /* Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to AttachThreadInput. diff --git a/reactos/win32ss/user/ntuser/input.h b/reactos/win32ss/user/ntuser/input.h index 985d2c96a30..c34eb4a9ff0 100644 --- a/reactos/win32ss/user/ntuser/input.h +++ b/reactos/win32ss/user/ntuser/input.h @@ -63,7 +63,7 @@ INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID); BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt); DWORD NTAPI CreateSystemThreads(UINT Type); NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL); -PTHREADINFO FASTCALL IsThreadAttach(PTHREADINFO); +BOOL FASTCALL IsRemoveAttachThread(PTHREADINFO); VOID FASTCALL DoTheScreenSaver(VOID); #define ThreadHasInputAccess(W32Thread) (TRUE) diff --git a/reactos/win32ss/user/ntuser/keyboard.c b/reactos/win32ss/user/ntuser/keyboard.c index 7af7cc5a84e..2b2cf6260fd 100644 --- a/reactos/win32ss/user/ntuser/keyboard.c +++ b/reactos/win32ss/user/ntuser/keyboard.c @@ -825,6 +825,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d TRACE("HotKey Processed\n"); bPostMsg = FALSE; } + wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */ if (wSimpleVk == VK_SHIFT) /* shift can't be extended */ bExt = FALSE; @@ -892,23 +893,31 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } else if (pFocusQueue && bPostMsg) { - PWND Wnd = pFocusQueue->spwndFocus; - if (!Wnd) + PWND Wnd = pFocusQueue->spwndFocus; // SysInit..... + + pti = pFocusQueue->ptiKeyboard; + + if (!Wnd && pFocusQueue->spwndActive) // SysInit..... { - // Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input. + // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input. Wnd = pFocusQueue->spwndActive; } + if (Wnd) pti = Wnd->head.pti; - if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED ) + if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN ) { - ERR("ProcessKeyEvent Active Focus window is dead!\n"); - return FALSE; + if ( (Msg.wParam == VK_SHIFT || + Msg.wParam == VK_CONTROL || + Msg.wParam == VK_MENU ) && + !IS_KEY_DOWN(gafAsyncKeyState, Msg.wParam)) + { + ERR("Set last input\n"); + //ptiLastInput = pti; + } } - - pti = Wnd->head.pti; /* Init message */ - Msg.hwnd = UserHMGetHandle(Wnd); + Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL; Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */ Msg.lParam = MAKELPARAM(1, wScanCode); Msg.time = dwTime; @@ -934,6 +943,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d /* Post a keyboard message */ TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam); + if (!Wnd) {ERR("Window is NULL\n");} MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0); } @@ -956,9 +966,9 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected) /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue(); - if (pFocusQueue && pFocusQueue->ptiOwner) + if (pFocusQueue && pFocusQueue->ptiKeyboard) { - pKl = pFocusQueue->ptiOwner->KeyboardLayout; + pKl = pFocusQueue->ptiKeyboard->KeyboardLayout; } if (!pKl) @@ -1039,9 +1049,9 @@ UserProcessKeyboardInput( /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue(); - if (pFocusQueue && pFocusQueue->ptiOwner) + if (pFocusQueue && pFocusQueue->ptiKeyboard) { - pKl = pFocusQueue->ptiOwner->KeyboardLayout; + pKl = pFocusQueue->ptiKeyboard->KeyboardLayout; } if (!pKl) diff --git a/reactos/win32ss/user/ntuser/main.c b/reactos/win32ss/user/ntuser/main.c index df84709f02d..c872d020554 100644 --- a/reactos/win32ss/user/ntuser/main.c +++ b/reactos/win32ss/user/ntuser/main.c @@ -154,6 +154,9 @@ Win32kProcessCallback(struct _EPROCESS *Process, ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER; } + // Fixme check if this process is allowed. + ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off. + /* Create pools for GDI object attributes */ ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG'); ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG'); @@ -275,14 +278,17 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) RtlZeroMemory(ptiCurrent, sizeof(THREADINFO)); + /* Initialize the THREADINFO */ + PsSetThreadWin32Thread(Thread, ptiCurrent); + IntReferenceThreadInfo(ptiCurrent); + ptiCurrent->pEThread = Thread; + ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); pTeb->Win32ThreadInfo = ptiCurrent; ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo; TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread); - /* Initialize the THREADINFO */ - IntReferenceThreadInfo(ptiCurrent); InitializeListHead(&ptiCurrent->WindowListHead); InitializeListHead(&ptiCurrent->W32CallbackListHead); InitializeListHead(&ptiCurrent->PostedMessagesListHead); @@ -294,8 +300,6 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) { InitializeListHead(&ptiCurrent->aphkStart[i]); } - ptiCurrent->pEThread = Thread; - ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList; ptiCurrent->ppi->ptiList = ptiCurrent; ptiCurrent->ppi->cThreads++; @@ -307,7 +311,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) { goto error; } - Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, + Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, ExEventObjectType, KernelMode, (PVOID*)&ptiCurrent->pEventQueueServer, NULL); if (!NT_SUCCESS(Status)) @@ -319,7 +323,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) KeQueryTickCount(&LargeTickCount); ptiCurrent->timeLast = LargeTickCount.u.LowPart; - + ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent); if(ptiCurrent->MessageQueue == NULL) { @@ -419,8 +423,14 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) /* mark the thread as fully initialized */ ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED; - ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) && + (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi )) + { + ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + } + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + ERR_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent); return STATUS_SUCCESS; error: @@ -483,27 +493,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) ppiCurrent = ptiCurrent->ppi; ASSERT(ppiCurrent); - // ptiTo - if (IsThreadAttach(ptiCurrent)) - { - PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent); - TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n"); - UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE); - } + IsRemoveAttachThread(ptiCurrent); - // ptiFrom - if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue) - { - PTHREADINFO ptiTo; - ptiTo = ptiCurrent->MessageQueue->ptiOwner; - TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n"); - if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE); - else - { - // eThread maybe okay but Win32Thread already made NULL! - ERR_CH(UserThread,"Attached Thread ptiFrom did not switch due to ptiTo is NULL!\n"); - } - } + ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE; + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; /* Decrement thread count and check if its 0 */ ppiCurrent->cThreads--; @@ -553,9 +546,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) */ co_DestroyThreadWindows(Thread); - if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling) + if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling && + ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED) { - //ERR_CH(UserThread,"DestroyProcessClasses\n"); + ERR_CH(UserThread,"DestroyProcessClasses\n"); /* no process windows should exist at this point, or the function will assert! */ DestroyProcessClasses(ppiCurrent); ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED; @@ -592,8 +586,24 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) if (ptiCurrent->KeyboardLayout) UserDereferenceObject(ptiCurrent->KeyboardLayout); - IntSetThreadDesktop(NULL, TRUE); + if (gptiForeground == ptiCurrent) + { +// IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0); +// IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0); + gptiForeground = NULL; + } + + // Fixes CORE-6384 & CORE-7030. +/* if (ptiLastInput == ptiCurrent) + { + if (!ppiCurrent->ptiList) + ptiLastInput = gptiForeground; + else + ptiLastInput = ppiCurrent->ptiList; + ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n"); + } +*/ TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent); /* Free the THREADINFO */ diff --git a/reactos/win32ss/user/ntuser/message.c b/reactos/win32ss/user/ntuser/message.c index d4064ee5390..5b4c27ff1b5 100644 --- a/reactos/win32ss/user/ntuser/message.c +++ b/reactos/win32ss/user/ntuser/message.c @@ -502,13 +502,7 @@ VOID FASTCALL IdlePing(VOID) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); - PUSER_MESSAGE_QUEUE ForegroundQueue; - PTHREADINFO pti, ptiForeground = NULL; - - ForegroundQueue = IntGetFocusMessageQueue(); - - if (ForegroundQueue) - ptiForeground = ForegroundQueue->ptiOwner; + PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); @@ -516,7 +510,7 @@ IdlePing(VOID) { pti->pClientInfo->cSpins = 0; // Reset spins. - if ( pti->pDeskInfo && pti == ptiForeground ) + if ( pti->pDeskInfo && pti == gptiForeground ) { if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) || pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ) @@ -602,13 +596,14 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR { LRESULT lRes; USER_REFERENCE_ENTRY Ref; +// PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); if (!pWnd || pWnd == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP pWnd == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND return 0; - TRACE("Internal Event Msg %u hWnd %p\n", msg, pWnd->head.h); + TRACE("Internal Event Msg %p hWnd 0x%x\n",msg,pWnd->head.h); switch(msg) { @@ -632,7 +627,7 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR { PWND Window = (PWND)wparam; if (wparam) UserRefObjectCo(Window, &Ref); - lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE,TRUE); + lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE); if (wparam) UserDerefObjectCo(Window); return lRes; } @@ -751,6 +746,14 @@ IntDispatchMessage(PMSG pMsg) /* * Internal version of PeekMessage() doing all the work + * + * MSDN: + * Sent messages + * Posted messages + * Input (hardware) messages and system internal events + * Sent messages (again) + * WM_PAINT messages + * WM_TIMER messages */ BOOL FASTCALL co_IntPeekMessage( PMSG Msg, @@ -770,7 +773,7 @@ co_IntPeekMessage( PMSG Msg, RemoveMessages = RemoveMsg & PM_REMOVE; ProcessMask = HIWORD(RemoveMsg); - + /* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed)". */ if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT); @@ -1083,6 +1086,19 @@ UserPostThreadMessage( PTHREADINFO pti, return TRUE; } +PTHREADINFO FASTCALL +IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg) +{ + if ( ptiCur ) + { + if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue ) + { + return NULL; + } + } + return Window->head.pti; +} + BOOL FASTCALL UserPostMessage( HWND Wnd, UINT Msg, @@ -1192,11 +1208,11 @@ UserPostMessage( HWND Wnd, if (WM_QUIT == Msg) { - MsqPostQuitMessage(Window->head.pti, wParam); + MsqPostQuitMessage(pti, wParam); } else { - MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0); + MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0); } } return TRUE; @@ -1230,7 +1246,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; LPARAM lParamPacked; - PTHREADINFO Win32Thread; + PTHREADINFO Win32Thread, ptiSendTo = NULL; ULONG_PTR Hi, Lo, Result = 0; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; @@ -1246,8 +1262,9 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, Win32Thread = PsGetCurrentThreadWin32Thread(); - if ( Win32Thread && - Window->head.pti == Win32Thread) + ptiSendTo = IntSendTo(Window, Win32Thread, Msg); + + if ( !ptiSendTo ) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1333,7 +1350,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, RETURN( TRUE); } - if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti)) + if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo/*Window->head.pti*/)) { // FIXME: Set window hung and add to a list. /* FIXME: Set a LastError? */ @@ -1349,7 +1366,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, do { - Status = co_MsqSendMessage( Window->head.pti, + Status = co_MsqSendMessage( ptiSendTo, //Window->head.pti, hWnd, Msg, wParam, @@ -1361,7 +1378,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, } while ((STATUS_TIMEOUT == Status) && (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) && - !MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list. + !MsqIsHung(ptiSendTo/*Window->head.pti*/)); // FIXME: Set window hung and add to a list. if (STATUS_TIMEOUT == Status) { @@ -1491,7 +1508,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; LPARAM lParamPacked; - PTHREADINFO Win32Thread; + PTHREADINFO Win32Thread, ptiSendTo = NULL; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; PUSER_SENT_MESSAGE Message; @@ -1519,9 +1536,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, { RETURN(FALSE); } + + ptiSendTo = IntSendTo(Window, Win32Thread, Msg); if (Msg & 0x80000000 && - Window->head.pti == Win32Thread) + !ptiSendTo) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE); @@ -1542,14 +1561,14 @@ co_IntSendMessageWithCallBack( HWND hWnd, lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam); } - if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread))) + if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, !!ptiSendTo))) { ERR("Failed to pack message parameters\n"); RETURN( FALSE); } /* If it can be sent now, then send it. */ - if (Window->head.pti == Win32Thread) + if ( !ptiSendTo ) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1599,7 +1618,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, } } - if (Window->head.pti == Win32Thread) + if ( !ptiSendTo) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1622,7 +1641,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->Result = 0; Message->lResult = 0; Message->QS_Flags = 0; - Message->ptiReceiver = Window->head.pti; + Message->ptiReceiver = ptiSendTo; //Window->head.pti; Message->ptiSender = NULL; // mjmartin, you are right! This is null. Message->ptiCallBackSender = Win32Thread; Message->DispatchingListEntry.Flink = NULL; @@ -1633,10 +1652,10 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->QS_Flags = QS_SENDMESSAGE; if (Msg & 0x80000000) // Higher priority event message! - InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); + InsertHeadList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry); else - InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE); + InsertTailList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry); + MsqWakeQueue(ptiSendTo/*Window->head.pti*/, QS_SENDMESSAGE, TRUE); RETURN(TRUE); @@ -1674,7 +1693,7 @@ co_IntPostOrSendMessage( HWND hWnd, pti = PsGetCurrentThreadWin32Thread(); - if ( Window->head.pti->MessageQueue != pti->MessageQueue && + if ( IntSendTo(Window, pti, Msg) && FindMsgMemory(Msg) == 0 ) { Result = UserPostMessage(hWnd, Msg, wParam, lParam); diff --git a/reactos/win32ss/user/ntuser/misc.c b/reactos/win32ss/user/ntuser/misc.c index 935104f7cfd..52f0abe377c 100644 --- a/reactos/win32ss/user/ntuser/misc.c +++ b/reactos/win32ss/user/ntuser/misc.c @@ -662,8 +662,11 @@ void UserDbgAssertThreadInfo(BOOL showCaller) 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) @@ -673,6 +676,7 @@ void UserDbgAssertThreadInfo(BOOL showCaller) } pci->dwTIFlags = pti->TIF_flags; } +*/ } void diff --git a/reactos/win32ss/user/ntuser/msgqueue.c b/reactos/win32ss/user/ntuser/msgqueue.c index 5be8095794b..c4e677ddf69 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.c +++ b/reactos/win32ss/user/ntuser/msgqueue.c @@ -404,7 +404,6 @@ MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent) { ERR("This Message Queue is in Destroy!\n"); } - pti->pcti->fsWakeBits |= MessageBits; pti->pcti->fsChangeBits |= MessageBits; @@ -475,6 +474,10 @@ ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits) { if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY; } + if (MessageBits & QS_EVENT) + { + if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT; + } pti->pcti->fsWakeBits &= ~ClrMask; pti->pcti->fsChangeBits &= ~ClrMask; @@ -506,6 +509,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook { LARGE_INTEGER LargeTickCount; MSLLHOOKSTRUCT MouseHookData; +// PDESKTOP pDesk; PWND pwnd, pwndDesktop; HDC hdcScreen; PTHREADINFO pti; @@ -549,6 +553,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook /* Get the desktop window */ pwndDesktop = UserGetDesktopWindow(); if (!pwndDesktop) return; +// pDesk = pwndDesktop->head.rpdesk; /* Check if the mouse is captured */ Msg->hwnd = IntGetCaptureWindow(); @@ -626,6 +631,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook } else { + //if (!IntGetCaptureWindow()) ptiLastInput = pti; TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd)); MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0); } @@ -661,7 +667,7 @@ MsqDestroyMessage(PUSER_MESSAGE Message) } BOOLEAN FASTCALL -co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti) +co_MsqDispatchOneSentMessage(PTHREADINFO pti) { PUSER_SENT_MESSAGE SaveMsg, Message; PLIST_ENTRY Entry; @@ -911,12 +917,6 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, ptiSender = PsGetCurrentThreadWin32Thread(); - IntReferenceMessageQueue(ptiReceiver->MessageQueue); - /* Take reference on this MessageQueue if its a callback. It will be released - when message is processed or removed from target hwnd MessageQueue */ - if (CompletionCallback) - IntReferenceMessageQueue(ptiSender->MessageQueue); - Message->Msg.hwnd = hwnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; @@ -1180,6 +1180,12 @@ MsqPostMessage(PTHREADINFO pti, PUSER_MESSAGE Message; PUSER_MESSAGE_QUEUE MessageQueue; + if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY ) + { + ERR("Post Msg; Thread or Q is Dead!\n"); + return; + } + if(!(Message = MsqCreateMessage(Msg))) { return; @@ -1189,6 +1195,7 @@ MsqPostMessage(PTHREADINFO pti, if (dwQEvent) { + ERR("Post Msg; System Qeued Event Message!\n"); InsertHeadList(&pti->PostedMessagesListHead, &Message->ListEntry); } @@ -1206,7 +1213,7 @@ MsqPostMessage(PTHREADINFO pti, if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it. Message->dwQEvent = dwQEvent; Message->QS_Flags = MessageBits; - //Message->pti = pti; Fixed in ATI changes. See CORE-6551 + Message->pti = pti; MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE)); } @@ -1254,7 +1261,7 @@ FASTCALL IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest) { // PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y); - hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this??? +// hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this??? if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or msg->message != WM_MOUSEMOVE || // Mouse click changes or @@ -1491,7 +1498,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT hook.dwExtraInfo = 0 /* extra_info */ ; co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook ); - ERR("WH_MOUSE dorpped mouse message!\n"); + ERR("WH_MOUSE dropped mouse message!\n"); /* Remove and skip message */ *RemoveMessages = TRUE; @@ -1805,7 +1812,7 @@ MsqPeekMessage(IN PTHREADINFO pti, ListHead = &pti->PostedMessagesListHead; if (IsListEmpty(CurrentEntry)) return FALSE; - + CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); do @@ -1880,9 +1887,8 @@ HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue) { - MessageQueue->ptiOwner = pti; MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1); - InitializeListHead(&MessageQueue->HardwareMessagesListHead); + InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here! MessageQueue->spwndFocus = NULL; MessageQueue->iCursorLevel = 0; MessageQueue->CursorObject = NULL; @@ -1900,7 +1906,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) PLIST_ENTRY CurrentEntry; PUSER_MESSAGE CurrentMessage; PUSER_SENT_MESSAGE CurrentSentMessage; - + /* cleanup posted messages */ while (!IsListEmpty(&pti->PostedMessagesListHead)) { @@ -1936,7 +1942,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) if (CurrentSentMessage->Msg.lParam) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - + /* free the message */ ExFreePool(CurrentSentMessage); } @@ -1999,16 +2005,16 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) pti->nCntsQBits[QSRosPostMessage] = 0; pti->nCntsQBits[QSRosSendMessage] = 0; pti->nCntsQBits[QSRosHotKey] = 0; - + pti->nCntsQBits[QSRosEvent] = 0; } - + VOID FASTCALL MsqCleanupMessageQueue(PTHREADINFO pti) { PUSER_MESSAGE_QUEUE MessageQueue; MessageQueue = pti->MessageQueue; - MessageQueue->cThreads--; + MessageQueue->cThreads--; if (MessageQueue->cThreads) { @@ -2033,6 +2039,7 @@ MsqCleanupMessageQueue(PTHREADINFO pti) IntGetSysCursorInfo()->CurrentCursorObject = NULL; } + ERR("DereferenceObject pCursor\n"); UserDereferenceObject(pCursor); } diff --git a/reactos/win32ss/user/ntuser/msgqueue.h b/reactos/win32ss/user/ntuser/msgqueue.h index 4b2a8ceaa6b..365f76536e5 100644 --- a/reactos/win32ss/user/ntuser/msgqueue.h +++ b/reactos/win32ss/user/ntuser/msgqueue.h @@ -42,7 +42,6 @@ typedef struct _USER_MESSAGE_QUEUE /* Reference counter, only access this variable with interlocked functions! */ LONG References; - PTHREADINFO ptiOwner; // temp.. /* Desktop that the message queue is attached to */ struct _DESKTOP *Desktop; diff --git a/reactos/win32ss/user/ntuser/object.c b/reactos/win32ss/user/ntuser/object.c index 6189050c11c..363e175a28f 100644 --- a/reactos/win32ss/user/ntuser/object.c +++ b/reactos/win32ss/user/ntuser/object.c @@ -548,6 +548,13 @@ UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner) #endif } + +HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type) +{ + if (handle) return (PWND)UserGetObjectNoErr(gHandleTable, handle, type); + return NULL; +} + /* * NtUserValidateHandleSecure * diff --git a/reactos/win32ss/user/ntuser/object.h b/reactos/win32ss/user/ntuser/object.h index 51355746184..22267d6fa12 100644 --- a/reactos/win32ss/user/ntuser/object.h +++ b/reactos/win32ss/user/ntuser/object.h @@ -18,6 +18,7 @@ BOOL FASTCALL UserCreateHandleTable(VOID); BOOL FASTCALL UserObjectInDestroy(HANDLE); void DbgUserDumpHandleTable(); VOID FASTCALL UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner); +HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type); static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry) diff --git a/reactos/win32ss/user/ntuser/window.c b/reactos/win32ss/user/ntuser/window.c index 52255f3e438..25a1b0a7633 100644 --- a/reactos/win32ss/user/ntuser/window.c +++ b/reactos/win32ss/user/ntuser/window.c @@ -123,7 +123,12 @@ IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits ) styleNew = (pwnd->style | set_bits) & ~clear_bits; if (styleNew == styleOld) return styleNew; pwnd->style = styleNew; - if ((styleOld ^ styleNew) & WS_VISIBLE) DceResetActiveDCEs( pwnd ); + if ((styleOld ^ styleNew) & WS_VISIBLE) // State Change. + { + if (styleOld & WS_VISIBLE) pwnd->head.pti->cVisWindows--; + if (styleNew & WS_VISIBLE) pwnd->head.pti->cVisWindows++; + DceResetActiveDCEs( pwnd ); + } return styleOld; } @@ -159,21 +164,16 @@ IntIsWindow(HWND hWnd) BOOL FASTCALL IntIsWindowVisible(PWND Wnd) { - BOOL Ret = TRUE; - do + PWND Temp = Wnd; + for (;;) { - if (!(Wnd->style & WS_VISIBLE)) - { - Ret = FALSE; - break; - } - if (Wnd->spwndParent != NULL) - Wnd = Wnd->spwndParent; - else - break; + if (!Temp) return TRUE; + if (!(Temp->style & WS_VISIBLE)) break; + if (Temp->style & WS_MINIMIZE && Temp != Wnd) break; + if (Temp->fnid == FNID_DESKTOP) return TRUE; + Temp = Temp->spwndParent; } - while (Wnd != NULL); - return Ret; + return FALSE; } PWND FASTCALL @@ -436,6 +436,7 @@ static LRESULT co_UserFreeWindow(PWND Window, } Window->state2 |= WNDS2_INDESTROY; Window->style &= ~WS_VISIBLE; + Window->head.pti->cVisWindows--; IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0); @@ -497,9 +498,6 @@ static LRESULT co_UserFreeWindow(PWND Window, /* flush the message queue */ MsqRemoveWindowMessagesFromQueue(Window); - NT_ASSERT(Window->head.pti); - IntDereferenceMessageQueue(Window->head.pti->MessageQueue); - /* from now on no messages can be sent to this window anymore */ Window->state |= WNDS_DESTROYED; Window->fnid |= FNID_FREED; @@ -578,6 +576,7 @@ static LRESULT co_UserFreeWindow(PWND Window, GreDeleteObject(Window->hrgnClip); Window->hrgnClip = NULL; } + Window->head.pti->cWindows--; // ASSERT(Window != NULL); UserFreeWindowInfo(Window->head.pti, Window); @@ -1098,8 +1097,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner) Wnd->head.pti == WndNewOwner->head.pti || WndOldOwner->head.pti != WndNewOwner->head.pti ) { - ERR("ProcessOwnerSwap Old out.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE); + //ERR("ProcessOwnerSwap Old out.\n"); + UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE); } } } @@ -1110,8 +1109,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner) if (!WndOldOwner || WndOldOwner->head.pti != WndNewOwner->head.pti ) { - ERR("ProcessOwnerSwap New in.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE); + //ERR("ProcessOwnerSwap New in.\n"); + UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE); } } } @@ -1140,6 +1139,8 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) goto Error; } + /* if parent belongs to a different thread and the window isn't */ + /* top-level, attach the two threads */ IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner); if (IntValidateOwnerDepth(Wnd, WndNewOwner)) @@ -1186,6 +1187,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) /* Some applications try to set a child as a parent */ if (IntIsChildWindow(Wnd, WndNewParent)) { + TRACE("IntSetParent try to set a child as a parent.\n"); EngSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } @@ -1196,6 +1198,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) { if (Wnd == pWndExam) { + TRACE("IntSetParent Failed Test for set parent to parent!\n"); EngSetLastError(ERROR_INVALID_PARAMETER); return NULL; } @@ -1210,7 +1213,10 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) /* Window must belong to current process */ if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process()) + { + ERR("IntSetParent Window must belong to current process!\n"); return NULL; + } WndOldParent = Wnd->spwndParent; @@ -1249,22 +1255,31 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) } + if ( WndNewParent == co_GetDesktopWindow(Wnd) && + !(Wnd->style & WS_CLIPSIBLINGS) ) + { + Wnd->style |= WS_CLIPSIBLINGS; + DceResetActiveDCEs(Wnd); + } + + /* if parent belongs to a different thread and the window isn't */ + /* top-level, attach the two threads */ if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) { if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd)) { if (Wnd->head.pti != WndOldParent->head.pti) { - ERR("SetParent Old out.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE); + //ERR("SetParent Old out.\n"); + UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE); } } if ( WndNewParent != co_GetDesktopWindow(Wnd)) { if (Wnd->head.pti != WndNewParent->head.pti) { - ERR("SetParent New in.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE); + //ERR("SetParent New in.\n"); + UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE); } } } @@ -1278,10 +1293,11 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) * in the z-order and send the expected WM_WINDOWPOSCHANGING and * WM_WINDOWPOSCHANGED notification messages. */ + //ERR("IntSetParent SetWindowPos 1\n"); co_WinPosSetWindowPos( Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST), pt.x, pt.y, 0, 0, swFlags); - + //ERR("IntSetParent SetWindowPos 2\n"); if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL); return WndOldParent; @@ -1302,6 +1318,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) if (hWndChild == IntGetDesktopWindow()) { + ERR("UserSetParent Access Denied!\n"); EngSetLastError(ERROR_ACCESS_DENIED); return( NULL); } @@ -1310,6 +1327,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) { if (!(WndParent = UserGetWindowObject(hWndNewParent))) { + ERR("UserSetParent Bad New Parent!\n"); return( NULL); } } @@ -1323,6 +1341,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) if (!(Wnd = UserGetWindowObject(hWndChild))) { + ERR("UserSetParent Bad Child!\n"); return( NULL); } @@ -1762,13 +1781,14 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, pWnd->InternalPos.MaxPos.x = pWnd->InternalPos.MaxPos.y = -1; pWnd->InternalPos.IconPos.x = pWnd->InternalPos.IconPos.y = -1; - IntReferenceMessageQueue(pWnd->head.pti->MessageQueue); if (pWnd->spwndParent != NULL && Cs->hwndParent != 0) { pWnd->HideFocus = pWnd->spwndParent->HideFocus; pWnd->HideAccel = pWnd->spwndParent->HideAccel; } + pWnd->head.pti->cWindows++; + if (Class->hIcon && !Class->hIconSm) { Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON, @@ -1962,8 +1982,8 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, Class->atomClassName != gpsi->atomSysClass[ICLS_IME] && pti != pWnd->spwndOwner->head.pti) { - ERR("CreateWindow Owner in.\n"); - //UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE); + //ERR("CreateWindow Owner in.\n"); + UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE); } } @@ -2203,6 +2223,15 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, Cs->lpszName = (LPCWSTR) WindowName; Cs->lpszClass = (LPCWSTR) ClassName; + if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) + { + if (ParentWindow != co_GetDesktopWindow(Window)) + { + Cs->x += ParentWindow->rcClient.left; + Cs->y += ParentWindow->rcClient.top; + } + } + /* Send the WM_GETMINMAXINFO message */ Size.cx = Cs->cx; Size.cy = Cs->cy; @@ -2220,6 +2249,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, Window->rcWindow.top = Cs->y; Window->rcWindow.right = Cs->x + Size.cx; Window->rcWindow.bottom = Cs->y + Size.cy; +/* if (0 != (Window->style & WS_CHILD) && ParentWindow) { // ERR("co_UserCreateWindowEx(): Offset rcWindow\n"); @@ -2227,6 +2257,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, ParentWindow->rcClient.left, ParentWindow->rcClient.top); } +*/ Window->rcClient = Window->rcWindow; /* Link the window */ @@ -2239,8 +2270,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, IntLinkHwnd(Window, hwndInsertAfter); } - // Remove flags that are retro. - if (!(Window->state2 & WNDS2_WIN31COMPAT)) // FIXME: support version flags. + if (!(Window->state2 & WNDS2_WIN31COMPAT)) { if (Class->style & CS_PARENTDC && !(ParentWindow->style & WS_CLIPCHILDREN)) Window->style &= ~(WS_CLIPSIBLINGS | WS_CLIPCHILDREN); @@ -2252,8 +2282,8 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, { if (pti != Window->spwndParent->head.pti) { - ERR("CreateWindow Parent in.\n"); - //UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE); + //ERR("CreateWindow Parent in.\n"); + UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE); } } } @@ -2267,14 +2297,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } /* Send the WM_NCCALCSIZE message */ + { + // RECT rc; MaxPos.x = Window->rcWindow.left; MaxPos.y = Window->rcWindow.top; Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient); + //rc = Window->rcWindow; + //Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)&rc); + //Window->rcClient = rc; RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left, MaxPos.y - Window->rcWindow.top); - + } /* Send the WM_CREATE message. */ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs); @@ -2593,8 +2628,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) { if (Window->spwndOwner) { - ERR("DestroyWindow Owner out.\n"); - //UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE); + //ERR("DestroyWindow Owner out.\n"); + UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE); } } } @@ -2632,8 +2667,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) { if (!IntIsTopLevelWindow(Window)) { - ERR("DestroyWindow Parent out.\n"); - //UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE); + //ERR("DestroyWindow Parent out.\n"); + UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE); } } } @@ -3377,9 +3412,12 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) if (ti->pDeskInfo) { ti->pDeskInfo->hShellWindow = hwndShell; + ti->pDeskInfo->spwndShell = WndShell; ti->pDeskInfo->ppiShellProcess = ti->ppi; } + UserRegisterHotKey(WndShell, SC_TASKLIST, MOD_CONTROL, VK_ESCAPE); + UserDerefObjectCo(WndShell); ObDereferenceObject(WinStaObject); @@ -3579,6 +3617,12 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) else Window->ExStyle &= ~WS_EX_WINDOWEDGE; + if ((Style.styleOld ^ Style.styleNew) & WS_VISIBLE) + { + if (Style.styleOld & WS_VISIBLE) Window->head.pti->cVisWindows--; + if (Style.styleNew & WS_VISIBLE) Window->head.pti->cVisWindows++; + DceResetActiveDCEs( Window ); + } Window->style = (DWORD)Style.styleNew; co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style); break; diff --git a/reactos/win32ss/user/ntuser/winpos.c b/reactos/win32ss/user/ntuser/winpos.c index ccaa0c2a968..bc4cc6598ce 100644 --- a/reactos/win32ss/user/ntuser/winpos.c +++ b/reactos/win32ss/user/ntuser/winpos.c @@ -237,6 +237,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd) if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) ) { UserRefObjectCo(pWndSetActive, &Ref); + //ERR("ActivateOtherWindowMin Set FG 1\n"); co_IntSetForegroundWindow(pWndSetActive); UserDerefObjectCo(pWndSetActive); //ERR("AOWM 2 Exit Good\n"); @@ -273,6 +274,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd) if ((pWndSetActive = pWndTemp)) { UserRefObjectCo(pWndSetActive, &Ref); + //ERR("ActivateOtherWindowMin Set FG 2\n"); co_IntSetForegroundWindow(pWndSetActive); UserDerefObjectCo(pWndSetActive); //ERR("AOWM 3 Exit Good\n"); @@ -299,7 +301,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL) if (style & WS_MINIMIZE) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; return TRUE; - /* FIXME: This window could be disable because the child that closed + /* FIXME: This window could be disable because the child that closed was a popup. */ //return !(style & WS_DISABLED); } @@ -314,7 +316,6 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Wnd) { PWND WndTo = NULL; - HWND Fg, previous; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); @@ -345,26 +346,24 @@ done: if (WndTo) UserRefObjectCo(WndTo, &Ref); - Fg = UserGetForegroundWindow(); - if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL?? No, rule #4. + if (!gpqForeground || Wnd == gpqForeground->spwndActive) { - /* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */ + /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */ + //ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo); if (co_IntSetForegroundWindow(WndTo)) { - UserDerefObjectCo(WndTo); + if (WndTo) UserDerefObjectCo(WndTo); return; } } - - if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE,FALSE) || /* Ok for WndTo to be NULL here */ - !previous) + //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo); + if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE)) /* Ok for WndTo to be NULL here */ { - co_IntSetActiveWindow(0,NULL,FALSE,TRUE,FALSE); + co_IntSetActiveWindow(0,FALSE,TRUE,FALSE); } if (WndTo) UserDerefObjectCo(WndTo); } - UINT FASTCALL co_WinPosArrangeIconicWindows(PWND parent) @@ -1131,11 +1130,71 @@ FixClientRect(PRECTL ClientRect, PRECTL WindowRect) ClientRect->bottom = WindowRect->bottom; } } +/*********************************************************************** + * get_valid_rects + * + * Compute the valid rects from the old and new client rect and WVR_* flags. + * Helper for WM_NCCALCSIZE handling. + */ +static +VOID FASTCALL +get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid ) +{ + int cx, cy; + + if (flags & WVR_REDRAW) + { + RECTL_vSetEmptyRect( &valid[0] ); + RECTL_vSetEmptyRect( &valid[1] ); + return; + } + + if (flags & WVR_VALIDRECTS) + { + if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) || + !RECTL_bIntersectRect( &valid[1], &valid[1], old_client )) + { + RECTL_vSetEmptyRect( &valid[0] ); + RECTL_vSetEmptyRect( &valid[1] ); + return; + } + flags = WVR_ALIGNLEFT | WVR_ALIGNTOP; + } + else + { + valid[0] = *new_client; + valid[1] = *old_client; + } + + /* make sure the rectangles have the same size */ + cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left ); + cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top ); + + if (flags & WVR_ALIGNBOTTOM) + { + valid[0].top = valid[0].bottom - cy; + valid[1].top = valid[1].bottom - cy; + } + else + { + valid[0].bottom = valid[0].top + cy; + valid[1].bottom = valid[1].top + cy; + } + if (flags & WVR_ALIGNRIGHT) + { + valid[0].left = valid[0].right - cx; + valid[1].left = valid[1].right - cx; + } + else + { + valid[0].right = valid[0].left + cx; + valid[1].right = valid[1].left + cx; + } +} static LONG FASTCALL -co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, - RECT* WindowRect, RECT* ClientRect) +co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL* ClientRect, RECTL* validRects) { PWND Parent; UINT wvrFlags = 0; @@ -1148,9 +1207,10 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, NCCALCSIZE_PARAMS params; WINDOWPOS winposCopy; - params.rgrc[0] = *WindowRect; - params.rgrc[1] = Window->rcWindow; - params.rgrc[2] = Window->rcClient; + params.rgrc[0] = *WindowRect; // new coordinates of a window that has been moved or resized + params.rgrc[1] = Window->rcWindow; // window before it was moved or resized + params.rgrc[2] = Window->rcClient; // client area before the window was moved or resized + Parent = Window->spwndParent; if (0 != (Window->style & WS_CHILD) && Parent) { @@ -1161,6 +1221,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left, - Parent->rcClient.top); } + params.lppos = &winposCopy; winposCopy = *WinPos; @@ -1170,7 +1231,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom) { - *ClientRect = params.rgrc[0]; + *ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize if ((Window->style & WS_CHILD) && Parent) { RECTL_vOffsetRect(ClientRect, Parent->rcClient.left, @@ -1179,21 +1240,30 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, FixClientRect(ClientRect, WindowRect); } - /* FIXME: WVR_ALIGNxxx */ - if (ClientRect->left != Window->rcClient.left || ClientRect->top != Window->rcClient.top) { WinPos->flags &= ~SWP_NOCLIENTMOVE; } - if ((ClientRect->right - ClientRect->left != - Window->rcClient.right - Window->rcClient.left) || - (ClientRect->bottom - ClientRect->top != - Window->rcClient.bottom - Window->rcClient.top)) + if (ClientRect->right - ClientRect->left != + Window->rcClient.right - Window->rcClient.left) { WinPos->flags &= ~SWP_NOCLIENTSIZE; } + else + wvrFlags &= ~WVR_HREDRAW; + + if (ClientRect->bottom - ClientRect->top != + Window->rcClient.bottom - Window->rcClient.top) + { + WinPos->flags &= ~SWP_NOCLIENTSIZE; + } + else + wvrFlags &= ~WVR_VREDRAW; + + validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination rectangle + validRects[1] = params.rgrc[2]; // third rectangle contains the valid source rectangle } else { @@ -1205,6 +1275,13 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, } } + if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW)) + { + RECTL_vSetEmptyRect( &validRects[0] ); + RECTL_vSetEmptyRect( &validRects[1] ); + } + else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects ); + return wvrFlags; } @@ -1215,15 +1292,46 @@ co_WinPosDoWinPosChanging(PWND Window, PRECTL WindowRect, PRECTL ClientRect) { - INT X, Y; - ASSERT_REFS_CO(Window); + /* Send WM_WINDOWPOSCHANGING message */ + if (!(WinPos->flags & SWP_NOSENDCHANGING)) { co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos); } + /* Calculate new position and size */ + + *WindowRect = Window->rcWindow; + *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow : Window->rcClient; + + if (!(WinPos->flags & SWP_NOSIZE)) + { + if (Window->style & WS_MINIMIZE) + { + WindowRect->right = WindowRect->left + UserGetSystemMetrics(SM_CXICON); + WindowRect->bottom = WindowRect->top + UserGetSystemMetrics(SM_CYICON); + } + else + { + WindowRect->right = WindowRect->left + WinPos->cx; + WindowRect->bottom = WindowRect->top + WinPos->cy; + } + } +#if 0 + if (!(WinPos->flags & SWP_NOMOVE)) + { + WindowRect->left = WinPos->x; + WindowRect->top = WinPos->y; + WindowRect->right += WinPos->x - Window->rcWindow.left; + WindowRect->bottom += WinPos->y - Window->rcWindow.top; + RECTL_vOffsetRect(ClientRect, + WinPos->x - Window->rcWindow.left, + WinPos->y - Window->rcWindow.top); + + } + *WindowRect = Window->rcWindow; *ClientRect = Window->rcClient; @@ -1232,22 +1340,26 @@ co_WinPosDoWinPosChanging(PWND Window, WindowRect->right = WindowRect->left + WinPos->cx; WindowRect->bottom = WindowRect->top + WinPos->cy; } - +#endif if (!(WinPos->flags & SWP_NOMOVE)) { + INT X, Y; PWND Parent; X = WinPos->x; Y = WinPos->y; + //ERR("Not SWP_NOMOVE\n"); Parent = Window->spwndParent; - if ((0 != (Window->style & WS_CHILD)) && Parent) + if ((0 != (Window->style & WS_CHILD)) && Parent && + Parent != Window->head.rpdesk->pDeskInfo->spwnd) { + //ERR("Not SWP_NOMOVE Parent client offset\n"); X += Parent->rcClient.left; Y += Parent->rcClient.top; } - WindowRect->left = X; - WindowRect->top = Y; - WindowRect->right += X - Window->rcWindow.left; + WindowRect->left = X; + WindowRect->top = Y; + WindowRect->right += X - Window->rcWindow.left; WindowRect->bottom += Y - Window->rcWindow.top; RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left, @@ -1256,6 +1368,10 @@ co_WinPosDoWinPosChanging(PWND Window, WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; + TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n", + WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y, + WinPos->cx, WinPos->cy, WinPos->flags ); + return TRUE; } @@ -1396,6 +1512,21 @@ static BOOL FASTCALL WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) { + PWND Parent; + POINT pt; + + /* Finally make sure that all coordinates are valid */ + if (WinPos->x < -32768) WinPos->x = -32768; + else if (WinPos->x > 32767) WinPos->x = 32767; + if (WinPos->y < -32768) WinPos->y = -32768; + else if (WinPos->y > 32767) WinPos->y = 32767; + + WinPos->cx = max(WinPos->cx, 0); + WinPos->cy = max(WinPos->cy, 0); + + Parent = UserGetAncestor( Wnd, GA_PARENT ); + if (!IntIsWindowVisible( Parent )) WinPos->flags |= SWP_NOREDRAW; + if (Wnd->style & WS_VISIBLE) { WinPos->flags &= ~SWP_SHOWWINDOW; @@ -1407,9 +1538,6 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) WinPos->flags |= SWP_NOREDRAW; } - WinPos->cx = max(WinPos->cx, 0); - WinPos->cy = max(WinPos->cy, 0); - /* Check for right size */ if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx && Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy) @@ -1417,10 +1545,15 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) WinPos->flags |= SWP_NOSIZE; } + pt.x = WinPos->x; + pt.y = WinPos->y; + IntClientToScreen( Parent, &pt ); +// ERR("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos->x,WinPos->y,pt.x,pt.y); /* Check for right position */ - if (Wnd->rcWindow.left == WinPos->x && - Wnd->rcWindow.top == WinPos->y) + if (Wnd->rcWindow.left == pt.x && + Wnd->rcWindow.top == pt.y) { +// ERR("In right pos\n"); WinPos->flags |= SWP_NOMOVE; } @@ -1526,6 +1659,7 @@ co_WinPosSetWindowPos( WINDOWPOS WinPos; RECTL NewWindowRect; RECTL NewClientRect; + RECTL valid_rects[2]; PROSRGNDATA VisRgn; HRGN VisBefore = NULL; HRGN VisAfter = NULL; @@ -1543,7 +1677,7 @@ co_WinPosSetWindowPos( ASSERT_REFS_CO(Window); - /* FIXME: Get current active window from active queue. */ + /* FIXME: Get current active window from active queue. Why? since r2915. */ bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y); @@ -1555,6 +1689,27 @@ co_WinPosSetWindowPos( WinPos.cy = cy; WinPos.flags = flags; + if ( flags & SWP_ASYNCWINDOWPOS ) + { + LRESULT lRes; + PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS), USERTAG_SWP); + if ( ppos ) + { + WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag. + *ppos = WinPos; + /* Yes it's a pointer inside Win32k! */ + lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos); + /* We handle this the same way as Event Hooks and Hooks. */ + if ( !lRes ) + { + ExFreePoolWithTag(ppos, USERTAG_SWP); + return FALSE; + } + return TRUE; + } + return FALSE; + } + co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect); // HWND_NOTOPMOST is redirected in WinPosFixupFlags. @@ -1610,9 +1765,11 @@ co_WinPosSetWindowPos( } } - WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect); + WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects); - TRACE("co_WinPosDoNCCALCSize returned %lu\n", WvrFlags); +// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags, +// valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom, +// valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom); /* Validate link windows. (also take into account shell window in hwndShellWindow) */ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow()) @@ -1624,6 +1781,7 @@ co_WinPosSetWindowPos( if ((ParentWindow = Window->spwndParent)) // Must have a Parent window! { + //ERR("SetWindowPos has parent window.\n"); if (WinPos.hwndInsertAfter == HWND_TOPMOST) { InsertAfterWindow = NULL; @@ -1682,20 +1840,8 @@ co_WinPosSetWindowPos( OldWindowRect = Window->rcWindow; OldClientRect = Window->rcClient; - - if (OldClientRect.bottom - OldClientRect.top == - NewClientRect.bottom - NewClientRect.top) - { - WvrFlags &= ~WVR_VREDRAW; - } - - if (OldClientRect.right - OldClientRect.left == - NewClientRect.right - NewClientRect.left) - { - WvrFlags &= ~WVR_HREDRAW; - } - - /* FIXME: Actually do something with WVR_VALIDRECTS */ + //ERR("SetWindowPos OldWindowRect: %d %d %d %d\n", OldWindowRect.left,OldWindowRect.top,OldWindowRect.right,OldWindowRect.bottom); + //ERR("SetWindowPos OldClientRect: %d %d %d %d\n", OldClientRect.left,OldClientRect.top,OldClientRect.right,OldClientRect.bottom); if (NewClientRect.left != OldClientRect.left || NewClientRect.top != OldClientRect.top) @@ -1708,6 +1854,9 @@ co_WinPosSetWindowPos( Window->rcWindow = NewWindowRect; Window->rcClient = NewClientRect; + //ERR("SetWindowPos NewWindowRect: %d %d %d %d\n", NewWindowRect.left,NewWindowRect.top,NewWindowRect.right,NewWindowRect.bottom); + //ERR("SetWindowPos NewClientRect: %d %d %d %d\n", NewClientRect.left,NewClientRect.top,NewClientRect.right,NewClientRect.bottom); + /* erase parent when hiding or resizing child */ if (WinPos.flags & SWP_HIDEWINDOW) { @@ -1721,6 +1870,7 @@ co_WinPosSetWindowPos( co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0); Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE ); + Window->head.pti->cVisWindows--; IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } else if (WinPos.flags & SWP_SHOWWINDOW) @@ -1729,6 +1879,7 @@ co_WinPosSetWindowPos( co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0); Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 ); + Window->head.pti->cVisWindows++; IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } @@ -1955,7 +2106,10 @@ co_WinPosSetWindowPos( else { //ERR("SetWindowPos Set FG Window!\n"); - co_IntSetForegroundWindow(Window); + if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW? + co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests. + else + co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow. } } @@ -2036,7 +2190,7 @@ co_WinPosSendSizeMove(PWND Wnd) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam); - if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP ) + if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP ) lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top); else lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left, Wnd->rcClient.top-Wnd->spwndParent->rcClient.top); @@ -2056,9 +2210,9 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) LONG style; PWND Parent; PTHREADINFO pti; - // BOOL ShowOwned = FALSE; // HRGN VisibleRgn; - + //ERR("co_WinPosShowWindow START\n"); + BOOL ShowOwned = FALSE; ASSERT_REFS_CO(Wnd); pti = PsGetCurrentThreadWin32Thread(); @@ -2071,6 +2225,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) { if (!WasVisible) { + //ERR("co_WinPosShowWindow Exit Bad\n"); return(FALSE); } Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE; @@ -2091,11 +2246,12 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_NOACTIVATE; if (!(style & WS_MINIMIZE)) { - //IntShowOwnedPopups(Wnd, FALSE ); + IntShowOwnedPopups(Wnd, FALSE ); // Fix wine Win test_SetFocus todo #1 & #2, if (Cmd == SW_SHOWMINIMIZED) { + //ERR("co_WinPosShowWindow Set focus 1\n"); if ((style & (WS_CHILD | WS_POPUP)) == WS_CHILD) co_UserSetFocus(Wnd->spwndParent); else @@ -2114,7 +2270,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } break; @@ -2125,7 +2284,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_SHOWWINDOW; if (!(style & WS_MAXIMIZE)) { - //ShowOwned = TRUE; + ShowOwned = TRUE; Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) | SWP_FRAMECHANGED; @@ -2139,7 +2298,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good 1\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } break; @@ -2177,7 +2339,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good 3\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } if ( style & WS_CHILD && @@ -2187,6 +2352,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) break; default: + //ERR("co_WinPosShowWindow Exit Good 4\n"); return WasVisible; } @@ -2214,7 +2380,8 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Wnd->pcls->style & CS_SAVEBITS && ((Cmd == SW_SHOW) || (Cmd == SW_NORMAL))) { - co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE,FALSE); + ERR("WinPosShowWindow Set active\n"); + UserSetActiveWindow(Wnd); Swp |= SWP_NOACTIVATE | SWP_NOZORDER; } #endif @@ -2242,7 +2409,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); - //if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE ); + if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE ); if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE)) { @@ -2281,6 +2448,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) // Fix wine Win test_SetFocus todo #3, if (!(style & WS_CHILD)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_ACTIVATE, WA_ACTIVE, 0); } + //ERR("co_WinPosShowWindow EXIT\n"); return(WasVisible); } From 533fa53c13fb22f8807b75bd73763bb841236256 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Oct 2013 05:31:48 +0000 Subject: [PATCH 22/36] - Fix build. svn path=/trunk/; revision=60719 --- reactos/win32ss/user/ntuser/keyboard.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reactos/win32ss/user/ntuser/keyboard.c b/reactos/win32ss/user/ntuser/keyboard.c index 2b2cf6260fd..28ac361b63d 100644 --- a/reactos/win32ss/user/ntuser/keyboard.c +++ b/reactos/win32ss/user/ntuser/keyboard.c @@ -904,6 +904,13 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } if (Wnd) pti = Wnd->head.pti; + /* Init message */ + Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL; + Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */ + Msg.lParam = MAKELPARAM(1, wScanCode); + Msg.time = dwTime; + Msg.pt = gpsi->ptCursor; + if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN ) { if ( (Msg.wParam == VK_SHIFT || @@ -916,13 +923,6 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } } - /* Init message */ - Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL; - Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */ - Msg.lParam = MAKELPARAM(1, wScanCode); - Msg.time = dwTime; - Msg.pt = gpsi->ptCursor; - /* If it is VK_PACKET, high word of wParam is used for wchar */ if (!bPacket) { From 746f5c09a79d7abfbb547b5079f8fcde4d029f10 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 20 Oct 2013 05:36:36 +0000 Subject: [PATCH 23/36] - Fix ATI test and go. svn path=/trunk/; revision=60720 --- rostests/apitests/user32/AttachThreadInput.c | 32 ++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/rostests/apitests/user32/AttachThreadInput.c b/rostests/apitests/user32/AttachThreadInput.c index c8a95ff1cd7..979851f7d94 100644 --- a/rostests/apitests/user32/AttachThreadInput.c +++ b/rostests/apitests/user32/AttachThreadInput.c @@ -357,6 +357,7 @@ void Test_Focus() //Focus Active Capture Foreground Capture { BOOL ret; + trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd); /* Window 1 is in the foreground */ SetForegroundWindow(data[1].hWnd); SetActiveWindow(data[0].hWnd); @@ -552,15 +553,17 @@ void Test_SendInput() BOOL ret; + //trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd); + /* First try sending input without attaching. It will go to the foreground */ { SetForegroundWindow(data[1].hWnd); SetActiveWindow(data[0].hWnd); + + ok(GetForegroundWindow() == data[1].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow()); + ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow()); - ok(GetForegroundWindow() == data[1].hWnd, "wrong foreground\n"); - ok(GetActiveWindow() == data[0].hWnd, "wrong active\n"); - - FlushMessages(); + FlushMessages(); EMPTY_CACHE_(&data[0].cache); EMPTY_CACHE_(&data[1].cache); @@ -574,7 +577,7 @@ void Test_SendInput() } /* Next attach and send input. It will go to the same thread as before */ - { + { // from to ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE); ok(ret==1, "expected AttachThreadInput to succeed\n"); @@ -591,12 +594,15 @@ void Test_SendInput() COMPARE_CACHE_(&data[1].cache, Thread1_chain); } - /* Now set foregroung and active again. Input will go to thread 0 */ + /* Now set foreground and active again. Input will go to thread 0 */ { SetForegroundWindow(data[1].hWnd); SetActiveWindow(data[0].hWnd); - FlushMessages(); + + ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow()); + ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow()); + EMPTY_CACHE_(&data[0].cache); EMPTY_CACHE_(&data[1].cache); @@ -630,12 +636,15 @@ void Test_SendInput() COMPARE_CACHE_(&data[1].cache, empty_chain); } - /* Now set foregroung and active again. Input will go to thread 0 */ + /* Now set foreground and active again. Input will go to thread 0 */ { SetForegroundWindow(data[1].hWnd); SetActiveWindow(data[0].hWnd); - FlushMessages(); + + ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow()); + ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow()); + EMPTY_CACHE_(&data[0].cache); EMPTY_CACHE_(&data[1].cache); @@ -657,9 +666,8 @@ START_TEST(AttachThreadInput) if(!InitThreads()) return; - win_skip("skip Test_SimpleParameters that crash ros\n"); - //Test_SimpleParameters(); - //cleanup_attachments(); + Test_SimpleParameters(); + cleanup_attachments(); Test_Focus(); cleanup_attachments(); Test_UnaffectedMessages(); From 41537ba703ee5b36c1b9339ed7a16eebd6f6cd57 Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 20 Oct 2013 09:41:54 +0000 Subject: [PATCH 24/36] [NTOS] - Correctly compute addresses of MI_VAD_BITMAP and MI_WORKING_SET_LIST. In trunk's MM it went unnoticed because nothing really cares about these two structs. svn path=/trunk/; revision=60721 --- reactos/ntoskrnl/include/internal/i386/mm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/i386/mm.h b/reactos/ntoskrnl/include/internal/i386/mm.h index 72bbcec2552..27237a67a2b 100644 --- a/reactos/ntoskrnl/include/internal/i386/mm.h +++ b/reactos/ntoskrnl/include/internal/i386/mm.h @@ -96,11 +96,11 @@ PULONG MmGetPageDirectory(VOID); #define MI_MAPPING_RANGE_START (ULONG)HYPER_SPACE #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + \ MI_HYPERSPACE_PTES * PAGE_SIZE) -#define MI_DUMMY_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \ +#define MI_DUMMY_PTE (PMMPTE)((ULONG_PTR)MI_MAPPING_RANGE_END + \ PAGE_SIZE) -#define MI_VAD_BITMAP (PMMPTE)(MI_DUMMY_PTE + \ +#define MI_VAD_BITMAP (PMMPTE)((ULONG_PTR)MI_DUMMY_PTE + \ PAGE_SIZE) -#define MI_WORKING_SET_LIST (PMMPTE)(MI_VAD_BITMAP + \ +#define MI_WORKING_SET_LIST (PMMPTE)((ULONG_PTR)MI_VAD_BITMAP + \ PAGE_SIZE) /* On x86, these two are the same */ From 9d3f488a5789316ebc1b0ec2dcf22a0d4f445340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 20 Oct 2013 13:51:18 +0000 Subject: [PATCH 25/36] [USETUP]: Fix spanish translations, suggestions by Mario Rugiero and Julio Carchi CORE-7516 #resolve #comment Suggestions committed in revision r60722. Thanks :) svn path=/trunk/; revision=60722 --- reactos/base/setup/usetup/lang/es-ES.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index 930accac885..f98579721af 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -986,25 +986,25 @@ static MUI_ENTRY esESBootLoaderEntries[] = { 6, 8, - "El programa est  instalando el cargador de arranque", + "El programa est instalando el cargador de arranque", TEXT_STYLE_NORMAL }, { 8, 12, - "Instalar cargador de arranque en el disco duro (MBR and VBR).", + "Instalar el cargador de arranque en el disco duro (MBR y VBR).", TEXT_STYLE_NORMAL }, { 8, 13, - "Instalar cargador de arranque en el disco duro (VBR only).", + "Instalar el cargador de arranque en el disco duro (s¢lo VBR).", TEXT_STYLE_NORMAL }, { 8, 14, - "Instalar cargador de inicio en un disquete.", + "Instalar el cargador de inicio en un disquete.", TEXT_STYLE_NORMAL }, { From 56df983f97310ca40fbcc331890fb7e290d10928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 20 Oct 2013 13:54:16 +0000 Subject: [PATCH 26/36] Fix the fix. svn path=/trunk/; revision=60723 --- reactos/base/setup/usetup/lang/es-ES.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/setup/usetup/lang/es-ES.h b/reactos/base/setup/usetup/lang/es-ES.h index f98579721af..2089e1e313e 100644 --- a/reactos/base/setup/usetup/lang/es-ES.h +++ b/reactos/base/setup/usetup/lang/es-ES.h @@ -986,7 +986,7 @@ static MUI_ENTRY esESBootLoaderEntries[] = { 6, 8, - "El programa est instalando el cargador de arranque", + "El programa est  instalando el cargador de arranque", TEXT_STYLE_NORMAL }, { From 9625b9b82057bd27e560fd9ffc9158d976b0d808 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 20 Oct 2013 19:46:28 +0000 Subject: [PATCH 27/36] =?UTF-8?q?[WIN32K]=20Add=20GreSetObjectOwnerEx,=20a?= =?UTF-8?q?llowing=20to=20set=20the=20owner=20of=20not-owned=20objects=20b?= =?UTF-8?q?y=20passing=20GDIOBJFLAG=5FIGNOREPID=20as=203rd=20parameter.=20?= =?UTF-8?q?Use=20with=20care=20:)=20Dedicated=20to=20Alexander=20and=20Her?= =?UTF-8?q?m=C3=A8s.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit svn path=/trunk/; revision=60725 --- reactos/win32ss/gdi/ntgdi/gdiobj.c | 108 +++++++++++++++++++++-------- reactos/win32ss/gdi/ntgdi/gdiobj.h | 7 ++ 2 files changed, 88 insertions(+), 27 deletions(-) diff --git a/reactos/win32ss/gdi/ntgdi/gdiobj.c b/reactos/win32ss/gdi/ntgdi/gdiobj.c index a5d75bba98c..740fd92363c 100644 --- a/reactos/win32ss/gdi/ntgdi/gdiobj.c +++ b/reactos/win32ss/gdi/ntgdi/gdiobj.c @@ -222,7 +222,7 @@ InitGdiHandleTable(void) FORCEINLINE VOID -IncrementGdiHandleCount(void) +IncrementCurrentProcessGdiHandleCount(void) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount); @@ -230,12 +230,42 @@ IncrementGdiHandleCount(void) FORCEINLINE VOID -DecrementGdiHandleCount(void) +DecrementCurrentProcessGdiHandleCount(void) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount); } +FORCEINLINE +VOID +IncrementGdiHandleCount(ULONG ulProcessId) +{ + PEPROCESS pep; + PPROCESSINFO ppi; + NTSTATUS Status; + + Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep); + NT_ASSERT(NT_SUCCESS(Status)); + + ppi = PsGetProcessWin32Process(pep); + if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount); +} + +FORCEINLINE +VOID +DecrementGdiHandleCount(ULONG ulProcessId) +{ + PEPROCESS pep; + PPROCESSINFO ppi; + NTSTATUS Status; + + Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep); + NT_ASSERT(NT_SUCCESS(Status)); + + ppi = PsGetProcessWin32Process(pep); + if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount); +} + static PENTRY ENTRY_pentPopFreeEntry(VOID) @@ -497,7 +527,7 @@ GDIOBJ_vDereferenceObject(POBJ pobj) /* Decrement the process handle count */ ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj == HandleToUlong(PsGetCurrentProcessId())); - DecrementGdiHandleCount(); + DecrementCurrentProcessGdiHandleCount(); } /* Push entry to the free list */ @@ -710,7 +740,7 @@ GDIOBJ_hInsertObject( if (ulOwner == GDI_OBJ_HMGR_POWNED) { /* Increment the process handle count */ - IncrementGdiHandleCount(); + IncrementCurrentProcessGdiHandleCount(); /* Use Process id */ ulOwner = HandleToUlong(PsGetCurrentProcessId()); @@ -729,50 +759,64 @@ VOID NTAPI GDIOBJ_vSetObjectOwner( POBJ pobj, - ULONG ulOwner) + ULONG ulNewOwner) { PENTRY pentry; + ULONG ulOldOwner; /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */ if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr)) { - DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulOwner); + DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner); return; } /* Get the handle entry */ - ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr)); + NT_ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr)); pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)]; + /* Check if the new owner is the same as the old one */ + ulOldOwner = pentry->ObjectOwner.ulObj; + if (ulOldOwner == ulNewOwner) + { + /* Nothing to do */ + return; + } + /* Is the current process requested? */ - if (ulOwner == GDI_OBJ_HMGR_POWNED) + if (ulNewOwner == GDI_OBJ_HMGR_POWNED) { /* Use process id */ - ulOwner = HandleToUlong(PsGetCurrentProcessId()); - if (pentry->ObjectOwner.ulObj != ulOwner) - { - IncrementGdiHandleCount(); - } + ulNewOwner = HandleToUlong(PsGetCurrentProcessId()); } // HACK - if (ulOwner == GDI_OBJ_HMGR_NONE) - ulOwner = GDI_OBJ_HMGR_PUBLIC; + if (ulNewOwner == GDI_OBJ_HMGR_NONE) + ulNewOwner = GDI_OBJ_HMGR_PUBLIC; - if (ulOwner == GDI_OBJ_HMGR_PUBLIC || - ulOwner == GDI_OBJ_HMGR_NONE) + /* Was the object process owned? */ + if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) && + (ulOldOwner != GDI_OBJ_HMGR_NONE)) + { + /* Decrement the previous owners handle count */ + DecrementGdiHandleCount(ulOldOwner); + } + + /* Is the new owner a process? */ + if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) && + (ulNewOwner != GDI_OBJ_HMGR_NONE)) + { + /* Increment the new owners handle count */ + IncrementGdiHandleCount(ulNewOwner); + } + else { /* Make sure we don't leak user mode memory */ - ASSERT(pentry->pUser == NULL); - if (pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC && - pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE) - { - DecrementGdiHandleCount(); - } + NT_ASSERT(pentry->pUser == NULL); } /* Set new owner */ - pentry->ObjectOwner.ulObj = ulOwner; + pentry->ObjectOwner.ulObj = ulNewOwner; DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0); } @@ -970,9 +1014,10 @@ GreGetObjectOwner(HGDIOBJ hobj) BOOL NTAPI -GreSetObjectOwner( +GreSetObjectOwnerEx( HGDIOBJ hobj, - ULONG ulOwner) + ULONG ulOwner, + ULONG Flags) { PENTRY pentry; @@ -984,7 +1029,7 @@ GreSetObjectOwner( } /* Reference the handle entry */ - pentry = ENTRY_ReferenceEntryByHandle(hobj, 0); + pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags); if (!pentry) { DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj); @@ -1000,6 +1045,15 @@ GreSetObjectOwner( return TRUE; } +BOOL +NTAPI +GreSetObjectOwner( + HGDIOBJ hobj, + ULONG ulOwner) +{ + return GreSetObjectOwnerEx(hobj, ulOwner, 0); +} + INT NTAPI GreGetObject( diff --git a/reactos/win32ss/gdi/ntgdi/gdiobj.h b/reactos/win32ss/gdi/ntgdi/gdiobj.h index b459a0cbc79..5eb30a3ea7d 100644 --- a/reactos/win32ss/gdi/ntgdi/gdiobj.h +++ b/reactos/win32ss/gdi/ntgdi/gdiobj.h @@ -93,6 +93,13 @@ GreSetObjectOwner( HGDIOBJ hobj, ULONG ulOwner); +BOOL +NTAPI +GreSetObjectOwnerEx( + HGDIOBJ hobj, + ULONG ulOwner, + ULONG Flags); + INT NTAPI GreGetObject( From 92bd19337bf6da96e8e071f593790936b1bc11da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 20 Oct 2013 22:35:15 +0000 Subject: [PATCH 28/36] [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 svn path=/trunk/; revision=60726 --- reactos/win32ss/include/ntuser.h | 3 +- reactos/win32ss/user/ntuser/ntstubs.c | 29 ++++++- .../user/winsrv/consrv/condrv/conoutput.c | 8 -- .../win32ss/user/winsrv/consrv/conoutput.c | 81 +++---------------- 4 files changed, 39 insertions(+), 82 deletions(-) diff --git a/reactos/win32ss/include/ntuser.h b/reactos/win32ss/include/ntuser.h index 1677a769216..862fae52cce 100644 --- a/reactos/win32ss/include/ntuser.h +++ b/reactos/win32ss/include/ntuser.h @@ -1571,6 +1571,7 @@ NtUserCloseWindowStation( typedef enum _CONSOLECONTROL { GuiConsoleWndClassAtom, + ConsoleMakePalettePublic = 5, ConsoleAcquireDisplayOwnership, } CONSOLECONTROL, *PCONSOLECONTROL; @@ -1579,7 +1580,7 @@ APIENTRY NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength); + IN ULONG ConsoleCtrlInfoLength); HANDLE NTAPI diff --git a/reactos/win32ss/user/ntuser/ntstubs.c b/reactos/win32ss/user/ntuser/ntstubs.c index b421f57215b..ab165f45f89 100644 --- a/reactos/win32ss/user/ntuser/ntstubs.c +++ b/reactos/win32ss/user/ntuser/ntstubs.c @@ -546,7 +546,7 @@ APIENTRY NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength) + IN ULONG ConsoleCtrlInfoLength) { NTSTATUS Status = STATUS_SUCCESS; @@ -562,8 +562,8 @@ NtUserConsoleControl( { _SEH2_TRY { - ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM)); + ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -575,8 +575,33 @@ NtUserConsoleControl( 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; } diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c b/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c index a4f388739ec..27bbe48837d 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/conoutput.c @@ -237,8 +237,6 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, { BOOL Success; - DPRINT1("ConDrvSetConsolePalette\n"); - /* * Parameters validation */ @@ -256,11 +254,9 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, 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 ) @@ -272,10 +268,6 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, Buffer->PaletteHandle = PaletteHandle; Buffer->PaletteUsage = PaletteUsage; } - else - { - DPRINT1("TermSetPalette failed\n"); - } return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } diff --git a/reactos/win32ss/user/winsrv/consrv/conoutput.c b/reactos/win32ss/user/winsrv/consrv/conoutput.c index bca67fd7ff1..e7ea3846af1 100644 --- a/reactos/win32ss/user/winsrv/consrv/conoutput.c +++ b/reactos/win32ss/user/winsrv/consrv/conoutput.c @@ -63,38 +63,7 @@ CSR_API(SrvSetConsolePalette) // 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,51 +80,21 @@ CSR_API(SrvSetConsolePalette) &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; } From e64f2a9675f23fcdd33d3bdb50c18639584c56bc Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 21 Oct 2013 09:13:14 +0000 Subject: [PATCH 29/36] [INCLUDE] - sam.idl: Rename GROUP_ATTRIBUTE_INFORMATION to SAMPR_GROUP_ATTRIBUTE_INFORMATION in order to avoid confilcts with new types in ntsam.h. - ntsam.h: Add missing group specific structures. svn path=/trunk/; revision=60727 --- reactos/include/ddk/ntsam.h | 23 +++++++++++++++++++++++ reactos/include/reactos/idl/sam.idl | 6 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/reactos/include/ddk/ntsam.h b/reactos/include/ddk/ntsam.h index 5f272831629..63d8fcf5514 100644 --- a/reactos/include/ddk/ntsam.h +++ b/reactos/include/ddk/ntsam.h @@ -440,6 +440,29 @@ typedef enum _GROUP_INFORMATION_CLASS GroupReplicationInformation } GROUP_INFORMATION_CLASS; +typedef struct _GROUP_GENERAL_INFORMATION +{ + UNICODE_STRING Name; + ULONG Attributes; + ULONG MemberCount; + UNICODE_STRING AdminComment; +} GROUP_GENERAL_INFORMATION, *PGROUP_GENERAL_INFORMATION; + +typedef struct _GROUP_NAME_INFORMATION +{ + UNICODE_STRING Name; +} GROUP_NAME_INFORMATION, *PGROUP_NAME_INFORMATION; + +typedef struct _GROUP_ATTRIBUTE_INFORMATION +{ + ULONG Attributes; +} GROUP_ATTRIBUTE_INFORMATION, *PGROUP_ATTRIBUTE_INFORMATION; + +typedef struct GROUP_ADM_COMMENT_INFORMATION +{ + UNICODE_STRING AdminComment; +} GROUP_ADM_COMMENT_INFORMATION, *PGROUP_ADM_COMMENT_INFORMATION; + typedef struct _GROUP_MEMBERSHIP { ULONG RelativeId; diff --git a/reactos/include/reactos/idl/sam.idl b/reactos/include/reactos/idl/sam.idl index e9434ad25f1..7111d7f92b0 100644 --- a/reactos/include/reactos/idl/sam.idl +++ b/reactos/include/reactos/idl/sam.idl @@ -366,10 +366,10 @@ typedef [switch_type(DOMAIN_DISPLAY_INFORMATION)] union _SAMPR_DISPLAY_INFO_BUFF [case(DomainDisplayOemGroup)] SAMPR_DOMAIN_DISPLAY_OEM_GROUP_BUFFER OemGroupInformation; } SAMPR_DISPLAY_INFO_BUFFER, *PSAMPR_DISPLAY_INFO_BUFFER; -typedef struct _GROUP_ATTRIBUTE_INFORMATION +typedef struct _SAMPR_GROUP_ATTRIBUTE_INFORMATION { unsigned long Attributes; -} GROUP_ATTRIBUTE_INFORMATION, *PGROUP_ATTRIBUTE_INFORMATION; +} SAMPR_GROUP_ATTRIBUTE_INFORMATION, *PSAMPR_GROUP_ATTRIBUTE_INFORMATION; typedef struct _SAMPR_GROUP_GENERAL_INFORMATION { @@ -404,7 +404,7 @@ typedef [switch_type(GROUP_INFORMATION_CLASS)] union _SAMPR_GROUP_INFO_BUFFER { [case(GroupGeneralInformation)] SAMPR_GROUP_GENERAL_INFORMATION General; [case(GroupNameInformation)] SAMPR_GROUP_NAME_INFORMATION Name; - [case(GroupAttributeInformation)] GROUP_ATTRIBUTE_INFORMATION Attribute; + [case(GroupAttributeInformation)] SAMPR_GROUP_ATTRIBUTE_INFORMATION Attribute; [case(GroupAdminCommentInformation)] SAMPR_GROUP_ADM_COMMENT_INFORMATION AdminComment; [case(GroupReplicationInformation)] SAMPR_GROUP_GENERAL_INFORMATION DoNotUse; } SAMPR_GROUP_INFO_BUFFER, *PSAMPR_GROUP_INFO_BUFFER; From 89f9c1211703915a2331388225705591475e98bf Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 21 Oct 2013 10:25:21 +0000 Subject: [PATCH 30/36] [SAMSRV] - SampSetupCreateUserAccount, SamrCreateUserInDomain and SamrCreateUser2InDomain: Set the PrivateData attribute. - SamrGetAliasMembership: Remove a superfluous call to SampRegCloseKey. - SampQueryUserAll and SampSetUserAll: Disable access to the SecDesc attribute as long as it is not set upon user account creation. svn path=/trunk/; revision=60728 --- reactos/dll/win32/samsrv/samrpc.c | 25 ++++++++++++++++++++++++- reactos/dll/win32/samsrv/setup.c | 10 ++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 3e7780c272b..5bf8f743f26 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -2469,6 +2469,16 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the PrivateData attribute */ + Status = SampSetObjectAttributeString(UserObject, + L"PrivateData", + NULL); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + /* FIXME: Set SecDesc attribute*/ if (NT_SUCCESS(Status)) @@ -3191,7 +3201,6 @@ TRACE("Open %S\n", MemberSidString); } done: - SampRegCloseKey(&MembersKeyHandle); SampRegCloseKey(&MembersKeyHandle); SampRegCloseKey(&AliasesKeyHandle); @@ -6810,6 +6819,7 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR) { +#if 0 Length = 0; SampGetObjectAttribute(UserObject, L"SecDesc", @@ -6836,6 +6846,7 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (!NT_SUCCESS(Status)) goto done; } +#endif } *Buffer = InfoBuffer; @@ -7607,11 +7618,13 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject, if (WhichFields & USER_ALL_SECURITYDESCRIPTOR) { +#if 0 Status = SampSetObjectAttribute(UserObject, L"SecDesc", REG_BINARY, Buffer->All.SecurityDescriptor.SecurityDescriptor, Buffer->All.SecurityDescriptor.Length); +#endif } if (WriteFixedData == TRUE) @@ -8786,6 +8799,16 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the PrivateData attribute */ + Status = SampSetObjectAttributeString(UserObject, + L"PrivateData", + NULL); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + /* FIXME: Set SecDesc attribute*/ if (NT_SUCCESS(Status)) diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index ce96c7ae23e..cf2bbb058fb 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -510,6 +510,16 @@ SampSetupCreateUserAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Set PrivateData attribute*/ + Status = SampRegSetValue(hAccountKey, + L"PrivateData", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + /* FIXME: Set SecDesc attribute*/ From ab4c296d0fa65faafc17d1ea5a3f1f2b645260aa Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 21 Oct 2013 18:53:26 +0000 Subject: [PATCH 31/36] [SAMSRV] Create and set a security descriptor for new alias account objects. svn path=/trunk/; revision=60729 --- reactos/dll/win32/samsrv/samrpc.c | 26 +++ reactos/dll/win32/samsrv/samsrv.h | 8 +- reactos/dll/win32/samsrv/security.c | 288 ++++++++++++++++++++++++++++ reactos/dll/win32/samsrv/setup.c | 19 ++ 4 files changed, 339 insertions(+), 2 deletions(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 5bf8f743f26..dc12d216c31 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -2714,6 +2714,8 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, SAM_DOMAIN_FIXED_DATA FixedDomainData; PSAM_DB_OBJECT DomainObject; PSAM_DB_OBJECT AliasObject; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; @@ -2758,6 +2760,15 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Create the security descriptor */ + Status = SampCreateAliasSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("SampCreateAliasSD failed (Status 0x%08lx)\n", Status); + goto done; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -2837,6 +2848,18 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set SecDesc attribute*/ + Status = SampSetObjectAttribute(AliasObject, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + if (NT_SUCCESS(Status)) { *AliasHandle = (SAMPR_HANDLE)AliasObject; @@ -2844,6 +2867,9 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, } done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + RtlReleaseResource(&SampResource); TRACE("returns with status 0x%08lx\n", Status); diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index f781287b161..fcc5c62a1da 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -321,13 +321,17 @@ SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, OUT PULONG Size); NTSTATUS -SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd, +SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR *DomainSd, OUT PULONG Size); NTSTATUS -SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd, +SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR *DomainSd, OUT PULONG Size); +NTSTATUS +SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd, + OUT PULONG Size); + /* setup.c */ diff --git a/reactos/dll/win32/samsrv/security.c b/reactos/dll/win32/samsrv/security.c index f58939106c4..f18fdf3beee 100644 --- a/reactos/dll/win32/samsrv/security.c +++ b/reactos/dll/win32/samsrv/security.c @@ -859,4 +859,292 @@ done: return Status; } + +NTSTATUS +SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PSID AccountOperatorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Account Operators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ACCOUNT_OPS, + 0, + 0, + 0, + 0, + 0, + 0, + &AccountOperatorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 3 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid) + + RtlLengthSid(AccountOperatorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + READ_CONTROL | ALIAS_READ_INFORMATION | ALIAS_LIST_MEMBERS, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ALIAS_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ALIAS_ALL_ACCESS, + AccountOperatorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + ALIAS_WRITE_ACCOUNT | ALIAS_REMOVE_MEMBER | + ALIAS_ADD_MEMBER, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *AliasSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + + /* EOF */ diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index cf2bbb058fb..1f1b531809c 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -98,6 +98,8 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, WCHAR szAccountKeyName[32]; HANDLE hAccountKey = NULL; HANDLE hNamesKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; NTSTATUS Status; swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId); @@ -125,6 +127,20 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Create the server SD */ + Status = SampCreateAliasSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set SecDesc attribute*/ + Status = SampRegSetValue(hAccountKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; Status = SampRegOpenKey(hDomainKey, L"Aliases\\Names", @@ -142,6 +158,9 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, done: SampRegCloseKey(&hNamesKey); + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + if (hAccountKey != NULL) { SampRegCloseKey(&hAccountKey); From 9a3424b618eb595005eecc2bc6ca030c075daea0 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 21 Oct 2013 20:16:56 +0000 Subject: [PATCH 32/36] [SAMSRV] Create and set a security descriptor for new group account objects. svn path=/trunk/; revision=60730 --- reactos/dll/win32/samsrv/samrpc.c | 28 ++- reactos/dll/win32/samsrv/samsrv.h | 4 + reactos/dll/win32/samsrv/security.c | 286 ++++++++++++++++++++++++++++ reactos/dll/win32/samsrv/setup.c | 20 ++ 4 files changed, 337 insertions(+), 1 deletion(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index dc12d216c31..3b42f573f4d 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -1770,6 +1770,8 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, SAM_GROUP_FIXED_DATA FixedGroupData; PSAM_DB_OBJECT DomainObject; PSAM_DB_OBJECT GroupObject; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; @@ -1814,6 +1816,15 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Create the security descriptor */ + Status = SampCreateGroupSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("SampCreateGroupSD failed (Status 0x%08lx)\n", Status); + goto done; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -1910,6 +1921,18 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the SecDesc attribute*/ + Status = SampSetObjectAttribute(GroupObject, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + if (NT_SUCCESS(Status)) { *GroupHandle = (SAMPR_HANDLE)GroupObject; @@ -1917,6 +1940,9 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, } done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + RtlReleaseResource(&SampResource); TRACE("returns with status 0x%08lx\n", Status); @@ -2848,7 +2874,7 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } - /* Set SecDesc attribute*/ + /* Set the SecDesc attribute*/ Status = SampSetObjectAttribute(AliasObject, L"SecDesc", REG_BINARY, diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index fcc5c62a1da..91427a0d523 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -332,6 +332,10 @@ NTSTATUS SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd, OUT PULONG Size); +NTSTATUS +SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd, + OUT PULONG Size); + /* setup.c */ diff --git a/reactos/dll/win32/samsrv/security.c b/reactos/dll/win32/samsrv/security.c index f18fdf3beee..dab82ad12b9 100644 --- a/reactos/dll/win32/samsrv/security.c +++ b/reactos/dll/win32/samsrv/security.c @@ -1147,4 +1147,290 @@ done: } +NTSTATUS +SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PSID AccountOperatorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Account Operators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ACCOUNT_OPS, + 0, + 0, + 0, + 0, + 0, + 0, + &AccountOperatorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 3 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid) + + RtlLengthSid(AccountOperatorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + READ_CONTROL | GROUP_LIST_MEMBERS | GROUP_READ_INFORMATION, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GROUP_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GROUP_ALL_ACCESS, + AccountOperatorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + GROUP_REMOVE_MEMBER | GROUP_ADD_MEMBER | + GROUP_WRITE_ACCOUNT, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *GroupSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + /* EOF */ diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index 1f1b531809c..ad758cadca7 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -264,6 +264,8 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, WCHAR szAccountKeyName[32]; HANDLE hAccountKey = NULL; HANDLE hNamesKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; NTSTATUS Status; /* Initialize fixed group data */ @@ -305,6 +307,21 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Create the security descriptor */ + Status = SampCreateGroupSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SecDesc attribute*/ + Status = SampRegSetValue(hAccountKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; + Status = SampRegOpenKey(hDomainKey, L"Groups\\Names", KEY_ALL_ACCESS, @@ -321,6 +338,9 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, done: SampRegCloseKey(&hNamesKey); + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + if (hAccountKey != NULL) { SampRegCloseKey(&hAccountKey); From 508dc39a87a15a32d1f22c2fb3ca227f0027a76d Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 22 Oct 2013 19:01:07 +0000 Subject: [PATCH 33/36] [SHELL32] - Import SHCreateShellFolderView implementation and fixes for -Ex from Wine CORE-7334 #resolve svn path=/trunk/; revision=60731 --- reactos/dll/win32/shell32/shellord.cpp | 46 ++++++++++++-------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/reactos/dll/win32/shell32/shellord.cpp b/reactos/dll/win32/shell32/shellord.cpp index 166b8e473bf..b83b6adc7eb 100644 --- a/reactos/dll/win32/shell32/shellord.cpp +++ b/reactos/dll/win32/shell32/shellord.cpp @@ -1009,21 +1009,18 @@ HRESULT WINAPI SHCreateShellFolderViewEx( LPCSFV psvcbi, /* [in] shelltemplate struct */ IShellView **ppv) /* [out] IShellView pointer */ { - IShellView * psf; + IShellView *psf; HRESULT hRes; TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n", - psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback, - psvcbi->fvm, psvcbi->psvOuter); + psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback, + psvcbi->fvm, psvcbi->psvOuter); + *ppv = NULL; hRes = IShellView_Constructor(psvcbi->pshf, &psf); if (FAILED(hRes)) return hRes; - if (!psf) - return E_OUTOFMEMORY; - - psf->AddRef(); hRes = psf->QueryInterface(IID_IShellView, (LPVOID *)ppv); psf->Release(); @@ -1914,25 +1911,24 @@ HRESULT WINAPI SHCreateStdEnumFmtEtc( */ HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv) { - HRESULT ret = S_OK; + IShellView *psf; + HRESULT hRes; - FIXME("SHCreateShellFolderView() stub\n"); + *ppsv = NULL; + if (!pcsfv || pcsfv->cbSize != sizeof(*pcsfv)) + return E_INVALIDARG; - if (!pcsfv || sizeof(*pcsfv) != pcsfv->cbSize) - ret = E_INVALIDARG; - else - { - LPVOID lpdata = 0;/*LocalAlloc(LMEM_ZEROINIT, 0x4E4);*/ + TRACE("sf=%p outer=%p callback=%p\n", + pcsfv->pshf, pcsfv->psvOuter, pcsfv->psfvcb); - if (!lpdata) - ret = E_OUTOFMEMORY; - else - { - /* Initialize and return unknown lpdata structure */ - } - } + hRes = IShellView_Constructor(pcsfv->pshf, &psf); + if (FAILED(hRes)) + return hRes; - return ret; + hRes = psf->QueryInterface(IID_IShellView, (LPVOID *)ppsv); + psf->Release(); + + return hRes; } /************************************************************************* @@ -2113,8 +2109,8 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) if (!(dwFlags & SHERB_NOCONFIRMATION)) { /* FIXME - * enumerate available files - * show confirmation dialog + * enumerate available files + * show confirmation dialog */ FIXME("show confirmation dialog\n"); } @@ -2137,7 +2133,7 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) if (!(dwFlags & SHERB_NOSOUND)) { dwSize = sizeof(szPath); - ret = RegGetValueW(HKEY_CURRENT_USER, + ret = RegGetValueW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\Explorer\\EmptyRecycleBin\\.Current", NULL, RRF_RT_REG_EXPAND_SZ, From 053591f6b4b5288a6d7bbb35303c653538aa0b7d Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 22 Oct 2013 19:09:45 +0000 Subject: [PATCH 34/36] [SHELL32_WINETEST] - Add tests for SHCreateShellFolderView[Ex]. Already applied upstream. CORE-7334 svn path=/trunk/; revision=60732 --- rostests/winetests/shell32/shlfolder.c | 123 +++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/rostests/winetests/shell32/shlfolder.c b/rostests/winetests/shell32/shlfolder.c index ef8aae9cb6b..092f29a2a14 100644 --- a/rostests/winetests/shell32/shlfolder.c +++ b/rostests/winetests/shell32/shlfolder.c @@ -72,6 +72,8 @@ static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static UINT (WINAPI *pGetSystemWow64DirectoryW)(LPWSTR, UINT); static HRESULT (WINAPI *pSHCreateDefaultContextMenu)(const DEFCONTEXTMENU*,REFIID,void**); +static HRESULT (WINAPI *pSHCreateShellFolderView)(const SFV_CREATE *pcsfv, IShellView **ppsv); +static HRESULT (WINAPI *pSHCreateShellFolderViewEx)(LPCSFV psvcbi, IShellView **ppv); static const char *debugstr_guid(REFIID riid) { @@ -140,6 +142,8 @@ static void init_function_pointers(void) MAKEFUNC(SHGetIDListFromObject); MAKEFUNC(SHGetItemFromObject); MAKEFUNC(SHCreateDefaultContextMenu); + MAKEFUNC(SHCreateShellFolderView); + MAKEFUNC(SHCreateShellFolderViewEx); #undef MAKEFUNC #define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord))) @@ -4596,6 +4600,123 @@ static void test_SHCreateDefaultContextMenu(void) Cleanup(); } +static void test_SHCreateShellFolderView(void) +{ + HRESULT hr; + IShellView *psv; + SFV_CREATE sfvc; + IShellFolder *desktop; + ULONG refCount; + + if (!pSHCreateShellFolderView) + { + win_skip("SHCreateShellFolderView missing.\n"); + return; + } + + hr = SHGetDesktopFolder(&desktop); + ok(hr == S_OK, "got (0x%08x)\n", hr); + + if (0) + { + /* crash on win7 */ + pSHCreateShellFolderView(NULL, NULL); + } + + psv = (void *)0xdeadbeef; + hr = pSHCreateShellFolderView(NULL, &psv); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psv == NULL, "psv = %p\n", psv); + + memset(&sfvc, 0, sizeof(sfvc)); + psv = (void *)0xdeadbeef; + hr = pSHCreateShellFolderView(&sfvc, &psv); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psv == NULL, "psv = %p\n", psv); + + memset(&sfvc, 0, sizeof(sfvc)); + sfvc.cbSize = sizeof(sfvc) - 1; + psv = (void *)0xdeadbeef; + hr = pSHCreateShellFolderView(&sfvc, &psv); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psv == NULL, "psv = %p\n", psv); + + memset(&sfvc, 0, sizeof(sfvc)); + sfvc.cbSize = sizeof(sfvc) + 1; + psv = (void *)0xdeadbeef; + hr = pSHCreateShellFolderView(&sfvc, &psv); + ok(hr == E_INVALIDARG, "Got 0x%08x\n", hr); + ok(psv == NULL, "psv = %p\n", psv); + + memset(&sfvc, 0, sizeof(sfvc)); + sfvc.cbSize = sizeof(sfvc); + sfvc.pshf = desktop; + psv = NULL; + hr = pSHCreateShellFolderView(&sfvc, &psv); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(psv != NULL, "psv = %p\n", psv); + if (psv) + { + refCount = IShellView_Release(psv); + ok(refCount == 0, "refCount = %u\n", refCount); + } + + IShellFolder_Release(desktop); +} + +static void test_SHCreateShellFolderViewEx(void) +{ + HRESULT hr; + IShellView *psv; + CSFV csfv; + IShellFolder *desktop; + ULONG refCount; + + if (!pSHCreateShellFolderViewEx) + { + win_skip("SHCreateShellFolderViewEx missing.\n"); + return; + } + + hr = SHGetDesktopFolder(&desktop); + ok(hr == S_OK, "got (0x%08x)\n", hr); + + if (0) + { + /* crash on win7 */ + pSHCreateShellFolderViewEx(NULL, NULL); + pSHCreateShellFolderViewEx(NULL, &psv); + pSHCreateShellFolderViewEx(&csfv, NULL); + } + + memset(&csfv, 0, sizeof(csfv)); + csfv.pshf = desktop; + psv = NULL; + hr = pSHCreateShellFolderViewEx(&csfv, &psv); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(psv != NULL, "psv = %p\n", psv); + if (psv) + { + refCount = IShellView_Release(psv); + ok(refCount == 0, "refCount = %u\n", refCount); + } + + memset(&csfv, 0, sizeof(csfv)); + csfv.cbSize = sizeof(csfv); + csfv.pshf = desktop; + psv = NULL; + hr = pSHCreateShellFolderViewEx(&csfv, &psv); + ok(hr == S_OK, "Got 0x%08x\n", hr); + ok(psv != NULL, "psv = %p\n", psv); + if (psv) + { + refCount = IShellView_Release(psv); + ok(refCount == 0, "refCount = %u\n", refCount); + } + + IShellFolder_Release(desktop); +} + START_TEST(shlfolder) { init_function_pointers(); @@ -4632,6 +4753,8 @@ START_TEST(shlfolder) test_ShellItemBindToHandler(); test_ShellItemGetAttributes(); test_SHCreateDefaultContextMenu(); + test_SHCreateShellFolderView(); + test_SHCreateShellFolderViewEx(); OleUninitialize(); } From 8efecdcf15883e8f32006d257f338db29c801ab0 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Tue, 22 Oct 2013 19:51:25 +0000 Subject: [PATCH 35/36] [EXPLORER] - Remove no longer needed special casing for __MINGW32__. Patch by Ivan Rodionov. CORE-7335 #resolve #comment Thanks! Committed in r60733. svn path=/trunk/; revision=60733 --- reactos/base/shell/explorer/CMakeLists.txt | 1 - reactos/base/shell/explorer/explorer.cpp | 38 ------------- reactos/base/shell/explorer/globals.h | 2 - .../shell/explorer/shell/shellbrowser.cpp | 13 ----- .../base/shell/explorer/shell/shellbrowser.h | 8 +-- .../shell/explorer/taskbar/desktopbar.cpp | 2 - .../base/shell/explorer/taskbar/startmenu.cpp | 54 +------------------ .../base/shell/explorer/taskbar/taskbar.cpp | 4 -- .../shell/explorer/taskbar/traynotify.cpp | 13 ----- .../shell/explorer/utility/shellclasses.cpp | 7 --- .../shell/explorer/utility/shellclasses.h | 4 -- 11 files changed, 3 insertions(+), 143 deletions(-) diff --git a/reactos/base/shell/explorer/CMakeLists.txt b/reactos/base/shell/explorer/CMakeLists.txt index 5a7f9767908..383fa5cb29b 100644 --- a/reactos/base/shell/explorer/CMakeLists.txt +++ b/reactos/base/shell/explorer/CMakeLists.txt @@ -5,7 +5,6 @@ set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL) add_definitions( -DWIN32 - -D__MINGW32__ -D__WINDRES__) #add_pch(explorer precomp.h) diff --git a/reactos/base/shell/explorer/explorer.cpp b/reactos/base/shell/explorer/explorer.cpp index cdeb9aa2fb4..b3de9a9932b 100644 --- a/reactos/base/shell/explorer/explorer.cpp +++ b/reactos/base/shell/explorer/explorer.cpp @@ -69,9 +69,7 @@ ExplorerGlobals::ExplorerGlobals() #endif _log = NULL; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) _SHRestricted = 0; -#endif _hwndDesktopBar = 0; _hwndShellView = 0; _hwndDesktop = 0; @@ -81,11 +79,7 @@ ExplorerGlobals::ExplorerGlobals() void ExplorerGlobals::init(HINSTANCE hInstance) { _hInstance = hInstance; - -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) _SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted"); -#endif - _icon_cache.init(); } @@ -999,38 +993,6 @@ int explorer_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdShow) } - // MinGW does not provide a Unicode startup routine, so we have to implement an own. -#if defined(__MINGW32__) && defined(UNICODE) - -#define _tWinMain wWinMain -int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); - -int main(int argc, char* argv[]) -{ - CONTEXT("main"); - - STARTUPINFO startupinfo; - int nShowCmd = SW_SHOWNORMAL; - - GetStartupInfo(&startupinfo); - - if (startupinfo.dwFlags & STARTF_USESHOWWINDOW) - nShowCmd = startupinfo.wShowWindow; - - LPWSTR cmdline = GetCommandLineW(); - - while(*cmdline && !_istspace((unsigned)*cmdline)) - ++cmdline; - - while(_istspace((unsigned)*cmdline)) - ++cmdline; - - return wWinMain(GetModuleHandle(NULL), 0, cmdline, nShowCmd); -} - -#endif // __MINGW && UNICODE - - static bool SetShellReadyEvent(LPCTSTR evtName) { HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, evtName); diff --git a/reactos/base/shell/explorer/globals.h b/reactos/base/shell/explorer/globals.h index 9afa257a53d..1776c9b8aab 100644 --- a/reactos/base/shell/explorer/globals.h +++ b/reactos/base/shell/explorer/globals.h @@ -279,9 +279,7 @@ extern struct ExplorerGlobals FILE* _log; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) DWORD(STDAPICALLTYPE* _SHRestricted)(RESTRICTIONS); -#endif FileTypeManager _ftype_mgr; IconCache _icon_cache; diff --git a/reactos/base/shell/explorer/shell/shellbrowser.cpp b/reactos/base/shell/explorer/shell/shellbrowser.cpp index 1c74c86393c..50b95a3f655 100644 --- a/reactos/base/shell/explorer/shell/shellbrowser.cpp +++ b/reactos/base/shell/explorer/shell/shellbrowser.cpp @@ -39,11 +39,7 @@ const LPCTSTR C_DRIVE = C_DRIVE_STR; ShellBrowser::ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs) -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) : super(IID_IShellFolderViewCB), -#else - : -#endif _hwnd(hwnd), _hwndFrame(hwndFrame), _left_hwnd(left_hwnd), @@ -449,7 +445,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW; } -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) SFV_CREATE sfv_create; sfv_create.cbSize = sizeof(SFV_CREATE); @@ -458,9 +453,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) sfv_create.psfvcb = this; HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView); -#else - HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView); -#endif if (FAILED(hr)) { _pShellView = NULL; @@ -480,9 +472,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS); } - -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) - /// shell view callback HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -495,8 +484,6 @@ HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, L return E_NOTIMPL; } -#endif - HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida) { diff --git a/reactos/base/shell/explorer/shell/shellbrowser.h b/reactos/base/shell/explorer/shell/shellbrowser.h index be910f1beb5..203b6d2c883 100644 --- a/reactos/base/shell/explorer/shell/shellbrowser.h +++ b/reactos/base/shell/explorer/shell/shellbrowser.h @@ -57,10 +57,8 @@ struct BrowserCallback /// Implementation of IShellBrowserImpl interface in explorer child windows -struct ShellBrowser : public IShellBrowserImpl -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) - , public IComSrvBase, public SimpleComObject -#endif +struct ShellBrowser : public IShellBrowserImpl, + public IComSrvBase, public SimpleComObject { ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs); @@ -168,12 +166,10 @@ protected: void InitializeTree(); bool InitDragDrop(); -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) typedef IComSrvBase super; // IShellFolderViewCB virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam); -#endif map _image_map; diff --git a/reactos/base/shell/explorer/taskbar/desktopbar.cpp b/reactos/base/shell/explorer/taskbar/desktopbar.cpp index 20f58410966..c740ee94363 100644 --- a/reactos/base/shell/explorer/taskbar/desktopbar.cpp +++ b/reactos/base/shell/explorer/taskbar/desktopbar.cpp @@ -114,9 +114,7 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs) // create task bar _hwndTaskBar = TaskBar::Create(_hwnd); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOTRAYITEMSDISPLAY)) -#endif // create tray notification area _hwndNotify = NotifyArea::Create(_hwnd); diff --git a/reactos/base/shell/explorer/taskbar/startmenu.cpp b/reactos/base/shell/explorer/taskbar/startmenu.cpp index 194d4544520..56f51c48e3c 100644 --- a/reactos/base/shell/explorer/taskbar/startmenu.cpp +++ b/reactos/base/shell/explorer/taskbar/startmenu.cpp @@ -1560,9 +1560,7 @@ StartMenuRoot::StartMenuRoot(HWND hwnd, const StartMenuRootCreateInfo& info) : super(hwnd, info._icon_size), _hwndStartButton(0) { -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCOMMONGROUPS)) -#endif try { // insert directory "All Users\Start Menu" ShellDirectory cmn_startmenu(GetDesktopFolder(), SpecialFolderPath(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd); @@ -1706,34 +1704,12 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) AddSeparator(); -#ifdef __MINGW32__ - HKEY hkey, hkeyAdv; - DWORD value, len; - - if (RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"), &hkey)) - hkey = 0; - - if (RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), &hkeyAdv)) - hkeyAdv = 0; - -#define IS_VALUE_ZERO(hk, name) \ - (!hk || (len=sizeof(value),RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE)&value, &len) || !value)) - -#define IS_VALUE_NOT_ZERO(hk, name) \ - (!hk || (len=sizeof(value),RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE)&value, &len) || value>0)) -#endif - - // insert hard coded start entries AddButton(ResString(IDS_PROGRAMS), ICID_APPS, true, IDC_PROGRAMS); AddButton(ResString(IDS_DOCUMENTS), ICID_DOCUMENTS, true, IDC_DOCUMENTS); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORECENTDOCSMENU)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoRecentDocsMenu"))) -#endif AddButton(ResString(IDS_RECENT), ICID_RECENT, true, IDC_RECENT); AddButton(ResString(IDS_FAVORITES), ICID_FAVORITES, true, IDC_FAVORITES); @@ -1742,42 +1718,26 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) AddButton(ResString(IDS_BROWSE), ICID_FOLDER, true, IDC_BROWSE); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOFIND)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoFind"))) -#endif AddButton(ResString(IDS_SEARCH), ICID_SEARCH, true, IDC_SEARCH); AddButton(ResString(IDS_START_HELP), ICID_INFO, false, IDC_START_HELP); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORUN)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoRun"))) -#endif AddButton(ResString(IDS_LAUNCH), ICID_ACTION, false, IDC_LAUNCH); AddSeparator(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || SHRestricted(REST_STARTMENULOGOFF) != 1) -#else - if (IS_VALUE_NOT_ZERO(hkeyAdv, _T("StartMenuLogoff"))) -#endif AddButton(ResString(IDS_LOGOFF), ICID_LOGOFF, false, IDC_LOGOFF); #ifdef __REACTOS__ AddButton(ResString(IDS_RESTART), ICID_RESTART, false, IDC_RESTART); #endif -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCLOSE)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoClose"))) -#endif AddButton(ResString(IDS_SHUTDOWN), ICID_SHUTDOWN, false, IDC_SHUTDOWN); #ifndef __REACTOS__ @@ -1785,10 +1745,6 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) #endif -#ifdef __MINGW32__ - RegCloseKey(hkeyAdv); - RegCloseKey(hkey); -#endif #ifdef _LIGHT_STARTMENU @@ -2205,18 +2161,14 @@ void SettingsMenu::AddEntries() AddButton(ResString(IDS_ADMIN), ICID_ADMIN, true, IDC_ADMIN); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) -#endif - AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU); + AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU); AddButton(ResString(IDS_DESKTOPBAR_SETTINGS), ICID_DESKSETTING, false, ID_DESKTOPBAR_SETTINGS); AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, false, IDC_PRINTERS); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) -#endif AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONTROLPAN, false, IDC_CONTROL_PANEL); } @@ -2224,9 +2176,7 @@ void BrowseMenu::AddEntries() { super::AddEntries(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NONETHOOD)) // or REST_NOENTIRENETWORK ? -#endif #if defined(ROSSHELL) || defined(__REACTOS__) // __REACTOS__ to be removed when printer/network will be implemented AddButton(ResString(IDS_NETWORK), ICID_NETWORK, false, IDC_NETWORK); #else @@ -2242,9 +2192,7 @@ void SearchMenu::AddEntries() AddButton(ResString(IDS_SEARCH_FILES), ICID_SEARCH_DOC, false, IDC_SEARCH_FILES); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_HASFINDCOMPUTERS)) -#endif AddButton(ResString(IDS_SEARCH_COMPUTER),ICID_COMPUTER, false, IDC_SEARCH_COMPUTER); AddButton(ResString(IDS_SEARCH_PRG), ICID_APPS, false, IDC_SEARCH_PROGRAM); diff --git a/reactos/base/shell/explorer/taskbar/taskbar.cpp b/reactos/base/shell/explorer/taskbar/taskbar.cpp index 83c4b14058d..5db82d95b8e 100644 --- a/reactos/base/shell/explorer/taskbar/taskbar.cpp +++ b/reactos/base/shell/explorer/taskbar/taskbar.cpp @@ -133,7 +133,6 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs) //SetWindowFont(_htoolbar, GetStockFont(ANSI_VAR_FONT), FALSE); //SendMessage(_htoolbar, TB_SETPADDING, 0, MAKELPARAM(8,8)); -#ifndef __MINGW32__ // TBMETRICS missing in MinGW (as of 20.09.2005) // set metrics for the Taskbar toolbar to enable button spacing TBMETRICS metrics; @@ -145,7 +144,6 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs) metrics.cyButtonSpacing = 3; SendMessage(_htoolbar, TB_SETMETRICS, 0, (LPARAM)&metrics); -#endif _next_id = IDC_FIRST_APP; @@ -264,11 +262,9 @@ int TaskBar::Notify(int id, NMHDR* pnmh) ActivateApp(it, false, false); // don't restore minimized windows on right button click -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) static DynamicFct pSHRestricted(TEXT("SHELL32"), "SHRestricted"); if (pSHRestricted && !(*pSHRestricted)(REST_NOTRAYCONTEXTMENU)) -#endif ShowAppSystemMenu(it); } break;} diff --git a/reactos/base/shell/explorer/taskbar/traynotify.cpp b/reactos/base/shell/explorer/taskbar/traynotify.cpp index ea0e85a4204..7e2690a9af6 100644 --- a/reactos/base/shell/explorer/taskbar/traynotify.cpp +++ b/reactos/base/shell/explorer/taskbar/traynotify.cpp @@ -133,7 +133,6 @@ bool NotifyInfo::modify(NOTIFYICONDATA* pnid) changes = true; ///@todo compare icon } -#ifdef NIF_STATE // as of 21.08.2003 missing in MinGW headers if (pnid->uFlags & NIF_STATE) { DWORD new_state = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask); @@ -142,7 +141,6 @@ bool NotifyInfo::modify(NOTIFYICONDATA* pnid) changes = true; } } -#endif // store tool tip text if (pnid->uFlags & NIF_TIP) { @@ -252,9 +250,7 @@ void NotifyArea::read_config() // read notification icon settings from XML configuration XMLPos cfg_pos = g_Globals.get_cfg(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK)) -#endif { if (cfg_pos.go_down("desktopbar")) { clock_visible = XMLBoolRef(XMLPos(cfg_pos,"options"), "show-clock", !get_hide_clock_from_registry()); @@ -609,12 +605,10 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni */ bool changes = entry.modify(pnid); -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers if (DetermineHideState(entry) && entry._mode==NIM_HIDE) { entry._dwState |= NIS_HIDDEN; changes = true; } -#endif if (changes) UpdateIcons(); ///@todo call only if really changes occurred @@ -635,7 +629,6 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni } break;} -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers case NIM_SETFOCUS: SetForegroundWindow(_hwnd); return TRUE; @@ -648,7 +641,6 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni return TRUE; } else return FALSE; -#endif } return FALSE; @@ -662,9 +654,7 @@ void NotifyArea::UpdateIcons() for(NotifyIconMap::const_iterator it=_icon_map.begin(); it!=_icon_map.end(); ++it) { const NotifyInfo& entry = it->second; -#ifdef NIF_STATE // as of 21.08.2003 missing in MinGW headers if (_show_hidden || !(entry._dwState & NIS_HIDDEN)) -#endif _sorted_icons.insert(entry); } @@ -830,8 +820,6 @@ void NotifyIconConfig::create_name() } -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers - bool NotifyIconConfig::match(const NotifyIconConfig& props) const { if (!_tipText.empty() && !props._tipText.empty()) @@ -873,7 +861,6 @@ bool NotifyArea::DetermineHideState(NotifyInfo& entry) return false; } -#endif String string_from_mode(NOTIFYICONMODE mode) diff --git a/reactos/base/shell/explorer/utility/shellclasses.cpp b/reactos/base/shell/explorer/utility/shellclasses.cpp index 5f66e2a1380..bbaea385c21 100644 --- a/reactos/base/shell/explorer/utility/shellclasses.cpp +++ b/reactos/base/shell/explorer/utility/shellclasses.cpp @@ -483,20 +483,15 @@ SpecialFolderFSPath::SpecialFolderFSPath(int folder, HWND hwnd) void CtxMenuInterfaces::reset() { _pctxmenu2 = NULL; - -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) _pctxmenu3 = NULL; -#endif } bool CtxMenuInterfaces::HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam) { -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) if (_pctxmenu3) { if (SUCCEEDED(_pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam))) return true; } -#endif if (_pctxmenu2) if (SUCCEEDED(_pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam))) @@ -512,11 +507,9 @@ IContextMenu* CtxMenuInterfaces::query_interfaces(IContextMenu* pcm1) reset(); // Get the higher version context menu interfaces. -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) if (pcm1->QueryInterface(IID_IContextMenu3, (void**)&pcm) == NOERROR) _pctxmenu3 = (LPCONTEXTMENU3)pcm; else -#endif if (pcm1->QueryInterface(IID_IContextMenu2, (void**)&pcm) == NOERROR) _pctxmenu2 = (LPCONTEXTMENU2)pcm; diff --git a/reactos/base/shell/explorer/utility/shellclasses.h b/reactos/base/shell/explorer/utility/shellclasses.h index 3e69dc67383..a46f997bb24 100644 --- a/reactos/base/shell/explorer/utility/shellclasses.h +++ b/reactos/base/shell/explorer/utility/shellclasses.h @@ -1114,9 +1114,7 @@ struct CtxMenuInterfaces IContextMenu2* _pctxmenu2; -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) IContextMenu3* _pctxmenu3; -#endif }; template struct ExtContextMenuHandlerT @@ -1151,7 +1149,6 @@ template struct ExtContextMenuHandlerT break; -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) case WM_MENUCHAR: // only supported by IContextMenu3 if (_cm_ifs._pctxmenu3) { LRESULT lResult = 0; @@ -1162,7 +1159,6 @@ template struct ExtContextMenuHandlerT } return 0; -#endif } return super::WndProc(nmsg, wparam, lparam); From dd2d4349e2144e33d847db6d88985352f2ebdb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Wed, 23 Oct 2013 00:12:17 +0000 Subject: [PATCH 36/36] [CONSRV]: Fix console palette setting. For that, we create a console framebuffer on which we draw the different active screen buffers (be they text or graphics), we can change the palette associated to this framebuffer and then we draw the framebuffer on screen. Console palettes now work !!!!!! @ [TheFlash] Part 2/2 svn path=/trunk/; revision=60734 --- .../win32ss/user/winsrv/consrv/condrv/text.c | 2 + .../win32ss/user/winsrv/consrv/conoutput.h | 4 +- .../winsrv/consrv/frontends/gui/graphics.c | 25 +- .../winsrv/consrv/frontends/gui/guisettings.h | 14 +- .../winsrv/consrv/frontends/gui/guiterm.c | 251 ++++++++---------- .../user/winsrv/consrv/frontends/gui/text.c | 68 ++--- 6 files changed, 179 insertions(+), 185 deletions(-) diff --git a/reactos/win32ss/user/winsrv/consrv/condrv/text.c b/reactos/win32ss/user/winsrv/consrv/condrv/text.c index 074e67d7919..02f7260bdf5 100644 --- a/reactos/win32ss/user/winsrv/consrv/condrv/text.c +++ b/reactos/win32ss/user/winsrv/consrv/condrv/text.c @@ -1340,6 +1340,8 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, Buffer->ViewSize.X = CapturedWindowRect.Right - CapturedWindowRect.Left + 1; Buffer->ViewSize.Y = CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1; + // TermResizeTerminal(Console); + return STATUS_SUCCESS; } diff --git a/reactos/win32ss/user/winsrv/consrv/conoutput.h b/reactos/win32ss/user/winsrv/consrv/conoutput.h index c2e59f8c61c..29da4c4c699 100644 --- a/reactos/win32ss/user/winsrv/consrv/conoutput.h +++ b/reactos/win32ss/user/winsrv/consrv/conoutput.h @@ -40,7 +40,7 @@ NTSTATUS FASTCALL ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, VOID NTAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); // VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); -// PCONSOLE_SCREEN_BUFFER -// ConDrvGetActiveScreenBuffer(IN PCONSOLE Console); +PCONSOLE_SCREEN_BUFFER +ConDrvGetActiveScreenBuffer(IN PCONSOLE Console); /* EOF */ diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/graphics.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/graphics.c index 58267a7c15a..e0fc4f3d4a2 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/graphics.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/graphics.c @@ -46,11 +46,16 @@ GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer) VOID GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc) + PRECT rcView, + PRECT rcFramebuffer) { if (Buffer->BitMap == NULL) return; + rcFramebuffer->left = Buffer->ViewOrigin.X * 1 + rcView->left; + rcFramebuffer->top = Buffer->ViewOrigin.Y * 1 + rcView->top; + rcFramebuffer->right = Buffer->ViewOrigin.X * 1 + rcView->right; + rcFramebuffer->bottom = Buffer->ViewOrigin.Y * 1 + rcView->bottom; + /* Grab the mutex */ NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL); @@ -59,15 +64,15 @@ GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, * the Y-coordinate of the "lower-left corner" of the image, be the DIB * in bottom-up or top-down mode. */ - SetDIBitsToDevice(hDC, - /* Coordinates / size of the repainted rectangle, in the view's frame */ - rc->left, - rc->top, - rc->right - rc->left, - rc->bottom - rc->top, + SetDIBitsToDevice(GuiData->hMemDC, + /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */ + rcFramebuffer->left, + rcFramebuffer->top, + rcFramebuffer->right - rcFramebuffer->left, + rcFramebuffer->bottom - rcFramebuffer->top, /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */ - Buffer->ViewOrigin.X + rc->left, - Buffer->ViewOrigin.Y + rc->top, + rcFramebuffer->left, + rcFramebuffer->top, 0, Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight Buffer->BitMap, diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h index 0c0f0cdf417..9851a36dffe 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h @@ -41,20 +41,22 @@ typedef struct _GUI_CONSOLE_DATA { CRITICAL_SECTION Lock; BOOL WindowSizeLock; - HANDLE hGuiInitEvent; - POINT OldCursor; - HWND hWindow; /* Handle to the console's window */ - HICON hIcon; /* Handle to the console's icon (big) */ - HICON hIconSm; /* Handle to the console's icon (small) */ + POINT OldCursor; LONG_PTR WndStyle; LONG_PTR WndStyleEx; BOOL IsWndMax; WINDOWPLACEMENT WndPl; - HPALETTE hSysPalette; /* Handle to the original system palette */ + HWND hWindow; /* Handle to the console's window */ + HDC hMemDC; /* Memory DC holding the console framebuffer */ + HBITMAP hBitmap; /* Console framebuffer */ + HPALETTE hSysPalette; /* Handle to the original system palette */ + + HICON hIcon; /* Handle to the console's icon (big) */ + HICON hIconSm; /* Handle to the console's icon (small) */ /*** The following may be put per-screen-buffer !! ***/ HCURSOR hCursor; /* Handle to the mouse cursor */ diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index aaf9dc3753a..437e97a14d6 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -250,7 +250,7 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord); static VOID NTAPI GuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region); static VOID -GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData); +GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit); static LRESULT @@ -265,7 +265,6 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM Ret = FALSE; goto Quit; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; /* @@ -412,16 +411,12 @@ GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData) } static VOID -GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData) +GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; SCROLLINFO sInfo; DWORD Width, Height; - UINT WidthUnit, HeightUnit; - - GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); Width = Buff->ViewSize.X * WidthUnit + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); @@ -551,6 +546,11 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) ReleaseDC(GuiData->hWindow, hDC); + /* Initialize the terminal framebuffer */ + GuiData->hMemDC = CreateCompatibleDC(NULL); + GuiData->hBitmap = NULL; + GuiData->hSysPalette = NULL; /* Original system palette */ + // FIXME: Keep these instructions here ? /////////////////////////////////// Console->ActiveBuffer->CursorBlinkOn = TRUE; Console->ActiveBuffer->ForceCursorOff = FALSE; @@ -570,8 +570,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) static VOID SmallRectToRect(PGUI_CONSOLE_DATA GuiData, PRECT Rect, PSMALL_RECT SmallRect) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; UINT WidthUnit, HeightUnit; GetScreenBufferSizeUnits(Buffer, GuiData, &WidthUnit, &HeightUnit); @@ -647,13 +646,13 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord) VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc); + PRECT rcView, + PRECT rcFramebuffer); VOID GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc); + PRECT rcView, + PRECT rcFramebuffer); static VOID GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData) @@ -661,49 +660,54 @@ GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData) BOOL Success = TRUE; PCONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - HDC hDC; PAINTSTRUCT ps; + RECT rcPaint; if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { Success = FALSE; goto Quit; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; - hDC = BeginPaint(GuiData->hWindow, &ps); - if (hDC != NULL && + BeginPaint(GuiData->hWindow, &ps); + if (ps.hdc != NULL && ps.rcPaint.left < ps.rcPaint.right && ps.rcPaint.top < ps.rcPaint.bottom) { EnterCriticalSection(&GuiData->Lock); + /* Compose the current screen-buffer on-memory */ if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) { GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer, - GuiData, hDC, &ps.rcPaint); + GuiData, &ps.rcPaint, &rcPaint); } else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */ { GuiPaintGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)ActiveBuffer, - GuiData, hDC, &ps.rcPaint); + GuiData, &ps.rcPaint, &rcPaint); } + /* Send it to screen */ + BitBlt(ps.hdc, + ps.rcPaint.left, + ps.rcPaint.top, + rcPaint.right - rcPaint.left, + rcPaint.bottom - rcPaint.top, + GuiData->hMemDC, + rcPaint.left, + rcPaint.top, + SRCCOPY); + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - RECT rc; - SmallRectToRect(GuiData, &rc, &Console->Selection.srSelection); + SmallRectToRect(GuiData, &rcPaint, &Console->Selection.srSelection); - /* invert the selection */ - if (IntersectRect(&rc, &ps.rcPaint, &rc)) + /* Invert the selection */ + if (IntersectRect(&rcPaint, &ps.rcPaint, &rcPaint)) { - PatBlt(hDC, - rc.left, - rc.top, - rc.right - rc.left, - rc.bottom - rc.top, - DSTINVERT); + InvertRect(ps.hdc, &rcPaint); } } @@ -751,7 +755,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) @@ -924,14 +927,15 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + Buff = GuiData->ActiveBuffer; if (GetType(Buff) == TEXTMODE_BUFFER) { GuiInvalidateCell(&Console->TermIFace, Buff->CursorPosition.X, Buff->CursorPosition.Y); Buff->CursorBlinkOn = !Buff->CursorBlinkOn; - if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y)) + if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || + (GuiData->OldCursor.y != Buff->CursorPosition.Y)) { SCROLLINFO xScroll; int OldScrollX = -1, OldScrollY = -1; @@ -946,11 +950,14 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) // If we successfully got the info for the horizontal scrollbar if (OldScrollX >= 0) { - if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) || (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X))) + if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) || + (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X))) { // Handle the horizontal scroll bar - if (Buff->CursorPosition.X >= Buff->ViewSize.X) NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1; - else NewScrollX = 0; + if (Buff->CursorPosition.X >= Buff->ViewSize.X) + NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1; + else + NewScrollX = 0; } else { @@ -960,11 +967,14 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) // If we successfully got the info for the vertical scrollbar if (OldScrollY >= 0) { - if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) || (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y))) + if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) || + (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y))) { // Handle the vertical scroll bar - if (Buff->CursorPosition.Y >= Buff->ViewSize.Y) NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1; - else NewScrollY = 0; + if (Buff->CursorPosition.Y >= Buff->ViewSize.Y) + NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1; + else + NewScrollY = 0; } else { @@ -999,6 +1009,7 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) SetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll, TRUE); } UpdateWindow(GuiData->hWindow); + // InvalidateRect(GuiData->hWindow, NULL, FALSE); GuiData->OldCursor.x = Buff->CursorPosition.X; GuiData->OldCursor.y = Buff->CursorPosition.Y; } @@ -1035,9 +1046,20 @@ GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData) static LRESULT GuiConsoleHandleNcDestroy(HWND hWnd) { + PGUI_CONSOLE_DATA GuiData = GuiGetGuiData(hWnd); + KillTimer(hWnd, CONGUI_UPDATE_TIMER); GetSystemMenu(hWnd, TRUE); + if (GuiData) + { + /* Free the terminal framebuffer */ + if (GuiData->hMemDC ) DeleteDC(GuiData->hMemDC); + if (GuiData->hBitmap) DeleteObject(GuiData->hBitmap); + // if (GuiData->hSysPalette) DeleteObject(GuiData->hSysPalette); + if (GuiData->Font) DeleteObject(GuiData->Font); + } + /* Free the GuiData registration */ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)NULL); @@ -1047,8 +1069,7 @@ GuiConsoleHandleNcDestroy(HWND hWnd) static COORD PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; COORD Coord; UINT WidthUnit, HeightUnit; @@ -1327,7 +1348,7 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData) if (OpenClipboard(GuiData->hWindow) == TRUE) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1354,8 +1375,7 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData) { if (OpenClipboard(GuiData->hWindow) == TRUE) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1380,7 +1400,6 @@ GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); @@ -1413,7 +1432,7 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam) if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) { - PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; DWORD windx, windy, charx, chary; UINT WidthUnit, HeightUnit; @@ -1453,7 +1472,7 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam) Buff->ViewSize.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y; } - GuiConsoleResizeWindow(GuiData); + GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit); // Adjust the start of the visible area if we are attempting to show nonexistent areas if ((Buff->ScreenBufferSize.X - Buff->ViewOrigin.X) < Buff->ViewSize.X) Buff->ViewOrigin.X = Buff->ScreenBufferSize.X - Buff->ViewSize.X; @@ -1507,7 +1526,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + Buff = GuiData->ActiveBuffer; if (uMsg == WM_HSCROLL) { @@ -1595,6 +1614,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) SetScrollInfo(GuiData->hWindow, fnBar, &sInfo, TRUE); UpdateWindow(GuiData->hWindow); + // InvalidateRect(GuiData->hWindow, NULL, FALSE); } Quit: @@ -1697,7 +1717,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_PALETTECHANGED: { - PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); + PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; DPRINT1("WM_PALETTECHANGED called\n"); @@ -1721,19 +1741,13 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) if (ActiveBuffer->PaletteHandle) { - /* Get the Device Context of the console window */ - HDC hDC = GetDC(GuiData->hWindow); - DPRINT1("WM_PALETTECHANGED changing palette\n"); - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - /* Release the Device Context and return */ - ReleaseDC(GuiData->hWindow, hDC); + RealizePalette(GuiData->hMemDC); } DPRINT1("WM_PALETTECHANGED quit\n"); @@ -1966,9 +1980,32 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case PM_RESIZE_TERMINAL: { + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; + HDC hDC; + HBITMAP hnew, hold; + + DWORD Width, Height; + UINT WidthUnit, HeightUnit; + + GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); + + Width = Buff->ScreenBufferSize.X * WidthUnit ; + Height = Buff->ScreenBufferSize.Y * HeightUnit; + + /* Recreate the framebuffer */ + hDC = GetDC(GuiData->hWindow); + hnew = CreateCompatibleBitmap(hDC, Width, Height); + ReleaseDC(GuiData->hWindow, hDC); + hold = SelectObject(GuiData->hMemDC, hnew); + if (GuiData->hBitmap) + { + if (hold == GuiData->hBitmap) DeleteObject(GuiData->hBitmap); + } + GuiData->hBitmap = hnew; + /* Resize the window to the user's values */ GuiData->WindowSizeLock = TRUE; - GuiConsoleResizeWindow(GuiData); + GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit); GuiData->WindowSizeLock = FALSE; break; } @@ -2063,9 +2100,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Move and resize the window to the user's values */ /* CAN WE DEADLOCK ?? */ GuiConsoleMoveWindow(GuiData); - GuiData->WindowSizeLock = TRUE; - GuiConsoleResizeWindow(GuiData); - GuiData->WindowSizeLock = FALSE; + SendMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0); /* Switch to full-screen mode if necessary */ if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE); @@ -2423,9 +2458,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This, } } - /* Original system palette */ - GuiData->hSysPalette = NULL; - /* Mouse is shown by default with its default cursor shape */ GuiData->hCursor = ghDefaultCursor; GuiData->MouseCursorRefCount = 0; @@ -2511,6 +2543,7 @@ GuiDrawRegion(IN OUT PFRONTEND This, SmallRectToRect(GuiData, &RegionRect, Region); /* Do not erase the background: it speeds up redrawing and reduce flickering */ InvalidateRect(GuiData->hWindow, &RegionRect, FALSE); + /**UpdateWindow(GuiData->hWindow);**/ } static VOID NTAPI @@ -2529,7 +2562,7 @@ GuiWriteStream(IN OUT PFRONTEND This, if (NULL == GuiData || NULL == GuiData->hWindow) return; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); + Buff = GuiData->ActiveBuffer; if (GetType(Buff) != TEXTMODE_BUFFER) return; if (0 != ScrolledLines) @@ -2578,7 +2611,7 @@ GuiSetCursorInfo(IN OUT PFRONTEND This, { PGUI_CONSOLE_DATA GuiData = This->Data; - if (/*ConDrvGetActiveScreenBuffer(GuiData->Console)*/GuiData->ActiveBuffer == Buff) + if (GuiData->ActiveBuffer == Buff) { GuiInvalidateCell(This, Buff->CursorPosition.X, Buff->CursorPosition.Y); } @@ -2594,7 +2627,7 @@ GuiSetScreenInfo(IN OUT PFRONTEND This, { PGUI_CONSOLE_DATA GuiData = This->Data; - if (/*ConDrvGetActiveScreenBuffer(GuiData->Console)*/GuiData->ActiveBuffer == Buff) + if (GuiData->ActiveBuffer == Buff) { /* Redraw char at old position (remove cursor) */ GuiInvalidateCell(This, OldCursorX, OldCursorY); @@ -2611,11 +2644,6 @@ GuiResizeTerminal(IN OUT PFRONTEND This) PGUI_CONSOLE_DATA GuiData = This->Data; /* Resize the window to the user's values */ - // GuiData->WindowSizeLock = TRUE; - // GuiConsoleResizeWindow(GuiData); - // GuiData->WindowSizeLock = FALSE; - // NOTE: This code ^^ causes deadlocks... - PostMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0); } @@ -2623,15 +2651,14 @@ static VOID NTAPI GuiSetActiveScreenBuffer(IN OUT PFRONTEND This) { PGUI_CONSOLE_DATA GuiData = This->Data; - PCONSOLE_SCREEN_BUFFER ActiveBuffer; // = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); - HDC hDC; + PCONSOLE_SCREEN_BUFFER ActiveBuffer; HPALETTE hPalette; EnterCriticalSection(&GuiData->Lock); GuiData->WindowSizeLock = TRUE; InterlockedExchangePointer(&GuiData->ActiveBuffer, - GuiData->Console->ActiveBuffer); + ConDrvGetActiveScreenBuffer(GuiData->Console)); GuiData->WindowSizeLock = FALSE; LeaveCriticalSection(&GuiData->Lock); @@ -2650,20 +2677,14 @@ GuiSetActiveScreenBuffer(IN OUT PFRONTEND This) DPRINT1("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette); - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); + /* Set the new palette for the framebuffer */ + SelectPalette(GuiData->hMemDC, hPalette, FALSE); - /* Set the new palette */ - SelectPalette(hDC, hPalette, FALSE); - - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - /* Release the Device Context */ - ReleaseDC(GuiData->hWindow, hDC); + RealizePalette(GuiData->hMemDC); GuiResizeTerminal(This); // ConioDrawConsole(Console); @@ -2674,7 +2695,6 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This, IN PCONSOLE_SCREEN_BUFFER ScreenBuffer) { PGUI_CONSOLE_DATA GuiData = This->Data; - HDC hDC; /* * If we were notified to release a screen buffer that is not actually @@ -2690,19 +2710,13 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This, * it ONLY. */ - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); - /* Release the old active palette and set the default one */ - if (GetCurrentObject(hDC, OBJ_PAL) == ScreenBuffer->PaletteHandle) + if (GetCurrentObject(GuiData->hMemDC, OBJ_PAL) == ScreenBuffer->PaletteHandle) { /* Set the new palette */ - SelectPalette(hDC, GuiData->hSysPalette, FALSE); + SelectPalette(GuiData->hMemDC, GuiData->hSysPalette, FALSE); } - /* Release the Device Context */ - ReleaseDC(GuiData->hWindow, hDC); - /* Set the adequate active screen buffer */ if (ScreenBuffer != GuiData->Console->ActiveBuffer) { @@ -2842,7 +2856,6 @@ GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, return; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(GuiData->Console); ActiveBuffer = GuiData->ActiveBuffer; if (ActiveBuffer) { @@ -2873,54 +2886,26 @@ GuiSetPalette(IN OUT PFRONTEND This, HPALETTE PaletteHandle, UINT PaletteUsage) { - BOOL Success = TRUE; PGUI_CONSOLE_DATA GuiData = This->Data; - // PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); - HDC hDC; HPALETTE OldPalette; - DPRINT1("GuiSetPalette checkpt 0\n"); - - // if (GetType(ActiveBuffer) != GRAPHICS_BUFFER) return FALSE; + // if (GetType(GuiData->ActiveBuffer) != GRAPHICS_BUFFER) return FALSE; if (PaletteHandle == NULL) return FALSE; - DPRINT1("GuiSetPalette checkpt 1\n"); + /* Set the new palette for the framebuffer */ + OldPalette = SelectPalette(GuiData->hMemDC, PaletteHandle, FALSE); + if (OldPalette == NULL) return FALSE; - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); - - DPRINT1("GuiSetPalette calling SelectPalette(0x%p, 0x%p, FALSE)\n", hDC, PaletteHandle); - - /* Set the new palette */ - OldPalette = SelectPalette(hDC, PaletteHandle, FALSE); - DPRINT1("OldPalette = 0x%p\n", OldPalette); - if (OldPalette == NULL) - { - DPRINT1("SelectPalette failed\n"); - Success = FALSE; - goto Quit; - } - - DPRINT1("GuiSetPalette checkpt 2\n"); - - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - DPRINT1("GuiData->hSysPalette before == 0x%p\n", GuiData->hSysPalette); + RealizePalette(GuiData->hMemDC); /* Save the original system palette handle */ if (GuiData->hSysPalette == NULL) GuiData->hSysPalette = OldPalette; - DPRINT1("GuiData->hSysPalette after == 0x%p\n", GuiData->hSysPalette); - -Quit: - DPRINT1("GuiSetPalette Quit\n"); - /* Release the Device Context and return */ - ReleaseDC(GuiData->hWindow, hDC); - return Success; + return TRUE; } static ULONG NTAPI diff --git a/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c b/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c index 38bc4413063..313e50c493b 100644 --- a/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/reactos/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -185,8 +185,8 @@ GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer) VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc) + PRECT rcView, + PRECT rcFramebuffer) { PCONSOLE Console = Buffer->Header.Console; // ASSERT(Console == GuiData->Console); @@ -202,20 +202,25 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, if (Buffer->Buffer == NULL) return; - TopLine = rc->top / GuiData->CharHeight + Buffer->ViewOrigin.Y; - BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y; - LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X; - RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buffer->ViewOrigin.X; + rcFramebuffer->left = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->left; + rcFramebuffer->top = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->top; + rcFramebuffer->right = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->right; + rcFramebuffer->bottom = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->bottom; + + LeftChar = rcFramebuffer->left / GuiData->CharWidth; + TopLine = rcFramebuffer->top / GuiData->CharHeight; + RightChar = rcFramebuffer->right / GuiData->CharWidth; + BottomLine = rcFramebuffer->bottom / GuiData->CharHeight; + + if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; + if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes; - SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); - SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); + SetTextColor(GuiData->hMemDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); + SetBkColor(GuiData->hMemDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); - if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; - if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; - - OldFont = SelectObject(hDC, GuiData->Font); + OldFont = SelectObject(GuiData->hMemDC, GuiData->Font); for (Line = TopLine; Line <= BottomLine; Line++) { @@ -232,9 +237,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, */ if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { - TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + TextOutW(GuiData->hMemDC, + Start * GuiData->CharWidth, + Line * GuiData->CharHeight, LineBuffer, Char - Start); Start = Char; @@ -242,8 +247,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, Attribute = From->Attributes; if (Attribute != LastAttribute) { - SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); - SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); + SetTextColor(GuiData->hMemDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); + SetBkColor(GuiData->hMemDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); LastAttribute = Attribute; } } @@ -251,9 +256,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, *(To++) = (From++)->Char.UnicodeChar; } - TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + TextOutW(GuiData->hMemDC, + Start * GuiData->CharWidth, + Line * GuiData->CharHeight, LineBuffer, RightChar - Start + 1); } @@ -271,30 +276,25 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); + Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes; + if (Attribute == DEFAULT_SCREEN_ATTRIB) Attribute = Buffer->ScreenDefaultAttrib; - if (Attribute != DEFAULT_SCREEN_ATTRIB) - { - CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); - } - else - { - CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Buffer->ScreenDefaultAttrib)); - } + CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); + OldBrush = SelectObject(GuiData->hMemDC, CursorBrush); - OldBrush = SelectObject(hDC, CursorBrush); - PatBlt(hDC, - (CursorX - Buffer->ViewOrigin.X) * GuiData->CharWidth, - (CursorY - Buffer->ViewOrigin.Y) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), + PatBlt(GuiData->hMemDC, + CursorX * GuiData->CharWidth, + CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), GuiData->CharWidth, CursorHeight, PATCOPY); - SelectObject(hDC, OldBrush); + SelectObject(GuiData->hMemDC, OldBrush); DeleteObject(CursorBrush); } } - SelectObject(hDC, OldFont); + SelectObject(GuiData->hMemDC, OldFont); } /* EOF */