Leaked source code of windows server 2003
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.

1155 lines
28 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1998
  4. *
  5. * TITLE: IDrvItem.Cpp
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: marke
  10. *
  11. * DATE: 30 Aug, 1998
  12. *
  13. * DESCRIPTION:
  14. * Implementation of the WIA test camera item methods.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #include "stiexe.h"
  19. #include "linklist.h"
  20. #include "wiamindr.h"
  21. #include "ienumitm.h"
  22. #include "helpers.h"
  23. #include "lockmgr.h"
  24. VOID WINAPI FreeDrvItemContextCallback(VOID *pData);
  25. VOID WINAPI ReleaseDrvItemCallback(VOID *pData);
  26. /**************************************************************************\
  27. * CWiaDrvItem::QueryInterface
  28. *
  29. * Standard COM method.
  30. *
  31. * Arguments:
  32. *
  33. * iid - Interface ID to query
  34. * ppv - Pointer to returned interface.
  35. *
  36. * Return Value:
  37. *
  38. * Status
  39. *
  40. * History:
  41. *
  42. * 1/19/1999 Original Version
  43. *
  44. \**************************************************************************/
  45. HRESULT _stdcall CWiaDrvItem::QueryInterface(const IID& iid, void** ppv)
  46. {
  47. *ppv = NULL;
  48. if ((iid == IID_IUnknown) || (iid == IID_IWiaDrvItem)) {
  49. *ppv = (IWiaDrvItem*) this;
  50. } else {
  51. return E_NOINTERFACE;
  52. }
  53. AddRef();
  54. return (S_OK);
  55. }
  56. ULONG _stdcall CWiaDrvItem::AddRef()
  57. {
  58. InterlockedIncrement((long*) &m_cRef);
  59. return m_cRef;
  60. }
  61. ULONG _stdcall CWiaDrvItem::Release()
  62. {
  63. ULONG ulRefCount = m_cRef - 1;
  64. if (InterlockedDecrement((long*) &m_cRef) == 0) {
  65. delete this;
  66. return 0;
  67. }
  68. return ulRefCount;
  69. }
  70. /**************************************************************************\
  71. * CWiaDrvItem
  72. *
  73. * CWiaDrvItem constructor.
  74. *
  75. * Arguments:
  76. *
  77. * None
  78. *
  79. * Return Value:
  80. *
  81. * Status
  82. *
  83. * History:
  84. *
  85. * 1/19/1999 Original Version
  86. *
  87. \**************************************************************************/
  88. CWiaDrvItem::CWiaDrvItem()
  89. {
  90. m_ulSig = CWIADRVITEM_SIG;
  91. m_cRef = 0;
  92. m_pbDrvItemContext = NULL;
  93. m_pIWiaMiniDrv = NULL;
  94. m_pCWiaTree = NULL;
  95. m_pActiveDevice = NULL;
  96. InitializeListHead(&m_leAppItemListHead);
  97. }
  98. /**************************************************************************\
  99. * Initialize
  100. *
  101. * Initializ a new CWiaDrvItem.
  102. *
  103. * Arguments:
  104. *
  105. * lFlags - Object flags for new item.
  106. * bstrItemName - Item name.
  107. * bstrFullItemName - Full item name, including path.
  108. * pIWiaMiniDrv - Pointer to the device object.
  109. * cbDevSpecContext - Number of bytes to allocate for device
  110. * specific context.
  111. * ppDevSpecContext - Pointer to returned device specific context.
  112. *
  113. * Return Value:
  114. *
  115. * Status
  116. *
  117. * History:
  118. *
  119. * 1/19/1999 Original Version
  120. *
  121. \**************************************************************************/
  122. HRESULT _stdcall CWiaDrvItem::Initialize(
  123. LONG lFlags,
  124. BSTR bstrItemName,
  125. BSTR bstrFullItemName,
  126. IWiaMiniDrv *pIWiaMiniDrv,
  127. LONG cbDevSpecContext,
  128. BYTE **ppDevSpecContext
  129. )
  130. {
  131. DBG_FN(CWiaDrvItem::Initialize);
  132. DBG_TRC(("CWiaDrvItem::Initialize: 0x%08X, %S", this, bstrItemName));
  133. HRESULT hr = S_OK;
  134. if (pIWiaMiniDrv == NULL) {
  135. DBG_ERR(("CWiaDrvItem::Initialize, bad pIWiaMiniDrv parameter"));
  136. return E_INVALIDARG;
  137. }
  138. m_pCWiaTree = new CWiaTree;
  139. if (m_pCWiaTree) {
  140. hr = m_pCWiaTree->Initialize(lFlags,
  141. bstrItemName,
  142. bstrFullItemName,
  143. (void*)this);
  144. if (SUCCEEDED(hr)) {
  145. m_pIWiaMiniDrv = pIWiaMiniDrv;
  146. //
  147. // alloc device specific context
  148. //
  149. if (cbDevSpecContext > 0) {
  150. hr = AllocDeviceSpecContext(cbDevSpecContext, ppDevSpecContext);
  151. }
  152. }
  153. if (FAILED(hr)) {
  154. delete m_pCWiaTree;
  155. m_pCWiaTree = NULL;
  156. }
  157. }
  158. else {
  159. DBG_ERR(("CWiaDrvItem::Initialize, new CWiaTree failed"));
  160. hr = E_OUTOFMEMORY;
  161. }
  162. return hr;
  163. }
  164. /**************************************************************************\
  165. * ~CWiaDrvItem
  166. *
  167. * CWiaDrvItem destructor
  168. *
  169. * Arguments:
  170. *
  171. * None
  172. *
  173. * Return Value:
  174. *
  175. * Status
  176. *
  177. * History:
  178. *
  179. * 1/19/1999 Original Version
  180. *
  181. \**************************************************************************/
  182. CWiaDrvItem::~CWiaDrvItem()
  183. {
  184. DBG_TRC(("CWiaDrvItem::~CWiaDrvItem, (destroy)"));
  185. //
  186. // Release the backing tree item.
  187. //
  188. if (m_pCWiaTree) {
  189. delete m_pCWiaTree;
  190. m_pCWiaTree = NULL;
  191. }
  192. //
  193. // free device driver references
  194. //
  195. if (m_pbDrvItemContext != NULL) {
  196. FreeDrvItemContextCallback((VOID*)this);
  197. // DBG_ERR(("CWiaDrvItem destroy, device specific context not empty"));
  198. }
  199. //
  200. // Unlink the app item list.
  201. //
  202. LIST_ENTRY *pEntry;
  203. PAPP_ITEM_LIST_EL pElem;
  204. while (!IsListEmpty(&m_leAppItemListHead)) {
  205. pEntry = RemoveHeadList(&m_leAppItemListHead);
  206. if (pEntry) {
  207. pElem = CONTAINING_RECORD( pEntry, APP_ITEM_LIST_EL, ListEntry );
  208. if (pElem) {
  209. LocalFree(pElem);
  210. }
  211. }
  212. }
  213. //
  214. // clear all members
  215. //
  216. if (m_pActiveDevice) {
  217. //
  218. // If the ACTIVE_DEVICE is pointing to us, make sure
  219. // we set its Driver Item pointer to NULL since we're going away...
  220. //
  221. if (m_pActiveDevice->m_pRootDrvItem == this) {
  222. m_pActiveDevice->SetDriverItem(NULL);
  223. }
  224. m_pActiveDevice = NULL;
  225. }
  226. m_ulSig = 0;
  227. m_pbDrvItemContext = NULL;
  228. m_pIWiaMiniDrv = NULL;
  229. }
  230. /**************************************************************************\
  231. * CWiaDrvItem::AddItemToFolder
  232. *
  233. * Add a CWiaDrvItem to the driver item tree.
  234. *
  235. * Arguments:
  236. *
  237. * pIParent - Parent of the driver item.
  238. *
  239. * Return Value:
  240. *
  241. * Status
  242. *
  243. * History:
  244. *
  245. * 1/19/1999 Original Version
  246. *
  247. \**************************************************************************/
  248. HRESULT _stdcall CWiaDrvItem::AddItemToFolder(IWiaDrvItem *pIParent)
  249. {
  250. DBG_FN(CWiaDrvItem::AddItemToFolder);
  251. HRESULT hr = S_OK;
  252. if (!pIParent) {
  253. DBG_ERR(("CWiaDrvItem::AddItemToFolder, NULL parent"));
  254. return E_INVALIDARG;
  255. }
  256. //
  257. // Get temporary parent object.
  258. //
  259. CWiaDrvItem *pParent = (CWiaDrvItem *)pIParent;
  260. //
  261. // Use tree method to add item.
  262. //
  263. hr = m_pCWiaTree->AddItemToFolder(pParent->m_pCWiaTree);
  264. if (SUCCEEDED(hr)) {
  265. //
  266. // Inc ref count of this (child) item since we're giving out
  267. // a reference for it to parent.
  268. //
  269. this->AddRef();
  270. //
  271. // If the parent of this drv item has corresponding app items,
  272. // run down the list and add a new child app item to each tree.
  273. //
  274. {
  275. CWiaCritSect CritSect(&g_semDeviceMan);
  276. PLIST_ENTRY pEntry = pParent->m_leAppItemListHead.Flink;
  277. while (pEntry != &pParent->m_leAppItemListHead) {
  278. PAPP_ITEM_LIST_EL pElem;
  279. pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
  280. CWiaItem *pCWiaItem = pElem->pCWiaItem;
  281. hr = pCWiaItem->UpdateWiaItemTree(ADD_ITEM, this);
  282. if (FAILED(hr)) {
  283. break;
  284. }
  285. pEntry = pEntry->Flink;
  286. }
  287. }
  288. }
  289. return hr;
  290. }
  291. /**************************************************************************\
  292. * RemoveItemFromFolder
  293. *
  294. * Remove a CWiaDrvItem from the driver item tree and mark it so that
  295. * no device access can be done through it.
  296. *
  297. * Arguments:
  298. *
  299. * lReason - Reason for removal of CWiaDrvItem.
  300. *
  301. * Return Value:
  302. *
  303. * Status
  304. *
  305. * History:
  306. *
  307. * 1/19/1999 Original Version
  308. *
  309. \**************************************************************************/
  310. HRESULT _stdcall CWiaDrvItem::RemoveItemFromFolder(LONG lReason)
  311. {
  312. DBG_FN(CWiaDrvItem::RemoveItemFromFolder);
  313. HRESULT hr = S_OK;
  314. //
  315. // Use tree method to remove item.
  316. //
  317. hr = m_pCWiaTree->RemoveItemFromFolder(lReason);
  318. if (SUCCEEDED(hr)) {
  319. //
  320. // If this drv item has corresponding app items, run down the
  321. // list and unlink the app item from each tree.
  322. //
  323. {
  324. CWiaCritSect CritSect(&g_semDeviceMan);
  325. PLIST_ENTRY pEntry = m_leAppItemListHead.Flink;
  326. while (pEntry != &m_leAppItemListHead) {
  327. PAPP_ITEM_LIST_EL pElem;
  328. pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
  329. CWiaItem *pCWiaItem = pElem->pCWiaItem;
  330. pCWiaItem->UpdateWiaItemTree(DELETE_ITEM, this);
  331. pEntry = pEntry->Flink;
  332. }
  333. }
  334. //
  335. // Free device specific context.
  336. //
  337. FreeDrvItemContextCallback((VOID*)this);
  338. }
  339. //
  340. // release reference
  341. //
  342. this->Release();
  343. return S_OK;
  344. }
  345. HRESULT _stdcall CWiaDrvItem::CallDrvUninitializeForAppItems(
  346. ACTIVE_DEVICE *pActiveDevice)
  347. {
  348. //
  349. // If this drv item has corresponding app items, run down the
  350. // list and call drvUnInitializeWia for each App. Item.
  351. //
  352. if (pActiveDevice) {
  353. PLIST_ENTRY pEntry = m_leAppItemListHead.Flink;
  354. while (pEntry != &m_leAppItemListHead) {
  355. PLIST_ENTRY pEntryNext = pEntry->Flink;
  356. PAPP_ITEM_LIST_EL pElem;
  357. pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
  358. CWiaItem *pCWiaItem = pElem->pCWiaItem;
  359. HRESULT hr = E_FAIL;
  360. LONG lDevErrVal = 0;
  361. if (pCWiaItem) {
  362. //
  363. // Only call drvUninitializeWia if it has not been called for this item
  364. // already...
  365. //
  366. if (!(pCWiaItem->m_lInternalFlags & ITEM_FLAG_DRV_UNINITIALIZE_THROWN)) {
  367. hr = g_pStiLockMgr->RequestLock(pActiveDevice, WIA_LOCK_WAIT_TIME, FALSE);
  368. if(SUCCEEDED(hr)) {
  369. hr = pActiveDevice->m_DrvWrapper.WIA_drvUnInitializeWia((BYTE*)pCWiaItem);
  370. if (FAILED(hr)) {
  371. DBG_WRN(("CWiaDrvItem::CallDrvUninitializeForAppItems, drvUnitializeWia failed"));
  372. }
  373. pCWiaItem->m_lInternalFlags |= ITEM_FLAG_DRV_UNINITIALIZE_THROWN;
  374. g_pStiLockMgr->RequestUnlock(pActiveDevice, FALSE);
  375. }
  376. }
  377. }
  378. pEntry = pEntryNext;
  379. }
  380. DBG_TRC(("Done calling drvUnInitializeWia for all items..."));
  381. } else {
  382. ASSERT(("CWiaDrvItem::CallDrvUninitializeForAppItems , called with NULL - this should never happen!", pActiveDevice));
  383. }
  384. //
  385. // We don't care what happened - always return S_OK
  386. //
  387. return S_OK;
  388. }
  389. /**************************************************************************\
  390. * GetDeviceSpecContext
  391. *
  392. * Get the device specific context from a driver item.
  393. *
  394. * Arguments:
  395. *
  396. * ppSpecContext - Pointer to a pointer to receive the device
  397. * specific context pointer.
  398. *
  399. * Return Value:
  400. *
  401. * Status
  402. *
  403. * History:
  404. *
  405. * 1/19/1999 Original Version
  406. *
  407. \**************************************************************************/
  408. HRESULT _stdcall CWiaDrvItem::GetDeviceSpecContext(PBYTE *ppSpecContext)
  409. {
  410. DBG_FN(CWiaDrvItem::GetDeviceSpecContext);
  411. if (ppSpecContext == NULL) {
  412. DBG_ERR(("GetDeviceSpecContext, NULL ppSpecContext pointer"));
  413. return E_POINTER;
  414. }
  415. *ppSpecContext = m_pbDrvItemContext;
  416. if (!m_pbDrvItemContext) {
  417. DBG_ERR(("GetDeviceSpecContext, NULL device specific context"));
  418. return E_INVALIDARG;
  419. }
  420. return S_OK;
  421. }
  422. /**************************************************************************\
  423. * AllocDeviceSpecContext
  424. *
  425. * Allocate the device specific context from a driver item.
  426. *
  427. * Arguments:
  428. *
  429. * cbDevSpecContext - Number of bytes to allocate for device
  430. * specific context.
  431. * ppDevSpecContext - Pointer to returned device specific context.
  432. *
  433. * Return Value:
  434. *
  435. * Status
  436. *
  437. * History:
  438. *
  439. * 1/19/1999 Original Version
  440. *
  441. \**************************************************************************/
  442. HRESULT _stdcall CWiaDrvItem::AllocDeviceSpecContext(
  443. LONG cbSize,
  444. PBYTE *ppSpecContext)
  445. {
  446. DBG_FN(CWiaDrvItem::AllocDeviceSpecContext);
  447. //
  448. // validate size, may want to set max
  449. //
  450. if ((cbSize < 0) || (cbSize > WIA_MAX_CTX_SIZE)) {
  451. DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, request > WIA_MAX_CTX_SIZE"));
  452. return E_INVALIDARG;
  453. }
  454. //
  455. // if a spec context already exists then fail
  456. //
  457. if (m_pbDrvItemContext != NULL) {
  458. DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, Context already exists!"));
  459. return E_INVALIDARG;
  460. }
  461. //
  462. // attempt to alloc
  463. //
  464. m_pbDrvItemContext = (PBYTE)LocalAlloc(LPTR, cbSize);
  465. if (m_pbDrvItemContext == NULL) {
  466. DBG_ERR(("CWiaDrvItem::AllocDeviceSpecContext, unable to allocate %d bytes", cbSize));
  467. return E_OUTOFMEMORY;
  468. }
  469. //
  470. // return ctx if pointer supplied
  471. //
  472. if (ppSpecContext != NULL) {
  473. *ppSpecContext = m_pbDrvItemContext;
  474. }
  475. return S_OK;
  476. }
  477. /**************************************************************************\
  478. * FreeDeviceSpecContext
  479. *
  480. * Free device specific context
  481. *
  482. * Arguments:
  483. *
  484. * None
  485. *
  486. * Return Value:
  487. *
  488. * Status
  489. *
  490. * History:
  491. *
  492. * 1/19/1999 Original Version
  493. *
  494. \**************************************************************************/
  495. HRESULT _stdcall CWiaDrvItem::FreeDeviceSpecContext(void)
  496. {
  497. DBG_FN(CWiaDrvItem::FreeDeviceSpecContext);
  498. if (m_pbDrvItemContext != NULL) {
  499. LocalFree(m_pbDrvItemContext);
  500. m_pbDrvItemContext = NULL;
  501. }
  502. return S_OK;
  503. }
  504. /**************************************************************************\
  505. * GetItemFlags
  506. *
  507. * Return the driver item flags.
  508. *
  509. * Arguments:
  510. *
  511. * plFlags - Pointer to a value to receive the driver item flags.
  512. *
  513. * Return Value:
  514. *
  515. * Status
  516. *
  517. * History:
  518. *
  519. * 1/19/1999 Original Version
  520. *
  521. \**************************************************************************/
  522. HRESULT _stdcall CWiaDrvItem::GetItemFlags(LONG *plFlags)
  523. {
  524. DBG_FN(CWiaDrvItem::GetItemFlags);
  525. return m_pCWiaTree->GetItemFlags(plFlags);
  526. }
  527. /**************************************************************************\
  528. * LinkToDrvItem
  529. *
  530. * Adds the passed in CWiaItem to the driver items list of corresponding
  531. * application items.
  532. *
  533. * Arguments:
  534. *
  535. * pCWiaItem - Pointer to application item.
  536. *
  537. * Return Value:
  538. *
  539. * Status
  540. *
  541. * History:
  542. *
  543. * 1/19/1999 Original Version
  544. *
  545. \**************************************************************************/
  546. HRESULT _stdcall CWiaDrvItem::LinkToDrvItem(CWiaItem *pCWiaItem)
  547. {
  548. DBG_FN(CWiaDrvItem::LinkToDrvItem);
  549. CWiaCritSect CritSect(&g_semDeviceMan);
  550. PAPP_ITEM_LIST_EL pElem;
  551. pElem = (PAPP_ITEM_LIST_EL) LocalAlloc(0, sizeof(APP_ITEM_LIST_EL));
  552. if (pElem) {
  553. pElem->pCWiaItem = pCWiaItem;
  554. InsertHeadList(&m_leAppItemListHead, &pElem->ListEntry);
  555. return S_OK;
  556. }
  557. else {
  558. DBG_ERR(("CWiaDrvItem::LinkToDrvItem alloc of APP_ITEM_LIST_EL failed"));
  559. return E_OUTOFMEMORY;
  560. }
  561. }
  562. /**************************************************************************\
  563. * UnlinkFromDrvItem
  564. *
  565. * Removes the passed in CWiaItem from the driver items list of
  566. * corresponding application items.
  567. *
  568. * Arguments:
  569. *
  570. * pCWiaItem - Pointer to application item.
  571. *
  572. * Return Value:
  573. *
  574. * Status
  575. *
  576. * History:
  577. *
  578. * 1/19/1999 Original Version
  579. *
  580. \**************************************************************************/
  581. HRESULT _stdcall CWiaDrvItem::UnlinkFromDrvItem(CWiaItem *pCWiaItem)
  582. {
  583. DBG_FN(CWiaDrvItem::UnlinkFromDrvItem);
  584. CWiaCritSect CritSect(&g_semDeviceMan);
  585. PLIST_ENTRY pEntry = m_leAppItemListHead.Flink;
  586. while (pEntry != &m_leAppItemListHead) {
  587. PAPP_ITEM_LIST_EL pElem;
  588. pElem = CONTAINING_RECORD(pEntry, APP_ITEM_LIST_EL, ListEntry);
  589. if (pElem->pCWiaItem == pCWiaItem) {
  590. RemoveEntryList(pEntry);
  591. LocalFree(pElem);
  592. return S_OK;
  593. }
  594. pEntry = pEntry->Flink;
  595. }
  596. DBG_ERR(("CWiaDrvItem::UnlinkFromDrvItem, app item not found: 0x%08X", pCWiaItem));
  597. return S_FALSE;
  598. }
  599. /**************************************************************************\
  600. * CWiaDrvItem::GetFullItemName
  601. *
  602. * Allocates and fills in a BSTR with this items full name. The full item
  603. * name includes item path information.
  604. *
  605. * Arguments:
  606. *
  607. * pbstrFullItemName - Pointer to returned full item name.
  608. *
  609. * Return Value:
  610. *
  611. * Status
  612. *
  613. * History:
  614. *
  615. * 1/19/1999 Original Version
  616. *
  617. \**************************************************************************/
  618. HRESULT _stdcall CWiaDrvItem::GetFullItemName(BSTR *pbstrFullItemName)
  619. {
  620. DBG_FN(CWiaDrvItem::GetFullItemName);
  621. return m_pCWiaTree->GetFullItemName(pbstrFullItemName);
  622. }
  623. /**************************************************************************\
  624. * CWiaDrvItem::GetItemName
  625. *
  626. * Allocates and fills in a BSTR with this items name. The item name
  627. * does not include item path information.
  628. *
  629. * Arguments:
  630. *
  631. * pbstrItemName - Pointer to returned item name.
  632. *
  633. * Return Value:
  634. *
  635. * Status
  636. *
  637. * History:
  638. *
  639. * 1/19/1999 Original Version
  640. *
  641. \**************************************************************************/
  642. HRESULT _stdcall CWiaDrvItem::GetItemName(BSTR *pbstrItemName)
  643. {
  644. DBG_FN(CWiaDrvItem::GetItemName);
  645. return m_pCWiaTree->GetItemName(pbstrItemName);
  646. }
  647. /**************************************************************************\
  648. * CWiaDrvItem::DumpItemData
  649. *
  650. * Allocate buffer and dump formatted private CWiaDrvItem data into it.
  651. * This method is debug only. Free component returns E_NOTIMPL.
  652. *
  653. * Arguments:
  654. *
  655. * bstrDrvItemData - Pointer to allocated buffer. Caller must free.
  656. *
  657. * Return Value:
  658. *
  659. * Status
  660. *
  661. * History:
  662. *
  663. * 1/19/1999 Original Version
  664. *
  665. \**************************************************************************/
  666. HRESULT _stdcall CWiaDrvItem::DumpItemData(BSTR *bstrDrvItemData)
  667. {
  668. DBG_FN(CWiaDrvItem::DumpItemData);
  669. #ifdef ITEMDEBUG
  670. #define TREE_BUF_SIZE 1024
  671. #define BUF_SIZE 512 + TREE_BUF_SIZE
  672. #define LINE_SIZE 128
  673. WCHAR szTemp[BUF_SIZE], szTreeTmp[TREE_BUF_SIZE];
  674. LPOLESTR psz = szTemp;
  675. wcscpy(szTemp, L"");
  676. psz+= wsprintfW(psz, L"Drv item, CWiaDrvItem: %08X\r\n\r\n", this);
  677. psz+= wsprintfW(psz, L"Address Member Value\r\n");
  678. psz+= wsprintfW(psz, L"%08X m_ulSig: %08X\r\n", &m_ulSig, m_ulSig);
  679. psz+= wsprintfW(psz, L"%08X m_cRef: %08X\r\n", &m_cRef, m_cRef);
  680. psz+= wsprintfW(psz, L"%08X m_pIWiaMiniDrv: %08X\r\n", &m_pIWiaMiniDrv, m_pIWiaMiniDrv);
  681. psz+= wsprintfW(psz, L"%08X m_pbDrvItemContext: %08X\r\n", &m_pbDrvItemContext, m_pbDrvItemContext);
  682. psz+= wsprintfW(psz, L"%08X m_leAppItemListHead:%08X\r\n", &m_leAppItemListHead,m_leAppItemListHead);
  683. psz+= wsprintfW(psz, L"\r\n");
  684. BSTR bstrTree;
  685. HRESULT hr = m_pCWiaTree->DumpTreeData(&bstrTree);
  686. if (SUCCEEDED(hr)) {
  687. psz+= wsprintfW(psz, L"%ls", bstrTree);
  688. SysFreeString(bstrTree);
  689. }
  690. psz+= wsprintfW(psz, L"\r\n");
  691. if (psz > (szTemp + (BUF_SIZE - LINE_SIZE))) {
  692. DBG_ERR(("CWiaDrvItem::DumpDrvItemData buffer too small"));
  693. }
  694. if (bstrDrvItemData)
  695. {
  696. *bstrDrvItemData = SysAllocString(szTemp);
  697. if (*bstrDrvItemData) {
  698. return S_OK;
  699. }
  700. }
  701. return E_OUTOFMEMORY;
  702. #else
  703. return E_NOTIMPL;
  704. #endif
  705. }
  706. /**************************************************************************\
  707. * CWiaDrvItem::UnlinkItemTree
  708. *
  709. * This method unlinks the tree. Must be called on the root
  710. * driver item.
  711. *
  712. * Arguments:
  713. *
  714. * lReason - Reason for unlinking the tree.
  715. *
  716. * Return Value:
  717. *
  718. * Status
  719. *
  720. * History:
  721. *
  722. * 1/21/1999 Original Version
  723. *
  724. \**************************************************************************/
  725. HRESULT _stdcall CWiaDrvItem::UnlinkItemTree(LONG lReason)
  726. {
  727. DBG_FN(CWiaDrvItem::UnlinkItemTree);
  728. //
  729. // AddRef this item, since ReleaseDrvItemCallback will call release
  730. // and we don't want to destroy this object.
  731. //
  732. AddRef();
  733. return m_pCWiaTree->UnlinkItemTree(lReason,
  734. (PFN_UNLINK_CALLBACK)ReleaseDrvItemCallback);
  735. }
  736. /**************************************************************************\
  737. * CWiaDrvItem::FindItemByName
  738. *
  739. * Locate a driver item by it's full item name.
  740. *
  741. * Arguments:
  742. *
  743. * lFlags - Operation flags.
  744. * bstrFullItemName - Requested item name.
  745. * ppItem - Pointer to returned item, if found.
  746. *
  747. * Return Value:
  748. *
  749. * Status
  750. *
  751. * History:
  752. *
  753. * 1/27/1999 Original Version
  754. *
  755. \**************************************************************************/
  756. HRESULT CWiaDrvItem::FindItemByName(
  757. LONG lFlags,
  758. BSTR bstrFullItemName,
  759. IWiaDrvItem **ppItem)
  760. {
  761. DBG_FN(CWiaDrvItem::FindItemByName);
  762. if (ppItem) {
  763. *ppItem = NULL;
  764. }
  765. else {
  766. DBG_ERR(("CWiaDrvItem::FindItemByName NULL ppItem"));
  767. return E_INVALIDARG;
  768. }
  769. CWiaTree *pCWiaTree;
  770. HRESULT hr = m_pCWiaTree->FindItemByName(lFlags, bstrFullItemName, &pCWiaTree);
  771. if (hr == S_OK) {
  772. pCWiaTree->GetItemData((void**)ppItem);
  773. if (*ppItem) {
  774. (*ppItem)->AddRef();
  775. }
  776. }
  777. return hr;
  778. }
  779. /**************************************************************************\
  780. * CWiaDrvItem::FindChildItemByName
  781. *
  782. * Locate a child item by it's item name.
  783. *
  784. * Arguments:
  785. *
  786. * bstrItemName - Requested item name.
  787. * ppIChildItem - Pointer to returned item, if found.
  788. *
  789. * Return Value:
  790. *
  791. * Status
  792. *
  793. * History:
  794. *
  795. * 1/27/1999 Original Version
  796. *
  797. \**************************************************************************/
  798. HRESULT CWiaDrvItem::FindChildItemByName(
  799. BSTR bstrItemName,
  800. IWiaDrvItem **ppIChildItem)
  801. {
  802. DBG_FN(CWiaDrvItem::FindChildItemName);
  803. CWiaTree *pCWiaTree;
  804. HRESULT hr = m_pCWiaTree->FindChildItemByName(bstrItemName, &pCWiaTree);
  805. if (hr == S_OK) {
  806. hr = pCWiaTree->GetItemData((void**)ppIChildItem);
  807. if ((hr == S_OK) && (*ppIChildItem)) {
  808. (*ppIChildItem)->AddRef();
  809. }
  810. }
  811. return hr;
  812. }
  813. /**************************************************************************\
  814. * CWiaDrvItem::GetParent
  815. *
  816. * Get parent of this item.
  817. *
  818. * Arguments:
  819. *
  820. * ppIParentItem - Pointer to returned parent, if found.
  821. *
  822. * Return Value:
  823. *
  824. * Status
  825. *
  826. * History:
  827. *
  828. * 1/27/1999 Original Version
  829. *
  830. \**************************************************************************/
  831. HRESULT CWiaDrvItem::GetParentItem(IWiaDrvItem **ppIParentItem)
  832. {
  833. DBG_FN(CWiaDrvItem::GetParentItem);
  834. CWiaTree *pCWiaTree;
  835. HRESULT hr = m_pCWiaTree->GetParentItem(&pCWiaTree);
  836. if (hr == S_OK) {
  837. pCWiaTree->GetItemData((void**)ppIParentItem);
  838. }
  839. else {
  840. *ppIParentItem = NULL;
  841. }
  842. return hr;
  843. }
  844. /**************************************************************************\
  845. * CWiaDrvItem::GetFirstChild
  846. *
  847. * Return the first child item of this folder.
  848. *
  849. * Arguments:
  850. *
  851. * ppIChildItem - Pointer to returned child item, if found.
  852. *
  853. * Return Value:
  854. *
  855. * Status
  856. *
  857. * History:
  858. *
  859. * 1/27/1999 Original Version
  860. *
  861. \**************************************************************************/
  862. HRESULT CWiaDrvItem::GetFirstChildItem(IWiaDrvItem **ppIChildItem)
  863. {
  864. DBG_FN(CWiaDrvItem::GetFirstChildItem);
  865. CWiaTree *pCWiaTree;
  866. HRESULT hr = m_pCWiaTree->GetFirstChildItem(&pCWiaTree);
  867. if (hr == S_OK) {
  868. pCWiaTree->GetItemData((void**)ppIChildItem);
  869. }
  870. else {
  871. *ppIChildItem = NULL;
  872. }
  873. return hr;
  874. }
  875. /**************************************************************************\
  876. * CWiaDrvItem::GetNextSiblingItem
  877. *
  878. * Find the next sibling of this item.
  879. *
  880. * Arguments:
  881. *
  882. * ppSiblingItem - Pointer to the returned sibling item, if found.
  883. *
  884. * Return Value:
  885. *
  886. * Status
  887. *
  888. * History:
  889. *
  890. * 1/27/1999 Original Version
  891. *
  892. \**************************************************************************/
  893. HRESULT CWiaDrvItem::GetNextSiblingItem(
  894. IWiaDrvItem **ppSiblingItem)
  895. {
  896. DBG_FN(CWiaDrvItem::GetNextSiblingItem);
  897. CWiaTree *pCWiaTree;
  898. HRESULT hr = m_pCWiaTree->GetNextSiblingItem(&pCWiaTree);
  899. if (hr == S_OK) {
  900. pCWiaTree->GetItemData((void**)ppSiblingItem);
  901. }
  902. else {
  903. *ppSiblingItem = NULL;
  904. }
  905. return hr;
  906. }
  907. /**************************************************************************\
  908. * FreeDrvItemContextCallback
  909. *
  910. * Callback function to free the driver item context. Called by
  911. * CWiaTree::UnlinkItemTree(...) for each node in the tree.
  912. *
  913. * Arguments:
  914. *
  915. * pData - payload data for the tree node. We know that this will be
  916. * a driver item, since only a driver item specifies this
  917. * callback (see CWiaDrvItem::UnlinkItemTree(...))
  918. *
  919. * Return Value:
  920. *
  921. * Status
  922. *
  923. * History:
  924. *
  925. * 10/20/1998 Original Version
  926. *
  927. \**************************************************************************/
  928. VOID WINAPI FreeDrvItemContextCallback(
  929. VOID *pData)
  930. {
  931. DBG_FN(::FreeDrvItemContextCallback);
  932. CWiaDrvItem *pDrvItem = (CWiaDrvItem*) pData;
  933. HRESULT hr = S_OK;
  934. if (pDrvItem) {
  935. //
  936. // Free device specific context, if it exists.
  937. //
  938. LONG lFlags = 0;
  939. LONG lDevErrVal;
  940. if (pDrvItem->m_pbDrvItemContext != NULL) {
  941. __try {
  942. if (pDrvItem->m_pIWiaMiniDrv) {
  943. hr = pDrvItem->m_pIWiaMiniDrv->drvFreeDrvItemContext(lFlags,
  944. pDrvItem->m_pbDrvItemContext,
  945. &lDevErrVal);
  946. }
  947. if (FAILED(hr)) {
  948. DBG_ERR(("FreeDrvItemContextCallback, drvFreeDrvItemContext failed 0x%X", hr));
  949. }
  950. } __except(EXCEPTION_EXECUTE_HANDLER) {
  951. DBG_WRN(("FreeDrvItemContextCallback, exception calling drvFreeDrvItemContext (this is expected)"));
  952. }
  953. LocalFree(pDrvItem->m_pbDrvItemContext);
  954. pDrvItem->m_pbDrvItemContext = NULL;
  955. } else {
  956. DBG_TRC(("FreeDrvItemContextCallback, Context is NULL! Nothing to free..."));
  957. }
  958. }
  959. }
  960. VOID WINAPI ReleaseDrvItemCallback(
  961. VOID *pData)
  962. {
  963. DBG_FN(::ReleaseDrvItemCallback);
  964. CWiaDrvItem *pDrvItem = (CWiaDrvItem*) pData;
  965. HRESULT hr = S_OK;
  966. if (pDrvItem) {
  967. //
  968. // First, free the driver item context
  969. //
  970. FreeDrvItemContextCallback(pData);
  971. //
  972. // Call release on the driver item
  973. //
  974. pDrvItem->Release();
  975. }
  976. }