~ubuntu-branches/ubuntu/raring/freerdp/raring-proposed

« back to all changes in this revision

Viewing changes to channels/rdpdr/smartcard/scard_main.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, Jeremy Bicha, Jean-Louis Dupond, Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120131100214-jaok3uwvni7sqxth
Tags: 1.0.0-0git1
Upload current Debian packaging git to get this rolling for precise.

[ Jeremy Bicha ]
* New upstream release. Closes: #647498.
* Updated symbols and bumped soname
* debian/control:
  - Added new build dependencies
  - Bump Standards-Version to 3.9.2
* debian/source/format: Set to 3.0 (quilt)
* debian/rules: Turn on strict symbols checking
* debian/watch: Watch github

[ Jean-Louis Dupond ]
* debian/control: Updated homepage
* debian/copyright: Reflect upstream switch to the Apache license

[ Martin Pitt ]
* debian/libfreerdp0.symbols: Fix version number, should
  be 1.0~beta5, not 1.0-beta5.
* debian/control: Add libavcodec-dev build dependency, upstream build system
  checks for that. Thanks Jean-Louis Dupond!

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   FreeRDP: A Remote Desktop Protocol client.
 
3
   Redirected Smart Card Device Service
 
4
 
 
5
   Copyright 2011 O.S. Systems Software Ltda.
 
6
   Copyright 2011 Eduardo Fiss Beloni <beloni@ossystems.com.br>
 
7
   Copyright 2011 Anthony Tong <atong@trustedcs.com>
 
8
 
 
9
   Licensed under the Apache License, Version 2.0 (the "License");
 
10
   you may not use this file except in compliance with the License.
 
11
   You may obtain a copy of the License at
 
12
 
 
13
       http://www.apache.org/licenses/LICENSE-2.0
 
14
 
 
15
   Unless required by applicable law or agreed to in writing, software
 
16
   distributed under the License is distributed on an "AS IS" BASIS,
 
17
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
18
   See the License for the specific language governing permissions and
 
19
   limitations under the License.
 
20
*/
 
21
 
 
22
#include "config.h"
 
23
 
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
 
 
28
#include <freerdp/utils/list.h>
 
29
#include <freerdp/utils/thread.h>
 
30
#include <freerdp/utils/svc_plugin.h>
 
31
 
 
32
#include "rdpdr_types.h"
 
33
#include "rdpdr_constants.h"
 
34
 
 
35
#include "scard_main.h"
 
36
 
 
37
 
 
38
static void
 
39
scard_free(DEVICE* dev)
 
40
{
 
41
        SCARD_DEVICE* scard = (SCARD_DEVICE*)dev;
 
42
        IRP* irp;
 
43
 
 
44
        freerdp_thread_stop(scard->thread);
 
45
        freerdp_thread_free(scard->thread);
 
46
        
 
47
        while ((irp = (IRP*)list_dequeue(scard->irp_list)) != NULL)
 
48
                irp->Discard(irp);
 
49
        list_free(scard->irp_list);
 
50
 
 
51
        xfree(dev);
 
52
        return;
 
53
}
 
54
 
 
55
 
 
56
static void
 
57
scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
 
58
{
 
59
        switch (irp->MajorFunction)
 
60
        {
 
61
                case IRP_MJ_DEVICE_CONTROL:
 
62
                        scard_device_control(scard, irp);
 
63
                        break;
 
64
 
 
65
                default:
 
66
                        printf("MajorFunction 0x%X unexpected for smartcards.", irp->MajorFunction);
 
67
                        DEBUG_WARN("Smartcard MajorFunction 0x%X not supported.", irp->MajorFunction);
 
68
                        irp->IoStatus = STATUS_NOT_SUPPORTED;
 
69
                        irp->Complete(irp);
 
70
                        break;
 
71
        }
 
72
}
 
73
 
 
74
 
 
75
static void
 
76
scard_process_irp_list(SCARD_DEVICE* scard)
 
77
{
 
78
        IRP *irp;
 
79
 
 
80
        while (!freerdp_thread_is_stopped(scard->thread))
 
81
        {
 
82
                freerdp_thread_lock(scard->thread);
 
83
                irp = (IRP *) list_dequeue(scard->irp_list);
 
84
                freerdp_thread_unlock(scard->thread);
 
85
 
 
86
                if (irp == NULL)
 
87
                        break;
 
88
 
 
89
                scard_process_irp(scard, irp);
 
90
        }
 
91
}
 
