📄 osx.c
字号:
} return NULL;}static unsigned long HIDCloseReleaseInterface (pRecDevice pDevice){ IOReturn result = kIOReturnSuccess; if (HIDIsValidDevice(pDevice) && (NULL != pDevice->interface)) { // close the interface result = (*(IOHIDDeviceInterface**) pDevice->interface)->close (pDevice->interface); if (kIOReturnNotOpen == result) { // do nothing as device was not opened, thus can't be closed } else if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to close IOHIDDeviceInterface.", result); //release the interface result = (*(IOHIDDeviceInterface**) pDevice->interface)->Release (pDevice->interface); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDCloseReleaseInterface - Failed to release interface.", result); pDevice->interface = NULL; } return result;}// ---------------------------------// count number of devices in global device list (gpDeviceList)static UInt32 hid_CountCurrentDevices (void){ pRecDevice pDevice = gpDeviceList; UInt32 devices = 0; while (pDevice) { devices++; pDevice = pDevice->pNext; } return devices;}static UInt32 HIDCountDevices (void){ gNumDevices = hid_CountCurrentDevices (); return gNumDevices;}static void hid_DisposeDeviceElements (pRecElement pElement){ if (pElement) { if (pElement->pChild) hid_DisposeDeviceElements (pElement->pChild); if (pElement->pSibling) hid_DisposeDeviceElements (pElement->pSibling); free (pElement); }}static pRecDevice hid_DisposeDevice (pRecDevice pDevice){ kern_return_t result = KERN_SUCCESS; pRecDevice pDeviceNext = NULL; if (HIDIsValidDevice(pDevice)) { // save next device prior to disposing of this device pDeviceNext = pDevice->pNext; result = HIDDequeueDevice (pDevice);#if 0 if (kIOReturnSuccess != result) HIDReportErrorNum ("hid_DisposeDevice: HIDDequeueDevice error: 0x%8.8X.", result);#endif 1 hid_DisposeDeviceElements (pDevice->pListElements); pDevice->pListElements = NULL; result = HIDCloseReleaseInterface (pDevice); // function sanity checks interface value (now application does not own device) if (kIOReturnSuccess != result) HIDReportErrorNum ("hid_DisposeDevice: HIDCloseReleaseInterface error: 0x%8.8X.", result);#if USE_NOTIFICATIONS if (pDevice->interface) { // replace (*pDevice->interface)->Release(pDevice->interface); result = IODestroyPlugInInterface (pDevice->interface); if (kIOReturnSuccess != result) HIDReportErrorNum ("hid_DisposeDevice: IODestroyPlugInInterface error: 0x%8.8X.", result); } if (pDevice->notification) { result = IOObjectRelease((io_object_t) pDevice->notification); if (kIOReturnSuccess != result) HIDReportErrorNum ("hid_DisposeDevice: IOObjectRelease error: 0x%8.8X.", result); }#endif USE_NOTIFICATIONS // remove this device from the device list if (gpDeviceList == pDevice) // head of list? gpDeviceList = pDeviceNext; else { pRecDevice pDeviceTemp = pDeviceNext = gpDeviceList; // we're going to return this if we don't find ourselfs in the list while (pDeviceTemp) { if (pDeviceTemp->pNext == pDevice) // found us! { // take us out of linked list pDeviceTemp->pNext = pDeviceNext = pDevice->pNext; break; } pDeviceTemp = pDeviceTemp->pNext; } } free (pDevice); } // update device count gNumDevices = hid_CountCurrentDevices (); return pDeviceNext;}// ---------------------------------// disposes and releases queue, sets queue to NULL,.// Note: will have no effect if device or queue do not existstatic IOReturn hid_DisposeReleaseQueue (pRecDevice pDevice){ IOReturn result = kIOReturnError; // assume failure (pessimist!) if (HIDIsValidDevice(pDevice)) // need valid device { if (pDevice->queue) // and queue { // stop queue result = (*(IOHIDQueueInterface**) pDevice->queue)->stop (pDevice->queue); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to stop queue.", result); // dispose of queue result = (*(IOHIDQueueInterface**) pDevice->queue)->dispose (pDevice->queue); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to dipose queue.", result); // release the queue result = (*(IOHIDQueueInterface**) pDevice->queue)->Release (pDevice->queue); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("hid_DisposeReleaseQueue - Failed to release queue.", result); pDevice->queue = NULL; } else HIDREPORTERROR ("hid_DisposeReleaseQueue - no queue."); } else HIDREPORTERROR ("hid_DisposeReleaseQueue - Invalid device."); return result;}// ---------------------------------// completely removes all elements from queue and releases queue and closes device interface// does not release device interfaces, application must call HIDReleaseDeviceList on exitstatic unsigned long HIDDequeueDevice (pRecDevice pDevice){ IOReturn result = kIOReturnSuccess; if (HIDIsValidDevice(pDevice)) { if ((pDevice->interface) && (pDevice->queue)) { // iterate through elements and if queued, remove pRecElement pElement = HIDGetFirstDeviceElement (pDevice, kHIDElementTypeIO); while (pElement) { if ((*(IOHIDQueueInterface**) pDevice->queue)->hasElement (pDevice->queue, pElement->cookie)) { result = (*(IOHIDQueueInterface**) pDevice->queue)->removeElement (pDevice->queue, pElement->cookie); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDDequeueDevice - Failed to remove element from queue.", result); } pElement = HIDGetNextDeviceElement (pElement, kHIDElementTypeIO); } } // ensure queue is disposed and released // interface will be closed and released on call to HIDReleaseDeviceList result = hid_DisposeReleaseQueue (pDevice); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("removeElement - Failed to dispose and release queue.", result);#if USE_ASYNC_EVENTS else if (NULL != pDevice->queueRunLoopSource) { if (CFRunLoopContainsSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode)) CFRunLoopRemoveSource(CFRunLoopGetCurrent(), pDevice->queueRunLoopSource, kCFRunLoopDefaultMode); CFRelease(pDevice->queueRunLoopSource); pDevice->queueRunLoopSource = NULL; }#endif USE_ASYNC_EVENTS } else { HIDREPORTERROR ("HIDDequeueDevice - Invalid device."); result = kIOReturnBadArgument; } return result;}// ---------------------------------// releases all device queues for quit or rebuild (must be called)// does not release device interfaces, application must call HIDReleaseDeviceList on exitstatic unsigned long HIDReleaseAllDeviceQueues (void){ IOReturn result = kIOReturnBadArgument; pRecDevice pDevice = HIDGetFirstDevice (); while (pDevice) { result = HIDDequeueDevice (pDevice); if (kIOReturnSuccess != result) HIDREPORTERRORNUM ("HIDReleaseAllDeviceQueues - Could not dequeue device.", result); pDevice = HIDGetNextDevice (pDevice); } return result;}// ---------------------------------// Get the next event in the queue for a device// elements or entire device should be queued prior to calling this with HIDQueueElement or HIDQueueDevice// returns true if an event is avialable for the element and fills out *pHIDEvent structure, returns false otherwise// Note: kIOReturnUnderrun returned from getNextEvent indicates an empty queue not an error condition// Note: application should pass in a pointer to a IOHIDEventStruct cast to a void (for CFM compatibility)static unsigned char HIDGetEvent (pRecDevice pDevice, void * pHIDEvent){ IOReturn result = kIOReturnBadArgument; AbsoluteTime zeroTime = {0,0}; if (HIDIsValidDevice(pDevice)) { if (pDevice->queue) { result = (*(IOHIDQueueInterface**) pDevice->queue)->getNextEvent (pDevice->queue, (IOHIDEventStruct *)pHIDEvent, zeroTime, 0); if (kIOReturnUnderrun == result) return false; // no events in queue not an error per say else if (kIOReturnSuccess != result) // actual error versus just an empty queue HIDREPORTERRORNUM ("HIDGetEvent - Could not get HID event via getNextEvent.", result); else return true; } else HIDREPORTERROR ("HIDGetEvent - queue does not exist."); } else HIDREPORTERROR ("HIDGetEvent - invalid device."); return false; // did not get event}static unsigned long HIDCreateOpenDeviceInterface (UInt32 hidDevice, pRecDevice pDevice){ IOReturn result = kIOReturnSuccess; HRESULT plugInResult = S_OK; SInt32 score = 0; IOCFPlugInInterface ** ppPlugInInterface = NULL; if (NULL == pDevice->interface) { result = IOCreatePlugInInterfaceForService (hidDevice, kIOHIDDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &ppPlugInInterface, &score); if (kIOReturnSuccess == result) { // Call a method of the intermediate plug-in to create the device interface plugInResult = (*ppPlugInInterface)->QueryInterface (ppPlugInInterface, CFUUIDGetUUIDBytes (kIOHIDDeviceInterfaceID), (void *) &(pDevice->interface)); if (S_OK != plugInResult) HIDReportErrorNum ("CouldnÕt query HID class device interface from plugInInterface", plugInResult); IODestroyPlugInInterface (ppPlugInInterface); // replace (*ppPlugInInterface)->Release (ppPlugInInterface) } else HIDReportErrorNum ("Failed to create **plugInInterface via IOCreatePlugInInterfaceForService.", result); } if (NULL != pDevice->interface) { result = (*(IOHIDDeviceInterface**)pDevice->interface)->open (pDevice->interface, 0); if (kIOReturnSuccess != result) HIDReportErrorNum ("Failed to open pDevice->interface via open.", result); } return result;}// ---------------------------------// adds device to linked list of devices passed in (handles NULL lists properly)// (returns where you just stored it)static pRecDevice* hid_AddDevice (pRecDevice *ppListDeviceHead, pRecDevice pNewDevice){ pRecDevice* result = NULL; if (NULL == *ppListDeviceHead) result = ppListDeviceHead; else { pRecDevice pDevicePrevious = NULL, pDevice = *ppListDeviceHead; while (pDevice) { pDevicePrevious = pDevice; pDevice = pDevicePrevious->pNext; } result = &pDevicePrevious->pNext; } pNewDevice->pNext = NULL; *result = pNewDevice; return result;}static pRecDevice hid_BuildDevice (io_object_t hidDevice){ pRecDevice pDevice = (pRecDevice) malloc (sizeof (recDevice)); if (NULL != pDevice) { // get dictionary for HID properties CFMutableDictionaryRef hidProperties = 0; kern_return_t result = IORegistryEntryCreateCFProperties (hidDevice, &hidProperties, kCFAllocatorDefault, kNilOptions); // clear record bzero(pDevice, sizeof(recDevice)); if ((result == KERN_SUCCESS) && (NULL != hidProperties))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -