Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

868 lines
19 KiB

  1. /*****************************************************************************
  2. *
  3. * Device.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Implementation for pass-through ( empty) user mode still image driver (USD)
  10. * Insance of this object class is created for devices, which do not provide
  11. * vendor-specific USD.
  12. * Methods implemented in this object are only for sending/receiving escape
  13. * sequences from app to device.
  14. *
  15. * Contents:
  16. *
  17. * CStiEmptyUSD_New
  18. *
  19. *****************************************************************************/
  20. /*
  21. #include <windows.h>
  22. #include <windowsx.h>
  23. #include <objbase.h>
  24. #include <regstr.h>
  25. #include <setupapi.h>
  26. #include <cfgmgr32.h>
  27. #include <devguid.h>
  28. #include <stdio.h>
  29. #include <stilog.h>
  30. #include <stiregi.h>
  31. #include <sti.h>
  32. #include <stierr.h>
  33. #include <stiusd.h>
  34. #include "wia.h"
  35. #include "stipriv.h"
  36. #include "stiapi.h"
  37. #include "stirc.h"
  38. #include "debug.h"
  39. */
  40. #include "sticomm.h"
  41. #define DbgFl DbgFlStiObj
  42. /*****************************************************************************
  43. *
  44. * Declare the interfaces we will be providing.
  45. *
  46. *****************************************************************************/
  47. Primary_Interface(CStiEmptyUSD, IStiUSD);
  48. Interface_Template_Begin(CStiEmptyUSD)
  49. Primary_Interface_Template(CStiEmptyUSD, IStiUSD)
  50. Interface_Template_End(CStiEmptyUSD)
  51. /*****************************************************************************
  52. *
  53. * @doc INTERNAL
  54. *
  55. * @struct CStiEmptyUSD |
  56. *
  57. * The <i CStiEmptyUSD> device object
  58. *
  59. *
  60. * @field IStiDevice | stidev
  61. *
  62. * @comm
  63. *
  64. *
  65. *****************************************************************************/
  66. typedef struct CStiEmptyUSD {
  67. /* Supported interfaces */
  68. IStiUSD usd;
  69. DWORD dwVersion;
  70. RD(LONG cCrit;)
  71. D(DWORD thidCrit;)
  72. BOOL fCritInited;
  73. CRITICAL_SECTION crst;
  74. PSTIDEVICECONTROL pDcb;
  75. } CStiEmptyUSD, *PCStiEmptyUSD;
  76. #define ThisClass CStiEmptyUSD
  77. #define ThisInterface IStiUSD
  78. #ifdef DEBUG
  79. Default_QueryInterface(CStiEmptyUSD)
  80. Default_AddRef(CStiEmptyUSD)
  81. Default_Release(CStiEmptyUSD)
  82. #else
  83. #define CStiEmptyUSD_QueryInterface Common_QueryInterface
  84. #define CStiEmptyUSD_AddRef Common_AddRef
  85. #define CStiEmptyUSD_Release Common_Release
  86. #endif
  87. #define CStiEmptyUSD_QIHelper Common_QIHelper
  88. #pragma BEGIN_CONST_DATA
  89. #pragma END_CONST_DATA
  90. /*****************************************************************************
  91. *
  92. * @doc EXTERNAL
  93. *
  94. * @method HRESULT | CStiEmptyUSD | GetStatus |
  95. *
  96. * @parm PSTI_DEVICE_STATUS | PSTI_DEVICE_STATUS pDevStatus) |
  97. *
  98. * @returns
  99. *
  100. * Returns a COM error code.
  101. *
  102. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  103. *
  104. *****************************************************************************/
  105. STDMETHODIMP
  106. CStiEmptyUSD_GetStatus(
  107. PSTIUSD pUsd,
  108. PSTI_DEVICE_STATUS pDevStatus
  109. )
  110. {
  111. HRESULT hres = STIERR_INVALID_PARAM;
  112. EnterProcR(CStiEmptyUSD::GetStatus,(_ "pp", pUsd, pDevStatus));
  113. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  114. PCStiEmptyUSD this = _thisPv(pUsd);
  115. hres = STIERR_UNSUPPORTED;
  116. }
  117. ExitOleProc();
  118. return hres;
  119. }
  120. /*****************************************************************************
  121. *
  122. * @doc EXTERNAL
  123. *
  124. * @method HRESULT | CStiEmptyUSD | DeviceReset |
  125. *
  126. * @parm
  127. *
  128. * @returns
  129. *
  130. * Returns a COM error code.
  131. *
  132. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  133. *
  134. *****************************************************************************/
  135. STDMETHODIMP
  136. CStiEmptyUSD_DeviceReset(
  137. PSTIUSD pUsd
  138. )
  139. {
  140. HRESULT hres;
  141. EnterProcR(CStiEmptyUSD::DeviceReset,(_ "p", pUsd));
  142. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  143. PCStiEmptyUSD this = _thisPv(pUsd);
  144. hres = STIERR_UNSUPPORTED;
  145. }
  146. ExitOleProc();
  147. return hres;
  148. }
  149. /*****************************************************************************
  150. *
  151. * @doc EXTERNAL
  152. *
  153. * @method HRESULT | CStiEmptyUSD | Diagnostic |
  154. *
  155. * @parm LPDIAG | pBuffer |
  156. *
  157. * @returns
  158. *
  159. * Returns a COM error code.
  160. *
  161. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  162. *
  163. *****************************************************************************/
  164. STDMETHODIMP
  165. CStiEmptyUSD_Diagnostic(
  166. PSTIUSD pUsd,
  167. LPSTI_DIAG pBuffer
  168. )
  169. {
  170. HRESULT hres;
  171. EnterProcR(CStiEmptyUSD::Diagnostic,(_ "p", pUsd, pBuffer ));
  172. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  173. PCStiEmptyUSD this = _thisPv(pUsd);
  174. hres = STI_OK;
  175. }
  176. ExitOleProc();
  177. return hres;
  178. }
  179. /*****************************************************************************
  180. *
  181. * @doc EXTERNAL
  182. *
  183. * @method HRESULT | CStiEmptyUSD | SetNotificationEvent |
  184. * Specify the event that should be set when the device
  185. * state changes, or turns off such notifications.
  186. *
  187. * @cwrap LPSTIUSD | lpStiDevice
  188. *
  189. * @parm IN HANDLE | hEvent |
  190. *
  191. * @returns
  192. *
  193. * Returns a COM error code.
  194. *
  195. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  196. * <c E_INVALIDARG>: The thing isn't an event handle.
  197. *
  198. *
  199. *****************************************************************************/
  200. STDMETHODIMP
  201. CStiEmptyUSD_SetNotificationEvent(
  202. PSTIUSD pUsd,
  203. HANDLE hEvent
  204. )
  205. {
  206. HRESULT hres;
  207. EnterProcR(CStiEmptyUSD::SetNotificationEvent,(_ "px", pUsd, hEvent ));
  208. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  209. PCStiEmptyUSD this = _thisPv(pUsd);
  210. hres = STIERR_UNSUPPORTED;
  211. }
  212. ExitOleProc();
  213. return hres;
  214. }
  215. /*****************************************************************************
  216. *
  217. * @doc EXTERNAL
  218. *
  219. * @method HRESULT | CStiEmptyUSD | GetNotificationData |
  220. *
  221. * @parm LPVOID* | ppBuffer |
  222. *
  223. * @returns
  224. *
  225. * Returns a COM error code.
  226. *
  227. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  228. *
  229. *****************************************************************************/
  230. STDMETHODIMP
  231. CStiEmptyUSD_GetNotificationData(
  232. PSTIUSD pUsd,
  233. LPSTINOTIFY pBuffer
  234. )
  235. {
  236. HRESULT hres;
  237. EnterProcR(CStiEmptyUSD::GetNotificationData,(_ "p", pUsd, pBuffer));
  238. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  239. PCStiEmptyUSD this = _thisPv(pUsd);
  240. hres = STIERR_UNSUPPORTED;
  241. }
  242. ExitOleProc();
  243. return hres;
  244. }
  245. /*****************************************************************************
  246. *
  247. * @doc EXTERNAL
  248. *
  249. * @method HRESULT | CStiEmptyUSD | Escape |
  250. *
  251. * @parm
  252. *
  253. * @returns
  254. *
  255. * Returns a COM error code.
  256. *
  257. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  258. *
  259. *****************************************************************************/
  260. STDMETHODIMP
  261. CStiEmptyUSD_Escape(
  262. PSTIUSD pUsd,
  263. STI_RAW_CONTROL_CODE EscapeFunction,
  264. LPVOID lpInData,
  265. DWORD cbInDataSize,
  266. LPVOID lpOutData,
  267. DWORD cbOutDataSize,
  268. LPDWORD pcbActualData
  269. )
  270. {
  271. HRESULT hres;
  272. LPDWORD pcbTemp = NULL;
  273. EnterProcR(CStiEmptyUSD::Escape,(_ "pxpxp", pUsd, EscapeFunction,lpInData,cbInDataSize,lpOutData ));
  274. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  275. PCStiEmptyUSD this = _thisPv(pUsd);
  276. hres = S_OK;
  277. // Validate arguments
  278. if (pcbActualData && !SUCCEEDED(hresFullValidPdwOut(pcbActualData, 7))) {
  279. ExitOleProc();
  280. return STIERR_INVALID_PARAM;
  281. }
  282. // Write indata to device if needed.
  283. if (EscapeFunction == StiWriteControlInfo || EscapeFunction == StiTransact) {
  284. hres = IStiDeviceControl_RawWriteData(this->pDcb,lpInData,cbInDataSize,NULL);
  285. }
  286. // If write was required and succeeded , read result data
  287. if (SUCCEEDED(hres)) {
  288. DWORD dwBytesReturned = 0;
  289. if (EscapeFunction == StiReadControlInfo || EscapeFunction == StiTransact) {
  290. if (pcbActualData) {
  291. *pcbActualData = cbOutDataSize;
  292. pcbTemp = pcbActualData;
  293. }
  294. else {
  295. dwBytesReturned = cbOutDataSize;
  296. pcbTemp = &dwBytesReturned;
  297. }
  298. hres = IStiDeviceControl_RawReadData(this->pDcb,lpOutData,pcbTemp,NULL);
  299. }
  300. }
  301. }
  302. ExitOleProc();
  303. return hres;
  304. }
  305. /*****************************************************************************
  306. *
  307. * @doc EXTERNAL
  308. *
  309. * @method HRESULT | CStiEmptyUSD | GetLastError |
  310. *
  311. * @parm
  312. *
  313. * @returns
  314. *
  315. * Returns a COM error code.
  316. *
  317. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  318. *
  319. *****************************************************************************/
  320. STDMETHODIMP
  321. CStiEmptyUSD_GetLastError(
  322. PSTIUSD pUsd,
  323. LPDWORD pdwLastDeviceError
  324. )
  325. {
  326. HRESULT hres = STI_OK;
  327. EnterProcR(CStiEmptyUSD::GetLastError,(_ "p", pUsd ));
  328. // Validate parameters
  329. if (!pdwLastDeviceError) {
  330. ExitOleProc();
  331. return STIERR_INVALID_PARAM;
  332. }
  333. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  334. PCStiEmptyUSD this = _thisPv(pUsd);
  335. if (this->pDcb ) {
  336. hres = IStiDeviceControl_GetLastError(this->pDcb,pdwLastDeviceError);
  337. }
  338. }
  339. ExitOleProc();
  340. return hres;
  341. }
  342. /*****************************************************************************
  343. *
  344. * @doc EXTERNAL
  345. *
  346. * @method HRESULT | CStiEmptyUSD | LockDevice |
  347. *
  348. * @parm
  349. *
  350. * @returns
  351. *
  352. * Returns a COM error code.
  353. *
  354. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  355. *
  356. *****************************************************************************/
  357. STDMETHODIMP
  358. CStiEmptyUSD_LockDevice(
  359. PSTIUSD pUsd
  360. )
  361. {
  362. HRESULT hres;
  363. EnterProcR(CStiEmptyUSD::LockDevice,(_ "p", pUsd ));
  364. // Validate parameters
  365. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  366. PCStiEmptyUSD this = _thisPv(pUsd);
  367. }
  368. ExitOleProc();
  369. return hres;
  370. }
  371. /*****************************************************************************
  372. *
  373. * @doc EXTERNAL
  374. *
  375. * @method HRESULT | CStiEmptyUSD | UnLockDevice |
  376. *
  377. * @parm
  378. *
  379. * @returns
  380. *
  381. * Returns a COM error code.
  382. *
  383. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  384. *
  385. *****************************************************************************/
  386. STDMETHODIMP
  387. CStiEmptyUSD_UnLockDevice(
  388. PSTIUSD pUsd
  389. )
  390. {
  391. HRESULT hres;
  392. EnterProcR(CStiEmptyUSD::UnLockDevice,(_ "p", pUsd ));
  393. // Validate parameters
  394. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  395. PCStiEmptyUSD this = _thisPv(pUsd);
  396. }
  397. ExitOleProc();
  398. return hres;
  399. }
  400. /*****************************************************************************
  401. *
  402. * @doc EXTERNAL
  403. *
  404. * @method HRESULT | IStiUSD | RawReadData |
  405. *
  406. * @parm
  407. *
  408. * @returns
  409. *
  410. * Returns a COM error code.
  411. *
  412. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  413. *
  414. *****************************************************************************/
  415. STDMETHODIMP
  416. CStiEmptyUSD_RawReadData(
  417. PSTIUSD pUsd,
  418. LPVOID lpBuffer,
  419. LPDWORD lpdwNumberOfBytes,
  420. LPOVERLAPPED lpOverlapped
  421. )
  422. {
  423. HRESULT hres;
  424. EnterProcR(CStiEmptyUSD::RawReadData,(_ "p", pUsd ));
  425. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  426. PCStiEmptyUSD this = _thisPv(pUsd);
  427. hres = IStiDeviceControl_RawReadData(this->pDcb,lpBuffer,lpdwNumberOfBytes,lpOverlapped);
  428. }
  429. ExitOleProc();
  430. return hres;
  431. }
  432. /*****************************************************************************
  433. *
  434. * @doc EXTERNAL
  435. *
  436. * @method HRESULT | IStiUSD | RawWriteData |
  437. *
  438. * @parm
  439. *
  440. * @returns
  441. *
  442. * Returns a COM error code.
  443. *
  444. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  445. *
  446. *****************************************************************************/
  447. STDMETHODIMP
  448. CStiEmptyUSD_RawWriteData(
  449. PSTIUSD pUsd,
  450. LPVOID lpBuffer,
  451. DWORD dwNumberOfBytes,
  452. LPOVERLAPPED lpOverlapped
  453. )
  454. {
  455. HRESULT hres;
  456. EnterProcR(IStiUSD::RawWriteData,(_ "p", pUsd ));
  457. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  458. PCStiEmptyUSD this = _thisPv(pUsd);
  459. hres = IStiDeviceControl_RawWriteData(this->pDcb,lpBuffer,dwNumberOfBytes,lpOverlapped);
  460. }
  461. ExitOleProc();
  462. return hres;
  463. }
  464. /*****************************************************************************
  465. *
  466. * @doc EXTERNAL
  467. *
  468. * @method HRESULT | IStiUSD | RawReadCommand |
  469. *
  470. * @parm
  471. *
  472. * @returns
  473. *
  474. * Returns a COM error code.
  475. *
  476. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  477. *
  478. *****************************************************************************/
  479. STDMETHODIMP
  480. CStiEmptyUSD_RawReadCommand(
  481. PSTIUSD pUsd,
  482. LPVOID lpBuffer,
  483. LPDWORD lpdwNumberOfBytes,
  484. LPOVERLAPPED lpOverlapped
  485. )
  486. {
  487. HRESULT hres;
  488. EnterProcR(IStiUSD::RawReadCommand,(_ "p", pUsd ));
  489. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  490. PCStiEmptyUSD this = _thisPv(pUsd);
  491. hres = IStiDeviceControl_RawReadCommand(this->pDcb,lpBuffer,lpdwNumberOfBytes,lpOverlapped);
  492. }
  493. ExitOleProc();
  494. return hres;
  495. }
  496. /*****************************************************************************
  497. *
  498. * @doc EXTERNAL
  499. *
  500. * @method HRESULT | IStiUSD | RawWriteCommand |
  501. *
  502. * @parm
  503. *
  504. * @returns
  505. *
  506. * Returns a COM error code.
  507. *
  508. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  509. *
  510. *****************************************************************************/
  511. STDMETHODIMP
  512. CStiEmptyUSD_RawWriteCommand(
  513. PSTIUSD pUsd,
  514. LPVOID lpBuffer,
  515. DWORD dwNumberOfBytes,
  516. LPOVERLAPPED lpOverlapped
  517. )
  518. {
  519. HRESULT hres;
  520. EnterProcR(IStiUSD::RawWriteCommand,(_ "p", pUsd ));
  521. if (SUCCEEDED(hres = hresPvI(pUsd, ThisInterface))) {
  522. PCStiEmptyUSD this = _thisPv(pUsd);
  523. hres = IStiDeviceControl_RawWriteCommand(this->pDcb,lpBuffer,dwNumberOfBytes,lpOverlapped);
  524. }
  525. ExitOleProc();
  526. return hres;
  527. }
  528. /*****************************************************************************
  529. *
  530. * @doc INTERNAL
  531. *
  532. * @mfunc void | CStiEmptyUSD | Init |
  533. *
  534. * Initialize the internal parts of the StiDevice object.
  535. *
  536. *****************************************************************************/
  537. void INLINE
  538. CStiEmptyUSD_Init(
  539. PCStiEmptyUSD this
  540. )
  541. {
  542. // Initialize instance variables
  543. this->pDcb = NULL;
  544. }
  545. /*****************************************************************************
  546. *
  547. * @doc INTERNAL
  548. *
  549. * @func void | CStiDev_Finalize |
  550. *
  551. * Releases the resources of a generic device.
  552. *
  553. * @parm PV | pvObj |
  554. *
  555. * Object being released. Note that it may not have been
  556. * completely initialized, so everything should be done
  557. * carefully.
  558. *
  559. *****************************************************************************/
  560. void INTERNAL
  561. CStiEmptyUSD_Finalize(PV pvObj)
  562. {
  563. HRESULT hres = STI_OK;
  564. PCStiEmptyUSD this = pvObj;
  565. IStiDeviceControl_Release(this->pDcb);
  566. this->pDcb = NULL;
  567. }
  568. /*****************************************************************************
  569. *
  570. * @doc INTERNAL
  571. *
  572. * @func void | USD_Initialize |
  573. *
  574. *
  575. * @parm | |
  576. *
  577. *
  578. *****************************************************************************/
  579. STDMETHODIMP
  580. CStiEmptyUSD_Initialize(
  581. PSTIUSD pUsd,
  582. PSTIDEVICECONTROL pHelDcb,
  583. DWORD dwStiVersion,
  584. HKEY hkeyParameters
  585. )
  586. {
  587. HRESULT hres = STI_OK;
  588. EnterProcR(CStiEmptyUSD::USD_Initialize,(_ "ppx", pUsd,pHelDcb ,dwStiVersion));
  589. // Validate parameters
  590. if (!pHelDcb) {
  591. ExitOleProc();
  592. return STIERR_INVALID_PARAM;
  593. }
  594. if (SUCCEEDED(hres = hresPvI(pUsd, IStiUSD))) {
  595. PCStiEmptyUSD this = _thisPv(pUsd);
  596. // Mark that we are using this instance
  597. IStiDeviceControl_AddRef(pHelDcb);
  598. this->pDcb = pHelDcb;
  599. hres = STI_OK;
  600. }
  601. ExitOleProc();
  602. return hres;
  603. }
  604. /*****************************************************************************
  605. *
  606. * @doc INTERNAL
  607. *
  608. * @func void | USD_Initialize |
  609. *
  610. *
  611. * @parm | |
  612. *
  613. *
  614. *****************************************************************************/
  615. STDMETHODIMP
  616. CStiEmptyUSD_GetCapabilities(
  617. PSTIUSD pUsd,
  618. PSTI_USD_CAPS pUsdCaps
  619. )
  620. {
  621. HRESULT hres = STI_OK;
  622. EnterProcR(CStiEmptyUSD::USD_Initialize,(_ "pp", pUsd,pUsdCaps));
  623. // Validate parameters
  624. if (!pUsdCaps) {
  625. ExitOleProc();
  626. return STIERR_INVALID_PARAM;
  627. }
  628. if (SUCCEEDED(hres = hresPvI(pUsd, IStiUSD))) {
  629. PCStiEmptyUSD this = _thisPv(pUsd);
  630. // Set that we are only pass-through, requiring serialization
  631. ZeroMemory(pUsdCaps,sizeof(*pUsdCaps));
  632. pUsdCaps->dwVersion = STI_VERSION;
  633. hres = STI_OK;
  634. }
  635. ExitOleProc();
  636. return hres;
  637. }
  638. /*****************************************************************************
  639. *
  640. * @doc INTERNAL
  641. *
  642. * @mfunc HRESULT | CStiEmptyUSD | New |
  643. *
  644. * Create a new StiDevice object, uninitialized.
  645. *
  646. * @parm IN PUNK | punkOuter |
  647. *
  648. * Controlling unknown for aggregation.
  649. *
  650. * @parm IN RIID | riid |
  651. *
  652. * Desired interface to new object.
  653. *
  654. * @parm OUT PPV | ppvObj |
  655. *
  656. * Output pointer for new object.
  657. *
  658. *****************************************************************************/
  659. STDMETHODIMP
  660. CStiEmptyUSD_New(PUNK punkOuter, RIID riid, PPV ppvObj)
  661. {
  662. HRESULT hres;
  663. EnterProcR(CStiEmptyUSD::<constructor>, (_ "Gp", riid, punkOuter));
  664. hres = Common_NewRiid(CStiEmptyUSD, punkOuter, riid, ppvObj);
  665. if (SUCCEEDED(hres)) {
  666. PCStiEmptyUSD this = _thisPv(*ppvObj);
  667. CStiEmptyUSD_Init(this);
  668. }
  669. ExitOleProcPpvR(ppvObj);
  670. return hres;
  671. }
  672. /*****************************************************************************
  673. *
  674. * The long-awaited vtbls and templates
  675. *
  676. *****************************************************************************/
  677. #pragma BEGIN_CONST_DATA
  678. #define CStiEmptyUSD_Signature (DWORD)'USD'
  679. Primary_Interface_Begin(CStiEmptyUSD, IStiUSD)
  680. CStiEmptyUSD_Initialize,
  681. CStiEmptyUSD_GetCapabilities,
  682. CStiEmptyUSD_GetStatus,
  683. CStiEmptyUSD_DeviceReset,
  684. CStiEmptyUSD_Diagnostic,
  685. CStiEmptyUSD_Escape,
  686. CStiEmptyUSD_GetLastError,
  687. CStiEmptyUSD_LockDevice,
  688. CStiEmptyUSD_UnLockDevice,
  689. CStiEmptyUSD_RawReadData,
  690. CStiEmptyUSD_RawWriteData,
  691. CStiEmptyUSD_RawReadCommand,
  692. CStiEmptyUSD_RawWriteCommand,
  693. CStiEmptyUSD_SetNotificationEvent,
  694. CStiEmptyUSD_GetNotificationData,
  695. Primary_Interface_End(CStiEmptyUSD, IStiDevice)