⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 init.c

📁 driver wdk
💻 C
📖 第 1 页 / 共 4 页
字号:
//++
// File Name:
//		init.c
//
// Contents:
//		Driver initialization code
//--

//
// Driver-specific header files...
//
#include "version.h"
#include "ave2k.h"
#include "ave2kif.h"
#include "ave2kregs.h"
#include "AudioCtrl.h"
#include "DSP.h"
#include "Saa7111.h"
#include "ave2kutil.h"
#include "iic.h"
#include "channel2.h"
#include "debi.h"

VOID
Ave2kDpcForOSD(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
	);
VOID
Ave2kDpcForAudioReport(
    IN PKDPC Dpc,
    IN PVOID DeferredContext,
    IN PVOID SystemArgument1,
    IN PVOID SystemArgument2
	);

//Global variables shared by all devices
//DISPLAY_PARAMETER DisplayParameter;
ULONG VGAAddress;
KSPIN_LOCK  IsrSpinLock;
KIRQL  IsrSynchronizeIrql;
#if _WIN32_WINNT==0x0400
#define WIN_NT	1
#else
#define WIN_2K	1
#endif
#if _WIN32_WINNT==0x0500
USHORT BoardVersion;
long NtDeviceNumber=0;
#endif
//
// Forward declarations of local functions
//
static BOOLEAN InitializeData(PDEVICE_EXTENSION pDE);
void InitializeHardware(PDEVICE_EXTENSION pDE);

#if _WIN32_WINNT==0x0400
static NTSTATUS
Ave2kCreateDevice (
	IN PDRIVER_OBJECT DriverObject,
	PDEVICE_BLOCK DeviceBlock,
	IN ULONG NtDeviceNumber
	);
#else
void GetDeviceInfo(PDEVICE_OBJECT DeviceObject);//used to get the specified deive information;
PCHAR PnPMinorFunctionString (UCHAR MinorFunction);
//used to realease hardware resource,it is different from Ave2kPReleaseHardware,
//the later is used in nt device driver
VOID Ave2kPnPReleaseHardware(IN PDEVICE_EXTENSION pDevExt);
ULONG HexCharToInt(char *buf);
#endif

static BOOLEAN
Ave2kInitDevice(
	IN PVOID SynchContext
	);

//
// If the compiler can handle it, make the DriverEntry
// routine discardable, so that it doesn't waste space
//    
#ifdef ALLOC_PRAGMA

#pragma alloc_text( init, DriverEntry )

#if _WIN32_WINNT==0x0400
#pragma alloc_text( init, Ave2kCreateDevice )
#endif

#endif // ALLOC_PRAGMA

