?? devload.c
字號(hào):
/* 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.
//
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -