26#include <freerdp/config.h>
28#include <winpr/assert.h>
31#include <winpr/print.h>
32#include <winpr/stream.h>
33#include <winpr/smartcard.h>
35#include <freerdp/freerdp.h>
36#include <freerdp/channels/rdpdr.h>
37#include <freerdp/channels/scard.h>
39#include <freerdp/utils/rdpdr_utils.h>
41#include <freerdp/utils/smartcard_operations.h>
42#include <freerdp/utils/smartcard_pack.h>
44#include <freerdp/log.h>
45#define TAG FREERDP_TAG("utils.smartcard.ops")
49 WINPR_ASSERT(operation);
52 smartcard_scard_context_native_from_redir(&(operation->call.handles.hContext));
53 operation->hCard = smartcard_scard_handle_native_from_redir(&(operation->call.handles.hCard));
55 return SCARD_S_SUCCESS;
63 WINPR_ASSERT(operation);
65 status = smartcard_unpack_establish_context_call(s, &operation->call.establishContext);
66 if (status != SCARD_S_SUCCESS)
68 return scard_log_status_error(TAG,
"smartcard_unpack_establish_context_call", status);
71 return SCARD_S_SUCCESS;
79 WINPR_ASSERT(operation);
81 status = smartcard_unpack_context_call(s, &operation->call.context,
"ReleaseContext");
82 if (status != SCARD_S_SUCCESS)
83 scard_log_status_error(TAG,
"smartcard_unpack_context_call", status);
93 WINPR_ASSERT(operation);
95 status = smartcard_unpack_context_call(s, &operation->call.context,
"IsValidContext");
105 WINPR_ASSERT(operation);
107 status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, FALSE);
117 WINPR_ASSERT(operation);
119 status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, TRUE);
129 WINPR_ASSERT(operation);
131 status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, FALSE);
141 WINPR_ASSERT(operation);
143 status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, TRUE);
153 WINPR_ASSERT(operation);
156 smartcard_unpack_context_and_two_strings_a_call(s, &operation->call.contextAndTwoStringA);
166 WINPR_ASSERT(operation);
169 smartcard_unpack_context_and_two_strings_w_call(s, &operation->call.contextAndTwoStringW);
179 WINPR_ASSERT(operation);
181 status = smartcard_unpack_context_and_string_a_call(s, &operation->call.contextAndStringA);
191 WINPR_ASSERT(operation);
193 status = smartcard_unpack_context_and_string_w_call(s, &operation->call.contextAndStringW);
203 WINPR_ASSERT(operation);
205 status = smartcard_unpack_locate_cards_a_call(s, &operation->call.locateCardsA);
215 WINPR_ASSERT(operation);
217 status = smartcard_unpack_locate_cards_w_call(s, &operation->call.locateCardsW);
225 WINPR_ASSERT(operation);
227 return smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
233 WINPR_ASSERT(operation);
235 return smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
243 WINPR_ASSERT(operation);
245 status = smartcard_unpack_context_call(s, &operation->call.context,
"Cancel");
255 WINPR_ASSERT(operation);
257 status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
267 WINPR_ASSERT(operation);
269 status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
279 WINPR_ASSERT(operation);
281 status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
291 WINPR_ASSERT(operation);
293 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
304 WINPR_ASSERT(operation);
306 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
317 WINPR_ASSERT(operation);
319 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
330 WINPR_ASSERT(operation);
332 status = smartcard_unpack_state_call(s, &operation->call.state);
342 WINPR_ASSERT(operation);
344 status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
354 WINPR_ASSERT(operation);
356 status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
366 WINPR_ASSERT(operation);
368 status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
378 WINPR_ASSERT(operation);
380 status = smartcard_unpack_control_call(s, &operation->call.control);
390 WINPR_ASSERT(operation);
392 status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
402 WINPR_ASSERT(operation);
404 status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
412 WINPR_ASSERT(operation);
414 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
415 return SCARD_F_INTERNAL_ERROR;
417 Stream_Read_INT32(s, operation->call.lng.LongValue);
419 return SCARD_S_SUCCESS;
427 WINPR_ASSERT(operation);
429 status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
439 WINPR_ASSERT(operation);
441 status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
451 WINPR_ASSERT(operation);
453 status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
463 WINPR_ASSERT(operation);
465 status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
475 WINPR_ASSERT(operation);
477 status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
487 WINPR_ASSERT(operation);
489 status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
499 WINPR_ASSERT(operation);
501 status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
509 WINPR_UNUSED(operation);
510 WLog_WARN(TAG,
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
511 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
512 return SCARD_E_UNSUPPORTED_FEATURE;
520 WINPR_ASSERT(operation);
522 status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
532 WINPR_ASSERT(operation);
534 status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
539LONG smartcard_irp_device_control_decode(
wStream* s, UINT32 CompletionId, UINT32 FileId,
546 WINPR_ASSERT(operation);
550 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32))
551 return SCARD_F_INTERNAL_ERROR;
553 const UINT32 outputBufferLength = Stream_Get_UINT32(s);
554 const UINT32 inputBufferLength = Stream_Get_UINT32(s);
555 const UINT32 ioControlCode = Stream_Get_UINT32(s);
557 operation->ioControlCode = ioControlCode;
558 operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
559 operation->outputBufferLength = outputBufferLength;
561 if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength))
563 WLog_WARN(TAG,
"InputBufferLength mismatch: Actual: %" PRIuz
" Expected: %" PRIuz
"",
564 Stream_Length(s), Stream_GetPosition(s) + inputBufferLength);
565 return SCARD_F_INTERNAL_ERROR;
568 WLog_DBG(TAG,
"%s (0x%08" PRIX32
") FileId: %" PRIu32
" CompletionId: %" PRIu32
"",
569 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId);
571 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
572 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
574 status = smartcard_unpack_common_type_header(s);
575 if (status != SCARD_S_SUCCESS)
578 status = smartcard_unpack_private_type_header(s);
579 if (status != SCARD_S_SUCCESS)
584 switch (ioControlCode)
586 case SCARD_IOCTL_ESTABLISHCONTEXT:
587 status = smartcard_EstablishContext_Decode(s, operation);
590 case SCARD_IOCTL_RELEASECONTEXT:
591 status = smartcard_ReleaseContext_Decode(s, operation);
594 case SCARD_IOCTL_ISVALIDCONTEXT:
595 status = smartcard_IsValidContext_Decode(s, operation);
598 case SCARD_IOCTL_LISTREADERGROUPSA:
599 status = smartcard_ListReaderGroupsA_Decode(s, operation);
602 case SCARD_IOCTL_LISTREADERGROUPSW:
603 status = smartcard_ListReaderGroupsW_Decode(s, operation);
606 case SCARD_IOCTL_LISTREADERSA:
607 status = smartcard_ListReadersA_Decode(s, operation);
610 case SCARD_IOCTL_LISTREADERSW:
611 status = smartcard_ListReadersW_Decode(s, operation);
614 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
615 status = smartcard_context_and_string_a_Decode(s, operation);
618 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
619 status = smartcard_context_and_string_w_Decode(s, operation);
622 case SCARD_IOCTL_FORGETREADERGROUPA:
623 status = smartcard_context_and_string_a_Decode(s, operation);
626 case SCARD_IOCTL_FORGETREADERGROUPW:
627 status = smartcard_context_and_string_w_Decode(s, operation);
630 case SCARD_IOCTL_INTRODUCEREADERA:
631 status = smartcard_context_and_two_strings_a_Decode(s, operation);
634 case SCARD_IOCTL_INTRODUCEREADERW:
635 status = smartcard_context_and_two_strings_w_Decode(s, operation);
638 case SCARD_IOCTL_FORGETREADERA:
639 status = smartcard_context_and_string_a_Decode(s, operation);
642 case SCARD_IOCTL_FORGETREADERW:
643 status = smartcard_context_and_string_w_Decode(s, operation);
646 case SCARD_IOCTL_ADDREADERTOGROUPA:
647 status = smartcard_context_and_two_strings_a_Decode(s, operation);
650 case SCARD_IOCTL_ADDREADERTOGROUPW:
651 status = smartcard_context_and_two_strings_w_Decode(s, operation);
654 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
655 status = smartcard_context_and_two_strings_a_Decode(s, operation);
658 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
659 status = smartcard_context_and_two_strings_w_Decode(s, operation);
662 case SCARD_IOCTL_LOCATECARDSA:
663 status = smartcard_LocateCardsA_Decode(s, operation);
666 case SCARD_IOCTL_LOCATECARDSW:
667 status = smartcard_LocateCardsW_Decode(s, operation);
670 case SCARD_IOCTL_GETSTATUSCHANGEA:
671 status = smartcard_GetStatusChangeA_Decode(s, operation);
674 case SCARD_IOCTL_GETSTATUSCHANGEW:
675 status = smartcard_GetStatusChangeW_Decode(s, operation);
678 case SCARD_IOCTL_CANCEL:
679 status = smartcard_Cancel_Decode(s, operation);
682 case SCARD_IOCTL_CONNECTA:
683 status = smartcard_ConnectA_Decode(s, operation);
686 case SCARD_IOCTL_CONNECTW:
687 status = smartcard_ConnectW_Decode(s, operation);
690 case SCARD_IOCTL_RECONNECT:
691 status = smartcard_Reconnect_Decode(s, operation);
694 case SCARD_IOCTL_DISCONNECT:
695 status = smartcard_Disconnect_Decode(s, operation);
698 case SCARD_IOCTL_BEGINTRANSACTION:
699 status = smartcard_BeginTransaction_Decode(s, operation);
702 case SCARD_IOCTL_ENDTRANSACTION:
703 status = smartcard_EndTransaction_Decode(s, operation);
706 case SCARD_IOCTL_STATE:
707 status = smartcard_State_Decode(s, operation);
710 case SCARD_IOCTL_STATUSA:
711 status = smartcard_StatusA_Decode(s, operation);
714 case SCARD_IOCTL_STATUSW:
715 status = smartcard_StatusW_Decode(s, operation);
718 case SCARD_IOCTL_TRANSMIT:
719 status = smartcard_Transmit_Decode(s, operation);
722 case SCARD_IOCTL_CONTROL:
723 status = smartcard_Control_Decode(s, operation);
726 case SCARD_IOCTL_GETATTRIB:
727 status = smartcard_GetAttrib_Decode(s, operation);
730 case SCARD_IOCTL_SETATTRIB:
731 status = smartcard_SetAttrib_Decode(s, operation);
734 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
735 status = smartcard_AccessStartedEvent_Decode(s, operation);
738 case SCARD_IOCTL_LOCATECARDSBYATRA:
739 status = smartcard_LocateCardsByATRA_Decode(s, operation);
742 case SCARD_IOCTL_LOCATECARDSBYATRW:
743 status = smartcard_LocateCardsByATRW_Decode(s, operation);
746 case SCARD_IOCTL_READCACHEA:
747 status = smartcard_ReadCacheA_Decode(s, operation);
750 case SCARD_IOCTL_READCACHEW:
751 status = smartcard_ReadCacheW_Decode(s, operation);
754 case SCARD_IOCTL_WRITECACHEA:
755 status = smartcard_WriteCacheA_Decode(s, operation);
758 case SCARD_IOCTL_WRITECACHEW:
759 status = smartcard_WriteCacheW_Decode(s, operation);
762 case SCARD_IOCTL_GETTRANSMITCOUNT:
763 status = smartcard_GetTransmitCount_Decode(s, operation);
766 case SCARD_IOCTL_RELEASETARTEDEVENT:
767 status = smartcard_ReleaseStartedEvent_Decode(s, operation);
770 case SCARD_IOCTL_GETREADERICON:
771 status = smartcard_GetReaderIcon_Decode(s, operation);
774 case SCARD_IOCTL_GETDEVICETYPEID:
775 status = smartcard_GetDeviceTypeId_Decode(s, operation);
779 status = SCARD_F_INTERNAL_ERROR;
783 smartcard_call_to_operation_handle(operation);
785 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
786 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
788 offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
789 smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8);
792 if (Stream_GetPosition(s) < Stream_Length(s))
794 size_t difference = 0;
795 difference = Stream_Length(s) - Stream_GetPosition(s);
797 "IRP was not fully parsed %s (%s [0x%08" PRIX32
"]): Actual: %" PRIuz
798 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
799 scard_get_ioctl_string(ioControlCode, TRUE),
800 scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
801 Stream_GetPosition(s), Stream_Length(s), difference);
802 winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
805 if (Stream_GetPosition(s) > Stream_Length(s))
807 size_t difference = 0;
808 difference = Stream_GetPosition(s) - Stream_Length(s);
810 "IRP was parsed beyond its end %s (0x%08" PRIX32
"): Actual: %" PRIuz
811 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
812 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
813 Stream_Length(s), difference);
821 for (UINT32 x = 0; x < cReaders; x++)
824 free(state->szReader);
827 free(rgReaderStates);
832 for (UINT32 x = 0; x < cReaders; x++)
835 free(state->szReader);
838 free(rgReaderStates);
845 switch (op->ioControlCode)
847 case SCARD_IOCTL_CANCEL:
848 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
849 case SCARD_IOCTL_RELEASETARTEDEVENT:
850 case SCARD_IOCTL_LISTREADERGROUPSA:
851 case SCARD_IOCTL_LISTREADERGROUPSW:
852 case SCARD_IOCTL_RECONNECT:
853 case SCARD_IOCTL_DISCONNECT:
854 case SCARD_IOCTL_BEGINTRANSACTION:
855 case SCARD_IOCTL_ENDTRANSACTION:
856 case SCARD_IOCTL_STATE:
857 case SCARD_IOCTL_STATUSA:
858 case SCARD_IOCTL_STATUSW:
859 case SCARD_IOCTL_ESTABLISHCONTEXT:
860 case SCARD_IOCTL_RELEASECONTEXT:
861 case SCARD_IOCTL_ISVALIDCONTEXT:
862 case SCARD_IOCTL_GETATTRIB:
863 case SCARD_IOCTL_GETTRANSMITCOUNT:
866 case SCARD_IOCTL_LOCATECARDSA:
869 free(call->mszCards);
871 free_reader_states_a(call->rgReaderStates, call->cReaders);
874 case SCARD_IOCTL_LOCATECARDSW:
877 free(call->mszCards);
879 free_reader_states_w(call->rgReaderStates, call->cReaders);
883 case SCARD_IOCTL_LOCATECARDSBYATRA:
887 free_reader_states_a(call->rgReaderStates, call->cReaders);
890 case SCARD_IOCTL_LOCATECARDSBYATRW:
893 free_reader_states_w(call->rgReaderStates, call->cReaders);
896 case SCARD_IOCTL_FORGETREADERA:
897 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
898 case SCARD_IOCTL_FORGETREADERGROUPA:
905 case SCARD_IOCTL_FORGETREADERW:
906 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
907 case SCARD_IOCTL_FORGETREADERGROUPW:
914 case SCARD_IOCTL_INTRODUCEREADERA:
915 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
916 case SCARD_IOCTL_ADDREADERTOGROUPA:
925 case SCARD_IOCTL_INTRODUCEREADERW:
926 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
927 case SCARD_IOCTL_ADDREADERTOGROUPW:
936 case SCARD_IOCTL_LISTREADERSA:
937 case SCARD_IOCTL_LISTREADERSW:
940 free(call->mszGroups);
943 case SCARD_IOCTL_GETSTATUSCHANGEA:
946 free_reader_states_a(call->rgReaderStates, call->cReaders);
950 case SCARD_IOCTL_GETSTATUSCHANGEW:
953 free_reader_states_w(call->rgReaderStates, call->cReaders);
956 case SCARD_IOCTL_GETREADERICON:
959 free(call->szReaderName);
962 case SCARD_IOCTL_GETDEVICETYPEID:
965 free(call->szReaderName);
968 case SCARD_IOCTL_CONNECTA:
971 free(call->szReader);
974 case SCARD_IOCTL_CONNECTW:
977 free(call->szReader);
980 case SCARD_IOCTL_SETATTRIB:
981 free(op->call.setAttrib.pbAttr);
983 case SCARD_IOCTL_TRANSMIT:
986 free(call->pbSendBuffer);
987 free(call->pioSendPci);
988 free(call->pioRecvPci);
991 case SCARD_IOCTL_CONTROL:
994 free(call->pvInBuffer);
997 case SCARD_IOCTL_READCACHEA:
1000 free(call->szLookupName);
1001 free(call->Common.CardIdentifier);
1004 case SCARD_IOCTL_READCACHEW:
1007 free(call->szLookupName);
1008 free(call->Common.CardIdentifier);
1011 case SCARD_IOCTL_WRITECACHEA:
1014 free(call->szLookupName);
1015 free(call->Common.CardIdentifier);
1016 free(call->Common.pbData);
1019 case SCARD_IOCTL_WRITECACHEW:
1022 free(call->szLookupName);
1023 free(call->Common.CardIdentifier);
1024 free(call->Common.pbData);