/* * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. * Copyright (c) 2009, 2010, 2011 Your File System, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, * this list of conditions and the following disclaimer in the * documentation * and/or other materials provided with the distribution. * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. * nor the names of their contributors may be used to endorse or promote * products derived from this software without specific prior written * permission from Kernel Drivers, LLC and Your File System, Inc. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // // File: AFSInit.cpp // #include "AFSCommon.h" #ifndef AMD64 extern "C" { extern void *KeServiceDescriptorTable; }; #endif // // DriverEntry // // This is the initial entry point for the driver. // // Inputs: // DriverObject Pointer to Driver Object created by I/O manager // RegistryPath Pointer to registry path representing this Driver // // Returns: // Success To indicate Driver's inituaialization processing // was successful // NT ERROR STATUS Otherwise -- Driver does not remain loaded // NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS ntStatus = STATUS_SUCCESS; AFSDeviceExt *pDeviceExt; ULONG ulTimeIncrement = 0; UNICODE_STRING uniSymLinkName; UNICODE_STRING uniDeviceName; ULONG ulIndex = 0; ULONG ulValue = 0; UNICODE_STRING uniValueName; BOOLEAN bExit = FALSE; UNICODE_STRING uniRoutine; RTL_OSVERSIONINFOW sysVersion; __try { DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__); // // Initialize some local variables for easier processing // uniSymLinkName.Buffer = NULL; AFSDumpFileLocation.Length = 0; AFSDumpFileLocation.MaximumLength = 0; AFSDumpFileLocation.Buffer = NULL; AFSDumpFileName.Length = 0; AFSDumpFileName.Buffer = NULL; AFSDumpFileName.MaximumLength = 0; ExInitializeResourceLite( &AFSDbgLogLock); // // Initialize the server name // AFSReadServerName(); RtlZeroMemory( &sysVersion, sizeof( RTL_OSVERSIONINFOW)); sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW); RtlGetVersion( &sysVersion); RtlInitUnicodeString( &uniRoutine, L"ZwSetInformationToken"); AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine); if( AFSSetInformationToken == NULL) { #ifndef AMD64 AFSSrvcTableEntry *pServiceTable = NULL; pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable; // // Only perform this lookup for Windows XP. // if( pServiceTable != NULL && sysVersion.dwMajorVersion == 5 && sysVersion.dwMinorVersion == 1) { AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6]; } #endif } // // And the global root share name // RtlInitUnicodeString( &AFSGlobalRootName, AFS_GLOBAL_ROOT_SHARE_NAME); RtlZeroMemory( &AFSNoPAGAuthGroup, sizeof( GUID)); // // Our backdoor to not let the driver load // if( bExit) { try_return( ntStatus); } // // Perform some initialization // AFSDriverObject = DriverObject; ntStatus = AFSReadRegistry( RegistryPath); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus); ntStatus = STATUS_SUCCESS; } // // Initialize the debug log and dump file interface // AFSInitializeDbgLog(); AFSInitializeDumpFile(); #if DBG if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY)) { DbgPrint("AFSRedirFs DriverEntry - Break on entry\n"); AFSBreakPoint(); if ( bExit) { // // Just as above // try_return( ntStatus = STATUS_UNSUCCESSFUL); } } #endif if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) && !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN)) { AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n"); try_return( ntStatus = STATUS_UNSUCCESSFUL); } // // Setup the registry string // AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength; AFSRegistryPath.Length = RegistryPath->Length; AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool, AFSRegistryPath.Length, AFS_GENERIC_MEMORY_18_TAG); if( AFSRegistryPath.Buffer == NULL) { DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n"); try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); } RtlCopyMemory( AFSRegistryPath.Buffer, RegistryPath->Buffer, RegistryPath->Length); if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN)) { // // Update the shutdown flag // ulValue = (ULONG)-1; RtlInitUnicodeString( &uniValueName, AFS_REG_SHUTDOWN_STATUS); AFSUpdateRegistryParameter( &uniValueName, REG_DWORD, &ulValue, sizeof( ULONG)); } RtlInitUnicodeString( &uniDeviceName, AFS_CONTROL_DEVICE_NAME); ntStatus = IoCreateDeviceSecure( DriverObject, sizeof( AFSDeviceExt), &uniDeviceName, FILE_DEVICE_NETWORK_FILE_SYSTEM, 0, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX, (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT, &AFSDeviceObject); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus); try_return( ntStatus); } // // Setup the device extension // pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList); FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync); // // Now initialize the control device // ntStatus = AFSInitializeControlDevice(); if( !NT_SUCCESS( ntStatus)) { try_return( ntStatus); } // // Allocate our symbolic link for service communication // RtlInitUnicodeString( &uniSymLinkName, AFS_SYMLINK_NAME); ntStatus = IoCreateSymbolicLink( &uniSymLinkName, &uniDeviceName); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus); // // OK, no one can communicate with us so fail // try_return( ntStatus); } // // Fill in the dispatch table // for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++) { DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch; } DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose; DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead; DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo; DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA; DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo; DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown; DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup; DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity; DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl; //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota; //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota; // // Since we are not a true FSD then we are not controlling a device and hence these will not be needed // #ifdef FSD_NOT_USED DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower; DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP; #endif // // Fast IO Dispatch table // DriverObject->FastIoDispatch = &AFSFastIoDispatch; RtlZeroMemory( &AFSFastIoDispatch, sizeof( AFSFastIoDispatch)); // // Again, since we are not a registered FSD many of these are not going to be called. They are here // for completeness. // AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo; AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush; AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush; AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl; AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile; AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile; AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice; //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite; //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite; AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead; AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete; AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite; AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete; AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed; AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed; AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed; AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed; AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen; // // Cache manager callback routines. // AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite; AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite; AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead; AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead; // // System process. // AFSSysProcess = PsGetCurrentProcessId(); // // Register for shutdown notification // IoRegisterShutdownNotification( AFSDeviceObject); // // Initialize the system process cb // AFSInitializeProcessCB( 0, (ULONGLONG)AFSSysProcess); // // Initialize the redirector device // ntStatus = AFSInitRDRDevice(); if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n"); try_return( ntStatus); } // // Initialize some server name based strings // AFSInitServerStrings(); // // Register the call back for process creation and tear down // PsSetCreateProcessNotifyRoutine( AFSProcessNotify, FALSE); try_exit: if( !NT_SUCCESS( ntStatus)) { DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus); if( AFSRegistryPath.Buffer != NULL) { ExFreePool( AFSRegistryPath.Buffer); } if( uniSymLinkName.Buffer != NULL) { IoDeleteSymbolicLink( &uniSymLinkName); } if( AFSDeviceObject != NULL) { AFSRemoveControlDevice(); FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync); IoUnregisterShutdownNotification( AFSDeviceObject); IoDeleteDevice( AFSDeviceObject); } AFSTearDownDbgLog(); ExDeleteResourceLite( &AFSDbgLogLock); } } __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSRedirFs DriverEntry\n"); } return ntStatus; }