oemioctl.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 378 行

C
378
字号
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1998  Microsoft Corporation

Module Name:

   oemioctl.c

Abstract:

Notes:

   This file implements the NK kernel I/O control API.

--*/

#define WINCEMACRO 1

#include <windows.h>
#include <nkintr.h>
#include <altoona.h>
#include <hal.h>
#include <ethdbg.h>
#include <halether.h>

#undef DeviceIoControl
#include <oalio.h>
#include <wdmhal.h>
#include "pc_ddk.h"

// No Vmini support in Cedar.
#undef IMGSHAREETH

unsigned int strlenW(LPCWSTR str);

static const WCHAR HALPlatformStr[] = L"BOSTON Platform";
static const WCHAR HALOEMStr[] = L"BOSTON";
extern USHORT wLocalMAC[3];	// in halether.c

extern	void	JumpTo (DWORD dwAddress);

#ifdef IMGSHAREETH
BOOL OEMEthCurrentPacketFilter(PDWORD pdwRequestedFilter);
BOOL OEMEthMulticastList(PUCHAR pucMulticastAddressList, DWORD dwNoOfAddresses);
#endif

#ifdef HAL_DVCM
extern HRESULT Ioctl_Register_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
extern HRESULT Ioctl_Send_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
extern HRESULT Ioctl_Unregister_DataCollector(LPVOID,DWORD,LPVOID,DWORD);
#endif


/*
     @func     BOOL | OEMIoControl | generic HAL request
     @rdesc    none
     @comm     OEMIoControl is called by the Kernel when a device driver or application
             program calls <f KernelIoControl>. The system is fully preemtible when this
               function is called. The kernel does no processing of this API. It is
               provided to allow an OEM device driver to communicate with kernel mode
               HAL code.
     @xref <l Overview.Pegasus Kernel OEM Interface> <f KernelIoControl>
*/
BOOL OEMIoControl( DWORD dwIoControlCode, LPVOID lpInBuf, DWORD nInBufSize,
    LPVOID lpOutBuf, DWORD nOutBufSize, LPDWORD lpBytesReturned)
{
    BOOL retval = FALSE;
    DWORD len;
    EDBG_ADDR DestAddr;
    PUDP_PACKET pUDPPacket;

    switch (dwIoControlCode)
    {

        /////////////////////////////////////////////////////////////////////////
        //      misc...
        //
    
        case IOCTL_HAL_INIT_RTC:
                if (nInBufSize >= sizeof(SYSTEMTIME))
                    retval = OEMSetRealTime( (LPSYSTEMTIME)lpInBuf);
                break;

        /////////////////////////////////////////////////////////////////////////
        //      Translate interrupt into SYSINTR
        //
       
#define IOCTL_HAL_MAP_INTERRUPT 0x3 
        case IOCTL_HAL_TRANSLATE_IRQ:
        case IOCTL_HAL_MAP_INTERRUPT:
            retval = OEMMapInterrupt(*(DWORD *)lpInBuf, 0, (DWORD *)lpOutBuf);
            if (retval && lpBytesReturned)
                *lpBytesReturned = sizeof(ULONG);
            //RETAILMSG(1, (TEXT("IOCTL_HAL_TRANSLATE_IRQ (In=0x%x  Out=0x%x)\r\n"), *(PULONG)lpInBuf, *(PULONG)lpOutBuf));
            break;
            

        /////////////////////////////////////////////////////////////////////////
        //      Used by CEDDK.DLL
        //

        case IOCTL_HAL_DDK_CALL:

                if ((nInBufSize != sizeof(BUSDATA_PARMS)) ||
                        (!lpInBuf) )
                {
                        // Oops, parameter list isn't what we expected.
                        SetLastError( ERROR_INVALID_PARAMETER );
                }

                if ( *(DWORD *)lpInBuf == IOCTL_HAL_SETBUSDATA )
                {
                        //RETAILMSG (1, (TEXT("OEMIoctl::: Bus  no = %d .\r\n"), ((PBUSDATA_PARMS)lpInBuf)->BusNumber));
                        //RETAILMSG (1, (TEXT("OEMIoctl::: Slot no = %d .\r\n"), ((PBUSDATA_PARMS)lpInBuf)->SlotNumber));
                        //RETAILMSG (1, (TEXT("OEMIoctl::: Length  = %d .\r\n"), ((PBUSDATA_PARMS)lpInBuf)->Length));

                        ((PBUSDATA_PARMS)lpInBuf)->ReturnCode = OEMSetBusDataByOffset(
                                                      ((PBUSDATA_PARMS)lpInBuf)->BusDataType,
                                                      ((PBUSDATA_PARMS)lpInBuf)->BusNumber,
                                                      ((PBUSDATA_PARMS)lpInBuf)->SlotNumber,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Buffer,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Offset,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Length
                                                      );
                        retval = TRUE;
                }
                else if ( *(DWORD *)lpInBuf == IOCTL_HAL_GETBUSDATA )
                {
                        ((PBUSDATA_PARMS)lpInBuf)->ReturnCode = OEMGetBusDataByOffset(
                                                      ((PBUSDATA_PARMS)lpInBuf)->BusDataType,
                                                      ((PBUSDATA_PARMS)lpInBuf)->BusNumber,
                                                      ((PBUSDATA_PARMS)lpInBuf)->SlotNumber,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Buffer,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Offset,
                                                      ((PBUSDATA_PARMS)lpInBuf)->Length
                                                      );
                        retval = TRUE;
                }
                else
                {
                        // Oops, parameter list isn't what we expected.
                        SetLastError( ERROR_INVALID_PARAMETER );
                }
                break;

        // briaking - Added for CE 3.0
        case IOCTL_HAL_GET_DEVICE_INFO :
            if( nInBufSize == 4 )
            {
                switch( *(LPDWORD)lpInBuf ) 
                {
                case SPI_GETPLATFORMTYPE:
                    len = ( strlenW( HALPlatformStr ) + 1 ) * sizeof( WCHAR );
                    if( nOutBufSize >= len )
                    {
                        memcpy( lpOutBuf, HALPlatformStr, len );
                        retval = TRUE;
                    } 
                    else
                    {
                        SetLastError( ERROR_INSUFFICIENT_BUFFER );
                    }
                    break;
                case SPI_GETOEMINFO:
                    len = ( strlenW( HALOEMStr ) + 1 ) * sizeof( WCHAR );
                    if (nOutBufSize >= len) 
                    {
                        memcpy(lpOutBuf,HALOEMStr,len);
                        retval = TRUE;
                    }
                    else
                    {
                        SetLastError( ERROR_INSUFFICIENT_BUFFER );
                    }
                    break;
                default:
                    SetLastError( ERROR_INVALID_PARAMETER );
                }
            }
            else 
            {
                SetLastError( ERROR_INVALID_PARAMETER );
            }
            break;

        // briaking - added for CE 3.0
        case IOCTL_HAL_GET_UUID :
    		if( lpOutBuf && ( nOutBufSize >= sizeof(GUID) ) ) 
            {
    			if( lpBytesReturned ) 
                {
    				*lpBytesReturned = sizeof(GUID);
    			}
    			// OEM's with unique ID hardware can return the value here.

    			// The ALTOONA platform does not have any unique ID settings.
    			// We'll use the Kernel Ethernet Debug address if non-zero
    			if( wLocalMAC[0] | wLocalMAC[1] | wLocalMAC[2] ) 
                {
    				memcpy( lpOutBuf, (char *)wLocalMAC, sizeof(GUID) );
    				return TRUE;
    			}
                else
                {
    				SetLastError( ERROR_NOT_SUPPORTED );
    				return FALSE;
    			}
    		}
            else
            {
    			SetLastError( ERROR_INVALID_PARAMETER );
    			return FALSE;
    		}
    		break;



        /////////////////////////////////////////////////////////////////////////
        //		Used by Mini Shell to reset after receiving complete image of 
        //		nk.bin from http server.
		//		

	    case IOCTL_HAL_REBOOT: // briaking - IOCTL_HAL_REBOOT added for CE 3.0
		case HAL_IOCTL_ALTOONA_RESET:	
				JumpTo (0xBFC00000);		//	This will never return...									
				break;						//	System resets !!!


	////////////////////////////////////////////////////////////////////////

    case IOCTL_HAL_SEND_UDP :
        if ((lpInBuf == NULL) || (nInBufSize < sizeof(EDBG_ADDR))) {
            SetLastError(ERROR_INVALID_PARAMETER);
            break;
        }
        pUDPPacket = (PUDP_PACKET)lpInBuf;
        // Send the packet
        DestAddr.dwIP = pUDPPacket->dwDestIP;
        memcpy ((char *)DestAddr.wMAC, pUDPPacket->DestMAC,
                sizeof(pUDPPacket->DestMAC));
        DestAddr.wPort = pUDPPacket->wDestPort;

        len = EdbgSendUDP(lpInBuf, &DestAddr, pUDPPacket->wSrcPort, pUDPPacket->Packet, pUDPPacket->wPacketLen);
        // This returns 0 for success
        if (0 == len) {
            retval = TRUE;
        }
        break;

    case IOCTL_EDBG_REGISTER_CLIENT:
        return EdbgRegisterClient(lpInBuf, lpOutBuf, (UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR *)lpBytesReturned);

    case IOCTL_EDBG_DEREGISTER_CLIENT:
        return EdbgDeregisterClient((UCHAR)nInBufSize);

    case IOCTL_EDBG_REGISTER_DFLT_CLIENT:
        return EdbgRegisterDfltClient((UCHAR)nInBufSize, (UCHAR)nOutBufSize, (UCHAR **)lpInBuf, (UCHAR **)lpOutBuf);

    case IOCTL_EDBG_SEND:
        return EdbgSend((UCHAR)nInBufSize, lpInBuf, nOutBufSize);

    case IOCTL_EDBG_RECV:
        return EdbgRecv((UCHAR)nInBufSize, lpInBuf, lpOutBuf, nOutBufSize);

    case IOCTL_EDBG_SET_DEBUG:
        EdbgSetDebug(nInBufSize);
        break;

    case IOCTL_SET_KERNEL_COMM_DEV:
        // Routine to change underlying communications device for kernel services
        return SetKernelCommDev((UCHAR)nInBufSize,(UCHAR)nOutBufSize);


        ////////////////////////////////////////////////////////////////////////
        //
        //  The support for VMini..
        //
#ifdef IMGSHAREETH
        case IOCTL_VBRIDGE_GET_TX_PACKET:
            return VBridgeUGetOneTxPacket((PUCHAR *)lpOutBuf);
            break;
    
        case IOCTL_VBRIDGE_GET_TX_PACKET_COMPLETE:
            VBridgeUGetOneTxPacketComplete((PUCHAR)lpInBuf, nInBufSize);
            return TRUE;
            break;
    
        case IOCTL_VBRIDGE_GET_RX_PACKET:
            return VBridgeUGetOneRxPacket((PUCHAR *)lpOutBuf, lpBytesReturned);
            break;
    
        case IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE:
            VBridgeUGetOneRxPacketComplete((PUCHAR)lpInBuf);
            return TRUE;
            break;
    
        case IOCTL_VBRIDGE_GET_ETHERNET_MAC:
            VBridgeUGetEDBGMac((PBYTE)lpOutBuf);
            return TRUE;
            break;
    
	case IOCTL_VBRIDGE_CURRENT_PACKET_FILTER:
	    ////////////////////////////////////////////////////////////////////
	    //	First, see if filter setting is implemented, then inform vbridge
	    //	on the new filtering.
	    //
            if (OEMEthCurrentPacketFilter((PDWORD)lpInBuf))
	    {
	        VBridgeUCurrentPacketFilter((PDWORD)lpInBuf);
	        return TRUE;
	    }
	    return FALSE;
            break;
	    	
	case IOCTL_VBRIDGE_802_3_MULTICAST_LIST:
            if (OEMEthMulticastList((PUCHAR)lpInBuf, nInBufSize))
		return TRUE;		
	    return FALSE;
            break;
            
        case IOCTL_VBRIDGE_SHARED_ETHERNET:
            ////////////////////////////////////////////////////////////////////
            //  Yes, this kernel supports shared ethernet port.
            //
            return TRUE;
            break;

#endif	// IMGSHAREETH
        ////////////////////////////////////////////////////////////////////////


        ////////////////////////////////////////////////////////////////////////
        //
        // Celog support
#ifdef HAL_DVCM

        case IOCTL_COLLECTOR_REGISTER:
            if( FAILED(Ioctl_Register_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
                return FALSE;
            else
                retval = TRUE;
            break;
      
        case IOCTL_COLLECTOR_SEND:
            if( FAILED(Ioctl_Send_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
                return FALSE;
            else
                retval = TRUE;
            break;
      
        case IOCTL_COLLECTOR_UNREGISTER:
            if( FAILED(Ioctl_Unregister_DataCollector(lpInBuf,nInBufSize,lpOutBuf,nOutBufSize)))
                return FALSE;
            else
                retval = TRUE;
            break;
      
#endif // HAL_DVCM
        ////////////////////////////////////////////////////////////////////////


        default:
                SetLastError( ERROR_NOT_SUPPORTED );
                break;





    }

    return retval;
}

⌨️ 快捷键说明

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