1 |
/* OpenPGP Smart Card Mini Driver |
2 |
Copyright (C) 2009 Vincent Le Toux |
3 |
|
4 |
This library is Free software; you can redistribute it and/or |
5 |
modify it under the terms of the GNU Lesser General Public |
6 |
License version 2.1 as published by the Free Software Foundation. |
7 |
|
8 |
This library is distributed in the hope that it will be useful, |
9 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 |
Lesser General Public License for more details. |
12 |
|
13 |
You should have received a copy of the GNU Lesser General Public |
14 |
License along with this library; if not, write to the Free Software |
15 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
16 |
*/ |
17 |
|
18 |
#include <windows.h> |
19 |
#include <cardmod.h> |
20 |
#include "Tracing.h" |
21 |
#include "Context.h" |
22 |
#include "CryptoOperations.h" |
23 |
#include "PinOperations.h" |
24 |
|
25 |
// 4.4 Card capabilities |
26 |
|
27 |
/** This function queries the card and card-specific minidriver combination |
28 |
for the functionality that is provided at this level, such as certificate or |
29 |
file compression.*/ |
30 |
|
31 |
DWORD WINAPI CardQueryCapabilities( |
32 |
__in PCARD_DATA pCardData, |
33 |
__inout PCARD_CAPABILITIES pCardCapabilities |
34 |
) |
35 |
{ |
36 |
DWORD dwReturn = 0, dwVersion; |
37 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter"); |
38 |
__try |
39 |
{ |
40 |
if ( pCardData == NULL ) |
41 |
{ |
42 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); |
43 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
44 |
__leave; |
45 |
} |
46 |
if ( pCardCapabilities == NULL ) |
47 |
{ |
48 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardCapabilities == NULL"); |
49 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
50 |
__leave; |
51 |
} |
52 |
dwVersion = (pCardCapabilities->dwVersion == 0) ? 1 : pCardCapabilities->dwVersion; |
53 |
if ( dwVersion != CARD_CAPABILITIES_CURRENT_VERSION ) |
54 |
{ |
55 |
Trace(WINEVENT_LEVEL_ERROR, L"dwVersion %d", dwVersion); |
56 |
dwReturn = ERROR_REVISION_MISMATCH; |
57 |
__leave; |
58 |
} |
59 |
pCardCapabilities->fCertificateCompression = TRUE; |
60 |
pCardCapabilities->fKeyGen = TRUE; |
61 |
dwReturn = 0; |
62 |
} |
63 |
__finally |
64 |
{ |
65 |
} |
66 |
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); |
67 |
return dwReturn; |
68 |
} |
69 |
|
70 |
// 4.5 Card and container properties |
71 |
|
72 |
/** The CardGetContainerProperty function is modeled after the query |
73 |
functions of CAPI for keys. It takes a LPWSTR that indicates which parameter |
74 |
is being requested. Then it returns data written into the pbData parameter.*/ |
75 |
|
76 |
DWORD WINAPI CardGetContainerProperty( |
77 |
__in PCARD_DATA pCardData, |
78 |
__in BYTE bContainerIndex, |
79 |
__in LPCWSTR wszProperty, |
80 |
__out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData, |
81 |
__in DWORD cbData, |
82 |
__out PDWORD pdwDataLen, |
83 |
__in DWORD dwFlags |
84 |
) |
85 |
{ |
86 |
DWORD dwReturn = 0; |
87 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex = %d wszProperty = %s", bContainerIndex, wszProperty); |
88 |
__try |
89 |
{ |
90 |
if ( pCardData == NULL ) |
91 |
{ |
92 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); |
93 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
94 |
__leave; |
95 |
} |
96 |
if ( pdwDataLen == NULL ) |
97 |
{ |
98 |
Trace(WINEVENT_LEVEL_ERROR, L"pdwDataLen == NULL"); |
99 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
100 |
__leave; |
101 |
} |
102 |
if ( wszProperty == NULL ) |
103 |
{ |
104 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL"); |
105 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
106 |
__leave; |
107 |
} |
108 |
if (dwFlags) |
109 |
{ |
110 |
Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); |
111 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
112 |
__leave; |
113 |
} |
114 |
if (bContainerIndex >= MaxContainer) |
115 |
{ |
116 |
Trace(WINEVENT_LEVEL_ERROR, L"bContainerIndex == %d", bContainerIndex); |
117 |
dwReturn = SCARD_E_NO_KEY_CONTAINER ; |
118 |
__leave; |
119 |
} |
120 |
if (wcscmp(wszProperty,CCP_CONTAINER_INFO) == 0) |
121 |
{ |
122 |
if (cbData < sizeof(CONTAINER_INFO)) |
123 |
{ |
124 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
125 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
126 |
__leave; |
127 |
} |
128 |
*pdwDataLen = cbData; |
129 |
dwReturn = CardGetContainerInfo(pCardData, bContainerIndex, dwFlags, (PCONTAINER_INFO) pbData); |
130 |
} |
131 |
else if (wcscmp(wszProperty,CCP_PIN_IDENTIFIER) == 0) |
132 |
{ |
133 |
if (cbData < sizeof(PIN_ID)) |
134 |
{ |
135 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
136 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
137 |
__leave; |
138 |
} |
139 |
*pdwDataLen = cbData; |
140 |
if(bContainerIndex >= MaxContainer) |
141 |
{ |
142 |
dwReturn = SCARD_E_NO_KEY_CONTAINER; |
143 |
Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", bContainerIndex); |
144 |
__leave; |
145 |
} |
146 |
(*(PDWORD)pbData) = Containers[bContainerIndex].PinId; |
147 |
dwReturn = 0; |
148 |
} |
149 |
/*else if (wcscmp(wszProperty,CCP_ASSOCIATED_ECDH_KEY) == 0) |
150 |
{ |
151 |
}*/ |
152 |
else |
153 |
{ |
154 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty); |
155 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
156 |
__leave; |
157 |
} |
158 |
} |
159 |
__finally |
160 |
{ |
161 |
} |
162 |
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); |
163 |
return dwReturn; |
164 |
} |
165 |
|
166 |
/** This function sets the properties on containers. Only two container |
167 |
properties are supported: |
168 |
CCP_PIN_IDENTIFIER |
169 |
CCP_ASSOCIATED_ECDH_KEY |
170 |
*/ |
171 |
|
172 |
DWORD WINAPI CardSetContainerProperty( |
173 |
__in PCARD_DATA pCardData, |
174 |
__in BYTE bContainerIndex, |
175 |
__in LPCWSTR wszProperty, |
176 |
__in_bcount(cbDataLen) PBYTE pbData, |
177 |
__in DWORD cbDataLen, |
178 |
__in DWORD dwFlags |
179 |
) |
180 |
{ |
181 |
DWORD dwReturn = 0; |
182 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter bContainerIndex = %d wszProperty = %s", bContainerIndex, wszProperty); |
183 |
__try |
184 |
{ |
185 |
if ( pCardData == NULL ) |
186 |
{ |
187 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); |
188 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
189 |
__leave; |
190 |
} |
191 |
if ( wszProperty == NULL ) |
192 |
{ |
193 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL"); |
194 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
195 |
__leave; |
196 |
} |
197 |
if ( pbData == NULL ) |
198 |
{ |
199 |
Trace(WINEVENT_LEVEL_ERROR, L"pbData == NULL"); |
200 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
201 |
__leave; |
202 |
} |
203 |
if (dwFlags) |
204 |
{ |
205 |
Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); |
206 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
207 |
__leave; |
208 |
} |
209 |
if (wcscmp(wszProperty,CCP_PIN_IDENTIFIER) == 0) |
210 |
{ |
211 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
212 |
__leave; |
213 |
} |
214 |
else if (wcscmp(wszProperty,CCP_ASSOCIATED_ECDH_KEY) == 0) |
215 |
{ |
216 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
217 |
__leave; |
218 |
} |
219 |
else |
220 |
{ |
221 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty); |
222 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
223 |
__leave; |
224 |
} |
225 |
|
226 |
} |
227 |
__finally |
228 |
{ |
229 |
} |
230 |
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); |
231 |
return dwReturn; |
232 |
} |
233 |
|
234 |
/** The CardGetProperty function is modeled after the query functions of |
235 |
CAPI for keys. It takes a LPWSTR that indicates which parameter is being |
236 |
requested. The function returns data in the pbData parameter.*/ |
237 |
|
238 |
DWORD WINAPI CardGetProperty( |
239 |
__in PCARD_DATA pCardData, |
240 |
__in LPCWSTR wszProperty, |
241 |
__out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData, |
242 |
__in DWORD cbData, |
243 |
__out PDWORD pdwDataLen, |
244 |
__in DWORD dwFlags |
245 |
) |
246 |
{ |
247 |
DWORD dwReturn = 0; |
248 |
PBYTE pbTempData = NULL; |
249 |
DWORD dwTempSize = 0; |
250 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter wszProperty = %s", wszProperty); |
251 |
__try |
252 |
{ |
253 |
if ( pCardData == NULL ) |
254 |
{ |
255 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); |
256 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
257 |
__leave; |
258 |
} |
259 |
if ( wszProperty == NULL ) |
260 |
{ |
261 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL"); |
262 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
263 |
__leave; |
264 |
} |
265 |
if ( pdwDataLen == NULL ) |
266 |
{ |
267 |
Trace(WINEVENT_LEVEL_ERROR, L"pdwDataLen == NULL"); |
268 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
269 |
__leave; |
270 |
} |
271 |
if (wcscmp(wszProperty,CP_CARD_FREE_SPACE) == 0) |
272 |
{ |
273 |
*pdwDataLen = sizeof(CARD_FREE_SPACE_INFO); |
274 |
if (cbData < *pdwDataLen) |
275 |
{ |
276 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
277 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
278 |
__leave; |
279 |
} |
280 |
dwReturn = CardQueryFreeSpace(pCardData, dwFlags, (PCARD_FREE_SPACE_INFO) pbData); |
281 |
} |
282 |
else if (wcscmp(wszProperty,CP_CARD_CAPABILITIES) == 0) |
283 |
{ |
284 |
*pdwDataLen = sizeof(CARD_CAPABILITIES); |
285 |
if (cbData < *pdwDataLen) |
286 |
{ |
287 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
288 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
289 |
__leave; |
290 |
} |
291 |
dwReturn = CardQueryCapabilities(pCardData, (PCARD_CAPABILITIES) pbData); |
292 |
} |
293 |
else if (wcscmp(wszProperty,CP_CARD_KEYSIZES) == 0) |
294 |
{ |
295 |
*pdwDataLen = sizeof(CARD_KEY_SIZES); |
296 |
if (cbData < *pdwDataLen) |
297 |
{ |
298 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
299 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
300 |
__leave; |
301 |
} |
302 |
dwReturn = CardQueryKeySizes(pCardData, dwFlags, 0, (PCARD_KEY_SIZES) pbData); |
303 |
} |
304 |
else if (wcscmp(wszProperty,CP_CARD_READ_ONLY) == 0) |
305 |
{ |
306 |
*pdwDataLen = sizeof(BOOL); |
307 |
if (cbData < *pdwDataLen) |
308 |
{ |
309 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
310 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
311 |
__leave; |
312 |
} |
313 |
*((PBOOL)pbData) = TRUE; |
314 |
} |
315 |
else if (wcscmp(wszProperty,CP_CARD_CACHE_MODE) == 0) |
316 |
{ |
317 |
*pdwDataLen = sizeof(DWORD); |
318 |
if (cbData < *pdwDataLen) |
319 |
{ |
320 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
321 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
322 |
__leave; |
323 |
} |
324 |
*((PDWORD)pbData) = CP_CACHE_MODE_NO_CACHE; |
325 |
} |
326 |
else if (wcscmp(wszProperty,CP_SUPPORTS_WIN_X509_ENROLLMENT) == 0) |
327 |
{ |
328 |
*pdwDataLen = sizeof(BOOL); |
329 |
if (cbData < *pdwDataLen) |
330 |
{ |
331 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
332 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
333 |
__leave; |
334 |
} |
335 |
*((PBOOL)pbData) = FALSE; |
336 |
} |
337 |
else if (wcscmp(wszProperty,CP_CARD_GUID) == 0) |
338 |
{ |
339 |
dwReturn = CardReadFile(pCardData, NULL, szCARD_IDENTIFIER_FILE, 0, &pbTempData, &dwTempSize); |
340 |
if (dwReturn) |
341 |
{ |
342 |
__leave; |
343 |
} |
344 |
*pdwDataLen = dwTempSize; |
345 |
if (cbData < *pdwDataLen) |
346 |
{ |
347 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
348 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
349 |
__leave; |
350 |
} |
351 |
memcpy(pbData, pbTempData, dwTempSize); |
352 |
} |
353 |
else if (wcscmp(wszProperty,CP_CARD_SERIAL_NO) == 0) |
354 |
{ |
355 |
*pdwDataLen = sizeof(OPENPGP_AID); |
356 |
if (cbData < *pdwDataLen) |
357 |
{ |
358 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
359 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
360 |
__leave; |
361 |
} |
362 |
memcpy(pbData, &(((POPENPGP_CONTEXT)pCardData->pvVendorSpecific)->Aid), sizeof(OPENPGP_AID)); |
363 |
dwReturn = 0; |
364 |
} |
365 |
else if (wcscmp(wszProperty,CP_CARD_PIN_INFO) == 0) |
366 |
{ |
367 |
PPIN_INFO pPinInfo; |
368 |
*pdwDataLen = sizeof(PIN_INFO); |
369 |
if (cbData < *pdwDataLen) |
370 |
{ |
371 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
372 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
373 |
__leave; |
374 |
} |
375 |
pPinInfo = (PPIN_INFO) pbData; |
376 |
dwReturn = GetPinInfo(dwFlags, pPinInfo); |
377 |
} |
378 |
else if (wcscmp(wszProperty,CP_CARD_LIST_PINS) == 0) |
379 |
{ |
380 |
PPIN_SET pPinSet; |
381 |
*pdwDataLen = sizeof(PIN_SET); |
382 |
if (cbData < *pdwDataLen) |
383 |
{ |
384 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
385 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
386 |
__leave; |
387 |
} |
388 |
pPinSet = (PPIN_SET) pbData; |
389 |
} |
390 |
else if (wcscmp(wszProperty,CP_CARD_AUTHENTICATED_STATE) == 0) |
391 |
{ |
392 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
393 |
} |
394 |
else if (wcscmp(wszProperty,CP_CARD_PIN_STRENGTH_VERIFY) == 0) |
395 |
{ |
396 |
PPIN_SET pPinSet; |
397 |
*pdwDataLen = sizeof(PIN_SET); |
398 |
if (cbData < *pdwDataLen) |
399 |
{ |
400 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
401 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
402 |
__leave; |
403 |
} |
404 |
pPinSet = (PPIN_SET) pbData; |
405 |
*pPinSet = CARD_PIN_STRENGTH_PLAINTEXT; |
406 |
} |
407 |
else if (wcscmp(wszProperty,CP_KEY_IMPORT_SUPPORT) == 0) |
408 |
{ |
409 |
*pdwDataLen = sizeof(DWORD); |
410 |
if (cbData < *pdwDataLen) |
411 |
{ |
412 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
413 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
414 |
__leave; |
415 |
} |
416 |
*((PDWORD)pbData) = CARD_KEY_IMPORT_RSA_KEYEST; |
417 |
} |
418 |
else if (wcscmp(wszProperty,CP_ENUM_ALGORITHMS ) == 0) |
419 |
{ |
420 |
if (dwFlags == CARD_CIPHER_OPERATION) |
421 |
{ |
422 |
*pdwDataLen = sizeof(OPENPGP_SUPPORTED_CYPHER_ALGORITHM); |
423 |
if (cbData < *pdwDataLen) |
424 |
{ |
425 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
426 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
427 |
__leave; |
428 |
} |
429 |
memcpy(pbData,OPENPGP_SUPPORTED_CYPHER_ALGORITHM,*pdwDataLen); |
430 |
} |
431 |
else if (dwFlags == CARD_ASYMMETRIC_OPERATION ) |
432 |
{ |
433 |
*pdwDataLen = sizeof(OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM); |
434 |
if (cbData < *pdwDataLen) |
435 |
{ |
436 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
437 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
438 |
__leave; |
439 |
} |
440 |
memcpy(pbData,OPENPGP_SUPPORTED_ASYMETRIC_ALGORITHM,*pdwDataLen); |
441 |
} |
442 |
else |
443 |
{ |
444 |
Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); |
445 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
446 |
} |
447 |
} |
448 |
else if (wcscmp(wszProperty,CP_PADDING_SCHEMES ) == 0) |
449 |
{ |
450 |
if (dwFlags == CARD_CIPHER_OPERATION) |
451 |
{ |
452 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
453 |
} |
454 |
else if (dwFlags == CARD_ASYMMETRIC_OPERATION ) |
455 |
{ |
456 |
*pdwDataLen = sizeof(DWORD); |
457 |
if (cbData < *pdwDataLen) |
458 |
{ |
459 |
Trace(WINEVENT_LEVEL_ERROR, L"cbData == %d", cbData); |
460 |
dwReturn = ERROR_INSUFFICIENT_BUFFER; |
461 |
__leave; |
462 |
} |
463 |
*((PDWORD)pbData) = CARD_PADDING_PKCS1; |
464 |
} |
465 |
else |
466 |
{ |
467 |
Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); |
468 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
469 |
} |
470 |
|
471 |
} |
472 |
else if (wcscmp(wszProperty,CP_CHAINING_MODES ) == 0) |
473 |
{ |
474 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
475 |
} |
476 |
else |
477 |
{ |
478 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty); |
479 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
480 |
__leave; |
481 |
} |
482 |
} |
483 |
__finally |
484 |
{ |
485 |
if (pbTempData) |
486 |
{ |
487 |
pCardData->pfnCspFree(pbTempData); |
488 |
} |
489 |
} |
490 |
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); |
491 |
return dwReturn; |
492 |
} |
493 |
|
494 |
/** This function can be used to set properties on the card.*/ |
495 |
|
496 |
DWORD WINAPI CardSetProperty( |
497 |
__in PCARD_DATA pCardData, |
498 |
__in LPCWSTR wszProperty, |
499 |
__in_bcount(cbDataLen) PBYTE pbData, |
500 |
__in DWORD cbDataLen, |
501 |
__in DWORD dwFlags |
502 |
) |
503 |
{ |
504 |
DWORD dwReturn = 0; |
505 |
Trace(WINEVENT_LEVEL_VERBOSE, L"Enter wszProperty = %s", wszProperty); |
506 |
__try |
507 |
{ |
508 |
if ( pCardData == NULL ) |
509 |
{ |
510 |
Trace(WINEVENT_LEVEL_ERROR, L"pCardData == NULL"); |
511 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
512 |
__leave; |
513 |
} |
514 |
if ( wszProperty == NULL ) |
515 |
{ |
516 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == NULL"); |
517 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
518 |
__leave; |
519 |
} |
520 |
if (dwFlags) |
521 |
{ |
522 |
Trace(WINEVENT_LEVEL_ERROR, L"dwFlags == %d", dwFlags); |
523 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
524 |
__leave; |
525 |
} |
526 |
if (wcscmp(wszProperty,CP_CARD_FREE_SPACE) == 0 |
527 |
|| wcscmp(wszProperty,CP_CARD_CAPABILITIES) == 0 |
528 |
|| wcscmp(wszProperty,CP_CARD_KEYSIZES) == 0 |
529 |
|| wcscmp(wszProperty,CP_CARD_LIST_PINS) == 0 |
530 |
|| wcscmp(wszProperty,CP_CARD_AUTHENTICATED_STATE) == 0 |
531 |
|| wcscmp(wszProperty,CP_KEY_IMPORT_SUPPORT) == 0 |
532 |
|| wcscmp(wszProperty,CP_ENUM_ALGORITHMS) == 0 |
533 |
|| wcscmp(wszProperty,CP_PADDING_SCHEMES) == 0 |
534 |
|| wcscmp(wszProperty,CP_CHAINING_MODES) == 0) |
535 |
{ |
536 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s SCARD_E_UNSUPPORTED_FEATURE", wszProperty); |
537 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
538 |
__leave; |
539 |
} |
540 |
else if (wcscmp(wszProperty,CP_CARD_READ_ONLY) == 0) |
541 |
{ |
542 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
543 |
} |
544 |
else if (wcscmp(wszProperty,CP_CARD_CACHE_MODE) == 0) |
545 |
{ |
546 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
547 |
} |
548 |
else if (wcscmp(wszProperty,CP_SUPPORTS_WIN_X509_ENROLLMENT) == 0) |
549 |
{ |
550 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
551 |
} |
552 |
else if (wcscmp(wszProperty,CP_CARD_GUID) == 0) |
553 |
{ |
554 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
555 |
} |
556 |
else if (wcscmp(wszProperty,CP_CARD_SERIAL_NO) == 0) |
557 |
{ |
558 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
559 |
} |
560 |
else if (wcscmp(wszProperty,CP_CARD_PIN_INFO) == 0) |
561 |
{ |
562 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
563 |
} |
564 |
else if (wcscmp(wszProperty,CP_CARD_PIN_STRENGTH_VERIFY) == 0) |
565 |
{ |
566 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE ; |
567 |
} |
568 |
else |
569 |
{ |
570 |
Trace(WINEVENT_LEVEL_ERROR, L"wszProperty == %s", wszProperty); |
571 |
dwReturn = SCARD_E_INVALID_PARAMETER; |
572 |
__leave; |
573 |
} |
574 |
dwReturn = SCARD_E_UNSUPPORTED_FEATURE; |
575 |
} |
576 |
__finally |
577 |
{ |
578 |
} |
579 |
Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn); |
580 |
return dwReturn; |
581 |
} |
582 |
|