Re: Win 98 vxd fulle path

From: pesko (psk_NOSPAM_at_mail-online.dk)
Date: 04/07/04


Date: Wed, 7 Apr 2004 20:50:14 +0200

Oh, I found it.
On Windows 98 FE one might use code like (this is a header file)

#ifndef __TIB_INCLUDED__
#define __TIB_INCLUDED__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <basedef.h>
#include <ctype.h>
#include <ifs.h>
#include "vwin32.h"

#ifndef _MAC
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
#else
// some Macintosh compilers don't define wchar_t in a convenient location,
or define it as a char
typedef unsigned short WCHAR; // wc, 16-bit UNICODE character
#endif

typedef WCHAR *PWCHAR;
typedef WCHAR *LPWCH, *PWCH;
typedef CONST WCHAR *LPCWCH, *PCWCH;
typedef WCHAR *NWPSTR;
typedef WCHAR *LPWSTR, *PWSTR;

typedef CONST WCHAR *LPCWSTR, *PCWSTR;

//
// ANSI (Multi-byte Character) types
//
typedef CHAR *PCHAR;
typedef CHAR *LPCH, *PCH;

typedef CONST CHAR *LPCCH, *PCCH;
typedef CHAR *NPSTR;
typedef CHAR *LPSTR, *PSTR;
typedef CONST CHAR *LPCSTR, *PCSTR;
typedef LPWSTR PTSTR, LPTSTR;

//
// Neutral ANSI/UNICODE types and macros
//
#ifdef UNICODE // r_winnt

#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
typedef WCHAR TUCHAR, *PTUCHAR;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */

#define __TEXT(quote) L##quote // r_winnt
typedef LPWSTR LPTCH, PTCH;
typedef LPWSTR PTSTR, LPTSTR;
typedef LPCWSTR LPCTSTR;
typedef LPWSTR LP;
#define __TEXT(quote) L##quote // r_winnt
#else /* UNICODE */ // r_winnt

#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
typedef unsigned char TUCHAR, *PTUCHAR;
#define _TCHAR_DEFINED
#endif /* !_TCHAR_DEFINED */
#endif

//===========================================================
// File: TIB.H
// Author: Matt Pietrek
// From: Microsoft Systems Journal "Under the Hood", May 1996
//===========================================================

#ifndef FARPROC
typedef int (__stdcall *FARPROC)();
#endif

#define MAKELP(sel, off) ((PVOID)MAKELONG((off), (sel)))
#define SELECTOROF(lp) HIWORD(lp)
#define OFFSETOF(lp) LOWORD(lp)

typedef BYTE *LPBYTE;

#pragma pack(push,1)

typedef struct _STARTUPINFOA {
    DWORD cb;
    LPSTR lpReserved;
    LPSTR lpDesktop;
    LPSTR lpTitle;
    DWORD dwX;
    DWORD dwY;
    DWORD dwXSize;
    DWORD dwYSize;
    DWORD dwXCountChars;
    DWORD dwYCountChars;
    DWORD dwFillAttribute;
    DWORD dwFlags;
    WORD wShowWindow;
    WORD cbReserved2;
    LPBYTE lpReserved2;
    HANDLE hStdInput;
    HANDLE hStdOutput;
    HANDLE hStdError;
} STARTUPINFOA, *LPSTARTUPINFOA;

