#include "internal.h" #include "VirtualSCReader.h" #include "queue.h" #include "device.h" #include "driver.h" #include #include #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* device = NULL; HRESULT hr; OutputDebugString(L"[VivoKeySmartReader]CreateInstance"); // // Allocate a new instance of the device class. // hr = CComObject::CreateInstance(&device); if (device==NULL) { return E_OUTOFMEMORY; } // // Initialize the instance. // device->AddRef(); OutputDebugString(L"[VivoKeySmartReader]SetLockingConstraint"); // FxDeviceInit->SetLockingConstraint(WdfDeviceLevel); CComPtr spCallback; OutputDebugString(L"[VivoKeySmartReader]QueryInterface"); // hr = device->QueryInterface(IID_IUnknown, (void**)&spCallback); CComPtr 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;inumInstances;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 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;iinstance=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;ishutdown(); 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 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 >::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 >::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); }