/***************************************************************************** @doc INT EXT ****************************************************************************** * $ProjectName: $ * $ProjectRevision: $ *----------------------------------------------------------------------------- * $Source: z:/pr/cmeu0/sw/sccmusbm.ms/rcs/scusbsyn.c $ * $Revision: 1.3 $ *----------------------------------------------------------------------------- * $Author: TBruendl $ *----------------------------------------------------------------------------- * History: see EOF *----------------------------------------------------------------------------- * * Copyright Đ 2000 OMNIKEY AG ******************************************************************************/ #include "wdm.h" #include "stdarg.h" #include "stdio.h" #include "usbdi.h" #include "usbdlib.h" #include "sccmusbm.h" /***************************************************************************** Routine Description: Powers a synchronous card and reads the ATR Arguments: Return Value: *****************************************************************************/ NTSTATUS CMUSB_PowerOnSynchronousCard ( IN PSMARTCARD_EXTENSION smartcardExtension, IN PUCHAR pbATR, OUT PULONG pulATRLength ) { PDEVICE_OBJECT deviceObject; NTSTATUS status = STATUS_SUCCESS; NTSTATUS DebugStatus; UCHAR abMaxAtrBuffer[SCARD_ATR_LENGTH]; UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE]; UCHAR bResetMode; SmartcardDebug(DEBUG_TRACE, ("%s!PowerOnSynchronousCard: Enter\n",DRIVER_NAME)); deviceObject = smartcardExtension->OsData->DeviceObject; // in case of warm reset we have to power off the card first if (smartcardExtension->MinorIoControlCode != SCARD_COLD_RESET) { status = CMUSB_PowerOffCard (smartcardExtension ); if (status != STATUS_SUCCESS) { // if we can't turn off power there must be a serious error goto ExitPowerOnSynchronousCard; } } // set card parameters smartcardExtension->ReaderExtension->CardParameters.bBaudRate = 0; smartcardExtension->ReaderExtension->CardParameters.bCardType = CMUSB_SMARTCARD_SYNCHRONOUS; smartcardExtension->ReaderExtension->CardParameters.bStopBits = 0; status = CMUSB_SetCardParameters (deviceObject, smartcardExtension->ReaderExtension->CardParameters.bCardType, smartcardExtension->ReaderExtension->CardParameters.bBaudRate, smartcardExtension->ReaderExtension->CardParameters.bStopBits); if (status != STATUS_SUCCESS) { // if we can't set the card parameters there must be a serious error goto ExitPowerOnSynchronousCard; } RtlFillMemory((PVOID)abMaxAtrBuffer, sizeof(abMaxAtrBuffer), 0x00); // resync CardManUSB by reading the status byte // still necessary with synchronous cards ??? smartcardExtension->SmartcardRequest.BufferLength = 0; status = CMUSB_WriteP0(deviceObject, 0x20, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitPowerOnSynchronousCard; } smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1; status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitPowerOnSynchronousCard; } else if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitPowerOnSynchronousCard; } // check if card is really inserted if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00) { status = STATUS_NO_MEDIA; goto ExitPowerOnSynchronousCard; } // issue power on command // according to WZ nothing is sent back smartcardExtension->SmartcardRequest.BufferLength = 0; status = CMUSB_WriteP0(deviceObject, 0x10, //bRequest, SMARTCARD_COLD_RESET, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't issue the power on command there must be a serious error goto ExitPowerOnSynchronousCard; } // build control code for ATR abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 1,0,0,0); abSendBuffer[1]=CMUSB_CalcSynchControl(1,1,0,0, 1,0,0,0); abSendBuffer[2]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0); // fill memory so that we can discard first byte RtlFillMemory((PVOID)&abSendBuffer[3],5,abSendBuffer[2]); // now get 4 bytes ATR -> 32 bytes to send abSendBuffer[8]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0); RtlFillMemory((PVOID)&abSendBuffer[9],31,abSendBuffer[8]); //now set clock to low to finish operation //and of course additional fill bytes abSendBuffer[40]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0); RtlFillMemory((PVOID)&abSendBuffer[41],7,abSendBuffer[40]); // now send command type 08 to CardManUSB smartcardExtension->SmartcardRequest.BufferLength = 48; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write ATR command there must be a serious error if (status == STATUS_DEVICE_DATA_ERROR) { //error mapping necessary because there are CardManUSB //which have no support for synchronous cards status = STATUS_UNRECOGNIZED_MEDIA; } goto ExitPowerOnSynchronousCard; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitPowerOnSynchronousCard; } else if (status != STATUS_SUCCESS) { // if we can't read the ATR -> there must be a serious error goto ExitPowerOnSynchronousCard; } if (smartcardExtension->SmartcardReply.BufferLength!=6) { // 48 bytes sent but not 6 bytes received // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitPowerOnSynchronousCard; } // now bytes 1-4 in SmartcardReply.Buffer should be ATR SmartcardDebug(DEBUG_ATR, ("%s!ATR = %02x %02x %02x %02x\n",DRIVER_NAME, smartcardExtension->SmartcardReply.Buffer[1], smartcardExtension->SmartcardReply.Buffer[2], smartcardExtension->SmartcardReply.Buffer[3], smartcardExtension->SmartcardReply.Buffer[4])); // check if ATR != 0xFF -> synchronous card if (smartcardExtension->SmartcardReply.Buffer[1]==0xFF && smartcardExtension->SmartcardReply.Buffer[2]==0xFF && smartcardExtension->SmartcardReply.Buffer[3]==0xFF && smartcardExtension->SmartcardReply.Buffer[4]==0xFF ) { status = STATUS_UNRECOGNIZED_MEDIA; *pulATRLength = 0; goto ExitPowerOnSynchronousCard; } //it seems we have a synchronous smart card and a valid ATR //letīs set the variables smartcardExtension->ReaderExtension->fRawModeNecessary = TRUE; *pulATRLength = 4; RtlCopyBytes((PVOID) pbATR, (PVOID) &(smartcardExtension->SmartcardReply.Buffer[1]), *pulATRLength ); ExitPowerOnSynchronousCard: if (status!=STATUS_SUCCESS) { // turn off VCC again CMUSB_PowerOffCard (smartcardExtension ); // ignor status } SmartcardDebug(DEBUG_TRACE, ("%s!PowerOnSynchronousCard: Exit %lx\n",DRIVER_NAME,status)); return status; } /***************************************************************************** Routine Description: Data transfer to synchronous cards SLE 4442/4432 Arguments: Return Value: *****************************************************************************/ NTSTATUS CMUSB_Transmit2WBP ( IN PSMARTCARD_EXTENSION smartcardExtension ) { PDEVICE_OBJECT deviceObject; NTSTATUS status = STATUS_SUCCESS; NTSTATUS DebugStatus; PCHAR pbInData; ULONG ulBytesToRead; ULONG ulBitsToRead; ULONG ulBytesToReadThisStep; ULONG ulBytesRead; UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE]; int i; SmartcardDebug(DEBUG_TRACE, ("%s!Transmit2WBP: Enter\n",DRIVER_NAME)); deviceObject = smartcardExtension->OsData->DeviceObject; // resync CardManUSB by reading the status byte // still necessary with synchronous cards ??? smartcardExtension->SmartcardRequest.BufferLength = 0; status = CMUSB_WriteP0(deviceObject, 0x20, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitTransmit2WBP; } smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1; status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit2WBP; } else if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitTransmit2WBP; } // check if card is really inserted if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00) { // it is not sure, which error messages are accepted // status = STATUS_NO_MEDIA_IN_DEVICE; status = STATUS_UNRECOGNIZED_MEDIA; goto ExitTransmit2WBP; } pbInData = smartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER); ulBitsToRead = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead; ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0); // ulBitsToWrite = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite; // ulBytesToWrite = ulBitsToWrite/8; if (smartcardExtension->IoRequest.ReplyBufferLength < ulBytesToRead) { status = STATUS_BUFFER_OVERFLOW; goto ExitTransmit2WBP; } // send command status=CMUSB_SendCommand2WBP(smartcardExtension, pbInData); if (status != STATUS_SUCCESS) { // if we can't send the command -> proceeding is sensless goto ExitTransmit2WBP; } // now we have to differenciate, wheter card is in // outgoing data mode (after read command) or // in processing mode (after write/erase command) switch (*pbInData) { case SLE4442_READ: case SLE4442_READ_PROT_MEM: case SLE4442_READ_SEC_MEM: // outgoing data mode //now read data abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0); RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]); //read data in 6 byte packages ulBytesRead=0; do { if ((ulBytesToRead - ulBytesRead) > ATTR_MAX_IFSD_SYNCHRON_USB/8) ulBytesToReadThisStep = ATTR_MAX_IFSD_SYNCHRON_USB/8; else ulBytesToReadThisStep = ulBytesToRead - ulBytesRead; // now send command type 08 to CardManUSB smartcardExtension->SmartcardRequest.BufferLength = ulBytesToReadThisStep*8; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitTransmit2WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit2WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitTransmit2WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=ulBytesToReadThisStep) { // wrong number of bytes read // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitTransmit2WBP; } RtlCopyBytes((PVOID) &(smartcardExtension->IoRequest.ReplyBuffer[ulBytesRead]), (PVOID) smartcardExtension->SmartcardReply.Buffer, smartcardExtension->SmartcardReply.BufferLength); ulBytesRead+=smartcardExtension->SmartcardReply.BufferLength; } while ((status == STATUS_SUCCESS) && (ulBytesToRead > ulBytesRead)); *(smartcardExtension->IoRequest.Information)=ulBytesRead; if (status!=STATUS_SUCCESS) { goto ExitTransmit2WBP; } // according to datasheet, clock should be set to low now // this is not necessary, because this is done before next command // or card is reseted respectivly break; case SLE4442_WRITE: case SLE4442_WRITE_PROT_MEM: case SLE4442_COMPARE_PIN: case SLE4442_UPDATE_SEC_MEM: // processing mode abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0); RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]); do { // now send command type 08 to CardManUSB smartcardExtension->SmartcardRequest.BufferLength = ATTR_MAX_IFSD_SYNCHRON_USB; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitTransmit2WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit2WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitTransmit2WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=ATTR_MAX_IFSD_SYNCHRON_USB/8) { // wrong number of bytes read // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitTransmit2WBP; } /* not necessary this way, check last byte only ulReplySum=0; for (i=0;i<(int)smartcardExtension->SmartcardReply.BufferLength;i++) { ulReplySum+=smartcardExtension->SmartcardReply.Buffer[i]; } */ } while ((status == STATUS_SUCCESS) && (smartcardExtension->SmartcardReply.Buffer[smartcardExtension->SmartcardReply.BufferLength-1]==0)); *(smartcardExtension->IoRequest.Information)=0; if (status!=STATUS_SUCCESS) { goto ExitTransmit2WBP; } // according to datasheet, clock should be set to low now // this is not necessary, because this is done before next command // or card is reseted respectivly break; default: // should not happen status=STATUS_ILLEGAL_INSTRUCTION; goto ExitTransmit2WBP; } ExitTransmit2WBP: SmartcardDebug(DEBUG_TRACE, ("%s!Transmit2WBP: Exit %lx\n",DRIVER_NAME,status)); return status; } /***************************************************************************** Routine Description: Transmits a command (3 Bytes) to a SLE 4442/4432 Arguments: Return Value: *****************************************************************************/ NTSTATUS CMUSB_SendCommand2WBP ( IN PSMARTCARD_EXTENSION smartcardExtension, IN PUCHAR pbCommandData ) { PDEVICE_OBJECT deviceObject; NTSTATUS status = STATUS_SUCCESS; NTSTATUS DebugStatus; UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE]; UCHAR* pByte; UCHAR bValue; int i,j; SmartcardDebug(DEBUG_TRACE, ("%s!SendCommand2WBP: Enter\n",DRIVER_NAME)); SmartcardDebug(DEBUG_PROTOCOL, ("%s!SendCommand2WBP: 4442 Command = %02x %02x %02x\n",DRIVER_NAME, pbCommandData[0], pbCommandData[1], pbCommandData[2])); deviceObject = smartcardExtension->OsData->DeviceObject; // build control code for command to send // command is in first 3 Bytes of pbInData abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0); abSendBuffer[1]=CMUSB_CalcSynchControl(0,0,1,1, 0,1,1,1); abSendBuffer[2]=CMUSB_CalcSynchControl(0,1,1,0, 0,1,1,0); pByte=&abSendBuffer[3]; for (j=0;j<3;j++) { for (i=0;i<8;i++) { bValue=(pbCommandData[j]&(1<SmartcardRequest.BufferLength = 32; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitSendCommand2WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitSendCommand2WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitSendCommand2WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=4) { // 32 bytes sent but not 4 bytes received // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitSendCommand2WBP; } ExitSendCommand2WBP: SmartcardDebug(DEBUG_TRACE, ("%s!SendCommand2WBP: Exit %lx\n",DRIVER_NAME,status)); return status; } /***************************************************************************** Routine Description: Data transfer to synchronous cards SLE 4428/4418 Arguments: Return Value: *****************************************************************************/ NTSTATUS CMUSB_Transmit3WBP ( IN PSMARTCARD_EXTENSION smartcardExtension ) { PDEVICE_OBJECT deviceObject; NTSTATUS status = STATUS_SUCCESS; NTSTATUS DebugStatus; PCHAR pbInData; ULONG ulBytesToRead; ULONG ulBitsToRead; ULONG ulBytesToReadThisStep; ULONG ulBytesRead; UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE]; int i; SmartcardDebug(DEBUG_TRACE, ("%s!Transmit3WBP: Enter\n",DRIVER_NAME)); deviceObject = smartcardExtension->OsData->DeviceObject; // resync CardManUSB by reading the status byte // still necessary with synchronous cards ??? smartcardExtension->SmartcardRequest.BufferLength = 0; status = CMUSB_WriteP0(deviceObject, 0x20, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitTransmit3WBP; } smartcardExtension->ReaderExtension->ulTimeoutP1 = DEFAULT_TIMEOUT_P1; status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit3WBP; } else if (status != STATUS_SUCCESS) { // if we can't read the status there must be a serious error goto ExitTransmit3WBP; } // check if card is really inserted if (smartcardExtension->SmartcardReply.Buffer[0] == 0x00) { // it is not sure, which error messages are accepted // status = STATUS_NO_MEDIA_IN_DEVICE; status = STATUS_UNRECOGNIZED_MEDIA; goto ExitTransmit3WBP; } pbInData = smartcardExtension->IoRequest.RequestBuffer + sizeof(SYNC_TRANSFER); ulBitsToRead = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToRead; ulBytesToRead = ulBitsToRead/8 + (ulBitsToRead % 8 ? 1 : 0); // ulBitsToWrite = ((PSYNC_TRANSFER)(smartcardExtension->IoRequest.RequestBuffer))->ulSyncBitsToWrite; // ulBytesToWrite = ulBitsToWrite/8; if (smartcardExtension->IoRequest.ReplyBufferLength < ulBytesToRead) { status = STATUS_BUFFER_OVERFLOW; goto ExitTransmit3WBP; } // send command status=CMUSB_SendCommand3WBP(smartcardExtension, pbInData); if (status != STATUS_SUCCESS) { // if we can't send the command -> proceeding is useless goto ExitTransmit3WBP; } // now we have to differenciate, wheter card is in // outgoing data mode (after read command) or // in processing mode (after write/erase command) switch (*pbInData & 0x3F) { case SLE4428_READ: case SLE4428_READ_PROT: // outgoing data mode //now read data abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0); RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]); //read data in 6 byte packages ulBytesRead=0; do { if ((ulBytesToRead - ulBytesRead) > ATTR_MAX_IFSD_SYNCHRON_USB/8) ulBytesToReadThisStep = ATTR_MAX_IFSD_SYNCHRON_USB/8; else ulBytesToReadThisStep = ulBytesToRead - ulBytesRead; // now send command type 08 to CardManUSB smartcardExtension->SmartcardRequest.BufferLength = ulBytesToReadThisStep*8; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitTransmit3WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit3WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitTransmit3WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=ulBytesToReadThisStep) { // wrong number of bytes read // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitTransmit3WBP; } RtlCopyBytes((PVOID) &(smartcardExtension->IoRequest.ReplyBuffer[ulBytesRead]), (PVOID) smartcardExtension->SmartcardReply.Buffer, smartcardExtension->SmartcardReply.BufferLength); ulBytesRead+=smartcardExtension->SmartcardReply.BufferLength; } while ((status == STATUS_SUCCESS) && (ulBytesToRead > ulBytesRead)); *(smartcardExtension->IoRequest.Information)=ulBytesRead; if (status!=STATUS_SUCCESS) { goto ExitTransmit3WBP; } // according to datasheet, clock should be set to low now // this is not necessary, because this is done before next command // or card is reseted respectivly break; case SLE4428_WRITE: case SLE4428_WRITE_PROT: case SLE4428_COMPARE: case SLE4428_SET_COUNTER&0x3F: case SLE4428_COMPARE_PIN&0x3F: // processing mode abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,1,0,0); RtlFillMemory((PVOID)&abSendBuffer[1],ATTR_MAX_IFSD_SYNCHRON_USB-1,abSendBuffer[0]); do { // now send command type 08 to CardManUSB smartcardExtension->SmartcardRequest.BufferLength = ATTR_MAX_IFSD_SYNCHRON_USB; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitTransmit3WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitTransmit3WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitTransmit3WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=ATTR_MAX_IFSD_SYNCHRON_USB/8) { // wrong number of bytes read // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitTransmit3WBP; } } while ((status == STATUS_SUCCESS) && (smartcardExtension->SmartcardReply.Buffer[smartcardExtension->SmartcardReply.BufferLength-1]==0xFF)); *(smartcardExtension->IoRequest.Information)=0; if (status!=STATUS_SUCCESS) { goto ExitTransmit3WBP; } // according to datasheet, clock should be set to low now // this is not necessary, because this is done before next command // or card is reseted respectivly break; default: // should not happen status=STATUS_ILLEGAL_INSTRUCTION; goto ExitTransmit3WBP; } ExitTransmit3WBP: SmartcardDebug(DEBUG_TRACE, ("%s!Transmit3WBP: Exit %lx\n",DRIVER_NAME,status)); return status; } /***************************************************************************** Routine Description: Transmits a command (3 Bytes) to a SLE 4428/4418 Arguments: Return Value: *****************************************************************************/ NTSTATUS CMUSB_SendCommand3WBP ( IN PSMARTCARD_EXTENSION smartcardExtension, IN PUCHAR pbCommandData ) { PDEVICE_OBJECT deviceObject; NTSTATUS status = STATUS_SUCCESS; NTSTATUS DebugStatus; UCHAR abSendBuffer[CMUSB_SYNCH_BUFFER_SIZE]; UCHAR* pByte; UCHAR bValue; int i,j; SmartcardDebug(DEBUG_TRACE, ("%s!SendCommand3WBP: Enter\n",DRIVER_NAME)); SmartcardDebug(DEBUG_PROTOCOL, ("%s!SendCommand3WBP: 4442 Command = %02x %02x %02x\n",DRIVER_NAME, pbCommandData[0], pbCommandData[1], pbCommandData[2])); deviceObject = smartcardExtension->OsData->DeviceObject; // build control code for command to send // command is in first 3 Bytes of pbInData abSendBuffer[0]=CMUSB_CalcSynchControl(0,0,0,0, 0,0,0,0); pByte=&abSendBuffer[1]; for (j=0;j<3;j++) { for (i=0;i<8;i++) { bValue=(pbCommandData[j]&(1<SmartcardRequest.BufferLength = 32; RtlCopyBytes((PVOID) smartcardExtension->SmartcardRequest.Buffer, (PVOID) abSendBuffer, smartcardExtension->SmartcardRequest.BufferLength); status = CMUSB_WriteP0(deviceObject, 0x08, //bRequest, 0x00, //bValueLo, 0x00, //bValueHi, 0x00, //bIndexLo, 0x00 //bIndexHi, ); if (status != STATUS_SUCCESS) { // if we can't write command there must be a serious error goto ExitSendCommand3WBP; } status = CMUSB_ReadP1(deviceObject); if (status == STATUS_DEVICE_DATA_ERROR) { DebugStatus = CMUSB_ReadStateAfterP1Stalled(deviceObject); goto ExitSendCommand3WBP; } else if (status != STATUS_SUCCESS) { // if we can't read there must be a serious error goto ExitSendCommand3WBP; } if (smartcardExtension->SmartcardReply.BufferLength!=4) { // 32 bytes sent but not 4 bytes received // -> something went wrong status=STATUS_DEVICE_DATA_ERROR; goto ExitSendCommand3WBP; } ExitSendCommand3WBP: SmartcardDebug(DEBUG_TRACE, ("%s!SendCommand3WBP: Exit %lx\n",DRIVER_NAME,status)); return status; } /***************************************************************************** * History: * $Log: scusbsyn.c $ * Revision 1.3 2000/08/24 09:04:39 TBruendl * No comment given * * Revision 1.2 2000/07/24 11:35:00 WFrischauf * No comment given * * Revision 1.1 2000/07/20 11:50:16 WFrischauf * No comment given * * ******************************************************************************/