/[openpgpmdrv]/trunk/OpenPGPminidriver/CardAndContainerProperties.c
ViewVC logotype

Contents of /trunk/OpenPGPminidriver/CardAndContainerProperties.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Thu Feb 25 22:09:17 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 16302 byte(s)
fixed public key export (big endian - little endian issue)
signature works (sign & verify)
decrypt really decrypt but output not recognized yet by cryptoapi
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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26