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

📄 iocontrol.c

📁 driver wdk
💻 C
📖 第 1 页 / 共 2 页
字号:
//++
// File Name:
//		IoControl.c
//
// Contents:
//		Dispatch routines for control code: IRP_MJ_DEVICE_CONTROL
//--

//
// Driver-specific header files
//
#include "version.h"
#include "Ave2k.h"
#include "Ave2kregs.h"
#include "Ave2kOverlay.h"
#include "ave2kutil.h"
#include "saa7111.h"
#include "iic.h"
#include "AudioCtrl.h"
#include "debi.h"

//External defined global variables shared by all devices
//extern DISPLAY_PARAMETER DisplayParameter;
extern ULONG VGAAddress;

static int CheckChannel(PDEVICE_EXTENSION pDE, ULONG Channel);
void InitializeHardware(PDEVICE_EXTENSION pDE);
//
// Forward declarations of local routines
//
// 
static NTSTATUS ave2kOverlayControl(PDEVICE_EXTENSION pDE);
//static BOOLEAN SetClipRect(PDEVICE_EXTENSION pDE,PAVE2KCLIPLIST pClipList);

//
// If the compiler can handle it, save space
// by making various routines pageable
//    
#ifdef ALLOC_PRAGMA
#pragma alloc_text( page, Ave2kDispatchDeviceIoControl )
#endif //ALLOC_PRAGMA