typedef struct TDB //name: K16TDB
{
    WORD TDB_next; //00 next task in dispatch queue
                                // end with 0, where is the first ?
    WORD TDB_taskSP; //02 Saved SS:SP for this task
    WORD TDB_taskSS; //04
    WORD TDB_nEvents; //06 Task event counter
    BYTE TDB_priority; //08 Task priority (0 is highest)
    BYTE TDB_thread_ordinal; //09 ordinal number of this thread
    WORD TDB_thread_next; //0a next thread
    WORD TDB_thread_tdb; //0c the real TDB for this task
    WORD TDB_thread_list; //0e list of allocated thread structures
    WORD TDB_thread_free; //10 free list of available thread
structures
    WORD TDB_thread_count; //12 total count of tread structures
    WORD TDB_FCW; //14 Floating point control word
    WORD TDB_flags; //16 Task flags
    WORD TDB_ErrMode; //18 Error mode for this task
    WORD TDB_ExpWinVer; //1a Expected Windows version for this task
    WORD TDB_HInstance; //1c instance handle of task
    WORD TDB_HMODULE; //1e module database for task
                                // selector ptr to 'NE'
                                // W16Module go
    WORD TDB_Queue; //20 Task Event Queue pointer
    WORD TDB_Parent; //22 TDB of the task that started this up
    WORD TDB_SigAction; //24 Action for app task signal
    FARPROC TDB_ASignalProc; //26 App's signal procedure address
    FARPROC TDB_USignalProc; //2a User's Task Signal procedure address
    FARPROC TDB_GNotifyProc; //2e Task global discard notify proc.
    FARPROC TDB_INTVECS[7]; //32 Task specfic hardware interrupts
    DWORD TDB_CompatFlags; //4e Compatibility flags
    WORD TDB_FS_selector; //52 Same selector as FS (points inside TCB)
    DWORD TDB_ring3_thread_db;//54 32 bit address of KERNEL32 thread
database
                                // Ring3TCB go
    WORD TDB_thunk_stack_ss; //58 selector used for stack during thunking
    WORD TDB_filler[3]; //5a appears to be unused
    WORD TDB_PSP; //60 MSDOS Process Data Block (aka, the PSP)
    LPBYTE TDB_DTA; //62 MSDOS Disk Transfer Address
    BYTE TDB_Drive; //66 MSDOS current drive
    char TDB_Directory[65]; //67 MSDOS current directory
    WORD TDB_Validity; //a8 initial AX to be passed to a task
    WORD TDB_Yield_to; //aa DirectedYield arg stored here
    WORD TDB_LibInitSeg; //ac segment address of libraries to init
    WORD TDB_LibInitOff; //ae MakeProcInstance thunks live here.
    WORD TDB_MPI_Sel; //b0 Code selector for thunks
    WORD TDB_more_thunks; //b2 selector of segment with more MPI
thunks
    WORD TDB_PT_sig; //b4 'PT'
    WORD TDB_unused1; //b6
    WORD TDB_next_MPI_thunk; //b8
    char TDB_MPI_Thunks[0x38]; //ba
    char TDB_ModName[8]; //f2 Name of Module.
    WORD TDB_sig; //fa 'TD' Signature word to detect bogus
code
    DWORD TDB_unused2;
    char TDB_current_directory[0x110]; //100h Current directory
} TDB, *LPTDB;

typedef struct _ENVIRONMENT_DATABASE //why not name EDB
{
    PSTR pszEnvironment; //00h Pointer to Environment
    DWORD un1; //04h
    PSTR pszCmdLine; //08h Pointer to command line
    PSTR pszCurrDirectory; //0Ch Pointer to current directory
    LPSTARTUPINFOA pStartupInfo;//10h Pointer to STARTUPINFOA struct go
    HANDLE hStdIn; //14h Standard Input
    HANDLE hStdOut; //18h Standard Output
    HANDLE hStdErr; //1Ch Standard Error
    DWORD un2; //20h
    DWORD InheritConsole; //24h
    DWORD BreakType; //28h
    DWORD BreakSem; //2Ch
    DWORD BreakEvent; //30h
    DWORD BreakThreadID; //34h
    DWORD BreakHandlers; //38h
} EDB, *PEDB;