//++
// Function:
//		DriverEntry
//
// Description:
//		This function initializes the driver, locates
//		and claims hardware resources, and creates
//		various NT objects needed to process I/O
//		requests.
//
// Arguments:
//		Pointer to the Driver object
//		Registry path string for driver service key
//
// Return Value:
//		NTSTATUS signaling success or failure
//--
NTSTATUS
DriverEntry(
	IN PDRIVER_OBJECT DriverObject,
	IN PUNICODE_STRING RegistryPath
	)
{
	NTSTATUS status;
#if _WIN32_WINNT==0x0400
	PDEVICE_CONFIG ConfigList;
	ULONG NtDeviceNumber;
	ULONG i;

	//Allocate space for configuration
	ConfigList = ExAllocatePool(PagedPool,sizeof(*ConfigList));
	RtlZeroMemory(ConfigList, sizeof(*ConfigList));
	//KdPrint(("Config List=%d", sizeof(*ConfigList)));
	//KdPrint(("Device Config=%d", sizeof(DEVICE_CONFIG)));
	//KdPrint(("Decive Block=%d", sizeof(DEVICE_BLOCK)));
	//
	// Load up the Config list...
	//
	status = Ave2kGetHardwareInfo(
				DriverObject,
				RegistryPath,
				ConfigList );
	if( !NT_SUCCESS( status ))
	{
		ExFreePool(ConfigList);
		return status;
    }

	//Initialize variables used by IoConnectInterrupt
	KeInitializeSpinLock(&IsrSpinLock);

	//Get max. value of all found device
	IsrSynchronizeIrql =0;
	for(i=0;i<ConfigList->Count;i++){
		if(ConfigList->Device[i].Dirql > IsrSynchronizeIrql)
			IsrSynchronizeIrql = ConfigList->Device[i].Dirql;
	}

	//
	// Allocate the hardware...
	//
	status = Ave2kReportHardwareUsage(
				DriverObject,
				ConfigList );
	if( !NT_SUCCESS( status ))
	{
		ExFreePool(ConfigList);
		return status;
	}
#else
	HANDLE hDevice;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	UNICODE_STRING deviceName;
	WCHAR deviceNameBuffer[ AVE2K_MAX_NAME_LENGTH ];
	DebugPrintInit("AVE2K ");
	DebugPrintMsg("In the DriverEntry!");
	//Initialize variables used by IoConnectInterrupt
	KeInitializeSpinLock(&IsrSpinLock);

	deviceName.Buffer = deviceNameBuffer;
	deviceName.MaximumLength = AVE2K_MAX_NAME_LENGTH;
	deviceName.Length = 0;
   	RtlAppendUnicodeToString( 
		&deviceName,
   		L"\\DosDevices\\AVE2Kp1");

	InitializeObjectAttributes(
				&ObjectAttributes,
				&deviceName,
				0,
				NULL,
				NULL);
	if(ZwCreateFile(
				&hDevice,
				GENERIC_READ,
				&ObjectAttributes,
				&IoStatusBlock,
				0,
				FILE_ATTRIBUTE_NORMAL,
				FILE_SHARE_READ,
				FILE_OPEN,
				0,
				NULL,
				0
				)==STATUS_SUCCESS){
		ZwClose(hDevice);
	}
	else{
		//if not exist reset other card's counter
		ULONG nTotalOther=0;
		RtlWriteRegistryValue(
			RTL_REGISTRY_SERVICES,
			L"ave2kp\\",
			L"TotalCard",
			REG_DWORD,
			&nTotalOther,
			4);
#if TD_WIN98
		RtlWriteRegistryValue(
			RTL_REGISTRY_SERVICES,
			L"ave5kex\\Enum",
			L"Count",
			REG_DWORD,
			&nTotalOther,
			4);
#endif
	}

	Ave2kGetVGAHardwareInfo(); 
#endif
	//
	// Export other driver entry points...
	//
	DriverObject->DriverStartIo = Ave2kStartIo;
 	DriverObject->DriverUnload = Ave2kDriverUnload;
	
	DriverObject->MajorFunction[ IRP_MJ_CREATE ] =
		Ave2kDispatchOpenClose;
	DriverObject->MajorFunction[ IRP_MJ_CLOSE ] =
		Ave2kDispatchOpenClose;
	DriverObject->MajorFunction[ IRP_MJ_WRITE ] =
		Ave2kDispatchWrite;
	DriverObject->MajorFunction[ IRP_MJ_READ ] =
		Ave2kDispatchRead;
	DriverObject->MajorFunction[ IRP_MJ_CLEANUP ] =
		Ave2kDispatchCleanup;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
        Ave2kDispatchDeviceIoControl;
#if _WIN32_WINNT==0x0400
	//
	// Initialize a Device object for each piece
	// of hardware we've found
	//
	NtDeviceNumber = 0;

	for( i = 0;
		 i < ConfigList->Count;
		 i++ )
		{
   			status = Ave2kCreateDevice(
   						DriverObject,
						&(ConfigList->Device[i]),
						NtDeviceNumber );

   			if( !NT_SUCCESS( status )) break;
			NtDeviceNumber++;
		}

	if( !NT_SUCCESS( status ))
	{
		Ave2kReleaseHardware( DriverObject );
	}

	//Deallocate device configuration data
	ExFreePool( ConfigList );
	return status;
#else
    DriverObject->MajorFunction[IRP_MJ_PNP]            = Ave2kDispatchPnp;
    DriverObject->MajorFunction[IRP_MJ_POWER]          = Ave2kDispatchPower;
    DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Ave2kDispatchSystemControl;
    DriverObject->DriverExtension->AddDevice           = Ave2kAddDevice; 
	return STATUS_SUCCESS;
#endif
}

