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);
148static LONG smartcard_ContextAndTwoStringA_decode_request(
wStream* s,
154 WINPR_ASSERT(operation);
157 smartcard_unpack_context_and_two_strings_a_call(s, &operation->call.contextAndTwoStringA);
162static LONG smartcard_ContextAndTwoStringW_decode_request(
wStream* s,
168 WINPR_ASSERT(operation);
171 smartcard_unpack_context_and_two_strings_w_call(s, &operation->call.contextAndTwoStringW);
181 WINPR_ASSERT(operation);
183 status = smartcard_unpack_context_and_string_a_call(s, &operation->call.contextAndStringA);
193 WINPR_ASSERT(operation);
195 status = smartcard_unpack_context_and_string_w_call(s, &operation->call.contextAndStringW);
205 WINPR_ASSERT(operation);
207 status = smartcard_unpack_locate_cards_a_call(s, &operation->call.locateCardsA);
217 WINPR_ASSERT(operation);
219 status = smartcard_unpack_locate_cards_w_call(s, &operation->call.locateCardsW);
227 WINPR_ASSERT(operation);
229 return smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
235 WINPR_ASSERT(operation);
237 return smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
245 WINPR_ASSERT(operation);
247 status = smartcard_unpack_context_call(s, &operation->call.context,
"Cancel");
257 WINPR_ASSERT(operation);
259 status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
269 WINPR_ASSERT(operation);
271 status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
281 WINPR_ASSERT(operation);
283 status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
293 WINPR_ASSERT(operation);
295 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
306 WINPR_ASSERT(operation);
308 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
319 WINPR_ASSERT(operation);
321 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
332 WINPR_ASSERT(operation);
334 status = smartcard_unpack_state_call(s, &operation->call.state);
344 WINPR_ASSERT(operation);
346 status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
356 WINPR_ASSERT(operation);
358 status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
368 WINPR_ASSERT(operation);
370 status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
380 WINPR_ASSERT(operation);
382 status = smartcard_unpack_control_call(s, &operation->call.control);
392 WINPR_ASSERT(operation);
394 status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
404 WINPR_ASSERT(operation);
406 status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
414 WINPR_ASSERT(operation);
416 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
417 return SCARD_F_INTERNAL_ERROR;
419 Stream_Read_INT32(s, operation->call.lng.LongValue);
421 return SCARD_S_SUCCESS;
429 WINPR_ASSERT(operation);
431 status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
441 WINPR_ASSERT(operation);
443 status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
453 WINPR_ASSERT(operation);
455 status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
465 WINPR_ASSERT(operation);
467 status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
477 WINPR_ASSERT(operation);
479 status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
489 WINPR_ASSERT(operation);
491 status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
501 WINPR_ASSERT(operation);
503 status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
511 WINPR_UNUSED(operation);
512 WLog_WARN(TAG,
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
513 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
514 return SCARD_E_UNSUPPORTED_FEATURE;
522 WINPR_ASSERT(operation);
524 status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
534 WINPR_ASSERT(operation);
536 status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
541LONG smartcard_irp_device_control_decode(
wStream* s, UINT32 CompletionId, UINT32 FileId,
544 return smartcard_irp_device_control_decode_request(s, CompletionId, FileId, operation);
547LONG smartcard_irp_device_control_decode_request(
wStream* s, UINT32 CompletionId, UINT32 FileId,
554 WINPR_ASSERT(operation);
558 if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH))
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_request(s, operation);
598 case SCARD_IOCTL_RELEASECONTEXT:
599 status = smartcard_ReleaseContext_decode_request(s, operation);
602 case SCARD_IOCTL_ISVALIDCONTEXT:
603 status = smartcard_IsValidContext_decode_request(s, operation);
606 case SCARD_IOCTL_LISTREADERGROUPSA:
607 status = smartcard_ListReaderGroupsA_decode_request(s, operation);
610 case SCARD_IOCTL_LISTREADERGROUPSW:
611 status = smartcard_ListReaderGroupsW_decode_request(s, operation);
614 case SCARD_IOCTL_LISTREADERSA:
615 status = smartcard_ListReadersA_decode_request(s, operation);
618 case SCARD_IOCTL_LISTREADERSW:
619 status = smartcard_ListReadersW_decode_request(s, operation);
622 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
623 status = smartcard_ContextAndStringA_decode_request(s, operation);
626 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
627 status = smartcard_ContextAndStringW_decode_request(s, operation);
630 case SCARD_IOCTL_FORGETREADERGROUPA:
631 status = smartcard_ContextAndStringA_decode_request(s, operation);
634 case SCARD_IOCTL_FORGETREADERGROUPW:
635 status = smartcard_ContextAndStringW_decode_request(s, operation);
638 case SCARD_IOCTL_INTRODUCEREADERA:
639 status = smartcard_ContextAndTwoStringA_decode_request(s, operation);
642 case SCARD_IOCTL_INTRODUCEREADERW:
643 status = smartcard_ContextAndTwoStringW_decode_request(s, operation);
646 case SCARD_IOCTL_FORGETREADERA:
647 status = smartcard_ContextAndStringA_decode_request(s, operation);
650 case SCARD_IOCTL_FORGETREADERW:
651 status = smartcard_ContextAndStringW_decode_request(s, operation);
654 case SCARD_IOCTL_ADDREADERTOGROUPA:
655 status = smartcard_ContextAndTwoStringA_decode_request(s, operation);
658 case SCARD_IOCTL_ADDREADERTOGROUPW:
659 status = smartcard_ContextAndTwoStringW_decode_request(s, operation);
662 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
663 status = smartcard_ContextAndTwoStringA_decode_request(s, operation);
666 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
667 status = smartcard_ContextAndTwoStringW_decode_request(s, operation);
670 case SCARD_IOCTL_LOCATECARDSA:
671 status = smartcard_LocateCardsA_decode_request(s, operation);
674 case SCARD_IOCTL_LOCATECARDSW:
675 status = smartcard_LocateCardsW_decode_request(s, operation);
678 case SCARD_IOCTL_GETSTATUSCHANGEA:
679 status = smartcard_GetStatusChangeA_decode_request(s, operation);
682 case SCARD_IOCTL_GETSTATUSCHANGEW:
683 status = smartcard_GetStatusChangeW_decode_request(s, operation);
686 case SCARD_IOCTL_CANCEL:
687 status = smartcard_Cancel_decode_request(s, operation);
690 case SCARD_IOCTL_CONNECTA:
691 status = smartcard_ConnectA_decode_request(s, operation);
694 case SCARD_IOCTL_CONNECTW:
695 status = smartcard_ConnectW_decode_request(s, operation);
698 case SCARD_IOCTL_RECONNECT:
699 status = smartcard_Reconnect_decode_request(s, operation);
702 case SCARD_IOCTL_DISCONNECT:
703 status = smartcard_Disconnect_decode_request(s, operation);
706 case SCARD_IOCTL_BEGINTRANSACTION:
707 status = smartcard_BeginTransaction_decode_request(s, operation);
710 case SCARD_IOCTL_ENDTRANSACTION:
711 status = smartcard_EndTransaction_decode_request(s, operation);
714 case SCARD_IOCTL_STATE:
715 status = smartcard_State_decode_request(s, operation);
718 case SCARD_IOCTL_STATUSA:
719 status = smartcard_StatusA_decode_request(s, operation);
722 case SCARD_IOCTL_STATUSW:
723 status = smartcard_StatusW_decode_request(s, operation);
726 case SCARD_IOCTL_TRANSMIT:
727 status = smartcard_Transmit_decode_request(s, operation);
730 case SCARD_IOCTL_CONTROL:
731 status = smartcard_Control_decode_request(s, operation);
734 case SCARD_IOCTL_GETATTRIB:
735 status = smartcard_GetAttrib_decode_request(s, operation);
738 case SCARD_IOCTL_SETATTRIB:
739 status = smartcard_SetAttrib_decode_request(s, operation);
742 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
743 status = smartcard_AccessStartedEvent_decode_request(s, operation);
746 case SCARD_IOCTL_LOCATECARDSBYATRA:
747 status = smartcard_LocateCardsByATRA_decode_request(s, operation);
750 case SCARD_IOCTL_LOCATECARDSBYATRW:
751 status = smartcard_LocateCardsByATRW_decode_request(s, operation);
754 case SCARD_IOCTL_READCACHEA:
755 status = smartcard_ReadCacheA_decode_request(s, operation);
758 case SCARD_IOCTL_READCACHEW:
759 status = smartcard_ReadCacheW_decode_request(s, operation);
762 case SCARD_IOCTL_WRITECACHEA:
763 status = smartcard_WriteCacheA_decode_request(s, operation);
766 case SCARD_IOCTL_WRITECACHEW:
767 status = smartcard_WriteCacheW_decode_request(s, operation);
770 case SCARD_IOCTL_GETTRANSMITCOUNT:
771 status = smartcard_GetTransmitCount_decode_request(s, operation);
774 case SCARD_IOCTL_RELEASETARTEDEVENT:
775 status = smartcard_ReleaseStartedEvent_decode_request(s, operation);
778 case SCARD_IOCTL_GETREADERICON:
779 status = smartcard_GetReaderIcon_decode_request(s, operation);
782 case SCARD_IOCTL_GETDEVICETYPEID:
783 status = smartcard_GetDeviceTypeId_decode_request(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 if (smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8) < 0)
798 return STATUS_INVALID_PARAMETER;
801 if (Stream_GetPosition(s) < Stream_Length(s))
803 size_t difference = 0;
804 difference = Stream_Length(s) - Stream_GetPosition(s);
806 "IRP was not fully parsed %s (%s [0x%08" PRIX32
"]): Actual: %" PRIuz
807 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
808 scard_get_ioctl_string(ioControlCode, TRUE),
809 scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
810 Stream_GetPosition(s), Stream_Length(s), difference);
811 winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
814 if (Stream_GetPosition(s) > Stream_Length(s))
816 size_t difference = 0;
817 difference = Stream_GetPosition(s) - Stream_Length(s);
819 "IRP was parsed beyond its end %s (0x%08" PRIX32
"): Actual: %" PRIuz
820 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
821 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
822 Stream_Length(s), difference);
831 WINPR_ASSERT(operation);
833 return smartcard_unpack_establish_context_return(s, &operation->
ret.establishContext);
839 WINPR_ASSERT(operation);
842 smartcard_trace_long_return(&ret,
"ReleaseContext");
843 return SCARD_S_SUCCESS;
849 WINPR_ASSERT(operation);
852 smartcard_trace_long_return(&ret,
"IsValidContext");
853 return SCARD_S_SUCCESS;
859 WINPR_ASSERT(operation);
861 return smartcard_unpack_list_reader_groups_return(s, &operation->
ret.listReaders, FALSE);
867 WINPR_ASSERT(operation);
869 return smartcard_unpack_list_reader_groups_return(s, &operation->
ret.listReaders, TRUE);
875 WINPR_ASSERT(operation);
877 return smartcard_unpack_list_readers_return(s, &operation->
ret.listReaders, FALSE);
883 WINPR_ASSERT(operation);
885 return smartcard_unpack_list_readers_return(s, &operation->
ret.listReaders, TRUE);
891 WINPR_ASSERT(operation);
893 return smartcard_unpack_get_status_change_return(s, &operation->
ret.getStatusChange, FALSE);
899 WINPR_ASSERT(operation);
901 return smartcard_unpack_get_status_change_return(s, &operation->
ret.getStatusChange, TRUE);
907 WINPR_ASSERT(operation);
910 smartcard_trace_long_return(&ret,
"Cancel");
911 return SCARD_S_SUCCESS;
917 WINPR_ASSERT(operation);
919 return smartcard_unpack_connect_return(s, &operation->
ret.connect);
925 WINPR_ASSERT(operation);
927 return smartcard_unpack_connect_return(s, &operation->
ret.connect);
933 WINPR_ASSERT(operation);
935 return smartcard_unpack_reconnect_return(s, &operation->
ret.reconnect);
941 WINPR_ASSERT(operation);
944 smartcard_trace_long_return(&ret,
"Disconnect");
945 return SCARD_S_SUCCESS;
951 WINPR_ASSERT(operation);
954 smartcard_trace_long_return(&ret,
"BeginTransaction");
955 return SCARD_S_SUCCESS;
961 WINPR_ASSERT(operation);
964 smartcard_trace_long_return(&ret,
"EndTransaction");
965 return SCARD_S_SUCCESS;
971 WINPR_ASSERT(operation);
973 return smartcard_unpack_status_return(s, &operation->
ret.status, FALSE);
979 WINPR_ASSERT(operation);
981 return smartcard_unpack_status_return(s, &operation->
ret.status, TRUE);
987 WINPR_ASSERT(operation);
989 return smartcard_unpack_transmit_return(s, &operation->
ret.transmit);
995 WINPR_ASSERT(operation);
997 return smartcard_unpack_control_return(s, &operation->
ret.control);
1003 WINPR_ASSERT(operation);
1005 return smartcard_unpack_get_attrib_return(s, &operation->
ret.getAttrib);
1011 WINPR_ASSERT(operation);
1014 smartcard_trace_long_return(&ret,
"SetAttrib");
1015 return SCARD_S_SUCCESS;
1018LONG smartcard_irp_device_control_decode_response(
wStream* s, UINT32 ioControlCode,
1021 LONG status = SCARD_S_SUCCESS;
1024 WINPR_ASSERT(operation);
1026 if (!Stream_CheckAndLogRequiredLength(TAG, s, RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH))
1027 return SCARD_F_INTERNAL_ERROR;
1029 const size_t startPosition = Stream_GetPosition(s);
1031 const UINT32 outputBufferLength = Stream_Get_UINT32(s);
1032 operation->ioControlCode = ioControlCode;
1033 operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
1034 operation->outputBufferLength = outputBufferLength;
1036 if (outputBufferLength == 0)
1037 return SCARD_S_SUCCESS;
1039 if (!Stream_CheckAndLogRequiredLength(TAG, s, outputBufferLength))
1040 return SCARD_F_INTERNAL_ERROR;
1042 status = smartcard_unpack_common_type_header(s);
1043 if (status != SCARD_S_SUCCESS)
1046 status = smartcard_unpack_private_type_header(s);
1047 if (status != SCARD_S_SUCCESS)
1050 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1051 return SCARD_F_INTERNAL_ERROR;
1055 if (operation->
returnCode != SCARD_S_SUCCESS)
1057 WLog_WARN(TAG,
"%s failed with ReturnCode %s [0x%08" PRIX32
"]",
1058 scard_get_ioctl_string(ioControlCode, TRUE),
1060 return SCARD_S_SUCCESS;
1063 switch (ioControlCode)
1065 case SCARD_IOCTL_ESTABLISHCONTEXT:
1066 status = smartcard_EstablishContext_decode_response(s, operation);
1069 case SCARD_IOCTL_RELEASECONTEXT:
1070 status = smartcard_ReleaseContext_decode_response(s, operation);
1073 case SCARD_IOCTL_ISVALIDCONTEXT:
1074 status = smartcard_IsValidContext_decode_response(s, operation);
1077 case SCARD_IOCTL_LISTREADERGROUPSA:
1078 status = smartcard_ListReaderGroupsA_decode_response(s, operation);
1081 case SCARD_IOCTL_LISTREADERGROUPSW:
1082 status = smartcard_ListReaderGroupsW_decode_response(s, operation);
1085 case SCARD_IOCTL_LISTREADERSA:
1086 status = smartcard_ListReadersA_decode_response(s, operation);
1089 case SCARD_IOCTL_LISTREADERSW:
1090 status = smartcard_ListReadersW_decode_response(s, operation);
1093 case SCARD_IOCTL_GETSTATUSCHANGEA:
1094 status = smartcard_GetStatusChangeA_decode_response(s, operation);
1097 case SCARD_IOCTL_GETSTATUSCHANGEW:
1098 status = smartcard_GetStatusChangeW_decode_response(s, operation);
1101 case SCARD_IOCTL_CANCEL:
1102 status = smartcard_Cancel_decode_response(s, operation);
1105 case SCARD_IOCTL_CONNECTA:
1106 status = smartcard_ConnectA_decode_response(s, operation);
1109 case SCARD_IOCTL_CONNECTW:
1110 status = smartcard_ConnectW_decode_response(s, operation);
1113 case SCARD_IOCTL_RECONNECT:
1114 status = smartcard_Reconnect_decode_response(s, operation);
1117 case SCARD_IOCTL_DISCONNECT:
1118 status = smartcard_Disconnect_decode_response(s, operation);
1121 case SCARD_IOCTL_BEGINTRANSACTION:
1122 status = smartcard_BeginTransaction_decode_response(s, operation);
1125 case SCARD_IOCTL_ENDTRANSACTION:
1126 status = smartcard_EndTransaction_decode_response(s, operation);
1129 case SCARD_IOCTL_STATUSA:
1130 status = smartcard_StatusA_decode_response(s, operation);
1133 case SCARD_IOCTL_STATUSW:
1134 status = smartcard_StatusW_decode_response(s, operation);
1137 case SCARD_IOCTL_TRANSMIT:
1138 status = smartcard_Transmit_decode_response(s, operation);
1141 case SCARD_IOCTL_CONTROL:
1142 status = smartcard_Control_decode_response(s, operation);
1145 case SCARD_IOCTL_GETATTRIB:
1146 status = smartcard_GetAttrib_decode_response(s, operation);
1149 case SCARD_IOCTL_SETATTRIB:
1150 status = smartcard_SetAttrib_decode_response(s, operation);
1154 WLog_WARN(TAG,
"unsupported response for %s (0x%08" PRIX32
")",
1155 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode);
1159 if (status != SCARD_S_SUCCESS)
1162 const size_t offset = startPosition + RDPDR_DEVICE_IO_CONTROL_RSP_HDR_LENGTH;
1163 if (smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8) < 0)
1164 return STATUS_INVALID_PARAMETER;
1169static LONG smartcard_EstablishContext_encode_request(
wStream* s,
1173 WINPR_ASSERT(operation);
1175 return smartcard_pack_establish_context_call(s, &operation->call.establishContext);
1178static LONG smartcard_ReleaseContext_encode_request(
wStream* s,
1182 WINPR_ASSERT(operation);
1184 return smartcard_pack_context_call(s, &operation->call.context,
"ReleaseContext");
1187static LONG smartcard_IsValidContext_encode_request(
wStream* s,
1191 WINPR_ASSERT(operation);
1193 return smartcard_pack_context_call(s, &operation->call.context,
"IsValidContext");
1196static LONG smartcard_ListReaderGroupsA_encode_request(
wStream* s,
1200 WINPR_ASSERT(operation);
1202 return smartcard_pack_list_reader_groups_call(s, &operation->call.listReaderGroups, FALSE);
1205static LONG smartcard_ListReaderGroupsW_encode_request(
wStream* s,
1209 WINPR_ASSERT(operation);
1211 return smartcard_pack_list_reader_groups_call(s, &operation->call.listReaderGroups, TRUE);
1217 WINPR_ASSERT(operation);
1219 return smartcard_pack_list_readers_call(s, &operation->call.listReaders, FALSE);
1225 WINPR_ASSERT(operation);
1227 return smartcard_pack_list_readers_call(s, &operation->call.listReaders, TRUE);
1230static LONG smartcard_GetStatusChangeA_encode_request(
wStream* s,
1234 WINPR_ASSERT(operation);
1236 return smartcard_pack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
1239static LONG smartcard_GetStatusChangeW_encode_request(
wStream* s,
1243 WINPR_ASSERT(operation);
1245 return smartcard_pack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
1251 WINPR_ASSERT(operation);
1253 return smartcard_pack_context_call(s, &operation->call.context,
"Cancel");
1259 WINPR_ASSERT(operation);
1261 return smartcard_pack_connect_a_call(s, &operation->call.connectA);
1267 WINPR_ASSERT(operation);
1269 return smartcard_pack_connect_w_call(s, &operation->call.connectW);
1275 WINPR_ASSERT(operation);
1277 return smartcard_pack_reconnect_call(s, &operation->call.reconnect);
1283 WINPR_ASSERT(operation);
1285 return smartcard_pack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
1289static LONG smartcard_BeginTransaction_encode_request(
wStream* s,
1293 WINPR_ASSERT(operation);
1295 return smartcard_pack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
1296 "BeginTransaction");
1299static LONG smartcard_EndTransaction_encode_request(
wStream* s,
1303 WINPR_ASSERT(operation);
1305 return smartcard_pack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
1312 WINPR_ASSERT(operation);
1314 return smartcard_pack_status_call(s, &operation->call.status, FALSE);
1320 WINPR_ASSERT(operation);
1322 return smartcard_pack_status_call(s, &operation->call.status, TRUE);
1328 WINPR_ASSERT(operation);
1330 return smartcard_pack_transmit_call(s, &operation->call.transmit);
1336 WINPR_ASSERT(operation);
1338 return smartcard_pack_control_call(s, &operation->call.control);
1344 WINPR_ASSERT(operation);
1346 return smartcard_pack_get_attrib_call(s, &operation->call.getAttrib);
1352 WINPR_ASSERT(operation);
1354 return smartcard_pack_set_attrib_call(s, &operation->call.setAttrib);
1359 LONG status = SCARD_S_SUCCESS;
1362 WINPR_ASSERT(operation);
1364 const UINT32 ioControlCode = operation->ioControlCode;
1366 const size_t headerPos = Stream_GetPosition(s);
1367 Stream_Zero(s, SMARTCARD_COMMON_TYPE_HEADER_LENGTH);
1368 Stream_Zero(s, SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH);
1370 switch (ioControlCode)
1372 case SCARD_IOCTL_ESTABLISHCONTEXT:
1373 status = smartcard_EstablishContext_encode_request(s, operation);
1376 case SCARD_IOCTL_RELEASECONTEXT:
1377 status = smartcard_ReleaseContext_encode_request(s, operation);
1380 case SCARD_IOCTL_ISVALIDCONTEXT:
1381 status = smartcard_IsValidContext_encode_request(s, operation);
1384 case SCARD_IOCTL_LISTREADERGROUPSA:
1385 status = smartcard_ListReaderGroupsA_encode_request(s, operation);
1388 case SCARD_IOCTL_LISTREADERGROUPSW:
1389 status = smartcard_ListReaderGroupsW_encode_request(s, operation);
1392 case SCARD_IOCTL_LISTREADERSA:
1393 status = smartcard_ListReadersA_encode_request(s, operation);
1396 case SCARD_IOCTL_LISTREADERSW:
1397 status = smartcard_ListReadersW_encode_request(s, operation);
1400 case SCARD_IOCTL_GETSTATUSCHANGEA:
1401 status = smartcard_GetStatusChangeA_encode_request(s, operation);
1404 case SCARD_IOCTL_GETSTATUSCHANGEW:
1405 status = smartcard_GetStatusChangeW_encode_request(s, operation);
1408 case SCARD_IOCTL_CANCEL:
1409 status = smartcard_Cancel_encode_request(s, operation);
1412 case SCARD_IOCTL_CONNECTA:
1413 status = smartcard_ConnectA_encode_request(s, operation);
1416 case SCARD_IOCTL_CONNECTW:
1417 status = smartcard_ConnectW_encode_request(s, operation);
1420 case SCARD_IOCTL_RECONNECT:
1421 status = smartcard_Reconnect_encode_request(s, operation);
1424 case SCARD_IOCTL_DISCONNECT:
1425 status = smartcard_Disconnect_encode_request(s, operation);
1428 case SCARD_IOCTL_BEGINTRANSACTION:
1429 status = smartcard_BeginTransaction_encode_request(s, operation);
1432 case SCARD_IOCTL_ENDTRANSACTION:
1433 status = smartcard_EndTransaction_encode_request(s, operation);
1436 case SCARD_IOCTL_STATUSA:
1437 status = smartcard_StatusA_encode_request(s, operation);
1440 case SCARD_IOCTL_STATUSW:
1441 status = smartcard_StatusW_encode_request(s, operation);
1444 case SCARD_IOCTL_TRANSMIT:
1445 status = smartcard_Transmit_encode_request(s, operation);
1448 case SCARD_IOCTL_CONTROL:
1449 status = smartcard_Control_encode_request(s, operation);
1452 case SCARD_IOCTL_GETATTRIB:
1453 status = smartcard_GetAttrib_encode_request(s, operation);
1456 case SCARD_IOCTL_SETATTRIB:
1457 status = smartcard_SetAttrib_encode_request(s, operation);
1461 WLog_WARN(TAG,
"unsupported request for %s (0x%08" PRIX32
")",
1462 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode);
1463 return SCARD_E_UNSUPPORTED_FEATURE;
1466 if (status != SCARD_S_SUCCESS)
1469 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
1470 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
1472 const LONG rc = smartcard_pack_write_size_align(s, Stream_GetPosition(s), 8);
1473 if (rc != SCARD_S_SUCCESS)
1477 const size_t dataEndPos = Stream_GetPosition(s);
1478 const size_t payloadSize = dataEndPos - headerPos;
1479 const size_t objectBufferLength =
1480 payloadSize - SMARTCARD_COMMON_TYPE_HEADER_LENGTH - SMARTCARD_PRIVATE_TYPE_HEADER_LENGTH;
1482 status = smartcard_pack_write_size_align(s, payloadSize, 8);
1483 if (status != SCARD_S_SUCCESS)
1486 const size_t endPos = Stream_GetPosition(s);
1487 if (!Stream_SetPosition(s, headerPos))
1488 return SCARD_E_BAD_SEEK;
1489 smartcard_pack_common_type_header(s);
1490 smartcard_pack_private_type_header(s, (UINT32)objectBufferLength);
1491 if (!Stream_SetPosition(s, endPos))
1492 return SCARD_E_BAD_SEEK;
1493 Stream_SealLength(s);
1500 for (UINT32 x = 0; x < cReaders; x++)
1503 free(state->szReader);
1506 free(rgReaderStates);
1511 for (UINT32 x = 0; x < cReaders; x++)
1514 free(state->szReader);
1517 free(rgReaderStates);
1526 switch (op->ioControlCode)
1528 case SCARD_IOCTL_CANCEL:
1529 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
1530 case SCARD_IOCTL_RELEASETARTEDEVENT:
1531 case SCARD_IOCTL_LISTREADERGROUPSA:
1532 case SCARD_IOCTL_LISTREADERGROUPSW:
1533 case SCARD_IOCTL_RECONNECT:
1534 case SCARD_IOCTL_DISCONNECT:
1535 case SCARD_IOCTL_BEGINTRANSACTION:
1536 case SCARD_IOCTL_ENDTRANSACTION:
1537 case SCARD_IOCTL_STATE:
1538 case SCARD_IOCTL_STATUSA:
1539 case SCARD_IOCTL_STATUSW:
1540 case SCARD_IOCTL_ESTABLISHCONTEXT:
1541 case SCARD_IOCTL_RELEASECONTEXT:
1542 case SCARD_IOCTL_ISVALIDCONTEXT:
1543 case SCARD_IOCTL_GETATTRIB:
1544 case SCARD_IOCTL_GETTRANSMITCOUNT:
1546 case SCARD_IOCTL_LOCATECARDSA:
1549 free(call->mszCards);
1551 free_reader_states_a(call->rgReaderStates, call->cReaders);
1554 case SCARD_IOCTL_LOCATECARDSW:
1557 free(call->mszCards);
1559 free_reader_states_w(call->rgReaderStates, call->cReaders);
1562 case SCARD_IOCTL_LOCATECARDSBYATRA:
1566 free_reader_states_a(call->rgReaderStates, call->cReaders);
1569 case SCARD_IOCTL_LOCATECARDSBYATRW:
1572 free_reader_states_w(call->rgReaderStates, call->cReaders);
1575 case SCARD_IOCTL_FORGETREADERA:
1576 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
1577 case SCARD_IOCTL_FORGETREADERGROUPA:
1583 case SCARD_IOCTL_FORGETREADERW:
1584 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
1585 case SCARD_IOCTL_FORGETREADERGROUPW:
1591 case SCARD_IOCTL_INTRODUCEREADERA:
1592 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
1593 case SCARD_IOCTL_ADDREADERTOGROUPA:
1600 case SCARD_IOCTL_INTRODUCEREADERW:
1601 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
1602 case SCARD_IOCTL_ADDREADERTOGROUPW:
1609 case SCARD_IOCTL_LISTREADERSA:
1610 case SCARD_IOCTL_LISTREADERSW:
1613 free(call->mszGroups);
1616 case SCARD_IOCTL_GETSTATUSCHANGEA:
1619 free_reader_states_a(call->rgReaderStates, call->cReaders);
1622 case SCARD_IOCTL_GETSTATUSCHANGEW:
1625 free_reader_states_w(call->rgReaderStates, call->cReaders);
1628 case SCARD_IOCTL_GETREADERICON:
1631 free(call->szReaderName);
1634 case SCARD_IOCTL_GETDEVICETYPEID:
1637 free(call->szReaderName);
1640 case SCARD_IOCTL_CONNECTA:
1643 free(call->szReader);
1646 case SCARD_IOCTL_CONNECTW:
1649 free(call->szReader);
1652 case SCARD_IOCTL_SETATTRIB:
1653 free(op->call.setAttrib.pbAttr);
1655 case SCARD_IOCTL_TRANSMIT:
1658 free(call->pbSendBuffer);
1659 free(call->pioSendPci);
1660 free(call->pioRecvPci);
1663 case SCARD_IOCTL_CONTROL:
1666 free(call->pvInBuffer);
1669 case SCARD_IOCTL_READCACHEA:
1672 free(call->szLookupName);
1673 free(call->Common.CardIdentifier);
1676 case SCARD_IOCTL_READCACHEW:
1679 free(call->szLookupName);
1680 free(call->Common.CardIdentifier);
1683 case SCARD_IOCTL_WRITECACHEA:
1686 free(call->szLookupName);
1687 free(call->Common.CardIdentifier);
1688 free(call->Common.pbData);
1691 case SCARD_IOCTL_WRITECACHEW:
1694 free(call->szLookupName);
1695 free(call->Common.CardIdentifier);
1696 free(call->Common.pbData);
1704 switch (op->ioControlCode)
1706 case SCARD_IOCTL_LISTREADERSA:
1707 case SCARD_IOCTL_LISTREADERSW:
1708 case SCARD_IOCTL_LISTREADERGROUPSA:
1709 case SCARD_IOCTL_LISTREADERGROUPSW:
1715 case SCARD_IOCTL_STATUSA:
1716 case SCARD_IOCTL_STATUSW:
1719 free(ret->mszReaderNames);
1722 case SCARD_IOCTL_GETSTATUSCHANGEA:
1723 case SCARD_IOCTL_GETSTATUSCHANGEW:
1726 free(ret->rgReaderStates);
1729 case SCARD_IOCTL_TRANSMIT:
1732 free(ret->pbRecvBuffer);
1733 free(ret->pioRecvPci);
1736 case SCARD_IOCTL_CONTROL:
1739 free(call->pvOutBuffer);
1742 case SCARD_IOCTL_GETATTRIB:
union SMARTCARD_OPERATION::@30 ret