typedef struct _HANDLE_TABLE_ENTRY
{
    DWORD flags; // Valid flags depend on what type of object this is
    PVOID pObject; // Pointer to the object that the handle refers to
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;

typedef struct _HANDLE_TABLE
{
    DWORD cEntries; // Max number of handles in table
    HANDLE_TABLE_ENTRY array[1]; // An array (number is given by
cEntries)
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _MODREF
{
    struct MODREF* pNextModRef; //00h
    DWORD un1; //04h number of ?
    DWORD un2; //08h Ring0TCB ?
    DWORD un3; //0Ch
    WORD mteIndex; //10h
    WORD un4; //12h
    DWORD un5; //14h
    PVOID ppdb; //18h Pointer to process database
    DWORD un6; //1Ch
    DWORD un7; //20h
    DWORD un8; //24h
} MODREF, *PMODREF;

#if defined(_M_MRX000) && !(defined(MIDL_PASS) || defined(RC_INVOKED)) &&
defined(ENABLE_RESTRICTED)
#define RESTRICTED_POINTER __restrict
#else
#define RESTRICTED_POINTER
#endif

typedef struct _RTL_CRITICAL_SECTION_DEBUG {
    WORD Type;
    WORD CreatorBackTraceIndex;
    struct _RTL_CRITICAL_SECTION *CriticalSection;
    LIST_ENTRY ProcessLocksList;
    DWORD EntryCount;
    DWORD ContentionCount;
    DWORD Spare[ 2 ];
} RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG,
RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG;

typedef struct _RTL_CRITICAL_SECTION {
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;

    //
    // The following three fields control entering and exiting the critical
    // section for the resource
    //

    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread; // from the thread's ClientId->UniqueThread
    HANDLE LockSemaphore;
    DWORD SpinCount;
} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;

typedef RTL_CRITICAL_SECTION CRITICAL_SECTION;

typedef struct _PROCESS_DATABASE//PDB
{
    DWORD Type; //00h KERNEL32 object type (5)
    DWORD cReference; //04h Number of references to process
    DWORD un1; //08h
    DWORD someEvent; //0Ch An event object (What's it used
for???)
    DWORD TerminationStatus; //10h Returned by GetExitCodeProcess
    DWORD un2; //14h
    DWORD DefaultHeap; //18h Address of the process heap
    DWORD MemoryContext; //1Ch pointer to the process's context goo
    DWORD flags; //20h go
    DWORD pPSP; //24h Linear address of PSP?
    WORD PSPSelector; //28h
    WORD MTEIndex; //2Ah *4+ModuleList=IMTE goo
    WORD cThreads; //2Ch
    WORD cNotTermThreads; //2Eh
    WORD un3; //30h
    WORD cRing0Threads; //32h number of ring 0 threads
    HANDLE HeapHandle; //34h Heap to allocate handle tables out of
                                // This seems to always be the KERNEL32
heap
    DWORD W16TDB; //38h Win16 Task Database selector goo
    DWORD MemMapFiles; //3Ch memory mapped file list (?)
    PEDB pEDB; //40h Pointer to Environment Database go
    PHANDLE_TABLE pHandleTable; //44h Pointer to process handle table
    struct PDB* ParentPDB; //48h Parent process database
    PMODREF MODREFlist; //4Ch Module reference list go
    DWORD ThreadList; //50h Threads in this process
    DWORD DebuggeeCB; //54h Debuggee Context block?
    DWORD LocalHeapFreeHead; //58h Head of free list in process heap
    DWORD InitialRing0ID; //5Ch
    CRITICAL_SECTION crst; //60h defined in winnt.h goo 24h len
           // yes, this structure is 24h len
    DWORD pConsole; //84h Pointer to console for process
    DWORD tlsInUseBits1; //88h // Represents TLS indices 0 - 31
    DWORD tlsInUseBits2; //8Ch // Represents TLS indices 32 - 63
    DWORD ProcessDWORD; //90h
    struct PDB* ProcessGroup; //94h
    DWORD pExeMODREF; //98h pointer to EXE's MODREF
    DWORD TopExcFilter; //9Ch Top Exception Filter?
    DWORD BasePriority; //A0h Base scheduling priority for process
    DWORD HeapOwnList; //A4h Head of the list of process heaps
    DWORD HeapHandleBlockList;//A8h Pointer to head of heap handle block
list
    DWORD pSomeHeapPtr; //ACh normally zero, but can a pointer to a
                                //moveable handle block in the heap
    DWORD pConsoleProvider; //B0h Process that owns the console we're
using?
    WORD EnvironSelector; //B4h Selector containing process
environment
    WORD ErrorMode; //B6H SetErrorMode value (also thunks to
Win16)
    DWORD pevtLoadFinished; //B8h Pointer to event LoadFinished?
    WORD UTState; //BCh
} PDB, *PPDB, PROCESS_DATABASE, *PPROCESS_DATABASE;

#define TDB_FLAGS_WIN32 0x0010
#define TDB_FLAGS_WINOLDAP 0x0001