#if _WIN32_WINNT==0x0400
//++
// Function:
//		Ave2kCreateDevice
//
// Description:
//		This function creates and initializes a
//		single Device object, using a set of hardware
//		descriptions from the Config block.
//
// Arguments:
//		Pointer to the Driver object
//		Pointer to config data about the device
//		Number to associate with NT Device object
//
// Return Value:
//		NTSTATUS signaling success or failure
//--
static NTSTATUS
Ave2kCreateDevice (
	IN PDRIVER_OBJECT DriverObject,
	PDEVICE_BLOCK DeviceBlock,
	IN ULONG NtDeviceNumber
	)
{
	NTSTATUS status;
	
	PDEVICE_OBJECT pDevObj;
    PDEVICE_EXTENSION pDevExt;

	UNICODE_STRING deviceName;
	WCHAR deviceNameBuffer[ AVE2K_MAX_NAME_LENGTH ];
	
	UNICODE_STRING linkName;
	WCHAR linkNameBuffer[ AVE2K_MAX_NAME_LENGTH ];
	
	UNICODE_STRING	number;
	WCHAR numberBuffer[10];

	number.Buffer = numberBuffer;
	number.MaximumLength = 10;
	
	//
   	// Form the base NT device name...
   	//
	deviceName.Buffer = deviceNameBuffer;
	deviceName.MaximumLength = AVE2K_MAX_NAME_LENGTH;
	deviceName.Length = 0;
   	RtlAppendUnicodeToString( 
		&deviceName,
   		AVE2K_NT_DEVICE_NAME );

	//
	// Convert the device number into a string and
	// attach it to the end of the device name.
	//
	number.Length = 0;
	RtlIntegerToUnicodeString( 
		NtDeviceNumber, 
		10, 
		&number ); 
	RtlAppendUnicodeStringToString( 
		&deviceName,
		&number );

    //If NtDeviceNumber is 1, now deviceName is "\\Device\\Ave2k1"
    // Create a Device object for this device...
    //
	status = IoCreateDevice(
				DriverObject,
				sizeof( DEVICE_EXTENSION ),
				&deviceName,
				FILE_DEVICE_UNKNOWN,
				0,
				TRUE,       //exclusive
					&pDevObj );

	if( !NT_SUCCESS( status )) 
	{
		return status;
    }

#ifdef USING_DIRECT_IO
	pDevObj->Flags |= DO_DIRECT_IO;
#else
	pDevObj->Flags |= DO_BUFFERED_IO; 
#endif

	//
    // Initialize the Device Extension
    //
	pDevExt = pDevObj->DeviceExtension;
    pDevExt->DeviceObject = pDevObj;
	pDevExt->NtDeviceNumber = NtDeviceNumber;
	
	//
	// Copy things from Device Block
	//
	pDevExt->PortBase = (UCHAR *)DeviceBlock->PortBase;
	pDevExt->PortSpan = DeviceBlock->PortSpan;	
	pDevExt->BusNumber = DeviceBlock->BusNumber;
	pDevExt->SlotNumber = DeviceBlock->SlotNumber;
	pDevExt->BoardVersion = DeviceBlock->BoardVersion;
	
	InitializeHardware(pDevExt);


	//
   	// Form the Win32 symbolic link name.
   	//
	linkName.Buffer = linkNameBuffer;
	linkName.MaximumLength = AVE2K_MAX_NAME_LENGTH;
	linkName.Length = 0;
	RtlAppendUnicodeToString( 
		&linkName,
		AVE2K_WIN32_DEVICE_NAME );
	//
	// Reset the number string and do another
	// conversion. Win32 device numbers are
	// one greater than the NT equivalent.
	//
	number.Length = 0;
	RtlIntegerToUnicodeString( 
		NtDeviceNumber + 1,
		10,
		&number ); 
	RtlAppendUnicodeStringToString( 
		&linkName,
		&number );
	    
	//        
	// Create a symbolic link so our device is
	// visible to Win32...
	//
 	status = IoCreateSymbolicLink(
 				&linkName, 
				&deviceName );
    
	//
    // See if the symbolic link was created...
    //
	if( !NT_SUCCESS( status )) 
	{
    	IoDeleteDevice( pDevObj );
		return status;
    }

	//Init device data
    if(InitializeData(pDevExt)==FALSE)
		return STATUS_UNSUCCESSFUL;
	//
	// Make sure device interrupts are OFF
	//
	Ave2kDisableInterrupts( pDevExt );

	//
	// Connect to an Interrupt object...
	//
	status = 
		IoConnectInterrupt( 
 			&pDevExt->pInterrupt,
			Ave2kIsr,
			pDevExt,
			&IsrSpinLock,//NULL,
			DeviceBlock->SystemVector,
			DeviceBlock->Dirql,
			IsrSynchronizeIrql,//DeviceBlock->Dirql,
			DeviceBlock->InterruptMode,
			TRUE,       //ShareVector,
			DeviceBlock->Affinity,
			FALSE );
					    
	if( !NT_SUCCESS( status )) 
	{
		IoDeleteSymbolicLink( &linkName );
		IoDeleteDevice( pDevObj );
		return status;
	}

	//
	// Initialize the hardware and enable interrupts
	//
	//KeSynchronizeExecution(
	//	pDevExt->pInterrupt,
	//	Ave2kInitDevice,
	//	pDevExt ); deleted 02/08/22. 
	//Actually the function don't enable any interrupt, and here interrupt shoud be disabled by
	//preceding Ave2kDisableInterrupts.
	return status;
}
#endif

