mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[HOTPLUG] Display devices that are attached to a removable device
This commit is contained in:
parent
7db342f8a1
commit
68b6639ade
2 changed files with 238 additions and 55 deletions
|
@ -8,12 +8,17 @@
|
|||
|
||||
#include "hotplug.h"
|
||||
|
||||
#include <initguid.h>
|
||||
#include <devguid.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
typedef struct _HOTPLUG_DATA
|
||||
{
|
||||
SP_CLASSIMAGELIST_DATA ImageListData;
|
||||
DWORD dwFlags;
|
||||
} HOTPLUG_DATA, *PHOTPLUG_DATA;
|
||||
|
||||
|
||||
|
@ -26,6 +31,197 @@ APPLET Applets[NUM_APPLETS] =
|
|||
{IDI_HOTPLUG, IDS_CPLNAME, IDS_CPLDESCRIPTION, InitApplet}
|
||||
};
|
||||
|
||||
static
|
||||
DWORD
|
||||
GetHotPlugFlags(VOID)
|
||||
{
|
||||
HKEY hKey = NULL;
|
||||
DWORD dwFlags = 0;
|
||||
DWORD dwSize, dwError;
|
||||
|
||||
dwError = RegOpenKeyExW(HKEY_CURRENT_USER,
|
||||
REGSTR_PATH_SYSTRAY,
|
||||
0,
|
||||
KEY_READ,
|
||||
&hKey);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
dwSize = sizeof(dwFlags);
|
||||
dwError = RegQueryValueExW(hKey,
|
||||
L"HotPlugFlags",
|
||||
NULL,
|
||||
NULL,
|
||||
(LPBYTE)&dwFlags,
|
||||
&dwSize);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
dwFlags = 0;
|
||||
|
||||
done:
|
||||
if (hKey != NULL)
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return dwFlags;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
DWORD
|
||||
SetHotPlugFlags(
|
||||
_In_ DWORD dwFlags)
|
||||
{
|
||||
HKEY hKey = NULL;
|
||||
DWORD dwError;
|
||||
|
||||
dwError = RegCreateKeyExW(HKEY_CURRENT_USER,
|
||||
REGSTR_PATH_SYSTRAY,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_WRITE,
|
||||
NULL,
|
||||
&hKey,
|
||||
NULL);
|
||||
if (dwError != ERROR_SUCCESS)
|
||||
goto done;
|
||||
|
||||
dwError = RegSetValueExW(hKey,
|
||||
L"HotPlugFlags",
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&dwFlags,
|
||||
sizeof(dwFlags));
|
||||
|
||||
done:
|
||||
if (hKey != NULL)
|
||||
RegCloseKey(hKey);
|
||||
|
||||
return dwError;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
HTREEITEM
|
||||
InsertDeviceTreeItem(
|
||||
_In_ HWND hwndDeviceTree,
|
||||
_In_ HTREEITEM hParent,
|
||||
_In_ DWORD DevInst,
|
||||
_In_ PHOTPLUG_DATA pHotplugData)
|
||||
{
|
||||
WCHAR szDisplayName[40];
|
||||
WCHAR szGuidString[MAX_GUID_STRING_LEN];
|
||||
TVINSERTSTRUCTW tvItem;
|
||||
GUID ClassGuid;
|
||||
INT nClassImage;
|
||||
DWORD dwSize;
|
||||
CONFIGRET cr;
|
||||
|
||||
/* Get the device description */
|
||||
dwSize = sizeof(szDisplayName);
|
||||
cr = CM_Get_DevNode_Registry_Property(DevInst,
|
||||
CM_DRP_DEVICEDESC,
|
||||
NULL,
|
||||
szDisplayName,
|
||||
&dwSize,
|
||||
0);
|
||||
if (cr != CR_SUCCESS)
|
||||
wcscpy(szDisplayName, L"Unknown Device");
|
||||
|
||||
/* Get the class GUID */
|
||||
dwSize = sizeof(szGuidString);
|
||||
cr = CM_Get_DevNode_Registry_Property(DevInst,
|
||||
CM_DRP_CLASSGUID,
|
||||
NULL,
|
||||
szGuidString,
|
||||
&dwSize,
|
||||
0);
|
||||
if (cr == CR_SUCCESS)
|
||||
{
|
||||
pSetupGuidFromString(szGuidString, &ClassGuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&ClassGuid, &GUID_DEVCLASS_UNKNOWN, sizeof(GUID));
|
||||
}
|
||||
|
||||
/* Get the image for the class this device is in */
|
||||
SetupDiGetClassImageIndex(&pHotplugData->ImageListData,
|
||||
&ClassGuid,
|
||||
&nClassImage);
|
||||
|
||||
/* Add it to the device tree */
|
||||
ZeroMemory(&tvItem, sizeof(tvItem));
|
||||
tvItem.hParent = hParent;
|
||||
tvItem.hInsertAfter = TVI_LAST;
|
||||
|
||||
tvItem.item.mask = TVIF_STATE | TVIF_TEXT /*| TVIF_PARAM*/ | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
||||
tvItem.item.state = TVIS_EXPANDED;
|
||||
tvItem.item.stateMask = TVIS_EXPANDED;
|
||||
tvItem.item.pszText = szDisplayName;
|
||||
tvItem.item.iImage = nClassImage;
|
||||
tvItem.item.iSelectedImage = nClassImage;
|
||||
tvItem.item.lParam = (LPARAM)NULL;
|
||||
|
||||
return TreeView_InsertItem(hwndDeviceTree, &tvItem);
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
RecursiveInsertSubDevices(
|
||||
_In_ HWND hwndDeviceTree,
|
||||
_In_ HTREEITEM hParentItem,
|
||||
_In_ DWORD ParentDevInst,
|
||||
_In_ PHOTPLUG_DATA pHotplugData)
|
||||
{
|
||||
HTREEITEM hTreeItem;
|
||||
DEVINST ChildDevInst;
|
||||
CONFIGRET cr;
|
||||
|
||||
DPRINT("RecursiveInsertSubDevices()\n");
|
||||
|
||||
cr = CM_Get_Child(&ChildDevInst, ParentDevInst, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
{
|
||||
DPRINT("No child! %lu\n", cr);
|
||||
return;
|
||||
}
|
||||
|
||||
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
|
||||
hParentItem,
|
||||
ChildDevInst,
|
||||
pHotplugData);
|
||||
if (hTreeItem != NULL)
|
||||
{
|
||||
RecursiveInsertSubDevices(hwndDeviceTree,
|
||||
hTreeItem,
|
||||
ChildDevInst,
|
||||
pHotplugData);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
cr = CM_Get_Sibling(&ChildDevInst, ChildDevInst, 0);
|
||||
if (cr != CR_SUCCESS)
|
||||
{
|
||||
DPRINT("No sibling! %lu\n", cr);
|
||||
return;
|
||||
}
|
||||
|
||||
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
|
||||
hParentItem,
|
||||
ChildDevInst,
|
||||
pHotplugData);
|
||||
if (hTreeItem != NULL)
|
||||
{
|
||||
RecursiveInsertSubDevices(hwndDeviceTree,
|
||||
hTreeItem,
|
||||
ChildDevInst,
|
||||
pHotplugData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
VOID
|
||||
|
@ -33,19 +229,18 @@ EnumHotpluggedDevices(
|
|||
HWND hwndDeviceTree,
|
||||
PHOTPLUG_DATA pHotplugData)
|
||||
{
|
||||
WCHAR szDisplayName[40];
|
||||
SP_DEVINFO_DATA did = { 0 };
|
||||
HDEVINFO hdev;
|
||||
int idev;
|
||||
DWORD dwCapabilities, dwSize;
|
||||
ULONG ulStatus, ulProblem;
|
||||
TVINSERTSTRUCTW tvItem;
|
||||
// HTREEITEM hTreeItem;
|
||||
WCHAR szGuidString[MAX_GUID_STRING_LEN];
|
||||
GUID ClassGuid;
|
||||
INT nClassImage;
|
||||
|
||||
HTREEITEM hTreeItem;
|
||||
CONFIGRET cr;
|
||||
|
||||
|
||||
DPRINT1("EnumHotpluggedDevices()\n");
|
||||
|
||||
TreeView_DeleteAllItems(hwndDeviceTree);
|
||||
|
||||
hdev = SetupDiGetClassDevs(NULL, NULL, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT);
|
||||
|
@ -85,56 +280,18 @@ EnumHotpluggedDevices(
|
|||
((dwCapabilities & CM_DEVCAP_EJECTSUPPORTED) || (ulStatus & DN_DISABLEABLE)) &&
|
||||
ulProblem == 0)
|
||||
{
|
||||
/* Get the device description */
|
||||
dwSize = sizeof(szDisplayName);
|
||||
cr = CM_Get_DevNode_Registry_Property(did.DevInst,
|
||||
CM_DRP_DEVICEDESC,
|
||||
NULL,
|
||||
szDisplayName,
|
||||
&dwSize,
|
||||
0);
|
||||
if (cr != CR_SUCCESS)
|
||||
wcscpy(szDisplayName, L"Unknown Device");
|
||||
hTreeItem = InsertDeviceTreeItem(hwndDeviceTree,
|
||||
TVI_ROOT,
|
||||
did.DevInst,
|
||||
pHotplugData);
|
||||
|
||||
/* Get the class GUID */
|
||||
dwSize = sizeof(szGuidString);
|
||||
cr = CM_Get_DevNode_Registry_Property(did.DevInst,
|
||||
CM_DRP_CLASSGUID,
|
||||
NULL,
|
||||
szGuidString,
|
||||
&dwSize,
|
||||
0);
|
||||
if (cr == CR_SUCCESS)
|
||||
if ((hTreeItem != NULL) && (pHotplugData->dwFlags & HOTPLUG_DISPLAY_DEVICE_COMPONENTS))
|
||||
{
|
||||
pSetupGuidFromString(szGuidString, &ClassGuid);
|
||||
RecursiveInsertSubDevices(hwndDeviceTree,
|
||||
hTreeItem,
|
||||
did.DevInst,
|
||||
pHotplugData);
|
||||
}
|
||||
else
|
||||
{
|
||||
// memcpy(&ClassGuid, GUID_DEVCLASS_UNKNOWN, sizeof(GUID));
|
||||
}
|
||||
|
||||
/* Get the image for the class this device is in */
|
||||
SetupDiGetClassImageIndex(&pHotplugData->ImageListData,
|
||||
&ClassGuid,
|
||||
&nClassImage);
|
||||
|
||||
/* Add it to the device tree */
|
||||
ZeroMemory(&tvItem, sizeof(tvItem));
|
||||
tvItem.hParent = TVI_ROOT;
|
||||
tvItem.hInsertAfter = TVI_FIRST;
|
||||
|
||||
tvItem.item.mask = TVIF_STATE | TVIF_TEXT /*| TVIF_PARAM*/ | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
||||
tvItem.item.state = TVIS_EXPANDED;
|
||||
tvItem.item.stateMask = TVIS_EXPANDED;
|
||||
tvItem.item.pszText = szDisplayName;
|
||||
tvItem.item.iImage = nClassImage;
|
||||
tvItem.item.iSelectedImage = nClassImage;
|
||||
tvItem.item.lParam = (LPARAM)NULL;
|
||||
|
||||
/*hTreeItem =*/ TreeView_InsertItem(hwndDeviceTree, &tvItem);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -154,7 +311,6 @@ SafeRemovalDlgProc(
|
|||
|
||||
UNREFERENCED_PARAMETER(lParam);
|
||||
|
||||
|
||||
pHotplugData = (PHOTPLUG_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
|
||||
|
||||
switch (uMsg)
|
||||
|
@ -168,6 +324,11 @@ SafeRemovalDlgProc(
|
|||
pHotplugData->ImageListData.cbSize = sizeof(pHotplugData->ImageListData);
|
||||
SetupDiGetClassImageList(&pHotplugData->ImageListData);
|
||||
|
||||
pHotplugData->dwFlags = GetHotPlugFlags();
|
||||
|
||||
if (pHotplugData->dwFlags & HOTPLUG_DISPLAY_DEVICE_COMPONENTS)
|
||||
Button_SetCheck(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DISPLAY_COMPONENTS), BST_CHECKED);
|
||||
|
||||
TreeView_SetImageList(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE),
|
||||
pHotplugData->ImageListData.ImageList,
|
||||
TVSIL_NORMAL);
|
||||
|
@ -185,6 +346,23 @@ SafeRemovalDlgProc(
|
|||
EndDialog(hwndDlg, TRUE);
|
||||
break;
|
||||
|
||||
case IDC_SAFE_REMOVE_DISPLAY_COMPONENTS:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
if (pHotplugData != NULL)
|
||||
{
|
||||
if (Button_GetCheck(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DISPLAY_COMPONENTS)) == BST_CHECKED)
|
||||
pHotplugData->dwFlags |= HOTPLUG_DISPLAY_DEVICE_COMPONENTS;
|
||||
else
|
||||
pHotplugData->dwFlags &= ~HOTPLUG_DISPLAY_DEVICE_COMPONENTS;
|
||||
|
||||
SetHotPlugFlags(pHotplugData->dwFlags);
|
||||
|
||||
EnumHotpluggedDevices(GetDlgItem(hwndDlg, IDC_SAFE_REMOVE_DEVICE_TREE),
|
||||
pHotplugData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -238,7 +416,7 @@ InitApplet(
|
|||
LPARAM wParam,
|
||||
LPARAM lParam)
|
||||
{
|
||||
DPRINT1("InitApplet()\n");
|
||||
DPRINT("InitApplet()\n");
|
||||
|
||||
DialogBox(hApplet,
|
||||
MAKEINTRESOURCE(IDD_SAFE_REMOVE_HARDWARE_DIALOG),
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <winuser.h>
|
||||
#include <wincon.h>
|
||||
#include <winreg.h>
|
||||
#include <windowsx.h>
|
||||
#include <commctrl.h>
|
||||
#include <cpl.h>
|
||||
#include <tchar.h>
|
||||
|
@ -15,9 +16,13 @@
|
|||
#include <setupapi.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <dbt.h>
|
||||
#include <regstr.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
/* Hotplug Flags */
|
||||
#define HOTPLUG_DISPLAY_DEVICE_COMPONENTS 0x00000002
|
||||
|
||||
// Globals
|
||||
extern HINSTANCE hApplet;
|
||||
|
||||
|
|
Loading…
Reference in a new issue