diff --git a/drivers/storage/class/class2/class2.c b/drivers/storage/class/class2/class2.c
index 5639f07294..2c9ca071c3 100644
--- a/drivers/storage/class/class2/class2.c
+++ b/drivers/storage/class/class2/class2.c
@@ -12,6 +12,10 @@
 #include <scsi.h>
 #include <include/class2.h>
 #include <stdio.h>
+#ifdef __REACTOS__
+#include <ntifs.h>
+#include <ndk/obfuncs.h>
+#endif
 
 //#define NDEBUG
 #include <debug.h>
@@ -37,6 +41,23 @@
 #define DEFAULT_SECTORS_PER_TRACK    63
 #define DEFAULT_TRACKS_PER_CYLINDER 255
 
+#ifdef __REACTOS__
+typedef struct _CLASS_DEVICE_INFO {
+  ULONG Signature;
+  ULONG DeviceType;
+  ULONG Partitions;
+  ULONG DeviceNumber;
+  ULONG DriveNumber;
+  PDEVICE_OBJECT LowerDevice;
+} CLASS_DEVICE_INFO, *PCLASS_DEVICE_INFO;
+
+typedef struct _CLASS_DRIVER_EXTENSION {
+  ULONG PortNumber;
+  UNICODE_STRING RegistryPath;
+  CLASS_INIT_DATA InitializationData;
+} CLASS_DRIVER_EXTENSION, *PCLASS_DRIVER_EXTENSION;
+#endif
+
 NTSTATUS
 NTAPI
 ScsiClassCreateClose(
@@ -131,6 +152,158 @@ DriverEntry(
     return STATUS_SUCCESS;
 }
 
+#ifdef __REACTOS__
+NTSTATUS
+ScsiQueryDeviceName(
+    IN PDEVICE_OBJECT DeviceObject,
+    OUT POBJECT_NAME_INFORMATION * OutBuffer)
+{
+    ULONG Length;
+    OBJECT_NAME_INFORMATION ObjectNameInfo, *ObjectNameInfoPtr = NULL;
+    NTSTATUS Status;
+
+    /* Query device name */
+    Length = 0;
+    Status = ObQueryNameString(DeviceObject, &ObjectNameInfo, sizeof(OBJECT_NAME_INFORMATION), &Length);
+    if (Status == STATUS_INFO_LENGTH_MISMATCH)
+    {
+        ObjectNameInfoPtr = ExAllocatePool(NonPagedPool, Length);
+        if (ObjectNameInfoPtr == NULL)
+        {
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        Status = ObQueryNameString(DeviceObject, ObjectNameInfoPtr, Length, &Length);
+    }
+
+    /* Fail if device has no name */
+    if (!NT_SUCCESS(Status) || ObjectNameInfoPtr == NULL)
+    {
+        if (ObjectNameInfoPtr != NULL)
+        {
+            ExFreePool(ObjectNameInfoPtr);
+        }
+        /* This is the case when we have no name, force failure */
+        else
+        {
+            Status = STATUS_INVALID_PARAMETER;
+        }
+
+        return Status;
+    }
+
+    /* Return our allocated buffer */
+    *OutBuffer = ObjectNameInfoPtr;
+
+    return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+NotifyMountMgr(IN PDEVICE_OBJECT LowerDeviceObject)
+{
+    NTSTATUS Status;
+    POBJECT_NAME_INFORMATION DeviceName;
+    PMOUNTMGR_MOUNT_POINT MountPoint;
+    PMOUNTMGR_MOUNT_POINTS MountPoints;
+    UNICODE_STRING MountMgrDevice;
+    PFILE_OBJECT FileObject;
+    PDEVICE_OBJECT DeviceObject;
+    KEVENT Event;
+    PIRP Irp;
+    IO_STATUS_BLOCK IoStatus;
+
+    /* Get MountMgr pointer */
+    RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
+    Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
+                                      &FileObject, &DeviceObject);
+    if (!NT_SUCCESS(Status))
+    {
+        return;
+    }
+
+    Status = ScsiQueryDeviceName(LowerDeviceObject, &DeviceName);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(FileObject);
+        return;
+    }
+
+    DPRINT1("Going to delete drive letter for: %wZ\n", &DeviceName->Name);
+
+    /* Allocate input buffer */
+    MountPoint = ExAllocatePool(NonPagedPool, sizeof(MOUNTMGR_MOUNT_POINT) + DeviceName->Name.Length);
+    if (MountPoint == NULL)
+    {
+        ExFreePool(DeviceName);
+        ObDereferenceObject(FileObject);
+        return;
+    }
+
+    /* Allocate output buffer, it should be big enough
+     * If not, to bad, we won't delete drive letter
+     * FIXME
+     */
+    MountPoints = ExAllocatePool(NonPagedPool, sizeof(MOUNTMGR_MOUNT_POINTS) + 3 * 255);
+    if (MountPoints == NULL)
+    {
+        ExFreePool(MountPoint);
+        ExFreePool(DeviceName);
+        ObDereferenceObject(FileObject);
+        return;
+    }
+
+    /* Zero input structure (not the rest, we don't care) */
+    RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
+
+    /* Set the device name - we must not delete using DOS letter */
+    MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
+    MountPoint->DeviceNameLength = DeviceName->Name.Length;
+    RtlCopyMemory((PVOID)((ULONG_PTR)MountPoint + MountPoint->DeviceNameOffset),
+                  DeviceName->Name.Buffer,
+                  DeviceName->Name.Length);
+
+    /* No longer need device name */
+    ExFreePool(DeviceName);
+
+    /* Prepare IRP for MountMgr */
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_DELETE_POINTS,
+                                        DeviceObject,
+                                        MountPoint,
+                                        sizeof(MOUNTMGR_MOUNT_POINT) + MountPoint->DeviceNameLength,
+                                        MountPoints,
+                                        sizeof(MOUNTMGR_MOUNT_POINTS) + 3 * 255,
+                                        FALSE,
+                                        &Event,
+                                        &IoStatus);
+    if (Irp == NULL)
+    {
+        ExFreePool(MountPoints);
+        ExFreePool(MountPoint);
+        ObDereferenceObject(FileObject);
+        return;
+    }
+
+    /* Call MountMgr */
+    Status = IoCallDriver(DeviceObject, Irp);
+    if (Status == STATUS_PENDING)
+    {
+        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
+        Status = IoStatus.Status;
+    }
+
+    /* Done */
+    DPRINT1("Reported to the MountMgr: %lx\n", Status);
+
+    ExFreePool(MountPoints);
+    ExFreePool(MountPoint);
+    ObDereferenceObject(FileObject);
+
+    return;
+}
+#endif
+
 NTSTATUS
 NTAPI
 ScsiClassPlugPlay(
@@ -138,13 +311,39 @@ ScsiClassPlugPlay(
     IN PIRP Irp)
 {
     PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+#ifdef __REACTOS__
+    PCLASS_DEVICE_INFO DeviceInfo = DeviceObject->DeviceExtension;
+#endif
 
     if (IrpSp->MinorFunction == IRP_MN_START_DEVICE)
     {
+#ifndef __REACTOS__
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+#else
+        ASSERT(DeviceInfo->Signature == '2slc');
+        IoSkipCurrentIrpStackLocation(Irp);
+        return IoCallDriver(DeviceInfo->LowerDevice, Irp);
+#endif
+    }
+#if __REACTOS__
+    else if (IrpSp->MinorFunction == IRP_MN_REMOVE_DEVICE)
+    {
+        ASSERT(DeviceInfo->Signature == '2slc');
+
+        IoForwardIrpSynchronously(DeviceInfo->LowerDevice, Irp);
+
+        NotifyMountMgr(DeviceInfo->LowerDevice);
+
         Irp->IoStatus.Status = STATUS_SUCCESS;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+        IoDetachDevice(DeviceInfo->LowerDevice);
+        IoDeleteDevice(DeviceObject);
         return STATUS_SUCCESS;
     }
+#endif
     else
     {
         Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
@@ -154,6 +353,57 @@ ScsiClassPlugPlay(
 }
 
 
+#ifdef __REACTOS__
+NTSTATUS
+NTAPI
+ScsiClassAddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PhysicalDeviceObject)
+{
+    PCLASS_DRIVER_EXTENSION DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
+    PCLASS_DEVICE_INFO DeviceInfo;
+    PDEVICE_OBJECT DeviceObject;
+    NTSTATUS Status;
+
+    if (DriverExtension->InitializationData.ClassFindDevices(DriverObject, &DriverExtension->RegistryPath, &DriverExtension->InitializationData,
+                                                             PhysicalDeviceObject, DriverExtension->PortNumber))
+    {
+        /* Create a device object */
+        Status = IoCreateDevice(DriverObject,
+                                sizeof(CLASS_DEVICE_INFO),
+                                NULL,
+                                DriverExtension->InitializationData.DeviceType,
+                                0,
+                                FALSE,
+                                &DeviceObject);
+        if (!NT_SUCCESS(Status))
+        {
+            return Status;
+        }
+
+        DPRINT1("Created DO %p for PDO %p\n", DeviceObject, PhysicalDeviceObject);
+
+        DeviceInfo = DeviceObject->DeviceExtension;
+        RtlZeroMemory(DeviceInfo, sizeof(CLASS_DEVICE_INFO));
+        DeviceInfo->Signature = '2slc';
+
+        /* Attach it to the PDO */
+        DeviceInfo->LowerDevice = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
+        DeviceInfo->DeviceType = DriverExtension->InitializationData.DeviceType;
+
+        DriverExtension->PortNumber++;
+    }
+    else
+    {
+        /* Failed to find device */
+        DbgPrint("FAILED TO FIND DEVICE!\n");
+    }
+
+    return STATUS_SUCCESS;
+}
+#endif
+
+
 
 ULONG
 NTAPI
@@ -194,6 +444,10 @@ Return Value:
     PFILE_OBJECT    fileObject;
     CCHAR           deviceNameBuffer[256];
     BOOLEAN         deviceFound = FALSE;
+#ifdef __REACTOS__
+    PCLASS_DRIVER_EXTENSION DriverExtension;
+    PUNICODE_STRING RegistryPath = Argument2;
+#endif
 
     DebugPrint((3,"\n\nSCSI Class Driver\n"));
 
@@ -224,6 +478,29 @@ Return Value:
         return (ULONG) STATUS_REVISION_MISMATCH;
     }
 
+#if __REACTOS__
+    status = IoAllocateDriverObjectExtension(DriverObject,
+                                             DriverObject,
+                                             sizeof(CLASS_DRIVER_EXTENSION),
+                                             (PVOID *)&DriverExtension);
+    if (!NT_SUCCESS(status))
+        return status;
+
+    RtlCopyMemory(&DriverExtension->InitializationData, InitializationData, sizeof(CLASS_INIT_DATA));
+    DriverExtension->PortNumber = 0;
+
+    DriverExtension->RegistryPath.Buffer = ExAllocatePool(PagedPool, RegistryPath->MaximumLength);
+    if (!DriverExtension->RegistryPath.Buffer)
+        return STATUS_NO_MEMORY;
+
+    DriverExtension->RegistryPath.Length = RegistryPath->Length;
+    DriverExtension->RegistryPath.MaximumLength = RegistryPath->MaximumLength;
+
+    RtlCopyMemory(DriverExtension->RegistryPath.Buffer,
+                  RegistryPath->Buffer,
+                  RegistryPath->Length);
+#endif
+
     //
     // Update driver object with entry points.
     //
@@ -237,6 +514,9 @@ Return Value:
     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiClassDeviceControlDispatch;
     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = ScsiClassShutdownFlush;
     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = ScsiClassShutdownFlush;
+#ifdef __REACTOS__
+    DriverObject->DriverExtension->AddDevice = ScsiClassAddDevice;
+#endif
 
     if (InitializationData->ClassStartIo) {
         DriverObject->DriverStartIo = InitializationData->ClassStartIo;
