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

📄 emulserv.cpp

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*==================================================================
	File:		emulserv.cpp
	
	Contains:	Pseudo service device to arbitrate emulator interrupt SYSINTR_EMULSERV
				usage.
				
	Written by:	Craig vinet
	
	Copyright:	2002 Connectix Corporation
==================================================================*/

#include <windows.h>
#include "emulserv.h"

#include <wdm.h> // for READ_PORT_XXXX, WRITE_PORT_XXXX
#include <Pkfuncs.h>
#include <nkintr.h>
#include <cardserv.h>
#include <devload.h>
#include <winnls.h>

#include <storemgr.h>
#include <diskio.h>
#include <s3c2410x_ioport.h>
#include <s3c2410x_base_regs.h>

#include <vcefsd.h>
#include "fserver.h"
#include "SpeakerHeadset.h"

#define SYSINTR_EMULSERV (SYSINTR_FIRMWARE+15) // TODO: Get some other way

// ioctls to read or change BSP Args to indicate storage is mounted or unmounted
#define IOCTL_HAL_GET_SHARED_FOLDER_FLAG      CTL_CODE(FILE_DEVICE_HAL,1097, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HAL_SET_SHARED_FOLDER_FLAG      CTL_CODE(FILE_DEVICE_HAL,1098, METHOD_BUFFERED, FILE_ANY_ACCESS)


// Layout of the DeviceEmulator's EmulServ device
typedef struct {
	unsigned __int32 InterruptMask;
	unsigned __int32 InterruptPending;
} EmulServDevice;

// Holds data for the device
struct DeviceInfo
{
	DeviceInfo()				// Constructor
	{
		fInterruptEvent = 0;		// Event signaled when interrupt occurs
		fInterruptID = 0;			// IRQ of the interrupt
		fIntrServiceThread = NULL;	// Handle to the interrupt servicing thread (IST)
	}			
	
	HANDLE		fInterruptEvent;	// fInterruptEvent signaled when interrupt occurs
	HANDLE		fIntrServiceThread;	// Handle to InterruptServiceThread
	DWORD		fInterruptID;		// Logical interrupt ID
};


/*------------------------------------------------------------------
	Defines and const
------------------------------------------------------------------*/

// Emulator Services IRQ
const WCHAR *g_szDrvRegPath = L"Drivers\\EMULSERV";

/*------------------------------------------------------------------
	Globals
------------------------------------------------------------------*/
BOOL 		deviceInitialized = FALSE;
DeviceInfo	deviceInfo;

HANDLE hDev = NULL;
static HANDLE g_hFSD = NULL;

#define VCEFSD_PROFILE     TEXT("VCEFSD")

CRITICAL_SECTION 	g_csMain;

volatile EmulServDevice *v_EmulServDevice;

/*------------------------------------------------------------------
	Local Prototypes
------------------------------------------------------------------*/
static DWORD WINAPI InterruptServiceThread( PVOID Empty );
static void ProcessFolderSharingChange();

static BOOL StartIST();
static void StopIST();

static BOOL InitializeGlobals();
static void DeInitializeGlobals();

static ULONG AckInterrupt();
static VOID InstallInterrupt();
static VOID UninstallInterrupt();

static DWORD GetDiskInfo(	PDISK_INFO pInfo );
static BOOL GetDeviceInfo(PSTORAGEDEVICEINFO pInfo);


/*------------------------------------------------------------------
	DllMain
	
	Entry point called when a process hooks up to the DLL.
------------------------------------------------------------------*/

BOOL APIENTRY DllMain(HANDLE hinstDLL, DWORD fdwReason, LPVOID lpv)
{
	switch ( fdwReason )
	{
		case DLL_PROCESS_ATTACH:
			if ( deviceInitialized == FALSE )
			{
				return InitializeGlobals();
			}
			break;
		case DLL_PROCESS_DETACH:
			if( deviceInitialized == TRUE )
			{
				DeInitializeGlobals();
			}
			break;
		case DLL_THREAD_ATTACH:
		 	break;
		case DLL_THREAD_DETACH:
			break;
	}
	
	return TRUE;
}


/*------------------------------------------------------------------
	InterruptServiceThread
	
	When interrupt occurs on IRQ 10, this thread is triggered to 
	dispatch interrupt.

------------------------------------------------------------------*/

#define kFServerChangedServiceMask		0x40000000
#define kSPKHeadsetChangedMask                  0x00000001

