Author: aandrejevic Date: Sat Aug 1 21:48:06 2015 New Revision: 68592
URL: http://svn.reactos.org/svn/reactos?rev=68592&view=rev Log: [NTVDM] Implement XMS function 0Fh (Reallocate Extended Memory Block).
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/d... ============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c [iso-8859-1] Sat Aug 1 21:48:06 2015 @@ -272,6 +272,89 @@ return XMS_STATUS_OUT_OF_MEMORY; }
+static UCHAR XmsRealloc(WORD Handle, WORD NewSize) +{ + DWORD BlockNumber; + PXMS_HANDLE HandleEntry = GetHandleRecord(Handle); + DWORD CurrentIndex = 0; + ULONG RunStart; + ULONG RunSize; + + if (!ValidateHandle(HandleEntry)) + return XMS_STATUS_INVALID_HANDLE; + + if (HandleEntry->LockCount) + return XMS_STATUS_LOCKED; + + /* Get the block number */ + BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE; + + if (NewSize < HandleEntry->Size) + { + /* Just reduce the size of this block */ + RtlClearBits(&AllocBitmap, BlockNumber + NewSize, HandleEntry->Size - NewSize); + FreeBlocks += HandleEntry->Size - NewSize; + HandleEntry->Size = NewSize; + } + else if (NewSize > HandleEntry->Size) + { + /* Check if we can expand in-place */ + if (RtlAreBitsClear(&AllocBitmap, + BlockNumber + HandleEntry->Size, + NewSize - HandleEntry->Size)) + { + /* Just increase the size of this block */ + RtlSetBits(&AllocBitmap, + BlockNumber + HandleEntry->Size, + NewSize - HandleEntry->Size); + FreeBlocks -= NewSize - HandleEntry->Size; + HandleEntry->Size = NewSize; + + /* We're done */ + return XMS_STATUS_SUCCESS; + } + + /* Deallocate the current block range */ + RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size); + + /* Find a new place for this block */ + while (CurrentIndex < XMS_BLOCKS) + { + RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart); + if (RunSize == 0) break; + + if (RunSize >= NewSize) + { + /* Allocate the new range */ + RtlSetBits(&AllocBitmap, RunStart, NewSize); + + /* Move the data to the new location */ + RtlMoveMemory((PVOID)REAL_TO_PHYS(XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE), + (PVOID)REAL_TO_PHYS(HandleEntry->Address), + HandleEntry->Size * XMS_BLOCK_SIZE); + + /* Update the handle entry */ + HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE; + HandleEntry->Size = NewSize; + + /* Update the free block counter */ + FreeBlocks -= NewSize - HandleEntry->Size; + + return XMS_STATUS_SUCCESS; + } + + /* Keep searching */ + CurrentIndex = RunStart + RunSize; + } + + /* Restore the old block range */ + RtlSetBits(&AllocBitmap, BlockNumber, HandleEntry->Size); + return XMS_STATUS_OUT_OF_MEMORY; + } + + return XMS_STATUS_SUCCESS; +} + static UCHAR XmsFree(WORD Handle) { DWORD BlockNumber; @@ -478,7 +561,7 @@ WORD Handle; UCHAR Result = XmsAlloc(getDX(), &Handle);
- if (Result >= 0) + if (Result == XMS_STATUS_SUCCESS) { setAX(1); setDX(Handle); @@ -497,7 +580,7 @@ { UCHAR Result = XmsFree(getDX());
- setAX(Result >= 0); + setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } @@ -571,7 +654,7 @@ DWORD Address; UCHAR Result = XmsLock(getDX(), &Address);
- if (Result >= 0) + if (Result == XMS_STATUS_SUCCESS) { setAX(1);
@@ -593,7 +676,7 @@ { UCHAR Result = XmsUnlock(getDX());
- setAX(Result >= 0); + setAX(Result == XMS_STATUS_SUCCESS); setBL(Result); break; } @@ -627,40 +710,10 @@ /* Reallocate Extended Memory Block */ case 0x0F: { - PXMS_HANDLE HandleEntry = GetHandleRecord(getDX()); - WORD NewSize = getBX(); - - if (!ValidateHandle(HandleEntry)) - { - setAX(0); - setBL(XMS_STATUS_INVALID_HANDLE); - break; - } - - if (HandleEntry->LockCount) - { - setAX(0); - setBL(XMS_STATUS_LOCKED); - break; - } - - /* Check for reduction or enlargement */ - if (NewSize < HandleEntry->Size) - { - /* Reduction, the easy case: just update the size */ - HandleEntry->Size = NewSize; - } - else - { - /* Enlargement: we need to reallocate elsewhere */ - UNIMPLEMENTED; - setAX(0); - setBL(XMS_STATUS_NOT_IMPLEMENTED); - break; - } - - setAX(1); - setBL(XMS_STATUS_SUCCESS); + UCHAR Result = XmsRealloc(getDX(), getBX()); + + setAX(Result == XMS_STATUS_SUCCESS); + setBL(Result); break; }