windows-nt/Source/XPSP1/NT/net/streams/sys/sh_api.c

225 lines
4.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
sh_api.c
Abstract:
This module implements the Stream Head Driver functions that map
between NT IRPs and STREAMS APIs.
Author:
Eric Chin (ericc) July 1, 1991
Revision History:
--*/
#include "shead.h"
#include "sh_inc.h"
NTSTATUS
SHDispIoctl(
IN PIRP irp,
IN PIO_STACK_LOCATION irpsp
)
/*++
Routine Description:
This routine unwraps the IRP sent via a STREAMS ioctl(2) api, probes
the arguments, and calls the appropriate do_*() function.
Arguments:
irp - pointer to I/O request packet
irpsp - pointer to current stack location in IRP
Return Value:
NTSTATUS - Status of request
--*/
{
int icode;
char *inbuf;
NTSTATUS status;
int MyErrno, retval;
ASSERT((irpsp->Parameters.DeviceIoControl.IoControlCode & 0x3) ==
METHOD_BUFFERED);
ASSERT(irpsp->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STREAMS_IOCTL);
IF_STRMDBG(CALL) {
STRMTRACE(("SHEAD: SHDispIoctl(irp = %lx), fileobj = %lx\n",
irp, irpsp->FileObject));
}
if (irpsp->Parameters.DeviceIoControl.InputBufferLength < sizeof(int)) {
IF_STRMDBG(TERSE) {
STRMTRACE(("SHEAD: SHDispIoctl() insufficient inbuflen = %lx\n",
irpsp->Parameters.DeviceIoControl.InputBufferLength));
}
shortreply(irp, STATUS_INVALID_PARAMETER, 0);
return(STATUS_INVALID_PARAMETER);
}
/*
* the first int in the input buffer is the ioctl(2) command code,
* followed by command-specific parameters.
*/
icode = * (int *) irp->AssociatedIrp.SystemBuffer;
inbuf = (char *) irp->AssociatedIrp.SystemBuffer + sizeof(int);
switch (icode) {
case I_STR:
return(SHDispIStr(irp));
break;
case I_FDINSERT:
return(SHDispFdInsert(irp, irpsp));
break;
case I_PUSH:
status = do_push(
irp,
inbuf,
irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
&retval,
&MyErrno);
break;
case I_LINK:
status = do_link(
irp,
inbuf,
irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
&retval,
&MyErrno);
break;
case I_DEBUG:
status = do_sdebug(
irp,
irpsp->FileObject,
inbuf,
irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
&retval,
&MyErrno);
break;
case I_UNLINK:
status = do_unlink(
irp,
inbuf,
irpsp->Parameters.DeviceIoControl.InputBufferLength - sizeof(int),
&retval,
&MyErrno);
break;
default:
retval = -1;
MyErrno = EINVAL;
status = STATUS_SUCCESS;
break;
}
switch (status) {
case STATUS_PENDING:
break;
default:
if (NT_SUCCESS(status)) {
SHpGenReply(irp, retval, MyErrno);
}
else {
shortreply(irp, status, 0);
}
break;
}
IF_STRMDBG(CALL) {
STRMTRACE(("SHEAD: SHDispIoctl(irp = %lx) status = %lx\n",
irp, status));
}
return(status);
} // SHDispIoctl
NTSTATUS
SHDispPoll(
IN PIRP irp,
IN PIO_STACK_LOCATION irpsp
)
/*++
Routine Description:
This routine unwraps the IRP sent via a STREAMS poll(2) api, probes
the arguments, and then calls do_poll().
Arguments:
irp - pointer to I/O request packet
irpsp - pointer to current stack location in IRP
Return Value:
NTSTATUS - Status of request
--*/
{
NTSTATUS status;
int MyErrno, retval;
ASSERT((irpsp->Parameters.DeviceIoControl.IoControlCode & 0x3) ==
METHOD_BUFFERED);
ASSERT(irpsp->Parameters.DeviceIoControl.IoControlCode ==
IOCTL_STREAMS_POLL);
IF_STRMDBG(CALL) {
STRMTRACE(("SHEAD: SHDispPoll(), SysBuf = %lx, UserBuf = %lx\n",
irp->AssociatedIrp.SystemBuffer, irp->UserBuffer));
}
status = do_poll(
irp,
irp->AssociatedIrp.SystemBuffer,
irpsp->Parameters.DeviceIoControl.InputBufferLength,
&retval,
&MyErrno);
switch (status) {
case STATUS_PENDING:
break;
default:
if (NT_SUCCESS(status)) {
SHpGenReply(irp, retval, MyErrno);
}
else {
shortreply(irp, status, 0);
}
break;
}
IF_STRMDBG(CALL) {
STRMTRACE(("SHEAD: SHDispPoll(irp = %lx) status = %lx\n", irp, status));
}
return(status);
} // SHDispPoll