2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include "AFSCommon.h"
44 extern void *KeServiceDescriptorTable;
48 typedef NTSTATUS (*PsSetCreateProcessNotifyRoutineEx_t)( PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine, BOOLEAN Remove);
53 // This is the initial entry point for the driver.
56 // DriverObject Pointer to Driver Object created by I/O manager
57 // RegistryPath Pointer to registry path representing this Driver
60 // Success To indicate Driver's inituaialization processing
62 // NT ERROR STATUS Otherwise -- Driver does not remain loaded
66 DriverEntry( PDRIVER_OBJECT DriverObject,
67 PUNICODE_STRING RegistryPath)
70 NTSTATUS ntStatus = STATUS_SUCCESS;
71 AFSDeviceExt *pDeviceExt = NULL;
72 UNICODE_STRING uniSymLinkName;
73 UNICODE_STRING uniDeviceName;
76 UNICODE_STRING uniValueName;
77 BOOLEAN bExit = FALSE;
78 UNICODE_STRING uniRoutine;
79 RTL_OSVERSIONINFOW sysVersion;
80 UNICODE_STRING uniPsSetCreateProcessNotifyRoutineEx;
81 PsSetCreateProcessNotifyRoutineEx_t pPsSetCreateProcessNotifyRoutineEx = NULL;
86 DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__);
89 // Initialize some local variables for easier processing
92 uniSymLinkName.Buffer = NULL;
94 AFSDumpFileLocation.Length = 0;
95 AFSDumpFileLocation.MaximumLength = 0;
96 AFSDumpFileLocation.Buffer = NULL;
98 AFSDumpFileName.Length = 0;
99 AFSDumpFileName.Buffer = NULL;
100 AFSDumpFileName.MaximumLength = 0;
102 ExInitializeResourceLite( &AFSDbgLogLock);
105 // Initialize the server name
110 AFSReadMountRootName();
112 RtlZeroMemory( &sysVersion,
113 sizeof( RTL_OSVERSIONINFOW));
115 sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);
117 RtlGetVersion( &sysVersion);
119 RtlInitUnicodeString( &uniRoutine,
120 L"ZwSetInformationToken");
122 AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine);
124 if( AFSSetInformationToken == NULL)
127 AFSSrvcTableEntry *pServiceTable = NULL;
129 pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable;
132 // Only perform this lookup for Windows XP.
135 if( pServiceTable != NULL &&
136 sysVersion.dwMajorVersion == 5 &&
137 sysVersion.dwMinorVersion == 1)
139 AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6];
145 // And the global root share name
148 RtlInitUnicodeString( &AFSGlobalRootName,
149 AFS_GLOBAL_ROOT_SHARE_NAME);
151 RtlZeroMemory( &AFSNoPAGAuthGroup,
155 // Our backdoor to not let the driver load
160 try_return( ntStatus);
164 // Perform some initialization
167 AFSDriverObject = DriverObject;
169 ntStatus = AFSReadRegistry( RegistryPath);
171 if( !NT_SUCCESS( ntStatus))
174 DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus);
176 ntStatus = STATUS_SUCCESS;
181 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
184 DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");
193 try_return( ntStatus = STATUS_UNSUCCESSFUL);
198 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
199 !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
202 AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");
204 try_return( ntStatus = STATUS_UNSUCCESSFUL);
208 // Initialize the debug log and dump file interface
211 AFSInitializeDbgLog();
213 AFSInitializeDumpFile();
216 // Setup the registry string
219 AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength;
220 AFSRegistryPath.Length = RegistryPath->Length;
222 AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool,
223 AFSRegistryPath.Length,
224 AFS_GENERIC_MEMORY_18_TAG);
226 if( AFSRegistryPath.Buffer == NULL)
229 DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n");
231 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
234 RtlCopyMemory( AFSRegistryPath.Buffer,
235 RegistryPath->Buffer,
236 RegistryPath->Length);
238 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN))
242 // Update the shutdown flag
247 RtlInitUnicodeString( &uniValueName,
248 AFS_REG_SHUTDOWN_STATUS);
250 AFSUpdateRegistryParameter( &uniValueName,
256 RtlInitUnicodeString( &uniDeviceName,
257 AFS_CONTROL_DEVICE_NAME);
259 ntStatus = IoCreateDeviceSecure( DriverObject,
260 sizeof( AFSDeviceExt),
262 FILE_DEVICE_NETWORK_FILE_SYSTEM,
263 FILE_DEVICE_SECURE_OPEN | FILE_REMOTE_DEVICE,
265 &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,
266 (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT,
269 if( !NT_SUCCESS( ntStatus))
272 DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus);
274 try_return( ntStatus);
278 // Setup the device extension
281 pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
283 InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList);
284 FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync);
287 // Now initialize the control device
290 ntStatus = AFSInitializeControlDevice();
292 if( !NT_SUCCESS( ntStatus))
295 try_return( ntStatus);
299 // Allocate our symbolic link for service communication
302 RtlInitUnicodeString( &uniSymLinkName,
305 ntStatus = IoCreateSymbolicLink( &uniSymLinkName,
308 if( !NT_SUCCESS( ntStatus))
311 DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus);
314 // OK, no one can communicate with us so fail
317 try_return( ntStatus);
321 // Fill in the dispatch table
324 for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++)
327 DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch;
330 DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate;
331 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose;
332 DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead;
333 DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite;
334 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo;
335 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo;
336 DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA;
337 DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA;
338 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers;
339 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo;
340 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo;
341 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl;
342 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl;
343 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl;
344 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl;
345 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown;
346 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl;
347 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup;
348 DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity;
349 DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity;
350 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl;
351 //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota;
352 //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota;
355 // Since we are not a true FSD then we are not controlling a device and hence these will not be needed
360 DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower;
361 DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP;
366 // Fast IO Dispatch table
369 DriverObject->FastIoDispatch = &AFSFastIoDispatch;
371 RtlZeroMemory( &AFSFastIoDispatch,
372 sizeof( AFSFastIoDispatch));
375 // Again, since we are not a registered FSD many of these are not going to be called. They are here
379 AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
380 AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo
381 AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read
382 AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write
383 AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo
384 AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo
385 AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock
386 AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle
387 AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll
388 AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey
389 AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo;
390 AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush;
391 AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush;
392 AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl;
393 AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile;
394 AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile;
395 AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice;
396 //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite;
397 //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite;
398 AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead;
399 AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete;
400 AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite;
401 AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete;
402 AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed;
403 AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed;
404 AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed;
405 AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed;
406 AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen;
409 // Cache manager callback routines.
412 AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite;
413 AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
414 AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead;
415 AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;
421 AFSSysProcess = PsGetCurrentProcessId();
424 // Initialize the worker Queues and their syncrhonization structures
427 KeInitializeEvent( &pDeviceExt->Specific.Control.WorkerQueueHasItems,
428 SynchronizationEvent,
431 ExInitializeResourceLite( &pDeviceExt->Specific.Control.QueueLock);
433 KeInitializeEvent( &pDeviceExt->Specific.Control.IOWorkerQueueHasItems,
434 SynchronizationEvent,
437 ExInitializeResourceLite( &pDeviceExt->Specific.Control.IOQueueLock);
441 // Register for shutdown notification
444 IoRegisterShutdownNotification( AFSDeviceObject);
447 // Initialize the system process cb
450 AFSInitializeProcessCB( 0,
451 (ULONGLONG)AFSSysProcess);
454 // Initialize the redirector device
457 ntStatus = AFSInitRDRDevice();
459 if( !NT_SUCCESS( ntStatus))
462 DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");
464 try_return( ntStatus);
468 // Initialize some server name based strings
471 AFSInitServerStrings();
474 // Register the call back for process creation and tear down.
475 // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx
476 // will be used. This function returns STATUS_ACCESS_DENIED
477 // if there is a signing error. In that case, the AFSProcessNotifyEx
478 // routine has not been registered and we can fallback to the
479 // Windows 2000 interface and AFSProcessNotify.
482 RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx,
483 L"PsSetCreateProcessNotifyRoutineEx");
485 pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx);
487 ntStatus = STATUS_ACCESS_DENIED;
489 if ( pPsSetCreateProcessNotifyRoutineEx)
492 ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx,
496 if ( ntStatus == STATUS_ACCESS_DENIED)
499 ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
503 ntStatus = STATUS_SUCCESS;
507 if( !NT_SUCCESS( ntStatus))
510 DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);
512 if( AFSRegistryPath.Buffer != NULL)
515 ExFreePool( AFSRegistryPath.Buffer);
518 if( uniSymLinkName.Buffer != NULL)
521 IoDeleteSymbolicLink( &uniSymLinkName);
524 if( AFSDeviceObject != NULL)
527 AFSRemoveControlDevice();
529 FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);
531 IoUnregisterShutdownNotification( AFSDeviceObject);
533 IoDeleteDevice( AFSDeviceObject);
538 ExDeleteResourceLite( &AFSDbgLogLock);
541 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
546 "EXCEPTION - AFSRedirFs DriverEntry\n"));
548 AFSDumpTraceFilesFnc();