static DWORD WINAPI
InterruptServiceThread( PVOID /*ignore*/ )   // NULL pointer does nothing.
{
	while ( TRUE )		// loop forever
	{
	 	// Wait for interrrupt event
		if ( WaitForSingleObject( deviceInfo.fInterruptEvent, INFINITE ) == WAIT_FAILED ) // Something bad happened
		{
			continue;
		}
		
		EnterCriticalSection (&g_csMain);

		DEBUGMSG( TRUE, (TEXT("Emulator Services:InterruptServiceThread() Interrupt: Fired!\n")) );
		
		// Ack int & Dispatch events here
		ULONG event = AckInterrupt();

		if( event & kFServerChangedServiceMask )
		{
			ProcessFolderSharingChange();
		}
                if( event & kSPKHeadsetChangedMask ) 
                {
                    ProcessSPKMaskChange();
                }

		InterruptDone( deviceInfo.fInterruptID );

		LeaveCriticalSection (&g_csMain);
	}
    return(0);
}

/*------------------------------------------------------------------
    ProcessFolderSharingChange
    
    Checks the Device Emulator to see if folder sharing is enabled.
    If it is enabled and the shared folder is mounted, unmount the folder.
    If it is enabled and the shared folder is unmounted, mount the folder.
------------------------------------------------------------------*/
static void ProcessFolderSharingChange()
{
    
    DEBUGMSG( TRUE, (TEXT("Emulator Services:+ProcessFolderSharingChange()\r\n")) );
    
    volatile FolderSharingDevice *v_tempFolderShareDevice;
    DWORD error;

    v_tempFolderShareDevice = (volatile FolderSharingDevice*)VirtualAlloc(NULL, sizeof(*v_tempFolderShareDevice), MEM_RESERVE, PAGE_NOACCESS);
    if (v_tempFolderShareDevice == NULL)
    {
        //DEBUGMSG(ZONE_ERROR, (L"EMULSERV_ProcessFolderSharingChange ERROR: FolderShareDevice VirtualAlloc Failed\n") );
        goto Done;
    }
    if (!VirtualCopy((LPVOID)v_tempFolderShareDevice, (PVOID)(0x500f4000>>8), sizeof(*v_tempFolderShareDevice), PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL))
    {
        error = GetLastError();
        //DEBUGMSG(ZONE_ERROR, (L"EMULSERV_ProcessFolderSharingChange ERROR: FolderShareDevice VirtualCopy Failed\n") );
        goto Done;
    }

    v_tempFolderShareDevice->Code = kServerPollCompletion;
    unsigned __int32 mounted = v_tempFolderShareDevice->Result;
    VirtualFree((LPVOID*)v_tempFolderShareDevice, 0, MEM_RELEASE);
    if(mounted != kErrorInvalidFunction)
    {
        // folder sharing enabled
        DEBUGMSG( TRUE, (TEXT("Emulator Services:Folder sharing is enabled()\r\n")) );
        if(g_hFSD == NULL)
        {
            DEBUGMSG( TRUE, (TEXT("Emulator Services:+Mounting Device()\r\n")) );
            g_hFSD = ActivateDevice(g_szDrvRegPath, 0);
            BOOL setFlagTrue = TRUE;
            KernelIoControl(IOCTL_HAL_SET_SHARED_FOLDER_FLAG, &setFlagTrue, sizeof(BOOL), 0, 0, 0);
            DEBUGMSG( TRUE, (TEXT("Emulator Services:-Mounting Device()\r\n")) );
        }
    }
    else
    {
        DEBUGMSG( TRUE, (TEXT("Emulator Services:Folder sharing NOT enabled()\r\n")) );
        if(g_hFSD != NULL)
        {
            DEBUGMSG( TRUE, (TEXT("Emulator Services:+Unmounting Device()\r\n")) );
            DeactivateDevice(g_hFSD);
            BOOL setFlagFalse = FALSE;
            KernelIoControl(IOCTL_HAL_SET_SHARED_FOLDER_FLAG, &setFlagFalse, sizeof(BOOL), 0, 0, 0);
            DEBUGMSG( TRUE, (TEXT("Emulator Services:-Unmounting Device()\r\n")) );
            g_hFSD = NULL;
        }
    }
Done:

    DEBUGMSG( TRUE, (TEXT("Emulator Services:-ProcessFolderSharingChange()\r\n")) );
}



/*------------------------------------------------------------------
	StartIST
	
	Starts the interrupt service thread
	Returns: Success(true) or failure(false)
------------------------------------------------------------------*/

