Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 57978)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 57979)
@@ -183,5 +183,9 @@
     SYSTEM_INFO_INDEX_SERIAL1_IOBASE    = 24,
     SYSTEM_INFO_INDEX_SERIAL1_IRQ       = 25,
-    SYSTEM_INFO_INDEX_END               = 26,
+    SYSTEM_INFO_INDEX_PARALLEL0_IOBASE  = 26,
+    SYSTEM_INFO_INDEX_PARALLEL0_IRQ     = 27,
+    SYSTEM_INFO_INDEX_PARALLEL1_IOBASE  = 28,
+    SYSTEM_INFO_INDEX_PARALLEL1_IRQ     = 29,
+    SYSTEM_INFO_INDEX_END               = 30,
     SYSTEM_INFO_INDEX_INVALID           = 0x80,
     SYSTEM_INFO_INDEX_VALID             = 0x200
@@ -313,4 +317,19 @@
     /** Serial 1 IO port base */
     RTIOPORT            uSerial1IoPortBase;
+
+    /** @name Parallel port config bits
+     * @{ */
+    /** Parallel 0 IRQ number */
+    uint8_t             uParallel0Irq;
+    /** Parallel 1 IRQ number */
+    uint8_t             uParallel1Irq;
+    /** Parallel 0 IO port base */
+    RTIOPORT            uParallel0IoPortBase;
+    /** Parallel 1 IO port base */
+    RTIOPORT            uParallel1IoPortBase;
+    /** @} */
+
+    uint32_t            u32Alignment1;
+
     /** ACPI port base interface. */
     PDMIBASE            IBase;
@@ -322,5 +341,5 @@
     PPDMDEVINSRC        pDevInsRC;
 
-    uint32_t            Alignment1;
+    uint32_t            Alignment2;
     /** Pointer to the driver base interface. */
     R3PTRTYPE(PPDMIBASE) pDrvBase;
@@ -345,5 +364,5 @@
     /** ACPI custom OEM Rev */
     uint32_t            u32OemRevision;
-    uint32_t            Alignment2;
+    uint32_t            Alignment3;
 
     /** The custom table binary data. */
@@ -1319,4 +1338,20 @@
             break;
 
+        case SYSTEM_INFO_INDEX_PARALLEL0_IOBASE:
+            *pu32 = pThis->uParallel0IoPortBase;
+            break;
+
+        case SYSTEM_INFO_INDEX_PARALLEL0_IRQ:
+            *pu32 = pThis->uParallel0Irq;
+            break;
+
+        case SYSTEM_INFO_INDEX_PARALLEL1_IOBASE:
+            *pu32 = pThis->uParallel1IoPortBase;
+            break;
+
+        case SYSTEM_INFO_INDEX_PARALLEL1_IRQ:
+            *pu32 = pThis->uParallel1Irq;
+            break;
+
         case SYSTEM_INFO_INDEX_END:
             /** @todo why isn't this setting any output value?  */
@@ -3057,4 +3092,8 @@
                               "CustomTable\0"
                               "SLICTable\0"
+                              "Parallel0IoPortBase\0"
+                              "Parallel1IoPortBase\0"
+                              "Parallel0Irq\0"
+                              "Parallel1Irq\0"
                               ))
         return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
@@ -3194,4 +3233,28 @@
         return PDMDEV_SET_ERROR(pDevIns, rc,
                                 N_("Configuration error: Failed to read \"Serial1IoPortBase\""));
+
+    /*
+     * Query settings for both parallel ports, if the CFGM keys don't exist pretend that
+     * the corresponding parallel port is not enabled.
+     */
+    rc = CFGMR3QueryU8Def(pCfg, "Parallel0Irq", &pThis->uSerial0Irq, 0);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to read \"Parallel0Irq\""));
+
+    rc = CFGMR3QueryU16Def(pCfg, "Parallel0IoPortBase", &pThis->uParallel0IoPortBase, 0);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to read \"Parallel0IoPortBase\""));
+
+    rc = CFGMR3QueryU8Def(pCfg, "Parallel1Irq", &pThis->uParallel1Irq, 0);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to read \"Parallel1Irq\""));
+
+    rc = CFGMR3QueryU16Def(pCfg, "Parallel1IoPortBase", &pThis->uParallel1IoPortBase, 0);
+    if (RT_FAILURE(rc))
+        return PDMDEV_SET_ERROR(pDevIns, rc,
+                                N_("Configuration error: Failed to read \"Parallel1IoPortBase\""));
 
     /* Try to attach the other CPUs */
