📄 sdclient.cpp
字号:
SD_API_STATUS CSDBusDriver::GetCustomRegPath(PSDCARD_DEVICE_CONTEXT pDevice,
LPTSTR pPath,
DWORD cchPath,
BOOL BasePath)
{
SD_PARSED_REGISTER_CID ParsedRegisters; // parsed registers
SD_API_STATUS status = SD_API_STATUS_SUCCESS; // intermediate status
PREFAST_DEBUGCHK(pDevice);
DEBUGCHK(pPath);
// for Memory or MMC get the CID
if ( (Device_SD_Memory == pDevice->DeviceType) ||
(Device_MMC == pDevice->DeviceType) ) {
// get the parsed CID registers
status = SDCardInfoQuery__X((SD_DEVICE_HANDLE)pDevice,
SD_INFO_REGISTER_CID,
&ParsedRegisters,
sizeof(ParsedRegisters));
if (SD_API_SUCCESS(status)) {
// build up the string
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\CID-%d-%c%c-%c%c%c%c%c"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
ParsedRegisters.ManufacturerID,
(TCHAR)ParsedRegisters.OEMApplicationID[0],
(TCHAR)ParsedRegisters.OEMApplicationID[1],
(TCHAR)ParsedRegisters.ProductName[0],
(TCHAR)ParsedRegisters.ProductName[1],
(TCHAR)ParsedRegisters.ProductName[2],
(TCHAR)ParsedRegisters.ProductName[3],
(TCHAR)ParsedRegisters.ProductName[4]);
DEBUGCHK(SUCCEEDED(hr));
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom MMC/SD path: %s \n"),pPath));
}
}
else if (Device_SD_IO == pDevice->DeviceType) {
if (BasePath) {
// build the custom registry path for the card as a whole
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID);
DEBUGCHK(SUCCEEDED(hr));
} else {
// build the custom registry path for the SDIO card function
HRESULT hr = StringCchPrintf(pPath, cchPath, TEXT("%s\\MANF-%04X-CARDID-%04X-FUNC-%d"),
SDCARD_CUSTOM_DEVICE_REG_PATH,
pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->ManufacturerID,
pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CardID,
pDevice->SDCardInfo.SDIOInformation.Function);
DEBUGCHK(SUCCEEDED(hr));
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: built custom SDIO path: %s \n"),pPath));
}
else {
DEBUG_ASSERT(FALSE);
status = SD_API_STATUS_INVALID_PARAMETER;
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDLoadDevice - load the associated device driver
// Input: pDevice - the device instance requiring it's device driver to be loaded
// Output:
// Notes:
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::SDLoadDevice(PSDCARD_DEVICE_CONTEXT pDevice)
{
TCHAR loadPath[MAX_KEY_PATH_LENGTH]; // string buffer
TCHAR keyString[MAX_KEY_NAME_LENGTH]; // key string for value string
BOOLEAN deviceFound = FALSE; // device found flag
SD_API_STATUS status; // intermediate status
HKEY hKey; // the key
PREFAST_DEBUGCHK(pDevice);
// clear out the device specific context, the device is
// now going to be loaded
pDevice->pDeviceContext = NULL;
// get the custom path for the card or function
status = GetCustomRegPath(pDevice, loadPath, dim(loadPath), FALSE);
if (!SD_API_SUCCESS(status)) {
return status;
}
// attempt to open the path
if ( (RegOpenKeyEx(HKEY_LOCAL_MACHINE, loadPath, 0, KEY_ALL_ACCESS,
&hKey) == ERROR_SUCCESS) ) {
RegCloseKey(hKey);
deviceFound = TRUE;
} else {
// no CUSTOM driver path was found so set the default path
if (Device_SD_Memory == pDevice->DeviceType) {
// set the default load path for SD Memory Devices
wcscpy(loadPath, SDCARD_SDMEMORY_CLASS_REG_PATH);
deviceFound = TRUE;
} else if (Device_MMC == pDevice->DeviceType) {
// set the default load path for MMC devices
wcscpy(loadPath, SDCARD_MMC_CLASS_REG_PATH);
deviceFound = TRUE;
} else if (Device_SD_IO == pDevice->DeviceType) {
if (SD_IO_NON_STANDARD_DEVICE_CODE == pDevice->SDCardInfo.SDIOInformation.DeviceCode) {
// can't support this device, it has the non-standard device code and the registry does not
// contain the settings for the driver
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: SDIO Device class is of type UNKNOWN, no custom driver found at %s\n"), loadPath));
} else {
// put back in the default device code reg path
HRESULT hr = StringCchPrintf(loadPath, dim(loadPath),
TEXT("%s\\%d"),SDCARD_SDIO_CLASS_REG_PATH,
pDevice->SDCardInfo.SDIOInformation.DeviceCode);
DEBUGCHK(SUCCEEDED(hr));
deviceFound = TRUE;
}
}
}
if (deviceFound) {
CReg regLoadPath(HKEY_LOCAL_MACHINE, loadPath);
if ( !regLoadPath.IsOK() ||
!regLoadPath.ValueSZ(DEVLOAD_DLLNAME_VALNAME, keyString, dim(keyString) * sizeof(*keyString)) ) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to get DLL name in path : %s \n"), loadPath));
return SD_API_STATUS_NO_SUCH_DEVICE;
}
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDBusDriver: Loading Driver : %s \n"),keyString));
// load the DLL
// we load it so we can save the module handle and pass it to the client driver
// so it can register its debug zones
pDevice->hDriver = LoadDriver(keyString);
if (pDevice->hDriver == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to load driver DLL : %s \n"), keyString));
return SD_API_STATUS_NO_SUCH_DEVICE;
}
// mark the slot as ready
PSDBUS_HC_SLOT_CONTEXT pSlot = pDevice->pSlot;
pSlot->SlotState = Ready;
PSDBUS_HC_CONTEXT pHostController = pSlot->pHostController;
DEBUGCHK(pDevice->pDeviceFolder == NULL);
status = m_sdBusEnum.ActivateChild(loadPath,
pHostController->dwHCNumber,
pSlot->SlotIndex,
pDevice->SDCardInfo.SDIOInformation.Function,
pDevice, &pDevice->pDeviceFolder);
if ( (pDevice->DeviceType == Device_SD_IO) &&
pDevice->SDCardInfo.SDIOInformation.fWUS ) {
// This SDIO function supports wake up. Tell the host to
// allow waking on SDIO interrupts if the client has a
// registry entry enabling this. It is okay if the host fails
// this call.
BOOL fWakeOnSDIOInterrupts =
regLoadPath.ValueDW(SDCARD_WAKE_ON_SDIO_INTERRUPTS_VALNAME);
if (fWakeOnSDIOInterrupts) {
SD_API_STATUS statusHandler =
pHostController->pSlotOptionHandler(pHostController,
pSlot->SlotIndex, SDHCDWakeOnSDIOInterrupts,
&fWakeOnSDIOInterrupts, sizeof(fWakeOnSDIOInterrupts));
if (!SD_API_SUCCESS(statusHandler)) {
DEBUGMSG(SDCARD_ZONE_WARN, (_T("SD: Could not enable waking on SDIO interrupts\r\n")));
}
}
}
// free the library, the previous ActivateDevice call will keep the driver loaded
FreeLibrary(pDevice->hDriver);
pDevice->hDriver = NULL;
if (!SD_API_SUCCESS(status)) {
pDevice->pSlot->SlotState = SlotInitFailed;
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: Failed to load driver with path: %s \n"), loadPath));
return status;
}
return SD_API_STATUS_SUCCESS;
}
return SD_API_STATUS_NO_SUCH_DEVICE;
}
///////////////////////////////////////////////////////////////////////////////
// SDUnloadDevice - unload the client device
// Input: pDevice - the device instance requiring it's device driver to be unloaded
// Output:
// Notes:
// returns SD_API_STATUS
///////////////////////////////////////////////////////////////////////////////
VOID CSDBusDriver::SDUnloadDevice(PSDCARD_DEVICE_CONTEXT pDevice)
{
CSDBusDriver *pBusDriver = (CSDBusDriver *)pDevice->pSystemContext; // the bus driver
LONG refcount; // reference count
ULONG maxWait; // max wait
PREFAST_DEBUGCHK(pBusDriver != NULL);
// notify the client
NotifyClient(pDevice,
SDCardEjected);
maxWait = DEFAULT_MAX_WAIT_COUNT;
// poll until all pending requests are gone
// since the slot has been marked for device removal
// all incomming requests and request in the slot queue will get rejected
// so we do not need to flush out the request queue but rather wait until request processing
// flushes them out normally
while (((refcount =
SDDCGetRefCount(((volatile SDCARD_DEVICE_CONTEXT *)pDevice))) != 0) &&
maxWait) {
DEBUGMSG(SDBUS_ZONE_DEVICE,
(TEXT("SDUnloadDevice: Device: %s has %d refcount, waitcnt:%d waiting....\n"),
SDDCGetClientName(pDevice), refcount, maxWait));
Sleep(DEFAULT_REFCOUNT_WAIT);
maxWait--;
}
if (0 == maxWait) {
DEBUG_CHECK(FALSE,
(TEXT("SDUnloadDevice: Device %s, has %d outstanding requests that cannot be completed! \n"),
SDDCGetClientName(pDevice), refcount));
}
// all requests have been flushed, deactivate the device
if (pDevice->pDeviceFolder != NULL) {
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDUnloadDevice: Deactivating Device: %s \n"),SDDCGetClientName(pDevice)));
m_sdBusEnum.DeactivateChild(pDevice->pDeviceFolder);
}
pBusDriver->DeleteClientDevice(pDevice);
DEBUGMSG(SDBUS_ZONE_DEVICE, (TEXT("SDUnloadDevice: Client Device deleted \n")));
}
///////////////////////////////////////////////////////////////////////////////
// SDRegisterClient__X - register a client device
// Input: hDevice - device handle
// pDeviceContext - device specific context allocated by driver
// pInfo - registration information
//
// Output:
// Notes:
// returns SD_API_STATUS_SUCCESS
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS SDRegisterClient__X(SD_DEVICE_HANDLE hDevice,
PVOID pDeviceContext,
PSDCARD_CLIENT_REGISTRATION_INFO pInfo)
{
SD_API_STATUS status = SD_API_STATUS_INVALID_PARAMETER; // intermediate status
CSDBusDriver *pBusDriver; // the bus driver
PSDCARD_DEVICE_CONTEXT pDevice = (PSDCARD_DEVICE_CONTEXT) hDevice;
if (!ValidateClientHandle(pDevice)) {
return SD_API_STATUS_INVALID_HANDLE;
}
if (pInfo == NULL) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDRegisterClient : Reg info is NULL!\n")));
}
else {
pBusDriver = (CSDBusDriver *)pDevice->pSystemContext;
DEBUGCHK(pBusDriver != NULL);
if (pBusDriver != NULL) {
status = pBusDriver->RegisterClientDevice(pDevice,
pDeviceContext, pInfo);
if (status != SD_API_STATUS_SUCCESS) {
DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDRegisterClient: Failed to register client 0x%08X \n"),status));
}
}
}
return status;
}
///////////////////////////////////////////////////////////////////////////////
// SDAcquireDeviceLock - acquire the synchronization lock for the device
// Input: hDevice - device handle
//
// Output:
// Notes:
// Caller must call SDReleaseDeviceLock to release the lock
///////////////////////////////////////////////////////////////////////////////
VOID SDAcquireDeviceLock(SD_DEVICE_HANDLE hDevice)
{
EnterCriticalSection(&(((PSDCARD_DEVICE_CONTEXT)hDevice)->DeviceCritSection));
}
///////////////////////////////////////////////////////////////////////////////
// SDReleaseDeviceLock - release the synchronization lock for the device
// Input: hDevice - device handle
//
// Output:
// Notes:
// Caller must have previously called SDAcquireDeviceLock
///////////////////////////////////////////////////////////////////////////////
VOID SDReleaseDeviceLock(SD_DEVICE_HANDLE hDevice)
{
LeaveCriticalSection(&(((PSDCARD_DEVICE_CONTEXT)hDevice)->DeviceCritSection));
}
// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -