📄 pcmcia.c
字号:
} // RunDetectors
//
// Function to start a driver in the devload manner or to LoadDriver(devdll)
// and GetProcAddress(entry) and call an entrypoint.
//
// Return FALSE only if the driver key does not exist in the registry.
//
BOOL
LoadPCCardDriver(
CARD_SOCKET_HANDLE hSock,
LPTSTR PnpId,
LPTSTR DevName
)
{
HKEY hDevKey;
PFN_DEV_ENTRY pfnEntry;
TCHAR DevDll[DEVDLL_LEN];
TCHAR DevEntry[DEVENTRY_LEN];
TCHAR RegPath[REG_PATH_LEN];
TCHAR PnpMFCId[REG_PATH_LEN];
DWORD status;
DWORD ValLen;
DWORD ValType;
HMODULE hDevDll;
//
// Format the registry path for this device.
//
_tcscpy(RegPath, s_PcmciaKey);
_tcscat(RegPath, TEXT("\\"));
if (DevName == NULL) {
_tcscat(RegPath, 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) {
ValLen = _tcslen(RegPath);
RegPath[ValLen] = (TCHAR) '-';
RegPath[ValLen+1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
RegPath[ValLen+2] = (TCHAR) 0;
}
} else {
_tcscat(RegPath, DevName);
}
//
// If a driver exists for this PNP id, then use it.
//
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegPath,
0,
0,
&hDevKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!LoadPCCardDriver: RegOpenKeyEx(%s) returned %d\r\n"),
RegPath, status));
return FALSE;
}
//
// Get the entrypoint and dll names. If the entrypoint name does not exist
// then call StartDriver which will call RegisterDevice on the driver's
// behalf.
//
ValLen = sizeof(DevEntry);
status = RegQueryValueEx(
hDevKey,
DEVLOAD_ENTRYPOINT_VALNAME,
NULL,
&ValType,
(PUCHAR)DevEntry,
&ValLen);
if (status != ERROR_SUCCESS) {
_tcscpy(PnpMFCId, PnpId);
if (hSock.uFunction > 0) {
ValLen = _tcslen(PnpMFCId);
if (ValLen > 5 && PnpMFCId[ValLen-5] == '-') {
_tcsncpy(PnpMFCId + ValLen, PnpMFCId + ValLen - 5, 5);
_tcsncpy(PnpMFCId + ValLen - 5, L"-DEV", 4);
PnpMFCId[ValLen-1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
PnpMFCId[ValLen+5] = (TCHAR) 0;
} else {
_tcscat(PnpMFCId, L"-DEV");
PnpMFCId[ValLen+4] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
PnpMFCId[ValLen+5] = (TCHAR) 0;
}
}
RegCloseKey(hDevKey);
StartDriver(RegPath, PnpMFCId, MAX_LOAD_ORDER+1, hSock);
return TRUE;
}
ValLen = sizeof(DevDll);
status = RegQueryValueEx(
hDevKey,
s_DllName_ValName,
NULL,
&ValType,
(PUCHAR)DevDll,
&ValLen);
RegCloseKey(hDevKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!LoadPCCardDriver: RegQueryValueEx(DllName) returned %d\r\n"),
status));
return TRUE;
}
//
// Load the dll, get the entrypoint's procaddr and call it.
//
hDevDll = LoadDriver(DevDll);
if (hDevDll == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!LoadPCCardDriver: LoadDriver(%s) failed %d\r\n"),
DevDll, GetLastError()));
return TRUE;
}
pfnEntry = (PFN_DEV_ENTRY) GetProcAddress(hDevDll, DevEntry);
if (pfnEntry == NULL) {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!LoadPCCardDriver: GetProcAddr(%s, %s) failed %d\r\n"),
DevDll, DevEntry, GetLastError()));
FreeLibrary(hDevDll);
return TRUE;
}
//
// It is the device driver's responsibility to call RegisterDevice.
// The following FreeLibrary will not unload the DLL if it has registered.
//
DEBUGMSG(ZONE_PCMCIA,
(TEXT("DEVICE!LoadPCCardDriver: Calling %s:%s. socket handle = %d %d\r\n"),
DevDll, DevEntry, hSock.uSocket, hSock.uFunction));
(pfnEntry)(RegPath);
FreeLibrary(hDevDll);
return TRUE;
} // LoadPCCardDriver
//
// Function to search the registry under HLM\Drivers\PCMCIA for a device driver
// for a newly inserted card. If there is no driver associated with the card's
// PNP id, then look at the card's CIS to figure out what generic device driver
// to use. If the generic driver doesn't recognize it, then see if one of the
// installable detection modules recognizes it.
//
VOID
FindPCCardDriver(
CARD_SOCKET_HANDLE hSock,
LPTSTR PnpId
)
{
DWORD status;
UCHAR buf[sizeof(CARD_DATA_PARMS) + 256];
PCARD_TUPLE_PARMS pParms;
PCARD_DATA_PARMS pTuple;
PUCHAR pData;
LPTSTR DevKeyName;
UCHAR DevType;
//
// If there is a driver for this particular card, then try it first
//
if (LoadPCCardDriver(hSock, PnpId, NULL)) {
return;
}
DevKeyName = NULL;
DevType = PCCARD_TYPE_UNKNOWN; // 0xff
//
// Find this card's device type to provide a hint to the detection modules
// (Find the second one if possible to skip a potential CISTPL_FUNCID in a
// MFCs global tuple chain)
//
pParms = (PCARD_TUPLE_PARMS)buf;
pParms->hSocket = hSock;
pParms->uDesiredTuple = CISTPL_FUNCID; // contains the device type.
pParms->fAttributes = 0;
status = pfnGetFirstTuple(pParms);
if (status == CERR_SUCCESS) {
if (hSock.uFunction > 0) {
status = pfnGetNextTuple(pParms);
if (status != CERR_SUCCESS) {
status = pfnGetFirstTuple(pParms);
}
}
if (status == CERR_SUCCESS) {
pTuple = (PCARD_DATA_PARMS)buf;
pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
pTuple->uTupleOffset = 0;
status = pfnGetTupleData(pTuple);
if (status == CERR_SUCCESS) {
pData = buf + sizeof(CARD_DATA_PARMS);
DevType = *pData;
} else {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!FindPCCardDriver: CardGetTupleData returned %d\r\n"), status));
}
}
} else {
DEBUGMSG(ZONE_PCMCIA|ZONE_ERROR,
(TEXT("DEVICE!FindPCCardDriver: CardGetFirstTuple returned %d\r\n"), status));
}
DevKeyName = RunDetectors(hSock, DevType, (LPTSTR)buf, sizeof(buf)/sizeof(TCHAR));
if (DevKeyName) {
if (LoadPCCardDriver(hSock, PnpId, DevKeyName)) {
return;
}
} else {
QueryDriverName(PnpId, DevType, hSock); // unrecognized card inserted,
// ask user for driver name.
}
return;
} // FindPCCardDriver
//
// Function to search through HLM\Drivers\Active for a matching CARD_SOCKET_HANDLE
// Return code is the device's handle. A handle of 0 indicates that no match was
// found. The active device number is copied to ActiveNum on success.
//
DWORD
FindActiveBySocket(
CARD_SOCKET_HANDLE hSock,
LPTSTR RegPath
)
{
DWORD Handle;
DWORD RegEnum;
DWORD status;
DWORD ValLen;
DWORD ValType;
LPTSTR RegPathPtr;
HKEY DevKey;
HKEY ActiveKey;
TCHAR DevNum[DEVNAME_LEN];
CARD_SOCKET_HANDLE hRegSock;
_tcscpy(RegPath, s_ActiveKey);
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegPath,
0,
0,
&ActiveKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!FindActiveBySocket: RegOpenKeyEx(%s) returned %d\r\n"),
RegPath, status));
return 0;
}
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!FindActiveBySocket: RegEnumKeyEx() returned %d\r\n"),
status));
RegCloseKey(ActiveKey);
return 0;
}
status = RegOpenKeyEx(
ActiveKey,
DevNum,
0,
0,
&DevKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!FindActiveBySocket: RegOpenKeyEx(%s) returned %d\r\n"),
DevNum, status));
goto fabs_next;
}
//
// See if the socket value matches
//
ValLen = sizeof(hRegSock);
status = RegQueryValueEx(
DevKey,
DEVLOAD_SOCKET_VALNAME,
NULL,
&ValType,
(PUCHAR)&hRegSock,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!FindActiveBySocket: RegQueryValueEx(%s\\Socket) returned %d\r\n"),
DevNum, status));
goto fabs_next;
}
//
// Is this the one the caller wants?
//
if (!((hRegSock.uSocket == hSock.uSocket) &&
(hRegSock.uFunction == hSock.uFunction))) {
goto fabs_next; // No.
}
ValLen = sizeof(Handle);
status = RegQueryValueEx(
DevKey,
DEVLOAD_HANDLE_VALNAME,
NULL,
&ValType,
(PUCHAR)&Handle,
&ValLen);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!FindActiveBySocket: RegQueryValueEx(%s\\Handle) returned %d\r\n"),
DevNum, status));
//
// We found the device, but can't get its handle.
//
Handle = 0;
} else {
//
// Format the registry path
//
RegPathPtr = RegPath + _tcslen(RegPath);
RegPathPtr[0] = (TCHAR)'\\';
RegPathPtr++;
_tcscpy(RegPathPtr, DevNum);
}
RegCloseKey(ActiveKey);
RegCloseKey(DevKey);
return Handle;
fabs_next:
RegCloseKey(DevKey);
RegEnum++;
} // while
} // FindActiveBySocket
//
// Function to delete all the values under an active key that we were unable
// to delete (most likely because someone else has it opened).
//
VOID
DeleteActiveValues(
LPTSTR ActivePath
)
{
HKEY hActiveKey;
DWORD status;
//
// Open active key
//
status = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
ActivePath,
0,
0,
&hActiveKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ACTIVE|ZONE_ERROR,
(TEXT("DEVICE!DeleteActiveValues: RegOpenKeyEx(%s) returned %d\r\n"),
ActivePath, status));
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -