Пример #1
0
static NTSTATUS
CdfsGetBothDirectoryInformation(PFCB Fcb,
                                PDEVICE_EXTENSION DeviceExt,
                                PFILE_BOTH_DIR_INFORMATION Info,
                                ULONG BufferLength)
{
    ULONG Length;

    DPRINT("CdfsGetBothDirectoryInformation() called\n");

    UNREFERENCED_PARAMETER(DeviceExt);

    Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
    if ((sizeof (FILE_BOTH_DIR_INFORMATION) + Length) > BufferLength)
        return(STATUS_BUFFER_OVERFLOW);

    Info->FileNameLength = Length;
    Info->NextEntryOffset =
        ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG));
    RtlCopyMemory(Info->FileName, Fcb->ObjectName, Length);

    /* Convert file times */
    CdfsDateTimeToSystemTime(Fcb,
        &Info->CreationTime);
    Info->LastWriteTime = Info->CreationTime;
    Info->ChangeTime = Info->CreationTime;

    /* Convert file flags */
    CdfsFileFlagsToAttributes(Fcb,
        &Info->FileAttributes);

    if (CdfsFCBIsDirectory(Fcb))
    {
        Info->EndOfFile.QuadPart = 0;
        Info->AllocationSize.QuadPart = 0;
    }
    else
    {
        Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;

        /* Make AllocSize a rounded up multiple of the sector size */
        Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
    }

    //  Info->FileIndex=;
    Info->EaSize = 0;

    /* Copy short name */
    ASSERT(Fcb->ShortNameU.Length / sizeof(WCHAR) <= 12);
    Info->ShortNameLength = (CCHAR)Fcb->ShortNameU.Length;
    RtlCopyMemory(Info->ShortName, Fcb->ShortNameU.Buffer, Fcb->ShortNameU.Length);

    return(STATUS_SUCCESS);
}
Пример #2
0
VOID
CdfsReleaseFCB(PDEVICE_EXTENSION Vcb,
               PFCB Fcb)
{
    KIRQL  oldIrql;

    DPRINT("releasing FCB at %x: %S, refCount:%d\n",
        Fcb,
        Fcb->PathName,
        Fcb->RefCount);

    KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
    Fcb->RefCount--;
    if (Fcb->RefCount <= 0 && !CdfsFCBIsDirectory(Fcb))
    {
        RemoveEntryList(&Fcb->FcbListEntry);
        CdfsDestroyFCB(Fcb);
    }
    KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
Пример #3
0
/*
* FUNCTION: Retrieve the standard file information
*/
static NTSTATUS
CdfsGetStandardInformation(PFCB Fcb,
                           PDEVICE_OBJECT DeviceObject,
                           PFILE_STANDARD_INFORMATION StandardInfo,
                           PULONG BufferLength)
{
    DPRINT("CdfsGetStandardInformation() called\n");

    UNREFERENCED_PARAMETER(DeviceObject);

    if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
        return STATUS_BUFFER_OVERFLOW;

    /* PRECONDITION */
    ASSERT(StandardInfo != NULL);
    ASSERT(Fcb != NULL);

    RtlZeroMemory(StandardInfo,
        sizeof(FILE_STANDARD_INFORMATION));

    if (CdfsFCBIsDirectory(Fcb))
    {
        StandardInfo->AllocationSize.QuadPart = 0LL;
        StandardInfo->EndOfFile.QuadPart = 0LL;
        StandardInfo->Directory = TRUE;
    }
    else
    {
        StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
        StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
        StandardInfo->Directory = FALSE;
    }
    StandardInfo->NumberOfLinks = 0;
    StandardInfo->DeletePending = FALSE;

    *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
    return(STATUS_SUCCESS);
}
Пример #4
0
NTSTATUS
CdfsAttachFCBToFileObject(PDEVICE_EXTENSION Vcb,
                          PFCB Fcb,
                          PFILE_OBJECT FileObject)
{
    PCCB  newCCB;

    newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(CCB), TAG_CCB);
    if (newCCB == NULL)
    {
        return(STATUS_INSUFFICIENT_RESOURCES);
    }
    memset(newCCB, 0, sizeof(CCB));

    FileObject->ReadAccess = TRUE;
    FileObject->WriteAccess = FALSE;
    FileObject->DeleteAccess = FALSE;
    FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
    FileObject->FsContext = Fcb;
    FileObject->FsContext2 = newCCB;
    newCCB->PtrFileObject = FileObject;
    Fcb->DevExt = Vcb;

    if (CdfsFCBIsDirectory(Fcb))
    {
        CcInitializeCacheMap(FileObject,
            (PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
            FALSE,
            &(CdfsGlobalData->CacheMgrCallbacks),
            Fcb);
        Fcb->Flags |= FCB_CACHE_INITIALIZED;
    }

    DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);

    return(STATUS_SUCCESS);
}
Пример #5
0
/*
* FUNCTION: Retrieve the file network open information
*/
static NTSTATUS
CdfsGetNetworkOpenInformation(PFCB Fcb,
                              PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
                              PULONG BufferLength)
{
    ASSERT(NetworkInfo);
    ASSERT(Fcb);

    if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
        return(STATUS_BUFFER_OVERFLOW);

    CdfsDateTimeToSystemTime(Fcb,
        &NetworkInfo->CreationTime);
    CdfsDateTimeToSystemTime(Fcb,
        &NetworkInfo->LastAccessTime);
    CdfsDateTimeToSystemTime(Fcb,
        &NetworkInfo->LastWriteTime);
    CdfsDateTimeToSystemTime(Fcb,
        &NetworkInfo->ChangeTime);
    if (CdfsFCBIsDirectory(Fcb))
    {
        NetworkInfo->AllocationSize.QuadPart = 0LL;
        NetworkInfo->EndOfFile.QuadPart = 0LL;
    }
    else
    {
        NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
        NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
    }
    CdfsFileFlagsToAttributes(Fcb,
        &NetworkInfo->FileAttributes);

    *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);

    return(STATUS_SUCCESS);
}
Пример #6
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;
}
Пример #7
0
NTSTATUS
CdfsMakeFCBFromDirEntry(PVCB Vcb,
                        PFCB DirectoryFCB,
                        PWSTR LongName,
                        PWSTR ShortName,
                        PDIR_RECORD Record,
                        ULONG DirectorySector,
                        ULONG DirectoryOffset,
                        PFCB * fileFCB)
{
    WCHAR pathName[MAX_PATH];
    PFCB rcFCB;
    ULONG Size;

    if (LongName [0] != 0 && wcslen (DirectoryFCB->PathName) +
        sizeof(WCHAR) + wcslen (LongName) > MAX_PATH)
    {
        return(STATUS_OBJECT_NAME_INVALID);
    }

    wcscpy(pathName, DirectoryFCB->PathName);
    if (!CdfsFCBIsRoot(DirectoryFCB))
    {
        wcscat(pathName, L"\\");
    }

    if (LongName[0] != 0)
    {
        wcscat(pathName, LongName);
    }
    else
    {
        WCHAR entryName[MAX_PATH];

        CdfsGetDirEntryName(Vcb, Record, entryName);
        wcscat(pathName, entryName);
    }

    rcFCB = CdfsCreateFCB(pathName);
    memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD));

    /* Copy short name into FCB */
    rcFCB->ShortNameU.Length = wcslen(ShortName) * sizeof(WCHAR);
    rcFCB->ShortNameU.MaximumLength = rcFCB->ShortNameU.Length;
    rcFCB->ShortNameU.Buffer = rcFCB->ShortNameBuffer;
    wcscpy(rcFCB->ShortNameBuffer, ShortName);

    Size = rcFCB->Entry.DataLengthL;

    rcFCB->RFCB.FileSize.QuadPart = Size;
    rcFCB->RFCB.ValidDataLength.QuadPart = Size;
    rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE);
    if (CdfsFCBIsDirectory(rcFCB))
    {
        CdfsFCBInitializeCache(Vcb, rcFCB);
    }
    rcFCB->IndexNumber.u.HighPart = DirectorySector;
    rcFCB->IndexNumber.u.LowPart = DirectoryOffset;
    rcFCB->RefCount++;
    CdfsAddFCBToTable(Vcb, rcFCB);
    *fileFCB = rcFCB;

    DPRINT("%S %d %I64d\n", LongName, Size, rcFCB->RFCB.AllocationSize.QuadPart);

    return(STATUS_SUCCESS);
}
Пример #8
0
/*
* FUNCTION: Retrieve all file information
*/
static NTSTATUS
CdfsGetAllInformation(PFILE_OBJECT FileObject,
                      PFCB Fcb,
                      PFILE_ALL_INFORMATION Info,
                      PULONG BufferLength)
{
    ULONG NameLength;

    ASSERT(Info);
    ASSERT(Fcb);

    NameLength = Fcb->PathName.Length;
    if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength)
        return(STATUS_BUFFER_OVERFLOW);

    /* Basic Information */
    CdfsDateTimeToSystemTime(Fcb,
        &Info->BasicInformation.CreationTime);
    CdfsDateTimeToSystemTime(Fcb,
        &Info->BasicInformation.LastAccessTime);
    CdfsDateTimeToSystemTime(Fcb,
        &Info->BasicInformation.LastWriteTime);
    CdfsDateTimeToSystemTime(Fcb,
        &Info->BasicInformation.ChangeTime);
    CdfsFileFlagsToAttributes(Fcb,
        &Info->BasicInformation.FileAttributes);

    /* Standard Information */
    if (CdfsFCBIsDirectory(Fcb))
    {
        Info->StandardInformation.AllocationSize.QuadPart = 0LL;
        Info->StandardInformation.EndOfFile.QuadPart = 0LL;
        Info->StandardInformation.Directory = TRUE;
    }
    else
    {
        Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
        Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
        Info->StandardInformation.Directory = FALSE;
    }
    Info->StandardInformation.NumberOfLinks = 0;
    Info->StandardInformation.DeletePending = FALSE;

    /* Internal Information */
    Info->InternalInformation.IndexNumber.QuadPart = Fcb->IndexNumber.QuadPart;

    /* EA Information */
    Info->EaInformation.EaSize = 0;

    /* Access Information */
    /* The IO-Manager adds this information */

    /* Position Information */
    Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;

    /* Mode Information */
    /* The IO-Manager adds this information */

    /* Alignment Information */
    /* The IO-Manager adds this information */

    /* Name Information */
    Info->NameInformation.FileNameLength = NameLength;
    RtlCopyMemory(Info->NameInformation.FileName,
        Fcb->PathName.Buffer,
        NameLength + sizeof(WCHAR));

    *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));

    return STATUS_SUCCESS;
}