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;
72 ULONG ulTimeIncrement = 0;
73 UNICODE_STRING uniSymLinkName;
74 UNICODE_STRING uniDeviceName;
77 UNICODE_STRING uniValueName;
78 BOOLEAN bExit = FALSE;
79 UNICODE_STRING uniRoutine;
80 RTL_OSVERSIONINFOW sysVersion;
81 UNICODE_STRING uniPsSetCreateProcessNotifyRoutineEx;
82 PsSetCreateProcessNotifyRoutineEx_t pPsSetCreateProcessNotifyRoutineEx = NULL;
87 DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__);
90 // Initialize some local variables for easier processing
93 uniSymLinkName.Buffer = NULL;
95 AFSDumpFileLocation.Length = 0;
96 AFSDumpFileLocation.MaximumLength = 0;
97 AFSDumpFileLocation.Buffer = NULL;
99 AFSDumpFileName.Length = 0;
100 AFSDumpFileName.Buffer = NULL;
101 AFSDumpFileName.MaximumLength = 0;
103 ExInitializeResourceLite( &AFSDbgLogLock);
106 // Initialize the server name
111 AFSReadMountRootName();
113 RtlZeroMemory( &sysVersion,
114 sizeof( RTL_OSVERSIONINFOW));
116 sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);
118 RtlGetVersion( &sysVersion);
120 RtlInitUnicodeString( &uniRoutine,
121 L"ZwSetInformationToken");
123 AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine);
125 if( AFSSetInformationToken == NULL)
128 AFSSrvcTableEntry *pServiceTable = NULL;
130 pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable;
133 // Only perform this lookup for Windows XP.
136 if( pServiceTable != NULL &&
137 sysVersion.dwMajorVersion == 5 &&
138 sysVersion.dwMinorVersion == 1)
140 AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6];
146 // And the global root share name
149 RtlInitUnicodeString( &AFSGlobalRootName,
150 AFS_GLOBAL_ROOT_SHARE_NAME);
152 RtlZeroMemory( &AFSNoPAGAuthGroup,
156 // Our backdoor to not let the driver load
161 try_return( ntStatus);
165 // Perform some initialization
168 AFSDriverObject = DriverObject;
170 ntStatus = AFSReadRegistry( RegistryPath);
172 if( !NT_SUCCESS( ntStatus))
175 DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus);
177 ntStatus = STATUS_SUCCESS;
181 // Initialize the debug log and dump file interface
184 AFSInitializeDbgLog();
186 AFSInitializeDumpFile();
190 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
193 DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");
202 try_return( ntStatus = STATUS_UNSUCCESSFUL);
207 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
208 !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
211 AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");
213 try_return( ntStatus = STATUS_UNSUCCESSFUL);
217 // Setup the registry string
220 AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength;
221 AFSRegistryPath.Length = RegistryPath->Length;
223 AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool,
224 AFSRegistryPath.Length,
225 AFS_GENERIC_MEMORY_18_TAG);
227 if( AFSRegistryPath.Buffer == NULL)
230 DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n");
232 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
235 RtlCopyMemory( AFSRegistryPath.Buffer,
236 RegistryPath->Buffer,
237 RegistryPath->Length);
239 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN))
243 // Update the shutdown flag
248 RtlInitUnicodeString( &uniValueName,
249 AFS_REG_SHUTDOWN_STATUS);
251 AFSUpdateRegistryParameter( &uniValueName,
257 RtlInitUnicodeString( &uniDeviceName,
258 AFS_CONTROL_DEVICE_NAME);
260 ntStatus = IoCreateDeviceSecure( DriverObject,
261 sizeof( AFSDeviceExt),
263 FILE_DEVICE_NETWORK_FILE_SYSTEM,
266 &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,
267 (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT,
270 if( !NT_SUCCESS( ntStatus))
273 DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus);
275 try_return( ntStatus);
279 // Setup the device extension
282 pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
284 InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList);
285 FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync);
288 // Now initialize the control device
291 ntStatus = AFSInitializeControlDevice();
293 if( !NT_SUCCESS( ntStatus))
296 try_return( ntStatus);
300 // Allocate our symbolic link for service communication
303 RtlInitUnicodeString( &uniSymLinkName,
306 ntStatus = IoCreateSymbolicLink( &uniSymLinkName,
309 if( !NT_SUCCESS( ntStatus))
312 DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus);
315 // OK, no one can communicate with us so fail
318 try_return( ntStatus);
322 // Fill in the dispatch table
325 for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++)
328 DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch;
331 DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate;
332 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose;
333 DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead;
334 DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite;
335 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo;
336 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo;
337 DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA;
338 DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA;
339 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers;
340 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo;
341 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo;
342 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl;
343 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl;
344 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl;
345 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl;
346 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown;
347 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl;
348 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup;
349 DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity;
350 DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity;
351 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl;
352 //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota;
353 //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota;
356 // Since we are not a true FSD then we are not controlling a device and hence these will not be needed
361 DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower;
362 DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP;
367 // Fast IO Dispatch table
370 DriverObject->FastIoDispatch = &AFSFastIoDispatch;
372 RtlZeroMemory( &AFSFastIoDispatch,
373 sizeof( AFSFastIoDispatch));
376 // Again, since we are not a registered FSD many of these are not going to be called. They are here
380 AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
381 AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo
382 AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read
383 AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write
384 AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo
385 AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo
386 AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock
387 AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle
388 AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll
389 AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey
390 AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo;
391 AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush;
392 AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush;
393 AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl;
394 AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile;
395 AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile;
396 AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice;
397 //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite;
398 //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite;
399 AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead;
400 AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete;
401 AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite;
402 AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete;
403 AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed;
404 AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed;
405 AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed;
406 AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed;
407 AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen;
410 // Cache manager callback routines.
413 AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite;
414 AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
415 AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead;
416 AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;
422 AFSSysProcess = PsGetCurrentProcessId();
425 // Register for shutdown notification
428 IoRegisterShutdownNotification( AFSDeviceObject);
431 // Initialize the system process cb
434 AFSInitializeProcessCB( 0,
435 (ULONGLONG)AFSSysProcess);
438 // Initialize the redirector device
441 ntStatus = AFSInitRDRDevice();
443 if( !NT_SUCCESS( ntStatus))
446 DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");
448 try_return( ntStatus);
452 // Initialize some server name based strings
455 AFSInitServerStrings();
458 // Register the call back for process creation and tear down.
459 // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx
460 // will be used. This function returns STATUS_ACCESS_DENIED
461 // if there is a signing error. In that case, the AFSProcessNotifyEx
462 // routine has not been registered and we can fallback to the
463 // Windows 2000 interface and AFSProcessNotify.
466 RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx,
467 L"PsSetCreateProcessNotifyRoutineEx");
469 pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx);
471 ntStatus = STATUS_ACCESS_DENIED;
473 if ( pPsSetCreateProcessNotifyRoutineEx)
476 ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx,
480 if ( ntStatus == STATUS_ACCESS_DENIED)
483 ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
487 ntStatus = STATUS_SUCCESS;
491 if( !NT_SUCCESS( ntStatus))
494 DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);
496 if( AFSRegistryPath.Buffer != NULL)
499 ExFreePool( AFSRegistryPath.Buffer);
502 if( uniSymLinkName.Buffer != NULL)
505 IoDeleteSymbolicLink( &uniSymLinkName);
508 if( AFSDeviceObject != NULL)
511 AFSRemoveControlDevice();
513 FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);
515 IoUnregisterShutdownNotification( AFSDeviceObject);
517 IoDeleteDevice( AFSDeviceObject);
522 ExDeleteResourceLite( &AFSDbgLogLock);
525 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
530 "EXCEPTION - AFSRedirFs DriverEntry\n");
532 AFSDumpTraceFilesFnc();