Example #1
0
NTSTATUS
NTAPI
NpCommonQuerySecurityInfo(IN PDEVICE_OBJECT DeviceObject,
                          IN PIRP Irp)
{
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    NTSTATUS Status;
    PNP_FCB Fcb;
    PNP_CCB Ccb;
    ULONG NamedPipeEnd;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
                                      (PVOID*)&Fcb,
                                      &Ccb,
                                      &NamedPipeEnd);
    if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
    if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;

    Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation,
                                           Irp->UserBuffer,
                                           &IoStack->Parameters.QuerySecurity.Length,
                                           &Fcb->SecurityDescriptor);
    if (Status == STATUS_BUFFER_TOO_SMALL)
    {
        Irp->IoStatus.Information = IoStack->Parameters.QuerySecurity.Length;
        Status = STATUS_BUFFER_OVERFLOW;
    }

    return Status;
}
Example #2
0
NTSTATUS
NTAPI
NpImpersonate(IN PDEVICE_OBJECT DeviceObject,
              IN PIRP Irp)
{
    ULONG NamedPipeEnd;
    PNP_CCB Ccb;
    NTSTATUS Status;
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
    if (NodeTypeCode == NPFS_NTC_CCB)
    {
        if (NamedPipeEnd == FILE_PIPE_SERVER_END)
        {
            Status = NpImpersonateClientContext(Ccb);
        }
        else
        {
            Status = STATUS_ILLEGAL_FUNCTION;
        }
    }

    return Status;
}
Example #3
0
NTSTATUS
NTAPI
NpCommonFlushBuffers(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
{
    NODE_TYPE_CODE NodeTypeCode;
    PNP_CCB Ccb;
    ULONG NamedPipeEnd;
    NTSTATUS Status;
    PNP_DATA_QUEUE FlushQueue;
    PAGED_CODE();

    NodeTypeCode = NpDecodeFileObject(IoGetCurrentIrpStackLocation(Irp)->FileObject,
                                      NULL,
                                      &Ccb,
                                      &NamedPipeEnd);
    if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_PIPE_DISCONNECTED;

    ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);

    if (NamedPipeEnd == FILE_PIPE_SERVER_END)
    {
        FlushQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
    }
    else
    {
        FlushQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
    }

    if (FlushQueue->QueueState == WriteEntries)
    {
        Status = NpAddDataQueueEntry(NamedPipeEnd,
                                     Ccb,
                                     FlushQueue,
                                     WriteEntries,
                                     2,
                                     0,
                                     Irp,
                                     NULL,
                                     0);
    }
    else
    {
        Status = STATUS_SUCCESS;
    }

    ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
    return Status;
}
Example #4
0
NTSTATUS
NTAPI
NpCommonSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
                        IN PIRP Irp)
{
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    NTSTATUS Status;
    PNP_FCB Fcb;
    PNP_CCB Ccb;
    ULONG NamedPipeEnd;
    PSECURITY_DESCRIPTOR OldSecurityDescriptor;
    PSECURITY_DESCRIPTOR TempSecurityDescriptor;
    PSECURITY_DESCRIPTOR NewSecurityDescriptor;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject,
                                      (PVOID*)&Fcb,
                                      &Ccb,
                                      &NamedPipeEnd);
    if (!NodeTypeCode) return STATUS_PIPE_DISCONNECTED;
    if (NodeTypeCode != NPFS_NTC_CCB) return STATUS_INVALID_PARAMETER;

    OldSecurityDescriptor = TempSecurityDescriptor = Fcb->SecurityDescriptor;
    Status = SeSetSecurityDescriptorInfo(NULL,
                                         &IoStack->Parameters.SetSecurity.SecurityInformation,
                                         IoStack->Parameters.SetSecurity.SecurityDescriptor,
                                         &TempSecurityDescriptor,
                                         TRUE,
                                         IoGetFileObjectGenericMapping());
    if (!NT_SUCCESS(Status)) return Status;

    Status = ObLogSecurityDescriptor(TempSecurityDescriptor, &NewSecurityDescriptor, 1);
    ASSERT(TempSecurityDescriptor != OldSecurityDescriptor);
    ExFreePoolWithTag(TempSecurityDescriptor, 0);

    if (!NT_SUCCESS(Status)) return Status;

    Fcb->SecurityDescriptor = NewSecurityDescriptor;
    ObDereferenceSecurityDescriptor(OldSecurityDescriptor, 1);
    return Status;
}
Example #5
0
NTSTATUS
NTAPI
NpListen(IN PDEVICE_OBJECT DeviceObject,
         IN PIRP Irp,
         IN PLIST_ENTRY List)
{
    ULONG NamedPipeEnd;
    PNP_CCB Ccb;
    NTSTATUS Status;
    NODE_TYPE_CODE NodeTypeCode;
    PIO_STACK_LOCATION IoStack;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
    if (NodeTypeCode == NPFS_NTC_CCB)
    {
        if (NamedPipeEnd == FILE_PIPE_SERVER_END)
        {
            ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);

            Status = NpSetListeningPipeState(Ccb, Irp, List);

            NpUninitializeSecurity(Ccb);

            ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
        }
        else
        {
            Status = STATUS_ILLEGAL_FUNCTION;
        }
    }
    else
    {
        Status = STATUS_ILLEGAL_FUNCTION;
    }

    return Status;
}
Example #6
0
File: read.c Project: GYGit/reactos
BOOLEAN
NTAPI
NpCommonRead(IN PFILE_OBJECT FileObject,
             IN PVOID Buffer,
             IN ULONG BufferSize,
             OUT PIO_STATUS_BLOCK IoStatus,
             IN PIRP Irp,
             IN PLIST_ENTRY List)
{
    NODE_TYPE_CODE NodeType;
    PNP_DATA_QUEUE ReadQueue;
    PNP_EVENT_BUFFER EventBuffer;
    NTSTATUS Status;
    ULONG NamedPipeEnd;
    PNP_CCB Ccb;
    PNP_NONPAGED_CCB NonPagedCcb;
    BOOLEAN ReadOk;
    PAGED_CODE();

    IoStatus->Information = 0;
    NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);

    if (!NodeType)
    {
        IoStatus->Status = STATUS_PIPE_DISCONNECTED;
        return TRUE;
    }

    if (NodeType != NPFS_NTC_CCB)
    {
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        return TRUE;
    }

    NonPagedCcb = Ccb->NonPagedCcb;
    ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);

    if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE || Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE)
    {
        IoStatus->Status = Ccb->NamedPipeState != FILE_PIPE_DISCONNECTED_STATE ? STATUS_PIPE_LISTENING : STATUS_PIPE_DISCONNECTED;
        ReadOk = TRUE;
        goto Quickie;
    }

    ASSERT((Ccb->NamedPipeState == FILE_PIPE_CONNECTED_STATE) || (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE));

    if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND) ||
        (NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND))
    {
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        ReadOk = TRUE;
        goto Quickie;
    }

    if (NamedPipeEnd == FILE_PIPE_SERVER_END)
    {
        ReadQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
    }
    else
    {
        ReadQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
    }

    EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];

    if (ReadQueue->QueueState == WriteEntries)
    {
        *IoStatus = NpReadDataQueue(ReadQueue,
                                    FALSE,
                                    FALSE,
                                    Buffer,
                                    BufferSize,
                                    Ccb->ReadMode[NamedPipeEnd],
                                    Ccb,
                                    List);
        if (!NT_SUCCESS(IoStatus->Status))
        {
            ReadOk = TRUE;
            goto Quickie;
        }

        ReadOk = TRUE;
        if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
        goto Quickie;
    }

    if (Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE)
    {
        IoStatus->Status = STATUS_PIPE_BROKEN;
        ReadOk = TRUE;
        if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
        goto Quickie;
    }

    if (Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
    {
        IoStatus->Status = STATUS_PIPE_EMPTY;
        ReadOk = TRUE;
        if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
        goto Quickie;
    }

    if (!Irp)
    {
        ReadOk = FALSE;
        goto Quickie;
    }

    Status = NpAddDataQueueEntry(NamedPipeEnd,
                                 Ccb,
                                 ReadQueue,
                                 ReadEntries,
                                 Buffered,
                                 BufferSize,
                                 Irp,
                                 NULL,
                                 0);
    IoStatus->Status = Status;
    if (!NT_SUCCESS(Status))
    {
        ReadOk = FALSE;
    }
    else
    {
        ReadOk = TRUE;
        if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
    }

Quickie:
    ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
    return ReadOk;
}
Example #7
0
NTSTATUS
NpCommonSetInformation (
    IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for creating/opening a file.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - the return status for the operation

--*/

{
    PIO_STACK_LOCATION IrpSp;
    NTSTATUS Status;

    ULONG Length;
    FILE_INFORMATION_CLASS FileInformationClass;
    PVOID Buffer;

    NODE_TYPE_CODE NodeTypeCode;
    PFCB Fcb;
    PCCB Ccb;
    NAMED_PIPE_END NamedPipeEnd;

    PAGED_CODE();

    //
    //  Get the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "NpCommonSetInformation...\n", 0);
    DebugTrace( 0, Dbg, " Irp                    = %08lx\n", Irp);
    DebugTrace( 0, Dbg, " ->Length               = %08lx\n", IrpSp->Parameters.SetFile.Length);
    DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", IrpSp->Parameters.SetFile.FileInformationClass);
    DebugTrace( 0, Dbg, " ->Buffer               = %08lx\n", Irp->AssociatedIrp.SystemBuffer);

    //
    //  Get the ccb and figure out who we are, and make sure we're not
    //  disconnected.
    //

    if ((NodeTypeCode = NpDecodeFileObject( IrpSp->FileObject,
                                            &Fcb,
                                            &Ccb,
                                            &NamedPipeEnd )) == NTC_UNDEFINED) {

        DebugTrace(0, Dbg, "Pipe is disconnected from us\n", 0);

        NpCompleteRequest( Irp, STATUS_PIPE_DISCONNECTED );
        Status = STATUS_PIPE_DISCONNECTED;

        DebugTrace(-1, Dbg, "NpCommonSetInformation -> %08lx\n", Status );
        return Status;
    }

    //
    //  Case on the type of the context, We can only query information
    //  on an Fcb, Dcb, or Root Dcb.  If we are not passed on of these
    //  we immediately tell the caller that there is an invalid parameter.
    //

    if (NodeTypeCode != NPFS_NTC_CCB) {

        NpCompleteRequest( Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg, "NpCommonQueryInformation -> STATUS_INVALID_PARAMETER\n", 0);
        return STATUS_INVALID_PARAMETER;
    }

    //
    //  Reference our input parameter to make things easier
    //

    Length = IrpSp->Parameters.SetFile.Length;
    FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
    Buffer = Irp->AssociatedIrp.SystemBuffer;

    //
    //  Based on the information class we'll do differnt actions. Each
    //  procedure that we're calling will complete the request.
    //

    switch (FileInformationClass) {

    case FileBasicInformation:

        Status = NpSetBasicInfo( Ccb, Buffer );
        break;

    case FilePipeInformation:

        Status = NpSetPipeInfo( Fcb, Ccb, Buffer, NamedPipeEnd );
        break;

    default:

        Status = STATUS_INVALID_PARAMETER;
        break;
    }

    //
    //  complete the request
    //

    NpCompleteRequest( Irp, Status );

    DebugTrace(-1, Dbg, "NpCommonSetInformation -> %08lx\n", Status);
    return Status;
}
Example #8
0
NTSTATUS
NpCommonQueryInformation (
    IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for creating/opening a file.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - the return status for the operation

--*/

{
    PIO_STACK_LOCATION IrpSp;
    NTSTATUS Status;

    ULONG Length;
    FILE_INFORMATION_CLASS FileInformationClass;
    PVOID Buffer;

    NODE_TYPE_CODE NodeTypeCode;
    PFCB Fcb;
    PCCB Ccb;
    NAMED_PIPE_END NamedPipeEnd;

    PFILE_ALL_INFORMATION AllInfo;

    PAGED_CODE();

    //
    //  Get the current stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "NpCommonQueryInformation...\n", 0);
    DebugTrace( 0, Dbg, " Irp                    = %08lx\n", Irp);
    DebugTrace( 0, Dbg, " ->Length               = %08lx\n", IrpSp->Parameters.QueryFile.Length);
    DebugTrace( 0, Dbg, " ->FileInformationClass = %08lx\n", IrpSp->Parameters.QueryFile.FileInformationClass);
    DebugTrace( 0, Dbg, " ->Buffer               = %08lx\n", Irp->AssociatedIrp.SystemBuffer);

    //
    //  Get the ccb and figure out who we are, and make sure we're not
    //  disconnected.
    //

    if ((NodeTypeCode = NpDecodeFileObject( IrpSp->FileObject,
                                            &Fcb,
                                            &Ccb,
                                            &NamedPipeEnd )) == NTC_UNDEFINED) {

        DebugTrace(0, Dbg, "Pipe is disconnected from us\n", 0);

        NpCompleteRequest( Irp, STATUS_PIPE_DISCONNECTED );
        Status = STATUS_PIPE_DISCONNECTED;

        DebugTrace(-1, Dbg, "NpCommonQueryInformation -> %08lx\n", Status );
        return Status;
    }

    //
    //  Case on the type of the context, We can only query information
    //  on an Fcb, Dcb, or Root Dcb.  If we are not passed on of these
    //  we immediately tell the caller that there is an invalid parameter.
    //

    if (NodeTypeCode != NPFS_NTC_CCB) {

        DebugTrace(0, Dbg, "Node type code is not ccb\n", 0);

        NpCompleteRequest( Irp, STATUS_INVALID_PARAMETER );

        DebugTrace(-1, Dbg, "NpCommonQueryInformation -> STATUS_INVALID_PARAMETER\n", 0);
        return STATUS_INVALID_PARAMETER;
    }

    //
    //  Reference our input parameter to make things easier
    //

    Length = IrpSp->Parameters.QueryFile.Length;
    FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
    Buffer = Irp->AssociatedIrp.SystemBuffer;

    //
    //  Based on the information class we'll do different actions.  Each
    //  of the procedure that we're calling fill up as much of the
    //  buffer as possible and return the remaining length, and status
    //  This is done so that we can use them to build up the
    //  FileAllInformation request.  These procedures do not complete the
    //  Irp, instead this procedure must complete the Irp.
    //

    switch (FileInformationClass) {

    case FileAllInformation:

        //
        //  For the all information class we'll typecast a local
        //  pointer to the output buffer and then call the
        //  individual routines to fill in the buffer.
        //

        AllInfo = Buffer;

        Length -= (sizeof(FILE_ACCESS_INFORMATION)
                   + sizeof(FILE_MODE_INFORMATION)
                   + sizeof(FILE_ALIGNMENT_INFORMATION));

        //
        //  Only the QueryName call can return non-success
        //

        (VOID)NpQueryBasicInfo( Ccb, &AllInfo->BasicInformation, &Length );
        (VOID)NpQueryStandardInfo( Ccb, &AllInfo->StandardInformation, &Length );
        (VOID)NpQueryInternalInfo( Ccb, &AllInfo->InternalInformation, &Length );
        (VOID)NpQueryEaInfo( Ccb, &AllInfo->EaInformation, &Length );
        (VOID)NpQueryPositionInfo( Ccb, &AllInfo->PositionInformation, &Length, NamedPipeEnd );

        Status = NpQueryNameInfo( Ccb, &AllInfo->NameInformation, &Length );

        break;

    case FileBasicInformation:

        Status = NpQueryBasicInfo( Ccb, Buffer, &Length );
        break;

    case FileStandardInformation:

        Status = NpQueryStandardInfo( Ccb, Buffer, &Length );
        break;

    case FileInternalInformation:

        Status = NpQueryInternalInfo( Ccb, Buffer, &Length );
        break;

    case FileEaInformation:

        Status = NpQueryEaInfo( Ccb, Buffer, &Length );
        break;

    case FilePositionInformation:

        Status = NpQueryPositionInfo( Ccb, Buffer, &Length, NamedPipeEnd );
        break;

    case FileNameInformation:

        Status = NpQueryNameInfo( Ccb, Buffer, &Length );
        break;

    case FilePipeInformation:

        Status = NpQueryPipeInfo( Fcb, Ccb, Buffer, &Length, NamedPipeEnd );
        break;

    case FilePipeLocalInformation:

        Status = NpQueryPipeLocalInfo( Fcb, Ccb, Buffer, &Length, NamedPipeEnd );
        break;

    default:

        Status = STATUS_INVALID_PARAMETER;
        break;
    }

    //
    //  Set the information field to the number of bytes actually filled in
    //  and then complete the request
    //

    Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
    NpCompleteRequest( Irp, Status );

    DebugTrace(-1, Dbg, "NpCommonQueryInformation -> %08lx\n", Status );
    return Status;
}
Example #9
0
NTSTATUS
NpCommonFlushBuffers (
    IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for Flushing buffers for a file.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - the return status for the operation

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp;

    PCCB Ccb;
    NAMED_PIPE_END NamedPipeEnd;

    PDATA_QUEUE WriteQueue;

    //
    //  Get the current stack location
    //

    PAGED_CODE();

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "NpCommonFlushBuffers\n", 0);
    DebugTrace( 0, Dbg, "Irp        = %08lx\n", Irp);
    DebugTrace( 0, Dbg, "FileObject = %08lx\n", IrpSp->FileObject);

    //
    //  Decode the file object to figure out who we are.  If the result
    //  is not a ccb then the pipe has been disconnected.  We don't need the
    //  Fcb back from the call
    //

    if (NpDecodeFileObject( IrpSp->FileObject,
                            NULL,
                            &Ccb,
                            &NamedPipeEnd ) != NPFS_NTC_CCB) {

        DebugTrace(0, Dbg, "Pipe is disconnected from us\n", 0);

        NpCompleteRequest( Irp, STATUS_PIPE_DISCONNECTED );
        Status = STATUS_PIPE_DISCONNECTED;

        DebugTrace(-1, Dbg, "NpCommonFlushBuffers -> %08lx\n", Status );
        return Status;
    }

    NpAcquireExclusiveCcb(Ccb);

    try {

        //
        //  Figure out the data queue that the flush buffer is
        //  targetted at.  It is the queue that we do writes into
        //

        if (NamedPipeEnd == FILE_PIPE_SERVER_END) {

            WriteQueue = &Ccb->DataQueue[ FILE_PIPE_OUTBOUND ];

        } else {

            WriteQueue = &Ccb->DataQueue[ FILE_PIPE_INBOUND ];
        }

        //
        //  Now from the write queue check if contains write entries.  If
        //  it does not contain write entries then we immediately complete
        //  this irp with success because there isn't anything to flush
        //

        if (!NpIsDataQueueWriters( WriteQueue )) {

            DebugTrace(0, Dbg, "Pipe does not contain write entries\n", 0);

            NpCompleteRequest( Irp, STATUS_SUCCESS );
            try_return(Status = STATUS_SUCCESS);
        }

        //
        //  Otherwise the queue is full of writes so we simply
        //  enqueue this irp to the back to the queue and set our
        //  return status to pending, also mark the irp pending
        //

        IoMarkIrpPending( Irp );

        (VOID)NpAddDataQueueEntry( WriteQueue,
                                   WriteEntries,
                                   Flush,
                                   0,
                                   Irp,
                                   NULL );
        Status = STATUS_PENDING;

    try_exit: NOTHING;
    } finally {
        NpReleaseCcb(Ccb);
    }


    DebugTrace(-1, Dbg, "NpCommonFlushBuffers -> %08lx\n", Status);
    return Status;
}
Example #10
0
NTSTATUS
NpCommonClose (
    IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for creating/opening a file.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - the return status for the operation

--*/

{
    NTSTATUS Status;

    PIO_STACK_LOCATION IrpSp;

    NODE_TYPE_CODE NodeTypeCode;
    PFCB Fcb;
    PCCB Ccb;

    PAGED_CODE();

    //
    //  Get the current stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "NpCommonClose...\n", 0);
    DebugTrace( 0, Dbg, " Irp                    = %08lx\n", Irp);

    //
    //  Now acquire exclusive access to the vcb
    //

    NpAcquireExclusiveVcb();

    try {

        //
        //  Decode the file object to figure out who we are.  If the result
        //  is null then the pipe has been disconnected.
        //

        if ((NodeTypeCode = NpDecodeFileObject( IrpSp->FileObject,
                                                &Fcb,
                                                &Ccb,
                                                NULL )) == NTC_UNDEFINED) {

            DebugTrace(0, Dbg, "Pipe is disconnected from us\n", 0);

            NpCompleteRequest( Irp, STATUS_PIPE_DISCONNECTED );
            try_return( Status = STATUS_PIPE_DISCONNECTED );
        }

        //
        //  Now case on the type of file object we're closing
        //

        switch (NodeTypeCode) {

        case NPFS_NTC_VCB:

            //
            //  Decrement the Open count and clear our fields in the file object
            //

            NpVcb->OpenCount -= 1;
            NpSetFileObject( IrpSp->FileObject, NULL, NULL, FILE_PIPE_SERVER_END );

            break;

        case NPFS_NTC_ROOT_DCB:

            //
            //  Decrement the Open count and clear our fields in the file object
            //

            Fcb->OpenCount -= 1;
            NpSetFileObject( IrpSp->FileObject, NULL, NULL, FILE_PIPE_SERVER_END );

            //
            //  Remove the root dcb ccb.
            //

            NpDeleteCcb( Ccb );

            break;

        case NPFS_NTC_CCB:

            break;
        }

        //
        //  Complete the close irp
        //

        NpCompleteRequest( Irp, STATUS_SUCCESS );

        Status = STATUS_SUCCESS;

    try_exit: NOTHING;
    } finally {

        NpReleaseVcb( );
    }

    DebugTrace(-1, Dbg, "NpCommonClose -> %08lx\n", Status);
    return Status;
}
Example #11
0
NTSTATUS
NTAPI
NpQueryClientProcess(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
{
    PIO_STACK_LOCATION IoStackLocation;
    NODE_TYPE_CODE NodeTypeCode;
    PNP_CCB Ccb;
    PNP_CLIENT_PROCESS ClientSession, QueryBuffer;
    ULONG Length;
    PAGED_CODE();

    /* Get the current stack location */
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

    /* Decode the file object and check the node type */
    NodeTypeCode = NpDecodeFileObject(IoStackLocation->FileObject, 0, &Ccb, 0);
    if (NodeTypeCode != NPFS_NTC_CCB)
    {
        return STATUS_PIPE_DISCONNECTED;
    }

    /* Get the length of the query buffer */
    Length = IoStackLocation->Parameters.QueryFile.Length;
    if (Length < 8)
    {
        return STATUS_INVALID_PARAMETER;
    }

    QueryBuffer = Irp->AssociatedIrp.SystemBuffer;

    /* Lock the Ccb */
    ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);

    /* Get the CCBs client session and check if it's set */
    ClientSession = Ccb->ClientSession;
    if (ClientSession != NULL)
    {
        /* Copy first 2 fields */
        QueryBuffer->Unknown = ClientSession->Unknown;
        QueryBuffer->Process = ClientSession->Process;
    }
    else
    {
        /* Copy the process from the CCB */
        QueryBuffer->Unknown = NULL;
        QueryBuffer->Process = Ccb->Process;
    }

    /* Does the caller provide a large enough buffer for the full data? */
    if (Length >= sizeof(NP_CLIENT_PROCESS))
    {
        Irp->IoStatus.Information = sizeof(NP_CLIENT_PROCESS);

        /* Do we have a ClientSession structure? */
        if (ClientSession != NULL)
        {
            /* Copy length and the data */
            QueryBuffer->DataLength = ClientSession->DataLength;
            RtlCopyMemory(QueryBuffer->Buffer,
                          ClientSession->Buffer,
                          ClientSession->DataLength);

            /* NULL terminate the buffer */
            NT_ASSERT(QueryBuffer->DataLength <= 30);
            QueryBuffer->Buffer[QueryBuffer->DataLength / sizeof(WCHAR)] = 0;
        }
        else
        {
            /* No data */
            QueryBuffer->DataLength = 0;
            QueryBuffer->Buffer[0] = 0;
        }
    }
    else
    {
        Irp->IoStatus.Information = FIELD_OFFSET(NP_CLIENT_PROCESS, DataLength);
    }

    /* Unlock the Ccb */
    ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);

    return STATUS_SUCCESS;
}
Example #12
0
NTSTATUS
NTAPI
NpPeek(IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp,
       IN PLIST_ENTRY List)
{
    PIO_STACK_LOCATION IoStack;
    NODE_TYPE_CODE Type;
    ULONG OutputLength;
    ULONG NamedPipeEnd;
    PNP_CCB Ccb;
    PFILE_PIPE_PEEK_BUFFER PeekBuffer;
    PNP_DATA_QUEUE DataQueue;
    ULONG_PTR BytesPeeked;
    IO_STATUS_BLOCK IoStatus;
    NTSTATUS Status;
    PNP_DATA_QUEUE_ENTRY DataEntry;
    PAGED_CODE();

    IoStack = IoGetCurrentIrpStackLocation(Irp);
    OutputLength = IoStack->Parameters.FileSystemControl.OutputBufferLength;
    Type = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);

    if (!Type)
    {
        return STATUS_PIPE_DISCONNECTED;
    }

    if ((Type != NPFS_NTC_CCB) &&
            (OutputLength < FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data)))
    {
        return STATUS_INVALID_PARAMETER;
    }

    PeekBuffer = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
    if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
    {
        if (NamedPipeEnd != FILE_PIPE_SERVER_END)
        {
            NpBugCheck(NamedPipeEnd, 0, 0);
        }

        DataQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
    }
    else
    {
        DataQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
    }

    if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
    {
        if (Ccb->NamedPipeState != FILE_PIPE_CLOSING_STATE)
        {
            return STATUS_INVALID_PIPE_STATE;
        }

        if (DataQueue->QueueState != WriteEntries)
        {
            return STATUS_PIPE_BROKEN;
        }
    }

    PeekBuffer->NamedPipeState = 0;
    PeekBuffer->ReadDataAvailable = 0;
    PeekBuffer->NumberOfMessages = 0;
    PeekBuffer->MessageLength = 0;
    PeekBuffer->NamedPipeState = Ccb->NamedPipeState;
    BytesPeeked = FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data);

    if (DataQueue->QueueState == WriteEntries)
    {
        DataEntry = CONTAINING_RECORD(DataQueue->Queue.Flink,
                                      NP_DATA_QUEUE_ENTRY,
                                      QueueEntry);
        ASSERT((DataEntry->DataEntryType == Buffered) || (DataEntry->DataEntryType == Unbuffered));

        PeekBuffer->ReadDataAvailable = DataQueue->BytesInQueue - DataQueue->ByteOffset;
        if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE)
        {
            PeekBuffer->NumberOfMessages = DataQueue->EntriesInQueue;
            PeekBuffer->MessageLength = DataEntry->DataSize - DataQueue->ByteOffset;
        }

        if (OutputLength == FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data))
        {
            Status = PeekBuffer->ReadDataAvailable ? STATUS_BUFFER_OVERFLOW : STATUS_SUCCESS;
        }
        else
        {
            IoStatus = NpReadDataQueue(DataQueue,
                                       TRUE,
                                       FALSE,
                                       PeekBuffer->Data,
                                       OutputLength - FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data),
                                       Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE,
                                       Ccb,
                                       List);
            Status = IoStatus.Status;
            BytesPeeked += IoStatus.Information;
        }
    }
    else
    {
        Status = STATUS_SUCCESS;
    }

    Irp->IoStatus.Information = BytesPeeked;
    return Status;
}
Example #13
0
NTSTATUS
NTAPI
NpSetClientProcess(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
{
    PIO_STACK_LOCATION IoStackLocation;
    NODE_TYPE_CODE NodeTypeCode;
    PNP_CCB Ccb;
    ULONG Length;
    PNP_CLIENT_PROCESS InputBuffer, ClientSession, OldClientSession;
    PAGED_CODE();

    /* Get the current stack location */
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

    /* Only kernel calls are allowed! */
    if (IoStackLocation->MinorFunction != IRP_MN_KERNEL_CALL)
    {
        return STATUS_ACCESS_DENIED;
    }

    /* Decode the file object and check the node type */
    NodeTypeCode = NpDecodeFileObject(IoStackLocation->FileObject, 0, &Ccb, 0);
    if (NodeTypeCode != NPFS_NTC_CCB)
    {
        return STATUS_PIPE_DISCONNECTED;
    }

    /* Get the length of the query buffer and check if it's valid */
    Length = IoStackLocation->Parameters.QueryFile.Length;
    if (Length != sizeof(NP_CLIENT_PROCESS))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Get the buffer and check if the data Length is valid */
    InputBuffer = Irp->AssociatedIrp.SystemBuffer;
    if (InputBuffer->DataLength > 30)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Allocate a new structure */
    ClientSession = ExAllocatePoolWithQuotaTag(PagedPool,
                    sizeof(NP_CLIENT_PROCESS),
                    'iFpN');

    /* Copy the full input buffer */
    RtlCopyMemory(ClientSession, InputBuffer, sizeof(NP_CLIENT_PROCESS));

    /* Lock the Ccb */
    ExAcquireResourceExclusiveLite(&Ccb->NonPagedCcb->Lock, TRUE);

    /* Get the old ClientSession and set the new */
    OldClientSession = Ccb->ClientSession;
    Ccb->ClientSession = ClientSession;

    /* Copy the process to the CCB */
    Ccb->Process = ClientSession->Process;

    /* Unlock the Ccb */
    ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);

    /* Check if there was already a ClientSession */
    if (OldClientSession != NULL)
    {
        /* Free it */
        ExFreePoolWithTag(OldClientSession, 'iFpN');
    }

    return STATUS_SUCCESS;
}
Example #14
0
    if (Irp->RequestorMode == UserMode)
    {
        _SEH2_TRY
        {
            ProbeForRead(InBuffer, InLength, sizeof(CHAR));
            ProbeForWrite(OutBuffer, OutLength, sizeof(CHAR));
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            _SEH2_YIELD(return _SEH2_GetExceptionCode());
        }
        _SEH2_END;
    }

    NodeTypeCode = NpDecodeFileObject(IoStack->FileObject, NULL, &Ccb, &NamedPipeEnd);
    if (NodeTypeCode != NPFS_NTC_CCB)
    {
        return STATUS_PIPE_DISCONNECTED;
    }

    NonPagedCcb = Ccb->NonPagedCcb;
    ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);

    if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
    {
        Status = STATUS_INVALID_PIPE_STATE;
        goto Quickie;
    }

    if (NamedPipeEnd != FILE_PIPE_CLIENT_END)
Example #15
0
BOOLEAN
NTAPI
NpCommonWrite(IN PFILE_OBJECT FileObject,
              IN PVOID Buffer,
              IN ULONG DataSize,
              IN PETHREAD Thread,
              IN PIO_STATUS_BLOCK IoStatus,
              IN PIRP Irp,
              IN PLIST_ENTRY List)
{
    NODE_TYPE_CODE NodeType;
    BOOLEAN WriteOk;
    PNP_CCB Ccb;
    PNP_NONPAGED_CCB NonPagedCcb;
    PNP_DATA_QUEUE WriteQueue;
    NTSTATUS Status;
    PNP_EVENT_BUFFER EventBuffer;
    ULONG BytesWritten, NamedPipeEnd, ReadMode;
    PAGED_CODE();

    IoStatus->Information = 0;
    NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);

    if (!NodeType)
    {
        IoStatus->Status = STATUS_PIPE_DISCONNECTED;
        return TRUE;
    }

    if (NodeType != NPFS_NTC_CCB)
    {
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        return TRUE;
    }

    NonPagedCcb = Ccb->NonPagedCcb;
    ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);

    if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE)
    {
        if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE)
        {
            IoStatus->Status = STATUS_PIPE_DISCONNECTED;
        }
        else if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE)
        {
            IoStatus->Status = STATUS_PIPE_LISTENING;
        }
        else
        {
            ASSERT(Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE);
            IoStatus->Status = STATUS_PIPE_CLOSING;
        }

        WriteOk = TRUE;
        goto Quickie;
    }

    if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) ||
        (NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND))
    {
        IoStatus->Status = STATUS_INVALID_PARAMETER;
        WriteOk = TRUE;
        goto Quickie;
    }

    IoStatus->Status = STATUS_SUCCESS;
    IoStatus->Information = DataSize;

    if (NamedPipeEnd == FILE_PIPE_SERVER_END)
    {
        WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND];
        ReadMode = Ccb->ReadMode[FILE_PIPE_CLIENT_END];
    }
    else
    {
        WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND];
        ReadMode = Ccb->ReadMode[FILE_PIPE_SERVER_END];
    }

    EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];

    if ((WriteQueue->QueueState == ReadEntries &&
        WriteQueue->BytesInQueue < DataSize &&
        WriteQueue->Quota < DataSize - WriteQueue->BytesInQueue) ||
        (WriteQueue->QueueState == ReadEntries &&
        WriteQueue->Quota - WriteQueue->QuotaUsed < DataSize))
    {
        if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE &&
            Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION)
        {
            IoStatus->Information = 0;
            IoStatus->Status = STATUS_SUCCESS;
            WriteOk = TRUE;
            goto Quickie;
        }

        if (!Irp)
        {
            WriteOk = FALSE;
            goto Quickie;
        }
    }

    Status = NpWriteDataQueue(WriteQueue,
                              ReadMode,
                              Buffer,
                              DataSize,
                              Ccb->Fcb->NamedPipeType,
                              &BytesWritten,
                              Ccb,
                              NamedPipeEnd,
                              Thread,
                              List);
    IoStatus->Status = Status;

    if (Status == STATUS_MORE_PROCESSING_REQUIRED)
    {
        ASSERT(WriteQueue->QueueState != ReadEntries);
        if ((Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION || !Irp) &&
            ((WriteQueue->Quota - WriteQueue->QuotaUsed) < BytesWritten))
        {
            IoStatus->Information = DataSize - BytesWritten;
            IoStatus->Status = STATUS_SUCCESS;
        }
        else
        {
            ASSERT(WriteQueue->QueueState != ReadEntries);

            IoStatus->Status = NpAddDataQueueEntry(NamedPipeEnd,
                                                   Ccb,
                                                   WriteQueue,
                                                   WriteEntries,
                                                   Buffered,
                                                   DataSize,
                                                   Irp,
                                                   Buffer,
                                                   DataSize - BytesWritten);
        }
    }

    if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE);
    WriteOk = TRUE;

