00250 :
00251
00252 This service dynamically unloads a device or
file system driver from
00253
the currently running system. It requires that
the caller have
the
00254 appropriate privilege to execute
this service.
00255
00256 Arguments:
00257
00258 DriverServiceName - Specifies
the name of
the node in
the registry
00259 associated with
the driver to be unloaded.
00260
00261 Return Value:
00262
00263 The status returned
is the final completion status of
the operation.
00264
00265 --*/
00266
00267 {
00268
KPROCESSOR_MODE requestorMode;
00269 UNICODE_STRING driverServiceName;
00270 PWCHAR nameBuffer = (PWCHAR)
NULL;
00271
NTSTATUS status;
00272 OBJECT_ATTRIBUTES objectAttributes;
00273 HANDLE keyHandle;
00274 UNICODE_STRING driverName;
00275 HANDLE driverHandle;
00276
PDRIVER_OBJECT driverObject;
00277 BOOLEAN unloadDriver;
00278
00279
PAGED_CODE();
00280
00281
00282
00283
00284
00285 requestorMode = KeGetPreviousMode();
00286
00287
if (requestorMode !=
KernelMode) {
00288
00289
00290
00291
00292
00293
00294
00295
if (!
SeSinglePrivilegeCheck( SeLoadDriverPrivilege, requestorMode )) {
00296
return STATUS_PRIVILEGE_NOT_HELD;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
try {
00306
00307 driverServiceName =
ProbeAndReadUnicodeString( DriverServiceName );
00308
00309
if (!driverServiceName.Length) {
00310
return STATUS_INVALID_PARAMETER;
00311 }
00312
00313
ProbeForRead( driverServiceName.Buffer,
00314 driverServiceName.Length,
00315
sizeof( WCHAR ) );
00316
00317 nameBuffer =
ExAllocatePoolWithQuota( PagedPool,
00318 driverServiceName.Length );
00319
00320 RtlCopyMemory( nameBuffer,
00321 driverServiceName.Buffer,
00322 driverServiceName.Length );
00323
00324 driverServiceName.Buffer = nameBuffer;
00325
00326 } except(EXCEPTION_EXECUTE_HANDLER) {
00327
00328
00329
00330
00331
00332
00333
00334
00335
if (nameBuffer) {
00336
ExFreePool( nameBuffer );
00337 }
00338
return GetExceptionCode();
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 status = ZwUnloadDriver( &driverServiceName );
00351
ExFreePool( nameBuffer );
00352
return status;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 status =
IopOpenRegistryKey( &keyHandle,
00362 (HANDLE) NULL,
00363 DriverServiceName,
00364 KEY_READ,
00365 FALSE );
00366
if (!
NT_SUCCESS( status )) {
00367
return status;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376 status =
IopGetDriverNameFromKeyNode( keyHandle,
00377 &driverName );
00378
NtClose( keyHandle );
00379
if (!
NT_SUCCESS( status )) {
00380
return status;
00381 }
00382
00383
00384
00385
00386
00387 InitializeObjectAttributes( &objectAttributes,
00388 &driverName,
00389 OBJ_CASE_INSENSITIVE,
00390 (HANDLE) NULL,
00391 (PSECURITY_DESCRIPTOR) NULL );
00392
00393 status =
ObOpenObjectByName( &objectAttributes,
00394 IoDriverObjectType,
00395 KernelMode,
00396 NULL,
00397 FILE_READ_DATA,
00398 (PVOID) NULL,
00399 &driverHandle );
00400
00401
00402
00403
00404
00405
00406
00407
ExFreePool( driverName.Buffer );
00408
00409
00410
00411
00412
00413
00414
if (!
NT_SUCCESS( status )) {
00415
return status;
00416 }
00417
00418
00419
00420
00421
00422
00423 status =
ObReferenceObjectByHandle( driverHandle,
00424 0,
00425 IoDriverObjectType,
00426 KernelMode,
00427 (PVOID *) &driverObject,
00428 NULL );
00429
NtClose( driverHandle );
00430
00431
if (!
NT_SUCCESS( status )) {
00432
return status;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
if (driverObject->
DriverUnload == (
PDRIVER_UNLOAD)
NULL ||
00443 !driverObject->
DriverSection) {
00444
ObDereferenceObject( driverObject );
00445
return STATUS_INVALID_DEVICE_REQUEST;
00446 }
00447
00448
00449
00450
00451
00452
00453 status =
IopCheckUnloadDriver(driverObject,&unloadDriver);
00454
00455
if (
NT_SUCCESS(status) ) {
00456
return status;
00457 }
00458
00459
if (unloadDriver) {
00460
00461
if (
PsGetCurrentProcess() ==
PsInitialSystemProcess) {
00462
00463
00464
00465
00466
00467
00468 driverObject->
DriverUnload( driverObject );
00469
00470 }
else {
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
LOAD_PACKET loadPacket;
00481
00482
KeInitializeEvent( &loadPacket.
Event, NotificationEvent, FALSE );
00483 loadPacket.
DriverObject = driverObject;
00484
ExInitializeWorkItem( &loadPacket.
WorkQueueItem,
00485 IopLoadUnloadDriver,
00486 &loadPacket );
00487
ExQueueWorkItem( &loadPacket.
WorkQueueItem, DelayedWorkQueue );
00488 (
VOID)
KeWaitForSingleObject( &loadPacket.
Event,
00489 Executive,
00490 KernelMode,
00491 FALSE,
00492 (PLARGE_INTEGER) NULL );
00493 }
00494
ObMakeTemporaryObject( driverObject );
00495
ObDereferenceObject( driverObject );
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
ObDereferenceObject( driverObject );
00505
return STATUS_SUCCESS;
00506 }
}