📄 devicelistctrl.cpp
字号:
// DeviceListCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "EzDriverSetup.h"
#include "DeviceListCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDeviceListCtrl
#ifndef DT
#define DT DebugTrace
extern BOOL DebugTrace(const char * lpszFormat,...);
#endif
#pragma comment(lib,"cfgmgr32.lib")
#pragma comment(lib,"cfgmgr.lib")
#pragma comment(lib,"ccfapi32.lib")
CDeviceListCtrl::CDeviceListCtrl()
{
ZeroMemory(&m_sid,sizeof(m_sid));
m_hDevInfo = NULL;
}
CDeviceListCtrl::~CDeviceListCtrl()
{
}
BEGIN_MESSAGE_MAP(CDeviceListCtrl, CListCtrl)
//{{AFX_MSG_MAP(CDeviceListCtrl)
ON_WM_DESTROY()
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDeviceListCtrl message handlers
void CDeviceListCtrl::OnDestroy()
{
int nc = this->GetItemCount();
for(int i=0;i<nc;i++)
{
CItemData *pData = (CItemData *)GetItemData(i);
if(pData)
{
SetItemData(i,NULL);
delete pData;
}
}
SetupDiDestroyClassImageList(&m_sid);
CListCtrl::OnDestroy();
}
void CDeviceListCtrl::PreSubclassWindow()
{
Init();
CListCtrl::PreSubclassWindow();
}
int CDeviceListCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CListCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
Init();
return 0;
}
void CDeviceListCtrl::Init()
{
ASSERT(!m_sid.ImageList);
Reset();
}
void CDeviceListCtrl::Reset()
{
if(!GetSafeHwnd())
return;
DeleteAllItems();
SetupDiDestroyClassImageList(&m_sid);
m_sid.cbSize = sizeof(m_sid);
m_sid.ImageList = NULL;
m_sid.Reserved = 0;
SetupDiGetClassImageList(&m_sid);
CImageList *pImageList = CImageList::FromHandle(m_sid.ImageList);
SetImageList(pImageList,LVSIL_NORMAL);
int nc = GetImageList(LVSIL_NORMAL)->GetImageCount();
GetImageList(LVSIL_NORMAL)->SetOverlayImage(nc-2,1);
GetImageList(LVSIL_NORMAL)->SetOverlayImage(nc-3,2);
if(m_hDevInfo)
{
SetupDiDestroyDeviceInfoList(m_hDevInfo);
m_hDevInfo = NULL;
}
m_szCurHwID.Empty();
m_szInfFile.Empty();
}
BOOL CDeviceListCtrl::DeleteAllItems()
{
//delete item's data
int nc = GetItemCount();
for(int i=0;i<nc;i++)
{
CItemData *pItemData = (CItemData *)GetItemData(i);
delete pItemData;
SetItemData(i,NULL);
}
return CListCtrl::DeleteAllItems();
}
BOOL CDeviceListCtrl::OpenInfFile(CString szInfFile)
{
//cleanup old items
Reset();
CStringArray szArrHwID;
{
CInfFileHelper infHelper;
if(!infHelper.OpenInfFile(szInfFile))
return FALSE;
CStringArray szArr;
infHelper.GetManufacturer(szArr);
for(int i=0;i<szArr.GetSize();i++)
{
CStringArray szArrHwIDTemp;
infHelper.GetHardwareID(szArr[i],szArrHwIDTemp);
szArrHwID.Append(szArrHwIDTemp);
}
//infHelper.GetHardwareID(szArr[0],szArrHwID);
}
m_szInfFile = szInfFile;
BOOL bOK = FALSE;
GUID guid;
char szClassName[MAX_PATH];
bOK = SetupDiGetINFClass(szInfFile,&guid,szClassName,MAX_PATH,0);
if(!bOK)
{
DT("open file fail:%s",szInfFile);
return FALSE;
}
m_hDevInfo = SetupDiGetClassDevs(&guid,NULL,NULL,
DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE);
SP_DEVINSTALL_PARAMS sppd = {0};
sppd.cbSize = sizeof(sppd);
bOK = SetupDiGetDeviceInstallParams(m_hDevInfo,NULL,&sppd);
sppd.Flags = DI_ENUMSINGLEINF;
sppd.FlagsEx = DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
strcpy(sppd.DriverPath,szInfFile);
bOK = SetupDiSetDeviceInstallParams(m_hDevInfo,NULL,&sppd);
bOK = SetupDiBuildDriverInfoList(m_hDevInfo,NULL,SPDIT_CLASSDRIVER);
int nIndex = 0;
SP_DRVINFO_DATA driverInfo={0};
driverInfo.cbSize = sizeof(driverInfo);
char szHardID[MAX_PATH+1];
szHardID[0]='\0';
do
{
bOK = SetupDiEnumDriverInfo(m_hDevInfo,0,SPDIT_CLASSDRIVER,nIndex++,&driverInfo);
if(bOK)
{
char szBuf[2000];
ZeroMemory(szBuf,2000);
DWORD dwRequiredSize=0;
PSP_DRVINFO_DETAIL_DATA pDriverDetail =(PSP_DRVINFO_DETAIL_DATA)szBuf;
pDriverDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
if(SetupDiGetDriverInfoDetail(m_hDevInfo,NULL,&driverInfo,
pDriverDetail,2000,&dwRequiredSize))
{
strncpy(szHardID,pDriverDetail->HardwareID,MAX_PATH);
DT("HardID:%s",szHardID);
}
}
}while(bOK);
SetupDiDestroyDriverInfoList(m_hDevInfo,NULL,SPDIT_CLASSDRIVER);
nIndex = -1;
do
{
SP_DEVINFO_DATA spdd={0};
spdd.cbSize = sizeof(spdd);
bOK = SetupDiEnumDeviceInfo(m_hDevInfo,++nIndex,&spdd);
if(bOK)
{
char szBuf[2000];
SetupDiGetDeviceRegistryProperty(m_hDevInfo,&spdd,SPDRP_HARDWAREID,
NULL,(PBYTE)szBuf,2000,NULL);
DT("DeviceID:%s",szBuf);
if(CInfFileHelper::MatchHwID(szArrHwID,szBuf))
{
m_szCurHwID = szBuf;
SetupDiGetDeviceRegistryProperty(m_hDevInfo,&spdd,SPDRP_DEVICEDESC,
NULL,(PBYTE)szBuf,2000,NULL);
int nImageIndex = 0;
SetupDiGetClassImageIndex(&m_sid,&spdd.ClassGuid,&nImageIndex);
int nItemIndex = InsertItem(GetItemCount(),szBuf,nImageIndex);
ULONG uStatus,uProblem;
CM_Get_DevNode_Status(&uStatus,&uProblem,spdd.DevInst,0);
CItemData *pData = new CItemData;
pData->m_nDeviceIndex = nIndex;
pData->m_uProblem = uProblem;
pData->m_uStatus = uStatus;
pData->m_sdd = spdd;
SetItemData(nItemIndex,(DWORD)pData);
if(uStatus & DN_HAS_PROBLEM)
SetItemState(nItemIndex,INDEXTOOVERLAYMASK(1),LVIS_OVERLAYMASK);
else if(!(uStatus & DN_STARTED))
{
SetItemState(nItemIndex,INDEXTOOVERLAYMASK(2),LVIS_OVERLAYMASK);
}
}
}
}while(bOK);
Test();
return TRUE;
}
void CDeviceListCtrl::OnBtn(UINT nID)
{
if(!IsFunctionEnabled(nID))
return;
//*
if(m_szCurHwID.IsEmpty())
{
CInfFileHelper infHelper;
if(!infHelper.OpenInfFile(m_szInfFile))
return ;
CStringArray szArr;
infHelper.GetManufacturer(szArr);
for(int i=0;i<szArr.GetSize();i++)
{
CStringArray szArrHwIDTemp;
infHelper.GetHardwareID(szArr[i],szArrHwIDTemp);
if(szArrHwIDTemp.GetSize()>0)
{
m_szCurHwID = szArrHwIDTemp[0];
break;
}
}
}
if(m_szCurHwID.IsEmpty())
{
AfxMessageBox(IDS_NO_HWID);
return;
}
//*/
CWaitCursor wait;
int nSel = GetFirstSel();
BOOL bOK = FALSE;
if(nID == IDC_BTN_UPDATE_DRIVER)
{
UpdateDriverForPlugAndPlayDevices(NULL,m_szCurHwID,m_szInfFile,
0,NULL);
OpenInfFile(m_szInfFile);
Select(nSel);
}
else if(nID == IDC_BTN_ENABLE_DEVICE)
{
if(nSel != -1)
{
CItemData *pData = (CItemData *)GetItemData(nSel);
BOOL bDisabled = IsDeviceDisabled(nSel);
SP_DEVINFO_DATA spdd={sizeof(SP_DEVINFO_DATA)};
bOK = SetupDiEnumDeviceInfo(m_hDevInfo,pData->m_nDeviceIndex,&spdd);
if(bOK)
{
SP_PROPCHANGE_PARAMS spp= {sizeof(SP_CLASSINSTALL_HEADER)};
spp.StateChange = bDisabled?DICS_ENABLE:DICS_DISABLE;
spp.Scope = DICS_FLAG_GLOBAL;
spp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
bOK = SetupDiSetClassInstallParams(m_hDevInfo,&spdd,
(PSP_CLASSINSTALL_HEADER)&spp,sizeof(spp));
bOK = SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,m_hDevInfo,&spdd);
OpenInfFile(m_szInfFile);
}
Select(nSel);
}
}
else if(nID == IDC_BTN_ADD_DEVICE)
{
CDriverSetupHelper ds;
if(ds.Install(m_szInfFile,m_szCurHwID))
{
OpenInfFile(m_szInfFile);
Select(0xFFFF);
}
else
DT("add device fail!");
}
else if(nID == IDC_BTN_REMOVE_DEVICE)
{
CItemData *pData = (CItemData *)GetItemData(nSel);
SP_DEVINFO_DATA spdd={0};
spdd.cbSize = sizeof(spdd);
bOK = SetupDiEnumDeviceInfo(m_hDevInfo,pData->m_nDeviceIndex,&spdd);
bOK = SetupDiRemoveDevice(m_hDevInfo,&spdd);
OpenInfFile(m_szInfFile);
Select(nSel);
}
else if(nID == IDC_BTN_RESTART_DEVICE)
{
CItemData *pData = (CItemData *)GetItemData(nSel);
SP_PROPCHANGE_PARAMS spp= {sizeof(SP_CLASSINSTALL_HEADER)};
spp.StateChange = DICS_PROPCHANGE;
spp.Scope = DICS_FLAG_CONFIGSPECIFIC;
spp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
bOK = SetupDiSetClassInstallParams(m_hDevInfo,&pData->m_sdd,
(PSP_CLASSINSTALL_HEADER)&spp,sizeof(spp));
DWORD dwErr = GetLastError();
bOK = SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,m_hDevInfo,&pData->m_sdd);
OpenInfFile(m_szInfFile);
Select(nSel);
}
else if(nID == IDC_BTN_REFRESH)//re enum device
{
DEVINST hDevInst = NULL;
CM_Locate_DevNode_Ex(&hDevInst,NULL,CM_LOCATE_DEVNODE_NORMAL,NULL);
CM_Reenumerate_DevNode_Ex(hDevInst,0,0);
}
}
BOOL CDeviceListCtrl::IsFunctionEnabled(UINT nID)
{
if(nID == IDC_BTN_REFRESH)
return TRUE;
POSITION pos = GetFirstSelectedItemPosition();
BOOL bSel = (pos != NULL);
int nc = this->GetItemCount();
if(bSel)
{
int nSel = GetNextSelectedItem(pos);
CItemData *pData = (CItemData *)GetItemData(nSel);
if(!pData)
{
ASSERT(FALSE);
return FALSE;
}
if(pData->m_uStatus & DN_HAS_PROBLEM)
{
//if(pData->m_uProblem & CM_PROB_DISABLED)
}
}
else
{
if(nc>0)
{
if(nID == IDC_BTN_UPDATE_DRIVER)
return TRUE;
}
if(nID == IDC_BTN_ADD_DEVICE)
{
DT(m_szInfFile);
return !m_szInfFile.IsEmpty();
}
else
return FALSE;
}
return TRUE;
}
BOOL CDeviceListCtrl::Find(UINT nIDArr[], UINT cbSize, UINT nFind)
{
for(UINT i=0;i<cbSize;i++)
{
if(nIDArr[i] == nFind)
return TRUE;
}
return FALSE;
}
BOOL CDeviceListCtrl::IsDeviceDisabled(int nIndex)
{
if(nIndex == -1)
{
POSITION pos = GetFirstSelectedItemPosition();
if(pos)
nIndex = GetNextSelectedItem(pos);
}
if(nIndex == -1)
return FALSE;
ASSERT(nIndex>=0 && nIndex<GetItemCount());
CItemData *pData = (CItemData *)GetItemData(nIndex);
if(!pData)
{
ASSERT(FALSE);
return FALSE;
}
BOOL bDisabled = FALSE;
if(pData->m_uStatus & DN_HAS_PROBLEM)
{
bDisabled = (BOOL)(pData->m_uProblem & CM_PROB_DISABLED);
}
return bDisabled;
}
int CDeviceListCtrl::GetFirstSel()
{
int nSel = -1;
POSITION pos = GetFirstSelectedItemPosition();
BOOL bSel = (pos != NULL);
if(bSel)
{
nSel = GetNextSelectedItem(pos);
}
return nSel;
}
LRESULT CDeviceListCtrl::OnDeviceChanged(WPARAM wp, LPARAM lp)
{
int nSel = GetFirstSel();
OpenInfFile(m_szInfFile);
Select(nSel);
return 0;
}
void CDeviceListCtrl::Select(int nIndex)
{
int nc = GetItemCount();
if(nIndex<0)
nIndex = 0;
else if(nIndex>=nc)
nIndex = nc-1;
if(nc>0 && nIndex>=0 && nIndex<nc)
SetItemState (nIndex,LVIS_SELECTED|LVIS_FOCUSED,LVIS_SELECTED|LVIS_FOCUSED);
}
void CDeviceListCtrl::Test()
{
//UpdateDriverForPlugAndPlayDevices(NULL,"Toaster\\MsToaster",
// "G:\\WINDDK\\2600\\src\\general\\toaster\\bin\\toaster.inf",0,NULL);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -