Example #1
0
static
VOID
IopDeviceFree(
    IN OUT PIO_DEVICE_OBJECT* ppDeviceObject
    )
{
    PIO_DEVICE_OBJECT pDeviceObject = *ppDeviceObject;

    if (pDeviceObject)
    {
        // The object should have already been rundown

        LWIO_ASSERT(LwListIsEmpty(&pDeviceObject->FileObjectsList));

        // The device should not be in any lists.
        LWIO_ASSERT(LwListIsEmpty(&pDeviceObject->RootLinks));
        LWIO_ASSERT(LwListIsEmpty(&pDeviceObject->DriverLinks));

        RtlUnicodeStringFree(&pDeviceObject->DeviceName);

        LwRtlCleanupMutex(&pDeviceObject->Mutex);
        LwRtlCleanupMutex(&pDeviceObject->CancelMutex);

        IopDriverDereference(&pDeviceObject->Driver);

        IoMemoryFree(pDeviceObject);
        *ppDeviceObject = NULL;
    }
}
Example #2
0
VOID
IopFileObjectFree(
    IN OUT PIO_FILE_OBJECT* ppFileObject
    )
{
    PIO_FILE_OBJECT pFileObject = *ppFileObject;

    if (pFileObject)
    {
        LWIO_ASSERT(LwListIsEmpty(&pFileObject->IrpList));

        IopIrpFreeZctIrpList(pFileObject);

        IopDeviceLock(pFileObject->pDevice);
        LwListRemove(&pFileObject->DeviceLinks);
        IopDeviceUnlock(pFileObject->pDevice);

        IopDeviceDereference(&pFileObject->pDevice);

        LwRtlCleanupConditionVariable(&pFileObject->Rundown.Condition);
        LwRtlCleanupMutex(&pFileObject->Mutex);

        LwRtlUnicodeStringFree(&pFileObject->FileName);

        IopIrpDereference(&pFileObject->pCloseIrp);

        IoMemoryFree(pFileObject);
        *ppFileObject = NULL;
    }
}
Example #3
0
static
VOID
PvfsWildcardStackDestroy(
    PLW_LIST_LINKS pStack
    )
{
    PSTR a = NULL;
    PSTR b = NULL;

    while (!LwListIsEmpty(pStack))
    {
        PvfsWildcardStackPop(pStack, &a, &b);
    }
}
Example #4
0
NTSTATUS
NpfsClientCloseHandle(
    PNPFS_CCB pCCB
    )
{
    NTSTATUS ntStatus = 0;
    PNPFS_PIPE pPipe = NULL;
    PNPFS_CCB pSCB = NULL;
    PLW_LIST_LINKS pLink = NULL;
    PNPFS_IRP_CONTEXT pReadContext = NULL;

    pPipe = pCCB->pPipe;

    ENTER_MUTEX(&pPipe->PipeMutex);

    pSCB = pPipe->pSCB;

    pPipe->PipeClientState = PIPE_CLIENT_CLOSED;

    while (pSCB && !LwListIsEmpty(&pSCB->ReadIrpList))
    {
        pLink = pSCB->ReadIrpList.Next;
        LwListRemove(pLink);

        pReadContext = LW_STRUCT_FROM_FIELD(pLink, NPFS_IRP_CONTEXT, Link);

        NpfsServerCompleteReadFile(pSCB, pReadContext);
    }

    pthread_cond_signal(&pPipe->PipeCondition);

    if (pPipe->PipeServerState == PIPE_SERVER_CLOSED)
    {
        ntStatus = NpfsFreePipeContext(pPipe);
        BAIL_ON_NT_STATUS(ntStatus);
    }

error:

    pPipe->pCCB = NULL;

    LEAVE_MUTEX(&pPipe->PipeMutex);

    NpfsReleaseCCB(pCCB);

    return(ntStatus);
}
Example #5
0
PLW_LIST_LINKS
LwListTraverse(
    IN PLW_LIST_LINKS Head,
    IN PLW_LIST_LINKS Cursor
    )
{
    if (LwListIsEmpty(Head)) {
        return NULL;
    }

    if (Cursor == NULL) {
        return Head->Next;
    }

    if (Cursor->Next == Head) {
        return NULL;
    }

    return Cursor->Next;
}
Example #6
0
BOOL
PvfsListIsEmpty(
    PPVFS_LIST pList
    )
{
    BOOLEAN bIsEmpty = FALSE;
    NTSTATUS ntError = STATUS_SUCCESS;

    if (pList->CurrentSize == 0)
    {
        bIsEmpty = TRUE;
        if (!LwListIsEmpty(&pList->DataList))
        {
            /* This would be a logic error */
            ntError = STATUS_INTERNAL_ERROR;
            ntError = ntError;
        }
    }

    return bIsEmpty;
}
Example #7
0
VOID
IopIrpFreeZctIrpList(
    IN OUT PIO_FILE_OBJECT pFileObject
    )
{
    PLW_LIST_LINKS pLinks = NULL;;
    PIRP_INTERNAL irpInternal = NULL;
    PIRP pIrp = NULL;

    while (!LwListIsEmpty(&pFileObject->ZctCompletionIrpList))
    {
        pLinks = LwListRemoveHead(&pFileObject->ZctCompletionIrpList);
        irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, CancelLinks);
        pIrp = &irpInternal->Irp;

        LWIO_ASSERT(1 == irpInternal->ReferenceCount);
        LWIO_ASSERT(!pIrp->FileHandle);

        IopIrpDereference(&pIrp);
    }
}
Example #8
0
BOOLEAN
PvfsWildcardMatch(
    IN PSTR pszPathname,
    IN PSTR pszPattern,
    IN BOOLEAN bCaseSensitive
    )
{
    NTSTATUS ntError = STATUS_SUCCESS;
    PSTR pszString = NULL;
    PSTR pszMatch  = NULL;
    PSTR pszPathUpper = NULL;
    PSTR pszPatternUpper = NULL;
    BOOLEAN bMatched = FALSE;
    LW_LIST_LINKS Stack;

    // Quick check for an exact match

    if (!strchr(pszPattern, '?') && !strchr(pszPattern, '*'))
    {
        return RtlCStringIsEqual(pszPathname, pszPattern, bCaseSensitive);
    }

    // If we have a case insensitive search, upper case the Pathname
    // and Pattern for easier comparison

    pszString = pszPathname;
    pszMatch = pszPattern;

    if (!bCaseSensitive) {
        ntError = RtlCStringDuplicate(&pszPathUpper, pszPathname);
        BAIL_ON_NT_STATUS(ntError);

        ntError = RtlCStringDuplicate(&pszPatternUpper, pszPattern);
        BAIL_ON_NT_STATUS(ntError);

        PvfsCStringUpper(pszPathUpper);
        PvfsCStringUpper(pszPatternUpper);

        pszString = pszPathUpper;
        pszMatch  = pszPatternUpper;
    }


    // Enter state machine

    LwListInit(&Stack);

reset_state:
    while (PVFS_CSTRING_NON_NULL(pszString) && PVFS_CSTRING_NON_NULL(pszMatch))
    {
        PVFS_WILDCARD_TYPE eState = 0;
        CHAR cSrc = '\0';
        CHAR cMatch = '\0';
        DWORD dwCount = 0;

        // Save the current CHAR

        cSrc = *pszString;
        cMatch = *pszMatch;


        // Certain characters should never match and hence allow us to filter
        // certain file patterns

        if (cSrc == PVFS_STREAM_DELIMINATOR_C)
        {
            bMatched = FALSE;
            goto cleanup;
        }

        // Consumes the pattern from pszMatch

        eState = NextMatchState(&pszMatch, &dwCount);

        switch (eState)
        {
        case PVFS_WILDCARD_TYPE_NONE:
            if (cSrc != cMatch)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString++;
            }
            break;

        case PVFS_WILDCARD_TYPE_SPLAT:
        {
            // We are done if this is the last character in the pattern
            if (!PVFS_CSTRING_NON_NULL(pszMatch))
            {
                pszString = NULL;
            }
            else
            {
                // Be greedy - Consume as much of the string using the '*'
                // as possible.  This will require a stack in order to backtrack
                // on a failure.
                pszString = PvfsWildcardEatString(pszString, pszMatch);
                if (!pszString)
                {
                    ntError = STATUS_NO_MATCH;
                }
                else
                {
                    // Add next character past "String" match and the previously
                    // match "Pattern" state (so we pick up the '*' when we pop
                    // the stack
                    ntError = PvfsWildcardStackPush(
                                  &Stack,
                                  pszString+1,
                                  pszMatch-1);
                    BAIL_ON_NT_STATUS(ntError);
                }
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE:
        {
            DWORD i = 0;

            // Consume dwCount characters
            for (i=0;
                 (i<dwCount) && PVFS_CSTRING_NON_NULL(pszString);
                 i++, pszString++)
            {
                // no loop body
                ;
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_DOT:
            // For now deal with the '.' as just another character
            if (cSrc != cMatch)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString++;
            }

            break;

        case PVFS_WILDCARD_TYPE_SPLAT_DOT:
        {
            PSTR pszCursor = NULL;

            // Similar to "A*B" except we search for the '.' from the end

            if ((pszCursor = strrchr(pszString, '.')) == NULL)
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }
            else
            {
                pszString = pszCursor + 1;
            }
            break;
        }

        case PVFS_WILDCARD_TYPE_SINGLE_DOT:
        {
            DWORD i = 0;

            // We can match 0 - dwCount characters up to the last '.'
            // This is really a hold over from DOS 8.3 filenames

            for (i=0;
                 i<dwCount && PVFS_CSTRING_NON_NULL(pszString) && (*pszString != '.');
                 i++, pszString++)
            {
                // no loop body
                ;
            }

            // If we any path left, it better be on '.' for a match

            if (*pszString == '.')
            {
                pszString++;
            }
            else
            {
                ntError = STATUS_NO_MATCH;
                pszString = NULL;
            }

            break;
        }

        }    // end of switch {...}
    }        // end of for {...}

    // We matched if pszString is empty AND either pszMatch is empty
    // OR only contains wildcard characters

    if ((ntError == STATUS_SUCCESS) &&
        !PVFS_CSTRING_NON_NULL(pszString) &&
        (!PVFS_CSTRING_NON_NULL(pszMatch) ||
         PvfsCStringOnlyContainsChars(pszMatch, "?*")))
    {
        bMatched = TRUE;
    }
    else if (!LwListIsEmpty(&Stack))
    {
        // Pop back to the earlier state, consume one character (*from '*')
        // and try another path
        ntError = PvfsWildcardStackPop(&Stack, &pszString, &pszMatch);
        BAIL_ON_NT_STATUS(ntError);

        pszString++;
        goto reset_state;
    }


cleanup:

    PvfsWildcardStackDestroy(&Stack);

    if (!bCaseSensitive)
    {
        PVFS_FREE(&pszPathUpper);
        PVFS_FREE(&pszPatternUpper);
    }

    // If we have any string left to parse, we don't have a match

    return bMatched;

error:
    goto cleanup;
}
Example #9
0
NTSTATUS
IopDeviceRundown(
    IN PIO_DEVICE_OBJECT pDeviceObject
    )
{
    NTSTATUS status = 0;
    int EE = 0;
    BOOLEAN isLocked = FALSE;
    PLW_LIST_LINKS pLinks = NULL;
    LW_LIST_LINKS rundownList = { 0 };

    LwListInit(&rundownList);

    IopDeviceLock(pDeviceObject);
    isLocked = TRUE;

    if (IsSetFlag(pDeviceObject->Flags, IO_DEVICE_OBJECT_FLAG_RUNDOWN))
    {
        // TODO: Perhaps wait if currently running down.

        status = STATUS_SUCCESS;
        GOTO_CLEANUP_EE(EE);
    }

    SetFlag(pDeviceObject->Flags, IO_DEVICE_OBJECT_FLAG_RUNDOWN);

    // Gather rundown list

    for (pLinks = pDeviceObject->FileObjectsList.Next;
         pLinks != &pDeviceObject->FileObjectsList;
         pLinks = pLinks->Next)
    {
        PIO_FILE_OBJECT pFileObject = LW_STRUCT_FROM_FIELD(pLinks, IO_FILE_OBJECT, DeviceLinks);

        IopFileObjectReference(pFileObject);
        LwListInsertTail(&rundownList, &pFileObject->RundownLinks);
    }

    IopDeviceUnlock(pDeviceObject);
    isLocked = FALSE;

    // Now, actually run down every file w/o holding the device lock.

    while (!LwListIsEmpty(&rundownList))
    {
        PIO_FILE_OBJECT pFileObject = NULL;

        pLinks = LwListRemoveHead(&rundownList);
        pFileObject = LW_STRUCT_FROM_FIELD(pLinks, IO_FILE_OBJECT, RundownLinks);

        IopFileObjectRundown(pFileObject);
    }

    IopRootRemoveDevice(pDeviceObject->Driver->Root, &pDeviceObject->RootLinks);

cleanup:
    if (isLocked)
    {
        IopDeviceUnlock(pDeviceObject);
    }

    IO_LOG_LEAVE_ON_STATUS_EE(status, EE);
    return status;
}
Example #10
0
NTSTATUS
NpfsClientWriteFile_Connected(
    PNPFS_CCB pCCB,
    PNPFS_IRP_CONTEXT pIrpContext
    )
{
    NTSTATUS ntStatus = 0;
    PNPFS_PIPE pPipe = NULL;
    PNPFS_CCB pSCB = NULL;
    PVOID pBuffer = NULL;
    ULONG Length = 0;
    ULONG ulBytesTransferred = 0;
    PLW_LIST_LINKS pLink = NULL;
    PNPFS_IRP_CONTEXT pReadContext = NULL;

    switch (pIrpContext->pIrp->Type)
    {
        case IRP_TYPE_FS_CONTROL:

            pBuffer = pIrpContext->pIrp->Args.IoFsControl.InputBuffer;
            Length = pIrpContext->pIrp->Args.IoFsControl.InputBufferLength;

            break;

        default:

            pBuffer = pIrpContext->pIrp->Args.ReadWrite.Buffer;
            Length = pIrpContext->pIrp->Args.ReadWrite.Length;

            break;
    }

    pPipe = pCCB->pPipe;
    pSCB = pPipe->pSCB;


    ntStatus = NpfsEnqueueBuffer(
                        &pSCB->mdlList,
                        pBuffer,
                        Length,
                        &ulBytesTransferred);
    BAIL_ON_NT_STATUS(ntStatus);

    while (!LwListIsEmpty(&pSCB->ReadIrpList) &&
           !NpfsMdlListIsEmpty(&pSCB->mdlList))
    {
        pLink = pSCB->ReadIrpList.Next;
        LwListRemove(pLink);

        pReadContext = LW_STRUCT_FROM_FIELD(pLink, NPFS_IRP_CONTEXT, Link);

        NpfsServerCompleteReadFile(pSCB, pReadContext);
    }

    pthread_cond_signal(&pPipe->PipeCondition);

    pIrpContext->pIrp->IoStatusBlock.BytesTransferred = ulBytesTransferred;

error:

    pIrpContext->pIrp->IoStatusBlock.Status = ntStatus;

    return(ntStatus);
}
Example #11
0
VOID
IopIrpCancelFileObject(
    IN PIO_FILE_OBJECT pFileObject,
    IN BOOLEAN IsForRundown
    )
{
    BOOLEAN isLocked = FALSE;
    PLW_LIST_LINKS pLinks = NULL;
    PIRP_INTERNAL irpInternal = NULL;
    LW_LIST_LINKS cancelList = { 0 };
    PIRP pIrp = NULL;

    LwListInit(&cancelList);

    // Gather IRPs we want to cancel while holding FO lock.
    IopFileObjectLock(pFileObject);
    isLocked = TRUE;

    if (IsSetFlag(pFileObject->Flags, FILE_OBJECT_FLAG_CANCELLED))
    {
        GOTO_CLEANUP();
    }

    if (IsForRundown)
    {
        SetFlag(pFileObject->Flags, FILE_OBJECT_FLAG_CANCELLED);
    }

    // gather list of IRPs
    for (pLinks = pFileObject->IrpList.Next;
         pLinks != &pFileObject->IrpList;
         pLinks = pLinks->Next)
    {
        irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, FileObjectLinks);

        LWIO_ASSERT(irpInternal->Irp.FileHandle == pFileObject);

        // Verify that this IRP is not already being cancelled.
        if (!irpInternal->CancelLinks.Next)
        {
            IopIrpReference(&irpInternal->Irp);
            LwListInsertTail(&cancelList, &irpInternal->CancelLinks);
        }
    }
    IopFileObjectUnlock(pFileObject);
    isLocked = FALSE;

    // Iterate over list, calling IopIrpCancel as appropriate.
    while (!LwListIsEmpty(&cancelList))
    {
        pLinks = LwListRemoveHead(&cancelList);
        irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, CancelLinks);
        pIrp = &irpInternal->Irp;

        IopIrpCancel(pIrp);
        IopIrpDereference(&pIrp);
    }

cleanup:
    if (isLocked)
    {
        IopFileObjectUnlock(pFileObject);
    }
}