Skip to content

Commit 85be764

Browse files
ecm-pushbxPerditionC
authored andcommitted
fix 2F.4A MS-DOS v5 style HMA access services
* Reject allocation call with too large requested size, rather than allocating the remaining HMA. * Align returned offset to paragraph boundary. * Allow to allocate up to the very last byte of the HMA, rather than 1 byte less. * Pass last allocated byte to AllocateHMASpace instead of the byte past it, which would carry for a full allocation.
1 parent 5de2eb1 commit 85be764

File tree

2 files changed

+26
-12
lines changed

2 files changed

+26
-12
lines changed

kernel/blockio.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ void AllocateHMASpace (size_t lowbuffer, size_t highbuffer)
500500
do
501501
{
502502
/* check if buffer intersects with requested area */
503-
if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer)
503+
if (FP_OFF(bp) <= highbuffer && FP_OFF(bp+1) > lowbuffer)
504504
{
505505
flush1(bp);
506506
/* unlink bp from buffer chain */

kernel/inthndlr.c

+25-11
Original file line numberDiff line numberDiff line change
@@ -1928,26 +1928,40 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
19281928
{
19291929
COUNT rc;
19301930
long lrc;
1931-
UDWORD tsize;
1931+
UWORD requestedsize;
19321932

19331933
#define r (*pr)
19341934

19351935
if (r.AH == 0x4a)
19361936
{
1937-
size_t size = 0, offs = 0xffff;
1937+
size_t size = 0, offs = 0xffff, realoffs; /* defaults for no alloc */
19381938

19391939
r.ES = offs;
19401940
if (FP_SEG(firstAvailableBuf) == offs) /* HMA present? */
19411941
{
1942-
offs = FP_OFF(firstAvailableBuf);
1943-
size = ~offs; /* BX for query HMA */
1944-
if (r.AL == 0x02) /* allocate HMA space */
1945-
{
1946-
tsize = (r.BX + 0xf) & 0xfffffff0UL; /* align to paragraph */
1947-
if (tsize < size)
1948-
size = (UWORD)tsize;
1949-
AllocateHMASpace(offs, offs+size);
1950-
firstAvailableBuf += size;
1942+
realoffs = FP_OFF(firstAvailableBuf);
1943+
if (realoffs <= 0xFFF0) { /* if any free (not yet exthausted) */
1944+
offs = realoffs;
1945+
offs += 15;
1946+
offs &= ~ 15; /* annoying: buffers may be unaligned */
1947+
size = - offs; /* bx + di = 10000h */
1948+
if (r.AL == 0x02) /* allocate HMA space */
1949+
{
1950+
requestedsize = (r.BX + 15) & ~ 15; /* align to paragraph */
1951+
if (requestedsize < r.BX ||
1952+
requestedsize > size) { /* overflow or OOM */
1953+
size = 0;
1954+
offs = 0xffff; /* requested more than we have */
1955+
} else {
1956+
size = (UWORD)requestedsize; /* return rounded size */
1957+
AllocateHMASpace(realoffs, offs + size - 1); /* ! realoffs */
1958+
if ( ((UDWORD)offs + (UDWORD)size) == 0x10000UL ) {
1959+
firstAvailableBuf = MK_FP(0xFFFF, 0xFFFF); /* exhausted */
1960+
} else {
1961+
firstAvailableBuf += size; /* advance free pointer */
1962+
}
1963+
}
1964+
}
19511965
}
19521966
}
19531967
r.DI = offs;

0 commit comments

Comments
 (0)