Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 1 | /* |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 2 | * Task functions |
Alexandre Julliard | 234bc24 | 1994-12-10 13:02:28 +0000 | [diff] [blame] | 3 | * |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 4 | * Copyright 1995 Alexandre Julliard |
| 5 | */ |
| 6 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 7 | #include <stdlib.h> |
| 8 | #include <string.h> |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 9 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 10 | #include "windows.h" |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 11 | #include "user.h" |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 12 | #include "callback.h" |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 13 | #include "drive.h" |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 14 | #include "file.h" |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 15 | #include "global.h" |
| 16 | #include "instance.h" |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 17 | #include "message.h" |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 18 | #include "miscemu.h" |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 19 | #include "module.h" |
| 20 | #include "neexe.h" |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 21 | #include "peexe.h" |
| 22 | #include "pe_image.h" |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 23 | #include "process.h" |
Alexandre Julliard | b817f4f | 1996-03-14 18:08:34 +0000 | [diff] [blame] | 24 | #include "queue.h" |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 25 | #include "selectors.h" |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 26 | #include "stackframe.h" |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 27 | #include "task.h" |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 28 | #include "thread.h" |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 29 | #include "toolhelp.h" |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 30 | #include "winnt.h" |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 31 | #include "winsock.h" |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 32 | #include "thread.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 33 | #include "debug.h" |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 34 | #include "dde_proc.h" |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame^] | 35 | #include "server.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame] | 36 | |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 37 | /* Min. number of thunks allocated when creating a new segment */ |
| 38 | #define MIN_THUNKS 32 |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 39 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 40 | /* Pointer to function to switch to a larger stack */ |
| 41 | int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL; |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 42 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame^] | 43 | |
| 44 | static THHOOK DefaultThhook = { 0 }; |
| 45 | THHOOK *pThhook = &DefaultThhook; |
| 46 | |
| 47 | #define hCurrentTask (pThhook->CurTDB) |
| 48 | #define hFirstTask (pThhook->HeadTDB) |
| 49 | #define hLockedTask (pThhook->LockTDB) |
| 50 | |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 51 | static HTASK16 hTaskToKill = 0; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 52 | static UINT16 nTaskCount = 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 53 | |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 54 | static void TASK_YieldToSystem(TDB*); |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 55 | |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame^] | 56 | /*********************************************************************** |
| 57 | * TASK_InstallTHHook |
| 58 | */ |
| 59 | void TASK_InstallTHHook( THHOOK *pNewThhook ) |
| 60 | { |
| 61 | THHOOK *pOldThhook = pThhook; |
| 62 | |
| 63 | pThhook = pNewThhook? pNewThhook : &DefaultThhook; |
| 64 | |
| 65 | *pThhook = *pOldThhook; |
| 66 | } |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 67 | |
| 68 | /*********************************************************************** |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 69 | * TASK_GetNextTask |
| 70 | */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 71 | HTASK16 TASK_GetNextTask( HTASK16 hTask ) |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 72 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 73 | TDB* pTask = (TDB*)GlobalLock16(hTask); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 74 | |
| 75 | if (pTask->hNext) return pTask->hNext; |
| 76 | return (hFirstTask != hTask) ? hFirstTask : 0; |
| 77 | } |
| 78 | |
| 79 | |
| 80 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 81 | * TASK_LinkTask |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 82 | */ |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 83 | static void TASK_LinkTask( HTASK16 hTask ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 84 | { |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 85 | HTASK16 *prevTask; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 86 | TDB *pTask; |
| 87 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 88 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 89 | prevTask = &hFirstTask; |
| 90 | while (*prevTask) |
| 91 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 92 | TDB *prevTaskPtr = (TDB *)GlobalLock16( *prevTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 93 | if (prevTaskPtr->priority >= pTask->priority) break; |
| 94 | prevTask = &prevTaskPtr->hNext; |
| 95 | } |
| 96 | pTask->hNext = *prevTask; |
| 97 | *prevTask = hTask; |
| 98 | nTaskCount++; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 102 | /*********************************************************************** |
| 103 | * TASK_UnlinkTask |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 104 | */ |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 105 | static void TASK_UnlinkTask( HTASK16 hTask ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 106 | { |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 107 | HTASK16 *prevTask; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 108 | TDB *pTask; |
| 109 | |
| 110 | prevTask = &hFirstTask; |
| 111 | while (*prevTask && (*prevTask != hTask)) |
| 112 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 113 | pTask = (TDB *)GlobalLock16( *prevTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 114 | prevTask = &pTask->hNext; |
| 115 | } |
| 116 | if (*prevTask) |
| 117 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 118 | pTask = (TDB *)GlobalLock16( *prevTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 119 | *prevTask = pTask->hNext; |
| 120 | pTask->hNext = 0; |
| 121 | nTaskCount--; |
| 122 | } |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 126 | /*********************************************************************** |
| 127 | * TASK_CreateThunks |
| 128 | * |
| 129 | * Create a thunk free-list in segment 'handle', starting from offset 'offset' |
| 130 | * and containing 'count' entries. |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 131 | */ |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 132 | static void TASK_CreateThunks( HGLOBAL16 handle, WORD offset, WORD count ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 133 | { |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 134 | int i; |
| 135 | WORD free; |
| 136 | THUNKS *pThunk; |
| 137 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 138 | pThunk = (THUNKS *)((BYTE *)GlobalLock16( handle ) + offset); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 139 | pThunk->next = 0; |
| 140 | pThunk->magic = THUNK_MAGIC; |
| 141 | pThunk->free = (int)&pThunk->thunks - (int)pThunk; |
| 142 | free = pThunk->free; |
| 143 | for (i = 0; i < count-1; i++) |
| 144 | { |
| 145 | free += 8; /* Offset of next thunk */ |
| 146 | pThunk->thunks[4*i] = free; |
| 147 | } |
| 148 | pThunk->thunks[4*i] = 0; /* Last thunk */ |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 149 | } |
| 150 | |
| 151 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 152 | /*********************************************************************** |
| 153 | * TASK_AllocThunk |
| 154 | * |
| 155 | * Allocate a thunk for MakeProcInstance(). |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 156 | */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 157 | static SEGPTR TASK_AllocThunk( HTASK16 hTask ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 158 | { |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 159 | TDB *pTask; |
| 160 | THUNKS *pThunk; |
| 161 | WORD sel, base; |
| 162 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 163 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 164 | sel = pTask->hCSAlias; |
| 165 | pThunk = &pTask->thunks; |
| 166 | base = (int)pThunk - (int)pTask; |
| 167 | while (!pThunk->free) |
| 168 | { |
| 169 | sel = pThunk->next; |
| 170 | if (!sel) /* Allocate a new segment */ |
| 171 | { |
| 172 | sel = GLOBAL_Alloc( GMEM_FIXED, sizeof(THUNKS) + (MIN_THUNKS-1)*8, |
| 173 | pTask->hPDB, TRUE, FALSE, FALSE ); |
| 174 | if (!sel) return (SEGPTR)0; |
| 175 | TASK_CreateThunks( sel, 0, MIN_THUNKS ); |
| 176 | pThunk->next = sel; |
| 177 | } |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 178 | pThunk = (THUNKS *)GlobalLock16( sel ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 179 | base = 0; |
| 180 | } |
| 181 | base += pThunk->free; |
| 182 | pThunk->free = *(WORD *)((BYTE *)pThunk + pThunk->free); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 183 | return PTR_SEG_OFF_TO_SEGPTR( sel, base ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 184 | } |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 185 | |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 186 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 187 | /*********************************************************************** |
| 188 | * TASK_FreeThunk |
| 189 | * |
| 190 | * Free a MakeProcInstance() thunk. |
| 191 | */ |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 192 | static BOOL32 TASK_FreeThunk( HTASK16 hTask, SEGPTR thunk ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 193 | { |
| 194 | TDB *pTask; |
| 195 | THUNKS *pThunk; |
| 196 | WORD sel, base; |
| 197 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 198 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 199 | sel = pTask->hCSAlias; |
| 200 | pThunk = &pTask->thunks; |
| 201 | base = (int)pThunk - (int)pTask; |
| 202 | while (sel && (sel != HIWORD(thunk))) |
| 203 | { |
| 204 | sel = pThunk->next; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 205 | pThunk = (THUNKS *)GlobalLock16( sel ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 206 | base = 0; |
| 207 | } |
| 208 | if (!sel) return FALSE; |
| 209 | *(WORD *)((BYTE *)pThunk + LOWORD(thunk) - base) = pThunk->free; |
| 210 | pThunk->free = LOWORD(thunk) - base; |
| 211 | return TRUE; |
| 212 | } |
| 213 | |
| 214 | |
| 215 | /*********************************************************************** |
| 216 | * TASK_CallToStart |
| 217 | * |
| 218 | * 32-bit entry point for a new task. This function is responsible for |
| 219 | * setting up the registers and jumping to the 16-bit entry point. |
| 220 | */ |
| 221 | static void TASK_CallToStart(void) |
| 222 | { |
Alexandre Julliard | b1bac32 | 1996-12-15 19:45:59 +0000 | [diff] [blame] | 223 | int exit_code = 1; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 224 | TDB *pTask = (TDB *)GlobalLock16( hCurrentTask ); |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 225 | NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 226 | SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 227 | |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 228 | SET_CUR_THREAD( pTask->thdb ); |
Alexandre Julliard | 642d313 | 1998-07-12 19:29:36 +0000 | [diff] [blame^] | 229 | CLIENT_InitThread(); |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 230 | /* Terminate the stack frame */ |
| 231 | THREAD_STACK16(pTask->thdb)->frame32 = NULL; |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 232 | if (pModule->flags & NE_FFLAGS_WIN32) |
| 233 | { |
| 234 | /* FIXME: all this is an ugly hack */ |
| 235 | |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 236 | FARPROC32 entry = (FARPROC32)RVA_PTR( PROCESS_Current()->exe_modref->module, OptionalHeader.AddressOfEntryPoint ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 237 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 238 | pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc; |
| 239 | if (pModule->heap_size) |
| 240 | LocalInit( pTask->hInstance, 0, pModule->heap_size ); |
| 241 | |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 242 | InitApp( pTask->hModule ); |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 243 | PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 ); |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 244 | TRACE(relay, "(entryproc=%p)\n", entry ); |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 245 | exit_code = entry(); |
Alexandre Julliard | b1bac32 | 1996-12-15 19:45:59 +0000 | [diff] [blame] | 246 | TASK_KillCurrentTask( exit_code ); |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 247 | } |
| 248 | else |
| 249 | { |
| 250 | /* Registers at initialization must be: |
| 251 | * ax zero |
| 252 | * bx stack size in bytes |
| 253 | * cx heap size in bytes |
| 254 | * si previous app instance |
| 255 | * di current app instance |
| 256 | * bp zero |
| 257 | * es selector to the PSP |
| 258 | * ds dgroup of the application |
| 259 | * ss stack selector |
| 260 | * sp top of the stack |
| 261 | */ |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 262 | CONTEXT context; |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 263 | |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 264 | memset( &context, 0, sizeof(context) ); |
| 265 | CS_reg(&context) = pSegTable[pModule->cs - 1].selector; |
| 266 | DS_reg(&context) = pSegTable[pModule->dgroup - 1].selector; |
| 267 | ES_reg(&context) = pTask->hPDB; |
| 268 | EIP_reg(&context) = pModule->ip; |
| 269 | EBX_reg(&context) = pModule->stack_size; |
| 270 | ECX_reg(&context) = pModule->heap_size; |
| 271 | EDI_reg(&context) = context.SegDs; |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 272 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 273 | TRACE(task, "Starting main program: cs:ip=%04lx:%04x ds=%04lx ss:sp=%04x:%04x\n", |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 274 | CS_reg(&context), IP_reg(&context), DS_reg(&context), |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 275 | SELECTOROF(pTask->thdb->cur_stack), |
| 276 | OFFSETOF(pTask->thdb->cur_stack) ); |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 277 | |
Alexandre Julliard | 44ed71f | 1997-12-21 19:17:50 +0000 | [diff] [blame] | 278 | Callbacks->CallRegisterShortProc( &context, 0 ); |
Alexandre Julliard | b1bac32 | 1996-12-15 19:45:59 +0000 | [diff] [blame] | 279 | /* This should never return */ |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 280 | ERR( task, "Main program returned! (should never happen)\n" ); |
Alexandre Julliard | b1bac32 | 1996-12-15 19:45:59 +0000 | [diff] [blame] | 281 | TASK_KillCurrentTask( 1 ); |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 282 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | |
| 286 | /*********************************************************************** |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 287 | * TASK_Create |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 288 | */ |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 289 | HTASK16 TASK_Create( THDB *thdb, NE_MODULE *pModule, HINSTANCE16 hInstance, |
| 290 | HINSTANCE16 hPrevInstance, UINT16 cmdShow) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 291 | { |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 292 | HTASK16 hTask; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 293 | TDB *pTask; |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 294 | LPSTR cmd_line; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 295 | WORD sp; |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 296 | char *stack32Top; |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 297 | char name[10]; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 298 | STACK16FRAME *frame16; |
| 299 | STACK32FRAME *frame32; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 300 | PDB32 *pdb32 = thdb->process; |
| 301 | SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 302 | |
| 303 | /* Allocate the task structure */ |
| 304 | |
| 305 | hTask = GLOBAL_Alloc( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB), |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 306 | pModule->self, FALSE, FALSE, FALSE ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 307 | if (!hTask) return 0; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 308 | pTask = (TDB *)GlobalLock16( hTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 309 | |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 310 | /* Fill the task structure */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 311 | |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 312 | pTask->nEvents = 1; /* So the task can be started */ |
| 313 | pTask->hSelf = hTask; |
| 314 | pTask->flags = 0; |
Alexandre Julliard | b1bac32 | 1996-12-15 19:45:59 +0000 | [diff] [blame] | 315 | |
| 316 | if (pModule->flags & NE_FFLAGS_WIN32) |
| 317 | pTask->flags |= TDBF_WIN32; |
| 318 | |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 319 | pTask->version = pModule->expected_version; |
| 320 | pTask->hInstance = hInstance; |
| 321 | pTask->hPrevInstance = hPrevInstance; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 322 | pTask->hModule = pModule->self; |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 323 | pTask->hParent = hCurrentTask; |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 324 | pTask->magic = TDB_MAGIC; |
| 325 | pTask->nCmdShow = cmdShow; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 326 | pTask->thdb = thdb; |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 327 | pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80; |
| 328 | strcpy( pTask->curdir, "\\" ); |
| 329 | lstrcpyn32A( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ), |
| 330 | sizeof(pTask->curdir) - 1 ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 331 | |
| 332 | /* Create the thunks block */ |
| 333 | |
| 334 | TASK_CreateThunks( hTask, (int)&pTask->thunks - (int)pTask, 7 ); |
| 335 | |
| 336 | /* Copy the module name */ |
| 337 | |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 338 | GetModuleName( pModule->self, name, sizeof(name) ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 339 | strncpy( pTask->module_name, name, sizeof(pTask->module_name) ); |
| 340 | |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 341 | /* Allocate a selector for the PDB */ |
| 342 | |
| 343 | pTask->hPDB = GLOBAL_CreateBlock( GMEM_FIXED, &pTask->pdb, sizeof(PDB), |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 344 | pModule->self, FALSE, FALSE, FALSE, NULL ); |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 345 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 346 | /* Fill the PDB */ |
| 347 | |
| 348 | pTask->pdb.int20 = 0x20cd; |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 349 | pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */ |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 350 | PUT_DWORD(&pTask->pdb.dispatcher[1], (DWORD)NE_GetEntryPoint( |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 351 | GetModuleHandle16("KERNEL"), 102 )); /* KERNEL.102 is DOS3Call() */ |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 352 | pTask->pdb.savedint22 = INT_GetHandler( 0x22 ); |
| 353 | pTask->pdb.savedint23 = INT_GetHandler( 0x23 ); |
| 354 | pTask->pdb.savedint24 = INT_GetHandler( 0x24 ); |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 355 | pTask->pdb.fileHandlesPtr = |
| 356 | PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(pTask->hPDB), |
| 357 | (int)&((PDB *)0)->fileHandles ); |
Alexandre Julliard | c6c0944 | 1997-01-12 18:32:19 +0000 | [diff] [blame] | 358 | pTask->pdb.hFileHandles = 0; |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 359 | memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) ); |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 360 | pTask->pdb.environment = pdb32->env_db->env_sel; |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 361 | pTask->pdb.nbFiles = 20; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 362 | |
| 363 | /* Fill the command line */ |
| 364 | |
| 365 | cmd_line = pdb32->env_db->cmd_line; |
| 366 | while (*cmd_line && (*cmd_line != ' ') && (*cmd_line != '\t')) cmd_line++; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 367 | while ((*cmd_line == ' ') || (*cmd_line == '\t')) cmd_line++; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 368 | lstrcpyn32A( pTask->pdb.cmdLine+1, cmd_line, sizeof(pTask->pdb.cmdLine)-1); |
| 369 | pTask->pdb.cmdLine[0] = strlen( pTask->pdb.cmdLine + 1 ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 370 | |
| 371 | /* Get the compatibility flags */ |
| 372 | |
Alexandre Julliard | da0cfb3 | 1996-12-01 17:17:47 +0000 | [diff] [blame] | 373 | pTask->compat_flags = GetProfileInt32A( "Compatibility", name, 0 ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 374 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 375 | /* Allocate a code segment alias for the TDB */ |
| 376 | |
| 377 | pTask->hCSAlias = GLOBAL_CreateBlock( GMEM_FIXED, (void *)pTask, |
| 378 | sizeof(TDB), pTask->hPDB, TRUE, |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 379 | FALSE, FALSE, NULL ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 380 | |
| 381 | /* Set the owner of the environment block */ |
| 382 | |
| 383 | FarSetOwner( pTask->pdb.environment, pTask->hPDB ); |
| 384 | |
| 385 | /* Default DTA overwrites command-line */ |
| 386 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 387 | pTask->dta = PTR_SEG_OFF_TO_SEGPTR( pTask->hPDB, |
| 388 | (int)&pTask->pdb.cmdLine - (int)&pTask->pdb ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 389 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 390 | /* Create the 16-bit stack frame */ |
| 391 | |
| 392 | if (!(sp = pModule->sp)) |
| 393 | sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size; |
| 394 | sp &= ~1; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 395 | pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( pTask->hInstance, sp ); |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 396 | pTask->thdb->cur_stack -= sizeof(STACK16FRAME) + sizeof(STACK32FRAME *); |
| 397 | frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack ); |
| 398 | frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp; |
| 399 | frame16->bp = LOWORD(frame16->ebp); |
| 400 | frame16->ds = frame16->es = pTask->hInstance; |
| 401 | frame16->entry_point = 0; |
| 402 | frame16->entry_cs = 0; |
| 403 | /* The remaining fields will be initialized in TASK_Reschedule */ |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 404 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 405 | /* Create the 32-bit stack frame */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 406 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 407 | stack32Top = (char*)pTask->thdb->teb.stack_top; |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 408 | frame16->frame32 = frame32 = (STACK32FRAME *)stack32Top - 1; |
| 409 | frame32->frame16 = pTask->thdb->cur_stack + sizeof(STACK16FRAME); |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 410 | frame32->edi = 0; |
| 411 | frame32->esi = 0; |
| 412 | frame32->edx = 0; |
| 413 | frame32->ecx = 0; |
| 414 | frame32->ebx = 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 415 | frame32->retaddr = (DWORD)TASK_CallToStart; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 416 | /* The remaining fields will be initialized in TASK_Reschedule */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 417 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 418 | if (!THREAD_Current()->cur_stack) |
| 419 | THREAD_Current()->cur_stack = pTask->thdb->cur_stack; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 420 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 421 | /* Add the task to the linked list */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 422 | |
| 423 | TASK_LinkTask( hTask ); |
| 424 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 425 | TRACE(task, "module='%s' cmdline='%s' task=%04x\n", |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 426 | name, cmd_line, hTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 427 | |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 428 | return hTask; |
| 429 | } |
| 430 | |
| 431 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 432 | /*********************************************************************** |
| 433 | * TASK_DeleteTask |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 434 | */ |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 435 | static void TASK_DeleteTask( HTASK16 hTask ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 436 | { |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 437 | TDB *pTask; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 438 | HGLOBAL16 hPDB; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 439 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 440 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 441 | hPDB = pTask->hPDB; |
| 442 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 443 | pTask->magic = 0xdead; /* invalidate signature */ |
| 444 | |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 445 | /* Delete the Win32 part of the task */ |
| 446 | |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 447 | K32OBJ_DecCount( &pTask->thdb->process->header ); |
| 448 | K32OBJ_DecCount( &pTask->thdb->header ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 449 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 450 | /* Free the task module */ |
| 451 | |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 452 | FreeModule16( pTask->hModule ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 453 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 454 | /* Free the selector aliases */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 455 | |
| 456 | GLOBAL_FreeBlock( pTask->hCSAlias ); |
| 457 | GLOBAL_FreeBlock( pTask->hPDB ); |
| 458 | |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 459 | /* Free the task structure itself */ |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 460 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 461 | GlobalFree16( hTask ); |
Alexandre Julliard | 7e56f68 | 1996-01-31 19:02:28 +0000 | [diff] [blame] | 462 | |
| 463 | /* Free all memory used by this task (including the 32-bit stack, */ |
| 464 | /* the environment block and the thunk segments). */ |
| 465 | |
| 466 | GlobalFreeAll( hPDB ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 467 | } |
| 468 | |
| 469 | |
| 470 | /*********************************************************************** |
| 471 | * TASK_KillCurrentTask |
| 472 | * |
| 473 | * Kill the currently running task. As it's not possible to kill the |
| 474 | * current task like this, it is simply marked for destruction, and will |
| 475 | * be killed when either TASK_Reschedule or this function is called again |
| 476 | * in the context of another task. |
| 477 | */ |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 478 | void TASK_KillCurrentTask( INT16 exitCode ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 479 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 480 | TDB* pTask = (TDB*) GlobalLock16( hCurrentTask ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 481 | if (!pTask) USER_ExitWindows(); /* No current task yet */ |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 482 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 483 | TRACE(task, "Killing task %04x\n", hCurrentTask ); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 484 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 485 | /* Delete active sockets */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 486 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 487 | if( pTask->pwsi ) |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 488 | WINSOCK_DeleteTaskWSI( pTask, pTask->pwsi ); |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 489 | |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 490 | /* Perform USER cleanup */ |
| 491 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 492 | if (pTask->userhandler) |
| 493 | pTask->userhandler( hCurrentTask, USIG_TERMINATION, 0, |
| 494 | pTask->hInstance, pTask->hQueue ); |
Alexandre Julliard | 2ace16a | 1996-04-28 15:09:19 +0000 | [diff] [blame] | 495 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 496 | if (hTaskToKill && (hTaskToKill != hCurrentTask)) |
| 497 | { |
| 498 | /* If another task is already marked for destruction, */ |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 499 | /* we can kill it now, as we are in another context. */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 500 | TASK_DeleteTask( hTaskToKill ); |
| 501 | } |
| 502 | |
| 503 | if (nTaskCount <= 1) |
| 504 | { |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 505 | TRACE(task, "this is the last task, exiting\n" ); |
Alexandre Julliard | 889f742 | 1997-04-15 17:19:52 +0000 | [diff] [blame] | 506 | USER_ExitWindows(); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 507 | } |
| 508 | |
| 509 | /* Remove the task from the list to be sure we never switch back to it */ |
| 510 | TASK_UnlinkTask( hCurrentTask ); |
Alexandre Julliard | da0cfb3 | 1996-12-01 17:17:47 +0000 | [diff] [blame] | 511 | if( nTaskCount ) |
| 512 | { |
| 513 | TDB* p = (TDB *)GlobalLock16( hFirstTask ); |
| 514 | while( p ) |
| 515 | { |
| 516 | if( p->hYieldTo == hCurrentTask ) p->hYieldTo = 0; |
| 517 | p = (TDB *)GlobalLock16( p->hNext ); |
| 518 | } |
| 519 | } |
| 520 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 521 | hTaskToKill = hCurrentTask; |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 522 | hLockedTask = 0; |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 523 | |
Alexandre Julliard | da0cfb3 | 1996-12-01 17:17:47 +0000 | [diff] [blame] | 524 | pTask->nEvents = 0; |
| 525 | TASK_YieldToSystem(pTask); |
| 526 | |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 527 | /* We should never return from this Yield() */ |
| 528 | |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 529 | ERR(task,"Return of the living dead %04x!!!\n", hCurrentTask); |
Alexandre Julliard | d471965 | 1995-12-12 18:49:11 +0000 | [diff] [blame] | 530 | exit(1); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 531 | } |
| 532 | |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 533 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 534 | * TASK_Reschedule |
| 535 | * |
| 536 | * This is where all the magic of task-switching happens! |
| 537 | * |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 538 | * Note: This function should only be called via the TASK_YieldToSystem() |
| 539 | * wrapper, to make sure that all the context is saved correctly. |
| 540 | * |
| 541 | * It must not call functions that may yield control. |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 542 | */ |
| 543 | void TASK_Reschedule(void) |
| 544 | { |
| 545 | TDB *pOldTask = NULL, *pNewTask; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 546 | HTASK16 hTask = 0; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 547 | STACK16FRAME *newframe16; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 548 | |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 549 | #ifdef CONFIG_IPC |
Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 550 | dde_reschedule(); |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 551 | #endif |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 552 | /* First check if there's a task to kill */ |
| 553 | |
| 554 | if (hTaskToKill && (hTaskToKill != hCurrentTask)) |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 555 | { |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 556 | TASK_DeleteTask( hTaskToKill ); |
Alexandre Julliard | b7258be | 1995-09-01 15:57:28 +0000 | [diff] [blame] | 557 | hTaskToKill = 0; |
| 558 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 559 | |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 560 | /* Find a task to yield to */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 561 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 562 | pOldTask = (TDB *)GlobalLock16( hCurrentTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 563 | if (pOldTask && pOldTask->hYieldTo) |
| 564 | { |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 565 | /* check for DirectedYield() */ |
| 566 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 567 | hTask = pOldTask->hYieldTo; |
Alexandre Julliard | da0cfb3 | 1996-12-01 17:17:47 +0000 | [diff] [blame] | 568 | pNewTask = (TDB *)GlobalLock16( hTask ); |
| 569 | if( !pNewTask || !pNewTask->nEvents) hTask = 0; |
| 570 | pOldTask->hYieldTo = 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 571 | } |
| 572 | |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 573 | /* extract hardware events only! */ |
| 574 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 575 | if (!hTask) EVENT_WaitNetEvent( FALSE, TRUE ); |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 576 | |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 577 | while (!hTask) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 578 | { |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 579 | /* Find a task that has an event pending */ |
| 580 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 581 | hTask = hFirstTask; |
| 582 | while (hTask) |
| 583 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 584 | pNewTask = (TDB *)GlobalLock16( hTask ); |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 585 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 586 | TRACE(task, "\ttask = %04x, events = %i\n", hTask, pNewTask->nEvents); |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 587 | |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 588 | if (pNewTask->nEvents) break; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 589 | hTask = pNewTask->hNext; |
| 590 | } |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 591 | if (hLockedTask && (hTask != hLockedTask)) hTask = 0; |
| 592 | if (hTask) break; |
| 593 | |
| 594 | /* No task found, wait for some events to come in */ |
| 595 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 596 | EVENT_WaitNetEvent( TRUE, TRUE ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 597 | } |
| 598 | |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 599 | if (hTask == hCurrentTask) |
| 600 | { |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 601 | TRACE(task, "returning to the current task(%04x)\n", hTask ); |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 602 | return; /* Nothing to do */ |
| 603 | } |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 604 | pNewTask = (TDB *)GlobalLock16( hTask ); |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 605 | TRACE(task, "Switching to task %04x (%.8s)\n", |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 606 | hTask, pNewTask->module_name ); |
| 607 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 608 | /* Make the task the last in the linked list (round-robin scheduling) */ |
| 609 | |
| 610 | pNewTask->priority++; |
| 611 | TASK_UnlinkTask( hTask ); |
| 612 | TASK_LinkTask( hTask ); |
| 613 | pNewTask->priority--; |
| 614 | |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 615 | /* Finish initializing the new task stack if necessary */ |
| 616 | |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 617 | newframe16 = THREAD_STACK16( pNewTask->thdb ); |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 618 | if (!newframe16->entry_cs) |
| 619 | { |
| 620 | STACK16FRAME *oldframe16 = CURRENT_STACK16; |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 621 | STACK32FRAME *oldframe32 = oldframe16->frame32; |
| 622 | STACK32FRAME *newframe32 = newframe16->frame32; |
Alexandre Julliard | a0b2b1d | 1997-11-16 17:38:29 +0000 | [diff] [blame] | 623 | newframe16->entry_ip = oldframe16->entry_ip; |
| 624 | newframe16->entry_cs = oldframe16->entry_cs; |
| 625 | newframe16->ip = oldframe16->ip; |
| 626 | newframe16->cs = oldframe16->cs; |
| 627 | newframe32->ebp = oldframe32->ebp; |
| 628 | newframe32->restore_addr = oldframe32->restore_addr; |
| 629 | newframe32->codeselector = oldframe32->codeselector; |
| 630 | } |
| 631 | |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 632 | /* Switch to the new stack */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 633 | |
| 634 | hCurrentTask = hTask; |
Alexandre Julliard | 02e9008 | 1998-01-04 17:49:09 +0000 | [diff] [blame] | 635 | SET_CUR_THREAD( pNewTask->thdb ); |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 636 | pNewTask->ss_sp = pNewTask->thdb->cur_stack; |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 637 | } |
| 638 | |
| 639 | |
| 640 | /*********************************************************************** |
| 641 | * TASK_YieldToSystem |
| 642 | * |
| 643 | * Scheduler interface, this way we ensure that all "unsafe" events are |
| 644 | * processed outside the scheduler. |
| 645 | */ |
| 646 | void TASK_YieldToSystem(TDB* pTask) |
| 647 | { |
| 648 | MESSAGEQUEUE* pQ; |
| 649 | |
Alexandre Julliard | 491502b | 1997-11-01 19:08:16 +0000 | [diff] [blame] | 650 | Callbacks->CallTaskRescheduleProc(); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 651 | |
| 652 | if( pTask ) |
| 653 | { |
| 654 | pQ = (MESSAGEQUEUE*)GlobalLock16(pTask->hQueue); |
Alexandre Julliard | f0cbfa0 | 1997-02-15 14:29:56 +0000 | [diff] [blame] | 655 | if( pQ && pQ->flags & QUEUE_FLAG_XEVENT && |
| 656 | !(pQ->wakeBits & (QS_SENDMESSAGE | QS_SMRESULT)) ) |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 657 | { |
| 658 | pQ->flags &= ~QUEUE_FLAG_XEVENT; |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 659 | EVENT_WaitNetEvent( FALSE, FALSE ); |
Alexandre Julliard | 9ea19e5 | 1997-01-01 17:29:55 +0000 | [diff] [blame] | 660 | } |
| 661 | } |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 662 | } |
| 663 | |
| 664 | |
| 665 | /*********************************************************************** |
| 666 | * InitTask (KERNEL.91) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 667 | * |
| 668 | * Called by the application startup code. |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 669 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 670 | void WINAPI InitTask( CONTEXT *context ) |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 671 | { |
| 672 | TDB *pTask; |
| 673 | NE_MODULE *pModule; |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 674 | SEGTABLEENTRY *pSegTable; |
| 675 | INSTANCEDATA *pinstance; |
| 676 | LONG stacklow, stackhi; |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 677 | |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 678 | if (context) EAX_reg(context) = 0; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 679 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 680 | if (!(pModule = NE_GetPtr( pTask->hModule ))) return; |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 681 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 682 | /* This is a hack to install task USER signal handler before |
| 683 | * implicitly loaded DLLs are initialized (see windows/user.c) */ |
| 684 | |
| 685 | pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc; |
| 686 | |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 687 | /* Initialize implicitly loaded DLLs */ |
Alexandre Julliard | 2787be8 | 1995-05-22 18:23:01 +0000 | [diff] [blame] | 688 | NE_InitializeDLLs( pTask->hModule ); |
| 689 | |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 690 | if (context) |
| 691 | { |
| 692 | /* Registers on return are: |
| 693 | * ax 1 if OK, 0 on error |
| 694 | * cx stack limit in bytes |
| 695 | * dx cmdShow parameter |
| 696 | * si instance handle of the previous instance |
| 697 | * di instance handle of the new task |
| 698 | * es:bx pointer to command-line inside PSP |
| 699 | */ |
| 700 | EAX_reg(context) = 1; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 701 | |
| 702 | if (!pTask->pdb.cmdLine[0]) EBX_reg(context) = 0x80; |
| 703 | else |
| 704 | { |
| 705 | LPBYTE p = &pTask->pdb.cmdLine[1]; |
| 706 | while ((*p == ' ') || (*p == '\t')) p++; |
| 707 | EBX_reg(context) = 0x80 + (p - pTask->pdb.cmdLine); |
| 708 | } |
Alexandre Julliard | 139a4b1 | 1996-11-02 14:24:07 +0000 | [diff] [blame] | 709 | ECX_reg(context) = pModule->stack_size; |
| 710 | EDX_reg(context) = pTask->nCmdShow; |
| 711 | ESI_reg(context) = (DWORD)pTask->hPrevInstance; |
| 712 | EDI_reg(context) = (DWORD)pTask->hInstance; |
| 713 | ES_reg (context) = (WORD)pTask->hPDB; |
| 714 | } |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 715 | |
| 716 | /* Initialize the local heap */ |
| 717 | if ( pModule->heap_size ) |
| 718 | { |
| 719 | LocalInit( pTask->hInstance, 0, pModule->heap_size ); |
| 720 | } |
| 721 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 722 | /* Initialize the INSTANCEDATA structure */ |
| 723 | pSegTable = NE_SEG_TABLE( pModule ); |
| 724 | stacklow = pSegTable[pModule->ss - 1].minsize; |
| 725 | stackhi = stacklow + pModule->stack_size; |
| 726 | if (stackhi > 0xffff) stackhi = 0xffff; |
| 727 | pinstance = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN(CURRENT_DS, 0); |
| 728 | pinstance->stackbottom = stackhi; /* yup, that's right. Confused me too. */ |
| 729 | pinstance->stacktop = stacklow; |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 730 | pinstance->stackmin = OFFSETOF( pTask->thdb->cur_stack ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 731 | } |
| 732 | |
| 733 | |
| 734 | /*********************************************************************** |
| 735 | * WaitEvent (KERNEL.30) |
| 736 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 737 | BOOL16 WINAPI WaitEvent( HTASK16 hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 738 | { |
| 739 | TDB *pTask; |
| 740 | |
| 741 | if (!hTask) hTask = hCurrentTask; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 742 | pTask = (TDB *)GlobalLock16( hTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 743 | if (pTask->nEvents > 0) |
| 744 | { |
| 745 | pTask->nEvents--; |
| 746 | return FALSE; |
| 747 | } |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 748 | TASK_YieldToSystem(pTask); |
| 749 | |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 750 | /* When we get back here, we have an event */ |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 751 | |
Alexandre Julliard | bd34d4f | 1995-06-20 19:08:12 +0000 | [diff] [blame] | 752 | if (pTask->nEvents > 0) pTask->nEvents--; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 753 | return TRUE; |
| 754 | } |
| 755 | |
| 756 | |
| 757 | /*********************************************************************** |
| 758 | * PostEvent (KERNEL.31) |
| 759 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 760 | void WINAPI PostEvent( HTASK16 hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 761 | { |
| 762 | TDB *pTask; |
| 763 | |
| 764 | if (!hTask) hTask = hCurrentTask; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 765 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 766 | pTask->nEvents++; |
| 767 | } |
| 768 | |
| 769 | |
| 770 | /*********************************************************************** |
| 771 | * SetPriority (KERNEL.32) |
| 772 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 773 | void WINAPI SetPriority( HTASK16 hTask, INT16 delta ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 774 | { |
| 775 | TDB *pTask; |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 776 | INT16 newpriority; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 777 | |
| 778 | if (!hTask) hTask = hCurrentTask; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 779 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 780 | newpriority = pTask->priority + delta; |
| 781 | if (newpriority < -32) newpriority = -32; |
| 782 | else if (newpriority > 15) newpriority = 15; |
| 783 | |
| 784 | pTask->priority = newpriority + 1; |
| 785 | TASK_UnlinkTask( hTask ); |
| 786 | TASK_LinkTask( hTask ); |
| 787 | pTask->priority--; |
| 788 | } |
| 789 | |
| 790 | |
| 791 | /*********************************************************************** |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 792 | * LockCurrentTask (KERNEL.33) |
| 793 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 794 | HTASK16 WINAPI LockCurrentTask( BOOL16 bLock ) |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 795 | { |
| 796 | if (bLock) hLockedTask = hCurrentTask; |
| 797 | else hLockedTask = 0; |
| 798 | return hLockedTask; |
| 799 | } |
| 800 | |
| 801 | |
| 802 | /*********************************************************************** |
| 803 | * IsTaskLocked (KERNEL.122) |
| 804 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 805 | HTASK16 WINAPI IsTaskLocked(void) |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 806 | { |
| 807 | return hLockedTask; |
| 808 | } |
| 809 | |
| 810 | |
| 811 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 812 | * OldYield (KERNEL.117) |
| 813 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 814 | void WINAPI OldYield(void) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 815 | { |
| 816 | TDB *pCurTask; |
| 817 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 818 | pCurTask = (TDB *)GlobalLock16( hCurrentTask ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 819 | if (pCurTask) pCurTask->nEvents++; /* Make sure we get back here */ |
Alexandre Julliard | 2c69f6d | 1996-09-28 18:11:01 +0000 | [diff] [blame] | 820 | TASK_YieldToSystem(pCurTask); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 821 | if (pCurTask) pCurTask->nEvents--; |
| 822 | } |
| 823 | |
| 824 | |
| 825 | /*********************************************************************** |
| 826 | * DirectedYield (KERNEL.150) |
| 827 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 828 | void WINAPI DirectedYield( HTASK16 hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 829 | { |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 830 | TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); |
| 831 | pCurTask->hYieldTo = hTask; |
| 832 | OldYield(); |
| 833 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 834 | |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 835 | |
| 836 | /*********************************************************************** |
| 837 | * UserYield (USER.332) |
| 838 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 839 | void WINAPI UserYield(void) |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 840 | { |
| 841 | TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); |
| 842 | MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue ); |
| 843 | /* Handle sent messages */ |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 844 | while (queue && (queue->wakeBits & QS_SENDMESSAGE)) |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 845 | QUEUE_ReceiveMessage( queue ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 846 | |
| 847 | OldYield(); |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 848 | |
| 849 | queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue ); |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 850 | while (queue && (queue->wakeBits & QS_SENDMESSAGE)) |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 851 | QUEUE_ReceiveMessage( queue ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 852 | } |
| 853 | |
| 854 | |
| 855 | /*********************************************************************** |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 856 | * Yield16 (KERNEL.29) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 857 | */ |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 858 | void WINAPI Yield16(void) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 859 | { |
Alexandre Julliard | ef702d8 | 1996-05-28 18:54:58 +0000 | [diff] [blame] | 860 | TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask ); |
| 861 | if (pCurTask) pCurTask->hYieldTo = 0; |
| 862 | if (pCurTask && pCurTask->hQueue) UserYield(); |
| 863 | else OldYield(); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 864 | } |
| 865 | |
| 866 | |
| 867 | /*********************************************************************** |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 868 | * MakeProcInstance16 (KERNEL.51) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 869 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 870 | FARPROC16 WINAPI MakeProcInstance16( FARPROC16 func, HANDLE16 hInstance ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 871 | { |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 872 | BYTE *thunk,*lfunc; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 873 | SEGPTR thunkaddr; |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 874 | |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 875 | if (!hInstance) hInstance = CURRENT_DS; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 876 | thunkaddr = TASK_AllocThunk( hCurrentTask ); |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 877 | if (!thunkaddr) return (FARPROC16)0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 878 | thunk = PTR_SEG_TO_LIN( thunkaddr ); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 879 | lfunc = PTR_SEG_TO_LIN( func ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 880 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 881 | TRACE(task, "(%08lx,%04x): got thunk %08lx\n", |
Alexandre Julliard | 59730ae | 1996-03-24 16:20:51 +0000 | [diff] [blame] | 882 | (DWORD)func, hInstance, (DWORD)thunkaddr ); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 883 | if (((lfunc[0]==0x8c) && (lfunc[1]==0xd8)) || |
| 884 | ((lfunc[0]==0x1e) && (lfunc[1]==0x58)) |
| 885 | ) { |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 886 | FIXME(task,"thunk would be useless for %p, overwriting with nop;nop;\n", func ); |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 887 | lfunc[0]=0x90; /* nop */ |
| 888 | lfunc[1]=0x90; /* nop */ |
| 889 | } |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 890 | |
| 891 | *thunk++ = 0xb8; /* movw instance, %ax */ |
| 892 | *thunk++ = (BYTE)(hInstance & 0xff); |
| 893 | *thunk++ = (BYTE)(hInstance >> 8); |
| 894 | *thunk++ = 0xea; /* ljmp func */ |
| 895 | *(DWORD *)thunk = (DWORD)func; |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 896 | return (FARPROC16)thunkaddr; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 897 | } |
| 898 | |
| 899 | |
| 900 | /*********************************************************************** |
Alexandre Julliard | 3051b64 | 1996-07-05 17:14:13 +0000 | [diff] [blame] | 901 | * FreeProcInstance16 (KERNEL.52) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 902 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 903 | void WINAPI FreeProcInstance16( FARPROC16 func ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 904 | { |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 905 | TRACE(task, "(%08lx)\n", (DWORD)func ); |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 906 | TASK_FreeThunk( hCurrentTask, (SEGPTR)func ); |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 907 | } |
| 908 | |
| 909 | |
| 910 | /********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 911 | * GetCodeHandle (KERNEL.93) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 912 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 913 | HANDLE16 WINAPI GetCodeHandle( FARPROC16 proc ) |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 914 | { |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 915 | HANDLE16 handle; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 916 | BYTE *thunk = (BYTE *)PTR_SEG_TO_LIN( proc ); |
| 917 | |
| 918 | /* Return the code segment containing 'proc'. */ |
| 919 | /* Not sure if this is really correct (shouldn't matter that much). */ |
| 920 | |
| 921 | /* Check if it is really a thunk */ |
| 922 | if ((thunk[0] == 0xb8) && (thunk[3] == 0xea)) |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 923 | handle = GlobalHandle16( thunk[6] + (thunk[7] << 8) ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 924 | else |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 925 | handle = GlobalHandle16( HIWORD(proc) ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 926 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 927 | return handle; |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 928 | } |
| 929 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 930 | |
Alexandre Julliard | e658d82 | 1997-11-30 17:45:40 +0000 | [diff] [blame] | 931 | /********************************************************************** |
| 932 | * DefineHandleTable16 (KERNEL.94) |
| 933 | */ |
| 934 | BOOL16 WINAPI DefineHandleTable16( WORD wOffset ) |
| 935 | { |
| 936 | return TRUE; /* FIXME */ |
| 937 | } |
| 938 | |
| 939 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 940 | /*********************************************************************** |
| 941 | * SetTaskQueue (KERNEL.34) |
| 942 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 943 | HQUEUE16 WINAPI SetTaskQueue( HTASK16 hTask, HQUEUE16 hQueue ) |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 944 | { |
Alexandre Julliard | 8cc3a5e | 1996-08-11 15:49:51 +0000 | [diff] [blame] | 945 | HQUEUE16 hPrev; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 946 | TDB *pTask; |
| 947 | |
| 948 | if (!hTask) hTask = hCurrentTask; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 949 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame] | 950 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 951 | hPrev = pTask->hQueue; |
| 952 | pTask->hQueue = hQueue; |
Alexandre Julliard | c981d0b | 1996-03-31 16:40:13 +0000 | [diff] [blame] | 953 | |
| 954 | TIMER_SwitchQueue( hPrev, hQueue ); |
| 955 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 956 | return hPrev; |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 957 | } |
| 958 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 959 | |
| 960 | /*********************************************************************** |
| 961 | * GetTaskQueue (KERNEL.35) |
| 962 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 963 | HQUEUE16 WINAPI GetTaskQueue( HTASK16 hTask ) |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 964 | { |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 965 | TDB *pTask; |
| 966 | |
| 967 | if (!hTask) hTask = hCurrentTask; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 968 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 969 | return pTask->hQueue; |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 970 | } |
| 971 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 972 | |
| 973 | /*********************************************************************** |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 974 | * SwitchStackTo (KERNEL.108) |
| 975 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 976 | void WINAPI SwitchStackTo( WORD seg, WORD ptr, WORD top ) |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 977 | { |
| 978 | TDB *pTask; |
| 979 | STACK16FRAME *oldFrame, *newFrame; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 980 | INSTANCEDATA *pData; |
| 981 | UINT16 copySize; |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 982 | |
| 983 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 984 | if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return; |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 985 | TRACE(task, "old=%04x:%04x new=%04x:%04x\n", |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 986 | SELECTOROF( pTask->thdb->cur_stack ), |
| 987 | OFFSETOF( pTask->thdb->cur_stack ), seg, ptr ); |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 988 | |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 989 | /* Save the old stack */ |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 990 | |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 991 | oldFrame = THREAD_STACK16( pTask->thdb ); |
| 992 | /* pop frame + args and push bp */ |
| 993 | pData->old_ss_sp = pTask->thdb->cur_stack - sizeof(STACK16FRAME) |
| 994 | - 2 * sizeof(WORD); |
| 995 | *(WORD *)PTR_SEG_TO_LIN(pData->old_ss_sp) = oldFrame->bp; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 996 | pData->stacktop = top; |
| 997 | pData->stackmin = ptr; |
| 998 | pData->stackbottom = ptr; |
| 999 | |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1000 | /* Switch to the new stack */ |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1001 | |
Alexandre Julliard | 17216f5 | 1997-10-12 16:30:17 +0000 | [diff] [blame] | 1002 | /* Note: we need to take the 3 arguments into account; otherwise, |
| 1003 | * the stack will underflow upon return from this function. |
| 1004 | */ |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1005 | copySize = oldFrame->bp - OFFSETOF(pData->old_ss_sp); |
| 1006 | copySize += 3 * sizeof(WORD) + sizeof(STACK16FRAME); |
| 1007 | pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( seg, ptr - copySize ); |
| 1008 | newFrame = THREAD_STACK16( pTask->thdb ); |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1009 | |
| 1010 | /* Copy the stack frame and the local variables to the new stack */ |
| 1011 | |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1012 | memmove( newFrame, oldFrame, copySize ); |
| 1013 | newFrame->bp = ptr; |
| 1014 | *(WORD *)PTR_SEG_OFF_TO_LIN( seg, ptr ) = 0; /* clear previous bp */ |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1015 | } |
| 1016 | |
| 1017 | |
| 1018 | /*********************************************************************** |
| 1019 | * SwitchStackBack (KERNEL.109) |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1020 | */ |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 1021 | void WINAPI SwitchStackBack( CONTEXT *context ) |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1022 | { |
| 1023 | TDB *pTask; |
| 1024 | STACK16FRAME *oldFrame, *newFrame; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1025 | INSTANCEDATA *pData; |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1026 | |
| 1027 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 1028 | if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack)))) |
Alexandre Julliard | d37eb36 | 1997-07-20 16:23:21 +0000 | [diff] [blame] | 1029 | return; |
| 1030 | if (!pData->old_ss_sp) |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1031 | { |
Alexandre Julliard | 46ea8b3 | 1998-05-03 19:01:20 +0000 | [diff] [blame] | 1032 | WARN( task, "No previous SwitchStackTo\n" ); |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1033 | return; |
| 1034 | } |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 1035 | TRACE(task, "restoring stack %04x:%04x\n", |
| 1036 | SELECTOROF(pData->old_ss_sp), OFFSETOF(pData->old_ss_sp) ); |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1037 | |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1038 | oldFrame = THREAD_STACK16( pTask->thdb ); |
| 1039 | |
| 1040 | /* Pop bp from the previous stack */ |
| 1041 | |
| 1042 | BP_reg(context) = *(WORD *)PTR_SEG_TO_LIN(pData->old_ss_sp); |
| 1043 | pData->old_ss_sp += sizeof(WORD); |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1044 | |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1045 | /* Switch back to the old stack */ |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1046 | |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1047 | pTask->thdb->cur_stack = pData->old_ss_sp - sizeof(STACK16FRAME); |
Alexandre Julliard | dadf78f | 1998-05-17 17:13:43 +0000 | [diff] [blame] | 1048 | SS_reg(context) = SELECTOROF(pData->old_ss_sp); |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1049 | ESP_reg(context) = OFFSETOF(pData->old_ss_sp) - sizeof(DWORD); /*ret addr*/ |
Alexandre Julliard | d37eb36 | 1997-07-20 16:23:21 +0000 | [diff] [blame] | 1050 | pData->old_ss_sp = 0; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1051 | |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1052 | /* Build a stack frame for the return */ |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1053 | |
Alexandre Julliard | a845b88 | 1998-06-01 10:44:35 +0000 | [diff] [blame] | 1054 | newFrame = THREAD_STACK16( pTask->thdb ); |
Alexandre Julliard | 0623a6f | 1998-01-18 18:01:49 +0000 | [diff] [blame] | 1055 | newFrame->frame32 = oldFrame->frame32; |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 1056 | if (TRACE_ON(relay)) |
Alexandre Julliard | 3db94ef | 1997-09-28 17:43:24 +0000 | [diff] [blame] | 1057 | { |
| 1058 | newFrame->entry_ip = oldFrame->entry_ip; |
| 1059 | newFrame->entry_cs = oldFrame->entry_cs; |
| 1060 | } |
Alexandre Julliard | ac9c9b0 | 1996-07-28 18:50:11 +0000 | [diff] [blame] | 1061 | } |
| 1062 | |
| 1063 | |
| 1064 | /*********************************************************************** |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1065 | * GetTaskQueueDS (KERNEL.118) |
| 1066 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1067 | void WINAPI GetTaskQueueDS( CONTEXT *context ) |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1068 | { |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 1069 | DS_reg(context) = GlobalHandleToSel( GetTaskQueue(0) ); |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1070 | } |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1071 | |
| 1072 | |
| 1073 | /*********************************************************************** |
| 1074 | * GetTaskQueueES (KERNEL.119) |
| 1075 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1076 | void WINAPI GetTaskQueueES( CONTEXT *context ) |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1077 | { |
Alexandre Julliard | ca22b33 | 1996-07-12 19:02:39 +0000 | [diff] [blame] | 1078 | ES_reg(context) = GlobalHandleToSel( GetTaskQueue(0) ); |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1079 | } |
Alexandre Julliard | ade697e | 1995-11-26 13:59:11 +0000 | [diff] [blame] | 1080 | |
| 1081 | |
| 1082 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1083 | * GetCurrentTask (KERNEL.36) |
| 1084 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1085 | HTASK16 WINAPI GetCurrentTask(void) |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 1086 | { |
Alexandre Julliard | af0bae5 | 1995-10-03 17:06:08 +0000 | [diff] [blame] | 1087 | return hCurrentTask; |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 1088 | } |
| 1089 | |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1090 | DWORD WINAPI WIN16_GetCurrentTask(void) |
Alexandre Julliard | 2d93d00 | 1996-05-21 15:01:41 +0000 | [diff] [blame] | 1091 | { |
| 1092 | /* This is the version used by relay code; the first task is */ |
| 1093 | /* returned in the high word of the result */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1094 | return MAKELONG( hCurrentTask, hFirstTask ); |
| 1095 | } |
| 1096 | |
| 1097 | |
| 1098 | /*********************************************************************** |
| 1099 | * GetCurrentPDB (KERNEL.37) |
| 1100 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1101 | HANDLE16 WINAPI GetCurrentPDB(void) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1102 | { |
| 1103 | TDB *pTask; |
| 1104 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1105 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1106 | return pTask->hPDB; |
| 1107 | } |
| 1108 | |
| 1109 | |
| 1110 | /*********************************************************************** |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 1111 | * GetInstanceData (KERNEL.54) |
| 1112 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1113 | INT16 WINAPI GetInstanceData( HINSTANCE16 instance, WORD buffer, INT16 len ) |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 1114 | { |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1115 | char *ptr = (char *)GlobalLock16( instance ); |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 1116 | if (!ptr || !len) return 0; |
| 1117 | if ((int)buffer + len >= 0x10000) len = 0x10000 - buffer; |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 1118 | memcpy( (char *)GlobalLock16(CURRENT_DS) + buffer, ptr + buffer, len ); |
Alexandre Julliard | a2f2e01 | 1995-06-06 16:40:35 +0000 | [diff] [blame] | 1119 | return len; |
| 1120 | } |
| 1121 | |
| 1122 | |
| 1123 | /*********************************************************************** |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1124 | * GetExeVersion (KERNEL.105) |
| 1125 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1126 | WORD WINAPI GetExeVersion(void) |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1127 | { |
| 1128 | TDB *pTask; |
| 1129 | |
| 1130 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
| 1131 | return pTask->version; |
| 1132 | } |
| 1133 | |
| 1134 | |
| 1135 | /*********************************************************************** |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 1136 | * SetErrorMode16 (KERNEL.107) |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 1137 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1138 | UINT16 WINAPI SetErrorMode16( UINT16 mode ) |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 1139 | { |
| 1140 | TDB *pTask; |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 1141 | UINT16 oldMode; |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 1142 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1143 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 1144 | oldMode = pTask->error_mode; |
| 1145 | pTask->error_mode = mode; |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 1146 | pTask->thdb->process->error_mode = mode; |
Alexandre Julliard | 4f8c37b | 1996-01-14 18:12:01 +0000 | [diff] [blame] | 1147 | return oldMode; |
| 1148 | } |
| 1149 | |
| 1150 | |
| 1151 | /*********************************************************************** |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 1152 | * SetErrorMode32 (KERNEL32.486) |
| 1153 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1154 | UINT32 WINAPI SetErrorMode32( UINT32 mode ) |
Alexandre Julliard | 349a953 | 1997-02-02 19:01:52 +0000 | [diff] [blame] | 1155 | { |
| 1156 | return SetErrorMode16( (UINT16)mode ); |
| 1157 | } |
| 1158 | |
| 1159 | |
| 1160 | /*********************************************************************** |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 1161 | * GetDOSEnvironment (KERNEL.131) |
| 1162 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1163 | SEGPTR WINAPI GetDOSEnvironment(void) |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 1164 | { |
| 1165 | TDB *pTask; |
| 1166 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1167 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 1168 | return PTR_SEG_OFF_TO_SEGPTR( pTask->pdb.environment, 0 ); |
Alexandre Julliard | 808cb04 | 1995-08-17 17:11:36 +0000 | [diff] [blame] | 1169 | } |
| 1170 | |
| 1171 | |
| 1172 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1173 | * GetNumTasks (KERNEL.152) |
| 1174 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1175 | UINT16 WINAPI GetNumTasks(void) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1176 | { |
| 1177 | return nTaskCount; |
| 1178 | } |
| 1179 | |
| 1180 | |
| 1181 | /*********************************************************************** |
| 1182 | * GetTaskDS (KERNEL.155) |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1183 | * |
| 1184 | * Note: this function apparently returns a DWORD with LOWORD == HIWORD. |
| 1185 | * I don't think we need to bother with this. |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1186 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1187 | HINSTANCE16 WINAPI GetTaskDS(void) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1188 | { |
| 1189 | TDB *pTask; |
| 1190 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1191 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1192 | return pTask->hInstance; |
| 1193 | } |
| 1194 | |
| 1195 | |
| 1196 | /*********************************************************************** |
| 1197 | * IsTask (KERNEL.320) |
| 1198 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1199 | BOOL16 WINAPI IsTask( HTASK16 hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1200 | { |
| 1201 | TDB *pTask; |
| 1202 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1203 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return FALSE; |
| 1204 | if (GlobalSize16( hTask ) < sizeof(TDB)) return FALSE; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1205 | return (pTask->magic == TDB_MAGIC); |
| 1206 | } |
| 1207 | |
| 1208 | |
| 1209 | /*********************************************************************** |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1210 | * SetTaskSignalProc (KERNEL.38) |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1211 | * |
| 1212 | * Real 16-bit interface is provided by the THUNK_SetTaskSignalProc. |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1213 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1214 | FARPROC16 WINAPI SetTaskSignalProc( HTASK16 hTask, FARPROC16 proc ) |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1215 | { |
| 1216 | TDB *pTask; |
| 1217 | FARPROC16 oldProc; |
| 1218 | |
| 1219 | if (!hTask) hTask = hCurrentTask; |
| 1220 | if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL; |
Alexandre Julliard | 77b9918 | 1997-09-14 17:17:23 +0000 | [diff] [blame] | 1221 | oldProc = (FARPROC16)pTask->userhandler; |
| 1222 | pTask->userhandler = (USERSIGNALPROC)proc; |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1223 | return oldProc; |
| 1224 | } |
| 1225 | |
| 1226 | |
| 1227 | /*********************************************************************** |
| 1228 | * SetSigHandler (KERNEL.140) |
| 1229 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1230 | WORD WINAPI SetSigHandler( FARPROC16 newhandler, FARPROC16* oldhandler, |
| 1231 | UINT16 *oldmode, UINT16 newmode, UINT16 flag ) |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1232 | { |
Alexandre Julliard | 54c2711 | 1998-03-29 19:44:57 +0000 | [diff] [blame] | 1233 | FIXME(task,"(%p,%p,%p,%d,%d), unimplemented.\n", |
| 1234 | newhandler,oldhandler,oldmode,newmode,flag ); |
Alexandre Julliard | f1aa303 | 1996-08-05 17:42:43 +0000 | [diff] [blame] | 1235 | |
| 1236 | if (flag != 1) return 0; |
| 1237 | if (!newmode) newhandler = NULL; /* Default handler */ |
| 1238 | if (newmode != 4) |
| 1239 | { |
| 1240 | TDB *pTask; |
| 1241 | |
| 1242 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0; |
| 1243 | if (oldmode) *oldmode = pTask->signal_flags; |
| 1244 | pTask->signal_flags = newmode; |
| 1245 | if (oldhandler) *oldhandler = pTask->sighandler; |
| 1246 | pTask->sighandler = newhandler; |
| 1247 | } |
| 1248 | return 0; |
| 1249 | } |
| 1250 | |
| 1251 | |
| 1252 | /*********************************************************************** |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 1253 | * GlobalNotify (KERNEL.154) |
| 1254 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1255 | VOID WINAPI GlobalNotify( FARPROC16 proc ) |
Alexandre Julliard | bf9130a | 1996-10-13 17:45:47 +0000 | [diff] [blame] | 1256 | { |
| 1257 | TDB *pTask; |
| 1258 | |
| 1259 | if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return; |
| 1260 | pTask->discardhandler = proc; |
| 1261 | } |
| 1262 | |
| 1263 | |
| 1264 | /*********************************************************************** |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1265 | * GetExePtr (KERNEL.133) |
| 1266 | */ |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1267 | static HMODULE16 GetExePtrHelper( HANDLE16 handle, HTASK16 *hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1268 | { |
| 1269 | char *ptr; |
Alexandre Julliard | 18f92e7 | 1996-07-17 20:02:21 +0000 | [diff] [blame] | 1270 | HANDLE16 owner; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1271 | |
| 1272 | /* Check for module handle */ |
| 1273 | |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1274 | if (!(ptr = GlobalLock16( handle ))) return 0; |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 1275 | if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return handle; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1276 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1277 | /* Search for this handle inside all tasks */ |
| 1278 | |
| 1279 | *hTask = hFirstTask; |
| 1280 | while (*hTask) |
| 1281 | { |
| 1282 | TDB *pTask = (TDB *)GlobalLock16( *hTask ); |
| 1283 | if ((*hTask == handle) || |
| 1284 | (pTask->hInstance == handle) || |
| 1285 | (pTask->hQueue == handle) || |
| 1286 | (pTask->hPDB == handle)) return pTask->hModule; |
| 1287 | *hTask = pTask->hNext; |
| 1288 | } |
| 1289 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1290 | /* Check the owner for module handle */ |
| 1291 | |
| 1292 | owner = FarGetOwner( handle ); |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1293 | if (!(ptr = GlobalLock16( owner ))) return 0; |
Alexandre Julliard | 23946ad | 1997-06-16 17:43:53 +0000 | [diff] [blame] | 1294 | if (((NE_MODULE *)ptr)->magic == IMAGE_OS2_SIGNATURE) return owner; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1295 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1296 | /* Search for the owner inside all tasks */ |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1297 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1298 | *hTask = hFirstTask; |
| 1299 | while (*hTask) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1300 | { |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1301 | TDB *pTask = (TDB *)GlobalLock16( *hTask ); |
| 1302 | if ((*hTask == owner) || |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1303 | (pTask->hInstance == owner) || |
| 1304 | (pTask->hQueue == owner) || |
| 1305 | (pTask->hPDB == owner)) return pTask->hModule; |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1306 | *hTask = pTask->hNext; |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1307 | } |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1308 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1309 | return 0; |
| 1310 | } |
| 1311 | |
Alexandre Julliard | ebfc0fe | 1998-06-28 18:40:26 +0000 | [diff] [blame] | 1312 | HMODULE16 WINAPI GetExePtr( HANDLE16 handle ) |
| 1313 | { |
| 1314 | HTASK16 dummy; |
| 1315 | return GetExePtrHelper( handle, &dummy ); |
| 1316 | } |
| 1317 | |
| 1318 | void WINAPI WIN16_GetExePtr( CONTEXT *context ) |
| 1319 | { |
| 1320 | WORD *stack = PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context)); |
| 1321 | HANDLE16 handle = (HANDLE16)stack[2]; |
| 1322 | HTASK16 hTask = 0; |
| 1323 | HMODULE16 hModule; |
| 1324 | |
| 1325 | hModule = GetExePtrHelper( handle, &hTask ); |
| 1326 | |
| 1327 | AX_reg(context) = CX_reg(context) = hModule; |
| 1328 | if (hTask) ES_reg(context) = hTask; |
| 1329 | } |
| 1330 | |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1331 | /*********************************************************************** |
| 1332 | * TaskFirst (TOOLHELP.63) |
| 1333 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1334 | BOOL16 WINAPI TaskFirst( TASKENTRY *lpte ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1335 | { |
| 1336 | lpte->hNext = hFirstTask; |
| 1337 | return TaskNext( lpte ); |
| 1338 | } |
| 1339 | |
| 1340 | |
| 1341 | /*********************************************************************** |
| 1342 | * TaskNext (TOOLHELP.64) |
| 1343 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1344 | BOOL16 WINAPI TaskNext( TASKENTRY *lpte ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1345 | { |
| 1346 | TDB *pTask; |
| 1347 | INSTANCEDATA *pInstData; |
| 1348 | |
Alexandre Julliard | a69b88b | 1998-03-15 20:29:56 +0000 | [diff] [blame] | 1349 | TRACE(toolhelp, "(%p): task=%04x\n", lpte, lpte->hNext ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1350 | if (!lpte->hNext) return FALSE; |
Alexandre Julliard | 1285c2f | 1996-05-06 16:06:24 +0000 | [diff] [blame] | 1351 | pTask = (TDB *)GlobalLock16( lpte->hNext ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1352 | if (!pTask || pTask->magic != TDB_MAGIC) return FALSE; |
| 1353 | pInstData = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( pTask->hInstance, 0 ); |
| 1354 | lpte->hTask = lpte->hNext; |
| 1355 | lpte->hTaskParent = pTask->hParent; |
| 1356 | lpte->hInst = pTask->hInstance; |
| 1357 | lpte->hModule = pTask->hModule; |
Alexandre Julliard | 60ce85c | 1998-02-01 18:33:27 +0000 | [diff] [blame] | 1358 | lpte->wSS = SELECTOROF( pTask->thdb->cur_stack ); |
| 1359 | lpte->wSP = OFFSETOF( pTask->thdb->cur_stack ); |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1360 | lpte->wStackTop = pInstData->stacktop; |
| 1361 | lpte->wStackMinimum = pInstData->stackmin; |
| 1362 | lpte->wStackBottom = pInstData->stackbottom; |
| 1363 | lpte->wcEvents = pTask->nEvents; |
| 1364 | lpte->hQueue = pTask->hQueue; |
| 1365 | strncpy( lpte->szModule, pTask->module_name, 8 ); |
| 1366 | lpte->szModule[8] = '\0'; |
| 1367 | lpte->wPSPOffset = 0x100; /*??*/ |
| 1368 | lpte->hNext = pTask->hNext; |
| 1369 | return TRUE; |
| 1370 | } |
| 1371 | |
| 1372 | |
| 1373 | /*********************************************************************** |
| 1374 | * TaskFindHandle (TOOLHELP.65) |
| 1375 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1376 | BOOL16 WINAPI TaskFindHandle( TASKENTRY *lpte, HTASK16 hTask ) |
Alexandre Julliard | 594997c | 1995-04-30 10:05:20 +0000 | [diff] [blame] | 1377 | { |
| 1378 | lpte->hNext = hTask; |
| 1379 | return TaskNext( lpte ); |
Alexandre Julliard | 3f2abfa | 1994-08-16 15:43:11 +0000 | [diff] [blame] | 1380 | } |
Alexandre Julliard | 339eefc | 1996-06-23 14:56:20 +0000 | [diff] [blame] | 1381 | |
| 1382 | |
| 1383 | /*********************************************************************** |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 1384 | * GetAppCompatFlags16 (KERNEL.354) |
Alexandre Julliard | 339eefc | 1996-06-23 14:56:20 +0000 | [diff] [blame] | 1385 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1386 | DWORD WINAPI GetAppCompatFlags16( HTASK16 hTask ) |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 1387 | { |
| 1388 | return GetAppCompatFlags32( hTask ); |
| 1389 | } |
| 1390 | |
| 1391 | |
| 1392 | /*********************************************************************** |
Alexandre Julliard | c7c217b | 1998-04-13 12:21:30 +0000 | [diff] [blame] | 1393 | * GetAppCompatFlags32 (USER32.206) |
Alexandre Julliard | 2197901 | 1997-03-05 08:22:35 +0000 | [diff] [blame] | 1394 | */ |
Alexandre Julliard | 670cdc4 | 1997-08-24 16:00:30 +0000 | [diff] [blame] | 1395 | DWORD WINAPI GetAppCompatFlags32( HTASK32 hTask ) |
Alexandre Julliard | 339eefc | 1996-06-23 14:56:20 +0000 | [diff] [blame] | 1396 | { |
| 1397 | TDB *pTask; |
| 1398 | |
| 1399 | if (!hTask) hTask = GetCurrentTask(); |
| 1400 | if (!(pTask=(TDB *)GlobalLock16( (HTASK16)hTask ))) return 0; |
| 1401 | if (GlobalSize16(hTask) < sizeof(TDB)) return 0; |
| 1402 | return pTask->compat_flags; |
| 1403 | } |