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/…
==============================================================================
--- 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;
}