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

📄 devload.c

📁 windows ce 3.00 嵌入式操作系统源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* File:    devload.c
 *
 * Purpose: WinCE device manager initialization and built-in device management
 *
 * Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved.
 */
#include <windows.h>
#include <types.h>
#include <winreg.h>
#include <tchar.h>
#include <device.h>
#include <devload.h>
#include <devloadp.h>
#include <cardserv.h>
#ifndef TARGET_NT
#include <dbt.h>
#include <tapi.h>
#include <tspi.h>
#include <tapicomn.h>
#include <notify.h>
#include <windev.h>
#else
#include <devemul.h>
#endif // TARGET_NT

//
// Functions:
//  DevicePostInit
//  CallTapiDeviceChange
//  AnnounceNewDevice
//  NotifyDevice
//  StartOneDriver
//  StartDriver
//  InitDevices
//  DevloadInit
//

extern VOID InitPCMCIA(VOID);       // pcmcia.c
extern void InitTAPIDevices(void);  // pcmcia.c
extern HANDLE v_hPcmciaDll;         // pcmcia.c
extern CRITICAL_SECTION g_devcs;    // device.c
extern LIST_ENTRY g_DevChain;       // device.c

int v_NextDeviceNum;            // Used to create active device list
HMODULE v_hTapiDLL;
HMODULE v_hCoreDLL;
BOOL g_bSystemInitd;

const TCHAR s_DllName_ValName[] = DEVLOAD_DLLNAME_VALNAME;
const TCHAR s_ActiveKey[] = DEVLOAD_ACTIVE_KEY;
const TCHAR s_BuiltInKey[] = DEVLOAD_BUILT_IN_KEY;
const TCHAR s_PcmciaKey[] = DEVLOAD_PCMCIA_KEY;

#ifdef DEBUG

//
// These defines must match the ZONE_* defines in devloadp.h
//
#define DBG_ERROR      1
#define DBG_WARNING    2
#define DBG_FUNCTION   4
#define DBG_INIT       8
#define DBG_BUILTIN    16
#define DBG_PCMCIA     32
#define DBG_ACTIVE     64
#define DBG_TAPI       128
#define DBG_FSD        256
#define DBG_DYING      512

DBGPARAM dpCurSettings = {
    TEXT("DEVLOAD"), {
    TEXT("Errors"),TEXT("Warnings"),TEXT("Functions"),TEXT("Initialization"),
    TEXT("Built-In Devices"),TEXT("PCMCIA Devices"),TEXT("Active Devices"),TEXT("TAPI stuff"),
    TEXT("File System Drvr"),TEXT("Dying Devs"),TEXT("Undefined"),TEXT("Undefined"),
    TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined") },
#ifdef TARGET_NT // Enable some debug prints.
	DBG_PCMCIA
#else 
    0
#endif // TARGET_NT
};
#endif  // DEBUG

//
// Function to call a newly registered device's post initialization
// device I/O control function.
//
VOID
DevicePostInit(
    LPTSTR DevName,
    DWORD  dwIoControlCode,
    DWORD  Handle,          // Handle from RegisterDevice
    HKEY   hDevKey
    )
{
    HANDLE hDev;
    BOOL ret;
    POST_INIT_BUF PBuf;

    DEBUGMSG(ZONE_ACTIVE,
        (TEXT("DEVICE!DevicePostInit calling CreateFile(%s)\r\n"), DevName));
    hDev = CreateFile(
                DevName,
                GENERIC_READ|GENERIC_WRITE,
                0,
                NULL,
                OPEN_EXISTING,
                0,
                NULL);
    if (hDev == INVALID_HANDLE_VALUE) {
        DEBUGMSG(ZONE_ACTIVE,
            (TEXT("DEVICE!DevicePostInit CreateFile(%s) failed %d\r\n"),
            DevName, GetLastError()));
        return;
    }

    DEBUGMSG(ZONE_ACTIVE,
        (TEXT("DEVICE!DevicePostInit calling DeviceIoControl(%s, %d)\r\n"),
         DevName, dwIoControlCode));
    PBuf.p_hDevice = (HANDLE)Handle;
    PBuf.p_hDeviceKey = hDevKey;
    ret = DeviceIoControl(
              hDev,
              dwIoControlCode,
              &PBuf,
              sizeof(PBuf),
              NULL,
              0,
              NULL,
              NULL);
    DEBUGMSG(ZONE_ACTIVE,
        (TEXT("DEVICE!DevicePostInit DeviceIoControl(%s, %d) "),
         DevName, dwIoControlCode));
    if (ret == TRUE) {
        DEBUGMSG(ZONE_ACTIVE, (TEXT("succeeded\r\n")));
    } else {
        DEBUGMSG(ZONE_ACTIVE, (TEXT("failed\r\n")));
    }
    CloseHandle(hDev);
}   // DevicePostInit



//
// Function to notify TAPI of a device change. A TAPI device has a key which
// contains a Tsp value listing the TAPI Service Provider.
//
// Returns TRUE if the device has a TAPI association.
//
BOOL
CallTapiDeviceChange(
    HKEY hActiveKey,
    LPCTSTR DevName,
    BOOL bDelete
    )
{
#ifndef TARGET_NT
    DWORD ValType;
    DWORD ValLen;
    DWORD status;
    HKEY DevKey;
    TCHAR DevKeyPath[REG_PATH_LEN];
    BOOL bTapiDevice;

typedef BOOL (WINAPI *PFN_TapiDeviceChange) (HKEY DevKey, LPCWSTR lpszDevName, BOOL bDelete);
	PFN_TapiDeviceChange pfnTapiDeviceChange;

    //
    // TAPI.DLL must be loaded first.
    //
    if (v_hTapiDLL == NULL) {
        DEBUGMSG(ZONE_TAPI|ZONE_ERROR,
            (TEXT("DEVICE!CallTapiDeviceChange TAPI.DLL not loaded yet.\r\n")));
        return FALSE;
    }

    //
    // It's a TAPI device if a subkey of the device key contains a TSP value.
    //
    ValLen = sizeof(DevKeyPath);
    status = RegQueryValueEx(            // Read Device Key Path
                hActiveKey,
                DEVLOAD_DEVKEY_VALNAME,
                NULL,
                &ValType,
                (LPBYTE)DevKeyPath,
                &ValLen);
    if (status) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("DEVICE!CallTapiDeviceChange RegQueryValueEx(%s) failed %d\r\n"),
            DEVLOAD_DEVKEY_VALNAME, status));
            return FALSE;
    }

    status = RegOpenKeyEx(             // Open the Device Key
                HKEY_LOCAL_MACHINE,
                DevKeyPath,
                0,
                0,
                &DevKey);
    if (status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
            (TEXT("DEVICE!CallTapiDeviceChange: RegOpenKeyEx(%s) returned %d\r\n"),
            DevKeyPath, status));
        return FALSE;
    }


	// Try to find the pointer to TapiDeviceChange
	pfnTapiDeviceChange = (PFN_TapiDeviceChange)GetProcAddress (v_hTapiDLL, TEXT("TapiDeviceChange"));
	if (pfnTapiDeviceChange == NULL) {
        DEBUGMSG(ZONE_TAPI,
            (TEXT("DEVICE!CallTapiDeviceChange can't get pointer to TapiDeviceChange.\r\n")));
        return FALSE;
	}
		
    bTapiDevice = pfnTapiDeviceChange(DevKey, DevName, bDelete);
    RegCloseKey(DevKey);
    return bTapiDevice;
#endif // TARGET_NT
}   // CallTapiDeviceChange


//
// Function to format and send a Windows broadcast message announcing the arrival
// or removal of a device in the system.
//
VOID
BroadcastDeviceChange(
    LPTSTR DevName,
    BOOL bNew
    )
{
#ifndef TARGET_NT
    PDEV_BROADCAST_PORT pBCast;
    DWORD len;
    LPTSTR str;
	typedef BOOL (WINAPI *PFN_SendNotifyMessageW)(HWND hWnd, UINT Msg,
											  WPARAM wParam,
											  LPARAM lParam);
	PFN_SendNotifyMessageW pfnSendNotifyMessageW;

	if (v_hCoreDLL == NULL) {
    	v_hCoreDLL = (HMODULE)LoadLibrary(TEXT("COREDLL.DLL"));
    	if (v_hCoreDLL == NULL) {
            DEBUGMSG(ZONE_TAPI|ZONE_ERROR,
                (TEXT("DEVICE!BroadcastDeviceChange unable to load CoreDLL.\r\n")));
    		return;
    	}
	}

	pfnSendNotifyMessageW = (PFN_SendNotifyMessageW)GetProcAddress(v_hCoreDLL, TEXT("SendNotifyMessageW"));
	if (pfnSendNotifyMessageW == NULL) {
		DEBUGMSG (ZONE_PCMCIA, (TEXT("Can't find SendNotifyMessage\r\n")));
		return;
	}
    //
    // Don't use GWE API functions if not there
    //
    if (IsAPIReady(SH_WMGR) == FALSE) {
        return;
    }

    len = sizeof(DEV_BROADCAST_HDR) + (_tcslen(DevName) + 1)*sizeof(TCHAR);

    pBCast = LocalAlloc(LPTR, len);
    if (pBCast == NULL) {
        return;
    }

        pBCast->dbcp_devicetype = DBT_DEVTYP_PORT;
    pBCast->dbcp_reserved = 0;
    str = (LPTSTR)&(pBCast->dbcp_name[0]);
    _tcscpy(str, DevName);
    pBCast->dbcp_size = len;

    DEBUGMSG(ZONE_PCMCIA,
        (TEXT("DEVICE!BroadcastDeviceChange Calling SendNotifyMessage for device %s\r\n"), DevName));

	// Call the function
    pfnSendNotifyMessageW(
        HWND_BROADCAST,
        WM_DEVICECHANGE,
        (bNew) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
        (LPARAM)pBCast);

    LocalFree(pBCast);

#endif // TARGET_NT
}   // BroadcastDeviceChange


//
// Function to signal the app notification system of a device change
//
VOID
NotifyDevice(
    LPTSTR DevName,
    LPTSTR Op
    )
{
#ifndef TARGET_NT
    DWORD len;
    LPTSTR str;

    //
    // First check if shell functions can be called.
    //
    if (IsAPIReady(SH_WMGR) == FALSE) {
        DEBUGMSG(ZONE_PCMCIA,
            (TEXT("DEVICE!NotifyDevice IsAPIReady(SH_MGR i.e. GWES) returned FALSE, not calling CeEventHasOccurred(%s %s)\r\n"),
            Op, DevName));
        return;
    }

    len = (_tcslen(Op) + _tcslen(DevName) + 2)*sizeof(TCHAR);

    str = LocalAlloc(LPTR, len);
    if (str == NULL) {
        return;
    }

    //
    // Format the end of the command line
    //
    _tcscpy(str, Op);
    _tcscat(str, TEXT(" "));
    _tcscat(str, DevName);

    DEBUGMSG(ZONE_PCMCIA,
        (TEXT("DEVICE!NotifyDevice Calling CeEventHasOccurred(%s)\r\n"), str));
    CeEventHasOccurred(NOTIFICATION_EVENT_DEVICE_CHANGE, str);
    LocalFree(str);
#endif // TARGET_NT
}   // NotifyDevice


typedef struct _DEVICE_CHANGE_CONTEXT {
    TCHAR DevName[DEVNAME_LEN];
    BOOL bNew;
} DEVICE_CHANGE_CONTEXT, * PDEVICE_CHANGE_CONTEXT;


//
// Thread function to call CeEventHasOccurred and SendNotifyMessage for a device
// that has been recently installed or removed. Another thread is needed because
// in the context in which the device changes occur, the gwes and the filesystem
// critical sections are taken.
//
DWORD
DeviceNotifyThread(
   IN PVOID ThreadContext
   )
{
    PDEVICE_CHANGE_CONTEXT pdcc = (PDEVICE_CHANGE_CONTEXT)ThreadContext;

    BroadcastDeviceChange(pdcc->DevName, pdcc->bNew);
    NotifyDevice(pdcc->DevName, (pdcc->bNew) ? NOTIFY_DEVICE_ADD : NOTIFY_DEVICE_REMOVE);
    LocalFree(pdcc);
    return 0;
}   // DeviceNotifyThread


//
// Function to start a thread that signals a device change via the application
// notification system and via a broadcast windows message.
//
VOID
StartDeviceNotify(
    LPTSTR DevName,
    BOOL bNew
    )
{
    PDEVICE_CHANGE_CONTEXT pdcc;
    HANDLE hThd;

    pdcc = LocalAlloc(LPTR, sizeof(DEVICE_CHANGE_CONTEXT));
    if (pdcc == NULL) {
        return;
    }

    pdcc->bNew = bNew;
    memcpy(pdcc->DevName, DevName, DEVNAME_LEN*sizeof(TCHAR));

    hThd = CreateThread(NULL, 0,
                     (LPTHREAD_START_ROUTINE)&DeviceNotifyThread,
                     (LPVOID) pdcc, 0, NULL);
    if (hThd != NULL) {
        CloseHandle(hThd);
    } else {
        LocalFree(pdcc);
    }
}   // StartDeviceNotify

//
// Function to RegisterDevice a device driver and add it to the active device list
// in HLM\Drivers\Active and then signal the system that a new device is available.
//

⌨️ 快捷键说明

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