Ignore:
Timestamp:
Jun 18, 2009, 11:53:26 AM (16 years ago)
Author:
ydario
Message:

Kernel32 updates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/thread.cpp

    r10606 r21302  
    3434#include <handlemanager.h>
    3535#include <codepage.h>
    36 #include <heapstring.h>
     36
     37#include "hmhandle.h"
     38#include "hmthread.h"
     39#include <kbdhook.h>
    3740
    3841#include <FastInfoBlocks.h>
     42#include <custombuild.h>
    3943
    4044#define DBG_LOCALLOG    DBG_thread
     
    4549static ULONG priorityclass = NORMAL_PRIORITY_CLASS;
    4650
     51//******************************************************************************
     52//******************************************************************************
     53HANDLE WIN32API CreateThread(LPSECURITY_ATTRIBUTES  lpsa,
     54                             DWORD                  cbStack,
     55                             LPTHREAD_START_ROUTINE lpStartAddr,
     56                             LPVOID                 lpvThreadParm,
     57                             DWORD                  fdwCreate,
     58                             LPDWORD                lpIDThread)
     59{
     60    return HMCreateThread(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread);
     61}
     62/*****************************************************************************
     63 * Name      : HMCreateThread
     64 * Purpose   : router function for CreateThread
     65 * Parameters:
     66 * Variables :
     67 * Result    :
     68 * Remark    :
     69 * Status    :
     70 *
     71 * Author    : SvL
     72 *****************************************************************************/
     73HANDLE HMCreateThread(LPSECURITY_ATTRIBUTES  lpsa,
     74                      DWORD                  cbStack,
     75                      LPTHREAD_START_ROUTINE lpStartAddr,
     76                      LPVOID                 lpvThreadParm,
     77                      DWORD                  fdwCreate,
     78                      LPDWORD                lpIDThread,
     79                      BOOL                   fRegisterThread)
     80{
     81  HMDeviceHandler *pDeviceHandler;         /* device handler for this handle */
     82  PHMHANDLE       pHandle;
     83  HANDLE          rc;                                     /* API return code */
     84
     85  SetLastError(ERROR_SUCCESS);
     86
     87  pHandle = HMHandleGetFreePtr(HMTYPE_THREAD);                         /* get free handle */
     88  if (pHandle == NULL)                            /* oops, no free handles ! */
     89  {
     90    SetLastError(ERROR_NOT_ENOUGH_MEMORY);      /* use this as error message */
     91    return 0; //according to MSDN
     92  }
     93
     94  /* call the device handler */
     95  rc = pHandle->pDeviceHandler->CreateThread(&pHandle->hmHandleData,
     96                                    lpsa,  cbStack, lpStartAddr,
     97                                    lpvThreadParm, fdwCreate, lpIDThread, fRegisterThread);
     98
     99  if (rc == 0)     /* oops, creation failed within the device handler */
     100  {
     101      HMHandleFree(pHandle->hmHandleData.hWin32Handle);
     102      return 0;                                           /* signal error */
     103  }
     104
     105  return pHandle->hmHandleData.hWin32Handle;
     106}
     107/*****************************************************************************
     108 * Name      : HMGetThreadPriority
     109 * Purpose   : router function for GetThreadPriority
     110 * Parameters:
     111 * Variables :
     112 * Result    :
     113 * Remark    :
     114 * Status    :
     115 *
     116 * Author    : SvL
     117 *****************************************************************************/
     118INT WIN32API GetThreadPriority(HANDLE hThread)
     119{
     120  INT       lpResult;                /* result from the device handler's API */
     121  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     122
     123  SetLastError(ERROR_SUCCESS);
     124                                                          /* validate handle */
     125  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     126  if (pHMHandle == NULL)                                     /* error ? */
     127  {
     128    return -1; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     129  }
     130
     131  lpResult = pHMHandle->pDeviceHandler->GetThreadPriority(hThread, &pHMHandle->hmHandleData);
     132
     133  return (lpResult);                                  /* deliver return code */
     134}
     135/*****************************************************************************
     136 * Name      : HMSuspendThread
     137 * Purpose   : router function for SuspendThread
     138 * Parameters:
     139 * Variables :
     140 * Result    :
     141 * Remark    :
     142 * Status    :
     143 *
     144 * Author    : SvL
     145 *****************************************************************************/
     146DWORD WIN32API SuspendThread(HANDLE hThread)
     147{
     148  HANDLE    lpResult;                /* result from the device handler's API */
     149  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     150
     151  SetLastError(ERROR_SUCCESS);
     152                                                         /* validate handle */
     153  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     154  if (pHMHandle == NULL)                                     /* error ? */
     155  {
     156    return -1; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     157  }
     158
     159  lpResult = pHMHandle->pDeviceHandler->SuspendThread(hThread, &pHMHandle->hmHandleData);
     160
     161  return (lpResult);                                  /* deliver return code */
     162}
     163/*****************************************************************************
     164 * Name      : HMSetThreadPriority
     165 * Purpose   : router function for SetThreadPriority
     166 * Parameters:
     167 * Variables :
     168 * Result    :
     169 * Remark    :
     170 * Status    :
     171 *
     172 * Author    : SvL
     173 *****************************************************************************/
     174BOOL WIN32API SetThreadPriority(HANDLE hThread, int priority)
     175{
     176  BOOL      lpResult;                   /* result from the device handler's API */
     177  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     178
     179  SetLastError(ERROR_SUCCESS);
     180                                                          /* validate handle */
     181  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     182  if (pHMHandle == NULL)                                     /* error ? */
     183  {
     184    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     185  }
     186  lpResult = pHMHandle->pDeviceHandler->SetThreadPriority(hThread, &pHMHandle->hmHandleData, priority);
     187
     188  return (lpResult);                                  /* deliver return code */
     189}
     190/*****************************************************************************
     191 * Name      : HMGetThreadContext
     192 * Purpose   : router function for GetThreadContext
     193 * Parameters:
     194 * Variables :
     195 * Result    :
     196 * Remark    :
     197 * Status    :
     198 *
     199 * Author    : SvL
     200 *****************************************************************************/
     201BOOL WIN32API GetThreadContext(HANDLE hThread, CONTEXT *lpContext)
     202{
     203  BOOL      lpResult;                /* result from the device handler's API */
     204  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     205
     206  SetLastError(ERROR_SUCCESS);
     207                                                          /* validate handle */
     208  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     209  if (pHMHandle == NULL)                                     /* error ? */
     210  {
     211    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     212  }
     213
     214  lpResult = pHMHandle->pDeviceHandler->GetThreadContext(hThread, &pHMHandle->hmHandleData, lpContext);
     215
     216  return (lpResult);                                  /* deliver return code */
     217}
     218/*****************************************************************************
     219 * Name      : HMSetThreadContext
     220 * Purpose   : router function for SetThreadContext
     221 * Parameters:
     222 * Variables :
     223 * Result    :
     224 * Remark    :
     225 * Status    :
     226 *
     227 * Author    : SvL
     228 *****************************************************************************/
     229BOOL WIN32API SetThreadContext(HANDLE hThread, const CONTEXT *lpContext)
     230{
     231  BOOL      lpResult;                /* result from the device handler's API */
     232  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     233
     234  SetLastError(ERROR_SUCCESS);
     235                                                          /* validate handle */
     236  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     237  if (pHMHandle == NULL)                                     /* error ? */
     238  {
     239    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     240  }
     241  lpResult = pHMHandle->pDeviceHandler->SetThreadContext(hThread, &pHMHandle->hmHandleData, lpContext);
     242
     243  return (lpResult);                                  /* deliver return code */
     244}
     245/*****************************************************************************
     246 * Name      : HMGetThreadTimes
     247 * Purpose   : router function for HMGetThreadTimes
     248 * Parameters:
     249 * Variables :
     250 * Result    :
     251 * Remark    :
     252 * Status    :
     253 *
     254 * Author    : SvL
     255 *****************************************************************************/
     256BOOL WIN32API GetThreadTimes(HANDLE hThread, LPFILETIME lpCreationTime,
     257                      LPFILETIME lpExitTime, LPFILETIME lpKernelTime,
     258                      LPFILETIME lpUserTime)
     259{
     260  BOOL      lpResult;                /* result from the device handler's API */
     261  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     262
     263  SetLastError(ERROR_SUCCESS);
     264                                                          /* validate handle */
     265  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     266  if (pHMHandle == NULL)                                     /* error ? */
     267  {
     268    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     269  }
     270
     271  lpResult = pHMHandle->pDeviceHandler->GetThreadTimes(hThread, &pHMHandle->hmHandleData,
     272                                                       lpCreationTime, lpExitTime,
     273                                                       lpKernelTime, lpUserTime);
     274
     275  return (lpResult);                                  /* deliver return code */
     276}
     277/*****************************************************************************
     278 * Name      : HMTerminateThread
     279 * Purpose   : router function for TerminateThread
     280 * Parameters:
     281 * Variables :
     282 * Result    :
     283 * Remark    :
     284 * Status    :
     285 *
     286 * Author    : SvL
     287 *****************************************************************************/
     288BOOL WIN32API TerminateThread(HANDLE hThread, DWORD exitcode)
     289{
     290  BOOL      lpResult;                /* result from the device handler's API */
     291  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     292
     293  SetLastError(ERROR_SUCCESS);
     294                                                          /* validate handle */
     295  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     296  if (pHMHandle == NULL)                                     /* error ? */
     297  {
     298    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     299  }
     300
     301  lpResult = pHMHandle->pDeviceHandler->TerminateThread(hThread, &pHMHandle->hmHandleData, exitcode);
     302
     303  return (lpResult);                                  /* deliver return code */
     304}
     305/*****************************************************************************
     306 * Name      : HMResumeThread
     307 * Purpose   : router function for ResumeThread
     308 * Parameters:
     309 * Variables :
     310 * Result    :
     311 * Remark    :
     312 * Status    :
     313 *
     314 * Author    : SvL
     315 *****************************************************************************/
     316DWORD WIN32API ResumeThread(HANDLE hThread)
     317{
     318  DWORD     lpResult;                /* result from the device handler's API */
     319  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     320
     321  SetLastError(ERROR_SUCCESS);
     322                                                 /* validate handle */
     323  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     324  if (pHMHandle == NULL)                                     /* error ? */
     325  {
     326    return -1; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     327  }
     328
     329  lpResult = pHMHandle->pDeviceHandler->ResumeThread(hThread, &pHMHandle->hmHandleData);
     330
     331  return (lpResult);                                  /* deliver return code */
     332}
     333
     334/*****************************************************************************
     335 * Name      : HMGetExitCodeThread
     336 * Purpose   : router function for GetExitCodeThread
     337 * Parameters:
     338 * Variables :
     339 * Result    :
     340 * Remark    :
     341 * Status    :
     342 *
     343 * Author    : SvL
     344 *****************************************************************************/
     345BOOL WIN32API GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode)
     346{
     347  BOOL      lpResult;                /* result from the device handler's API */
     348  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     349
     350  SetLastError(ERROR_SUCCESS);
     351                                                          /* validate handle */
     352  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     353  if (pHMHandle == NULL)                                     /* error ? */
     354  {
     355    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     356  }
     357
     358  lpResult = pHMHandle->pDeviceHandler->GetExitCodeThread(hThread, &pHMHandle->hmHandleData, lpExitCode);
     359
     360  return (lpResult);                                  /* deliver return code */
     361}
     362/*****************************************************************************
     363 * Name      : HMSetThreadTerminated
     364 * Purpose   :
     365 * Parameters:
     366 * Variables :
     367 * Result    :
     368 * Remark    :
     369 * Status    :
     370 *
     371 * Author    : SvL
     372 *****************************************************************************/
     373BOOL HMSetThreadTerminated(HANDLE hThread)
     374{
     375  BOOL      lpResult;                /* result from the device handler's API */
     376  PHMHANDLE pHMHandle;       /* pointer to the handle structure in the table */
     377
     378  SetLastError(ERROR_SUCCESS);
     379                                                          /* validate handle */
     380  pHMHandle = HMHandleQueryPtr(hThread);              /* get the index */
     381  if (pHMHandle == NULL)                                     /* error ? */
     382  {
     383    return FALSE; //last error set by HMHandleQueryPtr (ERROR_INVALID_HANDLE)
     384  }
     385  lpResult = pHMHandle->pDeviceHandler->SetThreadTerminated(hThread, &pHMHandle->hmHandleData);
     386
     387  return (lpResult);                                  /* deliver return code */
     388}
    47389//******************************************************************************
    48390//******************************************************************************
     
    312654    }
    313655}
    314 
    315 #define MQP_INSTANCE_PERMQ              0x00000001 // from os2im.h
    316656//******************************************************************************
    317657//******************************************************************************
     
    320660    EXCEPTION_FRAME  exceptFrame;
    321661    Win32Thread     *me = (Win32Thread *)lpData;
     662    ULONG            dwFlags = me->dwFlags;
    322663    ULONG            threadCallback = (ULONG)me->pCallback;
    323664    LPVOID           userdata  = me->lpUserData;
     
    334675    dprintf(("Win32ThreadProc: Thread handle 0x%x, thread id %d", GetCurrentThread(), GetCurrentThreadId()));
    335676
    336     winteb->flags = me->dwFlags;
     677    winteb->flags = dwFlags;
    337678
    338679    winteb->entry_point = (void *)threadCallback;
     
    343684    winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
    344685    rc = OSLibWinSetCp(winteb->o.odin.hmq, GetDisplayCodepage());
    345     dprintf(("WinSetCP was %sOK(%d, %d)", rc ? "" : "not "));
     686    dprintf(("WinSetCP was %sOK", rc ? "" : "not "));
     687    hookInit(winteb->o.odin.hab);
    346688
    347689    dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
    348690    dprintf(("Stack top 0x%x, stack end 0x%x", winteb->stack_top, winteb->stack_low));
    349 
    350     if( IsDBCSEnv())
    351         /* IM instace is created per message queue, that is, thread */
    352         OSLibImSetMsgQueueProperty( winteb->o.odin.hmq, MQP_INSTANCE_PERMQ );
    353691
    354692    //Note: The Win32 exception structure referenced by FS:[0] is the same
     
    389727    }
    390728    else {
     729        hookKill(winteb->o.odin.hab);
    391730        HMSetThreadTerminated(GetCurrentThread());
    392731        winteb->o.odin.exceptFrame = 0;
     
    416755 * @param   fForceFSSwitch      If set we will force switching to Odin32 FS selector.
    417756 *                              If clear it depends on defaults.
     757 * @deprecated
    418758 */
    419759USHORT WIN32API ODIN_ThreadEnterOdinContext(void *pExceptionRegRec, BOOL fForceFSSwitch)
     
    429769    if (!pTeb)
    430770    {
    431         BOOL fMainThread = fibGetTid() == 1;
    432         HANDLE hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, fMainThread);
    433         pTeb = CreateTEB(hThreadMain, fibGetTid());
    434         if (!pTeb || InitializeThread(pTeb, fMainThread) == FALSE)
     771        HANDLE hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, TRUE);
     772        pTeb = CreateTEB(hThreadMain, ODIN_GetCurrentThreadId());
     773        if (!pTeb || InitializeThread(pTeb, fibGetTid() == 1) == FALSE)
    435774        {
    436775            dprintf(("ODIN_ThreadEnterOdinContext: Failed to create TEB!"));
     
    471810 * @param   fForceFSSwitch      If set we will force switching to Odin32 FS selector.
    472811 *                              If clear it depends on defaults.
     812 * @deprecated
    473813 */
    474814void   WIN32API ODIN_ThreadLeaveOdinContext(void *pExceptionRegRec, USHORT selFSOld)
     
    505845 *                              Must be located on the callers stack.
    506846 * @param   fRemoveOdinExcpt    Remove the odin exception handler.
     847 * @deprecated
    507848 */
    508849USHORT WIN32API ODIN_ThreadLeaveOdinContextNested(void *pExceptionRegRec, BOOL fRemoveOdinExcpt)
     
    551892 * @param   selFSOld            The Odin FS selector returned by the Nested Leave api.
    552893 *
     894 * @deprecated
    553895 */
    554896void   WIN32API ODIN_ThreadEnterOdinContextNested(void *pExceptionRegRec, BOOL fRestoreOdinExcpt, USHORT selFSOld)
     
    578920
    579921
     922/** Save thread context and/or load other thread context.
     923 * @param   pCtx    Where to save the current thread context.
     924 * @param   fFlags  Flags telling what to do.
     925 * @todo Need to do special handling of NESTED flag?
     926 */
     927void    WIN32API ODIN_ThreadContextSave(PODINTHREADCTX pCtx, unsigned fFlags)
     928{
     929    TEB *pTeb = NULL;
     930
     931    /*
     932     * Do requested saves.
     933     */
     934    if (pCtx)
     935    {
     936        memset(pCtx, 0, sizeof(*pCtx));
     937        pCtx->fFlags = fFlags;
     938        if (fFlags & OTCTXF_SAVE_FPU)
     939            pCtx->cw = _control87(0, 0);
     940        if (fFlags & OTCTXF_SAVE_FS)
     941            pCtx->fs = GetFS();
     942    }
     943
     944    /*
     945     * Get Odin32 TEB.
     946     */
     947    if (fFlags & (OTCTXF_LOAD_FS_ODIN32 | OTCTXF_LOAD_XCPT_ODIN32))
     948    {
     949        /*
     950         * Get TEB pointer, create it if necessary.
     951         * @todo    Check if this really is the thread which the TEB was created
     952         *          for. If not create the TEB. This is rather unlikely..
     953         */
     954        pTeb = GetThreadTEB();
     955        if (!pTeb)
     956        {
     957            HANDLE hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, TRUE);
     958            dprintf(("Setup external thread %x!", hThreadMain));
     959            pTeb = CreateTEB(hThreadMain, ODIN_GetCurrentThreadId());
     960            if (!pTeb ||  !InitializeThread(pTeb, fibGetTid() == 1))
     961            {
     962                dprintf(("ODIN_ThreadContextSave: Failed to create TEB!"));
     963                DebugInt3();
     964            }
     965        }
     966    }
     967
     968    /*
     969     * Install exception handler if requested.
     970     */
     971    if (fFlags & OTCTXF_LOAD_XCPT_ODIN32)
     972    {
     973        OS2UnsetExceptionHandler(&pCtx->XctpRegRec);
     974        if (    pTeb
     975            &&  !pTeb->o.odin.exceptFrame)  /* if allready present, we'll keep the first one. */
     976            pTeb->o.odin.exceptFrame = (ULONG)&pCtx->XctpRegRec;
     977    }
     978
     979    /*
     980     * Do requested loads.
     981     */
     982    if (fFlags & OTCTXF_LOAD_FPU_ODIN32)
     983        CONTROL87(0x27F, 0xFFFF);   //Set FPU control word to 0x27F (same as in NT)
     984    if (fFlags & OTCTXF_LOAD_FPU_OS2)
     985        CONTROL87(0x37F, 0xFFFF);   //Set FPU control word to 0x37F as that's most common on OS/2.
     986    if ((fFlags & OTCTXF_LOAD_FS_ODIN32) && pTeb)
     987        SetFS(pTeb->teb_sel);
     988}
     989
     990
     991/** Restore saved thread context and/or do additional loads.
     992 * @param   pCtx    Where to save the current thread context.
     993 * @param   fFlags  Flags telling extra stuff to load.
     994 *                  Only CTCTXF_LOAD_* flags will be evaluated.
     995 * @todo Need to do special handling of NESTED flag?
     996 */
     997void    WIN32API ODIN_ThreadContextRestore(PODINTHREADCTX pCtx, unsigned fFlags)
     998{
     999    /*
     1000     * Restore context.
     1001     */
     1002    if (pCtx)
     1003    {
     1004        if (pCtx->fFlags & OTCTXF_SAVE_FPU)
     1005            CONTROL87(pCtx->cw, 0xffff);
     1006        if (pCtx->fFlags & OTCTXF_SAVE_FS)
     1007            SetFS(pCtx->fs);
     1008        if (pCtx->fFlags & OTCTXF_LOAD_XCPT_ODIN32)
     1009        {
     1010            TEB *pTeb = GetThreadTEB();
     1011            if (pTeb && pTeb->o.odin.exceptFrame == (ULONG)&pCtx->XctpRegRec)
     1012                pTeb->o.odin.exceptFrame = 0;
     1013            OS2UnsetExceptionHandler(&pCtx->XctpRegRec);
     1014        }
     1015        memset(pCtx, 0, sizeof(*pCtx));
     1016    }
     1017
     1018    /*
     1019     * Do requested loads.
     1020     */
     1021    if (fFlags & OTCTXF_LOAD_FPU_ODIN32)
     1022        CONTROL87(0x27F, 0xFFFF);   //Set FPU control word to 0x27F (same as in NT)
     1023    if (fFlags & OTCTXF_LOAD_FPU_OS2)
     1024        CONTROL87(0x37F, 0xFFFF);   //Set FPU control word to 0x37F as that's most common on OS/2.
     1025    if ((fFlags & OTCTXF_LOAD_FS_ODIN32))
     1026    {
     1027        /*
     1028         * Get TEB pointer, create it if necessary.
     1029         * @todo    Check if this really is the thread which the TEB was created
     1030         *          for. If not create the TEB. This is rather unlikely..
     1031         */
     1032        TEB *pTeb = GetThreadTEB();
     1033        if (!pTeb)
     1034        {
     1035            HANDLE hThreadMain = HMCreateThread(NULL, 0, 0, 0, 0, 0, TRUE);
     1036            pTeb = CreateTEB(hThreadMain, ODIN_GetCurrentThreadId());
     1037            if (    !pTeb
     1038                ||  !InitializeThread(pTeb, fibGetTid() == 1))
     1039            {
     1040                dprintf(("ODIN_ThreadContextRestore: Failed to create TEB!"));
     1041                DebugInt3();
     1042            }
     1043        }
     1044        if (pTeb)
     1045            SetFS(pTeb->teb_sel);
     1046    }
     1047}
     1048
Note: See TracChangeset for help on using the changeset viewer.