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); }
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; }