Files
vsmartcard/virtualsmartcard/win32/VivoKeySmartReader/device.cpp
2024-05-21 07:31:18 -07:00

338 lines
11 KiB
C++

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