From 3284022bfc270986e4805aa4b347d033f1535634 Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Wed, 14 May 2014 03:29:58 +0000 Subject: [PATCH] [NTVDM] Implement INT 21h function AH = 67h (Set Handle Count). svn path=/trunk/; revision=63288 --- reactos/subsystems/ntvdm/dos/dos32krnl/dos.c | 94 ++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c b/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c index 6ce7e3faf76..8a03448bfc2 100644 --- a/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c +++ b/reactos/subsystems/ntvdm/dos/dos32krnl/dos.c @@ -584,6 +584,87 @@ static VOID DosCopyHandleTable(LPBYTE DestinationTable) } } +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) { BYTE SftIndex; @@ -2433,6 +2514,19 @@ VOID WINAPI DosInt21h(LPWORD Stack) 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: { -- 2.17.1