⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdmisc.cpp

📁 PXA27x/ MainstionIII平台下SDIO驱动完整代码 Windows CE 6.0嵌入式操作系统
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//

// Copyright (c) 2002 BSQUARE Corporation.  All rights reserved.
// DO NOT REMOVE --- BEGIN EXTERNALLY DEVELOPED SOURCE CODE ID 40973--- DO NOT REMOVE

// Miscellaneous Apis

#include <SDCardDDK.h>
#include <devload.h>
#include <SafeInt.hxx>
#include "busacc.hpp"

extern "C" {

///////////////////////////////////////////////////////////////////////////////
//  SDInitializeQueue - initialize a driver allocated request queue
//  Input:  pQueue - queue to initialize        
//  Output: 
//  Return: 
//  Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDInitializeQueue(PSD_REQUEST_QUEUE pQueue) {
    InitializeListHead(&pQueue->ListHead);
    pQueue->QueueCount = 0;
}

///////////////////////////////////////////////////////////////////////////////
//  SDQueueBusRequest - queue a request (FIFO order)
//  Input:  pQueue - queue to use
//          pRequest - request to add to queue        
//  Output: 
//  Return: 
//  Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDQueueBusRequest(PSD_REQUEST_QUEUE pQueue, PSD_BUS_REQUEST pRequest) 
{
    // insert at the tail
    InsertTailList(&pQueue->ListHead, &pRequest->ListEntry);
    pQueue->QueueCount++;
}

///////////////////////////////////////////////////////////////////////////////
//  SDRemoveEntryFromQueue - remove and entry from the queue
//  Input:  pQueue - queue to use
//          pRequest - request to be removed       
//  Output: 
//  Return: 
//  Notes:
///////////////////////////////////////////////////////////////////////////////
VOID SDRemoveEntryFromQueue(PSD_REQUEST_QUEUE pQueue, PSD_BUS_REQUEST pRequest) 
{
    // just remove the entry
    RemoveEntryList(&pRequest->ListEntry);
    pQueue->QueueCount--;
}

///////////////////////////////////////////////////////////////////////////////
//  SDDequeueBusRequest - de-queue a request (FIFO order)
//  Input:  pQueue - the queue        
//  Output: 
//  Return: the first request queued , otherwise NULL if request queue is empty 
//  Notes:
///////////////////////////////////////////////////////////////////////////////
PSD_BUS_REQUEST SDDequeueBusRequest(PSD_REQUEST_QUEUE pQueue) 
{
    PLIST_ENTRY pListEntry; // list entry

    if (IsListEmpty(&pQueue->ListHead)) {
        return NULL;
    }
    // dequeue from the head         
    pListEntry = RemoveHeadList(&pQueue->ListHead);
    DEBUG_CHECK((pQueue->QueueCount != 0), (TEXT("SDDequeueBusRequest: Queue Count is zero! \n")));
    pQueue->QueueCount--;
    return CONTAINING_RECORD(pListEntry, SD_BUS_REQUEST, ListEntry);
}

///////////////////////////////////////////////////////////////////////////////
//  SDGetCurrentRequest - Get the current request at the front of the queue
//                        but do not remove it from the queue
//  Input:  pQueue - the queue        
//  Output: 
//  Return: the current request that is at the front of the queue (FIFO orer)
//          NULL if the queue is empty
//  Notes:
///////////////////////////////////////////////////////////////////////////////
PSD_BUS_REQUEST SDGetCurrentRequest(PSD_REQUEST_QUEUE pQueue) 
{
    PLIST_ENTRY pListEntry; // list entry from head of the queue

    if (IsListEmpty(&pQueue->ListHead)) {
        return NULL;
    }
    // the current request is the first request      
    pListEntry = pQueue->ListHead.Flink;

    return CONTAINING_RECORD(pListEntry, SD_BUS_REQUEST, ListEntry);
}

