// SetupClasses.cpp : Implementation of CSetupClasses #include "stdafx.h" #include "DevCon2.h" #include "SetupClass.h" #include "SetupClassEnum.h" #include "SetupClasses.h" #include "DeviceConsole.h" #include "Devices.h" #include "xStrings.h" #include "utils.h" ///////////////////////////////////////////////////////////////////////////// // CSetupClasses CSetupClasses::~CSetupClasses() { DWORD c; if(pSetupClasses) { for(c=0;cRelease(); } delete [] pSetupClasses; } if(pMachine) { SysFreeString(pMachine); } } STDMETHODIMP CSetupClasses::get_Count(long *pVal) { *pVal = (long)Count; return S_OK; } STDMETHODIMP CSetupClasses::Item(long Index, LPDISPATCH *ppVal) { *ppVal = NULL; DWORD i = (DWORD)Index; if(i<1 || i > Count) { return E_INVALIDARG; } i--; pSetupClasses[i]->AddRef(); *ppVal = pSetupClasses[i]; return S_OK; } STDMETHODIMP CSetupClasses::get__NewEnum(IUnknown **ppUnk) { *ppUnk = NULL; HRESULT hr; CComObject *pEnum = NULL; hr = CComObject::CreateInstance(&pEnum); if(FAILED(hr)) { return hr; } if(!pEnum) { return E_OUTOFMEMORY; } pEnum->AddRef(); if(!pEnum->CopySetupClasses(pSetupClasses,Count)) { pEnum->Release(); return E_OUTOFMEMORY; } *ppUnk = pEnum; return S_OK; } BOOL CSetupClasses::IncreaseArraySize(DWORD add) { CSetupClass** pNewSetupClasses; DWORD Inc; DWORD c; if((ArraySize-Count)>=add) { return TRUE; } Inc = ArraySize + add + 32; pNewSetupClasses = new CSetupClass*[Inc]; if(!pNewSetupClasses) { return FALSE; } for(c=0;cnClasses2) { nClasses = nClasses2; } if(!nClasses) { // // no classes // delete [] pList; return S_FALSE; } for(c=0;c *d; HRESULT hr; hr = CComObject::CreateInstance(&d); if(FAILED(hr)) { return hr; } d->AddRef(); hr = d->Init(pGuid,pMachine,DeviceConsole); if(FAILED(hr)) { d->Release(); return hr; } pSetupClasses[Count++] = d; return S_OK; } STDMETHODIMP CSetupClasses::Add(VARIANT ClassNames) { // // can pass in a collection // CComObject *pStrings = NULL; HRESULT hr; DWORD c; BSTR str; hr = CComObject::CreateInstance(&pStrings); if(FAILED(hr)) { return hr; } pStrings->AddRef(); hr = pStrings->InternalInsert(0,&ClassNames); if(FAILED(hr)) { pStrings->Release(); return hr; } for(c=0;pStrings->InternalEnum(c,&str);c++) { hr = AppendClass(str); if(FAILED(hr)) { pStrings->Release(); return hr; } } pStrings->Release(); return c ? S_OK : S_FALSE; } BOOL CSetupClasses::FindDuplicate(GUID *pGuid) { DWORD c; for(c=0;cIsDuplicate(pGuid)) { return TRUE; } } return FALSE; } STDMETHODIMP CSetupClasses::Remove(VARIANT v) { // TODO: Add your implementation code here return S_OK; } HRESULT CSetupClasses::GetIndex(LPVARIANT Index, DWORD *pAt) { CComVariant v; HRESULT hr; if(IsNumericVariant(Index)) { hr = v.ChangeType(VT_I4,Index); if(FAILED(hr)) { return DISP_E_TYPEMISMATCH; } if(V_I4(&v)<1) { return E_INVALIDARG; } *pAt = ((DWORD)V_I4(&v))-1; return S_OK; } // // user actually supplied guid? // hr = v.ChangeType(VT_BSTR,Index); if(FAILED(hr)) { return DISP_E_TYPEMISMATCH; } if(!Count) { // // cannot match anything // return E_INVALIDARG; } BSTR pMatch = V_BSTR(&v); if(pMatch[0]!=L'{') { return E_INVALIDARG; } // // obtain GUID // GUID guid; hr = CLSIDFromString((LPWSTR)pMatch,&guid); if(FAILED(hr)) { return hr; } DWORD c; for(c=0;cIsDuplicate(&guid)) { *pAt = c; return S_OK; } } // // still none found // return E_INVALIDARG; } STDMETHODIMP CSetupClasses::Devices(VARIANT flags, LPDISPATCH *pDevices) { // // combine devices for all classes // DWORD diflags = 0; HRESULT hr; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; HDEVINFO hPrevDevInfo = NULL; DWORD Err; DWORD c; hr = TranslateDeviceFlags(&flags,&diflags); if(FAILED(hr)) { return hr; } for(c=0;cGuid(),NULL,NULL,diflags,hPrevDevInfo,pMachine,NULL); if(hDevInfo == INVALID_HANDLE_VALUE) { Err = GetLastError(); if(hPrevDevInfo) { SetupDiDestroyDeviceInfoList(hPrevDevInfo); } return HRESULT_FROM_SETUPAPI(Err); } hPrevDevInfo = hDevInfo; } if(hDevInfo == INVALID_HANDLE_VALUE) { return E_INVALIDARG; } CComObject *d; hr = CComObject::CreateInstance(&d); if(FAILED(hr)) { SetupDiDestroyDeviceInfoList(hDevInfo); return hr; } d->AddRef(); hr = d->Init(hDevInfo,DeviceConsole); if(FAILED(hr)) { d->Release(); return hr; } *pDevices = d; return S_OK; } HRESULT CSetupClasses::AllClasses() { DWORD nClasses; DWORD nClasses2; DWORD c; DWORD Err; HRESULT hr; // // start with empty list // if(pSetupClasses) { for(c=0;cRelease(); } delete [] pSetupClasses; } // // all classes // if(SetupDiBuildClassInfoListEx(0,NULL,0,&nClasses,pMachine,NULL) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(!nClasses) { // // no classes // return S_FALSE; } GUID *pList = new GUID[nClasses]; if(!pList) { return E_OUTOFMEMORY; } if(SetupDiBuildClassInfoListEx(0,pList,nClasses,&nClasses2,pMachine,NULL) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // // count may have changed since last call // if(nClasses>nClasses2) { nClasses = nClasses2; } if(!nClasses) { // // no classes // delete [] pList; return S_FALSE; } for(c=0;c