92
 
 
93
 
 
94
struct scard_irp_thread_args {
 
95
        SCARD_DEVICE* scard;
 
96
        IRP* irp;
 
97
        freerdp_thread* thread;
 
98
};
 
99
 
 
100
 
 
101
static void
 
102
scard_process_irp_thread_func(struct scard_irp_thread_args* args)
 
103
{
 
104
        scard_process_irp(args->scard, args->irp);
 
105
 
 
106
        freerdp_thread_free(args->thread);
 
107
        xfree(args);
 
108
}
 
109
 
 
110
 
 
111
static void *
 
112
scard_thread_func(void* arg)
 
113
{
 
114
        SCARD_DEVICE* scard = (SCARD_DEVICE*) arg;
 
115
 
 
116
        while (1)
 
117
        {
 
118
                freerdp_thread_wait(scard->thread);
 
119
 
 
120
                if (freerdp_thread_is_stopped(scard->thread))
 
121
                        break;
 
122
 
 
123
                freerdp_thread_reset(scard->thread);
 
124
                scard_process_irp_list(scard);
 
125
        }
 
126
 
 
127
        freerdp_thread_quit(scard->thread);
 
128
 
 
129
        return NULL;
 
130
}
 
131
 
 
132
 
 
133
static void
 
134
scard_irp_request(DEVICE* device, IRP* irp)
 
135
{
 
136
        SCARD_DEVICE* scard = (SCARD_DEVICE*)device;
 
137
 
 
138
        if (irp->MajorFunction == IRP_MJ_DEVICE_CONTROL &&
 
139
                        scard_async_op(irp))
 
140
        {
 
141
                /*
 
142
                 * certain potentially long running operations
 
143
                 * get their own thread
 
144
                 * TODO: revise this mechanism.. maybe worker pool
 
145
                 */
 
146
                struct scard_irp_thread_args *args = xmalloc(sizeof(struct scard_irp_thread_args));
 
147
 
 
148
 
 
149
                args->thread = freerdp_thread_new();
 
150
                args->scard = scard;
 
151
                args->irp = irp;
 
152
                freerdp_thread_start(args->thread, scard_process_irp_thread_func, args);
 
153
 
 
154
                return;
 
155
        }
 
156
 
 
157
        freerdp_thread_lock(scard->thread);
 
158
        list_enqueue(scard->irp_list, irp);
 
159
        freerdp_thread_unlock(scard->thread);
 
160
 
 
161
        freerdp_thread_signal(scard->thread);
 
162
}
 
163
 
 
164
 
 
165
int
 
166
DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
 
167
{
 
168
        SCARD_DEVICE* scard;
 
169
        char* name;
 
170
        char* path;
 
171
        int i, length;
 
172
 
 
173
        name = (char *)pEntryPoints->plugin_data->data[1];
 
174
        path = (char *)pEntryPoints->plugin_data->data[2];
 
175
 
 
176
        if (name)
 
177
        {
 
178
                /* TODO: check if server supports sc redirect (version 5.1) */
 
179
 
 
180
                scard = xnew(SCARD_DEVICE);
 
181
 
 
182
                scard->device.type = RDPDR_DTYP_SMARTCARD;
 
183
                scard->device.name = "SCARD";
 
184
                scard->device.IRPRequest = scard_irp_request;
 
185
                scard->device.Free = scard_free;
 
186
 
 
187
                length = strlen(scard->device.name);
 
188
                scard->device.data = stream_new(length + 1);
 
189
 
 
190
                for (i = 0; i <= length; i++)
 
191
                        stream_write_uint8(scard->device.data, name[i] < 0 ? '_' : name[i]);
 
192
 
 
193
                scard->path = path;
 
194
 
 
195
                scard->irp_list = list_new();
 
196
                scard->thread = freerdp_thread_new();
 
197
 
 
198
                pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE *)scard);
 
199
 
 
200
                freerdp_thread_start(scard->thread, scard_thread_func, scard);
 
201
        }
 
202
 
 
203
        return 0;
 
204
}