📄 sdmisc.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 + -