typedef HPROPSHEETPAGE (WINAPI *PCREATEPROPERTYSHEETPAGEW)(LPCPROPSHEETPAGEW);
typedef BOOL (WINAPI *PDESTROYPROPERTYSHEETPAGE)(HPROPSHEETPAGE);
-typedef enum
-{
- DEA_DISABLE = 0,
- DEA_ENABLE,
- DEA_UNKNOWN
-} DEVENABLEACTION;
-
typedef struct _DEVADVPROP_INFO
{
+ HWND hWndGeneralPage;
+ HWND hWndParent;
+ WNDPROC ParentOldWndProc;
+ HICON hDevIcon;
+
HDEVINFO DeviceInfoSet;
- PSP_DEVINFO_DATA DeviceInfoData;
+ SP_DEVINFO_DATA DeviceInfoData;
+ HDEVINFO CurrentDeviceInfoSet;
+ SP_DEVINFO_DATA CurrentDeviceInfoData;
+ DEVINST ParentDevInst;
+ HMACHINE hMachine;
+ LPCWSTR lpMachineName;
+
HINSTANCE hComCtl32;
- HANDLE hMachine;
- BOOL CanDisable;
- BOOL DeviceEnabled;
+ PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
+ PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
+
+ DWORD PropertySheetType;
+ DWORD nDevPropSheets;
+ HPROPSHEETPAGE *DevPropSheets;
+
+ BOOL FreeDevPropSheets : 1;
+ BOOL CanDisable : 1;
+ BOOL DeviceStarted : 1;
+ BOOL DeviceUsageChanged : 1;
+ BOOL CloseDevInst : 1;
+ BOOL IsAdmin : 1;
+ BOOL DoDefaultDevAction : 1;
+ BOOL PageInitialized : 1;
+ BOOL ShowRemotePages : 1;
+ BOOL HasDriverPage : 1;
+ BOOL HasResourcePage : 1;
+ BOOL HasPowerPage : 1;
+
WCHAR szDevName[255];
WCHAR szTemp[255];
WCHAR szDeviceID[1];
} DEVADVPROP_INFO, *PDEVADVPROP_INFO;
+typedef struct _ENUMDRIVERFILES_CONTEXT
+{
+ HWND hDriversListView;
+ UINT nCount;
+} ENUMDRIVERFILES_CONTEXT, *PENUMDRIVERFILES_CONTEXT;
+
+#define PM_INITIALIZE (WM_APP + 0x101)
+
+
+static UINT WINAPI
+EnumDeviceDriverFilesCallback(IN PVOID Context,
+ IN UINT Notification,
+ IN UINT_PTR Param1,
+ IN UINT_PTR Param2)
+{
+ LVITEM li;
+ PENUMDRIVERFILES_CONTEXT EnumDriverFilesContext = (PENUMDRIVERFILES_CONTEXT)Context;
+
+ li.mask = LVIF_TEXT | LVIF_STATE;
+ li.iItem = EnumDriverFilesContext->nCount++;
+ li.iSubItem = 0;
+ li.state = (li.iItem == 0 ? LVIS_SELECTED : 0);
+ li.stateMask = LVIS_SELECTED;
+ li.pszText = (LPWSTR)Param1;
+ ListView_InsertItem(EnumDriverFilesContext->hDriversListView,
+ &li);
+ return NO_ERROR;
+}
+
+
+static VOID
+UpdateDriverDetailsDlg(IN HWND hwndDlg,
+ IN HWND hDriversListView,
+ IN PDEVADVPROP_INFO dap)
+{
+ HDEVINFO DeviceInfoSet;
+ PSP_DEVINFO_DATA DeviceInfoData;
+ SP_DRVINFO_DATA DriverInfoData;
+ ENUMDRIVERFILES_CONTEXT EnumDriverFilesContext;
+
+ if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+ {
+ DeviceInfoSet = dap->CurrentDeviceInfoSet;
+ DeviceInfoData = &dap->CurrentDeviceInfoData;
+ }
+ else
+ {
+ DeviceInfoSet = dap->DeviceInfoSet;
+ DeviceInfoData = &dap->DeviceInfoData;
+ }
+
+ /* set the device image */
+ SendDlgItemMessage(hwndDlg,
+ IDC_DEVICON,
+ STM_SETICON,
+ (WPARAM)dap->hDevIcon,
+ 0);
+
+ /* set the device name edit control text */
+ SetDlgItemText(hwndDlg,
+ IDC_DEVNAME,
+ dap->szDevName);
+
+ /* fill the driver files list view */
+ EnumDriverFilesContext.hDriversListView = hDriversListView;
+ EnumDriverFilesContext.nCount = 0;
+
+ ListView_DeleteAllItems(EnumDriverFilesContext.hDriversListView);
+ DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+ if (FindCurrentDriver(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData) &&
+ SetupDiSetSelectedDriver(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData))
+ {
+ HSPFILEQ queueHandle;
+
+ queueHandle = SetupOpenFileQueue();
+ if (queueHandle != (HSPFILEQ)INVALID_HANDLE_VALUE)
+ {
+ SP_DEVINSTALL_PARAMS DeviceInstallParams = {0};
+ DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+ if (SetupDiGetDeviceInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ &DeviceInstallParams))
+ {
+ DeviceInstallParams.FileQueue = queueHandle;
+ DeviceInstallParams.Flags |= DI_NOVCP;
+
+ if (SetupDiSetDeviceInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ &DeviceInstallParams) &&
+ SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES,
+ DeviceInfoSet,
+ DeviceInfoData))
+ {
+ DWORD scanResult;
+ RECT rcClient;
+ LVCOLUMN lvc;
+
+ /* enumerate the driver files */
+ SetupScanFileQueue(queueHandle,
+ SPQ_SCAN_USE_CALLBACK,
+ NULL,
+ EnumDeviceDriverFilesCallback,
+ &EnumDriverFilesContext,
+ &scanResult);
+
+ /* update the list view column width */
+ GetClientRect(hDriversListView,
+ &rcClient);
+ lvc.mask = LVCF_WIDTH;
+ lvc.cx = rcClient.right;
+ ListView_SetColumn(hDriversListView,
+ 0,
+ &lvc);
+ }
+ }
+
+ SetupCloseFileQueue(queueHandle);
+ }
+ }
+}
+
+
+static INT_PTR
+CALLBACK
+DriverDetailsDlgProc(IN HWND hwndDlg,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PDEVADVPROP_INFO dap;
+ INT_PTR Ret = FALSE;
+
+ dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
+ DWL_USER);
+
+ if (dap != NULL || uMsg == WM_INITDIALOG)
+ {
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ {
+ EndDialog(hwndDlg,
+ IDOK);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ EndDialog(hwndDlg,
+ IDCANCEL);
+ break;
+ }
+
+ case WM_INITDIALOG:
+ {
+ LV_COLUMN lvc;
+ HWND hDriversListView;
+
+ dap = (PDEVADVPROP_INFO)lParam;
+ if (dap != NULL)
+ {
+ SetWindowLongPtr(hwndDlg,
+ DWL_USER,
+ (DWORD_PTR)dap);
+
+ hDriversListView = GetDlgItem(hwndDlg,
+ IDC_DRIVERFILES);
+
+ /* add a column to the list view control */
+ lvc.mask = LVCF_FMT | LVCF_WIDTH;
+ lvc.fmt = LVCFMT_LEFT;
+ lvc.cx = 0;
+ ListView_InsertColumn(hDriversListView,
+ 0,
+ &lvc);
+
+ UpdateDriverDetailsDlg(hwndDlg,
+ hDriversListView,
+ dap);
+ }
+
+ Ret = TRUE;
+ break;
+ }
+ }
+ }
+
+ return Ret;
+}
+
+
+static VOID
+UpdateDriverDlg(IN HWND hwndDlg,
+ IN PDEVADVPROP_INFO dap)
+{
+ HDEVINFO DeviceInfoSet;
+ PSP_DEVINFO_DATA DeviceInfoData;
+
+ if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+ {
+ DeviceInfoSet = dap->CurrentDeviceInfoSet;
+ DeviceInfoData = &dap->CurrentDeviceInfoData;
+ }
+ else
+ {
+ DeviceInfoSet = dap->DeviceInfoSet;
+ DeviceInfoData = &dap->DeviceInfoData;
+ }
+
+ /* set the device image */
+ SendDlgItemMessage(hwndDlg,
+ IDC_DEVICON,
+ STM_SETICON,
+ (WPARAM)dap->hDevIcon,
+ 0);
+
+ /* set the device name edit control text */
+ SetDlgItemText(hwndDlg,
+ IDC_DEVNAME,
+ dap->szDevName);
+
+ /* query the driver provider */
+ if (GetDriverProviderString(DeviceInfoSet,
+ DeviceInfoData,
+ dap->szTemp,
+ sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
+ {
+ SetDlgItemText(hwndDlg,
+ IDC_DRVPROVIDER,
+ dap->szTemp);
+ }
+
+ /* query the driver date */
+ if (GetDriverDateString(DeviceInfoSet,
+ DeviceInfoData,
+ dap->szTemp,
+ sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
+ {
+ SetDlgItemText(hwndDlg,
+ IDC_DRVDATE,
+ dap->szTemp);
+ }
+
+ /* query the driver version */
+ if (GetDriverVersionString(DeviceInfoSet,
+ DeviceInfoData,
+ dap->szTemp,
+ sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
+ {
+ SetDlgItemText(hwndDlg,
+ IDC_DRVVERSION,
+ dap->szTemp);
+ }
+}
+
+
+static INT_PTR
+CALLBACK
+AdvProcDriverDlgProc(IN HWND hwndDlg,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PDEVADVPROP_INFO dap;
+ INT_PTR Ret = FALSE;
+
+ dap = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg,
+ DWL_USER);
+
+ if (dap != NULL || uMsg == WM_INITDIALOG)
+ {
+ switch (uMsg)
+ {
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_DRIVERDETAILS:
+ {
+ DialogBoxParam(hDllInstance,
+ MAKEINTRESOURCE(IDD_DRIVERDETAILS),
+ hwndDlg,
+ DriverDetailsDlgProc,
+ (ULONG_PTR)dap);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ NMHDR *hdr = (NMHDR*)lParam;
+ switch (hdr->code)
+ {
+ case PSN_APPLY:
+ break;
+ }
+ break;
+ }
+
+ case WM_INITDIALOG:
+ {
+ dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
+ if (dap != NULL)
+ {
+ SetWindowLongPtr(hwndDlg,
+ DWL_USER,
+ (DWORD_PTR)dap);
+
+ UpdateDriverDlg(hwndDlg,
+ dap);
+ }
+ Ret = TRUE;
+ break;
+ }
+ }
+ }
+
+ return Ret;
+}
+
+
static VOID
InitDevUsageActions(IN HWND hwndDlg,
IN HWND hComboBox,
{
INT Index;
UINT i;
- struct
+ UINT Actions[] =
{
- UINT szId;
- DEVENABLEACTION Action;
- } Actions[] =
- {
- {IDS_ENABLEDEVICE, DEA_ENABLE},
- {IDS_DISABLEDEVICE, DEA_DISABLE},
+ IDS_ENABLEDEVICE,
+ IDS_DISABLEDEVICE,
};
for (i = 0;
{
/* fill in the device usage combo box */
if (LoadString(hDllInstance,
- Actions[i].szId,
+ Actions[i],
dap->szTemp,
sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
{
SendMessage(hComboBox,
CB_SETITEMDATA,
(WPARAM)Index,
- (LPARAM)Actions[i].Action);
+ (LPARAM)Actions[i]);
- switch (Actions[i].Action)
+ switch (Actions[i])
{
- case DEA_ENABLE:
- if (dap->DeviceEnabled)
+ case IDS_ENABLEDEVICE:
+ if (dap->DeviceStarted)
{
SendMessage(hComboBox,
CB_SETCURSEL,
}
break;
- case DEA_DISABLE:
- if (!dap->DeviceEnabled)
+ case IDS_DISABLEDEVICE:
+ if (!dap->DeviceStarted)
{
SendMessage(hComboBox,
CB_SETCURSEL,
}
-static DEVENABLEACTION
+static UINT
GetSelectedUsageAction(IN HWND hComboBox)
{
INT Index;
- DEVENABLEACTION Ret = DEA_UNKNOWN;
+ UINT Ret = 0;
Index = (INT)SendMessage(hComboBox,
CB_GETCURSEL,
CB_GETITEMDATA,
(WPARAM)Index,
0);
- if (iRet != CB_ERR && iRet < (INT)DEA_UNKNOWN)
+ if (iRet != CB_ERR)
{
- Ret = (DEVENABLEACTION)iRet;
+ Ret = (UINT)iRet;
}
}
}
-static VOID
+static BOOL
ApplyGeneralSettings(IN HWND hwndDlg,
IN PDEVADVPROP_INFO dap)
{
- DEVENABLEACTION SelectedUsageAction;
+ BOOL Ret = FALSE;
- SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg,
- IDC_DEVUSAGE));
- if (SelectedUsageAction != DEA_UNKNOWN)
+ if (dap->DeviceUsageChanged && dap->IsAdmin && dap->CanDisable)
{
+ UINT SelectedUsageAction;
+ BOOL NeedReboot = FALSE;
+
+ SelectedUsageAction = GetSelectedUsageAction(GetDlgItem(hwndDlg,
+ IDC_DEVUSAGE));
switch (SelectedUsageAction)
{
- case DEA_ENABLE:
- if (!dap->DeviceEnabled)
+ case IDS_ENABLEDEVICE:
+ if (!dap->DeviceStarted)
{
- /* FIXME - enable device */
+ Ret = EnableDevice(dap->DeviceInfoSet,
+ &dap->DeviceInfoData,
+ TRUE,
+ 0,
+ &NeedReboot);
}
break;
- case DEA_DISABLE:
- if (dap->DeviceEnabled)
+ case IDS_DISABLEDEVICE:
+ if (dap->DeviceStarted)
{
- /* FIXME - disable device */
+ Ret = EnableDevice(dap->DeviceInfoSet,
+ &dap->DeviceInfoData,
+ FALSE,
+ 0,
+ &NeedReboot);
}
break;
break;
}
- /* disable the apply button */
- PropSheet_UnChanged(GetParent(hwndDlg),
- hwndDlg);
+ if (Ret)
+ {
+ if (NeedReboot)
+ {
+ /* make PropertySheet() return PSM_REBOOTSYSTEM */
+ PropSheet_RebootSystem(hwndDlg);
+ }
+ }
+ else
+ {
+ /* FIXME - display an error message */
+ DPRINT1("Failed to enable/disable device! LastError: %d\n",
+ GetLastError());
+ }
}
+ else
+ Ret = !dap->DeviceUsageChanged;
+
+ /* disable the apply button */
+ PropSheet_UnChanged(GetParent(hwndDlg),
+ hwndDlg);
+ dap->DeviceUsageChanged = FALSE;
+ return Ret;
}
static VOID
UpdateDevInfo(IN HWND hwndDlg,
IN PDEVADVPROP_INFO dap,
- IN BOOL ReOpenDevice)
+ IN BOOL ReOpen)
{
- HICON hIcon;
- HWND hDevUsage;
+ HWND hDevUsage, hPropSheetDlg, hDevProbBtn;
+ CONFIGRET cr;
+ ULONG Status, ProblemNumber;
+ SP_DEVINSTALL_PARAMS_W InstallParams;
+ UINT TroubleShootStrId = IDS_TROUBLESHOOTDEV;
+ BOOL bFlag, bDevActionAvailable = TRUE;
+ BOOL bDrvInstalled = FALSE;
+ DWORD iPage;
+ HDEVINFO DeviceInfoSet = NULL;
+ PSP_DEVINFO_DATA DeviceInfoData = NULL;
+ PROPSHEETHEADER psh;
+ DWORD nDriverPages = 0;
+
+ hPropSheetDlg = GetParent(hwndDlg);
+
+ if (dap->PageInitialized)
+ {
+ /* switch to the General page */
+ PropSheet_SetCurSelByID(hPropSheetDlg,
+ IDD_DEVICEGENERAL);
- if (ReOpenDevice)
+ /* remove and destroy the existing device property sheet pages */
+ if (dap->DevPropSheets != NULL)
+ {
+ for (iPage = 0;
+ iPage != dap->nDevPropSheets;
+ iPage++)
+ {
+ if (dap->DevPropSheets[iPage] != NULL)
+ {
+ PropSheet_RemovePage(hPropSheetDlg,
+ -1,
+ dap->DevPropSheets[iPage]);
+ }
+ }
+ }
+ }
+
+ iPage = 0;
+
+ if (dap->FreeDevPropSheets)
{
- /* note, we ignore the fact that SetupDiOpenDeviceInfo could fail here,
- in case of failure we're still going to query information from it even
- though those calls are going to fail. But they return readable strings
- even in that case. */
- SetupDiOpenDeviceInfo(dap->DeviceInfoSet,
- dap->szDeviceID,
- hwndDlg,
- 0,
- dap->DeviceInfoData);
+ /* don't free the array if it's the one allocated in
+ DisplayDeviceAdvancedProperties */
+ HeapFree(GetProcessHeap(),
+ 0,
+ dap->DevPropSheets);
+
+ dap->FreeDevPropSheets = FALSE;
+ }
+
+ dap->DevPropSheets = NULL;
+ dap->nDevPropSheets = 0;
+
+ if (ReOpen)
+ {
+ /* create a new device info set and re-open the device */
+ if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+ {
+ 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->CurrentDeviceInfoData))
+ {
+ if (dap->CloseDevInst)
+ {
+ SetupDiDestroyDeviceInfoList(dap->DeviceInfoSet);
+ }
+
+ dap->CloseDevInst = TRUE;
+ dap->DeviceInfoSet = dap->CurrentDeviceInfoSet;
+ dap->DeviceInfoData = dap->CurrentDeviceInfoData;
+ dap->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
+ }
+ else
+ goto GetParentNode;
+ }
+ else
+ {
+GetParentNode:
+ /* get the parent node from the initial devinst */
+ CM_Get_Parent_Ex(&dap->ParentDevInst,
+ dap->DeviceInfoData.DevInst,
+ 0,
+ dap->hMachine);
+ }
+
+ if (dap->CurrentDeviceInfoSet != INVALID_HANDLE_VALUE)
+ {
+ DeviceInfoSet = dap->CurrentDeviceInfoSet;
+ DeviceInfoData = &dap->CurrentDeviceInfoData;
+ }
+ else
+ {
+ DeviceInfoSet = dap->DeviceInfoSet;
+ DeviceInfoData = &dap->DeviceInfoData;
+ }
+ }
+ else
+ {
+ DeviceInfoSet = dap->DeviceInfoSet;
+ DeviceInfoData = &dap->DeviceInfoData;
+ }
+
+ dap->HasDriverPage = FALSE;
+ dap->HasResourcePage = FALSE;
+ dap->HasPowerPage = FALSE;
+ if (IsDriverInstalled(DeviceInfoData->DevInst,
+ dap->hMachine,
+ &bDrvInstalled) &&
+ bDrvInstalled)
+ {
+ if (SetupDiCallClassInstaller((dap->ShowRemotePages ?
+ DIF_ADDREMOTEPROPERTYPAGE_ADVANCED :
+ DIF_ADDPROPERTYPAGE_ADVANCED),
+ DeviceInfoSet,
+ DeviceInfoData))
+ {
+ /* get install params */
+ InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
+ if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet,
+ DeviceInfoData,
+ &InstallParams))
+ {
+ /* zero the flags */
+ InstallParams.Flags = 0;
+ }
+
+ dap->HasDriverPage = !(InstallParams.Flags & DI_DRIVERPAGE_ADDED);
+ dap->HasResourcePage = !(InstallParams.Flags & DI_RESOURCEPAGE_ADDED);
+ dap->HasPowerPage = !(InstallParams.Flags & DI_FLAGSEX_POWERPAGE_ADDED);
+ }
+ }
+
+ /* get the device icon */
+ if (dap->hDevIcon != NULL)
+ {
+ DestroyIcon(dap->hDevIcon);
+ dap->hDevIcon = NULL;
+ }
+ if (!SetupDiLoadClassIcon(&DeviceInfoData->ClassGuid,
+ &dap->hDevIcon,
+ NULL))
+ {
+ dap->hDevIcon = NULL;
}
/* get the device name */
- if (GetDeviceDescriptionString(dap->DeviceInfoSet,
- dap->DeviceInfoData,
+ if (GetDeviceDescriptionString(DeviceInfoSet,
+ DeviceInfoData,
dap->szDevName,
sizeof(dap->szDevName) / sizeof(dap->szDevName[0])))
{
- PropSheet_SetTitle(GetParent(hwndDlg),
+ PropSheet_SetTitle(hPropSheetDlg,
PSH_PROPTITLE,
dap->szDevName);
}
/* set the device image */
- if (SetupDiLoadClassIcon(&dap->DeviceInfoData->ClassGuid,
- &hIcon,
- NULL))
- {
- HICON hOldIcon = (HICON)SendDlgItemMessage(hwndDlg,
- IDC_DEVICON,
- STM_SETICON,
- (WPARAM)hIcon,
- 0);
- if (hOldIcon != NULL)
- {
- DestroyIcon(hOldIcon);
- }
- }
+ SendDlgItemMessage(hwndDlg,
+ IDC_DEVICON,
+ STM_SETICON,
+ (WPARAM)dap->hDevIcon,
+ 0);
/* set the device name edit control text */
SetDlgItemText(hwndDlg,
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])))
{
}
/* 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])))
{
}
/* 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])))
{
dap->szTemp);
}
- /* set the device status edit control text */
- if (GetDeviceStatusString(dap->DeviceInfoData->DevInst,
- dap->hMachine,
- dap->szTemp,
- sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
+ /* set the device status edit control text */
+ if (GetDeviceStatusString(DeviceInfoData->DevInst,
+ dap->hMachine,
+ dap->szTemp,
+ sizeof(dap->szTemp) / sizeof(dap->szTemp[0])))
+ {
+ SetDlgItemText(hwndDlg,
+ IDC_DEVSTATUS,
+ dap->szTemp);
+ }
+
+ /* set the device troubleshoot button text and disable it if necessary */
+ hDevProbBtn = GetDlgItem(hwndDlg,
+ IDC_DEVPROBLEM);
+ cr = CM_Get_DevNode_Status_Ex(&Status,
+ &ProblemNumber,
+ DeviceInfoData->DevInst,
+ 0,
+ dap->hMachine);
+ if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM))
+ {
+ switch (ProblemNumber)
+ {
+ case CM_PROB_DEVLOADER_FAILED:
+ {
+ /* FIXME - only if it's not a root bus devloader,
+ disable the button otherwise */
+ TroubleShootStrId = IDS_UPDATEDRV;
+ break;
+ }
+
+ case CM_PROB_OUT_OF_MEMORY:
+ case CM_PROB_ENTRY_IS_WRONG_TYPE:
+ case CM_PROB_LACKED_ARBITRATOR:
+ case CM_PROB_FAILED_START:
+ case CM_PROB_LIAR:
+ case CM_PROB_UNKNOWN_RESOURCE:
+ {
+ TroubleShootStrId = IDS_UPDATEDRV;
+ break;
+ }
+
+ case CM_PROB_BOOT_CONFIG_CONFLICT:
+ case CM_PROB_NORMAL_CONFLICT:
+ case CM_PROB_REENUMERATION:
+ {
+ /* FIXME - Troubleshoot conflict */
+ break;
+ }
+
+ case CM_PROB_FAILED_FILTER:
+ case CM_PROB_REINSTALL:
+ case CM_PROB_FAILED_INSTALL:
+ {
+ TroubleShootStrId = IDS_REINSTALLDRV;
+ break;
+ }
+
+ case CM_PROB_DEVLOADER_NOT_FOUND:
+ {
+ /* FIXME - 4 cases:
+ 1) if it's a missing system devloader:
+ - disable the button (Reinstall Driver)
+ 2) if it's not a system devloader but still missing:
+ - Reinstall Driver
+ 3) if it's not a system devloader but the file can be found:
+ - Update Driver
+ 4) if it's a missing or empty software key
+ - Update Driver
+ */
+ break;
+ }
+
+ case CM_PROB_INVALID_DATA:
+ case CM_PROB_PARTIAL_LOG_CONF:
+ case CM_PROB_NO_VALID_LOG_CONF:
+ case CM_PROB_HARDWARE_DISABLED:
+ case CM_PROB_CANT_SHARE_IRQ:
+ case CM_PROB_TRANSLATION_FAILED:
+ case CM_PROB_SYSTEM_SHUTDOWN:
+ case CM_PROB_PHANTOM:
+ bDevActionAvailable = FALSE;
+ break;
+
+ case CM_PROB_NOT_VERIFIED:
+ case CM_PROB_DEVICE_NOT_THERE:
+ /* FIXME - search hardware */
+ break;
+
+ case CM_PROB_NEED_RESTART:
+ case CM_PROB_WILL_BE_REMOVED:
+ case CM_PROB_MOVED:
+ case CM_PROB_TOO_EARLY:
+ case CM_PROB_DISABLED_SERVICE:
+ TroubleShootStrId = IDS_REBOOT;
+ break;
+
+ case CM_PROB_REGISTRY:
+ /* FIXME - check registry? */
+ break;
+
+ case CM_PROB_DISABLED:
+ /* if device was disabled by the user: */
+ TroubleShootStrId = IDS_ENABLEDEV;
+ /* FIXME - otherwise disable button because the device was
+ disabled by the system*/
+ break;
+
+ case CM_PROB_DEVLOADER_NOT_READY:
+ /* FIXME - if it's a graphics adapter:
+ - if it's a a secondary adapter and the main adapter
+ couldn't be found
+ - disable button
+ - else
+ - Properties
+ - else
+ - Update driver
+ */
+ break;
+
+ case CM_PROB_FAILED_ADD:
+ TroubleShootStrId = IDS_PROPERTIES;
+ break;
+ }
+ }
+
+ if (LoadString(hDllInstance,
+ TroubleShootStrId,
+ dap->szTemp,
+ sizeof(dap->szTemp) / sizeof(dap->szTemp[0])) != 0)
{
- SetDlgItemText(hwndDlg,
- IDC_DEVSTATUS,
- dap->szTemp);
+ SetWindowText(hDevProbBtn,
+ dap->szTemp);
}
+ EnableWindow(hDevProbBtn,
+ dap->IsAdmin && bDevActionAvailable);
/* check if the device can be enabled/disabled */
hDevUsage = GetDlgItem(hwndDlg,
IDC_DEVUSAGE);
- if (!CanDisableDevice(dap->DeviceInfoData->DevInst,
- dap->hMachine,
- &dap->CanDisable))
+ dap->CanDisable = FALSE;
+ dap->DeviceStarted = FALSE;
+
+ if (CanDisableDevice(DeviceInfoData->DevInst,
+ dap->hMachine,
+ &bFlag))
{
- dap->CanDisable = FALSE;
+ dap->CanDisable = bFlag;
}
- if (!IsDeviceEnabled(dap->DeviceInfoData->DevInst,
- dap->hMachine,
- &dap->DeviceEnabled))
+ if (IsDeviceStarted(DeviceInfoData->DevInst,
+ dap->hMachine,
+ &bFlag))
{
- dap->DeviceEnabled = FALSE;
+ dap->DeviceStarted = bFlag;
}
/* 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,
dap);
}
+ /* find out how many new device property sheets to add.
+ fake a PROPSHEETHEADER structure, we don't plan to
+ call PropertySheet again!*/
+ psh.dwSize = sizeof(PROPSHEETHEADER);
+ psh.dwFlags = 0;
+ psh.nPages = 0;
+
+ /* get the number of device property sheets for the device */
+ if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
+ DeviceInfoData,
+ &psh,
+ 0,
+ &nDriverPages,
+ dap->PropertySheetType) &&
+ nDriverPages != 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ dap->nDevPropSheets += nDriverPages;
+ }
+ else
+ {
+ nDriverPages = 0;
+ }
+
+ /* include the driver page */
+ if (dap->HasDriverPage)
+ dap->nDevPropSheets++;
+
+ /* add the device property sheets */
+ if (dap->nDevPropSheets != 0)
+ {
+ dap->DevPropSheets = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ dap->nDevPropSheets * sizeof(HPROPSHEETPAGE));
+ if (dap->DevPropSheets != NULL)
+ {
+ if (nDriverPages != 0)
+ {
+ psh.phpage = dap->DevPropSheets;
+
+ /* query the device property sheet pages to add */
+ if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
+ DeviceInfoData,
+ &psh,
+ dap->nDevPropSheets,
+ NULL,
+ dap->PropertySheetType))
+ {
+ /* add the property sheets */
+ for (iPage = 0;
+ iPage != nDriverPages;
+ iPage++)
+ {
+ PropSheet_AddPage(hPropSheetDlg,
+ dap->DevPropSheets[iPage]);
+ }
+
+ dap->FreeDevPropSheets = TRUE;
+ }
+ else
+ {
+ /* cleanup, we were unable to get the device property sheets */
+ iPage = nDriverPages;
+ dap->nDevPropSheets -= nDriverPages;
+ nDriverPages = 0;
+ }
+ }
+ else
+ iPage = 0;
+
+ /* add the driver page if necessary */
+ if (dap->HasDriverPage)
+ {
+ PROPSHEETPAGE pspDriver = {0};
+ pspDriver.dwSize = sizeof(PROPSHEETPAGE);
+ pspDriver.dwFlags = PSP_DEFAULT;
+ pspDriver.hInstance = hDllInstance;
+ pspDriver.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEDRIVER);
+ pspDriver.pfnDlgProc = AdvProcDriverDlgProc;
+ pspDriver.lParam = (LPARAM)dap;
+ dap->DevPropSheets[iPage] = dap->pCreatePropertySheetPageW(&pspDriver);
+ if (dap->DevPropSheets[iPage] != NULL)
+ {
+ if (PropSheet_AddPage(hPropSheetDlg,
+ dap->DevPropSheets[iPage]))
+ {
+ iPage++;
+ }
+ else
+ {
+ dap->pDestroyPropertySheetPage(dap->DevPropSheets[iPage]);
+ dap->DevPropSheets[iPage] = NULL;
+ }
+ }
+ }
+ }
+ else
+ dap->nDevPropSheets = 0;
+ }
+
/* finally, disable the apply button */
- PropSheet_UnChanged(GetParent(hwndDlg),
+ PropSheet_UnChanged(hPropSheetDlg,
hwndDlg);
+ dap->DeviceUsageChanged = FALSE;
+}
+
+
+static LRESULT
+CALLBACK
+DlgParentSubWndProc(IN HWND hwnd,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PDEVADVPROP_INFO dap;
+
+ dap = (PDEVADVPROP_INFO)GetProp(hwnd,
+ L"DevMgrDevChangeSub");
+ if (dap != NULL)
+ {
+ if (uMsg == WM_DEVICECHANGE && !IsWindowVisible(dap->hWndGeneralPage))
+ {
+ SendMessage(dap->hWndGeneralPage,
+ WM_DEVICECHANGE,
+ wParam,
+ lParam);
+ }
+
+ /* pass the message the the old window proc */
+ return CallWindowProc(dap->ParentOldWndProc,
+ hwnd,
+ uMsg,
+ wParam,
+ lParam);
+ }
+ else
+ {
+ /* this is not a good idea if the subclassed window was an ansi
+ window, but we failed finding out the previous window proc
+ so we can't use CallWindowProc. This should rarely - if ever -
+ happen. */
+
+ return DefWindowProc(hwnd,
+ uMsg,
+ wParam,
+ lParam);
+ }
}
{
PropSheet_Changed(GetParent(hwndDlg),
hwndDlg);
+ dap->DeviceUsageChanged = TRUE;
+ }
+ break;
+ }
+
+ case IDC_DEVPROBLEM:
+ {
+ if (dap->IsAdmin)
+ {
+ /* display the device problem wizard */
+ ShowDeviceProblemWizard(hwndDlg,
+ dap->DeviceInfoSet,
+ &dap->DeviceInfoData,
+ dap->hMachine);
}
break;
}
dap = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
if (dap != NULL)
{
+ HWND hWndParent;
+
+ dap->hWndGeneralPage = hwndDlg;
+
SetWindowLongPtr(hwndDlg,
DWL_USER,
(DWORD_PTR)dap);
- UpdateDevInfo(hwndDlg,
- dap,
- FALSE);
+ /* subclass the parent window to always receive
+ WM_DEVICECHANGE messages */
+ hWndParent = GetParent(hwndDlg);
+ if (hWndParent != NULL)
+ {
+ /* subclass the parent window. This is not safe
+ if the parent window belongs to another thread! */
+ dap->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent,
+ GWLP_WNDPROC,
+ (LONG_PTR)DlgParentSubWndProc);
+
+ if (dap->ParentOldWndProc != NULL &&
+ SetProp(hWndParent,
+ L"DevMgrDevChangeSub",
+ (HANDLE)dap))
+ {
+ dap->hWndParent = hWndParent;
+ }
+ }
+
+ /* do not call UpdateDevInfo directly in here because it modifies
+ the pages of the property sheet! */
+ PostMessage(hwndDlg,
+ PM_INITIALIZE,
+ 0,
+ 0);
}
Ret = TRUE;
break;
case WM_DEVICECHANGE:
{
- /* FIXME - don't call UpdateDevInfo in all events */
+ /* FIXME - don't call UpdateDevInfo for all events */
UpdateDevInfo(hwndDlg,
dap,
TRUE);
+ Ret = TRUE;
+ break;
+ }
+
+ case PM_INITIALIZE:
+ {
+ UpdateDevInfo(hwndDlg,
+ dap,
+ FALSE);
+ dap->PageInitialized = TRUE;
break;
}
case WM_DESTROY:
{
- HICON hDevIcon;
-
- /* destroy the device icon */
- hDevIcon = (HICON)SendDlgItemMessage(hwndDlg,
- IDC_DEVICON,
- STM_GETICON,
- 0,
- 0);
- if (hDevIcon != NULL)
+ /* restore the old window proc of the subclassed parent window */
+ if (dap->hWndParent != NULL && dap->ParentOldWndProc != NULL)
{
- DestroyIcon(hDevIcon);
+ if (SetWindowLongPtr(dap->hWndParent,
+ GWLP_WNDPROC,
+ (LONG_PTR)dap->ParentOldWndProc) == (LONG_PTR)DlgParentSubWndProc)
+ {
+ RemoveProp(dap->hWndParent,
+ L"DevMgrDevChangeSub");
+ }
}
break;
}
IN HDEVINFO DeviceInfoSet,
IN PSP_DEVINFO_DATA DeviceInfoData,
IN HINSTANCE hComCtl32,
- IN LPCWSTR lpMachineName)
+ IN LPCWSTR lpMachineName,
+ IN DWORD dwFlags)
{
PROPSHEETHEADER psh = {0};
PROPSHEETPAGE pspGeneral = {0};
- DWORD nPropSheets = 0;
PPROPERTYSHEETW pPropertySheetW;
PCREATEPROPERTYSHEETPAGEW pCreatePropertySheetPageW;
PDESTROYPROPERTYSHEETPAGE pDestroyPropertySheetPage;
PDEVADVPROP_INFO DevAdvPropInfo;
- DWORD PropertySheetType;
- HANDLE hMachine = NULL;
+ HMACHINE hMachine = NULL;
DWORD DevIdSize = 0;
INT_PTR Ret = -1;
0,
&DevIdSize))
{
- DPRINT1("SetupDiGetDeviceInterfaceDetail unexpectedly returned TRUE!\n");
+ DPRINT1("SetupDiGetDeviceInstanceId unexpectedly returned TRUE!\n");
return -1;
}
DevIdSize = (DWORD)wcslen(lpDeviceID) + 1;
}
- if (lpMachineName != NULL)
+ if (lpMachineName != NULL && lpMachineName[0] != L'\0')
{
CONFIGRET cr = CM_Connect_Machine(lpMachineName,
&hMachine);
/* create the internal structure associated with the "General",
"Driver", ... pages */
DevAdvPropInfo = HeapAlloc(GetProcessHeap(),
- 0,
+ HEAP_ZERO_MEMORY,
FIELD_OFFSET(DEVADVPROP_INFO,
szDeviceID) +
(DevIdSize * sizeof(WCHAR)));
if (DevAdvPropInfo == NULL)
{
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto Cleanup;
}
goto Cleanup;
}
}
+ else
+ {
+ /* copy the device instance id supplied by the caller */
+ wcscpy(DevAdvPropInfo->szDeviceID,
+ lpDeviceID);
+ }
DevAdvPropInfo->DeviceInfoSet = DeviceInfoSet;
- DevAdvPropInfo->DeviceInfoData = DeviceInfoData;
- DevAdvPropInfo->hComCtl32 = hComCtl32;
+ DevAdvPropInfo->DeviceInfoData = *DeviceInfoData;
+ DevAdvPropInfo->CurrentDeviceInfoSet = INVALID_HANDLE_VALUE;
+ DevAdvPropInfo->CurrentDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+ DevAdvPropInfo->ShowRemotePages = (lpMachineName != NULL && lpMachineName[0] != L'\0');
DevAdvPropInfo->hMachine = hMachine;
+ DevAdvPropInfo->lpMachineName = lpMachineName;
DevAdvPropInfo->szDevName[0] = L'\0';
+ DevAdvPropInfo->hComCtl32 = hComCtl32;
+ DevAdvPropInfo->pCreatePropertySheetPageW = pCreatePropertySheetPageW;
+ DevAdvPropInfo->pDestroyPropertySheetPage = pDestroyPropertySheetPage;
+
+ DevAdvPropInfo->IsAdmin = IsUserAdmin();
+ DevAdvPropInfo->DoDefaultDevAction = ((dwFlags & DPF_DEVICE_STATUS_ACTION) != 0);
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW;
psh.hwndParent = hWndParent;
psh.pszCaption = DevAdvPropInfo->szDevName;
- PropertySheetType = lpMachineName != NULL ?
- DIGCDP_FLAG_REMOTE_ADVANCED :
- DIGCDP_FLAG_ADVANCED;
-
- /* find out how many property sheets we need */
- if (SetupDiGetClassDevPropertySheets(DeviceInfoSet,
- DeviceInfoData,
- &psh,
- 0,
- &nPropSheets,
- PropertySheetType) &&
- nPropSheets != 0)
- {
- DPRINT1("SetupDiGetClassDevPropertySheets unexpectedly returned TRUE!\n");
- goto Cleanup;
- }
-
- if (nPropSheets != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
- {
- goto Cleanup;
- }
+ DevAdvPropInfo->PropertySheetType = DevAdvPropInfo->ShowRemotePages ?
+ DIGCDP_FLAG_REMOTE_ADVANCED :
+ DIGCDP_FLAG_ADVANCED;
psh.phpage = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
- (nPropSheets + 1) * sizeof(HPROPSHEETPAGE));
+ 1 * sizeof(HPROPSHEETPAGE));
if (psh.phpage == NULL)
{
goto Cleanup;
pspGeneral.pszTemplate = (LPCWSTR)MAKEINTRESOURCE(IDD_DEVICEGENERAL);
pspGeneral.pfnDlgProc = AdvPropGeneralDlgProc;
pspGeneral.lParam = (LPARAM)DevAdvPropInfo;
- psh.phpage[0] = pCreatePropertySheetPageW(&pspGeneral);
- if (psh.phpage[0] != NULL)
+ psh.phpage[psh.nPages] = pCreatePropertySheetPageW(&pspGeneral);
+ if (psh.phpage[psh.nPages] != NULL)
{
psh.nPages++;
}
- if (nPropSheets != 0)
- {
- /* create the device property sheets */
- if (!SetupDiGetClassDevPropertySheets(DeviceInfoSet,
- DeviceInfoData,
- &psh,
- nPropSheets + psh.nPages,
- NULL,
- PropertySheetType))
- {
- goto Cleanup;
- }
- }
-
- /* FIXME - add the "Driver" property sheet if necessary */
+ DevAdvPropInfo->nDevPropSheets = psh.nPages;
if (psh.nPages != 0)
{
Cleanup:
/* in case of failure the property sheets must be destroyed */
- for (i = 0;
- i < psh.nPages;
- i++)
+ if (psh.phpage != NULL)
{
- if (psh.phpage[i] != NULL)
+ for (i = 0;
+ i < psh.nPages;
+ i++)
{
- pDestroyPropertySheetPage(psh.phpage[i]);
+ if (psh.phpage[i] != NULL)
+ {
+ pDestroyPropertySheetPage(psh.phpage[i]);
+ }
}
}
}
- HeapFree(GetProcessHeap(),
- 0,
- psh.phpage);
+ if (DevAdvPropInfo != NULL)
+ {
+ if (DevAdvPropInfo->FreeDevPropSheets)
+ {
+ /* don't free the array if it's the one allocated in
+ DisplayDeviceAdvancedProperties */
+ HeapFree(GetProcessHeap(),
+ 0,
+ DevAdvPropInfo->DevPropSheets);
+ }
+
+ 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);
+ }
+
+ if (DevAdvPropInfo->hDevIcon != NULL)
+ {
+ DestroyIcon(DevAdvPropInfo->hDevIcon);
+ }
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ DevAdvPropInfo);
+ }
- HeapFree(GetProcessHeap(),
- 0,
- DevAdvPropInfo);
+ if (psh.phpage != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ psh.phpage);
+ }
if (hMachine != NULL)
{
* lpDeviceID: Specifies the device whose properties are to be shown
*
* RETURN VALUE
- * -1: if errors occured
- *
- * REVISIONS
- *
- * NOTE
+ * Always returns -1, a call to GetLastError returns 0 if successful
*
* @implemented
*/
INT_PTR
WINAPI
-DeviceAdvancedPropertiesW(HWND hWndParent,
- LPCWSTR lpMachineName,
- LPCWSTR lpDeviceID)
+DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL,
+ IN LPCWSTR lpMachineName OPTIONAL,
+ IN LPCWSTR lpDeviceID)
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DevInfoData;
HINSTANCE hComCtl32;
INT_PTR Ret = -1;
+ if (lpDeviceID == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
/* dynamically load comctl32 */
hComCtl32 = LoadAndInitComctl32();
if (hComCtl32 != NULL)
{
- if (lpMachineName != NULL)
- {
- hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
- hWndParent,
- lpMachineName,
- NULL);
- }
- else
- {
- hDevInfo = SetupDiCreateDeviceInfoList(NULL,
- hWndParent);
- }
-
+ hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
+ hWndParent,
+ lpMachineName,
+ NULL);
if (hDevInfo != INVALID_HANDLE_VALUE)
{
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
hDevInfo,
&DevInfoData,
hComCtl32,
- lpMachineName);
+ lpMachineName,
+ 0);
}
SetupDiDestroyDeviceInfoList(hDevInfo);
* lpDeviceID: Specifies the device whose properties are to be shown
*
* RETURN VALUE
- * -1: if errors occured
- *
- * REVISIONS
- *
- * NOTE
+ * Always returns -1, a call to GetLastError returns 0 if successful
*
* @implemented
*/
INT_PTR
WINAPI
-DeviceAdvancedPropertiesA(HWND hWndParent,
- LPCSTR lpMachineName,
- LPCSTR lpDeviceID)
+DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL,
+ IN LPCSTR lpMachineName OPTIONAL,
+ IN LPCSTR lpDeviceID)
{
LPWSTR lpMachineNameW = NULL;
LPWSTR lpDeviceIDW = NULL;
return Ret;
}
+
+
+/***************************************************************************
+ * NAME EXPORTED
+ * DevicePropertiesExA
+ *
+ * DESCRIPTION
+ * Invokes the extended device properties dialog
+ *
+ * ARGUMENTS
+ * hWndParent: Handle to the parent window
+ * lpMachineName: Machine Name, NULL is the local machine
+ * lpDeviceID: Specifies the device whose properties are to be shown, optional if
+ * bShowDevMgr is nonzero
+ * dwFlags: This parameter can be a combination of the following flags:
+ * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
+ * the default device status action button
+ * to be clicked (Troubleshoot, Enable
+ * Device, etc)
+ * bShowDevMgr: If non-zero it displays the device manager instead of
+ * the advanced device property dialog
+ *
+ * RETURN VALUE
+ * 1: if bShowDevMgr is non-zero and no error occured
+ * -1: a call to GetLastError returns 0 if successful
+ *
+ * @implemented
+ */
+INT_PTR
+WINAPI
+DevicePropertiesExA(IN HWND hWndParent OPTIONAL,
+ IN LPCSTR lpMachineName OPTIONAL,
+ IN LPCSTR lpDeviceID OPTIONAL,
+ IN DWORD dwFlags OPTIONAL,
+ IN BOOL bShowDevMgr)
+{
+ LPWSTR lpMachineNameW = NULL;
+ LPWSTR lpDeviceIDW = NULL;
+ INT_PTR Ret = -1;
+
+ if (lpMachineName != NULL)
+ {
+ if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
+ CP_ACP)))
+ {
+ goto Cleanup;
+ }
+ }
+ if (lpDeviceID != NULL)
+ {
+ if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID,
+ CP_ACP)))
+ {
+ goto Cleanup;
+ }
+ }
+
+ Ret = DevicePropertiesExW(hWndParent,
+ lpMachineNameW,
+ lpDeviceIDW,
+ dwFlags,
+ bShowDevMgr);
+
+Cleanup:
+ if (lpMachineNameW != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpMachineNameW);
+ }
+ if (lpDeviceIDW != NULL)
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ lpDeviceIDW);
+ }
+
+ return Ret;
+}
+
+
+/***************************************************************************
+ * NAME EXPORTED
+ * DevicePropertiesExW
+ *
+ * DESCRIPTION
+ * Invokes the extended device properties dialog
+ *
+ * ARGUMENTS
+ * hWndParent: Handle to the parent window
+ * lpMachineName: Machine Name, NULL is the local machine
+ * lpDeviceID: Specifies the device whose properties are to be shown, optional if
+ * bShowDevMgr is nonzero
+ * dwFlags: This parameter can be a combination of the following flags:
+ * * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
+ * the default device status action button
+ * to be clicked (Troubleshoot, Enable
+ * Device, etc)
+ * bShowDevMgr: If non-zero it displays the device manager instead of
+ * the advanced device property dialog
+ *
+ * RETURN VALUE
+ * 1: if bShowDevMgr is non-zero and no error occured
+ * -1: a call to GetLastError returns 0 if successful
+ *
+ * @unimplemented
+ */
+INT_PTR
+WINAPI
+DevicePropertiesExW(IN HWND hWndParent OPTIONAL,
+ IN LPCWSTR lpMachineName OPTIONAL,
+ IN LPCWSTR lpDeviceID OPTIONAL,
+ IN DWORD dwFlags OPTIONAL,
+ IN BOOL bShowDevMgr)
+{
+ INT_PTR Ret = -1;
+
+ if (dwFlags & ~(DPF_UNKNOWN | DPF_DEVICE_STATUS_ACTION))
+ {
+ DPRINT1("DevPropertiesExW: Invalid flags: 0x%x\n",
+ dwFlags & ~(DPF_UNKNOWN | DPF_DEVICE_STATUS_ACTION));
+ SetLastError(ERROR_INVALID_FLAGS);
+ return -1;
+ }
+
+ if (bShowDevMgr)
+ {
+ DPRINT("DevPropertiesExW doesn't support bShowDevMgr!\n");
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ }
+ else
+ {
+ HDEVINFO hDevInfo;
+ SP_DEVINFO_DATA DevInfoData;
+ HINSTANCE hComCtl32;
+
+ if (lpDeviceID == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
+ /* dynamically load comctl32 */
+ hComCtl32 = LoadAndInitComctl32();
+ if (hComCtl32 != NULL)
+ {
+ hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
+ hWndParent,
+ lpMachineName,
+ NULL);
+ if (hDevInfo != INVALID_HANDLE_VALUE)
+ {
+ DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+ if (SetupDiOpenDeviceInfo(hDevInfo,
+ lpDeviceID,
+ hWndParent,
+ 0,
+ &DevInfoData))
+ {
+ Ret = DisplayDeviceAdvancedProperties(hWndParent,
+ lpDeviceID,
+ hDevInfo,
+ &DevInfoData,
+ hComCtl32,
+ lpMachineName,
+ dwFlags);
+ }
+
+ SetupDiDestroyDeviceInfoList(hDevInfo);
+ }
+
+ FreeLibrary(hComCtl32);
+ }
+ }
+
+ return Ret;
+}