00098 : PVDMQUERYDIRINFO pVdmQueryDir
00099
00100 FileHandle - Supplies a handle to
the directory
file for which information
00101 should be returned.
00102
00103 FileInformation - Supplies a buffer to receive
the requested information
00104 returned about
the contents of
the directory.
00105
00106 Length - Supplies
the length, in bytes, of
the FileInformation buffer.
00107
00108
FileName - Supplies a
file name within
the specified directory.
00109
00110 FileIndex - Supplies a
file index within
the specified directory.
00111
00112 The FileInformationClass
is assumed to be FILE_BOTH_DIR_INFORMATION
00113 The Caller's mode
is assumed to be
UserMode
00114 Synchronous IO
is used
00115
00116 --*/
00117
00118 {
00119 KIRQL irql;
00120
NTSTATUS status;
00121
PKEVENT Event;
00122
00123 HANDLE FileHandle;
00124 IO_STATUS_BLOCK IoStatusBlock;
00125 PVOID FileInformation;
00126 ULONG Length;
00127 UNICODE_STRING
FileName;
00128 PUNICODE_STRING pFileNameSrc;
00129 ULONG FileIndex;
00130
00131
PQDIR_POOLDATA QDirPoolData =
NULL;
00132 FILE_FS_DEVICE_INFORMATION DeviceInfo;
00133
00134
PMDL mdl;
00135
PIRP irp;
00136
PIO_STACK_LOCATION irpSp;
00137 PCHAR SystemBuffer;
00138
PFILE_OBJECT fileObject;
00139
PDEVICE_OBJECT DeviceObject;
00140
00141
00142
PAGED_CODE();
00143
00144
00145
00146
00147
00148
00149
try {
00150
00151
00152
00153
00154
ProbeForRead( pVdmQueryDir,
sizeof(VDMQUERYDIRINFO),
sizeof(ULONG));
00155
00156 FileHandle = pVdmQueryDir->FileHandle;
00157 FileInformation = pVdmQueryDir->FileInformation;
00158 Length = pVdmQueryDir->Length;
00159 FileIndex = pVdmQueryDir->FileIndex;
00160 pFileNameSrc = pVdmQueryDir->FileName;
00161
00162
00163
00164
00165
00166
00167
00168
00169
if (
NULL == pFileNameSrc) {
00170
return(STATUS_INVALID_PARAMETER);
00171 }
00172
00173
FileName =
ProbeAndReadUnicodeString(pFileNameSrc);
00174
if (!
FileName.Length ||
00175
FileName.Length > MAXIMUM_FILENAME_LENGTH<<1) {
00176
return(STATUS_INVALID_PARAMETER);
00177 }
00178
00179
ProbeForRead(
FileName.Buffer,
FileName.Length,
sizeof( UCHAR ));
00180
00181
00182
00183
00184
00185
ProbeForWrite( FileInformation, Length,
sizeof( ULONG ) );
00186
00187
00188
00189
00190
00191
00192
00193
if (Length <
sizeof(FILE_BOTH_DIR_INFORMATION)) {
00194
return STATUS_INFO_LENGTH_MISMATCH;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204 QDirPoolData = (
PQDIR_POOLDATA)
ExAllocatePoolWithQuotaTag(
00205 NonPagedPool,
00206
sizeof(
QDIR_POOLDATA) +
FileName.Length,
00207 ' MDV');
00208
00209
00210
00211
00212
00213 QDirPoolData->
FileName.Length =
FileName.Length;
00214 QDirPoolData->
FileName.MaximumLength =
FileName.Length;
00215 QDirPoolData->
FileName.Buffer = QDirPoolData->
FileNameBuf;
00216 RtlCopyMemory( QDirPoolData->
FileNameBuf,
00217
FileName.Buffer,
00218
FileName.Length );
00219
00220
00221 } except(EXCEPTION_EXECUTE_HANDLER) {
00222
00223
if (QDirPoolData) {
00224
ExFreePool(QDirPoolData);
00225 }
00226
00227
return GetExceptionCode();
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 status =
ObReferenceObjectByHandle( FileHandle,
00238 FILE_LIST_DIRECTORY,
00239 IoFileObjectType,
00240 UserMode,
00241 (PVOID *) &fileObject,
00242 (
POBJECT_HANDLE_INFORMATION) NULL );
00243
if (!
NT_SUCCESS( status )) {
00244
if (QDirPoolData) {
00245
ExFreePool(QDirPoolData);
00246 }
00247
return status;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
Event = &QDirPoolData->
kevent;
00260
KeInitializeEvent(Event, SynchronizationEvent, FALSE);
00261
00262
00263
00264
00265
00266
00267
KeClearEvent( &fileObject->Event );
00268
00269
00270
00271
00272
00273 DeviceObject =
IoGetRelatedDeviceObject( fileObject );
00274
00275
00276
00277
00278
00279
00280 irp =
IoAllocateIrp( DeviceObject->
StackSize, TRUE );
00281
if (!irp) {
00282
00283
00284
00285
00286
00287
00288
ObDereferenceObject( fileObject );
00289
if (QDirPoolData) {
00290
ExFreePool(QDirPoolData);
00291 }
00292
00293
return STATUS_INSUFFICIENT_RESOURCES;
00294 }
00295
00296
00297
00298
00299
00300 irp->
Flags = (ULONG)
IRP_SYNCHRONOUS_API;
00301 irp->
RequestorMode =
UserMode;
00302
00303 irp->
UserIosb = &IoStatusBlock;
00304 irp->
UserEvent =
Event;
00305
00306 irp->
Overlay.AsynchronousParameters.UserApcRoutine =
NULL;
00307 irp->
AssociatedIrp.SystemBuffer = (PVOID)
NULL;
00308 SystemBuffer =
NULL;
00309
00310
00311 irp->
Tail.Overlay.Thread =
PsGetCurrentThread();
00312 irp->
Tail.Overlay.OriginalFileObject = fileObject;
00313 irp->
Tail.Overlay.AuxiliaryBuffer =
NULL;
00314 irp->
MdlAddress =
NULL;
00315
00316
00317
00318
00319
00320
00321 irpSp =
IoGetNextIrpStackLocation( irp );
00322 irpSp->
MajorFunction =
IRP_MJ_DIRECTORY_CONTROL;
00323 irpSp->
MinorFunction =
IRP_MN_QUERY_DIRECTORY;
00324 irpSp->
FileObject = fileObject;
00325
00326
00327
00328
00329
00330
00331
00332 irpSp->
Parameters.QueryDirectory.Length = Length;
00333 irpSp->
Parameters.QueryDirectory.FileInformationClass = FileBothDirectoryInformation;
00334 irpSp->
Parameters.QueryDirectory.FileIndex = FileIndex;
00335
00336
if (QDirPoolData->
FileName.Length) {
00337 irpSp->
Parameters.QueryDirectory.FileName = (PSTRING)&QDirPoolData->
FileName;
00338 }
else {
00339 irpSp->
Parameters.QueryDirectory.FileName =
NULL;
00340 }
00341
00342 irpSp->
Flags =
SL_INDEX_SPECIFIED;
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
if (DeviceObject->
Flags &
DO_BUFFERED_IO) {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
try {
00365
00366
00367
00368
00369
00370
00371 SystemBuffer =
ExAllocatePoolWithQuotaTag( NonPagedPool,
00372 Length,
00373 ' MDV' );
00374
00375 irp->
AssociatedIrp.SystemBuffer = SystemBuffer;
00376
00377
00378 } except(EXCEPTION_EXECUTE_HANDLER) {
00379
00380
IoFreeIrp(irp);
00381
00382
ObDereferenceObject( fileObject );
00383
00384
if (QDirPoolData) {
00385
ExFreePool(QDirPoolData);
00386 }
00387
00388
return GetExceptionCode();
00389 }
00390
00391
00392 }
else if (DeviceObject->
Flags &
DO_DIRECT_IO) {
00393
00394
00395
00396
00397
00398
00399
00400
00401 mdl = (
PMDL)
NULL;
00402
00403
try {
00404
00405
00406
00407
00408
00409
00410
00411
00412 mdl =
IoAllocateMdl( FileInformation, Length, FALSE, TRUE, irp );
00413
if (mdl ==
NULL) {
00414
ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES );
00415 }
00416
MmProbeAndLockPages( mdl, UserMode, IoWriteAccess );
00417
00418 } except(EXCEPTION_EXECUTE_HANDLER) {
00419
00420
if (irp->
MdlAddress !=
NULL) {
00421
IoFreeMdl( irp->
MdlAddress );
00422 }
00423
00424
IoFreeIrp(irp);
00425
00426
ObDereferenceObject( fileObject );
00427
00428
if (QDirPoolData) {
00429
ExFreePool(QDirPoolData);
00430 }
00431
00432
return GetExceptionCode();
00433 }
00434
00435 }
else {
00436
00437
00438
00439
00440
00441
00442 irp->
UserBuffer = FileInformation;
00443
00444 }
00445
00446
00447
00448
00449
00450
00451
KeRaiseIrql( APC_LEVEL, &irql );
00452 InsertHeadList( &irp->
Tail.Overlay.Thread->IrpList,
00453 &irp->
ThreadListEntry );
00454
KeLowerIrql( irql );
00455
00456
00457
00458
00459
00460
00461 status =
IoCallDriver(DeviceObject, irp);
00462
00463
if (status == STATUS_PENDING) {
00464 status =
KeWaitForSingleObject(
00465 Event,
00466 UserRequest,
00467 UserMode,
00468 FALSE,
00469 NULL );
00470 }
00471
00472
if (
NT_SUCCESS(status)) {
00473 status = IoStatusBlock.Status;
00474
if (
NT_SUCCESS(status) || status == STATUS_BUFFER_OVERFLOW) {
00475
if (SystemBuffer) {
00476
try {
00477 RtlCopyMemory( FileInformation,
00478 SystemBuffer,
00479 IoStatusBlock.Information
00480 );
00481
00482 } except(EXCEPTION_EXECUTE_HANDLER) {
00483 status = GetExceptionCode();
00484 }
00485 }
00486 }
00487 }
00488
00489
00490
00491
00492
00493
if (QDirPoolData) {
00494
ExFreePool(QDirPoolData);
00495 }
00496
00497
if (SystemBuffer) {
00498
ExFreePool(SystemBuffer);
00499 }
00500
00501
00502
return status;
00503 }