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
|
#ifndef __WINE_KERNEL_PRIVATE_H
|
||||||
#define __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);
|
HANDLE WINAPI OpenConsoleW(LPCWSTR, DWORD, BOOL, DWORD);
|
||||||
BOOL WINAPI VerifyConsoleIoHandle(HANDLE);
|
BOOL WINAPI VerifyConsoleIoHandle(HANDLE);
|
||||||
HANDLE WINAPI DuplicateConsoleHandle(HANDLE, DWORD, BOOL, DWORD);
|
HANDLE WINAPI DuplicateConsoleHandle(HANDLE, DWORD, BOOL, DWORD);
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "winternl.h"
|
#include "winternl.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
#include "kernel_private.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
@ -468,35 +469,27 @@ DWORD WINAPI GetModuleFileNameA(
|
||||||
DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size )
|
DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size )
|
||||||
{
|
{
|
||||||
ULONG magic;
|
ULONG magic;
|
||||||
|
LDR_MODULE *pldr;
|
||||||
|
NTSTATUS nts;
|
||||||
|
WIN16_SUBSYSTEM_TIB *win16_tib;
|
||||||
|
|
||||||
lpFileName[0] = 0;
|
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 );
|
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 );
|
if (!hModule) hModule = NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||||
GetLongPathNameW(path, lpFileName, size);
|
nts = LdrFindEntryForAddress( hModule, &pldr );
|
||||||
}
|
if (nts == STATUS_SUCCESS) lstrcpynW(lpFileName, pldr->FullDllName.Buffer, size);
|
||||||
}
|
else SetLastError( RtlNtStatusToDosError( nts ) );
|
||||||
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 ) );
|
|
||||||
|
|
||||||
}
|
|
||||||
LdrUnlockLoaderLock( 0, magic );
|
LdrUnlockLoaderLock( 0, magic );
|
||||||
|
done:
|
||||||
TRACE( "%s\n", debugstr_w(lpFileName) );
|
TRACE( "%s\n", debugstr_w(lpFileName) );
|
||||||
return strlenW(lpFileName);
|
return strlenW(lpFileName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,11 +256,12 @@ static BOOL TASK_FreeThunk( SEGPTR thunk )
|
||||||
* by entering the Win16Lock while linking the task into the
|
* by entering the Win16Lock while linking the task into the
|
||||||
* global task list.
|
* 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;
|
HTASK16 hTask;
|
||||||
TDB *pTask;
|
TDB *pTask;
|
||||||
FARPROC16 proc;
|
FARPROC16 proc;
|
||||||
|
char curdir[MAX_PATH];
|
||||||
HMODULE16 hModule = pModule ? pModule->self : 0;
|
HMODULE16 hModule = pModule ? pModule->self : 0;
|
||||||
|
|
||||||
/* Allocate the task structure */
|
/* Allocate the task structure */
|
||||||
|
@ -274,26 +275,16 @@ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cm
|
||||||
|
|
||||||
pTask->hSelf = hTask;
|
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->version = pModule ? pModule->expected_version : 0x0400;
|
||||||
pTask->hModule = hModule;
|
pTask->hModule = hModule;
|
||||||
pTask->hParent = GetCurrentTask();
|
pTask->hParent = GetCurrentTask();
|
||||||
pTask->magic = TDB_MAGIC;
|
pTask->magic = TDB_MAGIC;
|
||||||
pTask->nCmdShow = cmdShow;
|
pTask->nCmdShow = cmdShow;
|
||||||
pTask->teb = teb;
|
|
||||||
pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80;
|
GetCurrentDirectoryA( sizeof(curdir), curdir );
|
||||||
strcpy( pTask->curdir, "\\" );
|
GetShortPathNameA( curdir, curdir, sizeof(curdir) );
|
||||||
WideCharToMultiByte(CP_ACP, 0, DRIVE_GetDosCwd(DRIVE_GetCurrentDrive()), -1,
|
pTask->curdrive = (curdir[0] - 'A') | 0x80;
|
||||||
pTask->curdir + 1, sizeof(pTask->curdir) - 1, NULL, NULL);
|
lstrcpynA( pTask->curdir, curdir + 2, sizeof(pTask->curdir) );
|
||||||
pTask->curdir[sizeof(pTask->curdir) - 1] = 0; /* ensure 0 termination */
|
|
||||||
|
|
||||||
/* Create the thunks block */
|
/* 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) )
|
if ( !(pTask->flags & TDBF_WIN32) )
|
||||||
NtCreateEvent( &pTask->hEvent, EVENT_ALL_ACCESS, NULL, TRUE, FALSE );
|
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;
|
if (!initial_task) initial_task = hTask;
|
||||||
|
|
||||||
return pTask;
|
return pTask;
|
||||||
|
@ -419,19 +407,41 @@ void TASK_CreateMainTask(void)
|
||||||
|
|
||||||
GetStartupInfoA( &startup_info );
|
GetStartupInfoA( &startup_info );
|
||||||
if (startup_info.dwFlags & STARTF_USESHOWWINDOW) cmdShow = startup_info.wShowWindow;
|
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)
|
if (!pTask)
|
||||||
{
|
{
|
||||||
ERR("could not create task for main process\n");
|
ERR("could not create task for main process\n");
|
||||||
ExitProcess(1);
|
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 */
|
/* Add the task to the linked list */
|
||||||
/* (no need to get the win16 lock, we are the only thread at this point) */
|
/* (no need to get the win16 lock, we are the only thread at this point) */
|
||||||
TASK_LinkTask( pTask->hSelf );
|
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 */
|
/* startup routine for a new 16-bit thread */
|
||||||
static DWORD CALLBACK task_start( TDB *pTask )
|
static DWORD CALLBACK task_start( TDB *pTask )
|
||||||
{
|
{
|
||||||
|
@ -439,6 +449,7 @@ static DWORD CALLBACK task_start( TDB *pTask )
|
||||||
|
|
||||||
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
NtCurrentTeb()->tibflags &= ~TEBF_WIN32;
|
||||||
NtCurrentTeb()->htask16 = pTask->hSelf;
|
NtCurrentTeb()->htask16 = pTask->hSelf;
|
||||||
|
NtCurrentTeb()->Tib.SubSystemTib = allocate_win16_tib( pTask );
|
||||||
|
|
||||||
_EnterWin16Lock();
|
_EnterWin16Lock();
|
||||||
TASK_LinkTask( pTask->hSelf );
|
TASK_LinkTask( pTask->hSelf );
|
||||||
|
@ -459,7 +470,7 @@ HTASK16 TASK_SpawnTask( NE_MODULE *pModule, WORD cmdShow,
|
||||||
{
|
{
|
||||||
TDB *pTask;
|
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 )))
|
if (!(*hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)task_start, pTask, 0, NULL )))
|
||||||
{
|
{
|
||||||
TASK_DeleteTask( pTask->hSelf );
|
TASK_DeleteTask( pTask->hSelf );
|
||||||
|
|
Loading…
Reference in New Issue