fcb.c
来自「一个类似windows」· C语言 代码 · 共 687 行 · 第 1/2 页
C
687 行
}
NTSTATUS
NtfsMakeFCBFromDirEntry(PVCB Vcb,
PFCB DirectoryFCB,
PWSTR Name,
PDIR_RECORD Record,
PFCB * fileFCB)
{
WCHAR pathName[MAX_PATH];
PFCB rcFCB;
ULONG Size;
if (Name [0] != 0 && wcslen (DirectoryFCB->PathName) +
sizeof(WCHAR) + wcslen (Name) > MAX_PATH)
{
return(STATUS_OBJECT_NAME_INVALID);
}
wcscpy(pathName, DirectoryFCB->PathName);
if (!NtfsFCBIsRoot(DirectoryFCB))
{
wcscat(pathName, L"\\");
}
if (Name[0] != 0)
{
wcscat(pathName, Name);
}
else
{
WCHAR entryName[MAX_PATH];
NtfsGetDirEntryName(Vcb, Record, entryName);
wcscat(pathName, entryName);
}
rcFCB = NtfsCreateFCB(pathName);
memcpy(&rcFCB->Entry, Record, sizeof(DIR_RECORD));
Size = rcFCB->Entry.DataLengthL;
rcFCB->RFCB.FileSize.QuadPart = Size;
rcFCB->RFCB.ValidDataLength.QuadPart = Size;
rcFCB->RFCB.AllocationSize.QuadPart = ROUND_UP(Size, BLOCKSIZE);
// DPRINT1("%S %d %d\n", longName, Size, (ULONG)rcFCB->RFCB.AllocationSize.QuadPart);
NtfsFCBInitializeCache(Vcb, rcFCB);
rcFCB->RefCount++;
NtfsAddFCBToTable(Vcb, rcFCB);
*fileFCB = rcFCB;
return(STATUS_SUCCESS);
}
#endif
NTSTATUS
NtfsAttachFCBToFileObject(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->SectionObjectPointer = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject = FileObject;
Fcb->DevExt = Vcb;
if (!(Fcb->Flags & FCB_CACHE_INITIALIZED))
{
#ifdef ROS_USE_CC_AND_FS
NTSTATUS Status;
Status = CcRosInitializeFileCache(FileObject,
CACHEPAGESIZE(Vcb));
if (!NT_SUCCESS(Status))
{
DbgPrint("CcRosInitializeFileCache failed\n");
KEBUGCHECK(0);
}
#else
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
NULL,
NULL);
#endif
Fcb->Flags |= FCB_CACHE_INITIALIZED;
}
//DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);
return(STATUS_SUCCESS);
}
static NTSTATUS
NtfsDirFindFile(PDEVICE_EXTENSION DeviceExt,
PFCB DirectoryFcb,
PWSTR FileToFind,
PFCB *FoundFCB)
{
#if 0
WCHAR TempName[2];
WCHAR Name[256];
PVOID Block;
ULONG FirstSector;
ULONG DirSize;
PDIR_RECORD Record;
ULONG Offset;
ULONG BlockOffset;
NTSTATUS Status;
LARGE_INTEGER StreamOffset;
PVOID Context;
ASSERT(DeviceExt);
ASSERT(DirectoryFcb);
ASSERT(FileToFind);
DPRINT("NtfsDirFindFile(VCB:%08x, dirFCB:%08x, File:%S)\n",
DeviceExt,
DirectoryFcb,
FileToFind);
DPRINT("Dir Path:%S\n", DirectoryFcb->PathName);
/* default to '.' if no filename specified */
if (wcslen(FileToFind) == 0)
{
TempName[0] = L'.';
TempName[1] = 0;
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;
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);
NtfsGetDirEntryName(DeviceExt, Record, Name);
DPRINT("Name '%S'\n", Name);
if (wstrcmpjoki(Name, FileToFind))
{
DPRINT("Match found, %S\n", Name);
Status = NtfsMakeFCBFromDirEntry(DeviceExt,
DirectoryFcb,
Name,
Record,
FoundFCB);
CcUnpinData(Context);
return(Status);
}
Offset += Record->RecordLength;
BlockOffset += Record->RecordLength;
Record = (PDIR_RECORD)(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");
return(STATUS_UNSUCCESSFUL);
}
Record = (PDIR_RECORD)(Block + BlockOffset);
}
if (Offset >= DirSize)
break;
}
CcUnpinData(Context);
#endif
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
NTSTATUS
NtfsGetFCBForFile(PDEVICE_EXTENSION Vcb,
PFCB *pParentFCB,
PFCB *pFCB,
const PWSTR pFileName)
{
NTSTATUS Status;
WCHAR pathName [MAX_PATH];
WCHAR elementName [MAX_PATH];
PWCHAR currentElement;
PFCB FCB;
PFCB parentFCB;
DPRINT("NtfsGetFCBForFile(%x, %x, %x, '%S')\n",
Vcb,
pParentFCB,
pFCB,
pFileName);
/* Dummy code */
// FCB = NtfsOpenRootFCB(Vcb);
// *pFCB = FCB;
// *pParentFCB = NULL;
#if 1
/* Trivial case, open of the root directory on volume */
if (pFileName [0] == L'\0' || wcscmp(pFileName, L"\\") == 0)
{
DPRINT("returning root FCB\n");
FCB = NtfsOpenRootFCB(Vcb);
*pFCB = FCB;
*pParentFCB = NULL;
return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
}
else
{
currentElement = pFileName + 1;
wcscpy (pathName, L"\\");
FCB = NtfsOpenRootFCB (Vcb);
}
parentFCB = NULL;
/* Parse filename and check each path element for existance and access */
while (NtfsGetNextPathElement(currentElement) != 0)
{
/* Skip blank directory levels */
if ((NtfsGetNextPathElement(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)
{
NtfsReleaseFCB(Vcb, parentFCB);
parentFCB = NULL;
}
/* fail if element in FCB is not a directory */
if (!NtfsFCBIsDirectory(FCB))
{
DPRINT("Element in requested path is not a directory\n");
NtfsReleaseFCB(Vcb, FCB);
FCB = 0;
*pParentFCB = NULL;
*pFCB = NULL;
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
parentFCB = FCB;
/* Extract next directory level into dirName */
NtfsWSubString(pathName,
pFileName,
NtfsGetNextPathElement(currentElement) - pFileName);
DPRINT(" pathName:%S\n", pathName);
FCB = NtfsGrabFCBFromTable(Vcb, pathName);
if (FCB == NULL)
{
NtfsWSubString(elementName,
currentElement,
NtfsGetNextPathElement(currentElement) - currentElement);
DPRINT(" elementName:%S\n", elementName);
Status = NtfsDirFindFile(Vcb, parentFCB, elementName, &FCB);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
*pParentFCB = parentFCB;
*pFCB = NULL;
currentElement = NtfsGetNextPathElement(currentElement);
if (*currentElement == L'\0' || NtfsGetNextPathElement(currentElement + 1) == 0)
{
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
else
{
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
}
else if (!NT_SUCCESS(Status))
{
NtfsReleaseFCB(Vcb, parentFCB);
*pParentFCB = NULL;
*pFCB = NULL;
return(Status);
}
}
currentElement = NtfsGetNextPathElement(currentElement);
}
*pParentFCB = parentFCB;
*pFCB = FCB;
#endif
return(STATUS_SUCCESS);
}
/* EOF */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?