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.

783 lines
20 KiB

  1. /*++
  2. Copyright (C) 1999- Microsoft Corporation
  3. Module Name:
  4. eventcb.cpp
  5. Abstract:
  6. This module implements CWiaPTPEventCallback class
  7. Author:
  8. William Hsieh (williamh) created
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. //
  13. // This method is the callback function for every PTP event
  14. //
  15. // Input:
  16. // pEvent -- PTP event block
  17. //
  18. HRESULT
  19. CWiaMiniDriver::EventCallbackDispatch(
  20. PPTP_EVENT pEvent
  21. )
  22. {
  23. DBG_FN("CWiaMiniDriver::EventCallback");
  24. HRESULT hr = S_OK;
  25. CPtpMutex cpm(m_hPtpMutex);
  26. if (!pEvent)
  27. {
  28. wiauDbgError("EventCallback", "invalid arg");
  29. return E_INVALIDARG;
  30. }
  31. //
  32. // Events are not expected when there is no open session. Just ignore the event
  33. //
  34. if (!m_pPTPCamera || !m_pPTPCamera->IsCameraSessionOpen())
  35. {
  36. wiauDbgError("EventCallback", "events not expected while there is no open session");
  37. return E_FAIL;
  38. }
  39. //
  40. // Figure out what the event is and call the appropriate function
  41. //
  42. switch (pEvent->EventCode)
  43. {
  44. case PTP_EVENTCODE_CANCELTRANSACTION:
  45. hr = S_OK;
  46. break;
  47. case PTP_EVENTCODE_OBJECTADDED:
  48. hr = AddNewObject(pEvent->Params[0]);
  49. break;
  50. case PTP_EVENTCODE_OBJECTREMOVED:
  51. hr = RemoveObject(pEvent->Params[0]);
  52. break;
  53. case PTP_EVENTCODE_STOREADDED:
  54. hr = AddNewStorage(pEvent->Params[0]);
  55. break;
  56. case PTP_EVENTCODE_STOREREMOVED:
  57. hr = RemoveStorage(pEvent->Params[0]);
  58. break;
  59. case PTP_EVENTCODE_DEVICEPROPCHANGED:
  60. hr = DevicePropChanged((WORD) pEvent->Params[0]);
  61. break;
  62. case PTP_EVENTCODE_OBJECTINFOCHANGED:
  63. hr = ObjectInfoChanged(pEvent->Params[0]);
  64. break;
  65. case PTP_EVENTCODE_DEVICEINFOCHANGED:
  66. // WIAFIX-8/29/2000-davepar Need to handle this
  67. //hr = RebuildDrvItemTree(&DevErrVal);
  68. break;
  69. case PTP_EVENTCODE_REQUESTOBJECTTRANSFER:
  70. //
  71. // This event is ignored, because we don't know where to put the image. Maybe
  72. // it should cause a "button pushed" event.
  73. //
  74. break;
  75. case PTP_EVENTCODE_STOREFULL:
  76. hr = StorageFull(pEvent->Params[0]);
  77. break;
  78. case PTP_EVENTCODE_DEVICERESET:
  79. // WIAFIX-8/29/2000-davepar Need to handle this
  80. //hr = RebuildDrvItemTree(&DevErrVal);
  81. break;
  82. case PTP_EVENTCODE_STORAGEINFOCHANGED:
  83. hr = StorageInfoChanged(pEvent->Params[0]);
  84. break;
  85. case PTP_EVENTCODE_CAPTURECOMPLETE:
  86. hr = CaptureComplete();
  87. break;
  88. case PTP_EVENTCODE_UNREPORTEDSTATUS:
  89. // WIAFIX-8/29/2000-davepar Need to handle this
  90. //hr = RebuildDrvItemTree(&DevErrVal);
  91. break;
  92. default:
  93. //
  94. // If it is a vendor's event, post it
  95. //
  96. if (pEvent->EventCode & PTP_DATACODE_VENDORMASK)
  97. {
  98. hr = PostVendorEvent(pEvent->EventCode);
  99. }
  100. break;
  101. }
  102. return hr;
  103. }
  104. //
  105. // This function adds a new object to the driver item tree. If a new driver
  106. // item is added, a WIA_EVENT_ITEM_CREATED event will be signaled.
  107. //
  108. // Input:
  109. // ObjectHandle -- the new object handle
  110. //
  111. HRESULT
  112. CWiaMiniDriver::AddNewObject(DWORD ObjectHandle)
  113. {
  114. DBG_FN("CWiaMiniDriver::AddNewObject");
  115. HRESULT hr = S_OK;
  116. //
  117. // If there is a capture in progress, we need to wait until all new objects are reported, and
  118. // only then start querying imformation about them. See a sample sequence from the spec below:
  119. //
  120. // -> InitiateCapture Operation ->
  121. // <- InitiateCapture Response <-
  122. // <- ObjectAdded Event(1) <-
  123. // <- ObjectAdded Event(2) <-
  124. // <- ObjectAdded Event(n) <-
  125. // <- CaptureComplete Event <-
  126. // -> GetObjectInfo Operation(1) ->
  127. // <- ObjectInfo Dataset/Response(1) <-
  128. // -> GetObjectInfo Operation(2) ->
  129. // <- ObjectInfo Dataset/Response(2) <-
  130. // -> GetObjectInfo Operation(n) ->
  131. // <- ObjectInfo Dataset/Response(n) <-
  132. //
  133. //
  134. // Check if there is a capture in progress
  135. //
  136. DWORD dwWait = WaitForSingleObject(m_TakePictureDoneEvent, 0);
  137. //
  138. // If there is no capture in progress, process the new object immediately
  139. //
  140. if (dwWait == WAIT_OBJECT_0)
  141. {
  142. hr = AddObject(ObjectHandle, TRUE);
  143. if (FAILED(hr))
  144. {
  145. wiauDbgError("AddNewObject", "AddObject failed");
  146. goto Cleanup;
  147. }
  148. }
  149. //
  150. // If there is a capture in progress, add the new object's handle to the list,
  151. // all new objects will be processed once capture is finished
  152. //
  153. else if (dwWait == WAIT_TIMEOUT)
  154. {
  155. m_CapturedObjects.Add(ObjectHandle);
  156. }
  157. //
  158. // WAIT_FAILED or WAIT_ABANDONED - something's wrong
  159. //
  160. else
  161. {
  162. wiauDbgError("AddNewObject", "WaitForSingle object failed");
  163. hr = E_FAIL;
  164. goto Cleanup;
  165. }
  166. Cleanup:
  167. return hr;
  168. }
  169. //
  170. // This function removes the given object handle from the driver item tree.
  171. // If the object handle has a driver item associated with it and the
  172. // driver item is removed, a WIA_EVENT_ITEM_REMOVED event will be signaled.
  173. //
  174. // Input:
  175. // ObjectHandle -- the object handle to be removed
  176. //
  177. HRESULT
  178. CWiaMiniDriver::RemoveObject(DWORD ObjectHandle)
  179. {
  180. DBG_FN("CWiaMiniDriver::RemoveObject");
  181. HRESULT hr = S_OK;
  182. //
  183. // Find the driver item for the object handle.
  184. //
  185. IWiaDrvItem *pDrvItem = m_HandleItem.Lookup(ObjectHandle);
  186. if (!pDrvItem)
  187. {
  188. wiauDbgError("RemoveObject", "tried to remove object that doesn't exist");
  189. return S_FALSE;
  190. }
  191. //
  192. // Try to remove the object from the ancillary assoc array, in case it's there too. Ancillary
  193. // association objects actually point to images in the handle/item map, so don't delete the
  194. // actual item
  195. //
  196. if (m_AncAssocParent.Remove(ObjectHandle))
  197. {
  198. wiauDbgTrace("RemoveObject", "ancillary association object removed");
  199. }
  200. else
  201. {
  202. BSTR bstrFullName;
  203. hr = pDrvItem->GetFullItemName(&bstrFullName);
  204. if (FAILED(hr))
  205. {
  206. wiauDbgError("RemoveObject", "GetFullItemName failed");
  207. return hr;
  208. }
  209. hr = pDrvItem->RemoveItemFromFolder(WiaItemTypeDisconnected);
  210. if (FAILED(hr))
  211. {
  212. wiauDbgError("RemoveObject", "UnlinkItemTree failed");
  213. return hr;
  214. }
  215. hr = wiasQueueEvent(m_bstrDeviceId, &WIA_EVENT_ITEM_DELETED, bstrFullName);
  216. if (FAILED(hr))
  217. {
  218. wiauDbgError("RemoveObject", "wiasQueueEvent failed");
  219. return hr;
  220. }
  221. SysFreeString(bstrFullName);
  222. }
  223. //
  224. // Remove the object from the handle/drvItem association
  225. //
  226. m_HandleItem.Remove(ObjectHandle);
  227. return hr;
  228. }
  229. //
  230. // This function adds a new storage to the driver item tree.
  231. // A WIA_EVENT_STORAGE_CREATED event will be singaled.
  232. //
  233. // Input:
  234. // StorageId -- the new storage id to be added
  235. //
  236. HRESULT
  237. CWiaMiniDriver::AddNewStorage(DWORD StorageId)
  238. {
  239. DBG_FN("CWiaMiniDriver::AddNewStorage");
  240. HRESULT hr = S_OK;
  241. CArray32 StorageIdList;
  242. //
  243. // If several logical stores were added, the device may indicate
  244. // to re-enumerate the stores
  245. //
  246. if (StorageId == PTP_STORAGEID_UNDEFINED)
  247. {
  248. hr = m_pPTPCamera->GetStorageIDs(&StorageIdList);
  249. if (FAILED(hr))
  250. {
  251. wiauDbgError("AddNewStorage", "GetStorageIDs failed");
  252. return hr;
  253. }
  254. //
  255. // Loop through the list of new storage ids, removing the ones
  256. // that have already been enumerated
  257. //
  258. int index;
  259. for (int count = 0; count < StorageIdList.GetSize(); count++)
  260. {
  261. index = m_StorageIds.Find(StorageIdList[count]);
  262. if (index >= 0)
  263. {
  264. StorageIdList.RemoveAt(index);
  265. }
  266. }
  267. }
  268. //
  269. // Otherwise there is just one storage id to work on
  270. //
  271. else
  272. {
  273. StorageIdList.Add(StorageId);
  274. }
  275. //
  276. // Loop through all of the new storage ids
  277. //
  278. CPtpStorageInfo tempSI;
  279. for (int storageIndex = 0; storageIndex < StorageIdList.GetSize(); storageIndex++)
  280. {
  281. //
  282. // Get info for the new storage
  283. //
  284. hr = m_pPTPCamera->GetStorageInfo(StorageIdList[storageIndex], &tempSI);
  285. if (FAILED(hr))
  286. {
  287. wiauDbgError("drvInitializeWia", "GetStorageInfo failed");
  288. return hr;
  289. }
  290. //
  291. // Add the storage id to the main list
  292. //
  293. if (!m_StorageIds.Add(StorageIdList[storageIndex]))
  294. {
  295. wiauDbgError("AddNewStorage", "add storage id failed");
  296. return E_OUTOFMEMORY;
  297. }
  298. //
  299. // Add storage info to array
  300. //
  301. if (!m_StorageInfos.Add(tempSI))
  302. {
  303. wiauDbgError("drvInitializeWia", "add storage info failed");
  304. return E_OUTOFMEMORY;
  305. }
  306. //
  307. // Add an empty entry to the DCIM handle array
  308. //
  309. ULONG dummy = 0;
  310. if (!m_DcimHandle.Add(dummy))
  311. {
  312. wiauDbgError("AddNewStorage", "add dcim handle failed");
  313. return E_OUTOFMEMORY;
  314. }
  315. //
  316. // Loop through all of the objects on the new storage, adding them one
  317. // at a time.
  318. //
  319. CArray32 ObjectHandleList;
  320. hr = m_pPTPCamera->GetObjectHandles(StorageIdList[storageIndex], PTP_FORMATCODE_ALL,
  321. PTP_OBJECTHANDLE_ALL, &ObjectHandleList);
  322. if (FAILED(hr))
  323. {
  324. wiauDbgError("AddNewStorage", "GetObjectHandles failed");
  325. return hr;
  326. }
  327. //
  328. // Iterate through the object handles, creating a WIA driver item for each
  329. //
  330. for (int objectindex = 0; objectindex < ObjectHandleList.GetSize(); objectindex++)
  331. {
  332. hr = AddObject(ObjectHandleList[objectindex], TRUE);
  333. if (FAILED(hr))
  334. {
  335. wiauDbgError("AddNewStorage", "AddObject failed");
  336. return hr;
  337. }
  338. }
  339. }
  340. return hr;
  341. }
  342. //
  343. // This function removes all of the objects on a storage from the
  344. // driver item tree, signalling WIA_EVENT_ITEM_DELETED as appropriate.
  345. //
  346. // Input:
  347. // StorageId -- storage to delete
  348. //
  349. HRESULT
  350. CWiaMiniDriver::RemoveStorage(DWORD StorageId)
  351. {
  352. DBG_FN("CWiaMiniDriver::RemoveStorage");
  353. HRESULT hr = S_OK;
  354. //
  355. // If the lower 16 bits of the storage id is 0xffff, an entire physical store
  356. // was removed--match only the upper 16 bits of the storage id
  357. //
  358. DWORD StorageIdMask = PTP_STORAGEID_ALL;
  359. if ((StorageId & PTP_STORAGEID_LOGICAL) == PTP_STORAGEID_LOGICAL)
  360. {
  361. StorageIdMask = PTP_STORAGEID_PHYSICAL;
  362. StorageId &= StorageIdMask;
  363. }
  364. //
  365. // Traverse the driver item tree depth-first looking for objects that were on
  366. // the removed storage
  367. //
  368. CWiaArray<IWiaDrvItem*> ItemStack;
  369. IWiaDrvItem *pCurrent = NULL;
  370. IWiaDrvItem *pChild = NULL;
  371. IWiaDrvItem *pSibling = NULL;
  372. if (m_pDrvItemRoot)
  373. {
  374. hr = m_pDrvItemRoot->GetFirstChildItem(&pCurrent);
  375. if (FAILED(hr))
  376. {
  377. wiauDbgError("RemoveStorage", "GetFirstChildItem failed");
  378. return hr;
  379. }
  380. }
  381. else
  382. {
  383. wiauDbgWarning("RemoveStorage", "Tree is not built yet (m_pDrvItemRoot is NULL)");
  384. pCurrent = NULL;
  385. }
  386. while (pCurrent)
  387. {
  388. hr = pCurrent->GetFirstChildItem(&pChild);
  389. //
  390. // GetFirstChildItem returns E_INVALIDARG if there are no child items
  391. //
  392. if (FAILED(hr) && hr != E_INVALIDARG)
  393. {
  394. wiauDbgError("RemoveStorage", "GetFirstChildItem failed");
  395. return hr;
  396. }
  397. //
  398. // Children exist, so traverse down the tree
  399. //
  400. if (hr != E_INVALIDARG && pChild)
  401. {
  402. if (!ItemStack.Push(pCurrent))
  403. {
  404. wiauDbgError("RemoveStorage", "memory allocation failed");
  405. return E_OUTOFMEMORY;
  406. }
  407. pCurrent = pChild;
  408. pChild = NULL;
  409. }
  410. //
  411. // No children, so look for siblings and potentially delete the current driver item
  412. //
  413. else
  414. {
  415. //
  416. // Loop through all of the siblings
  417. //
  418. while (TRUE)
  419. {
  420. hr = pCurrent->GetNextSiblingItem(&pSibling);
  421. if (FAILED(hr))
  422. {
  423. wiauDbgError("RemoveStorage", "GetNextSiblingItem failed");
  424. return hr;
  425. }
  426. //
  427. // See if the item is on the storage which was removed
  428. //
  429. PDRVITEM_CONTEXT pDrvItemContext;
  430. hr = pCurrent->GetDeviceSpecContext((BYTE **) &pDrvItemContext);
  431. if (FAILED(hr))
  432. {
  433. wiauDbgError("RemoveStorage", "GetDeviceSpecContext failed");
  434. return hr;
  435. }
  436. if ((pDrvItemContext->pObjectInfo->m_StorageId & StorageIdMask) == StorageId)
  437. {
  438. //
  439. // Remove the item
  440. //
  441. hr = RemoveObject(pDrvItemContext->pObjectInfo->m_ObjectHandle);
  442. if (FAILED(hr))
  443. {
  444. wiauDbgError("RemoveStorage", "RemoveObject failed");
  445. return hr;
  446. }
  447. }
  448. //
  449. // Found a sibling, so go to the top and look for children
  450. //
  451. if (pSibling)
  452. {
  453. pCurrent = pSibling;
  454. pSibling = NULL;
  455. break;
  456. }
  457. //
  458. // No sibling, so pop up a level
  459. //
  460. else
  461. {
  462. if (ItemStack.GetSize() > 0)
  463. {
  464. if (!ItemStack.Pop(pCurrent))
  465. {
  466. wiauDbgError("RemoveStorage", "Pop failed");
  467. return E_FAIL;
  468. }
  469. }
  470. //
  471. // No more levels to pop, so the loop is done
  472. //
  473. else
  474. {
  475. pCurrent = NULL;
  476. break;
  477. }
  478. }
  479. }
  480. }
  481. }
  482. //
  483. // Remove the store from the appropriate arrays
  484. //
  485. for (int count = 0; count < m_StorageIds.GetSize(); count++)
  486. {
  487. if ((m_StorageIds[count] & StorageIdMask) == StorageId)
  488. {
  489. m_StorageIds.RemoveAt(count);
  490. m_StorageInfos.RemoveAt(count);
  491. m_DcimHandle.RemoveAt(count);
  492. count--;
  493. }
  494. }
  495. return hr;
  496. }
  497. //
  498. // This function updates the value for a property
  499. //
  500. // Input:
  501. // PropCode -- property code that was updated
  502. //
  503. HRESULT
  504. CWiaMiniDriver::DevicePropChanged(WORD PropCode)
  505. {
  506. DBG_FN("CWiaMiniDriver::DevicePropChanged");
  507. HRESULT hr = S_OK;
  508. int idx = m_DeviceInfo.m_SupportedProps.Find(PropCode);
  509. if (idx < 0)
  510. {
  511. wiauDbgWarning("DevicePropChanged", "prop code not found %d", PropCode);
  512. return hr;
  513. }
  514. hr = m_pPTPCamera->GetDevicePropValue(PropCode, &m_PropDescs[idx]);
  515. if (FAILED(hr))
  516. {
  517. wiauDbgError("DevicePropChanged", "GetDevicePropValue failed");
  518. return hr;
  519. }
  520. return hr;
  521. }
  522. //
  523. // This function updates the object info for an object
  524. //
  525. // Input:
  526. // ObjectHandle -- the object whose ObjectInfo needs updating
  527. //
  528. HRESULT
  529. CWiaMiniDriver::ObjectInfoChanged(DWORD ObjectHandle)
  530. {
  531. DBG_FN("CWiaMiniDriver::ObjectInfoChanged");
  532. HRESULT hr = S_OK;
  533. //
  534. // Find the driver item for the object handle.
  535. //
  536. IWiaDrvItem *pDrvItem = m_HandleItem.Lookup(ObjectHandle);
  537. if (!pDrvItem)
  538. {
  539. wiauDbgError("ObjectInfoChanged", "tried to update object that doesn't exist");
  540. return S_FALSE;
  541. }
  542. PDRVITEM_CONTEXT pDrvItemContext;
  543. hr = pDrvItem->GetDeviceSpecContext((BYTE **) &pDrvItemContext);
  544. if (FAILED(hr))
  545. {
  546. wiauDbgError("ObjectInfoChanged", "GetDeviceSpecContext failed");
  547. return hr;
  548. }
  549. hr = m_pPTPCamera->GetObjectInfo(ObjectHandle, pDrvItemContext->pObjectInfo);
  550. if (FAILED(hr))
  551. {
  552. wiauDbgError("ObjectInfoChanged", "GetObjectInfo failed");
  553. return hr;
  554. }
  555. return hr;
  556. }
  557. //
  558. // This function marks a storage as full
  559. //
  560. // Input:
  561. // StorageId -- the storage to be marked
  562. //
  563. HRESULT
  564. CWiaMiniDriver::StorageFull(DWORD StorageId)
  565. {
  566. DBG_FN("CWiaMiniDriver::StorageFull");
  567. HRESULT hr = S_OK;
  568. INT index = m_StorageIds.Find(StorageId);
  569. if (index < 0)
  570. {
  571. wiauDbgError("StorageFull", "storage id not found");
  572. return S_FALSE;
  573. }
  574. CPtpStorageInfo *pStorageInfo = &m_StorageInfos[index];
  575. pStorageInfo->m_FreeSpaceInBytes = 0;
  576. pStorageInfo->m_FreeSpaceInImages = 0;
  577. //
  578. // Signal that the TakePicture command is complete, if the driver was waiting for one
  579. //
  580. if (!SetEvent(m_TakePictureDoneEvent))
  581. {
  582. hr = HRESULT_FROM_WIN32(::GetLastError());
  583. wiauDbgErrorHr(hr, "EventCallbackDispatch", "SetEvent failed");
  584. return hr;
  585. }
  586. return hr;
  587. }
  588. //
  589. // This function updates a StorageInfo
  590. //
  591. // Input:
  592. // StorageId -- the storage id to be updated
  593. //
  594. HRESULT
  595. CWiaMiniDriver::StorageInfoChanged(DWORD StorageId)
  596. {
  597. DBG_FN("CWiaMiniDriver::StorageInfoChanged");
  598. HRESULT hr = S_OK;
  599. INT index = m_StorageIds.Find(StorageId);
  600. if (index < 0)
  601. {
  602. wiauDbgError("StorageInfoChanged", "storage id not found");
  603. return S_FALSE;
  604. }
  605. CPtpStorageInfo *pStorageInfo = &m_StorageInfos[index];
  606. hr = m_pPTPCamera->GetStorageInfo(StorageId, pStorageInfo);
  607. if (FAILED(hr))
  608. {
  609. wiauDbgError("StorageInfoChanged", "GetStorageInfo failed");
  610. return hr;
  611. }
  612. return hr;
  613. }
  614. //
  615. // This function processes the CaptureComplete event
  616. //
  617. // Input:
  618. // StorageId -- the storage id to be updated
  619. //
  620. HRESULT
  621. CWiaMiniDriver::CaptureComplete()
  622. {
  623. DBG_FN("CWiaMiniDriver::CaptureComplete");
  624. HRESULT hr = S_OK;
  625. //
  626. // Signal that the TakePicture command is complete
  627. //
  628. if (!SetEvent(m_TakePictureDoneEvent))
  629. {
  630. hr = HRESULT_FROM_WIN32(::GetLastError());
  631. wiauDbgErrorHr(hr, "EventCallbackDispatch", "SetEvent failed");
  632. return hr;
  633. }
  634. return hr;
  635. }
  636. //
  637. // This function posts a vendor defined event
  638. //
  639. // Input:
  640. // EventCode -- the event code
  641. //
  642. HRESULT
  643. CWiaMiniDriver::PostVendorEvent(WORD EventCode)
  644. {
  645. DBG_FN("CWiaMiniDriver::PostVendorEvent");
  646. HRESULT hr = S_OK;
  647. CVendorEventInfo *pEventInfo = NULL;
  648. pEventInfo = m_VendorEventMap.Lookup(EventCode);
  649. if (pEventInfo)
  650. {
  651. hr = wiasQueueEvent(m_bstrDeviceId, pEventInfo->pGuid, NULL);
  652. if (FAILED(hr))
  653. {
  654. wiauDbgError("PostVendorEvent", "wiasQueueEvent failed");
  655. return hr;
  656. }
  657. }
  658. return hr;
  659. }