Quickie:
    ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock);
    return WriteOk;
}
Example #16
0
NTSTATUS
NpCommonDirectoryControl (
    IN PNPFS_DEVICE_OBJECT NpfsDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine does the common code for directory control functions.

Arguments:

    NpfsDeviceObject - Supplies the named pipe device object

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;

    PIO_STACK_LOCATION IrpSp;

    PFCB Fcb;
    PROOT_DCB_CCB Ccb;

    PAGED_CODE();

    //
    //  Get the current stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "NpCommonDirectoryControl...\n", 0);
    DebugTrace( 0, Dbg, "Irp  = %08lx\n", Irp);

    //
    //  Decode the file object to figure out who we are.  If the result
    //  is not the root dcb then its an illegal parameter.
    //

    if (NpDecodeFileObject( IrpSp->FileObject,
                            &Fcb,
                            (PCCB *)&Ccb,
                            NULL ) != NPFS_NTC_ROOT_DCB) {

        DebugTrace(0, Dbg, "Not a directory\n", 0);

        NpCompleteRequest( Irp, STATUS_INVALID_PARAMETER );
        Status = STATUS_INVALID_PARAMETER;

        DebugTrace(-1, Dbg, "NpCommonDirectoryControl -> %08lx\n", Status );
        return Status;
    }

    //
    //  We know this is a directory control so we'll case on the
    //  minor function, and call the appropriate work routines.
    //

    switch (IrpSp->MinorFunction) {

    case IRP_MN_QUERY_DIRECTORY:

        Status = NpQueryDirectory( Fcb, Ccb, Irp );
        break;

    case IRP_MN_NOTIFY_CHANGE_DIRECTORY:

        Status = NpNotifyChangeDirectory( Fcb, Ccb, Irp );
        break;

    default:

        //
        //  For all other minor function codes we say they're invalid
        //  and complete the request.
        //

        DebugTrace(0, DEBUG_TRACE_ERROR, "Invalid FS Control Minor Function Code %08lx\n", IrpSp->MinorFunction);

        NpCompleteRequest( Irp, STATUS_INVALID_DEVICE_REQUEST );
        Status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    DebugTrace(-1, Dbg, "NpCommonDirectoryControl -> %08lx\n", Status);
    return Status;
}