From 1dc8d80ca19aa71dbad381ea6839757cdd05641b Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 23 Apr 2024 08:28:38 +0900 Subject: [PATCH] [SHELL32] SHChangeNotify: Add drive, remove drive (#6782) Implementing missing features... JIRA issue: CORE-13950 - Add WM_DEVICECHANGE message handler in the shell window to detect DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE. - Use GetLogicalDrives function to detect drives. - Use SHChangeNotify to send SHCNE_DRIVEADD and SHCNE_DRIVEREMOVED notifications. - Modify CDefView::OnChangeNotify. --- dll/win32/shell32/CDefView.cpp | 2 ++ .../shell32/shelldesktop/CDesktopBrowser.cpp | 35 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dll/win32/shell32/CDefView.cpp b/dll/win32/shell32/CDefView.cpp index 4eba53fb520..76cdf915d82 100644 --- a/dll/win32/shell32/CDefView.cpp +++ b/dll/win32/shell32/CDefView.cpp @@ -2287,6 +2287,7 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & { case SHCNE_MKDIR: case SHCNE_CREATE: + case SHCNE_DRIVEADD: if (bParent0) { if (LV_FindItemByPidl(ILFindLastID(Pidls[0])) == -1) @@ -2297,6 +2298,7 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & break; case SHCNE_RMDIR: case SHCNE_DELETE: + case SHCNE_DRIVEREMOVED: if (bParent0) LV_DeleteItem(ILFindLastID(Pidls[0])); break; diff --git a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp index e5e53441dd1..26bf34d5a08 100644 --- a/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp +++ b/dll/win32/shell32/shelldesktop/CDesktopBrowser.cpp @@ -26,6 +26,8 @@ #include #endif +#include + WINE_DEFAULT_DEBUG_CHANNEL(desktop); static const WCHAR szProgmanClassName[] = L"Progman"; @@ -45,6 +47,7 @@ private: CComPtr m_ChangeNotifyServer; HWND m_hwndChangeNotifyServer; + DWORD m_dwDrives; LRESULT _NotifyTray(UINT uMsg, WPARAM wParam, LPARAM lParam); HRESULT _Resize(); @@ -85,6 +88,7 @@ public: LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnGetChangeNotifyServer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); + LRESULT OnDeviceChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); LRESULT OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled); DECLARE_WND_CLASS_EX(szProgmanClassName, CS_DBLCLKS, COLOR_DESKTOP) @@ -99,6 +103,7 @@ BEGIN_MSG_MAP(CBaseBar) MESSAGE_HANDLER(WM_COMMAND, OnCommand) MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) MESSAGE_HANDLER(WM_DESKTOP_GET_CNOTIFY_SERVER, OnGetChangeNotifyServer) + MESSAGE_HANDLER(WM_DEVICECHANGE, OnDeviceChange) MESSAGE_HANDLER(WM_PROGMAN_OPENSHELLSETTINGS, OnShowOptionsDlg) END_MSG_MAP() @@ -112,7 +117,8 @@ END_COM_MAP() CDesktopBrowser::CDesktopBrowser(): m_hAccel(NULL), m_hWndShellView(NULL), - m_hwndChangeNotifyServer(NULL) + m_hwndChangeNotifyServer(NULL), + m_dwDrives(::GetLogicalDrives()) { } @@ -460,6 +466,33 @@ LRESULT CDesktopBrowser::OnGetChangeNotifyServer(UINT uMsg, WPARAM wParam, LPARA return (LRESULT)m_hwndChangeNotifyServer; } +// Detect DBT_DEVICEARRIVAL and DBT_DEVICEREMOVECOMPLETE +LRESULT CDesktopBrowser::OnDeviceChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) +{ + if (wParam != DBT_DEVICEARRIVAL && wParam != DBT_DEVICEREMOVECOMPLETE) + return 0; + + DWORD dwDrives = ::GetLogicalDrives(); + for (INT iDrive = 0; iDrive <= 'Z' - 'A'; ++iDrive) + { + WCHAR szPath[MAX_PATH]; + DWORD dwBit = (1 << iDrive); + if (!(m_dwDrives & dwBit) && (dwDrives & dwBit)) // The drive is added + { + PathBuildRootW(szPath, iDrive); + SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATHW, szPath, NULL); + } + else if ((m_dwDrives & dwBit) && !(dwDrives & dwBit)) // The drive is removed + { + PathBuildRootW(szPath, iDrive); + SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATHW, szPath, NULL); + } + } + + m_dwDrives = dwDrives; + return 0; +} + extern VOID WINAPI ShowFolderOptionsDialog(UINT Page, BOOL Async); LRESULT CDesktopBrowser::OnShowOptionsDlg(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)