Exemple #1
0
NTSTATUS
CdfsCloseFile(PDEVICE_EXTENSION DeviceExt,
              PFILE_OBJECT FileObject)
              /*
              * FUNCTION: Closes a file
              */
{
    PCCB Ccb;

    DPRINT("CdfsCloseFile(DeviceExt %p, FileObject %p)\n",
        DeviceExt,
        FileObject);

    Ccb = (PCCB)(FileObject->FsContext2);

    DPRINT("Ccb %p\n", Ccb);
    if (Ccb == NULL)
    {
        return(STATUS_SUCCESS);
    }

    FileObject->FsContext2 = NULL;

    if (FileObject->FileName.Buffer)
    {
        // This a FO, that was created outside from FSD.
        // Some FO's are created with IoCreateStreamFileObject() insid from FSD.
        // This FO's don't have a FileName.
        CdfsReleaseFCB(DeviceExt, FileObject->FsContext);
    }

    if (Ccb->DirectorySearchPattern.Buffer)
    {
        ExFreePoolWithTag(Ccb->DirectorySearchPattern.Buffer, TAG_CCB);
    }
    ExFreePoolWithTag(Ccb, TAG_CCB);

    return(STATUS_SUCCESS);
}
Exemple #2
0
NTSTATUS
CdfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
                  PFCB *pParentFCB,
                  PFCB *pFCB,
                  PUNICODE_STRING FileName)
{
    UNICODE_STRING PathName;
    UNICODE_STRING ElementName;
    NTSTATUS Status;
    WCHAR  pathName [MAX_PATH];
    WCHAR  elementName [MAX_PATH];
    PWCHAR  currentElement;
    PFCB  FCB;
    PFCB  parentFCB;

    DPRINT("CdfsGetFCBForFile(%x, %x, %x, '%wZ')\n",
        Vcb,
        pParentFCB,
        pFCB,
        FileName);

    /* Trivial case, open of the root directory on volume */
    if (FileName->Buffer[0] == L'\0' || wcscmp(FileName->Buffer, L"\\") == 0)
    {
        DPRINT("returning root FCB\n");

        FCB = CdfsOpenRootFCB(Vcb);
        *pFCB = FCB;
        *pParentFCB = NULL;

        return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
    }
    else
    {
        currentElement = &FileName->Buffer[1];
        wcscpy (pathName, L"\\");
        FCB = CdfsOpenRootFCB (Vcb);
    }
    parentFCB = NULL;

    /* Parse filename and check each path element for existance and access */
    while (CdfsGetNextPathElement(currentElement) != 0)
    {
        /*  Skip blank directory levels */
        if ((CdfsGetNextPathElement(currentElement) - currentElement) == 0)
        {
            currentElement++;
            continue;
        }

        DPRINT("Parsing, currentElement:%S\n", currentElement);
        DPRINT("  parentFCB:%x FCB:%x\n", parentFCB, FCB);

        /* Descend to next directory level */
        if (parentFCB)
        {
            CdfsReleaseFCB(Vcb, parentFCB);
            parentFCB = NULL;
        }

        /* fail if element in FCB is not a directory */
        if (!CdfsFCBIsDirectory(FCB))
        {
            DPRINT("Element in requested path is not a directory\n");

            CdfsReleaseFCB(Vcb, FCB);
            FCB = 0;
            *pParentFCB = NULL;
            *pFCB = NULL;

            return(STATUS_OBJECT_PATH_NOT_FOUND);
        }
        parentFCB = FCB;

        /* Extract next directory level into dirName */
        CdfsWSubString(pathName,
            FileName->Buffer,
            CdfsGetNextPathElement(currentElement) - FileName->Buffer);
        DPRINT("  pathName:%S\n", pathName);

        RtlInitUnicodeString(&PathName, pathName);

        FCB = CdfsGrabFCBFromTable(Vcb, &PathName);
        if (FCB == NULL)
        {
            CdfsWSubString(elementName,
                currentElement,
                CdfsGetNextPathElement(currentElement) - currentElement);
            DPRINT("  elementName:%S\n", elementName);

            RtlInitUnicodeString(&ElementName, elementName);
            Status = CdfsDirFindFile(Vcb,
                parentFCB,
                &ElementName,
                &FCB);
            if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
            {
                *pParentFCB = parentFCB;
                *pFCB = NULL;
                currentElement = CdfsGetNextPathElement(currentElement);
                if (*currentElement == L'\0' || CdfsGetNextPathElement(currentElement + 1) == 0)
                {
                    return(STATUS_OBJECT_NAME_NOT_FOUND);
                }
                else
                {
                    return(STATUS_OBJECT_PATH_NOT_FOUND);
                }
            }
            else if (!NT_SUCCESS(Status))
            {
                CdfsReleaseFCB(Vcb, parentFCB);
                *pParentFCB = NULL;
                *pFCB = NULL;

                return(Status);
            }
        }
        currentElement = CdfsGetNextPathElement(currentElement);
    }

    *pParentFCB = parentFCB;
    *pFCB = FCB;

    return STATUS_SUCCESS;
}