Changeset 21302 for trunk/src/kernel32/thread.cpp
- Timestamp:
- Jun 18, 2009, 11:53:26 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/thread.cpp
r10606 r21302 34 34 #include <handlemanager.h> 35 35 #include <codepage.h> 36 #include <heapstring.h> 36 37 #include "hmhandle.h" 38 #include "hmthread.h" 39 #include <kbdhook.h> 37 40 38 41 #include <FastInfoBlocks.h> 42 #include <custombuild.h> 39 43 40 44 #define DBG_LOCALLOG DBG_thread … … 45 49 static ULONG priorityclass = NORMAL_PRIORITY_CLASS; 46 50 51 //****************************************************************************** 52 //****************************************************************************** 53 HANDLE 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 *****************************************************************************/ 73 HANDLE 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 *****************************************************************************/ 118 INT 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 *****************************************************************************/ 146 DWORD 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 *****************************************************************************/ 174 BOOL 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 *****************************************************************************/ 201 BOOL 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 *****************************************************************************/ 229 BOOL 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 *****************************************************************************/ 256 BOOL 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 *****************************************************************************/ 288 BOOL 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 *****************************************************************************/ 316 DWORD 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 *****************************************************************************/ 345 BOOL 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 *****************************************************************************/ 373 BOOL 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 } 47 389 //****************************************************************************** 48 390 //****************************************************************************** … … 312 654 } 313 655 } 314 315 #define MQP_INSTANCE_PERMQ 0x00000001 // from os2im.h316 656 //****************************************************************************** 317 657 //****************************************************************************** … … 320 660 EXCEPTION_FRAME exceptFrame; 321 661 Win32Thread *me = (Win32Thread *)lpData; 662 ULONG dwFlags = me->dwFlags; 322 663 ULONG threadCallback = (ULONG)me->pCallback; 323 664 LPVOID userdata = me->lpUserData; … … 334 675 dprintf(("Win32ThreadProc: Thread handle 0x%x, thread id %d", GetCurrentThread(), GetCurrentThreadId())); 335 676 336 winteb->flags = me->dwFlags;677 winteb->flags = dwFlags; 337 678 338 679 winteb->entry_point = (void *)threadCallback; … … 343 684 winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab); 344 685 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); 346 688 347 689 dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq)); 348 690 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 );353 691 354 692 //Note: The Win32 exception structure referenced by FS:[0] is the same … … 389 727 } 390 728 else { 729 hookKill(winteb->o.odin.hab); 391 730 HMSetThreadTerminated(GetCurrentThread()); 392 731 winteb->o.odin.exceptFrame = 0; … … 416 755 * @param fForceFSSwitch If set we will force switching to Odin32 FS selector. 417 756 * If clear it depends on defaults. 757 * @deprecated 418 758 */ 419 759 USHORT WIN32API ODIN_ThreadEnterOdinContext(void *pExceptionRegRec, BOOL fForceFSSwitch) … … 429 769 if (!pTeb) 430 770 { 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) 435 774 { 436 775 dprintf(("ODIN_ThreadEnterOdinContext: Failed to create TEB!")); … … 471 810 * @param fForceFSSwitch If set we will force switching to Odin32 FS selector. 472 811 * If clear it depends on defaults. 812 * @deprecated 473 813 */ 474 814 void WIN32API ODIN_ThreadLeaveOdinContext(void *pExceptionRegRec, USHORT selFSOld) … … 505 845 * Must be located on the callers stack. 506 846 * @param fRemoveOdinExcpt Remove the odin exception handler. 847 * @deprecated 507 848 */ 508 849 USHORT WIN32API ODIN_ThreadLeaveOdinContextNested(void *pExceptionRegRec, BOOL fRemoveOdinExcpt) … … 551 892 * @param selFSOld The Odin FS selector returned by the Nested Leave api. 552 893 * 894 * @deprecated 553 895 */ 554 896 void WIN32API ODIN_ThreadEnterOdinContextNested(void *pExceptionRegRec, BOOL fRestoreOdinExcpt, USHORT selFSOld) … … 578 920 579 921 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 */ 927 void 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 */ 997 void 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.