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, NtLoadDriver)
00031
#pragma alloc_text(PAGE, NtUnloadDriver)
00032
#endif
00033
00034
NTSTATUS
00035 NtLoadDriver(
00036 IN PUNICODE_STRING DriverServiceName
00037 )
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 {
00059
KPROCESSOR_MODE requestorMode;
00060 UNICODE_STRING driverServiceName;
00061 PWCHAR nameBuffer = (PWCHAR)
NULL;
00062
LOAD_PACKET loadPacket;
00063
00064
PAGED_CODE();
00065
00066
00067
00068
00069
00070 requestorMode = KeGetPreviousMode();
00071
00072
if (requestorMode !=
KernelMode) {
00073
00074
00075
00076
00077
00078
00079
00080
if (!
SeSinglePrivilegeCheck(
SeLoadDriverPrivilege, requestorMode )) {
00081
return STATUS_PRIVILEGE_NOT_HELD;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
try {
00091
00092 driverServiceName =
ProbeAndReadUnicodeString( DriverServiceName );
00093
00094
if (!driverServiceName.Length) {
00095
return STATUS_INVALID_PARAMETER;
00096 }
00097
00098
ProbeForRead( driverServiceName.Buffer,
00099 driverServiceName.Length,
00100
sizeof( WCHAR ) );
00101
00102 nameBuffer =
ExAllocatePoolWithQuota(
PagedPool,
00103 driverServiceName.Length );
00104
00105 RtlCopyMemory( nameBuffer,
00106 driverServiceName.Buffer,
00107 driverServiceName.Length );
00108
00109 driverServiceName.Buffer = nameBuffer;
00110
00111 } except(
EXCEPTION_EXECUTE_HANDLER) {
00112
00113
00114
00115
00116
00117
00118
00119
00120
if (nameBuffer) {
00121
ExFreePool( nameBuffer );
00122 }
00123
return GetExceptionCode();
00124 }
00125 }
else {
00126 driverServiceName = *DriverServiceName;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
KeInitializeEvent( &loadPacket.
Event, NotificationEvent,
FALSE );
00141 loadPacket.
DriverObject = (
PDRIVER_OBJECT)
NULL;
00142 loadPacket.
DriverServiceName = &driverServiceName;
00143
00144
if (
PsGetCurrentProcess() ==
PsInitialSystemProcess) {
00145
00146
00147
00148
00149
00150
IopLoadUnloadDriver(&loadPacket);
00151
00152 }
else {
00153
00154
ExInitializeWorkItem( &loadPacket.
WorkQueueItem,
00155
IopLoadUnloadDriver,
00156 &loadPacket );
00157
00158
ExQueueWorkItem( &loadPacket.
WorkQueueItem,
DelayedWorkQueue );
00159
00160
KeWaitForSingleObject( &loadPacket.
Event,
00161
UserRequest,
00162
KernelMode,
00163
FALSE,
00164 (PLARGE_INTEGER)
NULL );
00165
00166 }
00167
00168
00169
00170
00171
00172
00173
if (nameBuffer) {
00174
ExFreePool( nameBuffer );
00175 }
00176
00177
return loadPacket.
FinalStatus;
00178 }
00179
00180
NTSTATUS
00181 IopCheckUnloadDriver(
00182 IN
PDRIVER_OBJECT driverObject,
00183 OUT PBOOLEAN unloadDriver
00184 )
00185 {
00186
PDEVICE_OBJECT deviceObject;
00187 KIRQL irql;
00188
00189
00190
00191
00192
00193
00194 ExAcquireSpinLock( &
IopDatabaseLock, &irql );
00195
00196
if ((driverObject->DeviceObject ==
NULL &&
00197 (driverObject->Flags &
DRVO_UNLOAD_INVOKED)) ||
00198 (driverObject->DeviceObject &&
00199 driverObject->DeviceObject->DeviceObjectExtension->ExtensionFlags
00200 &
DOE_UNLOAD_PENDING)) {
00201
00202
00203
00204
00205
00206
00207
00208
00209 ExReleaseSpinLock( &
IopDatabaseLock, irql );
00210
00211
ObDereferenceObject( driverObject );
00212
return STATUS_SUCCESS;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 deviceObject = driverObject->DeviceObject;
00225 *unloadDriver =
TRUE;
00226
00227
while (deviceObject) {
00228 deviceObject->
DeviceObjectExtension->
ExtensionFlags |=
DOE_UNLOAD_PENDING;
00229
if (deviceObject->
ReferenceCount || deviceObject->
AttachedDevice) {
00230 *unloadDriver =
FALSE;
00231 }
00232 deviceObject = deviceObject->
NextDevice;
00233 }
00234
00235
if (*unloadDriver) {
00236 driverObject->
Flags |=
DRVO_UNLOAD_INVOKED;
00237 }
00238
00239 ExReleaseSpinLock( &
IopDatabaseLock, irql );
00240
return STATUS_UNSUCCESSFUL;
00241 }
00242
00243
NTSTATUS
00244 NtUnloadDriver(
00245 IN PUNICODE_STRING DriverServiceName
00246 )
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
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 }