Rename BixV Reader to VivoKey Smart Reader
This commit is contained in:
138
virtualsmartcard/win32/VivoKeySmartReader/DllMain.cpp
Normal file
138
virtualsmartcard/win32/VivoKeySmartReader/DllMain.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "internal.h"
|
||||
|
||||
class CVirtualSmartCardDriverModule : public CAtlDllModuleT<CVirtualSmartCardDriverModule> {} _AtlModule;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DllMain
|
||||
//
|
||||
// This is the main DLL Entry Point.
|
||||
//
|
||||
// Parameters:
|
||||
// hInstance - Handle to the DLL module
|
||||
// dwReason - Indicates why the DLL entry point is being called
|
||||
// lpReserved - Additional information based on dwReason
|
||||
//
|
||||
// Return Values:
|
||||
// TRUE = initialization succeeds
|
||||
// FALSE = initialization fails
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance,
|
||||
DWORD dwReason,
|
||||
LPVOID lpReserved)
|
||||
{
|
||||
inFunc
|
||||
(lpReserved);
|
||||
|
||||
switch (dwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
DisableThreadLibraryCalls(hInstance);
|
||||
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
_AtlModule.Term();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Call the ATL module class so it can initialize
|
||||
return _AtlModule.DllMain(dwReason, lpReserved);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DllCanUnloadNow
|
||||
//
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
//
|
||||
// Parameters:
|
||||
// void - (unused argument)
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: DLL can be unloaded
|
||||
// S_FALSE: DLL cannot be unloaded now
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
inFunc
|
||||
return _AtlModule.DllCanUnloadNow();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DllGetClassObject
|
||||
//
|
||||
// Returns a class factory to create an object of the requested type
|
||||
//
|
||||
// Parameters:
|
||||
// rclsid - CLSID that will associate the correct data and code
|
||||
// riid - Reference to the IID the caller will use
|
||||
// ppv - pointer to an interface pointer requested in riid
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: The object was retrieved successfully.
|
||||
// CLASS_E_CLASSNOTAVAILABLE: The DLL does not support the class
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
STDAPI DllGetClassObject(__in REFCLSID rclsid, __in REFIID riid, __deref_out LPVOID* ppv)
|
||||
{
|
||||
inFunc
|
||||
return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DllRegisterServer
|
||||
//
|
||||
// Adds entries to the system registry
|
||||
//
|
||||
// Parameters:
|
||||
// void - (unused argument)
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: The registry entries were created successfully
|
||||
// SELFREG_E_TYPELIB: The server was unable to complete the
|
||||
// registration of all the type libraries used by its classes
|
||||
// SELFREG_E_CLASS: The server was unable to complete the
|
||||
// registration of all the object classes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
inFunc
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DllUnregisterServer
|
||||
//
|
||||
// Removes entries from the system registry
|
||||
//
|
||||
// Parameters:
|
||||
// void - (unused argument)
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: The registry entries were removed successfully
|
||||
// S_FALSE: Unregistration of known entries was successful, but
|
||||
// other entries still exist for this server's classes
|
||||
// SELFREG_E_TYPELIB: The server was unable to remove the entries
|
||||
// of all the type libraries used by its classes
|
||||
// SELFREG_E_CLASS: The server was unable to to remove the entries
|
||||
// of all the object classes
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
inFunc
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
286
virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp
Normal file
286
virtualsmartcard/win32/VivoKeySmartReader/PipeReader.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "reader.h"
|
||||
#include "device.h"
|
||||
#include <winscard.h>
|
||||
#include "memory.h"
|
||||
#include <Sddl.h>
|
||||
#include "sectionLocker.h"
|
||||
|
||||
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
|
||||
{
|
||||
TCHAR * szSD = TEXT("D:") // Discretionary ACL
|
||||
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
|
||||
// users
|
||||
TEXT("(A;OICI;GA;;;BA)"); // Allow full control
|
||||
// to administrators
|
||||
|
||||
if (NULL == pSA)
|
||||
return FALSE;
|
||||
|
||||
return ConvertStringSecurityDescriptorToSecurityDescriptor(
|
||||
szSD,
|
||||
SDDL_REVISION_1,
|
||||
&(pSA->lpSecurityDescriptor),
|
||||
NULL);
|
||||
}
|
||||
|
||||
PipeReader::PipeReader() {
|
||||
rpcType=0;
|
||||
state=SCARD_ABSENT;
|
||||
|
||||
InitializeCriticalSection(&eventSection);
|
||||
InitializeCriticalSection(&dataSection);
|
||||
}
|
||||
|
||||
void PipeReader::init(wchar_t *section) {
|
||||
wchar_t temp[300];
|
||||
swprintf(temp,L"SCardSimulatorDriver%i",instance);
|
||||
GetPrivateProfileStringW(section,L"PIPE_NAME",temp,pipeName,300,L"VivoKeySmartReader.ini");
|
||||
swprintf(temp,L"SCardSimulatorDriverEvents%i",instance);
|
||||
GetPrivateProfileStringW(section,L"PIPE_EVENT_NAME",temp,pipeEventName,300,L"VivoKeySmartReader.ini");
|
||||
|
||||
}
|
||||
|
||||
bool PipeReader::CheckATR() {
|
||||
if (pipe==NULL)
|
||||
return false;
|
||||
DWORD read=0;
|
||||
DWORD command=1;
|
||||
if (!WriteFile(pipe,&command,sizeof(DWORD),&read,NULL)) {
|
||||
return false;
|
||||
}
|
||||
FlushFileBuffers(pipe);
|
||||
DWORD size=0;
|
||||
if (!ReadFile(pipe,&size,sizeof(DWORD),&read,NULL)) {
|
||||
return false;
|
||||
}
|
||||
if (size==0)
|
||||
return false;
|
||||
BYTE ATR[100];
|
||||
if (!ReadFile(pipe,ATR,size,&read,NULL)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool PipeReader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen) {
|
||||
if (pipe==NULL)
|
||||
return false;
|
||||
DWORD command=2;
|
||||
DWORD read=0;
|
||||
if (!WriteFile(pipe,&command,sizeof(DWORD),&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
DWORD dwAPDUlen=(DWORD)APDUlen;
|
||||
if (!WriteFile(pipe,&dwAPDUlen,sizeof(DWORD),&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
if (!WriteFile(pipe,APDU,APDUlen,&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
FlushFileBuffers(pipe);
|
||||
DWORD dwRespLen=0;
|
||||
if (!ReadFile(pipe,&dwRespLen,sizeof(DWORD),&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
if (0 != dwRespLen) {
|
||||
BYTE *p=(BYTE *)realloc(*Resp, dwRespLen);
|
||||
if (p==NULL) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
*Resp=p;
|
||||
}
|
||||
if (!ReadFile(pipe,*Resp,dwRespLen,&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
(*Resplen)=(int)dwRespLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PipeReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
|
||||
if (pipe==NULL)
|
||||
return false;
|
||||
DWORD command=reset ? 0 : 1;
|
||||
DWORD read=0;
|
||||
if (!WriteFile(pipe,&command,sizeof(DWORD),&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
FlushFileBuffers(pipe);
|
||||
DWORD size=0;
|
||||
if (!ReadFile(pipe,&size,sizeof(DWORD),&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
if (size==0)
|
||||
return false;
|
||||
if (!ReadFile(pipe,ATR,size,&read,NULL)) {
|
||||
pipe=NULL;
|
||||
return false;
|
||||
}
|
||||
(*ATRsize)=size;
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD PipeReader::startServer() {
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = FALSE;
|
||||
CreateMyDACL(&sa);
|
||||
|
||||
wchar_t temp[300];
|
||||
swprintf(temp,L"\\\\.\\pipe\\%s",pipeName);
|
||||
HANDLE _pipe=CreateNamedPipe(temp,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,PIPE_UNLIMITED_INSTANCES,0,0,0,&sa);
|
||||
swprintf(temp,L"\\\\.\\pipe\\%s",pipeEventName);
|
||||
HANDLE _eventpipe=CreateNamedPipe(temp,PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,PIPE_TYPE_BYTE,PIPE_UNLIMITED_INSTANCES,0,0,0,&sa);
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[VivoKeySmartReader]Pipe created:%s:%p",pipeName,_pipe);
|
||||
OutputDebugString(log);
|
||||
|
||||
while (true) {
|
||||
//__try {
|
||||
BOOL ris=ConnectNamedPipe(_pipe,NULL);
|
||||
if (ris==0) {
|
||||
swprintf(log,L"[VivoKeySmartReader]Pipe NOT connected:%x",GetLastError());
|
||||
OutputDebugString(log);
|
||||
}
|
||||
else {
|
||||
swprintf(log,L"[VivoKeySmartReader]Pipe connected");
|
||||
OutputDebugString(log);
|
||||
}
|
||||
ris=ConnectNamedPipe(_eventpipe,NULL);
|
||||
if (ris==0) {
|
||||
swprintf(log,L"[VivoKeySmartReader]Event Pipe NOT connected:%x",GetLastError());
|
||||
OutputDebugString(log);
|
||||
}
|
||||
else {
|
||||
swprintf(log,L"[VivoKeySmartReader]Event Pipe connected");
|
||||
OutputDebugString(log);
|
||||
}
|
||||
pipe=_pipe;
|
||||
eventpipe=_eventpipe;
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// if I'm waiting for card insertion, verify if there's a card present
|
||||
if (initProtocols()) {
|
||||
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;
|
||||
DWORD read=0;
|
||||
if (!ReadFile(eventpipe,&command,sizeof(DWORD),&read,NULL)) {
|
||||
state=SCARD_ABSENT;
|
||||
OutputDebugString(L"[VivoKeySmartReader]Pipe error");
|
||||
powered=0;
|
||||
pipe=NULL;
|
||||
eventpipe=NULL;
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
OutputDebugString(L"[VivoKeySmartReader]complete Wait Remove");
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Remove Unmarked");
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Remove Completed");
|
||||
}
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
}
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
OutputDebugString(L"[VivoKeySmartReader]cancel Wait Remove");
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Insert Unmarked");
|
||||
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Insert Cancelled");
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
DisconnectNamedPipe(_pipe);
|
||||
DisconnectNamedPipe(_eventpipe);
|
||||
break;
|
||||
}
|
||||
OutputDebugString(L"[VivoKeySmartReader]Pipe data");
|
||||
if (command==0)
|
||||
powered=0;
|
||||
if (command==0 && !waitRemoveIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_ABSENT;
|
||||
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.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_SWALLOWED;
|
||||
initProtocols();
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
//__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// wchar_t log[300];
|
||||
// DWORD err=GetExceptionCode();
|
||||
// swprintf(log,L"Exception:%08X",err);
|
||||
// OutputDebugString(log);
|
||||
//}
|
||||
}
|
||||
OutputDebugString(L"[VivoKeySmartReader]Pipe quit!!!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PipeReader::shutdown() {
|
||||
state=SCARD_ABSENT;
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
while (!waitInsertIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
124
virtualsmartcard/win32/VivoKeySmartReader/Queue.cpp
Normal file
124
virtualsmartcard/win32/VivoKeySmartReader/Queue.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "internal.h"
|
||||
#include "Device.h"
|
||||
#include "Queue.h"
|
||||
#include "SectionLocker.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyQueue::CMyQueue
|
||||
//
|
||||
// Object constructor function
|
||||
//
|
||||
// Initialize member variables
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
CMyQueue::CMyQueue() :
|
||||
m_pParentDevice(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyQueue::~CMyQueue
|
||||
//
|
||||
// Object destructor function
|
||||
//
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
CMyQueue::~CMyQueue()
|
||||
{
|
||||
// Release the reference that was incremented in CreateInstance()
|
||||
SAFE_RELEASE(m_pParentDevice);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyQueue::CreateInstance
|
||||
//
|
||||
// This function supports the COM factory creation system
|
||||
//
|
||||
// Parameters:
|
||||
// parentDevice - A pointer to the CWSSDevice object
|
||||
// ppUkwn - pointer to a pointer to the queue to be returned
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: The queue was created successfully
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CMyQueue::CreateInstance(__in IWDFDevice* pWdfDevice, CMyDevice* pMyDevice)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
CComObject<CMyQueue>* pMyQueue = NULL;
|
||||
|
||||
if(NULL == pMyDevice)
|
||||
{
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT hr = CComObject<CMyQueue>::CreateInstance(&pMyQueue);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
// AddRef the object
|
||||
pMyQueue->AddRef();
|
||||
|
||||
// Store the parent device object
|
||||
pMyQueue->m_pParentDevice = pMyDevice;
|
||||
|
||||
// Increment the reference for the lifetime of the CMyQueue object.
|
||||
pMyQueue->m_pParentDevice->AddRef();
|
||||
|
||||
CComPtr<IUnknown> spIUnknown;
|
||||
hr = pMyQueue->QueryInterface(IID_IUnknown, (void**)&spIUnknown);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
// Create the framework queue
|
||||
CComPtr<IWDFIoQueue> spDefaultQueue;
|
||||
hr = pWdfDevice->CreateIoQueue( spIUnknown,
|
||||
TRUE, // DefaultQueue
|
||||
WdfIoQueueDispatchParallel, // Parallel queue handling
|
||||
FALSE, // PowerManaged
|
||||
TRUE, // AllowZeroLengthRequests
|
||||
&spDefaultQueue
|
||||
);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
OutputDebugString (L"[VivoKeySmartReader]IoQueue NOT Created\n");
|
||||
}
|
||||
else
|
||||
OutputDebugString (L"[VivoKeySmartReader]IoQueue Created\n");
|
||||
|
||||
}
|
||||
|
||||
// Release the pMyQueue pointer when done. Note: UMDF holds a reference to it above
|
||||
SAFE_RELEASE(pMyQueue);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyQueue::OnDeviceIoControl
|
||||
//
|
||||
// This method is called when an IOCTL is sent to the device
|
||||
//
|
||||
// Parameters:
|
||||
// pQueue - pointer to an IO queue
|
||||
// pRequest - pointer to an IO request
|
||||
// ControlCode - The IOCTL to process
|
||||
// InputBufferSizeInBytes - the size of the input buffer
|
||||
// OutputBufferSizeInBytes - the size of the output buffer
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
STDMETHODIMP_ (void) CMyQueue::OnDeviceIoControl(
|
||||
__in IWDFIoQueue* pQueue,
|
||||
__in IWDFIoRequest* pRequest,
|
||||
__in ULONG ControlCode,
|
||||
SIZE_T InputBufferSizeInBytes,
|
||||
SIZE_T OutputBufferSizeInBytes
|
||||
)
|
||||
{
|
||||
m_pParentDevice->ProcessIoControl(pQueue,pRequest,ControlCode,InputBufferSizeInBytes,OutputBufferSizeInBytes);
|
||||
}
|
||||
36
virtualsmartcard/win32/VivoKeySmartReader/Queue.h
Normal file
36
virtualsmartcard/win32/VivoKeySmartReader/Queue.h
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
class ATL_NO_VTABLE CMyQueue :
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public IQueueCallbackDeviceIoControl
|
||||
{
|
||||
public:
|
||||
virtual ~CMyQueue();
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CMyQueue)
|
||||
|
||||
BEGIN_COM_MAP(CMyQueue)
|
||||
COM_INTERFACE_ENTRY(IQueueCallbackDeviceIoControl)
|
||||
END_COM_MAP()
|
||||
|
||||
static HRESULT CreateInstance(__in IWDFDevice* pWdfDevice, CMyDevice* pMyDevice);
|
||||
|
||||
protected:
|
||||
CMyQueue();
|
||||
|
||||
// COM Interface methods
|
||||
public:
|
||||
// IQueueCallbackDeviceIoControl
|
||||
STDMETHOD_ (void, OnDeviceIoControl)(
|
||||
__in IWDFIoQueue* pQueue,
|
||||
__in IWDFIoRequest* pRequest,
|
||||
__in ULONG ControlCode,
|
||||
SIZE_T InputBufferSizeInBytes,
|
||||
SIZE_T OutputBufferSizeInBytes
|
||||
);
|
||||
|
||||
private:
|
||||
CMyDevice* m_pParentDevice; // Parent device object
|
||||
};
|
||||
|
||||
440
virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp
Normal file
440
virtualsmartcard/win32/VivoKeySmartReader/Reader.cpp
Normal file
@@ -0,0 +1,440 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "reader.h"
|
||||
#include "device.h"
|
||||
#include <winscard.h>
|
||||
#include "memory.h"
|
||||
#include <Sddl.h>
|
||||
#include "SectionLocker.h"
|
||||
|
||||
void Reader::init(wchar_t *section) {
|
||||
section;
|
||||
state=SCARD_ABSENT;
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardIsPresent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
|
||||
OutputDebugString(L"[VivoKeySmartReader][IPRE]IOCTL_SMARTCARD_IS_PRESENT");
|
||||
if (CheckATR()) {
|
||||
// there's a smart card present, so complete the request
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
else {
|
||||
// there's no smart card present, so leave the request pending; it will be completed later
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
waitInsertIpr.push_back(pRequest);
|
||||
IRequestCallbackCancel *callback;
|
||||
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
|
||||
pRequest->MarkCancelable(callback);
|
||||
callback->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardGetState(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
OutputDebugString(L"[VivoKeySmartReader][GSTA]IOCTL_SMARTCARD_GET_STATE");
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[VivoKeySmartReader]STATE:%08X",state);
|
||||
OutputDebugString(log);
|
||||
setInt(device,pRequest,state);
|
||||
}
|
||||
void Reader::IoSmartCardIsAbsent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
OutputDebugString(L"[VivoKeySmartReader][IABS]IOCTL_SMARTCARD_IS_ABSENT");
|
||||
if (!CheckATR()) {
|
||||
// there's no smart card present, so complete the request
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
// there's a smart card present, so leave the request pending; it will be completed later
|
||||
waitRemoveIpr.push_back(pRequest);
|
||||
IRequestCallbackCancel *callback;
|
||||
|
||||
device->QueryInterface(__uuidof(IRequestCallbackCancel),(void**)&callback);
|
||||
pRequest->MarkCancelable(callback);
|
||||
callback->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
OutputDebugString(L"[VivoKeySmartReader][POWR]IOCTL_SMARTCARD_POWER");
|
||||
DWORD code=getInt(pRequest);
|
||||
if (code==SCARD_COLD_RESET) {
|
||||
OutputDebugString(L"[VivoKeySmartReader][POWR]SCARD_COLD_RESET");
|
||||
protocol=0;
|
||||
powered=1;
|
||||
state=SCARD_NEGOTIABLE;
|
||||
}
|
||||
else if (code==SCARD_WARM_RESET) {
|
||||
OutputDebugString(L"[VivoKeySmartReader][POWR]SCARD_WARM_RESET");
|
||||
protocol=0;
|
||||
powered=1;
|
||||
state=SCARD_NEGOTIABLE;
|
||||
}
|
||||
else if (code==SCARD_POWER_DOWN) {
|
||||
OutputDebugString(L"[VivoKeySmartReader][POWR]SCARD_POWER_DOWN");
|
||||
protocol=0;
|
||||
powered=0;
|
||||
state=SCARD_SWALLOWED;
|
||||
}
|
||||
if (code==SCARD_COLD_RESET || code==SCARD_WARM_RESET) {
|
||||
BYTE ATR[100];
|
||||
DWORD ATRsize;
|
||||
if (!QueryATR(ATR,&ATRsize,true))
|
||||
{
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
setBuffer(device,pRequest,ATR,ATRsize);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
UNREFERENCED_PARAMETER(instance);
|
||||
|
||||
DWORD requestedProtocol=getInt(pRequest);
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[VivoKeySmartReader][SPRT]IOCTL_SMARTCARD_SET_PROTOCOL:%08X",requestedProtocol);
|
||||
OutputDebugString(log);
|
||||
|
||||
BYTE ATR[100];
|
||||
DWORD ATRsize;
|
||||
state=SCARD_SPECIFIC;
|
||||
if (!QueryATR(ATR,&ATRsize,true))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((requestedProtocol & SCARD_PROTOCOL_T1) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
|
||||
protocol = SCARD_PROTOCOL_T1;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]PROTOCOL SET: T1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((requestedProtocol & SCARD_PROTOCOL_T0) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T0) != 0)) {
|
||||
protocol = SCARD_PROTOCOL_T0;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]PROTOCOL SET: T0");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T1) != 0)) {
|
||||
protocol = SCARD_PROTOCOL_T1;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]PROTOCOL SET: T1");
|
||||
return;
|
||||
}
|
||||
|
||||
if (((requestedProtocol & (SCARD_PROTOCOL_DEFAULT)) != 0) &&
|
||||
((availableProtocol & SCARD_PROTOCOL_T0) != 0)) {
|
||||
protocol = SCARD_PROTOCOL_T0;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]PROTOCOL SET: T0");
|
||||
return;
|
||||
}
|
||||
{
|
||||
state=SCARD_NEGOTIABLE;
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardSetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
UNREFERENCED_PARAMETER(instance);
|
||||
OutputDebugString(L"[VivoKeySmartReader][SATT]IOCTL_SMARTCARD_SET_ATTRIBUTE");
|
||||
|
||||
IWDFMemory *inmem=NULL;
|
||||
pRequest->GetInputMemory(&inmem);
|
||||
|
||||
SIZE_T size;
|
||||
BYTE *data=(BYTE *)inmem->GetDataBuffer(&size);
|
||||
|
||||
DWORD minCode=*(DWORD*)(data);
|
||||
bool handled=false;
|
||||
if (minCode==SCARD_ATTR_DEVICE_IN_USE) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"[VivoKeySmartReader][SATT]SCARD_ATTR_DEVICE_IN_USE");
|
||||
pRequest->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
handled=true;
|
||||
}
|
||||
inmem->Release();
|
||||
if (!handled) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[VivoKeySmartReader][SATT]ERROR_NOT_SUPPORTED:%08X",minCode);
|
||||
OutputDebugString(log);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardTransmit(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
UNREFERENCED_PARAMETER(outBufSize);
|
||||
OutputDebugString(L"[VivoKeySmartReader][TRSM]IOCTL_SMARTCARD_TRANSMIT");
|
||||
SCARD_IO_REQUEST *scardRequest=NULL;
|
||||
int scardRequestSize=0;
|
||||
BYTE *RAPDU=NULL;
|
||||
int RAPDUSize=0;
|
||||
if (!getBuffer(pRequest,(void **)&scardRequest,&scardRequestSize)
|
||||
|| scardRequestSize<sizeof *scardRequest
|
||||
|| scardRequest->dwProtocol!=protocol) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_INVALID_DEVICE_STATE, 0);
|
||||
goto end;
|
||||
}
|
||||
if (!QueryTransmit((BYTE *)(scardRequest+1),
|
||||
scardRequestSize-sizeof(SCARD_IO_REQUEST),
|
||||
&RAPDU,&RAPDUSize))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
goto end;
|
||||
}
|
||||
SCARD_IO_REQUEST *p=(SCARD_IO_REQUEST *)realloc(scardRequest,RAPDUSize+sizeof(SCARD_IO_REQUEST));
|
||||
if (p==NULL) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_INVALID_DEVICE_STATE, 0);
|
||||
goto end;
|
||||
}
|
||||
scardRequest = p;
|
||||
scardRequest->cbPciLength=sizeof(SCARD_IO_REQUEST);
|
||||
scardRequest->dwProtocol=protocol;
|
||||
memcpy(scardRequest+1,RAPDU,RAPDUSize);
|
||||
setBuffer(device,pRequest,scardRequest,RAPDUSize+sizeof(SCARD_IO_REQUEST));
|
||||
end:
|
||||
free(scardRequest);
|
||||
free(RAPDU);
|
||||
}
|
||||
|
||||
void Reader::IoSmartCardGetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize) {
|
||||
UNREFERENCED_PARAMETER(inBufSize);
|
||||
|
||||
wchar_t log[300]=L"";
|
||||
char temp[300];
|
||||
|
||||
DWORD code=getInt(pRequest);
|
||||
swprintf(log,L"[VivoKeySmartReader][GATT] - code %0X",code);
|
||||
OutputDebugString(log);
|
||||
|
||||
switch(code) {
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA009):
|
||||
// custom attribute; RPC_TYPE
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]RPC_TYPE");
|
||||
setInt(device,pRequest,rpcType);
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00a):
|
||||
// custom attribute; PipeName
|
||||
if (rpcType==0) {
|
||||
PipeReader *pipe=(PipeReader *)this;
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]PIPE_NAME");
|
||||
sprintf(temp,"%S",pipe->pipeName);
|
||||
setString(device,pRequest,(char*)temp,(int)outBufSize);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00b):
|
||||
// custom attribute; EventPipeName
|
||||
if (rpcType==0) {
|
||||
PipeReader *pipe=(PipeReader *)this;
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]EVENT_PIPE_NAME");
|
||||
sprintf(temp,"%S",pipe->pipeEventName);
|
||||
setString(device,pRequest,(char*)temp,(int)outBufSize);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00c):
|
||||
// custom attribute; TCP port
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]PORT");
|
||||
setInt(device,pRequest,tcpIp->port);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00d):
|
||||
// custom attribute; TCP event port
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]EVENT_PORT");
|
||||
setInt(device,pRequest,tcpIp->eventPort);
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
return;
|
||||
case SCARD_ATTR_VALUE(SCARD_CLASS_VENDOR_DEFINED, 0xA00e):
|
||||
// custom attribute; TCP base port
|
||||
if (rpcType==1) {
|
||||
TcpIpReader *tcpIp=(TcpIpReader *)this;
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]BASE_PORT");
|
||||
setInt(device,pRequest,tcpIp->portBase);
|
||||
tcpIp;
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
return;
|
||||
case SCARD_ATTR_CHARACTERISTICS:
|
||||
// 0x00000000 No special characteristics
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_CHARACTERISTICS");
|
||||
setInt(device,pRequest,0);
|
||||
return;
|
||||
case SCARD_ATTR_VENDOR_NAME:
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_VENDOR_NAME");
|
||||
setString(device,pRequest,vendorName,(int)outBufSize);
|
||||
return;
|
||||
case SCARD_ATTR_VENDOR_IFD_TYPE:
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_VENDOR_IFD_TYPE");
|
||||
setString(device,pRequest,vendorIfdType,(int)outBufSize);
|
||||
return;
|
||||
case SCARD_ATTR_DEVICE_UNIT:
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_DEVICE_UNIT");
|
||||
setInt(device,pRequest,deviceUnit);
|
||||
return;
|
||||
case SCARD_ATTR_ATR_STRING:
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_ATR_STRING");
|
||||
BYTE ATR[100];
|
||||
DWORD ATRsize;
|
||||
if (!QueryATR(ATR,&ATRsize))
|
||||
{
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(STATUS_NO_MEDIA, 0);
|
||||
return;
|
||||
}
|
||||
setBuffer(device,pRequest,ATR,ATRsize);
|
||||
return;
|
||||
case SCARD_ATTR_CURRENT_PROTOCOL_TYPE:
|
||||
OutputDebugString(L"[VivoKeySmartReader][GATT]SCARD_ATTR_CURRENT_PROTOCOL_TYPE");
|
||||
setInt(device,pRequest,protocol); // T=0 or T=1
|
||||
return;
|
||||
default: {
|
||||
swprintf(log,L"[VivoKeySmartReader][GATT]ERROR_NOT_SUPPORTED:%08X",code);
|
||||
OutputDebugString(log);
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Reader::CheckATR() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Reader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen) {
|
||||
APDU;
|
||||
APDUlen;
|
||||
Resp;
|
||||
Resplen;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Reader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
|
||||
ATR;
|
||||
ATRsize;
|
||||
reset;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Reader::initProtocols() {
|
||||
// ask ATR to determine available protocols
|
||||
BYTE ATR[100];
|
||||
DWORD ATRsize=100;
|
||||
availableProtocol=0;
|
||||
if (QueryATR(ATR,&ATRsize,true))
|
||||
{
|
||||
availableProtocol=0;
|
||||
int iNumHistBytes=0;
|
||||
int iTotHistBytes=0;
|
||||
int y=0;
|
||||
int block=1;
|
||||
bool isHist=false;
|
||||
char let='A';
|
||||
for (unsigned int i=0;i<ATRsize && ! isHist;i++) {
|
||||
if (i==0) {
|
||||
// we are in TS
|
||||
}
|
||||
else if (i==1) {
|
||||
// we are in T0; read number of historical bytes
|
||||
let='A';
|
||||
y=ATR[i] >> 4;
|
||||
iTotHistBytes=ATR[i] & 0xF;
|
||||
}
|
||||
else {
|
||||
while ((y & 1)==0) {
|
||||
let++;
|
||||
y>>=1;
|
||||
if (y==0) {
|
||||
isHist=true;
|
||||
iNumHistBytes=1;
|
||||
i--;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
// we are in T(let)(block)
|
||||
y=y & 0xE;
|
||||
if (let=='D') {
|
||||
// check available protocol(s)
|
||||
protocol=(ATR[i] & 0x0f);
|
||||
availableProtocol|=1 << protocol;
|
||||
// prepare for next block
|
||||
let='A';
|
||||
y=ATR[i] >> 4;
|
||||
block++;
|
||||
}
|
||||
}
|
||||
end:
|
||||
;
|
||||
}
|
||||
//support at least T=0
|
||||
if (availableProtocol==0)
|
||||
availableProtocol=1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD Reader::startServer() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Reader::shutdown() {
|
||||
}
|
||||
108
virtualsmartcard/win32/VivoKeySmartReader/Reader.h
Normal file
108
virtualsmartcard/win32/VivoKeySmartReader/Reader.h
Normal file
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <Winsock2.h>
|
||||
#include <vector>
|
||||
|
||||
class CMyDevice;
|
||||
|
||||
class Reader {
|
||||
public:
|
||||
CMyDevice *device;
|
||||
std::vector< CComPtr<IWDFIoRequest> > waitRemoveIpr;
|
||||
std::vector< CComPtr<IWDFIoRequest> > waitInsertIpr;
|
||||
inbuf;
|
||||
outbuf;
|
||||
|
||||
HANDLE serverThread;
|
||||
|
||||
char vendorName[300];
|
||||
char vendorIfdType[300];
|
||||
int deviceUnit;
|
||||
int powered;
|
||||
int instance;
|
||||
int rpcType;
|
||||
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);
|
||||
void IoSmartCardIsAbsent(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
|
||||
void IoSmartCardPower(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
|
||||
void IoSmartCardSetAttribute(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
|
||||
void IoSmartCardSetProtocol(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
|
||||
void IoSmartCardTransmit(IWDFIoRequest* pRequest,SIZE_T inBufSize,SIZE_T outBufSize);
|
||||
|
||||
bool initProtocols();
|
||||
virtual bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen);
|
||||
virtual bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false);
|
||||
virtual bool CheckATR();
|
||||
virtual DWORD startServer();
|
||||
virtual void shutdown();
|
||||
virtual void init(wchar_t *section);
|
||||
|
||||
};
|
||||
|
||||
class PipeReader : public Reader {
|
||||
public:
|
||||
wchar_t pipeName[300];
|
||||
wchar_t pipeEventName[300];
|
||||
HANDLE pipe;
|
||||
HANDLE eventpipe;
|
||||
|
||||
PipeReader();
|
||||
bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen);
|
||||
bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false);
|
||||
bool CheckATR();
|
||||
DWORD startServer();
|
||||
void shutdown();
|
||||
void init(wchar_t *section);
|
||||
|
||||
CRITICAL_SECTION eventSection;
|
||||
CRITICAL_SECTION dataSection;
|
||||
};
|
||||
|
||||
class TcpIpReader : public Reader {
|
||||
public:
|
||||
static int portBase;
|
||||
int port;
|
||||
int eventPort;
|
||||
SOCKET socket;
|
||||
SOCKET AcceptSocket;
|
||||
SOCKET eventsocket;
|
||||
bool breakSocket;
|
||||
|
||||
TcpIpReader();
|
||||
bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen);
|
||||
bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false);
|
||||
bool CheckATR();
|
||||
DWORD startServer();
|
||||
void shutdown();
|
||||
void init(wchar_t *section);
|
||||
|
||||
CRITICAL_SECTION eventSection;
|
||||
CRITICAL_SECTION dataSection;
|
||||
};
|
||||
|
||||
class VpcdReader : public Reader {
|
||||
public:
|
||||
static int portBase;
|
||||
short port;
|
||||
void *ctx;
|
||||
bool breakSocket;
|
||||
bool cardPresent;
|
||||
|
||||
VpcdReader();
|
||||
~VpcdReader();
|
||||
bool QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen);
|
||||
bool QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset=false);
|
||||
bool CheckATR();
|
||||
DWORD startServer();
|
||||
void shutdown();
|
||||
void init(wchar_t *section);
|
||||
void signalRemoval(void);
|
||||
void signalInsertion(void);
|
||||
|
||||
CRITICAL_SECTION ioSection;
|
||||
};
|
||||
332
virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp
Normal file
332
virtualsmartcard/win32/VivoKeySmartReader/TcpIpReader.cpp
Normal file
@@ -0,0 +1,332 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "reader.h"
|
||||
#include "device.h"
|
||||
#include <winscard.h>
|
||||
#include "memory.h"
|
||||
#include <Sddl.h>
|
||||
#include "sectionLocker.h"
|
||||
|
||||
|
||||
int TcpIpReader::portBase;
|
||||
|
||||
TcpIpReader::TcpIpReader() {
|
||||
rpcType=1;
|
||||
state=SCARD_ABSENT;
|
||||
}
|
||||
void TcpIpReader::init(wchar_t *section) {
|
||||
portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",29500,L"VivoKeySmartReader.ini");
|
||||
|
||||
port=GetPrivateProfileInt(section,L"TCP_PORT",portBase+(instance<<1),L"VivoKeySmartReader.ini");
|
||||
eventPort=GetPrivateProfileInt(section,L"TCP_EVENT_PORT",portBase+1+(instance<<1),L"VivoKeySmartReader.ini");
|
||||
|
||||
InitializeCriticalSection(&eventSection);
|
||||
InitializeCriticalSection(&dataSection);
|
||||
}
|
||||
|
||||
bool TcpIpReader::CheckATR() {
|
||||
if (AcceptSocket==NULL)
|
||||
return false;
|
||||
int read=0;
|
||||
DWORD command=1;
|
||||
if ((read=send(AcceptSocket,(char*)&command,sizeof(DWORD),NULL))<=0) {
|
||||
return false;
|
||||
}
|
||||
DWORD size=0;
|
||||
if ((read=recv(AcceptSocket,(char*)&size,sizeof(DWORD),MSG_WAITALL))<=0) {
|
||||
return false;
|
||||
}
|
||||
if (size==0)
|
||||
return false;
|
||||
BYTE ATR[100];
|
||||
if ((read=recv(AcceptSocket,(char*)ATR,size,MSG_WAITALL))<=0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool TcpIpReader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen) {
|
||||
if (AcceptSocket==NULL)
|
||||
return false;
|
||||
DWORD command=2;
|
||||
DWORD read=0;
|
||||
if ((read=send(AcceptSocket,(char*)&command,sizeof(DWORD),NULL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
DWORD dwAPDUlen=(DWORD)APDUlen;
|
||||
if ((read=send(AcceptSocket,(char*)&dwAPDUlen,sizeof(DWORD),NULL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
if ((read=send(AcceptSocket,(char*)APDU,APDUlen,NULL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
DWORD dwRespLen=0;
|
||||
if ((read=recv(AcceptSocket,(char*)&dwRespLen,sizeof(DWORD),MSG_WAITALL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
if (0 != dwRespLen) {
|
||||
BYTE *p=(BYTE *)realloc(*Resp, dwRespLen);
|
||||
if (p==NULL) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
*Resp=p;
|
||||
}
|
||||
if ((read=recv(AcceptSocket,(char*)*Resp,dwRespLen,MSG_WAITALL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
(*Resplen)=(int)dwRespLen;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcpIpReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
|
||||
if (AcceptSocket==NULL)
|
||||
return false;
|
||||
int read=0;
|
||||
DWORD command=reset ? 0 : 1;
|
||||
if ((read=send(AcceptSocket,(char*)&command,sizeof(DWORD),NULL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
DWORD size=0;
|
||||
if ((read=recv(AcceptSocket,(char*)&size,sizeof(DWORD),MSG_WAITALL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
if (size==0)
|
||||
return false;
|
||||
if ((read=recv(AcceptSocket,(char*)ATR,size,MSG_WAITALL))<=0) {
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
AcceptSocket=NULL;
|
||||
return false;
|
||||
}
|
||||
(*ATRsize)=size;
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD TcpIpReader::startServer() {
|
||||
breakSocket=false;
|
||||
|
||||
wchar_t log[300];
|
||||
while (true) {
|
||||
//__try {
|
||||
fd_set readfds;
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
// Set server socket to set
|
||||
FD_SET(socket, &readfds);
|
||||
|
||||
// Timeout parameter
|
||||
timeval tv = { 0 };
|
||||
tv.tv_sec = 5;
|
||||
|
||||
while(true) {
|
||||
if (breakSocket)
|
||||
return 0;
|
||||
FD_SET(socket, &readfds);
|
||||
int ret = select(0, &readfds, NULL, NULL, &tv);
|
||||
if (ret > 0)
|
||||
break;
|
||||
if (ret<0) {
|
||||
DWORD err=WSAGetLastError();
|
||||
swprintf(log,L"[VivoKeySmartReader]wsa err:%x",err);
|
||||
OutputDebugString(log);
|
||||
if (err==0x2736) {
|
||||
socket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0);
|
||||
sockaddr_in Service;
|
||||
Service.sin_family = AF_INET;
|
||||
Service.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
Service.sin_port = htons((u_short)(port));
|
||||
bind(socket, (SOCKADDR *) &Service, sizeof (Service));
|
||||
listen(socket, 1);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
// Set server socket to set
|
||||
FD_SET(socket, &readfds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SOCKET AcceptEventSocket;
|
||||
|
||||
AcceptSocket = accept(socket, NULL, NULL);
|
||||
closesocket(socket);
|
||||
socket=NULL;
|
||||
if (AcceptSocket == INVALID_SOCKET)
|
||||
return 0;
|
||||
|
||||
swprintf(log,L"[VivoKeySmartReader]Socket connected:%i",AcceptSocket);
|
||||
OutputDebugString(log);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
// Set server socket to set
|
||||
FD_SET(eventsocket, &readfds);
|
||||
|
||||
while(true) {
|
||||
if (breakSocket)
|
||||
return 0;
|
||||
FD_SET(eventsocket, &readfds);
|
||||
int ret = select(0, &readfds, NULL, NULL, &tv);
|
||||
if (ret > 0)
|
||||
break;
|
||||
if (ret<0) {
|
||||
DWORD err=WSAGetLastError();
|
||||
swprintf(log,L"[VivoKeySmartReader]wsa err:%x",err);
|
||||
OutputDebugString(log);
|
||||
if (err==0x2736) {
|
||||
eventsocket=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0);
|
||||
sockaddr_in eventService;
|
||||
eventService.sin_family = AF_INET;
|
||||
eventService.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||
eventService.sin_port = htons((u_short)(eventPort));
|
||||
bind(eventsocket, (SOCKADDR *) &eventService, sizeof (eventService));
|
||||
listen(eventsocket, 1);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
// Set server socket to set
|
||||
FD_SET(eventsocket, &readfds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AcceptEventSocket = accept(eventsocket, NULL, NULL);
|
||||
closesocket(eventsocket);
|
||||
eventsocket=NULL;
|
||||
if (AcceptEventSocket == INVALID_SOCKET)
|
||||
return 0;
|
||||
|
||||
swprintf(log,L"[VivoKeySmartReader]Event Socket connected:%i",AcceptEventSocket);
|
||||
OutputDebugString(log);
|
||||
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// if I'm waiting for card insertion, verify if there's a card present
|
||||
if (initProtocols()) {
|
||||
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;
|
||||
int read=0;
|
||||
if ((read=recv(AcceptEventSocket,(char*)&command,sizeof(DWORD),MSG_WAITALL))<=0) {
|
||||
state=SCARD_ABSENT;
|
||||
OutputDebugString(L"[VivoKeySmartReader]Socket error");
|
||||
powered=0;
|
||||
::shutdown(AcceptSocket,SD_BOTH);
|
||||
::shutdown(AcceptEventSocket,SD_BOTH);
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
OutputDebugString(L"[VivoKeySmartReader]complete Wait Remove");
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Remove Unmarked");
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Remove Completed");
|
||||
}
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
}
|
||||
if (!waitInsertIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
OutputDebugString(L"[VivoKeySmartReader]cancel Wait Remove");
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Insert Unmarked");
|
||||
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
OutputDebugString(L"[VivoKeySmartReader]Wait Insert Cancelled");
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
OutputDebugString(L"[VivoKeySmartReader]Socket data");
|
||||
if (command==0)
|
||||
powered=0;
|
||||
if (command==0 && !waitRemoveIpr.empty()) {
|
||||
// card removed
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_ABSENT;
|
||||
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.empty()) {
|
||||
// card inserted
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
state=SCARD_SWALLOWED;
|
||||
initProtocols();
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
//__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
// wchar_t log[300];
|
||||
// DWORD err=GetExceptionCode();
|
||||
// swprintf(log,L"Exception:%08X",err);
|
||||
// OutputDebugString(log);
|
||||
//}
|
||||
}
|
||||
OutputDebugString(L"[VivoKeySmartReader]Socket quit!!!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TcpIpReader::shutdown() {
|
||||
state=SCARD_ABSENT;
|
||||
breakSocket=true;
|
||||
{
|
||||
closesocket(eventsocket);
|
||||
closesocket(socket);
|
||||
}
|
||||
WaitForSingleObject(serverThread,10000);
|
||||
serverThread=NULL;
|
||||
eventsocket=NULL;
|
||||
socket=NULL;
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
while (!waitInsertIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import "wudfddi.idl";
|
||||
|
||||
[
|
||||
uuid(8B9C88E9-7E63-46c7-832B-D48D0290E4BF),
|
||||
version(1.0),
|
||||
helpstring("VirtualSCReader Driver Type Library")
|
||||
]
|
||||
library VirtualSCReaderDriverLib
|
||||
{
|
||||
importlib("stdole2.tlb");
|
||||
[
|
||||
uuid(A44A2DF4-DCA4-4767-8EC4-86FE611C2EA7),
|
||||
helpstring("VirtualSCReader Class")
|
||||
]
|
||||
coclass VirtualSCReaderDriver
|
||||
{
|
||||
[default] interface IDriverEntry;
|
||||
};
|
||||
};
|
||||
BIN
virtualsmartcard/win32/VivoKeySmartReader/VivoKeySmartReader.inf
Normal file
BIN
virtualsmartcard/win32/VivoKeySmartReader/VivoKeySmartReader.inf
Normal file
Binary file not shown.
@@ -0,0 +1,21 @@
|
||||
[Driver]
|
||||
NumReaders=3
|
||||
|
||||
[Reader0]
|
||||
RPC_TYPE=0
|
||||
VENDOR_NAME=Fabio Ottavi
|
||||
VENDOR_IFD_TYPE=Pipe Reader
|
||||
DECIVE_UNIT=0
|
||||
|
||||
[Reader1]
|
||||
RPC_TYPE=1
|
||||
VENDOR_NAME=Fabio Ottavi
|
||||
VENDOR_IFD_TYPE=TCP/IP Reader
|
||||
DECIVE_UNIT=1
|
||||
|
||||
[Reader2]
|
||||
RPC_TYPE=2
|
||||
VENDOR_NAME=Virtual Smart Card Architecture
|
||||
VENDOR_IFD_TYPE=Virtual PCD
|
||||
TCP_PORT=35963
|
||||
DECIVE_UNIT=2
|
||||
@@ -0,0 +1,98 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Neutral (Default) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEUD)
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
|
||||
#pragma code_page(1252)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 6,0,6000,16384
|
||||
PRODUCTVERSION 6,0,6000,16384
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x9L
|
||||
#else
|
||||
FILEFLAGS 0x8L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040004b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "VivoKey"
|
||||
VALUE "FileDescription", "VivoKey Smart Reader Driver"
|
||||
VALUE "FileVersion", "6.0.6000.16384"
|
||||
VALUE "InternalName", "VivoKeySmartReader"
|
||||
VALUE "LegalCopyright", "Frank Morgner, GPLv3 and VivoKey"
|
||||
VALUE "OriginalFilename", "VivoKeySmartReader.dll"
|
||||
VALUE "ProductName", "VivoKey Smart Reader"
|
||||
VALUE "ProductVersion", "6.0.6000.16384"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x400, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // Neutral (Default) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Italian (Italy) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ITA)
|
||||
LANGUAGE LANG_ITALIAN, SUBLANG_ITALIAN
|
||||
#pragma code_page(1252)
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // Italian (Italy) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Exports.def" />
|
||||
<None Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\vpcd\lock.c" />
|
||||
<ClCompile Include="..\..\src\vpcd\vpcd.c" />
|
||||
<ClCompile Include="Device.cpp" />
|
||||
<ClCompile Include="DllMain.cpp" />
|
||||
<ClCompile Include="Driver.cpp" />
|
||||
<ClCompile Include="memory.cpp" />
|
||||
<ClCompile Include="PipeReader.cpp" />
|
||||
<ClCompile Include="Queue.cpp" />
|
||||
<ClCompile Include="Reader.cpp" />
|
||||
<ClCompile Include="sectionLocker.cpp" />
|
||||
<ClCompile Include="TcpIpReader.cpp" />
|
||||
<ClCompile Include="VpcdReader.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\vpcd\lock.h" />
|
||||
<ClInclude Include="..\..\src\vpcd\vpcd.h" />
|
||||
<ClInclude Include="Device.h" />
|
||||
<ClInclude Include="Driver.h" />
|
||||
<ClInclude Include="Internal.h" />
|
||||
<ClInclude Include="memory.h" />
|
||||
<ClInclude Include="Queue.h" />
|
||||
<ClInclude Include="Reader.h" />
|
||||
<ClInclude Include="Resource.h" />
|
||||
<ClInclude Include="sectionLocker.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="VivoKeySmartReader.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="VivoKeySmartReader.inf" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{1D286E48-DE79-41FF-844B-56ED3764D4DA}</ProjectGuid>
|
||||
<TemplateGuid>{2177f19c-eb4c-4687-9e7f-f9eec1f12cf1}</TemplateGuid>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<MinimumVisualStudioVersion>12.0</MinimumVisualStudioVersion>
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform Condition="'$(Platform)' == ''">Win32</Platform>
|
||||
<RootNamespace>VivoKeySmartReader</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfAtl>Static</UseOfAtl>
|
||||
<UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfAtl>Static</UseOfAtl>
|
||||
<UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfAtl>Static</UseOfAtl>
|
||||
<UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<TargetVersion>Windows10</TargetVersion>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfAtl>Static</UseOfAtl>
|
||||
<UMDF_VERSION_MAJOR>1</UMDF_VERSION_MAJOR>
|
||||
<DriverTargetPlatform>Desktop</DriverTargetPlatform>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WppEnabled>true</WppEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">internal.h</WppScanConfigurationData>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
<CallingConvention>
|
||||
</CallingConvention>
|
||||
<ShowIncludes>true</ShowIncludes>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>.\Exports.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WppEnabled>true</WppEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">internal.h</WppScanConfigurationData>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>.\Exports.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WppEnabled>true</WppEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">internal.h</WppScanConfigurationData>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>.\Exports.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WppEnabled>true</WppEnabled>
|
||||
<WppScanConfigurationData Condition="'%(ClCompile.ScanConfigurationData)' == ''">internal.h</WppScanConfigurationData>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<ModuleDefinitionFile>.\Exports.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>Ws2_32.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<FilesToPackage Include="$(TargetPath)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="VirtualSCReader.idl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Driver Files">
|
||||
<UniqueIdentifier>{8E41214B-6785-4CFE-B992-037D68949A14}</UniqueIdentifier>
|
||||
<Extensions>inf;inv;inx;mof;mc;</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Inf Include="VivoKeySmartReader.inf">
|
||||
<Filter>Driver Files</Filter>
|
||||
</Inf>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Device.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Driver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Internal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="memory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Queue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Reader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="sectionLocker.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\vpcd\lock.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\vpcd\vpcd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Exports.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<ClCompile Include="Device.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Driver.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="VivoKeySmartReader.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DllMain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="memory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PipeReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Queue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Reader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="sectionLocker.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TcpIpReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VpcdReader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\vpcd\lock.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\vpcd\vpcd.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Midl Include="VirtualSCReader.idl">
|
||||
<Filter>Source Files</Filter>
|
||||
</Midl>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
167
virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp
Normal file
167
virtualsmartcard/win32/VivoKeySmartReader/VpcdReader.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "reader.h"
|
||||
#include "device.h"
|
||||
#include <winscard.h>
|
||||
#include "memory.h"
|
||||
#include <Sddl.h>
|
||||
#include "sectionLocker.h"
|
||||
#include "../../src/vpcd/vpcd.h"
|
||||
|
||||
|
||||
int VpcdReader::portBase;
|
||||
|
||||
VpcdReader::VpcdReader() {
|
||||
rpcType=2;
|
||||
state = SCARD_ABSENT;
|
||||
cardPresent = false;
|
||||
InitializeCriticalSection(&ioSection);
|
||||
}
|
||||
|
||||
VpcdReader::~VpcdReader() {
|
||||
DeleteCriticalSection(&ioSection);
|
||||
}
|
||||
void VpcdReader::init(wchar_t *section) {
|
||||
portBase=GetPrivateProfileInt(L"Driver",L"RPC_PORT_BASE",VPCDPORT,L"VivoKeySmartReader.ini");
|
||||
|
||||
port=(short) GetPrivateProfileInt(section,L"TCP_PORT",portBase+instance,L"VivoKeySmartReader.ini");
|
||||
}
|
||||
|
||||
bool VpcdReader::CheckATR() {
|
||||
bool r = false;
|
||||
|
||||
if (vicc_present((struct vicc_ctx *) ctx) == 1) {
|
||||
r = true;
|
||||
}
|
||||
|
||||
|
||||
if (r) {
|
||||
signalInsertion();
|
||||
}
|
||||
else {
|
||||
signalRemoval();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
bool VpcdReader::QueryTransmit(BYTE *APDU,int APDUlen,BYTE **Resp,int *Resplen) {
|
||||
bool r = false;
|
||||
|
||||
if (APDU && APDUlen && Resplen) {
|
||||
ssize_t rapdu_len = vicc_transmit((struct vicc_ctx *) ctx, APDUlen, APDU, Resp);
|
||||
if (rapdu_len > 0) {
|
||||
*Resplen = rapdu_len;
|
||||
r = true;
|
||||
} else {
|
||||
signalRemoval();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool VpcdReader::QueryATR(BYTE *ATR,DWORD *ATRsize,bool reset) {
|
||||
unsigned char *atr = NULL;
|
||||
int atr_len;
|
||||
bool r = false;
|
||||
|
||||
if (ATR && ATRsize) {
|
||||
atr_len = vicc_getatr((struct vicc_ctx *) ctx, &atr);
|
||||
if (atr_len > 0) {
|
||||
/* TODO do length checking on length of ATR when ATRsize is
|
||||
* correctly initialized by Reader.cpp */
|
||||
memcpy(ATR, atr, atr_len);
|
||||
*ATRsize = atr_len;
|
||||
free(atr);
|
||||
r = true;
|
||||
if (reset) {
|
||||
vicc_reset((struct vicc_ctx *) ctx);
|
||||
}
|
||||
} else {
|
||||
signalRemoval();
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
DWORD VpcdReader::startServer() {
|
||||
breakSocket = false;
|
||||
ctx = vicc_init(NULL, port);
|
||||
while (!breakSocket) {
|
||||
CheckATR();
|
||||
Sleep(1000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VpcdReader::shutdown() {
|
||||
breakSocket=true;
|
||||
WaitForSingleObject(serverThread,10000);
|
||||
serverThread = NULL;
|
||||
vicc_exit((struct vicc_ctx *) ctx);
|
||||
state=SCARD_ABSENT;
|
||||
ctx = NULL;
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
}
|
||||
while (!waitInsertIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK)
|
||||
ipr->Complete(HRESULT_FROM_WIN32(ERROR_CANCELLED));
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void VpcdReader::signalRemoval(void) {
|
||||
if (cardPresent) {
|
||||
cardPresent = false;
|
||||
state=SCARD_ABSENT;
|
||||
if (!waitRemoveIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitRemoveIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitRemoveIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
ipr->CompleteWithInformation(STATUS_SUCCESS, 0);
|
||||
}
|
||||
waitRemoveIpr.pop_back();
|
||||
}
|
||||
}
|
||||
if (!waitInsertIpr.empty()) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
while (!waitInsertIpr.empty()) {
|
||||
CComPtr<IWDFIoRequest> ipr = waitInsertIpr.back();
|
||||
if (ipr->UnmarkCancelable()==S_OK) {
|
||||
ipr->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
}
|
||||
waitInsertIpr.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VpcdReader::signalInsertion(void) {
|
||||
if (!cardPresent) {
|
||||
cardPresent = true;
|
||||
while (!waitInsertIpr.empty()) {
|
||||
if (initProtocols()) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
337
virtualsmartcard/win32/VivoKeySmartReader/device.cpp
Normal file
337
virtualsmartcard/win32/VivoKeySmartReader/device.cpp
Normal file
@@ -0,0 +1,337 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "queue.h"
|
||||
#include "device.h"
|
||||
#include "driver.h"
|
||||
#include <stdio.h>
|
||||
#include <winscard.h>
|
||||
#include "memory.h"
|
||||
#include "SectionLocker.h"
|
||||
|
||||
HRESULT
|
||||
CMyDevice::CreateInstance(
|
||||
__in IWDFDriver *FxDriver,
|
||||
__in IWDFDeviceInitialize * FxDeviceInit
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This method creates and initializs an instance of the virtual smart card reader driver's
|
||||
device callback object.
|
||||
|
||||
Arguments:
|
||||
|
||||
FxDeviceInit - the settings for the device.
|
||||
|
||||
Device - a location to store the referenced pointer to the device object.
|
||||
|
||||
Return Value:
|
||||
|
||||
Status
|
||||
|
||||
--*/
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
CComObject<CMyDevice>* device = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
OutputDebugString(L"[VivoKeySmartReader]CreateInstance"); //
|
||||
// Allocate a new instance of the device class.
|
||||
//
|
||||
hr = CComObject<CMyDevice>::CreateInstance(&device);
|
||||
|
||||
if (device==NULL)
|
||||
{
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the instance.
|
||||
//
|
||||
device->AddRef();
|
||||
|
||||
OutputDebugString(L"[VivoKeySmartReader]SetLockingConstraint"); //
|
||||
FxDeviceInit->SetLockingConstraint(WdfDeviceLevel);
|
||||
|
||||
CComPtr<IUnknown> spCallback;
|
||||
OutputDebugString(L"[VivoKeySmartReader]QueryInterface"); //
|
||||
hr = device->QueryInterface(IID_IUnknown, (void**)&spCallback);
|
||||
|
||||
CComPtr<IWDFDevice> spIWDFDevice;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
OutputDebugString(L"[VivoKeySmartReader]CreateDevice"); //
|
||||
hr = FxDriver->CreateDevice(FxDeviceInit, spCallback, &spIWDFDevice);
|
||||
}
|
||||
|
||||
device->numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"VivoKeySmartReader.ini");
|
||||
|
||||
WSADATA wsaData;
|
||||
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if (iResult != NO_ERROR) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Error at WSAStartup()\n");
|
||||
}
|
||||
|
||||
for (int i=0;i<device->numInstances;i++) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]CreateDeviceInterface"); //
|
||||
wchar_t name[10];
|
||||
swprintf(name,L"DEV%i",i);
|
||||
|
||||
if (spIWDFDevice->CreateDeviceInterface(&SmartCardReaderGuid,name)!=0)
|
||||
OutputDebugString(L"[VivoKeySmartReader]CreateDeviceInterface Failed");
|
||||
}
|
||||
|
||||
SAFE_RELEASE(device);
|
||||
return hr;
|
||||
}
|
||||
|
||||
void CMyDevice::ProcessIoControl(__in IWDFIoQueue* pQueue,
|
||||
__in IWDFIoRequest* pRequest,
|
||||
__in ULONG ControlCode,
|
||||
SIZE_T inBufSize,
|
||||
SIZE_T outBufSize)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pQueue);
|
||||
wchar_t log[300];
|
||||
swprintf(log,L"[VivoKeySmartReader][IOCT]IOCTL %08X - In %i Out %i",ControlCode,inBufSize,outBufSize);
|
||||
OutputDebugString(log);
|
||||
|
||||
//SectionLocker lock(m_RequestLock);
|
||||
int instance=0;
|
||||
{
|
||||
CComPtr<IWDFFile> pFileObject;
|
||||
pRequest->GetFileObject(&pFileObject);
|
||||
|
||||
if (pFileObject != NULL)
|
||||
{
|
||||
DWORD logLen=300;
|
||||
pFileObject->RetrieveFileName(log,&logLen);
|
||||
instance=_wtoi(log+(logLen-2));
|
||||
}
|
||||
}
|
||||
Reader &reader=*readers[instance];
|
||||
|
||||
if (ControlCode==IOCTL_SMARTCARD_GET_ATTRIBUTE) {
|
||||
reader.IoSmartCardGetAttribute(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_IS_PRESENT) {
|
||||
reader.IoSmartCardIsPresent(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_GET_STATE) {
|
||||
reader.IoSmartCardGetState(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_IS_ABSENT) {
|
||||
reader.IoSmartCardIsAbsent(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_SET_PROTOCOL) {
|
||||
reader.IoSmartCardSetProtocol(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
else if (ControlCode==IOCTL_SMARTCARD_TRANSMIT) {
|
||||
reader.IoSmartCardTransmit(pRequest,inBufSize,outBufSize);
|
||||
return;
|
||||
}
|
||||
swprintf(log,L"[VivoKeySmartReader][IOCT]ERROR_NOT_SUPPORTED:%08X",ControlCode);
|
||||
OutputDebugString(log);
|
||||
pRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED), 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI ServerFunc(Reader *reader) {
|
||||
return reader->startServer();
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyDevice::OnPrepareHardware
|
||||
//
|
||||
// Called by UMDF to prepare the hardware for use.
|
||||
//
|
||||
// Parameters:
|
||||
// pWdfDevice - pointer to an IWDFDevice object representing the
|
||||
// device
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: success
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
HRESULT CMyDevice::OnPrepareHardware(
|
||||
__in IWDFDevice* pWdfDevice
|
||||
)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
// Store the IWDFDevice pointer
|
||||
m_pWdfDevice = pWdfDevice;
|
||||
|
||||
// Configure the default IO Queue
|
||||
HRESULT hr = CMyQueue::CreateInstance(m_pWdfDevice, this);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyDevice::OnReleaseHardware
|
||||
//
|
||||
// Called by WUDF to uninitialize the hardware.
|
||||
//
|
||||
// Parameters:
|
||||
// pWdfDevice - pointer to an IWDFDevice object for the device
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK:
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CMyDevice::OnReleaseHardware(
|
||||
__in IWDFDevice* pWdfDevice
|
||||
)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
|
||||
// Release the IWDFDevice handle, if it matches
|
||||
if (pWdfDevice == m_pWdfDevice.p)
|
||||
{
|
||||
m_pWdfDevice.Release();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT CMyDevice::OnD0Entry(IN IWDFDevice* pWdfDevice,IN WDF_POWER_DEVICE_STATE previousState) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
UNREFERENCED_PARAMETER(previousState);
|
||||
|
||||
numInstances=GetPrivateProfileInt(L"Driver",L"NumReaders",1,L"VivoKeySmartReader.ini");
|
||||
readers.resize(numInstances);
|
||||
|
||||
for (int i=0;i<numInstances;i++) {
|
||||
wchar_t section[300];
|
||||
char sectionA[300];
|
||||
swprintf(section,L"Reader%i",i);
|
||||
sprintf(sectionA,"Reader%i",i);
|
||||
|
||||
int rpcType=GetPrivateProfileInt(section,L"RPC_TYPE",0,L"VivoKeySmartReader.ini");
|
||||
if (rpcType==0)
|
||||
readers[i]=new PipeReader();
|
||||
else if (rpcType==1)
|
||||
readers[i]=new TcpIpReader();
|
||||
else if (rpcType==2)
|
||||
readers[i]=new VpcdReader();
|
||||
|
||||
readers[i]->instance=i;
|
||||
readers[i]->device=this;
|
||||
GetPrivateProfileStringA(sectionA,"VENDOR_NAME","VivoKey",readers[i]->vendorName,sizeof readers[i]->vendorName,"VivoKeySmartReader.ini");
|
||||
GetPrivateProfileStringA(sectionA,"VENDOR_IFD_TYPE","VIRTUAL_CARD_READER",readers[i]->vendorIfdType,sizeof readers[i]->vendorIfdType,"VivoKeySmartReader.ini");
|
||||
readers[i]->deviceUnit=GetPrivateProfileInt(section,L"DEVICE_UNIT",i,L"VivoKeySmartReader.ini");
|
||||
readers[i]->protocol=0;
|
||||
|
||||
readers[i]->init(section);
|
||||
|
||||
DWORD pipeThreadID;
|
||||
readers[i]->serverThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ServerFunc,readers[i],0,&pipeThreadID);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CMyDevice::OnD0Exit(IN IWDFDevice* pWdfDevice,IN WDF_POWER_DEVICE_STATE newState) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
UNREFERENCED_PARAMETER(newState);
|
||||
// dovrei fermare tutti i thread in ascolto dei lettori
|
||||
shutDown();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void CMyDevice::shutDown() {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
for (int i=0;i<numInstances;i++) {
|
||||
readers[i]->shutdown();
|
||||
delete readers[i];
|
||||
}
|
||||
numInstances=0;
|
||||
}
|
||||
HRESULT CMyDevice::OnQueryRemove(IN IWDFDevice* pWdfDevice) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
OutputDebugString(L"[VivoKeySmartReader]OnQueryRemove");
|
||||
shutDown();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT CMyDevice::OnQueryStop(IN IWDFDevice* pWdfDevice) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
OutputDebugString(L"[VivoKeySmartReader]OnQueryStop");
|
||||
shutDown();
|
||||
return S_OK;
|
||||
}
|
||||
void CMyDevice::OnSurpriseRemoval(IN IWDFDevice* pWdfDevice) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pWdfDevice);
|
||||
OutputDebugString(L"[VivoKeySmartReader]OnSurpriseRemoval");
|
||||
shutDown();
|
||||
}
|
||||
|
||||
STDMETHODIMP_ (void) CMyDevice::OnCancel(IN IWDFIoRequest* pWdfRequest) {
|
||||
SectionLogger a(__FUNCTION__);
|
||||
|
||||
wchar_t log[300];
|
||||
SectionLocker lock(m_RequestLock);
|
||||
|
||||
int instance=0;
|
||||
{
|
||||
CComPtr<IWDFFile> pFileObject;
|
||||
pWdfRequest->GetFileObject(&pFileObject);
|
||||
|
||||
if (pFileObject != NULL)
|
||||
{
|
||||
DWORD logLen=300;
|
||||
pFileObject->RetrieveFileName(log,&logLen);
|
||||
instance=_wtoi(log+(logLen-2));
|
||||
}
|
||||
}
|
||||
Reader &reader=*readers[instance];
|
||||
|
||||
for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitRemoveIpr.begin();
|
||||
it != reader.waitRemoveIpr.end(); it++) {
|
||||
if (pWdfRequest == *it) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Cancel Remove");
|
||||
reader.waitRemoveIpr.erase(it);
|
||||
}
|
||||
}
|
||||
for (std::vector< CComPtr<IWDFIoRequest> >::iterator it = reader.waitInsertIpr.begin();
|
||||
it != reader.waitInsertIpr.end(); it++) {
|
||||
if (pWdfRequest == *it) {
|
||||
OutputDebugString(L"[VivoKeySmartReader]Cancel Insert");
|
||||
reader.waitInsertIpr.erase(it);
|
||||
}
|
||||
}
|
||||
pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_CANCELLED), 0);
|
||||
}
|
||||
|
||||
98
virtualsmartcard/win32/VivoKeySmartReader/device.h
Normal file
98
virtualsmartcard/win32/VivoKeySmartReader/device.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "reader.h"
|
||||
|
||||
//
|
||||
// Class for the iotrace driver.
|
||||
//
|
||||
class CMyDevice;
|
||||
|
||||
|
||||
class ATL_NO_VTABLE CMyDevice :
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public IPnpCallbackHardware,
|
||||
public IPnpCallback,
|
||||
public IRequestCallbackCancel
|
||||
{
|
||||
public:
|
||||
~CMyDevice() {
|
||||
DeleteCriticalSection(&m_RequestLock);
|
||||
}
|
||||
|
||||
DECLARE_NOT_AGGREGATABLE(CMyDevice)
|
||||
|
||||
BEGIN_COM_MAP(CMyDevice)
|
||||
COM_INTERFACE_ENTRY(IPnpCallbackHardware)
|
||||
COM_INTERFACE_ENTRY(IPnpCallback)
|
||||
COM_INTERFACE_ENTRY(IRequestCallbackCancel)
|
||||
END_COM_MAP()
|
||||
|
||||
CMyDevice(VOID)
|
||||
{
|
||||
InitializeCriticalSection(&m_RequestLock);
|
||||
m_pWdfDevice = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Private data members.
|
||||
//
|
||||
private:
|
||||
|
||||
CComPtr<IWDFDevice> m_pWdfDevice;
|
||||
std::vector<Reader*> readers;
|
||||
int numInstances;
|
||||
|
||||
//
|
||||
// Private methods.
|
||||
//
|
||||
|
||||
private:
|
||||
|
||||
|
||||
HRESULT ConfigureQueue();
|
||||
|
||||
//
|
||||
// Public methods
|
||||
//
|
||||
public:
|
||||
|
||||
CRITICAL_SECTION m_RequestLock;
|
||||
|
||||
//
|
||||
// The factory method used to create an instance of this driver.
|
||||
//
|
||||
|
||||
static
|
||||
HRESULT CreateInstance(
|
||||
__in IWDFDriver *FxDriver,
|
||||
__in IWDFDeviceInitialize *FxDeviceInit
|
||||
);
|
||||
|
||||
//
|
||||
// COM methods
|
||||
//
|
||||
public:
|
||||
|
||||
//
|
||||
// IUnknown methods.
|
||||
//
|
||||
|
||||
void ProcessIoControl(__in IWDFIoQueue* pQueue,
|
||||
__in IWDFIoRequest* pRequest,
|
||||
__in ULONG ControlCode,
|
||||
SIZE_T InputBufferSizeInBytes,
|
||||
SIZE_T OutputBufferSizeInBytes);
|
||||
|
||||
STDMETHOD_ (HRESULT, OnPrepareHardware)(__in IWDFDevice* pWdfDevice);
|
||||
STDMETHOD_ (HRESULT, OnReleaseHardware)(__in IWDFDevice* pWdfDevice);
|
||||
STDMETHOD_ (HRESULT, OnD0Entry)(IN IWDFDevice* pWdfDevice,IN WDF_POWER_DEVICE_STATE previousState);
|
||||
STDMETHOD_ (HRESULT, OnD0Exit )(IN IWDFDevice* pWdfDevice,IN WDF_POWER_DEVICE_STATE newState);
|
||||
STDMETHOD_ (HRESULT, OnQueryRemove )(IN IWDFDevice* pWdfDevice);
|
||||
STDMETHOD_ (HRESULT, OnQueryStop)(IN IWDFDevice* pWdfDevice);
|
||||
STDMETHOD_ (void, OnSurpriseRemoval)(IN IWDFDevice* pWdfDevice);
|
||||
STDMETHOD_ (void, OnCancel)(IN IWDFIoRequest* pWdfRequest);
|
||||
|
||||
void shutDown();
|
||||
};
|
||||
|
||||
75
virtualsmartcard/win32/VivoKeySmartReader/driver.cpp
Normal file
75
virtualsmartcard/win32/VivoKeySmartReader/driver.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
#include "internal.h"
|
||||
#include "VirtualSCReader.h"
|
||||
#include "driver.h"
|
||||
#include "device.h"
|
||||
#include <stdio.h>
|
||||
#include "SectionLocker.h"
|
||||
|
||||
CMyDriver::CMyDriver()
|
||||
{
|
||||
inFunc
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyDriver::OnDeviceAdd
|
||||
//
|
||||
// The framework call this function when device is detected. This driver
|
||||
// creates a device callback object
|
||||
//
|
||||
// Parameters:
|
||||
// pDriver - pointer to an IWDFDriver object
|
||||
// pDeviceInit - pointer to a device initialization object
|
||||
//
|
||||
// Return Values:
|
||||
// S_OK: device initialized successfully
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CMyDriver::OnDeviceAdd(
|
||||
__in IWDFDriver* pDriver,
|
||||
__in IWDFDeviceInitialize* pDeviceInit
|
||||
)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
HRESULT hr = CMyDevice::CreateInstance(pDriver, pDeviceInit);
|
||||
|
||||
return hr;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyDriver::OnInitialize
|
||||
//
|
||||
// The framework calls this function just after loading the driver. The driver
|
||||
// can perform any global, device independent intialization in this routine.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
HRESULT CMyDriver::OnInitialize(
|
||||
__in IWDFDriver* pDriver
|
||||
)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pDriver);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CMyDriver::OnDeinitialize
|
||||
//
|
||||
// The framework calls this function just before de-initializing itself. All
|
||||
// WDF framework resources should be released by driver before returning
|
||||
// from this call.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
void CMyDriver::OnDeinitialize(
|
||||
__in IWDFDriver* pDriver
|
||||
)
|
||||
{
|
||||
inFunc
|
||||
SectionLogger a(__FUNCTION__);
|
||||
UNREFERENCED_PARAMETER(pDriver);
|
||||
return;
|
||||
}
|
||||
|
||||
37
virtualsmartcard/win32/VivoKeySmartReader/driver.h
Normal file
37
virtualsmartcard/win32/VivoKeySmartReader/driver.h
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// This class handles driver events for the skeleton sample. In particular
|
||||
// it supports the OnDeviceAdd event, which occurs when the driver is called
|
||||
// to setup per-device handlers for a new device stack.
|
||||
//
|
||||
|
||||
class ATL_NO_VTABLE CMyDriver :
|
||||
public CComObjectRootEx<CComMultiThreadModel>,
|
||||
public CComCoClass<CMyDriver, &CLSID_VirtualSCReaderDriver>,
|
||||
public IDriverEntry
|
||||
{
|
||||
public:
|
||||
CMyDriver();
|
||||
|
||||
DECLARE_NO_REGISTRY()
|
||||
DECLARE_CLASSFACTORY()
|
||||
DECLARE_NOT_AGGREGATABLE(CMyDriver)
|
||||
|
||||
BEGIN_COM_MAP(CMyDriver)
|
||||
COM_INTERFACE_ENTRY(IDriverEntry)
|
||||
END_COM_MAP()
|
||||
|
||||
public:
|
||||
//
|
||||
// IDriverEntry
|
||||
//
|
||||
STDMETHOD (OnInitialize)(__in IWDFDriver* pDriver);
|
||||
STDMETHOD (OnDeviceAdd)(__in IWDFDriver* pDriver, __in IWDFDeviceInitialize* pDeviceInit);
|
||||
STDMETHOD_ (void, OnDeinitialize)(__in IWDFDriver* pDriver);
|
||||
};
|
||||
|
||||
OBJECT_ENTRY_AUTO(__uuidof(VirtualSCReaderDriver), CMyDriver)
|
||||
|
||||
15
virtualsmartcard/win32/VivoKeySmartReader/exports.def
Normal file
15
virtualsmartcard/win32/VivoKeySmartReader/exports.def
Normal file
@@ -0,0 +1,15 @@
|
||||
; Skeleton.def : Declares the module parameters.
|
||||
|
||||
;
|
||||
; TODO: Change the library name here to match your binary name.
|
||||
;
|
||||
|
||||
LIBRARY "UMDFSkeleton.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow PRIVATE
|
||||
DllGetClassObject PRIVATE
|
||||
DllRegisterServer PRIVATE
|
||||
DllUnregisterServer PRIVATE
|
||||
|
||||
|
||||
75
virtualsmartcard/win32/VivoKeySmartReader/internal.h
Normal file
75
virtualsmartcard/win32/VivoKeySmartReader/internal.h
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
#include <atlbase.h>
|
||||
#include <atlcom.h>
|
||||
#include <atlstr.h>
|
||||
|
||||
//__user_driver; // Macro letting the compiler know this is not a kernel driver (this will help surpress needless warnings)
|
||||
|
||||
// Common WPD and WUDF headers
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }}
|
||||
#endif
|
||||
|
||||
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
|
||||
#define STATUS_NO_MEDIA ((NTSTATUS)0xC0000178L)
|
||||
#define STATUS_INVALID_DEVICE_STATE ((NTSTATUS)0xC0000184L)
|
||||
|
||||
|
||||
//
|
||||
// Include the WUDF DDI
|
||||
//
|
||||
#include <devioctl.h>
|
||||
#include <initguid.h>
|
||||
#include <propkeydef.h>
|
||||
#include <propvarutil.h>
|
||||
#include "PortableDeviceTypes.h"
|
||||
#include "PortableDeviceClassExtension.h"
|
||||
#include "PortableDevice.h"
|
||||
|
||||
#include "wudfddi.h"
|
||||
|
||||
//
|
||||
// Use specstrings for in/out annotation of function parameters.
|
||||
//
|
||||
|
||||
#include "specstrings.h"
|
||||
|
||||
//
|
||||
// Forward definitions of classes in the other header files.
|
||||
//
|
||||
|
||||
typedef class CMyDriver *PCMyDriver;
|
||||
typedef class CMyDevice *PCMyDevice;
|
||||
|
||||
//
|
||||
DEFINE_GUID(SmartCardReaderGuid, 0x50DD5230, 0xBA8A, 0x11D1, 0xBF,0x5D,0x00,0x00,0xF8,0x05,0xF5,0x30);
|
||||
//
|
||||
// Include the type specific headers.
|
||||
//
|
||||
|
||||
//class funcTrace {
|
||||
//public:
|
||||
// TCHAR funcN[500];
|
||||
// funcTrace (char *func) {
|
||||
// TCHAR funcName[500];
|
||||
// wsprintf(funcN, _T("%S"), func);
|
||||
// wsprintf(funcName, _T("[VivoKeySmartReader]IN -> %s"), funcN);
|
||||
// OutputDebugString(funcName);
|
||||
// }
|
||||
// ~funcTrace () {
|
||||
// TCHAR funcName[500];
|
||||
// wsprintf(funcName, _T("[VivoKeySmartReader]OUT -> %s"), funcN);
|
||||
// OutputDebugString(funcName);
|
||||
// }
|
||||
//};
|
||||
|
||||
//#define inFunc funcTrace _ftrace(__FUNCTION__);
|
||||
#define inFunc
|
||||
91
virtualsmartcard/win32/VivoKeySmartReader/memory.cpp
Normal file
91
virtualsmartcard/win32/VivoKeySmartReader/memory.cpp
Normal file
@@ -0,0 +1,91 @@
|
||||
#include "memory.h"
|
||||
#include "SectionLocker.h"
|
||||
|
||||
bool getBuffer(IWDFIoRequest* pRequest,void **buffer,int *bufferLen) {
|
||||
IWDFMemory *inmem=NULL;
|
||||
pRequest->GetInputMemory(&inmem);
|
||||
if (inmem==NULL) {
|
||||
OutputDebugString(L"GetInputMemory failed");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
SIZE_T size;
|
||||
void *data=inmem->GetDataBuffer(&size);
|
||||
if (0 != size) {
|
||||
void *out = realloc(*buffer, size);
|
||||
if (out==NULL) {
|
||||
OutputDebugString(L"realloc failed");
|
||||
return false;
|
||||
}
|
||||
memcpy(out,data,size);
|
||||
(*buffer)=out;
|
||||
}
|
||||
(*bufferLen)=(int)size;
|
||||
inmem->Release();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,int inSize) {
|
||||
IWDFMemory *outmem=NULL;
|
||||
pRequest->GetOutputMemory (&outmem);
|
||||
if (outmem==NULL) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"GetOutputMemory failed");
|
||||
pRequest->Complete(HRESULT_FROM_WIN32(ERROR_GEN_FAILURE));
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
outmem->CopyFromBuffer(0,result,inSize);
|
||||
outmem->Release();
|
||||
pRequest->CompleteWithInformation(0,(SIZE_T)inSize);
|
||||
}
|
||||
}
|
||||
|
||||
void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,int outSize) {
|
||||
IWDFMemory *outmem=NULL;
|
||||
pRequest->GetOutputMemory (&outmem);
|
||||
if (outmem==NULL) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"GetOutputMemory failed");
|
||||
pRequest->Complete(HRESULT_FROM_WIN32(ERROR_GEN_FAILURE));
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
int size=min(outSize,(int)strlen(result)+1);
|
||||
outmem->CopyFromBuffer(0,result,size);
|
||||
outmem->Release();
|
||||
pRequest->CompleteWithInformation(0,(SIZE_T)size);
|
||||
}
|
||||
}
|
||||
void setInt(CMyDevice *device,IWDFIoRequest* pRequest,DWORD result) {
|
||||
IWDFMemory *outmem=NULL;
|
||||
pRequest->GetOutputMemory (&outmem);
|
||||
if (outmem==NULL) {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
OutputDebugString(L"GetOutputMemory failed");
|
||||
pRequest->Complete(HRESULT_FROM_WIN32(ERROR_GEN_FAILURE));
|
||||
}
|
||||
else {
|
||||
SectionLocker lock(device->m_RequestLock);
|
||||
outmem->CopyFromBuffer(0,&result,sizeof(result));
|
||||
outmem->Release();
|
||||
pRequest->CompleteWithInformation(0,sizeof(result));
|
||||
}
|
||||
}
|
||||
DWORD getInt(IWDFIoRequest* pRequest) {
|
||||
|
||||
IWDFMemory *inmem=NULL;
|
||||
pRequest->GetInputMemory(&inmem);
|
||||
if (inmem==NULL) {
|
||||
OutputDebugString(L"GetInputMemory failed");
|
||||
return 0xffffffff;
|
||||
}
|
||||
else {
|
||||
SIZE_T size;
|
||||
void *data=inmem->GetDataBuffer(&size);
|
||||
DWORD d=*(DWORD *)data;
|
||||
inmem->Release();
|
||||
return d;
|
||||
}
|
||||
}
|
||||
10
virtualsmartcard/win32/VivoKeySmartReader/memory.h
Normal file
10
virtualsmartcard/win32/VivoKeySmartReader/memory.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "internal.h"
|
||||
#include "device.h"
|
||||
|
||||
|
||||
bool getBuffer(IWDFIoRequest* pRequest,void **buffer,int *bufferLen);
|
||||
void setString(CMyDevice *device,IWDFIoRequest* pRequest,char *result,int outSize);
|
||||
void setBuffer(CMyDevice *device,IWDFIoRequest* pRequest,void *result,int inSize);
|
||||
void setInt(CMyDevice *device,IWDFIoRequest* pRequest,DWORD result);
|
||||
DWORD getInt(IWDFIoRequest* pRequest);
|
||||
1496
virtualsmartcard/win32/VivoKeySmartReader/resource.h
Normal file
1496
virtualsmartcard/win32/VivoKeySmartReader/resource.h
Normal file
File diff suppressed because it is too large
Load Diff
46
virtualsmartcard/win32/VivoKeySmartReader/sectionLocker.cpp
Normal file
46
virtualsmartcard/win32/VivoKeySmartReader/sectionLocker.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "sectionLocker.h"
|
||||
void *ShowMe=NULL;
|
||||
SectionLocker::SectionLocker(CRITICAL_SECTION &critsection,char *function,int line,void* object) {
|
||||
critsection;
|
||||
this->section=&critsection;
|
||||
Function=function;
|
||||
Line=line;
|
||||
Object=object;
|
||||
DWORD start=GetTickCount();
|
||||
if (TryEnterCriticalSection(section)==0) {
|
||||
char logBuffer[500];
|
||||
sprintf(logBuffer,"[VivoKeySmartReader]Locking:Function:%s,Line:%i,Object:%p,Lock:%p",Function,Line,Object,section);
|
||||
OutputDebugStringA(logBuffer);
|
||||
ShowMe=section;
|
||||
EnterCriticalSection(section);
|
||||
DWORD end=GetTickCount();
|
||||
sprintf(logBuffer,"[VivoKeySmartReader]Elapsed:%i ms",end-start);
|
||||
OutputDebugStringA(logBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
SectionLocker::~SectionLocker() {
|
||||
if (section==ShowMe) {
|
||||
char logBuffer[500];
|
||||
sprintf(logBuffer,"[VivoKeySmartReader]Unlocking:Function:%s,Line:%i,Object:%p,Lock:%p",Function,Line,Object,section);
|
||||
OutputDebugStringA(logBuffer);
|
||||
ShowMe=NULL;
|
||||
}
|
||||
LeaveCriticalSection(section);
|
||||
}
|
||||
|
||||
SectionLogger::SectionLogger(char *section) {
|
||||
section;
|
||||
start=GetTickCount();
|
||||
char logBuffer[500];
|
||||
SectionName=section;
|
||||
sprintf(logBuffer,"[VivoKeySmartReader]Start section:%s",SectionName);
|
||||
OutputDebugStringA(logBuffer);
|
||||
}
|
||||
SectionLogger::~SectionLogger() {
|
||||
DWORD end=GetTickCount();
|
||||
char logBuffer[500];
|
||||
sprintf(logBuffer,"[VivoKeySmartReader]End section:%s elapsed:%i",SectionName,end-start);
|
||||
OutputDebugStringA(logBuffer);
|
||||
}
|
||||
|
||||
24
virtualsmartcard/win32/VivoKeySmartReader/sectionLocker.h
Normal file
24
virtualsmartcard/win32/VivoKeySmartReader/sectionLocker.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "internal.h"
|
||||
|
||||
class SectionLocker {
|
||||
char *Function;
|
||||
int Line;
|
||||
void *Object;
|
||||
public:
|
||||
CRITICAL_SECTION *section;
|
||||
|
||||
SectionLocker(CRITICAL_SECTION &critsection,char *function,int line,void* object);
|
||||
//SectionLocker(CRITICAL_SECTION §ion);
|
||||
~SectionLocker();
|
||||
};
|
||||
|
||||
class SectionLogger {
|
||||
DWORD start;
|
||||
char *SectionName;
|
||||
public:
|
||||
SectionLogger(char *section);
|
||||
~SectionLogger();
|
||||
};
|
||||
|
||||
#define lock(x) lockObj(x,__FUNCTION__,__LINE__,NULL)
|
||||
Reference in New Issue
Block a user