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.

1424 lines
33 KiB

  1. /*++
  2. Copyright (C) 2000 Microsoft Corporation
  3. Module Name:
  4. iso15740.cpp
  5. Abstract:
  6. This module implements methods used for manipulating PTP structures
  7. Author:
  8. Dave Parsons
  9. Revision History:
  10. --*/
  11. #include "ptppch.h"
  12. #include <platform.h> // for MAKELONGLONG
  13. //
  14. // This function returns a 2 byte integer from raw data and advances the pointer
  15. //
  16. // Input:
  17. // ppRaw -- pointer to a pointer to the raw data
  18. //
  19. WORD
  20. ParseWord(BYTE **ppRaw)
  21. {
  22. WORD w;
  23. // we know that **ppRaw points to a little-endian word
  24. w = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
  25. *ppRaw += sizeof(WORD);
  26. return w;
  27. }
  28. //
  29. // This function returns a 4 byte integer from raw data and advances the pointer
  30. //
  31. // Input:
  32. // ppRaw -- pointer to a pointer to the raw data
  33. //
  34. DWORD
  35. ParseDword(BYTE **ppRaw)
  36. {
  37. DWORD dw;
  38. // we know that **ppRaw points to a little-endian dword
  39. dw = MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
  40. MAKEWORD((*ppRaw)[2],(*ppRaw)[3]));
  41. *ppRaw += sizeof(DWORD);
  42. return dw;
  43. }
  44. //
  45. // This function returns an 8 byte integer from raw data and advances the pointer
  46. //
  47. // Input:
  48. // ppRaw -- pointer to a pointer to the raw data
  49. //
  50. QWORD
  51. ParseQword(BYTE **ppRaw)
  52. {
  53. QWORD qw;
  54. // we know that **ppRaw points to a little-endian qword
  55. qw = MAKELONGLONG(MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
  56. MAKEWORD((*ppRaw)[2],(*ppRaw)[3])),
  57. MAKELONG(MAKEWORD((*ppRaw)[4],(*ppRaw)[5]),
  58. MAKEWORD((*ppRaw)[6],(*ppRaw)[7])));
  59. *ppRaw += sizeof(QWORD);
  60. return qw;
  61. }
  62. //
  63. // This function writes a 2 byte integer to a raw data buffer and advances the pointer
  64. //
  65. // Input:
  66. // ppRaw -- pointer to pointer to the raw data
  67. // value -- value to write
  68. //
  69. VOID
  70. WriteWord(BYTE **ppRaw, WORD value)
  71. {
  72. (*ppRaw)[0] = LOBYTE(LOWORD(value));
  73. (*ppRaw)[1] = HIBYTE(LOWORD(value));
  74. *ppRaw += sizeof(WORD);
  75. return;
  76. }
  77. //
  78. // This function writes a 4 byte integer to a raw data buffer and advances the pointer
  79. //
  80. // Input:
  81. // ppRaw -- pointer to pointer to the raw data
  82. // value -- value to write
  83. //
  84. VOID
  85. WriteDword(BYTE **ppRaw, DWORD value)
  86. {
  87. (*ppRaw)[0] = LOBYTE(LOWORD(value));
  88. (*ppRaw)[1] = HIBYTE(LOWORD(value));
  89. (*ppRaw)[2] = LOBYTE(HIWORD(value));
  90. (*ppRaw)[3] = HIBYTE(HIWORD(value));
  91. *ppRaw += sizeof(DWORD);
  92. return;
  93. }
  94. //
  95. // CBstr constructor
  96. //
  97. CBstr::CBstr() :
  98. m_bstrString(NULL)
  99. {
  100. }
  101. //
  102. // CBstr copy constructor
  103. //
  104. CBstr::CBstr(const CBstr &src)
  105. {
  106. m_bstrString = SysAllocString(src.m_bstrString);
  107. }
  108. //
  109. // CBstr destructor
  110. //
  111. CBstr::~CBstr()
  112. {
  113. if (m_bstrString)
  114. SysFreeString(m_bstrString);
  115. }
  116. //
  117. // Make a copy of a string
  118. //
  119. HRESULT
  120. CBstr::Copy(WCHAR *wcsString)
  121. {
  122. HRESULT hr = S_OK;
  123. if (m_bstrString)
  124. {
  125. if (!SysReAllocString(&m_bstrString, wcsString))
  126. {
  127. wiauDbgError("Copy", "memory allocation failed");
  128. return E_OUTOFMEMORY;
  129. }
  130. }
  131. else
  132. {
  133. m_bstrString = SysAllocString(wcsString);
  134. if (!m_bstrString)
  135. {
  136. wiauDbgError("Copy", "memory allocation failed");
  137. return E_OUTOFMEMORY;
  138. }
  139. }
  140. return hr;
  141. }
  142. //
  143. // This function initializes a BSTR from a raw PTP string, clearing
  144. // the BSTR first, if needed
  145. //
  146. // Input:
  147. // ppRaw -- pointer to pointer to raw data to initialize the string from
  148. // bParse -- indicates whether to advance the raw pointer or not
  149. //
  150. HRESULT
  151. CBstr::Init(
  152. BYTE **ppRaw,
  153. BOOL bParse
  154. )
  155. {
  156. HRESULT hr = S_OK;
  157. //
  158. // Check arguments
  159. //
  160. if (!ppRaw || !*ppRaw)
  161. {
  162. wiauDbgError("Init", "invalid arg");
  163. return E_INVALIDARG;
  164. }
  165. //
  166. // Extract the length from the raw data, and set up a more convenient pointer
  167. // to the string data (skipping over the length byte)
  168. //
  169. int length = (UCHAR) **ppRaw;
  170. OLECHAR *pRaw = (OLECHAR *) (*ppRaw + sizeof(UCHAR));
  171. if (m_bstrString)
  172. {
  173. if (!SysReAllocStringLen(&m_bstrString, pRaw, length))
  174. {
  175. wiauDbgError("Init", "memory allocation failed");
  176. return E_OUTOFMEMORY;
  177. }
  178. }
  179. else
  180. {
  181. m_bstrString = SysAllocStringLen(pRaw, length);
  182. if (!m_bstrString)
  183. {
  184. wiauDbgError("Init", "memory allocation failed");
  185. return E_OUTOFMEMORY;
  186. }
  187. }
  188. //
  189. // If requested, advance the raw pointer past the string. One byte for the length and
  190. // 2 times the number of chars in the wide string.
  191. //
  192. if (bParse)
  193. {
  194. *ppRaw += sizeof(UCHAR) + length * sizeof(USHORT);
  195. }
  196. return hr;
  197. }
  198. //
  199. // This function writes the string to a buffer in PTP format
  200. //
  201. // Input:
  202. // ppRaw -- pointer to pointer to buffer
  203. // Length -- amount of space left in the buffer in bytes
  204. //
  205. VOID
  206. CBstr::WriteToBuffer(
  207. BYTE **ppRaw
  208. )
  209. {
  210. UCHAR NumChars = (UCHAR) Length();
  211. //
  212. // Add one for null terminating char, but only if string is non-empty
  213. //
  214. if (NumChars > 0)
  215. NumChars++;
  216. int NumBytes = NumChars * sizeof(WCHAR);
  217. **ppRaw = NumChars;
  218. (*ppRaw)++;
  219. if (NumChars > 0)
  220. {
  221. memcpy(*ppRaw, String(), NumBytes);
  222. *ppRaw += NumBytes;
  223. }
  224. return;
  225. }
  226. //
  227. // This function dumps a PTP string to the log
  228. //
  229. // Input:
  230. // szDesc -- Description for the string
  231. //
  232. VOID
  233. CBstr::Dump(char *szDesc)
  234. {
  235. if (m_bstrString && SysStringLen(m_bstrString) > 0)
  236. {
  237. wiauDbgDump("", "%s %S", szDesc, m_bstrString);
  238. }
  239. else
  240. {
  241. wiauDbgDump("", "%s <blank>", szDesc);
  242. }
  243. return;
  244. }
  245. //
  246. // Dumps the contents of a CArray8 to the log
  247. //
  248. // Input:
  249. // szDesc -- description for the string
  250. // szFiller -- filler to use for subsequent lines
  251. //
  252. VOID
  253. CArray8::Dump(
  254. char *szDesc,
  255. char *szFiller
  256. )
  257. {
  258. HRESULT hr = S_OK;
  259. char szPart[MAX_PATH] = "\0";
  260. char szMsg[MAX_PATH] = "\0";
  261. //
  262. // Make sure array is not empty
  263. //
  264. if (GetSize() > 0)
  265. {
  266. //
  267. // Prime output string
  268. //
  269. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
  270. if (FAILED(hr))
  271. {
  272. goto Cleanup;
  273. }
  274. //
  275. // Loop through the elements
  276. //
  277. for (int count = 0; count < GetSize(); count++)
  278. {
  279. //
  280. // Start a new line every 8 values
  281. //
  282. if ((count != 0) && (count % 8 == 0))
  283. {
  284. wiauDbgDump("", "%s", szMsg);
  285. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
  286. if (FAILED(hr))
  287. {
  288. goto Cleanup;
  289. }
  290. }
  291. hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%02x", m_aT[count]);
  292. if (FAILED(hr))
  293. {
  294. goto Cleanup;
  295. }
  296. hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
  297. if (FAILED(hr))
  298. {
  299. goto Cleanup;
  300. }
  301. }
  302. wiauDbgDump("", "%s", szMsg);
  303. }
  304. else
  305. {
  306. wiauDbgDump("", "%s <blank>", szDesc);
  307. }
  308. Cleanup:
  309. if (FAILED(hr))
  310. {
  311. wiauDbgErrorHr(hr, "CArray8::Dump", "Failed to dump array");
  312. }
  313. return;
  314. }
  315. //
  316. // Dumps the contents of a CArray16 to the log
  317. //
  318. // Input:
  319. // szDesc -- description for the string
  320. // szFiller -- filler to use for subsequent lines
  321. //
  322. VOID
  323. CArray16::Dump(
  324. char *szDesc,
  325. char *szFiller
  326. )
  327. {
  328. HRESULT hr = S_OK;
  329. char szMsg[MAX_PATH] = "\0";
  330. char szPart[MAX_PATH] = "\0";
  331. //
  332. // Make sure it's not empty
  333. //
  334. if (GetSize() > 0)
  335. {
  336. //
  337. // Prime output string
  338. //
  339. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
  340. if (FAILED(hr))
  341. {
  342. goto Cleanup;
  343. }
  344. //
  345. // Loop through the elements
  346. //
  347. for (int count = 0; count < GetSize(); count++)
  348. {
  349. //
  350. // Start a new line every 4 values
  351. //
  352. if ((count != 0) && (count % 4 == 0))
  353. {
  354. wiauDbgDump("", "%s", szMsg);
  355. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
  356. if (FAILED(hr))
  357. {
  358. goto Cleanup;
  359. }
  360. }
  361. hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%04x", m_aT[count]);
  362. if (FAILED(hr))
  363. {
  364. goto Cleanup;
  365. }
  366. hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
  367. if (FAILED(hr))
  368. {
  369. goto Cleanup;
  370. }
  371. }
  372. wiauDbgDump("", "%s", szMsg);
  373. }
  374. else
  375. {
  376. wiauDbgDump("", "%s <blank>", szDesc);
  377. }
  378. Cleanup:
  379. if (FAILED(hr))
  380. {
  381. wiauDbgErrorHr(hr, "CArray16::Dump", "Failed to dump array");
  382. }
  383. return;
  384. }
  385. //
  386. // This function parses a CArray32 from an array of UCHARs
  387. //
  388. BOOL
  389. CArray32::ParseFrom8(
  390. BYTE **ppRaw,
  391. int NumSize
  392. )
  393. {
  394. if (!ppRaw || !*ppRaw)
  395. return FALSE;
  396. RemoveAll();
  397. // Get the number of elements from the raw data
  398. ULONG NumElems;
  399. switch (NumSize)
  400. {
  401. case 4:
  402. NumElems = MAKELONG(MAKEWORD((*ppRaw)[0], (*ppRaw)[1]), MAKEWORD((*ppRaw)[2], (*ppRaw)[3]));
  403. break;
  404. case 2:
  405. NumElems = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
  406. break;
  407. case 1:
  408. NumElems = **ppRaw;
  409. break;
  410. default:
  411. return FALSE;
  412. }
  413. *ppRaw += NumSize;
  414. // Allocate space for the array
  415. if (!GrowTo(NumElems))
  416. return FALSE;
  417. // Copy in the elements, one at a time
  418. BYTE *pValues = *ppRaw;
  419. ULONG value = 0;
  420. for (ULONG count = 0; count < NumElems; count++)
  421. {
  422. value = (ULONG) pValues[count];
  423. if (!Add(value))
  424. return FALSE;
  425. }
  426. // Advance the raw pointer past the array and number of elements field
  427. *ppRaw += NumElems * sizeof(BYTE);
  428. return TRUE;
  429. }
  430. //
  431. // This function parses a CArray32 from an array of WORDs
  432. //
  433. BOOL
  434. CArray32::ParseFrom16(
  435. BYTE **ppRaw,
  436. int NumSize
  437. )
  438. {
  439. if (!ppRaw || !*ppRaw)
  440. return FALSE;
  441. RemoveAll();
  442. // Get the number of elements from the raw data
  443. ULONG NumElems;
  444. switch (NumSize)
  445. {
  446. case 4:
  447. NumElems = MAKELONG(MAKEWORD((*ppRaw)[0], (*ppRaw)[1]), MAKEWORD((*ppRaw)[2], (*ppRaw)[3]));
  448. break;
  449. case 2:
  450. NumElems = MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
  451. break;
  452. case 1:
  453. NumElems = **ppRaw;
  454. break;
  455. default:
  456. return FALSE;
  457. }
  458. *ppRaw += NumSize;
  459. // Allocate space for the array
  460. if (!GrowTo(NumElems))
  461. return FALSE;
  462. // Copy in the elements, one at a time
  463. ULONG value = 0;
  464. for (ULONG count = 0; count < NumElems; count++)
  465. {
  466. value = (ULONG) MAKEWORD((*ppRaw)[0], (*ppRaw)[1]);
  467. *ppRaw += sizeof(WORD);
  468. if (!Add(value))
  469. return FALSE;
  470. }
  471. return TRUE;
  472. }
  473. //
  474. // Copies values from an array of bytes
  475. //
  476. BOOL
  477. CArray32::Copy(CArray8 values8)
  478. {
  479. RemoveAll();
  480. GrowTo(values8.GetSize());
  481. for (int count = 0; count < values8.GetSize(); count++)
  482. {
  483. ULONG value = values8[count];
  484. if (!Add(value))
  485. return FALSE;
  486. }
  487. return TRUE;
  488. }
  489. //
  490. // Copies values from an array of bytes
  491. //
  492. BOOL
  493. CArray32::Copy(CArray16 values16)
  494. {
  495. RemoveAll();
  496. GrowTo(values16.GetSize());
  497. for (int count = 0; count < values16.GetSize(); count++)
  498. {
  499. ULONG value = values16[count];
  500. if (!Add(value))
  501. return FALSE;
  502. }
  503. return TRUE;
  504. }
  505. //
  506. // Dumps the contents of a CArray32 to the log
  507. //
  508. // Input:
  509. // szDesc -- description for the string
  510. // szFiller -- filler to use for subsequent lines
  511. //
  512. VOID
  513. CArray32::Dump(
  514. char *szDesc,
  515. char *szFiller
  516. )
  517. {
  518. HRESULT hr = S_OK;
  519. char szMsg[MAX_PATH] = "\0";
  520. char szPart[MAX_PATH] = "\0";
  521. //
  522. // Make sure it's not empty
  523. //
  524. if (GetSize() > 0)
  525. {
  526. //
  527. // Prime output string
  528. //
  529. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szDesc);
  530. if (FAILED(hr))
  531. {
  532. goto Cleanup;
  533. }
  534. //
  535. // Loop through the elements
  536. //
  537. for (int count = 0; count < GetSize(); count++)
  538. {
  539. //
  540. // Start a new line every 4 values
  541. //
  542. if ((count != 0) && (count % 4 == 0))
  543. {
  544. wiauDbgDump("", "%s", szMsg);
  545. hr = StringCchCopyA(szMsg, ARRAYSIZE(szMsg), szFiller);
  546. if (FAILED(hr))
  547. {
  548. goto Cleanup;
  549. }
  550. }
  551. hr = StringCchPrintfA(szPart, ARRAYSIZE(szPart), " 0x%08x", m_aT[count]);
  552. if (FAILED(hr))
  553. {
  554. goto Cleanup;
  555. }
  556. hr = StringCchCatA(szMsg, ARRAYSIZE(szMsg), szPart);
  557. if (FAILED(hr))
  558. {
  559. goto Cleanup;
  560. }
  561. }
  562. wiauDbgDump("", "%s", szMsg);
  563. }
  564. else
  565. {
  566. wiauDbgDump("", "%s <blank>", szDesc);
  567. }
  568. Cleanup:
  569. if (FAILED(hr))
  570. {
  571. wiauDbgErrorHr(hr, "CArray32::Dump", "Failed to dump array");
  572. }
  573. return;
  574. }
  575. //
  576. // This function initializes a string array from raw data, clearing
  577. // the array first, if needed
  578. //
  579. // Input:
  580. // ppRaw -- pointer to pointer to raw data to initialize the string from
  581. // bParse -- indicates whether to advance the raw pointer or not
  582. //
  583. HRESULT
  584. CArrayString::Init(
  585. BYTE **ppRaw,
  586. int NumSize
  587. )
  588. {
  589. HRESULT hr = S_OK;
  590. if (!ppRaw || !*ppRaw)
  591. return E_INVALIDARG;
  592. RemoveAll();
  593. // Get the number of elements from the raw data
  594. int NumElems;
  595. switch (NumSize)
  596. {
  597. case 4:
  598. NumElems = MAKELONG(MAKEWORD((*ppRaw)[0],(*ppRaw)[1]),
  599. MAKEWORD((*ppRaw)[2],(*ppRaw)[3]));
  600. break;
  601. case 2:
  602. NumElems = MAKEWORD((*ppRaw)[0],(*ppRaw)[1]);
  603. break;
  604. case 1:
  605. NumElems = (BYTE) **ppRaw;
  606. break;
  607. default:
  608. return E_FAIL;
  609. }
  610. // Allocate space for the array
  611. if (!GrowTo(NumElems))
  612. return E_OUTOFMEMORY;
  613. // Advance past the number of elements field
  614. *ppRaw += NumSize;
  615. // Read in each string
  616. CBstr tempStr;
  617. for (int count = 0; count < NumElems; count++)
  618. {
  619. tempStr.Init(ppRaw, TRUE);
  620. if (!Add(tempStr))
  621. return E_FAIL;
  622. }
  623. return hr;
  624. }
  625. //
  626. // Dumps the contents of a CArrayString to the log
  627. //
  628. // Input:
  629. // szDesc -- description for the string
  630. // szFiller -- filler to use for subsequent lines
  631. //
  632. VOID
  633. CArrayString::Dump(
  634. char *szDesc,
  635. char *szFiller
  636. )
  637. {
  638. int count;
  639. //
  640. // Make sure it's not empty
  641. //
  642. if (GetSize() > 0)
  643. {
  644. //
  645. // Dump first string with description
  646. //
  647. m_aT[0].Dump(szDesc);
  648. //
  649. // Loop through the elements, dumping with the filler
  650. //
  651. for (count = 1; count < GetSize(); count++)
  652. m_aT[count].Dump(szFiller);
  653. }
  654. else
  655. {
  656. wiauDbgDump("", "%s <blank>", szDesc);
  657. }
  658. return;
  659. }
  660. //
  661. // CPtpDeviceInfo constructor
  662. //
  663. CPtpDeviceInfo::CPtpDeviceInfo() :
  664. m_Version(0),
  665. m_VendorExtId(0),
  666. m_VendorExtVersion(0),
  667. m_FuncMode(0)
  668. {
  669. }
  670. //
  671. // CPtpDeviceInfo copying constructor
  672. //
  673. CPtpDeviceInfo::CPtpDeviceInfo(const CPtpDeviceInfo &src) :
  674. m_Version(src.m_Version),
  675. m_VendorExtId(src.m_VendorExtId),
  676. m_VendorExtVersion(src.m_VendorExtVersion),
  677. m_cbstrVendorExtDesc(src.m_cbstrVendorExtDesc),
  678. m_FuncMode(src.m_FuncMode),
  679. m_cbstrManufacturer(src.m_cbstrManufacturer),
  680. m_cbstrModel(src.m_cbstrModel),
  681. m_cbstrDeviceVersion(src.m_cbstrDeviceVersion),
  682. m_cbstrSerialNumber(src.m_cbstrSerialNumber)
  683. {
  684. for (INT i = 0; i < src.m_SupportedOps.GetSize(); i++)
  685. {
  686. m_SupportedOps.Add(src.m_SupportedOps[i]);
  687. }
  688. for (i = 0; i < src.m_SupportedEvents.GetSize(); i++)
  689. {
  690. m_SupportedEvents.Add(src.m_SupportedEvents[i]);
  691. }
  692. for (i = 0; i < src.m_SupportedProps.GetSize(); i++)
  693. {
  694. m_SupportedProps.Add(src.m_SupportedProps[i]);
  695. }
  696. for (i = 0; i < src.m_SupportedCaptureFmts.GetSize(); i++)
  697. {
  698. m_SupportedCaptureFmts.Add(src.m_SupportedCaptureFmts[i]);
  699. }
  700. for (i = 0; i < src.m_SupportedImageFmts.GetSize(); i++)
  701. {
  702. m_SupportedImageFmts.Add(src.m_SupportedImageFmts[i]);
  703. }
  704. }
  705. //
  706. // CPtpDeviceInfo destructor
  707. //
  708. CPtpDeviceInfo::~CPtpDeviceInfo()
  709. {
  710. }
  711. //
  712. // This function initializes the device info from raw data
  713. //
  714. // Input:
  715. // pRawData -- the raw data
  716. //
  717. HRESULT
  718. CPtpDeviceInfo::Init(BYTE *pRawData)
  719. {
  720. HRESULT hr = S_OK;
  721. BYTE *pCurrent = pRawData;
  722. m_Version = ParseWord(&pCurrent);
  723. m_VendorExtId = ParseDword(&pCurrent);
  724. m_VendorExtVersion = ParseWord(&pCurrent);
  725. hr = m_cbstrVendorExtDesc.Init(&pCurrent, TRUE);
  726. if (FAILED(hr))
  727. return hr;
  728. m_FuncMode = ParseWord(&pCurrent);
  729. if (!m_SupportedOps.Parse(&pCurrent))
  730. return E_FAIL;
  731. if (!m_SupportedEvents.Parse(&pCurrent))
  732. return E_FAIL;
  733. if (!m_SupportedProps.Parse(&pCurrent))
  734. return E_FAIL;
  735. if (!m_SupportedCaptureFmts.Parse(&pCurrent))
  736. return E_FAIL;
  737. if (!m_SupportedImageFmts.Parse(&pCurrent))
  738. return E_FAIL;
  739. hr = m_cbstrManufacturer.Init(&pCurrent, TRUE);
  740. if (FAILED(hr))
  741. return hr;
  742. hr = m_cbstrModel.Init(&pCurrent, TRUE);
  743. if (FAILED(hr))
  744. return hr;
  745. hr = m_cbstrDeviceVersion.Init(&pCurrent, TRUE);
  746. if (FAILED(hr))
  747. return hr;
  748. hr = m_cbstrSerialNumber.Init(&pCurrent, TRUE);
  749. if (FAILED(hr))
  750. return hr;
  751. return hr;
  752. }
  753. //
  754. // This function dumps the device information to the log
  755. //
  756. VOID
  757. CPtpDeviceInfo::Dump()
  758. {
  759. wiauDbgDump("", "DumpDeviceInfo, dumping DeviceInfo:");
  760. wiauDbgDump("", " Standard version = 0x%04x", m_Version);
  761. wiauDbgDump("", " Vendor ext id = 0x%08x", m_VendorExtId);
  762. wiauDbgDump("", " Vendor ext ver = 0x%04x", m_VendorExtVersion);
  763. m_cbstrVendorExtDesc.Dump( " Vendor ext desc =");
  764. m_SupportedOps.Dump( " Ops supported =", " ");
  765. m_SupportedEvents.Dump( " Events supported =", " ");
  766. m_SupportedProps.Dump( " Props supported =", " ");
  767. m_SupportedCaptureFmts.Dump( " Capture fmts supp =", " ");
  768. m_SupportedImageFmts.Dump( " Img formats supp =", " ");
  769. m_cbstrManufacturer.Dump( " Manufacturer =");
  770. m_cbstrModel.Dump( " Model =");
  771. m_cbstrDeviceVersion.Dump( " Device Version =");
  772. m_cbstrSerialNumber.Dump( " Serial Number =");
  773. return;
  774. }
  775. //
  776. // CPtpStorageInfo constructor
  777. //
  778. CPtpStorageInfo::CPtpStorageInfo() :
  779. m_StorageId(0),
  780. m_StorageType(0),
  781. m_FileSystemType(0),
  782. m_AccessCapability(0),
  783. m_MaxCapacity(0),
  784. m_FreeSpaceInBytes(0),
  785. m_FreeSpaceInImages(0)
  786. {
  787. }
  788. //
  789. // CPtpStorageInfo destructor
  790. //
  791. CPtpStorageInfo::~CPtpStorageInfo()
  792. {
  793. }
  794. //
  795. // This function initializes the device info from raw data
  796. //
  797. // Input:
  798. // pRawData -- the raw data
  799. //
  800. HRESULT
  801. CPtpStorageInfo::Init(
  802. BYTE *pRawData,
  803. DWORD StorageId
  804. )
  805. {
  806. HRESULT hr = S_OK;
  807. BYTE *pCurrent = pRawData;
  808. m_StorageId = StorageId;
  809. m_StorageType = ParseWord(&pCurrent);
  810. m_FileSystemType = ParseWord(&pCurrent);
  811. m_AccessCapability = ParseWord(&pCurrent);
  812. m_MaxCapacity = ParseQword(&pCurrent);
  813. m_FreeSpaceInBytes = ParseQword(&pCurrent);
  814. m_FreeSpaceInImages = ParseDword(&pCurrent);
  815. hr = m_cbstrStorageDesc.Init(&pCurrent, TRUE);
  816. if (FAILED(hr))
  817. return hr;
  818. hr = m_cbstrStorageLabel.Init(&pCurrent, TRUE);
  819. if (FAILED(hr))
  820. return hr;
  821. return hr;
  822. }
  823. //
  824. // This function dumps the storage information to the log
  825. //
  826. VOID
  827. CPtpStorageInfo::Dump()
  828. {
  829. wiauDbgDump("", "DumpStorageInfo, dumping StorageInfo for store 0x%08x:", m_StorageId);
  830. wiauDbgDump("", " Storage type = 0x%04x", m_StorageType);
  831. wiauDbgDump("", " File system type = 0x%04x", m_FileSystemType);
  832. wiauDbgDump("", " Access capability = 0x%04x", m_AccessCapability);
  833. wiauDbgDump("", " Max capacity = %I64u", m_MaxCapacity);
  834. wiauDbgDump("", " Free space (byte) = %I64u", m_FreeSpaceInBytes);
  835. wiauDbgDump("", " Free space (imgs) = %u", m_FreeSpaceInImages);
  836. m_cbstrStorageDesc.Dump( " Storage desc =");
  837. m_cbstrStorageLabel.Dump( " Storage label =");
  838. return;
  839. }
  840. //
  841. // CPtpObjectInfo constructor
  842. //
  843. CPtpObjectInfo::CPtpObjectInfo() :
  844. m_ObjectHandle(0),
  845. m_StorageId(0),
  846. m_FormatCode(0),
  847. m_ProtectionStatus(0),
  848. m_CompressedSize(0),
  849. m_ThumbFormat(0),
  850. m_ThumbCompressedSize(0),
  851. m_ThumbPixWidth(0),
  852. m_ThumbPixHeight(0),
  853. m_ImagePixWidth(0),
  854. m_ImagePixHeight(0),
  855. m_ImageBitDepth(0),
  856. m_ParentHandle(0),
  857. m_AssociationType(0),
  858. m_AssociationDesc(0),
  859. m_SequenceNumber(0)
  860. {
  861. }
  862. //
  863. // CPtpObjectInfo destructor
  864. //
  865. CPtpObjectInfo::~CPtpObjectInfo()
  866. {
  867. }
  868. //
  869. // This function initializes the object info from raw data
  870. //
  871. // Input:
  872. // pRawData -- the raw data
  873. // ObjectHandle -- the object's handle
  874. //
  875. HRESULT
  876. CPtpObjectInfo::Init(
  877. BYTE *pRawData,
  878. DWORD ObjectHandle
  879. )
  880. {
  881. HRESULT hr = S_OK;
  882. BYTE *pCurrent = pRawData;
  883. m_ObjectHandle = ObjectHandle;
  884. m_StorageId = ParseDword(&pCurrent);
  885. m_FormatCode = ParseWord(&pCurrent);
  886. m_ProtectionStatus = ParseWord(&pCurrent);
  887. m_CompressedSize = ParseDword(&pCurrent);
  888. m_ThumbFormat = ParseWord(&pCurrent);
  889. m_ThumbCompressedSize = ParseDword(&pCurrent);
  890. m_ThumbPixWidth = ParseDword(&pCurrent);
  891. m_ThumbPixHeight = ParseDword(&pCurrent);
  892. m_ImagePixWidth = ParseDword(&pCurrent);
  893. m_ImagePixHeight = ParseDword(&pCurrent);
  894. m_ImageBitDepth = ParseDword(&pCurrent);
  895. m_ParentHandle = ParseDword(&pCurrent);
  896. m_AssociationType = ParseWord(&pCurrent);
  897. m_AssociationDesc = ParseDword(&pCurrent);
  898. m_SequenceNumber = ParseDword(&pCurrent);
  899. hr = m_cbstrFileName.Init(&pCurrent, TRUE);
  900. if (FAILED(hr))
  901. return hr;
  902. hr = m_cbstrCaptureDate.Init(&pCurrent, TRUE);
  903. if (FAILED(hr))
  904. return hr;
  905. hr = m_cbstrModificationDate.Init(&pCurrent, TRUE);
  906. if (FAILED(hr))
  907. return hr;
  908. hr = m_cbstrKeywords.Init(&pCurrent, TRUE);
  909. if (FAILED(hr))
  910. return hr;
  911. return hr;
  912. }
  913. //
  914. // This function writes the ObjectInfo structure to a buffer in PTP format
  915. //
  916. // Input:
  917. // ppRaw -- pointer to pointer to buffer
  918. // Length -- amount of space left in the buffer in bytes
  919. //
  920. VOID
  921. CPtpObjectInfo::WriteToBuffer(
  922. BYTE **ppRaw
  923. )
  924. {
  925. WriteDword(ppRaw, m_StorageId);
  926. WriteWord(ppRaw, m_FormatCode);
  927. WriteWord(ppRaw, m_ProtectionStatus);
  928. WriteDword(ppRaw, m_CompressedSize);
  929. WriteWord(ppRaw, m_ThumbFormat);
  930. WriteDword(ppRaw, m_ThumbCompressedSize);
  931. WriteDword(ppRaw, m_ThumbPixWidth);
  932. WriteDword(ppRaw, m_ThumbPixHeight);
  933. WriteDword(ppRaw, m_ImagePixWidth);
  934. WriteDword(ppRaw, m_ImagePixHeight);
  935. WriteDword(ppRaw, m_ImageBitDepth);
  936. WriteDword(ppRaw, m_ParentHandle);
  937. WriteWord(ppRaw, m_AssociationType);
  938. WriteDword(ppRaw, m_AssociationDesc);
  939. WriteDword(ppRaw, m_SequenceNumber);
  940. m_cbstrFileName.WriteToBuffer(ppRaw);
  941. m_cbstrCaptureDate.WriteToBuffer(ppRaw);
  942. m_cbstrModificationDate.WriteToBuffer(ppRaw);
  943. m_cbstrKeywords.WriteToBuffer(ppRaw);
  944. return;
  945. }
  946. //
  947. // This function dumps the object information to the log
  948. //
  949. VOID
  950. CPtpObjectInfo::Dump()
  951. {
  952. wiauDbgDump("", "DumpObjectInfo, dumping ObjectInfo for object 0x%08x:", m_ObjectHandle);
  953. wiauDbgDump("", " Storage id = 0x%08x", m_StorageId);
  954. wiauDbgDump("", " Format code = 0x%04x", m_FormatCode);
  955. wiauDbgDump("", " Protection status = 0x%04x", m_ProtectionStatus);
  956. wiauDbgDump("", " Compressed size = %u", m_CompressedSize);
  957. wiauDbgDump("", " Thumbnail format = 0x%04x", m_ThumbFormat);
  958. wiauDbgDump("", " Thumbnail size = %u", m_ThumbCompressedSize);
  959. wiauDbgDump("", " Thumbnail width = %u", m_ThumbPixWidth);
  960. wiauDbgDump("", " Thumbnail height = %u", m_ThumbPixHeight);
  961. wiauDbgDump("", " Image width = %u", m_ImagePixWidth);
  962. wiauDbgDump("", " Image height = %u", m_ImagePixHeight);
  963. wiauDbgDump("", " Image bit depth = %u", m_ImageBitDepth);
  964. wiauDbgDump("", " Parent obj handle = 0x%08x", m_ParentHandle);
  965. wiauDbgDump("", " Association type = 0x%04x", m_AssociationType);
  966. wiauDbgDump("", " Association desc = 0x%08x", m_AssociationDesc);
  967. wiauDbgDump("", " Sequence number = %u", m_SequenceNumber);
  968. m_cbstrFileName.Dump( " File name =");
  969. m_cbstrCaptureDate.Dump( " Capture date =");
  970. m_cbstrModificationDate.Dump( " Modification date =");
  971. m_cbstrKeywords.Dump( " Keywords =");
  972. return;
  973. }
  974. //
  975. // CPtpPropDesc constructor
  976. //
  977. CPtpPropDesc::CPtpPropDesc() :
  978. m_PropCode(0),
  979. m_DataType(0),
  980. m_GetSet(0),
  981. m_FormFlag(0),
  982. m_NumValues(0),
  983. m_lDefault(0),
  984. m_lCurrent(0),
  985. m_lRangeMin(0),
  986. m_lRangeMax(0),
  987. m_lRangeStep(0)
  988. {
  989. }
  990. //
  991. // CPtpPropDesc destructor
  992. //
  993. CPtpPropDesc::~CPtpPropDesc()
  994. {
  995. }
  996. //
  997. // This function initializes a CPtpPropDesc from raw data
  998. //
  999. // Input:
  1000. // pRawData -- pointer to the raw data
  1001. //
  1002. HRESULT
  1003. CPtpPropDesc::Init(BYTE *pRawData)
  1004. {
  1005. HRESULT hr = S_OK;
  1006. BYTE *pCurrent = pRawData;
  1007. m_PropCode = ParseWord(&pCurrent);
  1008. m_DataType = ParseWord(&pCurrent);
  1009. m_GetSet = *pCurrent++;
  1010. switch (m_DataType)
  1011. {
  1012. case PTP_DATATYPE_INT8:
  1013. case PTP_DATATYPE_UINT8:
  1014. m_lDefault = *pCurrent++;
  1015. m_lCurrent = *pCurrent++;
  1016. break;
  1017. case PTP_DATATYPE_INT16:
  1018. case PTP_DATATYPE_UINT16:
  1019. m_lDefault = ParseWord(&pCurrent);
  1020. m_lCurrent = ParseWord(&pCurrent);
  1021. break;
  1022. case PTP_DATATYPE_INT32:
  1023. case PTP_DATATYPE_UINT32:
  1024. m_lDefault = ParseDword(&pCurrent);
  1025. m_lCurrent = ParseDword(&pCurrent);
  1026. break;
  1027. case PTP_DATATYPE_STRING:
  1028. hr = m_cbstrDefault.Init(&pCurrent, TRUE);
  1029. if (FAILED(hr)) return hr;
  1030. hr = m_cbstrCurrent.Init(&pCurrent, TRUE);
  1031. if (FAILED(hr)) return hr;
  1032. break;
  1033. default:
  1034. return E_FAIL;
  1035. }
  1036. m_FormFlag = *pCurrent++;
  1037. if (m_FormFlag == PTP_FORMFLAGS_RANGE)
  1038. {
  1039. switch (m_DataType)
  1040. {
  1041. case PTP_DATATYPE_INT8:
  1042. case PTP_DATATYPE_UINT8:
  1043. m_lRangeMin = *pCurrent++;
  1044. m_lRangeMax = *pCurrent++;
  1045. m_lRangeStep = *pCurrent++;
  1046. m_lRangeStep = max(1, m_lRangeStep);
  1047. break;
  1048. case PTP_DATATYPE_INT16:
  1049. case PTP_DATATYPE_UINT16:
  1050. m_lRangeMin = ParseWord(&pCurrent);
  1051. m_lRangeMax = ParseWord(&pCurrent);
  1052. m_lRangeStep = ParseWord(&pCurrent);
  1053. m_lRangeStep = max(1, m_lRangeStep);
  1054. break;
  1055. case PTP_DATATYPE_INT32:
  1056. case PTP_DATATYPE_UINT32:
  1057. m_lRangeMin = ParseDword(&pCurrent);
  1058. m_lRangeMax = ParseDword(&pCurrent);
  1059. m_lRangeStep = ParseDword(&pCurrent);
  1060. m_lRangeStep = max(1, m_lRangeStep);
  1061. break;
  1062. case PTP_DATATYPE_STRING:
  1063. hr = m_cbstrRangeMin.Init(&pCurrent, TRUE);
  1064. if (FAILED(hr)) return hr;
  1065. hr = m_cbstrRangeMax.Init(&pCurrent, TRUE);
  1066. if (FAILED(hr)) return hr;
  1067. hr = m_cbstrRangeStep.Init(&pCurrent, TRUE);
  1068. if (FAILED(hr)) return hr;
  1069. break;
  1070. default:
  1071. return E_FAIL;
  1072. }
  1073. }
  1074. else if (m_FormFlag == PTP_FORMFLAGS_ENUM)
  1075. {
  1076. switch (m_DataType)
  1077. {
  1078. case PTP_DATATYPE_INT8:
  1079. case PTP_DATATYPE_UINT8:
  1080. if (!m_lValues.ParseFrom8(&pCurrent, 2))
  1081. return E_FAIL;
  1082. break;
  1083. case PTP_DATATYPE_INT16:
  1084. case PTP_DATATYPE_UINT16:
  1085. if (!m_lValues.ParseFrom16(&pCurrent, 2))
  1086. return E_FAIL;
  1087. break;
  1088. case PTP_DATATYPE_INT32:
  1089. case PTP_DATATYPE_UINT32:
  1090. if (!m_lValues.Parse(&pCurrent, 2))
  1091. return E_FAIL;
  1092. break;
  1093. case PTP_DATATYPE_STRING:
  1094. hr = m_cbstrValues.Init(&pCurrent, 2);
  1095. if (FAILED(hr)) return hr;
  1096. break;
  1097. default:
  1098. return E_FAIL;
  1099. }
  1100. m_NumValues = max(m_lValues.GetSize(), m_cbstrValues.GetSize());
  1101. }
  1102. return hr;
  1103. }
  1104. //
  1105. // This function sets the current value of a CPtpPropDesc from raw data
  1106. //
  1107. // Input:
  1108. // pRaw -- pointer to the raw data
  1109. //
  1110. HRESULT
  1111. CPtpPropDesc::ParseValue(BYTE *pRaw)
  1112. {
  1113. HRESULT hr = S_OK;
  1114. BYTE *pCurrent = pRaw;
  1115. switch (m_DataType)
  1116. {
  1117. case PTP_DATATYPE_INT8:
  1118. case PTP_DATATYPE_UINT8:
  1119. m_lCurrent = *pCurrent++;
  1120. break;
  1121. case PTP_DATATYPE_INT16:
  1122. case PTP_DATATYPE_UINT16:
  1123. m_lCurrent = ParseWord(&pCurrent);
  1124. break;
  1125. case PTP_DATATYPE_INT32:
  1126. case PTP_DATATYPE_UINT32:
  1127. m_lCurrent = ParseDword(&pCurrent);
  1128. break;
  1129. case PTP_DATATYPE_STRING:
  1130. hr = m_cbstrCurrent.Init(&pCurrent, TRUE);
  1131. break;
  1132. default:
  1133. return E_FAIL;
  1134. }
  1135. return hr;
  1136. }
  1137. //
  1138. // This function writes the current value of a CPtpPropDesc to a raw buffer
  1139. //
  1140. // Input:
  1141. // ppRaw -- pointer to pointer to a raw buffer
  1142. //
  1143. VOID
  1144. CPtpPropDesc::WriteValue(BYTE **ppRaw)
  1145. {
  1146. switch (m_DataType)
  1147. {
  1148. case PTP_DATATYPE_INT8:
  1149. case PTP_DATATYPE_UINT8:
  1150. **ppRaw = (BYTE) m_lCurrent;
  1151. (*ppRaw)++;
  1152. break;
  1153. case PTP_DATATYPE_INT16:
  1154. case PTP_DATATYPE_UINT16:
  1155. WriteWord(ppRaw, (WORD) m_lCurrent);
  1156. break;
  1157. case PTP_DATATYPE_INT32:
  1158. case PTP_DATATYPE_UINT32:
  1159. WriteDword(ppRaw, m_lCurrent);
  1160. break;
  1161. case PTP_DATATYPE_STRING:
  1162. m_cbstrCurrent.WriteToBuffer(ppRaw);
  1163. break;
  1164. }
  1165. return;
  1166. }
  1167. //
  1168. // This function dumps the property description information to the log
  1169. //
  1170. VOID
  1171. CPtpPropDesc::Dump()
  1172. {
  1173. wiauDbgDump("", "CPtpPropDesc::Dump, dumping PropDesc for property 0x%04x:", m_PropCode);
  1174. wiauDbgDump("", " Data type = 0x%04x", m_DataType);
  1175. wiauDbgDump("", " GetSet = 0x%02x", m_GetSet);
  1176. if (m_DataType == PTP_DATATYPE_STRING)
  1177. {
  1178. m_cbstrDefault.Dump(" Default =");
  1179. m_cbstrCurrent.Dump(" Current =");
  1180. wiauDbgDump("", " Form flag = 0x%02x", m_FormFlag);
  1181. switch (m_FormFlag)
  1182. {
  1183. case PTP_FORMFLAGS_RANGE:
  1184. m_cbstrRangeMin.Dump(" Range min =");
  1185. m_cbstrRangeMax.Dump(" Range max =");
  1186. m_cbstrRangeStep.Dump(" Range step =");
  1187. break;
  1188. case PTP_FORMFLAGS_ENUM:
  1189. m_cbstrValues.Dump(" Valid values =", " ");
  1190. break;
  1191. default:
  1192. wiauDbgDump("", " <unknown valid value type>");
  1193. }
  1194. }
  1195. else
  1196. {
  1197. wiauDbgDump("", " Default = 0x%08x", m_lDefault);
  1198. wiauDbgDump("", " Current = 0x%08x", m_lCurrent);
  1199. wiauDbgDump("", " Form flag = 0x%02x", m_FormFlag);
  1200. switch (m_FormFlag)
  1201. {
  1202. case PTP_FORMFLAGS_RANGE:
  1203. wiauDbgDump("", " Range min = 0x%08x", m_lRangeMin);
  1204. wiauDbgDump("", " Range max = 0x%08x", m_lRangeMax);
  1205. wiauDbgDump("", " Range step = 0x%08x", m_lRangeStep);
  1206. break;
  1207. case PTP_FORMFLAGS_ENUM:
  1208. m_lValues.Dump(" Valid values =", " ");
  1209. break;
  1210. default:
  1211. wiauDbgDump("", " <unknown valid value type>");
  1212. }
  1213. }
  1214. return;
  1215. }
  1216. //
  1217. // This function dumps the property value to the log
  1218. //
  1219. VOID
  1220. CPtpPropDesc::DumpValue()
  1221. {
  1222. wiauDbgDump("", "CPtpPropDescDumpValue, current value for property 0x%04x:", m_PropCode);
  1223. if (m_DataType == PTP_DATATYPE_STRING)
  1224. m_cbstrCurrent.Dump(" Current =");
  1225. else
  1226. wiauDbgDump("", " Current = 0x%08x", m_lCurrent);
  1227. return;
  1228. }