///////////////////////////////////////////////////////////////////////////////
//  SDGetDeviceHandle - Get the device handle from the context passed in
//                      XXX_Init
//  Input:  InitContext - Context passed in XXX_Init
//          
//  Output: ppRegPath - registry path of device (optional)
//  Return: SD Client Device Handle or NULL on failure
//  Notes:  
//      
//      Caller must free ppRegPath using SDFreeMemory Api
///////////////////////////////////////////////////////////////////////////////
SD_DEVICE_HANDLE SDGetDeviceHandle(DWORD InitContext, PWCHAR *ppRegPath)
{
    LPCTSTR pszActivePath = (LPCTSTR) InitContext;

    DEBUGCHK(pszActivePath);

    DEBUGMSG(SDCARD_ZONE_INIT, (TEXT("SDGetDeviceHandle: ActivePath: %s \n"),
        pszActivePath));

    SD_DEVICE_HANDLE device = NULL;
    HKEY hkActive = NULL;
    LPTSTR pszDeviceKey = NULL;
    DWORD cbData;
    DWORD dwErr;

    SDBusAccess * bAccess = CreateSDBusAcess(pszActivePath);
    if (bAccess == NULL ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("CreateSDBusAcess: Failed to createSDBusAccess on %s; %d \n"), 
            pszActivePath, GetLastError()));
        goto EXIT;
    }

    dwErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pszActivePath,
        0, 0, &hkActive);
    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetDeviceHandle: Failed to open path %s; %d \n"), 
            pszActivePath, dwErr));
        goto EXIT;
    }

    dwErr = RegQueryValueEx(hkActive, DEVLOAD_DEVKEY_VALNAME, 0, NULL, NULL, &cbData);
    if ( (dwErr != ERROR_SUCCESS) || (cbData == 0) ) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetDeviceHandle: Failed to find real key in active path %s \n"),
            pszActivePath));
        goto EXIT;
    }

    pszDeviceKey = (LPTSTR) SDAllocateMemoryWithTag(cbData, 0);
    if (pszDeviceKey == NULL) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetDeviceHandle: Failed to allocate reg path \n")));
        goto EXIT;
    }

    dwErr = RegQueryValueEx(hkActive, DEVLOAD_DEVKEY_VALNAME, 0, NULL, 
        (PBYTE) pszDeviceKey, &cbData);
    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetDeviceHandle: Failed to find real key in active path %s \n"),
            pszActivePath));
        goto EXIT;
    }
    pszDeviceKey[(cbData / sizeof(TCHAR)) - 1] = 0;

    cbData = sizeof(device);
    dwErr = RegQueryValueEx(hkActive, DEVLOAD_CLIENTINFO_VALNAME, 0, NULL, 
        (PBYTE) &device, &cbData);
    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDGetDeviceHandle: Failed to get ClientInfo key in active path %s \n"),
            pszActivePath));
        goto EXIT;
    }

    DEBUG_CHECK((0 != device), (TEXT("SDGetDeviceHandle: Device Handle from registery is NULL!\n")));

EXIT:

    if (hkActive) RegCloseKey(hkActive);

    if (pszDeviceKey) {
        if (ppRegPath && device) {
            // Only return string if we are returning success.
            *ppRegPath = pszDeviceKey;
        }
        else {
            SDFreeMemory(pszDeviceKey);
        }
    }

    return device;
}



///////////////////////////////////////////////////////////////////////////////
//  SDGetRegPathFromInitContext - Get the real device registry path from the context 
//                                passed in XXX_Init
//  Input:  pActivePath - device active path
//          Length      - length in bytes of pRegPath
//  Output: pRegPath - caller supplied storage for the registry path
//  Return: win32 error
//  Notes:  
//      For streams drivers the InitContext passed in the XXX_Init entry point
//      is the active registry path and not the real path of the device.
//      This function can be used to retrieve the real path
//
///////////////////////////////////////////////////////////////////////////////
DWORD SDGetRegPathFromInitContext(PWCHAR pActivePath, PWCHAR pRegPath, ULONG Length)
{
    DWORD              win32Status;     // win32 status
    HKEY               hKey;            // reg key handle
    ULONG              dataSize;        // size of key

    if ((win32Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
        pActivePath,
        0,
        KEY_ALL_ACCESS,
        &hKey)) != ERROR_SUCCESS) {
            DEBUGMSG(SDCARD_ZONE_ERROR, (TEXT("SDCard: Failed to open key; %d \n"), win32Status));
            return win32Status;
        }


        dataSize = Length;

        // retrieve the real reg path 
        win32Status = RegQueryValueEx(hKey, 
            DEVLOAD_DEVKEY_VALNAME, 
            0, 
            NULL, 
            (PUCHAR)pRegPath, 
            &dataSize);

        // don't need the active key anymore
        RegCloseKey(hKey);

        return win32Status;

}


// Shifts pbInput down by dwBitOffset.
static
VOID
ShiftBytes(PBYTE pbInput, ULONG cbInput, DWORD dwBitOffset, PBYTE pbOutput) 
{
    PREFAST_DEBUGCHK(pbInput);
    PREFAST_DEBUGCHK(pbOutput);

    DWORD dwByteIndex = dwBitOffset / 8;
    dwBitOffset %= 8;

    DWORD dwRemainderShift = 8 - dwBitOffset;

    // Only copy 4 bytes max.
    DWORD dwEndIndex = min(dwByteIndex + sizeof(DWORD), cbInput);
    DWORD dwCurrOutputIndex = 0;
    while (dwByteIndex < dwEndIndex) {
        DEBUGCHK(dwCurrOutputIndex < sizeof(DWORD));
        DEBUGCHK(dwByteIndex < cbInput);

        pbOutput[dwCurrOutputIndex] = pbInput[dwByteIndex] >> dwBitOffset;

        ++dwByteIndex;

        if (dwByteIndex != cbInput) {
            BYTE bTemp = pbInput[dwByteIndex];
            bTemp <<= dwRemainderShift;
            pbOutput[dwCurrOutputIndex] |= bTemp;
        }

        ++dwCurrOutputIndex;
    }
}


///////////////////////////////////////////////////////////////////////////////
//  GetBitSlice - Get a bit slice from a stream of bytes
//  Input:  pBuffer - buffer containing data stream
//          cbBuffer - size of buffer in bytes
//          dwBitOffset - bit offset from start of buffer
//          ucBitCount - number of bits (less than or equal to 32)
//  Output: 
//
//  Return: returns a DWORD contain the bit slice shifted to fill the least significant bits
//  Notes:  will raise an SEH exception if integer overflow occurs
///////////////////////////////////////////////////////////////////////////////
DWORD GetBitSlice(PUCHAR pBuffer, ULONG cbBuffer, DWORD dwBitOffset, UCHAR ucBitCount)
{
    UCHAR rgbShifted[4] = { 0 };

    if (ucBitCount > 32) {
        DEBUG_CHECK(FALSE, (TEXT("GetBitSlice: invalid number of bits \n")));
        return 0;
    }

    typedef SafeInt<DWORD> SafeDW;
    // Exception will be raised on the next line if there is an overflow.
    if ( (SafeDW(dwBitOffset) + SafeDW(ucBitCount)) > (SafeDW(cbBuffer) * 8) ) {
        DEBUG_CHECK(FALSE, (TEXT("GetBitSlice: invalid bit offset given the number of bits \n")));
        return 0;
    }

    // Shift the pBuffer down by dwBitOffset bits.
    ShiftBytes(pBuffer, cbBuffer, dwBitOffset, rgbShifted);

    DWORD dwUsedBytes; // How many bytes have valid data.

    if (ucBitCount % 8 == 0) {
        // Return a byte multiple.
        dwUsedBytes = ucBitCount / 8;
    }
    else {
        // Clear the last used byte of upper bits.
        DWORD dwLastByteIndex = (ucBitCount - 1) / 8;
        DWORD dwRemainderShift = 8 - (ucBitCount % 8);
        rgbShifted[dwLastByteIndex] <<= dwRemainderShift;
        rgbShifted[dwLastByteIndex] >>= dwRemainderShift;
        dwUsedBytes = dwLastByteIndex + 1;
    }

    // Clear the unused bytes.
    if (dwUsedBytes != sizeof(rgbShifted)) {
        memset(rgbShifted + dwUsedBytes, 0, sizeof(rgbShifted) - dwUsedBytes);
    }

    DWORD dwRet;
    memcpy(&dwRet, rgbShifted, sizeof(dwRet));

    return dwRet;
}

}

// DO NOT REMOVE --- END EXTERNALLY DEVELOPED SOURCE CODE ID --- DO NOT REMOVE

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -