1 /**
2 * FreeRDP: A Remote Desktop Protocol Implementation
3 * Device Redirection Virtual Channel
4 *
5 * Copyright 2010-2011 Vic Lee
6 * Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Copyright 2015 Thincast Technologies GmbH
8 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <winpr/crt.h>
32 #include <winpr/stream.h>
33
34 #include "rdpdr_main.h"
35 #include "devman.h"
36 #include "irp.h"
37
38 /**
39 * Function description
40 *
41 * @return 0 on success, otherwise a Win32 error code
42 */
irp_free(IRP * irp)43 static UINT irp_free(IRP* irp)
44 {
45 if (!irp)
46 return CHANNEL_RC_OK;
47
48 Stream_Free(irp->input, TRUE);
49 Stream_Free(irp->output, TRUE);
50
51 _aligned_free(irp);
52 return CHANNEL_RC_OK;
53 }
54
55 /**
56 * Function description
57 *
58 * @return 0 on success, otherwise a Win32 error code
59 */
irp_complete(IRP * irp)60 static UINT irp_complete(IRP* irp)
61 {
62 size_t pos;
63 rdpdrPlugin* rdpdr;
64 UINT error;
65
66 rdpdr = (rdpdrPlugin*)irp->devman->plugin;
67
68 pos = Stream_GetPosition(irp->output);
69 Stream_SetPosition(irp->output, RDPDR_DEVICE_IO_RESPONSE_LENGTH - 4);
70 Stream_Write_UINT32(irp->output, irp->IoStatus); /* IoStatus (4 bytes) */
71 Stream_SetPosition(irp->output, pos);
72
73 error = rdpdr_send(rdpdr, irp->output);
74 irp->output = NULL;
75
76 return irp_free(irp);
77 }
78
irp_new(DEVMAN * devman,wStream * s,UINT * error)79 IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
80 {
81 IRP* irp;
82 DEVICE* device;
83 UINT32 DeviceId;
84
85 if (Stream_GetRemainingLength(s) < 20)
86 {
87 if (error)
88 *error = ERROR_INVALID_DATA;
89 return NULL;
90 }
91
92 Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
93 device = devman_get_device_by_id(devman, DeviceId);
94
95 if (!device)
96 {
97 WLog_WARN(TAG, "devman_get_device_by_id failed!");
98 if (error)
99 *error = CHANNEL_RC_OK;
100
101 return NULL;
102 };
103
104 irp = (IRP*)_aligned_malloc(sizeof(IRP), MEMORY_ALLOCATION_ALIGNMENT);
105
106 if (!irp)
107 {
108 WLog_ERR(TAG, "_aligned_malloc failed!");
109 if (error)
110 *error = CHANNEL_RC_NO_MEMORY;
111 return NULL;
112 }
113
114 ZeroMemory(irp, sizeof(IRP));
115
116 irp->input = s;
117 irp->device = device;
118 irp->devman = devman;
119
120 Stream_Read_UINT32(s, irp->FileId); /* FileId (4 bytes) */
121 Stream_Read_UINT32(s, irp->CompletionId); /* CompletionId (4 bytes) */
122 Stream_Read_UINT32(s, irp->MajorFunction); /* MajorFunction (4 bytes) */
123 Stream_Read_UINT32(s, irp->MinorFunction); /* MinorFunction (4 bytes) */
124
125 irp->output = Stream_New(NULL, 256);
126 if (!irp->output)
127 {
128 WLog_ERR(TAG, "Stream_New failed!");
129 _aligned_free(irp);
130 if (error)
131 *error = CHANNEL_RC_NO_MEMORY;
132 return NULL;
133 }
134 Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
135 Stream_Write_UINT16(irp->output, PAKID_CORE_DEVICE_IOCOMPLETION); /* PacketId (2 bytes) */
136 Stream_Write_UINT32(irp->output, DeviceId); /* DeviceId (4 bytes) */
137 Stream_Write_UINT32(irp->output, irp->CompletionId); /* CompletionId (4 bytes) */
138 Stream_Write_UINT32(irp->output, 0); /* IoStatus (4 bytes) */
139
140 irp->Complete = irp_complete;
141 irp->Discard = irp_free;
142
143 irp->thread = NULL;
144 irp->cancelled = FALSE;
145
146 if (error)
147 *error = CHANNEL_RC_OK;
148
149 return irp;
150 }
151