Commit c93afe6b authored by Alexandre Julliard's avatar Alexandre Julliard

kernel: Handle a failure to load winedos a bit more gracefully.

parent 0e085844
...@@ -80,7 +80,7 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except); ...@@ -80,7 +80,7 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except);
struct winedos_exports winedos; struct winedos_exports winedos;
void load_winedos(void) BOOL load_winedos(void)
{ {
static HANDLE hRunOnce /* = 0 */; static HANDLE hRunOnce /* = 0 */;
static HMODULE hWineDos /* = 0 */; static HMODULE hWineDos /* = 0 */;
...@@ -88,7 +88,7 @@ void load_winedos(void) ...@@ -88,7 +88,7 @@ void load_winedos(void)
/* FIXME: this isn't 100% thread safe, as we won't catch access to 1MB while /* FIXME: this isn't 100% thread safe, as we won't catch access to 1MB while
* loading winedos (and may return uninitialized valued) * loading winedos (and may return uninitialized valued)
*/ */
if (hWineDos) return; if (hWineDos) goto done;
if (hRunOnce == 0) if (hRunOnce == 0)
{ {
HANDLE hEvent = CreateEventW( NULL, TRUE, FALSE, NULL ); HANDLE hEvent = CreateEventW( NULL, TRUE, FALSE, NULL );
...@@ -97,29 +97,31 @@ void load_winedos(void) ...@@ -97,29 +97,31 @@ void load_winedos(void)
HMODULE hModule; HMODULE hModule;
/* ok, we're the winning thread */ /* ok, we're the winning thread */
VirtualProtect( DOSMEM_dosmem + DOSMEM_protect, if (!VirtualProtect( DOSMEM_dosmem + DOSMEM_protect,
DOSMEM_SIZE - DOSMEM_protect, DOSMEM_SIZE - DOSMEM_protect,
PAGE_EXECUTE_READWRITE, NULL ); PAGE_EXECUTE_READWRITE, NULL ) ||
if (!(hModule = LoadLibraryA( "winedos.dll" ))) !(hModule = LoadLibraryA( "winedos.dll" )))
{ {
ERR("Could not load winedos.dll, DOS subsystem unavailable\n"); ERR("Could not load winedos.dll, DOS subsystem unavailable\n");
hWineDos = (HMODULE)1; /* not to try to load it again */ hModule = (HMODULE)1; /* not to try to load it again */
return;
} }
else
{
#define GET_ADDR(func) winedos.func = (void *)GetProcAddress( hModule, #func ); #define GET_ADDR(func) winedos.func = (void *)GetProcAddress( hModule, #func );
GET_ADDR(AllocDosBlock); GET_ADDR(AllocDosBlock);
GET_ADDR(FreeDosBlock); GET_ADDR(FreeDosBlock);
GET_ADDR(ResizeDosBlock); GET_ADDR(ResizeDosBlock);
GET_ADDR(inport); GET_ADDR(inport);
GET_ADDR(outport); GET_ADDR(outport);
GET_ADDR(EmulateInterruptPM); GET_ADDR(EmulateInterruptPM);
GET_ADDR(CallBuiltinHandler); GET_ADDR(CallBuiltinHandler);
GET_ADDR(BiosTick); GET_ADDR(BiosTick);
#undef GET_ADDR #undef GET_ADDR
}
RtlRemoveVectoredExceptionHandler( dosmem_handler ); RtlRemoveVectoredExceptionHandler( dosmem_handler );
hWineDos = hModule; hWineDos = hModule;
SetEvent( hRunOnce ); SetEvent( hRunOnce );
return; goto done;
} }
/* someone beat us here... */ /* someone beat us here... */
CloseHandle( hEvent ); CloseHandle( hEvent );
...@@ -127,6 +129,8 @@ void load_winedos(void) ...@@ -127,6 +129,8 @@ void load_winedos(void)
/* and wait for the winner to have finished */ /* and wait for the winner to have finished */
WaitForSingleObject( hRunOnce, INFINITE ); WaitForSingleObject( hRunOnce, INFINITE );
done:
return (hWineDos != (HMODULE)1);
} }
/****************************************************************** /******************************************************************
...@@ -142,8 +146,7 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except) ...@@ -142,8 +146,7 @@ static LONG WINAPI dosmem_handler(EXCEPTION_POINTERS* except)
if (addr >= (ULONG_PTR)DOSMEM_dosmem + DOSMEM_protect && if (addr >= (ULONG_PTR)DOSMEM_dosmem + DOSMEM_protect &&
addr < (ULONG_PTR)DOSMEM_dosmem + DOSMEM_SIZE) addr < (ULONG_PTR)DOSMEM_dosmem + DOSMEM_SIZE)
{ {
load_winedos(); if (load_winedos()) return EXCEPTION_CONTINUE_EXECUTION;
return EXCEPTION_CONTINUE_EXECUTION;
} }
} }
return EXCEPTION_CONTINUE_SEARCH; return EXCEPTION_CONTINUE_SEARCH;
......
...@@ -113,7 +113,7 @@ extern BOOL DOSMEM_Init(void); ...@@ -113,7 +113,7 @@ extern BOOL DOSMEM_Init(void);
extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */ extern LPVOID DOSMEM_MapRealToLinear(DWORD); /* real-mode to linear */
extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */ extern LPVOID DOSMEM_MapDosToLinear(UINT); /* linear DOS to Wine */
extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */ extern UINT DOSMEM_MapLinearToDos(LPVOID); /* linear Wine to DOS */
extern void load_winedos(void); extern BOOL load_winedos(void);
/* environ.c */ /* environ.c */
extern void ENV_CopyStartupInformation(void); extern void ENV_CopyStartupInformation(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment