diff --git a/base/applications/rapps/rapps/firefox36.txt b/base/applications/rapps/rapps/firefox36.txt index cff4b21274c..92b7a75b809 100644 --- a/base/applications/rapps/rapps/firefox36.txt +++ b/base/applications/rapps/rapps/firefox36.txt @@ -2,47 +2,47 @@ [Section] Name = Mozilla Firefox 3.6 -Version = 3.6.10 +Version = 3.6.11 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Web Browsers out there. Size = 8.1M Category = 5 URLSite = http://www.mozilla.com/en-US/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/en-US/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/en-US/Firefox%20Setup%203.6.11.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Webbrowser. Size = 8.0M URLSite = http://www.mozilla-europe.org/de/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/de/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/de/Firefox%20Setup%203.6.11.exe [Section.040a] Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Size = 8.0M URLSite = http://www.mozilla-europe.org/es/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/es-ES/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/es-ES/Firefox%20Setup%203.6.11.exe [Section.0414] Description = Mest populære og best også gratis nettleserene der ute. Size = 8.0M URLSite = http://www.mozilla-europe.org/no/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/nb-NO/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/nb-NO/Firefox%20Setup%203.6.11.exe [Section.0415] Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych. Size = 8.8M URLSite = http://www.mozilla-europe.org/pl/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/pl/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/pl/Firefox%20Setup%203.6.11.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных браузеров. Size = 8.4M URLSite = http://www.mozilla-europe.org/ru/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/ru/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/ru/Firefox%20Setup%203.6.11.exe [Section.0422] Description = Найпопулярніший та один з кращих безплатних веб-браузерів. Size = 8.4M URLSite = http://www.mozilla-europe.org/uk/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.10/win32/uk/Firefox%20Setup%203.6.10.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.11/win32/uk/Firefox%20Setup%203.6.11.exe diff --git a/base/applications/rapps/rapps/libreoffice.txt b/base/applications/rapps/rapps/libreoffice.txt index 8edeb91de0a..f9d6959ff15 100644 --- a/base/applications/rapps/rapps/libreoffice.txt +++ b/base/applications/rapps/rapps/libreoffice.txt @@ -2,13 +2,13 @@ [Section] Name = LibreOffice -Version = 3.3.0 Beta 1 +Version = 3.3.0 Beta 2 Licence = LGPL Description = Former called OpenOffice. Open Source Office Suite. -Size = 138.0MB +Size = 318.0MB Category = 6 URLSite = http://www.documentfoundation.org/ -URLDownload = http://download.documentfoundation.org/libreoffice/testing/LO_3.3.0-beta1_Win_x86_install_en-US.exe +URLDownload = http://download.documentfoundation.org/libreoffice/testing/3.3.0-beta2/win/x86/LibO_3.3.0_beta2_Win_x86_install_multi.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/mirandaim.txt b/base/applications/rapps/rapps/mirandaim.txt index 5c9fc34a53a..8cc6b8ee29e 100644 --- a/base/applications/rapps/rapps/mirandaim.txt +++ b/base/applications/rapps/rapps/mirandaim.txt @@ -2,13 +2,13 @@ [Section] Name = Miranda IM -Version = 0.9.5 +Version = 0.9.8 Licence = GPL Description = Open source multiprotocol instant messaging application - May not work completely. -Size = 2.2MB +Size = 3.0MB Category = 5 URLSite = http://www.miranda-im.org/ -URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.5-unicode.exe +URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.8-unicode.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/mirc.txt b/base/applications/rapps/rapps/mirc.txt index 695630a24e0..83a74f3b307 100644 --- a/base/applications/rapps/rapps/mirc.txt +++ b/base/applications/rapps/rapps/mirc.txt @@ -2,13 +2,13 @@ [Section] Name = mIRC -Version = 7.1 +Version = 7.14 Licence = Shareware Description = The most popular client for the Internet Relay Chat (IRC). -Size = 1.8M +Size = 2.0M Category = 5 URLSite = http://www.mirc.com/ -URLDownload = http://download.mirc.com/mirc71.exe +URLDownload = http://download.mirc.com/mirc714.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/opera.txt b/base/applications/rapps/rapps/opera.txt index 6852b4c8492..f16c517559b 100644 --- a/base/applications/rapps/rapps/opera.txt +++ b/base/applications/rapps/rapps/opera.txt @@ -2,13 +2,13 @@ [Section] Name = Opera -Version = 10.62 +Version = 10.63 Licence = Freeware Description = The popular Opera Browser with many advanced features and including a Mail and BitTorrent client. Size = 12.7M Category = 5 URLSite = http://www.opera.com/ -URLDownload = http://get4.opera.com/pub/opera/win/1062/int/Opera_1062_int_Setup.exe +URLDownload = http://get4.opera.com/pub/opera/win/1063/int/Opera_1063_int_Setup.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/scummvm.txt b/base/applications/rapps/rapps/scummvm.txt index 27747581a66..bc7286ea979 100644 --- a/base/applications/rapps/rapps/scummvm.txt +++ b/base/applications/rapps/rapps/scummvm.txt @@ -2,13 +2,13 @@ [Section] Name = ScummVM -Version = 1.1.1 +Version = 1.2.0 Licence = GPL Description = Sam and Max, Day of the Tentacle, etc on ReactOS. -Size = 3.3MB +Size = 3.5MB Category = 4 URLSite = http://scummvm.org/ -URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.1.1/scummvm-1.1.1-win32.exe +URLDownload = http://dfn.dl.sourceforge.net/project/scummvm/scummvm/1.2.0/scummvm-1.2.0-win32.exe CDPath = none [Section.0407] diff --git a/base/applications/rapps/rapps/seamonkey.txt b/base/applications/rapps/rapps/seamonkey.txt index 3dd172cfb9e..4544d24d0ac 100644 --- a/base/applications/rapps/rapps/seamonkey.txt +++ b/base/applications/rapps/rapps/seamonkey.txt @@ -2,31 +2,31 @@ [Section] Name = Mozilla SeaMonkey -Version = 2.0.8 +Version = 2.0.9 Licence = MPL/GPL/LGPL Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need. Size = 10.1MB Category = 5 URLSite = http://www.seamonkey-project.org/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/en-US/SeaMonkey%20Setup%202.0.8.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.9/win32/en-US/SeaMonkey%20Setup%202.0.9.exe CDPath = none [Section.0407] Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. Size = 10.0MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/de/SeaMonkey%20Setup%202.0.8.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.9/win32/de/SeaMonkey%20Setup%202.0.9.exe [Section.040a] Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás. Size = 10.0MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/es-ES/SeaMonkey%20Setup%202.0.8.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.9/win32/es-ES/SeaMonkey%20Setup%202.0.9.exe [Section.0415] Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz. Size = 10.8MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/pl/SeaMonkey%20Setup%202.0.8.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.9/win32/pl/SeaMonkey%20Setup%202.0.9.exe [Section.0419] Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор. Size = 10.4MB -URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.8/win32/ru/SeaMonkey%20Setup%202.0.8.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.9/win32/ru/SeaMonkey%20Setup%202.0.9.exe diff --git a/base/applications/rapps/rapps/thunderbird.txt b/base/applications/rapps/rapps/thunderbird.txt index 71dce2f44bc..0d3fa6e3d3d 100644 --- a/base/applications/rapps/rapps/thunderbird.txt +++ b/base/applications/rapps/rapps/thunderbird.txt @@ -2,41 +2,41 @@ [Section] Name = Mozilla Thunderbird -Version = 3.1.4 +Version = 3.1.5 Licence = MPL/GPL/LGPL Description = The most popular and one of the best free Mail Clients out there. Size = 9.0M Category = 5 URLSite = http://www.mozilla-europe.org/en/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/en-US/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/en-US/Thunderbird%20Setup%203.1.5.exe CDPath = none [Section.0407] Description = Der populärste und einer der besten freien Mail-Clients. Size = 8.8M URLSite = http://www.mozilla-europe.org/de/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/de/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/de/Thunderbird%20Setup%203.1.5.exe [Section.040a] Description = El más popular y uno de los mejores clientes mail que hay. Size = 8.8M URLSite = http://www.mozilla-europe.org/es/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/es-ES/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/es-ES/Thunderbird%20Setup%203.1.5.exe [Section.0415] Description = Najpopularniejszy i jeden z najlepszych darmowych klientów poczty. Size = 9.7M URLSite = http://www.mozilla-europe.org/pl/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/pl/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/pl/Thunderbird%20Setup%203.1.5.exe [Section.0419] Description = Один из самых популярных и лучших бесплатных почтовых клиентов. Size = 9.2M URLSite = http://www.mozilla-europe.org/ru/products/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/ru/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/ru/Thunderbird%20Setup%203.1.5.exe [Section.0422] Description = Найпопулярніший та один з кращих поштових клієнтів. Size = 9.2M URLSite = http://www.mozillamessaging.com/uk/thunderbird/ -URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.4/win32/uk/Thunderbird%20Setup%203.1.4.exe +URLDownload = http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.1.5/win32/uk/Thunderbird%20Setup%203.1.5.exe diff --git a/base/shell/explorer/desktop/desktop.cpp b/base/shell/explorer/desktop/desktop.cpp index aa63996e964..99b990bec39 100644 --- a/base/shell/explorer/desktop/desktop.cpp +++ b/base/shell/explorer/desktop/desktop.cpp @@ -435,6 +435,12 @@ LRESULT DesktopWindow::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) explorer_show_frame(SW_SHOWNORMAL); break; + case WM_DISPLAYCHANGE: + MoveWindow(_hwnd, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE); + MoveWindow(g_Globals._hwndShellView, 0, 0, LOWORD(lparam), HIWORD(lparam), TRUE); + MoveWindow(_desktopBar, 0, HIWORD(lparam) - DESKTOPBARBAR_HEIGHT, LOWORD(lparam), DESKTOPBARBAR_HEIGHT, TRUE); + break; + case WM_GETISHELLBROWSER: return (LRESULT)static_cast(this); diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c index b30b11ea07e..28bce05cb7d 100644 --- a/base/system/services/rpcserver.c +++ b/base/system/services/rpcserver.c @@ -31,9 +31,6 @@ typedef struct _SCMGR_HANDLE typedef struct _MANAGER_HANDLE { SCMGR_HANDLE Handle; - - /* FIXME: Insert more data here */ - WCHAR DatabaseName[1]; } MANAGER_HANDLE, *PMANAGER_HANDLE; @@ -41,11 +38,7 @@ typedef struct _MANAGER_HANDLE typedef struct _SERVICE_HANDLE { SCMGR_HANDLE Handle; - PSERVICE ServiceEntry; - - /* FIXME: Insert more data here */ - } SERVICE_HANDLE, *PSERVICE_HANDLE; @@ -149,7 +142,7 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName, if (lpDatabaseName == NULL) lpDatabaseName = SERVICES_ACTIVE_DATABASEW; - if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0) + if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0) { DPRINT("Database %S, does not exist\n",lpDatabaseName); return ERROR_DATABASE_DOES_NOT_EXIST; @@ -168,8 +161,6 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName, Ptr->Handle.Tag = MANAGER_TAG; - /* FIXME: initialize more data here */ - wcscpy(Ptr->DatabaseName, lpDatabaseName); *Handle = (SC_HANDLE)Ptr; @@ -192,7 +183,6 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry, Ptr->Handle.Tag = SERVICE_TAG; - /* FIXME: initialize more data here */ Ptr->ServiceEntry = lpServiceEntry; *Handle = (SC_HANDLE)Ptr; @@ -453,9 +443,10 @@ DWORD RCloseServiceHandle( if (*hSCObject == 0) return ERROR_INVALID_HANDLE; - hManager = (PMANAGER_HANDLE)*hSCObject; - hService = (PSERVICE_HANDLE)*hSCObject; - if (hManager->Handle.Tag == MANAGER_TAG) + hManager = ScmGetServiceManagerFromHandle(*hSCObject); + hService = ScmGetServiceFromHandle(*hSCObject); + + if (hManager != NULL) { DPRINT("Found manager handle\n"); @@ -467,7 +458,7 @@ DWORD RCloseServiceHandle( DPRINT("RCloseServiceHandle() done\n"); return ERROR_SUCCESS; } - else if (hService->Handle.Tag == SERVICE_TAG) + else if (hService != NULL) { DPRINT("Found service handle\n"); @@ -561,6 +552,8 @@ DWORD RControlService( DWORD dwError = ERROR_SUCCESS; DWORD pcbBytesNeeded = 0; DWORD dwServicesReturned = 0; + DWORD dwControlsAccepted; + DWORD dwCurrentState; HKEY hServicesKey = NULL; DPRINT("RControlService() called\n"); @@ -662,6 +655,49 @@ DWORD RControlService( } else { + dwControlsAccepted = lpService->Status.dwControlsAccepted; + dwCurrentState = lpService->Status.dwCurrentState; + + /* Check the current state before sending a control request */ + switch (dwCurrentState) + { + case SERVICE_STOP_PENDING: + case SERVICE_STOPPED: + return ERROR_SERVICE_CANNOT_ACCEPT_CTRL; + + case SERVICE_START_PENDING: + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + break; + + case SERVICE_CONTROL_INTERROGATE: + RtlCopyMemory(lpServiceStatus, + &lpService->Status, + sizeof(SERVICE_STATUS)); + return ERROR_SUCCESS; + + default: + return ERROR_SERVICE_CANNOT_ACCEPT_CTRL; + } + break; + } + + /* Check if the control code is acceptable to the service */ + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0) + return ERROR_INVALID_SERVICE_CONTROL; + break; + + case SERVICE_CONTROL_PAUSE: + case SERVICE_CONTROL_CONTINUE: + if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0) + return ERROR_INVALID_SERVICE_CONTROL; + break; + } + /* Send control code to the service */ dwError = ScmControlService(lpService, dwControl); diff --git a/boot/bootdata/hivesys_i386.inf b/boot/bootdata/hivesys_i386.inf index 9bffb34dea1..a622feeb74c 100644 --- a/boot/bootdata/hivesys_i386.inf +++ b/boot/bootdata/hivesys_i386.inf @@ -1085,7 +1085,7 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init" HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ImagePath",0x00020000,"system32\drivers\blue.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Type",0x00010001,0x00000001 ; Cdfs (ISO96660) filesystem driver diff --git a/boot/bootdata/packages/reactos.dff b/boot/bootdata/packages/reactos.dff index d391b7bc85c..c5e998d4b36 100644 --- a/boot/bootdata/packages/reactos.dff +++ b/boot/bootdata/packages/reactos.dff @@ -586,6 +586,8 @@ media\fonts\symbol.ttf 3 media\fonts\tahoma.ttf 3 media\fonts\tahomabd.ttf 3 +media\vgafonts\vgafonts.cab 4 + media\nls\c_037.nls 1 media\nls\c_424.nls 1 media\nls\c_500.nls 1 diff --git a/dll/win32/gdi32/include/gdi32p.h b/dll/win32/gdi32/include/gdi32p.h index 5cc09870a94..e8b5e63952d 100644 --- a/dll/win32/gdi32/include/gdi32p.h +++ b/dll/win32/gdi32/include/gdi32p.h @@ -146,7 +146,7 @@ typedef BOOL (WINAPI *STARTPAGEPRINTER) (HANDLE); typedef BOOL (WINAPI *SEEKPRINTER) (HANDLE,LARGE_INTEGER,PLARGE_INTEGER,DWORD,BOOL); typedef BOOL (WINAPI *SPLREADPRINTER) (HANDLE,LPBYTE *,DWORD); // Same as ddk/winsplp.h DriverUnloadComplete? -typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR); +typedef BOOL (WINAPI *SPLDRIVERUNLOADCOMPLETE) (LPWSTR); // Driver support: // DrvDocumentEvent api/winddiui.h not W2k8 DocumentEventAW typedef INT (WINAPI *DOCUMENTEVENT) (HANDLE,HDC,INT,ULONG,PVOID,ULONG,PVOID); @@ -173,10 +173,10 @@ HEAP_strdupA2W( VOID HEAP_free(LPVOID memory); -VOID +VOID FASTCALL FONT_TextMetricWToA( - const TEXTMETRICW *ptmW, + const TEXTMETRICW *ptmW, LPTEXTMETRICA ptmA ); @@ -279,7 +279,7 @@ WINAPI GdiSetLastError( DWORD dwErrCode ); DWORD WINAPI GdiGetCodePage(HDC); -UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO ); +UINT FASTCALL DIB_BitmapBitsSize( CONST BITMAPINFO* ); int WINAPI diff --git a/dll/win32/gdi32/misc/wingl.c b/dll/win32/gdi32/misc/wingl.c index 5373c6f4d2d..b20ac7ee9d2 100644 --- a/dll/win32/gdi32/misc/wingl.c +++ b/dll/win32/gdi32/misc/wingl.c @@ -166,6 +166,10 @@ SetPixelFormat(HDC hdc, INT iPixelFormat, CONST PIXELFORMATDESCRIPTOR * ppfd) { + /* Can only be set once */ + INT current = GetPixelFormat(hdc); + if(current) return current == iPixelFormat ; + if (glSetPixelFormat == NULL) if (OpenGLEnable() == FALSE) return(0); diff --git a/dll/win32/gdi32/objects/bitmap.c b/dll/win32/gdi32/objects/bitmap.c index 2c7d4cea90c..8d93036c7d9 100644 --- a/dll/win32/gdi32/objects/bitmap.c +++ b/dll/win32/gdi32/objects/bitmap.c @@ -34,7 +34,7 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines ) UINT FASTCALL -DIB_BitmapBitsSize( PBITMAPINFO Info ) +DIB_BitmapBitsSize( CONST BITMAPINFO* Info ) { UINT Ret; @@ -43,16 +43,16 @@ DIB_BitmapBitsSize( PBITMAPINFO Info ) if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info; - Ret = Core->bcHeight * + Ret = Core->bcHeight * ((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8; } else /* assume BITMAPINFOHEADER */ { - if ((Info->bmiHeader.biCompression) && + if ((Info->bmiHeader.biCompression) && (Info->bmiHeader.biCompression != BI_BITFIELDS)) return Info->bmiHeader.biSizeImage; // Make Height positive always.... - Ret = abs(Info->bmiHeader.biHeight) * + Ret = abs(Info->bmiHeader.biHeight) * ((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8; } return Ret; @@ -132,12 +132,12 @@ WINAPI GdiGetBitmapBitsSize(BITMAPINFO *lpbmi) { int retSize; - + if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes)) { /* Calc the bits Size and align it*/ - retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) * - LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31) + retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) * + LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31) & -32) / 8; } else @@ -148,13 +148,13 @@ GdiGetBitmapBitsSize(BITMAPINFO *lpbmi) if (lpbmi->bmiHeader.biHeight >=0 ) { /* Calc the bits Size and align it*/ - retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth * + retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8; } else { /* Make height postiive if it negitve then calc the bits Size and align it*/ - retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth * + retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8; } } @@ -189,7 +189,7 @@ CreateDIBSection( { // Verify header due to converted may == info. if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) { - if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG ) { SetLastError(ERROR_INVALID_PARAMETER); @@ -319,7 +319,7 @@ CreateBitmapIndirect(const BITMAP *pbm) (!(pbm->bmWidthBytes & 1)) ) { - + bitmap = CreateBitmap(pbm->bmWidth, pbm->bmHeight, pbm->bmPlanes, @@ -409,7 +409,7 @@ GetDIBits( { if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) { - if ( lpbmi->bmiHeader.biCompression == BI_JPEG || + if ( lpbmi->bmiHeader.biCompression == BI_JPEG || lpbmi->bmiHeader.biCompression == BI_PNG ) { SetLastError(ERROR_INVALID_PARAMETER); @@ -461,78 +461,61 @@ CreateDIBitmap( HDC hDC, LONG width, height, compr, dibsize; WORD planes, bpp; // PDC_ATTR pDc_Attr; - PBITMAPINFO pConvertedInfo; - UINT ConvertedInfoSize; - UINT cjBmpScanSize; - PVOID pvSafeBits = NULL; + UINT InfoSize = 0; + UINT cjBmpScanSize = 0; HBITMAP hBmp; + NTSTATUS Status = STATUS_SUCCESS; if (!Header) return 0; - pConvertedInfo = ConvertBitmapInfo(Data, ColorUse, - &ConvertedInfoSize, FALSE); - if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1) { GdiSetLastError(ERROR_INVALID_PARAMETER); return NULL; } - if ( pConvertedInfo ) - { - if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) - { - if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || - pConvertedInfo->bmiHeader.biCompression == BI_PNG ) - { - hBmp = NULL; - goto Exit; - } - } - } - // For Icm support. // GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) - cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo); - DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize); + if(Data) + { + _SEH2_TRY + { + cjBmpScanSize = DIB_BitmapBitsSize(Data); + CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize); + InfoSize += Data->bmiHeader.biSize; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + } + + if(!NT_SUCCESS(Status)) + { + GdiSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,InfoSize,cjBmpScanSize); if ( !width || !height ) hBmp = GetStockObject(DEFAULT_BITMAP); else { - if ( Bits && Init == CBM_INIT ) - { - pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); - if (pvSafeBits == NULL) - { - hBmp = NULL; - goto Exit; - } - else - { - RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize); - } - } - hBmp = NtGdiCreateDIBitmapInternal(hDC, width, height, Init, - (LPBYTE)pvSafeBits, - (PBITMAPINFO)pConvertedInfo, + (LPBYTE)Bits, + (LPBITMAPINFO)Data, ColorUse, - ConvertedInfoSize, + InfoSize, cjBmpScanSize, 0, 0); - - if ( Bits && Init == CBM_INIT ) - RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); } -Exit: - if (Data != pConvertedInfo) - RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); return hBmp; } @@ -588,7 +571,7 @@ SetDIBits(HDC hDC, if ( hOldBitmap ) { - if ( hDC ) + if ( hDC ) hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE); if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) @@ -782,7 +765,7 @@ SetDIBitsToDevice( /* if ( !pDc_Attr || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && - (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc, @@ -806,7 +789,7 @@ SetDIBitsToDevice( RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpbmi != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); - + return LinesCopied; } @@ -886,17 +869,12 @@ StretchDIBits(HDC hdc, } } #endif - if ( iUsage ) // Save time, we only look at non RGB. - { - pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, - &ConvertedInfoSize, FALSE); - if (!pConvertedInfo) - { + pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage, + &ConvertedInfoSize, FALSE); + if (!pConvertedInfo) + { return 0; - } - } - else - pConvertedInfo = (PBITMAPINFO)lpBitsInfo; + } cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo); @@ -933,7 +911,7 @@ StretchDIBits(HDC hdc, /* if ( !pDc_Attr || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && - (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiStretchDIBitsInternal( hdc, diff --git a/dll/win32/gdi32/objects/dc.c b/dll/win32/gdi32/objects/dc.c index ddc33e501f1..eb9dcf2ff30 100644 --- a/dll/win32/gdi32/objects/dc.c +++ b/dll/win32/gdi32/objects/dc.c @@ -15,7 +15,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver, { UNICODE_STRING Device, Output; HDC hDC = NULL; - BOOL Display = FALSE, Default = TRUE; + BOOL Display = FALSE, Default = FALSE; ULONG UMdhpdev = 0; HANDLE hspool = NULL; @@ -31,7 +31,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver, if ((!lpwszDevice) && (!lpwszDriver)) { - Default = FALSE; // Ask Win32k to set Default device. + Default = TRUE; // Ask Win32k to set Default device. Display = TRUE; // Most likely to be DISPLAY. } else @@ -60,7 +60,7 @@ IntCreateDICW ( LPCWSTR lpwszDriver, DPRINT1("Not a DISPLAY device! %wZ\n", &Device); } - hDC = NtGdiOpenDCW( (Default ? &Device : NULL), + hDC = NtGdiOpenDCW( (Default ? NULL : &Device), (PDEVMODEW) lpInitData, (lpwszOutput ? &Output : NULL), iType, // DCW 0 and ICW 1. @@ -318,7 +318,7 @@ WINAPI DeleteObject(HGDIOBJ hObject) { UINT Type = 0; - + /* From Wine: DeleteObject does not SetLastError() on a null object */ if(!hObject) return FALSE; @@ -332,7 +332,7 @@ DeleteObject(HGDIOBJ hObject) Type = GDI_HANDLE_GET_TYPE(hObject); - if ((Type == GDI_OBJECT_TYPE_METAFILE) || + if ((Type == GDI_OBJECT_TYPE_METAFILE) || (Type == GDI_OBJECT_TYPE_ENHMETAFILE)) return FALSE; @@ -348,7 +348,7 @@ DeleteObject(HGDIOBJ hObject) case GDI_OBJECT_TYPE_METADC: return MFDRV_DeleteObject( hObject ); case GDI_OBJECT_TYPE_EMF: - { + { PLDC pLDC = GdiGetLDC(hObject); if ( !pLDC ) return FALSE; return EMFDRV_DeleteObject( hObject ); @@ -533,7 +533,7 @@ GetDeviceCaps(HDC hDC, return NtGdiGetDeviceCaps(hDC,i); } DPRINT("Device CAPS2\n"); - + switch (i) { case DRIVERVERSION: @@ -1603,7 +1603,7 @@ SelectObject(HDC hDC, #if 0 case GDI_OBJECT_TYPE_METADC: - return MFDRV_SelectObject( hDC, hGdiObj); + return MFDRV_SelectObject( hDC, hGdiObj); case GDI_OBJECT_TYPE_EMF: PLDC pLDC = GdiGetLDC(hDC); if ( !pLDC ) return NULL; diff --git a/dll/win32/user32/include/cursor.h b/dll/win32/user32/include/cursor.h index 67d3053f3be..a8e966eae4e 100644 --- a/dll/win32/user32/include/cursor.h +++ b/dll/win32/user32/include/cursor.h @@ -1,2 +1,12 @@ HCURSOR -CursorIconToCursor(HICON hIcon, BOOL SemiTransparent); +CursorIconToCursor(HICON hIcon, + BOOL SemiTransparent); + +HICON CreateCursorIconFromData(PVOID ImageData, + ICONIMAGE* IconImage, + int cxDesired, + int cyDesired, + int xHotspot, + int yHotspot, + BOOL fIcon); + diff --git a/dll/win32/user32/include/user32.h b/dll/win32/user32/include/user32.h index ba2a8364656..a0472b3ae62 100644 --- a/dll/win32/user32/include/user32.h +++ b/dll/win32/user32/include/user32.h @@ -43,7 +43,8 @@ #include #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) -#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId)) +#define ISITHOOKED(HookId) (GetWin32ClientInfo()->fsHooks & HOOKID_TO_FLAG(HookId) ||\ + (GetWin32ClientInfo()->pDeskInfo && GetWin32ClientInfo()->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId))) /* Temporarily in here for now. */ typedef struct _USERAPIHOOKINFO @@ -168,7 +169,7 @@ SharedPtrToKernel(PVOID Ptr) static __inline BOOL IsThreadHooked(PCLIENTINFO pci) { - return pci->fsHooks != 0; + return (pci->fsHooks|pci->pDeskInfo->fsHooks) != 0; } static __inline PDESKTOPINFO @@ -194,3 +195,4 @@ VOID FASTCALL GetConnected(VOID); BOOL FASTCALL DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi); BOOL FASTCALL TestWindowProcess(PWND); VOID UserGetWindowBorders(DWORD, DWORD, SIZE *, BOOL); +VOID FASTCALL IntNotifyWinEvent(DWORD, HWND, LONG, LONG, DWORD); diff --git a/dll/win32/user32/include/user32p.h b/dll/win32/user32/include/user32p.h index 0227e8edce3..7bcf68cf777 100644 --- a/dll/win32/user32/include/user32p.h +++ b/dll/win32/user32/include/user32p.h @@ -83,9 +83,6 @@ #define NtUserGetCursorPos(lpPoint) \ (BOOL)NtUserCallOneParam((DWORD_PTR)lpPoint, ONEPARAM_ROUTINE_GETCURSORPOSITION) -#define NtUserIsWindowInDestroy(hWnd) \ - (BOOL)NtUserCallOneParam((DWORD_PTR)hWnd, ONEPARAM_ROUTINE_ISWINDOWINDESTROY) - #define NtUserEnableProcessWindowGhosting(bEnable) \ NtUserCallOneParam((DWORD_PTR)bEnable, ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING) diff --git a/dll/win32/user32/misc/display.c b/dll/win32/user32/misc/display.c index 9090454c14b..e9de23e4e4a 100644 --- a/dll/win32/user32/misc/display.c +++ b/dll/win32/user32/misc/display.c @@ -457,7 +457,6 @@ ChangeDisplaySettingsExA( LONG rc; UNICODE_STRING DeviceName; PUNICODE_STRING pDeviceName = &DeviceName; - LPDEVMODEW pDevModeW; if (lpszDeviceName != NULL) { @@ -471,14 +470,19 @@ ChangeDisplaySettingsExA( pDeviceName = NULL; if (lpDevMode != NULL) + { + LPDEVMODEW pDevModeW; pDevModeW = GdiConvertToDevmodeW(lpDevMode); + if(pDevModeW) + { + rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam ); + RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + } + else + rc = DISP_CHANGE_SUCCESSFUL; + } else - pDevModeW = NULL; - - rc = NtUserChangeDisplaySettings ( pDeviceName, pDevModeW, hwnd, dwflags, lParam ); - - if (pDevModeW != NULL) - RtlFreeHeap(GetProcessHeap(), 0, pDevModeW); + rc = NtUserChangeDisplaySettings ( pDeviceName, NULL, hwnd, dwflags, lParam ); if (lpszDeviceName != NULL) RtlFreeUnicodeString ( &DeviceName ); @@ -539,6 +543,6 @@ ChangeDisplaySettingsW( DWORD dwflags) { if(lpDevMode) - lpDevMode->dmDriverExtra = 0; + lpDevMode->dmDriverExtra = 0; return ChangeDisplaySettingsExW ( NULL, lpDevMode, NULL, dwflags, 0 ); } diff --git a/dll/win32/user32/misc/misc.c b/dll/win32/user32/misc/misc.c index 76aaf462a31..e7b7672cfdc 100644 --- a/dll/win32/user32/misc/misc.c +++ b/dll/win32/user32/misc/misc.c @@ -304,13 +304,13 @@ GetUser32Handle(HANDLE handle) static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] = { FALSE, /* VALIDATE_TYPE_FREE (not used) */ - FALSE, /* VALIDATE_TYPE_WIN FALSE */ + FALSE, /* VALIDATE_TYPE_WIN */ TRUE, /* VALIDATE_TYPE_MENU FALSE */ TRUE, /* VALIDATE_TYPE_CURSOR */ TRUE, /* VALIDATE_TYPE_MWPOS */ - TRUE, /* VALIDATE_TYPE_HOOK FALSE */ + FALSE, /* VALIDATE_TYPE_HOOK */ FALSE, /* (not used) */ - TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */ + FALSE, /* VALIDATE_TYPE_CALLPROC */ TRUE, /* VALIDATE_TYPE_ACCEL */ FALSE, /* (not used) */ FALSE, /* (not used) */ diff --git a/dll/win32/user32/windows/class.c b/dll/win32/user32/windows/class.c index d55d29c913a..70171c6d0eb 100644 --- a/dll/win32/user32/windows/class.c +++ b/dll/win32/user32/windows/class.c @@ -298,7 +298,7 @@ IntGetWndProc(PWND pWnd, BOOL Ansi) } return Ret; } - // Wine Class tests: + // Wine Class tests: /* Edit controls are special - they return a wndproc handle when GetWindowLongPtr is called with a different A/W. On the other hand there is no W->A->W conversion so this control @@ -831,7 +831,6 @@ CreateSmallIcon(HICON StdIcon) int SmallIconWidth; int SmallIconHeight; BITMAP StdBitmapInfo; - HDC hInfoDc = NULL; HDC hSourceDc = NULL; HDC hDestDc = NULL; ICONINFO SmallInfo; @@ -867,15 +866,6 @@ CreateSmallIcon(HICON StdIcon) return StdIcon; } - /* Get a handle to a info DC and handles to DCs which can be used to - select a bitmap into. This is done to avoid triggering a switch to - graphics mode (if we're currently in text/blue screen mode) */ - hInfoDc = CreateICW(NULL, NULL, NULL, NULL); - if (NULL == hInfoDc) - { - ERR("Failed to create info DC\n"); - goto cleanup; - } hSourceDc = CreateCompatibleDC(NULL); if (NULL == hSourceDc) { @@ -895,7 +885,7 @@ CreateSmallIcon(HICON StdIcon) ERR("Failed to select source color bitmap\n"); goto cleanup; } - SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth, + SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight); if (NULL == SmallInfo.hbmColor) { @@ -921,8 +911,7 @@ CreateSmallIcon(HICON StdIcon) ERR("Failed to select source mask bitmap\n"); goto cleanup; } - SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1, - NULL); + SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight); if (NULL == SmallInfo.hbmMask) { ERR("Failed to create mask bitmap\n"); @@ -976,10 +965,6 @@ cleanup: { DeleteDC(hSourceDc); } - if (NULL != hInfoDc) - { - DeleteDC(hInfoDc); - } return SmallIcon; } @@ -1070,9 +1055,9 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx, clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer; clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer; clsMenuName.pusMenuName = &MenuName; - + Atom = NtUserRegisterClassExWOW( &WndClass, - &ClassName, + &ClassName, NULL, //PUNICODE_STRING ClsNVersion, &clsMenuName, fnID, diff --git a/dll/win32/user32/windows/cursoricon.c b/dll/win32/user32/windows/cursoricon.c index 0c88734834c..f7ada0b80af 100644 --- a/dll/win32/user32/windows/cursoricon.c +++ b/dll/win32/user32/windows/cursoricon.c @@ -458,10 +458,16 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height, void *color_bits, *mask_bits; BOOL ret = FALSE; HDC hdc = 0; + static HDC hScreenDC = 0; if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] ))))) return FALSE; - if (!(hdc = CreateCompatibleDC( 0 ))) goto done; + if(!hScreenDC) + { + hScreenDC = GetDC(0); + if(!hScreenDC) goto done; + } + if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done; memcpy( info, bmi, size ); info->bmiHeader.biHeight /= 2; @@ -485,8 +491,8 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height, else { if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done; - if (!(*color = CreateBitmap( width, height, bmi->bmiHeader.biPlanes, - bmi->bmiHeader.biBitCount, NULL ))) + if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES), + GetDeviceCaps(hScreenDC, BITSPIXEL), NULL ))) { DeleteObject( *mask ); goto done; @@ -523,7 +529,7 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height, ret = TRUE; done: - DeleteDC( hdc ); + if(hdc) DeleteDC( hdc ); HeapFree( GetProcessHeap(), 0, info ); return ret; } diff --git a/dll/win32/user32/windows/defwnd.c b/dll/win32/user32/windows/defwnd.c index 628940de1d6..76b34be0e9f 100644 --- a/dll/win32/user32/windows/defwnd.c +++ b/dll/win32/user32/windows/defwnd.c @@ -103,6 +103,7 @@ BOOL FASTCALL DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi) { + BOOL Ret; LARGE_STRING lsString; if ( String ) @@ -112,7 +113,12 @@ DefSetText(HWND hWnd, PCWSTR String, BOOL Ansi) else RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&lsString, String, 0); } - return NtUserDefSetText(hWnd, (String ? &lsString : NULL)); + Ret = NtUserDefSetText(hWnd, (String ? &lsString : NULL)); + + if (Ret) + IntNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); + + return Ret; } void @@ -1969,7 +1975,6 @@ RealDefWindowProcA(HWND hWnd, { DefWndNCPaint(hWnd, (HRGN)1, -1); } - Result = 1; break; } diff --git a/dll/win32/user32/windows/draw.c b/dll/win32/user32/windows/draw.c index c722dc7dbe8..dd50c75b1c3 100644 --- a/dll/win32/user32/windows/draw.c +++ b/dll/win32/user32/windows/draw.c @@ -1373,9 +1373,9 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp, } if (flags & DSS_DISABLED) - hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT)); + hbrtmp = GetSysColorBrush(COLOR_3DHILIGHT); else if (flags & DSS_DEFAULT) - hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW)); + hbrtmp = GetSysColorBrush(COLOR_3DSHADOW); /* Draw light or dark shadow */ if (flags & (DSS_DISABLED|DSS_DEFAULT)) @@ -1388,13 +1388,11 @@ IntDrawState(HDC hdc, HBRUSH hbr, DRAWSTATEPROC func, LPARAM lp, WPARAM wp, if(!BitBlt(hdc, x+1, y+1, cx, cy, memdc, 0, 0, 0x00B8074A)) goto cleanup; SelectObject(hdc, hbsave); - DeleteObject(hbrtmp); - hbrtmp = 0; } if (flags & DSS_DISABLED) { - hbr = hbrtmp = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW)); + hbr = hbrtmp = GetSysColorBrush(COLOR_3DSHADOW); if(!hbrtmp) goto cleanup; } @@ -1418,8 +1416,6 @@ cleanup: SelectObject(hdc, hbsave); if(hbmsave) SelectObject(memdc, hbmsave); - if(hbrtmp) - DeleteObject(hbrtmp); if(hbm) DeleteObject(hbm); if(memdc) diff --git a/dll/win32/user32/windows/hook.c b/dll/win32/user32/windows/hook.c index 304f9320a96..b848225741b 100644 --- a/dll/win32/user32/windows/hook.c +++ b/dll/win32/user32/windows/hook.c @@ -34,6 +34,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32); +typedef struct _NOTIFYEVENT +{ + DWORD event; + LONG idObject; + LONG idChild; + DWORD flags; +} NOTIFYEVENT, *PNOTIFYEVENT; + /* PRIVATE FUNCTIONS *********************************************************/ static @@ -99,6 +107,29 @@ IntSetWindowsHook( return NtUserSetWindowsHookEx(hMod, &USModuleName, dwThreadId, idHook, lpfn, bAnsi); } +/* + Since ReactOS uses User32 as the main message source this was needed. + Base on the funny rules from the wine tests it left it with this option. + 8^( + */ +VOID +FASTCALL +IntNotifyWinEvent( + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD flags + ) +{ + NOTIFYEVENT ne; + ne.event = event; + ne.idObject = idObject; + ne.idChild = idChild; + ne.flags = flags; + if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(event)) + NtUserCallHwndParam(hwnd, (DWORD)&ne, HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT); +} /* FUNCTIONS *****************************************************************/ @@ -195,7 +226,7 @@ CallNextHookEx( { PCLIENTINFO ClientInfo; DWORD Flags, Save; - PHOOK pHook; + PHOOK pHook, phkNext; LRESULT lResult = 0; GetConnected(); @@ -204,9 +235,14 @@ CallNextHookEx( if (!ClientInfo->phkCurrent) return 0; - pHook = SharedPtrToUser(ClientInfo->phkCurrent); + pHook = DesktopPtrToUser(ClientInfo->phkCurrent); - if (pHook->HookId == WH_CALLWNDPROC || pHook->HookId == WH_CALLWNDPROCRET) + if (!pHook->phkNext) return 0; // Nothing to do.... + + phkNext = DesktopPtrToUser(pHook->phkNext); + + if ( phkNext->HookId == WH_CALLWNDPROC || + phkNext->HookId == WH_CALLWNDPROCRET) { Save = ClientInfo->dwHookData; Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK; @@ -215,7 +251,7 @@ CallNextHookEx( if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK; else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK; - if (pHook->HookId == WH_CALLWNDPROC) + if (phkNext->HookId == WH_CALLWNDPROC) { PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam; @@ -225,7 +261,7 @@ CallNextHookEx( pCWP->lParam, (ULONG_PTR)&lResult, FNID_CALLWNDPROC, - pHook->Ansi); + phkNext->Ansi); } else { @@ -239,7 +275,7 @@ CallNextHookEx( pCWPR->lParam, (ULONG_PTR)&lResult, FNID_CALLWNDPROCRET, - pHook->Ansi); + phkNext->Ansi); } ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK); ClientInfo->dwHookData = Save; @@ -252,23 +288,27 @@ CallNextHookEx( /* - * @unimplemented + * @implemented */ HHOOK WINAPI SetWindowsHookW(int idHook, HOOKPROC lpfn) { - return IntSetWindowsHook(idHook, lpfn, NULL, 0, FALSE); + DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread); + return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, FALSE); +// return NtUserSetWindowsHookAW(idHook, lpfn, FALSE); } /* - * @unimplemented + * @implemented */ HHOOK WINAPI SetWindowsHookA(int idHook, HOOKPROC lpfn) { - return IntSetWindowsHook(idHook, lpfn, NULL, 0, TRUE); + DWORD ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread); + return IntSetWindowsHook(idHook, lpfn, NULL, ThreadId, TRUE); +// return NtUserSetWindowsHookAW(idHook, lpfn, TRUE); } /* @@ -377,7 +417,7 @@ IsWinEventHookInstalled( } /* - * @unimplemented + * @implemented */ HHOOK WINAPI @@ -392,7 +432,7 @@ SetWindowsHookExA( /* - * @unimplemented + * @implemented */ HHOOK WINAPI @@ -409,22 +449,21 @@ NTSTATUS WINAPI User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) { PHOOKPROC_CALLBACK_ARGUMENTS Common; - LRESULT Result; CREATESTRUCTW Csw; CBT_CREATEWNDW CbtCreatewndw; - CREATESTRUCTA Csa; - CBT_CREATEWNDA CbtCreatewnda; PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL; - WPARAM wParam = 0; - LPARAM lParam = 0; - PKBDLLHOOKSTRUCT KeyboardLlData; - PMSLLHOOKSTRUCT MouseLlData; - PMSG Msg; - PMOUSEHOOKSTRUCT MHook; - PCWPSTRUCT CWP; - PCWPRETSTRUCT CWPR; + KBDLLHOOKSTRUCT KeyboardLlData, *pKeyboardLlData; + MSLLHOOKSTRUCT MouseLlData, *pMouseLlData; + MSG Msg, *pMsg; + PMOUSEHOOKSTRUCT pMHook; + CWPSTRUCT CWP, *pCWP; + CWPRETSTRUCT CWPR, *pCWPR; PRECTL prl; LPCBTACTIVATESTRUCT pcbtas; + WPARAM wParam = 0; + LPARAM lParam = 0; + LRESULT Result = 0; + BOOL Hit = FALSE; Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Arguments; @@ -438,34 +477,16 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) ((PCHAR) Common + Common->lParam); Csw = CbtCreatewndExtra->Cs; - if (NULL != CbtCreatewndExtra->Cs.lpszName) - { - Csw.lpszName = (LPCWSTR)((PCHAR) CbtCreatewndExtra - + (ULONG_PTR) CbtCreatewndExtra->Cs.lpszName); - } - if (0 != HIWORD(CbtCreatewndExtra->Cs.lpszClass)) - { - Csw.lpszClass = (LPCWSTR)((PCHAR) CbtCreatewndExtra - + LOWORD((ULONG_PTR) CbtCreatewndExtra->Cs.lpszClass)); - } + Csw.lpszName = CbtCreatewndExtra->Cs.lpszName; + Csw.lpszClass = CbtCreatewndExtra->Cs.lpszClass; wParam = Common->wParam; - if (Common->Ansi) - { - memcpy(&Csa, &Csw, sizeof(CREATESTRUCTW)); - CbtCreatewnda.lpcs = &Csa; - CbtCreatewnda.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter; - lParam = (LPARAM) &CbtCreatewnda; - } - else - { - CbtCreatewndw.lpcs = &Csw; - CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter; - lParam = (LPARAM) &CbtCreatewndw; - } + CbtCreatewndw.lpcs = &Csw; + CbtCreatewndw.hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter; + lParam = (LPARAM) &CbtCreatewndw; break; case HCBT_CLICKSKIPPED: - MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); - lParam = (LPARAM) MHook; + pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); + lParam = (LPARAM) pMHook; break; case HCBT_MOVESIZE: prl = (PRECTL)((PCHAR) Common + Common->lParam); @@ -475,7 +496,7 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) pcbtas = (LPCBTACTIVATESTRUCT)((PCHAR) Common + Common->lParam); lParam = (LPARAM) pcbtas; break; - case HCBT_KEYSKIPPED: + case HCBT_KEYSKIPPED: /* The rest SEH support */ case HCBT_MINMAX: case HCBT_SETFOCUS: case HCBT_SYSCOMMAND: @@ -490,7 +511,17 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) } if (Common->Proc) - Result = Common->Proc(Common->Code, wParam, lParam); + { + _SEH2_TRY + { + Result = Common->Proc(Common->Code, wParam, lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; + } else { ERR("Common = 0x%x, Proc = 0x%x\n",Common,Common->Proc); @@ -499,46 +530,86 @@ User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength) { case HCBT_CREATEWND: CbtCreatewndExtra->WndInsertAfter = CbtCreatewndw.hwndInsertAfter; + CbtCreatewndExtra->Cs.x = CbtCreatewndw.lpcs->x; + CbtCreatewndExtra->Cs.y = CbtCreatewndw.lpcs->y; + CbtCreatewndExtra->Cs.cx = CbtCreatewndw.lpcs->cx; + CbtCreatewndExtra->Cs.cy = CbtCreatewndw.lpcs->cy; break; } break; } case WH_KEYBOARD_LL: - KeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) KeyboardLlData); + ERR("WH_KEYBOARD_LL: Code %d, wParam %d\n",Common->Code,Common->wParam); + pKeyboardLlData = (PKBDLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); + RtlCopyMemory(&KeyboardLlData, pKeyboardLlData, sizeof(KBDLLHOOKSTRUCT)); + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &KeyboardLlData); break; case WH_MOUSE_LL: - MouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MouseLlData); + pMouseLlData = (PMSLLHOOKSTRUCT)((PCHAR) Common + Common->lParam); + RtlCopyMemory(&MouseLlData, pMouseLlData, sizeof(MSLLHOOKSTRUCT)); + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &MouseLlData); break; - case WH_MOUSE: - MHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) MHook); + case WH_MOUSE: /* SEH support */ + pMHook = (PMOUSEHOOKSTRUCT)((PCHAR) Common + Common->lParam); + _SEH2_TRY + { + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) pMHook); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; break; case WH_CALLWNDPROC: - CWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWP); + ERR("WH_CALLWNDPROC: Code %d, wParam %d\n",Common->Code,Common->wParam); + pCWP = (PCWPSTRUCT)((PCHAR) Common + Common->lParam); + RtlCopyMemory(&CWP, pCWP, sizeof(CWPSTRUCT)); + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWP); break; case WH_CALLWNDPROCRET: - CWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) CWPR); + pCWPR = (PCWPRETSTRUCT)((PCHAR) Common + Common->lParam); + RtlCopyMemory(&CWPR, pCWPR, sizeof(CWPRETSTRUCT)); + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &CWPR); break; - case WH_MSGFILTER: + case WH_MSGFILTER: /* All SEH support */ + ERR("WH_MSGFILTER: Code %d, wParam %d\n",Common->Code,Common->wParam); case WH_SYSMSGFILTER: case WH_GETMESSAGE: - Msg = (PMSG)((PCHAR) Common + Common->lParam); -// FIXME("UHOOK Memory: %x: %x\n",Common, Msg); - Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) Msg); + pMsg = (PMSG)((PCHAR) Common + Common->lParam); + RtlCopyMemory(&Msg, pMsg, sizeof(MSG)); + _SEH2_TRY + { + Result = Common->Proc(Common->Code, Common->wParam, (LPARAM) &Msg); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; + if (!Hit && Common->HookId == WH_GETMESSAGE) + RtlCopyMemory(pMsg, &Msg, sizeof(MSG)); break; - case WH_FOREGROUNDIDLE: + case WH_FOREGROUNDIDLE: /* <-- SEH support */ case WH_KEYBOARD: case WH_SHELL: - Result = Common->Proc(Common->Code, Common->wParam, Common->lParam); + _SEH2_TRY + { + Result = Common->Proc(Common->Code, Common->wParam, Common->lParam); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; break; default: return ZwCallbackReturn(NULL, 0, STATUS_NOT_SUPPORTED); } - + if (Hit) + { + ERR("Hook Exception! Id: %d, Code %d, Proc 0x%x\n",Common->HookId,Common->Code,Common->Proc); + } return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS); } diff --git a/dll/win32/user32/windows/input.c b/dll/win32/user32/windows/input.c index aa9a997f070..08e457bf5a1 100644 --- a/dll/win32/user32/windows/input.c +++ b/dll/win32/user32/windows/input.c @@ -138,6 +138,7 @@ EnableWindow(HWND hWnd, if (Update) { + IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0); } // Return nonzero if it was disabled, or zero if it wasn't: diff --git a/dll/win32/user32/windows/menu.c b/dll/win32/user32/windows/menu.c index dd8f1ff1780..c9e87de47de 100644 --- a/dll/win32/user32/windows/menu.c +++ b/dll/win32/user32/windows/menu.c @@ -1636,6 +1636,8 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl top_popup_hmenu = hmenu; } + IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0); + /* Display the window */ SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0, @@ -3445,6 +3447,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, if (MenuInfo.Flags & MF_POPUP) { + IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0); DestroyWindow(MenuInfo.Wnd); MenuInfo.Wnd = NULL; @@ -3518,7 +3521,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT MenuInfo.Wnd = hWnd; MenuSetRosMenuInfo(&MenuInfo); } - + + IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART, + hWnd, + MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU, + CHILDID_SELF, 0); return TRUE; } /*********************************************************************** @@ -3528,6 +3535,7 @@ static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup) { TRACE("hwnd=%p\n", hWnd); + IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0); SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 ); ShowCaret(0); top_popup = 0; @@ -3645,7 +3653,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y, { BOOL ret = FALSE; - if (!IsMenu(Menu)) + if (!IsMenu(Menu)) { SetLastError( ERROR_INVALID_MENU_HANDLE ); return FALSE; diff --git a/dll/win32/user32/windows/message.c b/dll/win32/user32/windows/message.c index 2c89b7863df..2645c87f234 100644 --- a/dll/win32/user32/windows/message.c +++ b/dll/win32/user32/windows/message.c @@ -2064,13 +2064,18 @@ SendMessageW(HWND Wnd, if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) { - if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo())) + if ( Window != NULL && + Window->head.pti == ti && + !IsThreadHooked(GetWin32ClientInfo()) && + !(Window->state & WNDS_SERVERSIDEWINDOWPROC) ) { /* NOTE: We can directly send messages to the window procedure if *all* the following conditions are met: * Window belongs to calling thread * The calling thread is not being hooked + * Not calling a server side proc: + Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage */ return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE); @@ -2130,13 +2135,18 @@ SendMessageA(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam) if (Wnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST)) { - if (Window != NULL && Window->head.pti == ti && !IsThreadHooked(GetWin32ClientInfo())) + if ( Window != NULL && + Window->head.pti == ti && + !IsThreadHooked(GetWin32ClientInfo()) && + !(Window->state & WNDS_SERVERSIDEWINDOWPROC) ) { /* NOTE: We can directly send messages to the window procedure if *all* the following conditions are met: * Window belongs to calling thread * The calling thread is not being hooked + * Not calling a server side proc: + Desktop, Switch, ScrollBar, Menu, IconTitle, or hWndMessage */ return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE); diff --git a/dll/win32/user32/windows/window.c b/dll/win32/user32/windows/window.c index 468536ee290..1b1a0894e15 100644 --- a/dll/win32/user32/windows/window.c +++ b/dll/win32/user32/windows/window.c @@ -2060,7 +2060,11 @@ AnyPopup(VOID) BOOL WINAPI IsWindowInDestroy(HWND hWnd) { - return NtUserIsWindowInDestroy(hWnd); + PWND pwnd; + pwnd = ValidateHwnd(hWnd); + if (!pwnd) + return FALSE; + return ((pwnd->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY); } /* diff --git a/drivers/ksfilter/ks/property.c b/drivers/ksfilter/ks/property.c index b1a17e3ed09..b7f93fe2ac7 100644 --- a/drivers/ksfilter/ks/property.c +++ b/drivers/ksfilter/ks/property.c @@ -47,6 +47,25 @@ FindPropertyHandler( IoStatus->Information = PropertySet[Index].PropertyItem[ItemIndex].MinData; return STATUS_MORE_ENTRIES; } + + /* store property set */ + *Set = (PKSPROPERTY_SET)&PropertySet[Index]; + + if (Property->Flags & KSPROPERTY_TYPE_SET) + { + /* store property handler */ + *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler; + return STATUS_SUCCESS; + } + + if (Property->Flags & KSPROPERTY_TYPE_GET) + { + /* store property handler */ + *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler; + return STATUS_SUCCESS; + } + + if (Property->Flags & KSPROPERTY_TYPE_BASICSUPPORT) { PULONG Flags; @@ -64,14 +83,21 @@ FindPropertyHandler( /* clear flags */ *Flags = 0; + IoStatus->Information = sizeof(ULONG); + + if (PropertySet[Index].PropertyItem[ItemIndex].SupportHandler) + { + /* use support handler from driver */ + *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].SupportHandler; + return STATUS_SUCCESS; + } + if (PropertySet[Index].PropertyItem[ItemIndex].GetSupported) *Flags |= KSPROPERTY_TYPE_GET; if (PropertySet[Index].PropertyItem[ItemIndex].SetSupported) *Flags |= KSPROPERTY_TYPE_SET; - IoStatus->Information = sizeof(ULONG); - if (OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) { /* get output buffer */ @@ -89,14 +115,6 @@ FindPropertyHandler( } return STATUS_SUCCESS; } - if (Property->Flags & KSPROPERTY_TYPE_SET) - *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler; - - if (Property->Flags & KSPROPERTY_TYPE_GET) - *PropertyHandler = PropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler; - - *Set = (PKSPROPERTY_SET)&PropertySet[Index]; - return STATUS_SUCCESS; } } } @@ -171,7 +189,7 @@ KspPropertyHandler( } } } - else if (IsEqualGUIDAligned(&Property->Set, &GUID_NULL) && Property->Id == 0 && Property->Flags == KSPROPERTY_TYPE_SETSUPPORT) + else if (IsEqualGUIDAligned(&Property->Set, &GUID_NULL) && Property->Id == 0 && (Property->Flags & KSPROPERTY_TYPE_SETSUPPORT) == KSPROPERTY_TYPE_SETSUPPORT) { // store output size Irp->IoStatus.Information = sizeof(GUID) * PropertySetsCount; @@ -189,7 +207,7 @@ KspPropertyHandler( { RtlMoveMemory(&Guid[Index], PropertySet[Index].Set, sizeof(GUID)); } - return STATUS_SUCCESS; + Status = STATUS_SUCCESS; } /* done */ diff --git a/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp index fe0232d7674..e7882bb8da9 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_wavecyclic.cpp @@ -327,7 +327,7 @@ CPortFilterWaveCyclic::Init( NTSTATUS NTAPI CPortFilterWaveCyclic::FreePin( - IN struct IPortPinWaveCyclic* Pin) + IN PPORTPINWAVECYCLIC Pin) { ULONG Index; diff --git a/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp index c62cfbf3d61..639fb86720f 100644 --- a/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/filter_wavepci.cpp @@ -96,13 +96,14 @@ CPortFilterWavePci::NewIrpTarget( return STATUS_UNSUCCESSFUL; } - if (m_Pins[ConnectDetails->PinId] && m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount) + if (m_Pins[ConnectDetails->PinId] && + (m_Descriptor->Factory.Instances[ConnectDetails->PinId].CurrentPinInstanceCount == m_Descriptor->Factory.Instances[ConnectDetails->PinId].MaxFilterInstanceCount)) { - // release existing instance - PC_ASSERT(0); - m_Pins[ConnectDetails->PinId]->Close(DeviceObject, NULL); + // no available instance + return STATUS_UNSUCCESSFUL; } + // now create the pin Status = NewPortPinWavePci(&Pin); if (!NT_SUCCESS(Status)) @@ -305,6 +306,26 @@ CPortFilterWavePci::Init( return STATUS_SUCCESS; } +NTSTATUS +NTAPI +CPortFilterWavePci::FreePin( + IN struct IPortPinWavePci* Pin) +{ + ULONG Index; + + for(Index = 0; Index < m_Descriptor->Factory.PinDescriptorCount; Index++) + { + if (m_Pins[Index] == Pin) + { + m_Descriptor->Factory.Instances[Index].CurrentPinInstanceCount--; + m_Pins[Index] = NULL; + return STATUS_SUCCESS; + } + } + return STATUS_UNSUCCESSFUL; +} + + NTSTATUS NewPortFilterWavePci( OUT IPortFilterWavePci ** OutFilter) diff --git a/drivers/wdm/audio/backpln/portcls/guids.cpp b/drivers/wdm/audio/backpln/portcls/guids.cpp index 457868d2c62..34fed4811fb 100644 --- a/drivers/wdm/audio/backpln/portcls/guids.cpp +++ b/drivers/wdm/audio/backpln/portcls/guids.cpp @@ -79,6 +79,7 @@ const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, { const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_DrmAudioStream = {0x2f2c8ddd, 0x4198, 0x4fac, {0xba, 0x29, 0x61, 0xbb, 0x05, 0xb7, 0xde, 0x06}}; const GUID KSEVENTSETID_LoopedStreaming = {0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}}; const GUID KSEVENTSETID_Connection = {0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00}}; diff --git a/drivers/wdm/audio/backpln/portcls/interfaces.hpp b/drivers/wdm/audio/backpln/portcls/interfaces.hpp index dc030ed1168..248bcbe9012 100644 --- a/drivers/wdm/audio/backpln/portcls/interfaces.hpp +++ b/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -321,8 +321,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) STDMETHOD_(NTSTATUS, Init)(THIS_ IN KSPIN_CONNECT *ConnectDetails, IN ULONG FrameSize, - IN ULONG Alignment, - IN PVOID SilenceBuffer) PURE; + IN ULONG Alignment) PURE; STDMETHOD_(NTSTATUS, AddMapping)(THIS_ IN PIRP Irp, @@ -363,8 +362,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) STDMETHODIMP_(NTSTATUS) Init(THIS_ \ IN KSPIN_CONNECT *ConnectDetails, \ IN ULONG FrameSize, \ - IN ULONG Alignment, \ - IN PVOID SilenceBuffer); \ + IN ULONG Alignment); \ \ STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \ IN PIRP Irp, \ @@ -599,6 +597,8 @@ DECLARE_INTERFACE_(IIrpStreamVirtual, IIrpStream) #undef INTERFACE #define INTERFACE IPortFilterWavePci +struct IPortPinWavePci; + DECLARE_INTERFACE_(IPortFilterWavePci, IIrpTarget) { DEFINE_ABSTRACT_UNKNOWN() @@ -607,6 +607,9 @@ DECLARE_INTERFACE_(IPortFilterWavePci, IIrpTarget) STDMETHOD_(NTSTATUS, Init)(THIS_ IN PPORTWAVEPCI Port)PURE; + + STDMETHOD_(NTSTATUS, FreePin)(THIS_ + IN struct IPortPinWavePci* Pin)PURE; }; typedef IPortFilterWavePci *PPORTFILTERWAVEPCI; @@ -614,7 +617,10 @@ typedef IPortFilterWavePci *PPORTFILTERWAVEPCI; #define IMP_IPortFilterPci \ IMP_IIrpTarget; \ STDMETHODIMP_(NTSTATUS) Init(THIS_ \ - IN PPORTWAVEPCI Port) + IN PPORTWAVEPCI Port); \ + STDMETHODIMP_(NTSTATUS) FreePin(THIS_ \ + IN struct IPortPinWavePci* Pin) + /***************************************************************************** * IPortPinWavePci diff --git a/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/drivers/wdm/audio/backpln/portcls/irpstream.cpp index aa6f392f87d..a19a6da6e5c 100644 --- a/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -43,7 +43,6 @@ protected: LIST_ENTRY m_IrpList; LIST_ENTRY m_FreeIrpList; PIRP m_Irp; - PVOID m_SilenceBuffer; ULONG m_OutOfMapping; ULONG m_MaxFrameSize; @@ -84,12 +83,10 @@ NTAPI CIrpQueue::Init( IN KSPIN_CONNECT *ConnectDetails, IN ULONG FrameSize, - IN ULONG Alignment, - IN PVOID SilenceBuffer) + IN ULONG Alignment) { m_ConnectDetails = ConnectDetails; m_MaxFrameSize = FrameSize; - m_SilenceBuffer = SilenceBuffer; m_Alignment = Alignment; InitializeListHead(&m_IrpList); @@ -259,22 +256,13 @@ CIrpQueue::GetMapping( m_CurrentOffset = Offset = 0; } - if (!Irp && m_SilenceBuffer && m_MaxFrameSize) - { - DPRINT("NoIrp\n"); - // no irp available, use silence buffer - *Buffer = (PUCHAR)m_SilenceBuffer; - *BufferSize = m_MaxFrameSize; - return STATUS_SUCCESS; - } - if (!Irp) { // no irp buffer available + DPRINT("NoIrp\n"); return STATUS_UNSUCCESSFUL; } - // get stream header StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; diff --git a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp index 4bcad8c49d0..5a616f302ec 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp @@ -604,7 +604,7 @@ CPortPinDMus::Init( } } - Status = m_IrpQueue->Init(ConnectDetails, 0, 0, NULL); + Status = m_IrpQueue->Init(ConnectDetails, 0, 0); if (!NT_SUCCESS(Status)) { DPRINT("IrpQueue_Init failed with %x\n", Status); diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index 003b9b339cd..226457c1059 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -73,7 +73,7 @@ protected: ULONG m_StopCount; KSAUDIO_POSITION m_Position; KSALLOCATOR_FRAMING m_AllocatorFraming; - SUBDEVICE_DESCRIPTOR m_Descriptor; + PSUBDEVICE_DESCRIPTOR m_Descriptor; KSPIN_LOCK m_EventListLock; LIST_ENTRY m_EventList; @@ -105,10 +105,12 @@ NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); +NTSTATUS NTAPI PinWaveCyclicDRMHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); +DEFINE_KSPROPERTY_DRMSET(PinWaveCyclicDRMSet, PinWaveCyclicDRMHandler); KSEVENT_ITEM PinWaveCyclicConnectionEventSet = { @@ -146,6 +148,13 @@ KSPROPERTY_SET PinWaveCyclicPropertySet[] = (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet, 0, NULL + }, + { + &KSPROPSETID_DrmAudioStream, + sizeof(PinWaveCyclicDRMSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWaveCyclicDRMSet, + 0, + NULL } }; @@ -192,6 +201,19 @@ CPortPinWaveCyclic::QueryInterface( return STATUS_UNSUCCESSFUL; } +NTSTATUS +NTAPI +PinWaveCyclicDRMHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + DPRINT1("PinWaveCyclicDRMHandler\n"); + ASSERT(0); + return STATUS_INVALID_PARAMETER; +} + + NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent( @@ -448,12 +470,14 @@ PinWaveCyclicState( { // FIXME // complete with successful state + Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); Pin->m_IrpQueue->CancelBuffers(); Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } else if (Pin->m_State == KSSTATE_STOP) { + Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); Pin->m_IrpQueue->CancelBuffers(); Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; @@ -662,6 +686,7 @@ CPortPinWaveCyclic::UpdateCommonBuffer( ULONG BufferLength; ULONG BytesToCopy; ULONG BufferSize; + ULONG Gap; PUCHAR Buffer; NTSTATUS Status; @@ -672,7 +697,18 @@ CPortPinWaveCyclic::UpdateCommonBuffer( { Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); if (!NT_SUCCESS(Status)) - return; + { + Gap = Position - m_CommonBufferOffset; + if (Gap > m_FrameSize) + { + // insert silence samples + DPRINT1("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength); + m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); + + m_CommonBufferOffset += BufferLength; + break; + } + } BytesToCopy = min(BufferLength, BufferSize); @@ -688,7 +724,7 @@ CPortPinWaveCyclic::UpdateCommonBuffer( m_IrpQueue->UpdateMapping(BytesToCopy); m_CommonBufferOffset += BytesToCopy; - BufferLength = Position - m_CommonBufferOffset; + BufferLength -= BytesToCopy; m_Position.PlayOffset += BytesToCopy; if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) @@ -720,7 +756,18 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( { Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); if (!NT_SUCCESS(Status)) - return; + { + Gap = m_CommonBufferSize - m_CommonBufferOffset + Position; + if (Gap > m_FrameSize) + { + // insert silence samples + DPRINT1("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position); + m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); + + m_CommonBufferOffset += BufferLength; + } + break; + } BytesToCopy = min(BufferLength, BufferSize); @@ -741,7 +788,7 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( m_CommonBufferOffset += BytesToCopy; m_Position.PlayOffset += BytesToCopy; - BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + BufferLength -=BytesToCopy; if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) { @@ -751,7 +798,6 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; } } - } if (Gap == Length) @@ -773,22 +819,13 @@ CPortPinWaveCyclic::RequestService() { ULONG Position; NTSTATUS Status; - PUCHAR Buffer; - ULONG BufferSize; ULONGLONG OldOffset, NewOffset; PC_ASSERT_IRQL(DISPATCH_LEVEL); if (m_State == KSSTATE_RUN) { - Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - { - return; - } - Status = m_Stream->GetPosition(&Position); - DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); OldOffset = m_Position.PlayOffset; @@ -841,7 +878,7 @@ CPortPinWaveCyclic::DeviceIoControl( if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { /* handle property with subdevice descriptor */ - Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); + Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor); if (Status == STATUS_NOT_FOUND) { @@ -854,11 +891,11 @@ CPortPinWaveCyclic::DeviceIoControl( } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { - Status = PcHandleEnableEventWithTable(Irp, &m_Descriptor); + Status = PcHandleEnableEventWithTable(Irp, m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) { - Status = PcHandleDisableEventWithTable(Irp, &m_Descriptor); + Status = PcHandleDisableEventWithTable(Irp, m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) { @@ -960,27 +997,29 @@ CPortPinWaveCyclic::Close( { // free format FreeItem(m_Format, TAG_PORTCLASS); + + // format is freed m_Format = NULL; } if (m_IrpQueue) { - // fixme cancel irps + // cancel remaining irps + m_IrpQueue->CancelBuffers(); + + // release irp queue m_IrpQueue->Release(); - } - - if (m_Port) - { - // release reference to port driver - m_Port->Release(); - m_Port = NULL; + // queue is freed + m_IrpQueue = NULL; } if (m_ServiceGroup) { // remove member from service group m_ServiceGroup->RemoveMember(PSERVICESINK(this)); + + // do not release service group, it is released by the miniport object m_ServiceGroup = NULL; } @@ -999,22 +1038,37 @@ CPortPinWaveCyclic::Close( // set state to stop m_State = KSSTATE_STOP; - DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); + // release stream m_Stream->Release(); + // stream is now freed + m_Stream = NULL; } if (m_Filter) { - // release reference to filter instance + // disconnect pin from filter m_Filter->FreePin((PPORTPINWAVECYCLIC)this); + + // release filter reference m_Filter->Release(); + + // pin is done with filter m_Filter = NULL; } + if (m_Port) + { + // release reference to port driver + m_Port->Release(); + + // work is done for port + m_Port = NULL; + } + Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -1103,7 +1157,6 @@ CPortPinWaveCyclic::Init( PKSDATAFORMAT DataFormat; PDEVICE_OBJECT DeviceObject; BOOLEAN Capture; - PVOID SilenceBuffer; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; //IDrmAudioStream * DrmAudio = NULL; @@ -1162,7 +1215,6 @@ CPortPinWaveCyclic::Init( #endif DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); - DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize); if (!NT_SUCCESS(Status)) return Status; @@ -1186,18 +1238,26 @@ CPortPinWaveCyclic::Init( InitializeListHead(&m_EventList); KeInitializeSpinLock(&m_EventListLock); - /* set up subdevice descriptor */ - RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); - m_Descriptor.FilterPropertySet = PinWaveCyclicPropertySet; - m_Descriptor.FilterPropertySetCount = sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET); - m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; - m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; - m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; - m_Descriptor.PortPin = (PVOID)this; - m_Descriptor.EventSetCount = sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET); - m_Descriptor.EventSet = PinWaveCyclicEventSet; - m_Descriptor.EventList = &m_EventList; - m_Descriptor.EventListLock = &m_EventListLock; + Status = PcCreateSubdeviceDescriptor(&m_Descriptor, + SubDeviceDescriptor->InterfaceCount, + SubDeviceDescriptor->Interfaces, + 0, /* FIXME KSINTERFACE_STANDARD with KSINTERFACE_STANDARD_STREAMING / KSINTERFACE_STANDARD_LOOPED_STREAMING */ + NULL, + sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET), + PinWaveCyclicPropertySet, + 0, + 0, + 0, + NULL, + sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET), + PinWaveCyclicEventSet, + SubDeviceDescriptor->DeviceDescriptor); + + m_Descriptor->UnknownStream = (PUNKNOWN)m_Stream; + m_Descriptor->UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; + m_Descriptor->PortPin = (PVOID)this; + m_Descriptor->EventList = &m_EventList; + m_Descriptor->EventListLock = &m_EventListLock; // initialize reset state m_ResetState = KSRESET_END; @@ -1230,9 +1290,7 @@ CPortPinWaveCyclic::Init( PC_ASSERT(NT_SUCCESS(Status)); PC_ASSERT(m_FrameSize); - SilenceBuffer = AllocateItem(NonPagedPool, m_FrameSize, TAG_PORTCLASS); - if (!SilenceBuffer) - return STATUS_INSUFFICIENT_RESOURCES; + DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u CommonBufferSize %lu\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize, m_CommonBufferSize); /* set up allocator framing */ @@ -1243,10 +1301,9 @@ CPortPinWaveCyclic::Init( m_AllocatorFraming.Reserved = 0; m_AllocatorFraming.FrameSize = m_FrameSize; - m_Stream->Silence(SilenceBuffer, m_FrameSize); m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize); - Status = m_IrpQueue->Init(ConnectDetails, m_FrameSize, 0, SilenceBuffer); + Status = m_IrpQueue->Init(ConnectDetails, m_FrameSize, 0); if (!NT_SUCCESS(Status)) { m_IrpQueue->Release(); @@ -1265,9 +1322,6 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); - return STATUS_SUCCESS; } diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp index 430ae5e8190..9a1cc75613b 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -62,8 +62,6 @@ protected: KSAUDIO_POSITION m_Position; ULONG m_StopCount; - ULONG m_Delay; - BOOL m_bUsePrefetch; ULONG m_PrefetchOffset; SUBDEVICE_DESCRIPTOR m_Descriptor; @@ -637,41 +635,85 @@ CPortPinWavePci::Close( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - ISubdevice *SubDevice; NTSTATUS Status; - PSUBDEVICE_DESCRIPTOR Descriptor; + + if (m_Format) + { + // free format + FreeItem(m_Format, TAG_PORTCLASS); + + // format is freed + m_Format = NULL; + } + + if (m_IrpQueue) + { + // cancel remaining irps + m_IrpQueue->CancelBuffers(); + + // release irp queue + m_IrpQueue->Release(); + + // queue is freed + m_IrpQueue = NULL; + } + if (m_ServiceGroup) { + // remove member from service group m_ServiceGroup->RemoveMember(PSERVICESINK(this)); + + // do not release service group, it is released by the miniport object + m_ServiceGroup = NULL; } if (m_Stream) { if (m_State != KSSTATE_STOP) { - m_Stream->SetState(KSSTATE_STOP); + // stop stream + Status = m_Stream->SetState(KSSTATE_STOP); + if (!NT_SUCCESS(Status)) + { + DPRINT("Warning: failed to stop stream with %x\n", Status); + PC_ASSERT(0); + } } + // set state to stop + m_State = KSSTATE_STOP; + + DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); + + // release stream m_Stream->Release(); + + // stream is now freed + m_Stream = NULL; } - Status = m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice); - if (NT_SUCCESS(Status)) + if (m_Filter) { - Status = SubDevice->GetDescriptor(&Descriptor); - if (NT_SUCCESS(Status)) - { - Descriptor->Factory.Instances[m_ConnectDetails->PinId].CurrentPinInstanceCount--; - } - SubDevice->Release(); + // disconnect pin from filter + m_Filter->FreePin((PPORTPINWAVEPCI)this); + + // release filter reference + m_Filter->Release(); + + // pin is done with filter + m_Filter = NULL; } - if (m_Format) + if (m_Port) { - FreeItem(m_Format, TAG_PORTCLASS); - m_Format = NULL; + // release reference to port driver + m_Port->Release(); + + // work is done for port + m_Port = NULL; } + // successfully complete irp Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -756,33 +798,18 @@ CPortPinWavePci::Init( NTSTATUS Status; PKSDATAFORMAT DataFormat; BOOLEAN Capture; + ISubdevice * Subdevice = NULL; + PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; - Port->AddRef(); - Filter->AddRef(); - - m_Port = Port; - m_Filter = Filter; - m_KsPinDescriptor = KsPinDescriptor; - m_ConnectDetails = ConnectDetails; - m_Miniport = GetWavePciMiniport(Port); - m_DeviceObject = DeviceObject; - - DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); - - DPRINT("IPortPinWavePci_fnInit entered\n"); - - m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); - if (!m_Format) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); - + // check if it is a source / sink pin if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) { + // sink pin Capture = FALSE; } else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) { + // source pin Capture = TRUE; } else @@ -792,6 +819,45 @@ CPortPinWavePci::Init( while(TRUE); } + // add port / filter reference + Port->AddRef(); + Filter->AddRef(); + + // initialize pin + m_Port = Port; + m_Filter = Filter; + m_KsPinDescriptor = KsPinDescriptor; + m_ConnectDetails = ConnectDetails; + m_Miniport = GetWavePciMiniport(Port); + m_DeviceObject = DeviceObject; + m_State = KSSTATE_STOP; + m_Capture = Capture; + + DPRINT("IPortPinWavePci_fnInit entered\n"); + + // get dataformat + DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); + + // allocate data format + m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); + if (!m_Format) + { + // release references + m_Port->Release(); + m_Filter->Release(); + + // no dangling pointers + Port = NULL; + Filter = NULL; + + // failed to allocate data format + return STATUS_INSUFFICIENT_RESOURCES; + } + + // copy data format + RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); + + // allocate new stream Status = m_Miniport->NewStream(&m_Stream, NULL, NonPagedPool, @@ -805,47 +871,81 @@ CPortPinWavePci::Init( DPRINT("IPortPinWavePci_fnInit Status %x\n", Status); if (!NT_SUCCESS(Status)) - return Status; - - if (m_ServiceGroup) { - Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed to add pin to service group\n"); - return Status; - } + // free references + Port->Release(); + Filter->Release(); + + // free data format + FreeItem(m_Format, TAG_PORTCLASS); + + // no dangling pointers + m_Port = NULL; + m_Filter = NULL; + m_Format = NULL; + + // failed to allocate stream + return Status; } - // delay of 10 milisec - m_Delay = Int32x32To64(10, -10000); - + // get allocator requirements for pin Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming); + if (NT_SUCCESS(Status)) + { + DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", + m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); + } + + // allocate new irp queue + Status = NewIrpQueue(&m_IrpQueue); if (!NT_SUCCESS(Status)) { - DPRINT("GetAllocatorFraming failed with %x\n", Status); + // free references + Port->Release(); + Filter->Release(); + m_Stream->Release(); + + // free data format + FreeItem(m_Format, TAG_PORTCLASS); + + // no dangling pointers + m_Port = NULL; + m_Filter = NULL; + m_Format = NULL; + m_Stream = NULL; + + // failed to allocate irp queue + return Status; } - DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", - m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); + // initialize irp queue + Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); + if (!NT_SUCCESS(Status)) + { + // this should never happen + ASSERT(0); + } - ISubdevice * Subdevice = NULL; // get subdevice interface Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); if (!NT_SUCCESS(Status)) - return Status; - - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; + { + // this function should never fail + ASSERT(0); + } + // get subdevice descriptor Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); if (!NT_SUCCESS(Status)) { - // failed to get descriptor - Subdevice->Release(); - return Status; + // this function should never fail + ASSERT(0); } + // release subdevice + Subdevice->Release(); + /* set up subdevice descriptor */ RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); m_Descriptor.FilterPropertySet = PinWavePciPropertySet; @@ -855,21 +955,30 @@ CPortPinWavePci::Init( m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; m_Descriptor.PortPin = (PVOID)this; - - - Status = NewIrpQueue(&m_IrpQueue); - if (!NT_SUCCESS(Status)) - return Status; - - Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, NULL); - if (!NT_SUCCESS(Status)) + if (m_ServiceGroup) { - DPRINT("IrpQueue_Init failed with %x\n", Status); - return Status; + Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); + if (!NT_SUCCESS(Status)) + { + // free references + m_Stream->Release(); + Port->Release(); + Filter->Release(); + + // free data format + FreeItem(m_Format, TAG_PORTCLASS); + + // no dangling pointers + m_Stream = NULL; + m_Port = NULL; + m_Filter = NULL; + m_Format = NULL; + + // failed to add to service group + return Status; + } } - m_State = KSSTATE_STOP; - m_Capture = Capture; return STATUS_SUCCESS; } diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp index 7c3d0367123..fd6be3cc28f 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp @@ -587,7 +587,7 @@ CPortPinWaveRT::Init( goto cleanup; } - Status = m_IrpQueue->Init(ConnectDetails, 0, 0, NULL); + Status = m_IrpQueue->Init(ConnectDetails, 0, 0); if (!NT_SUCCESS(Status)) { goto cleanup; diff --git a/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp index 6566fe67299..41879cd8950 100644 --- a/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp @@ -275,12 +275,12 @@ CPortWaveCyclic::Init( } // create the subdevice descriptor - Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, + Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 4, InterfaceGuids, - 0, + 0, NULL, - 2, + 2, WaveCyclicPropertySet, 0, 0, diff --git a/drivers/wdm/audio/backpln/portcls/private.hpp b/drivers/wdm/audio/backpln/portcls/private.hpp index 17adc4c8af5..e2e600bd75e 100644 --- a/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/drivers/wdm/audio/backpln/portcls/private.hpp @@ -356,6 +356,22 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\ } + +#define DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_DRMAUDIOSTREAM_CONTENTID,\ + NULL,\ + sizeof(KSPROPERTY),\ + sizeof(ULONG),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_DRMSET(PinSet,\ + PropPositionHandler)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(PropPositionHandler)\ +} + #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ diff --git a/drivers/wdm/audio/backpln/portcls/undoc.cpp b/drivers/wdm/audio/backpln/portcls/undoc.cpp index f65af7e69a5..08970a8564a 100644 --- a/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -8,22 +8,6 @@ #include "private.hpp" - -KSPIN_INTERFACE PinInterfaces[] = -{ - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_STREAMING, - 0 - }, - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_LOOPED_STREAMING, - 0 - } -}; - - NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory( @@ -86,274 +70,6 @@ PcHandleDisableEventWithTable( return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); } -NTSTATUS -PcHandleGuidNullRequest( - IN OUT PIRP Irp, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - PPCNODE_DESCRIPTOR Node; - PPCPROPERTY_ITEM PropertyItem; - PIO_STACK_LOCATION IoStack; - PKSP_NODE Property; - LPGUID Buffer; - ULONG Count = 0, SubIndex, Index; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); - - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } - - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; - - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - BOOL Found = FALSE; - for (SubIndex = 0; SubIndex < Count; SubIndex++) - { - if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) - { - Found = TRUE; - break; - } - } - if (!Found) - { - RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); - Count++; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } - - // store result length - Irp->IoStatus.Information = sizeof (GUID) * Count; - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) - { - // buffer too small - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_MORE_ENTRIES; - } - - RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_SUCCESS; -} - -NTSTATUS -PcFindNodePropertyHandler( - PIRP Irp, - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, - OUT PPCPROPERTY_ITEM * OutPropertyItem) -{ - PPCNODE_DESCRIPTOR Node; - PPCPROPERTY_ITEM PropertyItem; - PIO_STACK_LOCATION IoStack; - PKSP_NODE Property; - ULONG Index; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) - { - // request is out of bounds - DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount); - return STATUS_INVALID_PARAMETER; - } - - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); - - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_NOT_FOUND; - } - - // sanity checks - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - - DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount); - for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) - { - //found property handler - *OutPropertyItem = PropertyItem; - return STATUS_SUCCESS; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } - - // no handler yet found - DPRINT("NotFound\n"); - return STATUS_NOT_FOUND; -} - -NTSTATUS -PcNodeBasicSupportHandler( - PIRP Irp, - PPCPROPERTY_ITEM PropertyItem) -{ - PULONG Flags; - PIO_STACK_LOCATION IoStack; - PKSPROPERTY_DESCRIPTION Description; - PKSP_NODE Property; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); - Flags= (PULONG)Irp->UserBuffer; - - // reset flags - *Flags = 0; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) - *Flags |= KSPROPERTY_TYPE_SET; - - if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) - *Flags |= KSPROPERTY_TYPE_GET; - - // store result length - Irp->IoStatus.Information = sizeof(ULONG); - - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) - { - // get output buffer - Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; - - // store result - Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); - Description->PropTypeSet.Set = KSPROPTYPESETID_General; - Description->PropTypeSet.Id = 0; - Description->PropTypeSet.Flags = 0; - Description->MembersListCount = 0; - Description->Reserved = 0; - - Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); - } - return STATUS_SUCCESS; -} - - -NTSTATUS -PcHandleNodePropertyRequest( - PIRP Irp, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - PIO_STACK_LOCATION IoStack; - PPCPROPERTY_ITEM PropertyItem; - PPCPROPERTY_REQUEST PropertyRequest; - PKSP_NODE Property; - NTSTATUS Status; - - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) - { - // certainly not a node property request - return STATUS_NOT_FOUND; - } - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) - { - return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor); - } - - // find property handler - Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem); - - // check for success - if (!NT_SUCCESS(Status)) - { - // might not be a node property request - DPRINT("NotFound\n"); - return STATUS_NOT_FOUND; - } - - if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) - { - // caller issued a basic property request - if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) - { - // driver does not have a basic support handler - return PcNodeBasicSupportHandler(Irp, PropertyItem); - } - } - - // sanity check - PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); - - // allocate a property request - PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); - if (!PropertyRequest) - return STATUS_INSUFFICIENT_RESOURCES; - - // initialize property request - PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; - PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; - PropertyRequest->Irp = Irp; - PropertyRequest->Node = Property->NodeId; - PropertyRequest->PropertyItem = PropertyItem; - PropertyRequest->Verb = Property->Property.Flags; - PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); - PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); - PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - PropertyRequest->Value = Irp->UserBuffer; - - Status = PropertyItem->Handler(PropertyRequest); - - if (Status != STATUS_PENDING) - { - //request completed - Irp->IoStatus.Information = PropertyRequest->ValueSize; - FreeItem(PropertyRequest, TAG_PORTCLASS); - } - - // done - DPRINT("Status %x\n", Status); - return Status; -} - NTSTATUS NTAPI PcHandlePropertyWithTable( @@ -362,21 +78,22 @@ PcHandlePropertyWithTable( IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) { - NTSTATUS Status; + PIO_STACK_LOCATION IoStack; - // try handle it as node property request - Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor); + // get current irp stack location + IoStack = IoGetCurrentIrpStackLocation(Irp); - if (Status == STATUS_NOT_FOUND) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) { - // store device descriptor - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; - - /* then try KsPropertyHandler */ - Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); + // certainly an invalid request + return STATUS_INVALID_PARAMETER; } - return Status; + // store device descriptor + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; + + // then try KsPropertyHandler + return KsPropertyHandler(Irp, PropertySetCount, PropertySet); } VOID @@ -406,15 +123,380 @@ PcAddToEventTable( } NTSTATUS -PcAddToPropertyTable( - PVOID Ptr, - LONG Unknown, - LONG Unknown2, - LONG Unknown3, - CHAR Unknown4) +NTAPI +PropertyItemDispatch( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PPCPROPERTY_REQUEST PropertyRequest; + PSUBDEVICE_DESCRIPTOR Descriptor; + PKSPROPERTY Property; + PPCNODE_DESCRIPTOR NodeDescriptor; + PKSNODEPROPERTY NodeProperty; + PKSPROPERTY_SET PropertySet; + PPCPROPERTY_ITEM PropertyItem; + PPCAUTOMATION_TABLE NodeAutomation; + PIO_STACK_LOCATION IoStack; + ULONG InstanceSize, ValueSize, Index; + PVOID Instance; + NTSTATUS Status; + + // allocate a property request + PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); + if (!PropertyRequest) + return STATUS_INSUFFICIENT_RESOURCES; + + // grab device descriptor + Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + // get current irp stack + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // get input property request + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + // get property set + PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp); + + // sanity check + PC_ASSERT(Descriptor); + PC_ASSERT(Descriptor->UnknownMiniport); + + // get instance / value size + InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength; + Instance = Data; + ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + + // initialize property request + PropertyRequest->MajorTarget = Descriptor->UnknownMiniport; + PropertyRequest->MinorTarget = Descriptor->UnknownStream; + PropertyRequest->Irp = Irp; + PropertyRequest->Verb = Property->Flags; + + + // check if this is filter / pin property request + if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY)) + { + // adjust input buffer size + InstanceSize -= sizeof(KSPROPERTY); + Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY)); + + // filter / pin property request dont use node field + PropertyRequest->Node = MAXULONG; + } + else if (InstanceSize >= sizeof(KSNODEPROPERTY)) + { + // request is for a node + InstanceSize -= sizeof(KSNODEPROPERTY); + Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY)); + + // cast node property request + NodeProperty = (PKSNODEPROPERTY)Request; + + // store node id + PropertyRequest->Node = NodeProperty->NodeId; + } + else + { + // invalid buffer size + return STATUS_INVALID_BUFFER_SIZE; + } + + // store instance size + PropertyRequest->InstanceSize = InstanceSize; + PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL); + + // store value size + PropertyRequest->ValueSize = ValueSize; + PropertyRequest->Value = (ValueSize != 0 ? Irp->UserBuffer : NULL); + + // now scan the property set for the attached property set item stored in Relations member + if (PropertySet) + { + // sanity check + PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set)); + + for(Index = 0; Index < PropertySet->PropertiesCount; Index++) + { + // check if they got the same property id + if (PropertySet->PropertyItem[Index].PropertyId == Property->Id) + { + // found item + PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations; + + // done + break; + } + } + } + + // check if there has been a property set item attached + if (!PropertyRequest->PropertyItem) + { + // is topology node id valid + if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount) + { + // get node descriptor + NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize); + + // get node automation table + NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable; + + // has it got a automation table + if (NodeAutomation) + { + // now scan the properties and check if it supports this request + PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties; + for(Index = 0; Index < NodeAutomation->PropertyCount; Index++) + { + // are they same property + if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set)) + { + if (PropertyItem->Id == Property->Id) + { + // found match + PropertyRequest->PropertyItem = PropertyItem; + + // done + break; + } + } + + // move to next property item + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize); + } + } + } + } + + if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler) + { + // now call the handler + UNICODE_STRING GuidBuffer; + RtlStringFromGUID(Property->Set, &GuidBuffer); + DPRINT1("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p\n", + PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize, + PropertyRequest->PropertyItem->Handler, PropertyRequest); +#if 0 + Status = PropertyRequest->PropertyItem->Handler(PropertyRequest); +#else + Status = STATUS_NOT_FOUND; +#endif + Irp->IoStatus.Information = PropertyRequest->ValueSize; + + if (Status != STATUS_PENDING) + { + // free property request + FreeItem(PropertyRequest, TAG_PORTCLASS); + } + } + else + { + FreeItem(PropertyRequest, TAG_PORTCLASS); + Status = STATUS_NOT_FOUND; + } + + /* done */ + return Status; +} + +NTSTATUS +PcAddToPropertyTable( + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, + IN PPCPROPERTY_ITEM PropertyItem, + IN ULONG bNode) +{ + ULONG bFound = FALSE; + ULONG Index, PropertySetIndex, PropertySetItemIndex; + PKSPROPERTY_SET NewPropertySet; + PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem; + LPGUID Guid; + //UNICODE_STRING GuidBuffer; + +ASSERT(PropertyItem->Set); + // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer); + // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags); + + + + //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount); + // first step check if the property set is present already + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++) + { + + //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer); + //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount); + if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set)) + { + // property set is already present + bFound = TRUE; + PropertySetIndex = Index; + + // break out + break; + } + } + + // is the property set present + if (!bFound) + { + // need to allocate a property set + NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS); + if (!NewPropertySet) + { + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; + } + + // need to allocate property set guid + Guid = (LPGUID)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); + if (!Guid) + { + // out of memory + FreeItem(NewPropertySet, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // are any existing property sets + if (SubDeviceDescriptor->FilterPropertySetCount) + { + // copy property sets + RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET)); + + // release memory + FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS); + } + + // store new property set descriptors + SubDeviceDescriptor->FilterPropertySet = NewPropertySet; + + // store index + PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount; + + // increment property set count + SubDeviceDescriptor->FilterPropertySetCount++; + + // copy property guid + RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID)); + + // initialize property set + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid; + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0; + } + + // as the property set has been indentified, now search for duplicate property set item entries + FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem; + bFound = FALSE; + + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++) + { + // now search for an equal property set item + if (FilterPropertyItem->PropertyId == PropertyItem->Id) + { + // found existing property set item + bFound = TRUE; + PropertySetItemIndex = Index; + break; + } + + // move to next entry + FilterPropertyItem++; + } + + if (!bFound) + { + // need to allocate memory for new property set item + NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!NewFilterPropertyItem) + { + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; + } + + // are any existing property set items + if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount) + { + // copy property item sets + RtlMoveMemory(NewFilterPropertyItem, + (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM)); + + // release old descriptors + FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS); + } + + // store new descriptor + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem; + + // store index + PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; + + // increment property item set count + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++; + + // now initialize property item + FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex]; + FilterPropertyItem->PropertyId = PropertyItem->Id; + FilterPropertyItem->MinProperty = sizeof(KSPROPERTY); + FilterPropertyItem->MinData = 0; + + // are any set operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_SET) + { + // setup handler + FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch; + } + + // are set operation supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } + + // are get operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } + + // are basic support operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_BASICSUPPORT) + { + // setup handler + FilterPropertyItem->SupportHandler = PropertyItemDispatch; + } + + if (!bNode) + { + // store property item in relations + // only store property item of filter properties / pin properties + // because filter & pin properties do not require a specific context + // on the other hand node properties are specifically bound to a node + + FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem; + } + } + else + { + // property set item handler already present + + if (bNode) + { + // filter & pin properties should not be exposed on a node + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL); + } + else + { + // node properties should not be exposed on a filter & pin + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL); + } + } + + // done + return STATUS_SUCCESS; } NTSTATUS @@ -491,6 +573,15 @@ DumpFilterDescriptor( EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + NodeDescriptor->AutomationTable->EventItemSize); } + DPRINT1(" Index %u PropertyCount %u\n", Index, NodeDescriptor->AutomationTable->PropertyCount); + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + RtlStringFromGUID(*PropertyItem->Set, &GuidString); + DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); + + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } } @@ -539,10 +630,13 @@ PcCreateSubdeviceDescriptor( IN PPCFILTER_DESCRIPTOR FilterDescription) { SUBDEVICE_DESCRIPTOR * Descriptor; - ULONG Index; + ULONG Index, SubIndex; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; PPCPIN_DESCRIPTOR SrcDescriptor; + PPCNODE_DESCRIPTOR NodeDescriptor; + PPCPROPERTY_ITEM PropertyItem; + // allocate subdevice descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES; @@ -551,6 +645,7 @@ PcCreateSubdeviceDescriptor( InitializeListHead(&Descriptor->SymbolicLinkList); InitializeListHead(&Descriptor->PhysicalConnectionList); + //FIXME add driver category guids Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); if (!Descriptor->Interfaces) goto cleanup; @@ -559,98 +654,215 @@ PcCreateSubdeviceDescriptor( RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount); Descriptor->InterfaceCount = InterfaceCount; + //DumpFilterDescriptor(FilterDescription); + + // are any property sets supported by the portcls if (FilterPropertiesCount) { - /// FIXME - /// handle driver properties - - DumpFilterDescriptor(FilterDescription); - + // first allocate filter properties set Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); if (! Descriptor->FilterPropertySet) goto cleanup; + // now copy all filter property sets Descriptor->FilterPropertySetCount = FilterPropertiesCount; for(Index = 0; Index < FilterPropertiesCount; Index++) { + // copy property set RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET)); + + if (Descriptor->FilterPropertySet[Index].PropertiesCount) + { + // copy property items to make sure they are dynamically allocated + Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!Descriptor->FilterPropertySet[Index].PropertyItem) + { + // no memory + goto cleanup; + } + + // copy filter property items + RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM)); + } } } - Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); - if (!Descriptor->Topology) - goto cleanup; - - if (FilterDescription->ConnectionCount) + // now check if the filter descriptor supports filter properties + if (FilterDescription->AutomationTable) { - Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyConnections) - goto cleanup; + // get first entry + PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; - RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); - Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; - } - - if (FilterDescription->NodeCount) - { - Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodes) - goto cleanup; - - Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodesNames) - goto cleanup; - - for(Index = 0; Index < FilterDescription->NodeCount; Index++) + // copy driver filter property sets + for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) { - if (FilterDescription->Nodes[Index].Type) + // add the property item + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID)); - } - if (FilterDescription->Nodes[Index].Name) - { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID)); + // goto cleanup + goto cleanup; } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); } - Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; } + // check if the filter has pins if (FilterDescription->PinCount) { + // allocate pin factory descriptors Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS); if (!Descriptor->Factory.KsPinDescriptor) goto cleanup; + // allocate pin instance info Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); if (!Descriptor->Factory.Instances) goto cleanup; + // initialize pin factory descriptor Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR); + // grab first entry SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins; - DPRINT("Size %u Expected %u\n", FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR)); // copy pin factories for(Index = 0; Index < FilterDescription->PinCount; Index++) { + // copy pin descriptor RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR)); - Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces; - Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE); - - DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount); - + // initialize pin factory instance data Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0; Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount; Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount; Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount; + + // check if the descriptor has an automation table + if (SrcDescriptor->AutomationTable) + { + // it has, grab first entry + PropertyItem = (PPCPROPERTY_ITEM)SrcDescriptor->AutomationTable->Properties; + + // now add all supported property items + for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add the property item to the table + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // goto cleanup + goto cleanup; + } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + SrcDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next entry SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize); } } + // allocate topology descriptor + Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); + if (!Descriptor->Topology) + goto cleanup; + + // are there any connections + if (FilterDescription->ConnectionCount) + { + // allocate connection descriptor + Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyConnections) + goto cleanup; + + // copy connection descriptor + RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); + + // store connection count + Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; + } + + // does the filter have nodes + if (FilterDescription->NodeCount) + { + // allocate topology node types array + Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodes) + goto cleanup; + + // allocate topology node names array + Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodesNames) + goto cleanup; + + // grab first entry + NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; + + // iterate all nodes and copy node types / names and node properties + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + // does it have a type + if (NodeDescriptor->Type) + { + // copy node type + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); + } + + // does it have a node name + if (NodeDescriptor->Name) + { + // copy node name + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); + } + + // check if has an automation table + if (NodeDescriptor->AutomationTable) + { + // grab first entry + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + + // copy all node properties into the global property set + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add to property set + Status = PcAddToPropertyTable(Descriptor, PropertyItem, TRUE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // failed + goto cleanup; + } + + // move to next property item + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next descriptor + NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); + } + + // now store the topology node count + Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; + } + + // store descriptor Descriptor->DeviceDescriptor = FilterDescription; + + // store result *OutSubdeviceDescriptor = Descriptor; + // done return STATUS_SUCCESS; cleanup: diff --git a/hal/halx86/generic/usage.c b/hal/halx86/generic/usage.c index c35df96c3e5..be6710d73fd 100644 --- a/hal/halx86/generic/usage.c +++ b/hal/halx86/generic/usage.c @@ -235,8 +235,9 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName, if (!HalpGetInfoFromACPI) { /* No, so use our local table */ - Port = HalpComPortIrqMapping[0][0]; - for (i = 0; Port; i++) + for (i = 0, Port = HalpComPortIrqMapping[i][0]; + Port; + i++, Port = HalpComPortIrqMapping[i][0]) { /* Is this the port we want? */ if (Port == (ULONG_PTR)KdComPortInUse) @@ -248,9 +249,6 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName, PRIMARY_VECTOR_BASE, HIGH_LEVEL); } - - /* Next port */ - Port = HalpComPortIrqMapping[i][0]; } } } @@ -509,6 +507,9 @@ HalpEnableInterruptHandler(IN UCHAR Flags, IN PVOID Handler, IN KINTERRUPT_MODE Mode) { + /* Set the IDT_LATCHED flag for latched interrupts */ + if (Mode == Latched) Flags |= IDT_LATCHED; + /* Register the vector */ HalpRegisterVector(Flags, BusVector, SystemVector, Irql); diff --git a/include/psdk/ks.h b/include/psdk/ks.h index 62357d623a1..7f99f136077 100644 --- a/include/psdk/ks.h +++ b/include/psdk/ks.h @@ -1005,11 +1005,6 @@ DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_Genera KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY */ -#define KSPROPSETID_DrmAudioStream -/* - KSPROPERTY_DRMAUDIOSTREAM_CONTENTID -*/ - #define KSPROPSETID_Hrtf3d /* KSPROPERTY_HRTF3D_FILTER_FORMAT diff --git a/include/psdk/ksmedia.h b/include/psdk/ksmedia.h index 32e5e3e5269..5a34bba37e6 100644 --- a/include/psdk/ksmedia.h +++ b/include/psdk/ksmedia.h @@ -565,6 +565,15 @@ typedef struct { #endif // !_NTDDK_ } LOOPEDSTREAMING_POSITION_EVENT_DATA, *PLOOPEDSTREAMING_POSITION_EVENT_DATA ; +#define STATIC_KSPROPSETID_DrmAudioStream\ + 0x2f2c8ddd, 0x4198, 0x4fac, 0xba, 0x29, 0x61, 0xbb, 0x5, 0xb7, 0xde, 0x6 +DEFINE_GUIDSTRUCT("2F2C8DDD-4198-4fac-BA29-61BB05B7DE06", KSPROPSETID_DrmAudioStream); +#define KSPROPSETID_DrmAudioStream DEFINE_GUIDNAMED(KSPROPSETID_DrmAudioStream) + +typedef enum { + KSPROPERTY_DRMAUDIOSTREAM_CONTENTID +} KSPROPERTY_DRMAUDIOSTREAM; + /* SysAudio Properties diff --git a/include/reactos/win32k/ntuser.h b/include/reactos/win32k/ntuser.h index 920e4e1abff..64071cb9066 100644 --- a/include/reactos/win32k/ntuser.h +++ b/include/reactos/win32k/ntuser.h @@ -51,13 +51,15 @@ VOID NTAPI RtlInitLargeAnsiString(IN OUT PLARGE_ANSI_STRING,IN PCSZ,IN INT); VOID NTAPI RtlInitLargeUnicodeString(IN OUT PLARGE_UNICODE_STRING,IN PCWSTR,IN INT); BOOL NTAPI RtlLargeStringToUnicodeString( PUNICODE_STRING, PLARGE_STRING); +#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1) + typedef struct _DESKTOPINFO { PVOID pvDesktopBase; PVOID pvDesktopLimit; struct _WND *spwnd; DWORD fsHooks; - struct tagHOOK * aphkStart[16]; + LIST_ENTRY aphkStart[NB_HOOKS]; HWND hTaskManWindow; HWND hProgmanWindow; @@ -127,15 +129,23 @@ typedef struct _PROCMARKHEAD /* Window Client Information structure */ struct _ETHREAD; +#define WEF_SETBYWNDPTI 0x0001 + typedef struct tagHOOK { THRDESKHEAD head; + struct tagHOOK *phkNext; /* This is for user space. */ + int HookId; /* Hook table index */ + ULONG_PTR offPfn; + ULONG flags; /* Some internal flags */ + INT ihmod; + PTHREADINFO ptiHooked; + struct _DESKTOP *rpdesk; + /* ReactOS */ LIST_ENTRY Chain; /* Hook chain entry */ struct _ETHREAD* Thread; /* Thread owning the hook */ - int HookId; /* Hook table index */ HOOKPROC Proc; /* Hook function */ BOOLEAN Ansi; /* Is it an Ansi hook? */ - ULONG Flags; /* Some internal flags */ UNICODE_STRING ModuleName; /* Module name for global hooks */ } HOOK, *PHOOK; @@ -3149,7 +3159,6 @@ typedef struct tagKMDDELPARAM #define NOPARAM_ROUTINE_ANYPOPUP 0xffff0006 #define ONEPARAM_ROUTINE_CSRSS_GUICHECK 0xffff0008 #define ONEPARAM_ROUTINE_SWITCHCARETSHOWING 0xfffe0008 -#define ONEPARAM_ROUTINE_ISWINDOWINDESTROY 0xfffe000c #define ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING 0xfffe000d #define ONEPARAM_ROUTINE_GETDESKTOPMAPPING 0xfffe000e #define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0xfffe0027 @@ -3167,6 +3176,7 @@ typedef struct tagKMDDELPARAM #define TWOPARAM_ROUTINE_SETCARETPOS 0xfffd0060 #define TWOPARAM_ROUTINE_REGISTERLOGONPROC 0xfffd0062 #define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004 +#define HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT 0x1005 DWORD NTAPI diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 28bc779111c..bf676b610f1 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -514,6 +514,21 @@ IopAssignDeviceResources( IN PDEVICE_NODE DeviceNode ); +NTSTATUS +NTAPI +IopCreateResourceListFromRequirements( + IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, + OUT PCM_RESOURCE_LIST *ResourceList +); + +NTSTATUS +NTAPI +IopDetectResourceConflict( + IN PCM_RESOURCE_LIST ResourceList, + IN BOOLEAN Silent, + OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor +); + // // PNP Routines // diff --git a/ntoskrnl/io/iomgr/iorsrce.c b/ntoskrnl/io/iomgr/iorsrce.c index af5913146c6..9d52881ce12 100644 --- a/ntoskrnl/io/iomgr/iorsrce.c +++ b/ntoskrnl/io/iomgr/iorsrce.c @@ -841,7 +841,7 @@ IoGetConfigurationInformation(VOID) } /* - * @unimplemented + * @halfplemented */ NTSTATUS NTAPI IoReportResourceUsage(PUNICODE_STRING DriverClassName, @@ -876,13 +876,48 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName, * a conflict is detected with another driver. */ { - UNIMPLEMENTED; - *ConflictDetected = FALSE; - return STATUS_SUCCESS; + NTSTATUS Status; + PCM_RESOURCE_LIST ResourceList; + + DPRINT1("IoReportResourceUsage is halfplemented!\n"); + + if (!DriverList && !DeviceList) + return STATUS_INVALID_PARAMETER; + + if (DeviceList) + ResourceList = DeviceList; + else + ResourceList = DriverList; + + Status = IopDetectResourceConflict(ResourceList, FALSE, NULL); + if (Status == STATUS_CONFLICTING_ADDRESSES) + { + *ConflictDetected = TRUE; + + if (!OverrideConflict) + { + DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); + return STATUS_CONFLICTING_ADDRESSES; + } + else + { + DPRINT1("Proceeding with conflicting resources\n"); + } + } + else if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* TODO: Claim resources in registry */ + + *ConflictDetected = FALSE; + + return STATUS_SUCCESS; } /* - * @unimplemented + * @halfplemented */ NTSTATUS NTAPI IoAssignResources(PUNICODE_STRING RegistryPath, @@ -892,8 +927,23 @@ IoAssignResources(PUNICODE_STRING RegistryPath, PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, PCM_RESOURCE_LIST* AllocatedResources) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + NTSTATUS Status; + + DPRINT1("IoAssignResources is halfplemented!\n"); + + Status = IopCreateResourceListFromRequirements(RequestedResources, + AllocatedResources); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_CONFLICTING_ADDRESSES) + DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); + + return Status; + } + + /* TODO: Claim resources in registry */ + + return STATUS_SUCCESS; } /* diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 165b0b06f59..94a20dc18ce 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -38,9 +38,6 @@ NTSTATUS IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, PVOID Context); -NTSTATUS -IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList); - NTSTATUS PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject, IN OUT PKEVENT SyncEvent OPTIONAL, @@ -379,7 +376,7 @@ IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject, ResourceList = DriverList; /* Look for a resource conflict */ - Status = IopDetectResourceConflict(ResourceList); + Status = IopDetectResourceConflict(ResourceList, FALSE, NULL); if (Status == STATUS_CONFLICTING_ADDRESSES) { /* Oh noes */ diff --git a/ntoskrnl/io/pnpmgr/pnpres.c b/ntoskrnl/io/pnpmgr/pnpres.c index 71319f8abd1..733440dd5fb 100644 --- a/ntoskrnl/io/pnpmgr/pnpres.c +++ b/ntoskrnl/io/pnpmgr/pnpres.c @@ -12,12 +12,6 @@ #define NDEBUG #include -NTSTATUS -IopDetectResourceConflict( - IN PCM_RESOURCE_LIST ResourceList, - IN BOOLEAN Silent, - OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor); - static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) @@ -187,8 +181,8 @@ IopFindInterruptResource( return FALSE; } -static -NTSTATUS + +NTSTATUS NTAPI IopCreateResourceListFromRequirements( IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, OUT PCM_RESOURCE_LIST *ResourceList) @@ -336,9 +330,6 @@ IopCheckResourceDescriptor( ULONG i, ii; BOOLEAN Result = FALSE; - if (ResDesc->ShareDisposition == CmResourceShareShared) - return FALSE; - for (i = 0; i < ResourceList->Count; i++) { PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList; @@ -615,40 +606,61 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (DeviceNode->ResourceList) { - PWCHAR DeviceName = NULL; UNICODE_STRING NameU; - UNICODE_STRING Suffix; + UNICODE_STRING RawSuffix, TranslatedSuffix; ULONG OldLength = 0; ASSERT(DeviceNode->ResourceListTranslated); + + RtlInitUnicodeString(&TranslatedSuffix, L".Translated"); + RtlInitUnicodeString(&RawSuffix, L".Raw"); Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, DevicePropertyPhysicalDeviceObjectName, 0, NULL, &OldLength); - if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL)) - { - DeviceName = ExAllocatePool(NonPagedPool, OldLength); - ASSERT(DeviceName); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(OldLength); + + NameU.Buffer = ExAllocatePool(PagedPool, OldLength + TranslatedSuffix.Length); + if (!NameU.Buffer) + { + ZwClose(PnpMgrLevel2); + return STATUS_INSUFFICIENT_RESOURCES; + } + + NameU.Length = 0; + NameU.MaximumLength = OldLength + TranslatedSuffix.Length; + + Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, + DevicePropertyPhysicalDeviceObjectName, + NameU.MaximumLength, + NameU.Buffer, + &OldLength); + if (!NT_SUCCESS(Status)) + { + ZwClose(PnpMgrLevel2); + ExFreePool(NameU.Buffer); + return Status; + } + } + else if (!NT_SUCCESS(Status)) + { + /* Some failure */ + ZwClose(PnpMgrLevel2); + return Status; + } + else + { + /* This should never happen */ + ASSERT(FALSE); + } + + NameU.Length = OldLength; - IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, - DevicePropertyPhysicalDeviceObjectName, - OldLength, - DeviceName, - &OldLength); - - RtlInitUnicodeString(&NameU, DeviceName); - } - else - { - /* Some failure */ - ASSERT(!NT_SUCCESS(Status)); - return Status; - } - - RtlInitUnicodeString(&Suffix, L".Raw"); - RtlAppendUnicodeStringToString(&NameU, &Suffix); + RtlAppendUnicodeStringToString(&NameU, &RawSuffix); Status = ZwSetValueKey(PnpMgrLevel2, &NameU, @@ -659,14 +671,14 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (!NT_SUCCESS(Status)) { ZwClose(PnpMgrLevel2); + ExFreePool(NameU.Buffer); return Status; } /* "Remove" the suffix by setting the length back to what it used to be */ - NameU.Length = (USHORT)OldLength; + NameU.Length = OldLength; - RtlInitUnicodeString(&Suffix, L".Translated"); - RtlAppendUnicodeStringToString(&NameU, &Suffix); + RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix); Status = ZwSetValueKey(PnpMgrLevel2, &NameU, @@ -675,8 +687,8 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 DeviceNode->ResourceListTranslated, PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated)); ZwClose(PnpMgrLevel2); - ASSERT(DeviceName); - ExFreePool(DeviceName); + ExFreePool(NameU.Buffer); + if (!NT_SUCCESS(Status)) return Status; } @@ -718,7 +730,7 @@ IopTranslateDeviceResources( DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceListTranslated) { - Status =STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; goto cleanup; } RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize); @@ -743,6 +755,7 @@ IopTranslateDeviceResources( &DescriptorTranslated->u.Port.Start)) { Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate port resource (Start: 0xI64x)\n", DescriptorRaw->u.Port.Start.QuadPart); goto cleanup; } break; @@ -756,6 +769,14 @@ IopTranslateDeviceResources( DescriptorRaw->u.Interrupt.Vector, (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, &DescriptorTranslated->u.Interrupt.Affinity); + + if (!DescriptorTranslated->u.Interrupt.Vector) + { + Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate interrupt resource (Vector: 0x%x | Level: 0x%x)\n", DescriptorRaw->u.Interrupt.Vector, + DescriptorRaw->u.Interrupt.Level); + goto cleanup; + } break; } case CmResourceTypeMemory: @@ -769,6 +790,7 @@ IopTranslateDeviceResources( &DescriptorTranslated->u.Memory.Start)) { Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate memory resource (Start: 0xI64x)\n", DescriptorRaw->u.Memory.Start.QuadPart); goto cleanup; } } @@ -864,16 +886,21 @@ IopAssignDeviceResources( Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements, &DeviceNode->ResourceList); if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath); goto ByeBye; + } - Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL); - if (!NT_SUCCESS(Status)) - goto ByeBye; + /* IopCreateResourceListFromRequirements should NEVER succeed with a conflicting list */ + ASSERT(IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL) != STATUS_CONFLICTING_ADDRESSES); Finish: Status = IopTranslateDeviceResources(DeviceNode); if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath); goto ByeBye; + } Status = IopUpdateResourceMapForPnPDevice(DeviceNode); if (!NT_SUCCESS(Status)) @@ -935,7 +962,7 @@ ByeBye: return Result; } -NTSTATUS +NTSTATUS NTAPI IopDetectResourceConflict( IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c index dd0f818e0ca..16bbad16350 100644 --- a/ntoskrnl/mm/ARM3/virtual.c +++ b/ntoskrnl/mm/ARM3/virtual.c @@ -1048,6 +1048,48 @@ MmFlushVirtualMemory(IN PEPROCESS Process, return STATUS_SUCCESS; } +ULONG +NTAPI +MiGetPageProtection(IN PMMPTE PointerPte) +{ + MMPTE TempPte; + PMMPFN Pfn; + PAGED_CODE(); + + /* Copy this PTE's contents */ + TempPte = *PointerPte; + + /* Assure it's not totally zero */ + ASSERT(TempPte.u.Long); + + /* Check for a special prototype format */ + if (TempPte.u.Soft.Valid == 0 && + TempPte.u.Soft.Prototype == 1) + { + /* Unsupported now */ + UNIMPLEMENTED; + ASSERT(FALSE); + } + + /* In the easy case of transition or demand zero PTE just return its protection */ + if (!TempPte.u.Hard.Valid) return MmProtectToValue[TempPte.u.Soft.Protection]; + + /* If we get here, the PTE is valid, so look up the page in PFN database */ + Pfn = MiGetPfnEntry(TempPte.u.Hard.PageFrameNumber); + + if (!Pfn->u3.e1.PrototypePte) + { + /* Return protection of the original pte */ + return MmProtectToValue[Pfn->OriginalPte.u.Soft.Protection]; + } + + /* This is hardware PTE */ + UNIMPLEMENTED; + ASSERT(FALSE); + + return PAGE_NOACCESS; +} + ULONG NTAPI MiQueryAddressState(IN PVOID Va, @@ -1119,9 +1161,9 @@ MiQueryAddressState(IN PVOID Va, { /* This means it's committed */ State = MEM_COMMIT; - - /* For now, we lie about the protection */ - Protect = PAGE_EXECUTE_READWRITE; + + /* Get protection state of this page */ + Protect = MiGetPageProtection(PointerPte); } else { @@ -2306,7 +2348,7 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, NTSTATUS Status; PMMVAD Vad = NULL; PVOID Address, NextAddress; - BOOLEAN Found; + BOOLEAN Found = FALSE; ULONG NewProtect, NewState, BaseVpn; MEMORY_BASIC_INFORMATION MemoryInfo; KAPC_STATE ApcState; @@ -2329,9 +2371,34 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, if ((BaseAddress > MM_HIGHEST_VAD_ADDRESS) || (PAGE_ALIGN(BaseAddress) == (PVOID)USER_SHARED_DATA)) { - /* FIXME: We should return some bogus info structure */ - UNIMPLEMENTED; - while (TRUE); + Address = PAGE_ALIGN(BaseAddress); + + /* Make up an info structure describing this range */ + MemoryInfo.BaseAddress = Address; + MemoryInfo.AllocationProtect = PAGE_READONLY; + MemoryInfo.Type = MEM_PRIVATE; + + /* Special case for shared data */ + if (Address == (PVOID)USER_SHARED_DATA) + { + MemoryInfo.AllocationBase = (PVOID)USER_SHARED_DATA; + MemoryInfo.State = MEM_COMMIT; + MemoryInfo.Protect = PAGE_READONLY; + MemoryInfo.RegionSize = PAGE_SIZE; + } + else + { + MemoryInfo.AllocationBase = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1; + MemoryInfo.State = MEM_RESERVE; + MemoryInfo.Protect = PAGE_NOACCESS; + MemoryInfo.RegionSize = (ULONG_PTR)MemoryInfo.AllocationBase - (ULONG_PTR)Address; + } + + /* Return the data (FIXME: Use SEH) */ + *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo; + if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); + + return STATUS_SUCCESS; } /* Check if this is for a local or remote process */ @@ -2390,11 +2457,61 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, /* Was a VAD found? */ if (!Found) { - /* We don't handle this yet */ - UNIMPLEMENTED; - while (TRUE); + Address = PAGE_ALIGN(BaseAddress); + + /* Calculate region size */ + if (Vad) + { + if (Vad->StartingVpn >= BaseVpn) + { + /* Region size is the free space till the start of that VAD */ + MemoryInfo.RegionSize = (ULONG_PTR)(Vad->StartingVpn << PAGE_SHIFT) - (ULONG_PTR)Address; + } + else + { + /* Get the next VAD */ + Vad = (PMMVAD)MiGetNextNode((PMMADDRESS_NODE)Vad); + if (Vad) + { + /* Region size is the free space till the start of that VAD */ + MemoryInfo.RegionSize = (ULONG_PTR)(Vad->StartingVpn << PAGE_SHIFT) - (ULONG_PTR)Address; + } + else + { + /* Maximum possible region size with that base address */ + MemoryInfo.RegionSize = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1 - (PCHAR)Address; + } + } + } + else + { + /* Maximum possible region size with that base address */ + MemoryInfo.RegionSize = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1 - (PCHAR)Address; + } + + /* Check if we were attached */ + if (ProcessHandle != NtCurrentProcess()) + { + /* Detach and derefernece the process */ + KeUnstackDetachProcess(&ApcState); + ObDereferenceObject(TargetProcess); + } + + /* Build the rest of the initial information block */ + MemoryInfo.BaseAddress = Address; + MemoryInfo.AllocationBase = NULL; + MemoryInfo.AllocationProtect = 0; + MemoryInfo.State = MEM_FREE; + MemoryInfo.Protect = PAGE_NOACCESS; + MemoryInfo.Type = 0; + + /* Return the data (FIXME: Use SEH) */ + *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo; + if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); + + return STATUS_SUCCESS; } - + /* This must be a VM VAD */ ASSERT(Vad->u.VadFlags.PrivateMemory); diff --git a/subsystems/win32/csrss/win32csr/desktopbg.c b/subsystems/win32/csrss/win32csr/desktopbg.c index 1853ab6cc21..14a6155fb00 100644 --- a/subsystems/win32/csrss/win32csr/desktopbg.c +++ b/subsystems/win32/csrss/win32csr/desktopbg.c @@ -68,6 +68,10 @@ DtbgWindowProc(HWND Wnd, case WM_CLOSE: return 0; + case WM_DISPLAYCHANGE: + MoveWindow(Wnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE); + break; + case WM_NOTIFY: { PPRIVATE_NOTIFY_DESKTOP nmh = (PPRIVATE_NOTIFY_DESKTOP)lParam; diff --git a/subsystems/win32/win32k/CMakeLists.txt b/subsystems/win32/win32k/CMakeLists.txt index 0654d679df6..36f2ceb1a96 100644 --- a/subsystems/win32/win32k/CMakeLists.txt +++ b/subsystems/win32/win32k/CMakeLists.txt @@ -12,7 +12,8 @@ add_definitions(-DLANGPACK) add_definitions(-D_WIN32K_) list(APPEND SOURCE - dib/dib1bpp.c + dib/alphablend.c + dib/dib1bpp.c dib/dib4bpp.c dib/dib8bpp.c dib/dib16bpp.c @@ -34,12 +35,15 @@ list(APPEND SOURCE eng/float.c eng/gradient.c eng/lineto.c + eng/ldevobj.c eng/mapping.c eng/mem.c eng/engmisc.c eng/mouse.c eng/paint.c + eng/pdevobj.c eng/perfcnt.c + eng/rlecomp.c eng/semaphor.c eng/sort.c eng/string.c @@ -48,7 +52,6 @@ list(APPEND SOURCE eng/transblt.c eng/engwindow.c eng/xlate.c - ldr/loader.c main/dllmain.c misc/driver.c misc/err.c diff --git a/subsystems/win32/win32k/dib/alphablend.c b/subsystems/win32/win32k/dib/alphablend.c new file mode 100644 index 00000000000..be269cf5c37 --- /dev/null +++ b/subsystems/win32/win32k/dib/alphablend.c @@ -0,0 +1,123 @@ +/* + * PROJECT: Win32 subsystem + * LICENSE: See COPYING in the top level directory + * FILE: subsystems/win32/win32k/dib/stretchblt.c + * PURPOSE: AlphaBlend implementation suitable for all bit depths + * PROGRAMMERS: Jérôme Gardou + */ + +#include + +#define NDEBUG +#include + +typedef union +{ + ULONG ul; + struct + { + UCHAR red; + UCHAR green; + UCHAR blue; + UCHAR alpha; + } col; +} NICEPIXEL32; + +static __inline UCHAR +Clamp8(ULONG val) +{ + return (val > 255) ? 255 : val; +} + +BOOLEAN +DIB_XXBPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, + RECTL* SourceRect, CLIPOBJ* ClipRegion, + XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) +{ + INT DstX, DstY, SrcX, SrcY; + BLENDFUNCTION BlendFunc; + register NICEPIXEL32 DstPixel32; + register NICEPIXEL32 SrcPixel32; + UCHAR Alpha, SrcBpp = BitsPerFormat(Source->iBitmapFormat); + EXLATEOBJ* pexlo; + EXLATEOBJ exloSrcRGB, exloDstRGB, exloRGBSrc; + PFN_DIB_PutPixel pfnDibPutPixel = DibFunctionsForBitmapFormat[Dest->iBitmapFormat].DIB_PutPixel; + + DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", + SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, + DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); + + BlendFunc = BlendObj->BlendFunction; + if (BlendFunc.BlendOp != AC_SRC_OVER) + { + DPRINT1("BlendOp != AC_SRC_OVER\n"); + return FALSE; + } + if (BlendFunc.BlendFlags != 0) + { + DPRINT1("BlendFlags != 0\n"); + return FALSE; + } + if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) + { + DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); + return FALSE; + } + if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && + SrcBpp != 32) + { + DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); + return FALSE; + } + + if (!ColorTranslation) + { + DPRINT1("ColorTranslation must not be NULL!\n"); + return FALSE; + } + + pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); + EXLATEOBJ_vInitialize(&exloSrcRGB, pexlo->ppalSrc, &gpalRGB, 0, 0, 0); + EXLATEOBJ_vInitialize(&exloDstRGB, pexlo->ppalDst, &gpalRGB, 0, 0, 0); + EXLATEOBJ_vInitialize(&exloRGBSrc, &gpalRGB, pexlo->ppalSrc, 0, 0, 0); + + SrcY = SourceRect->top; + DstY = DestRect->top; + while ( DstY < DestRect->bottom ) + { + SrcX = SourceRect->left; + DstX = DestRect->left; + while(DstX < DestRect->right) + { + SrcPixel32.ul = DIB_GetSource(Source, SrcX, SrcY, &exloSrcRGB.xlo); + SrcPixel32.col.red = (SrcPixel32.col.red * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel32.col.green = (SrcPixel32.col.green * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel32.col.blue = (SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha) / 255; + + Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? + (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : + BlendFunc.SourceConstantAlpha ; + + DstPixel32.ul = DIB_GetSource(Dest, DstX, DstY, &exloDstRGB.xlo); + DstPixel32.col.red = Clamp8((DstPixel32.col.red * (255 - Alpha)) / 255 + SrcPixel32.col.red) ; + DstPixel32.col.green = Clamp8((DstPixel32.col.green * (255 - Alpha)) / 255 + SrcPixel32.col.green) ; + DstPixel32.col.blue = Clamp8((DstPixel32.col.blue * (255 - Alpha)) / 255 + SrcPixel32.col.blue) ; + DstPixel32.ul = XLATEOBJ_iXlate(&exloRGBSrc.xlo, DstPixel32.ul); + pfnDibPutPixel(Dest, DstX, DstY, XLATEOBJ_iXlate(ColorTranslation, DstPixel32.ul)); + + DstX++; + SrcX = SourceRect->left + ((DstX-DestRect->left)*(SourceRect->right - SourceRect->left)) + /(DestRect->right-DestRect->left); + } + DstY++; + SrcY = SourceRect->top + ((DstY-DestRect->top)*(SourceRect->bottom - SourceRect->top)) + /(DestRect->bottom-DestRect->top); + } + + EXLATEOBJ_vCleanup(&exloDstRGB); + EXLATEOBJ_vCleanup(&exloRGBSrc); + EXLATEOBJ_vCleanup(&exloSrcRGB); + + return TRUE; +} + diff --git a/subsystems/win32/win32k/dib/dib.c b/subsystems/win32/win32k/dib/dib.c index 30591d3d27d..2066c9e0b72 100644 --- a/subsystems/win32/win32k/dib/dib.c +++ b/subsystems/win32/win32k/dib/dib.c @@ -29,25 +29,25 @@ DIB_FUNCTIONS DibFunctionsForBitmapFormat[] = { DIB_1BPP_PutPixel, DIB_1BPP_GetPixel, DIB_1BPP_HLine, DIB_1BPP_VLine, DIB_1BPP_BitBlt, DIB_1BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt, - DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_1BPP_AlphaBlend + DIB_1BPP_TransparentBlt, DIB_1BPP_ColorFill, DIB_XXBPP_AlphaBlend }, /* BMF_4BPP */ { DIB_4BPP_PutPixel, DIB_4BPP_GetPixel, DIB_4BPP_HLine, DIB_4BPP_VLine, DIB_4BPP_BitBlt, DIB_4BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt, - DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_4BPP_AlphaBlend + DIB_4BPP_TransparentBlt, DIB_4BPP_ColorFill, DIB_XXBPP_AlphaBlend }, /* BMF_8BPP */ { DIB_8BPP_PutPixel, DIB_8BPP_GetPixel, DIB_8BPP_HLine, DIB_8BPP_VLine, DIB_8BPP_BitBlt, DIB_8BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt, - DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_8BPP_AlphaBlend + DIB_8BPP_TransparentBlt, DIB_8BPP_ColorFill, DIB_XXBPP_AlphaBlend }, /* BMF_16BPP */ { DIB_16BPP_PutPixel, DIB_16BPP_GetPixel, DIB_16BPP_HLine, DIB_16BPP_VLine, DIB_16BPP_BitBlt, DIB_16BPP_BitBltSrcCopy, DIB_XXBPP_StretchBlt, - DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_16BPP_AlphaBlend + DIB_16BPP_TransparentBlt, DIB_16BPP_ColorFill, DIB_XXBPP_AlphaBlend }, /* BMF_24BPP */ { diff --git a/subsystems/win32/win32k/dib/dib.h b/subsystems/win32/win32k/dib/dib.h index bae2199fe59..4ae455bc92b 100644 --- a/subsystems/win32/win32k/dib/dib.h +++ b/subsystems/win32/win32k/dib/dib.h @@ -78,7 +78,6 @@ BOOLEAN DIB_1BPP_BitBlt(PBLTINFO); BOOLEAN DIB_1BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_1BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_1BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); -BOOLEAN DIB_1BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); VOID DIB_4BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG); ULONG DIB_4BPP_GetPixel(SURFOBJ*,LONG,LONG); @@ -88,7 +87,6 @@ BOOLEAN DIB_4BPP_BitBlt(PBLTINFO); BOOLEAN DIB_4BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_4BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_4BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); -BOOLEAN DIB_4BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); VOID DIB_8BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG); ULONG DIB_8BPP_GetPixel(SURFOBJ*,LONG,LONG); @@ -98,7 +96,6 @@ BOOLEAN DIB_8BPP_BitBlt(PBLTINFO); BOOLEAN DIB_8BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_8BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_8BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); -BOOLEAN DIB_8BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); VOID DIB_16BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG); ULONG DIB_16BPP_GetPixel(SURFOBJ*,LONG,LONG); @@ -108,7 +105,6 @@ BOOLEAN DIB_16BPP_BitBlt(PBLTINFO); BOOLEAN DIB_16BPP_BitBltSrcCopy(PBLTINFO); BOOLEAN DIB_16BPP_TransparentBlt(SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,XLATEOBJ*,ULONG); BOOLEAN DIB_16BPP_ColorFill(SURFOBJ*, RECTL*, ULONG); -BOOLEAN DIB_16BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); VOID DIB_24BPP_PutPixel(SURFOBJ*,LONG,LONG,ULONG); ULONG DIB_24BPP_GetPixel(SURFOBJ*,LONG,LONG); @@ -132,6 +128,7 @@ BOOLEAN DIB_32BPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATE BOOLEAN DIB_XXBPP_StretchBlt(SURFOBJ*,SURFOBJ*,SURFOBJ*,SURFOBJ*,RECTL*,RECTL*,POINTL*,BRUSHOBJ*,POINTL*,XLATEOBJ*,ROP4); BOOLEAN DIB_XXBPP_FloodFillSolid(SURFOBJ*, BRUSHOBJ*, RECTL*, POINTL*, ULONG, UINT); +BOOLEAN DIB_XXBPP_AlphaBlend(SURFOBJ*, SURFOBJ*, RECTL*, RECTL*, CLIPOBJ*, XLATEOBJ*, BLENDOBJ*); extern unsigned char notmask[2]; extern unsigned char altnotmask[2]; diff --git a/subsystems/win32/win32k/dib/dib16bpp.c b/subsystems/win32/win32k/dib/dib16bpp.c index de569716586..a1d72ae7251 100644 --- a/subsystems/win32/win32k/dib/dib16bpp.c +++ b/subsystems/win32/win32k/dib/dib16bpp.c @@ -525,174 +525,4 @@ DIB_16BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return TRUE; } -typedef union -{ - ULONG ul; - struct - { - UCHAR red; - UCHAR green; - UCHAR blue; - UCHAR alpha; - } col; -} NICEPIXEL32; - -typedef union -{ - USHORT us; - struct - { - USHORT red:5, - green:6, - blue:5; - } col; -} NICEPIXEL16; - -static __inline UCHAR -Clamp5(ULONG val) -{ - return (val > 31) ? 31 : val; -} - -static __inline UCHAR -Clamp8(ULONG val) -{ - return (val > 255) ? 255 : val; -} - -static __inline UCHAR -Clamp6(ULONG val) -{ - return (val > 63) ? 63 : val; -} - -BOOLEAN -DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, - RECTL* SourceRect, CLIPOBJ* ClipRegion, - XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) -{ - INT Rows, Cols, SrcX, SrcY; - register PUSHORT Dst; - ULONG DstDelta; - BLENDFUNCTION BlendFunc; - register NICEPIXEL16 SrcPixel16; - register NICEPIXEL16 DstPixel16; - register NICEPIXEL32 SrcPixel32; - register NICEPIXEL32 DstPixel32; - UCHAR Alpha, SrcBpp; - EXLATEOBJ *pexlo; - EXLATEOBJ exloDst2Src; - - DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", - SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, - DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - - ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && - DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); - - BlendFunc = BlendObj->BlendFunction; - if (BlendFunc.BlendOp != AC_SRC_OVER) - { - DPRINT1("BlendOp != AC_SRC_OVER\n"); - return FALSE; - } - if (BlendFunc.BlendFlags != 0) - { - DPRINT1("BlendFlags != 0\n"); - return FALSE; - } - if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) - { - DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); - return FALSE; - } - if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && - BitsPerFormat(Source->iBitmapFormat) != 32) - { - DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); - return FALSE; - } - - if (!ColorTranslation) - { - DPRINT1("ColorTranslation must not be NULL!\n"); - return FALSE; - } - - pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); - EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0); - - Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + - (DestRect->left << 1)); - DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1); - SrcBpp = BitsPerFormat(Source->iBitmapFormat); - - Rows = DestRect->bottom - DestRect->top; - SrcY = SourceRect->top; - while (--Rows >= 0) - { - Cols = DestRect->right - DestRect->left; - SrcX = SourceRect->left; - while (--Cols >= 0) - { - if (SrcBpp <= 16) - { - SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel32.col.red = (SrcPixel16.col.red << 3); - SrcPixel32.col.green = (SrcPixel16.col.green << 2); - SrcPixel32.col.blue = (SrcPixel16.col.blue << 3); - - SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.alpha = (SrcBpp == 32) ? - (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : - BlendFunc.SourceConstantAlpha; - - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - - DstPixel16.us = *Dst; - DstPixel16.col.red = Clamp5(DstPixel16.col.red * (255 - Alpha) / 255 + - (SrcPixel32.col.red >> 3)); - - DstPixel16.col.green = Clamp6(DstPixel16.col.green * (255 - Alpha) / 255 + - (SrcPixel32.col.green >> 2)); - - DstPixel16.col.blue = Clamp5(DstPixel16.col.blue * (255 - Alpha) / 255 + - (SrcPixel32.col.blue >> 3)); - - *Dst++ = DstPixel16.us; - } - else - { - SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); - - SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.alpha = (SrcBpp == 32) ? - (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : - BlendFunc.SourceConstantAlpha; - - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - - DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst); - SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); - SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); - SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); - *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul); - } - } - - Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta); - SrcY++; - } - - EXLATEOBJ_vCleanup(&exloDst2Src); - - return TRUE; -} - /* EOF */ diff --git a/subsystems/win32/win32k/dib/dib1bpp.c b/subsystems/win32/win32k/dib/dib1bpp.c index 3686754e5dd..b924112351c 100644 --- a/subsystems/win32/win32k/dib/dib1bpp.c +++ b/subsystems/win32/win32k/dib/dib1bpp.c @@ -33,7 +33,7 @@ DIB_1BPP_GetPixel(SURFOBJ *SurfObj, LONG x, LONG y) VOID DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) { - while(x1 < x2) + while(x1 < x2) { DIB_1BPP_PutPixel(SurfObj, x1, y, c); x1++; @@ -43,7 +43,7 @@ DIB_1BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) VOID DIB_1BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) { - while(y1 < y2) + while(y1 < y2) { DIB_1BPP_PutPixel(SurfObj, x, y1, c); y1++; @@ -474,13 +474,4 @@ DIB_1BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return FALSE; } -BOOLEAN -DIB_1BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, - RECTL* SourceRect, CLIPOBJ* ClipRegion, - XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) -{ - UNIMPLEMENTED; - return FALSE; -} - /* EOF */ diff --git a/subsystems/win32/win32k/dib/dib24bpp.c b/subsystems/win32/win32k/dib/dib24bpp.c index 3810024a6f8..0642862b0b1 100644 --- a/subsystems/win32/win32k/dib/dib24bpp.c +++ b/subsystems/win32/win32k/dib/dib24bpp.c @@ -37,7 +37,7 @@ DIB_24BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) LONG lDelta = SurfObj->lDelta; c &= 0xFFFFFF; - while(y1++ < y2) + while(y1++ < y2) { *(PUSHORT)(addr) = c & 0xFFFF; *(addr + 2) = c >> 16; @@ -466,7 +466,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, { INT Rows, Cols, SrcX, SrcY; register PUCHAR Dst; - ULONG DstDelta; BLENDFUNCTION BlendFunc; register NICEPIXEL32 DstPixel, SrcPixel; UCHAR Alpha, SrcBpp; @@ -475,9 +474,6 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && - DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); - BlendFunc = BlendObj->BlendFunction; if (BlendFunc.BlendOp != AC_SRC_OVER) { @@ -503,39 +499,41 @@ DIB_24BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + (DestRect->left * 3)); - DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) * 3); SrcBpp = BitsPerFormat(Source->iBitmapFormat); - Rows = DestRect->bottom - DestRect->top; + Rows = 0; SrcY = SourceRect->top; - while (--Rows >= 0) - { - Cols = DestRect->right - DestRect->left; - SrcX = SourceRect->left; - while (--Cols >= 0) + while (++Rows <= DestRect->bottom - DestRect->top) + { + Cols = 0; + SrcX = SourceRect->left; + while (++Cols <= DestRect->right - DestRect->left) + { + SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation); + SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255; + if (!(BlendFunc.AlphaFormat & AC_SRC_ALPHA)) { - SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha; - - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha; - - /* copy only 24bits of dst */ - DstPixel.ul = *(PUSHORT)(Dst) + (*(Dst+2) << 16); - DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red); - DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green); - DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue); - /* copy back 24bits of result */ - *(PUSHORT)(Dst) = (USHORT)(DstPixel.ul & 0xFFFF); - *(Dst + 2) = (UCHAR)((DstPixel.ul >> 16) & 0xFF); - Dst = (PUCHAR)((ULONG_PTR)Dst + 3); + Alpha = BlendFunc.SourceConstantAlpha ; } - Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta); - SrcY++; - } + else + { + Alpha = (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255; + } + + DstPixel.col.red = Clamp8((*Dst * (255 - Alpha)) / 255 + SrcPixel.col.red) ; + DstPixel.col.green = Clamp8((*(Dst+1) * (255 - Alpha) / 255 + SrcPixel.col.green)) ; + DstPixel.col.blue = Clamp8((*(Dst+2) * (255 - Alpha)) / 255 + SrcPixel.col.blue) ; + *Dst++ = DstPixel.col.red; + *Dst++ = DstPixel.col.green; + *Dst++ = DstPixel.col.blue; + SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left); + } + Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) + + (DestRect->left*3)); + SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top); + } return TRUE; } diff --git a/subsystems/win32/win32k/dib/dib32bpp.c b/subsystems/win32/win32k/dib/dib32bpp.c index 6c4704b1c96..50c819380ce 100644 --- a/subsystems/win32/win32k/dib/dib32bpp.c +++ b/subsystems/win32/win32k/dib/dib32bpp.c @@ -54,8 +54,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) PBYTE SourceBits_4BPP, SourceLine_4BPP; PDWORD Source32, Dest32; - DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 - + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + + (BltInfo->DestRect.top * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left; switch (BltInfo->SourceSurface->iBitmapFormat) @@ -83,8 +83,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) break; case BMF_4BPP: - SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 - + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + SourceBits_4BPP = (PBYTE)BltInfo->SourceSurface->pvScan0 + + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + (BltInfo->SourcePoint.x >> 1); for (j=BltInfo->DestRect.top; jDestRect.bottom; j++) @@ -156,8 +156,8 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) break; case BMF_24BPP: - SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 - + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + SourceLine = (PBYTE)BltInfo->SourceSurface->pvScan0 + + (BltInfo->SourcePoint.y * BltInfo->SourceSurface->lDelta) + 3 * BltInfo->SourcePoint.x; DestLine = DestBits; @@ -182,7 +182,7 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) break; case BMF_32BPP: - if (NULL == BltInfo->XlateSourceToDest || + if (NULL == BltInfo->XlateSourceToDest || 0 != (BltInfo->XlateSourceToDest->flXlate & XO_TRIVIAL)) { if (BltInfo->DestRect.top < BltInfo->SourcePoint.y) @@ -197,10 +197,10 @@ DIB_32BPP_BitBltSrcCopy(PBLTINFO BltInfo) } else { - SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 - + ((BltInfo->SourcePoint.y - + BltInfo->DestRect.bottom - - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + SourceBits = (PBYTE)BltInfo->SourceSurface->pvScan0 + + ((BltInfo->SourcePoint.y + + BltInfo->DestRect.bottom + - BltInfo->DestRect.top - 1) * BltInfo->SourceSurface->lDelta) + 4 * BltInfo->SourcePoint.x; DestBits = (PBYTE)BltInfo->DestSurface->pvScan0 + ((BltInfo->DestRect.bottom - 1) * BltInfo->DestSurface->lDelta) + 4 * BltInfo->DestRect.left; for (j = BltInfo->DestRect.bottom - 1; BltInfo->DestRect.top <= j; j--) @@ -348,7 +348,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, { INT Rows, Cols, SrcX, SrcY; register PULONG Dst; - ULONG DstDelta; BLENDFUNCTION BlendFunc; register NICEPIXEL32 DstPixel, SrcPixel; UCHAR Alpha, SrcBpp; @@ -357,9 +356,6 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && - DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); - BlendFunc = BlendObj->BlendFunction; if (BlendFunc.BlendOp != AC_SRC_OVER) { @@ -385,35 +381,38 @@ DIB_32BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + (DestRect->left << 2)); - DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 2); SrcBpp = BitsPerFormat(Source->iBitmapFormat); - Rows = DestRect->bottom - DestRect->top; - SrcY = SourceRect->top; - while (--Rows >= 0) + Rows = 0; + SrcY = SourceRect->top; + while (++Rows <= DestRect->bottom - DestRect->top) { - Cols = DestRect->right - DestRect->left; + Cols = 0; SrcX = SourceRect->left; - while (--Cols >= 0) + while (++Cols <= DestRect->right - DestRect->left) { - SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha; + SrcPixel.ul = DIB_GetSource(Source, SrcX, SrcY, ColorTranslation); + SrcPixel.col.red = (SrcPixel.col.red * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel.col.green = (SrcPixel.col.green * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel.col.blue = (SrcPixel.col.blue * BlendFunc.SourceConstantAlpha) / 255; + SrcPixel.col.alpha = (32 == SrcBpp) ? + (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha) / 255 : + BlendFunc.SourceConstantAlpha ; Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha; + SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha ; DstPixel.ul = *Dst; - DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red); - DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green); - DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue); - DstPixel.col.alpha = Clamp8(DstPixel.col.alpha * (255 - Alpha) / 255 + SrcPixel.col.alpha); + DstPixel.col.red = Clamp8((DstPixel.col.red * (255 - Alpha)) / 255 + SrcPixel.col.red) ; + DstPixel.col.green = Clamp8((DstPixel.col.green * (255 - Alpha)) / 255 + SrcPixel.col.green) ; + DstPixel.col.blue = Clamp8((DstPixel.col.blue * (255 - Alpha)) / 255 + SrcPixel.col.blue) ; + DstPixel.col.alpha = Clamp8((DstPixel.col.alpha * (255 - Alpha)) / 255 + SrcPixel.col.alpha) ; *Dst++ = DstPixel.ul; + SrcX = SourceRect->left + (Cols*(SourceRect->right - SourceRect->left))/(DestRect->right - DestRect->left); } - Dst = (PULONG)((ULONG_PTR)Dst + DstDelta); - SrcY++; + Dst = (PULONG)((ULONG_PTR)Dest->pvScan0 + ((DestRect->top + Rows) * Dest->lDelta) + + (DestRect->left << 2)); + SrcY = SourceRect->top + (Rows*(SourceRect->bottom - SourceRect->top))/(DestRect->bottom - DestRect->top); } return TRUE; diff --git a/subsystems/win32/win32k/dib/dib4bpp.c b/subsystems/win32/win32k/dib/dib4bpp.c index 1626b8e8397..e27c2264b70 100644 --- a/subsystems/win32/win32k/dib/dib4bpp.c +++ b/subsystems/win32/win32k/dib/dib4bpp.c @@ -32,7 +32,7 @@ DIB_4BPP_HLine(SURFOBJ *SurfObj, LONG x1, LONG x2, LONG y, ULONG c) PBYTE addr = (PBYTE)SurfObj->pvScan0 + (x1>>1) + y * SurfObj->lDelta; LONG cx = x1; - while(cx < x2) + while(cx < x2) { *addr = (*addr & notmask[x1&1]) | (c << ((1-(x1&1))<<2)); if((++x1 & 1) == 0) @@ -48,7 +48,7 @@ DIB_4BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) int lDelta = SurfObj->lDelta; addr += (x>>1) + y1 * lDelta; - while(y1++ < y2) + while(y1++ < y2) { *addr = (*addr & notmask[x&1]) | (c << ((1-(x&1))<<2)); addr += lDelta; @@ -81,8 +81,8 @@ DIB_4BPP_BitBltSrcCopy(PBLTINFO BltInfo) if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0) { DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0)); - } - else + } + else { DIB_4BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1)); } @@ -375,13 +375,4 @@ DIB_4BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return FALSE; } -BOOLEAN -DIB_4BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, - RECTL* SourceRect, CLIPOBJ* ClipRegion, - XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) -{ - UNIMPLEMENTED; - return FALSE; -} - /* EOF */ diff --git a/subsystems/win32/win32k/dib/dib8bpp.c b/subsystems/win32/win32k/dib/dib8bpp.c index 3fac604f5c4..e13331c8042 100644 --- a/subsystems/win32/win32k/dib/dib8bpp.c +++ b/subsystems/win32/win32k/dib/dib8bpp.c @@ -43,7 +43,7 @@ DIB_8BPP_VLine(SURFOBJ *SurfObj, LONG x, LONG y1, LONG y2, ULONG c) LONG lDelta = SurfObj->lDelta; byteaddr = addr; - while(y1++ < y2) + while(y1++ < y2) { *addr = c; @@ -74,8 +74,8 @@ DIB_8BPP_BitBltSrcCopy(PBLTINFO BltInfo) if(DIB_1BPP_GetPixel(BltInfo->SourceSurface, sx, sy) == 0) { DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 0)); - } - else + } + else { DIB_8BPP_PutPixel(BltInfo->DestSurface, i, j, XLATEOBJ_iXlate(BltInfo->XlateSourceToDest, 1)); } @@ -362,130 +362,4 @@ DIB_8BPP_TransparentBlt(SURFOBJ *DestSurf, SURFOBJ *SourceSurf, return TRUE; } -typedef union { - ULONG ul; - struct { - UCHAR red; - UCHAR green; - UCHAR blue; - UCHAR alpha; - } col; -} NICEPIXEL32; - -typedef union { - USHORT us; - struct { - USHORT red:5, - green:6, - blue:5; - } col; -} NICEPIXEL16; - -static __inline UCHAR -Clamp8(ULONG val) -{ - return (val > 255) ? 255 : val; -} - -BOOLEAN -DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect, - RECTL* SourceRect, CLIPOBJ* ClipRegion, - XLATEOBJ* ColorTranslation, BLENDOBJ* BlendObj) -{ - INT Rows, Cols, SrcX, SrcY; - register PUCHAR Dst; - ULONG DstDelta; - BLENDFUNCTION BlendFunc; - register NICEPIXEL32 DstPixel32; - register NICEPIXEL32 SrcPixel32; - register NICEPIXEL16 SrcPixel16; - UCHAR Alpha, SrcBpp; - EXLATEOBJ exloDst2Src; - EXLATEOBJ* pexlo; - - DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n", - SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom, - DestRect->left, DestRect->top, DestRect->right, DestRect->bottom); - - ASSERT(DestRect->bottom - DestRect->top == SourceRect->bottom - SourceRect->top && - DestRect->right - DestRect->left == SourceRect->right - SourceRect->left); - - BlendFunc = BlendObj->BlendFunction; - if (BlendFunc.BlendOp != AC_SRC_OVER) - { - DPRINT1("BlendOp != AC_SRC_OVER\n"); - return FALSE; - } - if (BlendFunc.BlendFlags != 0) - { - DPRINT1("BlendFlags != 0\n"); - return FALSE; - } - if ((BlendFunc.AlphaFormat & ~AC_SRC_ALPHA) != 0) - { - DPRINT1("Unsupported AlphaFormat (0x%x)\n", BlendFunc.AlphaFormat); - return FALSE; - } - if ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0 && - BitsPerFormat(Source->iBitmapFormat) != 32) - { - DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n"); - return FALSE; - } - if (!ColorTranslation) - { - DPRINT1("ColorTranslation must not be NULL!\n"); - return FALSE; - } - - pexlo = CONTAINING_RECORD(ColorTranslation, EXLATEOBJ, xlo); - EXLATEOBJ_vInitialize(&exloDst2Src, pexlo->ppalDst, pexlo->ppalSrc, 0, 0, 0); - - Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) + - DestRect->left); - DstDelta = Dest->lDelta - (DestRect->right - DestRect->left); - SrcBpp = BitsPerFormat(Source->iBitmapFormat); - - Rows = DestRect->bottom - DestRect->top; - SrcY = SourceRect->top; - while (--Rows >= 0) - { - Cols = DestRect->right - DestRect->left; - SrcX = SourceRect->left; - while (--Cols >= 0) - { - if (SrcBpp <= 16) - { - SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation); - SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2); - SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4); - SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2); - } - else - { - SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY); - } - SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255; - SrcPixel32.col.alpha = (SrcBpp == 32) ? (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha; - - Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ? - SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha; - - DstPixel32.ul = XLATEOBJ_iXlate(&exloDst2Src.xlo, *Dst); - SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red); - SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green); - SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue); - *Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul); - } - Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta); - SrcY++; - } - - EXLATEOBJ_vCleanup(&exloDst2Src); - - return TRUE; -} - /* EOF */ diff --git a/subsystems/win32/win32k/eng/alphablend.c b/subsystems/win32/win32k/eng/alphablend.c index 34b2930cd68..afd1b5e5f54 100644 --- a/subsystems/win32/win32k/eng/alphablend.c +++ b/subsystems/win32/win32k/eng/alphablend.c @@ -1,4 +1,4 @@ -/* +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: GDI alpha blending functions @@ -25,10 +25,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest, IN PRECTL SourceRect, IN BLENDOBJ *BlendObj) { - RECTL SourceStretchedRect; - SIZEL SourceStretchedSize; - HBITMAP SourceStretchedBitmap = 0; - SURFOBJ* SourceStretchedObj = NULL; RECTL InputRect; RECTL OutputRect; RECTL ClipRect; @@ -39,7 +35,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest, INTENG_ENTER_LEAVE EnterLeaveDest; SURFOBJ* InputObj; SURFOBJ* OutputObj; - LONG Width; LONG ClippingType; RECT_ENUM RectEnum; BOOL EnumMore; @@ -71,7 +66,7 @@ EngAlphaBlend(IN SURFOBJ *psoDest, InputRect = *SourceRect; if ( (InputRect.top < 0) || (InputRect.bottom < 0) || (InputRect.left < 0) || (InputRect.right < 0) || - InputRect.right > psoSource->sizlBitmap.cx || + InputRect.right > psoSource->sizlBitmap.cx || InputRect.bottom > psoSource->sizlBitmap.cy ) { SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -111,68 +106,9 @@ EngAlphaBlend(IN SURFOBJ *psoDest, return TRUE; } - /* Stretch source if needed */ - if (OutputRect.right - OutputRect.left != InputRect.right - InputRect.left || - OutputRect.bottom - OutputRect.top != InputRect.bottom - InputRect.top) - { - SourceStretchedSize.cx = OutputRect.right - OutputRect.left; - SourceStretchedSize.cy = OutputRect.bottom - OutputRect.top; - Width = DIB_GetDIBWidthBytes(SourceStretchedSize.cx, BitsPerFormat(psoSource->iBitmapFormat)); - /* FIXME: Maybe it is a good idea to use EngCreateDeviceBitmap and IntEngStretchBlt - if possible to get a HW accelerated stretch. */ - SourceStretchedBitmap = EngCreateBitmap(SourceStretchedSize, Width, psoSource->iBitmapFormat, - BMF_TOPDOWN | BMF_NOZEROINIT, NULL); - if (SourceStretchedBitmap == 0) - { - DPRINT1("EngCreateBitmap failed!\n"); - return FALSE; - } - SourceStretchedObj = EngLockSurface((HSURF)SourceStretchedBitmap); - if (SourceStretchedObj == NULL) - { - DPRINT1("EngLockSurface failed!\n"); - EngDeleteSurface((HSURF)SourceStretchedBitmap); - return FALSE; - } - - SourceStretchedRect.left = 0; - SourceStretchedRect.right = SourceStretchedSize.cx; - SourceStretchedRect.top = 0; - SourceStretchedRect.bottom = SourceStretchedSize.cy; - /* FIXME: IntEngStretchBlt isn't used here atm because it results in a - try to acquire an already acquired mutex (lock the already locked source surface) */ - /*if (!IntEngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, - NULL, &SourceStretchedRect, SourceRect, NULL, - NULL, NULL, COLORONCOLOR))*/ - if (!EngStretchBlt(SourceStretchedObj, psoSource, NULL, NULL, NULL, - NULL, NULL, &SourceStretchedRect, &InputRect, - NULL, COLORONCOLOR)) - { - DPRINT1("EngStretchBlt failed!\n"); - EngFreeMem(SourceStretchedObj->pvBits); - EngUnlockSurface(SourceStretchedObj); - EngDeleteSurface((HSURF)SourceStretchedBitmap); - return FALSE; - } - InputRect.top = SourceStretchedRect.top; - InputRect.bottom = SourceStretchedRect.bottom; - InputRect.left = SourceStretchedRect.left; - InputRect.right = SourceStretchedRect.right; - psoSource = SourceStretchedObj; - } - /* Now call the DIB function */ if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj)) { - if (SourceStretchedObj != NULL) - { - EngFreeMem(SourceStretchedObj->pvBits); - EngUnlockSurface(SourceStretchedObj); - } - if (SourceStretchedBitmap != 0) - { - EngDeleteSurface((HSURF)SourceStretchedBitmap); - } return FALSE; } InputRect.left += Translate.x; @@ -182,16 +118,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest, if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj)) { - IntEngLeave(&EnterLeaveSource); - if (SourceStretchedObj != NULL) - { - EngFreeMem(SourceStretchedObj->pvBits); - EngUnlockSurface(SourceStretchedObj); - } - if (SourceStretchedBitmap != 0) - { - EngDeleteSurface((HSURF)SourceStretchedBitmap); - } return FALSE; } OutputRect.left += Translate.x; @@ -261,16 +187,6 @@ EngAlphaBlend(IN SURFOBJ *psoDest, IntEngLeave(&EnterLeaveDest); IntEngLeave(&EnterLeaveSource); - if (SourceStretchedObj != NULL) - { - EngFreeMem(SourceStretchedObj->pvBits); - EngUnlockSurface(SourceStretchedObj); - } - if (SourceStretchedBitmap != 0) - { - EngDeleteSurface((HSURF)SourceStretchedBitmap); - } - return Ret; } @@ -305,17 +221,8 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest, return TRUE; } - SURFACE_LockBitmapBits(psurfDest); - MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top, - DestRect->right, DestRect->bottom); - - if (psoSource != psoDest) - SURFACE_LockBitmapBits(psurfSource); - MouseSafetyOnDrawStart(psoSource, SourceRect->left, SourceRect->top, - SourceRect->right, SourceRect->bottom); - /* Call the driver's DrvAlphaBlend if available */ - if (psurfDest->flHooks & HOOK_ALPHABLEND) + if (psurfDest->flags & HOOK_ALPHABLEND) { ret = GDIDEVFUNCS(psoDest).AlphaBlend( psoDest, psoSource, ClipRegion, ColorTranslation, @@ -328,12 +235,6 @@ IntEngAlphaBlend(IN SURFOBJ *psoDest, DestRect, SourceRect, BlendObj); } - MouseSafetyOnDrawEnd(psoSource); - if (psoSource != psoDest) - SURFACE_UnlockBitmapBits(psurfSource); - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurfDest); - return ret; } diff --git a/subsystems/win32/win32k/eng/bitblt.c b/subsystems/win32/win32k/eng/bitblt.c index b74e890cfd0..e6dd4970d5c 100644 --- a/subsystems/win32/win32k/eng/bitblt.c +++ b/subsystems/win32/win32k/eng/bitblt.c @@ -522,7 +522,7 @@ EngBitBlt(SURFOBJ *DestObj, } BOOL APIENTRY -IntEngBitBltEx( +IntEngBitBlt( SURFOBJ *psoTrg, SURFOBJ *psoSrc, SURFOBJ *psoMask, @@ -533,8 +533,7 @@ IntEngBitBltEx( POINTL *pptlMask, BRUSHOBJ *pbo, POINTL *pptlBrush, - ROP4 rop4, - BOOL bRemoveMouse) + ROP4 rop4) { SURFACE *psurfTrg; SURFACE *psurfSrc = NULL; @@ -583,28 +582,11 @@ IntEngBitBltEx( psurfSrc = NULL; } - if (bRemoveMouse) - { - SURFACE_LockBitmapBits(psurfTrg); - - if (psoSrc) - { - if (psoSrc != psoTrg) - { - SURFACE_LockBitmapBits(psurfSrc); - } - MouseSafetyOnDrawStart(psoSrc, rclSrc.left, rclSrc.top, - rclSrc.right, rclSrc.bottom); - } - MouseSafetyOnDrawStart(psoTrg, rclClipped.left, rclClipped.top, - rclClipped.right, rclClipped.bottom); - } - /* Is the target surface device managed? */ - if (psurfTrg->flHooks & HOOK_BITBLT) + if (psurfTrg->flags & HOOK_BITBLT) { /* Is the source a different device managed surface? */ - if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flHooks & HOOK_BITBLT) + if (psoSrc && psoSrc->hdev != psoTrg->hdev && psurfSrc->flags & HOOK_BITBLT) { DPRINT1("Need to copy to standard bitmap format!\n"); ASSERT(FALSE); @@ -614,7 +596,7 @@ IntEngBitBltEx( } /* Is the source surface device managed? */ - else if (psoSrc && psurfSrc->flHooks & HOOK_BITBLT) + else if (psoSrc && psurfSrc->flags & HOOK_BITBLT) { pfnBitBlt = GDIDEVFUNCS(psoSrc).BitBlt; } @@ -637,21 +619,6 @@ IntEngBitBltEx( // FIXME: cleanup temp surface! - if (bRemoveMouse) - { - MouseSafetyOnDrawEnd(psoTrg); - if (psoSrc) - { - MouseSafetyOnDrawEnd(psoSrc); - if (psoSrc != psoTrg) - { - SURFACE_UnlockBitmapBits(psurfSrc); - } - } - - SURFACE_UnlockBitmapBits(psurfTrg); - } - return bResult; } @@ -983,27 +950,20 @@ IntEngMaskBlt(SURFOBJ *psoDest, ASSERT(psoDest); psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); - SURFACE_LockBitmapBits(psurfDest); - MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top, - OutputRect.right, OutputRect.bottom); - /* Dummy BitBlt to let driver know that it should flush its changes. This should really be done using a call to DrvSynchronizeSurface, but the VMware driver doesn't hook that call. */ - IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, + IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, DestRect, pptlMask, pptlMask, pbo, BrushOrigin, - R4_NOOP, FALSE); + R4_NOOP); ret = EngMaskBitBlt(psoDest, psoMask, ClipRegion, DestColorTranslation, SourceColorTranslation, &OutputRect, &InputPoint, pbo, BrushOrigin); /* Dummy BitBlt to let driver know that something has changed. */ - IntEngBitBltEx(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, + IntEngBitBlt(psoDest, NULL, psoMask, ClipRegion, DestColorTranslation, DestRect, pptlMask, pptlMask, pbo, BrushOrigin, - R4_NOOP, FALSE); - - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurfDest); + R4_NOOP); return ret; } diff --git a/subsystems/win32/win32k/eng/copybits.c b/subsystems/win32/win32k/eng/copybits.c index 73a477dd13d..afb2f16cc99 100644 --- a/subsystems/win32/win32k/eng/copybits.c +++ b/subsystems/win32/win32k/eng/copybits.c @@ -53,13 +53,7 @@ EngCopyBits(SURFOBJ *psoDest, ASSERT(psoDest != NULL && psoSource != NULL && DestRect != NULL && SourcePoint != NULL); psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); - SURFACE_LockBitmapBits(psurfSource); - psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); - if (psoDest != psoSource) - { - SURFACE_LockBitmapBits(psurfDest); - } // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, // mark the copy block function to be DrvCopyBits instead of the @@ -73,7 +67,7 @@ EngCopyBits(SURFOBJ *psoDest, if (psoDest->iType!=STYPE_BITMAP) { /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ - if (psurfDest->flHooks & HOOK_COPYBITS) + if (psurfDest->flags & HOOK_COPYBITS) { ret = GDIDEVFUNCS(psoDest).CopyBits( psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); @@ -86,7 +80,7 @@ EngCopyBits(SURFOBJ *psoDest, if (psoSource->iType!=STYPE_BITMAP) { /* FIXME: Eng* functions shouldn't call Drv* functions. ? */ - if (psurfSource->flHooks & HOOK_COPYBITS) + if (psurfSource->flags & HOOK_COPYBITS) { ret = GDIDEVFUNCS(psoSource).CopyBits( psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); @@ -180,12 +174,6 @@ EngCopyBits(SURFOBJ *psoDest, } cleanup: - if (psoDest != psoSource) - { - SURFACE_UnlockBitmapBits(psurfDest); - } - SURFACE_UnlockBitmapBits(psurfSource); - return ret; } @@ -198,20 +186,7 @@ IntEngCopyBits( RECTL *prclDest, POINTL *ptlSource) { - BOOL bResult; - - MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y, - (ptlSource->x + abs(prclDest->right - prclDest->left)), - (ptlSource->y + abs(prclDest->bottom - prclDest->top))); - - MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom); - - bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource); - - MouseSafetyOnDrawEnd(psoDest); - MouseSafetyOnDrawEnd(psoSource); - - return bResult; + return EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource); } diff --git a/subsystems/win32/win32k/eng/device.c b/subsystems/win32/win32k/eng/device.c index 0e51ea05eef..0965a967fc8 100644 --- a/subsystems/win32/win32k/eng/device.c +++ b/subsystems/win32/win32k/eng/device.c @@ -12,6 +12,264 @@ #define NDEBUG #include +PGRAPHICS_DEVICE gpPrimaryGraphicsDevice; +PGRAPHICS_DEVICE gpVgaGraphicsDevice; + +static PGRAPHICS_DEVICE gpGraphicsDeviceFirst = NULL; +static PGRAPHICS_DEVICE gpGraphicsDeviceLast = NULL; +static HSEMAPHORE ghsemGraphicsDeviceList; +static ULONG giDevNum = 1; + +BOOL +NTAPI +InitDeviceImpl() +{ + ghsemGraphicsDeviceList = EngCreateSemaphore(); + if (!ghsemGraphicsDeviceList) + return FALSE; + + return TRUE; +} + + +PGRAPHICS_DEVICE +NTAPI +EngpRegisterGraphicsDevice( + PUNICODE_STRING pustrDeviceName, + PUNICODE_STRING pustrDiplayDrivers, + PUNICODE_STRING pustrDescription, + PDEVMODEW pdmDefault) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVICE_OBJECT pDeviceObject; + PFILE_OBJECT pFileObject; + NTSTATUS Status; + PWSTR pwsz; + ULONG i, cj, cModes = 0; + BOOL bEnable = TRUE; + PDEVMODEINFO pdminfo; + PDEVMODEW pdm, pdmEnd; + PLDEVOBJ pldev; + + DPRINT1("EngpRegisterGraphicsDevice(%S)\n", pustrDeviceName->Buffer); + + /* Allocate a GRAPHICS_DEVICE structure */ + pGraphicsDevice = ExAllocatePoolWithTag(PagedPool, + sizeof(GRAPHICS_DEVICE), + GDITAG_GDEVICE); + if (!pGraphicsDevice) + { + DPRINT1("ExAllocatePoolWithTag failed\n"); + return NULL; + } + + /* Try to open the driver */ + Status = IoGetDeviceObjectPointer(pustrDeviceName, + FILE_READ_DATA | FILE_WRITE_DATA, + &pFileObject, + &pDeviceObject); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not open driver, 0x%lx\n", Status); + ExFreePoolWithTag(pGraphicsDevice, GDITAG_GDEVICE); + return NULL; + } + + /* Enable the device */ + EngFileWrite(pFileObject, &bEnable, sizeof(BOOL), &cj); + + /* Copy the device and file object pointers */ + pGraphicsDevice->DeviceObject = pDeviceObject; + pGraphicsDevice->FileObject = pFileObject; + + /* Copy device name */ + wcsncpy(pGraphicsDevice->szNtDeviceName, + pustrDeviceName->Buffer, + sizeof(pGraphicsDevice->szNtDeviceName) / sizeof(WCHAR)); + + /* Create a win device name (FIXME: virtual devices!) */ + swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (CHAR)giDevNum); + + /* Allocate a buffer for the strings */ + cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); + pwsz = ExAllocatePoolWithTag(PagedPool, cj, GDITAG_DRVSUP); + if (!pwsz) + { + DPRINT1("Could not allocate string buffer\n"); + ASSERT(FALSE); // FIXME + } + + /* Copy display driver names */ + pGraphicsDevice->pDiplayDrivers = pwsz; + RtlCopyMemory(pGraphicsDevice->pDiplayDrivers, + pustrDiplayDrivers->Buffer, + pustrDiplayDrivers->Length); + + /* Copy description */ + pGraphicsDevice->pwszDescription = pwsz + pustrDiplayDrivers->Length / sizeof(WCHAR); + RtlCopyMemory(pGraphicsDevice->pwszDescription, + pustrDescription->Buffer, + pustrDescription->Length + sizeof(WCHAR)); + + /* Initialize the pdevmodeInfo list and default index */ + pGraphicsDevice->pdevmodeInfo = NULL; + pGraphicsDevice->iDefaultMode = 0; + pGraphicsDevice->iCurrentMode = 0; + + // FIXME: initialize state flags + pGraphicsDevice->StateFlags = 0; + + /* Loop through the driver names + * This is a REG_MULTI_SZ string */ + for (; *pwsz; pwsz += wcslen(pwsz) + 1) + { + DPRINT1("trying driver: %ls\n", pwsz); + /* Try to load the display driver */ + pldev = EngLoadImageEx(pwsz, LDEV_DEVICE_DISPLAY); + if (!pldev) + { + DPRINT1("Could not load driver: '%ls'\n", pwsz); + continue; + } + + /* Get the mode list from the driver */ + pdminfo = LDEVOBJ_pdmiGetModes(pldev, pDeviceObject); + if (!pdminfo) + { + DPRINT1("Could not get mode list for '%ls'\n", pwsz); + continue; + } + + /* Attach the mode info to the device */ + pdminfo->pdmiNext = pGraphicsDevice->pdevmodeInfo; + pGraphicsDevice->pdevmodeInfo = pdminfo; + + /* Count DEVMODEs */ + pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); + for (pdm = pdminfo->adevmode; + pdm + 1 <= pdmEnd; + pdm = (DEVMODEW*)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) + { + cModes++; + } + + // FIXME: release the driver again until it's used? + } + + if (!pGraphicsDevice->pdevmodeInfo || cModes == 0) + { + DPRINT1("No devmodes\n"); + ExFreePool(pGraphicsDevice); + return NULL; + } + + /* Allocate an index buffer */ + pGraphicsDevice->cDevModes = cModes; + pGraphicsDevice->pDevModeList = ExAllocatePoolWithTag(PagedPool, + cModes * sizeof(DEVMODEENTRY), + GDITAG_GDEVICE); + if (!pGraphicsDevice->pDevModeList) + { + DPRINT1("No devmode list\n"); + ExFreePool(pGraphicsDevice); + return NULL; + } + + /* Loop through all DEVMODEINFOs */ + for (pdminfo = pGraphicsDevice->pdevmodeInfo, i = 0; + pdminfo; + pdminfo = pdminfo->pdmiNext) + { + /* Calculate End of the DEVMODEs */ + pdmEnd = (DEVMODEW*)((PCHAR)pdminfo->adevmode + pdminfo->cbdevmode); + + /* Loop through the DEVMODEs */ + for (pdm = pdminfo->adevmode; + pdm + 1 <= pdmEnd; + pdm = (PDEVMODEW)((PCHAR)pdm + pdm->dmSize + pdm->dmDriverExtra)) + { + /* Compare with the default entry */ + if (pdm->dmBitsPerPel == pdmDefault->dmBitsPerPel && + pdm->dmPelsWidth == pdmDefault->dmPelsWidth && + pdm->dmPelsHeight == pdmDefault->dmPelsHeight && + pdm->dmDisplayFrequency == pdmDefault->dmDisplayFrequency) + { + pGraphicsDevice->iDefaultMode = i; + pGraphicsDevice->iCurrentMode = i; + DPRINT1("Found default entry: %ld '%ls'\n", i, pdm->dmDeviceName); + } + + /* Initialize the entry */ + pGraphicsDevice->pDevModeList[i].dwFlags = 0; + pGraphicsDevice->pDevModeList[i].pdm = pdm; + i++; + } + } + + /* Lock loader */ + EngAcquireSemaphore(ghsemGraphicsDeviceList); + + /* Insert the device into the global list */ + pGraphicsDevice->pNextGraphicsDevice = gpGraphicsDeviceLast; + gpGraphicsDeviceLast = pGraphicsDevice; + if (!gpGraphicsDeviceFirst) + gpGraphicsDeviceFirst = pGraphicsDevice; + + /* Increment device number */ + giDevNum++; + + /* Unlock loader */ + EngReleaseSemaphore(ghsemGraphicsDeviceList); + DPRINT1("Prepared %ld modes for %ls\n", cModes, pGraphicsDevice->pwszDescription); + + return pGraphicsDevice; +} + + +PGRAPHICS_DEVICE +NTAPI +EngpFindGraphicsDevice( + PUNICODE_STRING pustrDevice, + ULONG iDevNum, + DWORD dwFlags) +{ + UNICODE_STRING ustrCurrent; + PGRAPHICS_DEVICE pGraphicsDevice; + ULONG i; + + /* Lock list */ + EngAcquireSemaphore(ghsemGraphicsDeviceList); + + if (pustrDevice) + { + /* Loop through the list of devices */ + for (pGraphicsDevice = gpGraphicsDeviceFirst; + pGraphicsDevice; + pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice) + { + /* Compare the device name */ + RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName); + if (RtlEqualUnicodeString(&ustrCurrent, pustrDevice, FALSE)) + { + break; + } + } + } + else + { + /* Loop through the list of devices */ + for (pGraphicsDevice = gpGraphicsDeviceFirst, i = 0; + pGraphicsDevice && i < iDevNum; + pGraphicsDevice = pGraphicsDevice->pNextGraphicsDevice, i++); + } + + /* Unlock list */ + EngReleaseSemaphore(ghsemGraphicsDeviceList); + + return pGraphicsDevice; +} + + static NTSTATUS EngpFileIoRequest( @@ -39,7 +297,7 @@ EngpFileIoRequest( /* Initialize an event */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); - /* Build IPR */ + /* Build IRP */ liStartOffset.QuadPart = ullStartOffset; pIrp = IoBuildSynchronousFsdRequest(ulMajorFunction, pDeviceObject, @@ -113,7 +371,7 @@ EngFileIoControl( /* Initialize an event */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); - /* Build IO control IPR */ + /* Build IO control IRP */ pIrp = IoBuildDeviceIoControlRequest(dwIoControlCode, pDeviceObject, lpInBuffer, diff --git a/subsystems/win32/win32k/eng/engbrush.c b/subsystems/win32/win32k/eng/engbrush.c index a13d11b5385..c61e0e47f9f 100644 --- a/subsystems/win32/win32k/eng/engbrush.c +++ b/subsystems/win32/win32k/eng/engbrush.c @@ -18,8 +18,6 @@ VOID NTAPI EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) { - HPALETTE hpal = NULL; - ASSERT(pebo); ASSERT(pbrush); ASSERT(pdc); @@ -35,14 +33,11 @@ EBRUSHOBJ_vInit(EBRUSHOBJ *pebo, PBRUSH pbrush, PDC pdc) pebo->crCurrentText = pdc->pdcattr->crForegroundClr; pebo->psurfTrg = pdc->dclevel.pSurface; -// ASSERT(pebo->psurfTrg); // FIXME: some dcs don't have a surface + ASSERT(pebo->psurfTrg); + ASSERT(pebo->psurfTrg->ppal); - if (pebo->psurfTrg) - hpal = pebo->psurfTrg->hDIBPalette; - if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault; - pebo->ppalSurf = PALETTE_ShareLockPalette(hpal); - if (!pebo->ppalSurf) - pebo->ppalSurf = &gpalRGB; + pebo->ppalSurf = pebo->psurfTrg->ppal; + GDIOBJ_IncrementShareCount(&pebo->ppalSurf->BaseObject); if (pbrush->flAttrs & GDIBRUSH_IS_NULL) { @@ -80,7 +75,12 @@ EBRUSHOBJ_vSetSolidBrushColor(EBRUSHOBJ *pebo, COLORREF crColor) pebo->ulRGBColor = crColor; /* Initialize an XLATEOBJ RGB -> surface */ - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, pebo->ppalSurf, 0, 0, 0); + EXLATEOBJ_vInitialize(&exlo, + &gpalRGB, + pebo->ppalSurf, + pebo->crCurrentBack, + 0, + 0); /* Translate the brush color to the target format */ iSolidColor = XLATEOBJ_iXlate(&exlo.xlo, crColor); @@ -109,8 +109,7 @@ EBRUSHOBJ_vCleanup(EBRUSHOBJ *pebo) pebo->BrushObject.pvRbrush = NULL; } - if (pebo->ppalSurf != &gpalRGB) - PALETTE_ShareUnlockPalette(pebo->ppalSurf); + PALETTE_ShareUnlockPalette(pebo->ppalSurf); } VOID @@ -145,7 +144,7 @@ EngRealizeBrush( ULONG lWidth; /* Calculate width in bytes of the realized brush */ - lWidth = DIB_GetDIBWidthBytes(psoPattern->sizlBitmap.cx, + lWidth = WIDTH_BYTES_ALIGN32(psoPattern->sizlBitmap.cx, BitsPerFormat(psoDst->iBitmapFormat)); /* Allocate a bitmap */ @@ -192,12 +191,8 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) PPDEVOBJ ppdev = NULL; EXLATEOBJ exlo; - // FIXME: all EBRUSHOBJs need a surface, see EBRUSHOBJ_vInit - if (!pebo->psurfTrg) - { - DPRINT1("Pattern brush has no target surface!\n"); - return FALSE; - } + /* All EBRUSHOBJs have a surface, see EBRUSHOBJ_vInit */ + ASSERT(pebo->psurfTrg); ppdev = (PPDEVOBJ)pebo->psurfTrg->SurfObj.hdev; @@ -210,16 +205,18 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) psurfPattern = SURFACE_ShareLockSurface(pebo->pbrush->hbmPattern); ASSERT(psurfPattern); + ASSERT(psurfPattern->ppal); /* FIXME: implement mask */ psurfMask = NULL; /* Initialize XLATEOBJ for the brush */ - EXLATEOBJ_vInitBrushXlate(&exlo, - pebo->pbrush, - pebo->psurfTrg, - pebo->crCurrentText, - pebo->crCurrentBack); + EXLATEOBJ_vInitialize(&exlo, + psurfPattern->ppal, + pebo->psurfTrg->ppal, + 0, + pebo->crCurrentBack, + pebo->crCurrentText); /* Create the realization */ bResult = pfnRealzizeBrush(&pebo->BrushObject, diff --git a/subsystems/win32/win32k/eng/engmisc.c b/subsystems/win32/win32k/eng/engmisc.c index af544c95d55..31ea864dc9d 100644 --- a/subsystems/win32/win32k/eng/engmisc.c +++ b/subsystems/win32/win32k/eng/engmisc.c @@ -56,7 +56,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, { /* Driver needs to support DrvCopyBits, else we can't do anything */ SURFACE *psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); - if (!(psurfDest->flHooks & HOOK_COPYBITS)) + if (!(psurfDest->flags & HOOK_COPYBITS)) { return FALSE; } @@ -64,7 +64,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, /* Allocate a temporary bitmap */ BitmapSize.cx = DestRect->right - DestRect->left; BitmapSize.cy = DestRect->bottom - DestRect->top; - Width = DIB_GetDIBWidthBytes(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat)); + Width = WIDTH_BYTES_ALIGN32(BitmapSize.cx, BitsPerFormat(psoDest->iBitmapFormat)); EnterLeave->OutputBitmap = EngCreateBitmap(BitmapSize, Width, psoDest->iBitmapFormat, BMF_TOPDOWN | BMF_NOZEROINIT, NULL); @@ -127,7 +127,6 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, &ClippedDestRect, &SrcPoint)) { EngDeleteClip(EnterLeave->TrivialClipObj); - EngFreeMem((*ppsoOutput)->pvBits); EngUnlockSurface(*ppsoOutput); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); return FALSE; @@ -149,7 +148,7 @@ IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave, if (NULL != *ppsoOutput) { SURFACE* psurfOutput = CONTAINING_RECORD(*ppsoOutput, SURFACE, SurfObj); - if (0 != (psurfOutput->flHooks & HOOK_SYNCHRONIZE)) + if (0 != (psurfOutput->flags & HOOK_SYNCHRONIZE)) { if (NULL != GDIDEVFUNCS(*ppsoOutput).SynchronizeSurface) { @@ -219,7 +218,6 @@ IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave) Result = TRUE; } } - EngFreeMem(EnterLeave->OutputObj->pvBits); EngUnlockSurface(EnterLeave->OutputObj); EngDeleteSurface((HSURF)EnterLeave->OutputBitmap); EngDeleteClip(EnterLeave->TrivialClipObj); diff --git a/subsystems/win32/win32k/eng/gradient.c b/subsystems/win32/win32k/eng/gradient.c index c3ef6535c04..75faeae5c33 100644 --- a/subsystems/win32/win32k/eng/gradient.c +++ b/subsystems/win32/win32k/eng/gradient.c @@ -548,14 +548,7 @@ IntEngGradientFill( psurf = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); ASSERT(psurf); - SURFACE_LockBitmapBits(psurf); - MouseSafetyOnDrawStart( - psoDest, - pco->rclBounds.left, - pco->rclBounds.top, - pco->rclBounds.right, - pco->rclBounds.bottom); - if(psurf->flHooks & HOOK_GRADIENTFILL) + if(psurf->flags & HOOK_GRADIENTFILL) { Ret = GDIDEVFUNCS(psoDest).GradientFill( psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, @@ -566,8 +559,6 @@ IntEngGradientFill( Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents, pptlDitherOrg, ulMode); } - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurf); return Ret; } diff --git a/subsystems/win32/win32k/eng/ldevobj.c b/subsystems/win32/win32k/eng/ldevobj.c new file mode 100644 index 00000000000..6296a01b385 --- /dev/null +++ b/subsystems/win32/win32k/eng/ldevobj.c @@ -0,0 +1,504 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Support for logical devices + * FILE: subsystems/win32/win32k/eng/ldevobj.c + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +#include + +#include + +#define NDEBUG +#include + +#ifndef RVA_TO_ADDR +#define RVA_TO_ADDR(Base,Rva) ((PVOID)(((ULONG_PTR)(Base)) + (Rva))) +#endif + +/** Globals *******************************************************************/ + +HSEMAPHORE ghsemLDEVList; +LDEVOBJ *gpldevHead = NULL; +LDEVOBJ *gpldevWin32k = NULL; + + +/** Private functions *********************************************************/ + +BOOL +NTAPI +InitLDEVImpl() +{ + /* Initialize the loader lock */ + ghsemLDEVList = EngCreateSemaphore(); + if (!ghsemLDEVList) + { + return FALSE; + } + + /* Allocate a LDEVOBJ for win32k */ + gpldevWin32k = ExAllocatePoolWithTag(PagedPool, + sizeof(LDEVOBJ) + + sizeof(SYSTEM_GDI_DRIVER_INFORMATION), + GDITAG_LDEV); + if (!gpldevWin32k) + { + return FALSE; + } + + /* Initialize the LDEVOBJ for win32k */ + gpldevWin32k->pldevNext = NULL; + gpldevWin32k->pldevPrev = NULL; + gpldevWin32k->ldevtype = LDEV_DEVICE_DISPLAY; + gpldevWin32k->cRefs = 1; + gpldevWin32k->ulDriverVersion = GDI_ENGINE_VERSION; + gpldevWin32k->pGdiDriverInfo = (PVOID)(gpldevWin32k + 1); + RtlInitUnicodeString(&gpldevWin32k->pGdiDriverInfo->DriverName, + L"\\SystemRoot\\System32\\win32k.sys"); + gpldevWin32k->pGdiDriverInfo->ImageAddress = &__ImageBase; + gpldevWin32k->pGdiDriverInfo->SectionPointer = NULL; + gpldevWin32k->pGdiDriverInfo->EntryPoint = (PVOID)DriverEntry; + gpldevWin32k->pGdiDriverInfo->ExportSectionPointer = NULL; + gpldevWin32k->pGdiDriverInfo->ImageLength = 0; // FIXME; + + return TRUE; +} + +PLDEVOBJ +NTAPI +LDEVOBJ_AllocLDEV(LDEVTYPE ldevtype) +{ + PLDEVOBJ pldev; + + /* Allocate the structure from paged pool */ + pldev = ExAllocatePoolWithTag(PagedPool, sizeof(LDEVOBJ), GDITAG_LDEV); + if (!pldev) + { + DPRINT1("Failed to allocate LDEVOBJ.\n"); + return NULL; + } + + /* Zero out the structure */ + RtlZeroMemory(pldev, sizeof(LDEVOBJ)); + + /* Set the ldevtype */ + pldev->ldevtype = ldevtype; + + return pldev; +} + +VOID +NTAPI +LDEVOBJ_vFreeLDEV(PLDEVOBJ pldev) +{ + /* Make sure we don't have a driver loaded */ + ASSERT(pldev && pldev->pGdiDriverInfo == NULL); + + /* Free the memory */ + ExFreePoolWithTag(pldev, TAG_LDEV); +} + +PDEVMODEINFO +NTAPI +LDEVOBJ_pdmiGetModes( + PLDEVOBJ pldev, + HANDLE hDriver) +{ + ULONG cbSize, cbFull; + PDEVMODEINFO pdminfo; + + DPRINT("LDEVOBJ_pdmiGetModes(%p, %p)\n", pldev, hDriver); + + /* Call the driver to get the required size */ + cbSize = pldev->pfn.GetModes(hDriver, 0, NULL); + if (!cbSize) + { + DPRINT1("DrvGetModes returned 0\n"); + return NULL; + } + + /* Add space for the header */ + cbFull = cbSize + FIELD_OFFSET(DEVMODEINFO, adevmode); + + /* Allocate a buffer for the DEVMODE array */ + pdminfo = ExAllocatePoolWithTag(PagedPool, cbFull, GDITAG_DEVMODE); + if (!pdminfo) + { + DPRINT1("Could not allocate devmodeinfo\n"); + return NULL; + } + + pdminfo->pldev = pldev; + pdminfo->cbdevmode = cbSize; + + /* Call the driver again to fill the buffer */ + cbSize = pldev->pfn.GetModes(hDriver, cbSize, pdminfo->adevmode); + if (!cbSize) + { + /* Could not get modes */ + DPRINT1("returned size %ld(%ld)\n", cbSize, pdminfo->cbdevmode); + ExFreePool(pdminfo); + pdminfo = NULL; + } + + return pdminfo; +} + + +BOOL +NTAPI +LDEVOBJ_bLoadImage( + IN PLDEVOBJ pldev, + PUNICODE_STRING pstrPathName) +{ + PSYSTEM_GDI_DRIVER_INFORMATION pDriverInfo; + NTSTATUS Status; + ULONG cbSize; + + /* Make sure no image is loaded yet */ + ASSERT(pldev && pldev->pGdiDriverInfo == NULL); + + /* Allocate a SYSTEM_GDI_DRIVER_INFORMATION structure */ + cbSize = sizeof(SYSTEM_GDI_DRIVER_INFORMATION) + pstrPathName->Length; + pDriverInfo = ExAllocatePoolWithTag(PagedPool, cbSize, GDITAG_LDEV); + if (!pDriverInfo) + { + DPRINT1("Failed to allocate SYSTEM_GDI_DRIVER_INFORMATION\n"); + return FALSE; + } + + /* Initialize the UNICODE_STRING and copy the driver name */ + RtlInitEmptyUnicodeString(&pDriverInfo->DriverName, + (PWSTR)(pDriverInfo + 1), + pstrPathName->Length); + RtlCopyUnicodeString(&pDriverInfo->DriverName, pstrPathName); + + /* Try to load the driver */ + Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, + pDriverInfo, + sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to load a GDI driver: '%S', Status = 0x%lx\n", + pstrPathName->Buffer, Status); + + /* Free the allocated memory */ + ExFreePoolWithTag(pDriverInfo, TAG_LDEV); + return FALSE; + } + + /* Set the driver info */ + pldev->pGdiDriverInfo = pDriverInfo; + + /* Return success. */ + return TRUE; +} + +VOID +NTAPI +LDEVOBJ_vUnloadImage( + IN PLDEVOBJ pldev) +{ + NTSTATUS Status; + + /* Make sure we have a driver info */ + ASSERT(pldev && pldev->pGdiDriverInfo != NULL); + + /* Check if we have loaded a driver */ + if (pldev->pfn.DisableDriver) + { + /* Call the unload function */ + pldev->pfn.DisableDriver(); + } + + /* Unload the driver */ + Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation, + &pldev->pGdiDriverInfo->ImageAddress, + sizeof(HANDLE)); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to unload the driver, this is bad.\n"); + } + + /* Free the driver info structure */ + ExFreePoolWithTag(pldev->pGdiDriverInfo, GDITAG_LDEV); + pldev->pGdiDriverInfo = NULL; +} + +BOOL +NTAPI +LDEVOBJ_bLoadDriver( + IN PLDEVOBJ pldev) +{ + PFN_DrvEnableDriver pfnEnableDriver; + DRVENABLEDATA ded; + ULONG i; + + /* Make sure we have a driver info */ + ASSERT(pldev && pldev->pGdiDriverInfo != NULL); + + /* Call the drivers DrvEnableDriver function */ + RtlZeroMemory(&ded, sizeof(ded)); + pfnEnableDriver = pldev->pGdiDriverInfo->EntryPoint; + if (!pfnEnableDriver(GDI_ENGINE_VERSION, sizeof(ded), &ded)) + { + DPRINT1("DrvEnableDriver failed\n"); + + /* Unload the image. */ + LDEVOBJ_vUnloadImage(pldev); + return FALSE; + } + + /* Copy the returned driver version */ + pldev->ulDriverVersion = ded.iDriverVersion; + + /* Fill the driver function array */ + for (i = 0; i < ded.c; i++) + { + pldev->apfn[ded.pdrvfn[i].iFunc] = ded.pdrvfn[i].pfn; + } + + /* Return success. */ + return TRUE; +} + + +PVOID +NTAPI +LDEVOBJ_pvFindImageProcAddress( + IN PLDEVOBJ pldev, + IN LPSTR pszProcName) +{ + PVOID pvImageBase; + PIMAGE_EXPORT_DIRECTORY pExportDir; + PVOID pvProcAdress = NULL; + PUSHORT pOrdinals; + PULONG pNames, pAddresses; + ULONG i, cbSize; + + /* Make sure we have a driver info */ + ASSERT(pldev && pldev->pGdiDriverInfo != NULL); + + /* Get the pointer to the export directory */ + pvImageBase = pldev->pGdiDriverInfo->ImageAddress; + pExportDir = RtlImageDirectoryEntryToData(pvImageBase, + TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, + &cbSize); + if (!pExportDir) + { + return NULL; + } + + /* Get pointers to some tables */ + pNames = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNames); + pOrdinals = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfNameOrdinals); + pAddresses = RVA_TO_ADDR(pvImageBase, pExportDir->AddressOfFunctions); + + /* Loop the export table */ + for (i = 0; i < pExportDir->NumberOfNames; i++) + { + /* Compare the name */ + if (_stricmp(pszProcName, RVA_TO_ADDR(pvImageBase, pNames[i])) == 0) + { + /* Found! Calculate the procedure address */ + pvProcAdress = RVA_TO_ADDR(pvImageBase, pAddresses[pOrdinals[i]]); + break; + } + } + + /* Return the address */ + return pvProcAdress; +} + +PLDEVOBJ +NTAPI +EngLoadImageEx( + LPWSTR pwszDriverName, + ULONG ldevtype) +{ + WCHAR acwBuffer[MAX_PATH]; + PLDEVOBJ pldev; + UNICODE_STRING strDriverName; + ULONG cwcLength; + LPWSTR pwsz; + + DPRINT("EngLoadImageEx(%ls, %ld)\n", pwszDriverName, ldevtype); + ASSERT(pwszDriverName); + + /* Initialize buffer for the the driver name */ + RtlInitEmptyUnicodeString(&strDriverName, acwBuffer, sizeof(acwBuffer)); + + /* Start path with systemroot */ + RtlAppendUnicodeToString(&strDriverName, L"\\SystemRoot\\System32\\"); + + /* Get Length of given string */ + cwcLength = wcslen(pwszDriverName); + + /* Check if we have a system32 path given */ + pwsz = pwszDriverName + cwcLength; + while (pwsz > pwszDriverName) + { + if (_wcsnicmp(pwsz, L"\\system32\\", 10) == 0) + { + /* Driver name starts after system32 */ + pwsz += 10; + break; + } + pwsz--; + } + + /* Append the driver name */ + RtlAppendUnicodeToString(&strDriverName, pwsz); + + /* MSDN says "The driver must include this suffix in the pwszDriver string." + But in fact it's optional. */ + if (_wcsnicmp(pwszDriverName + cwcLength - 4, L".dll", 4) != 0) + { + /* Append the .dll suffix */ + RtlAppendUnicodeToString(&strDriverName, L".dll"); + } + + /* Lock loader */ + EngAcquireSemaphore(ghsemLDEVList); + + /* Search the List of LDEVS for the driver name */ + for (pldev = gpldevHead; pldev != NULL; pldev = pldev->pldevNext) + { + /* Check if the ldev is associated with a file */ + if (pldev->pGdiDriverInfo) + { + /* Check for match (case insensative) */ + if (RtlEqualUnicodeString(&pldev->pGdiDriverInfo->DriverName, &strDriverName, 1)) + { + /* Image found in LDEV list */ + break; + } + } + } + + /* Did we find one? */ + if (!pldev) + { + /* No, allocate a new LDEVOBJ */ + pldev = LDEVOBJ_AllocLDEV(ldevtype); + if (!pldev) + { + DPRINT1("Could not allocate LDEV\n"); + goto leave; + } + + /* Load the image */ + if (!LDEVOBJ_bLoadImage(pldev, &strDriverName)) + { + LDEVOBJ_vFreeLDEV(pldev); + pldev = NULL; + DPRINT1("LDEVOBJ_bLoadImage failed\n"); + goto leave; + } + + /* Shall we load a driver? */ + if (ldevtype != LDEV_IMAGE) + { + /* Load the driver */ + if (!LDEVOBJ_bLoadDriver(pldev)) + { + DPRINT1("LDEVOBJ_bLoadDriver failed\n"); + LDEVOBJ_vFreeLDEV(pldev); + pldev = NULL; + goto leave; + } + } + + /* Insert the LDEV into the global list */ + pldev->pldevPrev = NULL; + pldev->pldevNext = gpldevHead; + gpldevHead = pldev; + } + + /* Increase ref count */ + pldev->cRefs++; + +leave: + /* Unlock loader */ + EngReleaseSemaphore(ghsemLDEVList); + + DPRINT("EngLoadImageEx returning %p\n", pldev); + + return pldev; +} + + +/** Exported functions ********************************************************/ + +HANDLE +APIENTRY +EngLoadImage( + LPWSTR pwszDriverName) +{ + return (HANDLE)EngLoadImageEx(pwszDriverName, LDEV_IMAGE); +} + + +VOID +APIENTRY +EngUnloadImage( + IN HANDLE hModule) +{ + PLDEVOBJ pldev = (PLDEVOBJ)hModule; + + /* Make sure the LDEV is in the list */ + ASSERT(pldev->pldevPrev || pldev->pldevNext); + + /* Lock loader */ + EngAcquireSemaphore(ghsemLDEVList); + + /* Decrement reference count */ + pldev->cRefs--; + + /* No more references left? */ + if (pldev->cRefs == 0) + { + /* Remove ldev from the list */ + if (pldev->pldevPrev) + pldev->pldevPrev->pldevNext = pldev->pldevNext; + if (pldev->pldevNext) + pldev->pldevNext->pldevPrev = pldev->pldevPrev; + + /* Unload the image */ + LDEVOBJ_vUnloadImage(pldev); + } + + /* Unlock loader */ + EngReleaseSemaphore(ghsemLDEVList); +} + + +PVOID +APIENTRY +EngFindImageProcAddress( + IN HANDLE hModule, + IN LPSTR lpProcName) +{ + PLDEVOBJ pldev = (PLDEVOBJ)hModule; + + ASSERT(gpldevWin32k != NULL); + + /* Check if win32k is requested */ + if (!pldev) + { + pldev = gpldevWin32k; + } + + /* Check if the drivers entry point is requested */ + if (_strnicmp(lpProcName, "DrvEnableDriver", 15) == 0) + { + return pldev->pGdiDriverInfo->EntryPoint; + } + + /* Try to find the address */ + return LDEVOBJ_pvFindImageProcAddress(pldev, lpProcName); +} + diff --git a/subsystems/win32/win32k/eng/lineto.c b/subsystems/win32/win32k/eng/lineto.c index a67b47af5b1..d5db687be0e 100644 --- a/subsystems/win32/win32k/eng/lineto.c +++ b/subsystems/win32/win32k/eng/lineto.c @@ -565,10 +565,7 @@ IntEngLineTo(SURFOBJ *psoDest, if (b.left == b.right) b.right++; if (b.top == b.bottom) b.bottom++; - SURFACE_LockBitmapBits(psurfDest); - MouseSafetyOnDrawStart(psoDest, x1, y1, x2, y2); - - if (psurfDest->flHooks & HOOK_LINETO) + if (psurfDest->flags & HOOK_LINETO) { /* Call the driver's DrvLineTo */ ret = GDIDEVFUNCS(psoDest).LineTo( @@ -576,7 +573,7 @@ IntEngLineTo(SURFOBJ *psoDest, } #if 0 - if (! ret && (psurfDest->flHooks & HOOK_STROKEPATH)) + if (! ret && (psurfDest->flags & HOOK_STROKEPATH)) { /* FIXME: Emulate LineTo using drivers DrvStrokePath and set ret on success */ } @@ -587,9 +584,6 @@ IntEngLineTo(SURFOBJ *psoDest, ret = EngLineTo(psoDest, ClipObj, pbo, x1, y1, x2, y2, RectBounds, Mix); } - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurfDest); - return ret; } diff --git a/subsystems/win32/win32k/eng/mapping.c b/subsystems/win32/win32k/eng/mapping.c index 7e445d7c631..0da46dfca29 100644 --- a/subsystems/win32/win32k/eng/mapping.c +++ b/subsystems/win32/win32k/eng/mapping.c @@ -3,7 +3,7 @@ * PROJECT: ReactOS kernel * PURPOSE: Functions for mapping files and sections * FILE: subsys/win32k/eng/device.c - * PROGRAMER: + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */ #include @@ -11,12 +11,348 @@ #define NDEBUG #include +// HACK!!! +#define MmMapViewInSessionSpace MmMapViewInSystemSpace +#define MmUnmapViewInSessionSpace MmUnmapViewInSystemSpace + +typedef struct _ENGSECTION +{ + PVOID pvSectionObject; + PVOID pvMappedBase; + SIZE_T cjViewSize; + ULONG ulTag; +} ENGSECTION, *PENGSECTION; + +typedef struct _FILEVIEW +{ + LARGE_INTEGER LastWriteTime; + PVOID pvKView; + PVOID pvViewFD; + SIZE_T cjView; + PVOID pSection; +} FILEVIEW, *PFILEVIEW; + +typedef struct _FONTFILEVIEW +{ + FILEVIEW; + DWORD reserved[2]; + PWSTR pwszPath; + SIZE_T ulRegionSize; + ULONG cKRefCount; + ULONG cRefCountFD; + PVOID pvSpoolerBase; + DWORD dwSpoolerPid; +} FONTFILEVIEW, *PFONTFILEVIEW; + +enum +{ + FVF_SYSTEMROOT = 1, + FVF_READONLY = 2, + FVF_FONTFILE = 4, +}; + +HANDLE ghSystem32Directory; +HANDLE ghRootDirectory; + + +PVOID +NTAPI +EngCreateSection( + IN ULONG fl, + IN SIZE_T cjSize, + IN ULONG ulTag) +{ + NTSTATUS Status; + PENGSECTION pSection; + PVOID pvSectionObject; + LARGE_INTEGER liSize; + + /* Allocate a section object */ + pSection = EngAllocMem(0, sizeof(ENGSECTION), 'stsU'); + if (!pSection) return NULL; + + liSize.QuadPart = cjSize; + Status = MmCreateSection(&pvSectionObject, + SECTION_ALL_ACCESS, + NULL, + &liSize, + PAGE_READWRITE, + SEC_COMMIT, + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create a section Status=0x%x\n", Status); + EngFreeMem(pSection); + return NULL; + } + + /* Set the fields of the section */ + pSection->ulTag = ulTag; + pSection->pvSectionObject = pvSectionObject; + pSection->pvMappedBase = NULL; + pSection->cjViewSize = cjSize; + + return pSection; +} + + +BOOL +APIENTRY +EngMapSection( + IN PVOID pvSection, + IN BOOL bMap, + IN HANDLE hProcess, + OUT PVOID* pvBaseAddress) +{ + NTSTATUS Status; + PENGSECTION pSection = pvSection; + PEPROCESS pepProcess; + + /* Get a pointer to the process */ + Status = ObReferenceObjectByHandle(hProcess, + PROCESS_VM_OPERATION, + NULL, + KernelMode, + (PVOID*)&pepProcess, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not access process %p, Status=0x%lx\n", hProcess, Status); + return FALSE; + } + + if (bMap) + { + /* Make sure the section isn't already mapped */ + ASSERT(pSection->pvMappedBase == NULL); + + /* Map the section into the process address space */ + Status = MmMapViewOfSection(pSection->pvSectionObject, + pepProcess, + &pSection->pvMappedBase, + 0, + pSection->cjViewSize, + NULL, + &pSection->cjViewSize, + 0, + 0, + PAGE_READWRITE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + } + } + else + { + /* Make sure the section is mapped */ + ASSERT(pSection->pvMappedBase); + + /* Unmap the section from the process address space */ + Status = MmUnmapViewOfSection(pepProcess, pSection->pvMappedBase); + if (NT_SUCCESS(Status)) + { + pSection->pvMappedBase = NULL; + } + else + { + DPRINT1("Failed to unmap a section @ &p Status=0x%x\n", + pSection->pvMappedBase, Status); + } + } + + /* Dereference the process */ + ObDereferenceObject(pepProcess); + + /* Set the new mapping base and return bool status */ + *pvBaseAddress = pSection->pvMappedBase; + return NT_SUCCESS(Status); +} + +BOOL +APIENTRY +EngFreeSectionMem( + IN PVOID pvSection OPTIONAL, + IN PVOID pvMappedBase OPTIONAL) +{ + NTSTATUS Status; + PENGSECTION pSection = pvSection; + BOOL bResult = TRUE; + + /* Did the caller give us a mapping base? */ + if (pvMappedBase) + { + Status = MmUnmapViewInSessionSpace(pvMappedBase); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status); + bResult = FALSE; + } + } + + /* Check if we should free the section as well */ + if (pSection) + { + /* Dereference the kernel section */ + ObDereferenceObject(pSection->pvSectionObject); + + /* Finally free the section memory itself */ + EngFreeMem(pSection); + } + + return bResult; +} + +PVOID +APIENTRY +EngAllocSectionMem( + OUT PVOID *ppvSection, + IN ULONG fl, + IN SIZE_T cjSize, + IN ULONG ulTag) +{ + NTSTATUS Status; + PENGSECTION pSection; + + /* Check parameter */ + if (cjSize == 0) return NULL; + + /* Allocate a section object */ + pSection = EngCreateSection(fl, cjSize, ulTag); + if (!pSection) + { + *ppvSection = NULL; + return NULL; + } + + /* Map the section in session space */ + Status = MmMapViewInSessionSpace(pSection->pvSectionObject, + &pSection->pvMappedBase, + &pSection->cjViewSize); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + *ppvSection = NULL; + EngFreeSectionMem(pSection, NULL); + return NULL; + } + + if (fl & FL_ZERO_MEMORY) + { + RtlZeroMemory(pSection->pvMappedBase, cjSize); + } + + /* Set section pointer and return base address */ + *ppvSection = pSection; + return pSection->pvMappedBase; +} + + +PFILEVIEW +NTAPI +EngLoadModuleEx( + LPWSTR pwsz, + ULONG cjSizeOfModule, + FLONG fl) +{ + PFILEVIEW pFileView = NULL; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE hRootDir; + UNICODE_STRING ustrFileName; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION FileInformation; + HANDLE hFile; + NTSTATUS Status; + LARGE_INTEGER liSize; + + if (fl & FVF_FONTFILE) + { + pFileView = EngAllocMem(0, sizeof(FONTFILEVIEW), 'vffG'); + } + else + { + pFileView = EngAllocMem(0, sizeof(FILEVIEW), 'liFg'); + } + + /* Check for success */ + if (!pFileView) return NULL; + + /* Check if the file is relative to system32 */ + if (fl & FVF_SYSTEMROOT) + { + hRootDir = ghSystem32Directory; + } + else + { + hRootDir = ghRootDirectory; + } + + /* Initialize unicode string and object attributes */ + RtlInitUnicodeString(&ustrFileName, pwsz); + InitializeObjectAttributes(&ObjectAttributes, + &ustrFileName, + OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE, + hRootDir, + NULL); + + /* Now open the file */ + Status = ZwCreateFile(&hFile, + FILE_READ_DATA, + &ObjectAttributes, + &IoStatusBlock, + NULL, + FILE_ATTRIBUTE_NORMAL, + 0, + FILE_OPEN, + FILE_NON_DIRECTORY_FILE, + NULL, + 0); + + Status = ZwQueryInformationFile(hFile, + &IoStatusBlock, + &FileInformation, + sizeof(FILE_BASIC_INFORMATION), + FileBasicInformation); + if (NT_SUCCESS(Status)) + { + pFileView->LastWriteTime = FileInformation.LastWriteTime; + } + + /* Create a section from the file */ + liSize.QuadPart = cjSizeOfModule; + Status = MmCreateSection(&pFileView->pSection, + SECTION_ALL_ACCESS, + NULL, + cjSizeOfModule ? &liSize : NULL, + fl & FVF_READONLY ? PAGE_EXECUTE_READ : PAGE_EXECUTE_READWRITE, + SEC_COMMIT, + hFile, + NULL); + + /* Close the file handle */ + ZwClose(hFile); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create a section Status=0x%x\n", Status); + EngFreeMem(pFileView); + return NULL; + } + + + pFileView->pvKView = NULL; + pFileView->pvViewFD = NULL; + pFileView->cjView = 0; + + return pFileView; +} + HANDLE APIENTRY EngLoadModule(LPWSTR pwsz) { - UNIMPLEMENTED; - return NULL; + /* Forward to EngLoadModuleEx */ + return (HANDLE)EngLoadModuleEx(pwsz, 0, FVF_READONLY | FVF_SYSTEMROOT); } HANDLE @@ -25,9 +361,8 @@ EngLoadModuleForWrite( IN LPWSTR pwsz, IN ULONG cjSizeOfModule) { - // www.osr.com/ddk/graphics/gdifncs_98rr.htm - UNIMPLEMENTED; - return NULL; + /* Forward to EngLoadModuleEx */ + return (HANDLE)EngLoadModuleEx(pwsz, cjSizeOfModule, FVF_SYSTEMROOT); } PVOID @@ -36,17 +371,46 @@ EngMapModule( IN HANDLE h, OUT PULONG pulSize) { - // www.osr.com/ddk/graphics/gdifncs_9b1j.htm - UNIMPLEMENTED; - return NULL; + PFILEVIEW pFileView = (PFILEVIEW)h; + NTSTATUS Status; + + pFileView->cjView = 0; + + /* Map the section in session space */ + Status = MmMapViewInSessionSpace(pFileView->pSection, + &pFileView->pvKView, + &pFileView->cjView); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to map a section Status=0x%x\n", Status); + *pulSize = 0; + return NULL; + } + + *pulSize = pFileView->cjView; + return pFileView->pvKView; } VOID APIENTRY -EngFreeModule (IN HANDLE h) +EngFreeModule(IN HANDLE h) { - // www.osr.com/ddk/graphics/gdifncs_9fzb.htm - UNIMPLEMENTED; + PFILEVIEW pFileView = (PFILEVIEW)h; + NTSTATUS Status; + + /* Unmap the section */ + Status = MmUnmapViewInSessionSpace(pFileView->pvKView); + if (!NT_SUCCESS(Status)) + { + DPRINT1("MmUnmapViewInSessionSpace failed: 0x%lx\n", Status); + ASSERT(FALSE); + } + + /* Dereference the section */ + ObDereferenceObject(pFileView->pSection); + + /* Free the file view memory */ + EngFreeMem(pFileView); } PVOID @@ -56,8 +420,28 @@ EngMapFile( IN ULONG cjSize, OUT ULONG_PTR *piFile) { - UNIMPLEMENTED; - return NULL; + HANDLE hModule; + PVOID pvBase; + + /* Load the file */ + hModule = EngLoadModuleEx(pwsz, 0, 0); + if (!hModule) + { + *piFile = 0; + return NULL; + } + + /* Map the file */ + pvBase = EngMapModule(hModule, &cjSize); + if (!pvBase) + { + EngFreeModule(hModule); + hModule = NULL; + } + + /* Set iFile and return mapped base */ + *piFile = (ULONG_PTR)hModule; + return pvBase; } BOOL @@ -65,8 +449,11 @@ APIENTRY EngUnmapFile( IN ULONG_PTR iFile) { - UNIMPLEMENTED; - return FALSE; + HANDLE hModule = (HANDLE)iFile; + + EngFreeModule(hModule); + + return TRUE; } @@ -110,36 +497,3 @@ EngUnmapFontFile( // www.osr.com/ddk/graphics/gdifncs_09wn.htm EngUnmapFontFileFD(iFile); } - - -BOOLEAN -APIENTRY -EngMapSection(IN PVOID Section, - IN BOOLEAN Map, - IN HANDLE Process, - IN PVOID* BaseAddress) -{ - UNIMPLEMENTED; - return FALSE; -} - -PVOID -APIENTRY -EngAllocSectionMem(IN PVOID SectionObject, - IN ULONG Flags, - IN SIZE_T MemSize, - IN ULONG Tag) -{ - UNIMPLEMENTED; - return NULL; -} - - -BOOLEAN -APIENTRY -EngFreeSectionMem(IN PVOID SectionObject OPTIONAL, - IN PVOID MappedBase) -{ - UNIMPLEMENTED; - return FALSE; -} diff --git a/subsystems/win32/win32k/eng/mem.c b/subsystems/win32/win32k/eng/mem.c index a49e4fe5cab..1fb81b339bc 100644 --- a/subsystems/win32/win32k/eng/mem.c +++ b/subsystems/win32/win32k/eng/mem.c @@ -79,6 +79,7 @@ EngAllocUserMem(SIZE_T cj, ULONG Tag) } /* TODO: Add allocation info to AVL tree (stored inside W32PROCESS structure) */ + //hSecure = EngSecureMem(NewMem, cj); return NewMem; } @@ -166,6 +167,7 @@ HackUnsecureVirtualMemory( HANDLE APIENTRY EngSecureMem(PVOID Address, ULONG Length) { + return (HANDLE)-1; // HACK!!! return MmSecureVirtualMemory(Address, Length, PAGE_READWRITE); } @@ -175,6 +177,7 @@ EngSecureMem(PVOID Address, ULONG Length) VOID APIENTRY EngUnsecureMem(HANDLE Mem) { + if (Mem == (HANDLE)-1) return; // HACK!!! MmUnsecureVirtualMemory((PVOID) Mem); } diff --git a/subsystems/win32/win32k/eng/mouse.c b/subsystems/win32/win32k/eng/mouse.c index 93ab14d4f6d..b2db0e61af7 100644 --- a/subsystems/win32/win32k/eng/mouse.c +++ b/subsystems/win32/win32k/eng/mouse.c @@ -37,23 +37,17 @@ EngSetPointerTag( */ INT INTERNAL_CALL MouseSafetyOnDrawStart( - SURFOBJ *pso, + PPDEVOBJ ppdev, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2) { LONG tmp; - PDEVOBJ *ppdev; GDIPOINTER *pgp; - ASSERT(pso != NULL); - - ppdev = GDIDEV(pso); - if (ppdev == NULL) - { - return FALSE; - } + ASSERT(ppdev != NULL); + ASSERT(ppdev->pSurface != NULL); pgp = &ppdev->Pointer; @@ -83,12 +77,12 @@ MouseSafetyOnDrawStart( } if (pgp->Exclude.right >= HazardX1 - && pgp->Exclude.left <= HazardX2 - && pgp->Exclude.bottom >= HazardY1 - && pgp->Exclude.top <= HazardY2) + && pgp->Exclude.left <= HazardX2 + && pgp->Exclude.bottom >= HazardY1 + && pgp->Exclude.top <= HazardY2) { ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount; - ppdev->pfnMovePointer(pso, -1, -1, NULL); + ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj, -1, -1, NULL); } return(TRUE); @@ -99,19 +93,12 @@ MouseSafetyOnDrawStart( */ INT INTERNAL_CALL MouseSafetyOnDrawEnd( - SURFOBJ *pso) + PPDEVOBJ ppdev) { - PDEVOBJ *ppdev; GDIPOINTER *pgp; - ASSERT(pso != NULL); - - ppdev = (PDEVOBJ*)pso->hdev; - - if (ppdev == NULL) - { - return(FALSE); - } + ASSERT(ppdev != NULL); + ASSERT(ppdev->pSurface != NULL); pgp = &ppdev->Pointer; @@ -125,7 +112,10 @@ MouseSafetyOnDrawEnd( return FALSE; } - ppdev->pfnMovePointer(pso, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude); + ppdev->pfnMovePointer(&ppdev->pSurface->SurfObj, + gpsi->ptCursor.x, + gpsi->ptCursor.y, + &pgp->Exclude); ppdev->SafetyRemoveLevel = 0; @@ -175,18 +165,17 @@ IntHideMousePointer( ptlSave.x = rclDest.left - pt.x; ptlSave.y = rclDest.top - pt.y; - IntEngBitBltEx(psoDest, - &pgp->psurfSave->SurfObj, - NULL, - NULL, - NULL, - &rclDest, - &ptlSave, - &ptlSave, - NULL, - NULL, - ROP3_TO_ROP4(SRCCOPY), - FALSE); + IntEngBitBlt(psoDest, + &pgp->psurfSave->SurfObj, + NULL, + NULL, + NULL, + &rclDest, + &ptlSave, + &ptlSave, + NULL, + NULL, + ROP3_TO_ROP4(SRCCOPY)); } VOID @@ -229,77 +218,72 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) rclPointer.bottom = min(pgp->Size.cy, psoDest->sizlBitmap.cy - pt.y); /* Copy the pixels under the cursor to temporary surface. */ - IntEngBitBltEx(&pgp->psurfSave->SurfObj, - psoDest, - NULL, - NULL, - NULL, - &rclPointer, - (POINTL*)&rclSurf, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCCOPY), - FALSE); + IntEngBitBlt(&pgp->psurfSave->SurfObj, + psoDest, + NULL, + NULL, + NULL, + &rclPointer, + (POINTL*)&rclSurf, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCCOPY)); /* Blt the pointer on the screen. */ if (pgp->psurfColor) { - IntEngBitBltEx(psoDest, - &pgp->psurfMask->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCAND), - FALSE); + IntEngBitBlt(psoDest, + &pgp->psurfMask->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCAND)); - IntEngBitBltEx(psoDest, - &pgp->psurfColor->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCINVERT), - FALSE); + IntEngBitBlt(psoDest, + &pgp->psurfColor->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCINVERT)); } else { - IntEngBitBltEx(psoDest, - &pgp->psurfMask->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCAND), - FALSE); + IntEngBitBlt(psoDest, + &pgp->psurfMask->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCAND)); rclPointer.top += pgp->Size.cy; - IntEngBitBltEx(psoDest, - &pgp->psurfMask->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP3_TO_ROP4(SRCINVERT), - FALSE); + IntEngBitBlt(psoDest, + &pgp->psurfMask->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP3_TO_ROP4(SRCINVERT)); } } @@ -353,7 +337,7 @@ EngSetPointerShape( rectl.bottom = sizel.cy; /* Calculate lDelta for our surfaces. */ - lDelta = DIB_GetDIBWidthBytes(sizel.cx, + lDelta = WIDTH_BYTES_ALIGN32(sizel.cx, BitsPerFormat(pso->iBitmapFormat)); /* Create a bitmap for saving the pixels under the cursor. */ @@ -373,10 +357,10 @@ EngSetPointerShape( /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, - lDelta, - pso->iBitmapFormat, - BMF_TOPDOWN | BMF_NOZEROINIT, - NULL); + lDelta, + pso->iBitmapFormat, + BMF_TOPDOWN | BMF_NOZEROINIT, + NULL); psurfColor = SURFACE_ShareLockSurface(hbmColor); if (!psurfColor) goto failure; @@ -540,28 +524,13 @@ EngMovePointer( prcl->right = prcl->left + pgp->Size.cx; prcl->bottom = prcl->top + pgp->Size.cy; } - } + } else if (prcl != NULL) { prcl->left = prcl->top = prcl->right = prcl->bottom = -1; } } -VOID APIENTRY -IntEngMovePointer( - IN SURFOBJ *pso, - IN LONG x, - IN LONG y, - IN RECTL *prcl) -{ - SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj); - PPDEVOBJ ppdev = (PPDEVOBJ)pso->hdev; - - SURFACE_LockBitmapBits(psurf); - ppdev->pfnMovePointer(pso, x, y, prcl); - SURFACE_UnlockBitmapBits(psurf); -} - ULONG APIENTRY IntEngSetPointerShape( IN SURFOBJ *pso, @@ -576,13 +545,11 @@ IntEngSetPointerShape( IN FLONG fl) { ULONG ulResult = SPS_DECLINE; - SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj); PFN_DrvSetPointerShape pfnSetPointerShape; PPDEVOBJ ppdev = GDIDEV(pso); pfnSetPointerShape = GDIDEVFUNCS(pso).SetPointerShape; - SURFACE_LockBitmapBits(psurf); if (pfnSetPointerShape) { ulResult = pfnSetPointerShape(pso, @@ -620,8 +587,6 @@ IntEngSetPointerShape( ppdev->pfnMovePointer = EngMovePointer; } - SURFACE_UnlockBitmapBits(psurf); - return ulResult; } @@ -649,10 +614,14 @@ GreSetPointerShape( return 0; } - psurf = pdc->dclevel.pSurface; + ASSERT(pdc->dctype == DCTYPE_DIRECT); + EngAcquireSemaphore(pdc->ppdev->hsemDevLock); + /* We're not sure DC surface is the good one */ + psurf = pdc->ppdev->pSurface; if (!psurf) { DPRINT1("DC has no surface.\n"); + EngReleaseSemaphore(pdc->ppdev->hsemDevLock); DC_UnlockDc(pdc); return 0; } @@ -668,7 +637,7 @@ GreSetPointerShape( { /* We have one, lock it */ psurfColor = SURFACE_ShareLockSurface(hbmColor); - + if (psurfColor) { /* Create an XLATEOBJ, no mono support */ @@ -700,6 +669,8 @@ GreSetPointerShape( if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); + EngReleaseSemaphore(pdc->ppdev->hsemDevLock); + /* Unlock the DC */ DC_UnlockDc(pdc); @@ -724,12 +695,23 @@ GreMovePointer( DPRINT1("Failed to lock the DC.\n"); return; } + ASSERT(pdc->dctype == DCTYPE_DIRECT); - /* Store the cursor exclude position in the PDEV */ - prcl = &pdc->ppdev->Pointer.Exclude; + /* Acquire PDEV lock */ + EngAcquireSemaphore(pdc->ppdev->hsemDevLock); - /* Call Eng/Drv function */ - IntEngMovePointer(&pdc->dclevel.pSurface->SurfObj, x, y, prcl); + /* Check if we need to move it */ + if(pdc->ppdev->SafetyRemoveLevel == 0) + { + /* Store the cursor exclude position in the PDEV */ + prcl = &pdc->ppdev->Pointer.Exclude; + + /* Call Eng/Drv function */ + pdc->ppdev->pfnMovePointer(&pdc->ppdev->pSurface->SurfObj, x, y, prcl); + } + + /* Release PDEV lock */ + EngReleaseSemaphore(pdc->ppdev->hsemDevLock); /* Unlock the DC */ DC_UnlockDc(pdc); diff --git a/subsystems/win32/win32k/eng/paint.c b/subsystems/win32/win32k/eng/paint.c index d1290b3e9e9..d59c4f217aa 100644 --- a/subsystems/win32/win32k/eng/paint.c +++ b/subsystems/win32/win32k/eng/paint.c @@ -32,14 +32,13 @@ #define NDEBUG #include -static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor) +BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor) { LONG y; ULONG LineWidth; ASSERT(pso); ASSERT(pRect); - MouseSafetyOnDrawStart(pso, pRect->left, pRect->top, pRect->right, pRect->bottom); LineWidth = pRect->right - pRect->left; DPRINT(" LineWidth: %d, top: %d, bottom: %d\n", LineWidth, pRect->top, pRect->bottom); for (y = pRect->top; y < pRect->bottom; y++) @@ -47,22 +46,9 @@ static BOOL APIENTRY FillSolidUnlocked(SURFOBJ *pso, PRECTL pRect, ULONG iColor) DibFunctionsForBitmapFormat[pso->iBitmapFormat].DIB_HLine( pso, pRect->left, pRect->right, y, iColor); } - MouseSafetyOnDrawEnd(pso); - return TRUE; } -BOOL APIENTRY FillSolid(SURFOBJ *pso, PRECTL pRect, ULONG iColor) -{ - SURFACE *psurf; - BOOL Result; - psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj); - SURFACE_LockBitmapBits(psurf); - Result = FillSolidUnlocked(pso, pRect, iColor); - SURFACE_UnlockBitmapBits(psurf); - return Result; -} - BOOL APIENTRY EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, BRUSHOBJ *BrushObj, POINTL *BrushPoint) @@ -85,7 +71,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, if (ClipRegion->iDComplexity == DC_RECT) { - FillSolidUnlocked(pso, &(ClipRegion->rclBounds), iColor); + FillSolid(pso, &(ClipRegion->rclBounds), iColor); } else { /* Enumerate all the rectangles and draw them */ @@ -94,7 +80,7 @@ EngPaintRgn(SURFOBJ *pso, CLIPOBJ *ClipRegion, ULONG iColor, MIX Mix, do { EnumMore = CLIPOBJ_bEnum(ClipRegion, sizeof(RectEnum), (PVOID) &RectEnum); for (i = 0; i < RectEnum.c; i++) { - FillSolidUnlocked(pso, RectEnum.arcl + i, iColor); + FillSolid(pso, RectEnum.arcl + i, iColor); } } while (EnumMore); } @@ -136,18 +122,11 @@ IntEngPaint(IN SURFOBJ *pso, DPRINT("pso->iType == %d\n", pso->iType); /* Is the surface's Paint function hooked? */ - if((pso->iType!=STYPE_BITMAP) && (psurf->flHooks & HOOK_PAINT)) + if((pso->iType!=STYPE_BITMAP) && (psurf->flags & HOOK_PAINT)) { // Call the driver's DrvPaint - SURFACE_LockBitmapBits(psurf); - MouseSafetyOnDrawStart(pso, ClipRegion->rclBounds.left, - ClipRegion->rclBounds.top, ClipRegion->rclBounds.right, - ClipRegion->rclBounds.bottom); - ret = GDIDEVFUNCS(pso).Paint( pso, ClipRegion, Brush, BrushOrigin, Mix); - MouseSafetyOnDrawEnd(pso); - SURFACE_UnlockBitmapBits(psurf); return ret; } return EngPaint(pso, ClipRegion, Brush, BrushOrigin, Mix ); diff --git a/subsystems/win32/win32k/eng/pdevobj.c b/subsystems/win32/win32k/eng/pdevobj.c new file mode 100644 index 00000000000..26c0f4b8416 --- /dev/null +++ b/subsystems/win32/win32k/eng/pdevobj.c @@ -0,0 +1,844 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Support for physical devices + * FILE: subsystems/win32/win32k/eng/pdevobj.c + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) + */ + +#include + +#include + +#define NDEBUG +#include + +PPDEVOBJ gppdevPrimary = NULL; + +static PPDEVOBJ gppdevList = NULL; +static HSEMAPHORE ghsemPDEV; + +BOOL +NTAPI +InitPDEVImpl() +{ + ghsemPDEV = EngCreateSemaphore(); + return TRUE; +} + + +PPDEVOBJ +PDEVOBJ_AllocPDEV() +{ + PPDEVOBJ ppdev; + + ppdev = ExAllocatePoolWithTag(PagedPool, sizeof(PDEVOBJ), GDITAG_PDEV); + if (!ppdev) + return NULL; + + RtlZeroMemory(ppdev, sizeof(PDEVOBJ)); + + ppdev->cPdevRefs = 1; + + return ppdev; +} + +VOID +NTAPI +PDEVOBJ_vRelease(PPDEVOBJ ppdev) +{ + /* Lock loader */ + EngAcquireSemaphore(ghsemPDEV); + + /* Decrease reference count */ + --ppdev->cPdevRefs; + + ASSERT(ppdev->cPdevRefs >= 0) ; + + /* Check if references are left */ + if (ppdev->cPdevRefs == 0) + { + /* Do we have a surface? */ + if(ppdev->pSurface) + { + /* Release the surface and let the driver free it */ + SURFACE_ShareUnlockSurface(ppdev->pSurface); + ppdev->pfn.DisableSurface(ppdev->dhpdev); + } + + /* Do we have a palette? */ + if(ppdev->ppalSurf) + { + PALETTE_ShareUnlockPalette(ppdev->ppalSurf); + } + + /* Disable PDEV */ + ppdev->pfn.DisablePDEV(ppdev->dhpdev); + + /* Remove it from list */ + if( ppdev == gppdevList ) + gppdevList = ppdev->ppdevNext ; + else + { + PPDEVOBJ ppdevCurrent = gppdevList; + BOOL found = FALSE ; + while (!found && ppdevCurrent->ppdevNext) + { + if (ppdevCurrent->ppdevNext == ppdev) + found = TRUE; + else + ppdevCurrent = ppdevCurrent->ppdevNext ; + } + if(found) + ppdevCurrent->ppdevNext = ppdev->ppdevNext; + } + + /* Is this the primary one ? */ + if (ppdev == gppdevPrimary) + gppdevPrimary = NULL; + + /* Free it */ + ExFreePoolWithTag(ppdev, GDITAG_PDEV ); + } + + /* Unlock loader */ + EngReleaseSemaphore(ghsemPDEV); + +} + +BOOL +NTAPI +PDEVOBJ_bEnablePDEV( + PPDEVOBJ ppdev, + PDEVMODEW pdevmode, + PWSTR pwszLogAddress) +{ + PFN_DrvEnablePDEV pfnEnablePDEV; + + DPRINT1("PDEVOBJ_bEnablePDEV()\n"); + + /* Get the DrvEnablePDEV function */ + pfnEnablePDEV = ppdev->pldev->pfn.EnablePDEV; + + /* Call the drivers DrvEnablePDEV function */ + ppdev->dhpdev = pfnEnablePDEV(pdevmode, + pwszLogAddress, + HS_DDI_MAX, + ppdev->ahsurf, + sizeof(GDIINFO), + &ppdev->gdiinfo, + sizeof(DEVINFO), + &ppdev->devinfo, + (HDEV)ppdev, + ppdev->pGraphicsDevice->pwszDescription, + ppdev->pGraphicsDevice->DeviceObject); + + /* Fix up some values */ + if (ppdev->gdiinfo.ulLogPixelsX == 0) + ppdev->gdiinfo.ulLogPixelsX = 96; + + if (ppdev->gdiinfo.ulLogPixelsY == 0) + ppdev->gdiinfo.ulLogPixelsY = 96; + + /* Setup Palette */ + GDIOBJ_SetOwnership(ppdev->devinfo.hpalDefault, NULL); + ppdev->ppalSurf = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); + + DPRINT1("PDEVOBJ_bEnablePDEV - dhpdev = %p\n", ppdev->dhpdev); + + return TRUE; +} + +VOID +NTAPI +PDEVOBJ_vCompletePDEV( + PPDEVOBJ ppdev) +{ + /* Call the drivers DrvCompletePDEV function */ + ppdev->pldev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev); +} + +PSURFACE +NTAPI +PDEVOBJ_pSurface( + PPDEVOBJ ppdev) +{ + HSURF hsurf; + + /* Check if we already have a surface */ + if (ppdev->pSurface) + { + /* Increment reference count */ + GDIOBJ_IncrementShareCount(&ppdev->pSurface->BaseObject); + } + else + { + /* Call the drivers DrvEnableSurface */ + hsurf = ppdev->pldev->pfn.EnableSurface(ppdev->dhpdev); + + /* Lock the surface */ + ppdev->pSurface = SURFACE_ShareLockSurface(hsurf); + } + + DPRINT("PDEVOBJ_pSurface() returning %p\n", ppdev->pSurface); + return ppdev->pSurface; +} + +PDEVMODEW +NTAPI +PDEVOBJ_pdmMatchDevMode( + PPDEVOBJ ppdev, + PDEVMODEW pdm) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVMODEW pdmCurrent; + INT i; + DWORD dwFields; + + pGraphicsDevice = ppdev->pGraphicsDevice; + + for (i = 0; i < pGraphicsDevice->cDevModes; i++) + { + pdmCurrent = pGraphicsDevice->pDevModeList[i].pdm; + + /* Compare asked DEVMODE fields + * Only compare those that are valid in both DEVMODE structs */ + dwFields = pdmCurrent->dmFields & pdm->dmFields ; + /* For now, we only need those */ + if ((dwFields & DM_BITSPERPEL) && + (pdmCurrent->dmBitsPerPel != pdm->dmBitsPerPel)) + continue; + if ((dwFields & DM_PELSWIDTH) && + (pdmCurrent->dmPelsWidth != pdm->dmPelsWidth)) + continue; + if ((dwFields & DM_PELSHEIGHT) && + (pdmCurrent->dmPelsHeight != pdm->dmPelsHeight)) + continue; + if ((dwFields & DM_DISPLAYFREQUENCY) && + (pdmCurrent->dmDisplayFrequency != pdm->dmDisplayFrequency)) + continue; + + /* Match! Return the DEVMODE */ + return pdmCurrent; + } + + /* Nothing found */ + return NULL; +} + +static +PPDEVOBJ +EngpCreatePDEV( + PUNICODE_STRING pustrDeviceName, + PDEVMODEW pdm) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PPDEVOBJ ppdev; + + /* Try to find the GRAPHICS_DEVICE */ + if (pustrDeviceName) + { + pGraphicsDevice = EngpFindGraphicsDevice(pustrDeviceName, 0, 0); + if (!pGraphicsDevice) + { + DPRINT1("No GRAPHICS_DEVICE found for %ls!\n", + pustrDeviceName ? pustrDeviceName->Buffer : 0); + return NULL; + } + } + else + { + pGraphicsDevice = gpPrimaryGraphicsDevice; + } + + /* Allocate a new PDEVOBJ */ + ppdev = PDEVOBJ_AllocPDEV(); + if (!ppdev) + { + DPRINT1("failed to allocate a PDEV\n"); + return NULL; + } + + /* If no DEVMODEW is given, ... */ + if (!pdm) + { + /* ... use the device's default one */ + pdm = pGraphicsDevice->pDevModeList[pGraphicsDevice->iDefaultMode].pdm; + DPRINT1("Using iDefaultMode = %ld\n", pGraphicsDevice->iDefaultMode); + } + + /* Try to get a diplay driver */ + ppdev->pldev = EngLoadImageEx(pdm->dmDeviceName, LDEV_DEVICE_DISPLAY); + if (!ppdev->pldev) + { + DPRINT1("Could not load display driver '%ls'\n", + pGraphicsDevice->pDiplayDrivers); + ExFreePoolWithTag(ppdev, GDITAG_PDEV); + return NULL; + } + + /* Copy the function table */ + ppdev->pfn = ppdev->pldev->pfn; + + /* Set MovePointer function */ + ppdev->pfnMovePointer = ppdev->pfn.MovePointer; + if (!ppdev->pfnMovePointer) + ppdev->pfnMovePointer = EngMovePointer; + + ppdev->pGraphicsDevice = pGraphicsDevice; + ppdev->hsemDevLock = EngCreateSemaphore(); + // Should we change the ative mode of pGraphicsDevice ? + ppdev->pdmwDev = PDEVOBJ_pdmMatchDevMode(ppdev, pdm) ; + + /* FIXME! */ + ppdev->flFlags = PDEV_DISPLAY; + + /* HACK: Don't use the pointer */ + ppdev->Pointer.Exclude.right = -1; + + /* Call the driver to enable the PDEV */ + if (!PDEVOBJ_bEnablePDEV(ppdev, pdm, NULL)) + { + DPRINT1("Failed to enable PDEV!\n"); + ASSERT(FALSE); + } + + /* FIXME: this must be done in a better way */ + pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_ATTACHED_TO_DESKTOP; + + /* Tell the driver that the PDEV is ready */ + PDEVOBJ_vCompletePDEV(ppdev); + + /* Return the PDEV */ + return ppdev; +} + +VOID +NTAPI +PDEVOBJ_vSwitchPdev( + PPDEVOBJ ppdev, + PPDEVOBJ ppdev2) +{ + PDEVOBJ pdevTmp; + DWORD tmpStateFlags; + + /* Exchange data */ + pdevTmp = *ppdev; + + /* Exchange driver functions */ + ppdev->pfn = ppdev2->pfn; + ppdev2->pfn = pdevTmp.pfn; + + /* Exchange LDEVs */ + ppdev->pldev = ppdev2->pldev; + ppdev2->pldev = pdevTmp.pldev; + + /* Exchange DHPDEV */ + ppdev->dhpdev = ppdev2->dhpdev; + ppdev2->dhpdev = pdevTmp.dhpdev; + + /* Exchange surfaces and associate them with their new PDEV */ + ppdev->pSurface = ppdev2->pSurface; + ppdev2->pSurface = pdevTmp.pSurface; + ppdev->pSurface->SurfObj.hdev = (HDEV)ppdev; + ppdev2->pSurface->SurfObj.hdev = (HDEV)ppdev2; + + /* Exchange devinfo */ + ppdev->devinfo = ppdev2->devinfo; + ppdev2->devinfo = pdevTmp.devinfo; + + /* Exchange gdiinfo */ + ppdev->gdiinfo = ppdev2->gdiinfo; + ppdev2->gdiinfo = pdevTmp.gdiinfo; + + /* Exchange DEVMODE */ + ppdev->pdmwDev = ppdev2->pdmwDev; + ppdev2->pdmwDev = pdevTmp.pdmwDev; + + /* Exchange state flags */ + tmpStateFlags = ppdev->pGraphicsDevice->StateFlags; + ppdev->pGraphicsDevice->StateFlags = ppdev2->pGraphicsDevice->StateFlags; + ppdev2->pGraphicsDevice->StateFlags = tmpStateFlags; + + /* Notify each driver instance of its new HDEV association */ + ppdev->pfn.CompletePDEV(ppdev->dhpdev, (HDEV)ppdev); + ppdev2->pfn.CompletePDEV(ppdev2->dhpdev, (HDEV)ppdev2); +} + + +BOOL +NTAPI +PDEVOBJ_bSwitchMode( + PPDEVOBJ ppdev, + PDEVMODEW pdm) +{ + UNICODE_STRING ustrDevice; + PPDEVOBJ ppdevTmp; + PSURFACE pSurface; + BOOL retval = FALSE; + + /* Lock the PDEV */ + EngAcquireSemaphore(ppdev->hsemDevLock); + /* And everything else */ + EngAcquireSemaphore(ghsemPDEV); + + DPRINT1("PDEVOBJ_bSwitchMode, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface); + + // Lookup the GraphicsDevice + select DEVMODE + // pdm = PDEVOBJ_pdmMatchDevMode(ppdev, pdm); + + /* 1. Temporarily disable the current PDEV */ + if (!ppdev->pfn.AssertMode(ppdev->dhpdev, FALSE)) + { + DPRINT1("DrvAssertMode failed\n"); + goto leave; + } + + /* 2. Create new PDEV */ + RtlInitUnicodeString(&ustrDevice, ppdev->pGraphicsDevice->szWinDeviceName); + ppdevTmp = EngpCreatePDEV(&ustrDevice, pdm); + if (!ppdevTmp) + { + DPRINT1("Failed to create a new PDEV\n"); + goto leave; + } + + /* 3. Create a new surface */ + pSurface = PDEVOBJ_pSurface(ppdevTmp); + if (!pSurface) + { + DPRINT1("DrvEnableSurface failed\n"); + goto leave; + } + + /* 4. Get DirectDraw information */ + /* 5. Enable DirectDraw Not traced */ + /* 6. Copy old PDEV state to new PDEV instance */ + + /* 7. Switch the PDEVs */ + PDEVOBJ_vSwitchPdev(ppdev, ppdevTmp); + + /* 8. Disable DirectDraw */ + + PDEVOBJ_vRelease(ppdevTmp); + + /* Update primary display capabilities */ + if(ppdev == gppdevPrimary) + { + PDEVOBJ_vGetDeviceCaps(ppdev, &GdiHandleTable->DevCaps); + } + + /* Success! */ + retval = TRUE; +leave: + /* Unlock PDEV */ + EngReleaseSemaphore(ppdev->hsemDevLock); + EngReleaseSemaphore(ghsemPDEV); + + DPRINT1("leave, ppdev = %p, pSurface = %p\n", ppdev, ppdev->pSurface); + + return retval; +} + + +PPDEVOBJ +NTAPI +EngpGetPDEV( + PUNICODE_STRING pustrDeviceName) +{ + UNICODE_STRING ustrCurrent; + PPDEVOBJ ppdev; + PGRAPHICS_DEVICE pGraphicsDevice; + + /* Acquire PDEV lock */ + EngAcquireSemaphore(ghsemPDEV); + + /* If no device name is given, ... */ + if (!pustrDeviceName && gppdevPrimary) + { + /* ... use the primary PDEV */ + ppdev = gppdevPrimary; + + /* Reference the pdev */ + InterlockedIncrement(&ppdev->cPdevRefs); + goto leave; + } + + /* Loop all present PDEVs */ + for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext) + { + /* Get a pointer to the GRAPHICS_DEVICE */ + pGraphicsDevice = ppdev->pGraphicsDevice; + + /* Compare the name */ + RtlInitUnicodeString(&ustrCurrent, pGraphicsDevice->szWinDeviceName); + if (RtlEqualUnicodeString(pustrDeviceName, &ustrCurrent, FALSE)) + { + /* Found! Reference the PDEV */ + InterlockedIncrement(&ppdev->cPdevRefs); + break; + } + } + + /* Did we find one? */ + if (!ppdev) + { + /* No, create a new PDEV */ + ppdev = EngpCreatePDEV(pustrDeviceName, NULL); + if (ppdev) + { + /* Insert the PDEV into the list */ + ppdev->ppdevNext = gppdevList; + gppdevList = ppdev; + + /* Set as primary PDEV, if we don't have one yet */ + if (!gppdevPrimary) + { + gppdevPrimary = ppdev; + ppdev->pGraphicsDevice->StateFlags |= DISPLAY_DEVICE_PRIMARY_DEVICE; + } + } + } + +leave: + /* Release PDEV lock */ + EngReleaseSemaphore(ghsemPDEV); + + return ppdev; +} + +INT +NTAPI +PDEVOBJ_iGetColorManagementCaps(PPDEVOBJ ppdev) +{ + INT ret = CM_NONE; + + if (ppdev->flFlags & PDEV_DISPLAY) + { + if (ppdev->devinfo.iDitherFormat == BMF_8BPP || + ppdev->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP) + ret = CM_GAMMA_RAMP; + } + + if (ppdev->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR) + ret |= CM_CMYK_COLOR; + if (ppdev->devinfo.flGraphicsCaps & GCAPS_ICM) + ret |= CM_DEVICE_ICM; + + return ret; +} + +VOID +NTAPI +PDEVOBJ_vGetDeviceCaps( + IN PPDEVOBJ ppdev, + OUT PDEVCAPS pDevCaps) +{ + PGDIINFO pGdiInfo = &ppdev->gdiinfo; + + pDevCaps->ulVersion = pGdiInfo->ulVersion; + pDevCaps->ulTechnology = pGdiInfo->ulTechnology; + pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000; + pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000; + pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize; + pDevCaps->ulVertSize = pGdiInfo->ulVertSize; + pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes; + pDevCaps->ulVertRes = pGdiInfo->ulVertRes; + pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel; + if (pDevCaps->ulBitsPixel == 15) pDevCaps->ulBitsPixel = 16; + pDevCaps->ulPlanes = pGdiInfo->cPlanes; + pDevCaps->ulNumPens = pGdiInfo->ulNumColors; + if (pDevCaps->ulNumPens != -1) pDevCaps->ulNumPens *= 5; + pDevCaps->ulNumFonts = 0; // PDEVOBJ_cFonts(ppdev); + pDevCaps->ulNumColors = pGdiInfo->ulNumColors; + pDevCaps->ulRasterCaps = pGdiInfo->flRaster; + pDevCaps->ulAspectX = pGdiInfo->ulAspectX; + pDevCaps->ulAspectY = pGdiInfo->ulAspectY; + pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY; + pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX; + pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY; + pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg; + pDevCaps->ulColorRes = pGdiInfo->ulDACRed + + pGdiInfo->ulDACGreen + + pGdiInfo->ulDACBlue; + pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx; + pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy; + pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x; + pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y; + pDevCaps->ulTextCaps = pGdiInfo->flTextCaps; + pDevCaps->ulTextCaps |= (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER); + if (pGdiInfo->ulTechnology != DT_PLOTTER) + pDevCaps->ulTextCaps |= TC_VA_ABLE; + pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh; + pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes; + pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes; + pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment; + pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes; + pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes; + pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment; + pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment; + pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend; + pDevCaps->ulColorMgmtCaps = PDEVOBJ_iGetColorManagementCaps(ppdev); +} + + +/** Exported functions ********************************************************/ + +LPWSTR +APIENTRY +EngGetDriverName(IN HDEV hdev) +{ + PPDEVOBJ ppdev = (PPDEVOBJ)hdev; + PLDEVOBJ pldev; + + if (!hdev) + return NULL; + + pldev = ppdev->pldev; + ASSERT(pldev); + + if (!pldev->pGdiDriverInfo) + return NULL; + + return pldev->pGdiDriverInfo->DriverName.Buffer; +} + + +INT +APIENTRY +NtGdiGetDeviceCaps( + HDC hdc, + INT Index) +{ + PDC pdc; + DEVCAPS devcaps; + + /* Lock the given DC */ + pdc = DC_LockDc(hdc); + if (!pdc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return 0; + } + + /* Get the data */ + PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps); + + /* Unlock the DC */ + DC_UnlockDc(pdc); + + /* Return capability */ + switch (Index) + { + case DRIVERVERSION: + return devcaps.ulVersion; + + case TECHNOLOGY: + return devcaps.ulTechnology; + + case HORZSIZE: + return devcaps.ulHorzSize; + + case VERTSIZE: + return devcaps.ulVertSize; + + case HORZRES: + return devcaps.ulHorzRes; + + case VERTRES: + return devcaps.ulVertRes; + + case LOGPIXELSX: + return devcaps.ulLogPixelsX; + + case LOGPIXELSY: + return devcaps.ulLogPixelsY; + + case BITSPIXEL: + return devcaps.ulBitsPixel; + + case PLANES: + return devcaps.ulPlanes; + + case NUMBRUSHES: + return -1; + + case NUMPENS: + return devcaps.ulNumPens; + + case NUMFONTS: + return devcaps.ulNumFonts; + + case NUMCOLORS: + return devcaps.ulNumColors; + + case ASPECTX: + return devcaps.ulAspectX; + + case ASPECTY: + return devcaps.ulAspectY; + + case ASPECTXY: + return devcaps.ulAspectXY; + + case CLIPCAPS: + return CP_RECTANGLE; + + case SIZEPALETTE: + return devcaps.ulSizePalette; + + case NUMRESERVED: + return 20; + + case COLORRES: + return devcaps.ulColorRes; + + case DESKTOPVERTRES: + return devcaps.ulVertRes; + + case DESKTOPHORZRES: + return devcaps.ulHorzRes; + + case BLTALIGNMENT: + return devcaps.ulBltAlignment; + + case SHADEBLENDCAPS: + return devcaps.ulShadeBlend; + + case COLORMGMTCAPS: + return devcaps.ulColorMgmtCaps; + + case PHYSICALWIDTH: + return devcaps.ulPhysicalWidth; + + case PHYSICALHEIGHT: + return devcaps.ulPhysicalHeight; + + case PHYSICALOFFSETX: + return devcaps.ulPhysicalOffsetX; + + case PHYSICALOFFSETY: + return devcaps.ulPhysicalOffsetY; + + case VREFRESH: + return devcaps.ulVRefresh; + + case RASTERCAPS: + return devcaps.ulRasterCaps; + + case CURVECAPS: + return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE | + CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT); + + case LINECAPS: + return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE | + LC_STYLED | LC_WIDESTYLED | LC_INTERIORS); + + case POLYGONALCAPS: + return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE | + PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS); + + case TEXTCAPS: + return devcaps.ulTextCaps; + + case CAPS1: + case PDEVICESIZE: + case SCALINGFACTORX: + case SCALINGFACTORY: + default: + return 0; + } + + return 0; +} + + +BOOL +APIENTRY +NtGdiGetDeviceCapsAll( + IN HDC hDC, + OUT PDEVCAPS pDevCaps) +{ + PDC pdc; + DEVCAPS devcaps; + BOOL bResult = TRUE; + + /* Lock the given DC */ + pdc = DC_LockDc(hDC); + if (!pdc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + + /* Get the data */ + PDEVOBJ_vGetDeviceCaps(pdc->ppdev, &devcaps); + + /* Unlock the DC */ + DC_UnlockDc(pdc); + + /* Copy data to caller */ + _SEH2_TRY + { + ProbeForWrite(pDevCaps, sizeof(DEVCAPS), 1); + RtlCopyMemory(pDevCaps, &devcaps, sizeof(DEVCAPS)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + bResult = FALSE; + } + _SEH2_END; + + return bResult; +} + +DHPDEV +APIENTRY +NtGdiGetDhpdev( + IN HDEV hdev) +{ + PPDEVOBJ ppdev; + DHPDEV dhpdev = NULL; + + /* Check parameter */ + if (!hdev || (PCHAR)hdev < (PCHAR)MmSystemRangeStart) + return NULL; + + /* Lock PDEV list */ + EngAcquireSemaphore(ghsemPDEV); + + /* Walk through the list of PDEVs */ + for (ppdev = gppdevList; ppdev; ppdev = ppdev->ppdevNext) + { + /* Compare with the given HDEV */ + if (ppdev == hdev) + { + /* Found the PDEV! Get it's dhpdev and break */ + dhpdev = ppdev->dhpdev; + break; + } + } + + /* Unlock PDEV list */ + EngReleaseSemaphore(ghsemPDEV); + + return dhpdev; +} + +PSIZEL +FASTCALL +PDEVOBJ_sizl(PPDEVOBJ ppdev, PSIZEL psizl) +{ + if (ppdev->flFlags & PDEV_META_DEVICE) + { + psizl->cx = ppdev->ulHorzRes; + psizl->cy = ppdev->ulVertRes; + } + else + { + psizl->cx = ppdev->gdiinfo.ulHorzRes; + psizl->cy = ppdev->gdiinfo.ulVertRes; + } + return psizl; +} diff --git a/subsystems/win32/win32k/eng/rlecomp.c b/subsystems/win32/win32k/eng/rlecomp.c new file mode 100644 index 00000000000..dc8a0712f44 --- /dev/null +++ b/subsystems/win32/win32k/eng/rlecomp.c @@ -0,0 +1,99 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: RLE compression + * FILE: subsystems/win32k/eng/rlecomp.c + * PROGRAMER: Jason Filby + */ + +#include + +#define NDEBUG +#include + +enum Rle_EscapeCodes +{ + RLE_EOL = 0, /* End of line */ + RLE_END = 1, /* End of bitmap */ + RLE_DELTA = 2 /* Delta */ +}; + +VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format) +{ + INT x = 0; + INT y = Size.cy - 1; + INT c; + INT length; + INT width; + INT height = Size.cy - 1; + BYTE *begin = CompressedBits; + BYTE *bits = CompressedBits; + BYTE *temp; + INT shift = 0; + + if (Format == BMF_4RLE) + shift = 1; + else if(Format != BMF_8RLE) + return; + + width = ((Size.cx + shift) >> shift); + + _SEH2_TRY + { + while (y >= 0) + { + length = (*bits++) >> shift; + if (length) + { + c = *bits++; + while (length--) + { + if (x >= width) break; + temp = UncompressedBits + (((height - y) * Delta) + x); + x++; + *temp = c; + } + } + else + { + length = *bits++; + switch (length) + { + case RLE_EOL: + x = 0; + y--; + break; + case RLE_END: + _SEH2_YIELD(return); + case RLE_DELTA: + x += (*bits++) >> shift; + y -= (*bits++) >> shift; + break; + default: + length = length >> shift; + while (length--) + { + c = *bits++; + if (x < width) + { + temp = UncompressedBits + (((height - y) * Delta) + x); + x++; + *temp = c; + } + } + if ((bits - begin) & 1) + { + bits++; + } + } + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DPRINT1("Decoding error\n"); + } + _SEH2_END; + + return; +} diff --git a/subsystems/win32/win32k/eng/semaphor.c b/subsystems/win32/win32k/eng/semaphor.c index d09d4c9022b..ce9780fc0bf 100644 --- a/subsystems/win32/win32k/eng/semaphor.c +++ b/subsystems/win32/win32k/eng/semaphor.c @@ -69,6 +69,19 @@ EngReleaseSemaphore ( IN HSEMAPHORE hsem ) IntGdiReleaseSemaphore ( hsem ); } +VOID +NTAPI +EngAcquireSemaphoreShared( + IN HSEMAPHORE hsem) +{ + PTHREADINFO pti; + + ASSERT(hsem); + ExEnterCriticalRegionAndAcquireResourceShared((PERESOURCE)hsem); + pti = PsGetThreadWin32Thread(PsGetCurrentThread()); + if (pti) ++pti->dwEngAcquireCount; +} + /* * @implemented */ diff --git a/subsystems/win32/win32k/eng/stretchblt.c b/subsystems/win32/win32k/eng/stretchblt.c index 932d93d5cb4..a6f3d4f4572 100644 --- a/subsystems/win32/win32k/eng/stretchblt.c +++ b/subsystems/win32/win32k/eng/stretchblt.c @@ -462,25 +462,16 @@ IntEngStretchBlt(SURFOBJ *psoDest, /* No success yet */ ret = FALSE; - SURFACE_LockBitmapBits(psurfDest); - MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top, - OutputRect.right, OutputRect.bottom); if (UsesSource) { psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); - if (psoSource != psoDest) - { - SURFACE_LockBitmapBits(psurfSource); - } - MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top, - InputRect.right, InputRect.bottom); } /* Prepare color adjustment */ /* Call the driver's DrvStretchBlt if available */ - if (psurfDest->flHooks & HOOK_STRETCHBLTROP) + if (psurfDest->flags & HOOK_STRETCHBLTROP) { /* Drv->StretchBltROP (look at http://www.osronline.com/ddkx/graphics/ddifncs_0z3b.htm ) */ ret = GDIDEVFUNCS(psoDest).StretchBltROP(psoDest, @@ -514,17 +505,6 @@ IntEngStretchBlt(SURFOBJ *psoDest, ROP); } - if (UsesSource) - { - MouseSafetyOnDrawEnd(psoSource); - if (psoSource != psoDest) - { - SURFACE_UnlockBitmapBits(psurfSource); - } - } - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurfDest); - return ret; } diff --git a/subsystems/win32/win32k/eng/surface.c b/subsystems/win32/win32k/eng/surface.c index 126ae9542ce..622b99da2d5 100644 --- a/subsystems/win32/win32k/eng/surface.c +++ b/subsystems/win32/win32k/eng/surface.c @@ -3,7 +3,8 @@ * PROJECT: ReactOS kernel * PURPOSE: GDI Driver Surace Functions * FILE: subsys/win32k/eng/surface.c - * PROGRAMER: Jason Filby + * PROGRAMERS: Jason Filby + * Timo Kreuzer * REVISION HISTORY: * 3/7/1999: Created * 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED) @@ -17,43 +18,24 @@ #define NDEBUG #include -enum Rle_EscapeCodes +ULONG giUniqueSurface = 0; + +UCHAR +gajBitsPerFormat[11] = { - RLE_EOL = 0, /* End of line */ - RLE_END = 1, /* End of bitmap */ - RLE_DELTA = 2 /* Delta */ + 0, /* 0: unused */ + 1, /* 1: BMF_1BPP */ + 4, /* 2: BMF_4BPP */ + 8, /* 3: BMF_8BPP */ + 16, /* 4: BMF_16BPP */ + 24, /* 5: BMF_24BPP */ + 32, /* 6: BMF_32BPP */ + 4, /* 7: BMF_4RLE */ + 8, /* 8: BMF_8RLE */ + 0, /* 9: BMF_JPEG */ + 0, /* 10: BMF_PNG */ }; -INT FASTCALL BitsPerFormat(ULONG Format) -{ - switch (Format) - { - case BMF_1BPP: - return 1; - - case BMF_4BPP: - /* Fall through */ - case BMF_4RLE: - return 4; - - case BMF_8BPP: - /* Fall through */ - case BMF_8RLE: - return 8; - - case BMF_16BPP: - return 16; - - case BMF_24BPP: - return 24; - - case BMF_32BPP: - return 32; - - default: - return 0; - } -} ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression) { @@ -90,534 +72,238 @@ ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression) } } -BOOL INTERNAL_CALL +BOOL +INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody) { PSURFACE psurf = (PSURFACE)ObjectBody; PVOID pvBits = psurf->SurfObj.pvBits; + NTSTATUS Status; - /* If this is an API bitmap, free the bits */ - if (pvBits != NULL && - (psurf->flFlags & BITMAPOBJ_IS_APIBITMAP)) + /* Check if the surface has bits */ + if (pvBits) { - /* Check if we have a DIB section */ - if (psurf->hSecure) - { - // FIXME: IMPLEMENT ME! - // MmUnsecureVirtualMemory(psurf->hSecure); - if (psurf->hDIBSection) - { - /* DIB was created from a section */ - NTSTATUS Status; + /* Only bitmaps can have bits */ + ASSERT(psurf->SurfObj.iType == STYPE_BITMAP); - pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset); - Status = ZwUnmapViewOfSection(NtCurrentProcess(), pvBits); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Could not unmap section view!\n"); - // Should we BugCheck here? - } - } - else + /* Check if it is a DIB section */ + if (psurf->hDIBSection) + { + /* Unsecure the memory */ + EngUnsecureMem(psurf->hSecure); + + /* Calculate the real start of the section */ + pvBits = (PVOID)((ULONG_PTR)pvBits - psurf->dwOffset); + + /* Unmap the section */ + Status = MmUnmapViewOfSection(PsGetCurrentProcess(), pvBits); + if (!NT_SUCCESS(Status)) { - /* DIB was allocated */ - EngFreeUserMem(pvBits); + DPRINT1("Could not unmap section view!\n"); + // Should we BugCheck here? + ASSERT(FALSE); } } + else if (psurf->SurfObj.fjBitmap & BMF_USERMEM) + { + /* Bitmap was allocated from usermode memory */ + EngFreeUserMem(pvBits); + } + else if (psurf->SurfObj.fjBitmap & BMF_KMSECTION) + { + /* Bitmap was allocated from a kernel section */ + if (!EngFreeSectionMem(NULL, pvBits)) + { + DPRINT1("EngFreeSectionMem failed for %p!\n", pvBits); + // Should we BugCheck here? + ASSERT(FALSE); + } + } + else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK) + { + /* HACK: Free RLE decompressed bits */ + EngFreeMem(pvBits); + } else { - // FIXME: use TAG - ExFreePool(psurf->SurfObj.pvBits); - } - - if (psurf->hDIBPalette != NULL) - { - GreDeleteObject(psurf->hDIBPalette); + /* There should be nothing to free */ + ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE); } } - if (NULL != psurf->BitsLock) + /* Free palette */ + if(psurf->ppal) { - ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE); - psurf->BitsLock = NULL; + PALETTE_ShareUnlockPalette(psurf->ppal); } return TRUE; } -BOOL INTERNAL_CALL -SURFACE_InitBitsLock(PSURFACE psurf) + +PSURFACE +NTAPI +SURFACE_AllocSurface( + IN ULONG iType, + IN ULONG cx, + IN ULONG cy, + IN ULONG iFormat) { - psurf->BitsLock = ExAllocatePoolWithTag(NonPagedPool, - sizeof(FAST_MUTEX), - TAG_SURFACE); - if (NULL == psurf->BitsLock) - { - return FALSE; - } - - ExInitializeFastMutex(psurf->BitsLock); - - return TRUE; -} - -void INTERNAL_CALL -SURFACE_CleanupBitsLock(PSURFACE psurf) -{ - if (NULL != psurf->BitsLock) - { - ExFreePoolWithTag(psurf->BitsLock, TAG_SURFACE); - psurf->BitsLock = NULL; - } -} - - -/* - * @implemented - */ -HBITMAP APIENTRY -EngCreateDeviceBitmap(IN DHSURF dhsurf, - IN SIZEL Size, - IN ULONG Format) -{ - HBITMAP NewBitmap; + PSURFACE psurf; SURFOBJ *pso; - NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL); - if (!NewBitmap) + /* Verify format */ + if (iFormat < BMF_1BPP || iFormat > BMF_PNG) { - DPRINT1("EngCreateBitmap failed\n"); - return 0; - } - - pso = EngLockSurface((HSURF)NewBitmap); - if (!pso) - { - DPRINT1("EngLockSurface failed on newly created bitmap!\n"); - GreDeleteObject(NewBitmap); + DPRINT1("Invalid bitmap format: %ld\n", iFormat); return NULL; } - pso->dhsurf = dhsurf; - EngUnlockSurface(pso); + /* Allocate a SURFACE object */ + psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP); - return NewBitmap; + if (psurf) + { + /* Initialize the basic fields */ + pso = &psurf->SurfObj; + pso->hsurf = psurf->BaseObject.hHmgr; + pso->sizlBitmap.cx = cx; + pso->sizlBitmap.cy = cy; + pso->iBitmapFormat = iFormat; + pso->iType = iType; + pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface); + + /* Assign a default palette and increment its reference count */ + psurf->ppal = appalSurfaceDefault[iFormat]; + GDIOBJ_IncrementShareCount(&psurf->ppal->BaseObject); + } + + return psurf; } -BOOL DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format) +BOOL +NTAPI +SURFACE_bSetBitmapBits( + IN PSURFACE psurf, + IN USHORT fjBitmap, + IN ULONG ulWidth, + IN PVOID pvBits OPTIONAL) { - INT x = 0; - INT y = Size.cy - 1; - INT c; - INT length; - INT width; - INT height = Size.cy - 1; - BYTE *begin = CompressedBits; - BYTE *bits = CompressedBits; - BYTE *temp; - INT shift = 0; + SURFOBJ *pso = &psurf->SurfObj; + PVOID pvSection; + UCHAR cBitsPixel; - if (Format == BMF_4RLE) - shift = 1; - else if(Format != BMF_8RLE) - return FALSE; + /* Only bitmaps can have bits */ + ASSERT(psurf->SurfObj.iType == STYPE_BITMAP); - width = ((Size.cx + shift) >> shift); + /* Get bits per pixel from the format */ + cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat]; - _SEH2_TRY + /* Is a width in bytes given? */ + if (ulWidth) { - while (y >= 0) + /* Align the width (Windows compatibility, drivers expect that) */ + ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel); + } + else + { + /* Calculate width from the bitmap width in pixels */ + ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel); + } + + /* Calculate the bitmap size in bytes */ + pso->cjBits = ulWidth * pso->sizlBitmap.cy; + + /* Did the caller provide bits? */ + if (pvBits) + { + /* Yes, so let him free it */ + fjBitmap |= BMF_DONT_FREE; + } + else if (pso->cjBits) + { + /* We must allocate memory, check what kind */ + if (fjBitmap & BMF_USERMEM) { - length = (*bits++) >> shift; - if (length) - { - c = *bits++; - while (length--) - { - if (x >= width) break; - temp = UncompressedBits + (((height - y) * Delta) + x); - x++; - *temp = c; - } - } - else - { - length = *bits++; - switch (length) - { - case RLE_EOL: - x = 0; - y--; - break; - case RLE_END: - _SEH2_YIELD(return TRUE); - case RLE_DELTA: - x += (*bits++) >> shift; - y -= (*bits++) >> shift; - break; - default: - length = length >> shift; - while (length--) - { - c = *bits++; - if (x < width) - { - temp = UncompressedBits + (((height - y) * Delta) + x); - x++; - *temp = c; - } - } - if ((bits - begin) & 1) - { - bits++; - } - } - } + /* User mode memory was requested */ + pvBits = EngAllocUserMem(pso->cjBits, 0); } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - DPRINT1("Decoding error\n"); - _SEH2_YIELD(return FALSE); - } - _SEH2_END; + else + { + /* Use a kernel mode section */ + fjBitmap |= BMF_KMSECTION; + pvBits = EngAllocSectionMem(&pvSection, + (fjBitmap & BMF_NOZEROINIT) ? + 0 : FL_ZERO_MEMORY, + pso->cjBits, TAG_DIB); + /* Free the section already, but keep the mapping */ + if (pvBits) EngFreeSectionMem(pvSection, NULL); + } + + /* Check for failure */ + if (!pvBits) return FALSE; + } + + /* Set pvBits, pvScan0 and lDelta */ + pso->pvBits = pvBits; + if (fjBitmap & BMF_TOPDOWN) + { + /* Topdown is the normal way */ + pso->pvScan0 = pso->pvBits; + pso->lDelta = ulWidth; + } + else + { + /* Inversed bitmap (bottom up) */ + pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth); + pso->lDelta = -ulWidth; + } + + pso->fjBitmap = fjBitmap; + + /* Success */ return TRUE; } -HBITMAP FASTCALL -IntCreateBitmap(IN SIZEL Size, - IN LONG Width, - IN ULONG Format, - IN ULONG Flags, - IN PVOID Bits) +HBITMAP +APIENTRY +EngCreateBitmap( + IN SIZEL sizl, + IN LONG lWidth, + IN ULONG iFormat, + IN ULONG fl, + IN PVOID pvBits) { + PSURFACE psurf; HBITMAP hbmp; - SURFOBJ *pso; - PSURFACE psurf; - PVOID UncompressedBits; - ULONG UncompressedFormat; - if (Format == 0) - return 0; - - psurf = SURFACE_AllocSurfaceWithHandle(); - if (psurf == NULL) - { - return 0; - } - hbmp = psurf->BaseObject.hHmgr; - - if (! SURFACE_InitBitsLock(psurf)) - { - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(hbmp); - return 0; - } - pso = &psurf->SurfObj; - - if (Format == BMF_4RLE) - { - pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP)); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedFormat = BMF_4BPP; - UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); - DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format); - } - else if (Format == BMF_8RLE) - { - pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP)); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedFormat = BMF_8BPP; - UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); - DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format); - } - else - { - pso->lDelta = abs(Width); - pso->cjBits = pso->lDelta * Size.cy; - UncompressedBits = Bits; - UncompressedFormat = Format; - } - - if (UncompressedBits != NULL) - { - pso->pvBits = UncompressedBits; - } - else - { - if (pso->cjBits == 0) - { - pso->pvBits = NULL; - } - else - { - if (0 != (Flags & BMF_USERMEM)) - { - pso->pvBits = EngAllocUserMem(pso->cjBits, 0); - } - else - { - pso->pvBits = EngAllocMem(0 != (Flags & BMF_NOZEROINIT) ? - 0 : FL_ZERO_MEMORY, - pso->cjBits, TAG_DIB); - } - if (pso->pvBits == NULL) - { - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(hbmp); - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - return 0; - } - } - } - - if (0 == (Flags & BMF_TOPDOWN)) - { - pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta); - pso->lDelta = - pso->lDelta; - } - else - { - pso->pvScan0 = pso->pvBits; - } - - pso->dhsurf = 0; /* device managed surface */ - pso->hsurf = (HSURF)hbmp; - pso->dhpdev = NULL; - pso->hdev = NULL; - pso->sizlBitmap = Size; - pso->iBitmapFormat = UncompressedFormat; - pso->iType = STYPE_BITMAP; - pso->fjBitmap = Flags & (BMF_TOPDOWN | BMF_NOZEROINIT); - pso->iUniq = 0; - - psurf->flHooks = 0; - psurf->flFlags = 0; - psurf->dimension.cx = 0; - psurf->dimension.cy = 0; - - psurf->hSecure = NULL; - psurf->hDIBSection = NULL; - - SURFACE_UnlockSurface(psurf); - - return hbmp; -} - -/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */ -typedef struct _DEVBITMAPINFO -{ - ULONG Format; - ULONG Width; - ULONG Height; - ULONG Flags; - ULONG Size; -} DEVBITMAPINFO, *PDEVBITMAPINFO; - -SURFOBJ* -FASTCALL -SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, - IN PVOID Bits) -{ - BOOLEAN Compressed = FALSE; - ULONG ScanLine = 0; // Compiler is dumb - ULONG Size; - SURFOBJ *pso; - PSURFACE psurf; - SIZEL LocalSize; - BOOLEAN AllocatedLocally = FALSE; - PVOID DecompressedBits = NULL; - - /* - * First, check the format so we can get the aligned scanline width. - * RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines - * since they are compressed surfaces! - */ - switch (BitmapInfo->Format) - { - case BMF_1BPP: - ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3; - break; - - case BMF_4BPP: - ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1; - break; - - case BMF_8BPP: - ScanLine = (BitmapInfo->Width + 3) & ~3; - break; - - case BMF_16BPP: - ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1; - break; - - case BMF_24BPP: - ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3; - break; - - case BMF_32BPP: - ScanLine = BitmapInfo->Width << 2; - break; - - case BMF_8RLE: - ScanLine = (BitmapInfo->Width + 3) & ~3; - Compressed = TRUE; - break; - case BMF_4RLE: - ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1; - Compressed = TRUE; - break; - - case BMF_JPEG: - case BMF_PNG: - ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-) - DPRINT1("No support for JPEG and PNG formats\n"); - return NULL; - - default: - DPRINT1("Invalid bitmap format\n"); - return NULL; - } - - /* Save local bitmap size */ - LocalSize.cy = BitmapInfo->Height; - LocalSize.cx = BitmapInfo->Width; - - /* Does the device manage its own surface? */ - if (!Bits) - { - /* We need to allocate bits for the caller, figure out the size */ - if (Compressed) - { - /* Note: we should not be seeing this scenario from ENGDDI */ - ASSERT(FALSE); - DPRINT1("RLE compressed bitmap requested with no valid bitmap bits\n"); - return NULL; - } - else - { - /* The height times the bytes for each scanline */ - Size = BitmapInfo->Height * ScanLine; - } - - if (Size) - { - /* Check for allocation flag */ - if (BitmapInfo->Flags & BMF_USERMEM) - { - /* Get the bits from user-mode memory */ - Bits = EngAllocUserMem(Size, 'mbuG'); - } - else - { - /* Get kernel bits (zeroed out if requested) */ - Bits = EngAllocMem((BitmapInfo->Flags & BMF_NOZEROINIT) ? 0 : FL_ZERO_MEMORY, - Size, - TAG_DIB); - } - AllocatedLocally = TRUE; - /* Bail out if that failed */ - if (!Bits) return NULL; - } - } - else - { - /* Should not have asked for user memory */ - ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0); - - if (Compressed) - { - DecompressedBits = EngAllocMem(FL_ZERO_MEMORY, BitmapInfo->Height * ScanLine, TAG_DIB); - - if(!DecompressedBits) - return NULL; - - if(!DecompressBitmap(LocalSize, (BYTE *)Bits, (BYTE *)DecompressedBits, ScanLine, BitmapInfo->Format)) - { - EngFreeMem(DecompressedBits); - return NULL; - } - - BitmapInfo->Format = (BitmapInfo->Format == BMF_4RLE) ? BMF_4BPP : BMF_8BPP; - } - } - - /* Allocate the actual surface object structure */ - psurf = SURFACE_AllocSurfaceWithHandle(); + /* Allocate a surface */ + psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat); if (!psurf) { - if(Bits && AllocatedLocally) - { - if(BitmapInfo->Flags & BMF_USERMEM) - EngFreeUserMem(Bits); - else - EngFreeMem(Bits); - } - if (DecompressedBits) - EngFreeMem(DecompressedBits); + DPRINT1("SURFACE_AllocSurface failed.\n"); return NULL; } - /* Lock down the surface */ - if (!SURFACE_InitBitsLock(psurf)) + /* Get the handle for the bitmap */ + hbmp = (HBITMAP)psurf->SurfObj.hsurf; + + /* Set the bitmap bits */ + if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits)) { /* Bail out if that failed */ - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(psurf->BaseObject.hHmgr); + DPRINT1("SURFACE_bSetBitmapBits failed.\n"); + SURFACE_FreeSurfaceByHandle(hbmp); return NULL; } - /* We should now have our surface object */ - pso = &psurf->SurfObj; + /* Set public ownership */ + GDIOBJ_SetOwnership(hbmp, NULL); - /* Save format and flags */ - pso->iBitmapFormat = BitmapInfo->Format; - pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM); - - /* Save size and type */ - pso->sizlBitmap = LocalSize; - pso->iType = STYPE_BITMAP; - - /* Device-managed surface, no flags or dimension */ - pso->dhsurf = 0; - pso->dhpdev = NULL; - pso->hdev = NULL; - psurf->flFlags = 0; - psurf->dimension.cx = 0; - psurf->dimension.cy = 0; - psurf->hSecure = NULL; - psurf->hDIBSection = NULL; - psurf->flHooks = 0; - - /* Set bits */ - if(Compressed) - pso->pvBits = DecompressedBits; - else - pso->pvBits = Bits; - - /* Number of bits is based on the height times the scanline */ - pso->cjBits = BitmapInfo->Height * ScanLine; - if (BitmapInfo->Flags & BMF_TOPDOWN) - { - /* For topdown, the base address starts with the bits */ - pso->pvScan0 = pso->pvBits; - pso->lDelta = ScanLine; - } - else - { - /* Otherwise we start with the end and go up */ - pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine); - pso->lDelta = -ScanLine; - } - - /* Finally set the handle and uniq */ - pso->hsurf = (HSURF)psurf->BaseObject.hHmgr; - pso->iUniq = 0; - - /* Unlock and return the surface */ + /* Unlock the surface and return */ SURFACE_UnlockSurface(psurf); - return pso; + return hbmp; } /* @@ -625,108 +311,66 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo, */ HBITMAP APIENTRY -EngCreateBitmap(IN SIZEL Size, - IN LONG Width, - IN ULONG Format, - IN ULONG Flags, - IN PVOID Bits) +EngCreateDeviceBitmap( + IN DHSURF dhsurf, + IN SIZEL sizl, + IN ULONG iFormat) { - SURFOBJ* Surface; - DEVBITMAPINFO BitmapInfo; - - /* Capture the parameters */ - BitmapInfo.Format = Format; - BitmapInfo.Width = Size.cx; - BitmapInfo.Height = Size.cy; - BitmapInfo.Flags = Flags; - - /* - * If the display driver supports framebuffer access, use the scanline width - * to determine the actual width of the bitmap, and convert it to pels instead - * of bytes. - */ - if ((Bits) && (Width)) - { - switch (BitmapInfo.Format) - { - /* Do the conversion for each bit depth we support */ - case BMF_1BPP: - BitmapInfo.Width = Width * 8; - break; - case BMF_4BPP: - BitmapInfo.Width = Width * 2; - break; - case BMF_8BPP: - BitmapInfo.Width = Width; - break; - case BMF_16BPP: - BitmapInfo.Width = Width / 2; - break; - case BMF_24BPP: - BitmapInfo.Width = Width / 3; - break; - case BMF_32BPP: - BitmapInfo.Width = Width / 4; - break; - } - } - - /* Now create the surface */ - Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits); - if (!Surface) return 0; - - /* Set public ownership and reutrn the handle */ - GDIOBJ_SetOwnership(Surface->hsurf, NULL); - return Surface->hsurf; -} - -/* - * @unimplemented - */ -HSURF APIENTRY -EngCreateDeviceSurface(IN DHSURF dhsurf, - IN SIZEL Size, - IN ULONG Format) -{ - HSURF hsurf; - SURFOBJ *pso; PSURFACE psurf; + HBITMAP hbmp; - psurf = SURFACE_AllocSurfaceWithHandle(); + /* Allocate a surface */ + psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat); if (!psurf) { return 0; } - hsurf = psurf->BaseObject.hHmgr; - GDIOBJ_SetOwnership(hsurf, NULL); + /* Set the device handle */ + psurf->SurfObj.dhsurf = dhsurf; - if (!SURFACE_InitBitsLock(psurf)) + /* Get the handle for the bitmap */ + hbmp = (HBITMAP)psurf->SurfObj.hsurf; + + /* Set public ownership */ + GDIOBJ_SetOwnership(hbmp, NULL); + + /* Unlock the surface and return */ + SURFACE_UnlockSurface(psurf); + return hbmp; +} + +HSURF +APIENTRY +EngCreateDeviceSurface( + IN DHSURF dhsurf, + IN SIZEL sizl, + IN ULONG iFormat) +{ + PSURFACE psurf; + HSURF hsurf; + + /* Allocate a surface */ + psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat); + if (!psurf) { - SURFACE_UnlockSurface(psurf); - SURFACE_FreeSurfaceByHandle(hsurf); return 0; } - pso = &psurf->SurfObj; - pso->dhsurf = dhsurf; - pso->hsurf = hsurf; - pso->sizlBitmap = Size; - pso->iBitmapFormat = Format; - pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)); - pso->iType = STYPE_DEVICE; - pso->iUniq = 0; + /* Set the device handle */ + psurf->SurfObj.dhsurf = dhsurf; - psurf->flHooks = 0; + /* Get the handle for the surface */ + hsurf = psurf->SurfObj.hsurf; + /* Set public ownership */ + GDIOBJ_SetOwnership(hsurf, NULL); + + /* Unlock the surface and return */ SURFACE_UnlockSurface(psurf); - return hsurf; } -/* - * @implemented - */ BOOL APIENTRY EngAssociateSurface( @@ -753,17 +397,19 @@ EngAssociateSurface( pso->dhpdev = ppdev->dhpdev; /* Hook up specified functions */ - psurf->flHooks = flHooks; + psurf->flags &= ~HOOK_FLAGS; + psurf->flags |= (flHooks & HOOK_FLAGS); + + /* Get palette */ + psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); SURFACE_UnlockSurface(psurf); return TRUE; } -/* - * @implemented - */ -BOOL APIENTRY +BOOL +APIENTRY EngModifySurface( IN HSURF hsurf, IN HDEV hdev, @@ -795,17 +441,20 @@ EngModifySurface( pso->dhpdev = ppdev->dhpdev; /* Hook up specified functions */ - psurf->flHooks = flHooks; + psurf->flags &= ~HOOK_FLAGS; + psurf->flags |= (flHooks & HOOK_FLAGS); + + /* Get palette */ + psurf->ppal = PALETTE_ShareLockPalette(ppdev->devinfo.hpalDefault); SURFACE_UnlockSurface(psurf); return TRUE; } -/* - * @implemented - */ -BOOL APIENTRY + +BOOL +APIENTRY EngDeleteSurface(IN HSURF hsurf) { GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess()); @@ -813,17 +462,16 @@ EngDeleteSurface(IN HSURF hsurf) return TRUE; } -/* - * @implemented - */ -BOOL APIENTRY -EngEraseSurface(SURFOBJ *pso, - RECTL *Rect, - ULONG iColor) +BOOL +APIENTRY +EngEraseSurface( + SURFOBJ *pso, + RECTL *prcl, + ULONG iColor) { ASSERT(pso); - ASSERT(Rect); - return FillSolid(pso, Rect, iColor); + ASSERT(prcl); + return FillSolid(pso, prcl, iColor); } /* @@ -836,10 +484,8 @@ NtGdiEngLockSurface(IN HSURF hsurf) } -/* - * @implemented - */ -SURFOBJ * APIENTRY +SURFOBJ * +APIENTRY EngLockSurface(IN HSURF hsurf) { SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP); @@ -850,20 +496,15 @@ EngLockSurface(IN HSURF hsurf) return NULL; } - -/* - * @implemented - */ -VOID APIENTRY +VOID +APIENTRY NtGdiEngUnlockSurface(IN SURFOBJ *pso) { EngUnlockSurface(pso); } -/* - * @implemented - */ -VOID APIENTRY +VOID +APIENTRY EngUnlockSurface(IN SURFOBJ *pso) { if (pso != NULL) @@ -873,5 +514,4 @@ EngUnlockSurface(IN SURFOBJ *pso) } } - /* EOF */ diff --git a/subsystems/win32/win32k/eng/transblt.c b/subsystems/win32/win32k/eng/transblt.c index bca22440edd..0bfc145eb94 100644 --- a/subsystems/win32/win32k/eng/transblt.c +++ b/subsystems/win32/win32k/eng/transblt.c @@ -76,7 +76,7 @@ EngTransparentBlt(SURFOBJ *psoDest, OutputRect.top = DestRect->bottom; OutputRect.bottom = DestRect->top; } - + if(Clip) { if(OutputRect.left < Clip->rclBounds.left) @@ -284,17 +284,7 @@ IntEngTransparentBlt(SURFOBJ *psoDest, OutputRect = InputClippedRect; } - if(psoSource != psoDest) - { - SURFACE_LockBitmapBits(psurfSource); - MouseSafetyOnDrawStart(psoSource, InputRect.left, InputRect.top, - InputRect.right, InputRect.bottom); - } - SURFACE_LockBitmapBits(psurfDest); - MouseSafetyOnDrawStart(psoDest, OutputRect.left, OutputRect.top, - OutputRect.right, OutputRect.bottom); - - if(psurfDest->flHooks & HOOK_TRANSPARENTBLT) + if(psurfDest->flags & HOOK_TRANSPARENTBLT) { Ret = GDIDEVFUNCS(psoDest).TransparentBlt( psoDest, psoSource, Clip, ColorTranslation, &OutputRect, @@ -309,14 +299,6 @@ IntEngTransparentBlt(SURFOBJ *psoDest, &OutputRect, &InputRect, iTransColor, Reserved); } - MouseSafetyOnDrawEnd(psoDest); - SURFACE_UnlockBitmapBits(psurfDest); - if(psoSource != psoDest) - { - MouseSafetyOnDrawEnd(psoSource); - SURFACE_UnlockBitmapBits(psurfSource); - } - return Ret; } diff --git a/subsystems/win32/win32k/eng/xlate.c b/subsystems/win32/win32k/eng/xlate.c index 77f2a213ae1..8f9962341e3 100644 --- a/subsystems/win32/win32k/eng/xlate.c +++ b/subsystems/win32/win32k/eng/xlate.c @@ -64,7 +64,7 @@ EXLATEOBJ_iXlateRGBtoBGR(PEXLATEOBJ pxlo, ULONG iColor) { ULONG iNewColor; - /* Copy green and alpha */ + /* Copy green */ iNewColor = iColor & 0xff00ff00; /* Mask red and blue */ @@ -362,19 +362,19 @@ EXLATEOBJ_vInitialize( EXLATEOBJ_vInitTrivial(pexlo); if (ppalDst == ppalSrc || !ppalSrc || !ppalDst || - ((ppalDst->Mode == PAL_RGB || ppalDst->Mode == PAL_BGR) && - ppalDst->Mode == ppalSrc->Mode)) + ((ppalDst->flFlags == PAL_RGB || ppalDst->flFlags == PAL_BGR) && + ppalDst->flFlags == ppalSrc->flFlags)) { return; } pexlo->ppalSrc = ppalSrc; pexlo->ppalDst = ppalDst; - pexlo->xlo.iSrcType = ppalSrc->Mode; - pexlo->xlo.iDstType = ppalDst->Mode; + pexlo->xlo.iSrcType = ppalSrc->flFlags; + pexlo->xlo.iDstType = ppalDst->flFlags; /* Chack if both of the pallettes are indexed */ - if (!(ppalSrc->Mode & PAL_INDEXED) || !(ppalDst->Mode & PAL_INDEXED)) + if (!(ppalSrc->flFlags & PAL_INDEXED) || !(ppalDst->flFlags & PAL_INDEXED)) { /* At least one palette is not indexed, calculate shifts/masks */ ULONG aulMasksSrc[3], aulMasksDst[3]; @@ -391,10 +391,10 @@ EXLATEOBJ_vInitialize( pexlo->ulBlueShift = CalculateShift(aulMasksSrc[2], aulMasksDst[2]); } - if (ppalSrc->Mode & PAL_MONOCHROME) + if (ppalSrc->flFlags & PAL_MONOCHROME) { /* This is a monochrome palette */ - if (!(ppalDst->Mode & PAL_MONOCHROME)) + if (!(ppalDst->flFlags & PAL_MONOCHROME)) { /* Mono to color, use the dest DC's fore and back color */ pexlo->pfnXlate = EXLATEOBJ_iXlateTable; @@ -406,28 +406,28 @@ EXLATEOBJ_vInitialize( PALETTE_ulGetNearestIndex(ppalDst, crDstBackColor); } } - else if (ppalDst->Mode & PAL_MONOCHROME) + else if (ppalDst->flFlags & PAL_MONOCHROME) { pexlo->pfnXlate = EXLATEOBJ_iXlateToMono; pexlo->xlo.flXlate |= XO_TO_MONO; pexlo->xlo.cEntries = 1; - if (ppalSrc->Mode & PAL_INDEXED) + if (ppalSrc->flFlags & PAL_INDEXED) { pexlo->aulXlate[0] = PALETTE_ulGetNearestPaletteIndex(ppalSrc, crSrcBackColor); } - else if (ppalSrc->Mode & PAL_BGR) + else if (ppalSrc->flFlags & PAL_BGR) { pexlo->aulXlate[0] = crSrcBackColor; } - else if (ppalSrc->Mode & PAL_RGB) + else if (ppalSrc->flFlags & PAL_RGB) { pexlo->aulXlate[0] = RGB(GetBValue(crSrcBackColor), GetGValue(crSrcBackColor), GetRValue(crSrcBackColor)); } - else if (ppalSrc->Mode & PAL_BITFIELDS) + else if (ppalSrc->flFlags & PAL_BITFIELDS) { PALETTE_vGetBitMasks(ppalSrc, &pexlo->ulRedMask); pexlo->ulRedShift = CalculateShift(0xFF, pexlo->ulRedMask); @@ -437,7 +437,7 @@ EXLATEOBJ_vInitialize( pexlo->aulXlate[0] = EXLATEOBJ_iXlateShiftAndMask(pexlo, crSrcBackColor); } } - else if (ppalSrc->Mode & PAL_INDEXED) + else if (ppalSrc->flFlags & PAL_INDEXED) { cEntries = ppalSrc->NumColors; @@ -458,7 +458,7 @@ EXLATEOBJ_vInitialize( pexlo->xlo.cEntries = cEntries; pexlo->pfnXlate = EXLATEOBJ_iXlateTable; - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) { pexlo->xlo.flXlate |= XO_TABLE; @@ -504,78 +504,78 @@ EXLATEOBJ_vInitialize( } } } - else if (ppalSrc->Mode & PAL_RGB) + else if (ppalSrc->flFlags & PAL_RGB) { - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoPal; - else if (ppalDst->Mode & PAL_BGR) + else if (ppalDst->flFlags & PAL_BGR) pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR; - else if (ppalDst->Mode & PAL_RGB16_555) + else if (ppalDst->flFlags & PAL_RGB16_555) pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto555; - else if (ppalDst->Mode & PAL_RGB16_565) + else if (ppalDst->flFlags & PAL_RGB16_565) pexlo->pfnXlate = EXLATEOBJ_iXlateRGBto565; - else if (ppalDst->Mode & PAL_BITFIELDS) + else if (ppalDst->flFlags & PAL_BITFIELDS) pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; } - else if (ppalSrc->Mode & PAL_BGR) + else if (ppalSrc->flFlags & PAL_BGR) { - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal; - else if (ppalDst->Mode & PAL_RGB) + else if (ppalDst->flFlags & PAL_RGB) /* The inverse function works the same */ pexlo->pfnXlate = EXLATEOBJ_iXlateRGBtoBGR; - else if (ppalDst->Mode & PAL_RGB16_555) + else if (ppalDst->flFlags & PAL_RGB16_555) pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto555; - else if (ppalDst->Mode & PAL_RGB16_565) + else if (ppalDst->flFlags & PAL_RGB16_565) pexlo->pfnXlate = EXLATEOBJ_iXlateBGRto565; - else if (ppalDst->Mode & PAL_BITFIELDS) + else if (ppalDst->flFlags & PAL_BITFIELDS) pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; } - else if (ppalSrc->Mode & PAL_RGB16_555) + else if (ppalSrc->flFlags & PAL_RGB16_555) { - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) pexlo->pfnXlate = EXLATEOBJ_iXlate555toPal; - else if (ppalDst->Mode & PAL_RGB) + else if (ppalDst->flFlags & PAL_RGB) pexlo->pfnXlate = EXLATEOBJ_iXlate555toRGB; - else if (ppalDst->Mode & PAL_BGR) + else if (ppalDst->flFlags & PAL_BGR) pexlo->pfnXlate = EXLATEOBJ_iXlate555toBGR; - else if (ppalDst->Mode & PAL_RGB16_565) + else if (ppalDst->flFlags & PAL_RGB16_565) pexlo->pfnXlate = EXLATEOBJ_iXlate555to565; - else if (ppalDst->Mode & PAL_BITFIELDS) + else if (ppalDst->flFlags & PAL_BITFIELDS) pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; } - else if (ppalSrc->Mode & PAL_RGB16_565) + else if (ppalSrc->flFlags & PAL_RGB16_565) { - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) pexlo->pfnXlate = EXLATEOBJ_iXlate565toPal; - else if (ppalDst->Mode & PAL_RGB) + else if (ppalDst->flFlags & PAL_RGB) pexlo->pfnXlate = EXLATEOBJ_iXlate565toRGB; - else if (ppalDst->Mode & PAL_BGR) + else if (ppalDst->flFlags & PAL_BGR) pexlo->pfnXlate = EXLATEOBJ_iXlate565toBGR; - else if (ppalDst->Mode & PAL_RGB16_555) + else if (ppalDst->flFlags & PAL_RGB16_555) pexlo->pfnXlate = EXLATEOBJ_iXlate565to555; - else if (ppalDst->Mode & PAL_BITFIELDS) + else if (ppalDst->flFlags & PAL_BITFIELDS) pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; } - else if (ppalSrc->Mode & PAL_BITFIELDS) + else if (ppalSrc->flFlags & PAL_BITFIELDS) { - if (ppalDst->Mode & PAL_INDEXED) + if (ppalDst->flFlags & PAL_INDEXED) pexlo->pfnXlate = EXLATEOBJ_iXlateBitfieldsToPal; else pexlo->pfnXlate = EXLATEOBJ_iXlateShiftAndMask; @@ -603,157 +603,24 @@ EXLATEOBJ_vInitXlateFromDCs( PDC pdcDst) { PSURFACE psurfDst, psurfSrc; - HPALETTE hpalSrc, hpalDst; - PPALETTE ppalSrc, ppalDst, ppalDstDc; - - DPRINT("Enter EXLATEOBJ_vInitXlateFromDCs\n"); - - /* Do basic init */ - EXLATEOBJ_vInitTrivial(pexlo); psurfDst = pdcDst->dclevel.pSurface; psurfSrc = pdcSrc->dclevel.pSurface; + /* Check for trivial color translation */ if (psurfDst == psurfSrc) { + EXLATEOBJ_vInitTrivial(pexlo); return; } - hpalSrc = psurfSrc->hDIBPalette; - if (!hpalSrc) - hpalSrc = pPrimarySurface->devinfo.hpalDefault; - - ppalSrc = PALETTE_ShareLockPalette(hpalSrc); - if (!ppalSrc) - return; - - hpalDst = psurfDst->hDIBPalette; - if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault; - - ppalDst = PALETTE_ShareLockPalette(hpalDst); - if (!ppalDst) - { - PALETTE_ShareUnlockPalette(ppalSrc); - return; - } - - ppalDstDc = pdcDst->dclevel.ppal; - ASSERT(ppalDstDc); - - /* KB41464 details how to convert between mono and color */ - if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP) - { - if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP) - { - // HACK!! FIXME: 1bpp DDBs should have gpalMono already! - EXLATEOBJ_vInitialize(pexlo, - ppalSrc, - &gpalMono, - pdcSrc->pdcattr->crBackgroundClr, - pdcDst->pdcattr->crBackgroundClr, - pdcDst->pdcattr->crForegroundClr); - } - } - else if (psurfSrc->SurfObj.iBitmapFormat == BMF_1BPP && !psurfSrc->hSecure) - { - // HACK!! FIXME: 1bpp DDBs should have gpalMono already! - EXLATEOBJ_vInitialize(pexlo, - &gpalMono, - ppalDst, - 0, - pdcDst->pdcattr->crBackgroundClr, - pdcDst->pdcattr->crForegroundClr); - } - else - { - EXLATEOBJ_vInitialize(pexlo, ppalSrc, ppalDst, 0, 0, 0); - } - - PALETTE_ShareUnlockPalette(ppalDst); - PALETTE_ShareUnlockPalette(ppalSrc); -} - - -VOID -NTAPI -EXLATEOBJ_vInitBrushXlate( - PEXLATEOBJ pexlo, - BRUSH *pbrush, - SURFACE *psurfDst, - COLORREF crForegroundClr, - COLORREF crBackgroundClr) -{ - HPALETTE hpalDst = NULL; - PPALETTE ppalDst, ppalPattern; - SURFACE *psurfPattern; - - ASSERT(pexlo); - ASSERT(pbrush); - ASSERT(psurfDst); - ASSERT(!(pbrush->flAttrs & (GDIBRUSH_IS_SOLID | GDIBRUSH_IS_NULL))); - - EXLATEOBJ_vInitTrivial(pexlo); - - hpalDst = psurfDst->hDIBPalette; - if (!hpalDst) hpalDst = pPrimarySurface->devinfo.hpalDefault; - ppalDst = PALETTE_ShareLockPalette(hpalDst); - if (!ppalDst) - { - DPRINT1("No ppalDst!\n"); - return; - } - - psurfPattern = SURFACE_ShareLockSurface(pbrush->hbmPattern); - if (!psurfPattern) - { - PALETTE_ShareUnlockPalette(ppalDst); - return; - } - -#if 0 - if (psurfDst->SurfObj.iBitmapFormat == BMF_1BPP) - { - if (psurfSrc->SurfObj.iBitmapFormat != BMF_1BPP) - { - // HACK!! FIXME: 1bpp DDBs should have gpalMono already! - EXLATEOBJ_vInitialize(pexlo, - ppalSrc, - &gpalMono, - 0, - crBackgroundClr, - crForegroundClr); - } - } - else -#endif - if (psurfPattern->SurfObj.iBitmapFormat == BMF_1BPP && - !(pbrush->flAttrs & GDIBRUSH_IS_DIB)) - { - /* Special case: 1 bpp pattern, not a DIB brush. */ - if (psurfDst->SurfObj.iBitmapFormat != BMF_1BPP) - { - // HACK!! FIXME: 1bpp DDBs should have gpalMono already! - EXLATEOBJ_vInitialize(pexlo, - &gpalMono, - ppalDst, - 0, - crBackgroundClr, - crForegroundClr); - } - } - else - { - /* Default: use the patterns' palette */ - ppalPattern = PALETTE_LockPalette(psurfPattern->hDIBPalette); - if (ppalPattern) - { - EXLATEOBJ_vInitialize(pexlo, &gpalRGB, ppalDst, 0, 0, 0); - PALETTE_UnlockPalette(ppalPattern); - } - } - - PALETTE_ShareUnlockPalette(ppalDst); - SURFACE_ShareUnlockSurface(psurfPattern); + /* Normal initialisation. No surface means DEFAULT_BITMAP */ + EXLATEOBJ_vInitialize(pexlo, + psurfSrc ? psurfSrc->ppal : &gpalMono, + psurfDst ? psurfDst->ppal : &gpalMono, + pdcSrc->pdcattr->crBackgroundClr, + pdcDst->pdcattr->crBackgroundClr, + pdcDst->pdcattr->crForegroundClr); } VOID @@ -827,9 +694,9 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut) /* Verify palette type match */ if (!ppal || ((iPal == XO_SRCPALETTE || iPal == XO_DESTPALETTE) - && !(ppal->Mode & PAL_INDEXED)) || + && !(ppal->flFlags & PAL_INDEXED)) || ((iPal == XO_SRCBITFIELDS || iPal == XO_DESTBITFIELDS) - && !(ppal->Mode & PAL_BITFIELDS))) + && !(ppal->flFlags & PAL_BITFIELDS))) { return 0; } @@ -840,7 +707,7 @@ XLATEOBJ_cGetPalette(XLATEOBJ *pxlo, ULONG iPal, ULONG cPal, ULONG *pPalOut) } /* Copy the values into the buffer */ - if (ppal->Mode & PAL_INDEXED) + if (ppal->flFlags & PAL_INDEXED) { cPal = min(cPal, ppal->NumColors); for (i = 0; i < cPal; i++) diff --git a/subsystems/win32/win32k/include/bitmaps.h b/subsystems/win32/win32k/include/bitmaps.h index 6a5e731c375..802028d4afa 100644 --- a/subsystems/win32/win32k/include/bitmaps.h +++ b/subsystems/win32/win32k/include/bitmaps.h @@ -2,11 +2,47 @@ #include "surface.h" -INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth); -int APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth); -INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse); +typedef struct tagBITMAPV5INFO +{ + BITMAPV5HEADER bmiHeader; + RGBQUAD bmiColors[256]; +} BITMAPV5INFO, *PBITMAPV5INFO; + INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer); HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits); HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap); UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel); -INT FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp); + +HBITMAP +APIENTRY +GreCreateBitmap( + IN INT nWidth, + IN INT nHeight, + IN UINT cPlanes, + IN UINT cBitsPixel, + IN OPTIONAL PVOID pvBits); + +HBITMAP +APIENTRY +GreCreateBitmapEx( + IN INT nWidth, + IN INT nHeight, + IN ULONG cjWidthBytes, + IN ULONG iFormat, + IN USHORT fjBitmap, + IN ULONG cjBits, + IN OPTIONAL PVOID pvBits, + IN FLONG flags); + +HBITMAP +FASTCALL +GreCreateDIBitmapInternal( + IN HDC hDc, + IN INT cx, + IN INT cy, + IN DWORD fInit, + IN OPTIONAL LPBYTE pjInit, + IN OPTIONAL PBITMAPINFO pbmi, + IN DWORD iUsage, + IN FLONG fl, + IN HANDLE hcmXform); diff --git a/subsystems/win32/win32k/include/dc.h b/subsystems/win32/win32k/include/dc.h index 41621f973c1..8150b169900 100644 --- a/subsystems/win32/win32k/include/dc.h +++ b/subsystems/win32/win32k/include/dc.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef __WIN32K_DC_H +#define __WIN32K_DC_H typedef struct _DC *PDC; @@ -22,6 +23,30 @@ typedef struct _DC *PDC; /* fl */ #define DC_FL_PAL_BACK 1 +#define DC_DISPLAY 1 +#define DC_DIRECT 2 +#define DC_CANCELED 4 +#define DC_PERMANANT 0x08 +#define DC_DIRTY_RAO 0x10 +#define DC_ACCUM_WMGR 0x20 +#define DC_ACCUM_APP 0x40 +#define DC_RESET 0x80 +#define DC_SYNCHRONIZEACCESS 0x100 +#define DC_EPSPRINTINGESCAPE 0x200 +#define DC_TEMPINFODC 0x400 +#define DC_FULLSCREEN 0x800 +#define DC_IN_CLONEPDEV 0x1000 +#define DC_REDIRECTION 0x2000 +#define DC_SHAREACCESS 0x4000 + +typedef enum +{ + DCTYPE_DIRECT = 0, + DCTYPE_MEMORY = 1, + DCTYPE_INFO = 2, +} DCTYPE; + + /* Type definitions ***********************************************************/ typedef struct _ROS_DC_INFO @@ -29,7 +54,7 @@ typedef struct _ROS_DC_INFO HRGN hClipRgn; /* Clip region (may be 0) */ HRGN hGCClipRgn; /* GC clip region (ClipRgn AND VisRgn) */ - CLIPOBJ *CombinedClip; /* Use XCLIPOBJ in DC. */ + CLIPOBJ *CombinedClip; UNICODE_STRING DriverName; @@ -136,13 +161,12 @@ extern PDC defaultDCstate; NTSTATUS FASTCALL InitDcImpl(VOID); PPDEVOBJ FASTCALL IntEnumHDev(VOID); -HDC FASTCALL DC_AllocDC(PUNICODE_STRING Driver); +PDC NTAPI DC_AllocDcWithHandle(); VOID FASTCALL DC_InitDC(HDC DCToInit); -HDC FASTCALL DC_FindOpenDC(PUNICODE_STRING Driver); VOID FASTCALL DC_AllocateDcAttr(HDC); VOID FASTCALL DC_FreeDcAttr(HDC); BOOL INTERNAL_CALL DC_Cleanup(PVOID ObjectBody); -BOOL FASTCALL DC_SetOwnership(HDC DC, PEPROCESS Owner); +BOOL FASTCALL DC_SetOwnership(HDC hDC, PEPROCESS Owner); VOID FASTCALL DC_LockDisplay(HDC); VOID FASTCALL DC_UnlockDisplay(HDC); BOOL FASTCALL IntGdiDeleteDC(HDC, BOOL); @@ -155,10 +179,16 @@ VOID FASTCALL DC_vUpdateFillBrush(PDC pdc); VOID FASTCALL DC_vUpdateLineBrush(PDC pdc); VOID FASTCALL DC_vUpdateTextBrush(PDC pdc); VOID FASTCALL DC_vUpdateBackgroundBrush(PDC pdc); +VOID FASTCALL DC_vFinishBlit(PDC pdc1, PDC pdc2); +VOID FASTCALL DC_vPrepareDCsForBlit(PDC pdc1, RECT rc1, PDC pdc2, RECT rc2); + +VOID NTAPI DC_vRestoreDC(IN PDC pdc, INT iSaveLevel); BOOL FASTCALL DCU_SyncDcAttrtoUser(PDC); BOOL FASTCALL DCU_SynchDcAttrtoUser(HDC); VOID FASTCALL DCU_SetDcUndeletable(HDC); +VOID NTAPI DC_vFreeDcAttr(PDC pdc); +VOID NTAPI DC_vInitDc(PDC pdc, DCTYPE dctype, PPDEVOBJ ppdev); COLORREF FASTCALL IntGdiSetBkColor (HDC hDC, COLORREF Color); INT FASTCALL IntGdiSetBkMode(HDC hDC, INT backgroundMode); @@ -174,12 +204,9 @@ VOID FASTCALL IntGdiUnreferencePdev(PPDEVOBJ pPDev, DWORD CleanUpType); HDC FASTCALL IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC); BOOL FASTCALL IntGdiCleanDC(HDC hDC); VOID FASTCALL IntvGetDeviceCaps(PPDEVOBJ, PDEVCAPS); -INT FASTCALL IntGdiGetDeviceCaps(PDC,INT); BOOL FASTCALL MakeInfoDC(PDC,BOOL); BOOL FASTCALL IntSetDefaultRegion(PDC); -extern PPDEVOBJ pPrimarySurface; - VOID FORCEINLINE DC_vSelectSurface(PDC pdc, PSURFACE psurfNew) @@ -228,5 +255,6 @@ DC_vSelectPalette(PDC pdc, PPALETTE ppal) pdc->dclevel.ppal = ppal; } -BOOL FASTCALL IntPrepareDriverIfNeeded(VOID); -extern PDEVOBJ PrimarySurface; +extern PBRUSH pbrDefaultBrush ; + +#endif /* not __WIN32K_DC_H */ diff --git a/subsystems/win32/win32k/include/device.h b/subsystems/win32/win32k/include/device.h new file mode 100644 index 00000000000..cdf60d7f80a --- /dev/null +++ b/subsystems/win32/win32k/include/device.h @@ -0,0 +1,57 @@ + +//#define _PDEVOBJ _PDEVOBJ2 +//#define PDEVOBJ PDEVOBJ2 +//#define PPDEVOBJ PPDEVOBJ2 + +//typedef struct _PDEVOBJ *PPDEVOBJ; + +#define TAG_GDEV 'gdev' + +VOID +APIENTRY +EngFileWrite( + IN PFILE_OBJECT pFileObject, + IN PVOID lpBuffer, + IN SIZE_T nLength, + IN PSIZE_T lpBytesWritten); + +PGRAPHICS_DEVICE +NTAPI +EngpFindGraphicsDevice( + PUNICODE_STRING pustrDevice, + DWORD iDevNum, + DWORD dwFlags); + +PGRAPHICS_DEVICE +NTAPI +EngpRegisterGraphicsDevice( + PUNICODE_STRING pustrDeviceName, + PUNICODE_STRING pustrDiplayDrivers, + PUNICODE_STRING pustrDescription, + PDEVMODEW pdmDefault); + +BOOL +NTAPI +InitDeviceImpl(); + +BOOL +FASTCALL +DC_AllocDcAttr(PDC pdc); + +//#define KeRosDumpStackFrames(Frames, Count) KdSystemDebugControl(TAG('R', 'o', 's', 'D'), (PVOID)Frames, Count, NULL, 0, NULL, KernelMode) +NTSYSAPI ULONG APIENTRY RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags); + +BOOL +NTAPI +PDEVOBJ_bSwitchMode( + PPDEVOBJ ppdev, + PDEVMODEW pdm); + +PDEVMODEW +NTAPI +PDEVOBJ_pdmMatchDevMode( + PPDEVOBJ ppdev, + PDEVMODEW pdm); + +extern PGRAPHICS_DEVICE gpPrimaryGraphicsDevice; +extern PGRAPHICS_DEVICE gpVgaGraphicsDevice; diff --git a/subsystems/win32/win32k/include/dib.h b/subsystems/win32/win32k/include/dib.h index 479476d3850..9d5b2b18462 100644 --- a/subsystems/win32/win32k/include/dib.h +++ b/subsystems/win32/win32k/include/dib.h @@ -5,15 +5,17 @@ INT FASTCALL DIB_BitmapInfoSize (const BITMAPINFO * info, WORD coloruse); HBITMAP APIENTRY -DIB_CreateDIBSection (PDC dc, PBITMAPINFO bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch); -INT APIENTRY -DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, PLONG width, PLONG height, PWORD planes, PWORD bpp, PLONG compr, PLONG size ); +DIB_CreateDIBSection (PDC dc, CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset, DWORD ovr_pitch); +int FASTCALL +DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, + LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ); INT APIENTRY DIB_GetDIBImageBytes (INT width, INT height, INT depth); -INT FASTCALL -DIB_GetDIBWidthBytes (INT width, INT depth); -RGBQUAD * FASTCALL -DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi); +HPALETTE FASTCALL +DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi); HPALETTE FASTCALL -BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType); +BuildDIBPalette (CONST BITMAPINFO *bmi); + +BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage); +VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig); \ No newline at end of file diff --git a/subsystems/win32/win32k/include/eng.h b/subsystems/win32/win32k/include/eng.h index 5d95070c03c..3ed830acad8 100644 --- a/subsystems/win32/win32k/include/eng.h +++ b/subsystems/win32/win32k/include/eng.h @@ -21,3 +21,19 @@ IntEngWindowChanged( VOID FASTCALL IntGdiAcquireSemaphore ( HSEMAPHORE hsem ); VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem ); ULONGLONG APIENTRY EngGetTickCount(VOID); + +BOOL +APIENTRY +EngFreeSectionMem( + IN PVOID pvSection OPTIONAL, + IN PVOID pvMappedBase OPTIONAL); + +PVOID +APIENTRY +EngAllocSectionMem( + OUT PVOID *ppvSection, + IN ULONG fl, + IN SIZE_T cjSize, + IN ULONG ulTag); + +VOID DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG iFormat); diff --git a/subsystems/win32/win32k/include/gdiobj.h b/subsystems/win32/win32k/include/gdiobj.h index 9ce98f0d830..a1a56b7ae24 100644 --- a/subsystems/win32/win32k/include/gdiobj.h +++ b/subsystems/win32/win32k/include/gdiobj.h @@ -71,6 +71,7 @@ VOID INTERNAL_CALL GDIOBJ_FreeObj (POBJ pObj, UCHAR ObjectType); BOOL INTERNAL_CALL GDIOBJ_FreeObjByHandle (HGDIOBJ hObj, DWORD ObjectType); PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType); PGDIOBJ INTERNAL_CALL GDIOBJ_ShareLockObj (HGDIOBJ hObj, DWORD ObjectType); +VOID INTERNAL_CALL GDIOBJ_LockMultipleObjs(ULONG ulCount, IN HGDIOBJ* ahObj, OUT PGDIOBJ* apObj); PVOID INTERNAL_CALL GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process); diff --git a/subsystems/win32/win32k/include/hook.h b/subsystems/win32/win32k/include/hook.h index d09304b4895..ce6d64e1b9f 100644 --- a/subsystems/win32/win32k/include/hook.h +++ b/subsystems/win32/win32k/include/hook.h @@ -1,17 +1,10 @@ #pragma once #define HOOK_THREAD_REFERENCED (0x1) -#define NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1) #define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK) #define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1)) #define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks & HOOKID_TO_FLAG(HookId)) -typedef struct tagHOOKTABLE -{ - LIST_ENTRY Hooks[NB_HOOKS]; /* array of hook chains */ - UINT Counts[NB_HOOKS]; /* use counts for each hook chain */ -} HOOKTABLE, *PHOOKTABLE; - typedef struct tagEVENTHOOK { THROBJHEAD head; @@ -32,11 +25,22 @@ typedef struct tagEVENTTABLE UINT Counts; } EVENTTABLE, *PEVENTTABLE; +typedef struct _NOTIFYEVENT +{ + DWORD event; + LONG idObject; + LONG idChild; + DWORD flags; +} NOTIFYEVENT, *PNOTIFYEVENT; + +LRESULT FASTCALL co_CallHook(INT HookId, INT Code, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam); LRESULT FASTCALL co_EVENT_CallEvents(DWORD, HWND, UINT_PTR, LONG_PTR); VOID FASTCALL HOOK_DestroyThreadHooks(PETHREAD Thread); +VOID FASTCALL EVENT_DestroyThreadEvents(PETHREAD Thread); PHOOK FASTCALL IntGetHookObject(HHOOK); PHOOK FASTCALL IntGetNextHook(PHOOK Hook); LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam, BOOL Ansi); +BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC); /* EOF */ diff --git a/subsystems/win32/win32k/include/inteng.h b/subsystems/win32/win32k/include/inteng.h index dc0bc98a845..9bcfc0ab838 100644 --- a/subsystems/win32/win32k/include/inteng.h +++ b/subsystems/win32/win32k/include/inteng.h @@ -45,7 +45,7 @@ IntEngLineTo(SURFOBJ *Surface, MIX mix); BOOL APIENTRY -IntEngBitBltEx(SURFOBJ *DestObj, +IntEngBitBlt(SURFOBJ *DestObj, SURFOBJ *SourceObj, SURFOBJ *Mask, CLIPOBJ *ClipRegion, @@ -55,14 +55,7 @@ IntEngBitBltEx(SURFOBJ *DestObj, POINTL *MaskOrigin, BRUSHOBJ *Brush, POINTL *BrushOrigin, - ROP4 Rop4, - BOOL RemoveMouse); -#define IntEngBitBlt(DestObj, SourceObj, Mask, ClipRegion, ColorTranslation, \ - DestRect, SourcePoint, MaskOrigin, Brush, BrushOrigin, \ - Rop4) \ - IntEngBitBltEx((DestObj), (SourceObj), (Mask), (ClipRegion), \ - (ColorTranslation), (DestRect), (SourcePoint), \ - (MaskOrigin), (Brush), (BrushOrigin), (Rop4), TRUE) + ROP4 Rop4); BOOL APIENTRY IntEngStretchBlt(SURFOBJ *DestObj, diff --git a/subsystems/win32/win32k/include/intgdi.h b/subsystems/win32/win32k/include/intgdi.h index d547ba460d6..fcbb7a08e10 100644 --- a/subsystems/win32/win32k/include/intgdi.h +++ b/subsystems/win32/win32k/include/intgdi.h @@ -167,9 +167,6 @@ IntGetSysColor(INT nIndex); /* Other Stuff */ -INT FASTCALL -IntGdiGetDeviceCaps(PDC dc, INT Index); - INT FASTCALL IntGdiEscape(PDC dc, @@ -186,14 +183,6 @@ IntEnumDisplaySettings( IN OUT LPDEVMODEW pDevMode, IN DWORD dwFlags); -LONG -FASTCALL -IntChangeDisplaySettings( - IN PUNICODE_STRING pDeviceName OPTIONAL, - IN LPDEVMODEW pDevMode, - IN DWORD dwflags, - IN PVOID lParam OPTIONAL); - HBITMAP FASTCALL IntCreateCompatibleBitmap(PDC Dc, diff --git a/subsystems/win32/win32k/include/ldevobj.h b/subsystems/win32/win32k/include/ldevobj.h new file mode 100644 index 00000000000..40070db631c --- /dev/null +++ b/subsystems/win32/win32k/include/ldevobj.h @@ -0,0 +1,86 @@ + +#ifdef __GNUC__ +/* Hack, for bug in ld. Will be removed soon. */ +#define __ImageBase _image_base__ +#endif +extern IMAGE_DOS_HEADER __ImageBase; + + +#define TAG_LDEV 'Gldv' + +#define GDI_ENGINE_VERSION DDI_DRIVER_VERSION_NT5_01 + +typedef enum +{ + LDEV_DEVICE_DISPLAY = 1, + LDEV_DEVICE_PRINTER = 2, + LDEV_DEVICE_META = 3, + LDEV_DEVICE_MIRROR = 4, + LDEV_IMAGE = 5, + LDEV_FONT = 6, +} LDEVTYPE; + +typedef struct _LDEVOBJ +{ + struct _LDEVOBJ *pldevNext; + struct _LDEVOBJ *pldevPrev; + SYSTEM_GDI_DRIVER_INFORMATION *pGdiDriverInfo; + LDEVTYPE ldevtype; + ULONG cRefs; + ULONG ulDriverVersion; + + union + { + PVOID apfn[INDEX_LAST]; + DRIVER_FUNCTIONS pfn; + }; + +} LDEVOBJ, *PLDEVOBJ; + +extern PLDEVOBJ gpldevHead; +extern HSEMAPHORE ghsemDriverMgmt; + +PLDEVOBJ +NTAPI +LDEVOBJ_pldevLoadImage( + PUNICODE_STRING pusPathName, + LDEVTYPE ldevtype); + +BOOL +NTAPI +LDEVOBJ_bLoadDriver( + IN PLDEVOBJ pldev); + +PVOID +NTAPI +LDEVOBJ_pvFindImageProcAddress( + IN PLDEVOBJ pldev, + IN LPSTR lpProcName); + +PDEVMODEINFO +NTAPI +LDEVOBJ_pdmiGetModes( + PLDEVOBJ pldev, + HANDLE hDriver); + +BOOL +NTAPI +InitLDEVImpl(); + +PLDEVOBJ +APIENTRY +EngLoadImageEx( + LPWSTR pwszDriverName, + ULONG ldevtype); + +PLDEVOBJ +NTAPI +EngGetLDEV( + PDEVMODEW pdm); + +NTSTATUS +APIENTRY +DriverEntry ( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath); + diff --git a/subsystems/win32/win32k/include/misc.h b/subsystems/win32/win32k/include/misc.h index 366c44b4b7c..cfe47888512 100644 --- a/subsystems/win32/win32k/include/misc.h +++ b/subsystems/win32/win32k/include/misc.h @@ -29,6 +29,33 @@ VOID FASTCALL IntUserManualGuiCheck(LONG Check); PVOID APIENTRY HackSecureVirtualMemory(IN PVOID,IN SIZE_T,IN ULONG,OUT PVOID *); VOID APIENTRY HackUnsecureVirtualMemory(IN PVOID); +NTSTATUS +NTAPI +RegOpenKey( + LPCWSTR pwszKeyName, + PHKEY phkey); + +NTSTATUS +NTAPI +RegQueryValue( + IN HKEY hkey, + IN PCWSTR pwszValueName, + IN ULONG ulType, + OUT PVOID pvData, + IN OUT PULONG pcbValue); + +VOID +NTAPI +RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData); + +VOID +NTAPI +RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData); + +BOOL +NTAPI +RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData); + BOOL NTAPI RegReadUserSetting( diff --git a/subsystems/win32/win32k/include/mouse.h b/subsystems/win32/win32k/include/mouse.h index 0e5f68b9626..306148bef30 100644 --- a/subsystems/win32/win32k/include/mouse.h +++ b/subsystems/win32/win32k/include/mouse.h @@ -2,8 +2,8 @@ #include -INT INTERNAL_CALL MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2); -INT INTERNAL_CALL MouseSafetyOnDrawEnd(SURFOBJ *SurfObj); +INT INTERNAL_CALL MouseSafetyOnDrawStart(PPDEVOBJ ppdev, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2); +INT INTERNAL_CALL MouseSafetyOnDrawEnd(PPDEVOBJ ppdev); #ifndef XBUTTON1 #define XBUTTON1 (0x01) diff --git a/subsystems/win32/win32k/include/msgqueue.h b/subsystems/win32/win32k/include/msgqueue.h index e35ab0f5a15..569f1028d83 100644 --- a/subsystems/win32/win32k/include/msgqueue.h +++ b/subsystems/win32/win32k/include/msgqueue.h @@ -87,9 +87,6 @@ typedef struct _USER_MESSAGE_QUEUE /* Caret information for this queue */ PTHRDCARETINFO CaretInfo; - /* Window hooks */ - PHOOKTABLE Hooks; - /* queue state tracking */ WORD WakeMask; WORD QueueBits; @@ -212,9 +209,6 @@ BOOL APIENTRY IntInitMessagePumpHook(); BOOL APIENTRY IntUninitMessagePumpHook(); #define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) -PHOOKTABLE FASTCALL MsqGetHooks(PUSER_MESSAGE_QUEUE Queue); -VOID FASTCALL MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks); - LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam); LPARAM FASTCALL MsqGetMessageExtraInfo(VOID); VOID APIENTRY MsqRemoveWindowMessagesFromQueue(PVOID pWindow); /* F*(&$ headers, will be gone in the rewrite! */ diff --git a/subsystems/win32/win32k/include/palette.h b/subsystems/win32/win32k/include/palette.h index 76839b075f5..82fcb3ca05b 100644 --- a/subsystems/win32/win32k/include/palette.h +++ b/subsystems/win32/win32k/include/palette.h @@ -40,7 +40,7 @@ typedef struct _PALETTE PALOBJ PalObj; XLATEOBJ *logicalToSystem; HPALETTE Self; - ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR + FLONG flFlags; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR ULONG NumColors; PALETTEENTRY *IndexedColors; ULONG RedMask; @@ -52,8 +52,8 @@ typedef struct _PALETTE HDEV hPDev; } PALETTE, *PPALETTE; -extern PALETTE gpalRGB, gpalBGR, gpalMono; - +extern PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault; +extern PPALETTE appalSurfaceDefault[]; HPALETTE FASTCALL PALETTE_AllocPalette(ULONG Mode, ULONG NumColors, diff --git a/subsystems/win32/win32k/include/pdevobj.h b/subsystems/win32/win32k/include/pdevobj.h index ca0c3fa0821..6a19a1bffec 100644 --- a/subsystems/win32/win32k/include/pdevobj.h +++ b/subsystems/win32/win32k/include/pdevobj.h @@ -1,6 +1,5 @@ -#pragma once - -#include +#ifndef __WIN32K_PDEVOBJ_H +#define __WIN32K_PDEVOBJ_H /* PDEVOBJ flags */ #define PDEV_DISPLAY 0x00000001 /* Display device */ @@ -37,6 +36,21 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */ } GDIPOINTER, *PGDIPOINTER; +typedef struct _DEVMODEINFO +{ + struct _DEVMODEINFO *pdmiNext; + struct _LDEVOBJ *pldev; + ULONG cbdevmode; + DEVMODEW adevmode[1]; +} DEVMODEINFO, *PDEVMODEINFO; + +typedef struct +{ + DWORD dwFlags; + PDEVMODEW pdm; + +} DEVMODEENTRY, *PDEVMODEENTRY; + typedef struct _GRAPHICS_DEVICE { WCHAR szNtDeviceName[CCHDEVICENAME/2]; @@ -48,15 +62,17 @@ typedef struct _GRAPHICS_DEVICE DWORD hkClassDriverConfig; DWORD StateFlags; /* See DISPLAY_DEVICE_* */ ULONG cbdevmodeInfo; - PVOID devmodeInfo; - DWORD cbdevmodeInfo1; - PVOID devmodeInfo1; - LPWSTR pwszDeviceNames; + PDEVMODEINFO pdevmodeInfo; + ULONG cDevModes; + PDEVMODEENTRY pDevModeList; + LPWSTR pDiplayDrivers; LPWSTR pwszDescription; DWORD dwUnknown; PVOID pUnknown; PFILE_OBJECT FileObject; DWORD ProtocolType; + ULONG iDefaultMode; + ULONG iCurrentMode; } GRAPHICS_DEVICE, *PGRAPHICS_DEVICE; typedef struct _PDEVOBJ @@ -64,8 +80,8 @@ typedef struct _PDEVOBJ BASEOBJECT BaseObject; struct _PDEVOBJ * ppdevNext; - INT cPdevRefs; - INT cPdevOpenRefs; + LONG cPdevRefs; + LONG cPdevOpenRefs; struct _PDEVOBJ * ppdevParent; FLONG flFlags; // flags // FLONG flAccelerated; @@ -98,17 +114,17 @@ typedef struct _PDEVOBJ // PFN_DrvSetPalette pfnDrvSetPalette; // PFN_DrvNotify pfnDrvNotify; // ULONG TagSig; -// PLDEVOBJ pldev; + struct _LDEVOBJ * pldev; DHPDEV dhpdev; /* DHPDEV for device. */ - PVOID ppalSurf; /* PEPALOBJ/PPALETTE for this device. */ + struct _PALETTE* ppalSurf; /* PEPALOBJ/PPALETTE for this device. */ DEVINFO devinfo; GDIINFO gdiinfo; - HSURF pSurface; /* SURFACE for this device., FIXME: PSURFACE */ + PSURFACE pSurface; /* SURFACE for this device. */ // HANDLE hSpooler; /* Handle to spooler, if spooler dev driver. */ // PVOID pDesktopId; PGRAPHICS_DEVICE pGraphicsDevice; POINTL ptlOrigion; - PVOID pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */ + PDEVMODEW pdmwDev; /* Ptr->DEVMODEW.dmSize + dmDriverExtra == alloc size. */ // DWORD Unknown3; FLONG DxDd_Flags; /* DxDD active status flags. */ // LONG devAttr; @@ -117,15 +133,12 @@ typedef struct _PDEVOBJ union { DRIVER_FUNCTIONS DriverFunctions; + DRIVER_FUNCTIONS pfn; PVOID apfn[INDEX_LAST]; // B8C 0x0598 }; /* ros specific */ ULONG DxDd_nCount; - ULONG DisplayNumber; - DEVMODEW DMW; - PFILE_OBJECT VideoFileObject; - BOOLEAN PreparedDriver; GDIPOINTER Pointer; /* Stuff to keep track of software cursors; win32k gdi part */ UINT SafetyRemoveLevel; /* at what level was the cursor removed? @@ -134,13 +147,47 @@ typedef struct _PDEVOBJ struct _EDD_DIRECTDRAW_GLOBAL * pEDDgpl; } PDEVOBJ, *PPDEVOBJ; -/* PDEV and EDDX extra data container.*/ -typedef struct _PDEVEDD -{ - PDEVOBJ pdevobj; - EDD_DIRECTDRAW_GLOBAL EDDgpl; -} PDEVEDD, *PPDEVEDD; +/* Globals ********************************************************************/ -PSIZEL FASTCALL PDEV_sizl(PPDEVOBJ, PSIZEL); +extern PPDEVOBJ gppdevPrimary; +#define pPrimarySurface gppdevPrimary -extern ULONG gdwDirectDrawContext; + +/* Function prototypes ********************************************************/ + +PPDEVOBJ +NTAPI +EngpGetPDEV(PUNICODE_STRING pustrDevice); + +VOID +NTAPI +PDEVOBJ_vRelease(PPDEVOBJ ppdev); + +PSURFACE +NTAPI +PDEVOBJ_pSurface( + PPDEVOBJ ppdev); + +VOID +NTAPI +PDEVOBJ_vGetDeviceCaps( + PPDEVOBJ ppdev, + PDEVCAPS pDevCaps); + +BOOL +NTAPI +InitPDEVImpl(); + +BOOL +NTAPI +InitLDEVImpl(); + +BOOL +NTAPI +InitDeviceImpl(); + +PSIZEL +FASTCALL +PDEVOBJ_sizl(PPDEVOBJ, PSIZEL); + +#endif /* !__WIN32K_PDEVOBJ_H */ diff --git a/subsystems/win32/win32k/include/region.h b/subsystems/win32/win32k/include/region.h index d29b1b04fdf..5ad6e2cb52f 100644 --- a/subsystems/win32/win32k/include/region.h +++ b/subsystems/win32/win32k/include/region.h @@ -14,7 +14,7 @@ typedef struct _ROSRGNDATA RGNDATAHEADER rdh; RECTL *Buffer; -} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA; +} ROSRGNDATA, *PROSRGNDATA, *LPROSRGNDATA, REGION, *PREGION; /* Functions ******************************************************************/ diff --git a/subsystems/win32/win32k/include/surface.h b/subsystems/win32/win32k/include/surface.h index 3fe90540467..485f3dc72b3 100644 --- a/subsystems/win32/win32k/include/surface.h +++ b/subsystems/win32/win32k/include/surface.h @@ -8,48 +8,88 @@ /* GDI surface object */ typedef struct _SURFACE { - BASEOBJECT BaseObject; + BASEOBJECT BaseObject; - SURFOBJ SurfObj; - FLONG flHooks; - FLONG flFlags; - struct _PALETTE *ppal; + SURFOBJ SurfObj; + //XDCOBJ * pdcoAA; + FLONG flags; + struct _PALETTE *ppal; + //UINT unk_050; - union - { - HANDLE hSecureUMPD; // if UMPD_SURFACE set - HANDLE hMirrorParent;// if MIRROR_SURFACE set - HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set - }; + union + { + HANDLE hSecureUMPD; // if UMPD_SURFACE set + HANDLE hMirrorParent;// if MIRROR_SURFACE set + HANDLE hDDSurface; // if DIRECTDRAW_SURFACE set + }; - SIZEL dimension; /* For SetBitmapDimension(), do NOT use + SIZEL sizlDim; /* For SetBitmapDimension(), do NOT use to get width/height of bitmap, use bitmap.bmWidth/bitmap.bmHeight for that */ - - HDC hDC; // Doc in "Undocumented Windows", page 546, seems to be supported with XP. - ULONG cRef; // 0x064 - HPALETTE hpalHint; - /* For device-independent bitmaps: */ - HANDLE hDIBSection; - HANDLE hSecure; - DWORD dwOffset; + HDC hdc; // Doc in "Undocumented Windows", page 546, seems to be supported with XP. + ULONG cRef; + HPALETTE hpalHint; + + /* For device-independent bitmaps: */ + HANDLE hDIBSection; + HANDLE hSecure; + DWORD dwOffset; + //UINT unk_078; /* reactos specific */ - PFAST_MUTEX BitsLock; /* You need to hold this lock before you touch - the actual bits in the bitmap */ - HPALETTE hDIBPalette; - DWORD dsBitfields[3]; // hack, should probably use palette instead - DWORD biClrUsed; - DWORD biClrImportant; + DWORD biClrImportant; } SURFACE, *PSURFACE; -#define BITMAPOBJ_IS_APIBITMAP 0x1 +// flags field: +//#define HOOK_BITBLT 0x00000001 +//#define HOOK_STRETCHBLT 0x00000002 +//#define HOOK_PLGBLT 0x00000004 +//#define HOOK_TEXTOUT 0x00000008 +//#define HOOK_PAINT 0x00000010 +//#define HOOK_STROKEPATH 0x00000020 +//#define HOOK_FILLPATH 0x00000040 +//#define HOOK_STROKEANDFILLPATH 0x00000080 +//#define HOOK_LINETO 0x00000100 +//#define SHAREACCESS_SURFACE 0x00000200 +//#define HOOK_COPYBITS 0x00000400 +//#define REDIRECTION_SURFACE 0x00000800 // ? +//#define HOOK_MOVEPANNING 0x00000800 +//#define HOOK_SYNCHRONIZE 0x00001000 +//#define HOOK_STRETCHBLTROP 0x00002000 +//#define HOOK_SYNCHRONIZEACCESS 0x00004000 +//#define USE_DEVLOCK_SURFACE 0x00004000 +//#define HOOK_TRANSPARENTBLT 0x00008000 +//#define HOOK_ALPHABLEND 0x00010000 +//#define HOOK_GRADIENTFILL 0x00020000 +//#if (NTDDI_VERSION < 0x06000000) +// #define HOOK_FLAGS 0x0003B5FF +//#else +// #define HOOK_FLAGS 0x0003B5EF +//#endif +#define UMPD_SURFACE 0x00040000 +#define MIRROR_SURFACE 0x00080000 +#define DIRECTDRAW_SURFACE 0x00100000 +#define DRIVER_CREATED_SURFACE 0x00200000 +#define ENG_CREATE_DEVICE_SURFACE 0x00400000 +#define DDB_SURFACE 0x00800000 +#define LAZY_DELETE_SURFACE 0x01000000 +#define BANDING_SURFACE 0x02000000 +#define API_BITMAP 0x04000000 +#define PALETTE_SELECT_SET 0x08000000 +#define UNREADABLE_SURFACE 0x10000000 +#define DYNAMIC_MODE_PALETTE 0x20000000 +#define ABORT_SURFACE 0x40000000 +#define PDEV_SURFACE 0x80000000 + + +#define BMF_DONT_FREE 0x100 +#define BMF_RLE_HACK 0x200 + /* Internal interface */ -#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE)) #define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP)) #define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE) #define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP) @@ -64,15 +104,31 @@ typedef struct _SURFACE #define SURFACE_ShareUnlockSurface(pBMObj) \ GDIOBJ_ShareUnlockObjByPtr ((POBJ)pBMObj) -#define SURFACE_LockBitmapBits(pBMObj) ExEnterCriticalRegionAndAcquireFastMutexUnsafe((pBMObj)->BitsLock) -#define SURFACE_UnlockBitmapBits(pBMObj) ExReleaseFastMutexUnsafeAndLeaveCriticalRegion((pBMObj)->BitsLock) - BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody); -BOOL INTERNAL_CALL SURFACE_InitBitsLock(SURFACE *pBMObj); -void INTERNAL_CALL SURFACE_CleanupBitsLock(SURFACE *pBMObj); + +PSURFACE +NTAPI +SURFACE_AllocSurface( + IN ULONG iType, + IN ULONG cx, + IN ULONG cy, + IN ULONG iFormat); + +BOOL +NTAPI +SURFACE_bSetBitmapBits( + IN PSURFACE psurf, + IN USHORT fjBitmap, + IN ULONG ulWidth, + IN PVOID pvBits OPTIONAL); #define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev)) #define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions -INT FASTCALL BitsPerFormat (ULONG Format); ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression); +extern UCHAR gajBitsPerFormat[]; +#define BitsPerFormat(Format) gajBitsPerFormat[Format] + +#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3) +#define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3) + diff --git a/subsystems/win32/win32k/include/win32.h b/subsystems/win32/win32k/include/win32.h index 63dfba76fe2..ed1e645a0a6 100644 --- a/subsystems/win32/win32k/include/win32.h +++ b/subsystems/win32/win32k/include/win32.h @@ -96,6 +96,7 @@ typedef struct _THREADINFO LIST_ENTRY PtiLink; POINT ptLast; + LIST_ENTRY aphkStart[NB_HOOKS]; CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL. /* ReactOS */ LIST_ENTRY WindowListHead; @@ -150,6 +151,8 @@ typedef struct _W32PROCESS LIST_ENTRY GDIBrushAttrFreeList; } W32PROCESS, *PW32PROCESS; +#define CLIBS 32 + typedef struct _PROCESSINFO { W32PROCESS; @@ -158,11 +161,15 @@ typedef struct _PROCESSINFO struct _DESKTOP* rpdeskStartup; PCLS pclsPrivateList; PCLS pclsPublicList; - + DWORD dwhmodLibLoadedMask; + HANDLE ahmodLibLoaded[CLIBS]; + struct _WINSTATION_OBJECT *prpwinsta; + HWINSTA hwinsta; + ACCESS_MASK amwinsta; + DWORD dwHotkey; HMONITOR hMonitor; - + LUID luidSession; USERSTARTUPINFO usi; - ULONG Flags; DWORD dwLayout; DWORD dwRegisteredClasses; /* ReactOS */ diff --git a/subsystems/win32/win32k/include/win32kp.h b/subsystems/win32/win32k/include/win32kp.h index ea3bd61497a..8bcf046195b 100644 --- a/subsystems/win32/win32k/include/win32kp.h +++ b/subsystems/win32/win32k/include/win32kp.h @@ -78,4 +78,6 @@ #include #include #include +#include +#include #include diff --git a/subsystems/win32/win32k/include/window.h b/subsystems/win32/win32k/include/window.h index a91183a0153..39a55b26e00 100644 --- a/subsystems/win32/win32k/include/window.h +++ b/subsystems/win32/win32k/include/window.h @@ -104,7 +104,7 @@ IntShowOwnedPopups( PWND owner, BOOL fShow ); LRESULT FASTCALL IntDefWindowProc( PWND Window, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL Ansi); -VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG); +VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG, DWORD); PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING); WNDPROC FASTCALL IntGetWindowProc(PWND,BOOL); diff --git a/subsystems/win32/win32k/include/xlateobj.h b/subsystems/win32/win32k/include/xlateobj.h index a2ffedb7615..18d2f240012 100644 --- a/subsystems/win32/win32k/include/xlateobj.h +++ b/subsystems/win32/win32k/include/xlateobj.h @@ -45,7 +45,6 @@ DbgCmpXlate(XLATEOBJ *pxlo1, XLATEOBJ *pxlo2); VOID NTAPI EXLATEOBJ_vInitialize(PEXLATEOBJ pexlo, PALETTE *ppalSrc, PALETTE *ppalDst, ULONG, ULONG, ULONG); VOID NTAPI EXLATEOBJ_vInitXlateFromDCs(PEXLATEOBJ pexlo, PDC pdcSrc, PDC pdcDst); -VOID NTAPI EXLATEOBJ_vInitBrushXlate(PEXLATEOBJ pexlo, BRUSH *pbrush, SURFACE *psurf, COLORREF crForegroundClr, COLORREF crBackgroundClr); VOID NTAPI EXLATEOBJ_vInitSrcMonoXlate(PEXLATEOBJ pexlo, PPALETTE ppalDst, ULONG Color0, ULONG Color1); VOID NTAPI EXLATEOBJ_vCleanup(PEXLATEOBJ pexlo); diff --git a/subsystems/win32/win32k/ldr/loader.c b/subsystems/win32/win32k/ldr/loader.c deleted file mode 100644 index bc867c2c4ac..00000000000 --- a/subsystems/win32/win32k/ldr/loader.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* $Id$ - * - */ - -#include - -#define NDEBUG -#include - - -extern LIST_ENTRY GlobalDriverListHead; - - -/* - * Blatantly stolen from ldr/utils.c in ntdll. I can't link ntdll from - * here, though. - */ -NTSTATUS APIENTRY -LdrGetProcedureAddress (IN PVOID BaseAddress, - IN PANSI_STRING Name, - IN ULONG Ordinal, - OUT PVOID *ProcedureAddress) -{ - PIMAGE_EXPORT_DIRECTORY ExportDir; - PUSHORT OrdinalPtr; - PULONG NamePtr; - PULONG AddressPtr; - ULONG i = 0; - - DPRINT("LdrGetProcedureAddress (BaseAddress %x Name %Z Ordinal %lu ProcedureAddress %x)\n", - BaseAddress, Name, Ordinal, ProcedureAddress); - - /* Get the pointer to the export directory */ - ExportDir = (PIMAGE_EXPORT_DIRECTORY) - RtlImageDirectoryEntryToData (BaseAddress, - TRUE, - IMAGE_DIRECTORY_ENTRY_EXPORT, - &i); - - DPRINT("ExportDir %x i %lu\n", ExportDir, i); - - if (!ExportDir || !i || !ProcedureAddress) - { - return STATUS_INVALID_PARAMETER; - } - - AddressPtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfFunctions); - if (Name && Name->Length) - { - /* by name */ - OrdinalPtr = (PUSHORT)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNameOrdinals); - NamePtr = (PULONG)((ULONG_PTR)BaseAddress + (ULONG)ExportDir->AddressOfNames); - for( i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++) - { - if (!strcmp(Name->Buffer, (char*)((ULONG_PTR)BaseAddress + *NamePtr))) - { - *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG)AddressPtr[*OrdinalPtr]); - return STATUS_SUCCESS; - } - } - DPRINT1("LdrGetProcedureAddress: Can't resolve symbol '%Z'\n", Name); - } - else - { - /* by ordinal */ - Ordinal &= 0x0000FFFF; - if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions) - { - *ProcedureAddress = (PVOID)((ULONG_PTR)BaseAddress + (ULONG_PTR)AddressPtr[Ordinal - ExportDir->Base]); - return STATUS_SUCCESS; - } - DPRINT1("LdrGetProcedureAddress: Can't resolve symbol @%d\n", Ordinal); - } - - return STATUS_PROCEDURE_NOT_FOUND; -} - -PVOID APIENTRY -EngFindImageProcAddress(IN HANDLE Module, - IN LPSTR ProcName) -{ - PVOID Function; - NTSTATUS Status; - ANSI_STRING ProcNameString; - unsigned i; - static struct - { - PCSTR ProcName; - PVOID ProcAddress; - } - Win32kExports[] = - { - { "BRUSHOBJ_hGetColorTransform", BRUSHOBJ_hGetColorTransform }, - { "EngAlphaBlend", EngAlphaBlend }, - { "EngClearEvent", EngClearEvent }, - { "EngControlSprites", EngControlSprites }, - { "EngCreateEvent", EngCreateEvent }, - { "EngDeleteEvent", EngDeleteEvent }, - { "EngDeleteFile", EngDeleteFile }, - { "EngDeleteSafeSemaphore", EngDeleteSafeSemaphore }, - { "EngDeleteWnd", EngDeleteWnd }, - { "EngDitherColor", EngDitherColor }, - { "EngGetPrinterDriver", EngGetPrinterDriver }, - { "EngGradientFill", EngGradientFill }, - { "EngHangNotification", EngHangNotification }, - { "EngInitializeSafeSemaphore", EngInitializeSafeSemaphore }, - { "EngLockDirectDrawSurface", EngLockDirectDrawSurface }, - { "EngLpkInstalled", EngLpkInstalled }, - { "EngMapEvent", EngMapEvent }, - { "EngMapFile", EngMapFile }, - { "EngMapFontFileFD", EngMapFontFileFD }, - { "EngModifySurface", EngModifySurface }, - { "EngMovePointer", EngMovePointer }, - { "EngPlgBlt", EngPlgBlt }, - { "EngQueryDeviceAttribute", EngQueryDeviceAttribute }, - { "EngQueryPalette", EngQueryPalette }, - { "EngQuerySystemAttribute", EngQuerySystemAttribute }, - { "EngReadStateEvent", EngReadStateEvent }, - { "EngRestoreFloatingPointState", EngRestoreFloatingPointState }, - { "EngSaveFloatingPointState", EngSaveFloatingPointState }, - { "EngSetEvent", EngSetEvent }, - { "EngSetPointerShape", EngSetPointerShape }, - { "EngSetPointerTag", EngSetPointerTag }, - { "EngStretchBltROP", EngStretchBltROP }, - { "EngTransparentBlt", EngTransparentBlt }, - { "EngUnlockDirectDrawSurface", EngUnlockDirectDrawSurface }, - { "EngUnmapEvent", EngUnmapEvent }, - { "EngUnmapFile", EngUnmapFile }, - { "EngUnmapFontFileFD", EngUnmapFontFileFD }, - { "EngWaitForSingleObject", EngWaitForSingleObject }, - { "FONTOBJ_pfdg", FONTOBJ_pfdg }, - { "FONTOBJ_pjOpenTypeTablePointer", FONTOBJ_pjOpenTypeTablePointer }, - { "FONTOBJ_pQueryGlyphAttrs", FONTOBJ_pQueryGlyphAttrs }, - { "FONTOBJ_pwszFontFilePaths", FONTOBJ_pwszFontFilePaths }, - { "HeapVidMemAllocAligned", HeapVidMemAllocAligned }, - { "HT_Get8BPPMaskPalette", HT_Get8BPPMaskPalette }, - { "STROBJ_bEnumPositionsOnly", STROBJ_bEnumPositionsOnly }, - { "STROBJ_bGetAdvanceWidths", STROBJ_bGetAdvanceWidths }, - { "STROBJ_fxBreakExtra", STROBJ_fxBreakExtra }, - { "STROBJ_fxCharacterExtra", STROBJ_fxCharacterExtra }, - { "VidMemFree", VidMemFree }, - { "XLATEOBJ_hGetColorTransform", XLATEOBJ_hGetColorTransform } - }; - - if (NULL == Module) - { - DPRINT("Looking for win32k export %s\n", ProcName); - for (i = 0; i < sizeof(Win32kExports) / sizeof(Win32kExports[0]); i++) - { - if (0 == strcmp(ProcName, Win32kExports[i].ProcName)) - { - DPRINT("Found it index %u address %p\n", i, Win32kExports[i].ProcName); - return Win32kExports[i].ProcAddress; - } - } - return NULL; - } - RtlInitAnsiString(&ProcNameString, ProcName); - Status = LdrGetProcedureAddress(((PDRIVERS)Module)->BaseAddress, - &ProcNameString, - 0, - &Function); - if (!NT_SUCCESS(Status)) - { - return(NULL); - } - return(Function); -} - - -/* - * @implemented - */ -HANDLE -APIENTRY -EngLoadImage (LPWSTR DriverName) -{ - SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; - PDRIVERS DriverInfo = NULL; - NTSTATUS Status; - - RtlInitUnicodeString(&GdiDriverInfo.DriverName, DriverName); - if( !IsListEmpty(&GlobalDriverListHead) ) - { - PLIST_ENTRY CurrentEntry = GlobalDriverListHead.Flink; - PDRIVERS Current; - /* probably the driver was already loaded, let's try to find it out */ - while( CurrentEntry != &GlobalDriverListHead ) - { - Current = CONTAINING_RECORD(CurrentEntry, DRIVERS, ListEntry); - if( Current && (0 == RtlCompareUnicodeString(&GdiDriverInfo.DriverName, &Current->DriverName, FALSE)) ) { - DriverInfo = Current; - break; - } - CurrentEntry = CurrentEntry->Flink; - }; - } - - if( !DriverInfo ) - { - /* the driver was not loaded before, so let's do that */ - Status = ZwSetSystemInformation(SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); - if (!NT_SUCCESS(Status)) { - DPRINT1("ZwSetSystemInformation failed with Status 0x%lx\n", Status); - } - else { - DriverInfo = ExAllocatePoolWithTag(PagedPool, sizeof(DRIVERS), TAG_DRIVER); - DriverInfo->DriverName.MaximumLength = GdiDriverInfo.DriverName.MaximumLength; - DriverInfo->DriverName.Length = GdiDriverInfo.DriverName.Length; - DriverInfo->DriverName.Buffer = ExAllocatePoolWithTag(PagedPool, GdiDriverInfo.DriverName.MaximumLength, TAG_DRIVER); - RtlCopyUnicodeString(&DriverInfo->DriverName, &GdiDriverInfo.DriverName); - DriverInfo->SectionPointer = GdiDriverInfo.SectionPointer; - DriverInfo->BaseAddress = GdiDriverInfo.ImageAddress; - InsertHeadList(&GlobalDriverListHead, &DriverInfo->ListEntry); - } - } - - return DriverInfo; -} - -VOID -APIENTRY -EngUnloadImage ( IN HANDLE hModule ) -{ - NTSTATUS Status; - PDRIVERS DriverInfo = (PDRIVERS)hModule; - - DPRINT("hModule 0x%x\n", hModule); - - Status = ZwSetSystemInformation(SystemUnloadGdiDriverInformation, - DriverInfo->SectionPointer, sizeof(PVOID)); - - if(!NT_SUCCESS(Status)) - { - DPRINT1("ZwSetSystemInformation failed with status 0x%08X\n", - Status); - } - else - { - ExFreePool(DriverInfo->DriverName.Buffer); - RemoveEntryList(&DriverInfo->ListEntry); - ExFreePool(DriverInfo); - } -} - -/* EOF */ diff --git a/subsystems/win32/win32k/main/dllmain.c b/subsystems/win32/win32k/main/dllmain.c index 0c992c0e72f..b12d96fa8ba 100644 --- a/subsystems/win32/win32k/main/dllmain.c +++ b/subsystems/win32/win32k/main/dllmain.c @@ -34,8 +34,6 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process); PGDI_HANDLE_TABLE GdiHandleTable = NULL; PSECTION_OBJECT GdiTableSection = NULL; -LIST_ENTRY GlobalDriverListHead; - HANDLE GlobalUserHeap = NULL; PSECTION_OBJECT GlobalUserHeapSection = NULL; @@ -175,6 +173,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread, { struct _EPROCESS *Process; PTHREADINFO Win32Thread; + int i; DECLARE_RETURN(NTSTATUS); DPRINT("Enter Win32kThreadCallback\n"); @@ -214,6 +213,10 @@ Win32kThreadCallback(struct _ETHREAD *Thread, InitializeListHead(&Win32Thread->WindowListHead); InitializeListHead(&Win32Thread->W32CallbackListHead); InitializeListHead(&Win32Thread->PtiLink); + for (i = 0; i < NB_HOOKS; i++) + { + InitializeListHead(&Win32Thread->aphkStart[i]); + } /* * inherit the thread desktop and process window station (if not yet inherited) from the process startup @@ -290,6 +293,7 @@ Win32kThreadCallback(struct _ETHREAD *Thread, Win32Thread->TIF_flags |= TIF_INCLEANUP; DceFreeThreadDCE(Win32Thread); HOOK_DestroyThreadHooks(Thread); + EVENT_DestroyThreadEvents(Thread); /* Cleanup timers */ DestroyTimersForThread(Win32Thread); KeSetEvent(Win32Thread->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); @@ -362,6 +366,7 @@ Win32kInitWin32Thread(PETHREAD Thread) return(STATUS_SUCCESS); } +C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE); /* * This definition doesn't work @@ -417,8 +422,19 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } - /* Initialize a list of loaded drivers in Win32 subsystem */ - InitializeListHead(&GlobalDriverListHead); + if (!gpsi) + { + gpsi = UserHeapAlloc(sizeof(SERVERINFO)); + if (gpsi) + { + RtlZeroMemory(gpsi, sizeof(SERVERINFO)); + DPRINT("Global Server Data -> %x\n", gpsi); + } + else + { + ASSERT(FALSE); + } + } if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore(); @@ -429,6 +445,26 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } + /* Initialize default palettes */ + PALETTE_Init(); + + /* Create stock objects, ie. precreated objects commonly + used by win32 applications */ + CreateStockObjects(); + CreateSysColorObjects(); + + InitXlateImpl(); + InitPDEVImpl(); + InitLDEVImpl(); + InitDeviceImpl(); + + Status = InitDcImpl(); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to initialize Device context implementation!\n"); + return STATUS_UNSUCCESSFUL; + } + Status = InitUserImpl(); if (!NT_SUCCESS(Status)) { @@ -520,13 +556,6 @@ DriverEntry ( return(Status); } - Status = InitDcImpl(); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to initialize Device context implementation!\n"); - return STATUS_UNSUCCESSFUL; - } - /* Initialize FreeType library */ if (! InitFontSupport()) { @@ -534,13 +563,6 @@ DriverEntry ( return STATUS_UNSUCCESSFUL; } - InitXlateImpl(); - - /* Create stock objects, ie. precreated objects commonly - used by win32 applications */ - CreateStockObjects(); - CreateSysColorObjects(); - gusLanguageID = IntGdiGetLanguageID(); return STATUS_SUCCESS; diff --git a/subsystems/win32/win32k/misc/copy.c b/subsystems/win32/win32k/misc/copy.c index a40a5be6ffb..6a50d5562dd 100644 --- a/subsystems/win32/win32k/misc/copy.c +++ b/subsystems/win32/win32k/misc/copy.c @@ -5,7 +5,7 @@ NTSTATUS _MmCopyFromCaller( PVOID Target, PVOID Source, UINT Bytes ) { _SEH2_TRY { - /* ProbeForRead(Source,Bytes,1); */ + ProbeForRead(Source,Bytes,1); RtlCopyMemory(Target,Source,Bytes); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) diff --git a/subsystems/win32/win32k/misc/driver.c b/subsystems/win32/win32k/misc/driver.c index 8b25b137b33..8b137891791 100644 --- a/subsystems/win32/win32k/misc/driver.c +++ b/subsystems/win32/win32k/misc/driver.c @@ -1,621 +1 @@ -/* - * ReactOS W32 Subsystem - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -/* $Id$ - * - * GDI Driver support routines - * (mostly swiped from Wine) - * - */ -#include - -#define NDEBUG -#include - -/* #define TRACE_DRV_CALLS to get a log of all calls into the display driver. */ -#undef TRACE_DRV_CALLS - - -typedef struct _GRAPHICS_DRIVER -{ - PWSTR Name; - PFN_DrvEnableDriver EnableDriver; - int ReferenceCount; - struct _GRAPHICS_DRIVER *Next; -} GRAPHICS_DRIVER, *PGRAPHICS_DRIVER; - -static PGRAPHICS_DRIVER DriverList; -static PGRAPHICS_DRIVER GenericDriver = NULL; - -BOOL DRIVER_RegisterDriver(LPCWSTR Name, PFN_DrvEnableDriver EnableDriver) -{ - PGRAPHICS_DRIVER Driver; - - DPRINT( "DRIVER_RegisterDriver( Name: %S )\n", Name ); - - if (GenericDriver != NULL) - { - return FALSE; - } - Driver = ExAllocatePoolWithTag(PagedPool, sizeof(*Driver), TAG_DRIVER); - if (!Driver) return FALSE; - Driver->ReferenceCount = 0; - Driver->EnableDriver = EnableDriver; - if (Name) - { - Driver->Name = ExAllocatePoolWithTag(PagedPool, - (wcslen(Name) + 1) * sizeof(WCHAR), - TAG_DRIVER); - if (Driver->Name == NULL) - { - DPRINT1("Out of memory\n"); - ExFreePoolWithTag(Driver, TAG_DRIVER); - return FALSE; - } - - wcscpy(Driver->Name, Name); - Driver->Next = DriverList; - DriverList = Driver; - return TRUE; - } - - GenericDriver = Driver; - return TRUE; -} - -PFN_DrvEnableDriver DRIVER_FindExistingDDIDriver(LPCWSTR Name) -{ - GRAPHICS_DRIVER *Driver = DriverList; - while (Driver && Name) - { - if (!_wcsicmp(Driver->Name, Name)) - { - return Driver->EnableDriver; - } - Driver = Driver->Next; - } - - return NULL; -} - -PFN_DrvEnableDriver DRIVER_FindDDIDriver(LPCWSTR Name) -{ - static WCHAR DefaultPath[] = L"\\SystemRoot\\System32\\"; - static WCHAR DefaultExtension[] = L".DLL"; - PFN_DrvEnableDriver ExistingDriver; - SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo; - NTSTATUS Status; - LPWSTR FullName; - LPCWSTR p; - BOOL PathSeparatorFound; - BOOL DotFound; - UINT Size; - - DotFound = FALSE; - PathSeparatorFound = FALSE; - p = Name; - while (L'\0' != *p) - { - if (L'\\' == *p || L'/' == *p) - { - PathSeparatorFound = TRUE; - DotFound = FALSE; - } - else if (L'.' == *p) - { - DotFound = TRUE; - } - p++; - } - - Size = (wcslen(Name) + 1) * sizeof(WCHAR); - if (! PathSeparatorFound) - { - Size += sizeof(DefaultPath) - sizeof(WCHAR); - } - if (! DotFound) - { - Size += sizeof(DefaultExtension) - sizeof(WCHAR); - } - FullName = ExAllocatePoolWithTag(PagedPool, Size, TAG_DRIVER); - if (NULL == FullName) - { - DPRINT1("Out of memory\n"); - return NULL; - } - if (PathSeparatorFound) - { - FullName[0] = L'\0'; - } - else - { - wcscpy(FullName, DefaultPath); - } - wcscat(FullName, Name); - if (! DotFound) - { - wcscat(FullName, DefaultExtension); - } - - /* First see if the driver hasn't already been loaded */ - ExistingDriver = DRIVER_FindExistingDDIDriver(FullName); - if (ExistingDriver) - { - ExFreePoolWithTag(FullName, TAG_DRIVER); - return ExistingDriver; - } - - /* If not, then load it */ - RtlInitUnicodeString (&GdiDriverInfo.DriverName, FullName); - Status = ZwSetSystemInformation (SystemLoadGdiDriverInformation, &GdiDriverInfo, sizeof(SYSTEM_GDI_DRIVER_INFORMATION)); - - if (!NT_SUCCESS(Status)) - { - ExFreePoolWithTag(FullName, TAG_DRIVER); - return NULL; - } - - DRIVER_RegisterDriver( L"DISPLAY", GdiDriverInfo.EntryPoint); - DRIVER_RegisterDriver( FullName, GdiDriverInfo.EntryPoint); - ExFreePoolWithTag(FullName, TAG_DRIVER); - return (PFN_DrvEnableDriver)GdiDriverInfo.EntryPoint; -} - -#define BEGIN_FUNCTION_MAP() \ - ULONG i; \ - for (i = 0; i < DED->c; i++) \ - { \ - switch(DED->pdrvfn[i].iFunc) \ - { - -#define END_FUNCTION_MAP() \ - default: \ - DPRINT1("Unsupported DDI function 0x%x\n", DED->pdrvfn[i].iFunc); \ - break; \ - } \ - } - -#ifdef TRACE_DRV_CALLS - -typedef struct _TRACEDRVINFO - { - unsigned Index; - char *Name; - PVOID DrvRoutine; - } -TRACEDRVINFO, *PTRACEDRVINFO; - -__asm__( -" .text\n" -"TraceDrv:\n" -" pushl %eax\n" -" call _FindTraceInfo\n" -" add $4,%esp\n" -" pushl %eax\n" -" pushl 4(%eax)\n" -" call _DbgPrint\n" -" addl $4,%esp\n" -" popl %eax\n" -" mov 8(%eax),%eax\n" -" jmp *%eax\n" -); - -#define TRACEDRV_ROUTINE(function) \ -unsigned TraceDrvIndex##function = INDEX_Drv##function; \ -__asm__ ( \ -" .text\n" \ -"_Trace" #function ":\n" \ -" movl _TraceDrvIndex" #function ",%eax\n" \ -" jmp TraceDrv\n" \ -); \ -extern PVOID Trace##function; - -TRACEDRV_ROUTINE(EnablePDEV) -TRACEDRV_ROUTINE(CompletePDEV) -TRACEDRV_ROUTINE(DisablePDEV) -TRACEDRV_ROUTINE(EnableSurface) -TRACEDRV_ROUTINE(DisableSurface) -TRACEDRV_ROUTINE(AssertMode) -TRACEDRV_ROUTINE(Offset) -TRACEDRV_ROUTINE(ResetPDEV) -TRACEDRV_ROUTINE(DisableDriver) -TRACEDRV_ROUTINE(CreateDeviceBitmap) -TRACEDRV_ROUTINE(DeleteDeviceBitmap) -TRACEDRV_ROUTINE(RealizeBrush) -TRACEDRV_ROUTINE(DitherColor) -TRACEDRV_ROUTINE(StrokePath) -TRACEDRV_ROUTINE(FillPath) -TRACEDRV_ROUTINE(StrokeAndFillPath) -TRACEDRV_ROUTINE(Paint) -TRACEDRV_ROUTINE(BitBlt) -TRACEDRV_ROUTINE(TransparentBlt) -TRACEDRV_ROUTINE(CopyBits) -TRACEDRV_ROUTINE(StretchBlt) -TRACEDRV_ROUTINE(StretchBltROP) -TRACEDRV_ROUTINE(SetPalette) -TRACEDRV_ROUTINE(TextOut) -TRACEDRV_ROUTINE(Escape) -TRACEDRV_ROUTINE(DrawEscape) -TRACEDRV_ROUTINE(QueryFont) -TRACEDRV_ROUTINE(QueryFontTree) -TRACEDRV_ROUTINE(QueryFontData) -TRACEDRV_ROUTINE(SetPointerShape) -TRACEDRV_ROUTINE(MovePointer) -TRACEDRV_ROUTINE(LineTo) -TRACEDRV_ROUTINE(SendPage) -TRACEDRV_ROUTINE(StartPage) -TRACEDRV_ROUTINE(EndDoc) -TRACEDRV_ROUTINE(StartDoc) -TRACEDRV_ROUTINE(GetGlyphMode) -TRACEDRV_ROUTINE(Synchronize) -TRACEDRV_ROUTINE(SaveScreenBits) -TRACEDRV_ROUTINE(GetModes) -TRACEDRV_ROUTINE(Free) -TRACEDRV_ROUTINE(DestroyFont) -TRACEDRV_ROUTINE(QueryFontCaps) -TRACEDRV_ROUTINE(LoadFontFile) -TRACEDRV_ROUTINE(UnloadFontFile) -TRACEDRV_ROUTINE(FontManagement) -TRACEDRV_ROUTINE(QueryTrueTypeTable) -TRACEDRV_ROUTINE(QueryTrueTypeOutline) -TRACEDRV_ROUTINE(GetTrueTypeFile) -TRACEDRV_ROUTINE(QueryFontFile) -TRACEDRV_ROUTINE(QueryAdvanceWidths) -TRACEDRV_ROUTINE(SetPixelFormat) -TRACEDRV_ROUTINE(DescribePixelFormat) -TRACEDRV_ROUTINE(SwapBuffers) -TRACEDRV_ROUTINE(StartBanding) -TRACEDRV_ROUTINE(NextBand) -TRACEDRV_ROUTINE(GetDirectDrawInfo) -TRACEDRV_ROUTINE(EnableDirectDraw) -TRACEDRV_ROUTINE(DisableDirectDraw) -TRACEDRV_ROUTINE(QuerySpoolType) -TRACEDRV_ROUTINE(IcmSetDeviceGammaRamp) -TRACEDRV_ROUTINE(GradientFill) -TRACEDRV_ROUTINE(SynchronizeSurface) -TRACEDRV_ROUTINE(AlphaBlend) - -#define TRACEDRVINFO_ENTRY(function) \ - { INDEX_Drv##function, "Drv" #function "\n", NULL } -static TRACEDRVINFO TraceDrvInfo[] = - { - TRACEDRVINFO_ENTRY(EnablePDEV), - TRACEDRVINFO_ENTRY(CompletePDEV), - TRACEDRVINFO_ENTRY(DisablePDEV), - TRACEDRVINFO_ENTRY(EnableSurface), - TRACEDRVINFO_ENTRY(DisableSurface), - TRACEDRVINFO_ENTRY(AssertMode), - TRACEDRVINFO_ENTRY(Offset), - TRACEDRVINFO_ENTRY(ResetPDEV), - TRACEDRVINFO_ENTRY(DisableDriver), - TRACEDRVINFO_ENTRY(CreateDeviceBitmap), - TRACEDRVINFO_ENTRY(DeleteDeviceBitmap), - TRACEDRVINFO_ENTRY(RealizeBrush), - TRACEDRVINFO_ENTRY(DitherColor), - TRACEDRVINFO_ENTRY(StrokePath), - TRACEDRVINFO_ENTRY(FillPath), - TRACEDRVINFO_ENTRY(StrokeAndFillPath), - TRACEDRVINFO_ENTRY(Paint), - TRACEDRVINFO_ENTRY(BitBlt), - TRACEDRVINFO_ENTRY(TransparentBlt), - TRACEDRVINFO_ENTRY(CopyBits), - TRACEDRVINFO_ENTRY(StretchBlt), - TRACEDRVINFO_ENTRY(StretchBltROP), - TRACEDRVINFO_ENTRY(SetPalette), - TRACEDRVINFO_ENTRY(TextOut), - TRACEDRVINFO_ENTRY(Escape), - TRACEDRVINFO_ENTRY(DrawEscape), - TRACEDRVINFO_ENTRY(QueryFont), - TRACEDRVINFO_ENTRY(QueryFontTree), - TRACEDRVINFO_ENTRY(QueryFontData), - TRACEDRVINFO_ENTRY(SetPointerShape), - TRACEDRVINFO_ENTRY(MovePointer), - TRACEDRVINFO_ENTRY(LineTo), - TRACEDRVINFO_ENTRY(SendPage), - TRACEDRVINFO_ENTRY(StartPage), - TRACEDRVINFO_ENTRY(EndDoc), - TRACEDRVINFO_ENTRY(StartDoc), - TRACEDRVINFO_ENTRY(GetGlyphMode), - TRACEDRVINFO_ENTRY(Synchronize), - TRACEDRVINFO_ENTRY(SaveScreenBits), - TRACEDRVINFO_ENTRY(GetModes), - TRACEDRVINFO_ENTRY(Free), - TRACEDRVINFO_ENTRY(DestroyFont), - TRACEDRVINFO_ENTRY(QueryFontCaps), - TRACEDRVINFO_ENTRY(LoadFontFile), - TRACEDRVINFO_ENTRY(UnloadFontFile), - TRACEDRVINFO_ENTRY(FontManagement), - TRACEDRVINFO_ENTRY(QueryTrueTypeTable), - TRACEDRVINFO_ENTRY(QueryTrueTypeOutline), - TRACEDRVINFO_ENTRY(GetTrueTypeFile), - TRACEDRVINFO_ENTRY(QueryFontFile), - TRACEDRVINFO_ENTRY(QueryAdvanceWidths), - TRACEDRVINFO_ENTRY(SetPixelFormat), - TRACEDRVINFO_ENTRY(DescribePixelFormat), - TRACEDRVINFO_ENTRY(SwapBuffers), - TRACEDRVINFO_ENTRY(StartBanding), - TRACEDRVINFO_ENTRY(NextBand), - TRACEDRVINFO_ENTRY(GetDirectDrawInfo), - TRACEDRVINFO_ENTRY(EnableDirectDraw), - TRACEDRVINFO_ENTRY(DisableDirectDraw), - TRACEDRVINFO_ENTRY(QuerySpoolType), - TRACEDRVINFO_ENTRY(IcmSetDeviceGammaRamp), - TRACEDRVINFO_ENTRY(GradientFill), - TRACEDRVINFO_ENTRY(SynchronizeSurface), - TRACEDRVINFO_ENTRY(AlphaBlend) - }; - -PTRACEDRVINFO -FindTraceInfo(unsigned Index) -{ - unsigned i; - - for (i = 0; i < sizeof(TraceDrvInfo) / sizeof(TRACEDRVINFO); i++) - { - if (TraceDrvInfo[i].Index == Index) - { - return TraceDrvInfo + i; - } - } - - return NULL; -} - -#define DRIVER_FUNCTION(function) \ - case INDEX_Drv##function: \ - FindTraceInfo(INDEX_Drv##function)->DrvRoutine = DED->pdrvfn[i].pfn; \ - *(PVOID*)&DF->function = &Trace##function; \ - break -#else -#define DRIVER_FUNCTION(function) \ - case INDEX_Drv##function: \ - *(PVOID*)&DF->function = DED->pdrvfn[i].pfn; \ - break -#endif - -BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED, - PDRIVER_FUNCTIONS DF) -{ - BEGIN_FUNCTION_MAP(); - DRIVER_FUNCTION(EnablePDEV); - DRIVER_FUNCTION(CompletePDEV); - DRIVER_FUNCTION(DisablePDEV); - DRIVER_FUNCTION(EnableSurface); - DRIVER_FUNCTION(DisableSurface); - DRIVER_FUNCTION(AssertMode); - DRIVER_FUNCTION(Offset); - DRIVER_FUNCTION(ResetPDEV); - DRIVER_FUNCTION(DisableDriver); - DRIVER_FUNCTION(Unknown1); - DRIVER_FUNCTION(CreateDeviceBitmap); - DRIVER_FUNCTION(DeleteDeviceBitmap); - DRIVER_FUNCTION(RealizeBrush); - DRIVER_FUNCTION(DitherColor); - DRIVER_FUNCTION(StrokePath); - DRIVER_FUNCTION(FillPath); - DRIVER_FUNCTION(StrokeAndFillPath); - DRIVER_FUNCTION(Paint); - DRIVER_FUNCTION(BitBlt); - DRIVER_FUNCTION(CopyBits); - DRIVER_FUNCTION(StretchBlt); - DRIVER_FUNCTION(Unknown2); - DRIVER_FUNCTION(SetPalette); - DRIVER_FUNCTION(TextOut); - DRIVER_FUNCTION(Escape); - DRIVER_FUNCTION(DrawEscape); - DRIVER_FUNCTION(QueryFont); - DRIVER_FUNCTION(QueryFontTree); - DRIVER_FUNCTION(QueryFontData); - DRIVER_FUNCTION(SetPointerShape); - DRIVER_FUNCTION(MovePointer); - DRIVER_FUNCTION(LineTo); - DRIVER_FUNCTION(SendPage); - DRIVER_FUNCTION(StartPage); - DRIVER_FUNCTION(EndDoc); - DRIVER_FUNCTION(StartDoc); - DRIVER_FUNCTION(Unknown3); - DRIVER_FUNCTION(GetGlyphMode); - DRIVER_FUNCTION(Synchronize); - DRIVER_FUNCTION(Unknown4); - DRIVER_FUNCTION(SaveScreenBits); - DRIVER_FUNCTION(GetModes); - DRIVER_FUNCTION(Free); - DRIVER_FUNCTION(DestroyFont); - DRIVER_FUNCTION(QueryFontCaps); - DRIVER_FUNCTION(LoadFontFile); - DRIVER_FUNCTION(UnloadFontFile); - DRIVER_FUNCTION(FontManagement); - DRIVER_FUNCTION(QueryTrueTypeTable); - DRIVER_FUNCTION(QueryTrueTypeOutline); - DRIVER_FUNCTION(GetTrueTypeFile); - DRIVER_FUNCTION(QueryFontFile); - DRIVER_FUNCTION(QueryAdvanceWidths); - DRIVER_FUNCTION(SetPixelFormat); - DRIVER_FUNCTION(DescribePixelFormat); - DRIVER_FUNCTION(SwapBuffers); - DRIVER_FUNCTION(StartBanding); - DRIVER_FUNCTION(NextBand); - DRIVER_FUNCTION(GetDirectDrawInfo); - DRIVER_FUNCTION(EnableDirectDraw); - DRIVER_FUNCTION(DisableDirectDraw); - DRIVER_FUNCTION(QuerySpoolType); - DRIVER_FUNCTION(Unknown5); - DRIVER_FUNCTION(IcmCreateColorTransform); - DRIVER_FUNCTION(IcmDeleteColorTransform); - DRIVER_FUNCTION(IcmCheckBitmapBits); - DRIVER_FUNCTION(IcmSetDeviceGammaRamp); - DRIVER_FUNCTION(GradientFill); - DRIVER_FUNCTION(StretchBltROP); - DRIVER_FUNCTION(PlgBlt); - DRIVER_FUNCTION(AlphaBlend); - DRIVER_FUNCTION(SynthesizeFont); - DRIVER_FUNCTION(GetSynthesizedFontFiles); - DRIVER_FUNCTION(TransparentBlt); - DRIVER_FUNCTION(QueryPerBandInfo); - DRIVER_FUNCTION(QueryDeviceSupport); - DRIVER_FUNCTION(Reserved1); - DRIVER_FUNCTION(Reserved2); - DRIVER_FUNCTION(Reserved3); - DRIVER_FUNCTION(Reserved4); - DRIVER_FUNCTION(Reserved5); - DRIVER_FUNCTION(Reserved6); - DRIVER_FUNCTION(Reserved7); - DRIVER_FUNCTION(Reserved8); - DRIVER_FUNCTION(DeriveSurface); - DRIVER_FUNCTION(QueryGlyphAttrs); - DRIVER_FUNCTION(Notify); - DRIVER_FUNCTION(SynchronizeSurface); - DRIVER_FUNCTION(ResetDevice); - DRIVER_FUNCTION(Reserved9); - DRIVER_FUNCTION(Reserved10); - DRIVER_FUNCTION(Reserved11); - END_FUNCTION_MAP(); - - return TRUE; -} - -typedef LONG VP_STATUS; -typedef VP_STATUS (APIENTRY *PMP_DRIVERENTRY)(PVOID, PVOID); - -PFILE_OBJECT DRIVER_FindMPDriver(ULONG DisplayNumber) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - WCHAR DeviceNameBuffer[20]; - UNICODE_STRING DeviceName; - IO_STATUS_BLOCK Iosb; - HANDLE DisplayHandle; - NTSTATUS Status; - PFILE_OBJECT VideoFileObject; - - swprintf(DeviceNameBuffer, L"\\??\\DISPLAY%d", DisplayNumber + 1); - RtlInitUnicodeString(&DeviceName, DeviceNameBuffer); - InitializeObjectAttributes(&ObjectAttributes, - &DeviceName, - 0, - NULL, - NULL); - Status = ZwOpenFile(&DisplayHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &Iosb, - 0, - FILE_SYNCHRONOUS_IO_ALERT); - if (NT_SUCCESS(Status)) - { - Status = ObReferenceObjectByHandle(DisplayHandle, - FILE_READ_DATA | FILE_WRITE_DATA, - IoFileObjectType, - KernelMode, - (PVOID *)&VideoFileObject, - NULL); - ZwClose(DisplayHandle); - } - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to connect to miniport (Status %lx)\n", Status); - DPRINT1("Perhaps the miniport wasn't loaded?\n"); - return(NULL); - } - - return VideoFileObject; -} - - -BOOL DRIVER_UnregisterDriver(LPCWSTR Name) -{ - PGRAPHICS_DRIVER Driver = NULL; - - if (Name) - { - if (DriverList != NULL) - { - if (!_wcsicmp(DriverList->Name, Name)) - { - Driver = DriverList; - DriverList = DriverList->Next; - } - else - { - Driver = DriverList; - while (Driver->Next && _wcsicmp(Driver->Name, Name)) - { - Driver = Driver->Next; - } - } - } - } - else - { - if (GenericDriver != NULL) - { - Driver = GenericDriver; - GenericDriver = NULL; - } - } - - if (Driver != NULL) - { - ExFreePoolWithTag(Driver->Name, TAG_DRIVER); - ExFreePoolWithTag(Driver, TAG_DRIVER); - - return TRUE; - } - else - { - return FALSE; - } -} - -INT DRIVER_ReferenceDriver (LPCWSTR Name) -{ - GRAPHICS_DRIVER *Driver = DriverList; - - while (Driver && Name) - { - DPRINT( "Comparing %S to %S\n", Driver->Name, Name ); - if (!_wcsicmp( Driver->Name, Name)) - { - return ++Driver->ReferenceCount; - } - Driver = Driver->Next; - } - DPRINT( "Driver %S not found to reference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - ASSERT( GenericDriver != 0 ); - return ++GenericDriver->ReferenceCount; -} - -INT DRIVER_UnreferenceDriver (LPCWSTR Name) -{ - GRAPHICS_DRIVER *Driver = DriverList; - - while (Driver && Name) - { - DPRINT( "Comparing %S to %S\n", Driver->Name, Name ); - if (!_wcsicmp( Driver->Name, Name)) - { - return --Driver->ReferenceCount; - } - Driver = Driver->Next; - } - DPRINT( "Driver '%S' not found to dereference, generic count: %d\n", Name, GenericDriver->ReferenceCount ); - ASSERT( GenericDriver != 0 ); - return --GenericDriver->ReferenceCount; -} -/* EOF */ diff --git a/subsystems/win32/win32k/misc/file.c b/subsystems/win32/win32k/misc/file.c index 1e2281aa517..856de99015d 100644 --- a/subsystems/win32/win32k/misc/file.c +++ b/subsystems/win32/win32k/misc/file.c @@ -149,213 +149,98 @@ W32kMapViewOfSection( return pvBase; } -typedef struct tagBITMAPV5INFO -{ - BITMAPV5HEADER bmiHeader; - RGBQUAD bmiColors[256]; -} BITMAPV5INFO, *PBITMAPV5INFO; - -// FIXME: this should go to dibobj.c -NTSTATUS -ProbeAndConvertBitmapInfo( - OUT BITMAPV5HEADER *pbmhDst, - OUT RGBQUAD *pbmiColorsDst, - ULONG cColors, - IN PBITMAPINFO pbmiUnsafe) -{ - DWORD dwSize; - RGBQUAD *pbmiColors; - ULONG ulWidthBytes; - - /* Get the size and probe */ - ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1); - dwSize = pbmiUnsafe->bmiHeader.biSize; - ProbeForRead(pbmiUnsafe, dwSize, 1); - - /* Check the size */ - // FIXME: are intermediate sizes allowed? As what are they interpreted? - // make sure we don't use a too big dwSize later - if (dwSize != sizeof(BITMAPCOREHEADER) && - dwSize != sizeof(BITMAPINFOHEADER) && - dwSize != sizeof(BITMAPV4HEADER) && - dwSize != sizeof(BITMAPV5HEADER)) - { - return STATUS_INVALID_PARAMETER; - } - - pbmiColors = (RGBQUAD*)((PCHAR)pbmiUnsafe + dwSize); - - pbmhDst->bV5Size = sizeof(BITMAPV5HEADER); - - if (dwSize == sizeof(BITMAPCOREHEADER)) - { - PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe; - - /* Manually copy the fields that are present */ - pbmhDst->bV5Width = pbch->bcWidth; - pbmhDst->bV5Height = pbch->bcHeight; - pbmhDst->bV5Planes = pbch->bcPlanes; - pbmhDst->bV5BitCount = pbch->bcBitCount; - - /* Set some default values */ - pbmhDst->bV5Compression = BI_RGB; - pbmhDst->bV5SizeImage = 0; - pbmhDst->bV5XPelsPerMeter = 72; - pbmhDst->bV5YPelsPerMeter = 72; - pbmhDst->bV5ClrUsed = 0; - pbmhDst->bV5ClrImportant = 0; - } - else - { - /* Copy valid fields */ - memcpy(pbmhDst, pbmiUnsafe, dwSize); - - /* Zero out the rest of the V5 header */ - memset((char*)pbmhDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize); - } - - - if (dwSize < sizeof(BITMAPV4HEADER)) - { - if (pbmhDst->bV5Compression == BI_BITFIELDS) - { - DWORD *pMasks = (DWORD*)pbmiColors; - pbmhDst->bV5RedMask = pMasks[0]; - pbmhDst->bV5GreenMask = pMasks[1]; - pbmhDst->bV5BlueMask = pMasks[2]; - pbmhDst->bV5AlphaMask = 0; - pbmhDst->bV5ClrUsed = 0; - } - -// pbmhDst->bV5CSType; -// pbmhDst->bV5Endpoints; -// pbmhDst->bV5GammaRed; -// pbmhDst->bV5GammaGreen; -// pbmhDst->bV5GammaBlue; - } - - if (dwSize < sizeof(BITMAPV5HEADER)) - { -// pbmhDst->bV5Intent; -// pbmhDst->bV5ProfileData; -// pbmhDst->bV5ProfileSize; -// pbmhDst->bV5Reserved; - } - - ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes * - pbmhDst->bV5BitCount + 31) & ~31) / 8; - - if (pbmhDst->bV5SizeImage == 0) - pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height); - - if (pbmhDst->bV5ClrUsed == 0) - pbmhDst->bV5ClrUsed = pbmhDst->bV5BitCount == 1 ? 2 : - (pbmhDst->bV5BitCount == 4 ? 16 : - (pbmhDst->bV5BitCount == 8 ? 256 : 0)); - - if (pbmhDst->bV5Planes != 1) - { - return STATUS_INVALID_PARAMETER; - } - - if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 && - pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 && - pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 && - pbmhDst->bV5BitCount != 32) - { - DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount); - return STATUS_INVALID_PARAMETER; - } - - if ((pbmhDst->bV5BitCount == 0 && - pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG)) - { - DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression); - return STATUS_INVALID_PARAMETER; - } - - if (pbmhDst->bV5Compression == BI_BITFIELDS && - pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32) - { - DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount); - return STATUS_INVALID_PARAMETER; - } - - /* Copy Colors */ - cColors = min(cColors, pbmhDst->bV5ClrUsed); - memcpy(pbmiColorsDst, pbmiColors, cColors * sizeof(RGBQUAD)); - - return STATUS_SUCCESS; -} - - HBITMAP NTAPI UserLoadImage(PCWSTR pwszName) { - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; HANDLE hFile, hSection; BITMAPFILEHEADER *pbmfh; LPBITMAPINFO pbmi; - ULONG cjInfoSize; PVOID pvBits; HBITMAP hbmp = 0; - BITMAPV5INFO bmiLocal; + + DPRINT("Enter UserLoadImage(%ls)\n", pwszName); /* Open the file */ hFile = W32kOpenFile(pwszName, FILE_READ_DATA); - if (hFile == INVALID_HANDLE_VALUE) - return NULL; + if (!hFile) + { + return NULL; + } /* Create a section */ hSection = W32kCreateFileSection(hFile, SEC_COMMIT, PAGE_READONLY, 0); ZwClose(hFile); if (!hSection) - return NULL; + { + return NULL; + } /* Map the section */ pbmfh = W32kMapViewOfSection(hSection, PAGE_READONLY, 0); ZwClose(hSection); if (!pbmfh) - return NULL; + { + return NULL; + } /* Get a pointer to the BITMAPINFO */ pbmi = (LPBITMAPINFO)(pbmfh + 1); - /* Create a normalized local BITMAPINFO */ - _SEH2_TRY - { - Status = ProbeAndConvertBitmapInfo(&bmiLocal.bmiHeader, - bmiLocal.bmiColors, - 256, - pbmi); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END + _SEH2_TRY + { + ProbeForRead(&pbmfh->bfSize, sizeof(DWORD), 1); + ProbeForRead(pbmfh, pbmfh->bfSize, 1); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END - if (NT_SUCCESS(Status)) + if(!NT_SUCCESS(Status)) + { + DPRINT1("Bad File?\n"); + goto leave; + } + + if (pbmfh->bfType == 0x4D42 /* 'BM' */) { - cjInfoSize = bmiLocal.bmiHeader.bV5Size + - bmiLocal.bmiHeader.bV5ClrUsed * sizeof(RGBQUAD); - pvBits = (PVOID)((PCHAR)pbmi + cjInfoSize); + /* Could be BITMAPCOREINFO */ + BITMAPINFO* pConvertedInfo; + HDC hdc; - // FIXME: use Gre... so that the BITMAPINFO doesn't get probed - hbmp = NtGdiCreateDIBitmapInternal(NULL, - bmiLocal.bmiHeader.bV5Width, - bmiLocal.bmiHeader.bV5Height, - CBM_INIT, - pvBits, - pbmi, - DIB_RGB_COLORS, - bmiLocal.bmiHeader.bV5Size, - bmiLocal.bmiHeader.bV5SizeImage, - 0, - 0); + pvBits = (PVOID)((PCHAR)pbmfh + pbmfh->bfOffBits); + + pConvertedInfo = DIB_ConvertBitmapInfo(pbmi, DIB_RGB_COLORS); + if(!pConvertedInfo) + { + DPRINT1("Unable to convert the bitmap Info\n"); + goto leave; + } + + hdc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE); + + hbmp = GreCreateDIBitmapInternal(hdc, + pConvertedInfo->bmiHeader.biWidth, + pConvertedInfo->bmiHeader.biHeight, + CBM_INIT, + pvBits, + pConvertedInfo, + DIB_RGB_COLORS, + 0, + 0); + + NtGdiDeleteObjectApp(hdc); + DIB_FreeConvertedBitmapInfo(pConvertedInfo, pbmi); } + else + { + DPRINT1("Unknown file type!\n"); + } +leave: /* Unmap our section, we don't need it anymore */ ZwUnmapViewOfSection(NtCurrentProcess(), pbmfh); diff --git a/subsystems/win32/win32k/misc/registry.c b/subsystems/win32/win32k/misc/registry.c index fcaefabb62f..86bac347f2f 100644 --- a/subsystems/win32/win32k/misc/registry.c +++ b/subsystems/win32/win32k/misc/registry.c @@ -11,6 +11,134 @@ #define NDEBUG #include +NTSTATUS +NTAPI +RegOpenKey( + LPCWSTR pwszKeyName, + PHKEY phkey) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING ustrKeyName; + HKEY hkey; + + /* Initialize the key name */ + RtlInitUnicodeString(&ustrKeyName, pwszKeyName); + + /* Initialize object attributes */ + InitializeObjectAttributes(&ObjectAttributes, + &ustrKeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + /* Open the key */ + Status = ZwOpenKey(&hkey, KEY_READ, &ObjectAttributes); + if (NT_SUCCESS(Status)) + { + *phkey = hkey; + } + + return Status; +} + +NTSTATUS +NTAPI +RegQueryValue( + IN HKEY hkey, + IN PCWSTR pwszValueName, + IN ULONG ulType, + OUT PVOID pvData, + IN OUT PULONG pcbValue) +{ + NTSTATUS Status; + UNICODE_STRING ustrValueName; + BYTE ajBuffer[100]; + PKEY_VALUE_PARTIAL_INFORMATION pInfo; + ULONG cbInfoSize, cbDataSize; + + /* Check if the local buffer is sufficient */ + cbInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + *pcbValue; + if (cbInfoSize <= sizeof(ajBuffer)) + { + pInfo = (PVOID)ajBuffer; + } + else + { + /* It's not, allocate a sufficient buffer */ + pInfo = ExAllocatePoolWithTag(PagedPool, cbInfoSize, TAG_TEMP); + if (!pInfo) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + } + + /* Query the value */ + RtlInitUnicodeString(&ustrValueName, pwszValueName); + Status = ZwQueryValueKey(hkey, + &ustrValueName, + KeyValuePartialInformation, + (PVOID)pInfo, + cbInfoSize, + &cbInfoSize); + + cbDataSize = cbInfoSize - FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data); + + if (NT_SUCCESS(Status)) + { + /* Did we get the right type */ + if (pInfo->Type == ulType) + { + /* Copy the contents to the caller */ + RtlCopyMemory(pvData, pInfo->Data, min(*pcbValue, cbDataSize)); + } + else + Status = STATUS_OBJECT_TYPE_MISMATCH; + } + + /* Return the data size to the caller */ + *pcbValue = cbDataSize; + + /* Cleanup */ + if (pInfo != (PVOID)ajBuffer) + ExFreePoolWithTag(pInfo, TAG_TEMP); + + return Status; + +} + +VOID +NTAPI +RegWriteSZ(HKEY hkey, PWSTR pwszValue, PWSTR pwszData) +{ + UNICODE_STRING ustrValue; + UNICODE_STRING ustrData; + + RtlInitUnicodeString(&ustrValue, pwszValue); + RtlInitUnicodeString(&ustrData, pwszData); + ZwSetValueKey(hkey, &ustrValue, 0, REG_SZ, &ustrData, ustrData.Length + sizeof(WCHAR)); +} + +VOID +NTAPI +RegWriteDWORD(HKEY hkey, PWSTR pwszValue, DWORD dwData) +{ + UNICODE_STRING ustrValue; + + RtlInitUnicodeString(&ustrValue, pwszValue); + ZwSetValueKey(hkey, &ustrValue, 0, REG_DWORD, &dwData, sizeof(DWORD)); +} + +BOOL +NTAPI +RegReadDWORD(HKEY hkey, PWSTR pwszValue, PDWORD pdwData) +{ + NTSTATUS Status; + ULONG cbSize = sizeof(DWORD); + Status = RegQueryValue(hkey, pwszValue, REG_DWORD, pdwData, &cbSize); + return NT_SUCCESS(Status); +} + BOOL NTAPI RegReadUserSetting( @@ -163,7 +291,8 @@ RegWriteUserSetting( Status = RtlAppendUnicodeToString(&usKeyName, pwszKeyName); if (!NT_SUCCESS(Status)) { - DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", Status, usKeyName.Length, usKeyName.MaximumLength); + DPRINT1("RtlAppendUnicodeToString failed with Status=%lx, buf:%d,%d\n", + Status, usKeyName.Length, usKeyName.MaximumLength); return FALSE; } diff --git a/subsystems/win32/win32k/ntddraw/dxeng.c b/subsystems/win32/win32k/ntddraw/dxeng.c index 58413a584ff..135c048b07b 100644 --- a/subsystems/win32/win32k/ntddraw/dxeng.c +++ b/subsystems/win32/win32k/ntddraw/dxeng.c @@ -1,4 +1,4 @@ - /* +/* * PROJECT: ReactOS Win32 Subsystem * LICENSE: GPL - See COPYING in the top level directory * FILE: subsystems/win32/win32k/ntddraw/dxeng.c @@ -297,8 +297,7 @@ DxEngGetHdevData(HDEV hDev, break; case DxEGShDevData_hSpooler: DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_hSpooler\n"); - // retVal = (DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver. - retVal = (DWORD_PTR) PDev->VideoFileObject->DeviceObject; + retVal = 0;//(DWORD_PTR) PDev->hSpooler; // If the device is a spooler driver. break; case DxEGShDevData_DitherFmt: DPRINT1("requested DXEGSHDEVDATA DxEGShDevData_DitherFmt\n"); diff --git a/subsystems/win32/win32k/ntuser/callback.c b/subsystems/win32/win32k/ntuser/callback.c index e536d4ca7e1..2b4f2409a8b 100644 --- a/subsystems/win32/win32k/ntuser/callback.c +++ b/subsystems/win32/win32k/ntuser/callback.c @@ -324,20 +324,18 @@ co_IntCallHookProc(INT HookId, PUNICODE_STRING ModuleName) { ULONG ArgumentLength; - PVOID Argument; + PVOID Argument = NULL; LRESULT Result = 0; NTSTATUS Status; PVOID ResultPointer; ULONG ResultLength; PHOOKPROC_CALLBACK_ARGUMENTS Common; - CBT_CREATEWNDW *CbtCreateWnd =NULL; + CBT_CREATEWNDW *CbtCreateWnd = NULL; PCHAR Extra; PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS CbtCreatewndExtra = NULL; - UNICODE_STRING WindowName; - UNICODE_STRING ClassName; - PANSI_STRING asWindowName; - PANSI_STRING asClassName; PTHREADINFO pti; + PWND pWnd; + BOOL Hit = FALSE; ASSERT(Proc); @@ -356,36 +354,17 @@ co_IntCallHookProc(INT HookId, switch(Code) { case HCBT_CREATEWND: + pWnd = UserGetWindowObject((HWND) wParam); + if (!pWnd) + { + DPRINT1("WH_CBT HCBT_CREATEWND wParam bad hWnd!\n"); + goto Fault_Exit; + } + // Due to KsStudio.exe, just pass the callers original pointers + // except class which point to kernel space if not an atom. + // Found by, Olaf Siejka CbtCreateWnd = (CBT_CREATEWNDW *) lParam; ArgumentLength += sizeof(HOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS); - - asWindowName = (PANSI_STRING)&WindowName; - asClassName = (PANSI_STRING)&ClassName; - - if (Ansi) - { - RtlInitAnsiString(asWindowName, (PCSZ)CbtCreateWnd->lpcs->lpszName); - ArgumentLength += WindowName.Length + sizeof(CHAR); - } - else - { - RtlInitUnicodeString(&WindowName, CbtCreateWnd->lpcs->lpszName); - ArgumentLength += WindowName.Length + sizeof(WCHAR); - } - - if (! IS_ATOM(CbtCreateWnd->lpcs->lpszClass)) - { - if (Ansi) - { - RtlInitAnsiString(asClassName, (PCSZ)CbtCreateWnd->lpcs->lpszClass); - ArgumentLength += ClassName.Length + sizeof(CHAR); - } - else - { - RtlInitUnicodeString(&ClassName, CbtCreateWnd->lpcs->lpszClass); - ArgumentLength += ClassName.Length + sizeof(WCHAR); - } - } break; case HCBT_MOVESIZE: @@ -408,7 +387,7 @@ co_IntCallHookProc(INT HookId, break; default: DPRINT1("Trying to call unsupported CBT hook %d\n", Code); - return 0; + goto Fault_Exit; } break; case WH_KEYBOARD_LL: @@ -437,14 +416,14 @@ co_IntCallHookProc(INT HookId, break; default: DPRINT1("Trying to call unsupported window hook %d\n", HookId); - return 0; + goto Fault_Exit; } Argument = IntCbAllocateMemory(ArgumentLength); if (NULL == Argument) { DPRINT1("HookProc callback failed: out of memory\n"); - return 0; + goto Fault_Exit; } Common = (PHOOKPROC_CALLBACK_ARGUMENTS) Argument; Common->HookId = HookId; @@ -454,7 +433,8 @@ co_IntCallHookProc(INT HookId, Common->Proc = Proc; Common->Ansi = Ansi; Common->ModuleNameLength = ModuleName->Length; - memcpy(Common->ModuleName, ModuleName->Buffer, ModuleName->Length); + if (ModuleName->Buffer) + RtlCopyMemory(Common->ModuleName, ModuleName->Buffer, ModuleName->Length); Extra = (PCHAR) Common->ModuleName + Common->ModuleNameLength; switch(HookId) @@ -467,34 +447,9 @@ co_IntCallHookProc(INT HookId, CbtCreatewndExtra = (PHOOKPROC_CBT_CREATEWND_EXTRA_ARGUMENTS) Extra; RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) ); CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter; + CbtCreatewndExtra->Cs.lpszClass = CbtCreateWnd->lpcs->lpszClass; // if Atom + CbtCreatewndExtra->Cs.lpszName = CbtCreateWnd->lpcs->lpszName; Extra = (PCHAR) (CbtCreatewndExtra + 1); - RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length); - CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra); - CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer; - Extra += WindowName.Length; - if (Ansi) - { - *((CHAR *) Extra) = '\0'; - Extra += sizeof(CHAR); - } - else - { - *((WCHAR *) Extra) = L'\0'; - Extra += sizeof(WCHAR); - } - - if (! IS_ATOM(ClassName.Buffer)) - { - RtlCopyMemory(Extra, ClassName.Buffer, ClassName.Length); - CbtCreatewndExtra->Cs.lpszClass = - (LPCWSTR)(ULONG_PTR) MAKELONG(Extra - (PCHAR) CbtCreatewndExtra, 1); - Extra += ClassName.Length; - - if (Ansi) - *((CHAR *) Extra) = '\0'; - else - *((WCHAR *) Extra) = L'\0'; - } break; case HCBT_CLICKSKIPPED: RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MOUSEHOOKSTRUCT)); @@ -535,7 +490,6 @@ co_IntCallHookProc(INT HookId, case WH_GETMESSAGE: RtlCopyMemory(Extra, (PVOID) lParam, sizeof(MSG)); Common->lParam = (LPARAM) (Extra - (PCHAR) Common); -// DPRINT1("KHOOK Memory: %x\n",Common); break; case WH_FOREGROUNDIDLE: case WH_KEYBOARD: @@ -565,37 +519,47 @@ co_IntCallHookProc(INT HookId, _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Result = 0; + Hit = TRUE; } _SEH2_END; if (!NT_SUCCESS(Status)) { - return 0; + goto Fault_Exit; } - - if (HookId == WH_CBT && Code == HCBT_CREATEWND) + /* Support write backs... SEH is in UserCallNextHookEx. */ + switch (HookId) { - if (CbtCreatewndExtra) - { - _SEH2_TRY - { /* - The parameters could have been changed, include the coordinates - and dimensions of the window. We copy it back. - */ - CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter; - CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x; - CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y; - CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx; - CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + case WH_CBT: + if (Code == HCBT_CREATEWND) { - Result = 0; + if (CbtCreatewndExtra) + {/* + The parameters could have been changed, include the coordinates + and dimensions of the window. We copy it back. + */ + CbtCreateWnd->hwndInsertAfter = CbtCreatewndExtra->WndInsertAfter; + CbtCreateWnd->lpcs->x = CbtCreatewndExtra->Cs.x; + CbtCreateWnd->lpcs->y = CbtCreatewndExtra->Cs.y; + CbtCreateWnd->lpcs->cx = CbtCreatewndExtra->Cs.cx; + CbtCreateWnd->lpcs->cy = CbtCreatewndExtra->Cs.cy; + } } - _SEH2_END; - } + break; + // "The GetMsgProc hook procedure can examine or modify the message." + case WH_GETMESSAGE: + if (lParam) + { + RtlCopyMemory((PVOID) lParam, Extra, sizeof(MSG)); + } + break; } +Fault_Exit: + if (Hit) + { + DPRINT1("Exception CallHookProc HookId %d Code %d\n",HookId,Code); + } if (Argument) IntCbFreeMemory(Argument); return Result; diff --git a/subsystems/win32/win32k/ntuser/caret.c b/subsystems/win32/win32k/ntuser/caret.c index 3ebae7ae11b..76d58a7120b 100644 --- a/subsystems/win32/win32k/ntuser/caret.c +++ b/subsystems/win32/win32k/ntuser/caret.c @@ -30,10 +30,13 @@ static BOOL FASTCALL co_IntHideCaret(PTHRDCARETINFO CaretInfo) { + PWND pWnd; if(CaretInfo->hWnd && CaretInfo->Visible && CaretInfo->Showing) { + pWnd = UserGetWindowObject(CaretInfo->hWnd); co_IntSendMessage(CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); CaretInfo->Showing = 0; + IntNotifyWinEvent(EVENT_OBJECT_HIDE, pWnd, OBJID_CARET, CHILDID_SELF, 0); return TRUE; } return FALSE; @@ -43,17 +46,20 @@ BOOL FASTCALL co_IntDestroyCaret(PTHREADINFO Win32Thread) { PUSER_MESSAGE_QUEUE ThreadQueue; + PWND pWnd; ThreadQueue = (PUSER_MESSAGE_QUEUE)Win32Thread->MessageQueue; if(!ThreadQueue || !ThreadQueue->CaretInfo) return FALSE; + pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); co_IntHideCaret(ThreadQueue->CaretInfo); ThreadQueue->CaretInfo->Bitmap = (HBITMAP)0; ThreadQueue->CaretInfo->hWnd = (HWND)0; ThreadQueue->CaretInfo->Size.cx = ThreadQueue->CaretInfo->Size.cy = 0; ThreadQueue->CaretInfo->Showing = 0; ThreadQueue->CaretInfo->Visible = 0; + IntNotifyWinEvent(EVENT_OBJECT_DESTROY, pWnd, OBJID_CARET, CHILDID_SELF, 0); return TRUE; } @@ -176,6 +182,7 @@ BOOL FASTCALL co_IntSetCaretPos(int X, int Y) { PTHREADINFO pti; + PWND pWnd; PUSER_MESSAGE_QUEUE ThreadQueue; pti = PsGetCurrentThreadWin32Thread(); @@ -183,6 +190,7 @@ co_IntSetCaretPos(int X, int Y) if(ThreadQueue->CaretInfo->hWnd) { + pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); if(ThreadQueue->CaretInfo->Pos.x != X || ThreadQueue->CaretInfo->Pos.y != Y) { co_IntHideCaret(ThreadQueue->CaretInfo); @@ -191,6 +199,7 @@ co_IntSetCaretPos(int X, int Y) ThreadQueue->CaretInfo->Pos.y = Y; co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM); + IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_CARET, CHILDID_SELF, 0); } return TRUE; } @@ -277,6 +286,7 @@ BOOL FASTCALL co_UserHideCaret(PWND Window OPTIONAL) BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL) { PTHREADINFO pti; + PWND pWnd; PUSER_MESSAGE_QUEUE ThreadQueue; if (Window) ASSERT_REFS_CO(Window); @@ -301,11 +311,12 @@ BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL) ThreadQueue->CaretInfo->Visible = 1; if(!ThreadQueue->CaretInfo->Showing) { + pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd); co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0); + IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0); } IntSetTimer(UserGetWindowObject(ThreadQueue->CaretInfo->hWnd), IDCARETTIMER, IntGetCaretBlinkTime(), NULL, TMRF_SYSTEM); } - return TRUE; } @@ -370,7 +381,7 @@ NtUserCreateCaret( } ThreadQueue->CaretInfo->Visible = 0; ThreadQueue->CaretInfo->Showing = 0; - + IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_CARET, CHILDID_SELF, 0); RETURN(TRUE); CLEANUP: diff --git a/subsystems/win32/win32k/ntuser/clipboard.c b/subsystems/win32/win32k/ntuser/clipboard.c index 538cf25707e..4d79962b17f 100644 --- a/subsystems/win32/win32k/ntuser/clipboard.c +++ b/subsystems/win32/win32k/ntuser/clipboard.c @@ -243,34 +243,62 @@ IntEmptyClipboardData(VOID) /*==============================================================*/ HANDLE FASTCALL -renderBITMAPfromDIB(LPBYTE hDIB) +renderBITMAPfromDIB(LPBYTE pDIB) { HDC hdc; HBITMAP hbitmap; - unsigned int offset; - BITMAPINFOHEADER *ih; + PBITMAPINFO pBmi, pConvertedBmi = NULL; + NTSTATUS Status ; + UINT offset = 0; /* Stupid compiler */ + + pBmi = (BITMAPINFO*)pDIB; //hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE); - ih = (BITMAPINFOHEADER *)hDIB; + /* Probe it */ + _SEH2_TRY + { + ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1); + ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1); + pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); + if(!pConvertedBmi) + { + Status = STATUS_INVALID_PARAMETER; + } + else + { + offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS); + ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END - offset = sizeof(BITMAPINFOHEADER) + ((ih->biBitCount <= 8) ? (sizeof(RGBQUAD) * (1 << ih->biBitCount)) : 0); + if(!NT_SUCCESS(Status)) + { + UserReleaseDC(ClipboardWindow, hdc, FALSE); + return NULL; + } - hbitmap = NtGdiCreateDIBitmapInternal(hdc, - ih->biWidth, - ih->biHeight, - CBM_INIT, - (LPBYTE)ih+offset, - (LPBITMAPINFO)ih, - DIB_RGB_COLORS, - ih->biBitCount, - ih->biSizeImage, - 0, - 0); + hbitmap = GreCreateDIBitmapInternal(hdc, + pConvertedBmi->bmiHeader.biWidth, + pConvertedBmi->bmiHeader.biHeight, + CBM_INIT, + pDIB+offset, + pConvertedBmi, + DIB_RGB_COLORS, + 0, + 0); //UserReleaseDC(NULL, hdc, FALSE); UserReleaseDC(ClipboardWindow, hdc, FALSE); + DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi); + return hbitmap; } diff --git a/subsystems/win32/win32k/ntuser/cursoricon.c b/subsystems/win32/win32k/ntuser/cursoricon.c index 427632e3ba7..2d8ff953a06 100644 --- a/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/subsystems/win32/win32k/ntuser/cursoricon.c @@ -109,7 +109,7 @@ UserSetCursor( PCURICON_OBJECT OldCursor; HCURSOR hOldCursor = (HCURSOR)0; HDC hdcScreen; - + CurInfo = IntGetSysCursorInfo(); OldCursor = CurInfo->CurrentCursorObject; @@ -483,6 +483,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process) } + /* * @implemented */ @@ -692,6 +693,35 @@ CLEANUP: END_CLEANUP; } +BOOL +APIENTRY +UserClipCursor( + RECTL *prcl) +{ + /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */ + PSYSTEM_CURSORINFO CurInfo; + PWND DesktopWindow = NULL; + + CurInfo = IntGetSysCursorInfo(); + + DesktopWindow = UserGetDesktopWindow(); + + if (prcl != NULL && + (prcl->right > prcl->left) && + (prcl->bottom > prcl->top) && + DesktopWindow != NULL) + { + CurInfo->bClipped = TRUE; + RECTL_bIntersectRect(&CurInfo->rcClip, prcl, &DesktopWindow->rcWindow); + UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); + } + else + { + CurInfo->bClipped = FALSE; + } + + return TRUE; +} /* * @implemented @@ -699,45 +729,37 @@ CLEANUP: BOOL APIENTRY NtUserClipCursor( - RECTL *UnsafeRect) + RECTL *prcl) { - /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */ - PSYSTEM_CURSORINFO CurInfo; - RECTL Rect; - PWND DesktopWindow = NULL; - DECLARE_RETURN(BOOL); + RECTL rclLocal; + BOOL bResult; - DPRINT("Enter NtUserClipCursor\n"); - UserEnterExclusive(); - - if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT)))) + if (prcl) { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN(FALSE); + _SEH2_TRY + { + /* Probe and copy rect */ + ProbeForRead(prcl, sizeof(RECTL), 1); + rclLocal = *prcl; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + _SEH2_YIELD(return FALSE;) + } + _SEH2_END + + prcl = &rclLocal; } + + UserEnterExclusive(); - CurInfo = IntGetSysCursorInfo(); + /* Call the internal function */ + bResult = UserClipCursor(prcl); - DesktopWindow = UserGetDesktopWindow(); - - if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top) - && DesktopWindow && UnsafeRect != NULL) - { - - CurInfo->bClipped = TRUE; - RECTL_bIntersectRect(&CurInfo->rcClip, &Rect, &DesktopWindow->rcWindow); - UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); - - RETURN(TRUE); - } - - CurInfo->bClipped = FALSE; - RETURN(TRUE); - -CLEANUP: - DPRINT("Leave NtUserClipCursor, ret=%i\n",_ret_); UserLeave(); - END_CLEANUP; + + return bResult; } @@ -937,12 +959,12 @@ NtUserSetCursorContents( /* Delete old bitmaps */ if ((CurIcon->IconInfo.hbmColor) - && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor)) + && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor)) { GreDeleteObject(CurIcon->IconInfo.hbmColor); } if ((CurIcon->IconInfo.hbmMask) - && (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)) + && CurIcon->IconInfo.hbmMask != IconInfo.hbmMask) { GreDeleteObject(CurIcon->IconInfo.hbmMask); } @@ -968,8 +990,8 @@ NtUserSetCursorContents( CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2; SURFACE_UnlockSurface(psurfBmp); - GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL); } + GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL); Ret = TRUE; @@ -1287,23 +1309,12 @@ UserDrawIconEx( if(bAlpha && (diFlags & DI_IMAGE)) { BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA }; - DWORD Pixel; - BYTE Red, Green, Blue, Alpha; - DWORD Count = 0; + BYTE Alpha; INT i, j; PSURFACE psurf; - PBYTE pBits ; + PBYTE ptr ; HBITMAP hMemBmp = NULL; - pBits = ExAllocatePoolWithTag(PagedPool, - bmpColor.bmWidthBytes * abs(bmpColor.bmHeight), - TAG_BITMAP); - if (pBits == NULL) - { - Ret = FALSE; - goto CleanupAlpha; - } - hMemBmp = BITMAP_CopyBitmap(hbmColor); if(!hMemBmp) { @@ -1317,35 +1328,22 @@ UserDrawIconEx( DPRINT1("SURFACE_LockSurface failed!\n"); goto CleanupAlpha; } - /* get color bits */ - IntGetBitmapBits(psurf, - bmpColor.bmWidthBytes * abs(bmpColor.bmHeight), - pBits); /* premultiply with the alpha channel value */ - for (i = 0; i < abs(bmpColor.bmHeight); i++) + for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++) { - Count = i*bmpColor.bmWidthBytes; - for (j = 0; j < bmpColor.bmWidth; j++) + ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta; + for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++) { - Pixel = *(DWORD *)(pBits + Count); + Alpha = ptr[3]; + ptr[0] = (ptr[0] * Alpha) / 0xff; + ptr[1] = (ptr[1] * Alpha) / 0xff; + ptr[2] = (ptr[2] * Alpha) / 0xff; - Alpha = ((BYTE)(Pixel >> 24) & 0xff); - - Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff; - Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff; - Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff; - - *(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24)); - - Count += sizeof(DWORD); + ptr += 4; } } - /* set mem bits */ - IntSetBitmapBits(psurf, - bmpColor.bmWidthBytes * abs(bmpColor.bmHeight), - pBits); SURFACE_UnlockSurface(psurf); hTmpBmp = NtGdiSelectBitmap(hMemDC, hMemBmp); @@ -1364,12 +1362,10 @@ UserDrawIconEx( NULL); NtGdiSelectBitmap(hMemDC, hTmpBmp); CleanupAlpha: - if(pBits) ExFreePoolWithTag(pBits, TAG_BITMAP); if(hMemBmp) NtGdiDeleteObjectApp(hMemBmp); if(Ret) goto done; } - if (diFlags & DI_MASK) { hTmpBmp = NtGdiSelectBitmap(hMemDC, hbmMask); diff --git a/subsystems/win32/win32k/ntuser/desktop.c b/subsystems/win32/win32k/ntuser/desktop.c index 3a054f2f08d..894245d219b 100644 --- a/subsystems/win32/win32k/ntuser/desktop.c +++ b/subsystems/win32/win32k/ntuser/desktop.c @@ -616,8 +616,6 @@ UserRedrawDesktop() { PWND Window = NULL; - UserEnterExclusive(); - Window = UserGetDesktopWindow(); IntInvalidateWindows( Window, @@ -626,7 +624,6 @@ UserRedrawDesktop() RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN); - UserLeave(); } @@ -884,6 +881,7 @@ NtUserCreateDesktop( LARGE_STRING WindowName; PWND pWnd = NULL; CREATESTRUCTW Cs; + INT i; DECLARE_RETURN(HDESK); DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); @@ -1026,6 +1024,11 @@ NtUserCreateDesktop( /* Initialize some local (to win32k) desktop state. */ InitializeListHead(&DesktopObject->PtiList); DesktopObject->ActiveMessageQueue = NULL; + /* Setup Global Hooks. */ + for (i = 0; i < NB_HOOKS; i++) + { + InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]); + } ExFreePoolWithTag(DesktopName.Buffer, TAG_STRING); if (! NT_SUCCESS(Status)) diff --git a/subsystems/win32/win32k/ntuser/display.c b/subsystems/win32/win32k/ntuser/display.c index b5986a58df2..7ab53638f1a 100644 --- a/subsystems/win32/win32k/ntuser/display.c +++ b/subsystems/win32/win32k/ntuser/display.c @@ -1,199 +1,881 @@ /* - * PROJECT: ReactOS Kernel - * LICENSE: GPL - See COPYING in the top level directory - * FILE: subsystems/win32/win32k/ntuser/display.c - * PURPOSE: display settings - * COPYRIGHT: Copyright 2007 ReactOS - * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * PURPOSE: Video initialization and display settings + * FILE: subsystems/win32/win32k/ntuser/display.c + * PROGRAMER: Timo Kreuzer (timo.kreuzer@reactos.org) */ -/* INCLUDES ******************************************************************/ - #include +#include + #define NDEBUG #include -#define SIZEOF_DEVMODEW_300 188 -#define SIZEOF_DEVMODEW_400 212 -#define SIZEOF_DEVMODEW_500 220 +BOOL InitSysParams(); -/* PUBLIC FUNCTIONS ***********************************************************/ +BOOL gbBaseVideo = 0; -NTSTATUS -APIENTRY -NtUserEnumDisplaySettings( - PUNICODE_STRING pusDeviceName, - DWORD iModeNum, - LPDEVMODEW lpDevMode, /* FIXME is this correct? */ - DWORD dwFlags ) +static const PWCHAR KEY_ROOT = L""; +static const PWCHAR KEY_VIDEO = L"\\Registry\\Machine\\HARDWARE\\DEVICEMAP\\VIDEO"; + +VOID +RegWriteDisplaySettings(HKEY hkey, PDEVMODEW pdm) { - NTSTATUS Status; - LPDEVMODEW pSafeDevMode; - PUNICODE_STRING pusSafeDeviceName = NULL; - UNICODE_STRING usSafeDeviceName; - USHORT Size = 0, ExtraSize = 0; - - /* Copy the devmode */ - _SEH2_TRY - { - ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1); - Size = lpDevMode->dmSize; - ExtraSize = lpDevMode->dmDriverExtra; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - DPRINT("FIXME ? : Out of range of DEVMODEW size \n"); - _SEH2_YIELD(return _SEH2_GetExceptionCode()); - } - _SEH2_END; - - if (Size != sizeof(DEVMODEW)) - { - return STATUS_BUFFER_TOO_SMALL; - } - - pSafeDevMode = ExAllocatePoolWithTag(PagedPool, Size + ExtraSize, GDITAG_DEVMODE); - if (pSafeDevMode == NULL) - { - return STATUS_NO_MEMORY; - } - pSafeDevMode->dmSize = Size; - pSafeDevMode->dmDriverExtra = ExtraSize; - - /* Copy the device name */ - if (pusDeviceName != NULL) - { - Status = IntSafeCopyUnicodeString(&usSafeDeviceName, pusDeviceName); - if (!NT_SUCCESS(Status)) - { - ExFreePool(pSafeDevMode); - return Status; - } - pusSafeDeviceName = &usSafeDeviceName; - } - - /* Call internal function */ - Status = IntEnumDisplaySettings(pusSafeDeviceName, iModeNum, pSafeDevMode, dwFlags); - - if (pusSafeDeviceName != NULL) - RtlFreeUnicodeString(pusSafeDeviceName); - - if (!NT_SUCCESS(Status)) - { - ExFreePool(pSafeDevMode); - return Status; - } - - /* Copy some information back */ - _SEH2_TRY - { - ProbeForWrite(lpDevMode,Size + ExtraSize, 1); - lpDevMode->dmPelsWidth = pSafeDevMode->dmPelsWidth; - lpDevMode->dmPelsHeight = pSafeDevMode->dmPelsHeight; - lpDevMode->dmBitsPerPel = pSafeDevMode->dmBitsPerPel; - lpDevMode->dmDisplayFrequency = pSafeDevMode->dmDisplayFrequency; - lpDevMode->dmDisplayFlags = pSafeDevMode->dmDisplayFlags; - - /* output private/extra driver data */ - if (ExtraSize > 0) - { - memcpy((PCHAR)lpDevMode + Size, (PCHAR)pSafeDevMode + Size, ExtraSize); - } - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - ExFreePool(pSafeDevMode); - return Status; + RegWriteDWORD(hkey, L"DefaultSettings.BitsPerPel", pdm->dmBitsPerPel); + RegWriteDWORD(hkey, L"DefaultSettings.XResolution", pdm->dmPelsWidth); + RegWriteDWORD(hkey, L"DefaultSettings.YResolution", pdm->dmPelsHeight); + RegWriteDWORD(hkey, L"DefaultSettings.Flags", pdm->dmDisplayFlags); + RegWriteDWORD(hkey, L"DefaultSettings.VRefresh", pdm->dmDisplayFrequency); + RegWriteDWORD(hkey, L"DefaultSettings.XPanning", pdm->dmPanningWidth); + RegWriteDWORD(hkey, L"DefaultSettings.YPanning", pdm->dmPanningHeight); + RegWriteDWORD(hkey, L"DefaultSettings.Orientation", pdm->dmDisplayOrientation); + RegWriteDWORD(hkey, L"DefaultSettings.FixedOutput", pdm->dmDisplayFixedOutput); + RegWriteDWORD(hkey, L"Attach.RelativeX", pdm->dmPosition.x); + RegWriteDWORD(hkey, L"Attach.RelativeY", pdm->dmPosition.y); +// RegWriteDWORD(hkey, L"Attach.ToDesktop, pdm->dmBitsPerPel", pdm->); } - -LONG -APIENTRY -NtUserChangeDisplaySettings( - PUNICODE_STRING lpszDeviceName, - LPDEVMODEW lpDevMode, - HWND hwnd, - DWORD dwflags, - LPVOID lParam) +VOID +RegReadDisplaySettings(HKEY hkey, PDEVMODEW pdm) { - NTSTATUS Status = STATUS_SUCCESS; - LPDEVMODEW lpSafeDevMode = NULL; - DEVMODEW DevMode; - PUNICODE_STRING pSafeDeviceName = NULL; - UNICODE_STRING SafeDeviceName; - LONG Ret; + DWORD dwValue; - /* Check arguments */ -#ifdef CDS_VIDEOPARAMETERS - if (dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) -#else - if (lParam != NULL) -#endif - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return DISP_CHANGE_BADPARAM; + /* Zero out the structure */ + RtlZeroMemory(pdm, sizeof(DEVMODEW)); + +/* Helper macro */ +#define READ(field, str, flag) \ + if (RegReadDWORD(hkey, L##str, &dwValue)) \ + { \ + pdm->field = dwValue; \ + pdm->dmFields |= flag; \ } - if (hwnd != NULL) + /* Read all present settings */ + READ(dmBitsPerPel, "DefaultSettings.BitsPerPel", DM_BITSPERPEL); + READ(dmPelsWidth, "DefaultSettings.XResolution", DM_PELSWIDTH); + READ(dmPelsHeight, "DefaultSettings.YResolution", DM_PELSHEIGHT); + READ(dmDisplayFlags, "DefaultSettings.Flags", DM_DISPLAYFLAGS); + READ(dmDisplayFrequency, "DefaultSettings.VRefresh", DM_DISPLAYFREQUENCY); + READ(dmPanningWidth, "DefaultSettings.XPanning", DM_PANNINGWIDTH); + READ(dmPanningHeight, "DefaultSettings.YPanning", DM_PANNINGHEIGHT); + READ(dmDisplayOrientation, "DefaultSettings.Orientation", DM_DISPLAYORIENTATION); + READ(dmDisplayFixedOutput, "DefaultSettings.FixedOutput", DM_DISPLAYFIXEDOUTPUT); + READ(dmPosition.x, "Attach.RelativeX", DM_POSITION); + READ(dmPosition.y, "Attach.RelativeY", DM_POSITION); +} + +PGRAPHICS_DEVICE +NTAPI +InitDisplayDriver( + IN PWSTR pwszDeviceName, + IN PWSTR pwszRegKey) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + UNICODE_STRING ustrDeviceName, ustrDisplayDrivers, ustrDescription; + NTSTATUS Status; + WCHAR awcBuffer[128]; + ULONG cbSize; + HKEY hkey; + DEVMODEW dmDefault; + + DPRINT1("InitDisplayDriver(%S, %S);\n", + pwszDeviceName, pwszRegKey); + + /* Open the driver's registry key */ + Status = RegOpenKey(pwszRegKey, &hkey); + if (!NT_SUCCESS(Status)) { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return DISP_CHANGE_BADPARAM; + DPRINT1("Failed to open registry key: %ls\n", pwszRegKey); + return NULL; } - /* Copy devmode */ - if (lpDevMode != NULL) + /* Query the diplay drivers */ + cbSize = sizeof(awcBuffer) - 10; + Status = RegQueryValue(hkey, + L"InstalledDisplayDrivers", + REG_MULTI_SZ, + awcBuffer, + &cbSize); + if (!NT_SUCCESS(Status)) { + DPRINT1("Didn't find 'InstalledDisplayDrivers', status = 0x%lx\n", Status); + ZwClose(hkey); + return NULL; + } + + /* Initialize the UNICODE_STRING */ + ustrDisplayDrivers.Buffer = awcBuffer; + ustrDisplayDrivers.MaximumLength = cbSize; + ustrDisplayDrivers.Length = cbSize; + + /* Set Buffer for description and size of remaining buffer */ + ustrDescription.Buffer = awcBuffer + (cbSize / sizeof(WCHAR)); + cbSize = sizeof(awcBuffer) - cbSize; + + /* Query the device string */ + Status = RegQueryValue(hkey, + L"Device Description", + REG_SZ, + ustrDescription.Buffer, + &cbSize); + if (NT_SUCCESS(Status)) + { + ustrDescription.MaximumLength = cbSize; + ustrDescription.Length = cbSize; + } + else + { + RtlInitUnicodeString(&ustrDescription, L""); + } + + /* Query the default settings */ + RegReadDisplaySettings(hkey, &dmDefault); + + /* Close the registry key */ + ZwClose(hkey); + + /* Register the device with GDI */ + RtlInitUnicodeString(&ustrDeviceName, pwszDeviceName); + pGraphicsDevice = EngpRegisterGraphicsDevice(&ustrDeviceName, + &ustrDisplayDrivers, + &ustrDescription, + &dmDefault); + + return pGraphicsDevice; +} + +BOOL +InitVideo( + PUNICODE_STRING pustrRegPath, + FLONG flags) +{ + ULONG iDevNum, iVGACompatible = -1, ulMaxObjectNumber = 0; + WCHAR awcDeviceName[20]; + WCHAR awcBuffer[256]; + NTSTATUS Status; + PGRAPHICS_DEVICE pGraphicsDevice; + ULONG cbValue; + HKEY hkey; + + DPRINT1("----------------------------- InitVideo() -------------------------------\n"); + + Status = RegOpenKey(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control", &hkey); + if (NT_SUCCESS(Status)) + { + cbValue = 256; + Status = RegQueryValue(hkey, L"SystemStartOptions", REG_SZ, awcBuffer, &cbValue); + if (NT_SUCCESS(Status)) + { + /* Check if VGA mode is requested. */ + if (wcsstr(awcBuffer, L"/BASEVIDEO") != 0) + { + DPRINT1("VGA mode requested.\n"); + gbBaseVideo = TRUE; + } + } + + ZwClose(hkey); + } + + /* Open the key for the adapters */ + Status = RegOpenKey(KEY_VIDEO, &hkey); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Could not open device registry key!\n"); + ASSERT(FALSE); + } + + /* Read the name of the VGA adapter */ + cbValue = 20; + Status = RegQueryValue(hkey, L"VgaCompatible", REG_SZ, awcDeviceName, &cbValue); + if (NT_SUCCESS(Status)) + { + iVGACompatible = _wtoi(&awcDeviceName[13]); + DPRINT1("VGA adapter = %ld\n", iVGACompatible); + } + + /* Get the maximum mumber of adapters */ + if (!RegReadDWORD(hkey, L"MaxObjectNumber", &ulMaxObjectNumber)) + { + DPRINT1("Could not read MaxObjectNumber, defaulting to 0.\n"); + } + + DPRINT("Found %ld devices\n", ulMaxObjectNumber); + + /* Loop through all adapters */ + cbValue = 256; + for (iDevNum = 0; iDevNum <= ulMaxObjectNumber; iDevNum++) + { + /* Create the adapter's key name */ + swprintf(awcDeviceName, L"\\Device\\Video%lu", iDevNum); + + /* Read the reg key name */ + Status = RegQueryValue(hkey, awcDeviceName, REG_SZ, awcBuffer, &cbValue); + + pGraphicsDevice = InitDisplayDriver(awcDeviceName, awcBuffer); + + /* Check if this is the VGA adapter */ + if (iDevNum == iVGACompatible) + { + /* Set the VGA device as primary */ + gpVgaGraphicsDevice = pGraphicsDevice; + DPRINT1("gpVgaGraphicsDevice = %p\n", gpVgaGraphicsDevice); + } + + /* Set the first one as primary device */ + if (!gpPrimaryGraphicsDevice) + gpPrimaryGraphicsDevice = pGraphicsDevice; + } + + ZwClose(hkey); + + if (gbBaseVideo) + { + if (gpVgaGraphicsDevice) + { + /* Set the VgaAdapter as primary */ + gpPrimaryGraphicsDevice = gpVgaGraphicsDevice; + // FIXME: DEVMODE + } + else + { + DPRINT1("Could not find VGA compatible driver. Trying normal.\n"); + } + } + + InitSysParams(); + + return 1; +} + +NTSTATUS +NTAPI +UserEnumDisplayDevices( + PUNICODE_STRING pustrDevice, + DWORD iDevNum, + PDISPLAY_DEVICEW pdispdev, + DWORD dwFlags) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + ULONG cbSize; + HKEY hkey; + NTSTATUS Status; + + /* Ask gdi for the GRAPHICS_DEVICE */ + pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, iDevNum, 0); + if (!pGraphicsDevice) + { + /* No device found */ + DPRINT1("No GRAPHICS_DEVICE found\n"); + return STATUS_UNSUCCESSFUL; + } + + /* Open thhe device map registry key */ + Status = RegOpenKey(KEY_VIDEO, &hkey); + if (!NT_SUCCESS(Status)) + { + /* No device found */ + DPRINT1("Could not open reg key\n"); + return STATUS_UNSUCCESSFUL; + } + + /* Query the registry path */ + cbSize = sizeof(pdispdev->DeviceKey); + RegQueryValue(hkey, + pGraphicsDevice->szNtDeviceName, + REG_SZ, + pdispdev->DeviceKey, + &cbSize); + + /* Close registry key */ + ZwClose(hkey); + + /* Copy device name, device string and StateFlags */ + wcsncpy(pdispdev->DeviceName, pGraphicsDevice->szWinDeviceName, 32); + wcsncpy(pdispdev->DeviceString, pGraphicsDevice->pwszDescription, 128); + pdispdev->StateFlags = pGraphicsDevice->StateFlags; + + // FIXME: fill in DEVICE ID + + return STATUS_SUCCESS; +} + +//NTSTATUS +BOOL +NTAPI +NtUserEnumDisplayDevices( + PUNICODE_STRING pustrDevice, + DWORD iDevNum, + PDISPLAY_DEVICEW pDisplayDevice, + DWORD dwFlags) +{ + UNICODE_STRING ustrDevice; + WCHAR awcDevice[CCHDEVICENAME]; + DISPLAY_DEVICEW dispdev; + NTSTATUS Status; + + DPRINT("Enter NtUserEnumDisplayDevices(%wZ, %ld)\n", + pustrDevice, iDevNum); + + // FIXME: HACK, desk.cpl passes broken crap + if (pustrDevice && iDevNum != 0) + return FALSE; + + dispdev.cb = sizeof(DISPLAY_DEVICEW); + + if (pustrDevice) + { + /* Initialize destination string */ + RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); + _SEH2_TRY { - ProbeForRead(lpDevMode, sizeof(DevMode.dmSize), 1); - DevMode.dmSize = lpDevMode->dmSize; - DevMode.dmSize = min(sizeof(DevMode), DevMode.dmSize); - ProbeForRead(lpDevMode, DevMode.dmSize, 1); - RtlCopyMemory(&DevMode, lpDevMode, DevMode.dmSize); + /* Probe the UNICODE_STRING and the buffer */ + ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); + ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); + + /* Copy the string */ + RtlCopyUnicodeString(&ustrDevice, pustrDevice); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { +// _SEH2_YIELD(return _SEH2_GetExceptionCode()); + _SEH2_YIELD(return NT_SUCCESS(_SEH2_GetExceptionCode())); + } + _SEH2_END + + if (ustrDevice.Length > 0) + pustrDevice = &ustrDevice; + else + pustrDevice = NULL; + } + + /* Acquire global USER lock */ + UserEnterExclusive(); + + /* Call the internal function */ + Status = UserEnumDisplayDevices(pustrDevice, iDevNum, &dispdev, dwFlags); + + /* Release lock */ + UserLeave(); + + /* On success copy data to caller */ + if (NT_SUCCESS(Status)) + { + /* Enter SEH */ + _SEH2_TRY + { + /* First probe the cb field */ + ProbeForWrite(&pDisplayDevice->cb, sizeof(DWORD), 1); + + /* Check the buffer size */ + if (pDisplayDevice->cb) + { + /* Probe the output buffer */ + pDisplayDevice->cb = min(pDisplayDevice->cb, sizeof(dispdev)); + ProbeForWrite(pDisplayDevice, pDisplayDevice->cb, 1); + + /* Copy as much as the given buffer allows */ + RtlCopyMemory(pDisplayDevice, &dispdev, pDisplayDevice->cb); + } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END + } + DPRINT1("Leave NtUserEnumDisplayDevices, Status = 0x%lx\n", Status); + /* Return the result */ +// return Status; + return NT_SUCCESS(Status); // FIXME +} + +NTSTATUS +NTAPI +UserEnumCurrentDisplaySettings( + PUNICODE_STRING pustrDevice, + PDEVMODEW *ppdm) +{ + PPDEVOBJ ppdev; + + /* Get the PDEV for the device */ + ppdev = EngpGetPDEV(pustrDevice); + if (!ppdev) + { + /* No device found */ + DPRINT1("No PDEV found!\n"); + return STATUS_UNSUCCESSFUL; + } + + *ppdm = ppdev->pdmwDev; + PDEVOBJ_vRelease(ppdev); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +UserEnumDisplaySettings( + PUNICODE_STRING pustrDevice, + DWORD iModeNum, + LPDEVMODEW *ppdm, + DWORD dwFlags) +{ + PGRAPHICS_DEVICE pGraphicsDevice; + PDEVMODEENTRY pdmentry; + ULONG i, iFoundMode; + + DPRINT("Enter UserEnumDisplaySettings('%ls', %ld)\n", + pustrDevice ? pustrDevice->Buffer : NULL, iModeNum); + + /* Ask gdi for the GRAPHICS_DEVICE */ + pGraphicsDevice = EngpFindGraphicsDevice(pustrDevice, 0, 0); + + if (!pGraphicsDevice) + { + /* No device found */ + DPRINT1("No device found!\n"); + return STATUS_UNSUCCESSFUL; + } + + if (iModeNum >= pGraphicsDevice->cDevModes) + return STATUS_NO_MORE_ENTRIES; + + iFoundMode = 0; + for (i = 0; i < pGraphicsDevice->cDevModes; i++) + { + pdmentry = &pGraphicsDevice->pDevModeList[i]; + + /* FIXME: consider EDS_RAWMODE */ +#if 0 + if ((!(dwFlags & EDS_RAWMODE) && (pdmentry->dwFlags & 1)) ||! + (dwFlags & EDS_RAWMODE)) +#endif + { + /* Is this the one we want? */ + if (iFoundMode == iModeNum) + { + *ppdm = pdmentry->pdm; + return STATUS_SUCCESS; + } + + /* Increment number of found modes */ + iFoundMode++; + } + } + + /* Nothing was found */ + return STATUS_INVALID_PARAMETER; +} + +NTSTATUS +NTAPI +UserOpenDisplaySettingsKey( + OUT PHKEY phkey, + IN PUNICODE_STRING pustrDevice, + IN BOOL bGlobal) +{ + HKEY hkey; + DISPLAY_DEVICEW dispdev; + NTSTATUS Status; + + /* Get device info */ + Status = UserEnumDisplayDevices(pustrDevice, 0, &dispdev, 0); + if (!NT_SUCCESS(Status)) + return Status; + + if (bGlobal) + { + // FIXME: need to fix the registry key somehow + } + + /* Open the registry key */ + Status = RegOpenKey(dispdev.DeviceKey, &hkey); + if (!NT_SUCCESS(Status)) + return Status; + + *phkey = hkey; + + return Status; +} + +NTSTATUS +NTAPI +UserEnumRegistryDisplaySettings( + IN PUNICODE_STRING pustrDevice, + OUT LPDEVMODEW pdm) +{ + HKEY hkey; + NTSTATUS Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, 0); + if(NT_SUCCESS(Status)) + { + RegReadDisplaySettings(hkey, pdm); + ZwClose(hkey); + return STATUS_SUCCESS; + } + return Status ; +} + + +NTSTATUS +APIENTRY +NtUserEnumDisplaySettings( + IN PUNICODE_STRING pustrDevice, + IN DWORD iModeNum, + OUT LPDEVMODEW lpDevMode, + IN DWORD dwFlags) +{ + UNICODE_STRING ustrDevice; + WCHAR awcDevice[CCHDEVICENAME]; + NTSTATUS Status; + ULONG cbSize, cbExtra; + DEVMODEW dmReg, *pdm; + + DPRINT1("Enter NtUserEnumDisplaySettings(%ls, %ld)\n", + pustrDevice ? pustrDevice->Buffer : 0, iModeNum); + + if (pustrDevice) + { + /* Initialize destination string */ + RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); + + _SEH2_TRY + { + /* Probe the UNICODE_STRING and the buffer */ + ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); + ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); + + /* Copy the string */ + RtlCopyUnicodeString(&ustrDevice, pustrDevice); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return _SEH2_GetExceptionCode()); + } + _SEH2_END + + pustrDevice = &ustrDevice; + } + + /* Acquire global USER lock */ + UserEnterExclusive(); + + if (iModeNum == ENUM_REGISTRY_SETTINGS) + { + /* Get the registry settings */ + Status = UserEnumRegistryDisplaySettings(pustrDevice, &dmReg); + pdm = &dmReg; + } + else if (iModeNum == ENUM_CURRENT_SETTINGS) + { + /* Get the current settings */ + Status = UserEnumCurrentDisplaySettings(pustrDevice, &pdm); + } + else + { + /* Get specified settings */ + Status = UserEnumDisplaySettings(pustrDevice, iModeNum, &pdm, dwFlags); + } + + /* Release lock */ + UserLeave(); + + /* Did we succeed? */ + if (NT_SUCCESS(Status)) + { + /* Copy some information back */ + _SEH2_TRY + { + ProbeForRead(lpDevMode, sizeof(DEVMODEW), 1); + cbSize = lpDevMode->dmSize; + cbExtra = lpDevMode->dmDriverExtra; + + ProbeForWrite(lpDevMode, cbSize + cbExtra, 1); + /* Output what we got */ + RtlCopyMemory(lpDevMode, pdm, min(cbSize, pdm->dmSize)); + + /* output private/extra driver data */ + if (cbExtra > 0 && pdm->dmDriverExtra > 0) + { + RtlCopyMemory((PCHAR)lpDevMode + cbSize, + (PCHAR)pdm + pdm->dmSize, + min(cbExtra, pdm->dmDriverExtra)); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + } + + return Status; +} + +BOOL APIENTRY UserClipCursor(RECTL *prcl); +VOID APIENTRY UserRedrawDesktop(); +HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange); + +LONG +APIENTRY +UserChangeDisplaySettings( + PUNICODE_STRING pustrDevice, + LPDEVMODEW pdm, + HWND hwnd, + DWORD flags, + LPVOID lParam) +{ + DEVMODEW dm; + LONG lResult = DISP_CHANGE_SUCCESSFUL; + HKEY hkey; + NTSTATUS Status; + PPDEVOBJ ppdev; + PDESKTOP pdesk; + + /* If no DEVMODE is given, use registry settings */ + if (!pdm) + { + /* Get the registry settings */ + Status = UserEnumRegistryDisplaySettings(pustrDevice, &dm); if (!NT_SUCCESS(Status)) { - SetLastNtError(Status); + DPRINT1("Could not load registry settings\n"); return DISP_CHANGE_BADPARAM; } + } + else if (pdm->dmSize < FIELD_OFFSET(DEVMODEW, dmFields)) + return DISP_CHANGE_BADMODE; /* This is what winXP SP3 returns */ + else + dm = *pdm; - if (DevMode.dmDriverExtra > 0) + /* Check params */ + if ((dm.dmFields & (DM_PELSWIDTH | DM_PELSHEIGHT)) != (DM_PELSWIDTH | DM_PELSHEIGHT)) + { + DPRINT1("devmode doesn't specify the resolution.\n"); + return DISP_CHANGE_BADMODE; + } + + /* Get the PDEV */ + ppdev = EngpGetPDEV(pustrDevice); + if (!ppdev) + { + DPRINT1("failed to get PDEV\n"); + return DISP_CHANGE_BADPARAM; + } + + /* Fixup values */ + if(dm.dmBitsPerPel == 0 || !(dm.dmFields & DM_BITSPERPEL)) + { + dm.dmBitsPerPel = ppdev->pdmwDev->dmBitsPerPel; + dm.dmFields |= DM_BITSPERPEL; + } + + if((dm.dmFields & DM_DISPLAYFREQUENCY) && (dm.dmDisplayFrequency == 0)) + dm.dmDisplayFrequency = ppdev->pdmwDev->dmDisplayFrequency; + + /* Look for the requested DEVMODE */ + pdm = PDEVOBJ_pdmMatchDevMode(ppdev, &dm); + if (!pdm) + { + DPRINT1("Could not find a matching DEVMODE\n"); + lResult = DISP_CHANGE_BADMODE; + goto leave; + } + else if (flags & CDS_TEST) + { + /* It's possible, go ahead! */ + lResult = DISP_CHANGE_SUCCESSFUL; + goto leave; + } + + /* Shall we update the registry? */ + if (flags & CDS_UPDATEREGISTRY) + { + /* Open the local or global settings key */ + Status = UserOpenDisplaySettingsKey(&hkey, pustrDevice, flags & CDS_GLOBAL); + if (NT_SUCCESS(Status)) { - DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n"); - DevMode.dmDriverExtra = 0; + /* Store the settings */ + RegWriteDisplaySettings(hkey, pdm); + + /* Close the registry key */ + ZwClose(hkey); } - lpSafeDevMode = &DevMode; + else + { + DPRINT1("Could not open registry key\n"); + lResult = DISP_CHANGE_NOTUPDATED; + } + } + + /* Check if DEVMODE matches the current mode */ + if (pdm == ppdev->pdmwDev && !(flags & CDS_RESET)) + { + DPRINT1("DEVMODE matches, nothing to do\n"); + goto leave; + } + + /* Shall we apply the settings? */ + if (!(flags & CDS_NORESET)) + { + ULONG ulResult; + + /* Remove mouse pointer */ + UserSetCursor(NULL, TRUE); + + /* Do the mode switch */ + ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm); + + /* Restore mouse pointer, no hooks called */ + UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE); + + /* Check for failure */ + if (!ulResult) + { + DPRINT1("failed to set mode\n"); + lResult = (lResult == DISP_CHANGE_NOTUPDATED) ? + DISP_CHANGE_FAILED : DISP_CHANGE_RESTART; + + goto leave; + } + + /* Update the system metrics */ + InitMetrics(); + + //IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps); + + /* Remove all cursor clipping */ + UserClipCursor(NULL); + + pdesk = IntGetActiveDesktop(); + //IntHideDesktop(pdesk); + + /* Send WM_DISPLAYCHANGE to all toplevel windows */ + co_IntSendMessageTimeout(HWND_BROADCAST, + WM_DISPLAYCHANGE, + (WPARAM)ppdev->gdiinfo.cBitsPixel, + (LPARAM)(ppdev->gdiinfo.ulHorzRes + (ppdev->gdiinfo.ulVertRes << 16)), + SMTO_NORMAL, + 100, + &ulResult); + + //co_IntShowDesktop(pdesk, ppdev->gdiinfo.ulHorzRes, ppdev->gdiinfo.ulVertRes); + + UserRedrawDesktop(); + } + +leave: + /* Release the PDEV */ + PDEVOBJ_vRelease(ppdev); + + return lResult; +} + +LONG +APIENTRY +NtUserChangeDisplaySettings( + PUNICODE_STRING pustrDevice, + LPDEVMODEW lpDevMode, + HWND hwnd, + DWORD dwflags, + LPVOID lParam) +{ + WCHAR awcDevice[CCHDEVICENAME]; + UNICODE_STRING ustrDevice; + DEVMODEW dmLocal; + LONG lRet; + + /* Check arguments */ + if ((dwflags != CDS_VIDEOPARAMETERS && lParam != NULL) || + (hwnd != NULL)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return DISP_CHANGE_BADPARAM; + } + + /* Check flags */ + if ((dwflags & (CDS_GLOBAL|CDS_NORESET)) && !(dwflags & CDS_UPDATEREGISTRY)) + { + return DISP_CHANGE_BADFLAGS; } /* Copy the device name */ - if (lpszDeviceName != NULL) + if (pustrDevice) { - Status = IntSafeCopyUnicodeString(&SafeDeviceName, lpszDeviceName); - if (!NT_SUCCESS(Status)) + /* Initialize destination string */ + RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); + + _SEH2_TRY { - SetLastNtError(Status); - return DISP_CHANGE_BADPARAM; + /* Probe the UNICODE_STRING and the buffer */ + ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); + ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); + + /* Copy the string */ + RtlCopyUnicodeString(&ustrDevice, pustrDevice); } - pSafeDeviceName = &SafeDeviceName; + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Set and return error */ + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return DISP_CHANGE_BADPARAM); + } + _SEH2_END + + pustrDevice = &ustrDevice; + } + + /* Copy devmode */ + if (lpDevMode) + { + _SEH2_TRY + { + /* Probe the size field of the structure */ + ProbeForRead(lpDevMode, sizeof(dmLocal.dmSize), 1); + + /* Calculate usable size */ + dmLocal.dmSize = min(sizeof(dmLocal), lpDevMode->dmSize); + + /* Probe and copy the full DEVMODE */ + ProbeForRead(lpDevMode, dmLocal.dmSize, 1); + RtlCopyMemory(&dmLocal, lpDevMode, dmLocal.dmSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Set and return error */ + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return DISP_CHANGE_BADPARAM); + } + _SEH2_END + + /* Check for extra parameters */ + if (dmLocal.dmDriverExtra > 0) + { + /* FIXME: TODO */ + DPRINT1("lpDevMode->dmDriverExtra is IGNORED!\n"); + dmLocal.dmDriverExtra = 0; + } + + /* Use the local structure */ + lpDevMode = &dmLocal; } + // FIXME: Copy videoparameters + + /* Acquire global USER lock */ + UserEnterExclusive(); + /* Call internal function */ - Ret = IntChangeDisplaySettings(pSafeDeviceName, lpSafeDevMode, dwflags, lParam); + lRet = UserChangeDisplaySettings(pustrDevice, lpDevMode, hwnd, dwflags, NULL); - if (pSafeDeviceName != NULL) - RtlFreeUnicodeString(pSafeDeviceName); + /* Release lock */ + UserLeave(); - return Ret; + return lRet; } diff --git a/subsystems/win32/win32k/ntuser/event.c b/subsystems/win32/win32k/ntuser/event.c index 02d2ffeb2a2..e768c2e09d0 100644 --- a/subsystems/win32/win32k/ntuser/event.c +++ b/subsystems/win32/win32k/ntuser/event.c @@ -2,7 +2,7 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Window event handlers - * FILE: subsystem/win32/win32k/ntuser/event.c + * FILE: subsystems/win32/win32k/ntuser/event.c * PROGRAMER: James Tabor (james.tabor@rectos.org) */ @@ -103,12 +103,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH, LONG idChild) { NTSTATUS Status; - ULONG_PTR uResult; - EVENTPACK EP; + PEVENTPACK pEP; + ULONG_PTR uResult = 0; - EP.pEH = pEH; - EP.idObject = idObject; - EP.idChild = idChild; + pEP = ExAllocatePoolWithTag(NonPagedPool, sizeof(EVENTPACK), TAG_HOOK); + if (!pEP) return 0; + + pEP->pEH = pEH; + pEP->idObject = idObject; + pEP->idChild = idChild; /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ @@ -116,16 +119,18 @@ IntCallLowLevelEvent( PEVENTHOOK pEH, hwnd, event, 0, - (LPARAM)&EP, + (LPARAM)pEP, 5000, TRUE, MSQ_ISEVENT, &uResult); - + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(pEP, TAG_HOOK); + } return NT_SUCCESS(Status) ? uResult : 0; } - static BOOL FASTCALL @@ -145,14 +150,49 @@ IntRemoveEvent(PEVENTHOOK pEH) return FALSE; } +VOID +FASTCALL +EVENT_DestroyThreadEvents(PETHREAD Thread) +{ + PTHREADINFO pti; + PEVENTHOOK pEH; + PLIST_ENTRY pLE; + + pti = Thread->Tcb.Win32Thread; + if (!pti) return; + + if (!GlobalEvents || !GlobalEvents->Counts) return; + + pLE = GlobalEvents->Events.Flink; + if (IsListEmpty(pLE)) return; + + pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); + do + { + if (IsListEmpty(pLE)) break; + if (!pEH) break; + pLE = pEH->Chain.Flink; + if (pEH->head.pti == pti) + { + IntRemoveEvent(pEH); + } + pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); + } while (pLE != &GlobalEvents->Events); + + return; +} + /* FUNCTIONS *****************************************************************/ +// +// Dispatch MsgQueue Event Call processor! +// LRESULT FASTCALL co_EVENT_CallEvents( DWORD event, - HWND hwnd, - UINT_PTR idObject, - LONG_PTR idChild) + HWND hwnd, + UINT_PTR idObject, + LONG_PTR idChild) { PEVENTHOOK pEH; LRESULT Result; @@ -165,9 +205,11 @@ co_EVENT_CallEvents( DWORD event, hwnd, pEP->idObject, pEP->idChild, - (DWORD_PTR)(NtCurrentTeb()->ClientId).UniqueThread, + PtrToUint(NtCurrentTeb()->ClientId.UniqueThread), (DWORD)EngGetTickCount(), pEH->Proc); + + ExFreePoolWithTag(pEP, TAG_HOOK); return Result; } @@ -177,55 +219,66 @@ IntNotifyWinEvent( DWORD Event, PWND pWnd, LONG idObject, - LONG idChild) + LONG idChild, + DWORD flags) { PEVENTHOOK pEH; PLIST_ENTRY pLE; + PTHREADINFO pti, ptiCurrent; DPRINT("IntNotifyWinEvent GlobalEvents = 0x%x pWnd 0x%x\n",GlobalEvents, pWnd); - if (!pWnd) return; + if (!GlobalEvents || !GlobalEvents->Counts) return; if (pWnd && pWnd->state & WNDS_DESTROYED) return; - if (!GlobalEvents || !GlobalEvents->Counts) return; + ptiCurrent = PsGetCurrentThreadWin32Thread(); + + if (pWnd && flags & WEF_SETBYWNDPTI) + pti = pWnd->head.pti; + else + pti = ptiCurrent; pLE = GlobalEvents->Events.Flink; pEH = CONTAINING_RECORD(pLE, EVENTHOOK, Chain); do - { + { + if (!pEH) break; UserReferenceObject(pEH); // Must be inside the event window. if ( (pEH->eventMin <= Event) && (pEH->eventMax >= Event)) { - if (pEH->head.pti->pEThread != PsGetCurrentThread()) - { // if all process || all thread || other thread same process - if (!(pEH->idProcess) || !(pEH->idThread) || - (NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess)) +// if all process || all thread || other thread same process +// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process) + if ( (!pEH->idProcess || pEH->idProcess == PtrToUint(pti->pEThread->Cid.UniqueProcess)) && + (!(pEH->Flags & WINEVENT_SKIPOWNPROCESS) || pEH->head.pti->ppi != pti->ppi) && + (!pEH->idThread || pEH->idThread == PtrToUint(pti->pEThread->Cid.UniqueThread)) && + (!(pEH->Flags & WINEVENT_SKIPOWNTHREAD) || pEH->head.pti != pti) && + pEH->head.pti->rpdesk == ptiCurrent->rpdesk ) // Same as hooks. + { + // Send message to the thread if pEH is not current. + if (pEH->head.pti != ptiCurrent) { + DPRINT1("Global Event 0x%x, idObject %d\n", Event, idObject); IntCallLowLevelEvent( pEH, Event, UserHMGetHandle(pWnd), idObject, idChild); } - }// if ^skip own thread && ((Pid && CPid == Pid && ^skip own process) || all process) - else if ( !(pEH->Flags & WINEVENT_SKIPOWNTHREAD) && - ( ((pEH->idProcess && - NtCurrentTeb()->ClientId.UniqueProcess == (PVOID)(DWORD_PTR)pEH->idProcess) && - !(pEH->Flags & WINEVENT_SKIPOWNPROCESS)) || - !pEH->idProcess ) ) - { - // What in the deuce is this right-aligned formatting? - co_IntCallEventProc( UserHMGetHandle(pEH), - Event, - UserHMGetHandle(pWnd), - idObject, - idChild, - PtrToUint(NtCurrentTeb()->ClientId.UniqueThread), - (DWORD)EngGetTickCount(), - pEH->Proc); - } + else + { + DPRINT1("Local Event 0x%x, idObject %d\n", Event, idObject); + co_IntCallEventProc( UserHMGetHandle(pEH), + Event, + UserHMGetHandle(pWnd), + idObject, + idChild, + PtrToUint(NtCurrentTeb()->ClientId.UniqueThread), + (DWORD)EngGetTickCount(), + pEH->Proc); + } + } } UserDereferenceObject(pEH); pLE = pEH->Chain.Flink; @@ -246,17 +299,21 @@ NtUserNotifyWinEvent( UserEnterExclusive(); /* Validate input */ - if (hWnd && (hWnd != INVALID_HANDLE_VALUE) && !(Window = UserGetWindowObject(hWnd))) + if (hWnd && (hWnd != INVALID_HANDLE_VALUE)) { - UserLeave(); - return; + Window = UserGetWindowObject(hWnd); + if (!Window) + { + UserLeave(); + return; + } } if (gpsi->dwInstalledEventHooks & GetMaskFromEvent(Event)) { - UserRefObjectCo(Window, &Ref); - IntNotifyWinEvent( Event, Window, idObject, idChild); - UserDerefObjectCo(Window); + if (Window) UserRefObjectCo(Window, &Ref); + IntNotifyWinEvent( Event, Window, idObject, idChild, WEF_SETBYWNDPTI); + if (Window) UserDerefObjectCo(Window); } UserLeave(); } @@ -322,7 +379,7 @@ NtUserSetWinEventHook( goto SetEventExit; } } - + // Creator, pti is set here. pEH = UserCreateObject(gHandleTable, NULL, &Handle, otEvent, sizeof(EVENTHOOK)); if (pEH) { @@ -330,16 +387,18 @@ NtUserSetWinEventHook( GlobalEvents->Counts++; UserHMGetHandle(pEH) = Handle; - if (Thread) - pEH->head.pti = Thread->Tcb.Win32Thread; - else - pEH->head.pti = GetW32ThreadInfo(); pEH->eventMin = eventMin; pEH->eventMax = eventMax; - pEH->idProcess = idProcess; - pEH->idThread = idThread; + pEH->idProcess = idProcess; // These are cmp'ed + pEH->idThread = idThread; // " pEH->Flags = dwflags; - + /* + If WINEVENT_INCONTEXT, set offset from hmod and proc. Save ihmod from + the atom index table where the hmod data is saved to be recalled later + if fSync set by WINEVENT_INCONTEXT. + If WINEVENT_OUTOFCONTEXT just use proc.. + Do this instead.... + */ if (NULL != hmodWinEventProc) { pEH->offPfn = (ULONG_PTR)((char *)lpfnWinEventProc - (char *)hmodWinEventProc); diff --git a/subsystems/win32/win32k/ntuser/focus.c b/subsystems/win32/win32k/ntuser/focus.c index 5832eaf41ad..414b1523bf7 100644 --- a/subsystems/win32/win32k/ntuser/focus.c +++ b/subsystems/win32/win32k/ntuser/focus.c @@ -165,6 +165,7 @@ co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd) { if (hWndPrev) { + IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0); co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0); } } @@ -174,6 +175,8 @@ co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd) { if (hWnd) { + PWND pWnd = UserGetWindowObject(hWnd); + IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0); co_IntPostOrSendMessage(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 0); } } @@ -356,8 +359,10 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL) cbt.fMouse = FALSE; cbt.hWndActive = hWndPrev; if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) + { + DPRINT1("SetActiveWindow WH_CBT Call Hook return!\n"); return 0; - + } ThreadQueue->ActiveWindow = hWnd; co_IntSendDeactivateMessages(hWndPrev, hWnd); @@ -392,9 +397,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL) return hWndPrev; } - if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) - return 0; - + if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) + { + DPRINT1("SetFocusWindow 1 WH_CBT Call Hook return!\n"); + return 0; + } ThreadQueue->FocusWindow = Window->head.h; co_IntSendKillFocusMessages(hWndPrev, Window->head.h); @@ -403,9 +410,11 @@ co_IntSetFocusWindow(PWND Window OPTIONAL) else { ThreadQueue->FocusWindow = 0; - - if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) - return 0; + if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) + { + DPRINT1("SetFocusWindow 2 WH_CBT Call Hook return!\n"); + return 0; + } co_IntSendKillFocusMessages(hWndPrev, 0); } @@ -533,7 +542,7 @@ NtUserSetCapture(HWND hWnd) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; - PWND Window; + PWND Window, pWnd; HWND hWndPrev; DECLARE_RETURN(HWND); @@ -553,13 +562,23 @@ NtUserSetCapture(HWND hWnd) hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd); + if (hWndPrev) + { + pWnd = UserGetWindowObject(hWndPrev); + if (pWnd) + IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + } + /* also remove other windows if not capturing anymore */ - if(hWnd == NULL) + if (hWnd == NULL) { MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL); MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL); } + if (Window) + IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd); ThreadQueue->CaptureWindow = hWnd; diff --git a/subsystems/win32/win32k/ntuser/hook.c b/subsystems/win32/win32k/ntuser/hook.c index 6b6df548973..ed2a30e6271 100644 --- a/subsystems/win32/win32k/ntuser/hook.c +++ b/subsystems/win32/win32k/ntuser/hook.c @@ -2,8 +2,10 @@ * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: Window hooks - * FILE: subsystem/win32/win32k/ntuser/hook.c + * FILE: subsystems/win32/win32k/ntuser/hook.c * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) + * James Tabor (james.tabor@rectos.org) + * * REVISION HISTORY: * 06-06-2001 CSH Created * NOTE: Most of this code was adapted from Wine, @@ -15,474 +17,117 @@ #define NDEBUG #include -static PHOOKTABLE GlobalHooks; - +typedef struct _HOOKPACK +{ + PHOOK pHk; + LPARAM lParam; +} HOOKPACK, *PHOOKPACK; /* PRIVATE FUNCTIONS *********************************************************/ - -/* create a new hook table */ -static -PHOOKTABLE -IntAllocHookTable(void) -{ - PHOOKTABLE Table; - UINT i; - - Table = ExAllocatePoolWithTag(PagedPool, sizeof(HOOKTABLE), TAG_HOOK); - if (NULL != Table) - { - for (i = 0; i < NB_HOOKS; i++) - { - InitializeListHead(&Table->Hooks[i]); - Table->Counts[i] = 0; - } - } - - return Table; -} - - -PHOOK -FASTCALL -IntGetHookObject(HHOOK hHook) -{ - PHOOK Hook; - - if (!hHook) - { - SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); - return NULL; - } - - Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook); - if (!Hook) - { - SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); - return NULL; - } - - ASSERT(Hook->head.cLockObj >= 0); - - Hook->head.cLockObj++; - - return Hook; -} - - - -/* create a new hook and add it to the specified table */ -static -PHOOK -IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinStaObj) -{ - PTHREADINFO W32Thread; - PHOOK Hook; - PHOOKTABLE Table = Global ? GlobalHooks : MsqGetHooks(((PTHREADINFO)Thread->Tcb.Win32Thread)->MessageQueue); - HANDLE Handle; - - if (NULL == Table) - { - Table = IntAllocHookTable(); - if (NULL == Table) - { - return NULL; - } - if (Global) - { - GlobalHooks = Table; - } - else - { - MsqSetHooks(((PTHREADINFO)Thread->Tcb.Win32Thread)->MessageQueue, Table); - } - } - - Hook = UserCreateObject(gHandleTable, NULL, &Handle, otHook, sizeof(HOOK)); - if (NULL == Hook) - { - return NULL; - } - - Hook->Thread = Thread; - Hook->HookId = HookId; - - if (Thread) - { - W32Thread = ((PTHREADINFO)Thread->Tcb.Win32Thread); - ASSERT(W32Thread != NULL); - W32Thread->fsHooks |= HOOKID_TO_FLAG(HookId); - - if (W32Thread->pClientInfo) - W32Thread->pClientInfo->fsHooks = W32Thread->fsHooks; - - if (W32Thread->pDeskInfo) // Do this for now. - W32Thread->pDeskInfo->fsHooks= W32Thread->fsHooks; - - Hook->head.pti = W32Thread; - Hook->head.rpdesk = W32Thread->rpdesk; - } - - RtlInitUnicodeString(&Hook->ModuleName, NULL); - - InsertHeadList(&Table->Hooks[HOOKID_TO_INDEX(HookId)], &Hook->Chain); - - return Hook; -} - -/* get the hook table that a given hook belongs to */ -static -PHOOKTABLE -FASTCALL -IntGetTable(PHOOK Hook) -{ - if (NULL == Hook->Thread || WH_KEYBOARD_LL == Hook->HookId || - WH_MOUSE_LL == Hook->HookId) - { - return GlobalHooks; - } - - return MsqGetHooks(((PTHREADINFO)Hook->Thread->Tcb.Win32Thread)->MessageQueue); -} - -/* get the first hook in the chain */ -static -PHOOK -FASTCALL -IntGetFirstHook(PHOOKTABLE Table, int HookId) -{ - PLIST_ENTRY Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - - return Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)] - ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain); -} - -/* find the first non-deleted hook in the chain */ -static -PHOOK -FASTCALL -IntGetFirstValidHook(PHOOKTABLE Table, int HookId) -{ - PHOOK Hook; - PLIST_ENTRY Elem; - - Hook = IntGetFirstHook(Table, HookId); - - while (NULL != Hook && NULL == Hook->Proc) - { - Elem = Hook->Chain.Flink; - Hook = (Elem == &Table->Hooks[HOOKID_TO_INDEX(HookId)] - ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain)); - } - - return Hook; -} - -/* find the next hook in the chain, skipping the deleted ones */ -PHOOK -FASTCALL -IntGetNextHook(PHOOK Hook) -{ - PHOOKTABLE Table = IntGetTable(Hook); - int HookId = Hook->HookId; - PLIST_ENTRY Elem; - - Elem = Hook->Chain.Flink; - while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)]) - { - Hook = CONTAINING_RECORD(Elem, HOOK, Chain); - if (NULL != Hook->Proc) - { - return Hook; - } - } - - if (NULL != GlobalHooks && Table != GlobalHooks) /* now search through the global table */ - { - return IntGetFirstValidHook(GlobalHooks, HookId); - } - - return NULL; -} - -/* free a hook, removing it from its chain */ -static -VOID -FASTCALL -IntFreeHook(PHOOKTABLE Table, PHOOK Hook, PWINSTATION_OBJECT WinStaObj) -{ - RemoveEntryList(&Hook->Chain); - RtlFreeUnicodeString(&Hook->ModuleName); - - /* Dereference thread if required */ - if (Hook->Flags & HOOK_THREAD_REFERENCED) - { - ObDereferenceObject(Hook->Thread); - } - - /* Close handle */ - UserDeleteObject(UserHMGetHandle(Hook), otHook); -} - -/* remove a hook, freeing it if the chain is not in use */ -static -VOID -IntRemoveHook(PHOOK Hook, PWINSTATION_OBJECT WinStaObj, BOOL TableAlreadyLocked) -{ - PTHREADINFO W32Thread; - PHOOKTABLE Table = IntGetTable(Hook); - - ASSERT(NULL != Table); // At this point this should not be null! - - W32Thread = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread); - ASSERT(W32Thread != NULL); - W32Thread->fsHooks &= ~HOOKID_TO_FLAG(Hook->HookId); - - GetWin32ClientInfo()->fsHooks = W32Thread->fsHooks; - - if (W32Thread->pDeskInfo) // Do this for now. - W32Thread->pDeskInfo->fsHooks= W32Thread->fsHooks; - - if (0 != Table->Counts[HOOKID_TO_INDEX(Hook->HookId)]) - { - Hook->Proc = NULL; /* chain is in use, just mark it and return */ - } - else - { - IntFreeHook(Table, Hook, WinStaObj); - } -} - -/* release a hook chain, removing deleted hooks if the use count drops to 0 */ -static -VOID -FASTCALL -IntReleaseHookChain(PHOOKTABLE Table, int HookId, PWINSTATION_OBJECT WinStaObj) -{ - PLIST_ENTRY Elem; - PHOOK HookObj; - - if (NULL == Table) - { - return; - } - - /* use count shouldn't already be 0 */ - ASSERT(0 != Table->Counts[HOOKID_TO_INDEX(HookId)]); - - if (0 == Table->Counts[HOOKID_TO_INDEX(HookId)]) - { - return; - } - - if (0 == --Table->Counts[HOOKID_TO_INDEX(HookId)]) - { - Elem = Table->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - - while (Elem != &Table->Hooks[HOOKID_TO_INDEX(HookId)]) - { - HookObj = CONTAINING_RECORD(Elem, HOOK, Chain); - Elem = Elem->Flink; - - if (NULL == HookObj->Proc) - { - IntFreeHook(Table, HookObj, WinStaObj); - } - } - } -} - static LRESULT FASTCALL -IntCallLowLevelHook(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam) +IntCallLowLevelHook( PHOOK Hook, + INT Code, + WPARAM wParam, + LPARAM lParam) { NTSTATUS Status; - ULONG_PTR uResult; + PTHREADINFO pti; + PHOOKPACK pHP; + ULONG_PTR uResult = 0; + + if (Hook->Thread) + pti = Hook->Thread->Tcb.Win32Thread; + else + pti = Hook->head.pti; + + pHP = ExAllocatePoolWithTag(NonPagedPool, sizeof(HOOKPACK), TAG_HOOK); + if (!pHP) return 0; + + pHP->pHk = Hook; + pHP->lParam = lParam; /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage(((PTHREADINFO)Hook->Thread->Tcb.Win32Thread)->MessageQueue, - IntToPtr(Code), - Hook->HookId, + Status = co_MsqSendMessage( pti->MessageQueue, + IntToPtr(Code), // hWnd + Hook->HookId, // Msg wParam, - lParam, + (LPARAM)pHP, 5000, TRUE, MSQ_ISHOOK, - &uResult); - - return NT_SUCCESS(Status) ? uResult : 0; -} - -/* - Called from inside kernel space. - */ -LRESULT -FASTCALL -co_HOOK_CallHooks(INT HookId, INT Code, WPARAM wParam, LPARAM lParam) -{ - PHOOK Hook, SaveHook; - PTHREADINFO pti; - PCLIENTINFO ClientInfo; - PHOOKTABLE Table; - LRESULT Result; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; - - ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK); - -#if 0 - /* FIXME! Check pDeskInfo->fsHooks for global hooks! */ - if (!ISITHOOKED(HookId)) - { - return 0; - } -#endif - - pti = PsGetCurrentThreadWin32Thread(); - if (!pti) - { - Table = NULL; - } - else - { - Table = MsqGetHooks(pti->MessageQueue); - } - - if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId))) - { - /* try global table */ - Table = GlobalHooks; - if (NULL == Table || ! (Hook = IntGetFirstValidHook(Table, HookId))) - { - return 0; /* no hook set */ - } - } - - if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)) - { - DPRINT1("\nHook found by Id and posted to Thread! %d\n",HookId ); - /* Post it in message queue. */ - return IntCallLowLevelHook(Hook, Code, wParam, lParam); - } - - Table->Counts[HOOKID_TO_INDEX(HookId)]++; - if (Table != GlobalHooks && GlobalHooks != NULL) - { - GlobalHooks->Counts[HOOKID_TO_INDEX(HookId)]++; - } - - ClientInfo = GetWin32ClientInfo(); - SaveHook = ClientInfo->phkCurrent; - ClientInfo->phkCurrent = Hook; /* Load the call. */ - - Result = co_IntCallHookProc(HookId, - Code, - wParam, - lParam, - Hook->Proc, - Hook->Ansi, - &Hook->ModuleName); - - ClientInfo->phkCurrent = SaveHook; - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - + &uResult); if (!NT_SUCCESS(Status)) { - DPRINT1("Invalid window station????\n"); - } - else - { - IntReleaseHookChain(MsqGetHooks(pti->MessageQueue), HookId, WinStaObj); - IntReleaseHookChain(GlobalHooks, HookId, WinStaObj); - ObDereferenceObject(WinStaObj); - } - - return Result; -} - -VOID -FASTCALL -HOOK_DestroyThreadHooks(PETHREAD Thread) -{ - int HookId; - PLIST_ENTRY Elem; - PHOOK HookObj; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; - - if (NULL != GlobalHooks) - { - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Invalid window station????\n"); - return; - } - - for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) - { - /* only low-level keyboard/mouse global hooks can be owned by a thread */ - switch(HookId) - { - case WH_KEYBOARD_LL: - case WH_MOUSE_LL: - Elem = GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)].Flink; - - while (Elem != &GlobalHooks->Hooks[HOOKID_TO_INDEX(HookId)]) - { - HookObj = CONTAINING_RECORD(Elem, HOOK, Chain); - Elem = Elem->Flink; - - if (HookObj->Thread == Thread) - { - IntRemoveHook(HookObj, WinStaObj, TRUE); - } - } - break; - } - } + DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status); + ExFreePoolWithTag(pHP, TAG_HOOK); } + return NT_SUCCESS(Status) ? uResult : 0; } static LRESULT FASTCALL -co_HOOK_CallHookNext(PHOOK Hook, INT Code, WPARAM wParam, LPARAM lParam) +co_HOOK_CallHookNext( PHOOK Hook, + INT Code, + WPARAM wParam, + LPARAM lParam) { - if ((Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL)) + if ( (Hook->Thread != PsGetCurrentThread()) && (Hook->Thread != NULL) ) { - DPRINT1("CALLING HOOK from another Thread. %d\n", Hook->HookId); + DPRINT1("Calling Next HOOK from another Thread. %d\n", Hook->HookId); return IntCallLowLevelHook(Hook, Code, wParam, lParam); } - DPRINT("CALLING HOOK %d\n", Hook->HookId); + DPRINT("Calling Next HOOK %d\n", Hook->HookId); - return co_IntCallHookProc(Hook->HookId, - Code, - wParam, - lParam, - Hook->Proc, - Hook->Ansi, + return co_IntCallHookProc( Hook->HookId, + Code, + wParam, + lParam, + Hook->Proc, + Hook->Ansi, &Hook->ModuleName); } +// +// Dispatch MsgQueue Hook Call processor! +// +LRESULT +FASTCALL +co_CallHook( INT HookId, + INT Code, + WPARAM wParam, + LPARAM lParam) +{ + LRESULT Result; + PHOOK phk; + PHOOKPACK pHP = (PHOOKPACK)lParam; + + phk = pHP->pHk; + /* The odds are high for this to be a Global call. */ + Result = co_IntCallHookProc( HookId, + Code, + wParam, + pHP->lParam, + phk->Proc, + phk->Ansi, + &phk->ModuleName); + + ExFreePoolWithTag(pHP, TAG_HOOK); + return Result; +} LRESULT FASTCALL -IntCallDebugHook(PHOOK Hook, - int Code, - WPARAM wParam, - LPARAM lParam) +IntCallDebugHook( PHOOK Hook, + int Code, + WPARAM wParam, + LPARAM lParam, + BOOL Ansi) { LRESULT lResult = 0; ULONG Size; @@ -608,16 +253,13 @@ IntCallDebugHook(PHOOK Hook, return lResult; } -/* - Called from user space via CallNextHook. - */ LRESULT FASTCALL -UserCallNextHookEx(PHOOK Hook, - int Code, - WPARAM wParam, - LPARAM lParam, - BOOL Ansi) +UserCallNextHookEx( PHOOK Hook, + int Code, + WPARAM wParam, + LPARAM lParam, + BOOL Ansi) { LRESULT lResult = 0; BOOL BadChk = FALSE; @@ -940,7 +582,11 @@ UserCallNextHookEx(PHOOK Hook, break; } break; - +/* + Note WH_JOURNALPLAYBACK, + "To have the system wait before processing the message, the return value + must be the amount of time, in clock ticks, that the system should wait." + */ case WH_JOURNALPLAYBACK: case WH_JOURNALRECORD: { @@ -1002,7 +648,7 @@ UserCallNextHookEx(PHOOK Hook, } case WH_DEBUG: - lResult = IntCallDebugHook(Hook, Code, wParam, lParam); + lResult = IntCallDebugHook(Hook, Code, wParam, lParam, Ansi); break; /* @@ -1018,70 +664,451 @@ UserCallNextHookEx(PHOOK Hook, DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId); break; } - return lResult; } +PHOOK +FASTCALL +IntGetHookObject(HHOOK hHook) +{ + PHOOK Hook; + + if (!hHook) + { + SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); + return NULL; + } + + Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook); + if (!Hook) + { + SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); + return NULL; + } + + UserReferenceObject(Hook); + + return Hook; +} + +/* get the first hook in the chain */ +static +PHOOK +FASTCALL +IntGetFirstHook(PLIST_ENTRY Table) +{ + PLIST_ENTRY Elem = Table->Flink; + + if (IsListEmpty(Table)) return NULL; + + return Elem == Table ? NULL : CONTAINING_RECORD(Elem, HOOK, Chain); +} + +/* find the next hook in the chain */ +PHOOK +FASTCALL +IntGetNextHook(PHOOK Hook) +{ + int HookId = Hook->HookId; + PLIST_ENTRY Elem; + PTHREADINFO pti; + + if (Hook->Thread) + { + pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread); + + Elem = Hook->Chain.Flink; + if (Elem != &pti->aphkStart[HOOKID_TO_INDEX(HookId)]) + return CONTAINING_RECORD(Elem, HOOK, Chain); + } + else + { + pti = PsGetCurrentThreadWin32Thread(); + + Elem = Hook->Chain.Flink; + if (Elem != &pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) + return CONTAINING_RECORD(Elem, HOOK, Chain); + } + return NULL; +} + +/* free a hook, removing it from its chain */ +static +VOID +FASTCALL +IntFreeHook(PHOOK Hook) +{ + RemoveEntryList(&Hook->Chain); + if (Hook->ModuleName.Buffer) + { + ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK); + Hook->ModuleName.Buffer = NULL; + } + /* Close handle */ + UserDeleteObject(UserHMGetHandle(Hook), otHook); +} + +/* remove a hook, freeing it from the chain */ +static +BOOL +FASTCALL +IntRemoveHook(PHOOK Hook) +{ + INT HookId; + PTHREADINFO pti; + + HookId = Hook->HookId; + + if (Hook->Thread) // Local + { + pti = ((PTHREADINFO)Hook->Thread->Tcb.Win32Thread); + + IntFreeHook( Hook); + + if ( IsListEmpty(&pti->aphkStart[HOOKID_TO_INDEX(HookId)]) ) + { + pti->fsHooks &= ~HOOKID_TO_FLAG(HookId); + _SEH2_TRY + { + GetWin32ClientInfo()->fsHooks = pti->fsHooks; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + return TRUE; + } + } + else // Global + { + IntFreeHook( Hook); + + pti = PsGetCurrentThreadWin32Thread(); + + if ( pti->rpdesk && + pti->rpdesk->pDeskInfo && + IsListEmpty(&pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]) ) + { + pti->rpdesk->pDeskInfo->fsHooks &= ~HOOKID_TO_FLAG(HookId); + return TRUE; + } + } + return FALSE; +} + +VOID +FASTCALL +HOOK_DestroyThreadHooks(PETHREAD Thread) +{ + PTHREADINFO pti; + int HookId; + PHOOK HookObj; + PLIST_ENTRY pElem; + + pti = Thread->Tcb.Win32Thread; + if (!pti || !pti->pDeskInfo) return; + +// Local Thread cleanup. + if (pti->fsHooks) + { + for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) + { + PLIST_ENTRY pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)]; + + if (IsListEmpty(pLLE)) continue; + + pElem = pLLE->Flink; + HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); + do + { + if (!HookObj) break; + if (IntRemoveHook(HookObj)) break; + pElem = HookObj->Chain.Flink; + HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); + } + while (pElem != pLLE); + } + pti->fsHooks = 0; + } +// Global search based on Thread and cleanup. + if (pti->rpdesk->pDeskInfo->fsHooks) + { + for (HookId = WH_MINHOOK; HookId <= WH_MAXHOOK; HookId++) + { + PLIST_ENTRY pGLE = &pti->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]; + + if (IsListEmpty(pGLE)) continue; + + pElem = pGLE->Flink; + HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); + do + { + if (!HookObj) break; + if (HookObj->head.pti == pti) + { + if (IntRemoveHook(HookObj)) break; + } + pElem = HookObj->Chain.Flink; + HookObj = CONTAINING_RECORD(pElem, HOOK, Chain); + } + while (pElem != pGLE); + } + } + return; +} + +/* + Win32k Kernel Space Hook Caller. + */ +LRESULT +FASTCALL +co_HOOK_CallHooks( INT HookId, + INT Code, + WPARAM wParam, + LPARAM lParam) +{ + PHOOK Hook, SaveHook; + PTHREADINFO pti; + PCLIENTINFO ClientInfo; + PLIST_ENTRY pLLE, pGLE; + BOOL Local = FALSE, Global = FALSE; + LRESULT Result = 0; + + ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK); + + pti = PsGetCurrentThreadWin32Thread(); + if (!pti || !pti->rpdesk || !pti->rpdesk->pDeskInfo) + goto Exit; // Must have a desktop running for hooks. + + if ( pti->TIF_flags & TIF_INCLEANUP) + goto Exit; + + if ( ISITHOOKED(HookId) ) + { + DPRINT("Local Hooker %d\n", HookId); + Local = TRUE; + } + + if ( pti->rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(HookId) ) + { + DPRINT("Global Hooker %d\n", HookId); + Global = TRUE; + } + + if ( !Local && !Global ) goto Exit; // No work! + + pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)]; + pGLE = &pti->rpdesk->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)]; + Hook = NULL; + + /* SetWindowHookEx sorts out the Thread issue by placing the Hook to + the correct Thread if not NULL. + */ + if ( Local ) + { + Hook = IntGetFirstHook(pLLE); + if (!Hook) + { + DPRINT1("No Local Hook Found!\n"); + goto Exit; + } + ObReferenceObject(Hook->Thread); + + ClientInfo = pti->pClientInfo; + SaveHook = pti->sphkCurrent; + + /* Load it for the next call. */ + pti->sphkCurrent = Hook; + Hook->phkNext = IntGetNextHook(Hook); + if (ClientInfo) + { + _SEH2_TRY + { + ClientInfo->phkCurrent = Hook; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ClientInfo = NULL; // Don't bother next run. + } + _SEH2_END; + } + Result = co_IntCallHookProc( HookId, + Code, + wParam, + lParam, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); + if (ClientInfo) + { + _SEH2_TRY + { + ClientInfo->phkCurrent = SaveHook; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + } + _SEH2_END; + } + pti->sphkCurrent = SaveHook; + Hook->phkNext = NULL; + ObDereferenceObject(Hook->Thread); + } + + if ( Global ) + { + PTHREADINFO ptiHook; + + Hook = IntGetFirstHook(pGLE); + if (!Hook) + { + DPRINT1("No Global Hook Found!\n"); + goto Exit; + } + /* Performance goes down the drain. If more hooks are associated to this + * hook ID, this will have to post to each of the thread message queues + * or make a direct call. + */ + do + { + /* Hook->Thread is null, we hax around this with Hook->head.pti. */ + ptiHook = Hook->head.pti; + + /* "Global hook monitors messages for all threads in the same desktop + * as the calling thread." + */ + if ( ptiHook->TIF_flags & TIF_INCLEANUP || + ptiHook->rpdesk != pti->rpdesk) + { + Hook = IntGetNextHook(Hook); + if (!Hook) break; + continue; + } + // Lockup the thread while this links through user world. + ObReferenceObject(ptiHook->pEThread); + if (ptiHook != pti ) + { + DPRINT("\nGlobal Hook posting to another Thread! %d\n",HookId ); + Result = IntCallLowLevelHook(Hook, Code, wParam, lParam); + } + else + { /* Make the direct call. */ + DPRINT("\nLocal Hook calling to Thread! %d\n",HookId ); + Result = co_IntCallHookProc( HookId, + Code, + wParam, + lParam, + Hook->Proc, + Hook->Ansi, + &Hook->ModuleName); + } + ObDereferenceObject(ptiHook->pEThread); + Hook = IntGetNextHook(Hook); + } + while ( Hook ); + DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result); + } +Exit: + return Result; +} + +BOOL +FASTCALL +IntUnhookWindowsHook(int HookId, HOOKPROC pfnFilterProc) +{ + PHOOK Hook; + PLIST_ENTRY pLLE, pLE; + PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); + + if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId ) + { + SetLastWin32Error(ERROR_INVALID_HOOK_FILTER); + return FALSE; + } + + if (pti->fsHooks) + { + pLLE = &pti->aphkStart[HOOKID_TO_INDEX(HookId)]; + + if (IsListEmpty(pLLE)) return FALSE; + + pLE = pLLE->Flink; + Hook = CONTAINING_RECORD(pLE, HOOK, Chain); + do + { + if (!Hook) break; + if (Hook->Proc == pfnFilterProc) + { + if (Hook->head.pti == pti) + { + IntRemoveHook(Hook); + UserDereferenceObject(Hook); + return TRUE; + } + else + { + SetLastWin32Error(ERROR_ACCESS_DENIED); + return FALSE; + } + } + pLE = Hook->Chain.Flink; + Hook = CONTAINING_RECORD(pLE, HOOK, Chain); + } + while (pLE != pLLE); + } + return FALSE; +} + +/* + * Support for compatibility only? Global hooks are processed in kernel space. + * This is very thread specific! Never seeing applications with more than one + * hook per thread installed. Most of the applications are Global hookers and + * associated with just one hook Id. Maybe it's for diagnostic testing or a + * throw back to 3.11? + */ LRESULT APIENTRY -NtUserCallNextHookEx(int Code, - WPARAM wParam, - LPARAM lParam, - BOOL Ansi) +NtUserCallNextHookEx( int Code, + WPARAM wParam, + LPARAM lParam, + BOOL Ansi) { + PTHREADINFO pti; PHOOK HookObj, NextObj; PCLIENTINFO ClientInfo; - PWINSTATION_OBJECT WinStaObj; - NTSTATUS Status; + LRESULT lResult = 0; DECLARE_RETURN(LRESULT); DPRINT("Enter NtUserCallNextHookEx\n"); UserEnterExclusive(); - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( 0); - } + pti = GetW32ThreadInfo(); - ObDereferenceObject(WinStaObj); - - ClientInfo = GetWin32ClientInfo(); - - if (!ClientInfo) RETURN( 0); - - HookObj = ClientInfo->phkCurrent; + HookObj = pti->sphkCurrent; if (!HookObj) RETURN( 0); - /* Check that the first hook in the chain is not this hook */ - NextObj = IntGetFirstHook(IntGetTable(HookObj), HookObj->HookId); + NextObj = HookObj->phkNext; - /* Its the same so it has already been called */ - if (HookObj == NextObj) RETURN(0); - - UserReferenceObject(HookObj); - - Ansi = HookObj->Ansi; - - if (NULL != HookObj->Thread && (HookObj->Thread != PsGetCurrentThread())) + pti->sphkCurrent = NextObj; + ClientInfo = pti->pClientInfo; + _SEH2_TRY { - DPRINT1("Thread mismatch\n"); - UserDereferenceObject(HookObj); - SetLastWin32Error(ERROR_INVALID_HANDLE); - RETURN( 0); + ClientInfo->phkCurrent = NextObj; } - - NextObj = IntGetNextHook(HookObj); - ClientInfo->phkCurrent = NextObj; /* Preset next hook from list. */ - UserCallNextHookEx( HookObj, Code, wParam, lParam, Ansi); - UserDereferenceObject(HookObj); + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ClientInfo = NULL; + } + _SEH2_END; - RETURN( (LRESULT)NextObj); + /* Now in List run down. */ + if (ClientInfo && NextObj) + { + NextObj->phkNext = IntGetNextHook(NextObj); + lResult = UserCallNextHookEx( NextObj, Code, wParam, lParam, NextObj->Ansi); + } + RETURN( lResult); CLEANUP: DPRINT("Leave NtUserCallNextHookEx, ret=%i\n",_ret_); @@ -1091,43 +1118,51 @@ CLEANUP: HHOOK APIENTRY -NtUserSetWindowsHookAW(int idHook, - HOOKPROC lpfn, - BOOL Ansi) +NtUserSetWindowsHookAW( int idHook, + HOOKPROC lpfn, + BOOL Ansi) { + DWORD ThreadId; UNICODE_STRING USModuleName; RtlInitUnicodeString(&USModuleName, NULL); + ThreadId = PtrToUint(NtCurrentTeb()->ClientId.UniqueThread); - return NtUserSetWindowsHookEx(NULL, &USModuleName, 0, idHook, lpfn, Ansi); + return NtUserSetWindowsHookEx( NULL, + &USModuleName, + ThreadId, + idHook, + lpfn, + Ansi); } HHOOK APIENTRY -NtUserSetWindowsHookEx(HINSTANCE Mod, - PUNICODE_STRING UnsafeModuleName, - DWORD ThreadId, - int HookId, - HOOKPROC HookProc, - BOOL Ansi) +NtUserSetWindowsHookEx( HINSTANCE Mod, + PUNICODE_STRING UnsafeModuleName, + DWORD ThreadId, + int HookId, + HOOKPROC HookProc, + BOOL Ansi) { PWINSTATION_OBJECT WinStaObj; - PCLIENTINFO ClientInfo; - BOOLEAN Global; - PETHREAD Thread; PHOOK Hook; UNICODE_STRING ModuleName; NTSTATUS Status; HHOOK Handle; - BOOLEAN ThreadReferenced = FALSE; + PETHREAD Thread = NULL; + PTHREADINFO ptiCurrent, pti = NULL; + BOOL Hit = FALSE; DECLARE_RETURN(HHOOK); DPRINT("Enter NtUserSetWindowsHookEx\n"); UserEnterExclusive(); + ptiCurrent = GetW32ThreadInfo(); + if (HookId < WH_MINHOOK || WH_MAXHOOK < HookId ) { - SetLastWin32Error(ERROR_INVALID_PARAMETER); + SetLastWin32Error(ERROR_INVALID_HOOK_FILTER); RETURN( NULL); } @@ -1137,174 +1172,217 @@ NtUserSetWindowsHookEx(HINSTANCE Mod, RETURN( NULL); } - ClientInfo = GetWin32ClientInfo(); - if (ThreadId) /* thread-local hook */ { - if (HookId == WH_JOURNALRECORD || + if ( HookId == WH_JOURNALRECORD || HookId == WH_JOURNALPLAYBACK || HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL || HookId == WH_SYSMSGFILTER) - { - /* these can only be global */ - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } + { + DPRINT1("Local hook installing Global HookId: %d\n",HookId); + /* these can only be global */ + SetLastWin32Error(ERROR_GLOBAL_ONLY_HOOK); + RETURN( NULL); + } - Mod = NULL; - Global = FALSE; + if (!NT_SUCCESS(PsLookupThreadByThreadId((HANDLE)(DWORD_PTR) ThreadId, &Thread))) + { + DPRINT1("Invalid thread id 0x%x\n", ThreadId); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + RETURN( NULL); + } - if (!NT_SUCCESS(PsLookupThreadByThreadId((HANDLE)(DWORD_PTR) ThreadId, &Thread))) - { - DPRINT1("Invalid thread id 0x%x\n", ThreadId); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } + pti = Thread->Tcb.Win32Thread; - /* Thread was referenced */ - ThreadReferenced = TRUE; - if (Thread->ThreadsProcess != PsGetCurrentProcess()) - { - ObDereferenceObject(Thread); - DPRINT1("Can't specify thread belonging to another process\n"); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - RETURN( NULL); - } + ObDereferenceObject(Thread); + + if ( pti->rpdesk != ptiCurrent->rpdesk) // gptiCurrent->rpdesk) + { + DPRINT1("Local hook wrong desktop HookId: %d\n",HookId); + SetLastWin32Error(ERROR_ACCESS_DENIED); + RETURN( NULL); + } + + if (Thread->ThreadsProcess != PsGetCurrentProcess()) + { + if ( !Mod && + (HookId == WH_GETMESSAGE || + HookId == WH_CALLWNDPROC || + HookId == WH_CBT || + HookId == WH_HARDWARE || + HookId == WH_DEBUG || + HookId == WH_SHELL || + HookId == WH_FOREGROUNDIDLE || + HookId == WH_CALLWNDPROCRET) ) + { + DPRINT1("Local hook needs hMod HookId: %d\n",HookId); + SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD); + RETURN( NULL); + } + + if ( (pti->TIF_flags & (TIF_CSRSSTHREAD|TIF_SYSTEMTHREAD)) && + (HookId == WH_GETMESSAGE || + HookId == WH_CALLWNDPROC || + HookId == WH_CBT || + HookId == WH_HARDWARE || + HookId == WH_DEBUG || + HookId == WH_SHELL || + HookId == WH_FOREGROUNDIDLE || + HookId == WH_CALLWNDPROCRET) ) + { + SetLastWin32Error(ERROR_HOOK_TYPE_NOT_ALLOWED); + RETURN( NULL); + } + } } else /* system-global hook */ { - if (HookId == WH_KEYBOARD_LL || HookId == WH_MOUSE_LL) - { - Mod = NULL; - Thread = PsGetCurrentThread(); - - Status = ObReferenceObjectByPointer(Thread, - THREAD_ALL_ACCESS, - PsThreadType, - KernelMode); - - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( (HANDLE) NULL); - } - - /* Thread was referenced */ - ThreadReferenced = TRUE; - } - else if (NULL == Mod) - { - SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD); - RETURN( NULL); - } - else - { - Thread = NULL; - } - Global = TRUE; + pti = ptiCurrent; // gptiCurrent; + if ( !Mod && + (HookId == WH_GETMESSAGE || + HookId == WH_CALLWNDPROC || + HookId == WH_CBT || + HookId == WH_SYSMSGFILTER || + HookId == WH_HARDWARE || + HookId == WH_DEBUG || + HookId == WH_SHELL || + HookId == WH_FOREGROUNDIDLE || + HookId == WH_CALLWNDPROCRET) ) + { + DPRINT1("Global hook needs hMod HookId: %d\n",HookId); + SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD); + RETURN( NULL); + } } - if ((Global && (HookId != WH_KEYBOARD_LL && HookId != WH_MOUSE_LL)) || - WH_DEBUG == HookId || - WH_JOURNALPLAYBACK == HookId || - WH_JOURNALRECORD == HookId) - { -#if 0 /* Removed to get winEmbed working again */ - UNIMPLEMENTED -#else - DPRINT1("Not implemented: HookId %d Global %s\n", HookId, Global ? "TRUE" : "FALSE"); -#endif - - /* Dereference thread if needed */ - if (ThreadReferenced) ObDereferenceObject(Thread); - SetLastWin32Error(ERROR_NOT_SUPPORTED); - RETURN( NULL); - } - - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, + Status = IntValidateWindowStationHandle( PsGetCurrentProcess()->Win32WindowStation, + KernelMode, + 0, &WinStaObj); if (!NT_SUCCESS(Status)) { - /* Dereference thread if needed */ - if (ThreadReferenced) ObDereferenceObject(Thread); - SetLastNtError(Status); - RETURN( (HANDLE) NULL); + SetLastNtError(Status); + RETURN( NULL); } - - Hook = IntAddHook(Thread, HookId, Global, WinStaObj); - if (NULL == Hook) - { - /* Dereference thread if needed */ - if (ThreadReferenced) ObDereferenceObject(Thread); - ObDereferenceObject(WinStaObj); - RETURN( NULL); - } - - /* Let IntFreeHook now that this thread needs a dereference */ - if (ThreadReferenced) - { - Hook->Flags |= HOOK_THREAD_REFERENCED; - } - - if (NULL != Mod) - { - Status = MmCopyFromCaller(&ModuleName, UnsafeModuleName, sizeof(UNICODE_STRING)); - if (!NT_SUCCESS(Status)) - { - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - ObDereferenceObject(WinStaObj); - SetLastNtError(Status); - RETURN( NULL); - } - - Hook->ModuleName.Buffer = ExAllocatePoolWithTag(PagedPool, - ModuleName.MaximumLength, - TAG_HOOK); - if (NULL == Hook->ModuleName.Buffer) - { - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - ObDereferenceObject(WinStaObj); - SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); - RETURN( NULL); - } - - Hook->ModuleName.MaximumLength = ModuleName.MaximumLength; - Status = MmCopyFromCaller(Hook->ModuleName.Buffer, - ModuleName.Buffer, - ModuleName.MaximumLength); - if (!NT_SUCCESS(Status)) - { - ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK); - UserDereferenceObject(Hook); - IntRemoveHook(Hook, WinStaObj, FALSE); - ObDereferenceObject(WinStaObj); - SetLastNtError(Status); - RETURN( NULL); - } - - Hook->ModuleName.Length = ModuleName.Length; - /* make proc relative to the module base */ - Hook->Proc = (void *)((char *)HookProc - (char *)Mod); - } - else - Hook->Proc = HookProc; - - Hook->Ansi = Ansi; - Handle = UserHMGetHandle(Hook); - - /* Clear the client threads next hook. */ - ClientInfo->phkCurrent = 0; - - UserDereferenceObject(Hook); - ObDereferenceObject(WinStaObj); + Hook = UserCreateObject(gHandleTable, NULL, &Handle, otHook, sizeof(HOOK)); + + if (!Hook) + { + RETURN( NULL); + } + + Hook->ihmod = (INT)Mod; // Module Index from atom table, Do this for now. + Hook->Thread = Thread; /* Set Thread, Null is Global. */ + Hook->HookId = HookId; + Hook->rpdesk = pti->rpdesk; + Hook->phkNext = NULL; /* Dont use as a chain! Use link lists for chaining. */ + Hook->Proc = HookProc; + Hook->Ansi = Ansi; + + if (ThreadId) /* thread-local hook */ + { + InsertHeadList(&pti->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain); + pti->sphkCurrent = NULL; + Hook->ptiHooked = pti; + pti->fsHooks |= HOOKID_TO_FLAG(HookId); + + if (pti->pClientInfo) + { + if ( pti->ppi == ptiCurrent->ppi) /* gptiCurrent->ppi) */ + { + _SEH2_TRY + { + pti->pClientInfo->fsHooks = pti->fsHooks; + pti->pClientInfo->phkCurrent = 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; + if (Hit) + { + DPRINT1("Problem writing to Local ClientInfo!\n"); + } + } + else + { + KeAttachProcess(&pti->ppi->peProcess->Pcb); + _SEH2_TRY + { + pti->pClientInfo->fsHooks = pti->fsHooks; + pti->pClientInfo->phkCurrent = 0; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Hit = TRUE; + } + _SEH2_END; + KeDetachProcess(); + if (Hit) + { + DPRINT1("Problem writing to Remote ClientInfo!\n"); + } + } + } + } + else + { + InsertHeadList(&pti->pDeskInfo->aphkStart[HOOKID_TO_INDEX(HookId)], &Hook->Chain); + Hook->ptiHooked = NULL; + //gptiCurrent->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId); + pti->pDeskInfo->fsHooks |= HOOKID_TO_FLAG(HookId); + } + + RtlInitUnicodeString(&Hook->ModuleName, NULL); + + if (Mod) + { + Status = MmCopyFromCaller(&ModuleName, + UnsafeModuleName, + sizeof(UNICODE_STRING)); + if (!NT_SUCCESS(Status)) + { + IntRemoveHook(Hook); + SetLastNtError(Status); + RETURN( NULL); + } + + Hook->ModuleName.Buffer = ExAllocatePoolWithTag( PagedPool, + ModuleName.MaximumLength, + TAG_HOOK); + if (NULL == Hook->ModuleName.Buffer) + { + IntRemoveHook(Hook); + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + RETURN( NULL); + } + + Hook->ModuleName.MaximumLength = ModuleName.MaximumLength; + Status = MmCopyFromCaller( Hook->ModuleName.Buffer, + ModuleName.Buffer, + ModuleName.MaximumLength); + if (!NT_SUCCESS(Status)) + { + ExFreePoolWithTag(Hook->ModuleName.Buffer, TAG_HOOK); + Hook->ModuleName.Buffer = NULL; + IntRemoveHook(Hook); + SetLastNtError(Status); + RETURN( NULL); + } + + Hook->ModuleName.Length = ModuleName.Length; + /* make proc relative to the module base */ + Hook->offPfn = (ULONG_PTR)((char *)HookProc - (char *)Mod); + } + else + Hook->offPfn = 0; + + DPRINT1("Installing: HookId %d Global %s\n", HookId, !ThreadId ? "TRUE" : "FALSE"); RETURN( Handle); CLEANUP: @@ -1313,46 +1391,28 @@ CLEANUP: END_CLEANUP; } - BOOL APIENTRY NtUserUnhookWindowsHookEx(HHOOK Hook) { - PWINSTATION_OBJECT WinStaObj; PHOOK HookObj; - NTSTATUS Status; DECLARE_RETURN(BOOL); DPRINT("Enter NtUserUnhookWindowsHookEx\n"); UserEnterExclusive(); - Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation, - KernelMode, - 0, - &WinStaObj); - - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - RETURN( FALSE); - } - - /* Status = UserReferenceObjectByHandle(gHandleTable, Hook, - otHookProc, (PVOID *) &HookObj); */ if (!(HookObj = IntGetHookObject(Hook))) { DPRINT1("Invalid handle passed to NtUserUnhookWindowsHookEx\n"); - ObDereferenceObject(WinStaObj); /* SetLastNtError(Status); */ RETURN( FALSE); } ASSERT(Hook == UserHMGetHandle(HookObj)); - IntRemoveHook(HookObj, WinStaObj, FALSE); + IntRemoveHook(HookObj); UserDereferenceObject(HookObj); - ObDereferenceObject(WinStaObj); RETURN( TRUE); diff --git a/subsystems/win32/win32k/ntuser/input.c b/subsystems/win32/win32k/ntuser/input.c index 316b9308b31..9a4339d1981 100644 --- a/subsystems/win32/win32k/ntuser/input.c +++ b/subsystems/win32/win32k/ntuser/input.c @@ -1347,7 +1347,7 @@ IntKeyboardInput(KEYBDINPUT *ki) KbdHookData.dwExtraInfo = ki->dwExtraInfo; if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData)) { - DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n", + DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n", Msg.message, vk_hook, Msg.lParam); if (Entered) UserLeave(); return FALSE; diff --git a/subsystems/win32/win32k/ntuser/kbdlayout.c b/subsystems/win32/win32k/ntuser/kbdlayout.c index 5d04cd81902..a6ac6e68bfb 100644 --- a/subsystems/win32/win32k/ntuser/kbdlayout.c +++ b/subsystems/win32/win32k/ntuser/kbdlayout.c @@ -163,10 +163,7 @@ static BOOL UserLoadKbdDll(WCHAR *wsKLID, DPRINT("Loaded %wZ\n", &FullLayoutPath); RtlInitAnsiString( &kbdProcedureName, "KbdLayerDescriptor" ); - LdrGetProcedureAddress((*(PDRIVERS*)phModule)->BaseAddress, - &kbdProcedureName, - 0, - (PVOID*)&layerDescGetFn); + layerDescGetFn = EngFindImageProcAddress(*phModule, "KbdLayerDescriptor"); if(layerDescGetFn) { diff --git a/subsystems/win32/win32k/ntuser/message.c b/subsystems/win32/win32k/ntuser/message.c index 403e02b84ce..afec69e5cd1 100644 --- a/subsystems/win32/win32k/ntuser/message.c +++ b/subsystems/win32/win32k/ntuser/message.c @@ -368,9 +368,10 @@ IntDispatchMessage(PMSG pMsg) { LARGE_INTEGER TickCount; LONG Time; - LRESULT retval; + LRESULT retval = 0; PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; + PTHREADINFO pti; LPARAM lParamPacked; PWND Window = NULL; @@ -380,17 +381,20 @@ IntDispatchMessage(PMSG pMsg) if (!Window) return 0; } + pti = PsGetCurrentThreadWin32Thread(); + if (((pMsg->message == WM_SYSTIMER) || (pMsg->message == WM_TIMER)) && (pMsg->lParam) ) { if (pMsg->message == WM_TIMER) { - if (ValidateTimerCallback(PsGetCurrentThreadWin32Thread(),pMsg->lParam)) + ObReferenceObject(pti->pEThread); + if (ValidateTimerCallback(pti,pMsg->lParam)) { KeQueryTickCount(&TickCount); Time = MsqCalculateMessageTime(&TickCount); - return co_IntCallWindowProc((WNDPROC)pMsg->lParam, + retval = co_IntCallWindowProc((WNDPROC)pMsg->lParam, TRUE, pMsg->hwnd, WM_TIMER, @@ -398,7 +402,8 @@ IntDispatchMessage(PMSG pMsg) (LPARAM)Time, sizeof(LPARAM)); } - return 0; + ObDereferenceObject(pti->pEThread); + return retval; } else { @@ -431,7 +436,7 @@ IntDispatchMessage(PMSG pMsg) DPRINT1("Failed to pack message parameters\n"); return 0; } - + ObReferenceObject(pti->pEThread); retval = co_IntCallWindowProc( Window->lpfnWndProc, !Window->Unicode, pMsg->hwnd, @@ -452,6 +457,7 @@ IntDispatchMessage(PMSG pMsg) co_UserGetUpdateRgn( Window, hrgn, TRUE ); REGION_FreeRgnByHandle( hrgn ); } + ObDereferenceObject(pti->pEThread); return retval; } @@ -625,7 +631,7 @@ co_IntTranslateMouseMessage( } } - if ( gspv.bMouseClickLock && + if ( gspv.bMouseClickLock && ( (Msg->message == WM_LBUTTONUP) || (Msg->message == WM_LBUTTONDOWN) ) ) { @@ -784,6 +790,7 @@ BOOL ProcessMouseMessage(MSG* Msg, BOOLEAN RemoveMessages) HCBT_CLICKSKIPPED, Msg->message, (LPARAM)&MHook); + DPRINT1("MouseMessage WH_CBT Call Hook return!\n"); return FALSE; } @@ -812,6 +819,7 @@ BOOL ProcessKeyboardMessage(MSG* Msg, BOOLEAN RemoveMessages) HCBT_KEYSKIPPED, LOWORD(Msg->wParam), Msg->lParam ); + DPRINT1("KeyboardMessage WH_CBT Call Hook return!\n"); return FALSE; } return TRUE; @@ -859,98 +867,98 @@ co_IntPeekMessage( PUSER_MESSAGE Msg, do { - KeQueryTickCount(&LargeTickCount); - ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart; + KeQueryTickCount(&LargeTickCount); + ThreadQueue->LastMsgRead = LargeTickCount.u.LowPart; - /* Dispatch sent messages here. */ - while (co_MsqDispatchOneSentMessage(ThreadQueue)) - ; + /* Dispatch sent messages here. */ + while (co_MsqDispatchOneSentMessage(ThreadQueue)) + ; - /* Now look for a quit message. */ + /* Now look for a quit message. */ - if (ThreadQueue->QuitPosted) - { - /* According to the PSDK, WM_QUIT messages are always returned, regardless - of the filter specified */ - Msg->Msg.hwnd = NULL; - Msg->Msg.message = WM_QUIT; - Msg->Msg.wParam = ThreadQueue->QuitExitCode; - Msg->Msg.lParam = 0; - if (RemoveMessages) - { - ThreadQueue->QuitPosted = FALSE; - } + if (ThreadQueue->QuitPosted) + { + /* According to the PSDK, WM_QUIT messages are always returned, regardless + of the filter specified */ + Msg->Msg.hwnd = NULL; + Msg->Msg.message = WM_QUIT; + Msg->Msg.wParam = ThreadQueue->QuitExitCode; + Msg->Msg.lParam = 0; + if (RemoveMessages) + { + ThreadQueue->QuitPosted = FALSE; + } return TRUE; - } + } - /* Now check for normal messages. */ + /* Now check for normal messages. */ if (co_MsqFindMessage( ThreadQueue, - FALSE, - RemoveMessages, - Window, - MsgFilterMin, - MsgFilterMax, + FALSE, + RemoveMessages, + Window, + MsgFilterMin, + MsgFilterMax, &Message )) - { - RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE)); - if (RemoveMessages) - { - MsqDestroyMessage(Message); - } + { + RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE)); + if (RemoveMessages) + { + MsqDestroyMessage(Message); + } break; - } + } - /* Check for hardware events. */ + /* Check for hardware events. */ if(co_MsqFindMessage( ThreadQueue, - TRUE, - RemoveMessages, - Window, - MsgFilterMin, - MsgFilterMax, + TRUE, + RemoveMessages, + Window, + MsgFilterMin, + MsgFilterMax, &Message )) - { - RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE)); - if (RemoveMessages) - { - MsqDestroyMessage(Message); - } + { + RtlCopyMemory(Msg, Message, sizeof(USER_MESSAGE)); + if (RemoveMessages) + { + MsqDestroyMessage(Message); + } if(!ProcessHardwareMessage(&Msg->Msg, RemoveMessages)) continue; break; - } - - /* Check for sent messages again. */ - while (co_MsqDispatchOneSentMessage(ThreadQueue)) - ; - - /* Check for paint messages. */ - if( IntGetPaintMessage( Window, - MsgFilterMin, - MsgFilterMax, - pti, - &Msg->Msg, - RemoveMessages)) - { - break; - } - - if (PostTimerMessages(Window)) - { - continue; - } - - return FALSE; } + + /* Check for sent messages again. */ + while (co_MsqDispatchOneSentMessage(ThreadQueue)) + ; + + /* Check for paint messages. */ + if( IntGetPaintMessage( Window, + MsgFilterMin, + MsgFilterMax, + pti, + &Msg->Msg, + RemoveMessages)) + { + break; + } + + if (PostTimerMessages(Window)) + { + continue; + } + + return FALSE; + } while (TRUE); - // The WH_GETMESSAGE hook enables an application to monitor messages about to - // be returned by the GetMessage or PeekMessage function. + // The WH_GETMESSAGE hook enables an application to monitor messages about to + // be returned by the GetMessage or PeekMessage function. - co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg); - return TRUE; + co_HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, RemoveMsg & PM_REMOVE, (LPARAM)&Msg->Msg); + return TRUE; } static NTSTATUS FASTCALL @@ -1232,7 +1240,7 @@ UserPostMessage( HWND Wnd, return FALSE; } - if (!Wnd) + if (!Wnd) return UserPostThreadMessage( PtrToInt(PsGetCurrentThreadId()), Msg, wParam, @@ -1249,6 +1257,7 @@ UserPostMessage( HWND Wnd, if (List != NULL) { + UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam); for (i = 0; List[i]; i++) UserPostMessage(List[i], Msg, wParam, lParam); ExFreePool(List); @@ -1322,13 +1331,13 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, UINT uTimeout, ULONG_PTR *uResult ) { - ULONG_PTR Result; NTSTATUS Status; PWND Window = NULL; PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; LPARAM lParamPacked; PTHREADINFO Win32Thread; + ULONG_PTR Result = 0; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; @@ -1369,6 +1378,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, RETURN( FALSE); } + ObReferenceObject(Win32Thread->pEThread); Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, !Window->Unicode, hWnd, @@ -1381,6 +1391,8 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, *uResult = Result; } + ObDereferenceObject(Win32Thread->pEThread); + IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) @@ -1474,6 +1486,9 @@ co_IntSendMessageTimeout( HWND hWnd, return 0; } + /* Send message to the desktop window too! */ + co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult); + Children = IntWinListChildren(DesktopWindow); if (NULL == Children) { @@ -1575,7 +1590,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, /* If this is not a callback and it can be sent now, then send it. */ if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { - + ObReferenceObject(Win32Thread->pEThread); Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, !Window->Unicode, hWnd, @@ -1587,6 +1602,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, { *uResult = Result; } + ObDereferenceObject(Win32Thread->pEThread); } IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); @@ -1818,6 +1834,7 @@ UserSendNotifyMessage( HWND hWnd, if (List != NULL) { + UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam); for (i = 0; List[i]; i++) { UserSendNotifyMessage(List[i], Msg, wParam, lParam); @@ -2410,7 +2427,7 @@ NtUserDispatchMessage(PMSG UnsafeMsgInfo) BOOL Hit = FALSE; MSG SafeMsg; - UserEnterExclusive(); + UserEnterExclusive(); _SEH2_TRY { ProbeForRead(UnsafeMsgInfo, sizeof(MSG), 1); @@ -2422,7 +2439,7 @@ NtUserDispatchMessage(PMSG UnsafeMsgInfo) Hit = TRUE; } _SEH2_END; - + if (!Hit) Res = IntDispatchMessage(&SafeMsg); UserLeave(); @@ -2553,12 +2570,13 @@ NtUserMessageCall( 2000, &RetVal); } + Ret = RetVal; } else if (parm.flags & BSF_POSTMESSAGE) { Ret = UserPostMessage(HWND_BROADCAST, Msg, wParam, lParam); } - else if ( parm.flags & BSF_SENDNOTIFYMESSAGE) + else //Everything else,,,, if ( parm.flags & BSF_SENDNOTIFYMESSAGE) { Ret = UserSendNotifyMessage(HWND_BROADCAST, Msg, wParam, lParam); } @@ -2584,21 +2602,31 @@ NtUserMessageCall( case FNID_CALLWNDPROC: case FNID_CALLWNDPROCRET: { - PCLIENTINFO ClientInfo = GetWin32ClientInfo(); - PHOOK NextObj, Hook = ClientInfo->phkCurrent; + PTHREADINFO pti; + PCLIENTINFO ClientInfo; + PHOOK NextObj, Hook; - if (!ClientInfo || !Hook) break; + pti = GetW32ThreadInfo(); - UserReferenceObject(Hook); + Hook = pti->sphkCurrent; - if (Hook->Thread && (Hook->Thread != PsGetCurrentThread())) + if (!Hook) break; + + NextObj = Hook->phkNext; + ClientInfo = pti->pClientInfo; + _SEH2_TRY { - UserDereferenceObject(Hook); - break; + ClientInfo->phkCurrent = NextObj; } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + ClientInfo = NULL; + } + _SEH2_END; - NextObj = IntGetNextHook(Hook); - ClientInfo->phkCurrent = NextObj; + if (!ClientInfo || !NextObj) break; + + NextObj->phkNext = IntGetNextHook(NextObj); if ( Hook->HookId == WH_CALLWNDPROC) { @@ -2634,8 +2662,6 @@ NtUserMessageCall( Hook->Ansi, &Hook->ModuleName); } - UserDereferenceObject(Hook); - lResult = (LRESULT) NextObj; } break; } @@ -2656,11 +2682,11 @@ NtUserMessageCall( { BadChk = TRUE; } - _SEH2_END; + _SEH2_END; } break; default: - break; + break; } UserLeave(); diff --git a/subsystems/win32/win32k/ntuser/metric.c b/subsystems/win32/win32k/ntuser/metric.c index be2b1a10367..e8829570a16 100644 --- a/subsystems/win32/win32k/ntuser/metric.c +++ b/subsystems/win32/win32k/ntuser/metric.c @@ -24,9 +24,19 @@ FASTCALL InitMetrics(VOID) { INT *piSysMet; + ULONG Width, Height; - ULONG Width = pPrimarySurface->gdiinfo.ulHorzRes; - ULONG Height = pPrimarySurface->gdiinfo.ulVertRes; + /* FIXME: HACK, due to missing PDEV on first init */ + if (!pPrimarySurface) + { + Width = 640; + Height = 480; + } + else + { + Width = pPrimarySurface->gdiinfo.ulHorzRes; + Height = pPrimarySurface->gdiinfo.ulVertRes; + } piSysMet = gpsi->aiSysMet; diff --git a/subsystems/win32/win32k/ntuser/msgqueue.c b/subsystems/win32/win32k/ntuser/msgqueue.c index 5d0bee88eba..0f102a1c51d 100644 --- a/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/subsystems/win32/win32k/ntuser/msgqueue.c @@ -798,7 +798,7 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) KbdHookData.dwExtraInfo = 0; if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData)) { - DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n", + DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n", Msg.message, Msg.wParam, Msg.lParam); if (Entered) UserLeave(); return; @@ -948,26 +948,25 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) &Message->ListEntry); if (Message->HookMessage == MSQ_ISHOOK) - { - Result = co_HOOK_CallHooks(Message->Msg.message, - (INT)(INT_PTR)Message->Msg.hwnd, - Message->Msg.wParam, - Message->Msg.lParam); + { // Direct Hook Call processor + Result = co_CallHook( Message->Msg.message, // HookId + (INT)(INT_PTR)Message->Msg.hwnd, // Code + Message->Msg.wParam, + Message->Msg.lParam); } else if (Message->HookMessage == MSQ_ISEVENT) - { + { // Direct Event Call processor Result = co_EVENT_CallEvents( Message->Msg.message, Message->Msg.hwnd, Message->Msg.wParam, Message->Msg.lParam); } else - { - /* Call the window procedure. */ - Result = co_IntSendMessage(Message->Msg.hwnd, - Message->Msg.message, - Message->Msg.wParam, - Message->Msg.lParam); + { /* Call the window procedure. */ + Result = co_IntSendMessage( Message->Msg.hwnd, + Message->Msg.message, + Message->Msg.wParam, + Message->Msg.lParam); } /* remove the message from the local dispatching list, because it doesn't need @@ -1133,10 +1132,10 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_SENT_MESSAGE Message; KEVENT CompletionEvent; NTSTATUS WaitStatus; - LRESULT Result; PUSER_MESSAGE_QUEUE ThreadQueue; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; + LRESULT Result = 0; //// Result could be trashed. //// if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG))) { @@ -1154,7 +1153,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, /* FIXME - increase reference counter of sender's message queue here */ - Result = 0; Message->Msg.hwnd = Wnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; @@ -1164,6 +1162,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, Message->SenderQueue = ThreadQueue; IntReferenceMessageQueue(ThreadQueue); Message->CompletionCallback = NULL; + Message->CompletionCallbackContext = 0; Message->HookMessage = HookMessage; Message->HasPackedLParam = FALSE; @@ -1632,18 +1631,6 @@ MsqDestroyMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) IntDereferenceMessageQueue(MessageQueue); } -PHOOKTABLE FASTCALL -MsqGetHooks(PUSER_MESSAGE_QUEUE Queue) -{ - return Queue->Hooks; -} - -VOID FASTCALL -MsqSetHooks(PUSER_MESSAGE_QUEUE Queue, PHOOKTABLE Hooks) -{ - Queue->Hooks = Hooks; -} - LPARAM FASTCALL MsqSetMessageExtraInfo(LPARAM lParam) { diff --git a/subsystems/win32/win32k/ntuser/ntstubs.c b/subsystems/win32/win32k/ntuser/ntstubs.c index 3219a953411..9d4cc5b0d81 100644 --- a/subsystems/win32/win32k/ntuser/ntstubs.c +++ b/subsystems/win32/win32k/ntuser/ntstubs.c @@ -199,39 +199,6 @@ NtUserDrawAnimatedRects( return 0; } -BOOL -APIENTRY -NtUserEnumDisplayDevices ( - PUNICODE_STRING lpDevice, /* device name */ - DWORD iDevNum, /* display device */ - PDISPLAY_DEVICEW lpDisplayDevice, /* device information */ - DWORD dwFlags ) /* reserved */ -{ - DPRINT1("NtUserEnumDisplayDevices() is UNIMPLEMENTED!\n"); - if (lpDevice->Length == 0 && iDevNum > 0) - { - /* Only one display device present */ - return FALSE; - } - else if (lpDevice->Length != 0) - { - /* Can't enumerate monitors :( */ - return FALSE; - } - if (lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE)) - return FALSE; - - wcscpy(lpDisplayDevice->DeviceName, L"\\\\.\\DISPLAY1"); - wcscpy(lpDisplayDevice->DeviceString, L""); - lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP - | DISPLAY_DEVICE_MODESPRUNED - | DISPLAY_DEVICE_PRIMARY_DEVICE - | DISPLAY_DEVICE_VGA_COMPATIBLE; - lpDisplayDevice->DeviceID[0] = L'0'; - lpDisplayDevice->DeviceKey[0] = L'0'; - return TRUE; -} - DWORD APIENTRY NtUserEvent( diff --git a/subsystems/win32/win32k/ntuser/ntuser.c b/subsystems/win32/win32k/ntuser/ntuser.c index 14857b09f25..1ca06aba1cc 100644 --- a/subsystems/win32/win32k/ntuser/ntuser.c +++ b/subsystems/win32/win32k/ntuser/ntuser.c @@ -73,16 +73,6 @@ NTSTATUS FASTCALL InitUserImpl(VOID) return Status; } - if (!gpsi) - { - gpsi = UserHeapAlloc(sizeof(SERVERINFO)); - if (gpsi) - { - RtlZeroMemory(gpsi, sizeof(SERVERINFO)); - DPRINT("Global Server Data -> %x\n", gpsi); - } - } - InitUserAtoms(); InitSysParams(); @@ -90,6 +80,8 @@ NTSTATUS FASTCALL InitUserImpl(VOID) return STATUS_SUCCESS; } +BOOL +InitVideo(ULONG); NTSTATUS NTAPI @@ -100,6 +92,7 @@ UserInitialize( // Set W32PF_Flags |= (W32PF_READSCREENACCESSGRANTED | W32PF_IOWINSTA) // Create Object Directory,,, Looks like create workstation. "\\Windows\\WindowStations" // Create Event for Diconnect Desktop. + InitVideo(0); // Initialize Video. // { // DrvInitConsole. @@ -139,8 +132,8 @@ NtUserInitialize( { NTSTATUS Status; - DPRINT("Enter NtUserInitialize(%lx, %p, %p)\n", - dwWinVersion, hPowerRequestEvent, hMediaRequestEvent); + DPRINT1("Enter NtUserInitialize(%lx, %p, %p)\n", + dwWinVersion, hPowerRequestEvent, hMediaRequestEvent); /* Check the Windows version */ if (dwWinVersion != 0) diff --git a/subsystems/win32/win32k/ntuser/object.c b/subsystems/win32/win32k/ntuser/object.c index 0c3fb075d7e..222b36cb6b8 100644 --- a/subsystems/win32/win32k/ntuser/object.c +++ b/subsystems/win32/win32k/ntuser/object.c @@ -330,8 +330,8 @@ UserCreateObject( PUSER_HANDLE_TABLE ht, { case otWindow: // case otMenu: -// case otHook: -// case otCallProc: + case otHook: + case otCallProc: case otInputContext: Object = DesktopHeapAlloc(rpdesk, size); dt = TRUE; @@ -420,8 +420,8 @@ UserDereferenceObject(PVOID object) { case otWindow: // case otMenu: -// case otHook: -// case otCallProc: + case otHook: + case otCallProc: case otInputContext: return DesktopHeapFree(((PTHRDESKHEAD)object)->rpdesk, object); diff --git a/subsystems/win32/win32k/ntuser/simplecall.c b/subsystems/win32/win32k/ntuser/simplecall.c index af977096c8a..29d35958e44 100644 --- a/subsystems/win32/win32k/ntuser/simplecall.c +++ b/subsystems/win32/win32k/ntuser/simplecall.c @@ -228,21 +228,6 @@ NtUserCallOneParam( RETURN (ret); } - case ONEPARAM_ROUTINE_ISWINDOWINDESTROY: - { - PWND Window; - DWORD_PTR Result; - - if(!(Window = UserGetWindowObject((HWND)Param))) - { - RETURN( FALSE); - } - - Result = (DWORD_PTR)IntIsWindowInDestroy(Window); - - RETURN( Result); - } - case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING: { BOOL Enable; @@ -473,6 +458,8 @@ NtUserCallTwoParam( case TWOPARAM_ROUTINE_SETCURSORPOS: RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, FALSE)); + case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK: + RETURN( IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2)); } DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n", Routine, Param1, Param2); @@ -713,6 +700,21 @@ NtUserCallHwndParam( UserLeave(); return 0; } + + case HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT: + { + PWND pWnd; + PNOTIFYEVENT pne; + UserEnterExclusive(); + pne = (PNOTIFYEVENT)Param; + if (hWnd) + pWnd = UserGetWindowObject(hWnd); + else + pWnd = NULL; + IntNotifyWinEvent(pne->event, pWnd, pne->idObject, pne->idChild, pne->flags); + UserLeave(); + return 0; + } } UNIMPLEMENTED; diff --git a/subsystems/win32/win32k/ntuser/windc.c b/subsystems/win32/win32k/ntuser/windc.c index e6b3cfa5ad9..e5534172c6b 100644 --- a/subsystems/win32/win32k/ntuser/windc.c +++ b/subsystems/win32/win32k/ntuser/windc.c @@ -41,6 +41,9 @@ DceCreateDisplayDC(VOID) UNICODE_STRING DriverName; RtlInitUnicodeString(&DriverName, L"DISPLAY"); hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, FALSE); + + co_IntGraphicsCheck(TRUE); + // // If NULL, first time through! Build the default window dc! // diff --git a/subsystems/win32/win32k/ntuser/window.c b/subsystems/win32/win32k/ntuser/window.c index 0b270cf8c0b..f6e588fa1d8 100644 --- a/subsystems/win32/win32k/ntuser/window.c +++ b/subsystems/win32/win32k/ntuser/window.c @@ -163,7 +163,6 @@ IntIsWindow(HWND hWnd) } - PWND FASTCALL IntGetParent(PWND Wnd) { @@ -179,7 +178,6 @@ IntGetParent(PWND Wnd) return NULL; } - /* * IntWinListChildren * @@ -348,7 +346,7 @@ static LRESULT co_UserFreeWindow(PWND Window, Window->state2 |= WNDS2_INDESTROY; Window->style &= ~WS_VISIBLE; - IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, 0); + IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0); /* remove the window already at this point from the thread window list so we don't get into trouble when destroying the thread windows while we're still @@ -399,7 +397,9 @@ static LRESULT co_UserFreeWindow(PWND Window, if(BelongsToThreadData) co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0); } + DestroyTimersForWindow(ThreadData, Window); + HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too! /* flush the message queue */ @@ -1168,6 +1168,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) } + IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); /* * SetParent additionally needs to make hwnd the top window * in the z-order and send the expected WM_WINDOWPOSCHANGING and @@ -1227,13 +1228,6 @@ IntUnlinkWindow(PWND Wnd) Wnd->spwndPrev = Wnd->spwndNext = NULL; } -BOOL FASTCALL -IntIsWindowInDestroy(PWND Window) -{ - return ((Window->state2 & WNDS2_INDESTROY) == WNDS2_INDESTROY); -} - - BOOL FASTCALL IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl) @@ -1635,6 +1629,33 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, pti = PsGetCurrentThreadWin32Thread(); + if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL)) + { + if (ParentWindow) + { + if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD && + ParentWindow->ExStyle & WS_EX_LAYOUTRTL && + !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) ) + Cs->dwExStyle |= WS_EX_LAYOUTRTL; + } + else + {/* + Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx : + + Dialog boxes and message boxes do not inherit layout, so you must + set the layout explicitly. + */ + if ( Class && Class->fnid != FNID_DIALOG) + { + PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); + if (ppi->dwLayout & LAYOUT_RTL) + { + Cs->dwExStyle |= WS_EX_LAYOUTRTL; + } + } + } + } + /* Automatically add WS_EX_WINDOWEDGE */ if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) || ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) && @@ -1877,17 +1898,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, PLARGE_STRING WindowName) { PWND Window = NULL, ParentWindow = NULL, OwnerWindow; - HWND hWnd, hWndParent, hWndOwner; + HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter; DWORD dwStyle; PWINSTATION_OBJECT WinSta; PCLS Class = NULL; SIZE Size; POINT MaxPos; - CBT_CREATEWNDW CbtCreate; + CBT_CREATEWNDW * pCbtCreate; LRESULT Result; USER_REFERENCE_ENTRY ParentRef, Ref; PTHREADINFO pti; + ANSI_STRING asClassName; DWORD dwShowMode = SW_SHOW; + CREATESTRUCTW *pCsw; DECLARE_RETURN(PWND); /* Get the current window station and reference it */ @@ -1900,6 +1923,10 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, WinSta = pti->rpdesk->rpwinstaParent; ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0); + pCsw = NULL; + pCbtCreate = NULL; + RtlInitAnsiString(&asClassName, NULL); + /* Get the class and reference it*/ Class = IntGetAndReferenceClass(ClassName, Cs->hInstance); if(!Class) @@ -1956,22 +1983,57 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, RETURN(0); } - hWnd = Window->head.h; + hWnd = UserHMGetHandle(Window); UserRefObjectCo(Window, &Ref); ObDereferenceObject(WinSta); - /* Call the WH_CBT hook */ - dwStyle = Cs->style; - Cs->style = Window->style; /* HCBT_CREATEWND needs the real window style */ - CbtCreate.lpcs = Cs; - CbtCreate.hwndInsertAfter = HWND_TOP; + //// Call the WH_CBT hook //// - if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate)) + // Allocate the calling structures Justin Case this goes Global. + pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK); + pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK); + + /* Fill the new CREATESTRUCTW */ + pCsw->lpCreateParams = Cs->lpCreateParams; + pCsw->hInstance = Cs->hInstance; + pCsw->hMenu = Cs->hMenu; + pCsw->hwndParent = Cs->hwndParent; + pCsw->cx = Cs->cx; + pCsw->cy = Cs->cy; + pCsw->x = Cs->x; + pCsw->y = Cs->y; + pCsw->dwExStyle = Cs->dwExStyle; + dwStyle = Cs->style; // Save it anyway. + pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */ + + pCsw->lpszName = (LPCWSTR) WindowName->Buffer; + pCsw->lpszClass = (LPCWSTR) ClassName->Buffer; + + if (Window->state & WNDS_ANSICREATOR) { - DPRINT1("HCBT_CREATEWND hook failed!\n"); + if (!IS_ATOM(ClassName->Buffer)) + { + RtlUnicodeStringToAnsiString(&asClassName, ClassName, TRUE); + pCsw->lpszClass = (LPCWSTR) asClassName.Buffer; + } + } + + pCbtCreate->lpcs = pCsw; + pCbtCreate->hwndInsertAfter = HWND_TOP; + + Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate); + if (Result != 0) + { + DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result); RETURN( (PWND) NULL); } + // Write back changes. + Cs->cx = pCsw->cx; + Cs->cy = pCsw->cy; + Cs->x = pCsw->x; + Cs->y = pCsw->y; + hwndInsertAfter = pCbtCreate->hwndInsertAfter; Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/ @@ -2014,7 +2076,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } /* Send the NCCREATE message */ - Result = co_IntSendMessage(Window->head.h, WM_NCCREATE, 0, (LPARAM) Cs); + Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs); if (!Result) { DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n"); @@ -2032,7 +2094,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, /* Send the WM_CREATE message. */ - Result = co_IntSendMessage(Window->head.h, WM_CREATE, 0, (LPARAM) Cs); + Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs); if (Result == (LRESULT)-1) { DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n"); @@ -2040,7 +2102,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } /* Send the EVENT_OBJECT_CREATE event*/ - IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, 0); + IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0); /* By setting the flag below it can be examined to determine if the window was created successfully and a valid pwnd was passed back to caller since @@ -2102,7 +2164,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, if (Window->ExStyle & WS_EX_MDICHILD) { - co_IntSendMessage(ParentWindow->head.h, WM_MDIREFRESHMENU, 0, 0); + co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0); /* ShowWindow won't activate child windows */ co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE); } @@ -2121,6 +2183,10 @@ CLEANUP: IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi); } + if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK); + if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK); + RtlFreeAnsiString(&asClassName); + if (Window) { UserDerefObjectCo(Window); @@ -2280,7 +2346,7 @@ NtUserCreateWindowEx( /* Call the internal function */ pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName); - if(!pwnd) + if(!pwnd) { DPRINT1("co_UserCreateWindowEx failed!\n"); } @@ -2343,7 +2409,11 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) /* If window was created successfully and it is hooked */ if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED)) { - if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE; + if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) + { + DPRINT1("Destroy Window WH_CBT Call Hook return!\n"); + return FALSE; + } } /* Inform the parent */ diff --git a/subsystems/win32/win32k/ntuser/winpos.c b/subsystems/win32/win32k/ntuser/winpos.c index 7a9562613c4..04c0fd7263f 100644 --- a/subsystems/win32/win32k/ntuser/winpos.c +++ b/subsystems/win32/win32k/ntuser/winpos.c @@ -299,8 +299,10 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos) WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow); if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag)) + { + DPRINT1("WinPosMinMaximize WH_CBT Call Hook return!\n"); return SWP_NOSIZE | SWP_NOMOVE; - + } if (Wnd->style & WS_MINIMIZE) { if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0)) @@ -385,7 +387,6 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos) } } } - return(SwpFlags); } @@ -1358,6 +1359,14 @@ co_WinPosSetWindowPos( co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos); } + if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED || + !(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) ) + { + PWND pWnd = UserGetWindowObject(WinPos.hwnd); + if (pWnd) + IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + } + return TRUE; } diff --git a/subsystems/win32/win32k/objects/arc.c b/subsystems/win32/win32k/objects/arc.c index 58393036608..e2ffeb50fdc 100644 --- a/subsystems/win32/win32k/objects/arc.c +++ b/subsystems/win32/win32k/objects/arc.c @@ -31,7 +31,7 @@ BOOL FASTCALL IntDrawArc( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, d static BOOL FASTCALL -IntArc( DC *dc, +IntArc( DC *dc, int Left, int Top, int Right, @@ -91,7 +91,7 @@ IntArc( DC *dc, } if (!PenWidth) PenWidth = 1; - pbrushPen->ptPenWidth.x = PenWidth; + pbrushPen->ptPenWidth.x = PenWidth; RectBounds.left = Left; RectBounds.right = Right; @@ -105,7 +105,7 @@ IntArc( DC *dc, IntLPtoDP(dc, (LPPOINT)&RectBounds, 2); IntLPtoDP(dc, (LPPOINT)&RectSEpts, 2); - + RectBounds.left += dc->ptlDCOrig.x; RectBounds.right += dc->ptlDCOrig.x; RectBounds.top += dc->ptlDCOrig.y; @@ -172,7 +172,7 @@ IntArc( DC *dc, } if (arctype == GdiTypeChord) PUTLINE(EfCx + CenterX, EfCy + CenterY, SfCx + CenterX, SfCy + CenterY, dc->eboLine); - + pbrushPen->ptPenWidth.x = PenOrigWidth; PEN_UnlockPen(pbrushPen); DPRINT("IntArc Exit.\n"); @@ -219,12 +219,6 @@ IntGdiArcInternal( pdcattr = dc->pdcattr; - if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) - DC_vUpdateFillBrush(dc); - - if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) - DC_vUpdateLineBrush(dc); - if (arctype == GdiTypeArcTo) { if (dc->dclevel.flPath & DCPATH_CLOCKWISE) @@ -329,7 +323,14 @@ NtGdiAngleArc( } worker.l = dwStartAngle; worker1.l = dwSweepAngle; + DC_vPrepareDCsForBlit(pDC, pDC->rosdc.CombinedClip->rclBounds, + NULL, pDC->rosdc.CombinedClip->rclBounds); + if (pDC->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(pDC); + if (pDC->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(pDC); Ret = IntGdiAngleArc( pDC, x, y, dwRadius, worker.f, worker1.f); + DC_vFinishBlit(pDC, NULL); DC_UnlockDc( pDC ); return Ret; } @@ -364,6 +365,15 @@ NtGdiArcInternal( return TRUE; } + DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, + NULL, dc->rosdc.CombinedClip->rclBounds); + + if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(dc); + + if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(dc); + Ret = IntGdiArcInternal( arctype, dc, @@ -376,6 +386,7 @@ NtGdiArcInternal( XEndArc, YEndArc); + DC_vFinishBlit(dc, NULL); DC_UnlockDc( dc ); return Ret; } diff --git a/subsystems/win32/win32k/objects/bitblt.c b/subsystems/win32/win32k/objects/bitblt.c index f685b1163e5..5854743cdc6 100644 --- a/subsystems/win32/win32k/objects/bitblt.c +++ b/subsystems/win32/win32k/objects/bitblt.c @@ -42,6 +42,8 @@ NtGdiAlphaBlend( { PDC DCDest; PDC DCSrc; + HDC ahDC[2]; + PGDIOBJ apObj[2]; SURFACE *BitmapDest, *BitmapSrc; RECTL DestRect, SourceRect; BOOL bResult; @@ -55,45 +57,30 @@ NtGdiAlphaBlend( return FALSE; } - DCDest = DC_LockDc(hDCDest); - if (NULL == DCDest) + DPRINT("Locking DCs\n"); + ahDC[0] = hDCDest; + ahDC[1] = hDCSrc ; + GDIOBJ_LockMultipleObjs(2, ahDC, apObj); + DCDest = apObj[0]; + DCSrc = apObj[1]; + + if ((NULL == DCDest) || (NULL == DCSrc)) { - DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCDest); + DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hDCDest, hDCSrc); SetLastWin32Error(ERROR_INVALID_HANDLE); + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); return FALSE; } - if (DCDest->dctype == DC_TYPE_INFO) + if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO) { - DC_UnlockDc(DCDest); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); /* Yes, Windows really returns TRUE in this case */ return TRUE; } - if (hDCSrc != hDCDest) - { - DCSrc = DC_LockDc(hDCSrc); - if (NULL == DCSrc) - { - DC_UnlockDc(DCDest); - DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiAlphaBlend\n", hDCSrc); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - - if (DCSrc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } - } - else - { - DCSrc = DCDest; - } - DestRect.left = XOriginDest; DestRect.top = YOriginDest; DestRect.right = XOriginDest + WidthDest; @@ -121,35 +108,35 @@ NtGdiAlphaBlend( !SourceRect.right || !SourceRect.bottom) { - if (hDCSrc != hDCDest) - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); return TRUE; } + /* Prepare DCs for blit */ + DPRINT("Preparing DCs for blit\n"); + DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect); + /* Determine surfaces to be used in the bitblt */ BitmapDest = DCDest->dclevel.pSurface; if (!BitmapDest) { - if (hDCSrc != hDCDest) - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); - return FALSE; + bResult = FALSE ; + goto leave ; } BitmapSrc = DCSrc->dclevel.pSurface; if (!BitmapSrc) { - if (hDCSrc != hDCDest) - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); - return FALSE; + bResult = FALSE; + goto leave; } /* Create the XLATEOBJ. */ EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); /* Perform the alpha blend operation */ + DPRINT("Performing the alpha Blend\n"); bResult = IntEngAlphaBlend(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, DCDest->rosdc.CombinedClip, @@ -159,9 +146,11 @@ NtGdiAlphaBlend( &BlendObj); EXLATEOBJ_vCleanup(&exlo); - DC_UnlockDc(DCDest); - if (hDCSrc != hDCDest) - DC_UnlockDc(DCSrc); +leave : + DPRINT("Finishing blit\n"); + DC_vFinishBlit(DCDest, DCSrc); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); return bResult; } @@ -182,59 +171,64 @@ NtGdiBitBlt( { PDC DCDest; PDC DCSrc = NULL; + HDC ahDC[2]; + PGDIOBJ apObj[2]; PDC_ATTR pdcattr = NULL; SURFACE *BitmapDest, *BitmapSrc = NULL; - RECTL DestRect; + RECTL DestRect, SourceRect; POINTL SourcePoint; BOOL Status = FALSE; EXLATEOBJ exlo; XLATEOBJ *XlateObj = NULL; BOOL UsesSource = ROP3_USES_SOURCE(ROP); - DCDest = DC_LockDc(hDCDest); + DPRINT("Locking DCs\n"); + ahDC[0] = hDCDest; + ahDC[1] = hDCSrc ; + GDIOBJ_LockMultipleObjs(2, ahDC, apObj); + DCDest = apObj[0]; + DCSrc = apObj[1]; + if (NULL == DCDest) { + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest); return FALSE; } if (DCDest->dctype == DC_TYPE_INFO) { - DC_UnlockDc(DCDest); + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); /* Yes, Windows really returns TRUE in this case */ return TRUE; } if (UsesSource) { - if (hDCSrc != hDCDest) + if (NULL == DCSrc) { - DCSrc = DC_LockDc(hDCSrc); - if (NULL == DCSrc) - { - DC_UnlockDc(DCDest); - DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc); - return FALSE; - } - if (DCSrc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); + DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc); + return FALSE; } - else + if (DCSrc->dctype == DC_TYPE_INFO) { - DCSrc = DCDest; + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; } } + else if(DCSrc) + { + DPRINT1("Getting a valid Source handle without using source!!!\n"); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + DCSrc = NULL ; + } pdcattr = DCDest->pdcattr; - if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) - DC_vUpdateFillBrush(DCDest); - DestRect.left = XDest; DestRect.top = YDest; DestRect.right = XDest+Width; @@ -255,8 +249,19 @@ NtGdiBitBlt( SourcePoint.x += DCSrc->ptlDCOrig.x; SourcePoint.y += DCSrc->ptlDCOrig.y; + /* Calculate Source Rect */ + SourceRect.left = SourcePoint.x; + SourceRect.top = SourcePoint.y; + SourceRect.right = SourcePoint.x + DestRect.right - DestRect.left; + SourceRect.bottom = SourcePoint.y + DestRect.bottom - DestRect.top ; } + /* Prepare blit */ + DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect); + + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(DCDest); + /* Determine surfaces to be used in the bitblt */ BitmapDest = DCDest->dclevel.pSurface; if (!BitmapDest) @@ -291,14 +296,15 @@ NtGdiBitBlt( &DCDest->dclevel.pbrFill->ptOrigin, ROP3_TO_ROP4(ROP)); - if (UsesSource) + if (UsesSource) EXLATEOBJ_vCleanup(&exlo); cleanup: - if (UsesSource && hDCSrc != hDCDest) + DC_vFinishBlit(DCDest, DCSrc); + if (UsesSource) { - DC_UnlockDc(DCSrc); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); } - DC_UnlockDc(DCDest); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); return Status; } @@ -318,97 +324,38 @@ NtGdiTransparentBlt( COLORREF TransColor) { PDC DCDest, DCSrc; + HDC ahDC[2]; + PGDIOBJ apObj[2]; RECTL rcDest, rcSrc; SURFACE *BitmapDest, *BitmapSrc = NULL; - HPALETTE SourcePalette = 0, DestPalette = 0; - PPALETTE PalDestGDI, PalSourceGDI; ULONG TransparentColor = 0; BOOL Ret = FALSE; EXLATEOBJ exlo; - if(!(DCDest = DC_LockDc(hdcDst))) - { - DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcDst); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - if (DCDest->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(DCDest); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } + DPRINT("Locking DCs\n"); + ahDC[0] = hdcDst; + ahDC[1] = hdcSrc ; + GDIOBJ_LockMultipleObjs(2, ahDC, apObj); + DCDest = apObj[0]; + DCSrc = apObj[1]; - if((hdcDst != hdcSrc) && !(DCSrc = DC_LockDc(hdcSrc))) + if ((NULL == DCDest) || (NULL == DCSrc)) { - DC_UnlockDc(DCDest); - DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiTransparentBlt\n", hdcSrc); + DPRINT1("Invalid dc handle (dest=0x%08x, src=0x%08x) passed to NtGdiAlphaBlend\n", hdcDst, hdcSrc); SetLastWin32Error(ERROR_INVALID_HANDLE); + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + if(DCDest) GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); return FALSE; } - if(hdcDst == hdcSrc) + if (DCDest->dctype == DC_TYPE_INFO || DCDest->dctype == DCTYPE_INFO) { - DCSrc = DCDest; - } - - if (DCSrc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(DCSrc); - if(hdcDst != hdcSrc) - { - DC_UnlockDc(DCDest); - } + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); /* Yes, Windows really returns TRUE in this case */ return TRUE; } - BitmapDest = DCDest->dclevel.pSurface; - if (!BitmapDest) - { - goto done; - } - - BitmapSrc = DCSrc->dclevel.pSurface; - if (!BitmapSrc) - { - goto done; - } - - DestPalette = BitmapDest->hDIBPalette; - if (!DestPalette) DestPalette = pPrimarySurface->devinfo.hpalDefault; - - SourcePalette = BitmapSrc->hDIBPalette; - if (!SourcePalette) SourcePalette = pPrimarySurface->devinfo.hpalDefault; - - if(!(PalSourceGDI = PALETTE_LockPalette(SourcePalette))) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - goto done; - } - PALETTE_UnlockPalette(PalSourceGDI); - - if(DestPalette != SourcePalette) - { - if (!(PalDestGDI = PALETTE_LockPalette(DestPalette))) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - goto done; - } - PALETTE_UnlockPalette(PalDestGDI); - } - else - { - PalDestGDI = PalSourceGDI; - } - - /* Translate Transparent (RGB) Color to the source palette */ - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, PalSourceGDI, 0, 0, 0); - TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor); - EXLATEOBJ_vCleanup(&exlo); - - EXLATEOBJ_vInitialize(&exlo, PalSourceGDI, PalDestGDI, 0, 0, 0); - rcDest.left = xDst; rcDest.top = yDst; rcDest.right = rcDest.left + cxDst; @@ -431,17 +378,39 @@ NtGdiTransparentBlt( rcSrc.right += DCSrc->ptlDCOrig.x; rcSrc.bottom += DCSrc->ptlDCOrig.y; + /* Prepare for blit */ + DC_vPrepareDCsForBlit(DCDest, rcDest, DCSrc, rcSrc); + + BitmapDest = DCDest->dclevel.pSurface; + if (!BitmapDest) + { + goto done; + } + + BitmapSrc = DCSrc->dclevel.pSurface; + if (!BitmapSrc) + { + goto done; + } + + /* Translate Transparent (RGB) Color to the source palette */ + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, BitmapSrc->ppal, 0, 0, 0); + TransparentColor = XLATEOBJ_iXlate(&exlo.xlo, (ULONG)TransColor); + EXLATEOBJ_vCleanup(&exlo); + + EXLATEOBJ_vInitXlateFromDCs(&exlo, DCSrc, DCDest); + Ret = IntEngTransparentBlt(&BitmapDest->SurfObj, &BitmapSrc->SurfObj, DCDest->rosdc.CombinedClip, &exlo.xlo, &rcDest, &rcSrc, TransparentColor, 0); -done: - DC_UnlockDc(DCSrc); - if(hdcDst != hdcSrc) - { - DC_UnlockDc(DCDest); - } EXLATEOBJ_vCleanup(&exlo); + +done: + DC_vFinishBlit(DCDest, DCSrc); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + return Ret; } @@ -674,6 +643,8 @@ GreStretchBltMask( PDC DCDest; PDC DCSrc = NULL; PDC DCMask = NULL; + HDC ahDC[3]; + PGDIOBJ apObj[3]; PDC_ATTR pdcattr; SURFACE *BitmapDest, *BitmapSrc = NULL; SURFACE *BitmapMask = NULL; @@ -692,52 +663,59 @@ GreStretchBltMask( return FALSE; } - DCDest = DC_LockDc(hDCDest); + DPRINT("Locking DCs\n"); + ahDC[0] = hDCDest; + ahDC[1] = hDCSrc ; + ahDC[2] = hDCMask ; + GDIOBJ_LockMultipleObjs(3, ahDC, apObj); + DCDest = apObj[0]; + DCSrc = apObj[1]; + DCMask = apObj[2]; + if (NULL == DCDest) { - DPRINT1("Invalid destination dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCDest); - SetLastWin32Error(ERROR_INVALID_HANDLE); + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject); + DPRINT("Invalid destination dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCDest); return FALSE; } if (DCDest->dctype == DC_TYPE_INFO) { - DC_UnlockDc(DCDest); + if(DCSrc) GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); /* Yes, Windows really returns TRUE in this case */ return TRUE; } if (UsesSource) { - if (hDCSrc != hDCDest) + if (NULL == DCSrc) { - DCSrc = DC_LockDc(hDCSrc); - if (NULL == DCSrc) - { - DC_UnlockDc(DCDest); - DPRINT1("Invalid source dc handle (0x%08x) passed to NtGdiStretchBlt\n", hDCSrc); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - if (DCSrc->dctype == DC_TYPE_INFO) - { - DC_UnlockDc(DCSrc); - DC_UnlockDc(DCDest); - /* Yes, Windows really returns TRUE in this case */ - return TRUE; - } + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); + if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject); + DPRINT("Invalid source dc handle (0x%08x) passed to NtGdiBitBlt\n", hDCSrc); + return FALSE; } - else + if (DCSrc->dctype == DC_TYPE_INFO) { - DCSrc = DCDest; + GDIOBJ_UnlockObjByPtr(&DCDest->BaseObject); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + if(DCMask) GDIOBJ_UnlockObjByPtr(&DCMask->BaseObject); + /* Yes, Windows really returns TRUE in this case */ + return TRUE; } } + else if(DCSrc) + { + DPRINT1("Getting a valid Source handle without using source!!!\n"); + GDIOBJ_UnlockObjByPtr(&DCSrc->BaseObject); + DCSrc = NULL ; + } pdcattr = DCDest->pdcattr; - if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) - DC_vUpdateFillBrush(DCDest); - DestRect.left = XOriginDest; DestRect.top = YOriginDest; DestRect.right = XOriginDest+WidthDest; @@ -767,6 +745,12 @@ GreStretchBltMask( BrushOrigin.x = 0; BrushOrigin.y = 0; + /* Only prepare Source and Dest, hdcMask represents a DIB */ + DC_vPrepareDCsForBlit(DCDest, DestRect, DCSrc, SourceRect); + + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(DCDest); + /* Determine surfaces to be used in the bitblt */ BitmapDest = DCDest->dclevel.pSurface; if (BitmapDest == NULL) @@ -787,28 +771,25 @@ GreStretchBltMask( BrushOrigin.y += DCDest->ptlDCOrig.y; /* Make mask surface for source surface */ - if (BitmapSrc && hDCMask) + if (BitmapSrc && DCMask) { - DCMask = DC_LockDc(hDCMask); - if (DCMask) + BitmapMask = DCMask->dclevel.pSurface; + if (BitmapMask && + (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc || + BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc)) { - BitmapMask = DCMask->dclevel.pSurface; - if (BitmapMask && - (BitmapMask->SurfObj.sizlBitmap.cx < WidthSrc || - BitmapMask->SurfObj.sizlBitmap.cy < HeightSrc)) - { - DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n", - BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy, - WidthSrc, HeightSrc); - goto failed; - } - /* Create mask offset point */ - MaskPoint.x = XOriginMask; - MaskPoint.y = YOriginMask; - IntLPtoDP(DCMask, &MaskPoint, 1); - MaskPoint.x += DCMask->ptlDCOrig.x; - MaskPoint.y += DCMask->ptlDCOrig.x; + DPRINT1("%dx%d mask is smaller than %dx%d bitmap\n", + BitmapMask->SurfObj.sizlBitmap.cx, BitmapMask->SurfObj.sizlBitmap.cy, + WidthSrc, HeightSrc); + EXLATEOBJ_vCleanup(&exlo); + goto failed; } + /* Create mask offset point */ + MaskPoint.x = XOriginMask; + MaskPoint.y = YOriginMask; + IntLPtoDP(DCMask, &MaskPoint, 1); + MaskPoint.x += DCMask->ptlDCOrig.x; + MaskPoint.y += DCMask->ptlDCOrig.x; } /* Perform the bitblt operation */ @@ -823,13 +804,14 @@ GreStretchBltMask( &DCDest->eboFill.BrushObject, &BrushOrigin, ROP3_TO_ROP4(ROP)); - -failed: if (UsesSource) { EXLATEOBJ_vCleanup(&exlo); } - if (UsesSource && hDCSrc != hDCDest) + +failed: + DC_vFinishBlit(DCDest, DCSrc); + if (UsesSource) { DC_UnlockDc(DCSrc); } @@ -889,19 +871,12 @@ IntPatBlt( { RECTL DestRect; SURFACE *psurf; - EBRUSHOBJ eboFill; + EBRUSHOBJ eboFill ; POINTL BrushOrigin; BOOL ret; ASSERT(pbrush); - psurf = pdc->dclevel.pSurface; - if (psurf == NULL) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - if (pbrush->flAttrs & GDIBRUSH_IS_NULL) { return TRUE; @@ -939,6 +914,13 @@ IntPatBlt( BrushOrigin.x = pbrush->ptOrigin.x + pdc->ptlDCOrig.x; BrushOrigin.y = pbrush->ptOrigin.y + pdc->ptlDCOrig.y; + DC_vPrepareDCsForBlit(pdc, DestRect, NULL, DestRect); + + psurf = pdc->dclevel.pSurface; + + if (pdc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(pdc); + EBRUSHOBJ_vInit(&eboFill, pbrush, pdc); ret = IntEngBitBlt( @@ -950,10 +932,12 @@ IntPatBlt( &DestRect, NULL, NULL, - &eboFill.BrushObject, // use pDC->eboFill + &eboFill.BrushObject, &BrushOrigin, ROP3_TO_ROP4(dwRop)); + DC_vFinishBlit(pdc, NULL); + EBRUSHOBJ_vCleanup(&eboFill); return ret; diff --git a/subsystems/win32/win32k/objects/bitmaps.c b/subsystems/win32/win32k/objects/bitmaps.c index f471a67e502..c3b7e8f148b 100644 --- a/subsystems/win32/win32k/objects/bitmaps.c +++ b/subsystems/win32/win32k/objects/bitmaps.c @@ -22,110 +22,198 @@ #define NDEBUG #include -HBITMAP APIENTRY -IntGdiCreateBitmap( - INT Width, - INT Height, - UINT Planes, - UINT BitsPixel, - IN OPTIONAL LPBYTE pBits) +LONG APIENTRY +IntSetBitmapBits( + PSURFACE psurf, + DWORD Bytes, + IN PBYTE Bits) { - HBITMAP hBitmap; - SIZEL Size; - LONG WidthBytes; - PSURFACE psurfBmp; + /* Don't copy more bytes than the buffer has */ + Bytes = min(Bytes, psurf->SurfObj.cjBits); - /* NOTE: Windows also doesn't store nr. of planes separately! */ - BitsPixel = BITMAP_GetRealBitsPixel(BitsPixel * Planes); + RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes); - /* Check parameters */ - if (BitsPixel == 0 || Width <= 0 || Width >= 0x8000000 || Height == 0) + return Bytes; +} + +void +NTAPI +UnsafeSetBitmapBits( + PSURFACE psurf, + IN ULONG cjBits, + IN PVOID pvBits) +{ + PUCHAR pjDst, pjSrc; + LONG lDeltaDst, lDeltaSrc; + ULONG nWidth, nHeight, cBitsPixel; + + nWidth = psurf->SurfObj.sizlBitmap.cx; + nHeight = psurf->SurfObj.sizlBitmap.cy; + cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); + + /* Get pointers */ + pjDst = psurf->SurfObj.pvScan0; + pjSrc = pvBits; + lDeltaDst = psurf->SurfObj.lDelta; + lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); + + while (nHeight--) { - DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", - Width, Height, BitsPixel); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; + /* Copy one line */ + memcpy(pjDst, pjSrc, lDeltaSrc); + pjSrc += lDeltaSrc; + pjDst += lDeltaDst; } - WidthBytes = BITMAP_GetWidthBytes(Width, BitsPixel); +} - Size.cx = Width; - Size.cy = abs(Height); +HBITMAP +APIENTRY +GreCreateBitmapEx( + IN INT nWidth, + IN INT nHeight, + IN ULONG cjWidthBytes, + IN ULONG iFormat, + IN USHORT fjBitmap, + IN ULONG cjSizeImage, + IN OPTIONAL PVOID pvBits, + IN FLONG flags) +{ + PSURFACE psurf; + SURFOBJ *pso; + HBITMAP hbmp; + PVOID pvCompressedBits; + SIZEL sizl; - /* Make sure that cjBits will not overflow */ - if ((ULONGLONG)WidthBytes * Size.cy >= 0x100000000ULL) + /* Verify format */ + if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL; + + /* Allocate a surface */ + psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat); + if (!psurf) { - DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", - Width, Height, BitsPixel); - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } - - /* Create the bitmap object. */ - hBitmap = IntCreateBitmap(Size, WidthBytes, - BitmapFormat(BitsPixel, BI_RGB), - (Height < 0 ? BMF_TOPDOWN : 0) | - (NULL == pBits ? 0 : BMF_NOZEROINIT), NULL); - if (!hBitmap) - { - DPRINT("IntGdiCreateBitmap: returned 0\n"); - return 0; - } - - psurfBmp = SURFACE_LockSurface(hBitmap); - if (psurfBmp == NULL) - { - GreDeleteObject(hBitmap); + DPRINT1("SURFACE_AllocSurface failed.\n"); return NULL; } - psurfBmp->flFlags = BITMAPOBJ_IS_APIBITMAP; - psurfBmp->hDC = NULL; // Fixme + /* Get the handle for the bitmap and the surfobj */ + hbmp = (HBITMAP)psurf->SurfObj.hsurf; + pso = &psurf->SurfObj; - if (NULL != pBits) + /* The infamous RLE hack */ + if (iFormat == BMF_4RLE || iFormat == BMF_8RLE) { - IntSetBitmapBits(psurfBmp, psurfBmp->SurfObj.cjBits, pBits); + sizl.cx = nWidth; + sizl.cy = nHeight; + pvCompressedBits = pvBits; + pvBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB); + DecompressBitmap(sizl, pvCompressedBits, pvBits, pso->lDelta, iFormat); + fjBitmap |= BMF_RLE_HACK; } - SURFACE_UnlockSurface(psurfBmp); + /* Mark as API bitmap */ + psurf->flags |= (flags | API_BITMAP); - DPRINT("IntGdiCreateBitmap : %dx%d, %d BPP colors, topdown %d, returning %08x\n", - Size.cx, Size.cy, BitsPixel, (Height < 0 ? 1 : 0), hBitmap); + /* Set the bitmap bits */ + if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits)) + { + /* Bail out if that failed */ + DPRINT1("SURFACE_bSetBitmapBits failed.\n"); + SURFACE_FreeSurfaceByHandle(hbmp); + return NULL; + } - return hBitmap; + /* Unlock the surface and return */ + SURFACE_UnlockSurface(psurf); + return hbmp; } +/* Creates a DDB surface, + * as in CreateCompatibleBitmap or CreateBitmap. + */ +HBITMAP +APIENTRY +GreCreateBitmap( + IN INT nWidth, + IN INT nHeight, + IN UINT cPlanes, + IN UINT cBitsPixel, + IN OPTIONAL PVOID pvBits) +{ + /* Call the extended function */ + return GreCreateBitmapEx(nWidth, + nHeight, + 0, /* auto width */ + BitmapFormat(cBitsPixel * cPlanes, BI_RGB), + 0, /* no bitmap flags */ + 0, /* auto size */ + pvBits, + DDB_SURFACE /* DDB */); +} -HBITMAP APIENTRY +HBITMAP +APIENTRY NtGdiCreateBitmap( - INT Width, - INT Height, - UINT Planes, - UINT BitsPixel, + IN INT nWidth, + IN INT nHeight, + IN UINT cPlanes, + IN UINT cBitsPixel, IN OPTIONAL LPBYTE pUnsafeBits) { + HBITMAP hbmp; + ULONG cjWidthBytes, iFormat; + + /* NOTE: Windows also doesn't store nr. of planes separately! */ + cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes); + + /* Calculate bitmap format */ + iFormat = BitmapFormat(cBitsPixel, BI_RGB); + + /* Check parameters */ + if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0) + { + DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", + nWidth, nHeight, cBitsPixel); + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* Make sure that cjBits will not overflow */ + cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); + if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL) + { + DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", + nWidth, nHeight, cBitsPixel); + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + + /* cBitsPixel = cBitsPixel * cPlanes now! */ + hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL); + if (pUnsafeBits) { - BOOL Hit = FALSE; - UINT cjBits = BITMAP_GetWidthBytes(Width, BitsPixel) * abs(Height); - - // FIXME: Use MmSecureVirtualMemory + PSURFACE psurf = SURFACE_LockSurface(hbmp); _SEH2_TRY { - ProbeForRead(pUnsafeBits, cjBits, 1); + ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1); + UnsafeSetBitmapBits(psurf, 0, pUnsafeBits); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Hit = TRUE; + SURFACE_UnlockSurface(psurf); + SURFACE_FreeSurfaceByHandle(hbmp); + _SEH2_YIELD(return NULL;) } _SEH2_END - if (Hit) return 0; + SURFACE_UnlockSurface(psurf); } - return IntGdiCreateBitmap(Width, Height, Planes, BitsPixel, pUnsafeBits); + return hbmp; } + HBITMAP FASTCALL IntCreateCompatibleBitmap( PDC Dc, @@ -143,11 +231,21 @@ IntCreateCompatibleBitmap( { if (Dc->dctype != DC_TYPE_MEMORY) { - Bmp = IntGdiCreateBitmap(abs(Width), - abs(Height), - IntGdiGetDeviceCaps(Dc,PLANES), - IntGdiGetDeviceCaps(Dc,BITSPIXEL), - NULL); + PSURFACE psurf; + + Bmp = GreCreateBitmap(abs(Width), + abs(Height), + 1, + Dc->ppdev->gdiinfo.cBitsPixel, + NULL); + psurf = SURFACE_LockSurface(Bmp); + ASSERT(psurf); + /* Set palette */ + psurf->ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault); + /* Set flags */ + psurf->flags = API_BITMAP; + psurf->hdc = NULL; // Fixme + SURFACE_UnlockSurface(psurf); } else { @@ -160,83 +258,71 @@ IntCreateCompatibleBitmap( { if (Count == sizeof(BITMAP)) { - /* We have a bitmap bug!!! W/O the HACK, we have white icons. + PSURFACE psurfBmp; - MSDN Note: When a memory device context is created, it initially - has a 1-by-1 monochrome bitmap selected into it. If this memory - device context is used in CreateCompatibleBitmap, the bitmap that - is created is a monochrome bitmap. To create a color bitmap, use - the hDC that was used to create the memory device context, as - shown in the following code: - - HDC memDC = CreateCompatibleDC(hDC); - HBITMAP memBM = CreateCompatibleBitmap(hDC, nWidth, nHeight); - SelectObject(memDC, memBM); - */ - Bmp = IntGdiCreateBitmap(abs(Width), - abs(Height), - dibs.dsBm.bmPlanes, - IntGdiGetDeviceCaps(Dc,BITSPIXEL),//<-- HACK! dibs.dsBm.bmBitsPixel, // <-- Correct! - NULL); + Bmp = GreCreateBitmap(abs(Width), + abs(Height), + 1, + dibs.dsBm.bmBitsPixel, + NULL); + psurfBmp = SURFACE_LockSurface(Bmp); + ASSERT(psurfBmp); + /* Assign palette */ + psurfBmp->ppal = psurf->ppal; + GDIOBJ_IncrementShareCount((POBJ)psurf->ppal); + /* Set flags */ + psurfBmp->flags = API_BITMAP; + psurfBmp->hdc = NULL; // Fixme + SURFACE_UnlockSurface(psurfBmp); } else { /* A DIB section is selected in the DC */ - BITMAPINFO *bi; + BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0}; PVOID Bits; + BITMAPINFO* bi = (BITMAPINFO*)buf; - /* Allocate memory for a BITMAPINFOHEADER structure and a - color table. The maximum number of colors in a color table - is 256 which corresponds to a bitmap with depth 8. - Bitmaps with higher depths don't have color tables. */ - bi = ExAllocatePoolWithTag(PagedPool, - sizeof(BITMAPINFOHEADER) + - 256 * sizeof(RGBQUAD), - TAG_TEMP); + bi->bmiHeader.biSize = sizeof(bi->bmiHeader); + bi->bmiHeader.biWidth = Width; + bi->bmiHeader.biHeight = Height; + bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes; + bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount; + bi->bmiHeader.biCompression = dibs.dsBmih.biCompression; + bi->bmiHeader.biSizeImage = 0; + bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter; + bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter; + bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed; + bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant; - if (bi) + if (bi->bmiHeader.biCompression == BI_BITFIELDS) { - bi->bmiHeader.biSize = sizeof(bi->bmiHeader); - bi->bmiHeader.biWidth = Width; - bi->bmiHeader.biHeight = Height; - bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes; - bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount; - bi->bmiHeader.biCompression = dibs.dsBmih.biCompression; - bi->bmiHeader.biSizeImage = 0; - bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter; - bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter; - bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed; - bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant; + /* Copy the color masks */ + RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD)); + } + else if (bi->bmiHeader.biBitCount <= 8) + { + /* Copy the color table */ + UINT Index; + PPALETTE PalGDI; - if (bi->bmiHeader.biCompression == BI_BITFIELDS) + if (!psurf->ppal) { - /* Copy the color masks */ - RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3 * sizeof(DWORD)); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return 0; } - else if (bi->bmiHeader.biBitCount <= 8) + + PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr); + + for (Index = 0; + Index < 256 && Index < PalGDI->NumColors; + Index++) { - /* Copy the color table */ - UINT Index; - PPALETTE PalGDI = PALETTE_LockPalette(psurf->hDIBPalette); - - if (!PalGDI) - { - ExFreePoolWithTag(bi, TAG_TEMP); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return 0; - } - - for (Index = 0; - Index < 256 && Index < PalGDI->NumColors; - Index++) - { - bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed; - bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen; - bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue; - bi->bmiColors[Index].rgbReserved = 0; - } - PALETTE_UnlockPalette(PalGDI); + bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed; + bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen; + bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue; + bi->bmiColors[Index].rgbReserved = 0; } + PALETTE_UnlockPalette(PalGDI); Bmp = DIB_CreateDIBSection(Dc, bi, @@ -245,8 +331,6 @@ IntCreateCompatibleBitmap( NULL, 0, 0); - - ExFreePoolWithTag(bi, TAG_TEMP); return Bmp; } } @@ -272,7 +356,7 @@ NtGdiCreateCompatibleBitmap( } if (!hDC) - return IntGdiCreateBitmap(Width, Height, 1, 1, 0); + return GreCreateBitmap(Width, Height, 1, 1, 0); Dc = DC_LockDc(hDC); @@ -313,7 +397,7 @@ NtGdiGetBitmapDimension( _SEH2_TRY { ProbeForWrite(Dimension, sizeof(SIZE), 1); - *Dimension = psurfBmp->dimension; + *Dimension = psurfBmp->sizlDim; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -334,8 +418,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) BOOL bInRect = FALSE; SURFACE *psurf; SURFOBJ *pso; - HPALETTE hpal = 0; - PPALETTE ppal; EXLATEOBJ exlo; HBITMAP hBmpTmp; @@ -361,21 +443,8 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) psurf = dc->dclevel.pSurface; if (psurf) { - pso = &psurf->SurfObj; - hpal = psurf->hDIBPalette; - if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault; - ppal = PALETTE_ShareLockPalette(hpal); - - if (psurf->SurfObj.iBitmapFormat == BMF_1BPP && !psurf->hSecure) - { - /* FIXME: palette should be gpalMono already ! */ - EXLATEOBJ_vInitialize(&exlo, &gpalMono, &gpalRGB, 0, 0xffffff, 0); - } - else - { - EXLATEOBJ_vInitialize(&exlo, ppal, &gpalRGB, 0, 0xffffff, 0); - } - + pso = &psurf->SurfObj; + EXLATEOBJ_vInitialize(&exlo, psurf->ppal, &gpalRGB, 0, 0xffffff, 0); // check if this DC has a DIB behind it... if (pso->pvScan0) // STYPE_BITMAP == pso->iType { @@ -385,7 +454,6 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) } EXLATEOBJ_vCleanup(&exlo); - PALETTE_ShareUnlockPalette(ppal); } } DC_UnlockDc(dc); @@ -412,7 +480,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos) 0, 0); - //HBITMAP hBmpTmp = IntGdiCreateBitmap(1, 1, 1, 32, NULL); + //HBITMAP hBmpTmp = GreCreateBitmap(1, 1, 1, 32, NULL); if (hBmpTmp) { HBITMAP hBmpOld = (HBITMAP)NtGdiSelectBitmap(hDCTmp, hBmpTmp); @@ -482,6 +550,36 @@ IntGetBitmapBits( return ret; } +VOID +FASTCALL +UnsafeGetBitmapBits( + PSURFACE psurf, + DWORD Bytes, + OUT PBYTE pvBits) +{ + PUCHAR pjDst, pjSrc; + LONG lDeltaDst, lDeltaSrc; + ULONG nWidth, nHeight, cBitsPixel; + + nWidth = psurf->SurfObj.sizlBitmap.cx; + nHeight = psurf->SurfObj.sizlBitmap.cy; + cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); + + /* Get pointers */ + pjSrc = psurf->SurfObj.pvScan0; + pjDst = pvBits; + lDeltaSrc = psurf->SurfObj.lDelta; + lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); + + while (nHeight--) + { + /* Copy one line */ + RtlCopyMemory(pjDst, pjSrc, lDeltaDst); + pjSrc += lDeltaSrc; + pjDst += lDeltaDst; + } +} + LONG APIENTRY NtGdiGetBitmapBits( HBITMAP hBitmap, @@ -503,7 +601,7 @@ NtGdiGetBitmapBits( return 0; } - bmSize = BITMAP_GetWidthBytes(psurf->SurfObj.sizlBitmap.cx, + bmSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx, BitsPerFormat(psurf->SurfObj.iBitmapFormat)) * abs(psurf->SurfObj.sizlBitmap.cy); @@ -521,7 +619,8 @@ NtGdiGetBitmapBits( _SEH2_TRY { ProbeForWrite(pUnsafeBits, Bytes, 1); - ret = IntGetBitmapBits(psurf, Bytes, pUnsafeBits); + UnsafeGetBitmapBits(psurf, Bytes, pUnsafeBits); + ret = Bytes; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -535,46 +634,6 @@ NtGdiGetBitmapBits( } -LONG APIENTRY -IntSetBitmapBits( - PSURFACE psurf, - DWORD Bytes, - IN PBYTE Bits) -{ - LONG ret; - - /* Don't copy more bytes than the buffer has */ - Bytes = min(Bytes, psurf->SurfObj.cjBits); - -#if 0 - /* FIXME: call DDI specific function here if available */ - if (psurf->DDBitmap) - { - DPRINT("Calling device specific BitmapBits\n"); - if (psurf->DDBitmap->funcs->pBitmapBits) - { - ret = psurf->DDBitmap->funcs->pBitmapBits(hBitmap, - (void *)Bits, - Bytes, - DDB_SET); - } - else - { - DPRINT("BitmapBits == NULL??\n"); - ret = 0; - } - } - else -#endif - { - RtlCopyMemory(psurf->SurfObj.pvBits, Bits, Bytes); - ret = Bytes; - } - - return ret; -} - - LONG APIENTRY NtGdiSetBitmapBits( HBITMAP hBitmap, @@ -599,7 +658,8 @@ NtGdiSetBitmapBits( _SEH2_TRY { ProbeForRead(pUnsafeBits, Bytes, 1); - ret = IntSetBitmapBits(psurf, Bytes, pUnsafeBits); + UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits); + ret = 1; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -637,7 +697,7 @@ NtGdiSetBitmapDimension( _SEH2_TRY { ProbeForWrite(Size, sizeof(SIZE), 1); - *Size = psurf->dimension; + *Size = psurf->sizlDim; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -647,8 +707,8 @@ NtGdiSetBitmapDimension( } /* The dimension is changed even if writing the old value failed */ - psurf->dimension.cx = Width; - psurf->dimension.cy = Height; + psurf->sizlDim.cx = Width; + psurf->sizlDim.cy = Height; SURFACE_UnlockSurface(psurf); @@ -665,7 +725,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color) switch (*Color >> 24) { case 0x10: /* DIBINDEX */ - if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1) + if (IntGetDIBColorTable(hDC, LOWORD(*Color), 1, &quad) == 1) { *Color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue); } @@ -707,7 +767,7 @@ VOID IntHandleSpecialColorType(HDC hDC, COLORREF* Color) default: DPRINT("Unsupported color type %d passed\n", *Color >> 24); break; - } + } } BOOL APIENTRY @@ -786,40 +846,6 @@ BITMAP_GetRealBitsPixel(UINT nBitsPixel) return 0; } -INT FASTCALL -BITMAP_GetWidthBytes(INT bmWidth, INT bpp) -{ -#if 0 - switch (bpp) - { - case 1: - return 2 * ((bmWidth+15) >> 4); - - case 24: - bmWidth *= 3; /* fall through */ - case 8: - return bmWidth + (bmWidth & 1); - - case 32: - return bmWidth * 4; - - case 16: - case 15: - return bmWidth * 2; - - case 4: - return 2 * ((bmWidth+3) >> 2); - - default: - DPRINT ("stub"); - } - - return -1; -#endif - - return ((bmWidth * bpp + 15) & ~15) >> 3; -} - HBITMAP FASTCALL BITMAP_CopyBitmap(HBITMAP hBitmap) { @@ -833,7 +859,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap) return 0; } - Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP); + Bitmap = SURFACE_LockSurface(hBitmap); if (Bitmap == NULL) { return 0; @@ -846,34 +872,23 @@ BITMAP_CopyBitmap(HBITMAP hBitmap) Size.cx = abs(bm.bmWidth); Size.cy = abs(bm.bmHeight); - res = IntCreateBitmap(Size, - bm.bmWidthBytes, - BitmapFormat(bm.bmBitsPixel * bm.bmPlanes, BI_RGB), - (bm.bmHeight < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT, - NULL); + res = GreCreateBitmapEx(Size.cx, + Size.cy, + bm.bmWidthBytes, + Bitmap->SurfObj.iBitmapFormat, + Bitmap->SurfObj.fjBitmap, + Bitmap->SurfObj.cjBits, + NULL, + Bitmap->flags); + if (res) { - PBYTE buf; - - resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP); + resBitmap = SURFACE_LockSurface(res); if (resBitmap) { - buf = ExAllocatePoolWithTag(PagedPool, - bm.bmWidthBytes * abs(bm.bmHeight), - TAG_BITMAP); - if (buf == NULL) - { - GDIOBJ_UnlockObjByPtr((POBJ)resBitmap); - GDIOBJ_UnlockObjByPtr((POBJ)Bitmap); - GreDeleteObject(res); - return 0; - } - IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf); - IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf); - ExFreePoolWithTag(buf,TAG_BITMAP); - resBitmap->flFlags = Bitmap->flFlags; - GDIOBJ_UnlockObjByPtr((POBJ)resBitmap); + IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits); + SURFACE_UnlockSurface(resBitmap); } else { @@ -882,7 +897,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap) } } - GDIOBJ_UnlockObjByPtr((POBJ)Bitmap); + SURFACE_UnlockSurface(Bitmap); return res; } @@ -900,15 +915,17 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer) pBitmap->bmType = 0; pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx; pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy; - pBitmap->bmWidthBytes = abs(psurf->SurfObj.lDelta); pBitmap->bmPlanes = 1; pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat); + pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel); /* Check for DIB section */ if (psurf->hSecure) { /* Set bmBits in this case */ pBitmap->bmBits = psurf->SurfObj.pvBits; + /* DIBs data are 32 bits aligned */ + pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel); if (Count >= sizeof(DIBSECTION)) { @@ -920,38 +937,44 @@ BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer) pds->dsBmih.biHeight = pds->dsBm.bmHeight; pds->dsBmih.biPlanes = pds->dsBm.bmPlanes; pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel; - switch (psurf->SurfObj.iBitmapFormat) - { - /* FIXME: What about BI_BITFIELDS? */ - case BMF_1BPP: - case BMF_4BPP: - case BMF_8BPP: - case BMF_16BPP: - case BMF_24BPP: - case BMF_32BPP: - pds->dsBmih.biCompression = BI_RGB; - break; - case BMF_4RLE: - pds->dsBmih.biCompression = BI_RLE4; - break; - case BMF_8RLE: - pds->dsBmih.biCompression = BI_RLE8; - break; - case BMF_JPEG: - pds->dsBmih.biCompression = BI_JPEG; - break; - case BMF_PNG: - pds->dsBmih.biCompression = BI_PNG; - break; - } + if(psurf->ppal->flFlags & PAL_BITFIELDS) + { + pds->dsBmih.biCompression = BI_BITFIELDS; + } + else + { + switch (psurf->SurfObj.iBitmapFormat) + { + case BMF_1BPP: + case BMF_4BPP: + case BMF_8BPP: + case BMF_16BPP: + case BMF_24BPP: + case BMF_32BPP: + pds->dsBmih.biCompression = BI_RGB; + break; + case BMF_4RLE: + pds->dsBmih.biCompression = BI_RLE4; + break; + case BMF_8RLE: + pds->dsBmih.biCompression = BI_RLE8; + break; + case BMF_JPEG: + pds->dsBmih.biCompression = BI_JPEG; + break; + case BMF_PNG: + pds->dsBmih.biCompression = BI_PNG; + break; + } + } pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits; pds->dsBmih.biXPelsPerMeter = 0; pds->dsBmih.biYPelsPerMeter = 0; - pds->dsBmih.biClrUsed = psurf->biClrUsed; + pds->dsBmih.biClrUsed = psurf->ppal->NumColors; pds->dsBmih.biClrImportant = psurf->biClrImportant; - pds->dsBitfields[0] = psurf->dsBitfields[0]; - pds->dsBitfields[1] = psurf->dsBitfields[1]; - pds->dsBitfields[2] = psurf->dsBitfields[2]; + pds->dsBitfields[0] = psurf->ppal->RedMask; + pds->dsBitfields[1] = psurf->ppal->GreenMask; + pds->dsBitfields[2] = psurf->ppal->BlueMask; pds->dshSection = psurf->hDIBSection; pds->dsOffset = psurf->dwOffset; @@ -975,14 +998,15 @@ APIENTRY NtGdiGetDCforBitmap( IN HBITMAP hsurf) { - HDC hDC = NULL; + HDC hdc = NULL; PSURFACE psurf = SURFACE_LockSurface(hsurf); if (psurf) { - hDC = psurf->hDC; + hdc = psurf->hdc; SURFACE_UnlockSurface(psurf); } - return hDC; + return hdc; } + /* EOF */ diff --git a/subsystems/win32/win32k/objects/brush.c b/subsystems/win32/win32k/objects/brush.c index c8682f6a849..d1f8175d62a 100644 --- a/subsystems/win32/win32k/objects/brush.c +++ b/subsystems/win32/win32k/objects/brush.c @@ -1,9 +1,9 @@ -/* +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS win32 subsystem * PURPOSE: Functions for brushes * FILE: subsystem/win32/win32k/objects/brush.c - * PROGRAMER: + * PROGRAMER: */ #include @@ -19,13 +19,13 @@ typedef struct _GDI_OBJ_ATTR_FREELIST DWORD nEntries; PVOID AttrList[GDIOBJATTRFREE]; } GDI_OBJ_ATTR_FREELIST, *PGDI_OBJ_ATTR_FREELIST; - + typedef struct _GDI_OBJ_ATTR_ENTRY { RGN_ATTR Attr[GDIOBJATTRFREE]; } GDI_OBJ_ATTR_ENTRY, *PGDI_OBJ_ATTR_ENTRY; -static const USHORT HatchBrushes[NB_HATCH_STYLES][8] = +static const ULONG HatchBrushes[NB_HATCH_STYLES][8] = { {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF}, /* HS_HORIZONTAL */ {0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7}, /* HS_VERTICAL */ @@ -46,7 +46,7 @@ AllocateObjectAttr(VOID) PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList; PGDI_OBJ_ATTR_ENTRY pGdiObjAttrEntry; int i; - + pti = PsGetCurrentThreadWin32Thread(); if (pti->pgdiBrushAttr) { @@ -127,9 +127,9 @@ FreeObjectAttr(PVOID pAttr) PGDI_OBJ_ATTR_FREELIST pGdiObjAttrFreeList; pti = PsGetCurrentThreadWin32Thread(); - + if (!pti) return; - + if (!pti->pgdiBrushAttr) { // If it is null, just cache it for the next time. pti->pgdiBrushAttr = pAttr; @@ -244,129 +244,6 @@ BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer) return sizeof(LOGBRUSH); } -/** - * @name CalculateColorTableSize - * - * Internal routine to calculate the number of color table entries. - * - * @param BitmapInfoHeader - * Input bitmap information header, can be any version of - * BITMAPINFOHEADER or BITMAPCOREHEADER. - * - * @param ColorSpec - * Pointer to variable which specifiing the color mode (DIB_RGB_COLORS - * or DIB_RGB_COLORS). On successful return this value is normalized - * according to the bitmap info. - * - * @param ColorTableSize - * On successful return this variable is filled with number of - * entries in color table for the image with specified parameters. - * - * @return - * TRUE if the input values together form a valid image, FALSE otherwise. - */ -BOOL -APIENTRY -CalculateColorTableSize( - CONST BITMAPINFOHEADER *BitmapInfoHeader, - UINT *ColorSpec, - UINT *ColorTableSize) -{ - WORD BitCount; - DWORD ClrUsed; - DWORD Compression; - - /* - * At first get some basic parameters from the passed BitmapInfoHeader - * structure. It can have one of the following formats: - * - BITMAPCOREHEADER (the oldest one with totally different layout - * from the others) - * - BITMAPINFOHEADER (the standard and most common header) - * - BITMAPV4HEADER (extension of BITMAPINFOHEADER) - * - BITMAPV5HEADER (extension of BITMAPV4HEADER) - */ - if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER)) - { - BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount; - ClrUsed = 0; - Compression = BI_RGB; - } - else - { - BitCount = BitmapInfoHeader->biBitCount; - ClrUsed = BitmapInfoHeader->biClrUsed; - Compression = BitmapInfoHeader->biCompression; - } - - switch (Compression) - { - case BI_BITFIELDS: - if (*ColorSpec == DIB_PAL_COLORS) - *ColorSpec = DIB_RGB_COLORS; - - if (BitCount != 16 && BitCount != 32) - return FALSE; - - /* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in - * the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask). - * For BITMAPINFOHEADER the color masks are stored in the palette. */ - if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER)) - *ColorTableSize = 0; - else - *ColorTableSize = 3; - - return TRUE; - - case BI_RGB: - switch (BitCount) - { - case 1: - *ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2; - return TRUE; - - case 4: - *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; - return TRUE; - - case 8: - *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; - return TRUE; - - default: - if (*ColorSpec == DIB_PAL_COLORS) - *ColorSpec = DIB_RGB_COLORS; - if (BitCount != 16 && BitCount != 24 && BitCount != 32) - return FALSE; - *ColorTableSize = ClrUsed; - return TRUE; - } - - case BI_RLE4: - if (BitCount == 4) - { - *ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16; - return TRUE; - } - return FALSE; - - case BI_RLE8: - if (BitCount == 8) - { - *ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256; - return TRUE; - } - return FALSE; - - case BI_JPEG: - case BI_PNG: - *ColorTableSize = ClrUsed; - return TRUE; - - default: - return FALSE; - } -} - HBRUSH APIENTRY IntGdiCreateDIBBrush( @@ -379,9 +256,7 @@ IntGdiCreateDIBBrush( PBRUSH pbrush; HBITMAP hPattern; ULONG_PTR DataPtr; - UINT PaletteEntryCount; - PSURFACE psurfPattern; - INT PaletteType; + PVOID pvDIBits; if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) { @@ -389,36 +264,19 @@ IntGdiCreateDIBBrush( return NULL; } - if (!CalculateColorTableSize(&BitmapInfo->bmiHeader, - &ColorSpec, - &PaletteEntryCount)) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return NULL; - } + DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec); - // FIXME: What about BI_BITFIELDS - DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize; - if (ColorSpec == DIB_RGB_COLORS) - DataPtr += PaletteEntryCount * sizeof(RGBQUAD); - else - DataPtr += PaletteEntryCount * sizeof(USHORT); - - hPattern = IntGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth, - BitmapInfo->bmiHeader.biHeight, - BitmapInfo->bmiHeader.biPlanes, - BitmapInfo->bmiHeader.biBitCount, - (PVOID)DataPtr); + hPattern = DIB_CreateDIBSection(NULL, BitmapInfo, ColorSpec, &pvDIBits, NULL, 0, 0); if (hPattern == NULL) { SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return NULL; } - - psurfPattern = SURFACE_LockSurface(hPattern); - ASSERT(psurfPattern != NULL); - psurfPattern->hDIBPalette = BuildDIBPalette(BitmapInfo, &PaletteType); - SURFACE_UnlockSurface(psurfPattern); + RtlCopyMemory(pvDIBits, + (PVOID)DataPtr, + DIB_GetDIBImageBytes(BitmapInfo->bmiHeader.biWidth, + BitmapInfo->bmiHeader.biHeight, + BitmapInfo->bmiHeader.biBitCount * BitmapInfo->bmiHeader.biPlanes)); pbrush = BRUSH_AllocBrushWithHandle(); if (pbrush == NULL) @@ -455,7 +313,7 @@ IntGdiCreateHatchBrush( return 0; } - hPattern = IntGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]); + hPattern = GreCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]); if (hPattern == NULL) { SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); diff --git a/subsystems/win32/win32k/objects/cliprgn.c b/subsystems/win32/win32k/objects/cliprgn.c index 63b629add84..8698bb3ee98 100644 --- a/subsystems/win32/win32k/objects/cliprgn.c +++ b/subsystems/win32/win32k/objects/cliprgn.c @@ -28,27 +28,16 @@ CLIPPING_UpdateGCRegion(DC* Dc) PROSRGNDATA CombinedRegion; HRGN hRgnVis = Dc->prgnVis->BaseObject.hHmgr; - /* Experiment with API region based on wine.. */ - if (Dc->rosdc.hClipRgn && Dc->dclevel.prgnMeta) + // would prefer this, but the rest of the code sucks +// ASSERT(Dc->rosdc.hGCClipRgn); +// ASSERT(Dc->rosdc.hClipRgn); + if (!Dc->prgnVis) { - PROSRGNDATA pClipRgn; - - if ((pClipRgn = RGNOBJAPI_Lock(Dc->rosdc.hClipRgn, NULL))) - { - if (!Dc->prgnAPI) Dc->prgnAPI = IntSysCreateRectpRgn( 0, 0, 0, 0 ); - - IntGdiCombineRgn( Dc->prgnAPI, - pClipRgn, - Dc->dclevel.prgnMeta, - RGN_AND ); - RGNOBJAPI_Unlock(pClipRgn); - } + DPRINT1("Warning, prgnVis is NULL!\n"); } else { - if (Dc->prgnAPI) - GreDeleteObject(((PROSRGNDATA)Dc->prgnAPI)->BaseObject.hHmgr); - Dc->prgnAPI = NULL; + hRgnVis = Dc->prgnVis->BaseObject.hHmgr ; } @@ -62,28 +51,27 @@ CLIPPING_UpdateGCRegion(DC* Dc) NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, Dc->ptlDCOrig.x, Dc->ptlDCOrig.y); - if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) - { - CLIPOBJ *CombinedClip; - - CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount, - CombinedRegion->Buffer, - &CombinedRegion->rdh.rcBound); + if((CombinedRegion = RGNOBJAPI_Lock(Dc->rosdc.hGCClipRgn, NULL))) + { + CLIPOBJ *CombinedClip; - RGNOBJAPI_Unlock(CombinedRegion); + CombinedClip = IntEngCreateClipRegion(CombinedRegion->rdh.nCount, + CombinedRegion->Buffer, + &CombinedRegion->rdh.rcBound); - if (!CombinedClip) - { - DPRINT1("IntEngCreateClipRegion() failed\n"); - return ERROR; - } + RGNOBJAPI_Unlock(CombinedRegion); - if (Dc->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + if ( !CombinedClip ) + { + DPRINT1("IntEngCreateClipRegion() failed\n"); + return ERROR; + } - Dc->rosdc.CombinedClip = CombinedClip; - } + if(Dc->rosdc.CombinedClip != NULL) + IntEngDeleteClipRegion(Dc->rosdc.CombinedClip); + Dc->rosdc.CombinedClip = CombinedClip ; + } return NtGdiOffsetRgn(Dc->rosdc.hGCClipRgn, -Dc->ptlDCOrig.x, -Dc->ptlDCOrig.y); } @@ -115,7 +103,6 @@ GdiSelectVisRgn(HDC hdc, HRGN hrgn) NtGdiOffsetRgn(dc->prgnVis->BaseObject.hHmgr, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y); CLIPPING_UpdateGCRegion(dc); } - DC_UnlockDc(dc); return retval; @@ -166,6 +153,7 @@ int FASTCALL GdiExtSelectClipRgn(PDC dc, else NtGdiCombineRgn(dc->rosdc.hClipRgn, dc->rosdc.hClipRgn, hrgn, fnMode); } + return CLIPPING_UpdateGCRegion(dc); } @@ -233,6 +221,7 @@ GdiGetClipBox(HDC hDC, PRECTL rc) retval = REGION_GetRgnBox(pRgnNew, rc); REGION_FreeRgnByHandle(pRgnNew->BaseObject.hHmgr); + DC_UnlockDc(dc); if(Unlock) REGION_UnlockRgn(pRgn); return retval; @@ -529,6 +518,7 @@ IntGdiSetMetaRgn(PDC pDC) return Ret; } + int APIENTRY NtGdiSetMetaRgn(HDC hDC) { INT Ret; @@ -570,7 +560,7 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnClip, pDC->dclevel.prgnMeta, - RGN_AND ); + RGN_AND); } else { @@ -579,43 +569,42 @@ NEW_CLIPPING_UpdateGCRegion(PDC pDC) IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnClip, NULL, - RGN_COPY ); + RGN_COPY); } else if (pDC->dclevel.prgnMeta) { IntGdiCombineRgn( pDC->prgnAPI, pDC->dclevel.prgnMeta, NULL, - RGN_COPY ); + RGN_COPY); } } IntGdiCombineRgn( pDC->prgnRao, pDC->prgnVis, pDC->prgnAPI, - RGN_AND ); + RGN_AND); - RtlCopyMemory( &pDC->erclClip, - &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound, - sizeof(RECTL)); + RtlCopyMemory(&pDC->erclClip, + &((PROSRGNDATA)pDC->prgnRao)->rdh.rcBound, + sizeof(RECTL)); pDC->fs &= ~DC_FLAG_DIRTY_RAO; IntGdiOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y); // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build - // the rects from region objects rects in pClipRgn->Buffer. + // the rects from region objects rects in pClipRgn->Buffer. // With pDC->co.pClipRgn->Buffer, // pDC->co.pClipRgn = pDC->prgnRao ? pDC->prgnRao : pDC->prgnVis; co = IntEngCreateClipRegion( ((PROSRGNDATA)pDC->prgnRao)->rdh.nCount, ((PROSRGNDATA)pDC->prgnRao)->Buffer, - &pDC->erclClip); - + &pDC->erclClip); if (co) { if (pDC->rosdc.CombinedClip != NULL) - IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); + IntEngDeleteClipRegion(pDC->rosdc.CombinedClip); pDC->rosdc.CombinedClip = co; } diff --git a/subsystems/win32/win32k/objects/dcattr.c b/subsystems/win32/win32k/objects/dcattr.c index 1fa8535d9cc..93673c77717 100644 --- a/subsystems/win32/win32k/objects/dcattr.c +++ b/subsystems/win32/win32k/objects/dcattr.c @@ -152,35 +152,49 @@ FreeDcAttr(PDC_ATTR pDc_Attr) return; } +BOOL +FASTCALL +DC_AllocDcAttr(PDC pdc) +{ + DC_AllocateDcAttr(pdc->BaseObject.hHmgr); + *pdc->pdcattr = pdc->dcattr; + return TRUE; +} + +// CHECK against current head VOID FASTCALL DC_AllocateDcAttr(HDC hDC) { PVOID NewMem = NULL; PDC pDC; + HANDLE Pid = NtCurrentProcess(); + ULONG MemSize = sizeof(DC_ATTR); //PAGE_SIZE it will allocate that size + NTSTATUS Status = ZwAllocateVirtualMemory(Pid, + &NewMem, + 0, + &MemSize, + MEM_COMMIT|MEM_RESERVE, + PAGE_READWRITE); { INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)hDC); PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index]; - - NewMem = AllocateDcAttr(); - // FIXME: dc could have been deleted!!! use GDIOBJ_InsertUserData - - if (NewMem) + if (NT_SUCCESS(Status)) { - RtlZeroMemory(NewMem, sizeof(DC_ATTR)); - Entry->UserData = NewMem; - DPRINT("DC_ATTR allocated! 0x%x\n",NewMem); + RtlZeroMemory(NewMem, MemSize); + Entry->UserData = NewMem; + DPRINT("DC_ATTR allocated! 0x%x\n",NewMem); } else { - DPRINT1("DC_ATTR not allocated!\n"); + DPRINT("DC_ATTR not allocated!\n"); } } pDC = DC_LockDc(hDC); ASSERT(pDC->pdcattr == &pDC->dcattr); - if (NewMem) + if(NewMem) { pDC->pdcattr = NewMem; // Store pointer } @@ -188,23 +202,37 @@ DC_AllocateDcAttr(HDC hDC) } VOID -FASTCALL -DC_FreeDcAttr(HDC DCToFree ) +NTAPI +DC_vFreeDcAttr(PDC pdc) { - PDC pDC = DC_LockDc(DCToFree); - if (pDC->pdcattr == &pDC->dcattr) return; // Internal DC object! - pDC->pdcattr = &pDC->dcattr; - DC_UnlockDc(pDC); + HANDLE Pid = NtCurrentProcess(); + INT Index; + PGDI_TABLE_ENTRY pent; - { - INT Index = GDI_HANDLE_GET_INDEX((HGDIOBJ)DCToFree); - PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index]; - if (Entry->UserData) + if (pdc->pdcattr == &pdc->dcattr) { - FreeDcAttr(Entry->UserData); - Entry->UserData = NULL; + // Internal DC object! + return; + } + + pdc->pdcattr = &pdc->dcattr; + + Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr); + pent = &GdiHandleTable->Entries[Index]; + if(pent->UserData) + { + ULONG MemSize = sizeof(DC_ATTR); + NTSTATUS Status = ZwFreeVirtualMemory(Pid, + &pent->UserData, + &MemSize, + MEM_RELEASE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("DC_FreeDC failed to free DC_ATTR 0x%p\n", pent->UserData); + ASSERT(FALSE); + } + pent->UserData = NULL; } - } } @@ -218,12 +246,8 @@ CopytoUserDcAttr(PDC dc, PDC_ATTR pdcattr) _SEH2_TRY { - ProbeForWrite( pdcattr, - sizeof(DC_ATTR), - 1); - RtlCopyMemory( pdcattr, - &dc->dcattr, - sizeof(DC_ATTR)); + ProbeForWrite(pdcattr, sizeof(DC_ATTR), 1); + RtlCopyMemory(pdcattr, &dc->dcattr, sizeof(DC_ATTR)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { diff --git a/subsystems/win32/win32k/objects/dclife.c b/subsystems/win32/win32k/objects/dclife.c index 0dffdd41193..75113441b85 100644 --- a/subsystems/win32/win32k/objects/dclife.c +++ b/subsystems/win32/win32k/objects/dclife.c @@ -12,169 +12,361 @@ #define NDEBUG #include +//FIXME: windows uses 0x0012009f +#define DIRTY_DEFAULT DIRTY_CHARSET|DIRTY_BACKGROUND|DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL + +PSURFACE psurfDefaultBitmap = NULL; +PBRUSH pbrDefaultBrush = NULL; + +// FIXME: these should go to floatobj.h or something +#define FLOATOBJ_0 {0x00000000, 0x00000000} +#define FLOATOBJ_1 {0x40000000, 0x00000002} +#define FLOATOBJ_16 {0x40000000, 0x00000006} +#define FLOATOBJ_1_16 {0x40000000, 0xfffffffe} + +static const FLOATOBJ gef0 = FLOATOBJ_0; +static const FLOATOBJ gef1 = FLOATOBJ_1; +static const FLOATOBJ gef16 = FLOATOBJ_16; + +static const MATRIX gmxWorldToDeviceDefault = +{ + FLOATOBJ_16, FLOATOBJ_0, + FLOATOBJ_0, FLOATOBJ_16, + FLOATOBJ_0, FLOATOBJ_0, + 0, 0, 0x4b +}; + +static const MATRIX gmxDeviceToWorldDefault = +{ + FLOATOBJ_1_16, FLOATOBJ_0, + FLOATOBJ_0, FLOATOBJ_1_16, + FLOATOBJ_0, FLOATOBJ_0, + 0, 0, 0x53 +}; + +static const MATRIX gmxWorldToPageDefault = +{ + FLOATOBJ_1, FLOATOBJ_0, + FLOATOBJ_0, FLOATOBJ_1, + FLOATOBJ_0, FLOATOBJ_0, + 0, 0, 0x63 +}; + +// HACK!! Fix XFORMOBJ then use 1:16 / 16:1 +#define gmxWorldToDeviceDefault gmxWorldToPageDefault +#define gmxDeviceToWorldDefault gmxWorldToPageDefault + /** Internal functions ********************************************************/ -HDC FASTCALL -DC_AllocDC(PUNICODE_STRING Driver) +NTSTATUS +InitDcImpl() { - PDC NewDC; - PDC_ATTR pdcattr; - HDC hDC; - PWSTR Buf = NULL; - XFORM xformTemplate; - PBRUSH pbrush; - HSURF hsurf; + psurfDefaultBitmap = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]); + if (!psurfDefaultBitmap) + return STATUS_UNSUCCESSFUL; - if (Driver != NULL) - { - Buf = ExAllocatePoolWithTag(PagedPool, Driver->MaximumLength, TAG_DC); - if (!Buf) - { - DPRINT1("ExAllocatePoolWithTag failed\n"); - return NULL; - } - RtlCopyMemory(Buf, Driver->Buffer, Driver->MaximumLength); - } + pbrDefaultBrush = BRUSH_ShareLockBrush(StockObjects[BLACK_BRUSH]); + if (!pbrDefaultBrush) + return STATUS_UNSUCCESSFUL; - NewDC = (PDC)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DC); - if (!NewDC) - { - if (Buf) - { - ExFreePoolWithTag(Buf, TAG_DC); - } - DPRINT1("GDIOBJ_AllocObjWithHandle failed\n"); - return NULL; - } - - hDC = NewDC->BaseObject.hHmgr; - - NewDC->pdcattr = &NewDC->dcattr; - DC_AllocateDcAttr(hDC); - - if (Driver != NULL) - { - RtlCopyMemory(&NewDC->rosdc.DriverName, Driver, sizeof(UNICODE_STRING)); - NewDC->rosdc.DriverName.Buffer = Buf; - } - pdcattr = NewDC->pdcattr; - - // FIXME: no floating point in the kernel! - xformTemplate.eM11 = 1.0f; - xformTemplate.eM12 = 0.0f; - xformTemplate.eM21 = 0.0f; - xformTemplate.eM22 = 1.0f; - xformTemplate.eDx = 0.0f; - xformTemplate.eDy = 0.0f; - XForm2MatrixS(&NewDC->dclevel.mxWorldToDevice, &xformTemplate); - XForm2MatrixS(&NewDC->dclevel.mxDeviceToWorld, &xformTemplate); - XForm2MatrixS(&NewDC->dclevel.mxWorldToPage, &xformTemplate); - - // Setup syncing bits for the dcattr data packets. - pdcattr->flXform = DEVICE_TO_PAGE_INVALID; - - pdcattr->ulDirty_ = 0; // Server side - - pdcattr->iMapMode = MM_TEXT; - pdcattr->iGraphicsMode = GM_COMPATIBLE; - pdcattr->jFillMode = ALTERNATE; - - pdcattr->szlWindowExt.cx = 1; // Float to Int,,, WRONG! - pdcattr->szlWindowExt.cy = 1; - pdcattr->szlViewportExt.cx = 1; - pdcattr->szlViewportExt.cy = 1; - - pdcattr->crForegroundClr = 0; - pdcattr->ulForegroundClr = 0; - - pdcattr->ulBackgroundClr = 0xffffff; - pdcattr->crBackgroundClr = 0xffffff; - - pdcattr->ulPenClr = RGB(0, 0, 0); - pdcattr->crPenClr = RGB(0, 0, 0); - - pdcattr->ulBrushClr = RGB(255, 255, 255); // Do this way too. - pdcattr->crBrushClr = RGB(255, 255, 255); - -//// This fixes the default brush and pen settings. See DC_InitDC. - - /* Create the default fill brush */ - pdcattr->hbrush = NtGdiGetStockObject(WHITE_BRUSH); - NewDC->dclevel.pbrFill = BRUSH_ShareLockBrush(pdcattr->hbrush); - EBRUSHOBJ_vInit(&NewDC->eboFill, NewDC->dclevel.pbrFill, NewDC); - - /* Create the default pen / line brush */ - pdcattr->hpen = NtGdiGetStockObject(BLACK_PEN); - NewDC->dclevel.pbrLine = PEN_ShareLockPen(pdcattr->hpen); - EBRUSHOBJ_vInit(&NewDC->eboLine, NewDC->dclevel.pbrLine, NewDC); - - /* Create the default text brush */ - pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(BLACK_BRUSH)); - EBRUSHOBJ_vInit(&NewDC->eboText, pbrush, NewDC); - pdcattr->ulDirty_ |= DIRTY_TEXT; - - /* Create the default background brush */ - pbrush = BRUSH_ShareLockBrush(NtGdiGetStockObject(WHITE_BRUSH)); - EBRUSHOBJ_vInit(&NewDC->eboBackground, pbrush, NewDC); - - pdcattr->hlfntNew = NtGdiGetStockObject(SYSTEM_FONT); - TextIntRealizeFont(pdcattr->hlfntNew,NULL); - NewDC->hlfntCur = pdcattr->hlfntNew; - NewDC->dclevel.plfnt = GDIOBJ_GetKernelObj(pdcattr->hlfntNew); - - NewDC->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE); - NewDC->dclevel.ppal = PALETTE_ShareLockPalette(NewDC->dclevel.hpal); - /* This should never fail */ - ASSERT(NewDC->dclevel.ppal); - - NewDC->dclevel.laPath.eMiterLimit = 10.0; // FIXME: use FLOATL or FLOATOBJ! - - NewDC->dclevel.lSaveDepth = 1; - - hsurf = (HBITMAP)PrimarySurface.pSurface; // <- what kind of haxx0ry is that? - NewDC->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); - - /* Allocate a Vis region */ - NewDC->prgnVis = IntSysCreateRectpRgn(0, 0, 1, 1); - if (!NewDC->prgnVis) - { - DPRINT1("IntSysCreateRectpRgn failed\n"); - if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC)) - { - ASSERT(FALSE); - } - return NULL; - } - - return NewDC; + return STATUS_SUCCESS; } -BOOL INTERNAL_CALL + +PDC +NTAPI +DC_AllocDcWithHandle() +{ + PDC pdc; + pdc = (PDC)GDIOBJ_AllocObjWithHandle(GDILoObjType_LO_DC_TYPE); + + pdc->pdcattr = &pdc->dcattr; + + return pdc; +} + + +void +DC_InitHack(PDC pdc) +{ + TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL); + pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0); + + /* This should never fail */ + ASSERT(pdc->dclevel.ppal); + + /* Select regions */ + pdc->rosdc.hClipRgn = NULL; + pdc->rosdc.hGCClipRgn = NULL; +} + +VOID +NTAPI +DC_vInitDc( + PDC pdc, + DCTYPE dctype, + PPDEVOBJ ppdev) +{ + /* Setup some basic fields */ + pdc->dctype = dctype; + pdc->ppdev = ppdev; + pdc->dhpdev = ppdev->dhpdev; + pdc->hsem = ppdev->hsemDevLock; + pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps; + pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2; + pdc->fs = DC_DIRTY_RAO; + + /* Setup dc attribute */ + pdc->pdcattr = &pdc->dcattr; + pdc->dcattr.pvLDC = NULL; + pdc->dcattr.ulDirty_ = DIRTY_DEFAULT; + if (ppdev == gppdevPrimary) + pdc->dcattr.ulDirty_ |= DC_PRIMARY_DISPLAY; + + /* Setup the DC size */ + if (dctype == DCTYPE_MEMORY) + { + /* Memory DCs have a 1 x 1 bitmap by default */ + pdc->dclevel.sizl.cx = 1; + pdc->dclevel.sizl.cy = 1; + } + else + { + /* Other DC's are as big as the related PDEV */ + pdc->dclevel.sizl.cx = ppdev->gdiinfo.ulHorzRes; + pdc->dclevel.sizl.cy = ppdev->gdiinfo.ulVertRes; + } + + /* Setup Window rect based on DC size */ + pdc->erclWindow.left = 0; + pdc->erclWindow.top = 0; + pdc->erclWindow.right = pdc->dclevel.sizl.cx; + pdc->erclWindow.bottom = pdc->dclevel.sizl.cy; + + if (dctype == DCTYPE_DIRECT) + { + /* Direct DCs get the surface from the PDEV */ + pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev); + + pdc->erclBounds.left = 0x7fffffff; + pdc->erclBounds.top = 0x7fffffff; + pdc->erclBounds.right = 0x80000000; + pdc->erclBounds.bottom = 0x80000000; + pdc->erclBoundsApp.left = 0xffffffff; + pdc->erclBoundsApp.top = 0xfffffffc; + pdc->erclBoundsApp.right = 0x00007ffc; // FIXME + pdc->erclBoundsApp.bottom = 0x00000333; // FIXME + pdc->erclClip = pdc->erclBounds; +// pdc->co + + pdc->fs |= DC_SYNCHRONIZEACCESS | DC_ACCUM_APP | DC_PERMANANT | DC_DISPLAY; + } + else + { + /* Non-direct DCs don't have a surface by default */ + pdc->dclevel.pSurface = NULL; + + // FIXME: HACK, because our code expects a surface + pdc->dclevel.pSurface = SURFACE_ShareLockSurface(StockObjects[DEFAULT_BITMAP]); + + pdc->erclBounds.left = 0; + pdc->erclBounds.top = 0; + pdc->erclBounds.right = 0; + pdc->erclBounds.bottom = 0; + pdc->erclBoundsApp = pdc->erclBounds; + pdc->erclClip = pdc->erclWindow; +// pdc->co = NULL + } + +// pdc->dcattr.VisRectRegion: + + /* Setup coordinate transformation data */ + pdc->dclevel.mxWorldToDevice = gmxWorldToDeviceDefault; + pdc->dclevel.mxDeviceToWorld = gmxDeviceToWorldDefault; + pdc->dclevel.mxWorldToPage = gmxWorldToPageDefault; + pdc->dclevel.efM11PtoD = gef16; + pdc->dclevel.efM22PtoD = gef16; + pdc->dclevel.efDxPtoD = gef0; + pdc->dclevel.efDyPtoD = gef0; + pdc->dclevel.efM11_TWIPS = gef0; + pdc->dclevel.efM22_TWIPS = gef0; + pdc->dclevel.efPr11 = gef0; + pdc->dclevel.efPr22 = gef0; + pdc->dcattr.mxWorldToDevice = pdc->dclevel.mxWorldToDevice; + pdc->dcattr.mxDeviceToWorld = pdc->dclevel.mxDeviceToWorld; + pdc->dcattr.mxWorldToPage = pdc->dclevel.mxWorldToPage; + pdc->dcattr.efM11PtoD = pdc->dclevel.efM11PtoD; + pdc->dcattr.efM22PtoD = pdc->dclevel.efM22PtoD; + pdc->dcattr.efDxPtoD = pdc->dclevel.efDxPtoD; + pdc->dcattr.efDyPtoD = pdc->dclevel.efDyPtoD; + pdc->dcattr.iMapMode = MM_TEXT; + pdc->dcattr.dwLayout = 0; + pdc->dcattr.flXform = PAGE_TO_DEVICE_SCALE_IDENTITY | + PAGE_TO_DEVICE_IDENTITY | + WORLD_TO_PAGE_IDENTITY; + + /* Setup more coordinates */ + pdc->ptlDCOrig.x = 0; + pdc->ptlDCOrig.y = 0; + pdc->dcattr.lWindowOrgx = 0; + pdc->dcattr.ptlWindowOrg.x = 0; + pdc->dcattr.ptlWindowOrg.y = 0; + pdc->dcattr.szlWindowExt.cx = 1; + pdc->dcattr.szlWindowExt.cy = 1; + pdc->dcattr.ptlViewportOrg.x = 0; + pdc->dcattr.ptlViewportOrg.y = 0; + pdc->dcattr.szlViewportExt.cx = 1; + pdc->dcattr.szlViewportExt.cy = 1; + pdc->dcattr.szlVirtualDevicePixel.cx = ppdev->gdiinfo.ulHorzRes; + pdc->dcattr.szlVirtualDevicePixel.cy = ppdev->gdiinfo.ulVertRes; + pdc->dcattr.szlVirtualDeviceMm.cx = ppdev->gdiinfo.ulHorzSize; + pdc->dcattr.szlVirtualDeviceMm.cy = ppdev->gdiinfo.ulVertSize; + pdc->dcattr.szlVirtualDeviceSize.cx = 0; + pdc->dcattr.szlVirtualDeviceSize.cy = 0; + + /* Setup regions */ + pdc->prgnAPI = NULL; + pdc->prgnRao = NULL; + /* Allocate a Vis region */ + pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); + ASSERT(pdc->prgnVis); + GDIOBJ_CopyOwnership(pdc->BaseObject.hHmgr, pdc->prgnVis->BaseObject.hHmgr); + + /* Setup palette */ + pdc->dclevel.hpal = StockObjects[DEFAULT_PALETTE]; + pdc->dclevel.ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal); + + /* Setup path */ + pdc->dclevel.hPath = NULL; + pdc->dclevel.flPath = 0; +// pdc->dclevel.lapath: + + /* Setup colors */ + pdc->dcattr.crBackgroundClr = RGB(0xff, 0xff, 0xff); + pdc->dcattr.ulBackgroundClr = RGB(0xff, 0xff, 0xff); + pdc->dcattr.crForegroundClr = RGB(0, 0, 0); + pdc->dcattr.ulForegroundClr = RGB(0, 0, 0); + pdc->dcattr.crBrushClr = RGB(0xff, 0xff, 0xff); + pdc->dcattr.ulBrushClr = RGB(0xff, 0xff, 0xff); + pdc->dcattr.crPenClr = RGB(0, 0, 0); + pdc->dcattr.ulPenClr = RGB(0, 0, 0); + + /* Select the default fill and line brush */ + pdc->dcattr.hbrush = StockObjects[WHITE_BRUSH]; + pdc->dcattr.hpen = StockObjects[BLACK_PEN]; + pdc->dclevel.pbrFill = BRUSH_ShareLockBrush(pdc->pdcattr->hbrush); + pdc->dclevel.pbrLine = PEN_ShareLockPen(pdc->pdcattr->hpen); + pdc->dclevel.ptlBrushOrigin.x = 0; + pdc->dclevel.ptlBrushOrigin.y = 0; + pdc->dcattr.ptlBrushOrigin = pdc->dclevel.ptlBrushOrigin; + + /* Initialize EBRUSHOBJs */ + EBRUSHOBJ_vInit(&pdc->eboFill, pdc->dclevel.pbrFill, pdc); + EBRUSHOBJ_vInit(&pdc->eboLine, pdc->dclevel.pbrLine, pdc); + EBRUSHOBJ_vInit(&pdc->eboText, pbrDefaultBrush, pdc); + EBRUSHOBJ_vInit(&pdc->eboBackground, pbrDefaultBrush, pdc); + + /* Setup fill data */ + pdc->dcattr.jROP2 = R2_COPYPEN; + pdc->dcattr.jBkMode = 2; + pdc->dcattr.lBkMode = 2; + pdc->dcattr.jFillMode = ALTERNATE; + pdc->dcattr.lFillMode = 1; + pdc->dcattr.jStretchBltMode = 1; + pdc->dcattr.lStretchBltMode = 1; + pdc->ptlFillOrigin.x = 0; + pdc->ptlFillOrigin.y = 0; + + /* Setup drawing position */ + pdc->dcattr.ptlCurrent.x = 0; + pdc->dcattr.ptlCurrent.y = 0; + pdc->dcattr.ptfxCurrent.x = 0; + pdc->dcattr.ptfxCurrent.y = 0; + + /* Setup ICM data */ + pdc->dclevel.lIcmMode = 0; + pdc->dcattr.lIcmMode = 0; + pdc->dcattr.hcmXform = NULL; + pdc->dcattr.flIcmFlags = 0; + pdc->dcattr.IcmBrushColor = CLR_INVALID; + pdc->dcattr.IcmPenColor = CLR_INVALID; + pdc->dcattr.pvLIcm = NULL; + pdc->dcattr.hColorSpace = NULL; // FIXME: 0189001f + pdc->dclevel.pColorSpace = NULL; // FIXME + pdc->pClrxFormLnk = NULL; +// pdc->dclevel.ca = + + /* Setup font data */ + pdc->hlfntCur = NULL; // FIXME: 2f0a0cf8 + pdc->pPFFList = NULL; + pdc->flSimulationFlags = 0; + pdc->lEscapement = 0; + pdc->prfnt = NULL; + pdc->dcattr.flFontMapper = 0; + pdc->dcattr.flTextAlign = 0; + pdc->dcattr.lTextAlign = 0; + pdc->dcattr.lTextExtra = 0; + pdc->dcattr.lRelAbs = 1; + pdc->dcattr.lBreakExtra = 0; + pdc->dcattr.cBreak = 0; + pdc->dcattr.hlfntNew = StockObjects[SYSTEM_FONT]; +// pdc->dclevel.pFont = LFONT_ShareLockFont(pdc->dcattr.hlfntNew); + + /* Other stuff */ + pdc->hdcNext = NULL; + pdc->hdcPrev = NULL; + pdc->ipfdDevMax = 0x0000ffff; + pdc->ulCopyCount = -1; + pdc->ptlDoBanding.x = 0; + pdc->ptlDoBanding.y = 0; + pdc->dclevel.lSaveDepth = 1; + pdc->dclevel.hdcSave = NULL; + pdc->dcattr.iGraphicsMode = GM_COMPATIBLE; + pdc->dcattr.iCS_CP = 0; + pdc->pSurfInfo = NULL; + +} + +BOOL +INTERNAL_CALL DC_Cleanup(PVOID ObjectBody) { - PDC pDC = (PDC)ObjectBody; + PDC pdc = (PDC)ObjectBody; - /* Free driver name (HACK) */ - if (pDC->rosdc.DriverName.Buffer) - ExFreePoolWithTag(pDC->rosdc.DriverName.Buffer, TAG_DC); + /* Free DC_ATTR */ + DC_vFreeDcAttr(pdc); + + /* Delete saved DCs */ + DC_vRestoreDC(pdc, 1); /* Deselect dc objects */ - DC_vSelectSurface(pDC, NULL); - DC_vSelectFillBrush(pDC, NULL); - DC_vSelectLineBrush(pDC, NULL); - DC_vSelectPalette(pDC, NULL); - - /* Dereference default brushes */ - if (pDC->eboText.pbrush) - BRUSH_ShareUnlockBrush(pDC->eboText.pbrush); - if (pDC->eboBackground.pbrush) - BRUSH_ShareUnlockBrush(pDC->eboBackground.pbrush); + DC_vSelectSurface(pdc, NULL); + DC_vSelectFillBrush(pdc, NULL); + DC_vSelectLineBrush(pdc, NULL); + DC_vSelectPalette(pdc, NULL); /* Cleanup the dc brushes */ - EBRUSHOBJ_vCleanup(&pDC->eboFill); - EBRUSHOBJ_vCleanup(&pDC->eboLine); - EBRUSHOBJ_vCleanup(&pDC->eboText); - EBRUSHOBJ_vCleanup(&pDC->eboBackground); + EBRUSHOBJ_vCleanup(&pdc->eboFill); + EBRUSHOBJ_vCleanup(&pdc->eboLine); + EBRUSHOBJ_vCleanup(&pdc->eboText); + EBRUSHOBJ_vCleanup(&pdc->eboBackground); + + /* Free regions */ + if (pdc->rosdc.hClipRgn) + GreDeleteObject(pdc->rosdc.hClipRgn); + if (pdc->prgnVis) + REGION_FreeRgnByHandle(pdc->prgnVis->BaseObject.hHmgr); + if (pdc->rosdc.hGCClipRgn) + GreDeleteObject(pdc->rosdc.hGCClipRgn); + if (NULL != pdc->rosdc.CombinedClip) + IntEngDeleteClipRegion(pdc->rosdc.CombinedClip); + + PATH_Delete(pdc->dclevel.hPath); + + if(pdc->dclevel.pSurface) + SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + + PDEVOBJ_vRelease(pdc->ppdev) ; return TRUE; } @@ -186,205 +378,187 @@ DC_SetOwnership(HDC hDC, PEPROCESS Owner) INT Index; PGDI_TABLE_ENTRY Entry; PDC pDC; + BOOL ret = FALSE; - if (!GDIOBJ_SetOwnership(hDC, Owner)) return FALSE; - pDC = DC_LockDc(hDC); - if (pDC) + if (!GDIOBJ_SetOwnership(hDC, Owner)) { + DPRINT1("GDIOBJ_SetOwnership failed\n"); + return FALSE; + } + + pDC = DC_LockDc(hDC); + if (!pDC) + { + DPRINT1("Could not lock DC\n"); + return FALSE; + } + /* System Regions: These regions do not use attribute sections and when allocated, use gdiobj level functions. */ - if (pDC->rosdc.hClipRgn) - { // FIXME! HAX!!! - Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn); - Entry = &GdiHandleTable->Entries[Index]; - if (Entry->UserData) FreeObjectAttr(Entry->UserData); - Entry->UserData = NULL; - // - if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) return FALSE; - } - if (pDC->prgnVis) - { // FIXME! HAX!!! - Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr); - Entry = &GdiHandleTable->Entries[Index]; - if (Entry->UserData) FreeObjectAttr(Entry->UserData); - Entry->UserData = NULL; - // - if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) return FALSE; - } - if (pDC->rosdc.hGCClipRgn) - { // FIXME! HAX!!! - Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn); - Entry = &GdiHandleTable->Entries[Index]; - if (Entry->UserData) FreeObjectAttr(Entry->UserData); - Entry->UserData = NULL; - // - if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) return FALSE; - } - if (pDC->dclevel.hPath) - { - if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) return FALSE; - } - DC_UnlockDc(pDC); + if (pDC->rosdc.hClipRgn) + { // FIXME! HAX!!! + Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hClipRgn); + Entry = &GdiHandleTable->Entries[Index]; + if (Entry->UserData) FreeObjectAttr(Entry->UserData); + Entry->UserData = NULL; + // + if (!GDIOBJ_SetOwnership(pDC->rosdc.hClipRgn, Owner)) goto leave; } + if (pDC->prgnVis) + { // FIXME! HAX!!! + Index = GDI_HANDLE_GET_INDEX(pDC->prgnVis->BaseObject.hHmgr); + Entry = &GdiHandleTable->Entries[Index]; + if (Entry->UserData) FreeObjectAttr(Entry->UserData); + Entry->UserData = NULL; + // + if (!GDIOBJ_SetOwnership(pDC->prgnVis->BaseObject.hHmgr, Owner)) goto leave; + } + if (pDC->rosdc.hGCClipRgn) + { // FIXME! HAX!!! + Index = GDI_HANDLE_GET_INDEX(pDC->rosdc.hGCClipRgn); + Entry = &GdiHandleTable->Entries[Index]; + if (Entry->UserData) FreeObjectAttr(Entry->UserData); + Entry->UserData = NULL; + // + if (!GDIOBJ_SetOwnership(pDC->rosdc.hGCClipRgn, Owner)) goto leave; + } + if (pDC->dclevel.hPath) + { + if (!GDIOBJ_SetOwnership(pDC->dclevel.hPath, Owner)) goto leave; + } + ret = TRUE; - return TRUE; +leave: + DC_UnlockDc(pDC); + + return ret; } -HDC FASTCALL -IntGdiCreateDC( - PUNICODE_STRING Driver, - PUNICODE_STRING Device, - PVOID pUMdhpdev, - CONST PDEVMODEW InitData, - BOOL CreateAsIC) +int FASTCALL +CLIPPING_UpdateGCRegion(DC* Dc); + +static +void +DC_vUpdateDC(PDC pdc) { - HDC hdc; - PDC pdc; - PDC_ATTR pdcattr; - HRGN hVisRgn; - UNICODE_STRING StdDriver; - BOOL calledFromUser; + HRGN hVisRgn ; + PPDEVOBJ ppdev = pdc->ppdev ; - RtlInitUnicodeString(&StdDriver, L"DISPLAY"); + pdc->dhpdev = ppdev->dhpdev; - DPRINT("DriverName: %wZ, DeviceName: %wZ\n", Driver, Device); + SURFACE_ShareUnlockSurface(pdc->dclevel.pSurface); + pdc->dclevel.pSurface = PDEVOBJ_pSurface(ppdev); - if (NULL == Driver || 0 == RtlCompareUnicodeString(Driver, &StdDriver, TRUE)) + PDEVOBJ_sizl(pdc->ppdev, &pdc->dclevel.sizl); + hVisRgn = NtGdiCreateRectRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy); + ASSERT(hVisRgn); + GdiSelectVisRgn(pdc->BaseObject.hHmgr, hVisRgn); + GreDeleteObject(hVisRgn); + + pdc->flGraphicsCaps = ppdev->devinfo.flGraphicsCaps; + pdc->flGraphicsCaps2 = ppdev->devinfo.flGraphicsCaps2; + + /* Mark EBRUSHOBJs as dirty */ + pdc->pdcattr->ulDirty_ |= DIRTY_DEFAULT ; +} + +/* Prepare a blit for up to 2 DCs */ +/* rc1 and rc2 are the rectangles where we want to draw or + * from where we take pixels. */ +VOID +FASTCALL +DC_vPrepareDCsForBlit(PDC pdc1, + RECT rc1, + PDC pdc2, + RECT rc2) +{ + PDC pdcFirst, pdcSecond; + PRECT prcFirst, prcSecond; + /* Lock them in good order */ + if(pdc2) { - if (CreateAsIC) + if((ULONG_PTR)pdc1->ppdev->hsemDevLock >= (ULONG_PTR)pdc2->ppdev->hsemDevLock) { - if (! IntPrepareDriverIfNeeded()) - { - /* Here, we have two possibilities: - * a) return NULL, and hope that the caller - * won't call us in a loop - * b) bugcheck, but caller is unable to - * react on the problem - */ - /*DPRINT1("Unable to prepare graphics driver, returning NULL ic\n"); - return NULL;*/ - KeBugCheck(VIDEO_DRIVER_INIT_FAILURE); - } + pdcFirst = pdc1; + prcFirst = &rc1; + pdcSecond = pdc2; + prcSecond = &rc2; } else { - calledFromUser = UserIsEntered(); - if (!calledFromUser) - { - UserEnterExclusive(); - } - - if (! co_IntGraphicsCheck(TRUE)) - { - if (!calledFromUser) - { - UserLeave(); - } - DPRINT1("Unable to initialize graphics, returning NULL dc\n"); - return NULL; - } - - if (!calledFromUser) - { - UserLeave(); - } - + pdcFirst = pdc2; + prcFirst = &rc2; + pdcSecond = pdc1; + prcSecond = &rc1; } } - - /* Check for existing DC object */ - if ((hdc = DC_FindOpenDC(Driver)) != NULL) - { - hdc = NtGdiCreateCompatibleDC(hdc); - if (!hdc) - DPRINT1("NtGdiCreateCompatibleDC() failed\n"); - return hdc; - } - - /* Allocate a DC object */ - pdc = DC_AllocDC(Driver); - if (pdc == NULL) - { - DPRINT1("DC_AllocDC() failed\n"); - return NULL; - } - hdc = pdc->BaseObject.hHmgr; - pdcattr = pdc->pdcattr; - - pdc->dctype = DC_TYPE_DIRECT; - - pdc->dhpdev = PrimarySurface.dhpdev; - if (pUMdhpdev) pUMdhpdev = pdc->dhpdev; // set DHPDEV for device. - pdc->ppdev = (PVOID)&PrimarySurface; - - // ATM we only have one display. - pdcattr->ulDirty_ |= DC_PRIMARY_DISPLAY; - - pdc->flGraphicsCaps = PrimarySurface.devinfo.flGraphicsCaps; - pdc->flGraphicsCaps2 = PrimarySurface.devinfo.flGraphicsCaps2; - - pdc->dclevel.hpal = NtGdiGetStockObject(DEFAULT_PALETTE); - - pdcattr->jROP2 = R2_COPYPEN; - - pdc->erclWindow.top = pdc->erclWindow.left = 0; - pdc->erclWindow.right = pdc->ppdev->gdiinfo.ulHorzRes; - pdc->erclWindow.bottom = pdc->ppdev->gdiinfo.ulVertRes; - pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE; // Default is CCW. - - pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0); - - hVisRgn = IntSysCreateRectRgn(0, 0, pdc->ppdev->gdiinfo.ulHorzRes, - pdc->ppdev->gdiinfo.ulVertRes); - - if (!CreateAsIC) - { - pdc->pSurfInfo = NULL; -// pdc->dclevel.pSurface = - DC_UnlockDc(pdc); - - /* Initialize the DC state */ - IntGdiSetTextColor(hdc, RGB(0, 0, 0)); - IntGdiSetBkColor(hdc, RGB(255, 255, 255)); - } else { - /* From MSDN2: - The CreateIC function creates an information context for the specified device. - The information context provides a fast way to get information about the - device without creating a device context (DC). However, GDI drawing functions - cannot accept a handle to an information context. - */ - pdc->dctype = DC_TYPE_INFO; -// pdc->pSurfInfo = -// DC_vSelectSurface(pdc, NULL); - pdcattr->crBackgroundClr = pdcattr->ulBackgroundClr = RGB(255, 255, 255); - pdcattr->crForegroundClr = RGB(0, 0, 0); - DC_UnlockDc(pdc); + pdcFirst = pdc1 ; + prcFirst = &rc1; + pdcSecond = NULL ; } - DC_InitDC(hdc); - if (hVisRgn) + if(pdcFirst && pdcFirst->dctype == DCTYPE_DIRECT) { - GdiSelectVisRgn(hdc, hVisRgn); - REGION_FreeRgnByHandle(hVisRgn); + EngAcquireSemaphore(pdcFirst->ppdev->hsemDevLock); + MouseSafetyOnDrawStart(pdcFirst->ppdev, + prcFirst->left, + prcFirst->top, + prcFirst->right, + prcFirst->bottom) ; + /* Update surface if needed */ + if(pdcFirst->ppdev->pSurface != pdcFirst->dclevel.pSurface) + { + DC_vUpdateDC(pdcFirst); + } + } + if(pdcSecond && pdcSecond->dctype == DCTYPE_DIRECT) + { + EngAcquireSemaphore(pdcSecond->ppdev->hsemDevLock); + MouseSafetyOnDrawStart(pdcSecond->ppdev, + prcSecond->left, + prcSecond->top, + prcSecond->right, + prcSecond->bottom) ; + /* Update surface if needed */ + if(pdcSecond->ppdev->pSurface != pdcSecond->dclevel.pSurface) + { + DC_vUpdateDC(pdcSecond); + } } - - IntGdiSetTextAlign(hdc, TA_TOP); - IntGdiSetBkMode(hdc, OPAQUE); - - return hdc; } +/* Finishes a blit for one or two DCs */ +VOID +FASTCALL +DC_vFinishBlit(PDC pdc1, PDC pdc2) +{ + if(pdc1->dctype == DCTYPE_DIRECT) + { + MouseSafetyOnDrawEnd(pdc1->ppdev); + EngReleaseSemaphore(pdc1->ppdev->hsemDevLock); + } -HDC APIENTRY -NtGdiOpenDCW( - PUNICODE_STRING Device, - DEVMODEW *InitData, + if(pdc2) + { + if(pdc2->dctype == DCTYPE_DIRECT) + { + MouseSafetyOnDrawEnd(pdc2->ppdev); + EngReleaseSemaphore(pdc2->ppdev->hsemDevLock); + } + } +} + +HDC +NTAPI +GreOpenDCW( + PUNICODE_STRING pustrDevice, + DEVMODEW *pdmInit, PUNICODE_STRING pustrLogAddr, ULONG iType, BOOL bDisplay, @@ -392,98 +566,210 @@ NtGdiOpenDCW( VOID *pDriverInfo2, VOID *pUMdhpdev) { - UNICODE_STRING SafeDevice; - DEVMODEW SafeInitData; - PVOID Dhpdev; - HDC Ret; - NTSTATUS Status = STATUS_SUCCESS; + PPDEVOBJ ppdev; + PDC pdc; + HDC hdc; - if (!Device) return UserGetDesktopDC(iType,FALSE,TRUE); + DPRINT("GreOpenDCW(%S, iType=%ld)\n", + pustrDevice ? pustrDevice->Buffer : NULL, iType); - if (InitData) + /* Get a PDEVOBJ for the device */ + ppdev = EngpGetPDEV(pustrDevice); + if (!ppdev) { + DPRINT1("Didn't find a suitable PDEV\n"); + return NULL; + } + + DPRINT("GreOpenDCW - ppdev = %p\n", ppdev); + + pdc = DC_AllocDcWithHandle(); + if (!pdc) + { + DPRINT1("Could not Allocate a DC\n"); + PDEVOBJ_vRelease(ppdev); + return NULL; + } + hdc = pdc->BaseObject.hHmgr; + + /* Lock ppdev and initialize the new DC */ + DC_vInitDc(pdc, iType, ppdev); + /* FIXME: HACK! */ + DC_InitHack(pdc); + + DC_AllocDcAttr(pdc); + + DC_UnlockDc(pdc); + + DPRINT("returning hdc = %p\n", hdc); + + return hdc; +} + +HDC +APIENTRY +NtGdiOpenDCW( + PUNICODE_STRING pustrDevice, + DEVMODEW *pdmInit, + PUNICODE_STRING pustrLogAddr, + ULONG iType, + BOOL bDisplay, + HANDLE hspool, + VOID *pDriverInfo2, + VOID *pUMdhpdev) +{ + UNICODE_STRING ustrDevice; + WCHAR awcDevice[CCHDEVICENAME]; + DEVMODEW dmInit; + PVOID dhpdev; + HDC hdc; + + /* Only if a devicename is given, we need any data */ + if (pustrDevice) + { + /* Initialize destination string */ + RtlInitEmptyUnicodeString(&ustrDevice, awcDevice, sizeof(awcDevice)); + _SEH2_TRY { + /* Probe the UNICODE_STRING and the buffer */ + ProbeForRead(pustrDevice, sizeof(UNICODE_STRING), 1); + ProbeForRead(pustrDevice->Buffer, pustrDevice->Length, 1); + + /* Copy the string */ + RtlCopyUnicodeString(&ustrDevice, pustrDevice); + + if (pdmInit) + { + /* FIXME: could be larger */ + ProbeForRead(pdmInit, sizeof(DEVMODEW), 1); + RtlCopyMemory(&dmInit, pdmInit, sizeof(DEVMODEW)); + } + if (pUMdhpdev) { - ProbeForWrite(pUMdhpdev, sizeof(PVOID), 1); + ProbeForWrite(pUMdhpdev, sizeof(HANDLE), 1); } - ProbeForRead(InitData, sizeof(DEVMODEW), 1); - RtlCopyMemory(&SafeInitData, InitData, sizeof(DEVMODEW)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Status = _SEH2_GetExceptionCode(); + SetLastNtError(_SEH2_GetExceptionCode()); + _SEH2_YIELD(return NULL); } - _SEH2_END; - - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return NULL; - } - /* FIXME - InitData can have some more bytes! */ + _SEH2_END } - - if (Device) + else { - Status = IntSafeCopyUnicodeString(&SafeDevice, Device); - if (!NT_SUCCESS(Status)) + pdmInit = NULL; + pUMdhpdev = NULL; + } + + /* FIXME: HACK! */ + if (pustrDevice) + { + UNICODE_STRING ustrDISPLAY = RTL_CONSTANT_STRING(L"DISPLAY"); + if (RtlEqualUnicodeString(&ustrDevice, &ustrDISPLAY, TRUE)) { - SetLastNtError(Status); - return NULL; + pustrDevice = NULL; } } - Ret = IntGdiCreateDC(Device ? &SafeDevice : NULL, - NULL, - pUMdhpdev ? &Dhpdev : NULL, - InitData ? &SafeInitData : NULL, - (BOOL) iType); // FALSE 0 DCW, TRUE 1 ICW + /* Call the internal function */ + hdc = GreOpenDCW(pustrDevice ? &ustrDevice : NULL, + pdmInit ? &dmInit : NULL, + NULL, // fixme pwszLogAddress + iType, + bDisplay, + hspool, + NULL, //FIXME: pDriverInfo2 + pUMdhpdev ? &dhpdev : NULL); - // FIXME!!!! - if (pUMdhpdev) pUMdhpdev = Dhpdev; + /* If we got a HDC and a UM dhpdev is requested,... */ + if (hdc && pUMdhpdev) + { + /* Copy dhpdev to caller (FIXME: use dhpdev?? */ + _SEH2_TRY + { + /* Pointer was already probed */ + *(HANDLE*)pUMdhpdev = dhpdev; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Ignore error */ + } + _SEH2_END + } - return Ret; + return hdc; } -HDC FASTCALL -IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC) + +HDC +APIENTRY +NtGdiCreateCompatibleDC(HDC hdc) { - HDC hDC; - UNICODE_STRING DriverName; - RtlInitUnicodeString(&DriverName, L"DISPLAY"); + HDC hdcNew; + PPDEVOBJ ppdev; + PDC pdc, pdcNew; - if (DcType != DC_TYPE_MEMORY) - hDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, (DcType == DC_TYPE_INFO)); - else - hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth! -// -// There is room to grow here~ -// + DPRINT("NtGdiCreateCompatibleDC(0x%p)\n", hdc); -// -// If NULL, first time through! Build the default (was window) dc! -// Setup clean DC state for the system. -// - if (hDC && !defaultDCstate) // Ultra HAX! Dedicated to GvG! - { // This is a cheesy way to do this. - PDC dc = DC_LockDc(hDC); - HSURF hsurf; - defaultDCstate = ExAllocatePoolWithTag(PagedPool, sizeof(DC), TAG_DC); - if (!defaultDCstate) + /* Did the caller provide a DC? */ + if (hdc) + { + /* Yes, try to lock it */ + pdc = DC_LockDc(hdc); + if (!pdc) { - DC_UnlockDc(dc); + DPRINT1("Could not lock source DC %p\n", hdc); return NULL; } - RtlZeroMemory(defaultDCstate, sizeof(DC)); - defaultDCstate->pdcattr = &defaultDCstate->dcattr; - hsurf = (HSURF)PrimarySurface.pSurface; // HAX - defaultDCstate->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); - DC_vCopyState(dc, defaultDCstate, TRUE); - DC_UnlockDc(dc); + + /* Get the pdev from the DC */ + ppdev = pdc->ppdev; + InterlockedIncrement(&ppdev->cPdevRefs); + + /* Unlock the source DC */ + DC_UnlockDc(pdc); } - return hDC; + else + { + /* No DC given, get default device */ + ppdev = EngpGetPDEV(NULL); + } + + if (!ppdev) + { + DPRINT1("Didn't find a suitable PDEV\n"); + return NULL; + } + + /* Allocate a new DC */ + pdcNew = DC_AllocDcWithHandle(); + if (!pdcNew) + { + DPRINT1("Could not allocate a new DC\n"); + PDEVOBJ_vRelease(ppdev); + return NULL; + } + hdcNew = pdcNew->BaseObject.hHmgr; + + /* Lock ppdev and initialize the new DC */ + DC_vInitDc(pdcNew, DCTYPE_MEMORY, ppdev); + /* FIXME: HACK! */ + DC_InitHack(pdcNew); + + /* Allocate a dc attribute */ + DC_AllocDcAttr(pdcNew); + + // HACK! + DC_vSelectSurface(pdcNew, psurfDefaultBitmap); + + DC_UnlockDc(pdcNew); + + DPRINT("Leave NtGdiCreateCompatibleDC hdcNew = %p\n", hdcNew); + + return hdcNew; } BOOL @@ -500,102 +786,69 @@ IntGdiDeleteDC(HDC hDC, BOOL Force) if (!Force) { + /* Windows permits NtGdiDeleteObjectApp to delete a permanent DC + * For some reason, it's still a valid handle, pointing to some kernel data. + * Not sure if this is a bug, a feature, some cache stuff... Who knows? + * See NtGdiDeleteObjectApp test for details */ if (DCToDelete->fs & DC_FLAG_PERMANENT) { - DPRINT1("No! You Naughty Application!\n"); DC_UnlockDc(DCToDelete); - return UserReleaseDC(NULL, hDC, FALSE); + if(UserReleaseDC(NULL, hDC, FALSE)) + { + /* ReactOs feature : call UserReleaseDC + * I don't think windows does it. + * Still, complain, no one should ever call DeleteDC + * on a window DC */ + DPRINT1("No, you naughty application!\n"); + return TRUE; + } + else + { + /* This is not a window owned DC. + * Force its deletion */ + return IntGdiDeleteDC(hDC, TRUE); + } } } - /* First delete all saved DCs */ - while (DCToDelete->dclevel.lSaveDepth > 1) - { - PDC savedDC; - HDC savedHDC; - - savedHDC = DCToDelete->hdcNext; - savedDC = DC_LockDc(savedHDC); - if (savedDC == NULL) - { - break; - } - DCToDelete->hdcNext = savedDC->hdcNext; - DCToDelete->dclevel.lSaveDepth--; - DC_UnlockDc(savedDC); - IntGdiDeleteDC(savedHDC, Force); - } - - /* Free GDI resources allocated to this DC */ - if (!(DCToDelete->dclevel.flPath & DCPATH_SAVESTATE)) - { - /* - NtGdiSelectPen (DCHandle, STOCK_BLACK_PEN); - NtGdiSelectBrush (DCHandle, STOCK_WHITE_BRUSH); - NtGdiSelectFont (DCHandle, STOCK_SYSTEM_FONT); - DC_LockDC (DCHandle); NtGdiSelectXxx does not recognize stock objects yet */ - } - if (DCToDelete->rosdc.hClipRgn) - { - GreDeleteObject(DCToDelete->rosdc.hClipRgn); - } - if (DCToDelete->prgnVis) - { - GreDeleteObject(DCToDelete->prgnVis->BaseObject.hHmgr); - } - if (NULL != DCToDelete->rosdc.CombinedClip) - { - IntEngDeleteClipRegion(DCToDelete->rosdc.CombinedClip); - } - if (DCToDelete->rosdc.hGCClipRgn) - { - GreDeleteObject(DCToDelete->rosdc.hGCClipRgn); - } - if (DCToDelete->dclevel.prgnMeta) - { - GreDeleteObject(((PROSRGNDATA)DCToDelete->dclevel.prgnMeta)->BaseObject.hHmgr); - } - if (DCToDelete->prgnAPI) - { - GreDeleteObject(((PROSRGNDATA)DCToDelete->prgnAPI)->BaseObject.hHmgr); - } - PATH_Delete(DCToDelete->dclevel.hPath); - DC_UnlockDc(DCToDelete); - GreDeleteObject(hDC); + + if (!IsObjectDead(hDC)) + { + if (!GDIOBJ_FreeObjByHandle(hDC, GDI_OBJECT_TYPE_DC)) + { + DPRINT1("DC_FreeDC failed\n"); + } + } + else + { + DPRINT1("Attempted to Delete 0x%x currently being destroyed!!!\n", hDC); + } + return TRUE; } -HDC FASTCALL -DC_FindOpenDC(PUNICODE_STRING Driver) +BOOL +APIENTRY +NtGdiDeleteObjectApp(HANDLE DCHandle) { - return NULL; -} + /* Complete all pending operations */ + NtGdiFlushUserBatch(); -/*! - * Initialize some common fields in the Device Context structure. -*/ -VOID FASTCALL -DC_InitDC(HDC DCHandle) -{ -// NtGdiRealizeDefaultPalette(DCHandle); + if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE; -//// Removed for now.. See above brush and pen. -// NtGdiSelectBrush(DCHandle, NtGdiGetStockObject( WHITE_BRUSH )); -// NtGdiSelectPen(DCHandle, NtGdiGetStockObject( BLACK_PEN )); -//// - //NtGdiSelectFont(DCHandle, hFont); + if (GDI_HANDLE_GET_TYPE(DCHandle) != GDI_OBJECT_TYPE_DC) + return GreDeleteObject((HGDIOBJ) DCHandle); - /* - { - int res; - res = CLIPPING_UpdateGCRegion(DCToInit); - ASSERT ( res != ERROR ); - } - */ + if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE; - /* Set virtual resolution */ - NtGdiSetVirtualResolution(DCHandle, 0, 0, 0, 0); + if (!GDIOBJ_OwnedByCurrentProcess(DCHandle)) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return FALSE; + } + + return IntGdiDeleteDC(DCHandle, FALSE); } BOOL @@ -618,7 +871,7 @@ MakeInfoDC(PDC pdc, BOOL bSet) pdc->dctype = DC_TYPE_INFO; pdc->dclevel.pSurface = NULL; - PDEV_sizl(pdc->ppdev, &sizl); + PDEVOBJ_sizl(pdc->ppdev, &sizl); if ( sizl.cx == pdc->dclevel.sizl.cx && sizl.cy == pdc->dclevel.sizl.cy ) @@ -669,132 +922,42 @@ NtGdiMakeInfoDC( return FALSE; } -HDC APIENTRY -NtGdiCreateCompatibleDC(HDC hDC) + +HDC FASTCALL +IntGdiCreateDC( + PUNICODE_STRING Driver, + PUNICODE_STRING pustrDevice, + PVOID pUMdhpdev, + CONST PDEVMODEW pdmInit, + BOOL CreateAsIC) { - PDC pdcNew, pdcOld; - PDC_ATTR pdcattrNew, pdcattrOld; - HDC hdcNew, DisplayDC = NULL; - UNICODE_STRING DriverName; - DWORD Layout = 0; - HSURF hsurf; + HDC hdc; - if (hDC == NULL) - { - RtlInitUnicodeString(&DriverName, L"DISPLAY"); - DisplayDC = IntGdiCreateDC(&DriverName, NULL, NULL, NULL, TRUE); - if (NULL == DisplayDC) - { - DPRINT1("Failed to create DisplayDC\n"); - return NULL; - } - hDC = DisplayDC; - } + hdc = GreOpenDCW(pustrDevice, + pdmInit, + NULL, + CreateAsIC ? DCTYPE_INFO : + (Driver ? DC_TYPE_DIRECT : DC_TYPE_DIRECT), + TRUE, + NULL, + NULL, + pUMdhpdev); - /* Allocate a new DC based on the original DC's device */ - pdcOld = DC_LockDc(hDC); - if (NULL == pdcOld) - { - if (NULL != DisplayDC) - { - NtGdiDeleteObjectApp(DisplayDC); - } - DPRINT1("Failed to lock hDC\n"); - return NULL; - } - pdcNew = DC_AllocDC(&pdcOld->rosdc.DriverName); - if (!pdcNew) - { - DPRINT1("Failed to create pdcNew\n"); - DC_UnlockDc(pdcOld); - if (DisplayDC) - { - NtGdiDeleteObjectApp(DisplayDC); - } - return NULL; - } - hdcNew = pdcNew->BaseObject.hHmgr; - - pdcattrOld = pdcOld->pdcattr; - pdcattrNew = pdcNew->pdcattr; - - /* Copy information from original DC to new DC */ - pdcNew->dclevel.hdcSave = hdcNew; - - pdcNew->dhpdev = pdcOld->dhpdev; - - /* DriverName is copied in the AllocDC routine */ - pdcattrNew->ptlWindowOrg = pdcattrOld->ptlWindowOrg; - pdcattrNew->szlWindowExt = pdcattrOld->szlWindowExt; - pdcattrNew->ptlViewportOrg = pdcattrOld->ptlViewportOrg; - pdcattrNew->szlViewportExt = pdcattrOld->szlViewportExt; - - pdcNew->dctype = DC_TYPE_MEMORY; // Always! - hsurf = NtGdiGetStockObject(DEFAULT_BITMAP); - pdcNew->dclevel.pSurface = SURFACE_ShareLockSurface(hsurf); - pdcNew->ppdev = pdcOld->ppdev; - pdcNew->dclevel.hpal = pdcOld->dclevel.hpal; - - pdcattrNew->lTextAlign = pdcattrOld->lTextAlign; - pdcattrNew->lBkMode = pdcattrOld->lBkMode; - pdcattrNew->jBkMode = pdcattrOld->jBkMode; - pdcattrNew->jROP2 = pdcattrOld->jROP2; - pdcattrNew->dwLayout = pdcattrOld->dwLayout; - if (pdcattrOld->dwLayout & LAYOUT_ORIENTATIONMASK) Layout = pdcattrOld->dwLayout; - pdcNew->dclevel.flPath = pdcOld->dclevel.flPath; - pdcattrNew->ulDirty_ = pdcattrOld->ulDirty_; - pdcattrNew->iCS_CP = pdcattrOld->iCS_CP; - - pdcNew->erclWindow.left = pdcNew->erclWindow.top = 0; - pdcNew->erclWindow.right = pdcNew->erclWindow.bottom = 1; - - DC_UnlockDc(pdcNew); - DC_UnlockDc(pdcOld); - if (NULL != DisplayDC) - { - NtGdiDeleteObjectApp(DisplayDC); - } - - if (Layout) NtGdiSetLayout(hdcNew, -1, Layout); - - DC_InitDC(hdcNew); - return hdcNew; + return hdc; } - -BOOL -APIENTRY -NtGdiDeleteObjectApp(HANDLE DCHandle) +HDC FASTCALL +IntGdiCreateDisplayDC(HDEV hDev, ULONG DcType, BOOL EmptyDC) { - GDIOBJTYPE ObjType; + HDC hDC; + UNIMPLEMENTED; + ASSERT(FALSE); - /* Complete all pending operations */ - NtGdiFlushUserBatch(); + if (DcType == DC_TYPE_MEMORY) + hDC = NtGdiCreateCompatibleDC(NULL); // OH~ Yuck! I think I taste vomit in my mouth! + else + hDC = IntGdiCreateDC(NULL, NULL, NULL, NULL, (DcType == DC_TYPE_INFO)); - if (GDI_HANDLE_IS_STOCKOBJ(DCHandle)) return TRUE; - - if (IsObjectDead((HGDIOBJ)DCHandle)) return TRUE; - - ObjType = GDI_OBJECT_GET_TYPE_INDEX((ULONG_PTR)DCHandle); - - if (GreGetObjectOwner( DCHandle, ObjType)) - { - switch(ObjType) - { - case GDIObjType_DC_TYPE: - return IntGdiDeleteDC(DCHandle, FALSE); - - case GDIObjType_RGN_TYPE: - case GDIObjType_SURF_TYPE: - case GDIObjType_PAL_TYPE: - case GDIObjType_LFONT_TYPE: - case GDIObjType_BRUSH_TYPE: - return GreDeleteObject((HGDIOBJ) DCHandle); - - default: - return FALSE; - } - } - return (DCHandle != NULL); + return hDC; } diff --git a/subsystems/win32/win32k/objects/dcobjs.c b/subsystems/win32/win32k/objects/dcobjs.c index 3a093a01401..bba8441435d 100644 --- a/subsystems/win32/win32k/objects/dcobjs.c +++ b/subsystems/win32/win32k/objects/dcobjs.c @@ -110,8 +110,10 @@ DC_vUpdateTextBrush(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; + /* Timo : The text brush should never be changed. + * Jérôme : Yeah, but its palette must be updated anyway! */ if(pdcattr->ulDirty_ & DIRTY_TEXT) - EBRUSHOBJ_vUpdate(&pdc->eboText, pdc->eboText.pbrush, pdc); + EBRUSHOBJ_vUpdate(&pdc->eboText, pbrDefaultBrush, pdc); /* Update the eboText's solid color */ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboText, pdcattr->crForegroundClr); @@ -127,7 +129,7 @@ DC_vUpdateBackgroundBrush(PDC pdc) PDC_ATTR pdcattr = pdc->pdcattr; if(pdcattr->ulDirty_ & DIRTY_BACKGROUND) - EBRUSHOBJ_vUpdate(&pdc->eboBackground, pdc->eboBackground.pbrush, pdc); + EBRUSHOBJ_vUpdate(&pdc->eboBackground, pbrDefaultBrush, pdc); /* Update the eboBackground's solid color */ EBRUSHOBJ_vSetSolidBrushColor(&pdc->eboBackground, pdcattr->crBackgroundClr); @@ -164,7 +166,7 @@ GdiSelectPalette( /* Is this a valid palette for this depth? */ if ((BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) <= 8 - && ppal->Mode == PAL_INDEXED) || + && (ppal->flFlags & PAL_INDEXED)) || (BitsPerFormat(pdc->dclevel.pSurface->SurfObj.iBitmapFormat) > 8)) { /* Get old palette, set new one */ @@ -282,14 +284,24 @@ NtGdiSelectBitmap( } /* Get the handle for the old bitmap */ - psurfOld = pDC->dclevel.pSurface; - hOrgBmp = psurfOld ? psurfOld->BaseObject.hHmgr : NULL; + ASSERT(pDC->dclevel.pSurface); + hOrgBmp = pDC->dclevel.pSurface->BaseObject.hHmgr; + + /* Lock it, to be sure while we mess with it*/ + psurfOld = SURFACE_LockSurface(hOrgBmp); + + /* Reset hdc, this surface isn't selected anymore */ + psurfOld->hdc = NULL; /* Release the old bitmap, reference the new */ DC_vSelectSurface(pDC, psurfBmp); + /* And unlock it, now we're done */ + SURFACE_UnlockSurface(psurfOld); + // If Info DC this is zero and pSurface is moved to DC->pSurfInfo. - psurfBmp->hDC = hDC; + psurfBmp->hdc = hDC; + /* FIXME; improve by using a region without a handle and selecting it */ hVisRgn = IntSysCreateRectRgn( 0, @@ -356,6 +368,7 @@ NtGdiSelectClipPath( if (pPath->state != PATH_Closed) { SetLastWin32Error(ERROR_CAN_NOT_COMPLETE); + DC_UnlockDc(pdc); return FALSE; } diff --git a/subsystems/win32/win32k/objects/dcstate.c b/subsystems/win32/win32k/objects/dcstate.c index f7942f33d02..889a8733087 100644 --- a/subsystems/win32/win32k/objects/dcstate.c +++ b/subsystems/win32/win32k/objects/dcstate.c @@ -15,9 +15,14 @@ VOID FASTCALL DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To) { + DPRINT("DC_vCopyState(%p, %p)\n", pdcSrc->BaseObject.hHmgr, pdcDst->BaseObject.hHmgr); + /* Copy full DC attribute */ *pdcDst->pdcattr = *pdcSrc->pdcattr; - + + /* Get/SetDCState() don't change hVisRgn field ("Undoc. Windows" p.559). */ + /* The VisRectRegion field needs to be set to a valid state */ + /* Mark some fields as dirty */ pdcDst->pdcattr->ulDirty_ |= 0x0012001f; // Note: Use if, To is FALSE.... @@ -36,7 +41,6 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To) pdcDst->dclevel.hpal = pdcSrc->dclevel.hpal; /* Handle references here correctly */ - DC_vSelectSurface(pdcDst, pdcSrc->dclevel.pSurface); DC_vSelectFillBrush(pdcDst, pdcSrc->dclevel.pbrFill); DC_vSelectLineBrush(pdcDst, pdcSrc->dclevel.pbrLine); DC_vSelectPalette(pdcDst, pdcSrc->dclevel.ppal); @@ -91,16 +95,96 @@ NtGdiResetDC( } +VOID +NTAPI +DC_vRestoreDC( + IN PDC pdc, + INT iSaveLevel) +{ + PEPROCESS pepCurrentProcess; + HDC hdcSave; + PDC pdcSave; + + ASSERT(iSaveLevel > 0); + DPRINT("DC_vRestoreDC(%p, %ld)\n", pdc->BaseObject.hHmgr, iSaveLevel); + + /* Get current process */ + pepCurrentProcess = PsGetCurrentProcess(); + + /* Loop the save levels */ + while (pdc->dclevel.lSaveDepth > iSaveLevel) + { + hdcSave = pdc->dclevel.hdcSave; + DPRINT("RestoreDC = %p\n", hdcSave); + + /* Set us as the owner */ + if (!GDIOBJ_SetOwnership(hdcSave, pepCurrentProcess)) + { + /* Could not get ownership. That's bad! */ + DPRINT1("Could not get ownership of saved DC (%p) for hdc %p!\n", + hdcSave, pdc->BaseObject.hHmgr); + return;// FALSE; + } + + /* Lock the saved dc */ + pdcSave = DC_LockDc(hdcSave); + if (!pdcSave) + { + /* WTF? Internal error! */ + DPRINT1("Could not lock the saved DC (%p) for dc %p!\n", + hdcSave, pdc->BaseObject.hHmgr); + return;// FALSE; + } + + /* Remove the saved dc from the queue */ + pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave; + + /* Decrement save level */ + pdc->dclevel.lSaveDepth--; + + /* Is this the state we want? */ + if (pdc->dclevel.lSaveDepth == iSaveLevel) + { + /* Copy the state back */ + DC_vCopyState(pdcSave, pdc, FALSE); + + /* Only memory DC's change their surface */ + if (pdc->dctype == DCTYPE_MEMORY) + DC_vSelectSurface(pdc, pdcSave->dclevel.pSurface); + + // Restore Path by removing it, if the Save flag is set. + // BeginPath will takecare of the rest. + if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE) + { + PATH_Delete(pdc->dclevel.hPath); + pdc->dclevel.hPath = 0; + pdc->dclevel.flPath &= ~DCPATH_SAVE; + } + } + + /* Prevent save dc from being restored */ + pdcSave->dclevel.lSaveDepth = 1; + + /* Unlock it */ + DC_UnlockDc(pdcSave); + /* Delete the saved dc */ + GreDeleteObject(hdcSave); + } + + DPRINT("Leave DC_vRestoreDC()\n"); +} + + + BOOL APIENTRY NtGdiRestoreDC( HDC hdc, INT iSaveLevel) { - PDC pdc, pdcSave; - HDC hdcSave; + PDC pdc; - DPRINT("NtGdiRestoreDC(%lx, %d)\n", hdc, iSaveLevel); + DPRINT("NtGdiRestoreDC(%p, %d)\n", hdc, iSaveLevel); /* Lock the original DC */ pdc = DC_LockDc(hdc); @@ -126,67 +210,12 @@ NtGdiRestoreDC( return FALSE; } - /* Loop the save levels */ - while (pdc->dclevel.lSaveDepth > iSaveLevel) - { - hdcSave = pdc->dclevel.hdcSave; - - /* Set us as the owner */ - if (!IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_POWNED, FALSE )) - { - /* Could not get ownership. That's bad! */ - DPRINT1("Could not get ownership of saved DC (%p) for dc %p!\n", - hdcSave, hdc); - return FALSE; - } - - /* Lock the saved dc */ - pdcSave = DC_LockDc(hdcSave); - if (!pdcSave) - { - /* WTF? Internal error! */ - DPRINT1("Could not lock the saved DC (%p) for dc %p!\n", - hdcSave, hdc); - DC_UnlockDc(pdc); - return FALSE; - } - - /* Remove the saved dc from the queue */ - pdc->dclevel.hdcSave = pdcSave->dclevel.hdcSave; - - /* Decrement save level */ - pdc->dclevel.lSaveDepth--; - - /* Is this the state we want? */ - if (pdc->dclevel.lSaveDepth == iSaveLevel) - { - /* Copy the state back */ - DC_vCopyState(pdcSave, pdc, FALSE); - - // Restore Path by removing it, if the Save flag is set. - // BeginPath will takecare of the rest. - if (pdc->dclevel.hPath && pdc->dclevel.flPath & DCPATH_SAVE) - { - PATH_Delete(pdc->dclevel.hPath); - pdc->dclevel.hPath = 0; - pdc->dclevel.flPath &= ~DCPATH_SAVE; - } - // Attempt to plug the leak! - if (pdcSave->rosdc.hClipRgn) - { - DPRINT("Have hClipRgn!\n"); - REGION_FreeRgnByHandle(pdcSave->rosdc.hClipRgn); - } - // FIXME! Handle prgnMeta! - } - - /* Delete the saved dc */ - GreDeleteObject(hdcSave); - } + /* Call the internal function */ + DC_vRestoreDC(pdc, iSaveLevel); DC_UnlockDc(pdc); - DPRINT("Leaving NtGdiRestoreDC\n"); + DPRINT("Leave NtGdiRestoreDC\n"); return TRUE; } @@ -200,7 +229,7 @@ NtGdiSaveDC( PDC pdc, pdcSave; INT lSaveDepth; - DPRINT("NtGdiSaveDC(%lx)\n", hDC); + DPRINT("NtGdiSaveDC(%p)\n", hDC); /* Lock the original dc */ pdc = DC_LockDc(hDC); @@ -212,7 +241,7 @@ NtGdiSaveDC( } /* Allocate a new dc */ - pdcSave = DC_AllocDC(NULL); + pdcSave = DC_AllocDcWithHandle(); if (pdcSave == NULL) { DPRINT("Could not allocate a new DC\n"); @@ -221,12 +250,25 @@ NtGdiSaveDC( } hdcSave = pdcSave->BaseObject.hHmgr; - /* Copy the current state */ - DC_vCopyState(pdc, pdcSave, TRUE); + InterlockedIncrement(&pdc->ppdev->cPdevRefs); + DC_vInitDc(pdcSave, DCTYPE_MEMORY, pdc->ppdev); + + /* Handle references here correctly */ +// pdcSrc->dclevel.pSurface = NULL; +// pdcSrc->dclevel.pbrFill = NULL; +// pdcSrc->dclevel.pbrLine = NULL; +// pdcSrc->dclevel.ppal = NULL; /* Make it a kernel handle (FIXME: windows handles this different, see wiki)*/ - IntGdiSetDCOwnerEx(hdcSave, GDI_OBJ_HMGR_NONE, FALSE); + GDIOBJ_SetOwnership(hdcSave, NULL); + + /* Copy the current state */ + DC_vCopyState(pdc, pdcSave, TRUE); + + /* Only memory DC's change their surface */ + if (pdc->dctype == DCTYPE_MEMORY) + DC_vSelectSurface(pdcSave, pdc->dclevel.pSurface); /* Copy path. FIXME: why this way? */ pdcSave->dclevel.hPath = pdc->dclevel.hPath; @@ -243,7 +285,7 @@ NtGdiSaveDC( DC_UnlockDc(pdcSave); DC_UnlockDc(pdc); - DPRINT("Leave NtGdiSaveDC: %ld\n", lSaveDepth); + DPRINT("Leave NtGdiSaveDC: %ld, hdcSave = %p\n", lSaveDepth, hdcSave); return lSaveDepth; } diff --git a/subsystems/win32/win32k/objects/dcutil.c b/subsystems/win32/win32k/objects/dcutil.c index f856ea19bda..0471c7dc9d2 100644 --- a/subsystems/win32/win32k/objects/dcutil.c +++ b/subsystems/win32/win32k/objects/dcutil.c @@ -145,7 +145,7 @@ IntSetDefaultRegion(PDC pdc) if (pdc->ppdev->flFlags & PDEV_META_DEVICE) { pSurface = pdc->dclevel.pSurface; - if (pSurface && pSurface->flFlags & PDEV_SURFACE) + if (pSurface && pSurface->flags & PDEV_SURFACE) { rclClip.left += pdc->ppdev->ptlOrigion.x; rclClip.top += pdc->ppdev->ptlOrigion.y; diff --git a/subsystems/win32/win32k/objects/device.c b/subsystems/win32/win32k/objects/device.c index b6fb6a24708..c9b930331fa 100644 --- a/subsystems/win32/win32k/objects/device.c +++ b/subsystems/win32/win32k/objects/device.c @@ -11,584 +11,27 @@ #define NDEBUG #include -// TODO: proper implementation of LDEVOBJ and PDEVOBJ interface - -/*static*/ PDEVOBJ PrimarySurface; -PPDEVOBJ pPrimarySurface = &PrimarySurface; -static KEVENT VideoDriverNeedsPreparation; -static KEVENT VideoDriverPrepared; PDC defaultDCstate = NULL; -PSIZEL -FASTCALL -PDEV_sizl(PPDEVOBJ ppdev, PSIZEL psizl) +VOID FASTCALL +IntGdiReferencePdev(PPDEVOBJ ppdev) { - if (ppdev->flFlags & PDEV_META_DEVICE) - { - psizl->cx = ppdev->ulHorzRes; - psizl->cy = ppdev->ulVertRes; - } - else - { - psizl->cx = ppdev->gdiinfo.ulHorzRes; - psizl->cy = ppdev->gdiinfo.ulVertRes; - } - return psizl; + UNIMPLEMENTED; } -NTSTATUS FASTCALL -InitDcImpl(VOID) +VOID FASTCALL +IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType) { - KeInitializeEvent(&VideoDriverNeedsPreparation, SynchronizationEvent, TRUE); - KeInitializeEvent(&VideoDriverPrepared, NotificationEvent, FALSE); - return STATUS_SUCCESS; -} - - -static BOOLEAN FASTCALL -GetRegistryPath(PUNICODE_STRING RegistryPath, ULONG DisplayNumber) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - WCHAR DeviceNameBuffer[20]; - NTSTATUS Status; - - swprintf(DeviceNameBuffer, L"\\Device\\Video%lu", DisplayNumber); - RtlInitUnicodeString(RegistryPath, NULL); - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].Name = DeviceNameBuffer; - QueryTable[0].EntryContext = RegistryPath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, - L"VIDEO", - QueryTable, - NULL, - NULL); - if (! NT_SUCCESS(Status)) - { - DPRINT1("No \\Device\\Video%lu value in DEVICEMAP\\VIDEO found\n", DisplayNumber); - return FALSE; - } - - DPRINT("RegistryPath %wZ\n", RegistryPath); - - return TRUE; -} - - -NTSTATUS -NTAPI -EnumDisplayQueryRoutine(IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext) -{ - if ((Context == NULL) && ((ValueType == REG_SZ) || (ValueType == REG_MULTI_SZ))) - { - *(PULONG)EntryContext = ValueLength; - } - else - { - DPRINT1("Value data: %S %d\n", ValueData, ValueLength); - RtlCopyMemory(Context, ValueData, ValueLength); - } - - return STATUS_SUCCESS; -} - -static BOOL FASTCALL -FindDriverFileNames(PUNICODE_STRING DriverFileNames, ULONG DisplayNumber) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - UNICODE_STRING RegistryPath; - NTSTATUS Status; - PWCHAR DriverNames = NULL; - ULONG Length = 0; - - if (! GetRegistryPath(&RegistryPath, DisplayNumber)) - { - DPRINT("GetRegistryPath failed\n"); - return FALSE; - } - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_NOEXPAND; - QueryTable[0].Name = L"InstalledDisplayDrivers"; - QueryTable[0].EntryContext = &Length; - QueryTable[0].QueryRoutine = EnumDisplayQueryRoutine; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - RegistryPath.Buffer, - QueryTable, - NULL, - NULL); - // DPRINT1("Status: %lx\n", Status); - if (Length) - { - DriverNames = ExAllocatePoolWithTag(PagedPool, Length, TAG_DRIVER); - // DPRINT1("Length allocated: %d\n", Length); - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - RegistryPath.Buffer, - QueryTable, - DriverNames, - NULL); - if (!NT_SUCCESS(Status)) DriverNames = NULL; - } - - ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY); - if (! NT_SUCCESS(Status)) - { - DPRINT1("No InstalledDisplayDrivers value in service entry found\n"); - return FALSE; - } - - RtlInitUnicodeString(DriverFileNames, DriverNames); - DriverFileNames->Length = Length; - DriverFileNames->MaximumLength = Length; - //DPRINT1("DriverFileNames %wZ\n", DriverFileNames); - - return TRUE; -} - - -static NTSTATUS APIENTRY -DevModeCallback(IN PWSTR ValueName, - IN ULONG ValueType, - IN PVOID ValueData, - IN ULONG ValueLength, - IN PVOID Context, - IN PVOID EntryContext) -{ - PDEVMODEW DevMode = (PDEVMODEW) Context; - - DPRINT("Found registry value for name %S: type %d, length %d\n", - ValueName, ValueType, ValueLength); - - if (REG_DWORD == ValueType && sizeof(DWORD) == ValueLength) - { - if (0 == _wcsicmp(ValueName, L"DefaultSettings.BitsPerPel")) - { - DevMode->dmBitsPerPel = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.Flags")) - { - DevMode->dmDisplayFlags = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.VRefresh")) - { - DevMode->dmDisplayFrequency = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XPanning")) - { - DevMode->dmPanningWidth = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.XResolution")) - { - DevMode->dmPelsWidth = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YPanning")) - { - DevMode->dmPanningHeight = *((DWORD *) ValueData); - } - else if (0 == _wcsicmp(ValueName, L"DefaultSettings.YResolution")) - { - DevMode->dmPelsHeight = *((DWORD *) ValueData); - } - } - - return STATUS_SUCCESS; -} - - -static BOOL FASTCALL -SetupDevMode(PDEVMODEW DevMode, ULONG DisplayNumber) -{ - UNICODE_STRING RegistryPath; - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - NTSTATUS Status; - BOOLEAN Valid = TRUE; - - if (!GetRegistryPath(&RegistryPath, DisplayNumber)) - { - DPRINT("GetRegistryPath failed\n"); - return FALSE; - } - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - QueryTable[0].QueryRoutine = DevModeCallback; - QueryTable[0].Flags = 0; - QueryTable[0].Name = NULL; - QueryTable[0].EntryContext = NULL; - QueryTable[0].DefaultType = REG_NONE; - QueryTable[0].DefaultData = NULL; - QueryTable[0].DefaultLength = 0; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - RegistryPath.Buffer, - QueryTable, - DevMode, - NULL); - if (! NT_SUCCESS(Status)) - { - DPRINT("RtlQueryRegistryValues for %wZ failed with status 0x%08x\n", - &RegistryPath, Status); - Valid = FALSE; - } - else - { - DPRINT("dmBitsPerPel %d dmDisplayFrequency %d dmPelsWidth %d dmPelsHeight %d\n", - DevMode->dmBitsPerPel, DevMode->dmDisplayFrequency, - DevMode->dmPelsWidth, DevMode->dmPelsHeight); - if (0 == DevMode->dmBitsPerPel || 0 == DevMode->dmDisplayFrequency - || 0 == DevMode->dmPelsWidth || 0 == DevMode->dmPelsHeight) - { - DPRINT("Not all required devmode members are set\n"); - Valid = FALSE; - } - } - - ExFreePoolWithTag(RegistryPath.Buffer, TAG_RTLREGISTRY); - - if (! Valid) - { - RtlZeroMemory(DevMode, sizeof(DEVMODEW)); - } - - return Valid; -} - -static BOOL FASTCALL -IntPrepareDriver(VOID) -{ - PFN_DrvEnableDriver GDEnableDriver; - DRVENABLEDATA DED; - UNICODE_STRING DriverFileNames; - PWSTR CurrentName; - BOOL GotDriver; - BOOL DoDefault; - ULONG DisplayNumber; - LARGE_INTEGER Zero; - BOOLEAN ret = FALSE; - - Zero.QuadPart = 0; - if (STATUS_SUCCESS != KeWaitForSingleObject(&VideoDriverNeedsPreparation, Executive, KernelMode, TRUE, &Zero)) - { - /* Concurrent access. Wait for VideoDriverPrepared event */ - if (STATUS_SUCCESS == KeWaitForSingleObject(&VideoDriverPrepared, Executive, KernelMode, TRUE, NULL)) - ret = PrimarySurface.PreparedDriver; - goto cleanup; - } - // HAX! Fixme so I can support more than one! So how many? - for (DisplayNumber = 0; ; DisplayNumber++) - { - DPRINT("Trying to load display driver no. %d\n", DisplayNumber); - - RtlZeroMemory(&PrimarySurface, sizeof(PrimarySurface)); - -// if (!pPrimarySurface) pPrimarySurface = ExAllocatePoolWithTag(PagedPool, gdwDirectDrawContext + sizeof(PDEVOBJ), TAG_GDIPDEV); - - PrimarySurface.VideoFileObject = DRIVER_FindMPDriver(DisplayNumber); - - /* Open the miniport driver */ - if (PrimarySurface.VideoFileObject == NULL) - { - DPRINT1("FindMPDriver failed\n"); - goto cleanup; - } - - /* Retrieve DDI driver names from registry */ - RtlInitUnicodeString(&DriverFileNames, NULL); - if (!FindDriverFileNames(&DriverFileNames, DisplayNumber)) - { - DPRINT1("FindDriverFileNames failed\n"); - continue; - } - - /* - * DriverFileNames may be a list of drivers in REG_SZ_MULTI format, - * scan all of them until a good one found. - */ - CurrentName = DriverFileNames.Buffer; - GotDriver = FALSE; - while (!GotDriver && - CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR))) - { - /* Get the DDI driver's entry point */ - GDEnableDriver = DRIVER_FindDDIDriver(CurrentName); - if (NULL == GDEnableDriver) - { - DPRINT("FindDDIDriver failed for %S\n", CurrentName); - } - else - { - /* Call DDI driver's EnableDriver function */ - RtlZeroMemory(&DED, sizeof(DED)); - - if (! GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof(DED), &DED)) - { - DPRINT("DrvEnableDriver failed for %S\n", CurrentName); - } - else - { - GotDriver = TRUE; - } - } - - if (! GotDriver) - { - /* Skip to the next name but never get past the Unicode string */ - while (L'\0' != *CurrentName && - CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR))) - { - CurrentName++; - } - if (CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR))) - { - CurrentName++; - } - } - } - - if (!GotDriver) - { - ObDereferenceObject(PrimarySurface.VideoFileObject); - ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY); - DPRINT1("No suitable DDI driver found\n"); - continue; - } - - DPRINT1("Display driver %S loaded\n", CurrentName); - - ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY); - - DPRINT("Building DDI Functions\n"); - - /* Construct DDI driver function dispatch table */ - if (!DRIVER_BuildDDIFunctions(&DED, &PrimarySurface.DriverFunctions)) - { - ObDereferenceObject(PrimarySurface.VideoFileObject); - DPRINT1("BuildDDIFunctions failed\n"); - goto cleanup; - } - - /* Allocate a phyical device handle from the driver */ - // Support DMW.dmSize + DMW.dmDriverExtra & Alloc DMW then set prt pdmwDev. - PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW); - if (SetupDevMode(&PrimarySurface.DMW, DisplayNumber)) - { - PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV( - &PrimarySurface.DMW, - L"", - HS_DDI_MAX, - PrimarySurface.ahsurf, - sizeof(PrimarySurface.gdiinfo), - &PrimarySurface.gdiinfo, - sizeof(PrimarySurface.devinfo), - &PrimarySurface.devinfo, - NULL, - L"", - (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject)); - DoDefault = (NULL == PrimarySurface.dhpdev); - if (DoDefault) - { - DPRINT1("DrvEnablePDev with registry parameters failed\n"); - } - } - else - { - DoDefault = TRUE; - } - - if (DoDefault) - { - RtlZeroMemory(&(PrimarySurface.DMW), sizeof(DEVMODEW)); - PrimarySurface.DMW.dmSize = sizeof (PrimarySurface.DMW); - PrimarySurface.dhpdev = PrimarySurface.DriverFunctions.EnablePDEV( - &PrimarySurface.DMW, - L"", - HS_DDI_MAX, - PrimarySurface.ahsurf, - sizeof(PrimarySurface.gdiinfo), - &PrimarySurface.gdiinfo, - sizeof(PrimarySurface.devinfo), - &PrimarySurface.devinfo, - NULL, - L"", - (HANDLE) (PrimarySurface.VideoFileObject->DeviceObject)); - - if (NULL == PrimarySurface.dhpdev) - { - ObDereferenceObject(PrimarySurface.VideoFileObject); - DPRINT1("DrvEnablePDEV with default parameters failed\n"); - DPRINT1("Perhaps DDI driver doesn't match miniport driver?\n"); - continue; - } - - // Update the primary surface with what we really got - PrimarySurface.DMW.dmPelsWidth = PrimarySurface.gdiinfo.ulHorzRes; - PrimarySurface.DMW.dmPelsHeight = PrimarySurface.gdiinfo.ulVertRes; - PrimarySurface.DMW.dmBitsPerPel = PrimarySurface.gdiinfo.cBitsPixel; - PrimarySurface.DMW.dmDisplayFrequency = PrimarySurface.gdiinfo.ulVRefresh; - } - - if (!PrimarySurface.DMW.dmDriverExtra) - { - PrimarySurface.pdmwDev = &PrimarySurface.DMW; // HAX! - } - else - { - DPRINT1("WARNING!!! Need to Alloc DMW !!!!!!\n"); - } - // Dont remove until we finish testing other drivers. - if (PrimarySurface.DMW.dmDriverExtra != 0) - { - DPRINT1("**** DMW extra = %u bytes. Please report to ros-dev@reactos.org ****\n", PrimarySurface.DMW.dmDriverExtra); - } - - if (0 == PrimarySurface.gdiinfo.ulLogPixelsX) - { - DPRINT("Adjusting gdiinfo.ulLogPixelsX\n"); - PrimarySurface.gdiinfo.ulLogPixelsX = 96; - } - if (0 == PrimarySurface.gdiinfo.ulLogPixelsY) - { - DPRINT("Adjusting gdiinfo.ulLogPixelsY\n"); - PrimarySurface.gdiinfo.ulLogPixelsY = 96; - } - - PrimarySurface.Pointer.Exclude.right = -1; - - DPRINT("calling completePDev\n"); - - /* Complete initialization of the physical device */ - PrimarySurface.DriverFunctions.CompletePDEV( - PrimarySurface.dhpdev, - (HDEV)&PrimarySurface); - - DPRINT("calling DRIVER_ReferenceDriver\n"); - - DRIVER_ReferenceDriver(L"DISPLAY"); - - PrimarySurface.PreparedDriver = TRUE; - PrimarySurface.DisplayNumber = DisplayNumber; - PrimarySurface.flFlags = PDEV_DISPLAY; // Hard set,, add more flags. - PrimarySurface.hsemDevLock = (PERESOURCE)EngCreateSemaphore(); - // Should be null,, but make sure for now. - PrimarySurface.pvGammaRamp = NULL; - PrimarySurface.ppdevNext = NULL; // Fixme! We need to support more than display drvs. - PrimarySurface.ppdevParent = NULL; // Always NULL if primary. - PrimarySurface.pGraphicsDevice = NULL; // Fixme! - PrimarySurface.pEDDgpl = ExAllocatePoolWithTag(PagedPool, sizeof(EDD_DIRECTDRAW_GLOBAL), TAG_EDDGBL); - if (PrimarySurface.pEDDgpl) - { - RtlZeroMemory( PrimarySurface.pEDDgpl ,sizeof(EDD_DIRECTDRAW_GLOBAL)); - ret = TRUE; - } - goto cleanup; - } - -cleanup: - KeSetEvent(&VideoDriverPrepared, 1, FALSE); - return ret; + UNIMPLEMENTED; } BOOL FASTCALL -IntPrepareDriverIfNeeded(VOID) -{ - return (PrimarySurface.PreparedDriver ? TRUE : IntPrepareDriver()); -} - -static BOOL FASTCALL -PrepareVideoPrt(VOID) -{ - PIRP Irp; - NTSTATUS Status; - IO_STATUS_BLOCK Iosb; - BOOL Prepare = TRUE; - ULONG Length = sizeof(BOOL); - PIO_STACK_LOCATION StackPtr; - LARGE_INTEGER StartOffset; - PFILE_OBJECT FileObject = PrimarySurface.VideoFileObject; - PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject; - - DPRINT("PrepareVideoPrt() called\n"); - - KeClearEvent(&PrimarySurface.VideoFileObject->Event); - - ObReferenceObjectByPointer(FileObject, 0, IoFileObjectType, KernelMode); - - StartOffset.QuadPart = 0; - Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, - DeviceObject, - (PVOID) &Prepare, - Length, - &StartOffset, - NULL, - &Iosb); - if (NULL == Irp) - { - return FALSE; - } - - /* Set up IRP Data */ - Irp->Tail.Overlay.OriginalFileObject = FileObject; - Irp->RequestorMode = KernelMode; - Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL; - Irp->Overlay.AsynchronousParameters.UserApcContext = NULL; - Irp->Flags |= IRP_WRITE_OPERATION; - - /* Setup Stack Data */ - StackPtr = IoGetNextIrpStackLocation(Irp); - StackPtr->FileObject = PrimarySurface.VideoFileObject; - StackPtr->Parameters.Write.Key = 0; - - Status = IoCallDriver(DeviceObject, Irp); - - if (STATUS_PENDING == Status) - { - KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, TRUE, 0); - Status = Iosb.Status; - } - - return NT_SUCCESS(Status); -} - - -BOOL FASTCALL -IntCreatePrimarySurface(VOID) +IntCreatePrimarySurface() { SIZEL SurfSize; - RECTL SurfaceRect; - SURFOBJ *SurfObj; + SURFOBJ *pso; BOOL calledFromUser; - if (! IntPrepareDriverIfNeeded()) - { - return FALSE; - } - - if (! PrepareVideoPrt()) - { - return FALSE; - } - - DPRINT("calling EnableSurface\n"); - /* Enable the drawing surface */ - PrimarySurface.pSurface = - PrimarySurface.DriverFunctions.EnableSurface(PrimarySurface.dhpdev); - if (NULL == PrimarySurface.pSurface) - { - /* PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE);*/ - PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev); - ObDereferenceObject(PrimarySurface.VideoFileObject); - DPRINT1("DrvEnableSurface failed\n"); - return FALSE; - } - - PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, TRUE); - calledFromUser = UserIsEntered(); //fixme: possibly upgrade a shared lock if (!calledFromUser) { @@ -596,31 +39,23 @@ IntCreatePrimarySurface(VOID) } /* attach monitor */ - IntAttachMonitor(&PrimarySurface, PrimarySurface.DisplayNumber); + IntAttachMonitor(gppdevPrimary, 0); - SurfObj = EngLockSurface(PrimarySurface.pSurface); - SurfObj->dhpdev = PrimarySurface.dhpdev; - SurfSize = SurfObj->sizlBitmap; - SurfaceRect.left = SurfaceRect.top = 0; - SurfaceRect.right = SurfObj->sizlBitmap.cx; - SurfaceRect.bottom = SurfObj->sizlBitmap.cy; - /* FIXME - why does EngEraseSurface() sometimes crash? - EngEraseSurface(SurfObj, &SurfaceRect, 0); */ + DPRINT1("IntCreatePrimarySurface, pPrimarySurface=%p, pPrimarySurface->pSurface = %p\n", + pPrimarySurface, pPrimarySurface->pSurface); + + /* Create surface */ + pso = &PDEVOBJ_pSurface(pPrimarySurface)->SurfObj; + SurfSize = pso->sizlBitmap; /* Put the pointer in the center of the screen */ - gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2; - gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2; + gpsi->ptCursor.x = pso->sizlBitmap.cx / 2; + gpsi->ptCursor.y = pso->sizlBitmap.cy / 2; - /* Give the PDEV a MovePointer function */ - PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer; - if (!PrimarySurface.pfnMovePointer) - PrimarySurface.pfnMovePointer = EngMovePointer; - - EngUnlockSurface(SurfObj); co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy); // Init Primary Displays Device Capabilities. - IntvGetDeviceCaps(&PrimarySurface, &GdiHandleTable->DevCaps); + PDEVOBJ_vGetDeviceCaps(pPrimarySurface, &GdiHandleTable->DevCaps); if (!calledFromUser) { @@ -631,1139 +66,20 @@ IntCreatePrimarySurface(VOID) } VOID FASTCALL -IntDestroyPrimarySurface(VOID) +IntDestroyPrimarySurface() { - BOOL calledFromUser; - - DRIVER_UnreferenceDriver(L"DISPLAY"); - - calledFromUser = UserIsEntered(); - if (!calledFromUser) - { - UserEnterExclusive(); - } - - /* detach monitor */ - IntDetachMonitor(&PrimarySurface); - - if (!calledFromUser) - { - UserLeave(); - } - - /* - * FIXME: Hide a mouse pointer there. Also because we have to prevent - * memory leaks with the Eng* mouse routines. - */ - - DPRINT("Reseting display\n" ); - PrimarySurface.DriverFunctions.AssertMode(PrimarySurface.dhpdev, FALSE); - PrimarySurface.DriverFunctions.DisableSurface(PrimarySurface.dhpdev); - PrimarySurface.DriverFunctions.DisablePDEV(PrimarySurface.dhpdev); - PrimarySurface.PreparedDriver = FALSE; - KeSetEvent(&VideoDriverNeedsPreparation, 1, FALSE); - KeResetEvent(&VideoDriverPrepared); - - DceEmptyCache(); - - ObDereferenceObject(PrimarySurface.VideoFileObject); + UNIMPLEMENTED; } -INT -FASTCALL -IntcFonts(PPDEVOBJ pDevObj) -{ - ULONG_PTR Junk; -// Msdn DrvQueryFont: -// If the number of fonts in DEVINFO is -1 and iFace is zero, the driver -// should return the number of fonts it supports. - if ( pDevObj->devinfo.cFonts == -1) - { - if (pDevObj->DriverFunctions.QueryFont) - pDevObj->devinfo.cFonts = - (ULONG)pDevObj->DriverFunctions.QueryFont(pDevObj->dhpdev, 0, 0, &Junk); - else - pDevObj->devinfo.cFonts = 0; - } - return pDevObj->devinfo.cFonts; -} - -// -// Support multi display/device locks. -// -VOID -FASTCALL -DC_LockDisplay(HDC hDC) -{ - PERESOURCE Resource; - PDC dc = DC_LockDc(hDC); - if (!dc) return; - Resource = dc->ppdev->hsemDevLock; - DC_UnlockDc(dc); - if (!Resource) return; - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite( Resource , TRUE); -} - -VOID -FASTCALL -DC_UnlockDisplay(HDC hDC) -{ - PERESOURCE Resource; - PDC dc = DC_LockDc(hDC); - if (!dc) return; - Resource = dc->ppdev->hsemDevLock; - DC_UnlockDc(dc); - if (!Resource) return; - ExReleaseResourceLite( Resource ); - KeLeaveCriticalRegion(); -} - -// -// Enumerate HDev -// PPDEVOBJ FASTCALL IntEnumHDev(VOID) { // I guess we will soon have more than one primary surface. // This will do for now. - return &PrimarySurface; + return pPrimarySurface; } -VOID FASTCALL -IntGdiReferencePdev(PPDEVOBJ ppdev) -{ - if (!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore(); // Hax, should be in dllmain.c - IntGdiAcquireSemaphore(hsemDriverMgmt); - ppdev->cPdevRefs++; - IntGdiReleaseSemaphore(hsemDriverMgmt); -} - -VOID FASTCALL -IntGdiUnreferencePdev(PPDEVOBJ ppdev, DWORD CleanUpType) -{ - IntGdiAcquireSemaphore(hsemDriverMgmt); - ppdev->cPdevRefs--; - if (!ppdev->cPdevRefs) - { - // Handle the destruction of ppdev or PDEVOBJ or PDEVOBJ or PDEV etc. - } - IntGdiReleaseSemaphore(hsemDriverMgmt); -} - - - -INT -FASTCALL -IntGetColorManagementCaps(PPDEVOBJ pDevObj) -{ - INT ret = CM_NONE; - - if ( pDevObj->flFlags & PDEV_DISPLAY) - { - if (pDevObj->devinfo.iDitherFormat == BMF_8BPP || - pDevObj->devinfo.flGraphicsCaps2 & GCAPS2_CHANGEGAMMARAMP) - ret = CM_GAMMA_RAMP; - } - if (pDevObj->devinfo.flGraphicsCaps & GCAPS_CMYKCOLOR) - ret |= CM_CMYK_COLOR; - if (pDevObj->devinfo.flGraphicsCaps & GCAPS_ICM) - ret |= CM_DEVICE_ICM; - return ret; -} - -INT FASTCALL -IntGdiGetDeviceCaps(PDC dc, INT Index) -{ - INT ret = 0; - PPDEVOBJ ppdev = dc->ppdev; - /* Retrieve capability */ - switch (Index) - { - case DRIVERVERSION: - ret = ppdev->gdiinfo.ulVersion; - break; - - case TECHNOLOGY: - ret = ppdev->gdiinfo.ulTechnology; - break; - - case HORZSIZE: - ret = ppdev->gdiinfo.ulHorzSize; - break; - - case VERTSIZE: - ret = ppdev->gdiinfo.ulVertSize; - break; - - case HORZRES: - ret = ppdev->gdiinfo.ulHorzRes; - break; - - case VERTRES: - ret = ppdev->gdiinfo.ulVertRes; - break; - - case LOGPIXELSX: - ret = ppdev->gdiinfo.ulLogPixelsX; - break; - - case LOGPIXELSY: - ret = ppdev->gdiinfo.ulLogPixelsY; - break; - - case CAPS1: - if ( ppdev->pGraphicsDevice && - (((PGRAPHICS_DEVICE)ppdev->pGraphicsDevice)->StateFlags & - DISPLAY_DEVICE_MIRRORING_DRIVER)) - ret = C1_MIRRORING; - break; - - case BITSPIXEL: - ret = ppdev->gdiinfo.cBitsPixel; - break; - - case PLANES: - ret = ppdev->gdiinfo.cPlanes; - break; - - case NUMBRUSHES: - ret = -1; - break; - - case NUMPENS: - ret = ppdev->gdiinfo.ulNumColors; - if ( ret != -1 ) ret *= 5; - break; - - case NUMFONTS: - ret = IntcFonts(ppdev); - break; - - case NUMCOLORS: - ret = ppdev->gdiinfo.ulNumColors; - break; - - case ASPECTX: - ret = ppdev->gdiinfo.ulAspectX; - break; - - case ASPECTY: - ret = ppdev->gdiinfo.ulAspectY; - break; - - case ASPECTXY: - ret = ppdev->gdiinfo.ulAspectXY; - break; - - case CLIPCAPS: - ret = CP_RECTANGLE; - break; - - case SIZEPALETTE: - ret = ppdev->gdiinfo.ulNumPalReg; - break; - - case NUMRESERVED: - ret = 20; - break; - - case COLORRES: - ret = ppdev->gdiinfo.ulDACRed + - ppdev->gdiinfo.ulDACGreen + - ppdev->gdiinfo.ulDACBlue; - break; - - case DESKTOPVERTRES: - ret = ppdev->gdiinfo.ulVertRes; - break; - - case DESKTOPHORZRES: - ret = ppdev->gdiinfo.ulHorzRes; - break; - - case BLTALIGNMENT: - ret = ppdev->gdiinfo.ulBltAlignment; - break; - - case SHADEBLENDCAPS: - ret = ppdev->gdiinfo.flShadeBlend; - break; - - case COLORMGMTCAPS: - ret = IntGetColorManagementCaps(ppdev); - break; - - case PHYSICALWIDTH: - ret = ppdev->gdiinfo.szlPhysSize.cx; - break; - - case PHYSICALHEIGHT: - ret = ppdev->gdiinfo.szlPhysSize.cy; - break; - - case PHYSICALOFFSETX: - ret = ppdev->gdiinfo.ptlPhysOffset.x; - break; - - case PHYSICALOFFSETY: - ret = ppdev->gdiinfo.ptlPhysOffset.y; - break; - - case VREFRESH: - ret = ppdev->gdiinfo.ulVRefresh; - break; - - case RASTERCAPS: - ret = ppdev->gdiinfo.flRaster; - break; - - case CURVECAPS: - ret = (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE | - CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT); - break; - - case LINECAPS: - ret = (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE | - LC_STYLED | LC_WIDESTYLED | LC_INTERIORS); - break; - - case POLYGONALCAPS: - ret = (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE | - PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS); - break; - - case TEXTCAPS: - ret = ppdev->gdiinfo.flTextCaps; - if (ppdev->gdiinfo.ulTechnology) ret |= TC_VA_ABLE; - ret |= (TC_SO_ABLE|TC_UA_ABLE); - break; - - case PDEVICESIZE: - case SCALINGFACTORX: - case SCALINGFACTORY: - default: - ret = 0; - break; - } - - return ret; -} - -INT APIENTRY -NtGdiGetDeviceCaps(HDC hDC, - INT Index) -{ - PDC dc; - INT ret; - - dc = DC_LockDc(hDC); - if (dc == NULL) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return 0; - } - - ret = IntGdiGetDeviceCaps(dc, Index); - - DPRINT("(%04x,%d): returning %d\n", hDC, Index, ret); - - DC_UnlockDc( dc ); - return ret; -} - -VOID -FASTCALL -IntvGetDeviceCaps( - PPDEVOBJ pDevObj, - PDEVCAPS pDevCaps) -{ - ULONG Tmp = 0; - PGDIINFO pGdiInfo = &pDevObj->gdiinfo; - - pDevCaps->ulVersion = pGdiInfo->ulVersion; - pDevCaps->ulTechnology = pGdiInfo->ulTechnology; - pDevCaps->ulHorzSizeM = (pGdiInfo->ulHorzSize + 500) / 1000; - pDevCaps->ulVertSizeM = (pGdiInfo->ulVertSize + 500) / 1000; - pDevCaps->ulHorzSize = pGdiInfo->ulHorzSize; - pDevCaps->ulVertSize = pGdiInfo->ulVertSize; - pDevCaps->ulHorzRes = pGdiInfo->ulHorzRes; - pDevCaps->ulVertRes = pGdiInfo->ulVertRes; - pDevCaps->ulVRefresh = pGdiInfo->ulVRefresh; - pDevCaps->ulDesktopHorzRes = pGdiInfo->ulHorzRes; - pDevCaps->ulDesktopVertRes = pGdiInfo->ulVertRes; - pDevCaps->ulBltAlignment = pGdiInfo->ulBltAlignment; - pDevCaps->ulPlanes = pGdiInfo->cPlanes; - - pDevCaps->ulBitsPixel = pGdiInfo->cBitsPixel; - if (pGdiInfo->cBitsPixel == 15) pDevCaps->ulBitsPixel = 16; - - Tmp = pGdiInfo->ulNumColors; - if ( Tmp != -1 ) Tmp *= 5; - pDevCaps->ulNumPens = Tmp; - pDevCaps->ulNumColors = pGdiInfo->ulNumColors; - - pDevCaps->ulNumFonts = IntcFonts(pDevObj); - - pDevCaps->ulRasterCaps = pGdiInfo->flRaster; - pDevCaps->ulShadeBlend = pGdiInfo->flShadeBlend; - pDevCaps->ulAspectX = pGdiInfo->ulAspectX; - pDevCaps->ulAspectY = pGdiInfo->ulAspectY; - pDevCaps->ulAspectXY = pGdiInfo->ulAspectXY; - pDevCaps->ulLogPixelsX = pGdiInfo->ulLogPixelsX; - pDevCaps->ulLogPixelsY = pGdiInfo->ulLogPixelsY; - pDevCaps->ulSizePalette = pGdiInfo->ulNumPalReg; - pDevCaps->ulColorRes = pGdiInfo->ulDACRed + pGdiInfo->ulDACGreen + pGdiInfo->ulDACBlue; - pDevCaps->ulPhysicalWidth = pGdiInfo->szlPhysSize.cx; - pDevCaps->ulPhysicalHeight = pGdiInfo->szlPhysSize.cy; - pDevCaps->ulPhysicalOffsetX = pGdiInfo->ptlPhysOffset.x; - pDevCaps->ulPhysicalOffsetY = pGdiInfo->ptlPhysOffset.y; - pDevCaps->ulPanningHorzRes = pGdiInfo->ulPanningHorzRes; - pDevCaps->ulPanningVertRes = pGdiInfo->ulPanningVertRes; - pDevCaps->xPanningAlignment = pGdiInfo->xPanningAlignment; - pDevCaps->yPanningAlignment = pGdiInfo->yPanningAlignment; - - Tmp = 0; - Tmp = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER); - - pDevCaps->ulTextCaps = pGdiInfo->flTextCaps | (TC_SO_ABLE|TC_UA_ABLE|TC_CP_STROKE|TC_OP_STROKE|TC_OP_CHARACTER); - - if (pGdiInfo->ulTechnology) - pDevCaps->ulTextCaps = Tmp | TC_VA_ABLE; - - pDevCaps->ulColorMgmtCaps = IntGetColorManagementCaps(pDevObj); - - return; -} - -/* -* @implemented -*/ -BOOL -APIENTRY -NtGdiGetDeviceCapsAll ( - IN HDC hDC, - OUT PDEVCAPS pDevCaps) -{ - PDC dc; - PDEVCAPS pSafeDevCaps; - NTSTATUS Status = STATUS_SUCCESS; - - dc = DC_LockDc(hDC); - if (!dc) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return FALSE; - } - - pSafeDevCaps = ExAllocatePoolWithTag(PagedPool, sizeof(DEVCAPS), TAG_TEMP); - - if (!pSafeDevCaps) - { - DC_UnlockDc(dc); - return FALSE; - } - - IntvGetDeviceCaps(dc->ppdev, pSafeDevCaps); - - _SEH2_TRY - { - ProbeForWrite(pDevCaps, - sizeof(DEVCAPS), - 1); - RtlCopyMemory(pDevCaps, pSafeDevCaps, sizeof(DEVCAPS)); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END; - - ExFreePoolWithTag(pSafeDevCaps, TAG_TEMP); - DC_UnlockDc(dc); - - if (!NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return FALSE; - } - return TRUE; -} - - -/* - * @implemented - */ -DHPDEV -APIENTRY -NtGdiGetDhpdev( - IN HDEV hdev) -{ - PPDEVOBJ ppdev, pGdiDevice = (PPDEVOBJ) hdev; - if (!pGdiDevice) return NULL; - if ( pGdiDevice < (PPDEVOBJ)MmSystemRangeStart) return NULL; - ppdev = pPrimarySurface; - IntGdiAcquireSemaphore(hsemDriverMgmt); - do - { - if (pGdiDevice == ppdev) break; - else - ppdev = ppdev->ppdevNext; - } - while (ppdev != NULL); - IntGdiReleaseSemaphore(hsemDriverMgmt); - if (!ppdev) return NULL; - return pGdiDevice->dhpdev; -} - -static NTSTATUS FASTCALL -GetVideoRegistryKey( - OUT PUNICODE_STRING RegistryPath, - IN PCUNICODE_STRING DeviceName) /* ex: "\Device\Video0" */ -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - NTSTATUS Status; - - RtlInitUnicodeString(RegistryPath, NULL); - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].Name = DeviceName->Buffer; - QueryTable[0].EntryContext = RegistryPath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, - L"VIDEO", - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("No %wZ value in DEVICEMAP\\VIDEO found (Status 0x%08lx)\n", DeviceName, Status); - return STATUS_NO_SUCH_DEVICE; - } - - DPRINT("RegistryPath %wZ\n", RegistryPath); - return STATUS_SUCCESS; -} - - -static NTSTATUS FASTCALL -GetVideoDeviceName( - OUT PUNICODE_STRING VideoDeviceName, - IN PCUNICODE_STRING DisplayDevice) /* ex: "\.\DISPLAY1" or "\??\DISPLAY1" */ -{ - UNICODE_STRING Prefix = RTL_CONSTANT_STRING(L"\\??\\"); - UNICODE_STRING ObjectName; - UNICODE_STRING KernelModeName = { 0, }; - OBJECT_ATTRIBUTES ObjectAttributes; - USHORT LastSlash; - ULONG Length; - HANDLE LinkHandle = NULL; - NTSTATUS Status; - - RtlInitUnicodeString(VideoDeviceName, NULL); - - /* Get device name (DisplayDevice is "\.\xxx") */ - for (LastSlash = DisplayDevice->Length / sizeof(WCHAR); LastSlash > 0; LastSlash--) - { - if (DisplayDevice->Buffer[LastSlash - 1] == L'\\') - break; - } - - if (LastSlash == 0) - { - DPRINT1("Invalid device name '%wZ'\n", DisplayDevice); - Status = STATUS_OBJECT_NAME_INVALID; - goto cleanup; - } - ObjectName = *DisplayDevice; - ObjectName.Length -= LastSlash * sizeof(WCHAR); - ObjectName.MaximumLength -= LastSlash * sizeof(WCHAR); - ObjectName.Buffer += LastSlash; - - /* Create "\??\xxx" (ex: "\??\DISPLAY1") */ - KernelModeName.MaximumLength = Prefix.Length + ObjectName.Length + sizeof(UNICODE_NULL); - KernelModeName.Buffer = ExAllocatePoolWithTag(PagedPool, - KernelModeName.MaximumLength, - TAG_DC); - if (!KernelModeName.Buffer) - { - Status = STATUS_NO_MEMORY; - goto cleanup; - } - RtlCopyUnicodeString(&KernelModeName, &Prefix); - Status = RtlAppendUnicodeStringToString(&KernelModeName, &ObjectName); - if (!NT_SUCCESS(Status)) - goto cleanup; - - /* Open \??\xxx (ex: "\??\DISPLAY1") */ - InitializeObjectAttributes(&ObjectAttributes, - &KernelModeName, - OBJ_KERNEL_HANDLE, - NULL, - NULL); - Status = ZwOpenSymbolicLinkObject(&LinkHandle, - GENERIC_READ, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to open symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status); - Status = STATUS_NO_SUCH_DEVICE; - goto cleanup; - } - - Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, &Length); - if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL) - { - DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status); - Status = STATUS_NO_SUCH_DEVICE; - goto cleanup; - } - VideoDeviceName->MaximumLength = Length; - VideoDeviceName->Buffer = ExAllocatePoolWithTag(PagedPool, - VideoDeviceName->MaximumLength + sizeof(UNICODE_NULL), - TAG_DC); - if (!VideoDeviceName->Buffer) - { - Status = STATUS_NO_MEMORY; - goto cleanup; - } - Status = ZwQuerySymbolicLinkObject(LinkHandle, VideoDeviceName, NULL); - VideoDeviceName->Buffer[VideoDeviceName->MaximumLength / sizeof(WCHAR) - 1] = UNICODE_NULL; - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to query symbolic link %wZ (Status 0x%08lx)\n", &KernelModeName, Status); - Status = STATUS_NO_SUCH_DEVICE; - goto cleanup; - } - Status = STATUS_SUCCESS; - -cleanup: - if (!NT_SUCCESS(Status) && VideoDeviceName->Buffer) - ExFreePoolWithTag(VideoDeviceName->Buffer, TAG_DC); - if (KernelModeName.Buffer) - ExFreePoolWithTag(KernelModeName.Buffer, TAG_DC); - if (LinkHandle) - ZwClose(LinkHandle); - return Status; -} - -LONG -FASTCALL -IntChangeDisplaySettings( - IN PUNICODE_STRING pDeviceName OPTIONAL, - IN LPDEVMODEW DevMode, - IN DWORD dwflags, - IN PVOID lParam OPTIONAL) -{ - BOOLEAN NoReset = FALSE; - BOOLEAN Reset = FALSE; - LONG Ret = DISP_CHANGE_SUCCESSFUL; - NTSTATUS Status ; - - DPRINT1("display flags : %x\n",dwflags); - - if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY) - { - /* Check global, reset and noreset flags */ - if ((dwflags & CDS_GLOBAL) == CDS_GLOBAL) - DPRINT1("CDS_GLOBAL unhandled"); - if ((dwflags & CDS_NORESET) == CDS_NORESET) - NoReset = TRUE; - dwflags &= ~(CDS_GLOBAL | CDS_NORESET); - } - if ((dwflags & CDS_RESET) == CDS_RESET) - Reset = TRUE; - if ((dwflags & CDS_SET_PRIMARY) == CDS_SET_PRIMARY) - DPRINT1("CDS_SET_PRIMARY unhandled"); - dwflags &= ~(CDS_RESET | CDS_SET_PRIMARY); - - if (Reset && NoReset) - return DISP_CHANGE_BADFLAGS; - - if (dwflags == 0) - { - /* Dynamically change graphics mode */ - DPRINT1("flag 0 UNIMPLEMENTED\n"); - SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED); - return DISP_CHANGE_FAILED; - } - - if ((dwflags & CDS_TEST) == CDS_TEST) - { - /* Test resolution */ - dwflags &= ~CDS_TEST; - Status = IntEnumDisplaySettings(pDeviceName, ENUM_REGISTRY_SETTINGS, DevMode, 0); - if (!NT_SUCCESS(Status)) - Ret = DISP_CHANGE_BADMODE; - return Ret; - } - - if ((dwflags & CDS_FULLSCREEN) == CDS_FULLSCREEN) - { - DEVMODEW lpDevMode; - /* Full Screen */ - dwflags &= ~CDS_FULLSCREEN; - DPRINT1("flag CDS_FULLSCREEN partially implemented\n"); - Ret = DISP_CHANGE_FAILED; - - RtlZeroMemory(&lpDevMode, sizeof(DEVMODEW)); - lpDevMode.dmSize = sizeof(DEVMODEW); - - Status = IntEnumDisplaySettings(pDeviceName, ENUM_CURRENT_SETTINGS, &lpDevMode, 0); - if (!NT_SUCCESS(Status)) - return DISP_CHANGE_FAILED; - - DPRINT1("Req Mode : %d x %d x %d\n", DevMode->dmPelsWidth,DevMode->dmPelsHeight,DevMode->dmBitsPerPel); - DPRINT1("Current Mode : %d x %d x %d\n", lpDevMode.dmPelsWidth,lpDevMode.dmPelsHeight, lpDevMode.dmBitsPerPel); - - - if ((lpDevMode.dmBitsPerPel == DevMode->dmBitsPerPel) && - (lpDevMode.dmPelsWidth == DevMode->dmPelsWidth) && - (lpDevMode.dmPelsHeight == DevMode->dmPelsHeight)) - Ret = DISP_CHANGE_SUCCESSFUL; - } - - if ((dwflags & CDS_VIDEOPARAMETERS) == CDS_VIDEOPARAMETERS) - { - dwflags &= ~CDS_VIDEOPARAMETERS; - if (lParam == NULL) - Ret=DISP_CHANGE_BADPARAM; - else - { - DPRINT1("flag CDS_VIDEOPARAMETERS UNIMPLEMENTED\n"); - Ret = DISP_CHANGE_FAILED; - SetLastWin32Error(ERROR_CALL_NOT_IMPLEMENTED); - } - - } - - if ((dwflags & CDS_UPDATEREGISTRY) == CDS_UPDATEREGISTRY) - { - - UNICODE_STRING DeviceName; - UNICODE_STRING RegistryKey; - UNICODE_STRING InDeviceName; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE DevInstRegKey; - ULONG NewValue; - - DPRINT1("set CDS_UPDATEREGISTRY\n"); - - dwflags &= ~CDS_UPDATEREGISTRY; - - /* Check if pDeviceName is NULL, we need to retrieve it */ - if (pDeviceName == NULL) - { - WCHAR szBuffer[MAX_DRIVER_NAME]; - PDC DC; - PWND Wnd=NULL; - HWND hWnd; - HDC hDC; - - hWnd = IntGetDesktopWindow(); - if (!(Wnd = UserGetWindowObject(hWnd))) - { - return FALSE; - } - - hDC = UserGetWindowDC(Wnd); - - DC = DC_LockDc(hDC); - if (NULL == DC) - { - return FALSE; - } - swprintf (szBuffer, L"\\\\.\\DISPLAY%lu", DC->ppdev->DisplayNumber); - DC_UnlockDc(DC); - - RtlInitUnicodeString(&InDeviceName, szBuffer); - pDeviceName = &InDeviceName; - } - - Status = GetVideoDeviceName(&DeviceName, pDeviceName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to get destination of '%wZ' (Status 0x%08lx)\n", pDeviceName, Status); - return DISP_CHANGE_FAILED; - } - Status = GetVideoRegistryKey(&RegistryKey, &DeviceName); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to get registry key for '%wZ' (Status 0x%08lx)\n", &DeviceName, Status); - ExFreePoolWithTag(DeviceName.Buffer, TAG_DC); - return DISP_CHANGE_FAILED; - } - ExFreePoolWithTag(DeviceName.Buffer, TAG_DC); - - InitializeObjectAttributes(&ObjectAttributes, &RegistryKey, - OBJ_CASE_INSENSITIVE, NULL, NULL); - Status = ZwOpenKey(&DevInstRegKey, KEY_SET_VALUE, &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to open registry key %wZ (Status 0x%08lx)\n", &RegistryKey, Status); - ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY); - return DISP_CHANGE_FAILED; - } - ExFreePoolWithTag(RegistryKey.Buffer, TAG_RTLREGISTRY); - - /* Update needed fields */ - if (NT_SUCCESS(Status) && DevMode->dmFields & DM_BITSPERPEL) - { - RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.BitsPerPel"); - NewValue = DevMode->dmBitsPerPel; - Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue)); - } - - if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSWIDTH) - { - RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.XResolution"); - NewValue = DevMode->dmPelsWidth; - Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue)); - } - - if (NT_SUCCESS(Status) && DevMode->dmFields & DM_PELSHEIGHT) - { - RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.YResolution"); - NewValue = DevMode->dmPelsHeight; - Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue)); - } - - if (NT_SUCCESS(Status) && DevMode->dmFields & DM_DISPLAYFREQUENCY) - { - RtlInitUnicodeString(&RegistryKey, L"DefaultSettings.VRefresh"); - NewValue = DevMode->dmDisplayFrequency; - Status = ZwSetValueKey(DevInstRegKey, &RegistryKey, 0, REG_DWORD, &NewValue, sizeof(NewValue)); - } - - ZwClose(DevInstRegKey); - if (NT_SUCCESS(Status)) - Ret = DISP_CHANGE_RESTART; - else - /* return DISP_CHANGE_NOTUPDATED when we can save to reg only valid for NT */ - Ret = DISP_CHANGE_NOTUPDATED; - } - - if (dwflags != 0) - Ret = DISP_CHANGE_BADFLAGS; - - DPRINT("IntChangeDisplaySettings returning %x\n", Ret); - return Ret; -} - - - -#define SIZEOF_DEVMODEW_300 188 -#define SIZEOF_DEVMODEW_400 212 -#define SIZEOF_DEVMODEW_500 220 - -static NTSTATUS FASTCALL -GetDisplayNumberFromDeviceName( - IN PUNICODE_STRING pDeviceName OPTIONAL, - OUT ULONG *DisplayNumber) -{ - UNICODE_STRING DisplayString = RTL_CONSTANT_STRING(L"\\\\.\\DISPLAY"); - NTSTATUS Status = STATUS_SUCCESS; - ULONG Length; - ULONG Number; - ULONG i; - - if (DisplayNumber == NULL) - return STATUS_INVALID_PARAMETER_2; - - /* Check if DeviceName is valid */ - if (pDeviceName && - pDeviceName->Length > 0 && pDeviceName->Length <= DisplayString.Length) - return STATUS_OBJECT_NAME_INVALID; - - if (pDeviceName == NULL || pDeviceName->Length == 0) - { - PWND DesktopObject; - HDC DesktopHDC; - PDC pDC; - - DesktopObject = UserGetDesktopWindow(); - DesktopHDC = UserGetWindowDC(DesktopObject); - pDC = DC_LockDc(DesktopHDC); - - *DisplayNumber = pDC->ppdev->DisplayNumber; - - DC_UnlockDc(pDC); - UserReleaseDC(DesktopObject, DesktopHDC, FALSE); - - return STATUS_SUCCESS; - } - - /* Hack to check if the first parts are equal, by faking the device name length */ - Length = pDeviceName->Length; - pDeviceName->Length = DisplayString.Length; - if (RtlEqualUnicodeString(&DisplayString, pDeviceName, FALSE) == FALSE) - Status = STATUS_OBJECT_NAME_INVALID; - pDeviceName->Length = Length; - - if (NT_SUCCESS(Status)) - { - /* Convert the last part of pDeviceName to a number */ - Number = 0; - Length = pDeviceName->Length / sizeof(WCHAR); - for (i = DisplayString.Length / sizeof(WCHAR); i < Length; i++) - { - WCHAR Char = pDeviceName->Buffer[i]; - if (Char >= L'0' && Char <= L'9') - Number = Number * 10 + Char - L'0'; - else if (Char != L'\0') - return STATUS_OBJECT_NAME_INVALID; - } - - *DisplayNumber = Number - 1; - } - - return Status; -} - -/*! \brief Enumerate possible display settings for the given display... - * - * \todo Make thread safe!? - * \todo Don't ignore pDeviceName - * \todo Implement non-raw mode (only return settings valid for driver and monitor) - */ -NTSTATUS -FASTCALL -IntEnumDisplaySettings( - IN PUNICODE_STRING pDeviceName OPTIONAL, - IN DWORD iModeNum, - IN OUT LPDEVMODEW pDevMode, - IN DWORD dwFlags) -{ - static DEVMODEW *CachedDevModes = NULL, *CachedDevModesEnd = NULL; - static DWORD SizeOfCachedDevModes = 0; - static UNICODE_STRING CachedDeviceName; - PDEVMODEW CachedMode = NULL; - DEVMODEW DevMode; - ULONG DisplayNumber; - NTSTATUS Status; - - Status = GetDisplayNumberFromDeviceName(pDeviceName, &DisplayNumber); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - if (pDevMode != NULL) - { - DPRINT("DevMode->dmSize = %d\n", pDevMode->dmSize); - DPRINT("DevMode->dmExtraSize = %d\n", pDevMode->dmDriverExtra); - if (pDevMode->dmSize != SIZEOF_DEVMODEW_300 && - pDevMode->dmSize != SIZEOF_DEVMODEW_400 && - pDevMode->dmSize != SIZEOF_DEVMODEW_500) - { - return STATUS_BUFFER_TOO_SMALL; - } - } - - if (iModeNum == ENUM_CURRENT_SETTINGS) - { - CachedMode = &PrimarySurface.DMW; - ASSERT(CachedMode->dmSize > 0); - } - else if (iModeNum == ENUM_REGISTRY_SETTINGS) - { - RtlZeroMemory(&DevMode, sizeof (DevMode)); - DevMode.dmSize = sizeof (DevMode); - DevMode.dmDriverExtra = 0; - if (SetupDevMode(&DevMode, DisplayNumber)) - CachedMode = &DevMode; - else - { - return STATUS_UNSUCCESSFUL; // FIXME: what status? - } - /* FIXME: Maybe look for the matching devmode supplied by the - * driver so we can provide driver private/extra data? - */ - } - else - { - BOOL IsCachedDevice = (CachedDevModes != NULL); - - if (CachedDevModes && - ((pDeviceName == NULL && CachedDeviceName.Length > 0) || - (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length == 0) || - (pDeviceName != NULL && pDeviceName->Buffer != NULL && CachedDeviceName.Length > 0 && RtlEqualUnicodeString(pDeviceName, &CachedDeviceName, TRUE) == FALSE))) - { - IsCachedDevice = FALSE; - } - - if (iModeNum == 0 || IsCachedDevice == FALSE) /* query modes from drivers */ - { - UNICODE_STRING DriverFileNames; - LPWSTR CurrentName; - DRVENABLEDATA DrvEnableData; - - /* Free resources from last driver cache */ - if (IsCachedDevice == FALSE && CachedDeviceName.Buffer != NULL) - { - RtlFreeUnicodeString(&CachedDeviceName); - } - - /* Retrieve DDI driver names from registry */ - RtlInitUnicodeString(&DriverFileNames, NULL); - if (!FindDriverFileNames(&DriverFileNames, DisplayNumber)) - { - DPRINT1("FindDriverFileNames failed\n"); - return STATUS_UNSUCCESSFUL; - } - - if (!IntPrepareDriverIfNeeded()) - { - DPRINT1("IntPrepareDriverIfNeeded failed\n"); - return STATUS_UNSUCCESSFUL; - } - - /* - * DriverFileNames may be a list of drivers in REG_SZ_MULTI format, - * scan all of them until a good one found. - */ - CurrentName = DriverFileNames.Buffer; - for (;CurrentName < DriverFileNames.Buffer + (DriverFileNames.Length / sizeof (WCHAR)); - CurrentName += wcslen(CurrentName) + 1) - { - INT i; - PFN_DrvEnableDriver GDEnableDriver; - PFN_DrvGetModes GetModes = NULL; - INT SizeNeeded, SizeUsed; - - /* Get the DDI driver's entry point */ - //GDEnableDriver = DRIVER_FindDDIDriver(CurrentName); - GDEnableDriver = DRIVER_FindExistingDDIDriver(L"DISPLAY"); - if (NULL == GDEnableDriver) - { - DPRINT("FindDDIDriver failed for %S\n", CurrentName); - continue; - } - - /* Call DDI driver's EnableDriver function */ - RtlZeroMemory(&DrvEnableData, sizeof(DrvEnableData)); - - if (!GDEnableDriver(DDI_DRIVER_VERSION_NT5_01, sizeof (DrvEnableData), &DrvEnableData)) - { - DPRINT("DrvEnableDriver failed for %S\n", CurrentName); - continue; - } - - CachedDevModesEnd = CachedDevModes; - - /* find DrvGetModes function */ - for (i = 0; i < DrvEnableData.c; i++) - { - PDRVFN DrvFn = DrvEnableData.pdrvfn + i; - - if (DrvFn->iFunc == INDEX_DrvGetModes) - { - GetModes = (PFN_DrvGetModes)DrvFn->pfn; - break; - } - } - - if (GetModes == NULL) - { - DPRINT("DrvGetModes doesn't exist for %S\n", CurrentName); - continue; - } - - /* make sure we have enough memory to hold the modes */ - SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), 0, NULL); - if (SizeNeeded <= 0) - { - DPRINT("DrvGetModes failed for %S\n", CurrentName); - break; - } - - SizeUsed = (PCHAR)CachedDevModesEnd - (PCHAR)CachedDevModes; - if (SizeOfCachedDevModes < SizeUsed + SizeNeeded) - { - PVOID NewBuffer; - - SizeOfCachedDevModes += SizeNeeded; - NewBuffer = ExAllocatePoolWithTag(PagedPool, SizeOfCachedDevModes, GDITAG_DEVMODE); - if (NewBuffer == NULL) - { - /* clean up */ - ExFreePool(CachedDevModes); - CachedDevModes = NULL; - CachedDevModesEnd = NULL; - SizeOfCachedDevModes = 0; - - if (CachedDeviceName.Buffer != NULL) - RtlFreeUnicodeString(&CachedDeviceName); - - return STATUS_NO_MEMORY; - } - if (CachedDevModes != NULL) - { - RtlCopyMemory(NewBuffer, CachedDevModes, SizeUsed); - ExFreePool(CachedDevModes); - } - CachedDevModes = NewBuffer; - CachedDevModesEnd = (DEVMODEW *)((PCHAR)NewBuffer + SizeUsed); - } - - if (!IsCachedDevice) - { - if (CachedDeviceName.Buffer != NULL) - RtlFreeUnicodeString(&CachedDeviceName); - - if (pDeviceName) - IntSafeCopyUnicodeString(&CachedDeviceName, pDeviceName); - - IsCachedDevice = TRUE; - } - - /* query modes */ - SizeNeeded = GetModes((HANDLE)(PrimarySurface.VideoFileObject->DeviceObject), - SizeNeeded, - CachedDevModesEnd); - if (SizeNeeded <= 0) - { - DPRINT("DrvGetModes failed for %S\n", CurrentName); - } - else - { - CachedDevModesEnd = (DEVMODEW *)((PCHAR)CachedDevModesEnd + SizeNeeded); - } - } - - ExFreePoolWithTag(DriverFileNames.Buffer, TAG_RTLREGISTRY); - } - - /* return cached info */ - CachedMode = CachedDevModes; - if (CachedMode >= CachedDevModesEnd) - { - return STATUS_NO_MORE_ENTRIES; - } - while (iModeNum-- > 0 && CachedMode < CachedDevModesEnd) - { - ASSERT(CachedMode->dmSize > 0); - CachedMode = (DEVMODEW *)((PCHAR)CachedMode + CachedMode->dmSize + CachedMode->dmDriverExtra); - } - if (CachedMode >= CachedDevModesEnd) - { - return STATUS_NO_MORE_ENTRIES; - } - } - - ASSERT(CachedMode != NULL); - - if (pDevMode != NULL) - { - RtlCopyMemory(pDevMode, CachedMode, min(pDevMode->dmSize, CachedMode->dmSize)); - RtlZeroMemory(pDevMode + pDevMode->dmSize, pDevMode->dmDriverExtra); - RtlCopyMemory(pDevMode + min(pDevMode->dmSize, CachedMode->dmSize), CachedMode + CachedMode->dmSize, min(pDevMode->dmDriverExtra, CachedMode->dmDriverExtra)); - } - - return STATUS_SUCCESS; -} - INT APIENTRY NtGdiDrawEscape( @@ -1776,3 +92,4 @@ NtGdiDrawEscape( return 0; } + diff --git a/subsystems/win32/win32k/objects/dibobj.c b/subsystems/win32/win32k/objects/dibobj.c index f8ce6460278..116aebf93f8 100644 --- a/subsystems/win32/win32k/objects/dibobj.c +++ b/subsystems/win32/win32k/objects/dibobj.c @@ -42,6 +42,26 @@ static const RGBQUAD EGAColorsQuads[16] = { { 0xff, 0xff, 0xff, 0x00 } }; +static const RGBTRIPLE EGAColorsTriples[16] = { +/* rgbBlue, rgbGreen, rgbRed */ + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x80 }, + { 0x00, 0x80, 0x00 }, + { 0x00, 0x80, 0x80 }, + { 0x80, 0x00, 0x00 }, + { 0x80, 0x00, 0x80 }, + { 0x80, 0x80, 0x00 }, + { 0x80, 0x80, 0x80 }, + { 0xc0, 0xc0, 0xc0 }, + { 0x00, 0x00, 0xff }, + { 0x00, 0xff, 0x00 }, + { 0x00, 0xff, 0xff }, + { 0xff, 0x00, 0x00 }, + { 0xff, 0x00, 0xff }, + { 0xff, 0xff, 0x00 }, + { 0xff, 0xff, 0xff } +}; + static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */ /* rgbBlue, rgbGreen, rgbRed, rgbReserved */ { 0x00, 0x00, 0x00, 0x00 }, @@ -66,6 +86,30 @@ static const RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palet { 0xff, 0xff, 0xff, 0x00 } }; +static const RGBQUAD DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */ +/* rgbBlue, rgbGreen, rgbRed, rgbReserved */ + { 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x80 }, + { 0x00, 0x80, 0x00 }, + { 0x00, 0x80, 0x80 }, + { 0x80, 0x00, 0x00 }, + { 0x80, 0x00, 0x80 }, + { 0x80, 0x80, 0x00 }, + { 0xc0, 0xc0, 0xc0 }, + { 0xc0, 0xdc, 0xc0 }, + { 0xf0, 0xca, 0xa6 }, + { 0xf0, 0xfb, 0xff }, + { 0xa4, 0xa0, 0xa0 }, + { 0x80, 0x80, 0x80 }, + { 0x00, 0x00, 0xf0 }, + { 0x00, 0xff, 0x00 }, + { 0x00, 0xff, 0xff }, + { 0xff, 0x00, 0x00 }, + { 0xff, 0x00, 0xff }, + { 0xff, 0xff, 0x00 }, + { 0xff, 0xff, 0xff } +}; + UINT APIENTRY @@ -109,14 +153,15 @@ IntSetDIBColorTable( if (StartIndex + Entries > (1 << biBitCount)) Entries = (1 << biBitCount) - StartIndex; - PalGDI = PALETTE_LockPalette(psurf->hDIBPalette); - if (PalGDI == NULL) + if (psurf->ppal == NULL) { DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_HANDLE); return 0; } + PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr); + for (Index = StartIndex; Index < StartIndex + Entries && Index < PalGDI->NumColors; Index++) @@ -181,14 +226,15 @@ IntGetDIBColorTable( if (StartIndex + Entries > (1 << biBitCount)) Entries = (1 << biBitCount) - StartIndex; - PalGDI = PALETTE_LockPalette(psurf->hDIBPalette); - if (PalGDI == NULL) + if (psurf->ppal == NULL) { DC_UnlockDc(dc); SetLastWin32Error(ERROR_INVALID_HANDLE); return 0; } + PalGDI = PALETTE_LockPalette(psurf->ppal->BaseObject.hHmgr); + for (Index = StartIndex; Index < StartIndex + Entries && Index < PalGDI->NumColors; Index++) @@ -219,132 +265,67 @@ IntSetDIBits( CONST BITMAPINFO *bmi, UINT ColorUse) { - SURFACE *bitmap; HBITMAP SourceBitmap; + PSURFACE psurfDst, psurfSrc; INT result = 0; - BOOL copyBitsResult; - SURFOBJ *DestSurf, *SourceSurf; - SIZEL SourceSize; - POINTL ZeroPoint; - RECTL DestRect; - EXLATEOBJ exlo; - PPALETTE ppalDDB, ppalDIB; - //RGBQUAD *lpRGB; - HPALETTE DDB_Palette, DIB_Palette; - ULONG DIB_Palette_Type; - INT DIBWidth; + RECT rcDst; + POINTL ptSrc; + PVOID pvBits; + EXLATEOBJ exlo; - // Check parameters - if (!(bitmap = SURFACE_LockSurface(hBitmap))) + SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0); + if (0 == SourceBitmap) { - return 0; - } - - // Get RGB values - //if (ColorUse == DIB_PAL_COLORS) - // lpRGB = DIB_MapPaletteColors(hDC, bmi); - //else - // lpRGB = &bmi->bmiColors; - - DestSurf = &bitmap->SurfObj; - - // Create source surface - SourceSize.cx = bmi->bmiHeader.biWidth; - SourceSize.cy = ScanLines; - - // Determine width of DIB - DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount); - - SourceBitmap = EngCreateBitmap(SourceSize, - DIBWidth, - BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), - bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, - (PVOID) Bits); - if (0 == SourceBitmap) - { - SURFACE_UnlockSurface(bitmap); + DPRINT1("Error : Could not create a DIBSection.\n"); SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); return 0; } - SourceSurf = EngLockSurface((HSURF)SourceBitmap); - if (NULL == SourceSurf) - { - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return 0; - } + RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, + bmi->bmiHeader.biHeight, + bmi->bmiHeader.biBitCount)); - // Use hDIBPalette if it exists - if (bitmap->hDIBPalette) - { - DDB_Palette = bitmap->hDIBPalette; - } - else - { - // Destination palette obtained from the hDC - DDB_Palette = DC->ppdev->devinfo.hpalDefault; - } + psurfDst = SURFACE_LockSurface(hBitmap); + psurfSrc = SURFACE_LockSurface(SourceBitmap); - ppalDDB = PALETTE_LockPalette(DDB_Palette); - if (NULL == ppalDDB) - { - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return 0; - } + if(!(psurfSrc && psurfDst)) + { + DPRINT1("Error, could not lock surfaces\n"); + goto cleanup; + } - // Source palette obtained from the BITMAPINFO - DIB_Palette = BuildDIBPalette((PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type); - if (NULL == DIB_Palette) - { - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - SURFACE_UnlockSurface(bitmap); - SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return 0; - } + rcDst.top = bmi->bmiHeader.biHeight < 0 ? + abs(bmi->bmiHeader.biHeight) - (ScanLines + StartScan) : StartScan; + rcDst.left = 0; + rcDst.bottom = rcDst.top + ScanLines; + rcDst.right = psurfDst->SurfObj.sizlBitmap.cx; - ppalDIB = PALETTE_LockPalette(DIB_Palette); + ptSrc.x = 0; + ptSrc.y = 0; - /* Initialize XLATEOBJ for color translation */ - EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0); + EXLATEOBJ_vInitialize(&exlo, psurfSrc->ppal, psurfDst->ppal, 0, 0, 0); - // Zero point - ZeroPoint.x = 0; - ZeroPoint.y = 0; + result = IntEngCopyBits(&psurfDst->SurfObj, + &psurfSrc->SurfObj, + NULL, + &exlo.xlo, + &rcDst, + &ptSrc); + if(result) + result = ScanLines; - // Determine destination rectangle - DestRect.left = 0; - DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines; - DestRect.right = SourceSize.cx; - DestRect.bottom = DestRect.top + ScanLines; + EXLATEOBJ_vCleanup(&exlo); - copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint); - - // If it succeeded, return number of scanlines copies - if (copyBitsResult == TRUE) - { - result = SourceSize.cy; -// or -// result = abs(bmi->bmiHeader.biHeight) - StartScan; - } - - // Clean up - EXLATEOBJ_vCleanup(&exlo); - PALETTE_UnlockPalette(ppalDIB); - PALETTE_UnlockPalette(ppalDDB); - PALETTE_FreePaletteByHandle(DIB_Palette); - EngUnlockSurface(SourceSurf); - EngDeleteSurface((HSURF)SourceBitmap); - -// if (ColorUse == DIB_PAL_COLORS) -// WinFree((LPSTR)lpRGB); - - SURFACE_UnlockSurface(bitmap); +cleanup: + if(psurfSrc) + { + SURFACE_UnlockSurface(psurfSrc); + } + if(psurfDst) + { + SURFACE_UnlockSurface(psurfDst); + } + GreDeleteObject(SourceBitmap); return result; } @@ -366,17 +347,19 @@ NtGdiSetDIBits( PDC Dc; INT Ret; NTSTATUS Status = STATUS_SUCCESS; - UINT cjBits; if (!Bits) return 0; _SEH2_TRY - { // FYI: We converted from CORE in gdi. - ProbeForRead(bmi, sizeof(BITMAPINFO), 1); - cjBits = bmi->bmiHeader.biBitCount * bmi->bmiHeader.biPlanes * bmi->bmiHeader.biWidth; - cjBits = ((cjBits + 31) & ~31) / 8; - cjBits *= ScanLines; - ProbeForRead(Bits, cjBits, 1); + { + ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForRead(bmi, bmi->bmiHeader.biSize, 1); + ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1); + ProbeForRead(Bits, + DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, + ScanLines, + bmi->bmiHeader.biBitCount), + 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -440,15 +423,14 @@ NtGdiSetDIBitsToDeviceInternal( INT DIBWidth; SIZEL SourceSize; EXLATEOBJ exlo; - PPALETTE ppalDDB = NULL, ppalDIB = NULL; - HPALETTE hpalDDB, hpalDIB = NULL; - ULONG DIBPaletteType; + PPALETTE ppalDIB = NULL; + HPALETTE hpalDIB = NULL; if (!Bits) return 0; _SEH2_TRY { - ProbeForRead(bmi, cjMaxInfo , 1); + ProbeForRead(bmi, cjMaxInfo, 1); ProbeForRead(Bits, cjMaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -474,15 +456,7 @@ NtGdiSetDIBitsToDeviceInternal( return 0; } - /* Use destination palette obtained from the DC by default */ - hpalDDB = pDC->ppdev->devinfo.hpalDefault; - - /* Try to use hDIBPalette if it exists */ pSurf = pDC->dclevel.pSurface; - if (pSurf && pSurf->hDIBPalette) - { - hpalDDB = pSurf->hDIBPalette; - } pDestSurf = pSurf ? &pSurf->SurfObj : NULL; @@ -506,11 +480,12 @@ NtGdiSetDIBitsToDeviceInternal( SourceSize.cx = bmi->bmiHeader.biWidth; SourceSize.cy = ScanLines; - DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount); + DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount); hSourceBitmap = EngCreateBitmap(SourceSize, DIBWidth, - BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), + BitmapFormat(bmi->bmiHeader.biBitCount, + bmi->bmiHeader.biCompression), bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, (PVOID) Bits); if (!hSourceBitmap) @@ -527,17 +502,10 @@ NtGdiSetDIBitsToDeviceInternal( goto Exit; } - /* Obtain destination palette */ - ppalDDB = PALETTE_LockPalette(hpalDDB); - if (!ppalDDB) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - Status = STATUS_UNSUCCESSFUL; - goto Exit; - } + ASSERT(pSurf->ppal); /* Create a palette for the DIB */ - hpalDIB = BuildDIBPalette(bmi, (PINT)&DIBPaletteType); + hpalDIB = BuildDIBPalette(bmi); if (!hpalDIB) { SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); @@ -547,7 +515,7 @@ NtGdiSetDIBitsToDeviceInternal( /* Lock the DIB palette */ ppalDIB = PALETTE_LockPalette(hpalDIB); - if (!ppalDDB) + if (!ppalDIB) { SetLastWin32Error(ERROR_INVALID_HANDLE); Status = STATUS_UNSUCCESSFUL; @@ -555,7 +523,7 @@ NtGdiSetDIBitsToDeviceInternal( } /* Initialize EXLATEOBJ */ - EXLATEOBJ_vInitialize(&exlo, ppalDIB, ppalDDB, 0, 0, 0); + EXLATEOBJ_vInitialize(&exlo, ppalDIB, pSurf->ppal, 0, 0, 0); /* Copy the bits */ DPRINT("BitsToDev with dstsurf=(%d|%d) (%d|%d), src=(%d|%d) w=%d h=%d\n", @@ -583,7 +551,6 @@ Exit: } if (ppalDIB) PALETTE_UnlockPalette(ppalDIB); - if (ppalDDB) PALETTE_UnlockPalette(ppalDDB); if (pSourceSurf) EngUnlockSurface(pSourceSurf); if (hSourceBitmap) EngDeleteSurface((HSURF)hSourceBitmap); @@ -608,37 +575,29 @@ NtGdiGetDIBitsInternal( UINT MaxBits, UINT MaxInfo) { - PDC Dc; - SURFACE *psurf = NULL; - HBITMAP hDestBitmap = NULL; - HPALETTE hSourcePalette = NULL; - HPALETTE hDestPalette = NULL; - PPALETTE ppalSrc = NULL; - PPALETTE ppalDst = NULL; - NTSTATUS Status = STATUS_SUCCESS; - ULONG Result = 0; - BOOL bPaletteMatch = FALSE; - PBYTE ChkBits = Bits; - PVOID ColorPtr; - RGBQUAD *rgbQuads; - ULONG DestPaletteType; - ULONG Index; + BITMAPCOREINFO* pbmci = NULL; + PSURFACE psurf = NULL; + PDC pDC; + LONG width, height; + WORD planes, bpp; + DWORD compr, size ; + int i, bitmap_type; + RGBTRIPLE* rgbTriples; + RGBQUAD* rgbQuads; + VOID* colorPtr; + NTSTATUS Status = STATUS_SUCCESS; DPRINT("Entered NtGdiGetDIBitsInternal()\n"); if ((Usage && Usage != DIB_PAL_COLORS) || !Info || !hBitmap) return 0; - // if ScanLines == 0, no need to copy Bits. - if (!ScanLines) - ChkBits = NULL; - _SEH2_TRY { - ProbeForRead(&Info->bmiHeader.biSize, sizeof(DWORD), 1); - - ProbeForWrite(Info, Info->bmiHeader.biSize, 1); // Comp for Core. - if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1); + /* Probe for read and write */ + ProbeForRead(Info, MaxInfo, 1); + ProbeForWrite(Info, MaxInfo, 1); + if (Bits) ProbeForWrite(Bits, MaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -651,340 +610,397 @@ NtGdiGetDIBitsInternal( return 0; } - Dc = DC_LockDc(hDC); - if (Dc == NULL) return 0; - if (Dc->dctype == DC_TYPE_INFO) + colorPtr = (LPBYTE)Info + Info->bmiHeader.biSize; + rgbTriples = colorPtr; + rgbQuads = colorPtr; + + bitmap_type = DIB_GetBitmapInfo(&Info->bmiHeader, + &width, + &height, + &planes, + &bpp, + &compr, + &size); + if(bitmap_type == -1) + { + DPRINT("Wrong bitmap format\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } + else if(bitmap_type == 0) + { + /* We need a BITMAPINFO to create a DIB, but we have to fill + * the BITMAPCOREINFO we're provided */ + pbmci = (BITMAPCOREINFO*)Info; + Info = DIB_ConvertBitmapInfo((BITMAPINFO*)pbmci, Usage); + if(Info == NULL) + { + DPRINT1("Error, could not convert the BITMAPCOREINFO!\n"); + return 0; + } + rgbQuads = Info->bmiColors; + } + + pDC = DC_LockDc(hDC); + if (pDC == NULL || pDC->dctype == DC_TYPE_INFO) { - DC_UnlockDc(Dc); - return 0; + ScanLines = 0; + goto done; } - DC_UnlockDc(Dc); /* Get a pointer to the source bitmap object */ psurf = SURFACE_LockSurface(hBitmap); if (psurf == NULL) - return 0; - - hSourcePalette = psurf->hDIBPalette; - if (!hSourcePalette) { - hSourcePalette = pPrimarySurface->devinfo.hpalDefault; + ScanLines = 0; + goto done; } - ColorPtr = ((PBYTE)Info + Info->bmiHeader.biSize); - rgbQuads = (RGBQUAD *)ColorPtr; + /* Fill in the structure */ + switch(bpp) + { + case 0: /* Only info */ + if(pbmci) + { + pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx; + pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ? + -psurf->SurfObj.sizlBitmap.cy : + psurf->SurfObj.sizlBitmap.cy; + pbmci->bmciHeader.bcPlanes = 1; + pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat); + } + Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx; + Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ? + -psurf->SurfObj.sizlBitmap.cy : + psurf->SurfObj.sizlBitmap.cy;; + Info->bmiHeader.biPlanes = 1; + Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat); + Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( Info->bmiHeader.biWidth, + Info->bmiHeader.biHeight, + Info->bmiHeader.biBitCount); + if(psurf->hSecure) + { + switch(Info->bmiHeader.biBitCount) + { + case 16: + case 32: + Info->bmiHeader.biCompression = BI_BITFIELDS; + break; + default: + Info->bmiHeader.biCompression = BI_RGB; + break; + } + } + else if(Info->bmiHeader.biBitCount > 8) + { + Info->bmiHeader.biCompression = BI_BITFIELDS; + } + else + { + Info->bmiHeader.biCompression = BI_RGB; + } + Info->bmiHeader.biXPelsPerMeter = 0; + Info->bmiHeader.biYPelsPerMeter = 0; + Info->bmiHeader.biClrUsed = 0; + Info->bmiHeader.biClrImportant = 0; + ScanLines = abs(Info->bmiHeader.biHeight); + goto done; - /* Copy palette information - * Always create a palette for 15 & 16 bit. */ - if ((Info->bmiHeader.biBitCount == BitsPerFormat(psurf->SurfObj.iBitmapFormat) && - Info->bmiHeader.biBitCount != 15 && Info->bmiHeader.biBitCount != 16) || - !ChkBits) - { - hDestPalette = hSourcePalette; - bPaletteMatch = TRUE; - } - else - hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault; + case 1: + case 4: + case 8: + Info->bmiHeader.biClrUsed = 0; - ppalSrc = PALETTE_LockPalette(hSourcePalette); - /* FIXME - ppalSrc can be NULL!!! Don't assert here! */ - ASSERT(ppalSrc); + /* If the bitmap if a DIB section and has the same format than what + * we're asked, go ahead! */ + if((psurf->hSecure) && + (BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp)) + { + if(Usage == DIB_RGB_COLORS) + { + unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp); - if (!bPaletteMatch) - { - ppalDst = PALETTE_LockPalette(hDestPalette); - /* FIXME - ppalDst can be NULL!!!! Don't assert here!!! */ - DPRINT("ppalDst : %p\n", ppalDst); - ASSERT(ppalDst); - } - else - { - ppalDst = ppalSrc; - } + if(pbmci) + { + for(i=0; i < colors; i++) + { + rgbTriples[i].rgbtRed = psurf->ppal->IndexedColors[i].peRed; + rgbTriples[i].rgbtGreen = psurf->ppal->IndexedColors[i].peGreen; + rgbTriples[i].rgbtBlue = psurf->ppal->IndexedColors[i].peBlue; + } + } + if(colors != 1 << bpp) Info->bmiHeader.biClrUsed = colors; + for(i=0; i < colors; i++) + { + rgbQuads[i].rgbRed = psurf->ppal->IndexedColors[i].peRed; + rgbQuads[i].rgbGreen = psurf->ppal->IndexedColors[i].peGreen; + rgbQuads[i].rgbBlue = psurf->ppal->IndexedColors[i].peBlue; + } + } + else + { + for(i=0; i < 1 << bpp; i++) + { + if(pbmci) ((WORD*)rgbTriples)[i] = i; + ((WORD*)rgbQuads)[i] = i; + } + } + } + else + { + if(Usage == DIB_PAL_COLORS) + { + for(i=0; i < 1 << bpp; i++) + { + if(pbmci) ((WORD*)rgbTriples)[i] = i; + ((WORD*)rgbQuads)[i] = i; + } + } + else if(bpp > 1 && bpp == BitsPerFormat(psurf->SurfObj.iBitmapFormat)) { + /* For color DDBs in native depth (mono DDBs always have + a black/white palette): + Generate the color map from the selected palette */ + PPALETTE pDcPal = PALETTE_LockPalette(pDC->dclevel.hpal); + if(!pDcPal) + { + ScanLines = 0 ; + goto done ; + } + for (i = 0; i < pDcPal->NumColors; i++) { + if (pbmci) + { + rgbTriples[i].rgbtRed = pDcPal->IndexedColors[i].peRed; + rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen; + rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue; + } - /* Copy palette. */ - /* FIXME: This is largely incomplete. ATM no Core!*/ - switch (Info->bmiHeader.biBitCount) - { - case 1: - case 4: - case 8: - Info->bmiHeader.biClrUsed = 0; - if (psurf->hSecure && - BitsPerFormat(psurf->SurfObj.iBitmapFormat) == Info->bmiHeader.biBitCount) - { - if (Usage == DIB_RGB_COLORS) - { - if (ppalDst->NumColors != 1 << Info->bmiHeader.biBitCount) - Info->bmiHeader.biClrUsed = ppalDst->NumColors; - for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors; - Index++) + rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed; + rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen; + rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue; + rgbQuads[i].rgbReserved = 0; + } + PALETTE_UnlockPalette(pDcPal); + } else { + switch (bpp) { + case 1: + if (pbmci) { - rgbQuads[Index].rgbRed = ppalDst->IndexedColors[Index].peRed; - rgbQuads[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen; - rgbQuads[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue; - rgbQuads[Index].rgbReserved = 0; + rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen = + rgbTriples[0].rgbtBlue = 0; + rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen = + rgbTriples[1].rgbtBlue = 0xff; } - } - else - { - PWORD Ptr = ColorPtr; - for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount); - Index++) + rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = + rgbQuads[0].rgbBlue = 0; + rgbQuads[0].rgbReserved = 0; + rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = + rgbQuads[1].rgbBlue = 0xff; + rgbQuads[1].rgbReserved = 0; + break; + + case 4: + if (pbmci) + RtlCopyMemory(rgbTriples, EGAColorsTriples, sizeof(EGAColorsTriples)); + RtlCopyMemory(rgbQuads, EGAColorsQuads, sizeof(EGAColorsQuads)); + + break; + + case 8: { - Ptr[Index] = (WORD)Index; - } - } - } - else - { - if (Usage == DIB_PAL_COLORS) - { - PWORD Ptr = ColorPtr; - for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount); - Index++) - { - Ptr[Index] = (WORD)Index; - } - } - else if (Info->bmiHeader.biBitCount > 1 && bPaletteMatch) - { - for (Index = 0; - Index < (1 << Info->bmiHeader.biBitCount) && Index < ppalDst->NumColors; - Index++) - { - Info->bmiColors[Index].rgbRed = ppalDst->IndexedColors[Index].peRed; - Info->bmiColors[Index].rgbGreen = ppalDst->IndexedColors[Index].peGreen; - Info->bmiColors[Index].rgbBlue = ppalDst->IndexedColors[Index].peBlue; - Info->bmiColors[Index].rgbReserved = 0; - } - } - else - { - switch (Info->bmiHeader.biBitCount) - { - case 1: - rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen = rgbQuads[0].rgbBlue = 0; - rgbQuads[0].rgbReserved = 0; - rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen = rgbQuads[1].rgbBlue = 0xff; - rgbQuads[1].rgbReserved = 0; - break; - case 4: - RtlCopyMemory(ColorPtr, EGAColorsQuads, sizeof(EGAColorsQuads)); - break; - case 8: + INT r, g, b; + RGBQUAD *color; + if (pbmci) { - INT r, g, b; - RGBQUAD *color; + RGBTRIPLE *colorTriple; - RtlCopyMemory(rgbQuads, DefLogPaletteQuads, 10 * sizeof(RGBQUAD)); - RtlCopyMemory(rgbQuads + 246, DefLogPaletteQuads + 10, 10 * sizeof(RGBQUAD)); - color = rgbQuads + 10; - for (r = 0; r <= 5; r++) /* FIXME */ - for (g = 0; g <= 5; g++) - for (b = 0; b <= 5; b++) - { - color->rgbRed = (r * 0xff) / 5; - color->rgbGreen = (g * 0xff) / 5; - color->rgbBlue = (b * 0xff) / 5; - color->rgbReserved = 0; + RtlCopyMemory(rgbTriples, DefLogPaletteTriples, + 10 * sizeof(RGBTRIPLE)); + RtlCopyMemory(rgbTriples + 246, DefLogPaletteTriples + 10, + 10 * sizeof(RGBTRIPLE)); + colorTriple = rgbTriples + 10; + for(r = 0; r <= 5; r++) /* FIXME */ + { + for(g = 0; g <= 5; g++) + { + for(b = 0; b <= 5; b++) + { + colorTriple->rgbtRed = (r * 0xff) / 5; + colorTriple->rgbtGreen = (g * 0xff) / 5; + colorTriple->rgbtBlue = (b * 0xff) / 5; color++; } + } + } } - break; + memcpy(rgbQuads, DefLogPaletteQuads, + 10 * sizeof(RGBQUAD)); + memcpy(rgbQuads + 246, DefLogPaletteQuads + 10, + 10 * sizeof(RGBQUAD)); + color = rgbQuads + 10; + for(r = 0; r <= 5; r++) /* FIXME */ + { + for(g = 0; g <= 5; g++) + { + for(b = 0; b <= 5; b++) + { + color->rgbRed = (r * 0xff) / 5; + color->rgbGreen = (g * 0xff) / 5; + color->rgbBlue = (b * 0xff) / 5; + color->rgbReserved = 0; + color++; + } + } + } } } } + } + break; - case 15: - if (Info->bmiHeader.biCompression == BI_BITFIELDS) - { - ((PDWORD)Info->bmiColors)[0] = 0x7c00; - ((PDWORD)Info->bmiColors)[1] = 0x03e0; - ((PDWORD)Info->bmiColors)[2] = 0x001f; - } - break; + case 15: + if (Info->bmiHeader.biCompression == BI_BITFIELDS) + { + ((PDWORD)Info->bmiColors)[0] = 0x7c00; + ((PDWORD)Info->bmiColors)[1] = 0x03e0; + ((PDWORD)Info->bmiColors)[2] = 0x001f; + } + break; - case 16: - if (Info->bmiHeader.biCompression == BI_BITFIELDS) + case 16: + if (Info->bmiHeader.biCompression == BI_BITFIELDS) + { + if (psurf->hSecure) + { + ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask; + ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask; + ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask; + } + else { ((PDWORD)Info->bmiColors)[0] = 0xf800; ((PDWORD)Info->bmiColors)[1] = 0x07e0; ((PDWORD)Info->bmiColors)[2] = 0x001f; } - break; + } + break; - case 24: - case 32: - if (Info->bmiHeader.biCompression == BI_BITFIELDS) + case 24: + case 32: + if (Info->bmiHeader.biCompression == BI_BITFIELDS) + { + if (psurf->hSecure) + { + ((PDWORD)Info->bmiColors)[0] = psurf->ppal->RedMask; + ((PDWORD)Info->bmiColors)[1] = psurf->ppal->GreenMask; + ((PDWORD)Info->bmiColors)[2] = psurf->ppal->BlueMask; + } + else { ((PDWORD)Info->bmiColors)[0] = 0xff0000; ((PDWORD)Info->bmiColors)[1] = 0x00ff00; ((PDWORD)Info->bmiColors)[2] = 0x0000ff; } - break; - } - - if (!bPaletteMatch) - PALETTE_UnlockPalette(ppalDst); - - /* fill out the BITMAPINFO struct */ - if (!ChkBits) - { // Core or not to Core? We have converted from Core in Gdi~ so? - if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) - { - BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info; - coreheader->bcWidth = psurf->SurfObj.sizlBitmap.cx; - coreheader->bcPlanes = 1; - coreheader->bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat); - coreheader->bcHeight = psurf->SurfObj.sizlBitmap.cy; - if (psurf->SurfObj.lDelta > 0) - coreheader->bcHeight = -coreheader->bcHeight; } - - if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) - { - Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx; - Info->bmiHeader.biHeight = psurf->SurfObj.sizlBitmap.cy; - Info->bmiHeader.biPlanes = 1; - Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat); - switch (psurf->SurfObj.iBitmapFormat) - { - /* FIXME: What about BI_BITFIELDS? */ - case BMF_1BPP: - case BMF_4BPP: - case BMF_8BPP: - case BMF_16BPP: - case BMF_24BPP: - case BMF_32BPP: - Info->bmiHeader.biCompression = BI_RGB; - break; - case BMF_4RLE: - Info->bmiHeader.biCompression = BI_RLE4; - break; - case BMF_8RLE: - Info->bmiHeader.biCompression = BI_RLE8; - break; - case BMF_JPEG: - Info->bmiHeader.biCompression = BI_JPEG; - break; - case BMF_PNG: - Info->bmiHeader.biCompression = BI_PNG; - break; - } - /* Image size has to be calculated */ - Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(Info->bmiHeader.biWidth, - Info->bmiHeader.biBitCount) * Info->bmiHeader.biHeight; - Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */ - Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */ - Info->bmiHeader.biClrUsed = 0; - Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */ - /* Report negtive height for top-down bitmaps. */ - if (psurf->SurfObj.lDelta > 0) - Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight; - } - Result = psurf->SurfObj.sizlBitmap.cy; + break; } - else - { - SIZEL DestSize; - POINTL SourcePoint; + Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp); -// -// If we have a good dib pointer, why not just copy bits from there w/o XLATE'ing them. -// - /* Create the destination bitmap too for the copy operation */ - if (StartScan > psurf->SurfObj.sizlBitmap.cy) + if(Bits && ScanLines) + { + /* Create a DIBSECTION, blt it, profit */ + PVOID pDIBits ; + HBITMAP hBmpDest; + PSURFACE psurfDest; + EXLATEOBJ exlo; + RECT rcDest; + POINTL srcPoint; + BOOL ret ; + + if (StartScan > psurf->SurfObj.sizlBitmap.cy) { - goto cleanup; + ScanLines = 0; + goto done; } else { ScanLines = min(ScanLines, psurf->SurfObj.sizlBitmap.cy - StartScan); - DestSize.cx = psurf->SurfObj.sizlBitmap.cx; - DestSize.cy = ScanLines; + } - hDestBitmap = NULL; + /* Fixup values */ + Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx; + Info->bmiHeader.biHeight = height < 0 ? + -ScanLines : ScanLines; + /* Create the DIB */ + hBmpDest = DIB_CreateDIBSection(pDC, Info, Usage, &pDIBits, NULL, 0, 0); + /* Restore them */ + Info->bmiHeader.biWidth = width; + Info->bmiHeader.biHeight = height; - if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) - { - BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info; - hDestBitmap = EngCreateBitmap(DestSize, - DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount), - BitmapFormat(coreheader->bcBitCount, BI_RGB), - 0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN, - Bits); - } + if(!hBmpDest) + { + DPRINT1("Unable to create a DIB Section!\n"); + SetLastWin32Error(ERROR_INVALID_PARAMETER); + ScanLines = 0; + goto done ; + } - if (Info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) - { - Info->bmiHeader.biSizeImage = DIB_GetDIBWidthBytes(DestSize.cx, - Info->bmiHeader.biBitCount) * DestSize.cy; + psurfDest = SURFACE_LockSurface(hBmpDest); - hDestBitmap = EngCreateBitmap(DestSize, - DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), - BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression), - 0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN, - Bits); - } + rcDest.left = 0; + rcDest.top = 0; + rcDest.bottom = ScanLines; + rcDest.right = psurf->SurfObj.sizlBitmap.cx; - if (hDestBitmap == NULL) - goto cleanup; - } + srcPoint.x = 0; + srcPoint.y = height < 0 ? + psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines) : StartScan; - if (NT_SUCCESS(Status)) - { - EXLATEOBJ exlo; - SURFOBJ *DestSurfObj; - RECTL DestRect; + EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0, 0, 0); - EXLATEOBJ_vInitialize(&exlo, ppalSrc, ppalDst, 0, 0, 0); + ret = IntEngCopyBits(&psurfDest->SurfObj, + &psurf->SurfObj, + NULL, + &exlo.xlo, + &rcDest, + &srcPoint); - SourcePoint.x = 0; - SourcePoint.y = psurf->SurfObj.sizlBitmap.cy - (StartScan + ScanLines); + if(!ret) + ScanLines = 0; + else + { + Status = STATUS_SUCCESS; + _SEH2_TRY + { + RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END - /* Determine destination rectangle */ - DestRect.top = 0; - DestRect.left = 0; - DestRect.right = DestSize.cx; - DestRect.bottom = DestSize.cy; + if(!NT_SUCCESS(Status)) + { + DPRINT1("Unable to copy bits to the user provided pointer\n"); + ScanLines = 0; + } + } - DestSurfObj = EngLockSurface((HSURF)hDestBitmap); + GreDeleteObject(hBmpDest); + EXLATEOBJ_vCleanup(&exlo); + } + else ScanLines = abs(height); - if (IntEngCopyBits(DestSurfObj, - &psurf->SurfObj, - NULL, - &exlo.xlo, - &DestRect, - &SourcePoint)) - { - DPRINT("GetDIBits %d \n",abs(Info->bmiHeader.biHeight) - StartScan); - Result = ScanLines; - } +done: - EXLATEOBJ_vCleanup(&exlo); - EngUnlockSurface(DestSurfObj); - } - } -cleanup: - PALETTE_UnlockPalette(ppalSrc); + if(pDC) DC_UnlockDc(pDC); + if(psurf) SURFACE_UnlockSurface(psurf); + if(pbmci) DIB_FreeConvertedBitmapInfo(Info, (BITMAPINFO*)pbmci); - if (hDestBitmap != NULL) - EngDeleteSurface((HSURF)hDestBitmap); - - if (hDestPalette != NULL && bPaletteMatch == FALSE) - PALETTE_FreePaletteByHandle(hDestPalette); - - SURFACE_UnlockSurface(psurf); - - DPRINT("leaving NtGdiGetDIBitsInternal\n"); - - return Result; + return ScanLines; } + INT APIENTRY NtGdiStretchDIBitsInternal( @@ -1005,113 +1021,121 @@ NtGdiStretchDIBitsInternal( UINT cjMaxBits, HANDLE hcmXform) { - HBITMAP hBitmap, hOldBitmap = NULL; - HDC hdcMem; - HPALETTE hPal = NULL; - PDC pDC; - BOOL Hit = FALSE; + PDC pdc; + INT ret = 0; + LONG height; + LONG width; + WORD planes, bpp; + DWORD compr, size; + HBITMAP hBitmap; + BOOL fastpath = FALSE; + NTSTATUS Status = STATUS_SUCCESS; + PBYTE safeBits ; if (!Bits || !BitsInfo) - { - SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; - } + + safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB); + if(!safeBits) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + if (!(pdc = DC_LockDc(hDC))) + { + ExFreePoolWithTag(safeBits, TAG_DIB); + SetLastWin32Error(ERROR_INVALID_HANDLE); + return 0; + } _SEH2_TRY { ProbeForRead(BitsInfo, cjMaxInfo, 1); ProbeForRead(Bits, cjMaxBits, 1); + if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1) + { + DPRINT1("Invalid bitmap\n"); + Status = STATUS_INVALID_PARAMETER; + } + RtlCopyMemory(safeBits, Bits, cjMaxBits); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Hit = TRUE; + Status = _SEH2_GetExceptionCode(); } _SEH2_END - if (Hit) + if(!NT_SUCCESS(Status)) { - DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits); + DPRINT1("Error, failed to read the DIB bits\n"); + goto cleanup; + } + + if (width < 0) + { + DPRINT1("Bitmap has a negative width\n"); return 0; } - hdcMem = NtGdiCreateCompatibleDC(hDC); - if (hdcMem == NULL) + hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP); + + if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 && + DestWidth == SrcWidth && DestHeight == SrcHeight && + compr == BI_RGB && + ROP == SRCCOPY) { - DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n"); - return 0; + BITMAP bmp; + if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp)) + { + if (bmp.bmBitsPixel == bpp && + bmp.bmWidth == SrcWidth && + bmp.bmHeight == SrcHeight && + bmp.bmPlanes == planes) + fastpath = TRUE; + } } - hBitmap = NtGdiCreateCompatibleBitmap(hDC, - abs(BitsInfo->bmiHeader.biWidth), - abs(BitsInfo->bmiHeader.biHeight)); - if (hBitmap == NULL) + if (fastpath) { - DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n"); - DPRINT1("hDC : 0x%08x \n", hDC); - DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth); - DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight); - return 0; + /* fast path */ + DPRINT1("using fast path\n"); + ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage); } - - /* Select the bitmap into hdcMem, and save a handle to the old bitmap */ - hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap); - - if (Usage == DIB_PAL_COLORS) - { - hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE); - hPal = GdiSelectPalette(hdcMem, hPal, FALSE); - } - - if (BitsInfo->bmiHeader.biCompression == BI_RLE4 || - BitsInfo->bmiHeader.biCompression == BI_RLE8) - { - /* copy existing bitmap from destination dc */ - if (SrcWidth == DestWidth && SrcHeight == DestHeight) - NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, - SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0); - else - NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, - SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight, - ROP, 0); - } - - pDC = DC_LockDc(hdcMem); - if (pDC != NULL) - { - /* Note BitsInfo->bmiHeader.biHeight is the number of scanline, - * if it negitve we getting to many scanline for scanline is UINT not - * a INT, so we need make the negtive value to positve and that make the - * count correct for negtive bitmap, TODO : we need testcase for this api */ - IntSetDIBits(pDC, hBitmap, 0, abs(BitsInfo->bmiHeader.biHeight), Bits, - BitsInfo, Usage); - - DC_UnlockDc(pDC); - } - - - /* Origin for DIBitmap may be bottom left (positive biHeight) or top - left (negative biHeight) */ - if (SrcWidth == DestWidth && SrcHeight == DestHeight) - NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, - ROP, 0, 0); else - NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, - SrcWidth, SrcHeight, ROP, 0); + { + /* slow path - need to use StretchBlt */ + HBITMAP hOldBitmap; + HDC hdcMem; + PVOID pvBits; - /* cleanup */ - if (hPal) - GdiSelectPalette(hdcMem, hPal, FALSE); + hdcMem = NtGdiCreateCompatibleDC( hDC ); + hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0); + if(!hBitmap) + { + DPRINT1("Error, failed to create a DIB section\n"); + NtGdiDeleteObjectApp(hdcMem); + goto cleanup; + } + RtlCopyMemory(pvBits, safeBits, cjMaxBits); + hOldBitmap = NtGdiSelectBitmap( hdcMem, hBitmap ); - if (hOldBitmap) - NtGdiSelectBitmap(hdcMem, hOldBitmap); - - NtGdiDeleteObjectApp(hdcMem); - - GreDeleteObject(hBitmap); - - return SrcHeight; + /* Origin for DIBitmap may be bottom left (positive biHeight) or top + left (negative biHeight) */ + ret = NtGdiStretchBlt( hDC, XDest, YDest, DestWidth, DestHeight, + hdcMem, XSrc, abs(height) - SrcHeight - YSrc, + SrcWidth, SrcHeight, ROP, 0 ); + + if(ret) + ret = SrcHeight; + NtGdiSelectBitmap( hdcMem, hOldBitmap ); + NtGdiDeleteObjectApp( hdcMem ); + GreDeleteObject( hBitmap ); + } +cleanup: + ExFreePoolWithTag(safeBits, TAG_DIB); + DC_UnlockDc(pdc); + return ret; } @@ -1137,40 +1161,19 @@ IntCreateDIBitmap( else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE; else { - if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) - { - const RGBQUAD *rgb = data->bmiColors; - DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); + const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize); + DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); - // Check if the first color of the colormap is black - if ((col == RGB(0, 0, 0))) - { - rgb++; - col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); - - // If the second color is white, create a monochrome bitmap - fColor = (col != RGB(0xff,0xff,0xff)); - } - else fColor = TRUE; - } - else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + // Check if the first color of the colormap is black + if ((col == RGB(0, 0, 0))) { - RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors; - DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue); + rgb++; + col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); - if ((col == RGB(0,0,0))) - { - rgb++; - col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue); - fColor = (col != RGB(0xff,0xff,0xff)); - } - else fColor = TRUE; - } - else - { - DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize); - return 0; + // If the second color is white, create a monochrome bitmap + fColor = (col != RGB(0xff,0xff,0xff)); } + else fColor = TRUE; } // Now create the bitmap @@ -1180,11 +1183,11 @@ IntCreateDIBitmap( } else { - handle = IntGdiCreateBitmap(width, - height, - 1, - 1, - NULL); + handle = GreCreateBitmap(width, + height, + 1, + 1, + NULL); } if (height < 0) @@ -1214,72 +1217,106 @@ NtGdiCreateDIBitmapInternal( IN UINT cjMaxBits, IN FLONG fl, IN HANDLE hcmXform) +{ + NTSTATUS Status = STATUS_SUCCESS; + PBYTE safeBits = NULL; + HBITMAP hbmResult = NULL; + + if(pjInit && (fInit == CBM_INIT)) + { + safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB); + if(!safeBits) + { + SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } + } + + _SEH2_TRY + { + if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1); + if(pjInit && (fInit == CBM_INIT)) + { + ProbeForRead(pjInit, cjMaxBits, 1); + RtlCopyMemory(safeBits, pjInit, cjMaxBits); + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + goto cleanup; + } + + hbmResult = GreCreateDIBitmapInternal(hDc, + cx, + cy, + fInit, + safeBits, + pbmi, + iUsage, + fl, + hcmXform); + +cleanup: + if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB); + return hbmResult; +} + +HBITMAP +FASTCALL +GreCreateDIBitmapInternal( + IN HDC hDc, + IN INT cx, + IN INT cy, + IN DWORD fInit, + IN OPTIONAL LPBYTE pjInit, + IN OPTIONAL PBITMAPINFO pbmi, + IN DWORD iUsage, + IN FLONG fl, + IN HANDLE hcmXform) { PDC Dc; HBITMAP Bmp; - UINT bpp; + WORD bpp; + HDC hdcDest; - if (!hDc) // CreateBitmap + if (!hDc) /* 1bpp monochrome bitmap */ { // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this. - hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE); - if (!hDc) + hdcDest = NtGdiCreateCompatibleDC(0); + if(!hdcDest) { - SetLastWin32Error(ERROR_INVALID_HANDLE); return NULL; } - - Dc = DC_LockDc(hDc); - if (!Dc) - { - NtGdiDeleteObjectApp(hDc); - SetLastWin32Error(ERROR_INVALID_HANDLE); - return NULL; - } - bpp = 1; - Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); - - DC_UnlockDc(Dc); - NtGdiDeleteObjectApp(hDc); } - else // CreateCompatibleBitmap + else { - Dc = DC_LockDc(hDc); - if (!Dc) - { - SetLastWin32Error(ERROR_INVALID_HANDLE); - return NULL; - } - /* pbmi == null - First create an un-initialised bitmap. The depth of the bitmap - should match that of the hdc and not that supplied in bmih. - */ - if (pbmi) - bpp = pbmi->bmiHeader.biBitCount; - else - { - if (Dc->dctype != DC_TYPE_MEMORY) - bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL); - else - { - DIBSECTION dibs; - INT Count; - SURFACE *psurf = Dc->dclevel.pSurface; - Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs); - if (!Count) - bpp = 1; - else - { - if (Count == sizeof(BITMAP)) - /* A device-dependent bitmap is selected in the DC */ - bpp = dibs.dsBm.bmBitsPixel; - else - /* A DIB section is selected in the DC */ - bpp = dibs.dsBmih.biBitCount; - } - } - } - Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); - DC_UnlockDc(Dc); + hdcDest = hDc; + } + + Dc = DC_LockDc(hdcDest); + if (!Dc) + { + SetLastWin32Error(ERROR_INVALID_HANDLE); + return NULL; + } + /* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap + * if bpp != 1 and ignore the real value that was passed */ + if (pbmi) + bpp = pbmi->bmiHeader.biBitCount; + else + bpp = 0; + Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); + DC_UnlockDc(Dc); + + if(!hDc) + { + NtGdiDeleteObjectApp(hdcDest); } return Bmp; } @@ -1291,7 +1328,7 @@ NtGdiCreateDIBSection( IN HDC hDC, IN OPTIONAL HANDLE hSection, IN DWORD dwOffset, - IN LPBITMAPINFO bmi, + IN BITMAPINFO* bmi, IN DWORD Usage, IN UINT cjHeader, IN FLONG fl, @@ -1301,9 +1338,28 @@ NtGdiCreateDIBSection( HBITMAP hbitmap = 0; DC *dc; BOOL bDesktopDC = FALSE; + NTSTATUS Status = STATUS_SUCCESS; if (!bmi) return hbitmap; // Make sure. + _SEH2_TRY + { + ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1); + ProbeForRead(bmi, bmi->bmiHeader.biSize, 1); + ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, Usage), 1); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return NULL; + } + // If the reference hdc is null, take the desktop dc if (hDC == 0) { @@ -1314,7 +1370,7 @@ NtGdiCreateDIBSection( if ((dc = DC_LockDc(hDC))) { hbitmap = DIB_CreateDIBSection(dc, - (BITMAPINFO*)bmi, + bmi, Usage, Bits, hSection, @@ -1337,7 +1393,7 @@ HBITMAP APIENTRY DIB_CreateDIBSection( PDC dc, - BITMAPINFO *bmi, + CONST BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, @@ -1347,17 +1403,15 @@ DIB_CreateDIBSection( HBITMAP res = 0; SURFACE *bmp = NULL; void *mapBits = NULL; + HPALETTE hpal ; // Fill BITMAP32 structure with DIB data - BITMAPINFOHEADER *bi = &bmi->bmiHeader; + CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader; INT effHeight; ULONG totalSize; BITMAP bm; SIZEL Size; - RGBQUAD *lpRGB; HANDLE hSecure; - DWORD dsBitfields[3] = {0}; - ULONG ColorCount; DPRINT("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n", bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, @@ -1373,7 +1427,7 @@ DIB_CreateDIBSection( bm.bmType = 0; bm.bmWidth = bi->biWidth; bm.bmHeight = effHeight; - bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount); + bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount); bm.bmPlanes = bi->biPlanes; bm.bmBitsPixel = bi->biBitCount; @@ -1431,6 +1485,7 @@ DIB_CreateDIBSection( { offset = 0; bm.bmBits = EngAllocUserMem(totalSize, 0); + if(!bm.bmBits) goto cleanup; } // hSecure = MmSecureVirtualMemory(bm.bmBits, totalSize, PAGE_READWRITE); @@ -1438,116 +1493,76 @@ DIB_CreateDIBSection( if (usage == DIB_PAL_COLORS) { - lpRGB = DIB_MapPaletteColors(dc, bmi); - ColorCount = bi->biClrUsed; - if (ColorCount == 0) - { - ColorCount = 1 << bi->biBitCount; - } + if(dc) + { + PPALETTE pdcPal ; + pdcPal = PALETTE_LockPalette(dc->dclevel.hpal); + hpal = DIB_MapPaletteColors(pdcPal, bmi); + PALETTE_UnlockPalette(pdcPal); + } + else + { + /* For DIB Brushes */ + DPRINT1("FIXME : Unsupported DIB_PAL_COLORS without a DC to map colors.\n"); + /* HACK */ + hpal = (HPALETTE) 0xFFFFFFFF; + } } else - { - lpRGB = bmi->bmiColors; - ColorCount = 1 << bi->biBitCount; - } + { + hpal = BuildDIBPalette(bmi); + } - /* Set dsBitfields values */ - if (usage == DIB_PAL_COLORS || bi->biBitCount <= 8) - { - dsBitfields[0] = dsBitfields[1] = dsBitfields[2] = 0; - } - else if (bi->biCompression == BI_RGB) - { - switch (bi->biBitCount) - { - case 15: - case 16: - dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0x7c00; - dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x03e0; - dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x001f; - break; - - case 24: - case 32: - dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)lpRGB : 0xff0000; - dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 1) : 0x00ff00; - dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)lpRGB + 2) : 0x0000ff; - break; - } - } - else - { - dsBitfields[0] = ((DWORD*)bmi->bmiColors)[0]; - dsBitfields[1] = ((DWORD*)bmi->bmiColors)[1]; - dsBitfields[2] = ((DWORD*)bmi->bmiColors)[2]; - } + if(!hpal) + { + DPRINT1("Error : Could not create a palette for the DIB.\n"); + goto cleanup; + } // Create Device Dependent Bitmap and add DIB pointer Size.cx = bm.bmWidth; Size.cy = abs(bm.bmHeight); - res = IntCreateBitmap(Size, - bm.bmWidthBytes, - BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression), - BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT | - (bi->biHeight < 0 ? BMF_TOPDOWN : 0), - bm.bmBits); + res = GreCreateBitmapEx(bm.bmWidth, + abs(bm.bmHeight), + bm.bmWidthBytes, + BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression), + BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT | + (bi->biHeight < 0 ? BMF_TOPDOWN : 0), + bi->biSizeImage, + bm.bmBits, + 0); if (!res) { - if (lpRGB != bmi->bmiColors) - { - ExFreePoolWithTag(lpRGB, TAG_COLORMAP); - } SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES); - return NULL; + goto cleanup; } bmp = SURFACE_LockSurface(res); if (NULL == bmp) { - if (lpRGB != bmi->bmiColors) - { - ExFreePoolWithTag(lpRGB, TAG_COLORMAP); - } - SetLastWin32Error(ERROR_INVALID_HANDLE); - GreDeleteObject(bmp); - return NULL; + SetLastWin32Error(ERROR_INVALID_HANDLE); + goto cleanup; } /* WINE NOTE: WINE makes use of a colormap, which is a color translation table between the DIB and the X physical device. Obviously, this is left out of the ReactOS implementation. Instead, we call NtGdiSetDIBColorTable. */ - if (bi->biBitCount <= 8) - { - bi->biClrUsed = 1 << bi->biBitCount; - } - else - { - bi->biClrUsed = 0; - } - bmp->hDIBSection = section; bmp->hSecure = hSecure; bmp->dwOffset = offset; - bmp->flFlags = BITMAPOBJ_IS_APIBITMAP; - bmp->dsBitfields[0] = dsBitfields[0]; - bmp->dsBitfields[1] = dsBitfields[1]; - bmp->dsBitfields[2] = dsBitfields[2]; - bmp->biClrUsed = bi->biClrUsed; + bmp->flags = API_BITMAP; bmp->biClrImportant = bi->biClrImportant; - if (bi->biClrUsed != 0) - { - bmp->hDIBPalette = PALETTE_AllocPaletteIndexedRGB(ColorCount, lpRGB); - } - else - { - bmp->hDIBPalette = PALETTE_AllocPalette(PAL_BITFIELDS, 0, NULL, - dsBitfields[0], - dsBitfields[1], - dsBitfields[2]); - } + /* HACK */ + if(hpal != (HPALETTE)0xFFFFFFFF) + { + bmp->ppal = PALETTE_ShareLockPalette(hpal); + /* Lazy delete hpal, it will be freed at surface release */ + GreDeleteObject(hpal); + } // Clean up in case of errors +cleanup: if (!res || !bmp || !bm.bmBits) { DPRINT("got an error res=%08x, bmp=%p, bm.bmBits=%p\n", res, bmp, bm.bmBits); @@ -1574,11 +1589,6 @@ DIB_CreateDIBSection( } } - if (lpRGB != bmi->bmiColors) - { - ExFreePoolWithTag(lpRGB, TAG_COLORMAP); - } - if (bmp) { SURFACE_UnlockSurface(bmp); @@ -1594,15 +1604,39 @@ DIB_CreateDIBSection( } /*********************************************************************** - * DIB_GetDIBWidthBytes + * DIB_GetBitmapInfo * - * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned. - * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm - * 11/16/1999 (RJJ) lifted from wine + * Get the info from a bitmap header. + * Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error. */ -INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth) +int +FASTCALL +DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, + LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ) { - return ((width * depth + 31) & ~31) >> 3; + if (header->biSize == sizeof(BITMAPCOREHEADER)) + { + const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header; + *width = core->bcWidth; + *height = core->bcHeight; + *planes = core->bcPlanes; + *bpp = core->bcBitCount; + *compr = BI_RGB; + *size = 0; + return 0; + } + if (header->biSize >= sizeof(BITMAPINFOHEADER)) /* assume BITMAPINFOHEADER */ + { + *width = header->biWidth; + *height = header->biHeight; + *planes = header->biPlanes; + *bpp = header->biBitCount; + *compr = header->biCompression; + *size = header->biSizeImage; + return 1; + } + DPRINT1("(%d): unknown/wrong size for header\n", header->biSize ); + return -1; } /*********************************************************************** @@ -1614,7 +1648,7 @@ INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth) INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth) { - return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height); + return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height); } /*********************************************************************** @@ -1626,90 +1660,93 @@ INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth) INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse) { - int colors; + unsigned int colors, size, masks = 0; if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { - BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)info; + const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info; colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0; - return sizeof(BITMAPCOREHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD)); + return sizeof(BITMAPCOREHEADER) + colors * + ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD)); } else /* assume BITMAPINFOHEADER */ { colors = info->bmiHeader.biClrUsed; - if (!colors && (info->bmiHeader.biBitCount <= 8)) colors = 1 << info->bmiHeader.biBitCount; - return sizeof(BITMAPINFOHEADER) + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD)); + if (colors > 256) colors = 256; + if (!colors && (info->bmiHeader.biBitCount <= 8)) + colors = 1 << info->bmiHeader.biBitCount; + if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3; + size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) ); + return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD)); } } -RGBQUAD * +HPALETTE FASTCALL -DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi) +DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi) { - RGBQUAD *lpRGB; + PALETTEENTRY* ppalEntries; ULONG nNumColors,i; USHORT *lpIndex; - PPALETTE palGDI; + HPALETTE hpal; - palGDI = PALETTE_LockPalette(dc->dclevel.hpal); - - if (NULL == palGDI) + if (!(ppal->flFlags & PAL_INDEXED)) { return NULL; } - if (palGDI->Mode != PAL_INDEXED) - { - PALETTE_UnlockPalette(palGDI); - return NULL; - } - nNumColors = 1 << lpbmi->bmiHeader.biBitCount; if (lpbmi->bmiHeader.biClrUsed) { nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed); } - lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP); - if (lpRGB == NULL) + /* Don't have more colors than we need */ + nNumColors = min(ppal->NumColors, nNumColors); + + ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP); + if (ppalEntries == NULL) { - PALETTE_UnlockPalette(palGDI); + DPRINT1("Could not allocate palette entries\n"); return NULL; } - lpIndex = (USHORT *)&lpbmi->bmiColors[0]; + lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize); for (i = 0; i < nNumColors; i++) { - if (*lpIndex < palGDI->NumColors) + if (*lpIndex < ppal->NumColors) { - lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed; - lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen; - lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue; + ppalEntries[i] = ppal->IndexedColors[*lpIndex]; } else { - lpRGB[i].rgbRed = 0; - lpRGB[i].rgbGreen = 0; - lpRGB[i].rgbBlue = 0; + ppalEntries[i].peRed = 0; + ppalEntries[i].peGreen = 0; + ppalEntries[i].peBlue = 0; + ppalEntries[i].peFlags = 0; } - lpRGB[i].rgbReserved = 0; + lpIndex++; } - PALETTE_UnlockPalette(palGDI); - return lpRGB; + hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0); + + ExFreePoolWithTag(ppalEntries, TAG_COLORMAP); + + return hpal; } HPALETTE FASTCALL -BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType) +BuildDIBPalette(CONST BITMAPINFO *bmi) { BYTE bits; ULONG ColorCount; - PALETTEENTRY *palEntries = NULL; HPALETTE hPal; - ULONG RedMask, GreenMask, BlueMask; + ULONG RedMask = 0, GreenMask = 0, BlueMask = 0; + PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize); + INT paletteType; // Determine Bits Per Pixel bits = bmi->bmiHeader.biBitCount; @@ -1717,29 +1754,43 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType) // Determine paletteType from Bits Per Pixel if (bits <= 8) { - *paletteType = PAL_INDEXED; + paletteType = PAL_INDEXED; RedMask = GreenMask = BlueMask = 0; } else if (bmi->bmiHeader.biCompression == BI_BITFIELDS) { - *paletteType = PAL_BITFIELDS; - RedMask = ((ULONG *)bmi->bmiColors)[0]; - GreenMask = ((ULONG *)bmi->bmiColors)[1]; - BlueMask = ((ULONG *)bmi->bmiColors)[2]; - } - else if (bits < 24) - { - *paletteType = PAL_BITFIELDS; - RedMask = 0x7c00; - GreenMask = 0x03e0; - BlueMask = 0x001f; + paletteType = PAL_BITFIELDS; + RedMask = pdwColors[0]; + GreenMask = pdwColors[1]; + BlueMask = pdwColors[2]; } else { - *paletteType = PAL_BGR; - RedMask = 0xff0000; - GreenMask = 0x00ff00; - BlueMask = 0x0000ff; + paletteType = PAL_BITFIELDS; + switch (bits) + { + case 15: + paletteType |= PAL_RGB16_555; + RedMask = 0x7C00; + GreenMask = 0x03E0; + BlueMask = 0x001F; + break; + + case 16: + paletteType |= PAL_RGB16_565; + RedMask = 0xF800; + GreenMask = 0x07E0; + BlueMask = 0x001F; + break; + + case 24: + case 32: + paletteType |= PAL_BGR; + RedMask = 0xFF0000; + GreenMask = 0x00FF00; + BlueMask = 0x0000FF; + break; + } } if (bmi->bmiHeader.biClrUsed == 0) @@ -1751,18 +1802,96 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType) ColorCount = bmi->bmiHeader.biClrUsed; } - if (PAL_INDEXED == *paletteType) + if (PAL_INDEXED == paletteType) { - hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors); + hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors); } else { - hPal = PALETTE_AllocPalette(*paletteType, ColorCount, - (ULONG*) palEntries, + hPal = PALETTE_AllocPalette(paletteType, 0, + NULL, RedMask, GreenMask, BlueMask); } return hPal; } +/* Converts a BITMAPCOREINFO to a BITMAPINFO structure, + * or does nothing if it's already a BITMAPINFO (or V4 or V5) */ +BITMAPINFO* +FASTCALL +DIB_ConvertBitmapInfo (CONST BITMAPINFO* pbmi, DWORD Usage) +{ + CONST BITMAPCOREINFO* pbmci = (BITMAPCOREINFO*)pbmi; + BITMAPINFO* pNewBmi ; + UINT numColors = 0, ColorsSize = 0; + + if(pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) return (BITMAPINFO*)pbmi; + if(pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) return NULL; + + if(pbmci->bmciHeader.bcBitCount <= 8) + { + numColors = 1 << pbmci->bmciHeader.bcBitCount; + if(Usage == DIB_PAL_COLORS) + { + ColorsSize = numColors * sizeof(WORD); + } + else + { + ColorsSize = numColors * sizeof(RGBQUAD); + } + } + else if (Usage == DIB_PAL_COLORS) + { + /* Invalid at high Res */ + return NULL; + } + + pNewBmi = ExAllocatePoolWithTag(PagedPool, sizeof(BITMAPINFOHEADER) + ColorsSize, TAG_DIB); + if(!pNewBmi) return NULL; + + RtlZeroMemory(pNewBmi, sizeof(BITMAPINFOHEADER) + ColorsSize); + + pNewBmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pNewBmi->bmiHeader.biBitCount = pbmci->bmciHeader.bcBitCount; + pNewBmi->bmiHeader.biWidth = pbmci->bmciHeader.bcWidth; + pNewBmi->bmiHeader.biHeight = pbmci->bmciHeader.bcHeight; + pNewBmi->bmiHeader.biPlanes = pbmci->bmciHeader.bcPlanes; + pNewBmi->bmiHeader.biCompression = BI_RGB ; + pNewBmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(pNewBmi->bmiHeader.biWidth, + pNewBmi->bmiHeader.biHeight, + pNewBmi->bmiHeader.biBitCount); + + if(Usage == DIB_PAL_COLORS) + { + RtlCopyMemory(pNewBmi->bmiColors, pbmci->bmciColors, ColorsSize); + } + else + { + UINT i; + for(i=0; ibmiColors[i].rgbRed = pbmci->bmciColors[i].rgbtRed; + pNewBmi->bmiColors[i].rgbGreen = pbmci->bmciColors[i].rgbtGreen; + pNewBmi->bmiColors[i].rgbBlue = pbmci->bmciColors[i].rgbtBlue; + } + } + + return pNewBmi ; +} + +/* Frees a BITMAPINFO created with DIB_ConvertBitmapInfo */ +VOID +FASTCALL +DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig) +{ + if(converted != orig) + ExFreePoolWithTag(converted, TAG_DIB); +} + + + + + + /* EOF */ diff --git a/subsystems/win32/win32k/objects/drawing.c b/subsystems/win32/win32k/objects/drawing.c index 0cc9a23200d..adc6e9ccf29 100755 --- a/subsystems/win32/win32k/objects/drawing.c +++ b/subsystems/win32/win32k/objects/drawing.c @@ -64,14 +64,14 @@ typedef struct _Rect } Rect, *PRect; int FASTCALL IntFillRect(DC *dc, INT XLeft, INT YLeft, INT Width, INT Height, PBRUSH pbrush, BOOL Pen); -int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen); +//int FASTCALL app_fill_rect(DC *dc, Rect r, PBRUSH pbrush, BOOL Pen); static POINT INTERNAL_CALL app_new_point(int x, int y) { - POINT p; + POINT p; p.x = x; p.y = y; return p; @@ -332,7 +332,7 @@ app_draw_ellipse(DC *g, Rect r, PBRUSH pbrush) * * The draw_arc algorithm is based on draw_ellipse, but unlike * that algorithm is not symmetric in the general case, since - * an angular portion is clipped from the shape. + * an angular portion is clipped from the shape. * This clipping is performed by keeping track of two hypothetical * lines joining the centre point to the enclosing rectangle, * at the angles start_angle and end_angle, using a line-intersection @@ -376,7 +376,7 @@ app_fill_arc_rect(DC *g, rise2 = p2.y - p0.y; run2 = p2.x - p0.x; - if (r.y <= p0.y) // + if (r.y <= p0.y) // { /* in top half of arc ellipse */ @@ -599,7 +599,7 @@ app_fill_arc_rect(DC *g, * between an outer and inner ellipse, and also the draw_arc and * fill_arc operations which additionally clip drawing between * a start_angle and an end_angle. - * + * */ static int @@ -912,7 +912,7 @@ app_fill_arc(DC *g, Rect r, int start_angle, int end_angle, PBRUSH pbrush, BOOL r1.height = r1.y+r1.height-r2.y; r1.y = r2.y; while (r1.height > 0) { - result &= app_fill_arc_rect(g, + result &= app_fill_arc_rect(g, rect(r1.x, r1.y, r1.width, 1), p0, p1, p2, start_angle, end_angle, pbrush, FALSE); r1.y += 1; @@ -1273,7 +1273,7 @@ IntFillArc( PDC dc, pdcattr = dc->pdcattr; pbrush = BRUSH_LockBrush(pdcattr->hbrush); - if (!pbrush) + if (!pbrush) { DPRINT1("FillArc Fail\n"); SetLastWin32Error(ERROR_INTERNAL_ERROR); @@ -1285,7 +1285,7 @@ IntFillArc( PDC dc, (dc->dclevel.flPath & DCPATH_CLOCKWISE) ? -Start : -End, pbrush, Chord); - BRUSH_UnlockBrush(pbrush); + BRUSH_UnlockBrush(pbrush); return ret; } @@ -1329,7 +1329,7 @@ IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, - INT Height, + INT Height, PBRUSH pbrush) { return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), pbrush); @@ -1343,7 +1343,7 @@ IntFillRoundRect( PDC dc, INT Right, INT Bottom, INT Wellipse, - INT Hellipse, + INT Hellipse, PBRUSH pbrush) { Rect r; @@ -1385,7 +1385,7 @@ IntFillRoundRect( PDC dc, 270, 360, pbrush,FALSE); app_fill_arc(dc, rect(r.x+r.width-rx-rx, r.y, rx+rx, ry+ry), - 0, 90, pbrush,FALSE); + 0, 90, pbrush,FALSE); } if (Wellipse < r.width) { @@ -1419,7 +1419,7 @@ IntDrawRoundRect( PDC dc, r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top)); rx = Wellipse/2; ry = Hellipse/2; - + if (Wellipse > r.width) { if (Hellipse > r.height) // > W > H @@ -1437,7 +1437,7 @@ IntDrawRoundRect( PDC dc, app_draw_arc(dc, rect(r.x, r.y, Wellipse - 1, r.height - 1), 90, 270, pbrushPen, FALSE); app_draw_arc(dc, rect(Right - Wellipse, r.y, Wellipse - 1, r.height - 1), - 270, 90, pbrushPen, FALSE); + 270, 90, pbrushPen, FALSE); } else // < W < H { diff --git a/subsystems/win32/win32k/objects/fillshap.c b/subsystems/win32/win32k/objects/fillshap.c index 327b628ed30..7779de4313f 100644 --- a/subsystems/win32/win32k/objects/fillshap.c +++ b/subsystems/win32/win32k/objects/fillshap.c @@ -110,7 +110,7 @@ IntGdiPolygon(PDC dc, psurf, &dc->eboFill.BrushObject, Points, - Count, + Count, DestRect, &BrushOrigin); } @@ -271,15 +271,15 @@ NtGdiEllipse( } if (!PenWidth) PenWidth = 1; - pbrush->ptPenWidth.x = PenWidth; + pbrush->ptPenWidth.x = PenWidth; RectBounds.left = Left; RectBounds.right = Right; RectBounds.top = Top; RectBounds.bottom = Bottom; - + IntLPtoDP(dc, (LPPOINT)&RectBounds, 2); - + RectBounds.left += dc->ptlDCOrig.x; RectBounds.right += dc->ptlDCOrig.x; RectBounds.top += dc->ptlDCOrig.y; @@ -298,7 +298,7 @@ NtGdiEllipse( CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2); pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush); - if (NULL == pFillBrushObj) + if (NULL == pFillBrushObj) { DPRINT1("FillEllipse Fail\n"); SetLastWin32Error(ERROR_INTERNAL_ERROR); @@ -478,6 +478,15 @@ NtGdiPolyPolyDraw( IN HDC hDC, return TRUE; } + DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, + NULL, dc->rosdc.CombinedClip->rclBounds); + + if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(dc); + + if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(dc); + /* Perform the actual work */ switch (iFunc) { @@ -502,6 +511,7 @@ NtGdiPolyPolyDraw( IN HDC hDC, } /* Cleanup and return */ + DC_vFinishBlit(dc, NULL); DC_UnlockDc(dc); ExFreePool(pTemp); @@ -529,19 +539,6 @@ IntRectangle(PDC dc, pdcattr = dc->pdcattr; - /* Do we rotate or shear? */ - if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE)) - { - - POINTL DestCoords[4]; - ULONG PolyCounts = 4; - DestCoords[0].x = DestCoords[3].x = LeftRect; - DestCoords[0].y = DestCoords[1].y = TopRect; - DestCoords[1].x = DestCoords[2].x = RightRect; - DestCoords[2].y = DestCoords[3].y = BottomRect; - // Use IntGdiPolyPolygon so to support PATH. - return IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1); - } // Rectangle Path only. if ( PATH_IsPathOpen(dc->dclevel) ) { @@ -567,6 +564,8 @@ IntRectangle(PDC dc, DestRect.bottom--; } + DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect); + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); @@ -580,6 +579,7 @@ IntRectangle(PDC dc, ret = FALSE; goto cleanup; } + psurf = dc->dclevel.pSurface; if (!psurf) { @@ -645,6 +645,8 @@ IntRectangle(PDC dc, } cleanup: + DC_vFinishBlit(dc, NULL); + /* Move current position in DC? MSDN: The current position is neither used nor updated by Rectangle. */ @@ -675,8 +677,25 @@ NtGdiRectangle(HDC hDC, return TRUE; } - ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect ); - DC_UnlockDc ( dc ); + /* Do we rotate or shear? */ + if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE)) + { + POINTL DestCoords[4]; + ULONG PolyCounts = 4; + + DestCoords[0].x = DestCoords[3].x = LeftRect; + DestCoords[0].y = DestCoords[1].y = TopRect; + DestCoords[1].x = DestCoords[2].x = RightRect; + DestCoords[2].y = DestCoords[3].y = BottomRect; + // Use IntGdiPolyPolygon so to support PATH. + ret = IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1); + } + else + { + ret = IntRectangle(dc, LeftRect, TopRect, RightRect, BottomRect ); + } + + DC_UnlockDc(dc); return ret; } @@ -750,7 +769,7 @@ IntRoundRect( } if (!PenWidth) PenWidth = 1; - pbrushLine->ptPenWidth.x = PenWidth; + pbrushLine->ptPenWidth.x = PenWidth; RectBounds.left = Left; RectBounds.top = Top; @@ -765,12 +784,12 @@ IntRoundRect( RectBounds.bottom += dc->ptlDCOrig.y; pbrushFill = BRUSH_LockBrush(pdcattr->hbrush); - if (NULL == pbrushFill) + if (NULL == pbrushFill) { DPRINT1("FillRound Fail\n"); SetLastWin32Error(ERROR_INTERNAL_ERROR); ret = FALSE; - } + } else { RtlCopyMemory(&brushTemp, pbrushFill, sizeof(brushTemp)); @@ -849,16 +868,14 @@ GreGradientFill( { PDC pdc; SURFACE *psurf; - PPALETTE ppal; EXLATEOBJ exlo; RECTL rclExtent; POINTL ptlDitherOrg; ULONG i; BOOL bRet; - HPALETTE hDestPalette; - /* Check parameters */ - if (ulMode == GRADIENT_FILL_TRIANGLE) + /* check parameters */ + if (ulMode & GRADIENT_FILL_TRIANGLE) { PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh; @@ -888,13 +905,13 @@ GreGradientFill( /* Lock the output DC */ pdc = DC_LockDc(hdc); - if (!pdc) + if(!pdc) { SetLastWin32Error(ERROR_INVALID_HANDLE); return FALSE; } - if (pdc->dctype == DC_TYPE_INFO) + if(pdc->dctype == DC_TYPE_INFO) { DC_UnlockDc(pdc); /* Yes, Windows really returns TRUE in this case */ @@ -902,11 +919,11 @@ GreGradientFill( } psurf = pdc->dclevel.pSurface; - if (!psurf) + if(!psurf) { /* Memory DC with no surface selected */ DC_UnlockDc(pdc); - return TRUE; // CHECKME + return TRUE; //CHECKME } /* calculate extent */ @@ -919,8 +936,8 @@ GreGradientFill( rclExtent.top = min(rclExtent.top, (pVertex + i)->y); rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y); } - IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2); + rclExtent.left += pdc->ptlDCOrig.x; rclExtent.right += pdc->ptlDCOrig.x; rclExtent.top += pdc->ptlDCOrig.y; @@ -928,33 +945,29 @@ GreGradientFill( ptlDitherOrg.x = ptlDitherOrg.y = 0; IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1); + ptlDitherOrg.x += pdc->ptlDCOrig.x; ptlDitherOrg.y += pdc->ptlDCOrig.y; - hDestPalette = psurf->hDIBPalette; - if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault; - - ppal = PALETTE_LockPalette(hDestPalette); - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0); + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0); ASSERT(pdc->rosdc.CombinedClip); + DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent); + bRet = IntEngGradientFill(&psurf->SurfObj, - pdc->rosdc.CombinedClip, - &exlo.xlo, - pVertex, - nVertex, - pMesh, - nMesh, - &rclExtent, - &ptlDitherOrg, - ulMode); + pdc->rosdc.CombinedClip, + &exlo.xlo, + pVertex, + nVertex, + pMesh, + nMesh, + &rclExtent, + &ptlDitherOrg, + ulMode); EXLATEOBJ_vCleanup(&exlo); - - if (ppal) - PALETTE_UnlockPalette(ppal); - + DC_vFinishBlit(pdc, NULL); DC_UnlockDc(pdc); return bRet; @@ -996,16 +1009,16 @@ NtGdiGradientFill( return FALSE; } - cbVertex = nVertex * sizeof(TRIVERTEX); - if (cbVertex + cbMesh <= cbVertex) + cbVertex = nVertex * sizeof(TRIVERTEX) ; + if(cbVertex + cbMesh <= cbVertex) { /* Overflow */ - return FALSE; + return FALSE ; } /* Allocate a kernel mode buffer */ SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE); - if (!SafeVertex) + if(!SafeVertex) { SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -1048,8 +1061,6 @@ NtGdiExtFloodFill( PDC dc; PDC_ATTR pdcattr; SURFACE *psurf = NULL; - HPALETTE hpal; - PPALETTE ppal; EXLATEOBJ exlo; BOOL Ret = FALSE; RECTL DestRect; @@ -1094,11 +1105,7 @@ NtGdiExtFloodFill( goto cleanup; } - hpal = dc->dclevel.pSurface->hDIBPalette; - if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault; - ppal = PALETTE_ShareLockPalette(hpal); - - EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0); + EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0); /* Only solid fills supported for now * How to support pattern brushes and non standard surfaces (not offering dib functions): @@ -1108,7 +1115,6 @@ NtGdiExtFloodFill( Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType); EXLATEOBJ_vCleanup(&exlo); - PALETTE_ShareUnlockPalette(ppal); cleanup: DC_UnlockDc(dc); diff --git a/subsystems/win32/win32k/objects/freetype.c b/subsystems/win32/win32k/objects/freetype.c index 7b44fa384d7..f4d17cc5f8c 100644 --- a/subsystems/win32/win32k/objects/freetype.c +++ b/subsystems/win32/win32k/objects/freetype.c @@ -2249,7 +2249,7 @@ TextIntGetTextExtentPoint(PDC dc, Size->cx = (TotalWidth + 32) >> 6; Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight); - Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72); + Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72); return TRUE; } @@ -3160,7 +3160,7 @@ GreExtTextOutW( LONGLONG TextLeft, RealXStart; ULONG TextTop, previous, BackgroundLeft; FT_Bool use_kerning; - RECTL DestRect, MaskRect; + RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0}; POINTL SourcePoint, BrushOrigin; HBITMAP HSourceGlyph; SURFOBJ *SourceGlyphSurf; @@ -3175,8 +3175,6 @@ GreExtTextOutW( BOOLEAN Render; POINT Start; BOOL DoBreak = FALSE; - HPALETTE hDestPalette; - PPALETTE ppalDst; USHORT DxShift; // TODO: Write test-cases to exactly match real Windows in different @@ -3196,9 +3194,6 @@ GreExtTextOutW( pdcattr = dc->pdcattr; - if (pdcattr->ulDirty_ & DIRTY_TEXT) - DC_vUpdateTextBrush(dc); - if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE) { if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) @@ -3232,13 +3227,6 @@ GreExtTextOutW( IntLPtoDP(dc, (POINT *)lprc, 2); } - psurf = dc->dclevel.pSurface; - if (!psurf) - { - goto fail; - } - SurfObj = &psurf->SurfObj; - Start.x = XStart; Start.y = YStart; IntLPtoDP(dc, &Start, 1); @@ -3267,8 +3255,13 @@ GreExtTextOutW( DestRect.right += dc->ptlDCOrig.x; DestRect.bottom += dc->ptlDCOrig.y; + DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect); + + if (pdcattr->ulDirty_ & DIRTY_BACKGROUND) + DC_vUpdateBackgroundBrush(dc); + IntEngBitBlt( - &psurf->SurfObj, + &dc->dclevel.pSurface->SurfObj, NULL, NULL, dc->rosdc.CombinedClip, @@ -3280,6 +3273,7 @@ GreExtTextOutW( &BrushOrigin, ROP3_TO_ROP4(PATCOPY)); fuOptions &= ~ETO_OPAQUE; + DC_vFinishBlit(dc, NULL); } else { @@ -3444,19 +3438,24 @@ GreExtTextOutW( TextTop = YStart; BackgroundLeft = (RealXStart + 32) >> 6; - /* Create the xlateobj */ - hDestPalette = psurf->hDIBPalette; - if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault; - ppalDst = PALETTE_LockPalette(hDestPalette); - EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0); - EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0); - PALETTE_UnlockPalette(ppalDst); + /* Lock blit with a dummy rect */ + DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect); + psurf = dc->dclevel.pSurface ; + SurfObj = &psurf->SurfObj ; + + EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0); + EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0); + + if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND)) + DC_vUpdateBackgroundBrush(dc) ; + + if(dc->pdcattr->ulDirty_ & DIRTY_TEXT) + DC_vUpdateTextBrush(dc) ; /* * The main rendering loop. */ - for (i = 0; i < Count; i++) { if (fuOptions & ETO_GLYPH_INDEX) @@ -3505,6 +3504,7 @@ GreExtTextOutW( DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6; DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6); DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6); + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); IntEngBitBlt( &psurf->SurfObj, NULL, @@ -3517,7 +3517,9 @@ GreExtTextOutW( &dc->eboBackground.BrushObject, &BrushOrigin, ROP3_TO_ROP4(PATCOPY)); + MouseSafetyOnDrawEnd(dc->ppdev); BackgroundLeft = DestRect.right; + } DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left; @@ -3570,7 +3572,7 @@ GreExtTextOutW( DestRect.right = lprc->right + dc->ptlDCOrig.x; DoBreak = TRUE; } - + MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom); IntEngMaskBlt( SurfObj, SourceGlyphSurf, @@ -3581,6 +3583,7 @@ GreExtTextOutW( (PPOINTL)&MaskRect, &dc->eboText.BrushObject, &BrushOrigin); + MouseSafetyOnDrawEnd(dc->ppdev) ; EngUnlockSurface(SourceGlyphSurf); EngDeleteSurface((HSURF)HSourceGlyph); @@ -3610,9 +3613,9 @@ GreExtTextOutW( String++; } - IntUnLockFreeType; + DC_vFinishBlit(dc, NULL) ; EXLATEOBJ_vCleanup(&exloRGB2Dst); EXLATEOBJ_vCleanup(&exloDst2RGB); if (TextObj != NULL) @@ -3628,6 +3631,7 @@ fail2: fail: if (TextObj != NULL) TEXTOBJ_UnlockText(TextObj); + DC_UnlockDc(dc); return FALSE; diff --git a/subsystems/win32/win32k/objects/gdibatch.c b/subsystems/win32/win32k/objects/gdibatch.c index 5a367250409..7ddb1fa24e1 100644 --- a/subsystems/win32/win32k/objects/gdibatch.c +++ b/subsystems/win32/win32k/objects/gdibatch.c @@ -51,8 +51,9 @@ SynchonizeDriver(FLONG Flags) Flags = DSS_TIMER_EVENT; Device = IntEnumHDev(); - - SurfObj = EngLockSurface( Device->pSurface ); +// UNIMPLEMENTED; +//ASSERT(FALSE); + SurfObj = 0;// EngLockSurface( Device->pSurface ); if(!SurfObj) return; DoDeviceSync( SurfObj, NULL, Flags); EngUnlockSurface(SurfObj); diff --git a/subsystems/win32/win32k/objects/gdiobj.c b/subsystems/win32/win32k/objects/gdiobj.c index 66937461359..f9bacf092e5 100644 --- a/subsystems/win32/win32k/objects/gdiobj.c +++ b/subsystems/win32/win32k/objects/gdiobj.c @@ -8,7 +8,7 @@ /** INCLUDES ******************************************************************/ -//#define GDI_DEBUG +#define GDI_DEBUG #include #define NDEBUG @@ -635,10 +635,7 @@ LockHandle: PEPROCESS OldProcess; Object->BaseFlags |= BASEFLAG_READY_TO_DIE; DPRINT("Object %p, ulShareCount = %d\n", Object->hHmgr, Object->ulShareCount); - //GDIDBG_TRACECALLER(); - //GDIDBG_TRACESHARELOCKER(GDI_HANDLE_GET_INDEX(hObj)); - /* Set NULL owner. This will permit an other process to kill the object - * Do the work here to avoid race conditions */ + /* Set NULL owner. Do the work here to avoid race conditions */ Status = PsLookupProcessByProcessId((HANDLE)((ULONG_PTR)PrevProcId & ~0x1), &OldProcess); if (NT_SUCCESS(Status)) { @@ -649,7 +646,7 @@ LockHandle: } ObDereferenceObject(OldProcess); } - (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId); + (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, NULL); /* Don't wait on shared locks */ return FALSE; } @@ -660,7 +657,7 @@ LockHandle: */ DPRINT1("Object->cExclusiveLock = %d\n", Object->cExclusiveLock); GDIDBG_TRACECALLER(); - GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj)); + GDIDBG_TRACELOCKER(hObj); (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId); /* do not assert here for it will call again from dxg.sys it being call twice */ @@ -702,7 +699,7 @@ LockHandle: } DPRINT1("Type = 0x%lx, KernelData = 0x%p, ProcessId = 0x%p\n", Entry->Type, Entry->KernelData, Entry->ProcessId); GDIDBG_TRACECALLER(); - GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); + GDIDBG_TRACEALLOCATOR(hObj); } } @@ -833,7 +830,7 @@ GreDeleteObject(HGDIOBJ hObject) break; case GDI_OBJECT_TYPE_DC: - DC_FreeDcAttr(hObject); +// DC_FreeDcAttr(hObject); break; } @@ -970,12 +967,14 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType) if(hObj == NULL) return NULL ; + GDIDBG_INITLOOPTRACE(); + HandleIndex = GDI_HANDLE_GET_INDEX(hObj); HandleType = GDI_HANDLE_GET_TYPE(hObj); HandleUpper = GDI_HANDLE_GET_UPPER(hObj); /* Check that the handle index is valid. */ - if (HandleIndex >= GDI_HANDLE_COUNT) + if (HandleIndex >= GDI_HANDLE_COUNT ) return NULL; Entry = &GdiHandleTable->Entries[HandleIndex]; @@ -1001,7 +1000,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType) { DPRINT1("Tried to lock object (0x%p) of wrong owner! ProcessId = %p, HandleProcessId = %p\n", hObj, ProcessId, HandleProcessId); GDIDBG_TRACECALLER(); - GDIDBG_TRACEALLOCATOR(GDI_HANDLE_GET_INDEX(hObj)); + GDIDBG_TRACEALLOCATOR(hObj); return NULL; } @@ -1077,6 +1076,7 @@ GDIOBJ_LockObj(HGDIOBJ hObj, DWORD ExpectedType) /* * The handle is currently locked, wait some time and try again. */ + GDIDBG_TRACELOOP(hObj, PrevProcId, NULL); DelayExecution(); continue; @@ -1649,6 +1649,38 @@ GDI_MapHandleTable(PSECTION_OBJECT SectionObject, PEPROCESS Process) return MappedView; } +/* Locks 2 or 3 objects at a time */ +VOID +INTERNAL_CALL +GDIOBJ_LockMultipleObjs(ULONG ulCount, + IN HGDIOBJ* ahObj, + OUT PGDIOBJ* apObj) +{ + UINT auiIndices[3] = {0,1,2}; + UINT i, tmp ; + BOOL bUnsorted = TRUE; + + /* First is greatest */ + while(bUnsorted) + { + bUnsorted = FALSE; + for(i=1; idcattr, pDC->pdcattr, sizeof(DC_ATTR)); + DC_vFreeDcAttr(pDC); DC_UnlockDc( pDC ); - DC_FreeDcAttr( hDC ); // Free the dcattr! - if (!DC_SetOwnership( hDC, NULL )) // This hDC is inaccessible! return Ret; } diff --git a/subsystems/win32/win32k/objects/icm.c b/subsystems/win32/win32k/objects/icm.c index f0d7ef72e7a..3dfe7d01d18 100644 --- a/subsystems/win32/win32k/objects/icm.c +++ b/subsystems/win32/win32k/objects/icm.c @@ -256,9 +256,9 @@ UpdateDeviceGammaRamp( HDEV hPDev ) palPtr = (PALOBJ*) palGDI; if (pGDev->flFlags & PDEV_GAMMARAMP_TABLE) - palGDI->Mode |= PAL_GAMMACORRECTION; + palGDI->flFlags |= PAL_GAMMACORRECTION; else - palGDI->Mode &= ~PAL_GAMMACORRECTION; + palGDI->flFlags &= ~PAL_GAMMACORRECTION; if (!(pGDev->flFlags & PDEV_DRIVER_PUNTED_CALL)) // No punting, we hook { diff --git a/subsystems/win32/win32k/objects/line.c b/subsystems/win32/win32k/objects/line.c index 173b3f91b25..28ff28ae049 100644 --- a/subsystems/win32/win32k/objects/line.c +++ b/subsystems/win32/win32k/objects/line.c @@ -113,9 +113,6 @@ IntGdiLineTo(DC *dc, } else { - if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) - DC_vUpdateLineBrush(dc); - psurf = dc->dclevel.pSurface; if (NULL == psurf) { @@ -250,6 +247,9 @@ IntGdiPolyline(DC *dc, if (PATH_IsPathOpen(dc->dclevel)) return PATH_Polyline(dc, pt, Count); + DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, + NULL, dc->rosdc.CombinedClip->rclBounds); + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) DC_vUpdateFillBrush(dc); @@ -295,6 +295,8 @@ IntGdiPolyline(DC *dc, } } + DC_vFinishBlit(dc, NULL); + return Ret; } @@ -376,6 +378,7 @@ NtGdiLineTo(HDC hDC, { DC *dc; BOOL Ret; + RECT rcLockRect ; dc = DC_LockDc(hDC); if (!dc) @@ -390,8 +393,28 @@ NtGdiLineTo(HDC hDC, return TRUE; } + rcLockRect.left = dc->pdcattr->ptlCurrent.x; + rcLockRect.top = dc->pdcattr->ptlCurrent.y; + rcLockRect.right = XEnd; + rcLockRect.bottom = YEnd; + + IntLPtoDP(dc, &rcLockRect, 2); + + /* The DCOrg is in device coordinates */ + rcLockRect.left += dc->ptlDCOrig.x; + rcLockRect.top += dc->ptlDCOrig.y; + rcLockRect.right += dc->ptlDCOrig.x; + rcLockRect.bottom += dc->ptlDCOrig.y; + + DC_vPrepareDCsForBlit(dc, rcLockRect, NULL, rcLockRect); + + if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(dc); + Ret = IntGdiLineTo(dc, XEnd, YEnd); + DC_vFinishBlit(dc, NULL); + DC_UnlockDc(dc); return Ret; } diff --git a/subsystems/win32/win32k/objects/palette.c b/subsystems/win32/win32k/objects/palette.c index f031fd3b1ca..47dbd28eaa6 100644 --- a/subsystems/win32/win32k/objects/palette.c +++ b/subsystems/win32/win32k/objects/palette.c @@ -14,7 +14,8 @@ static UINT SystemPaletteUse = SYSPAL_NOSTATIC; /* the program need save the pallete and restore it */ -PALETTE gpalRGB, gpalBGR, gpalMono; +PALETTE gpalRGB, gpalBGR, gpalMono, gpalRGB555, gpalRGB565, *gppalDefault; +PPALETTE appalSurfaceDefault[11]; const PALETTEENTRY g_sysPalTemplate[NB_RESERVED_COLORS] = { @@ -84,18 +85,51 @@ HPALETTE FASTCALL PALETTE_Init(VOID) /* palette_size = visual->map_entries; */ - gpalRGB.Mode = PAL_RGB; + gpalRGB.flFlags = PAL_RGB; gpalRGB.RedMask = RGB(0xFF, 0x00, 0x00); gpalRGB.GreenMask = RGB(0x00, 0xFF, 0x00); gpalRGB.BlueMask = RGB(0x00, 0x00, 0xFF); + gpalRGB.BaseObject.ulShareCount = 0; + gpalRGB.BaseObject.BaseFlags = 0 ; - gpalBGR.Mode = PAL_BGR; + gpalBGR.flFlags = PAL_BGR; gpalBGR.RedMask = RGB(0x00, 0x00, 0xFF); gpalBGR.GreenMask = RGB(0x00, 0xFF, 0x00); gpalBGR.BlueMask = RGB(0xFF, 0x00, 0x00); + gpalBGR.BaseObject.ulShareCount = 0; + gpalBGR.BaseObject.BaseFlags = 0 ; + + gpalRGB555.flFlags = PAL_RGB16_555 | PAL_BITFIELDS; + gpalRGB555.RedMask = 0x7C00; + gpalRGB555.GreenMask = 0x3E0; + gpalRGB555.BlueMask = 0x1F; + gpalRGB555.BaseObject.ulShareCount = 0; + gpalRGB555.BaseObject.BaseFlags = 0 ; + + gpalRGB565.flFlags = PAL_RGB16_565 | PAL_BITFIELDS; + gpalRGB565.RedMask = 0xF800; + gpalRGB565.GreenMask = 0x7E0; + gpalRGB565.BlueMask = 0x1F; + gpalRGB565.BaseObject.ulShareCount = 0; + gpalRGB565.BaseObject.BaseFlags = 0 ; memset(&gpalMono, 0, sizeof(PALETTE)); - gpalMono.Mode = PAL_MONOCHROME; + gpalMono.flFlags = PAL_MONOCHROME; + gpalMono.BaseObject.ulShareCount = 0; + gpalMono.BaseObject.BaseFlags = 0 ; + + /* Initialize default surface palettes */ + gppalDefault = PALETTE_ShareLockPalette(hpalette); + appalSurfaceDefault[BMF_1BPP] = &gpalMono; + appalSurfaceDefault[BMF_4BPP] = gppalDefault; + appalSurfaceDefault[BMF_8BPP] = gppalDefault; + appalSurfaceDefault[BMF_16BPP] = &gpalRGB565; + appalSurfaceDefault[BMF_24BPP] = &gpalBGR; + appalSurfaceDefault[BMF_32BPP] = &gpalBGR; + appalSurfaceDefault[BMF_4RLE] = gppalDefault; + appalSurfaceDefault[BMF_8RLE] = gppalDefault; + appalSurfaceDefault[BMF_JPEG] = &gpalRGB; + appalSurfaceDefault[BMF_PNG] = &gpalRGB; return hpalette; } @@ -128,7 +162,7 @@ PALETTE_AllocPalette(ULONG Mode, NewPalette = PalGDI->BaseObject.hHmgr; PalGDI->Self = NewPalette; - PalGDI->Mode = Mode; + PalGDI->flFlags = Mode; if (NULL != Colors) { @@ -144,20 +178,22 @@ PALETTE_AllocPalette(ULONG Mode, RtlCopyMemory(PalGDI->IndexedColors, Colors, sizeof(PALETTEENTRY) * NumColors); } - if (PAL_INDEXED == Mode) + if (Mode & PAL_INDEXED) { PalGDI->NumColors = NumColors; } - else if (PAL_BITFIELDS == Mode) + else if (Mode & PAL_BITFIELDS) { PalGDI->RedMask = Red; PalGDI->GreenMask = Green; PalGDI->BlueMask = Blue; - + if (Red == 0x7c00 && Green == 0x3E0 && Blue == 0x1F) - PalGDI->Mode |= PAL_RGB16_555; + PalGDI->flFlags |= PAL_RGB16_555; else if (Red == 0xF800 && Green == 0x7E0 && Blue == 0x1F) - PalGDI->Mode |= PAL_RGB16_565; + PalGDI->flFlags |= PAL_RGB16_565; + else if (Red == 0xFF0000 && Green == 0xFF00 && Blue == 0xFF) + PalGDI->flFlags |= PAL_BGR; } PALETTE_UnlockPalette(PalGDI); @@ -183,7 +219,7 @@ PALETTE_AllocPaletteIndexedRGB(ULONG NumColors, NewPalette = PalGDI->BaseObject.hHmgr; PalGDI->Self = NewPalette; - PalGDI->Mode = PAL_INDEXED; + PalGDI->flFlags = PAL_INDEXED; PalGDI->IndexedColors = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * NumColors, @@ -287,7 +323,7 @@ ULONG NTAPI PALETTE_ulGetNearestIndex(PALETTE* ppal, ULONG ulColor) { - if (ppal->Mode & PAL_INDEXED) // use fl & PALINDEXED + if (ppal->flFlags & PAL_INDEXED) // use fl & PALINDEXED return PALETTE_ulGetNearestPaletteIndex(ppal, ulColor); else return PALETTE_ulGetNearestBitFieldsIndex(ppal, ulColor); @@ -299,19 +335,19 @@ PALETTE_vGetBitMasks(PPALETTE ppal, PULONG pulColors) { ASSERT(pulColors); - if (ppal->Mode & PAL_INDEXED || ppal->Mode & PAL_RGB) + if (ppal->flFlags & PAL_INDEXED || ppal->flFlags & PAL_RGB) { pulColors[0] = RGB(0xFF, 0x00, 0x00); pulColors[1] = RGB(0x00, 0xFF, 0x00); pulColors[2] = RGB(0x00, 0x00, 0xFF); } - else if (ppal->Mode & PAL_BGR) + else if (ppal->flFlags & PAL_BGR) { pulColors[0] = RGB(0x00, 0x00, 0xFF); pulColors[1] = RGB(0x00, 0xFF, 0x00); pulColors[2] = RGB(0xFF, 0x00, 0x00); } - else if (ppal->Mode & PAL_BITFIELDS) + else if (ppal->flFlags & PAL_BITFIELDS) { pulColors[0] = ppal->RedMask; pulColors[1] = ppal->GreenMask; @@ -358,7 +394,7 @@ EngCreatePalette( { HPALETTE Palette; - Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue); + Palette = PALETTE_AllocPalette(Mode, NumColors, Colors, Red, Green, Blue); if (Palette != NULL) { GDIOBJ_SetOwnership(Palette, NULL); @@ -399,7 +435,7 @@ PALOBJ_cGetColors(PALOBJ *PalObj, ULONG Start, ULONG Colors, ULONG *PaletteEntry /* NOTE: PaletteEntry ULONGs are in the same order as PALETTEENTRY. */ RtlCopyMemory(PaletteEntry, PalGDI->IndexedColors + Start, sizeof(ULONG) * Colors); - if (PalGDI->Mode & PAL_GAMMACORRECTION) + if (PalGDI->flFlags & PAL_GAMMACORRECTION) ColorCorrection(PalGDI, (PPALETTEENTRY)PaletteEntry, Colors); return Colors; @@ -630,17 +666,17 @@ COLORREF APIENTRY NtGdiGetNearestColor(HDC hDC, COLORREF Color) return nearest; } - if (palGDI->Mode & PAL_INDEXED) + if (palGDI->flFlags & PAL_INDEXED) { ULONG index; index = PALETTE_ulGetNearestPaletteIndex(palGDI, Color); nearest = PALETTE_ulGetRGBColorFromIndex(palGDI, index); } - else if (palGDI->Mode & PAL_RGB || palGDI->Mode & PAL_BGR) + else if (palGDI->flFlags & PAL_RGB || palGDI->flFlags & PAL_BGR) { nearest = Color; } - else if (palGDI->Mode & PAL_BITFIELDS) + else if (palGDI->flFlags & PAL_BITFIELDS) { RBits = 8 - GetNumberOfBits(palGDI->RedMask); GBits = 8 - GetNumberOfBits(palGDI->GreenMask); @@ -668,7 +704,7 @@ NtGdiGetNearestPaletteIndex( if (ppal) { - if (ppal->Mode & PAL_INDEXED) + if (ppal->flFlags & PAL_INDEXED) { /* Return closest match for the given RGB color */ index = PALETTE_ulGetNearestPaletteIndex(ppal, crColor); diff --git a/subsystems/win32/win32k/objects/path.c b/subsystems/win32/win32k/objects/path.c index 04a1314719d..da4e31fa572 100644 --- a/subsystems/win32/win32k/objects/path.c +++ b/subsystems/win32/win32k/objects/path.c @@ -408,7 +408,7 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid FLOAT_POINT ellCorners[2]; pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + if (!pPath) return FALSE; /* Check that path is open */ if(pPath->state!=PATH_Open) @@ -544,7 +544,7 @@ PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, if ( pPath->state != PATH_Open ) { Ret = FALSE; - goto ArcExit; + goto ArcExit; } /* Check for zero height / width */ @@ -697,7 +697,7 @@ PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) pPath = PATH_LockPath( dc->dclevel.hPath ); if (!pPath) return FALSE; - + /* Check that path is open */ if ( pPath->state != PATH_Open ) { @@ -805,7 +805,7 @@ PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) pPath = PATH_LockPath( dc->dclevel.hPath ); if (!pPath) return FALSE; - + /* Check that path is open */ if ( pPath->state != PATH_Open ) { @@ -1597,7 +1597,7 @@ PATH_WidenPath(DC *dc) numStrokes++; j = 0; if (numStrokes == 1) - pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); + pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); else { pOldStrokes = pStrokes; // Save old pointer. @@ -1627,7 +1627,7 @@ PATH_WidenPath(DC *dc) } } - pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH); + pNewPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH); PATH_InitGdiPath(pNewPath); pNewPath->state = PATH_Open; @@ -2012,7 +2012,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size) } IntGdiCloseFigure( pPath ); - PATH_UnlockPath( pPath ); + PATH_UnlockPath( pPath ); return TRUE; } @@ -2020,7 +2020,7 @@ PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size) * PATH_ExtTextOut */ BOOL -FASTCALL +FASTCALL PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, LPCWSTR str, UINT count, const INT *dx) { @@ -2210,7 +2210,7 @@ NtGdiCloseFigure(HDC hDC) { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; - } + } pPath = PATH_LockPath( pDc->dclevel.hPath ); if (!pPath) { @@ -2281,7 +2281,7 @@ NtGdiFillPath(HDC hDC) PPATH pPath; PDC_ATTR pdcattr; PDC dc = DC_LockDc ( hDC ); - + if ( !dc ) { SetLastWin32Error(ERROR_INVALID_PARAMETER); @@ -2294,6 +2294,9 @@ NtGdiFillPath(HDC hDC) return FALSE; } + DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, + NULL, dc->rosdc.CombinedClip->rclBounds); + pdcattr = dc->pdcattr; if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) @@ -2311,6 +2314,7 @@ NtGdiFillPath(HDC hDC) } PATH_UnlockPath( pPath ); + DC_vFinishBlit(dc, NULL); DC_UnlockDc ( dc ); return ret; } @@ -2328,7 +2332,7 @@ NtGdiFlattenPath(HDC hDC) pDc = DC_LockDc(hDC); if (!pDc) { - SetLastWin32Error(ERROR_INVALID_HANDLE); + SetLastWin32Error(ERROR_INVALID_HANDLE); return FALSE; } @@ -2572,6 +2576,9 @@ NtGdiStrokeAndFillPath(HDC hDC) return FALSE; } + DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, + NULL, pDc->rosdc.CombinedClip->rclBounds); + pdcattr = pDc->pdcattr; if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) @@ -2585,6 +2592,7 @@ NtGdiStrokeAndFillPath(HDC hDC) if (bRet) PATH_EmptyPath(pPath); PATH_UnlockPath( pPath ); + DC_vFinishBlit(pDc, NULL); DC_UnlockDc(pDc); return bRet; } @@ -2612,12 +2620,17 @@ NtGdiStrokePath(HDC hDC) return FALSE; } + DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, + NULL, pDc->rosdc.CombinedClip->rclBounds); + pdcattr = pDc->pdcattr; if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) DC_vUpdateLineBrush(pDc); bRet = PATH_StrokePath(pDc, pPath); + + DC_vFinishBlit(pDc, NULL); PATH_EmptyPath(pPath); PATH_UnlockPath( pPath ); @@ -2630,7 +2643,7 @@ APIENTRY NtGdiWidenPath(HDC hDC) { BOOL Ret; - PDC pdc = DC_LockDc ( hDC ); + PDC pdc = DC_LockDc ( hDC ); if ( !pdc ) { SetLastWin32Error(ERROR_INVALID_PARAMETER); diff --git a/subsystems/win32/win32k/objects/pen.c b/subsystems/win32/win32k/objects/pen.c index 8d02e9bdb0a..5884945c285 100644 --- a/subsystems/win32/win32k/objects/pen.c +++ b/subsystems/win32/win32k/objects/pen.c @@ -63,11 +63,11 @@ IntGdiExtCreatePen( { HPEN hPen; PBRUSH pbrushPen; - static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55}; - static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0}; - static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38}; - static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0}; - static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38}; + static const BYTE PatternAlternate[] = {0x55, 0x55, 0x55, 0}; + static const BYTE PatternDash[] = {0xFF, 0xFF, 0xC0, 0}; + static const BYTE PatternDot[] = {0xE3, 0x8E, 0x38, 0}; + static const BYTE PatternDashDot[] = {0xFF, 0x81, 0xC0, 0}; + static const BYTE PatternDashDotDot[] = {0xFF, 0x8E, 0x38, 0}; dwWidth = abs(dwWidth); @@ -125,27 +125,27 @@ IntGdiExtCreatePen( case PS_ALTERNATE: pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP; - pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); + pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate); break; case PS_DOT: pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP; - pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot); + pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot); break; case PS_DASH: pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP; - pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash); + pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash); break; case PS_DASHDOT: pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP; - pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot); + pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot); break; case PS_DASHDOTDOT: pbrushPen->flAttrs |= GDIBRUSH_IS_BITMAP; - pbrushPen->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot); + pbrushPen->hbmPattern = GreCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot); break; case PS_INSIDEFRAME: diff --git a/subsystems/win32/win32k/objects/region.c b/subsystems/win32/win32k/objects/region.c index 03814d5db60..9a73ace548e 100644 --- a/subsystems/win32/win32k/objects/region.c +++ b/subsystems/win32/win32k/objects/region.c @@ -3687,7 +3687,7 @@ NtGdiGetRandomRgn( else if (pDC->dclevel.prgnMeta) hSrc = ((PROSRGNDATA)pDC->dclevel.prgnMeta)->BaseObject.hHmgr; break; case SYSRGN: - if (pDC->prgnVis) hSrc = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr; + if (pDC->prgnVis) hSrc = pDC->prgnVis->BaseObject.hHmgr; break; default: hSrc = 0; diff --git a/subsystems/win32/win32k/objects/stockobj.c b/subsystems/win32/win32k/objects/stockobj.c index 5499a6fd956..02b07dfbf94 100644 --- a/subsystems/win32/win32k/objects/stockobj.c +++ b/subsystems/win32/win32k/objects/stockobj.c @@ -180,7 +180,7 @@ CreateStockObjects(void) StockObjects[NULL_PEN] = IntCreateStockPen(NullPen.lopnStyle, NullPen.lopnWidth.x, BS_SOLID, NullPen.lopnColor); StockObjects[20] = NULL; /* TODO: Unknown internal stock object */ - StockObjects[DEFAULT_BITMAP] = IntGdiCreateBitmap(1, 1, 1, 1, NULL); + StockObjects[DEFAULT_BITMAP] = GreCreateBitmap(1, 1, 1, 1, NULL); (void) TextIntCreateFontIndirect(&OEMFixedFont, (HFONT*)&StockObjects[OEM_FIXED_FONT]); (void) TextIntCreateFontIndirect(&AnsiFixedFont, (HFONT*)&StockObjects[ANSI_FIXED_FONT]); @@ -190,7 +190,7 @@ CreateStockObjects(void) (void) TextIntCreateFontIndirect(&SystemFixedFont, (HFONT*)&StockObjects[SYSTEM_FIXED_FONT]); (void) TextIntCreateFontIndirect(&DefaultGuiFont, (HFONT*)&StockObjects[DEFAULT_GUI_FONT]); - StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)PALETTE_Init(); + StockObjects[DEFAULT_PALETTE] = (HGDIOBJ)gppalDefault->BaseObject.hHmgr; for (Object = 0; Object < NB_STOCK_OBJECTS; Object++) { diff --git a/subsystems/win32/win32k/stubs/stubs.c b/subsystems/win32/win32k/stubs/stubs.c index 82a8555354a..7685c19ad99 100644 --- a/subsystems/win32/win32k/stubs/stubs.c +++ b/subsystems/win32/win32k/stubs/stubs.c @@ -150,18 +150,6 @@ EngFindResource( return NULL; } -/* - * @unimplemented - */ -LPWSTR -APIENTRY -EngGetDriverName ( IN HDEV hdev ) -{ - // www.osr.com/ddk/graphics/gdifncs_2gx3.htm - UNIMPLEMENTED; - return NULL; -} - /* * @unimplemented */