diff --git a/reactos/drivers/bus/directory.rbuild b/reactos/drivers/bus/directory.rbuild
index 11a8fbe3852..fc752ff4e18 100644
--- a/reactos/drivers/bus/directory.rbuild
+++ b/reactos/drivers/bus/directory.rbuild
@@ -13,4 +13,7 @@
+
+
+
diff --git a/reactos/drivers/bus/pcmcia/fdo.c b/reactos/drivers/bus/pcmcia/fdo.c
new file mode 100644
index 00000000000..348fd1cf9ea
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/fdo.c
@@ -0,0 +1,25 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: drivers/bus/pcmcia/fdo.c
+ * PURPOSE: PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include
+
+//#define NDEBUG
+#include
+
+NTSTATUS
+NTAPI
+PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt,
+ PIRP Irp)
+{
+ UNIMPLEMENTED
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_NOT_SUPPORTED;
+}
+
diff --git a/reactos/drivers/bus/pcmcia/pcmcia.c b/reactos/drivers/bus/pcmcia/pcmcia.c
new file mode 100644
index 00000000000..b9c32579bec
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/pcmcia.c
@@ -0,0 +1,217 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: drivers/bus/pcmcia/pcmcia.c
+ * PURPOSE: PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include
+
+//#define NDEBUG
+#include
+
+NTSTATUS
+NTAPI
+PcmciaCreateClose(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = 0;
+
+ DPRINT("PCMCIA: Create/Close\n");
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+PcmciaDeviceControl(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS Status;
+
+ DPRINT("PCMCIA: DeviceIoControl\n");
+
+ Irp->IoStatus.Information = 0;
+
+ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+ {
+ default:
+ DPRINT1("PCMCIA: Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ Irp->IoStatus.Status = Status;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+VOID
+NTAPI
+PcmciaUnload(PDRIVER_OBJECT DriverObject)
+{
+ DPRINT("PCMCIA: Unload\n");
+}
+
+NTSTATUS
+NTAPI
+PcmciaPlugPlay(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension;
+
+ DPRINT("PCMCIA: PnP\n");
+ if (Common->IsFDO)
+ {
+ return PcmciaFdoPlugPlay((PPCMCIA_FDO_EXTENSION)Common,
+ Irp);
+ }
+ else
+ {
+ return PcmciaPdoPlugPlay((PPCMCIA_PDO_EXTENSION)Common,
+ Irp);
+ }
+}
+
+NTSTATUS
+NTAPI
+PcmciaPower(PDEVICE_OBJECT DeviceObject,
+ PIRP Irp)
+{
+ PPCMCIA_COMMON_EXTENSION Common = DeviceObject->DeviceExtension;
+ PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ NTSTATUS Status;
+
+ switch (IrpSp->MinorFunction)
+ {
+ case IRP_MN_QUERY_POWER:
+ /* I don't see any reason that we should care */
+ DPRINT("PCMCIA: IRP_MN_QUERY_POWER\n");
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_POWER_SEQUENCE:
+ DPRINT("PCMCIA: IRP_MN_POWER_SEQUENCE\n");
+ RtlCopyMemory(IrpSp->Parameters.PowerSequence.PowerSequence,
+ &Common->PowerSequence,
+ sizeof(POWER_SEQUENCE));
+ Status = STATUS_SUCCESS;
+ break;
+
+ case IRP_MN_WAIT_WAKE:
+ /* Not really sure about this */
+ DPRINT("PCMCIA: IRP_MN_WAIT_WAKE\n");
+ Status = STATUS_NOT_SUPPORTED;
+ break;
+
+ case IRP_MN_SET_POWER:
+ DPRINT("PCMCIA: IRP_MN_SET_POWER\n");
+ if (IrpSp->Parameters.Power.Type == SystemPowerState)
+ {
+ Common->SystemPowerState = IrpSp->Parameters.Power.State.SystemState;
+
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Common->DevicePowerState = IrpSp->Parameters.Power.State.DeviceState;
+
+ /* Update the POWER_SEQUENCE struct */
+ if (Common->DevicePowerState <= PowerDeviceD1)
+ Common->PowerSequence.SequenceD1++;
+
+ if (Common->DevicePowerState <= PowerDeviceD2)
+ Common->PowerSequence.SequenceD2++;
+
+ if (Common->DevicePowerState <= PowerDeviceD3)
+ Common->PowerSequence.SequenceD3++;
+
+ /* Start the underlying device if we are handling this for a PDO */
+ if (!Common->IsFDO)
+ Status = PcmciaPdoSetPowerState((PPCMCIA_PDO_EXTENSION)Common);
+ else
+ Status = STATUS_SUCCESS;
+ }
+
+ /* Report that we changed state to the Power Manager */
+ PoSetPowerState(DeviceObject, IrpSp->Parameters.Power.Type, IrpSp->Parameters.Power.State);
+ break;
+
+ default:
+ DPRINT1("PCMCIA: Invalid MN code in MJ_POWER handler %x\n", IrpSp->MinorFunction);
+ ASSERT(FALSE);
+ Status = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+PcmciaAddDevice(PDRIVER_OBJECT DriverObject,
+ PDEVICE_OBJECT PhysicalDeviceObject)
+{
+ PPCMCIA_FDO_EXTENSION FdoExt;
+ PDEVICE_OBJECT Fdo;
+ NTSTATUS Status;
+
+ DPRINT("PCMCIA: AddDevice\n");
+
+ Status = IoCreateDevice(DriverObject,
+ sizeof(*FdoExt),
+ NULL,
+ FILE_DEVICE_BUS_EXTENDER,
+ FILE_DEVICE_SECURE_OPEN,
+ FALSE,
+ &Fdo);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ FdoExt = Fdo->DeviceExtension;
+
+ RtlZeroMemory(FdoExt, sizeof(*FdoExt));
+
+ InitializeListHead(&FdoExt->ChildDeviceList);
+ KeInitializeSpinLock(&FdoExt->Lock);
+
+ FdoExt->Common.Self = Fdo;
+ FdoExt->Common.IsFDO = TRUE;
+ FdoExt->Common.State = dsStopped;
+
+ FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
+ PhysicalDeviceObject);
+
+ Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+DriverEntry(PDRIVER_OBJECT DriverObject,
+ PUNICODE_STRING RegistryPath)
+{
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = PcmciaCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = PcmciaCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcmciaDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_PNP] = PcmciaPlugPlay;
+ DriverObject->MajorFunction[IRP_MJ_POWER] = PcmciaPower;
+
+ DriverObject->DriverExtension->AddDevice = PcmciaAddDevice;
+ DriverObject->DriverUnload = PcmciaUnload;
+
+ DPRINT1("PCMCIA: DriverEntry\n");
+
+ return STATUS_SUCCESS;
+}
diff --git a/reactos/drivers/bus/pcmcia/pcmcia.h b/reactos/drivers/bus/pcmcia/pcmcia.h
new file mode 100644
index 00000000000..32dd5f28a06
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/pcmcia.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+typedef enum {
+ dsStopped,
+ dsStarted,
+ dsPaused,
+ dsRemoved,
+ dsSurpriseRemoved
+} PCMCIA_DEVICE_STATE;
+
+typedef struct _PCMCIA_COMMON_EXTENSION {
+ PDEVICE_OBJECT Self;
+ BOOLEAN IsFDO;
+ POWER_SEQUENCE PowerSequence;
+ PCMCIA_DEVICE_STATE State;
+ DEVICE_POWER_STATE DevicePowerState;
+ SYSTEM_POWER_STATE SystemPowerState;
+} PCMCIA_COMMON_EXTENSION, *PPCMCIA_COMMON_EXTENSION;
+
+typedef struct _PCMCIA_PDO_EXTENSION {
+ PCMCIA_COMMON_EXTENSION Common;
+} PCMCIA_PDO_EXTENSION, *PPCMCIA_PDO_EXTENSION;
+
+typedef struct _PCMCIA_FDO_EXTENSION {
+ PCMCIA_COMMON_EXTENSION Common;
+ PDEVICE_OBJECT Ldo;
+ LIST_ENTRY ChildDeviceList;
+ KSPIN_LOCK Lock;
+} PCMCIA_FDO_EXTENSION, *PPCMCIA_FDO_EXTENSION;
+
+/* pdo.c */
+NTSTATUS
+NTAPI
+PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt,
+ PIRP Irp);
+
+NTSTATUS
+NTAPI
+PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt);
+
+/* fdo.c */
+NTSTATUS
+NTAPI
+PcmciaFdoPlugPlay(PPCMCIA_FDO_EXTENSION FdoExt,
+ PIRP Irp);
+
diff --git a/reactos/drivers/bus/pcmcia/pcmcia.rbuild b/reactos/drivers/bus/pcmcia/pcmcia.rbuild
new file mode 100644
index 00000000000..2d33ce5dcd6
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/pcmcia.rbuild
@@ -0,0 +1,12 @@
+
+
+
+
+ .
+ ntoskrnl
+ hal
+ fdo.c
+ pcmcia.c
+ pdo.c
+ pcmcia.rc
+
diff --git a/reactos/drivers/bus/pcmcia/pcmcia.rc b/reactos/drivers/bus/pcmcia/pcmcia.rc
new file mode 100644
index 00000000000..13958160676
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/pcmcia.rc
@@ -0,0 +1,5 @@
+#define REACTOS_VERSION_DLL
+#define REACTOS_STR_FILE_DESCRIPTION "PCMCIA Bus Driver\0"
+#define REACTOS_STR_INTERNAL_NAME "pcmcia\0"
+#define REACTOS_STR_ORIGINAL_FILENAME "pcmcia.sys\0"
+#include
diff --git a/reactos/drivers/bus/pcmcia/pdo.c b/reactos/drivers/bus/pcmcia/pdo.c
new file mode 100644
index 00000000000..0e4d16886ee
--- /dev/null
+++ b/reactos/drivers/bus/pcmcia/pdo.c
@@ -0,0 +1,34 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel
+ * FILE: drivers/bus/pcmcia/pdo.c
+ * PURPOSE: PCMCIA Bus Driver
+ * PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
+ */
+
+#include
+
+//#define NDEBUG
+#include
+
+NTSTATUS
+NTAPI
+PcmciaPdoPlugPlay(PPCMCIA_PDO_EXTENSION PdoExt,
+ PIRP Irp)
+{
+ UNIMPLEMENTED
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PcmciaPdoSetPowerState(PPCMCIA_PDO_EXTENSION PdoExt)
+{
+ UNIMPLEMENTED
+
+ return STATUS_SUCCESS;
+}
+