Index: /trunk/src/VBox/Devices/PC/vbox.dsl
===================================================================
--- /trunk/src/VBox/Devices/PC/vbox.dsl	(revision 57978)
+++ /trunk/src/VBox/Devices/PC/vbox.dsl	(revision 57979)
@@ -154,4 +154,8 @@
         SL1B,  32, // Serial1 base IO address  
         SL1I,  32, // Serial1 IRQ
+        PP0B,  32, // Parallel0 base IO address  
+        PP0I,  32, // Parallel0 IRQ
+        PP1B,  32, // Parallel1 base IO address  
+        PP1I,  32, // Parallel1 IRQ
         Offset (0x80),
         ININ, 32,
@@ -667,19 +671,70 @@
                 }
 
-                // Parallel port
-                Device (LPT)
+                // Parallel port 0
+                Device (^LPT0)
                 {
                     Name (_HID, EisaId ("PNP0400"))
+                    Name (_UID, 0x01)
                     Method (_STA, 0, NotSerialized)
                     {
-                        Return (0x0F)
-                    }
-                    Name (_CRS, ResourceTemplate ()
-                    {
-                        IO (Decode16, 0x0378, 0x0378, 0x08, 0x08)
-                        IO (Decode16, 0x0778, 0x0778, 0x08, 0x08)
-                        IRQNoFlags () {7}
+                        If (LEqual (PP0B, Zero))
+                        {
+                            Return (0x00)
+                        }
+                        Else
+                        {
+                            Return (0x0F)
+                        }
+                    }
+                    Name (CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0378, 0x0378, 0x08, 0x08, _Y18)
+                        IRQNoFlags (_Y19) {7}
                     })
-                }
+                    Method (_CRS, 0, NotSerialized)
+                    {
+                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y18._MIN, PMI0)
+                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y18._MAX, PMA0)
+                        CreateWordField (CRS, \_SB.PCI0.LPT0._Y19._INT, PIQ0)
+                        Store (PP0B, PMI0)
+                        Store (PP0B, PMA0)
+                        ShiftLeft (0x01, PP0I, PIQ0)
+                        Return (CRS)
+                    }
+                }
+
+                // Parallel port 1
+                Device (^LPT1)
+                {
+                    Name (_HID, EisaId ("PNP0400"))
+                    Name (_UID, 0x02)
+                    Method (_STA, 0, NotSerialized)
+                    {
+                        If (LEqual (PP1B, Zero))
+                        {
+                            Return (0x00)
+                        }
+                        Else
+                        {
+                            Return (0x0F)
+                        }
+                    }
+                    Name (CRS, ResourceTemplate ()
+                    {
+                        IO (Decode16, 0x0278, 0x0278, 0x08, 0x08, _Y20)
+                        IRQNoFlags (_Y21) {5}
+                    })
+                    Method (_CRS, 0, NotSerialized)
+                    {
+                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y20._MIN, PMI1)
+                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y20._MAX, PMA1)
+                        CreateWordField (CRS, \_SB.PCI0.LPT1._Y21._INT, PIQ1)
+                        Store (PP1B, PMI1)
+                        Store (PP1B, PMA1)
+                        ShiftLeft (0x01, PP1I, PIQ1)
+                        Return (CRS)
+                    }
+                }
+
 
                 // Serial port 0
Index: /trunk/src/VBox/Devices/Parallel/DevParallel.cpp
===================================================================
--- /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 57978)
+++ /trunk/src/VBox/Devices/Parallel/DevParallel.cpp	(revision 57979)
@@ -357,14 +357,21 @@
                     return VINF_IOM_R3_IOPORT_WRITE;
 #else
-                    /* Set data direction. */
-                    if (u8 & LPT_CONTROL_ENABLE_BIDIRECT)
-                        rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, false /* fForward */);
+                    if (RT_LIKELY(pThis->pDrvHostParallelConnector))
+                    {
+                        /* Set data direction. */
+                        if (u8 & LPT_CONTROL_ENABLE_BIDIRECT)
+                            rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, false /* fForward */);
+                        else
+                            rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, true /* fForward */);
+                        AssertRC(rc);
+
+                        u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
+
+                        rc = pThis->pDrvHostParallelConnector->pfnWriteControl(pThis->pDrvHostParallelConnector, u8);
+                        AssertRC(rc);
+                    }
                     else
