VOID SoundUnload( IN OUT PDRIVER_OBJECT pDriverObject ) /*++ Routine Description: Arguments: pGDI - Pointer to global data Return Value: NONE --*/ { PGLOBAL_DEVICE_INFO pGDI; PGLOBAL_DEVICE_INFO pGDIFirst; // // Find our global data - // HACK HACK !!! we may the synth stuff // pGDI = ((PLOCAL_DEVICE_INFO)pDriverObject->DeviceObject->DeviceExtension) ->pGlobalInfo; if (pGDI->Key == SYNTH_KEY) { pGDI = CONTAINING_RECORD((PGLOBAL_SYNTH_INFO)pGDI, GLOBAL_DEVICE_INFO, Synth); } pGDIFirst = pGDI; // // Write out volume settings // do { if (pGDI->DeviceObject[MixerDevice]) { SoundSaveMixerSettings(pGDI); } pGDI = pGDI->Next; } while (pGDI != pGDIFirst); // // Assume all handles (and therefore interrupts etc) are closed down // // // Delete the things we allocated - devices, Interrupt objects, // adapter objects. The driver object has a chain of devices // across it. // SoundCleanup(pGDI); }
void SystemCleanup (void) { SoundCleanup(); InputCleanup(); VideoCleanup(); DirCleanup(); TimerCleanup(); //LuaClose(); }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPathName ) /*++ DriverEntry() Routine Description: This routine performs initialization for the sound blaster device driver when it is first loaded Arguments: pDriverObject - Pointer to a driver object. RegistryPathName - the path to our driver services node Return Value: The function value is the final status from the initialization operation. --*/ { SOUND_CARD_INSTANCE CardInstance; NTSTATUS Status; PGLOBAL_DEVICE_INFO pGDI; /******************************************************************** * * Initialize debugging * ********************************************************************/ #if DBG DriverName = "SNDBLST"; #endif #if DBG if (SoundDebugLevel >= 4) { DbgBreakPoint(); } #endif /******************************************************************** * * Initialize each card in turn * ********************************************************************/ CardInstance.PrevGDI = NULL; CardInstance.pDriverObject = pDriverObject; /* ** Initialize the driver object dispatch table. */ pDriverObject->DriverUnload = SoundUnload; pDriverObject->MajorFunction[IRP_MJ_CREATE] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_CLOSE] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_READ] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_WRITE] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_CLEANUP] = SoundDispatch; pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = SoundShutdown; Status = SoundEnumSubkeys(RegistryPathName, PARMS_SUBKEY, SoundCardInstanceInit, (PVOID)&CardInstance); /* ** Save the return statuses */ if (CardInstance.PrevGDI) { pGDI = CardInstance.PrevGDI; for (;;) { // // Save the Driver load status in the registry for the // User-mode DLL to pick up // SoundWriteRegistryDWORD( pGDI->RegistryPathName, SOUND_REG_CONFIGERROR, pGDI->LoadStatus); pGDI = pGDI->Next; if (pGDI == CardInstance.PrevGDI) { break; } } } /* ** If this failed then free everything */ if (!NT_SUCCESS(Status)) { if (CardInstance.PrevGDI) { SoundCleanup(CardInstance.PrevGDI); /* ** Log a meaningful error for the one that failed! */ } return Status; } return STATUS_SUCCESS; }