00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include "psp.h"
00024
#include "winerror.h"
00025
00026
#if defined(_WIN64)
00027
#include <wow64t.h>
00028
#endif
00029
00030
00031
00032
00033
00034
00035 extern KMUTANT ObpInitKillMutant;
00036
00037
00038
00039
00040 extern PEPROCESS ExpDefaultErrorPortProcess;
00041 extern BOOLEAN
PsWatchEnabled;
00042
00043
00044
00045
00046
00047
00048 #define WS_CATCH_SIZE 8192
00049 #define WS_OVERHEAD 16
00050 #define MAX_WS_CATCH_INDEX (((WS_CATCH_SIZE-WS_OVERHEAD)/sizeof(PROCESS_WS_WATCH_INFORMATION)) - 2)
00051
00052 KPRIORITY
PspPriorityTable[PROCESS_PRIORITY_CLASS_ABOVE_NORMAL+1] = {8,4,8,13,24,6,10};
00053
00054
NTSTATUS
00055
PsConvertToGuiThread(
00056 VOID
00057 );
00058
00059
NTSTATUS
00060
PspQueryWorkingSetWatch(
00061 IN HANDLE ProcessHandle,
00062 IN PROCESSINFOCLASS ProcessInformationClass,
00063 OUT PVOID ProcessInformation,
00064 IN ULONG ProcessInformationLength,
00065 OUT PULONG ReturnLength OPTIONAL,
00066 IN KPROCESSOR_MODE PreviousMode
00067 );
00068
00069
NTSTATUS
00070
PspQueryQuotaLimits(
00071 IN HANDLE ProcessHandle,
00072 IN PROCESSINFOCLASS ProcessInformationClass,
00073 OUT PVOID ProcessInformation,
00074 IN ULONG ProcessInformationLength,
00075 OUT PULONG ReturnLength OPTIONAL,
00076 IN KPROCESSOR_MODE PreviousMode
00077 );
00078
00079
NTSTATUS
00080
PspQueryPooledQuotaLimits(
00081 IN HANDLE ProcessHandle,
00082 IN PROCESSINFOCLASS ProcessInformationClass,
00083 OUT PVOID ProcessInformation,
00084 IN ULONG ProcessInformationLength,
00085 OUT PULONG ReturnLength OPTIONAL,
00086 IN KPROCESSOR_MODE PreviousMode
00087 );
00088
00089
NTSTATUS
00090
PspSetQuotaLimits(
00091 IN HANDLE ProcessHandle,
00092 IN PROCESSINFOCLASS ProcessInformationClass,
00093 IN PVOID ProcessInformation,
00094 IN ULONG ProcessInformationLength,
00095 IN KPROCESSOR_MODE PreviousMode
00096 );
00097
00098
#ifdef ALLOC_PRAGMA
00099
#pragma alloc_text(PAGE, PsEstablishWin32Callouts)
00100
#pragma alloc_text(PAGE, PsConvertToGuiThread)
00101
#pragma alloc_text(PAGE, NtQueryInformationProcess)
00102
#pragma alloc_text(PAGE, NtSetInformationProcess)
00103
#pragma alloc_text(PAGE, NtQueryInformationThread)
00104
#pragma alloc_text(PAGE, NtSetInformationThread)
00105
#pragma alloc_text(PAGE, PsSetProcessPriorityByClass)
00106
#pragma alloc_text(PAGELK, PspQueryWorkingSetWatch)
00107
#pragma alloc_text(PAGELK, PspQueryQuotaLimits)
00108
#pragma alloc_text(PAGELK, PspQueryPooledQuotaLimits)
00109
#pragma alloc_text(PAGELK, PspSetQuotaLimits)
00110
#endif
00111
00112
NTSTATUS
00113 PspQueryWorkingSetWatch(
00114 IN HANDLE ProcessHandle,
00115 IN PROCESSINFOCLASS ProcessInformationClass,
00116 OUT PVOID ProcessInformation,
00117 IN ULONG ProcessInformationLength,
00118 OUT PULONG ReturnLength OPTIONAL,
00119 IN KPROCESSOR_MODE PreviousMode
00120 )
00121 {
00122 PPAGEFAULT_HISTORY WorkingSetCatcher;
00123 ULONG SpaceNeeded;
00124
PEPROCESS Process;
00125 KIRQL OldIrql;
00126
NTSTATUS st;
00127
00128 st =
ObReferenceObjectByHandle(
00129 ProcessHandle,
00130 PROCESS_QUERY_INFORMATION,
00131
PsProcessType,
00132 PreviousMode,
00133 (PVOID *)&Process,
00134
NULL
00135 );
00136
00137
if ( !
NT_SUCCESS(st) ) {
00138
return st;
00139 }
00140
00141
if ( !(WorkingSetCatcher = Process->WorkingSetWatch) ) {
00142
ObDereferenceObject(Process);
00143
return STATUS_UNSUCCESSFUL;
00144 }
00145
00146
MmLockPagableSectionByHandle(
ExPageLockHandle);
00147 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql);
00148
00149
if ( WorkingSetCatcher->CurrentIndex ) {
00150
00151
00152
00153
00154
00155 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingPc =
NULL;
00156
00157
00158
00159
00160
if (WorkingSetCatcher->CurrentIndex != WorkingSetCatcher->MaxIndex)
00161 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa =
NULL;
00162
else
00163 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa = (PVOID) 1;
00164
00165 SpaceNeeded = (WorkingSetCatcher->CurrentIndex+1) *
sizeof(PROCESS_WS_WATCH_INFORMATION);
00166 }
else {
00167 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
00168
MmUnlockPagableImageSection(
ExPageLockHandle);
00169
ObDereferenceObject(Process);
00170
return STATUS_NO_MORE_ENTRIES;
00171 }
00172
00173
if ( ProcessInformationLength < SpaceNeeded ) {
00174 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
00175
MmUnlockPagableImageSection(
ExPageLockHandle);
00176
ObDereferenceObject(Process);
00177
return STATUS_BUFFER_TOO_SMALL;
00178 }
00179
00180
00181
00182
00183
00184
00185 WorkingSetCatcher->CurrentIndex =
MAX_WS_CATCH_INDEX;
00186
00187 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
00188
00189
try {
00190 RtlMoveMemory(ProcessInformation,&WorkingSetCatcher->WatchInfo[0],SpaceNeeded);
00191
if (ARGUMENT_PRESENT(ReturnLength) ) {
00192 *ReturnLength = SpaceNeeded;
00193 }
00194 } except(
EXCEPTION_EXECUTE_HANDLER) {
00195 ;
00196 }
00197
00198 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql);
00199 WorkingSetCatcher->CurrentIndex = 0;
00200 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
00201
00202
MmUnlockPagableImageSection(
ExPageLockHandle);
00203
ObDereferenceObject(Process);
00204
00205
return STATUS_SUCCESS;
00206 }
00207
00208
NTSTATUS
00209 PspQueryQuotaLimits(
00210 IN HANDLE ProcessHandle,
00211 IN PROCESSINFOCLASS ProcessInformationClass,
00212 OUT PVOID ProcessInformation,
00213 IN ULONG ProcessInformationLength,
00214 OUT PULONG ReturnLength OPTIONAL,
00215 IN KPROCESSOR_MODE PreviousMode
00216 )
00217 {
00218 QUOTA_LIMITS QuotaLimits;
00219
PEPROCESS Process;
00220 KIRQL OldIrql;
00221
NTSTATUS st;
00222
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00223
00224
if ( ProcessInformationLength != (ULONG)
sizeof(QUOTA_LIMITS) ) {
00225
return STATUS_INFO_LENGTH_MISMATCH;
00226 }
00227
00228 st =
ObReferenceObjectByHandle(
00229 ProcessHandle,
00230 PROCESS_QUERY_INFORMATION,
00231
PsProcessType,
00232 PreviousMode,
00233 (PVOID *)&Process,
00234
NULL
00235 );
00236
if ( !
NT_SUCCESS(st) ) {
00237
return st;
00238 }
00239
00240
00241 QuotaBlock = Process->QuotaBlock;
00242
00243
MmLockPagableSectionByHandle(
ExPageLockHandle);
00244
00245
if ( QuotaBlock != &
PspDefaultQuotaBlock ) {
00246 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00247
00248 QuotaLimits.PagedPoolLimit = QuotaBlock->
QuotaPoolLimit[
PagedPool];
00249 QuotaLimits.NonPagedPoolLimit = QuotaBlock->
QuotaPoolLimit[
NonPagedPool];
00250 QuotaLimits.PagefileLimit = QuotaBlock->
PagefileLimit;
00251 QuotaLimits.TimeLimit.LowPart = 0xffffffff;
00252 QuotaLimits.TimeLimit.HighPart = 0xffffffff;
00253
00254 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00255 }
else {
00256 QuotaLimits.PagedPoolLimit = (SIZE_T)-1;
00257 QuotaLimits.NonPagedPoolLimit = (SIZE_T)-1;
00258 QuotaLimits.PagefileLimit = (SIZE_T)-1;
00259 QuotaLimits.TimeLimit.LowPart = 0xffffffff;
00260 QuotaLimits.TimeLimit.HighPart = 0xffffffff;
00261 }
00262
00263 QuotaLimits.MinimumWorkingSetSize =
00264 Process->Vm.MinimumWorkingSetSize <<
PAGE_SHIFT;
00265 QuotaLimits.MaximumWorkingSetSize =
00266 Process->Vm.MaximumWorkingSetSize <<
PAGE_SHIFT;
00267
00268
ObDereferenceObject(Process);
00269
00270
00271
00272
00273
00274
00275
00276
try {
00277 *(PQUOTA_LIMITS) ProcessInformation = QuotaLimits;
00278
00279
if (ARGUMENT_PRESENT(ReturnLength) ) {
00280 *ReturnLength =
sizeof(QUOTA_LIMITS);
00281 }
00282 } except(
EXCEPTION_EXECUTE_HANDLER) {
00283 ;
00284 }
00285
00286
MmUnlockPagableImageSection(
ExPageLockHandle);
00287
return STATUS_SUCCESS;
00288 }
00289
00290
NTSTATUS
00291 PspQueryPooledQuotaLimits(
00292 IN HANDLE ProcessHandle,
00293 IN PROCESSINFOCLASS ProcessInformationClass,
00294 OUT PVOID ProcessInformation,
00295 IN ULONG ProcessInformationLength,
00296 OUT PULONG ReturnLength OPTIONAL,
00297 IN KPROCESSOR_MODE PreviousMode
00298 )
00299 {
00300
PEPROCESS Process;
00301 KIRQL OldIrql;
00302
NTSTATUS st;
00303
PEPROCESS_QUOTA_BLOCK QuotaBlock;
00304 POOLED_USAGE_AND_LIMITS UsageAndLimits;
00305
00306
if ( ProcessInformationLength != (ULONG)
sizeof(POOLED_USAGE_AND_LIMITS) ) {
00307
return STATUS_INFO_LENGTH_MISMATCH;
00308 }
00309
00310 st =
ObReferenceObjectByHandle(
00311 ProcessHandle,
00312 PROCESS_QUERY_INFORMATION,
00313
PsProcessType,
00314 PreviousMode,
00315 (PVOID *)&Process,
00316
NULL
00317 );
00318
if ( !
NT_SUCCESS(st) ) {
00319
return st;
00320 }
00321
00322
00323 QuotaBlock = Process->QuotaBlock;
00324
00325
MmLockPagableSectionByHandle(
ExPageLockHandle);
00326
00327 ExAcquireSpinLock(&QuotaBlock->
QuotaLock,&OldIrql);
00328
00329 UsageAndLimits.PagedPoolLimit = QuotaBlock->
QuotaPoolLimit[
PagedPool];
00330 UsageAndLimits.NonPagedPoolLimit = QuotaBlock->
QuotaPoolLimit[
NonPagedPool];
00331 UsageAndLimits.PagefileLimit = QuotaBlock->
PagefileLimit;
00332
00333 UsageAndLimits.PagedPoolUsage = QuotaBlock->
QuotaPoolUsage[
PagedPool];
00334 UsageAndLimits.NonPagedPoolUsage = QuotaBlock->
QuotaPoolUsage[
NonPagedPool];
00335 UsageAndLimits.PagefileUsage = QuotaBlock->
PagefileUsage;
00336
00337 UsageAndLimits.PeakPagedPoolUsage = QuotaBlock->
QuotaPeakPoolUsage[
PagedPool];
00338 UsageAndLimits.PeakNonPagedPoolUsage = QuotaBlock->
QuotaPeakPoolUsage[
NonPagedPool];
00339 UsageAndLimits.PeakPagefileUsage = QuotaBlock->
PeakPagefileUsage;
00340
00341 ExReleaseSpinLock(&QuotaBlock->
QuotaLock,OldIrql);
00342
MmUnlockPagableImageSection(
ExPageLockHandle);
00343
00344
ObDereferenceObject(Process);
00345
00346
00347
00348
00349
00350
00351
00352
try {
00353 *(PPOOLED_USAGE_AND_LIMITS) ProcessInformation = UsageAndLimits;
00354
00355
if (ARGUMENT_PRESENT(ReturnLength) ) {
00356 *ReturnLength =
sizeof(POOLED_USAGE_AND_LIMITS);
00357 }
00358 } except(
EXCEPTION_EXECUTE_HANDLER) {
00359
return STATUS_SUCCESS;
00360 }
00361
00362
return STATUS_SUCCESS;
00363 }
00364
00365
NTSTATUS
00366 PspSetPrimaryToken(
00367 IN HANDLE ProcessHandle,
00368 IN HANDLE TokenHandle OPTIONAL,
00369 IN PACCESS_TOKEN TokenPointer OPTIONAL
00370 )
00371
00372
00373
00374
00375
00376
00377 {
00378
NTSTATUS st ;
00379 BOOLEAN HasPrivilege ;
00380 BOOLEAN IsChildToken ;
00381
PEPROCESS Process ;
00382
KPROCESSOR_MODE PreviousMode ;
00383
00384
00385
00386
00387
00388
00389 PreviousMode = KeGetPreviousMode();
00390
00391
if ( TokenHandle )
00392 {
00393
00394
00395
00396
00397
00398 st =
ObReferenceObjectByHandle (
00399 TokenHandle,
00400 TOKEN_ASSIGN_PRIMARY,
00401
SeTokenObjectType(),
00402 PreviousMode,
00403 (PVOID *)&TokenPointer,
00404
NULL
00405 );
00406
00407
if (!
NT_SUCCESS(st)) {
00408
return( st );
00409 }
00410 }
00411
00412 st =
SeIsChildTokenByPointer(
00413 TokenPointer,
00414 &IsChildToken
00415 );
00416
00417
if (!
NT_SUCCESS(st)) {
00418
00419
if ( TokenHandle ) {
00420
ObDereferenceObject( TokenPointer );
00421 }
00422
return( st );
00423 }
00424
00425
if (!IsChildToken ) {
00426
00427
00428
00429
00430
00431
00432 HasPrivilege =
SeCheckPrivilegedObject(
00433
SeAssignPrimaryTokenPrivilege,
00434 ProcessHandle,
00435 PROCESS_SET_INFORMATION,
00436 PreviousMode
00437 );
00438
00439
if ( !HasPrivilege ) {
00440
00441
if ( TokenHandle ) {
00442
ObDereferenceObject( TokenPointer );
00443 }
00444
00445
return( STATUS_PRIVILEGE_NOT_HELD );
00446 }
00447
00448 }
00449
00450 st =
ObReferenceObjectByHandle(
00451 ProcessHandle,
00452 PROCESS_SET_INFORMATION,
00453
PsProcessType,
00454 PreviousMode,
00455 (PVOID *)&Process,
00456
NULL
00457 );
00458
00459
if (
NT_SUCCESS(st) ) {
00460
00461
00462
00463
00464
00465
00466 st =
PspAssignPrimaryToken( Process,
NULL, TokenPointer );
00467
00468
00469
00470
00471
00472
00473
if (
NT_SUCCESS(st) ) {
00474
00475
NTSTATUS accesst;
00476 BOOLEAN AccessCheck;
00477 BOOLEAN MemoryAllocated;
00478 PSECURITY_DESCRIPTOR SecurityDescriptor;
00479
SECURITY_SUBJECT_CONTEXT SubjectContext;
00480
00481 st =
ObGetObjectSecurity(
00482 Process,
00483 &SecurityDescriptor,
00484 &MemoryAllocated
00485 );
00486
00487
if (
NT_SUCCESS(st) ) {
00488
00489
00490
00491
00492
00493 SubjectContext.
ProcessAuditId = Process;
00494 SubjectContext.
PrimaryToken =
PsReferencePrimaryToken(Process);
00495 SubjectContext.
ClientToken =
NULL;
00496 AccessCheck =
SeAccessCheck(
00497 SecurityDescriptor,
00498 &SubjectContext,
00499
FALSE,
00500 MAXIMUM_ALLOWED,
00501 0,
00502
NULL,
00503 &
PsProcessType->
TypeInfo.
GenericMapping,
00504 PreviousMode,
00505 &Process->GrantedAccess,
00506 &accesst
00507 );
00508
PsDereferencePrimaryToken(SubjectContext.
PrimaryToken);
00509
ObReleaseObjectSecurity(
00510 SecurityDescriptor,
00511 MemoryAllocated
00512 );
00513
if ( !AccessCheck ) {
00514 Process->GrantedAccess = 0;
00515 }
00516 }
00517 }
00518
00519
ObDereferenceObject(Process);
00520 }
00521
00522
if ( TokenHandle) {
00523
ObDereferenceObject( TokenPointer );
00524 }
00525
00526
return st;
00527 }
00528
00529
00530
NTSTATUS
00531 NtQueryInformationProcess(
00532 IN HANDLE ProcessHandle,
00533 IN PROCESSINFOCLASS ProcessInformationClass,
00534 OUT PVOID ProcessInformation,
00535 IN ULONG ProcessInformationLength,
00536 OUT PULONG ReturnLength OPTIONAL
00537 )
00538
00539 {
00540
PEPROCESS Process;
00541
KPROCESSOR_MODE PreviousMode;
00542
NTSTATUS st;
00543 PROCESS_BASIC_INFORMATION BasicInfo;
00544 VM_COUNTERS VmCounters;
00545 IO_COUNTERS IoCounters;
00546 KERNEL_USER_TIMES SysUserTime;
00547 HANDLE
DebugPort;
00548 ULONG HandleCount;
00549 ULONG DefaultHardErrorMode;
00550 HANDLE Wx86Info;
00551
PHANDLE_TABLE Ht;
00552 ULONG DisableBoost;
00553 PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo;
00554 PROCESS_SESSION_INFORMATION SessionInfo;
00555 PROCESS_PRIORITY_CLASS PriorityClass;
00556 ULONG_PTR Wow64Info;
00557
00558
PAGED_CODE();
00559
00560
00561
00562
00563
00564 PreviousMode = KeGetPreviousMode();
00565
if (PreviousMode !=
KernelMode) {
00566
try {
00567
ProbeForWrite(ProcessInformation,
00568 ProcessInformationLength,
00569
sizeof(ULONG));
00570
if (ARGUMENT_PRESENT(ReturnLength)) {
00571
ProbeForWriteUlong(ReturnLength);
00572 }
00573 } except(
EXCEPTION_EXECUTE_HANDLER) {
00574
return GetExceptionCode();
00575 }
00576 }
00577
00578
00579
00580
00581
00582
switch ( ProcessInformationClass ) {
00583
00584
case ProcessWorkingSetWatch:
00585
00586
return PspQueryWorkingSetWatch(
00587 ProcessHandle,
00588 ProcessInformationClass,
00589 ProcessInformation,
00590 ProcessInformationLength,
00591 ReturnLength,
00592 PreviousMode
00593 );
00594
00595
case ProcessBasicInformation:
00596
00597
if ( ProcessInformationLength != (ULONG)
sizeof(PROCESS_BASIC_INFORMATION) ) {
00598
return STATUS_INFO_LENGTH_MISMATCH;
00599 }
00600
00601 st =
ObReferenceObjectByHandle(
00602 ProcessHandle,
00603 PROCESS_QUERY_INFORMATION,
00604
PsProcessType,
00605 PreviousMode,
00606 (PVOID *)&Process,
00607
NULL
00608 );
00609
if ( !
NT_SUCCESS(st) ) {
00610
return st;
00611 }
00612
00613 BasicInfo.ExitStatus = Process->ExitStatus;
00614 BasicInfo.PebBaseAddress = Process->Peb;
00615 BasicInfo.AffinityMask = Process->Pcb.Affinity;
00616 BasicInfo.BasePriority = Process->Pcb.BasePriority;
00617 BasicInfo.UniqueProcessId = (ULONG_PTR)Process->UniqueProcessId;
00618 BasicInfo.InheritedFromUniqueProcessId = (ULONG_PTR)Process->InheritedFromUniqueProcessId;
00619
00620
ObDereferenceObject(Process);
00621
00622
00623
00624
00625
00626
00627
00628
try {
00629 *(PPROCESS_BASIC_INFORMATION) ProcessInformation = BasicInfo;
00630
00631
if (ARGUMENT_PRESENT(ReturnLength) ) {
00632 *ReturnLength =
sizeof(PROCESS_BASIC_INFORMATION);
00633 }
00634 } except(
EXCEPTION_EXECUTE_HANDLER) {
00635
return STATUS_SUCCESS;
00636 }
00637
00638
return STATUS_SUCCESS;
00639
00640
case ProcessDefaultHardErrorMode:
00641
00642
if ( ProcessInformationLength !=
sizeof(ULONG) ) {
00643
return STATUS_INFO_LENGTH_MISMATCH;
00644 }
00645
00646 st =
ObReferenceObjectByHandle(
00647 ProcessHandle,
00648 PROCESS_QUERY_INFORMATION,
00649
PsProcessType,
00650 PreviousMode,
00651 (PVOID *)&Process,
00652
NULL
00653 );
00654
00655
if ( !
NT_SUCCESS(st) ) {
00656
return st;
00657 }
00658
00659 DefaultHardErrorMode = Process->DefaultHardErrorProcessing;
00660
00661
ObDereferenceObject(Process);
00662
00663
try {
00664 *(PULONG) ProcessInformation = DefaultHardErrorMode;
00665
00666
if (ARGUMENT_PRESENT(ReturnLength) ) {
00667 *ReturnLength =
sizeof(ULONG);
00668 }
00669 } except(
EXCEPTION_EXECUTE_HANDLER) {
00670
return STATUS_SUCCESS;
00671 }
00672
00673
return STATUS_SUCCESS;
00674
case ProcessQuotaLimits:
00675
00676
return PspQueryQuotaLimits(
00677 ProcessHandle,
00678 ProcessInformationClass,
00679 ProcessInformation,
00680 ProcessInformationLength,
00681 ReturnLength,
00682 PreviousMode
00683 );
00684
00685
case ProcessPooledUsageAndLimits:
00686
00687
return PspQueryPooledQuotaLimits(
00688 ProcessHandle,
00689 ProcessInformationClass,
00690 ProcessInformation,
00691 ProcessInformationLength,
00692 ReturnLength,
00693 PreviousMode
00694 );
00695
00696
case ProcessIoCounters:
00697
00698
if ( ProcessInformationLength != (ULONG)
sizeof(IO_COUNTERS) ) {
00699
return STATUS_INFO_LENGTH_MISMATCH;
00700 }
00701
00702 st =
ObReferenceObjectByHandle(
00703 ProcessHandle,
00704 PROCESS_QUERY_INFORMATION,
00705
PsProcessType,
00706 PreviousMode,
00707 (PVOID *)&Process,
00708
NULL
00709 );
00710
if ( !
NT_SUCCESS(st) ) {
00711
return st;
00712 }
00713
00714 IoCounters.ReadOperationCount = Process->ReadOperationCount.QuadPart;
00715 IoCounters.WriteOperationCount = Process->WriteOperationCount.QuadPart;
00716 IoCounters.OtherOperationCount = Process->OtherOperationCount.QuadPart;
00717 IoCounters.ReadTransferCount = Process->ReadTransferCount.QuadPart;
00718 IoCounters.WriteTransferCount = Process->WriteTransferCount.QuadPart;
00719 IoCounters.OtherTransferCount = Process->OtherTransferCount.QuadPart;
00720
00721
ObDereferenceObject(Process);
00722
00723
00724
00725
00726
00727
00728
00729
try {
00730 *(PIO_COUNTERS) ProcessInformation = IoCounters;
00731
00732
if (ARGUMENT_PRESENT(ReturnLength) ) {
00733 *ReturnLength =
sizeof(IO_COUNTERS);
00734 }
00735 } except(
EXCEPTION_EXECUTE_HANDLER) {
00736
return STATUS_SUCCESS;
00737 }
00738
00739
return STATUS_SUCCESS;
00740
00741
case ProcessVmCounters:
00742
00743
if ( ProcessInformationLength != (ULONG)
sizeof(VM_COUNTERS) ) {
00744
return STATUS_INFO_LENGTH_MISMATCH;
00745 }
00746
00747 st =
ObReferenceObjectByHandle(
00748 ProcessHandle,
00749 PROCESS_QUERY_INFORMATION,
00750
PsProcessType,
00751 PreviousMode,
00752 (PVOID *)&Process,
00753
NULL
00754 );
00755
if ( !
NT_SUCCESS(st) ) {
00756
return st;
00757 }
00758
00759
00760
00761
00762
00763
00764
00765 VmCounters.PeakVirtualSize = Process->PeakVirtualSize;
00766 VmCounters.VirtualSize = Process->VirtualSize;
00767 VmCounters.PageFaultCount = Process->Vm.PageFaultCount;
00768 VmCounters.PeakWorkingSetSize = Process->Vm.PeakWorkingSetSize <<
PAGE_SHIFT;
00769 VmCounters.WorkingSetSize = Process->Vm.WorkingSetSize <<
PAGE_SHIFT;
00770 VmCounters.QuotaPeakPagedPoolUsage = Process->QuotaPeakPoolUsage[
PagedPool];
00771 VmCounters.QuotaPagedPoolUsage = Process->QuotaPoolUsage[
PagedPool];
00772 VmCounters.QuotaPeakNonPagedPoolUsage = Process->QuotaPeakPoolUsage[
NonPagedPool];
00773 VmCounters.QuotaNonPagedPoolUsage = Process->QuotaPoolUsage[
NonPagedPool];
00774 VmCounters.PagefileUsage = Process->PagefileUsage <<
PAGE_SHIFT;
00775 VmCounters.PeakPagefileUsage = Process->PeakPagefileUsage <<
PAGE_SHIFT;
00776
00777
ObDereferenceObject(Process);
00778
00779
00780
00781
00782
00783
00784
00785
try {
00786 *(PVM_COUNTERS) ProcessInformation = VmCounters;
00787
00788
if (ARGUMENT_PRESENT(ReturnLength) ) {
00789 *ReturnLength =
sizeof(VM_COUNTERS);
00790 }
00791 } except(
EXCEPTION_EXECUTE_HANDLER) {
00792
return STATUS_SUCCESS;
00793 }
00794
00795
return STATUS_SUCCESS;
00796
00797
case ProcessTimes:
00798
00799
if ( ProcessInformationLength != (ULONG)
sizeof(KERNEL_USER_TIMES) ) {
00800
return STATUS_INFO_LENGTH_MISMATCH;
00801 }
00802
00803 st =
ObReferenceObjectByHandle(
00804 ProcessHandle,
00805 PROCESS_QUERY_INFORMATION,
00806
PsProcessType,
00807 PreviousMode,
00808 (PVOID *)&Process,
00809
NULL
00810 );
00811
00812
if ( !
NT_SUCCESS(st) ) {
00813
return st;
00814 }
00815
00816
00817
00818
00819
00820 SysUserTime.KernelTime.QuadPart = UInt32x32To64(Process->Pcb.KernelTime,
00821
KeMaximumIncrement);
00822
00823 SysUserTime.UserTime.QuadPart = UInt32x32To64(Process->Pcb.UserTime,
00824
KeMaximumIncrement);
00825
00826 SysUserTime.CreateTime = Process->CreateTime;
00827 SysUserTime.ExitTime = Process->ExitTime;
00828
00829
ObDereferenceObject(Process);
00830
00831
00832
00833
00834
00835
00836
00837
try {
00838 *(PKERNEL_USER_TIMES) ProcessInformation = SysUserTime;
00839
00840
if (ARGUMENT_PRESENT(ReturnLength) ) {
00841 *ReturnLength =
sizeof(KERNEL_USER_TIMES);
00842 }
00843 } except(
EXCEPTION_EXECUTE_HANDLER) {
00844
return STATUS_SUCCESS;
00845 }
00846
00847
return STATUS_SUCCESS;
00848
00849
case ProcessDebugPort :
00850
00851
00852
00853
00854
00855
00856
00857
if ( ProcessInformationLength != (ULONG)
sizeof(HANDLE) ) {
00858
return STATUS_INFO_LENGTH_MISMATCH;
00859 }
00860
00861 st =
ObReferenceObjectByHandle(
00862 ProcessHandle,
00863 PROCESS_QUERY_INFORMATION,
00864
PsProcessType,
00865 PreviousMode,
00866 (PVOID *)&Process,
00867
NULL
00868 );
00869
00870
if ( !
NT_SUCCESS(st) ) {
00871
return st;
00872 }
00873
00874
if (Process->DebugPort ==
NULL) {
00875
00876
DebugPort =
NULL;
00877
00878 }
else if (ProcessInformationLength == (ULONG)
sizeof(HANDLE)) {
00879
00880
DebugPort = (HANDLE)-1;
00881
00882 }
00883
00884
ObDereferenceObject(Process);
00885
00886
00887
00888
00889
00890
00891
00892
try {
00893 *(PHANDLE) ProcessInformation =
DebugPort;
00894
00895
if (ARGUMENT_PRESENT(ReturnLength) ) {
00896 *ReturnLength =
sizeof(HANDLE);
00897 }
00898 } except(
EXCEPTION_EXECUTE_HANDLER) {
00899
return STATUS_ACCESS_VIOLATION;
00900 }
00901
00902
return STATUS_SUCCESS;
00903
00904
case ProcessHandleCount :
00905
00906
if ( ProcessInformationLength != (ULONG)
sizeof(ULONG) ) {
00907
return STATUS_INFO_LENGTH_MISMATCH;
00908 }
00909
00910 st =
ObReferenceObjectByHandle(
00911 ProcessHandle,
00912 PROCESS_QUERY_INFORMATION,
00913
PsProcessType,
00914 PreviousMode,
00915 (PVOID *)&Process,
00916
NULL
00917 );
00918
00919
if ( !
NT_SUCCESS(st) ) {
00920
return st;
00921 }
00922
00923
KeWaitForSingleObject( &
ObpInitKillMutant,
00924
Executive,
00925
KernelMode,
00926
FALSE,
00927
NULL
00928 );
00929
00930 Ht = (
PHANDLE_TABLE)Process->ObjectTable;
00931
00932
if ( Ht ) {
00933 HandleCount = Ht->
HandleCount;
00934 }
00935
else {
00936 HandleCount = 0;
00937 }
00938
00939
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00940
00941
ObDereferenceObject(Process);
00942
00943
00944
00945
00946
00947
00948
00949
try {
00950 *(PULONG) ProcessInformation = HandleCount;
00951
00952
if (ARGUMENT_PRESENT(ReturnLength) ) {
00953 *ReturnLength =
sizeof(HANDLE);
00954 }
00955 } except(
EXCEPTION_EXECUTE_HANDLER) {
00956
return STATUS_SUCCESS;
00957 }
00958
00959
return STATUS_SUCCESS;
00960
00961
case ProcessLdtInformation :
00962
00963 st =
ObReferenceObjectByHandle(
00964 ProcessHandle,
00965 PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
00966
PsProcessType,
00967 PreviousMode,
00968 (PVOID *)&Process,
00969
NULL
00970 );
00971
00972
if ( !
NT_SUCCESS(st) ) {
00973
return st;
00974 }
00975
00976
try {
00977
00978 st =
PspQueryLdtInformation(
00979 Process,
00980 ProcessInformation,
00981 ProcessInformationLength,
00982 ReturnLength
00983 );
00984
00985 } except(
EXCEPTION_EXECUTE_HANDLER) {
00986 st = STATUS_SUCCESS;
00987 }
00988
00989
ObDereferenceObject(Process);
00990
return st;
00991
00992
00993
case ProcessWx86Information :
00994
00995
if ( ProcessInformationLength !=
sizeof(HANDLE) ) {
00996
return STATUS_INFO_LENGTH_MISMATCH;
00997 }
00998
00999 Wx86Info =
NULL;
01000
01001
#ifndef i386
01002
st =
ObReferenceObjectByHandle(
01003 ProcessHandle,
01004 PROCESS_QUERY_INFORMATION,
01005
PsProcessType,
01006 PreviousMode,
01007 (PVOID *)&Process,
01008
NULL
01009 );
01010
01011
if ( !
NT_SUCCESS(st) ) {
01012
return st;
01013 }
01014
01015
if ((ULONG_PTR)Process->VdmObjects ==
sizeof(WX86TIB)) {
01016 Wx86Info = Process->VdmObjects;
01017 }
01018
01019
ObDereferenceObject(Process);
01020
#endif
01021
01022
try {
01023 *(PHANDLE) ProcessInformation = Wx86Info;
01024
01025
if (ARGUMENT_PRESENT(ReturnLength) ) {
01026 *ReturnLength =
sizeof(HANDLE);
01027 }
01028 } except(
EXCEPTION_EXECUTE_HANDLER) {
01029
return STATUS_SUCCESS;
01030 }
01031
01032
return STATUS_SUCCESS;
01033
01034
case ProcessPriorityBoost:
01035
if ( ProcessInformationLength !=
sizeof(ULONG) ) {
01036
return STATUS_INFO_LENGTH_MISMATCH;
01037 }
01038
01039 st =
ObReferenceObjectByHandle(
01040 ProcessHandle,
01041 PROCESS_QUERY_INFORMATION,
01042
PsProcessType,
01043 PreviousMode,
01044 (PVOID *)&Process,
01045
NULL
01046 );
01047
01048
if ( !
NT_SUCCESS(st) ) {
01049
return st;
01050 }
01051
01052 DisableBoost = Process->Pcb.DisableBoost ? 1 : 0;
01053
01054
ObDereferenceObject(Process);
01055
01056
try {
01057 *(PULONG)ProcessInformation = DisableBoost;
01058
01059
if (ARGUMENT_PRESENT(ReturnLength) ) {
01060 *ReturnLength =
sizeof(ULONG);
01061 }
01062 } except(
EXCEPTION_EXECUTE_HANDLER) {
01063
return GetExceptionCode();
01064 }
01065
01066
return st;
01067
01068
case ProcessDeviceMap:
01069 DeviceMapInfo = (PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation;
01070
if ( ProcessInformationLength !=
sizeof(DeviceMapInfo->Query) ) {
01071
return STATUS_INFO_LENGTH_MISMATCH;
01072 }
01073
01074 st =
ObReferenceObjectByHandle(
01075 ProcessHandle,
01076 PROCESS_QUERY_INFORMATION,
01077
PsProcessType,
01078 PreviousMode,
01079 (PVOID *)&Process,
01080
NULL
01081 );
01082
01083
if ( !
NT_SUCCESS(st) ) {
01084
return st;
01085 }
01086
01087 st =
ObQueryDeviceMapInformation( Process, DeviceMapInfo );
01088
ObDereferenceObject(Process);
01089
return st;
01090
01091
case ProcessSessionInformation :
01092
01093
if ( ProcessInformationLength != (ULONG)
sizeof(PROCESS_SESSION_INFORMATION) ) {
01094
return STATUS_INFO_LENGTH_MISMATCH;
01095 }
01096
01097 st =
ObReferenceObjectByHandle(
01098 ProcessHandle,
01099 PROCESS_QUERY_INFORMATION,
01100
PsProcessType,
01101 PreviousMode,
01102 (PVOID *)&Process,
01103
NULL
01104 );
01105
if ( !
NT_SUCCESS(st) ) {
01106
return st;
01107 }
01108
01109 SessionInfo.SessionId = Process->SessionId;
01110
01111
ObDereferenceObject(Process);
01112
01113
try {
01114 *(PPROCESS_SESSION_INFORMATION) ProcessInformation = SessionInfo;
01115
01116
if (ARGUMENT_PRESENT(ReturnLength) ) {
01117 *ReturnLength =
sizeof(PROCESS_SESSION_INFORMATION);
01118 }
01119 } except(
EXCEPTION_EXECUTE_HANDLER) {
01120
return STATUS_SUCCESS;
01121 }
01122
01123
return( STATUS_SUCCESS );
01124
01125
01126
01127
case ProcessPriorityClass:
01128
01129
if ( ProcessInformationLength !=
sizeof(PROCESS_PRIORITY_CLASS) ) {
01130
return STATUS_INFO_LENGTH_MISMATCH;
01131 }
01132
01133 st =
ObReferenceObjectByHandle(
01134 ProcessHandle,
01135 PROCESS_QUERY_INFORMATION,
01136
PsProcessType,
01137 PreviousMode,
01138 (PVOID *)&Process,
01139
NULL
01140 );
01141
if ( !
NT_SUCCESS(st) ) {
01142
return st;
01143 }
01144
01145 PriorityClass.Foreground =
FALSE;
01146 PriorityClass.PriorityClass = Process->PriorityClass;
01147
01148
ObDereferenceObject(Process);
01149
01150
try {
01151 *(PPROCESS_PRIORITY_CLASS) ProcessInformation = PriorityClass;
01152
01153
if (ARGUMENT_PRESENT(ReturnLength) ) {
01154 *ReturnLength =
sizeof(PROCESS_PRIORITY_CLASS);
01155 }
01156 } except(
EXCEPTION_EXECUTE_HANDLER) {
01157
return STATUS_SUCCESS;
01158 }
01159
01160
return( STATUS_SUCCESS );
01161
01162
01163
case ProcessWow64Information:
01164
01165
if ( ProcessInformationLength !=
sizeof(ULONG_PTR) ) {
01166
return STATUS_INFO_LENGTH_MISMATCH;
01167 }
01168
01169 st =
ObReferenceObjectByHandle(
01170 ProcessHandle,
01171 PROCESS_QUERY_INFORMATION,
01172
PsProcessType,
01173 PreviousMode,
01174 (PVOID *)&Process,
01175
NULL
01176 );
01177
if ( !
NT_SUCCESS(st) ) {
01178
return st;
01179 }
01180
01181 Wow64Info = 0;
01182
01183
if (Process->Wow64Process !=
NULL) {
01184 Wow64Info = (ULONG_PTR)(Process->Wow64Process->Wow64);
01185 }
01186
01187
01188
ObDereferenceObject(Process);
01189
01190
try {
01191 *(PULONG_PTR)ProcessInformation = Wow64Info;
01192
01193
if (ARGUMENT_PRESENT(ReturnLength) ) {
01194 *ReturnLength =
sizeof(ULONG_PTR);
01195 }
01196 } except(
EXCEPTION_EXECUTE_HANDLER) {
01197
return STATUS_SUCCESS;
01198 }
01199
01200
return( STATUS_SUCCESS );
01201
01202
01203
default:
01204
01205
return STATUS_INVALID_INFO_CLASS;
01206 }
01207
01208 }
01209
01210
NTSTATUS
01211 PspSetQuotaLimits(
01212 IN HANDLE ProcessHandle,
01213 IN PROCESSINFOCLASS ProcessInformationClass,
01214 IN PVOID ProcessInformation,
01215 IN ULONG ProcessInformationLength,
01216 IN KPROCESSOR_MODE PreviousMode
01217 )
01218 {
01219
PEPROCESS Process;
01220 QUOTA_LIMITS RequestedLimits;
01221 KIRQL OldIrql;
01222
PEPROCESS_QUOTA_BLOCK NewQuotaBlock;
01223 BOOLEAN HasPrivilege =
FALSE;
01224
NTSTATUS st, ReturnStatus;
01225 PVOID UnlockHandle;
01226 SIZE_T NewLimit;
01227
01228
if ( ProcessInformationLength !=
sizeof(QUOTA_LIMITS) ) {
01229
return STATUS_INFO_LENGTH_MISMATCH;
01230 }
01231
01232
try {
01233 RequestedLimits = *(PQUOTA_LIMITS) ProcessInformation;
01234 } except(
EXCEPTION_EXECUTE_HANDLER) {
01235
return GetExceptionCode();
01236 }
01237
01238 st =
ObReferenceObjectByHandle(
01239 ProcessHandle,
01240 PROCESS_SET_QUOTA,
01241
PsProcessType,
01242 PreviousMode,
01243 (PVOID *)&Process,
01244
NULL
01245 );
01246
01247
if ( !
NT_SUCCESS(st) ) {
01248
return st;
01249 }
01250
01251 UnlockHandle =
NULL;
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269 ReturnStatus = STATUS_SUCCESS;
01270
01271
if ( Process->QuotaBlock == &
PspDefaultQuotaBlock ) {
01272
if ( RequestedLimits.MinimumWorkingSetSize &&
01273 RequestedLimits.MaximumWorkingSetSize ) {
01274
01275
if ( RequestedLimits.MinimumWorkingSetSize != (SIZE_T)-1 &&
01276 RequestedLimits.MaximumWorkingSetSize != (SIZE_T)-1 ) {
01277
if ( Process->Job ) {
01278
KeEnterCriticalRegion();
01279
ExAcquireResourceShared(&Process->Job->JobLock,
TRUE);
01280
01281
if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) {
01282 RequestedLimits.MinimumWorkingSetSize = Process->Job->MinimumWorkingSetSize;
01283 RequestedLimits.MaximumWorkingSetSize = Process->Job->MaximumWorkingSetSize;
01284 }
01285
01286
ExReleaseResource(&Process->Job->JobLock);
01287
KeLeaveCriticalRegion();
01288 }
01289 }
01290
01291
KeAttachProcess (&Process->Pcb);
01292 ReturnStatus =
MmAdjustWorkingSetSize (
01293 RequestedLimits.MinimumWorkingSetSize,
01294 RequestedLimits.MaximumWorkingSetSize,
01295
FALSE
01296 );
01297
KeDetachProcess();
01298
01299 }
else {
01300
01301
01302
01303
01304
01305
01306
if ( !
SeSinglePrivilegeCheck(
SeIncreaseQuotaPrivilege,PreviousMode) ) {
01307
ObDereferenceObject(Process);
01308
return STATUS_PRIVILEGE_NOT_HELD;
01309 }
01310
01311 NewQuotaBlock =
ExAllocatePool(
NonPagedPool,
sizeof(*NewQuotaBlock));
01312
if ( !NewQuotaBlock ) {
01313
ObDereferenceObject(Process);
01314
return STATUS_NO_MEMORY;
01315 }
01316 RtlZeroMemory(NewQuotaBlock,
sizeof(*NewQuotaBlock));
01317
01318
01319
01320
01321
01322
KeInitializeSpinLock(&NewQuotaBlock->QuotaLock);
01323 NewQuotaBlock->ReferenceCount = 1;
01324
01325
01326
01327
01328
01329
MmLockPagableSectionByHandle(
ExPageLockHandle);
01330 UnlockHandle =
ExPageLockHandle;
01331
01332 ExAcquireSpinLock(&
PspDefaultQuotaBlock.
QuotaLock, &OldIrql );
01333
01334
01335 NewQuotaBlock->QuotaPeakPoolUsage[
NonPagedPool] = Process->QuotaPeakPoolUsage[
NonPagedPool];
01336 NewQuotaBlock->QuotaPeakPoolUsage[
PagedPool] = Process->QuotaPeakPoolUsage[
PagedPool];
01337 NewQuotaBlock->QuotaPoolUsage[
NonPagedPool] = Process->QuotaPoolUsage[
NonPagedPool];
01338 NewQuotaBlock->QuotaPoolUsage[
PagedPool] = Process->QuotaPoolUsage[
PagedPool];
01339
01340 NewQuotaBlock->PagefileUsage = Process->PagefileUsage;
01341 NewQuotaBlock->PeakPagefileUsage = Process->PeakPagefileUsage;
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 NewQuotaBlock->QuotaPoolLimit[
PagedPool] =
PspDefaultPagedLimit;
01354 NewQuotaBlock->QuotaPoolLimit[
NonPagedPool] =
PspDefaultNonPagedLimit;
01355 NewQuotaBlock->PagefileLimit =
PspDefaultPagefileLimit;
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
if ( NewQuotaBlock->QuotaPoolUsage[
PagedPool] > NewQuotaBlock->QuotaPoolLimit[
PagedPool] ) {
01367
01368
while ( (
PspDefaultPagedLimit == 0) &&
MmRaisePoolQuota(
PagedPool,NewQuotaBlock->QuotaPoolLimit[
PagedPool],&NewLimit) ) {
01369 NewQuotaBlock->QuotaPoolLimit[
PagedPool] = NewLimit;
01370
if ( NewQuotaBlock->QuotaPoolUsage[
PagedPool] <= NewLimit ) {
01371
goto LimitRaised0;
01372 }
01373 }
01374
01375
01376
01377
01378
01379 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql );
01380
MmUnlockPagableImageSection(UnlockHandle);
01381
ExFreePool(NewQuotaBlock);
01382
ObDereferenceObject(Process);
01383
return STATUS_QUOTA_EXCEEDED;
01384 }
01385
01386
01387
01388
01389
01390 LimitRaised0:
01391
if ( NewQuotaBlock->QuotaPoolUsage[
NonPagedPool] > NewQuotaBlock->QuotaPoolLimit[
NonPagedPool] ) {
01392
01393
while ( (
PspDefaultNonPagedLimit == 0) &&
MmRaisePoolQuota(
NonPagedPool,NewQuotaBlock->QuotaPoolLimit[
NonPagedPool],&NewLimit) ) {
01394 NewQuotaBlock->QuotaPoolLimit[
NonPagedPool] = NewLimit;
01395
if ( NewQuotaBlock->QuotaPoolUsage[
NonPagedPool] <= NewLimit ) {
01396
goto LimitRaised1;
01397 }
01398 }
01399
01400
01401
01402
01403
01404 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql );
01405
MmUnlockPagableImageSection(UnlockHandle);
01406
ExFreePool(NewQuotaBlock);
01407
ObDereferenceObject(Process);
01408
return STATUS_QUOTA_EXCEEDED;
01409 }
01410
01411
01412
01413
01414
01415 LimitRaised1:
01416
if ( NewQuotaBlock->PagefileUsage > NewQuotaBlock->PagefileLimit ) {
01417
01418
01419
01420
01421
01422 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql );
01423
MmUnlockPagableImageSection(UnlockHandle);
01424
ExFreePool(NewQuotaBlock);
01425
ObDereferenceObject(Process);
01426
return STATUS_QUOTA_EXCEEDED;
01427 }
01428
01429
01430
01431
01432
01433
01434
if ( Process->QuotaBlock != &
PspDefaultQuotaBlock ) {
01435 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql );
01436
ExFreePool(NewQuotaBlock);
01437 }
else {
01438
01439
01440
01441
01442
01443
01444
if ( Process->QuotaPoolUsage[
NonPagedPool] <=
PspDefaultQuotaBlock.
QuotaPoolUsage[
NonPagedPool] ) {
01445
PspDefaultQuotaBlock.
QuotaPoolUsage[
NonPagedPool] -= Process->QuotaPoolUsage[
NonPagedPool];
01446 }
01447
else {
01448
PspDefaultQuotaBlock.
QuotaPoolUsage[
NonPagedPool] = 0;
01449 }
01450
01451
if ( Process->QuotaPoolUsage[
PagedPool] <=
PspDefaultQuotaBlock.
QuotaPoolUsage[
PagedPool] ) {
01452
PspDefaultQuotaBlock.
QuotaPoolUsage[
PagedPool] -= Process->QuotaPoolUsage[
PagedPool];
01453 }
01454
else {
01455
PspDefaultQuotaBlock.
QuotaPoolUsage[
PagedPool] = 0;
01456 }
01457
01458
if ( Process->PagefileUsage <=
PspDefaultQuotaBlock.
PagefileUsage ) {
01459
PspDefaultQuotaBlock.
PagefileUsage -= Process->PagefileUsage;
01460 }
01461
01462 Process->QuotaBlock = NewQuotaBlock;
01463 ExReleaseSpinLock(&
PspDefaultQuotaBlock.
QuotaLock,OldIrql );
01464 }
01465
MmUnlockPagableImageSection(UnlockHandle);
01466 ReturnStatus = STATUS_SUCCESS;
01467 }
01468 }
else {
01469
01470
01471
01472
01473
01474
if ( RequestedLimits.MinimumWorkingSetSize &&
01475 RequestedLimits.MaximumWorkingSetSize ) {
01476
01477
if ( RequestedLimits.MinimumWorkingSetSize != (SIZE_T)-1 &&
01478 RequestedLimits.MaximumWorkingSetSize != (SIZE_T)-1 ) {
01479
if ( Process->Job ) {
01480
KeEnterCriticalRegion();
01481
ExAcquireResourceShared(&Process->Job->JobLock,
TRUE);
01482
01483
if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_WORKINGSET ) {
01484 RequestedLimits.MinimumWorkingSetSize = Process->Job->MinimumWorkingSetSize;
01485 RequestedLimits.MaximumWorkingSetSize = Process->Job->MaximumWorkingSetSize;
01486 }
01487
01488
ExReleaseResource(&Process->Job->JobLock);
01489
KeLeaveCriticalRegion();
01490 }
01491 }
01492
01493
KeAttachProcess (&Process->Pcb);
01494 ReturnStatus =
MmAdjustWorkingSetSize (
01495 RequestedLimits.MinimumWorkingSetSize,
01496 RequestedLimits.MaximumWorkingSetSize,
01497
FALSE
01498 );
01499
KeDetachProcess();
01500
01501 }
01502 }
01503
ObDereferenceObject(Process);
01504
01505
return ReturnStatus;
01506
01507 }
01508
01509
NTSTATUS
01510 NtSetInformationProcess(
01511 IN HANDLE ProcessHandle,
01512 IN PROCESSINFOCLASS ProcessInformationClass,
01513 IN PVOID ProcessInformation,
01514 IN ULONG ProcessInformationLength
01515 )
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542 {
01543
01544
PEPROCESS Process;
01545
PETHREAD Thread;
01546
KPROCESSOR_MODE PreviousMode;
01547
NTSTATUS st;
01548 KPRIORITY BasePriority;
01549 ULONG BoostValue;
01550 ULONG DefaultHardErrorMode;
01551 PVOID
DebugPort;
01552 PVOID ExceptionPort;
01553 HANDLE DebugPortHandle;
01554 BOOLEAN EnableAlignmentFaultFixup;
01555 HANDLE ExceptionPortHandle;
01556 ULONG ProbeAlignment;
01557 HANDLE PrimaryTokenHandle;
01558 BOOLEAN HasPrivilege =
FALSE;
01559 BOOLEAN IsChildToken =
FALSE;
01560 PLIST_ENTRY Next;
01561 UCHAR MemoryPriority;
01562 PROCESS_PRIORITY_CLASS LocalPriorityClass;
01563 PROCESS_FOREGROUND_BACKGROUND LocalForeground;
01564 HANDLE Wx86Info;
01565 KAFFINITY Affinity, AffinityWithMasks;
01566 ULONG_PTR BigAffinity;
01567 ULONG DisableBoost;
01568 BOOLEAN bDisableBoost;
01569 PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo;
01570 HANDLE
DirectoryHandle;
01571 PROCESS_SESSION_INFORMATION SessionInfo;
01572 ULONG BytesCopied;
01573 PACCESS_TOKEN
Token;
01574
01575
PAGED_CODE();
01576
01577
01578
01579
01580
01581 PreviousMode = KeGetPreviousMode();
01582
if (PreviousMode !=
KernelMode) {
01583
01584
if (ProcessInformationClass == ProcessBasePriority) {
01585 ProbeAlignment =
sizeof(KPRIORITY);
01586
01587 }
else if (ProcessInformationClass == ProcessEnableAlignmentFaultFixup) {
01588 ProbeAlignment =
sizeof(BOOLEAN);
01589 }
else if (ProcessInformationClass == ProcessForegroundInformation) {
01590 ProbeAlignment =
sizeof(PROCESS_FOREGROUND_BACKGROUND);
01591 }
else if (ProcessInformationClass == ProcessPriorityClass) {
01592 ProbeAlignment =
sizeof(BOOLEAN);
01593 }
else if (ProcessInformationClass == ProcessAffinityMask) {
01594 ProbeAlignment =
sizeof (ULONG_PTR);
01595 }
else {
01596 ProbeAlignment =
sizeof(ULONG);
01597 }
01598
01599
try {
01600
ProbeForRead(
01601 ProcessInformation,
01602 ProcessInformationLength,
01603 ProbeAlignment
01604 );
01605 } except(
EXCEPTION_EXECUTE_HANDLER) {
01606
return GetExceptionCode();
01607 }
01608 }
01609
01610
01611
01612
01613
01614
switch ( ProcessInformationClass ) {
01615
01616
case ProcessWorkingSetWatch:
01617 {
01618 PPAGEFAULT_HISTORY WorkingSetCatcher;
01619
01620 st =
ObReferenceObjectByHandle(
01621 ProcessHandle,
01622 PROCESS_SET_INFORMATION,
01623
PsProcessType,
01624 PreviousMode,
01625 (PVOID *)&Process,
01626
NULL
01627 );
01628
01629
if ( !
NT_SUCCESS(st) ) {
01630
return st;
01631 }
01632
01633 WorkingSetCatcher =
ExAllocatePool(
NonPagedPool,
WS_CATCH_SIZE);
01634
if ( !WorkingSetCatcher ) {
01635
ObDereferenceObject(Process);
01636
return STATUS_NO_MEMORY;
01637 }
01638
01639
PsWatchEnabled =
TRUE;
01640 WorkingSetCatcher->CurrentIndex = 0;
01641 WorkingSetCatcher->MaxIndex =
MAX_WS_CATCH_INDEX;
01642
01643 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
01644
01645
if ( st != STATUS_SUCCESS ) {
01646
ExFreePool(WorkingSetCatcher);
01647
ObDereferenceObject( Process );
01648
return STATUS_PROCESS_IS_TERMINATING;
01649 }
01650
01651
if ( Process->WorkingSetWatch ) {
01652
PsUnlockProcess(Process);
01653
ExFreePool(WorkingSetCatcher);
01654
ObDereferenceObject(Process);
01655
return STATUS_PORT_ALREADY_SET;
01656 }
01657
01658
KeInitializeSpinLock(&WorkingSetCatcher->SpinLock);
01659 Process->WorkingSetWatch = WorkingSetCatcher;
01660
01661
PsUnlockProcess(Process);
01662
01663
ObDereferenceObject(Process);
01664
01665
return STATUS_SUCCESS;
01666 }
01667
01668
case ProcessBasePriority:
01669 {
01670
01671
01672
01673
01674
01675
01676
if ( ProcessInformationLength !=
sizeof(KPRIORITY) ) {
01677
return STATUS_INFO_LENGTH_MISMATCH;
01678 }
01679
01680
try {
01681 BasePriority = *(KPRIORITY *)ProcessInformation;
01682 } except(
EXCEPTION_EXECUTE_HANDLER) {
01683
return GetExceptionCode();
01684 }
01685
01686
if ( BasePriority & 0x80000000 ) {
01687 MemoryPriority =
MEMORY_PRIORITY_FOREGROUND;
01688 BasePriority &= ~0x80000000;
01689 }
01690
else {
01691 MemoryPriority =
MEMORY_PRIORITY_BACKGROUND;
01692 }
01693
01694
if ( BasePriority > HIGH_PRIORITY ||
01695 BasePriority <= LOW_PRIORITY ) {
01696
01697
return STATUS_INVALID_PARAMETER;
01698 }
01699
01700 st =
ObReferenceObjectByHandle(
01701 ProcessHandle,
01702 PROCESS_SET_INFORMATION,
01703
PsProcessType,
01704 PreviousMode,
01705 (PVOID *)&Process,
01706
NULL
01707 );
01708
01709
if ( !
NT_SUCCESS(st) ) {
01710
return st;
01711 }
01712
01713
01714
if ( BasePriority > Process->Pcb.BasePriority ) {
01715
01716
01717
01718
01719
01720
01721
01722 HasPrivilege =
SeCheckPrivilegedObject(
01723
SeIncreaseBasePriorityPrivilege,
01724 ProcessHandle,
01725 PROCESS_SET_INFORMATION,
01726 PreviousMode
01727 );
01728
01729
if (!HasPrivilege) {
01730
01731
ObDereferenceObject(Process);
01732
return STATUS_PRIVILEGE_NOT_HELD;
01733 }
01734 }
01735
01736
KeSetPriorityProcess(&Process->Pcb,BasePriority);
01737
MmSetMemoryPriorityProcess(Process, MemoryPriority);
01738
ObDereferenceObject(Process);
01739
01740
return STATUS_SUCCESS;
01741 }
01742
01743
case ProcessPriorityClass:
01744 {
01745
if ( ProcessInformationLength !=
sizeof(PROCESS_PRIORITY_CLASS) ) {
01746
return STATUS_INFO_LENGTH_MISMATCH;
01747 }
01748
01749
try {
01750 LocalPriorityClass = *(PPROCESS_PRIORITY_CLASS)ProcessInformation;
01751 } except(
EXCEPTION_EXECUTE_HANDLER) {
01752
return GetExceptionCode();
01753 }
01754
01755
if ( LocalPriorityClass.PriorityClass > PROCESS_PRIORITY_CLASS_ABOVE_NORMAL ) {
01756
return STATUS_INVALID_PARAMETER;
01757 }
01758
01759 st =
ObReferenceObjectByHandle(
01760 ProcessHandle,
01761 PROCESS_SET_INFORMATION,
01762
PsProcessType,
01763 PreviousMode,
01764 (PVOID *)&Process,
01765
NULL
01766 );
01767
01768
if ( !
NT_SUCCESS(st) ) {
01769
return st;
01770 }
01771
01772
01773
if ( LocalPriorityClass.PriorityClass != Process->PriorityClass &&
01774 LocalPriorityClass.PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME ) {
01775
01776
01777
01778
01779
01780
01781
01782 HasPrivilege =
SeCheckPrivilegedObject(
01783
SeIncreaseBasePriorityPrivilege,
01784 ProcessHandle,
01785 PROCESS_SET_INFORMATION,
01786 PreviousMode
01787 );
01788
01789
if (!HasPrivilege) {
01790
01791
ObDereferenceObject(Process);
01792
return STATUS_PRIVILEGE_NOT_HELD;
01793 }
01794 }
01795
01796
01797
01798
01799
01800
if ( Process->Job ) {
01801
KeEnterCriticalRegion();
01802
ExAcquireResourceShared(&Process->Job->JobLock,
TRUE);
01803
01804
if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS ) {
01805 LocalPriorityClass.PriorityClass = Process->Job->PriorityClass;
01806 }
01807
01808
ExReleaseResource(&Process->Job->JobLock);
01809
KeLeaveCriticalRegion();
01810 }
01811
01812 Process->PriorityClass = LocalPriorityClass.PriorityClass;
01813
01814
PsSetProcessPriorityByClass(Process, LocalPriorityClass.Foreground ?
01815
PsProcessPriorityForeground :
PsProcessPriorityBackground);
01816
01817
ObDereferenceObject(Process);
01818
01819
return STATUS_SUCCESS;
01820 }
01821
01822
case ProcessForegroundInformation:
01823 {
01824
01825
if ( ProcessInformationLength !=
sizeof(PROCESS_FOREGROUND_BACKGROUND) ) {
01826
return STATUS_INFO_LENGTH_MISMATCH;
01827 }
01828
01829
try {
01830 LocalForeground = *(PPROCESS_FOREGROUND_BACKGROUND)ProcessInformation;
01831 } except(
EXCEPTION_EXECUTE_HANDLER) {
01832
return GetExceptionCode();
01833 }
01834
01835 st =
ObReferenceObjectByHandle(
01836 ProcessHandle,
01837 PROCESS_SET_INFORMATION,
01838
PsProcessType,
01839 PreviousMode,
01840 (PVOID *)&Process,
01841
NULL
01842 );
01843
01844
if ( !
NT_SUCCESS(st) ) {
01845
return st;
01846 }
01847
01848
01849
PsSetProcessPriorityByClass(Process, LocalForeground.Foreground ?
01850
PsProcessPriorityForeground :
PsProcessPriorityBackground);
01851
01852
ObDereferenceObject(Process);
01853
01854
return STATUS_SUCCESS;
01855 }
01856
01857
case ProcessRaisePriority:
01858 {
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
if ( ProcessInformationLength !=
sizeof(ULONG) ) {
01869
return STATUS_INFO_LENGTH_MISMATCH;
01870 }
01871
01872
try {
01873 BoostValue = *(PULONG)ProcessInformation;
01874 } except(
EXCEPTION_EXECUTE_HANDLER) {
01875
return GetExceptionCode();
01876 }
01877
01878 st =
ObReferenceObjectByHandle(
01879 ProcessHandle,
01880 PROCESS_SET_INFORMATION,
01881
PsProcessType,
01882 PreviousMode,
01883 (PVOID *)&Process,
01884
NULL
01885 );
01886
01887
if ( !
NT_SUCCESS(st) ) {
01888
return st;
01889 }
01890
01891
01892
01893
01894
01895
01896
01897 st =
PsLockProcess(Process,
KernelMode,
PsLockReturnTimeout);
01898
01899
if ( st != STATUS_SUCCESS ) {
01900
ObDereferenceObject( Process );
01901
return( st );
01902 }
01903
01904 Next = Process->ThreadListHead.Flink;
01905
01906
while ( Next != &Process->ThreadListHead) {
01907 Thread = (
PETHREAD)(CONTAINING_RECORD(Next,
ETHREAD,ThreadListEntry));
01908
KeBoostPriorityThread(&Thread->
Tcb,(KPRIORITY)BoostValue);
01909 Next = Next->Flink;
01910 }
01911
01912
PsUnlockProcess(Process);
01913
01914
ObDereferenceObject(Process);
01915
01916
return STATUS_SUCCESS;
01917 }
01918
01919
case ProcessDefaultHardErrorMode:
01920 {
01921
if ( ProcessInformationLength !=
sizeof(ULONG) ) {
01922
return STATUS_INFO_LENGTH_MISMATCH;
01923 }
01924
01925
try {
01926 DefaultHardErrorMode = *(PULONG)ProcessInformation;
01927 } except(
EXCEPTION_EXECUTE_HANDLER) {
01928
return GetExceptionCode();
01929 }
01930
01931 st =
ObReferenceObjectByHandle(
01932 ProcessHandle,
01933 PROCESS_SET_INFORMATION,
01934
PsProcessType,
01935 PreviousMode,
01936 (PVOID *)&Process,
01937
NULL
01938 );
01939
01940
if ( !
NT_SUCCESS(st) ) {
01941
return st;
01942 }
01943
01944 Process->DefaultHardErrorProcessing = DefaultHardErrorMode;
01945
if (DefaultHardErrorMode & PROCESS_HARDERROR_ALIGNMENT_BIT) {
01946
KeSetAutoAlignmentProcess(&Process->Pcb,
TRUE);
01947 }
01948
else {
01949
KeSetAutoAlignmentProcess(&Process->Pcb,
FALSE);
01950 }
01951
01952
ObDereferenceObject(Process);
01953
01954
return STATUS_SUCCESS;
01955 }
01956
01957
case ProcessQuotaLimits:
01958 {
01959
return PspSetQuotaLimits(
01960 ProcessHandle,
01961 ProcessInformationClass,
01962 ProcessInformation,
01963 ProcessInformationLength,
01964 PreviousMode
01965 );
01966 }
01967
01968
case ProcessDebugPort :
01969 {
01970
if ( ProcessInformationLength !=
sizeof(HANDLE) ) {
01971
return STATUS_INFO_LENGTH_MISMATCH;
01972 }
01973
01974
try {
01975 DebugPortHandle = *(PHANDLE) ProcessInformation;
01976 } except(
EXCEPTION_EXECUTE_HANDLER) {
01977
return GetExceptionCode();
01978 }
01979
01980
if ( DebugPortHandle ) {
01981 st =
ObReferenceObjectByHandle (
01982 DebugPortHandle,
01983 0,
01984
LpcPortObjectType,
01985 PreviousMode,
01986 (PVOID *)&
DebugPort,
01987
NULL
01988 );
01989
if ( !
NT_SUCCESS(st) ) {
01990
return st;
01991 }
01992 }
else {
01993
return STATUS_INVALID_PARAMETER;
01994 }
01995
01996 st =
ObReferenceObjectByHandle(
01997 ProcessHandle,
01998 PROCESS_SET_PORT,
01999
PsProcessType,
02000 PreviousMode,
02001 (PVOID *)&Process,
02002
NULL
02003 );
02004
02005
if ( !
NT_SUCCESS(st) ) {
02006
if (
DebugPort ) {
02007
ObDereferenceObject(
DebugPort);
02008 }
02009
return st;
02010 }
02011
02012
02013
02014
02015
02016
02017
if ( InterlockedCompareExchangePointer(&Process->DebugPort,
DebugPort,
NULL) ==
NULL ) {
02018
02019
if ( (Process->ExitTime.QuadPart != 0 ||
KeReadStateProcess(&Process->Pcb) !=
FALSE) ) {
02020
DebugPort = InterlockedExchangePointer(&Process->DebugPort,
NULL);
02021
if (
DebugPort ) {
02022
ObDereferenceObject(
DebugPort);
02023 }
02024
ObDereferenceObject( Process );
02025
return STATUS_PROCESS_IS_TERMINATING;
02026 }
02027 }
02028
else {
02029
ObDereferenceObject(Process);
02030
ObDereferenceObject(
DebugPort);
02031
return STATUS_PORT_ALREADY_SET;
02032 }
02033
02034
KeAttachProcess (&Process->Pcb);
02035
if (Process->Peb !=
NULL) {
02036 Process->Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort !=
NULL ?
TRUE :
FALSE);
02037
#if defined(_WIN64)
02038
if (Process->Wow64Process !=
NULL) {
02039 PPEB32 Peb32 = (PPEB32)Process->Wow64Process->Wow64;
02040
if (Peb32 !=
NULL) {
02041 Peb32->BeingDebugged = Process->Peb->BeingDebugged;
02042 }
02043 }
02044
#endif
02045
}
02046
KeDetachProcess();
02047
02048
02049
ObDereferenceObject(Process);
02050
02051
return STATUS_SUCCESS;
02052 }
02053
02054
case ProcessExceptionPort :
02055 {
02056
if ( ProcessInformationLength !=
sizeof(HANDLE) ) {
02057
return STATUS_INFO_LENGTH_MISMATCH;
02058 }
02059
02060
try {
02061 ExceptionPortHandle = *(PHANDLE) ProcessInformation;
02062 } except(
EXCEPTION_EXECUTE_HANDLER) {
02063
return GetExceptionCode();
02064 }
02065
02066 st =
ObReferenceObjectByHandle (
02067 ExceptionPortHandle,
02068 0,
02069
LpcPortObjectType,
02070 PreviousMode,
02071 (PVOID *)&ExceptionPort,
02072
NULL
02073 );
02074
if ( !
NT_SUCCESS(st) ) {
02075
return st;
02076 }
02077
02078 st =
ObReferenceObjectByHandle(
02079 ProcessHandle,
02080 PROCESS_SET_PORT,
02081
PsProcessType,
02082 PreviousMode,
02083 (PVOID *)&Process,
02084
NULL
02085 );
02086
02087
if ( !
NT_SUCCESS(st) ) {
02088
ObDereferenceObject(ExceptionPort);
02089
return st;
02090 }
02091
02092 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02093
02094
if ( st != STATUS_SUCCESS ) {
02095
ObDereferenceObject(ExceptionPort);
02096
ObDereferenceObject( Process );
02097
return STATUS_PROCESS_IS_TERMINATING;
02098 }
02099
02100
if ( Process->ExceptionPort ) {
02101
ObDereferenceObject(Process);
02102
ObDereferenceObject(ExceptionPort);
02103
PsUnlockProcess(Process);
02104
return STATUS_PORT_ALREADY_SET;
02105 }
else {
02106 Process->ExceptionPort = ExceptionPort;
02107 }
02108
PsUnlockProcess(Process);
02109
02110
ObDereferenceObject(Process);
02111
02112
return STATUS_SUCCESS;
02113 }
02114
02115
case ProcessAccessToken :
02116 {
02117
02118
if ( ProcessInformationLength !=
sizeof(PROCESS_ACCESS_TOKEN) ) {
02119
return STATUS_INFO_LENGTH_MISMATCH;
02120 }
02121
02122
try {
02123 PrimaryTokenHandle = ((PROCESS_ACCESS_TOKEN *)ProcessInformation)->Token;
02124
02125 } except(
EXCEPTION_EXECUTE_HANDLER) {
02126
return GetExceptionCode();
02127 }
02128
02129
02130 st =
PspSetPrimaryToken(
02131 ProcessHandle,
02132 PrimaryTokenHandle,
02133
NULL );
02134
02135
return st;
02136 }
02137
02138
02139
case ProcessLdtInformation:
02140
02141 st =
ObReferenceObjectByHandle(
02142 ProcessHandle,
02143 PROCESS_SET_INFORMATION | PROCESS_VM_WRITE,
02144
PsProcessType,
02145 PreviousMode,
02146 (PVOID *)&Process,
02147
NULL
02148 );
02149
02150
if ( !
NT_SUCCESS(st) ) {
02151
return st;
02152 }
02153
02154
try {
02155 st =
PspSetLdtInformation(
02156 Process,
02157 ProcessInformation,
02158 ProcessInformationLength
02159 );
02160 } except (
EXCEPTION_EXECUTE_HANDLER) {
02161 st = STATUS_SUCCESS;
02162 }
02163
02164
ObDereferenceObject(Process);
02165
return st;
02166
02167
case ProcessLdtSize:
02168
02169 st =
ObReferenceObjectByHandle(
02170 ProcessHandle,
02171 PROCESS_SET_INFORMATION | PROCESS_VM_WRITE,
02172
PsProcessType,
02173 PreviousMode,
02174 (PVOID *)&Process,
02175
NULL
02176 );
02177
02178
if ( !
NT_SUCCESS(st) ) {
02179
return st;
02180 }
02181
02182
try {
02183
02184 st =
PspSetLdtSize(
02185 Process,
02186 ProcessInformation,
02187 ProcessInformationLength
02188 );
02189
02190 } except(
EXCEPTION_EXECUTE_HANDLER) {
02191
02192 st = GetExceptionCode();
02193
02194 }
02195
02196
ObDereferenceObject(Process);
02197
return st;
02198
02199
case ProcessIoPortHandlers:
02200
02201 st =
ObReferenceObjectByHandle(
02202 ProcessHandle,
02203 PROCESS_SET_INFORMATION,
02204
PsProcessType,
02205 PreviousMode,
02206 (PVOID *)&Process,
02207
NULL
02208 );
02209
02210
if ( !
NT_SUCCESS(st) ) {
02211
return st;
02212 }
02213
02214 st =
PspSetProcessIoHandlers(
02215 Process,
02216 ProcessInformation,
02217 ProcessInformationLength
02218 );
02219
02220
ObDereferenceObject(Process);
02221
return st;
02222
02223
case ProcessUserModeIOPL:
02224
02225
02226
02227
02228
02229
02230
02231
if (!
SeSinglePrivilegeCheck(RtlConvertLongToLuid(
02232 SE_TCB_PRIVILEGE),
02233 PreviousMode )) {
02234
02235
return STATUS_PRIVILEGE_NOT_HELD;
02236
02237 }
02238
02239 st =
ObReferenceObjectByHandle(
02240 ProcessHandle,
02241 PROCESS_SET_INFORMATION,
02242
PsProcessType,
02243 PreviousMode,
02244 (PVOID *)&Process,
02245
NULL
02246 );
02247
02248
if (
NT_SUCCESS(st) ) {
02249
02250
#ifdef i386
02251
Ke386SetIOPL(&Process->Pcb);
02252
#endif
02253
02254
ObDereferenceObject(Process);
02255 }
02256
02257
return st;
02258
02259
02260
02261
02262
02263
case ProcessEnableAlignmentFaultFixup:
02264
02265
if ( ProcessInformationLength !=
sizeof(BOOLEAN) ) {
02266
return STATUS_INFO_LENGTH_MISMATCH;
02267 }
02268
02269
try {
02270 EnableAlignmentFaultFixup = *(PBOOLEAN)ProcessInformation;
02271
02272 } except(
EXCEPTION_EXECUTE_HANDLER) {
02273
return GetExceptionCode();
02274 }
02275
02276 st =
ObReferenceObjectByHandle(
02277 ProcessHandle,
02278 PROCESS_SET_INFORMATION,
02279
PsProcessType,
02280 PreviousMode,
02281 (PVOID *)&Process,
02282
NULL
02283 );
02284
02285
if ( !
NT_SUCCESS(st) ) {
02286
return st;
02287 }
02288
02289
if ( EnableAlignmentFaultFixup ) {
02290 Process->DefaultHardErrorProcessing |= PROCESS_HARDERROR_ALIGNMENT_BIT;
02291 }
02292
else {
02293 Process->DefaultHardErrorProcessing &= ~PROCESS_HARDERROR_ALIGNMENT_BIT;
02294 }
02295
02296
KeSetAutoAlignmentProcess( &(Process->Pcb), EnableAlignmentFaultFixup );
02297
ObDereferenceObject(Process);
02298
return STATUS_SUCCESS;
02299
02300
02301
#ifndef i386
02302
case ProcessWx86Information :
02303
if ( ProcessInformationLength !=
sizeof(HANDLE) ) {
02304
return STATUS_INFO_LENGTH_MISMATCH;
02305 }
02306
02307
try {
02308 Wx86Info = *(PHANDLE) ProcessInformation;
02309 }
02310 except(
EXCEPTION_EXECUTE_HANDLER) {
02311
return GetExceptionCode();
02312 }
02313
02314 st =
ObReferenceObjectByHandle(
02315 ProcessHandle,
02316 PROCESS_SET_INFORMATION,
02317
PsProcessType,
02318 PreviousMode,
02319 (PVOID *)&Process,
02320
NULL
02321 );
02322
02323
if (!
NT_SUCCESS(st)) {
02324
return st;
02325 }
02326
02327
02328
02329
02330
02331
02332
if ((ULONG_PTR)Wx86Info !=
sizeof(WX86TIB)) {
02333
if ((ULONG_PTR)Wx86Info != 0 || Process !=
PsGetCurrentProcess()) {
02334
ObDereferenceObject( Process );
02335
return STATUS_INVALID_PARAMETER;
02336 }
02337
02338 Wx86Info =
NULL;
02339 }
02340
02341
02342 Process->VdmObjects = Wx86Info;
02343
02344
02345
02346
02347
02348
02349
if (Wx86Info ==
NULL) {
02350
NTSTATUS xst;
02351 PTEB Teb;
02352 PLIST_ENTRY Next;
02353 PWX86TIB Wx86Tib;
02354 PVOID BaseAddress;
02355 SIZE_T StackSize;
02356
02357 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02358
if ( st != STATUS_SUCCESS ) {
02359
ObDereferenceObject(Process);
02360
return STATUS_PROCESS_IS_TERMINATING;
02361 }
02362
02363 Next = Process->ThreadListHead.Flink;
02364
02365
while ( Next != &Process->ThreadListHead) {
02366
02367 Thread = (
PETHREAD)(CONTAINING_RECORD(Next,
ETHREAD,ThreadListEntry));
02368
if ( !
IS_SYSTEM_THREAD(Thread) ) {
02369
if ( Thread->
Tcb.
Teb ) {
02370 Teb = (PTEB)Thread->
Tcb.
Teb;
02371
try {
02372 Wx86Tib = Teb->Vdm;
02373 Teb->Vdm = 0;
02374
ProbeForRead(Wx86Tib,
sizeof(WX86TIB),
sizeof(ULONG));
02375
if (Wx86Tib && Wx86Tib->Size ==
sizeof(WX86TIB)) {
02376 StackSize = 0;
02377 BaseAddress = Wx86Tib->DeallocationStack;
02378 ZwFreeVirtualMemory(ProcessHandle,
02379 &BaseAddress,
02380 &StackSize,
02381 MEM_RELEASE
02382 );
02383
02384
if (Teb->Wx86Thread.DeallocationCpu) {
02385 BaseAddress = Teb->Wx86Thread.DeallocationCpu;
02386 Teb->Wx86Thread.DeallocationCpu = 0;
02387 StackSize = 0;
02388 st = ZwFreeVirtualMemory(ProcessHandle,
02389 &BaseAddress,
02390 &StackSize,
02391 MEM_RELEASE
02392 );
02393 }
02394 }
02395 }
02396 except(
EXCEPTION_EXECUTE_HANDLER) {
02397 ;
02398 }
02399 }
02400 }
02401 Next = Next->Flink;
02402 }
02403
02404
PsUnlockProcess(Process);
02405 }
02406
02407
ObDereferenceObject(Process);
02408
return STATUS_SUCCESS;
02409
#endif
02410
02411
case ProcessAffinityMask:
02412
02413
#ifdef _WIN64
02414
if ( ProcessInformationLength !=
sizeof(ULONG_PTR) ) {
02415
02416
02417
02418
02419
C_ASSERT(
sizeof(KAFFINITY) !=
sizeof(ULONG_PTR) );
02420
return STATUS_INFO_LENGTH_MISMATCH;
02421 }
02422
#else
02423
if ( ProcessInformationLength !=
sizeof(KAFFINITY) ) {
02424
return STATUS_INFO_LENGTH_MISMATCH;
02425 }
02426
#endif
02427
02428
try {
02429 BigAffinity = *(PULONG_PTR)ProcessInformation;
02430 Affinity = (KAFFINITY)BigAffinity;
02431
02432 }
02433 except(
EXCEPTION_EXECUTE_HANDLER) {
02434
return GetExceptionCode();
02435 }
02436
02437 AffinityWithMasks = Affinity &
KeActiveProcessors;
02438
02439
if ( !Affinity || ( AffinityWithMasks != Affinity ) ) {
02440
return STATUS_INVALID_PARAMETER;
02441 }
02442
02443 st =
ObReferenceObjectByHandle(
02444 ProcessHandle,
02445 PROCESS_SET_INFORMATION,
02446
PsProcessType,
02447 PreviousMode,
02448 (PVOID *)&Process,
02449
NULL
02450 );
02451
02452
if ( !
NT_SUCCESS(st) ) {
02453
return st;
02454 }
02455
02456
02457
02458
02459
02460
if ( Process->Job ) {
02461
KeEnterCriticalRegion();
02462
ExAcquireResourceShared(&Process->Job->JobLock,
TRUE);
02463
02464
if ( Process->Job->LimitFlags & JOB_OBJECT_LIMIT_AFFINITY ) {
02465 AffinityWithMasks = Process->Job->Affinity;
02466 }
02467
02468
ExReleaseResource(&Process->Job->JobLock);
02469
KeLeaveCriticalRegion();
02470 }
02471
02472
02473 {
02474
NTSTATUS xst;
02475 PLIST_ENTRY Next;
02476
PETHREAD OriginalThread;
02477
02478
02479
02480
02481
02482
02483
02484
02485 xst =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02486
02487
if ( xst != STATUS_SUCCESS ) {
02488
ObDereferenceObject( Process );
02489
return STATUS_PROCESS_IS_TERMINATING;
02490 }
02491
02492 Process->Pcb.Affinity = AffinityWithMasks;
02493
02494 Next = Process->ThreadListHead.Flink;
02495
02496
while ( Next != &Process->ThreadListHead) {
02497
02498 Thread = (
PETHREAD)(CONTAINING_RECORD(Next,
ETHREAD,ThreadListEntry));
02499
KeSetAffinityThread(&Thread->
Tcb,AffinityWithMasks);
02500 Next = Next->Flink;
02501 }
02502
02503
PsUnlockProcess(Process);
02504 }
02505
ObDereferenceObject(Process);
02506
return STATUS_SUCCESS;
02507
02508
case ProcessPriorityBoost:
02509
if ( ProcessInformationLength !=
sizeof(ULONG) ) {
02510
return STATUS_INFO_LENGTH_MISMATCH;
02511 }
02512
02513
try {
02514 DisableBoost = *(PULONG)ProcessInformation;
02515 } except(
EXCEPTION_EXECUTE_HANDLER) {
02516
return GetExceptionCode();
02517 }
02518
02519 bDisableBoost = (DisableBoost ?
TRUE :
FALSE);
02520
02521 st =
ObReferenceObjectByHandle(
02522 ProcessHandle,
02523 PROCESS_SET_INFORMATION,
02524
PsProcessType,
02525 PreviousMode,
02526 (PVOID *)&Process,
02527
NULL
02528 );
02529
02530
if ( !
NT_SUCCESS(st) ) {
02531
return st;
02532 }
02533
02534 {
02535
NTSTATUS xst;
02536 PLIST_ENTRY Next;
02537
PETHREAD OriginalThread;
02538
02539
02540
02541
02542
02543
02544
02545
02546 xst =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02547
02548
if ( xst != STATUS_SUCCESS ) {
02549
ObDereferenceObject( Process );
02550
return STATUS_PROCESS_IS_TERMINATING;
02551 }
02552
02553 Process->Pcb.DisableBoost = bDisableBoost;
02554
02555 Next = Process->ThreadListHead.Flink;
02556
02557
while ( Next != &Process->ThreadListHead) {
02558
02559 Thread = (
PETHREAD)(CONTAINING_RECORD(Next,
ETHREAD,ThreadListEntry));
02560
KeSetDisableBoostThread(&Thread->
Tcb,bDisableBoost);
02561 Next = Next->Flink;
02562 }
02563
02564
PsUnlockProcess(Process);
02565 }
02566
ObDereferenceObject(Process);
02567
return STATUS_SUCCESS;
02568
02569
case ProcessDeviceMap:
02570 DeviceMapInfo = (PPROCESS_DEVICEMAP_INFORMATION)ProcessInformation;
02571
if ( ProcessInformationLength !=
sizeof(DeviceMapInfo->Set) ) {
02572
return STATUS_INFO_LENGTH_MISMATCH;
02573 }
02574
02575
try {
02576
DirectoryHandle = DeviceMapInfo->Set.DirectoryHandle;
02577 } except(
EXCEPTION_EXECUTE_HANDLER) {
02578
return GetExceptionCode();
02579 }
02580
02581 st =
ObReferenceObjectByHandle(
02582 ProcessHandle,
02583 PROCESS_SET_INFORMATION,
02584
PsProcessType,
02585 PreviousMode,
02586 (PVOID *)&Process,
02587
NULL
02588 );
02589
02590
if ( !
NT_SUCCESS(st) ) {
02591
return st;
02592 }
02593
02594
02595
02596
02597
02598
02599
02600
02601 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02602
02603
if ( st != STATUS_SUCCESS ) {
02604
ObDereferenceObject( Process );
02605
return STATUS_PROCESS_IS_TERMINATING;
02606 }
02607
02608 st =
ObSetDeviceMap( Process,
DirectoryHandle );
02609
PsUnlockProcess(Process);
02610
ObDereferenceObject(Process);
02611
return st;
02612
02613
case ProcessSessionInformation :
02614
02615
02616
02617
02618
if ( ProcessInformationLength != (ULONG)
sizeof(PROCESS_SESSION_INFORMATION) ) {
02619
return STATUS_INFO_LENGTH_MISMATCH;
02620 }
02621
02622
try {
02623 SessionInfo = *(PPROCESS_SESSION_INFORMATION) ProcessInformation;
02624 } except(
EXCEPTION_EXECUTE_HANDLER) {
02625
return GetExceptionCode();
02626 }
02627
02628
02629
02630
02631
if ( !
SeSinglePrivilegeCheck(
SeTcbPrivilege,PreviousMode) ) {
02632
return( STATUS_PRIVILEGE_NOT_HELD );
02633 }
02634
02635
02636
02637
02638 st =
ObReferenceObjectByHandle(
02639 ProcessHandle,
02640 PROCESS_SET_INFORMATION | PROCESS_SET_SESSIONID,
02641
PsProcessType,
02642 PreviousMode,
02643 (PVOID *)&Process,
02644
NULL
02645 );
02646
if ( !
NT_SUCCESS(st) ) {
02647
return st;
02648 }
02649
02650
02651
02652
02653
02654
02655
02656
Token =
PsReferencePrimaryToken( Process );
02657
SeSetSessionIdToken(
Token, SessionInfo.SessionId );
02658
PsDereferencePrimaryToken(
Token );
02659
02660
02661
02662
02663
02664
02665 Process->SessionId = SessionInfo.SessionId;
02666
02667
02668 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
02669
02670
if ( st != STATUS_SUCCESS ) {
02671
ObDereferenceObject(Process);
02672
return STATUS_PROCESS_IS_TERMINATING;
02673 }
02674
02675
02676
02677
02678
if (Process->Peb !=
NULL) {
02679
02680
02681
KeAttachProcess (&Process->Pcb);
02682
02683
02684
02685
02686
02687 Process->Peb->SessionId = Process->SessionId;
02688
02689
KeDetachProcess();
02690
02691 }
02692
02693
PsUnlockProcess(Process);
02694
ObDereferenceObject(Process);
02695
02696
return( st );
02697
02698
default:
02699
return STATUS_INVALID_INFO_CLASS;
02700 }
02701
02702 }
02703
02704
02705
NTSTATUS
02706 NtQueryInformationThread(
02707 IN HANDLE ThreadHandle,
02708 IN THREADINFOCLASS ThreadInformationClass,
02709 OUT PVOID ThreadInformation,
02710 IN ULONG ThreadInformationLength,
02711 OUT PULONG ReturnLength OPTIONAL
02712 )
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743 {
02744
02745 LARGE_INTEGER PerformanceCount;
02746
PETHREAD Thread;
02747
PEPROCESS Process;
02748 ULONG LastThread;
02749
KPROCESSOR_MODE PreviousMode;
02750
NTSTATUS st;
02751 THREAD_BASIC_INFORMATION BasicInfo;
02752 KERNEL_USER_TIMES SysUserTime;
02753 PVOID Win32StartAddressValue;
02754 ULONG DisableBoost;
02755 ULONG IoPending ;
02756 KIRQL irql ;
02757
02758
02759
02760
02761
02762
PAGED_CODE();
02763
02764 PreviousMode = KeGetPreviousMode();
02765
if (PreviousMode !=
KernelMode) {
02766
try {
02767
ProbeForWrite(ThreadInformation,
02768 ThreadInformationLength,
02769
sizeof(ULONG));
02770
if (ARGUMENT_PRESENT(ReturnLength)) {
02771
ProbeForWriteUlong(ReturnLength);
02772 }
02773 } except(
EXCEPTION_EXECUTE_HANDLER) {
02774
return GetExceptionCode();
02775 }
02776 }
02777
02778
02779
02780
02781
02782
switch ( ThreadInformationClass ) {
02783
02784
case ThreadBasicInformation:
02785
02786
if ( ThreadInformationLength != (ULONG)
sizeof(THREAD_BASIC_INFORMATION) ) {
02787
return STATUS_INFO_LENGTH_MISMATCH;
02788 }
02789
02790 st =
ObReferenceObjectByHandle(
02791
ThreadHandle,
02792 THREAD_QUERY_INFORMATION,
02793
PsThreadType,
02794 PreviousMode,
02795 (PVOID *)&Thread,
02796
NULL
02797 );
02798
if ( !
NT_SUCCESS(st) ) {
02799
return st;
02800 }
02801
02802
if (
KeReadStateThread(&Thread->Tcb)) {
02803 BasicInfo.ExitStatus = Thread->ExitStatus;
02804 }
02805
else {
02806 BasicInfo.ExitStatus = STATUS_PENDING;
02807 }
02808
02809 BasicInfo.TebBaseAddress = (PTEB) Thread->Tcb.Teb;
02810 BasicInfo.ClientId = Thread->Cid;
02811 BasicInfo.AffinityMask = Thread->Tcb.Affinity;
02812 BasicInfo.Priority = Thread->Tcb.Priority;
02813 BasicInfo.BasePriority =
KeQueryBasePriorityThread(&Thread->Tcb);
02814
02815
ObDereferenceObject(Thread);
02816
02817
02818
02819
02820
02821
02822
02823
try {
02824 *(PTHREAD_BASIC_INFORMATION) ThreadInformation = BasicInfo;
02825
02826
if (ARGUMENT_PRESENT(ReturnLength) ) {
02827 *ReturnLength =
sizeof(THREAD_BASIC_INFORMATION);
02828 }
02829 } except(
EXCEPTION_EXECUTE_HANDLER) {
02830
return STATUS_SUCCESS;
02831 }
02832
02833
return STATUS_SUCCESS;
02834
02835
case ThreadTimes:
02836
02837
if ( ThreadInformationLength != (ULONG)
sizeof(KERNEL_USER_TIMES) ) {
02838
return STATUS_INFO_LENGTH_MISMATCH;
02839 }
02840
02841 st =
ObReferenceObjectByHandle(
02842
ThreadHandle,
02843 THREAD_QUERY_INFORMATION,
02844
PsThreadType,
02845 PreviousMode,
02846 (PVOID *)&Thread,
02847
NULL
02848 );
02849
02850
if ( !
NT_SUCCESS(st) ) {
02851
return st;
02852 }
02853
02854 SysUserTime.KernelTime.QuadPart = UInt32x32To64(Thread->Tcb.KernelTime,
02855
KeMaximumIncrement);
02856
02857 SysUserTime.UserTime.QuadPart = UInt32x32To64(Thread->Tcb.UserTime,
02858
KeMaximumIncrement);
02859
02860 SysUserTime.CreateTime.QuadPart =
PS_GET_THREAD_CREATE_TIME(Thread);
02861
if (
KeReadStateThread(&Thread->Tcb)) {
02862 SysUserTime.ExitTime = Thread->ExitTime;
02863 }
else {
02864 SysUserTime.ExitTime.QuadPart = 0;
02865 }
02866
ObDereferenceObject(Thread);
02867
02868
02869
02870
02871
02872
02873
02874
try {
02875 *(PKERNEL_USER_TIMES) ThreadInformation = SysUserTime;
02876
02877
if (ARGUMENT_PRESENT(ReturnLength) ) {
02878 *ReturnLength =
sizeof(KERNEL_USER_TIMES);
02879 }
02880 } except(
EXCEPTION_EXECUTE_HANDLER) {
02881
return STATUS_SUCCESS;
02882 }
02883
02884
return STATUS_SUCCESS;
02885
02886
case ThreadDescriptorTableEntry :
02887
02888 st =
ObReferenceObjectByHandle(
02889
ThreadHandle,
02890 THREAD_QUERY_INFORMATION,
02891
PsThreadType,
02892 PreviousMode,
02893 (PVOID *)&Thread,
02894
NULL
02895 );
02896
02897
if ( !
NT_SUCCESS(st) ) {
02898
return st;
02899 }
02900
02901 st =
PspQueryDescriptorThread( Thread,
02902 ThreadInformation,
02903 ThreadInformationLength,
02904 ReturnLength
02905 );
02906
02907
ObDereferenceObject(Thread);
02908
02909
return st;
02910
02911
case ThreadQuerySetWin32StartAddress:
02912
if ( ThreadInformationLength !=
sizeof(ULONG_PTR) ) {
02913
return STATUS_INFO_LENGTH_MISMATCH;
02914 }
02915
02916 st =
ObReferenceObjectByHandle(
02917
ThreadHandle,
02918 THREAD_QUERY_INFORMATION,
02919
PsThreadType,
02920 PreviousMode,
02921 (PVOID *)&Thread,
02922
NULL
02923 );
02924
02925
if ( !
NT_SUCCESS(st) ) {
02926
return st;
02927 }
02928
02929 Win32StartAddressValue = Thread->Win32StartAddress;
02930
ObDereferenceObject(Thread);
02931
02932
try {
02933 *(PVOID *) ThreadInformation = Win32StartAddressValue;
02934
02935
if (ARGUMENT_PRESENT(ReturnLength) ) {
02936 *ReturnLength =
sizeof(ULONG_PTR);
02937 }
02938 } except(
EXCEPTION_EXECUTE_HANDLER) {
02939
return GetExceptionCode();
02940 }
02941
02942
return st;
02943
02944
02945
02946
02947
02948
case ThreadPerformanceCount:
02949
if ( ThreadInformationLength !=
sizeof(LARGE_INTEGER) ) {
02950
return STATUS_INFO_LENGTH_MISMATCH;
02951 }
02952
02953 st =
ObReferenceObjectByHandle(
02954
ThreadHandle,
02955 THREAD_QUERY_INFORMATION,
02956
PsThreadType,
02957 PreviousMode,
02958 (PVOID *)&Thread,
02959
NULL
02960 );
02961
02962
if ( !
NT_SUCCESS(st) ) {
02963
return st;
02964 }
02965
02966 PerformanceCount.LowPart = Thread->PerformanceCountLow;
02967 PerformanceCount.HighPart = Thread->PerformanceCountHigh;
02968
ObDereferenceObject(Thread);
02969
02970
try {
02971 *(PLARGE_INTEGER)ThreadInformation = PerformanceCount;
02972
02973
if (ARGUMENT_PRESENT(ReturnLength) ) {
02974 *ReturnLength =
sizeof(LARGE_INTEGER);
02975 }
02976 } except(
EXCEPTION_EXECUTE_HANDLER) {
02977
return GetExceptionCode();
02978 }
02979
02980
return st;
02981
02982
case ThreadAmILastThread:
02983
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
02984
return STATUS_INFO_LENGTH_MISMATCH;
02985 }
02986
02987 Thread =
PsGetCurrentThread();
02988 Process =
THREAD_TO_PROCESS(Thread);
02989
02990
if ( (Process->
ThreadListHead.Flink == Process->
ThreadListHead.Blink)
02991 && (Process->
ThreadListHead.Flink == &Thread->ThreadListEntry) ) {
02992 LastThread = 1;
02993 }
02994
else {
02995 LastThread = 0;
02996 }
02997
02998
try {
02999 *(PULONG)ThreadInformation = LastThread;
03000
03001
if (ARGUMENT_PRESENT(ReturnLength) ) {
03002 *ReturnLength =
sizeof(ULONG);
03003 }
03004 } except(
EXCEPTION_EXECUTE_HANDLER) {
03005
return GetExceptionCode();
03006 }
03007
03008
return STATUS_SUCCESS;
03009
03010
case ThreadPriorityBoost:
03011
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
03012
return STATUS_INFO_LENGTH_MISMATCH;
03013 }
03014
03015 st =
ObReferenceObjectByHandle(
03016
ThreadHandle,
03017 THREAD_QUERY_INFORMATION,
03018
PsThreadType,
03019 PreviousMode,
03020 (PVOID *)&Thread,
03021
NULL
03022 );
03023
03024
if ( !
NT_SUCCESS(st) ) {
03025
return st;
03026 }
03027
03028 DisableBoost = Thread->Tcb.DisableBoost ? 1 : 0;
03029
03030
ObDereferenceObject(Thread);
03031
03032
try {
03033 *(PULONG)ThreadInformation = DisableBoost;
03034
03035
if (ARGUMENT_PRESENT(ReturnLength) ) {
03036 *ReturnLength =
sizeof(ULONG);
03037 }
03038 } except(
EXCEPTION_EXECUTE_HANDLER) {
03039
return GetExceptionCode();
03040 }
03041
03042
return st;
03043
03044
case ThreadIsIoPending:
03045
03046
03047
03048
03049
03050
03051
03052
03053
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
03054
return STATUS_INFO_LENGTH_MISMATCH;
03055 }
03056
03057 st =
ObReferenceObjectByHandle(
03058
ThreadHandle,
03059 THREAD_QUERY_INFORMATION,
03060
PsThreadType,
03061 PreviousMode,
03062 (PVOID *)&Thread,
03063
NULL
03064 );
03065
03066
if ( !
NT_SUCCESS(st) ) {
03067
return st;
03068 }
03069
03070
03071
03072
03073
03074
03075
KeRaiseIrql(
APC_LEVEL, &irql );
03076
03077 IoPending = !IsListEmpty( &Thread->IrpList );
03078
03079
KeLowerIrql( irql );
03080
03081
ObDereferenceObject(Thread);
03082
03083
try {
03084 *(PULONG)ThreadInformation = IoPending ;
03085
03086
if (ARGUMENT_PRESENT(ReturnLength) ) {
03087 *ReturnLength =
sizeof(ULONG);
03088 }
03089 } except(
EXCEPTION_EXECUTE_HANDLER) {
03090
return GetExceptionCode();
03091 }
03092
03093
return STATUS_SUCCESS ;
03094
03095
03096
default:
03097
return STATUS_INVALID_INFO_CLASS;
03098 }
03099
03100 }
03101
03102
NTSTATUS
03103 NtSetInformationThread(
03104 IN HANDLE ThreadHandle,
03105 IN THREADINFOCLASS ThreadInformationClass,
03106 IN PVOID ThreadInformation,
03107 IN ULONG ThreadInformationLength
03108 )
03109
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135 {
03136
PEEVENT_PAIR EventPair;
03137 HANDLE EventPairHandle;
03138
PETHREAD Thread;
03139
PEPROCESS Process;
03140
KPROCESSOR_MODE PreviousMode;
03141
NTSTATUS st;
03142 KAFFINITY Affinity, AffinityWithMasks;
03143 ULONG_PTR BigAffinity;
03144 KPRIORITY Priority;
03145 LONG BasePriority;
03146 ULONG TlsIndex;
03147 PVOID TlsArrayAddress;
03148 PVOID Win32StartAddressValue;
03149 ULONG ProbeAlignment;
03150 BOOLEAN EnableAlignmentFaultFixup;
03151 ULONG IdealProcessor;
03152 ULONG DisableBoost;
03153 PVOID *ExpansionSlots;
03154 HANDLE ImpersonationTokenHandle;
03155 BOOLEAN HasPrivilege;
03156
03157
PAGED_CODE();
03158
03159
03160
03161
03162
03163 PreviousMode = KeGetPreviousMode();
03164
if (PreviousMode !=
KernelMode) {
03165
try {
03166
03167
switch (ThreadInformationClass) {
03168
03169
case ThreadPriority :
03170 ProbeAlignment =
sizeof(KPRIORITY);
03171
break;
03172
case ThreadAffinityMask :
03173
case ThreadQuerySetWin32StartAddress :
03174 ProbeAlignment =
sizeof (ULONG_PTR);
03175
break;
03176
case ThreadEnableAlignmentFaultFixup :
03177 ProbeAlignment =
sizeof (BOOLEAN);
03178
break;
03179
default :
03180 ProbeAlignment =
sizeof(ULONG);
03181 }
03182
03183
ProbeForRead(
03184 ThreadInformation,
03185 ThreadInformationLength,
03186 ProbeAlignment
03187 );
03188 } except(
EXCEPTION_EXECUTE_HANDLER) {
03189
return GetExceptionCode();
03190 }
03191 }
03192
03193
03194
03195
03196
03197
switch ( ThreadInformationClass ) {
03198
03199
case ThreadPriority:
03200
03201
if ( ThreadInformationLength !=
sizeof(KPRIORITY) ) {
03202
return STATUS_INFO_LENGTH_MISMATCH;
03203 }
03204
03205
try {
03206 Priority = *(KPRIORITY *)ThreadInformation;
03207 } except(
EXCEPTION_EXECUTE_HANDLER) {
03208
return GetExceptionCode();
03209 }
03210
03211
if ( Priority > HIGH_PRIORITY ||
03212 Priority <= LOW_PRIORITY ) {
03213
03214
return STATUS_INVALID_PARAMETER;
03215 }
03216
03217
if ( Priority >= LOW_REALTIME_PRIORITY ) {
03218
03219
03220
03221
03222
03223
03224 HasPrivilege =
SeCheckPrivilegedObject(
03225
SeIncreaseBasePriorityPrivilege,
03226
ThreadHandle,
03227 THREAD_SET_INFORMATION,
03228 PreviousMode
03229 );
03230
03231
if (!HasPrivilege) {
03232
return STATUS_PRIVILEGE_NOT_HELD;
03233 }
03234 }
03235
03236 st =
ObReferenceObjectByHandle(
03237
ThreadHandle,
03238 THREAD_SET_INFORMATION,
03239
PsThreadType,
03240 PreviousMode,
03241 (PVOID *)&Thread,
03242
NULL
03243 );
03244
03245
if ( !
NT_SUCCESS(st) ) {
03246
return st;
03247 }
03248
03249 Process =
THREAD_TO_PROCESS(Thread);
03250
03251
KeSetPriorityThread(&Thread->Tcb,Priority);
03252
03253
ObDereferenceObject(Thread);
03254
03255
return STATUS_SUCCESS;
03256
03257
case ThreadBasePriority:
03258
03259
if ( ThreadInformationLength !=
sizeof(LONG) ) {
03260
return STATUS_INFO_LENGTH_MISMATCH;
03261 }
03262
03263
try {
03264 BasePriority = *(PLONG)ThreadInformation;
03265 } except(
EXCEPTION_EXECUTE_HANDLER) {
03266
return GetExceptionCode();
03267 }
03268
03269 st =
ObReferenceObjectByHandle(
03270
ThreadHandle,
03271 THREAD_SET_INFORMATION,
03272
PsThreadType,
03273 PreviousMode,
03274 (PVOID *)&Thread,
03275
NULL
03276 );
03277
03278
if ( !
NT_SUCCESS(st) ) {
03279
return st;
03280 }
03281 Process =
THREAD_TO_PROCESS(Thread);
03282
03283
03284
if ( BasePriority > THREAD_BASE_PRIORITY_MAX ||
03285 BasePriority < THREAD_BASE_PRIORITY_MIN ) {
03286
if ( BasePriority == THREAD_BASE_PRIORITY_LOWRT+1 ||
03287 BasePriority == THREAD_BASE_PRIORITY_IDLE-1 ) {
03288 ;
03289 }
03290
else {
03291
03292
03293
03294
03295
03296
03297
if (
PsGetCurrentProcess() ==
ExpDefaultErrorPortProcess ||
03298 Process->
PriorityClass == PROCESS_PRIORITY_CLASS_REALTIME ){
03299 ;
03300 }
03301
else {
03302
ObDereferenceObject(Thread);
03303
return STATUS_INVALID_PARAMETER;
03304 }
03305 }
03306 }
03307
03308
03309
03310
03311
03312
03313
03314
03315
if ( Process->
Job && (Process->
Job->
LimitFlags & JOB_OBJECT_LIMIT_PRIORITY_CLASS) ) {
03316
if ( Process->
PriorityClass != PROCESS_PRIORITY_CLASS_REALTIME ){
03317
if ( BasePriority > 0 ) {
03318
ObDereferenceObject(Thread);
03319
return STATUS_SUCCESS;
03320 }
03321 }
03322 }
03323
03324
KeSetBasePriorityThread(&Thread->Tcb,BasePriority);
03325
03326
ObDereferenceObject(Thread);
03327
03328
return STATUS_SUCCESS;
03329
03330
case ThreadEnableAlignmentFaultFixup:
03331
03332
if ( ThreadInformationLength !=
sizeof(BOOLEAN) ) {
03333
return STATUS_INFO_LENGTH_MISMATCH;
03334 }
03335
03336
try {
03337 EnableAlignmentFaultFixup = *(PBOOLEAN)ThreadInformation;
03338 } except(
EXCEPTION_EXECUTE_HANDLER) {
03339
return GetExceptionCode();
03340 }
03341
03342 st =
ObReferenceObjectByHandle(
03343
ThreadHandle,
03344 THREAD_SET_INFORMATION,
03345
PsThreadType,
03346 PreviousMode,
03347 (PVOID *)&Thread,
03348
NULL
03349 );
03350
03351
if ( !
NT_SUCCESS(st) ) {
03352
return st;
03353 }
03354
03355
KeSetAutoAlignmentThread( &(Thread->Tcb), EnableAlignmentFaultFixup );
03356
03357
ObDereferenceObject(Thread);
03358
03359
return STATUS_SUCCESS;
03360
03361
case ThreadAffinityMask:
03362
03363
if ( ThreadInformationLength !=
sizeof(ULONG_PTR) ) {
03364
return STATUS_INFO_LENGTH_MISMATCH;
03365 }
03366
03367
try {
03368 BigAffinity = *(ULONG_PTR *) ThreadInformation;
03369 Affinity = (KAFFINITY) BigAffinity;
03370 } except(
EXCEPTION_EXECUTE_HANDLER) {
03371
return GetExceptionCode();
03372 }
03373
03374
if ( !Affinity ) {
03375
03376
return STATUS_INVALID_PARAMETER;
03377
03378 }
03379
03380 st =
ObReferenceObjectByHandle(
03381
ThreadHandle,
03382 THREAD_SET_INFORMATION,
03383
PsThreadType,
03384 PreviousMode,
03385 (PVOID *)&Thread,
03386
NULL
03387 );
03388
03389
if ( !
NT_SUCCESS(st) ) {
03390
return st;
03391 }
03392
03393 Process =
THREAD_TO_PROCESS(Thread);
03394
03395
03396
03397
03398
03399
03400
03401
03402 st =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
03403
03404
if ( st != STATUS_SUCCESS ) {
03405
ObDereferenceObject(Thread);
03406
return STATUS_PROCESS_IS_TERMINATING;
03407 }
03408
03409 AffinityWithMasks = Affinity & Process->
Pcb.
Affinity;
03410
03411
if ( AffinityWithMasks != Affinity ) {
03412
03413 st = STATUS_INVALID_PARAMETER;
03414
03415 }
else {
03416
03417
KeSetAffinityThread(
03418 &Thread->Tcb,
03419 AffinityWithMasks
03420 );
03421 st = STATUS_SUCCESS;
03422 }
03423
03424
PsUnlockProcess(Process);
03425
03426
ObDereferenceObject(Thread);
03427
03428
return st;
03429
03430
case ThreadImpersonationToken:
03431
03432
03433
if ( ThreadInformationLength !=
sizeof(HANDLE) ) {
03434
return STATUS_INFO_LENGTH_MISMATCH;
03435 }
03436
03437
03438
try {
03439 ImpersonationTokenHandle = *(PHANDLE) ThreadInformation;
03440 } except(
EXCEPTION_EXECUTE_HANDLER) {
03441
return GetExceptionCode();
03442 }
03443
03444
03445 st =
ObReferenceObjectByHandle(
03446
ThreadHandle,
03447 THREAD_SET_THREAD_TOKEN,
03448
PsThreadType,
03449 PreviousMode,
03450 (PVOID *)&Thread,
03451
NULL
03452 );
03453
03454
if ( !
NT_SUCCESS(st) ) {
03455
return st;
03456 }
03457
03458
03459
03460
03461
03462
03463 st =
PsAssignImpersonationToken( Thread, ImpersonationTokenHandle );
03464
03465
03466
ObDereferenceObject(Thread);
03467
03468
return st;
03469
03470
case ThreadQuerySetWin32StartAddress:
03471
if ( ThreadInformationLength !=
sizeof(ULONG_PTR) ) {
03472
return STATUS_INFO_LENGTH_MISMATCH;
03473 }
03474
03475
03476
try {
03477 Win32StartAddressValue = *(PVOID *) ThreadInformation;
03478 } except(
EXCEPTION_EXECUTE_HANDLER) {
03479
return GetExceptionCode();
03480 }
03481
03482
03483 st =
ObReferenceObjectByHandle(
03484
ThreadHandle,
03485 THREAD_SET_INFORMATION,
03486
PsThreadType,
03487 PreviousMode,
03488 (PVOID *)&Thread,
03489
NULL
03490 );
03491
03492
if ( !
NT_SUCCESS(st) ) {
03493
return st;
03494 }
03495
03496 Thread->Win32StartAddress = (PVOID)Win32StartAddressValue;
03497
ObDereferenceObject(Thread);
03498
03499
return st;
03500
03501
03502
case ThreadIdealProcessor:
03503
03504
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
03505
return STATUS_INFO_LENGTH_MISMATCH;
03506 }
03507
03508
03509
try {
03510 IdealProcessor = *(PULONG)ThreadInformation;
03511 } except(
EXCEPTION_EXECUTE_HANDLER) {
03512
return GetExceptionCode();
03513 }
03514
03515
if ( IdealProcessor >
MAXIMUM_PROCESSORS ) {
03516
return STATUS_INVALID_PARAMETER;
03517 }
03518
03519 st =
ObReferenceObjectByHandle(
03520
ThreadHandle,
03521 THREAD_SET_INFORMATION,
03522
PsThreadType,
03523 PreviousMode,
03524 (PVOID *)&Thread,
03525
NULL
03526 );
03527
03528
if ( !
NT_SUCCESS(st) ) {
03529
return st;
03530 }
03531
03532
03533
03534
03535
03536
03537 st = (
NTSTATUS)
KeSetIdealProcessorThread(&Thread->Tcb,(CCHAR)IdealProcessor);
03538
03539
ObDereferenceObject(Thread);
03540
03541
return st;
03542
03543
03544
case ThreadPriorityBoost:
03545
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
03546
return STATUS_INFO_LENGTH_MISMATCH;
03547 }
03548
03549
try {
03550 DisableBoost = *(PULONG)ThreadInformation;
03551 } except(
EXCEPTION_EXECUTE_HANDLER) {
03552
return GetExceptionCode();
03553 }
03554
03555 st =
ObReferenceObjectByHandle(
03556
ThreadHandle,
03557 THREAD_SET_INFORMATION,
03558
PsThreadType,
03559 PreviousMode,
03560 (PVOID *)&Thread,
03561
NULL
03562 );
03563
03564
if ( !
NT_SUCCESS(st) ) {
03565
return st;
03566 }
03567
03568
KeSetDisableBoostThread(&Thread->Tcb,DisableBoost ?
TRUE :
FALSE);
03569
03570
ObDereferenceObject(Thread);
03571
03572
return st;
03573
03574
case ThreadZeroTlsCell:
03575
if ( ThreadInformationLength !=
sizeof(ULONG) ) {
03576
return STATUS_INFO_LENGTH_MISMATCH;
03577 }
03578
03579
03580
try {
03581 TlsIndex = *(PULONG) ThreadInformation;
03582 } except(
EXCEPTION_EXECUTE_HANDLER) {
03583
return GetExceptionCode();
03584 }
03585
03586 st =
ObReferenceObjectByHandle(
03587
ThreadHandle,
03588 THREAD_SET_INFORMATION,
03589
PsThreadType,
03590 PreviousMode,
03591 (PVOID *)&Thread,
03592
NULL
03593 );
03594
03595
if ( !
NT_SUCCESS(st) ) {
03596
return st;
03597 }
03598
03599
if ( Thread !=
PsGetCurrentThread() ) {
03600
ObDereferenceObject( Thread );
03601
return STATUS_INVALID_PARAMETER;
03602 }
03603 {
03604
NTSTATUS xst;
03605 PTEB Teb;
03606 PLIST_ENTRY Next;
03607
PETHREAD OriginalThread;
03608
03609 OriginalThread = Thread;
03610
03611 Process =
THREAD_TO_PROCESS(Thread);
03612
03613
03614
03615
03616
03617
03618
03619
03620 xst =
PsLockProcess(Process,PreviousMode,
PsLockPollOnTimeout);
03621
03622
if ( xst != STATUS_SUCCESS ) {
03623
ObDereferenceObject( OriginalThread );
03624
return STATUS_PROCESS_IS_TERMINATING;
03625 }
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636 Next = Process->
ThreadListHead.Flink;
03637
03638
while ( Next != &Process->
ThreadListHead) {
03639
03640 Thread = (
PETHREAD)(CONTAINING_RECORD(Next,
ETHREAD,ThreadListEntry));
03641
if ( !
IS_SYSTEM_THREAD(Thread) ) {
03642
if ( Thread->Tcb.Teb ) {
03643 Teb = (PTEB)Thread->Tcb.Teb;
03644
03645
if ( TlsIndex > TLS_MINIMUM_AVAILABLE-1 ) {
03646
if ( TlsIndex < (TLS_MINIMUM_AVAILABLE+TLS_EXPANSION_SLOTS) - 1 ) {
03647
03648
03649
03650
03651
try {
03652
#if defined(_WIN64)
03653
if (Process->
Wow64Process) {
03654 PTEB32 Teb32;
03655 PLONG ExpansionSlots32;
03656
03657 Teb32 = WOW64_GET_TEB32(Teb);
03658
if (Teb32) {
03659 ExpansionSlots32 = ULongToPtr(
ProbeAndReadLong(&(Teb32->TlsExpansionSlots)));
03660
if (ExpansionSlots32) {
03661
ProbeAndWriteLong(ExpansionSlots32 + TlsIndex - TLS_MINIMUM_AVAILABLE, 0);
03662 }
03663 }
03664 }
03665
else
03666
#endif
03667
{
03668 ExpansionSlots = Teb->TlsExpansionSlots;
03669
ProbeForRead(ExpansionSlots,TLS_EXPANSION_SLOTS*4,8);
03670
if ( ExpansionSlots ) {
03671 ExpansionSlots[TlsIndex-TLS_MINIMUM_AVAILABLE] = 0;
03672 }
03673
03674 }
03675 }
03676 except(
EXCEPTION_EXECUTE_HANDLER) {
03677 ;
03678 }
03679 }
03680 }
03681
else {
03682
try {
03683
#if defined(_WIN64)
03684
if (Process->
Wow64Process) {
03685 PTEB32 Teb32;
03686
03687 Teb32 = WOW64_GET_TEB32(Teb);
03688
if(Teb32) {
03689
ProbeAndWriteLong(Teb32->TlsSlots + TlsIndex, 0);
03690 }
03691 }
03692
else
03693
#endif
03694
{
03695 Teb->TlsSlots[TlsIndex] =
NULL;
03696 }
03697 }
03698 except(
EXCEPTION_EXECUTE_HANDLER) {
03699 ;
03700 }
03701 }
03702
03703 }
03704 }
03705 Next = Next->Flink;
03706 }
03707
03708
PsUnlockProcess(Process);
03709
03710
ObDereferenceObject(OriginalThread);
03711
03712 }
03713
return st;
03714
break;
03715
03716
case ThreadSetTlsArrayAddress:
03717
if ( ThreadInformationLength !=
sizeof(PVOID) ) {
03718
return STATUS_INFO_LENGTH_MISMATCH;
03719 }
03720
03721
03722
try {
03723 TlsArrayAddress = *(PVOID *)ThreadInformation;
03724 } except(
EXCEPTION_EXECUTE_HANDLER) {
03725
return GetExceptionCode();
03726 }
03727
03728 st =
ObReferenceObjectByHandle(
03729
ThreadHandle,
03730 THREAD_SET_INFORMATION,
03731
PsThreadType,
03732 PreviousMode,
03733 (PVOID *)&Thread,
03734
NULL
03735 );
03736
03737
if ( !
NT_SUCCESS(st) ) {
03738
return st;
03739 }
03740
03741 Thread->Tcb.TlsArray = TlsArrayAddress;
03742
03743
#if defined(_MIPS_)
03744
03745
if (Thread ==
PsGetCurrentThread()) {
03746 PCR->TlsArray = TlsArrayAddress;
03747 }
03748
03749
#endif
03750
03751
ObDereferenceObject(Thread);
03752
03753
return st;
03754
break;
03755
03756
case ThreadHideFromDebugger:
03757
if ( ThreadInformationLength != 0 ) {
03758
return STATUS_INFO_LENGTH_MISMATCH;
03759 }
03760
03761 st =
ObReferenceObjectByHandle(
03762
ThreadHandle,
03763 THREAD_SET_INFORMATION,
03764
PsThreadType,
03765 PreviousMode,
03766 (PVOID *)&Thread,
03767
NULL
03768 );
03769
03770
if ( !
NT_SUCCESS(st) ) {
03771
return st;
03772 }
03773
03774 Thread->HideFromDebugger =
TRUE;
03775
03776
ObDereferenceObject(Thread);
03777
03778
return st;
03779
break;
03780
03781
default:
03782
return STATUS_INVALID_INFO_CLASS;
03783 }
03784 }
03785
03786
03787
NTSTATUS
03788 PsWatchWorkingSet(
03789 IN NTSTATUS Status,
03790 IN PVOID PcValue,
03791 IN PVOID Va
03792 )
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810 {
03811
PEPROCESS Process;
03812 PPAGEFAULT_HISTORY WorkingSetCatcher;
03813 KIRQL OldIrql;
03814 BOOLEAN TransitionFault =
FALSE;
03815
03816
if ( !
NT_SUCCESS(
Status ))
03817
return Status;
03818
03819
03820
03821
if (
Status <= STATUS_PAGE_FAULT_DEMAND_ZERO ) {
03822 TransitionFault =
TRUE;
03823 }
03824 Process =
PsGetCurrentProcess();
03825
if ( !(WorkingSetCatcher = Process->
WorkingSetWatch) ) {
03826
return Status;
03827 }
03828
03829 ExAcquireSpinLock(&WorkingSetCatcher->SpinLock,&OldIrql);
03830
if ( WorkingSetCatcher->CurrentIndex >= WorkingSetCatcher->MaxIndex ) {
03831 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
03832
return Status;
03833 }
03834
03835
03836
03837 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingPc = PcValue;
03838 WorkingSetCatcher->WatchInfo[WorkingSetCatcher->CurrentIndex].FaultingVa = TransitionFault ? (PVOID)((ULONG_PTR)Va | 1) : (PVOID)((ULONG_PTR)Va & 0xfffffffe) ;
03839 WorkingSetCatcher->CurrentIndex++;
03840
03841 ExReleaseSpinLock(&WorkingSetCatcher->SpinLock,OldIrql);
03842
return Status;
03843 }
03844
03845 PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout;
03846 PKWIN32_THREAD_CALLOUT PspW32ThreadCallout;
03847 PKWIN32_JOB_CALLOUT PspW32JobCallout;
03848 extern PKWIN32_POWEREVENT_CALLOUT PopEventCallout;
03849 extern PKWIN32_POWERSTATE_CALLOUT PopStateCallout;
03850
03851
03852
03853
NTKERNELAPI
03854
VOID
03855 PsEstablishWin32Callouts(
03856 IN PKWIN32_PROCESS_CALLOUT ProcessCallout,
03857 IN PKWIN32_THREAD_CALLOUT ThreadCallout,
03858 IN PKWIN32_GLOBALATOMTABLE_CALLOUT GlobalAtomTableCallout,
03859 IN PKWIN32_POWEREVENT_CALLOUT PowerEventCallout,
03860 IN PKWIN32_POWERSTATE_CALLOUT PowerStateCallout,
03861 IN PKWIN32_JOB_CALLOUT JobCallout,
03862 IN PVOID BatchFlushRoutine
03863 )
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897
03898
03899
03900
03901 {
03902
PAGED_CODE();
03903
03904
PspW32ProcessCallout = ProcessCallout;
03905
PspW32ThreadCallout = ThreadCallout;
03906
ExGlobalAtomTableCallout = GlobalAtomTableCallout;
03907
KeGdiFlushUserBatch = (
PGDI_BATCHFLUSH_ROUTINE)BatchFlushRoutine;
03908
PopEventCallout = PowerEventCallout;
03909
PopStateCallout = PowerStateCallout;
03910
PspW32JobCallout = JobCallout;
03911
03912 }
03913
03914
03915
VOID
03916 PsSetProcessPriorityByClass(
03917 IN
PEPROCESS Process,
03918 IN PSPROCESSPRIORITYMODE PriorityMode
03919 )
03920 {
03921 KPRIORITY BasePriority;
03922 UCHAR MemoryPriority;
03923 ULONG QuantumIndex;
03924
03925
PAGED_CODE();
03926
03927
03928 BasePriority =
PspPriorityTable[Process->PriorityClass];
03929
03930
03931
if ( PriorityMode ==
PsProcessPriorityForeground ) {
03932 QuantumIndex =
PsPrioritySeperation;
03933 MemoryPriority =
MEMORY_PRIORITY_FOREGROUND;
03934
#if defined(_X86_)
03935
Process->MmAgressiveWsTrimMask &= ~
PS_WS_TRIM_BACKGROUND_ONLY_APP;
03936
#endif // _X86_
03937
}
03938
else {
03939 QuantumIndex = 0;
03940 MemoryPriority =
MEMORY_PRIORITY_BACKGROUND;
03941 }
03942
03943
if ( Process->PriorityClass != PROCESS_PRIORITY_CLASS_IDLE ) {
03944
if ( Process->Job &&
PspUseJobSchedulingClasses ) {
03945 Process->Pcb.ThreadQuantum =
PspJobSchedulingClasses[Process->Job->SchedulingClass];
03946 }
03947
else {
03948 Process->Pcb.ThreadQuantum =
PspForegroundQuantum[QuantumIndex];
03949 }
03950 }
03951
else {
03952 Process->Pcb.ThreadQuantum =
THREAD_QUANTUM;
03953 }
03954
03955
KeSetPriorityProcess(&Process->Pcb,BasePriority);
03956
if ( PriorityMode !=
PsProcessPrioritySpinning ) {
03957
MmSetMemoryPriorityProcess(Process, MemoryPriority);
03958 }
03959 }
03960
03961
03962
03963
NTSTATUS
03964 PsConvertToGuiThread(
03965 VOID
03966 )
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988
03989
03990
03991
03992
03993
03994 #
if defined(i386)
03995 #pragma optimize (
"y",off)
03996 #endif
03997
03998 {
03999 PVOID NewStack;
04000 PVOID OldStack;
04001
PETHREAD Thread;
04002
PEPROCESS Process;
04003
NTSTATUS Status;
04004
04005
PAGED_CODE();
04006
04007
if (KeGetPreviousMode() ==
KernelMode) {
04008
return STATUS_INVALID_PARAMETER;
04009 }
04010
04011
if ( !
PspW32ProcessCallout ) {
04012
return STATUS_ACCESS_DENIED;
04013 }
04014
04015
04016 Thread =
PsGetCurrentThread();
04017
04018
04019
04020
04021
04022
04023
04024
if ( Thread->
Tcb.
ServiceTable != (PVOID)&
KeServiceDescriptorTable[0] ) {
04025
return STATUS_ALREADY_WIN32;
04026 }
04027
04028 Process =
PsGetCurrentProcess();
04029
04030
04031
04032
04033
04034
if ( !Thread->
Tcb.
LargeStack ) {
04035
04036 NewStack =
MmCreateKernelStack(
TRUE);
04037
04038
if ( !NewStack ) {
04039
04040 NtCurrentTeb()->LastErrorValue = (LONG)ERROR_NOT_ENOUGH_MEMORY;
04041
04042
return STATUS_NO_MEMORY;
04043 }
04044
04045
#if defined(_IA64_)
04046
OldStack =
KeSwitchKernelStack(NewStack,
04047 (UCHAR *)NewStack - KERNEL_LARGE_STACK_COMMIT,
04048 (UCHAR *)NewStack + KERNEL_LARGE_BSTORE_COMMIT);
04049
#else
04050
OldStack =
KeSwitchKernelStack(NewStack,
04051 (UCHAR *)NewStack - KERNEL_LARGE_STACK_COMMIT);
04052
#endif // defined(_IA64_)
04053
04054
MmDeleteKernelStack(OldStack,
FALSE);
04055
04056 }
04057
04058
PERFINFO_CONVERT_TO_GUI_THREAD(Thread);
04059
04060
04061
04062
04063
04064
04065
Status = (
PspW32ProcessCallout)(Process,
TRUE);
04066
04067
if ( !
NT_SUCCESS(
Status) ) {
04068
return Status;
04069 }
04070
04071
04072
04073
04074
04075
04076 Thread->
Tcb.
ServiceTable = (PVOID)&
KeServiceDescriptorTableShadow[0];
04077
04078
ASSERT( Thread->
Tcb.
Win32Thread == 0 );
04079
04080
04081
04082
04083
04084
04085
Status = (
PspW32ThreadCallout)(Thread,
PsW32ThreadCalloutInitialize);
04086
if ( !
NT_SUCCESS(
Status) ) {
04087 Thread->
Tcb.
ServiceTable = (PVOID)&
KeServiceDescriptorTable[0];
04088 }
04089
04090
return Status;
04091
04092 }