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.

985 lines
23 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. ksacapi.c
  5. Abstract:
  6. Kernel mode SAC api
  7. Author:
  8. Brian Guarraci (briangu), 2001
  9. Revision History:
  10. --*/
  11. #include "ksacapip.h"
  12. #include <ksacapi.h>
  13. #include <ntddsac.h>
  14. //
  15. // Machine Information table and routines.
  16. //
  17. #define INIT_OBJA(Obja,UnicodeString,UnicodeText) \
  18. \
  19. RtlInitUnicodeString((UnicodeString),(UnicodeText)); \
  20. \
  21. InitializeObjectAttributes( \
  22. (Obja), \
  23. (UnicodeString), \
  24. OBJ_CASE_INSENSITIVE, \
  25. NULL, \
  26. NULL \
  27. )
  28. //
  29. // Memory management routine aliases
  30. //
  31. #define KSAC_API_ALLOCATE_MEMORY(_s)
  32. #define KSAC_API_FREE_MEMORY(_p)
  33. #define KSAC_API_ASSERT(c,s)\
  34. ASSERT(c);\
  35. if (!(c)) {\
  36. return s;\
  37. }
  38. #define KSAC_VALIDATE_CHANNEL_HANDLE(_h)\
  39. KSAC_API_ASSERT( \
  40. _h->ChannelHandle->DriverHandle, \
  41. STATUS_INVALID_PARAMETER_1 \
  42. ); \
  43. KSAC_API_ASSERT( \
  44. _h->ChannelHandle->DriverHandle != INVALID_HANDLE_VALUE, \
  45. STATUS_INVALID_PARAMETER_1 \
  46. ); \
  47. KSAC_API_ASSERT( \
  48. _h->SacEventHandle != INVALID_HANDLE_VALUE, \
  49. STATUS_INVALID_PARAMETER_1 \
  50. ); \
  51. KSAC_API_ASSERT( \
  52. _h->SacEvent != NULL, \
  53. STATUS_INVALID_PARAMETER_1 \
  54. );
  55. NTSTATUS
  56. KSacHandleOpen(
  57. OUT HANDLE* SacHandle,
  58. OUT HANDLE* SacEventHandle,
  59. OUT PKEVENT* SacEvent
  60. )
  61. /*++
  62. Routine Description:
  63. This routine opens a handle to the SAC driver and
  64. creates and initializes an associated syncrhonization event.
  65. Arguments:
  66. SacHandle - the driver handle
  67. SacEventHandle - the event handle
  68. SacEvent - the sac event
  69. Return Value:
  70. Status
  71. --*/
  72. {
  73. NTSTATUS Status;
  74. OBJECT_ATTRIBUTES ObjAttr;
  75. UNICODE_STRING UnicodeString;
  76. IO_STATUS_BLOCK IoStatusBlock;
  77. KSAC_API_ASSERT(SacHandle == NULL, STATUS_INVALID_PARAMETER_1);
  78. KSAC_API_ASSERT(SacEventHandle == NULL, STATUS_INVALID_PARAMETER_2);
  79. KSAC_API_ASSERT(SacEvent == NULL, STATUS_INVALID_PARAMETER_3);
  80. //
  81. // Open the SAC driver
  82. //
  83. INIT_OBJA(&ObjAttr, &UnicodeString, L"\\Device\\SAC");
  84. Status = ZwCreateFile(
  85. *SacHandle,
  86. GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
  87. &ObjAttr,
  88. &IoStatusBlock,
  89. NULL,
  90. FILE_ATTRIBUTE_NORMAL,
  91. FILE_SHARE_READ | FILE_SHARE_WRITE,
  92. FILE_OPEN,
  93. 0,
  94. NULL,
  95. 0
  96. );
  97. if (!NT_SUCCESS(Status)) {
  98. return Status;
  99. }
  100. //
  101. // Initialize the SAC Kernel event
  102. //
  103. RtlInitUnicodeString(&UnicodeString, L"\\SetupDDSacEvent");
  104. *SacEvent = IoCreateSynchronizationEvent(
  105. &UnicodeString,
  106. SacEventHandle
  107. );
  108. if (*SacEvent == NULL) {
  109. ZwClose(*SacHandle);
  110. return STATUS_UNSUCCESSFUL;
  111. }
  112. return STATUS_SUCCESS;
  113. }
  114. NTSTATUS
  115. KSacHandleClose(
  116. IN OUT HANDLE* SacHandle,
  117. IN OUT HANDLE* SacEventHandle,
  118. IN OUT PKEVENT* SacEvent
  119. )
  120. /*++
  121. Routine Description:
  122. This routine closes a handle to the SAC driver and
  123. closes the associated syncrhonization event.
  124. Arguments:
  125. SacHandle - the driver handle
  126. SacEventHandle - the event handle
  127. SacEvent - the sac event
  128. Return Value:
  129. Status
  130. --*/
  131. {
  132. KSAC_API_ASSERT(*SacHandle != NULL, STATUS_INVALID_PARAMETER_1);
  133. KSAC_API_ASSERT(*SacEventHandle != NULL, STATUS_INVALID_PARAMETER_2);
  134. UNREFERENCED_PARAMETER(SacEvent);
  135. ZwClose(*SacHandle);
  136. ZwClose(*SacEventHandle);
  137. //
  138. // Null the handles
  139. //
  140. *SacEventHandle = NULL;
  141. *SacHandle = NULL;
  142. return STATUS_SUCCESS;
  143. }
  144. NTSTATUS
  145. KSacChannelOpen(
  146. OUT PKSAC_CHANNEL_HANDLE SacChannelHandle,
  147. IN PSAC_CHANNEL_OPEN_ATTRIBUTES SacChannelAttributes
  148. )
  149. /*++
  150. Routine Description:
  151. This routine opens a SAC channel with the specified attributes.
  152. Arguments:
  153. SacChannelHandle - on success, contains the handle to the new channel
  154. SacChannelAttributes - the attributes of the new channel
  155. Return Value:
  156. Status
  157. --*/
  158. {
  159. NTSTATUS Status;
  160. OBJECT_ATTRIBUTES ObjAttr;
  161. UNICODE_STRING UnicodeString;
  162. IO_STATUS_BLOCK IoStatusBlock;
  163. ULONG OpenChannelCmdSize;
  164. PSAC_CMD_OPEN_CHANNEL OpenChannelCmd;
  165. SAC_RSP_OPEN_CHANNEL OpenChannelRsp;
  166. HANDLE DriverHandle;
  167. HANDLE SacEventHandle;
  168. PKEVENT SacEvent;
  169. KSAC_API_ASSERT(SacChannelHandle != NULL, STATUS_INVALID_PARAMETER_1);
  170. KSAC_API_ASSERT(SacChannelAttributes != NULL, STATUS_INVALID_PARAMETER_2);
  171. //
  172. // default: we didn't get a valid handle
  173. //
  174. RtlZeroMemory(SacChannelHandle, sizeof(KSAC_CHANNEL_HANDLE));
  175. //
  176. // Verify that if the user wants to use the CLOSE_EVENT, we received one to use
  177. //
  178. KSAC_API_ASSERT(
  179. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT)
  180. && SacChannelAttributes->CloseEvent) ||
  181. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT)
  182. && !SacChannelAttributes->CloseEvent),
  183. STATUS_INVALID_PARAMETER_2
  184. );
  185. //
  186. // Verify that if the user wants to use the HAS_NEW_DATA_EVENT, we received one to use
  187. //
  188. KSAC_API_ASSERT(
  189. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
  190. && SacChannelAttributes->HasNewDataEvent) ||
  191. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
  192. && !SacChannelAttributes->HasNewDataEvent),
  193. STATUS_INVALID_PARAMETER_2
  194. );
  195. #if ENABLE_CHANNEL_LOCKING
  196. //
  197. // Verify that if the user wants to use the LOCK_EVENT, we received one to use
  198. //
  199. KSAC_API_ASSERT(
  200. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT)
  201. && SacChannelAttributes->LockEvent) ||
  202. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT)
  203. && !SacChannelAttributes->LockEvent),
  204. STATUS_INVALID_PARAMETER_2
  205. );
  206. #endif
  207. //
  208. // Verify that if the user wants to use the REDRAW_EVENT, we received one to use
  209. //
  210. KSAC_API_ASSERT(
  211. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT)
  212. && SacChannelAttributes->RedrawEvent) ||
  213. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT)
  214. && !SacChannelAttributes->RedrawEvent),
  215. STATUS_INVALID_PARAMETER_2
  216. );
  217. //
  218. // If the channel type isn't cmd,
  219. // then make sure they sent us a name.
  220. //
  221. if (SacChannelAttributes->Type != ChannelTypeCmd) {
  222. KSAC_API_ASSERT(SacChannelAttributes->Name, STATUS_INVALID_PARAMETER_2);
  223. } else {
  224. //
  225. // Make sure they didn't pass us a name or description.
  226. //
  227. KSAC_API_ASSERT(SacChannelAttributes->Name == NULL, STATUS_INVALID_PARAMETER_2);
  228. KSAC_API_ASSERT(SacChannelAttributes->Description == NULL, STATUS_INVALID_PARAMETER_2);
  229. }
  230. //
  231. // create the Open Channel message structure
  232. //
  233. OpenChannelCmdSize = sizeof(SAC_CMD_OPEN_CHANNEL);
  234. OpenChannelCmd = (PSAC_CMD_OPEN_CHANNEL)KSAC_API_ALLOCATE_MEMORY(OpenChannelCmdSize);
  235. ASSERT(OpenChannelCmd);
  236. if (!OpenChannelCmd) {
  237. return STATUS_NO_MEMORY;
  238. }
  239. RtlZeroMemory(OpenChannelCmd, OpenChannelCmdSize);
  240. //
  241. // default: we failed
  242. //
  243. Status = STATUS_UNSUCCESSFUL;
  244. //
  245. // Attempt to open the new channel
  246. //
  247. do {
  248. //
  249. // initialize the Open Channel message structure
  250. //
  251. OpenChannelCmd->Attributes = SacChannelAttributes;
  252. //
  253. // Get a handle to the SAC driver
  254. //
  255. Status = KSacHandleOpen(
  256. &DriverHandle,
  257. &SacEventHandle,
  258. &SacEvent
  259. );
  260. if (!NT_SUCCESS(Status)) {
  261. break;
  262. }
  263. //
  264. // Send down an IOCTL for opening a channel
  265. //
  266. Status = ZwDeviceIoControlFile(
  267. DriverHandle,
  268. SacEventHandle,
  269. NULL,
  270. NULL,
  271. &IoStatusBlock,
  272. IOCTL_SAC_OPEN_CHANNEL,
  273. OpenChannelCmd,
  274. OpenChannelCmdSize,
  275. &OpenChannelRsp,
  276. sizeof(OpenChannelRsp)
  277. );
  278. if (Status == STATUS_PENDING) {
  279. LARGE_INTEGER TimeOut;
  280. TimeOut.QuadPart = Int32x32To64((LONG)90000, -1000);
  281. Status = KeWaitForSingleObject(
  282. SacEvent,
  283. Executive,
  284. KernelMode,
  285. FALSE,
  286. &TimeOut
  287. );
  288. if (Status == STATUS_SUCCESS) {
  289. Status = IoStatusBlock.Status;
  290. }
  291. }
  292. if (!NT_SUCCESS(Status)) {
  293. KSacClose(
  294. &DriverHandle,
  295. &SacEventHandle,
  296. &SacEvent
  297. );
  298. break;
  299. }
  300. //
  301. // the new channel was created, so pass back the handle to it
  302. //
  303. SacChannelHandle->ChannelHandle->DriverHandle = DriverHandle;
  304. SacChannelHandle->ChannelHandle->ChannelHandle = OpenChannelRsp.Handle;
  305. SacChannelHandle->SacEventHandle = SacEventHandle;
  306. SacChannelHandle->SacEvent = SacEvent;
  307. } while ( FALSE );
  308. //
  309. // we are done with the cmd structure
  310. //
  311. FREE_POOL(OpenChannelCmd);
  312. return Status;
  313. }
  314. NTSTATUS
  315. KSacChannelClose(
  316. IN OUT PKSAC_CHANNEL_HANDLE SacChannelHandle
  317. )
  318. /*++
  319. Routine Description:
  320. Arguments:
  321. None.
  322. Return Value:
  323. None.
  324. --*/
  325. {
  326. NTSTATUS Status;
  327. IO_STATUS_BLOCK IoStatusBlock;
  328. SAC_CMD_CLOSE_CHANNEL CloseChannelCmd;
  329. KSAC_VALIDATE_CHANNEL_HANDLE(SacChannelHandle);
  330. //
  331. // Get the channel handle
  332. //
  333. CloseChannelCmd.Handle.ChannelHandle = SacChannelHandle->ChannelHandle->ChannelHandle;
  334. //
  335. // Send down an IOCTL for closing a channel
  336. //
  337. Status = ZwDeviceIoControlFile(
  338. SacChannelHandle->ChannelHandle->DriverHandle,
  339. SacChannelHandle->SacEventHandle,
  340. NULL,
  341. NULL,
  342. &IoStatusBlock,
  343. IOCTL_SAC_CLOSE_CHANNEL,
  344. &CloseChannelCmd,
  345. sizeof(CloseChannelCmd),
  346. NULL,
  347. 0
  348. );
  349. if (Status == STATUS_PENDING) {
  350. LARGE_INTEGER TimeOut;
  351. TimeOut.QuadPart = Int32x32To64((LONG)90000, -1000);
  352. Status = KeWaitForSingleObject(
  353. SacChannelHandle->SacEvent,
  354. Executive,
  355. KernelMode,
  356. FALSE,
  357. &TimeOut
  358. );
  359. if (Status == STATUS_SUCCESS) {
  360. Status = IoStatusBlock.Status;
  361. }
  362. }
  363. //
  364. // Close the driver handle
  365. //
  366. KSacHandleClose(
  367. &SacChannelHandle->ChannelHandle->DriverHandle,
  368. &SacChannelHandle->SacEventHandle,
  369. &SacChannelHandle->SacEvent
  370. );
  371. //
  372. // Null the channel handle since it is no longer valid
  373. //
  374. RtlZeroMemory(SacChannelHandle, sizeof(KSAC_CHANNEL_HANDLE));
  375. return Status;
  376. }
  377. NTSTATUS
  378. KSacChannelWrite(
  379. IN PKSAC_CHANNEL_HANDLE SacChannelHandle,
  380. IN PCBYTE Buffer,
  381. IN ULONG BufferSize
  382. )
  383. /*++
  384. Routine Description:
  385. Write the given buffer to the specified SAC Channel
  386. Arguments:
  387. SacChannelHandle - The channel to write the buffer to
  388. Buffer - data buffer
  389. BufferSize - size of the buffer
  390. Return Value:
  391. Status
  392. --*/
  393. {
  394. NTSTATUS Status;
  395. IO_STATUS_BLOCK IoStatusBlock;
  396. ULONG WriteChannelCmdSize;
  397. PSAC_CMD_WRITE_CHANNEL WriteChannelCmd;
  398. KSAC_VALIDATE_CHANNEL_HANDLE(SacChannelHandle);
  399. KSAC_API_ASSERT(Buffer, STATUS_INVALID_PARAMETER_2);
  400. //
  401. // initialize the Write To Channel message structure
  402. //
  403. WriteChannelCmdSize = sizeof(SAC_CMD_WRITE_CHANNEL) + (BufferSize * sizeof(UCHAR));
  404. WriteChannelCmd = (PSAC_CMD_WRITE_CHANNEL)KSAC_API_ALLOCATE_MEMORY(WriteChannelCmdSize);
  405. KSAC_API_ASSERT(WriteChannelCmd, FALSE);
  406. //
  407. // Zero the command structure
  408. //
  409. RtlZeroMemory(WriteChannelCmd, WriteChannelCmdSize);
  410. //
  411. // Set the length of the string to send
  412. //
  413. // Note: Size does not include the terminating NULL,
  414. // becase we don't want to send that.
  415. //
  416. WriteChannelCmd->Size = BufferSize;
  417. //
  418. // Set the buffer to be written
  419. //
  420. WriteChannelCmd->Buffer = Buffer;
  421. //
  422. // Indicate which channel this command is for
  423. //
  424. WriteChannelCmd->Handle.ChannelHandle = SacChannelHandle->ChannelHandle->ChannelHandle;
  425. //
  426. // Send the string to the channel
  427. //
  428. Status = ZwDeviceIoControlFile(
  429. SacChannelHandle->ChannelHandle->DriverHandle,
  430. SacChannelHandle->SacEventHandle,
  431. NULL,
  432. NULL,
  433. &IoStatusBlock,
  434. IOCTL_SAC_WRITE_CHANNEL,
  435. WriteChannelCmd,
  436. WriteChannelCmdSize,
  437. NULL,
  438. 0
  439. );
  440. if (Status == STATUS_PENDING) {
  441. LARGE_INTEGER TimeOut;
  442. TimeOut.QuadPart = Int32x32To64((LONG)90000, -1000);
  443. Status = KeWaitForSingleObject(
  444. SacChannelHandle->SacEvent,
  445. Executive,
  446. KernelMode,
  447. FALSE,
  448. &TimeOut
  449. );
  450. if (Status == STATUS_SUCCESS) {
  451. Status = IoStatusBlock.Status;
  452. }
  453. }
  454. return Status;
  455. }
  456. NTSTATUS
  457. KSacChannelRawWrite(
  458. IN KSAC_CHANNEL_HANDLE SacChannelHandle,
  459. IN PCBYTE Buffer,
  460. IN ULONG BufferSize
  461. )
  462. /*++
  463. Routine Description:
  464. Write the given buffer to the specified SAC Channel
  465. Arguments:
  466. SacChannelHandle - The channel to write the buffer to
  467. Buffer - data buffer
  468. BufferSize - size of the buffer
  469. Return Value:
  470. Status
  471. --*/
  472. {
  473. //
  474. // relay the write to the actual write routine
  475. //
  476. return KSacChannelWrite(
  477. SacChannelHandle,
  478. Buffer,
  479. BufferSize
  480. );
  481. }
  482. NTSTATUS
  483. KSacChannelVTUTF8WriteString(
  484. IN KSAC_CHANNEL_HANDLE SacChannelHandle,
  485. IN PCWSTR String
  486. )
  487. /*++
  488. Routine Description:
  489. This routine writes a null-terminated Unicode String to the specified Channel.
  490. Arguments:
  491. SacChannelHandle - The channel to write the buffer to
  492. String - A null-terminated Unicode string
  493. Return Value:
  494. Status
  495. TRUE --> the buffer was sent
  496. --*/
  497. {
  498. BOOL Status;
  499. ULONG BufferSize;
  500. //
  501. // Treating the String as a data buffer, we calculate it's size
  502. // not including the null termination
  503. //
  504. BufferSize = wcslen(String) * sizeof(WCHAR);
  505. KSAC_API_ASSERT(BufferSize > 0, FALSE);
  506. //
  507. // Write the data to the channel
  508. //
  509. Status = SacChannelWrite(
  510. SacChannelHandle,
  511. (PCBYTE)String,
  512. BufferSize
  513. );
  514. return Status;
  515. }
  516. NTSTATUS
  517. KSacChannelVTUTF8Write(
  518. IN KSAC_CHANNEL_HANDLE SacChannelHandle,
  519. IN PCWCHAR Buffer,
  520. IN ULONG BufferSize
  521. )
  522. /*++
  523. Routine Description:
  524. This routines writes an array of WCHAR to the VTUTF8 channel specified.
  525. Arguments:
  526. SacChannelHandle - The channel to write the buffer to
  527. Buffer - data buffer
  528. BufferSize - size of the buffer
  529. Note: Buffer is not null-terminated
  530. BufferSize should not count a null-termination.
  531. Return Value:
  532. Status
  533. --*/
  534. {
  535. //
  536. // relay the write to the actual write routine
  537. //
  538. return KSacChannelWrite(
  539. SacChannelHandle,
  540. (PCBYTE)Buffer,
  541. BufferSize
  542. );
  543. }
  544. NTSTATUS
  545. KSacChannelHasNewData(
  546. IN PKSAC_CHANNEL_HANDLE SacChannelHandle,
  547. OUT PBOOLEAN InputWaiting
  548. )
  549. /*++
  550. Routine Description:
  551. This routine checks to see if there is any waiting input for
  552. the channel specified by the handle
  553. Arguments:
  554. SacChannelHandle - the channel to write the string to
  555. InputWaiting - the input buffer status
  556. Return Value:
  557. Status
  558. --*/
  559. {
  560. HEADLESS_RSP_POLL Response;
  561. NTSTATUS Status;
  562. SIZE_T Length;
  563. IO_STATUS_BLOCK IoStatusBlock;
  564. SAC_CMD_POLL_CHANNEL PollChannelCmd;
  565. SAC_RSP_POLL_CHANNEL PollChannelRsp;
  566. KSAC_VALIDATE_KSAC_CHANNEL_HANDLE(SacChannelHandle);
  567. //
  568. // Initialize the Poll command
  569. //
  570. RtlZeroMemory(&PollChannelCmd, sizeof(SAC_RSP_POLL_CHANNEL));
  571. PollChannelCmd.Handle.ChannelHandle = SacChannelHandle->ChannelHandle->ChannelHandle;
  572. //
  573. // Send down an IOCTL for polling a channel
  574. //
  575. Status = ZwDeviceIoControlFile(
  576. SacChannelHandle->ChannelHandle->DriverHandle,
  577. SacChannelHandle->SacEventHandle,
  578. NULL,
  579. NULL,
  580. &IoStatusBlock,
  581. IOCTL_SAC_POLL_CHANNEL,
  582. &PollChannelCmd,
  583. sizeof(PollChannelCmd),
  584. &PollChannelRsp,
  585. sizeof(PollChannelRsp)
  586. );
  587. if (Status == STATUS_PENDING) {
  588. LARGE_INTEGER TimeOut;
  589. TimeOut.QuadPart = Int32x32To64((LONG)90000, -1000);
  590. Status = KeWaitForSingleObject(
  591. SacChannelHandle->SacEvent,
  592. Executive,
  593. KernelMode,
  594. FALSE,
  595. &TimeOut
  596. );
  597. if (Status == STATUS_SUCCESS) {
  598. Status = IoStatusBlock.Status;
  599. }
  600. }
  601. //
  602. // Return the status to the user
  603. //
  604. if (NT_SUCCESS(Status)) {
  605. *InputWaiting = PollChannelRsp.InputWaiting;
  606. } else {
  607. *InputWaiting = FALSE;
  608. }
  609. return Status;
  610. }
  611. NTSTATUS
  612. KSacChannelRead(
  613. IN PKSAC_CHANNEL_HANDLE SacChannelHandle,
  614. IN PCBYTE Buffer,
  615. IN ULONG BufferSize,
  616. OUT PULONG ByteCount
  617. )
  618. /*++
  619. Routine Description:
  620. This routine reads data from the channel specified.
  621. Arguments:
  622. SacChannelHandle - the channel to read from
  623. Buffer - destination buffer
  624. BufferSize - size of the destination buffer (bytes)
  625. ByteCount - the actual # of byte read
  626. Return Value:
  627. Status
  628. --*/
  629. {
  630. UCHAR Byte;
  631. BOOLEAN Success;
  632. TIME_FIELDS StartTime;
  633. TIME_FIELDS EndTime;
  634. HEADLESS_RSP_GET_BYTE Response;
  635. SIZE_T Length;
  636. NTSTATUS Status;
  637. IO_STATUS_BLOCK IoStatusBlock;
  638. SAC_CMD_READ_CHANNEL ReadChannelCmd;
  639. ULONG ReadChannelRspSize;
  640. PSAC_RSP_READ_CHANNEL ReadChannelRsp;
  641. KSAC_VALIDATE_KSAC_CHANNEL_HANDLE(SacChannelHandle);
  642. KSAC_API_ASSERT(Buffer, STATUS_INVALID_PARAMETER_2);
  643. KSAC_API_ASSERT(BufferSize > 0, STATUS_INVALID_PARAMETER_2);
  644. //
  645. // Initialize the IOCTL command
  646. //
  647. ReadChannelCmd.Handle.ChannelHandle = SacChannelHandle->ChannelHandle->ChannelHandle;
  648. //
  649. // Initialize the IOCTL response
  650. //
  651. ReadChannelRsp = (PSAC_RSP_READ_CHANNEL)Buffer;
  652. //
  653. // Send down an IOCTL for reading a channel
  654. //
  655. Status = ZwDeviceIoControlFile(
  656. SacChannelHandle->ChannelHandle->DriverHandle,
  657. SacChannelHandle->SacEventHandle,
  658. NULL,
  659. NULL,
  660. &IoStatusBlock,
  661. IOCTL_SAC_READ_CHANNEL,
  662. &ReadChannelCmd,
  663. sizeof(ReadChannelCmd),
  664. ReadChannelRsp,
  665. ReadChannelRspSize
  666. );
  667. if (Status == STATUS_PENDING) {
  668. LARGE_INTEGER TimeOut;
  669. TimeOut.QuadPart = Int32x32To64((LONG)90000, -1000);
  670. Status = KeWaitForSingleObject(
  671. SacChannelHandle->SacEvent,
  672. Executive,
  673. KernelMode,
  674. FALSE,
  675. &TimeOut
  676. );
  677. if (Status == STATUS_SUCCESS) {
  678. Status = IoStatusBlock.Status;
  679. }
  680. }
  681. return Status;
  682. }
  683. NTSTATUS
  684. KSacChannelVTUTF8Read(
  685. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  686. OUT PWSTR Buffer,
  687. IN ULONG BufferSize,
  688. OUT PULONG ByteCount
  689. )
  690. /*++
  691. Routine Description:
  692. This routine reads data from the channel specified.
  693. Arguments:
  694. SacChannelHandle - the channel to read from
  695. Buffer - destination buffer
  696. BufferSize - size of the destination buffer (bytes)
  697. ByteCount - the actual # of byte read
  698. Note: the Buffer upon return is NOT null terminated
  699. Return Value:
  700. Status
  701. --*/
  702. {
  703. return KSacChannelRead(
  704. SacChannelHandle,
  705. (PBYTE)Buffer,
  706. BufferSize,
  707. ByteCount
  708. );
  709. }
  710. NTSTATUS
  711. KSacChannelRawRead(
  712. IN KSAC_CHANNEL_HANDLE SacChannelHandle,
  713. OUT PBYTE Buffer,
  714. IN ULONG BufferSize,
  715. OUT PULONG ByteCount
  716. )
  717. /*++
  718. Routine Description:
  719. This routine reads data from the channel specified.
  720. Arguments:
  721. SacChannelHandle - the channel to read from
  722. Buffer - destination buffer
  723. BufferSize - size of the destination buffer (bytes)
  724. ByteCount - the actual # of byte read
  725. Return Value:
  726. Status
  727. --*/
  728. {
  729. return KSacChannelRead(
  730. SacChannelHandle,
  731. Buffer,
  732. BufferSize,
  733. ByteCount
  734. );
  735. }