PLFS_TABLE LfsTable_Create( IN PLFS Lfs ) { PLFS_TABLE lfsTable; LfsReference (Lfs); lfsTable = ExAllocatePoolWithTag( NonPagedPool, sizeof(LFS_TABLE), LFS_ALLOC_TAG ); if (lfsTable == NULL) { ASSERT(LFS_INSUFFICIENT_RESOURCES); LfsDereference (Lfs); return NULL; } RtlZeroMemory( lfsTable, sizeof(LFS_TABLE) ); KeInitializeSpinLock(&lfsTable->SpinLock); InitializeListHead(&lfsTable->LfsTabPartitionList) ; lfsTable->ReferenceCount = 1; lfsTable->Lfs = Lfs; return lfsTable; }
PPRIMARY Primary_Create ( IN PLFS Lfs ) { PPRIMARY primary; OBJECT_ATTRIBUTES objectAttributes; LONG i; NTSTATUS ntStatus; LARGE_INTEGER timeOut; SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_Create: Entered\n")); LfsReference (Lfs); primary = ExAllocatePoolWithTag( NonPagedPool, sizeof(PRIMARY), LFS_ALLOC_TAG ); if (primary == NULL) { ASSERT(LFS_INSUFFICIENT_RESOURCES); LfsDereference (Lfs); return NULL; } RtlZeroMemory( primary, sizeof(PRIMARY) ); KeInitializeSpinLock(&primary->SpinLock); primary->ReferenceCount = 1; primary->Lfs = Lfs; // InitializeListHead(&primary->LfsDeviceExtQueue); // KeInitializeSpinLock(&primary->LfsDeviceExtQSpinLock); for(i=0; i<MAX_SOCKETLPX_INTERFACE; i++) { InitializeListHead(&primary->PrimarySessionQueue[i]); KeInitializeSpinLock(&primary->PrimarySessionQSpinLock[i]); } primary->Agent.ThreadHandle = 0; primary->Agent.ThreadObject = NULL; primary->Agent.Flags = 0; KeInitializeEvent(&primary->Agent.ReadyEvent, NotificationEvent, FALSE); InitializeListHead(&primary->Agent.RequestQueue); KeInitializeSpinLock(&primary->Agent.RequestQSpinLock); KeInitializeEvent(&primary->Agent.RequestEvent, NotificationEvent, FALSE); primary->Agent.ListenPort = DEFAULT_PRIMARY_PORT; primary->Agent.ActiveListenSocketCount = 0; InitializeObjectAttributes(&objectAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); ntStatus = PsCreateSystemThread( &primary->Agent.ThreadHandle, THREAD_ALL_ACCESS, &objectAttributes, NULL, NULL, PrimaryAgentThreadProc, primary ); if(!NT_SUCCESS(ntStatus)) { ASSERT(LFS_UNEXPECTED); Primary_Close(primary); return NULL; } ntStatus = ObReferenceObjectByHandle( primary->Agent.ThreadHandle, FILE_READ_DATA, NULL, KernelMode, &primary->Agent.ThreadObject, NULL ); if(!NT_SUCCESS(ntStatus)) { ASSERT(LFS_INSUFFICIENT_RESOURCES); Primary_Close(primary); return NULL; } timeOut.QuadPart = - LFS_TIME_OUT; // 10 sec ntStatus = KeWaitForSingleObject( &primary->Agent.ReadyEvent, Executive, KernelMode, FALSE, &timeOut ); ASSERT(ntStatus == STATUS_SUCCESS); KeClearEvent(&primary->Agent.ReadyEvent); if(ntStatus != STATUS_SUCCESS) { ASSERT(LFS_BUG); Primary_Close(primary); return NULL; } SPY_LOG_PRINT( LFS_DEBUG_PRIMARY_INFO, ("Primary_Create: primary = %p\n", primary)); return primary; }
NTSTATUS CtxInstanceSetup ( __in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType ) /*++ Routine Description: This routine is called whenever a new instance is created on a volume. This gives us a chance to decide if we need to attach to this volume or not. Arguments: FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing opaque handles to this filter, instance and its associated volume. Flags - Flags describing the reason for this attach request. Return Value: STATUS_SUCCESS - attach STATUS_FLT_DO_NOT_ATTACH - do not attach --*/ { PCTX_INSTANCE_CONTEXT instanceContext = NULL; NTSTATUS status = STATUS_SUCCESS; ULONG volumeNameLength; #if __NDAS_FS_MINI__ ULONG propertyLengthReturned; UNICODE_STRING ntfs; UNICODE_STRING ndasNtfs; UNICODE_STRING fat; UNICODE_STRING ndasFat; PNETDISK_PARTITION netdiskPartition; NETDISK_ENABLE_MODE netdiskEnableMode; #endif #if __LFS__ ULONG propertyLengthReturned; BOOLEAN result; UNICODE_STRING ntfs; UNICODE_STRING ndasNtfs; UNICODE_STRING fat; UNICODE_STRING ndasFat; PENABLED_NETDISK enabledNetdisk; NETDISK_ENABLE_MODE netdiskEnableMode; #endif UNREFERENCED_PARAMETER( Flags ); UNREFERENCED_PARAMETER( VolumeDeviceType ); UNREFERENCED_PARAMETER( VolumeFilesystemType ); PAGED_CODE(); #if __NDAS_FS_MINI__ DebugTrace( DEBUG_TRACE_INSTANCES, ("[Ctx]: Instance setup started FltObjects = %p\n", FltObjects) ); #endif DebugTrace( DEBUG_TRACE_INSTANCES, ("[Ctx]: Instance setup started (Volume = %p, Instance = %p)\n", FltObjects->Volume, FltObjects->Instance) ); // // Allocate and initialize the context for this volume // // // Allocate the instance context // DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, ("[Ctx]: Allocating instance context (Volume = %p, Instance = %p)\n", FltObjects->Volume, FltObjects->Instance) ); status = FltAllocateContext( FltObjects->Filter, FLT_INSTANCE_CONTEXT, CTX_INSTANCE_CONTEXT_SIZE, NonPagedPool, &instanceContext ); if (!NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, ("[Ctx]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%x)\n", FltObjects->Volume, FltObjects->Instance, status) ); goto CtxInstanceSetupCleanup; } #if __NDAS_FS_MINI__ RtlZeroMemory( instanceContext, sizeof(CTX_INSTANCE_CONTEXT) ); status = FltGetVolumeProperties( FltObjects->Volume, NULL, 0, &propertyLengthReturned ); DebugTrace( DEBUG_TRACE_INSTANCES, ("[MiniSpy]: IRP_MJ_VOLUME_MOUNT FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n", status, propertyLengthReturned) ); instanceContext->VolumeProperties = ExAllocatePoolWithTag( PagedPool, propertyLengthReturned, CTX_VOLUME_PROPERTY_TAG ); status = FltGetVolumeProperties( FltObjects->Volume, instanceContext->VolumeProperties, propertyLengthReturned, &propertyLengthReturned ); DebugTrace( DEBUG_TRACE_INSTANCES, ("[MiniSpy]: FltGetVolumeProperties, status = %x, propertyLengthReturned = %d\n", status, propertyLengthReturned) ); if( !NT_SUCCESS( status )) { status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } DebugTrace( DEBUG_TRACE_INSTANCES, ("[MiniSpy]: FltGetVolumeProperties, DeviceType = %d " "FileSystemDriverName = %wZ\n" "FileSystemDeviceName = %wZ " "RealDeviceName = %wZ\n", instanceContext->VolumeProperties->DeviceType, &instanceContext->VolumeProperties->FileSystemDriverName, &instanceContext->VolumeProperties->FileSystemDeviceName, &instanceContext->VolumeProperties->RealDeviceName) ); RtlInitUnicodeString( &ntfs, L"\\Ntfs" ); RtlInitUnicodeString( &ndasNtfs, NDAS_NTFS_DEVICE_NAME ); RtlInitUnicodeString( &fat, L"\\Fat" ); RtlInitUnicodeString( &ndasFat, NDAS_FAT_DEVICE_NAME ); if (!(RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE) || RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE) || RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE) || RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE))) { status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } status = FltGetDeviceObject( FltObjects->Volume, &instanceContext->DeviceObject ); if (!NT_SUCCESS(status)) { status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } status = FltGetDiskDeviceObject( FltObjects->Volume, &instanceContext->DiskDeviceObject ); if (!NT_SUCCESS(status)) { status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } DebugTrace( DEBUG_TRACE_INSTANCES, ("DeviceObject = %p, DiskDeviceObject = %p\n", instanceContext->DeviceObject, instanceContext->DiskDeviceObject) ); if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) && !GlobalLfs.NdasFatRwSupport && !GlobalLfs.NdasFatRoSupport || RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE) && !GlobalLfs.NdasNtfsRwSupport && !GlobalLfs.NdasNtfsRoSupport) { NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) { status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager, GlobalLfs.NdasFatRwIndirect ? TRUE : FALSE, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice, &netdiskPartition, &netdiskEnableMode ); } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) { status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager, GlobalLfs.NdasNtfsRwIndirect ? TRUE : FALSE, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice, &netdiskPartition, &netdiskEnableMode ); } else { status = NetdiskManager_PreMountVolume( GlobalLfs.NetdiskManager, FALSE, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.DeviceObject, instanceContext->DiskDeviceObject, //pIrpSp->Parameters.MountVolume.Vpb->RealDevice, &netdiskPartition, &netdiskEnableMode ); } SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("NetdiskManager_IsNetdiskPartition status = %x\n", status) ); if (!NT_SUCCESS(status)) { if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE) || RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) { NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } switch (netdiskEnableMode) { case NETDISK_READ_ONLY: if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) { if (GlobalLfs.NdasFatRoSupport) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) { if (!GlobalLfs.NdasFatRoSupport) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) { if (GlobalLfs.NdasNtfsRoSupport) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) { if (!GlobalLfs.NdasNtfsRoSupport) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else { NDASFS_ASSERT( FALSE ); } break; case NETDISK_SECONDARY: case NETDISK_PRIMARY: case NETDISK_SECONDARY2PRIMARY: if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) { if (GlobalLfs.NdasFatRwSupport && FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) { if (!(GlobalLfs.NdasFatRwSupport && FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) { if (GlobalLfs.NdasNtfsRwSupport && FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE)) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) { if (!(GlobalLfs.NdasNtfsRwSupport && FlagOn(netdiskPartition->EnabledNetdisk->NetdiskInformation.EnabledFeatures, NDASFEATURE_SIMULTANEOUS_WRITE))) { NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, netdiskPartition, netdiskEnableMode, FALSE, 0, NULL, NULL ); NDASFS_ASSERT( FALSE ); status = STATUS_FLT_DO_NOT_ATTACH; goto CtxInstanceSetupCleanup; } } else { NDASFS_ASSERT( FALSE ); } break; default: NDASFS_ASSERT( FALSE ); break; } LfsReference( &GlobalLfs ); ExInitializeFastMutex( &instanceContext->LfsDeviceExt.FastMutex ); instanceContext->LfsDeviceExt.ReferenceCount = 1; InitializeListHead( &instanceContext->LfsDeviceExt.LfsQListEntry ); instanceContext->LfsDeviceExt.Flags = LFS_DEVICE_FLAG_INITIALIZING; instanceContext->LfsDeviceExt.FileSpyDeviceObject = NULL; instanceContext->LfsDeviceExt.InstanceContext = instanceContext; FltReferenceContext( instanceContext->LfsDeviceExt.InstanceContext ); instanceContext->LfsDeviceExt.NetdiskPartition = netdiskPartition; instanceContext->LfsDeviceExt.NetdiskEnabledMode = netdiskEnableMode; instanceContext->LfsDeviceExt.FilteringMode = LFS_NO_FILTERING; instanceContext->LfsDeviceExt.DiskDeviceObject = instanceContext->DiskDeviceObject; instanceContext->LfsDeviceExt.MountVolumeDeviceObject = instanceContext->DiskDeviceObject; SPY_LOG_PRINT( SPYDEBUG_ERROR, ("FileSpy!CtxInstanceSetup: instanceContext->LfsDeviceExt.DiskDeviceObject = %p\n", instanceContext->LfsDeviceExt.DiskDeviceObject) ); ExInterlockedInsertTailList( &GlobalLfs.LfsDeviceExtQueue, &instanceContext->LfsDeviceExt.LfsQListEntry, &GlobalLfs.LfsDeviceExtQSpinLock ); if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ntfs, TRUE)) { instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NTFS; } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasNtfs, TRUE)) { instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_NTFS; } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &fat, TRUE)) { instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_FAT; } else if (RtlEqualUnicodeString(&instanceContext->VolumeProperties->FileSystemDeviceName, &ndasFat, TRUE)) { instanceContext->LfsDeviceExt.FileSystemType = LFS_FILE_SYSTEM_NDAS_FAT; } else { NDASFS_ASSERT( FALSE ); } NetdiskManager_PostMountVolume( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode, TRUE, instanceContext->LfsDeviceExt.FileSystemType, &instanceContext->LfsDeviceExt, &instanceContext->LfsDeviceExt.NetdiskPartitionInformation ); switch (netdiskEnableMode) { case NETDISK_READ_ONLY: instanceContext->LfsDeviceExt.FilteringMode = LFS_READONLY; break; case NETDISK_SECONDARY: instanceContext->LfsDeviceExt.FilteringMode = LFS_SECONDARY; break; case NETDISK_PRIMARY: case NETDISK_SECONDARY2PRIMARY: instanceContext->LfsDeviceExt.FilteringMode = LFS_PRIMARY; break; default: ASSERT( LFS_BUG ); break; } SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING ); ASSERT( instanceContext->DiskDeviceObject->Vpb->DeviceObject ); instanceContext->LfsDeviceExt.Vpb = instanceContext->LfsDeviceExt.DiskDeviceObject->Vpb; // Vpb will be changed in IrpSp Why ? instanceContext->LfsDeviceExt.BaseVolumeDeviceObject = instanceContext->LfsDeviceExt.Vpb->DeviceObject; switch (instanceContext->LfsDeviceExt.FilteringMode) { case LFS_READONLY: { // // We don't support cache purging yet. // SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: READONLY newDevExt->LfsDeviceExt = %p " "newDevExt->LfsDeviceExt.FileSystemType = %d\n", &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) ); instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject; NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode, status, instanceContext->LfsDeviceExt.AttachedToDeviceObject ); status = SpyFsControlReadonlyMountVolumeComplete( &instanceContext->LfsDeviceExt ); break; } case LFS_PRIMARY: { instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject; ASSERT( instanceContext->LfsDeviceExt.AttachedToDeviceObject ); NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode, status, instanceContext->LfsDeviceExt.AttachedToDeviceObject ); SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("LfsFsControlMountVolumeComplete: LFS_PRIMARY newDevExt->LfsDeviceExt = %p " "newDevExt->LfsDeviceExt.FileSystemType = %d\n", &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) ); status = STATUS_SUCCESS; break; } case LFS_SECONDARY: { instanceContext->LfsDeviceExt.AttachedToDeviceObject = instanceContext->DeviceObject; //NULL; //instanceContext->NLExtHeader.AttachedToDeviceObject; NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode, status, instanceContext->LfsDeviceExt.AttachedToDeviceObject ); SPY_LOG_PRINT( LFS_DEBUG_LFS_INFO, ("CtxInstanceSetup: LFS_SECONDARY newDevExt->LfsDeviceExt = %p " "newDevExt->LfsDeviceExt.FileSystemType = %d\n", &instanceContext->LfsDeviceExt, instanceContext->LfsDeviceExt.FileSystemType) ); status = SpyFsControlSecondaryMountVolumeComplete( &instanceContext->LfsDeviceExt ); if (instanceContext->LfsDeviceExt.FilteringMode == LFS_SECONDARY_TO_PRIMARY) { NetdiskManager_ChangeMode( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, &instanceContext->LfsDeviceExt.NetdiskEnabledMode ); } break; } default: NDASFS_ASSERT( FALSE ); NetdiskManager_MountVolumeComplete( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode, status, NULL ); status = STATUS_SUCCESS; break; } // // We completed initialization of this device object, so now // clear the initializing flag. // if (status == STATUS_SUCCESS) { ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING ); ClearFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTING ); SetFlag( instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_MOUNTED ); } else { NTSTATUS status2; NDASFS_ASSERT( FALSE ); // // Queue an event to notify user applications // XevtQueueVolumeInvalidOrLocked( -1, instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.SlotNo, instanceContext->LfsDeviceExt.NetdiskPartitionInformation.NetdiskInformation.UnitDiskNo ); // // Try to unplug // status2 = NetdiskManager_UnplugNetdisk( GlobalLfs.NetdiskManager, instanceContext->LfsDeviceExt.NetdiskPartition, instanceContext->LfsDeviceExt.NetdiskEnabledMode ); ASSERT( NT_SUCCESS(status2) ); } #endif // // Get the NT volume name length // status = FltGetVolumeName( FltObjects->Volume, NULL, &volumeNameLength ); if( !NT_SUCCESS( status ) && (status != STATUS_BUFFER_TOO_SMALL) ) { DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n", FltObjects->Volume, FltObjects->Instance, status) ); goto CtxInstanceSetupCleanup; } // // Allocate a string big enough to take the volume name // instanceContext->VolumeName.MaximumLength = (USHORT) volumeNameLength; status = CtxAllocateUnicodeString( &instanceContext->VolumeName ); if( !NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, ("[Ctx]: Failed to allocate volume name string. (Volume = %p, Instance = %p, Status = 0x%x)\n", FltObjects->Volume, FltObjects->Instance, status) ); goto CtxInstanceSetupCleanup; } // // Get the NT volume name // status = FltGetVolumeName( FltObjects->Volume, &instanceContext->VolumeName, &volumeNameLength ); if( !NT_SUCCESS( status ) ) { DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n", FltObjects->Volume, FltObjects->Instance, status) ); goto CtxInstanceSetupCleanup; } instanceContext->Instance = FltObjects->Instance; instanceContext->Volume = FltObjects->Volume; // // Set the instance context. // DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, ("[Ctx]: Setting instance context %p for volume %wZ (Volume = %p, Instance = %p)\n", instanceContext, &instanceContext->VolumeName, FltObjects->Volume, FltObjects->Instance) ); status = FltSetInstanceContext( FltObjects->Instance, FLT_SET_CONTEXT_KEEP_IF_EXISTS, instanceContext, NULL ); if( !NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR, ("[Ctx]: Failed to set instance context for volume %wZ (Volume = %p, Instance = %p, Status = 0x%08X)\n", &instanceContext->VolumeName, FltObjects->Volume, FltObjects->Instance, status) ); goto CtxInstanceSetupCleanup; } CtxInstanceSetupCleanup: #if __NDAS_FS_MINI__ if (status != STATUS_SUCCESS) { if (instanceContext->DiskDeviceObject) { ObDereferenceObject( instanceContext->DiskDeviceObject ); instanceContext->DiskDeviceObject = NULL; } if (instanceContext->DeviceObject) { ObDereferenceObject( instanceContext->DeviceObject ); instanceContext->DeviceObject = NULL; } if (instanceContext->VolumeProperties) { ExFreePoolWithTag( instanceContext->VolumeProperties, CTX_VOLUME_PROPERTY_TAG ); instanceContext->VolumeProperties = NULL; } if (FlagOn(instanceContext->LfsDeviceExt.Flags, LFS_DEVICE_FLAG_INITIALIZING)) { LfsDeviceExt_Dereference( &instanceContext->LfsDeviceExt ); } } #endif // // If FltAllocateContext suceeded then we MUST release the context, // irrespective of whether FltSetInstanceContext suceeded or not. // // FltAllocateContext increments the ref count by one. // A successful FltSetInstanceContext increments the ref count by one // and also associates the context with the file system object // // FltReleaseContext decrements the ref count by one. // // When FltSetInstanceContext succeeds, calling FltReleaseContext will // leave the context with a ref count of 1 corresponding to the internal // reference to the context from the file system structures // // When FltSetInstanceContext fails, calling FltReleaseContext will // leave the context with a ref count of 0 which is correct since // there is no reference to the context from the file system structures // if ( instanceContext != NULL ) { DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, ("[Ctx]: Releasing instance context %p (Volume = %p, Instance = %p)\n", instanceContext, FltObjects->Volume, FltObjects->Instance) ); FltReleaseContext( instanceContext ); } if (NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_INSTANCES, ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n", FltObjects->Volume, FltObjects->Instance) ); } else { DebugTrace( DEBUG_TRACE_INSTANCES, ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n", FltObjects->Volume, FltObjects->Instance) ); } return status; }