NTSTATUS CreateDevice ( IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; UNICODE_STRING devName; RtlInitUnicodeString(&devName,DEVICE_NAME); UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName,DOS_NAME); status = IoCreateDevice( pDriverObject, sizeof(DEVICE_EXTENSION), &(UNICODE_STRING)devName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj ); if (!NT_SUCCESS(status)) { KdPrint( ("create device is error!\n") ); return status; } IoRegisterShutdownNotification(pDevObj); pDevObj->Flags |= DO_BUFFERED_IO; pDevObj->Flags &= (~DO_DEVICE_INITIALIZING);//wdm used pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj; pDevExt->ustrDeviceName = devName;// pDevExt->ustrSymLinkName = symLinkName;// status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( pDevObj ); KdPrint( ("create symbolicLink is error!\n") ); return status; } //fanzhenxing add InitBlackCache(); InitFilterCache(); return STATUS_SUCCESS; }
EXTERN_C static NTSTATUS LogpInitializeBufferInfo( _In_ const wchar_t *LogFilePath, _In_opt_ PDEVICE_OBJECT DeviceObject, _Inout_ LogBufferInfo *Info) { NT_ASSERT(LogFilePath); NT_ASSERT(Info); KeInitializeSpinLock(&Info->SpinLock); auto status = ExInitializeResourceLite(&Info->Resource); if (!NT_SUCCESS(status)) { return status; } Info->ResourceInitialized = true; if (DeviceObject) { // We can handle IRP_MJ_SHUTDOWN in order to flush buffered log entries. status = IoRegisterShutdownNotification(DeviceObject); if (!NT_SUCCESS(status)) { LogpFinalizeBufferInfo(DeviceObject, Info); return status; } } // Allocate two log buffers on NonPagedPool. Info->LogBuffer1 = reinterpret_cast<char *>(ExAllocatePoolWithTag( NonPagedPoolNx, LOGP_BUFFER_SIZE, LOGP_POOL_TAG_NAME)); if (!Info->LogBuffer1) { LogpFinalizeBufferInfo(DeviceObject, Info); return STATUS_INSUFFICIENT_RESOURCES; } Info->LogBuffer2 = reinterpret_cast<char *>(ExAllocatePoolWithTag( NonPagedPoolNx, LOGP_BUFFER_SIZE, LOGP_POOL_TAG_NAME)); if (!Info->LogBuffer2) { LogpFinalizeBufferInfo(DeviceObject, Info); return STATUS_INSUFFICIENT_RESOURCES; } // Initialize these buffers RtlFillMemory(Info->LogBuffer1, LOGP_BUFFER_SIZE, 0xff); // for debug Info->LogBuffer1[0] = '\0'; Info->LogBuffer1[LOGP_BUFFER_SIZE - 1] = '\0'; // at the end RtlFillMemory(Info->LogBuffer2, LOGP_BUFFER_SIZE, 0xff); // for debug Info->LogBuffer2[0] = '\0'; Info->LogBuffer2[LOGP_BUFFER_SIZE - 1] = '\0'; // at the end // Buffer should be used is LogBuffer1, and location should be written logs // is the head of the buffer. Info->LogBufferHead = Info->LogBuffer1; Info->LogBufferTail = Info->LogBuffer1; // Initialize a log file UNICODE_STRING logFilePathU = {}; RtlInitUnicodeString(&logFilePathU, LogFilePath); OBJECT_ATTRIBUTES oa = {}; InitializeObjectAttributes(&oa, &logFilePathU, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr, nullptr); IO_STATUS_BLOCK ioStatus = {}; status = ZwCreateFile( &Info->LogFileHandle, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &ioStatus, nullptr, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, nullptr, 0); if (!NT_SUCCESS(status)) { LogpFinalizeBufferInfo(DeviceObject, Info); return status; } // Initialize a log buffer flush thread. Info->BufferFlushThreadShouldBeAlive = true; status = PsCreateSystemThread(&Info->BufferFlushThreadHandle, GENERIC_ALL, nullptr, nullptr, nullptr, LogpBufferFlushThreadRoutine, Info); if (!NT_SUCCESS(status)) { LogpFinalizeBufferInfo(DeviceObject, Info); return status; } return status; }
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { HEADLESS_RSP_QUERY_INFO HeadlessInformation; ULONG InfoSize = sizeof(HeadlessInformation); NTSTATUS Status; UNICODE_STRING DriverName; PDEVICE_OBJECT DeviceObject; PSAC_DEVICE_EXTENSION DeviceExtension; PAGED_CODE(); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n"); /* Check if EMS is enabled in the kernel */ HeadlessDispatch(HeadlessCmdQueryInformation, NULL, 0, &HeadlessInformation, &InfoSize); if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) && ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) || (HeadlessInformation.Serial.TerminalAttached))) { /* It is, so create the device */ RtlInitUnicodeString(&DriverName, L"\\Device\\SAC"); Status = IoCreateDevice(DriverObject, sizeof(SAC_DEVICE_EXTENSION), &DriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject); if (NT_SUCCESS(Status)) { /* Setup the device extension */ DeviceExtension = DeviceObject->DeviceExtension; DeviceExtension->Initialized = FALSE; /* Initialize the driver object */ RtlFillMemoryUlong(DriverObject->MajorFunction, RTL_NUMBER_OF(DriverObject->MajorFunction), (ULONG_PTR)Dispatch); DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl; DriverObject->FastIoDispatch = NULL; DriverObject->DriverUnload = UnloadHandler; /* Initialize driver data */ if (InitializeGlobalData(RegistryPath, DriverObject)) { /* Initialize device data */ if (InitializeDeviceData(DeviceObject)) { /* We're all good, register a shutdown notification */ IoRegisterShutdownNotification(DeviceObject); return Status; } } /* One of the initializations failed, bail out */ Status = STATUS_INSUFFICIENT_RESOURCES; } else { /* Print a debug statement if enabled */ SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status); } /* Free any data we may have allocated and exit with failure */ FreeGlobalData(); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status); return Status; } /* EMS is not enabled */ return STATUS_PORT_DISCONNECTED; }
NTSTATUS SoundCardInstanceInit( IN PWSTR RegistryPathName, IN PVOID Context ) { /* ** Instance data */ PSOUND_CARD_INSTANCE CardInstance; // // Return code from last function called // NTSTATUS Status; // // Configuration data : // SB_CONFIG_DATA ConfigData; // // Where we keep all general driver information // We avoid using static data because : // 1. Accesses are slower with 32-bit offsets // 2. We support more than one card instance // PGLOBAL_DEVICE_INFO pGDI; // // The number of devices we actually create // int NumberOfDevicesCreated; // // The context is the global device info pointer from the previous // instance // CardInstance = Context; /******************************************************************** * * Allocate our global info * ********************************************************************/ pGDI = (PGLOBAL_DEVICE_INFO)ExAllocatePool( NonPagedPool, sizeof(GLOBAL_DEVICE_INFO)); if (pGDI == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } dprintf4((" DriverEntry(): GlobalInfo : %08lXH", pGDI)); RtlZeroMemory(pGDI, sizeof(GLOBAL_DEVICE_INFO)); pGDI->Key = GDI_KEY; pGDI->Hw.Key = HARDWARE_KEY; pGDI->RegistryPathName = RegistryPathName; pGDI->Usage = 0xFF; // Free pGDI->DriverObject = CardInstance->pDriverObject; // // Mutual exclusion : // // Everything is synchronized on the DeviceMutex (except for // some stuff inside the wave device) except // // Midi external output which takes too long and so is synchronized // separately but grabs the DeviceMutex every time it actually // writes anything and // // Synth output where the hardware is separate but callbacks to the // mixer must grab the DeviceMutex. // KeInitializeMutex(&pGDI->DeviceMutex, 2 // High level ); KeInitializeMutex(&pGDI->MidiMutex, 1 // Low level ); KeInitializeMutex(&pGDI->Hw.DSPMutex, 3 // Highest level ); /******************************************************************** * * Add ourselves to the ring of cards * ********************************************************************/ if (CardInstance->PrevGDI == NULL) { pGDI->Next = pGDI; } else { PGLOBAL_DEVICE_INFO pNext; pNext = CardInstance->PrevGDI->Next; CardInstance->PrevGDI->Next = pGDI; pGDI->Next = pNext; } CardInstance->PrevGDI = pGDI; /******************************************************************** * * See if we can find our bus. We run on both ISA and EISA * We ASSUME that if there's an ISA bus we're on that * ********************************************************************/ Status = SoundGetBusNumber(Isa, &pGDI->BusNumber); if (!NT_SUCCESS(Status)) { // // Cound not find an ISA bus so try EISA // Status = SoundGetBusNumber(Eisa, &pGDI->BusNumber); if (!NT_SUCCESS(Status)) { Status = SoundGetBusNumber(MicroChannel, &pGDI->BusNumber); if (!NT_SUCCESS(Status)) { dprintf1(("driver does not work on non-Isa/Eisa/Mca")); return Status; } pGDI->BusType = MicroChannel; } else { pGDI->BusType = Eisa; } } else { pGDI->BusType = Isa; } // // Set configuration to default in case we don't get all the // values back from the registry. // // Also set default volume for all devices // ConfigData.Port = SOUND_DEF_PORT; ConfigData.InterruptNumber = SOUND_DEF_INT; ConfigData.DmaChannel = SOUND_DEF_DMACHANNEL; ConfigData.DmaChannel16 = SOUND_DEF_DMACHANNEL16; ConfigData.DmaBufferSize = DEFAULT_DMA_BUFFERSIZE; ConfigData.MPU401Port = SOUND_DEF_MPU401_PORT; ConfigData.LoadType = SOUND_LOADTYPE_NORMAL; ConfigData.MixerSettingsFound = FALSE; // // Get the system configuration information for this driver. // // // Port, Interrupt, DMA channel, DMA 16-bit channel DMA buffer size // { RTL_QUERY_REGISTRY_TABLE Table[2]; RtlZeroMemory(Table, sizeof(Table)); Table[0].QueryRoutine = SoundReadConfiguration; Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, pGDI->RegistryPathName, Table, &ConfigData, NULL ); if (!NT_SUCCESS(Status)) { dprintf1(("ERROR: DriverEntry(): RtlQueryRegistryValues() Failed with Status = %XH", Status)); return Status; } // End IF (!NT_SUCCESS(Status)) } // End Query Resistry Values // // Save additional Config data // pGDI->InterruptNumber = ConfigData.InterruptNumber; pGDI->DmaChannel = ConfigData.DmaChannel; pGDI->DmaChannel16 = ConfigData.DmaChannel16; // // Verify the DMA Buffer Size // if ( ConfigData.DmaBufferSize < MIN_DMA_BUFFERSIZE ) { ConfigData.DmaBufferSize = MIN_DMA_BUFFERSIZE; dprintf1((" DriverEntry(): Adjusting the DMA Buffer size, size in Registry was too small")); } // // print out some info about the configuration // dprintf2((" DriverEntry(): Base I/O Port = %XH", ConfigData.Port)); dprintf2((" DriverEntry(): Interrupt = %u", ConfigData.InterruptNumber)); dprintf2((" DriverEntry(): DMA Channel = %u", ConfigData.DmaChannel)); dprintf2((" DriverEntry(): DMA Channel (16 bit) = %u", ConfigData.DmaChannel16)); dprintf2((" DriverEntry(): DMA Buffer Size = %XH", ConfigData.DmaBufferSize)); dprintf2((" DriverEntry(): MPU 401 port = %XH", ConfigData.MPU401Port)); /* ** Create our wave devices to ease reporting problems */ Status = SBCreateDevice(pGDI, WaveInDevice); if (!NT_SUCCESS(Status)) { return Status; } Status = SBCreateDevice(pGDI, WaveOutDevice); if (!NT_SUCCESS(Status)) { return Status; } /* ** Say we want to be called at shutdown time */ Status = IoRegisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]); if (!NT_SUCCESS(Status)) { return Status; } pGDI->ShutdownRegistered = TRUE; /* ** Check the configuration and acquire the resources */ Status = SoundInitHardwareConfig(pGDI, &ConfigData); if (!NT_SUCCESS(Status)) { dprintf1(("ERROR: DriverEntry(): SoundInitHardwareConfig() Failed with Status = %XH", Status)); return Status; } /* ** Initialize generic device environments - first get the ** hardware routines in place. ** We do this here after we've found out what hardware we've got */ HwInitialize(pGDI); SoundInitMidiIn(&pGDI->MidiInfo, &pGDI->Hw); /* ** Register most of our resources. Some may be registered on ** the wave output device : ** 16-bit dma channel ** ** We wipe out the registration of the MPU401 port when we do this ** but this is OK. */ { ULONG PortToReport; PortToReport = ConfigData.Port + MIX_ADDR_PORT; Status = SoundReportResourceUsage( pGDI->DeviceObject[WaveInDevice], // As good as any device to own // it pGDI->BusType, pGDI->BusNumber, &ConfigData.InterruptNumber, INTERRUPT_MODE, (BOOLEAN)(SB16(&pGDI->Hw) ? TRUE : FALSE), // Sharable for SB16 &ConfigData.DmaChannel, &PortToReport, NUMBER_OF_SOUND_PORTS - MIX_ADDR_PORT); } if (!NT_SUCCESS(Status)) { dprintf1(("Error - failed to claim resources - code %8X", Status)); pGDI->LoadStatus = SOUND_CONFIG_ERROR; return Status; } /* ** Now we know what device we've got we can create the appropriate ** devices */ /* ** Thuderboard has no external midi and we're going to ** drive the SB16 in MPU401 mode if we can */ if (!pGDI->Hw.ThunderBoard) { // // Don't create the MPU401 device if it is disabled // if (!SB16(&pGDI->Hw) || (ULONG)-1 != ConfigData.MPU401Port) { Status = SBCreateDevice(pGDI, MidiOutDevice); if (!NT_SUCCESS(Status)) { return Status; } Status = SBCreateDevice(pGDI, MidiInDevice); if (!NT_SUCCESS(Status)) { return Status; } } } /* ** Create volume control stuff for those devices which have it */ if (SBPRO(&pGDI->Hw) || SB16(&pGDI->Hw) #ifdef SB_CD || pGDI->Hw.SBCDBase != NULL #endif // SB_CD ) { Status = SBCreateDevice(pGDI, LineInDevice); if (!NT_SUCCESS(Status)) { return Status; } Status = SBCreateDevice(pGDI, CDInternal); if (!NT_SUCCESS(Status)) { return Status; } Status = SBCreateDevice(pGDI, MixerDevice); if (!NT_SUCCESS(Status)) { return Status; } } else { /* Volume setting not supported for our wave device */ ((PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension)->CreationFlags |= SOUND_CREATION_NO_VOLUME; } /* ** Init the WaveInfo structure */ SoundInitializeWaveInfo(&pGDI->WaveInfo, (UCHAR)(SB1(&pGDI->Hw) ? SoundReprogramOnInterruptDMA : SoundAutoInitDMA), SoundQueryFormat, &pGDI->Hw); if (ConfigData.SynthType == SOUND_SYNTH_TYPE_NONE) { /* ** This will happen if the user selected a basic config without ** a synthesizer. */ dprintf2(("No synth!")); } else { Status = SynthInit(CardInstance->pDriverObject, pGDI->RegistryPathName, &pGDI->Synth, SB16(&pGDI->Hw) || SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0 ? ConfigData.Port : SYNTH_PORT, FALSE, // Interrupt not enabled pGDI->BusType, pGDI->BusNumber, NULL, SOUND_MIXER_INVALID_CONTROL_ID,// Set volume later TRUE, // Allow multiple SoundMidiOutGetSynthCaps ); if (!NT_SUCCESS(Status)) { /* ** OK - we can get along without a synth */ dprintf2(("No synth!")); } else { if (!pGDI->Synth.IsOpl3) { dprintf2(("Synth is Adlib")); } else { /* ** Bad aliasing in early sound blasters means we can ** guess wrong. */ if (!(SB16(&pGDI->Hw) || SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0)) { pGDI->Synth.IsOpl3 = FALSE; } dprintf2(("Synth is Opl3")); } } } /* ** Set the mixer up. ** ** Note that the mixer info depends on what hardware is present ** so this must be called after we have checked out the hardware. */ if (pGDI->DeviceObject[MixerDevice]) { Status = SoundMixerInit(pGDI->DeviceObject[MixerDevice]->DeviceExtension, &ConfigData.MixerSettings, ConfigData.MixerSettingsFound); if (!NT_SUCCESS(Status)) { return Status; } } /* ** Save new settings */ Status = SoundSaveConfig(pGDI->RegistryPathName, ConfigData.Port, ConfigData.DmaChannel, ConfigData.DmaChannel16, ConfigData.InterruptNumber, ConfigData.MPU401Port, (BOOLEAN)(pGDI->Synth.DeviceObject != NULL), pGDI->Synth.IsOpl3, pGDI->WaveInfo.DMABuf.BufferSize); if (!NT_SUCCESS(Status)) { return Status; } /* ** Finally test the PRO interrupt */ if (SBPRO(&pGDI->Hw)) { BOOLEAN Ok; SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension, TRUE); Ok = 0 == SoundTestWaveDevice(pGDI->DeviceObject[WaveOutDevice]); SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension, FALSE); if (!Ok) { pGDI->LoadStatus = SOUND_CONFIG_BADDMA; return STATUS_DEVICE_CONFIGURATION_ERROR; } } /* ** Exit OK Message */ pGDI->LoadStatus = SOUND_CONFIG_OK; return STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////////////////////// // DriverEntry // Installable driver initialization entry point. // This entry point is called directly by the I/O system. // // Arguments: // IN DriverObject // pointer to the driver object // // IN RegistryPath // pointer to a unicode string representing the path, // to driver-specific key in the registry. // // Return Value: // Status // NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status; PDEVICE_OBJECT deviceObject; PTESTDRV_DEVICE_EXTENSION deviceExtension; UNICODE_STRING ntName; UNICODE_STRING win32Name; testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++"); testdrvDebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__); #ifdef DBG // DbgBreakPoint(); #endif #ifdef TESTDRV_WMI_TRACE WPP_INIT_TRACING(DriverObject, RegistryPath); #endif RtlZeroMemory(&g_Data, sizeof(TESTDRV_DATA)); // save registry path g_Data.RegistryPath.Length = RegistryPath->Length; g_Data.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); g_Data.RegistryPath.Buffer = (PWCHAR)ExAllocatePoolWithTag( PagedPool, g_Data.RegistryPath.MaximumLength, TESTDRV_POOL_TAG ); if (g_Data.RegistryPath.Buffer == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__": Failed to allocate memory for RegistryPath"); return status; } RtlCopyUnicodeString(&g_Data.RegistryPath, RegistryPath); // setup our dispatch function table in the driver object DriverObject->MajorFunction[IRP_MJ_CREATE] = testdrvCreateDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = testdrvCloseDispatch; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = testdrvDeviceIoControlDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = testdrvReadDispatch; DriverObject->MajorFunction[IRP_MJ_WRITE] = testdrvWriteDispatch; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = testdrvCleanupDispatch; DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = testdrvShutdownDispatch; DriverObject->DriverUnload = testdrvUnload; // initialize device name RtlInitUnicodeString(&ntName, L"\\Device\\testdrvDevice"); ExInitializeFastMutex(&qemu_output_lock); // Create our function device object. status = IoCreateDevice( DriverObject, sizeof (TESTDRV_DEVICE_EXTENSION), &ntName, FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject ); if (!NT_SUCCESS (status)) { ExFreePool(g_Data.RegistryPath.Buffer); g_Data.RegistryPath.Buffer = NULL; testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. STATUS %x", status); return status; } // Initialize the device extension. deviceExtension = (PTESTDRV_DEVICE_EXTENSION)deviceObject->DeviceExtension; // Zero the memory RtlZeroMemory(deviceExtension, sizeof(TESTDRV_DEVICE_EXTENSION)); // save our device object pointer deviceExtension->DeviceObject = deviceObject; // This flag sets the buffering method for reads and writes // to METHOD_DIRECT. IOCTLs are handled by IO control codes // independent of the value of this flag. deviceObject->Flags |= DO_DIRECT_IO; RtlInitUnicodeString(&win32Name, L"\\??\\testdrvDevice"); status = IoCreateSymbolicLink(&win32Name, &ntName); if (!NT_SUCCESS(status)) { IoDeleteDevice(deviceObject); ExFreePool(g_Data.RegistryPath.Buffer); g_Data.RegistryPath.Buffer = NULL; return status; } IoRegisterShutdownNotification(deviceObject); InitializeListHead(&ModuleListHead); g_WorkItem = IoAllocateWorkItem(deviceObject); if(!g_WorkItem) return STATUS_INSUFFICIENT_RESOURCES; IoQueueWorkItem(g_WorkItem, GetSysModInfo, DelayedWorkQueue, g_WorkItem); //UpdateSysModuleList(); PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine); PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE); testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); return status; }
CPGPdiskInterface::CPGPdiskInterface(CPGPdiskDriver *pDriver) : KDevice(L"PGPdisk", FILE_DEVICE_UNKNOWN, L"PGPdisk", 0, DO_DIRECT_IO) { NTSTATUS status; pgpAssertAddrValid(pDriver, CPGPdiskDriver); mSecondsInactive = 0; mPGPdiskDriver = pDriver; mTimerStarted = FALSE; mUnmountAllMode = FALSE; mAutoUnmount = kDefaultAutoUnmount; mUnmountTimeout = kDefaultUnmountTimeout; mKeyboardFilter = NULL; mMouseFilter = NULL; mCreatedKeyboardFilter = FALSE; mCreatedMouseFilter = FALSE; if (!NT_SUCCESS(m_ConstructorStatus)) { mInitErr = DualErr(kPGDMinorError_DeviceConstructFailed, m_ConstructorStatus); } if (mInitErr.IsntError()) { mInitErr = mUserMemManager.mInitErr; } // Setup our system hooks. if (mInitErr.IsntError()) { mInitErr = SetupSystemHooks(); } // Start our one-second timer. if (mInitErr.IsntError()) { status = IoInitializeTimer(m_pDeviceObject, EverySecondCallback, NULL); if (!NT_SUCCESS(status)) { mInitErr = DualErr(kPGDMinorError_IoInitializeTimerFailed, status); } } if (mInitErr.IsntError()) { IoRegisterShutdownNotification(m_pDeviceObject); IoStartTimer(m_pDeviceObject); mTimerStarted = TRUE; } }
// // Typically called by a driver's AddDevice function, which is set when // calling PcInitializeAdapterDriver. This performs some common driver // operations, such as creating a device extension. // // The StartDevice parameter is a driver-supplied function which gets // called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE. // NTSTATUS NTAPI PcAddAdapterDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PCPFNSTARTDEVICE StartDevice, IN ULONG MaxObjects, IN ULONG DeviceExtensionSize) { NTSTATUS status = STATUS_UNSUCCESSFUL; PDEVICE_OBJECT fdo; PDEVICE_OBJECT PrevDeviceObject; PPCLASS_DEVICE_EXTENSION portcls_ext = NULL; DPRINT("PcAddAdapterDevice called\n"); PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); if (!DriverObject || !PhysicalDeviceObject || !StartDevice) { return STATUS_INVALID_PARAMETER; } // check if the DeviceExtensionSize is provided if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE ) { // driver does not need a device extension if ( DeviceExtensionSize != 0 ) { // DeviceExtensionSize must be zero return STATUS_INVALID_PARAMETER; } // set size to our extension size DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE; } // create the device status = IoCreateDevice(DriverObject, DeviceExtensionSize, NULL, FILE_DEVICE_KS, FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN, FALSE, &fdo); if (!NT_SUCCESS(status)) { DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status); return status; } // Obtain the new device extension portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension; // initialize the device extension RtlZeroMemory(portcls_ext, DeviceExtensionSize); // allocate create item portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); if (!portcls_ext->CreateItems) { // not enough resources status = STATUS_INSUFFICIENT_RESOURCES; goto cleanup; } // store max subdevice count portcls_ext->MaxSubDevices = MaxObjects; // store the physical device object portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject; // set up the start device function portcls_ext->StartDevice = StartDevice; // initialize timer lock KeInitializeSpinLock(&portcls_ext->TimerListLock); // initialize timer list InitializeListHead(&portcls_ext->TimerList); // initialize io timer IoInitializeTimer(fdo, PcIoTimerRoutine, NULL); // start the io timer IoStartTimer(fdo); // set io flags fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; // clear initializing flag fdo->Flags &= ~ DO_DEVICE_INITIALIZING; // allocate the device header status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems); // did we succeed if (!NT_SUCCESS(status)) { goto cleanup; } // attach device to device stack PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject); // did we succeed if (PrevDeviceObject) { // store the device object in the device header //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject); portcls_ext->PrevDeviceObject = PrevDeviceObject; } else { // return error code status = STATUS_UNSUCCESSFUL; goto cleanup; } // register shutdown notification IoRegisterShutdownNotification(PhysicalDeviceObject); return status; cleanup: if (portcls_ext->KsDeviceHeader) { // free the device header KsFreeDeviceHeader(portcls_ext->KsDeviceHeader); } if (portcls_ext->CreateItems) { // free previously allocated create items FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS); } // delete created fdo IoDeleteDevice(fdo); 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; }