/*********************************************************************** * WaitEvent (KERNEL.30) */ BOOL16 WINAPI WaitEvent16( HTASK16 hTask ) { TDB *pTask; if (!hTask) hTask = GetCurrentTask(); pTask = TASK_GetPtr( hTask ); if (pTask->flags & TDBF_WIN32) { FIXME("called for Win32 thread (%04x)!\n", GetCurrentThreadId()); return TRUE; } if (pTask->nEvents > 0) { pTask->nEvents--; return FALSE; } if (pTask->teb == NtCurrentTeb()) { DWORD lockCount; NtResetEvent( pTask->hEvent, NULL ); ReleaseThunkLock( &lockCount ); SYSLEVEL_CheckNotLevel( 1 ); WaitForSingleObject( pTask->hEvent, INFINITE ); RestoreThunkLock( lockCount ); if (pTask->nEvents > 0) pTask->nEvents--; } else FIXME("for other task %04x cur=%04x\n",pTask->hSelf,GetCurrentTask()); return TRUE; }
/*********************************************************************** * WIN32_OldYield (KERNEL.447) */ void WINAPI WIN32_OldYield16(void) { DWORD count; ReleaseThunkLock(&count); RestoreThunkLock(count); }
/********************************************************************** * WOW_CallProc32W */ static DWORD WOW_CallProc32W16( FARPROC proc32, DWORD nrofargs, DWORD *args ) { DWORD ret; DWORD mutex_count; ReleaseThunkLock( &mutex_count ); /* * FIXME: If ( nrofargs & CPEX_DEST_CDECL ) != 0, we should call a * 32-bit CDECL routine ... */ if (!proc32) ret = 0; else switch (nrofargs) { case 0: ret = proc32(); break; case 1: ret = proc32(args[0]); break; case 2: ret = proc32(args[0],args[1]); break; case 3: ret = proc32(args[0],args[1],args[2]); break; case 4: ret = proc32(args[0],args[1],args[2],args[3]); break; case 5: ret = proc32(args[0],args[1],args[2],args[3],args[4]); break; case 6: ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5]); break; case 7: ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6]); break; case 8: ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7]); break; case 9: ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8]); break; case 10:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9]); break; case 11:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]); break; case 12:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11]); break; case 13:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12]); break; case 14:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13]); break; case 15:ret = proc32(args[0],args[1],args[2],args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10],args[11],args[12],args[13],args[14]); break; default: /* FIXME: should go up to 32 arguments */ ERR("Unsupported number of arguments %ld, please report.\n",nrofargs); ret = 0; break; } RestoreThunkLock( mutex_count ); TRACE("returns %08lx\n",ret); return ret; }
/*********************************************************************** * VWin32_EventWait (KERNEL.450) */ VOID WINAPI VWin32_EventWait(HANDLE event) { DWORD mutex_count; ReleaseThunkLock( &mutex_count ); WaitForSingleObject( event, INFINITE ); RestoreThunkLock( mutex_count ); }
/*********************************************************************** * WaitForSingleObject (KERNEL.460) */ DWORD WINAPI WaitForSingleObject16( HANDLE handle, DWORD timeout ) { DWORD retval, mutex_count; ReleaseThunkLock( &mutex_count ); retval = WaitForSingleObject( handle, timeout ); RestoreThunkLock( mutex_count ); return retval; }
/*********************************************************************** * FreeLibrary32W (KERNEL.514) */ DWORD WINAPI FreeLibrary32W16( DWORD hLibModule ) { BOOL retv; DWORD mutex_count; ReleaseThunkLock( &mutex_count ); retv = FreeLibrary( (HMODULE)hLibModule ); RestoreThunkLock( mutex_count ); return (DWORD)retv; }
/*********************************************************************** * WaitForMultipleObjectsEx (KERNEL.495) */ DWORD WINAPI WaitForMultipleObjectsEx16( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable ) { DWORD retval, mutex_count; ReleaseThunkLock( &mutex_count ); retval = WaitForMultipleObjectsEx( count, handles, wait_all, timeout, alertable ); RestoreThunkLock( mutex_count ); return retval; }
/*********************************************************************** * LoadLibraryEx32W (KERNEL.513) */ DWORD WINAPI LoadLibraryEx32W16( LPCSTR lpszLibFile, DWORD hFile, DWORD dwFlags ) { HMODULE hModule; DWORD mutex_count; OFSTRUCT ofs; const char *p; if (!lpszLibFile) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } /* if the file cannot be found, call LoadLibraryExA anyway, since it might be a builtin module. This case is handled in MODULE_LoadLibraryExA */ if ((p = strrchr( lpszLibFile, '.' )) && !strchr( p, '\\' )) /* got an extension */ { if (OpenFile16( lpszLibFile, &ofs, OF_EXIST ) != HFILE_ERROR16) lpszLibFile = ofs.szPathName; } else { char buffer[MAX_PATH+4]; strcpy( buffer, lpszLibFile ); strcat( buffer, ".dll" ); if (OpenFile16( buffer, &ofs, OF_EXIST ) != HFILE_ERROR16) lpszLibFile = ofs.szPathName; } ReleaseThunkLock( &mutex_count ); hModule = LoadLibraryExA( lpszLibFile, (HANDLE)hFile, dwFlags ); RestoreThunkLock( mutex_count ); return (DWORD)hModule; }
/*********************************************************************** * main */ int main( int argc, char *argv[] ) { DWORD count; HINSTANCE16 instance; LOADPARAMS16 params; WORD showCmd[2]; char buffer[MAX_PATH]; STARTUPINFOA info; char *cmdline, *appname, **first_arg; char *p; if (!argv[1]) usage(); if (!strcmp( argv[1], "--app-name" )) { if (!(appname = argv[2])) usage(); first_arg = argv + 3; } else { if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL )) { WINE_MESSAGE( "winevdm: unable to exec '%s': file not found\n", argv[1] ); ExitProcess(1); } appname = buffer; first_arg = argv + 1; } if (*first_arg) first_arg++; /* skip program name */ cmdline = build_command_line( first_arg ); if (WINE_TRACE_ON(winevdm)) { int i; WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() ); WINE_TRACE( "appname = '%s'\n", appname ); WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 ); for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] ); } GetStartupInfoA( &info ); showCmd[0] = 2; showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL; params.hEnvironment = 0; params.cmdLine = MapLS( cmdline ); params.showCmd = MapLS( showCmd ); params.reserved = 0; RestoreThunkLock(1); /* grab the Win16 lock */ /* some programs assume mmsystem is always present */ LoadLibrary16( "gdi.exe" ); LoadLibrary16( "user.exe" ); LoadLibrary16( "mmsystem.dll" ); if ((instance = LoadModule16( appname, ¶ms )) < 32) { if (instance == 11) { /* first see if it is a .pif file */ if( ( p = strrchr( appname, '.' )) && !strcasecmp( p, ".pif")) pif_cmd( appname, cmdline + 1); else { /* try DOS format */ /* loader expects arguments to be regular C strings */ start_dos_exe( appname, cmdline + 1 ); } /* if we get back here it failed */ instance = GetLastError(); } WINE_MESSAGE( "winevdm: can't exec '%s': ", appname ); switch (instance) { case 2: WINE_MESSAGE("file not found\n" ); break; case 11: WINE_MESSAGE("invalid program file\n" ); break; default: WINE_MESSAGE("error=%d\n", instance ); break; } ExitProcess(instance); } /* wait forever; the process will be killed when the last task exits */ ReleaseThunkLock( &count ); Sleep( INFINITE ); return 0; }