void GameLogicProcessor::onMessage(const MsgComponentCreated<GameLogicComponent>& msg) { GameLogicComponent* glc = gameLogicHolder->getComponent(msg.component); glc->e_sys = getES(); glc->m_entity = msg.entity; m_notInitialized.emplace_back(msg.component); }
BOOL DemDispatch (ULONG iSvc) { #if DBG if(iSvc < SVC_DEMLASTSVC && (fShowSVCMsg & DEMSVCTRACE) && apfnSVC[iSvc] != demNotYetImplemented){ sprintf(demDebugBuffer,"DemDispatch: Entering %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n", aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI()); OutputDebugStringOem(demDebugBuffer); sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x\n", getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP()); OutputDebugStringOem(demDebugBuffer); } #endif if (iSvc >= SVC_DEMLASTSVC){ #if DBG sprintf(demDebugBuffer,"Unimplemented SVC index %x\n",iSvc); OutputDebugStringOem(demDebugBuffer); #endif setCF(1); return FALSE; } if (pHardErrPacket) { pHardErrPacket->vhe_fbInt24 = 0; } CurrentISVC = iSvc; (apfnSVC [iSvc])(); #if DBG if((fShowSVCMsg & DEMSVCTRACE)){ sprintf(demDebugBuffer,"DemDispatch:On Leaving %s\n\tAX=%.4x BX=%.4x CX=%.4x DX=%.4x DI=%.4x SI=%.4x\n", aSVCNames[iSvc],getAX(),getBX(),getCX(),getDX(),getDI(),getSI()); OutputDebugStringOem(demDebugBuffer); sprintf(demDebugBuffer,"\tCS=%.4x IP=%.4x DS=%.4x ES=%.4x SS=%.4x SP=%.4x BP=%.4x CF=%x\n", getCS(),getIP(), getDS(),getES(),getSS(),getSP(),getBP(),getCF()); OutputDebugStringOem(demDebugBuffer); } #endif return TRUE; }
static VOID CmdStartExternalCommand(VOID) { DWORD Result; // TODO: improve: this code has strong similarities // with the 'default' case of DosCreateProcess. LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI()); CHAR CmdLine[sizeof("cmd.exe /c ") + DOS_CMDLINE_LENGTH + 1] = ""; LPSTR CmdLinePtr; ULONG CmdLineLen; /* Spawn a user-defined 32-bit command preprocessor */ // FIXME: Use COMSPEC env var!! CmdLinePtr = CmdLine; strcpy(CmdLinePtr, "cmd.exe /c "); CmdLinePtr += strlen(CmdLinePtr); /* Build a Win32-compatible command-line */ CmdLineLen = min(strlen(Command), sizeof(CmdLine) - strlen(CmdLinePtr) - 1); RtlCopyMemory(CmdLinePtr, Command, CmdLineLen); CmdLinePtr[CmdLineLen] = '\0'; /* Remove any trailing return carriage character and NULL-terminate the command line */ while (*CmdLinePtr && *CmdLinePtr != '\r' && *CmdLinePtr != '\n') CmdLinePtr++; *CmdLinePtr = '\0'; DPRINT1("CMD Run Command '%s' ('%s')\n", Command, CmdLine); /* * No need to prepare the stack for DosStartComSpec since we won't start it. */ Result = DosStartProcess32(Command, CmdLine, SEG_OFF_TO_PTR(getES(), 0) /*Environment*/, MAKELONG(getIP(), getCS()) /*ReturnAddress*/, FALSE); if (Result != ERROR_SUCCESS) { DosDisplayMessage("Failed to start command '%s' ('%s'). Error: %u\n", Command, CmdLine, Result); setCF(0); setAL((UCHAR)Result); } else { DosDisplayMessage("Command '%s' ('%s') started successfully.\n", Command, CmdLine); #ifndef STANDALONE setCF(Repeat); // Set CF if we need to start a 16-bit process #else setCF(0); #endif } }
void GameLogicProcessor::Stop() { getES()->forAll<GameLogicComponent>( [](ComponentHandle handle, GameLogicComponent& l) { auto& pieces = l.m_gamelogics; for (GameLogic* logic : pieces) { logic->end(); } } ); }
VOID cmdExec (VOID) { DWORD i; DWORD dwRet; PCHAR pCommandTail; PCHAR pEnv; CHAR Buffer[MAX_PATH]; pCommandTail = (PCHAR) GetVDMAddr ((USHORT)getDS(),(USHORT)getSI()); pEnv = (PCHAR) GetVDMAddr ((USHORT)getES(),0); for (i=0 ; i<124 ; i++) { if (pCommandTail[i] == 0x0d){ pCommandTail[i] = 0; break; } } if (i == 124){ setCF(0); setAL((UCHAR)ERROR_BAD_FORMAT); return; } chDefaultDrive = (CHAR)(getAL() + 'A'); if (getAH() == 0) { cmdExec32 (pCommandTail,pEnv); } else { dwRet = GetEnvironmentVariable ("COMSPEC",Buffer,MAX_PATH); if (dwRet == 0 || dwRet >= MAX_PATH){ setCF(0); setAL((UCHAR)ERROR_BAD_ENVIRONMENT); return; } if ((dwRet + 4 + strlen(pCommandTail)) > MAX_PATH) { setCF(0); setAL((UCHAR)ERROR_BAD_ENVIRONMENT); return; } strcat (Buffer, " /c "); strcat (Buffer, pCommandTail); cmdExec32 (Buffer,pEnv); } return; }
static VOID CmdStartComSpec32(VOID) { DWORD Result; // TODO: improve: this code has strong similarities with the // 'default' case of DosCreateProcess and with the 'case 0x08'. CHAR CmdLine[sizeof("cmd.exe") + 1] = ""; /* Spawn a user-defined 32-bit command preprocessor */ // FIXME: Use COMSPEC env var!! strcpy(CmdLine, "cmd.exe"); DPRINT1("CMD Run 32-bit Command Interpreter '%s'\n", CmdLine); /* * No need to prepare the stack for DosStartComSpec since we won't start it. */ Result = DosStartProcess32(CmdLine, CmdLine, SEG_OFF_TO_PTR(getES(), 0) /*Environment*/, MAKELONG(getIP(), getCS()) /*ReturnAddress*/, FALSE); if (Result != ERROR_SUCCESS) { DosDisplayMessage("Failed to start 32-bit Command Interpreter '%s'. Error: %u\n", CmdLine, Result); setCF(0); setAL((UCHAR)Result); } else { DosDisplayMessage("32-bit Command Interpreter '%s' started successfully.\n", CmdLine); #ifndef STANDALONE setCF(Repeat); // Set CF if we need to start a 16-bit process #else setCF(0); #endif } }
VOID cmdExecComspec32 (VOID) { CHAR Buffer[MAX_PATH]; DWORD dwRet; PCHAR pEnv; dwRet = GetEnvironmentVariable ("COMSPEC",Buffer,MAX_PATH); if (dwRet == 0 || dwRet >= MAX_PATH){ setCF(0); setAL((UCHAR)ERROR_BAD_ENVIRONMENT); return; } pEnv = (PCHAR) GetVDMAddr ((USHORT)getES(),0); chDefaultDrive = (CHAR)(getAL() + 'A'); cmdExec32 (Buffer,pEnv); return; }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine is called when the driver is loaded by NT. Arguments: DriverObject - Pointer to driver object created by system. RegistryPath - Pointer to the name of the services node for this driver. Return Value: The function value is the final status from the initialization operation. --*/ { NTSTATUS ntStatus; PVOID BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL; UNICODE_STRING uszDriverString; UNICODE_STRING uszProcessEventString; UNICODE_STRING uszThreadEventString; PDEVICE_OBJECT pDeviceObject; HANDLE reg=0; OBJECT_ATTRIBUTES oa; UNICODE_STRING temp; char wbuf[100]; WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs; ULONG cr4reg; criticalSection csTest; HANDLE Ultimap2Handle; KernelCodeStepping=0; KernelWritesIgnoreWP = 0; this_cs=getCS(); this_ss=getSS(); this_ds=getDS(); this_es=getES(); this_fs=getFS(); this_gs=getGS(); //InitializeObjectAttributes(&ao, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); //PsCreateSystemThread(&Ultimap2Handle, 0, NULL, 0, NULL, TestThread, PsGetCurrentProcess()); DbgPrint("DBK loading..."); #ifdef TOBESIGNED DbgPrint("Signed version"); #endif //lame antiviruses and more lamer users that keep crying rootkit virus.... temp.Buffer=(PWCH)wbuf; temp.Length=0; temp.MaximumLength=100; RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable RtlAppendUnicodeToString(&temp, L"Service"); RtlAppendUnicodeToString(&temp, L"Descriptor"); RtlAppendUnicodeToString(&temp, L"Table"); KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp); DbgPrint("Loading driver\n"); if (RegistryPath) { DbgPrint("Registry path = %S\n", RegistryPath->Buffer); InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL); ntStatus=ZwOpenKey(®,KEY_QUERY_VALUE,&oa); if (ntStatus == STATUS_SUCCESS) { UNICODE_STRING A,B,C,D; PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD; ULONG ActualSize; DbgPrint("Opened the key\n"); BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); bufA=BufDriverString; bufB=BufDeviceString; bufC=BufProcessEventString; bufD=BufThreadEventString; RtlInitUnicodeString(&A, L"A"); RtlInitUnicodeString(&B, L"B"); RtlInitUnicodeString(&C, L"C"); RtlInitUnicodeString(&D, L"D"); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) { DbgPrint("Read ok\n"); RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data); RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data); RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data); RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data); DbgPrint("DriverString=%S\n",uszDriverString.Buffer); DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer); DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer); DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer); } else { ExFreePool(bufA); ExFreePool(bufB); ExFreePool(bufC); ExFreePool(bufD); DbgPrint("Failed reading the value\n"); ZwClose(reg); return STATUS_UNSUCCESSFUL;; } } else { DbgPrint("Failed opening the key\n"); return STATUS_UNSUCCESSFUL;; } } else loadedbydbvm=TRUE; ntStatus = STATUS_SUCCESS; if (!loadedbydbvm) { // Point uszDriverString at the driver name #ifndef CETC // Create and initialize device object ntStatus = IoCreateDevice(DriverObject, 0, &uszDriverString, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateDevice failed\n"); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } // Point uszDeviceString at the device name // Create symbolic link to the user-visible name ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus); // Delete device object if not successful IoDeleteDevice(pDeviceObject); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } #endif } //when loaded by dbvm driver object is 'valid' so store the function addresses DbgPrint("DriverObject=%p\n", DriverObject); // Load structure to point to IRP handlers... DriverObject->DriverUnload = UnloadDriver; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; if (loadedbydbvm) DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM; else DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; //Processlist init #ifndef CETC ProcessEventCount=0; KeInitializeSpinLock(&ProcesslistSL); #endif CreateProcessNotifyRoutineEnabled=FALSE; //threadlist init ThreadEventCount=0; BufferSize=0; processlist=NULL; #ifndef AMD64 //determine if PAE is used cr4reg=(ULONG)getCR4(); if ((cr4reg & 0x20)==0x20) { PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PDE_POS=0xC0604000; MAX_PTE_POS=0xC07FFFF8; } else { PTESize=4; PAGE_SIZE_LARGE=0x400000; MAX_PDE_POS=0xC0301000; MAX_PTE_POS=0xC03FFFFC; } #else PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL; MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL; #endif #ifdef CETC DbgPrint("Going to initialice CETC\n"); InitializeCETC(); #endif //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen DbgPrint("Initializing debugger\n"); debugger_initialize(); // Return success (don't do the devicestring, I need it for unload) DbgPrint("Cleaning up initialization buffers\n"); if (BufDriverString) { ExFreePool(BufDriverString); BufDriverString=NULL; } if (BufProcessEventString) { ExFreePool(BufProcessEventString); BufProcessEventString=NULL; } if (BufThreadEventString) { ExFreePool(BufThreadEventString); BufThreadEventString=NULL; } if (reg) { ZwClose(reg); reg=0; } //fetch cpu info { DWORD r[4]; DWORD a; __cpuid(r,0); DbgPrint("cpuid.0: r[1]=%x", r[1]); if (r[1]==0x756e6547) //GenuineIntel { __cpuid(r,1); a=r[0]; cpu_stepping=a & 0xf; cpu_model=(a >> 4) & 0xf; cpu_familyID=(a >> 8) & 0xf; cpu_type=(a >> 12) & 0x3; cpu_ext_modelID=(a >> 16) & 0xf; cpu_ext_familyID=(a >> 20) & 0xff; cpu_model=cpu_model + (cpu_ext_modelID << 4); cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4); if ((r[2]<<9) & 1) { DbgPrint("Intel cpu. IA32_FEATURE_CONTROL MSR=%x", readMSR(0x3a)); } else { DbgPrint("Intel cpu without IA32_FEATURE_CONTROL MSR"); } vmx_init_dovmcall(1); setup_APIC_BASE(); //for ultimap } else {
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) /*++ Routine Description: This routine is called when the driver is loaded by NT. Arguments: DriverObject - Pointer to driver object created by system. RegistryPath - Pointer to the name of the services node for this driver. Return Value: The function value is the final status from the initialization operation. --*/ { NTSTATUS ntStatus; PVOID BufDriverString=NULL,BufProcessEventString=NULL,BufThreadEventString=NULL; UNICODE_STRING uszDriverString; UNICODE_STRING uszProcessEventString; UNICODE_STRING uszThreadEventString; PDEVICE_OBJECT pDeviceObject; HANDLE reg=0; OBJECT_ATTRIBUTES oa; UNICODE_STRING temp; char wbuf[100]; WORD this_cs, this_ss, this_ds, this_es, this_fs, this_gs; ULONG cr4reg; criticalSection csTest; DbgPrint("I'm alive!\n"); //DbgPrint("%S",oa.ObjectName.Buffer); KernelCodeStepping=0; this_cs=getCS(); this_ss=getSS(); this_ds=getDS(); this_es=getES(); this_fs=getFS(); this_gs=getGS(); #ifdef AMD64 DbgPrint("cs=%x ss=%x ds=%x es=%x fs=%x gs=%x\n",getCS(), getSS(), getDS(), getES(), getFS(), getGS()); DbgPrint("fsbase=%llx gsbase=%llx gskernel=%llx\n", readMSR(0xc0000100), readMSR(0xc0000101), readMSR(0xc0000102)); DbgPrint("rbp=%llx\n", getRBP()); DbgPrint("gs:188=%llx\n", __readgsqword(0x188)); DbgPrint("current csr=%x\n", _mm_getcsr()); #endif DbgPrint("Test critical section routines\n"); RtlZeroMemory(&csTest,sizeof(criticalSection)); DbgPrint("csTest.locked=%d\n",csTest.locked); csEnter(&csTest); DbgPrint("After enter\n"); DbgPrint("csTest.locked=%d\n",csTest.locked); csLeave(&csTest); DbgPrint("After leave\n"); DbgPrint("csTest.locked=%d\n",csTest.locked); //lame antiviruses and more lamer users that keep crying rootkit virus.... temp.Buffer=(PWCH)wbuf; temp.Length=0; temp.MaximumLength=100; RtlAppendUnicodeToString(&temp, L"Ke"); //KeServiceDescriptorTable RtlAppendUnicodeToString(&temp, L"Service"); RtlAppendUnicodeToString(&temp, L"Descriptor"); RtlAppendUnicodeToString(&temp, L"Table"); KeServiceDescriptorTable=MmGetSystemRoutineAddress(&temp); DbgPrint("Loading driver\n"); if (RegistryPath) { DbgPrint("Registry path = %S\n", RegistryPath->Buffer); InitializeObjectAttributes(&oa,RegistryPath,OBJ_KERNEL_HANDLE ,NULL,NULL); ntStatus=ZwOpenKey(®,KEY_QUERY_VALUE,&oa); if (ntStatus == STATUS_SUCCESS) { UNICODE_STRING A,B,C,D; PKEY_VALUE_PARTIAL_INFORMATION bufA,bufB,bufC,bufD; ULONG ActualSize; DbgPrint("Opened the key\n"); BufDriverString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufDeviceString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufProcessEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); BufThreadEventString=ExAllocatePool(PagedPool,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100); bufA=BufDriverString; bufB=BufDeviceString; bufC=BufProcessEventString; bufD=BufThreadEventString; RtlInitUnicodeString(&A, L"A"); RtlInitUnicodeString(&B, L"B"); RtlInitUnicodeString(&C, L"C"); RtlInitUnicodeString(&D, L"D"); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&A,KeyValuePartialInformation ,bufA,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&B,KeyValuePartialInformation ,bufB,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&C,KeyValuePartialInformation ,bufC,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) ntStatus=ZwQueryValueKey(reg,&D,KeyValuePartialInformation ,bufD,sizeof(KEY_VALUE_PARTIAL_INFORMATION)+100,&ActualSize); if (ntStatus == STATUS_SUCCESS) { DbgPrint("Read ok\n"); RtlInitUnicodeString(&uszDriverString,(PCWSTR) bufA->Data); RtlInitUnicodeString(&uszDeviceString,(PCWSTR) bufB->Data); RtlInitUnicodeString(&uszProcessEventString,(PCWSTR) bufC->Data); RtlInitUnicodeString(&uszThreadEventString,(PCWSTR) bufD->Data); DbgPrint("DriverString=%S\n",uszDriverString.Buffer); DbgPrint("DeviceString=%S\n",uszDeviceString.Buffer); DbgPrint("ProcessEventString=%S\n",uszProcessEventString.Buffer); DbgPrint("ThreadEventString=%S\n",uszThreadEventString.Buffer); } else { ExFreePool(bufA); ExFreePool(bufB); ExFreePool(bufC); ExFreePool(bufD); DbgPrint("Failed reading the value\n"); ZwClose(reg); return STATUS_UNSUCCESSFUL;; } } else { DbgPrint("Failed opening the key\n"); return STATUS_UNSUCCESSFUL;; } } else loadedbydbvm=TRUE; ntStatus = STATUS_SUCCESS; if (!loadedbydbvm) { // Point uszDriverString at the driver name #ifndef CETC // Create and initialize device object ntStatus = IoCreateDevice(DriverObject, 0, &uszDriverString, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDeviceObject); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateDevice failed\n"); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } // Point uszDeviceString at the device name // Create symbolic link to the user-visible name ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString); if(ntStatus != STATUS_SUCCESS) { DbgPrint("IoCreateSymbolicLink failed: %x\n",ntStatus); // Delete device object if not successful IoDeleteDevice(pDeviceObject); ExFreePool(BufDriverString); ExFreePool(BufDeviceString); ExFreePool(BufProcessEventString); ExFreePool(BufThreadEventString); if (reg) ZwClose(reg); return ntStatus; } #endif } //when loaded by dbvm driver object is 'valid' so store the function addresses DbgPrint("DriverObject=%p\n", DriverObject); // Load structure to point to IRP handlers... DriverObject->DriverUnload = UnloadDriver; DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose; if (loadedbydbvm) DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)DispatchIoctlDBVM; else DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; //Processlist init #ifndef CETC ProcessEventCount=0; KeInitializeSpinLock(&ProcesslistSL); #endif CreateProcessNotifyRoutineEnabled=FALSE; //threadlist init ThreadEventCount=0; BufferSize=0; processlist=NULL; #ifndef AMD64 //determine if PAE is used cr4reg=(ULONG)getCR4(); if ((cr4reg & 0x20)==0x20) { PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PDE_POS=0xC0604000; MAX_PTE_POS=0xC07FFFF8; } else { PTESize=4; PAGE_SIZE_LARGE=0x400000; MAX_PDE_POS=0xC0301000; MAX_PTE_POS=0xC03FFFFC; } #else PTESize=8; //pae PAGE_SIZE_LARGE=0x200000; MAX_PTE_POS=0xFFFFF6FFFFFFFFF8ULL; MAX_PDE_POS=0xFFFFF6FB7FFFFFF8ULL; #endif #ifdef CETC DbgPrint("Going to initialice CETC\n"); InitializeCETC(); #endif //hideme(DriverObject); //ok, for those that see this, enabling this WILL f**k up try except routines, even in usermode you'll get a blue sreen DbgPrint("Initializing debugger\n"); debugger_initialize(); // Return success (don't do the devicestring, I need it for unload) DbgPrint("Cleaning up initialization buffers\n"); if (BufDriverString) { ExFreePool(BufDriverString); BufDriverString=NULL; } if (BufProcessEventString) { ExFreePool(BufProcessEventString); BufProcessEventString=NULL; } if (BufThreadEventString) { ExFreePool(BufThreadEventString); BufThreadEventString=NULL; } if (reg) { ZwClose(reg); reg=0; } //fetch cpu info { DWORD r[4]; DWORD a; __cpuid(r,1); a=r[0]; cpu_stepping=a & 0xf; cpu_model=(a >> 4) & 0xf; cpu_familyID=(a >> 8) & 0xf; cpu_type=(a >> 12) & 0x3; cpu_ext_modelID=(a >> 16) & 0xf; cpu_ext_familyID=(a >> 20) & 0xff; cpu_model=cpu_model + (cpu_ext_modelID << 4); cpu_familyID=cpu_familyID + (cpu_ext_familyID << 4); } { APIC y; DebugStackState x; DbgPrint("offset of LBR_Count=%d\n", (UINT_PTR)&x.LBR_Count-(UINT_PTR)&x); DbgPrint("Testing forEachCpu(...)\n"); forEachCpu(TestDPC, NULL, NULL, NULL); forEachCpuPassive(TestPassive, 0); DbgPrint("LVT_Performance_Monitor=%x\n", (UINT_PTR)&y.LVT_Performance_Monitor-(UINT_PTR)&y); } return STATUS_SUCCESS; }
__declspec(dllexport) void __cdecl VDDDispatch(void) { char str[512]; DWORD count; DWORD msgs; int retval; int node_num; BYTE* p; vdd_status_t* status; static DWORD writes; static DWORD bytes_written; static DWORD reads; static DWORD bytes_read; static DWORD inbuf_poll; static DWORD online_poll; static DWORD status_poll; static DWORD vdd_yields; static DWORD vdd_calls; VDD_IO_HANDLERS IOHandlers = { NULL }; static VDD_IO_PORTRANGE PortRange; retval=0; node_num=getBH(); lprintf(LOG_DEBUG,"VDD_OP: (handle=%d) %d (arg=%X)", getAX(),getBL(),getCX()); vdd_calls++; switch(getBL()) { case VDD_OPEN: sscanf("$Revision: 1.40 $", "%*s %s", revision); lprintf(LOG_INFO,"Synchronet Virtual Device Driver, rev %s %s %s" ,revision, __DATE__, __TIME__); #if 0 sprintf(str,"sbbsexec%d.log",node_num); fp=fopen(str,"wb"); #endif sprintf(str,"\\\\.\\mailslot\\sbbsexec\\wr%d",node_num); rdslot=CreateMailslot(str ,0 //LINEAR_RX_BUFLEN /* Max message size (0=any) */ ,MAILSLOT_WAIT_FOREVER /* Read timeout */ ,NULL); if(rdslot==INVALID_HANDLE_VALUE) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=1; break; } sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d",node_num); wrslot=CreateFile(str ,GENERIC_WRITE ,FILE_SHARE_READ ,NULL ,OPEN_EXISTING ,FILE_ATTRIBUTE_NORMAL ,(HANDLE) NULL); if(wrslot==INVALID_HANDLE_VALUE) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=2; break; } if(RingBufInit(&rdbuf, RINGBUF_SIZE_IN)!=0) { retval=3; break; } sprintf(str,"sbbsexec_hungup%d",node_num); hungup_event=OpenEvent( EVENT_ALL_ACCESS, /* access flag */ FALSE, /* inherit flag */ str); /* pointer to event-object name */ if(hungup_event==NULL) { lprintf(LOG_ERR,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); retval=4; break; } sprintf(str,"sbbsexec_hangup%d",node_num); hangup_event=OpenEvent( EVENT_ALL_ACCESS, /* access flag */ FALSE, /* inherit flag */ str); /* pointer to event-object name */ if(hangup_event==NULL) { lprintf(LOG_WARNING,"!VDD_OPEN: Error %d opening %s" ,GetLastError(),str); } status_poll=0; inbuf_poll=0; online_poll=0; yields=0; lprintf(LOG_INFO,"Yield interval: %f milliseconds", yield_interval); if(virtualize_uart) { lprintf(LOG_INFO,"Virtualizing UART (0x%x, IRQ %u)" ,uart_io_base, uart_irq); IOHandlers.inb_handler = uart_rdport; IOHandlers.outb_handler = uart_wrport; PortRange.First=uart_io_base; PortRange.Last=uart_io_base + UART_IO_RANGE; VDDInstallIOHook((HANDLE)getAX(), 1, &PortRange, &IOHandlers); interrupt_event=CreateEvent(NULL,FALSE,FALSE,NULL); InitializeCriticalSection(&interrupt_mutex); _beginthread(interrupt_thread, 0, NULL); } lprintf(LOG_DEBUG,"VDD_OPEN: Opened successfully (wrslot=%p)", wrslot); _beginthread(input_thread, 0, NULL); retval=0; break; case VDD_CLOSE: lprintf(LOG_INFO,"VDD_CLOSE: rdbuf=%u " "status_poll=%u inbuf_poll=%u online_poll=%u yields=%u vdd_yields=%u vdd_calls=%u" ,RingBufFull(&rdbuf),status_poll,inbuf_poll,online_poll ,yields,vdd_yields,vdd_calls); lprintf(LOG_INFO," read=%u bytes (in %u calls)",bytes_read,reads); lprintf(LOG_INFO," wrote=%u bytes (in %u calls)",bytes_written,writes); if(virtualize_uart) { lprintf(LOG_INFO,"Uninstalling Virtualizaed UART IO Hook"); VDDDeInstallIOHook((HANDLE)getAX(), 1, &PortRange); } CloseHandle(rdslot); CloseHandle(wrslot); if(hungup_event!=NULL) CloseHandle(hungup_event); if(hangup_event!=NULL) CloseHandle(hangup_event); #if 0 /* This isn't strictly necessary... and possibly the cause of a NULL dereference in the input_thread */ RingBufDispose(&rdbuf); #endif status_poll=0; retval=0; break; case VDD_READ: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_READ of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); retval=vdd_read(p, count); reads++; bytes_read+=retval; reset_yield(); break; case VDD_PEEK: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_PEEK of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); retval=RingBufPeek(&rdbuf,p,count); reset_yield(); break; case VDD_WRITE: count = getCX(); if(count != 1) lprintf(LOG_DEBUG,"VDD_WRITE of %d",count); p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); if(!WriteFile(wrslot,p,count,&retval,NULL)) { lprintf(LOG_ERR,"!VDD_WRITE: WriteFile Error %d (size=%d)" ,GetLastError(),retval); retval=0; } else { writes++; bytes_written+=retval; reset_yield(); } break; case VDD_STATUS: status_poll++; count = getCX(); if(count != sizeof(vdd_status_t)) { lprintf(LOG_DEBUG,"!VDD_STATUS: wrong size (%d!=%d)",count,sizeof(vdd_status_t)); retval=sizeof(vdd_status_t); break; } status = (vdd_status_t*) GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); status->inbuf_size=RINGBUF_SIZE_IN; status->inbuf_full=RingBufFull(&rdbuf); msgs=0; /* OUTBUF FULL/SIZE */ if(!GetMailslotInfo( wrslot, /* mailslot handle */ &status->outbuf_size, /* address of maximum message size */ &status->outbuf_full, /* address of size of next message */ &msgs, /* address of number of messages */ NULL /* address of read time-out */ )) { lprintf(LOG_ERR,"!VDD_STATUS: GetMailSlotInfo(%p) failed, error %u (msgs=%u, inbuf_full=%u, inbuf_size=%u)" ,wrslot ,GetLastError(), msgs, status->inbuf_full, status->inbuf_size); status->outbuf_full=0; status->outbuf_size=DEFAULT_MAX_MSG_SIZE; } else lprintf(LOG_DEBUG,"VDD_STATUS: MailSlot maxmsgsize=%u, nextmsgsize=%u, msgs=%u" ,status->outbuf_size ,status->outbuf_full ,msgs); if(status->outbuf_full==MAILSLOT_NO_MESSAGE) status->outbuf_full=0; status->outbuf_full*=msgs; /* ONLINE */ if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) status->online=0; else status->online=1; retval=0; /* success */ break; case VDD_INBUF_PURGE: RingBufReInit(&rdbuf); retval=0; break; case VDD_OUTBUF_PURGE: lprintf(LOG_WARNING,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED"); retval=0; break; case VDD_INBUF_FULL: retval=RingBufFull(&rdbuf); inbuf_poll++; break; case VDD_INBUF_SIZE: retval=RINGBUF_SIZE_IN; break; case VDD_OUTBUF_FULL: if(!GetMailslotInfo( wrslot, /* mailslot handle */ NULL, /* address of maximum message size */ &retval, /* address of size of next message */ &msgs, /* address of number of messages */ NULL /* address of read time-out */ )) retval=0; if(retval==MAILSLOT_NO_MESSAGE) retval=0; retval*=msgs; break; case VDD_OUTBUF_SIZE: if(!GetMailslotInfo( wrslot, /* mailslot handle */ &retval, /* address of maximum message size */ NULL, /* address of size of next message */ NULL, /* address of number of messages */ NULL /* address of read time-out */ )) retval=DEFAULT_MAX_MSG_SIZE; break; case VDD_ONLINE: if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0) retval=0; else retval=1; online_poll++; break; case VDD_YIELD: /* forced yield */ vdd_yields++; yield(); break; case VDD_MAYBE_YIELD: /* yield if YieldInterval is enabled and expired */ maybe_yield(); break; case VDD_LOAD_INI_FILE: /* Load and parse settings file */ { FILE* fp; char cwd[MAX_PATH+1]; /* Load exec/sbbsexec.ini first (setting default values) */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); iniFileName(ini_fname, sizeof(ini_fname), p, INI_FILENAME); if((fp=fopen(ini_fname,"r"))!=NULL) { ini=iniReadFile(fp); fclose(fp); parse_ini(ROOT_SECTION); } /* Load cwd/sbbsexec.ini second (over-riding default values) */ GetCurrentDirectory(sizeof(cwd),cwd); iniFileName(ini_fname, sizeof(ini_fname), cwd, INI_FILENAME); if((fp=fopen(ini_fname,"r"))!=NULL) { ini=iniReadFile(fp); fclose(fp); parse_ini(ROOT_SECTION); } } break; case VDD_LOAD_INI_SECTION: /* Parse (program-specific) sub-section of settings file */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); parse_ini(p); break; case VDD_DEBUG_OUTPUT: /* Send string to debug output */ count = getCX(); p = (BYTE*)GetVDMPointer((ULONG)((getES() << 16)|getDI()) ,count,FALSE); lputs(LOG_INFO, p); break; case VDD_HANGUP: hangup(); break; default: lprintf(LOG_ERR,"!UNKNOWN VDD_OP: %d",getBL()); break; } setAX((WORD)retval); }
VOID DpmiGetMemoryInfo( VOID ) /*++ Routine Description: This routine returns information about memory to the dos extender Arguments: None Return Value: None. --*/ { PDPMIMEMINFO UNALIGNED MemInfo; MEMORYSTATUS MemStatus; ULONG TotalFree, LargestFree; NTSTATUS Status; // // Get a pointer to the return structure // MemInfo = (PDPMIMEMINFO)Sim32GetVDMPointer( ((ULONG)getES()) << 16, 1, TRUE ); (CHAR *)MemInfo += (*GetDIRegister)(); // // Initialize the structure // RtlFillMemory(MemInfo, sizeof(DPMIMEMINFO), 0xFF); // // Get the information on memory // Status = VdmQueryFreeVirtualMemory( &TotalFree, &LargestFree ); if (Status == STATUS_NOT_IMPLEMENTED) { SAQueryFree( ExtMemSA, &TotalFree, &LargestFree ); } // // Return the information. // // Filled in MaxUnlocked,MaxLocked,UnlockedPages fields in this structute. // Director 4.0 get completlely confused if these fields are -1. // MaxUnlocked is correct based on LargestFree. The other two are fake // and match values on a real WFW machine. I have no way of making them // any better than this at this point. Hell, it makes director happy. // // sudeepb 01-Mar-1995. MemInfo->LargestFree = LargestFree; MemInfo->MaxUnlocked = LargestFree/4096; MemInfo->MaxLocked = 0xb61; MemInfo->AddressSpaceSize = 1024 * 1024 * 16 / 4096; MemInfo->UnlockedPages = 0xb68; MemInfo->FreePages = TotalFree / 4096; MemInfo->PhysicalPages = 1024 * 1024 * 16 / 4096; MemInfo->FreeAddressSpace = MemInfo->FreePages; // // Get the information on the page file // MemStatus.dwLength = sizeof(MEMORYSTATUS); GlobalMemoryStatus(&MemStatus); MemInfo->PageFileSize = MemStatus.dwTotalPageFile / 4096; }
VOID cmdCheckBinary (VOID) { LPSTR lpAppName; ULONG BinaryType; PPARAMBLOCK lpParamBlock; PCHAR lpCommandTail,lpTemp; ULONG AppNameLen,CommandTailLen = 0; USHORT CommandTailOff,CommandTailSeg,usTemp; NTSTATUS Status; UNICODE_STRING Unicode; OEM_STRING OemString; ANSI_STRING AnsiString; if(DontCheckDosBinaryType){ setCF(0); return; // DOS Exe } lpAppName = (LPSTR) GetVDMAddr (getDS(),getDX()); Unicode.Buffer = NULL; AnsiString.Buffer = NULL; RtlInitString((PSTRING)&OemString, lpAppName); Status = RtlOemStringToUnicodeString(&Unicode,&OemString,TRUE); if ( NT_SUCCESS(Status) ) { Status = RtlUnicodeStringToAnsiString(&AnsiString, &Unicode, TRUE); } if ( !NT_SUCCESS(Status) ) { Status = RtlNtStatusToDosError(Status); } else if (GetBinaryType (AnsiString.Buffer,(LPLONG)&BinaryType) == FALSE) { Status = GetLastError(); } if (Unicode.Buffer != NULL) { RtlFreeUnicodeString( &Unicode ); } if (AnsiString.Buffer != NULL) { RtlFreeAnsiString( &AnsiString); } if (Status){ setCF(1); setAX((USHORT)Status); return; // Invalid path } if (BinaryType == SCS_DOS_BINARY) { setCF(0); return; // DOS Exe } // Prevent certain WOW apps from being spawned by DOS exe's // This is for win31 compatibility else if (BinaryType == SCS_WOW_BINARY) { if (!IsWowAppRunnable(lpAppName)) { setCF(0); return; // Run as DOS Exe } } if (VDMForWOW && BinaryType == SCS_WOW_BINARY && IsFirstWOWCheckBinary) { IsFirstWOWCheckBinary = FALSE; setCF(0); return; // Special Hack for krnl286.exe } // dont allow running 32bit binaries from autoexec.nt. Reason is that // running non-dos binary requires that we should have read the actual // command from GetNextVDMCommand. Otherwise the whole design gets into // synchronization problems. if (IsFirstCall) { setCF(1); setAX((USHORT)ERROR_FILE_NOT_FOUND); return; } // Its a 32bit exe, replace the command with "command.com /z" and add the // original binary name to command tail. AppNameLen = strlen (lpAppName); lpParamBlock = (PPARAMBLOCK) GetVDMAddr (getES(),getBX()); if (lpParamBlock) { CommandTailOff = FETCHWORD(lpParamBlock->OffCmdTail); CommandTailSeg = FETCHWORD(lpParamBlock->SegCmdTail); lpCommandTail = (PCHAR) GetVDMAddr (CommandTailSeg,CommandTailOff); if (lpCommandTail){ CommandTailLen = *(PCHAR)lpCommandTail; lpCommandTail++; // point to the actual command tail if (CommandTailLen) CommandTailLen++; // For CR } // We are adding 3 below for "/z<space>" and anothre space between // AppName and CommandTail. if ((3 + AppNameLen + CommandTailLen ) > 128){ setCF(1); setAX((USHORT)ERROR_NOT_ENOUGH_MEMORY); return; } } // copy the stub command.com name strcpy ((PCHAR)&pSCSInfo->SCS_ComSpec,lpszComSpec+8); lpTemp = (PCHAR) &pSCSInfo->SCS_ComSpec; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setDS(usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setDX((usTemp)); // Form the command tail, first "3" is for "/z " pSCSInfo->SCS_CmdTail [0] = (UCHAR)(3 + AppNameLen + CommandTailLen); RtlCopyMemory ((PCHAR)&pSCSInfo->SCS_CmdTail[1],"/z ",3); strcpy ((PCHAR)&pSCSInfo->SCS_CmdTail[4],lpAppName); if (CommandTailLen) { pSCSInfo->SCS_CmdTail[4+AppNameLen] = ' '; RtlCopyMemory ((PCHAR)((ULONG)&pSCSInfo->SCS_CmdTail[4]+AppNameLen+1), lpCommandTail, CommandTailLen); } else { pSCSInfo->SCS_CmdTail[4+AppNameLen] = 0xd; } // Set the parameter Block if (lpParamBlock) { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,lpParamBlock->SegEnv); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,lpParamBlock->pFCB1); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,lpParamBlock->pFCB2); } else { STOREWORD(pSCSInfo->SCS_ParamBlock.SegEnv,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB1,0); STOREDWORD(pSCSInfo->SCS_ParamBlock.pFCB2,0); } lpTemp = (PCHAR) &pSCSInfo->SCS_CmdTail; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); STOREWORD(pSCSInfo->SCS_ParamBlock.OffCmdTail,usTemp); usTemp = (USHORT)((ULONG)lpTemp >> 4); STOREWORD(pSCSInfo->SCS_ParamBlock.SegCmdTail,usTemp); lpTemp = (PCHAR) &pSCSInfo->SCS_ParamBlock; lpTemp = (PCHAR)((ULONG)lpTemp - (ULONG)GetVDMAddr(0,0)); usTemp = (USHORT)((ULONG)lpTemp >> 4); setES (usTemp); usTemp = (USHORT)((ULONG)lpTemp & 0x0f); setBX (usTemp); setCF(0); return; }
VOID WINAPI ThirdPartyVDDBop(LPWORD Stack) { /* Get the Function Number and skip it */ BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP()); setIP(getIP() + 1); switch (FuncNum) { /* RegisterModule */ case 0: { BOOL Success = TRUE; WORD RetVal = 0; WORD Entry = 0; LPCSTR DllName = NULL, InitRoutineName = NULL, DispatchRoutineName = NULL; HMODULE hDll = NULL; VDD_PROC InitRoutine = NULL, DispatchRoutine = NULL; DPRINT("RegisterModule() called\n"); /* Clear the Carry Flag (no error happened so far) */ setCF(0); /* Retrieve the next free entry in the table (used later on) */ Entry = GetNextFreeVDDEntry(); if (Entry >= MAX_VDD_MODULES) { DPRINT1("Failed to create a new VDD module entry\n"); Success = FALSE; RetVal = 4; goto Quit; } /* Retrieve the VDD name in DS:SI */ DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI()); /* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */ if (TO_LINEAR(getES(), getDI()) != 0) InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI()); /* Retrieve the dispatch routine API name in DS:BX */ DispatchRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getBX()); DPRINT1("DllName = '%s' - InitRoutineName = '%s' - DispatchRoutineName = '%s'\n", (DllName ? DllName : "n/a"), (InitRoutineName ? InitRoutineName : "n/a"), (DispatchRoutineName ? DispatchRoutineName : "n/a")); /* Load the VDD DLL */ hDll = LoadLibraryA(DllName); if (hDll == NULL) { DWORD LastError = GetLastError(); Success = FALSE; if (LastError == ERROR_NOT_ENOUGH_MEMORY) { DPRINT1("Not enough memory to load DLL '%s'\n", DllName); RetVal = 4; goto Quit; } else { DPRINT1("Failed to load DLL '%s'; last error = %d\n", DllName, LastError); RetVal = 1; goto Quit; } } /* Load the initialization routine if needed */ if (InitRoutineName) { InitRoutine = (VDD_PROC)GetProcAddress(hDll, InitRoutineName); if (InitRoutine == NULL) { DPRINT1("Failed to load the initialization routine '%s'\n", InitRoutineName); Success = FALSE; RetVal = 3; goto Quit; } } /* Load the dispatch routine */ DispatchRoutine = (VDD_PROC)GetProcAddress(hDll, DispatchRoutineName); if (DispatchRoutine == NULL) { DPRINT1("Failed to load the dispatch routine '%s'\n", DispatchRoutineName); Success = FALSE; RetVal = 2; goto Quit; } /* If we arrived there, that means everything is OK */ /* Register the VDD DLL */ VDDList[Entry].hDll = hDll; VDDList[Entry].DispatchRoutine = DispatchRoutine; /* Call the initialization routine if needed */ if (InitRoutine) InitRoutine(); /* We succeeded. RetVal will contain a valid VDD DLL handle */ Success = TRUE; RetVal = ENTRY_TO_HANDLE(Entry); // Convert the entry to a valid handle Quit: if (!Success) { /* Unload the VDD DLL */ if (hDll) FreeLibrary(hDll); /* Set the Carry Flag to indicate that an error happened */ setCF(1); } // else // { // /* Clear the Carry Flag (success) */ // setCF(0); // } setAX(RetVal); break; } /* UnRegisterModule */ case 1: { WORD Handle = getAX(); WORD Entry = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry DPRINT("UnRegisterModule() called\n"); /* Sanity checks */ if (!IS_VALID_HANDLE(Handle) || VDDList[Entry].hDll == NULL) { DPRINT1("Invalid VDD DLL Handle: %d\n", Entry); /* Stop the VDM */ EmulatorTerminate(); return; } /* Unregister the VDD DLL */ FreeLibrary(VDDList[Entry].hDll); VDDList[Entry].hDll = NULL; VDDList[Entry].DispatchRoutine = NULL; break; } /* DispatchCall */ case 2: { WORD Handle = getAX(); WORD Entry = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry DPRINT("DispatchCall() called\n"); /* Sanity checks */ if (!IS_VALID_HANDLE(Handle) || VDDList[Entry].hDll == NULL || VDDList[Entry].DispatchRoutine == NULL) { DPRINT1("Invalid VDD DLL Handle: %d\n", Entry); /* Stop the VDM */ EmulatorTerminate(); return; } /* Call the dispatch routine */ VDDList[Entry].DispatchRoutine(); break; } default: { DPRINT1("Unknown 3rd-party VDD BOP Function: 0x%02X\n", FuncNum); setCF(1); break; } } }
bool GameLogicProcessor::Init() { gameLogicHolder = getES()->getHolder<GameLogicComponent>(); return true; }
static VOID WINAPI EmsIntHandler(LPWORD Stack) { switch (getAH()) { /* Get Manager Status */ case 0x40: { setAH(EMS_STATUS_SUCCESS); break; } /* Get Page Frame Segment */ case 0x41: { setAH(EMS_STATUS_SUCCESS); setBX(EmsSegment); break; } /* Get Number of Unallocated Pages */ case 0x42: { setAH(EMS_STATUS_SUCCESS); setBX(RtlNumberOfClearBits(&AllocBitmap)); setDX(EmsTotalPages); break; } /* Get Handle and Allocate Memory */ case 0x43: { USHORT Handle; UCHAR Status = EmsAlloc(getBX(), &Handle); if (Status == EMS_STATUS_SUCCESS) setDX(Handle); setAH(Status); break; } /* Map Memory */ case 0x44: { setAH(EmsMap(getDX(), getAL(), getBX())); break; } /* Release Handle and Memory */ case 0x45: { setAH(EmsFree(getDX())); break; } /* Get EMM Version */ case 0x46: { setAH(EMS_STATUS_SUCCESS); setAL(EMS_VERSION_NUM); break; } /* Save Page Map */ case 0x47: { // FIXME: This depends on an EMS handle given in DX RtlCopyMemory(MappingBackup, Mapping, sizeof(Mapping)); setAH(EMS_STATUS_SUCCESS); break; } /* Restore Page Map */ case 0x48: { // FIXME: This depends on an EMS handle given in DX RtlCopyMemory(Mapping, MappingBackup, sizeof(Mapping)); setAH(EMS_STATUS_SUCCESS); break; } /* Get Number of Opened Handles */ case 0x4B: { USHORT NumOpenHandles = 0; USHORT i; for (i = 0; i < ARRAYSIZE(HandleTable); i++) { if (HandleTable[i].Allocated) ++NumOpenHandles; } setAH(EMS_STATUS_SUCCESS); setBX(NumOpenHandles); break; } /* Get Handle Number of Pages */ case 0x4C: { PEMS_HANDLE HandleEntry = GetHandleRecord(getDX()); if (!ValidateHandle(HandleEntry)) { setAH(EMS_STATUS_INVALID_HANDLE); break; } setAH(EMS_STATUS_SUCCESS); setBX(HandleEntry->PageCount); break; } /* Get All Handles Number of Pages */ case 0x4D: { PEMS_HANDLE_PAGE_INFO HandlePageInfo = (PEMS_HANDLE_PAGE_INFO)SEG_OFF_TO_PTR(getES(), getDI()); USHORT NumOpenHandles = 0; USHORT i; for (i = 0; i < ARRAYSIZE(HandleTable); i++) { if (HandleTable[i].Allocated) { HandlePageInfo->Handle = i; HandlePageInfo->PageCount = HandleTable[i].PageCount; ++HandlePageInfo; ++NumOpenHandles; } } setAH(EMS_STATUS_SUCCESS); setBX(NumOpenHandles); break; } /* Get or Set Page Map */ case 0x4E: { switch (getAL()) { /* Get Mapping Registers */ // case 0x00: // TODO: NOT IMPLEMENTED /* Set Mapping Registers */ // case 0x01: // TODO: NOT IMPLEMENTED /* Get and Set Mapping Registers At Once */ // case 0x02: // TODO: NOT IMPLEMENTED /* Get Size of Page-Mapping Array */ case 0x03: { setAH(EMS_STATUS_SUCCESS); setAL(sizeof(Mapping)); break; } default: { DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL()); setAH(EMS_STATUS_UNKNOWN_FUNCTION); break; } } break; } /* Get/Set Handle Name */ case 0x53: { PEMS_HANDLE HandleEntry = GetHandleRecord(getDX()); if (!ValidateHandle(HandleEntry)) { setAH(EMS_STATUS_INVALID_HANDLE); break; } if (getAL() == 0x00) { /* Retrieve the name */ RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()), HandleEntry->Name, sizeof(HandleEntry->Name)); setAH(EMS_STATUS_SUCCESS); } else if (getAL() == 0x01) { /* Store the name */ RtlCopyMemory(HandleEntry->Name, SEG_OFF_TO_PTR(getDS(), getSI()), sizeof(HandleEntry->Name)); setAH(EMS_STATUS_SUCCESS); } else { DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL()); setAH(EMS_STATUS_INVALID_SUBFUNCTION); } break; } /* Handle Directory functions */ case 0x54: { if (getAL() == 0x00) { /* Get Handle Directory */ PEMS_HANDLE_DIR_ENTRY HandleDir = (PEMS_HANDLE_DIR_ENTRY)SEG_OFF_TO_PTR(getES(), getDI()); USHORT NumOpenHandles = 0; USHORT i; for (i = 0; i < ARRAYSIZE(HandleTable); i++) { if (HandleTable[i].Allocated) { HandleDir->Handle = i; RtlCopyMemory(HandleDir->Name, HandleTable[i].Name, sizeof(HandleDir->Name)); ++HandleDir; ++NumOpenHandles; } } setAH(EMS_STATUS_SUCCESS); setAL((UCHAR)NumOpenHandles); } else if (getAL() == 0x01) { /* Search for Named Handle */ PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI()); PEMS_HANDLE HandleFound = NULL; USHORT i; for (i = 0; i < ARRAYSIZE(HandleTable); i++) { if (HandleTable[i].Allocated && RtlCompareMemory(HandleName, HandleTable[i].Name, sizeof(HandleTable[i].Name)) == sizeof(HandleTable[i].Name)) { HandleFound = &HandleTable[i]; break; } } /* Bail out if no handle was found */ if (i >= ARRAYSIZE(HandleTable)) // HandleFound == NULL { setAH(EMS_STATUS_HANDLE_NOT_FOUND); break; } /* Return the handle number */ setDX(i); /* Sanity check: Check whether the handle was unnamed */ i = 0; while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0')) ++i; if (i >= sizeof(HandleFound->Name)) { setAH(EMS_STATUS_UNNAMED_HANDLE); } else { setAH(EMS_STATUS_SUCCESS); } } else if (getAL() == 0x02) { /* * Get Total Number of Handles * * This function retrieves the maximum number of handles * (allocated or not) the memory manager supports, which * a program may request. */ setAH(EMS_STATUS_SUCCESS); setBX(ARRAYSIZE(HandleTable)); } else { DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL()); setAH(EMS_STATUS_INVALID_SUBFUNCTION); } break; } /* Move/Exchange Memory */ case 0x57: { PUCHAR SourcePtr, DestPtr; PEMS_HANDLE HandleEntry; PEMS_PAGE PageEntry; BOOLEAN Exchange = getAL(); PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI()); if (Data->SourceType) { /* Expanded memory */ HandleEntry = GetHandleRecord(Data->SourceHandle); if (!ValidateHandle(HandleEntry)) { setAH(EMS_STATUS_INVALID_HANDLE); break; } PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment); if (!PageEntry) { setAH(EMS_STATUS_INV_LOGICAL_PAGE); break; } SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE + Data->SourceOffset); } else { /* Conventional memory */ SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset); } if (Data->DestType) { /* Expanded memory */ HandleEntry = GetHandleRecord(Data->DestHandle); if (!ValidateHandle(HandleEntry)) { setAH(EMS_STATUS_INVALID_HANDLE); break; } PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment); if (!PageEntry) { setAH(EMS_STATUS_INV_LOGICAL_PAGE); break; } DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE + Data->DestOffset); } else { /* Conventional memory */ DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset); } if (Exchange) { ULONG i; /* Exchange */ for (i = 0; i < Data->RegionLength; i++) { UCHAR Temp = DestPtr[i]; DestPtr[i] = SourcePtr[i]; SourcePtr[i] = Temp; } } else { /* Move */ RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength); } setAH(EMS_STATUS_SUCCESS); break; } /* Get Mappable Physical Address Array */ case 0x58: { if (getAL() == 0x00) { PEMS_MAPPABLE_PHYS_PAGE PageArray = (PEMS_MAPPABLE_PHYS_PAGE)SEG_OFF_TO_PTR(getES(), getDI()); ULONG i; for (i = 0; i < EMS_PHYSICAL_PAGES; i++) { PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4); PageArray->PageNumber = i; ++PageArray; } setAH(EMS_STATUS_SUCCESS); setCX(EMS_PHYSICAL_PAGES); } else if (getAL() == 0x01) { setAH(EMS_STATUS_SUCCESS); setCX(EMS_PHYSICAL_PAGES); } else { DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL()); setAH(EMS_STATUS_INVALID_SUBFUNCTION); } break; }
void ISV_RegisterModule (BOOL fMode) { char *pchDll,*pchInit,*pchDispatch; HANDLE hDll; FARPROC DispatchEntry; FARPROC InitEntry; ULONG i; UCHAR uchMode; // Check if we have free space in bop table. for (i=0; i<MAX_ISV_BOP; i++) { if (isvbop_table[i].hDll == 0) break; } if (i == MAX_ISV_BOP) { setCF (1); setAX(4); return; } uchMode = fMode ? TRUE : FALSE; pchDll = (PCHAR) Sim32GetVDMPointer (SEGOFF(getDS(),getSI()), 1, uchMode ); if (pchDll == NULL) { setCF (1); setAX(1); return; } pchInit = (PCHAR) Sim32GetVDMPointer(SEGOFF(getES(),getDI()), 1, uchMode ); pchDispatch = (PCHAR) Sim32GetVDMPointer(SEGOFF(getDS(),getBX()), 1, uchMode ); if (pchDispatch == NULL) { setCF (1); setAX(2); return; } if ((hDll = SafeLoadLibrary(pchDll)) == NULL){ setCF (1); setAX(1); return; } // Get the init entry point and dispatch entry point if (pchInit){ if ((ULONG)pchInit < 64*1024){ if (strlen (pchInit) >= MAX_PROC_NAME) { FreeLibrary(hDll); setCF (1); setAX(4); return; } strcpy (procbuffer,pchInit); pchInit = procbuffer; } if ((InitEntry = (MYFARPROC)GetProcAddress(hDll, pchInit)) == NULL){ FreeLibrary(hDll); setCF(1); setAX(3); return; } } if ((ULONG)pchDispatch < 64*1024){ if (strlen (pchDispatch) >= MAX_PROC_NAME) { FreeLibrary(hDll); setCF (1); setAX(4); return; } strcpy (procbuffer,pchDispatch); pchDispatch = procbuffer; } if ((DispatchEntry = (MYFARPROC)GetProcAddress(hDll, pchDispatch)) == NULL){ FreeLibrary(hDll); setCF(1); setAX(2); return; } // Call the init routine if (pchInit) { (*InitEntry)(); } // Fill up the bop table isvbop_table[i].hDll = hDll; isvbop_table[i].fpDispatch = DispatchEntry; i++; setAX((USHORT)i); return; }