-                        rc = pThis->pDrvHostParallelConnector->pfnSetPortDirection(pThis->pDrvHostParallelConnector, true /* fForward */);
-                    AssertRC(rc);
-                    u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
-
-                    rc = pThis->pDrvHostParallelConnector->pfnWriteControl(pThis->pDrvHostParallelConnector, u8);
-                    AssertRC(rc);
+                        u8 &= ~LPT_CONTROL_ENABLE_BIDIRECT; /* Clear bit. */
+
                     pThis->regControl = u8;
 #endif
@@ -462,9 +469,13 @@
             case 2:
 #ifndef IN_RING3
-                 rc = VINF_IOM_R3_IOPORT_READ;
+                rc = VINF_IOM_R3_IOPORT_READ;
 #else
-                 rc = pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
-                 AssertRC(rc);
-                 pThis->regControl |= LPT_CONTROL_BIT6 | LPT_CONTROL_BIT7;
+                if (RT_LIKELY(pThis->pDrvHostParallelConnector))
+                {
+                    rc = pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
+                    AssertRC(rc);
+                    pThis->regControl |= LPT_CONTROL_BIT6 | LPT_CONTROL_BIT7;
+                }
+
                 *pu32 = pThis->regControl;
 #endif
@@ -766,4 +777,10 @@
     {
         pThis->pDrvHostParallelConnector = PDMIBASE_QUERY_INTERFACE(pThis->pDrvBase, PDMIHOSTPARALLELCONNECTOR);
+
+        /* Set compatibility mode */
+        //pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
+        /* Get status of control register */
+        pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
+
         AssertMsgReturn(pThis->pDrvHostParallelConnector,
                         ("Configuration error: instance %d has no host parallel interface!\n", iInstance),
@@ -782,9 +799,4 @@
                                    N_("Parallel device %d cannot attach to host driver"), iInstance);
     }
-
-    /* Set compatibility mode */
-    //pThis->pDrvHostParallelConnector->pfnSetMode(pThis->pDrvHostParallelConnector, PDM_PARALLEL_PORT_MODE_COMPAT);
-    /* Get status of control register */
-    pThis->pDrvHostParallelConnector->pfnReadControl(pThis->pDrvHostParallelConnector, &pThis->regControl);
 
     return VINF_SUCCESS;
@@ -811,5 +823,5 @@
     PDM_DEVREG_CLASS_PARALLEL,
     /* cMaxInstances */
-    1,
+    2,
     /* cbInstance */
     sizeof(PARALLELPORT),
Index: /trunk/src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 57978)
+++ /trunk/src/VBox/Main/idl/VirtualBox.xidl	(revision 57979)
@@ -17255,5 +17255,5 @@
         Host parallel device name. If this parallel port is enabled, setting a
         @c null or an empty string as this attribute's value will result in
-        an error.
+        the parallel port behaving as if not connected to any device.
       </desc>
     </attribute>
Index: /trunk/src/VBox/Main/include/ParallelPortImpl.h
===================================================================
--- /trunk/src/VBox/Main/include/ParallelPortImpl.h	(revision 57978)
+++ /trunk/src/VBox/Main/include/ParallelPortImpl.h	(revision 57979)
@@ -51,4 +51,5 @@
     void i_commit();
     void i_copyFrom(ParallelPort *aThat);
+    void i_applyDefaults();
 
 private:
@@ -65,6 +66,4 @@
     HRESULT setPath(const com::Utf8Str &aPath);
 
-    HRESULT i_checkSetPath(const Utf8Str &str);
-
     struct Data;
     Data *m;
Index: /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
===================================================================
--- /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 57978)
+++ /trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp	(revision 57979)
@@ -2641,4 +2641,7 @@
          * Parallel (LPT) Ports
          */
+        /* parallel enabled mask to be passed to dev ACPI */
+        uint16_t auParallelIoPortBase[SchemaDefs::ParallelPortCount] = {0};
+        uint8_t auParallelIrq[SchemaDefs::ParallelPortCount] = {0};
         InsertConfigNode(pDevices, "parallel", &pDev);
         for (ULONG ulInstance = 0; ulInstance < SchemaDefs::ParallelPortCount; ++ulInstance)
@@ -2660,12 +2663,18 @@
             hrc = parallelPort->COMGETTER(IRQ)(&ulIRQ);                                     H();
             InsertConfigInteger(pCfg, "IRQ", ulIRQ);
+            auParallelIrq[ulInstance] = (uint8_t)ulIRQ;
             ULONG ulIOBase;
             hrc = parallelPort->COMGETTER(IOBase)(&ulIOBase);                               H();
             InsertConfigInteger(pCfg,   "IOBase", ulIOBase);
-            InsertConfigNode(pInst,     "LUN#0", &pLunL0);
-            InsertConfigString(pLunL0,  "Driver", "HostParallel");
-            InsertConfigNode(pLunL0,    "Config", &pLunL1);
+            auParallelIoPortBase[ulInstance] = (uint16_t)ulIOBase;
+
             hrc = parallelPort->COMGETTER(Path)(bstr.asOutParam());                         H();
-            InsertConfigString(pLunL1,  "DevicePath", bstr);
+            if (!bstr.isEmpty())
+            {
+                InsertConfigNode(pInst,     "LUN#0", &pLunL0);
+                InsertConfigString(pLunL0,  "Driver", "HostParallel");
+                InsertConfigNode(pLunL0,    "Config", &pLunL1);
+                InsertConfigString(pLunL1,  "DevicePath", bstr);
+            }
         }
 
@@ -3091,4 +3100,10 @@
             InsertConfigInteger(pCfg,  "Serial1IoPortBase", auSerialIoPortBase[1]);
             InsertConfigInteger(pCfg,  "Serial1Irq", auSerialIrq[1]);
+
+            InsertConfigInteger(pCfg,  "Parallel0IoPortBase", auParallelIoPortBase[0]);
+            InsertConfigInteger(pCfg,  "Parallel0Irq", auParallelIrq[0]);
+
+            InsertConfigInteger(pCfg,  "Parallel1IoPortBase", auParallelIoPortBase[1]);
+            InsertConfigInteger(pCfg,  "Parallel1Irq", auParallelIrq[1]);
 
             InsertConfigNode(pInst,    "LUN#0", &pLunL0);
Index: /trunk/src/VBox/Main/src-server/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 57978)
+++ /trunk/src/VBox/Main/src-server/MachineImpl.cpp	(revision 57979)
@@ -353,4 +353,8 @@
             for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot)
                 mSerialPorts[slot]->i_applyDefaults(aOsType);
+
+            /* Apply parallel port defaults */
+            for (ULONG slot = 0; slot < RT_ELEMENTS(mParallelPorts); ++slot)
+                mParallelPorts[slot]->i_applyDefaults();
 
             /* Let the OS type select 64-bit ness. */
Index: /trunk/src/VBox/Main/src-server/ParallelPortImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/ParallelPortImpl.cpp	(revision 57978)
+++ /trunk/src/VBox/Main/src-server/ParallelPortImpl.cpp	(revision 57979)
@@ -215,10 +215,4 @@
     if (m->bd->fEnabled != !!aEnabled)
     {
-        if (aEnabled &&
-            m->bd->strPath.isEmpty())
-            return setError(E_INVALIDARG,
-                            tr("Cannot enable the parallel port %d because the port path is empty or null"),
-                            m->bd->ulSlot);
-
         m->bd.backup();
         m->bd->fEnabled = !!aEnabled;
@@ -352,7 +346,4 @@
     if (aPath != m->bd->strPath)
     {
-        HRESULT rc = i_checkSetPath(aPath);
-        if (FAILED(rc)) return rc;
-
         m->bd.backup();
         m->bd->strPath = aPath;
@@ -498,21 +489,32 @@
 
 /**
- *  Validates COMSETTER(Path) arguments.
- */
-HRESULT ParallelPort::i_checkSetPath(const Utf8Str &str)
-{
-    AssertReturn(isWriteLockOnCurrentThread(), E_FAIL);
-
-    if (    m->bd->fEnabled
-         && str.isEmpty()
-       )
-        return setError(E_INVALIDARG,
-                        tr("Path of the parallel port %d may not be empty or null "
-                           "when the port is enabled"),
-                        m->bd->ulSlot);
-
-    return S_OK;
-}
-
+ * Applies the defaults for the given parallel port.
+ */
+void ParallelPort::i_applyDefaults()
+{
+    /* sanity */
+    AutoCaller autoCaller(this);
+    AssertComRCReturnVoid (autoCaller.rc());
+
+    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
+
+    /* Set some more defaults based on the slot. */
+    switch (m->bd->ulSlot)
+    {
+        case 0:
+        {
+            m->bd->ulIOBase = 0x378;
+            m->bd->ulIRQ = 7;
+            break;
+        }
+        case 1:
+        {
+            m->bd->ulIOBase = 0x278;
+            m->bd->ulIRQ = 5;
+            break;
+        }
+        default: break;
+    }
+}
 
 /* vi: set tabstop=4 shiftwidth=4 expandtab: */
