Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

job.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: job.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains the code to implement the job object in NTUSER. 00007 * 00008 * History: 00009 * 29-Jul-1997 CLupu Created. 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 00014 PW32JOB CreateW32Job(PEJOB Job); 00015 VOID UpdateJob(PW32JOB pW32Job); 00016 void SetProcessFlags(PW32JOB pW32Job, PPROCESSINFO ppi); 00017 BOOL JobCalloutAddProcess(PW32JOB, PPROCESSINFO); 00018 BOOL JobCalloutTerminate(PW32JOB); 00019 00020 /***************************************************************************\ 00021 * UserJobCallout 00022 * 00023 * History: 00024 * 29-Jul-1997 CLupu Created. 00025 \***************************************************************************/ 00026 NTSTATUS UserJobCallout( 00027 PKWIN32_JOBCALLOUT_PARAMETERS Parm) 00028 { 00029 NTSTATUS Status = STATUS_SUCCESS; 00030 PW32JOB pW32Job = NULL; 00031 PEJOB Job; 00032 PSW32JOBCALLOUTTYPE CalloutType; 00033 PVOID Data; 00034 00035 00036 Job = Parm->Job; 00037 CalloutType = Parm->CalloutType; 00038 Data = Parm->Data; 00039 00040 /* 00041 * The EJOB lock must be acquired at this time. 00042 */ 00043 UserAssert(ExIsResourceAcquiredExclusiveLite(&Job->JobLock)); 00044 00045 UserAssert(gpresUser != NULL); 00046 00047 BEGIN_REENTERCRIT(); 00048 00049 BEGINATOMICCHECK(); 00050 00051 /* 00052 * find the W32JOB in the global list (if any) 00053 */ 00054 pW32Job = gpJobsList; 00055 00056 while (pW32Job) { 00057 if (pW32Job->Job == Job) { 00058 break; 00059 } 00060 pW32Job = pW32Job->pNext; 00061 } 00062 00063 switch (CalloutType) { 00064 case PsW32JobCalloutSetInformation: 00065 00066 if (pW32Job == NULL) { 00067 00068 /* 00069 * The W32Job is not created yet. Assert that this is not 00070 * a call to remove UI restrictions 00071 */ 00072 UserAssert(Data != 0); 00073 00074 if ((pW32Job = CreateW32Job(Job)) == NULL) { 00075 Status = STATUS_UNSUCCESSFUL; 00076 break; 00077 } 00078 } else { 00079 00080 /* 00081 * The W32Job structure is already created. Return if 00082 * the restrictions are the same as before. 00083 */ 00084 if (PtrToUlong(Data) == pW32Job->restrictions) { 00085 TAGMSG0(DBGTAG_Job, "UserJobCallout: SetInformation same as before"); 00086 break; 00087 } 00088 } 00089 00090 /* 00091 * Set the restrictions 00092 */ 00093 pW32Job->restrictions = PtrToUlong(Data); 00094 00095 UpdateJob(pW32Job); 00096 break; 00097 00098 case PsW32JobCalloutAddProcess: 00099 00100 /* 00101 * 'Data' parameter is a pointer to W32PROCESS. So this callout 00102 * happens only for GUI processes. 00103 */ 00104 UserAssert(Job->UIRestrictionsClass != 0); 00105 00106 /* 00107 * Assert that the W32JOB structure is already created. 00108 */ 00109 UserAssert(pW32Job != NULL); 00110 00111 TAGMSG3(DBGTAG_Job, "UserJobCallout: AddProcess Job 0x%x W32Job 0x%x Process 0x%x", 00112 Job, pW32Job, (ULONG_PTR)Data); 00113 00114 /* 00115 * this callout must be only for GUI processes 00116 */ 00117 UserAssert(Data != NULL); 00118 00119 JobCalloutAddProcess(pW32Job, (PPROCESSINFO)Data); 00120 00121 break; 00122 00123 case PsW32JobCalloutTerminate: 00124 00125 TAGMSG2(DBGTAG_Job, "UserJobCallout: Terminate Job 0x%x W32Job 0x%x", 00126 Job, pW32Job); 00127 00128 if (pW32Job) { 00129 JobCalloutTerminate(pW32Job); 00130 } 00131 break; 00132 00133 default: 00134 TAGMSG2(DBGTAG_Job, "UserJobCallout: Invalid callout 0x%x Job 0x%x", 00135 CalloutType, Job); 00136 00137 Status = STATUS_NOT_IMPLEMENTED; 00138 break; 00139 } 00140 00141 ENDATOMICCHECK(); 00142 00143 END_REENTERCRIT(); 00144 00145 return Status; 00146 } 00147 00148 /***************************************************************************\ 00149 * CreateW32Job 00150 * 00151 * Creates a W32Job 00152 * 00153 * History: 00154 * 18-Mar-1998 CLupu Created. 00155 \***************************************************************************/ 00156 PW32JOB CreateW32Job( 00157 PEJOB Job) 00158 { 00159 PW32JOB pW32Job; 00160 00161 TAGMSG1(DBGTAG_Job, "CreateW32Job: EJOB 0x%x", Job); 00162 00163 pW32Job = UserAllocPoolZInit(sizeof(W32JOB), TAG_W32JOB); 00164 00165 if (pW32Job == NULL) { 00166 RIPMSG0(RIP_ERROR, "CreateW32Job: memory allocation error"); 00167 return NULL; 00168 } 00169 00170 /* 00171 * Create the global atom table for this job 00172 */ 00173 CreateGlobalAtomTable(&pW32Job->pAtomTable); 00174 00175 if (pW32Job->pAtomTable == NULL) { 00176 RIPMSG1(RIP_ERROR, "CreateW32Job: fail to create the atom table for job 0x%x", 00177 pW32Job); 00178 00179 UserFreePool(pW32Job); 00180 return NULL; 00181 } 00182 00183 /* 00184 * Link it in the W32 job's list 00185 */ 00186 pW32Job->pNext = gpJobsList; 00187 gpJobsList = pW32Job; 00188 00189 pW32Job->Job = Job; 00190 00191 TAGMSG2(DBGTAG_Job, "CreateW32Job: pW32Job 0x%x created for EJOB 0x%x", 00192 pW32Job, Job); 00193 00194 return pW32Job; 00195 } 00196 00197 /***************************************************************************\ 00198 * UpdateJob 00199 * 00200 * Walks the processinfo list in userk to update all the processes assigned 00201 * to this job . 00202 * 00203 * History: 00204 * 20-Mar-1998 CLupu Created. 00205 \***************************************************************************/ 00206 VOID UpdateJob( 00207 PW32JOB pW32Job) 00208 { 00209 PPROCESSINFO ppi; 00210 00211 UserAssert(ExIsResourceAcquiredExclusiveLite(&pW32Job->Job->JobLock)); 00212 CheckCritIn(); 00213 00214 TAGMSG1(DBGTAG_Job, "UpdateJob: pW32Job 0x%x", pW32Job); 00215 00216 /* 00217 * walk the GUI processes list to see if any new process got 00218 * assigned to the current job. 00219 */ 00220 ppi = gppiList; 00221 00222 while (ppi) { 00223 if (ppi->Process->Job == pW32Job->Job) { 00224 00225 /* 00226 * the process is assigned to this job 00227 */ 00228 if (ppi->pW32Job == NULL) { 00229 00230 /* 00231 * add the process to the W32 job 00232 */ 00233 JobCalloutAddProcess(pW32Job, ppi); 00234 } else { 00235 00236 /* 00237 * The process is already added to the job. Just 00238 * update the restrictions. 00239 */ 00240 SetProcessFlags(pW32Job, ppi); 00241 } 00242 } 00243 ppi = ppi->ppiNextRunning; 00244 } 00245 } 00246 00247 /***************************************************************************\ 00248 * RemoveProcessFromJob 00249 * 00250 * This is called during the delete process callout. 00251 * 00252 * History: 00253 * 30-Jul-1997 CLupu Created. 00254 \***************************************************************************/ 00255 BOOL RemoveProcessFromJob( 00256 PPROCESSINFO ppi) 00257 { 00258 PW32JOB pW32Job; 00259 UINT ip; 00260 00261 CheckCritIn(); 00262 00263 pW32Job = ppi->pW32Job; 00264 00265 TAGMSG2(DBGTAG_Job, "RemoveProcessFromJob: ppi 0x%x pW32Job 0x%x", 00266 ppi, pW32Job); 00267 00268 /* 00269 * The job might not have UI restrictions 00270 */ 00271 if (pW32Job == NULL) { 00272 return FALSE; 00273 } 00274 00275 /* 00276 * remove the ppi from the job's ppi table 00277 */ 00278 for (ip = 0; ip < pW32Job->uProcessCount; ip++) { 00279 00280 UserAssert(pW32Job->ppiTable[ip]->pW32Job == pW32Job); 00281 00282 if (ppi == pW32Job->ppiTable[ip]) { 00283 00284 ppi->pW32Job = NULL; 00285 00286 RtlMoveMemory(pW32Job->ppiTable + ip, 00287 pW32Job->ppiTable + ip + 1, 00288 (pW32Job->uProcessCount - ip - 1) * sizeof(PPROCESSINFO)); 00289 00290 (pW32Job->uProcessCount)--; 00291 00292 /* 00293 * free the process array if this is the last one. 00294 */ 00295 if (pW32Job->uProcessCount == 0) { 00296 UserFreePool(pW32Job->ppiTable); 00297 pW32Job->ppiTable = NULL; 00298 pW32Job->uMaxProcesses = 0; 00299 } 00300 00301 TAGMSG2(DBGTAG_Job, "RemoveProcessFromJob: ppi 0x%x removed from pW32Job 0x%x", 00302 ppi, pW32Job); 00303 00304 return TRUE; 00305 } 00306 } 00307 00308 TAGMSG2(DBGTAG_Job, "RemoveProcessFromJob: ppi 0x%x not found in pW32Job 0x%x", 00309 ppi, pW32Job); 00310 00311 UserAssert(0); 00312 00313 return FALSE; 00314 } 00315 00316 /***************************************************************************\ 00317 * SetProcessFlags 00318 * 00319 * History: 00320 * 29-Jul-1997 CLupu Created. 00321 \***************************************************************************/ 00322 void SetProcessFlags( 00323 PW32JOB pW32Job, 00324 PPROCESSINFO ppi) 00325 { 00326 PTHREADINFO pti; 00327 00328 CheckCritIn(); 00329 00330 TAGMSG3(DBGTAG_Job, "SetProcessFlags: pW32Job 0x%x ppi 0x%x restrictions 0x%x", 00331 pW32Job, ppi, pW32Job->restrictions); 00332 00333 UserAssert(ppi->pW32Job == pW32Job); 00334 00335 if (pW32Job->restrictions == 0) { 00336 ((PW32PROCESS)ppi)->W32PF_Flags &= ~W32PF_RESTRICTED; 00337 } else { 00338 ((PW32PROCESS)ppi)->W32PF_Flags |= W32PF_RESTRICTED; 00339 } 00340 00341 KeAttachProcess(&ppi->Process->Pcb); 00342 00343 /* 00344 * walk the pti list and set the restricted flag as appropriate 00345 */ 00346 pti = ppi->ptiList; 00347 00348 if (pW32Job->restrictions == 0) { 00349 while (pti) { 00350 pti->TIF_flags &= ~TIF_RESTRICTED; 00351 pti->pClientInfo->dwTIFlags &= ~TIF_RESTRICTED; 00352 pti = pti->ptiSibling; 00353 } 00354 } else { 00355 while (pti) { 00356 pti->TIF_flags |= TIF_RESTRICTED; 00357 pti->pClientInfo->dwTIFlags |= TIF_RESTRICTED; 00358 pti = pti->ptiSibling; 00359 } 00360 } 00361 00362 KeDetachProcess(); 00363 } 00364 00365 /***************************************************************************\ 00366 * JobCalloutAddProcess 00367 * 00368 * History: 00369 * 30-Jul-1997 CLupu Created. 00370 \***************************************************************************/ 00371 BOOL JobCalloutAddProcess( 00372 PW32JOB pW32Job, 00373 PPROCESSINFO ppi) 00374 { 00375 PPROCESSINFO* ppiTable; 00376 00377 CheckCritIn(); 00378 00379 UserAssert(pW32Job != NULL); 00380 00381 /* 00382 * This process is not yet initialized 00383 */ 00384 if (ppi->Process == NULL) { 00385 return FALSE; 00386 } 00387 00388 if (!(ppi->W32PF_Flags & W32PF_PROCESSCONNECTED)) { 00389 TAGMSG2(DBGTAG_Job, "JobCalloutAddProcess: pW32Job 0x%x ppi 0x%x not yet initialized", 00390 pW32Job, ppi); 00391 return FALSE; 00392 } 00393 00394 TAGMSG2(DBGTAG_Job, "JobCalloutAddProcess: pW32Job 0x%x ppi 0x%x", 00395 pW32Job, ppi); 00396 00397 #if DBG 00398 /* 00399 * Make sure the process is not already in the job's process list 00400 */ 00401 { 00402 UINT ip; 00403 for (ip = 0; ip < pW32Job->uProcessCount; ip++) { 00404 00405 UserAssert(pW32Job->ppiTable[ip]->pW32Job == pW32Job); 00406 UserAssert(ppi != pW32Job->ppiTable[ip]); 00407 } 00408 } 00409 #endif // DBG 00410 00411 /* 00412 * save the pW32Job pointer in the process info 00413 */ 00414 UserAssert(ppi->pW32Job == NULL); 00415 00416 ppi->pW32Job = pW32Job; 00417 00418 if (pW32Job->uProcessCount == pW32Job->uMaxProcesses) { 00419 00420 /* 00421 * No more room. Allocate more space for the process table 00422 */ 00423 if (pW32Job->uMaxProcesses == 0) { 00424 00425 UserAssert(pW32Job->ppiTable == NULL); 00426 00427 ppiTable = UserAllocPool(JP_DELTA * sizeof(PPROCESSINFO), TAG_W32JOBEXTRA); 00428 00429 } else { 00430 UserAssert(pW32Job->ppiTable != NULL); 00431 00432 ppiTable = UserReAllocPool(pW32Job->ppiTable, 00433 pW32Job->uMaxProcesses * sizeof(PPROCESSINFO), 00434 (pW32Job->uMaxProcesses + JP_DELTA) * sizeof(PPROCESSINFO), 00435 TAG_W32JOBEXTRA); 00436 } 00437 00438 if (ppiTable == NULL) { 00439 RIPMSG0(RIP_ERROR, "JobCalloutAddProcess: memory allocation error\n"); 00440 return FALSE; 00441 } 00442 00443 pW32Job->ppiTable = ppiTable; 00444 pW32Job->uMaxProcesses += JP_DELTA; 00445 } 00446 00447 /* 00448 * now add the process to the job 00449 */ 00450 pW32Job->ppiTable[pW32Job->uProcessCount] = ppi; 00451 (pW32Job->uProcessCount)++; 00452 00453 SetProcessFlags(pW32Job, ppi); 00454 00455 return TRUE; 00456 } 00457 00458 /***************************************************************************\ 00459 * JobCalloutTerminate 00460 * 00461 * This is called during the job object delete routine. 00462 * 00463 * History: 00464 * 30-Jul-1997 CLupu Created. 00465 \***************************************************************************/ 00466 BOOL JobCalloutTerminate( 00467 PW32JOB pW32Job) 00468 { 00469 CheckCritIn(); 00470 00471 UserAssert(pW32Job != NULL); 00472 00473 TAGMSG1(DBGTAG_Job, "JobCalloutTerminate: pW32Job 0x%x", pW32Job); 00474 00475 /* 00476 * No processes should be attached to this job 00477 */ 00478 UserAssert(pW32Job->ppiTable == NULL); 00479 UserAssert(pW32Job->uProcessCount == 0); 00480 UserAssert(pW32Job->uMaxProcesses == 0); 00481 00482 if (pW32Job->pgh) { 00483 UserAssert(pW32Job->ughCrt > 0); 00484 UserAssert(pW32Job->ughMax > 0); 00485 00486 UserFreePool(pW32Job->pgh); 00487 pW32Job->pgh = NULL; 00488 pW32Job->ughCrt = 0; 00489 pW32Job->ughMax = 0; 00490 } 00491 00492 /* 00493 * remove the W32 job from the job's list 00494 */ 00495 REMOVE_FROM_LIST(W32JOB, gpJobsList, pW32Job, pNext); 00496 00497 RtlDestroyAtomTable(pW32Job->pAtomTable); 00498 00499 UserFreePool(pW32Job); 00500 00501 return TRUE; 00502 }

Generated on Sat May 15 19:40:32 2004 for test by doxygen 1.3.7