//++
// Function:
//		Ave2kDispatchDeviceIoControl
//
// Description:
//		This function dispatches DeviceIoControl
//       requests from Win32
//
// Arguments:
//		Pointer to Device object
//		Pointer to IRP for this request
//
// Return Value:
//		This function returns STATUS_XXX
//--
NTSTATUS
Ave2kDispatchDeviceIoControl(
	IN PDEVICE_OBJECT pDO,
	IN PIRP Irp
	)
{
	NTSTATUS status;
	ULONG RegIndex, RegValue;
	PIO_STACK_LOCATION IrpStack =
		IoGetCurrentIrpStackLocation( Irp );

	PDEVICE_EXTENSION pDE =
		(PDEVICE_EXTENSION)pDO->DeviceExtension;

	ULONG ControlCode = 
		IrpStack->Parameters.
			DeviceIoControl.IoControlCode;

	ULONG OutBufferSize = 
		IrpStack->Parameters.
			DeviceIoControl.OutputBufferLength;

	ULONG InBufferSize = 
		IrpStack->Parameters.
			DeviceIoControl.InputBufferLength;

//	PXX_PERF_DATA pBuffer =	
//			(PXX_PERF_DATA)Irp->
//				AssociatedIrp.SystemBuffer;
    int nVT;
	switch( ControlCode )
	{
#if(TARGET_DEVICE==TD_TEST)
	    case IOCTL_READ_REGISTER:
			if(OutBufferSize != sizeof(ULONG) || InBufferSize != sizeof(ULONG)){
		       status = STATUS_INVALID_PARAMETER;
		       break;
			}
		   RegIndex=*((ULONG *)Irp->AssociatedIrp.SystemBuffer);
		   RegValue = Ave2kReadRegister(pDE,RegIndex);
		   *((ULONG *)Irp->AssociatedIrp.SystemBuffer) = RegValue;
		   Irp->IoStatus.Information = sizeof(RegValue);
		   status = STATUS_SUCCESS;
           break; 

	    case IOCTL_WRITE_REGISTER:
			if(InBufferSize != 2*sizeof(ULONG) || OutBufferSize != 0){
		       status = STATUS_INVALID_PARAMETER;
		       break;
			}
		   RegIndex=*((ULONG *)Irp->AssociatedIrp.SystemBuffer);
		   RegValue = *((ULONG *)Irp->AssociatedIrp.SystemBuffer +1);
		   Ave2kWriteRegister(pDE,RegIndex,RegValue);
		   status = STATUS_SUCCESS;
           break; 
#endif
		case IOCTL_DISPLAY_PARAMETER:
			if(InBufferSize != sizeof(DISPLAY_PARAMETER) || OutBufferSize != 0){
		       status = STATUS_INVALID_PARAMETER;
		       break;
			}
			{	PHYSICAL_ADDRESS NewBaseAddress ;
				//ULONG CurrentBaseAddress = VGAAddress;
				pDE->DisplayParameter = *((DISPLAY_PARAMETER *)Irp->AssociatedIrp.SystemBuffer);
				if(pDE->DisplayParameter.VirtualAddress!=(ULONG)NULL){
					NewBaseAddress = MmGetPhysicalAddress((PVOID)pDE->DisplayParameter.VirtualAddress);
					pDE->DisplayParameter.PhysicalAddress = NewBaseAddress.LowPart;
				}
				else//recover original setting
					pDE->DisplayParameter.PhysicalAddress = VGAAddress;
			}
			Irp->IoStatus.Information=0;
			status=STATUS_SUCCESS;
			break;
	
		case IOCTL_OVERLAY_WINDOW:
			{
				POVERLAY_WINDOW pOverlayWindow=(OVERLAY_WINDOW *)Irp->AssociatedIrp.SystemBuffer;
				if(InBufferSize != sizeof(OVERLAY_WINDOW) || OutBufferSize != 0)
				{
				   status = STATUS_INVALID_PARAMETER;
				   break;
				}
#if 0
				KdPrint(("Card%d: Open=%d Pos=%d:%d - %d:%d Open2=%d Pos= %d:%d - %d:%d\n",
					pDE->NtDeviceNumber+1,
					pOverlayWindow->OpenClose,
					pOverlayWindow->Left,
					pOverlayWindow->Top,
					pOverlayWindow->Right,
					pOverlayWindow->Bottom,
					pOverlayWindow->OpenClose2,
					pOverlayWindow->Left2,
					pOverlayWindow->Top2,
					pOverlayWindow->Right2,
					pOverlayWindow->Bottom2));
#endif
				if(pOverlayWindow->OpenClose){
					if(pOverlayWindow->Left<0 ||
						pOverlayWindow->Top<0 ||
						pOverlayWindow->Right>pDE->DisplayParameter.Width ||
						pOverlayWindow->Bottom>pDE->DisplayParameter.Height)
					{
					   status = STATUS_INVALID_PARAMETER;
					   break;
					}
				}
				if(pDE->Double && pOverlayWindow->OpenClose2){
					if(	pOverlayWindow->Left2<0 ||
						pOverlayWindow->Top2<0 ||
						pOverlayWindow->Right2>pDE->DisplayParameter.Width ||
						pOverlayWindow->Bottom2>pDE->DisplayParameter.Height)
					{
					   status = STATUS_INVALID_PARAMETER;
					   break;
					}
				}
				if(!pDE->Double)
					pOverlayWindow->OpenClose2=0;
				pDE->OverlayWindow=*pOverlayWindow;
				status=ave2kOverlayControl(pDE);
			}
			break;
		case IOCTL_DATA_STREAM:
			{
//				ULONG IsEnable = *(PULONG)Irp->AssociatedIrp.SystemBuffer;
				//ULONG Test;
				PAVE2KDATA_STREAM_CTL pDataCtrl = 
					       (PAVE2KDATA_STREAM_CTL)Irp->AssociatedIrp.SystemBuffer;
				if(!pDE->Compress || 
					InBufferSize != sizeof(AVE2KDATA_STREAM_CTL) || !CheckChannel(pDE, pDataCtrl->Channel))
					{
					   status = STATUS_INVALID_PARAMETER;
					   break;
					}
				//Test=Ave2kReadRegister(pDE, GPIO_CTRL);
				//KdPrint(("GPIO=%x\n", Test));
				//added on 03-3-4 by wjq
				
				nVT=GetVideoType(pDE,(UCHAR)pDataCtrl->Channel);
				if(nVT==VIDEOTYPE_NONE)
					pDE->VideoType[(UCHAR)pDataCtrl->Channel]=pDE->nPreVideoType[(UCHAR)pDataCtrl->Channel];
				else
					pDE->VideoType[(UCHAR)pDataCtrl->Channel] =nVT;
				if(pDataCtrl->Enable)
				    EnableAudio(pDE, (UCHAR)pDataCtrl->Channel);
				else{
					SetCompressFrameRate(pDE, 1, 0);
					DisableAudio(pDE, pDataCtrl->Channel, TRUE);
				}
				status=STATUS_SUCCESS;	
			}
			break;

#if 0
		case IOCTL_FETCH_CACHE:
			{
				if(OutBufferSize != sizeof(AUDIOSTREAMSECTOR)){
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				pDE->CurrentIrp=Irp;
				if(KeSynchronizeExecution(pDE->pInterrupt,
					SyncAudioRead,
					pDE)){
					status = STATUS_SUCCESS;
					Irp->IoStatus.Information = InBufferSize/*sizeof(AUDIOSTREAMSECTOR)*/;
				}
				else{
					status = STATUS_UNSUCCESSFUL;
					Irp->IoStatus.Information = 0;
				}
			}
			break;
#endif
		case IOCTL_CLIPPING:
			{
				PAVE2KCLIPLIST pClipList;
				pClipList=(PAVE2KCLIPLIST)Irp->AssociatedIrp.SystemBuffer;
				if(InBufferSize !=sizeof(AVE2KCLIPLIST) ||
					pClipList->lNumOfRect > 16)
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				if(TRUE == SetClipRect(pDE,pClipList))
					status = STATUS_SUCCESS;
				else
					status = STATUS_UNSUCCESSFUL;
			}
			break;
		case IOCTL_VIDEO_DATARATE:
			{
				PAVE2KDATA_RATE pRate=(PAVE2KDATA_RATE)Irp->AssociatedIrp.SystemBuffer;
				ULONG DataRate=pRate->DataRate;
				if(!pDE->Compress || 
					InBufferSize!=sizeof(AVE2KDATA_RATE) || !CheckChannel(pDE, pRate->Channel) ||
					DataRate  > 1151600 || DataRate < 19200)
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				//it's NOT supported when data is being processed
				if(TRUE == pDE->DataReceiving[pRate->Channel]){
					status = STATUS_UNSUCCESSFUL;
					break;
				}
				pDE->VideoDataRate[pRate->Channel] =(USHORT)(DataRate/400);
				status = STATUS_SUCCESS;
			}
			break;
        case IOCTL_AUDIO_DATARATE:
			{
				PAVE2KDATA_RATE pRate=(PAVE2KDATA_RATE)Irp->AssociatedIrp.SystemBuffer;
				ULONG DataRate=pRate->DataRate;
				if(!pDE->Compress || 
					InBufferSize!=sizeof(AVE2KDATA_RATE) || !CheckChannel(pDE, pRate->Channel) ||
					DataRate  > ARATE_384 ||
					DataRate < ARATE_32)
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				//it's NOT supported when data is being processed
				if(TRUE == pDE->DataReceiving[pRate->Channel]){
					status = STATUS_UNSUCCESSFUL;
					break;
				}
				pDE->AudioDataRate[pRate->Channel] = (USHORT)DataRate;
				status = STATUS_SUCCESS;
			}
			break;
		case IOCTL_VIDEO_PARAMETER:
			{
				PAVE2K_VIDEO_PARAMETER pPara;
				ULONG nChannel;
				pPara=(PAVE2K_VIDEO_PARAMETER)Irp->AssociatedIrp.SystemBuffer;
				if(InBufferSize!=sizeof(AVE2K_VIDEO_PARAMETER) &&
					InBufferSize!=sizeof(ULONG))
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				if(InBufferSize==sizeof(AVE2K_VIDEO_PARAMETER))
				{
					if(!CheckChannel(pDE, pPara->Channel)){
						status = STATUS_INVALID_PARAMETER;
						break;
					}
					else{
						//set parameter
						SetVideoParameter(pDE, pPara, pPara->Channel);
						status = STATUS_SUCCESS;
					}
				}
				else{
					nChannel=*(PULONG)Irp->AssociatedIrp.SystemBuffer;
					if(OutBufferSize != sizeof(AVE2K_VIDEO_PARAMETER) || !CheckChannel(pDE, nChannel))
					{
						status = STATUS_INVALID_PARAMETER;
					    break;
					}
					//get parameter
					GetVideoParameter(pDE, pPara, nChannel);
					Irp->IoStatus.Information = sizeof(AVE2K_VIDEO_PARAMETER);
					status = STATUS_SUCCESS;
				}
			}
			break;
		case IOCTL_STREAM_TYPE:
			{
				PAVE2K_STREAM_TYPE pType;
				if(!pDE->Compress || 
					(InBufferSize!=sizeof(AVE2K_STREAM_TYPE) &&
					OutBufferSize != sizeof(AVE2K_STREAM_TYPE)))
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				pType=((PAVE2K_STREAM_TYPE)Irp->AssociatedIrp.SystemBuffer);
				if(!CheckChannel(pDE, pType->Channel))
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				if(InBufferSize ==sizeof(AVE2K_STREAM_TYPE))
				{
					//set parameter
					pDE->DataFilter[pType->Channel] = pType->Stream;
					status = STATUS_SUCCESS;
				}
				else{
					//get parameter
					pType->Stream = pDE->DataFilter[pType->Channel];
					Irp->IoStatus.Information = sizeof(AVE2K_STREAM_TYPE);
					status = STATUS_SUCCESS;
				}
				break;
			}
		case IOCTL_VIDEO_FORMAT:
		{
			ULONG Format;
			ULONG Channel = *(PULONG)(Irp->AssociatedIrp.SystemBuffer);
			if((InBufferSize != sizeof(ULONG) && OutBufferSize != sizeof(ULONG)) || !CheckChannel(pDE, Channel))
			{
				status = STATUS_INVALID_PARAMETER;
				break;
			}
			//pDE->VideoType[Channel] = GetVideoType(pDE, Channel);	
			nVT=GetVideoType(pDE, Channel);	
			switch(nVT){//pDE->VideoType[Channel]){
			case VIDEOTYPE_NONE:
				Format=AVE2K_VIDEO_FORMAT_NONE;
				pDE->VideoType[Channel]=pDE->nPreVideoType[Channel];
				break;
			case VIDEOTYPE_PAL:
				Format=AVE2K_VIDEO_FORMAT_PAL;
				pDE->VideoType[Channel]=VIDEOTYPE_PAL;
				break;
			case VIDEOTYPE_NTSC:
				Format=AVE2K_VIDEO_FORMAT_NTSC;
				pDE->VideoType[Channel]=VIDEOTYPE_NTSC;
				break;
			}
			*(PULONG)(Irp->AssociatedIrp.SystemBuffer)=Format;
			Irp->IoStatus.Information = sizeof(ULONG);
			status = STATUS_SUCCESS;
			break;
		}
        case IOCTL_VIDEO_SOURCE:
			{
				PAVE2K_VIDEO_SOURCE pSource=(PAVE2K_VIDEO_SOURCE)Irp->AssociatedIrp.SystemBuffer;
				ULONG VideoSource=pSource->Source;
				if(! pDE->VideoSourceSelect){
					status = STATUS_NOT_IMPLEMENTED; 
					Irp->IoStatus.Information = 0;
					break;
				}
				if(InBufferSize!=sizeof(AVE2K_VIDEO_SOURCE) || !CheckChannel(pDE, pSource->Channel))
				{
					status = STATUS_INVALID_PARAMETER;
					break;
				}
				if(VideoSource==AVE2K_VIDEO_SRC_CVBS)
					SetVideoSource(pDE, VIDEOSOURCE_CVBS, pSource->Channel);
				else
					if(VideoSource==AVE2K_VIDEO_SRC_SVIDEO)
					SetVideoSource(pDE, VIDEOSOURCE_SVIDEO, pSource->Channel);
					else{
						status = STATUS_INVALID_PARAMETER;
						break;
					}
				status = STATUS_SUCCESS;
				break;
			}
		case IOCTL_BOARD_INFO:
			{
				PAVE2K_BOARD_INFO pInfo;
				if(OutBufferSize != sizeof(AVE2K_BOARD_INFO))
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				pInfo=(PAVE2K_BOARD_INFO)Irp->AssociatedIrp.SystemBuffer;
				pInfo->SerialsNo = pDE->SerialsNo;
				pInfo->Reserved = (pDE->BusNumber<<12)|(pDE->SlotNumber<<4)|(pDE->BoardVersion);
				if(pDE->Compress)
					pInfo->Reserved |= 0x80000000;
				if(pDE->ExtraFunctions)
					pInfo->Reserved |= 0x40000000;
				if(pDE->ExtraFunctions&0x02)
					pInfo->Reserved |= 0x20000000;
				pInfo->Double = pDE->Double;
				pInfo->VideoSourceSelect = pDE->VideoSourceSelect;
				if(pDE->VolumeControl != VOL_NONE){
					if(pDE->VolumeControl == VOL_ANASWTCH)
						pInfo->VolumeAbility= 3;
					else
						pInfo->VolumeAbility= 1;
				}
				else
					pInfo->VolumeAbility= 0;
				Irp->IoStatus.Information = sizeof(AVE2K_BOARD_INFO);
				status = STATUS_SUCCESS;
			break;
			}
		case IOCTL_VOLUME:
			{
				PAVE2K_VOLUME pVolume=(PAVE2K_VOLUME)(Irp->AssociatedIrp.SystemBuffer);
				PAVE2K_VOLUME_V pVolume_V=(PAVE2K_VOLUME_V)(Irp->AssociatedIrp.SystemBuffer);
				ULONG Volume=pVolume->Volume;//same position for both VOLUME and VOLUME_V
				if(pDE->VolumeControl == VOL_NONE){
					status = STATUS_NOT_IMPLEMENTED; 
					Irp->IoStatus.Information = 0;
					break;
				}
				if((InBufferSize != sizeof(AVE2K_VOLUME) &&InBufferSize != sizeof(AVE2K_VOLUME_V) )
					|| !CheckChannel(pDE,  pVolume->Channel) || Volume>100)
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				if(InBufferSize == sizeof(AVE2K_VOLUME_V)){//AVE-V
					if(pVolume_V->Target)
						SetM62429Volume_V0(pDE, pVolume_V->Channel, Volume);
					else
						SetM62429Volume_V1(pDE, pVolume_V->Channel, Volume);
					status = STATUS_SUCCESS;
					break;
				}
				//other cards
				switch(pDE->VolumeControl)
				{
				case VOL_X9221:
					//do X9221 action
					break;
				case VOL_X9241:
					//do X9241 action
					break;
				case VOL_M62429:
					//do M62429 action
					SetM62429Volume(pDE, pVolume->Channel, Volume);
					break;
				case VOL_ANASWTCH:
					SetAnalogSwitchVolume(pDE, Volume);
					break;
				}
				status = STATUS_SUCCESS;
				break;
			}
		case IOCTL_STATISTICS:
			{
			PAVE2K_STATISTICS pStat;
			ULONG t;
			ULONG Channel=*(PULONG)Irp->AssociatedIrp.SystemBuffer;
				if(!pDE->Compress || InBufferSize!= sizeof(LONG) || OutBufferSize != sizeof(AVE2K_STATISTICS) || !CheckChannel(pDE, Channel))
				{
					   status = STATUS_INVALID_PARAMETER;
					   break;
				}
				pStat=(PAVE2K_STATISTICS)Irp->AssociatedIrp.SystemBuffer;
				//pDE->Stat[0].StuffPacket=Ave2kReadRegister(pDE,MC1);
				//pDE->Stat[1].StuffPacket=Ave2kReadRegister(pDE,RPS_ADDR0);
				*pStat=pDE->Stat[Channel];
				Irp->IoStatus.Information = sizeof(AVE2K_STATISTICS);
				status = STATUS_SUCCESS;
			break;
			}

		case IOCTL_OVERLAY_FRMRATE:
			{
				ULONG nFrameRate;
				if(InBufferSize != sizeof(ULONG)){
					status = STATUS_INVALID_PARAMETER;
					break;
				}
				nFrameRate=*((ULONG *)Irp->AssociatedIrp.SystemBuffer);
				if(nFrameRate>FRMRATE_1_2){
					status = STATUS_INVALID_PARAMETER;
					break;
				}
				pDE->FrameRate=nFrameRate;
				//only update when 1 picture 
				if(pDE->OverlayWindow.OpenClose ^ pDE->OverlayWindow.OpenClose2)
					ave2kOverlayControl(pDE);

⌨️ 快捷键说明

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