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

@@ -169,13 +169,17 @@ 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;
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;
}
}
@@ -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();
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -205,13 +205,17 @@ 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;
}
}
@@ -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;
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();
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}