devload.c

来自「wince下的源代码集合打包」· C语言 代码 · 共 1,205 行 · 第 1/3 页

C
1,205
字号
/* 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.cextern void InitTAPIDevices(void);  // pcmcia.cextern HANDLE v_hPcmciaDll;         // pcmcia.cextern CRITICAL_SECTION g_devcs;    // device.cextern LIST_ENTRY g_DevChain;       // device.cint v_NextDeviceNum;            // Used to create active device listHMODULE 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      512DBGPARAM 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.//VOIDDevicePostInit(    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.//BOOLCallTapiDeviceChange(    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.//VOIDBroadcastDeviceChange(    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//VOIDNotifyDevice(    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}   // NotifyDevicetypedef 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.//DWORDDeviceNotifyThread(   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.//VOIDStartDeviceNotify(    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 + =
减小字号Ctrl + -
显示快捷键?