⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devicelistctrl.cpp

📁 驱动安装程序
💻 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 + -