mfplat/sample: Refactor sample_CopyToBuffer().
[wine.git] / dlls / winscard / unixlib.c
blobf1228b0eef6b49bdba609526419506dfc725413e
1 /*
2 * Copyright 2022 Hans Leidekker for CodeWeavers
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 as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #if 0
20 #pragma makedep unix
21 #endif
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winternl.h"
29 #include "winbase.h"
31 #include "wine/unixlib.h"
32 #include "unixlib.h"
34 #ifdef __APPLE__
35 LONG SCardEstablishContext( UINT32, const void *, const void *, UINT32 * );
36 LONG SCardReleaseContext( UINT32 );
37 LONG SCardIsValidContext( UINT32 );
38 LONG SCardGetStatusChange( UINT32, UINT32, void *, UINT32 );
39 LONG SCardCancel( UINT32 );
40 LONG SCardListReaders( UINT32, const char *, char *, UINT32 * );
41 LONG SCardListReaderGroups( UINT32, char *, UINT32 * );
42 LONG SCardConnect( UINT32, const char *, UINT32, UINT32, UINT32 *, UINT32 * );
43 LONG SCardStatus( UINT32, char *, UINT32 *, UINT32 *, UINT32 *, BYTE *, UINT32 * );
44 LONG SCardDisconnect( UINT32, UINT32 );
45 LONG SCardReconnect( UINT32, UINT32, UINT32, UINT32, UINT32 * );
46 LONG SCardBeginTransaction( UINT32 );
47 LONG SCardEndTransaction( UINT32, UINT32 );
48 LONG SCardTransmit( UINT32, const void *, const BYTE *, UINT32, void *, BYTE *, UINT32 * );
49 LONG SCardControl132( UINT32, UINT32, const void *, UINT32, void *, UINT32, UINT32 * );
50 LONG SCardGetAttrib( UINT32, UINT32, BYTE *, UINT32 * );
51 LONG SCardSetAttrib( UINT32, UINT32, const BYTE *, UINT32 );
52 #else
53 LONG SCardEstablishContext( UINT64, const void *, const void *, UINT64 * );
54 LONG SCardReleaseContext( UINT64 );
55 LONG SCardIsValidContext( UINT64 );
56 LONG SCardGetStatusChange( UINT64, UINT64, void *, UINT64 );
57 LONG SCardCancel( UINT64 );
58 LONG SCardListReaders( UINT64, const char *, char *, UINT64 * );
59 LONG SCardListReaderGroups( UINT64, char *, UINT64 * );
60 LONG SCardConnect( UINT64, const char *, UINT64, UINT64, UINT64 *, UINT64 * );
61 LONG SCardStatus( UINT64, char *, UINT64 *, UINT64 *, UINT64 *, BYTE *, UINT64 * );
62 LONG SCardDisconnect( UINT64, UINT64 );
63 LONG SCardReconnect( UINT64, UINT64, UINT64, UINT64, UINT64 * );
64 LONG SCardBeginTransaction( UINT64 );
65 LONG SCardEndTransaction( UINT64, UINT64 );
66 LONG SCardTransmit( UINT64, const void *, const BYTE *, UINT64, void *, BYTE *, UINT64 * );
67 LONG SCardControl( UINT64, UINT64, const void *, UINT64, void *, UINT64, UINT64 * );
68 LONG SCardGetAttrib( UINT64, UINT64, BYTE *, UINT64 * );
69 LONG SCardSetAttrib( UINT64, UINT64, const BYTE *, UINT64 );
70 #endif
72 static NTSTATUS scard_establish_context( void *args )
74 struct scard_establish_context_params *params = args;
75 #ifdef __APPLE__
76 NTSTATUS status;
77 UINT32 handle;
78 if (!(status = SCardEstablishContext( params->scope, NULL, NULL, &handle ))) *params->handle = handle;
79 return status;
80 #else
81 return SCardEstablishContext( params->scope, NULL, NULL, params->handle );
82 #endif
85 static NTSTATUS scard_release_context( void *args )
87 struct scard_release_context_params *params = args;
88 return SCardReleaseContext( params->handle );
91 static NTSTATUS scard_is_valid_context( void *args )
93 struct scard_is_valid_context_params *params = args;
94 return SCardIsValidContext( params->handle );
97 #ifdef __APPLE__
98 struct reader_state_macos
100 UINT64 reader;
101 UINT64 userdata;
102 UINT32 current_state;
103 UINT32 event_state;
104 UINT32 atr_size;
105 unsigned char atr[MAX_ATR_SIZE];
108 static struct reader_state_macos *map_states_in( const struct reader_state *state, unsigned int count )
110 struct reader_state_macos *ret;
111 unsigned int i;
113 if (!(ret = malloc( sizeof(*ret) * count ))) return NULL;
114 for (i = 0; i < count; i++)
116 ret[i].reader = state[i].reader;
117 ret[i].userdata = state[i].userdata;
118 ret[i].current_state = state[i].current_state;
119 ret[i].event_state = state[i].event_state;
120 memcpy( ret[i].atr, state[i].atr, state[i].atr_size );
121 ret[i].atr_size = state[i].atr_size;
123 return ret;
126 static void map_states_out( const struct reader_state_macos *state_macos, struct reader_state *state, unsigned int count )
128 unsigned int i;
129 for (i = 0; i < count; i++)
131 state[i].current_state = state_macos[i].current_state;
132 state[i].event_state = state_macos[i].event_state;
133 memcpy( state[i].atr, state_macos[i].atr, state_macos[i].atr_size );
134 state[i].atr_size = state_macos[i].atr_size;
137 #endif
139 static NTSTATUS scard_get_status_change( void *args )
141 struct scard_get_status_change_params *params = args;
142 #ifdef __APPLE__
143 NTSTATUS status;
144 struct reader_state_macos *states = map_states_in( params->states, params->count );
146 if (!states) return STATUS_NO_MEMORY;
147 if (!(status = SCardGetStatusChange( params->handle, params->timeout, states, params->count )))
148 map_states_out( states, params->states, params->count );
149 free( states );
150 return status;
151 #else
152 return SCardGetStatusChange( params->handle, params->timeout, params->states, params->count );
153 #endif
156 static NTSTATUS scard_cancel( void *args )
158 struct scard_cancel_params *params = args;
159 return SCardCancel( params->handle );
162 static NTSTATUS scard_list_readers( void *args )
164 struct scard_list_readers_params *params = args;
165 #ifdef __APPLE__
166 NTSTATUS status;
167 UINT32 len = *params->readers_len;
168 if (!(status = SCardListReaders( params->handle, params->groups, params->readers, &len ))) *params->readers_len = len;
169 return status;
170 #else
171 return SCardListReaders( params->handle, params->groups, params->readers, params->readers_len );
172 #endif
175 static NTSTATUS scard_list_reader_groups( void *args )
177 struct scard_list_reader_groups_params *params = args;
178 #ifdef __APPLE__
179 NTSTATUS status;
180 UINT32 len = *params->groups_len;
181 if (!(status = SCardListReaderGroups( params->handle, params->groups, &len ))) *params->groups_len = len;
182 return status;
183 #else
184 return SCardListReaderGroups( params->handle, params->groups, params->groups_len );
185 #endif
188 static NTSTATUS scard_connect( void *args )
190 struct scard_connect_params *params = args;
191 #ifdef __APPLE__
192 NTSTATUS status;
193 UINT32 handle, protocol;
194 if (!(status = SCardConnect( params->context_handle, params->reader, params->share_mode,
195 params->preferred_protocols, &handle, &protocol )))
197 *params->connect_handle = handle;
198 *params->protocol = protocol;
200 return status;
201 #else
202 return SCardConnect( params->context_handle, params->reader, params->share_mode, params->preferred_protocols,
203 params->connect_handle, params->protocol );
204 #endif
207 static NTSTATUS scard_status( void *args )
209 struct scard_status_params *params = args;
210 #ifdef __APPLE__
211 NTSTATUS status;
212 UINT32 names_len = params->names_len ? *params->names_len : 0;
213 UINT32 atr_len = params->atr_len ? *params->atr_len : 0;
214 UINT32 state, protocol;
216 if (!(status = SCardStatus( params->handle, params->names, params->names_len ? &names_len : NULL,
217 params->state ? &state : NULL, params->protocol ? &protocol : NULL, params->atr,
218 params->atr_len ? &atr_len : NULL )))
220 if (params->names_len) *params->names_len = names_len;
221 if (params->state) *params->state = state;
222 if (params->protocol) *params->protocol = protocol;
223 if (params->atr_len) *params->atr_len = atr_len;
225 return status;
226 #else
227 return SCardStatus( params->handle, params->names, params->names_len, params->state, params->protocol,
228 params->atr, params->atr_len );
229 #endif
232 static NTSTATUS scard_reconnect( void *args )
234 struct scard_reconnect_params *params = args;
235 #ifdef __APPLE__
236 NTSTATUS status;
237 UINT32 protocol;
238 if (!(status = SCardReconnect( params->handle, params->share_mode, params->preferred_protocols,
239 params->initialization, &protocol ))) *params->protocol = protocol;
240 return status;
241 #else
242 return SCardReconnect( params->handle, params->share_mode, params->preferred_protocols, params->initialization,
243 params->protocol );
244 #endif
247 static NTSTATUS scard_disconnect( void *args )
249 struct scard_disconnect_params *params = args;
250 return SCardDisconnect( params->handle, params->disposition );
253 static NTSTATUS scard_begin_transaction( void *args )
255 struct scard_begin_transaction_params *params = args;
256 return SCardBeginTransaction( params->handle );
259 static NTSTATUS scard_end_transaction( void *args )
261 struct scard_end_transaction_params *params = args;
262 return SCardEndTransaction( params->handle, params->disposition );
265 static NTSTATUS scard_transmit( void *args )
267 struct scard_transmit_params *params = args;
268 #ifdef __APPLE__
269 NTSTATUS status;
270 UINT32 len = *params->recv_buflen;
271 struct
273 UINT32 protocol;
274 UINT32 pci_len;
275 } send, recv;
277 send.protocol = params->send->protocol;
278 send.pci_len = params->send->pci_len;
279 if (params->recv)
281 recv.protocol = params->recv->protocol;
282 recv.pci_len = params->recv->pci_len;
284 if (!(status = SCardTransmit( params->handle, &send, params->send_buf, params->send_buflen, &recv,
285 params->recv_buf, &len )))
287 if (params->recv)
289 params->recv->protocol = recv.protocol;
290 params->recv->pci_len = recv.pci_len;
292 *params->recv_buflen = len;
294 return status;
295 #else
296 return SCardTransmit( params->handle, params->send, params->send_buf, params->send_buflen, params->recv,
297 params->recv_buf, params->recv_buflen );
298 #endif
301 static NTSTATUS scard_control( void *args )
303 struct scard_control_params *params = args;
304 #ifdef __APPLE__
305 NTSTATUS status;
306 UINT32 len;
307 if (!(status = SCardControl132( params->handle, params->code, params->in_buf, params->in_buflen, params->out_buf,
308 params->out_buflen, &len )))
309 *params->ret_len = len;
310 return status;
311 #else
312 return SCardControl( params->handle, params->code, params->in_buf, params->in_buflen, params->out_buf,
313 params->out_buflen, params->ret_len );
314 #endif
317 static NTSTATUS scard_get_attrib( void *args )
319 struct scard_get_attrib_params *params = args;
320 #ifdef __APPLE__
321 NTSTATUS status;
322 UINT32 len = *params->attr_len;
323 if (!(status = SCardGetAttrib( params->handle, params->id, params->attr, &len ))) *params->attr_len = len;
324 return status;
325 #else
326 return SCardGetAttrib( params->handle, params->id, params->attr, params->attr_len );
327 #endif
330 static NTSTATUS scard_set_attrib( void *args )
332 struct scard_set_attrib_params *params = args;
333 return SCardSetAttrib( params->handle, params->id, params->attr, params->attr_len );
336 const unixlib_entry_t __wine_unix_call_funcs[] =
338 scard_establish_context,
339 scard_release_context,
340 scard_is_valid_context,
341 scard_get_status_change,
342 scard_cancel,
343 scard_list_readers,
344 scard_list_reader_groups,
345 scard_connect,
346 scard_status,
347 scard_reconnect,
348 scard_disconnect,
349 scard_begin_transaction,
350 scard_end_transaction,
351 scard_transmit,
352 scard_control,
353 scard_get_attrib,
354 scard_set_attrib,
357 C_ASSERT( ARRAYSIZE(__wine_unix_call_funcs) == unix_funcs_count );
359 #ifdef _WIN64
361 typedef ULONG PTR32;
363 static NTSTATUS wow64_scard_establish_context( void *args )
365 struct
367 UINT64 scope;
368 PTR32 handle;
369 } const *params32 = args;
371 struct scard_establish_context_params params =
373 params32->scope,
374 ULongToPtr(params32->handle)
376 return scard_establish_context( &params );
379 static NTSTATUS wow64_scard_release_context( void *args )
381 struct
383 UINT64 handle;
384 } const *params32 = args;
386 struct scard_release_context_params params =
388 params32->handle
390 return scard_release_context( &params );
393 static NTSTATUS wow64_scard_is_valid_context( void *args )
395 struct
397 UINT64 handle;
398 } const *params32 = args;
400 struct scard_is_valid_context_params params =
402 params32->handle
404 return scard_is_valid_context( &params );
407 static NTSTATUS wow64_scard_get_status_change( void *args )
409 struct
411 UINT64 handle;
412 UINT64 timeout;
413 PTR32 states;
414 UINT64 count;
415 } const *params32 = args;
417 struct scard_get_status_change_params params =
419 params32->handle,
420 params32->timeout,
421 ULongToPtr(params32->states),
422 params32->count,
424 return scard_get_status_change( &params );
427 static NTSTATUS wow64_scard_cancel( void *args )
429 struct
431 UINT64 handle;
432 } const *params32 = args;
434 struct scard_cancel_params params =
436 params32->handle
438 return scard_cancel( &params );
441 static NTSTATUS wow64_scard_list_readers( void *args )
443 struct
445 UINT64 handle;
446 PTR32 groups;
447 PTR32 readers;
448 PTR32 readers_len;
449 } *params32 = args;
451 struct scard_list_readers_params params =
453 params32->handle,
454 ULongToPtr(params32->groups),
455 ULongToPtr(params32->readers),
456 ULongToPtr(params32->readers_len)
458 return scard_list_readers( &params );
461 static NTSTATUS wow64_scard_list_reader_groups( void *args )
463 struct
465 UINT64 handle;
466 PTR32 groups;
467 PTR32 groups_len;
468 } *params32 = args;
470 struct scard_list_reader_groups_params params =
472 params32->handle,
473 ULongToPtr(params32->groups),
474 ULongToPtr(params32->groups_len)
476 return scard_list_reader_groups( &params );
479 static NTSTATUS wow64_scard_connect( void *args )
481 struct
483 UINT64 context_handle;
484 PTR32 reader;
485 UINT64 share_mode;
486 UINT64 preferred_protocols;
487 PTR32 connect_handle;
488 PTR32 protocol;
489 } *params32 = args;
491 struct scard_connect_params params =
493 params32->context_handle,
494 ULongToPtr(params32->reader),
495 params32->share_mode,
496 params32->preferred_protocols,
497 ULongToPtr(params32->connect_handle),
498 ULongToPtr(params32->protocol)
500 return scard_connect( &params );
503 static NTSTATUS wow64_scard_status( void *args )
505 struct
507 UINT64 handle;
508 PTR32 names;
509 PTR32 names_len;
510 PTR32 state;
511 PTR32 protocol;
512 PTR32 atr;
513 PTR32 atr_len;
514 } *params32 = args;
516 struct scard_status_params params =
518 params32->handle,
519 ULongToPtr(params32->names),
520 ULongToPtr(params32->names_len),
521 ULongToPtr(params32->state),
522 ULongToPtr(params32->protocol),
523 ULongToPtr(params32->atr),
524 ULongToPtr(params32->atr_len)
526 return scard_status( &params );
529 static NTSTATUS wow64_scard_reconnect( void *args )
531 struct
533 UINT64 handle;
534 UINT64 share_mode;
535 UINT64 preferred_protocols;
536 UINT64 initialization;
537 PTR32 protocol;
538 } *params32 = args;
540 struct scard_reconnect_params params =
542 params32->handle,
543 params32->share_mode,
544 params32->preferred_protocols,
545 params32->initialization,
546 ULongToPtr(params32->protocol)
548 return scard_reconnect( &params );
551 static NTSTATUS wow64_scard_disconnect( void *args )
553 struct
555 UINT64 handle;
556 UINT64 disposition;
557 } *params32 = args;
559 struct scard_disconnect_params params =
561 params32->handle,
562 params32->disposition
564 return scard_disconnect( &params );
567 static NTSTATUS wow64_scard_begin_transaction( void *args )
569 struct
571 UINT64 handle;
572 } *params32 = args;
574 struct scard_begin_transaction_params params =
576 params32->handle
578 return scard_begin_transaction( &params );
581 static NTSTATUS wow64_scard_end_transaction( void *args )
583 struct
585 UINT64 handle;
586 UINT64 disposition;
587 } *params32 = args;
589 struct scard_end_transaction_params params =
591 params32->handle,
592 params32->disposition
594 return scard_end_transaction( &params );
597 static NTSTATUS wow64_scard_transmit( void *args )
599 struct
601 UINT64 handle;
602 PTR32 send;
603 PTR32 send_buf;
604 UINT64 send_buflen;
605 PTR32 recv;
606 PTR32 recv_buf;
607 PTR32 recv_buflen;
608 } *params32 = args;
610 struct scard_transmit_params params =
612 params32->handle,
613 ULongToPtr(params32->send),
614 ULongToPtr(params32->send_buf),
615 params32->send_buflen,
616 ULongToPtr(params32->recv),
617 ULongToPtr(params32->recv_buf),
618 ULongToPtr(params32->recv_buflen)
620 return scard_transmit( &params );
623 static NTSTATUS wow64_scard_control( void *args )
625 struct
627 UINT64 handle;
628 UINT64 code;
629 PTR32 in_buf;
630 UINT64 in_buflen;
631 PTR32 out_buf;
632 UINT64 out_buflen;
633 PTR32 ret_len;
634 } *params32 = args;
636 struct scard_control_params params =
638 params32->handle,
639 params32->code,
640 ULongToPtr(params32->in_buf),
641 params32->in_buflen,
642 ULongToPtr(params32->out_buf),
643 params32->out_buflen,
644 ULongToPtr(params32->ret_len)
646 return scard_control( &params );
649 static NTSTATUS wow64_scard_get_attrib( void *args )
651 struct
653 UINT64 handle;
654 UINT64 id;
655 PTR32 attr;
656 PTR32 attr_len;
657 } *params32 = args;
659 struct scard_get_attrib_params params =
661 params32->handle,
662 params32->id,
663 ULongToPtr(params32->attr),
664 ULongToPtr(params32->attr_len)
666 return scard_get_attrib( &params );
669 static NTSTATUS wow64_scard_set_attrib( void *args )
671 struct
673 UINT64 handle;
674 UINT64 id;
675 PTR32 attr;
676 UINT64 attr_len;
677 } *params32 = args;
679 struct scard_set_attrib_params params =
681 params32->handle,
682 params32->id,
683 ULongToPtr(params32->attr),
684 params32->attr_len
686 return scard_set_attrib( &params );
689 const unixlib_entry_t __wine_unix_call_wow64_funcs[] =
691 wow64_scard_establish_context,
692 wow64_scard_release_context,
693 wow64_scard_is_valid_context,
694 wow64_scard_get_status_change,
695 wow64_scard_cancel,
696 wow64_scard_list_readers,
697 wow64_scard_list_reader_groups,
698 wow64_scard_connect,
699 wow64_scard_status,
700 wow64_scard_reconnect,
701 wow64_scard_disconnect,
702 wow64_scard_begin_transaction,
703 wow64_scard_end_transaction,
704 wow64_scard_transmit,
705 wow64_scard_control,
706 wow64_scard_get_attrib,
707 wow64_scard_set_attrib,
710 C_ASSERT( ARRAYSIZE(__wine_unix_call_wow64_funcs) == unix_funcs_count );
712 #endif /* _WIN64 */