diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c index b699cff16c1..1d57efba72f 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c @@ -20,6 +20,7 @@ #include "dos/dem.h" #include "device.h" #include "himem.h" +#include "memory.h" #define XMS_DEVICE_NAME "XMSXXXX0" @@ -564,6 +565,74 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack) break; } + /* Allocate UMB */ + case 0x10: + { + WORD Segment; + WORD MaxAvailable; + BYTE OldAllocStrategy = Sda->AllocStrategy; + BOOLEAN OldLinkState = DosUmbLinked; + + DosLinkUmb(); + Sda->AllocStrategy = DOS_ALLOC_HIGH | DOS_ALLOC_BEST_FIT; + Segment = DosAllocateMemory(getDX(), &MaxAvailable); + + if (Segment) + { + setAX(1); + setBX(Segment); + } + else + { + setAX(0); + setBL(MaxAvailable ? XMS_STATUS_SMALLER_UMB : XMS_STATUS_OUT_OF_UMBS); + setDX(MaxAvailable); + } + + Sda->AllocStrategy = OldAllocStrategy; + if (!OldLinkState) DosUnlinkUmb(); + break; + } + + /* Free UMB */ + case 0x11: + { + if (DosFreeMemory(getDX())) + { + setAX(1); + } + else + { + setAX(0); + setBL(XMS_STATUS_INVALID_UMB); + } + + break; + } + + /* Reallocate UMB */ + case 0x12: + { + WORD Segment; + WORD MaxAvailable; + + Segment = DosResizeMemory(getDX(), getBX(), &MaxAvailable); + + if (Segment) + { + setAX(1); + } + else + { + setAX(0); + setBL(Sda->LastErrorCode == ERROR_INVALID_HANDLE + ? XMS_STATUS_INVALID_UMB : XMS_STATUS_SMALLER_UMB); + setDX(MaxAvailable); + } + + break; + } + default: { DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH()); diff --git a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h index a4b86e57dd5..c4d28748092 100644 --- a/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h +++ b/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.h @@ -28,6 +28,9 @@ #define XMS_STATUS_LOCKED 0xAB #define XMS_STATUS_LOCK_OVERFLOW 0xAC #define XMS_STATUS_CANNOT_LOCK 0xAD +#define XMS_STATUS_SMALLER_UMB 0xB0 +#define XMS_STATUS_OUT_OF_UMBS 0xB1 +#define XMS_STATUS_INVALID_UMB 0xB2 typedef struct _XMS_HANDLE {