NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNICODE_STRING DeviceName, DeviceLink; NTSTATUS NtStatus; PDEVICE_OBJECT DeviceObject = NULL; PDEVICE_EXTENSION extension; WinDbgPrint("WinPMEM - " PMEM_VERSION " - Physical memory acquisition\n"); #if PMEM_WRITE_ENABLED == 1 WinDbgPrint("WinPMEM write support available!"); #endif WinDbgPrint("Copyright (c) 2014, Michael Cohen <*****@*****.**>\n"); // Initialize import tables: if(PmemGetProcAddresses() != STATUS_SUCCESS) { WinDbgPrint("Failed to initialize import table. Aborting.\n"); goto error; }; RtlInitUnicodeString (&DeviceName, L"\\Device\\" PMEM_DEVICE_NAME); // We create our secure device. // http://msdn.microsoft.com/en-us/library/aa490540.aspx NtStatus = IoCreateDeviceSecure(DriverObject, sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, &GUID_DEVCLASS_PMEM_DUMPER, &DeviceObject); if (!NT_SUCCESS(NtStatus)) { WinDbgPrint ("IoCreateDevice failed. => %08X\n", NtStatus); return NtStatus; } DriverObject->MajorFunction[IRP_MJ_CREATE] = wddCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = wddClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = wddDispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_READ] = PmemRead; #if PMEM_WRITE_ENABLED == 1 { // Make sure that the drivers with write support are clearly marked as such. static char TAG[] = "Write Supported"; } // Support writing. DriverObject->MajorFunction[IRP_MJ_WRITE] = PmemWrite; #endif DriverObject->DriverUnload = IoUnload; // Use buffered IO - a bit slower but simpler to implement, and more // efficient for small reads. SetFlag(DeviceObject->Flags, DO_BUFFERED_IO ); ClearFlag(DeviceObject->Flags, DO_DIRECT_IO ); ClearFlag(DeviceObject->Flags, DO_DEVICE_INITIALIZING); RtlInitUnicodeString (&DeviceLink, L"\\DosDevices\\" PMEM_DEVICE_NAME); NtStatus = IoCreateSymbolicLink (&DeviceLink, &DeviceName); if (!NT_SUCCESS(NtStatus)) { WinDbgPrint ("IoCreateSymbolicLink failed. => %08X\n", NtStatus); IoDeleteDevice (DeviceObject); } // Populate globals in kernel context. CR3.QuadPart = __readcr3(); // Initialize the device extension with safe defaults. extension = DeviceObject->DeviceExtension; extension->mode = ACQUISITION_MODE_PHYSICAL_MEMORY; extension->MemoryHandle = 0; #if _WIN64 // Disable pte mapping for 32 bit systems. extension->pte_mmapper = pte_mmap_windows_new(); extension->pte_mmapper->loglevel = PTE_ERR; #else extension->pte_mmapper = NULL; #endif WinDbgPrint("Driver intialization completed."); return NtStatus; error: return STATUS_UNSUCCESSFUL; }
NTSTATUS DriverEntry ( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) /*++ Routine Description: This routine is called by the operating system to initialize the driver. It allocates a device object, initializes the supported Io callbacks, and creates a symlink to make the device accessible to Win32. It gets the registry callback version and stores it in the global variables g_MajorVersion and g_MinorVersion. It also calls CreateKTMResourceManager to create a resource manager that is used in the transaction samples. Arguments: DriverObject - Supplies the system control object for this test driver. RegistryPath - The string location of the driver's corresponding services key in the registry. Return value: Success or appropriate failure code. --*/ { NTSTATUS Status; UNICODE_STRING NtDeviceName; UNICODE_STRING DosDevicesLinkName; UNICODE_STRING DeviceSDDLString; UNREFERENCED_PARAMETER(RegistryPath); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "RegFltr: DriverEntry()\n"); DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "RegFltr: Use ed nt!Kd_IHVDRIVER_Mask 8 to enable more detailed printouts\n"); // // Create our device object. // RtlInitUnicodeString(&NtDeviceName, NT_DEVICE_NAME); RtlInitUnicodeString(&DeviceSDDLString, DEVICE_SDDL); // TODO(H): 看下这个函数 Status = IoCreateDeviceSecure( DriverObject, // pointer to driver object 0, // device extension size &NtDeviceName, // device name FILE_DEVICE_UNKNOWN, // device type 0, // device characteristics TRUE, // not exclusive &DeviceSDDLString, // SDDL string specifying access NULL, // device class guid &g_DeviceObj); // returned device object pointer if (!NT_SUCCESS(Status)) { return Status; } // // Set dispatch routines. // DriverObject->MajorFunction[IRP_MJ_CREATE] = DeviceCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DeviceClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DeviceCleanup; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl; DriverObject->DriverUnload = DeviceUnload; // // Create a link in the Win32 namespace. // RtlInitUnicodeString(&DosDevicesLinkName, DOS_DEVICES_LINK_NAME); Status = IoCreateSymbolicLink(&DosDevicesLinkName, &NtDeviceName); if (!NT_SUCCESS(Status)) { IoDeleteDevice(DriverObject->DeviceObject); return Status; } // // Get callback version. // // TODO(H): CmGetCallbackVersion(&g_MajorVersion, &g_MinorVersion); InfoPrint("Callback version %u.%u", g_MajorVersion, g_MinorVersion); // // Some variations depend on knowing if the OS is win8 or above // DetectOSVersion(); // // Set up KTM resource manager and pass in RMCallback as our // callback routine. // Status = CreateKTMResourceManager(RMCallback, NULL); if (NT_SUCCESS(Status)) { g_RMCreated = TRUE; } // // Initialize the callback context list // InitializeListHead(&g_CallbackCtxListHead); ExInitializeFastMutex(&g_CallbackCtxListLock); g_NumCallbackCtxListEntries = 0; return STATUS_SUCCESS; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING DeviceName; UNICODE_STRING DosDeviceName; // // Initialize a unicode string for the drivers object name. // RtlInitUnicodeString( &DeviceName, DEVICE_NAME_U ); // // Attempt to create a named device object // // // SDDL_DEVOBJ_SYS_ALL_ADM_ALL allows the kernel, system, and admin complete // control over the device. No other users may access the device // /* DECLARE_CONST_UNICODE_STRING( SDDL_DEVOBJ_SYS_ALL_ADM_ALL, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)" ); */ // -- Security descriptor //RtlInitUnicodeString(&sd, // _T("D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)(A;;GA;;;WD)")); Status = IoCreateDeviceSecure( DriverObject, 0, // sizeof(DEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, // FILE_DEVICE_NOTHING FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // &sd NULL, &DeviceObject ); if( !NT_SUCCESS(Status) ) { DbgPrint( "[chipsec] ERROR: DriverEntry: IoCreateDeviceSecure failed (status = %d)\n", Status ); return Status; } // // Create the symbolic link that the Win32 app can access the device // RtlInitUnicodeString (&DosDeviceName, DEVICE_NAME_DOS ); Status = IoCreateSymbolicLink(&DosDeviceName, &DeviceName); if( !NT_SUCCESS(Status) ) { DbgPrint( "[chipsec] ERROR: DriverEntry: IoCreateSymbolicLink failed\n" ); if(DeviceObject) { IoDeleteDevice(DeviceObject); } return Status; } // // Initialize the dispatch table of the driver object. // NT sends requests to these routines. // DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverOpen; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl; DriverObject->DriverUnload = DriverUnload; return Status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { NTSTATUS status; UNICODE_STRING devname, linkname; BOOLEAN ip_fw_started = FALSE, pfhook_started = FALSE; int i; g_driver_object = theDriverObject; log_init(); /* before starting ip_fw init ip_fw_nt wrappers */ ip_fw_nt_init(); rn_init(); init_tables(); iflist_init(); init_packet(); /* send load event to ip_fw */ status = module_ipfw->modevent(theDriverObject, MOD_LOAD, NULL); if (status != STATUS_SUCCESS) { KdPrint(("[wipfw] DriverEntry: ip_fw MOD_LOAD: 0x%x!\n", status)); goto done; } ip_fw_started = TRUE; /* setup pfhook */ status = pfhook_init(); if (status != STATUS_SUCCESS) { KdPrint(("[wipfw] DriverEntry: pfhook_init: 0x%x!\n", status)); goto done; } pfhook_started = TRUE; /* create control device and symbolic link */ RtlInitUnicodeString(&devname, L"\\Device\\ip_fw"); status = IoCreateDeviceSecure(theDriverObject, 0, &devname, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, (BOOLEAN) FALSE, \ &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, NULL, &g_devcontrol); if (status != STATUS_SUCCESS) { KdPrint(("[wipfw] DriverEntry: IoCreateDevice: 0x%x!\n", status)); goto done; } g_devcontrol->Flags |= DO_POWER_PAGABLE; RtlInitUnicodeString(&linkname, L"\\??\\ip_fw"); status = IoCreateSymbolicLink(&linkname, &devname); if (status != STATUS_SUCCESS) { KdPrint(("[wipfw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status)); goto done; } for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) theDriverObject->MajorFunction[i] = DeviceDispatch; theDriverObject->MajorFunction[IRP_MJ_PNP] = DeviceDispatch; #ifdef KLD_MODULE theDriverObject->DriverUnload = OnUnload; #endif status = STATUS_SUCCESS; done: if (status != STATUS_SUCCESS) { if (g_devcontrol != NULL) IoDeleteDevice(g_devcontrol); if (pfhook_started) pfhook_free(); if (ip_fw_started) module_ipfw->modevent(theDriverObject, MOD_UNLOAD, NULL); iflist_free(); log_free(); } return status; }
NTSTATUS DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath ) /*++ Routine Description: Installable driver initialization entry point. This entry point is called directly by the I/O system. Arguments: DriverObject - pointer to the driver object registryPath - pointer to a unicode string representing the path, to driver-specific key in the registry. Return Value: STATUS_SUCCESS if successful, STATUS_UNSUCCESSFUL otherwise --*/ { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING unicodeDeviceName; UNICODE_STRING unicodeDosDeviceName; PDEVICE_OBJECT deviceObject; PDEVICE_EXTENSION devExtension; HANDLE threadHandle; UNICODE_STRING sddlString; UNREFERENCED_PARAMETER (RegistryPath); CSAMP_KDPRINT(("DriverEntry Enter \n")); (void) RtlInitUnicodeString(&unicodeDeviceName, CSAMP_DEVICE_NAME_U); (void) RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"); // // We will create a secure deviceobject so that only processes running // in admin and local system account can access the device. Refer // "Security Descriptor String Format" section in the platform // SDK documentation to understand the format of the sddl string. // We need to do because this is a legacy driver and there is no INF // involved in installing the driver. For PNP drivers, security descriptor // is typically specified for the FDO in the INF file. // status = IoCreateDeviceSecure( DriverObject, sizeof(DEVICE_EXTENSION), &unicodeDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, (BOOLEAN) FALSE, &sddlString, (LPCGUID)&GUID_DEVCLASS_CANCEL_SAMPLE, &deviceObject ); if (!NT_SUCCESS(status)) { return status; } DbgPrint("DeviceObject %p\n", deviceObject); // // Allocate and initialize a Unicode String containing the Win32 name // for our device. // (void)RtlInitUnicodeString( &unicodeDosDeviceName, CSAMP_DOS_DEVICE_NAME_U ); status = IoCreateSymbolicLink( (PUNICODE_STRING) &unicodeDosDeviceName, (PUNICODE_STRING) &unicodeDeviceName ); if (!NT_SUCCESS(status)) { IoDeleteDevice(deviceObject); return status; } devExtension = deviceObject->DeviceExtension; DriverObject->MajorFunction[IRP_MJ_CREATE]= DriverObject->MajorFunction[IRP_MJ_CLOSE] = CsampCreateClose; DriverObject->MajorFunction[IRP_MJ_READ] = CsampRead; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CsampCleanup; DriverObject->DriverUnload = CsampUnload; // // Set the flag signifying that we will do buffered I/O. This causes NT // to allocate a buffer on a ReadFile operation which will then be copied // back to the calling application by the I/O subsystem // deviceObject->Flags |= DO_BUFFERED_IO; // // This is used to serailize access to the queue. // KeInitializeSpinLock(&devExtension->QueueLock); KeInitializeSemaphore(&devExtension->IrpQueueSemaphore, 0, MAXLONG ); // // Initialize the pending Irp devicequeue // InitializeListHead( &devExtension->PendingIrpQueue ); // // Initialize the cancel safe queue // IoCsqInitialize( &devExtension->CancelSafeQueue, CsampInsertIrp, CsampRemoveIrp, CsampPeekNextIrp, CsampAcquireLock, CsampReleaseLock, CsampCompleteCanceledIrp ); // // 10 is multiplied because system time is specified in 100ns units // devExtension->PollingInterval.QuadPart = Int32x32To64( CSAMP_RETRY_INTERVAL, -10); // // Note down system time // KeQuerySystemTime (&devExtension->LastPollTime); // // Start the polling thread. // devExtension->ThreadShouldStop = FALSE; status = PsCreateSystemThread(&threadHandle, (ACCESS_MASK)0, NULL, (HANDLE) 0, NULL, CsampPollingThread, deviceObject ); if ( !NT_SUCCESS( status )) { IoDeleteSymbolicLink( &unicodeDosDeviceName ); IoDeleteDevice( deviceObject ); return status; } // // Convert the Thread object handle into a pointer to the Thread object // itself. Then close the handle. // ObReferenceObjectByHandle(threadHandle, THREAD_ALL_ACCESS, NULL, KernelMode, &devExtension->ThreadObject, NULL ); ZwClose(threadHandle); CSAMP_KDPRINT(("DriverEntry Exit = %x\n", status)); ASSERT(NT_SUCCESS(status)); return status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath ) /*++ Routine Description: Called on loading. We create a device object to handle user-mode requests on, and register ourselves as a protocol with NDIS. Arguments: pDriverObject - Pointer to driver object created by system. pRegistryPath - Pointer to the Unicode name of the registry path for this driver. Return Value: NT Status code --*/ { NDIS_PROTOCOL_CHARACTERISTICS protocolChar; NTSTATUS status = STATUS_SUCCESS; NDIS_STRING protoName = NDIS_STRING_CONST("NdisProt"); UNICODE_STRING ntDeviceName; UNICODE_STRING win32DeviceName; BOOLEAN fSymbolicLink = FALSE; PDEVICE_OBJECT deviceObject = NULL; UNREFERENCED_PARAMETER(pRegistryPath); DEBUGP(DL_LOUD, ("DriverEntry\n")); Globals.pDriverObject = pDriverObject; NPROT_INIT_EVENT(&Globals.BindsComplete); do { // // Create our device object using which an application can // access NDIS devices. // RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); #ifndef WIN9X status = IoCreateDeviceSecure(pDriverObject, 0, &ntDeviceName, FILE_DEVICE_NETWORK, FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, NULL, &deviceObject); #else status = IoCreateDevice(pDriverObject, 0, &ntDeviceName, FILE_DEVICE_NETWORK, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); #endif if (!NT_SUCCESS (status)) { // // Either not enough memory to create a deviceobject or another // deviceobject with the same name exits. This could happen // if you install another instance of this device. // break; } RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName); if (!NT_SUCCESS(status)) { break; } fSymbolicLink = TRUE; deviceObject->Flags |= DO_DIRECT_IO; Globals.ControlDeviceObject = deviceObject; NPROT_INIT_LIST_HEAD(&Globals.OpenList); NPROT_INIT_LOCK(&Globals.GlobalLock); // // Initialize the protocol characterstic structure // NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); protocolChar.MajorNdisVersion = 5; protocolChar.MinorNdisVersion = 0; protocolChar.Name = protoName; protocolChar.OpenAdapterCompleteHandler = NdisProtOpenAdapterComplete; protocolChar.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete; protocolChar.SendCompleteHandler = NdisProtSendComplete; protocolChar.TransferDataCompleteHandler = NdisProtTransferDataComplete; protocolChar.ResetCompleteHandler = NdisProtResetComplete; protocolChar.RequestCompleteHandler = NdisProtRequestComplete; protocolChar.ReceiveHandler = NdisProtReceive; protocolChar.ReceiveCompleteHandler = NdisProtReceiveComplete; protocolChar.StatusHandler = NdisProtStatus; protocolChar.StatusCompleteHandler = NdisProtStatusComplete; protocolChar.BindAdapterHandler = NdisProtBindAdapter; protocolChar.UnbindAdapterHandler = NdisProtUnbindAdapter; protocolChar.UnloadHandler = NULL; protocolChar.ReceivePacketHandler = NdisProtReceivePacket; protocolChar.PnPEventHandler = NdisProtPnPEventHandler; // // Register as a protocol driver // NdisRegisterProtocol( (PNDIS_STATUS)&status, &Globals.NdisProtocolHandle, &protocolChar, sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); if (status != NDIS_STATUS_SUCCESS) { DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n")); status = STATUS_UNSUCCESSFUL; break; } #ifdef NDIS51 Globals.PartialCancelId = NdisGeneratePartialCancelId(); Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8); DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId)); #endif // // Now set only the dispatch points we would like to handle. // pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisProtOpen; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = NdisProtClose; pDriverObject->MajorFunction[IRP_MJ_READ] = NdisProtRead; pDriverObject->MajorFunction[IRP_MJ_WRITE] = NdisProtWrite; pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = NdisProtCleanup; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NdisProtIoControl; pDriverObject->DriverUnload = NdisProtUnload; status = STATUS_SUCCESS; } while (FALSE); if (!NT_SUCCESS(status)) { if (deviceObject) { #pragma prefast(disable:28107, "within critical section, device object is held") KeEnterCriticalRegion(); IoDeleteDevice(deviceObject); Globals.ControlDeviceObject = NULL; KeLeaveCriticalRegion(); } if (fSymbolicLink) { IoDeleteSymbolicLink(&win32DeviceName); } } return status; }
NTSTATUS DokanCreateDiskDevice( __in PDRIVER_OBJECT DriverObject, __in ULONG MountId, __in PWCHAR BaseGuid, __in PDOKAN_GLOBAL DokanGlobal, __in DEVICE_TYPE DeviceType, __in ULONG DeviceCharacteristics, __out PDokanDCB* Dcb ) { WCHAR diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR fsDeviceNameBuf[MAXIMUM_FILENAME_LENGTH]; WCHAR symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH]; PDEVICE_OBJECT diskDeviceObject; PDEVICE_OBJECT fsDeviceObject; PDokanDCB dcb; PDokanVCB vcb; UNICODE_STRING diskDeviceName; NTSTATUS status; BOOLEAN isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM); // make DeviceName and SymboliLink if (isNetworkFileSystem) { #ifdef DOKAN_NET_PROVIDER RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME); #else RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME); RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME); RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); #endif } else { RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_DISK_DEVICE_NAME); RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_FS_DEVICE_NAME); RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_SYMBOLIC_LINK_NAME); RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid); } RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf); // // make a DeviceObject for Disk Device // if (!isNetworkFileSystem) { status = IoCreateDeviceSecure( DriverObject, // DriverObject sizeof(DokanDCB), // DeviceExtensionSize &diskDeviceName, // DeviceName FILE_DEVICE_DISK, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &sddl, // Default SDDL String NULL, // Device Class GUID &diskDeviceObject); // DeviceObject } else { status = IoCreateDevice( DriverObject, // DriverObject sizeof(DokanDCB), // DeviceExtensionSize NULL, // DeviceName FILE_DEVICE_UNKNOWN, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &diskDeviceObject); // DeviceObject } if (!NT_SUCCESS(status)) { DDbgPrint(" IoCreateDevice (DISK_DEVICE) failed: 0x%x\n", status); return status; } DDbgPrint("DokanDiskDevice: %wZ created\n", &diskDeviceName); // // Initialize the device extension. // dcb = diskDeviceObject->DeviceExtension; *Dcb = dcb; dcb->DeviceObject = diskDeviceObject; dcb->Global = DokanGlobal; dcb->Identifier.Type = DCB; dcb->Identifier.Size = sizeof(DokanDCB); dcb->MountId = MountId; dcb->DeviceType = FILE_DEVICE_DISK; dcb->DeviceCharacteristics = DeviceCharacteristics; KeInitializeEvent(&dcb->KillEvent, NotificationEvent, FALSE); // // Establish user-buffer access method. // diskDeviceObject->Flags |= DO_DIRECT_IO; // initialize Event and Event queue DokanInitIrpList(&dcb->PendingIrp); DokanInitIrpList(&dcb->PendingEvent); DokanInitIrpList(&dcb->NotifyEvent); KeInitializeEvent(&dcb->ReleaseEvent, NotificationEvent, FALSE); // "0" means not mounted dcb->Mounted = 0; ExInitializeResourceLite(&dcb->Resource); dcb->CacheManagerNoOpCallbacks.AcquireForLazyWrite = &DokanNoOpAcquire; dcb->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &DokanNoOpRelease; dcb->CacheManagerNoOpCallbacks.AcquireForReadAhead = &DokanNoOpAcquire; dcb->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &DokanNoOpRelease; dcb->SymbolicLinkName = AllocateUnicodeString(symbolicLinkNameBuf); dcb->DiskDeviceName = AllocateUnicodeString(diskDeviceNameBuf); dcb->FileSystemDeviceName = AllocateUnicodeString(fsDeviceNameBuf); status = IoCreateDeviceSecure( DriverObject, // DriverObject sizeof(DokanVCB), // DeviceExtensionSize dcb->FileSystemDeviceName, // DeviceName DeviceType, // DeviceType DeviceCharacteristics, // DeviceCharacteristics FALSE, // Not Exclusive &sddl, // Default SDDL String NULL, // Device Class GUID &fsDeviceObject); // DeviceObject if (!NT_SUCCESS(status)) { DDbgPrint(" IoCreateDevice (FILE_SYSTEM_DEVICE) failed: 0x%x\n", status); IoDeleteDevice(diskDeviceObject); return status; } DDbgPrint("DokanFileSystemDevice: %wZ created\n", dcb->FileSystemDeviceName); vcb = fsDeviceObject->DeviceExtension; vcb->Identifier.Type = VCB; vcb->Identifier.Size = sizeof(DokanVCB); vcb->DeviceObject = fsDeviceObject; vcb->Dcb = dcb; dcb->Vcb = vcb; InitializeListHead(&vcb->NextFCB); InitializeListHead(&vcb->DirNotifyList); FsRtlNotifyInitializeSync(&vcb->NotifySync); ExInitializeFastMutex(&vcb->AdvancedFCBHeaderMutex); #if _WIN32_WINNT >= 0x0501 FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex); #else if (DokanFsRtlTeardownPerStreamContexts) { FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex); } #endif // // Establish user-buffer access method. // fsDeviceObject->Flags |= DO_DIRECT_IO; if (diskDeviceObject->Vpb) { // NOTE: This can be done by IoRegisterFileSystem + IRP_MN_MOUNT_VOLUME, // however that causes BSOD inside filter manager on Vista x86 after mount // (mouse hover on file). // Probably FS_FILTER_CALLBACKS.PreAcquireForSectionSynchronization is // not correctly called in that case. diskDeviceObject->Vpb->DeviceObject = fsDeviceObject; diskDeviceObject->Vpb->RealDevice = fsDeviceObject; diskDeviceObject->Vpb->Flags |= VPB_MOUNTED; diskDeviceObject->Vpb->VolumeLabelLength = (USHORT)wcslen(VOLUME_LABEL) * sizeof(WCHAR); RtlStringCchCopyW(diskDeviceObject->Vpb->VolumeLabel, sizeof(diskDeviceObject->Vpb->VolumeLabel) / sizeof(WCHAR), VOLUME_LABEL); diskDeviceObject->Vpb->SerialNumber = 0x19831116; } ObReferenceObject(fsDeviceObject); ObReferenceObject(diskDeviceObject); // // Create a symbolic link for userapp to interact with the driver. // status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName); if (!NT_SUCCESS(status)) { if (diskDeviceObject->Vpb) { diskDeviceObject->Vpb->DeviceObject = NULL; diskDeviceObject->Vpb->RealDevice = NULL; diskDeviceObject->Vpb->Flags = 0; } IoDeleteDevice(diskDeviceObject); IoDeleteDevice(fsDeviceObject); DDbgPrint(" IoCreateSymbolicLink returned 0x%x\n", status); return status; } DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName, dcb->DiskDeviceName); // Mark devices as initialized diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; fsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; //IoRegisterFileSystem(fsDeviceObject); if (isNetworkFileSystem) { // Run FsRtlRegisterUncProvider in System thread. HANDLE handle; PKTHREAD thread; OBJECT_ATTRIBUTES objectAttribs; InitializeObjectAttributes( &objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL); status = PsCreateSystemThread(&handle, THREAD_ALL_ACCESS, &objectAttribs, NULL, NULL, (PKSTART_ROUTINE)DokanRegisterUncProvider, dcb); if (!NT_SUCCESS(status)) { DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status); } else { ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL, KernelMode, &thread, NULL); ZwClose(handle); KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL); ObDereferenceObject(thread); } } //DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb); dcb->Mounted = 1; //DokanSendVolumeArrivalNotification(&deviceName); //DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb); return STATUS_SUCCESS; }
NTSTATUS DriverEntry( __in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath) { NTSTATUS status; PDEVICE_OBJECT deviceObject; PCONTROL_DEVICE_EXTENSION deviceExtension; ULONG i; WCHAR controlDeviceUnicodeStringBuffer[64]; UNICODE_STRING controlDeviceUnicodeString = { 0, sizeof(controlDeviceUnicodeStringBuffer), controlDeviceUnicodeStringBuffer}; KdPrint(("NdasPortExt DriverEntry build on %s %s at %s MSVC %d\n", __DATE__, __TIME__, __BUILDMACHINE_STRING__, _MSC_VER)); i = 0; do { status = RtlUnicodeStringPrintf( &controlDeviceUnicodeString, L"\\Device\\NdasPortExt%d", i++); if (!NT_SUCCESS(status)) { return status; } status = IoCreateDeviceSecure( DriverObject, sizeof(CONTROL_DEVICE_EXTENSION), &controlDeviceUnicodeString, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_KERNEL_ONLY, &GUID_DEVCLASS_UNKNOWN, &deviceObject); } while (STATUS_OBJECT_NAME_COLLISION == status); if (!NT_SUCCESS(status)) { KdPrint(("IoCreateDevice failed, status=%x\n", status)); return status; } KdPrint(("Control device=%p, name=%wZ\n", deviceObject, &controlDeviceUnicodeString)); deviceExtension = (PCONTROL_DEVICE_EXTENSION) deviceObject->DeviceExtension; RtlZeroMemory( deviceExtension, sizeof(CONTROL_DEVICE_EXTENSION)); for (i = 0; i < HOST_DEVICE_TYPE_COUNT; ++i) { deviceExtension->SymbolicLinkNames[i].Buffer = deviceExtension->SymbolicLinkNameBuffers[i]; deviceExtension->SymbolicLinkNames[i].MaximumLength = sizeof(deviceExtension->SymbolicLinkNameBuffers[i]); status = NdasPortExtRegisterExternalTypes( &controlDeviceUnicodeString, HostingDeviceTypes[i], &deviceExtension->SymbolicLinkNames[i]); if (!NT_SUCCESS(status)) { ULONG j = i; for (j = 0; j + 1 < i; ++j) { IoDeleteSymbolicLink(&deviceExtension->SymbolicLinkNames[i]); } return status; } } DriverObject->DriverUnload = NdasPortExtDriverUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdasPortExtCreateClose; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = NdasPortExtInternalDeviceControl; deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; KdPrint(("NdasPortExt loaded successfully.\n")); return STATUS_SUCCESS; }
NTSTATUS bus_plugin_dev(ioctl_usbvbus_plugin * plugin, PFDO_DEVICE_DATA fdodata, PFILE_OBJECT fo) { PDEVICE_OBJECT pdo; PPDO_DEVICE_DATA pdodata, old_pdodata; NTSTATUS status; ULONG len; PLIST_ENTRY entry; unsigned long i; PAGED_CODE (); Bus_KdPrint (fdodata, BUS_DBG_PNP_INFO, ("Exposing PDO\n" "======addr: %d\n" "======vendor:product: %04x:%04x\n", plugin->addr, plugin->vendor, plugin->product)); if(plugin->addr <= 0) return STATUS_INVALID_PARAMETER; ExAcquireFastMutex (&fdodata->Mutex); for (entry = fdodata->ListOfPDOs.Flink; entry != &fdodata->ListOfPDOs; entry = entry->Flink) { pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); if (plugin->addr == pdodata->SerialNo && pdodata->DevicePnPState != SurpriseRemovePending) { ExReleaseFastMutex (&fdodata->Mutex); return STATUS_INVALID_PARAMETER; } } ExReleaseFastMutex (&fdodata->Mutex); // Create the PDO // Bus_KdPrint(fdodata, BUS_DBG_PNP_NOISE, ("fdodata->NextLowerDriver = 0x%p\n", fdodata->NextLowerDriver)); // // PDO must have a name. You should let the system auto generate a // name by specifying FILE_AUTOGENERATED_DEVICE_NAME in the // DeviceCharacteristics parameter. Let us create a secure deviceobject, // in case the child gets installed as a raw device (RawDeviceOK), to prevent // an unpriviledged user accessing our device. This function is avaliable // in a static WDMSEC.LIB and can be used in Win2k, XP, and Server 2003 // Just make sure that the GUID specified here is not a setup class GUID. // If you specify a setup class guid, you must make sure that class is // installed before enumerating the PDO. // status = IoCreateDeviceSecure(fdodata->Self->DriverObject, sizeof (PDO_DEVICE_DATA), NULL, FILE_DEVICE_BUS_EXTENDER, FILE_AUTOGENERATED_DEVICE_NAME |FILE_DEVICE_SECURE_OPEN, FALSE, &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // read wdmsec.h for more info (LPCGUID)&GUID_SD_BUSENUM_PDO, &pdo); if (!NT_SUCCESS (status)) { return status; } pdodata = (PPDO_DEVICE_DATA) pdo->DeviceExtension; #define HARDWARE_IDS_TPL L"USB\\Vid_%04x&Pid_%04x&Rev_%04xZUSB\\Vid_%04x&Pid_%04xZ" len = sizeof(HARDWARE_IDS_TPL); pdodata->HardwareIDs = ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG); if (NULL == pdodata->HardwareIDs) { IoDeleteDevice(pdo); return STATUS_INSUFFICIENT_RESOURCES; } RtlStringCchPrintfW(pdodata->HardwareIDs, len/sizeof(wchar_t), HARDWARE_IDS_TPL, plugin->vendor, plugin->product, plugin->version, plugin->vendor, plugin->product); for(i=0;i<sizeof(HARDWARE_IDS_TPL);i++){ if('Z'==pdodata->HardwareIDs[i]) pdodata->HardwareIDs[i]=0; } #define COMPATIBLE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZ" #define COMPATIBLE_COMPOSITE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZUSB\\COMPOSITEZ" if(plugin->inum>1) len = sizeof(COMPATIBLE_COMPOSITE_IDS_TPL); else len = sizeof(COMPATIBLE_IDS_TPL); pdodata->compatible_ids = ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG); if (NULL == pdodata->compatible_ids) { ExFreePool(pdodata->HardwareIDs); IoDeleteDevice(pdo); return STATUS_INSUFFICIENT_RESOURCES; } RtlZeroMemory(pdodata->compatible_ids, len); pdodata->compatible_ids_len = len; RtlStringCchPrintfW(pdodata->compatible_ids, len/sizeof(wchar_t), (plugin->inum>1)?COMPATIBLE_COMPOSITE_IDS_TPL:COMPATIBLE_IDS_TPL, plugin->int0_class, plugin->int0_subclass, plugin->int0_protocol, plugin->int0_class, plugin->int0_subclass, plugin->int0_class); for(i=0;i<len;i++){ if('Z'==pdodata->compatible_ids[i]) pdodata->compatible_ids[i]=0; } old_pdodata = (PPDO_DEVICE_DATA) InterlockedCompareExchangePointer(&(fo->FsContext), pdodata, 0); if(old_pdodata){ KdPrint(("you can't plugin again")); ExFreePool(pdodata->HardwareIDs); ExFreePool(pdodata->compatible_ids); IoDeleteDevice(pdo); return STATUS_INVALID_PARAMETER; } pdodata->SerialNo = plugin->addr; pdodata->fo = fo; pdodata->devid = plugin->devid; pdodata->speed = plugin->speed; bus_init_pdo (pdo, fdodata); // // Device Relation changes if a new pdo is created. So let // the PNP system now about that. This forces it to send bunch of pnp // queries and cause the function driver to be loaded. // IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations); return status; }
NTSTATUS USBPcapCreateRootHubControlDevice(IN PDEVICE_EXTENSION hubExt, OUT PDEVICE_OBJECT *control, OUT USHORT *busId) { UNICODE_STRING ntDeviceName; UNICODE_STRING symbolicLinkName; PDEVICE_OBJECT controlDevice = NULL; PDEVICE_EXTENSION controlExt = NULL; NTSTATUS status; USHORT id; PWCHAR ntNameBuffer[MAX_NTNAME_LEN]; PWCHAR symbolicNameBuffer[MAX_SYMBOLIC_LEN]; ASSERT(hubExt->deviceMagic == USBPCAP_MAGIC_ROOTHUB); /* Acquire the control device ID */ id = (USHORT) InterlockedIncrement(&g_controlId); ntDeviceName.Length = 0; ntDeviceName.MaximumLength = MAX_NTNAME_LEN; ntDeviceName.Buffer = (PWSTR)ntNameBuffer; symbolicLinkName.Length = 0; symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN; symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer; status = RtlUnicodeStringPrintf(&ntDeviceName, NTNAME_PREFIX L"%hu", id); if (!NT_SUCCESS(status)) { return status; } status = RtlUnicodeStringPrintf(&symbolicLinkName, SYMBOLIC_PREFIX L"%hu", id); if (!NT_SUCCESS(status)) { return status; } KdPrint(("Creating device %wZ (%wZ)\n", &ntDeviceName, &symbolicLinkName)); status = IoCreateDeviceSecure(hubExt->pDrvObj, sizeof(DEVICE_EXTENSION), &ntDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, TRUE, /* Exclusive device */ &SDDL_DEVOBJ_SYS_ALL_ADM_ALL_EVERYONE_ANY, NULL, &controlDevice); if (NT_SUCCESS(status)) { controlDevice->Flags |= DO_DIRECT_IO; status = IoCreateSymbolicLink(&symbolicLinkName, &ntDeviceName); if (!NT_SUCCESS(status)) { IoDeleteDevice(controlDevice); KdPrint(("IoCreateSymbolicLink failed %x\n", status)); return status; } controlExt = (PDEVICE_EXTENSION)controlDevice->DeviceExtension; controlExt->deviceMagic = USBPCAP_MAGIC_CONTROL; controlExt->pThisDevObj = controlDevice; controlExt->pNextDevObj = NULL; controlExt->pDrvObj = hubExt->pDrvObj; IoInitializeRemoveLock(&controlExt->removeLock, 0, 0, 0); controlExt->parentRemoveLock = &hubExt->removeLock; /* Initialize USBPcap control context */ controlExt->context.control.id = id; controlExt->context.control.pRootHubObject = hubExt->pThisDevObj; KeInitializeSpinLock(&controlExt->context.control.csqSpinLock); InitializeListHead(&controlExt->context.control.lePendIrp); status = IoCsqInitialize(&controlExt->context.control.ioCsq, DkCsqInsertIrp, DkCsqRemoveIrp, DkCsqPeekNextIrp, DkCsqAcquireLock, DkCsqReleaseLock, DkCsqCompleteCanceledIrp); if (!NT_SUCCESS(status)) { DkDbgVal("Error initialize Cancel-safe queue!", status); goto End; } controlDevice->Flags &= ~DO_DEVICE_INITIALIZING; } else { KdPrint(("IoCreateDevice failed %x\n", status)); } End: if ((!NT_SUCCESS(status)) || (controlExt == NULL)) { if (controlDevice != NULL) { IoDeleteSymbolicLink(&symbolicLinkName); IoDeleteDevice(controlDevice); } } else { IoAcquireRemoveLock(controlExt->parentRemoveLock, NULL); *control = controlDevice; *busId = id; } return status; }
static NTSTATUS V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING deviceName; PDEVICE_OBJECT fdo = NULL; PXENV4V_EXTENSION pde = NULL; LONG val; BOOLEAN symlink = FALSE; LARGE_INTEGER seed; WCHAR *szSddl = NULL; UNICODE_STRING sddlString; CHAR *szFpath = NULL; TraceVerbose(("====> '%s'.\n", __FUNCTION__)); // We only allow one instance of this device type. If more than on pdo is created we need val = InterlockedCompareExchange(&g_deviceCreated, 1, 0); if (val != 0) { TraceWarning(("cannot instantiate more that one v4v device node.\n")); return STATUS_UNSUCCESSFUL; } do { // Create our device RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME); szSddl = g_win5Sddl; RtlInitUnicodeString(&sddlString, szSddl); status = IoCreateDeviceSecure(driverObject, sizeof(XENV4V_EXTENSION), &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &sddlString, (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT, &fdo); if (!NT_SUCCESS(status)) { TraceError(("failed to create device object - error: 0x%x\n", status)); fdo = NULL; break; } pde = (PXENV4V_EXTENSION)fdo->DeviceExtension; RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION)); RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME); RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText); // Create our symbolic link status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName); if (!NT_SUCCESS(status)) { TraceError(("failed to create symbolic - error: 0x%x\n", status)); break; } symlink = TRUE; // Get our xenstore path szFpath = xenbus_find_frontend(pdo); if (szFpath == NULL) { status = STATUS_NO_SUCH_DEVICE; TraceError(("failed to locate XenStore front end path\n")); break; } // Setup the extension pde->magic = XENV4V_MAGIC; pde->pdo = pdo; pde->fdo = fdo; IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0); pde->frontendPath = szFpath; szFpath = NULL; pde->state = XENV4V_DEV_STOPPED; // wait for start pde->lastPoState = PowerSystemWorking; pde->virqPort = null_EVTCHN_PORT(); KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo); KeInitializeSpinLock(&pde->virqLock); KeInitializeSpinLock(&pde->dpcLock); KeInitializeTimerEx(&pde->timer, NotificationTimer); KeInitializeDpc(&pde->timerDpc, V4vConnectTimerDpc, fdo); KeInitializeSpinLock(&pde->timerLock); pde->timerCounter = 0; InitializeListHead(&pde->contextList); KeInitializeSpinLock(&pde->contextLock); pde->contextCount = 0; InitializeListHead(&pde->ringList); KeInitializeSpinLock(&pde->ringLock); InitializeListHead(&pde->pendingIrpQueue); pde->pendingIrpCount = 0; KeInitializeSpinLock(&pde->queueLock); IoCsqInitializeEx(&pde->csqObject, V4vCsqInsertIrpEx, V4vCsqRemoveIrp, V4vCsqPeekNextIrp, V4vCsqAcquireLock, V4vCsqReleaseLock, V4vCsqCompleteCanceledIrp); InitializeListHead(&pde->destList); pde->destCount = 0; ExInitializeNPagedLookasideList(&pde->destLookasideList, NULL, NULL, 0, sizeof(XENV4V_DESTINATION), XENV4V_TAG, 0); KeQueryTickCount(&seed); pde->seed = seed.u.LowPart; // Now attach us to the stack pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo); if (pde->ldo == NULL) { TraceError(("failed to attach device to stack - error: 0x%x\n", status)); status = STATUS_NO_SUCH_DEVICE; break; } // Use direct IO and let the IO manager directly map user buffers; clear the init flag fdo->Flags |= DO_DIRECT_IO; fdo->Flags &= ~DO_DEVICE_INITIALIZING; // Made it here, go to connected state to be consistent xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED); } while (FALSE); if (!NT_SUCCESS(status)) { if (fdo != NULL) { if ((pde != NULL)&&(pde->ldo != NULL)) { IoDetachDevice(pde->ldo); } if (szFpath != NULL) { XmFreeMemory(szFpath); } if (symlink) { IoDeleteSymbolicLink(&pde->symbolicLink); } IoDeleteDevice(fdo); } } TraceVerbose(("<==== '%s'.\n", __FUNCTION__)); return status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath) { NTSTATUS status = STATUS_SUCCESS; NTSTATUS symbolicLinkCreationStatus = STATUS_SUCCESS; UNICODE_STRING deviceName; UNICODE_STRING dosDeviceName; HANDLE threadHandle; NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParams = {0}; UNICODE_STRING defaultSDDLString; #ifdef DEBUG DbgBreakPoint(); #endif status = drvCtlInit(driverObject); if (!NT_SUCCESS(status)) { goto Exit; } gDriverUnloading = FALSE; RtlInitUnicodeString(&defaultSDDLString, L"D:P(A;;GA;;;BU)"); RtlInitUnicodeString(&deviceName, DEVICE_NAME); status = IoCreateDeviceSecure( driverObject, 0, &deviceName, FILE_DEVICE_NETWORK, 0, FALSE, &defaultSDDLString, NULL, &gDeviceObject); if (!NT_SUCCESS(status)) { goto Exit; } RtlInitUnicodeString(&dosDeviceName, SYMBOLIC_LINK_NAME); status = IoCreateSymbolicLink(&dosDeviceName, &deviceName); symbolicLinkCreationStatus = status; if (!NT_SUCCESS(status)) { goto Exit; } status = FwpsInjectionHandleCreate0( AF_UNSPEC, FWPS_INJECTION_TYPE_STREAM, &gInjectionHandle); if (!NT_SUCCESS(status)) { goto Exit; } gNdisGenericObj = NdisAllocateGenericObject( driverObject, TAG_NDIS_OBJ, 0); if (gNdisGenericObj == NULL) { status = STATUS_NO_MEMORY; goto Exit; } nblPoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; nblPoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParams.Header.Size = NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; nblPoolParams.fAllocateNetBuffer = TRUE; nblPoolParams.DataSize = 0; nblPoolParams.PoolTag = TAG_NBL_POOL; gNetBufferListPool = NdisAllocateNetBufferListPool( gNdisGenericObj, &nblPoolParams); if(gNetBufferListPool == NULL) { status = STATUS_NO_MEMORY; goto Exit; } InitializeListHead(&gPacketQueue); KeInitializeSpinLock(&gPacketQueueLock); InitializeListHead(&flowContextList); KeInitializeSpinLock(&flowContextListLock); KeInitializeEvent( &gWorkerEvent, NotificationEvent, FALSE ); status = RegisterCallouts(gDeviceObject); if (!NT_SUCCESS(status)) { goto Exit; } status = PsCreateSystemThread( &threadHandle, THREAD_ALL_ACCESS, NULL, NULL, NULL, thAnalyzer, NULL); if (!NT_SUCCESS(status)) { goto Exit; } status = ObReferenceObjectByHandle( threadHandle, 0, NULL, KernelMode, (PVOID*) &gThreadObj, NULL); ASSERT(NT_SUCCESS(status)); KeSetBasePriorityThread( (PKTHREAD) gThreadObj, -2); ZwClose(threadHandle); driverObject->DriverUnload = DriverUnload; Exit: if (!NT_SUCCESS(status)) { if (gFwpmEngineHandle != NULL) { UnregisterCallouts(); } if (gInjectionHandle != NULL) { FwpsInjectionHandleDestroy0(gInjectionHandle); } if (gDeviceObject) { IoDeleteDevice(gDeviceObject); } if(NT_SUCCESS(symbolicLinkCreationStatus)) { IoDeleteSymbolicLink(&dosDeviceName); } if (gNetBufferListPool != NULL) { NdisFreeNetBufferListPool(gNetBufferListPool); } if (gNdisGenericObj != NULL) { NdisFreeGenericObject(gNdisGenericObj); } } 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; }