diff --git a/base/applications/mspaint/drawing.c b/base/applications/mspaint/drawing.c index 9aad82a073f..7d1ba0aa980 100644 --- a/base/applications/mspaint/drawing.c +++ b/base/applications/mspaint/drawing.c @@ -195,7 +195,7 @@ Brush(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG style) case 10: case 11: { - POINT offsTop[] = {{4, 3}, {2, -2}, {0, 0}, + POINT offsTop[] = {{4, -3}, {2, -2}, {0, 0}, {-3, -3}, {-2, -2}, {-1, 0}}; POINT offsBtm[] = {{-3, 4}, {-2, 2}, {-1, 1}, {4, 4}, {2, 2}, {0, 1}}; diff --git a/base/setup/usetup/lang/es-ES.h b/base/setup/usetup/lang/es-ES.h index 930accac885..2089e1e313e 100644 --- a/base/setup/usetup/lang/es-ES.h +++ b/base/setup/usetup/lang/es-ES.h @@ -992,19 +992,19 @@ static MUI_ENTRY esESBootLoaderEntries[] = { 8, 12, - "Instalar cargador de arranque en el disco duro (MBR and VBR).", + "Instalar el cargador de arranque en el disco duro (MBR y VBR).", TEXT_STYLE_NORMAL }, { 8, 13, - "Instalar cargador de arranque en el disco duro (VBR only).", + "Instalar el cargador de arranque en el disco duro (s¢lo VBR).", TEXT_STYLE_NORMAL }, { 8, 14, - "Instalar cargador de inicio en un disquete.", + "Instalar el cargador de inicio en un disquete.", TEXT_STYLE_NORMAL }, { diff --git a/base/shell/explorer/CMakeLists.txt b/base/shell/explorer/CMakeLists.txt index 5a7f9767908..383fa5cb29b 100644 --- a/base/shell/explorer/CMakeLists.txt +++ b/base/shell/explorer/CMakeLists.txt @@ -5,7 +5,6 @@ set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL) add_definitions( -DWIN32 - -D__MINGW32__ -D__WINDRES__) #add_pch(explorer precomp.h) diff --git a/base/shell/explorer/explorer.cpp b/base/shell/explorer/explorer.cpp index cdeb9aa2fb4..b3de9a9932b 100644 --- a/base/shell/explorer/explorer.cpp +++ b/base/shell/explorer/explorer.cpp @@ -69,9 +69,7 @@ ExplorerGlobals::ExplorerGlobals() #endif _log = NULL; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) _SHRestricted = 0; -#endif _hwndDesktopBar = 0; _hwndShellView = 0; _hwndDesktop = 0; @@ -81,11 +79,7 @@ ExplorerGlobals::ExplorerGlobals() void ExplorerGlobals::init(HINSTANCE hInstance) { _hInstance = hInstance; - -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) _SHRestricted = (DWORD(STDAPICALLTYPE*)(RESTRICTIONS)) GetProcAddress(GetModuleHandle(TEXT("SHELL32")), "SHRestricted"); -#endif - _icon_cache.init(); } @@ -999,38 +993,6 @@ int explorer_main(HINSTANCE hInstance, LPTSTR lpCmdLine, int cmdShow) } - // MinGW does not provide a Unicode startup routine, so we have to implement an own. -#if defined(__MINGW32__) && defined(UNICODE) - -#define _tWinMain wWinMain -int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int); - -int main(int argc, char* argv[]) -{ - CONTEXT("main"); - - STARTUPINFO startupinfo; - int nShowCmd = SW_SHOWNORMAL; - - GetStartupInfo(&startupinfo); - - if (startupinfo.dwFlags & STARTF_USESHOWWINDOW) - nShowCmd = startupinfo.wShowWindow; - - LPWSTR cmdline = GetCommandLineW(); - - while(*cmdline && !_istspace((unsigned)*cmdline)) - ++cmdline; - - while(_istspace((unsigned)*cmdline)) - ++cmdline; - - return wWinMain(GetModuleHandle(NULL), 0, cmdline, nShowCmd); -} - -#endif // __MINGW && UNICODE - - static bool SetShellReadyEvent(LPCTSTR evtName) { HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, evtName); diff --git a/base/shell/explorer/globals.h b/base/shell/explorer/globals.h index 9afa257a53d..1776c9b8aab 100644 --- a/base/shell/explorer/globals.h +++ b/base/shell/explorer/globals.h @@ -279,9 +279,7 @@ extern struct ExplorerGlobals FILE* _log; -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) DWORD(STDAPICALLTYPE* _SHRestricted)(RESTRICTIONS); -#endif FileTypeManager _ftype_mgr; IconCache _icon_cache; diff --git a/base/shell/explorer/shell/shellbrowser.cpp b/base/shell/explorer/shell/shellbrowser.cpp index 1c74c86393c..50b95a3f655 100644 --- a/base/shell/explorer/shell/shellbrowser.cpp +++ b/base/shell/explorer/shell/shellbrowser.cpp @@ -39,11 +39,7 @@ const LPCTSTR C_DRIVE = C_DRIVE_STR; ShellBrowser::ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs) -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) : super(IID_IShellFolderViewCB), -#else - : -#endif _hwnd(hwnd), _hwndFrame(hwndFrame), _left_hwnd(left_hwnd), @@ -449,7 +445,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) fs.fFlags = FWF_NOCLIENTEDGE|FWF_BESTFITWINDOW; } -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) SFV_CREATE sfv_create; sfv_create.cbSize = sizeof(SFV_CREATE); @@ -458,9 +453,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) sfv_create.psfvcb = this; HRESULT hr = SHCreateShellFolderView(&sfv_create, &_pShellView); -#else - HRESULT hr = folder->CreateViewObject(_hwnd, IID_IShellView, (void**)&_pShellView); -#endif if (FAILED(hr)) { _pShellView = NULL; @@ -480,9 +472,6 @@ void ShellBrowser::UpdateFolderView(IShellFolder* folder) _pShellView->UIActivate(SVUIA_ACTIVATE_NOFOCUS); } - -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) - /// shell view callback HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -495,8 +484,6 @@ HRESULT STDMETHODCALLTYPE ShellBrowser::MessageSFVCB(UINT uMsg, WPARAM wParam, L return E_NOTIMPL; } -#endif - HRESULT ShellBrowser::OnDefaultCommand(LPIDA pida) { diff --git a/base/shell/explorer/shell/shellbrowser.h b/base/shell/explorer/shell/shellbrowser.h index be910f1beb5..203b6d2c883 100644 --- a/base/shell/explorer/shell/shellbrowser.h +++ b/base/shell/explorer/shell/shellbrowser.h @@ -57,10 +57,8 @@ struct BrowserCallback /// Implementation of IShellBrowserImpl interface in explorer child windows -struct ShellBrowser : public IShellBrowserImpl -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) - , public IComSrvBase, public SimpleComObject -#endif +struct ShellBrowser : public IShellBrowserImpl, + public IComSrvBase, public SimpleComObject { ShellBrowser(HWND hwnd, HWND hwndFrame, HWND left_hwnd, WindowHandle& right_hwnd, ShellPathInfo& create_info, BrowserCallback* cb, CtxMenuInterfaces& cm_ifs); @@ -168,12 +166,10 @@ protected: void InitializeTree(); bool InitDragDrop(); -#ifndef __MINGW32__ // IShellFolderViewCB missing in MinGW (as of 25.09.2005) typedef IComSrvBase super; // IShellFolderViewCB virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam); -#endif map _image_map; diff --git a/base/shell/explorer/taskbar/desktopbar.cpp b/base/shell/explorer/taskbar/desktopbar.cpp index 20f58410966..c740ee94363 100644 --- a/base/shell/explorer/taskbar/desktopbar.cpp +++ b/base/shell/explorer/taskbar/desktopbar.cpp @@ -114,9 +114,7 @@ LRESULT DesktopBar::Init(LPCREATESTRUCT pcs) // create task bar _hwndTaskBar = TaskBar::Create(_hwnd); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOTRAYITEMSDISPLAY)) -#endif // create tray notification area _hwndNotify = NotifyArea::Create(_hwnd); diff --git a/base/shell/explorer/taskbar/startmenu.cpp b/base/shell/explorer/taskbar/startmenu.cpp index 194d4544520..56f51c48e3c 100644 --- a/base/shell/explorer/taskbar/startmenu.cpp +++ b/base/shell/explorer/taskbar/startmenu.cpp @@ -1560,9 +1560,7 @@ StartMenuRoot::StartMenuRoot(HWND hwnd, const StartMenuRootCreateInfo& info) : super(hwnd, info._icon_size), _hwndStartButton(0) { -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCOMMONGROUPS)) -#endif try { // insert directory "All Users\Start Menu" ShellDirectory cmn_startmenu(GetDesktopFolder(), SpecialFolderPath(CSIDL_COMMON_STARTMENU, _hwnd), _hwnd); @@ -1706,34 +1704,12 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) AddSeparator(); -#ifdef __MINGW32__ - HKEY hkey, hkeyAdv; - DWORD value, len; - - if (RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"), &hkey)) - hkey = 0; - - if (RegOpenKey(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), &hkeyAdv)) - hkeyAdv = 0; - -#define IS_VALUE_ZERO(hk, name) \ - (!hk || (len=sizeof(value),RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE)&value, &len) || !value)) - -#define IS_VALUE_NOT_ZERO(hk, name) \ - (!hk || (len=sizeof(value),RegQueryValueEx(hk, name, NULL, NULL, (LPBYTE)&value, &len) || value>0)) -#endif - - // insert hard coded start entries AddButton(ResString(IDS_PROGRAMS), ICID_APPS, true, IDC_PROGRAMS); AddButton(ResString(IDS_DOCUMENTS), ICID_DOCUMENTS, true, IDC_DOCUMENTS); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORECENTDOCSMENU)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoRecentDocsMenu"))) -#endif AddButton(ResString(IDS_RECENT), ICID_RECENT, true, IDC_RECENT); AddButton(ResString(IDS_FAVORITES), ICID_FAVORITES, true, IDC_FAVORITES); @@ -1742,42 +1718,26 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) AddButton(ResString(IDS_BROWSE), ICID_FOLDER, true, IDC_BROWSE); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOFIND)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoFind"))) -#endif AddButton(ResString(IDS_SEARCH), ICID_SEARCH, true, IDC_SEARCH); AddButton(ResString(IDS_START_HELP), ICID_INFO, false, IDC_START_HELP); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NORUN)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoRun"))) -#endif AddButton(ResString(IDS_LAUNCH), ICID_ACTION, false, IDC_LAUNCH); AddSeparator(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || SHRestricted(REST_STARTMENULOGOFF) != 1) -#else - if (IS_VALUE_NOT_ZERO(hkeyAdv, _T("StartMenuLogoff"))) -#endif AddButton(ResString(IDS_LOGOFF), ICID_LOGOFF, false, IDC_LOGOFF); #ifdef __REACTOS__ AddButton(ResString(IDS_RESTART), ICID_RESTART, false, IDC_RESTART); #endif -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCLOSE)) -#else - if (IS_VALUE_ZERO(hkey, _T("NoClose"))) -#endif AddButton(ResString(IDS_SHUTDOWN), ICID_SHUTDOWN, false, IDC_SHUTDOWN); #ifndef __REACTOS__ @@ -1785,10 +1745,6 @@ LRESULT StartMenuRoot::Init(LPCREATESTRUCT pcs) #endif -#ifdef __MINGW32__ - RegCloseKey(hkeyAdv); - RegCloseKey(hkey); -#endif #ifdef _LIGHT_STARTMENU @@ -2205,18 +2161,14 @@ void SettingsMenu::AddEntries() AddButton(ResString(IDS_ADMIN), ICID_ADMIN, true, IDC_ADMIN); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) -#endif - AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU); + AddButton(ResString(IDS_SETTINGS_MENU), ICID_CONFIG, true, IDC_SETTINGS_MENU); AddButton(ResString(IDS_DESKTOPBAR_SETTINGS), ICID_DESKSETTING, false, ID_DESKTOPBAR_SETTINGS); AddButton(ResString(IDS_PRINTERS), ICID_PRINTER, false, IDC_PRINTERS); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NOCONTROLPANEL)) -#endif AddButton(ResString(IDS_CONTROL_PANEL), ICID_CONTROLPAN, false, IDC_CONTROL_PANEL); } @@ -2224,9 +2176,7 @@ void BrowseMenu::AddEntries() { super::AddEntries(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_NONETHOOD)) // or REST_NOENTIRENETWORK ? -#endif #if defined(ROSSHELL) || defined(__REACTOS__) // __REACTOS__ to be removed when printer/network will be implemented AddButton(ResString(IDS_NETWORK), ICID_NETWORK, false, IDC_NETWORK); #else @@ -2242,9 +2192,7 @@ void SearchMenu::AddEntries() AddButton(ResString(IDS_SEARCH_FILES), ICID_SEARCH_DOC, false, IDC_SEARCH_FILES); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_HASFINDCOMPUTERS)) -#endif AddButton(ResString(IDS_SEARCH_COMPUTER),ICID_COMPUTER, false, IDC_SEARCH_COMPUTER); AddButton(ResString(IDS_SEARCH_PRG), ICID_APPS, false, IDC_SEARCH_PROGRAM); diff --git a/base/shell/explorer/taskbar/taskbar.cpp b/base/shell/explorer/taskbar/taskbar.cpp index 83c4b14058d..5db82d95b8e 100644 --- a/base/shell/explorer/taskbar/taskbar.cpp +++ b/base/shell/explorer/taskbar/taskbar.cpp @@ -133,7 +133,6 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs) //SetWindowFont(_htoolbar, GetStockFont(ANSI_VAR_FONT), FALSE); //SendMessage(_htoolbar, TB_SETPADDING, 0, MAKELPARAM(8,8)); -#ifndef __MINGW32__ // TBMETRICS missing in MinGW (as of 20.09.2005) // set metrics for the Taskbar toolbar to enable button spacing TBMETRICS metrics; @@ -145,7 +144,6 @@ LRESULT TaskBar::Init(LPCREATESTRUCT pcs) metrics.cyButtonSpacing = 3; SendMessage(_htoolbar, TB_SETMETRICS, 0, (LPARAM)&metrics); -#endif _next_id = IDC_FIRST_APP; @@ -264,11 +262,9 @@ int TaskBar::Notify(int id, NMHDR* pnmh) ActivateApp(it, false, false); // don't restore minimized windows on right button click -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) static DynamicFct pSHRestricted(TEXT("SHELL32"), "SHRestricted"); if (pSHRestricted && !(*pSHRestricted)(REST_NOTRAYCONTEXTMENU)) -#endif ShowAppSystemMenu(it); } break;} diff --git a/base/shell/explorer/taskbar/traynotify.cpp b/base/shell/explorer/taskbar/traynotify.cpp index ea0e85a4204..7e2690a9af6 100644 --- a/base/shell/explorer/taskbar/traynotify.cpp +++ b/base/shell/explorer/taskbar/traynotify.cpp @@ -133,7 +133,6 @@ bool NotifyInfo::modify(NOTIFYICONDATA* pnid) changes = true; ///@todo compare icon } -#ifdef NIF_STATE // as of 21.08.2003 missing in MinGW headers if (pnid->uFlags & NIF_STATE) { DWORD new_state = (_dwState&~pnid->dwStateMask) | (pnid->dwState&pnid->dwStateMask); @@ -142,7 +141,6 @@ bool NotifyInfo::modify(NOTIFYICONDATA* pnid) changes = true; } } -#endif // store tool tip text if (pnid->uFlags & NIF_TIP) { @@ -252,9 +250,7 @@ void NotifyArea::read_config() // read notification icon settings from XML configuration XMLPos cfg_pos = g_Globals.get_cfg(); -#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003) if (!g_Globals._SHRestricted || !SHRestricted(REST_HIDECLOCK)) -#endif { if (cfg_pos.go_down("desktopbar")) { clock_visible = XMLBoolRef(XMLPos(cfg_pos,"options"), "show-clock", !get_hide_clock_from_registry()); @@ -609,12 +605,10 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni */ bool changes = entry.modify(pnid); -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers if (DetermineHideState(entry) && entry._mode==NIM_HIDE) { entry._dwState |= NIS_HIDDEN; changes = true; } -#endif if (changes) UpdateIcons(); ///@todo call only if really changes occurred @@ -635,7 +629,6 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni } break;} -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers case NIM_SETFOCUS: SetForegroundWindow(_hwnd); return TRUE; @@ -648,7 +641,6 @@ LRESULT NotifyArea::ProcessTrayNotification(int notify_code, NOTIFYICONDATA* pni return TRUE; } else return FALSE; -#endif } return FALSE; @@ -662,9 +654,7 @@ void NotifyArea::UpdateIcons() for(NotifyIconMap::const_iterator it=_icon_map.begin(); it!=_icon_map.end(); ++it) { const NotifyInfo& entry = it->second; -#ifdef NIF_STATE // as of 21.08.2003 missing in MinGW headers if (_show_hidden || !(entry._dwState & NIS_HIDDEN)) -#endif _sorted_icons.insert(entry); } @@ -830,8 +820,6 @@ void NotifyIconConfig::create_name() } -#if NOTIFYICON_VERSION>=3 // as of 21.08.2003 missing in MinGW headers - bool NotifyIconConfig::match(const NotifyIconConfig& props) const { if (!_tipText.empty() && !props._tipText.empty()) @@ -873,7 +861,6 @@ bool NotifyArea::DetermineHideState(NotifyInfo& entry) return false; } -#endif String string_from_mode(NOTIFYICONMODE mode) diff --git a/base/shell/explorer/utility/shellclasses.cpp b/base/shell/explorer/utility/shellclasses.cpp index 5f66e2a1380..bbaea385c21 100644 --- a/base/shell/explorer/utility/shellclasses.cpp +++ b/base/shell/explorer/utility/shellclasses.cpp @@ -483,20 +483,15 @@ SpecialFolderFSPath::SpecialFolderFSPath(int folder, HWND hwnd) void CtxMenuInterfaces::reset() { _pctxmenu2 = NULL; - -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) _pctxmenu3 = NULL; -#endif } bool CtxMenuInterfaces::HandleMenuMsg(UINT nmsg, WPARAM wparam, LPARAM lparam) { -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) if (_pctxmenu3) { if (SUCCEEDED(_pctxmenu3->HandleMenuMsg(nmsg, wparam, lparam))) return true; } -#endif if (_pctxmenu2) if (SUCCEEDED(_pctxmenu2->HandleMenuMsg(nmsg, wparam, lparam))) @@ -512,11 +507,9 @@ IContextMenu* CtxMenuInterfaces::query_interfaces(IContextMenu* pcm1) reset(); // Get the higher version context menu interfaces. -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) if (pcm1->QueryInterface(IID_IContextMenu3, (void**)&pcm) == NOERROR) _pctxmenu3 = (LPCONTEXTMENU3)pcm; else -#endif if (pcm1->QueryInterface(IID_IContextMenu2, (void**)&pcm) == NOERROR) _pctxmenu2 = (LPCONTEXTMENU2)pcm; diff --git a/base/shell/explorer/utility/shellclasses.h b/base/shell/explorer/utility/shellclasses.h index 3e69dc67383..a46f997bb24 100644 --- a/base/shell/explorer/utility/shellclasses.h +++ b/base/shell/explorer/utility/shellclasses.h @@ -1114,9 +1114,7 @@ struct CtxMenuInterfaces IContextMenu2* _pctxmenu2; -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) IContextMenu3* _pctxmenu3; -#endif }; template struct ExtContextMenuHandlerT @@ -1151,7 +1149,6 @@ template struct ExtContextMenuHandlerT break; -#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005) case WM_MENUCHAR: // only supported by IContextMenu3 if (_cm_ifs._pctxmenu3) { LRESULT lResult = 0; @@ -1162,7 +1159,6 @@ template struct ExtContextMenuHandlerT } return 0; -#endif } return super::WndProc(nmsg, wparam, lparam); diff --git a/dll/ntdll/CMakeLists.txt b/dll/ntdll/CMakeLists.txt index 83e999970fd..9e51fc2ce7a 100644 --- a/dll/ntdll/CMakeLists.txt +++ b/dll/ntdll/CMakeLists.txt @@ -52,6 +52,7 @@ target_link_libraries(ntdll rtl ntdllsys libcntpr + uuid ${PSEH_LIB}) add_pch(ntdll include/ntdll.h) diff --git a/dll/ntdll/def/ntdll.spec b/dll/ntdll/def/ntdll.spec index a8c3d92b747..b45adaf0ec1 100644 --- a/dll/ntdll/def/ntdll.spec +++ b/dll/ntdll/def/ntdll.spec @@ -405,7 +405,7 @@ @ stdcall -arch=x86_64 RtlAddFunctionTable(ptr long long) ;@ stdcall RtlAddMandatoryAce(ptr long long long long ptr) @ stdcall RtlAddRefActivationContext(ptr) -;@ stdcall RtlAddRefMemoryStream +@ stdcall RtlAddRefMemoryStream(ptr) @ stdcall RtlAddVectoredContinueHandler(long ptr) @ stdcall RtlAddVectoredExceptionHandler(long ptr) ;@ stdcall RtlAddressInSectionTable @@ -440,8 +440,8 @@ @ stdcall RtlCheckRegistryKey(long ptr) @ stdcall RtlClearAllBits(ptr) @ stdcall RtlClearBits(ptr long long) -;@ stdcall RtlCloneMemoryStream -;@ stdcall RtlCommitMemoryStream +@ stdcall RtlCloneMemoryStream(ptr ptr) +@ stdcall RtlCommitMemoryStream(ptr long) @ stdcall RtlCompactHeap(long long) @ stdcall RtlCompareMemory(ptr ptr long) @ stdcall RtlCompareMemoryUlong(ptr long long) @@ -464,8 +464,8 @@ @ stdcall RtlCopyLuid(ptr ptr) @ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr) ;@ stdcall RtlCopyMappedMemory -;@ stdcall RtlCopyMemoryStreamTo -;@ stdcall RtlCopyOutOfProcessMemoryStreamTo +@ stdcall RtlCopyMemoryStreamTo(ptr ptr int64 ptr ptr) +@ stdcall RtlCopyOutOfProcessMemoryStreamTo(ptr ptr int64 ptr ptr) RtlCopyMemoryStreamTo ;@ stdcall RtlCopyRangeList ; 5.0 and 5.1 only @ stdcall RtlCopySecurityDescriptor(ptr ptr) @ stdcall RtlCopySid(long ptr ptr) @@ -571,7 +571,7 @@ @ stdcall -arch=win32 -ret64 RtlExtendedMagicDivide(double double long) @ stdcall RtlFillMemory(ptr long long) @ stdcall RtlFillMemoryUlong(ptr long long) -;@ stdcall RtlFinalReleaseOutOfProcessMemoryStream +@ stdcall RtlFinalReleaseOutOfProcessMemoryStream(ptr) @ stdcall RtlFindActivationContextSectionGuid(long ptr long ptr ptr) @ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr) @ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr) @@ -658,9 +658,9 @@ @ stdcall RtlInitAnsiString(ptr str) @ stdcall RtlInitAnsiStringEx(ptr str) @ stdcall RtlInitCodePageTable(ptr ptr) -;@ stdcall RtlInitMemoryStream +@ stdcall RtlInitMemoryStream(ptr) @ stdcall RtlInitNlsTables(ptr ptr ptr ptr) -;@ stdcall RtlInitOutOfProcessMemoryStream +@ stdcall RtlInitOutOfProcessMemoryStream(ptr) @ stdcall RtlInitString(ptr str) @ stdcall RtlInitUnicodeString(ptr wstr) @ stdcall RtlInitUnicodeStringEx(ptr wstr) @@ -735,7 +735,7 @@ @ stdcall RtlLocalTimeToSystemTime(ptr ptr) @ stdcall RtlLockBootStatusData(ptr) @ stdcall RtlLockHeap(long) -;@ stdcall RtlLockMemoryStreamRegion +@ stdcall RtlLockMemoryStreamRegion(ptr int64 int64 long) ;@ stdcall RtlLogStackBackTrace @ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr) @ stdcall RtlLookupElementGenericTable(ptr ptr) @@ -781,7 +781,7 @@ @ stdcall RtlQueryInformationAcl(ptr ptr long long) @ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr) @ stdcall RtlQueryInformationActiveActivationContext(long ptr long ptr) -;@ stdcall RtlQueryInterfaceMemoryStream +@ stdcall RtlQueryInterfaceMemoryStream(ptr ptr ptr) ;@ stdcall RtlQueryProcessBackTraceInformation @ stdcall RtlQueryProcessDebugInformation(long long ptr) ;@ stdcall RtlQueryProcessHeapInformation @@ -800,14 +800,14 @@ @ stdcall RtlRandom(ptr) @ stdcall RtlRandomEx(ptr) @ stdcall RtlReAllocateHeap(long long ptr long) -;@ stdcall RtlReadMemoryStream -;@ stdcall RtlReadOutOfProcessMemoryStream +@ stdcall RtlReadMemoryStream(ptr ptr long ptr) +@ stdcall RtlReadOutOfProcessMemoryStream(ptr ptr long ptr) @ stdcall RtlRealPredecessor(ptr) @ stdcall RtlRealSuccessor(ptr) @ stdcall RtlRegisterSecureMemoryCacheCallback(ptr) @ stdcall RtlRegisterWait(ptr ptr ptr ptr long long) @ stdcall RtlReleaseActivationContext(ptr) -;@ stdcall RtlReleaseMemoryStream +@ stdcall RtlReleaseMemoryStream(ptr) @ stdcall RtlReleasePebLock() @ stdcall RtlReleasePrivilege(ptr) @ stdcall RtlReleaseRelativeName(ptr) @@ -820,12 +820,12 @@ @ stdcall RtlResetRtlTranslations(ptr) @ stdcall -arch=x86_64 RtlRestoreContext(ptr ptr) @ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error -;@ stdcall RtlRevertMemoryStream +@ stdcall RtlRevertMemoryStream(ptr) @ stdcall RtlRunDecodeUnicodeString(long ptr) @ stdcall RtlRunEncodeUnicodeString(long ptr) @ stdcall RtlSecondsSince1970ToTime(long ptr) @ stdcall RtlSecondsSince1980ToTime(long ptr) -;@ stdcall RtlSeekMemoryStream +@ stdcall RtlSeekMemoryStream(ptr int64 long ptr) @ stdcall RtlSelfRelativeToAbsoluteSD2(ptr ptr) @ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stdcall RtlSetAllBits(ptr) @@ -844,7 +844,7 @@ @ stdcall RtlSetIoCompletionCallback(long ptr long) @ stdcall RtlSetLastWin32Error(long) @ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long) -;@ stdcall RtlSetMemoryStreamSize +@ stdcall RtlSetMemoryStreamSize(ptr int64) @ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long) @ stdcall RtlSetProcessIsCritical(long ptr long) ;@ stdcall RtlSetProperties ; RtlSetProperties @@ -869,7 +869,7 @@ @ stdcall RtlSleepConditionVariableSRW(ptr ptr ptr long) @ stdcall RtlSplay(ptr) ;@ stdcall RtlStartRXact -;@ stdcall RtlStatMemoryStream +@ stdcall RtlStatMemoryStream(ptr ptr long) @ stdcall RtlStringFromGUID(ptr ptr) @ stdcall RtlSubAuthorityCountSid(ptr) @ stdcall RtlSubAuthoritySid(ptr long) @@ -907,7 +907,7 @@ @ stdcall RtlUniform(ptr) @ stdcall RtlUnlockBootStatusData(ptr) @ stdcall RtlUnlockHeap(long) -;@ stdcall RtlUnlockMemoryStreamRegion +@ stdcall RtlUnlockMemoryStreamRegion(ptr int64 int64 long) @ stdcall -register RtlUnwind(ptr ptr ptr ptr) @ stdcall -arch=x86_64 RtlUnwindEx(long long ptr long ptr) @ stdcall RtlUpcaseUnicodeChar(long) @@ -938,7 +938,7 @@ @ stdcall RtlWow64EnableFsRedirectionEx(long ptr) @ stdcall RtlWakeAllConditionVariable(ptr) @ stdcall RtlWakeConditionVariable(ptr) -;@ stdcall RtlWriteMemoryStream +@ stdcall RtlWriteMemoryStream(ptr ptr long ptr) @ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long) @ stdcall RtlZeroHeap(ptr long) @ stdcall RtlZeroMemory(ptr long) diff --git a/dll/win32/samsrv/samrpc.c b/dll/win32/samsrv/samrpc.c index 3e7780c272b..3b42f573f4d 100644 --- a/dll/win32/samsrv/samrpc.c +++ b/dll/win32/samsrv/samrpc.c @@ -1770,6 +1770,8 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, SAM_GROUP_FIXED_DATA FixedGroupData; PSAM_DB_OBJECT DomainObject; PSAM_DB_OBJECT GroupObject; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; @@ -1814,6 +1816,15 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Create the security descriptor */ + Status = SampCreateGroupSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("SampCreateGroupSD failed (Status 0x%08lx)\n", Status); + goto done; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -1910,6 +1921,18 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the SecDesc attribute*/ + Status = SampSetObjectAttribute(GroupObject, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + if (NT_SUCCESS(Status)) { *GroupHandle = (SAMPR_HANDLE)GroupObject; @@ -1917,6 +1940,9 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle, } done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + RtlReleaseResource(&SampResource); TRACE("returns with status 0x%08lx\n", Status); @@ -2469,6 +2495,16 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the PrivateData attribute */ + Status = SampSetObjectAttributeString(UserObject, + L"PrivateData", + NULL); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + /* FIXME: Set SecDesc attribute*/ if (NT_SUCCESS(Status)) @@ -2704,6 +2740,8 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, SAM_DOMAIN_FIXED_DATA FixedDomainData; PSAM_DB_OBJECT DomainObject; PSAM_DB_OBJECT AliasObject; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; ULONG ulSize; ULONG ulRid; WCHAR szRid[9]; @@ -2748,6 +2786,15 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Create the security descriptor */ + Status = SampCreateAliasSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("SampCreateAliasSD failed (Status 0x%08lx)\n", Status); + goto done; + } + /* Get the fixed domain attributes */ ulSize = sizeof(SAM_DOMAIN_FIXED_DATA); Status = SampGetObjectAttribute(DomainObject, @@ -2827,6 +2874,18 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the SecDesc attribute*/ + Status = SampSetObjectAttribute(AliasObject, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + if (NT_SUCCESS(Status)) { *AliasHandle = (SAMPR_HANDLE)AliasObject; @@ -2834,6 +2893,9 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle, } done: + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + RtlReleaseResource(&SampResource); TRACE("returns with status 0x%08lx\n", Status); @@ -3191,7 +3253,6 @@ TRACE("Open %S\n", MemberSidString); } done: - SampRegCloseKey(&MembersKeyHandle); SampRegCloseKey(&MembersKeyHandle); SampRegCloseKey(&AliasesKeyHandle); @@ -6810,6 +6871,7 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (InfoBuffer->All.WhichFields & USER_ALL_SECURITYDESCRIPTOR) { +#if 0 Length = 0; SampGetObjectAttribute(UserObject, L"SecDesc", @@ -6836,6 +6898,7 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, if (!NT_SUCCESS(Status)) goto done; } +#endif } *Buffer = InfoBuffer; @@ -7607,11 +7670,13 @@ SampSetUserAll(PSAM_DB_OBJECT UserObject, if (WhichFields & USER_ALL_SECURITYDESCRIPTOR) { +#if 0 Status = SampSetObjectAttribute(UserObject, L"SecDesc", REG_BINARY, Buffer->All.SecurityDescriptor.SecurityDescriptor, Buffer->All.SecurityDescriptor.Length); +#endif } if (WriteFixedData == TRUE) @@ -8786,6 +8851,16 @@ SamrCreateUser2InDomain(IN SAMPR_HANDLE DomainHandle, goto done; } + /* Set the PrivateData attribute */ + Status = SampSetObjectAttributeString(UserObject, + L"PrivateData", + NULL); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + goto done; + } + /* FIXME: Set SecDesc attribute*/ if (NT_SUCCESS(Status)) diff --git a/dll/win32/samsrv/samsrv.h b/dll/win32/samsrv/samsrv.h index f781287b161..91427a0d523 100644 --- a/dll/win32/samsrv/samsrv.h +++ b/dll/win32/samsrv/samsrv.h @@ -321,13 +321,21 @@ SampCreateServerSD(OUT PSECURITY_DESCRIPTOR *ServerSd, OUT PULONG Size); NTSTATUS -SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd, +SampCreateBuiltinDomainSD(OUT PSECURITY_DESCRIPTOR *DomainSd, OUT PULONG Size); NTSTATUS -SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR *ServerSd, +SampCreateAccountDomainSD(OUT PSECURITY_DESCRIPTOR *DomainSd, OUT PULONG Size); +NTSTATUS +SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd, + OUT PULONG Size); + +NTSTATUS +SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd, + OUT PULONG Size); + /* setup.c */ diff --git a/dll/win32/samsrv/security.c b/dll/win32/samsrv/security.c index f58939106c4..dab82ad12b9 100644 --- a/dll/win32/samsrv/security.c +++ b/dll/win32/samsrv/security.c @@ -859,4 +859,578 @@ done: return Status; } + +NTSTATUS +SampCreateAliasSD(OUT PSECURITY_DESCRIPTOR *AliasSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PSID AccountOperatorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Account Operators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ACCOUNT_OPS, + 0, + 0, + 0, + 0, + 0, + 0, + &AccountOperatorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 3 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid) + + RtlLengthSid(AccountOperatorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + READ_CONTROL | ALIAS_READ_INFORMATION | ALIAS_LIST_MEMBERS, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ALIAS_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + ALIAS_ALL_ACCESS, + AccountOperatorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + ALIAS_WRITE_ACCOUNT | ALIAS_REMOVE_MEMBER | + ALIAS_ADD_MEMBER, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *AliasSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + + +NTSTATUS +SampCreateGroupSD(OUT PSECURITY_DESCRIPTOR *GroupSd, + OUT PULONG Size) +{ + PSECURITY_DESCRIPTOR AbsSD = NULL; + PSECURITY_DESCRIPTOR RelSD = NULL; + PSID EveryoneSid = NULL; + PSID AnonymousSid = NULL; + PSID AdministratorsSid = NULL; + PSID AccountOperatorsSid = NULL; + PACL Dacl = NULL; + PACL Sacl = NULL; + ULONG DaclSize; + ULONG SaclSize; + ULONG RelSDSize = 0; + NTSTATUS Status = STATUS_SUCCESS; + + + /* Create the Everyone SID */ + Status = RtlAllocateAndInitializeSid(&WorldAuthority, + 1, + SECURITY_WORLD_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Anonymous SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 1, + SECURITY_ANONYMOUS_LOGON_RID, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + &AnonymousSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Administrators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &AdministratorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Create the Account Operators SID */ + Status = RtlAllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ACCOUNT_OPS, + 0, + 0, + 0, + 0, + 0, + 0, + &AccountOperatorsSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* Allocate a buffer for the absolute SD */ + AbsSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SECURITY_DESCRIPTOR)); + if (AbsSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Create the absolute SD */ + Status = RtlCreateSecurityDescriptor(AbsSD, + SECURITY_DESCRIPTOR_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the DACL */ + DaclSize = sizeof(ACL) + + 3 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AdministratorsSid) + + RtlLengthSid(AccountOperatorsSid); + + Dacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Dacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Dacl, + DaclSize, + ACL_REVISION); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + READ_CONTROL | GROUP_LIST_MEMBERS | GROUP_READ_INFORMATION, + EveryoneSid); + ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GROUP_ALL_ACCESS, + AdministratorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAccessAllowedAce(Dacl, + ACL_REVISION, + GROUP_ALL_ACCESS, + AccountOperatorsSid); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the DACL */ + Status = RtlSetDaclSecurityDescriptor(AbsSD, + TRUE, + Dacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* allocate and create the SACL */ + SaclSize = sizeof(ACL) + + 2 * sizeof(ACE) + + RtlLengthSid(EveryoneSid) + + RtlLengthSid(AnonymousSid); + + Sacl = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + DaclSize); + if (Sacl == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + Status = RtlCreateAcl(Sacl, + SaclSize, + ACL_REVISION); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + ACCESS_SYSTEM_SECURITY | WRITE_DAC | DELETE | + GROUP_REMOVE_MEMBER | GROUP_ADD_MEMBER | + GROUP_WRITE_ACCOUNT, + EveryoneSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + Status = RtlAddAuditAccessAce(Sacl, + ACL_REVISION, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, + AnonymousSid, + TRUE, + TRUE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SACL */ + Status = RtlSetSaclSecurityDescriptor(AbsSD, + TRUE, + Sacl, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the owner SID */ + Status = RtlSetOwnerSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the group SID */ + Status = RtlSetGroupSecurityDescriptor(AbsSD, + AdministratorsSid, + FALSE); + ASSERT(Status == STATUS_SUCCESS); + if (!NT_SUCCESS(Status)) + goto done; + + /* Get the reqired buffer size for the self-relative SD */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + NULL, + &RelSDSize); + if (Status != STATUS_BUFFER_TOO_SMALL) + goto done; + + /* Allocate a buffer for the self-relative SD */ + RelSD = RtlAllocateHeap(RtlGetProcessHeap(), + HEAP_ZERO_MEMORY, + RelSDSize); + if (RelSD == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + /* Convert the absolute SD to self-relative format */ + Status = RtlAbsoluteToSelfRelativeSD(AbsSD, + RelSD, + &RelSDSize); + if (Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(Status == STATUS_SUCCESS); + goto done; + } + + *GroupSd = RelSD; + *Size = RelSDSize; + +done: + if (!NT_SUCCESS(Status)) + { + if (RelSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, RelSD); + } + + if (EveryoneSid != NULL) + RtlFreeSid(EveryoneSid); + + if (AnonymousSid != NULL) + RtlFreeSid(AnonymousSid); + + if (AdministratorsSid != NULL) + RtlFreeSid(AdministratorsSid); + + if (Dacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Dacl); + + if (Sacl != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sacl); + + if (AbsSD != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, AbsSD); + + return Status; +} + /* EOF */ diff --git a/dll/win32/samsrv/setup.c b/dll/win32/samsrv/setup.c index ce96c7ae23e..ad758cadca7 100644 --- a/dll/win32/samsrv/setup.c +++ b/dll/win32/samsrv/setup.c @@ -98,6 +98,8 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, WCHAR szAccountKeyName[32]; HANDLE hAccountKey = NULL; HANDLE hNamesKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; NTSTATUS Status; swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId); @@ -125,6 +127,20 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Create the server SD */ + Status = SampCreateAliasSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set SecDesc attribute*/ + Status = SampRegSetValue(hAccountKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; Status = SampRegOpenKey(hDomainKey, L"Aliases\\Names", @@ -142,6 +158,9 @@ SampSetupCreateAliasAccount(HANDLE hDomainKey, done: SampRegCloseKey(&hNamesKey); + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + if (hAccountKey != NULL) { SampRegCloseKey(&hAccountKey); @@ -245,6 +264,8 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, WCHAR szAccountKeyName[32]; HANDLE hAccountKey = NULL; HANDLE hNamesKey = NULL; + PSECURITY_DESCRIPTOR Sd = NULL; + ULONG SdSize = 0; NTSTATUS Status; /* Initialize fixed group data */ @@ -286,6 +307,21 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Create the security descriptor */ + Status = SampCreateGroupSD(&Sd, + &SdSize); + if (!NT_SUCCESS(Status)) + goto done; + + /* Set the SecDesc attribute*/ + Status = SampRegSetValue(hAccountKey, + L"SecDesc", + REG_BINARY, + Sd, + SdSize); + if (!NT_SUCCESS(Status)) + goto done; + Status = SampRegOpenKey(hDomainKey, L"Groups\\Names", KEY_ALL_ACCESS, @@ -302,6 +338,9 @@ SampSetupCreateGroupAccount(HANDLE hDomainKey, done: SampRegCloseKey(&hNamesKey); + if (Sd != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, Sd); + if (hAccountKey != NULL) { SampRegCloseKey(&hAccountKey); @@ -510,6 +549,16 @@ SampSetupCreateUserAccount(HANDLE hDomainKey, if (!NT_SUCCESS(Status)) goto done; + /* Set PrivateData attribute*/ + Status = SampRegSetValue(hAccountKey, + L"PrivateData", + REG_SZ, + (LPVOID)lpEmptyString, + sizeof(WCHAR)); + if (!NT_SUCCESS(Status)) + goto done; + + /* FIXME: Set SecDesc attribute*/ diff --git a/dll/win32/shell32/shellord.cpp b/dll/win32/shell32/shellord.cpp index 166b8e473bf..b83b6adc7eb 100644 --- a/dll/win32/shell32/shellord.cpp +++ b/dll/win32/shell32/shellord.cpp @@ -1009,21 +1009,18 @@ HRESULT WINAPI SHCreateShellFolderViewEx( LPCSFV psvcbi, /* [in] shelltemplate struct */ IShellView **ppv) /* [out] IShellView pointer */ { - IShellView * psf; + IShellView *psf; HRESULT hRes; TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n", - psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback, - psvcbi->fvm, psvcbi->psvOuter); + psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback, + psvcbi->fvm, psvcbi->psvOuter); + *ppv = NULL; hRes = IShellView_Constructor(psvcbi->pshf, &psf); if (FAILED(hRes)) return hRes; - if (!psf) - return E_OUTOFMEMORY; - - psf->AddRef(); hRes = psf->QueryInterface(IID_IShellView, (LPVOID *)ppv); psf->Release(); @@ -1914,25 +1911,24 @@ HRESULT WINAPI SHCreateStdEnumFmtEtc( */ HRESULT WINAPI SHCreateShellFolderView(const SFV_CREATE *pcsfv, IShellView **ppsv) { - HRESULT ret = S_OK; + IShellView *psf; + HRESULT hRes; - FIXME("SHCreateShellFolderView() stub\n"); + *ppsv = NULL; + if (!pcsfv || pcsfv->cbSize != sizeof(*pcsfv)) + return E_INVALIDARG; - if (!pcsfv || sizeof(*pcsfv) != pcsfv->cbSize) - ret = E_INVALIDARG; - else - { - LPVOID lpdata = 0;/*LocalAlloc(LMEM_ZEROINIT, 0x4E4);*/ + TRACE("sf=%p outer=%p callback=%p\n", + pcsfv->pshf, pcsfv->psvOuter, pcsfv->psfvcb); - if (!lpdata) - ret = E_OUTOFMEMORY; - else - { - /* Initialize and return unknown lpdata structure */ - } - } + hRes = IShellView_Constructor(pcsfv->pshf, &psf); + if (FAILED(hRes)) + return hRes; - return ret; + hRes = psf->QueryInterface(IID_IShellView, (LPVOID *)ppsv); + psf->Release(); + + return hRes; } /************************************************************************* @@ -2113,8 +2109,8 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) if (!(dwFlags & SHERB_NOCONFIRMATION)) { /* FIXME - * enumerate available files - * show confirmation dialog + * enumerate available files + * show confirmation dialog */ FIXME("show confirmation dialog\n"); } @@ -2137,7 +2133,7 @@ HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags) if (!(dwFlags & SHERB_NOSOUND)) { dwSize = sizeof(szPath); - ret = RegGetValueW(HKEY_CURRENT_USER, + ret = RegGetValueW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\Explorer\\EmptyRecycleBin\\.Current", NULL, RRF_RT_REG_EXPAND_SZ, diff --git a/include/ddk/ntsam.h b/include/ddk/ntsam.h index 5f272831629..63d8fcf5514 100644 --- a/include/ddk/ntsam.h +++ b/include/ddk/ntsam.h @@ -440,6 +440,29 @@ typedef enum _GROUP_INFORMATION_CLASS GroupReplicationInformation } GROUP_INFORMATION_CLASS; +typedef struct _GROUP_GENERAL_INFORMATION +{ + UNICODE_STRING Name; + ULONG Attributes; + ULONG MemberCount; + UNICODE_STRING AdminComment; +} GROUP_GENERAL_INFORMATION, *PGROUP_GENERAL_INFORMATION; + +typedef struct _GROUP_NAME_INFORMATION +{ + UNICODE_STRING Name; +} GROUP_NAME_INFORMATION, *PGROUP_NAME_INFORMATION; + +typedef struct _GROUP_ATTRIBUTE_INFORMATION +{ + ULONG Attributes; +} GROUP_ATTRIBUTE_INFORMATION, *PGROUP_ATTRIBUTE_INFORMATION; + +typedef struct GROUP_ADM_COMMENT_INFORMATION +{ + UNICODE_STRING AdminComment; +} GROUP_ADM_COMMENT_INFORMATION, *PGROUP_ADM_COMMENT_INFORMATION; + typedef struct _GROUP_MEMBERSHIP { ULONG RelativeId; diff --git a/include/ndk/rtlfuncs.h b/include/ndk/rtlfuncs.h index 3205fa1a7c8..0b1332923b9 100644 --- a/include/ndk/rtlfuncs.h +++ b/include/ndk/rtlfuncs.h @@ -4152,6 +4152,180 @@ RtlComputeImportTableHash( ); #endif +// +// MemoryStream functions +// +#ifdef NTOS_MODE_USER + +NTSYSAPI +VOID +NTAPI +RtlInitMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +VOID +NTAPI +RtlInitOutOfProcessMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +VOID +NTAPI +RtlFinalReleaseOutOfProcessMemoryStream( + _In_ PRTL_MEMORY_STREAM Stream +); + +NTSYSAPI +HRESULT +NTAPI +RtlQueryInterfaceMemoryStream( + _In_ struct IStream *This, + _In_ REFIID RequestedIid, + _Outptr_ PVOID *ResultObject +); + +NTSYSAPI +ULONG +NTAPI +RtlAddRefMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +ULONG +NTAPI +RtlReleaseMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +HRESULT +NTAPI +RtlReadMemoryStream( + _In_ struct IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead +); + +NTSYSAPI +HRESULT +NTAPI +RtlReadOutOfProcessMemoryStream( + _In_ struct IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead +); + +NTSYSAPI +HRESULT +NTAPI +RtlSeekMemoryStream( + _In_ struct IStream *This, + _In_ LARGE_INTEGER RelativeOffset, + _In_ ULONG Origin, + _Out_opt_ PULARGE_INTEGER ResultOffset +); + +NTSYSAPI +HRESULT +NTAPI +RtlCopyMemoryStreamTo( + _In_ struct IStream *This, + _In_ struct IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlCopyOutOfProcessMemoryStreamTo( + _In_ struct IStream *This, + _In_ struct IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlStatMemoryStream( + _In_ struct IStream *This, + _Out_ struct tagSTATSTG *Stats, + _In_ ULONG Flags +); + +// Dummy functions +NTSYSAPI +HRESULT +NTAPI +RtlWriteMemoryStream( + _In_ struct IStream *This, + _In_reads_bytes_(Length) CONST VOID *Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesWritten +); + +NTSYSAPI +HRESULT +NTAPI +RtlSetMemoryStreamSize( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER NewSize +); + +NTSYSAPI +HRESULT +NTAPI +RtlCommitMemoryStream( + _In_ struct IStream *This, + _In_ ULONG CommitFlags +); + +NTSYSAPI +HRESULT +NTAPI +RtlRevertMemoryStream( + _In_ struct IStream *This +); + +NTSYSAPI +HRESULT +NTAPI +RtlLockMemoryStreamRegion( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType +); + +NTSYSAPI +HRESULT +NTAPI +RtlUnlockMemoryStreamRegion( + _In_ struct IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType +); + +NTSYSAPI +HRESULT +NTAPI +RtlCloneMemoryStream( + _In_ struct IStream *This, + _Outptr_ struct IStream **ResultStream +); + +#endif // NTOS_MODE_USER + #ifdef __cplusplus } #endif diff --git a/include/ndk/rtltypes.h b/include/ndk/rtltypes.h index 825d62bc13f..7620c5c7f99 100644 --- a/include/ndk/rtltypes.h +++ b/include/ndk/rtltypes.h @@ -1559,6 +1559,44 @@ typedef struct _MESSAGE_RESOURCE_DATA #endif /* !NTOS_MODE_USER */ +#ifdef NTOS_MODE_USER + +// +// Memory Stream +// +#ifndef CONST_VTBL +#ifdef CONST_VTABLE +#define CONST_VTBL const +#else +#define CONST_VTBL +#endif +#endif + +struct IStreamVtbl; +struct IStream; +struct tagSTATSTG; + +typedef struct _RTL_MEMORY_STREAM RTL_MEMORY_STREAM, *PRTL_MEMORY_STREAM; + +typedef VOID +(NTAPI *PRTL_MEMORY_STREAM_FINAL_RELEASE_ROUTINE)( + _In_ PRTL_MEMORY_STREAM Stream +); + +struct _RTL_MEMORY_STREAM +{ + CONST_VTBL struct IStreamVtbl *Vtbl; + LONG RefCount; + ULONG Unk1; + PVOID Current; + PVOID Start; + PVOID End; + PRTL_MEMORY_STREAM_FINAL_RELEASE_ROUTINE FinalRelease; + HANDLE ProcessHandle; +}; + +#endif /* NTOS_MODE_USER */ + #ifdef __cplusplus } #endif diff --git a/include/reactos/idl/sam.idl b/include/reactos/idl/sam.idl index e9434ad25f1..7111d7f92b0 100644 --- a/include/reactos/idl/sam.idl +++ b/include/reactos/idl/sam.idl @@ -366,10 +366,10 @@ typedef [switch_type(DOMAIN_DISPLAY_INFORMATION)] union _SAMPR_DISPLAY_INFO_BUFF [case(DomainDisplayOemGroup)] SAMPR_DOMAIN_DISPLAY_OEM_GROUP_BUFFER OemGroupInformation; } SAMPR_DISPLAY_INFO_BUFFER, *PSAMPR_DISPLAY_INFO_BUFFER; -typedef struct _GROUP_ATTRIBUTE_INFORMATION +typedef struct _SAMPR_GROUP_ATTRIBUTE_INFORMATION { unsigned long Attributes; -} GROUP_ATTRIBUTE_INFORMATION, *PGROUP_ATTRIBUTE_INFORMATION; +} SAMPR_GROUP_ATTRIBUTE_INFORMATION, *PSAMPR_GROUP_ATTRIBUTE_INFORMATION; typedef struct _SAMPR_GROUP_GENERAL_INFORMATION { @@ -404,7 +404,7 @@ typedef [switch_type(GROUP_INFORMATION_CLASS)] union _SAMPR_GROUP_INFO_BUFFER { [case(GroupGeneralInformation)] SAMPR_GROUP_GENERAL_INFORMATION General; [case(GroupNameInformation)] SAMPR_GROUP_NAME_INFORMATION Name; - [case(GroupAttributeInformation)] GROUP_ATTRIBUTE_INFORMATION Attribute; + [case(GroupAttributeInformation)] SAMPR_GROUP_ATTRIBUTE_INFORMATION Attribute; [case(GroupAdminCommentInformation)] SAMPR_GROUP_ADM_COMMENT_INFORMATION AdminComment; [case(GroupReplicationInformation)] SAMPR_GROUP_GENERAL_INFORMATION DoNotUse; } SAMPR_GROUP_INFO_BUFFER, *PSAMPR_GROUP_INFO_BUFFER; diff --git a/lib/rtl/CMakeLists.txt b/lib/rtl/CMakeLists.txt index 56e698e14e4..e584c063a6e 100644 --- a/lib/rtl/CMakeLists.txt +++ b/lib/rtl/CMakeLists.txt @@ -33,6 +33,7 @@ list(APPEND SOURCE heapuser.c image.c interlck.c + memstream.c message.c largeint.c luid.c diff --git a/lib/rtl/memstream.c b/lib/rtl/memstream.c new file mode 100644 index 00000000000..776fbc64f77 --- /dev/null +++ b/lib/rtl/memstream.c @@ -0,0 +1,469 @@ +/* COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/rtl/mem.c + * PURPOSE: MemoryStream functions + * PROGRAMMER: David Quintana (gigaherz@gmail.com) + */ + +/* INCLUDES *******************************************************************/ + +#define COBJMACROS +#define CONST_VTABLE + +#include + +#define NDEBUG +#include + +/* VIRTUAL METHOD TABLES ******************************************************/ + +const struct IStreamVtbl RtlMemoryStreamVtbl = +{ + RtlQueryInterfaceMemoryStream, + RtlAddRefMemoryStream, + RtlReleaseMemoryStream, + RtlReadMemoryStream, + RtlWriteMemoryStream, + RtlSeekMemoryStream, + RtlSetMemoryStreamSize, + RtlCopyMemoryStreamTo, + RtlCommitMemoryStream, + RtlRevertMemoryStream, + RtlLockMemoryStreamRegion, + RtlUnlockMemoryStreamRegion, + RtlStatMemoryStream, + RtlCloneMemoryStream, +}; + +const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl = +{ + RtlQueryInterfaceMemoryStream, + RtlAddRefMemoryStream, + RtlReleaseMemoryStream, + RtlReadOutOfProcessMemoryStream, + RtlWriteMemoryStream, + RtlSeekMemoryStream, + RtlSetMemoryStreamSize, + RtlCopyMemoryStreamTo, + RtlCommitMemoryStream, + RtlRevertMemoryStream, + RtlLockMemoryStreamRegion, + RtlUnlockMemoryStreamRegion, + RtlStatMemoryStream, + RtlCloneMemoryStream, +}; + +/* FUNCTIONS ******************************************************************/ + +static +PRTL_MEMORY_STREAM +IStream_To_RTL_MEMORY_STREAM( + _In_ IStream *Interface) +{ + if (Interface == NULL) + return NULL; + + return CONTAINING_RECORD(Interface, RTL_MEMORY_STREAM, Vtbl); +} + +/* + * @implemented + */ +VOID +NTAPI +RtlInitMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream) +{ + RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); + Stream->Vtbl = &RtlMemoryStreamVtbl; +} + +/* + * @implemented + */ +VOID +NTAPI +RtlInitOutOfProcessMemoryStream( + _Out_ PRTL_MEMORY_STREAM Stream) +{ + RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); + Stream->Vtbl = &RtlOutOfProcessMemoryStreamVtbl; + Stream->FinalRelease = RtlFinalReleaseOutOfProcessMemoryStream; +} + +/* + * @unimplemented + */ +VOID +NTAPI +RtlFinalReleaseOutOfProcessMemoryStream( + _In_ PRTL_MEMORY_STREAM Stream) +{ + UNIMPLEMENTED; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlQueryInterfaceMemoryStream( + _In_ IStream *This, + _In_ REFIID RequestedIid, + _Outptr_ PVOID *ResultObject) +{ + if (IsEqualGUID(RequestedIid, &IID_IUnknown) || + IsEqualGUID(RequestedIid, &IID_ISequentialStream) || + IsEqualGUID(RequestedIid, &IID_IStream)) + { + IStream_AddRef(This); + *ResultObject = This; + return S_OK; + } + + *ResultObject = NULL; + return E_NOINTERFACE; +} + +/* + * @implemented + */ +ULONG +NTAPI +RtlAddRefMemoryStream( + _In_ IStream *This) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + return InterlockedIncrement(&Stream->RefCount); +} + +/* + * @implemented + */ +ULONG +NTAPI +RtlReleaseMemoryStream( + _In_ IStream *This) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + LONG Result; + + Result = InterlockedDecrement(&Stream->RefCount); + + if (Result == 0) + { + if (Stream->FinalRelease) + Stream->FinalRelease(Stream); + } + + return Result; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlReadMemoryStream( + _In_ IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead) +{ + ULONG CopyLength; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current; + + if (BytesRead) + *BytesRead = 0; + + if (!Length) + return S_OK; + + CopyLength = min(Available, Length); + + RtlMoveMemory(Buffer, Stream->Current, CopyLength); + + Stream->Current = (PUCHAR)Stream->Current + CopyLength; + + *BytesRead = CopyLength; + + return S_OK; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlReadOutOfProcessMemoryStream( + _In_ IStream *This, + _Out_writes_bytes_(Length) PVOID Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesRead) +{ + NTSTATUS Status; + ULONG CopyLength; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current; + + if (BytesRead) + *BytesRead = 0; + + if (!Length) + return S_OK; + + CopyLength = min(Available, Length); + + Status = NtReadVirtualMemory(Stream->ProcessHandle, + Stream->Current, + Buffer, + CopyLength, + BytesRead); + + if (NT_SUCCESS(Status)) + Stream->Current = (PUCHAR)Stream->Current + *BytesRead; + + return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status)); +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlSeekMemoryStream( + _In_ IStream *This, + _In_ LARGE_INTEGER RelativeOffset, + _In_ ULONG Origin, + _Out_opt_ PULARGE_INTEGER ResultOffset) +{ + PVOID NewPosition; + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + switch (Origin) + { + case STREAM_SEEK_SET: + NewPosition = (PUCHAR)Stream->Start + RelativeOffset.QuadPart; + break; + + case STREAM_SEEK_CUR: + NewPosition = (PUCHAR)Stream->Current + RelativeOffset.QuadPart; + break; + + case STREAM_SEEK_END: + NewPosition = (PUCHAR)Stream->End - RelativeOffset.QuadPart; + break; + + default: + return E_INVALIDARG; + } + + if (NewPosition < Stream->Start || NewPosition > Stream->End) + return STG_E_INVALIDPOINTER; + + Stream->Current = NewPosition; + + if (ResultOffset) + ResultOffset->QuadPart = (PUCHAR)Stream->Current - (PUCHAR)Stream->Start; + + return S_OK; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCopyMemoryStreamTo( + _In_ IStream *This, + _In_ IStream *Target, + _In_ ULARGE_INTEGER Length, + _Out_opt_ PULARGE_INTEGER BytesRead, + _Out_opt_ PULARGE_INTEGER BytesWritten) +{ + CHAR Buffer[1024]; + ULONGLONG TotalSize; + ULONG Left, Amount; + HRESULT Result; + + if (BytesRead) + BytesRead->QuadPart = 0; + if (BytesWritten) + BytesWritten->QuadPart = 0; + + if (!Target) + return S_OK; + + if (!Length.QuadPart) + return S_OK; + + /* Copy data */ + TotalSize = Length.QuadPart; + while (TotalSize) + { + Left = min(TotalSize, sizeof(Buffer)); + + /* Read */ + Result = IStream_Read(This, Buffer, Left, &Amount); + if (BytesRead) + BytesRead->QuadPart += Amount; + if (FAILED(Result) || Amount == 0) + break; + + Left = Amount; + + /* Write */ + Result = IStream_Write(Target, Buffer, Left, &Amount); + if (BytesWritten) + BytesWritten->QuadPart += Amount; + if (FAILED(Result) || Amount != Left) + break; + + TotalSize -= Left; + } + return Result; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlStatMemoryStream( + _In_ IStream *This, + _Out_ STATSTG *Stats, + _In_ ULONG Flags) +{ + PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); + + if (!Stats) + return STG_E_INVALIDPOINTER; + + RtlZeroMemory(Stats, sizeof(STATSTG)); + Stats->type = STGTY_STREAM; + Stats->cbSize.QuadPart = (PUCHAR)Stream->End - (PUCHAR)Stream->Start; + + return S_OK; +} + +/* DUMMY FUNCTIONS ************************************************************/ +/* + * The following functions return E_NOTIMPL in Windows Server 2003. + */ + +/* + * @implemented + */ +HRESULT +NTAPI +RtlWriteMemoryStream( + _In_ IStream *This, + _In_reads_bytes_(Length) CONST VOID *Buffer, + _In_ ULONG Length, + _Out_opt_ PULONG BytesWritten) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Buffer); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(BytesWritten); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlSetMemoryStreamSize( + _In_ IStream *This, + _In_ ULARGE_INTEGER NewSize) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(NewSize); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCommitMemoryStream( + _In_ IStream *This, + _In_ ULONG CommitFlags) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(CommitFlags); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlRevertMemoryStream( + _In_ IStream *This) +{ + UNREFERENCED_PARAMETER(This); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlLockMemoryStreamRegion( + _In_ IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Offset); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(LockType); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlUnlockMemoryStreamRegion( + _In_ IStream *This, + _In_ ULARGE_INTEGER Offset, + _In_ ULARGE_INTEGER Length, + _In_ ULONG LockType) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(Offset); + UNREFERENCED_PARAMETER(Length); + UNREFERENCED_PARAMETER(LockType); + + return E_NOTIMPL; +} + +/* + * @implemented + */ +HRESULT +NTAPI +RtlCloneMemoryStream( + _In_ IStream *This, + _Outptr_ IStream **ResultStream) +{ + UNREFERENCED_PARAMETER(This); + UNREFERENCED_PARAMETER(ResultStream); + + return E_NOTIMPL; +} diff --git a/ntoskrnl/include/internal/i386/asmmacro.S b/ntoskrnl/include/internal/i386/asmmacro.S index cf338d32338..2ab3bdfd6ff 100644 --- a/ntoskrnl/include/internal/i386/asmmacro.S +++ b/ntoskrnl/include/internal/i386/asmmacro.S @@ -241,6 +241,7 @@ ENDM #define KI_EXIT_RET HEX(080) #define KI_EXIT_IRET HEX(100) #define KI_EDITED_FRAME HEX(200) +#define KI_EXIT_RET8 HEX(400) #define KI_RESTORE_VOLATILES (KI_RESTORE_EAX OR KI_RESTORE_ECX_EDX) MACRO(KiTrapExitStub, Name, Flags) @@ -248,16 +249,16 @@ MACRO(KiTrapExitStub, Name, Flags) PUBLIC @&Name&@4 @&Name&@4: - if (Flags AND KI_RESTORE_EFLAGS) - - /* We will pop EFlags off the stack */ - OffsetEsp = KTRAP_FRAME_EFLAGS - - elseif (Flags AND KI_EXIT_IRET) + if (Flags AND KI_EXIT_RET8) OR (Flags AND KI_EXIT_IRET) /* This is the IRET frame */ OffsetEsp = KTRAP_FRAME_EIP + elseif (Flags AND KI_RESTORE_EFLAGS) + + /* We will pop EFlags off the stack */ + OffsetEsp = KTRAP_FRAME_EFLAGS + else OffsetEsp = 0 @@ -335,6 +336,13 @@ PUBLIC @&Name&@4 if (Flags AND KI_RESTORE_EFLAGS) + if (Flags AND KI_EXIT_RET8) + + /* We are at the IRET frame, so push EFLAGS first */ + push dword ptr [esp + 8] + + endif + /* Restore EFLAGS */ popfd @@ -357,6 +365,11 @@ PUBLIC @&Name&@4 /* Return to kernel mode with a jmp */ jmp edx + elseif (Flags AND KI_EXIT_RET8) + + /* Return to kernel mode with a ret 8 */ + ret 8 + elseif (Flags AND KI_EXIT_RET) /* Return to kernel mode with a ret */ diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index 47da49fcea1..f0343c521a8 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -383,13 +383,13 @@ KeI386VdmInitialize( ULONG_PTR NTAPI Ki386EnableGlobalPage( - IN volatile ULONG_PTR Context + IN ULONG_PTR Context ); ULONG_PTR NTAPI Ki386EnableTargetLargePage( - IN volatile ULONG_PTR Context + IN ULONG_PTR Context ); BOOLEAN diff --git a/ntoskrnl/include/internal/i386/mm.h b/ntoskrnl/include/internal/i386/mm.h index 72bbcec2552..27237a67a2b 100644 --- a/ntoskrnl/include/internal/i386/mm.h +++ b/ntoskrnl/include/internal/i386/mm.h @@ -96,11 +96,11 @@ PULONG MmGetPageDirectory(VOID); #define MI_MAPPING_RANGE_START (ULONG)HYPER_SPACE #define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + \ MI_HYPERSPACE_PTES * PAGE_SIZE) -#define MI_DUMMY_PTE (PMMPTE)(MI_MAPPING_RANGE_END + \ +#define MI_DUMMY_PTE (PMMPTE)((ULONG_PTR)MI_MAPPING_RANGE_END + \ PAGE_SIZE) -#define MI_VAD_BITMAP (PMMPTE)(MI_DUMMY_PTE + \ +#define MI_VAD_BITMAP (PMMPTE)((ULONG_PTR)MI_DUMMY_PTE + \ PAGE_SIZE) -#define MI_WORKING_SET_LIST (PMMPTE)(MI_VAD_BITMAP + \ +#define MI_WORKING_SET_LIST (PMMPTE)((ULONG_PTR)MI_VAD_BITMAP + \ PAGE_SIZE) /* On x86, these two are the same */ diff --git a/ntoskrnl/include/internal/i386/trap_x.h b/ntoskrnl/include/internal/i386/trap_x.h index d83276fb165..d6081c20d12 100644 --- a/ntoskrnl/include/internal/i386/trap_x.h +++ b/ntoskrnl/include/internal/i386/trap_x.h @@ -163,7 +163,7 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame, } /* Check DR values */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame)) { /* Check for active debugging */ if (KeGetCurrentThread()->Header.DebugActive) @@ -244,6 +244,7 @@ DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame DECLSPEC_NORETURN VOID FASTCALL KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame); DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame); +DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegmentsRet8(IN PKTRAP_FRAME TrapFrame); typedef ATTRIB_NORETURN @@ -382,7 +383,7 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame) TrapFrame->Dr7 = 0; /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Check for active debugging */ @@ -411,7 +412,7 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame) TrapFrame->Dr7 = 0; /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Check for active debugging */ diff --git a/ntoskrnl/include/internal/ke.h b/ntoskrnl/include/internal/ke.h index 78dfe6897e4..d90cf1b0eb8 100644 --- a/ntoskrnl/include/internal/ke.h +++ b/ntoskrnl/include/internal/ke.h @@ -1050,6 +1050,14 @@ KiCallUserMode( IN PULONG OutputLength ); +DECLSPEC_NORETURN +VOID +FASTCALL +KiCallbackReturn( + IN PVOID Stack, + IN NTSTATUS Status +); + VOID NTAPI KiInitMachineDependent(VOID); diff --git a/ntoskrnl/ke/i386/cpu.c b/ntoskrnl/ke/i386/cpu.c index 3b8f1fad176..2d741ab6144 100644 --- a/ntoskrnl/ke/i386/cpu.c +++ b/ntoskrnl/ke/i386/cpu.c @@ -1535,7 +1535,7 @@ KeFlushEntireTb(IN BOOLEAN Invalid, if (TargetAffinity) { /* Sanity check */ - ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb()); + ASSERT(Prcb == KeGetCurrentPrcb()); /* FIXME: TODO */ ASSERTMSG("Not yet implemented\n", FALSE); diff --git a/ntoskrnl/ke/i386/exp.c b/ntoskrnl/ke/i386/exp.c index eaacf4ea6a3..976d2ebddc7 100644 --- a/ntoskrnl/ke/i386/exp.c +++ b/ntoskrnl/ke/i386/exp.c @@ -137,7 +137,7 @@ NTAPI KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame) { /* Check if this is user-mode or V86 */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Return it directly */ @@ -175,7 +175,7 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame, Previous = KiEspFromTrapFrame(TrapFrame); /* Check if this is user-mode or V86 */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Write it directly */ @@ -225,7 +225,7 @@ KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame) /* Just return it */ return TrapFrame->HardwareSegSs; } - else if (TrapFrame->SegCs & MODE_MASK) + else if (KiUserTrap(TrapFrame)) { /* User mode, return the User SS */ return TrapFrame->HardwareSegSs | RPL_MASK; @@ -251,7 +251,7 @@ KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame, /* Just write it */ TrapFrame->HardwareSegSs = Ss; } - else if (TrapFrame->SegCs & MODE_MASK) + else if (KiUserTrap(TrapFrame)) { /* Usermode, save the User SS */ TrapFrame->HardwareSegSs = Ss | RPL_MASK; @@ -398,7 +398,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, TrapFrame->V86Fs = Context->SegFs; TrapFrame->V86Gs = Context->SegGs; } - else if (!(TrapFrame->SegCs & MODE_MASK)) + else if (!KiUserTrap(TrapFrame)) { /* For kernel mode, write the standard values */ TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK; @@ -429,7 +429,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, /* Handle the extended registers */ if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) == - CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame)) { /* Get the FX Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -463,7 +463,7 @@ KeContextToTrapFrame(IN PCONTEXT Context, /* Handle the floating point state */ if (((ContextFlags & CONTEXT_FLOATING_POINT) == - CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame)) { /* Get the FX Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -692,7 +692,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, /* Handle extended registers */ if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) == - CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame)) { /* Get the FX Save Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -712,7 +712,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame, /* Handle Floating Point */ if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) == - CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK)) + CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame)) { /* Get the FX Save Area */ FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1); @@ -1045,6 +1045,13 @@ DispatchToUser: } } _SEH2_END; + + DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n", + PsGetCurrentProcess()->ImageFileName, + ExceptionRecord->ExceptionCode, + ExceptionRecord->ExceptionAddress, + ExceptionRecord->ExceptionInformation[0], + ExceptionRecord->ExceptionInformation[1]); } /* Try second chance */ @@ -1060,11 +1067,13 @@ DispatchToUser: } /* 3rd strike, kill the process */ - DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p\n", + DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n", PsGetCurrentProcess()->ImageFileName, ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress, - PsGetCurrentProcess()->SectionBaseAddress); + PsGetCurrentProcess()->SectionBaseAddress, + ExceptionRecord->ExceptionInformation[0], + ExceptionRecord->ExceptionInformation[1]); ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode); KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED, diff --git a/ntoskrnl/ke/i386/patpge.c b/ntoskrnl/ke/i386/patpge.c index 41b474ae0e9..1e598ce355a 100644 --- a/ntoskrnl/ke/i386/patpge.c +++ b/ntoskrnl/ke/i386/patpge.c @@ -20,9 +20,9 @@ ULONG_PTR NTAPI INIT_FUNCTION -Ki386EnableGlobalPage(IN volatile ULONG_PTR Context) +Ki386EnableGlobalPage(IN ULONG_PTR Context) { - volatile PLONG Count = (PLONG)Context; + PLONG Count = (PLONG)Context; ULONG Cr4, Cr3; /* Disable interrupts */ @@ -144,7 +144,7 @@ Ki386IdentityMapMakeValid(PLARGE_IDENTITY_MAP IdentityMap, if (PageTable) *PageTable = (PHARDWARE_PTE)(Pde->PageFrameNumber << PAGE_SHIFT); } - + return TRUE; } @@ -172,7 +172,7 @@ Ki386MapAddress(PLARGE_IDENTITY_MAP IdentityMap, /* Get PTE of VirtualPtr, make it valid, and map PhysicalPtr there */ Pte = &PageTable[(VirtualPtr >> 12) & ((1 << PTE_BITS) - 1)]; Pte->Valid = 1; - Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT; + Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT); return TRUE; } @@ -189,7 +189,7 @@ Ki386ConvertPte(PHARDWARE_PTE Pte) PhysicalPtr = MmGetPhysicalAddress(VirtualPtr); /* Map its physical address in the page table provided by the caller */ - Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT; + Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT); } BOOLEAN diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s index 6817995ca35..272886d4891 100644 --- a/ntoskrnl/ke/i386/trap.s +++ b/ntoskrnl/ke/i386/trap.s @@ -166,6 +166,7 @@ KiTrapExitStub KiSystemCallTrapReturn, (KI_RESTORE_EAX OR KI_RESTORE_FS OR KI KiTrapExitStub KiEditedTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EDITED_FRAME OR KI_EXIT_RET) KiTrapExitStub KiTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_SEGMENTS OR KI_EXIT_IRET) KiTrapExitStub KiTrapReturnNoSegments, (KI_RESTORE_VOLATILES OR KI_EXIT_IRET) +KiTrapExitStub KiTrapReturnNoSegmentsRet8,(KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EXIT_RET8) #ifdef _MSC_VER EXTERN _PsConvertToGuiThread@0:PROC diff --git a/ntoskrnl/ke/i386/traphdlr.c b/ntoskrnl/ke/i386/traphdlr.c index 46b925aab24..e761cd0d82a 100644 --- a/ntoskrnl/ke/i386/traphdlr.c +++ b/ntoskrnl/ke/i386/traphdlr.c @@ -100,7 +100,7 @@ KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode) if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0)) { /* Check if the frame was from user mode or v86 mode */ - if ((TrapFrame->SegCs & MODE_MASK) || + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) { /* Handle debug registers */ @@ -124,13 +124,13 @@ KiEoiHelper(IN PKTRAP_FRAME TrapFrame) if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame); /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame); + if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame); /* Check for edited frame */ if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame); /* Exit the trap to kernel mode */ - KiTrapReturnNoSegments(TrapFrame); + KiTrapReturnNoSegmentsRet8(TrapFrame); } DECLSPEC_NORETURN @@ -152,7 +152,7 @@ KiServiceExit(IN PKTRAP_FRAME TrapFrame, KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode; /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame)) { /* Check if we were single stepping */ if (TrapFrame->EFlags & EFLAGS_TF) @@ -186,13 +186,13 @@ KiServiceExit2(IN PKTRAP_FRAME TrapFrame) if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame); /* Check for user mode exit */ - if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame); + if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame); /* Check for edited frame */ if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame); /* Exit the trap to kernel mode */ - KiTrapReturnNoSegments(TrapFrame); + KiTrapReturnNoSegmentsRet8(TrapFrame); } @@ -1250,10 +1250,10 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame) /* Call the access fault handler */ Status = MmAccessFault(TrapFrame->ErrCode & 1, (PVOID)Cr2, - TrapFrame->SegCs & MODE_MASK, + KiUserTrap(TrapFrame), TrapFrame); if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame); - + /* Check for syscall fault */ #if 0 if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) || @@ -1541,7 +1541,7 @@ KiSystemCall(IN PKTRAP_FRAME TrapFrame, TrapFrame->Dr7 = 0; /* Check if the frame was from user mode */ - if (TrapFrame->SegCs & MODE_MASK) + if (KiUserTrap(TrapFrame)) { /* Check for active debugging */ if (KeGetCurrentThread()->Header.DebugActive & 0xFF) diff --git a/ntoskrnl/ke/i386/usercall.c b/ntoskrnl/ke/i386/usercall.c index 9363c6fed5f..8876da053aa 100644 --- a/ntoskrnl/ke/i386/usercall.c +++ b/ntoskrnl/ke/i386/usercall.c @@ -67,7 +67,7 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame, _SEH2_TRY { /* Sanity check */ - ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode); + ASSERT(KiUserTrap(TrapFrame)); /* Get the aligned size */ AlignedEsp = Context.Esp & ~3; @@ -210,7 +210,7 @@ KeUserModeCallback(IN ULONG RoutineIndex, } -/* +/* * Stack layout for KiUserModeCallout: * ---------------------------------- * KCALLOUT_FRAME.ResultLength <= 2nd Parameter to KiCallUserMode @@ -351,5 +351,140 @@ KiUserModeCallout(PKCALLOUT_FRAME CalloutFrame) KiServiceExit(CallbackTrapFrame, 0); } +/*++ + * @name NtCallbackReturn + * + * The NtCallbackReturn routine returns to kernel mode after a user-mode + * callback was done through KeUserModeCallback. It uses the callback frame + * which was setup in order to return the information, restores the stack, + * and resumes execution where it was left off. + * + * @param Result + * Pointer to a caller-allocated buffer where the return data + * from the user-mode function is located. + * + * @param ResultLength + * Size of the Output Buffer described above. + * + * @param CallbackStatus + * Status code of the callback operation. + * + * @return Status code of the callback operation. + * + * @remark This call MUST be paired with KeUserModeCallback. + * + *--*/ +NTSTATUS +NTAPI +NtCallbackReturn( + _In_ PVOID Result, + _In_ ULONG ResultLength, + _In_ NTSTATUS CallbackStatus) +{ + PKTHREAD CurrentThread; + PKCALLOUT_FRAME CalloutFrame; + PKTRAP_FRAME CallbackTrapFrame, TrapFrame; + PFX_SAVE_AREA FxSaveArea, CbFxSaveArea; + ULONG Size; + PKPCR Pcr; + PKTSS Tss; + + /* Get the current thread and make sure we have a callback stack */ + CurrentThread = KeGetCurrentThread(); + CalloutFrame = CurrentThread->CallbackStack; + if (CalloutFrame == NULL) + { + return STATUS_NO_CALLBACK_ACTIVE; + } + + /* Get the trap frame */ + CallbackTrapFrame = CurrentThread->TrapFrame; + + /* Restore the exception list */ + Pcr = KeGetPcr(); + Pcr->NtTib.ExceptionList = CallbackTrapFrame->ExceptionList; + + /* Store the results in the callback stack */ + *((PVOID*)CalloutFrame->Result) = Result; + *((ULONG*)CalloutFrame->ResultLength) = ResultLength; + + /* Disable interrupts for NPX save and stack switch */ + _disable(); + + /* Set desination and origin NPX Frames */ + CbFxSaveArea = (PVOID)((ULONG)CurrentThread->InitialStack - sizeof(FX_SAVE_AREA)); + FxSaveArea = (PVOID)(CalloutFrame->InitialStack - sizeof(FX_SAVE_AREA)); + + /* Now copy back NPX State */ + FxSaveArea->U.FnArea.ControlWord = CbFxSaveArea->U.FnArea.ControlWord; + FxSaveArea->U.FnArea.StatusWord = CbFxSaveArea->U.FnArea.StatusWord; + FxSaveArea->U.FnArea.TagWord = CbFxSaveArea->U.FnArea.TagWord; + FxSaveArea->U.FnArea.DataSelector = CbFxSaveArea->U.FnArea.DataSelector; + FxSaveArea->Cr0NpxState = CbFxSaveArea->Cr0NpxState; + + /* Get the previous trap frame */ + TrapFrame = (PKTRAP_FRAME)CalloutFrame->TrapFrame; + + /* Check if we failed in user mode */ + if (CallbackStatus == STATUS_CALLBACK_POP_STACK) + { + /* Check if we came from v86 mode */ + if (CallbackTrapFrame->EFlags & EFLAGS_V86_MASK) + { + Size = sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, SegFs); + } + else + { + Size = FIELD_OFFSET(KTRAP_FRAME, V86Es) - FIELD_OFFSET(KTRAP_FRAME, SegFs); + } + + /* Copy back part of the trap frame */ + RtlCopyMemory(&TrapFrame->SegFs, &CallbackTrapFrame->SegFs, Size); + } + + /* Clear DR7 */ + TrapFrame->Dr7 = 0; + + /* Check if debugging was active */ + if (CurrentThread->Header.DebugActive & 0xFF) + { + /* Copy debug registers data from it */ + TrapFrame->Dr0 = CallbackTrapFrame->Dr0; + TrapFrame->Dr1 = CallbackTrapFrame->Dr1; + TrapFrame->Dr2 = CallbackTrapFrame->Dr2; + TrapFrame->Dr3 = CallbackTrapFrame->Dr3; + TrapFrame->Dr6 = CallbackTrapFrame->Dr6; + TrapFrame->Dr7 = CallbackTrapFrame->Dr7; + } + + /* Get TSS */ + Tss = Pcr->TSS; + + /* Check for V86 mode */ + if (TrapFrame->EFlags & EFLAGS_V86_MASK) + { + /* Set new stack address in TSS (full trap frame) */ + Tss->Esp0 = (ULONG_PTR)(TrapFrame + 1); + } + else + { + /* Set new stack address in TSS (non-V86 trap frame) */ + Tss->Esp0 = (ULONG_PTR)&TrapFrame->V86Es; + } + + /* Get the initial stack and restore it */ + CurrentThread->InitialStack = (PVOID)CalloutFrame->InitialStack; + + /* Restore the trap frame and the previous callback stack */ + CurrentThread->TrapFrame = TrapFrame; + CurrentThread->CallbackStack = (PVOID)CalloutFrame->CallbackStack; + + /* Bring interrupts back */ + _enable(); + + /* Now switch back to the old stack */ + KiCallbackReturn(&CalloutFrame->Edi, CallbackStatus); +} + /* EOF */ diff --git a/ntoskrnl/ke/i386/usercall_asm.S b/ntoskrnl/ke/i386/usercall_asm.S index 2a48a5f4f8d..5b2fbd07540 100644 --- a/ntoskrnl/ke/i386/usercall_asm.S +++ b/ntoskrnl/ke/i386/usercall_asm.S @@ -76,184 +76,22 @@ _KiCallUserMode@8: ret 8 -/*++ - * @name NtCallbackReturn - * - * The NtCallbackReturn routine returns to kernel mode after a user-mode - * callback was done through KeUserModeCallback. It uses the callback frame - * which was setup in order to return the information, restores the stack, - * and resumes execution where it was left off. - * - * @param Result - * Pointer to a caller-allocated buffer where the return data - * from the user-mode function is located. - * - * @param ResultLength - * Size of the Output Buffer described above. - * - * @param CallbackStatus - * Status code of the callback operation. - * - * @return Status code of the callback operation. - * - * @remark This call MUST be paired with KeUserModeCallback. - * - *--*/ -PUBLIC _NtCallbackReturn@12 -_NtCallbackReturn@12: - /* Get the current thread and make sure we have a callback stack */ - mov eax, fs:[KPCR_CURRENT_THREAD] - mov ecx, [eax+KTHREAD_CALLBACK_STACK] - test ecx, ecx - jz NoStack +PUBLIC @KiCallbackReturn@8 +@KiCallbackReturn@8: - /* Get the trap frame */ - mov ebx, [eax+KTHREAD_TRAP_FRAME] - - /* Restore the exception list */ - mov edx, [ebx+KTRAP_FRAME_EXCEPTION_LIST] - mov fs:[KPCR_EXCEPTION_LIST], edx - - /* Get the result, the result length and the status */ - mov edi, [esp+4] - mov esi, [esp+8] - mov ebp, [esp+12] - - /* Store the results in the callback stack */ - mov ebx, [ecx+CBSTACK_RESULT] - mov [ebx], edi - mov ebx, [ecx+CBSTACK_RESULT_LENGTH] - mov [ebx], esi - - /* Get the previous stack */ - mov ebx, [ecx] - - /* Disable interrupts for NPX save and stack switch */ - cli - - /* Get the initial stack and restore it */ - mov esi, [eax+KTHREAD_INITIAL_STACK] - mov [eax+KTHREAD_INITIAL_STACK], ebx - - /* Set desination and origin NPX Frames */ - sub esi, NPX_FRAME_LENGTH - sub ebx, NPX_FRAME_LENGTH - - /* Copy NPX Data */ - mov edx, [esi+FP_CONTROL_WORD] - mov [ebx+FP_CONTROL_WORD], edx - mov edx, [esi+FP_STATUS_WORD] - mov [ebx+FP_STATUS_WORD], edx - mov edx, [esi+FP_TAG_WORD] - mov [ebx+FP_TAG_WORD], edx - mov edx, [esi+FP_DATA_SELECTOR] - mov [ebx+FP_DATA_SELECTOR], edx - mov edx, [esi+FN_CR0_NPX_STATE] - mov [ebx+FN_CR0_NPX_STATE], edx - - /* Check if we failed in user mode */ - cmp ebp, STATUS_CALLBACK_POP_STACK - mov edi, [ecx+CBSTACK_TRAP_FRAME] - jz UserFault - -CheckDebug: - - /* Clear DR7 */ - and dword ptr [edi+KTRAP_FRAME_DR7], 0 - - /* Check if debugging was active */ - test byte ptr [eax+KTHREAD_DEBUG_ACTIVE], HEX(0FF) - jnz RestoreDebug - -RestoreStack: - - /* Get TSS */ - mov edx, fs:[KPCR_TSS] - - /* Restore stack pointer */ - lea esp, [ecx+CBSTACK_CALLBACK_STACK] - - /* Check if we were in V86 mode */ - test dword ptr [edi+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK - jnz V86Ret - sub ebx, 16 - -V86Ret: - /* Restore the ESP in TSS */ - mov [edx+KTSS_ESP0], ebx - - /* Restore the trap frame */ - mov [eax+KTHREAD_TRAP_FRAME], edi - - /* Bring interrupts back */ - sti - - /* Restore the callback stack*/ - pop [eax+KTHREAD_CALLBACK_STACK] + /* Restore the stack */ + mov esp, ecx /* Set status and return */ - mov eax, ebp + mov eax, edx pop edi pop esi pop ebx pop ebp - pop edx - /* Clean stack and jump back */ - add esp, 8 - jmp edx - -UserFault: - /* Set size to copy */ - mov ecx, (KTRAP_FRAME_V86_ES - KTRAP_FRAME_FS) / 4 - - /* Check if this was V86 mode */ - mov esi, [eax+KTHREAD_TRAP_FRAME] - test dword ptr [esi+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK - - /* Save EDI and load destination */ - mov edx, edi - lea edi, [edi+KTRAP_FRAME_FS] - jz NotV86 - add ecx, 16 / 4 - -NotV86: - /* Set source and copy */ - lea esi, [esi+KTRAP_FRAME_FS] - rep movsd - - /* Restore ECX and ECX */ - mov ecx, [eax+KTHREAD_CALLBACK_STACK] - mov edi, edx - jmp CheckDebug - -RestoreDebug: - /* Get a pointer to thread's trap frame */ - mov esi, [eax+KTHREAD_TRAP_FRAME] - - /* Copy debug registers data from it */ - mov edx, [esi+KTRAP_FRAME_DR0] - mov [edi+KTRAP_FRAME_DR0], edx - mov edx, [esi+KTRAP_FRAME_DR1] - mov [edi+KTRAP_FRAME_DR1], edx - mov edx, [esi+KTRAP_FRAME_DR2] - mov [edi+KTRAP_FRAME_DR2], edx - mov edx, [esi+KTRAP_FRAME_DR3] - mov [edi+KTRAP_FRAME_DR3], edx - mov edx, [esi+KTRAP_FRAME_DR6] - mov [edi+KTRAP_FRAME_DR6], edx - mov edx, [esi+KTRAP_FRAME_DR7] - mov [edi+KTRAP_FRAME_DR7], edx - - /* Jump back */ - jmp RestoreStack - -NoStack: - - /* Return failure */ - mov eax, STATUS_NO_CALLBACK_ACTIVE - ret 12 + /* Clean stack and return */ + ret 8 /*++ * @name KeSwitchKernelStack diff --git a/ntoskrnl/ke/time.c b/ntoskrnl/ke/time.c index 531cc85bb0f..e6bdd9ed4d9 100644 --- a/ntoskrnl/ke/time.c +++ b/ntoskrnl/ke/time.c @@ -153,7 +153,7 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame, /* Check if we came from user mode */ #ifndef _M_ARM - if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) + if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) #else if (TrapFrame->PreviousMode == UserMode) #endif diff --git a/win32ss/gdi/ntgdi/gdiobj.c b/win32ss/gdi/ntgdi/gdiobj.c index a5d75bba98c..740fd92363c 100644 --- a/win32ss/gdi/ntgdi/gdiobj.c +++ b/win32ss/gdi/ntgdi/gdiobj.c @@ -222,7 +222,7 @@ InitGdiHandleTable(void) FORCEINLINE VOID -IncrementGdiHandleCount(void) +IncrementCurrentProcessGdiHandleCount(void) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount); @@ -230,12 +230,42 @@ IncrementGdiHandleCount(void) FORCEINLINE VOID -DecrementGdiHandleCount(void) +DecrementCurrentProcessGdiHandleCount(void) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount); } +FORCEINLINE +VOID +IncrementGdiHandleCount(ULONG ulProcessId) +{ + PEPROCESS pep; + PPROCESSINFO ppi; + NTSTATUS Status; + + Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep); + NT_ASSERT(NT_SUCCESS(Status)); + + ppi = PsGetProcessWin32Process(pep); + if (ppi) InterlockedIncrement((LONG*)&ppi->GDIHandleCount); +} + +FORCEINLINE +VOID +DecrementGdiHandleCount(ULONG ulProcessId) +{ + PEPROCESS pep; + PPROCESSINFO ppi; + NTSTATUS Status; + + Status = PsLookupProcessByProcessId(ULongToHandle(ulProcessId), &pep); + NT_ASSERT(NT_SUCCESS(Status)); + + ppi = PsGetProcessWin32Process(pep); + if (ppi) InterlockedDecrement((LONG*)&ppi->GDIHandleCount); +} + static PENTRY ENTRY_pentPopFreeEntry(VOID) @@ -497,7 +527,7 @@ GDIOBJ_vDereferenceObject(POBJ pobj) /* Decrement the process handle count */ ASSERT(gpentHmgr[ulIndex].ObjectOwner.ulObj == HandleToUlong(PsGetCurrentProcessId())); - DecrementGdiHandleCount(); + DecrementCurrentProcessGdiHandleCount(); } /* Push entry to the free list */ @@ -710,7 +740,7 @@ GDIOBJ_hInsertObject( if (ulOwner == GDI_OBJ_HMGR_POWNED) { /* Increment the process handle count */ - IncrementGdiHandleCount(); + IncrementCurrentProcessGdiHandleCount(); /* Use Process id */ ulOwner = HandleToUlong(PsGetCurrentProcessId()); @@ -729,50 +759,64 @@ VOID NTAPI GDIOBJ_vSetObjectOwner( POBJ pobj, - ULONG ulOwner) + ULONG ulNewOwner) { PENTRY pentry; + ULONG ulOldOwner; /* This is a ugly HACK, needed to fix IntGdiSetDCOwnerEx */ if (GDI_HANDLE_IS_STOCKOBJ(pobj->hHmgr)) { - DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulOwner); + DPRINT("Trying to set ownership of stock object %p to %lx\n", pobj->hHmgr, ulNewOwner); return; } /* Get the handle entry */ - ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr)); + NT_ASSERT(GDI_HANDLE_GET_INDEX(pobj->hHmgr)); pentry = &gpentHmgr[GDI_HANDLE_GET_INDEX(pobj->hHmgr)]; + /* Check if the new owner is the same as the old one */ + ulOldOwner = pentry->ObjectOwner.ulObj; + if (ulOldOwner == ulNewOwner) + { + /* Nothing to do */ + return; + } + /* Is the current process requested? */ - if (ulOwner == GDI_OBJ_HMGR_POWNED) + if (ulNewOwner == GDI_OBJ_HMGR_POWNED) { /* Use process id */ - ulOwner = HandleToUlong(PsGetCurrentProcessId()); - if (pentry->ObjectOwner.ulObj != ulOwner) - { - IncrementGdiHandleCount(); - } + ulNewOwner = HandleToUlong(PsGetCurrentProcessId()); } // HACK - if (ulOwner == GDI_OBJ_HMGR_NONE) - ulOwner = GDI_OBJ_HMGR_PUBLIC; + if (ulNewOwner == GDI_OBJ_HMGR_NONE) + ulNewOwner = GDI_OBJ_HMGR_PUBLIC; - if (ulOwner == GDI_OBJ_HMGR_PUBLIC || - ulOwner == GDI_OBJ_HMGR_NONE) + /* Was the object process owned? */ + if ((ulOldOwner != GDI_OBJ_HMGR_PUBLIC) && + (ulOldOwner != GDI_OBJ_HMGR_NONE)) + { + /* Decrement the previous owners handle count */ + DecrementGdiHandleCount(ulOldOwner); + } + + /* Is the new owner a process? */ + if ((ulNewOwner != GDI_OBJ_HMGR_PUBLIC) && + (ulNewOwner != GDI_OBJ_HMGR_NONE)) + { + /* Increment the new owners handle count */ + IncrementGdiHandleCount(ulNewOwner); + } + else { /* Make sure we don't leak user mode memory */ - ASSERT(pentry->pUser == NULL); - if (pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_PUBLIC && - pentry->ObjectOwner.ulObj != GDI_OBJ_HMGR_NONE) - { - DecrementGdiHandleCount(); - } + NT_ASSERT(pentry->pUser == NULL); } /* Set new owner */ - pentry->ObjectOwner.ulObj = ulOwner; + pentry->ObjectOwner.ulObj = ulNewOwner; DBG_LOGEVENT(&pobj->slhLog, EVENT_SET_OWNER, 0); } @@ -970,9 +1014,10 @@ GreGetObjectOwner(HGDIOBJ hobj) BOOL NTAPI -GreSetObjectOwner( +GreSetObjectOwnerEx( HGDIOBJ hobj, - ULONG ulOwner) + ULONG ulOwner, + ULONG Flags) { PENTRY pentry; @@ -984,7 +1029,7 @@ GreSetObjectOwner( } /* Reference the handle entry */ - pentry = ENTRY_ReferenceEntryByHandle(hobj, 0); + pentry = ENTRY_ReferenceEntryByHandle(hobj, Flags); if (!pentry) { DPRINT("GreSetObjectOwner: Invalid handle 0x%p.\n", hobj); @@ -1000,6 +1045,15 @@ GreSetObjectOwner( return TRUE; } +BOOL +NTAPI +GreSetObjectOwner( + HGDIOBJ hobj, + ULONG ulOwner) +{ + return GreSetObjectOwnerEx(hobj, ulOwner, 0); +} + INT NTAPI GreGetObject( diff --git a/win32ss/gdi/ntgdi/gdiobj.h b/win32ss/gdi/ntgdi/gdiobj.h index b459a0cbc79..5eb30a3ea7d 100644 --- a/win32ss/gdi/ntgdi/gdiobj.h +++ b/win32ss/gdi/ntgdi/gdiobj.h @@ -93,6 +93,13 @@ GreSetObjectOwner( HGDIOBJ hobj, ULONG ulOwner); +BOOL +NTAPI +GreSetObjectOwnerEx( + HGDIOBJ hobj, + ULONG ulOwner, + ULONG Flags); + INT NTAPI GreGetObject( diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 1677a769216..862fae52cce 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1571,6 +1571,7 @@ NtUserCloseWindowStation( typedef enum _CONSOLECONTROL { GuiConsoleWndClassAtom, + ConsoleMakePalettePublic = 5, ConsoleAcquireDisplayOwnership, } CONSOLECONTROL, *PCONSOLECONTROL; @@ -1579,7 +1580,7 @@ APIENTRY NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength); + IN ULONG ConsoleCtrlInfoLength); HANDLE NTAPI diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c index e67ac78aee1..8b073dc0dcf 100644 --- a/win32ss/user/ntuser/desktop.c +++ b/win32ss/user/ntuser/desktop.c @@ -28,7 +28,7 @@ IntFreeDesktopHeap(IN PDESKTOP pdesk); /* Currently active desktop */ PDESKTOP gpdeskInputDesktop = NULL; HDC ScreenDeviceContext = NULL; -PTHREADINFO gptiDesktopThread; +PTHREADINFO gptiDesktopThread = NULL; HCURSOR gDesktopCursor = NULL; /* OBJECT CALLBACKS **********************************************************/ @@ -834,6 +834,9 @@ VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam) return; } + // Allow other devices have a shot at foreground. + if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL; + // FIXME: System Tray Support. HwndList = UserBuildShellHookHwndList(Desktop); diff --git a/win32ss/user/ntuser/desktop.h b/win32ss/user/ntuser/desktop.h index 25e1f9e331c..9d2fd2ef284 100644 --- a/win32ss/user/ntuser/desktop.h +++ b/win32ss/user/ntuser/desktop.h @@ -69,9 +69,10 @@ typedef struct _DESKTOP DESKTOP_SWITCHDESKTOP | \ DESKTOP_WRITEOBJECTS -extern PDESKTOP InputDesktop; +extern PDESKTOP gpdeskInputDesktop; extern PCLS DesktopWindowClass; extern HDC ScreenDeviceContext; +extern PTHREADINFO gptiForeground; extern PTHREADINFO gptiDesktopThread; typedef struct _SHELL_HOOK_WINDOW diff --git a/win32ss/user/ntuser/focus.c b/win32ss/user/ntuser/focus.c index 8902c129b84..cf79511c2d9 100644 --- a/win32ss/user/ntuser/focus.c +++ b/win32ss/user/ntuser/focus.c @@ -80,7 +80,7 @@ BOOL FASTCALL co_IntMakeWindowActive(PWND Window) { PWND spwndOwner; - if (Window) + if (VerifyWnd(Window)) { // Set last active for window and it's owner. spwndOwner = Window; while (spwndOwner->spwndOwner) @@ -132,6 +132,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO { UINT flags = SWP_NOSIZE | SWP_NOMOVE; if (Window == pwndTemp) flags |= SWP_NOACTIVATE; + //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground); co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags); } } @@ -156,8 +157,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO if ( OldTID ) { ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG; - ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags; - + // Note: Do not set pci flags, this does crash! for (phWnd = List; *phWnd; ++phWnd) { cWindow = ValidateHwndNoErr(*phWnd); @@ -168,13 +168,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO } } ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG; - ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags; } if ( NewTID ) { //// Prevents a resource crash due to reentrance! InAAPM = TRUE; pti->TIF_flags |= TIF_INACTIVATEAPPMSG; - pti->pClientInfo->dwTIFlags = pti->TIF_flags; //// for (phWnd = List; *phWnd; ++phWnd) { @@ -186,7 +184,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO } } } - ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + ExFreePool(List);//ExFreePoolWithTag(List, USERTAG_WINDOWLIST); } } if (WindowPrev) @@ -205,12 +203,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO co_IntMakeWindowActive(Window); - UserDerefObjectCo(Window); - /* FIXME: IntIsWindow */ + co_IntSendMessageNoWait( UserHMGetHandle(Window), WM_NCACTIVATE, - (WPARAM)(gpqForeground ? (Window == gpqForeground->spwndActive) : FALSE), + (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)), 0); //(LPARAM)hWndPrev); co_IntSendMessageNoWait( UserHMGetHandle(Window), @@ -226,6 +223,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO Window->state &= ~WNDS_NONCPAINT; + UserDerefObjectCo(Window); } return InAAPM; } @@ -294,7 +292,7 @@ IntFindChildWindowToOwner(PWND Root, PWND Owner) } VOID FASTCALL -FindRemoveAsyncMsg(PWND Wnd) +FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam) { PTHREADINFO pti; PUSER_SENT_MESSAGE Message; @@ -311,20 +309,60 @@ FindRemoveAsyncMsg(PWND Wnd) Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); do { + if (IsListEmpty(Entry)) return; + if (!Message) return; + Entry = Message->ListEntry.Flink; + if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW && Message->Msg.hwnd == UserHMGetHandle(Wnd) && - Message->Msg.wParam == 0 ) + Message->Msg.wParam == wParam ) { - TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd); - RemoveEntryList(Entry); // Purge the entry. + ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam); + RemoveEntryList(&Message->ListEntry); // Purge the entry. + ExFreePoolWithTag(Message, TAG_USRMSG); } - Entry = Message->ListEntry.Flink; Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); } while (Entry != &pti->SentMessagesListHead); } } +BOOL FASTCALL +ToggleFGActivate(PTHREADINFO pti) +{ + BOOL Ret; + PPROCESSINFO ppi = pti->ppi; + + Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE); + if (Ret) + { + pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; + } + else + Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE); + + if (Ret) + ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE; + //ERR("ToggleFGActivate is %d\n",Ret); + return Ret; +} + +BOOL FASTCALL +IsAllowedFGActive(PTHREADINFO pti, PWND Wnd) +{ + // Not allowed if one or more,, + if (!ToggleFGActivate(pti) || // bits not set, + pti->rpdesk != gpdeskInputDesktop || // not current Desktop, + pti->MessageQueue == gpqForeground || // if already the queue foreground, + IsFGLocked() || // foreground is locked, + Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it. + { + return FALSE; + } + //ERR("IsAllowedFGActive is TRUE\n"); + return TRUE; +} + /* Can the system force foreground from one or more conditions. */ @@ -339,6 +377,7 @@ CanForceFG(PPROCESSINFO ppi) gppiInputProvider == ppi || !gpqForeground ) return TRUE; + //ERR("CanForceFG is FALSE\n"); return FALSE; } @@ -356,37 +395,35 @@ CanForceFG(PPROCESSINFO ppi) * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). * No menus are active. */ - -static BOOL FASTCALL +static +BOOL FASTCALL co_IntSetForegroundAndFocusWindow( _In_ PWND Wnd, _In_ BOOL MouseActivate) { - HWND hWnd; + HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL; HWND hWndPrev = NULL; + PWND pWndPrev = NULL; PUSER_MESSAGE_QUEUE PrevForegroundQueue; PTHREADINFO pti; BOOL fgRet = FALSE, Ret = FALSE; - ASSERT_REFS_CO(Wnd); - NT_ASSERT(Wnd != NULL); + if (Wnd) ASSERT_REFS_CO(Wnd); - hWnd = UserHMGetHandle(Wnd); - - TRACE("SetForegroundAndFocusWindow(%p, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); + //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop. pti = PsGetCurrentThreadWin32Thread(); if (PrevForegroundQueue) { // Same Window Q as foreground just do active. - //ERR("Same Window Q as foreground just do active.\n"); if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue) { + //ERR("Same Window Q as foreground just do active.\n"); if (pti->MessageQueue == PrevForegroundQueue) { // Same WQ and TQ go active. //ERR("Same WQ and TQ go active.\n"); - Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE); + Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { // Same WQ and it is active. @@ -396,13 +433,14 @@ co_IntSetForegroundAndFocusWindow( else { // Same WQ as FG but not the same TQ send active. //ERR("Same WQ as FG but not the same TQ send active.\n"); - co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); + co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } return Ret; } hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0; + pWndPrev = PrevForegroundQueue->spwndActive; } if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) && @@ -410,16 +448,29 @@ co_IntSetForegroundAndFocusWindow( pti->ppi == ppiScrnSaver ) { - IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); - gptiForeground = Wnd->head.pti; - TRACE("Set Foreground pti 0x%p Q 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue); + + //ToggleFGActivate(pti); // win.c line 2662 fail + if (Wnd) + { + IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); + gptiForeground = Wnd->head.pti; + //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h); + } + else + { + IntSetFocusMessageQueue(NULL); + gptiForeground = NULL; + //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n"); + } /* Henri Verbeet, What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the other thread after we already changed the foreground window back to our own window. */ - FindRemoveAsyncMsg(Wnd); // Do this to fix test_SFW todos! + //ERR("SFAFW: 1\n"); + FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos! + fgRet = TRUE; } @@ -428,34 +479,41 @@ co_IntSetForegroundAndFocusWindow( { if (PrevForegroundQueue && fgRet && - Wnd->head.pti->MessageQueue != PrevForegroundQueue && PrevForegroundQueue->spwndActive) { //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev); if (pti->MessageQueue == PrevForegroundQueue) { //ERR("SFGW: TI same as Prev TI\n"); - co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE, FALSE); + co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE); + } + else if (pWndPrev) + { + //ERR("SFGW Deactivate: TI not same as Prev TI\n"); + // No real reason to wait here. + co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); } - else - co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); } } + if (!Wnd) return FALSE; // Always return false. + if (pti->MessageQueue == Wnd->head.pti->MessageQueue) { - Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE); + //ERR("Same PQ and WQ go active.\n"); + Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { + //ERR("Same Active and Wnd.\n"); Ret = TRUE; } else { + //ERR("Activate Not same PQ and WQ and Wnd.\n"); co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); Ret = TRUE; } - return Ret && fgRet; } @@ -500,7 +558,7 @@ co_IntMouseActivateWindow(PWND Wnd) } BOOL FASTCALL -co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async) +co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; @@ -509,38 +567,83 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, HWND hWnd = 0; BOOL InAAPM; CBTACTIVATESTRUCT cbt; - + //ERR("co_IntSetActiveWindow 1\n"); if (Wnd) { ASSERT_REFS_CO(Wnd); hWnd = UserHMGetHandle(Wnd); if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if (Wnd == UserGetDesktopWindow()) return FALSE; + //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd); } + //ERR("co_IntSetActiveWindow 2\n"); pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL; - if (Prev) *Prev = hWndPrev; - if (hWndPrev == hWnd) return TRUE; pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. - if (Wnd) + while (Wnd) { - if (ThreadQueue != Wnd->head.pti->MessageQueue) - { - PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); - // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... - if (!ForegroundQueue || ForegroundQueue == ThreadQueue) - { - return co_IntSetForegroundAndFocusWindow(Wnd, bMouse); - } - } + BOOL Ret, DoFG, AllowFG; if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE; + + if (ThreadQueue == Wnd->head.pti->MessageQueue) + { + if (IsAllowedFGActive(pti, Wnd)) + { + DoFG = TRUE; + } + else + { + //ERR("co_IntSetActiveWindow 3 Go Out!\n"); + break; + } + AllowFG = !pti->cVisWindows; // Nothing is visable. + //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + } + else //if (ThreadQueue != Wnd->head.pti->MessageQueue) + { + //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); + // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... + //if (!ForegroundQueue || ForegroundQueue == ThreadQueue) + if (!gpqForeground || gpqForeground == ThreadQueue) + { + DoFG = TRUE; + } + else + DoFG = FALSE; + if (DoFG) + { + if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows) + AllowFG = TRUE; + else + AllowFG = FALSE; + } + else + AllowFG = FALSE; + //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + } + Ret = FALSE; + if (DoFG) + { + pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + //ERR("co_IntSetActiveWindow 3c FG set\n"); + Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse); + if (AllowFG) + { + pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + } + else + { + pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; + } + } + return Ret; } /* Call CBT hook chain */ @@ -562,14 +665,16 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (WndPrev) { if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; - if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE; + if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE; } + WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active. + // While in calling message proc or hook: // Fail if a preemptive switch was made, current active not made previous, // focus window is dead or no longer the same thread queue. if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || - pWndChg != ThreadQueue->spwndActive || + pWndChg != WndPrev || (Wnd && !VerifyWnd(Wnd)) || ThreadQueue != pti->MessageQueue ) { @@ -582,6 +687,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED; IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + //// Breaks Atl-Esc/Tab via User32. + ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages. /* check if the specified window can be set in the input data of a given queue */ if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue) @@ -590,6 +697,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, ThreadQueue->spwndActive = Wnd; } + WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again. + InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); /* now change focus if necessary */ @@ -610,16 +719,40 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, if (InAAPM) { pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; - pti->pClientInfo->dwTIFlags = pti->TIF_flags; } // FIXME: Used in the menu loop!!! //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; + //ERR("co_IntSetActiveWindow Exit\n"); if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED; return (ThreadQueue->spwndActive == Wnd); } +BOOL FASTCALL +UserSetActiveWindow(PWND Wnd) +{ + if (Wnd) // Must have a window! + { + if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; + + return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE); + } + /* + Yes your eye are not deceiving you~! + + First part of wines Win.c test_SetActiveWindow: + + flush_events( TRUE ); + ShowWindow(hwnd, SW_HIDE); + SetFocus(0); + SetActiveWindow(0); + check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does! + + */ + return FALSE; +} + HWND FASTCALL co_UserSetFocus(PWND Window) { @@ -653,17 +786,10 @@ co_UserSetFocus(PWND Window) } /* Check if we can set the focus to this window */ - pwndTop = Window; - for (;;) + for (pwndTop = Window; pwndTop != NULL; pwndTop = pwndTop->spwndParent) { if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0; - if (!pwndTop->spwndParent || pwndTop->spwndParent == UserGetDesktopWindow()) - { - if ((pwndTop->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0; - break; - } - if (pwndTop->spwndParent == UserGetMessageWindow()) return 0; - pwndTop = pwndTop->spwndParent; + if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break; } if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev)) @@ -676,8 +802,13 @@ co_UserSetFocus(PWND Window) if (pwndTop != ThreadQueue->spwndActive) { PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop. - if (ThreadQueue != ForegroundQueue) // HACK see rule 2 & 3. + if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3. { + //ERR("SetFocus: Set Foreground!\n"); + if (!(pwndTop->style & WS_VISIBLE)) + { + pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; + } if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE)) { ERR("SetFocus: Set Foreground and Focus Failed!\n"); @@ -688,7 +819,8 @@ co_UserSetFocus(PWND Window) /* Set Active when it is needed. */ if (pwndTop != ThreadQueue->spwndActive) { - if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE, FALSE)) + //ERR("SetFocus: Set Active!\n"); + if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE)) { ERR("SetFocus: Set Active Failed!\n"); return 0; @@ -714,8 +846,6 @@ co_UserSetFocus(PWND Window) } else /* NULL hwnd passed in */ { -// if (!hWndPrev) return 0; /* nothing to do */ - if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev)) { ERR("SetFocus: 2 WH_CBT Call Hook return!\n"); @@ -857,7 +987,7 @@ IntReleaseCapture(VOID) BOOL FASTCALL co_IntSetForegroundWindow(PWND Window) { - ASSERT_REFS_CO(Window); + if (Window) ASSERT_REFS_CO(Window); return co_IntSetForegroundAndFocusWindow(Window, FALSE); } @@ -937,12 +1067,13 @@ IntAllowSetForegroundWindow(DWORD dwProcessId) } if (dwProcessId == ASFW_ANY) { // All processes will be enabled to set the foreground window. + //ERR("ptiLastInput is CLEARED!!\n"); ptiLastInput = NULL; } else { // Rule #3, last input event in force. - ERR("Fixme: ptiLastInput is SET!!\n"); - //ptiLastInput = ppi->ptiList; + ERR("ptiLastInput is SET!!\n"); + //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030. ObDereferenceObject(Process); } return TRUE; @@ -962,7 +1093,7 @@ NtUserGetForegroundWindow(VOID) RETURN( UserGetForegroundWindow()); CLEANUP: - TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", _ret_); + TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_); UserLeave(); END_CLEANUP; } @@ -993,7 +1124,7 @@ NtUserSetActiveWindow(HWND hWnd) { hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL; if (Window) UserRefObjectCo(Window, &Ref); - co_IntSetActiveWindow(Window, NULL, FALSE, TRUE, FALSE); + UserSetActiveWindow(Window); if (Window) UserDerefObjectCo(Window); RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 ); } diff --git a/win32ss/user/ntuser/focus.h b/win32ss/user/ntuser/focus.h index 48ac7efacd1..bc82c3bf5da 100644 --- a/win32ss/user/ntuser/focus.h +++ b/win32ss/user/ntuser/focus.h @@ -2,6 +2,7 @@ extern PUSER_MESSAGE_QUEUE gpqForeground; extern PUSER_MESSAGE_QUEUE gpqForegroundPrev; +extern PTHREADINFO ptiLastInput; /* * These functions take the window handles from current message queue. @@ -18,7 +19,8 @@ HWND APIENTRY IntGetCapture(VOID); HWND FASTCALL UserGetActiveWindow(VOID); BOOL FASTCALL co_IntMouseActivateWindow(PWND Window); BOOL FASTCALL co_IntSetForegroundWindow(PWND Window); -BOOL FASTCALL co_IntSetActiveWindow(PWND,HWND *,BOOL,BOOL,BOOL); BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window); +BOOL FASTCALL co_IntSetActiveWindow(PWND,BOOL,BOOL,BOOL); +BOOL FASTCALL UserSetActiveWindow(PWND Wnd); BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode); BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId); diff --git a/win32ss/user/ntuser/input.c b/win32ss/user/ntuser/input.c index 04382acac94..4223669256a 100644 --- a/win32ss/user/ntuser/input.c +++ b/win32ss/user/ntuser/input.c @@ -402,24 +402,47 @@ NtUserBlockInput( return ret; } -PTHREADINFO FASTCALL -IsThreadAttach(PTHREADINFO ptiTo) +BOOL +FASTCALL +IsRemoveAttachThread(PTHREADINFO pti) { + NTSTATUS Status; PATTACHINFO pai; + BOOL Ret = TRUE; + PTHREADINFO ptiFrom = NULL, ptiTo = NULL; - if (!gpai) return NULL; - - pai = gpai; do { - if (pai->pti2 == ptiTo) break; - pai = pai->paiNext; - } while (pai); + if (!gpai) return TRUE; + + pai = gpai; // Bottom of the list. - if (!pai) return NULL; + do + { + if (pai->pti2 == pti) + { + ptiFrom = pai->pti1; + ptiTo = pti; + break; + } + if (pai->pti1 == pti) + { + ptiFrom = pti; + ptiTo = pai->pti2; + break; + } + pai = pai->paiNext; + + } while (pai); - // Return ptiFrom. - return pai->pti1; + if (!pai && !ptiFrom && !ptiTo) break; + + Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE); + if (!NT_SUCCESS(Status)) Ret = FALSE; + + } while (Ret); + + return Ret; } NTSTATUS FASTCALL @@ -454,44 +477,52 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) paiCount++; ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount); - if (ptiTo->MessageQueue == ptiFrom->MessageQueue) + if (ptiTo->MessageQueue != ptiFrom->MessageQueue) + { + + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + + // FIXME: conditions? + if (ptiTo->MessageQueue == gpqForeground) + { + ERR("ptiTo is Foreground\n"); + } + else + { + ERR("ptiTo NOT Foreground\n"); + } + + if (ptiFrom->MessageQueue == gpqForeground) + { + ERR("ptiFrom is Foreground\n"); + ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive; + ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus; + ptiTo->MessageQueue->CursorObject = ptiFrom->MessageQueue->CursorObject; + ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture; + ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED); + ptiTo->MessageQueue->CaretInfo = ptiFrom->MessageQueue->CaretInfo; + IntSetFocusMessageQueue(NULL); + IntSetFocusMessageQueue(ptiTo->MessageQueue); + gptiForeground = ptiTo; + } + else + { + ERR("ptiFrom NOT Foreground\n"); + } + + MsqDestroyMessageQueue(ptiFrom); + + ptiFrom->MessageQueue = ptiTo->MessageQueue; + + ptiFrom->MessageQueue->cThreads++; + ERR("ptiTo S Share count %d\n", ptiFrom->MessageQueue->cThreads); + + IntReferenceMessageQueue(ptiTo->MessageQueue); + } + else { ERR("Attach Threads are already associated!\n"); } - - ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; - - /* Keep the original queue in pqAttach (ie do not trash it in a second attachment) */ - if (ptiFrom->pqAttach == NULL) - ptiFrom->pqAttach = ptiFrom->MessageQueue; - ptiFrom->MessageQueue = ptiTo->MessageQueue; - - ptiFrom->MessageQueue->cThreads++; - ERR("ptiTo S Share count %lu\n", ptiFrom->MessageQueue->cThreads); - - // FIXME: conditions? - if (ptiFrom->pqAttach == gpqForeground) - { - ERR("ptiFrom is Foreground\n"); - ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive; - ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus; - ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject; - ptiFrom->MessageQueue->spwndCapture = ptiFrom->pqAttach->spwndCapture; - ptiFrom->MessageQueue->QF_flags ^= ((ptiFrom->MessageQueue->QF_flags ^ ptiFrom->pqAttach->QF_flags) & QF_CAPTURELOCKED); - ptiFrom->MessageQueue->CaretInfo = ptiFrom->pqAttach->CaretInfo; - } - else - { - ERR("ptiFrom NOT Foreground\n"); - } - if (ptiTo->MessageQueue == gpqForeground) - { - ERR("ptiTo is Foreground\n"); - } - else - { - ERR("ptiTo NOT Foreground\n"); - } } else /* If clear, unlink and free it. */ { @@ -518,41 +549,31 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach) } if (!Hit) return STATUS_INVALID_PARAMETER; - - ASSERT(ptiFrom->pqAttach); ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount); - - /* Search list and check if the thread is attached one more time */ - pai = gpai; - while(pai) + + if (ptiTo->MessageQueue == ptiFrom->MessageQueue) { - /* If the thread is attached again , we are done */ - if (pai->pti1 == ptiFrom) - { - ptiFrom->MessageQueue->cThreads--; - ERR("ptiTo L Share count %lu\n", ptiFrom->MessageQueue->cThreads); - /* Use the message queue of the last attachment */ - ptiFrom->MessageQueue = pai->pti2->MessageQueue; - ptiFrom->MessageQueue->CursorObject = NULL; - ptiFrom->MessageQueue->spwndActive = NULL; - ptiFrom->MessageQueue->spwndFocus = NULL; - ptiFrom->MessageQueue->spwndCapture = NULL; - return STATUS_SUCCESS; - } - pai = pai->paiNext; - } + if (gptiForeground == ptiFrom) + { + ERR("ptiTo is now pti FG.\n"); + // MessageQueue foreground is set so switch threads. + gptiForeground = ptiTo; + } + ptiTo->MessageQueue->cThreads--; + ERR("ptiTo E Share count %d\n", ptiTo->MessageQueue->cThreads); + ASSERT(ptiTo->MessageQueue->cThreads >= 1); - ptiFrom->MessageQueue->cThreads--; - ERR("ptiTo E Share count %lu\n", ptiFrom->MessageQueue->cThreads); - ptiFrom->MessageQueue = ptiFrom->pqAttach; - // FIXME: conditions? - ptiFrom->MessageQueue->CursorObject = NULL; - ptiFrom->MessageQueue->spwndActive = NULL; - ptiFrom->MessageQueue->spwndFocus = NULL; - ptiFrom->MessageQueue->spwndCapture = NULL; - ptiFrom->pqAttach = NULL; - ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + IntDereferenceMessageQueue(ptiTo->MessageQueue); + + ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom); + + ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel; + } + else + { + ERR("Detaching Threads are not associated!\n"); + } } /* Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to AttachThreadInput. diff --git a/win32ss/user/ntuser/input.h b/win32ss/user/ntuser/input.h index 985d2c96a30..c34eb4a9ff0 100644 --- a/win32ss/user/ntuser/input.h +++ b/win32ss/user/ntuser/input.h @@ -63,7 +63,7 @@ INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID); BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt); DWORD NTAPI CreateSystemThreads(UINT Type); NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL); -PTHREADINFO FASTCALL IsThreadAttach(PTHREADINFO); +BOOL FASTCALL IsRemoveAttachThread(PTHREADINFO); VOID FASTCALL DoTheScreenSaver(VOID); #define ThreadHasInputAccess(W32Thread) (TRUE) diff --git a/win32ss/user/ntuser/keyboard.c b/win32ss/user/ntuser/keyboard.c index 7af7cc5a84e..28ac361b63d 100644 --- a/win32ss/user/ntuser/keyboard.c +++ b/win32ss/user/ntuser/keyboard.c @@ -825,6 +825,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d TRACE("HotKey Processed\n"); bPostMsg = FALSE; } + wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */ if (wSimpleVk == VK_SHIFT) /* shift can't be extended */ bExt = FALSE; @@ -892,28 +893,36 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d } else if (pFocusQueue && bPostMsg) { - PWND Wnd = pFocusQueue->spwndFocus; - if (!Wnd) + PWND Wnd = pFocusQueue->spwndFocus; // SysInit..... + + pti = pFocusQueue->ptiKeyboard; + + if (!Wnd && pFocusQueue->spwndActive) // SysInit..... { - // Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input. + // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input. Wnd = pFocusQueue->spwndActive; } - - if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED ) - { - ERR("ProcessKeyEvent Active Focus window is dead!\n"); - return FALSE; - } - - pti = Wnd->head.pti; + if (Wnd) pti = Wnd->head.pti; /* Init message */ - Msg.hwnd = UserHMGetHandle(Wnd); + Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL; Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */ Msg.lParam = MAKELPARAM(1, wScanCode); Msg.time = dwTime; Msg.pt = gpsi->ptCursor; + if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN ) + { + if ( (Msg.wParam == VK_SHIFT || + Msg.wParam == VK_CONTROL || + Msg.wParam == VK_MENU ) && + !IS_KEY_DOWN(gafAsyncKeyState, Msg.wParam)) + { + ERR("Set last input\n"); + //ptiLastInput = pti; + } + } + /* If it is VK_PACKET, high word of wParam is used for wchar */ if (!bPacket) { @@ -934,6 +943,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d /* Post a keyboard message */ TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam); + if (!Wnd) {ERR("Window is NULL\n");} MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0); } @@ -956,9 +966,9 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected) /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue(); - if (pFocusQueue && pFocusQueue->ptiOwner) + if (pFocusQueue && pFocusQueue->ptiKeyboard) { - pKl = pFocusQueue->ptiOwner->KeyboardLayout; + pKl = pFocusQueue->ptiKeyboard->KeyboardLayout; } if (!pKl) @@ -1039,9 +1049,9 @@ UserProcessKeyboardInput( /* Find the target thread whose locale is in effect */ pFocusQueue = IntGetFocusMessageQueue(); - if (pFocusQueue && pFocusQueue->ptiOwner) + if (pFocusQueue && pFocusQueue->ptiKeyboard) { - pKl = pFocusQueue->ptiOwner->KeyboardLayout; + pKl = pFocusQueue->ptiKeyboard->KeyboardLayout; } if (!pKl) diff --git a/win32ss/user/ntuser/main.c b/win32ss/user/ntuser/main.c index df84709f02d..c872d020554 100644 --- a/win32ss/user/ntuser/main.c +++ b/win32ss/user/ntuser/main.c @@ -154,6 +154,9 @@ Win32kProcessCallback(struct _EPROCESS *Process, ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER; } + // Fixme check if this process is allowed. + ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off. + /* Create pools for GDI object attributes */ ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG'); ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG'); @@ -275,14 +278,17 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) RtlZeroMemory(ptiCurrent, sizeof(THREADINFO)); + /* Initialize the THREADINFO */ + PsSetThreadWin32Thread(Thread, ptiCurrent); + IntReferenceThreadInfo(ptiCurrent); + ptiCurrent->pEThread = Thread; + ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); pTeb->Win32ThreadInfo = ptiCurrent; ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo; TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread); - /* Initialize the THREADINFO */ - IntReferenceThreadInfo(ptiCurrent); InitializeListHead(&ptiCurrent->WindowListHead); InitializeListHead(&ptiCurrent->W32CallbackListHead); InitializeListHead(&ptiCurrent->PostedMessagesListHead); @@ -294,8 +300,6 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) { InitializeListHead(&ptiCurrent->aphkStart[i]); } - ptiCurrent->pEThread = Thread; - ptiCurrent->ppi = PsGetCurrentProcessWin32Process(); ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList; ptiCurrent->ppi->ptiList = ptiCurrent; ptiCurrent->ppi->cThreads++; @@ -307,7 +311,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) { goto error; } - Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, + Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0, ExEventObjectType, KernelMode, (PVOID*)&ptiCurrent->pEventQueueServer, NULL); if (!NT_SUCCESS(Status)) @@ -319,7 +323,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) KeQueryTickCount(&LargeTickCount); ptiCurrent->timeLast = LargeTickCount.u.LowPart; - + ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent); if(ptiCurrent->MessageQueue == NULL) { @@ -419,8 +423,14 @@ UserCreateThreadInfo(struct _ETHREAD *Thread) /* mark the thread as fully initialized */ ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED; - ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) && + (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi )) + { + ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; + } + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + ERR_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent); return STATUS_SUCCESS; error: @@ -483,27 +493,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) ppiCurrent = ptiCurrent->ppi; ASSERT(ppiCurrent); - // ptiTo - if (IsThreadAttach(ptiCurrent)) - { - PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent); - TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n"); - UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE); - } + IsRemoveAttachThread(ptiCurrent); - // ptiFrom - if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue) - { - PTHREADINFO ptiTo; - ptiTo = ptiCurrent->MessageQueue->ptiOwner; - TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n"); - if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE); - else - { - // eThread maybe okay but Win32Thread already made NULL! - ERR_CH(UserThread,"Attached Thread ptiFrom did not switch due to ptiTo is NULL!\n"); - } - } + ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE; + ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; /* Decrement thread count and check if its 0 */ ppiCurrent->cThreads--; @@ -553,9 +546,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) */ co_DestroyThreadWindows(Thread); - if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling) + if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling && + ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED) { - //ERR_CH(UserThread,"DestroyProcessClasses\n"); + ERR_CH(UserThread,"DestroyProcessClasses\n"); /* no process windows should exist at this point, or the function will assert! */ DestroyProcessClasses(ppiCurrent); ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED; @@ -592,8 +586,24 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread) if (ptiCurrent->KeyboardLayout) UserDereferenceObject(ptiCurrent->KeyboardLayout); - IntSetThreadDesktop(NULL, TRUE); + if (gptiForeground == ptiCurrent) + { +// IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0); +// IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0); + gptiForeground = NULL; + } + + // Fixes CORE-6384 & CORE-7030. +/* if (ptiLastInput == ptiCurrent) + { + if (!ppiCurrent->ptiList) + ptiLastInput = gptiForeground; + else + ptiLastInput = ppiCurrent->ptiList; + ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n"); + } +*/ TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent); /* Free the THREADINFO */ diff --git a/win32ss/user/ntuser/message.c b/win32ss/user/ntuser/message.c index d4064ee5390..5b4c27ff1b5 100644 --- a/win32ss/user/ntuser/message.c +++ b/win32ss/user/ntuser/message.c @@ -502,13 +502,7 @@ VOID FASTCALL IdlePing(VOID) { PPROCESSINFO ppi = PsGetCurrentProcessWin32Process(); - PUSER_MESSAGE_QUEUE ForegroundQueue; - PTHREADINFO pti, ptiForeground = NULL; - - ForegroundQueue = IntGetFocusMessageQueue(); - - if (ForegroundQueue) - ptiForeground = ForegroundQueue->ptiOwner; + PTHREADINFO pti; pti = PsGetCurrentThreadWin32Thread(); @@ -516,7 +510,7 @@ IdlePing(VOID) { pti->pClientInfo->cSpins = 0; // Reset spins. - if ( pti->pDeskInfo && pti == ptiForeground ) + if ( pti->pDeskInfo && pti == gptiForeground ) { if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) || pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ) @@ -602,13 +596,14 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR { LRESULT lRes; USER_REFERENCE_ENTRY Ref; +// PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); if (!pWnd || pWnd == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP pWnd == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND return 0; - TRACE("Internal Event Msg %u hWnd %p\n", msg, pWnd->head.h); + TRACE("Internal Event Msg %p hWnd 0x%x\n",msg,pWnd->head.h); switch(msg) { @@ -632,7 +627,7 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR { PWND Window = (PWND)wparam; if (wparam) UserRefObjectCo(Window, &Ref); - lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE,TRUE); + lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE); if (wparam) UserDerefObjectCo(Window); return lRes; } @@ -751,6 +746,14 @@ IntDispatchMessage(PMSG pMsg) /* * Internal version of PeekMessage() doing all the work + * + * MSDN: + * Sent messages + * Posted messages + * Input (hardware) messages and system internal events + * Sent messages (again) + * WM_PAINT messages + * WM_TIMER messages */ BOOL FASTCALL co_IntPeekMessage( PMSG Msg, @@ -770,7 +773,7 @@ co_IntPeekMessage( PMSG Msg, RemoveMessages = RemoveMsg & PM_REMOVE; ProcessMask = HIWORD(RemoveMsg); - + /* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns all available messages (that is, no range filtering is performed)". */ if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT); @@ -1083,6 +1086,19 @@ UserPostThreadMessage( PTHREADINFO pti, return TRUE; } +PTHREADINFO FASTCALL +IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg) +{ + if ( ptiCur ) + { + if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue ) + { + return NULL; + } + } + return Window->head.pti; +} + BOOL FASTCALL UserPostMessage( HWND Wnd, UINT Msg, @@ -1192,11 +1208,11 @@ UserPostMessage( HWND Wnd, if (WM_QUIT == Msg) { - MsqPostQuitMessage(Window->head.pti, wParam); + MsqPostQuitMessage(pti, wParam); } else { - MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0); + MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0); } } return TRUE; @@ -1230,7 +1246,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; LPARAM lParamPacked; - PTHREADINFO Win32Thread; + PTHREADINFO Win32Thread, ptiSendTo = NULL; ULONG_PTR Hi, Lo, Result = 0; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; @@ -1246,8 +1262,9 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, Win32Thread = PsGetCurrentThreadWin32Thread(); - if ( Win32Thread && - Window->head.pti == Win32Thread) + ptiSendTo = IntSendTo(Window, Win32Thread, Msg); + + if ( !ptiSendTo ) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1333,7 +1350,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, RETURN( TRUE); } - if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti)) + if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo/*Window->head.pti*/)) { // FIXME: Set window hung and add to a list. /* FIXME: Set a LastError? */ @@ -1349,7 +1366,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, do { - Status = co_MsqSendMessage( Window->head.pti, + Status = co_MsqSendMessage( ptiSendTo, //Window->head.pti, hWnd, Msg, wParam, @@ -1361,7 +1378,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, } while ((STATUS_TIMEOUT == Status) && (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) && - !MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list. + !MsqIsHung(ptiSendTo/*Window->head.pti*/)); // FIXME: Set window hung and add to a list. if (STATUS_TIMEOUT == Status) { @@ -1491,7 +1508,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, PMSGMEMORY MsgMemoryEntry; INT lParamBufferSize; LPARAM lParamPacked; - PTHREADINFO Win32Thread; + PTHREADINFO Win32Thread, ptiSendTo = NULL; DECLARE_RETURN(LRESULT); USER_REFERENCE_ENTRY Ref; PUSER_SENT_MESSAGE Message; @@ -1519,9 +1536,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, { RETURN(FALSE); } + + ptiSendTo = IntSendTo(Window, Win32Thread, Msg); if (Msg & 0x80000000 && - Window->head.pti == Win32Thread) + !ptiSendTo) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE); @@ -1542,14 +1561,14 @@ co_IntSendMessageWithCallBack( HWND hWnd, lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam); } - if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread))) + if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, !!ptiSendTo))) { ERR("Failed to pack message parameters\n"); RETURN( FALSE); } /* If it can be sent now, then send it. */ - if (Window->head.pti == Win32Thread) + if ( !ptiSendTo ) { if (Win32Thread->TIF_flags & TIF_INCLEANUP) { @@ -1599,7 +1618,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, } } - if (Window->head.pti == Win32Thread) + if ( !ptiSendTo) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1622,7 +1641,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->Result = 0; Message->lResult = 0; Message->QS_Flags = 0; - Message->ptiReceiver = Window->head.pti; + Message->ptiReceiver = ptiSendTo; //Window->head.pti; Message->ptiSender = NULL; // mjmartin, you are right! This is null. Message->ptiCallBackSender = Win32Thread; Message->DispatchingListEntry.Flink = NULL; @@ -1633,10 +1652,10 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->QS_Flags = QS_SENDMESSAGE; if (Msg & 0x80000000) // Higher priority event message! - InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); + InsertHeadList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry); else - InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE); + InsertTailList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry); + MsqWakeQueue(ptiSendTo/*Window->head.pti*/, QS_SENDMESSAGE, TRUE); RETURN(TRUE); @@ -1674,7 +1693,7 @@ co_IntPostOrSendMessage( HWND hWnd, pti = PsGetCurrentThreadWin32Thread(); - if ( Window->head.pti->MessageQueue != pti->MessageQueue && + if ( IntSendTo(Window, pti, Msg) && FindMsgMemory(Msg) == 0 ) { Result = UserPostMessage(hWnd, Msg, wParam, lParam); diff --git a/win32ss/user/ntuser/misc.c b/win32ss/user/ntuser/misc.c index 935104f7cfd..52f0abe377c 100644 --- a/win32ss/user/ntuser/misc.c +++ b/win32ss/user/ntuser/misc.c @@ -662,8 +662,11 @@ void UserDbgAssertThreadInfo(BOOL showCaller) ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo); /*too bad we still get this assertion*/ + + // Why? Not all flags are passed to the user and doing so could crash the system........ + /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */ - if(pci->dwTIFlags != pti->TIF_flags) +/* if(pci->dwTIFlags != pti->TIF_flags) { ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags); if(showCaller) @@ -673,6 +676,7 @@ void UserDbgAssertThreadInfo(BOOL showCaller) } pci->dwTIFlags = pti->TIF_flags; } +*/ } void diff --git a/win32ss/user/ntuser/msgqueue.c b/win32ss/user/ntuser/msgqueue.c index 5be8095794b..c4e677ddf69 100644 --- a/win32ss/user/ntuser/msgqueue.c +++ b/win32ss/user/ntuser/msgqueue.c @@ -404,7 +404,6 @@ MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent) { ERR("This Message Queue is in Destroy!\n"); } - pti->pcti->fsWakeBits |= MessageBits; pti->pcti->fsChangeBits |= MessageBits; @@ -475,6 +474,10 @@ ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits) { if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY; } + if (MessageBits & QS_EVENT) + { + if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT; + } pti->pcti->fsWakeBits &= ~ClrMask; pti->pcti->fsChangeBits &= ~ClrMask; @@ -506,6 +509,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook { LARGE_INTEGER LargeTickCount; MSLLHOOKSTRUCT MouseHookData; +// PDESKTOP pDesk; PWND pwnd, pwndDesktop; HDC hdcScreen; PTHREADINFO pti; @@ -549,6 +553,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook /* Get the desktop window */ pwndDesktop = UserGetDesktopWindow(); if (!pwndDesktop) return; +// pDesk = pwndDesktop->head.rpdesk; /* Check if the mouse is captured */ Msg->hwnd = IntGetCaptureWindow(); @@ -626,6 +631,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook } else { + //if (!IntGetCaptureWindow()) ptiLastInput = pti; TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd)); MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0); } @@ -661,7 +667,7 @@ MsqDestroyMessage(PUSER_MESSAGE Message) } BOOLEAN FASTCALL -co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti) +co_MsqDispatchOneSentMessage(PTHREADINFO pti) { PUSER_SENT_MESSAGE SaveMsg, Message; PLIST_ENTRY Entry; @@ -911,12 +917,6 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver, ptiSender = PsGetCurrentThreadWin32Thread(); - IntReferenceMessageQueue(ptiReceiver->MessageQueue); - /* Take reference on this MessageQueue if its a callback. It will be released - when message is processed or removed from target hwnd MessageQueue */ - if (CompletionCallback) - IntReferenceMessageQueue(ptiSender->MessageQueue); - Message->Msg.hwnd = hwnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; @@ -1180,6 +1180,12 @@ MsqPostMessage(PTHREADINFO pti, PUSER_MESSAGE Message; PUSER_MESSAGE_QUEUE MessageQueue; + if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY ) + { + ERR("Post Msg; Thread or Q is Dead!\n"); + return; + } + if(!(Message = MsqCreateMessage(Msg))) { return; @@ -1189,6 +1195,7 @@ MsqPostMessage(PTHREADINFO pti, if (dwQEvent) { + ERR("Post Msg; System Qeued Event Message!\n"); InsertHeadList(&pti->PostedMessagesListHead, &Message->ListEntry); } @@ -1206,7 +1213,7 @@ MsqPostMessage(PTHREADINFO pti, if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it. Message->dwQEvent = dwQEvent; Message->QS_Flags = MessageBits; - //Message->pti = pti; Fixed in ATI changes. See CORE-6551 + Message->pti = pti; MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE)); } @@ -1254,7 +1261,7 @@ FASTCALL IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest) { // PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y); - hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this??? +// hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this??? if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or msg->message != WM_MOUSEMOVE || // Mouse click changes or @@ -1491,7 +1498,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT hook.dwExtraInfo = 0 /* extra_info */ ; co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook ); - ERR("WH_MOUSE dorpped mouse message!\n"); + ERR("WH_MOUSE dropped mouse message!\n"); /* Remove and skip message */ *RemoveMessages = TRUE; @@ -1805,7 +1812,7 @@ MsqPeekMessage(IN PTHREADINFO pti, ListHead = &pti->PostedMessagesListHead; if (IsListEmpty(CurrentEntry)) return FALSE; - + CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry); do @@ -1880,9 +1887,8 @@ HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) BOOLEAN FASTCALL MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue) { - MessageQueue->ptiOwner = pti; MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1); - InitializeListHead(&MessageQueue->HardwareMessagesListHead); + InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here! MessageQueue->spwndFocus = NULL; MessageQueue->iCursorLevel = 0; MessageQueue->CursorObject = NULL; @@ -1900,7 +1906,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) PLIST_ENTRY CurrentEntry; PUSER_MESSAGE CurrentMessage; PUSER_SENT_MESSAGE CurrentSentMessage; - + /* cleanup posted messages */ while (!IsListEmpty(&pti->PostedMessagesListHead)) { @@ -1936,7 +1942,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) if (CurrentSentMessage->Msg.lParam) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - + /* free the message */ ExFreePool(CurrentSentMessage); } @@ -1999,16 +2005,16 @@ MsqCleanupThreadMsgs(PTHREADINFO pti) pti->nCntsQBits[QSRosPostMessage] = 0; pti->nCntsQBits[QSRosSendMessage] = 0; pti->nCntsQBits[QSRosHotKey] = 0; - + pti->nCntsQBits[QSRosEvent] = 0; } - + VOID FASTCALL MsqCleanupMessageQueue(PTHREADINFO pti) { PUSER_MESSAGE_QUEUE MessageQueue; MessageQueue = pti->MessageQueue; - MessageQueue->cThreads--; + MessageQueue->cThreads--; if (MessageQueue->cThreads) { @@ -2033,6 +2039,7 @@ MsqCleanupMessageQueue(PTHREADINFO pti) IntGetSysCursorInfo()->CurrentCursorObject = NULL; } + ERR("DereferenceObject pCursor\n"); UserDereferenceObject(pCursor); } diff --git a/win32ss/user/ntuser/msgqueue.h b/win32ss/user/ntuser/msgqueue.h index 4b2a8ceaa6b..365f76536e5 100644 --- a/win32ss/user/ntuser/msgqueue.h +++ b/win32ss/user/ntuser/msgqueue.h @@ -42,7 +42,6 @@ typedef struct _USER_MESSAGE_QUEUE /* Reference counter, only access this variable with interlocked functions! */ LONG References; - PTHREADINFO ptiOwner; // temp.. /* Desktop that the message queue is attached to */ struct _DESKTOP *Desktop; diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c index b421f57215b..ab165f45f89 100644 --- a/win32ss/user/ntuser/ntstubs.c +++ b/win32ss/user/ntuser/ntstubs.c @@ -546,7 +546,7 @@ APIENTRY NtUserConsoleControl( IN CONSOLECONTROL ConsoleCtrl, IN PVOID ConsoleCtrlInfo, - IN DWORD ConsoleCtrlInfoLength) + IN ULONG ConsoleCtrlInfoLength) { NTSTATUS Status = STATUS_SUCCESS; @@ -562,8 +562,8 @@ NtUserConsoleControl( { _SEH2_TRY { - ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); ASSERT(ConsoleCtrlInfoLength == sizeof(ATOM)); + ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -575,8 +575,33 @@ NtUserConsoleControl( break; } + case ConsoleMakePalettePublic: + { + _SEH2_TRY + { + ASSERT(ConsoleCtrlInfoLength == sizeof(HPALETTE)); + ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, 1); + /* + * Make the palette handle public - Use the extended + * function introduced by Timo in revision 60725. + */ + GreSetObjectOwnerEx(*(HPALETTE*)ConsoleCtrlInfo, + GDI_OBJ_HMGR_PUBLIC, + GDIOBJFLAG_IGNOREPID); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + break; + } + case ConsoleAcquireDisplayOwnership: { + ERR("NtUserConsoleControl - ConsoleAcquireDisplayOwnership is UNIMPLEMENTED\n"); + Status = STATUS_NOT_IMPLEMENTED; break; } diff --git a/win32ss/user/ntuser/object.c b/win32ss/user/ntuser/object.c index 6189050c11c..363e175a28f 100644 --- a/win32ss/user/ntuser/object.c +++ b/win32ss/user/ntuser/object.c @@ -548,6 +548,13 @@ UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner) #endif } + +HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type) +{ + if (handle) return (PWND)UserGetObjectNoErr(gHandleTable, handle, type); + return NULL; +} + /* * NtUserValidateHandleSecure * diff --git a/win32ss/user/ntuser/object.h b/win32ss/user/ntuser/object.h index 51355746184..22267d6fa12 100644 --- a/win32ss/user/ntuser/object.h +++ b/win32ss/user/ntuser/object.h @@ -18,6 +18,7 @@ BOOL FASTCALL UserCreateHandleTable(VOID); BOOL FASTCALL UserObjectInDestroy(HANDLE); void DbgUserDumpHandleTable(); VOID FASTCALL UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner); +HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type); static __inline VOID UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry) diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index 52255f3e438..25a1b0a7633 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -123,7 +123,12 @@ IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits ) styleNew = (pwnd->style | set_bits) & ~clear_bits; if (styleNew == styleOld) return styleNew; pwnd->style = styleNew; - if ((styleOld ^ styleNew) & WS_VISIBLE) DceResetActiveDCEs( pwnd ); + if ((styleOld ^ styleNew) & WS_VISIBLE) // State Change. + { + if (styleOld & WS_VISIBLE) pwnd->head.pti->cVisWindows--; + if (styleNew & WS_VISIBLE) pwnd->head.pti->cVisWindows++; + DceResetActiveDCEs( pwnd ); + } return styleOld; } @@ -159,21 +164,16 @@ IntIsWindow(HWND hWnd) BOOL FASTCALL IntIsWindowVisible(PWND Wnd) { - BOOL Ret = TRUE; - do + PWND Temp = Wnd; + for (;;) { - if (!(Wnd->style & WS_VISIBLE)) - { - Ret = FALSE; - break; - } - if (Wnd->spwndParent != NULL) - Wnd = Wnd->spwndParent; - else - break; + if (!Temp) return TRUE; + if (!(Temp->style & WS_VISIBLE)) break; + if (Temp->style & WS_MINIMIZE && Temp != Wnd) break; + if (Temp->fnid == FNID_DESKTOP) return TRUE; + Temp = Temp->spwndParent; } - while (Wnd != NULL); - return Ret; + return FALSE; } PWND FASTCALL @@ -436,6 +436,7 @@ static LRESULT co_UserFreeWindow(PWND Window, } Window->state2 |= WNDS2_INDESTROY; Window->style &= ~WS_VISIBLE; + Window->head.pti->cVisWindows--; IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0); @@ -497,9 +498,6 @@ static LRESULT co_UserFreeWindow(PWND Window, /* flush the message queue */ MsqRemoveWindowMessagesFromQueue(Window); - NT_ASSERT(Window->head.pti); - IntDereferenceMessageQueue(Window->head.pti->MessageQueue); - /* from now on no messages can be sent to this window anymore */ Window->state |= WNDS_DESTROYED; Window->fnid |= FNID_FREED; @@ -578,6 +576,7 @@ static LRESULT co_UserFreeWindow(PWND Window, GreDeleteObject(Window->hrgnClip); Window->hrgnClip = NULL; } + Window->head.pti->cWindows--; // ASSERT(Window != NULL); UserFreeWindowInfo(Window->head.pti, Window); @@ -1098,8 +1097,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner) Wnd->head.pti == WndNewOwner->head.pti || WndOldOwner->head.pti != WndNewOwner->head.pti ) { - ERR("ProcessOwnerSwap Old out.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE); + //ERR("ProcessOwnerSwap Old out.\n"); + UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE); } } } @@ -1110,8 +1109,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner) if (!WndOldOwner || WndOldOwner->head.pti != WndNewOwner->head.pti ) { - ERR("ProcessOwnerSwap New in.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE); + //ERR("ProcessOwnerSwap New in.\n"); + UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE); } } } @@ -1140,6 +1139,8 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner) goto Error; } + /* if parent belongs to a different thread and the window isn't */ + /* top-level, attach the two threads */ IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner); if (IntValidateOwnerDepth(Wnd, WndNewOwner)) @@ -1186,6 +1187,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) /* Some applications try to set a child as a parent */ if (IntIsChildWindow(Wnd, WndNewParent)) { + TRACE("IntSetParent try to set a child as a parent.\n"); EngSetLastError( ERROR_INVALID_PARAMETER ); return NULL; } @@ -1196,6 +1198,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) { if (Wnd == pWndExam) { + TRACE("IntSetParent Failed Test for set parent to parent!\n"); EngSetLastError(ERROR_INVALID_PARAMETER); return NULL; } @@ -1210,7 +1213,10 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) /* Window must belong to current process */ if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process()) + { + ERR("IntSetParent Window must belong to current process!\n"); return NULL; + } WndOldParent = Wnd->spwndParent; @@ -1249,22 +1255,31 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) } + if ( WndNewParent == co_GetDesktopWindow(Wnd) && + !(Wnd->style & WS_CLIPSIBLINGS) ) + { + Wnd->style |= WS_CLIPSIBLINGS; + DceResetActiveDCEs(Wnd); + } + + /* if parent belongs to a different thread and the window isn't */ + /* top-level, attach the two threads */ if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) { if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd)) { if (Wnd->head.pti != WndOldParent->head.pti) { - ERR("SetParent Old out.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE); + //ERR("SetParent Old out.\n"); + UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE); } } if ( WndNewParent != co_GetDesktopWindow(Wnd)) { if (Wnd->head.pti != WndNewParent->head.pti) { - ERR("SetParent New in.\n"); - //UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE); + //ERR("SetParent New in.\n"); + UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE); } } } @@ -1278,10 +1293,11 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent) * in the z-order and send the expected WM_WINDOWPOSCHANGING and * WM_WINDOWPOSCHANGED notification messages. */ + //ERR("IntSetParent SetWindowPos 1\n"); co_WinPosSetWindowPos( Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST), pt.x, pt.y, 0, 0, swFlags); - + //ERR("IntSetParent SetWindowPos 2\n"); if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL); return WndOldParent; @@ -1302,6 +1318,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) if (hWndChild == IntGetDesktopWindow()) { + ERR("UserSetParent Access Denied!\n"); EngSetLastError(ERROR_ACCESS_DENIED); return( NULL); } @@ -1310,6 +1327,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) { if (!(WndParent = UserGetWindowObject(hWndNewParent))) { + ERR("UserSetParent Bad New Parent!\n"); return( NULL); } } @@ -1323,6 +1341,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) if (!(Wnd = UserGetWindowObject(hWndChild))) { + ERR("UserSetParent Bad Child!\n"); return( NULL); } @@ -1762,13 +1781,14 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, pWnd->InternalPos.MaxPos.x = pWnd->InternalPos.MaxPos.y = -1; pWnd->InternalPos.IconPos.x = pWnd->InternalPos.IconPos.y = -1; - IntReferenceMessageQueue(pWnd->head.pti->MessageQueue); if (pWnd->spwndParent != NULL && Cs->hwndParent != 0) { pWnd->HideFocus = pWnd->spwndParent->HideFocus; pWnd->HideAccel = pWnd->spwndParent->HideAccel; } + pWnd->head.pti->cWindows++; + if (Class->hIcon && !Class->hIconSm) { Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON, @@ -1962,8 +1982,8 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, Class->atomClassName != gpsi->atomSysClass[ICLS_IME] && pti != pWnd->spwndOwner->head.pti) { - ERR("CreateWindow Owner in.\n"); - //UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE); + //ERR("CreateWindow Owner in.\n"); + UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE); } } @@ -2203,6 +2223,15 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, Cs->lpszName = (LPCWSTR) WindowName; Cs->lpszClass = (LPCWSTR) ClassName; + if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) + { + if (ParentWindow != co_GetDesktopWindow(Window)) + { + Cs->x += ParentWindow->rcClient.left; + Cs->y += ParentWindow->rcClient.top; + } + } + /* Send the WM_GETMINMAXINFO message */ Size.cx = Cs->cx; Size.cy = Cs->cy; @@ -2220,6 +2249,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, Window->rcWindow.top = Cs->y; Window->rcWindow.right = Cs->x + Size.cx; Window->rcWindow.bottom = Cs->y + Size.cy; +/* if (0 != (Window->style & WS_CHILD) && ParentWindow) { // ERR("co_UserCreateWindowEx(): Offset rcWindow\n"); @@ -2227,6 +2257,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, ParentWindow->rcClient.left, ParentWindow->rcClient.top); } +*/ Window->rcClient = Window->rcWindow; /* Link the window */ @@ -2239,8 +2270,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, IntLinkHwnd(Window, hwndInsertAfter); } - // Remove flags that are retro. - if (!(Window->state2 & WNDS2_WIN31COMPAT)) // FIXME: support version flags. + if (!(Window->state2 & WNDS2_WIN31COMPAT)) { if (Class->style & CS_PARENTDC && !(ParentWindow->style & WS_CLIPCHILDREN)) Window->style &= ~(WS_CLIPSIBLINGS | WS_CLIPCHILDREN); @@ -2252,8 +2282,8 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, { if (pti != Window->spwndParent->head.pti) { - ERR("CreateWindow Parent in.\n"); - //UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE); + //ERR("CreateWindow Parent in.\n"); + UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE); } } } @@ -2267,14 +2297,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, } /* Send the WM_NCCALCSIZE message */ + { + // RECT rc; MaxPos.x = Window->rcWindow.left; MaxPos.y = Window->rcWindow.top; Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient); + //rc = Window->rcWindow; + //Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)&rc); + //Window->rcClient = rc; RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left, MaxPos.y - Window->rcWindow.top); - + } /* Send the WM_CREATE message. */ Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs); @@ -2593,8 +2628,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) { if (Window->spwndOwner) { - ERR("DestroyWindow Owner out.\n"); - //UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE); + //ERR("DestroyWindow Owner out.\n"); + UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE); } } } @@ -2632,8 +2667,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window) { if (!IntIsTopLevelWindow(Window)) { - ERR("DestroyWindow Parent out.\n"); - //UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE); + //ERR("DestroyWindow Parent out.\n"); + UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE); } } } @@ -3377,9 +3412,12 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView) if (ti->pDeskInfo) { ti->pDeskInfo->hShellWindow = hwndShell; + ti->pDeskInfo->spwndShell = WndShell; ti->pDeskInfo->ppiShellProcess = ti->ppi; } + UserRegisterHotKey(WndShell, SC_TASKLIST, MOD_CONTROL, VK_ESCAPE); + UserDerefObjectCo(WndShell); ObDereferenceObject(WinStaObject); @@ -3579,6 +3617,12 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi) else Window->ExStyle &= ~WS_EX_WINDOWEDGE; + if ((Style.styleOld ^ Style.styleNew) & WS_VISIBLE) + { + if (Style.styleOld & WS_VISIBLE) Window->head.pti->cVisWindows--; + if (Style.styleNew & WS_VISIBLE) Window->head.pti->cVisWindows++; + DceResetActiveDCEs( Window ); + } Window->style = (DWORD)Style.styleNew; co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style); break; diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index ccaa0c2a968..bc4cc6598ce 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -237,6 +237,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd) if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) ) { UserRefObjectCo(pWndSetActive, &Ref); + //ERR("ActivateOtherWindowMin Set FG 1\n"); co_IntSetForegroundWindow(pWndSetActive); UserDerefObjectCo(pWndSetActive); //ERR("AOWM 2 Exit Good\n"); @@ -273,6 +274,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd) if ((pWndSetActive = pWndTemp)) { UserRefObjectCo(pWndSetActive, &Ref); + //ERR("ActivateOtherWindowMin Set FG 2\n"); co_IntSetForegroundWindow(pWndSetActive); UserDerefObjectCo(pWndSetActive); //ERR("AOWM 3 Exit Good\n"); @@ -299,7 +301,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL) if (style & WS_MINIMIZE) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; return TRUE; - /* FIXME: This window could be disable because the child that closed + /* FIXME: This window could be disable because the child that closed was a popup. */ //return !(style & WS_DISABLED); } @@ -314,7 +316,6 @@ VOID FASTCALL co_WinPosActivateOtherWindow(PWND Wnd) { PWND WndTo = NULL; - HWND Fg, previous; USER_REFERENCE_ENTRY Ref; ASSERT_REFS_CO(Wnd); @@ -345,26 +346,24 @@ done: if (WndTo) UserRefObjectCo(WndTo, &Ref); - Fg = UserGetForegroundWindow(); - if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL?? No, rule #4. + if (!gpqForeground || Wnd == gpqForeground->spwndActive) { - /* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */ + /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */ + //ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo); if (co_IntSetForegroundWindow(WndTo)) { - UserDerefObjectCo(WndTo); + if (WndTo) UserDerefObjectCo(WndTo); return; } } - - if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE,FALSE) || /* Ok for WndTo to be NULL here */ - !previous) + //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo); + if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE)) /* Ok for WndTo to be NULL here */ { - co_IntSetActiveWindow(0,NULL,FALSE,TRUE,FALSE); + co_IntSetActiveWindow(0,FALSE,TRUE,FALSE); } if (WndTo) UserDerefObjectCo(WndTo); } - UINT FASTCALL co_WinPosArrangeIconicWindows(PWND parent) @@ -1131,11 +1130,71 @@ FixClientRect(PRECTL ClientRect, PRECTL WindowRect) ClientRect->bottom = WindowRect->bottom; } } +/*********************************************************************** + * get_valid_rects + * + * Compute the valid rects from the old and new client rect and WVR_* flags. + * Helper for WM_NCCALCSIZE handling. + */ +static +VOID FASTCALL +get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid ) +{ + int cx, cy; + + if (flags & WVR_REDRAW) + { + RECTL_vSetEmptyRect( &valid[0] ); + RECTL_vSetEmptyRect( &valid[1] ); + return; + } + + if (flags & WVR_VALIDRECTS) + { + if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) || + !RECTL_bIntersectRect( &valid[1], &valid[1], old_client )) + { + RECTL_vSetEmptyRect( &valid[0] ); + RECTL_vSetEmptyRect( &valid[1] ); + return; + } + flags = WVR_ALIGNLEFT | WVR_ALIGNTOP; + } + else + { + valid[0] = *new_client; + valid[1] = *old_client; + } + + /* make sure the rectangles have the same size */ + cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left ); + cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top ); + + if (flags & WVR_ALIGNBOTTOM) + { + valid[0].top = valid[0].bottom - cy; + valid[1].top = valid[1].bottom - cy; + } + else + { + valid[0].bottom = valid[0].top + cy; + valid[1].bottom = valid[1].top + cy; + } + if (flags & WVR_ALIGNRIGHT) + { + valid[0].left = valid[0].right - cx; + valid[1].left = valid[1].right - cx; + } + else + { + valid[0].right = valid[0].left + cx; + valid[1].right = valid[1].left + cx; + } +} static LONG FASTCALL -co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, - RECT* WindowRect, RECT* ClientRect) +co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL* ClientRect, RECTL* validRects) { PWND Parent; UINT wvrFlags = 0; @@ -1148,9 +1207,10 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, NCCALCSIZE_PARAMS params; WINDOWPOS winposCopy; - params.rgrc[0] = *WindowRect; - params.rgrc[1] = Window->rcWindow; - params.rgrc[2] = Window->rcClient; + params.rgrc[0] = *WindowRect; // new coordinates of a window that has been moved or resized + params.rgrc[1] = Window->rcWindow; // window before it was moved or resized + params.rgrc[2] = Window->rcClient; // client area before the window was moved or resized + Parent = Window->spwndParent; if (0 != (Window->style & WS_CHILD) && Parent) { @@ -1161,6 +1221,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left, - Parent->rcClient.top); } + params.lppos = &winposCopy; winposCopy = *WinPos; @@ -1170,7 +1231,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, if (params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom) { - *ClientRect = params.rgrc[0]; + *ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize if ((Window->style & WS_CHILD) && Parent) { RECTL_vOffsetRect(ClientRect, Parent->rcClient.left, @@ -1179,21 +1240,30 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, FixClientRect(ClientRect, WindowRect); } - /* FIXME: WVR_ALIGNxxx */ - if (ClientRect->left != Window->rcClient.left || ClientRect->top != Window->rcClient.top) { WinPos->flags &= ~SWP_NOCLIENTMOVE; } - if ((ClientRect->right - ClientRect->left != - Window->rcClient.right - Window->rcClient.left) || - (ClientRect->bottom - ClientRect->top != - Window->rcClient.bottom - Window->rcClient.top)) + if (ClientRect->right - ClientRect->left != + Window->rcClient.right - Window->rcClient.left) { WinPos->flags &= ~SWP_NOCLIENTSIZE; } + else + wvrFlags &= ~WVR_HREDRAW; + + if (ClientRect->bottom - ClientRect->top != + Window->rcClient.bottom - Window->rcClient.top) + { + WinPos->flags &= ~SWP_NOCLIENTSIZE; + } + else + wvrFlags &= ~WVR_VREDRAW; + + validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination rectangle + validRects[1] = params.rgrc[2]; // third rectangle contains the valid source rectangle } else { @@ -1205,6 +1275,13 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, } } + if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW)) + { + RECTL_vSetEmptyRect( &validRects[0] ); + RECTL_vSetEmptyRect( &validRects[1] ); + } + else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects ); + return wvrFlags; } @@ -1215,15 +1292,46 @@ co_WinPosDoWinPosChanging(PWND Window, PRECTL WindowRect, PRECTL ClientRect) { - INT X, Y; - ASSERT_REFS_CO(Window); + /* Send WM_WINDOWPOSCHANGING message */ + if (!(WinPos->flags & SWP_NOSENDCHANGING)) { co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos); } + /* Calculate new position and size */ + + *WindowRect = Window->rcWindow; + *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow : Window->rcClient; + + if (!(WinPos->flags & SWP_NOSIZE)) + { + if (Window->style & WS_MINIMIZE) + { + WindowRect->right = WindowRect->left + UserGetSystemMetrics(SM_CXICON); + WindowRect->bottom = WindowRect->top + UserGetSystemMetrics(SM_CYICON); + } + else + { + WindowRect->right = WindowRect->left + WinPos->cx; + WindowRect->bottom = WindowRect->top + WinPos->cy; + } + } +#if 0 + if (!(WinPos->flags & SWP_NOMOVE)) + { + WindowRect->left = WinPos->x; + WindowRect->top = WinPos->y; + WindowRect->right += WinPos->x - Window->rcWindow.left; + WindowRect->bottom += WinPos->y - Window->rcWindow.top; + RECTL_vOffsetRect(ClientRect, + WinPos->x - Window->rcWindow.left, + WinPos->y - Window->rcWindow.top); + + } + *WindowRect = Window->rcWindow; *ClientRect = Window->rcClient; @@ -1232,22 +1340,26 @@ co_WinPosDoWinPosChanging(PWND Window, WindowRect->right = WindowRect->left + WinPos->cx; WindowRect->bottom = WindowRect->top + WinPos->cy; } - +#endif if (!(WinPos->flags & SWP_NOMOVE)) { + INT X, Y; PWND Parent; X = WinPos->x; Y = WinPos->y; + //ERR("Not SWP_NOMOVE\n"); Parent = Window->spwndParent; - if ((0 != (Window->style & WS_CHILD)) && Parent) + if ((0 != (Window->style & WS_CHILD)) && Parent && + Parent != Window->head.rpdesk->pDeskInfo->spwnd) { + //ERR("Not SWP_NOMOVE Parent client offset\n"); X += Parent->rcClient.left; Y += Parent->rcClient.top; } - WindowRect->left = X; - WindowRect->top = Y; - WindowRect->right += X - Window->rcWindow.left; + WindowRect->left = X; + WindowRect->top = Y; + WindowRect->right += X - Window->rcWindow.left; WindowRect->bottom += Y - Window->rcWindow.top; RECTL_vOffsetRect(ClientRect, X - Window->rcWindow.left, @@ -1256,6 +1368,10 @@ co_WinPosDoWinPosChanging(PWND Window, WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; + TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n", + WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y, + WinPos->cx, WinPos->cy, WinPos->flags ); + return TRUE; } @@ -1396,6 +1512,21 @@ static BOOL FASTCALL WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) { + PWND Parent; + POINT pt; + + /* Finally make sure that all coordinates are valid */ + if (WinPos->x < -32768) WinPos->x = -32768; + else if (WinPos->x > 32767) WinPos->x = 32767; + if (WinPos->y < -32768) WinPos->y = -32768; + else if (WinPos->y > 32767) WinPos->y = 32767; + + WinPos->cx = max(WinPos->cx, 0); + WinPos->cy = max(WinPos->cy, 0); + + Parent = UserGetAncestor( Wnd, GA_PARENT ); + if (!IntIsWindowVisible( Parent )) WinPos->flags |= SWP_NOREDRAW; + if (Wnd->style & WS_VISIBLE) { WinPos->flags &= ~SWP_SHOWWINDOW; @@ -1407,9 +1538,6 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) WinPos->flags |= SWP_NOREDRAW; } - WinPos->cx = max(WinPos->cx, 0); - WinPos->cy = max(WinPos->cy, 0); - /* Check for right size */ if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx && Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy) @@ -1417,10 +1545,15 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) WinPos->flags |= SWP_NOSIZE; } + pt.x = WinPos->x; + pt.y = WinPos->y; + IntClientToScreen( Parent, &pt ); +// ERR("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos->x,WinPos->y,pt.x,pt.y); /* Check for right position */ - if (Wnd->rcWindow.left == WinPos->x && - Wnd->rcWindow.top == WinPos->y) + if (Wnd->rcWindow.left == pt.x && + Wnd->rcWindow.top == pt.y) { +// ERR("In right pos\n"); WinPos->flags |= SWP_NOMOVE; } @@ -1526,6 +1659,7 @@ co_WinPosSetWindowPos( WINDOWPOS WinPos; RECTL NewWindowRect; RECTL NewClientRect; + RECTL valid_rects[2]; PROSRGNDATA VisRgn; HRGN VisBefore = NULL; HRGN VisAfter = NULL; @@ -1543,7 +1677,7 @@ co_WinPosSetWindowPos( ASSERT_REFS_CO(Window); - /* FIXME: Get current active window from active queue. */ + /* FIXME: Get current active window from active queue. Why? since r2915. */ bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y); @@ -1555,6 +1689,27 @@ co_WinPosSetWindowPos( WinPos.cy = cy; WinPos.flags = flags; + if ( flags & SWP_ASYNCWINDOWPOS ) + { + LRESULT lRes; + PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS), USERTAG_SWP); + if ( ppos ) + { + WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag. + *ppos = WinPos; + /* Yes it's a pointer inside Win32k! */ + lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos); + /* We handle this the same way as Event Hooks and Hooks. */ + if ( !lRes ) + { + ExFreePoolWithTag(ppos, USERTAG_SWP); + return FALSE; + } + return TRUE; + } + return FALSE; + } + co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect); // HWND_NOTOPMOST is redirected in WinPosFixupFlags. @@ -1610,9 +1765,11 @@ co_WinPosSetWindowPos( } } - WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect); + WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects); - TRACE("co_WinPosDoNCCALCSize returned %lu\n", WvrFlags); +// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags, +// valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom, +// valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom); /* Validate link windows. (also take into account shell window in hwndShellWindow) */ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow()) @@ -1624,6 +1781,7 @@ co_WinPosSetWindowPos( if ((ParentWindow = Window->spwndParent)) // Must have a Parent window! { + //ERR("SetWindowPos has parent window.\n"); if (WinPos.hwndInsertAfter == HWND_TOPMOST) { InsertAfterWindow = NULL; @@ -1682,20 +1840,8 @@ co_WinPosSetWindowPos( OldWindowRect = Window->rcWindow; OldClientRect = Window->rcClient; - - if (OldClientRect.bottom - OldClientRect.top == - NewClientRect.bottom - NewClientRect.top) - { - WvrFlags &= ~WVR_VREDRAW; - } - - if (OldClientRect.right - OldClientRect.left == - NewClientRect.right - NewClientRect.left) - { - WvrFlags &= ~WVR_HREDRAW; - } - - /* FIXME: Actually do something with WVR_VALIDRECTS */ + //ERR("SetWindowPos OldWindowRect: %d %d %d %d\n", OldWindowRect.left,OldWindowRect.top,OldWindowRect.right,OldWindowRect.bottom); + //ERR("SetWindowPos OldClientRect: %d %d %d %d\n", OldClientRect.left,OldClientRect.top,OldClientRect.right,OldClientRect.bottom); if (NewClientRect.left != OldClientRect.left || NewClientRect.top != OldClientRect.top) @@ -1708,6 +1854,9 @@ co_WinPosSetWindowPos( Window->rcWindow = NewWindowRect; Window->rcClient = NewClientRect; + //ERR("SetWindowPos NewWindowRect: %d %d %d %d\n", NewWindowRect.left,NewWindowRect.top,NewWindowRect.right,NewWindowRect.bottom); + //ERR("SetWindowPos NewClientRect: %d %d %d %d\n", NewClientRect.left,NewClientRect.top,NewClientRect.right,NewClientRect.bottom); + /* erase parent when hiding or resizing child */ if (WinPos.flags & SWP_HIDEWINDOW) { @@ -1721,6 +1870,7 @@ co_WinPosSetWindowPos( co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0); Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE ); + Window->head.pti->cVisWindows--; IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } else if (WinPos.flags & SWP_SHOWWINDOW) @@ -1729,6 +1879,7 @@ co_WinPosSetWindowPos( co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0); Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 ); + Window->head.pti->cVisWindows++; IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } @@ -1955,7 +2106,10 @@ co_WinPosSetWindowPos( else { //ERR("SetWindowPos Set FG Window!\n"); - co_IntSetForegroundWindow(Window); + if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW? + co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests. + else + co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow. } } @@ -2036,7 +2190,7 @@ co_WinPosSendSizeMove(PWND Wnd) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam); - if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP ) + if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP ) lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top); else lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left, Wnd->rcClient.top-Wnd->spwndParent->rcClient.top); @@ -2056,9 +2210,9 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) LONG style; PWND Parent; PTHREADINFO pti; - // BOOL ShowOwned = FALSE; // HRGN VisibleRgn; - + //ERR("co_WinPosShowWindow START\n"); + BOOL ShowOwned = FALSE; ASSERT_REFS_CO(Wnd); pti = PsGetCurrentThreadWin32Thread(); @@ -2071,6 +2225,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) { if (!WasVisible) { + //ERR("co_WinPosShowWindow Exit Bad\n"); return(FALSE); } Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE; @@ -2091,11 +2246,12 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_NOACTIVATE; if (!(style & WS_MINIMIZE)) { - //IntShowOwnedPopups(Wnd, FALSE ); + IntShowOwnedPopups(Wnd, FALSE ); // Fix wine Win test_SetFocus todo #1 & #2, if (Cmd == SW_SHOWMINIMIZED) { + //ERR("co_WinPosShowWindow Set focus 1\n"); if ((style & (WS_CHILD | WS_POPUP)) == WS_CHILD) co_UserSetFocus(Wnd->spwndParent); else @@ -2114,7 +2270,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } break; @@ -2125,7 +2284,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_SHOWWINDOW; if (!(style & WS_MAXIMIZE)) { - //ShowOwned = TRUE; + ShowOwned = TRUE; Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) | SWP_FRAMECHANGED; @@ -2139,7 +2298,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good 1\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } break; @@ -2177,7 +2339,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Swp |= SWP_FRAMECHANGED; } else //// + { + //ERR("co_WinPosShowWindow Exit Good 3\n"); return TRUE; + } Swp |= SWP_NOSIZE | SWP_NOMOVE; } if ( style & WS_CHILD && @@ -2187,6 +2352,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) break; default: + //ERR("co_WinPosShowWindow Exit Good 4\n"); return WasVisible; } @@ -2214,7 +2380,8 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) Wnd->pcls->style & CS_SAVEBITS && ((Cmd == SW_SHOW) || (Cmd == SW_NORMAL))) { - co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE,FALSE); + ERR("WinPosShowWindow Set active\n"); + UserSetActiveWindow(Wnd); Swp |= SWP_NOACTIVATE | SWP_NOZORDER; } #endif @@ -2242,7 +2409,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); - //if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE ); + if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE ); if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE)) { @@ -2281,6 +2448,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd) // Fix wine Win test_SetFocus todo #3, if (!(style & WS_CHILD)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_ACTIVATE, WA_ACTIVE, 0); } + //ERR("co_WinPosShowWindow EXIT\n"); return(WasVisible); } diff --git a/win32ss/user/user32/windows/prop.c b/win32ss/user/user32/windows/prop.c index 1b06d7f58bb..8f9b1b8c2c4 100644 --- a/win32ss/user/user32/windows/prop.c +++ b/win32ss/user/user32/windows/prop.c @@ -53,7 +53,6 @@ IntGetProp(HWND hWnd, ATOM Atom) for (i = 0; i < pWnd->PropListItems; i++ ) { Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry); - if (!Property) break; if (Property->Atom == Atom) { return(Property); diff --git a/win32ss/user/winsrv/consrv/condrv/conoutput.c b/win32ss/user/winsrv/consrv/condrv/conoutput.c index a4f388739ec..27bbe48837d 100644 --- a/win32ss/user/winsrv/consrv/condrv/conoutput.c +++ b/win32ss/user/winsrv/consrv/condrv/conoutput.c @@ -237,8 +237,6 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, { BOOL Success; - DPRINT1("ConDrvSetConsolePalette\n"); - /* * Parameters validation */ @@ -256,11 +254,9 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, ASSERT(Console == Buffer->Header.Console); /* Change the palette */ - DPRINT1("ConDrvSetConsolePalette calling TermSetPalette\n"); Success = TermSetPalette(Console, PaletteHandle, PaletteUsage); if (Success) { - DPRINT1("TermSetPalette succeeded\n"); /* Free the old palette handle if there was already one set */ if ( Buffer->PaletteHandle != NULL && Buffer->PaletteHandle != PaletteHandle ) @@ -272,10 +268,6 @@ ConDrvSetConsolePalette(IN PCONSOLE Console, Buffer->PaletteHandle = PaletteHandle; Buffer->PaletteUsage = PaletteUsage; } - else - { - DPRINT1("TermSetPalette failed\n"); - } return (Success ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL); } diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index 074e67d7919..02f7260bdf5 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -1340,6 +1340,8 @@ ConDrvSetConsoleWindowInfo(IN PCONSOLE Console, Buffer->ViewSize.X = CapturedWindowRect.Right - CapturedWindowRect.Left + 1; Buffer->ViewSize.Y = CapturedWindowRect.Bottom - CapturedWindowRect.Top + 1; + // TermResizeTerminal(Console); + return STATUS_SUCCESS; } diff --git a/win32ss/user/winsrv/consrv/conoutput.c b/win32ss/user/winsrv/consrv/conoutput.c index bca67fd7ff1..e7ea3846af1 100644 --- a/win32ss/user/winsrv/consrv/conoutput.c +++ b/win32ss/user/winsrv/consrv/conoutput.c @@ -63,38 +63,7 @@ CSR_API(SrvSetConsolePalette) // PGRAPHICS_SCREEN_BUFFER Buffer; PCONSOLE_SCREEN_BUFFER Buffer; - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -\******************************************************************************/ - -#define PALETTESIZE 256 - - LPLOGPALETTE LogPalette; /* Pointer to logical palette */ - PALETTEENTRY MyPalette[] = - { {0, 0, 0x80,0} , // 1 - {0, 0x80,0, 0} , // 2 - {0, 0, 0, 0} , // 0 - {0, 0x80,0x80,0} , // 3 - {0x80,0, 0, 0} , // 4 - {0x80,0, 0x80,0} , // 5 - {0x80,0x80,0, 0} , // 6 - {0xC0,0xC0,0xC0,0} , // 7 - {0x80,0x80,0x80,0} , // 8 - {0, 0, 0xFF,0} , // 9 - {0, 0xFF,0, 0} , // 10 - {0, 0xFF,0xFF,0} , // 11 - {0xFF,0, 0, 0} , // 12 - {0xFF,0, 0xFF,0} , // 13 - {0xFF,0xFF,0, 0} , // 14 - {0xFF,0xFF,0xFF,0} }; // 15 - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -\******************************************************************************/ - - - DPRINT1("SrvSetConsolePalette\n"); + DPRINT("SrvSetConsolePalette\n"); // NOTE: Tests show that this function is used only for graphics screen buffers // and otherwise it returns FALSE + sets last error to invalid handle. @@ -111,51 +80,21 @@ CSR_API(SrvSetConsolePalette) &Buffer, GENERIC_WRITE, TRUE); if (!NT_SUCCESS(Status)) return Status; - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -\******************************************************************************/ - - DPRINT1("HACK: FIXME: SrvSetConsolePalette - Use hacked palette for testing purposes!!\n"); - - LogPalette = (LPLOGPALETTE)ConsoleAllocHeap(HEAP_ZERO_MEMORY, - (sizeof(LOGPALETTE) + - (sizeof(PALETTEENTRY) * PALETTESIZE))); - if (LogPalette) - { - UINT i; - - LogPalette->palVersion = 0x300; - LogPalette->palNumEntries = PALETTESIZE; - - for (i = 0 ; i < PALETTESIZE ; i++) - { - LogPalette->palPalEntry[i] = MyPalette[i % sizeof(MyPalette)/sizeof(MyPalette[0])]; - } - - SetPaletteRequest->PaletteHandle = CreatePalette(LogPalette); - SetPaletteRequest->Usage = SYSPAL_NOSTATIC256; - ConsoleFreeHeap(LogPalette); - } - else - { - DPRINT1("SrvSetConsolePalette - Hacked LogPalette is NULL\n"); - } - -/******************************************************************************\ -|************** HACK! HACK! HACK! HACK! HACK! HACK! HACK! HACK! ***************| -\******************************************************************************/ - - - DPRINT1("ConDrvSetConsolePalette calling...\n"); + /* + * Make the palette handle public, so that it can be + * used by other threads calling GDI functions on it. + * Indeed, the palette handle comes from a console app + * calling ourselves, running in CSRSS. + */ + NtUserConsoleControl(ConsoleMakePalettePublic, + &SetPaletteRequest->PaletteHandle, + sizeof(SetPaletteRequest->PaletteHandle)); Status = ConDrvSetConsolePalette(Buffer->Header.Console, Buffer, SetPaletteRequest->PaletteHandle, SetPaletteRequest->Usage); - DPRINT1("ConDrvSetConsolePalette returned Status 0x%08lx\n", Status); - ConSrvReleaseScreenBuffer(Buffer, TRUE); return Status; } diff --git a/win32ss/user/winsrv/consrv/conoutput.h b/win32ss/user/winsrv/consrv/conoutput.h index c2e59f8c61c..29da4c4c699 100644 --- a/win32ss/user/winsrv/consrv/conoutput.h +++ b/win32ss/user/winsrv/consrv/conoutput.h @@ -40,7 +40,7 @@ NTSTATUS FASTCALL ConDrvCreateScreenBuffer(OUT PCONSOLE_SCREEN_BUFFER* Buffer, VOID NTAPI ConioDeleteScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); // VOID FASTCALL ConioSetActiveScreenBuffer(PCONSOLE_SCREEN_BUFFER Buffer); -// PCONSOLE_SCREEN_BUFFER -// ConDrvGetActiveScreenBuffer(IN PCONSOLE Console); +PCONSOLE_SCREEN_BUFFER +ConDrvGetActiveScreenBuffer(IN PCONSOLE Console); /* EOF */ diff --git a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c index 58267a7c15a..e0fc4f3d4a2 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/graphics.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/graphics.c @@ -46,11 +46,16 @@ GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer) VOID GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc) + PRECT rcView, + PRECT rcFramebuffer) { if (Buffer->BitMap == NULL) return; + rcFramebuffer->left = Buffer->ViewOrigin.X * 1 + rcView->left; + rcFramebuffer->top = Buffer->ViewOrigin.Y * 1 + rcView->top; + rcFramebuffer->right = Buffer->ViewOrigin.X * 1 + rcView->right; + rcFramebuffer->bottom = Buffer->ViewOrigin.Y * 1 + rcView->bottom; + /* Grab the mutex */ NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL); @@ -59,15 +64,15 @@ GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, * the Y-coordinate of the "lower-left corner" of the image, be the DIB * in bottom-up or top-down mode. */ - SetDIBitsToDevice(hDC, - /* Coordinates / size of the repainted rectangle, in the view's frame */ - rc->left, - rc->top, - rc->right - rc->left, - rc->bottom - rc->top, + SetDIBitsToDevice(GuiData->hMemDC, + /* Coordinates / size of the repainted rectangle, in the framebuffer's frame */ + rcFramebuffer->left, + rcFramebuffer->top, + rcFramebuffer->right - rcFramebuffer->left, + rcFramebuffer->bottom - rcFramebuffer->top, /* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */ - Buffer->ViewOrigin.X + rc->left, - Buffer->ViewOrigin.Y + rc->top, + rcFramebuffer->left, + rcFramebuffer->top, 0, Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight Buffer->BitMap, diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h index 0c0f0cdf417..9851a36dffe 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h +++ b/win32ss/user/winsrv/consrv/frontends/gui/guisettings.h @@ -41,20 +41,22 @@ typedef struct _GUI_CONSOLE_DATA { CRITICAL_SECTION Lock; BOOL WindowSizeLock; - HANDLE hGuiInitEvent; - POINT OldCursor; - HWND hWindow; /* Handle to the console's window */ - HICON hIcon; /* Handle to the console's icon (big) */ - HICON hIconSm; /* Handle to the console's icon (small) */ + POINT OldCursor; LONG_PTR WndStyle; LONG_PTR WndStyleEx; BOOL IsWndMax; WINDOWPLACEMENT WndPl; - HPALETTE hSysPalette; /* Handle to the original system palette */ + HWND hWindow; /* Handle to the console's window */ + HDC hMemDC; /* Memory DC holding the console framebuffer */ + HBITMAP hBitmap; /* Console framebuffer */ + HPALETTE hSysPalette; /* Handle to the original system palette */ + + HICON hIcon; /* Handle to the console's icon (big) */ + HICON hIconSm; /* Handle to the console's icon (small) */ /*** The following may be put per-screen-buffer !! ***/ HCURSOR hCursor; /* Handle to the mouse cursor */ diff --git a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c index aaf9dc3753a..437e97a14d6 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/guiterm.c @@ -250,7 +250,7 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord); static VOID NTAPI GuiDrawRegion(IN OUT PFRONTEND This, SMALL_RECT* Region); static VOID -GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData); +GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit); static LRESULT @@ -265,7 +265,6 @@ GuiConsoleHandleSysMenuCommand(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM Ret = FALSE; goto Quit; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; /* @@ -412,16 +411,12 @@ GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData) } static VOID -GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData) +GuiConsoleResizeWindow(PGUI_CONSOLE_DATA GuiData, DWORD WidthUnit, DWORD HeightUnit) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; SCROLLINFO sInfo; DWORD Width, Height; - UINT WidthUnit, HeightUnit; - - GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); Width = Buff->ViewSize.X * WidthUnit + 2 * (GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXEDGE)); @@ -551,6 +546,11 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) ReleaseDC(GuiData->hWindow, hDC); + /* Initialize the terminal framebuffer */ + GuiData->hMemDC = CreateCompatibleDC(NULL); + GuiData->hBitmap = NULL; + GuiData->hSysPalette = NULL; /* Original system palette */ + // FIXME: Keep these instructions here ? /////////////////////////////////// Console->ActiveBuffer->CursorBlinkOn = TRUE; Console->ActiveBuffer->ForceCursorOff = FALSE; @@ -570,8 +570,7 @@ GuiConsoleHandleNcCreate(HWND hWnd, LPCREATESTRUCTW Create) static VOID SmallRectToRect(PGUI_CONSOLE_DATA GuiData, PRECT Rect, PSMALL_RECT SmallRect) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; UINT WidthUnit, HeightUnit; GetScreenBufferSizeUnits(Buffer, GuiData, &WidthUnit, &HeightUnit); @@ -647,13 +646,13 @@ GuiConsoleUpdateSelection(PCONSOLE Console, PCOORD coord) VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc); + PRECT rcView, + PRECT rcFramebuffer); VOID GuiPaintGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc); + PRECT rcView, + PRECT rcFramebuffer); static VOID GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData) @@ -661,49 +660,54 @@ GuiConsoleHandlePaint(PGUI_CONSOLE_DATA GuiData) BOOL Success = TRUE; PCONSOLE Console = GuiData->Console; PCONSOLE_SCREEN_BUFFER ActiveBuffer; - HDC hDC; PAINTSTRUCT ps; + RECT rcPaint; if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) { Success = FALSE; goto Quit; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; - hDC = BeginPaint(GuiData->hWindow, &ps); - if (hDC != NULL && + BeginPaint(GuiData->hWindow, &ps); + if (ps.hdc != NULL && ps.rcPaint.left < ps.rcPaint.right && ps.rcPaint.top < ps.rcPaint.bottom) { EnterCriticalSection(&GuiData->Lock); + /* Compose the current screen-buffer on-memory */ if (GetType(ActiveBuffer) == TEXTMODE_BUFFER) { GuiPaintTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)ActiveBuffer, - GuiData, hDC, &ps.rcPaint); + GuiData, &ps.rcPaint, &rcPaint); } else /* if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) */ { GuiPaintGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)ActiveBuffer, - GuiData, hDC, &ps.rcPaint); + GuiData, &ps.rcPaint, &rcPaint); } + /* Send it to screen */ + BitBlt(ps.hdc, + ps.rcPaint.left, + ps.rcPaint.top, + rcPaint.right - rcPaint.left, + rcPaint.bottom - rcPaint.top, + GuiData->hMemDC, + rcPaint.left, + rcPaint.top, + SRCCOPY); + if (Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) { - RECT rc; - SmallRectToRect(GuiData, &rc, &Console->Selection.srSelection); + SmallRectToRect(GuiData, &rcPaint, &Console->Selection.srSelection); - /* invert the selection */ - if (IntersectRect(&rc, &ps.rcPaint, &rc)) + /* Invert the selection */ + if (IntersectRect(&rcPaint, &ps.rcPaint, &rcPaint)) { - PatBlt(hDC, - rc.left, - rc.top, - rc.right - rc.left, - rc.bottom - rc.top, - DSTINVERT); + InvertRect(ps.hdc, &rcPaint); } } @@ -751,7 +755,6 @@ GuiConsoleHandleKey(PGUI_CONSOLE_DATA GuiData, UINT msg, WPARAM wParam, LPARAM l if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; if (Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) @@ -924,14 +927,15 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + Buff = GuiData->ActiveBuffer; if (GetType(Buff) == TEXTMODE_BUFFER) { GuiInvalidateCell(&Console->TermIFace, Buff->CursorPosition.X, Buff->CursorPosition.Y); Buff->CursorBlinkOn = !Buff->CursorBlinkOn; - if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || (GuiData->OldCursor.y != Buff->CursorPosition.Y)) + if ((GuiData->OldCursor.x != Buff->CursorPosition.X) || + (GuiData->OldCursor.y != Buff->CursorPosition.Y)) { SCROLLINFO xScroll; int OldScrollX = -1, OldScrollY = -1; @@ -946,11 +950,14 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) // If we successfully got the info for the horizontal scrollbar if (OldScrollX >= 0) { - if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) || (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X))) + if ((Buff->CursorPosition.X < Buff->ViewOrigin.X) || + (Buff->CursorPosition.X >= (Buff->ViewOrigin.X + Buff->ViewSize.X))) { // Handle the horizontal scroll bar - if (Buff->CursorPosition.X >= Buff->ViewSize.X) NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1; - else NewScrollX = 0; + if (Buff->CursorPosition.X >= Buff->ViewSize.X) + NewScrollX = Buff->CursorPosition.X - Buff->ViewSize.X + 1; + else + NewScrollX = 0; } else { @@ -960,11 +967,14 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) // If we successfully got the info for the vertical scrollbar if (OldScrollY >= 0) { - if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) || (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y))) + if ((Buff->CursorPosition.Y < Buff->ViewOrigin.Y) || + (Buff->CursorPosition.Y >= (Buff->ViewOrigin.Y + Buff->ViewSize.Y))) { // Handle the vertical scroll bar - if (Buff->CursorPosition.Y >= Buff->ViewSize.Y) NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1; - else NewScrollY = 0; + if (Buff->CursorPosition.Y >= Buff->ViewSize.Y) + NewScrollY = Buff->CursorPosition.Y - Buff->ViewSize.Y + 1; + else + NewScrollY = 0; } else { @@ -999,6 +1009,7 @@ GuiConsoleHandleTimer(PGUI_CONSOLE_DATA GuiData) SetScrollInfo(GuiData->hWindow, SB_VERT, &xScroll, TRUE); } UpdateWindow(GuiData->hWindow); + // InvalidateRect(GuiData->hWindow, NULL, FALSE); GuiData->OldCursor.x = Buff->CursorPosition.X; GuiData->OldCursor.y = Buff->CursorPosition.Y; } @@ -1035,9 +1046,20 @@ GuiConsoleHandleClose(PGUI_CONSOLE_DATA GuiData) static LRESULT GuiConsoleHandleNcDestroy(HWND hWnd) { + PGUI_CONSOLE_DATA GuiData = GuiGetGuiData(hWnd); + KillTimer(hWnd, CONGUI_UPDATE_TIMER); GetSystemMenu(hWnd, TRUE); + if (GuiData) + { + /* Free the terminal framebuffer */ + if (GuiData->hMemDC ) DeleteDC(GuiData->hMemDC); + if (GuiData->hBitmap) DeleteObject(GuiData->hBitmap); + // if (GuiData->hSysPalette) DeleteObject(GuiData->hSysPalette); + if (GuiData->Font) DeleteObject(GuiData->Font); + } + /* Free the GuiData registration */ SetWindowLongPtrW(hWnd, GWLP_USERDATA, (DWORD_PTR)NULL); @@ -1047,8 +1069,7 @@ GuiConsoleHandleNcDestroy(HWND hWnd) static COORD PointToCoord(PGUI_CONSOLE_DATA GuiData, LPARAM lParam) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; COORD Coord; UINT WidthUnit, HeightUnit; @@ -1327,7 +1348,7 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData) if (OpenClipboard(GuiData->hWindow) == TRUE) { PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1354,8 +1375,7 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData) { if (OpenClipboard(GuiData->hWindow) == TRUE) { - // PCONSOLE Console = GuiData->Console; - PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buffer = GuiData->ActiveBuffer; if (GetType(Buffer) == TEXTMODE_BUFFER) { @@ -1380,7 +1400,6 @@ GuiConsoleGetMinMaxInfo(PGUI_CONSOLE_DATA GuiData, PMINMAXINFO minMaxInfo) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return; - // ActiveBuffer = ConDrvGetActiveScreenBuffer(Console); ActiveBuffer = GuiData->ActiveBuffer; GetScreenBufferSizeUnits(ActiveBuffer, GuiData, &WidthUnit, &HeightUnit); @@ -1413,7 +1432,7 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam) if ((GuiData->WindowSizeLock == FALSE) && (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED)) { - PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; DWORD windx, windy, charx, chary; UINT WidthUnit, HeightUnit; @@ -1453,7 +1472,7 @@ GuiConsoleResize(PGUI_CONSOLE_DATA GuiData, WPARAM wParam, LPARAM lParam) Buff->ViewSize.Y = (chary <= Buff->ScreenBufferSize.Y) ? chary : Buff->ScreenBufferSize.Y; } - GuiConsoleResizeWindow(GuiData); + GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit); // Adjust the start of the visible area if we are attempting to show nonexistent areas if ((Buff->ScreenBufferSize.X - Buff->ViewOrigin.X) < Buff->ViewSize.X) Buff->ViewOrigin.X = Buff->ScreenBufferSize.X - Buff->ViewSize.X; @@ -1507,7 +1526,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return 0; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(Console); + Buff = GuiData->ActiveBuffer; if (uMsg == WM_HSCROLL) { @@ -1595,6 +1614,7 @@ GuiConsoleHandleScroll(PGUI_CONSOLE_DATA GuiData, UINT uMsg, WPARAM wParam) SetScrollInfo(GuiData->hWindow, fnBar, &sInfo, TRUE); UpdateWindow(GuiData->hWindow); + // InvalidateRect(GuiData->hWindow, NULL, FALSE); } Quit: @@ -1697,7 +1717,7 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case WM_PALETTECHANGED: { - PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); + PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; DPRINT1("WM_PALETTECHANGED called\n"); @@ -1721,19 +1741,13 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER) if (ActiveBuffer->PaletteHandle) { - /* Get the Device Context of the console window */ - HDC hDC = GetDC(GuiData->hWindow); - DPRINT1("WM_PALETTECHANGED changing palette\n"); - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - /* Release the Device Context and return */ - ReleaseDC(GuiData->hWindow, hDC); + RealizePalette(GuiData->hMemDC); } DPRINT1("WM_PALETTECHANGED quit\n"); @@ -1966,9 +1980,32 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case PM_RESIZE_TERMINAL: { + PCONSOLE_SCREEN_BUFFER Buff = GuiData->ActiveBuffer; + HDC hDC; + HBITMAP hnew, hold; + + DWORD Width, Height; + UINT WidthUnit, HeightUnit; + + GetScreenBufferSizeUnits(Buff, GuiData, &WidthUnit, &HeightUnit); + + Width = Buff->ScreenBufferSize.X * WidthUnit ; + Height = Buff->ScreenBufferSize.Y * HeightUnit; + + /* Recreate the framebuffer */ + hDC = GetDC(GuiData->hWindow); + hnew = CreateCompatibleBitmap(hDC, Width, Height); + ReleaseDC(GuiData->hWindow, hDC); + hold = SelectObject(GuiData->hMemDC, hnew); + if (GuiData->hBitmap) + { + if (hold == GuiData->hBitmap) DeleteObject(GuiData->hBitmap); + } + GuiData->hBitmap = hnew; + /* Resize the window to the user's values */ GuiData->WindowSizeLock = TRUE; - GuiConsoleResizeWindow(GuiData); + GuiConsoleResizeWindow(GuiData, WidthUnit, HeightUnit); GuiData->WindowSizeLock = FALSE; break; } @@ -2063,9 +2100,7 @@ GuiConsoleNotifyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) /* Move and resize the window to the user's values */ /* CAN WE DEADLOCK ?? */ GuiConsoleMoveWindow(GuiData); - GuiData->WindowSizeLock = TRUE; - GuiConsoleResizeWindow(GuiData); - GuiData->WindowSizeLock = FALSE; + SendMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0); /* Switch to full-screen mode if necessary */ if (GuiData->GuiInfo.FullScreen) SwitchFullScreen(GuiData, TRUE); @@ -2423,9 +2458,6 @@ GuiInitFrontEnd(IN OUT PFRONTEND This, } } - /* Original system palette */ - GuiData->hSysPalette = NULL; - /* Mouse is shown by default with its default cursor shape */ GuiData->hCursor = ghDefaultCursor; GuiData->MouseCursorRefCount = 0; @@ -2511,6 +2543,7 @@ GuiDrawRegion(IN OUT PFRONTEND This, SmallRectToRect(GuiData, &RegionRect, Region); /* Do not erase the background: it speeds up redrawing and reduce flickering */ InvalidateRect(GuiData->hWindow, &RegionRect, FALSE); + /**UpdateWindow(GuiData->hWindow);**/ } static VOID NTAPI @@ -2529,7 +2562,7 @@ GuiWriteStream(IN OUT PFRONTEND This, if (NULL == GuiData || NULL == GuiData->hWindow) return; - Buff = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); + Buff = GuiData->ActiveBuffer; if (GetType(Buff) != TEXTMODE_BUFFER) return; if (0 != ScrolledLines) @@ -2578,7 +2611,7 @@ GuiSetCursorInfo(IN OUT PFRONTEND This, { PGUI_CONSOLE_DATA GuiData = This->Data; - if (/*ConDrvGetActiveScreenBuffer(GuiData->Console)*/GuiData->ActiveBuffer == Buff) + if (GuiData->ActiveBuffer == Buff) { GuiInvalidateCell(This, Buff->CursorPosition.X, Buff->CursorPosition.Y); } @@ -2594,7 +2627,7 @@ GuiSetScreenInfo(IN OUT PFRONTEND This, { PGUI_CONSOLE_DATA GuiData = This->Data; - if (/*ConDrvGetActiveScreenBuffer(GuiData->Console)*/GuiData->ActiveBuffer == Buff) + if (GuiData->ActiveBuffer == Buff) { /* Redraw char at old position (remove cursor) */ GuiInvalidateCell(This, OldCursorX, OldCursorY); @@ -2611,11 +2644,6 @@ GuiResizeTerminal(IN OUT PFRONTEND This) PGUI_CONSOLE_DATA GuiData = This->Data; /* Resize the window to the user's values */ - // GuiData->WindowSizeLock = TRUE; - // GuiConsoleResizeWindow(GuiData); - // GuiData->WindowSizeLock = FALSE; - // NOTE: This code ^^ causes deadlocks... - PostMessageW(GuiData->hWindow, PM_RESIZE_TERMINAL, 0, 0); } @@ -2623,15 +2651,14 @@ static VOID NTAPI GuiSetActiveScreenBuffer(IN OUT PFRONTEND This) { PGUI_CONSOLE_DATA GuiData = This->Data; - PCONSOLE_SCREEN_BUFFER ActiveBuffer; // = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); - HDC hDC; + PCONSOLE_SCREEN_BUFFER ActiveBuffer; HPALETTE hPalette; EnterCriticalSection(&GuiData->Lock); GuiData->WindowSizeLock = TRUE; InterlockedExchangePointer(&GuiData->ActiveBuffer, - GuiData->Console->ActiveBuffer); + ConDrvGetActiveScreenBuffer(GuiData->Console)); GuiData->WindowSizeLock = FALSE; LeaveCriticalSection(&GuiData->Lock); @@ -2650,20 +2677,14 @@ GuiSetActiveScreenBuffer(IN OUT PFRONTEND This) DPRINT1("GuiSetActiveScreenBuffer using palette 0x%p\n", hPalette); - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); + /* Set the new palette for the framebuffer */ + SelectPalette(GuiData->hMemDC, hPalette, FALSE); - /* Set the new palette */ - SelectPalette(hDC, hPalette, FALSE); - - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, ActiveBuffer->PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, ActiveBuffer->PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - /* Release the Device Context */ - ReleaseDC(GuiData->hWindow, hDC); + RealizePalette(GuiData->hMemDC); GuiResizeTerminal(This); // ConioDrawConsole(Console); @@ -2674,7 +2695,6 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This, IN PCONSOLE_SCREEN_BUFFER ScreenBuffer) { PGUI_CONSOLE_DATA GuiData = This->Data; - HDC hDC; /* * If we were notified to release a screen buffer that is not actually @@ -2690,19 +2710,13 @@ GuiReleaseScreenBuffer(IN OUT PFRONTEND This, * it ONLY. */ - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); - /* Release the old active palette and set the default one */ - if (GetCurrentObject(hDC, OBJ_PAL) == ScreenBuffer->PaletteHandle) + if (GetCurrentObject(GuiData->hMemDC, OBJ_PAL) == ScreenBuffer->PaletteHandle) { /* Set the new palette */ - SelectPalette(hDC, GuiData->hSysPalette, FALSE); + SelectPalette(GuiData->hMemDC, GuiData->hSysPalette, FALSE); } - /* Release the Device Context */ - ReleaseDC(GuiData->hWindow, hDC); - /* Set the adequate active screen buffer */ if (ScreenBuffer != GuiData->Console->ActiveBuffer) { @@ -2842,7 +2856,6 @@ GuiGetLargestConsoleWindowSize(IN OUT PFRONTEND This, return; } - // ActiveBuffer = ConDrvGetActiveScreenBuffer(GuiData->Console); ActiveBuffer = GuiData->ActiveBuffer; if (ActiveBuffer) { @@ -2873,54 +2886,26 @@ GuiSetPalette(IN OUT PFRONTEND This, HPALETTE PaletteHandle, UINT PaletteUsage) { - BOOL Success = TRUE; PGUI_CONSOLE_DATA GuiData = This->Data; - // PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer; // ConDrvGetActiveScreenBuffer(GuiData->Console); - HDC hDC; HPALETTE OldPalette; - DPRINT1("GuiSetPalette checkpt 0\n"); - - // if (GetType(ActiveBuffer) != GRAPHICS_BUFFER) return FALSE; + // if (GetType(GuiData->ActiveBuffer) != GRAPHICS_BUFFER) return FALSE; if (PaletteHandle == NULL) return FALSE; - DPRINT1("GuiSetPalette checkpt 1\n"); + /* Set the new palette for the framebuffer */ + OldPalette = SelectPalette(GuiData->hMemDC, PaletteHandle, FALSE); + if (OldPalette == NULL) return FALSE; - /* Get the Device Context of the console window */ - hDC = GetDC(GuiData->hWindow); - - DPRINT1("GuiSetPalette calling SelectPalette(0x%p, 0x%p, FALSE)\n", hDC, PaletteHandle); - - /* Set the new palette */ - OldPalette = SelectPalette(hDC, PaletteHandle, FALSE); - DPRINT1("OldPalette = 0x%p\n", OldPalette); - if (OldPalette == NULL) - { - DPRINT1("SelectPalette failed\n"); - Success = FALSE; - goto Quit; - } - - DPRINT1("GuiSetPalette checkpt 2\n"); - - /* Specify the use of the system palette */ - SetSystemPaletteUse(hDC, PaletteUsage); + /* Specify the use of the system palette for the framebuffer */ + SetSystemPaletteUse(GuiData->hMemDC, PaletteUsage); /* Realize the (logical) palette */ - RealizePalette(hDC); - - DPRINT1("GuiData->hSysPalette before == 0x%p\n", GuiData->hSysPalette); + RealizePalette(GuiData->hMemDC); /* Save the original system palette handle */ if (GuiData->hSysPalette == NULL) GuiData->hSysPalette = OldPalette; - DPRINT1("GuiData->hSysPalette after == 0x%p\n", GuiData->hSysPalette); - -Quit: - DPRINT1("GuiSetPalette Quit\n"); - /* Release the Device Context and return */ - ReleaseDC(GuiData->hWindow, hDC); - return Success; + return TRUE; } static ULONG NTAPI diff --git a/win32ss/user/winsrv/consrv/frontends/gui/text.c b/win32ss/user/winsrv/consrv/frontends/gui/text.c index 38bc4413063..313e50c493b 100644 --- a/win32ss/user/winsrv/consrv/frontends/gui/text.c +++ b/win32ss/user/winsrv/consrv/frontends/gui/text.c @@ -185,8 +185,8 @@ GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer) VOID GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, PGUI_CONSOLE_DATA GuiData, - HDC hDC, - PRECT rc) + PRECT rcView, + PRECT rcFramebuffer) { PCONSOLE Console = Buffer->Header.Console; // ASSERT(Console == GuiData->Console); @@ -202,20 +202,25 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, if (Buffer->Buffer == NULL) return; - TopLine = rc->top / GuiData->CharHeight + Buffer->ViewOrigin.Y; - BottomLine = (rc->bottom + (GuiData->CharHeight - 1)) / GuiData->CharHeight - 1 + Buffer->ViewOrigin.Y; - LeftChar = rc->left / GuiData->CharWidth + Buffer->ViewOrigin.X; - RightChar = (rc->right + (GuiData->CharWidth - 1)) / GuiData->CharWidth - 1 + Buffer->ViewOrigin.X; + rcFramebuffer->left = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->left; + rcFramebuffer->top = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->top; + rcFramebuffer->right = Buffer->ViewOrigin.X * GuiData->CharWidth + rcView->right; + rcFramebuffer->bottom = Buffer->ViewOrigin.Y * GuiData->CharHeight + rcView->bottom; + + LeftChar = rcFramebuffer->left / GuiData->CharWidth; + TopLine = rcFramebuffer->top / GuiData->CharHeight; + RightChar = rcFramebuffer->right / GuiData->CharWidth; + BottomLine = rcFramebuffer->bottom / GuiData->CharHeight; + + if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; + if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; LastAttribute = ConioCoordToPointer(Buffer, LeftChar, TopLine)->Attributes; - SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); - SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); + SetTextColor(GuiData->hMemDC, RGBFromAttrib(Console, TextAttribFromAttrib(LastAttribute))); + SetBkColor(GuiData->hMemDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(LastAttribute))); - if (BottomLine >= Buffer->ScreenBufferSize.Y) BottomLine = Buffer->ScreenBufferSize.Y - 1; - if (RightChar >= Buffer->ScreenBufferSize.X) RightChar = Buffer->ScreenBufferSize.X - 1; - - OldFont = SelectObject(hDC, GuiData->Font); + OldFont = SelectObject(GuiData->hMemDC, GuiData->Font); for (Line = TopLine; Line <= BottomLine; Line++) { @@ -232,9 +237,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, */ if (From->Attributes != LastAttribute || (Char - Start == sizeof(LineBuffer) / sizeof(WCHAR))) { - TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + TextOutW(GuiData->hMemDC, + Start * GuiData->CharWidth, + Line * GuiData->CharHeight, LineBuffer, Char - Start); Start = Char; @@ -242,8 +247,8 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, Attribute = From->Attributes; if (Attribute != LastAttribute) { - SetTextColor(hDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); - SetBkColor(hDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); + SetTextColor(GuiData->hMemDC, RGBFromAttrib(Console, TextAttribFromAttrib(Attribute))); + SetBkColor(GuiData->hMemDC, RGBFromAttrib(Console, BkgdAttribFromAttrib(Attribute))); LastAttribute = Attribute; } } @@ -251,9 +256,9 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, *(To++) = (From++)->Char.UnicodeChar; } - TextOutW(hDC, - (Start - Buffer->ViewOrigin.X) * GuiData->CharWidth , - (Line - Buffer->ViewOrigin.Y) * GuiData->CharHeight, + TextOutW(GuiData->hMemDC, + Start * GuiData->CharWidth, + Line * GuiData->CharHeight, LineBuffer, RightChar - Start + 1); } @@ -271,30 +276,25 @@ GuiPaintTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer, TopLine <= CursorY && CursorY <= BottomLine) { CursorHeight = ConioEffectiveCursorSize(Console, GuiData->CharHeight); + Attribute = ConioCoordToPointer(Buffer, Buffer->CursorPosition.X, Buffer->CursorPosition.Y)->Attributes; + if (Attribute == DEFAULT_SCREEN_ATTRIB) Attribute = Buffer->ScreenDefaultAttrib; - if (Attribute != DEFAULT_SCREEN_ATTRIB) - { - CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); - } - else - { - CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Buffer->ScreenDefaultAttrib)); - } + CursorBrush = CreateSolidBrush(RGBFromAttrib(Console, Attribute)); + OldBrush = SelectObject(GuiData->hMemDC, CursorBrush); - OldBrush = SelectObject(hDC, CursorBrush); - PatBlt(hDC, - (CursorX - Buffer->ViewOrigin.X) * GuiData->CharWidth, - (CursorY - Buffer->ViewOrigin.Y) * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), + PatBlt(GuiData->hMemDC, + CursorX * GuiData->CharWidth, + CursorY * GuiData->CharHeight + (GuiData->CharHeight - CursorHeight), GuiData->CharWidth, CursorHeight, PATCOPY); - SelectObject(hDC, OldBrush); + SelectObject(GuiData->hMemDC, OldBrush); DeleteObject(CursorBrush); } } - SelectObject(hDC, OldFont); + SelectObject(GuiData->hMemDC, OldFont); } /* EOF */