/** * FreeRDP: A Remote Desktop Protocol Implementation * RemoteFX USB Redirection * * Copyright 2012 Atrust corp. * Copyright 2012 Alfred Liu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "searchman.h" static void searchman_rewind(USB_SEARCHMAN* searchman) { searchman->idev = searchman->head; } static int searchman_has_next(USB_SEARCHMAN* searchman) { if (searchman->idev == NULL) return 0; else return 1; } static USB_SEARCHDEV* searchman_get_next(USB_SEARCHMAN* searchman) { USB_SEARCHDEV* search; search = searchman->idev; searchman->idev = (USB_SEARCHDEV*) searchman->idev->next; return search; } static int searchman_list_add(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct) { USB_SEARCHDEV* search; search = (USB_SEARCHDEV*) malloc(sizeof(USB_SEARCHDEV)); search->prev = NULL; search->next = NULL; search->idVendor = idVendor; search->idProduct = idProduct; if (searchman->head == NULL) { /* linked list is empty */ searchman->head = search; searchman->tail = search; } else { /* append device to the end of the linked list */ searchman->tail->next = (void*)search; search->prev = (void*)searchman->tail; searchman->tail = search; } searchman->usb_numbers += 1; return 1; } static int searchman_list_remove(USB_SEARCHMAN* searchman, UINT16 idVendor, UINT16 idProduct) { USB_SEARCHDEV* search; USB_SEARCHDEV* point; searchman_rewind(searchman); while (searchman_has_next(searchman) != 0) { point = searchman_get_next(searchman); if (point->idVendor == idVendor && point->idProduct == idProduct) { /* set previous device to point to next device */ search = point; if (search->prev != NULL) { /* unregistered device is not the head */ point = (USB_SEARCHDEV*)search->prev; point->next = search->next; } else { /* unregistered device is the head, update head */ searchman->head = (USB_SEARCHDEV*)search->next; } /* set next device to point to previous device */ if (search->next != NULL) { /* unregistered device is not the tail */ point = (USB_SEARCHDEV*)search->next; point->prev = search->prev; } else { /* unregistered device is the tail, update tail */ searchman->tail = (USB_SEARCHDEV*)search->prev; } searchman->usb_numbers--; free(search); return 1; /* unregistration successful */ } } /* if we reach this point, the device wasn't found */ return 0; } static void searchman_start(USB_SEARCHMAN* self, void* func) { pthread_t thread; /* create search thread */ pthread_create(&thread, 0, func, self); pthread_detach(thread); self->strated = 1; } /* close thread */ static void searchman_close(USB_SEARCHMAN* self) { SetEvent(self->term_event); } static void searchman_list_show(USB_SEARCHMAN* self) { int num = 0; USB_SEARCHDEV* usb; fprintf(stderr, "=========== Usb Search List ========= \n"); self->rewind(self); while (self->has_next(self)) { usb = self->get_next(self); fprintf(stderr, " USB %d: \n", num++); fprintf(stderr, " idVendor: 0x%04X \n", usb->idVendor); fprintf(stderr, " idProduct: 0x%04X \n", usb->idProduct); } fprintf(stderr, "================= END =============== \n"); } void searchman_free(USB_SEARCHMAN* self) { USB_SEARCHDEV * dev; while (self->head != NULL) { dev = (USB_SEARCHDEV *)self->head; self->remove (self, dev->idVendor, dev->idProduct); } /* free searchman */ sem_destroy(&self->sem_term); CloseHandle(self->term_event); free(self); } USB_SEARCHMAN* searchman_new(void * urbdrc, UINT32 UsbDevice) { int ret; USB_SEARCHMAN* searchman; searchman = (USB_SEARCHMAN*) malloc(sizeof(USB_SEARCHMAN)); searchman->idev = NULL; searchman->head = NULL; searchman->tail = NULL; searchman->usb_numbers = 0; searchman->urbdrc = urbdrc; searchman->UsbDevice = UsbDevice; ret = pthread_mutex_init(&searchman->mutex, NULL); if (ret != 0) { fprintf(stderr, "searchman mutex initialization: searchman->mutex failed"); exit(EXIT_FAILURE); } /* load service */ searchman->add = searchman_list_add; searchman->remove = searchman_list_remove; searchman->rewind = searchman_rewind; searchman->get_next = searchman_get_next; searchman->has_next = searchman_has_next; searchman->show = searchman_list_show; searchman->start = searchman_start; searchman->close = searchman_close; searchman->free = searchman_free; searchman->strated = 0; searchman->term_event = CreateEvent(NULL, TRUE, FALSE, NULL); sem_init(&searchman->sem_term, 0, 0); return searchman; }