BixVReader: Add multi application support for IoRequests (#114)

fixes https://github.com/frankmorgner/vsmartcard/issues/105
This commit is contained in:
Frank Morgner
2017-11-24 11:20:01 +01:00
committed by GitHub
parent c95d82c936
commit 21a0d0cf48
6 changed files with 212 additions and 146 deletions

View File

@@ -10,15 +10,15 @@
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA) BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{ {
TCHAR * szSD = TEXT("D:") // Discretionary ACL TCHAR * szSD = TEXT("D:") // Discretionary ACL
TEXT("(D;OICI;GA;;;BG)") // Deny access to TEXT("(D;OICI;GA;;;BG)") // Deny access to
// built-in guests // built-in guests
TEXT("(D;OICI;GA;;;AN)") // Deny access to TEXT("(D;OICI;GA;;;AN)") // Deny access to
// anonymous logon // anonymous logon
TEXT("(A;OICI;GRGWGX;;;AU)") // Allow TEXT("(A;OICI;GRGWGX;;;AU)") // Allow
// read/write/execute // read/write/execute
// to authenticated // to authenticated
// users // users
TEXT("(A;OICI;GA;;;BA)"); // Allow full control TEXT("(A;OICI;GA;;;BA)"); // Allow full control
// to administrators // to administrators
if (NULL == pSA) if (NULL == pSA)
@@ -45,7 +45,7 @@ void PipeReader::init(wchar_t *section) {
GetPrivateProfileStringW(section,L"PIPE_NAME",temp,pipeName,300,L"BixVReader.ini"); GetPrivateProfileStringW(section,L"PIPE_NAME",temp,pipeName,300,L"BixVReader.ini");
swprintf(temp,L"SCardSimulatorDriverEvents%i",instance); swprintf(temp,L"SCardSimulatorDriverEvents%i",instance);
GetPrivateProfileStringW(section,L"PIPE_EVENT_NAME",temp,pipeEventName,300,L"BixVReader.ini"); GetPrivateProfileStringW(section,L"PIPE_EVENT_NAME",temp,pipeEventName,300,L"BixVReader.ini");
} }
bool PipeReader::CheckATR() { bool PipeReader::CheckATR() {
@@ -135,7 +135,7 @@ bool PipeReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
DWORD PipeReader::startServer() { DWORD PipeReader::startServer() {
SECURITY_ATTRIBUTES sa; SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE; sa.bInheritHandle = FALSE;
CreateMyDACL(&sa); CreateMyDACL(&sa);
wchar_t temp[300]; wchar_t temp[300];
@@ -169,17 +169,21 @@ DWORD PipeReader::startServer() {
} }
pipe=_pipe; pipe=_pipe;
eventpipe=_eventpipe; eventpipe=_eventpipe;
if (waitInsertIpr!=NULL) { if (!waitInsertIpr.empty()) {
SectionLocker lock(device->m_RequestLock);
// if I'm waiting for card insertion, verify if there's a card present // if I'm waiting for card insertion, verify if there's a card present
if (initProtocols()) { if (initProtocols()) {
if (waitInsertIpr->UnmarkCancelable()==S_OK) SectionLocker lock(device->m_RequestLock);
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); while (!waitInsertIpr.empty()) {
waitInsertIpr=NULL; CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
state=SCARD_SWALLOWED; if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
}
waitInsertIpr.pop_back();
}
state=SCARD_SWALLOWED;
} }
} }
while (true) { while (true) {
// wait for a command // wait for a command
DWORD command=0; DWORD command=0;
@@ -190,25 +194,34 @@ DWORD PipeReader::startServer() {
powered=0; powered=0;
pipe=NULL; pipe=NULL;
eventpipe=NULL; eventpipe=NULL;
if (waitRemoveIpr!=NULL) {// card inserted if (!waitRemoveIpr.empty()) {
// card inserted
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
OutputDebugString(L"[BixVReader]complete Wait Remove"); while (!waitRemoveIpr.empty()) {
if (waitRemoveIpr->UnmarkCancelable()==S_OK) { CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
OutputDebugString(L"[BixVReader]Wait Remove Unmarked"); OutputDebugString(L"[BixVReader]complete Wait Remove");
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); if (ipr->UnmarkCancelable()==S_OK) {
OutputDebugString(L"[BixVReader]Wait Remove Completed"); OutputDebugString(L"[BixVReader]Wait Remove Unmarked");
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]Wait Remove Completed");
}
waitRemoveIpr.pop_back();
} }
waitRemoveIpr=NULL;
} }
if (waitInsertIpr!=NULL) {// card removed if (!waitInsertIpr.empty()) {
// card removed
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
OutputDebugString(L"[BixVReader]cancel Wait Remove"); while (!waitInsertIpr.empty()) {
if (waitInsertIpr->UnmarkCancelable()==S_OK) { CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
OutputDebugString(L"[BixVReader]Wait Insert Unmarked"); OutputDebugString(L"[BixVReader]cancel Wait Remove");
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0); SectionLocker lock(device->m_RequestLock);
OutputDebugString(L"[BixVReader]Wait Insert Cancelled"); if (ipr->UnmarkCancelable()==S_OK) {
OutputDebugString(L"[BixVReader]Wait Insert Unmarked");
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
OutputDebugString(L"[BixVReader]Wait Insert Cancelled");
}
waitInsertIpr.pop_back();
} }
waitInsertIpr=NULL;
} }
DisconnectNamedPipe(_pipe); DisconnectNamedPipe(_pipe);
DisconnectNamedPipe(_eventpipe); DisconnectNamedPipe(_eventpipe);
@@ -217,22 +230,28 @@ DWORD PipeReader::startServer() {
OutputDebugString(L"[BixVReader]Pipe data"); OutputDebugString(L"[BixVReader]Pipe data");
if (command==0) if (command==0)
powered=0; powered=0;
if (command==0 && waitRemoveIpr!=NULL) {// card removed if (command==0 && !waitRemoveIpr.empty()) {
// card removed
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
state=SCARD_ABSENT; state=SCARD_ABSENT;
if (waitRemoveIpr->UnmarkCancelable()==S_OK) { while (!waitRemoveIpr.empty()) {
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
if (ipr->UnmarkCancelable()==S_OK)
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
waitRemoveIpr.pop_back();
} }
waitRemoveIpr=NULL;
} }
else if (command==1 && waitInsertIpr!=NULL) {// card inserted else if (command==1 && !waitInsertIpr.empty()) {
// card inserted
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
state=SCARD_SWALLOWED; state=SCARD_SWALLOWED;
initProtocols(); initProtocols();
if (waitInsertIpr->UnmarkCancelable()==S_OK) { while (!waitInsertIpr.empty()) {
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
if (ipr->UnmarkCancelable()==S_OK)
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
waitInsertIpr.pop_back();
} }
waitInsertIpr=NULL;
} }
} }
//} //}
@@ -249,16 +268,18 @@ DWORD PipeReader::startServer() {
void PipeReader::shutdown() { void PipeReader::shutdown() {
state=SCARD_ABSENT; state=SCARD_ABSENT;
if (waitRemoveIpr!=NULL) { while (!waitRemoveIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitRemoveIpr->UnmarkCancelable()==S_OK) CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); if (ipr->UnmarkCancelable()==S_OK)
waitRemoveIpr=NULL; ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitRemoveIpr.pop_back();
} }
if (waitInsertIpr!=NULL) { while (!waitInsertIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); if (ipr->UnmarkCancelable()==S_OK)
waitInsertIpr=NULL; ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitInsertIpr.pop_back();
} }
} }

View File

@@ -15,7 +15,7 @@ void Reader::init(wchar_t *section) {
void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) { void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
UNREFERENCED_PARAMETER(inBufSize); UNREFERENCED_PARAMETER(inBufSize);
UNREFERENCED_PARAMETER(outBufSize); UNREFERENCED_PARAMETER(outBufSize);
OutputDebugString(L"[BixVReader][IPRE]IOCTL_SMARTCARD_IS_PRESENT"); OutputDebugString(L"[BixVReader][IPRE]IOCTL_SMARTCARD_IS_PRESENT");
if (CheckATR()) { if (CheckATR()) {
// there's a smart card present, so complete the request // there's a smart card present, so complete the request
@@ -25,7 +25,7 @@ void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_
else { else {
// there's no smart card present, so leave the request pending; it will be completed later // there's no smart card present, so leave the request pending; it will be completed later
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
waitInsertIpr=pRequest; waitInsertIpr.push_back(pRequest);
IRequestCallbackCancel *callback; IRequestCallbackCancel *callback;
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback); device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
pRequest->MarkCancelable(callback); pRequest->MarkCancelable(callback);
@@ -54,7 +54,7 @@ void Reader::IoSmartCardIsAbsent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T
else { else {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
// there's a smart card present, so leave the request pending; it will be completed later // there's a smart card present, so leave the request pending; it will be completed later
waitRemoveIpr=pRequest; waitRemoveIpr.push_back(pRequest);
IRequestCallbackCancel *callback; IRequestCallbackCancel *callback;
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback); device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
@@ -91,7 +91,7 @@ void Reader::IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T ou
DWORD ATRsize; DWORD ATRsize;
if (!QueryATR(ATR,&ATRsize,true)) if (!QueryATR(ATR,&ATRsize,true))
{ {
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
return; return;
} }
setBuffer(device,pRequest,ATR,ATRsize); setBuffer(device,pRequest,ATR,ATRsize);
@@ -100,7 +100,7 @@ void Reader::IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T ou
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0); pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
} }
} }
void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) { void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
@@ -108,7 +108,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
UNREFERENCED_PARAMETER(outBufSize); UNREFERENCED_PARAMETER(outBufSize);
UNREFERENCED_PARAMETER(instance); UNREFERENCED_PARAMETER(instance);
DWORD requestedProtocol=getInt(pRequest); DWORD requestedProtocol=getInt(pRequest);
wchar_t log[300]; wchar_t log[300];
swprintf(log,L"[BixVReader][SPRT]IOCTL_SMARTCARD_SET_PROTOCOL:%08X",requestedProtocol); swprintf(log,L"[BixVReader][SPRT]IOCTL_SMARTCARD_SET_PROTOCOL:%08X",requestedProtocol);
OutputDebugString(log); OutputDebugString(log);
@@ -119,10 +119,10 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
if (!QueryATR(ATR,&ATRsize,true)) if (!QueryATR(ATR,&ATRsize,true))
{ {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
return; return;
} }
if (((requestedProtocol & SCARD_PROTOCOL_T1) != 0) && if (((requestedProtocol & SCARD_PROTOCOL_T1) != 0) &&
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) { ((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
protocol = SCARD_PROTOCOL_T1; protocol = SCARD_PROTOCOL_T1;
@@ -130,7 +130,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0); pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]PROTOCOL SET: T1"); OutputDebugString(L"[BixVReader]PROTOCOL SET: T1");
return; return;
} }
if (((requestedProtocol & SCARD_PROTOCOL_T0) != 0) && if (((requestedProtocol & SCARD_PROTOCOL_T0) != 0) &&
((availableProtocol & SCARD_PROTOCOL_T0) != 0)) { ((availableProtocol & SCARD_PROTOCOL_T0) != 0)) {
@@ -139,7 +139,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0); pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]PROTOCOL SET: T0"); OutputDebugString(L"[BixVReader]PROTOCOL SET: T0");
return; return;
} }
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) && if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) { ((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
@@ -148,7 +148,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0); pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]PROTOCOL SET: T1"); OutputDebugString(L"[BixVReader]PROTOCOL SET: T1");
return; return;
} }
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) && if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
((availableProtocol & SCARD_PROTOCOL_T0) != 0)) { ((availableProtocol & SCARD_PROTOCOL_T0) != 0)) {
@@ -157,7 +157,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0); pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]PROTOCOL SET: T0"); OutputDebugString(L"[BixVReader]PROTOCOL SET: T0");
return; return;
} }
{ {
state=SCARD_NEGOTIABLE; state=SCARD_NEGOTIABLE;
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
@@ -170,10 +170,10 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
UNREFERENCED_PARAMETER(outBufSize); UNREFERENCED_PARAMETER(outBufSize);
UNREFERENCED_PARAMETER(instance); UNREFERENCED_PARAMETER(instance);
OutputDebugString(L"[BixVReader][SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE"); OutputDebugString(L"[BixVReader][SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE");
IWDFMemory *inmem=NULL; IWDFMemory *inmem=NULL;
pRequest->GetInputMemory(&inmem); pRequest->GetInputMemory(&inmem);
SIZE_T size; SIZE_T size;
BYTE *data=(BYTE *)inmem->GetDataBuffer(&size); BYTE *data=(BYTE *)inmem->GetDataBuffer(&size);
@@ -212,7 +212,7 @@ void Reader::IoSmartCardTransmit(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T
if (!QueryTransmit(APDU+sizeof(SCARD_IO_REQUEST),APDUSize-sizeof(SCARD_IO_REQUEST),Resp+sizeof(SCARD_IO_REQUEST),&RespSize)) if (!QueryTransmit(APDU+sizeof(SCARD_IO_REQUEST),APDUSize-sizeof(SCARD_IO_REQUEST),Resp+sizeof(SCARD_IO_REQUEST),&RespSize))
{ {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
return; return;
} }
((SCARD_IO_REQUEST*)Resp)->cbPciLength=sizeof(SCARD_IO_REQUEST); ((SCARD_IO_REQUEST*)Resp)->cbPciLength=sizeof(SCARD_IO_REQUEST);
@@ -222,7 +222,7 @@ void Reader::IoSmartCardTransmit(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T
void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) { void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
UNREFERENCED_PARAMETER(inBufSize); UNREFERENCED_PARAMETER(inBufSize);
wchar_t log[300]=L""; wchar_t log[300]=L"";
char temp[300]; char temp[300];
@@ -238,7 +238,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
return; return;
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00a): case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00a):
// custom attribute; PipeName // custom attribute; PipeName
if (rpcType==0) { if (rpcType==0) {
PipeReader *pipe=(PipeReader *)this; PipeReader *pipe=(PipeReader *)this;
OutputDebugString(L"[BixVReader][GATT]PIPE_NAME"); OutputDebugString(L"[BixVReader][GATT]PIPE_NAME");
sprintf(temp,"%S",pipe->pipeName); sprintf(temp,"%S",pipe->pipeName);
@@ -251,7 +251,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
return; return;
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00b): case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00b):
// custom attribute; EventPipeName // custom attribute; EventPipeName
if (rpcType==0) { if (rpcType==0) {
PipeReader *pipe=(PipeReader *)this; PipeReader *pipe=(PipeReader *)this;
OutputDebugString(L"[BixVReader][GATT]EVENT_PIPE_NAME"); OutputDebugString(L"[BixVReader][GATT]EVENT_PIPE_NAME");
sprintf(temp,"%S",pipe->pipeEventName); sprintf(temp,"%S",pipe->pipeEventName);
@@ -264,7 +264,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
return; return;
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00c): case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00c):
// custom attribute; TCP port // custom attribute; TCP port
if (rpcType==1) { if (rpcType==1) {
TcpIpReader *tcpIp=(TcpIpReader *)this; TcpIpReader *tcpIp=(TcpIpReader *)this;
OutputDebugString(L"[BixVReader][GATT]PORT"); OutputDebugString(L"[BixVReader][GATT]PORT");
setInt(device,pRequest,tcpIp->port); setInt(device,pRequest,tcpIp->port);
@@ -276,7 +276,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
return; return;
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00d): case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00d):
// custom attribute; TCP event port // custom attribute; TCP event port
if (rpcType==1) { if (rpcType==1) {
TcpIpReader *tcpIp=(TcpIpReader *)this; TcpIpReader *tcpIp=(TcpIpReader *)this;
OutputDebugString(L"[BixVReader][GATT]EVENT_PORT"); OutputDebugString(L"[BixVReader][GATT]EVENT_PORT");
setInt(device,pRequest,tcpIp->eventPort); setInt(device,pRequest,tcpIp->eventPort);
@@ -288,7 +288,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
return; return;
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00e): case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00e):
// custom attribute; TCP base port // custom attribute; TCP base port
if (rpcType==1) { if (rpcType==1) {
TcpIpReader *tcpIp=(TcpIpReader *)this; TcpIpReader *tcpIp=(TcpIpReader *)this;
OutputDebugString(L"[BixVReader][GATT]BASE_PORT"); OutputDebugString(L"[BixVReader][GATT]BASE_PORT");
setInt(device,pRequest,tcpIp->portBase); setInt(device,pRequest,tcpIp->portBase);
@@ -323,7 +323,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
if (!QueryATR(ATR,&ATRsize)) if (!QueryATR(ATR,&ATRsize))
{ {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0); pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
return; return;
} }
setBuffer(device,pRequest,ATR,ATRsize); setBuffer(device,pRequest,ATR,ATRsize);
@@ -381,7 +381,7 @@ bool Reader::initProtocols() {
else if (i==1) { else if (i==1) {
// we are in T0; read number of historical bytes // we are in T0; read number of historical bytes
let='A'; let='A';
y=ATR[i] >> 4; y=ATR[i] >> 4;
iTotHistBytes=ATR[i] & 0xF; iTotHistBytes=ATR[i] & 0xF;
} }
else { else {

View File

@@ -1,14 +1,15 @@
#pragma once #pragma once
#include <Winsock2.h> #include <Winsock2.h>
#include <vector>
class CMyDevice; class CMyDevice;
class Reader { class Reader {
public: public:
CMyDevice *device; CMyDevice *device;
CComPtr<IWDFIoRequest> waitRemoveIpr; std::vector< CComPtr<IWDFIoRequest> > waitRemoveIpr;
CComPtr<IWDFIoRequest> waitInsertIpr; std::vector< CComPtr<IWDFIoRequest> > waitInsertIpr;
inbuf; inbuf;
outbuf; outbuf;
@@ -23,7 +24,7 @@ public:
int state; int state;
DWORD protocol; // T0 or T1 - protocol in use DWORD protocol; // T0 or T1 - protocol in use
DWORD availableProtocol; // T0, T1 or Both - protocols available DWORD availableProtocol; // T0, T1 or Both - protocols available
void IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize); void IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
void IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize); void IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
void IoSmartCardGetState(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize); void IoSmartCardGetState(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
@@ -57,7 +58,7 @@ public:
DWORD startServer(); DWORD startServer();
void shutdown(); void shutdown();
void init(wchar_t *section); void init(wchar_t *section);
CRITICAL_SECTION eventSection; CRITICAL_SECTION eventSection;
CRITICAL_SECTION dataSection; CRITICAL_SECTION dataSection;
}; };

View File

@@ -15,7 +15,7 @@ TcpIpReader::TcpIpReader() {
state=SCARD_ABSENT; state=SCARD_ABSENT;
} }
void TcpIpReader::init(wchar_t *section) { void TcpIpReader::init(wchar_t *section) {
portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",29500,L"BixVReader.ini"); portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",29500,L"BixVReader.ini");
port=GetPrivateProfileInt(section,L"TCP_PORT",portBase+(instance<<1),L"BixVReader.ini"); port=GetPrivateProfileInt(section,L"TCP_PORT",portBase+(instance<<1),L"BixVReader.ini");
eventPort=GetPrivateProfileInt(section,L"TCP_EVENT_PORT",portBase+1+(instance<<1),L"BixVReader.ini"); eventPort=GetPrivateProfileInt(section,L"TCP_EVENT_PORT",portBase+1+(instance<<1),L"BixVReader.ini");
@@ -205,17 +205,21 @@ DWORD TcpIpReader::startServer() {
swprintf(log,L"[BixVReader]Event Socket connected:%i",AcceptEventSocket); swprintf(log,L"[BixVReader]Event Socket connected:%i",AcceptEventSocket);
OutputDebugString(log); OutputDebugString(log);
if (waitInsertIpr!=NULL) { if (!waitInsertIpr.empty()) {
// if I'm waiting for card insertion, verify if there's a card present // if I'm waiting for card insertion, verify if there's a card present
if (initProtocols()) { if (initProtocols()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) while (!waitInsertIpr.empty()) {
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr=NULL; if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
}
waitInsertIpr.pop_back();
}
state=SCARD_SWALLOWED; state=SCARD_SWALLOWED;
} }
} }
while (true) { while (true) {
// wait for a command // wait for a command
DWORD command=0; DWORD command=0;
@@ -226,45 +230,62 @@ DWORD TcpIpReader::startServer() {
powered=0; powered=0;
::shutdown(AcceptSocket,SD_BOTH); ::shutdown(AcceptSocket,SD_BOTH);
::shutdown(AcceptEventSocket,SD_BOTH); ::shutdown(AcceptEventSocket,SD_BOTH);
if (waitRemoveIpr!=NULL) {// card inserted if (!waitRemoveIpr.empty()) {
OutputDebugString(L"[BixVReader]complete Wait Remove"); // card inserted
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitRemoveIpr->UnmarkCancelable()==S_OK) { while (!waitRemoveIpr.empty()) {
OutputDebugString(L"[BixVReader]Wait Remove Unmarked"); CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); OutputDebugString(L"[BixVReader]complete Wait Remove");
OutputDebugString(L"[BixVReader]Wait Remove Completed"); if (ipr->UnmarkCancelable()==S_OK) {
OutputDebugString(L"[BixVReader]Wait Remove Unmarked");
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
OutputDebugString(L"[BixVReader]Wait Remove Completed");
}
waitRemoveIpr.pop_back();
} }
waitRemoveIpr=NULL;
} }
if (waitInsertIpr!=NULL) {// card removed if (!waitInsertIpr.empty()) {
OutputDebugString(L"[BixVReader]cancel Wait Remove"); // card removed
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) { while (!waitInsertIpr.empty()) {
OutputDebugString(L"[BixVReader]Wait Insert Unmarked"); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0); OutputDebugString(L"[BixVReader]cancel Wait Remove");
OutputDebugString(L"[BixVReader]Wait Insert Cancelled"); SectionLocker lock(device->m_RequestLock);
if (ipr->UnmarkCancelable()==S_OK) {
OutputDebugString(L"[BixVReader]Wait Insert Unmarked");
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
OutputDebugString(L"[BixVReader]Wait Insert Cancelled");
}
waitInsertIpr.pop_back();
} }
waitInsertIpr=NULL;
} }
break; break;
} }
OutputDebugString(L"[BixVReader]Socket data"); OutputDebugString(L"[BixVReader]Socket data");
if (command==0) if (command==0)
powered=0; powered=0;
if (command==0 && waitRemoveIpr!=NULL) {// card removed if (command==0 && !waitRemoveIpr.empty()) {
// card removed
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
state=SCARD_ABSENT; state=SCARD_ABSENT;
if (waitRemoveIpr->UnmarkCancelable()==S_OK) while (!waitRemoveIpr.empty()) {
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitRemoveIpr=NULL; if (ipr->UnmarkCancelable()==S_OK)
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
waitRemoveIpr.pop_back();
}
} }
else if (command==1 && waitInsertIpr!=NULL) {// card inserted else if (command==1 && !waitInsertIpr.empty()) {
// card inserted
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
state=SCARD_SWALLOWED; state=SCARD_SWALLOWED;
initProtocols(); initProtocols();
if (waitInsertIpr->UnmarkCancelable()==S_OK) while (!waitInsertIpr.empty()) {
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr=NULL; if (ipr->UnmarkCancelable()==S_OK)
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
waitInsertIpr.pop_back();
}
} }
} }
//} //}
@@ -291,16 +312,18 @@ void TcpIpReader::shutdown() {
serverThread=NULL; serverThread=NULL;
eventsocket=NULL; eventsocket=NULL;
socket=NULL; socket=NULL;
if (waitRemoveIpr!=NULL) { while (!waitRemoveIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitRemoveIpr->UnmarkCancelable()==S_OK) CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); if (ipr->UnmarkCancelable()==S_OK)
waitRemoveIpr=NULL; ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitRemoveIpr.pop_back();
} }
if (waitInsertIpr!=NULL) { while (!waitInsertIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); if (ipr->UnmarkCancelable()==S_OK)
waitInsertIpr=NULL; ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitInsertIpr.pop_back();
} }
} }

