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.

224 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. sh_api.c
  5. Abstract:
  6. This module implements the Stream Head Driver functions that map
  7. between NT IRPs and STREAMS APIs.
  8. Author:
  9. Eric Chin (ericc) July 1, 1991
  10. Revision History:
  11. --*/
  12. #include "shead.h"
  13. #include "sh_inc.h"
  14. NTSTATUS
  15. SHDispIoctl(
  16. IN PIRP irp,
  17. IN PIO_STACK_LOCATION irpsp
  18. )
  19. /*++
  20. Routine Description:
  21. This routine unwraps the IRP sent via a STREAMS ioctl(2) api, probes
  22. the arguments, and calls the appropriate do_*() function.
  23. Arguments:
  24. irp - pointer to I/O request packet
  25. irpsp - pointer to current stack location in IRP
  26. Return Value:
  27. NTSTATUS - Status of request
  28. --*/
  29. {
  30. int icode;
  31. char *inbuf;
  32. NTSTATUS status;
  33. int MyErrno, retval;
  34. ASSERT((irpsp->Parameters.DeviceIoControl.IoControlCode & 0x3) ==
  35. METHOD_BUFFERED);
  36. ASSERT(irpsp->Parameters.DeviceIoControl.IoControlCode ==
  37. IOCTL_STREAMS_IOCTL);
  38. IF_STRMDBG(CALL) {
  39. STRMTRACE(("SHEAD: SHDispIoctl(irp = %lx), fileobj = %lx\n",
  40. irp, irpsp->FileObject));
  41. }
  42. if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(int)) {
  43. IF_STRMDBG(TERSE) {
  44. STRMTRACE(("SHEAD: SHDispIoctl() insufficient inbuflen = %lx\n",
  45. irpsp->Parameters.DeviceIoControl.InputBufferLength));
  46. }
  47. shortreply(irp, STATUS_INVALID_PARAMETER, 0);
  48. return(STATUS_INVALID_PARAMETER);
  49. }
  50. /*
  51. * the first int in the input buffer is the ioctl(2) command code,
  52. * followed by command-specific parameters.
  53. */
  54. icode = * (int *) irp->AssociatedIrp.SystemBuffer;
  55. inbuf = (char *) irp->AssociatedIrp.SystemBuffer + sizeof(int);
  56. switch (icode) {
  57. case I_STR:
  58. return(SHDispIStr(irp));
  59. break;
  60. case I_FDINSERT:
  61. return(SHDispFdInsert(irp, irpsp));
  62. break;
  63. case I_PUSH:
  64. status = do_push(
  65. irp,
  66. inbuf,
  67. irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
  68. &retval,
  69. &MyErrno);
  70. break;
  71. case I_LINK:
  72. status = do_link(
  73. irp,
  74. inbuf,
  75. irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
  76. &retval,
  77. &MyErrno);
  78. break;
  79. case I_DEBUG:
  80. status = do_sdebug(
  81. irp,
  82. irpsp->FileObject,
  83. inbuf,
  84. irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
  85. &retval,
  86. &MyErrno);
  87. break;
  88. case I_UNLINK:
  89. status = do_unlink(
  90. irp,
  91. inbuf,
  92. irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
  93. &retval,
  94. &MyErrno);
  95. break;
  96. default:
  97. retval = -1;
  98. MyErrno = EINVAL;
  99. status = STATUS_SUCCESS;
  100. break;
  101. }
  102. switch (status) {
  103. case STATUS_PENDING:
  104. break;
  105. default:
  106. if (NT_SUCCESS(status)) {
  107. SHpGenReply(irp, retval, MyErrno);
  108. }
  109. else {
  110. shortreply(irp, status, 0);
  111. }
  112. break;
  113. }
  114. IF_STRMDBG(CALL) {
  115. STRMTRACE(("SHEAD: SHDispIoctl(irp = %lx) status = %lx\n",
  116. irp, status));
  117. }
  118. return(status);
  119. } // SHDispIoctl
  120. NTSTATUS
  121. SHDispPoll(
  122. IN PIRP irp,
  123. IN PIO_STACK_LOCATION irpsp
  124. )
  125. /*++
  126. Routine Description:
  127. This routine unwraps the IRP sent via a STREAMS poll(2) api, probes
  128. the arguments, and then calls do_poll().
  129. Arguments:
  130. irp - pointer to I/O request packet
  131. irpsp - pointer to current stack location in IRP
  132. Return Value:
  133. NTSTATUS - Status of request
  134. --*/
  135. {
  136. NTSTATUS status;
  137. int MyErrno, retval;
  138. ASSERT((irpsp->Parameters.DeviceIoControl.IoControlCode & 0x3) ==
  139. METHOD_BUFFERED);
  140. ASSERT(irpsp->Parameters.DeviceIoControl.IoControlCode ==
  141. IOCTL_STREAMS_POLL);
  142. IF_STRMDBG(CALL) {
  143. STRMTRACE(("SHEAD: SHDispPoll(), SysBuf = %lx, UserBuf = %lx\n",
  144. irp->AssociatedIrp.SystemBuffer, irp->UserBuffer));
  145. }
  146. status = do_poll(
  147. irp,
  148. irp->AssociatedIrp.SystemBuffer,
  149. irpsp->Parameters.DeviceIoControl.InputBufferLength,
  150. &retval,
  151. &MyErrno);
  152. switch (status) {
  153. case STATUS_PENDING:
  154. break;
  155. default:
  156. if (NT_SUCCESS(status)) {
  157. SHpGenReply(irp, retval, MyErrno);
  158. }
  159. else {
  160. shortreply(irp, status, 0);
  161. }
  162. break;
  163. }
  164. IF_STRMDBG(CALL) {
  165. STRMTRACE(("SHEAD: SHDispPoll(irp = %lx) status = %lx\n", irp, status));
  166. }
  167. return(status);
  168. } // SHDispPoll