mirror of
https://github.com/reactos/reactos.git
synced 2025-07-26 23:23:39 +00:00
[NTVDM]: Commit some local changes that can be committed now:
- Whitespace fixes. - Improve some DPRINTs. - hardcoded_values--; - Fix DisplayMessage() for NULL-terminated strings. - Free the allocated block of memory in the mouse driver cleanup procedure. - Properly inherit the parent process environment block if needed. - Return the correct last error if DosCopyEnvironmentBlock fails. - Big ifs turned into switch. - Implement some INT 2Fh DOS multiplex functions (AX=1200h "Installation check", AX=1203h "Get DOS data segment", AX=1214h "Compare FAR pointers", AX=122Fh "Set DOS version to return"); remove the DPRINT for AX=1680h "Release Current Virtual Machine Time-slice". - Stubplement INT 2Ah "DOS critical sections / network" (it just monitors calls to itself at the moment). - Use the boot drive root path as the current directory if we failed retrieving a valid one. - Offsetize the DOS_SYSVARS members (so that I don't have to compute by head the offsets, especially when some of the members is a structure from which I don't know in advance its size); add some C_ASSERTs on the size of DOS standard structures. - Move the NullDriverRoutine buffer outside the sysvars buffer (because it has nothing to do inside it). - In ConDrvReadInput: do not echo the first part of an extended character. - Add basic support for changing the reported DosVersion. svn path=/trunk/; revision=68395
This commit is contained in:
parent
9dc9e37fcc
commit
597a383e60
13 changed files with 270 additions and 135 deletions
|
@ -32,9 +32,6 @@
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
// static BYTE CurrentDrive;
|
|
||||||
// static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
@ -105,7 +102,13 @@ BOOLEAN DosBuildSysEnvBlock(VOID)
|
||||||
LPSTR SourcePtr, Environment;
|
LPSTR SourcePtr, Environment;
|
||||||
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
|
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
|
||||||
|
|
||||||
/* Get the environment strings */
|
/*
|
||||||
|
* Get the environment strings
|
||||||
|
*
|
||||||
|
* NOTE: On non-STANDALONE builds, this corresponds to the VDM environment
|
||||||
|
* as created by BaseVDM for NTVDM. On STANDALONE builds this is the Win32
|
||||||
|
* environment. In this last case we need to convert it to a proper VDM env.
|
||||||
|
*/
|
||||||
SourcePtr = Environment = GetEnvironmentStrings();
|
SourcePtr = Environment = GetEnvironmentStrings();
|
||||||
if (Environment == NULL) return FALSE;
|
if (Environment == NULL) return FALSE;
|
||||||
|
|
||||||
|
@ -231,10 +234,6 @@ BOOLEAN DosBIOSInitialize(VOID)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Register the DOS 32-bit Interrupts */
|
|
||||||
// RegisterDosInt32(0x20, DosInt20h);
|
|
||||||
|
|
||||||
/* Initialize the DOS kernel */
|
/* Initialize the DOS kernel */
|
||||||
return DosKRNLInitialize();
|
return DosKRNLInitialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,11 @@ WORD NTAPI ConDrvReadInput(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
|
||||||
/* Check if this is a special character */
|
/* Check if this is a special character */
|
||||||
if (Character == 0) ExtendedCode = getAH();
|
if (Character == 0) ExtendedCode = getAH();
|
||||||
|
|
||||||
if (DoEcho) DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
|
|
||||||
Pointer[BytesRead++] = Character;
|
Pointer[BytesRead++] = Character;
|
||||||
|
|
||||||
|
if (Character != 0 && DoEcho)
|
||||||
|
DosPrintCharacter(DOS_OUTPUT_HANDLE, Character);
|
||||||
|
|
||||||
/* Stop on first carriage return */
|
/* Stop on first carriage return */
|
||||||
if (Character == '\r')
|
if (Character == '\r')
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,30 +98,30 @@ DosGetCountryInfo(IN OUT PWORD CountryId,
|
||||||
(LPSTR)&CountryInfo->DecimalSep,
|
(LPSTR)&CountryInfo->DecimalSep,
|
||||||
sizeof(CountryInfo->DecimalSep));
|
sizeof(CountryInfo->DecimalSep));
|
||||||
if (Return == 0) return LOWORD(GetLastError());
|
if (Return == 0) return LOWORD(GetLastError());
|
||||||
|
|
||||||
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE,
|
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SDATE,
|
||||||
(LPSTR)&CountryInfo->DateSep,
|
(LPSTR)&CountryInfo->DateSep,
|
||||||
sizeof(CountryInfo->DateSep));
|
sizeof(CountryInfo->DateSep));
|
||||||
if (Return == 0) return LOWORD(GetLastError());
|
if (Return == 0) return LOWORD(GetLastError());
|
||||||
|
|
||||||
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIME,
|
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_STIME,
|
||||||
(LPSTR)&CountryInfo->TimeSep,
|
(LPSTR)&CountryInfo->TimeSep,
|
||||||
sizeof(CountryInfo->TimeSep));
|
sizeof(CountryInfo->TimeSep));
|
||||||
if (Return == 0) return LOWORD(GetLastError());
|
if (Return == 0) return LOWORD(GetLastError());
|
||||||
|
|
||||||
// NOTE: '4: Symbol replace decimal separator' is unsupported.
|
// NOTE: '4: Symbol replace decimal separator' is unsupported.
|
||||||
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
|
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRENCY | LOCALE_RETURN_NUMBER,
|
||||||
(LPSTR)&NumVal,
|
(LPSTR)&NumVal,
|
||||||
sizeof(NumVal));
|
sizeof(NumVal));
|
||||||
if (Return == 0) return LOWORD(GetLastError());
|
if (Return == 0) return LOWORD(GetLastError());
|
||||||
CountryInfo->CurrencyFormat = (BYTE)NumVal;
|
CountryInfo->CurrencyFormat = (BYTE)NumVal;
|
||||||
|
|
||||||
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, // LOCALE_IDIGITS | LOCALE_RETURN_NUMBER
|
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICURRDIGITS | LOCALE_RETURN_NUMBER, // LOCALE_IDIGITS | LOCALE_RETURN_NUMBER
|
||||||
(LPSTR)&NumVal,
|
(LPSTR)&NumVal,
|
||||||
sizeof(NumVal));
|
sizeof(NumVal));
|
||||||
if (Return == 0) return LOWORD(GetLastError());
|
if (Return == 0) return LOWORD(GetLastError());
|
||||||
CountryInfo->CurrencyDigitsNum = (BYTE)NumVal;
|
CountryInfo->CurrencyDigitsNum = (BYTE)NumVal;
|
||||||
|
|
||||||
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME | LOCALE_RETURN_NUMBER,
|
Return = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ITIME | LOCALE_RETURN_NUMBER,
|
||||||
(LPSTR)&NumVal,
|
(LPSTR)&NumVal,
|
||||||
sizeof(NumVal));
|
sizeof(NumVal));
|
||||||
|
@ -129,7 +129,7 @@ DosGetCountryInfo(IN OUT PWORD CountryId,
|
||||||
CountryInfo->TimeFormat = (BYTE)NumVal;
|
CountryInfo->TimeFormat = (BYTE)NumVal;
|
||||||
|
|
||||||
CountryInfo->CaseMapPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, CaseMapRoutine), CountryDataSegment);
|
CountryInfo->CaseMapPtr = MAKELONG(FIELD_OFFSET(COUNTRY_DATA, CaseMapRoutine), CountryDataSegment);
|
||||||
|
|
||||||
// CountryInfo->DataListSep;
|
// CountryInfo->DataListSep;
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
|
@ -240,7 +240,7 @@ BOOLEAN DosCountryInitialize(VOID)
|
||||||
CountryDataSegment = DosAllocateMemory(sizeof(COUNTRY_DATA), NULL);
|
CountryDataSegment = DosAllocateMemory(sizeof(COUNTRY_DATA), NULL);
|
||||||
if (CountryDataSegment == 0) return FALSE;
|
if (CountryDataSegment == 0) return FALSE;
|
||||||
CountryData = (PCOUNTRY_DATA)SEG_OFF_TO_PTR(CountryDataSegment, 0x0000);
|
CountryData = (PCOUNTRY_DATA)SEG_OFF_TO_PTR(CountryDataSegment, 0x0000);
|
||||||
|
|
||||||
RtlMoveMemory(CountryData->CaseMapRoutine,
|
RtlMoveMemory(CountryData->CaseMapRoutine,
|
||||||
CaseMapRoutine,
|
CaseMapRoutine,
|
||||||
sizeof(CaseMapRoutine));
|
sizeof(CaseMapRoutine));
|
||||||
|
|
|
@ -123,6 +123,7 @@ typedef struct _DOS_DRIVER
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} DOS_DRIVER, *PDOS_DRIVER;
|
} DOS_DRIVER, *PDOS_DRIVER;
|
||||||
|
C_ASSERT(sizeof(DOS_DRIVER) == 0x12);
|
||||||
|
|
||||||
typedef struct _DOS_REQUEST_HEADER
|
typedef struct _DOS_REQUEST_HEADER
|
||||||
{
|
{
|
||||||
|
|
|
@ -91,7 +91,7 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether the directory string is of format "?:..." */
|
/* Check whether the directory string is of format "X:..." */
|
||||||
if (strlen(Directory) >= 2 && Directory[1] == ':')
|
if (strlen(Directory) >= 2 && Directory[1] == ':')
|
||||||
{
|
{
|
||||||
/* Get the drive number */
|
/* Get the drive number */
|
||||||
|
@ -114,8 +114,8 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
Attributes = GetFileAttributesA(Directory);
|
Attributes = GetFileAttributesA(Directory);
|
||||||
|
|
||||||
/* Make sure the path exists and is a directory */
|
/* Make sure the path exists and is a directory */
|
||||||
if ((Attributes == INVALID_FILE_ATTRIBUTES)
|
if ((Attributes == INVALID_FILE_ATTRIBUTES) ||
|
||||||
|| !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
!(Attributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
|
Sda->LastErrorCode = ERROR_PATH_NOT_FOUND;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -146,17 +146,11 @@ static BOOLEAN DosChangeDirectory(LPSTR Directory)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the directory part of the path */
|
/* Get the directory part of the path and set the current directory for the drive */
|
||||||
Path = strchr(DosDirectory, '\\');
|
Path = strchr(DosDirectory, '\\');
|
||||||
if (Path != NULL)
|
if (Path != NULL)
|
||||||
{
|
{
|
||||||
/* Skip the backslash */
|
Path++; // Skip the backslash
|
||||||
Path++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the directory for the drive */
|
|
||||||
if (Path != NULL)
|
|
||||||
{
|
|
||||||
strncpy(DosData->CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
|
strncpy(DosData->CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -829,8 +823,10 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
DWORD NumberOfFreeClusters;
|
DWORD NumberOfFreeClusters;
|
||||||
DWORD TotalNumberOfClusters;
|
DWORD TotalNumberOfClusters;
|
||||||
|
|
||||||
if (getDL() == 0x00) RootPath[0] = 'A' + Sda->CurrentDrive;
|
if (getDL() == 0x00)
|
||||||
else RootPath[0] = 'A' + getDL() - 1;
|
RootPath[0] = 'A' + Sda->CurrentDrive;
|
||||||
|
else
|
||||||
|
RootPath[0] = 'A' + getDL() - 1;
|
||||||
|
|
||||||
if (GetDiskFreeSpaceA(RootPath,
|
if (GetDiskFreeSpaceA(RootPath,
|
||||||
&SectorsPerCluster,
|
&SectorsPerCluster,
|
||||||
|
@ -914,7 +910,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
{
|
{
|
||||||
WORD CountryId = getAL() < 0xFF ? getAL() : getBX();
|
WORD CountryId = getAL() < 0xFF ? getAL() : getBX();
|
||||||
WORD ErrorCode;
|
WORD ErrorCode;
|
||||||
|
|
||||||
ErrorCode = DosGetCountryInfo(&CountryId,
|
ErrorCode = DosGetCountryInfo(&CountryId,
|
||||||
(PDOS_COUNTRY_INFO)SEG_OFF_TO_PTR(getDS(), getDX()));
|
(PDOS_COUNTRY_INFO)SEG_OFF_TO_PTR(getDS(), getDX()));
|
||||||
|
|
||||||
|
@ -1110,7 +1106,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
* See Ralf Brown: http://www.ctyme.com/intr/rb-2797.htm
|
* See Ralf Brown: http://www.ctyme.com/intr/rb-2797.htm
|
||||||
* "AX destroyed (DOS 3.3) AL seems to be drive of deleted file."
|
* "AX destroyed (DOS 3.3) AL seems to be drive of deleted file."
|
||||||
*/
|
*/
|
||||||
setAL(FileName[0] - 'A');
|
setAL(RtlUpperChar(FileName[0]) - 'A');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1519,54 +1515,68 @@ VOID WINAPI DosInt21h(LPWORD Stack)
|
||||||
/* Get/Set Memory Management Options */
|
/* Get/Set Memory Management Options */
|
||||||
case 0x58:
|
case 0x58:
|
||||||
{
|
{
|
||||||
if (getAL() == 0x00)
|
switch (getAL())
|
||||||
{
|
{
|
||||||
/* Get allocation strategy */
|
/* Get allocation strategy */
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
case 0x00:
|
||||||
setAX(Sda->AllocStrategy);
|
{
|
||||||
}
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
else if (getAL() == 0x01)
|
setAX(Sda->AllocStrategy);
|
||||||
{
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set allocation strategy */
|
/* Set allocation strategy */
|
||||||
|
case 0x01:
|
||||||
if ((getBL() & (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
|
||||||
== (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
|
||||||
{
|
{
|
||||||
/* Can't set both */
|
if ((getBL() & (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
== (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
||||||
setAX(ERROR_INVALID_PARAMETER);
|
{
|
||||||
|
/* Can't set both */
|
||||||
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
|
setAX(ERROR_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((getBL() & ~(DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
||||||
|
> DOS_ALLOC_LAST_FIT)
|
||||||
|
{
|
||||||
|
/* Invalid allocation strategy */
|
||||||
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
|
setAX(ERROR_INVALID_PARAMETER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sda->AllocStrategy = getBL();
|
||||||
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((getBL() & 0x3F) > DOS_ALLOC_LAST_FIT)
|
|
||||||
{
|
|
||||||
/* Invalid allocation strategy */
|
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
|
||||||
setAX(ERROR_INVALID_PARAMETER);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sda->AllocStrategy = getBL();
|
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
|
||||||
}
|
|
||||||
else if (getAL() == 0x02)
|
|
||||||
{
|
|
||||||
/* Get UMB link state */
|
/* Get UMB link state */
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
case 0x02:
|
||||||
setAL(DosUmbLinked ? 0x01 : 0x00);
|
{
|
||||||
}
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
else if (getAL() == 0x03)
|
setAL(DosUmbLinked ? 0x01 : 0x00);
|
||||||
{
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set UMB link state */
|
/* Set UMB link state */
|
||||||
if (getBX()) DosLinkUmb();
|
case 0x03:
|
||||||
else DosUnlinkUmb();
|
{
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
if (getBX())
|
||||||
}
|
DosLinkUmb();
|
||||||
else
|
else
|
||||||
{
|
DosUnlinkUmb();
|
||||||
|
|
||||||
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Invalid or unsupported function */
|
/* Invalid or unsupported function */
|
||||||
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
default:
|
||||||
setAX(ERROR_INVALID_FUNCTION);
|
{
|
||||||
|
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
|
||||||
|
setAX(ERROR_INVALID_FUNCTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -2021,10 +2031,77 @@ VOID WINAPI DosFastConOut(LPWORD Stack)
|
||||||
setAX(AX);
|
setAX(AX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID WINAPI DosInt2Ah(LPWORD Stack)
|
||||||
|
{
|
||||||
|
DPRINT1("INT 2Ah, AX=%4xh called\n", getAX());
|
||||||
|
}
|
||||||
|
|
||||||
VOID WINAPI DosInt2Fh(LPWORD Stack)
|
VOID WINAPI DosInt2Fh(LPWORD Stack)
|
||||||
{
|
{
|
||||||
switch (getAH())
|
switch (getAH())
|
||||||
{
|
{
|
||||||
|
/* DOS 3+ Internal Utility Functions */
|
||||||
|
case 0x12:
|
||||||
|
{
|
||||||
|
DPRINT1("INT 2Fh, AX=%4xh DOS Internal Utility Function called\n", getAX());
|
||||||
|
|
||||||
|
switch (getAL())
|
||||||
|
{
|
||||||
|
/* Installation Check */
|
||||||
|
case 0x00:
|
||||||
|
{
|
||||||
|
setAL(0xFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get DOS Data Segment */
|
||||||
|
case 0x03:
|
||||||
|
{
|
||||||
|
setDS(DOS_DATA_SEGMENT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compare FAR Pointers */
|
||||||
|
case 0x14:
|
||||||
|
{
|
||||||
|
PVOID PointerFromFarPointer1 = SEG_OFF_TO_PTR(getDS(), getSI());
|
||||||
|
PVOID PointerFromFarPointer2 = SEG_OFF_TO_PTR(getES(), getDI());
|
||||||
|
BOOLEAN AreEqual = (PointerFromFarPointer1 == PointerFromFarPointer2);
|
||||||
|
|
||||||
|
setZF(AreEqual);
|
||||||
|
setCF(!AreEqual);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set DOS Version Number to return */
|
||||||
|
case 0x2F:
|
||||||
|
{
|
||||||
|
WORD DosVersion = getDX();
|
||||||
|
|
||||||
|
// Special case: return the true DOS version when DX=00h
|
||||||
|
if (DosVersion == 0x0000)
|
||||||
|
DosData->DosVersion = DOS_VERSION;
|
||||||
|
else
|
||||||
|
DosData->DosVersion = DosVersion;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mostly Windows 2.x/3.x/9x support */
|
||||||
|
case 0x16:
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* AL=80h is DOS/Windows/DPMI "Release Current Virtual Machine Time-slice"
|
||||||
|
* Just do nothing in this case.
|
||||||
|
*/
|
||||||
|
if (getAL() != 0x80) goto Default;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Extended Memory Specification */
|
/* Extended Memory Specification */
|
||||||
case 0x43:
|
case 0x43:
|
||||||
{
|
{
|
||||||
|
@ -2057,7 +2134,7 @@ VOID WINAPI DosInt2Fh(LPWORD Stack)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: Default:
|
||||||
{
|
{
|
||||||
DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n",
|
DPRINT1("DOS Internal System Function INT 0x2F, AH = %xh, AL = %xh NOT IMPLEMENTED!\n",
|
||||||
getAH(), getAL());
|
getAH(), getAL());
|
||||||
|
@ -2073,6 +2150,8 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
UCHAR i;
|
UCHAR i;
|
||||||
PDOS_SFT Sft;
|
PDOS_SFT Sft;
|
||||||
LPSTR Path;
|
LPSTR Path;
|
||||||
|
BOOLEAN Success = TRUE;
|
||||||
|
DWORD dwRet;
|
||||||
CHAR CurrentDirectory[MAX_PATH];
|
CHAR CurrentDirectory[MAX_PATH];
|
||||||
CHAR DosDirectory[DOS_DIR_LENGTH];
|
CHAR DosDirectory[DOS_DIR_LENGTH];
|
||||||
|
|
||||||
|
@ -2103,60 +2182,89 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT);
|
SysVars->FirstSft = MAKELONG(DOS_DATA_OFFSET(Sft), DOS_DATA_SEGMENT);
|
||||||
SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories),
|
SysVars->CurrentDirs = MAKELONG(DOS_DATA_OFFSET(CurrentDirectories),
|
||||||
DOS_DATA_SEGMENT);
|
DOS_DATA_SEGMENT);
|
||||||
/* The last drive can be redefined with the LASTDRIVE command. At the moment, set the real maximum possible, 'Z'. */
|
/*
|
||||||
SysVars->NumLocalDrives = 'Z' - 'A' + 1;
|
* The last drive can be redefined with the LASTDRIVE command.
|
||||||
|
* At the moment, set the real maximum possible, 'Z'.
|
||||||
|
*/
|
||||||
|
SysVars->NumLocalDrives = 'Z' - 'A' + 1; // See #define NUM_DRIVES in dos.h
|
||||||
|
|
||||||
/* The boot drive is initialized to the %SYSTEMDRIVE% value */
|
/* The boot drive is initialized to the %SYSTEMDRIVE% value */
|
||||||
// NOTE: Using the NtSystemRoot system variable might be OS-specific...
|
// NOTE: Using the NtSystemRoot system variable might be OS-specific...
|
||||||
SysVars->BootDrive = SharedUserData->NtSystemRoot[0] - 'A' + 1;
|
SysVars->BootDrive = RtlUpcaseUnicodeChar(SharedUserData->NtSystemRoot[0]) - 'A' + 1;
|
||||||
|
|
||||||
/* Initialize the NUL device driver */
|
/* Initialize the NUL device driver */
|
||||||
SysVars->NullDevice.Link = 0xFFFFFFFF;
|
SysVars->NullDevice.Link = 0xFFFFFFFF;
|
||||||
SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER;
|
SysVars->NullDevice.DeviceAttributes = DOS_DEVATTR_NUL | DOS_DEVATTR_CHARACTER;
|
||||||
SysVars->NullDevice.StrategyRoutine = FIELD_OFFSET(DOS_SYSVARS, NullDriverRoutine);
|
// Offset from within the DOS data segment
|
||||||
|
SysVars->NullDevice.StrategyRoutine = DOS_DATA_OFFSET(NullDriverRoutine);
|
||||||
|
// Hardcoded to the RETF inside StrategyRoutine
|
||||||
SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6;
|
SysVars->NullDevice.InterruptRoutine = SysVars->NullDevice.StrategyRoutine + 6;
|
||||||
RtlFillMemory(SysVars->NullDevice.DeviceName,
|
RtlFillMemory(SysVars->NullDevice.DeviceName,
|
||||||
sizeof(SysVars->NullDevice.DeviceName),
|
sizeof(SysVars->NullDevice.DeviceName),
|
||||||
' ');
|
' ');
|
||||||
RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL"));
|
RtlCopyMemory(SysVars->NullDevice.DeviceName, "NUL", strlen("NUL"));
|
||||||
RtlCopyMemory(SysVars->NullDriverRoutine,
|
RtlCopyMemory(DosData->NullDriverRoutine,
|
||||||
NullDriverRoutine,
|
NullDriverRoutine,
|
||||||
sizeof(NullDriverRoutine));
|
sizeof(NullDriverRoutine));
|
||||||
|
|
||||||
|
/* Default DOS version to report */
|
||||||
|
DosData->DosVersion = DOS_VERSION;
|
||||||
|
|
||||||
/* Initialize the swappable data area */
|
/* Initialize the swappable data area */
|
||||||
Sda = &DosData->Sda;
|
Sda = &DosData->Sda;
|
||||||
RtlZeroMemory(Sda, sizeof(*Sda));
|
RtlZeroMemory(Sda, sizeof(*Sda));
|
||||||
|
|
||||||
/* Get the current directory */
|
/* Get the current directory and convert it to a DOS path */
|
||||||
if (!GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory))
|
dwRet = GetCurrentDirectoryA(sizeof(CurrentDirectory), CurrentDirectory);
|
||||||
|
if (dwRet == 0)
|
||||||
{
|
{
|
||||||
// TODO: Use some kind of default path?
|
Success = FALSE;
|
||||||
return FALSE;
|
DPRINT1("GetCurrentDirectoryA failed (Error: %u)\n", GetLastError());
|
||||||
|
}
|
||||||
|
else if (dwRet > sizeof(CurrentDirectory))
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
DPRINT1("Current directory too long (%d > MAX_PATH) for GetCurrentDirectoryA\n", dwRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert it to a DOS path */
|
if (Success)
|
||||||
if (!GetShortPathNameA(CurrentDirectory, DosDirectory, sizeof(DosDirectory)))
|
|
||||||
{
|
{
|
||||||
// TODO: Use some kind of default path?
|
dwRet = GetShortPathNameA(CurrentDirectory, DosDirectory, sizeof(DosDirectory));
|
||||||
return FALSE;
|
if (dwRet == 0)
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
DPRINT1("GetShortPathNameA failed (Error: %u)\n", GetLastError());
|
||||||
|
}
|
||||||
|
else if (dwRet > sizeof(DosDirectory))
|
||||||
|
{
|
||||||
|
Success = FALSE;
|
||||||
|
DPRINT1("Short path too long (%d > DOS_DIR_LENGTH) for GetShortPathNameA\n", dwRet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the drive */
|
if (!Success)
|
||||||
|
{
|
||||||
|
/* We failed, use the boot drive instead */
|
||||||
|
DosDirectory[0] = SysVars->BootDrive + 'A' - 1;
|
||||||
|
DosDirectory[1] = ':';
|
||||||
|
DosDirectory[2] = '\\';
|
||||||
|
DosDirectory[3] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the current drive */
|
||||||
Sda->CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A';
|
Sda->CurrentDrive = RtlUpperChar(DosDirectory[0]) - 'A';
|
||||||
|
|
||||||
/* Get the directory part of the path */
|
/* Get the directory part of the path and set the current directory */
|
||||||
Path = strchr(DosDirectory, '\\');
|
Path = strchr(DosDirectory, '\\');
|
||||||
if (Path != NULL)
|
if (Path != NULL)
|
||||||
{
|
{
|
||||||
/* Skip the backslash */
|
Path++; // Skip the backslash
|
||||||
Path++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the directory */
|
|
||||||
if (Path != NULL)
|
|
||||||
{
|
|
||||||
strncpy(DosData->CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH);
|
strncpy(DosData->CurrentDirectories[Sda->CurrentDrive], Path, DOS_DIR_LENGTH);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DosData->CurrentDirectories[Sda->CurrentDrive][0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the current PSP to the system PSP */
|
/* Set the current PSP to the system PSP */
|
||||||
Sda->CurrentPsp = SYSTEM_PSP;
|
Sda->CurrentPsp = SYSTEM_PSP;
|
||||||
|
@ -2205,7 +2313,13 @@ BOOLEAN DosKRNLInitialize(VOID)
|
||||||
RegisterDosInt32(0x2F, DosInt2Fh ); // Multiplex Interrupt
|
RegisterDosInt32(0x2F, DosInt2Fh ); // Multiplex Interrupt
|
||||||
|
|
||||||
/* Unimplemented DOS interrupts */
|
/* Unimplemented DOS interrupts */
|
||||||
RegisterDosInt32(0x2A, NULL); // Network - Installation Check
|
RegisterDosInt32(0x2A, DosInt2Ah); // DOS Critical Sections / Network
|
||||||
|
// RegisterDosInt32(0x2E, NULL); // COMMAND.COM "Reload Transient"
|
||||||
|
|
||||||
|
/* Reserved DOS interrupts */
|
||||||
|
RegisterDosInt32(0x2B, NULL);
|
||||||
|
RegisterDosInt32(0x2C, NULL);
|
||||||
|
RegisterDosInt32(0x2D, NULL);
|
||||||
|
|
||||||
/* Initialize country data */
|
/* Initialize country data */
|
||||||
DosCountryInitialize();
|
DosCountryInitialize();
|
||||||
|
|
|
@ -80,21 +80,25 @@ typedef struct _DOS_SYSVARS
|
||||||
WORD FirstMcb;
|
WORD FirstMcb;
|
||||||
|
|
||||||
/* This is where the SYSVARS really start */
|
/* This is where the SYSVARS really start */
|
||||||
DWORD FirstDpb;
|
DWORD FirstDpb; // 0x00
|
||||||
DWORD FirstSft;
|
DWORD FirstSft; // 0x04
|
||||||
DWORD ActiveClock;
|
DWORD ActiveClock; // 0x08
|
||||||
DWORD ActiveCon;
|
DWORD ActiveCon; // 0x0c
|
||||||
BYTE Reserved0[6];
|
BYTE Reserved0[6]; // 0x10
|
||||||
DWORD CurrentDirs;
|
DWORD CurrentDirs; // 0x16
|
||||||
BYTE Reserved1[6];
|
BYTE Reserved1[6]; // 0x1a
|
||||||
BYTE NumBlockDevices;
|
BYTE NumBlockDevices; // 0x20
|
||||||
BYTE NumLocalDrives; // Set by LASTDRIVE
|
BYTE NumLocalDrives; // 0x21 - Set by LASTDRIVE
|
||||||
DOS_DRIVER NullDevice;
|
DOS_DRIVER NullDevice; // 0x22
|
||||||
BYTE NullDriverRoutine[7];
|
BYTE Reserved2; // 0x34
|
||||||
BYTE Reserved2[8];
|
WORD ProgramVersionTable; // 0x35
|
||||||
BYTE BootDrive;
|
DWORD SetVerTable; // 0x37
|
||||||
BYTE UseDwordMoves;
|
WORD Reserved3[2]; // 0x3b
|
||||||
WORD ExtMemSize;
|
WORD BuffersNumber; // 0x3f - 'x' parameter in "BUFFERS=x,y" command
|
||||||
|
WORD BuffersLookaheadNumber; // 0x41 - 'y' parameter in "BUFFERS=x,y" command
|
||||||
|
BYTE BootDrive; // 0x43
|
||||||
|
BYTE UseDwordMoves; // 0x44
|
||||||
|
WORD ExtMemSize; // 0x45
|
||||||
} DOS_SYSVARS, *PDOS_SYSVARS;
|
} DOS_SYSVARS, *PDOS_SYSVARS;
|
||||||
|
|
||||||
typedef struct _DOS_CLOCK_TRANSFER_RECORD
|
typedef struct _DOS_CLOCK_TRANSFER_RECORD
|
||||||
|
@ -232,6 +236,8 @@ typedef struct _DOS_SDA
|
||||||
typedef struct _DOS_DATA
|
typedef struct _DOS_DATA
|
||||||
{
|
{
|
||||||
DOS_SYSVARS SysVars;
|
DOS_SYSVARS SysVars;
|
||||||
|
BYTE NullDriverRoutine[7];
|
||||||
|
WORD DosVersion; // DOS version to report to programs (can be different from the true one)
|
||||||
DOS_SDA Sda;
|
DOS_SDA Sda;
|
||||||
CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
|
||||||
BYTE Sft[ANYSIZE_ARRAY];
|
BYTE Sft[ANYSIZE_ARRAY];
|
||||||
|
@ -242,8 +248,7 @@ typedef struct _DOS_DATA
|
||||||
/* VARIABLES ******************************************************************/
|
/* VARIABLES ******************************************************************/
|
||||||
|
|
||||||
extern BOOLEAN DoEcho;
|
extern BOOLEAN DoEcho;
|
||||||
extern WORD DosErrorLevel;
|
extern PDOS_DATA DosData;
|
||||||
extern WORD DosLastError;
|
|
||||||
extern PDOS_SYSVARS SysVars;
|
extern PDOS_SYSVARS SysVars;
|
||||||
extern PDOS_SDA Sda;
|
extern PDOS_SDA Sda;
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
|
||||||
/* Make sure it's valid */
|
/* Make sure it's valid */
|
||||||
if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType != 'Z')
|
if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType != 'Z')
|
||||||
{
|
{
|
||||||
DPRINT("The DOS memory arena is corrupted!\n");
|
DPRINT1("The DOS memory arena is corrupted!\n");
|
||||||
Sda->LastErrorCode = ERROR_ARENA_TRASHED;
|
Sda->LastErrorCode = ERROR_ARENA_TRASHED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
|
||||||
/* Check if this block is big enough */
|
/* Check if this block is big enough */
|
||||||
if (CurrentMcb->Size < Size) goto Next;
|
if (CurrentMcb->Size < Size) goto Next;
|
||||||
|
|
||||||
switch (Sda->AllocStrategy & 0x3F)
|
switch (Sda->AllocStrategy & ~(DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
|
||||||
{
|
{
|
||||||
case DOS_ALLOC_FIRST_FIT:
|
case DOS_ALLOC_FIRST_FIT:
|
||||||
{
|
{
|
||||||
|
@ -159,7 +159,7 @@ Done:
|
||||||
if (CurrentMcb->Size > Size)
|
if (CurrentMcb->Size > Size)
|
||||||
{
|
{
|
||||||
/* It is, split it into two blocks */
|
/* It is, split it into two blocks */
|
||||||
if ((Sda->AllocStrategy & 0x3F) != DOS_ALLOC_LAST_FIT)
|
if ((Sda->AllocStrategy & ~(DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW)) != DOS_ALLOC_LAST_FIT)
|
||||||
{
|
{
|
||||||
PDOS_MCB NextMcb = SEGMENT_TO_MCB(Result + Size + 1);
|
PDOS_MCB NextMcb = SEGMENT_TO_MCB(Result + Size + 1);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct _DOS_MCB
|
||||||
BYTE Unused[3];
|
BYTE Unused[3];
|
||||||
CHAR Name[8];
|
CHAR Name[8];
|
||||||
} DOS_MCB, *PDOS_MCB;
|
} DOS_MCB, *PDOS_MCB;
|
||||||
|
C_ASSERT(sizeof(DOS_MCB) == 0x10);
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
/* VARIABLES ******************************************************************/
|
/* VARIABLES ******************************************************************/
|
||||||
|
|
|
@ -166,7 +166,7 @@ VOID DosClonePsp(WORD DestSegment, WORD SourceSegment)
|
||||||
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
|
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
|
||||||
|
|
||||||
/* Literally copy the PSP first */
|
/* Literally copy the PSP first */
|
||||||
RtlCopyMemory(DestPsp, SourcePsp, sizeof(DOS_PSP));
|
RtlCopyMemory(DestPsp, SourcePsp, sizeof(*DestPsp));
|
||||||
|
|
||||||
/* Save the interrupt vectors */
|
/* Save the interrupt vectors */
|
||||||
DestPsp->TerminateAddress = IntVecTable[0x22];
|
DestPsp->TerminateAddress = IntVecTable[0x22];
|
||||||
|
@ -222,7 +222,8 @@ VOID DosCreatePsp(WORD Segment, WORD ProgramSize)
|
||||||
PspBlock->HandleTablePtr = MAKELONG(0x18, Segment);
|
PspBlock->HandleTablePtr = MAKELONG(0x18, Segment);
|
||||||
|
|
||||||
/* Set the DOS version */
|
/* Set the DOS version */
|
||||||
PspBlock->DosVersion = DOS_VERSION;
|
// FIXME: This is here that SETVER stuff enters into action!
|
||||||
|
PspBlock->DosVersion = DosData->DosVersion;
|
||||||
|
|
||||||
/* Set the far call opcodes */
|
/* Set the far call opcodes */
|
||||||
PspBlock->FarCall[0] = 0xCD; // int 0x21
|
PspBlock->FarCall[0] = 0xCD; // int 0x21
|
||||||
|
@ -377,16 +378,20 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
/* If no optional environment is given... */
|
/* If no optional environment is given... */
|
||||||
if (Environment == NULL)
|
if (Environment == NULL)
|
||||||
{
|
{
|
||||||
/* ... get the one from the parameter block */
|
|
||||||
ASSERT(Parameters);
|
ASSERT(Parameters);
|
||||||
Environment = (LPCSTR)SEG_OFF_TO_PTR(Parameters->Environment, 0);
|
/* ... get the one from the parameter block (if not NULL)... */
|
||||||
|
if (Parameters->Environment)
|
||||||
|
Environment = (LPCSTR)SEG_OFF_TO_PTR(Parameters->Environment, 0);
|
||||||
|
/* ... or the one from the parent (otherwise) */
|
||||||
|
else
|
||||||
|
Environment = (LPCSTR)SEG_OFF_TO_PTR(SEGMENT_TO_PSP(Sda->CurrentPsp)->EnvBlock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy the environment block to DOS memory */
|
/* Copy the environment block to DOS memory */
|
||||||
EnvBlock = DosCopyEnvironmentBlock(Environment, ExecutablePath);
|
EnvBlock = DosCopyEnvironmentBlock(Environment, ExecutablePath);
|
||||||
if (EnvBlock == 0)
|
if (EnvBlock == 0)
|
||||||
{
|
{
|
||||||
Result = ERROR_NOT_ENOUGH_MEMORY;
|
Result = Sda->LastErrorCode;
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,7 +436,6 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
|
|
||||||
/* Try to allocate that much memory */
|
/* Try to allocate that much memory */
|
||||||
Segment = DosAllocateMemory((WORD)TotalSize, &MaxAllocSize);
|
Segment = DosAllocateMemory((WORD)TotalSize, &MaxAllocSize);
|
||||||
|
|
||||||
if (Segment == 0)
|
if (Segment == 0)
|
||||||
{
|
{
|
||||||
/* Check if there's at least enough memory for the minimum size */
|
/* Check if there's at least enough memory for the minimum size */
|
||||||
|
@ -460,8 +464,10 @@ DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
|
||||||
SEGMENT_TO_PSP(Segment)->EnvBlock = EnvBlock;
|
SEGMENT_TO_PSP(Segment)->EnvBlock = EnvBlock;
|
||||||
|
|
||||||
/* Calculate the segment where the program should be loaded */
|
/* Calculate the segment where the program should be loaded */
|
||||||
if (!LoadHigh) LoadSegment = Segment + (sizeof(DOS_PSP) >> 4);
|
if (!LoadHigh)
|
||||||
else LoadSegment = Segment + TotalSize - BaseSize;
|
LoadSegment = Segment + (sizeof(DOS_PSP) >> 4);
|
||||||
|
else
|
||||||
|
LoadSegment = Segment + TotalSize - BaseSize;
|
||||||
|
|
||||||
RelocFactor = LoadSegment;
|
RelocFactor = LoadSegment;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1025,11 +1025,15 @@ BOOLEAN DosMouseInitialize(VOID)
|
||||||
|
|
||||||
VOID DosMouseCleanup(VOID)
|
VOID DosMouseCleanup(VOID)
|
||||||
{
|
{
|
||||||
|
if (DriverState.ShowCount > 0) EraseMouseCursor();
|
||||||
|
DosMouseDisable();
|
||||||
|
|
||||||
/* Restore the old mouse service interrupt handler */
|
/* Restore the old mouse service interrupt handler */
|
||||||
((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
|
((PDWORD)BaseAddress)[DOS_MOUSE_INTERRUPT] = OldIntHandler;
|
||||||
|
|
||||||
if (DriverState.ShowCount > 0) EraseMouseCursor();
|
DosFreeMemory(MouseDataSegment);
|
||||||
DosMouseDisable();
|
MouseDataSegment = 0;
|
||||||
|
MouseData = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -454,7 +454,7 @@ VOID CmosInitialize(VOID)
|
||||||
OPEN_ALWAYS,
|
OPEN_ALWAYS,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
DPRINT1("CMOS opening %s ; GetLastError() = %u\n", hCmosRam != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
|
DPRINT1("CMOS opening %s (Error: %u)\n", hCmosRam != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
|
||||||
|
|
||||||
if (hCmosRam != INVALID_HANDLE_VALUE)
|
if (hCmosRam != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
|
@ -469,7 +469,7 @@ VOID CmosInitialize(VOID)
|
||||||
DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n", CmosSize, sizeof(CmosMemory));
|
DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n", CmosSize, sizeof(CmosMemory));
|
||||||
RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
|
RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
|
||||||
}
|
}
|
||||||
DPRINT1("CMOS loading %s ; GetLastError() = %u\n", Success ? "succeeded" : "failed", GetLastError());
|
DPRINT1("CMOS loading %s (Error: %u)\n", Success ? "succeeded" : "failed", GetLastError());
|
||||||
SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
|
SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ VdmMenuExists(HMENU hConsoleMenu)
|
||||||
{
|
{
|
||||||
if (GetMenuItemID(hConsoleMenu, i) == ID_SHOWHIDE_MOUSE)
|
if (GetMenuItemID(hConsoleMenu, i) == ID_SHOWHIDE_MOUSE)
|
||||||
{
|
{
|
||||||
/* set VdmMenuPos to the position of the existing menu */
|
/* Set VdmMenuPos to the position of the existing menu */
|
||||||
VdmMenuPos = i - 1;
|
VdmMenuPos = i - 1;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ static VOID EnableExtraHardware(HANDLE ConsoleInput)
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DisplayMessage(LPCWSTR Format, ...)
|
DisplayMessage(IN LPCWSTR Format, ...)
|
||||||
{
|
{
|
||||||
#ifndef WIN2K_COMPLIANT
|
#ifndef WIN2K_COMPLIANT
|
||||||
WCHAR StaticBuffer[256];
|
WCHAR StaticBuffer[256];
|
||||||
|
@ -242,11 +242,12 @@ DisplayMessage(LPCWSTR Format, ...)
|
||||||
/*
|
/*
|
||||||
* Retrieve the message length and if it is too long, allocate
|
* Retrieve the message length and if it is too long, allocate
|
||||||
* an auxiliary buffer; otherwise use the static buffer.
|
* an auxiliary buffer; otherwise use the static buffer.
|
||||||
|
* The string is built to be NULL-terminated.
|
||||||
*/
|
*/
|
||||||
MsgLen = _vscwprintf(Format, Parameters) + 1; // NULL-terminated
|
MsgLen = _vscwprintf(Format, Parameters);
|
||||||
if (MsgLen > ARRAYSIZE(StaticBuffer))
|
if (MsgLen >= ARRAYSIZE(StaticBuffer))
|
||||||
{
|
{
|
||||||
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, MsgLen * sizeof(WCHAR));
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, (MsgLen + 1) * sizeof(WCHAR));
|
||||||
if (Buffer == NULL)
|
if (Buffer == NULL)
|
||||||
{
|
{
|
||||||
/* Allocation failed, use the static buffer and display a suitable error message */
|
/* Allocation failed, use the static buffer and display a suitable error message */
|
||||||
|
@ -256,11 +257,15 @@ DisplayMessage(LPCWSTR Format, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
MsgLen = ARRAYSIZE(Buffer);
|
MsgLen = ARRAYSIZE(Buffer) - 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Display the message */
|
RtlZeroMemory(Buffer, (MsgLen + 1) * sizeof(WCHAR));
|
||||||
_vsnwprintf(Buffer, MsgLen, Format, Parameters);
|
_vsnwprintf(Buffer, MsgLen, Format, Parameters);
|
||||||
|
|
||||||
|
va_end(Parameters);
|
||||||
|
|
||||||
|
/* Display the message */
|
||||||
DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
|
DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
|
||||||
MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
|
MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
|
||||||
|
|
||||||
|
@ -268,8 +273,6 @@ DisplayMessage(LPCWSTR Format, ...)
|
||||||
/* Free the buffer if needed */
|
/* Free the buffer if needed */
|
||||||
if (Buffer != StaticBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
if (Buffer != StaticBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_end(Parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
|
|
|
@ -75,7 +75,7 @@ extern WCHAR** NtVdmArgv;
|
||||||
/*
|
/*
|
||||||
* Interface functions
|
* Interface functions
|
||||||
*/
|
*/
|
||||||
VOID DisplayMessage(LPCWSTR Format, ...);
|
VOID DisplayMessage(IN LPCWSTR Format, ...);
|
||||||
|
|
||||||
/*static*/ VOID
|
/*static*/ VOID
|
||||||
CreateVdmMenu(HANDLE ConOutHandle);
|
CreateVdmMenu(HANDLE ConOutHandle);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue