BixVReader: Add multi application support for IoRequests (#114)
fixes https://github.com/frankmorgner/vsmartcard/issues/105
This commit is contained in:
@@ -10,15 +10,15 @@
|
||||
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
|
||||
{
|
||||
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
|
||||
TEXT("(D;OICI;GA;;;AN)") // Deny access to
|
||||
// anonymous logon
|
||||
TEXT("(A;OICI;GRGWGX;;;AU)") // Allow
|
||||
// read/write/execute
|
||||
// to authenticated
|
||||
TEXT("(D;OICI;GA;;;AN)") // Deny access to
|
||||
// anonymous logon
|
||||
TEXT("(A;OICI;GRGWGX;;;AU)") // Allow
|
||||
// read/write/execute
|
||||
// to authenticated
|
||||
// users
|
||||
TEXT("(A;OICI;GA;;;BA)"); // Allow full control
|
||||
TEXT("(A;OICI;GA;;;BA)"); // Allow full control
|
||||
// to administrators
|
||||
|
||||
if (NULL == pSA)
|
||||
@@ -45,7 +45,7 @@ void PipeReader::init(wchar_t *section) {
|
||||
GetPrivateProfileStringW(section,L"PIPE_NAME",temp,pipeName,300,L"BixVReader.ini");
|
||||
swprintf(temp,L"SCardSimulatorDriverEvents%i",instance);
|
||||
GetPrivateProfileStringW(section,L"PIPE_EVENT_NAME",temp,pipeEventName,300,L"BixVReader.ini");
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool PipeReader::CheckATR() {
|
||||
@@ -135,7 +135,7 @@ bool PipeReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
|
||||
DWORD PipeReader::startServer() {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = FALSE;
|
||||
sa.bInheritHandle = FALSE;
|
||||
CreateMyDACL(&sa);
|
||||
|
||||
wchar_t temp[300];
|
||||
@@ -169,17 +169,21 @@ DWORD PipeReader::startServer() {
|
||||
}
|
||||
pipe=_pipe;
|
||||
eventpipe=_eventpipe;
|
||||
if (waitInsertIpr!=NULL) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// if I'm waiting for card insertion, verify if there's a card present
|
||||
if (initProtocols()) {
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr=NULL;
|
||||
state=SCARD_SWALLOWED;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
state=SCARD_SWALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (true) {
|
||||
// wait for a command
|
||||
DWORD command=0;
|
||||
@@ -190,25 +194,34 @@ DWORD PipeReader::startServer() {
|
||||
powered=0;
|
||||
pipe=NULL;
|
||||
eventpipe=NULL;
|
||||
if (waitRemoveIpr!=NULL) {// card inserted
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"[BixVReader]complete Wait Remove");
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[BixVReader]Wait Remove Unmarked");
|
||||
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[BixVReader]Wait Remove Completed");
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
OutputDebugString(L"[BixVReader]complete Wait Remove");
|
||||
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()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"[BixVReader]cancel Wait Remove");
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[BixVReader]Wait Insert Unmarked");
|
||||
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
OutputDebugString(L"[BixVReader]Wait Insert Cancelled");
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
OutputDebugString(L"[BixVReader]cancel Wait Remove");
|
||||
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;
|
||||
}
|
||||
DisconnectNamedPipe(_pipe);
|
||||
DisconnectNamedPipe(_eventpipe);
|
||||
@@ -217,22 +230,28 @@ DWORD PipeReader::startServer() {
|
||||
OutputDebugString(L"[BixVReader]Pipe data");
|
||||
if (command==0)
|
||||
powered=0;
|
||||
if (command==0 && waitRemoveIpr!=NULL) {// card removed
|
||||
if (command==0 && !waitRemoveIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_ABSENT;
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK) {
|
||||
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
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);
|
||||
state=SCARD_SWALLOWED;
|
||||
initProtocols();
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK) {
|
||||
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
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() {
|
||||
state=SCARD_ABSENT;
|
||||
if (waitRemoveIpr!=NULL) {
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK)
|
||||
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr=NULL;
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
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);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr=NULL;
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ void Reader::init(wchar_t *section) {
|
||||
void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
|
||||
|
||||
OutputDebugString(L"[BixVReader][IPRE]IOCTL_SMARTCARD_IS_PRESENT");
|
||||
if (CheckATR()) {
|
||||
// there's a smart card present, so complete the request
|
||||
@@ -25,7 +25,7 @@ void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_
|
||||
else {
|
||||
// there's no smart card present, so leave the request pending; it will be completed later
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
waitInsertIpr=pRequest;
|
||||
waitInsertIpr.push_back(pRequest);
|
||||
IRequestCallbackCancel *callback;
|
||||
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
|
||||
pRequest->MarkCancelable(callback);
|
||||
@@ -54,7 +54,7 @@ void Reader::IoSmartCardIsAbsent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
// there's a smart card present, so leave the request pending; it will be completed later
|
||||
waitRemoveIpr=pRequest;
|
||||
waitRemoveIpr.push_back(pRequest);
|
||||
IRequestCallbackCancel *callback;
|
||||
|
||||
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
|
||||
@@ -91,7 +91,7 @@ void Reader::IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T ou
|
||||
DWORD ATRsize;
|
||||
if (!QueryATR(ATR,&ATRsize,true))
|
||||
{
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
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(instance);
|
||||
|
||||
DWORD requestedProtocol=getInt(pRequest);
|
||||
DWORD requestedProtocol=getInt(pRequest);
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[BixVReader][SPRT]IOCTL_SMARTCARD_SET_PROTOCOL:%08X",requestedProtocol);
|
||||
OutputDebugString(log);
|
||||
@@ -119,10 +119,10 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
|
||||
if (!QueryATR(ATR,&ATRsize,true))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (((requestedProtocol & SCARD_PROTOCOL_T1) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
|
||||
protocol = SCARD_PROTOCOL_T1;
|
||||
@@ -130,7 +130,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[BixVReader]PROTOCOL SET: T1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (((requestedProtocol & 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);
|
||||
OutputDebugString(L"[BixVReader]PROTOCOL SET: T0");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
|
||||
@@ -148,7 +148,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[BixVReader]PROTOCOL SET: T1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T0) != 0)) {
|
||||
@@ -157,7 +157,7 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[BixVReader]PROTOCOL SET: T0");
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
state=SCARD_NEGOTIABLE;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
@@ -170,10 +170,10 @@ void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZ
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
UNREFERENCED_PARAMETER(instance);
|
||||
OutputDebugString(L"[BixVReader][SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE");
|
||||
|
||||
|
||||
IWDFMemory *inmem=NULL;
|
||||
pRequest->GetInputMemory(&inmem);
|
||||
|
||||
|
||||
SIZE_T 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))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
((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) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
|
||||
|
||||
wchar_t log[300]=L"";
|
||||
char temp[300];
|
||||
|
||||
@@ -238,7 +238,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00a):
|
||||
// custom attribute; PipeName
|
||||
if (rpcType==0) {
|
||||
if (rpcType==0) {
|
||||
PipeReader *pipe=(PipeReader *)this;
|
||||
OutputDebugString(L"[BixVReader][GATT]PIPE_NAME");
|
||||
sprintf(temp,"%S",pipe->pipeName);
|
||||
@@ -251,7 +251,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00b):
|
||||
// custom attribute; EventPipeName
|
||||
if (rpcType==0) {
|
||||
if (rpcType==0) {
|
||||
PipeReader *pipe=(PipeReader *)this;
|
||||
OutputDebugString(L"[BixVReader][GATT]EVENT_PIPE_NAME");
|
||||
sprintf(temp,"%S",pipe->pipeEventName);
|
||||
@@ -264,7 +264,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00c):
|
||||
// custom attribute; TCP port
|
||||
if (rpcType==1) {
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[BixVReader][GATT]PORT");
|
||||
setInt(device,pRequest,tcpIp->port);
|
||||
@@ -276,7 +276,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00d):
|
||||
// custom attribute; TCP event port
|
||||
if (rpcType==1) {
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[BixVReader][GATT]EVENT_PORT");
|
||||
setInt(device,pRequest,tcpIp->eventPort);
|
||||
@@ -288,7 +288,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00e):
|
||||
// custom attribute; TCP base port
|
||||
if (rpcType==1) {
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[BixVReader][GATT]BASE_PORT");
|
||||
setInt(device,pRequest,tcpIp->portBase);
|
||||
@@ -323,7 +323,7 @@ void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SI
|
||||
if (!QueryATR(ATR,&ATRsize))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
setBuffer(device,pRequest,ATR,ATRsize);
|
||||
@@ -381,7 +381,7 @@ bool Reader::initProtocols() {
|
||||
else if (i==1) {
|
||||
// we are in T0; read number of historical bytes
|
||||
let='A';
|
||||
y=ATR[i] >> 4;
|
||||
y=ATR[i] >> 4;
|
||||
iTotHistBytes=ATR[i] & 0xF;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <Winsock2.h>
|
||||
#include <vector>
|
||||
|
||||
class CMyDevice;
|
||||
|
||||
class Reader {
|
||||
public:
|
||||
CMyDevice *device;
|
||||
CComPtr<IWDFIoRequest> waitRemoveIpr;
|
||||
CComPtr<IWDFIoRequest> waitInsertIpr;
|
||||
std::vector< CComPtr<IWDFIoRequest> > waitRemoveIpr;
|
||||
std::vector< CComPtr<IWDFIoRequest> > waitInsertIpr;
|
||||
inbuf;
|
||||
outbuf;
|
||||
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
int state;
|
||||
DWORD protocol; // T0 or T1 - protocol in use
|
||||
DWORD availableProtocol; // T0, T1 or Both - protocols available
|
||||
|
||||
|
||||
void IoSmartCardGetAttribute(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);
|
||||
@@ -57,7 +58,7 @@ public:
|
||||
DWORD startServer();
|
||||
void shutdown();
|
||||
void init(wchar_t *section);
|
||||
|
||||
|
||||
CRITICAL_SECTION eventSection;
|
||||
CRITICAL_SECTION dataSection;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ TcpIpReader::TcpIpReader() {
|
||||
state=SCARD_ABSENT;
|
||||
}
|
||||
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");
|
||||
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);
|
||||
OutputDebugString(log);
|
||||
|
||||
if (waitInsertIpr!=NULL) {
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// if I'm waiting for card insertion, verify if there's a card present
|
||||
if (initProtocols()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr=NULL;
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
state=SCARD_SWALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (true) {
|
||||
// wait for a command
|
||||
DWORD command=0;
|
||||
@@ -226,45 +230,62 @@ DWORD TcpIpReader::startServer() {
|
||||
powered=0;
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
::shutdown(AcceptEventSocket,SD_BOTH);
|
||||
if (waitRemoveIpr!=NULL) {// card inserted
|
||||
OutputDebugString(L"[BixVReader]complete Wait Remove");
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[BixVReader]Wait Remove Unmarked");
|
||||
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[BixVReader]Wait Remove Completed");
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
OutputDebugString(L"[BixVReader]complete Wait Remove");
|
||||
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
|
||||
OutputDebugString(L"[BixVReader]cancel Wait Remove");
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[BixVReader]Wait Insert Unmarked");
|
||||
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
OutputDebugString(L"[BixVReader]Wait Insert Cancelled");
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
OutputDebugString(L"[BixVReader]cancel Wait Remove");
|
||||
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;
|
||||
}
|
||||
OutputDebugString(L"[BixVReader]Socket data");
|
||||
if (command==0)
|
||||
powered=0;
|
||||
if (command==0 && waitRemoveIpr!=NULL) {// card removed
|
||||
if (command==0 && !waitRemoveIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_ABSENT;
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK)
|
||||
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitRemoveIpr=NULL;
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
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);
|
||||
state=SCARD_SWALLOWED;
|
||||
initProtocols();
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr=NULL;
|
||||
initProtocols();
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
@@ -291,16 +312,18 @@ void TcpIpReader::shutdown() {
|
||||
serverThread=NULL;
|
||||
eventsocket=NULL;
|
||||
socket=NULL;
|
||||
if (waitRemoveIpr!=NULL) {
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK)
|
||||
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr=NULL;
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
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);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr=NULL;
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ VpcdReader::~VpcdReader() {
|
||||
DeleteCriticalSection(&ioSection);
|
||||
}
|
||||
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");
|
||||
}
|
||||
@@ -106,17 +106,21 @@ void VpcdReader::shutdown() {
|
||||
vicc_exit((struct vicc_ctx *) ctx);
|
||||
state=SCARD_ABSENT;
|
||||
ctx = NULL;
|
||||
if (waitRemoveIpr!=NULL) {
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK)
|
||||
waitRemoveIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr=NULL;
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
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);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr=NULL;
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,19 +128,26 @@ void VpcdReader::signalRemoval(void) {
|
||||
if (cardPresent) {
|
||||
cardPresent = false;
|
||||
state=SCARD_ABSENT;
|
||||
if (waitRemoveIpr!=NULL) {
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitRemoveIpr->UnmarkCancelable()==S_OK) {
|
||||
waitRemoveIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
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);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK) {
|
||||
waitInsertIpr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
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) {
|
||||
if (!cardPresent) {
|
||||
cardPresent = true;
|
||||
if (waitInsertIpr!=NULL) {
|
||||
while (!waitInsertIpr.empty()) {
|
||||
if (initProtocols()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
if (waitInsertIpr->UnmarkCancelable()==S_OK)
|
||||
waitInsertIpr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr=NULL;
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
state=SCARD_SWALLOWED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ CMyDevice::CreateInstance(
|
||||
|
||||
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.
|
||||
|
||||
Arguments:
|
||||
@@ -67,7 +67,7 @@ CMyDevice::CreateInstance(
|
||||
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;
|
||||
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
@@ -80,11 +80,11 @@ CMyDevice::CreateInstance(
|
||||
wchar_t name[10];
|
||||
swprintf(name,L"DEV%i",i);
|
||||
|
||||
if (spIWDFDevice->CreateDeviceInterface(&SmartCardReaderGuid,name)!=0)
|
||||
if (spIWDFDevice->CreateDeviceInterface(&SmartCardReaderGuid,name)!=0)
|
||||
OutputDebugString(L"[BixVReader]CreateDeviceInterface Failed");
|
||||
}
|
||||
|
||||
SAFE_RELEASE(device);
|
||||
SAFE_RELEASE(device);
|
||||
return hr;
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ void CMyDevice::ProcessIoControl(__in IWDFIoQueue* pQueue,
|
||||
|
||||
//SectionLocker lock(m_RequestLock);
|
||||
int instance=0;
|
||||
{
|
||||
{
|
||||
CComPtr<IWDFFile> pFileObject;
|
||||
pRequest->GetFileObject(&pFileObject);
|
||||
|
||||
@@ -135,7 +135,7 @@ void CMyDevice::ProcessIoControl(__in IWDFIoQueue* pQueue,
|
||||
else if (ControlCode==IOCTL_SMARTCARD_POWER) {
|
||||
reader.IoSmartCardPower(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_SET_ATTRIBUTE) {
|
||||
reader.IoSmartCardSetAttribute(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
@@ -165,7 +165,7 @@ DWORD WINAPI ServerFunc(Reader *reader) {
|
||||
//
|
||||
// CMyDevice::OnPrepareHardware
|
||||
//
|
||||
// Called by UMDF to prepare the hardware for use.
|
||||
// Called by UMDF to prepare the hardware for use.
|
||||
//
|
||||
// Parameters:
|
||||
// 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(previousState);
|
||||
|
||||
numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini");
|
||||
numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"BixVReader.ini");
|
||||
readers.resize(numInstances);
|
||||
|
||||
for (int i=0;i<numInstances;i++) {
|
||||
@@ -305,7 +305,7 @@ STDMETHODIMP_ (void) CMyDevice::OnCancel(IN IWDFIoRequest* pWdfRequest) {
|
||||
SectionLocker lock(m_RequestLock);
|
||||
|
||||
int instance=0;
|
||||
{
|
||||
{
|
||||
CComPtr<IWDFFile> pFileObject;
|
||||
pWdfRequest->GetFileObject(&pFileObject);
|
||||
|
||||
@@ -318,13 +318,19 @@ STDMETHODIMP_ (void) CMyDevice::OnCancel(IN IWDFIoRequest* pWdfRequest) {
|
||||
}
|
||||
Reader &reader=*readers[instance];
|
||||
|
||||
if (pWdfRequest==reader.waitRemoveIpr) {
|
||||
OutputDebugString(L"[BixVReader]Cancel Remove");
|
||||
reader.waitRemoveIpr=NULL;
|
||||
for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitRemoveIpr.begin();
|
||||
it != reader.waitRemoveIpr.end(); it++) {
|
||||
if (pWdfRequest == *it) {
|
||||
OutputDebugString(L"[BixVReader]Cancel Remove");
|
||||
reader.waitRemoveIpr.erase(it);
|
||||
}
|
||||
}
|
||||
else if (pWdfRequest==reader.waitInsertIpr) {
|
||||
OutputDebugString(L"[BixVReader]Cancel Insert");
|
||||
reader.waitInsertIpr=NULL;
|
||||
for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitInsertIpr.begin();
|
||||
it != reader.waitInsertIpr.end(); it++) {
|
||||
if (pWdfRequest == *it) {
|
||||
OutputDebugString(L"[BixVReader]Cancel Insert");
|
||||
reader.waitInsertIpr.erase(it);
|
||||
}
|
||||
}
|
||||
pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user