typedef struct _EXCEPTION_REGISTRATION_RECORD
{
    struct _EXCEPTION_REGISTRATION_RECORD * pNext;
    FARPROC pfnHandler;
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;

typedef struct _TIB
{
    PEXCEPTION_REGISTRATION_RECORD pvExcept; // 00h Head of exception record
list
    PVOID pvStackUserTop; // 04h Top of user stack
    PVOID pvStackUserBase; // 08h Base of user stack

    union // 0Ch (NT/Win95 differences)
    {
        struct // Win95 fields
        {
            WORD pvTDB; // 0Ch TDB
            WORD pvThunkSS; // 0Eh SS selector used for thunking to
16 bits
            DWORD unknown1; // 10h
        } WIN95;

        struct // WinNT fields
        {
            PVOID SubSystemTib; // 0Ch
            ULONG FiberData; // 10h
        } WINNT;
    } TIB_UNION1;

    PVOID pvArbitrary; // 14h Available for application use
    struct _tib *ptibSelf; // 18h Linear address of TIB structure

    union // 1Ch (NT/Win95 differences)
    {
        struct // Win95 fields
        {
            WORD TIBFlags; // 1Ch
            WORD Win16MutexCount; // 1Eh
            DWORD DebugContext; // 20h
            DWORD pCurrentPriority; // 24h
            DWORD pvQueue; // 28h Message Queue selector
        } WIN95;

        struct // WinNT fields
        {
            DWORD unknown1; // 1Ch
            DWORD processID; // 20h
            DWORD threadID; // 24h
            DWORD unknown2; // 28h
        } WINNT;
    } TIB_UNION2;

    PVOID* pvTLSArray; // 2Ch Thread Local Storage array

    union // 30h (NT/Win95 differences)
    {
        struct // Win95 fields
        {
            PVOID* pProcess; // 30h Pointer to owning process database
        } WIN95;
    } TIB_UNION3;

} TIB, *PTIB;

typedef struct _TDBX98 TDBX98;

typedef struct TDB98 {
    WORD Type; // 00 K32 object type
    WORD cReference; // 02 reference count
    DWORD pSomeEvent; // 04 K32 event object used when someone waits on
the thread object
    TIB tib; // 08 thread information block
    PDB* pProcess2; // 40 another pointer to associated PDB
    DWORD Flags; // 44 flags
    DWORD TerminationStatus; // 48 exit code
    WORD TIBSelector; // 4C selector used in FS to point to TIB
    WORD EmulatorSelector; // 4E memory block for saving x87 state
    DWORD cHandles; // 50
    TCB* Ring0Thread; // 54 R0 thread control block
    TDBX98* pTDBX; // 58 R0 thread database extension
    DWORD un1[109]; // 5C
    DWORD APISuspendCount; // 210 Count of SuspendThread's minus
ResumeThread's etc.
} TDB98, *PTDB98;

typedef struct _TDBX98 {
    DWORD un0; // 00
    TDB98* ptdb; // 04 R3 thread database
    PDB* ppdb; // 08 R3 process database
    DWORD ContextHandle; // 0C R0 memory context
    TCB* Ring0Thread; // 10 R0 thread control block
    VOID* WaitNodeList; // 14 Anchor of things we're waiting on
    DWORD WaitFlags; // 18 Blocking flags
    DWORD un1; // 1C
    DWORD TimeOutHandle; // 20
    DWORD WakeParam; // 24
    DWORD BlockHandle; // 28 R0 semaphore on which thread will wait inside
VWIN32
    DWORD BlockState; // 2C
    DWORD SuspendCount; // 30
    DWORD SuspendHandle; // 34
    DWORD MustCompleteCount; // 38 count of EnterMustComplete's minus
LeaveMustComplete's
    DWORD WaitExFlags; // 3C flags
    DWORD SyncWaitCount; // 40
    DWORD QueuedSyncFuncs; // 44
    DWORD UserAPCList; // 48
    DWORD KernAPCList; // 4C
    DWORD pPMPSPSelector; // 50
    DWORD BlockedOnID; // 54
};

typedef struct
{
    WORD sector_offset; // Offset to logical sector
    WORD segment_length; // Size in bytes of segment
    WORD flags; // flags for segment
    WORD alloc_size; // Segment allocation size
    WORD handle; // Global heap handle assigned by loader
} SEGMENT_RECORD, *LPSEGMENT_RECORD;

typedef enum
{ // Segment type constants
  CODE = 0x0000, // Code segment type
  DATA = 0x0001, // Data segment type
} SEGMENT_TYPES;

typedef struct NE //I name it W16Module
{
   WORD ne_signature; //00 'NE'
   WORD ne_usage; //02 reference count of module
   WORD ne_npEntryTable; //04 near pointer to entry table
   WORD ne_npNextExe; //06 next module database
   WORD ne_npAutoData; //08 near pointer to DGROUP segment
entry
   WORD ne_npFileInfo; //0a near pointer to OFSTRUCT with file
name
   WORD ne_flags; //0c
   WORD ne_autodata; //0e segment index of DGROUP segment
   WORD ne_heap; //10
   WORD ne_stack; //12
   DWORD ne_csip; //14
   DWORD ne_sssp; //18
   WORD ne_cseg; //1c
   WORD ne_cModules; //1e
   WORD ne_cbNonResNamesTab; //20
   WORD ne_segtab; //22
   WORD ne_rsrcTab; //24
   WORD ne_resNamesTab; //26 Pascal string of ModuleName
   WORD ne_modRefTab; //28
   WORD ne_importedNamesTab; //2a
   DWORD ne_nonResNamesTab; //2c
   WORD ne_cMovEnt; //30
   WORD ne_align; //32
   WORD ne_cres; //34
   unsigned char ne_exetyp; //36
   unsigned char ne_flagsother; //37
   WORD ne_importedNamesTab2; //38
   WORD ne_importedNamesTab3; //3a
   WORD ne_swaparea; //3c minimum code swap area size
   WORD ne_expver; //3e expected windows version num
   DWORD ne_Win32BaseAddr1; //40 (Win32 only) Base addr of module
   DWORD ne_Win32BaseAddr2; //44 (Win32 only) Base addr of module
   DWORD ne_Win32ResourceAddr; //48 (Win32 only) Base addr of resources
// DWORD ??? //54h
} MODULE, *LPMODULE;

typedef struct
{
    WORD firstEntry;
    WORD lastEntry;
    WORD nextBundle;
} ENTRY_BUNDLE_HEADER, *LPENTRY_BUNDLE_HEADER;

typedef struct
{
    BYTE segType;
    BYTE flags;
    BYTE segNumber;
    WORD offset;
} ENTRY, *LPENTRY;

typedef struct
{
    WORD ID;
    WORD count;
    DWORD function;
} RESOURCE_TYPE, *LPRESOURCE_TYPE;

typedef struct
{
    WORD offset;
    WORD length;

    WORD flags;
    WORD ID;
    WORD handle;
    WORD usage;
} RESOURCE_INFO, *LPRESOURCE_INFO;

#define NEAPPTYP 0x0700 // Application type mask
#define NEWINAPI 0x0300 // Uses windowing API
#define NEWINCOMPAT 0x0200 // Compatible with windowing API
#define NENOTWINCOMPAT 0x0100 // Not compatible with windowing API
#define NENONRES 0x0080 // Contains non-resident code segments
#define NELIM32 0x0010 // Uses LIM 3.2 API
#define NEPROT 0x0008 // Runs in protected mode only
#define NEPPLI 0x0004 // Per-Process Library Initialization

// Target operating systems

#define NE_UNKNOWN 0
#define NE_OS2 1 // Microsoft/IBM OS/2
#define NE_WINDOWS 2 // Microsoft Windows
#define NE_DOS4 3 // Microsoft European MS-DOS 4.x
#define NE_DEV386 4 // Microsoft Windows 386

#define MODFLAGS_DLL 0x8000
#define MODFLAGS_CALL_WEP 0x4000
#define MODFLAGS_SELF_LOADING 0x0800
#define MODFLAGS_APPTYPE 0x0300
                                    // 0x0300 = Uses Windows API
                                    // 0x0200 = Can be run in a window
                                    // 0x0100 = full-screen text app
#define MODFLAGS_IMPLICIT_LOAD 0x0040 // DLL is implicitly loaded
#define MODFLAGS_WIN32 0x0010
#define MODFLAGS_AUTODATA 0x0002
#define MODFLAGS_SINGLEDATA 0x0001

/* APPLIES only to WIN95
typedef struct tagOFSTRUCT_EXT
{
    WORD cBytes; // This is a single BYTE in the regular OFSTRUCT
    BYTE fFixedDisk;
    UINT nErrCode;
    BYTE reserved[4];
    char szPathName[128];
} OFSTRUCT_EXT;
*/

#define OFS_MAXPATHNAME MAX_PATH
typedef struct _OFSTRUCT {
    WORD cBytes;
    BYTE fFixedDisk;
    WORD nErrCode;
    WORD Reserved1;
    WORD Reserved2;
    CHAR szPathName[OFS_MAXPATHNAME];
} OFSTRUCT, *LPOFSTRUCT, *POFSTRUCT;

#pragma pack(pop)

HANDLE VXDINLINE NAKED VWIN32_GetCurrentProcessHandle()
{
    VxDJmp(VWIN32_GetCurrentProcessHandle);
};

PVOID VXDINLINE NAKED SelectorMapFlat(HVM hVMM, DWORD Selector, DWORD Flags)
{
    VMMJmp(_SelectorMapFlat)
}

PCHAR VXDINLINE GetFullPathName()
{
    PPDB lpPDB = (PPDB)VWIN32_GetCurrentProcessHandle();
    LPTDB lpTDB = SelectorMapFlat( Get_Sys_VM_Handle(), lpPDB->W16TDB | 0x7,
0 );
    LPMODULE lpMODULE = SelectorMapFlat( Get_Sys_VM_Handle(),
lpTDB->TDB_HMODULE | 0x7, 0);
    OFSTRUCT* lpofstruct = (OFSTRUCT*)((char*)lpMODULE +
lpMODULE->ne_npFileInfo);

    return lpofstruct->szPathName;
}



Relevant Pages