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.

948 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(CWDMDeviceControl, IStiDeviceControl);
  48. Interface_Template_Begin(CWDMDeviceControl)
  49. Primary_Interface_Template(CWDMDeviceControl, IStiDeviceControl)
  50. Interface_Template_End(CWDMDeviceControl)
  51. /*****************************************************************************
  52. *
  53. * @doc INTERNAL
  54. *
  55. * @struct CWDMDeviceControl |
  56. *
  57. * The <i CWDMDeviceControl> device object
  58. *
  59. *
  60. * @field IStiDeviceControl | stidev
  61. *
  62. * @comm
  63. *
  64. *
  65. *****************************************************************************/
  66. typedef struct CWDMDeviceControl {
  67. /* Supported interfaces */
  68. IStiDeviceControl devctl;
  69. DWORD dwVersion;
  70. DWORD dwDeviceType;
  71. DWORD dwMode;
  72. WCHAR wszPortName[MAX_PATH];
  73. DWORD dwFlags;
  74. DWORD dwContext;
  75. DWORD dwLastOperationError;
  76. HANDLE hDeviceHandle;
  77. HANDLE hDeviceControlHandle;
  78. } CWDMDeviceControl, *PCWDMDeviceControl;
  79. #define ThisClass CWDMDeviceControl
  80. #define ThisInterface IStiDeviceControl
  81. #ifdef DEBUG
  82. Default_QueryInterface(CWDMDeviceControl)
  83. Default_AddRef(CWDMDeviceControl)
  84. Default_Release(CWDMDeviceControl)
  85. #else
  86. #define CWDMDeviceControl_QueryInterface Common_QueryInterface
  87. #define CWDMDeviceControl_AddRef Common_AddRef
  88. #define CWDMDeviceControl_Release Common_Release
  89. #endif
  90. #define CWDMDeviceControl_QIHelper Common_QIHelper
  91. #pragma BEGIN_CONST_DATA
  92. #pragma END_CONST_DATA
  93. /*****************************************************************************
  94. *
  95. * @doc EXTERNAL
  96. *
  97. * @method HRESULT | CWDMDeviceControl | RawReadData |
  98. *
  99. * @parm | |
  100. *
  101. * @returns
  102. *
  103. * Returns a COM error code.
  104. *
  105. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  106. *
  107. *****************************************************************************/
  108. STDMETHODIMP
  109. CWDMDeviceControl_RawReadData(
  110. PSTIDEVICECONTROL pDev,
  111. LPVOID lpBuffer,
  112. LPDWORD lpdwNumberOfBytes,
  113. LPOVERLAPPED lpOverlapped
  114. )
  115. {
  116. HRESULT hres = STIERR_INVALID_PARAM;
  117. DWORD dwBytesReturned=0;
  118. BOOL fRet;
  119. EnterProc(CWDMDeviceControl_WDMRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
  120. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  121. PCWDMDeviceControl this = _thisPv(pDev);
  122. // Validate parameters here
  123. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) &&
  124. SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) &&
  125. (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
  126. // Call appropriate entry point
  127. fRet = ReadFile(this->hDeviceHandle,
  128. lpBuffer,
  129. *lpdwNumberOfBytes,
  130. lpdwNumberOfBytes,
  131. lpOverlapped
  132. );
  133. this->dwLastOperationError = GetLastError();
  134. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  135. }
  136. }
  137. ExitOleProc();
  138. return hres;
  139. }
  140. /*****************************************************************************
  141. *
  142. * @doc EXTERNAL
  143. *
  144. * @method HRESULT | CWDMDeviceControl | WDMRawWriteData |
  145. *
  146. * @parm | |
  147. *
  148. * @returns
  149. *
  150. * Returns a COM error code.
  151. *
  152. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  153. *
  154. *****************************************************************************/
  155. STDMETHODIMP
  156. CWDMDeviceControl_RawWriteData(
  157. PSTIDEVICECONTROL pDev,
  158. LPVOID lpBuffer,
  159. DWORD dwNumberOfBytes,
  160. LPOVERLAPPED lpOverlapped
  161. )
  162. {
  163. HRESULT hres = STIERR_INVALID_PARAM;
  164. DWORD dwBytesReturned=0;
  165. BOOL fRet;
  166. EnterProc(CWDMDeviceControl_WDMRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
  167. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  168. PCWDMDeviceControl this = _thisPv(pDev);
  169. // Validate parameters here
  170. hres = STIERR_INVALID_PARAM;
  171. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) {
  172. if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){
  173. // Call appropriate entry point
  174. fRet = WriteFile(this->hDeviceHandle,
  175. lpBuffer,
  176. dwNumberOfBytes,
  177. &dwBytesReturned,
  178. lpOverlapped
  179. );
  180. this->dwLastOperationError = GetLastError();
  181. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  182. }
  183. }
  184. }
  185. ExitOleProc();
  186. return hres;
  187. }
  188. /*****************************************************************************
  189. *
  190. * @doc EXTERNAL
  191. *
  192. * @method HRESULT | CWDMDeviceControl | RawReadControl |
  193. *
  194. * @parm | |
  195. *
  196. * @returns
  197. *
  198. * Returns a COM error code.
  199. *
  200. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  201. *
  202. *****************************************************************************/
  203. STDMETHODIMP
  204. CWDMDeviceControl_RawReadCommand(
  205. PSTIDEVICECONTROL pDev,
  206. LPVOID lpBuffer,
  207. LPDWORD lpdwNumberOfBytes,
  208. LPOVERLAPPED lpOverlapped
  209. )
  210. {
  211. HRESULT hres = STIERR_INVALID_PARAM;
  212. DWORD dwBytesReturned=0;
  213. BOOL fRet;
  214. EnterProc(CWDMDeviceControl_WDMRawReadData, (_ "pppp",pDev,lpBuffer,lpdwNumberOfBytes,lpOverlapped));
  215. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  216. PCWDMDeviceControl this = _thisPv(pDev);
  217. // Validate parameters here
  218. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwNumberOfBytes, 4, 3)) &&
  219. SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,*lpdwNumberOfBytes, 2)) &&
  220. (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4))) ){
  221. // Call appropriate entry point
  222. fRet = ReadFile(this->hDeviceControlHandle,
  223. lpBuffer,
  224. *lpdwNumberOfBytes,
  225. lpdwNumberOfBytes,
  226. lpOverlapped
  227. );
  228. this->dwLastOperationError = GetLastError();
  229. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  230. }
  231. }
  232. ExitOleProc();
  233. return hres;
  234. }
  235. /*****************************************************************************
  236. *
  237. * @doc EXTERNAL
  238. *
  239. * @method HRESULT | CWDMDeviceControl | WDMRawWriteData |
  240. *
  241. * @parm | |
  242. *
  243. * @returns
  244. *
  245. * Returns a COM error code.
  246. *
  247. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  248. *
  249. *****************************************************************************/
  250. STDMETHODIMP
  251. CWDMDeviceControl_RawWriteCommand(
  252. PSTIDEVICECONTROL pDev,
  253. LPVOID lpBuffer,
  254. DWORD dwNumberOfBytes,
  255. LPOVERLAPPED lpOverlapped
  256. )
  257. {
  258. HRESULT hres = STIERR_INVALID_PARAM;
  259. DWORD dwBytesReturned=0;
  260. BOOL fRet;
  261. EnterProc(CWDMDeviceControl_WDMRawWriteData, (_ "ppup",pDev,lpBuffer,dwNumberOfBytes,lpOverlapped));
  262. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  263. PCWDMDeviceControl this = _thisPv(pDev);
  264. // Validate parameters here
  265. hres = STIERR_INVALID_PARAM;
  266. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpBuffer,dwNumberOfBytes, 2)) ) {
  267. if (!lpOverlapped || SUCCEEDED(hres = hresFullValidReadPx(lpOverlapped, OVERLAPPED, 4)) ){
  268. // Call appropriate entry point
  269. fRet = WriteFile(this->hDeviceControlHandle,
  270. lpBuffer,
  271. dwNumberOfBytes,
  272. &dwBytesReturned,
  273. lpOverlapped
  274. );
  275. this->dwLastOperationError = GetLastError();
  276. hres = fRet ? STI_OK : HRESULT_FROM_WIN32(this->dwLastOperationError);
  277. }
  278. }
  279. }
  280. ExitOleProc();
  281. return hres;
  282. }
  283. /*****************************************************************************
  284. *
  285. * @doc EXTERNAL
  286. *
  287. * @method HRESULT | CWDMDeviceControl | RawReadControl |
  288. *
  289. * @parm | |
  290. *
  291. * @returns
  292. *
  293. * Returns a COM error code.
  294. *
  295. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  296. *
  297. *****************************************************************************/
  298. STDMETHODIMP
  299. CWDMDeviceControl_GetLastError(
  300. PSTIDEVICECONTROL pDev,
  301. LPDWORD lpdwLastError
  302. )
  303. {
  304. HRESULT hres = STIERR_INVALID_PARAM;
  305. DWORD dwBytesReturned=0;
  306. EnterProc(CWDMDeviceControl_GetLastError, (_ "pppp",pDev,lpdwLastError));
  307. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  308. PCWDMDeviceControl this = _thisPv(pDev);
  309. // Validate parameters here
  310. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpdwLastError,4, 2))) {
  311. *lpdwLastError = this->dwLastOperationError ;
  312. hres = STI_OK;
  313. }
  314. }
  315. ExitOleProc();
  316. return hres;
  317. }
  318. /*****************************************************************************
  319. *
  320. * @doc EXTERNAL
  321. *
  322. * @method HRESULT | CWDMDeviceControl | GetMyDevicePortName |
  323. *
  324. * @parm | |
  325. *
  326. * @returns
  327. *
  328. * Returns a COM error code.
  329. *
  330. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  331. *
  332. *****************************************************************************/
  333. STDMETHODIMP
  334. CWDMDeviceControl_GetMyDevicePortName(
  335. PSTIDEVICECONTROL pDev,
  336. LPWSTR lpszDevicePath,
  337. DWORD cwDevicePathSize
  338. )
  339. {
  340. HRESULT hres = STIERR_INVALID_PARAM;
  341. DWORD dwBytesReturned=0;
  342. EnterProc(CWDMDeviceControl_GetMyDevicePortName, (_ "pp",pDev,lpszDevicePath));
  343. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  344. PCWDMDeviceControl this = _thisPv(pDev);
  345. // Validate parameters here
  346. if (SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,4, 2)) &&
  347. SUCCEEDED(hres = hresFullValidReadPvCb(lpszDevicePath,sizeof(WCHAR)*cwDevicePathSize, 2)) ) {
  348. if (cwDevicePathSize > OSUtil_StrLenW(this->wszPortName)) {
  349. OSUtil_lstrcpyW(lpszDevicePath,this->wszPortName);
  350. hres = STI_OK;
  351. }
  352. else {
  353. hres = HRESULT_FROM_WIN32(ERROR_MORE_DATA);
  354. }
  355. }
  356. }
  357. ExitOleProc();
  358. return hres;
  359. }
  360. /*****************************************************************************
  361. *
  362. * @doc EXTERNAL
  363. *
  364. * @method HRESULT | CWDMDeviceControl | GetMyDeviceHandle |
  365. *
  366. * @parm | |
  367. *
  368. * @returns
  369. *
  370. * Returns a COM error code.
  371. *
  372. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  373. *
  374. *****************************************************************************/
  375. STDMETHODIMP
  376. CWDMDeviceControl_GetMyDeviceHandle(
  377. PSTIDEVICECONTROL pDev,
  378. LPHANDLE pHandle
  379. )
  380. {
  381. HRESULT hres = STIERR_INVALID_PARAM;
  382. DWORD dwBytesReturned=0;
  383. EnterProc(CWDMDeviceControl_GetMyDeviceHandle, (_ "pp",pDev,pHandle));
  384. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  385. PCWDMDeviceControl this = _thisPv(pDev);
  386. // Validate parameters here
  387. if (SUCCEEDED(hres = hresFullValidReadPvCb(pHandle,4, 2)) ) {
  388. if (INVALID_HANDLE_VALUE != this->hDeviceHandle) {
  389. *pHandle = this->hDeviceHandle;
  390. hres = STI_OK;
  391. }
  392. else {
  393. hres = HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
  394. }
  395. }
  396. }
  397. ExitOleProc();
  398. return hres;
  399. }
  400. /*****************************************************************************
  401. *
  402. * @doc EXTERNAL
  403. *
  404. * @method HRESULT | CWDMDeviceControl | pdwOpenMode |
  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. CWDMDeviceControl_GetMyDeviceOpenMode(
  417. PSTIDEVICECONTROL pDev,
  418. LPDWORD pdwOpenMode
  419. )
  420. {
  421. HRESULT hres = STIERR_INVALID_PARAM;
  422. DWORD dwBytesReturned=0;
  423. EnterProc(CWDMDeviceControl_GetMyDeviceOpenMode, (_ "pp",pDev,pdwOpenMode));
  424. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  425. PCWDMDeviceControl this = _thisPv(pDev);
  426. // Validate parameters here
  427. if (SUCCEEDED(hres = hresFullValidReadPvCb(pdwOpenMode,4, 2)) ) {
  428. *pdwOpenMode = this->dwMode;
  429. hres = STI_OK;
  430. }
  431. }
  432. ExitOleProc();
  433. return hres;
  434. }
  435. /*****************************************************************************
  436. *
  437. * @doc EXTERNAL
  438. *
  439. * @method HRESULT | CWDMDeviceControl | RawReadControl |
  440. *
  441. * @parm | |
  442. *
  443. * @returns
  444. *
  445. * Returns a COM error code.
  446. *
  447. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  448. *
  449. *****************************************************************************/
  450. STDMETHODIMP
  451. CWDMDeviceControl_RawDeviceControl(
  452. PSTIDEVICECONTROL pDev,
  453. USD_CONTROL_CODE EscapeFunction,
  454. LPVOID lpInData,
  455. DWORD cbInDataSize,
  456. LPVOID pOutData,
  457. DWORD dwOutDataSize,
  458. LPDWORD pdwActualData
  459. )
  460. {
  461. HRESULT hres = STIERR_INVALID_PARAM;
  462. DWORD dwBytesReturned=0;
  463. EnterProc(CWDMDeviceControl_RawDeviceControl, (_ "p",pDev));
  464. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  465. PCWDMDeviceControl this = _thisPv(pDev);
  466. // Validate parameters here
  467. hres = STIERR_UNSUPPORTED;
  468. }
  469. ExitOleProc();
  470. return hres;
  471. }
  472. /*****************************************************************************
  473. *
  474. * @doc EXTERNAL
  475. *
  476. * @method HRESULT | CWDMDeviceControl | WriteToErrorLog |
  477. *
  478. * @parm | |
  479. *
  480. * @returns
  481. *
  482. * Returns a COM error code.
  483. *
  484. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  485. *
  486. *****************************************************************************/
  487. STDMETHODIMP
  488. CWDMDeviceControl_WriteToErrorLog(
  489. PSTIDEVICECONTROL pDev,
  490. DWORD dwMessageType,
  491. LPCWSTR pszMessage,
  492. DWORD dwErrorCode
  493. )
  494. {
  495. HRESULT hres = STIERR_INVALID_PARAM;
  496. DWORD dwBytesReturned=0;
  497. EnterProc(CWDMDeviceControl_WriteToErrorLog, (_ "p",pDev));
  498. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  499. PCWDMDeviceControl this = _thisPv(pDev);
  500. //
  501. // Validate parameters here
  502. //
  503. if (SUCCEEDED(hres = hresFullValidReadPvCb(pszMessage,2, 3))) {
  504. #ifdef UNICODE
  505. ReportStiLogMessage(g_hStiFileLog,
  506. dwMessageType,
  507. pszMessage
  508. );
  509. #else
  510. LPTSTR lpszAnsi = NULL;
  511. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszAnsi,pszMessage))) {
  512. ReportStiLogMessage(g_hStiFileLog,
  513. dwMessageType,
  514. lpszAnsi
  515. );
  516. FreePpv(&lpszAnsi);
  517. }
  518. #endif
  519. }
  520. }
  521. ExitOleProc();
  522. return hres;
  523. }
  524. /*****************************************************************************
  525. *
  526. * @doc EXTERNAL
  527. *
  528. * @mfunc HRESULT | CWDMDeviceControl | Initialize |
  529. *
  530. * Initialize a DeviceControl object.
  531. *
  532. * @cwrap PSTIDEVICECONTROL | pDev
  533. *
  534. * @returns
  535. * Returns a COM error code. The following error codes are
  536. * intended to be illustrative and not necessarily comprehensive.
  537. *
  538. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  539. *
  540. * <c S_FALSE>: The device had already been initialized with
  541. * the instance GUID passed in <p lpGUID>.
  542. *
  543. *
  544. *****************************************************************************/
  545. STDMETHODIMP
  546. CWDMDeviceControl_Initialize(
  547. PSTIDEVICECONTROL pDev,
  548. DWORD dwDeviceType,
  549. DWORD dwDeviceMode,
  550. LPCWSTR pwszPortName,
  551. DWORD dwFlags
  552. )
  553. {
  554. HRESULT hres = STI_OK;
  555. WCHAR wszDeviceSymbolicName[MAX_PATH] = {L'\0'};
  556. //LPSTR pszAnsiDeviceName;
  557. EnterProcR(CWDMDeviceControl::Initialize,(_ "pp", pDev, pwszPortName));
  558. if (SUCCEEDED(hres = hresPvI(pDev, ThisInterface))) {
  559. PCWDMDeviceControl this = _thisPv(pDev);
  560. this->dwDeviceType = dwDeviceType;
  561. lstrcpynW(this->wszPortName,pwszPortName, sizeof(this->wszPortName) / sizeof(this->wszPortName[0]));
  562. //
  563. // Create symbolic name for the device we are trying to talk to
  564. // Try to open device data and control handles.
  565. //
  566. this->dwMode = dwDeviceMode;
  567. if (dwFlags & STI_HEL_OPEN_DATA) {
  568. OSUtil_lstrcatW(wszDeviceSymbolicName,this->wszPortName);
  569. // For devices with separate channels open them specially. Kernel mode
  570. // driver will need to understand convention
  571. // OSUtil_lstrcatW(wszDeviceSymbolicName,L"\\Data");
  572. this->hDeviceHandle = OSUtil_CreateFileW(wszDeviceSymbolicName,
  573. GENERIC_READ | GENERIC_WRITE, // Access mask
  574. 0, // Share mode
  575. NULL, // SA
  576. OPEN_EXISTING, // Create disposition
  577. FILE_ATTRIBUTE_SYSTEM, // Attributes
  578. NULL // Template
  579. );
  580. this->dwLastOperationError = GetLastError();
  581. hres = (this->hDeviceHandle != INVALID_HANDLE_VALUE) ?
  582. S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,this->dwLastOperationError);
  583. }
  584. //
  585. // If needed open control handle for the device
  586. //
  587. if (SUCCEEDED(hres) && (dwFlags & STI_HEL_OPEN_CONTROL)) {
  588. OSUtil_lstrcpyW(wszDeviceSymbolicName,REGSTR_PATH_STIDEVICES_W);
  589. OSUtil_lstrcatW(wszDeviceSymbolicName,L"\\");
  590. OSUtil_lstrcatW(wszDeviceSymbolicName,this->wszPortName);
  591. // For devices with separate channels open them specially. Kernel mode
  592. // driver will need to understand convention
  593. // OSUtil_lstrcatW(wszDeviceSymbolicName,L"\\Control");
  594. this->hDeviceControlHandle = OSUtil_CreateFileW(wszDeviceSymbolicName,
  595. GENERIC_READ | GENERIC_WRITE, // Access mask
  596. 0, // Share mode
  597. NULL, // SA
  598. OPEN_EXISTING, // Create disposition
  599. FILE_ATTRIBUTE_SYSTEM, // Attributes
  600. NULL // Template
  601. );
  602. this->dwLastOperationError = GetLastError();
  603. hres = (this->hDeviceControlHandle != INVALID_HANDLE_VALUE) ?
  604. S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,this->dwLastOperationError);
  605. }
  606. }
  607. ExitOleProc();
  608. return hres;
  609. }
  610. /*****************************************************************************
  611. *
  612. * @doc INTERNAL
  613. *
  614. * @mfunc void | CWDMDeviceControl | Init |
  615. *
  616. * Initialize the internal parts of the StiDevice object.
  617. *
  618. *****************************************************************************/
  619. void INLINE
  620. CWDMDeviceControl_Init(
  621. PCWDMDeviceControl this
  622. )
  623. {
  624. // Initialize instance variables
  625. this->dwContext = 0L;
  626. this->dwLastOperationError = NO_ERROR;
  627. this->hDeviceHandle = INVALID_HANDLE_VALUE;
  628. this->hDeviceControlHandle = INVALID_HANDLE_VALUE;
  629. }
  630. /*****************************************************************************
  631. *
  632. * @doc INTERNAL
  633. *
  634. * @func void | CWDMDeviceControl_Finalize |
  635. *
  636. * Releases the resources of a generic device.
  637. *
  638. * @parm PV | pvObj |
  639. *
  640. * Object being released. Note that it may not have been
  641. * completely initialized, so everything should be done
  642. * carefully.
  643. *
  644. *****************************************************************************/
  645. void INTERNAL
  646. CWDMDeviceControl_Finalize(PV pvObj)
  647. {
  648. HRESULT hres = STI_OK;
  649. PCWDMDeviceControl this = pvObj;
  650. // Close device handles
  651. if (IsValidHANDLE(this->hDeviceHandle)) {
  652. CloseHandle(this->hDeviceHandle);
  653. }
  654. if (IsValidHANDLE(this->hDeviceControlHandle)) {
  655. CloseHandle(this->hDeviceControlHandle );
  656. }
  657. this->dwContext = 0L;
  658. this->dwLastOperationError = NO_ERROR;
  659. this->hDeviceHandle = INVALID_HANDLE_VALUE;
  660. this->hDeviceControlHandle = INVALID_HANDLE_VALUE;
  661. }
  662. /*****************************************************************************
  663. *
  664. * @doc INTERNAL
  665. *
  666. * @mfunc HRESULT | CWDMDeviceControl | New |
  667. *
  668. * Create a new IDeviceControl object, uninitialized.
  669. *
  670. * @parm IN PUNK | punkOuter |
  671. *
  672. * Controlling unknown for aggregation.
  673. *
  674. * @parm IN RIID | riid |
  675. *
  676. * Desired interface to new object.
  677. *
  678. * @parm OUT PPV | ppvObj |
  679. *
  680. * Output pointer for new object.
  681. *
  682. *****************************************************************************/
  683. STDMETHODIMP
  684. CWDMDeviceControl_New(PUNK punkOuter, RIID riid, PPV ppvObj)
  685. {
  686. HRESULT hres;
  687. EnterProcR(CWDMDeviceControl::<constructor>, (_ "Gp", riid, punkOuter));
  688. hres = Common_NewRiid(CWDMDeviceControl, punkOuter, riid, ppvObj);
  689. if (SUCCEEDED(hres)) {
  690. PCWDMDeviceControl this = _thisPv(*ppvObj);
  691. CWDMDeviceControl_Init(this);
  692. }
  693. ExitOleProcPpvR(ppvObj);
  694. return hres;
  695. }
  696. /*****************************************************************************
  697. *
  698. * @doc INTERNAL
  699. *
  700. * @func HRESULT | NewDeviceControl |
  701. *
  702. * Creates and initializes DCB for given device.
  703. *
  704. *****************************************************************************/
  705. STDMETHODIMP
  706. NewDeviceControl(
  707. DWORD dwDeviceType,
  708. DWORD dwDeviceMode,
  709. LPCWSTR pwszPortName,
  710. DWORD dwFlags,
  711. PSTIDEVICECONTROL *ppDevCtl
  712. )
  713. {
  714. HRESULT hres = STI_OK;
  715. EnterProc(NewDeviceControl,(_ "xpp", dwDeviceType,pwszPortName,ppDevCtl));
  716. // Validate device type
  717. #ifdef DEBUG
  718. hres = STI_OK;
  719. switch (dwDeviceType) {
  720. case HEL_DEVICE_TYPE_WDM:
  721. break;
  722. case HEL_DEVICE_TYPE_PARALLEL:
  723. break;
  724. case HEL_DEVICE_TYPE_SERIAL:
  725. break;
  726. default:
  727. ValidateF(0,("Invalid dwvice type passed to DcbNew"));
  728. return STIERR_INVALID_PARAM;
  729. }
  730. // Validate string
  731. if (!pwszPortName || !*pwszPortName) {
  732. //AssertF(0,("Invalid device name passed to DcbNew"));
  733. hres = STIERR_INVALID_PARAM;
  734. }
  735. else {
  736. hres = hresFullValidPdwOut(ppDevCtl,3);
  737. }
  738. #else
  739. if (!pwszPortName || !*pwszPortName) {
  740. hres = STIERR_INVALID_PARAM;
  741. }
  742. #endif
  743. if (SUCCEEDED(hres)) {
  744. //
  745. // Now call appropriate initialization routine
  746. //
  747. switch (dwDeviceType) {
  748. case HEL_DEVICE_TYPE_WDM:
  749. case HEL_DEVICE_TYPE_PARALLEL:
  750. hres = CWDMDeviceControl_New(NULL, &IID_IStiDeviceControl,ppDevCtl);
  751. break;
  752. case HEL_DEVICE_TYPE_SERIAL:
  753. hres = CCommDeviceControl_New(NULL, &IID_IStiDeviceControl,ppDevCtl);
  754. break;
  755. default:
  756. ValidateF(0,("Invalid device type passed to DcbNew"));
  757. return STIERR_INVALID_PARAM;
  758. }
  759. }
  760. if (SUCCEEDED(hres)) {
  761. hres = IStiDeviceControl_Initialize(*ppDevCtl,dwDeviceType,dwDeviceMode,pwszPortName,dwFlags);
  762. }
  763. ExitOleProc();
  764. return hres;
  765. }
  766. /*****************************************************************************
  767. *
  768. * The long-awaited vtbls and templates
  769. *
  770. *****************************************************************************/
  771. #pragma BEGIN_CONST_DATA
  772. #define CWDMDeviceControl_Signature (DWORD)'WDM'
  773. Primary_Interface_Begin(CWDMDeviceControl, IStiDeviceControl)
  774. CWDMDeviceControl_Initialize,
  775. CWDMDeviceControl_RawReadData,
  776. CWDMDeviceControl_RawWriteData,
  777. CWDMDeviceControl_RawReadCommand,
  778. CWDMDeviceControl_RawWriteCommand,
  779. CWDMDeviceControl_RawDeviceControl,
  780. CWDMDeviceControl_GetLastError,
  781. CWDMDeviceControl_GetMyDevicePortName,
  782. CWDMDeviceControl_GetMyDeviceHandle,
  783. CWDMDeviceControl_GetMyDeviceOpenMode,
  784. CWDMDeviceControl_WriteToErrorLog,
  785. Primary_Interface_End(CWDMDeviceControl, IStiDeviceControl)