Changeset 19199


Ignore:
Timestamp:
Jun 11, 2002, 6:36:54 PM (23 years ago)
Author:
sandervl
Message:

thread linking + create TEB before thread creation

Location:
tags/trunk/src/kernel32
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified tags/trunk/src/kernel32/hmthread.cpp

    r19018 r19199  
    1 /* $Id: hmthread.cpp,v 1.12 2002-05-22 12:57:42 sandervl Exp $ */
     1/* $Id: hmthread.cpp,v 1.13 2002-06-11 16:36:53 sandervl Exp $ */
    22
    33/*
     
    4646                                         BOOL                   fFirstThread)
    4747{
    48   Win32Thread *winthread;
    49   DWORD threadid;
    50 
    51   if(lpIDThread == NULL) {
     48    Win32Thread *winthread;
     49    DWORD        threadid;
     50    HANDLE       hThread = pHMHandleData->hHMHandle;
     51
     52    if(lpIDThread == NULL) {
    5253        lpIDThread = &threadid;
    53   }
    54   pHMHandleData->dwInternalType = HMTYPE_THREAD;
    55   pHMHandleData->dwUserData     = THREAD_ALIVE;
    56 
    57   //SvL: This doesn't really create a thread, but only sets up the
    58   //     handle of thread 0
    59   if(fFirstThread) {
    60         pHMHandleData->hHMHandle = O32_GetCurrentThread(); //return Open32 handle of thread
    61         return pHMHandleData->hHMHandle;
    62   }
    63   winthread = new Win32Thread(lpStartAddr, lpvThreadParm, fdwCreate, pHMHandleData->hHMHandle);
    64 
    65   if(winthread == 0) {
    66       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    67       return(0);
    68   }
    69   // @@@PH Note: with debug code enabled, ODIN might request more stack space!
    70   //SvL: Also need more stack in release build (RealPlayer 7 sometimes runs
    71   //     out of stack
    72   if (cbStack > 0)
    73      cbStack <<= 1;     // double stack
    74   else
    75      cbStack = 1048576; // per default 1MB stack per thread
    76 
    77   pHMHandleData->hHMHandle = O32_CreateThread(lpsa,
    78                                               cbStack,
    79                                               winthread->GetOS2Callback(),
    80                                               (LPVOID)winthread,
    81                                               fdwCreate,
    82                                               lpIDThread);
    83 
    84   if(lpIDThread) {
    85       *lpIDThread = MAKE_THREADID(O32_GetCurrentProcessId(), *lpIDThread);
    86   }
    87   dprintf(("CreateThread created %08xh\n", pHMHandleData->hHMHandle));
     54    }
     55    pHMHandleData->dwInternalType = HMTYPE_THREAD;
     56    pHMHandleData->dwUserData     = THREAD_ALIVE;
     57
     58    //SvL: This doesn't really create a thread, but only sets up the
     59    //     handle of thread 0
     60    if(fFirstThread) {
     61            pHMHandleData->hHMHandle = O32_GetCurrentThread(); //return Open32 handle of thread
     62            return pHMHandleData->hHMHandle;
     63    }
     64    winthread = new Win32Thread(lpStartAddr, lpvThreadParm, fdwCreate, hThread);
     65
     66    if(winthread == 0) {
     67        DebugInt3();
     68        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
     69        return(0);
     70    }
     71    // @@@PH Note: with debug code enabled, ODIN might request more stack space!
     72    //SvL: Also need more stack in release build (RealPlayer 7 sometimes runs
     73    //     out of stack
     74    if (cbStack > 0)
     75        cbStack <<= 1;     // double stack
     76    else
     77        cbStack = 1048576; // per default 1MB stack per thread
     78
     79    pHMHandleData->hHMHandle = O32_CreateThread(lpsa, cbStack, winthread->GetOS2Callback(),
     80                                                (LPVOID)winthread, fdwCreate, lpIDThread);
     81
     82    *lpIDThread = MAKE_THREADID(O32_GetCurrentProcessId(), *lpIDThread);
     83   
     84    TEB *teb = GetTEBFromThreadHandle(hThread);
     85    if(teb) {
     86        //store thread id in TEB
     87        teb->o.odin.threadId = *lpIDThread;
     88    }
     89    dprintf(("CreateThread created %08x, id %x", pHMHandleData->hHMHandle, *lpIDThread));
    8890 
    89   return pHMHandleData->hHMHandle;
     91    return pHMHandleData->hHMHandle;
    9092}
    9193//******************************************************************************
  • TabularUnified tags/trunk/src/kernel32/initkernel32.cpp

    r18980 r19199  
    1 /* $Id: initkernel32.cpp,v 1.18 2002-05-16 12:16:00 sandervl Exp $
     1/* $Id: initkernel32.cpp,v 1.19 2002-06-11 16:36:53 sandervl Exp $
    22 *
    33 * KERNEL32 DLL entry point
     
    175175            //(std handles can be used in win32 dll initialization routines
    176176            HMInitialize();             /* store standard handles within HandleManager */
    177             InitDirectories();      //Must be done before InitializeTIB (which loads NTDLL -> USER32)
    178             InitializeTIB(TRUE);        //Must be done after HMInitialize!
     177            InitDirectories();          //Must be done before InitializeTIB (which loads NTDLL -> USER32)
     178            InitializeMainThread();     //Must be done after HMInitialize!
    179179            RegisterDevices();
    180180            Win32DllBase::setDefaultRenaming();
     
    234234    OSLibLVMExit();
    235235
    236     DestroyTIB();
     236    TEB *teb = GetThreadTEB();
     237    if(teb) DestroyTEB(teb);
    237238    DestroySharedHeap();
    238239    DestroyCodeHeap();
  • TabularUnified tags/trunk/src/kernel32/kernel32.def

    r19152 r19199  
    1 ; $Id: kernel32.def,v 1.138 2002-06-08 11:40:13 sandervl Exp $
     1; $Id: kernel32.def,v 1.139 2002-06-11 16:36:53 sandervl Exp $
    22
    33;Basis is Windows95 KERNEL32
     
    11991199    get_char_typeW                                                @2008 NONAME
    12001200
    1201     _InitializeTIB@4                                              @2010 NONAME
    1202     _DestroyTIB@0                                                 @2011 NONAME
    12031201    _GetProcessTIBSel@0                                           @2012 NONAME
    1204     
     1202   
    12051203    _SetRegistryRootKey@8                                         @2013 NONAME
    12061204    _SetCustomBuildName@8                                         @2014 NONAME
  • TabularUnified tags/trunk/src/kernel32/kernel32dbg.def

    r19152 r19199  
    1 ; $Id: kernel32dbg.def,v 1.14 2002-06-08 11:40:14 sandervl Exp $
     1; $Id: kernel32dbg.def,v 1.15 2002-06-11 16:36:53 sandervl Exp $
    22
    33;Basis is Windows95 KERNEL32
     
    11991199    get_char_typeW                                                @2008 NONAME
    12001200
    1201     _InitializeTIB@4                                              @2010 NONAME
    1202     _DestroyTIB@0                                                 @2011 NONAME
    12031201    _GetProcessTIBSel@0                                           @2012 NONAME
    1204     
     1202   
    12051203    _SetRegistryRootKey@8                                         @2013 NONAME
    12061204    _SetCustomBuildName@8                                         @2014 NONAME
  • TabularUnified tags/trunk/src/kernel32/thread.H

    r15653 r19199  
    1 /* $Id: thread.H,v 1.7 2001-02-11 10:34:44 sandervl Exp $ */
     1/* $Id: thread.H,v 1.8 2002-06-11 16:36:54 sandervl Exp $ */
    22
    33/*
     
    2424private:
    2525
    26  LPVOID      lpUserData;
    27  LPTHREAD_START_ROUTINE pCallback;
    28  DWORD       dwFlags;
    29  HANDLE      hThread;
     26    LPVOID      lpUserData;
     27    LPTHREAD_START_ROUTINE pCallback;
     28    DWORD       dwFlags;
     29    HANDLE      hThread;
     30    LPVOID      teb;
    3031
    31  friend DWORD OPEN32API Win32ThreadProc(LPVOID lpData);
     32    friend DWORD OPEN32API Win32ThreadProc(LPVOID lpData);
    3233};
    3334
  • TabularUnified tags/trunk/src/kernel32/thread.cpp

    r19016 r19199  
    1 /* $Id: thread.cpp,v 1.45 2002-05-22 12:57:17 sandervl Exp $ */
     1/* $Id: thread.cpp,v 1.46 2002-06-11 16:36:54 sandervl Exp $ */
    22
    33/*
     
    4545DWORD WIN32API GetCurrentThreadId()
    4646{
    47   // check cached identifier
    48   TEB *teb = GetThreadTEB();
    49   if(teb != NULL && teb->o.odin.threadId != 0xFFFFFFFF)
    50   {
    51     // this is set in InitializeTIB() already.
    52     return teb->o.odin.threadId;
    53   }
     47    // check cached identifier
     48    TEB *teb = GetThreadTEB();
     49    if(teb != NULL && teb->o.odin.threadId != 0xFFFFFFFF)
     50    {
     51        // this is set in InitializeTIB() already.
     52        return teb->o.odin.threadId;
     53    }
    5454 
    5555////  dprintf(("GetCurrentThreadId\n"));
    56   return MAKE_THREADID(O32_GetCurrentProcessId(), O32_GetCurrentThreadId());
     56    return MAKE_THREADID(O32_GetCurrentProcessId(), O32_GetCurrentThreadId());
    5757}
    5858//******************************************************************************
     
    6060HANDLE WIN32API GetCurrentThread()
    6161{
    62  TEB *teb;
     62    TEB *teb;
    6363
    6464    teb = GetThreadTEB();
    6565    if(teb == 0) {
    66         SetLastError(ERROR_INVALID_HANDLE); //todo
    67         return 0;
     66        SetLastError(ERROR_INVALID_HANDLE); //todo
     67        return 0;
    6868    }
    6969    return teb->o.odin.hThread;
     
    188188VOID WIN32API ExitThread(DWORD exitcode)
    189189{
    190  EXCEPTION_FRAME *exceptFrame;
    191  TEB             *teb;
    192 
    193   dprintf(("ExitThread %x (%x)", GetCurrentThread(), exitcode));
    194 
    195   teb = GetThreadTEB();
    196   if(teb != 0) {
    197         exceptFrame = (EXCEPTION_FRAME *)teb->o.odin.exceptFrame;
    198   }
    199   else  DebugInt3();
    200 
    201   HMSetThreadTerminated(GetCurrentThread());
    202   Win32DllBase::detachThreadFromAllDlls();    //send DLL_THREAD_DETACH message to all dlls
    203   Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
    204   if(WinExe)  WinExe->tlsDetachThread();      //destroy TLS structure of main exe
    205   DestroyTIB();
    206 
    207   if(exceptFrame) OS2UnsetExceptionHandler((void *)exceptFrame);
    208 
    209   O32_ExitThread(exitcode);
     190    EXCEPTION_FRAME *exceptFrame;
     191    TEB             *teb;
     192
     193    dprintf(("ExitThread %x (%x)", GetCurrentThread(), exitcode));
     194
     195    teb = GetThreadTEB();
     196    if(teb != 0) {
     197             exceptFrame = (EXCEPTION_FRAME *)teb->o.odin.exceptFrame;
     198    }
     199    else DebugInt3();
     200
     201    HMSetThreadTerminated(GetCurrentThread());
     202    Win32DllBase::detachThreadFromAllDlls();    //send DLL_THREAD_DETACH message to all dlls
     203    Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
     204    if(WinExe)  WinExe->tlsDetachThread();      //destroy TLS structure of main exe
     205
     206    if(teb) DestroyTEB(teb);
     207
     208    if(exceptFrame) OS2UnsetExceptionHandler((void *)exceptFrame);
     209
     210    O32_ExitThread(exitcode);
    210211}
    211212/*****************************************************************************
     
    223224 * Result    : TRUE / FALSE
    224225 * Remark    :
    225  * Status    : UNTESTED STUB
    226  *
    227  * Author    : Patrick Haller [Mon, 1998/06/15 08:00]
     226 * Status    : Fully functional
     227 *
     228 * Author    : SvL
    228229 *****************************************************************************/
    229230
     
    231232                                     DWORD  dwThreadAffinityMask)
    232233{
    233   dprintf(("KERNEL32: SetThreadAffinityMask(%08xh,%08xh)",
    234            hThread, dwThreadAffinityMask));
    235 
    236   if(hThread != GetCurrentThread()) {
    237       dprintf(("WARNING: Setting the affinity mask for another thread than the current one is not supported!!"));
    238       return FALSE;
    239   }
    240   return OSLibDosSetThreadAffinity(dwThreadAffinityMask);
     234    dprintf(("KERNEL32: SetThreadAffinityMask(%08xh,%08xh)", hThread, dwThreadAffinityMask));
     235
     236    if(hThread != GetCurrentThread()) {
     237        dprintf(("WARNING: Setting the affinity mask for another thread than the current one is not supported!!"));
     238        return FALSE;
     239    }
     240    return OSLibDosSetThreadAffinity(dwThreadAffinityMask);
    241241}
    242242//******************************************************************************
     
    268268Win32Thread::Win32Thread(LPTHREAD_START_ROUTINE pUserCallback, LPVOID lpData, DWORD dwFlags, HANDLE hThread)
    269269{
    270   lpUserData = lpData;
    271   pCallback  = pUserCallback;
    272   this->dwFlags = dwFlags;
    273   this->hThread = hThread;
     270    lpUserData = lpData;
     271    pCallback  = pUserCallback;
     272    this->dwFlags = dwFlags;
     273    this->hThread = hThread;
     274
     275    teb = CreateTEB(hThread, 0xFFFFFFFF);
     276    if(teb == NULL) {
     277        DebugInt3();
     278    }
    274279}
    275280//******************************************************************************
     
    277282DWORD OPEN32API Win32ThreadProc(LPVOID lpData)
    278283{
    279  EXCEPTION_FRAME exceptFrame;
    280  Win32Thread     *me = (Win32Thread *)lpData;
    281  ULONG            threadCallback = (ULONG)me->pCallback;
    282  LPVOID           userdata  = me->lpUserData;
    283  HANDLE           hThread   = me->hThread;
    284  DWORD            rc;
    285 
    286   delete(me);    //only called once
    287   dprintf(("Win32ThreadProc %x\n", GetCurrentThreadId()));
    288 
    289   TEB *winteb = (TEB *)InitializeTIB();
    290   if(winteb == NULL) {
    291         dprintf(("Win32ThreadProc: InitializeTIB failed!!"));
    292         DebugInt3();
    293         return 0;
    294   }
    295   winteb->flags = me->dwFlags;
    296 
    297   winteb->entry_point = (void *)threadCallback;
    298   winteb->entry_arg   = (void *)userdata;
    299   winteb->o.odin.hThread = hThread;
    300 
    301   winteb->o.odin.hab = OSLibWinInitialize();
    302   winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
    303   dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
    304 #ifdef DEBUG
    305   TEB *teb = GetThreadTEB();
    306   dprintf(("Stack top 0x%x, stack end 0x%x", teb->stack_top, teb->stack_low));
    307 #endif
    308 
    309   //Note: The Win32 exception structure referenced by FS:[0] is the same
    310   //      in OS/2
    311   OS2SetExceptionHandler((void *)&exceptFrame);
    312   winteb->o.odin.exceptFrame = (ULONG)&exceptFrame;
    313 
    314   //Determine if thread callback is inside a PE dll; if true, then force
    315   //switch to win32 TIB (FS selector)
    316   //(necessary for Opera when loading win32 plugins that create threads)
    317   Win32DllBase *dll;
    318   dll = Win32DllBase::findModuleByAddr(threadCallback);
    319   if(dll && dll->isPEImage()) {
    320        dprintf(("Win32ThreadProc: Force win32 TIB switch"));
    321        SetWin32TIB(TIB_SWITCH_FORCE_WIN32);
    322   }
    323   else SetWin32TIB(TIB_SWITCH_DEFAULT); //executable type determines whether or not FS is changed
    324 
    325   DWORD dwProcessAffinityMask, dwSystemAffinityMask;
    326 
    327   //Change the affinity mask of this thread to the mask for the whole process
    328   if(GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask) == TRUE) {
    329       SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
    330   }
    331 
    332   if(WinExe) WinExe->tlsAttachThread();     //setup TLS structure of main exe
    333   Win32DllBase::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
    334   Win32DllBase::attachThreadToAllDlls();    //send DLL_THREAD_ATTACH message to all dlls
    335 
    336   //Set FPU control word to 0x27F (same as in NT)
    337   CONTROL87(0x27F, 0xFFF);
    338   rc = AsmCallThreadHandler(threadCallback, userdata);
    339 
    340   if(fExitProcess) {
    341       OSLibDosExitThread(rc);
    342   }
    343   else {
    344       HMSetThreadTerminated(GetCurrentThread());
    345       winteb->o.odin.exceptFrame = 0;
    346       Win32DllBase::detachThreadFromAllDlls();  //send DLL_THREAD_DETACH message to all dlls
    347       Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
    348       if(WinExe) WinExe->tlsDetachThread();               //destroy TLS structure of main exe
    349       DestroyTIB();  //destroys TIB and restores FS
    350       OS2UnsetExceptionHandler((void *)&exceptFrame);
    351   }
    352 
    353   return rc;
    354 }
    355 //******************************************************************************
    356 //******************************************************************************
     284    EXCEPTION_FRAME  exceptFrame;
     285    Win32Thread     *me = (Win32Thread *)lpData;
     286    ULONG            threadCallback = (ULONG)me->pCallback;
     287    LPVOID           userdata  = me->lpUserData;
     288    DWORD            rc;
     289    TEB             *winteb    = (TEB *)me->teb;
     290
     291    delete(me);    //only called once
     292
     293    if(InitializeThread(winteb) == FALSE) {
     294            dprintf(("Win32ThreadProc: InitializeTIB failed!!"));
     295            DebugInt3();
     296            return 0;
     297    }
     298    dprintf(("Win32ThreadProc %x\n", GetCurrentThreadId()));
     299
     300    winteb->flags = me->dwFlags;
     301
     302    winteb->entry_point = (void *)threadCallback;
     303    winteb->entry_arg   = (void *)userdata;
     304
     305    winteb->o.odin.hab = OSLibWinInitialize();
     306    winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
     307    dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
     308    dprintf(("Stack top 0x%x, stack end 0x%x", winteb->stack_top, winteb->stack_low));
     309
     310    //Note: The Win32 exception structure referenced by FS:[0] is the same
     311    //      in OS/2
     312    OS2SetExceptionHandler((void *)&exceptFrame);
     313    winteb->o.odin.exceptFrame = (ULONG)&exceptFrame;
     314   
     315    //Determine if thread callback is inside a PE dll; if true, then force
     316    //switch to win32 TIB (FS selector)
     317    //(necessary for Opera when loading win32 plugins that create threads)
     318    Win32DllBase *dll;
     319    dll = Win32DllBase::findModuleByAddr(threadCallback);
     320    if(dll && dll->isPEImage()) {
     321         dprintf(("Win32ThreadProc: Force win32 TIB switch"));
     322         SetWin32TIB(TIB_SWITCH_FORCE_WIN32);
     323    }
     324    else SetWin32TIB(TIB_SWITCH_DEFAULT); //executable type determines whether or not FS is changed
     325
     326    DWORD dwProcessAffinityMask, dwSystemAffinityMask;
     327
     328    //Change the affinity mask of this thread to the mask for the whole process
     329    if(GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask) == TRUE) {
     330        SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
     331    }
     332
     333    if(WinExe) WinExe->tlsAttachThread();           //setup TLS structure of main exe
     334    Win32DllBase::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
     335    Win32DllBase::attachThreadToAllDlls();    //send DLL_THREAD_ATTACH message to all dlls
     336
     337    //Set FPU control word to 0x27F (same as in NT)
     338    CONTROL87(0x27F, 0xFFF);
     339    rc = AsmCallThreadHandler(threadCallback, userdata);
     340
     341    if(fExitProcess) {
     342        OSLibDosExitThread(rc);
     343    }
     344    else {
     345        HMSetThreadTerminated(GetCurrentThread());
     346        winteb->o.odin.exceptFrame = 0;
     347        Win32DllBase::detachThreadFromAllDlls();  //send DLL_THREAD_DETACH message to all dlls
     348        Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
     349        if(WinExe) WinExe->tlsDetachThread();             //destroy TLS structure of main exe
     350        DestroyTEB(winteb);  //destroys TIB and restores FS
     351        OS2UnsetExceptionHandler((void *)&exceptFrame);
     352    }
     353
     354    return rc;
     355}
     356//******************************************************************************
     357//******************************************************************************
  • TabularUnified tags/trunk/src/kernel32/wprocess.cpp

    r19014 r19199  
    1 /* $Id: wprocess.cpp,v 1.152 2002-05-21 12:07:11 sandervl Exp $ */
     1/* $Id: wprocess.cpp,v 1.153 2002-06-11 16:36:54 sandervl Exp $ */
    22
    33/*
     
    137137}
    138138//******************************************************************************
    139 // Set up the TIB selector and memory for the current thread
    140 //******************************************************************************
    141 TEB * WIN32API InitializeTIB(BOOL fMainThread)
    142 {
    143   TEB   *winteb;
    144   ULONG  hThreadMain;
    145   USHORT tibsel;
    146 
    147     //Allocate one dword to store the flat address of our TEB
    148     if(fMainThread) {
    149         dprintf(("InitializeTIB Process handle %x, id %x", GetCurrentProcess(), GetCurrentProcessId()));
    150 
    151         TIBFlatPtr = (DWORD *)OSLibAllocThreadLocalMemory(1);
    152         if(TIBFlatPtr == 0) {
    153             dprintf(("InitializeTIB: local thread memory alloc failed!!"));
    154             DebugInt3();
    155             return NULL;
    156         }
    157         //SvL: This doesn't really create a thread, but only sets up the
    158         //     handle of thread 0
    159         hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, TRUE);
    160     }
     139//Allocate TEB structure for new thread
     140//******************************************************************************
     141TEB *WIN32API CreateTEB(HANDLE hThread, DWORD dwThreadId)
     142{
     143    USHORT tibsel;
     144    TEB   *winteb;
     145
    161146    if(OSLibAllocSel(sizeof(TEB), &tibsel) == FALSE)
    162147    {
     
    173158    }
    174159    memset(winteb, 0, sizeof(TEB));
    175     *TIBFlatPtr = (DWORD)winteb;
     160
     161    threadListMutex.enter();
     162    TEB *teblast   = threadList;
     163    if(!teblast) {
     164        threadList = winteb;
     165        winteb->o.odin.next = NULL;
     166    }
     167    else {
     168        while(teblast->o.odin.next) {
     169            teblast = teblast->o.odin.next;
     170        }
     171        teblast->o.odin.next = winteb;
     172    }
     173    threadListMutex.leave();
    176174
    177175    winteb->except      = (PVOID)-1;               /* 00 Head of exception handling chain */
    178 
    179     winteb->stack_top   = (PVOID)OSLibGetTIB(TIB_STACKTOP); /* 04 Top of thread stack */
    180     winteb->stack_top   = (PVOID)(((ULONG)winteb->stack_top + 0xFFF) & ~0xFFF);
    181     //round to next page (OS/2 doesn't return a nice rounded value)
    182     winteb->stack_low   = (PVOID)OSLibGetTIB(TIB_STACKLOW); /* 08 Stack low-water mark */
    183     //round to page boundary (OS/2 doesn't return a nice rounded value)
    184     winteb->stack_low   = (PVOID)((ULONG)winteb->stack_low & ~0xFFF);
    185176    winteb->htask16     = (USHORT)OSLibGetPIB(PIB_TASKHNDL); /* 0c Win16 task handle */
    186177    winteb->stack_sel   = getSS();                 /* 0e 16-bit stack selector */
     
    190181    winteb->tls_ptr     = &winteb->tls_array[0];   /* 2c Pointer to TLS array */
    191182    winteb->process     = &ProcessPDB;             /* 30 owning process (used by NT3.51 applets)*/
    192    
    193183    winteb->delta_priority  = THREAD_PRIORITY_NORMAL;
    194     winteb->process         = &ProcessPDB;
     184    winteb->process     = &ProcessPDB;
     185
     186    //store selector of new TEB
     187    winteb->teb_sel = tibsel;
     188
     189    winteb->o.odin.hThread  = hThread;
     190    winteb->o.odin.threadId = dwThreadId;
     191
     192    return winteb;
     193}
     194//******************************************************************************
     195// Set up the TIB selector and memory for the main thread
     196//******************************************************************************
     197TEB *WIN32API InitializeMainThread()
     198{
     199    HANDLE hThreadMain;
     200    TEB   *teb;
     201
     202    //Allocate one dword to store the flat address of our TEB
     203    dprintf(("InitializeMainThread Process handle %x, id %x", GetCurrentProcess(), GetCurrentProcessId()));
     204
     205    TIBFlatPtr = (DWORD *)OSLibAllocThreadLocalMemory(1);
     206    if(TIBFlatPtr == 0) {
     207        dprintf(("InitializeTIB: local thread memory alloc failed!!"));
     208        DebugInt3();
     209        return NULL;
     210    }
     211    //SvL: This doesn't really create a thread, but only sets up the
     212    //     handle of thread 0
     213    hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, TRUE);
     214
     215    //create and initialize TEB
     216    teb = CreateTEB(hThreadMain, GetCurrentThreadId());
     217    if(teb == NULL || InitializeThread(teb, TRUE) == FALSE) {
     218        DebugInt3();
     219        return NULL;
     220    }
     221
     222    ProcessTIBSel              = teb->teb_sel;
     223
     224    //todo initialize PDB during process creation
     225    //todo: initialize TLS array if required
     226    //TLS in executable always TLS index 0?
     227////        ProcessPDB.exit_code       = 0x103; /* STILL_ACTIVE */
     228    ProcessPDB.threads         = 1;
     229    ProcessPDB.running_threads = 1;
     230    ProcessPDB.ring0_threads   = 1;
     231    ProcessPDB.system_heap     = GetProcessHeap();
     232    ProcessPDB.parent          = 0;
     233    ProcessPDB.group           = &ProcessPDB;
     234    ProcessPDB.priority        = 8;  /* Normal */
     235    ProcessPDB.heap            = ProcessPDB.system_heap;  /* will be changed later on */
     236    ProcessPDB.next            = NULL;
     237    ProcessPDB.winver          = 0xffff; /* to be determined */
     238    ProcessPDB.server_pid      = (void *)GetCurrentProcessId();
     239    ProcessPDB.tls_bits[0]     = 0; //all tls slots are free
     240    ProcessPDB.tls_bits[1]     = 0;
     241
     242    GetSystemTime(&ProcessPDB.creationTime) ;
     243
     244    /* Initialize the critical section */
     245    InitializeCriticalSection( &ProcessPDB.crit_section );
     246
     247//         ProcessPDB.startup_info    = &StartupInfo;
     248    ProcessPDB.unknown10       = (PVOID)&unknownPDBData[0];
     249    StartupInfo.cb             = sizeof(StartupInfo);
     250    StartupInfo.hStdInput      = GetStdHandle(STD_INPUT_HANDLE);
     251    StartupInfo.hStdOutput     = GetStdHandle(STD_OUTPUT_HANDLE);
     252    StartupInfo.hStdError      = GetStdHandle(STD_ERROR_HANDLE);
     253
     254    return teb;
     255}
     256//******************************************************************************
     257// Set up the TEB structure of the CURRENT (!) thread
     258//******************************************************************************
     259BOOL WIN32API InitializeThread(TEB *winteb, BOOL fMainThread)
     260{
     261    //store TEB address in thread locale memory for easy retrieval
     262    *TIBFlatPtr = (DWORD)winteb;
     263
    195264////    winteb->exit_code       = 0x103; /* STILL_ACTIVE */
    196     winteb->teb_sel         = tibsel;
     265
     266    winteb->stack_top              = (PVOID)OSLibGetTIB(TIB_STACKTOP); /* 04 Top of thread stack */
     267    winteb->stack_top              = (PVOID)(((ULONG)winteb->stack_top + 0xFFF) & ~0xFFF);
     268    //round to next page (OS/2 doesn't return a nice rounded value)
     269    winteb->stack_low              = (PVOID)OSLibGetTIB(TIB_STACKLOW); /* 08 Stack low-water mark */
     270    //round to page boundary (OS/2 doesn't return a nice rounded value)
     271    winteb->stack_low              = (PVOID)((ULONG)winteb->stack_low & ~0xFFF);
     272
    197273    winteb->o.odin.OrgTIBSel       = GetFS();
    198274    winteb->o.odin.pWsockData      = NULL;
    199     winteb->o.odin.threadId        = 0xFFFFFFFF;
    200     winteb->o.odin.threadId        = GetCurrentThreadId();
    201275#ifdef DEBUG
    202276    winteb->o.odin.dbgCallDepth    = 0;
    203277#endif
    204278    winteb->o.odin.pMessageBuffer  = NULL;
    205  
    206     if(fMainThread) {
    207          winteb->o.odin.hThread     = hThreadMain;
    208 //         ProcessPDB.startup_info    = &StartupInfo;
    209          ProcessPDB.unknown10       = (PVOID)&unknownPDBData[0];
    210          StartupInfo.cb             = sizeof(StartupInfo);
    211          StartupInfo.hStdInput      = GetStdHandle(STD_INPUT_HANDLE);
    212          StartupInfo.hStdOutput     = GetStdHandle(STD_OUTPUT_HANDLE);
    213          StartupInfo.hStdError      = GetStdHandle(STD_ERROR_HANDLE);
    214     }
    215     else winteb->o.odin.hThread    = GetCurrentThread();
    216279    winteb->o.odin.lcid            = GetUserDefaultLCID();
    217 
    218     threadListMutex.enter();
    219     TEB *teblast        = threadList;
    220     if(!teblast) {
    221         threadList = winteb;
    222     }
    223     else {
    224         while(teblast->o.odin.next) {
    225             teblast = teblast->o.odin.next;
    226         }
    227         teblast->o.odin.next = winteb;
    228     }
    229     winteb->o.odin.next        = NULL;
    230     threadListMutex.leave();
    231280
    232281    if(OSLibGetPIB(PIB_TASKTYPE) == TASKTYPE_PM)
     
    241290        *(ULONG *)&RtlAllocateAndInitializeSid = (ULONG)GetProcAddress(hInstNTDll, "RtlAllocateAndInitializeSid");
    242291        if(RtlAllocateAndInitializeSid == NULL) {
    243                 DebugInt3();
     292            DebugInt3();
    244293        }
    245294    }
     
    258307 
    259308    if (NULL != RtlAllocateAndInitializeSid) {
    260         RtlAllocateAndInitializeSid(&sidIdAuth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &winteb->o.odin.threadinfo.PrimaryGroup.PrimaryGroup);
     309         RtlAllocateAndInitializeSid(&sidIdAuth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &winteb->o.odin.threadinfo.PrimaryGroup.PrimaryGroup);
    261310    }
    262311    else DebugInt3();
     
    271320    winteb->o.odin.threadinfo.TokenType = TokenPrimary;
    272321
    273     if(fMainThread)
    274     {
    275         //todo initialize PDB during process creation
    276         //todo: initialize TLS array if required
    277         //TLS in executable always TLS index 0?
    278         ProcessTIBSel = tibsel;
    279 ////        ProcessPDB.exit_code       = 0x103; /* STILL_ACTIVE */
    280         ProcessPDB.threads         = 1;
    281         ProcessPDB.running_threads = 1;
    282         ProcessPDB.ring0_threads   = 1;
    283         ProcessPDB.system_heap     = GetProcessHeap();
    284         ProcessPDB.parent          = 0;
    285         ProcessPDB.group           = &ProcessPDB;
    286         ProcessPDB.priority        = 8;  /* Normal */
    287         ProcessPDB.heap            = ProcessPDB.system_heap;  /* will be changed later on */
    288         ProcessPDB.next            = NULL;
    289         ProcessPDB.winver          = 0xffff; /* to be determined */
    290         ProcessPDB.server_pid      = (void *)GetCurrentProcessId();
    291         ProcessPDB.tls_bits[0]     = 0; //all tls slots are free
    292         ProcessPDB.tls_bits[1]     = 0;
    293 
    294         GetSystemTime(&ProcessPDB.creationTime) ;
    295 
    296         /* Initialize the critical section */
    297         InitializeCriticalSection( &ProcessPDB.crit_section );
    298     }
    299     dprintf(("InitializeTIB setup TEB with selector %x", tibsel));
     322    dprintf(("InitializeTIB setup TEB with selector %x", winteb->teb_sel));
    300323    dprintf(("InitializeTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
    301     return winteb;
     324    return TRUE;
     325}
     326//******************************************************************************
     327// Destroy the TIB selector and memory for the current thread
     328//******************************************************************************
     329void WIN32API DestroyTEB(TEB *winteb)
     330{
     331    SHORT orgtibsel;
     332
     333    dprintf(("DestroyTIB: FS     = %x", GetFS()));
     334    dprintf(("DestroyTIB: FS:[0] = %x", QueryExceptionChain()));
     335
     336    orgtibsel = winteb->o.odin.OrgTIBSel;
     337
     338    dprintf(("DestroyTIB: OSLibFreeSel %x", winteb->teb_sel));
     339
     340    threadListMutex.enter();
     341    TEB *curteb        = threadList;
     342    if(curteb == winteb) {
     343        threadList = winteb->o.odin.next;
     344    }
     345    else {
     346        while(curteb->o.odin.next != winteb) {
     347            curteb = curteb->o.odin.next;
     348            if(curteb == NULL) {
     349                dprintf(("DestroyTIB: couldn't find teb %x", winteb));
     350                DebugInt3();
     351                break;
     352            }
     353        }
     354        if(curteb) {
     355            curteb->o.odin.next = winteb->o.odin.next;
     356        }
     357    }
     358    threadListMutex.leave();
     359
     360    // free allocated memory for security structures
     361    free( winteb->o.odin.threadinfo.pTokenGroups );
     362
     363#ifdef DEBUG
     364    if (winteb->o.odin.arrstrCallStack != NULL)
     365        free( winteb->o.odin.arrstrCallStack );
     366#endif
     367
     368    //Restore our original FS selector
     369    SetFS(orgtibsel);
     370
     371    //And free our own
     372    OSLibFreeSel(winteb->teb_sel);
     373
     374    *TIBFlatPtr = 0;
     375
     376    dprintf(("DestroyTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
     377    return;
    302378}
    303379//******************************************************************************
     
    309385    }
    310386    return ProcessTIBSel;
    311 }
    312 //******************************************************************************
    313 // Destroy the TIB selector and memory for the current thread
    314 //******************************************************************************
    315 void WIN32API DestroyTIB()
    316 {
    317  SHORT  orgtibsel;
    318  TEB   *winteb;
    319 
    320     dprintf(("DestroyTIB: FS     = %x", GetFS()));
    321     dprintf(("DestroyTIB: FS:[0] = %x", QueryExceptionChain()));
    322 
    323     winteb = (TEB *)*TIBFlatPtr;
    324     if(winteb) {
    325         orgtibsel = winteb->o.odin.OrgTIBSel;
    326 
    327         dprintf(("DestroyTIB: OSLibFreeSel %x", winteb->teb_sel));
    328 
    329         threadListMutex.enter();
    330         TEB *curteb        = threadList;
    331         if(curteb == winteb) {
    332             threadList = winteb->o.odin.next;
    333         }
    334         else {
    335             while(curteb->o.odin.next != winteb) {
    336                 curteb = curteb->o.odin.next;
    337                 if(curteb == NULL) {
    338                     dprintf(("DestroyTIB: couldn't find teb %x", winteb));
    339                     DebugInt3();
    340                     break;
    341                 }
    342             }
    343             if(curteb) {
    344                 curteb->o.odin.next = winteb->o.odin.next;
    345             }
    346         }
    347         threadListMutex.leave();
    348      
    349         // PH 2002-04-11
    350         // free allocated memory
    351         free( winteb->o.odin.threadinfo.pTokenGroups );
    352      
    353 #ifdef DEBUG
    354         if (winteb->o.odin.arrstrCallStack != NULL)
    355           free( winteb->o.odin.arrstrCallStack );
    356 #endif
    357      
    358         //Restore our original FS selector
    359         SetFS(orgtibsel);
    360 
    361         //And free our own
    362         OSLibFreeSel(winteb->teb_sel);
    363 
    364         *TIBFlatPtr = 0;
    365    }
    366    else dprintf(("Already destroyed TIB"));
    367 
    368    dprintf(("DestroyTIB: FS(%x):[0] = %x", GetFS(), QueryExceptionChain()));
    369    return;
    370387}
    371388/******************************************************************************/
     
    403420USHORT WIN32API SetWin32TIB(BOOL fForceSwitch)
    404421{
    405  SHORT  win32tibsel;
    406  TEB   *winteb;
     422    SHORT  win32tibsel;
     423    TEB   *winteb;
    407424
    408425    //If we're running an Odin32 OS/2 application (not converted!), then we
     
    420437    }
    421438    else {
    422         //we didn't create this thread, so allocate a selector now
    423         //NOTE: Possible memory leak (i.e. DART threads in WINMM)
    424         winteb = InitializeTIB();
    425         if(winteb == NULL) {
    426             DebugInt3();
    427             return GetFS();
    428         }
    429         win32tibsel = winteb->teb_sel;
    430 
    431         //Restore our win32 FS selector
    432         return SetReturnFS(win32tibsel);
     439        return GetFS();
    433440    }
    434441    // nested calls are OK, OS2ToWinCallback for instance
     
    471478 
    472479#ifdef PROFILE
    473   // Note: after this point we do not expect any more Win32-API calls,
    474   // so this is probably the best time to dump the gathered profiling
    475   // information
    476   PerfView_Write();
    477   ProfilerWrite();
    478   ProfilerTerminate();
     480    // Note: after this point we do not expect any more Win32-API calls,
     481    // so this is probably the best time to dump the gathered profiling
     482    // information
     483    PerfView_Write();
     484    ProfilerWrite();
     485    ProfilerTerminate();
    479486#endif /* PROFILE */
    480487 
    481 
    482  
    483488    //Restore original OS/2 TIB selector
    484     DestroyTIB();
     489    teb = GetThreadTEB();
     490    if(teb) DestroyTEB(teb);
    485491    SetExceptionChain((ULONG)-1);
    486492
Note: See TracChangeset for help on using the changeset viewer.