Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
3.1 KiB

  1. // Drivers.cpp : Implementation of CDriverPackages
  2. #include "stdafx.h"
  3. #include "DevCon2.h"
  4. #include "Driver.h"
  5. #include "Drivers.h"
  6. #include "DrvSearchSet.h"
  7. #include "DriversEnum.h"
  8. #include "utils.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CDriverPackages
  11. CDriverPackages::~CDriverPackages()
  12. {
  13. DWORD c;
  14. if(pDrivers) {
  15. for(c=0;c<Count;c++) {
  16. pDrivers[c]->Release();
  17. }
  18. delete [] pDrivers;
  19. }
  20. if(pDrvSearchSet) {
  21. pDrvSearchSet->Release();
  22. pDrvSearchSet = NULL;
  23. }
  24. }
  25. STDMETHODIMP CDriverPackages::get_Count(long *pVal)
  26. {
  27. *pVal = (long)Count;
  28. return S_OK;
  29. }
  30. STDMETHODIMP CDriverPackages::Item(long Index, LPDISPATCH *ppVal)
  31. {
  32. *ppVal = NULL;
  33. DWORD i = (DWORD)Index;
  34. if(i<1 || i > Count) {
  35. return E_INVALIDARG;
  36. }
  37. i--;
  38. pDrivers[i]->AddRef();
  39. *ppVal = pDrivers[i];
  40. return S_OK;
  41. }
  42. STDMETHODIMP CDriverPackages::get__NewEnum(IUnknown **ppUnk)
  43. {
  44. *ppUnk = NULL;
  45. HRESULT hr;
  46. CComObject<CDriverPackagesEnum> *pEnum = NULL;
  47. hr = CComObject<CDriverPackagesEnum>::CreateInstance(&pEnum);
  48. if(FAILED(hr)) {
  49. return hr;
  50. }
  51. if(!pEnum) {
  52. return E_OUTOFMEMORY;
  53. }
  54. pEnum->AddRef();
  55. if(!pEnum->CopyDrivers(pDrivers,Count)) {
  56. pEnum->Release();
  57. return E_OUTOFMEMORY;
  58. }
  59. *ppUnk = pEnum;
  60. return S_OK;
  61. }
  62. BOOL CDriverPackages::IncreaseArraySize(DWORD add)
  63. {
  64. CDriverPackage** pNewDrivers;
  65. DWORD Inc;
  66. DWORD c;
  67. if((ArraySize-Count)>=add) {
  68. return TRUE;
  69. }
  70. Inc = ArraySize + add + 32;
  71. pNewDrivers = new CDriverPackage*[Inc];
  72. if(!pNewDrivers) {
  73. return FALSE;
  74. }
  75. for(c=0;c<Count;c++) {
  76. pNewDrivers[c] = pDrivers[c];
  77. }
  78. delete [] pDrivers;
  79. pDrivers = pNewDrivers;
  80. ArraySize = Inc;
  81. return TRUE;
  82. }
  83. HRESULT CDriverPackages::Init(CDrvSearchSet *pSet)
  84. {
  85. DWORD c;
  86. if(pDrivers) {
  87. for(c=0;c<Count;c++) {
  88. pDrivers[c]->Release();
  89. }
  90. delete [] pDrivers;
  91. }
  92. pDrivers = NULL;
  93. Count = 0;
  94. if(pDrvSearchSet) {
  95. pDrvSearchSet->Release();
  96. pDrvSearchSet = NULL;
  97. }
  98. pSet->AddRef();
  99. pDrvSearchSet = pSet;
  100. return S_OK;
  101. }
  102. HRESULT CDriverPackages::InternalAdd(CDriverPackage *pDriver)
  103. {
  104. if(!IncreaseArraySize(1)) {
  105. return E_OUTOFMEMORY;
  106. }
  107. pDriver->AddRef();
  108. pDrivers[Count++] = pDriver;
  109. return S_OK;
  110. }
  111. STDMETHODIMP CDriverPackages::BestDriver(LPDISPATCH *ppVal)
  112. {
  113. DWORD Err;
  114. HRESULT hr;
  115. //
  116. // attempt to search for best driver
  117. //
  118. if(!SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV,
  119. pDrvSearchSet->GetDevInfoSet(),
  120. pDrvSearchSet->GetDevInfoData()
  121. )) {
  122. Err = GetLastError();
  123. hr = HRESULT_FROM_SETUPAPI(Err);
  124. return hr;
  125. }
  126. SP_DRVINFO_DATA DriverInfoData;
  127. ZeroMemory(&DriverInfoData,sizeof(DriverInfoData));
  128. DriverInfoData.cbSize = sizeof(DriverInfoData);
  129. if(!SetupDiGetSelectedDriver(pDrvSearchSet->GetDevInfoSet(),
  130. pDrvSearchSet->GetDevInfoData(),
  131. &DriverInfoData)) {
  132. Err = GetLastError();
  133. hr = HRESULT_FROM_SETUPAPI(Err);
  134. return hr;
  135. }
  136. //
  137. // now get the driver object associated with this
  138. //
  139. DWORD c;
  140. for(c=0;c<Count;c++) {
  141. if(pDrivers[c]->IsSame(&DriverInfoData)) {
  142. pDrivers[c]->AddRef();
  143. *ppVal = pDrivers[c];
  144. return S_OK;
  145. }
  146. }
  147. return E_UNEXPECTED;
  148. }