Started implementing support for the SubSystemTib field in the TEB of
16-bit threads. This allows GetModuleFileNameW to avoid calling 16-bit functions.
This commit is contained in:
parent
d344456adc
commit
fba7149a2d
|
@ -21,6 +21,23 @@
|
|||
#ifndef __WINE_KERNEL_PRIVATE_H
|
||||
#define __WINE_KERNEL_PRIVATE_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
/* The thread information for 16-bit threads */
|
||||
/* NtCurrentTeb()->SubSystemTib points to this */
|
||||
typedef struct
|
||||
{
|
||||
void *unknown; /* 00 unknown */
|
||||
UNICODE_STRING *exe_name; /* 04 exe module name */
|
||||
|
||||
/* the following fields do not exist under Windows */
|
||||
UNICODE_STRING exe_str; /* exe name string pointed to by exe_name */
|
||||
} WIN16_SUBSYSTEM_TIB;
|
||||
|
||||
HANDLE WINAPI OpenConsoleW(LPCWSTR, DWORD, BOOL, DWORD);
|
||||
BOOL WINAPI VerifyConsoleIoHandle(HANDLE);
|
||||
HANDLE WINAPI DuplicateConsoleHandle(HANDLE, DWORD, BOOL, DWORD);
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "winternl.h"
|
||||
#include "thread.h"
|
||||
#include "module.h"
|
||||
#include "kernel_private.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/unicode.h"
|
||||
|
@ -468,35 +469,27 @@ DWORD WINAPI GetModuleFileNameA(
|
|||
DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size )
|
||||
{
|
||||
ULONG magic;
|
||||
LDR_MODULE *pldr;
|
||||
NTSTATUS nts;
|
||||
WIN16_SUBSYSTEM_TIB *win16_tib;
|
||||
|
||||
lpFileName[0] = 0;
|
||||
|
||||
if (!hModule && ((win16_tib = NtCurrentTeb()->Tib.SubSystemTib)) && win16_tib->exe_name)
|
||||
{
|
||||
lstrcpynW( lpFileName, win16_tib->exe_name->Buffer, size );
|
||||
goto done;
|
||||
}
|
||||
|
||||
LdrLockLoaderLock( 0, NULL, &magic );
|
||||
if (!hModule && !(NtCurrentTeb()->tibflags & TEBF_WIN32))
|
||||
{
|
||||
/* 16-bit task - get current NE module name */
|
||||
NE_MODULE *pModule = NE_GetPtr( GetCurrentTask() );
|
||||
if (pModule)
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, path, MAX_PATH );
|
||||
GetLongPathNameW(path, lpFileName, size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LDR_MODULE* pldr;
|
||||
NTSTATUS nts;
|
||||
if (!hModule) hModule = NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||
nts = LdrFindEntryForAddress( hModule, &pldr );
|
||||
if (nts == STATUS_SUCCESS) lstrcpynW(lpFileName, pldr->FullDllName.Buffer, size);
|
||||
else SetLastError( RtlNtStatusToDosError( nts ) );
|
||||
|
||||
if (!hModule) hModule = NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||
nts = LdrFindEntryForAddress( hModule, &pldr );
|
||||
if (nts == STATUS_SUCCESS) lstrcpynW(lpFileName, pldr->FullDllName.Buffer, size);
|
||||
else SetLastError( RtlNtStatusToDosError( nts ) );
|
||||
|
||||
}
|
||||
LdrUnlockLoaderLock( 0, magic );
|
||||
|
||||
done:
|
||||
TRACE( "%s\n", debugstr_w(lpFileName) );
|
||||
return strlenW(lpFileName);
|
||||
}
|
||||
|
|
|
@ -256,11 +256,12 @@ static BOOL TASK_FreeThunk( SEGPTR thunk )
|
|||
* by entering the Win16Lock while linking the task into the
|
||||
* global task list.
|
||||
*/
|
||||
static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cmdline, BYTE len )
|
||||
static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, LPCSTR cmdline, BYTE len )
|
||||
{
|
||||
HTASK16 hTask;
|
||||
TDB *pTask;
|
||||
FARPROC16 proc;
|
||||
char curdir[MAX_PATH];
|
||||
HMODULE16 hModule = pModule ? pModule->self : 0;
|
||||
|
||||
/* Allocate the task structure */
|
||||
|
@ -274,26 +275,16 @@ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cm
|
|||
|
||||
pTask->hSelf = hTask;
|
||||
|
||||
if (teb && teb->tibflags & TEBF_WIN32)
|
||||
{
|
||||
pTask->flags |= TDBF_WIN32;
|
||||
pTask->hInstance = hModule;
|
||||
pTask->hPrevInstance = 0;
|
||||
/* NOTE: for 16-bit tasks, the instance handles are updated later on
|
||||
in NE_InitProcess */
|
||||
}
|
||||
|
||||
pTask->version = pModule ? pModule->expected_version : 0x0400;
|
||||
pTask->hModule = hModule;
|
||||
pTask->hParent = GetCurrentTask();
|
||||
pTask->magic = TDB_MAGIC;
|
||||
pTask->nCmdShow = cmdShow;
|
||||
pTask->teb = teb;
|
||||
pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80;
|
||||
strcpy( pTask->curdir, "\\" );
|
||||
WideCharToMultiByte(CP_ACP, 0, DRIVE_GetDosCwd(DRIVE_GetCurrentDrive()), -1,
|
||||
pTask->curdir + 1, sizeof(pTask->curdir) - 1, NULL, NULL);
|
||||
pTask->curdir[sizeof(pTask->curdir) - 1] = 0; /* ensure 0 termination */
|
||||
|
||||
GetCurrentDirectoryA( sizeof(curdir), curdir );
|
||||
GetShortPathNameA( curdir, curdir, sizeof(curdir) );
|
||||
pTask->curdrive = (curdir[0] - 'A') | 0x80;
|
||||
lstrcpynA( pTask->curdir, curdir + 2, sizeof(pTask->curdir) );
|
||||
|
||||
/* Create the thunks block */
|
||||
|
||||
|
@ -364,9 +355,6 @@ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cm
|
|||
if ( !(pTask->flags & TDBF_WIN32) )
|
||||
NtCreateEvent( &pTask->hEvent, EVENT_ALL_ACCESS, NULL, TRUE, FALSE );
|
||||
|
||||
/* Enter task handle into thread */
|
||||
|
||||
if (teb) teb->htask16 = hTask;
|
||||
if (!initial_task) initial_task = hTask;
|
||||
|
||||
return pTask;
|
||||
|
@ -419,19 +407,41 @@ void TASK_CreateMainTask(void)
|
|||
|
||||
GetStartupInfoA( &startup_info );
|
||||
if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
|
||||
pTask = TASK_Create( NULL, cmdShow, NtCurrentTeb(), NULL, 0 );
|
||||
pTask = TASK_Create( NULL, cmdShow, NULL, 0 );
|
||||
if (!pTask)
|
||||
{
|
||||
ERR("could not create task for main process\n");
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
||||
pTask->flags |= TDBF_WIN32;
|
||||
pTask->hInstance = 0;
|
||||
pTask->hPrevInstance = 0;
|
||||
pTask->teb = NtCurrentTeb();
|
||||
|
||||
NtCurrentTeb()->htask16 = pTask->hSelf;
|
||||
|
||||
/* Add the task to the linked list */
|
||||
/* (no need to get the win16 lock, we are the only thread at this point) */
|
||||
TASK_LinkTask( pTask->hSelf );
|
||||
}
|
||||
|
||||
|
||||
/* allocate the win16 TIB for a new 16-bit task */
|
||||
static WIN16_SUBSYSTEM_TIB *allocate_win16_tib( TDB *pTask )
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
WIN16_SUBSYSTEM_TIB *tib;
|
||||
NE_MODULE *pModule = NE_GetPtr( pTask->hModule );
|
||||
|
||||
if (!(tib = HeapAlloc( GetProcessHeap(), 0, sizeof(*tib) ))) return NULL;
|
||||
MultiByteToWideChar( CP_ACP, 0, NE_MODULE_NAME(pModule), -1, path, MAX_PATH );
|
||||
GetLongPathNameW( path, path, MAX_PATH );
|
||||
if (RtlCreateUnicodeString( &tib->exe_str, path )) tib->exe_name = &tib->exe_str;
|
||||
else tib->exe_name = NULL;
|
||||
return tib;
|
||||
}
|
||||
|
||||
/* startup routine for a new 16-bit thread */
|
||||
static DWORD CALLBACK task_start( TDB *pTask )
|
||||
{
|
||||
|
@ -439,6 +449,7 @@ static DWORD CALLBACK task_start( TDB *pTask )
|
|||
|
||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||
NtCurrentTeb()->htask16 = pTask->hSelf;
|
||||
NtCurrentTeb()->Tib.SubSystemTib = allocate_win16_tib( pTask );
|
||||
|
||||
_EnterWin16Lock();
|
||||
TASK_LinkTask( pTask->hSelf );
|
||||
|
@ -459,7 +470,7 @@ HTASK16 TASK_SpawnTask( NE_MODULE *pModule, WORD cmdShow,
|
|||
{
|
||||
TDB *pTask;
|
||||
|
||||
if (!(pTask = TASK_Create( pModule, cmdShow, NULL, cmdline, len ))) return 0;
|
||||
if (!(pTask = TASK_Create( pModule, cmdShow, cmdline, len ))) return 0;
|
||||
if (!(*hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)task_start, pTask, 0, NULL )))
|
||||
{
|
||||
TASK_DeleteTask( pTask->hSelf );
|
||||
|
|
Loading…
Reference in New Issue