Author: gedmurphy
Date: Thu Jun 25 18:59:23 2015
New Revision: 68265
URL:
http://svn.reactos.org/svn/reactos?rev=68265&view=rev
Log:
[DEVMGR]
- Add basic functionality for enabling and disabling devices. Make it accessible via the
toolbar and main menu
- Implement checking whether a device has a problem and if a device can be uninstalled
- Implement getting, setting and removing device flags in the install params
- Fix creating and destroying the (currently empty) context menu
Modified:
trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp
trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h
trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp
trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h
trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/D…
==============================================================================
--- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.cpp [iso-8859-1] Thu Jun 25 18:59:23
2015
@@ -22,10 +22,12 @@
m_ProblemNumber(0),
m_OverlayImage(0)
{
+ ZeroMemory(&m_DevinfoData, sizeof(SP_DEVINFO_DATA));
}
CDeviceNode::~CDeviceNode()
{
+ SetupDiDestroyDeviceInfoList(m_hDevInfo);
}
bool
@@ -36,6 +38,7 @@
CONFIGRET cr;
// ATLASSERT(m_DeviceId == NULL);
+
// Get the length of the device id string
cr = CM_Get_Device_ID_Size(&ulLength, m_DevInst, 0);
@@ -64,6 +67,23 @@
if (m_DeviceId == NULL)
return false;
+ //SP_DEVINFO_DATA DevinfoData;
+ m_hDevInfo = SetupDiCreateDeviceInfoListExW(NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (m_hDevInfo != INVALID_HANDLE_VALUE)
+ {
+ m_DevinfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+ SetupDiOpenDeviceInfoW(m_hDevInfo,
+ m_DeviceId,
+ NULL,
+ 0,
+ &m_DevinfoData);
+ }
+
+
+
// Get the current status of the device
cr = CM_Get_DevNode_Status_Ex(&m_Status,
&m_ProblemNumber,
@@ -145,6 +165,22 @@
return (cr == CR_SUCCESS ? true : false);
}
+bool
+CDeviceNode::HasProblem()
+{
+ CONFIGRET cr;
+ cr = CM_Get_DevNode_Status_Ex(&m_Status,
+ &m_ProblemNumber,
+ m_DevInst,
+ 0,
+ NULL);
+ if (cr == CR_SUCCESS)
+ {
+ return ((m_Status & (DN_HAS_PROBLEM | DN_PRIVATE_PROBLEM)) != 0);
+ }
+
+ return false;
+}
bool
CDeviceNode::IsHidden()
@@ -230,4 +266,155 @@
}
return false;
-}
+}
+
+bool
+CDeviceNode::CanUninstall()
+{
+ CONFIGRET cr;
+ cr = CM_Get_DevNode_Status_Ex(&m_Status,
+ &m_ProblemNumber,
+ m_DevInst,
+ 0,
+ NULL);
+ if (cr == CR_SUCCESS)
+ {
+ return ((m_Status & DN_DISABLEABLE) != 0 &&
+ (m_Status & DN_ROOT_ENUMERATED) == 0);
+ }
+
+ return false;
+}
+
+bool
+CDeviceNode::EnableDevice(
+ _In_ bool Enable,
+ _Out_ bool &NeedsReboot
+ )
+{
+ bool Ret = false;
+ bool Canceled = false;
+
+ SetFlags(DI_NODI_DEFAULTACTION, 0);
+
+ SP_PROPCHANGE_PARAMS pcp;
+ pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+ pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
+ pcp.StateChange = (Enable ? DICS_ENABLE : DICS_DISABLE);
+ pcp.HwProfile = 0;
+
+
+ // check both scopes to make sure we can make the change
+ for (int i = 0; i < 2; i++)
+ {
+ // Check globally first, then check config specific
+ pcp.Scope = (i == 0) ? DICS_FLAG_GLOBAL : DICS_FLAG_CONFIGSPECIFIC;
+
+ if (SetupDiSetClassInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &pcp.ClassInstallHeader,
+ sizeof(SP_PROPCHANGE_PARAMS)))
+ {
+ SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
+ m_hDevInfo,
+ &m_DevinfoData);
+ }
+
+ if (GetLastError() == ERROR_CANCELLED)
+ {
+ Canceled = true;
+ break;
+ }
+ }
+
+ if (Canceled == false)
+ {
+ pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
+ if (SetupDiSetClassInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &pcp.ClassInstallHeader,
+ sizeof(SP_PROPCHANGE_PARAMS)))
+ {
+ SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
+ }
+
+ if (Enable)
+ {
+ pcp.Scope = DICS_FLAG_GLOBAL;
+ if (SetupDiSetClassInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &pcp.ClassInstallHeader,
+ sizeof(SP_PROPCHANGE_PARAMS)))
+ {
+ SetupDiChangeState(m_hDevInfo, &m_DevinfoData);
+ }
+ }
+
+ SetFlags(DI_PROPERTIES_CHANGE, 0);
+
+ NeedsReboot = ((GetFlags() & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0);
+ }
+
+ RemoveFlags(DI_NODI_DEFAULTACTION, 0);
+
+ return true;
+}
+
+DWORD
+CDeviceNode::GetFlags(
+ )
+{
+ SP_DEVINSTALL_PARAMS DevInstallParams;
+ DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &DevInstallParams))
+ {
+ return DevInstallParams.Flags;
+ }
+ return 0;
+}
+
+bool
+CDeviceNode::SetFlags(
+ _In_ DWORD Flags,
+ _In_ DWORD FlagsEx
+ )
+{
+ SP_DEVINSTALL_PARAMS DevInstallParams;
+ DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &DevInstallParams))
+ {
+ DevInstallParams.Flags |= Flags;
+ DevInstallParams.FlagsEx |= FlagsEx;
+ return SetupDiSetDeviceInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &DevInstallParams);
+ }
+ return false;
+}
+
+bool
+CDeviceNode::RemoveFlags(
+ _In_ DWORD Flags,
+ _In_ DWORD FlagsEx
+ )
+{
+ SP_DEVINSTALL_PARAMS DevInstallParams;
+ DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ if (SetupDiGetDeviceInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &DevInstallParams))
+ {
+ DevInstallParams.Flags &= ~Flags;
+ DevInstallParams.FlagsEx &= ~FlagsEx;
+ return SetupDiSetDeviceInstallParamsW(m_hDevInfo,
+ &m_DevinfoData,
+ &DevInstallParams);
+ }
+ return false;
+}
+
+
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/D…
==============================================================================
--- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceNode.h [iso-8859-1] Thu Jun 25 18:59:23
2015
@@ -4,6 +4,8 @@
class CDeviceNode : public CNode
{
private:
+ SP_DEVINFO_DATA m_DevinfoData;
+ HDEVINFO m_hDevInfo;
DEVINST m_DevInst;
ULONG m_Status;
ULONG m_ProblemNumber;
@@ -22,13 +24,31 @@
DEVINST GetDeviceInst() { return m_DevInst; }
int GetOverlayImage() { return m_OverlayImage; }
- bool HasProblem() { return !!(m_ProblemNumber); }
+ bool HasProblem();
bool IsHidden();
bool CanDisable();
bool IsDisabled();
bool IsStarted();
bool IsInstalled();
- bool CanInstall() { return TRUE; } // unimplemented
- bool CanUninstall() { return TRUE; } // unimplemented
+ bool CanUninstall();
+
+ bool EnableDevice(
+ _In_ bool Enable,
+ _Out_ bool &NeedsReboot
+ );
+
+private:
+ bool SetFlags(
+ _In_ DWORD Flags,
+ _In_ DWORD FlagsEx
+ );
+
+ bool RemoveFlags(
+ _In_ DWORD Flags,
+ _In_ DWORD FlagsEx
+ );
+
+ DWORD GetFlags(
+ );
};
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/D…
==============================================================================
--- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.cpp [iso-8859-1] Thu Jun 25 18:59:23
2015
@@ -92,8 +92,7 @@
}
// Create the context menu and make properties the default item
- m_hMenu = LoadMenuW(g_hInstance, MAKEINTRESOURCEW(IDR_POPUP));
- m_hContextMenu = GetSubMenu(m_hMenu, 0);
+ m_hContextMenu = CreatePopupMenu();
SetMenuDefaultItem(m_hContextMenu, IDC_PROPERTIES, FALSE);
return !!(m_hTreeView);
@@ -110,7 +109,7 @@
ZeroMemory(&m_ImageListData, sizeof(SP_CLASSIMAGELIST_DATA));
}
- DestroyMenu(m_hMenu);
+ DestroyMenu(m_hContextMenu);
return true;
}
@@ -167,6 +166,18 @@
ScreenToClient(m_hTreeView, &pt) &&
PtInRect(&rc, pt))
{
+
+ CNode *Node = GetSelectedNode();
+ if (Node && Node->HasProperties())
+ {
+
+ }
+
+
+
+
+
+
INT xPos = GET_X_LPARAM(lParam);
INT yPos = GET_Y_LPARAM(lParam);
@@ -287,6 +298,24 @@
if (Node)
{
return Node->CanDisable();
+ }
+ return false;
+}
+
+bool
+CDeviceView::EnableSelectedDevice(
+ _In_ bool Enable,
+ _Out_ bool &NeedsReboot
+ )
+{
+ CDeviceNode *Node = dynamic_cast<CDeviceNode *>(GetSelectedNode());
+ if (Node)
+ {
+ if (Node->EnableDevice(Enable, NeedsReboot))
+ {
+ Refresh(m_ViewType, true, true);
+ return true;
+ }
}
return false;
}
@@ -362,10 +391,10 @@
0);
if (cr != CR_SUCCESS) return false;
- // Check for devices without a class
+ // Check if this is the unknown class
if (IsEqualGUID(*ClassGuid, GUID_DEVCLASS_UNKNOWN))
{
- // Get device info for all devices for all classes
+ // Get device info for all devices
*hDevInfo = SetupDiGetClassDevsW(NULL,
NULL,
NULL,
@@ -378,7 +407,6 @@
NULL,
NULL,
DIGCF_PRESENT);
-
}
return (hDevInfo != INVALID_HANDLE_VALUE);
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/D…
==============================================================================
--- trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/devmgr/devmgmt/DeviceView.h [iso-8859-1] Thu Jun 25 18:59:23
2015
@@ -78,6 +78,12 @@
bool IsDisabled(
_In_ LPTV_ITEMW TvItem
);
+
+ bool EnableSelectedDevice(
+ _In_ bool Enable,
+ _Out_ bool &NeedsReboot
+ );
+
bool SelDeviceIsStarted();
bool SelDeviceIsInstalled();
Modified: trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/devmgr/devmgmt/M…
==============================================================================
--- trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/devmgr/devmgmt/MainWindow.cpp [iso-8859-1] Thu Jun 25 18:59:23
2015
@@ -507,7 +507,7 @@
{
LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)lParam;
- UINT_PTR idButton = (UINT)lpttt->hdr.idFrom;
+ UINT_PTR idButton = lpttt->hdr.idFrom;
switch (idButton)
{
case IDC_PROPERTIES:
@@ -568,13 +568,19 @@
case IDC_ENABLE_DRV:
{
- MessageBox(m_hMainWnd, L"Not yet implemented", L"Enable
Driver", MB_OK);
+ bool NeedsReboot;
+ if (m_DeviceView->EnableSelectedDevice(true, NeedsReboot) &&
+ NeedsReboot)
+ {
+ MessageBox(m_hMainWnd, L"Rebooting", L"Enable",
MB_OK);
+ }
break;
}
case IDC_DISABLE_DRV:
{
- MessageBox(m_hMainWnd, L"Not yet implemented", L"Disable
Driver", MB_OK);
+ bool NeedsReboot;
+ m_DeviceView->EnableSelectedDevice(false, NeedsReboot);
break;
}