Author: hbelusca
Date: Thu Aug 6 23:00:17 2015
New Revision: 68606
URL:
http://svn.reactos.org/svn/reactos?rev=68606&view=rev
Log:
[NTVDM]
- Copy-paste error fix in the initialization of the collating table.
- Fix DosCombineFreeBlocks so that it doesn't say "DOS memory arena
corrupted" because while combining blocks, the current block became the last one and
we tried to merge it with a next block which, by definition, cannot exist (see comment in
the code).
- Remove a spurious call to DosCombineFreeBlocks in DosResizeMemory which was forgotten in
r68596.
- Check the validity of the encountered MCBs during the loop for linking or unlinking the
UMB chain to the main arena chain.
- Fix the size of the created UMB blocks.
Modified:
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/country.c
trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/country.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/country.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/country.c [iso-8859-1] Thu Aug 6
23:00:17 2015
@@ -279,8 +279,8 @@
CountryData->FNameTermTbl.Data[21] = ',';
CountryData->CollateTbl.Size = ARRAYSIZE(CountryData->CollateTbl.Data);
- for (i = 0; i < CountryData->LoCaseTbl.Size; ++i)
- CountryData->LoCaseTbl.Data[i] = i;
+ for (i = 0; i < CountryData->CollateTbl.Size; ++i)
+ CountryData->CollateTbl.Data[i] = i;
CountryData->DBCSLeadTbl.Size = 0; // Empty DBCS table
CountryData->DBCSLeadTbl.Data[0] = 0x0000;
Modified: trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/dos/…
==============================================================================
--- trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/mvdm/ntvdm/dos/dos32krnl/memory.c [iso-8859-1] Thu Aug 6
23:00:17 2015
@@ -63,7 +63,7 @@
/* Make sure it's valid */
if (!ValidateMcb(CurrentMcb))
{
- DPRINT1("The DOS memory arena is corrupted! (CurrentMcb = %04x;
PreviousMcb = %04X)\n", Segment, PrevSegment);
+ DPRINT1("The DOS memory arena is corrupted! (CurrentMcb = 0x%04X;
PreviousMcb = 0x%04X)\n", Segment, PrevSegment);
return;
}
@@ -82,12 +82,25 @@
static VOID DosCombineFreeBlocks(WORD StartBlock)
{
+ /* NOTE: This function is always called with valid MCB blocks */
+
PDOS_MCB CurrentMcb = SEGMENT_TO_MCB(StartBlock), NextMcb;
- /* If this is the last block or it's not free, quit */
- if (CurrentMcb->BlockType == 'Z' || CurrentMcb->OwnerPsp != 0) return;
-
- while (TRUE)
+ /* If the block is not free, quit */
+ if (CurrentMcb->OwnerPsp != 0) return;
+
+ /*
+ * Loop while the current block is not the last one. It can happen
+ * that the block is not the last one at the beginning, but becomes
+ * the last one at the end of the process. This happens in the case
+ * where its next following blocks are free but not combined yet,
+ * and they are terminated by a free last block. During the process
+ * all the blocks are combined together and we end up in the situation
+ * where the current (free) block is followed by the last (free) block.
+ * At the last step of the algorithm the current block becomes the
+ * last one.
+ */
+ while (CurrentMcb->BlockType != 'Z')
{
/* Get a pointer to the next MCB */
NextMcb = SEGMENT_TO_MCB(StartBlock + CurrentMcb->Size + 1);
@@ -210,7 +223,6 @@
}
Done:
-
DosMemValidate();
/* If we didn't find a free block, bail out */
@@ -278,12 +290,11 @@
PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment), NextMcb;
DPRINT("DosResizeMemory: BlockData 0x%04X, NewSize 0x%04X\n",
- BlockData,
- NewSize);
-
- DosMemValidate();
-
- /* Make sure this is a valid, allocated block */
+ BlockData, NewSize);
+
+ DosMemValidate();
+
+ /* Make sure this is a valid and allocated block */
if (BlockData == 0 || !ValidateMcb(Mcb) || Mcb->OwnerPsp == 0)
{
Success = FALSE;
@@ -291,15 +302,13 @@
goto Done;
}
- DosCombineFreeBlocks(SysVars->FirstMcb);
-
ReturnSize = Mcb->Size;
/* Check if we need to expand or contract the block */
if (NewSize > Mcb->Size)
{
/* We can't expand the last block */
- if (Mcb->BlockType != 'M')
+ if (Mcb->BlockType == 'Z')
{
Success = FALSE;
goto Done;
@@ -431,21 +440,32 @@
DPRINT("Linking UMB\n");
- /* Check if UMBs are already linked */
+ /* Check if UMBs are initialized and already linked */
if (SysVars->UmbChainStart == 0xFFFF) return FALSE;
if (SysVars->UmbLinked) return TRUE;
DosMemValidate();
- /* Find the last block */
- // FIXME: Use SysVars->UmbChainStart
- while ((Mcb->BlockType == 'M') && (Segment <= 0xFFFF))
- {
+ /* Find the last block before the start of the UMB chain */
+ while (Segment < SysVars->UmbChainStart)
+ {
+ /* Get a pointer to the MCB */
+ Mcb = SEGMENT_TO_MCB(Segment);
+
+ /* Make sure it's valid */
+ if (!ValidateMcb(Mcb))
+ {
+ DPRINT1("The DOS memory arena is corrupted!\n");
+ Sda->LastErrorCode = ERROR_ARENA_TRASHED;
+ return FALSE;
+ }
+
+ /* If this was the last MCB in the chain, quit */
+ if (Mcb->BlockType == 'Z') break;
+
+ /* Otherwise, update the segment and continue */
Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
- }
-
- DosMemValidate();
+ }
/* Make sure it's valid */
if (Mcb->BlockType != 'Z') return FALSE;
@@ -453,6 +473,8 @@
/* Connect the MCB with the UMB chain */
Mcb->BlockType = 'M';
+ DosMemValidate();
+
SysVars->UmbLinked = TRUE;
return TRUE;
}
@@ -464,25 +486,28 @@
DPRINT("Unlinking UMB\n");
- /* Check if UMBs are already unlinked */
+ /* Check if UMBs are initialized and already unlinked */
if (SysVars->UmbChainStart == 0xFFFF) return FALSE;
if (!SysVars->UmbLinked) return TRUE;
DosMemValidate();
- /* Find the block preceding the MCB that links it with the UMB chain */
- while (Segment <= 0xFFFF)
- {
- // FIXME: Use SysVars->UmbChainStart
- if ((Segment + Mcb->Size) == (SysVars->FirstMcb + USER_MEMORY_SIZE))
- {
- /* This is the last non-UMB segment */
- break;
+ /* Find the last block before the start of the UMB chain */
+ while (Segment < SysVars->UmbChainStart)
+ {
+ /* Get a pointer to the MCB */
+ Mcb = SEGMENT_TO_MCB(Segment);
+
+ /* Make sure it's valid */
+ if (!ValidateMcb(Mcb))
+ {
+ DPRINT1("The DOS memory arena is corrupted!\n");
+ Sda->LastErrorCode = ERROR_ARENA_TRASHED;
+ return FALSE;
}
/* Advance to the next MCB */
Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
}
/* Mark the MCB as the last MCB */
@@ -509,7 +534,7 @@
WORD DosGetPreviousUmb(WORD UmbSegment)
{
PDOS_MCB CurrentMcb;
- WORD Segment, PrevSegment = 0;
+ WORD Segment, PrevSegment = 0; // FIXME: or use UmbChainStart ??
if (SysVars->UmbChainStart == 0xFFFF)
return 0;
@@ -529,14 +554,13 @@
return 0;
}
- if (Segment >= UmbSegment)
- break;
+ /* We went over the UMB segment, quit */
+ if (Segment >= UmbSegment) break;
PrevSegment = Segment;
/* If this was the last MCB in the chain, quit */
- if (CurrentMcb->BlockType == 'Z')
- break;
+ if (CurrentMcb->BlockType == 'Z') break;
/* Otherwise, update the segment and continue */
Segment += CurrentMcb->Size + 1;
@@ -583,7 +607,7 @@
// It will be splitted as needed just below.
Mcb = SEGMENT_TO_MCB(SysVars->FirstMcb + USER_MEMORY_SIZE + 1); //
'+1': Readjust the fact that USER_MEMORY_SIZE is based using 0x9FFE instead of
0x9FFF
Mcb->BlockType = 'Z'; // At the moment it is really the last
block
- Mcb->Size = SysVars->UmbChainStart /* UmbSegment */ -
SysVars->FirstMcb - USER_MEMORY_SIZE - 2;
+ Mcb->Size = (SysVars->UmbChainStart /* UmbSegment */ -
SysVars->FirstMcb - USER_MEMORY_SIZE - 2) + 1;
Mcb->OwnerPsp = SYSTEM_PSP;
RtlCopyMemory(Mcb->Name, "SC ", sizeof("SC
")-1);
@@ -609,7 +633,7 @@
Mcb = SEGMENT_TO_MCB(UmbSegment + /*Mcb->Size*/(Size - 1) + 0);
// Mcb->BlockType = 'Z'; // FIXME: What if this block happens to be
the last one??
Mcb->BlockType = PrevMcb->BlockType;
- Mcb->Size = PrevMcb->Size - (UmbSegment + Size - PrevSegment);
+ Mcb->Size = PrevMcb->Size - (UmbSegment + Size - PrevSegment) + 1;
Mcb->OwnerPsp = PrevMcb->OwnerPsp;
RtlCopyMemory(Mcb->Name, PrevMcb->Name, sizeof(PrevMcb->Name));