Module: wine Branch: refs/heads/master Commit: c93afe6bfc625b375e996c557101b29bb33d1f13 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=c93afe6bfc625b375e996c55...
Author: Alexandre Julliard julliard@winehq.org Date: Wed Jan 25 13:19:11 2006 +0100
kernel: Handle a failure to load winedos a bit more gracefully.
---
dlls/kernel/dosmem.c | 41 ++++++++++++++++++++++------------------- dlls/kernel/kernel_private.h | 2 +- 2 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/dlls/kernel/dosmem.c b/dlls/kernel/dosmem.c index 30ca6cf..73bc2dc 100644 --- a/dlls/kernel/dosmem.c +++ b/dlls/kernel/dosmem.c @@ -80,7 +80,7 @@ static LONG WINAPI dosmem_handler(EXCEPT
struct winedos_exports winedos;
-void load_winedos(void) +BOOL load_winedos(void) { static HANDLE hRunOnce /* = 0 */; static HMODULE hWineDos /* = 0 */; @@ -88,7 +88,7 @@ void load_winedos(void) /* FIXME: this isn't 100% thread safe, as we won't catch access to 1MB while * loading winedos (and may return uninitialized valued) */ - if (hWineDos) return; + if (hWineDos) goto done; if (hRunOnce == 0) { HANDLE hEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); @@ -97,29 +97,31 @@ void load_winedos(void) HMODULE hModule;
/* ok, we're the winning thread */ - VirtualProtect( DOSMEM_dosmem + DOSMEM_protect, - DOSMEM_SIZE - DOSMEM_protect, - PAGE_EXECUTE_READWRITE, NULL ); - if (!(hModule = LoadLibraryA( "winedos.dll" ))) + if (!VirtualProtect( DOSMEM_dosmem + DOSMEM_protect, + DOSMEM_SIZE - DOSMEM_protect, + PAGE_EXECUTE_READWRITE, NULL ) || + !(hModule = LoadLibraryA( "winedos.dll" ))) { ERR("Could not load winedos.dll, DOS subsystem unavailable\n"); - hWineDos = (HMODULE)1; /* not to try to load it again */ - return; + hModule = (HMODULE)1; /* not to try to load it again */ } + else + { #define GET_ADDR(func) winedos.func = (void *)GetProcAddress( hModule, #func ); - GET_ADDR(AllocDosBlock); - GET_ADDR(FreeDosBlock); - GET_ADDR(ResizeDosBlock); - GET_ADDR(inport); - GET_ADDR(outport); - GET_ADDR(EmulateInterruptPM); - GET_ADDR(CallBuiltinHandler); - GET_ADDR(BiosTick); + GET_ADDR(AllocDosBlock); + GET_ADDR(FreeDosBlock); + GET_ADDR(ResizeDosBlock); + GET_ADDR(inport); + GET_ADDR(outport); + GET_ADDR(EmulateInterruptPM); + GET_ADDR(CallBuiltinHandler); + GET_ADDR(BiosTick); #undef GET_ADDR + } RtlRemoveVectoredExceptionHandler( dosmem_handler ); hWineDos = hModule; SetEvent( hRunOnce ); - return; + goto done; } /* someone beat us here... */ CloseHandle( hEvent ); @@ -127,6 +129,8 @@ void load_winedos(void)
/* and wait for the winner to have finished */ WaitForSingleObject( hRunOnce, INFINITE ); + done: + return (hWineDos != (HMODULE)1); }
/****************************************************************** @@ -142,8 +146,7 @@ static LONG WINAPI dosmem_handler(EXCEPT if (addr >= (ULONG_PTR)DOSMEM_dosmem + DOSMEM_protect && addr < (ULONG_PTR)DOSMEM_dosmem + DOSMEM_SIZE) { - load_winedos(); - return EXCEPTION_CONTINUE_EXECUTION; + if (load_winedos()) return EXCEPTION_CONTINUE_EXECUTION; } } return EXCEPTION_CONTINUE_SEARCH; diff --git a/dlls/kernel/kernel_private.h b/dlls/kernel/kernel_private.h index 7139ffb..c40a04b 100644 --- a/dlls/kernel/kernel_private.h +++ b/dlls/kernel/kernel_private.h @@ -113,7 +113,7 @@ extern BOOL DOSMEM_Init(void); extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */ extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */ extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */ -extern void load_winedos(void); +extern BOOL load_winedos(void);
/* environ.c */ extern void ENV_CopyStartupInformation(void);