windows-nt/Source/XPSP1/NT/base/pnp/tools/devcon2/drivers.cpp
2020-09-26 16:20:57 +08:00

169 lines
3.1 KiB
C++

// Drivers.cpp : Implementation of CDriverPackages
#include "stdafx.h"
#include "DevCon2.h"
#include "Driver.h"
#include "Drivers.h"
#include "DrvSearchSet.h"
#include "DriversEnum.h"
#include "utils.h"
/////////////////////////////////////////////////////////////////////////////
// CDriverPackages
CDriverPackages::~CDriverPackages()
{
DWORD c;
if(pDrivers) {
for(c=0;c<Count;c++) {
pDrivers[c]->Release();
}
delete [] pDrivers;
}
if(pDrvSearchSet) {
pDrvSearchSet->Release();
pDrvSearchSet = NULL;
}
}
STDMETHODIMP CDriverPackages::get_Count(long *pVal)
{
*pVal = (long)Count;
return S_OK;
}
STDMETHODIMP CDriverPackages::Item(long Index, LPDISPATCH *ppVal)
{
*ppVal = NULL;
DWORD i = (DWORD)Index;
if(i<1 || i > Count) {
return E_INVALIDARG;
}
i--;
pDrivers[i]->AddRef();
*ppVal = pDrivers[i];
return S_OK;
}
STDMETHODIMP CDriverPackages::get__NewEnum(IUnknown **ppUnk)
{
*ppUnk = NULL;
HRESULT hr;
CComObject<CDriverPackagesEnum> *pEnum = NULL;
hr = CComObject<CDriverPackagesEnum>::CreateInstance(&pEnum);
if(FAILED(hr)) {
return hr;
}
if(!pEnum) {
return E_OUTOFMEMORY;
}
pEnum->AddRef();
if(!pEnum->CopyDrivers(pDrivers,Count)) {
pEnum->Release();
return E_OUTOFMEMORY;
}
*ppUnk = pEnum;
return S_OK;
}
BOOL CDriverPackages::IncreaseArraySize(DWORD add)
{
CDriverPackage** pNewDrivers;
DWORD Inc;
DWORD c;
if((ArraySize-Count)>=add) {
return TRUE;
}
Inc = ArraySize + add + 32;
pNewDrivers = new CDriverPackage*[Inc];
if(!pNewDrivers) {
return FALSE;
}
for(c=0;c<Count;c++) {
pNewDrivers[c] = pDrivers[c];
}
delete [] pDrivers;
pDrivers = pNewDrivers;
ArraySize = Inc;
return TRUE;
}
HRESULT CDriverPackages::Init(CDrvSearchSet *pSet)
{
DWORD c;
if(pDrivers) {
for(c=0;c<Count;c++) {
pDrivers[c]->Release();
}
delete [] pDrivers;
}
pDrivers = NULL;
Count = 0;
if(pDrvSearchSet) {
pDrvSearchSet->Release();
pDrvSearchSet = NULL;
}
pSet->AddRef();
pDrvSearchSet = pSet;
return S_OK;
}
HRESULT CDriverPackages::InternalAdd(CDriverPackage *pDriver)
{
if(!IncreaseArraySize(1)) {
return E_OUTOFMEMORY;
}
pDriver->AddRef();
pDrivers[Count++] = pDriver;
return S_OK;
}
STDMETHODIMP CDriverPackages::BestDriver(LPDISPATCH *ppVal)
{
DWORD Err;
HRESULT hr;
//
// attempt to search for best driver
//
if(!SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV,
pDrvSearchSet->GetDevInfoSet(),
pDrvSearchSet->GetDevInfoData()
)) {
Err = GetLastError();
hr = HRESULT_FROM_SETUPAPI(Err);
return hr;
}
SP_DRVINFO_DATA DriverInfoData;
ZeroMemory(&DriverInfoData,sizeof(DriverInfoData));
DriverInfoData.cbSize = sizeof(DriverInfoData);
if(!SetupDiGetSelectedDriver(pDrvSearchSet->GetDevInfoSet(),
pDrvSearchSet->GetDevInfoData(),
&DriverInfoData)) {
Err = GetLastError();
hr = HRESULT_FROM_SETUPAPI(Err);
return hr;
}
//
// now get the driver object associated with this
//
DWORD c;
for(c=0;c<Count;c++) {
if(pDrivers[c]->IsSame(&DriverInfoData)) {
pDrivers[c]->AddRef();
*ppVal = pDrivers[c];
return S_OK;
}
}
return E_UNEXPECTED;
}