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
00028
#include "fsrtlp.h"
00029
#include <zwapi.h>
00030
#include <ntddmup.h>
00031
#include <ntddnull.h>
00032
00033 static WCHAR
MupRegKey[] =
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup";
00034 static WCHAR
UNCSymbolicLink[] =
L"\\DosDevices\\UNC";
00035 static WCHAR
DevNull[] =
L"\\Device\\Null";
00036 static WCHAR
DevMup[] = DD_MUP_DEVICE_NAME;
00037
00038
00039
00040
00041
00042
#undef MODULE_POOL_TAG
00043 #define MODULE_POOL_TAG ('nuSF')
00044
00045
00046
00047
00048
00049
NTSTATUS
00050
FsRtlpRegisterProviderWithMUP
00051 (
00052 IN HANDLE mupHandle,
00053 IN PUNICODE_STRING
RedirDevName,
00054 IN BOOLEAN
MailslotsSupported
00055 );
00056
00057
NTSTATUS
00058
FsRtlpOpenDev(
00059 IN OUT PHANDLE Handle,
00060 IN LPWSTR DevNameStr
00061 );
00062
00063
VOID
00064
FsRtlpSetSymbolicLink(
00065 IN PUNICODE_STRING DevName OPTIONAL
00066 );
00067
00068 BOOLEAN
00069
FsRtlpIsDfsEnabled();
00070
00071
#ifdef ALLOC_PRAGMA
00072
#pragma alloc_text(PAGE, FsRtlpRegisterProviderWithMUP)
00073
#pragma alloc_text(PAGE, FsRtlpOpenDev)
00074
#pragma alloc_text(PAGE, FsRtlpSetSymbolicLink)
00075
#pragma alloc_text(PAGE, FsRtlDeregisterUncProvider)
00076
#pragma alloc_text(PAGE, FsRtlRegisterUncProvider)
00077
#endif
00078
00079
00080
00081
00082
00083
00084
struct {
00085 HANDLE
MupHandle;
00086 HANDLE
ReturnedHandle;
00087 UNICODE_STRING
RedirDevName;
00088 BOOLEAN
MailslotsSupported;
00089 }
FsRtlpDRD = {0};
00090
00091
00092
00093
00094 KSEMAPHORE FsRtlpUncSemaphore;
00095
00096
00097
00098
00099 ULONG
FsRtlpRedirs = 0;
00100
00101
00102
NTSTATUS
00103
FsRtlpRegisterProviderWithMUP
00104 (
00105 IN HANDLE mupHandle,
00106 IN PUNICODE_STRING
RedirDevName,
00107 IN BOOLEAN
MailslotsSupported
00108 )
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 {
00130
NTSTATUS status;
00131 IO_STATUS_BLOCK ioStatusBlock;
00132 ULONG paramLength;
00133 PREDIRECTOR_REGISTRATION params;
00134
00135
PAGED_CODE();
00136
00137 paramLength =
sizeof( REDIRECTOR_REGISTRATION ) +
00138
RedirDevName->Length;
00139
00140 params =
ExAllocatePoolWithTag(
NonPagedPool, paramLength,
MODULE_POOL_TAG );
00141
if( params ==
NULL )
00142
return STATUS_INSUFFICIENT_RESOURCES;
00143
00144 params->DeviceNameOffset =
sizeof( REDIRECTOR_REGISTRATION );
00145 params->DeviceNameLength =
RedirDevName->Length;
00146 params->MailslotsSupported =
MailslotsSupported;
00147
00148 RtlMoveMemory(
00149 (PCHAR)params + params->DeviceNameOffset,
00150
RedirDevName->Buffer,
00151
RedirDevName->Length
00152 );
00153
00154 status =
NtFsControlFile(
00155 mupHandle,
00156 0,
00157
NULL,
00158
NULL,
00159 &ioStatusBlock,
00160 FSCTL_MUP_REGISTER_UNC_PROVIDER,
00161 params,
00162 paramLength,
00163
NULL,
00164 0
00165 );
00166
00167
if ( status == STATUS_PENDING ) {
00168 status =
NtWaitForSingleObject( mupHandle,
TRUE,
NULL );
00169 }
00170
00171
if (
NT_SUCCESS( status ) ) {
00172 status = ioStatusBlock.Status;
00173 }
00174
00175
ASSERT(
NT_SUCCESS( status ) );
00176
00177
ExFreePool( params );
00178
00179
return status;
00180 }
00181
00182
NTSTATUS
00183 FsRtlpOpenDev(
00184 IN OUT PHANDLE Handle,
00185 IN LPWSTR DevNameStr
00186 )
00187 {
00188
NTSTATUS status;
00189 UNICODE_STRING DevName;
00190 OBJECT_ATTRIBUTES objectAttributes;
00191 IO_STATUS_BLOCK ioStatusBlock;
00192
00193
PAGED_CODE();
00194
00195
RtlInitUnicodeString( &DevName, DevNameStr );
00196
00197 InitializeObjectAttributes(
00198 &objectAttributes,
00199 &DevName,
00200 0,
00201 0,
00202
NULL
00203 );
00204
00205 status =
ZwCreateFile(
00206
Handle,
00207 GENERIC_WRITE,
00208 &objectAttributes,
00209 &ioStatusBlock,
00210
NULL,
00211 FILE_ATTRIBUTE_NORMAL,
00212 FILE_SHARE_READ | FILE_SHARE_WRITE,
00213 FILE_OPEN,
00214 0,
00215
NULL,
00216 0
00217 );
00218
00219
if (
NT_SUCCESS( status ) ) {
00220 status = ioStatusBlock.Status;
00221 }
00222
00223
if( !
NT_SUCCESS( status ) ) {
00224 *
Handle = (HANDLE)-1;
00225 }
00226
00227
return status;
00228 }
00229
00230
VOID
00231 FsRtlpSetSymbolicLink( IN PUNICODE_STRING DevName OPTIONAL )
00232 {
00233
NTSTATUS status;
00234 UNICODE_STRING UncSymbolicName;
00235
00236
PAGED_CODE();
00237
00238
RtlInitUnicodeString( &UncSymbolicName,
UNCSymbolicLink );
00239 (
VOID)
IoDeleteSymbolicLink( &UncSymbolicName );
00240
if( ARGUMENT_PRESENT( DevName ) ) {
00241 status =
IoCreateSymbolicLink( &UncSymbolicName, DevName );
00242
ASSERT(
NT_SUCCESS( status ) );
00243 }
00244 }
00245
00246
NTSTATUS
00247 FsRtlRegisterUncProvider(
00248 IN OUT PHANDLE MupHandle,
00249 IN PUNICODE_STRING RedirDevName,
00250 IN BOOLEAN MailslotsSupported
00251 )
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 {
00274
NTSTATUS status;
00275 HANDLE mupHandle = (HANDLE)-1;
00276 UNICODE_STRING mupDriverName;
00277 BOOLEAN dfsEnabled;
00278
00279
PAGED_CODE();
00280
00281
KeWaitForSingleObject(&
FsRtlpUncSemaphore,
Executive,
KernelMode,
FALSE,
NULL );
00282
00283
if (
FsRtlpRedirs == 0) {
00284
00285 dfsEnabled =
FsRtlpIsDfsEnabled();
00286
00287
if (dfsEnabled) {
00288
FsRtlpRedirs = 1;
00289 RtlZeroMemory((PVOID) &
FsRtlpDRD,
sizeof(
FsRtlpDRD));
00290 }
00291
00292 }
00293
00294
switch(
FsRtlpRedirs ) {
00295
case 0:
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 status =
FsRtlpOpenDev( &mupHandle,
DevNull );
00307
00308
if( !
NT_SUCCESS( status ) )
00309
break;
00310
00311
00312
00313
00314
00315
FsRtlpDRD.RedirDevName.Buffer =
ExAllocatePoolWithTag(
NonPagedPool,
00316
RedirDevName->MaximumLength,
00317
MODULE_POOL_TAG );
00318
00319
if(
FsRtlpDRD.RedirDevName.Buffer ==
NULL ) {
00320 status = STATUS_INSUFFICIENT_RESOURCES;
00321
break;
00322 }
00323
00324
FsRtlpDRD.RedirDevName.Length =
RedirDevName->Length;
00325
FsRtlpDRD.RedirDevName.MaximumLength =
RedirDevName->MaximumLength;
00326
00327 RtlMoveMemory(
00328 (PCHAR)
FsRtlpDRD.RedirDevName.Buffer,
00329
RedirDevName->Buffer,
00330
RedirDevName->MaximumLength
00331 );
00332
00333
FsRtlpDRD.MailslotsSupported =
MailslotsSupported;
00334
FsRtlpDRD.ReturnedHandle = mupHandle;
00335
FsRtlpDRD.MupHandle = (HANDLE)-1;
00336
00337
00338
00339
00340
FsRtlpSetSymbolicLink(
RedirDevName );
00341
00342
break;
00343
00344
default:
00345
00346
00347
00348 status =
FsRtlpOpenDev( &mupHandle,
DevMup );
00349
00350
if( !
NT_SUCCESS( status ) ) {
00351
00352
RtlInitUnicodeString( &mupDriverName,
MupRegKey );
00353
00354 (
VOID)
ZwLoadDriver( &mupDriverName );
00355
00356 status =
FsRtlpOpenDev( &mupHandle,
DevMup );
00357
if( !
NT_SUCCESS( status ) )
00358
break;
00359 }
00360
00361
00362
00363
00364
if(
FsRtlpDRD.RedirDevName.Buffer ) {
00365
00366 status =
FsRtlpRegisterProviderWithMUP( mupHandle,
00367 &
FsRtlpDRD.RedirDevName,
00368
FsRtlpDRD.MailslotsSupported );
00369
00370
if( !
NT_SUCCESS( status ) )
00371
break;
00372
00373
FsRtlpDRD.MupHandle = mupHandle;
00374
00375
ExFreePool(
FsRtlpDRD.RedirDevName.Buffer );
00376
FsRtlpDRD.RedirDevName.Buffer =
NULL;
00377
00378
00379
00380
00381
RtlInitUnicodeString( &mupDriverName,
DevMup );
00382
FsRtlpSetSymbolicLink( &mupDriverName );
00383
00384 status =
FsRtlpOpenDev( &mupHandle,
DevMup );
00385
00386
if( !
NT_SUCCESS( status ) )
00387
break;
00388 }
00389
00390
00391
00392
00393 status =
FsRtlpRegisterProviderWithMUP( mupHandle,
00394
RedirDevName,
00395
MailslotsSupported );
00396
break;
00397
00398 }
00399
00400
if(
NT_SUCCESS( status ) ) {
00401
FsRtlpRedirs++;
00402 *
MupHandle = mupHandle;
00403
00404 }
else {
00405
if( mupHandle != (HANDLE)-1 && mupHandle !=
NULL ) {
00406 ZwClose( mupHandle );
00407 }
00408
00409 *
MupHandle = (HANDLE)-1;
00410 }
00411
00412
KeReleaseSemaphore(&
FsRtlpUncSemaphore, 0, 1,
FALSE );
00413
return status;
00414 }
00415
00416
00417
VOID
00418 FsRtlDeregisterUncProvider(
00419 IN HANDLE Handle
00420 )
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 {
00440
NTSTATUS status;
00441
00442
PAGED_CODE();
00443
00444
if(
Handle == (HANDLE)-1 ||
Handle ==
NULL )
00445
return;
00446
00447 status = ZwClose(
Handle );
00448
00449
if( !
NT_SUCCESS( status ) ) {
00450
return;
00451 }
00452
00453
KeWaitForSingleObject(&
FsRtlpUncSemaphore,
Executive,
KernelMode,
FALSE,
NULL );
00454
00455
ASSERT(
FsRtlpRedirs > 0 );
00456
00457
if(
Handle ==
FsRtlpDRD.ReturnedHandle ) {
00458
00459
00460
00461
00462
00463
00464
if(
FsRtlpDRD.RedirDevName.Buffer !=
NULL ) {
00465
ExFreePool(
FsRtlpDRD.RedirDevName.Buffer );
00466
FsRtlpDRD.RedirDevName.Buffer =
NULL;
00467 }
00468
00469
if(
FsRtlpDRD.MupHandle != (HANDLE)-1 ) {
00470 ZwClose(
FsRtlpDRD.MupHandle );
00471
FsRtlpDRD.MupHandle = (HANDLE)-1;
00472 }
00473
00474
FsRtlpDRD.ReturnedHandle = (HANDLE)-1;
00475
00476 }
00477
00478
if( --
FsRtlpRedirs == 0 ) {
00479
FsRtlpSetSymbolicLink( (PUNICODE_STRING)
NULL );
00480 }
00481
00482
KeReleaseSemaphore(&
FsRtlpUncSemaphore, 0, 1,
FALSE );
00483 }
00484
00485
00486 BOOLEAN
00487 FsRtlpIsDfsEnabled()
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 {
00508
NTSTATUS status;
00509 HANDLE mupRegHandle;
00510 OBJECT_ATTRIBUTES objectAttributes;
00511 ULONG valueSize;
00512 BOOLEAN dfsEnabled =
TRUE;
00513
00514 UNICODE_STRING mupRegKey = {
00515
sizeof(
MupRegKey) -
sizeof(WCHAR),
00516
sizeof(
MupRegKey),
00517
MupRegKey};
00518
00519
#define DISABLE_DFS_VALUE_NAME L"DisableDfs"
00520
00521 UNICODE_STRING disableDfs = {
00522
sizeof(
DISABLE_DFS_VALUE_NAME) -
sizeof(WCHAR),
00523
sizeof(
DISABLE_DFS_VALUE_NAME),
00524
DISABLE_DFS_VALUE_NAME};
00525
00526
struct {
00527 KEY_VALUE_PARTIAL_INFORMATION Info;
00528 ULONG
Buffer;
00529 } disableDfsValue;
00530
00531
00532 InitializeObjectAttributes(
00533 &objectAttributes,
00534 &mupRegKey,
00535 OBJ_CASE_INSENSITIVE,
00536 0,
00537
NULL
00538 );
00539
00540 status = ZwOpenKey(&mupRegHandle, KEY_READ, &objectAttributes);
00541
00542
if (
NT_SUCCESS(status)) {
00543
00544 status = ZwQueryValueKey(
00545 mupRegHandle,
00546 &disableDfs,
00547 KeyValuePartialInformation,
00548 (PVOID) &disableDfsValue,
00549
sizeof(disableDfsValue),
00550 &valueSize);
00551
00552
if (
NT_SUCCESS(status) && disableDfsValue.Info.Type == REG_DWORD) {
00553
00554
if ( (*((PULONG) disableDfsValue.Info.Data)) == 1 )
00555 dfsEnabled =
FALSE;
00556
00557 }
00558
00559 ZwClose( mupRegHandle );
00560
00561 }
00562
00563
return( dfsEnabled );
00564
00565 }