#include "stdafx.h" #include "devtree.h" #include #include #include #include void CDevice::GetProperty( HMACHINE hMachine, DEVNODE dn, ULONG Property, int IdType ) { CString strType; TCHAR Buffer[REGSTR_VAL_MAX_HCID_LEN]; ULONG Type; ULONG Size = sizeof(Buffer); strType.LoadString(IdType); // preload default string strType.LoadString(IDS_UNKNOWN); lstrcpy(Buffer, (LPCTSTR)strType); strType.LoadString(IdType); if (CR_SUCCESS == CM_Get_DevNode_Registry_Property_Ex(dn, Property, &Type, Buffer, &Size, 0, hMachine)) { if (REG_DWORD == Type || REG_MULTI_SZ == Type || REG_SZ == Type) { if (REG_DWORD == Type) { DWORD Data = *((DWORD*)Buffer); wsprintf(Buffer, _T("%08x"), *((DWORD*)Buffer) ); } else if (REG_MULTI_SZ == Type) { LPTSTR p = Buffer; while (_T('\0') != *p) { p += lstrlen(p); if (_T('\0') != *p) *p++ = _T(','); } } } } CAttribute* pAttr = new CAttribute(strType, Buffer); m_listAttributes.AddTail(pAttr); } // prepare device's attributes BOOL CDevice::Create( HMACHINE hMachine, DEVNODE DevNode ) { CString strType; CString strValue; LPTSTR Buffer; int BufferSize = MAX_PATH + MAX_DEVICE_ID_LEN; ULONG BufferLen = BufferSize * sizeof(TCHAR); m_pSibling = NULL; m_pParent = NULL; m_pChild = NULL; m_ImageIndex = 0; Buffer = strValue.GetBuffer(BufferSize); if (CR_SUCCESS == CM_Get_DevNode_Registry_Property_Ex(DevNode, CM_DRP_FRIENDLYNAME, NULL, Buffer, &BufferLen, 0, hMachine)) { m_strDisplayName = Buffer; } else { BufferLen = BufferSize * sizeof(TCHAR); if (CR_SUCCESS == CM_Get_DevNode_Registry_Property_Ex(DevNode, CM_DRP_DEVICEDESC, NULL, Buffer, &BufferLen, 0, hMachine)) { m_strDisplayName = Buffer; } else { m_strDisplayName.LoadString(IDS_UNKNOWN); } } CAttribute* pAttr; // pepare device' attributes // do standard ones first; if (CR_SUCCESS == CM_Get_Device_ID_Ex(DevNode, Buffer, BufferSize, 0, hMachine)) { strType.LoadString(IDS_DEVICEID); pAttr = new CAttribute(strType, Buffer); m_listAttributes.AddTail(pAttr); } ULONG Status, Problem; if (CR_SUCCESS == CM_Get_DevNode_Status_Ex(&Status, &Problem, DevNode, 0, hMachine)) { strValue.Format(_T("%08x"), Status); strType.LoadString(IDS_STATUS); pAttr = new CAttribute(strType, strValue); m_listAttributes.AddTail(pAttr); strType.LoadString(IDS_PROBLEM); strValue.Format(_T("%08x"), Problem); pAttr = new CAttribute(strType, strValue); m_listAttributes.AddTail(pAttr); } GetProperty(hMachine, DevNode, CM_DRP_SERVICE, IDS_SERVICE); GetProperty(hMachine, DevNode, CM_DRP_CAPABILITIES, IDS_CAPABILITIES); GetProperty(hMachine, DevNode, CM_DRP_CONFIGFLAGS, IDS_CONFIGFLAGS); GetProperty(hMachine, DevNode, CM_DRP_MFG, IDS_MFG); GetProperty(hMachine, DevNode, CM_DRP_CLASS, IDS_CLASS); GetProperty(hMachine, DevNode, CM_DRP_HARDWAREID, IDS_HARDWAREID); GetProperty(hMachine, DevNode, CM_DRP_COMPATIBLEIDS, IDS_COMPATIBLEID); GetProperty(hMachine, DevNode, CM_DRP_CLASSGUID, IDS_CLASSGUID); GetProperty(hMachine, DevNode, CM_DRP_LOCATION_INFORMATION, IDS_LOCATION); GetProperty(hMachine, DevNode, CM_DRP_BUSNUMBER, IDS_BUSNUMBER); GetProperty(hMachine, DevNode, CM_DRP_ENUMERATOR_NAME, IDS_ENUMERATOR_NAME); GetProperty(hMachine, DevNode, CM_DRP_DEVICEDESC, IDS_DEVICEDESC); GetProperty(hMachine, DevNode, CM_DRP_FRIENDLYNAME, IDS_FRIENDLYNAME); GetProperty(hMachine, DevNode, CM_DRP_DRIVER, IDS_DRIVER); GetProperty(hMachine, DevNode, CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME, IDS_PHYSICAL_DEVPATH); GetProperty(hMachine, DevNode, CM_DRP_UI_NUMBER, IDS_UI_NUMBER); GetProperty(hMachine, DevNode, CM_DRP_UPPERFILTERS, IDS_UPPERFILTERS); GetProperty(hMachine, DevNode, CM_DRP_LOWERFILTERS, IDS_LOWERFILTERS); GetProperty(hMachine, DevNode, CM_DRP_BUSTYPEGUID, IDS_BUSTYPEGUID); GetProperty(hMachine, DevNode, CM_DRP_LEGACYBUSTYPE, IDS_LEGACYBUSTYPE); return TRUE; } BOOL CDevice::EnumerateAttribute( int Index, CAttribute** ppAttr ) { if (m_listAttributes.IsEmpty() || Index >= m_listAttributes.GetCount()) return FALSE; POSITION pos = m_listAttributes.FindIndex(Index); *ppAttr = m_listAttributes.GetAt(pos); return TRUE; } CDevice::~CDevice() { if (!m_listAttributes.IsEmpty()) { POSITION pos = m_listAttributes.GetHeadPosition(); while (NULL != pos) { delete (CAttribute*)m_listAttributes.GetNext(pos); } m_listAttributes.RemoveAll(); } if (m_pChild) delete m_pChild; if (m_pSibling) delete m_pSibling; } BOOL CComputer::Create( LPCTSTR ComputerName ) { TCHAR LocalComputer[MAX_PATH]; DWORD Size = MAX_PATH - 2; GetComputerName(LocalComputer + 2, &Size); LocalComputer[0] = _T('\\'); LocalComputer[1] = _T('\\'); if (ComputerName && _T('\0') != *ComputerName && _T('\\') == ComputerName[0] && _T('\\') == ComputerName[1]) { m_strDisplayName = ComputerName + 2; m_IsLocal = (0 == lstrcmpi(ComputerName, LocalComputer)); CONFIGRET cr; if (CR_SUCCESS != (cr = CM_Connect_Machine(ComputerName, &m_hMachine))) { m_hMachine = NULL; SetLastError(ERROR_INVALID_COMPUTERNAME); OutputDebugString(_T("Connect computer failed\n")); TCHAR Text[MAX_PATH]; wsprintf(Text, _T("Machine Connection failed, cr= %lx(hex)\n"), cr); MessageBox(NULL, Text, _T("List Device"), MB_ICONSTOP | MB_OK); return FALSE; } } else { m_strDisplayName = LocalComputer + 2; m_IsLocal = TRUE; m_hMachine = NULL; } return TRUE; } CComputer::~CComputer() { CM_Disconnect_Machine(m_hMachine); } BOOL CDeviceTree::Create( LPCTSTR ComputerName ) { if (m_pComputer) { delete m_pComputer; SetupDiDestroyClassImageList(&m_ImageListData); m_ImageListData.cbSize = 0; m_pComputer = NULL; } ASSERT(NULL == m_pComputer); m_pComputer = new CComputer; if (m_pComputer->Create(ComputerName)) { m_ImageListData.cbSize = sizeof(m_ImageListData); SetupDiGetClassImageList(&m_ImageListData); int ImageIndex; SetupDiGetClassImageIndex(&m_ImageListData, (LPGUID)&GUID_DEVCLASS_COMPUTER, &ImageIndex); m_pComputer->SetImageIndex(ImageIndex); DEVNODE dnRoot; CM_Locate_DevNode_Ex(&dnRoot, NULL, 0, *m_pComputer); DEVNODE dnFirst; CM_Get_Child_Ex(&dnFirst, dnRoot, 0, *m_pComputer); return CreateSubtree(m_pComputer, NULL, dnFirst); } else { delete m_pComputer; m_pComputer = NULL; return FALSE; } } BOOL CDeviceTree::CreateSubtree( CDevice* pParent, CDevice* pSibling, DEVNODE dn ) { CDevice* pDevice; DEVNODE dnSibling, dnChild; do { if (CR_SUCCESS != CM_Get_Sibling_Ex(&dnSibling, dn, 0, *m_pComputer)) dnSibling = NULL; pDevice = new CDevice; pDevice->Create(*m_pComputer, dn); pDevice->SetParent(pParent); if (pSibling) pSibling->SetSibling(pDevice); else if (pParent) pParent->SetChild(pDevice); TCHAR GuidString[MAX_GUID_STRING_LEN]; ULONG Size = sizeof(GuidString); if (CR_SUCCESS == CM_Get_DevNode_Registry_Property_Ex(dn, CM_DRP_CLASSGUID, NULL, GuidString, &Size, 0, *m_pComputer) && _T('{') == GuidString[0] && _T('}') == GuidString[MAX_GUID_STRING_LEN - 2]) { GUID Guid; GuidString[MAX_GUID_STRING_LEN - 2] = _T('\0'); UuidFromString(&GuidString[1], &Guid); pDevice->SetClassGuid(&Guid); int Index; if (SetupDiGetClassImageIndex(&m_ImageListData, &Guid, &Index)) pDevice->SetImageIndex(Index); } if (CR_SUCCESS == CM_Get_Child_Ex(&dnChild, dn, 0, *m_pComputer)) { CreateSubtree(pDevice, NULL, dnChild); } dn = dnSibling; pSibling = pDevice; } while (NULL != dn); return TRUE; }