_Dispatch_type_(IRP_MJ_CLOSE)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_close(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_close(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
device_extension* Vcb = DeviceObject->DeviceExtension;
_Dispatch_type_(IRP_MJ_FLUSH_BUFFERS)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_flush_buffers(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );
PFILE_OBJECT FileObject = IrpSp->FileObject;
_Dispatch_type_(IRP_MJ_QUERY_VOLUME_INFORMATION)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_query_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_query_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
ULONG BytesCopied = 0;
_Dispatch_type_(IRP_MJ_SET_VOLUME_INFORMATION)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_set_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_set_volume_information(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
device_extension* Vcb = DeviceObject->DeviceExtension;
NTSTATUS Status;
return;
}
- ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(fcb->Vcb);
le = fcb->hardlinks.Flink;
while (le != &fcb->hardlinks) {
le = le->Flink;
}
- ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+ release_fcb_lock(fcb->Vcb);
}
void mark_fcb_dirty(_In_ fcb* fcb) {
Vcb = fcb->Vcb;
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
if (fileref)
free_fileref(fcb->Vcb, fileref);
else
free_fcb(Vcb, fcb);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
return STATUS_SUCCESS;
}
KeSetTimer(&Vcb->flush_thread_timer, time, NULL); // trigger the timer early
KeWaitForSingleObject(&Vcb->flush_thread_finished, Executive, KernelMode, FALSE, NULL);
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, Vcb->volume_fcb);
free_fcb(Vcb, Vcb->dummy_fcb);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
if (Vcb->root_file)
ObDereferenceObject(Vcb->root_file);
chunk* c = CONTAINING_RECORD(le, chunk, list_entry);
if (c->cache) {
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, c->cache);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
c->cache = NULL;
}
ExFreePool(c->devices);
if (c->cache) {
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, c->cache);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
}
ExDeleteResourceLite(&c->range_locks_lock);
ZwClose(Vcb->flush_thread_handle);
}
-NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) {
+NTSTATUS delete_fileref(_In_ file_ref* fileref, _In_opt_ PFILE_OBJECT FileObject, _In_opt_ PIRP Irp, _In_ LIST_ENTRY* rollback) {
LARGE_INTEGER newlength, time;
BTRFS_TIME now;
NTSTATUS Status;
}
fileref->fcb->deleted = TRUE;
+
+ le = fileref->children.Flink;
+ while (le != &fileref->children) {
+ file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
+
+ if (fr2->fcb->ads) {
+ fr2->fcb->deleted = TRUE;
+ mark_fcb_dirty(fr2->fcb);
+ }
+
+ le = le->Flink;
+ }
}
if (fileref->dc) {
mark_fcb_dirty(fileref->fcb); // so ROOT_ITEM gets updated
} else {
+ LIST_ENTRY* le;
+
// FIXME - we need a lock here
RemoveEntryList(&fileref->fcb->subvol->list_entry);
InsertTailList(&fileref->fcb->Vcb->drop_roots, &fileref->fcb->subvol->list_entry);
+
+ le = fileref->children.Flink;
+ while (le != &fileref->children) {
+ file_ref* fr2 = CONTAINING_RECORD(le, file_ref, list_entry);
+
+ if (fr2->fcb->ads) {
+ fr2->fcb->deleted = TRUE;
+ mark_fcb_dirty(fr2->fcb);
+ }
+
+ le = le->Flink;
+ }
}
}
} else {
_Dispatch_type_(IRP_MJ_CLEANUP)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_cleanup(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = IrpSp->FileObject;
locked = FALSE;
// fcb_lock needs to be acquired before fcb->Header.Resource
- ExAcquireResourceExclusiveLite(&fcb->Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(fcb->Vcb);
Status = delete_fileref(fileref, FileObject, Irp, &rollback);
if (!NT_SUCCESS(Status)) {
ERR("delete_fileref returned %08x\n", Status);
do_rollback(fcb->Vcb, &rollback);
- ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+ release_fcb_lock(fcb->Vcb);
ExReleaseResourceLite(&fcb->Vcb->tree_lock);
goto exit;
}
- ExReleaseResourceLite(&fcb->Vcb->fcb_lock);
+ release_fcb_lock(fcb->Vcb);
locked = FALSE;
goto exit;
}
+ /* HACK: stream file object seems to get deleted at some point
+ * leading to use after free when installing ReactOS on
+ * BtrFS.
+ * Workaround: leak a handle to the fileobject
+ * XXX: Could be improved by storing it somewhere and releasing it
+ * on dismount. Or even by referencing again the file object.
+ */
+#ifndef __REACTOS__
Vcb->root_file = IoCreateStreamFileObject(NULL, DeviceToMount);
+#else
+ {
+ HANDLE Dummy;
+ Vcb->root_file = IoCreateStreamFileObjectEx(NULL, DeviceToMount, &Dummy);
+ }
+#endif
Vcb->root_file->FsContext = root_fcb;
Vcb->root_file->SectionObjectPointer = &root_fcb->nonpaged->segment_object;
Vcb->root_file->Vpb = DeviceObject->Vpb;
if (Vcb->root_file)
ObDereferenceObject(Vcb->root_file);
else if (Vcb->root_fileref) {
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fileref(Vcb, Vcb->root_fileref);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
} else if (root_fcb) {
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, root_fcb);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
}
if (Vcb->volume_fcb) {
- ExAcquireResourceExclusiveLite(&Vcb->fcb_lock, TRUE);
+ acquire_fcb_lock_exclusive(Vcb);
free_fcb(Vcb, Vcb->volume_fcb);
- ExReleaseResourceLite(&Vcb->fcb_lock);
+ release_fcb_lock(Vcb);
}
ExDeleteResourceLite(&Vcb->tree_lock);
_Dispatch_type_(IRP_MJ_FILE_SYSTEM_CONTROL)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_file_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_file_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
device_extension* Vcb = DeviceObject->DeviceExtension;
_Dispatch_type_(IRP_MJ_LOCK_CONTROL)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_lock_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
fcb* fcb = IrpSp->FileObject->FsContext;
_Dispatch_type_(IRP_MJ_SHUTDOWN)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_shutdown(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
BOOL top_level;
device_extension* Vcb = DeviceObject->DeviceExtension;
+#ifdef __REACTOS__
+ LIST_ENTRY *Vcble, *le;
+#endif
FsRtlEnterFileSystem();
shutting_down = TRUE;
KeSetEvent(&mountmgr_thread_event, 0, FALSE);
+#ifndef __REACTOS__
while (!IsListEmpty(&VcbList)) {
Vcb = CONTAINING_RECORD(VcbList.Flink, device_extension, list_entry);
uninit(Vcb, TRUE);
}
+#else
+ Vcble = VcbList.Flink;
+ while (Vcble != &VcbList) {
+ Vcb = CONTAINING_RECORD(Vcble, device_extension, list_entry);
+
+ TRACE("shutting down Vcb %p\n", Vcb);
+
+ if (Vcb->balance.thread) {
+ Vcb->balance.paused = FALSE;
+ Vcb->balance.stopping = TRUE;
+ KeSetEvent(&Vcb->balance.event, 0, FALSE);
+ KeWaitForSingleObject(&Vcb->balance.finished, Executive, KernelMode, FALSE, NULL);
+ }
+
+ if (Vcb->scrub.thread) {
+ Vcb->scrub.paused = FALSE;
+ Vcb->scrub.stopping = TRUE;
+ KeSetEvent(&Vcb->scrub.event, 0, FALSE);
+ KeWaitForSingleObject(&Vcb->scrub.finished, Executive, KernelMode, FALSE, NULL);
+ }
+
+ if (Vcb->running_sends != 0) {
+ BOOL send_cancelled = FALSE;
+
+ ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, TRUE);
+
+ le = Vcb->send_ops.Flink;
+ while (le != &Vcb->send_ops) {
+ send_info* send = CONTAINING_RECORD(le, send_info, list_entry);
+
+ if (!send->cancelling) {
+ send->cancelling = TRUE;
+ send_cancelled = TRUE;
+ send->ccb = NULL;
+ KeSetEvent(&send->cleared_event, 0, FALSE);
+ }
+
+ le = le->Flink;
+ }
+
+ ExReleaseResourceLite(&Vcb->send_load_lock);
+
+ if (send_cancelled) {
+ while (Vcb->running_sends != 0) {
+ ExAcquireResourceExclusiveLite(&Vcb->send_load_lock, TRUE);
+ ExReleaseResourceLite(&Vcb->send_load_lock);
+ }
+ }
+ }
+
+ ExAcquireResourceExclusiveLite(&Vcb->tree_lock, TRUE);
+
+ if (Vcb->need_write && !Vcb->readonly) {
+ Status = do_write(Vcb, Irp);
+
+ if (!NT_SUCCESS(Status))
+ ERR("do_write returned %08x\n", Status);
+ }
+
+ Vcb->removing = TRUE;
+
+ ExReleaseResourceLite(&Vcb->tree_lock);
+ Vcble = Vcble->Flink;
+ }
+#endif
#ifdef _DEBUG
if (comfo) {
_Dispatch_type_(IRP_MJ_POWER)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_power(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
device_extension* Vcb = DeviceObject->DeviceExtension;
BOOL top_level;
_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL)
_Function_class_(DRIVER_DISPATCH)
+#ifdef __REACTOS__
+static NTSTATUS NTAPI drv_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#else
static NTSTATUS drv_system_control(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp) {
+#endif
NTSTATUS Status;
device_extension* Vcb = DeviceObject->DeviceExtension;
BOOL top_level;
DriverObject->DriverExtension->AddDevice = AddDevice;
+#ifdef __REACTOS__
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = drv_create;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = drv_close;
+ DriverObject->MajorFunction[IRP_MJ_READ] = drv_read;
+ DriverObject->MajorFunction[IRP_MJ_WRITE] = drv_write;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = drv_query_information;
+ DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = drv_set_information;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = drv_query_ea;
+ DriverObject->MajorFunction[IRP_MJ_SET_EA] = drv_set_ea;
+ DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = drv_flush_buffers;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = drv_query_volume_information;
+ DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = drv_set_volume_information;
+ DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = drv_directory_control;
+ DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = drv_file_system_control;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = drv_device_control;
+ DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = drv_shutdown;
+ DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = drv_lock_control;
+ DriverObject->MajorFunction[IRP_MJ_CLEANUP] = drv_cleanup;
+ DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = drv_query_security;
+ DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = drv_set_security;
+ DriverObject->MajorFunction[IRP_MJ_POWER] = drv_power;
+ DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = drv_system_control;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = drv_pnp;
+#else
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)drv_create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)drv_close;
DriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)drv_read;
DriverObject->MajorFunction[IRP_MJ_POWER] = (PDRIVER_DISPATCH)drv_power;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)drv_system_control;
DriverObject->MajorFunction[IRP_MJ_PNP] = (PDRIVER_DISPATCH)drv_pnp;
+#endif
init_fast_io_dispatch(&DriverObject->FastIoDispatch);
InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
Status = ZwCreateKey(®h, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY, &oa, 0, NULL, REG_OPTION_NON_VOLATILE, &dispos);
+ /* ReactOS specific hack: allow BtrFS driver to start in 1st stage with no hive */
+#ifndef __REACTOS__
if (!NT_SUCCESS(Status)) {
ERR("ZwCreateKey returned %08x\n", Status);
return Status;
}
watch_registry(regh);
+#else
+ if (NT_SUCCESS(Status)) {
+ watch_registry(regh);
+ }
+#endif
Status = IoReportDetectedDevice(drvobj, InterfaceTypeUndefined, 0xFFFFFFFF, 0xFFFFFFFF,
NULL, NULL, 0, &cde->buspdo);