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 RtlZeroMemory( &sysVersion,
112 sizeof( RTL_OSVERSIONINFOW));
114 sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);
116 RtlGetVersion( &sysVersion);
118 RtlInitUnicodeString( &uniRoutine,
119 L"ZwSetInformationToken");
121 AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine);
123 if( AFSSetInformationToken == NULL)
126 AFSSrvcTableEntry *pServiceTable = NULL;
128 pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable;
131 // Only perform this lookup for Windows XP.
134 if( pServiceTable != NULL &&
135 sysVersion.dwMajorVersion == 5 &&
136 sysVersion.dwMinorVersion == 1)
138 AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6];
144 // And the global root share name
147 RtlInitUnicodeString( &AFSGlobalRootName,
148 AFS_GLOBAL_ROOT_SHARE_NAME);
150 RtlZeroMemory( &AFSNoPAGAuthGroup,
154 // Our backdoor to not let the driver load
159 try_return( ntStatus);
163 // Perform some initialization
166 AFSDriverObject = DriverObject;
168 ntStatus = AFSReadRegistry( RegistryPath);
170 if( !NT_SUCCESS( ntStatus))
173 DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus);
175 ntStatus = STATUS_SUCCESS;
179 // Initialize the debug log and dump file interface
182 AFSInitializeDbgLog();
184 AFSInitializeDumpFile();
188 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
191 DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");
200 try_return( ntStatus = STATUS_UNSUCCESSFUL);
205 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
206 !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
209 AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");
211 try_return( ntStatus = STATUS_UNSUCCESSFUL);
215 // Setup the registry string
218 AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength;
219 AFSRegistryPath.Length = RegistryPath->Length;
221 AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool,
222 AFSRegistryPath.Length,
223 AFS_GENERIC_MEMORY_18_TAG);
225 if( AFSRegistryPath.Buffer == NULL)
228 DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n");
230 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
233 RtlCopyMemory( AFSRegistryPath.Buffer,
234 RegistryPath->Buffer,
235 RegistryPath->Length);
237 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN))
241 // Update the shutdown flag
246 RtlInitUnicodeString( &uniValueName,
247 AFS_REG_SHUTDOWN_STATUS);
249 AFSUpdateRegistryParameter( &uniValueName,
255 RtlInitUnicodeString( &uniDeviceName,
256 AFS_CONTROL_DEVICE_NAME);
258 ntStatus = IoCreateDeviceSecure( DriverObject,
259 sizeof( AFSDeviceExt),
261 FILE_DEVICE_NETWORK_FILE_SYSTEM,
264 &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,
265 (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT,
268 if( !NT_SUCCESS( ntStatus))
271 DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus);
273 try_return( ntStatus);
277 // Setup the device extension
280 pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
282 InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList);
283 FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync);
286 // Now initialize the control device
289 ntStatus = AFSInitializeControlDevice();
291 if( !NT_SUCCESS( ntStatus))
294 try_return( ntStatus);
298 // Allocate our symbolic link for service communication
301 RtlInitUnicodeString( &uniSymLinkName,
304 ntStatus = IoCreateSymbolicLink( &uniSymLinkName,
307 if( !NT_SUCCESS( ntStatus))
310 DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus);
313 // OK, no one can communicate with us so fail
316 try_return( ntStatus);
320 // Fill in the dispatch table
323 for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++)
326 DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch;
329 DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate;
330 DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose;
331 DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead;
332 DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite;
333 DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo;
334 DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo;
335 DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA;
336 DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA;
337 DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers;
338 DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo;
339 DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo;
340 DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl;
341 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl;
342 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl;
343 DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl;
344 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown;
345 DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl;
346 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup;
347 DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity;
348 DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity;
349 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl;
350 //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota;
351 //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota;
354 // Since we are not a true FSD then we are not controlling a device and hence these will not be needed
359 DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower;
360 DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP;
365 // Fast IO Dispatch table
368 DriverObject->FastIoDispatch = &AFSFastIoDispatch;
370 RtlZeroMemory( &AFSFastIoDispatch,
371 sizeof( AFSFastIoDispatch));
374 // Again, since we are not a registered FSD many of these are not going to be called. They are here
378 AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
379 AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo
380 AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read
381 AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write
382 AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo
383 AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo
384 AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock
385 AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle
386 AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll
387 AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey
388 AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo;
389 AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush;
390 AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush;
391 AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl;
392 AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile;
393 AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile;
394 AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice;
395 //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite;
396 //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite;
397 AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead;
398 AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete;
399 AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite;
400 AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete;
401 AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed;
402 AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed;
403 AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed;
404 AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed;
405 AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen;
408 // Cache manager callback routines.
411 AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite;
412 AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
413 AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead;
414 AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;
420 AFSSysProcess = PsGetCurrentProcessId();
423 // Register for shutdown notification
426 IoRegisterShutdownNotification( AFSDeviceObject);
429 // Initialize the system process cb
432 AFSInitializeProcessCB( 0,
433 (ULONGLONG)AFSSysProcess);
436 // Initialize the redirector device
439 ntStatus = AFSInitRDRDevice();
441 if( !NT_SUCCESS( ntStatus))
444 DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");
446 try_return( ntStatus);
450 // Initialize some server name based strings
453 AFSInitServerStrings();
456 // Register the call back for process creation and tear down
459 RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx,
460 L"PsSetCreateProcessNotifyRoutineEx");
462 pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx);
464 if ( pPsSetCreateProcessNotifyRoutineEx)
467 pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx,
473 PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
479 if( !NT_SUCCESS( ntStatus))
482 DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);
484 if( AFSRegistryPath.Buffer != NULL)
487 ExFreePool( AFSRegistryPath.Buffer);
490 if( uniSymLinkName.Buffer != NULL)
493 IoDeleteSymbolicLink( &uniSymLinkName);
496 if( AFSDeviceObject != NULL)
499 AFSRemoveControlDevice();
501 FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);
503 IoUnregisterShutdownNotification( AFSDeviceObject);
505 IoDeleteDevice( AFSDeviceObject);
510 ExDeleteResourceLite( &AFSDbgLogLock);
513 __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
518 "EXCEPTION - AFSRedirFs DriverEntry\n");