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.

1773 lines
43 KiB

  1. /*++
  2. Copyright (C) 1999- Microsoft Corporation
  3. Module Name:
  4. camera.cpp
  5. Abstract:
  6. This module implements the CPTPCamera class, which is a generic implementation
  7. of a PTP camera. Transport-specific processing is implemented in a sub-class.
  8. Author:
  9. William Hsieh (williamh) created
  10. Revision History:
  11. --*/
  12. #include "ptppch.h"
  13. //
  14. // This thread reads event data from the device and sends it back to the minidriver
  15. //
  16. // Input:
  17. // pParam -- pointer to the CPTPCamera subclassed object which can read the data
  18. // Output:
  19. // Thread exit code
  20. //
  21. DWORD
  22. WINAPI
  23. EventThread(
  24. LPVOID pParam
  25. )
  26. {
  27. DBG_FN("EventThread");
  28. HRESULT hr = S_OK;
  29. CPTPCamera *pDevice;
  30. wiauDbgTrace("EventThread", "starting");
  31. pDevice = (CPTPCamera *)pParam;
  32. if (!pDevice)
  33. {
  34. wiauDbgError("EventThread", "invalid arg");
  35. return ERROR_INVALID_PARAMETER;
  36. }
  37. DWORD Win32Err;
  38. //
  39. // Call the callback once with a NULL pointer so that it can initialize itself
  40. //
  41. hr = (pDevice->GetPTPEventCallback())(pDevice->GetEventCallbackParam(), NULL);
  42. if (FAILED(hr))
  43. {
  44. //
  45. // Log an error, but keep on catching events
  46. //
  47. wiauDbgError("EventThread", "event callback failed");
  48. }
  49. //
  50. // Read an event from the device. If an error occurs, log an error message and then
  51. // continue, unless the operation was aborted by the main thread.
  52. //
  53. PPTP_EVENT pEventBuffer = pDevice->GetEventBuffer();
  54. while (TRUE)
  55. {
  56. ZeroMemory(pEventBuffer, sizeof(*pEventBuffer));
  57. hr = pDevice->ReadEvent(pEventBuffer);
  58. if (FAILED(hr))
  59. {
  60. wiauDbgError("EventThread", "ReadEvent failed");
  61. break;;
  62. }
  63. if (hr == S_FALSE) {
  64. wiauDbgTrace("EventThread", "ReadEvent cancelled");
  65. break;
  66. }
  67. if (g_dwDebugFlags & WIAUDBG_DUMP) {
  68. DumpEvent(pEventBuffer);
  69. }
  70. //
  71. // Send the event back to the minidriver via its callback function
  72. //
  73. hr = (pDevice->GetPTPEventCallback())(pDevice->GetEventCallbackParam(), pEventBuffer);
  74. if (FAILED(hr))
  75. {
  76. wiauDbgError("EventThread", "event callback failed");
  77. }
  78. }
  79. //
  80. // The thread will now exit normally
  81. //
  82. wiauDbgTrace("EventThread", "exiting");
  83. return 0;
  84. }
  85. //
  86. // Constructor for CPTPCamera
  87. //
  88. CPTPCamera::CPTPCamera()
  89. : m_hEventThread(NULL),
  90. m_SessionId(0),
  91. m_Phase(CAMERA_PHASE_NOTREADY),
  92. m_NextTransactionId(PTP_TRANSACTIONID_MIN),
  93. m_pTransferBuffer(NULL),
  94. m_pPTPEventCB(NULL),
  95. m_pPTPDataCB(NULL),
  96. m_pEventCallbackParam(NULL),
  97. m_pDataCallbackParam(NULL),
  98. m_bCameraWasReset(FALSE),
  99. m_HackModel(HACK_MODEL_NONE),
  100. m_HackVersion(0.0)
  101. {
  102. //PP_INIT_TRACING(L"Microsoft\\WIA\\PtpUsb");
  103. }
  104. //
  105. // Destructor for CPTPCamera
  106. //
  107. CPTPCamera::~CPTPCamera()
  108. {
  109. if (m_pTransferBuffer)
  110. {
  111. delete [] m_pTransferBuffer;
  112. m_pTransferBuffer = NULL;
  113. }
  114. //PP_CLEANUP();
  115. }
  116. //
  117. // This function is the first one called by the driver to open access to the camera. The
  118. // subclass Open should call this function first.
  119. //
  120. // Input:
  121. // DevicePortName -- name used by sub-class to access device
  122. // pPTPEventCB -- pointer to event callback function
  123. //
  124. HRESULT
  125. CPTPCamera::Open(
  126. LPWSTR DevicePortName,
  127. PTPEventCallback pPTPEventCB,
  128. PTPDataCallback pPTPDataCB,
  129. LPVOID pEventParam,
  130. BOOL bEnableEvents
  131. )
  132. {
  133. DBG_FN("CPTPCamera::Open");
  134. HRESULT hr = S_OK;
  135. if (!DevicePortName ||
  136. ((bEnableEvents == TRUE) && (!pPTPEventCB)))
  137. {
  138. wiauDbgError("Open", "invalid arg");
  139. return E_INVALIDARG;
  140. }
  141. m_bEventsEnabled = bEnableEvents;
  142. //
  143. // Allocate the re-usable transfer buffer
  144. //
  145. m_pTransferBuffer = new BYTE[TRANSFER_BUFFER_SIZE];
  146. if (!m_pTransferBuffer)
  147. {
  148. wiauDbgError("Open", "memory allocation failed");
  149. return E_OUTOFMEMORY;
  150. }
  151. //
  152. // Save the callback pointers and object
  153. //
  154. m_pPTPEventCB = pPTPEventCB;
  155. m_pPTPDataCB = pPTPDataCB;
  156. m_pEventCallbackParam = pEventParam;
  157. m_pDataCallbackParam = NULL;
  158. //
  159. // The camera isn't actually ready yet, but this is the best place to set the phase to idle
  160. //
  161. m_Phase = CAMERA_PHASE_IDLE;
  162. if (m_bEventsEnabled)
  163. {
  164. //
  165. // Create a thread to listen for events
  166. //
  167. DWORD ThreadId;
  168. m_hEventThread = CreateThread(NULL, // security descriptor
  169. 0, // stack size, use same size as this thread
  170. EventThread, // thread procedure
  171. this, // parameter to the thread
  172. CREATE_SUSPENDED, // creation flags
  173. &ThreadId // to receive thread id
  174. );
  175. if (!m_hEventThread)
  176. {
  177. hr = HRESULT_FROM_WIN32(::GetLastError());
  178. wiauDbgErrorHr(hr, "Open", "CreateThread failed");
  179. return hr;
  180. }
  181. }
  182. //
  183. // The subclass should now open the device with CreateFile or equivalent
  184. //
  185. return hr;
  186. }
  187. //
  188. // This function closes the connection to the camera.
  189. //
  190. HRESULT
  191. CPTPCamera::Close()
  192. {
  193. DBG_FN("CPTPCamera::Close");
  194. HRESULT hr = S_OK;
  195. if (IsCameraSessionOpen())
  196. {
  197. hr = CloseSession();
  198. if (FAILED(hr))
  199. {
  200. wiauDbgError("Close", "CloseSession failed");
  201. return hr;
  202. }
  203. }
  204. return hr;
  205. }
  206. //
  207. // This function is responsible for executing a PTP command, reading or
  208. // writing any necessary data, and reading the response
  209. //
  210. // Input/Output:
  211. // pData -- pointer to use for optional reading or writing of data
  212. //
  213. HRESULT
  214. CPTPCamera::ExecuteCommand(
  215. BYTE *pReadData,
  216. UINT *pReadDataSize,
  217. BYTE *pWriteData,
  218. UINT WriteDataSize,
  219. UINT NumCommandParams,
  220. CAMERA_PHASE NextPhase
  221. )
  222. {
  223. DBG_FN("CPTPCamera::ExecuteCommand");
  224. HRESULT hr = S_OK;
  225. BOOL bCommandCancelled = FALSE;
  226. //
  227. // If data is being tranferred, check the appropriate buffer pointer
  228. //
  229. if ((NextPhase == CAMERA_PHASE_DATAIN && (!pReadData || !pReadDataSize)) ||
  230. (NextPhase == CAMERA_PHASE_DATAOUT && !pWriteData))
  231. {
  232. wiauDbgError("ExecuteCommand", "invalid arg");
  233. return E_INVALIDARG;
  234. }
  235. //
  236. // Verify NumCommandParams is not too big
  237. //
  238. if (NumCommandParams > COMMAND_NUMPARAMS_MAX)
  239. {
  240. wiauDbgError("ExecuteCommand", "Too many command params");
  241. return E_INVALIDARG;
  242. }
  243. //
  244. // Verify that the camera is ready
  245. //
  246. if (m_Phase != CAMERA_PHASE_IDLE)
  247. {
  248. wiauDbgError("ExecuteCommand", "camera is not in idle phase, phase = %d", m_Phase);
  249. return E_FAIL;
  250. }
  251. //
  252. // Set the session and transaction IDs
  253. //
  254. if (IsCameraSessionOpen())
  255. {
  256. m_CommandBuffer.SessionId = m_SessionId;
  257. m_CommandBuffer.TransactionId = GetNextTransactionId();
  258. }
  259. else
  260. {
  261. if (m_CommandBuffer.OpCode == PTP_OPCODE_GETDEVICEINFO ||
  262. m_CommandBuffer.OpCode == PTP_OPCODE_OPENSESSION)
  263. {
  264. m_CommandBuffer.SessionId = PTP_SESSIONID_NOSESSION;
  265. m_CommandBuffer.TransactionId = PTP_TRANSACTIONID_NOSESSION;
  266. }
  267. else
  268. {
  269. wiauDbgError("ExecuteCommand", "session must first be opened");
  270. return E_FAIL;
  271. }
  272. }
  273. if (g_dwDebugFlags & WIAUDBG_DUMP)
  274. DumpCommand(&m_CommandBuffer, NumCommandParams);
  275. //
  276. // Send the command to the camera
  277. //
  278. m_Phase = CAMERA_PHASE_CMD;
  279. hr = SendCommand(&m_CommandBuffer, NumCommandParams);
  280. if (FAILED(hr))
  281. {
  282. wiauDbgError("ExecuteCommand", "SendCommand failed");
  283. m_Phase = CAMERA_PHASE_IDLE;
  284. RecoverFromError();
  285. return hr;
  286. }
  287. m_Phase = NextPhase;
  288. //
  289. // Get data, if necessary
  290. //
  291. if (m_Phase == CAMERA_PHASE_DATAIN)
  292. {
  293. hr = ReadData(pReadData, pReadDataSize);
  294. if (FAILED(hr))
  295. {
  296. m_Phase = CAMERA_PHASE_IDLE;
  297. wiauDbgError("ExecuteCommand", "ReadData failed");
  298. RecoverFromError();
  299. return hr;
  300. }
  301. if (hr == S_FALSE)
  302. {
  303. bCommandCancelled = TRUE;
  304. }
  305. else
  306. {
  307. //
  308. // If transfer was cancelled, ReadData has already set appropriate next phase
  309. // If not, set it to CAMERA_PHASE_RESPONSE now
  310. //
  311. m_Phase = CAMERA_PHASE_RESPONSE;
  312. }
  313. }
  314. else
  315. {
  316. // there is no data phase, tell caller there is no in data
  317. // (please, note that caller knows and will adjust for
  318. // obligatory response size) #337129
  319. if(pReadDataSize) *pReadDataSize = 0;
  320. }
  321. //
  322. // Send data, if necessary
  323. //
  324. if (m_Phase == CAMERA_PHASE_DATAOUT)
  325. {
  326. hr = SendData(pWriteData, WriteDataSize);
  327. if (FAILED(hr))
  328. {
  329. wiauDbgError("ExecuteCommand", "SendData failed");
  330. m_Phase = CAMERA_PHASE_IDLE;
  331. RecoverFromError();
  332. return hr;
  333. }
  334. if (hr == S_FALSE)
  335. {
  336. bCommandCancelled = TRUE;
  337. }
  338. else
  339. {
  340. //
  341. // If transfer was cancelled, SendData has already set appropriate next phase
  342. // If not, set it to CAMERA_PHASE_RESPONSE now
  343. //
  344. m_Phase = CAMERA_PHASE_RESPONSE;
  345. }
  346. }
  347. //
  348. // Read the response, if necessary
  349. //
  350. if (m_Phase == CAMERA_PHASE_RESPONSE)
  351. {
  352. memset(&m_ResponseBuffer, NULL, sizeof(m_ResponseBuffer));
  353. hr = ReadResponse(&m_ResponseBuffer);
  354. if (FAILED(hr))
  355. {
  356. wiauDbgError("ExecuteCommand", "ReadResponse failed");
  357. m_Phase = CAMERA_PHASE_IDLE;
  358. RecoverFromError();
  359. return hr;
  360. }
  361. if (g_dwDebugFlags & WIAUDBG_DUMP)
  362. DumpResponse(&m_ResponseBuffer);
  363. if (m_ResponseBuffer.ResponseCode != PTP_RESPONSECODE_OK &&
  364. m_ResponseBuffer.ResponseCode != PTP_RESPONSECODE_SESSIONALREADYOPENED)
  365. {
  366. wiauDbgError("ExecuteCommand", "bad response code = 0x%04x", m_ResponseBuffer.ResponseCode);
  367. //
  368. // Convert the PTP response code to an HRESULT;
  369. //
  370. hr = HRESULT_FROM_PTP(m_ResponseBuffer.ResponseCode);
  371. }
  372. m_Phase = CAMERA_PHASE_IDLE;
  373. }
  374. if (SUCCEEDED(hr) && bCommandCancelled)
  375. {
  376. hr = S_FALSE;
  377. }
  378. return hr;
  379. }
  380. //
  381. // All of the "command" functions below have the same basic structure:
  382. // 1. Check the arguments (if any) to make sure they are valid
  383. // 2. Set up the opcode and parameters (if any) in the command buffer
  384. // 3. Call ExecuteCommand
  385. // 4. Check the return code
  386. // 5. Parse the returned raw data (if any) into a PTP structure
  387. // 6. If debugging is turned on, dump the data
  388. // 7. Return
  389. //
  390. //
  391. // This function gets the device info structure from the camera
  392. //
  393. // Output:
  394. // pDeviceInfo -- to receive the structure
  395. //
  396. HRESULT
  397. CPTPCamera::GetDeviceInfo(
  398. CPtpDeviceInfo *pDeviceInfo
  399. )
  400. {
  401. DBG_FN("CPTPCamera::GetDeviceInfo");
  402. HRESULT hr = S_OK;
  403. if (!pDeviceInfo)
  404. {
  405. wiauDbgError("GetDeviceInfo", "invalid arg");
  406. return E_INVALIDARG;
  407. }
  408. m_CommandBuffer.OpCode = PTP_OPCODE_GETDEVICEINFO;
  409. UINT size = TRANSFER_BUFFER_SIZE;
  410. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 0, CAMERA_PHASE_DATAIN);
  411. if (FAILED(hr))
  412. {
  413. wiauDbgError("GetDeviceInfo", "ExecuteCommand failed");
  414. return hr;
  415. }
  416. hr = pDeviceInfo->Init(m_pTransferBuffer);
  417. if (FAILED(hr))
  418. {
  419. wiauDbgError("GetDeviceInfo", "couldn't parse DeviceInfo data");
  420. return hr;
  421. }
  422. if (g_dwDebugFlags & WIAUDBG_DUMP)
  423. pDeviceInfo->Dump();
  424. //
  425. // Set the model and version hack variables
  426. //
  427. SetupHackInfo(pDeviceInfo);
  428. return hr;
  429. }
  430. //
  431. // This function opens a session on the camera for the caller. It is a little different
  432. // than the other command functions. If it initially fails, it tries to recover and
  433. // execute the OpenSession command again. It also starts the event thread.
  434. //
  435. // Input:
  436. // SessionId -- the session ID to open
  437. //
  438. HRESULT
  439. CPTPCamera::OpenSession(
  440. DWORD SessionId
  441. )
  442. {
  443. DBG_FN("CPTPCamera::OpenSession");
  444. HRESULT hr = S_OK;
  445. if (!SessionId)
  446. {
  447. wiauDbgError("OpenSession", "invalid arg");
  448. return E_INVALIDARG;
  449. }
  450. if (IsCameraSessionOpen())
  451. {
  452. wiauDbgError("OpenSession", "tried to open a session when one is already open");
  453. return E_FAIL;
  454. }
  455. m_CommandBuffer.OpCode = PTP_OPCODE_OPENSESSION;
  456. m_CommandBuffer.Params[0] = SessionId;
  457. hr = ExecuteCommand(NULL, NULL, NULL, 0, 1, CAMERA_PHASE_RESPONSE);
  458. if (FAILED(hr))
  459. {
  460. wiauDbgError("OpenSession", "ExecuteCommand failed... attempting to recover and re-execute");
  461. hr = RecoverFromError();
  462. if (FAILED(hr))
  463. {
  464. wiauDbgError("OpenSession", "RecoverFromError failed");
  465. return hr;
  466. }
  467. //
  468. // Trying executing the command again
  469. //
  470. hr = ExecuteCommand(NULL, NULL, NULL, 0, 1, CAMERA_PHASE_RESPONSE);
  471. if (FAILED(hr))
  472. {
  473. wiauDbgError("OpenSession", "ExecuteCommand failed the second time");
  474. return hr;
  475. }
  476. }
  477. //
  478. // Set the session id
  479. //
  480. m_SessionId = SessionId;
  481. wiauDbgTrace("OpenSession", "session %d opened", m_SessionId);
  482. //
  483. // Resume the event thread that was created suspended
  484. //
  485. if (!m_hEventThread)
  486. {
  487. wiauDbgError("OpenSession", "event thread is null");
  488. return E_FAIL;
  489. }
  490. if (ResumeThread(m_hEventThread) > 1)
  491. {
  492. wiauDbgError("OpenSession", "ResumeThread failed");
  493. return E_FAIL;
  494. }
  495. return hr;
  496. }
  497. //
  498. // This function closes the session
  499. //
  500. HRESULT
  501. CPTPCamera::CloseSession()
  502. {
  503. DBG_FN("CPTPCamera::CloseSession");
  504. HRESULT hr = S_OK;
  505. m_CommandBuffer.OpCode = PTP_OPCODE_CLOSESESSION;
  506. hr = ExecuteCommand(NULL, NULL, NULL, 0, 0, CAMERA_PHASE_RESPONSE);
  507. if (FAILED(hr))
  508. {
  509. wiauDbgError("CloseSession", "ExecuteCommand failed");
  510. return hr;
  511. }
  512. wiauDbgTrace("CloseSession", "session closed");
  513. //
  514. // The session is closed, so reset the session and transaction ids
  515. //
  516. m_SessionId = PTP_SESSIONID_NOSESSION;
  517. m_NextTransactionId = PTP_TRANSACTIONID_MIN;
  518. m_Phase = CAMERA_PHASE_NOTREADY;
  519. return hr;
  520. }
  521. //
  522. // This function retrieves the list of all available storages on the device
  523. //
  524. // Output:
  525. // pStorageIdArray -- An empty array to receive the storage IDs
  526. //
  527. HRESULT
  528. CPTPCamera::GetStorageIDs(
  529. CArray32 *pStorageIdArray
  530. )
  531. {
  532. DBG_FN("CPTPCamera::GetStorageIDs");
  533. HRESULT hr = S_OK;
  534. if (!pStorageIdArray)
  535. {
  536. wiauDbgError("GetStorageIDs", "invalid arg");
  537. return E_INVALIDARG;
  538. }
  539. m_CommandBuffer.OpCode = PTP_OPCODE_GETSTORAGEIDS;
  540. UINT size = TRANSFER_BUFFER_SIZE;
  541. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 0, CAMERA_PHASE_DATAIN);
  542. if (FAILED(hr))
  543. {
  544. wiauDbgError("GetStorageIDs", "ExecuteCommand failed");
  545. return hr;
  546. }
  547. BYTE *pTemp = m_pTransferBuffer;
  548. if (!pStorageIdArray->Parse(&pTemp))
  549. {
  550. wiauDbgError("GetStorageIDs", "couldn't parse storage id array");
  551. return hr;
  552. }
  553. if (g_dwDebugFlags & WIAUDBG_DUMP)
  554. pStorageIdArray->Dump(" Storage ids =", " ");
  555. return hr;
  556. }
  557. //
  558. // This function gets the information about the given storage
  559. //
  560. // Input:
  561. // StorageId -- the storage ID to get info about
  562. // Output:
  563. // pStorageInfo -- the structure to receive the information
  564. //
  565. HRESULT
  566. CPTPCamera::GetStorageInfo(
  567. DWORD StorageId,
  568. CPtpStorageInfo *pStorageInfo
  569. )
  570. {
  571. DBG_FN("CPTPCamera::GetStorageInfo");
  572. HRESULT hr = S_OK;
  573. if (!StorageId ||
  574. !pStorageInfo)
  575. {
  576. wiauDbgError("GetStorageInfo", "invalid arg");
  577. return E_INVALIDARG;
  578. }
  579. m_CommandBuffer.OpCode = PTP_OPCODE_GETSTORAGEINFO;
  580. m_CommandBuffer.Params[0] = StorageId;
  581. UINT size = TRANSFER_BUFFER_SIZE;
  582. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  583. if (FAILED(hr))
  584. {
  585. wiauDbgError("GetStorageInfo", "ExecuteCommand failed");
  586. return hr;
  587. }
  588. hr = pStorageInfo->Init(m_pTransferBuffer, StorageId);
  589. if (FAILED(hr))
  590. {
  591. wiauDbgError("GetStorageInfo", "couldn't parse storage info");
  592. return hr;
  593. }
  594. if (g_dwDebugFlags & WIAUDBG_DUMP)
  595. pStorageInfo->Dump();
  596. return hr;
  597. }
  598. //
  599. // This function gets the number of objects on a storage, optionally in a specific
  600. // format or under a specific association object
  601. //
  602. // Input:
  603. // StorageId -- the designated storage, e.g. PTP_STORAGEID_ALL
  604. // FormatCode -- optional format type, e.g. PTP_FORMATCODE_ALL, PTP_FORMATCODE_IMAGE
  605. // ParentObjectHandle -- the object handle under which to count objects
  606. // Output:
  607. // pNumObjects -- to receive the number of the object.
  608. //
  609. HRESULT
  610. CPTPCamera::GetNumObjects(
  611. DWORD StorageId,
  612. WORD FormatCode,
  613. DWORD ParentObjectHandle,
  614. UINT *pNumObjects
  615. )
  616. {
  617. DBG_FN("CPTPCamera::GetNumObjects");
  618. HRESULT hr = S_OK;
  619. if (!StorageId ||
  620. !pNumObjects)
  621. {
  622. wiauDbgError("GetNumObjects", "invalid arg");
  623. return E_INVALIDARG;
  624. }
  625. m_CommandBuffer.OpCode = PTP_OPCODE_GETNUMOBJECTS;
  626. m_CommandBuffer.Params[0] = StorageId;
  627. m_CommandBuffer.Params[1] = FormatCode;
  628. m_CommandBuffer.Params[2] = ParentObjectHandle;
  629. hr = ExecuteCommand(NULL, NULL, NULL, 0, 3, CAMERA_PHASE_RESPONSE);
  630. if (FAILED(hr))
  631. {
  632. wiauDbgError("GetNumObjects", "ExecuteCommand failed");
  633. return hr;
  634. }
  635. *pNumObjects = m_ResponseBuffer.Params[0];
  636. wiauDbgTrace("GetNumObjects", "number of objects = %d", *pNumObjects);
  637. return hr;
  638. }
  639. //
  640. // This function gets the object handles under the given parent object
  641. //
  642. // Input:
  643. // StorageId -- the designated storage, e.g. PTP_STORAGEID_ALL
  644. // FormatCode -- specifies what format type, e.g. PTP_FORMATCODE_ALL, PTP_FORMATCODE_IMAGE
  645. // ParentObjectHandle -- the object handle under which to enumerate the objects
  646. // Output:
  647. // pObjectHandleArray -- the array to receive the object handles
  648. //
  649. HRESULT
  650. CPTPCamera::GetObjectHandles(
  651. DWORD StorageId,
  652. WORD FormatCode,
  653. DWORD ParentObjectHandle,
  654. CArray32 *pObjectHandleArray
  655. )
  656. {
  657. DBG_FN("CPTPCamera::GetObjectHandles");
  658. HRESULT hr = S_OK;
  659. if (!StorageId ||
  660. !pObjectHandleArray)
  661. {
  662. wiauDbgError("GetObjectHandles", "invalid arg");
  663. return E_INVALIDARG;
  664. }
  665. m_CommandBuffer.OpCode = PTP_OPCODE_GETOBJECTHANDLES;
  666. m_CommandBuffer.Params[0] = StorageId;
  667. m_CommandBuffer.Params[1] = FormatCode;
  668. m_CommandBuffer.Params[2] = ParentObjectHandle;
  669. UINT size = TRANSFER_BUFFER_SIZE;
  670. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 3, CAMERA_PHASE_DATAIN);
  671. if (FAILED(hr))
  672. {
  673. wiauDbgError("GetObjectHandles", "ExecuteCommand failed");
  674. return hr;
  675. }
  676. BYTE *pTemp = m_pTransferBuffer;
  677. if (!pObjectHandleArray->Parse(&pTemp))
  678. {
  679. wiauDbgError("GetStorageIDs", "couldn't parse object handle array");
  680. return hr;
  681. }
  682. if (g_dwDebugFlags & WIAUDBG_DUMP)
  683. pObjectHandleArray->Dump(" Object handles =", " ");
  684. return hr;
  685. }
  686. //
  687. // This function gets the object info structure
  688. //
  689. // Input:
  690. // ObjectHandle -- the object handle
  691. // Output:
  692. // pObjectInfo -- pointer to retreived object info
  693. //
  694. HRESULT
  695. CPTPCamera::GetObjectInfo(
  696. DWORD ObjectHandle,
  697. CPtpObjectInfo *pObjectInfo
  698. )
  699. {
  700. DBG_FN("CPTPCamera::GetObjectInfo");
  701. HRESULT hr = S_OK;
  702. if (!ObjectHandle ||
  703. !pObjectInfo)
  704. {
  705. wiauDbgError("GetObjectInfo", "invalid arg");
  706. return E_INVALIDARG;
  707. }
  708. m_CommandBuffer.OpCode = PTP_OPCODE_GETOBJECTINFO;
  709. m_CommandBuffer.Params[0] = ObjectHandle;
  710. UINT size = TRANSFER_BUFFER_SIZE;
  711. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  712. if (FAILED(hr))
  713. {
  714. wiauDbgError("GetObjectInfo", "ExecuteCommand failed");
  715. return hr;
  716. }
  717. hr = pObjectInfo->Init(m_pTransferBuffer, ObjectHandle);
  718. if (FAILED(hr))
  719. {
  720. wiauDbgError("GetObjectInfo", "couldn't parse object info");
  721. return hr;
  722. }
  723. if (g_dwDebugFlags & WIAUDBG_DUMP)
  724. pObjectInfo->Dump();
  725. return hr;
  726. }
  727. //
  728. // This function retrieves an object
  729. //
  730. // Input:
  731. // ObjectHandle -- the handle that represents the object
  732. // pBuffer -- the buffer to use for transfer
  733. // BufferLen -- the buffer size
  734. //
  735. HRESULT
  736. CPTPCamera::GetObjectData(
  737. DWORD ObjectHandle,
  738. BYTE *pBuffer,
  739. UINT *pBufferLen,
  740. LPVOID pCallbackParam
  741. )
  742. {
  743. DBG_FN("CPTPCamera::GetObjectData");
  744. HRESULT hr = S_OK;
  745. if (!pBuffer ||
  746. !pBufferLen ||
  747. *pBufferLen == 0)
  748. {
  749. wiauDbgError("GetObjectData", "invalid arg");
  750. return E_INVALIDARG;
  751. }
  752. m_CommandBuffer.OpCode = PTP_OPCODE_GETOBJECT;
  753. m_CommandBuffer.Params[0] = ObjectHandle;
  754. m_pDataCallbackParam = pCallbackParam;
  755. hr = ExecuteCommand(pBuffer, pBufferLen, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  756. if (FAILED(hr))
  757. {
  758. wiauDbgError("GetObjectData", "ExecuteCommand failed");
  759. //
  760. // go ahead to have m_pDataCallbackParam cleared
  761. //
  762. }
  763. m_pDataCallbackParam = NULL;
  764. return hr;
  765. }
  766. //
  767. // This function gets the thumbnail for an object
  768. //
  769. // Input:
  770. // ObjectHandle -- the handle that represents the object
  771. // pBuffer -- the buffer to use for transfer
  772. // BufferLen -- the buffer size
  773. //
  774. HRESULT
  775. CPTPCamera::GetThumb(
  776. DWORD ObjectHandle,
  777. BYTE *pBuffer,
  778. UINT *pBufferLen
  779. )
  780. {
  781. DBG_FN("CPTPCamera::GetThumb");
  782. HRESULT hr = S_OK;
  783. if (!pBuffer ||
  784. !pBufferLen ||
  785. *pBufferLen == 0)
  786. {
  787. wiauDbgError("GetThumb", "invalid arg");
  788. return E_INVALIDARG;
  789. }
  790. m_CommandBuffer.OpCode = PTP_OPCODE_GETTHUMB;
  791. m_CommandBuffer.Params[0] = ObjectHandle;
  792. hr = ExecuteCommand(pBuffer, pBufferLen, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  793. if (FAILED(hr))
  794. {
  795. wiauDbgError("GetThumb", "ExecuteCommand failed");
  796. return hr;
  797. }
  798. return hr;
  799. }
  800. //
  801. // This function deletes the given object and its children
  802. //
  803. // Input:
  804. // ObjectHandle -- object handle that represents the object to be deleted, e.g. PTP_OBJECTHANDLE_ALL
  805. // FormatCode -- Limits the scope of the deletion if objects of FormatCode type, e.g. PTP_FORMATCODE_NOTUSED, PTP_FORMATCODE_ALLIMAGES
  806. //
  807. HRESULT
  808. CPTPCamera::DeleteObject(
  809. DWORD ObjectHandle,
  810. WORD FormatCode
  811. )
  812. {
  813. DBG_FN("CPTPCamera::DeleteObject");
  814. HRESULT hr = S_OK;
  815. m_CommandBuffer.OpCode = PTP_OPCODE_DELETEOBJECT;
  816. m_CommandBuffer.Params[0] = ObjectHandle;
  817. m_CommandBuffer.Params[1] = FormatCode;
  818. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  819. if (FAILED(hr))
  820. {
  821. wiauDbgError("DeleteObject", "ExecuteCommand failed");
  822. return hr;
  823. }
  824. return hr;
  825. }
  826. //
  827. // This function sends an ObjectInfo structure to the device in preparation for sending an object
  828. //
  829. // Input:
  830. // StorageId -- storage id for the new object, e.g. PTP_STORAGEID_UNDEFINED
  831. // ParentObjectHandle -- parent to use for the new object, e.g. PTP_OBJECTHANDLE_UNDEFINED, PTP_OBJECTHANDLE_ROOT
  832. // pDeviceInfo -- pointer to DeviceInfo structure
  833. // Output:
  834. // pResultStorageId -- location to store storage id where object will be stored
  835. // pResultParentObjectHandle -- parent object under which object will be stored
  836. // pResultObjectHandle -- location to store handle for the new object
  837. //
  838. HRESULT
  839. CPTPCamera::SendObjectInfo(
  840. DWORD StorageId,
  841. DWORD ParentObjectHandle,
  842. CPtpObjectInfo *pObjectInfo,
  843. DWORD *pResultStorageId,
  844. DWORD *pResultParentObjectHandle,
  845. DWORD *pResultObjectHandle
  846. )
  847. {
  848. DBG_FN("CPTPCamera::SendObjectInfo");
  849. HRESULT hr = S_OK;
  850. if (!pObjectInfo ||
  851. !pResultStorageId ||
  852. !pResultParentObjectHandle ||
  853. !pResultObjectHandle)
  854. {
  855. wiauDbgError("SendObjectInfo", "invalid arg");
  856. return E_INVALIDARG;
  857. }
  858. m_CommandBuffer.OpCode = PTP_OPCODE_SENDOBJECTINFO;
  859. m_CommandBuffer.Params[0] = StorageId;
  860. m_CommandBuffer.Params[1] = ParentObjectHandle;
  861. BYTE *pRaw = m_pTransferBuffer;
  862. pObjectInfo->WriteToBuffer(&pRaw);
  863. UINT size = (UINT) (pRaw - m_pTransferBuffer);
  864. hr = ExecuteCommand(NULL, NULL, m_pTransferBuffer, size, 2, CAMERA_PHASE_DATAOUT);
  865. if (FAILED(hr))
  866. {
  867. wiauDbgError("SendObjectInfo", "ExecuteCommand failed");
  868. return hr;
  869. }
  870. *pResultStorageId = m_ResponseBuffer.Params[0];
  871. *pResultParentObjectHandle = m_ResponseBuffer.Params[1];
  872. *pResultObjectHandle = m_ResponseBuffer.Params[2];
  873. wiauDbgTrace("SendObjectInfo", "ObjectInfo added, storage = 0x%08x, parent = 0x%08x, handle = 0x%08x",
  874. *pResultStorageId, *pResultParentObjectHandle, *pResultObjectHandle);
  875. return hr;
  876. }
  877. //
  878. // This function sends data for a new object
  879. //
  880. // Input:
  881. // pBuffer -- pointer to raw data
  882. // BufferLen -- length of the buffer
  883. //
  884. HRESULT
  885. CPTPCamera::SendObjectData(
  886. BYTE *pBuffer,
  887. UINT BufferLen
  888. )
  889. {
  890. DBG_FN("CPTPCamera::SendObjectData");
  891. HRESULT hr = S_OK;
  892. if (!pBuffer)
  893. {
  894. wiauDbgError("SendObjectData", "invalid arg");
  895. return E_INVALIDARG;
  896. }
  897. m_CommandBuffer.OpCode = PTP_OPCODE_SENDOBJECT;
  898. hr = ExecuteCommand(NULL, NULL, pBuffer, BufferLen, 0, CAMERA_PHASE_DATAOUT);
  899. if (FAILED(hr))
  900. {
  901. wiauDbgError("SendObjectData", "ExecuteCommand failed");
  902. return hr;
  903. }
  904. return hr;
  905. }
  906. //
  907. // This function asks the device to initiate a capture. The newly added object
  908. // will be reported via an ObjectAdded event, or StoreFull event if the store is full.
  909. //
  910. // Input:
  911. // StorageId -- where to save the capture object, e.g. PTP_STORAGEID_DEFAULT
  912. // FormatCode -- indicates what kind of object to capture, e.g. PTP_FORMATCODE_DEFAULT
  913. //
  914. HRESULT
  915. CPTPCamera::InitiateCapture(
  916. DWORD StorageId,
  917. WORD FormatCode
  918. )
  919. {
  920. DBG_FN("CPTPCamera::InitiateCapture");
  921. HRESULT hr = S_OK;
  922. m_CommandBuffer.OpCode = PTP_OPCODE_INITIATECAPTURE;
  923. m_CommandBuffer.Params[0] = StorageId;
  924. m_CommandBuffer.Params[1] = FormatCode;
  925. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  926. if (FAILED(hr))
  927. {
  928. wiauDbgError("InitiateCapture", "ExecuteCommand failed");
  929. return hr;
  930. }
  931. return hr;
  932. }
  933. //
  934. // This function formats a store on the device
  935. //
  936. // Input:
  937. // StorageId -- storage to format
  938. // FilesystemFormat -- optional format to use
  939. //
  940. HRESULT
  941. CPTPCamera::FormatStore(
  942. DWORD StorageId,
  943. WORD FilesystemFormat
  944. )
  945. {
  946. DBG_FN("CPTPCamera::FormatStore");
  947. HRESULT hr = S_OK;
  948. m_CommandBuffer.OpCode = PTP_OPCODE_FORMATSTORE;
  949. m_CommandBuffer.Params[0] = StorageId;
  950. m_CommandBuffer.Params[1] = FilesystemFormat;
  951. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  952. if (FAILED(hr))
  953. {
  954. wiauDbgError("FormatStore", "ExecuteCommand failed");
  955. return hr;
  956. }
  957. return hr;
  958. }
  959. //
  960. // This function resets the camera. A DeviceReset event will be sent and all open
  961. // sessions will be closed.
  962. //
  963. HRESULT
  964. CPTPCamera::ResetDevice()
  965. {
  966. DBG_FN("CPTPCamera::ResetDevice");
  967. HRESULT hr = S_OK;
  968. hr = SendResetDevice();
  969. if (FAILED(hr))
  970. {
  971. wiauDbgError("ResetDevice", "SendResetDevice failed");
  972. return hr;
  973. }
  974. wiauDbgTrace("ResetDevice", "device reset successfully");
  975. return hr;
  976. }
  977. //
  978. // This function tests the camera
  979. //
  980. HRESULT
  981. CPTPCamera::SelfTest(WORD SelfTestType)
  982. {
  983. DBG_FN("CPTPCamera::SelfTest");
  984. HRESULT hr = S_OK;
  985. m_CommandBuffer.OpCode = PTP_OPCODE_SELFTEST;
  986. m_CommandBuffer.Params[0] = SelfTestType;
  987. hr = ExecuteCommand(NULL, NULL, NULL, 0, 0, CAMERA_PHASE_RESPONSE);
  988. if (FAILED(hr))
  989. {
  990. wiauDbgError("SelfTest", "ExecuteCommand failed");
  991. return hr;
  992. }
  993. return hr;
  994. }
  995. //
  996. // This function sets the protection status of an object
  997. //
  998. // Input:
  999. // ObjectHandle -- handle of the object
  1000. // ProtectionStatus -- protection status
  1001. //
  1002. HRESULT
  1003. CPTPCamera::SetObjectProtection(
  1004. DWORD ObjectHandle,
  1005. WORD ProtectionStatus
  1006. )
  1007. {
  1008. DBG_FN("CPTPCamera::SetObjectProtection");
  1009. HRESULT hr = S_OK;
  1010. m_CommandBuffer.OpCode = PTP_OPCODE_SETOBJECTPROTECTION;
  1011. m_CommandBuffer.Params[0] = ObjectHandle;
  1012. m_CommandBuffer.Params[1] = ProtectionStatus;
  1013. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  1014. if (FAILED(hr))
  1015. {
  1016. wiauDbgError("SetObjectProtection", "ExecuteCommand failed");
  1017. return hr;
  1018. }
  1019. return hr;
  1020. }
  1021. //
  1022. // This function will cause the device to turn off
  1023. //
  1024. HRESULT
  1025. CPTPCamera::PowerDown()
  1026. {
  1027. DBG_FN("CPTPCamera::PowerDown");
  1028. HRESULT hr = S_OK;
  1029. m_CommandBuffer.OpCode = PTP_OPCODE_POWERDOWN;
  1030. hr = ExecuteCommand(NULL, NULL, NULL, 0, 0, CAMERA_PHASE_RESPONSE);
  1031. if (FAILED(hr))
  1032. {
  1033. wiauDbgError("PowerDown", "ExecuteCommand failed");
  1034. return hr;
  1035. }
  1036. return hr;
  1037. }
  1038. //
  1039. // This function retrieves a property description structure from the camera, allocating
  1040. // the appropriate CPtpPropDesc structure.
  1041. //
  1042. // Input:
  1043. // PropCode -- property code to retrieve
  1044. // pPropDesc -- pointer property description object
  1045. //
  1046. HRESULT
  1047. CPTPCamera::GetDevicePropDesc(
  1048. WORD PropCode,
  1049. CPtpPropDesc *pPropDesc
  1050. )
  1051. {
  1052. DBG_FN("CPtpCamera::GetDevicePropDesc");
  1053. HRESULT hr = S_OK;
  1054. if (!PropCode ||
  1055. !pPropDesc)
  1056. {
  1057. wiauDbgError("GetDevicePropDesc", "invalid arg");
  1058. return E_INVALIDARG;
  1059. }
  1060. m_CommandBuffer.OpCode = PTP_OPCODE_GETDEVICEPROPDESC;
  1061. m_CommandBuffer.Params[0] = PropCode;
  1062. UINT size = TRANSFER_BUFFER_SIZE;
  1063. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  1064. if (FAILED(hr))
  1065. {
  1066. wiauDbgError("GetDevicePropDesc", "ExecuteCommand failed");
  1067. return hr;
  1068. }
  1069. hr = pPropDesc->Init(m_pTransferBuffer);
  1070. if (FAILED(hr))
  1071. {
  1072. wiauDbgError("GetDevicePropDesc", "couldn't parse property description");
  1073. return hr;
  1074. }
  1075. if (g_dwDebugFlags & WIAUDBG_DUMP)
  1076. pPropDesc->Dump();
  1077. return hr;
  1078. }
  1079. //
  1080. // This function retrieves the current setting for a property.
  1081. //
  1082. // Input:
  1083. // PropCode -- property code to get value for
  1084. // pPropDesc -- pointer to property description object
  1085. //
  1086. HRESULT
  1087. CPTPCamera::GetDevicePropValue(
  1088. WORD PropCode,
  1089. CPtpPropDesc *pPropDesc
  1090. )
  1091. {
  1092. DBG_FN("CPtpCamera::GetDevicePropValue");
  1093. HRESULT hr = S_OK;
  1094. if (!PropCode ||
  1095. !pPropDesc)
  1096. {
  1097. wiauDbgError("GetDevicePropValue", "invalid arg");
  1098. return E_INVALIDARG;
  1099. }
  1100. m_CommandBuffer.OpCode = PTP_OPCODE_GETDEVICEPROPVALUE;
  1101. m_CommandBuffer.Params[0] = PropCode;
  1102. UINT size = TRANSFER_BUFFER_SIZE;
  1103. hr = ExecuteCommand(m_pTransferBuffer, &size, NULL, 0, 1, CAMERA_PHASE_DATAIN);
  1104. if (FAILED(hr))
  1105. {
  1106. wiauDbgError("GetDevicePropValue", "ExecuteCommand failed");
  1107. return hr;
  1108. }
  1109. hr = pPropDesc->ParseValue(m_pTransferBuffer);
  1110. if (FAILED(hr))
  1111. {
  1112. wiauDbgError("GetDevicePropValue", "couldn't parse property value");
  1113. return hr;
  1114. }
  1115. if (g_dwDebugFlags & WIAUDBG_DUMP)
  1116. pPropDesc->DumpValue();
  1117. return hr;
  1118. }
  1119. //
  1120. // This function sends a new setting for a property to the device
  1121. //
  1122. // Input:
  1123. // PropCode -- property code to set
  1124. // pPropDesc -- pointer to property description object
  1125. //
  1126. HRESULT
  1127. CPTPCamera::SetDevicePropValue(
  1128. WORD PropCode,
  1129. CPtpPropDesc *pPropDesc
  1130. )
  1131. {
  1132. DBG_FN("CPtpCamera::SetDevicePropValue");
  1133. HRESULT hr = S_OK;
  1134. if (!PropCode ||
  1135. !pPropDesc)
  1136. {
  1137. wiauDbgError("SetDevicePropValue", "invalid arg");
  1138. return E_INVALIDARG;
  1139. }
  1140. if (g_dwDebugFlags & WIAUDBG_DUMP)
  1141. pPropDesc->DumpValue();
  1142. m_CommandBuffer.OpCode = PTP_OPCODE_SETDEVICEPROPVALUE;
  1143. m_CommandBuffer.Params[0] = PropCode;
  1144. BYTE *pRaw = m_pTransferBuffer;
  1145. pPropDesc->WriteValue(&pRaw);
  1146. UINT size = (UINT) (pRaw - m_pTransferBuffer);
  1147. hr = ExecuteCommand(NULL, NULL, m_pTransferBuffer, size, 1, CAMERA_PHASE_DATAOUT);
  1148. if (FAILED(hr))
  1149. {
  1150. wiauDbgError("SetDevicePropValue", "ExecuteCommand failed");
  1151. return hr;
  1152. }
  1153. return hr;
  1154. }
  1155. //
  1156. // This function resets the of a property
  1157. //
  1158. // Input:
  1159. // PropCode -- property code to set
  1160. //
  1161. HRESULT
  1162. CPTPCamera::ResetDevicePropValue(
  1163. WORD PropCode
  1164. )
  1165. {
  1166. DBG_FN("CPtpCamera::ResetDevicePropValue");
  1167. HRESULT hr = S_OK;
  1168. if (!PropCode)
  1169. {
  1170. wiauDbgError("ResetDevicePropValue", "invalid arg");
  1171. return E_INVALIDARG;
  1172. }
  1173. m_CommandBuffer.OpCode = PTP_OPCODE_RESETDEVICEPROPVALUE;
  1174. m_CommandBuffer.Params[0] = PropCode;
  1175. hr = ExecuteCommand(NULL, NULL, NULL, 0, 1, CAMERA_PHASE_RESPONSE);
  1176. if (FAILED(hr))
  1177. {
  1178. wiauDbgError("ResetDevicePropValue", "ExecuteCommand failed");
  1179. return hr;
  1180. }
  1181. //
  1182. // WIAFIX-10/2/2000-davepar This function should reset the current value being held by the minidriver
  1183. //
  1184. return hr;
  1185. }
  1186. //
  1187. // This function terminates an open capture
  1188. //
  1189. // Input:
  1190. // TransactionId -- transaction id of InitiateOpenCapture command
  1191. //
  1192. HRESULT
  1193. CPTPCamera::TerminateCapture(
  1194. DWORD TransactionId
  1195. )
  1196. {
  1197. DBG_FN("CPtpCamera::TerminateCapture");
  1198. HRESULT hr = S_OK;
  1199. if (!TransactionId)
  1200. {
  1201. wiauDbgError("TerminateCapture", "invalid arg");
  1202. return E_INVALIDARG;
  1203. }
  1204. m_CommandBuffer.OpCode = PTP_OPCODE_TERMINATECAPTURE;
  1205. m_CommandBuffer.Params[0] = TransactionId;
  1206. hr = ExecuteCommand(NULL, NULL, NULL, 0, 1, CAMERA_PHASE_RESPONSE);
  1207. if (FAILED(hr))
  1208. {
  1209. wiauDbgError("TerminateCapture", "ExecuteCommand failed");
  1210. return hr;
  1211. }
  1212. return hr;
  1213. }
  1214. //
  1215. // This function moves an object on the device
  1216. //
  1217. // Input:
  1218. // ObjectHandle -- handle of object to move
  1219. // StorageId -- storage id of new location for object
  1220. // ParentObjectHandle -- handle of new parent for object
  1221. //
  1222. HRESULT
  1223. CPTPCamera::MoveObject(
  1224. DWORD ObjectHandle,
  1225. DWORD StorageId,
  1226. DWORD ParentObjectHandle
  1227. )
  1228. {
  1229. DBG_FN("CPtpCamera::MoveObject");
  1230. HRESULT hr = S_OK;
  1231. if (!ObjectHandle)
  1232. {
  1233. wiauDbgError("MoveObject", "invalid arg");
  1234. return E_INVALIDARG;
  1235. }
  1236. m_CommandBuffer.OpCode = PTP_OPCODE_MOVEOBJECT;
  1237. m_CommandBuffer.Params[0] = ObjectHandle;
  1238. m_CommandBuffer.Params[1] = StorageId;
  1239. m_CommandBuffer.Params[2] = ParentObjectHandle;
  1240. hr = ExecuteCommand(NULL, NULL, NULL, 0, 3, CAMERA_PHASE_RESPONSE);
  1241. if (FAILED(hr))
  1242. {
  1243. wiauDbgError("MoveObject", "ExecuteCommand failed");
  1244. return hr;
  1245. }
  1246. return hr;
  1247. }
  1248. //
  1249. // This function copies an object to a new location on the device
  1250. //
  1251. // Input:
  1252. // ObjectHandle -- handle of object to copy
  1253. // StorageId -- storage id for new object
  1254. // ParentObjectHandle -- handle of parent for new object
  1255. // pResultObjectHandle -- pointer to location to receive new object's handle
  1256. //
  1257. HRESULT
  1258. CPTPCamera::CopyObject(
  1259. DWORD ObjectHandle,
  1260. DWORD StorageId,
  1261. DWORD ParentObjectHandle,
  1262. DWORD *pResultObjectHandle
  1263. )
  1264. {
  1265. DBG_FN("CPtpCamera::CopyObject");
  1266. HRESULT hr = S_OK;
  1267. if (!ObjectHandle ||
  1268. !pResultObjectHandle)
  1269. {
  1270. wiauDbgError("CopyObject", "invalid arg");
  1271. return E_INVALIDARG;
  1272. }
  1273. m_CommandBuffer.OpCode = PTP_OPCODE_COPYOBJECT;
  1274. m_CommandBuffer.Params[0] = ObjectHandle;
  1275. m_CommandBuffer.Params[1] = StorageId;
  1276. m_CommandBuffer.Params[2] = ParentObjectHandle;
  1277. hr = ExecuteCommand(NULL, NULL, NULL, 0, 3, CAMERA_PHASE_RESPONSE);
  1278. if (FAILED(hr))
  1279. {
  1280. wiauDbgError("CopyObject", "ExecuteCommand failed");
  1281. return hr;
  1282. }
  1283. *pResultObjectHandle = m_ResponseBuffer.Params[0];
  1284. wiauDbgTrace("CopyObject", "Object 0x%08x copied to 0x%08x", ObjectHandle, *pResultObjectHandle);
  1285. return hr;
  1286. }
  1287. //
  1288. // This function retrieves a portion of an object
  1289. //
  1290. // Input:
  1291. // ObjectHandle -- the handle that represents the object
  1292. // pBuffer -- the buffer to use for transfer
  1293. // BufferLen -- the buffer size
  1294. //
  1295. HRESULT
  1296. CPTPCamera::GetPartialObject(
  1297. DWORD ObjectHandle,
  1298. UINT Offset,
  1299. UINT *pLength,
  1300. BYTE *pBuffer,
  1301. UINT *pResultLength,
  1302. LPVOID pCallbackParam
  1303. )
  1304. {
  1305. DBG_FN("CPTPCamera::GetPartialObject");
  1306. HRESULT hr = S_OK;
  1307. if (!pBuffer ||
  1308. !pLength ||
  1309. *pLength == 0 ||
  1310. !pResultLength)
  1311. {
  1312. wiauDbgError("GetPartialObject", "invalid arg");
  1313. return E_INVALIDARG;
  1314. }
  1315. m_CommandBuffer.OpCode = PTP_OPCODE_GETPARTIALOBJECT;
  1316. m_CommandBuffer.Params[0] = ObjectHandle;
  1317. m_CommandBuffer.Params[1] = Offset;
  1318. m_CommandBuffer.Params[2] = *pLength;
  1319. m_pDataCallbackParam = pCallbackParam;
  1320. hr = ExecuteCommand(pBuffer, pLength, NULL, 0, 3, CAMERA_PHASE_DATAIN);
  1321. if (FAILED(hr))
  1322. {
  1323. wiauDbgError("GetPartialObject", "ExecuteCommand failed");
  1324. m_pDataCallbackParam = NULL;
  1325. return hr;
  1326. }
  1327. m_pDataCallbackParam = NULL;
  1328. *pResultLength = m_ResponseBuffer.Params[0];
  1329. return hr;
  1330. }
  1331. //
  1332. // This function initiates an open capture
  1333. //
  1334. // Input:
  1335. // StorageId -- storage to use for new object(s)
  1336. // FormatCode -- format for new object(s)
  1337. //
  1338. HRESULT
  1339. CPTPCamera::InitiateOpenCapture(
  1340. DWORD StorageId,
  1341. WORD FormatCode
  1342. )
  1343. {
  1344. DBG_FN("CPtpCamera::InitiateOpenCapture");
  1345. HRESULT hr = S_OK;
  1346. m_CommandBuffer.OpCode = PTP_OPCODE_INITIATEOPENCAPTURE;
  1347. m_CommandBuffer.Params[0] = StorageId;
  1348. m_CommandBuffer.Params[1] = FormatCode;
  1349. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  1350. if (FAILED(hr))
  1351. {
  1352. wiauDbgError("InitiateOpenCapture", "ExecuteCommand failed");
  1353. hr = RecoverFromError();
  1354. if(FAILED(hr))
  1355. {
  1356. wiauDbgError("InitiateOpenCapture", "RecoverFromError failed");
  1357. return hr;
  1358. }
  1359. hr = ExecuteCommand(NULL, NULL, NULL, 0, 2, CAMERA_PHASE_RESPONSE);
  1360. if (FAILED(hr))
  1361. {
  1362. wiauDbgError("InitiateOpenCapture", "ExecuteCommand failed 2nd time");
  1363. return hr;
  1364. }
  1365. }
  1366. return hr;
  1367. }
  1368. //
  1369. // This function executes a vendor command
  1370. //
  1371. HRESULT
  1372. CPTPCamera::VendorCommand(
  1373. PTP_COMMAND *pCommand,
  1374. PTP_RESPONSE *pResponse,
  1375. UINT *pReadDataSize,
  1376. BYTE *pReadData,
  1377. UINT WriteDataSize,
  1378. BYTE *pWriteData,
  1379. UINT NumCommandParams,
  1380. int NextPhase
  1381. )
  1382. {
  1383. DBG_FN("CPTPCamera::VendorCommand");
  1384. HRESULT hr = S_OK;
  1385. memcpy(&m_CommandBuffer, pCommand, sizeof(m_CommandBuffer));
  1386. hr = ExecuteCommand(pReadData, pReadDataSize, pWriteData, WriteDataSize,
  1387. NumCommandParams, (CAMERA_PHASE) NextPhase);
  1388. if (FAILED(hr))
  1389. {
  1390. wiauDbgError("VendorCommand", "ExecuteCommand failed");
  1391. return hr;
  1392. }
  1393. memcpy(pResponse, &m_ResponseBuffer, sizeof(m_ResponseBuffer));
  1394. return hr;
  1395. }
  1396. //
  1397. // This function increments the transaction ID, rolling over if necessary
  1398. //
  1399. // Output:
  1400. // next transaction ID
  1401. //
  1402. DWORD
  1403. CPTPCamera::GetNextTransactionId()
  1404. {
  1405. // Valid transaction IDs range from PTP_TRANSACTIONID_MIN to
  1406. // PTP_TRANSACTIONID_MAX, inclusive.
  1407. //
  1408. if (PTP_TRANSACTIONID_MAX == m_NextTransactionId)
  1409. {
  1410. m_NextTransactionId = PTP_TRANSACTIONID_MIN;
  1411. return PTP_TRANSACTIONID_MAX;
  1412. }
  1413. else
  1414. {
  1415. return m_NextTransactionId++;
  1416. }
  1417. }
  1418. //
  1419. // Set m_HackModel and m_HackVersion according to device info
  1420. //
  1421. HRESULT CPTPCamera::SetupHackInfo(CPtpDeviceInfo *pDeviceInfo)
  1422. {
  1423. DBG_FN("CWiaMiniDriver::SetupHackInfo");
  1424. if (pDeviceInfo == NULL)
  1425. {
  1426. wiauDbgError("SetupHackInfo", "Invalid device info");
  1427. return E_INVALIDARG;
  1428. }
  1429. HRESULT hr = S_OK;
  1430. m_HackModel = HACK_MODEL_NONE;
  1431. m_HackVersion = 0.0;
  1432. //
  1433. // Kodak DC4800
  1434. //
  1435. if (wcscmp(pDeviceInfo->m_cbstrModel.String(), L"DC4800 Zoom Digital Camera") == 0)
  1436. {
  1437. m_HackModel = HACK_MODEL_DC4800;
  1438. wiauDbgTrace("SetupHackInfo", "Detected Kodak DC4800 camera");
  1439. }
  1440. //
  1441. // Any Sony camera
  1442. //
  1443. else if (wcsstr(pDeviceInfo->m_cbstrModel.String(), L"Sony") != NULL)
  1444. {
  1445. //
  1446. // Sony cameras report version as "01.0004"
  1447. //
  1448. WCHAR *pszStopChar = NULL;
  1449. double dbVersion = wcstod(pDeviceInfo->m_cbstrDeviceVersion.String(), &pszStopChar);
  1450. if (dbVersion != 0.0)
  1451. {
  1452. m_HackModel = HACK_MODEL_SONY;
  1453. m_HackVersion = dbVersion;
  1454. wiauDbgTrace("SetupHackInfo", "Detected Sony camera, version = %f", m_HackVersion);
  1455. }
  1456. }
  1457. //
  1458. // Nikon E2500
  1459. //
  1460. else if (wcsstr(pDeviceInfo->m_cbstrManufacturer.String(), L"Nikon") != NULL &&
  1461. wcscmp(pDeviceInfo->m_cbstrModel.String(), L"E2500") == 0)
  1462. {
  1463. //
  1464. // Nikon E2500 reports version as "E2500v1.0"
  1465. //
  1466. WCHAR *pch = wcsrchr(pDeviceInfo->m_cbstrDeviceVersion.String(), L'v');
  1467. if (pch != NULL)
  1468. {
  1469. WCHAR *pszStopChar = NULL;
  1470. double dbVersion = wcstod(pch + 1, &pszStopChar);
  1471. if (dbVersion != 0)
  1472. {
  1473. m_HackModel = HACK_MODEL_NIKON_E2500;
  1474. m_HackVersion = dbVersion;
  1475. wiauDbgTrace("SetupHackInfo", "Detected Nikon E2500 camera, version = %f", m_HackVersion);
  1476. }
  1477. }
  1478. }
  1479. else
  1480. {
  1481. wiauDbgTrace("SetupHackInfo", "Not detected any hack model");
  1482. }
  1483. return hr;
  1484. }