- if the device cannot be opened display information about the parent node
- only administrators can change the status of a device
Modified: trunk/reactos/lib/devmgr/En.rc
Modified: trunk/reactos/lib/devmgr/advprop.c
Modified: trunk/reactos/lib/devmgr/hwpage.c
Modified: trunk/reactos/lib/devmgr/misc.c
Modified: trunk/reactos/lib/devmgr/precomp.h
Modified: trunk/reactos/lib/devmgr/resource.h

Modified: trunk/reactos/lib/devmgr/En.rc
--- trunk/reactos/lib/devmgr/En.rc	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/En.rc	2005-12-03 11:55:07 UTC (rev 19836)
@@ -16,6 +16,7 @@
     IDS_DISABLEDEVICE "Do not use this device (disable)"
     IDS_UNKNOWNDEVICE "Unknown device"
     IDS_NODRIVERLOADED "No drivers are installed for this device."
+    IDS_DEVONPARENT "on %1"
 END
 
 STRINGTABLE

Modified: trunk/reactos/lib/devmgr/advprop.c
--- trunk/reactos/lib/devmgr/advprop.c	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/advprop.c	2005-12-03 11:55:07 UTC (rev 19836)
@@ -49,7 +49,10 @@
 
     HDEVINFO DeviceInfoSet;
     SP_DEVINFO_DATA DeviceInfoData;
-    HANDLE hMachine;
+    HDEVINFO CurrentDeviceInfoSet;
+    SP_DEVINFO_DATA CurrentDeviceInfoData;
+    DEVINST ParentDevInst;
+    HMACHINE hMachine;
     LPCWSTR lpMachineName;
 
     HINSTANCE hComCtl32;
@@ -62,7 +65,8 @@
     BOOL CanDisable : 1;
     BOOL DeviceEnabled : 1;
     BOOL DeviceUsageChanged : 1;
-    BOOL CreatedDevInfoSet : 1;
+    BOOL CloseDevInst : 1;
+    BOOL IsAdmin : 1;
 
     WCHAR szDevName[255];
     WCHAR szTemp[255];
