ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
January 2014
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
14 participants
426 discussions
Start a n
N
ew thread
[jgardou] 61545: [MESA] - Use PSEH to test and catch SSE exceptions #CORE-7727 Problem with software implementation is fixed with r61545. Investigating on vmware driver support.
by jgardou@svn.reactos.org
Author: jgardou Date: Mon Jan 6 18:39:42 2014 New Revision: 61545 URL:
http://svn.reactos.org/svn/reactos?rev=61545&view=rev
Log: [MESA] - Use PSEH to test and catch SSE exceptions #CORE-7727 Problem with software implementation is fixed with r61545. Investigating on vmware driver support. Modified: trunk/reactos/dll/opengl/mesa/x86/common_x86.c Modified: trunk/reactos/dll/opengl/mesa/x86/common_x86.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/opengl/mesa/x86/common…
============================================================================== --- trunk/reactos/dll/opengl/mesa/x86/common_x86.c [iso-8859-1] (original) +++ trunk/reactos/dll/opengl/mesa/x86/common_x86.c [iso-8859-1] Mon Jan 6 18:39:42 2014 @@ -51,6 +51,8 @@ #include "main/imports.h" #include "common_x86_asm.h" +#include <pseh/pseh2.h> + /** Bitmask of X86_FEATURE_x bits */ int _mesa_x86_cpu_features = 0x0; @@ -80,37 +82,6 @@ /* These are assembly functions: */ extern void _mesa_test_os_sse_support( void ); extern void _mesa_test_os_sse_exception_support( void ); - - -#if defined(WIN32) -#ifndef STATUS_FLOAT_MULTIPLE_TRAPS -# define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) -#endif -static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) -{ - PEXCEPTION_RECORD rec = exp->ExceptionRecord; - PCONTEXT ctx = exp->ContextRecord; - - if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) { - _mesa_debug(NULL, "EXCEPTION_ILLEGAL_INSTRUCTION\n" ); - _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); - } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) { - _mesa_debug(NULL, "STATUS_FLOAT_MULTIPLE_TRAPS\n"); - /* Windows seems to clear the exception flag itself, we just have to increment Eip */ - } else { - _mesa_debug(NULL, "UNEXPECTED EXCEPTION (0x%08x), terminating!\n" ); - return EXCEPTION_EXECUTE_HANDLER; - } - - if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) { - _mesa_debug(NULL, "Context does not contain control registers, terminating!\n"); - return EXCEPTION_EXECUTE_HANDLER; - } - ctx->Eip += 3; - - return EXCEPTION_CONTINUE_EXECUTION; -} -#endif /* WIN32 */ /** @@ -150,43 +121,53 @@ _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); } #elif defined(WIN32) - LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; - - /* Install our ExceptionFilter */ - oldFilter = SetUnhandledExceptionFilter( ExceptionFilter ); - - if ( cpu_has_xmm ) { - _mesa_debug(NULL, "Testing OS support for SSE...\n"); - - _mesa_test_os_sse_support(); - - if ( cpu_has_xmm ) { - _mesa_debug(NULL, "Yes.\n"); - } else { - _mesa_debug(NULL, "No!\n"); - } - } - - if ( cpu_has_xmm ) { - _mesa_debug(NULL, "Testing OS support for SSE unmasked exceptions...\n"); - - _mesa_test_os_sse_exception_support(); - - if ( cpu_has_xmm ) { - _mesa_debug(NULL, "Yes.\n"); - } else { - _mesa_debug(NULL, "No!\n"); - } - } - - /* Restore previous exception filter */ - SetUnhandledExceptionFilter( oldFilter ); - - if ( cpu_has_xmm ) { - _mesa_debug(NULL, "Tests of OS support for SSE passed.\n"); - } else { - _mesa_debug(NULL, "Tests of OS support for SSE failed!\n"); - } + if ( cpu_has_xmm ) { + _mesa_debug(NULL, "Testing OS support for SSE...\n"); + + _SEH2_TRY + { + _mesa_test_os_sse_support(); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + if(_SEH2_GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) + _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); + } + _SEH2_END; + + if ( cpu_has_xmm ) { + _mesa_debug(NULL, "Yes.\n"); + } else { + _mesa_debug(NULL, "No!\n"); + } + } + + if ( cpu_has_xmm ) { + _mesa_debug(NULL, "Testing OS support for SSE unmasked exceptions...\n"); + + _SEH2_TRY + { + _mesa_test_os_sse_exception_support(); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + if(_SEH2_GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) + _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); + } + _SEH2_END; + + if ( cpu_has_xmm ) { + _mesa_debug(NULL, "Yes.\n"); + } else { + _mesa_debug(NULL, "No!\n"); + } + } + + if ( cpu_has_xmm ) { + _mesa_debug(NULL, "Tests of OS support for SSE passed.\n"); + } else { + _mesa_debug(NULL, "Tests of OS support for SSE failed!\n"); + } #else /* Do nothing on other platforms for now. */
10 years, 11 months
1
0
0
0
[hbelusca] 61544: [NTVDM] Fix few problems in BiosCopyTextConsoleToVgaMemory (copied screen region and temp buffer freeing).
by hbelusca@svn.reactos.org
Author: hbelusca Date: Mon Jan 6 00:17:59 2014 New Revision: 61544 URL:
http://svn.reactos.org/svn/reactos?rev=61544&view=rev
Log: [NTVDM] Fix few problems in BiosCopyTextConsoleToVgaMemory (copied screen region and temp buffer freeing). Modified: branches/ntvdm/subsystems/ntvdm/bios.c Modified: branches/ntvdm/subsystems/ntvdm/bios.c URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Mon Jan 6 00:17:59 2014 @@ -797,12 +797,12 @@ return TRUE; } -static VOID BiosCopyTextConsoleToVgaMemory(VOID) +static VOID BiosCopyTextConsoleToVgaMemory(PCOORD ConsoleSize) { PCHAR_INFO CharBuffer; COORD BufferSize = {Bda->ScreenColumns, Bda->ScreenRows + 1}; COORD Origin = { 0, 0 }; - SMALL_RECT ScreenRect; + SMALL_RECT ConRect; INT i, j; INT Counter = 0; @@ -816,16 +816,17 @@ * sizeof(CHAR_INFO)); if (CharBuffer == NULL) return; - ScreenRect.Left = ScreenRect.Top = 0; - ScreenRect.Right = BufferSize.X; - ScreenRect.Bottom = BufferSize.Y; + ConRect.Left = 0; + ConRect.Top = ConsoleSize->Y - BufferSize.Y; + ConRect.Right = ConRect.Left + BufferSize.X - 1; + ConRect.Bottom = ConRect.Top + BufferSize.Y - 1; /* Read the data from the console into the temporary buffer... */ ReadConsoleOutputA(BiosConsoleOutput, CharBuffer, BufferSize, Origin, - &ScreenRect); + &ConRect); /* ... and copy the temporary buffer into the VGA memory */ for (i = 0; i < BufferSize.Y; i++) @@ -842,6 +843,9 @@ sizeof(WORD)); } } + + /* Free the temporary buffer */ + HeapFree(GetProcessHeap(), 0, CharBuffer); } static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers) @@ -1910,11 +1914,12 @@ /* Set the default video mode */ BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE); + GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo); + /* Copy console data into VGA memory */ - BiosCopyTextConsoleToVgaMemory(); + BiosCopyTextConsoleToVgaMemory(&ConsoleInfo.dwSize); /* Update the cursor position for the current page */ - GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo); BiosSetCursorPosition(ConsoleInfo.dwCursorPosition.Y, ConsoleInfo.dwCursorPosition.X, Bda->VideoPage); @@ -1968,8 +1973,8 @@ // ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1); // ConRect.Top *= (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1); ConRect.Top = ConsoleInfo.dwCursorPosition.Y; - ConRect.Right = ConRect.Left + BiosSavedBufferInfo.srWindow.Right - BiosSavedBufferInfo.srWindow.Left; - ConRect.Bottom = ConRect.Top + (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top); + ConRect.Right = ConRect.Left + BiosSavedBufferInfo.srWindow.Right - BiosSavedBufferInfo.srWindow.Left; + ConRect.Bottom = ConRect.Top + BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top ; /* See the following trick explanation in vga.c:VgaEnterTextMode() */ SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize); SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &ConRect);
10 years, 11 months
1
0
0
0
[hbelusca] 61543: [NTVDM] Save console in/out modes and cursor shape, and restore them at cleanup.
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Jan 5 22:21:57 2014 New Revision: 61543 URL:
http://svn.reactos.org/svn/reactos?rev=61543&view=rev
Log: [NTVDM] Save console in/out modes and cursor shape, and restore them at cleanup. Modified: branches/ntvdm/subsystems/ntvdm/bios.c Modified: branches/ntvdm/subsystems/ntvdm/bios.c URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Sun Jan 5 22:21:57 2014 @@ -37,6 +37,8 @@ static BYTE BiosKeyboardMap[256]; static HANDLE BiosConsoleInput = INVALID_HANDLE_VALUE; static HANDLE BiosConsoleOutput = INVALID_HANDLE_VALUE; +static DWORD BiosSavedConInMode, BiosSavedConOutMode; +static CONSOLE_CURSOR_INFO BiosSavedCursorInfo; static CONSOLE_SCREEN_BUFFER_INFO BiosSavedBufferInfo; /* @@ -1879,29 +1881,39 @@ return FALSE; } - /* Save the original console screen buffer information */ - if (!GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo)) + /* Save the original input and output console modes */ + if (!GetConsoleMode(BiosConsoleInput , &BiosSavedConInMode ) || + !GetConsoleMode(BiosConsoleOutput, &BiosSavedConOutMode)) { CloseHandle(BiosConsoleOutput); CloseHandle(BiosConsoleInput); return FALSE; } - /* Initialize VGA */ - if (!VgaInitialize(BiosConsoleOutput)) + /* Save the original cursor and console screen buffer information */ + if (!GetConsoleCursorInfo(BiosConsoleOutput, &BiosSavedCursorInfo) || + !GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo)) { CloseHandle(BiosConsoleOutput); CloseHandle(BiosConsoleInput); return FALSE; } + /* Initialize VGA */ + if (!VgaInitialize(BiosConsoleOutput)) + { + CloseHandle(BiosConsoleOutput); + CloseHandle(BiosConsoleInput); + return FALSE; + } + /* Set the default video mode */ BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE); /* Copy console data into VGA memory */ BiosCopyTextConsoleToVgaMemory(); - /* Update the cursor position for the current page (page 0) */ + /* Update the cursor position for the current page */ GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo); BiosSetCursorPosition(ConsoleInfo.dwCursorPosition.Y, ConsoleInfo.dwCursorPosition.X, @@ -1963,6 +1975,13 @@ SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &ConRect); // SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &BiosSavedBufferInfo.srWindow); SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize); + + /* Restore the original cursor shape */ + SetConsoleCursorInfo(BiosConsoleOutput, &BiosSavedCursorInfo); + + /* Restore the original input and output console modes */ + SetConsoleMode(BiosConsoleOutput, BiosSavedConOutMode); + SetConsoleMode(BiosConsoleInput , BiosSavedConInMode ); /* Close the console handles */ if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput);
10 years, 11 months
1
0
0
0
[hbelusca] 61542: [NTVDM] - Move console text buffer copy into VGA memory, to the BIOS (function BiosCopyTextConsoleToVgaMemory), and do it just after the BIOS sets its default display mode. - Try ...
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Jan 5 21:26:33 2014 New Revision: 61542 URL:
http://svn.reactos.org/svn/reactos?rev=61542&view=rev
Log: [NTVDM] - Move console text buffer copy into VGA memory, to the BIOS (function BiosCopyTextConsoleToVgaMemory), and do it just after the BIOS sets its default display mode. - Try to resize "correctly" the console to its original size when cleaning BIOS (Part 2/2, see revision 61538). Still WIP. - Code cleaning in vga.c Modified: branches/ntvdm/subsystems/ntvdm/bios.c branches/ntvdm/subsystems/ntvdm/bios.h branches/ntvdm/subsystems/ntvdm/vga.c Modified: branches/ntvdm/subsystems/ntvdm/bios.c URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Sun Jan 5 21:26:33 2014 @@ -264,9 +264,9 @@ &VideoMode_40x25_text, /* Mode 01h */ // 16 color &VideoMode_80x25_text, /* Mode 02h */ // 16 color (mono) &VideoMode_80x25_text, /* Mode 03h */ // 16 color - &VideoMode_320x200_4color, /* Mode 04h */ // 4 color - &VideoMode_320x200_4color, /* Mode 05h */ // same (m) - &VideoMode_640x200_2color, /* Mode 06h */ // 640*200 2 color + &VideoMode_320x200_4color, /* Mode 04h */ // CGA 4 color + &VideoMode_320x200_4color, /* Mode 05h */ // CGA same (m) + &VideoMode_640x200_2color, /* Mode 06h */ // CGA 640*200 2 color NULL, /* Mode 07h */ // MDA monochrome text 80*25 NULL, /* Mode 08h */ // PCjr NULL, /* Mode 09h */ // PCjr @@ -710,6 +710,138 @@ } } +static BOOLEAN BiosScrollWindow(INT Direction, + DWORD Amount, + SMALL_RECT Rectangle, + BYTE Page, + BYTE FillAttribute) +{ + DWORD i; + LPWORD WindowData; + WORD WindowWidth = Rectangle.Right - Rectangle.Left + 1; + WORD WindowHeight = Rectangle.Bottom - Rectangle.Top + 1; + DWORD WindowSize = WindowWidth * WindowHeight; + + /* Allocate a buffer for the window */ + WindowData = (LPWORD)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + WindowSize * sizeof(WORD)); + if (WindowData == NULL) return FALSE; + + /* Read the window data */ + BiosReadWindow(WindowData, Rectangle, Page); + + if ((Amount == 0) + || (((Direction == SCROLL_DIRECTION_UP) + || (Direction == SCROLL_DIRECTION_DOWN)) + && (Amount >= WindowHeight)) + || (((Direction == SCROLL_DIRECTION_LEFT) + || (Direction == SCROLL_DIRECTION_RIGHT)) + && (Amount >= WindowWidth))) + { + /* Fill the window */ + for (i = 0; i < WindowSize; i++) + { + WindowData[i] = MAKEWORD(' ', FillAttribute); + } + + goto Done; + } + + switch (Direction) + { + case SCROLL_DIRECTION_UP: + { + RtlMoveMemory(WindowData, + &WindowData[WindowWidth * Amount], + (WindowSize - WindowWidth * Amount) * sizeof(WORD)); + + for (i = 0; i < Amount * WindowWidth; i++) + { + WindowData[WindowSize - i - 1] = MAKEWORD(' ', FillAttribute); + } + + break; + } + + case SCROLL_DIRECTION_DOWN: + { + RtlMoveMemory(&WindowData[WindowWidth * Amount], + WindowData, + (WindowSize - WindowWidth * Amount) * sizeof(WORD)); + + for (i = 0; i < Amount * WindowWidth; i++) + { + WindowData[i] = MAKEWORD(' ', FillAttribute); + } + + break; + } + + default: + { + // TODO: NOT IMPLEMENTED! + UNIMPLEMENTED; + } + } + +Done: + /* Write back the window data */ + BiosWriteWindow(WindowData, Rectangle, Page); + + /* Free the window buffer */ + HeapFree(GetProcessHeap(), 0, WindowData); + + return TRUE; +} + +static VOID BiosCopyTextConsoleToVgaMemory(VOID) +{ + PCHAR_INFO CharBuffer; + COORD BufferSize = {Bda->ScreenColumns, Bda->ScreenRows + 1}; + COORD Origin = { 0, 0 }; + SMALL_RECT ScreenRect; + + INT i, j; + INT Counter = 0; + WORD Character; + DWORD VideoAddress = TO_LINEAR(TEXT_VIDEO_SEG, Bda->VideoPage * Bda->VideoPageSize); + + /* Allocate a temporary buffer for ReadConsoleOutput */ + CharBuffer = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + BufferSize.X * BufferSize.Y + * sizeof(CHAR_INFO)); + if (CharBuffer == NULL) return; + + ScreenRect.Left = ScreenRect.Top = 0; + ScreenRect.Right = BufferSize.X; + ScreenRect.Bottom = BufferSize.Y; + + /* Read the data from the console into the temporary buffer... */ + ReadConsoleOutputA(BiosConsoleOutput, + CharBuffer, + BufferSize, + Origin, + &ScreenRect); + + /* ... and copy the temporary buffer into the VGA memory */ + for (i = 0; i < BufferSize.Y; i++) + { + for (j = 0; j < BufferSize.X; j++) + { + Character = MAKEWORD(CharBuffer[Counter].Char.AsciiChar, + (BYTE)CharBuffer[Counter].Attributes); + ++Counter; + + /* Write to video memory */ + VgaWriteMemory(VideoAddress + (i * Bda->ScreenColumns + j) * sizeof(WORD), + (LPVOID)&Character, + sizeof(WORD)); + } + } +} + static BOOLEAN VgaSetRegisters(PVGA_REGISTERS Registers) { INT i; @@ -850,14 +982,43 @@ VgaSetPalette(Palette, Size); } -/* PUBLIC FUNCTIONS ***********************************************************/ +static VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page) +{ + /* Make sure the selected video page is valid */ + if (Page >= BIOS_MAX_PAGES) return; + + /* Get the cursor location */ + *Row = HIBYTE(Bda->CursorPosition[Page]); + *Column = LOBYTE(Bda->CursorPosition[Page]); +} + +static VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page) +{ + /* Make sure the selected video page is valid */ + if (Page >= BIOS_MAX_PAGES) return; + + /* Update the position in the BDA */ + Bda->CursorPosition[Page] = MAKEWORD(Column, Row); + + /* Check if this is the current video page */ + if (Page == Bda->VideoPage) + { + WORD Offset = Row * Bda->ScreenColumns + Column; + + /* Modify the CRTC registers */ + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG); + VgaWritePort(VGA_CRTC_DATA , LOBYTE(Offset)); + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG); + VgaWritePort(VGA_CRTC_DATA , HIBYTE(Offset)); + } +} BYTE BiosGetVideoMode(VOID) { return Bda->VideoMode; } -BOOLEAN BiosSetVideoMode(BYTE ModeNumber) +static BOOLEAN BiosSetVideoMode(BYTE ModeNumber) { BYTE Page; @@ -869,6 +1030,14 @@ if (!VgaSetRegisters(VgaMode)) return FALSE; VgaChangePalette(ModeNumber); + + /* + * IBM standard modes do not clear the screen if the + * high bit of AL is set (EGA or higher only). + * See Ralf Brown:
http://www.ctyme.com/intr/rb-0069.htm
+ * for more information. + */ + if ((ModeNumber & 0x08) == 0) VgaClearMemory(); // Bda->CrtModeControl; // Bda->CrtColorPaletteMask; @@ -895,14 +1064,14 @@ Bda->ScreenColumns = Resolution.X; Bda->ScreenRows = Resolution.Y - 1; - /* Set cursor position for each page */ + /* Set the cursor position for each page */ for (Page = 0; Page < BIOS_MAX_PAGES; ++Page) BiosSetCursorPosition(0, 0, Page); return TRUE; } -BOOLEAN BiosSetVideoPage(BYTE PageNumber) +static BOOLEAN BiosSetVideoPage(BYTE PageNumber) { BYTE Row, Column; @@ -932,8 +1101,719 @@ return TRUE; } +static VOID WINAPI BiosVideoService(LPWORD Stack) +{ + switch (getAH()) + { + /* Set Video Mode */ + case 0x00: + { + BiosSetVideoMode(getAL()); + break; + } + + /* Set Text-Mode Cursor Shape */ + case 0x01: + { + /* Update the BDA */ + Bda->CursorStartLine = getCH(); + Bda->CursorEndLine = getCL(); + + /* Modify the CRTC registers */ + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG); + VgaWritePort(VGA_CRTC_DATA , Bda->CursorStartLine); + VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG); + VgaWritePort(VGA_CRTC_DATA , Bda->CursorEndLine); + + break; + } + + /* Set Cursor Position */ + case 0x02: + { + BiosSetCursorPosition(getDH(), getDL(), getBH()); + break; + } + + /* Get Cursor Position */ + case 0x03: + { + /* Make sure the selected video page exists */ + if (getBH() >= BIOS_MAX_PAGES) break; + + /* Return the result */ + setAX(0); + setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine)); + setDX(Bda->CursorPosition[getBH()]); + break; + } + + /* Query Light Pen */ + case 0x04: + { + /* + * On modern BIOSes, this function returns 0 + * so that we can ignore the other registers. + */ + setAX(0); + break; + } + + /* Select Active Display Page */ + case 0x05: + { + BiosSetVideoPage(getAL()); + break; + } + + /* Scroll Window Up/Down */ + case 0x06: + case 0x07: + { + SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() }; + + /* Call the internal function */ + BiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP + : SCROLL_DIRECTION_DOWN, + getAL(), + Rectangle, + Bda->VideoPage, + getBH()); + + break; + } + + /* Read/Write Character From Cursor Position */ + case 0x08: + case 0x09: + case 0x0A: + { + WORD CharacterData = MAKEWORD(getAL(), getBL()); + BYTE Page = getBH(); + DWORD Offset; + + /* Check if the page exists */ + if (Page >= BIOS_MAX_PAGES) break; + + /* Find the offset of the character */ + Offset = Page * Bda->VideoPageSize + + (HIBYTE(Bda->CursorPosition[Page]) * Bda->ScreenColumns + + LOBYTE(Bda->CursorPosition[Page])) * 2; + + if (getAH() == 0x08) + { + /* Read from the video memory */ + VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), + (LPVOID)&CharacterData, + sizeof(WORD)); + + /* Return the character in AX */ + setAX(CharacterData); + } + else + { + /* Write to video memory */ + VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), + (LPVOID)&CharacterData, + (getBH() == 0x09) ? sizeof(WORD) : sizeof(BYTE)); + } + + break; + } + + /* Teletype Output */ + case 0x0E: + { + BiosPrintCharacter(getAL(), getBL(), getBH()); + break; + } + + /* Get Current Video Mode */ + case 0x0F: + { + setAX(MAKEWORD(Bda->VideoMode, Bda->ScreenColumns)); + setBX(MAKEWORD(getBL(), Bda->VideoPage)); + break; + } + + /* Palette Control */ + case 0x10: + { + switch (getAL()) + { + /* Set Single Palette Register */ + case 0x00: + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, getBL()); + + /* Write the data */ + VgaWritePort(VGA_AC_WRITE, getBH()); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Set Overscan Color */ + case 0x01: + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); + + /* Write the data */ + VgaWritePort(VGA_AC_WRITE, getBH()); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Set All Palette Registers */ + case 0x02: + { + INT i; + LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); + + /* Set the palette registers */ + for (i = 0; i <= VGA_AC_PAL_F_REG; i++) + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, i); + + /* Write the data */ + VgaWritePort(VGA_AC_WRITE, Buffer[i]); + } + + /* Set the overscan register */ + VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); + VgaWritePort(VGA_AC_WRITE, Buffer[VGA_AC_PAL_F_REG + 1]); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Get Single Palette Register */ + case 0x07: + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, getBL()); + + /* Read the data */ + setBH(VgaReadPort(VGA_AC_READ)); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Get Overscan Color */ + case 0x08: + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); + + /* Read the data */ + setBH(VgaReadPort(VGA_AC_READ)); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Get All Palette Registers */ + case 0x09: + { + INT i; + LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); + + /* Get the palette registers */ + for (i = 0; i <= VGA_AC_PAL_F_REG; i++) + { + /* Write the index */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, i); + + /* Read the data */ + Buffer[i] = VgaReadPort(VGA_AC_READ); + } + + /* Get the overscan register */ + VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); + Buffer[VGA_AC_PAL_F_REG + 1] = VgaReadPort(VGA_AC_READ); + + /* Enable screen and disable palette access */ + VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state + VgaWritePort(VGA_AC_INDEX, 0x20); + break; + } + + /* Set Individual DAC Register */ + case 0x10: + { + /* Write the index */ + // Certainly in BL and not in BX as said by Ralf Brown... + VgaWritePort(VGA_DAC_WRITE_INDEX, getBL()); + + /* Write the data in this order: Red, Green, Blue */ + VgaWritePort(VGA_DAC_DATA, getDH()); + VgaWritePort(VGA_DAC_DATA, getCH()); + VgaWritePort(VGA_DAC_DATA, getCL()); + + break; + } + + /* Set Block of DAC Registers */ + case 0x12: + { + INT i; + LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); + + /* Write the index */ + // Certainly in BL and not in BX as said by Ralf Brown... + VgaWritePort(VGA_DAC_WRITE_INDEX, getBL()); + + for (i = 0; i < getCX(); i++) + { + /* Write the data in this order: Red, Green, Blue */ + VgaWritePort(VGA_DAC_DATA, *Buffer++); + VgaWritePort(VGA_DAC_DATA, *Buffer++); + VgaWritePort(VGA_DAC_DATA, *Buffer++); + } + + break; + } + + /* Get Individual DAC Register */ + case 0x15: + { + /* Write the index */ + VgaWritePort(VGA_DAC_READ_INDEX, getBL()); + + /* Read the data in this order: Red, Green, Blue */ + setDH(VgaReadPort(VGA_DAC_DATA)); + setCH(VgaReadPort(VGA_DAC_DATA)); + setCL(VgaReadPort(VGA_DAC_DATA)); + + break; + } + + /* Get Block of DAC Registers */ + case 0x17: + { + INT i; + LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); + + /* Write the index */ + // Certainly in BL and not in BX as said by Ralf Brown... + VgaWritePort(VGA_DAC_READ_INDEX, getBL()); + + for (i = 0; i < getCX(); i++) + { + /* Write the data in this order: Red, Green, Blue */ + *Buffer++ = VgaReadPort(VGA_DAC_DATA); + *Buffer++ = VgaReadPort(VGA_DAC_DATA); + *Buffer++ = VgaReadPort(VGA_DAC_DATA); + } + + break; + } + + default: + { + DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n", + getAL()); + break; + } + } + + break; + } + + /* Scroll Window */ + case 0x12: + { + SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() }; + + /* Call the internal function */ + BiosScrollWindow(getBL(), + getAL(), + Rectangle, + Bda->VideoPage, + DEFAULT_ATTRIBUTE); + + break; + } + + /* Display combination code */ + case 0x1A: + { + switch(getAL()) + { + case 0x00: /* Get Display combiantion code */ + setAX(MAKEWORD(0x1A, 0x1A)); + setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */ + break; + case 0x01: /* Set Display combination code */ + DPRINT1("Set Display combination code - Unsupported\n"); + break; + default: + break; + } + break; + } + + default: + { + DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n", + getAH()); + } + } +} + +static VOID WINAPI BiosEquipmentService(LPWORD Stack) +{ + /* Return the equipment list */ + setAX(Bda->EquipmentList); +} + +static VOID WINAPI BiosGetMemorySize(LPWORD Stack) +{ + /* Return the conventional memory size in kB, typically 640 kB */ + setAX(Bda->MemorySize); +} + +static VOID WINAPI BiosMiscService(LPWORD Stack) +{ + switch (getAH()) + { + /* Copy Extended Memory */ + case 0x87: + { + DWORD Count = (DWORD)getCX() * 2; + PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI()); + DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24); + DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16); + DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24); + DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16); + + /* Check for flags */ + if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF; + if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF; + + if ((Count > SourceLimit) || (Count > DestLimit)) + { + setAX(0x80); + Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; + + break; + } + + /* Copy */ + RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase), + (PVOID)((ULONG_PTR)BaseAddress + SourceBase), + Count); + + setAX(ERROR_SUCCESS); + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + break; + } + + /* Get Extended Memory Size */ + case 0x88: + { + /* Return the number of KB of RAM after 1 MB */ + setAX((MAX_ADDRESS - 0x100000) / 1024); + + /* Clear CF */ + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; + + break; + } + + default: + { + DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n", + getAH()); + } + } +} + +static VOID WINAPI BiosKeyboardService(LPWORD Stack) +{ + switch (getAH()) + { + /* Wait for keystroke and read */ + case 0x00: + /* Wait for extended keystroke and read */ + case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h + { + /* Read the character (and wait if necessary) */ + setAX(BiosGetCharacter()); + break; + } + + /* Get keystroke status */ + case 0x01: + /* Get extended keystroke status */ + case 0x11: // FIXME: Temporarily do the same as INT 16h, 01h + { + WORD Data = BiosPeekCharacter(); + + if (Data != 0xFFFF) + { + /* There is a character, clear ZF and return it */ + Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF; + setAX(Data); + } + else + { + /* No character, set ZF */ + Stack[STACK_FLAGS] |= EMULATOR_FLAG_ZF; + } + + break; + } + + /* Get shift status */ + case 0x02: + { + /* Return the lower byte of the keyboard shift status word */ + setAL(LOBYTE(Bda->KeybdShiftFlags)); + break; + } + + /* Reserved */ + case 0x04: + { + DPRINT1("BIOS Function INT 16h, AH = 0x04 is RESERVED\n"); + break; + } + + /* Push keystroke */ + case 0x05: + { + /* Return 0 if success, 1 if failure */ + setAL(BiosKbdBufferPush(getCX()) == FALSE); + break; + } + + /* Get extended shift status */ + case 0x12: + { + /* + * Be careful! The returned word is similar to Bda->KeybdShiftFlags + * but the high byte is organized differently: + * the bytes 2 and 3 of the high byte are not the same... + */ + WORD KeybdShiftFlags = (Bda->KeybdShiftFlags & 0xF3FF); + + /* Return the extended keyboard shift status word */ + setAX(KeybdShiftFlags); + break; + } + + default: + { + DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n", + getAH()); + } + } +} + +static VOID WINAPI BiosTimeService(LPWORD Stack) +{ + switch (getAH()) + { + case 0x00: + { + /* Set AL to 1 if midnight had passed, 0 otherwise */ + setAL(Bda->MidnightPassed ? 0x01 : 0x00); + + /* Return the tick count in CX:DX */ + setCX(HIWORD(Bda->TickCounter)); + setDX(LOWORD(Bda->TickCounter)); + + /* Reset the midnight flag */ + Bda->MidnightPassed = FALSE; + + break; + } + + case 0x01: + { + /* Set the tick count to CX:DX */ + Bda->TickCounter = MAKELONG(getDX(), getCX()); + + /* Reset the midnight flag */ + Bda->MidnightPassed = FALSE; + + break; + } + + default: + { + DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n", + getAH()); + } + } +} + +static VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack) +{ + /* Increase the system tick count */ + Bda->TickCounter++; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ + +WORD BiosPeekCharacter(VOID) +{ + WORD CharacterData = 0; + + /* Get the key from the queue, but don't remove it */ + if (BiosKbdBufferTop(&CharacterData)) return CharacterData; + else return 0xFFFF; +} + +WORD BiosGetCharacter(VOID) +{ + WORD CharacterData = 0; + + /* Check if there is a key available */ + if (BiosKbdBufferTop(&CharacterData)) + { + /* A key was available, remove it from the queue */ + BiosKbdBufferPop(); + } + else + { + /* No key available. Set the handler CF to repeat the BOP */ + setCF(1); + // CharacterData = 0xFFFF; + } + + return CharacterData; +} + +VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page) +{ + WORD CharData = MAKEWORD(Character, Attribute); + BYTE Row, Column; + + /* Make sure the page exists */ + if (Page >= BIOS_MAX_PAGES) return; + + /* Get the cursor location */ + BiosGetCursorPosition(&Row, &Column, Page); + + if (Character == '\a') + { + /* Bell control character */ + // NOTE: We may use what the terminal emulator offers to us... + Beep(800, 200); + return; + } + else if (Character == '\b') + { + /* Backspace control character */ + if (Column > 0) + { + Column--; + } + else if (Row > 0) + { + Column = Bda->ScreenColumns - 1; + Row--; + } + + /* Erase the existing character */ + CharData = MAKEWORD(' ', Attribute); + EmulatorWriteMemory(&EmulatorContext, + TO_LINEAR(TEXT_VIDEO_SEG, + Page * Bda->VideoPageSize + + (Row * Bda->ScreenColumns + Column) * sizeof(WORD)), + (LPVOID)&CharData, + sizeof(WORD)); + } + else if (Character == '\t') + { + /* Horizontal Tabulation control character */ + do + { + // Taken from DOSBox + BiosPrintCharacter(' ', Attribute, Page); + BiosGetCursorPosition(&Row, &Column, Page); + } while (Column % 8); + } + else if (Character == '\n') + { + /* Line Feed control character */ + Row++; + } + else if (Character == '\r') + { + /* Carriage Return control character */ + Column = 0; + } + else + { + /* Default character */ + + /* Write the character */ + EmulatorWriteMemory(&EmulatorContext, + TO_LINEAR(TEXT_VIDEO_SEG, + Page * Bda->VideoPageSize + + (Row * Bda->ScreenColumns + Column) * sizeof(WORD)), + (LPVOID)&CharData, + sizeof(WORD)); + + /* Advance the cursor */ + Column++; + } + + /* Check if it passed the end of the row */ + if (Column >= Bda->ScreenColumns) + { + /* Return to the first column and go to the next line */ + Column = 0; + Row++; + } + + /* Scroll the screen up if needed */ + if (Row > Bda->ScreenRows) + { + /* The screen must be scrolled up */ + SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows }; + + BiosScrollWindow(SCROLL_DIRECTION_UP, + 1, + Rectangle, + Page, + DEFAULT_ATTRIBUTE); + + Row--; + } + + /* Set the cursor position */ + BiosSetCursorPosition(Row, Column, Page); +} + BOOLEAN BiosInitialize(VOID) { + CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; + /* Initialize the BDA */ Bda = (PBIOS_DATA_AREA)SEG_OFF_TO_PTR(BDA_SEGMENT, 0); Bda->EquipmentList = BIOS_EQUIPMENT_LIST; @@ -999,7 +1879,7 @@ return FALSE; } - /* Save the console screen buffer information */ + /* Save the original console screen buffer information */ if (!GetConsoleScreenBufferInfo(BiosConsoleOutput, &BiosSavedBufferInfo)) { CloseHandle(BiosConsoleOutput); @@ -1015,10 +1895,17 @@ return FALSE; } - /* Update the cursor position */ - BiosSetCursorPosition(BiosSavedBufferInfo.dwCursorPosition.Y, - BiosSavedBufferInfo.dwCursorPosition.X, - 0); + /* Set the default video mode */ + BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE); + + /* Copy console data into VGA memory */ + BiosCopyTextConsoleToVgaMemory(); + + /* Update the cursor position for the current page (page 0) */ + GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo); + BiosSetCursorPosition(ConsoleInfo.dwCursorPosition.Y, + ConsoleInfo.dwCursorPosition.X, + Bda->VideoPage); /* Set the console input mode */ SetConsoleMode(BiosConsoleInput, ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT); @@ -1055,841 +1942,31 @@ VOID BiosCleanup(VOID) { + SMALL_RECT ConRect; + CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; + PS2Cleanup(); /* Restore the old screen buffer */ SetConsoleActiveScreenBuffer(BiosConsoleOutput); - /* Restore the screen buffer size */ + /* Restore the original console size */ + GetConsoleScreenBufferInfo(BiosConsoleOutput, &ConsoleInfo); + ConRect.Left = 0; // BiosSavedBufferInfo.srWindow.Left; + // ConRect.Top = ConsoleInfo.dwCursorPosition.Y / (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1); + // ConRect.Top *= (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top + 1); + ConRect.Top = ConsoleInfo.dwCursorPosition.Y; + ConRect.Right = ConRect.Left + BiosSavedBufferInfo.srWindow.Right - BiosSavedBufferInfo.srWindow.Left; + ConRect.Bottom = ConRect.Top + (BiosSavedBufferInfo.srWindow.Bottom - BiosSavedBufferInfo.srWindow.Top); + /* See the following trick explanation in vga.c:VgaEnterTextMode() */ + SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize); + SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &ConRect); + // SetConsoleWindowInfo(BiosConsoleOutput, TRUE, &BiosSavedBufferInfo.srWindow); SetConsoleScreenBufferSize(BiosConsoleOutput, BiosSavedBufferInfo.dwSize); /* Close the console handles */ if (BiosConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleOutput); if (BiosConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(BiosConsoleInput); -} - -WORD BiosPeekCharacter(VOID) -{ - WORD CharacterData = 0; - - /* Get the key from the queue, but don't remove it */ - if (BiosKbdBufferTop(&CharacterData)) return CharacterData; - else return 0xFFFF; -} - -WORD BiosGetCharacter(VOID) -{ - WORD CharacterData = 0; - - /* Check if there is a key available */ - if (BiosKbdBufferTop(&CharacterData)) - { - /* A key was available, remove it from the queue */ - BiosKbdBufferPop(); - } - else - { - /* No key available. Set the handler CF to repeat the BOP */ - setCF(1); - // CharacterData = 0xFFFF; - } - - return CharacterData; -} - -VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page) -{ - /* Make sure the selected video page is valid */ - if (Page >= BIOS_MAX_PAGES) return; - - /* Get the cursor location */ - *Row = HIBYTE(Bda->CursorPosition[Page]); - *Column = LOBYTE(Bda->CursorPosition[Page]); -} - -VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page) -{ - /* Make sure the selected video page is valid */ - if (Page >= BIOS_MAX_PAGES) return; - - /* Update the position in the BDA */ - Bda->CursorPosition[Page] = MAKEWORD(Column, Row); - - /* Check if this is the current video page */ - if (Page == Bda->VideoPage) - { - WORD Offset = Row * Bda->ScreenColumns + Column; - - /* Modify the CRTC registers */ - VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_LOW_REG); - VgaWritePort(VGA_CRTC_DATA , LOBYTE(Offset)); - VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_LOC_HIGH_REG); - VgaWritePort(VGA_CRTC_DATA , HIBYTE(Offset)); - } -} - -BOOLEAN BiosScrollWindow(INT Direction, - DWORD Amount, - SMALL_RECT Rectangle, - BYTE Page, - BYTE FillAttribute) -{ - DWORD i; - LPWORD WindowData; - WORD WindowWidth = Rectangle.Right - Rectangle.Left + 1; - WORD WindowHeight = Rectangle.Bottom - Rectangle.Top + 1; - DWORD WindowSize = WindowWidth * WindowHeight; - - /* Allocate a buffer for the window */ - WindowData = (LPWORD)HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - WindowSize * sizeof(WORD)); - if (WindowData == NULL) return FALSE; - - /* Read the window data */ - BiosReadWindow(WindowData, Rectangle, Page); - - if ((Amount == 0) - || (((Direction == SCROLL_DIRECTION_UP) - || (Direction == SCROLL_DIRECTION_DOWN)) - && (Amount >= WindowHeight)) - || (((Direction == SCROLL_DIRECTION_LEFT) - || (Direction == SCROLL_DIRECTION_RIGHT)) - && (Amount >= WindowWidth))) - { - /* Fill the window */ - for (i = 0; i < WindowSize; i++) - { - WindowData[i] = MAKEWORD(' ', FillAttribute); - } - - goto Done; - } - - switch (Direction) - { - case SCROLL_DIRECTION_UP: - { - RtlMoveMemory(WindowData, - &WindowData[WindowWidth * Amount], - (WindowSize - WindowWidth * Amount) * sizeof(WORD)); - - for (i = 0; i < Amount * WindowWidth; i++) - { - WindowData[WindowSize - i - 1] = MAKEWORD(' ', FillAttribute); - } - - break; - } - - case SCROLL_DIRECTION_DOWN: - { - RtlMoveMemory(&WindowData[WindowWidth * Amount], - WindowData, - (WindowSize - WindowWidth * Amount) * sizeof(WORD)); - - for (i = 0; i < Amount * WindowWidth; i++) - { - WindowData[i] = MAKEWORD(' ', FillAttribute); - } - - break; - } - - default: - { - // TODO: NOT IMPLEMENTED! - UNIMPLEMENTED; - } - } - -Done: - /* Write back the window data */ - BiosWriteWindow(WindowData, Rectangle, Page); - - /* Free the window buffer */ - HeapFree(GetProcessHeap(), 0, WindowData); - - return TRUE; -} - -VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page) -{ - WORD CharData = MAKEWORD(Character, Attribute); - BYTE Row, Column; - - /* Make sure the page exists */ - if (Page >= BIOS_MAX_PAGES) return; - - /* Get the cursor location */ - BiosGetCursorPosition(&Row, &Column, Page); - - if (Character == '\a') - { - /* Bell control character */ - // NOTE: We may use what the terminal emulator offers to us... - Beep(800, 200); - return; - } - else if (Character == '\b') - { - /* Backspace control character */ - if (Column > 0) - { - Column--; - } - else if (Row > 0) - { - Column = Bda->ScreenColumns - 1; - Row--; - } - - /* Erase the existing character */ - CharData = MAKEWORD(' ', Attribute); - EmulatorWriteMemory(&EmulatorContext, - TO_LINEAR(TEXT_VIDEO_SEG, - Page * Bda->VideoPageSize + - (Row * Bda->ScreenColumns + Column) * sizeof(WORD)), - (LPVOID)&CharData, - sizeof(WORD)); - } - else if (Character == '\t') - { - /* Horizontal Tabulation control character */ - do - { - // Taken from DOSBox - BiosPrintCharacter(' ', Attribute, Page); - BiosGetCursorPosition(&Row, &Column, Page); - } while (Column % 8); - } - else if (Character == '\n') - { - /* Line Feed control character */ - Row++; - } - else if (Character == '\r') - { - /* Carriage Return control character */ - Column = 0; - } - else - { - /* Default character */ - - /* Write the character */ - EmulatorWriteMemory(&EmulatorContext, - TO_LINEAR(TEXT_VIDEO_SEG, - Page * Bda->VideoPageSize + - (Row * Bda->ScreenColumns + Column) * sizeof(WORD)), - (LPVOID)&CharData, - sizeof(WORD)); - - /* Advance the cursor */ - Column++; - } - - /* Check if it passed the end of the row */ - if (Column >= Bda->ScreenColumns) - { - /* Return to the first column and go to the next line */ - Column = 0; - Row++; - } - - /* Scroll the screen up if needed */ - if (Row > Bda->ScreenRows) - { - /* The screen must be scrolled up */ - SMALL_RECT Rectangle = { 0, 0, Bda->ScreenColumns - 1, Bda->ScreenRows }; - - BiosScrollWindow(SCROLL_DIRECTION_UP, - 1, - Rectangle, - Page, - DEFAULT_ATTRIBUTE); - - Row--; - } - - /* Set the cursor position */ - BiosSetCursorPosition(Row, Column, Page); -} - -VOID WINAPI BiosVideoService(LPWORD Stack) -{ - switch (getAH()) - { - /* Set Video Mode */ - case 0x00: - { - BiosSetVideoMode(getAL()); - VgaClearMemory(); - break; - } - - /* Set Text-Mode Cursor Shape */ - case 0x01: - { - /* Update the BDA */ - Bda->CursorStartLine = getCH(); - Bda->CursorEndLine = getCL(); - - /* Modify the CRTC registers */ - VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_START_REG); - VgaWritePort(VGA_CRTC_DATA , Bda->CursorStartLine); - VgaWritePort(VGA_CRTC_INDEX, VGA_CRTC_CURSOR_END_REG); - VgaWritePort(VGA_CRTC_DATA , Bda->CursorEndLine); - - break; - } - - /* Set Cursor Position */ - case 0x02: - { - BiosSetCursorPosition(getDH(), getDL(), getBH()); - break; - } - - /* Get Cursor Position */ - case 0x03: - { - /* Make sure the selected video page exists */ - if (getBH() >= BIOS_MAX_PAGES) break; - - /* Return the result */ - setAX(0); - setCX(MAKEWORD(Bda->CursorEndLine, Bda->CursorStartLine)); - setDX(Bda->CursorPosition[getBH()]); - break; - } - - /* Query Light Pen */ - case 0x04: - { - /* - * On modern BIOSes, this function returns 0 - * so that we can ignore the other registers. - */ - setAX(0); - break; - } - - /* Select Active Display Page */ - case 0x05: - { - BiosSetVideoPage(getAL()); - break; - } - - /* Scroll Window Up/Down */ - case 0x06: - case 0x07: - { - SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() }; - - /* Call the internal function */ - BiosScrollWindow((getAH() == 0x06) ? SCROLL_DIRECTION_UP - : SCROLL_DIRECTION_DOWN, - getAL(), - Rectangle, - Bda->VideoPage, - getBH()); - - break; - } - - /* Read/Write Character From Cursor Position */ - case 0x08: - case 0x09: - case 0x0A: - { - WORD CharacterData = MAKEWORD(getAL(), getBL()); - BYTE Page = getBH(); - DWORD Offset; - - /* Check if the page exists */ - if (Page >= BIOS_MAX_PAGES) break; - - /* Find the offset of the character */ - Offset = Page * Bda->VideoPageSize + - (HIBYTE(Bda->CursorPosition[Page]) * Bda->ScreenColumns + - LOBYTE(Bda->CursorPosition[Page])) * 2; - - if (getAH() == 0x08) - { - /* Read from the video memory */ - VgaReadMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), - (LPVOID)&CharacterData, - sizeof(WORD)); - - /* Return the character in AX */ - setAX(CharacterData); - } - else - { - /* Write to video memory */ - VgaWriteMemory(TO_LINEAR(TEXT_VIDEO_SEG, Offset), - (LPVOID)&CharacterData, - (getBH() == 0x09) ? sizeof(WORD) : sizeof(BYTE)); - } - - break; - } - - /* Teletype Output */ - case 0x0E: - { - BiosPrintCharacter(getAL(), getBL(), getBH()); - break; - } - - /* Get Current Video Mode */ - case 0x0F: - { - setAX(MAKEWORD(Bda->VideoMode, Bda->ScreenColumns)); - setBX(MAKEWORD(getBL(), Bda->VideoPage)); - break; - } - - /* Palette Control */ - case 0x10: - { - switch (getAL()) - { - /* Set Single Palette Register */ - case 0x00: - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, getBL()); - - /* Write the data */ - VgaWritePort(VGA_AC_WRITE, getBH()); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Set Overscan Color */ - case 0x01: - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); - - /* Write the data */ - VgaWritePort(VGA_AC_WRITE, getBH()); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Set All Palette Registers */ - case 0x02: - { - INT i; - LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); - - /* Set the palette registers */ - for (i = 0; i <= VGA_AC_PAL_F_REG; i++) - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, i); - - /* Write the data */ - VgaWritePort(VGA_AC_WRITE, Buffer[i]); - } - - /* Set the overscan register */ - VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); - VgaWritePort(VGA_AC_WRITE, Buffer[VGA_AC_PAL_F_REG + 1]); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Get Single Palette Register */ - case 0x07: - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, getBL()); - - /* Read the data */ - setBH(VgaReadPort(VGA_AC_READ)); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Get Overscan Color */ - case 0x08: - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); - - /* Read the data */ - setBH(VgaReadPort(VGA_AC_READ)); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Get All Palette Registers */ - case 0x09: - { - INT i; - LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); - - /* Get the palette registers */ - for (i = 0; i <= VGA_AC_PAL_F_REG; i++) - { - /* Write the index */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, i); - - /* Read the data */ - Buffer[i] = VgaReadPort(VGA_AC_READ); - } - - /* Get the overscan register */ - VgaWritePort(VGA_AC_INDEX, VGA_AC_OVERSCAN_REG); - Buffer[VGA_AC_PAL_F_REG + 1] = VgaReadPort(VGA_AC_READ); - - /* Enable screen and disable palette access */ - VgaReadPort(VGA_INSTAT1_READ); // Put the AC register into index state - VgaWritePort(VGA_AC_INDEX, 0x20); - break; - } - - /* Set Individual DAC Register */ - case 0x10: - { - /* Write the index */ - // Certainly in BL and not in BX as said by Ralf Brown... - VgaWritePort(VGA_DAC_WRITE_INDEX, getBL()); - - /* Write the data in this order: Red, Green, Blue */ - VgaWritePort(VGA_DAC_DATA, getDH()); - VgaWritePort(VGA_DAC_DATA, getCH()); - VgaWritePort(VGA_DAC_DATA, getCL()); - - break; - } - - /* Set Block of DAC Registers */ - case 0x12: - { - INT i; - LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); - - /* Write the index */ - // Certainly in BL and not in BX as said by Ralf Brown... - VgaWritePort(VGA_DAC_WRITE_INDEX, getBL()); - - for (i = 0; i < getCX(); i++) - { - /* Write the data in this order: Red, Green, Blue */ - VgaWritePort(VGA_DAC_DATA, *Buffer++); - VgaWritePort(VGA_DAC_DATA, *Buffer++); - VgaWritePort(VGA_DAC_DATA, *Buffer++); - } - - break; - } - - /* Get Individual DAC Register */ - case 0x15: - { - /* Write the index */ - VgaWritePort(VGA_DAC_READ_INDEX, getBL()); - - /* Read the data in this order: Red, Green, Blue */ - setDH(VgaReadPort(VGA_DAC_DATA)); - setCH(VgaReadPort(VGA_DAC_DATA)); - setCL(VgaReadPort(VGA_DAC_DATA)); - - break; - } - - /* Get Block of DAC Registers */ - case 0x17: - { - INT i; - LPBYTE Buffer = SEG_OFF_TO_PTR(getES(), getDX()); - - /* Write the index */ - // Certainly in BL and not in BX as said by Ralf Brown... - VgaWritePort(VGA_DAC_READ_INDEX, getBL()); - - for (i = 0; i < getCX(); i++) - { - /* Write the data in this order: Red, Green, Blue */ - *Buffer++ = VgaReadPort(VGA_DAC_DATA); - *Buffer++ = VgaReadPort(VGA_DAC_DATA); - *Buffer++ = VgaReadPort(VGA_DAC_DATA); - } - - break; - } - - default: - { - DPRINT1("BIOS Palette Control Sub-command AL = 0x%02X NOT IMPLEMENTED\n", - getAL()); - break; - } - } - - break; - } - - /* Scroll Window */ - case 0x12: - { - SMALL_RECT Rectangle = { getCL(), getCH(), getDL(), getDH() }; - - /* Call the internal function */ - BiosScrollWindow(getBL(), - getAL(), - Rectangle, - Bda->VideoPage, - DEFAULT_ATTRIBUTE); - - break; - } - - /* Display combination code */ - case 0x1A: - { - switch(getAL()) - { - case 0x00: /* Get Display combiantion code */ - setAX(MAKEWORD(0x1A, 0x1A)); - setBX(MAKEWORD(0x08, 0x00)); /* VGA w/ color analog display */ - break; - case 0x01: /* Set Display combination code */ - DPRINT1("Set Display combination code - Unsupported\n"); - break; - default: - break; - } - break; - } - - default: - { - DPRINT1("BIOS Function INT 10h, AH = 0x%02X NOT IMPLEMENTED\n", - getAH()); - } - } -} - -VOID WINAPI BiosEquipmentService(LPWORD Stack) -{ - /* Return the equipment list */ - setAX(Bda->EquipmentList); -} - -VOID WINAPI BiosGetMemorySize(LPWORD Stack) -{ - /* Return the conventional memory size in kB, typically 640 kB */ - setAX(Bda->MemorySize); -} - -VOID WINAPI BiosMiscService(LPWORD Stack) -{ - switch (getAH()) - { - /* Copy Extended Memory */ - case 0x87: - { - DWORD Count = (DWORD)getCX() * 2; - PFAST486_GDT_ENTRY Gdt = (PFAST486_GDT_ENTRY)SEG_OFF_TO_PTR(getES(), getSI()); - DWORD SourceBase = Gdt[2].Base + (Gdt[2].BaseMid << 16) + (Gdt[2].BaseHigh << 24); - DWORD SourceLimit = Gdt[2].Limit + (Gdt[2].LimitHigh << 16); - DWORD DestBase = Gdt[3].Base + (Gdt[3].BaseMid << 16) + (Gdt[3].BaseHigh << 24); - DWORD DestLimit = Gdt[3].Limit + (Gdt[3].LimitHigh << 16); - - /* Check for flags */ - if (Gdt[2].Granularity) SourceLimit = (SourceLimit << 12) | 0xFFF; - if (Gdt[3].Granularity) DestLimit = (DestLimit << 12) | 0xFFF; - - if ((Count > SourceLimit) || (Count > DestLimit)) - { - setAX(0x80); - Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; - - break; - } - - /* Copy */ - RtlMoveMemory((PVOID)((ULONG_PTR)BaseAddress + DestBase), - (PVOID)((ULONG_PTR)BaseAddress + SourceBase), - Count); - - setAX(ERROR_SUCCESS); - Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; - break; - } - - /* Get Extended Memory Size */ - case 0x88: - { - /* Return the number of KB of RAM after 1 MB */ - setAX((MAX_ADDRESS - 0x100000) / 1024); - - /* Clear CF */ - Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; - - break; - } - - default: - { - DPRINT1("BIOS Function INT 15h, AH = 0x%02X NOT IMPLEMENTED\n", - getAH()); - } - } -} - -VOID WINAPI BiosKeyboardService(LPWORD Stack) -{ - switch (getAH()) - { - /* Wait for keystroke and read */ - case 0x00: - /* Wait for extended keystroke and read */ - case 0x10: // FIXME: Temporarily do the same as INT 16h, 00h - { - /* Read the character (and wait if necessary) */ - setAX(BiosGetCharacter()); - break; - } - - /* Get keystroke status */ - case 0x01: - /* Get extended keystroke status */ - case 0x11: // FIXME: Temporarily do the same as INT 16h, 01h - { - WORD Data = BiosPeekCharacter(); - - if (Data != 0xFFFF) - { - /* There is a character, clear ZF and return it */ - Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF; - setAX(Data); - } - else - { - /* No character, set ZF */ - Stack[STACK_FLAGS] |= EMULATOR_FLAG_ZF; - } - - break; - } - - /* Get shift status */ - case 0x02: - { - /* Return the lower byte of the keyboard shift status word */ - setAL(LOBYTE(Bda->KeybdShiftFlags)); - break; - } - - /* Reserved */ - case 0x04: - { - DPRINT1("BIOS Function INT 16h, AH = 0x04 is RESERVED\n"); - break; - } - - /* Push keystroke */ - case 0x05: - { - /* Return 0 if success, 1 if failure */ - setAL(BiosKbdBufferPush(getCX()) == FALSE); - break; - } - - /* Get extended shift status */ - case 0x12: - { - /* - * Be careful! The returned word is similar to Bda->KeybdShiftFlags - * but the high byte is organized differently: - * the bytes 2 and 3 of the high byte are not the same... - */ - WORD KeybdShiftFlags = (Bda->KeybdShiftFlags & 0xF3FF); - - /* Return the extended keyboard shift status word */ - setAX(KeybdShiftFlags); - break; - } - - default: - { - DPRINT1("BIOS Function INT 16h, AH = 0x%02X NOT IMPLEMENTED\n", - getAH()); - } - } -} - -VOID WINAPI BiosTimeService(LPWORD Stack) -{ - switch (getAH()) - { - case 0x00: - { - /* Set AL to 1 if midnight had passed, 0 otherwise */ - setAL(Bda->MidnightPassed ? 0x01 : 0x00); - - /* Return the tick count in CX:DX */ - setCX(HIWORD(Bda->TickCounter)); - setDX(LOWORD(Bda->TickCounter)); - - /* Reset the midnight flag */ - Bda->MidnightPassed = FALSE; - - break; - } - - case 0x01: - { - /* Set the tick count to CX:DX */ - Bda->TickCounter = MAKELONG(getDX(), getCX()); - - /* Reset the midnight flag */ - Bda->MidnightPassed = FALSE; - - break; - } - - default: - { - DPRINT1("BIOS Function INT 1Ah, AH = 0x%02X NOT IMPLEMENTED\n", - getAH()); - } - } -} - -VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack) -{ - /* Increase the system tick count */ - Bda->TickCounter++; } VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack) Modified: branches/ntvdm/subsystems/ntvdm/bios.h URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.h?r…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/bios.h [iso-8859-1] Sun Jan 5 21:26:33 2014 @@ -151,31 +151,12 @@ extern PBIOS_DATA_AREA Bda; +WORD BiosPeekCharacter(VOID); +WORD BiosGetCharacter(VOID); +VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page); + BOOLEAN BiosInitialize(VOID); VOID BiosCleanup(VOID); -BYTE BiosGetVideoMode(VOID); -BOOLEAN BiosSetVideoMode(BYTE ModeNumber); -WORD BiosPeekCharacter(VOID); -WORD BiosGetCharacter(VOID); -VOID BiosGetCursorPosition(PBYTE Row, PBYTE Column, BYTE Page); -VOID BiosSetCursorPosition(BYTE Row, BYTE Column, BYTE Page); -VOID BiosPrintCharacter(CHAR Character, BYTE Attribute, BYTE Page); -BOOLEAN BiosScrollWindow( - INT Direction, - DWORD Amount, - SMALL_RECT Rectangle, - BYTE Page, - BYTE FillAttribute -); - -VOID WINAPI BiosVideoService(LPWORD Stack); -VOID WINAPI BiosEquipmentService(LPWORD Stack); -VOID WINAPI BiosGetMemorySize(LPWORD Stack); -VOID WINAPI BiosMiscService(LPWORD Stack); -VOID WINAPI BiosKeyboardService(LPWORD Stack); -VOID WINAPI BiosTimeService(LPWORD Stack); -VOID WINAPI BiosSystemTimerInterrupt(LPWORD Stack); - VOID BiosHandleIrq(BYTE IrqNumber, LPWORD Stack); #endif // _BIOS_H_ Modified: branches/ntvdm/subsystems/ntvdm/vga.c URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/vga.c?re…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/vga.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/vga.c [iso-8859-1] Sun Jan 5 21:26:33 2014 @@ -171,8 +171,7 @@ #endif -static HANDLE VgaSavedConsoleHandle = NULL; -static CONSOLE_SCREEN_BUFFER_INFO VgaSavedConsoleInfo; +static CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo; static BYTE VgaMemory[VGA_NUM_BANKS * VGA_BANK_SIZE]; static LPVOID ConsoleFramebuffer = NULL; @@ -234,15 +233,16 @@ /* Double-word addressing */ return 4; // sizeof(DWORD) } - - if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & VGA_CRTC_MODE_CONTROL_BYTE) + else if (VgaCrtcRegisters[VGA_CRTC_MODE_CONTROL_REG] & VGA_CRTC_MODE_CONTROL_BYTE) { /* Byte addressing */ return 1; // sizeof(BYTE) } - - /* Word addressing */ - return 2; // sizeof(WORD) + else + { + /* Word addressing */ + return 2; // sizeof(WORD) + } } static inline DWORD VgaTranslateReadAddress(DWORD Address) @@ -611,8 +611,8 @@ /* Release the console framebuffer mutex */ ReleaseMutex(ConsoleMutex); - /* Switch back to the default console buffer */ - // SetConsoleActiveScreenBuffer(VgaSavedConsoleHandle); + /* Switch back to the default console text buffer */ + // SetConsoleActiveScreenBuffer(TextConsoleBuffer); /* Cleanup the video data */ CloseHandle(ConsoleMutex); @@ -630,8 +630,8 @@ SetConsoleActiveScreenBuffer(TextConsoleBuffer); /* Resize the console */ - ConRect.Left = 0; // VgaSavedConsoleInfo.srWindow.Left; - ConRect.Top = VgaSavedConsoleInfo.srWindow.Top; + ConRect.Left = 0; // ConsoleInfo.srWindow.Left; + ConRect.Top = ConsoleInfo.srWindow.Top; ConRect.Right = ConRect.Left + Resolution->X - 1; ConRect.Bottom = ConRect.Top + Resolution->Y - 1; /* @@ -646,7 +646,7 @@ SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect); SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution); /* Update the saved console information */ - GetConsoleScreenBufferInfo(TextConsoleBuffer, &VgaSavedConsoleInfo); + GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo); /* Allocate a framebuffer */ ConsoleFramebuffer = HeapAlloc(GetProcessHeap(), @@ -689,9 +689,6 @@ static VOID VgaChangeMode(VOID) { COORD Resolution = VgaGetDisplayResolution(); - - /* Reset the mode change flag */ - // ModeChanged = FALSE; if (ScreenMode == GRAPHICS_MODE) { @@ -929,7 +926,9 @@ else { /* Text mode */ + DWORD CurrentAddr; PCHAR_INFO CharBuffer = (PCHAR_INFO)ConsoleFramebuffer; + CHAR_INFO CharInfo; /* Loop through the scanlines */ for (i = 0; i < Resolution.Y; i++) @@ -937,8 +936,7 @@ /* Loop through the characters */ for (j = 0; j < Resolution.X; j++) { - DWORD CurrentAddr = LOWORD((Address + j) * AddressSize); - CHAR_INFO CharInfo; + CurrentAddr = LOWORD((Address + j) * AddressSize); /* Plane 0 holds the character itself */ CharInfo.Char.AsciiChar = VgaMemory[CurrentAddr]; @@ -976,7 +974,7 @@ VgaCrtcRegisters[VGA_CRTC_CURSOR_LOC_HIGH_REG]); /* Just return if we are not in text mode */ - if ((VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) != 0) return; + if (VgaGcRegisters[VGA_GC_MISC_REG] & VGA_GC_MISC_NOALPHA) return; if (CursorStart < CursorEnd) { @@ -1078,14 +1076,14 @@ if (!ModeChanged && !CursorMoved && !PaletteChanged && !NeedsUpdate) return; + /* Change the display mode */ + if (ModeChanged) VgaChangeMode(); + + /* Change the text cursor location */ + if (CursorMoved) VgaUpdateTextCursor(); + /* Retrieve the current resolution */ Resolution = VgaGetDisplayResolution(); - - /* Change the display mode */ - if (ModeChanged) VgaChangeMode(); - - /* Change the text cursor location */ - if (CursorMoved) VgaUpdateTextCursor(); if (PaletteChanged) { @@ -1492,21 +1490,12 @@ BOOLEAN VgaInitialize(HANDLE TextHandle) { - INT i, j; - COORD Resolution; - DWORD AddressSize; - DWORD ScanlineSize; - COORD Origin = { 0, 0 }; - SMALL_RECT ScreenRect; - PCHAR_INFO CharBuffer; - DWORD Address = 0; - DWORD CurrentAddr; + /* Save the default text-mode console output handle */ + if (TextHandle == INVALID_HANDLE_VALUE) return FALSE; + TextConsoleBuffer = TextHandle; /* Save the console information */ - if (TextHandle == INVALID_HANDLE_VALUE) return FALSE; - VgaSavedConsoleHandle = TextHandle; - if (!GetConsoleScreenBufferInfo(VgaSavedConsoleHandle, - &VgaSavedConsoleInfo)) + if (!GetConsoleScreenBufferInfo(TextConsoleBuffer, &ConsoleInfo)) { return FALSE; } @@ -1515,8 +1504,8 @@ if (!VgaInitializePalette()) return FALSE; /***/ VgaResetPalette(); /***/ - /* Save the default text-mode console output handle */ - TextConsoleBuffer = TextHandle; + /* Switch to the text buffer */ + SetConsoleActiveScreenBuffer(TextConsoleBuffer); /* Clear the VGA memory */ VgaClearMemory(); @@ -1536,45 +1525,6 @@ RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA - /* Set the default video mode */ - BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE); - VgaChangeMode(); - - /* Get the data */ - Resolution = VgaGetDisplayResolution(); - CharBuffer = (PCHAR_INFO)ConsoleFramebuffer; - AddressSize = VgaGetAddressSize(); - ScreenRect.Left = ScreenRect.Top = 0; - ScreenRect.Right = Resolution.X; - ScreenRect.Bottom = Resolution.Y; - ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2; - - /* Read the data from the console into the framebuffer */ - ReadConsoleOutputA(TextConsoleBuffer, - CharBuffer, - Resolution, - Origin, - &ScreenRect); - - /* Loop through the scanlines */ - for (i = 0; i < Resolution.Y; i++) - { - /* Loop through the characters */ - for (j = 0; j < Resolution.X; j++) - { - CurrentAddr = LOWORD((Address + j) * AddressSize); - - /* Store the character in plane 0 */ - VgaMemory[CurrentAddr] = CharBuffer[i * Resolution.X + j].Char.AsciiChar; - - /* Store the attribute in plane 1 */ - VgaMemory[CurrentAddr + VGA_BANK_SIZE] = (BYTE)CharBuffer[i * Resolution.X + j].Attributes; - } - - /* Move to the next scanline */ - Address += ScanlineSize; - } - /* Return success */ return TRUE; }
10 years, 11 months
1
0
0
0
[jgardou] 61541: [WIN32K] - Implement NtGdiSwapBuffers
by jgardou@svn.reactos.org
Author: jgardou Date: Sun Jan 5 20:57:51 2014 New Revision: 61541 URL:
http://svn.reactos.org/svn/reactos?rev=61541&view=rev
Log: [WIN32K] - Implement NtGdiSwapBuffers Modified: trunk/reactos/win32ss/gdi/ntgdi/wingl.c Modified: trunk/reactos/win32ss/gdi/ntgdi/wingl.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/wingl.c?…
============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/wingl.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/wingl.c [iso-8859-1] Sun Jan 5 20:57:51 2014 @@ -128,7 +128,8 @@ return FALSE; } - if (!pdc->ipfdDevMax) IntGetipfdDevMax(pdc); + if (!pdc->ipfdDevMax) + IntGetipfdDevMax(pdc); if ( ipfd < 1 || ipfd > pdc->ipfdDevMax ) @@ -182,10 +183,59 @@ BOOL APIENTRY NtGdiSwapBuffers( - _In_ HDC hDC) -{ - UNIMPLEMENTED; - return FALSE; + _In_ HDC hdc) +{ + PDC pdc; + PPDEVOBJ ppdev; + HWND hWnd; + PWNDOBJ pWndObj; + SURFOBJ *pso = NULL; + BOOL Ret = FALSE; + + pdc = DC_LockDc(hdc); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + UserEnterExclusive(); + hWnd = UserGethWnd(hdc, &pWndObj); + UserLeave(); + + if (!hWnd) + { + EngSetLastError(ERROR_INVALID_WINDOW_STYLE); + goto Exit; + } + + ppdev = pdc->ppdev; + + /* + WndObj is needed so exit on NULL pointer. + */ + if (pWndObj) + pso = pWndObj->psoOwner; + else + { + EngSetLastError(ERROR_INVALID_PIXEL_FORMAT); + goto Exit; + } + + if (ppdev->flFlags & PDEV_META_DEVICE) + { + UNIMPLEMENTED; + goto Exit; + } + + if (ppdev->DriverFunctions.SwapBuffers) + { + Ret = ppdev->DriverFunctions.SwapBuffers(pso, pWndObj); + } + +Exit: + DC_UnlockDc(pdc); + return Ret; } /* EOF */
10 years, 11 months
1
0
0
0
[jgardou] 61540: [WIN32K] - Formatting only, no code change
by jgardou@svn.reactos.org
Author: jgardou Date: Sun Jan 5 20:50:09 2014 New Revision: 61540 URL:
http://svn.reactos.org/svn/reactos?rev=61540&view=rev
Log: [WIN32K] - Formatting only, no code change Modified: trunk/reactos/win32ss/gdi/ntgdi/wingl.c Modified: trunk/reactos/win32ss/gdi/ntgdi/wingl.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/ntgdi/wingl.c?…
============================================================================== --- trunk/reactos/win32ss/gdi/ntgdi/wingl.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/ntgdi/wingl.c [iso-8859-1] Sun Jan 5 20:50:09 2014 @@ -16,29 +16,29 @@ FASTCALL IntGetipfdDevMax(PDC pdc) { - INT Ret = 0; - PPDEVOBJ ppdev = pdc->ppdev; + INT Ret = 0; + PPDEVOBJ ppdev = pdc->ppdev; - if (ppdev->flFlags & PDEV_META_DEVICE) - { - return 0; - } + if (ppdev->flFlags & PDEV_META_DEVICE) + { + return 0; + } - if (ppdev->DriverFunctions.DescribePixelFormat) - { - Ret = ppdev->DriverFunctions.DescribePixelFormat( + if (ppdev->DriverFunctions.DescribePixelFormat) + { + Ret = ppdev->DriverFunctions.DescribePixelFormat( ppdev->dhpdev, 1, 0, NULL); - } + } - if (Ret) pdc->ipfdDevMax = Ret; + if (Ret) pdc->ipfdDevMax = Ret; - return Ret; + return Ret; } - _Success_(return != 0) +_Success_(return != 0) INT APIENTRY NtGdiDescribePixelFormat( @@ -47,142 +47,145 @@ _In_ UINT cjpfd, _When_(cjpfd != 0, _Out_) PPIXELFORMATDESCRIPTOR ppfd) { - PDC pdc; - PPDEVOBJ ppdev; - INT Ret = 0; - PIXELFORMATDESCRIPTOR pfdSafe; + PDC pdc; + PPDEVOBJ ppdev; + INT Ret = 0; + PIXELFORMATDESCRIPTOR pfdSafe; - if ((ppfd == NULL) && (cjpfd != 0)) return 0; + if ((ppfd == NULL) && (cjpfd != 0)) return 0; - pdc = DC_LockDc(hdc); - if (!pdc) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return 0; - } + pdc = DC_LockDc(hdc); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return 0; + } - if (!pdc->ipfdDevMax) IntGetipfdDevMax(pdc); + if (!pdc->ipfdDevMax) + IntGetipfdDevMax(pdc); - if ((ipfd < 1) || (ipfd > pdc->ipfdDevMax)) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto Exit; - } + if ((ipfd < 1) || (ipfd > pdc->ipfdDevMax)) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto Exit; + } - ppdev = pdc->ppdev; + ppdev = pdc->ppdev; - if (ppdev->flFlags & PDEV_META_DEVICE) - { - UNIMPLEMENTED; - goto Exit; - } + if (ppdev->flFlags & PDEV_META_DEVICE) + { + UNIMPLEMENTED; + goto Exit; + } - if (ppdev->DriverFunctions.DescribePixelFormat) - { - Ret = ppdev->DriverFunctions.DescribePixelFormat( - ppdev->dhpdev, - ipfd, - sizeof(pfdSafe), - &pfdSafe); - } + if (ppdev->DriverFunctions.DescribePixelFormat) + { + Ret = ppdev->DriverFunctions.DescribePixelFormat( + ppdev->dhpdev, + ipfd, + sizeof(pfdSafe), + &pfdSafe); + } - if (Ret && cjpfd) - { - _SEH2_TRY - { - cjpfd = min(cjpfd, sizeof(PIXELFORMATDESCRIPTOR)); - ProbeForWrite(ppfd, cjpfd, 1); - RtlCopyMemory(ppfd, &pfdSafe, cjpfd); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - } - _SEH2_END; - } + if (Ret && cjpfd) + { + _SEH2_TRY + { + cjpfd = min(cjpfd, sizeof(PIXELFORMATDESCRIPTOR)); + ProbeForWrite(ppfd, cjpfd, 1); + RtlCopyMemory(ppfd, &pfdSafe, cjpfd); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + } + _SEH2_END; + } Exit: - DC_UnlockDc(pdc); - return Ret; + DC_UnlockDc(pdc); + return Ret; } BOOL APIENTRY NtGdiSetPixelFormat( - IN HDC hdc, - IN INT ipfd) + _In_ HDC hdc, + _In_ INT ipfd) { - PDC pdc; - PPDEVOBJ ppdev; - HWND hWnd; - PWNDOBJ pWndObj; - SURFOBJ *pso = NULL; - BOOL Ret = FALSE; + PDC pdc; + PPDEVOBJ ppdev; + HWND hWnd; + PWNDOBJ pWndObj; + SURFOBJ *pso = NULL; + BOOL Ret = FALSE; - pdc = DC_LockDc(hdc); - if (!pdc) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + pdc = DC_LockDc(hdc); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } - if (!pdc->ipfdDevMax) IntGetipfdDevMax(pdc); + if (!pdc->ipfdDevMax) IntGetipfdDevMax(pdc); - if ( ipfd < 1 || - ipfd > pdc->ipfdDevMax ) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto Exit; - } + if ( ipfd < 1 || + ipfd > pdc->ipfdDevMax ) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto Exit; + } - UserEnterExclusive(); - hWnd = UserGethWnd(hdc, &pWndObj); - UserLeave(); + UserEnterExclusive(); + hWnd = UserGethWnd(hdc, &pWndObj); + UserLeave(); - if (!hWnd) - { - EngSetLastError(ERROR_INVALID_WINDOW_STYLE); - goto Exit; - } + if (!hWnd) + { + EngSetLastError(ERROR_INVALID_WINDOW_STYLE); + goto Exit; + } - ppdev = pdc->ppdev; + ppdev = pdc->ppdev; - /* - WndObj is needed so exit on NULL pointer. - */ - if (pWndObj) pso = pWndObj->psoOwner; - else - { - EngSetLastError(ERROR_INVALID_PIXEL_FORMAT); - goto Exit; - } + /* + WndObj is needed so exit on NULL pointer. + */ + if (pWndObj) + pso = pWndObj->psoOwner; + else + { + EngSetLastError(ERROR_INVALID_PIXEL_FORMAT); + goto Exit; + } - if (ppdev->flFlags & PDEV_META_DEVICE) - { - UNIMPLEMENTED; - goto Exit; - } + if (ppdev->flFlags & PDEV_META_DEVICE) + { + UNIMPLEMENTED; + goto Exit; + } - if (ppdev->DriverFunctions.SetPixelFormat) - { - Ret = ppdev->DriverFunctions.SetPixelFormat( + if (ppdev->DriverFunctions.SetPixelFormat) + { + Ret = ppdev->DriverFunctions.SetPixelFormat( pso, ipfd, hWnd); - } + } Exit: - DC_UnlockDc(pdc); - return Ret; + DC_UnlockDc(pdc); + return Ret; } BOOL APIENTRY -NtGdiSwapBuffers(HDC hDC) +NtGdiSwapBuffers( + _In_ HDC hDC) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* EOF */
10 years, 11 months
1
0
0
0
[ekohl] 61539: [LSASRV][MSV1_0] - Add all groups, of which the user is a member, to the token group list. - Remove the hard-coded administrators group and users group from the token group list. Thi...
by ekohl@svn.reactos.org
Author: ekohl Date: Sun Jan 5 16:06:16 2014 New Revision: 61539 URL:
http://svn.reactos.org/svn/reactos?rev=61539&view=rev
Log: [LSASRV][MSV1_0] - Add all groups, of which the user is a member, to the token group list. - Remove the hard-coded administrators group and users group from the token group list. This patch enables us to create ordinary user accounts which are not members of the administrator group and which do not have administrator privileges. Now we can start to test and fix the security components! Modified: trunk/reactos/dll/win32/lsasrv/authpackage.c trunk/reactos/dll/win32/lsasrv/lsasrv.h trunk/reactos/dll/win32/lsasrv/utils.c trunk/reactos/dll/win32/msv1_0/msv1_0.c Modified: trunk/reactos/dll/win32/lsasrv/authpackage.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/lsasrv/authpacka…
============================================================================== --- trunk/reactos/dll/win32/lsasrv/authpackage.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/lsasrv/authpackage.c [iso-8859-1] Sun Jan 5 16:06:16 2014 @@ -98,6 +98,60 @@ NTAPI LsaIFree_LSAPR_PRIVILEGE_SET(IN PLSAPR_PRIVILEGE_SET Ptr); +typedef wchar_t *PSAMPR_SERVER_NAME; +typedef void *SAMPR_HANDLE; + +typedef struct _SAMPR_ULONG_ARRAY +{ + unsigned long Count; + unsigned long *Element; +} SAMPR_ULONG_ARRAY, *PSAMPR_ULONG_ARRAY; + +typedef struct _SAMPR_SID_INFORMATION +{ + PRPC_SID SidPointer; +} SAMPR_SID_INFORMATION, *PSAMPR_SID_INFORMATION; + +typedef struct _SAMPR_PSID_ARRAY +{ + unsigned long Count; + PSAMPR_SID_INFORMATION Sids; +} SAMPR_PSID_ARRAY, *PSAMPR_PSID_ARRAY; + +NTSTATUS +NTAPI +SamIConnect( + PSAMPR_SERVER_NAME ServerName, + SAMPR_HANDLE *ServerHandle, + ACCESS_MASK DesiredAccess, + BOOLEAN Trusted); + +VOID +NTAPI +SamIFree_SAMPR_ULONG_ARRAY( + PSAMPR_ULONG_ARRAY Ptr); + +NTSTATUS +__stdcall +SamrCloseHandle( + SAMPR_HANDLE *SamHandle); + +NTSTATUS +__stdcall +SamrOpenDomain( + SAMPR_HANDLE ServerHandle, + ACCESS_MASK DesiredAccess, + PRPC_SID DomainId, + SAMPR_HANDLE *DomainHandle); + +NTSTATUS +__stdcall +SamrGetAliasMembership( + SAMPR_HANDLE DomainHandle, + PSAMPR_PSID_ARRAY SidArray, + PSAMPR_ULONG_ARRAY Membership); + + /* GLOBALS *****************************************************************/ static LIST_ENTRY PackageListHead; @@ -852,6 +906,223 @@ FIXME("TokenInformationType %d is not supported!\n", TokenInformationType); return STATUS_NOT_IMPLEMENTED; } + + return STATUS_SUCCESS; +} + + +static +NTSTATUS +LsapAppendSidToGroups( + IN PTOKEN_GROUPS *TokenGroups, + IN PSID DomainSid, + IN ULONG RelativeId) +{ + PTOKEN_GROUPS Groups; + PSID Sid; + ULONG Length; + ULONG i; + + Sid = LsapAppendRidToSid(DomainSid, RelativeId); + if (Sid == NULL) + { + ERR("Group SID creation failed!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (*TokenGroups == NULL) + { + Length = sizeof(TOKEN_GROUPS) + + (1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); + + Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); + if (Groups == NULL) + { + ERR("Group buffer allocation failed!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Groups->GroupCount = 1; + + Groups->Groups[0].Sid = Sid; + Groups->Groups[0].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + *TokenGroups = Groups; + } + else + { + for (i = 0; i < (*TokenGroups)->GroupCount; i++) + { + if (RtlEqualSid((*TokenGroups)->Groups[i].Sid, Sid)) + { + RtlFreeHeap(RtlGetProcessHeap(), 0, Sid); + return STATUS_SUCCESS; + } + } + + Length = sizeof(TOKEN_GROUPS) + + ((*TokenGroups)->GroupCount + 1 - ANYSIZE_ARRAY) * sizeof(SID_AND_ATTRIBUTES); + + Groups = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); + if (Groups == NULL) + { + ERR("Group buffer allocation failed!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Groups->GroupCount = (*TokenGroups)->GroupCount; + + for (i = 0; i < (*TokenGroups)->GroupCount; i++) + { + Groups->Groups[i].Sid = (*TokenGroups)->Groups[i].Sid; + Groups->Groups[i].Attributes = (*TokenGroups)->Groups[i].Attributes; + } + + Groups->Groups[Groups->GroupCount].Sid = Sid; + Groups->Groups[Groups->GroupCount].Attributes = + SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; + + Groups->GroupCount++; + + RtlFreeHeap(RtlGetProcessHeap(), 0, *TokenGroups); + + *TokenGroups = Groups; + } + + return STATUS_SUCCESS; +} + + +static +NTSTATUS +LsapAddSamGroups( + IN PVOID TokenInformation, + IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType) +{ + PLSA_TOKEN_INFORMATION_V1 TokenInfo1; + SAMPR_HANDLE ServerHandle = NULL; + SAMPR_HANDLE BuiltinDomainHandle = NULL; + SAMPR_HANDLE AccountDomainHandle = NULL; + SAMPR_PSID_ARRAY SidArray; + SAMPR_ULONG_ARRAY BuiltinMembership; + SAMPR_ULONG_ARRAY AccountMembership; + ULONG i; + NTSTATUS Status = STATUS_SUCCESS; + + if (TokenInformationType != LsaTokenInformationV1) + return STATUS_SUCCESS; + + TokenInfo1 = (PLSA_TOKEN_INFORMATION_V1)TokenInformation; + + SidArray.Count = TokenInfo1->Groups->GroupCount + 1; + SidArray.Sids = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + (TokenInfo1->Groups->GroupCount + 1) * sizeof(PRPC_SID)); + if (SidArray.Sids == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + SidArray.Sids[0].SidPointer = TokenInfo1->User.User.Sid; + for (i = 0; i < TokenInfo1->Groups->GroupCount; i++) + SidArray.Sids[i + 1].SidPointer = TokenInfo1->Groups->Groups[i].Sid; + + Status = SamIConnect(NULL, + &ServerHandle, + SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, + FALSE); + if (!NT_SUCCESS(Status)) + { + TRACE("SamIConnect failed (Status %08lx)\n", Status); + goto done; + } + + Status = SamrOpenDomain(ServerHandle, + DOMAIN_GET_ALIAS_MEMBERSHIP, + BuiltinDomainSid, + &BuiltinDomainHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SamrOpenDomain failed (Status %08lx)\n", Status); + goto done; + } + + Status = SamrOpenDomain(ServerHandle, + DOMAIN_GET_ALIAS_MEMBERSHIP, + AccountDomainSid, + &AccountDomainHandle); + if (!NT_SUCCESS(Status)) + { + TRACE("SamrOpenDomain failed (Status %08lx)\n", Status); + goto done; + } + + BuiltinMembership.Element = NULL; + Status = SamrGetAliasMembership(BuiltinDomainHandle, + &SidArray, + &BuiltinMembership); + if (!NT_SUCCESS(Status)) + { + TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status); + goto done; + } + + AccountMembership.Element = NULL; + Status = SamrGetAliasMembership(AccountDomainHandle, + &SidArray, + &AccountMembership); + if (!NT_SUCCESS(Status)) + { + TRACE("SamrGetAliasMembership failed (Status %08lx)\n", Status); + goto done; + } + + TRACE("Builtin Memberships: %lu\n", BuiltinMembership.Count); + for (i = 0; i < BuiltinMembership.Count; i++) + { + TRACE("RID %lu: %lu (0x%lx)\n", i, BuiltinMembership.Element[i], BuiltinMembership.Element[i]); + Status = LsapAppendSidToGroups(&TokenInfo1->Groups, + BuiltinDomainSid, + BuiltinMembership.Element[i]); + if (!NT_SUCCESS(Status)) + { + TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status); + goto done; + } + } + + TRACE("Account Memberships: %lu\n", AccountMembership.Count); + for (i = 0; i < AccountMembership.Count; i++) + { + TRACE("RID %lu: %lu (0x%lx)\n", i, AccountMembership.Element[i], AccountMembership.Element[i]); + Status = LsapAppendSidToGroups(&TokenInfo1->Groups, + AccountDomainSid, + AccountMembership.Element[i]); + if (!NT_SUCCESS(Status)) + { + TRACE("LsapAppendSidToGroups failed (Status %08lx)\n", Status); + goto done; + } + } + +done: + RtlFreeHeap(RtlGetProcessHeap(), 0, SidArray.Sids); + + if (AccountMembership.Element != NULL) + SamIFree_SAMPR_ULONG_ARRAY(&AccountMembership); + + if (BuiltinMembership.Element != NULL) + SamIFree_SAMPR_ULONG_ARRAY(&BuiltinMembership); + + if (AccountDomainHandle != NULL) + SamrCloseHandle(&AccountDomainHandle); + + if (BuiltinDomainHandle != NULL) + SamrCloseHandle(&BuiltinDomainHandle); + + if (ServerHandle != NULL) + SamrCloseHandle(&ServerHandle); + +// return Status; return STATUS_SUCCESS; } @@ -1231,6 +1502,14 @@ goto done; } + Status = LsapAddSamGroups(TokenInformation, + TokenInformationType); + if (!NT_SUCCESS(Status)) + { + ERR("LsapAddSamGroups() failed (Status 0x%08lx)\n", Status); + goto done; + } + Status = LsapSetTokenOwner(TokenInformation, TokenInformationType); if (!NT_SUCCESS(Status)) Modified: trunk/reactos/dll/win32/lsasrv/lsasrv.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/lsasrv/lsasrv.h?…
============================================================================== --- trunk/reactos/dll/win32/lsasrv/lsasrv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/lsasrv/lsasrv.h [iso-8859-1] Sun Jan 5 16:06:16 2014 @@ -415,4 +415,9 @@ LPWSTR lpBuffer, INT nBufferMax); +PSID +LsapAppendRidToSid( + PSID SrcSid, + ULONG Rid); + /* EOF */ Modified: trunk/reactos/dll/win32/lsasrv/utils.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/lsasrv/utils.c?r…
============================================================================== --- trunk/reactos/dll/win32/lsasrv/utils.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/lsasrv/utils.c [iso-8859-1] Sun Jan 5 16:06:16 2014 @@ -57,4 +57,40 @@ return i; } + +PSID +LsapAppendRidToSid( + PSID SrcSid, + ULONG Rid) +{ + ULONG Rids[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + UCHAR RidCount; + PSID DstSid; + ULONG i; + + RidCount = *RtlSubAuthorityCountSid(SrcSid); + if (RidCount >= 8) + return NULL; + + for (i = 0; i < RidCount; i++) + Rids[i] = *RtlSubAuthoritySid(SrcSid, i); + + Rids[RidCount] = Rid; + RidCount++; + + RtlAllocateAndInitializeSid(RtlIdentifierAuthoritySid(SrcSid), + RidCount, + Rids[0], + Rids[1], + Rids[2], + Rids[3], + Rids[4], + Rids[5], + Rids[6], + Rids[7], + &DstSid); + + return DstSid; +} + /* EOF */ Modified: trunk/reactos/dll/win32/msv1_0/msv1_0.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msv1_0/msv1_0.c?…
============================================================================== --- trunk/reactos/dll/win32/msv1_0/msv1_0.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/msv1_0/msv1_0.c [iso-8859-1] Sun Jan 5 16:06:16 2014 @@ -291,7 +291,7 @@ { SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY}; PTOKEN_GROUPS TokenGroups; -#define MAX_GROUPS 4 +#define MAX_GROUPS 2 DWORD GroupCount = 0; PSID Sid; NTSTATUS Status = STATUS_SUCCESS; @@ -310,45 +310,6 @@ } /* Member of the domain */ - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; - - -#if 1 - /* Member of 'Administrators' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); - TokenGroups->Groups[GroupCount].Sid = Sid; - TokenGroups->Groups[GroupCount].Attributes = - SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY; - GroupCount++; -#else - TRACE("Not adding user to Administrators group\n"); -#endif - - /* Member of 'Users' */ - RtlAllocateAndInitializeSid(&SystemAuthority, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_USERS, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - SECURITY_NULL_RID, - &Sid); TokenGroups->Groups[GroupCount].Sid = Sid; TokenGroups->Groups[GroupCount].Attributes = SE_GROUP_ENABLED | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_MANDATORY;
10 years, 11 months
1
0
0
0
[hbelusca] 61538: [NTVDM] Fix changing console size when entering a given text-mode. Inspired from our telnet console tconsole.cpp!SetWindowSize function. Part 1/2
by hbelusca@svn.reactos.org
Author: hbelusca Date: Sun Jan 5 14:14:26 2014 New Revision: 61538 URL:
http://svn.reactos.org/svn/reactos?rev=61538&view=rev
Log: [NTVDM] Fix changing console size when entering a given text-mode. Inspired from our telnet console tconsole.cpp!SetWindowSize function. Part 1/2 Modified: branches/ntvdm/subsystems/ntvdm/vga.c Modified: branches/ntvdm/subsystems/ntvdm/vga.c URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/vga.c?re…
============================================================================== --- branches/ntvdm/subsystems/ntvdm/vga.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/vga.c [iso-8859-1] Sun Jan 5 14:14:26 2014 @@ -171,6 +171,9 @@ #endif +static HANDLE VgaSavedConsoleHandle = NULL; +static CONSOLE_SCREEN_BUFFER_INFO VgaSavedConsoleInfo; + static BYTE VgaMemory[VGA_NUM_BANKS * VGA_BANK_SIZE]; static LPVOID ConsoleFramebuffer = NULL; static HANDLE TextConsoleBuffer = NULL; @@ -605,11 +608,11 @@ static VOID VgaLeaveGraphicsMode(VOID) { - /* Release the console framebuffer mutex if needed */ + /* Release the console framebuffer mutex */ ReleaseMutex(ConsoleMutex); - /* Switch back to the text buffer */ - SetConsoleActiveScreenBuffer(TextConsoleBuffer); + /* Switch back to the default console buffer */ + // SetConsoleActiveScreenBuffer(VgaSavedConsoleHandle); /* Cleanup the video data */ CloseHandle(ConsoleMutex); @@ -621,8 +624,29 @@ static BOOL VgaEnterTextMode(PCOORD Resolution) { + SMALL_RECT ConRect; + + /* Switch to the text buffer */ + SetConsoleActiveScreenBuffer(TextConsoleBuffer); + /* Resize the console */ + ConRect.Left = 0; // VgaSavedConsoleInfo.srWindow.Left; + ConRect.Top = VgaSavedConsoleInfo.srWindow.Top; + ConRect.Right = ConRect.Left + Resolution->X - 1; + ConRect.Bottom = ConRect.Top + Resolution->Y - 1; + /* + * Use this trick to effectively resize the console buffer and window, + * because: + * - SetConsoleScreenBufferSize fails if the new console screen buffer size + * is smaller than the current console window size, and: + * - SetConsoleWindowInfo fails if the new console window size is larger + * than the current console screen buffer size. + */ SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution); + SetConsoleWindowInfo(TextConsoleBuffer, TRUE, &ConRect); + SetConsoleScreenBufferSize(TextConsoleBuffer, *Resolution); + /* Update the saved console information */ + GetConsoleScreenBufferInfo(TextConsoleBuffer, &VgaSavedConsoleInfo); /* Allocate a framebuffer */ ConsoleFramebuffer = HeapAlloc(GetProcessHeap(), @@ -693,7 +717,7 @@ } else { - /* Enter 8-bit graphics mode */ + /* Enter graphics mode */ if (!VgaEnterGraphicsMode(&Resolution)) { DisplayMessage(L"An unexpected VGA error occurred while switching into graphics mode."); @@ -1478,12 +1502,24 @@ DWORD Address = 0; DWORD CurrentAddr; + /* Save the console information */ + if (TextHandle == INVALID_HANDLE_VALUE) return FALSE; + VgaSavedConsoleHandle = TextHandle; + if (!GetConsoleScreenBufferInfo(VgaSavedConsoleHandle, + &VgaSavedConsoleInfo)) + { + return FALSE; + } + /* Initialize the VGA palette and fail if it isn't successfully created */ if (!VgaInitializePalette()) return FALSE; /***/ VgaResetPalette(); /***/ - /* Set the global handle */ + /* Save the default text-mode console output handle */ TextConsoleBuffer = TextHandle; + + /* Clear the VGA memory */ + VgaClearMemory(); /* Register the I/O Ports */ RegisterIoPort(0x3CC, VgaReadPort, NULL); // VGA_MISC_READ @@ -1500,9 +1536,6 @@ RegisterIoPort(0x3CE, VgaReadPort, VgaWritePort); // VGA_GC_INDEX RegisterIoPort(0x3CF, VgaReadPort, VgaWritePort); // VGA_GC_DATA - /* Clear the VGA memory */ - VgaClearMemory(); - /* Set the default video mode */ BiosSetVideoMode(BIOS_DEFAULT_VIDEO_MODE); VgaChangeMode(); @@ -1512,7 +1545,7 @@ CharBuffer = (PCHAR_INFO)ConsoleFramebuffer; AddressSize = VgaGetAddressSize(); ScreenRect.Left = ScreenRect.Top = 0; - ScreenRect.Right = Resolution.X; + ScreenRect.Right = Resolution.X; ScreenRect.Bottom = Resolution.Y; ScanlineSize = (DWORD)VgaCrtcRegisters[VGA_CRTC_OFFSET_REG] * 2;
10 years, 11 months
1
0
0
0
[akhaldi] 61537: [SHELL32] * Move shell file operations to background threads to prevent the shell from hanging during long copies, deletes, and moves. * Improve drag and drop functionality. * Add ...
by akhaldi@svn.reactos.org
Author: akhaldi Date: Sun Jan 5 12:48:42 2014 New Revision: 61537 URL:
http://svn.reactos.org/svn/reactos?rev=61537&view=rev
Log: [SHELL32] * Move shell file operations to background threads to prevent the shell from hanging during long copies, deletes, and moves. * Improve drag and drop functionality. * Add a partial drop handler to the recycle bin. * Brought to you by Huw Campbell. CORE-3760 Modified: trunk/reactos/dll/win32/shell32/defcontextmenu.cpp trunk/reactos/dll/win32/shell32/folders/fs.cpp trunk/reactos/dll/win32/shell32/folders/fs.h trunk/reactos/dll/win32/shell32/folders/recyclebin.cpp trunk/reactos/dll/win32/shell32/folders/recyclebin.h trunk/reactos/dll/win32/shell32/shlview.cpp Modified: trunk/reactos/dll/win32/shell32/defcontextmenu.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/defconte…
============================================================================== --- trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/defcontextmenu.cpp [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -1037,7 +1037,6 @@ } SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL); - NotifyShellViewWindow(lpcmi, TRUE); TRACE("CP result %x\n", hr); return S_OK; @@ -1104,73 +1103,24 @@ ERR("no IDropTarget Interface\n"); return hr; } - //DWORD link = DROPEFFECT_LINK; SHSimulateDrop(pDT, pDataObj, MK_CONTROL|MK_SHIFT, NULL, NULL); - NotifyShellViewWindow(lpcmi, TRUE); return S_OK; } -HRESULT -CDefaultContextMenu::DoDelete( - LPCMINVOKECOMMANDINFO lpcmi) -{ - STRRET strTemp; - HRESULT hr = m_Dcm.psf->GetDisplayNameOf(m_Dcm.apidl[0], SHGDN_FORPARSING, &strTemp); - if(hr != S_OK) - { - ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr); - return hr; - } - - WCHAR wszPath[MAX_PATH]; - hr = StrRetToBufW(&strTemp, m_Dcm.apidl[0], wszPath, _countof(wszPath)); - if (hr != S_OK) - { - ERR("StrRetToBufW failed with %x\n", hr); - return hr; - } - - /* Only keep the base path */ - LPWSTR pwszFilename = PathFindFileNameW(wszPath); - *pwszFilename = L'\0'; - - /* Build paths list */ - LPWSTR pwszPaths = BuildPathsList(wszPath, m_Dcm.cidl, m_Dcm.apidl); - if (!pwszPaths) +HRESULT CDefaultContextMenu::DoDelete(LPCMINVOKECOMMANDINFO lpcmi) { + TRACE("(%p) Deleting\n", this); + + LPDATAOBJECT pDataObj; + + if (SUCCEEDED(SHCreateDataObject(m_Dcm.pidlFolder, m_Dcm.cidl, m_Dcm.apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj)))) + { + pDataObj->AddRef(); + SHCreateThread(DoDeleteThreadProc, pDataObj, NULL, NULL); + pDataObj->Release(); + } + else return E_FAIL; - - /* Delete them */ - SHFILEOPSTRUCTW FileOp; - ZeroMemory(&FileOp, sizeof(FileOp)); - FileOp.hwnd = GetActiveWindow(); - FileOp.wFunc = FO_DELETE; - FileOp.pFrom = pwszPaths; - FileOp.fFlags = FOF_ALLOWUNDO; - - if (SHFileOperationW(&FileOp) != 0) - { - ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(pwszPaths)); - return S_OK; - } - - /* Get the active IShellView */ - LPSHELLBROWSER lpSB = (LPSHELLBROWSER)SendMessageW(lpcmi->hwnd, CWM_GETISHELLBROWSER, 0, 0); - if (lpSB) - { - /* Is the treeview focused */ - HWND hwnd; - if (SUCCEEDED(lpSB->GetControlWindow(FCW_TREE, &hwnd))) - { - /* Remove selected items from treeview */ - HTREEITEM hItem = TreeView_GetSelection(hwnd); - if (hItem) - (void)TreeView_DeleteItem(hwnd, hItem); - } - } - NotifyShellViewWindow(lpcmi, TRUE); - - HeapFree(GetProcessHeap(), 0, pwszPaths); return S_OK; } Modified: trunk/reactos/dll/win32/shell32/folders/fs.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
============================================================================== --- trunk/reactos/dll/win32/shell32/folders/fs.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/fs.cpp [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -1419,6 +1419,27 @@ { TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect); + _DoDropData *data = reinterpret_cast<_DoDropData*> (HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData))); + data->This = this; + // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder). + data->This->AddRef(); + data->pDataObject = pDataObject; + // Also keep the data object in case it gets freed elsewhere. + data->pDataObject->AddRef(); + data->dwKeyState = dwKeyState; + data->pt = pt; + // Need to dereference as pdweffect is freed. + data->pdwEffect = *pdwEffect; + + SHCreateThread(reinterpret_cast<LPTHREAD_START_ROUTINE> (CFSFolder::_DoDropThreadProc), reinterpret_cast<void *> (data), NULL, NULL); + return S_OK; +} + +HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject, + DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) +{ + TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect); + HRESULT hr; bool bCopy = TRUE; bool bLinking = FALSE; @@ -1451,9 +1472,9 @@ if (pdwEffect) { TRACE("Current drop effect flag %i\n", *pdwEffect); - if (*pdwEffect & DROPEFFECT_MOVE) + if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE) bCopy = FALSE; - if (*pdwEffect & DROPEFFECT_LINK) + if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK) bLinking = TRUE; } @@ -1631,5 +1652,12 @@ } DWORD CFSFolder::_DoDropThreadProc(LPVOID lpParameter) { + _DoDropData *data = reinterpret_cast<_DoDropData*>(lpParameter); + data->This->_DoDrop(data->pDataObject, data->dwKeyState, data->pt, &data->pdwEffect); + //Release the CFSFolder and data object holds in the copying thread. + data->pDataObject->Release(); + data->This->Release(); + //Release the parameter from the heap. + HeapFree(GetProcessHeap(), 0, data); return 0; } Modified: trunk/reactos/dll/win32/shell32/folders/fs.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
============================================================================== --- trunk/reactos/dll/win32/shell32/folders/fs.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/fs.h [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -46,7 +46,8 @@ BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect); void SF_RegisterClipFmt(); BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut); - DWORD _DoDropThreadProc(LPVOID lpParameter); + static DWORD _DoDropThreadProc(LPVOID lpParameter); + virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect); public: CFSFolder(); @@ -116,4 +117,12 @@ END_COM_MAP() }; +struct _DoDropData { + CFSFolder *This; + IDataObject *pDataObject; + DWORD dwKeyState; + POINTL pt; + DWORD pdwEffect; +}; + #endif // _CFSFOLDER_H_ Modified: trunk/reactos/dll/win32/shell32/folders/recyclebin.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
============================================================================== --- trunk/reactos/dll/win32/shell32/folders/recyclebin.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/recyclebin.cpp [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -429,10 +429,24 @@ return S_OK; } +/************************************************************************** +* registers clipboardformat once +*/ +void CRecycleBin::SF_RegisterClipFmt() +{ + TRACE ("(%p)\n", this); + + if (!cfShellIDList) + cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); +} + CRecycleBin::CRecycleBin() { pidl = NULL; iIdEmpty = 0; + cfShellIDList = 0; + SF_RegisterClipFmt(); + fAcceptFmt = FALSE; } CRecycleBin::~CRecycleBin() @@ -556,8 +570,7 @@ if (IsEqualIID (riid, IID_IDropTarget)) { - WARN ("IDropTarget not implemented\n"); - hr = E_NOTIMPL; + hr = this->QueryInterface (IID_IDropTarget, ppv); } else if (IsEqualIID (riid, IID_IContextMenu) || IsEqualIID (riid, IID_IContextMenu2)) { @@ -605,7 +618,7 @@ { hr = CRecycleBinItemContextMenuConstructor(riid, apidl[0], (void **)&pObj); } - else if (IsEqualIID (riid, IID_IDropTarget) && (cidl >= 1)) + else if (IsEqualIID (riid, IID_IDropTarget) && (cidl == 1)) { hr = this->QueryInterface(IID_IDropTarget, (LPVOID *) & pObj); } @@ -1372,3 +1385,214 @@ return S_OK; } + +/**************************************************************************** + * IDropTarget implementation + */ +BOOL CRecycleBin::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect) +{ + /* TODO on shift we should delete, we should update the cursor manager to show this. */ + + DWORD dwEffect = DROPEFFECT_COPY; + + *pdwEffect = DROPEFFECT_NONE; + + if (fAcceptFmt) { /* Does our interpretation of the keystate ... */ + *pdwEffect = KeyStateToDropEffect (dwKeyState); + + if (*pdwEffect == DROPEFFECT_NONE) + *pdwEffect = dwEffect; + + /* ... matches the desired effect ? */ + if (dwEffect & *pdwEffect) { + return TRUE; + } + } + return FALSE; +} + +HRESULT WINAPI CRecycleBin::DragEnter(IDataObject *pDataObject, + DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) +{ + FIXME("Recycle bin drag over (%p)\n", this); + /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */ + fAcceptFmt = TRUE; + + QueryDrop(dwKeyState, pdwEffect); + return S_OK; +} + +HRESULT WINAPI CRecycleBin::DragOver(DWORD dwKeyState, POINTL pt, + DWORD *pdwEffect) +{ + TRACE("(%p)\n", this); + + if (!pdwEffect) + return E_INVALIDARG; + + QueryDrop(dwKeyState, pdwEffect); + + return S_OK; +} + +HRESULT WINAPI CRecycleBin::DragLeave() +{ + TRACE("(%p)\n", this); + + fAcceptFmt = FALSE; + + return S_OK; +} + +HRESULT WINAPI CRecycleBin::Drop(IDataObject *pDataObject, + DWORD dwKeyState, POINTL pt, DWORD *pdwEffect) +{ + FIXME("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect); + + /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */ + + FORMATETC fmt; + TRACE("(%p)->(DataObject=%p)\n", this, pDataObject); + InitFormatEtc (fmt, cfShellIDList, TYMED_HGLOBAL); + + /* Handle cfShellIDList Drop objects here, otherwise send the approriate message to other software */ + if (SUCCEEDED(pDataObject->QueryGetData(&fmt))) { + pDataObject->AddRef(); + SHCreateThread(DoDeleteThreadProc, pDataObject, NULL, NULL); + } + else + { + /* + * TODO call SetData on the data object with format CFSTR_TARGETCLSID + * set to the Recycle Bin's class identifier CLSID_RecycleBin. + */ + } + return S_OK; +} + +DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter) +{ + IDataObject *pda = (IDataObject*) lpParameter; + DoDeleteDataObject(pda); + //Release the data object + pda->Release(); + return 0; +} + +HRESULT WINAPI DoDeleteDataObject(IDataObject *pda) +{ + TRACE("performing delete"); + HRESULT hr; + + STGMEDIUM medium; + FORMATETC formatetc; + InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); + hr = pda->GetData(&formatetc, &medium); + if (FAILED(hr)) + return hr; + + /* lock the handle */ + LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal); + if (!lpcida) + { + ReleaseStgMedium(&medium); + return E_FAIL; + } + + /* convert the data into pidl */ + LPITEMIDLIST pidl; + LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida); + if (!apidl) + { + ReleaseStgMedium(&medium); + return E_FAIL; + } + + CComPtr<IShellFolder> psfDesktop; + CComPtr<IShellFolder> psfFrom = NULL; + + /* Grab the desktop shell folder */ + hr = SHGetDesktopFolder(&psfDesktop); + if (FAILED(hr)) + { + ERR("SHGetDesktopFolder failed\n"); + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + return E_FAIL; + } + + /* Find source folder, this is where the clipboard data was copied from */ + if (_ILIsDesktop(pidl)) + { + psfFrom = psfDesktop; + } + else + { + hr = psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID*)&psfFrom); + if (FAILED(hr)) + { + ERR("no IShellFolder\n"); + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + return E_FAIL; + } + } + + STRRET strTemp; + hr = psfFrom->GetDisplayNameOf(apidl[0], SHGDN_FORPARSING, &strTemp); + if (FAILED(hr)) + { + ERR("IShellFolder_GetDisplayNameOf failed with %x\n", hr); + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + return hr; + } + + WCHAR wszPath[MAX_PATH]; + hr = StrRetToBufW(&strTemp, apidl[0], wszPath, _countof(wszPath)); + if (FAILED(hr)) + { + ERR("StrRetToBufW failed with %x\n", hr); + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + return hr; + } + + /* Only keep the base path */ + LPWSTR pwszFilename = PathFindFileNameW(wszPath); + *pwszFilename = L'\0'; + + /* Build paths list */ + LPWSTR pwszPaths = BuildPathsList(wszPath, lpcida->cidl, (LPCITEMIDLIST*) apidl); + if (!pwszPaths) + { + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + return E_FAIL; + } + + /* Delete them */ + SHFILEOPSTRUCTW FileOp; + ZeroMemory(&FileOp, sizeof(FileOp)); + FileOp.wFunc = FO_DELETE; + FileOp.pFrom = pwszPaths; + FileOp.fFlags = FOF_ALLOWUNDO; + + if (SHFileOperationW(&FileOp) != 0) + { + ERR("SHFileOperation failed with 0x%x for %s\n", GetLastError(), debugstr_w(pwszPaths)); + hr = E_FAIL; + } + + HeapFree(GetProcessHeap(), 0, pwszPaths); + SHFree(pidl); + _ILFreeaPidl(apidl, lpcida->cidl); + ReleaseStgMedium(&medium); + + return hr; +} Modified: trunk/reactos/dll/win32/shell32/folders/recyclebin.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/folders/…
============================================================================== --- trunk/reactos/dll/win32/shell32/folders/recyclebin.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/folders/recyclebin.h [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -22,6 +22,9 @@ #ifndef _SHFLDR_RECYCLEBIN_H_ #define _SHFLDR_RECYCLEBIN_H_ +DWORD WINAPI DoDeleteThreadProc(LPVOID lpParameter); +HRESULT WINAPI DoDeleteDataObject(IDataObject *pda); + class CRecycleBin : public CComCoClass<CRecycleBin, &CLSID_RecycleBin>, public CComObjectRootEx<CComMultiThreadModelNoCS>, @@ -29,11 +32,16 @@ public IPersistFolder2, public IContextMenu, public IShellPropSheetExt, + public IDropTarget, public IShellExtInit { private: LPITEMIDLIST pidl; INT iIdEmpty; + UINT cfShellIDList; + void SF_RegisterClipFmt(); + BOOL fAcceptFmt; /* flag for pending Drop */ + BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect); public: CRecycleBin(); @@ -75,6 +83,12 @@ // IShellPropSheetExt virtual HRESULT WINAPI AddPages(LPFNSVADDPROPSHEETPAGE pfnAddPage, LPARAM lParam); virtual HRESULT WINAPI ReplacePage(EXPPS uPageID, LPFNSVADDPROPSHEETPAGE pfnReplaceWith, LPARAM lParam); + + // IDropTarget + virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect); + virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect); + virtual HRESULT WINAPI DragLeave(); + virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect); // IShellExtInit virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID); @@ -91,6 +105,7 @@ COM_INTERFACE_ENTRY_IID(IID_IShellFolder2, IShellFolder2) COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu) COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt) + COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget) COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit) END_COM_MAP() }; Modified: trunk/reactos/dll/win32/shell32/shlview.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shlview.…
============================================================================== --- trunk/reactos/dll/win32/shell32/shlview.cpp [iso-8859-1] (original) +++ trunk/reactos/dll/win32/shell32/shlview.cpp [iso-8859-1] Sun Jan 5 12:48:42 2014 @@ -1691,8 +1691,6 @@ { DWORD dwEffect2; DoDragDrop(pda, pds, dwEffect, &dwEffect2); - if ((dwEffect2 & DROPEFFECT_MOVE) == DROPEFFECT_MOVE) - this->Refresh(); } pda->Release(); }
10 years, 11 months
1
0
0
0
[ekohl] 61536: [SAMSRV] SamrGetAliasMembership: Do not overwrite enties of the RID array.
by ekohl@svn.reactos.org
Author: ekohl Date: Sun Jan 5 12:00:16 2014 New Revision: 61536 URL:
http://svn.reactos.org/svn/reactos?rev=61536&view=rev
Log: [SAMSRV] SamrGetAliasMembership: Do not overwrite enties of the RID array. Modified: trunk/reactos/dll/win32/samsrv/samrpc.c Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?…
============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sun Jan 5 12:00:16 2014 @@ -3250,6 +3250,7 @@ ULONG ValueCount; ULONG DataLength; ULONG i, j; + ULONG RidIndex; NTSTATUS Status; WCHAR NameBuffer[9]; @@ -3334,6 +3335,7 @@ goto done; } + RidIndex = 0; for (i = 0; i < SidArray->Count; i++) { ConvertSidToStringSid(SidArray->Sids[i].SidPointer, &MemberSidString); @@ -3365,7 +3367,9 @@ NULL); if (NT_SUCCESS(Status)) { - RidArray[j] = wcstoul(NameBuffer, NULL, 16); + /* FIXME: Do not return each RID more than once. */ + RidArray[RidIndex] = wcstoul(NameBuffer, NULL, 16); + RidIndex++; } } }
10 years, 11 months
1
0
0
0
← Newer
1
...
33
34
35
36
37
38
39
...
43
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Results per page:
10
25
50
100
200