Esempio n. 1
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);
}
Esempio n. 2
0
NTSTATUS
CdfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
                PFCB DirectoryFcb,
                PUNICODE_STRING FileToFind,
                PFCB *FoundFCB)
{
    UNICODE_STRING TempName;
    WCHAR Name[256];
    PVOID Block;
    ULONG DirSize;
    PDIR_RECORD Record;
    ULONG Offset;
    ULONG BlockOffset;
    NTSTATUS Status;

    LARGE_INTEGER StreamOffset, OffsetOfEntry;
    PVOID Context;

    WCHAR ShortNameBuffer[13];
    UNICODE_STRING ShortName;
    UNICODE_STRING LongName;
    UNICODE_STRING FileToFindUpcase;

    ASSERT(DeviceExt);
    ASSERT(DirectoryFcb);
    ASSERT(FileToFind);

    DPRINT("CdfsDirFindFile(VCB:%p, dirFCB:%p, File:%wZ)\n",
        DeviceExt,
        DirectoryFcb,
        FileToFind);
    DPRINT("Dir Path:%S\n", DirectoryFcb->PathName);

    /* default to '.' if no filename specified */
    if (FileToFind->Length == 0)
    {
        RtlInitUnicodeString(&TempName, L".");
        FileToFind = &TempName;
    }

    DirSize = DirectoryFcb->Entry.DataLengthL;
    StreamOffset.QuadPart = (LONGLONG)DirectoryFcb->Entry.ExtentLocationL * (LONGLONG)BLOCKSIZE;

    if (!CcMapData(DeviceExt->StreamFileObject,
        &StreamOffset,
        BLOCKSIZE,
        TRUE,
        &Context,
        &Block))
    {
        DPRINT("CcMapData() failed\n");
        return STATUS_UNSUCCESSFUL;
    }

    Offset = 0;
    BlockOffset = 0;
    Record = (PDIR_RECORD)Block;

    /* Upper case the expression for FsRtlIsNameInExpression */
    Status = RtlUpcaseUnicodeString(&FileToFindUpcase, FileToFind, TRUE);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    while(TRUE)
    {
        if (Record->RecordLength == 0)
        {
            DPRINT("RecordLength == 0  Stopped!\n");
            break;
        }

        DPRINT("RecordLength %u  ExtAttrRecordLength %u  NameLength %u\n",
            Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);

        CdfsGetDirEntryName(DeviceExt, Record, Name);
        DPRINT ("Name '%S'\n", Name);
        DPRINT ("Sector %lu\n", DirectoryFcb->Entry.ExtentLocationL);
        DPRINT ("Offset %lu\n", Offset);

        RtlInitUnicodeString(&LongName, Name);
        ShortName.Length = 0;
        ShortName.MaximumLength = 26;
        ShortName.Buffer = ShortNameBuffer;
        memset(ShortNameBuffer, 0, 26);

        OffsetOfEntry.QuadPart = StreamOffset.QuadPart + Offset;
        CdfsShortNameCacheGet(DirectoryFcb, &OffsetOfEntry, &LongName, &ShortName);

        DPRINT("ShortName '%wZ'\n", &ShortName);

        if (FsRtlIsNameInExpression(&FileToFindUpcase, &LongName, TRUE, NULL) ||
            FsRtlIsNameInExpression(&FileToFindUpcase, &ShortName, TRUE, NULL))
        {
            DPRINT("Match found, %S\n", Name);
            Status = CdfsMakeFCBFromDirEntry(DeviceExt,
                DirectoryFcb,
                Name,
                ShortNameBuffer,
                Record,
                DirectoryFcb->Entry.ExtentLocationL,
                Offset,
                FoundFCB);

            RtlFreeUnicodeString(&FileToFindUpcase);
            CcUnpinData(Context);

            return(Status);
        }

        Offset += Record->RecordLength;
        BlockOffset += Record->RecordLength;
        Record = (PDIR_RECORD)((ULONG_PTR)Block + BlockOffset);
        if (BlockOffset >= BLOCKSIZE || Record->RecordLength == 0)
        {
            DPRINT("Map next sector\n");
            CcUnpinData(Context);
            StreamOffset.QuadPart += BLOCKSIZE;
            Offset = ROUND_UP(Offset, BLOCKSIZE);
            BlockOffset = 0;

            if (!CcMapData(DeviceExt->StreamFileObject,
                &StreamOffset,
                BLOCKSIZE, TRUE,
                &Context, &Block))
            {
                DPRINT("CcMapData() failed\n");
                RtlFreeUnicodeString(&FileToFindUpcase);
                return(STATUS_UNSUCCESSFUL);
            }
            Record = (PDIR_RECORD)((ULONG_PTR)Block + BlockOffset);
        }

        if (Offset >= DirSize)
            break;
    }

    RtlFreeUnicodeString(&FileToFindUpcase);
    CcUnpinData(Context);

    return(STATUS_OBJECT_NAME_NOT_FOUND);
}
Esempio n. 3
0
/*
* FUNCTION: Retrieves the file name, be it in short or long file name format
*/
static NTSTATUS
CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
                 PVOID *Context,
                 PVOID *Block,
                 PLARGE_INTEGER StreamOffset,
                 ULONG DirLength,
                 PVOID *Ptr,
                 PWSTR Name,
                 PULONG pIndex,
                 PULONG CurrentOffset)
{
    PDIR_RECORD Record = *Ptr;
    ULONG Index;

    if (*CurrentOffset >= DirLength)
        return(STATUS_NO_MORE_ENTRIES);

    if (*CurrentOffset == 0)
    {
        Index = 0;
        Record = (PDIR_RECORD)*Block;
        while (Index < *pIndex)
        {
            (*Ptr) = (PVOID)((ULONG_PTR)(*Ptr) + Record->RecordLength);
            (*CurrentOffset) += Record->RecordLength;
            Record = *Ptr;
            if ((ULONG_PTR)(*Ptr) - (ULONG_PTR)(*Block) >= BLOCKSIZE || Record->RecordLength == 0)
            {
                DPRINT("Map next sector\n");
                CcUnpinData(*Context);
                StreamOffset->QuadPart += BLOCKSIZE;
                *CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
                if (!CcMapData(DeviceExt->StreamFileObject,
                    StreamOffset,
                    BLOCKSIZE, TRUE,
                    Context, Block))
                {
                    DPRINT("CcMapData() failed\n");
                    return(STATUS_UNSUCCESSFUL);
                }
                *Ptr = *Block;
                Record = (PDIR_RECORD)*Ptr;
            }
            if (*CurrentOffset >= DirLength)
                return(STATUS_NO_MORE_ENTRIES);

            Index++;
        }
    }

    if ((ULONG_PTR)(*Ptr) - (ULONG_PTR)(*Block) >= BLOCKSIZE || Record->RecordLength == 0)
    {
        DPRINT("Map next sector\n");
        CcUnpinData(*Context);
        StreamOffset->QuadPart += BLOCKSIZE;
        *CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
        if (!CcMapData(DeviceExt->StreamFileObject,
            StreamOffset,
            BLOCKSIZE, TRUE,
            Context, Block))
        {
            DPRINT("CcMapData() failed\n");
            return(STATUS_UNSUCCESSFUL);
        }
        *Ptr = *Block;
        Record = (PDIR_RECORD)*Ptr;
    }

    if (*CurrentOffset >= DirLength)
        return STATUS_NO_MORE_ENTRIES;

    DPRINT("Index %lu  RecordLength %lu  Offset %lu\n",
        *pIndex, Record->RecordLength, *CurrentOffset);

    if (!CdfsIsRecordValid(DeviceExt, Record))
    {
        CcUnpinData(*Context);
        return STATUS_DISK_CORRUPT_ERROR;
    }

    CdfsGetDirEntryName(DeviceExt, Record, Name);

    *Ptr = Record;

    return(STATUS_SUCCESS);
}