Windows2003-3790/termsrv/newclient/rdpdr/w32scard.cpp
2020-09-30 16:53:55 +02:00

6838 lines
201 KiB
C++

/*++
Copyright (c) 1998-2000 Microsoft Corporation
Module Name:
w32drive
Abstract:
This module defines a child of the client-side RDP
device redirection, the "w32scard" W32SCard to provide
SmartCard sub-system redirection on 32bit windows
Author:
reidk
Revision History:
--*/
#include <precom.h>
#define TRC_GROUP TRC_GROUP_NETWORK
#define TRC_FILE "W32SCard"
#include <atrcapi.h>
#include <w32scard.h>
#include <delayimp.h>
#include "proc.h"
#include "drconfig.h"
#include "w32utl.h"
#include "utl.h"
#include "drfsfile.h"
#include "scredir.h"
#include "scioctl.h"
#include "winsmcrd.h"
#ifdef OS_WINCE
#include <wcescard.h>
#define LoadLibraryA(x) LoadLibrary(L##x)
#define pfnSCardFreeMemory(hcontext, pv)
#endif
#define _TRY_status(x) \
__try \
{ \
x; \
} \
__except(EXCEPTION_EXECUTE_HANDLER) \
{ \
status = STATUS_UNSUCCESSFUL; \
goto ErrorReturn; \
}
#define _TRY_lReturn(x) \
__try \
{ \
x; \
} \
__except(EXCEPTION_EXECUTE_HANDLER) \
{ \
lReturn = SCARD_E_UNEXPECTED; \
goto ErrorReturn; \
}
#define _TRY_2(x) __try \
{ \
x; \
} \
__except(EXCEPTION_EXECUTE_HANDLER){} // do nothing
#define SCARD_CONTEXT_LIST_ALLOC_SIZE 6
#define SCARD_THREAD_LIST_ALLOC_SIZE 6
#define SCARD_IOREQUEST_LIST_ALLOC_SIZE 6
#define ATR_COPY_SIZE 36
void
SafeMesHandleFree(handle_t *ph)
{
if (*ph != 0)
{
MesHandleFree(*ph);
*ph = 0;
}
}
//---------------------------------------------------------------------------------------
//
// MIDL allocation routines
//
//---------------------------------------------------------------------------------------
void __RPC_FAR *__RPC_USER MIDL_user_allocate(size_t size)
{
return (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
}
void __RPC_USER MIDL_user_free(void __RPC_FAR *pv)
{
if (pv != NULL)
{
HeapFree(GetProcessHeap(), 0, pv);
}
}
///////////////////////////////////////////////////////////////
//
// W32SCard Methods
//
//
W32SCard::W32SCard(
ProcObj *processObject,
ULONG deviceID,
const TCHAR *deviceName,
const TCHAR *devicePath) : W32DrDeviceAsync(processObject, deviceID, devicePath)
/*++
Routine Description:
Constructor
Arguments:
processObject - Associated process object.
deviceName - Name of the drive.
id - Device ID for the drive.
devicePath - Path that can be opened by CreateFile
for drive.
Return Value:
NA
--*/
{
unsigned len;
DWORD i;
HRESULT hr;
DC_BEGIN_FN("W32SCard::W32SCard");
_deviceName = NULL;
_pFileObj = NULL;
_rgSCardContextList = NULL;
_dwSCardContextListSize = 0;
_rghThreadList = NULL;
_dwThreadListSize = 0;
_fInDestructor = FALSE;
_fFlushing = FALSE;
_hModWinscard = NULL;
_fCritSecsInitialized = FALSE;
_rgIORequestList = NULL;
_dwIORequestListSize = 0;
_fNewFailed = FALSE;
#ifndef OS_WINCE
_hModKernel32 = NULL;
_hStartedEvent = NULL;
_hRegisterWaitForStartedEvent = NULL;
_fCloseStartedEvent = FALSE;
_fUseRegisterWaitFuncs = FALSE;
#endif
SetDeviceProperty();
//
// Initialize the critical sections.
//
__try
{
InitializeCriticalSection(&_csContextList);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRC_ERR((
TB,
_T("InitializeCriticalSection() failed - Exception Code: %lx"),
GetExceptionCode()));
goto InvalidObject;
}
__try
{
InitializeCriticalSection(&_csThreadList);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRC_ERR((
TB,
_T("InitializeCriticalSection() failed - Exception Code: %lx"),
GetExceptionCode()));
DeleteCriticalSection(&_csContextList);
goto InvalidObject;
}
__try
{
InitializeCriticalSection(&_csWaitForStartedEvent);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
TRC_ERR((
TB,
_T("InitializeCriticalSection() failed - Exception Code: %lx"),
GetExceptionCode()));
DeleteCriticalSection(&_csContextList);
DeleteCriticalSection(&_csThreadList);
goto InvalidObject;
}
_fCritSecsInitialized = TRUE;
#ifdef OS_WINCE
if ((gpCESCard = new CESCard()) == NULL)
{
TRC_ERR((TB, _T("Failed to create synchronization object") ));
goto InvalidObject;
}
#endif
//
// Load the SCard* function pointers
//
if (!BindToSCardFunctions())
{
goto InvalidObject;
}
//
// Record the drive name.
//
TRC_ASSERT((deviceName != NULL), (TB, _T("deviceName is NULL")));
len = (STRLEN(deviceName) + 1);
_deviceName = new TCHAR[len];
if (_deviceName != NULL)
{
hr = StringCchCopy(_deviceName, len, deviceName);
TRC_ASSERT(SUCCEEDED(hr),(TB,_T("Pre checked copy failed: 0x%x"), hr));
}
else
{
goto InvalidObject;
}
//
// Initial allocation for context, thread, and IORequest lists
//
_rgSCardContextList = new SCARDCONTEXT[SCARD_CONTEXT_LIST_ALLOC_SIZE];
_rghThreadList = new HANDLE[SCARD_THREAD_LIST_ALLOC_SIZE];
_rgIORequestList = new PRDPDR_IOREQUEST_PACKET[SCARD_IOREQUEST_LIST_ALLOC_SIZE];
if ((_rgSCardContextList == NULL) ||
(_rghThreadList == NULL) ||
(_rgIORequestList == NULL))
{
goto InvalidObject;
}
else
{
_dwSCardContextListSize = SCARD_CONTEXT_LIST_ALLOC_SIZE;
_dwThreadListSize = SCARD_THREAD_LIST_ALLOC_SIZE;
_dwIORequestListSize = SCARD_IOREQUEST_LIST_ALLOC_SIZE;
memset(
_rgSCardContextList,
0,
sizeof(SCARDCONTEXT) * SCARD_CONTEXT_LIST_ALLOC_SIZE);
for (i=0; i<SCARD_THREAD_LIST_ALLOC_SIZE; i++)
{
_rghThreadList[i] = NULL;
}
for (i=0; i<SCARD_IOREQUEST_LIST_ALLOC_SIZE; i++)
{
_rgIORequestList[i] = NULL;
}
}
Return:
DC_END_FN();
return;
InvalidObject:
_fNewFailed = TRUE;
SetValid(FALSE);
goto Return;
}
W32SCard::~W32SCard()
/*++
Routine Description:
Destructor
Arguments:
NA
Return Value:
NA
--*/
{
DC_BEGIN_FN("W32SCard::~W32SCard");
_fInDestructor = TRUE;
#ifndef OS_WINCE
PVOID pv;
pv = InterlockedExchangePointer(&_hRegisterWaitForStartedEvent, NULL);
if (pv != NULL)
{
pfnUnregisterWaitEx(pv, INVALID_HANDLE_VALUE);
}
#endif
if (IsValid())
{
FlushIRPs();
}
if (_deviceName != NULL)
{
delete[]_deviceName;
}
if (_pFileObj != NULL)
{
_pFileObj->Release();
}
if (_rgSCardContextList != NULL)
{
delete[]_rgSCardContextList;
}
if (_rghThreadList != NULL)
{
delete[]_rghThreadList;
}
if (_rgIORequestList != NULL)
{
delete[]_rgIORequestList;
}
if (_hModWinscard != NULL)
{
FreeLibrary(_hModWinscard);
}
#ifndef OS_WINCE
if (_hModKernel32 != NULL)
{
FreeLibrary(_hModKernel32);
}
if (_hStartedEvent != NULL)
{
ReleaseStartedEvent();;
}
#endif
if (_fCritSecsInitialized)
{
DeleteCriticalSection(&_csContextList);
DeleteCriticalSection(&_csThreadList);
DeleteCriticalSection(&_csWaitForStartedEvent);
}
#ifdef OS_WINCE
delete gpCESCard;
#endif
DC_END_FN();
}
#ifndef OS_WINCE
extern LPCSTR g_szTscControlName;
#else
extern LPCWSTR g_szTscControlName;
#endif
HMODULE
W32SCard::AddRefCurrentModule()
{
#ifndef OS_WINCE
return (LoadLibraryA(g_szTscControlName));
#else
return LoadLibrary(g_szTscControlName);
#endif
}
VOID
W32SCard::FlushIRPs()
{
DC_BEGIN_FN("W32SCard::FlushIRPs");
DWORD i, j;
DWORD dwNumThreads = 0;
HANDLE *rgHandles = NULL;
_fFlushing = TRUE;
EnterCriticalSection(&_csContextList);
EnterCriticalSection(&_csThreadList);
//
// Clean up any oustanding threads that are blocked
//
if ((_rgSCardContextList != NULL) && (_rghThreadList != NULL))
{
//
// Count number of blocked threads
//
dwNumThreads = 0;
for (i=0; i<_dwThreadListSize; i++)
{
if (_rghThreadList[i] != NULL)
{
dwNumThreads++;
}
}
//
// Build an array of thread handles to wait for
//
#ifdef OS_WINCE
if (dwNumThreads > 0)
#endif
rgHandles = new HANDLE[dwNumThreads];
if (rgHandles != NULL)
{
dwNumThreads = 0;
for (i=0; i<_dwThreadListSize; i++)
{
if (_rghThreadList[i] != NULL)
{
#ifndef OS_WINCE
if (!DuplicateHandle(
GetCurrentProcess(),
_rghThreadList[i],
GetCurrentProcess(),
&(rgHandles[dwNumThreads]),
0,
FALSE,
DUPLICATE_SAME_ACCESS))
{
TRC_ERR((TB, _T("DuplicateHandle failed.")));
//
// Nothing we can do... just clean up the already
// duplicated handles
//
for (j=0; j<dwNumThreads; j++)
{
CloseHandle(rgHandles[j]);
}
//
// Setting dwNumThread to 0 will cause no wait
//
dwNumThreads = 0;
break;
}
#else //CE does not support DuplicateHandle for threads
rgHandles[dwNumThreads] = _rghThreadList[i];
#endif
dwNumThreads++;
}
}
}
else
{
TRC_ERR((TB, _T("new failed.")));
}
//
// Cancel any outstanding calls
//
for (i=0; i<_dwSCardContextListSize; i++)
{
if (_rgSCardContextList[i] != NULL)
{
pfnSCardCancel(_rgSCardContextList[i]);
}
}
}
LeaveCriticalSection(&_csContextList);
LeaveCriticalSection(&_csThreadList);
//
// Do the wait
//
if (dwNumThreads > 0)
{
#ifndef OS_WINCE
if (WaitForMultipleObjects(
dwNumThreads,
rgHandles,
TRUE,
INFINITE) == WAIT_TIMEOUT)
{
TRC_ERR((TB, _T("WaitForMultipleObjects timed out")));
}
#else
//CE does not support waiting for all at once
for (j=0; j<dwNumThreads; j++)
{
DWORD dwWait = WaitForSingleObject(rgHandles[j], 30 * 1000);
if (dwWait != WAIT_OBJECT_0)
{
TRC_ERR((TB, _T("WaitForSingleObject 0x%08x returned 0x%08x. GLE=%d(0x%08x)"), rgHandles[j], dwWait, GetLastError(), GetLastError()));
}
}
#endif
}
//
// Close the duplicate handles
//
for (i=0; i<dwNumThreads; i++)
{
CloseHandle(rgHandles[i]);
}
#ifdef OS_WINCE
gpCESCard->FlushIRPs();
#endif
if (rgHandles != NULL)
{
delete[]rgHandles;
}
_fFlushing = FALSE;
DC_END_FN();
}
DWORD
W32SCard::Enumerate(
IN ProcObj *procObj,
IN DrDeviceMgr *deviceMgr
)
/*++
Routine Description:
Enumerate devices of this type by adding appropriate device
instances to the device manager.
Arguments:
procObj - Corresponding process object.
deviceMgr - Device manager to add devices to.
Return Value:
ERROR_SUCCESS on success. Otherwise, an error code is returned.
--*/
{
W32SCard *pScardDeviceObj = NULL;
RDPDR_VERSION serverVer;
DrFile *pFileObj = NULL;
OSVERSIONINFOA osVersion;
DC_BEGIN_FN("W32SCard::Enumerate");
//
// Make sure we are on an OS that we support
//
memset(&osVersion, 0x00, sizeof(osVersion));
osVersion.dwOSVersionInfoSize = sizeof(osVersion);
if (!GetVersionExA(&osVersion))
{
TRC_ERR((TB, _T("GetVersionEx() failed")));
return ERROR_SUCCESS; // don't blcok anything else from running
}
if (osVersion.dwMajorVersion < 5)
{
TRC_DBG((TB,_T("SmartCard redirection does not work on platforms below Win2k, bailing out")));
return ERROR_SUCCESS;
}
if(!procObj->GetVCMgr().GetInitData()->fEnableSCardRedirection)
{
TRC_DBG((TB,_T("SmartCard redirection disabled, bailing out")));
return ERROR_SUCCESS;
}
serverVer = procObj->serverVersion();
//
// If the server doesn't support scard device redirection,
// then don't bother enumerate the scard device, simply
// return success
//
if (COMPARE_VERSION(serverVer.Minor, serverVer.Major,
RDPDR_MINOR_VERSION, RDPDR_MAJOR_VERSION) < 0)
{
TRC_NRM((TB, _T("Skipping scard device enumeration")));
return ERROR_SUCCESS;
}
//
// Create the scard device object
//
pScardDeviceObj = new W32SCard(
procObj,
deviceMgr->GetUniqueObjectID(),
SZ_SCARD_DEVICE_NAME,
SZ_SCARD_DEVICE_NAME);
if (pScardDeviceObj == NULL)
{
TRC_ERR((TB, _T("new W32SCard() failed")));
}
else
{
if (!(pScardDeviceObj->_fNewFailed))
{
pScardDeviceObj->Initialize();
}
if (!pScardDeviceObj->IsValid())
{
TRC_ERR((TB, _T("new W32SCard object is not valid")));
delete (pScardDeviceObj);
pScardDeviceObj = NULL;
}
else
{
//
// Create the single file object to be used for the Scard device object
//
// BTW, we can use INVALID_HANDLE_VALUE as the actual file handle since
// we don't really use the DrFile object except for the FileId
//
pScardDeviceObj->_pFileObj = new DrFile(
pScardDeviceObj,
DR_SMARTCARD_FILEID,
INVALID_HANDLE_VALUE);
if (pScardDeviceObj->_pFileObj == NULL)
{
TRC_ERR((TB, _T("new DrFile() failed")));
delete (pScardDeviceObj);
pScardDeviceObj = NULL;
}
else
{
pScardDeviceObj->_pFileObj->AddRef();
//
// Add the Scard device to the device manager
//
if (deviceMgr->AddObject(pScardDeviceObj) != STATUS_SUCCESS)
{
TRC_ERR((TB, _T("deviceMgr->AddObject() failed")));
delete (pScardDeviceObj);
pScardDeviceObj = NULL;
}
}
}
}
DC_END_FN();
return ERROR_SUCCESS;
}
ULONG
W32SCard::GetDevAnnounceDataSize()
/*++
Routine Description:
Return the size (in bytes) of a device announce packet for
this device.
Arguments:
NA
Return Value:
The size (in bytes) of a device announce packet for this device.
--*/
{
ULONG size = 0;
DC_BEGIN_FN("W32SCard::GetDevAnnounceDataSize");
TRC_ASSERT((IsValid()), (TB, _T("Invalid W32SCard object")));
if (!IsValid()) { return 0; }
size = 0;
//
// Add the base announce size.
//
size += sizeof(RDPDR_DEVICE_ANNOUNCE);
DC_END_FN();
return size;
}
VOID W32SCard::GetDevAnnounceData(
IN PRDPDR_DEVICE_ANNOUNCE pDeviceAnnounce
)
/*++
Routine Description:
Add a device announce packet for this device to the input buffer.
Arguments:
pDeviceAnnounce - Device Announce Buf for this Device
Return Value:
NA
--*/
{
DC_BEGIN_FN("W32SCard::GetDevAnnounceData");
TRC_ASSERT((IsValid()), (TB, _T("Invalid W32SCcard object")));
if (!IsValid()) {
DC_END_FN();
return;
}
pDeviceAnnounce->DeviceId = GetID();
pDeviceAnnounce->DeviceType = GetDeviceType();
pDeviceAnnounce->DeviceDataLength = 0;
//
// Record the device name in ANSI.
//
#ifdef UNICODE
RDPConvertToAnsi(_deviceName, (LPSTR) pDeviceAnnounce->PreferredDosName,
sizeof(pDeviceAnnounce->PreferredDosName)
);
#else
STRNCPY((char *)pDeviceAnnounce->PreferredDosName, _deviceName, PREFERRED_DOS_NAME_SIZE);
pDeviceAnnounce->PreferredDosName[PREFERRED_DOS_NAME_SIZE - 1] = '\0';
#endif
DC_END_FN();
}
//---------------------------------------------------------------------------------------
//
// These methods implement a list that is used for tracking all open SCardContexts,
// so that if we get disconnected with an open SCardContext that has blocked calls,
// we can call SCardCancel to get the threads back before the W32SCard object is
// fully deleted
//
//---------------------------------------------------------------------------------------
BOOL
W32SCard::AddSCardContextToList(
SCARDCONTEXT SCardContext)
{
DC_BEGIN_FN("W32SCard::AddSCardContextToList");
DWORD i = 0;
DWORD dwOpenSlot = 0xffffffff;
SCARDCONTEXT *pTemp = NULL;
BOOL fRet = TRUE;
EnterCriticalSection(&_csContextList);
//
// See if there is already an entry for this context,
// and keep track of the LAST open slot in case there isn't
//
for (i=0; i<_dwSCardContextListSize; i++)
{
if (_rgSCardContextList[i] == SCardContext)
{
//
// already exists
//
goto Return;
}
else if (_rgSCardContextList[i] == NULL)
{
dwOpenSlot = i;
}
}
//
// check to see if an open slot was found
//
if (dwOpenSlot != 0xffffffff)
{
//
// found
//
_rgSCardContextList[dwOpenSlot] = SCardContext;
}
else
{
//
// need to allocate more space
//
pTemp = new SCARDCONTEXT[ _dwSCardContextListSize +
SCARD_CONTEXT_LIST_ALLOC_SIZE];
if (pTemp == NULL)
{
TRC_ERR((TB, _T("new failed")));
fRet = FALSE;
LeaveCriticalSection(&_csContextList);
goto Return;
}
memset(
pTemp,
0,
sizeof(SCARDCONTEXT) *
(_dwSCardContextListSize + SCARD_CONTEXT_LIST_ALLOC_SIZE));
//
// populate newly allocated array with all current entries
//
for (i=0; i<_dwSCardContextListSize; i++)
{
pTemp[i] = _rgSCardContextList[i];
}
//
// add the new entry
//
pTemp[_dwSCardContextListSize] = SCardContext;
//
// free old list
//
delete[]_rgSCardContextList;
//
// reset member pointer and size
//
_rgSCardContextList = pTemp;
_dwSCardContextListSize += SCARD_CONTEXT_LIST_ALLOC_SIZE;
}
LeaveCriticalSection(&_csContextList);
Return:
DC_END_FN();
return (fRet);
}
void
W32SCard::RemoveSCardContextFromList(
SCARDCONTEXT SCardContext)
{
DC_BEGIN_FN("W32SCard::RemoveSCardContextFromList");
DWORD i = 0;
EnterCriticalSection(&_csContextList);
while (i < _dwSCardContextListSize)
{
if (_rgSCardContextList[i] == SCardContext)
{
pfnSCardCancel(_rgSCardContextList[i]);
_rgSCardContextList[i] = NULL;
break;
}
i++;
}
LeaveCriticalSection(&_csContextList);
Return:
DC_END_FN();
}
//---------------------------------------------------------------------------------------
//
// These methods implement a list that is used for tracking all threads that are
// currently operating on a SCard* call. The list is used during the W32SCard object
// destructor to wait on all the threads to return before allowing the object to be
// completely deleted.
//
//---------------------------------------------------------------------------------------
BOOL
W32SCard::AddThreadToList(HANDLE hThread)
{
DC_BEGIN_FN("W32SCard::AddThreadToList");
DWORD i = 0;
HANDLE *rghTemp = NULL;
BOOL fRet = TRUE;
DWORD dwNewSize = 0;
EnterCriticalSection(&_csThreadList);
//
// Search for an open slot
//
while (i < _dwThreadListSize)
{
if (_rghThreadList[i] == NULL)
{
//
// open slot found
//
break;
}
i++;
}
//
// check to see if an open slot was found
//
if (i < _dwThreadListSize)
{
//
// found
//
_rghThreadList[i] = hThread;
}
else
{
//
// need to allocate more space
//
dwNewSize = _dwThreadListSize + SCARD_THREAD_LIST_ALLOC_SIZE;
rghTemp = new HANDLE[dwNewSize];
if (rghTemp == NULL)
{
TRC_ERR((TB, _T("new failed")));
fRet = FALSE;
LeaveCriticalSection(&_csThreadList);
goto Return;
}
//
// populate newly allocated array with all current thread handles
//
for (i=0; i<_dwThreadListSize; i++)
{
rghTemp[i] = _rghThreadList[i];
}
//
// Initialize new entries
//
for (i=_dwThreadListSize; i<dwNewSize; i++)
{
rghTemp[i] = NULL;
}
//
// add the new entry
//
rghTemp[_dwThreadListSize] = hThread;
//
// free old list
//
delete[]_rghThreadList;
//
// reset member pointer and size
//
_rghThreadList = rghTemp;
_dwThreadListSize += SCARD_THREAD_LIST_ALLOC_SIZE;
}
LeaveCriticalSection(&_csThreadList);
Return:
DC_END_FN();
return (fRet);
}
void
W32SCard::RemoveThreadFromList(HANDLE hThread)
{
DC_BEGIN_FN("W32SCard::RemoveThreadFromList");
DWORD i = 0;
EnterCriticalSection(&_csThreadList);
while (i < _dwThreadListSize)
{
if (_rghThreadList[i] == hThread)
{
CloseHandle(_rghThreadList[i]);
_rghThreadList[i] = NULL;
break;
}
i++;
}
LeaveCriticalSection(&_csThreadList);
Return:
DC_END_FN();
}
//---------------------------------------------------------------------------------------
//
// This method implements a list that is used for tracking IORequests waiting for the
// started event
//
//---------------------------------------------------------------------------------------
BOOL
W32SCard::AddIORequestToList(
PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::AddIORequestToList");
DWORD i = 0;
PRDPDR_IOREQUEST_PACKET *rghTemp = NULL;
BOOL fRet = TRUE;
DWORD dwNewSize = 0;
//
// Only called in one place, which is wrapped in a CritSec, so no need for one here
//
//
// Search for an open slot
//
while (i < _dwIORequestListSize)
{
if (_rgIORequestList[i] == NULL)
{
//
// open slot found
//
break;
}
i++;
}
//
// check to see if an open slot was found
//
if (i < _dwIORequestListSize)
{
//
// found
//
_rgIORequestList[i] = pIoRequestPacket;
}
else
{
//
// need to allocate more space
//
dwNewSize = _dwIORequestListSize + SCARD_IOREQUEST_LIST_ALLOC_SIZE;
rghTemp = new PRDPDR_IOREQUEST_PACKET[dwNewSize];
if (rghTemp == NULL)
{
TRC_ERR((TB, _T("new failed")));
fRet = FALSE;
goto Return;
}
//
// populate newly allocated array with all current IoRequests
//
for (i=0; i<_dwIORequestListSize; i++)
{
rghTemp[i] = _rgIORequestList[i];
}
//
// Initialize new entries
//
for (i=_dwIORequestListSize; i<dwNewSize; i++)
{
rghTemp[i] = NULL;
}
//
// add the new entry
//
rghTemp[_dwIORequestListSize] = pIoRequestPacket;
//
// free old list
//
delete[]_rgIORequestList;
//
// reset member pointer and size
//
_rgIORequestList = rghTemp;
_dwIORequestListSize += SCARD_IOREQUEST_LIST_ALLOC_SIZE;
}
Return:
DC_END_FN();
return (fRet);
}
DWORD WINAPI
W32SCard::SCardHandleCall_ThreadProc(
LPVOID lpParameter)
{
DC_BEGIN_FN("W32SCard::SCardHandleCall_ThreadProc");
LONG lReturn = SCARD_S_SUCCESS;
SCARDHANDLECALLSTRUCT *pStruct = (SCARDHANDLECALLSTRUCT *) lpParameter;
W32SCard *pTHIS = pStruct->pTHIS;
HANDLE hThread = pStruct->hThread;
HMODULE hModExtraRefCount = pStruct->hModExtraRefCount;
pStruct = (SCARDHANDLECALLSTRUCT *) lpParameter;
//
// pStruct->hThread will be NULL if it wasn't added to the thread list...
// it wasn't added to the thread list then just get out.
//
if (pStruct->hThread == NULL)
{
FreeLibraryAndExitThread(pStruct->hModExtraRefCount, 0);
}
switch (pStruct->dwCallType)
{
case SCARD_IOCTL_CONNECTA:
TRC_DBG((TB, _T("SCARD_IOCTL_CONNECTA")));
pTHIS->Connect(
pStruct,
SCARD_IOCTL_CONNECTA);
break;
case SCARD_IOCTL_CONNECTW:
TRC_DBG((TB, _T("SCARD_IOCTL_CONNECTW")));
pTHIS->Connect(
pStruct,
SCARD_IOCTL_CONNECTW);
break;
case SCARD_IOCTL_RECONNECT:
TRC_DBG((TB, _T("SCARD_IOCTL_RECONNECT")));
pTHIS->Reconnect(
pStruct);
break;
case SCARD_IOCTL_DISCONNECT:
TRC_DBG((TB, _T("SCARD_IOCTL_DISCONNECT")));
pTHIS->HandleHCardAndDispositionCall(
pStruct,
SCARD_IOCTL_DISCONNECT);
break;
case SCARD_IOCTL_BEGINTRANSACTION:
TRC_DBG((TB, _T("SCARD_IOCTL_BEGINTRANSACTION")));
pTHIS->HandleHCardAndDispositionCall(
pStruct,
SCARD_IOCTL_BEGINTRANSACTION);
break;
case SCARD_IOCTL_ENDTRANSACTION:
TRC_DBG((TB, _T("SCARD_IOCTL_ENDTRANSACTION")));
pTHIS->HandleHCardAndDispositionCall(
pStruct,
SCARD_IOCTL_ENDTRANSACTION);
break;
#ifndef OS_WINCE
case SCARD_IOCTL_STATE:
TRC_DBG((TB, _T("SCARD_IOCTL_STATE")));
pTHIS->State(
pStruct);
break;
#endif
case SCARD_IOCTL_STATUSA:
TRC_DBG((TB, _T("SCARD_IOCTL_STATUSA")));
pTHIS->Status(
pStruct,
SCARD_IOCTL_STATUSA);
break;
case SCARD_IOCTL_STATUSW:
TRC_DBG((TB, _T("SCARD_IOCTL_STATUSW")));
pTHIS->Status(
pStruct,
SCARD_IOCTL_STATUSW);
break;
case SCARD_IOCTL_TRANSMIT:
TRC_DBG((TB, _T("SCARD_IOCTL_TRANSMIT")));
pTHIS->Transmit(
pStruct);
break;
case SCARD_IOCTL_CONTROL:
TRC_DBG((TB, _T("SCARD_IOCTL_CONTROL")));
pTHIS->Control(
pStruct);
break;
case SCARD_IOCTL_GETATTRIB:
TRC_DBG((TB, _T("SCARD_IOCTL_GETATTRIB")));
pTHIS->GetAttrib(
pStruct);
break;
case SCARD_IOCTL_SETATTRIB:
TRC_DBG((TB, _T("SCARD_IOCTL_SETATTRIB")));
pTHIS->SetAttrib(
pStruct);
break;
}
#if defined (OS_WINCE) && defined(DEBUG)
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pStruct->pIoRequestPacket->IoRequest);
TRC_DATA_DBG("Input buffer",(char *) (pIoRequest + 1), pIoRequest->Parameters.DeviceIoControl.InputBufferLength);
#endif
pTHIS->RemoveThreadFromList(hThread);
FreeLibraryAndExitThread(hModExtraRefCount, 0);
DC_END_FN();
#ifdef OS_WINCE
return 0;
#endif
}
VOID
W32SCard::DefaultIORequestMsgHandleWrapper(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN NTSTATUS serverReturnStatus
)
{
if (!_fInDestructor && !_fFlushing)
{
DefaultIORequestMsgHandle(pIoRequestPacket, serverReturnStatus);
}
else
{
//
// Just drop it on the floor if we are shutting down or flushing
//
delete(pIoRequestPacket);
}
}
VOID
W32SCard::MsgIrpDeviceControl(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN UINT32 packetLen
)
/*++
Routine Description:
Handle a file system control request from the server.
Arguments:
pIoRequestPacket - Server IO request packet.
packetLen - Length of the packet
Return Value:
NA
--*/
{
DC_BEGIN_FN("W32SCard::MsgIrpDeviceControl");
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
HMODULE hModExtraRefCount = NULL;
SCARDHANDLECALLSTRUCT *pStruct = NULL;
HANDLE hThread;
DWORD dwThreadId;
if (!pIoRequest->Parameters.DeviceIoControl.InputBufferLength)
{
// no data, get out
return;
}
switch(pIoRequest->Parameters.DeviceIoControl.IoControlCode)
{
case SCARD_IOCTL_ESTABLISHCONTEXT:
TRC_DBG((TB, _T("SCARD_IOCTL_ESTABLISHCONTEXT")));
EstablishContext(pIoRequestPacket);
break;
case SCARD_IOCTL_RELEASECONTEXT:
TRC_DBG((TB, _T("SCARD_IOCTL_RELEASECONTEXT")));
HandleContextCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_RELEASECONTEXT);
break;
case SCARD_IOCTL_ISVALIDCONTEXT:
TRC_DBG((TB, _T("SCARD_IOCTL_ISVALIDCONTEXT")));
HandleContextCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_ISVALIDCONTEXT);
break;
case SCARD_IOCTL_LISTREADERGROUPSA:
TRC_DBG((TB, _T("SCARD_IOCTL_LISTREADERGROUPSA")));
ListReaderGroups(
pIoRequestPacket,
SCARD_IOCTL_LISTREADERGROUPSA);
break;
case SCARD_IOCTL_LISTREADERGROUPSW:
TRC_DBG((TB, _T("SCARD_IOCTL_LISTREADERGROUPSW")));
ListReaderGroups(
pIoRequestPacket,
SCARD_IOCTL_LISTREADERGROUPSW);
break;
case SCARD_IOCTL_LISTREADERSA:
TRC_DBG((TB, _T("SCARD_IOCTL_LISTREADERSA")));
ListReaders(
pIoRequestPacket,
SCARD_IOCTL_LISTREADERSA);
break;
case SCARD_IOCTL_LISTREADERSW:
TRC_DBG((TB, _T("SCARD_IOCTL_LISTREADERSW")));
ListReaders(
pIoRequestPacket,
SCARD_IOCTL_LISTREADERSW);
break;
case SCARD_IOCTL_INTRODUCEREADERGROUPA:
TRC_DBG((TB, _T("SCARD_IOCTL_INTRODUCEREADERGROUPA")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_INTRODUCEREADERGROUPA);
break;
case SCARD_IOCTL_INTRODUCEREADERGROUPW:
TRC_DBG((TB, _T("SCARD_IOCTL_INTRODUCEREADERGROUPW")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_INTRODUCEREADERGROUPW);
break;
case SCARD_IOCTL_FORGETREADERGROUPA:
TRC_DBG((TB, _T("SCARD_IOCTL_FORGETREADERGROUPA")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_FORGETREADERGROUPA);
break;
case SCARD_IOCTL_FORGETREADERGROUPW:
TRC_DBG((TB, _T("SCARD_IOCTL_FORGETREADERGROUPW")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_FORGETREADERGROUPW);
break;
case SCARD_IOCTL_INTRODUCEREADERA:
TRC_DBG((TB, _T("SCARD_IOCTL_INTRODUCEREADERA")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_INTRODUCEREADERA);
break;
case SCARD_IOCTL_INTRODUCEREADERW:
TRC_DBG((TB, _T("SCARD_IOCTL_INTRODUCEREADERW")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_INTRODUCEREADERW);
break;
case SCARD_IOCTL_FORGETREADERA:
TRC_DBG((TB, _T("SCARD_IOCTL_FORGETREADERA")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_FORGETREADERA);
break;
case SCARD_IOCTL_FORGETREADERW:
TRC_DBG((TB, _T("SCARD_IOCTL_FORGETREADERW")));
HandleContextAndStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_FORGETREADERW);
break;
case SCARD_IOCTL_ADDREADERTOGROUPA:
TRC_DBG((TB, _T("SCARD_IOCTL_ADDREADERTOGROUPA")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_ADDREADERTOGROUPA);
break;
case SCARD_IOCTL_ADDREADERTOGROUPW:
TRC_DBG((TB, _T("SCARD_IOCTL_ADDREADERTOGROUPW")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_ADDREADERTOGROUPW);
break;
case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
TRC_DBG((TB, _T("SCARD_IOCTL_REMOVEREADERFROMGROUPA")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_REMOVEREADERFROMGROUPA);
break;
case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
TRC_DBG((TB, _T("SCARD_IOCTL_REMOVEREADERFROMGROUPW")));
HandleContextAndTwoStringCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_REMOVEREADERFROMGROUPW);
break;
case SCARD_IOCTL_LOCATECARDSA:
TRC_DBG((TB, _T("SCARD_IOCTL_LOCATECARDSA")));
LocateCardsA(pIoRequestPacket);
break;
case SCARD_IOCTL_LOCATECARDSW:
TRC_DBG((TB, _T("SCARD_IOCTL_LOCATECARDSW")));
LocateCardsW(pIoRequestPacket);
break;
case SCARD_IOCTL_LOCATECARDSBYATRA:
TRC_DBG((TB, _T("SCARD_IOCTL_LOCATECARDSBYATRA")));
LocateCardsByATRA(pIoRequestPacket);
break;
case SCARD_IOCTL_LOCATECARDSBYATRW:
TRC_DBG((TB, _T("SCARD_IOCTL_LOCATECARDSBYATRW")));
LocateCardsByATRW(pIoRequestPacket);
break;
case SCARD_IOCTL_GETSTATUSCHANGEA:
TRC_DBG((TB, _T("SCARD_IOCTL_GETSTATUSCHANGEA")));
GetStatusChangeWrapper(
pIoRequestPacket,
SCARD_IOCTL_GETSTATUSCHANGEA);
break;
case SCARD_IOCTL_GETSTATUSCHANGEW:
TRC_DBG((TB, _T("SCARD_IOCTL_GETSTATUSCHANGEW")));
GetStatusChangeWrapper(
pIoRequestPacket,
SCARD_IOCTL_GETSTATUSCHANGEW);
break;
case SCARD_IOCTL_CANCEL:
TRC_DBG((TB, _T("SCARD_IOCTL_CANCEL")));
HandleContextCallWithLongReturn(
pIoRequestPacket,
SCARD_IOCTL_CANCEL);
break;
//
// Possibly blocking calls, so create a thread to make the call
//
case SCARD_IOCTL_CONNECTA:
case SCARD_IOCTL_CONNECTW:
case SCARD_IOCTL_RECONNECT:
case SCARD_IOCTL_DISCONNECT:
case SCARD_IOCTL_BEGINTRANSACTION:
case SCARD_IOCTL_ENDTRANSACTION:
#ifndef OS_WINCE
case SCARD_IOCTL_STATE:
#endif
case SCARD_IOCTL_STATUSA:
case SCARD_IOCTL_STATUSW:
case SCARD_IOCTL_TRANSMIT:
case SCARD_IOCTL_CONTROL:
case SCARD_IOCTL_GETATTRIB:
case SCARD_IOCTL_SETATTRIB:
//
// Get a ref count on our dll so that we know the dll
// code won't disappear from underneath us. The thread will
// release this ref count when it exits
//
hModExtraRefCount = AddRefCurrentModule();
if (hModExtraRefCount == NULL)
{
TRC_ERR((TB, _T("AddRefCurrentModule() failed.")));
goto ErrorReturn;
}
//
// Allocate the struct to pass to the thread
//
pStruct = (SCARDHANDLECALLSTRUCT *)
MIDL_user_allocate(sizeof(SCARDHANDLECALLSTRUCT));
if (pStruct == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed to alloc %ld bytes."), sizeof(SCARDHANDLECALLSTRUCT)));
goto ErrorReturn;
}
pStruct->pTHIS = this;
pStruct->dwCallType = pIoRequest->Parameters.DeviceIoControl.IoControlCode;
pStruct->pIoRequestPacket = pIoRequestPacket;
pStruct->hModExtraRefCount = hModExtraRefCount;
pStruct->hThread = NULL;
//
// Create a thread that will do the actual work
//
EnterCriticalSection(&_csThreadList);
//
// If the object is currently being destroyed, then don't create a new thread.
//
if (_fInDestructor)
{
LeaveCriticalSection(&_csThreadList);
goto ErrorReturn;
}
hThread = CreateThread(
NULL,
0,
SCardHandleCall_ThreadProc,
pStruct,
CREATE_SUSPENDED,
&dwThreadId);
if (hThread == NULL)
{
TRC_ERR((TB, _T("CreateThread failed with %lx."), GetLastError()));
LeaveCriticalSection(&_csThreadList);
goto ErrorReturn;
}
if (!AddThreadToList(hThread))
{
LeaveCriticalSection(&_csThreadList);
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
//
// do this so we don't do an extra FreeLibrary. (since the thread actually
// got created the thread istself will do the FreeLibrary).
//
hModExtraRefCount = NULL;
goto ErrorReturn;
}
LeaveCriticalSection(&_csThreadList);
//
// Now let the thread go
//
pStruct->hThread = hThread;
ResumeThread(hThread);
//
// return here and let the thread we just created
// make the EncodeAndChannelWriteLongReturn call,
// which will send the return the calling server
//
break;
case SCARD_IOCTL_ACCESSSTARTEDEVENT:
TRC_DBG((TB, _T("SCARD_IOCTL_ACCESSSTARTEDEVENT")));
AccessStartedEvent(
pIoRequestPacket);
break;
#ifdef OS_WINCE
default:
TRC_ERR((TB, _T("Unsupported ioctl=0x%x(%d) function = %d"), pIoRequest->Parameters.DeviceIoControl.IoControlCode,
pIoRequest->Parameters.DeviceIoControl.IoControlCode, ((pIoRequest->Parameters.DeviceIoControl.IoControlCode & 0x3FFC) >> 2)));
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, STATUS_NOT_SUPPORTED);
break;
#endif
}
#if defined(OS_WINCE) && defined(DEBUG)
if (hModExtraRefCount != NULL)
{
TRC_DATA_DBG("Input buffer",(char *) (pIoRequest + 1), pIoRequest->Parameters.DeviceIoControl.InputBufferLength);
}
#endif
Return:
DC_END_FN();
return;
ErrorReturn:
if (hModExtraRefCount != NULL)
{
FreeLibrary(hModExtraRefCount);
}
MIDL_user_free(pStruct);
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, STATUS_NO_MEMORY);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::AllocateAndChannelWriteReplyPacket
//
//---------------------------------------------------------------------------------------
void
W32SCard::AllocateAndChannelWriteReplyPacket(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN char *pbEncodedBuffer,
IN unsigned long cbEncodedBuffer)
{
DC_BEGIN_FN("W32SCard::AllocateAndChannelWriteReplyPacket");
NTSTATUS status = STATUS_SUCCESS;
PRDPDR_IOCOMPLETION_PACKET pReplyPacket = NULL;
ULONG replyPacketSize = 0;
//
// If we are deleting this object, then just get out.
//
if (_fInDestructor || _fFlushing)
{
delete(pIoRequestPacket);
return;
}
//
// Check the size of the output buffer.
//
status = DrUTL_CheckIOBufOutputSize(pIoRequestPacket, cbEncodedBuffer);
//
// Allocate reply buffer
//
if (status == STATUS_SUCCESS)
{
status = DrUTL_AllocateReplyBuf(
pIoRequestPacket,
&pReplyPacket,
&replyPacketSize);
}
//
// Write reply to channel
//
if (status == STATUS_SUCCESS)
{
memcpy(
pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBuffer,
pbEncodedBuffer,
cbEncodedBuffer);
pReplyPacket->IoCompletion.Parameters.DeviceIoControl.OutputBufferLength
= cbEncodedBuffer;
pReplyPacket->IoCompletion.IoStatus = STATUS_SUCCESS;
//
// in DrUTL_AllocateReplyBuf the replyPacketSize is set to the max size
// allowed given the calling servers output buffer size, but we just need
// cbEncodedBuffer size. And, we know there is enough space since the
// DrUTL_CheckIOBufOutputSize call succeeded
//
replyPacketSize = cbEncodedBuffer +
(ULONG)FIELD_OFFSET(RDPDR_IOCOMPLETION_PACKET,
IoCompletion.Parameters.DeviceIoControl.OutputBuffer);
ProcessObject()->GetVCMgr().ChannelWrite(pReplyPacket, replyPacketSize);
}
else
{
goto ErrorReturn;
}
delete(pIoRequestPacket);
Return:
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::DecodeContextCall
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::DecodeContextCall(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
OUT SCARDCONTEXT *pSCardContext)
{
DC_BEGIN_FN("W32SCard::DecodeContextCall");
RPC_STATUS rpcStatus = RPC_S_OK;
LONG lReturn = SCARD_S_SUCCESS;
handle_t hDec = 0;
Context_Call ContextCall;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Do the decode
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
lReturn = SCARD_E_NO_MEMORY;
goto ErrorReturn;
}
memset(&ContextCall, 0, sizeof(ContextCall));
_TRY_lReturn(Context_Call_Decode(hDec, &ContextCall))
//
// Copy the decoded context to the callers memory
//
if (sizeof(SCARDCONTEXT) != ContextCall.Context.cbContext)
{
TRC_ERR((TB, _T("Invalid context from server")));
lReturn = SCARD_E_INVALID_PARAMETER;
goto ErrorReturn;
}
*pSCardContext = *((SCARDCONTEXT *) ContextCall.Context.pbContext);
//
// Free the resources used for decode of parameters
//
_TRY_2(Context_Call_Free(hDec, &ContextCall))
Return:
SafeMesHandleFree(&hDec);
DC_END_FN();
return (lReturn);
ErrorReturn:
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::DecodeContextAndStringCallA
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::DecodeContextAndStringCallA(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
OUT SCARDCONTEXT *pSCardContext,
OUT LPSTR *ppsz)
{
DC_BEGIN_FN("W32SCard::DecodeContextAndStringCallA");
RPC_STATUS rpcStatus = RPC_S_OK;
LONG lReturn = SCARD_S_SUCCESS;
handle_t hDec = 0;
BOOL fFreeDecode = FALSE;
ContextAndStringA_Call ContextAndStringCallA;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
UINT cbStrLen = 0;
HRESULT hr;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
lReturn = SCARD_E_NO_MEMORY;
goto ErrorReturn;
}
memset(&ContextAndStringCallA, 0, sizeof(ContextAndStringCallA));
_TRY_lReturn(ContextAndStringA_Call_Decode(hDec, &ContextAndStringCallA))
fFreeDecode = TRUE;
//
// Copy the contents to the callers out params
//
if (ContextAndStringCallA.Context.pbContext != NULL)
{
if (sizeof(SCARDCONTEXT) != ContextAndStringCallA.Context.cbContext)
{
TRC_ERR((TB, _T("Invalid context from server")));
lReturn = SCARD_E_INVALID_PARAMETER;
goto ErrorReturn;
}
*pSCardContext = *((SCARDCONTEXT *) ContextAndStringCallA.Context.pbContext);
}
else
{
*pSCardContext = NULL;
}
if (ContextAndStringCallA.sz == NULL)
{
TRC_ERR((TB, _T("Invalid string from server")));
lReturn = SCARD_E_INVALID_VALUE;
goto ErrorReturn;
}
cbStrLen = (strlen(ContextAndStringCallA.sz) + 1) * sizeof(char);
*ppsz = (LPSTR)
MIDL_user_allocate(cbStrLen);
if (*ppsz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
lReturn = SCARD_E_NO_MEMORY;
goto ErrorReturn;
}
hr = StringCbCopyA(*ppsz, cbStrLen, ContextAndStringCallA.sz);
TRC_ASSERT(SUCCEEDED(hr),(TB,_T("Pre checked copy failed: 0x%x"), hr));
Return:
if (fFreeDecode)
{
_TRY_2(ContextAndStringA_Call_Free(hDec, &ContextAndStringCallA))
}
SafeMesHandleFree(&hDec);
DC_END_FN();
return (lReturn);
ErrorReturn:
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::DecodeContextAndStringCallW
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::DecodeContextAndStringCallW(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
OUT SCARDCONTEXT *pSCardContext,
OUT LPWSTR *ppwsz)
{
DC_BEGIN_FN("W32SCard::DecodeContextAndStringCallW");
RPC_STATUS rpcStatus = RPC_S_OK;
LONG lReturn = SCARD_S_SUCCESS;
handle_t hDec = 0;
BOOL fFreeDecode = FALSE;
ContextAndStringW_Call ContextAndStringCallW;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
UINT cbStrLen = 0;
HRESULT hr;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
lReturn = SCARD_E_NO_MEMORY;
goto ErrorReturn;
}
memset(&ContextAndStringCallW, 0, sizeof(ContextAndStringCallW));
_TRY_lReturn(ContextAndStringW_Call_Decode(hDec, &ContextAndStringCallW))
fFreeDecode = TRUE;
//
// Copy the contents to the callers out params
//
if (ContextAndStringCallW.Context.pbContext != NULL)
{
if (sizeof(SCARDCONTEXT) != ContextAndStringCallW.Context.cbContext)
{
TRC_ERR((TB, _T("Invalid context from server")));
lReturn = SCARD_E_INVALID_PARAMETER;
goto ErrorReturn;
}
*pSCardContext = *((SCARDCONTEXT *) ContextAndStringCallW.Context.pbContext);
}
else
{
*pSCardContext = NULL;
}
if (ContextAndStringCallW.sz == NULL)
{
TRC_ERR((TB, _T("Invalid string from server")));
lReturn = SCARD_E_INVALID_VALUE;
goto ErrorReturn;
}
cbStrLen = (wcslen(ContextAndStringCallW.sz) + 1) * sizeof(WCHAR);
*ppwsz = (LPWSTR)
MIDL_user_allocate(cbStrLen);
if (*ppwsz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
lReturn = SCARD_E_NO_MEMORY;
goto ErrorReturn;
}
hr = StringCbCopyW(*ppwsz, cbStrLen, ContextAndStringCallW.sz);
TRC_ASSERT(SUCCEEDED(hr),(TB,_T("Pre checked copy failed: 0x%x"), hr));
Return:
if (fFreeDecode)
{
_TRY_2(ContextAndStringW_Call_Free(hDec, &ContextAndStringCallW))
}
SafeMesHandleFree(&hDec);
DC_END_FN();
return (lReturn);
ErrorReturn:
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::EncodeAndChannelWriteLongReturn
//
//---------------------------------------------------------------------------------------
void
W32SCard::EncodeAndChannelWriteLongReturn(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN LONG lReturn)
{
DC_BEGIN_FN("W32SCard::EncodeAndChannelWriteLongReturn");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hEnc = 0;
Long_Return LongReturn;
//
// Initialiaze struct to be encoded
//
LongReturn.ReturnCode = lReturn;
//
// Encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Long_Return_Encode(hEnc, &LongReturn))
//
// Send the return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::EstablishContext
//
//---------------------------------------------------------------------------------------
void
W32SCard::EstablishContext(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::EstablishContext");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
PRDPDR_IOCOMPLETION_PACKET pReplyPacket = NULL;
ULONG replyPacketSize = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
BOOL fFreeDecode = FALSE;
BOOL fFreeContext = FALSE;
EstablishContext_Call EstablishContextCall;
EstablishContext_Return EstablishContextReturn;
#ifndef OS_WINCE
DWORD dwScope;
#endif
SCARDCONTEXT SCardContext;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&EstablishContextCall, 0, sizeof(EstablishContextCall));
_TRY_status(EstablishContext_Call_Decode(hDec, &EstablishContextCall))
fFreeDecode = TRUE;
//
// Make the call to the SCard subsystem
//
memset(&EstablishContextReturn, 0, sizeof(EstablishContextReturn));
EstablishContextReturn.ReturnCode =
pfnSCardEstablishContext(
EstablishContextCall.dwScope,
NULL,
NULL,
&SCardContext);
if (EstablishContextReturn.ReturnCode == SCARD_S_SUCCESS)
{
EstablishContextReturn.Context.pbContext = (BYTE *) &SCardContext;
EstablishContextReturn.Context.cbContext = sizeof(SCARDCONTEXT);
fFreeContext = TRUE;
}
//
// Encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(EstablishContext_Return_Encode(hEnc, &EstablishContextReturn))
//
// Add the new context to the list before returing to caller
//
if (!AddSCardContextToList(SCardContext))
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(EstablishContext_Call_Free(hDec, &EstablishContextCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
if (fFreeContext)
{
pfnSCardReleaseContext(SCardContext);
}
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::HandleContextCallWithLongReturn
//
//---------------------------------------------------------------------------------------
void
W32SCard::HandleContextCallWithLongReturn(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::HandleContextCallWithLongReturn");
NTSTATUS status = STATUS_SUCCESS;
LONG lReturn = SCARD_S_SUCCESS;
SCARDCONTEXT SCardContext;
//
// Decode the context being released
//
lReturn = DecodeContextCall(pIoRequestPacket, &SCardContext);
if (lReturn == SCARD_S_SUCCESS)
{
//
// Make SCard subsystem call
//
switch(dwCallType)
{
case SCARD_IOCTL_RELEASECONTEXT:
#ifndef OS_WINCE
lReturn = pfnSCardReleaseContext(SCardContext);
#endif
RemoveSCardContextFromList(SCardContext);
#ifdef OS_WINCE
lReturn = pfnSCardReleaseContext(SCardContext); //the context must be released after you cancel any operations on the card
#endif
break;
case SCARD_IOCTL_ISVALIDCONTEXT:
lReturn = pfnSCardIsValidContext(SCardContext);
break;
case SCARD_IOCTL_CANCEL:
lReturn = pfnSCardCancel(SCardContext);
break;
}
}
//
// encode and write the return
//
EncodeAndChannelWriteLongReturn(pIoRequestPacket, lReturn);
Return:
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::EncodeAndChannelWriteLongAndMultiStringReturn
//
//---------------------------------------------------------------------------------------
void
W32SCard::EncodeAndChannelWriteLongAndMultiStringReturn(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN LONG lReturn,
IN BYTE *pb,
IN DWORD cch,
IN BOOL fUnicode)
{
DC_BEGIN_FN("W32SCard::EncodeAndChannelWriteLongAndMultiStringReturn");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t h = 0;
BOOL fFree = FALSE;
struct _LongAndMultiString_Return LongAndMultiSzReturn;
//
// Initialiaze struct to be encoded
//
LongAndMultiSzReturn.ReturnCode = lReturn;
LongAndMultiSzReturn.cBytes = fUnicode ? (cch * sizeof(WCHAR)) : cch;
//
// If we are just returning the byte count then send back a junk buffer
//
if (pb == NULL)
{
LongAndMultiSzReturn.msz = (BYTE *) MIDL_user_allocate(LongAndMultiSzReturn.cBytes);
if (LongAndMultiSzReturn.msz == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(LongAndMultiSzReturn.msz, 0, LongAndMultiSzReturn.cBytes);
}
else
{
LongAndMultiSzReturn.msz = pb;
}
//
// Encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&h);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(ListReaderGroups_Return_Encode(h, &LongAndMultiSzReturn))
//
// Send the return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(LongAndMultiSzReturn.msz);
}
SafeMesHandleFree(&h);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::ListReaderGroups
//
//---------------------------------------------------------------------------------------
void
W32SCard::ListReaderGroups(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::ListReaderGroups");
LONG lReturn = SCARD_S_SUCCESS;
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
handle_t hDec = 0;
SCARDCONTEXT SCardContext;
ListReaderGroups_Call ListReaderGroupsCall;
DWORD cch = 0;
BYTE *pb = NULL;
BOOL fFreeDecode = FALSE;
BOOL fDoAllocationLocally = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&ListReaderGroupsCall, 0, sizeof(ListReaderGroupsCall));
_TRY_status(ListReaderGroups_Call_Decode(hDec, &ListReaderGroupsCall))
fFreeDecode = TRUE;
if (ListReaderGroupsCall.Context.pbContext != NULL)
{
if (sizeof(SCARDCONTEXT) == ListReaderGroupsCall.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) ListReaderGroupsCall.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
}
else
{
SCardContext = NULL;
}
cch = ListReaderGroupsCall.cchGroups;
if (lReturn == SCARD_S_SUCCESS)
{
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
fDoAllocationLocally =
(!ListReaderGroupsCall.fmszGroupsIsNULL &&
(cch != SCARD_AUTOALLOCATE));
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
lReturn = pfnSCardListReaderGroupsW(
SCardContext,
NULL,
&cch);
if ((lReturn == SCARD_S_SUCCESS) && (cch > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_ERR((TB, _T("SCardListReaderGroupsW failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
//
// Make the ListReaderGroups call
//
if (dwCallType == SCARD_IOCTL_LISTREADERGROUPSA)
{
LPSTR psz = NULL;
if (fDoAllocationLocally)
{
psz = (LPSTR) MIDL_user_allocate(cch * sizeof(CHAR));
if (psz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
}
lReturn = pfnSCardListReaderGroupsA(
SCardContext,
(cch == SCARD_AUTOALLOCATE) ? (LPSTR) &psz : psz,
&cch);
pb = (LPBYTE) psz;
}
else
{
LPWSTR pwsz = NULL;
if (fDoAllocationLocally)
{
pwsz = (LPWSTR) MIDL_user_allocate(cch * sizeof(WCHAR));
if (pwsz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
}
lReturn = pfnSCardListReaderGroupsW(
SCardContext,
(cch == SCARD_AUTOALLOCATE) ? (LPWSTR) &pwsz : pwsz,
&cch);
pb = (LPBYTE) pwsz;
}
}
//
// If anything failed, make sure we don't return a string
//
if (lReturn != SCARD_S_SUCCESS)
{
if (fDoAllocationLocally)
{
MIDL_user_free(pb);
}
pb = NULL;
cch = 0;
}
//
// write the return to the channel
//
EncodeAndChannelWriteLongAndMultiStringReturn(
pIoRequestPacket,
lReturn,
pb,
cch,
(dwCallType == SCARD_IOCTL_LISTREADERGROUPSA) ? FALSE : TRUE);
Return:
if (pb != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(pb);
}
else
{
pfnSCardFreeMemory(SCardContext, pb);
}
}
if (fFreeDecode)
{
_TRY_2(ListReaderGroups_Call_Free(hDec, &ListReaderGroupsCall))
}
SafeMesHandleFree(&hDec);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::ListReaderGroups
//
//---------------------------------------------------------------------------------------
void
W32SCard::ListReaders(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::ListReaders");
LONG lReturn = SCARD_S_SUCCESS;
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
handle_t hDec = 0;
SCARDCONTEXT SCardContext;
ListReaders_Call ListReadersCall;
DWORD cch = 0;
BYTE *pb = NULL;
BOOL fFreeDecode = FALSE;
BOOL fDoAllocationLocally = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&ListReadersCall, 0, sizeof(ListReadersCall));
_TRY_status(ListReaders_Call_Decode(hDec, &ListReadersCall))
fFreeDecode = TRUE;
if (ListReadersCall.Context.pbContext != NULL)
{
if (sizeof(SCARDCONTEXT) == ListReadersCall.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) ListReadersCall.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
}
else
{
SCardContext = NULL;
}
cch = ListReadersCall.cchReaders;
if (lReturn == SCARD_S_SUCCESS)
{
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
fDoAllocationLocally =
(!ListReadersCall.fmszReadersIsNULL &&
(cch != SCARD_AUTOALLOCATE));
//
// Make the ListReaders call
//
if (dwCallType == SCARD_IOCTL_LISTREADERSA)
{
LPSTR psz = NULL;
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
lReturn = pfnSCardListReadersA(
SCardContext,
(LPSTR) ListReadersCall.mszGroups,
NULL,
&cch);
if ((lReturn == SCARD_S_SUCCESS) && (cch > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_DBG((TB, _T("SCardListReadersA failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
psz = (LPSTR) MIDL_user_allocate(cch * sizeof(CHAR));
if (psz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
}
lReturn = pfnSCardListReadersA(
SCardContext,
(LPSTR) ListReadersCall.mszGroups,
(cch == SCARD_AUTOALLOCATE) ? (LPSTR) &psz : psz,
&cch);
pb = (LPBYTE) psz;
}
else
{
LPWSTR pwsz = NULL;
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
lReturn = pfnSCardListReadersW(
SCardContext,
SCARD_ALL_READERS,
NULL,
&cch);
if ((lReturn == SCARD_S_SUCCESS) && (cch > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_NRM((TB, _T("SCardListReadersW failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
pwsz = (LPWSTR) MIDL_user_allocate(cch * sizeof(WCHAR));
if (pwsz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
}
lReturn = pfnSCardListReadersW(
SCardContext,
#ifndef OS_WINCE
(LPWSTR) ListReadersCall.mszGroups,
#else
SCARD_ALL_READERS,
#endif
(cch == SCARD_AUTOALLOCATE) ? (LPWSTR) &pwsz : pwsz,
&cch);
pb = (LPBYTE) pwsz;
}
}
//
// If anything failed, make sure we don't return a string
//
if (lReturn != SCARD_S_SUCCESS)
{
if (fDoAllocationLocally)
{
MIDL_user_free(pb);
}
pb = NULL;
cch = 0;
}
//
// write the return to the channel
//
EncodeAndChannelWriteLongAndMultiStringReturn(
pIoRequestPacket,
lReturn,
pb,
cch,
(dwCallType == SCARD_IOCTL_LISTREADERSA) ? FALSE : TRUE);
Return:
if (pb != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(pb);
}
else
{
#ifndef OS_WINCE
pfnSCardFreeMemory(SCardContext, pb);
#else
TRC_ASSERT(FALSE, (TB, _T("Shouldnt get here")));
#endif
}
}
if (fFreeDecode)
{
_TRY_2(ListReaders_Call_Free(hDec, &ListReadersCall))
}
SafeMesHandleFree(&hDec);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::HandleContextAndStringCallWithLongReturn
//
//---------------------------------------------------------------------------------------
void
W32SCard::HandleContextAndStringCallWithLongReturn(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::HandleContextAndStringCallWithLongReturn");
LONG lReturn = SCARD_S_SUCCESS;
NTSTATUS status = STATUS_SUCCESS;
SCARDCONTEXT SCardContext;
LPSTR sz = NULL;
LPWSTR wsz = NULL;
BOOL fASCIICall;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
fASCIICall = ( (dwCallType == SCARD_IOCTL_INTRODUCEREADERGROUPA) ||
(dwCallType == SCARD_IOCTL_FORGETREADERGROUPA) ||
(dwCallType == SCARD_IOCTL_FORGETREADERA));
//
// Decode input params
//
if (fASCIICall)
{
lReturn = DecodeContextAndStringCallA(
pIoRequestPacket,
&SCardContext,
&sz);
}
else
{
lReturn = DecodeContextAndStringCallW(
pIoRequestPacket,
&SCardContext,
&wsz);
}
if (lReturn == SCARD_S_SUCCESS)
{
//
// Make the SCard* call
//
switch (dwCallType)
{
case SCARD_IOCTL_INTRODUCEREADERGROUPA:
lReturn = pfnSCardIntroduceReaderGroupA(
SCardContext,
sz);
break;
case SCARD_IOCTL_INTRODUCEREADERGROUPW:
lReturn = pfnSCardIntroduceReaderGroupW(
SCardContext,
wsz);
break;
case SCARD_IOCTL_FORGETREADERGROUPA:
lReturn = pfnSCardForgetReaderGroupA(
SCardContext,
sz);
break;
case SCARD_IOCTL_FORGETREADERGROUPW:
lReturn = pfnSCardForgetReaderGroupW(
SCardContext,
wsz);
break;
case SCARD_IOCTL_FORGETREADERA:
lReturn = pfnSCardForgetReaderA(
SCardContext,
sz);
break;
case SCARD_IOCTL_FORGETREADERW:
lReturn = pfnSCardForgetReaderW(
SCardContext,
wsz);
break;
}
}
//
// send the return
//
EncodeAndChannelWriteLongReturn(pIoRequestPacket, lReturn);
Return:
MIDL_user_free(sz);
MIDL_user_free(wsz);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::HandleContextAndTwoStringCallWithLongReturn
//
//---------------------------------------------------------------------------------------
void
W32SCard::HandleContextAndTwoStringCallWithLongReturn(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::HandleContextAndTwoStringCallWithLongReturn");
RPC_STATUS rpcStatus = RPC_S_OK;
LONG lReturn = SCARD_S_SUCCESS;
NTSTATUS status = STATUS_SUCCESS;
SCARDCONTEXT SCardContext;
handle_t hDec = 0;
ContextAndTwoStringA_Call ContextAndTwoStringCallA;
ContextAndTwoStringW_Call ContextAndTwoStringCallW;
BOOL fASCIICall;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fASCIICall = ( (dwCallType == SCARD_IOCTL_INTRODUCEREADERA) ||
(dwCallType == SCARD_IOCTL_ADDREADERTOGROUPA) ||
(dwCallType == SCARD_IOCTL_REMOVEREADERFROMGROUPA));
if (fASCIICall)
{
memset(&ContextAndTwoStringCallA, 0, sizeof(ContextAndTwoStringCallA));
_TRY_status(ContextAndTwoStringA_Call_Decode(hDec, &ContextAndTwoStringCallA))
if (sizeof(SCARDCONTEXT) == ContextAndTwoStringCallA.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) ContextAndTwoStringCallA.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
}
else
{
memset(&ContextAndTwoStringCallW, 0, sizeof(ContextAndTwoStringCallW));
_TRY_status(ContextAndTwoStringW_Call_Decode(hDec, &ContextAndTwoStringCallW))
if (sizeof(SCARDCONTEXT) == ContextAndTwoStringCallW.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) ContextAndTwoStringCallW.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
}
//
// Check for NULL input strings
//
switch (dwCallType)
{
case SCARD_IOCTL_INTRODUCEREADERA:
case SCARD_IOCTL_ADDREADERTOGROUPA:
case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
if ((ContextAndTwoStringCallA.sz1 == NULL) ||
(ContextAndTwoStringCallA.sz2 == NULL))
{
lReturn = SCARD_E_INVALID_VALUE;
}
break;
case SCARD_IOCTL_INTRODUCEREADERW:
case SCARD_IOCTL_ADDREADERTOGROUPW:
case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
if ((ContextAndTwoStringCallW.sz1 == NULL) ||
(ContextAndTwoStringCallW.sz2 == NULL))
{
lReturn = SCARD_E_INVALID_VALUE;
}
break;
}
if (lReturn == SCARD_S_SUCCESS)
{
//
// Make the SCard* call
//
switch (dwCallType)
{
case SCARD_IOCTL_INTRODUCEREADERA:
lReturn = pfnSCardIntroduceReaderA(
SCardContext,
ContextAndTwoStringCallA.sz1,
ContextAndTwoStringCallA.sz2);
break;
case SCARD_IOCTL_INTRODUCEREADERW:
lReturn = pfnSCardIntroduceReaderW(
SCardContext,
ContextAndTwoStringCallW.sz1,
ContextAndTwoStringCallW.sz2);
break;
case SCARD_IOCTL_ADDREADERTOGROUPA:
lReturn = pfnSCardAddReaderToGroupA(
SCardContext,
ContextAndTwoStringCallA.sz1,
ContextAndTwoStringCallA.sz2);
break;
case SCARD_IOCTL_ADDREADERTOGROUPW:
lReturn = pfnSCardAddReaderToGroupW(
SCardContext,
ContextAndTwoStringCallW.sz1,
ContextAndTwoStringCallW.sz2);
break;
case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
lReturn = pfnSCardRemoveReaderFromGroupA(
SCardContext,
ContextAndTwoStringCallA.sz1,
ContextAndTwoStringCallA.sz2);
break;
case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
lReturn = pfnSCardRemoveReaderFromGroupW(
SCardContext,
ContextAndTwoStringCallW.sz1,
ContextAndTwoStringCallW.sz2);
break;
}
}
//
// Free up resources used for decode
//
if (fASCIICall)
{
_TRY_2(ContextAndTwoStringA_Call_Free(hDec, &ContextAndTwoStringCallA))
}
else
{
_TRY_2(ContextAndTwoStringW_Call_Free(hDec, &ContextAndTwoStringCallW))
}
//
// send the return
//
EncodeAndChannelWriteLongReturn(pIoRequestPacket, lReturn);
Return:
SafeMesHandleFree(&hDec);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::AllocateAndCopyReaderStateStructsForCall*
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::AllocateAndCopyReaderStateStructsForCallA(
IN DWORD cReaders,
IN ReaderStateA *rgReaderStatesFromDecode,
OUT LPSCARD_READERSTATE_A *prgReadersStatesForSCardCall)
{
DC_BEGIN_FN("W32SCard::AllocateAndCopyReaderStateStructsForCallA");
LPSCARD_READERSTATE_A rgReadersStatesForSCardCall = NULL;
DWORD i;
rgReadersStatesForSCardCall = (LPSCARD_READERSTATE_A)
MIDL_user_allocate(cReaders * sizeof(SCARD_READERSTATE_A));
if (rgReadersStatesForSCardCall == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
return (SCARD_E_NO_MEMORY);
}
memset(rgReadersStatesForSCardCall, 0, cReaders * sizeof(SCARD_READERSTATE_A));
for (i=0; i<cReaders; i++)
{
rgReadersStatesForSCardCall[i].dwCurrentState =
rgReaderStatesFromDecode[i].Common.dwCurrentState;
rgReadersStatesForSCardCall[i].dwEventState =
rgReaderStatesFromDecode[i].Common.dwEventState;
rgReadersStatesForSCardCall[i].cbAtr =
rgReaderStatesFromDecode[i].Common.cbAtr;
memcpy(
rgReadersStatesForSCardCall[i].rgbAtr,
rgReaderStatesFromDecode[i].Common.rgbAtr,
ATR_COPY_SIZE);
//
// just reference string in decoded struct instead of copying.
// this means the decode can't be free'd until the SCard* call is made
//
rgReadersStatesForSCardCall[i].szReader =
rgReaderStatesFromDecode[i].szReader;
}
*prgReadersStatesForSCardCall = rgReadersStatesForSCardCall;
DC_END_FN();
return (SCARD_S_SUCCESS);
}
LONG
W32SCard::AllocateAndCopyReaderStateStructsForCallW(
IN DWORD cReaders,
IN ReaderStateW *rgReaderStatesFromDecode,
OUT LPSCARD_READERSTATE_W *prgReadersStatesForSCardCall)
{
DC_BEGIN_FN("W32SCard::AllocateAndCopyReaderStateStructsForCallW");
LPSCARD_READERSTATE_W rgReadersStatesForSCardCall = NULL;
DWORD i;
rgReadersStatesForSCardCall = (LPSCARD_READERSTATE_W)
MIDL_user_allocate(cReaders * sizeof(SCARD_READERSTATE_W));
if (rgReadersStatesForSCardCall == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
return (SCARD_E_NO_MEMORY);
}
memset(rgReadersStatesForSCardCall, 0, cReaders * sizeof(SCARD_READERSTATE_W));
for (i=0; i<cReaders; i++)
{
rgReadersStatesForSCardCall[i].dwCurrentState =
rgReaderStatesFromDecode[i].Common.dwCurrentState;
rgReadersStatesForSCardCall[i].dwEventState =
rgReaderStatesFromDecode[i].Common.dwEventState;
rgReadersStatesForSCardCall[i].cbAtr =
rgReaderStatesFromDecode[i].Common.cbAtr;
memcpy(
rgReadersStatesForSCardCall[i].rgbAtr,
rgReaderStatesFromDecode[i].Common.rgbAtr,
ATR_COPY_SIZE);
//
// just reference string in decoded struct instead of copying.
// this means the decode can't be free'd until the SCard* call is made
//
rgReadersStatesForSCardCall[i].szReader =
rgReaderStatesFromDecode[i].szReader;
}
*prgReadersStatesForSCardCall = rgReadersStatesForSCardCall;
DC_END_FN();
return (SCARD_S_SUCCESS);
}
//---------------------------------------------------------------------------------------
//
// W32SCard::AllocateAndCopyATRMasksForCall
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::AllocateAndCopyATRMasksForCall(
IN DWORD cAtrs,
IN LocateCards_ATRMask *rgATRMasksFromDecode,
OUT SCARD_ATRMASK **prgATRMasksForCall)
{
DC_BEGIN_FN("W32SCard::AllocateAndCopyATRMasksForCall");
SCARD_ATRMASK *rgATRMasksForCall = NULL;
DWORD i;
rgATRMasksForCall = (SCARD_ATRMASK *)
MIDL_user_allocate(cAtrs * sizeof(SCARD_ATRMASK));
if (rgATRMasksForCall == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
return (SCARD_E_NO_MEMORY);
}
memset(rgATRMasksForCall, 0, cAtrs * sizeof(SCARD_ATRMASK));
for (i=0; i<cAtrs; i++)
{
rgATRMasksForCall[i].cbAtr = rgATRMasksFromDecode[i].cbAtr;
memcpy(
rgATRMasksForCall[i].rgbAtr,
rgATRMasksFromDecode[i].rgbAtr,
ATR_COPY_SIZE);
memcpy(
rgATRMasksForCall[i].rgbMask,
rgATRMasksFromDecode[i].rgbMask,
ATR_COPY_SIZE);
}
*prgATRMasksForCall = rgATRMasksForCall;
DC_END_FN();
return (SCARD_S_SUCCESS);
}
//---------------------------------------------------------------------------------------
//
// W32SCard::AllocateAndCopyReaderStateStructsForReturn*
//
//---------------------------------------------------------------------------------------
LONG
W32SCard::AllocateAndCopyReaderStateStructsForReturnA(
IN DWORD cReaders,
IN LPSCARD_READERSTATE_A rgReaderStatesFromSCardCall,
OUT ReaderState_Return **prgReaderStatesForReturn)
{
DC_BEGIN_FN("W32SCard::AllocateAndCopyReaderStateStructsForReturnA");
ReaderState_Return *rgReaderStatesForReturn = NULL;
DWORD i;
rgReaderStatesForReturn = (ReaderState_Return *)
MIDL_user_allocate(cReaders * sizeof(ReaderState_Return));
if (rgReaderStatesForReturn == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
return (SCARD_E_NO_MEMORY);
}
for (i=0; i<cReaders; i++)
{
rgReaderStatesForReturn[i].dwCurrentState =
rgReaderStatesFromSCardCall[i].dwCurrentState;
rgReaderStatesForReturn[i].dwEventState =
rgReaderStatesFromSCardCall[i].dwEventState;
rgReaderStatesForReturn[i].cbAtr =
rgReaderStatesFromSCardCall[i].cbAtr;
memcpy(
rgReaderStatesForReturn[i].rgbAtr,
rgReaderStatesFromSCardCall[i].rgbAtr,
ATR_COPY_SIZE);
}
*prgReaderStatesForReturn = rgReaderStatesForReturn;
DC_END_FN();
return (SCARD_S_SUCCESS);
}
LONG
W32SCard::AllocateAndCopyReaderStateStructsForReturnW(
IN DWORD cReaders,
IN LPSCARD_READERSTATE_W rgReaderStatesFromSCardCall,
OUT ReaderState_Return **prgReaderStatesForReturn)
{
DC_BEGIN_FN("W32SCard::AllocateAndCopyReaderStateStructsForReturnW");
ReaderState_Return *rgReaderStatesForReturn = NULL;
DWORD i;
rgReaderStatesForReturn = (ReaderState_Return *)
MIDL_user_allocate(cReaders * sizeof(ReaderState_Return));
if (rgReaderStatesForReturn == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
return (SCARD_E_NO_MEMORY);
}
for (i=0; i<cReaders; i++)
{
rgReaderStatesForReturn[i].dwCurrentState =
rgReaderStatesFromSCardCall[i].dwCurrentState;
rgReaderStatesForReturn[i].dwEventState =
rgReaderStatesFromSCardCall[i].dwEventState;
rgReaderStatesForReturn[i].cbAtr =
rgReaderStatesFromSCardCall[i].cbAtr;
memcpy(
rgReaderStatesForReturn[i].rgbAtr,
rgReaderStatesFromSCardCall[i].rgbAtr,
ATR_COPY_SIZE);
}
*prgReaderStatesForReturn = rgReaderStatesForReturn;
DC_END_FN();
return (SCARD_S_SUCCESS);
}
//---------------------------------------------------------------------------------------
//
// W32SCard::LocateCardsA
//
//---------------------------------------------------------------------------------------
void
W32SCard::LocateCardsA(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::LocateCardsA");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
LocateCardsA_Call LocateCardsCallA;
LocateCards_Return LocateCardsReturn;
LPSCARD_READERSTATE_A rgReaderStatesA = NULL;
BOOL fFreeDecode = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&LocateCardsReturn, 0, sizeof(LocateCardsReturn));
LocateCardsReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&LocateCardsCallA, 0, sizeof(LocateCardsCallA));
_TRY_status(LocateCardsA_Call_Decode(hDec, &LocateCardsCallA))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) == LocateCardsCallA.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) LocateCardsCallA.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
LocateCardsReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallA(
LocateCardsCallA.cReaders,
LocateCardsCallA.rgReaderStates,
&rgReaderStatesA);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
LocateCardsReturn.ReturnCode =
pfnSCardLocateCardsA(
SCardContext,
(LPCSTR) LocateCardsCallA.mszCards,
rgReaderStatesA,
LocateCardsCallA.cReaders);
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForReturnA(
LocateCardsCallA.cReaders,
rgReaderStatesA,
&(LocateCardsReturn.rgReaderStates));
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.cReaders = LocateCardsCallA.cReaders;
}
}
_TRY_status(LocateCards_Return_Encode(hEnc, &LocateCardsReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(LocateCardsA_Call_Free(hDec, &LocateCardsCallA))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesA);
MIDL_user_free(LocateCardsReturn.rgReaderStates);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::LocateCardsW
//
//---------------------------------------------------------------------------------------
void
W32SCard::LocateCardsW(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::LocateCardsW");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
LocateCardsW_Call LocateCardsCallW;
LocateCards_Return LocateCardsReturn;
LPSCARD_READERSTATE_W rgReaderStatesW = NULL;
BOOL fFreeDecode = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&LocateCardsReturn, 0, sizeof(LocateCardsReturn));
LocateCardsReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&LocateCardsCallW, 0, sizeof(LocateCardsCallW));
_TRY_status(LocateCardsW_Call_Decode(hDec, &LocateCardsCallW))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) == LocateCardsCallW.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) LocateCardsCallW.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
LocateCardsReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallW(
LocateCardsCallW.cReaders,
LocateCardsCallW.rgReaderStates,
&rgReaderStatesW);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
LocateCardsReturn.ReturnCode =
pfnSCardLocateCardsW(
SCardContext,
(LPCWSTR) LocateCardsCallW.mszCards,
rgReaderStatesW,
LocateCardsCallW.cReaders);
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForReturnW(
LocateCardsCallW.cReaders,
rgReaderStatesW,
&(LocateCardsReturn.rgReaderStates));
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.cReaders = LocateCardsCallW.cReaders;
}
}
_TRY_status(LocateCards_Return_Encode(hEnc, &LocateCardsReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(LocateCardsW_Call_Free(hDec, &LocateCardsCallW))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesW);
MIDL_user_free(LocateCardsReturn.rgReaderStates);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::LocateCardsByATRA
//
//---------------------------------------------------------------------------------------
void
W32SCard::LocateCardsByATRA(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::LocateCardsByATRA");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
LocateCardsByATRA_Call LocateCardsByATRCallA;
LocateCards_Return LocateCardsReturn;
LPSCARD_READERSTATE_A rgReaderStatesA = NULL;
SCARD_ATRMASK *rgATRMasksForCall = NULL;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&LocateCardsReturn, 0, sizeof(LocateCardsReturn));
LocateCardsReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&LocateCardsByATRCallA, 0, sizeof(LocateCardsByATRCallA));
_TRY_status(LocateCardsByATRA_Call_Decode(hDec, &LocateCardsByATRCallA))
if (sizeof(SCARDCONTEXT) == LocateCardsByATRCallA.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) LocateCardsByATRCallA.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
LocateCardsReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyATRMasksForCall(
LocateCardsByATRCallA.cAtrs,
LocateCardsByATRCallA.rgAtrMasks,
&rgATRMasksForCall);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallA(
LocateCardsByATRCallA.cReaders,
LocateCardsByATRCallA.rgReaderStates,
&rgReaderStatesA);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call... if it is available
//
#ifndef OS_WINCE
if (pfnSCardLocateCardsByATRW != NULL)
#else
if (pfnSCardLocateCardsByATRA != NULL)
#endif
{
LocateCardsReturn.ReturnCode =
pfnSCardLocateCardsByATRA(
SCardContext,
rgATRMasksForCall,
LocateCardsByATRCallA.cAtrs,
rgReaderStatesA,
LocateCardsByATRCallA.cReaders);
}
else
{
LocateCardsReturn.ReturnCode = ERROR_CALL_NOT_IMPLEMENTED;
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForReturnA(
LocateCardsByATRCallA.cReaders,
rgReaderStatesA,
&(LocateCardsReturn.rgReaderStates));
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.cReaders = LocateCardsByATRCallA.cReaders;
}
}
_TRY_status(LocateCards_Return_Encode(hEnc, &LocateCardsReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesA);
MIDL_user_free(LocateCardsReturn.rgReaderStates);
MIDL_user_free(rgATRMasksForCall);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::LocateCardsByATRW
//
//---------------------------------------------------------------------------------------
void
W32SCard::LocateCardsByATRW(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::LocateCardsByATRW");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
LocateCardsByATRW_Call LocateCardsByATRCallW;
LocateCards_Return LocateCardsReturn;
LPSCARD_READERSTATE_W rgReaderStatesW = NULL;
SCARD_ATRMASK *rgATRMasksForCall = NULL;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&LocateCardsReturn, 0, sizeof(LocateCardsReturn));
LocateCardsReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&LocateCardsByATRCallW, 0, sizeof(LocateCardsByATRCallW));
_TRY_status(LocateCardsByATRW_Call_Decode(hDec, &LocateCardsByATRCallW))
if (sizeof(SCARDCONTEXT) == LocateCardsByATRCallW.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) LocateCardsByATRCallW.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
LocateCardsReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyATRMasksForCall(
LocateCardsByATRCallW.cAtrs,
LocateCardsByATRCallW.rgAtrMasks,
&rgATRMasksForCall);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallW(
LocateCardsByATRCallW.cReaders,
LocateCardsByATRCallW.rgReaderStates,
&rgReaderStatesW);
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call... if it is available
//
if (pfnSCardLocateCardsByATRW != NULL)
{
LocateCardsReturn.ReturnCode =
pfnSCardLocateCardsByATRW(
SCardContext,
rgATRMasksForCall,
LocateCardsByATRCallW.cAtrs,
rgReaderStatesW,
LocateCardsByATRCallW.cReaders);
}
else
{
LocateCardsReturn.ReturnCode = ERROR_CALL_NOT_IMPLEMENTED;
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForReturnW(
LocateCardsByATRCallW.cReaders,
rgReaderStatesW,
&(LocateCardsReturn.rgReaderStates));
if (LocateCardsReturn.ReturnCode == SCARD_S_SUCCESS)
{
LocateCardsReturn.cReaders = LocateCardsByATRCallW.cReaders;
}
}
_TRY_status(LocateCards_Return_Encode(hEnc, &LocateCardsReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesW);
MIDL_user_free(LocateCardsReturn.rgReaderStates);
MIDL_user_free(rgATRMasksForCall);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::GetStatusChangeThreadProc and W32SCard::GetStatusChangeWrapper
//
//---------------------------------------------------------------------------------------
typedef struct _GETSTATUSCHANGESTRUCT
{
W32SCard *pTHIS;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket;
DWORD dwCallType;
HMODULE hModExtraRefCount;
HANDLE hThread;
} GETSTATUSCHANGESTRUCT;
DWORD WINAPI
W32SCard::GetStatusChangeThreadProc(
LPVOID lpParameter)
{
GETSTATUSCHANGESTRUCT *pGetStatusChangeStruct = (GETSTATUSCHANGESTRUCT *) lpParameter;
W32SCard *pTHIS = pGetStatusChangeStruct->pTHIS;
HANDLE hThread = NULL;
HMODULE hModExtraRefCount = NULL;
//
// pGetStatusChangeStruct->hThread will be NULL if it wasn't added to the thread
// list... if it wasn't added to the thread list then just get out.
//
if (pGetStatusChangeStruct->hThread == NULL)
{
FreeLibraryAndExitThread(pGetStatusChangeStruct->hModExtraRefCount, 0);
}
if (pGetStatusChangeStruct->dwCallType == SCARD_IOCTL_GETSTATUSCHANGEA)
{
pTHIS->GetStatusChangeA(pGetStatusChangeStruct->pIoRequestPacket);
}
else
{
pTHIS->GetStatusChangeW(pGetStatusChangeStruct->pIoRequestPacket);
}
hThread = pGetStatusChangeStruct->hThread;
hModExtraRefCount = pGetStatusChangeStruct->hModExtraRefCount;
MIDL_user_free(pGetStatusChangeStruct);
pTHIS->RemoveThreadFromList(hThread);
FreeLibraryAndExitThread(hModExtraRefCount, 0);
#ifdef OS_WINCE
return 0;
#endif
}
void
W32SCard::GetStatusChangeWrapper(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::GetStatusChangeWrapper");
LONG lReturn = SCARD_S_SUCCESS;
HMODULE hModExtraRefCount = NULL;
GETSTATUSCHANGESTRUCT *pGetStatusChangeStruct = NULL;
DWORD dwThreadId;
HANDLE hThread;
//
// Get a ref count on our dll so that we know the dll
// code won't disappear from underneath us. The thread will
// release this ref count when it exits
//
hModExtraRefCount = AddRefCurrentModule();
if (hModExtraRefCount == NULL)
{
lReturn = SCARD_E_UNEXPECTED;
goto ImmediateReturn;
}
//
// Create a thread to the actual work of the GetStatusChange call
//
// Need to do this since the call can block
//
pGetStatusChangeStruct = (GETSTATUSCHANGESTRUCT *)
MIDL_user_allocate(sizeof(GETSTATUSCHANGESTRUCT));
if (pGetStatusChangeStruct == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
lReturn = SCARD_E_NO_MEMORY;
goto ImmediateReturn;
}
pGetStatusChangeStruct->pTHIS = this;
pGetStatusChangeStruct->pIoRequestPacket = pIoRequestPacket;
pGetStatusChangeStruct->dwCallType = dwCallType;
pGetStatusChangeStruct->hModExtraRefCount = hModExtraRefCount;
pGetStatusChangeStruct->hThread = NULL;
EnterCriticalSection(&_csThreadList);
//
// If the object is currently being destroyed, then don't create a new thread.
//
if (_fInDestructor)
{
LeaveCriticalSection(&_csThreadList);
goto ImmediateReturn;
}
hThread = CreateThread(
NULL,
0,
GetStatusChangeThreadProc,
pGetStatusChangeStruct,
CREATE_SUSPENDED,
&dwThreadId);
if (hThread == NULL)
{
lReturn = SCARD_E_UNEXPECTED;
LeaveCriticalSection(&_csThreadList);
goto ImmediateReturn;
}
if (!AddThreadToList(hThread))
{
LeaveCriticalSection(&_csThreadList);
ResumeThread(hThread);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
goto ImmediateReturn;
}
LeaveCriticalSection(&_csThreadList);
//
// Now let the thread go
//
pGetStatusChangeStruct->hThread = hThread;
ResumeThread(hThread);
//
// Return here and let the thread that was just created
// do the real work.
//
Return:
DC_END_FN();
return;
ImmediateReturn:
if (hModExtraRefCount != NULL)
{
FreeLibrary(hModExtraRefCount);
}
MIDL_user_free(pGetStatusChangeStruct);
EncodeAndChannelWriteLongReturn(
pIoRequestPacket,
lReturn);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::GetStatusChangeA
//
//---------------------------------------------------------------------------------------
void
W32SCard::GetStatusChangeA(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::GetStatusChangeA");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
GetStatusChangeA_Call GetStatusChangeCallA;
GetStatusChange_Return GetStatusChangeReturn;
LPSCARD_READERSTATE_A rgReaderStatesA = NULL;
BOOL fFreeDecode = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&GetStatusChangeReturn, 0, sizeof(GetStatusChangeReturn));
GetStatusChangeReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&GetStatusChangeCallA, 0, sizeof(GetStatusChangeCallA));
_TRY_status(GetStatusChangeA_Call_Decode(hDec, &GetStatusChangeCallA))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) == GetStatusChangeCallA.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) GetStatusChangeCallA.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
GetStatusChangeReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallA(
GetStatusChangeCallA.cReaders,
GetStatusChangeCallA.rgReaderStates,
&rgReaderStatesA);
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
GetStatusChangeReturn.ReturnCode =
pfnSCardGetStatusChangeA(
SCardContext,
GetStatusChangeCallA.dwTimeOut,
rgReaderStatesA,
GetStatusChangeCallA.cReaders);
}
#ifdef OS_WINCE
if (GetStatusChangeReturn.ReturnCode != SCARD_S_SUCCESS)
{
for (DWORD i=0; i<GetStatusChangeCallA.cReaders; i++)
{
if (strcmp(rgReaderStatesA[i].szReader, SCPNP_NOTIFICATIONA) == 0)
{
rgReaderStatesA[i].dwEventState = SCARD_STATE_CHANGED | 0x00010000; //the desktop returns this value. what is it defined to?
GetStatusChangeReturn.ReturnCode = SCARD_S_SUCCESS;
}
}
}
#endif
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.ReturnCode
= AllocateAndCopyReaderStateStructsForReturnA(
GetStatusChangeCallA.cReaders,
rgReaderStatesA,
&(GetStatusChangeReturn.rgReaderStates));
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.cReaders = GetStatusChangeCallA.cReaders;
}
}
_TRY_status(GetStatusChange_Return_Encode(hEnc, &GetStatusChangeReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(GetStatusChangeA_Call_Free(hDec, &GetStatusChangeCallA))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesA);
MIDL_user_free(GetStatusChangeReturn.rgReaderStates);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::GetStatusChangeW
//
//---------------------------------------------------------------------------------------
void
W32SCard::GetStatusChangeW(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::GetStatusChangeW");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
GetStatusChangeW_Call GetStatusChangeCallW;
GetStatusChange_Return GetStatusChangeReturn;
LPSCARD_READERSTATE_W rgReaderStatesW = NULL;
BOOL fFreeDecode = FALSE;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&GetStatusChangeReturn, 0, sizeof(GetStatusChangeReturn));
GetStatusChangeReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and copy the input params
//
memset(&GetStatusChangeCallW, 0, sizeof(GetStatusChangeCallW));
_TRY_status(GetStatusChangeW_Call_Decode(hDec, &GetStatusChangeCallW))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) == GetStatusChangeCallW.Context.cbContext)
{
SCardContext = *((SCARDCONTEXT *) GetStatusChangeCallW.Context.pbContext);
}
else
{
TRC_ERR((TB, _T("Invalid context sent from server.")));
GetStatusChangeReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForCallW(
GetStatusChangeCallW.cReaders,
GetStatusChangeCallW.rgReaderStates,
&rgReaderStatesW);
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
GetStatusChangeReturn.ReturnCode =
pfnSCardGetStatusChangeW(
SCardContext,
GetStatusChangeCallW.dwTimeOut,
rgReaderStatesW,
GetStatusChangeCallW.cReaders);
}
#ifdef OS_WINCE
if (GetStatusChangeReturn.ReturnCode != SCARD_S_SUCCESS)
{
for (DWORD i=0; i<GetStatusChangeCallW.cReaders; i++)
{
if (lstrcmp(rgReaderStatesW[i].szReader, SCPNP_NOTIFICATION) == 0)
{
rgReaderStatesW[i].dwEventState = SCARD_STATE_CHANGED | 0x00010000; //the desktop returns this value. what is it defined to?
GetStatusChangeReturn.ReturnCode = SCARD_S_SUCCESS;
}
}
}
#endif
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.ReturnCode =
AllocateAndCopyReaderStateStructsForReturnW(
GetStatusChangeCallW.cReaders,
rgReaderStatesW,
&(GetStatusChangeReturn.rgReaderStates));
if (GetStatusChangeReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetStatusChangeReturn.cReaders = GetStatusChangeCallW.cReaders;
}
}
_TRY_status(GetStatusChange_Return_Encode(hEnc, &GetStatusChangeReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(GetStatusChangeW_Call_Free(hDec, &GetStatusChangeCallW))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(rgReaderStatesW);
MIDL_user_free(GetStatusChangeReturn.rgReaderStates);
MIDL_user_free(pbEncodedBuffer);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::Connect
//
//---------------------------------------------------------------------------------------
void
W32SCard::Connect(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::Connect");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
ConnectA_Call ConnectCallA;
ConnectW_Call ConnectCallW;
Connect_Return ConnectReturn;
BOOL fFreeDecode = FALSE;
BOOL fFreeHandle = FALSE;
SCARDHANDLE SCardHandle;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&ConnectReturn, 0, sizeof(ConnectReturn));
ConnectReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode input params and make the call to SCard*
//
if (dwCallType == SCARD_IOCTL_CONNECTA)
{
memset(&ConnectCallA, 0, sizeof(ConnectCallA));
_TRY_status(ConnectA_Call_Decode(hDec, &ConnectCallA))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) != ConnectCallA.Common.Context.cbContext)
{
TRC_ERR((TB, _T("Invalid parameter sent from server.")));
ConnectReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
else if (ConnectCallA.szReader == NULL)
{
TRC_ERR((TB, _T("Invalid parameter sent from server.")));
ConnectReturn.ReturnCode = SCARD_E_INVALID_VALUE;
}
else
{
SCardContext = *((SCARDCONTEXT *) ConnectCallA.Common.Context.pbContext);
ConnectReturn.ReturnCode =
pfnSCardConnectA(
SCardContext,
ConnectCallA.szReader,
ConnectCallA.Common.dwShareMode,
ConnectCallA.Common.dwPreferredProtocols,
&SCardHandle,
&ConnectReturn.dwActiveProtocol);
}
}
else
{
memset(&ConnectCallW, 0, sizeof(ConnectCallW));
_TRY_status(ConnectW_Call_Decode(hDec, &ConnectCallW))
fFreeDecode = TRUE;
if (sizeof(SCARDCONTEXT) != ConnectCallW.Common.Context.cbContext)
{
TRC_ERR((TB, _T("Invalid parameter sent from server.")));
ConnectReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
else if (ConnectCallW.szReader == NULL)
{
TRC_ERR((TB, _T("Invalid parameter sent from server.")));
ConnectReturn.ReturnCode = SCARD_E_INVALID_VALUE;
}
else
{
SCardContext = *((SCARDCONTEXT *) ConnectCallW.Common.Context.pbContext);
ConnectReturn.ReturnCode =
pfnSCardConnectW(
SCardContext,
ConnectCallW.szReader,
ConnectCallW.Common.dwShareMode,
ConnectCallW.Common.dwPreferredProtocols,
&SCardHandle,
&ConnectReturn.dwActiveProtocol);
}
}
if (ConnectReturn.ReturnCode == SCARD_S_SUCCESS)
{
ConnectReturn.hCard.Context.pbContext = 0;
ConnectReturn.hCard.Context.pbContext = NULL;
ConnectReturn.hCard.pbHandle = (BYTE *) &SCardHandle;
ConnectReturn.hCard.cbHandle = sizeof(SCARDHANDLE);
fFreeHandle = TRUE;
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Connect_Return_Encode(hEnc, &ConnectReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
if (dwCallType == SCARD_IOCTL_CONNECTA)
{
_TRY_2(ConnectA_Call_Free(hDec, &ConnectCallA))
}
else
{
_TRY_2(ConnectW_Call_Free(hDec, &ConnectCallW))
}
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
if (fFreeHandle)
{
pfnSCardDisconnect(SCardHandle, SCARD_LEAVE_CARD);
}
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::Reconnect
//
//---------------------------------------------------------------------------------------
void
W32SCard::Reconnect(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::Reconnect");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDHANDLE SCardHandle;
Reconnect_Call ReconnectCall;
Reconnect_Return ReconnectReturn;
BOOL fFreeDecode = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&ReconnectReturn, 0, sizeof(ReconnectReturn));
ReconnectReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode input params and make the call to SCard*
//
memset(&ReconnectCall, 0, sizeof(ReconnectCall));
_TRY_status(Reconnect_Call_Decode(hDec, &ReconnectCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == ReconnectCall.hCard.cbHandle)
{
SCardHandle = *((SCARDHANDLE *) ReconnectCall.hCard.pbHandle);
ReconnectReturn.ReturnCode =
pfnSCardReconnect(
SCardHandle,
ReconnectCall.dwShareMode,
ReconnectCall.dwPreferredProtocols,
ReconnectCall.dwInitialization,
&ReconnectReturn.dwActiveProtocol);
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
ReconnectReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Reconnect_Return_Encode(hEnc, &ReconnectReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFreeDecode)
{
_TRY_2(Reconnect_Call_Free(hDec, &ReconnectCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::HandleHCardAndDispositionCall
//
//---------------------------------------------------------------------------------------
void
W32SCard::HandleHCardAndDispositionCall(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::HandleHCardAndDispositionCall");
LONG lReturn = SCARD_S_SUCCESS;
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
handle_t hDec = 0;
SCARDHANDLE SCardHandle;
DWORD dwDisposition;
HCardAndDisposition_Call HCardAndDispositionCall;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&HCardAndDispositionCall, 0, sizeof(HCardAndDispositionCall));
_TRY_status(HCardAndDisposition_Call_Decode(hDec, &HCardAndDispositionCall))
if (sizeof(SCARDHANDLE) == HCardAndDispositionCall.hCard.cbHandle)
{
SCardHandle = *((SCARDHANDLE *) HCardAndDispositionCall.hCard.pbHandle);
dwDisposition = HCardAndDispositionCall.dwDisposition;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
//
// Free up resources used by decode
//
_TRY_2(HCardAndDisposition_Call_Free(hDec, &HCardAndDispositionCall))
SafeMesHandleFree(&hDec);
if (lReturn == SCARD_S_SUCCESS)
{
//
// Make SCard subsystem call
//
switch(dwCallType)
{
case SCARD_IOCTL_DISCONNECT:
lReturn = pfnSCardDisconnect(SCardHandle, dwDisposition);
break;
case SCARD_IOCTL_BEGINTRANSACTION:
lReturn = pfnSCardBeginTransaction(SCardHandle);
break;
case SCARD_IOCTL_ENDTRANSACTION:
lReturn = pfnSCardEndTransaction(SCardHandle, dwDisposition);
break;
}
}
//
// encode and write the return
//
EncodeAndChannelWriteLongReturn(pIoRequestPacket, lReturn);
Return:
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
#ifndef OS_WINCE
//---------------------------------------------------------------------------------------
//
// W32SCard::State
//
//---------------------------------------------------------------------------------------
void
W32SCard::State(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::State");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
State_Call StateCall;
State_Return StateReturn;
BOOL fFreeDecode = FALSE;
DWORD cbAtr = 0;
BOOL fDoAllocationLocally = FALSE;
LPBYTE pbAtr = NULL;
BOOL fFree = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&StateReturn, 0, sizeof(StateReturn));
StateReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode input params
//
memset(&StateCall, 0, sizeof(StateCall));
_TRY_status(State_Call_Decode(hDec, &StateCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == StateCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) StateCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) StateCall.hCard.pbHandle);
cbAtr = StateCall.cbAtrLen;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
StateReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (StateReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
fDoAllocationLocally =
(!StateCall.fpbAtrIsNULL &&
(cbAtr != SCARD_AUTOALLOCATE));
if (fDoAllocationLocally)
{
pbAtr = (LPBYTE) MIDL_user_allocate(cbAtr * sizeof(BYTE));
if (pbAtr == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
StateReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
if (StateReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
StateReturn.ReturnCode =
pfnSCardState(
SCardHandle,
&StateReturn.dwState,
&StateReturn.dwProtocol,
(cbAtr == SCARD_AUTOALLOCATE) ? (LPBYTE) &pbAtr : pbAtr,
&cbAtr);
}
if (StateReturn.ReturnCode == SCARD_S_SUCCESS)
{
StateReturn.cbAtrLen = cbAtr;
//
// If we are just returning the byte count then send back a junk buffer
//
if (pbAtr == NULL)
{
StateReturn.rgAtr = (BYTE *) MIDL_user_allocate(cbAtr);
if (StateReturn.rgAtr == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(StateReturn.rgAtr, 0, cbAtr);
}
else
{
StateReturn.rgAtr = pbAtr;
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(State_Return_Encode(hEnc, &StateReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(StateReturn.rgAtr);
}
if (pbAtr != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(pbAtr);
}
else
{
pfnSCardFreeMemory(SCardContext, pbAtr);
}
}
if (fFreeDecode)
{
_TRY_2(State_Call_Free(hDec, &StateCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
#endif
//---------------------------------------------------------------------------------------
//
// W32SCard::Status
//
//---------------------------------------------------------------------------------------
void
W32SCard::Status(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall,
IN DWORD dwCallType)
{
DC_BEGIN_FN("W32SCard::Status");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
Status_Call StatusCall;
Status_Return StatusReturn;
BOOL fFreeDecode = FALSE;
DWORD cchReaderLen = 0;
BOOL fDoAllocationLocally = FALSE;
LPBYTE psz = NULL;
BOOL fFree = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&StatusReturn, 0, sizeof(StatusReturn));
StatusReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&StatusCall, 0, sizeof(StatusCall));
_TRY_status(Status_Call_Decode(hDec, &StatusCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == StatusCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) StatusCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) StatusCall.hCard.pbHandle);
cchReaderLen = StatusCall.cchReaderLen;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
StatusReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (StatusReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
fDoAllocationLocally =
(!StatusCall.fmszReaderNamesIsNULL &&
(cchReaderLen != SCARD_AUTOALLOCATE));
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
StatusReturn.cbAtrLen = ATR_SIZE;
StatusReturn.ReturnCode =
pfnSCardStatusW(
SCardHandle,
NULL,
&cchReaderLen,
&StatusReturn.dwState,
&StatusReturn.dwProtocol,
(LPBYTE) &StatusReturn.pbAtr,
&StatusReturn.cbAtrLen);
if ((StatusReturn.ReturnCode == SCARD_S_SUCCESS) && (cchReaderLen > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_ERR((TB, _T("SCardStatusW failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
DWORD dwCharSize = (dwCallType == SCARD_IOCTL_STATUSA) ?
sizeof(char) : sizeof(WCHAR);
psz = (LPBYTE) MIDL_user_allocate(cchReaderLen * dwCharSize);
if (psz == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
StatusReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
if (StatusReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Make the call
//
StatusReturn.cbAtrLen = ATR_SIZE;
if (dwCallType == SCARD_IOCTL_STATUSA)
{
StatusReturn.ReturnCode =
pfnSCardStatusA(
SCardHandle,
(cchReaderLen == SCARD_AUTOALLOCATE) ? (LPSTR) &psz : (LPSTR) psz,
&cchReaderLen,
&StatusReturn.dwState,
&StatusReturn.dwProtocol,
(LPBYTE) &StatusReturn.pbAtr,
&StatusReturn.cbAtrLen);
if (StatusReturn.ReturnCode == SCARD_S_SUCCESS)
{
StatusReturn.cBytes = cchReaderLen * sizeof(char);
StatusReturn.mszReaderNames = psz;
}
}
else
{
StatusReturn.ReturnCode =
pfnSCardStatusW(
SCardHandle,
(cchReaderLen == SCARD_AUTOALLOCATE) ? (LPWSTR) &psz : (LPWSTR) psz,
&cchReaderLen,
&StatusReturn.dwState,
&StatusReturn.dwProtocol,
(LPBYTE) &StatusReturn.pbAtr,
&StatusReturn.cbAtrLen);
if (StatusReturn.ReturnCode == SCARD_S_SUCCESS)
{
StatusReturn.cBytes = cchReaderLen * sizeof(WCHAR);
StatusReturn.mszReaderNames = psz;
}
}
}
if (StatusReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// If we are just returning the byte count then send back a junk buffer
//
if (StatusReturn.mszReaderNames == NULL)
{
StatusReturn.mszReaderNames = (BYTE *) MIDL_user_allocate(StatusReturn.cBytes);
if (StatusReturn.mszReaderNames == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(StatusReturn.mszReaderNames, 0, StatusReturn.cBytes);
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Status_Return_Encode(hEnc, &StatusReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(StatusReturn.mszReaderNames);
}
if (psz != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(psz);
}
else
{
#ifndef OS_WINCE
pfnSCardFreeMemory(SCardContext, psz);
#else
TRC_ASSERT(FALSE, (TB, _T("Shouldnt get here")));
#endif
}
}
if (fFreeDecode)
{
_TRY_2(Status_Call_Free(hDec, &StatusCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::Transmit
//
//---------------------------------------------------------------------------------------
void
W32SCard::Transmit(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::Transmit");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
Transmit_Call TransmitCall;
Transmit_Return TransmitReturn;
BOOL fFreeDecode = FALSE;
BOOL fDoAllocationLocally = FALSE;
SCARD_IO_REQUEST *pSendPci = NULL;
SCARD_IO_REQUEST *pRecvPci = NULL;
SCardIO_Request *pReturnRecvPci = NULL;
DWORD cbRecvLength;
BYTE *pbRecvBuffer = NULL;
BOOL fFree = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&TransmitReturn, 0, sizeof(TransmitReturn));
TransmitReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode and setup the input params
//
memset(&TransmitCall, 0, sizeof(TransmitCall));
_TRY_status(Transmit_Call_Decode(hDec, &TransmitCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == TransmitCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) TransmitCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) TransmitCall.hCard.pbHandle);
cbRecvLength = TransmitCall.cbRecvLength;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
TransmitReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
//
// setup the pSendPci param of the call based on callers input
//
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
pSendPci = (LPSCARD_IO_REQUEST)
MIDL_user_allocate( sizeof(SCARD_IO_REQUEST) +
TransmitCall.ioSendPci.cbExtraBytes);
if (pSendPci != NULL)
{
pSendPci->dwProtocol = TransmitCall.ioSendPci.dwProtocol;
pSendPci->cbPciLength = sizeof(SCARD_IO_REQUEST) +
TransmitCall.ioSendPci.cbExtraBytes;
if (TransmitCall.ioSendPci.cbExtraBytes != 0)
{
memcpy(
((LPBYTE) pSendPci) + sizeof(SCARD_IO_REQUEST),
TransmitCall.ioSendPci.pbExtraBytes,
TransmitCall.ioSendPci.cbExtraBytes);
}
}
else
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
TransmitReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
//
// setup the pRecvPci param of the call based on callers input
//
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
if (TransmitCall.pioRecvPci != NULL)
{
pRecvPci = (LPSCARD_IO_REQUEST)
MIDL_user_allocate( sizeof(SCARD_IO_REQUEST) +
TransmitCall.pioRecvPci->cbExtraBytes);
if (pRecvPci != NULL)
{
pRecvPci->dwProtocol = TransmitCall.pioRecvPci->dwProtocol;
pRecvPci->cbPciLength = sizeof(SCARD_IO_REQUEST) +
TransmitCall.pioRecvPci->cbExtraBytes;
if (TransmitCall.ioSendPci.cbExtraBytes != 0)
{
memcpy(
((LPBYTE) pRecvPci) + sizeof(SCARD_IO_REQUEST),
TransmitCall.pioRecvPci->pbExtraBytes,
TransmitCall.pioRecvPci->cbExtraBytes);
}
}
else
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
TransmitReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
fDoAllocationLocally =
(!TransmitCall.fpbRecvBufferIsNULL &&
(cbRecvLength != SCARD_AUTOALLOCATE));
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
TransmitReturn.ReturnCode =
pfnSCardTransmit(
SCardHandle,
pSendPci,
TransmitCall.pbSendBuffer,
TransmitCall.cbSendLength,
pRecvPci,
NULL,
&cbRecvLength);
if ((TransmitReturn.ReturnCode == SCARD_S_SUCCESS) && (cbRecvLength > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_ERR((TB, _T("SCardTransmit failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
pbRecvBuffer = (LPBYTE) MIDL_user_allocate(cbRecvLength * sizeof(BYTE));
if (pbRecvBuffer == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
TransmitReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
//
// Make the call
//
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
TransmitReturn.ReturnCode =
pfnSCardTransmit(
SCardHandle,
pSendPci,
TransmitCall.pbSendBuffer,
TransmitCall.cbSendLength,
pRecvPci,
(cbRecvLength == SCARD_AUTOALLOCATE) ?
(LPBYTE) &pbRecvBuffer : pbRecvBuffer,
&cbRecvLength);
}
//
// copy over the output the return struct to be encoded
//
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
if (pRecvPci != NULL)
{
//
// Allocate space for struct plus the extra bytes at the end of it
// if needed
//
pReturnRecvPci = (SCardIO_Request *)
MIDL_user_allocate(
sizeof(SCardIO_Request) +
pRecvPci->cbPciLength);
if (pReturnRecvPci != NULL)
{
pReturnRecvPci->dwProtocol = pRecvPci->dwProtocol;
pReturnRecvPci->cbExtraBytes = pRecvPci->cbPciLength -
sizeof(SCARD_IO_REQUEST);
if (pReturnRecvPci->cbExtraBytes != 0)
{
//
// put bytes at end of struct since we allocated enough space for it
//
memcpy(
((LPBYTE) pReturnRecvPci) + sizeof(SCardIO_Request),
((LPBYTE) pRecvPci) + sizeof(SCARD_IO_REQUEST),
pReturnRecvPci->cbExtraBytes);
}
TransmitReturn.pioRecvPci = pReturnRecvPci;
}
else
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
TransmitReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
else
{
TransmitReturn.pioRecvPci = NULL;
}
TransmitReturn.cbRecvLength = cbRecvLength;
TransmitReturn.pbRecvBuffer = pbRecvBuffer;
}
if (TransmitReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// If we are just returning the byte count then send back a junk buffer
//
if (TransmitReturn.pbRecvBuffer == NULL)
{
TransmitReturn.pbRecvBuffer = (BYTE *) MIDL_user_allocate(TransmitReturn.cbRecvLength);
if (TransmitReturn.pbRecvBuffer == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(TransmitReturn.pbRecvBuffer, 0, TransmitReturn.cbRecvLength);
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Transmit_Return_Encode(hEnc, &TransmitReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(TransmitReturn.pbRecvBuffer);
}
MIDL_user_free(pSendPci);
MIDL_user_free(pRecvPci);
MIDL_user_free(pReturnRecvPci);
if (pbRecvBuffer != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(pbRecvBuffer);
}
else
{
#ifndef OS_WINCE
pfnSCardFreeMemory(SCardContext, pbRecvBuffer);
#else
TRC_ASSERT(FALSE, (TB, _T("Shouldnt get here")));
#endif
}
}
if (fFreeDecode)
{
_TRY_2(Transmit_Call_Free(hDec, &TransmitCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::Control
//
//---------------------------------------------------------------------------------------
void
W32SCard::Control(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::Control");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
Control_Call ControlCall;
Control_Return ControlReturn;
BOOL fFreeDecode = FALSE;
BOOL fDoAllocationLocally = FALSE;
DWORD cbBytesReturned = 0;
LPVOID lpOutBuffer = NULL;
BOOL fFree = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&ControlReturn, 0, sizeof(ControlReturn));
ControlReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
//
// Decode input params
//
memset(&ControlCall, 0, sizeof(ControlCall));
_TRY_status(Control_Call_Decode(hDec, &ControlCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == ControlCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) ControlCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) ControlCall.hCard.pbHandle);
cbBytesReturned = ControlCall.cbOutBufferSize;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
ControlReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
if (ControlReturn.ReturnCode == SCARD_S_SUCCESS)
{
fDoAllocationLocally =
(!ControlCall.fpvOutBufferIsNULL &&
(cbBytesReturned != SCARD_AUTOALLOCATE));
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
ControlReturn.ReturnCode =
pfnSCardControl(
SCardHandle,
ControlCall.dwControlCode,
ControlCall.pvInBuffer,
ControlCall.cbInBufferSize,
NULL,
cbBytesReturned,
&cbBytesReturned);
if ((ControlReturn.ReturnCode == SCARD_S_SUCCESS) && (cbBytesReturned > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_ERR((TB, _T("SCardControl failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
lpOutBuffer = (LPVOID) MIDL_user_allocate(cbBytesReturned * sizeof(BYTE));
if (lpOutBuffer == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
ControlReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
//
// Make the call
//
if (ControlReturn.ReturnCode == SCARD_S_SUCCESS)
{
ControlReturn.ReturnCode =
pfnSCardControl(
SCardHandle,
ControlCall.dwControlCode,
ControlCall.pvInBuffer,
ControlCall.cbInBufferSize,
(cbBytesReturned == SCARD_AUTOALLOCATE) ? (LPVOID) &lpOutBuffer : lpOutBuffer,
cbBytesReturned,
&cbBytesReturned);
}
if (ControlReturn.ReturnCode == SCARD_S_SUCCESS)
{
ControlReturn.cbOutBufferSize = cbBytesReturned;
//
// If we are just returning the byte count then send back a junk buffer
//
if (lpOutBuffer == NULL)
{
ControlReturn.pvOutBuffer = (BYTE *) MIDL_user_allocate(cbBytesReturned);
if (ControlReturn.pvOutBuffer == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(ControlReturn.pvOutBuffer, 0, cbBytesReturned);
}
else
{
ControlReturn.pvOutBuffer = (LPBYTE) lpOutBuffer;
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(Control_Return_Encode(hEnc, &ControlReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(ControlReturn.pvOutBuffer);
}
if (lpOutBuffer != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(lpOutBuffer);
}
else
{
#ifndef OS_WINCE
pfnSCardFreeMemory(SCardContext, lpOutBuffer);
#else
TRC_ASSERT(FALSE, (TB, _T("Shouldnt get here")));
#endif
}
}
if (fFreeDecode)
{
_TRY_2(Control_Call_Free(hDec, &ControlCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::GetAttrib
//
//---------------------------------------------------------------------------------------
void
W32SCard::GetAttrib(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::GetAttrib");
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
char *pbEncodedBuffer = NULL;
unsigned long cbEncodedBuffer = 0;
handle_t hDec = 0;
handle_t hEnc = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
GetAttrib_Call GetAttribCall;
GetAttrib_Return GetAttribReturn;
BOOL fFreeDecode = FALSE;
DWORD cbAttrLen = 0;
BOOL fDoAllocationLocally = FALSE;
LPBYTE pbAttr = NULL;
BOOL fFree = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
memset(&GetAttribReturn, 0, sizeof(GetAttribReturn));
GetAttribReturn.ReturnCode = SCARD_S_SUCCESS;
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&GetAttribCall, 0, sizeof(GetAttribCall));
_TRY_status(GetAttrib_Call_Decode(hDec, &GetAttribCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == GetAttribCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) GetAttribCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) GetAttribCall.hCard.pbHandle);
cbAttrLen = GetAttribCall.cbAttrLen;
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
GetAttribReturn.ReturnCode = SCARD_E_INVALID_PARAMETER;
}
if (GetAttribReturn.ReturnCode == SCARD_S_SUCCESS)
{
//
// Allocate if not in SCARD_AUTOALLOCATE mode and not a size only call
//
fDoAllocationLocally =
(!GetAttribCall.fpbAttrIsNULL &&
(cbAttrLen != SCARD_AUTOALLOCATE));
#ifdef OS_WINCE
if (!fDoAllocationLocally)
{
GetAttribReturn.ReturnCode =
pfnSCardGetAttrib(
SCardHandle,
GetAttribCall.dwAttrId,
NULL,
&cbAttrLen);
if ((GetAttribReturn.ReturnCode == SCARD_S_SUCCESS) && (cbAttrLen > 0))
fDoAllocationLocally = TRUE;
else
{
TRC_ERR((TB, _T("SCardGetAttrib failed")));
status = STATUS_UNSUCCESSFUL;
goto ErrorReturn;
}
}
#endif
if (fDoAllocationLocally)
{
pbAttr = (LPBYTE) MIDL_user_allocate(cbAttrLen);
if (pbAttr == NULL)
{
TRC_ERR((TB, _T("MIDL_user_allocate failed")));
GetAttribReturn.ReturnCode = SCARD_E_NO_MEMORY;
}
}
}
//
// Make the call
//
if (GetAttribReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetAttribReturn.ReturnCode =
pfnSCardGetAttrib(
SCardHandle,
GetAttribCall.dwAttrId,
(cbAttrLen == SCARD_AUTOALLOCATE) ? (LPBYTE) &pbAttr : pbAttr,
&cbAttrLen);
if (GetAttribReturn.ReturnCode == SCARD_S_SUCCESS)
{
GetAttribReturn.cbAttrLen = cbAttrLen;
//
// If we are just returning the byte count then send back a junk buffer
//
if (pbAttr == NULL)
{
GetAttribReturn.pbAttr = (BYTE *) MIDL_user_allocate(cbAttrLen);
if (GetAttribReturn.pbAttr == NULL)
{
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
fFree = TRUE;
memset(GetAttribReturn.pbAttr, 0, cbAttrLen);
}
else
{
GetAttribReturn.pbAttr = pbAttr;
}
}
}
//
// encode the return
//
rpcStatus = MesEncodeDynBufferHandleCreate(
&pbEncodedBuffer,
&cbEncodedBuffer,
&hEnc);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesEncodeDynBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
_TRY_status(GetAttrib_Return_Encode(hEnc, &GetAttribReturn))
//
// Send return
//
AllocateAndChannelWriteReplyPacket(
pIoRequestPacket,
pbEncodedBuffer,
cbEncodedBuffer);
Return:
if (fFree)
{
MIDL_user_free(GetAttribReturn.pbAttr);
}
if (pbAttr != NULL)
{
//
// Check to see whether we allocated or SCard allcated for us
//
if (fDoAllocationLocally)
{
MIDL_user_free(pbAttr);
}
else
{
#ifndef OS_WINCE
pfnSCardFreeMemory(SCardContext, pbAttr);
#else
TRC_ASSERT(FALSE, (TB, _T("Shouldnt get here")));
#endif
}
}
if (fFreeDecode)
{
_TRY_2(GetAttrib_Call_Free(hDec, &GetAttribCall))
}
SafeMesHandleFree(&hDec);
SafeMesHandleFree(&hEnc);
MIDL_user_free(pbEncodedBuffer);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
//---------------------------------------------------------------------------------------
//
// W32SCard::SetAttrib
//
//---------------------------------------------------------------------------------------
void
W32SCard::SetAttrib(
IN SCARDHANDLECALLSTRUCT *pSCardHandleCall)
{
DC_BEGIN_FN("W32SCard::SetAttrib");
LONG lReturn = SCARD_S_SUCCESS;
RPC_STATUS rpcStatus = RPC_S_OK;
NTSTATUS status = STATUS_SUCCESS;
handle_t hDec = 0;
SCARDCONTEXT SCardContext;
SCARDHANDLE SCardHandle;
SetAttrib_Call SetAttribCall;
BOOL fFreeDecode = FALSE;
PRDPDR_IOREQUEST_PACKET pIoRequestPacket = pSCardHandleCall->pIoRequestPacket;
PRDPDR_DEVICE_IOREQUEST pIoRequest = &(pIoRequestPacket->IoRequest);
//
// Decode input parameters
//
rpcStatus = MesDecodeBufferHandleCreate(
(char *) (pIoRequest + 1), // bytes are at end of struct
pIoRequest->Parameters.DeviceIoControl.InputBufferLength,
&hDec);
if (rpcStatus != RPC_S_OK)
{
TRC_ERR((TB, _T("MesDecodeBufferHandleCreate failed with %lx."), rpcStatus));
status = STATUS_NO_MEMORY;
goto ErrorReturn;
}
memset(&SetAttribCall, 0, sizeof(SetAttribCall));
_TRY_status(SetAttrib_Call_Decode(hDec, &SetAttribCall))
fFreeDecode = TRUE;
if (sizeof(SCARDHANDLE) == SetAttribCall.hCard.cbHandle)
{
SCardContext = *((SCARDCONTEXT *) SetAttribCall.hCard.Context.pbContext);
SCardHandle = *((SCARDHANDLE *) SetAttribCall.hCard.pbHandle);
}
else
{
TRC_ERR((TB, _T("Invalid handle sent from server.")));
lReturn = SCARD_E_INVALID_PARAMETER;
}
//
// Make the call
//
if (lReturn == SCARD_S_SUCCESS)
{
lReturn =
pfnSCardSetAttrib(
SCardHandle,
SetAttribCall.dwAttrId,
SetAttribCall.pbAttr,
SetAttribCall.cbAttrLen);
}
//
// Send return
//
EncodeAndChannelWriteLongReturn(
pIoRequestPacket,
lReturn);
Return:
if (fFreeDecode)
{
_TRY_2(SetAttrib_Call_Free(hDec, &SetAttribCall))
}
SafeMesHandleFree(&hDec);
MIDL_user_free(pSCardHandleCall);
DC_END_FN();
return;
ErrorReturn:
DefaultIORequestMsgHandleWrapper(pIoRequestPacket, status);
goto Return;
}
#ifndef OS_WINCE
//---------------------------------------------------------------------------------------
//
// W32SCard::AccessStartedEvent + supporting WaitForStartedEvent
//
//---------------------------------------------------------------------------------------
void
W32SCard::WaitForStartedEvent(
BOOLEAN TimerOrWaitFired)
{
DC_BEGIN_FN("W32SCard::WaitForStartedEvent");
LONG lReturn = SCARD_E_UNEXPECTED;
DWORD i;
PVOID pv;
//
// If TimerOrWaitFired is FALSE, that means the event was set...
// otherwise it timed out.
//
if (!TimerOrWaitFired)
{
lReturn = SCARD_S_SUCCESS;
}
EnterCriticalSection(&_csWaitForStartedEvent);
pv = InterlockedExchangePointer(&_hRegisterWaitForStartedEvent, NULL);
if (pv != NULL)
{
pfnUnregisterWaitEx(pv, NULL);
}
//
// Loop for each outstanding wait and send return
//
for (i=0; i<_dwIORequestListSize; i++)
{
if (_rgIORequestList[i] != NULL)
{
EncodeAndChannelWriteLongReturn(
_rgIORequestList[i],
lReturn);
_rgIORequestList[i] = NULL;
}
}
LeaveCriticalSection(&_csWaitForStartedEvent);
Return:
DC_END_FN();
}
VOID CALLBACK
WaitForStartedEventCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired)
{
W32SCard *pTHIS = (W32SCard *) lpParameter;
pTHIS->WaitForStartedEvent(TimerOrWaitFired);
}
typedef HANDLE (WINAPI FN_SCARDACCESSSTARTEDEVENT)(VOID);
typedef FN_SCARDACCESSSTARTEDEVENT *PFN_SCARDACCESSSTARTEDEVENT;
void
W32SCard::GetStartedEvent()
{
DC_BEGIN_FN("W32SCard::GetStartedEvent");
HMODULE hMod = NULL;
PFN_SCARDACCESSSTARTEDEVENT pSCardAccessStartedEvent= NULL;
HANDLE hEvent = NULL;
hMod = LoadLibraryA("winscard.dll");
if (hMod == NULL)
{
goto Return;
}
pSCardAccessStartedEvent = (PFN_SCARDACCESSSTARTEDEVENT)
GetProcAddress(hMod, "SCardAccessStartedEvent");
if (pSCardAccessStartedEvent != NULL)
{
_hStartedEvent = pSCardAccessStartedEvent();
}
else
{
TRC_ERR(( TB,
_T("GetProcAddress(SCardAccessStartedEvent) failed - LastError: %lx."),
GetLastError()));
}
FreeLibrary(hMod);
Return:
DC_END_FN();
}
typedef VOID (WINAPI FN_SCARDRELEASESTARTEDEVENT)(VOID);
typedef FN_SCARDRELEASESTARTEDEVENT *PFN_SCARDRELEASESTARTEDEVENT;
void
W32SCard::ReleaseStartedEvent()
{
DC_BEGIN_FN("W32SCard::ReleaseStartedEvent");
HMODULE hMod = NULL;
PFN_SCARDRELEASESTARTEDEVENT pSCardReleaseStartedEvent = NULL;
hMod = LoadLibraryA("winscard.dll");
if (hMod == NULL)
{
goto Return;
}
pSCardReleaseStartedEvent = (PFN_SCARDRELEASESTARTEDEVENT)
GetProcAddress(hMod, "SCardReleaseStartedEvent");
if (pSCardReleaseStartedEvent != NULL)
{
pSCardReleaseStartedEvent();
}
else
{
TRC_ERR(( TB,
_T("GetProcAddress(SCardReleaseStartedEvent) failed - LastError: %lx."),
GetLastError()));
}
FreeLibrary(hMod);
Return:
DC_END_FN();
}
#endif
void
W32SCard::AccessStartedEvent(
IN PRDPDR_IOREQUEST_PACKET pIoRequestPacket)
{
DC_BEGIN_FN("W32SCard::AccessStartedEvent");
LONG lReturn = SCARD_S_SUCCESS;
//
// Make sure only one thread registers at a time
//
EnterCriticalSection(&_csWaitForStartedEvent);
#ifndef OS_WINCE
//
// First, make sure we can get the started event
//
if (_hStartedEvent == NULL)
{
GetStartedEvent();
}
if (_hStartedEvent == NULL)
{
//
// Couldn't even get the event, so return error
//
lReturn = SCARD_E_NO_SERVICE;
goto ImmediateReturn;
}
//
// Now, check to see if the event is already signaled, if so,
// then just return success, otherwise, register a wait callback
// on the event so we don't block this thread
//
if (WaitForSingleObject(_hStartedEvent, 0) == WAIT_OBJECT_0)
{
//
// It is signaled, so return success
//
lReturn = SCARD_S_SUCCESS;
goto ImmediateReturn;
}
//
// If the object is currently being destroyed, then don't create a new thread.
//
if (_fInDestructor)
{
goto ImmediateReturn;
}
//
// Only allow one wait to be registered. The single wait callback will
// notify all waiting requests
//
if ((_hRegisterWaitForStartedEvent == NULL) && _fUseRegisterWaitFuncs)
{
if (!pfnRegisterWaitForSingleObject(
&_hRegisterWaitForStartedEvent,
_hStartedEvent,
WaitForStartedEventCallback,
this,
INFINITE,
WT_EXECUTEONLYONCE))
{
lReturn = SCARD_E_NO_SERVICE;
goto ImmediateReturn;
}
}
else if (!_fUseRegisterWaitFuncs)
{
lReturn = SCARD_E_UNEXPECTED;
goto ImmediateReturn;
}
#else
lReturn = SCARD_S_SUCCESS;
goto ImmediateReturn;
#endif
//
// Add this pIoRequestPacket to the list
//
if (!AddIORequestToList(pIoRequestPacket))
{
lReturn = SCARD_E_UNEXPECTED;
goto ImmediateReturn;
}
//
// return here and let the wait we just registered
// make the EncodeAndChannelWriteLongReturn call,
// which will send the return the calling server
//
Return:
LeaveCriticalSection(&_csWaitForStartedEvent);
DC_END_FN();
return;
ImmediateReturn:
EncodeAndChannelWriteLongReturn(
pIoRequestPacket,
lReturn);
goto Return;
}
HANDLE
W32SCard::StartFSFunc(
IN W32DRDEV_ASYNCIO_PARAMS *params,
OUT DWORD *status
)
/*++
Routine Description:
Start a generic asynchronous File System IO operation.
Arguments:
params - Context for the IO request.
status - Return status for IO request in the form of a windows
error code.
Return Value:
Returns a handle to an object that will be signalled when the read
completes, if it is not completed in this function. Otherwise, NULL
is returned.
--*/
{
#ifndef OS_WINCE
PRDPDR_DEVICE_IOREQUEST pIoRequest;
DrFile* pFile;
ULONG irpMajor;
#endif
DC_BEGIN_FN("W32SCard::StartFSFunc");
*status = ERROR_SUCCESS;
DC_END_FN();
return NULL;
}
DWORD
W32SCard::AsyncNotifyChangeDir(
IN W32DRDEV_ASYNCIO_PARAMS *params
)
/*++
Routine Description:
Directory change notification Function
Arguments:
params - Context for the IO request.
Return Value:
Always returns 0.
--*/
{
DC_BEGIN_FN("W32SCard::AsyncNotifyChangeDir");
DC_END_FN();
return ERROR_SUCCESS;
}
DWORD
W32SCard::AsyncDirCtrlFunc(
IN W32DRDEV_ASYNCIO_PARAMS *params
)
/*++
Routine Description:
Asynchrous Directory Control Function
Arguments:
params - Context for the IO request.
Return Value:
Always returns 0.
--*/
{
DC_BEGIN_FN("W32SCard::AsyncDirCtrlFunc");
DC_END_FN();
return ERROR_SUCCESS;
}
BOOL
W32SCard::BindToSCardFunctions()
{
#ifndef OS_WINCE
int i;
#endif
BOOL fRet = TRUE;
//
// Load winscard dll if it exists
//
_hModWinscard = LoadLibraryA("winscard.dll");
if (_hModWinscard != NULL)
{
//
// get the function pointers
//
#ifndef OS_WINCE
pfnSCardEstablishContext = (PFN_SCardEstablishContext) GetProcAddress(_hModWinscard, "SCardEstablishContext");
pfnSCardReleaseContext = (PFN_SCardReleaseContext) GetProcAddress(_hModWinscard, "SCardReleaseContext");
pfnSCardIsValidContext = (PFN_SCardIsValidContext) GetProcAddress(_hModWinscard, "SCardIsValidContext");
pfnSCardListReaderGroupsA = (PFN_SCardListReaderGroupsA) GetProcAddress(_hModWinscard, "SCardListReaderGroupsA");
pfnSCardListReaderGroupsW = (PFN_SCardListReaderGroupsW) GetProcAddress(_hModWinscard, "SCardListReaderGroupsW");
pfnSCardListReadersA = (PFN_SCardListReadersA) GetProcAddress(_hModWinscard, "SCardListReadersA");
pfnSCardListReadersW = (PFN_SCardListReadersW) GetProcAddress(_hModWinscard, "SCardListReadersW");
pfnSCardIntroduceReaderGroupA = (PFN_SCardIntroduceReaderGroupA) GetProcAddress(_hModWinscard, "SCardIntroduceReaderGroupA");
pfnSCardIntroduceReaderGroupW = (PFN_SCardIntroduceReaderGroupW) GetProcAddress(_hModWinscard, "SCardIntroduceReaderGroupW");
pfnSCardForgetReaderGroupA = (PFN_SCardForgetReaderGroupA) GetProcAddress(_hModWinscard, "SCardForgetReaderGroupA");
pfnSCardForgetReaderGroupW = (PFN_SCardForgetReaderGroupW) GetProcAddress(_hModWinscard, "SCardForgetReaderGroupW");
pfnSCardIntroduceReaderA = (PFN_SCardIntroduceReaderA) GetProcAddress(_hModWinscard, "SCardIntroduceReaderA");
pfnSCardIntroduceReaderW = (PFN_SCardIntroduceReaderW) GetProcAddress(_hModWinscard, "SCardIntroduceReaderW");
pfnSCardForgetReaderA = (PFN_SCardForgetReaderA) GetProcAddress(_hModWinscard, "SCardForgetReaderA");
pfnSCardForgetReaderW = (PFN_SCardForgetReaderW) GetProcAddress(_hModWinscard, "SCardForgetReaderW");
pfnSCardAddReaderToGroupA = (PFN_SCardAddReaderToGroupA) GetProcAddress(_hModWinscard, "SCardAddReaderToGroupA");
pfnSCardAddReaderToGroupW = (PFN_SCardAddReaderToGroupW) GetProcAddress(_hModWinscard, "SCardAddReaderToGroupW");
pfnSCardRemoveReaderFromGroupA = (PFN_SCardRemoveReaderFromGroupA) GetProcAddress(_hModWinscard, "SCardRemoveReaderFromGroupA");
pfnSCardRemoveReaderFromGroupW = (PFN_SCardRemoveReaderFromGroupW) GetProcAddress(_hModWinscard, "SCardRemoveReaderFromGroupW");
pfnSCardFreeMemory = (PFN_SCardFreeMemory) GetProcAddress(_hModWinscard, "SCardFreeMemory");
pfnSCardLocateCardsA = (PFN_SCardLocateCardsA) GetProcAddress(_hModWinscard, "SCardLocateCardsA");
pfnSCardLocateCardsW = (PFN_SCardLocateCardsW) GetProcAddress(_hModWinscard, "SCardLocateCardsW");
pfnSCardLocateCardsByATRA = (PFN_SCardLocateCardsByATRA) GetProcAddress(_hModWinscard, "SCardLocateCardsByATRA");
pfnSCardLocateCardsByATRW = (PFN_SCardLocateCardsByATRW) GetProcAddress(_hModWinscard, "SCardLocateCardsByATRW");
pfnSCardGetStatusChangeA = (PFN_SCardGetStatusChangeA) GetProcAddress(_hModWinscard, "SCardGetStatusChangeA");
pfnSCardGetStatusChangeW = (PFN_SCardGetStatusChangeW) GetProcAddress(_hModWinscard, "SCardGetStatusChangeW");
pfnSCardCancel = (PFN_SCardCancel) GetProcAddress(_hModWinscard, "SCardCancel");
pfnSCardConnectA = (PFN_SCardConnectA) GetProcAddress(_hModWinscard, "SCardConnectA");
pfnSCardConnectW = (PFN_SCardConnectW) GetProcAddress(_hModWinscard, "SCardConnectW");
pfnSCardReconnect = (PFN_SCardReconnect) GetProcAddress(_hModWinscard, "SCardReconnect");
pfnSCardDisconnect = (PFN_SCardDisconnect) GetProcAddress(_hModWinscard, "SCardDisconnect");
pfnSCardBeginTransaction = (PFN_SCardBeginTransaction) GetProcAddress(_hModWinscard, "SCardBeginTransaction");
pfnSCardEndTransaction = (PFN_SCardEndTransaction) GetProcAddress(_hModWinscard, "SCardEndTransaction");
pfnSCardState = (PFN_SCardState) GetProcAddress(_hModWinscard, "SCardState");
pfnSCardStatusA = (PFN_SCardStatusA) GetProcAddress(_hModWinscard, "SCardStatusA");
pfnSCardStatusW = (PFN_SCardStatusW) GetProcAddress(_hModWinscard, "SCardStatusW");
pfnSCardTransmit = (PFN_SCardTransmit) GetProcAddress(_hModWinscard, "SCardTransmit");
pfnSCardControl = (PFN_SCardControl) GetProcAddress(_hModWinscard, "SCardControl");
pfnSCardGetAttrib = (PFN_SCardGetAttrib) GetProcAddress(_hModWinscard, "SCardGetAttrib");
pfnSCardSetAttrib = (PFN_SCardSetAttrib) GetProcAddress(_hModWinscard, "SCardSetAttrib");
#else
pfnSCardListReadersA = SCardListReadersA;
pfnSCardLocateCardsA = SCardLocateCardsA;
pfnSCardLocateCardsByATRA = SCardLocateCardsByATRA;
pfnSCardGetStatusChangeA = SCardGetStatusChangeA;
pfnSCardConnectA = SCardConnectA;
pfnSCardStatusA = SCardStatusA;
pfnSCardIntroduceReaderA = SCardIntroduceReaderA;
pfnSCardForgetReaderA = SCardForgetReaderA;
pfnSCardListReaderGroupsA = SCardListReaderGroupsA;
pfnSCardListReaderGroupsW = SCardListReaderGroupsW;
pfnSCardIntroduceReaderGroupA = SCardIntroduceReaderGroupA;
pfnSCardIntroduceReaderGroupW = SCardIntroduceReaderGroupW;
pfnSCardForgetReaderGroupA = SCardForgetReaderGroupA;
pfnSCardForgetReaderGroupW = SCardForgetReaderGroupW;
pfnSCardAddReaderToGroupA = SCardAddReaderToGroupA;
pfnSCardAddReaderToGroupW = SCardAddReaderToGroupW;
pfnSCardRemoveReaderFromGroupA = SCardRemoveReaderFromGroupA;
pfnSCardRemoveReaderFromGroupW = SCardRemoveReaderFromGroupW;
pfnSCardConnectW = CESCardConnect;
pfnSCardReconnect = CESCardReconnect;
pfnSCardDisconnect = CESCardDisconnect;
pfnSCardBeginTransaction = CESCardBeginTransaction;
pfnSCardEndTransaction = CESCardEndTransaction;
pfnSCardTransmit = CESCardTransmit;
pfnSCardStatusW = CESCardStatus;
pfnSCardControl = CESCardControl;
pfnSCardGetAttrib = CESCardGetAttrib;
pfnSCardSetAttrib = CESCardSetAttrib;
gpfnSCardConnectW = (PFN_SCardConnectW) GetProcAddress(_hModWinscard, L"SCardConnectW");
gpfnSCardReconnect = (PFN_SCardReconnect) GetProcAddress(_hModWinscard, L"SCardReconnect");
gpfnSCardDisconnect = (PFN_SCardDisconnect) GetProcAddress(_hModWinscard, L"SCardDisconnect");
gpfnSCardBeginTransaction = (PFN_SCardBeginTransaction) GetProcAddress(_hModWinscard, L"SCardBeginTransaction");
gpfnSCardEndTransaction = (PFN_SCardEndTransaction) GetProcAddress(_hModWinscard, L"SCardEndTransaction");
gpfnSCardTransmit = (PFN_SCardTransmit) GetProcAddress(_hModWinscard, L"SCardTransmit");
gpfnSCardStatusW = (PFN_SCardStatusW) GetProcAddress(_hModWinscard, L"SCardStatusW");
gpfnSCardControl = (PFN_SCardControl) GetProcAddress(_hModWinscard, L"SCardControl");
gpfnSCardGetAttrib = (PFN_SCardGetAttrib) GetProcAddress(_hModWinscard, L"SCardGetAttrib");
gpfnSCardSetAttrib = (PFN_SCardSetAttrib) GetProcAddress(_hModWinscard, L"SCardSetAttrib");
pfnSCardEstablishContext = (PFN_SCardEstablishContext) GetProcAddress(_hModWinscard, L"SCardEstablishContext");
pfnSCardReleaseContext = (PFN_SCardReleaseContext) GetProcAddress(_hModWinscard, L"SCardReleaseContext");
pfnSCardIsValidContext = (PFN_SCardIsValidContext) GetProcAddress(_hModWinscard, L"SCardIsValidContext");
pfnSCardListReadersW = (PFN_SCardListReadersW) GetProcAddress(_hModWinscard, L"SCardListReadersW");
pfnSCardIntroduceReaderW = (PFN_SCardIntroduceReaderW) GetProcAddress(_hModWinscard, L"SCardIntroduceReaderW");
pfnSCardForgetReaderW = (PFN_SCardForgetReaderW) GetProcAddress(_hModWinscard, L"SCardForgetReaderW");
pfnSCardLocateCardsW = (PFN_SCardLocateCardsW) GetProcAddress(_hModWinscard, L"SCardLocateCardsW");
pfnSCardLocateCardsByATRW = (PFN_SCardLocateCardsByATRW) GetProcAddress(_hModWinscard, L"SCardLocateCardsByATRW");
pfnSCardGetStatusChangeW = (PFN_SCardGetStatusChangeW) GetProcAddress(_hModWinscard, L"SCardGetStatusChangeW");
pfnSCardCancel = (PFN_SCardCancel) GetProcAddress(_hModWinscard, L"SCardCancel");
gpfnSCardEstablishContext = pfnSCardEstablishContext;
gpfnSCardReleaseContext = pfnSCardReleaseContext;
gpfnSCardListReadersW = pfnSCardListReadersW;
gpfnSCardIntroduceReaderW = pfnSCardIntroduceReaderW;
gpfnSCardForgetReaderW = pfnSCardForgetReaderW;
gpfnSCardLocateCardsW = pfnSCardLocateCardsW;
gpfnSCardLocateCardsByATRW = pfnSCardLocateCardsByATRW;
gpfnSCardGetStatusChangeW = pfnSCardGetStatusChangeW;
#endif
//
// Note, don't check the pfnSCardLocateCardsByATR* API's since they aren't required.
//
if ((pfnSCardEstablishContext == NULL) ||
(pfnSCardReleaseContext == NULL) ||
(pfnSCardIsValidContext == NULL) ||
#ifndef OS_WINCE
(pfnSCardFreeMemory == NULL) ||
(pfnSCardState == NULL) ||
#endif
(pfnSCardListReaderGroupsA == NULL) ||
(pfnSCardListReaderGroupsW == NULL) ||
(pfnSCardListReadersA == NULL) ||
(pfnSCardListReadersW == NULL) ||
(pfnSCardIntroduceReaderGroupA == NULL) ||
(pfnSCardIntroduceReaderGroupW == NULL) ||
(pfnSCardForgetReaderGroupA == NULL) ||
(pfnSCardForgetReaderGroupW == NULL) ||
(pfnSCardIntroduceReaderA == NULL) ||
(pfnSCardIntroduceReaderW == NULL) ||
(pfnSCardForgetReaderA == NULL) ||
(pfnSCardForgetReaderW == NULL) ||
(pfnSCardAddReaderToGroupA == NULL) ||
(pfnSCardAddReaderToGroupW == NULL) ||
(pfnSCardRemoveReaderFromGroupA == NULL) ||
(pfnSCardRemoveReaderFromGroupW == NULL) ||
(pfnSCardLocateCardsA == NULL) ||
(pfnSCardLocateCardsW == NULL) ||
(pfnSCardGetStatusChangeA == NULL) ||
(pfnSCardGetStatusChangeW == NULL) ||
(pfnSCardCancel == NULL) ||
(pfnSCardConnectA == NULL) ||
(pfnSCardStatusA == NULL) ||
#ifndef OS_WINCE
(pfnSCardConnectW == NULL) ||
(pfnSCardReconnect == NULL) ||
(pfnSCardDisconnect == NULL) ||
(pfnSCardBeginTransaction == NULL) ||
(pfnSCardEndTransaction == NULL) ||
(pfnSCardTransmit == NULL) ||
(pfnSCardStatusW == NULL) ||
(pfnSCardControl == NULL) ||
(pfnSCardGetAttrib == NULL) ||
(pfnSCardSetAttrib == NULL))
#else
(gpfnSCardConnectW == NULL) ||
(gpfnSCardReconnect == NULL) ||
(gpfnSCardDisconnect == NULL) ||
(gpfnSCardBeginTransaction == NULL) ||
(gpfnSCardEndTransaction == NULL) ||
(gpfnSCardTransmit == NULL) ||
(gpfnSCardStatusW == NULL) ||
(gpfnSCardControl == NULL) ||
(gpfnSCardGetAttrib == NULL) ||
(gpfnSCardSetAttrib == NULL))
#endif
{
fRet = FALSE;
}
#ifndef OS_WINCE
_hModKernel32 = LoadLibraryA("kernel32.dll");
if (_hModKernel32 != NULL)
{
pfnRegisterWaitForSingleObject = (PFN_RegisterWaitForSingleObject)
GetProcAddress(_hModKernel32, "RegisterWaitForSingleObject");
pfnUnregisterWaitEx = (PFN_UnregisterWaitEx)
GetProcAddress(_hModKernel32, "UnregisterWaitEx");
if ((pfnRegisterWaitForSingleObject != NULL) &&
(pfnUnregisterWaitEx != NULL))
{
_fUseRegisterWaitFuncs = TRUE;
}
}
#endif
}
else
{
fRet = FALSE;
}
return (fRet);
}
//
// RPCRT4 stubs for dload failure
//
RPC_STATUS RPC_ENTRY
DLoadStub_MesDecodeBufferHandleCreate(
char * pBuffer,
unsigned long BufferSize,
handle_t * pHandle )
{
return (RPC_S_OUT_OF_MEMORY);
}
RPC_STATUS RPC_ENTRY
DLoadStub_MesEncodeDynBufferHandleCreate(
char * * pBuffer,
unsigned long * pEncodedSize,
handle_t * pHandle )
{
return (RPC_S_OUT_OF_MEMORY);
}
void RPC_ENTRY
DLoadStub_NdrMesTypeEncode2(
handle_t Handle,
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
const MIDL_STUB_DESC * pStubDesc,
PFORMAT_STRING pFormatString,
const void * pObject )
{
throw (RPC_S_OUT_OF_MEMORY);
return;
}
void RPC_ENTRY
DLoadStub_NdrMesTypeDecode2(
handle_t Handle,
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
const MIDL_STUB_DESC * pStubDesc,
PFORMAT_STRING pFormatString,
void * pObject )
{
throw (RPC_S_OUT_OF_MEMORY);
return;
}
void RPC_ENTRY
DLoadStub_NdrMesTypeFree2(
handle_t Handle,
const MIDL_TYPE_PICKLING_INFO * pPicklingInfo,
const MIDL_STUB_DESC * pStubDesc,
PFORMAT_STRING pFormatString,
void * pObject )
{
throw (RPC_S_OUT_OF_MEMORY);
return;
}
RPC_STATUS RPC_ENTRY
DLoadStub_MesHandleFree( handle_t Handle )
{
return (RPC_S_OUT_OF_MEMORY);
}
FARPROC WINAPI GetRPCRT4Stubs(LPCSTR szProcName)
{
DC_BEGIN_FN("W32SCard::GetRPCRT4Stubs");
if (0 == _stricmp(szProcName, "MesDecodeBufferHandleCreate"))
return (FARPROC)DLoadStub_MesDecodeBufferHandleCreate;
if (0 == _stricmp(szProcName, "MesEncodeDynBufferHandleCreate"))
return (FARPROC)DLoadStub_MesEncodeDynBufferHandleCreate;
if (0 == _stricmp(szProcName, "NdrMesTypeEncode2"))
return (FARPROC)DLoadStub_NdrMesTypeEncode2;
if (0 == _stricmp(szProcName, "NdrMesTypeDecode2"))
return (FARPROC)DLoadStub_NdrMesTypeDecode2;
if (0 == _stricmp(szProcName, "NdrMesTypeFree2"))
return (FARPROC)DLoadStub_NdrMesTypeFree2;
if (0 == _stricmp(szProcName, "MesHandleFree"))
return (FARPROC)DLoadStub_MesHandleFree;
TRC_ERR(( TB,
_T("RPCRT4 stub =%s= is missing. Fix it NOW!"),
szProcName));
DC_END_FN();
return (FARPROC) NULL;
}
//
// Dload error handler
//
FARPROC WINAPI DliHook(unsigned dliNotify, PDelayLoadInfo pdli)
{
DC_BEGIN_FN("W32SCard::DliHook");
FARPROC fp = 0;
switch (dliNotify)
{
case dliFailLoadLib:
{
if (0 == _stricmp("rpcrt4.dll", pdli->szDll))
{
fp = (FARPROC) -1;
}
}
break;
case dliFailGetProc:
{
SetLastError(ERROR_PROC_NOT_FOUND);
if (0 == _stricmp("rpcrt4.dll", pdli->szDll))
{
if (pdli->dlp.fImportByName)
{
fp = GetRPCRT4Stubs(pdli->dlp.szProcName);
}
else
{
TRC_ERR(( TB,
_T("RPCRT4 ordinal stub =%lx= is missing. Fix it NOW!"),
pdli->dlp.dwOrdinal));
fp = (FARPROC) NULL;
}
}
}
break;
}
DC_END_FN();
return fp;
}
PfnDliHook __pfnDliFailureHook2 = DliHook;