?? pcmcia.c
字號:
/* File: pcmcia.c
*
* Purpose: WinCE device loader for PCMCIA devices
*
* Copyright (c) 1995-2000 Microsoft Corporation. All rights reserved.
*/
#include <windows.h>
#include <types.h>
#include <tchar.h>
#include <winreg.h>
#include <cardserv.h>
#include <tuple.h>
#include <devload.h>
#include <devloadp.h>
#include <dbt.h>
#include <notify.h>
#include <extfile.h>
#include <netui.h>
#ifdef TARGET_NT
#include <devemul.h>
#include <device.h>
#include <proxy.h>
#endif // TARGET_NT
#ifdef INSTRUM_DEV
#include <instrumd.h>
#endif // INSTRUM_DEV
//
// This module contains these functions:
// QueryDriverNameThread
// QueryDriverName
// InitTapiDeviceChange
// RunDetectors
// LoadPCCardDriver
// FindPCCardDriver
// FindActiveBySocket
// I_DeactivateDevice
// IsCardInserted
// PcmciaCallBack
// InitPCMCIA
// InitTAPIDevices
//
// Functions from device.c
//
void NotifyFSDs(void);
void WaitForFSDs(void);
//
// Functions from devload.c
//
extern BOOL StartDriver(LPTSTR RegPath, LPTSTR PnpId, DWORD LoadOrder, CARD_SOCKET_HANDLE hSock);
extern BOOL CallTapiDeviceChange(HKEY hActiveKey, LPCTSTR DevName, BOOL bDelete);
extern VOID StartDeviceNotify(LPTSTR DevName, BOOL bNew);
extern HMODULE v_hTapiDLL;
CARD_CLIENT_HANDLE v_hPcmcia;
HANDLE v_hPcmciaDll;
REGISTERCLIENT pfnRegisterClient;
GETFIRSTTUPLE pfnGetFirstTuple;
GETNEXTTUPLE pfnGetNextTuple;
GETTUPLEDATA pfnGetTupleData;
GETSTATUS pfnGetStatus;
SYSTEMPOWER pfnSystemPower;
BOOL IsCardInserted(CARD_SOCKET_HANDLE hSock);
typedef struct _QUERY_NAME_CONTEXT {
LPTSTR PnpId;
UCHAR DevType;
CARD_SOCKET_HANDLE hSock;
} QUERY_NAME_CONTEXT, * PQUERY_NAME_CONTEXT;
typedef LPTSTR (*PFN_INSTALL_DRIVER)(LPTSTR, LPTSTR, DWORD);
//
// Thread to query the user for the name of the driver for
// an unrecognized pccard, call its Install_Driver function and
// start it.
//
DWORD
QueryDriverNameThread(
IN PVOID ThreadContext
)
{
PQUERY_NAME_CONTEXT pContext = (PQUERY_NAME_CONTEXT)ThreadContext;
HMODULE hInstallDll;
PFN_INSTALL_DRIVER pfnInstall;
LPTSTR RegPath = NULL;
GETDRIVERNAMEPARMS GDNP;
if (!IsCardInserted(pContext->hSock)) {
goto qdnt_exit;
}
GDNP.PCCardType = (DWORD)pContext->DevType;
GDNP.Socket = (DWORD)pContext->hSock.uSocket;
//
// Get this unrecognized card's device driver name.
//
if (!CallGetDriverName(NULL, &GDNP)) {
DEBUGMSG(ZONE_PCMCIA, (TEXT("DEVICE: CallGetDriverName failed %d\r\n"),
GetLastError()));
goto qdnt_exit;
}
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE: CallGetDriverName returned %s\r\n"), GDNP.DriverName));
hInstallDll = LoadDriver(GDNP.DriverName);
if (hInstallDll == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE: LoadDriver(%s) failed %d\r\n"),
GDNP.DriverName, GetLastError()));
goto qdnt_exit;
}
pfnInstall = (PFN_INSTALL_DRIVER)GetProcAddress(hInstallDll,
TEXT("Install_Driver"));
//
// Tell it to install itself
//
if (pfnInstall) {
RegPath = pfnInstall(
pContext->PnpId,
GDNP.DriverName,
sizeof(GDNP.DriverName));
}
//
// Start it
//
if (RegPath) {
StartDriver(
RegPath,
pContext->PnpId,
MAX_LOAD_ORDER+1,
pContext->hSock);
}
FreeLibrary(hInstallDll);
qdnt_exit:
LocalFree(pContext->PnpId);
LocalFree(pContext);
return 0;
} // QueryDriverNameThread
//
// Function to start a thread to query the user for the name of the driver for
// an unrecognized pccard.
//
VOID
QueryDriverName(
LPTSTR PnpId,
UCHAR DevType,
CARD_SOCKET_HANDLE hSock
)
{
HANDLE hThd;
LPTSTR pPnpId;
PQUERY_NAME_CONTEXT pContext;
DWORD cExtra;
pContext = LocalAlloc(LPTR, sizeof(QUERY_NAME_CONTEXT));
if (pContext == NULL) {
return;
}
cExtra = (hSock.uFunction > 0) ? 3 : 1;
pPnpId = LocalAlloc(LPTR, (_tcslen(PnpId) + cExtra) * sizeof(TCHAR));
if (pPnpId == NULL) {
LocalFree(pContext);
return;
}
_tcscpy(pPnpId, PnpId);
//
// Additional functions will have a "-n" appended to their PnpId where
// 'n' is the function number. This is so we can have a PnpId registry
// entry for each function.
//
if (hSock.uFunction > 0) {
cExtra = _tcslen(pPnpId);
pPnpId[cExtra] = (TCHAR) '-';
pPnpId[cExtra+1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
pPnpId[cExtra+2] = (TCHAR) 0;
}
pContext->PnpId = pPnpId;
pContext->DevType = DevType;
pContext->hSock = hSock;
hThd = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)&QueryDriverNameThread,
(LPVOID) pContext, 0, NULL);
if (hThd != NULL) {
CloseHandle(hThd);
} else {
LocalFree(pPnpId);
LocalFree(pContext);
}
} // QueryDriverName
//
// RunDetectors - Function to call the detection modules under the key
// HLM\Drivers\PCMCIA\Detect and return the key name under HLM\Drivers\PCMCIA
// for the device driver to load (will be passed to LoadPCCardDriver), or return
// NULL if none of the detection modules recognizes the card.
// The names of the keys under HLM\Drivers\PCMCIA\Detect are actually numbers to
// allow a definite ordering of the detection modules.
//
LPTSTR
RunDetectors(
CARD_SOCKET_HANDLE hSock,
UCHAR DevType,
LPTSTR StrBuf,
DWORD StrLen
)
{
HKEY hDetectKey;
HKEY hDetectMod;
PFN_DETECT_ENTRY pfnDetectEntry;
TCHAR DetectDll[DEVDLL_LEN];
TCHAR DetectEntry[DEVENTRY_LEN];
LPTSTR DeviceKey;
DWORD status;
DWORD ValLen;
DWORD ValType;
DWORD NumDetectKeys;
DWORD RegEnum;
DWORD DetectOrder;
HMODULE hDetectDll;
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
DEVLOAD_DETECT_KEY,
0,
0,
&hDetectKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: RegOpenKeyEx(%s) returned %d\r\n"),
DEVLOAD_DETECT_KEY, status));
return FALSE;
}
//
// See how many detection modules there are
//
RegEnum = sizeof(DetectDll);
status = RegQueryInfoKey(
hDetectKey,
DetectDll, // class name buffer (lpszClass)
&RegEnum, // ptr to length of class name buffer (lpcchClass)
NULL, // reserved
&NumDetectKeys, // ptr to number of subkeys (lpcSubKeys)
&ValType, // ptr to longest subkey name length (lpcchMaxSubKeyLen)
&ValLen, // ptr to longest class string length (lpcchMaxClassLen)
&DetectOrder, // ptr to number of value entries (lpcValues)
&DetectOrder, // ptr to longest value name length (lpcchMaxValueNameLen)
&ValLen, // ptr to longest value data length (lpcbMaxValueData)
NULL, // ptr to security descriptor length
NULL); // ptr to last write time
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: RegQueryInfoKey() returned %d.\r\n"),
status));
goto rd_end;
}
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!RunDetectors: %d detection modules\r\n"), NumDetectKeys));
//
// Call the detection modules in numeric order. (The key names are numbers).
//
DetectOrder = 0;
while (NumDetectKeys) {
//
// First check if the user yanked the card.
//
if (IsCardInserted(hSock) == FALSE) {
goto rd_end;
}
//
// Find the next detection module
//
wsprintf(DetectDll, TEXT("%02d"), DetectOrder); // format key name
status = RegOpenKeyEx(hDetectKey, DetectDll, 0, 0, &hDetectMod);
if (status) {
goto rd_next_detector1;
}
NumDetectKeys--;
//
// Get the detection module's DLL name
//
ValLen = sizeof(DetectDll);
status = RegQueryValueEx(
hDetectMod,
DEVLOAD_DLLNAME_VALNAME,
NULL,
&ValType,
(PUCHAR)&DetectDll,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: RegQueryValueEx(%d\\DetectDll) returned %d\r\n"),
DetectOrder, status));
goto rd_next_detector;
}
//
// Get the detection module's entrypoint
//
ValLen = sizeof(DetectEntry);
status = RegQueryValueEx(
hDetectMod,
DEVLOAD_ENTRYPOINT_VALNAME,
NULL,
&ValType,
(PUCHAR)DetectEntry,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: RegQueryValueEx(%d\\DetectEntry) returned %d\r\n"),
DetectOrder, status));
goto rd_next_detector;
}
//
// Load the detection module and get the address of its entrypoint
//
hDetectDll = LoadDriver(DetectDll);
if (hDetectDll == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: LoadLibrary(%s) failed %d\r\n"),
DetectDll, GetLastError()));
goto rd_next_detector;
}
pfnDetectEntry = (PFN_DETECT_ENTRY) GetProcAddress(hDetectDll, DetectEntry);
if (pfnDetectEntry == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!RunDetectors: GetProcAddr(%s, %s) failed %d\r\n"),
DetectDll, DetectEntry, GetLastError()));
FreeLibrary(hDetectDll);
goto rd_next_detector;
}
//
// Finally, call the detection module's entrypoint
//
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!RunDetectors: calling %d:%s:%s\r\n"),
DetectOrder, DetectDll, DetectEntry));
__try {
DeviceKey = (pfnDetectEntry)(hSock, DevType, StrBuf, StrLen);
} __except (EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!RunDetectors: faulted in %s:%s, continuing\r\n"),
DetectDll, DetectEntry));
DeviceKey = NULL;
}
FreeLibrary(hDetectDll);
if (DeviceKey) {
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!RunDetectors: %d:%s:%s returned %s\r\n"),
DetectOrder, DetectDll, DetectEntry, DeviceKey));
RegCloseKey(hDetectKey);
RegCloseKey(hDetectMod);
return DeviceKey;
}
rd_next_detector:
RegCloseKey(hDetectMod);
rd_next_detector1:
DetectOrder++;
}
rd_end:
RegCloseKey(hDetectKey);
return NULL;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -