mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 10:20:03 +00:00
[NTVDM]
Implement XMS function 0Fh (Reallocate Extended Memory Block). svn path=/trunk/; revision=68592
This commit is contained in:
parent
96c972db0b
commit
6828502269
|
@ -272,6 +272,89 @@ static UCHAR XmsAlloc(WORD Size, PWORD Handle)
|
|||
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 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
|||
WORD Handle;
|
||||
UCHAR Result = XmsAlloc(getDX(), &Handle);
|
||||
|
||||
if (Result >= 0)
|
||||
if (Result == XMS_STATUS_SUCCESS)
|
||||
{
|
||||
setAX(1);
|
||||
setDX(Handle);
|
||||
|
@ -497,7 +580,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
|||
{
|
||||
UCHAR Result = XmsFree(getDX());
|
||||
|
||||
setAX(Result >= 0);
|
||||
setAX(Result == XMS_STATUS_SUCCESS);
|
||||
setBL(Result);
|
||||
break;
|
||||
}
|
||||
|
@ -571,7 +654,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
|||
DWORD Address;
|
||||
UCHAR Result = XmsLock(getDX(), &Address);
|
||||
|
||||
if (Result >= 0)
|
||||
if (Result == XMS_STATUS_SUCCESS)
|
||||
{
|
||||
setAX(1);
|
||||
|
||||
|
@ -593,7 +676,7 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
|||
{
|
||||
UCHAR Result = XmsUnlock(getDX());
|
||||
|
||||
setAX(Result >= 0);
|
||||
setAX(Result == XMS_STATUS_SUCCESS);
|
||||
setBL(Result);
|
||||
break;
|
||||
}
|
||||
|
@ -627,40 +710,10 @@ static VOID WINAPI XmsBopProcedure(LPWORD Stack)
|
|||
/* Reallocate Extended Memory Block */
|
||||
case 0x0F:
|
||||
{
|
||||
PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
|
||||
WORD NewSize = getBX();
|
||||
UCHAR Result = XmsRealloc(getDX(), 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);
|
||||
setAX(Result == XMS_STATUS_SUCCESS);
|
||||
setBL(Result);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue