📄 load.c
字号:
//
if (hSock.uFunction > 0) {
ValLen = _tcslen(RegPath);
RegPath[ValLen] = (TCHAR) '-';
RegPath[ValLen+1] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
RegPath[ValLen+2] = (TCHAR) 0;
}
} else {
ValLen = _tcslen(RegPath);
_tcsncpy(RegPath + ValLen, DevName, DEVKEY_LEN - ValLen);
RegPath[DEVKEY_LEN - 1] = 0;
}
}
//
// 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_INIT|ZONE_ERROR,
(TEXT("PCMCIA:LoadPCCardDriver: RegOpenKeyEx(%s) returned %d\r\n"),
RegPath, status));
return FALSE;
}
// Handle the interrupt pending bit is bad case
if (pLsock != NULL) {
ValLen = sizeof(intrpend);
status = RegQueryValueEx(
hDevKey,
DEVLOAD_INTRPEND_VALNAME,
NULL,
&ValType,
(PUCHAR)&intrpend,
&ValLen);
if (status == ERROR_SUCCESS && ValType == DEVLOAD_INTRPEND_VALTYPE && intrpend != 0)
pLsock->fFlags |= LOG_SOCK_FLAG_NO_INTR_ACK;
}
//
// 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) {
_tcsncpy(PnpMFCId, PnpId, DEVKEY_LEN - 1);
PnpMFCId[DEVKEY_LEN - 1] = 0;
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 {
if (ValLen >= DEVKEY_LEN - 5)
ValLen = DEVKEY_LEN - 6;
_tcscpy(PnpMFCId + ValLen, L"-DEV");
PnpMFCId[ValLen+4] = (TCHAR) '0' + (TCHAR) hSock.uFunction;
PnpMFCId[ValLen+5] = (TCHAR) 0;
}
}
RegCloseKey(hDevKey);
{
REGINI reg[4];
DWORD dwBusType=PCMCIABus;
TCHAR tBuf[] = DEVLOAD_SOCKET_VALNAME TEXT("\0") DEVLOAD_PNPID_VALNAME TEXT("\0") DEVLOAD_REPARMS_VALNAME TEXT("\0");
reg[0].lpszVal = DEVLOAD_SOCKET_VALNAME;
reg[0].dwType = DEVLOAD_SOCKET_VALTYPE;
reg[0].pData = (PBYTE) &hSock;
reg[0].dwLen = sizeof(hSock);
reg[1].lpszVal = DEVLOAD_PNPID_VALNAME;
reg[1].dwType = DEVLOAD_PNPID_VALTYPE;
reg[1].pData = (PBYTE) PnpMFCId;
reg[1].dwLen = (_tcslen(PnpMFCId) + 1) * sizeof(TCHAR);
reg[2].lpszVal = DEVLOAD_REPARMS_VALNAME;
reg[2].dwType = DEVLOAD_REPARMS_VALTYPE;
reg[2].pData = (PBYTE) tBuf;
reg[2].dwLen = sizeof(tBuf);
reg[3].lpszVal = DEVLOAD_INTERFACETYPE_VALNAME;
reg[3].dwType = DEVLOAD_INTERFACETYPE_VALTYPE;
reg[3].pData = (PBYTE) &dwBusType;
reg[3].dwLen = sizeof(dwBusType);
if (pLsock) {
DEBUGCHK(RegPath != NULL);
pLsock->hDriver = ActivateDeviceEx(RegPath, ®[0], sizeof(reg)/sizeof(reg[0]), NULL);
if(pLsock->hDriver == NULL) {
DEBUGMSG(ZONE_INIT || ZONE_ERROR,
(_T("PCMCIA:LoadPCCardDriver: ActivateDeviceEx('%s') failed %d\r\n"),
RegPath, GetLastError()));
return FALSE;
}
}
}
return TRUE;
}
ValLen = sizeof(DevDll);
status = RegQueryValueEx(
hDevKey,
DEVLOAD_DLLNAME_VALNAME,
NULL,
&ValType,
(PUCHAR)DevDll,
&ValLen);
RegCloseKey(hDevKey);
if (status != ERROR_SUCCESS) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("PCMCIA: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_INIT|ZONE_ERROR,
(TEXT("PCMCIA:LoadPCCardDriver: LoadDriver(%s) failed %d\r\n"),
DevDll, GetLastError()));
return TRUE;
}
pfnEntry = (PFN_DEV_ENTRY) GetProcAddress(hDevDll, DevEntry);
if (pfnEntry == NULL) {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("PCMCIA: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_INIT,
(TEXT("PCMCIA:LoadPCCardDriver: Calling %s:%s. socket handle = %d %d\r\n"),
DevDll, DevEntry, hSock.uSocket, hSock.uFunction));
try {
(pfnEntry)(RegPath);
} except (EXCEPTION_EXECUTE_HANDLER) {
RETAILMSG(1, (TEXT("!PCMCIA:LoadPCCardDriver: entrypoint (%s:%s) faulted!\n"),
DevDll, DevEntry));
}
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.
//
static VOID
FindPCCardDriver(
CARD_SOCKET_HANDLE hSock,
LPTSTR PnpId
)
{
PPHYS_SOCKET pPsock = &v_Sockets[hSock.uSocket];
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, 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 = CardGetFirstTuple(pParms);
if (status == CERR_SUCCESS) {
if (hSock.uFunction > 0) {
status = CardGetNextTuple(pParms);
if (status != CERR_SUCCESS) {
status = CardGetFirstTuple(pParms);
}
}
if (status == CERR_SUCCESS) {
pTuple = (PCARD_DATA_PARMS)buf;
pTuple->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
pTuple->uTupleOffset = 0;
status = CardGetTupleData(pTuple);
if (status == CERR_SUCCESS) {
pData = buf + sizeof(CARD_DATA_PARMS);
DevType = *pData;
} else {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("PCMCIA:FindPCCardDriver: CardGetTupleData returned %d\r\n"), status));
}
}
} else {
DEBUGMSG(ZONE_INIT|ZONE_ERROR,
(TEXT("PCMCIA:FindPCCardDriver: CardGetFirstTuple returned %d\r\n"), status));
}
DevKeyName = RunDetectors(hSock, DevType, (LPTSTR)buf, sizeof(buf)/sizeof(TCHAR));
EnterCriticalSection(&v_DetectCrit);
if (pPsock->DetectState >= DETECT_REDO) {
LeaveCriticalSection(&v_DetectCrit);
return;
}
LeaveCriticalSection(&v_DetectCrit);
if (DevKeyName) {
if (LoadPCCardDriver(hSock, PnpId, DevKeyName, NULL)) {
return;
}
} else {
QueryDriverName(PnpId, DevType, hSock); // unrecognized card inserted,
// ask user for driver name.
}
return;
} // FindPCCardDriver
static DWORD
FindDriversThread (
LPVOID arg
)
{
PPHYS_SOCKET pPsock = (PPHYS_SOCKET) arg;
CARD_SOCKET_HANDLE hSock = pPsock->pLsock->hSock;
PLOG_SOCKET pLsock;
UINT i;
FDT_begin:
for (i = 0; i < pPsock->cFunctions; i++) {
hSock.uFunction = i;
pLsock = I_FindSocket(hSock);
if (pLsock == NULL) {
DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:FindDriversThread no logical socket for F%d\n"), i));
} else {
FindPCCardDriver(pLsock->hSock, pPsock->pDevId);
}
EnterCriticalSection(&v_DetectCrit);
if (pPsock->DetectState == DETECT_REDO) {
pPsock->DetectState = DETECT_PROG;
LeaveCriticalSection(&v_DetectCrit);
goto FDT_begin;
} else if (pPsock->DetectState == DETECT_QUIT) {
pPsock->DetectState = DETECT_NONE;
LeaveCriticalSection(&v_DetectCrit);
goto FDT_end;
}
LeaveCriticalSection(&v_DetectCrit);
}
EnterCriticalSection(&v_DetectCrit);
if (pPsock->DetectState == DETECT_REDO) {
pPsock->DetectState = DETECT_PROG;
LeaveCriticalSection(&v_DetectCrit);
goto FDT_begin;
} else {
pPsock->DetectState = DETECT_NONE;
}
LeaveCriticalSection(&v_DetectCrit);
FDT_end:
pPsock->fFlags &= ~PHYS_SOCK_FLAG_ACTIVE;
//
// If no clients are using this card, shut down power to
// the PCMCIA adapter, until a configuration is requested.
//
PcmciaPowerOff(
hSock.uSocket,
FALSE,
(CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
// Invalidate the thread handle so that the callback thread knows we're done;
// this is important for when the card is removed.
pPsock->hLoad = NULL;
return 0;
}
VOID
CardServLoadDriver (
UINT8 uSocket
)
{
PPHYS_SOCKET pPsock = &v_Sockets[uSocket];
PDCARD_SOCKET_STATE State;
HANDLE hThd;
CARD_SOCKET_HANDLE hSock;
int i;
DEBUGMSG(ZONE_FUNCTION, (TEXT("PCMCIA:CardServLoadDriver on socket %d\n"), uSocket));
DEBUGCHK(pPsock->hLoad == NULL);
DEBUGCHK(pPsock->pDevId == NULL);
//
// If the socket is a low power socket, then skip
// the battery check
//
if (PDCardGetSocket(uSocket, &State) != CERR_SUCCESS) {
return;
}
if (!(State.fSocketCaps & SOCK_CAP_LOW_VOLT)) {
//
// If the device is on battery power, query the
// user before applying power to the PC card
//
PcmciaPowerOff(uSocket, TRUE, (CARD_CLIENT_HANDLE)CARDSERV_CLIENT_HANDLE);
if (!BatteryCheck(uSocket)) {
// choose not to power the socket - remove insertion callbacks
// Kill resuming flag (CE_CARD_INSERTION would normally do this for us)
v_Sockets[uSocket].fFlags &= ~PHYS_SOCK_FLAG_RESUMING;
return;
}
}
v_Sockets[uSocket].fFlags |= PHYS_SOCK_FLAG_ACTIVE;
PcmciaPowerOn(uSocket);
//
// Compute card's device ID
//
i = CreateFunctions(uSocket);
if (i == 0) {
DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:CardServLoadDriver no functions found\n")));
return;
}
if (CreateDeviceID(uSocket, FALSE) != CERR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("PCMCIA:CardServLoadDriver cannot create deviceID\n")));
return;
}
DEBUGCHK(pPsock->pDevId != NULL);
hSock.uSocket = uSocket;
hSock.uFunction = 0;
CallbackAll(CE_CARD_INSERTION, CE_CARD_INSERTION, NULL, hSock, CALLBACK_FLAG_ALL_FUNCTIONS);
EnterCriticalSection(&v_DetectCrit);
if (pPsock->DetectState != DETECT_NONE) {
pPsock->DetectState = DETECT_REDO;
LeaveCriticalSection(&v_DetectCrit);
return;
}
pPsock->DetectState = DETECT_PROG;
LeaveCriticalSection(&v_DetectCrit);
hThd = CreateThread(0, 0, FindDriversThread, (LPVOID) pPsock, 0, (LPDWORD) &pPsock->hLoad);
if (!hThd) {
DEBUGMSG(ZONE_WARNING, (TEXT("PCMCIA:CardServLoadDriver cannot create a driver loading thread\n")));
return;
}
CeSetThreadPriority(hThd, g_LoaderPrio);
CloseHandle(hThd);
// Driver will eventually get loaded and register itself.
// Now we can proceed with queueing callbacks.
return;
}
VOID
CardServFreeDriver (
UINT8 uSocket
)
{
PLOG_SOCKET pLsock;
HANDLE hDev;
DEBUGMSG(ZONE_CALLBACK|ZONE_FUNCTION, (TEXT("PCMCIA:CardServFreeDriver sock %d\n"), uSocket));
// If hLoad is invalid, then the load thread is done
// and the wait will fail immediately; otherwise, the wait will
// block until the load thread completes. The load thread
// invalidates hLoad just before it exits.
WaitForSingleObject(v_Sockets[uSocket].hLoad, INFINITE);
DEBUGCHK(v_Sockets[uSocket].hLoad == NULL);
EnterCriticalSection(&v_SocketCrit);
pLsock = v_Sockets[uSocket].pLsock;
while (pLsock) {
hDev = pLsock->hDriver;
if (hDev) {
pLsock->hDriver = NULL;
LeaveCriticalSection(&v_SocketCrit);
DEBUGMSG(ZONE_CALLBACK, (TEXT("PCMCIA deactivating sock %d func %d\n"),
pLsock->hSock.uSocket, pLsock->hSock.uFunction));
DeactivateDevice(hDev);
EnterCriticalSection(&v_SocketCrit);
pLsock = v_Sockets[uSocket].pLsock;
} else
pLsock = pLsock->Next;
}
LeaveCriticalSection(&v_SocketCrit);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -