00049 :
00050
00051 This service returns quota entries associated with
the volume specified
00052 by
the FileHandle parameter. The amount of information returned
is based
00053 on
the size of
the quota information associated with
the volume,
the size
00054 of
the buffer, and whether or not a specific set of entries has been
00055 requested.
00056
00057 Arguments:
00058
00059 FileHandle - Supplies a handle to
the file/volume
for which
the quota
00060 information
is returned.
00061
00062 IoStatusBlock - Address of
the caller's I/O status block.
00063
00064
Buffer - Supplies a buffer to receive
the quota information
for the volume.
00065
00066 Length - Supplies
the length, in bytes, of
the buffer.
00067
00068 ReturnSingleEntry - Indicates that
only a single entry should be returned
00069 rather than filling
the buffer with as many entries as possible.
00070
00071 SidList - Optionally supplies a list of SIDs whose quota information
is to
00072 be returned.
00073
00074 SidListLength - Supplies
the length of
the SID list,
if one was specified.
00075
00076 StartSid - Supplies an optional SID that indicates that
the returned
00077 information
is to start with an entry other than
the first. This
00078 parameter
is ignored
if a SidList
is specified.
00079
00080 RestartScan - Indicates whether
the scan of
the quota information
is to be
00081 restarted from
the beginning.
00082
00083 Return Value:
00084
00085 The status returned
is the final completion status of
the operation.
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 }