00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
#include "iop.h"
00028
00029
#ifdef ALLOC_PRAGMA
00030
#pragma alloc_text(PAGE, NtQueryQuotaInformationFile)
00031
#pragma alloc_text(PAGE, NtSetQuotaInformationFile)
00032
#endif
00033
00034
NTSTATUS
00035 NtQueryQuotaInformationFile(
00036 IN HANDLE FileHandle,
00037 OUT PIO_STATUS_BLOCK IoStatusBlock,
00038 OUT PVOID Buffer,
00039 IN ULONG Length,
00040 IN BOOLEAN ReturnSingleEntry,
00041 IN PVOID SidList OPTIONAL,
00042 IN ULONG SidListLength,
00043 IN PULONG StartSid OPTIONAL,
00044 IN BOOLEAN RestartScan
00045 )
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 {
00090
00091
#define ALIGN_LONG( Address ) ( (Address + 3) & ~3 )
00092
00093
PIRP irp;
00094
NTSTATUS status;
00095
PFILE_OBJECT fileObject;
00096
PDEVICE_OBJECT deviceObject;
00097
PKEVENT event = (
PKEVENT)
NULL;
00098 PCHAR auxiliaryBuffer = (PCHAR)
NULL;
00099 ULONG startSidLength = 0;
00100 PSID startSid = (PSID)
NULL;
00101 PFILE_GET_QUOTA_INFORMATION sidList = (PFILE_GET_QUOTA_INFORMATION)
NULL;
00102
KPROCESSOR_MODE requestorMode;
00103
PIO_STACK_LOCATION irpSp;
00104 IO_STATUS_BLOCK localIoStatus;
00105 BOOLEAN synchronousIo;
00106 UCHAR subCount;
00107
00108
PAGED_CODE();
00109
00110
00111
00112
00113
00114 requestorMode = KeGetPreviousMode();
00115
00116
if (requestorMode !=
KernelMode) {
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
try {
00127
00128
00129
00130
00131
00132
ProbeForWriteIoStatus( IoStatusBlock );
00133
00134
00135
00136
00137
00138
#if defined(_X86_)
00139
ProbeForWrite(
Buffer, Length,
sizeof( ULONG ) );
00140
#elif defined(_WIN64)
00141
00142
00143
00144
00145
00146
if (
PsGetCurrentProcess()->Wow64Process) {
00147
ProbeForWrite(
Buffer, Length,
sizeof( ULONG ) );
00148 }
else {
00149
ProbeForWrite(
Buffer, Length,
sizeof( ULONGLONG ) );
00150 }
00151
#else
00152
ProbeForWrite(
Buffer, Length,
sizeof( ULONGLONG ) );
00153
#endif
00154
00155
00156
00157
00158
00159
00160
00161
if (ARGUMENT_PRESENT( StartSid )) {
00162
00163 subCount =
ProbeAndReadUchar( &(((SID *)(StartSid))->SubAuthorityCount) );
00164 startSidLength =
RtlLengthRequiredSid( subCount );
00165
ProbeForRead( StartSid, startSidLength,
sizeof( ULONG ) );
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
if (ARGUMENT_PRESENT( SidList ) && SidListLength) {
00175
00176
ProbeForRead( SidList, SidListLength,
sizeof( ULONG ) );
00177 auxiliaryBuffer =
ExAllocatePoolWithQuota(
NonPagedPool,
00178
ALIGN_LONG( SidListLength ) +
00179 startSidLength );
00180 sidList = (PFILE_GET_QUOTA_INFORMATION) auxiliaryBuffer;
00181
00182 RtlCopyMemory( auxiliaryBuffer, SidList, SidListLength );
00183
00184 }
else {
00185
00186
00187
00188
00189
00190
00191
00192 SidListLength = 0;
00193
if (ARGUMENT_PRESENT( StartSid )) {
00194 auxiliaryBuffer =
ExAllocatePoolWithQuota(
PagedPool,
00195 startSidLength );
00196 }
00197 }
00198
00199
00200
00201
00202
00203
00204
if (ARGUMENT_PRESENT( StartSid )) {
00205 startSid = (PSID) (auxiliaryBuffer +
ALIGN_LONG( SidListLength ));
00206
00207 RtlCopyMemory( startSid, StartSid, startSidLength );
00208 ((SID *) startSid)->SubAuthorityCount = subCount;
00209 }
00210
00211
00212 } except(
EXCEPTION_EXECUTE_HANDLER) {
00213
00214
00215
00216
00217
00218
00219
00220
00221
if (auxiliaryBuffer) {
00222
ExFreePool( auxiliaryBuffer );
00223 }
00224
00225
return GetExceptionCode();
00226
00227 }
00228
00229 }
else {
00230
00231
00232
00233
00234
00235
00236
00237
if (ARGUMENT_PRESENT( SidList ) && SidListLength) {
00238 sidList = SidList;
00239 }
00240
00241
if (ARGUMENT_PRESENT( StartSid )) {
00242 startSid = StartSid;
00243 }
00244 }
00245
00246
00247
00248
00249
00250
00251
if (sidList !=
NULL) {
00252 status =
IopCheckGetQuotaBufferValidity( sidList,
00253 SidListLength,
00254 &IoStatusBlock->Information );
00255
if (!
NT_SUCCESS( status )) {
00256
if (auxiliaryBuffer !=
NULL) {
00257
ExFreePool( auxiliaryBuffer );
00258 }
00259
return status;
00260
00261 }
00262 }
00263
00264
if (startSid !=
NULL) {
00265
00266
if (!
RtlValidSid( startSid )) {
00267
if (auxiliaryBuffer !=
NULL) {
00268
ExFreePool( auxiliaryBuffer );
00269 }
00270
return STATUS_INVALID_SID;
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 status =
ObReferenceObjectByHandle( FileHandle,
00282 0,
00283
IoFileObjectType,
00284 requestorMode,
00285 (PVOID *) &fileObject,
00286
NULL );
00287
if (!
NT_SUCCESS( status )) {
00288
if (auxiliaryBuffer) {
00289
ExFreePool( auxiliaryBuffer );
00290 }
00291
return status;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
if (fileObject->Flags &
FO_SYNCHRONOUS_IO) {
00302
00303 BOOLEAN interrupted;
00304
00305
if (!
IopAcquireFastLock( fileObject )) {
00306 status =
IopAcquireFileObjectLock( fileObject,
00307 requestorMode,
00308 (BOOLEAN) ((fileObject->Flags &
FO_ALERTABLE_IO) != 0),
00309 &interrupted );
00310
if (interrupted) {
00311
if (auxiliaryBuffer) {
00312
ExFreePool( auxiliaryBuffer );
00313 }
00314
ObDereferenceObject( fileObject );
00315
return status;
00316 }
00317 }
00318 synchronousIo =
TRUE;
00319 }
else {
00320
00321
00322
00323
00324
00325
00326
00327
00328 event =
ExAllocatePool(
NonPagedPool,
sizeof(
KEVENT ) );
00329
if (!event) {
00330
if (auxiliaryBuffer) {
00331
ExFreePool( auxiliaryBuffer );
00332 }
00333
ObDereferenceObject( fileObject );
00334
return STATUS_INSUFFICIENT_RESOURCES;
00335 }
00336
KeInitializeEvent( event, SynchronizationEvent,
FALSE );
00337 synchronousIo =
FALSE;
00338 }
00339
00340
00341
00342
00343
00344
KeClearEvent( &fileObject->Event );
00345
00346
00347
00348
00349
00350 deviceObject =
IoGetRelatedDeviceObject( fileObject );
00351
00352
00353
00354
00355
00356
00357 irp =
IoAllocateIrp( deviceObject->
StackSize,
TRUE );
00358
if (!irp) {
00359
00360
00361
00362
00363
00364
00365
if (!(fileObject->Flags &
FO_SYNCHRONOUS_IO)) {
00366
ExFreePool( event );
00367 }
00368
00369
IopAllocateIrpCleanup( fileObject, (
PKEVENT)
NULL );
00370
00371
if (auxiliaryBuffer) {
00372
ExFreePool( auxiliaryBuffer );
00373 }
00374
00375
return STATUS_INSUFFICIENT_RESOURCES;
00376 }
00377 irp->
Tail.Overlay.OriginalFileObject = fileObject;
00378 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
00379 irp->
RequestorMode = requestorMode;
00380
00381
00382
00383
00384
00385
if (synchronousIo) {
00386 irp->
UserEvent = (
PKEVENT)
NULL;
00387 irp->
UserIosb = IoStatusBlock;
00388 }
else {
00389 irp->
UserEvent = event;
00390 irp->
UserIosb = &localIoStatus;
00391 irp->
Flags =
IRP_SYNCHRONOUS_API;
00392 }
00393 irp->
Overlay.AsynchronousParameters.UserApcRoutine = (PIO_APC_ROUTINE)
NULL;
00394
00395
00396
00397
00398
00399
00400 irpSp =
IoGetNextIrpStackLocation( irp );
00401 irpSp->
MajorFunction =
IRP_MJ_QUERY_QUOTA;
00402 irpSp->
FileObject = fileObject;
00403
00404
00405
00406
00407
00408
00409
00410 irp->
Tail.Overlay.AuxiliaryBuffer = auxiliaryBuffer;
00411 irpSp->
Parameters.QueryQuota.SidList = sidList;
00412 irpSp->
Parameters.QueryQuota.SidListLength = SidListLength;
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
if (deviceObject->
Flags &
DO_BUFFERED_IO) {
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
if (Length) {
00439
try {
00440
00441
00442
00443
00444
00445
00446 irp->
AssociatedIrp.SystemBuffer =
00447
ExAllocatePoolWithQuota(
NonPagedPool, Length );
00448
00449 } except(
EXCEPTION_EXECUTE_HANDLER) {
00450
00451
00452
00453
00454
00455
00456
00457
00458
IopExceptionCleanup( fileObject,
00459 irp,
00460 (
PKEVENT)
NULL,
00461 event );
00462
00463
if (auxiliaryBuffer) {
00464
ExFreePool( auxiliaryBuffer );
00465 }
00466
00467
return GetExceptionCode();
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477 irp->
UserBuffer =
Buffer;
00478 irp->
Flags |= (ULONG) (
IRP_BUFFERED_IO |
00479
IRP_DEALLOCATE_BUFFER |
00480
IRP_INPUT_OPERATION);
00481 }
else {
00482 irp->
AssociatedIrp.SystemBuffer =
NULL;
00483 irp->
UserBuffer =
Buffer;
00484 }
00485
00486 }
else if (deviceObject->
Flags &
DO_DIRECT_IO) {
00487
00488
PMDL mdl;
00489
00490
00491
00492
00493
00494
00495
00496
00497 mdl = (
PMDL)
NULL;
00498
00499
if (Length) {
00500
try {
00501
00502
00503
00504
00505
00506
00507
00508
00509 mdl =
IoAllocateMdl(
Buffer, Length,
FALSE,
TRUE, irp );
00510
if (!mdl) {
00511
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
00512 }
00513
MmProbeAndLockPages( mdl, requestorMode,
IoWriteAccess );
00514
00515 } except(
EXCEPTION_EXECUTE_HANDLER) {
00516
00517
00518
00519
00520
00521
00522
00523
00524
IopExceptionCleanup( fileObject,
00525 irp,
00526 (
PKEVENT)
NULL,
00527 event );
00528
00529
if (auxiliaryBuffer) {
00530
ExFreePool( auxiliaryBuffer );
00531 }
00532
00533
return GetExceptionCode();
00534
00535 }
00536 }
00537
00538 }
else {
00539
00540
00541
00542
00543
00544
00545 irp->
UserBuffer =
Buffer;
00546
00547 }
00548
00549
00550
00551
00552
00553
00554 irpSp->
Parameters.QueryQuota.Length = Length;
00555 irpSp->
Parameters.QueryQuota.StartSid = StartSid;
00556 irpSp->
Flags = 0;
00557
if (RestartScan) {
00558 irpSp->
Flags =
SL_RESTART_SCAN;
00559 }
00560
if (ReturnSingleEntry) {
00561 irpSp->
Flags |=
SL_RETURN_SINGLE_ENTRY;
00562 }
00563
if (ARGUMENT_PRESENT( StartSid )) {
00564 irpSp->
Flags |=
SL_INDEX_SPECIFIED;
00565 }
00566
00567
00568
00569
00570
00571
00572 status =
IopSynchronousServiceTail( deviceObject,
00573 irp,
00574 fileObject,
00575
FALSE,
00576 requestorMode,
00577 synchronousIo,
00578
OtherTransfer );
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
if (!synchronousIo) {
00589
00590 status =
IopSynchronousApiServiceTail( status,
00591 event,
00592 irp,
00593 requestorMode,
00594 &localIoStatus,
00595 IoStatusBlock );
00596 }
00597
00598
return status;
00599 }
00600
00601
NTSTATUS
00602 NtSetQuotaInformationFile(
00603 IN HANDLE FileHandle,
00604 OUT PIO_STATUS_BLOCK IoStatusBlock,
00605 IN PVOID Buffer,
00606 IN ULONG Length
00607 )
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 {
00636
PAGED_CODE();
00637
00638
00639
00640
00641
00642
00643
return IopSetEaOrQuotaInformationFile( FileHandle,
00644 IoStatusBlock,
00645
Buffer,
00646 Length,
00647
FALSE );
00648 }