Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

unc.c File Reference

#include "fsrtlp.h"
#include <zwapi.h>
#include <ntddmup.h>
#include <ntddnull.h>

Go to the source code of this file.

Defines

#define MODULE_POOL_TAG   ('nuSF')
#define DISABLE_DFS_VALUE_NAME   L"DisableDfs"

Functions

NTSTATUS FsRtlpRegisterProviderWithMUP (IN HANDLE mupHandle, IN PUNICODE_STRING RedirDevName, IN BOOLEAN MailslotsSupported)
NTSTATUS FsRtlpOpenDev (IN OUT PHANDLE Handle, IN LPWSTR DevNameStr)
VOID FsRtlpSetSymbolicLink (IN PUNICODE_STRING DevName OPTIONAL)
BOOLEAN FsRtlpIsDfsEnabled ()
NTSTATUS FsRtlRegisterUncProvider (IN OUT PHANDLE MupHandle, IN PUNICODE_STRING RedirDevName, IN BOOLEAN MailslotsSupported)
VOID FsRtlDeregisterUncProvider (IN HANDLE Handle)

Variables

WCHAR MupRegKey [] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup"
WCHAR UNCSymbolicLink [] = L"\\DosDevices\\UNC"
WCHAR DevNull [] = L"\\Device\\Null"
WCHAR DevMup [] = DD_MUP_DEVICE_NAME
struct {
   HANDLE   MupHandle
   HANDLE   ReturnedHandle
   UNICODE_STRING   RedirDevName
   BOOLEAN   MailslotsSupported
FsRtlpDRD
KSEMAPHORE FsRtlpUncSemaphore
ULONG FsRtlpRedirs = 0


Define Documentation

#define DISABLE_DFS_VALUE_NAME   L"DisableDfs"
 

Referenced by FsRtlpIsDfsEnabled().

#define MODULE_POOL_TAG   ('nuSF')
 

Definition at line 43 of file unc.c.


Function Documentation

VOID FsRtlDeregisterUncProvider IN HANDLE  Handle  ) 
 

Definition at line 418 of file unc.c.

References ASSERT, Executive, ExFreePool(), FALSE, FsRtlpDRD, FsRtlpRedirs, FsRtlpSetSymbolicLink(), FsRtlpUncSemaphore, Handle, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

00424 : 00425 00426 This routine deregisters a redir as a UNC provider. 00427 00428 Arguments: 00429 00430 Handle - A handle to the Multiple UNC router, returned by the 00431 registration call. 00432 00433 Return Value: 00434 00435 None. 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 // The first redir in the system is closing. Release the state we saved 00461 // for it, and pass the close on to the MUP if necessary 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 }

BOOLEAN FsRtlpIsDfsEnabled  ) 
 

Definition at line 487 of file unc.c.

References Buffer, DISABLE_DFS_VALUE_NAME, FALSE, MupRegKey, NT_SUCCESS, NTSTATUS(), NULL, and TRUE.

Referenced by FsRtlRegisterUncProvider().

00491 : 00492 00493 This routine checks a registry key to see if the Dfs client is enabled. 00494 The client is assumed to be enabled by default, and disabled only if there 00495 is a registry value indicating that it should be disabled. 00496 00497 Arguments: 00498 00499 None 00500 00501 Return Value: 00502 00503 TRUE if Dfs client is enabled, FALSE otherwise. 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 } }

NTSTATUS FsRtlpOpenDev IN OUT PHANDLE  Handle,
IN LPWSTR  DevNameStr
 

Definition at line 183 of file unc.c.

References Handle, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RtlInitUnicodeString(), and ZwCreateFile().

Referenced by FsRtlRegisterUncProvider().

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 }

NTSTATUS FsRtlpRegisterProviderWithMUP IN HANDLE  mupHandle,
IN PUNICODE_STRING  RedirDevName,
IN BOOLEAN  MailslotsSupported
 

Definition at line 104 of file unc.c.

References ASSERT, ExAllocatePoolWithTag, ExFreePool(), MailslotsSupported, MODULE_POOL_TAG, NonPagedPool, NT_SUCCESS, NtFsControlFile(), NTSTATUS(), NtWaitForSingleObject(), NULL, PAGED_CODE, RedirDevName, and TRUE.

Referenced by FsRtlRegisterUncProvider().

00111 : 00112 00113 This private routine does the FSCTL to the MUP to tell it about 00114 a new redir 00115 00116 Arguments: 00117 00118 mupHandle - Handle to the MUP 00119 00120 RedirDevName - The device name of the redir. 00121 00122 MailslotsSupported - If TRUE, this redir supports mailslots. 00123 00124 Return Value: 00125 00126 NTSTATUS - The status of the operation. 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 }

VOID FsRtlpSetSymbolicLink IN PUNICODE_STRING DevName  OPTIONAL  ) 
 