//
// Make sure device interrupts are OFF
//
BOOLEAN Ave2kDisableInterrupts(PDEVICE_EXTENSION pDevExt )
{
	//clear all interrupt enable bits
	pDevExt->IERValue =0L;
	Ave2kWriteRegister(pDevExt,IER,pDevExt->IERValue);
	return TRUE;
}

//Set Value of IER of SAA7146
BOOLEAN Ave2kSetInterrupts(PDEVICE_EXTENSION pDevExt)
{
	Ave2kWriteRegister(pDevExt,IER,pDevExt->IERValue);
	return TRUE;
}

//++
// Function:
//		Ave2kStartIo
//
// Description:
//		This function is responsible for doing any
//		function-code specific pre-processing and 
//		then starting the actual data transfer.
//
// Arguments:
//		Pointer to the Device object
//		Pointer to the IRP for this request
//
// Return Value:
//		(None)
//--
VOID
Ave2kStartIo(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
	)
{
	KIRQL  OldIrql;
	PDEVICE_EXTENSION pDE=(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

	PIO_STACK_LOCATION IrpStack;// =
	   //IoGetCurrentIrpStackLocation( Irp );

	//if(IrpStack->MajorFunction != IRP_MJ_READ)
	//	return;

	// Before starting the operation, see if the
	// Cancel routine has run between the time
	// the IRP was removed from the Device Queue
	// and now. Start by grabbing the Cancel spin
	// lock.
	//
	IoAcquireCancelSpinLock( &OldIrql );

	//
	// Check the state of the Cancel flag. If 
	// it's set, release the spin lock and return
	// immediately. The IRP has already been  
	// processed by the Cancel routine.
	//
	if( Irp->Cancel )
	{
		IoReleaseCancelSpinLock( OldIrql );
		return;
	}

	//
	// If the Cancel flag is clear, remove the
	// IRP from the cancelable state and start
	// processing it.
	//
	else
	{
		IoSetCancelRoutine( Irp, NULL);//Ave2kCancelIrp );
		IoReleaseCancelSpinLock( OldIrql );
	}
/*	KeAcquireSpinLock(&pDE->ReadLock, &OldIrql);
	IrpStack = IoGetCurrentIrpStackLocation( Irp );
	ASSERT(IrpStack!=NULL);

#ifdef USING_DIRECT_IO
	pDE->ReadIrpDataBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
#else
	pDE->ReadIrpDataBuffer = pIrp->AssociatedIrp.SystemBuffer;  //Using buffered I/O
#endif
	if(KeSynchronizeExecution(
		pDE->pInterrupt,
		SyncAudioRead,
		DeviceObject->DeviceExtension))
	{
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = IrpStack->Parameters.Read.Length //sizeof(AUDIOSTREAMSECTOR);
		IoStartNextPacket(DeviceObject,TRUE);
		IoCompleteRequest(Irp,IO_NO_INCREMENT);
		pDE->ReadIrpDataBuffer=NULL;
	}
	KeReleaseSpinLock(&pDE->ReadLock, OldIrql);
	ErrorRecover(pDE, 0);*/
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -