diff options
Diffstat (limited to '')
-rw-r--r-- | private/mvdm/softpc.new/obj.vdm/ntvdm.c | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/private/mvdm/softpc.new/obj.vdm/ntvdm.c b/private/mvdm/softpc.new/obj.vdm/ntvdm.c new file mode 100644 index 000000000..be19e3327 --- /dev/null +++ b/private/mvdm/softpc.new/obj.vdm/ntvdm.c @@ -0,0 +1,354 @@ +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#include <windows.h> +#include "host_def.h" +#include "insignia.h" +#include <stdlib.h> +#include "xt.h" +#include "error.h" +#include "host_rrr.h" +#include "host_nls.h" +#include "nt_timer.h" + + + +void CpuEnvInit(void); + +typedef struct _CpuEnvironmentVariable { + struct _CpuEnvironmentVariable *Next; + char *Data; + char Name[1]; +} CPUENVVAR, *PCPUENVVAR; + +PCPUENVVAR CpuEnvVarListHead=NULL; + +#if DBG +BOOLEAN verboseGetenv; +#endif + + +INT host_main(INT argc, CHAR **argv); // located in base\support\main.c + +_CRTAPI1 main(int argc, CHAR ** argv) +{ + int ret=-1; + + /* + * Intialize synchronization events for the timer\heartbeat + * so that we can always suspend the heartbeat when an exception + * occurs. + */ + TimerInit(); + + + + try { + + CpuEnvInit(); + + /* + * Load in the default system error message, since a resource load + * will fail when we are out of memory, if this fails we must exit + * to avoid confusion. + */ + nls_init(); + + ret = host_main(argc, argv); + } + except(VdmUnhandledExceptionFilter(GetExceptionInformation())) { + ; // we shouldn't arrive here + } + + return ret; +} + + + + + + +// +// The following function is placed here, so build will resolve references to +// DbgBreakPoint here, instead of NTDLL. +// + +VOID +DbgBreakPoint( + VOID + ) +/*++ + +Routine Description: + + This routine is a substitute for the NT DbgBreakPoint routine. + If a user mode debugger is atached we invoke the real DbgBreakPoint() + thru the win32 api DebugBreak. + + If no usermode debugger is attached: + - free build no effect + - checked build raise an acces violation to invoke the system + hard error popup which will give user a chance to invoke + ntsd. + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ +HANDLE MyDebugPort; +DWORD dw; + + // are we being debugged ?? + dw = NtQueryInformationProcess( + NtCurrentProcess(), + ProcessDebugPort, + &MyDebugPort, + sizeof(MyDebugPort), + NULL ); + if (!NT_SUCCESS(dw) || MyDebugPort == NULL) { +#ifndef PROD + RaiseException(STATUS_ACCESS_VIOLATION, 0L, 0L, NULL); +#endif + return; + } + + DebugBreak(); +} + + + + + +/* + * Softpc env variables are mapped to the registry + * + * "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\WOW\CpuEnv" + * + * The string values for the CpuEnv key are read at initialization + * into the CpuEnv linked list. The Environment variables are defined + * as string key values, where the name of the value is equivalent to + * the Cpu Environment Variable name, and the string value is equivalent + * to the value of the environment variable value. This allows the + * emulator defaults to be overridden, by adding the appropriate value + * to CpuEnv subkey. Under standard retail setup there won't normally + * be a CpuEnv subkey, and NO cpu env variables defined to minimize + * code\data on a standard retail system. + * + */ + + + +/* + * Adds a CpuEnv KEY_VALUE_FULL_INFORMATION to the CpuEnvList + */ +BOOLEAN +AddToCpuEnvList( + PKEY_VALUE_FULL_INFORMATION KeyValueInfo + ) +{ + NTSTATUS Status; + ULONG BufferSize; + PCPUENVVAR CpuEnvVar; + UNICODE_STRING UnicodeString; + ANSI_STRING ValueName; + ANSI_STRING ValueData; + char NameBuffer[MAX_PATH+sizeof(WCHAR)]; + char DataBuffer[MAX_PATH+sizeof(WCHAR)]; + + + /* + * Convert Value Name and Data strings from unicode to ansi + */ + + ValueName.Buffer = NameBuffer; + ValueName.MaximumLength = sizeof(NameBuffer) - sizeof(WCHAR); + ValueName.Length = 0; + UnicodeString.Buffer = (PWSTR)KeyValueInfo->Name; + UnicodeString.MaximumLength = + UnicodeString.Length = (USHORT)KeyValueInfo->NameLength; + Status = RtlUnicodeStringToAnsiString(&ValueName, &UnicodeString,FALSE); + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + ValueData.Buffer = DataBuffer; + ValueData.MaximumLength = sizeof(DataBuffer) - sizeof(WCHAR); + ValueData.Length = 0; + UnicodeString.Buffer = (PWSTR)((PBYTE)KeyValueInfo + KeyValueInfo->DataOffset); + UnicodeString.MaximumLength = + UnicodeString.Length = (USHORT)KeyValueInfo->DataLength; + Status = RtlUnicodeStringToAnsiString(&ValueData, &UnicodeString, FALSE); + if (!NT_SUCCESS(Status)) { + return FALSE; + } + + + /* + * Allocate CPUENVLIST structure, with space for the ansi strings + */ + CpuEnvVar = malloc(sizeof(CPUENVVAR)+ // list structure size + ValueName.Length + // strlen Name + ValueData.Length + // strlen Data + 1 // Null for Data + ); + if (!CpuEnvVar) { + return FALSE; + } + + + /* + * Copy in the ansi strings, and link it into CpuEnvVar List + */ + memcpy(CpuEnvVar->Name, ValueName.Buffer, ValueName.Length); + *(CpuEnvVar->Name + ValueName.Length) = '\0'; + CpuEnvVar->Data = CpuEnvVar->Name + ValueName.Length + 1; + memcpy(CpuEnvVar->Data, ValueData.Buffer, ValueData.Length); + *(CpuEnvVar->Data + ValueData.Length) = '\0'; + CpuEnvVar->Next = CpuEnvVarListHead; + CpuEnvVarListHead = CpuEnvVar; + + return TRUE; +} + + + + +/* + * Reads the CpuEnv values from the registry, into CpuEnvList + */ +void +CpuEnvInit( + void + ) +{ + int Index; + NTSTATUS Status; + HANDLE CpuEnvKey = NULL; + ULONG ResultLength; + UNICODE_STRING UnicodeString; + OBJECT_ATTRIBUTES ObjectAttributes; + PKEY_VALUE_FULL_INFORMATION KeyValueInfo; + BYTE NameDataBuffer[sizeof(KEY_VALUE_FULL_INFORMATION) + MAX_PATH*2*sizeof(WCHAR)]; + + + + KeyValueInfo = (PKEY_VALUE_FULL_INFORMATION) NameDataBuffer; + +#ifndef MONITOR +/* + * BUGBUG temp hack code to add two env var, which aren't properly + * defaulted to in the risc cpu emulator + * + * THIS is to be removed before SUR ship 19-Dec-1995 Jonle + */ + { + PWCHAR Data; + + wcscpy(KeyValueInfo->Name, L"Soft486Buffers"); + KeyValueInfo->NameLength = wcslen(KeyValueInfo->Name) * sizeof(WCHAR); + Data = (PWCH)((PBYTE)KeyValueInfo->Name + KeyValueInfo->NameLength + sizeof(WCHAR)); + wcscpy(Data, L"511"); + KeyValueInfo->DataLength = wcslen(Data) * sizeof(WCHAR); + KeyValueInfo->DataOffset = (PBYTE)Data - (PBYTE)KeyValueInfo; + AddToCpuEnvList(KeyValueInfo); + + wcscpy(KeyValueInfo->Name, L"LCIF_FILENAME"); + KeyValueInfo->NameLength = wcslen(KeyValueInfo->Name) * sizeof(WCHAR); + Data = (PWCH)((PBYTE)KeyValueInfo->Name + KeyValueInfo->NameLength + sizeof(WCHAR)); + wcscpy(Data, L"R lcif"); + KeyValueInfo->DataLength = wcslen(Data) * sizeof(WCHAR); + KeyValueInfo->DataOffset = (PBYTE)Data - (PBYTE)KeyValueInfo; + AddToCpuEnvList(KeyValueInfo); + } + +#endif + + + + RtlInitUnicodeString( + &UnicodeString, + L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Wow\\CpuEnv" + ); + + InitializeObjectAttributes(&ObjectAttributes, + &UnicodeString, + OBJ_CASE_INSENSITIVE, + (HANDLE)NULL, + NULL + ); + + Status = NtOpenKey(&CpuEnvKey, + KEY_READ, + &ObjectAttributes + ); + + // + // If there is no CpuEnv key, CpuEnvList is empty. + // + if (!NT_SUCCESS(Status)) { + return; + } + + Index = 0; + while (TRUE) { + Status = NtEnumerateValueKey(CpuEnvKey, + Index, + KeyValueFullInformation, + KeyValueInfo, + sizeof(NameDataBuffer), + &ResultLength + ); + + if (!NT_SUCCESS(Status) || !AddToCpuEnvList(KeyValueInfo)) { + break; + } + + Index++; + }; + + NtClose(CpuEnvKey); + +#if DBG + { + char *pEnvStr; + pEnvStr = getenv("VERBOSE_GETENV"); + verboseGetenv = pEnvStr && !_stricmp(pEnvStr, "TRUE"); + } +#endif + +} + + + +/* + * In order to catch all references, we define our own + * version of the CRT getenv, which does the mapping. + */ +char * _CRTAPI1 getenv(const char *Name) +{ + PCPUENVVAR CpuEnvVar; + char *Value = NULL; + + CpuEnvVar = CpuEnvVarListHead; + while (CpuEnvVar) { + if (!_stricmp(CpuEnvVar->Name, Name)) { + Value = CpuEnvVar->Data; + break; + } + CpuEnvVar = CpuEnvVar->Next; + } + +#if DBG + if (verboseGetenv) { + DbgPrint("getenv %s:<%s>\n", Name, Value); + } +#endif + + return Value; +} |