BOOL
StartIST()
{
    
    BOOL bspArgsStorageMountedFlag;

    if( !(KernelIoControl(IOCTL_HAL_GET_SHARED_FOLDER_FLAG, 0, 0, &bspArgsStorageMountedFlag, sizeof(bspArgsStorageMountedFlag), 0)))
    {
        // If we failed, the OAL doesn't support the operation so we can simply ignore this flag
        bspArgsStorageMountedFlag = FALSE;
    }

    ULONG firstEvent = AckInterrupt();
    if( (firstEvent & kFServerChangedServiceMask) || bspArgsStorageMountedFlag )
    {
        ProcessFolderSharingChange();
    }

	// Initialize the interrupt to be associated with the fInterruptEvent event
    if ( !InterruptInitialize(deviceInfo.fInterruptID, deviceInfo.fInterruptEvent, NULL, 0) ) 
	{
		DEBUGMSG( TRUE, (TEXT("Emulator Services:StartIST() failed on InterruptInitialize.\n")) );
        return FALSE;
    }
	
    // Create the thread
	deviceInfo.fIntrServiceThread = CreateThread(NULL, 0, InterruptServiceThread, NULL, 0, NULL);
	
    if ( deviceInfo.fIntrServiceThread == NULL ) // Failure
	{
		DEBUGMSG( TRUE, (TEXT("Emulator Services:StartIST() failed to create interrupt service thread.\n")) );
        return FALSE;
    }
	
	InstallInterrupt();

	// Set thread priority above normal
    //CeSetThreadPriority( deviceInfo.fIntrServiceThread, THREAD_PRIORITY_ABOVE_NORMAL );
	SetThreadPriority(deviceInfo.fIntrServiceThread, THREAD_PRIORITY_HIGHEST);
	
	DEBUGMSG( TRUE, (TEXT("Emulator Services:StartIST() succeeded.\n")) );
	
	return TRUE;
}

/*------------------------------------------------------------------
	StopIST
------------------------------------------------------------------*/

void
StopIST()
{
	UninstallInterrupt();
}


/*------------------------------------------------------------------
	InitializeGlobals
	
	Initializations that should only occur once for the
	entire life of the driver
------------------------------------------------------------------*/

BOOL InitializeGlobals()
{
	// Set logical interrupt ID
	BOOL fRet = FALSE;
    volatile S3C2410X_IOPORT_REG *vpIOPRegs = NULL;

    ASSERT(v_EmulServDevice == NULL);
    
    DWORD dwIrq = 39;
    fRet = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq, sizeof(UINT32), &deviceInfo.fInterruptID, sizeof(UINT32), NULL);
    if (fRet == FALSE) {
		DEBUGMSG (1,(TEXT("IOCTL_HAL_REQUEST_SYSINTR for irq 0x%x failed\n\r"), dwIrq));
        goto EXIT;
    }

	v_EmulServDevice = (volatile EmulServDevice*)VirtualAlloc(NULL, sizeof(*v_EmulServDevice), MEM_RESERVE, PAGE_NOACCESS);
	if (v_EmulServDevice == NULL)
	{
		DEBUGMSG (1,(TEXT("v_EmulServDevice is not allocated\n\r")));
		fRet = FALSE;
        goto EXIT;
	}
	fRet = VirtualCopy((LPVOID)v_EmulServDevice, (PVOID)(0x500f5000>>8), sizeof(*v_EmulServDevice), PAGE_READWRITE|PAGE_NOCACHE|PAGE_PHYSICAL); 
	if (fRet == FALSE) {
		DEBUGMSG (1,(TEXT("v_EmulServDevice is not mapped\n\r")));
        goto EXIT;
	}
	DEBUGMSG (1,(TEXT("v_EmulServDevice is mapped to %x\n\r"), v_EmulServDevice));

	vpIOPRegs = (S3C2410X_IOPORT_REG*)VirtualAlloc(0, sizeof(S3C2410X_IOPORT_REG), MEM_RESERVE, PAGE_NOACCESS);
	if (vpIOPRegs == NULL) 
	{
		DEBUGMSG (1,(TEXT("m_vpIOPRegs is not allocated\n\r")));
		fRet = FALSE;
        goto EXIT;
	}
	fRet = VirtualCopy((PVOID)vpIOPRegs, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof(S3C2410X_IOPORT_REG), PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE);
    if (fRet == FALSE) {
		DEBUGMSG (1,(TEXT("m_vpIOPRegs is not mapped\n\r")));
		goto EXIT;
	}
	DEBUGMSG (1,(TEXT("m_vpIOPRegs is mapped to %x\n\r"), vpIOPRegs));

	vpIOPRegs->GPFCON = (vpIOPRegs->GPFCON & ~(0x3<<0x6)) | (0x2<<0x6); 
	vpIOPRegs->GPFUP  = (vpIOPRegs->GPFUP | (0x1<<0x3));    
	vpIOPRegs->EXTINT1 =(vpIOPRegs->EXTINT1 & ~(0xf<<0xc)) | (0x1<<0xc); 
	
	// Create events
	deviceInfo.fInterruptEvent	= CreateEvent(0, FALSE, FALSE, NULL);
	
	// Make sure events are valid
	if ( !deviceInfo.fInterruptEvent )
	{

⌨️ 快捷键说明

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