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.

1151 lines
26 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. sacapi.c
  5. Abstract:
  6. This is the C library used to interface to SAC driver.
  7. Author:
  8. Brian Guarraci (briangu)
  9. Revision History:
  10. --*/
  11. #include "sacapip.h"
  12. #include <sacapi.h>
  13. #include <ntddsac.h>
  14. #if DBG
  15. //
  16. // Counter to keep track of how many driver handles have been
  17. // requested and released.
  18. //
  19. static ULONG DriverHandleRefCount = 0;
  20. #endif
  21. //
  22. // Memory management routine aliases
  23. //
  24. #define SAC_API_ALLOCATE_MEMORY(s) LocalAlloc(LPTR, (s))
  25. #define SAC_API_FREE_MEMORY(p) LocalFree(p)
  26. //
  27. // enhanced assertion:
  28. //
  29. // First assert the condition,
  30. // if ASSERTs are turned off,
  31. // we bail out of the function with a status
  32. //
  33. #define SAC_API_ASSERT(c,s) \
  34. ASSERT(c); \
  35. if (!(c)) { \
  36. Status = s; \
  37. __leave; \
  38. }
  39. typedef GUID* PGUID;
  40. BOOL
  41. SacHandleOpen(
  42. OUT HANDLE* SacHandle
  43. )
  44. /*++
  45. Routine Description:
  46. Initialize a handle to the SAC driver
  47. Arguments:
  48. SacHandle - A pointer to the SAC Handle
  49. Return Value:
  50. Status
  51. TRUE --> SacHandle is valid
  52. --*/
  53. {
  54. BOOL Status;
  55. Status = TRUE;
  56. __try {
  57. SAC_API_ASSERT(SacHandle, FALSE);
  58. //
  59. // Open the SAC
  60. //
  61. // SECURITY:
  62. //
  63. // this handle cannot be inherited
  64. //
  65. *SacHandle = CreateFile(
  66. L"\\\\.\\SAC",
  67. GENERIC_READ | GENERIC_WRITE,
  68. 0,
  69. NULL,
  70. OPEN_EXISTING,
  71. 0,
  72. NULL
  73. );
  74. if (*SacHandle == INVALID_HANDLE_VALUE) {
  75. Status = FALSE;
  76. }
  77. #if DBG
  78. else {
  79. InterlockedIncrement((volatile long *)&DriverHandleRefCount);
  80. }
  81. #endif
  82. }
  83. __except(EXCEPTION_EXECUTE_HANDLER) {
  84. ASSERT(0);
  85. Status = FALSE;
  86. }
  87. return Status;
  88. }
  89. BOOL
  90. SacHandleClose(
  91. IN OUT HANDLE* SacHandle
  92. )
  93. /*++
  94. Routine Description:
  95. Close the handle to the SAC driver
  96. Arguments:
  97. SacHandle - A handle to the SAC driver
  98. Return Value:
  99. Status
  100. TRUE --> SacHandle is now invalid (NULL)
  101. --*/
  102. {
  103. BOOL Status;
  104. //
  105. // default: we succeeded to close the handle
  106. //
  107. Status = TRUE;
  108. __try {
  109. SAC_API_ASSERT(SacHandle, FALSE);
  110. SAC_API_ASSERT(*SacHandle != INVALID_HANDLE_VALUE, FALSE);
  111. //
  112. // close the handle to the SAC driver
  113. //
  114. Status = CloseHandle(*SacHandle);
  115. if (Status == TRUE) {
  116. //
  117. // NULL the SAC driver handle
  118. //
  119. *SacHandle = INVALID_HANDLE_VALUE;
  120. #if DBG
  121. InterlockedDecrement((volatile long *)&DriverHandleRefCount);
  122. #endif
  123. }
  124. }
  125. __except(EXCEPTION_EXECUTE_HANDLER) {
  126. ASSERT(0);
  127. Status = FALSE;
  128. }
  129. return Status;
  130. }
  131. BOOL
  132. SacChannelOpen(
  133. OUT PSAC_CHANNEL_HANDLE SacChannelHandle,
  134. IN PSAC_CHANNEL_OPEN_ATTRIBUTES SacChannelAttributes
  135. )
  136. /*++
  137. Routine Description:
  138. Open a SAC channel of the specified name
  139. Arguments:
  140. SacChannelHandle - The handle to the newly created channel
  141. SacChannelAttributes - The attributes describing the new channel
  142. Note: The SacChannelDescription parameter is optional.
  143. If SacChannelDescription != NULL,
  144. then the Channel description will be assigned the Unicode string pointed to
  145. by SacChannelDescription.
  146. If SacChannelDescription == NULL,
  147. then the Channel description will be null upon creation.
  148. Return Value:
  149. Status
  150. TRUE --> pHandle is valid
  151. --*/
  152. {
  153. BOOL Status;
  154. ULONG OpenChannelCmdSize;
  155. PSAC_CMD_OPEN_CHANNEL OpenChannelCmd;
  156. SAC_RSP_OPEN_CHANNEL OpenChannelRsp;
  157. DWORD Feedback;
  158. HANDLE DriverHandle;
  159. //
  160. // default
  161. //
  162. Status = FALSE;
  163. OpenChannelCmdSize = 0;
  164. OpenChannelCmd = NULL;
  165. DriverHandle = INVALID_HANDLE_VALUE;
  166. __try {
  167. SAC_API_ASSERT(SacChannelHandle, FALSE);
  168. SAC_API_ASSERT(SacChannelAttributes, FALSE);
  169. //
  170. // Get a handle to the driver and store it in the
  171. // Channel handle. This way, the api user doesn't have
  172. // explicitly open/close the driver handle.
  173. //
  174. Status = SacHandleOpen(&DriverHandle);
  175. if ((Status != TRUE) ||
  176. (DriverHandle == INVALID_HANDLE_VALUE)) {
  177. Status = FALSE;
  178. __leave;
  179. }
  180. SAC_API_ASSERT(Status == TRUE, FALSE);
  181. SAC_API_ASSERT(DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  182. //
  183. // Verify that if the user wants to use the CLOSE_EVENT, we received one to use
  184. //
  185. SAC_API_ASSERT(
  186. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT)
  187. && SacChannelAttributes->CloseEvent) ||
  188. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_CLOSE_EVENT)
  189. && !SacChannelAttributes->CloseEvent),
  190. FALSE
  191. );
  192. //
  193. // Verify that if the user wants to use the HAS_NEW_DATA_EVENT, we received one to use
  194. //
  195. SAC_API_ASSERT(
  196. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
  197. && SacChannelAttributes->HasNewDataEvent) ||
  198. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_HAS_NEW_DATA_EVENT)
  199. && !SacChannelAttributes->HasNewDataEvent),
  200. FALSE
  201. );
  202. #if ENABLE_CHANNEL_LOCKING
  203. //
  204. // Verify that if the user wants to use the LOCK_EVENT, we received one to use
  205. //
  206. SAC_API_ASSERT(
  207. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT)
  208. && SacChannelAttributes->LockEvent) ||
  209. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_LOCK_EVENT)
  210. && !SacChannelAttributes->LockEvent),
  211. FALSE
  212. );
  213. #endif
  214. //
  215. // Verify that if the user wants to use the REDRAW_EVENT, we received one to use
  216. //
  217. SAC_API_ASSERT(
  218. ((SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT)
  219. && SacChannelAttributes->RedrawEvent) ||
  220. (!(SacChannelAttributes->Flags & SAC_CHANNEL_FLAG_REDRAW_EVENT)
  221. && !SacChannelAttributes->RedrawEvent),
  222. FALSE
  223. );
  224. //
  225. // If the channel type isn't cmd,
  226. // then make sure they sent us a name.
  227. //
  228. if (SacChannelAttributes->Type != ChannelTypeCmd) {
  229. SAC_API_ASSERT(SacChannelAttributes->Name, FALSE);
  230. }
  231. __try {
  232. //
  233. // create and initialize the Open Channel message structure
  234. //
  235. OpenChannelCmdSize = sizeof(SAC_CMD_OPEN_CHANNEL);
  236. OpenChannelCmd = (PSAC_CMD_OPEN_CHANNEL)SAC_API_ALLOCATE_MEMORY(OpenChannelCmdSize);
  237. SAC_API_ASSERT(OpenChannelCmd, FALSE);
  238. //
  239. // Populate the new channel attributes
  240. //
  241. OpenChannelCmd->Attributes = *SacChannelAttributes;
  242. //
  243. // If the channel type isn't cmd,
  244. // then make sure they sent us a name.
  245. //
  246. if (SacChannelAttributes->Type == ChannelTypeCmd) {
  247. //
  248. // force the name and description to be empty
  249. //
  250. OpenChannelCmd->Attributes.Name[0] = UNICODE_NULL;
  251. OpenChannelCmd->Attributes.Description[0] = UNICODE_NULL;
  252. }
  253. //
  254. // Send down an IOCTL for opening a channel
  255. //
  256. Status = DeviceIoControl(
  257. DriverHandle,
  258. IOCTL_SAC_OPEN_CHANNEL,
  259. OpenChannelCmd,
  260. OpenChannelCmdSize,
  261. &OpenChannelRsp,
  262. sizeof(SAC_RSP_OPEN_CHANNEL),
  263. &Feedback,
  264. 0
  265. );
  266. //
  267. // if the channel was not successfully created, NULL
  268. // the channel handle
  269. //
  270. if (Status == FALSE) {
  271. __leave;
  272. }
  273. //
  274. // the new channel was created, so pass back the handle to it
  275. //
  276. SacChannelHandle->DriverHandle = DriverHandle;
  277. SacChannelHandle->ChannelHandle = OpenChannelRsp.Handle.ChannelHandle;
  278. }
  279. __except(EXCEPTION_EXECUTE_HANDLER) {
  280. Status = FALSE;
  281. }
  282. }
  283. __finally {
  284. if (OpenChannelCmd) {
  285. //
  286. // free the Open Channel message structure
  287. //
  288. SAC_API_FREE_MEMORY(OpenChannelCmd);
  289. }
  290. if (Status == FALSE) {
  291. if (DriverHandle != INVALID_HANDLE_VALUE) {
  292. //
  293. // Release the driver handle
  294. //
  295. SacHandleClose(&DriverHandle);
  296. //
  297. // NULL the sac channel handle
  298. //
  299. RtlZeroMemory(SacChannelHandle, sizeof(SAC_CHANNEL_HANDLE));
  300. }
  301. }
  302. }
  303. return Status;
  304. }
  305. BOOL
  306. SacChannelClose(
  307. IN OUT PSAC_CHANNEL_HANDLE SacChannelHandle
  308. )
  309. /*++
  310. Routine Description:
  311. Close the specified SAC channel
  312. NOTE: the channel pointer is made NULL under all conditions
  313. Arguments:
  314. SacChannelHandle - Channel to be closed
  315. Return Value:
  316. Status
  317. TRUE --> the channel was closed
  318. --*/
  319. {
  320. BOOL Status;
  321. SAC_CMD_CLOSE_CHANNEL CloseChannelCmd;
  322. DWORD Feedback;
  323. __try {
  324. if (!SacChannelHandle ||
  325. (SacChannelHandle == INVALID_HANDLE_VALUE) ||
  326. (SacChannelHandle->DriverHandle == INVALID_HANDLE_VALUE) ||
  327. !SacChannelHandle->DriverHandle) {
  328. Status = FALSE;
  329. __leave;
  330. }
  331. SAC_API_ASSERT(SacChannelHandle, FALSE);
  332. SAC_API_ASSERT(SacChannelHandle->DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  333. //
  334. // initialize the Close Channel message
  335. //
  336. RtlZeroMemory(&CloseChannelCmd, sizeof(SAC_CMD_CLOSE_CHANNEL));
  337. CloseChannelCmd.Handle.ChannelHandle = SacChannelHandle->ChannelHandle;
  338. //
  339. // Send down the IOCTL for closing the channel
  340. //
  341. Status = DeviceIoControl(
  342. SacChannelHandle->DriverHandle,
  343. IOCTL_SAC_CLOSE_CHANNEL,
  344. &CloseChannelCmd,
  345. sizeof(SAC_CMD_CLOSE_CHANNEL),
  346. NULL,
  347. 0,
  348. &Feedback,
  349. 0
  350. );
  351. //
  352. // Close the handle to the driver
  353. //
  354. SacHandleClose(&SacChannelHandle->DriverHandle);
  355. //
  356. // The channel handle is no longer valid, so NULL it
  357. //
  358. RtlZeroMemory(&SacChannelHandle->ChannelHandle, sizeof(GUID));
  359. }
  360. __except(EXCEPTION_EXECUTE_HANDLER) {
  361. Status = FALSE;
  362. }
  363. return Status;
  364. }
  365. BOOL
  366. SacChannelWrite(
  367. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  368. IN PCBYTE Buffer,
  369. IN ULONG BufferSize
  370. )
  371. /*++
  372. Routine Description:
  373. Write the given buffer to the specified SAC Channel
  374. Arguments:
  375. SacChannelHandle - The channel to write the buffer to
  376. Buffer - data buffer
  377. BufferSize - size of the buffer
  378. Return Value:
  379. Status
  380. TRUE --> the buffer was sent
  381. --*/
  382. {
  383. BOOL Status;
  384. ULONG WriteChannelCmdSize;
  385. PSAC_CMD_WRITE_CHANNEL WriteChannelCmd;
  386. DWORD Feedback;
  387. //
  388. // Default
  389. //
  390. Status = FALSE;
  391. WriteChannelCmdSize = 0;
  392. WriteChannelCmd = NULL;
  393. __try {
  394. SAC_API_ASSERT(SacChannelHandle.DriverHandle, FALSE);
  395. SAC_API_ASSERT(SacChannelHandle.DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  396. SAC_API_ASSERT(Buffer, FALSE);
  397. SAC_API_ASSERT(BufferSize > 0, FALSE);
  398. //
  399. // create and initialize the Open Channel message structure
  400. //
  401. WriteChannelCmdSize = sizeof(SAC_CMD_WRITE_CHANNEL) + BufferSize;
  402. WriteChannelCmd = (PSAC_CMD_WRITE_CHANNEL)SAC_API_ALLOCATE_MEMORY(WriteChannelCmdSize);
  403. SAC_API_ASSERT(WriteChannelCmd, FALSE);
  404. __try {
  405. //
  406. // Indicate which channel this command is for
  407. //
  408. WriteChannelCmd->Handle.ChannelHandle = SacChannelHandle.ChannelHandle;
  409. //
  410. // Set the length of the string to send
  411. //
  412. // Note: Size does not include the terminating NULL,
  413. // becase we don't want to send that.
  414. //
  415. WriteChannelCmd->Size = BufferSize;
  416. //
  417. // Set the buffer to be written
  418. //
  419. RtlCopyMemory(
  420. &(WriteChannelCmd->Buffer),
  421. Buffer,
  422. BufferSize
  423. );
  424. //
  425. // Send down the IOCTL for writing the message
  426. //
  427. Status = DeviceIoControl(
  428. SacChannelHandle.DriverHandle,
  429. IOCTL_SAC_WRITE_CHANNEL,
  430. WriteChannelCmd,
  431. WriteChannelCmdSize,
  432. NULL,
  433. 0,
  434. &Feedback,
  435. 0
  436. );
  437. }
  438. __except(EXCEPTION_EXECUTE_HANDLER) {
  439. Status = FALSE;
  440. }
  441. }
  442. __finally {
  443. //
  444. // if the cmd memory was allocated,
  445. // then release it
  446. //
  447. if (WriteChannelCmd) {
  448. SAC_API_FREE_MEMORY(WriteChannelCmd);
  449. }
  450. }
  451. return Status;
  452. }
  453. BOOL
  454. SacChannelRawWrite(
  455. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  456. IN PCBYTE Buffer,
  457. IN ULONG BufferSize
  458. )
  459. /*++
  460. Routine Description:
  461. Write the given buffer to the specified SAC Channel
  462. Arguments:
  463. SacChannelHandle - The channel to write the buffer to
  464. Buffer - data buffer
  465. BufferSize - size of the buffer
  466. Return Value:
  467. Status
  468. TRUE --> the buffer was sent
  469. --*/
  470. {
  471. //
  472. // relay the write to the actual write routine
  473. //
  474. return SacChannelWrite(
  475. SacChannelHandle,
  476. Buffer,
  477. BufferSize
  478. );
  479. }
  480. BOOL
  481. SacChannelVTUTF8WriteString(
  482. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  483. IN PCWSTR String
  484. )
  485. /*++
  486. Routine Description:
  487. This routine writes a null-terminated Unicode String to the specified Channel.
  488. Arguments:
  489. SacChannelHandle - The channel to write the buffer to
  490. String - A null-terminated Unicode string
  491. Return Value:
  492. Status
  493. TRUE --> the buffer was sent
  494. --*/
  495. {
  496. BOOL Status;
  497. ULONG BufferSize;
  498. __try {
  499. //
  500. // Treating the String as a data buffer, we calculate it's size
  501. // not including the null termination
  502. //
  503. BufferSize = (ULONG)(wcslen(String) * sizeof(WCHAR));
  504. SAC_API_ASSERT(BufferSize > 0, FALSE);
  505. //
  506. // Write the data to the channel
  507. //
  508. Status = SacChannelWrite(
  509. SacChannelHandle,
  510. (PCBYTE)String,
  511. BufferSize
  512. );
  513. }
  514. __except(EXCEPTION_EXECUTE_HANDLER) {
  515. Status = FALSE;
  516. }
  517. return Status;
  518. }
  519. BOOL
  520. SacChannelVTUTF8Write(
  521. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  522. IN PCWCHAR Buffer,
  523. IN ULONG BufferSize
  524. )
  525. /*++
  526. Routine Description:
  527. This routines writes an array of WCHAR to the VTUTF8 channel specified.
  528. Arguments:
  529. SacChannelHandle - The channel to write the buffer to
  530. Buffer - data buffer
  531. BufferSize - size of the buffer
  532. Note: Buffer is not null-terminated
  533. BufferSize should not count a null-termination.
  534. Return Value:
  535. Status
  536. TRUE --> the buffer was sent
  537. --*/
  538. {
  539. //
  540. // relay the write to the actual write routine
  541. //
  542. return SacChannelWrite(
  543. SacChannelHandle,
  544. (PCBYTE)Buffer,
  545. BufferSize
  546. );
  547. }
  548. BOOL
  549. SacChannelHasNewData(
  550. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  551. OUT PBOOL InputWaiting
  552. )
  553. /*++
  554. Routine Description:
  555. This routine checks to see if there is any waiting input for
  556. the channel specified by the handle
  557. Arguments:
  558. SacChannelHandle - the channel to write the string to
  559. InputWaiting - the input buffer status
  560. Return Value:
  561. Status
  562. TRUE --> the buffer status was retrieved
  563. --*/
  564. {
  565. BOOL Status;
  566. SAC_CMD_POLL_CHANNEL PollChannelCmd;
  567. SAC_RSP_POLL_CHANNEL PollChannelRsp;
  568. DWORD Feedback;
  569. __try {
  570. SAC_API_ASSERT(SacChannelHandle.DriverHandle, FALSE);
  571. SAC_API_ASSERT(SacChannelHandle.DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  572. //
  573. // Initialize and populate the poll command structure
  574. //
  575. RtlZeroMemory(&PollChannelCmd, sizeof(SAC_CMD_POLL_CHANNEL));
  576. PollChannelCmd.Handle.ChannelHandle = SacChannelHandle.ChannelHandle;
  577. //
  578. // Send down the IOCTL to poll for new input
  579. //
  580. Status = DeviceIoControl(
  581. SacChannelHandle.DriverHandle,
  582. IOCTL_SAC_POLL_CHANNEL,
  583. &PollChannelCmd,
  584. sizeof(SAC_CMD_POLL_CHANNEL),
  585. &PollChannelRsp,
  586. sizeof(SAC_RSP_POLL_CHANNEL),
  587. &Feedback,
  588. 0
  589. );
  590. if (Status) {
  591. *InputWaiting = PollChannelRsp.InputWaiting;
  592. }
  593. }
  594. __except(EXCEPTION_EXECUTE_HANDLER) {
  595. Status = FALSE;
  596. }
  597. return Status;
  598. }
  599. BOOL
  600. SacChannelRead(
  601. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  602. OUT PBYTE Buffer,
  603. IN ULONG BufferSize,
  604. OUT PULONG ByteCount
  605. )
  606. /*++
  607. Routine Description:
  608. This routine reads data from the channel specified.
  609. Arguments:
  610. SacChannelHandle - the channel to read from
  611. Buffer - destination buffer
  612. BufferSize - size of the destination buffer (bytes)
  613. ByteCount - the actual # of byte read
  614. Return Value:
  615. Status
  616. TRUE --> the buffer was read
  617. --*/
  618. {
  619. BOOL Status;
  620. SAC_CMD_READ_CHANNEL ReadChannelCmd;
  621. PSAC_RSP_READ_CHANNEL ReadChannelRsp;
  622. __try {
  623. SAC_API_ASSERT(SacChannelHandle.DriverHandle, FALSE);
  624. SAC_API_ASSERT(SacChannelHandle.DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  625. SAC_API_ASSERT(Buffer, FALSE);
  626. SAC_API_ASSERT(ByteCount, FALSE);
  627. //
  628. // Populate the read channel cmd
  629. //
  630. RtlZeroMemory(&ReadChannelCmd, sizeof(SAC_CMD_READ_CHANNEL));
  631. ReadChannelCmd.Handle.ChannelHandle = SacChannelHandle.ChannelHandle;
  632. ReadChannelRsp = (PSAC_RSP_READ_CHANNEL)Buffer;
  633. //
  634. // Send down the IOCTL to read input
  635. //
  636. Status = DeviceIoControl(
  637. SacChannelHandle.DriverHandle,
  638. IOCTL_SAC_READ_CHANNEL,
  639. &ReadChannelCmd,
  640. sizeof(SAC_CMD_READ_CHANNEL),
  641. ReadChannelRsp,
  642. BufferSize,
  643. ByteCount,
  644. 0
  645. );
  646. }
  647. __except(EXCEPTION_EXECUTE_HANDLER) {
  648. Status = FALSE;
  649. }
  650. return Status;
  651. }
  652. BOOL
  653. SacChannelVTUTF8Read(
  654. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  655. OUT PWSTR Buffer,
  656. IN ULONG BufferSize,
  657. OUT PULONG ByteCount
  658. )
  659. /*++
  660. Routine Description:
  661. This routine reads data from the channel specified.
  662. Arguments:
  663. SacChannelHandle - the channel to read from
  664. Buffer - destination buffer
  665. BufferSize - size of the destination buffer (bytes)
  666. ByteCount - the actual # of byte read
  667. Note: the Buffer upon return is NOT null terminated
  668. Return Value:
  669. Status
  670. TRUE --> the buffer was read
  671. --*/
  672. {
  673. return SacChannelRead(
  674. SacChannelHandle,
  675. (PBYTE)Buffer,
  676. BufferSize,
  677. ByteCount
  678. );
  679. }
  680. BOOL
  681. SacChannelRawRead(
  682. IN SAC_CHANNEL_HANDLE SacChannelHandle,
  683. OUT PBYTE Buffer,
  684. IN ULONG BufferSize,
  685. OUT PULONG ByteCount
  686. )
  687. /*++
  688. Routine Description:
  689. This routine reads data from the channel specified.
  690. Arguments:
  691. SacChannelHandle - the channel to read from
  692. Buffer - destination buffer
  693. BufferSize - size of the destination buffer (bytes)
  694. ByteCount - the actual # of byte read
  695. Return Value:
  696. Status
  697. TRUE --> the buffer was read
  698. --*/
  699. {
  700. return SacChannelRead(
  701. SacChannelHandle,
  702. Buffer,
  703. BufferSize,
  704. ByteCount
  705. );
  706. }
  707. BOOL
  708. SacRegisterCmdEvent(
  709. OUT HANDLE *pDriverHandle,
  710. IN HANDLE RequestSacCmdEvent,
  711. IN HANDLE RequestSacCmdSuccessEvent,
  712. IN HANDLE RequestSacCmdFailureEvent
  713. )
  714. /*++
  715. Routine Description:
  716. This routine configures the SAC driver with the event handlers
  717. and needed to implement the ability to launch cmd consoles via
  718. a user-mode service app.
  719. Note: Only one registration can exist at a time in the SAC driver.
  720. Arguments:
  721. pDriverHandle - on success, contains the driver handle used to register
  722. RequestSacCmdEvent - the event triggered when the SAC wants to launch a cmd console
  723. RequestSacCmdSuccessEvent - the event triggered when the cmd console has successfully launched
  724. RequestSacCmdFailureEvent - the event triggered when the cmd console has failed to launch
  725. Return Value:
  726. Status
  727. TRUE --> the cmd event was registered with the SAC driver
  728. --*/
  729. {
  730. BOOL Status;
  731. DWORD Feedback;
  732. SAC_CMD_SETUP_CMD_EVENT SacCmdEvent;
  733. HANDLE DriverHandle;
  734. //
  735. // default
  736. //
  737. *pDriverHandle = INVALID_HANDLE_VALUE;
  738. __try {
  739. SAC_API_ASSERT(pDriverHandle != NULL, FALSE);
  740. SAC_API_ASSERT(RequestSacCmdEvent, FALSE);
  741. SAC_API_ASSERT(RequestSacCmdSuccessEvent, FALSE);
  742. SAC_API_ASSERT(RequestSacCmdFailureEvent, FALSE);
  743. //
  744. // Get a handle to the driver. This way, the api user doesn't have
  745. // explicitly open/close the driver handle.
  746. //
  747. Status = SacHandleOpen(&DriverHandle);
  748. if ((Status != TRUE) ||
  749. (DriverHandle == INVALID_HANDLE_VALUE)) {
  750. Status = FALSE;
  751. __leave;
  752. }
  753. SAC_API_ASSERT(Status == TRUE, FALSE);
  754. SAC_API_ASSERT(DriverHandle != INVALID_HANDLE_VALUE, FALSE);
  755. //
  756. // Initialize the our SAC Cmd Info
  757. //
  758. SacCmdEvent.RequestSacCmdEvent = RequestSacCmdEvent;
  759. SacCmdEvent.RequestSacCmdSuccessEvent = RequestSacCmdSuccessEvent;
  760. SacCmdEvent.RequestSacCmdFailureEvent = RequestSacCmdFailureEvent;
  761. //
  762. // Send down the IOCTL for setting up the SAC Cmd launch event
  763. //
  764. Status = DeviceIoControl(
  765. DriverHandle,
  766. IOCTL_SAC_REGISTER_CMD_EVENT,
  767. &SacCmdEvent,
  768. sizeof(SAC_CMD_SETUP_CMD_EVENT),
  769. NULL,
  770. 0,
  771. &Feedback,
  772. 0
  773. );
  774. //
  775. // if we were successful,
  776. // then keep the driver handle
  777. //
  778. if (Status) {
  779. *pDriverHandle = DriverHandle;
  780. } else {
  781. //
  782. // Close the driver handle
  783. //
  784. SacHandleClose(&DriverHandle);
  785. }
  786. }
  787. __except(EXCEPTION_EXECUTE_HANDLER) {
  788. Status = FALSE;
  789. }
  790. return Status;
  791. }
  792. BOOL
  793. SacUnRegisterCmdEvent(
  794. IN OUT HANDLE *pDriverHandle
  795. )
  796. /*++
  797. Routine Description:
  798. This routine unregisters the event information required
  799. to launch cmd consoles via a user-mode service app.
  800. Arguments:
  801. pDriverHandle - on entry, contains the driver handle that was used to
  802. register the cmd event info
  803. on success, contains INVALID_HANDLE_VALUE
  804. Return Value:
  805. Status
  806. TRUE --> the cmd event was unregistered with the SAC driver
  807. --*/
  808. {
  809. BOOL Status;
  810. DWORD Feedback;
  811. //
  812. // default
  813. //
  814. Status = FALSE;
  815. __try {
  816. SAC_API_ASSERT(*pDriverHandle != INVALID_HANDLE_VALUE, FALSE);
  817. //
  818. // Send down the IOCTL for unregistering the SAC Cmd launch event
  819. //
  820. Status = DeviceIoControl(
  821. *pDriverHandle,
  822. IOCTL_SAC_UNREGISTER_CMD_EVENT,
  823. NULL,
  824. 0,
  825. NULL,
  826. 0,
  827. &Feedback,
  828. 0
  829. );
  830. //
  831. // Close the driver handle
  832. //
  833. SacHandleClose(pDriverHandle);
  834. }
  835. __except(EXCEPTION_EXECUTE_HANDLER) {
  836. Status = FALSE;
  837. }
  838. return Status;
  839. }