Definition at line 231 of file unc.c.

References ASSERT, IoCreateSymbolicLink(), IoDeleteSymbolicLink(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, RtlInitUnicodeString(), UNCSymbolicLink, and VOID().

Referenced by FsRtlDeregisterUncProvider(), and FsRtlRegisterUncProvider().

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 }

NTSTATUS FsRtlRegisterUncProvider IN OUT PHANDLE  MupHandle,
IN PUNICODE_STRING  RedirDevName,
IN BOOLEAN  MailslotsSupported
 

Definition at line 247 of file unc.c.

References DevMup, DevNull, ExAllocatePoolWithTag, Executive, ExFreePool(), FALSE, FsRtlpDRD, FsRtlpIsDfsEnabled(), FsRtlpOpenDev(), FsRtlpRedirs, FsRtlpRegisterProviderWithMUP(), FsRtlpSetSymbolicLink(), FsRtlpUncSemaphore, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), MailslotsSupported, MODULE_POOL_TAG, MupHandle, MupRegKey, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RedirDevName, RtlInitUnicodeString(), VOID(), and ZwLoadDriver().

00254 : 00255 00256 This routine registers a redir as a UNC provider. 00257 00258 Arguments: 00259 00260 Handle - Pointer to a handle. The handle is returned by the routine 00261 to be used when calling FsRtlDeregisterUncProvider. 00262 It is valid only if the routines returns STATUS_SUCCESS. 00263 00264 RedirDevName - The device name of the redir. 00265 00266 MailslotsSupported - If TRUE, this redir supports mailslots. 00267 00268 Return Value: 00269 00270 NTSTATUS - The status of the operation. 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 // Ok, the MUP isn't there and we don't need to use the 00298 // MUP for the first redir. 00299 // 00300 // We need to return a handle, but we're not really using the MUP yet. 00301 // And we may never use it (if there's only 1 redir). Return 00302 // a handle to the NULL device object, since we're committed to returning 00303 // a handle to our caller. Our caller isn't supposed to do anything with 00304 // the handle except to call FsRtlDeregisterUncProvider() with it. 00305 // 00306 status = FsRtlpOpenDev( &mupHandle, DevNull ); 00307 00308 if( !NT_SUCCESS( status ) ) 00309 break; 00310 00311 // 00312 // Save up enough state to allow us to call the MUP later with 00313 // this registration info if necessary. 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 // Set the UNC symbolic link to point to the redir we just loaded 00339 // 00340 FsRtlpSetSymbolicLink( RedirDevName ); 00341 00342 break; 00343 00344 default: 00345 // 00346 // This is the second or later redir load -- MUST use the MUP 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 // See if we need to tell the MUP about the first redir that registered 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 // Set the UNC symbolic link to point to the MUP 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 // Pass the request to the MUP for this redir 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 }


Variable Documentation

WCHAR DevMup[] = DD_MUP_DEVICE_NAME [static]
 

Definition at line 36 of file unc.c.

Referenced by FsRtlRegisterUncProvider().

WCHAR DevNull[] = L"\\Device\\Null" [static]
 

Definition at line 35 of file unc.c.

Referenced by FsRtlRegisterUncProvider().

struct { ... } FsRtlpDRD
 

Referenced by FsRtlDeregisterUncProvider(), and FsRtlRegisterUncProvider().

ULONG FsRtlpRedirs = 0
 

Definition at line 99 of file unc.c.

Referenced by FsRtlDeregisterUncProvider(), and FsRtlRegisterUncProvider().

KSEMAPHORE FsRtlpUncSemaphore
 

Definition at line 94 of file unc.c.

Referenced by FsRtlDeregisterUncProvider(), FsRtlInitSystem(), and FsRtlRegisterUncProvider().

BOOLEAN MailslotsSupported
 

Definition at line 88 of file unc.c.

Referenced by FsRtlpRegisterProviderWithMUP(), and FsRtlRegisterUncProvider().

HANDLE MupHandle
 

Definition at line 85 of file unc.c.

Referenced by FsRtlRegisterUncProvider().

WCHAR MupRegKey[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup" [static]
 

Definition at line 33 of file unc.c.

Referenced by FsRtlpIsDfsEnabled(), and FsRtlRegisterUncProvider().

UNICODE_STRING RedirDevName
 

Definition at line 87 of file unc.c.

Referenced by FsRtlpRegisterProviderWithMUP(), and FsRtlRegisterUncProvider().

HANDLE ReturnedHandle
 

Definition at line 86 of file unc.c.

Referenced by IopCreateMadeupNode().

WCHAR UNCSymbolicLink[] = L"\\DosDevices\\UNC" [static]
 

Definition at line 34 of file unc.c.

Referenced by FsRtlpSetSymbolicLink().


Generated on Sat May 15 19:45:52 2004 for test by doxygen 1.3.7