}
/* Create a new DCB for this directory */
- Fcb = FatCreateDcb(IrpContext, Vcb, ParentDcb);
- Fcb->FatHandle = FileHandle;
+ Fcb = FatCreateDcb(IrpContext, Vcb, ParentDcb, FileHandle);
/* Set share access */
IoSetShareAccess(*DesiredAccess, ShareAccess, FileObject, &Fcb->ShareAccess);
ULONG CreateDisposition;
/* Control blocks */
- PVCB Vcb, DecodedVcb;
- PFCB Fcb, NextFcb;
- PCCB Ccb;
+ PVCB Vcb, DecodedVcb, RelatedVcb;
+ PFCB Fcb, NextFcb, RelatedDcb;
+ PCCB Ccb, RelatedCcb;
PFCB ParentDcb;
/* IRP data */
UNICODE_STRING RemainingPart, FirstName, NextName;
OEM_STRING AnsiFirstName;
FF_ERROR FfError;
+ TYPE_OF_OPEN TypeOfOpen;
Iosb.Status = STATUS_SUCCESS;
/* Check if this is a relative open */
if (RelatedFO)
{
- // RelatedFO will be a parent directory
- UNIMPLEMENTED;
+ /* Decode the file object */
+ TypeOfOpen = FatDecodeFileObject(RelatedFO,
+ &RelatedVcb,
+ &RelatedDcb,
+ &RelatedCcb);
+
+ /* Check open type */
+ if (TypeOfOpen != UserFileOpen &&
+ TypeOfOpen != UserDirectoryOpen)
+ {
+ DPRINT1("Invalid file object!\n");
+
+ /* Cleanup and return */
+ FatReleaseVcb(IrpContext, Vcb);
+ return STATUS_OBJECT_PATH_NOT_FOUND;
+ }
+
+ /* File path must be relative */
+ if (FileName.Length != 0 &&
+ FileName.Buffer[0] == L'\\')
+ {
+ /* The name is absolute, fail */
+ FatReleaseVcb(IrpContext, Vcb);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ /* Make sure volume is the same */
+ ASSERT(RelatedVcb == Vcb);
+
+ /* Save VPB */
+ FileObject->Vpb = RelatedFO->Vpb;
+
+ /* Set parent DCB */
+ ParentDcb = RelatedDcb;
+
+ DPRINT1("Opening file '%wZ' relatively to '%wZ'\n", &FileName, &ParentDcb->FullFileName);
}
else
{
/* Create a DCB for this entry */
ParentDcb = FatCreateDcb(IrpContext,
Vcb,
- ParentDcb);
+ ParentDcb,
+ NULL);
/* Set its name */
FatSetFullNameInFcb(ParentDcb, &FirstName);