/********************************************************************** * DllMain (DOSVM.0) */ BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) { TRACE_(module)("(%p,%d,%p)\n", hinstDLL, fdwReason, lpvReserved); if (fdwReason == DLL_PROCESS_ATTACH) { DisableThreadLibraryCalls(hinstDLL); if (!DOSMEM_InitDosMemory()) return FALSE; DOSVM_InitSegments(); event_notifier = CreateEventW(NULL, FALSE, FALSE, NULL); if(!event_notifier) ERR("Failed to create event object!\n"); } return TRUE; }
/********************************************************************** * __wine_call_int_handler (KERNEL.@) */ void __wine_call_int_handler( CONTEXT86 *context, BYTE intnum ) { DOSMEM_InitDosMemory(); DOSVM_CallBuiltinHandler( context, intnum ); }
/********************************************************************** * DOSVM_EmulateInterruptPM * * Emulate software interrupt in 16-bit or 32-bit protected mode. * Called from signal handler when intXX opcode is executed. * * Pushes interrupt frame to stack and changes instruction * pointer to interrupt handler. */ BOOL DOSVM_EmulateInterruptPM( CONTEXT86 *context, BYTE intnum ) { TRACE_(relay)("Call DOS int 0x%02x ret=%04x:%08x\n" " eax=%08x ebx=%08x ecx=%08x edx=%08x\n" " esi=%08x edi=%08x ebp=%08x esp=%08x\n" " ds=%04x es=%04x fs=%04x gs=%04x ss=%04x flags=%08x\n", intnum, context->SegCs, context->Eip, context->Eax, context->Ebx, context->Ecx, context->Edx, context->Esi, context->Edi, context->Ebp, context->Esp, context->SegDs, context->SegEs, context->SegFs, context->SegGs, context->SegSs, context->EFlags ); DOSMEM_InitDosMemory(); if (context->SegCs == DOSVM_dpmi_segments->dpmi_sel) { DOSVM_BuildCallFrame( context, DOSVM_IntProcRelay, DOSVM_RawModeSwitchHandler ); } else if (context->SegCs == DOSVM_dpmi_segments->relay_code_sel) { /* * This must not be called using DOSVM_BuildCallFrame. */ DOSVM_RelayHandler( context ); } else if (context->SegCs == DOSVM_dpmi_segments->int48_sel) { /* Restore original flags stored into the stack by the caller. */ DWORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp); context->EFlags = stack[2]; if (intnum != context->Eip / DOSVM_STUB_PM48) WARN( "interrupt stub has been modified " "(interrupt is %02x, interrupt stub is %02x)\n", intnum, context->Eip/DOSVM_STUB_PM48 ); TRACE( "builtin interrupt %02x has been branched to\n", intnum ); if (intnum == 0x25 || intnum == 0x26) DOSVM_PushFlags( context, TRUE, TRUE ); DOSVM_BuildCallFrame( context, DOSVM_IntProcRelay, DOSVM_GetBuiltinHandler(intnum) ); } else if (context->SegCs == DOSVM_dpmi_segments->int16_sel) { /* Restore original flags stored into the stack by the caller. */ WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp); context->EFlags = (DWORD)MAKELONG( stack[2], HIWORD(context->EFlags) ); if (intnum != context->Eip / DOSVM_STUB_PM16) WARN( "interrupt stub has been modified " "(interrupt is %02x, interrupt stub is %02x)\n", intnum, context->Eip/DOSVM_STUB_PM16 ); TRACE( "builtin interrupt %02x has been branched to\n", intnum ); if (intnum == 0x25 || intnum == 0x26) DOSVM_PushFlags( context, FALSE, TRUE ); DOSVM_BuildCallFrame( context, DOSVM_IntProcRelay, DOSVM_GetBuiltinHandler(intnum) ); } else if (wine_ldt_is_system(context->SegCs)) { INTPROC proc; if (intnum >= sizeof(DOSVM_VectorsBuiltin)/sizeof(INTPROC)) return FALSE; if (!(proc = DOSVM_VectorsBuiltin[intnum])) return FALSE; proc( context ); } else { DOSVM_HardwareInterruptPM( context, intnum ); } return TRUE; }
/*********************************************************************** * __wine_load_dos_exe (KERNEL.@) * * Called from WineVDM when a new real-mode DOS process is started. * Loads DOS program into memory and executes the program. */ void __wine_load_dos_exe( LPCSTR filename, LPCSTR cmdline ) { char dos_cmdtail[126]; int dos_length = 0; HANDLE hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 ); if (hFile == INVALID_HANDLE_VALUE) return; DOSVM_isdosexe = TRUE; DOSMEM_InitDosMemory(); if(cmdline && *cmdline) { dos_length = strlen(cmdline); memmove( dos_cmdtail + 1, cmdline, (dos_length < 125) ? dos_length : 125 ); /* Non-empty command tail always starts with at least one space. */ dos_cmdtail[0] = ' '; dos_length++; /* * If command tail is longer than 126 characters, * set tail length to 127 and fill CMDLINE environment variable * with full command line (this includes filename). */ if (dos_length > 126) { char *cmd = HeapAlloc( GetProcessHeap(), 0, dos_length + strlen(filename) + 4 ); char *ptr = cmd; if (!cmd) return; /* * Append filename. If path includes spaces, quote the path. */ if (strchr(filename, ' ')) { *ptr++ = '\"'; strcpy( ptr, filename ); ptr += strlen(filename); *ptr++ = '\"'; } else { strcpy( ptr, filename ); ptr += strlen(filename); } /* * Append command tail. */ if (cmdline[0] != ' ') *ptr++ = ' '; strcpy( ptr, cmdline ); /* * Set environment variable. This will be passed to * new DOS process. */ if (!SetEnvironmentVariableA( "CMDLINE", cmd )) { HeapFree(GetProcessHeap(), 0, cmd ); return; } HeapFree(GetProcessHeap(), 0, cmd ); dos_length = 127; } } if (MZ_DoLoadImage( hFile, filename, NULL, 0 )) { DWORD err = MZ_Launch( dos_cmdtail, dos_length ); /* if we get back here it failed */ SetLastError( err ); } }