20#include <winpr/stream.h>
21#include <freerdp/channels/scard.h>
22#include <freerdp/utils/smartcard_pack.h>
26static wStream* build_locate_cards_by_atr_a(UINT32 cbAtr)
32 Stream_Write_UINT32(s, 0);
33 Stream_Write_UINT32(s, 0);
34 Stream_Write_UINT32(s, 1);
35 Stream_Write_UINT32(s, 0x00020000);
36 Stream_Write_UINT32(s, 0);
37 Stream_Write_UINT32(s, 0);
38 Stream_Write_UINT32(s, 1);
39 Stream_Write_UINT32(s, cbAtr);
44 if (!Stream_SetPosition(s, 0))
52static BOOL run_case(UINT32 cbAtr, BOOL expectAccept)
54 wStream* s = build_locate_cards_by_atr_a(cbAtr);
59 const LONG status = smartcard_unpack_locate_cards_by_atr_a_call(s, &call);
62 const BOOL accepted = status == SCARD_S_SUCCESS;
63 if (accepted != expectAccept)
65 printf(
"cbAtr=%" PRIu32
": expected %s, unpack returned 0x%08" PRIX32
"\n", cbAtr,
66 expectAccept ?
"accept" :
"reject", (UINT32)status);
67 free(call.rgAtrMasks);
71 free(call.rgAtrMasks);
77static wStream* build_set_attrib(UINT32 cbAttr, UINT32 cbAttrLen)
79 const UINT32 pad = (4 - (cbAttr % 4)) % 4;
80 wStream* s = Stream_New(
nullptr, 28 + 4 + cbAttr + pad);
84 Stream_Write_UINT32(s, 0);
85 Stream_Write_UINT32(s, 0);
86 Stream_Write_UINT32(s, 0);
87 Stream_Write_UINT32(s, 0x00020000);
88 Stream_Write_UINT32(s, 0);
89 Stream_Write_UINT32(s, cbAttrLen);
90 Stream_Write_UINT32(s, 0x00020004);
91 Stream_Write_UINT32(s, cbAttr);
92 Stream_Zero(s, cbAttr);
97 if (!Stream_SetPosition(s, 0))
107static BOOL run_set_attrib_case(UINT32 cbAttr, UINT32 cbAttrLen)
109 wStream* s = build_set_attrib(cbAttr, cbAttrLen);
114 const LONG status = smartcard_unpack_set_attrib_call(s, &call);
115 Stream_Free(s, TRUE);
118 if (status != SCARD_S_SUCCESS)
120 printf(
"set_attrib cbAttr=%" PRIu32
": unpack returned 0x%08" PRIX32
"\n", cbAttr,
124 else if (call.cbAttrLen > cbAttr)
126 printf(
"set_attrib cbAttr=%" PRIu32
": cbAttrLen=%" PRIu32
" exceeds payload\n", cbAttr,
135int TestSmartcardPack(
int argc,
char* argv[])
141 if (!run_case(0, TRUE))
143 if (!run_case(36, TRUE))
147 if (!run_case(37, FALSE))
149 if (!run_case(0xFFFFFFFF, FALSE))
153 if (!run_set_attrib_case(1, 0xFFFFFFFF))
155 if (!run_set_attrib_case(5, 0xFFFFFFFF))
158 if (!run_set_attrib_case(4, 0xFFFFFFFF))
160 if (!run_set_attrib_case(8, 2))