| File: | Xi/listdev.c |
| Location: | line 128, column 9 |
| Description: | String copy function overflows destination buffer |
| 1 | /************************************************************ | |||||
| 2 | ||||||
| 3 | Copyright 1989, 1998 The Open Group | |||||
| 4 | ||||||
| 5 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
| 6 | documentation for any purpose is hereby granted without fee, provided that | |||||
| 7 | the above copyright notice appear in all copies and that both that | |||||
| 8 | copyright notice and this permission notice appear in supporting | |||||
| 9 | documentation. | |||||
| 10 | ||||||
| 11 | The above copyright notice and this permission notice shall be included in | |||||
| 12 | all copies or substantial portions of the Software. | |||||
| 13 | ||||||
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
| 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
| 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
| 17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
| 18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
| 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
| 20 | ||||||
| 21 | Except as contained in this notice, the name of The Open Group shall not be | |||||
| 22 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
| 23 | in this Software without prior written authorization from The Open Group. | |||||
| 24 | ||||||
| 25 | Copyright 1989 by Hewlett-Packard Company, Palo Alto, California. | |||||
| 26 | ||||||
| 27 | All Rights Reserved | |||||
| 28 | ||||||
| 29 | Permission to use, copy, modify, and distribute this software and its | |||||
| 30 | documentation for any purpose and without fee is hereby granted, | |||||
| 31 | provided that the above copyright notice appear in all copies and that | |||||
| 32 | both that copyright notice and this permission notice appear in | |||||
| 33 | supporting documentation, and that the name of Hewlett-Packard not be | |||||
| 34 | used in advertising or publicity pertaining to distribution of the | |||||
| 35 | software without specific, written prior permission. | |||||
| 36 | ||||||
| 37 | HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||||
| 38 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||||
| 39 | HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||||
| 40 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||||
| 41 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||||
| 42 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||||
| 43 | SOFTWARE. | |||||
| 44 | ||||||
| 45 | ********************************************************/ | |||||
| 46 | ||||||
| 47 | /*********************************************************************** | |||||
| 48 | * | |||||
| 49 | * Extension function to list the available input devices. | |||||
| 50 | * | |||||
| 51 | */ | |||||
| 52 | ||||||
| 53 | #ifdef HAVE_DIX_CONFIG_H1 | |||||
| 54 | #include <dix-config.h> | |||||
| 55 | #endif | |||||
| 56 | ||||||
| 57 | #include <X11/X.h> /* for inputstr.h */ | |||||
| 58 | #include <X11/Xproto.h> /* Request macro */ | |||||
| 59 | #include "inputstr.h" /* DeviceIntPtr */ | |||||
| 60 | #include <X11/extensions/XI.h> | |||||
| 61 | #include <X11/extensions/XIproto.h> | |||||
| 62 | #include "XIstubs.h" | |||||
| 63 | #include "extnsionst.h" | |||||
| 64 | #include "exevents.h" | |||||
| 65 | #include "xace.h" | |||||
| 66 | #include "xkbsrv.h" | |||||
| 67 | #include "xkbstr.h" | |||||
| 68 | ||||||
| 69 | #include "listdev.h" | |||||
| 70 | ||||||
| 71 | /*********************************************************************** | |||||
| 72 | * | |||||
| 73 | * This procedure lists the input devices available to the server. | |||||
| 74 | * | |||||
| 75 | */ | |||||
| 76 | ||||||
| 77 | int | |||||
| 78 | SProcXListInputDevices(ClientPtr client) | |||||
| 79 | { | |||||
| 80 | REQUEST(xListInputDevicesReq)xListInputDevicesReq *stuff = (xListInputDevicesReq *)client-> requestBuffer; | |||||
| 81 | swaps(&stuff->length)do { if (sizeof(*(&stuff->length)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&stuff->length) & 1) && ((uintptr_t)(&stuff->length) & 1) == 0) *(&stuff->length) = lswaps(*(&stuff->length )); else swap_uint16((uint16_t *)(&stuff->length)); } while (0); | |||||
| 82 | return (ProcXListInputDevices(client)); | |||||
| ||||||
| 83 | } | |||||
| 84 | ||||||
| 85 | /*********************************************************************** | |||||
| 86 | * | |||||
| 87 | * This procedure calculates the size of the information to be returned | |||||
| 88 | * for an input device. | |||||
| 89 | * | |||||
| 90 | */ | |||||
| 91 | ||||||
| 92 | static void | |||||
| 93 | SizeDeviceInfo(DeviceIntPtr d, int *namesize, int *size) | |||||
| 94 | { | |||||
| 95 | int chunks; | |||||
| 96 | ||||||
| 97 | *namesize += 1; | |||||
| 98 | if (d->name) | |||||
| 99 | *namesize += strlen(d->name); | |||||
| 100 | if (d->key != NULL((void*)0)) | |||||
| 101 | *size += sizeof(xKeyInfo); | |||||
| 102 | if (d->button != NULL((void*)0)) | |||||
| 103 | *size += sizeof(xButtonInfo); | |||||
| 104 | if (d->valuator != NULL((void*)0)) { | |||||
| 105 | chunks = ((int) d->valuator->numAxes + 19) / VPC20; | |||||
| 106 | *size += (chunks * sizeof(xValuatorInfo) + | |||||
| 107 | d->valuator->numAxes * sizeof(xAxisInfo)); | |||||
| 108 | } | |||||
| 109 | } | |||||
| 110 | ||||||
| 111 | /*********************************************************************** | |||||
| 112 | * | |||||
| 113 | * This procedure copies data to the DeviceInfo struct, swapping if necessary. | |||||
| 114 | * | |||||
| 115 | * We need the extra byte in the allocated buffer, because the trailing null | |||||
| 116 | * hammers one extra byte, which is overwritten by the next name except for | |||||
| 117 | * the last name copied. | |||||
| 118 | * | |||||
| 119 | */ | |||||
| 120 | ||||||
| 121 | static void | |||||
| 122 | CopyDeviceName(char **namebuf, const char *name) | |||||
| 123 | { | |||||
| 124 | char *nameptr = *namebuf; | |||||
| 125 | ||||||
| 126 | if (name) { | |||||
| 127 | *nameptr++ = strlen(name); | |||||
| 128 | strcpy(nameptr, name)__builtin___strcpy_chk (nameptr, name, __builtin_object_size ( nameptr, 2 > 1 ? 1 : 0)); | |||||
| ||||||
| 129 | *namebuf += (strlen(name) + 1); | |||||
| 130 | } | |||||
| 131 | else { | |||||
| 132 | *nameptr++ = 0; | |||||
| 133 | *namebuf += 1; | |||||
| 134 | } | |||||
| 135 | } | |||||
| 136 | ||||||
| 137 | /*********************************************************************** | |||||
| 138 | * | |||||
| 139 | * This procedure copies ButtonClass information, swapping if necessary. | |||||
| 140 | * | |||||
| 141 | */ | |||||
| 142 | ||||||
| 143 | static void | |||||
| 144 | CopySwapButtonClass(ClientPtr client, ButtonClassPtr b, char **buf) | |||||
| 145 | { | |||||
| 146 | xButtonInfoPtr b2; | |||||
| 147 | ||||||
| 148 | b2 = (xButtonInfoPtr) * buf; | |||||
| 149 | b2->class = ButtonClass1; | |||||
| 150 | b2->length = sizeof(xButtonInfo); | |||||
| 151 | b2->num_buttons = b->numButtons; | |||||
| 152 | if (client && client->swapped) { | |||||
| 153 | swaps(&b2->num_buttons)do { if (sizeof(*(&b2->num_buttons)) != 2) wrong_size( ); if (__builtin_constant_p((uintptr_t)(&b2->num_buttons ) & 1) && ((uintptr_t)(&b2->num_buttons) & 1) == 0) *(&b2->num_buttons) = lswaps(*(&b2->num_buttons )); else swap_uint16((uint16_t *)(&b2->num_buttons)); } while (0); | |||||
| 154 | } | |||||
| 155 | *buf += sizeof(xButtonInfo); | |||||
| 156 | } | |||||
| 157 | ||||||
| 158 | /*********************************************************************** | |||||
| 159 | * | |||||
| 160 | * This procedure copies data to the DeviceInfo struct, swapping if necessary. | |||||
| 161 | * | |||||
| 162 | */ | |||||
| 163 | ||||||
| 164 | static void | |||||
| 165 | CopySwapDevice(ClientPtr client, DeviceIntPtr d, int num_classes, char **buf) | |||||
| 166 | { | |||||
| 167 | xDeviceInfoPtr dev; | |||||
| 168 | ||||||
| 169 | dev = (xDeviceInfoPtr) * buf; | |||||
| 170 | ||||||
| 171 | dev->id = d->id; | |||||
| 172 | dev->type = d->xinput_type; | |||||
| 173 | dev->num_classes = num_classes; | |||||
| 174 | if (IsMaster(d) && IsKeyboardDevice(d)) | |||||
| 175 | dev->use = IsXKeyboard1; | |||||
| 176 | else if (IsMaster(d) && IsPointerDevice(d)) | |||||
| 177 | dev->use = IsXPointer0; | |||||
| 178 | else if (d->valuator && d->button) | |||||
| 179 | dev->use = IsXExtensionPointer4; | |||||
| 180 | else if (d->key && d->kbdfeed) | |||||
| 181 | dev->use = IsXExtensionKeyboard3; | |||||
| 182 | else | |||||
| 183 | dev->use = IsXExtensionDevice2; | |||||
| 184 | ||||||
| 185 | if (client->swapped) { | |||||
| 186 | swapl(&dev->type)do { if (sizeof(*(&dev->type)) != 4) wrong_size(); if ( __builtin_constant_p((uintptr_t)(&dev->type) & 3) && ((uintptr_t)(&dev->type) & 3) == 0) *(&dev-> type) = lswapl(*(&dev->type)); else swap_uint32((uint32_t *)(&dev->type)); } while (0); | |||||
| 187 | } | |||||
| 188 | *buf += sizeof(xDeviceInfo); | |||||
| 189 | } | |||||
| 190 | ||||||
| 191 | /*********************************************************************** | |||||
| 192 | * | |||||
| 193 | * This procedure copies KeyClass information, swapping if necessary. | |||||
| 194 | * | |||||
| 195 | */ | |||||
| 196 | ||||||
| 197 | static void | |||||
| 198 | CopySwapKeyClass(ClientPtr client, KeyClassPtr k, char **buf) | |||||
| 199 | { | |||||
| 200 | xKeyInfoPtr k2; | |||||
| 201 | ||||||
| 202 | k2 = (xKeyInfoPtr) * buf; | |||||
| 203 | k2->class = KeyClass0; | |||||
| 204 | k2->length = sizeof(xKeyInfo); | |||||
| 205 | k2->min_keycode = k->xkbInfo->desc->min_key_code; | |||||
| 206 | k2->max_keycode = k->xkbInfo->desc->max_key_code; | |||||
| 207 | k2->num_keys = k2->max_keycode - k2->min_keycode + 1; | |||||
| 208 | if (client && client->swapped) { | |||||
| 209 | swaps(&k2->num_keys)do { if (sizeof(*(&k2->num_keys)) != 2) wrong_size(); if (__builtin_constant_p((uintptr_t)(&k2->num_keys) & 1) && ((uintptr_t)(&k2->num_keys) & 1) == 0) *(&k2->num_keys) = lswaps(*(&k2->num_keys)) ; else swap_uint16((uint16_t *)(&k2->num_keys)); } while (0); | |||||
| 210 | } | |||||
| 211 | *buf += sizeof(xKeyInfo); | |||||
| 212 | } | |||||
| 213 | ||||||
| 214 | /*********************************************************************** | |||||
| 215 | * | |||||
| 216 | * This procedure copies ValuatorClass information, swapping if necessary. | |||||
| 217 | * | |||||
| 218 | * Devices may have up to 255 valuators. The length of a ValuatorClass is | |||||
| 219 | * defined to be sizeof(ValuatorClassInfo) + num_axes * sizeof (xAxisInfo). | |||||
| 220 | * The maximum length is therefore (8 + 255 * 12) = 3068. However, the | |||||
| 221 | * length field is one byte. If a device has more than 20 valuators, we | |||||
| 222 | * must therefore return multiple valuator classes to the client. | |||||
| 223 | * | |||||
| 224 | */ | |||||
| 225 | ||||||
| 226 | static int | |||||
| 227 | CopySwapValuatorClass(ClientPtr client, DeviceIntPtr dev, char **buf) | |||||
| 228 | { | |||||
| 229 | int i, j, axes, t_axes; | |||||
| 230 | ValuatorClassPtr v = dev->valuator; | |||||
| 231 | xValuatorInfoPtr v2; | |||||
| 232 | AxisInfo *a; | |||||
| 233 | xAxisInfoPtr a2; | |||||
| 234 | ||||||
| 235 | for (i = 0, axes = v->numAxes; i < ((v->numAxes + 19) / VPC20); | |||||
| 236 | i++, axes -= VPC20) { | |||||
| 237 | t_axes = axes < VPC20 ? axes : VPC20; | |||||
| 238 | if (t_axes < 0) | |||||
| 239 | t_axes = v->numAxes % VPC20; | |||||
| 240 | v2 = (xValuatorInfoPtr) * buf; | |||||
| 241 | v2->class = ValuatorClass2; | |||||
| 242 | v2->length = sizeof(xValuatorInfo) + t_axes * sizeof(xAxisInfo); | |||||
| 243 | v2->num_axes = t_axes; | |||||
| 244 | v2->mode = valuator_get_mode(dev, 0); | |||||
| 245 | v2->motion_buffer_size = v->numMotionEvents; | |||||
| 246 | if (client && client->swapped) { | |||||
| 247 | swapl(&v2->motion_buffer_size)do { if (sizeof(*(&v2->motion_buffer_size)) != 4) wrong_size (); if (__builtin_constant_p((uintptr_t)(&v2->motion_buffer_size ) & 3) && ((uintptr_t)(&v2->motion_buffer_size ) & 3) == 0) *(&v2->motion_buffer_size) = lswapl(* (&v2->motion_buffer_size)); else swap_uint32((uint32_t *)(&v2->motion_buffer_size)); } while (0); | |||||
| 248 | } | |||||
| 249 | *buf += sizeof(xValuatorInfo); | |||||
| 250 | a = v->axes + (VPC20 * i); | |||||
| 251 | a2 = (xAxisInfoPtr) * buf; | |||||
| 252 | for (j = 0; j < t_axes; j++) { | |||||
| 253 | a2->min_value = a->min_value; | |||||
| 254 | a2->max_value = a->max_value; | |||||
| 255 | a2->resolution = a->resolution; | |||||
| 256 | if (client && client->swapped) { | |||||
| 257 | swapl(&a2->min_value)do { if (sizeof(*(&a2->min_value)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&a2->min_value) & 3) && ((uintptr_t)(&a2->min_value) & 3) == 0) *(&a2->min_value) = lswapl(*(&a2->min_value )); else swap_uint32((uint32_t *)(&a2->min_value)); } while (0); | |||||
| 258 | swapl(&a2->max_value)do { if (sizeof(*(&a2->max_value)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&a2->max_value) & 3) && ((uintptr_t)(&a2->max_value) & 3) == 0) *(&a2->max_value) = lswapl(*(&a2->max_value )); else swap_uint32((uint32_t *)(&a2->max_value)); } while (0); | |||||
| 259 | swapl(&a2->resolution)do { if (sizeof(*(&a2->resolution)) != 4) wrong_size() ; if (__builtin_constant_p((uintptr_t)(&a2->resolution ) & 3) && ((uintptr_t)(&a2->resolution) & 3) == 0) *(&a2->resolution) = lswapl(*(&a2->resolution )); else swap_uint32((uint32_t *)(&a2->resolution)); } while (0); | |||||
| 260 | } | |||||
| 261 | a2++; | |||||
| 262 | a++; | |||||
| 263 | *buf += sizeof(xAxisInfo); | |||||
| 264 | } | |||||
| 265 | } | |||||
| 266 | return i; | |||||
| 267 | } | |||||
| 268 | ||||||
| 269 | static void | |||||
| 270 | CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, | |||||
| 271 | char **classbuf) | |||||
| 272 | { | |||||
| 273 | if (dev->key != NULL((void*)0)) { | |||||
| 274 | CopySwapKeyClass(client, dev->key, classbuf); | |||||
| 275 | (*num_classes)++; | |||||
| 276 | } | |||||
| 277 | if (dev->button != NULL((void*)0)) { | |||||
| 278 | CopySwapButtonClass(client, dev->button, classbuf); | |||||
| 279 | (*num_classes)++; | |||||
| 280 | } | |||||
| 281 | if (dev->valuator != NULL((void*)0)) { | |||||
| 282 | (*num_classes) += CopySwapValuatorClass(client, dev, classbuf); | |||||
| 283 | } | |||||
| 284 | } | |||||
| 285 | ||||||
| 286 | /*********************************************************************** | |||||
| 287 | * | |||||
| 288 | * This procedure lists information to be returned for an input device. | |||||
| 289 | * | |||||
| 290 | */ | |||||
| 291 | ||||||
| 292 | static void | |||||
| 293 | ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev, | |||||
| 294 | char **devbuf, char **classbuf, char **namebuf) | |||||
| 295 | { | |||||
| 296 | CopyDeviceName(namebuf, d->name); | |||||
| 297 | CopySwapDevice(client, d, 0, devbuf); | |||||
| 298 | CopySwapClasses(client, d, &dev->num_classes, classbuf); | |||||
| 299 | } | |||||
| 300 | ||||||
| 301 | /*********************************************************************** | |||||
| 302 | * | |||||
| 303 | * This procedure checks if a device should be left off the list. | |||||
| 304 | * | |||||
| 305 | */ | |||||
| 306 | ||||||
| 307 | static Bool | |||||
| 308 | ShouldSkipDevice(ClientPtr client, DeviceIntPtr d) | |||||
| 309 | { | |||||
| 310 | /* don't send master devices other than VCP/VCK */ | |||||
| 311 | if (!IsMaster(d) || d == inputInfo.pointer ||d == inputInfo.keyboard) { | |||||
| 312 | int rc = XaceHook(XACE_DEVICE_ACCESS3, client, d, DixGetAttrAccess(1<<4)); | |||||
| 313 | ||||||
| 314 | if (rc == Success0) | |||||
| 315 | return FALSE0; | |||||
| 316 | } | |||||
| 317 | return TRUE1; | |||||
| 318 | } | |||||
| 319 | ||||||
| 320 | /*********************************************************************** | |||||
| 321 | * | |||||
| 322 | * This procedure lists the input devices available to the server. | |||||
| 323 | * | |||||
| 324 | * If this request is called by a client that has not issued a | |||||
| 325 | * GetExtensionVersion request with major/minor version set, we don't send the | |||||
| 326 | * complete device list. Instead, we only send the VCP, the VCK and floating | |||||
| 327 | * SDs. This resembles the setup found on XI 1.x machines. | |||||
| 328 | */ | |||||
| 329 | ||||||
| 330 | int | |||||
| 331 | ProcXListInputDevices(ClientPtr client) | |||||
| 332 | { | |||||
| 333 | xListInputDevicesReply rep; | |||||
| 334 | int numdevs = 0; | |||||
| 335 | int namesize = 1; /* need 1 extra byte for strcpy */ | |||||
| 336 | int i = 0, size = 0; | |||||
| 337 | int total_length; | |||||
| 338 | char *devbuf, *classbuf, *namebuf, *savbuf; | |||||
| 339 | Bool *skip; | |||||
| 340 | xDeviceInfo *dev; | |||||
| 341 | DeviceIntPtr d; | |||||
| 342 | ||||||
| 343 | REQUEST_SIZE_MATCH(xListInputDevicesReq)if ((sizeof(xListInputDevicesReq) >> 2) != client->req_len ) return(16); | |||||
| 344 | ||||||
| 345 | rep = (xListInputDevicesReply) { | |||||
| 346 | .repType = X_Reply1, | |||||
| 347 | .RepType = X_ListInputDevices2, | |||||
| 348 | .sequenceNumber = client->sequence, | |||||
| 349 | .length = 0 | |||||
| 350 | }; | |||||
| 351 | ||||||
| 352 | /* allocate space for saving skip value */ | |||||
| 353 | skip = calloc(sizeof(Bool), inputInfo.numDevices); | |||||
| 354 | if (!skip) | |||||
| 355 | return BadAlloc11; | |||||
| 356 | ||||||
| 357 | /* figure out which devices to skip */ | |||||
| 358 | numdevs = 0; | |||||
| 359 | for (d = inputInfo.devices; d; d = d->next, i++) { | |||||
| 360 | skip[i] = ShouldSkipDevice(client, d); | |||||
| 361 | if (skip[i]) | |||||
| 362 | continue; | |||||
| 363 | ||||||
| 364 | SizeDeviceInfo(d, &namesize, &size); | |||||
| 365 | numdevs++; | |||||
| 366 | } | |||||
| 367 | ||||||
| 368 | for (d = inputInfo.off_devices; d; d = d->next, i++) { | |||||
| 369 | skip[i] = ShouldSkipDevice(client, d); | |||||
| 370 | if (skip[i]) | |||||
| 371 | continue; | |||||
| 372 | ||||||
| 373 | SizeDeviceInfo(d, &namesize, &size); | |||||
| 374 | numdevs++; | |||||
| 375 | } | |||||
| 376 | ||||||
| 377 | /* allocate space for reply */ | |||||
| 378 | total_length = numdevs * sizeof(xDeviceInfo) + size + namesize; | |||||
| 379 | devbuf = (char *) calloc(1, total_length); | |||||
| 380 | classbuf = devbuf + (numdevs * sizeof(xDeviceInfo)); | |||||
| 381 | namebuf = classbuf + size; | |||||
| 382 | savbuf = devbuf; | |||||
| 383 | ||||||
| 384 | /* fill in and send reply */ | |||||
| 385 | i = 0; | |||||
| 386 | dev = (xDeviceInfoPtr) devbuf; | |||||
| 387 | for (d = inputInfo.devices; d; d = d->next, i++) { | |||||
| 388 | if (skip[i]) | |||||
| 389 | continue; | |||||
| 390 | ||||||
| 391 | ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); | |||||
| 392 | } | |||||
| 393 | ||||||
| 394 | for (d = inputInfo.off_devices; d; d = d->next, i++) { | |||||
| 395 | if (skip[i]) | |||||
| 396 | continue; | |||||
| 397 | ||||||
| 398 | ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); | |||||
| 399 | } | |||||
| 400 | rep.ndevices = numdevs; | |||||
| 401 | rep.length = bytes_to_int32(total_length); | |||||
| 402 | WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep){ if ((client)->swapped) (*ReplySwapVector[((xReq *)(client )->requestBuffer)->reqType]) (client, (int)(sizeof(xListInputDevicesReply )), &rep); else WriteToClient(client, (int)(sizeof(xListInputDevicesReply )), (&rep)); }; | |||||
| 403 | WriteToClient(client, total_length, savbuf); | |||||
| 404 | free(savbuf); | |||||
| 405 | free(skip); | |||||
| 406 | return Success0; | |||||
| 407 | } | |||||
| 408 | ||||||
| 409 | /*********************************************************************** | |||||
| 410 | * | |||||
| 411 | * This procedure writes the reply for the XListInputDevices function, | |||||
| 412 | * if the client and server have a different byte ordering. | |||||
| 413 | * | |||||
| 414 | */ | |||||
| 415 | ||||||
| 416 | void | |||||
| 417 | SRepXListInputDevices(ClientPtr client, int size, xListInputDevicesReply * rep) | |||||
| 418 | { | |||||
| 419 | swaps(&rep->sequenceNumber)do { if (sizeof(*(&rep->sequenceNumber)) != 2) wrong_size (); if (__builtin_constant_p((uintptr_t)(&rep->sequenceNumber ) & 1) && ((uintptr_t)(&rep->sequenceNumber ) & 1) == 0) *(&rep->sequenceNumber) = lswaps(*(& rep->sequenceNumber)); else swap_uint16((uint16_t *)(& rep->sequenceNumber)); } while (0); | |||||
| 420 | swapl(&rep->length)do { if (sizeof(*(&rep->length)) != 4) wrong_size(); if (__builtin_constant_p((uintptr_t)(&rep->length) & 3) && ((uintptr_t)(&rep->length) & 3) == 0 ) *(&rep->length) = lswapl(*(&rep->length)); else swap_uint32((uint32_t *)(&rep->length)); } while (0); | |||||
| 421 | WriteToClient(client, size, rep); | |||||
| 422 | } |