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);
227 WINPR_ASSERT(operation);
229 status = smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
239 WINPR_ASSERT(operation);
241 status = smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
251 WINPR_ASSERT(operation);
253 status = smartcard_unpack_context_call(s, &operation->call.context,
"Cancel");
263 WINPR_ASSERT(operation);
265 status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
275 WINPR_ASSERT(operation);
277 status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
287 WINPR_ASSERT(operation);
289 status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
299 WINPR_ASSERT(operation);
301 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
312 WINPR_ASSERT(operation);
314 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
325 WINPR_ASSERT(operation);
327 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
338 WINPR_ASSERT(operation);
340 status = smartcard_unpack_state_call(s, &operation->call.state);
350 WINPR_ASSERT(operation);
352 status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
362 WINPR_ASSERT(operation);
364 status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
374 WINPR_ASSERT(operation);
376 status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
386 WINPR_ASSERT(operation);
388 status = smartcard_unpack_control_call(s, &operation->call.control);
398 WINPR_ASSERT(operation);
400 status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
410 WINPR_ASSERT(operation);
412 status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
420 WINPR_ASSERT(operation);
422 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
423 return SCARD_F_INTERNAL_ERROR;
425 Stream_Read_INT32(s, operation->call.lng.LongValue);
427 return SCARD_S_SUCCESS;
435 WINPR_ASSERT(operation);
437 status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
447 WINPR_ASSERT(operation);
449 status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
459 WINPR_ASSERT(operation);
461 status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
471 WINPR_ASSERT(operation);
473 status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
483 WINPR_ASSERT(operation);
485 status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
495 WINPR_ASSERT(operation);
497 status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
507 WINPR_ASSERT(operation);
509 status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
517 WINPR_UNUSED(operation);
518 WLog_WARN(TAG,
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
519 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
520 return SCARD_E_UNSUPPORTED_FEATURE;
528 WINPR_ASSERT(operation);
530 status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
540 WINPR_ASSERT(operation);
542 status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
547LONG smartcard_irp_device_control_decode(
wStream* s, UINT32 CompletionId, UINT32 FileId,
554 WINPR_ASSERT(operation);
558 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32))
559 return SCARD_F_INTERNAL_ERROR;
561 const UINT32 outputBufferLength = Stream_Get_UINT32(s);
562 const UINT32 inputBufferLength = Stream_Get_UINT32(s);
563 const UINT32 ioControlCode = Stream_Get_UINT32(s);
565 operation->ioControlCode = ioControlCode;
566 operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
567 operation->outputBufferLength = outputBufferLength;
569 if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength))
571 WLog_WARN(TAG,
"InputBufferLength mismatch: Actual: %" PRIuz
" Expected: %" PRIuz
"",
572 Stream_Length(s), Stream_GetPosition(s) + inputBufferLength);
573 return SCARD_F_INTERNAL_ERROR;
576 WLog_DBG(TAG,
"%s (0x%08" PRIX32
") FileId: %" PRIu32
" CompletionId: %" PRIu32
"",
577 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId);
579 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
580 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
582 status = smartcard_unpack_common_type_header(s);
583 if (status != SCARD_S_SUCCESS)
586 status = smartcard_unpack_private_type_header(s);
587 if (status != SCARD_S_SUCCESS)
592 switch (ioControlCode)
594 case SCARD_IOCTL_ESTABLISHCONTEXT:
595 status = smartcard_EstablishContext_Decode(s, operation);
598 case SCARD_IOCTL_RELEASECONTEXT:
599 status = smartcard_ReleaseContext_Decode(s, operation);
602 case SCARD_IOCTL_ISVALIDCONTEXT:
603 status = smartcard_IsValidContext_Decode(s, operation);
606 case SCARD_IOCTL_LISTREADERGROUPSA:
607 status = smartcard_ListReaderGroupsA_Decode(s, operation);
610 case SCARD_IOCTL_LISTREADERGROUPSW:
611 status = smartcard_ListReaderGroupsW_Decode(s, operation);
614 case SCARD_IOCTL_LISTREADERSA:
615 status = smartcard_ListReadersA_Decode(s, operation);
618 case SCARD_IOCTL_LISTREADERSW:
619 status = smartcard_ListReadersW_Decode(s, operation);
622 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
623 status = smartcard_context_and_string_a_Decode(s, operation);
626 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
627 status = smartcard_context_and_string_w_Decode(s, operation);
630 case SCARD_IOCTL_FORGETREADERGROUPA:
631 status = smartcard_context_and_string_a_Decode(s, operation);
634 case SCARD_IOCTL_FORGETREADERGROUPW:
635 status = smartcard_context_and_string_w_Decode(s, operation);
638 case SCARD_IOCTL_INTRODUCEREADERA:
639 status = smartcard_context_and_two_strings_a_Decode(s, operation);
642 case SCARD_IOCTL_INTRODUCEREADERW:
643 status = smartcard_context_and_two_strings_w_Decode(s, operation);
646 case SCARD_IOCTL_FORGETREADERA:
647 status = smartcard_context_and_string_a_Decode(s, operation);
650 case SCARD_IOCTL_FORGETREADERW:
651 status = smartcard_context_and_string_w_Decode(s, operation);
654 case SCARD_IOCTL_ADDREADERTOGROUPA:
655 status = smartcard_context_and_two_strings_a_Decode(s, operation);
658 case SCARD_IOCTL_ADDREADERTOGROUPW:
659 status = smartcard_context_and_two_strings_w_Decode(s, operation);
662 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
663 status = smartcard_context_and_two_strings_a_Decode(s, operation);
666 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
667 status = smartcard_context_and_two_strings_w_Decode(s, operation);
670 case SCARD_IOCTL_LOCATECARDSA:
671 status = smartcard_LocateCardsA_Decode(s, operation);
674 case SCARD_IOCTL_LOCATECARDSW:
675 status = smartcard_LocateCardsW_Decode(s, operation);
678 case SCARD_IOCTL_GETSTATUSCHANGEA:
679 status = smartcard_GetStatusChangeA_Decode(s, operation);
682 case SCARD_IOCTL_GETSTATUSCHANGEW:
683 status = smartcard_GetStatusChangeW_Decode(s, operation);
686 case SCARD_IOCTL_CANCEL:
687 status = smartcard_Cancel_Decode(s, operation);
690 case SCARD_IOCTL_CONNECTA:
691 status = smartcard_ConnectA_Decode(s, operation);
694 case SCARD_IOCTL_CONNECTW:
695 status = smartcard_ConnectW_Decode(s, operation);
698 case SCARD_IOCTL_RECONNECT:
699 status = smartcard_Reconnect_Decode(s, operation);
702 case SCARD_IOCTL_DISCONNECT:
703 status = smartcard_Disconnect_Decode(s, operation);
706 case SCARD_IOCTL_BEGINTRANSACTION:
707 status = smartcard_BeginTransaction_Decode(s, operation);
710 case SCARD_IOCTL_ENDTRANSACTION:
711 status = smartcard_EndTransaction_Decode(s, operation);
714 case SCARD_IOCTL_STATE:
715 status = smartcard_State_Decode(s, operation);
718 case SCARD_IOCTL_STATUSA:
719 status = smartcard_StatusA_Decode(s, operation);
722 case SCARD_IOCTL_STATUSW:
723 status = smartcard_StatusW_Decode(s, operation);
726 case SCARD_IOCTL_TRANSMIT:
727 status = smartcard_Transmit_Decode(s, operation);
730 case SCARD_IOCTL_CONTROL:
731 status = smartcard_Control_Decode(s, operation);
734 case SCARD_IOCTL_GETATTRIB:
735 status = smartcard_GetAttrib_Decode(s, operation);
738 case SCARD_IOCTL_SETATTRIB:
739 status = smartcard_SetAttrib_Decode(s, operation);
742 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
743 status = smartcard_AccessStartedEvent_Decode(s, operation);
746 case SCARD_IOCTL_LOCATECARDSBYATRA:
747 status = smartcard_LocateCardsByATRA_Decode(s, operation);
750 case SCARD_IOCTL_LOCATECARDSBYATRW:
751 status = smartcard_LocateCardsByATRW_Decode(s, operation);
754 case SCARD_IOCTL_READCACHEA:
755 status = smartcard_ReadCacheA_Decode(s, operation);
758 case SCARD_IOCTL_READCACHEW:
759 status = smartcard_ReadCacheW_Decode(s, operation);
762 case SCARD_IOCTL_WRITECACHEA:
763 status = smartcard_WriteCacheA_Decode(s, operation);
766 case SCARD_IOCTL_WRITECACHEW:
767 status = smartcard_WriteCacheW_Decode(s, operation);
770 case SCARD_IOCTL_GETTRANSMITCOUNT:
771 status = smartcard_GetTransmitCount_Decode(s, operation);
774 case SCARD_IOCTL_RELEASETARTEDEVENT:
775 status = smartcard_ReleaseStartedEvent_Decode(s, operation);
778 case SCARD_IOCTL_GETREADERICON:
779 status = smartcard_GetReaderIcon_Decode(s, operation);
782 case SCARD_IOCTL_GETDEVICETYPEID:
783 status = smartcard_GetDeviceTypeId_Decode(s, operation);
787 status = SCARD_F_INTERNAL_ERROR;
791 smartcard_call_to_operation_handle(operation);
793 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
794 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
796 offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
797 smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8);
800 if (Stream_GetPosition(s) < Stream_Length(s))
802 size_t difference = 0;
803 difference = Stream_Length(s) - Stream_GetPosition(s);
805 "IRP was not fully parsed %s (%s [0x%08" PRIX32
"]): Actual: %" PRIuz
806 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
807 scard_get_ioctl_string(ioControlCode, TRUE),
808 scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
809 Stream_GetPosition(s), Stream_Length(s), difference);
810 winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
813 if (Stream_GetPosition(s) > Stream_Length(s))
815 size_t difference = 0;
816 difference = Stream_GetPosition(s) - Stream_Length(s);
818 "IRP was parsed beyond its end %s (0x%08" PRIX32
"): Actual: %" PRIuz
819 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
820 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
821 Stream_Length(s), difference);
829 for (UINT32 x = 0; x < cReaders; x++)
832 free(state->szReader);
835 free(rgReaderStates);
840 for (UINT32 x = 0; x < cReaders; x++)
843 free(state->szReader);
846 free(rgReaderStates);
853 switch (op->ioControlCode)
855 case SCARD_IOCTL_CANCEL:
856 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
857 case SCARD_IOCTL_RELEASETARTEDEVENT:
858 case SCARD_IOCTL_LISTREADERGROUPSA:
859 case SCARD_IOCTL_LISTREADERGROUPSW:
860 case SCARD_IOCTL_RECONNECT:
861 case SCARD_IOCTL_DISCONNECT:
862 case SCARD_IOCTL_BEGINTRANSACTION:
863 case SCARD_IOCTL_ENDTRANSACTION:
864 case SCARD_IOCTL_STATE:
865 case SCARD_IOCTL_STATUSA:
866 case SCARD_IOCTL_STATUSW:
867 case SCARD_IOCTL_ESTABLISHCONTEXT:
868 case SCARD_IOCTL_RELEASECONTEXT:
869 case SCARD_IOCTL_ISVALIDCONTEXT:
870 case SCARD_IOCTL_GETATTRIB:
871 case SCARD_IOCTL_GETTRANSMITCOUNT:
874 case SCARD_IOCTL_LOCATECARDSA:
877 free(call->mszCards);
879 free_reader_states_a(call->rgReaderStates, call->cReaders);
882 case SCARD_IOCTL_LOCATECARDSW:
885 free(call->mszCards);
887 free_reader_states_w(call->rgReaderStates, call->cReaders);
891 case SCARD_IOCTL_LOCATECARDSBYATRA:
895 free_reader_states_a(call->rgReaderStates, call->cReaders);
898 case SCARD_IOCTL_LOCATECARDSBYATRW:
901 free_reader_states_w(call->rgReaderStates, call->cReaders);
904 case SCARD_IOCTL_FORGETREADERA:
905 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
906 case SCARD_IOCTL_FORGETREADERGROUPA:
913 case SCARD_IOCTL_FORGETREADERW:
914 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
915 case SCARD_IOCTL_FORGETREADERGROUPW:
922 case SCARD_IOCTL_INTRODUCEREADERA:
923 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
924 case SCARD_IOCTL_ADDREADERTOGROUPA:
933 case SCARD_IOCTL_INTRODUCEREADERW:
934 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
935 case SCARD_IOCTL_ADDREADERTOGROUPW:
944 case SCARD_IOCTL_LISTREADERSA:
945 case SCARD_IOCTL_LISTREADERSW:
948 free(call->mszGroups);
951 case SCARD_IOCTL_GETSTATUSCHANGEA:
954 free_reader_states_a(call->rgReaderStates, call->cReaders);
958 case SCARD_IOCTL_GETSTATUSCHANGEW:
961 free_reader_states_w(call->rgReaderStates, call->cReaders);
964 case SCARD_IOCTL_GETREADERICON:
967 free(call->szReaderName);
970 case SCARD_IOCTL_GETDEVICETYPEID:
973 free(call->szReaderName);
976 case SCARD_IOCTL_CONNECTA:
979 free(call->szReader);
982 case SCARD_IOCTL_CONNECTW:
985 free(call->szReader);
988 case SCARD_IOCTL_SETATTRIB:
989 free(op->call.setAttrib.pbAttr);
991 case SCARD_IOCTL_TRANSMIT:
994 free(call->pbSendBuffer);
995 free(call->pioSendPci);
996 free(call->pioRecvPci);
999 case SCARD_IOCTL_CONTROL:
1002 free(call->pvInBuffer);
1005 case SCARD_IOCTL_READCACHEA:
1008 free(call->szLookupName);
1009 free(call->Common.CardIdentifier);
1012 case SCARD_IOCTL_READCACHEW:
1015 free(call->szLookupName);
1016 free(call->Common.CardIdentifier);
1019 case SCARD_IOCTL_WRITECACHEA:
1022 free(call->szLookupName);
1023 free(call->Common.CardIdentifier);
1024 free(call->Common.pbData);
1027 case SCARD_IOCTL_WRITECACHEW:
1030 free(call->szLookupName);
1031 free(call->Common.CardIdentifier);
1032 free(call->Common.pbData);