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.

956 lines
27 KiB

  1. /*****************************************************************************
  2. *
  3. * Hel.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * Hardware emulation layer calls. Used to provide common functionality
  10. * for built-in device types we support ( WDM, serial and parallel)
  11. * While access to DCB could be built as internal COM object , it does not make
  12. * much sense to invest in it, because DCBs are exclusively owned and not shared
  13. * between application objects or different applications. We also want to minimize
  14. * any overhead when talking to raw device interface.
  15. *
  16. * Note1: We don't deal at this level with access control, lower level drivers are supposed
  17. * to take care of this. Queuing of requests for non-reentrant devices is also not done here.
  18. * This Hel is basically thin layer of imaging device primitives, used only to isolate
  19. * command translator from actual hardware.
  20. *
  21. * Note2: Hel is not made extensible . If command translator needs to talk to non-supported
  22. * device, it will need to establish direct link to it. There is no requirement to use
  23. * Hel , it is service we provide to conformant devices.
  24. *
  25. * Contents:
  26. *
  27. *****************************************************************************/
  28. /*
  29. #include "wia.h"
  30. #include <stilog.h>
  31. #include <stiregi.h>
  32. #include <sti.h>
  33. #include <stierr.h>
  34. #include <stiusd.h>
  35. #include "stipriv.h"
  36. #include "debug.h"
  37. #define DbgFl DbgFlDevice
  38. */
  39. #include "sticomm.h"
  40. #include "validate.h"
  41. #define DbgFl DbgFlDevice
  42. /*****************************************************************************
  43. *
  44. * Declare the interfaces we will be providing.
  45. *
  46. *****************************************************************************/
  47. Primary_Interface(CCommDeviceControl, IStiDeviceControl);
  48. Interface_Template_Begin(CCommDeviceControl)
  49. Primary_Interface_Template(CCommDeviceControl, IStiDeviceControl)
  50. Interface_Template_End(CCommDeviceControl)
  51. /*****************************************************************************
  52. *
  53. * @doc INTERNAL
  54. *
  55. * @struct CCommDeviceControl |
  56. *
  57. * The <i CCommDeviceControl> device object
  58. *
  59. *
  60. * @field IStiDeviceControl | stidev
  61. *
  62. * @comm
  63. *
  64. *
  65. *****************************************************************************/
  66. #define IOBUFFERSIZE 255
  67. #define WRITETOTALTIMEOUT 20
  68. typedef struct CCommDeviceControl {
  69. /* Supported interfaces */
  70. IStiDeviceControl devctl;
  71. DWORD dwVersion;
  72. DWORD dwDeviceType;
  73. WCHAR wszPortName[MAX_PATH];
  74. DWORD dwFlags;
  75. DWORD dwMode;
  76. DWORD dwContext;
  77. DWORD dwLastOperationError;
  78. HANDLE hDeviceHandle;
  79. HANDLE hEvent;
  80. OVERLAPPED Overlapped;
  81. } CCommDeviceControl, *PCCommDeviceControl;
  82. #define ThisClass CCommDeviceControl
  83. #define ThisInterface IStiDeviceControl
  84. #ifdef DEBUG
  85. Default_QueryInterface(CCommDeviceControl)
  86. Default_AddRef(CCommDeviceControl)
  87. Default_Release(CCommDeviceControl)
  88. #else
  89. #define CCommDeviceControl_QueryInterface Common_QueryInterface
  90. #define CCommDeviceControl_AddRef Common_AddRef
  91. #define CCommDeviceControl_Release Common_Release
  92. #endif
  93. #define CCommDeviceControl_QIHelper Common_QIHelper
  94. #pragma BEGIN_CONST_DATA
  95. #pragma END_CONST_DATA
  96. /*****************************************************************************
  97. *
  98. * @doc EXTERNAL
  99. *
  100. * @method HRESULT | CCommDeviceControl | RawReadData |
  101. *
  102. * @parm | |
  103. *
  104. * @returns
  105. *
  106. * Returns a COM error code.
  107. *
  108. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  109. *
  110. *****************************************************************************/
  111. STDMETHODIMP
  112. CCommDeviceControl_RawReadData(
  113. PSTIDEVICECONTROL pDev,
  114. LPVOID lpBuffer,
  115. LPDWORD lpdwNumberOfBytes,
  116. LPOVERLAPPED lpOverlapped
  117. )
  118. {
  119. HRESULT hres = STIERR_INVALID_PARAM;
  120. DWORD dwBytesReturned=0;
  121. BOOL fRet = TRUE;
  122. OVERLAPPED Overlapped;
  123. COMSTAT ComStat;
  124. BOOL fBlocking = FALSE;
  125. DWORD dwErrorFlags;
  126. EnterProc(CCommDeviceControl_CommRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
  127. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  128. PCCommDeviceControl this = _thisPv(pDev);
  129. // Validate parameters here
  130. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) &&
  131. SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) &&
  132. (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
  133. // We always call asyncronous i/o operations in order to time-out lengthy ones
  134. if (!lpOverlapped) {
  135. ZeroX(Overlapped);
  136. lpOverlapped = &Overlapped;
  137. fBlocking = TRUE;
  138. }
  139. //
  140. ClearCommError(this->hDeviceHandle, &dwErrorFlags, &ComStat);
  141. *lpdwNumberOfBytes = min(*lpdwNumberOfBytes, ComStat.cbInQue);
  142. if (*lpdwNumberOfBytes == 0) {
  143. return (STI_OK);
  144. }
  145. //
  146. if (fRet = ReadFile(this->hDeviceHandle, lpBuffer, *lpdwNumberOfBytes, lpdwNumberOfBytes, lpOverlapped)) {
  147. return (STI_OK);
  148. }
  149. if (GetLastError() != ERROR_IO_PENDING)
  150. return (STI_OK);
  151. this->dwLastOperationError = GetLastError();
  152. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  153. }
  154. }
  155. ExitOleProc();
  156. return hres;
  157. }
  158. /*****************************************************************************
  159. *
  160. * @doc EXTERNAL
  161. *
  162. * @method HRESULT | CCommDeviceControl | CommRawWriteData |
  163. *
  164. * @parm | |
  165. *
  166. * @returns
  167. *
  168. * Returns a COM error code.
  169. *
  170. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  171. *
  172. *****************************************************************************/
  173. STDMETHODIMP
  174. CCommDeviceControl_RawWriteData(
  175. PSTIDEVICECONTROL pDev,
  176. LPVOID lpBuffer,
  177. DWORD dwNumberOfBytes,
  178. LPOVERLAPPED lpOverlapped
  179. )
  180. {
  181. HRESULT hres = STIERR_INVALID_PARAM;
  182. DWORD dwBytesReturned=0;
  183. BOOL fRet;
  184. EnterProc(CCommDeviceControl_CommRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
  185. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  186. PCCommDeviceControl this = _thisPv(pDev);
  187. // Validate parameters here
  188. hres = STIERR_INVALID_PARAM;
  189. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) {
  190. if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){
  191. // Call appropriate entry point
  192. fRet = WriteFile(this->hDeviceHandle,
  193. lpBuffer,
  194. dwNumberOfBytes,
  195. &dwBytesReturned,
  196. lpOverlapped
  197. );
  198. this->dwLastOperationError = GetLastError();
  199. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  200. }
  201. }
  202. }
  203. ExitOleProc();
  204. return hres;
  205. }
  206. /*****************************************************************************
  207. *
  208. * @doc EXTERNAL
  209. *
  210. * @method HRESULT | CCommDeviceControl | RawReadControl |
  211. *
  212. * @parm | |
  213. *
  214. * @returns
  215. *
  216. * Returns a COM error code.
  217. *
  218. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  219. *
  220. *****************************************************************************/
  221. STDMETHODIMP
  222. CCommDeviceControl_RawReadCommand(
  223. PSTIDEVICECONTROL pDev,
  224. LPVOID lpBuffer,
  225. LPDWORD lpdwNumberOfBytes,
  226. LPOVERLAPPED lpOverlapped
  227. )
  228. {
  229. HRESULT hres = STIERR_INVALID_PARAM;
  230. DWORD dwBytesReturned=0;
  231. //BOOL fRet;
  232. EnterProc(CCommDeviceControl_CommRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
  233. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  234. PCCommDeviceControl this = _thisPv(pDev);
  235. // Validate parameters here
  236. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) &&
  237. SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) &&
  238. (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
  239. hres = STIERR_UNSUPPORTED;
  240. }
  241. }
  242. ExitOleProc();
  243. return hres;
  244. }
  245. /*****************************************************************************
  246. *
  247. * @doc EXTERNAL
  248. *
  249. * @method HRESULT | CCommDeviceControl | CommRawWriteData |
  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. CCommDeviceControl_RawWriteCommand(
  262. PSTIDEVICECONTROL pDev,
  263. LPVOID lpBuffer,
  264. DWORD dwNumberOfBytes,
  265. LPOVERLAPPED lpOverlapped
  266. )
  267. {
  268. HRESULT hres = STIERR_INVALID_PARAM;
  269. DWORD dwBytesReturned=0;
  270. //BOOL fRet;
  271. EnterProc(CCommDeviceControl_CommRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
  272. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  273. PCCommDeviceControl this = _thisPv(pDev);
  274. // Validate parameters here
  275. hres = STIERR_INVALID_PARAM;
  276. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) {
  277. if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){
  278. hres = STIERR_UNSUPPORTED;
  279. }
  280. }
  281. }
  282. ExitOleProc();
  283. return hres;
  284. }
  285. /*****************************************************************************
  286. *
  287. * @doc EXTERNAL
  288. *
  289. * @method HRESULT | CCommDeviceControl | RawReadControl |
  290. *
  291. * @parm | |
  292. *
  293. * @returns
  294. *
  295. * Returns a COM error code.
  296. *
  297. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  298. *
  299. *****************************************************************************/
  300. STDMETHODIMP
  301. CCommDeviceControl_GetLastError(
  302. PSTIDEVICECONTROL pDev,
  303. LPDWORD lpdwLastError
  304. )
  305. {
  306. HRESULT hres = STIERR_INVALID_PARAM;
  307. DWORD dwBytesReturned=0;
  308. EnterProc(CCommDeviceControl_GetLastError, (_ "pppp",pDev,lpdwLastError));
  309. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  310. PCCommDeviceControl this = _thisPv(pDev);
  311. // Validate parameters here
  312. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwLastError,4, 2))) {
  313. *lpdwLastError = this->dwLastOperationError ;
  314. hres = STI_OK;
  315. }
  316. }
  317. ExitOleProc();
  318. return hres;
  319. }
  320. /*****************************************************************************
  321. *
  322. * @doc EXTERNAL
  323. *
  324. * @method HRESULT | CCommDeviceControl_ | GetMyDevicePortName |
  325. *
  326. * @parm | |
  327. *
  328. * @returns
  329. *
  330. * Returns a COM error code.
  331. *
  332. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  333. *
  334. *****************************************************************************/
  335. STDMETHODIMP
  336. CCommDeviceControl_GetMyDevicePortName(
  337. PSTIDEVICECONTROL pDev,
  338. LPWSTR lpszDevicePath,
  339. DWORD cwDevicePathSize
  340. )
  341. {
  342. HRESULT hres = STIERR_INVALID_PARAM;
  343. DWORD dwBytesReturned=0;
  344. EnterProc(CCommDeviceControl_GetMyDevicePortName, (_ "pp",pDev,lpszDevicePath));
  345. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  346. PCCommDeviceControl this = _thisPv(pDev);
  347. // Validate parameters here
  348. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,4, 2)) &&
  349. SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,2*cwDevicePathSize, 2)) ) {
  350. if (cwDevicePathSize > OSUtil_StrLenW(this->wszPortName)) {
  351. OSUtil_lstrcpyW(lpszDevicePath,this->wszPortName);
  352. hres = STI_OK;
  353. }
  354. else {
  355. hres = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
  356. }
  357. }
  358. }
  359. ExitOleProc();
  360. return hres;
  361. }
  362. /*****************************************************************************
  363. *
  364. * @doc EXTERNAL
  365. *
  366. * @method HRESULT | CCommDeviceControl | GetMyDeviceHandle |
  367. *
  368. * @parm | |
  369. *
  370. * @returns
  371. *
  372. * Returns a COM error code.
  373. *
  374. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  375. *
  376. *****************************************************************************/
  377. STDMETHODIMP
  378. CCommDeviceControl_GetMyDeviceHandle(
  379. PSTIDEVICECONTROL pDev,
  380. LPHANDLE pHandle
  381. )
  382. {
  383. HRESULT hres = STIERR_INVALID_PARAM;
  384. DWORD dwBytesReturned=0;
  385. EnterProc(CCommDeviceControl_GetMyDeviceHandle, (_ "pp",pDev,pHandle));
  386. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  387. PCCommDeviceControl this = _thisPv(pDev);
  388. // Validate parameters here
  389. if (SUCCEEDED(hres = hresFullValidReadPvCb(pHandle,4, 2)) ) {
  390. if (INVALID_HANDLE_VALUE != this->hDeviceHandle) {
  391. *pHandle = this->hDeviceHandle;
  392. hres = STI_OK;
  393. }
  394. else {
  395. hres = HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
  396. }
  397. }
  398. }
  399. ExitOleProc();
  400. return hres;
  401. }
  402. /*****************************************************************************
  403. *
  404. * @doc EXTERNAL
  405. *
  406. * @method HRESULT | GetMyDeviceOpenMode | pdwOpenMode |
  407. *
  408. * @parm | |
  409. *
  410. * @returns
  411. *
  412. * Returns a COM error code.
  413. *
  414. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  415. *
  416. *****************************************************************************/
  417. STDMETHODIMP
  418. CCommDeviceControl_GetMyDeviceOpenMode(
  419. PSTIDEVICECONTROL pDev,
  420. LPDWORD pdwOpenMode
  421. )
  422. {
  423. HRESULT hres = STIERR_INVALID_PARAM;
  424. DWORD dwBytesReturned=0;
  425. EnterProc(CCommDeviceControl_GetMyDeviceOpenMode, (_ "pp",pDev,pdwOpenMode));
  426. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  427. PCCommDeviceControl this = _thisPv(pDev);
  428. // Validate parameters here
  429. if (SUCCEEDED(hres = hresFullValidReadPvCb(pdwOpenMode,4, 2)) ) {
  430. *pdwOpenMode = this->dwMode;
  431. hres = STI_OK;
  432. }
  433. }
  434. ExitOleProc();
  435. return hres;
  436. }
  437. /*****************************************************************************
  438. *
  439. * @doc EXTERNAL
  440. *
  441. * @method HRESULT | CCommDeviceControl | RawReadControl |
  442. *
  443. * @parm | |
  444. *
  445. * @returns
  446. *
  447. * Returns a COM error code.
  448. *
  449. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  450. *
  451. *****************************************************************************/
  452. STDMETHODIMP
  453. CCommDeviceControl_RawDeviceControl(
  454. PSTIDEVICECONTROL pDev,
  455. USD_CONTROL_CODE EscapeFunction,
  456. LPVOID lpInData,
  457. DWORD cbInDataSize,
  458. LPVOID pOutData,
  459. DWORD dwOutDataSize,
  460. LPDWORD pdwActualData
  461. )
  462. {
  463. HRESULT hres = STIERR_INVALID_PARAM;
  464. DWORD dwBytesReturned=0;
  465. EnterProc(CCommDeviceControl_RawDeviceControl, (_ "p",pDev));
  466. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  467. PCCommDeviceControl this = _thisPv(pDev);
  468. // Validate parameters here
  469. hres = STIERR_UNSUPPORTED;
  470. }
  471. ExitOleProc();
  472. return hres;
  473. }
  474. /*****************************************************************************
  475. *
  476. * @doc EXTERNAL
  477. *
  478. * @method HRESULT | CCommDeviceControl | WriteToErrorLog |
  479. *
  480. * @parm | |
  481. *
  482. * @returns
  483. *
  484. * Returns a COM error code.
  485. *
  486. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  487. *
  488. *****************************************************************************/
  489. STDMETHODIMP
  490. CCommDeviceControl_WriteToErrorLog(
  491. PSTIDEVICECONTROL pDev,
  492. DWORD dwMessageType,
  493. LPCWSTR pszMessage,
  494. DWORD dwErrorCode
  495. )
  496. {
  497. HRESULT hres = STIERR_INVALID_PARAM;
  498. DWORD dwBytesReturned=0;
  499. EnterProc(CCommDeviceControl_WriteToErrorLog, (_ "p",pDev));
  500. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  501. PCCommDeviceControl this = _thisPv(pDev);
  502. //
  503. // Validate parameters here
  504. //
  505. if (SUCCEEDED(hres = hresFullValidReadPvCb(pszMessage,2, 3))) {
  506. #ifdef UNICODE
  507. ReportStiLogMessage(g_hStiFileLog,
  508. dwMessageType,
  509. pszMessage
  510. );
  511. #else
  512. LPTSTR lpszAnsi = NULL;
  513. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsi,pszMessage))) {
  514. ReportStiLogMessage(g_hStiFileLog,
  515. dwMessageType,
  516. lpszAnsi
  517. );
  518. FreePpv(&lpszAnsi);
  519. }
  520. #endif
  521. }
  522. }
  523. ExitOleProc();
  524. return hres;
  525. }
  526. /*****************************************************************************
  527. *
  528. * @doc EXTERNAL
  529. *
  530. * @mfunc HRESULT | CCommDeviceControl | Initialize |
  531. *
  532. * Initialize a DeviceControl object.
  533. *
  534. * @cwrap PSTIDEVICECONTROL | pDev
  535. *
  536. * @returns
  537. * Returns a COM error code. The following error codes are
  538. * intended to be illustrative and not necessarily comprehensive.
  539. *
  540. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  541. *
  542. * <c S_FALSE>: The device had already been initialized with
  543. * the instance GUID passed in <p lpGUID>.
  544. *
  545. *
  546. *****************************************************************************/
  547. STDMETHODIMP
  548. CCommDeviceControl_Initialize(
  549. PSTIDEVICECONTROL pDev,
  550. DWORD dwDeviceType,
  551. DWORD dwDeviceMode,
  552. LPCWSTR pwszPortName,
  553. DWORD dwFlags
  554. )
  555. {
  556. HRESULT hres = STI_OK;
  557. BOOL fRet = TRUE;
  558. WCHAR wszDeviceSymbolicName[MAX_PATH] = {L'\0'};
  559. COMMTIMEOUTS timoutInfo;
  560. //DWORD dwError;
  561. //LPSTR pszAnsiDeviceName;
  562. EnterProcR(CCommDeviceControl::Initialize,(_ "pp", pDev, pwszPortName));
  563. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  564. PCCommDeviceControl this = _thisPv(pDev);
  565. this->dwDeviceType = dwDeviceType;
  566. OSUtil_lstrcpyW(this->wszPortName,pwszPortName);
  567. this->dwMode = dwDeviceMode;
  568. if (dwFlags & STI_HEL_OPEN_DATA) {
  569. this->hDeviceHandle = OSUtil_CreateFileW(wszDeviceSymbolicName,
  570. GENERIC_READ | GENERIC_WRITE, // Access mask
  571. 0, // Share mode
  572. NULL, // SA
  573. OPEN_EXISTING, // Create disposition
  574. FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, // overlapped I/O
  575. NULL /* hTemplate must be NULL for comm devices */
  576. );
  577. this->dwLastOperationError = GetLastError();
  578. hres = (this->hDeviceHandle != INVALID_HANDLE_VALUE) ?
  579. S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,this->dwLastOperationError);
  580. // wake up read thread will a byte arrives
  581. SetCommMask(this->hDeviceHandle, EV_RXCHAR);
  582. // setup read/write buffer for I/O
  583. SetupComm(this->hDeviceHandle, IOBUFFERSIZE, IOBUFFERSIZE);
  584. // set time outs
  585. timoutInfo.ReadIntervalTimeout = MAXDWORD;
  586. timoutInfo.ReadTotalTimeoutMultiplier = 0;
  587. timoutInfo.ReadTotalTimeoutConstant = 0;
  588. timoutInfo.WriteTotalTimeoutMultiplier = 0;
  589. timoutInfo.WriteTotalTimeoutConstant = WRITETOTALTIMEOUT;
  590. if (!SetCommTimeouts(this->hDeviceHandle, &timoutInfo)) {
  591. fRet = FALSE;
  592. }
  593. else {
  594. // create I/O event used for overlapped i/o
  595. ZeroX(this->Overlapped);
  596. this->hEvent = CreateEvent( NULL, // no security
  597. TRUE, // explicit reset req
  598. FALSE, // initial event reset
  599. NULL ); // no name
  600. if (this->hEvent == NULL) {
  601. fRet = FALSE;
  602. }
  603. EscapeCommFunction(this->hDeviceHandle, SETDTR);
  604. }
  605. // Error code
  606. this->dwLastOperationError = GetLastError();
  607. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  608. }
  609. }
  610. ExitOleProc();
  611. return hres;
  612. }
  613. #if 0
  614. /*
  615. * SetupConnection
  616. *
  617. * Configure serial port with specified settings.
  618. */
  619. static BOOL SetupConnection(HANDLE hCom, LPDPCOMPORTADDRESS portSettings)
  620. {
  621. DCB dcb;
  622. dcb.DCBlength = sizeof(DCB);
  623. if (!GetCommState(hCom, &dcb))
  624. return (FALSE);
  625. // setup various port settings
  626. dcb.fBinary = TRUE;
  627. dcb.BaudRate = portSettings->dwBaudRate;
  628. dcb.ByteSize = 8;
  629. dcb.StopBits = (BYTE) portSettings->dwStopBits;
  630. dcb.Parity = (BYTE) portSettings->dwParity;
  631. if (portSettings->dwParity == NOPARITY)
  632. dcb.fParity = FALSE;
  633. else
  634. dcb.fParity = TRUE;
  635. // setup hardware flow control
  636. if ((portSettings->dwFlowControl == DPCPA_DTRFLOW) ||
  637. (portSettings->dwFlowControl == DPCPA_RTSDTRFLOW))
  638. {
  639. dcb.fOutxDsrFlow = TRUE;
  640. dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
  641. }
  642. else
  643. {
  644. dcb.fOutxDsrFlow = FALSE;
  645. dcb.fDtrControl = DTR_CONTROL_ENABLE;
  646. }
  647. if ((portSettings->dwFlowControl == DPCPA_RTSFLOW) ||
  648. (portSettings->dwFlowControl == DPCPA_RTSDTRFLOW))
  649. {
  650. dcb.fOutxCtsFlow = TRUE;
  651. dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  652. }
  653. else
  654. {
  655. dcb.fOutxCtsFlow = FALSE;
  656. dcb.fRtsControl = RTS_CONTROL_ENABLE;
  657. }
  658. // setup software flow control
  659. if (portSettings->dwFlowControl == DPCPA_XONXOFFFLOW)
  660. {
  661. dcb.fInX = TRUE;
  662. dcb.fOutX = TRUE;
  663. }
  664. else
  665. {
  666. dcb.fInX = FALSE;
  667. dcb.fOutX = FALSE;
  668. }
  669. dcb.XonChar = ASCII_XON;
  670. dcb.XoffChar = ASCII_XOFF;
  671. dcb.XonLim = 100;
  672. dcb.XoffLim = 100;
  673. if (!SetCommState( hCom, &dcb ))
  674. return (FALSE);
  675. return (TRUE);
  676. }
  677. #endif
  678. /*****************************************************************************
  679. *
  680. * @doc INTERNAL
  681. *
  682. * @mfunc void | CCommDeviceControl | Init |
  683. *
  684. * Initialize the internal parts of the StiDevice object.
  685. *
  686. *****************************************************************************/
  687. void INLINE
  688. CCommDeviceControl_Init(
  689. PCCommDeviceControl this
  690. )
  691. {
  692. // Initialize instance variables
  693. this->dwContext = 0L;
  694. this->dwLastOperationError = NO_ERROR;
  695. this->hDeviceHandle = INVALID_HANDLE_VALUE;
  696. }
  697. /*****************************************************************************
  698. *
  699. * @doc INTERNAL
  700. *
  701. * @func void | CCommDeviceControl_Finalize |
  702. *
  703. * Releases the resources of a communication port and closed the device
  704. *
  705. * @parm PV | pvObj |
  706. *
  707. * Object being released. Note that it may not have been
  708. * completely initialized, so everything should be done
  709. * carefully.
  710. *
  711. *****************************************************************************/
  712. void INTERNAL
  713. CCommDeviceControl_Finalize(PV pvObj)
  714. {
  715. HRESULT hres = STI_OK;
  716. PCCommDeviceControl this = pvObj;
  717. //
  718. SetCommMask(this->hDeviceHandle, 0 );
  719. //
  720. EscapeCommFunction(this->hDeviceHandle, CLRDTR );
  721. // purge any outstanding reads/writes and close device handle
  722. PurgeComm(this->hDeviceHandle, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
  723. // Close device handles
  724. if (IsValidHANDLE(this->hDeviceHandle)) {
  725. CloseHandle(this->hDeviceHandle);
  726. }
  727. this->dwContext = 0L;
  728. this->dwLastOperationError = NO_ERROR;
  729. this->hDeviceHandle = INVALID_HANDLE_VALUE;
  730. //this->hDeviceControlHandle = INVALID_HANDLE_VALUE;
  731. }
  732. /*****************************************************************************
  733. *
  734. * @doc INTERNAL
  735. *
  736. * @mfunc HRESULT | CCommDeviceControl | New |
  737. *
  738. * Create a new IDeviceControl object, uninitialized.
  739. *
  740. * @parm IN PUNK | punkOuter |
  741. *
  742. * Controlling unknown for aggregation.
  743. *
  744. * @parm IN RIID | riid |
  745. *
  746. * Desired interface to new object.
  747. *
  748. * @parm OUT PPV | ppvObj |
  749. *
  750. * Output pointer for new object.
  751. *
  752. *****************************************************************************/
  753. STDMETHODIMP
  754. CCommDeviceControl_New(PUNK punkOuter, RIID riid, PPV ppvObj)
  755. {
  756. HRESULT hres;
  757. EnterProcR(CCommDeviceControl::<constructor>, (_ "Gp", riid, punkOuter));
  758. hres = Common_NewRiid(CCommDeviceControl, punkOuter, riid, ppvObj);
  759. if (SUCCEEDED(hres)) {
  760. PCCommDeviceControl this = _thisPv(*ppvObj);
  761. CCommDeviceControl_Init(this);
  762. }
  763. ExitOleProcPpvR(ppvObj);
  764. return hres;
  765. }
  766. /*****************************************************************************
  767. *
  768. * The long-awaited vtbls and templates
  769. *
  770. *****************************************************************************/
  771. #pragma BEGIN_CONST_DATA
  772. #define CCommDeviceControl_Signature (DWORD)'Comm'
  773. Primary_Interface_Begin(CCommDeviceControl, IStiDeviceControl)
  774. CCommDeviceControl_Initialize,
  775. CCommDeviceControl_RawReadData,
  776. CCommDeviceControl_RawWriteData,
  777. CCommDeviceControl_RawReadCommand,
  778. CCommDeviceControl_RawWriteCommand,
  779. CCommDeviceControl_RawDeviceControl,
  780. CCommDeviceControl_GetLastError,
  781. CCommDeviceControl_GetMyDevicePortName,
  782. CCommDeviceControl_GetMyDeviceHandle,
  783. CCommDeviceControl_GetMyDeviceOpenMode,
  784. CCommDeviceControl_WriteToErrorLog,
  785. Primary_Interface_End(CCommDeviceControl, IStiDeviceControl)