mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
Sync with trunk for console graphics palettes.
svn path=/branches/ntvdm/; revision=60735
This commit is contained in:
@@ -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}};
|
||||
|
||||
@@ -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
|
||||
},
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@ set_cpp(WITH_RTTI WITH_EXCEPTIONS WITH_STL)
|
||||
|
||||
add_definitions(
|
||||
-DWIN32
|
||||
-D__MINGW32__
|
||||
-D__WINDRES__)
|
||||
|
||||
#add_pch(explorer precomp.h)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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<IShellFolderViewCB, ShellBrowser>, public SimpleComObject
|
||||
#endif
|
||||
struct ShellBrowser : public IShellBrowserImpl,
|
||||
public IComSrvBase<IShellFolderViewCB, ShellBrowser>, 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<IShellFolderViewCB, ShellBrowser> super;
|
||||
|
||||
// IShellFolderViewCB
|
||||
virtual HRESULT STDMETHODCALLTYPE MessageSFVCB(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
map<int, int> _image_map;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<DWORD(STDAPICALLTYPE*)(RESTRICTIONS)> pSHRestricted(TEXT("SHELL32"), "SHRestricted");
|
||||
|
||||
if (pSHRestricted && !(*pSHRestricted)(REST_NOTRAYCONTEXTMENU))
|
||||
#endif
|
||||
ShowAppSystemMenu(it);
|
||||
}
|
||||
break;}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -1114,9 +1114,7 @@ struct CtxMenuInterfaces
|
||||
|
||||
IContextMenu2* _pctxmenu2;
|
||||
|
||||
#ifndef __MINGW32__ // IContextMenu3 missing in MinGW (as of 6.2.2005)
|
||||
IContextMenu3* _pctxmenu3;
|
||||
#endif
|
||||
};
|
||||
|
||||
template<typename BASE> struct ExtContextMenuHandlerT
|
||||
@@ -1151,7 +1149,6 @@ template<typename BASE> 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<typename BASE> struct ExtContextMenuHandlerT
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
return super::WndProc(nmsg, wparam, lparam);
|
||||
|
||||
@@ -52,6 +52,7 @@ target_link_libraries(ntdll
|
||||
rtl
|
||||
ntdllsys
|
||||
libcntpr
|
||||
uuid
|
||||
${PSEH_LIB})
|
||||
|
||||
add_pch(ntdll include/ntdll.h)
|
||||
|
||||
+19
-19
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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*/
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,6 +33,7 @@ list(APPEND SOURCE
|
||||
heapuser.c
|
||||
image.c
|
||||
interlck.c
|
||||
memstream.c
|
||||
message.c
|
||||
largeint.c
|
||||
luid.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 <rtl.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -1050,6 +1050,14 @@ KiCallUserMode(
|
||||
IN PULONG OutputLength
|
||||
);
|
||||
|
||||
DECLSPEC_NORETURN
|
||||
VOID
|
||||
FASTCALL
|
||||
KiCallbackReturn(
|
||||
IN PVOID Stack,
|
||||
IN NTSTATUS Status
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitMachineDependent(VOID);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+20
-11
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+137
-2
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+81
-27
@@ -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(
|
||||
|
||||
@@ -93,6 +93,13 @@ GreSetObjectOwner(
|
||||
HGDIOBJ hobj,
|
||||
ULONG ulOwner);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
GreSetObjectOwnerEx(
|
||||
HGDIOBJ hobj,
|
||||
ULONG ulOwner,
|
||||
ULONG Flags);
|
||||
|
||||
INT
|
||||
NTAPI
|
||||
GreGetObject(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+201
-70
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
+98
-77
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
+40
-30
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
+228
-60
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user