/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: services/fs/cdfs/dirctl.c
+ * FILE: drivers/filesystems/cdfs/dirctl.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* Eric Kohl
CcUnpinData(*Context);
StreamOffset->QuadPart += BLOCKSIZE;
*CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
- if (!CcMapData(DeviceExt->StreamFileObject,
- StreamOffset,
- BLOCKSIZE, TRUE,
- Context, Block))
+ _SEH2_TRY
+ {
+ CcMapData(DeviceExt->StreamFileObject, StreamOffset, BLOCKSIZE, MAP_WAIT, Context, Block);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("CcMapData() failed\n");
- return(STATUS_UNSUCCESSFUL);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
*Ptr = *Block;
Record = (PDIR_RECORD)*Ptr;
}
CcUnpinData(*Context);
StreamOffset->QuadPart += BLOCKSIZE;
*CurrentOffset = ROUND_UP(*CurrentOffset, BLOCKSIZE);
- if (!CcMapData(DeviceExt->StreamFileObject,
- StreamOffset,
- BLOCKSIZE, TRUE,
- Context, Block))
+ _SEH2_TRY
+ {
+ CcMapData(DeviceExt->StreamFileObject, StreamOffset, BLOCKSIZE, MAP_WAIT, Context, Block);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("CcMapData() failed\n");
- return(STATUS_UNSUCCESSFUL);
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
*Ptr = *Block;
Record = (PDIR_RECORD)*Ptr;
}
DPRINT("Index %lu RecordLength %lu Offset %lu\n",
*pIndex, Record->RecordLength, *CurrentOffset);
- if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
- {
- wcscpy(Name, L".");
- }
- else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
- {
- wcscpy(Name, L"..");
- }
- else
+ if (!CdfsIsRecordValid(DeviceExt, Record))
{
- if (DeviceExt->CdInfo.JolietLevel == 0)
- {
- ULONG i;
-
- for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
- Name[i] = (WCHAR)Record->FileId[i];
- Name[i] = 0;
- }
- else
- {
- CdfsSwapString(Name, Record->FileId, Record->FileIdLength);
- }
+ CcUnpinData(*Context);
+ return STATUS_DISK_CORRUPT_ERROR;
}
- DPRINT("Name '%S'\n", Name);
+ CdfsGetDirEntryName(DeviceExt, Record, Name);
*Ptr = Record;
{
/* it's root : complete essentials fields then return ok */
RtlZeroMemory(Fcb, sizeof(FCB));
+ RtlInitEmptyUnicodeString(&Fcb->PathName, Fcb->PathNameBuffer, sizeof(Fcb->PathNameBuffer));
Fcb->PathNameBuffer[0] = '\\';
+ Fcb->PathName.Length = sizeof(WCHAR);
Fcb->ObjectName = &Fcb->PathNameBuffer[1];
Fcb->Entry.ExtentLocationL = DeviceExt->CdInfo.RootStart;
Fcb->Entry.DataLengthL = DeviceExt->CdInfo.RootSize;
Fcb->Entry.FileFlags = 0x02; //FILE_ATTRIBUTE_DIRECTORY;
- Fcb->PathName.Length = sizeof(WCHAR);
- Fcb->PathName.MaximumLength = sizeof(Fcb->PathNameBuffer);
- Fcb->PathName.Buffer = Fcb->PathNameBuffer;
if (pDirIndex)
*pDirIndex = 0;
StreamOffset.QuadPart += ROUND_DOWN(Offset, BLOCKSIZE);
}
- if (!CcMapData(DeviceExt->StreamFileObject, &StreamOffset,
- BLOCKSIZE, TRUE, &Context, &Block))
+ _SEH2_TRY
+ {
+ CcMapData(DeviceExt->StreamFileObject, &StreamOffset, BLOCKSIZE, MAP_WAIT, &Context, &Block);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("CcMapData() failed\n");
- return STATUS_UNSUCCESSFUL;
+ _SEH2_YIELD(return _SEH2_GetExceptionCode());
}
+ _SEH2_END;
Record = (PDIR_RECORD) ((ULONG_PTR)Block + Offset % BLOCKSIZE);
if (Offset)
{
break;
}
- else if (Status == STATUS_UNSUCCESSFUL)
+ else if (Status == STATUS_UNSUCCESSFUL || Status == STATUS_DISK_CORRUPT_ERROR)
{
/* Note: the directory cache has already been unpinned */
RtlFreeUnicodeString(&FileToFindUpcase);
DPRINT("Name '%S'\n", name);
RtlInitUnicodeString(&LongName, name);
+
ShortName.Length = 0;
ShortName.MaximumLength = 26;
ShortName.Buffer = ShortNameBuffer;
{
if (Parent->PathName.Buffer[0])
{
+ RtlCopyUnicodeString(&Fcb->PathName, &Parent->PathName);
len = Parent->PathName.Length / sizeof(WCHAR);
- memcpy(Fcb->PathName.Buffer, Parent->PathName.Buffer, Parent->PathName.Length);
- Fcb->PathName.Length = Parent->PathName.Length;
Fcb->ObjectName=&Fcb->PathName.Buffer[len];
if (len != 1 || Fcb->PathName.Buffer[0] != '\\')
{
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
- TempFcb.PathName.Buffer = TempFcb.PathNameBuffer;
- TempFcb.PathName.MaximumLength = sizeof(TempFcb.PathNameBuffer);
+ RtlInitEmptyUnicodeString(&TempFcb.PathName, TempFcb.PathNameBuffer, sizeof(TempFcb.PathNameBuffer));
Ccb = (PCCB)FileObject->FsContext2;
Fcb = (PFCB)FileObject->FsContext;
{
First = TRUE;
Ccb->DirectorySearchPattern.Buffer =
- ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), TAG_CCB);
+ ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), CDFS_SEARCH_PATTERN_TAG);
if (Ccb->DirectorySearchPattern.Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
else if (Ccb->DirectorySearchPattern.Buffer == NULL)
{
First = TRUE;
- Ccb->DirectorySearchPattern.Buffer = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_CCB);
+ Ccb->DirectorySearchPattern.Buffer = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), CDFS_SEARCH_PATTERN_TAG);
if (Ccb->DirectorySearchPattern.Buffer == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
if (Status == STATUS_BUFFER_OVERFLOW)
{
- if (Buffer0)
- {
- Buffer0->NextEntryOffset = 0;
- }
break;
}
}
else
{
- if (Buffer0)
- {
- Buffer0->NextEntryOffset = 0;
- }
-
if (First)
{
Status = STATUS_NO_SUCH_FILE;
Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
Buffer0->FileIndex = FileIndex++;
Ccb->Entry++;
+ BufferLength -= Buffer0->NextEntryOffset;
if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
{
break;
}
- BufferLength -= Buffer0->NextEntryOffset;
+
Buffer += Buffer0->NextEntryOffset;
}
if (FileIndex > 0)
{
Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength;
}
return(Status);
}
-NTSTATUS NTAPI
-CdfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
- PIRP Irp)
+static NTSTATUS
+CdfsNotifyChangeDirectory(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp,
+ PCDFS_IRP_CONTEXT IrpContext)
{
+ PDEVICE_EXTENSION DeviceExtension;
+ PFCB Fcb;
+ PCCB Ccb;
PIO_STACK_LOCATION Stack;
+ PFILE_OBJECT FileObject;
+
+ DPRINT("CdfsNotifyChangeDirectory() called\n");
+
+ DeviceExtension = DeviceObject->DeviceExtension;
+ Stack = IoGetCurrentIrpStackLocation(Irp);
+ FileObject = Stack->FileObject;
+
+ Ccb = (PCCB)FileObject->FsContext2;
+ Fcb = (PFCB)FileObject->FsContext;
+
+ FsRtlNotifyFullChangeDirectory(DeviceExtension->NotifySync,
+ &(DeviceExtension->NotifyList),
+ Ccb,
+ (PSTRING)&(Fcb->PathName),
+ BooleanFlagOn(Stack->Flags, SL_WATCH_TREE),
+ FALSE,
+ Stack->Parameters.NotifyDirectory.CompletionFilter,
+ Irp,
+ NULL,
+ NULL);
+
+ /* We won't handle IRP completion */
+ IrpContext->Flags &= ~IRPCONTEXT_COMPLETE;
+
+ return STATUS_PENDING;
+}
+
+
+NTSTATUS NTAPI
+CdfsDirectoryControl(
+ PCDFS_IRP_CONTEXT IrpContext)
+{
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
DPRINT("CdfsDirectoryControl() called\n");
- FsRtlEnterFileSystem();
- Stack = IoGetCurrentIrpStackLocation(Irp);
+ ASSERT(IrpContext);
- switch (Stack->MinorFunction)
+ Irp = IrpContext->Irp;
+ DeviceObject = IrpContext->DeviceObject;
+
+ Irp->IoStatus.Information = 0;
+
+ switch (IrpContext->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
Status = CdfsQueryDirectory(DeviceObject,
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
- DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ Status = CdfsNotifyChangeDirectory(DeviceObject,
+ Irp, IrpContext);
break;
default:
- DPRINT1("CDFS: MinorFunction %u\n", Stack->MinorFunction);
+ DPRINT1("CDFS: MinorFunction %u\n", IrpContext->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
- Irp->IoStatus.Status = Status;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- FsRtlExitFileSystem();
-
return(Status);
}