NTSTATUS DiskRemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type ) /*++ Routine Description: This routine will release any resources the device may have allocated for this device object and return. Arguments: DeviceObject - the device object being removed Return Value: status --*/ { PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension; PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension; PAGED_CODE(); // // Handle query and cancel // if((Type == IRP_MN_QUERY_REMOVE_DEVICE) || (Type == IRP_MN_CANCEL_REMOVE_DEVICE)) { return STATUS_SUCCESS; } // // Delete our object directory. // if(fdoExtension->DeviceDirectory != NULL) { ZwMakeTemporaryObject(fdoExtension->DeviceDirectory); ZwClose(fdoExtension->DeviceDirectory); fdoExtension->DeviceDirectory = NULL; } if(Type == IRP_MN_REMOVE_DEVICE) { FREE_POOL(fdoExtension->SenseData); IoGetConfigurationInformation()->DiskCount--; } DiskDeleteSymbolicLinks(DeviceObject); if (Type == IRP_MN_REMOVE_DEVICE) { ClassDeleteSrbLookasideList(commonExtension); } return STATUS_SUCCESS; }
NTSTATUS NTAPI DiskRemoveDevice( IN PDEVICE_OBJECT DeviceObject, IN UCHAR Type ) /*++ Routine Description: This routine will release any resources the device may have allocated for this device object and return. Arguments: DeviceObject - the device object being removed Return Value: status --*/ { PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension; PDISK_DATA diskData = commonExtension->DriverData; PAGED_CODE(); // // Handle query and cancel // if((Type == IRP_MN_QUERY_REMOVE_DEVICE) || (Type == IRP_MN_CANCEL_REMOVE_DEVICE)) { return STATUS_SUCCESS; } if(commonExtension->IsFdo) { PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension; // // Purge the cached partition table (if any). // DiskAcquirePartitioningLock(fdoExtension); DiskInvalidatePartitionTable(fdoExtension, TRUE); DiskReleasePartitioningLock(fdoExtension); // // Delete our object directory. // if(fdoExtension->AdapterDescriptor) { ExFreePool(fdoExtension->AdapterDescriptor); fdoExtension->AdapterDescriptor = NULL; } if(fdoExtension->DeviceDescriptor) { ExFreePool(fdoExtension->DeviceDescriptor); fdoExtension->DeviceDescriptor = NULL; } if(fdoExtension->SenseData) { ExFreePool(fdoExtension->SenseData); fdoExtension->SenseData = NULL; } if(fdoExtension->DeviceDirectory != NULL) { ZwMakeTemporaryObject(fdoExtension->DeviceDirectory); ZwClose(fdoExtension->DeviceDirectory); fdoExtension->DeviceDirectory = NULL; } if(Type == IRP_MN_REMOVE_DEVICE) { IoGetConfigurationInformation()->DiskCount--; } } else { //PPHYSICAL_DEVICE_EXTENSION pdoExtension = DeviceObject->DeviceExtension; } DiskDeleteSymbolicLinks(DeviceObject); // // Release the mounted device interface if we've set it. // if(diskData->PartitionInterfaceString.Buffer != NULL) { IoSetDeviceInterfaceState(&(diskData->PartitionInterfaceString), FALSE); RtlFreeUnicodeString(&(diskData->PartitionInterfaceString)); RtlInitUnicodeString(&(diskData->PartitionInterfaceString), NULL); } if(diskData->DiskInterfaceString.Buffer != NULL) { IoSetDeviceInterfaceState(&(diskData->DiskInterfaceString), FALSE); RtlFreeUnicodeString(&(diskData->DiskInterfaceString)); RtlInitUnicodeString(&(diskData->DiskInterfaceString), NULL); } ClassDeleteSrbLookasideList(commonExtension); return STATUS_SUCCESS; }
NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { UNICODE_STRING parameter_path;//注册表路径 RTL_QUERY_REGISTRY_TABLE query_table[2];//注册表查询返回值 ULONG n_devices;// NTSTATUS status; UNICODE_STRING device_dir_name; OBJECT_ATTRIBUTES object_attributes; ULONG n; USHORT n_created_devices; //后面这几行是对注册表路径一些。 parameter_path.Length = 0; parameter_path.MaximumLength = RegistryPath->Length + sizeof(PARAMETER_KEY); //获取绝对路径的长度 parameter_path.Buffer = (PWSTR) ExAllocatePool(PagedPool, parameter_path.MaximumLength);//分页的形式 if (parameter_path.Buffer == NULL) { return STATUS_INSUFFICIENT_RESOURCES;//分配失败。 } RtlCopyUnicodeString(¶meter_path, RegistryPath);//Copy运行时间库 RtlAppendUnicodeToString(¶meter_path, PARAMETER_KEY);//合并为完整路径 //HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FileDisk\Parameters // 接着对query_talbe进行操作。 RtlZeroMemory(&query_table[0], sizeof(query_table)); query_table[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; query_table[0].Name = NUMBEROFDEVICES_VALUE; query_table[0].EntryContext = &n_devices; status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, parameter_path.Buffer, &query_table[0], NULL, NULL ); ExFreePool(parameter_path.Buffer);//释放 if (!NT_SUCCESS(status)) { KdPrint(("FileDisk: Query registry failed, using default values.\n")); n_devices = DEFAULT_NUMBEROFDEVICES; } //相当于RtlInitUnicodeString(&device_name,L"\\Device\\FileDisk"); RtlInitUnicodeString(&device_dir_name, DEVICE_DIR_NAME); InitializeObjectAttributes( &object_attributes, &device_dir_name, OBJ_PERMANENT, NULL, NULL ); //当设备目录"\\Device"不存在的时候,你的创建会失败。所以应该先创建这个目录, // 使用ZwCreateDirectoryObject即可。 status = ZwCreateDirectoryObject( &dir_handle, DIRECTORY_ALL_ACCESS, &object_attributes ); if (!NT_SUCCESS(status)) { return status; } ZwMakeTemporaryObject(dir_handle); //创建的是 FILE_DEVICE_DISK 和 FILE_DEVICE_CD_ROM for (n = 0, n_created_devices = 0; n < n_devices; n++) { status = FileDiskCreateDevice(DriverObject, n, FILE_DEVICE_DISK); if (NT_SUCCESS(status)) { n_created_devices++; } } for (n = 0; n < n_devices; n++)// { status = FileDiskCreateDevice(DriverObject, n, FILE_DEVICE_CD_ROM); if (NT_SUCCESS(status)) { n_created_devices++; } } if (n_created_devices == 0) { ZwClose(dir_handle); return status; } //派谴例程 DriverObject->MajorFunction[IRP_MJ_CREATE] = FileDiskCreateClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = FileDiskCreateClose; DriverObject->MajorFunction[IRP_MJ_READ] = FileDiskReadWrite; DriverObject->MajorFunction[IRP_MJ_WRITE] = FileDiskReadWrite; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FileDiskDeviceControl; DriverObject->DriverUnload = FileDiskUnload; return STATUS_SUCCESS; }
NTSTATUS DfsDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS Status; UNICODE_STRING UnicodeString; PDEVICE_OBJECT DeviceObject; OBJECT_ATTRIBUTES ObjectAttributes; PWSTR p; int i; HANDLE hTemp; HANDLE DirHandle; IO_STATUS_BLOCK iosb; // // See if someone else has already created a File System Device object // with the name we intend to use. If so, we bail. // RtlInitUnicodeString( &UnicodeString, DFS_DRIVER_NAME ); InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, 0, NULL); Status = ZwCreateFile( &hTemp, SYNCHRONIZE, &ObjectAttributes, &iosb, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, 0, NULL, 0); if (NT_SUCCESS(Status)) { ZwClose( hTemp ); DfsDbgTrace(0, Dbg, "Dfs driver already loaded!\n", 0); return( STATUS_UNSUCCESSFUL ); } // // Create the filesystem device object. // Status = IoCreateDevice( DriverObject, 0, &UnicodeString, FILE_DEVICE_DFS_FILE_SYSTEM, FILE_REMOTE_DEVICE, FALSE, &DeviceObject ); if ( !NT_SUCCESS( Status ) ) { return Status; } // // Create a permanent object directory in which the logical root // device objects will reside. Make the directory temporary, so // we can just close the handle to make it go away. // UnicodeString.Buffer = p = LogicalRootDevPath; UnicodeString.Length = 0; UnicodeString.MaximumLength = MAX_LOGICAL_ROOT_LEN; while (*p++ != UNICODE_NULL) UnicodeString.Length += sizeof (WCHAR); InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_PERMANENT, NULL, NULL ); Status = ZwCreateDirectoryObject( &DirHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if ( !NT_SUCCESS( Status ) ) { return Status; } ZwMakeTemporaryObject(DirHandle); p[-1] = UNICODE_PATH_SEP; UnicodeString.Length += sizeof (WCHAR); // // Initialize the driver object with this driver's entry points. // Most are simply passed through to some other device driver. // for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = DfsVolumePassThrough; } DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)DfsFsdCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)DfsFsdClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = (PDRIVER_DISPATCH)DfsFsdCleanup; DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdQueryInformation; DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = (PDRIVER_DISPATCH)DfsFsdSetInformation; DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = (PDRIVER_DISPATCH)DfsFsdFileSystemControl; DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdQueryVolumeInformation; DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]= (PDRIVER_DISPATCH)DfsFsdSetVolumeInformation; DriverObject->FastIoDispatch = &FastIoDispatch; // // Initialize the global data structures // RtlZeroMemory(&DfsData, sizeof (DFS_DATA)); DfsData.NodeTypeCode = DSFS_NTC_DATA_HEADER; DfsData.NodeByteSize = sizeof( DFS_DATA ); InitializeListHead( &DfsData.VcbQueue ); InitializeListHead( &DfsData.DeletedVcbQueue ); InitializeListHead( &DfsData.Credentials ); InitializeListHead( &DfsData.DeletedCredentials ); DfsData.DriverObject = DriverObject; DfsData.FileSysDeviceObject = DeviceObject; DfsData.LogRootDevName = UnicodeString; ExInitializeResource( &DfsData.Resource ); KeInitializeEvent( &DfsData.PktWritePending, NotificationEvent, TRUE ); KeInitializeSemaphore( &DfsData.PktReferralRequests, 1, 1 ); DfsData.MachineState = DFS_CLIENT; // // Allocate Provider structures. // DfsData.pProvider = ExAllocatePool( PagedPool, sizeof ( PROVIDER_DEF ) * MAX_PROVIDERS); for (i = 0; i < MAX_PROVIDERS; i++) { DfsData.pProvider[i].NodeTypeCode = DSFS_NTC_PROVIDER; DfsData.pProvider[i].NodeByteSize = sizeof ( PROVIDER_DEF ); } DfsData.cProvider = 0; DfsData.maxProvider = MAX_PROVIDERS; // // Initialize the system wide PKT // PktInitialize(&DfsData.Pkt); { ULONG SystemSizeMultiplier; ULONG ZoneSegmentSize; switch (MmQuerySystemSize()) { default: case MmSmallSystem: SystemSizeMultiplier = 4; break; case MmMediumSystem: SystemSizeMultiplier = 8; break; case MmLargeSystem: SystemSizeMultiplier = 16; break; } // // Allocate the DFS_FCB hash table structure. The number of hash buckets // will depend upon the memory size of the system. // Status = DfsInitFcbs(SystemSizeMultiplier * 2); // // Now initialize the zone structures for allocating IRP context // records. The size of the zone will depend upon the memory // available in the system. // KeInitializeSpinLock( &DfsData.IrpContextSpinLock ); ZoneSegmentSize = (SystemSizeMultiplier * QuadAlign(sizeof(IRP_CONTEXT))) + sizeof(ZONE_SEGMENT_HEADER); (VOID) ExInitializeZone( &DfsData.IrpContextZone, QuadAlign(sizeof(IRP_CONTEXT)), FsRtlAllocatePool( NonPagedPool, ZoneSegmentSize ), ZoneSegmentSize ); } // // Set up global pointer to the system process. // DfsData.OurProcess = PsGetCurrentProcess(); // // Register the file system with the I/O system // IoRegisterFileSystem( DeviceObject ); // // Initialize the provider definitions from the registry. // if (!NT_SUCCESS( ProviderInit() )) { DfsDbgTrace(0,DEBUG_TRACE_ERROR, "Could not initialize some or all providers!\n", 0); } // // Initialize the logical roots device objects. These are what form the // link between the outside world and the Dfs driver. // Status = DfsInitializeLogicalRoot( DD_DFS_DEVICE_NAME, NULL, NULL, 0); if (!NT_SUCCESS(Status)) { DfsDbgTrace(-1, DEBUG_TRACE_ERROR, "Failed creation of root logical root %08lx\n", Status); return(Status); } // // Let us start off the Timer Routine. // RtlZeroMemory(&DfsTimerContext, sizeof(DFS_TIMER_CONTEXT)); DfsTimerContext.InUse = FALSE; DfsTimerContext.TickCount = 0; IoInitializeTimer(DeviceObject, DfsIoTimerRoutine, &DfsTimerContext); DfsDbgTrace(0, Dbg, "Initialized the Timer routine\n", 0); // // Let us start the timer now. // IoStartTimer(DeviceObject); return STATUS_SUCCESS; }