BOOL GetDevStatus(HDEVINFO h, SP_DEVINFO_DATA *dev_info_data, PULONG status, PULONG problem) { SP_DEVINFO_LIST_DETAIL_DATA detail; memset(&detail, 0, sizeof(detail)); detail.cbSize = sizeof(detail); SetupDiGetDeviceInfoListDetail(h, &detail); if (CM_Get_DevNode_Status_Ex(status, problem, dev_info_data->DevInst, 0, detail.RemoteMachineHandle) != CR_SUCCESS) { printf("SetupDiGetDeviceInfoListDetail: %x\n", GetLastError()); return FALSE; } return TRUE; }
static BOOL CanDisableDevice( IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *CanDisable) { CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE; cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *CanDisable = ((Status & DN_DISABLEABLE) != 0); Ret = TRUE; } return Ret; }
static BOOL IsDeviceStarted( IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *IsEnabled) { CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE; cr = CM_Get_DevNode_Status_Ex( &Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *IsEnabled = ((Status & DN_STARTED) != 0); Ret = TRUE; } return Ret; }
BOOL DumpDeviceResources(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo) /*++ Routine Description: Dump Resources to stdout Arguments: Devs )_ uniquely identify device DevInfo ) Return Value: none --*/ { SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail; ULONG status = 0; ULONG problem = 0; LOG_CONF config = 0; BOOL haveConfig = FALSE; // // see what state the device is in // devInfoListDetail.cbSize = sizeof(devInfoListDetail); if((!SetupDiGetDeviceInfoListDetail(Devs,&devInfoListDetail)) || (CM_Get_DevNode_Status_Ex(&status,&problem,DevInfo->DevInst,0,devInfoListDetail.RemoteMachineHandle)!=CR_SUCCESS)) { return FALSE; } // // see if the device is running and what resources it might be using // if(!(status & DN_HAS_PROBLEM)) { // // If this device is running, does this devinst have a ALLOC log config? // if (CM_Get_First_Log_Conf_Ex(&config, DevInfo->DevInst, ALLOC_LOG_CONF, devInfoListDetail.RemoteMachineHandle) == CR_SUCCESS) { haveConfig = TRUE; } } if(!haveConfig) { // // If no config so far, does it have a FORCED log config? // (note that technically these resources might be used by another device // but is useful info to show) // if (CM_Get_First_Log_Conf_Ex(&config, DevInfo->DevInst, FORCED_LOG_CONF, devInfoListDetail.RemoteMachineHandle) == CR_SUCCESS) { haveConfig = TRUE; } } if(!haveConfig) { // // if there's a hardware-disabled problem, boot-config isn't valid // otherwise use this if we don't have anything else // if(!(status & DN_HAS_PROBLEM) || (problem != CM_PROB_HARDWARE_DISABLED)) { // // Does it have a BOOT log config? // if (CM_Get_First_Log_Conf_Ex(&config, DevInfo->DevInst, BOOT_LOG_CONF, devInfoListDetail.RemoteMachineHandle) == CR_SUCCESS) { haveConfig = TRUE; } } } if(!haveConfig) { // // if we don't have any configuration, display an apropriate message // Padding(1); FormatToStream(stdout,(status & DN_STARTED) ? MSG_DUMP_NO_RESOURCES : MSG_DUMP_NO_RESERVED_RESOURCES ); return TRUE; } Padding(1); FormatToStream(stdout,(status & DN_STARTED) ? MSG_DUMP_RESOURCES : MSG_DUMP_RESERVED_RESOURCES ); // // dump resources // DumpDeviceResourcesOfType(DevInfo->DevInst,devInfoListDetail.RemoteMachineHandle,config,ResType_All); // // release handle // CM_Free_Log_Conf_Handle(config); return TRUE; }
BOOL DumpDeviceStatus(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo) /*++ Routine Description: Write device status to stdout Arguments: Devs )_ uniquely identify device DevInfo ) Return Value: none --*/ { SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail; ULONG status = 0; ULONG problem = 0; BOOL hasInfo = FALSE; BOOL isPhantom = FALSE; CONFIGRET cr = CR_SUCCESS; devInfoListDetail.cbSize = sizeof(devInfoListDetail); if((!SetupDiGetDeviceInfoListDetail(Devs,&devInfoListDetail)) || ((cr = CM_Get_DevNode_Status_Ex(&status,&problem,DevInfo->DevInst,0,devInfoListDetail.RemoteMachineHandle))!=CR_SUCCESS)) { if ((cr == CR_NO_SUCH_DEVINST) || (cr == CR_NO_SUCH_VALUE)) { isPhantom = TRUE; } else { Padding(1); FormatToStream(stdout,MSG_DUMP_STATUS_ERROR); return FALSE; } } // // handle off the status/problem codes // if (isPhantom) { Padding(1); FormatToStream(stdout,MSG_DUMP_PHANTOM); return TRUE; } if((status & DN_HAS_PROBLEM) && problem == CM_PROB_DISABLED) { hasInfo = TRUE; Padding(1); FormatToStream(stdout,MSG_DUMP_DISABLED); return TRUE; } if(status & DN_HAS_PROBLEM) { hasInfo = TRUE; Padding(1); FormatToStream(stdout,MSG_DUMP_PROBLEM,problem); } if(status & DN_PRIVATE_PROBLEM) { hasInfo = TRUE; Padding(1); FormatToStream(stdout,MSG_DUMP_PRIVATE_PROBLEM); } if(status & DN_STARTED) { Padding(1); FormatToStream(stdout,MSG_DUMP_STARTED); } else if (!hasInfo) { Padding(1); FormatToStream(stdout,MSG_DUMP_NOTSTARTED); } return TRUE; }
static VOID EnumDevices( HWND hTreeView, PDEVCLASS_ENTRY pClassArray, ULONG ulClassCount, BOOL bShowHidden) { HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; ULONG Status, Problem; DWORD DevIdSize; TCHAR DeviceName[MAX_DEV_LEN]; DWORD DevIndex; LPTSTR InstanceId; PDEVCLASS_ENTRY pClass; UINT OverlayImage; CONFIGRET cr; /* Get device info for all devices of a particular class */ hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (hDevInfo == INVALID_HANDLE_VALUE) return; for (DevIndex = 0; ; DevIndex++) { ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA)); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); InstanceId = NULL; DeviceName[0] = _T('\0'); OverlayImage = 0; if (!SetupDiEnumDeviceInfo(hDevInfo, DevIndex, &DeviceInfoData)) break; if (bShowHidden == FALSE && (IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_DEVCLASS_LEGACYDRIVER) || IsEqualGUID(&DeviceInfoData.ClassGuid, &GUID_DEVCLASS_VOLUME))) continue; pClass = GetClassFromClassGuid(pClassArray, ulClassCount, &DeviceInfoData.ClassGuid); /* get the device ID */ if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, NULL, 0, &DevIdSize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { InstanceId = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, DevIdSize * sizeof(TCHAR)); if (InstanceId != NULL) { if (!SetupDiGetDeviceInstanceId(hDevInfo, &DeviceInfoData, InstanceId, DevIdSize, NULL)) { HeapFree(GetProcessHeap(), 0, InstanceId); InstanceId = NULL; } } } } /* Skip the root device */ if (InstanceId != NULL && _tcscmp(InstanceId, _T("HTREE\\ROOT\\0")) == 0) { HeapFree(GetProcessHeap(), 0, InstanceId); InstanceId = NULL; continue; } /* Get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_FRIENDLYNAME, 0, (BYTE*)DeviceName, MAX_DEV_LEN, NULL)) { /* If the friendly name fails, try the description instead */ SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, 0, (BYTE*)DeviceName, MAX_DEV_LEN, NULL); } cr = CM_Get_DevNode_Status_Ex(&Status, &Problem, DeviceInfoData.DevInst, 0, NULL); if ((cr == CR_SUCCESS) && (Status & DN_HAS_PROBLEM)) { if (Problem == CM_PROB_DISABLED || Problem == CM_PROB_HARDWARE_DISABLED) OverlayImage = 2; else OverlayImage = 1; } InsertIntoTreeView(hTreeView, pClass->hItem, DeviceName, InstanceId, pClass->ClassImage, OverlayImage); if (OverlayImage != 0) { /* Expand the class if the device has a problem */ (void)TreeView_Expand(hTreeView, pClass->hItem, TVE_EXPAND); } pClass->bUsed = TRUE; } if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); }
static VOID InitProbeListPage(HWND hwndDlg) { LV_COLUMN Column; LV_ITEM Item; WCHAR szBuffer[MAX_STR_SIZE], szGuid[MAX_STR_SIZE], szTrimGuid[MAX_STR_SIZE], szStatusText[MAX_STR_SIZE]; HWND hList = GetDlgItem(hwndDlg, IDC_PROBELIST); PWSTR pstrStatusText; HDEVINFO hDevInfo; SP_DEVINFO_DATA DevInfoData; ULONG ulStatus, ulProblemNumber; GUID ClassGuid; RECT Rect; DWORD Index; if (!hList) return; ZeroMemory(&Column, sizeof(LV_COLUMN)); GetClientRect(hList, &Rect); Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; Column.fmt = LVCFMT_LEFT; Column.iSubItem = 0; Column.pszText = NULL; Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); (VOID) ListView_InsertColumn(hList, 0, &Column); ZeroMemory(&Item, sizeof(LV_ITEM)); LoadString(hApplet, IDS_ADDNEWDEVICE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)); Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.pszText = (LPWSTR) szBuffer; Item.iItem = (INT) ListView_GetItemCount(hList); Item.iImage = -1; (VOID) ListView_InsertItem(hList, &Item); hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0); if (hDevInfo == INVALID_HANDLE_VALUE) return; /* Get the device image List */ ImageListData.cbSize = sizeof(ImageListData); SetupDiGetClassImageList(&ImageListData); DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (Index = 0; TRUE; Index++) { szBuffer[0] = L'\0'; if (!SetupDiEnumDeviceInfo(hDevInfo, Index, &DevInfoData)) break; if (CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblemNumber, DevInfoData.DevInst, 0, NULL) == CR_SUCCESS) { if (ulStatus & DN_NO_SHOW_IN_DM) continue; } /* Get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_FRIENDLYNAME, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL)) { /* If the friendly name fails, try the description instead */ SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_DEVICEDESC, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL); } SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_CLASSGUID, 0, (BYTE*)szGuid, MAX_STR_SIZE, NULL); TrimGuidString(szGuid, szTrimGuid); UuidFromStringW(szTrimGuid, &ClassGuid); SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, &Item.iImage); DeviceProblemTextW(NULL, DevInfoData.DevInst, ulProblemNumber, szStatusText, sizeof(szStatusText) / sizeof(WCHAR)); pstrStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, sizeof(szStatusText)); lstrcpy(pstrStatusText, szStatusText); if (szBuffer[0] != L'\0') { /* Set device name */ Item.pszText = (LPWSTR) szBuffer; Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.lParam = (LPARAM) pstrStatusText; Item.iItem = (INT) ListView_GetItemCount(hList); (VOID) ListView_InsertItem(hList, &Item); } DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); } (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); SetupDiDestroyDeviceInfoList(hDevInfo); }
BOOL ShowDeviceProblemWizard(IN HWND hWndParent OPTIONAL, IN HDEVINFO hDevInfo, IN PSP_DEVINFO_DATA DevInfoData, IN HMACHINE hMachine OPTIONAL) { CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE; cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInfoData->DevInst, 0, 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 */ /* FIXME - display the update driver wizard */ 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: { /* FIXME - display the update driver wizard */ break; } case CM_PROB_BOOT_CONFIG_CONFLICT: case CM_PROB_NORMAL_CONFLICT: case CM_PROB_REENUMERATION: { /* FIXME - display the conflict wizard */ break; } case CM_PROB_FAILED_FILTER: case CM_PROB_REINSTALL: case CM_PROB_FAILED_INSTALL: { /* FIXME - display the driver (re)installation wizard */ break; } case CM_PROB_DEVLOADER_NOT_FOUND: { /* FIXME - 4 cases: 1) if it's a missing system devloader: - fail 2) if it's not a system devloader but still missing: - display the driver reinstallation wizard 3) if it's not a system devloader but the file can be found: - display the update driver wizard 4) if it's a missing or empty software key - display the update driver wizard */ 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: /* FIXME - do nothing */ break; case CM_PROB_NOT_VERIFIED: case CM_PROB_DEVICE_NOT_THERE: /* FIXME - display search hardware wizard */ 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: /* FIXME - reboot computer */ break; case CM_PROB_REGISTRY: /* FIXME - check registry */ break; case CM_PROB_DISABLED: { /* FIXME - if device was disabled by user display the "Enable Device" wizard, otherwise Troubleshoot 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 - do nothing or default action - else - display the Properties - else - Update driver */ break; } case CM_PROB_FAILED_ADD: { /* FIXME - display the properties of the sub-device */ break; } case CM_PROB_NO_SOFTCONFIG: case CM_PROB_IRQ_TRANSLATION_FAILED: case CM_PROB_FAILED_DRIVER_ENTRY: case CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD: case CM_PROB_DRIVER_FAILED_LOAD: case CM_PROB_DRIVER_SERVICE_KEY_INVALID: case CM_PROB_LEGACY_SERVICE_NO_DEVICES: case CM_PROB_DUPLICATE_DEVICE: case CM_PROB_FAILED_POST_START: case CM_PROB_HALTED: case CM_PROB_HELD_FOR_EJECT: case CM_PROB_DRIVER_BLOCKED: case CM_PROB_REGISTRY_TOO_LARGE: default: { /* FIXME - troubleshoot the device */ break; } } } return Ret; }