📄 pcmcia.c
字号:
}
//
// Delete some values so we no longer mistake it for a valid active key.
//
RegDeleteValue(hActiveKey, DEVLOAD_CLIENTINFO_VALNAME);
RegDeleteValue(hActiveKey, DEVLOAD_HANDLE_VALNAME);
RegDeleteValue(hActiveKey, DEVLOAD_DEVNAME_VALNAME);
RegDeleteValue(hActiveKey, DEVLOAD_DEVKEY_VALNAME);
RegDeleteValue(hActiveKey, DEVLOAD_PNPID_VALNAME);
RegDeleteValue(hActiveKey, DEVLOAD_SOCKET_VALNAME);
RegCloseKey(hActiveKey);
} // DeleteActiveValues
//
// Function to DeregisterDevice a device and remove its active key and announce
// the device's removal to the system.
//
BOOL
I_DeactivateDevice(
HANDLE hDevice,
LPTSTR ActivePath
)
{
HKEY hActiveKey;
DWORD status;
DWORD ValLen;
DWORD ValType;
TCHAR DevName[DEVNAME_LEN];
BOOL bAnnounce;
bAnnounce = FALSE;
//
// Open its active key in the registry
//
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
ActivePath,
0,
0,
&hActiveKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!I_DeactivateDevice: RegOpenKeyEx(%s) returned %d\r\n"),
ActivePath, status));
} else {
// We're going to need the name
ValLen = sizeof(DevName);
status = RegQueryValueEx(
hActiveKey,
DEVLOAD_DEVNAME_VALNAME,
NULL,
&ValType,
(PUCHAR)DevName,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!I_DeactivateDevice: RegQueryValueEx(DevName) returned %d\r\n"),
status));
RegCloseKey(hActiveKey);
} else {
bAnnounce = TRUE;
}
CallTapiDeviceChange(hActiveKey, DevName, TRUE); // bDelete == TRUE
RegCloseKey(hActiveKey);
}
#ifndef TARGET_NT
DeregisterDevice((HANDLE)hDevice);
#else
{ extern BOOL FS_DeregisterDevice(HANDLE);
FS_DeregisterDevice((HANDLE)hDevice);
}
#endif // TARGET_NT
status = RegDeleteKey(HKEY_LOCAL_MACHINE, ActivePath);
if (status) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,(TEXT("DEVICE!I_DeactivateDevice: RegDeleteKey failed %d\n"), status));
DeleteActiveValues(ActivePath);
}
//
// Announce to the world after the key has been deleted
//
if (bAnnounce) {
StartDeviceNotify(DevName, FALSE);
}
return TRUE;
}
//
// Returns TRUE if there is a card inserted in the specified socket
//
BOOL
IsCardInserted(
CARD_SOCKET_HANDLE hSock
)
{
STATUS status;
CARD_STATUS CardStatus;
CardStatus.hSocket = hSock;
status = pfnGetStatus(&CardStatus);
if (status == CERR_SUCCESS) {
if (CardStatus.fCardState & EVENT_MASK_CARD_DETECT) {
return TRUE;
}
} else {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!IsCardInserted: CardGetStatus returned %d\r\n"), status));
}
return FALSE;
} // IsCardInserted
//
// This is the PCMCIA callback function specified in CardRegisterClient.
// PCMCIA indicates card insertions and removals by calling this function.
//
STATUS PcmciaCallBack(
CARD_EVENT EventCode,
CARD_SOCKET_HANDLE hSock,
PCARD_EVENT_PARMS pParms
)
{
#define MAX_UNLOAD_DEVICES 32
DWORD DevHandle;
DWORD n;
TCHAR ActivePath[REG_PATH_LEN];
switch (EventCode) {
case CE_CARD_INSERTION:
//
// If no key exists in the active list for this socket, then this
// insertion notice is for a newly inserted card (i.e. it is not an
// artificial insertion notice)
//
if (IsCardInserted(hSock) == TRUE) {
DevHandle = FindActiveBySocket(hSock, ActivePath);
if (DevHandle == 0) {
//
// Look in the registry for a matching PNP id or device type
// and load the corresponding DLL.
//
FindPCCardDriver(
hSock,
(LPTSTR)pParms->Parm1 /* PNP ID string */);
}
#ifdef INSTRUM_DEV
instrum_cardInserted = TRUE;
SetEvent(instrum_insertEvent);
#endif
}
break;
case CE_CARD_REMOVAL:
//
// If this is not an artificial removal notice, then DeregisterDevice the
// associated device and remove its instance from the active list.
//
if (IsCardInserted(hSock) == FALSE) {
#ifdef INSTRUM_DEV
instrum_cardInserted = FALSE;
#endif
for (n = 0; n < MAX_UNLOAD_DEVICES; n++) {
DevHandle = FindActiveBySocket(hSock, ActivePath);
if (DevHandle) {
I_DeactivateDevice((HANDLE)DevHandle, ActivePath);
} else {
break; // no more devices
}
}
}
break;
case CE_PM_RESUME:
//
// This event occurs after the forced removals due to power off and
// after the subsequent inserts have occured. The filesystem needs an
// indication at this time to know that it's safe to do pc card I/O
//
#ifndef TARGET_NT
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!PcmciaCallBack: Calling FileSystemPowerFunction(FSNOTIFY_DEVICES_ON\r\n")));
WaitForFSDs();
FileSystemPowerFunction(FSNOTIFY_DEVICES_ON);
NotifyFSDs();
#endif // TARGET_NT
break;
}
return CERR_SUCCESS;
} // PcmciaCallBack
//
// Called at end of device.exe initialization.
//
VOID
InitPCMCIA(VOID)
{
CARD_REGISTER_PARMS Parms;
#ifdef TARGET_NT
// Check the wceemuld NT device driver.
if (!check_wceemuld()) {
v_hPcmciaDll = 0;
return;
}
#endif
if (!(v_hPcmciaDll = LoadDriver(TEXT("PCMCIA.DLL")))) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("DEVICE!InitPCMCIA: Failed to load PCMCIA.DLL\r\n")));
return;
}
pfnRegisterClient = (REGISTERCLIENT) GetProcAddress(v_hPcmciaDll, TEXT("CardRegisterClient"));
pfnGetFirstTuple = (GETFIRSTTUPLE) GetProcAddress(v_hPcmciaDll, TEXT("CardGetFirstTuple"));
pfnGetNextTuple = (GETNEXTTUPLE) GetProcAddress(v_hPcmciaDll, TEXT("CardGetNextTuple"));
pfnGetTupleData = (GETTUPLEDATA) GetProcAddress(v_hPcmciaDll, TEXT("CardGetTupleData"));
pfnGetStatus = (GETSTATUS) GetProcAddress(v_hPcmciaDll, TEXT("CardGetStatus"));
pfnSystemPower = (SYSTEMPOWER) GetProcAddress(v_hPcmciaDll, TEXT("CardSystemPower"));
if ((v_hPcmciaDll == NULL) ||
(pfnRegisterClient == NULL) ||
(pfnGetFirstTuple == NULL) ||
(pfnGetNextTuple == NULL) ||
(pfnGetTupleData == NULL) ||
(pfnGetStatus == NULL)) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT,
(TEXT("DEVICE!InitPCMCIA: Failed to load PCMCIA.DLL\r\n")));
FreeLibrary(v_hPcmciaDll);
v_hPcmciaDll = NULL;
return;
}
#ifdef INSTRUM_DEV
start_instrum_thread(v_hPcmciaDll);
#endif // INSTRUM_DEV
//
// Register callback function with PCMCIA driver
//
Parms.fEventMask = EVENT_MASK_CARD_DETECT|EVENT_MASK_POWER_MGMT;
Parms.fAttributes = CLIENT_ATTR_IO_DRIVER | CLIENT_ATTR_NOTIFY_SHARED |
CLIENT_ATTR_NOTIFY_EXCLUSIVE;
v_hPcmcia = (CARD_CLIENT_HANDLE)pfnRegisterClient(PcmciaCallBack, &Parms);
if (v_hPcmcia == 0) {
DEBUGMSG(ZONE_PCMCIA|ZONE_INIT|ZONE_ERROR,
(TEXT("DEVICE!InitPCMCIA: CardRegisterClient failed %d\r\n"), GetLastError()));
return;
}
} // InitPCMCIA
void
InitTapiDeviceChange(
HKEY hActiveKey
)
{
#ifndef TARGET_NT
TCHAR DevName[DEVNAME_LEN];
DWORD ValType;
DWORD ValLen;
DWORD status;
//
// Get the device name out of its active key in the registry
//
ValLen = sizeof(DevName);
status = RegQueryValueEx(
hActiveKey,
DEVLOAD_DEVNAME_VALNAME,
NULL,
&ValType,
(PUCHAR)DevName,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!InitTapiDeviceChange: RegQueryValueEx(DevName) returned %d\r\n"),
status));
return;
}
if (CallTapiDeviceChange(hActiveKey, DevName, FALSE /* bDelete == FALSE */)) {
//
// Cause a WM_DEVICECHANGE message to be posted and CeEventHasOccurred to
// be called while we have all the information available.
//
StartDeviceNotify(DevName, TRUE);
}
#endif // TARGET_NT
} // InitTapiDeviceChange
//
// Let TAPI know about the active devices.
// Called after the whole system has initialized.
//
void InitTAPIDevices(void)
{
#ifndef TARGET_NT
DWORD RegEnum;
DWORD status;
DWORD ValLen;
HKEY ActiveKey;
HKEY ActiveDevKey;
TCHAR DevNum[DEVNAME_LEN];
TCHAR RegPath[REG_PATH_LEN];
if (v_hTapiDLL) {
return;
}
v_hTapiDLL = (HMODULE)LoadDriver(TEXT("TAPI.DLL"));
if (v_hTapiDLL == NULL) {
return;
}
//
// Walk the active device list and call InitTapiDeviceChange(ADD) for
// each one since there will be tapi devices loaded before TAPI.DLL gets
// loaded. Tapi will only get notified if there is a Tsp value in the
// device key for the active device.
//
_tcscpy(RegPath, s_ActiveKey);
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegPath,
0,
0,
&ActiveKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!InitTAPIDevices: RegOpenKeyEx(%s) returned %d\r\n"),
RegPath, status));
return;
}
RegEnum = 0;
while (1) {
ValLen = sizeof(DevNum)/sizeof(TCHAR);
status = RegEnumKeyEx(
ActiveKey,
RegEnum,
DevNum,
&ValLen,
NULL,
NULL,
NULL,
NULL);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!InitTAPIDevices: RegEnumKeyEx() returned %d\r\n"),
status));
RegCloseKey(ActiveKey);
return;
}
status = RegOpenKeyEx(
ActiveKey,
DevNum,
0,
0,
&ActiveDevKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!InitTAPIDevices: RegOpenKeyEx(%s) returned %d\r\n"),
DevNum, status));
} else {
InitTapiDeviceChange(ActiveDevKey);
RegCloseKey(ActiveDevKey);
}
RegEnum++;
} // while
#endif // TARGET_NT
} // InitTAPIDevices
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -