VOID FFSFreeVcb( IN PFFS_VCB Vcb) { ASSERT(Vcb != NULL); ASSERT((Vcb->Identifier.Type == FFSVCB) && (Vcb->Identifier.Size == sizeof(FFS_VCB))); FsRtlNotifyUninitializeSync(&Vcb->NotifySync); if (Vcb->StreamObj) { if (IsFlagOn(Vcb->StreamObj->Flags, FO_FILE_MODIFIED)) { IO_STATUS_BLOCK IoStatus; CcFlushCache(&(Vcb->SectionObject), NULL, 0, &IoStatus); ClearFlag(Vcb->StreamObj->Flags, FO_FILE_MODIFIED); } if (Vcb->StreamObj->PrivateCacheMap) FFSSyncUninitializeCacheMap(Vcb->StreamObj); ObDereferenceObject(Vcb->StreamObj); Vcb->StreamObj = NULL; } #if DBG if (FsRtlNumberOfRunsInLargeMcb(&(Vcb->DirtyMcbs)) != 0) { LONGLONG DirtyVba; LONGLONG DirtyLba; LONGLONG DirtyLength; int i; for (i = 0; FsRtlGetNextLargeMcbEntry (&(Vcb->DirtyMcbs), i, &DirtyVba, &DirtyLba, &DirtyLength); i++) { FFSPrint((DBG_INFO, "DirtyVba = %I64xh\n", DirtyVba)); FFSPrint((DBG_INFO, "DirtyLba = %I64xh\n", DirtyLba)); FFSPrint((DBG_INFO, "DirtyLen = %I64xh\n\n", DirtyLength)); } FFSBreakPoint(); } #endif FsRtlUninitializeLargeMcb(&(Vcb->DirtyMcbs)); FFSFreeMcbTree(Vcb->McbTree); if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } ExDeleteResourceLite(&Vcb->McbResource); ExDeleteResourceLite(&Vcb->PagingIoResource); ExDeleteResourceLite(&Vcb->MainResource); IoDeleteDevice(Vcb->DeviceObject); }
VOID Readonly_Close ( IN PREADONLY Readonly ) { NTSTATUS status; LARGE_INTEGER timeOut; PLIST_ENTRY readonlyRequestEntry; PREADONLY_REQUEST readonlyRequest; SPY_LOG_PRINT( LFS_DEBUG_READONLY_INFO, ("Readonly close Readonly = %p\n", Readonly) ); ExAcquireFastMutex( &Readonly->FastMutex ); ASSERT( !FlagOn(Readonly->Flags, READONLY_FLAG_RECONNECTING) ); if (FlagOn(Readonly->Flags, READONLY_FLAG_CLOSED)) { //ASSERT( FALSE ); ExReleaseFastMutex( &Readonly->FastMutex ); return; } SetFlag( Readonly->Flags, READONLY_FLAG_CLOSED ); ExReleaseFastMutex( &Readonly->FastMutex ); FsRtlNotifyUninitializeSync( &Readonly->NotifySync ); if (Readonly->ThreadHandle == NULL) { //ASSERT( FALSE ); Readonly_Dereference( Readonly ); return; } ASSERT( Readonly->ThreadObject != NULL ); SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly close READONLY_REQ_DISCONNECT Readonly = %p\n", Readonly) ); readonlyRequest = AllocReadonlyRequest( Readonly, 0, FALSE ); readonlyRequest->RequestType = READONLY_REQ_DISCONNECT; QueueingReadonlyRequest( Readonly, readonlyRequest ); readonlyRequest = AllocReadonlyRequest( Readonly, 0, FALSE ); readonlyRequest->RequestType = READONLY_REQ_DOWN; QueueingReadonlyRequest( Readonly, readonlyRequest ); SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly close READONLY_REQ_DISCONNECT end Readonly = %p\n", Readonly) ); timeOut.QuadPart = -LFS_TIME_OUT; status = KeWaitForSingleObject( Readonly->ThreadObject, Executive, KernelMode, FALSE, &timeOut ); if (status == STATUS_SUCCESS) { SPY_LOG_PRINT( LFS_DEBUG_READONLY_TRACE, ("Readonly_Close: thread stoped Readonly = %p\n", Readonly) ); ObDereferenceObject( Readonly->ThreadObject ); Readonly->ThreadHandle = NULL; Readonly->ThreadObject = NULL; } else { ASSERT( LFS_BUG ); return; } if (!IsListEmpty(&Readonly->FcbQueue)) NDAS_ASSERT( FALSE ); if (!IsListEmpty(&Readonly->CcbQueue)) NDAS_ASSERT( FALSE ); if (!IsListEmpty(&Readonly->RequestQueue)) NDAS_ASSERT( FALSE ); while (readonlyRequestEntry = ExInterlockedRemoveHeadList(&Readonly->RequestQueue, &Readonly->RequestQSpinLock)) { PREADONLY_REQUEST readonlyRequest2; InitializeListHead( readonlyRequestEntry ); readonlyRequest2 = CONTAINING_RECORD( readonlyRequestEntry, READONLY_REQUEST, ListEntry ); readonlyRequest2->ExecuteStatus = STATUS_IO_DEVICE_ERROR; if (readonlyRequest2->Synchronous == TRUE) KeSetEvent( &readonlyRequest2->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferenceReadonlyRequest( readonlyRequest2 ); } Readonly_Dereference( Readonly ); return; }
NTSTATUS FFSInitializeVcb( IN PFFS_IRP_CONTEXT IrpContext, IN PFFS_VCB Vcb, IN PFFS_SUPER_BLOCK FFSSb, IN PDEVICE_OBJECT TargetDevice, IN PDEVICE_OBJECT VolumeDevice, IN PVPB Vpb) { BOOLEAN VcbResourceInitialized = FALSE; USHORT VolumeLabelLength; ULONG IoctlSize; BOOLEAN NotifySyncInitialized = FALSE; LONGLONG DiskSize; LONGLONG PartSize; NTSTATUS Status = STATUS_UNSUCCESSFUL; UNICODE_STRING RootNode; USHORT Buffer[2]; ULONG ChangeCount; __try { if (!Vpb) { Status = STATUS_DEVICE_NOT_READY; __leave; } Buffer[0] = L'\\'; Buffer[1] = 0; RootNode.Buffer = Buffer; RootNode.MaximumLength = RootNode.Length = 2; Vcb->McbTree = FFSAllocateMcb(Vcb, &RootNode, FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_NORMAL); if (!Vcb->McbTree) { __leave; } #if FFS_READ_ONLY SetFlag(Vcb->Flags, VCB_READ_ONLY); #endif //READ_ONLY if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA)) { SetFlag(Vcb->Flags, VCB_REMOVABLE_MEDIA); } if (IsFlagOn(Vpb->RealDevice->Characteristics, FILE_FLOPPY_DISKETTE)) { SetFlag(Vcb->Flags, VCB_FLOPPY_DISK); } #if 0 if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { if (IsFlagOn(FFSGlobal->Flags, FFS_SUPPORT_WRITING)) { ClearFlag(Vcb->Flags, VCB_READ_ONLY); } else { SetFlag(Vcb->Flags, VCB_READ_ONLY); } } else #endif { SetFlag(Vcb->Flags, VCB_READ_ONLY); } ExInitializeResourceLite(&Vcb->MainResource); ExInitializeResourceLite(&Vcb->PagingIoResource); ExInitializeResourceLite(&Vcb->McbResource); VcbResourceInitialized = TRUE; Vcb->McbTree->Inode = FFS_ROOT_INO; Vcb->Vpb = Vpb; Vcb->RealDevice = Vpb->RealDevice; Vpb->DeviceObject = VolumeDevice; { UNICODE_STRING LabelName; OEM_STRING OemName; LabelName.MaximumLength = 16 * 2; LabelName.Length = 0; LabelName.Buffer = Vcb->Vpb->VolumeLabel; RtlZeroMemory(LabelName.Buffer, LabelName.MaximumLength); VolumeLabelLength = 16; while((VolumeLabelLength > 0) && ((FFSSb->fs_volname[VolumeLabelLength-1] == 0x00) || (FFSSb->fs_volname[VolumeLabelLength-1] == 0x20))) { VolumeLabelLength--; } OemName.Buffer = FFSSb->fs_volname; OemName.MaximumLength = 16; OemName.Length = VolumeLabelLength; Status = FFSOEMToUnicode(&LabelName, &OemName); if (!NT_SUCCESS(Status)) { __leave; } Vpb->VolumeLabelLength = LabelName.Length; } Vpb->SerialNumber = ((ULONG*)FFSSb->fs_id)[0] + ((ULONG*)FFSSb->fs_id)[1] + ((ULONG*)FFSSb->fs_id)[2]; Vcb->StreamObj = IoCreateStreamFileObject(NULL, Vcb->Vpb->RealDevice); if (Vcb->StreamObj) { Vcb->StreamObj->SectionObjectPointer = &(Vcb->SectionObject); Vcb->StreamObj->Vpb = Vcb->Vpb; Vcb->StreamObj->ReadAccess = TRUE; if (IsFlagOn(Vcb->Flags, VCB_READ_ONLY)) { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } else { Vcb->StreamObj->WriteAccess = TRUE; Vcb->StreamObj->DeleteAccess = TRUE; } Vcb->StreamObj->FsContext = (PVOID) Vcb; Vcb->StreamObj->FsContext2 = NULL; Vcb->StreamObj->Vpb = Vcb->Vpb; SetFlag(Vcb->StreamObj->Flags, FO_NO_INTERMEDIATE_BUFFERING); } else { __leave; } InitializeListHead(&Vcb->FcbList); InitializeListHead(&Vcb->NotifyList); FsRtlNotifyInitializeSync(&Vcb->NotifySync); NotifySyncInitialized = TRUE; Vcb->DeviceObject = VolumeDevice; Vcb->TargetDeviceObject = TargetDevice; Vcb->OpenFileHandleCount = 0; Vcb->ReferenceCount = 0; Vcb->ffs_super_block = FFSSb; Vcb->Header.NodeTypeCode = (USHORT) FFSVCB; Vcb->Header.NodeByteSize = sizeof(FFS_VCB); Vcb->Header.IsFastIoPossible = FastIoIsNotPossible; Vcb->Header.Resource = &(Vcb->MainResource); Vcb->Header.PagingIoResource = &(Vcb->PagingIoResource); Vcb->Vpb->SerialNumber = 'PS'; DiskSize = Vcb->DiskGeometry.Cylinders.QuadPart * Vcb->DiskGeometry.TracksPerCylinder * Vcb->DiskGeometry.SectorsPerTrack * Vcb->DiskGeometry.BytesPerSector; IoctlSize = sizeof(PARTITION_INFORMATION); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &Vcb->PartitionInformation, &IoctlSize); PartSize = Vcb->PartitionInformation.PartitionLength.QuadPart; if (!NT_SUCCESS(Status)) { Vcb->PartitionInformation.StartingOffset.QuadPart = 0; Vcb->PartitionInformation.PartitionLength.QuadPart = DiskSize; PartSize = DiskSize; Status = STATUS_SUCCESS; } IoctlSize = sizeof(ULONG); Status = FFSDiskIoControl( TargetDevice, IOCTL_DISK_CHECK_VERIFY, NULL, 0, &ChangeCount, &IoctlSize); if (!NT_SUCCESS(Status)) { __leave; } Vcb->ChangeCount = ChangeCount; Vcb->Header.AllocationSize.QuadPart = Vcb->Header.FileSize.QuadPart = PartSize; Vcb->Header.ValidDataLength.QuadPart = (LONGLONG)(0x7fffffffffffffff); /* Vcb->Header.AllocationSize.QuadPart = (LONGLONG)(ffs_super_block->s_blocks_count - ffs_super_block->s_free_blocks_count) * (FFS_MIN_BLOCK << ffs_super_block->s_log_block_size); Vcb->Header.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; Vcb->Header.ValidDataLength.QuadPart = Vcb->Header.AllocationSize.QuadPart; */ { CC_FILE_SIZES FileSizes; FileSizes.AllocationSize.QuadPart = FileSizes.FileSize.QuadPart = Vcb->Header.AllocationSize.QuadPart; FileSizes.ValidDataLength.QuadPart= (LONGLONG)(0x7fffffffffffffff); CcInitializeCacheMap(Vcb->StreamObj, &FileSizes, TRUE, &(FFSGlobal->CacheManagerNoOpCallbacks), Vcb); } #if 0 // LoadGroup XXX if (!FFSLoadGroup(Vcb)) { Status = STATUS_UNSUCCESSFUL; __leave; } #endif FsRtlInitializeLargeMcb(&(Vcb->DirtyMcbs), PagedPool); InitializeListHead(&(Vcb->McbList)); if (IsFlagOn(FFSGlobal->Flags, FFS_CHECKING_BITMAP)) { FFSCheckBitmapConsistency(IrpContext, Vcb); } { ULONG dwData[FFS_BLOCK_TYPES] = {NDADDR, 1, 1, 1}; ULONG dwMeta[FFS_BLOCK_TYPES] = {0, 0, 0, 0}; ULONG i; if (FS_VERSION == 1) { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 2) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 2)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } else { for (i = 0; i < FFS_BLOCK_TYPES; i++) { dwData[i] = dwData[i] << ((BLOCK_BITS - 3) * i); if (i > 0) { dwMeta[i] = 1 + (dwMeta[i - 1] << (BLOCK_BITS - 3)); } Vcb->dwData[i] = dwData[i]; Vcb->dwMeta[i] = dwMeta[i]; } } } SetFlag(Vcb->Flags, VCB_INITIALIZED); } __finally { if (!NT_SUCCESS(Status)) { if (NotifySyncInitialized) { FsRtlNotifyUninitializeSync(&Vcb->NotifySync); } if (Vcb->ffs_super_block) { ExFreePool(Vcb->ffs_super_block); Vcb->ffs_super_block = NULL; } if (VcbResourceInitialized) { ExDeleteResourceLite(&Vcb->MainResource); ExDeleteResourceLite(&Vcb->PagingIoResource); } } } return Status; }
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; UNICODE_STRING uniPsSetCreateProcessNotifyRoutineEx; PsSetCreateProcessNotifyRoutineEx_t pPsSetCreateProcessNotifyRoutineEx = NULL; __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. // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx // will be used. This function returns STATUS_ACCESS_DENIED // if there is a signing error. In that case, the AFSProcessNotifyEx // routine has not been registered and we can fallback to the // Windows 2000 interface and AFSProcessNotify. // RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx, L"PsSetCreateProcessNotifyRoutineEx"); pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx); ntStatus = STATUS_ACCESS_DENIED; if ( pPsSetCreateProcessNotifyRoutineEx) { ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx, FALSE); } if ( ntStatus == STATUS_ACCESS_DENIED) { ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify, FALSE); } ntStatus = STATUS_SUCCESS; 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( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) ) { AFSDbgLogMsg( 0, 0, "EXCEPTION - AFSRedirFs DriverEntry\n"); AFSDumpTraceFilesFnc(); } return ntStatus; }