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; 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();
if (ipr->UnmarkCancelable()==S_OK) {
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
}
waitInsertIpr.pop_back();
}
state=SCARD_SWALLOWED; state=SCARD_SWALLOWED;
} }
} }
@@ -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

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

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;

View File

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

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

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