Author: aandrejevic
Date: Wed May 14 03:29:58 2014
New Revision: 63288
URL:
http://svn.reactos.org/svn/reactos?rev=63288&view=rev
Log:
[NTVDM]
Implement INT 21h function AH = 67h (Set Handle Count).
Modified:
trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c
Modified: trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/ntvdm/dos/dos32…
==============================================================================
--- trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Wed May 14 03:29:58
2014
@@ -582,6 +582,87 @@
/* Increase the reference count */
DosSystemFileTable[SourceTable[i]].RefCount++;
}
+}
+
+static BOOLEAN DosResizeHandleTable(WORD NewSize)
+{
+ PDOS_PSP PspBlock;
+ LPBYTE HandleTable;
+ WORD Segment;
+
+ /* Get the PSP block */
+ PspBlock = SEGMENT_TO_PSP(CurrentPsp);
+
+ if (NewSize == PspBlock->HandleTableSize)
+ {
+ /* No change */
+ return TRUE;
+ }
+
+ if (PspBlock->HandleTableSize > 20)
+ {
+ /* Get the segment of the current table */
+ Segment = (LOWORD(PspBlock->HandleTablePtr) >> 4) +
HIWORD(PspBlock->HandleTablePtr);
+
+ if (NewSize <= 20)
+ {
+ /* Get the current handle table */
+ HandleTable = FAR_POINTER(PspBlock->HandleTablePtr);
+
+ /* Copy it to the PSP */
+ RtlCopyMemory(PspBlock->HandleTable, HandleTable, NewSize);
+
+ /* Free the memory */
+ DosFreeMemory(Segment);
+
+ /* Update the handle table pointer and size */
+ PspBlock->HandleTableSize = NewSize;
+ PspBlock->HandleTablePtr = MAKELONG(0x18, CurrentPsp);
+ }
+ else
+ {
+ /* Resize the memory */
+ if (!DosResizeMemory(Segment, NewSize, NULL))
+ {
+ /* Unable to resize, try allocating it somewhere else */
+ Segment = DosAllocateMemory(NewSize, NULL);
+ if (Segment == 0) return FALSE;
+
+ /* Get the new handle table */
+ HandleTable = SEG_OFF_TO_PTR(Segment, 0);
+
+ /* Copy the handles to the new table */
+ RtlCopyMemory(HandleTable,
+ FAR_POINTER(PspBlock->HandleTablePtr),
+ PspBlock->HandleTableSize);
+
+ /* Update the handle table pointer */
+ PspBlock->HandleTablePtr = MAKELONG(0, Segment);
+ }
+
+ /* Update the handle table size */
+ PspBlock->HandleTableSize = NewSize;
+ }
+ }
+ else if (NewSize > 20)
+ {
+ Segment = DosAllocateMemory(NewSize, NULL);
+ if (Segment == 0) return FALSE;
+
+ /* Get the new handle table */
+ HandleTable = SEG_OFF_TO_PTR(Segment, 0);
+
+ /* Copy the handles from the PSP to the new table */
+ RtlCopyMemory(HandleTable,
+ FAR_POINTER(PspBlock->HandleTablePtr),
+ PspBlock->HandleTableSize);
+
+ /* Update the handle table pointer and size */
+ PspBlock->HandleTableSize = NewSize;
+ PspBlock->HandleTablePtr = MAKELONG(0, Segment);
+ }
+
+ return TRUE;
}
static BOOLEAN DosCloseHandle(WORD DosHandle)
@@ -2433,6 +2514,19 @@
break;
}
+ /* Set Handle Count */
+ case 0x67:
+ {
+ if (!DosResizeHandleTable(getBX()))
+ {
+ Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
+ setAX(DosLastError);
+ }
+ else Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
+
+ break;
+ }
+
/* Unsupported */
default:
{