|
|
/*++
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
|