00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00022
00023
00024
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
00042
00043 UserAssert(
ExIsResourceAcquiredExclusiveLite(&Job->
JobLock));
00044
00045 UserAssert(
gpresUser !=
NULL);
00046
00047 BEGIN_REENTERCRIT();
00048
00049
BEGINATOMICCHECK();
00050
00051
00052
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
00070
00071
00072 UserAssert(Data != 0);
00073
00074
if ((pW32Job =
CreateW32Job(Job)) ==
NULL) {
00075
Status = STATUS_UNSUCCESSFUL;
00076
break;
00077 }
00078 }
else {
00079
00080
00081
00082
00083
00084
if (PtrToUlong(Data) == pW32Job->
restrictions) {
00085 TAGMSG0(DBGTAG_Job,
"UserJobCallout: SetInformation same as before");
00086
break;
00087 }
00088 }
00089
00090
00091
00092
00093 pW32Job->
restrictions = PtrToUlong(Data);
00094
00095
UpdateJob(pW32Job);
00096
break;
00097
00098
case PsW32JobCalloutAddProcess:
00099
00100
00101
00102
00103
00104 UserAssert(Job->
UIRestrictionsClass != 0);
00105
00106
00107
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
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
00150
00151
00152
00153
00154
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
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
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
00199
00200
00201
00202
00203
00204
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
00218
00219
00220 ppi =
gppiList;
00221
00222
while (ppi) {
00223
if (ppi->Process->Job == pW32Job->
Job) {
00224
00225
00226
00227
00228
if (ppi->
pW32Job ==
NULL) {
00229
00230
00231
00232
00233
JobCalloutAddProcess(pW32Job, ppi);
00234 }
else {
00235
00236
00237
00238
00239
00240
SetProcessFlags(pW32Job, ppi);
00241 }
00242 }
00243 ppi = ppi->
ppiNextRunning;
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253
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
00270
00271
if (pW32Job ==
NULL) {
00272
return FALSE;
00273 }
00274
00275
00276
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
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
00318
00319
00320
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
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
00367
00368
00369
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
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
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
00413
00414 UserAssert(ppi->
pW32Job ==
NULL);
00415
00416 ppi->
pW32Job = pW32Job;
00417
00418
if (pW32Job->
uProcessCount == pW32Job->
uMaxProcesses) {
00419
00420
00421
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
00449
00450 pW32Job->
ppiTable[pW32Job->
uProcessCount] = ppi;
00451 (pW32Job->
uProcessCount)++;
00452
00453
SetProcessFlags(pW32Job, ppi);
00454
00455
return TRUE;
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
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
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
00494
00495
REMOVE_FROM_LIST(
W32JOB,
gpJobsList, pW32Job, pNext);
00496
00497
RtlDestroyAtomTable(pW32Job->
pAtomTable);
00498
00499 UserFreePool(pW32Job);
00500
00501
return TRUE;
00502 }