225 lines
4.9 KiB
C
225 lines
4.9 KiB
C
|
/*++
|
|||
|
|
|||
|
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
|