@@ -170,7 +174,7 @@
 ApplyGeneralSettings(IN HWND hwndDlg,
                      IN PDEVADVPROP_INFO dap)
 {
-    if (dap->DeviceUsageChanged)
+    if (dap->DeviceUsageChanged && dap->IsAdmin)
     {
         DEVENABLEACTION SelectedUsageAction;
 
@@ -217,13 +221,14 @@
     HWND hPropSheetDlg;
     BOOL bFlag;
     DWORD i;
+    HDEVINFO DeviceInfoSet = NULL;
+    PSP_DEVINFO_DATA DeviceInfoData = NULL;
 
     hPropSheetDlg = GetParent(hwndDlg);
 
     if (ReOpen)
     {
         PROPSHEETHEADER psh;
-        HDEVINFO hOldDevInfo;
 
         /* switch to the General page */
         PropSheet_SetCurSelByID(hPropSheetDlg,
@@ -254,47 +259,57 @@
         dap->nDevPropSheets = 0;
 
         /* create a new device info set and re-open the device */
-        hOldDevInfo = dap->DeviceInfoSet;
-        dap->DeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL,
-                                                           hwndDlg,
-                                                           dap->lpMachineName,
-                                                           NULL);
-        if (dap->DeviceInfoSet != INVALID_HANDLE_VALUE)
+        if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
         {
-            if (SetupDiOpenDeviceInfo(dap->DeviceInfoSet,
+            SetupDiDestroyDeviceInfoList(dap->CurrentDeviceInfoSet);
+        }
+
+        dap->ParentDevInst = 0;
+        dap->CurrentDeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL,
+                                                                  hwndDlg,
+                                                                  dap->lpMachineName,
+                                                                  NULL);
+        if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+        {
+            if (SetupDiOpenDeviceInfo(dap->CurrentDeviceInfoSet,
                                       dap->szDeviceID,
                                       hwndDlg,
                                       0,
-                                      &dap->DeviceInfoData))
+                                      &dap->CurrentDeviceInfoData))
             {
-                if (dap->CreatedDevInfoSet)
+                if (dap->CloseDevInst)
                 {
-                    SetupDiDestroyDeviceInfoList(hOldDevInfo);
+                    SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
                 }
 
-                dap->CreatedDevInfoSet = TRUE;
+                dap->CloseDevInst = TRUE;
+                dap->DeviceInfoSet = dap->CurrentDeviceInfoSet;
+                dap->DeviceInfoData = dap->CurrentDeviceInfoData;
+                dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
             }
             else
-            {
-                SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
-                dap->DeviceInfoSet = INVALID_HANDLE_VALUE;
-                dap->CreatedDevInfoSet = FALSE;
-            }
+                goto GetParentNode;
         }
         else
         {
-            /* oops, something went wrong, restore the old device info set */
-            dap->DeviceInfoSet = hOldDevInfo;
+GetParentNode:
+            /* get the parent node from the initial devinst */
+            CM_Get_Parent_Ex(&dap->ParentDevInst,
+                             dap->DeviceInfoData.DevInst,
+                             0,
+                             dap->hMachine);
+        }
 
-            if (dap->DeviceInfoSet != INVALID_HANDLE_VALUE)
-            {
-                SetupDiOpenDeviceInfo(dap->DeviceInfoSet,
-                                      dap->szDeviceID,
-                                      hwndDlg,
-                                      0,
-                                      &dap->DeviceInfoData);
-            }
+        if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+        {
+            DeviceInfoSet = dap->CurrentDeviceInfoSet;
+            DeviceInfoData = &dap->CurrentDeviceInfoData;
         }
+        else
+        {
+            DeviceInfoSet = dap->DeviceInfoSet;
+            DeviceInfoData = &dap->DeviceInfoData;
+        }
 
         /* find out how many new device property sheets to add.
            fake a PROPSHEETHEADER structure, we don't plan to
@@ -303,8 +318,8 @@
         psh.dwFlags = 0;
         psh.nPages = 0;
 
-        if (!SetupDiGetClassDevPropertySheets(dap->DeviceInfoSet,
-                                              &dap->DeviceInfoData,
+        if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
+                                              DeviceInfoData,
                                               &psh,
                                               0,
                                               &dap->nDevPropSheets,
@@ -319,8 +334,8 @@
                 psh.phpage = dap->DevPropSheets;
 
                 /* query the new property sheet pages to add */
-                if (SetupDiGetClassDevPropertySheets(dap->DeviceInfoSet,
-                                                     &dap->DeviceInfoData,
+                if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
+                                                     DeviceInfoData,
                                                      &psh,
                                                      dap->nDevPropSheets,
                                                      NULL,
@@ -353,10 +368,23 @@
                 dap->nDevPropSheets = 0;
         }
     }
+    else
+    {
+        if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+        {
+            DeviceInfoSet = dap->CurrentDeviceInfoSet;
+            DeviceInfoData = &dap->CurrentDeviceInfoData;
+        }
+        else
+        {
+            DeviceInfoSet = dap->DeviceInfoSet;
+            DeviceInfoData = &dap->DeviceInfoData;
+        }
+    }
 
     /* get the device name */
-    if (GetDeviceDescriptionString(dap->DeviceInfoSet,
-                                   &dap->DeviceInfoData,
+    if (GetDeviceDescriptionString(DeviceInfoSet,
+                                   DeviceInfoData,
                                    dap->szDevName,
                                    sizeof(dap->szDevName) / sizeof(dap->szDevName[0])))
     {
@@ -366,7 +394,7 @@
     }
 
     /* set the device image */
-    if (SetupDiLoadClassIcon(&dap->DeviceInfoData.ClassGuid,
+    if (SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid,
                              &hIcon,
                              NULL))
     {
@@ -387,7 +415,7 @@
                    dap->szDevName);
 
     /* set the device type edit control text */
-    if (GetDeviceTypeString(&dap->DeviceInfoData,
+    if (GetDeviceTypeString(DeviceInfoData,
                             dap->szTemp,
                             sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
     {
@@ -397,8 +425,8 @@
     }
 
     /* set the device manufacturer edit control text */
-    if (GetDeviceManufacturerString(dap->DeviceInfoSet,
-                                    &dap->DeviceInfoData,
+    if (GetDeviceManufacturerString(DeviceInfoSet,
+                                    DeviceInfoData,
                                     dap->szTemp,
                                     sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
     {
@@ -408,7 +436,8 @@
     }
 
     /* set the device location edit control text */
-    if (GetDeviceLocationString(dap->DeviceInfoData.DevInst,
+    if (GetDeviceLocationString(DeviceInfoData->DevInst,
+                                dap->ParentDevInst,
                                 dap->szTemp,
                                 sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
     {
@@ -418,7 +447,7 @@
     }
 
     /* set the device status edit control text */
-    if (GetDeviceStatusString(dap->DeviceInfoData.DevInst,
+    if (GetDeviceStatusString(DeviceInfoData->DevInst,
                               dap->hMachine,
                               dap->szTemp,
                               sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
@@ -435,14 +464,14 @@
     dap->CanDisable = FALSE;
     dap->DeviceEnabled = FALSE;
 
-    if (CanDisableDevice(dap->DeviceInfoData.DevInst,
+    if (CanDisableDevice(DeviceInfoData->DevInst,
                          dap->hMachine,
                          &bFlag))
     {
         dap->CanDisable = bFlag;
     }
 
-    if (IsDeviceEnabled(dap->DeviceInfoData.DevInst,
+    if (IsDeviceEnabled(DeviceInfoData->DevInst,
                         dap->hMachine,
                         &bFlag))
     {
@@ -452,9 +481,9 @@
     /* enable/disable the device usage controls */
     EnableWindow(GetDlgItem(hwndDlg,
                             IDC_DEVUSAGELABEL),
-                 dap->CanDisable);
+                 dap->CanDisable && dap->IsAdmin);
     EnableWindow(hDevUsage,
-                 dap->CanDisable);
+                 dap->CanDisable && dap->IsAdmin);
 
     /* clear the combobox */
     SendMessage(hDevUsage,
@@ -662,7 +691,7 @@
     PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
     PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
     PDEVADVPROP_INFO DevAdvPropInfo;
-    HANDLE hMachine = NULL;
+    HMACHINE hMachine = NULL;
     DWORD DevIdSize = 0;
     INT_PTR Ret = -1;
 
@@ -750,11 +779,16 @@
 
     DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
     DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
+    DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
+    DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
     DevAdvPropInfo->hMachine = hMachine;
     DevAdvPropInfo->lpMachineName = lpMachineName;
     DevAdvPropInfo->szDevName[0] = L'\0';
     DevAdvPropInfo->hComCtl32 = hComCtl32;
 
+    DevAdvPropInfo->IsAdmin = IsUserAdmin();
+
     psh.dwSize = sizeof(PROPSHEETHEADER);
     psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
     psh.hwndParent = hWndParent;
@@ -860,12 +894,17 @@
                      DevAdvPropInfo->DevPropSheets);
         }
 
-        if (DevAdvPropInfo->CreatedDevInfoSet)
+        if (DevAdvPropInfo->CloseDevInst)
         {
             /* close the device info set in case a new one was created */
             SetupDiDestroyDeviceInfoList(DevAdvPropInfo->DeviceInfoSet);
         }
 
+        if (DevAdvPropInfo->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+        {
+            SetupDiDestroyDeviceInfoList(DevAdvPropInfo->CurrentDeviceInfoSet);
+        }
+
         HeapFree(GetProcessHeap(),
                  0,
                  DevAdvPropInfo);

Modified: trunk/reactos/lib/devmgr/hwpage.c
--- trunk/reactos/lib/devmgr/hwpage.c	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/hwpage.c	2005-12-03 11:55:07 UTC (rev 19836)
@@ -182,6 +182,7 @@
 
         /* get the location string */
         if (GetDeviceLocationString(HwDevInfo->DevInfoData.DevInst,
+                                    0,
                                     szBuffer,
                                     sizeof(szBuffer) / sizeof(szBuffer[0])) &&
             LoadAndFormatString(hDllInstance,

Modified: trunk/reactos/lib/devmgr/misc.c
--- trunk/reactos/lib/devmgr/misc.c	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/misc.c	2005-12-03 11:55:07 UTC (rev 19836)
@@ -311,64 +311,89 @@
 
 
 BOOL
-GetDeviceLocationString(IN DEVINST dnDevInst,
+GetDeviceLocationString(IN DEVINST dnDevInst  OPTIONAL,
+                        IN DEVINST dnParentDevInst  OPTIONAL,
                         OUT LPWSTR szBuffer,
                         IN DWORD BufferSize)
 {
     DWORD RegDataType;
     ULONG DataSize;
     CONFIGRET cRet;
+    LPWSTR szFormatted;
     BOOL Ret = FALSE;
 
     DataSize = BufferSize * sizeof(WCHAR);
-    cRet = CM_Get_DevNode_Registry_Property(dnDevInst,
-                                            CM_DRP_LOCATION_INFORMATION,
-                                            &RegDataType,
-                                            szBuffer,
-                                            &DataSize,
-                                            0);
-    if (cRet != CR_SUCCESS ||
-        RegDataType != REG_SZ)
+    szBuffer[0] = L'\0';
+    if (dnParentDevInst != 0)
     {
-        szBuffer[0] = L'\0';
-        if (LoadString(hDllInstance,
-                       IDS_UNKNOWN,
-                       szBuffer,
-                       BufferSize))
+        /* query the parent node name */
+        if (CM_Get_DevNode_Registry_Property(dnParentDevInst,
+                                             CM_DRP_DEVICEDESC,
+                                             &RegDataType,
+                                             szBuffer,
+                                             &DataSize,
+                                             0) == CR_SUCCESS &&
+             RegDataType == REG_SZ &&
+             LoadAndFormatString(hDllInstance,
+                                 IDS_DEVONPARENT,
+                                 &szFormatted,
+                                 szBuffer) != 0)
         {
+            wcsncpy(szBuffer,
+                    szFormatted,
+                    BufferSize - 1);
+            szBuffer[BufferSize - 1] = L'\0';
+            LocalFree((HLOCAL)szFormatted);
             Ret = TRUE;
         }
     }
-    else
+    else if (dnDevInst != 0)
     {
-        /* FIXME - check string for NULL termination! */
-        Ret = TRUE;
-    }
+        cRet = CM_Get_DevNode_Registry_Property(dnDevInst,
+                                                CM_DRP_LOCATION_INFORMATION,
+                                                &RegDataType,
+                                                szBuffer,
+                                                &DataSize,
+                                                0);
+        if (cRet == CR_SUCCESS && RegDataType == REG_SZ)
+        {
+            /* FIXME - check string for NULL termination! */
+            Ret = TRUE;
+        }
 
-    if (szBuffer[0] >= L'0' && szBuffer[0] <= L'9')
-    {
-        /* convert the string to an integer value and create a
-           formatted string */
-        LPWSTR szFormatted;
-        ULONG ulLocation = (ULONG)wcstoul(szBuffer,
-                                          NULL,
-                                          10);
-        if (LoadAndFormatString(hDllInstance,
-                                IDS_LOCATIONSTR,
-                                &szFormatted,
-                                ulLocation,
-                                szBuffer) != 0)
+        if (Ret && szBuffer[0] >= L'0' && szBuffer[0] <= L'9')
         {
-            wcsncpy(szBuffer,
-                    szFormatted,
-                    BufferSize - 1);
-            szBuffer[BufferSize - 1] = L'\0';
-            LocalFree((HLOCAL)szFormatted);
+            /* convert the string to an integer value and create a
+               formatted string */
+            ULONG ulLocation = (ULONG)wcstoul(szBuffer,
+                                              NULL,
+                                              10);
+            if (LoadAndFormatString(hDllInstance,
+                                    IDS_LOCATIONSTR,
+                                    &szFormatted,
+                                    ulLocation,
+                                    szBuffer) != 0)
+            {
+                wcsncpy(szBuffer,
+                        szFormatted,
+                        BufferSize - 1);
+                szBuffer[BufferSize - 1] = L'\0';
+                LocalFree((HLOCAL)szFormatted);
+            }
+            else
+                Ret = FALSE;
         }
-        else
-            Ret = FALSE;
     }
 
+    if (!Ret &&
+        LoadString(hDllInstance,
+                   IDS_UNKNOWN,
+                   szBuffer,
+                   BufferSize))
+    {
+        Ret = TRUE;
+    }
+
     return Ret;
 }
 
@@ -430,7 +455,7 @@
 
 BOOL
 GetDeviceStatusString(IN DEVINST DevInst,
-                      IN HANDLE hMachine,
+                      IN HMACHINE hMachine,
                       OUT LPWSTR szBuffer,
                       IN DWORD BufferSize)
 {
@@ -514,7 +539,7 @@
 
 BOOL
 IsDeviceHidden(IN DEVINST DevInst,
-               IN HANDLE hMachine,
+               IN HMACHINE hMachine,
                OUT BOOL *IsHidden)
 {
     CONFIGRET cr;
@@ -538,7 +563,7 @@
 
 BOOL
 CanDisableDevice(IN DEVINST DevInst,
-                 IN HANDLE hMachine,
+                 IN HMACHINE hMachine,
                  OUT BOOL *CanDisable)
 {
     CONFIGRET cr;
@@ -562,7 +587,7 @@
 
 BOOL
 IsDeviceEnabled(IN DEVINST DevInst,
-                IN HANDLE hMachine,
+                IN HMACHINE hMachine,
                 OUT BOOL *IsEnabled)
 {
     CONFIGRET cr;

Modified: trunk/reactos/lib/devmgr/precomp.h
--- trunk/reactos/lib/devmgr/precomp.h	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/precomp.h	2005-12-03 11:55:07 UTC (rev 19836)
@@ -222,29 +222,30 @@
                             IN DWORD BufferSize);
 
 BOOL
-GetDeviceLocationString(IN DEVINST dnDevInst,
+GetDeviceLocationString(IN DEVINST dnDevInst  OPTIONAL,
+                        IN DEVINST dnParentDevInst  OPTIONAL,
                         OUT LPWSTR szBuffer,
                         IN DWORD BufferSize);
 
 BOOL
 GetDeviceStatusString(IN DEVINST DevInst,
-                      IN HANDLE hMachine,
+                      IN HMACHINE hMachine,
                       OUT LPWSTR szBuffer,
                       IN DWORD BufferSize);
 
 BOOL
 IsDeviceHidden(IN DEVINST DevInst,
-               IN HANDLE hMachine,
+               IN HMACHINE hMachine,
                OUT BOOL *IsHidden);
 
 BOOL
 CanDisableDevice(IN DEVINST DevInst,
-                 IN HANDLE hMachine,
+                 IN HMACHINE hMachine,
                  OUT BOOL *CanDisable);
 
 BOOL
 IsDeviceEnabled(IN DEVINST DevInst,
-                IN HANDLE hMachine,
+                IN HMACHINE hMachine,
                 OUT BOOL *IsEnabled);
 
 BOOL

Modified: trunk/reactos/lib/devmgr/resource.h
--- trunk/reactos/lib/devmgr/resource.h	2005-12-03 09:09:10 UTC (rev 19835)
+++ trunk/reactos/lib/devmgr/resource.h	2005-12-03 11:55:07 UTC (rev 19836)
@@ -37,6 +37,7 @@
 #define IDS_DISABLEDEVICE	0x109
 #define IDS_UNKNOWNDEVICE	0x10A
 #define IDS_NODRIVERLOADED	0x10B
+#define IDS_DEVONPARENT		0x10C
 
 #define IDS_DEV_NO_PROBLEM			0x200
 #define IDS_DEV_NOT_CONFIGURED			0x201