View File

@@ -22,7 +22,7 @@ VpcdReader::~VpcdReader() {
DeleteCriticalSection(&ioSection); DeleteCriticalSection(&ioSection);
} }
void VpcdReader::init(wchar_t *section) { void VpcdReader::init(wchar_t *section) {
portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"BixVReader.ini"); portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"BixVReader.ini");
port=(short) GetPrivateProfileInt(section,L"TCP_PORT",portBase+instance,L"BixVReader.ini"); port=(short) GetPrivateProfileInt(section,L"TCP_PORT",portBase+instance,L"BixVReader.ini");
} }
@@ -106,17 +106,21 @@ void VpcdReader::shutdown() {
vicc_exit((struct vicc_ctx *) ctx); vicc_exit((struct vicc_ctx *) ctx);
state=SCARD_ABSENT; state=SCARD_ABSENT;
ctx = NULL; ctx = NULL;
if (waitRemoveIpr!=NULL) { if (!waitRemoveIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitRemoveIpr->UnmarkCancelable()==S_OK) while (!waitRemoveIpr.empty()) {
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
waitRemoveIpr=NULL; if (ipr->UnmarkCancelable()==S_OK)
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitRemoveIpr.pop_back();
}
} }
if (waitInsertIpr!=NULL) { while (!waitInsertIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED)); if (ipr->UnmarkCancelable()==S_OK)
waitInsertIpr=NULL; ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
waitInsertIpr.pop_back();
} }
} }
@@ -124,19 +128,26 @@ void VpcdReader::signalRemoval(void) {
if (cardPresent) { if (cardPresent) {
cardPresent = false; cardPresent = false;
state=SCARD_ABSENT; state=SCARD_ABSENT;
if (waitRemoveIpr!=NULL) { if (!waitRemoveIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitRemoveIpr->UnmarkCancelable()==S_OK) { while (!waitRemoveIpr.empty()) {
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
}
waitRemoveIpr.pop_back();
} }
waitRemoveIpr=NULL;
} }
if (waitInsertIpr!=NULL) { if (!waitInsertIpr.empty()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) { while (!waitInsertIpr.empty()) {
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
SectionLocker lock(device->m_RequestLock);
if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
}
waitInsertIpr.pop_back();
} }
waitInsertIpr=NULL;
} }
} }
} }
@@ -144,12 +155,16 @@ void VpcdReader::signalRemoval(void) {
void VpcdReader::signalInsertion(void) { void VpcdReader::signalInsertion(void) {
if (!cardPresent) { if (!cardPresent) {
cardPresent = true; cardPresent = true;
if (waitInsertIpr!=NULL) { while (!waitInsertIpr.empty()) {
if (initProtocols()) { if (initProtocols()) {
SectionLocker lock(device->m_RequestLock); SectionLocker lock(device->m_RequestLock);
if (waitInsertIpr->UnmarkCancelable()==S_OK) while (!waitInsertIpr.empty()) {
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0); CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
waitInsertIpr=NULL; if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
}
waitInsertIpr.pop_back();
}
state=SCARD_SWALLOWED; state=SCARD_SWALLOWED;
} }
} }

View File

@@ -18,7 +18,7 @@ CMyDevice::CreateInstance(
Routine Description: Routine Description:
This method creates and initializs an instance of the virtual smart card reader driver's This method creates and initializs an instance of the virtual smart card reader driver's
device callback object. device callback object.
Arguments: Arguments:
@@ -67,7 +67,7 @@ CMyDevice::CreateInstance(
hr = FxDriver->CreateDevice(FxDeviceInit, spCallback, &spIWDFDevice); hr = FxDriver->CreateDevice(FxDeviceInit, spCallback, &spIWDFDevice);
} }
device->numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini"); device->numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini");
WSADATA wsaData; WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
@@ -80,11 +80,11 @@ CMyDevice::CreateInstance(
wchar_t name[10]; wchar_t name[10];
swprintf(name,L"DEV%i",i); swprintf(name,L"DEV%i",i);
if (spIWDFDevice->CreateDeviceInterface(&SmartCardReaderGuid,name)!=0) if (spIWDFDevice->CreateDeviceInterface(&SmartCardReaderGuid,name)!=0)
OutputDebugString(L"[BixVReader]CreateDeviceInterface Failed"); OutputDebugString(L"[BixVReader]CreateDeviceInterface Failed");
} }
SAFE_RELEASE(device); SAFE_RELEASE(device);
return hr; return hr;
} }
@@ -103,7 +103,7 @@ void CMyDevice::ProcessIoControl(__in IWDFIoQueue* pQueue,
//SectionLocker lock(m_RequestLock); //SectionLocker lock(m_RequestLock);
int instance=0; int instance=0;
{ {
CComPtr<IWDFFile> pFileObject; CComPtr<IWDFFile> pFileObject;
pRequest->GetFileObject(&pFileObject); pRequest->GetFileObject(&pFileObject);
@@ -135,7 +135,7 @@ void CMyDevice::ProcessIoControl(__in IWDFIoQueue* pQueue,
else if (ControlCode==IOCTL_SMARTCARD_POWER) { else if (ControlCode==IOCTL_SMARTCARD_POWER) {
reader.IoSmartCardPower(pRequest,inBufSize,outBufSize); reader.IoSmartCardPower(pRequest,inBufSize,outBufSize);
return; return;
} }
else if (ControlCode==IOCTL_SMARTCARD_SET_ATTRIBUTE) { else if (ControlCode==IOCTL_SMARTCARD_SET_ATTRIBUTE) {
reader.IoSmartCardSetAttribute(pRequest,inBufSize,outBufSize); reader.IoSmartCardSetAttribute(pRequest,inBufSize,outBufSize);
return; return;
@@ -165,7 +165,7 @@ DWORD WINAPI ServerFunc(Reader *reader) {
// //
// CMyDevice::OnPrepareHardware // CMyDevice::OnPrepareHardware
// //
// Called by UMDF to prepare the hardware for use. // Called by UMDF to prepare the hardware for use.
// //
// Parameters: // Parameters:
// pWdfDevice - pointer to an IWDFDevice object representing the // pWdfDevice - pointer to an IWDFDevice object representing the
@@ -228,7 +228,7 @@ HRESULT CMyDevice::OnD0Entry(IN IWDFDevice* pWdfDevice,IN WDF_POWER_DEVICE_STAT
UNREFERENCED_PARAMETER(pWdfDevice); UNREFERENCED_PARAMETER(pWdfDevice);
UNREFERENCED_PARAMETER(previousState); UNREFERENCED_PARAMETER(previousState);
numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini"); numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini");
readers.resize(numInstances); readers.resize(numInstances);
for (int i=0;i<numInstances;i++) { for (int i=0;i<numInstances;i++) {
@@ -305,7 +305,7 @@ STDMETHODIMP_ (void) CMyDevice::OnCancel(IN IWDFIoRequest* pWdfRequest) {
SectionLocker lock(m_RequestLock); SectionLocker lock(m_RequestLock);
int instance=0; int instance=0;
{ {
CComPtr<IWDFFile> pFileObject; CComPtr<IWDFFile> pFileObject;
pWdfRequest->GetFileObject(&pFileObject); pWdfRequest->GetFileObject(&pFileObject);
@@ -318,13 +318,19 @@ STDMETHODIMP_ (void) CMyDevice::OnCancel(IN IWDFIoRequest* pWdfRequest) {
} }
Reader &reader=*readers[instance]; Reader &reader=*readers[instance];
if (pWdfRequest==reader.waitRemoveIpr) { for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitRemoveIpr.begin();
OutputDebugString(L"[BixVReader]Cancel Remove"); it != reader.waitRemoveIpr.end(); it++) {
reader.waitRemoveIpr=NULL; if (pWdfRequest == *it) {
OutputDebugString(L"[BixVReader]Cancel Remove");
reader.waitRemoveIpr.erase(it);
}
} }
else if (pWdfRequest==reader.waitInsertIpr) { for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitInsertIpr.begin();
OutputDebugString(L"[BixVReader]Cancel Insert"); it != reader.waitInsertIpr.end(); it++) {
reader.waitInsertIpr=NULL; if (pWdfRequest == *it) {
OutputDebugString(L"[BixVReader]Cancel Insert");
reader.waitInsertIpr.erase(it);
}
} }
pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0); pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
} }