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.

465 lines
8.6 KiB

  1. // Driver.cpp : Implementation of CDriver
  2. #include <nt.h>
  3. #include <ntrtl.h>
  4. #include <nturtl.h>
  5. #include <windows.h>
  6. #include "stdafx.h"
  7. #include "blkdrv.h"
  8. #include "Driver.h"
  9. extern "C" {
  10. #include <cfgmgr32.h>
  11. #include "cfgmgrp.h"
  12. }
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CBlockedDrivers
  15. STDMETHODIMP CBlockedDrivers::BlockedDrivers(LPDISPATCH *pCollection)
  16. {
  17. HRESULT hr;
  18. CComObject<CDrivers> *pDriversCollection = NULL;
  19. CComObject<CDriver> *pDriver = NULL;
  20. GUID guidDB;
  21. long Count = 0;
  22. hr = CComObject<CDrivers>::CreateInstance(&pDriversCollection);
  23. if(FAILED(hr)) {
  24. return hr;
  25. }
  26. if(!pDriversCollection) {
  27. return E_OUTOFMEMORY;
  28. }
  29. pDriversCollection->AddRef();
  30. CONFIGRET cr;
  31. ULONG ulLength = 0;
  32. cr = CMP_GetBlockedDriverInfo(NULL, &ulLength, 0, NULL);
  33. if ((cr == CR_SUCCESS) && (ulLength == 0)) {
  34. //
  35. // No blocked drivers so set Count to zero to create an empty
  36. // collection.
  37. //
  38. Count = 0;
  39. } else if ((cr == CR_BUFFER_SMALL) && (ulLength > 0)) {
  40. //
  41. // Allocate some memory to hold the list of GUIDs
  42. //
  43. Count = ulLength/sizeof(GUID);
  44. m_guidIDs = new GUID[Count];
  45. if (m_guidIDs == NULL) {
  46. return E_OUTOFMEMORY;
  47. }
  48. cr = CMP_GetBlockedDriverInfo((LPBYTE)m_guidIDs, &ulLength, 0, NULL);
  49. if (cr != CR_SUCCESS) {
  50. return E_OUTOFMEMORY;
  51. }
  52. //
  53. // Open a handle to the database so we can get the database GUID.
  54. //
  55. if (!SdbGetStandardDatabaseGUID(SDB_DATABASE_MAIN_DRIVERS, &guidDB)) {
  56. return E_OUTOFMEMORY;
  57. }
  58. } else {
  59. //
  60. // We encountered an error.
  61. //
  62. return E_OUTOFMEMORY;
  63. }
  64. if(!pDriversCollection->InitDriverList(Count)) {
  65. pDriversCollection->Release();
  66. return E_OUTOFMEMORY;
  67. }
  68. for (long i=0; i<Count; i++) {
  69. hr = CComObject<CDriver>::CreateInstance(&pDriver);
  70. if(FAILED(hr)) {
  71. pDriversCollection->Release();
  72. return hr;
  73. }
  74. pDriver->AddRef();
  75. if(!pDriver->Init(&guidDB, &(m_guidIDs[i]))) {
  76. pDriver->Release();
  77. pDriversCollection->Release();
  78. return E_OUTOFMEMORY;
  79. }
  80. //
  81. // Add the driver to the list.
  82. //
  83. if(!pDriversCollection->SetDriver(i,pDriver)) {
  84. pDriver->Release();
  85. pDriversCollection->Release();
  86. return E_OUTOFMEMORY;
  87. }
  88. pDriver->Release();
  89. }
  90. *pCollection = pDriversCollection;
  91. return S_OK;
  92. }
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CDriver
  95. CDriver::~CDriver()
  96. {
  97. if(m_Name) {
  98. SysFreeString(m_Name);
  99. }
  100. if(m_Description) {
  101. SysFreeString(m_Description);
  102. }
  103. if (m_Manufacturer) {
  104. SysFreeString(m_Manufacturer);
  105. }
  106. if (m_HelpFile) {
  107. SysFreeString(m_HelpFile);
  108. }
  109. if (m_hAppHelpInfoContext) {
  110. SdbCloseApphelpInformation(m_hAppHelpInfoContext);
  111. }
  112. }
  113. STDMETHODIMP CDriver::get_Name(BSTR *pVal)
  114. {
  115. *pVal = SysAllocStringLen(m_Name,SysStringLen(m_Name));
  116. if(!*pVal) {
  117. return E_OUTOFMEMORY;
  118. }
  119. return S_OK;
  120. }
  121. STDMETHODIMP CDriver::get_Description(BSTR *pVal)
  122. {
  123. *pVal = SysAllocStringLen(m_Description,SysStringLen(m_Description));
  124. if(!*pVal) {
  125. return E_OUTOFMEMORY;
  126. }
  127. return S_OK;
  128. }
  129. STDMETHODIMP CDriver::get_Manufacturer(BSTR *pVal)
  130. {
  131. *pVal = SysAllocStringLen(m_Manufacturer,SysStringLen(m_Manufacturer));
  132. if(!*pVal) {
  133. return E_OUTOFMEMORY;
  134. }
  135. return S_OK;
  136. }
  137. STDMETHODIMP CDriver::get_HelpFile(BSTR *pVal)
  138. {
  139. *pVal = SysAllocStringLen(m_HelpFile,SysStringLen(m_HelpFile));
  140. if(!*pVal) {
  141. return E_OUTOFMEMORY;
  142. }
  143. return S_OK;
  144. }
  145. BSTR CDriver::GetValueFromDatabase(
  146. APPHELPINFORMATIONCLASS InfoClass
  147. )
  148. {
  149. DWORD cbSize = 0;
  150. //
  151. // Query for the size
  152. //
  153. cbSize = SdbQueryApphelpInformation(m_hAppHelpInfoContext,
  154. InfoClass,
  155. NULL,
  156. 0
  157. );
  158. if (cbSize == 0) {
  159. //
  160. // value must not exist.
  161. //
  162. return NULL;
  163. }
  164. PBYTE pBuffer = new BYTE[cbSize];
  165. if (pBuffer == NULL) {
  166. return NULL;
  167. }
  168. ZeroMemory(pBuffer, cbSize);
  169. cbSize = SdbQueryApphelpInformation(m_hAppHelpInfoContext,
  170. InfoClass,
  171. (LPVOID)pBuffer,
  172. cbSize
  173. );
  174. if (cbSize == 0) {
  175. return NULL;
  176. }
  177. BSTR bValue = SysAllocString((const OLECHAR *)pBuffer);
  178. delete pBuffer;
  179. return bValue;
  180. }
  181. BOOL CDriver::Init(GUID *pguidDB, GUID *pguidID)
  182. {
  183. if(!pguidDB || !pguidID) {
  184. return FALSE;
  185. }
  186. HAPPHELPINFOCONTEXT hAppHelpInfoContext = NULL;
  187. m_hAppHelpInfoContext = SdbOpenApphelpInformation(pguidDB, pguidID);
  188. if (!m_hAppHelpInfoContext) {
  189. return FALSE;
  190. }
  191. m_Name = GetValueFromDatabase(ApphelpExeName);
  192. m_Description = GetValueFromDatabase(ApphelpAppName);
  193. m_Manufacturer = GetValueFromDatabase(ApphelpVendorName);
  194. m_HelpFile = GetValueFromDatabase(ApphelpHelpCenterURL);
  195. return TRUE;
  196. }
  197. /////////////////////////////////////////////////////////////////////////////
  198. // CDrivers
  199. CDrivers::~CDrivers()
  200. {
  201. long c;
  202. if(pDrivers) {
  203. for(c=0;c<Count;c++) {
  204. if(pDrivers[c]) {
  205. pDrivers[c]->Release();
  206. }
  207. }
  208. delete [] pDrivers;
  209. }
  210. }
  211. STDMETHODIMP CDrivers::get_Count(long *pVal)
  212. {
  213. *pVal = Count;
  214. return S_OK;
  215. }
  216. STDMETHODIMP CDrivers::Item(long Index, LPDISPATCH *ppVal)
  217. {
  218. *ppVal = NULL;
  219. if(Index<1 || Index > Count) {
  220. return E_INVALIDARG;
  221. }
  222. Index--;
  223. pDrivers[Index]->AddRef();
  224. *ppVal = pDrivers[Index];
  225. return S_OK;
  226. }
  227. STDMETHODIMP CDrivers::get__NewEnum(IUnknown **ppUnk)
  228. {
  229. *ppUnk = NULL;
  230. HRESULT hr;
  231. CComObject<CDriversEnum> *pEnum = NULL;
  232. hr = CComObject<CDriversEnum>::CreateInstance(&pEnum);
  233. if(FAILED(hr)) {
  234. return hr;
  235. }
  236. if(!pEnum) {
  237. return E_OUTOFMEMORY;
  238. }
  239. pEnum->AddRef();
  240. if(!pEnum->InternalCopyDrivers(pDrivers,Count)) {
  241. pEnum->Release();
  242. return E_OUTOFMEMORY;
  243. }
  244. *ppUnk = pEnum;
  245. return S_OK;
  246. }
  247. BOOL CDrivers::InitDriverList(long NewCount)
  248. {
  249. long c;
  250. if(pDrivers) {
  251. for(c=0;c<Count;c++) {
  252. if(pDrivers[c]) {
  253. pDrivers[c]->Release();
  254. }
  255. }
  256. delete [] pDrivers;
  257. }
  258. Count = 0;
  259. pDrivers = new CDriver*[NewCount];
  260. if(!pDrivers) {
  261. return NULL;
  262. }
  263. for(c=0;c<NewCount;c++) {
  264. pDrivers[c] = NULL;
  265. }
  266. Count = NewCount;
  267. return TRUE;
  268. }
  269. BOOL CDrivers::SetDriver(long index, CDriver *pDriver)
  270. {
  271. if((index<0) || (index>=Count)) {
  272. return FALSE;
  273. }
  274. pDriver->AddRef();
  275. pDrivers[index] = pDriver;
  276. return TRUE;
  277. }
  278. /////////////////////////////////////////////////////////////////////////////
  279. // CDriversEnum
  280. CDriversEnum::~CDriversEnum()
  281. {
  282. long c;
  283. if(pDrivers) {
  284. for(c=0;c<Count;c++) {
  285. pDrivers[c]->Release();
  286. }
  287. delete [] pDrivers;
  288. }
  289. }
  290. HRESULT CDriversEnum::Next(
  291. ULONG celt,
  292. VARIANT * rgVar,
  293. ULONG * pCeltFetched
  294. )
  295. {
  296. ULONG fetched;
  297. CDriver *pDev;
  298. if(pCeltFetched) {
  299. *pCeltFetched = 0;
  300. }
  301. for(fetched = 0; fetched<celt && Position<Count ; fetched++,Position++) {
  302. VariantInit(&rgVar[fetched]);
  303. pDev = pDrivers[Position];
  304. pDev->AddRef();
  305. V_VT(&rgVar[fetched]) = VT_DISPATCH;
  306. V_DISPATCH(&rgVar[fetched]) = pDev;
  307. }
  308. if(pCeltFetched) {
  309. *pCeltFetched = fetched;
  310. }
  311. return (fetched<celt) ? S_FALSE : S_OK;
  312. }
  313. HRESULT CDriversEnum::Skip(
  314. ULONG celt
  315. )
  316. {
  317. long remaining = Count-Position;
  318. if(remaining<(long)celt) {
  319. Position = Count;
  320. return S_FALSE;
  321. } else {
  322. Position += (long)celt;
  323. return S_OK;
  324. }
  325. }
  326. HRESULT CDriversEnum::Reset(
  327. )
  328. {
  329. Position = 0;
  330. return S_OK;
  331. }
  332. HRESULT CDriversEnum::Clone(
  333. IEnumVARIANT ** ppEnum
  334. )
  335. {
  336. *ppEnum = NULL;
  337. HRESULT hr;
  338. CComObject<CDriversEnum> *pEnum = NULL;
  339. hr = CComObject<CDriversEnum>::CreateInstance(&pEnum);
  340. if(FAILED(hr)) {
  341. return hr;
  342. }
  343. if(!pEnum) {
  344. return E_OUTOFMEMORY;
  345. }
  346. if(!pEnum->InternalCopyDrivers(pDrivers,Count)) {
  347. delete pEnum;
  348. return E_OUTOFMEMORY;
  349. }
  350. pEnum->Position = Position;
  351. pEnum->AddRef();
  352. *ppEnum = pEnum;
  353. return S_OK;
  354. }
  355. BOOL CDriversEnum::InternalCopyDrivers(CDriver **pArray, long NewCount)
  356. {
  357. long c;
  358. if(pDrivers) {
  359. delete [] pDrivers;
  360. pDrivers = NULL;
  361. }
  362. Count = 0;
  363. Position = 0;
  364. pDrivers = new CDriver*[NewCount];
  365. if(!pDrivers) {
  366. return FALSE;
  367. }
  368. for(c=0;c<NewCount;c++) {
  369. pArray[c]->AddRef();
  370. pDrivers[c] = pArray[c];
  371. if(!pDrivers[c]) {
  372. Count = c;
  373. return FALSE;
  374. }
  375. }
  376. Count = NewCount;
  377. return TRUE;
  378. }