├── .gitignore ├── LICENSE ├── Podfile ├── Podfile.lock ├── Pods ├── Manifest.lock ├── Pods.xcodeproj │ └── project.pbxproj ├── Target Support Files │ ├── Pods-UsbDetective │ │ ├── Info.plist │ │ ├── Pods-UsbDetective-acknowledgements.markdown │ │ ├── Pods-UsbDetective-acknowledgements.plist │ │ ├── Pods-UsbDetective-dummy.m │ │ ├── Pods-UsbDetective-frameworks.sh │ │ ├── Pods-UsbDetective-resources.sh │ │ ├── Pods-UsbDetective-umbrella.h │ │ ├── Pods-UsbDetective.debug.xcconfig │ │ ├── Pods-UsbDetective.modulemap │ │ └── Pods-UsbDetective.release.xcconfig │ └── USBDeviceSwift │ │ ├── Info.plist │ │ ├── USBDeviceSwift-dummy.m │ │ ├── USBDeviceSwift-prefix.pch │ │ ├── USBDeviceSwift-umbrella.h │ │ ├── USBDeviceSwift.modulemap │ │ └── USBDeviceSwift.xcconfig └── USBDeviceSwift │ ├── LICENSE │ ├── README.md │ └── Sources │ ├── HIDDevice.swift │ ├── HIDDeviceMonitor.swift │ ├── SerialDevice.swift │ ├── SerialDeviceMonitor.swift │ ├── USBDevice.swift │ ├── USBDeviceMonitor.swift │ └── USBDeviceSwift.h ├── README.md ├── UsbDetective.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── UsbDetective.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist └── UsbDetective ├── AboutWindowController.swift ├── AppDelegate.swift ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json └── Contents.json ├── BBUSBKit ├── BBBUSBDeviceDescriptor.swift ├── BBBUSBEndpoint.swift ├── BBBUSBInterface.swift ├── BBBUSBKit.swift ├── BBBUSBKitCore.h ├── BBBUSBKitCore.m ├── BBUSBDevice.swift ├── BBUSBKit.h ├── USBDeviceInterface.h ├── USBDeviceInterface.m ├── USBInterfaceInterface.h └── USBInterfaceInterface.m ├── Base.lproj └── Main.storyboard ├── Info.plist ├── NewDeviceViewController.swift ├── NewDeviceWindowController.swift ├── UsbDetective-Bridging-Header.h └── UsbDetective.entitlements /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots/**/*.png 68 | fastlane/test_output 69 | .DS_Store 70 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'UsbDetective' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for testusb 9 | 10 | pod 'USBDeviceSwift' 11 | 12 | end 13 | 14 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - USBDeviceSwift (1.0.3) 3 | 4 | DEPENDENCIES: 5 | - USBDeviceSwift 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - USBDeviceSwift 10 | 11 | SPEC CHECKSUMS: 12 | USBDeviceSwift: b9e85b70d8a78a2f4196881d7b673b7a8b9d117a 13 | 14 | PODFILE CHECKSUM: 36a78c02345241c2ff6ce71744e4c90423e40f2e 15 | 16 | COCOAPODS: 1.5.2 17 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - USBDeviceSwift (1.0.3) 3 | 4 | DEPENDENCIES: 5 | - USBDeviceSwift 6 | 7 | SPEC REPOS: 8 | https://github.com/cocoapods/specs.git: 9 | - USBDeviceSwift 10 | 11 | SPEC CHECKSUMS: 12 | USBDeviceSwift: b9e85b70d8a78a2f4196881d7b673b7a8b9d117a 13 | 14 | PODFILE CHECKSUM: 36a78c02345241c2ff6ce71744e4c90423e40f2e 15 | 16 | COCOAPODS: 1.5.2 17 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 07B184B9A7E8908DC47CDD400789C83F /* HIDDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = EED874C7032F049D59DA98C5A9FED7A7 /* HIDDevice.swift */; }; 11 | 100ED2DD8E4788A11603C2C7B34E49C5 /* USBDeviceSwift-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 566685BC478BEA7393B41E3EEF45B6BE /* USBDeviceSwift-dummy.m */; }; 12 | 2315E0F041D3098849A75AC7C87215AC /* USBDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 41B494F2E5F41B7337DCFDB3A194C7CC /* USBDeviceMonitor.swift */; }; 13 | 4547FFC1ABE44649336F8FFFD92B967E /* Pods-UsbDetective-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C4C526C6E1E1578C818DFD8A4649BA0F /* Pods-UsbDetective-dummy.m */; }; 14 | 4947000C11CB0416D1ABBB4B2C8D2A09 /* Pods-UsbDetective-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B4A4798D8C6C55E4B0F7C57BB05972D /* Pods-UsbDetective-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 4B264D3B54B7D1860DDA1979CF90C351 /* USBDeviceSwift.h in Headers */ = {isa = PBXBuildFile; fileRef = 74DE11A9211A5EB2B4D7F2FF0E4ABE7D /* USBDeviceSwift.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | 69EC789F69BD428DC3B0CBD38A60BE1C /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF428FC7C7A6555B2B02D8E238C8D8F2 /* Cocoa.framework */; }; 17 | 80BBE7C5723F641051A55D8854193855 /* SerialDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD675DE0BB807C16F0323D1C2C0B0213 /* SerialDevice.swift */; }; 18 | 8F967C443C3D453E1649876D77CFC711 /* HIDDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9197F474CC8DF6CD112DF72B60E6328F /* HIDDeviceMonitor.swift */; }; 19 | 9EDD821E001418A2B6378F435EF540DC /* USBDeviceSwift-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B8282C14BC1C7BE3E4FB79A894770B28 /* USBDeviceSwift-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 20 | C9754411263A09822C1A2090052CF44D /* SerialDeviceMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 406374066234B68058C55CFCD6F1F632 /* SerialDeviceMonitor.swift */; }; 21 | D996D15A927C82DB2739A728419EA014 /* USBDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD050B03F06F888811B50A870E246D20 /* USBDevice.swift */; }; 22 | D9F32ADE75B74E0E8E10D18BB012AB15 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DF428FC7C7A6555B2B02D8E238C8D8F2 /* Cocoa.framework */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | FB7FC6091AD9327C590E21E1E08234EB /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 29778B5182CE94884F1D597D2A27DCD0; 31 | remoteInfo = USBDeviceSwift; 32 | }; 33 | /* End PBXContainerItemProxy section */ 34 | 35 | /* Begin PBXFileReference section */ 36 | 07DDEBC3566388A62DB5A9666A006FDF /* Pods-UsbDetective.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-UsbDetective.modulemap"; sourceTree = ""; }; 37 | 0B4A4798D8C6C55E4B0F7C57BB05972D /* Pods-UsbDetective-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-UsbDetective-umbrella.h"; sourceTree = ""; }; 38 | 141C6EC1CA4665E3BD242829D17B1FCA /* USBDeviceSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = USBDeviceSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 1D7F06515083D42930CAF871915EB592 /* Pods-UsbDetective.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-UsbDetective.release.xcconfig"; sourceTree = ""; }; 40 | 1E5EE5DC271B4423F65F6041E9AF5CB3 /* USBDeviceSwift.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = USBDeviceSwift.xcconfig; sourceTree = ""; }; 41 | 1E84098D9BAEDB01676D2590A7B00DA2 /* Pods-UsbDetective-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-UsbDetective-acknowledgements.markdown"; sourceTree = ""; }; 42 | 406374066234B68058C55CFCD6F1F632 /* SerialDeviceMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDeviceMonitor.swift; path = Sources/SerialDeviceMonitor.swift; sourceTree = ""; }; 43 | 41B494F2E5F41B7337DCFDB3A194C7CC /* USBDeviceMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = USBDeviceMonitor.swift; path = Sources/USBDeviceMonitor.swift; sourceTree = ""; }; 44 | 463052CE656C20C14268C66FBD90F056 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 4F4A455D19212958D87424C8C8F5B10F /* Pods_UsbDetective.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UsbDetective.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 566685BC478BEA7393B41E3EEF45B6BE /* USBDeviceSwift-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "USBDeviceSwift-dummy.m"; sourceTree = ""; }; 47 | 6F0343DC7A9C20B125701EA956B93CE5 /* Pods-UsbDetective-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-UsbDetective-resources.sh"; sourceTree = ""; }; 48 | 74DE11A9211A5EB2B4D7F2FF0E4ABE7D /* USBDeviceSwift.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = USBDeviceSwift.h; path = Sources/USBDeviceSwift.h; sourceTree = ""; }; 49 | 782D561553CB5E843E2B297F16EFAFEE /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 50 | 80827FB941624A27B72F4A5A892082F5 /* Pods-UsbDetective-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-UsbDetective-acknowledgements.plist"; sourceTree = ""; }; 51 | 84F0E736AB88D601E87B350B2CBA64F1 /* Pods-UsbDetective-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-UsbDetective-frameworks.sh"; sourceTree = ""; }; 52 | 9197F474CC8DF6CD112DF72B60E6328F /* HIDDeviceMonitor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HIDDeviceMonitor.swift; path = Sources/HIDDeviceMonitor.swift; sourceTree = ""; }; 53 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 54 | 9E4D51AC2FEC6C2C599264A8D7D52AF9 /* USBDeviceSwift.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = USBDeviceSwift.modulemap; sourceTree = ""; }; 55 | AA5CC87BF198BBA39EF2CD5C9D5347F4 /* Pods-UsbDetective.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-UsbDetective.debug.xcconfig"; sourceTree = ""; }; 56 | B8282C14BC1C7BE3E4FB79A894770B28 /* USBDeviceSwift-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "USBDeviceSwift-umbrella.h"; sourceTree = ""; }; 57 | C4C526C6E1E1578C818DFD8A4649BA0F /* Pods-UsbDetective-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-UsbDetective-dummy.m"; sourceTree = ""; }; 58 | CB20F189B90D14179BE6CA231A3EF461 /* USBDeviceSwift-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "USBDeviceSwift-prefix.pch"; sourceTree = ""; }; 59 | CD675DE0BB807C16F0323D1C2C0B0213 /* SerialDevice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SerialDevice.swift; path = Sources/SerialDevice.swift; sourceTree = ""; }; 60 | DD050B03F06F888811B50A870E246D20 /* USBDevice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = USBDevice.swift; path = Sources/USBDevice.swift; sourceTree = ""; }; 61 | DF428FC7C7A6555B2B02D8E238C8D8F2 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 62 | EED874C7032F049D59DA98C5A9FED7A7 /* HIDDevice.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HIDDevice.swift; path = Sources/HIDDevice.swift; sourceTree = ""; }; 63 | /* End PBXFileReference section */ 64 | 65 | /* Begin PBXFrameworksBuildPhase section */ 66 | 620BE27B49984A69ADB42C14C9EBD413 /* Frameworks */ = { 67 | isa = PBXFrameworksBuildPhase; 68 | buildActionMask = 2147483647; 69 | files = ( 70 | 69EC789F69BD428DC3B0CBD38A60BE1C /* Cocoa.framework in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | D8FA91AA8B91E6CC9E6E8FBB017846FE /* Frameworks */ = { 75 | isa = PBXFrameworksBuildPhase; 76 | buildActionMask = 2147483647; 77 | files = ( 78 | D9F32ADE75B74E0E8E10D18BB012AB15 /* Cocoa.framework in Frameworks */, 79 | ); 80 | runOnlyForDeploymentPostprocessing = 0; 81 | }; 82 | /* End PBXFrameworksBuildPhase section */ 83 | 84 | /* Begin PBXGroup section */ 85 | 11F8470DD06645E5066C1F07915F9D10 /* Support Files */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 782D561553CB5E843E2B297F16EFAFEE /* Info.plist */, 89 | 9E4D51AC2FEC6C2C599264A8D7D52AF9 /* USBDeviceSwift.modulemap */, 90 | 1E5EE5DC271B4423F65F6041E9AF5CB3 /* USBDeviceSwift.xcconfig */, 91 | 566685BC478BEA7393B41E3EEF45B6BE /* USBDeviceSwift-dummy.m */, 92 | CB20F189B90D14179BE6CA231A3EF461 /* USBDeviceSwift-prefix.pch */, 93 | B8282C14BC1C7BE3E4FB79A894770B28 /* USBDeviceSwift-umbrella.h */, 94 | ); 95 | name = "Support Files"; 96 | path = "../Target Support Files/USBDeviceSwift"; 97 | sourceTree = ""; 98 | }; 99 | 39E9EE8210D861DFD82346C1F5EB7218 /* Frameworks */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | FA7AC8429882A95AA0810A9DCDED54FF /* OS X */, 103 | ); 104 | name = Frameworks; 105 | sourceTree = ""; 106 | }; 107 | 6428924CC6D30421889A1A51B6567DC4 /* Pods-UsbDetective */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 463052CE656C20C14268C66FBD90F056 /* Info.plist */, 111 | 07DDEBC3566388A62DB5A9666A006FDF /* Pods-UsbDetective.modulemap */, 112 | 1E84098D9BAEDB01676D2590A7B00DA2 /* Pods-UsbDetective-acknowledgements.markdown */, 113 | 80827FB941624A27B72F4A5A892082F5 /* Pods-UsbDetective-acknowledgements.plist */, 114 | C4C526C6E1E1578C818DFD8A4649BA0F /* Pods-UsbDetective-dummy.m */, 115 | 84F0E736AB88D601E87B350B2CBA64F1 /* Pods-UsbDetective-frameworks.sh */, 116 | 6F0343DC7A9C20B125701EA956B93CE5 /* Pods-UsbDetective-resources.sh */, 117 | 0B4A4798D8C6C55E4B0F7C57BB05972D /* Pods-UsbDetective-umbrella.h */, 118 | AA5CC87BF198BBA39EF2CD5C9D5347F4 /* Pods-UsbDetective.debug.xcconfig */, 119 | 1D7F06515083D42930CAF871915EB592 /* Pods-UsbDetective.release.xcconfig */, 120 | ); 121 | name = "Pods-UsbDetective"; 122 | path = "Target Support Files/Pods-UsbDetective"; 123 | sourceTree = ""; 124 | }; 125 | 7DB346D0F39D3F0E887471402A8071AB = { 126 | isa = PBXGroup; 127 | children = ( 128 | 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, 129 | 39E9EE8210D861DFD82346C1F5EB7218 /* Frameworks */, 130 | CDF05F72B30D9F7ED29EB8C9AF153B67 /* Pods */, 131 | F47439BF261A4D1CE8DBF1326FB889BD /* Products */, 132 | B6FDF28698BA097B4B2334BC29E855AE /* Targets Support Files */, 133 | ); 134 | sourceTree = ""; 135 | }; 136 | B6FDF28698BA097B4B2334BC29E855AE /* Targets Support Files */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 6428924CC6D30421889A1A51B6567DC4 /* Pods-UsbDetective */, 140 | ); 141 | name = "Targets Support Files"; 142 | sourceTree = ""; 143 | }; 144 | C45D25063124FF8709F3304E7121C347 /* USBDeviceSwift */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | EED874C7032F049D59DA98C5A9FED7A7 /* HIDDevice.swift */, 148 | 9197F474CC8DF6CD112DF72B60E6328F /* HIDDeviceMonitor.swift */, 149 | CD675DE0BB807C16F0323D1C2C0B0213 /* SerialDevice.swift */, 150 | 406374066234B68058C55CFCD6F1F632 /* SerialDeviceMonitor.swift */, 151 | DD050B03F06F888811B50A870E246D20 /* USBDevice.swift */, 152 | 41B494F2E5F41B7337DCFDB3A194C7CC /* USBDeviceMonitor.swift */, 153 | 74DE11A9211A5EB2B4D7F2FF0E4ABE7D /* USBDeviceSwift.h */, 154 | 11F8470DD06645E5066C1F07915F9D10 /* Support Files */, 155 | ); 156 | path = USBDeviceSwift; 157 | sourceTree = ""; 158 | }; 159 | CDF05F72B30D9F7ED29EB8C9AF153B67 /* Pods */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | C45D25063124FF8709F3304E7121C347 /* USBDeviceSwift */, 163 | ); 164 | name = Pods; 165 | sourceTree = ""; 166 | }; 167 | F47439BF261A4D1CE8DBF1326FB889BD /* Products */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 4F4A455D19212958D87424C8C8F5B10F /* Pods_UsbDetective.framework */, 171 | 141C6EC1CA4665E3BD242829D17B1FCA /* USBDeviceSwift.framework */, 172 | ); 173 | name = Products; 174 | sourceTree = ""; 175 | }; 176 | FA7AC8429882A95AA0810A9DCDED54FF /* OS X */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | DF428FC7C7A6555B2B02D8E238C8D8F2 /* Cocoa.framework */, 180 | ); 181 | name = "OS X"; 182 | sourceTree = ""; 183 | }; 184 | /* End PBXGroup section */ 185 | 186 | /* Begin PBXHeadersBuildPhase section */ 187 | 1361C5026F4ED829AC5EA97A06972912 /* Headers */ = { 188 | isa = PBXHeadersBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 4947000C11CB0416D1ABBB4B2C8D2A09 /* Pods-UsbDetective-umbrella.h in Headers */, 192 | ); 193 | runOnlyForDeploymentPostprocessing = 0; 194 | }; 195 | 5A59319C1C2DF65671C2F0F0F5E012BE /* Headers */ = { 196 | isa = PBXHeadersBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 9EDD821E001418A2B6378F435EF540DC /* USBDeviceSwift-umbrella.h in Headers */, 200 | 4B264D3B54B7D1860DDA1979CF90C351 /* USBDeviceSwift.h in Headers */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXHeadersBuildPhase section */ 205 | 206 | /* Begin PBXNativeTarget section */ 207 | 29778B5182CE94884F1D597D2A27DCD0 /* USBDeviceSwift */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = 495EB2EE7514AE4FA25E82C4157C4309 /* Build configuration list for PBXNativeTarget "USBDeviceSwift" */; 210 | buildPhases = ( 211 | DD82C6DE85D936ECBF38066660892E23 /* Sources */, 212 | 620BE27B49984A69ADB42C14C9EBD413 /* Frameworks */, 213 | 5A59319C1C2DF65671C2F0F0F5E012BE /* Headers */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | ); 219 | name = USBDeviceSwift; 220 | productName = USBDeviceSwift; 221 | productReference = 141C6EC1CA4665E3BD242829D17B1FCA /* USBDeviceSwift.framework */; 222 | productType = "com.apple.product-type.framework"; 223 | }; 224 | 639CDA6334E1B445689C811E34CF39AB /* Pods-UsbDetective */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = A537D4EED5C16D1F933EC121E4A6726B /* Build configuration list for PBXNativeTarget "Pods-UsbDetective" */; 227 | buildPhases = ( 228 | C8180154C3151C62C21E8F323FA2AB0F /* Sources */, 229 | D8FA91AA8B91E6CC9E6E8FBB017846FE /* Frameworks */, 230 | 1361C5026F4ED829AC5EA97A06972912 /* Headers */, 231 | ); 232 | buildRules = ( 233 | ); 234 | dependencies = ( 235 | 547CF8C03AA230C6BAE1A9CD53FEEB7D /* PBXTargetDependency */, 236 | ); 237 | name = "Pods-UsbDetective"; 238 | productName = "Pods-UsbDetective"; 239 | productReference = 4F4A455D19212958D87424C8C8F5B10F /* Pods_UsbDetective.framework */; 240 | productType = "com.apple.product-type.framework"; 241 | }; 242 | /* End PBXNativeTarget section */ 243 | 244 | /* Begin PBXProject section */ 245 | D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { 246 | isa = PBXProject; 247 | attributes = { 248 | LastSwiftUpdateCheck = 0930; 249 | LastUpgradeCheck = 1010; 250 | }; 251 | buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; 252 | compatibilityVersion = "Xcode 3.2"; 253 | developmentRegion = English; 254 | hasScannedForEncodings = 0; 255 | knownRegions = ( 256 | en, 257 | ); 258 | mainGroup = 7DB346D0F39D3F0E887471402A8071AB; 259 | productRefGroup = F47439BF261A4D1CE8DBF1326FB889BD /* Products */; 260 | projectDirPath = ""; 261 | projectRoot = ""; 262 | targets = ( 263 | 639CDA6334E1B445689C811E34CF39AB /* Pods-UsbDetective */, 264 | 29778B5182CE94884F1D597D2A27DCD0 /* USBDeviceSwift */, 265 | ); 266 | }; 267 | /* End PBXProject section */ 268 | 269 | /* Begin PBXSourcesBuildPhase section */ 270 | C8180154C3151C62C21E8F323FA2AB0F /* Sources */ = { 271 | isa = PBXSourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | 4547FFC1ABE44649336F8FFFD92B967E /* Pods-UsbDetective-dummy.m in Sources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | DD82C6DE85D936ECBF38066660892E23 /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | 07B184B9A7E8908DC47CDD400789C83F /* HIDDevice.swift in Sources */, 283 | 8F967C443C3D453E1649876D77CFC711 /* HIDDeviceMonitor.swift in Sources */, 284 | 80BBE7C5723F641051A55D8854193855 /* SerialDevice.swift in Sources */, 285 | C9754411263A09822C1A2090052CF44D /* SerialDeviceMonitor.swift in Sources */, 286 | D996D15A927C82DB2739A728419EA014 /* USBDevice.swift in Sources */, 287 | 2315E0F041D3098849A75AC7C87215AC /* USBDeviceMonitor.swift in Sources */, 288 | 100ED2DD8E4788A11603C2C7B34E49C5 /* USBDeviceSwift-dummy.m in Sources */, 289 | ); 290 | runOnlyForDeploymentPostprocessing = 0; 291 | }; 292 | /* End PBXSourcesBuildPhase section */ 293 | 294 | /* Begin PBXTargetDependency section */ 295 | 547CF8C03AA230C6BAE1A9CD53FEEB7D /* PBXTargetDependency */ = { 296 | isa = PBXTargetDependency; 297 | name = USBDeviceSwift; 298 | target = 29778B5182CE94884F1D597D2A27DCD0 /* USBDeviceSwift */; 299 | targetProxy = FB7FC6091AD9327C590E21E1E08234EB /* PBXContainerItemProxy */; 300 | }; 301 | /* End PBXTargetDependency section */ 302 | 303 | /* Begin XCBuildConfiguration section */ 304 | 1C319FE8FEF78C160E1BFEB270E25F16 /* Release */ = { 305 | isa = XCBuildConfiguration; 306 | buildSettings = { 307 | ALWAYS_SEARCH_USER_PATHS = NO; 308 | CLANG_ANALYZER_NONNULL = YES; 309 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_ENABLE_OBJC_WEAK = YES; 315 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 316 | CLANG_WARN_BOOL_CONVERSION = YES; 317 | CLANG_WARN_COMMA = YES; 318 | CLANG_WARN_CONSTANT_CONVERSION = YES; 319 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 320 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 321 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 322 | CLANG_WARN_EMPTY_BODY = YES; 323 | CLANG_WARN_ENUM_CONVERSION = YES; 324 | CLANG_WARN_INFINITE_RECURSION = YES; 325 | CLANG_WARN_INT_CONVERSION = YES; 326 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 327 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 328 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 329 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 330 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 331 | CLANG_WARN_STRICT_PROTOTYPES = YES; 332 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 333 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 334 | CLANG_WARN_UNREACHABLE_CODE = YES; 335 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 336 | CODE_SIGNING_ALLOWED = NO; 337 | CODE_SIGNING_REQUIRED = NO; 338 | COPY_PHASE_STRIP = NO; 339 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 340 | ENABLE_NS_ASSERTIONS = NO; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | GCC_C_LANGUAGE_STANDARD = gnu11; 343 | GCC_NO_COMMON_BLOCKS = YES; 344 | GCC_PREPROCESSOR_DEFINITIONS = ( 345 | "POD_CONFIGURATION_RELEASE=1", 346 | "$(inherited)", 347 | ); 348 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 349 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 350 | GCC_WARN_UNDECLARED_SELECTOR = YES; 351 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 352 | GCC_WARN_UNUSED_FUNCTION = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | MACOSX_DEPLOYMENT_TARGET = 10.14; 355 | MTL_ENABLE_DEBUG_INFO = NO; 356 | PRODUCT_NAME = "$(TARGET_NAME)"; 357 | STRIP_INSTALLED_PRODUCT = NO; 358 | SWIFT_COMPILATION_MODE = wholemodule; 359 | SYMROOT = "${SRCROOT}/../build"; 360 | }; 361 | name = Release; 362 | }; 363 | 822B7102BBE44F4B911960928BE7992D /* Debug */ = { 364 | isa = XCBuildConfiguration; 365 | buildSettings = { 366 | ALWAYS_SEARCH_USER_PATHS = NO; 367 | CLANG_ANALYZER_NONNULL = YES; 368 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 369 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 370 | CLANG_CXX_LIBRARY = "libc++"; 371 | CLANG_ENABLE_MODULES = YES; 372 | CLANG_ENABLE_OBJC_ARC = YES; 373 | CLANG_ENABLE_OBJC_WEAK = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 389 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 390 | CLANG_WARN_STRICT_PROTOTYPES = YES; 391 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 392 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 393 | CLANG_WARN_UNREACHABLE_CODE = YES; 394 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 395 | CODE_SIGNING_ALLOWED = NO; 396 | CODE_SIGNING_REQUIRED = NO; 397 | COPY_PHASE_STRIP = NO; 398 | DEBUG_INFORMATION_FORMAT = dwarf; 399 | ENABLE_STRICT_OBJC_MSGSEND = YES; 400 | ENABLE_TESTABILITY = YES; 401 | GCC_C_LANGUAGE_STANDARD = gnu11; 402 | GCC_DYNAMIC_NO_PIC = NO; 403 | GCC_NO_COMMON_BLOCKS = YES; 404 | GCC_OPTIMIZATION_LEVEL = 0; 405 | GCC_PREPROCESSOR_DEFINITIONS = ( 406 | "POD_CONFIGURATION_DEBUG=1", 407 | "DEBUG=1", 408 | "$(inherited)", 409 | ); 410 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 411 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 412 | GCC_WARN_UNDECLARED_SELECTOR = YES; 413 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 414 | GCC_WARN_UNUSED_FUNCTION = YES; 415 | GCC_WARN_UNUSED_VARIABLE = YES; 416 | MACOSX_DEPLOYMENT_TARGET = 10.14; 417 | MTL_ENABLE_DEBUG_INFO = YES; 418 | ONLY_ACTIVE_ARCH = YES; 419 | PRODUCT_NAME = "$(TARGET_NAME)"; 420 | STRIP_INSTALLED_PRODUCT = NO; 421 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 422 | SYMROOT = "${SRCROOT}/../build"; 423 | }; 424 | name = Debug; 425 | }; 426 | ABCE7F7390A587C3DE6C629499F8A692 /* Release */ = { 427 | isa = XCBuildConfiguration; 428 | baseConfigurationReference = 1E5EE5DC271B4423F65F6041E9AF5CB3 /* USBDeviceSwift.xcconfig */; 429 | buildSettings = { 430 | CLANG_ENABLE_OBJC_WEAK = NO; 431 | CODE_SIGN_IDENTITY = ""; 432 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 433 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 434 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 435 | COMBINE_HIDPI_IMAGES = YES; 436 | CURRENT_PROJECT_VERSION = 1; 437 | DEFINES_MODULE = YES; 438 | DYLIB_COMPATIBILITY_VERSION = 1; 439 | DYLIB_CURRENT_VERSION = 1; 440 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 441 | FRAMEWORK_VERSION = A; 442 | GCC_PREFIX_HEADER = "Target Support Files/USBDeviceSwift/USBDeviceSwift-prefix.pch"; 443 | INFOPLIST_FILE = "Target Support Files/USBDeviceSwift/Info.plist"; 444 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 445 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 446 | MACOSX_DEPLOYMENT_TARGET = 10.10; 447 | MODULEMAP_FILE = "Target Support Files/USBDeviceSwift/USBDeviceSwift.modulemap"; 448 | PRODUCT_MODULE_NAME = USBDeviceSwift; 449 | PRODUCT_NAME = USBDeviceSwift; 450 | SDKROOT = macosx; 451 | SKIP_INSTALL = YES; 452 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 453 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 454 | SWIFT_VERSION = 4.0; 455 | VERSIONING_SYSTEM = "apple-generic"; 456 | VERSION_INFO_PREFIX = ""; 457 | }; 458 | name = Release; 459 | }; 460 | AF9226A7614C5EEF5B113D70FB3BF49A /* Debug */ = { 461 | isa = XCBuildConfiguration; 462 | baseConfigurationReference = AA5CC87BF198BBA39EF2CD5C9D5347F4 /* Pods-UsbDetective.debug.xcconfig */; 463 | buildSettings = { 464 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 465 | CLANG_ENABLE_OBJC_WEAK = NO; 466 | CODE_SIGN_IDENTITY = ""; 467 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 468 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 469 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 470 | COMBINE_HIDPI_IMAGES = YES; 471 | CURRENT_PROJECT_VERSION = 1; 472 | DEFINES_MODULE = YES; 473 | DYLIB_COMPATIBILITY_VERSION = 1; 474 | DYLIB_CURRENT_VERSION = 1; 475 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 476 | FRAMEWORK_VERSION = A; 477 | INFOPLIST_FILE = "Target Support Files/Pods-UsbDetective/Info.plist"; 478 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 479 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 480 | MACH_O_TYPE = staticlib; 481 | MACOSX_DEPLOYMENT_TARGET = 10.14; 482 | MODULEMAP_FILE = "Target Support Files/Pods-UsbDetective/Pods-UsbDetective.modulemap"; 483 | OTHER_LDFLAGS = ""; 484 | OTHER_LIBTOOLFLAGS = ""; 485 | PODS_ROOT = "$(SRCROOT)"; 486 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 487 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 488 | SDKROOT = macosx; 489 | SKIP_INSTALL = YES; 490 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 491 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 492 | VERSIONING_SYSTEM = "apple-generic"; 493 | VERSION_INFO_PREFIX = ""; 494 | }; 495 | name = Debug; 496 | }; 497 | BF9054038396DD7A28A7A7C77332C226 /* Release */ = { 498 | isa = XCBuildConfiguration; 499 | baseConfigurationReference = 1D7F06515083D42930CAF871915EB592 /* Pods-UsbDetective.release.xcconfig */; 500 | buildSettings = { 501 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; 502 | CLANG_ENABLE_OBJC_WEAK = NO; 503 | CODE_SIGN_IDENTITY = ""; 504 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 505 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 506 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 507 | COMBINE_HIDPI_IMAGES = YES; 508 | CURRENT_PROJECT_VERSION = 1; 509 | DEFINES_MODULE = YES; 510 | DYLIB_COMPATIBILITY_VERSION = 1; 511 | DYLIB_CURRENT_VERSION = 1; 512 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 513 | FRAMEWORK_VERSION = A; 514 | INFOPLIST_FILE = "Target Support Files/Pods-UsbDetective/Info.plist"; 515 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 516 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 517 | MACH_O_TYPE = staticlib; 518 | MACOSX_DEPLOYMENT_TARGET = 10.14; 519 | MODULEMAP_FILE = "Target Support Files/Pods-UsbDetective/Pods-UsbDetective.modulemap"; 520 | OTHER_LDFLAGS = ""; 521 | OTHER_LIBTOOLFLAGS = ""; 522 | PODS_ROOT = "$(SRCROOT)"; 523 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; 524 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; 525 | SDKROOT = macosx; 526 | SKIP_INSTALL = YES; 527 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 528 | VERSIONING_SYSTEM = "apple-generic"; 529 | VERSION_INFO_PREFIX = ""; 530 | }; 531 | name = Release; 532 | }; 533 | DC4EFC76DE6307B181FA66733941C148 /* Debug */ = { 534 | isa = XCBuildConfiguration; 535 | baseConfigurationReference = 1E5EE5DC271B4423F65F6041E9AF5CB3 /* USBDeviceSwift.xcconfig */; 536 | buildSettings = { 537 | CLANG_ENABLE_OBJC_WEAK = NO; 538 | CODE_SIGN_IDENTITY = ""; 539 | "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; 540 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 541 | "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; 542 | COMBINE_HIDPI_IMAGES = YES; 543 | CURRENT_PROJECT_VERSION = 1; 544 | DEFINES_MODULE = YES; 545 | DYLIB_COMPATIBILITY_VERSION = 1; 546 | DYLIB_CURRENT_VERSION = 1; 547 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 548 | FRAMEWORK_VERSION = A; 549 | GCC_PREFIX_HEADER = "Target Support Files/USBDeviceSwift/USBDeviceSwift-prefix.pch"; 550 | INFOPLIST_FILE = "Target Support Files/USBDeviceSwift/Info.plist"; 551 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 552 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 553 | MACOSX_DEPLOYMENT_TARGET = 10.10; 554 | MODULEMAP_FILE = "Target Support Files/USBDeviceSwift/USBDeviceSwift.modulemap"; 555 | PRODUCT_MODULE_NAME = USBDeviceSwift; 556 | PRODUCT_NAME = USBDeviceSwift; 557 | SDKROOT = macosx; 558 | SKIP_INSTALL = YES; 559 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; 560 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 561 | SWIFT_VERSION = 4.0; 562 | VERSIONING_SYSTEM = "apple-generic"; 563 | VERSION_INFO_PREFIX = ""; 564 | }; 565 | name = Debug; 566 | }; 567 | /* End XCBuildConfiguration section */ 568 | 569 | /* Begin XCConfigurationList section */ 570 | 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { 571 | isa = XCConfigurationList; 572 | buildConfigurations = ( 573 | 822B7102BBE44F4B911960928BE7992D /* Debug */, 574 | 1C319FE8FEF78C160E1BFEB270E25F16 /* Release */, 575 | ); 576 | defaultConfigurationIsVisible = 0; 577 | defaultConfigurationName = Release; 578 | }; 579 | 495EB2EE7514AE4FA25E82C4157C4309 /* Build configuration list for PBXNativeTarget "USBDeviceSwift" */ = { 580 | isa = XCConfigurationList; 581 | buildConfigurations = ( 582 | DC4EFC76DE6307B181FA66733941C148 /* Debug */, 583 | ABCE7F7390A587C3DE6C629499F8A692 /* Release */, 584 | ); 585 | defaultConfigurationIsVisible = 0; 586 | defaultConfigurationName = Release; 587 | }; 588 | A537D4EED5C16D1F933EC121E4A6726B /* Build configuration list for PBXNativeTarget "Pods-UsbDetective" */ = { 589 | isa = XCConfigurationList; 590 | buildConfigurations = ( 591 | AF9226A7614C5EEF5B113D70FB3BF49A /* Debug */, 592 | BF9054038396DD7A28A7A7C77332C226 /* Release */, 593 | ); 594 | defaultConfigurationIsVisible = 0; 595 | defaultConfigurationName = Release; 596 | }; 597 | /* End XCConfigurationList section */ 598 | }; 599 | rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; 600 | } 601 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## USBDeviceSwift 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 XMARTLABS 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 XMARTLABS 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in all 29 | copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 | SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | USBDeviceSwift 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_UsbDetective : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_UsbDetective 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then 7 | # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # frameworks to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 13 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 14 | 15 | COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" 16 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 17 | 18 | # Used as a return value for each invocation of `strip_invalid_archs` function. 19 | STRIP_BINARY_RETVAL=0 20 | 21 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 22 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 23 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 24 | 25 | # Copies and strips a vendored framework 26 | install_framework() 27 | { 28 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 29 | local source="${BUILT_PRODUCTS_DIR}/$1" 30 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 31 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 32 | elif [ -r "$1" ]; then 33 | local source="$1" 34 | fi 35 | 36 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 37 | 38 | if [ -L "${source}" ]; then 39 | echo "Symlinked..." 40 | source="$(readlink "${source}")" 41 | fi 42 | 43 | # Use filter instead of exclude so missing patterns don't throw errors. 44 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 45 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 46 | 47 | local basename 48 | basename="$(basename -s .framework "$1")" 49 | binary="${destination}/${basename}.framework/${basename}" 50 | if ! [ -r "$binary" ]; then 51 | binary="${destination}/${basename}" 52 | fi 53 | 54 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 55 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 56 | strip_invalid_archs "$binary" 57 | fi 58 | 59 | # Resign the code if required by the build settings to avoid unstable apps 60 | code_sign_if_enabled "${destination}/$(basename "$1")" 61 | 62 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 63 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 64 | local swift_runtime_libs 65 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 66 | for lib in $swift_runtime_libs; do 67 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 68 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 69 | code_sign_if_enabled "${destination}/${lib}" 70 | done 71 | fi 72 | } 73 | 74 | # Copies and strips a vendored dSYM 75 | install_dsym() { 76 | local source="$1" 77 | if [ -r "$source" ]; then 78 | # Copy the dSYM into a the targets temp dir. 79 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" 80 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" 81 | 82 | local basename 83 | basename="$(basename -s .framework.dSYM "$source")" 84 | binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" 85 | 86 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 87 | if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then 88 | strip_invalid_archs "$binary" 89 | fi 90 | 91 | if [[ $STRIP_BINARY_RETVAL == 1 ]]; then 92 | # Move the stripped file into its final destination. 93 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" 94 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" 95 | else 96 | # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. 97 | touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" 98 | fi 99 | fi 100 | } 101 | 102 | # Signs a framework with the provided identity 103 | code_sign_if_enabled() { 104 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY:-}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 105 | # Use the current code_sign_identitiy 106 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 107 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" 108 | 109 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 110 | code_sign_cmd="$code_sign_cmd &" 111 | fi 112 | echo "$code_sign_cmd" 113 | eval "$code_sign_cmd" 114 | fi 115 | } 116 | 117 | # Strip invalid architectures 118 | strip_invalid_archs() { 119 | binary="$1" 120 | # Get architectures for current target binary 121 | binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" 122 | # Intersect them with the architectures we are building for 123 | intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" 124 | # If there are no archs supported by this binary then warn the user 125 | if [[ -z "$intersected_archs" ]]; then 126 | echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." 127 | STRIP_BINARY_RETVAL=0 128 | return 129 | fi 130 | stripped="" 131 | for arch in $binary_archs; do 132 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 133 | # Strip non-valid architectures in-place 134 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 135 | stripped="$stripped $arch" 136 | fi 137 | done 138 | if [[ "$stripped" ]]; then 139 | echo "Stripped $binary of architectures:$stripped" 140 | fi 141 | STRIP_BINARY_RETVAL=1 142 | } 143 | 144 | 145 | if [[ "$CONFIGURATION" == "Debug" ]]; then 146 | install_framework "${BUILT_PRODUCTS_DIR}/USBDeviceSwift/USBDeviceSwift.framework" 147 | fi 148 | if [[ "$CONFIGURATION" == "Release" ]]; then 149 | install_framework "${BUILT_PRODUCTS_DIR}/USBDeviceSwift/USBDeviceSwift.framework" 150 | fi 151 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 152 | wait 153 | fi 154 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | set -u 4 | set -o pipefail 5 | 6 | if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then 7 | # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy 8 | # resources to, so exit 0 (signalling the script phase was successful). 9 | exit 0 10 | fi 11 | 12 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 13 | 14 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 15 | > "$RESOURCES_TO_COPY" 16 | 17 | XCASSET_FILES=() 18 | 19 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 20 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 21 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 22 | 23 | case "${TARGETED_DEVICE_FAMILY:-}" in 24 | 1,2) 25 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 26 | ;; 27 | 1) 28 | TARGET_DEVICE_ARGS="--target-device iphone" 29 | ;; 30 | 2) 31 | TARGET_DEVICE_ARGS="--target-device ipad" 32 | ;; 33 | 3) 34 | TARGET_DEVICE_ARGS="--target-device tv" 35 | ;; 36 | 4) 37 | TARGET_DEVICE_ARGS="--target-device watch" 38 | ;; 39 | *) 40 | TARGET_DEVICE_ARGS="--target-device mac" 41 | ;; 42 | esac 43 | 44 | install_resource() 45 | { 46 | if [[ "$1" = /* ]] ; then 47 | RESOURCE_PATH="$1" 48 | else 49 | RESOURCE_PATH="${PODS_ROOT}/$1" 50 | fi 51 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 52 | cat << EOM 53 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 54 | EOM 55 | exit 1 56 | fi 57 | case $RESOURCE_PATH in 58 | *.storyboard) 59 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 60 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 61 | ;; 62 | *.xib) 63 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 64 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 65 | ;; 66 | *.framework) 67 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 68 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 69 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 70 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 71 | ;; 72 | *.xcdatamodel) 73 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 74 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 75 | ;; 76 | *.xcdatamodeld) 77 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 78 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 79 | ;; 80 | *.xcmappingmodel) 81 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 82 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 83 | ;; 84 | *.xcassets) 85 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 86 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 87 | ;; 88 | *) 89 | echo "$RESOURCE_PATH" || true 90 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 91 | ;; 92 | esac 93 | } 94 | 95 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 96 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 97 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 98 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 99 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 100 | fi 101 | rm -f "$RESOURCES_TO_COPY" 102 | 103 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] 104 | then 105 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 106 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 107 | while read line; do 108 | if [[ $line != "${PODS_ROOT}*" ]]; then 109 | XCASSET_FILES+=("$line") 110 | fi 111 | done <<<"$OTHER_XCASSETS" 112 | 113 | if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then 114 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 115 | else 116 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" 117 | fi 118 | fi 119 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_UsbDetectiveVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_UsbDetectiveVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/USBDeviceSwift" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/USBDeviceSwift/USBDeviceSwift.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "USBDeviceSwift" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_UsbDetective { 2 | umbrella header "Pods-UsbDetective-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/USBDeviceSwift" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 6 | OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/USBDeviceSwift/USBDeviceSwift.framework/Headers" 7 | OTHER_LDFLAGS = $(inherited) -framework "USBDeviceSwift" 8 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/USBDeviceSwift-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_USBDeviceSwift : NSObject 3 | @end 4 | @implementation PodsDummy_USBDeviceSwift 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/USBDeviceSwift-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/USBDeviceSwift-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "USBDeviceSwift.h" 14 | 15 | FOUNDATION_EXPORT double USBDeviceSwiftVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char USBDeviceSwiftVersionString[]; 17 | 18 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/USBDeviceSwift.modulemap: -------------------------------------------------------------------------------- 1 | framework module USBDeviceSwift { 2 | umbrella header "USBDeviceSwift-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/USBDeviceSwift/USBDeviceSwift.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/USBDeviceSwift 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/USBDeviceSwift 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | SWIFT_VERSION = 4.0 12 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 XMARTLABS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/README.md: -------------------------------------------------------------------------------- 1 | # USBDeviceSwift 2 | 3 | **USBDeviceSwift** - is a wrapper for `IOKit.usb` and `IOKit.hid` and `IOKit.serial` written on pure Swift that allows you convenient work with USB devices. 4 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 18 | 19 |
8 | 9 | 11 | 12 |
16 | 17 |
20 | 21 | Working with `IOKit.usb` and `IOKit.hid` and `IOKit.serial` on Swift is a pain. A lot of not converted C code, pointers make your life harder. 22 | This library provides basic connect/disconnect events, converted functions to send and receive requests and examples. 23 | 24 | ## Getting Started 25 | 26 | ### Requirements 27 | 28 | * Mac OS X 10.10 29 | * Xcode 8+ 30 | * Swift 4 31 | 32 | ## Installation 33 | 34 | #### CocoaPods 35 | 36 | [CocoaPods](https://cocoapods.org/) is a dependency manager for Cocoa projects. 37 | 38 | Specify USBDeviceSwift into your project's `Podfile`: 39 | 40 | ```ruby 41 | # Uncomment the next line to define a global platform for your project 42 | # platform :ios, '9.0' 43 | 44 | target 'testusb' do 45 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 46 | use_frameworks! 47 | 48 | # Pods for testusb 49 | 50 | pod 'USBDeviceSwift' 51 | 52 | end 53 | ``` 54 | 55 | Then run the following command: 56 | 57 | ```bash 58 | $ pod install 59 | ``` 60 | 61 | #### Swift Package Manager 62 | 63 | [Swift Package Manager](https://swift.org/package-manager/) 64 | 65 | ``` 66 | import PackageDescription 67 | 68 | let package = Package( 69 | name: "Example project", 70 | dependencies: [ 71 | .Package(url: "https://github.com/Arti3DPlayer/USBDeviceSwift.git", majorVersion: 1), 72 | ] 73 | ) 74 | ``` 75 | 76 | ## Examples 77 | 78 | You will find all examples on Wiki page [here](https://github.com/Arti3DPlayer/USBDeviceSwift/wiki) 79 | 80 | ## License 81 | 82 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details 83 | 84 | ## Change Log 85 | 86 | This can be found in the [CHANGELOG.md](CHANGELOG.md) file. 87 | 88 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/HIDDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HIDDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit.hid 12 | 13 | public extension Notification.Name { 14 | static let HIDDeviceDataReceived = Notification.Name("HIDDeviceDataReceived") 15 | static let HIDDeviceConnected = Notification.Name("HIDDeviceConnected") 16 | static let HIDDeviceDisconnected = Notification.Name("HIDDeviceDisconnected") 17 | } 18 | 19 | public struct HIDMonitorData { 20 | public let vendorId:Int 21 | public let productId:Int 22 | 23 | public init (vendorId:Int, productId:Int) { 24 | self.vendorId = vendorId 25 | self.productId = productId 26 | } 27 | } 28 | 29 | public struct HIDDevice { 30 | public let id:String 31 | public let vendorId:Int 32 | public let productId:Int 33 | public let reportSize:Int 34 | public let device:IOHIDDevice 35 | public let name:String 36 | 37 | public init(device:IOHIDDevice) { 38 | self.device = device 39 | 40 | self.id = IOHIDDeviceGetProperty(self.device, kIOHIDLocationIDKey as CFString) as? String ?? "" 41 | self.name = IOHIDDeviceGetProperty(device, kIOHIDProductKey as CFString) as? String ?? "" 42 | self.vendorId = IOHIDDeviceGetProperty(self.device, kIOHIDVendorIDKey as CFString) as? Int ?? 0 43 | self.productId = IOHIDDeviceGetProperty(self.device, kIOHIDProductIDKey as CFString) as? Int ?? 0 44 | self.reportSize = IOHIDDeviceGetProperty(self.device, kIOHIDMaxInputReportSizeKey as CFString) as? Int ?? 0 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/HIDDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HIDDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/14/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit.hid 12 | 13 | 14 | open class HIDDeviceMonitor { 15 | public let vp:[HIDMonitorData] 16 | public let reportSize:Int 17 | 18 | public init(_ vp:[HIDMonitorData], reportSize:Int) { 19 | self.vp = vp 20 | self.reportSize = reportSize 21 | } 22 | 23 | @objc open func start() { 24 | let managerRef = IOHIDManagerCreate(kCFAllocatorDefault, IOOptionBits(kIOHIDOptionsTypeNone)) 25 | var deviceMatches:[[String:Any]] = [] 26 | for vp in self.vp { 27 | deviceMatches.append([kIOHIDProductIDKey: vp.productId, kIOHIDVendorIDKey: vp.vendorId]) 28 | } 29 | IOHIDManagerSetDeviceMatchingMultiple(managerRef, deviceMatches as CFArray) 30 | IOHIDManagerScheduleWithRunLoop(managerRef, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue); 31 | IOHIDManagerOpen(managerRef, IOOptionBits(kIOHIDOptionsTypeNone)); 32 | 33 | let matchingCallback:IOHIDDeviceCallback = { inContext, inResult, inSender, inIOHIDDeviceRef in 34 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 35 | this.rawDeviceAdded(inResult, inSender: inSender!, inIOHIDDeviceRef: inIOHIDDeviceRef) 36 | } 37 | 38 | let removalCallback:IOHIDDeviceCallback = { inContext, inResult, inSender, inIOHIDDeviceRef in 39 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 40 | this.rawDeviceRemoved(inResult, inSender: inSender!, inIOHIDDeviceRef: inIOHIDDeviceRef) 41 | } 42 | IOHIDManagerRegisterDeviceMatchingCallback(managerRef, matchingCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 43 | IOHIDManagerRegisterDeviceRemovalCallback(managerRef, removalCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 44 | 45 | 46 | RunLoop.current.run() 47 | } 48 | 49 | open func read(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, type: IOHIDReportType, reportId: UInt32, report: UnsafeMutablePointer, reportLength: CFIndex) { 50 | let data = Data(bytes: UnsafePointer(report), count: reportLength) 51 | NotificationCenter.default.post(name: .HIDDeviceDataReceived, object: ["data": data]) 52 | } 53 | 54 | open func rawDeviceAdded(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, inIOHIDDeviceRef: IOHIDDevice!) { 55 | // It would be better to look up the report size and create a chunk of memory of that size 56 | let report = UnsafeMutablePointer.allocate(capacity: reportSize) 57 | let inputCallback : IOHIDReportCallback = { inContext, inResult, inSender, type, reportId, report, reportLength in 58 | let this:HIDDeviceMonitor = unsafeBitCast(inContext, to: HIDDeviceMonitor.self) 59 | this.read(inResult, inSender: inSender!, type: type, reportId: reportId, report: report, reportLength: reportLength) 60 | } 61 | 62 | //Hook up inputcallback 63 | IOHIDDeviceRegisterInputReportCallback(inIOHIDDeviceRef!, report, reportSize, inputCallback, unsafeBitCast(self, to: UnsafeMutableRawPointer.self)) 64 | 65 | let device = HIDDevice(device:inIOHIDDeviceRef) 66 | NotificationCenter.default.post(name: .HIDDeviceConnected, object: ["device": device]) 67 | } 68 | 69 | open func rawDeviceRemoved(_ inResult: IOReturn, inSender: UnsafeMutableRawPointer, inIOHIDDeviceRef: IOHIDDevice!) { 70 | let device = HIDDevice(device:inIOHIDDeviceRef) 71 | NotificationCenter.default.post(name: .HIDDeviceDisconnected, object: [ 72 | "id": device.id 73 | ]) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/SerialDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SerialDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import IOKit.serial 11 | 12 | 13 | public extension Notification.Name { 14 | static let SerialDeviceAdded = Notification.Name("SerialDeviceAdded") 15 | static let SerialDeviceRemoved = Notification.Name("SerialDeviceRemoved") 16 | } 17 | 18 | public struct SerialDevice { 19 | public let path:String 20 | public var name:String? // USB Product Name 21 | public var vendorName:String? //USB Vendor Name 22 | public var serialNumber:String? //USB Serial Number 23 | public var vendorId:Int? //USB Vendor id 24 | public var productId:Int? //USB Product id 25 | 26 | init(path:String) { 27 | self.path = path 28 | } 29 | } 30 | 31 | extension SerialDevice: Hashable { 32 | public var hashValue: Int { 33 | return "\(path)".hashValue 34 | } 35 | 36 | public static func ==(lhs: SerialDevice, rhs: SerialDevice) -> Bool { 37 | return lhs.path == rhs.path 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/SerialDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SerialDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 3/9/18. 6 | // Copyright © 2018 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Foundation 11 | import IOKit 12 | import IOKit.serial 13 | 14 | 15 | open class SerialDeviceMonitor { 16 | var serialDevices:[SerialDevice] = [] 17 | var portUsageIntervalTime:Float = 0.25 18 | open var filterDevices:((_ devices:[SerialDevice])->[SerialDevice])? 19 | 20 | public init() { 21 | } 22 | 23 | private func getParentProperty(device:io_object_t, key:String) -> AnyObject? { 24 | return IORegistryEntrySearchCFProperty(device, kIOServicePlane, key as CFString, kCFAllocatorDefault, IOOptionBits(kIORegistryIterateRecursively | kIORegistryIterateParents)) 25 | } 26 | 27 | func getDeviceProperty(device:io_object_t, key:String) -> AnyObject? { 28 | let cfKey = key as CFString 29 | let propValue = IORegistryEntryCreateCFProperty(device, cfKey, kCFAllocatorDefault, 0) 30 | 31 | return propValue?.takeUnretainedValue() 32 | } 33 | 34 | func getSerialDevices(iterator: io_iterator_t) { 35 | var newSerialDevices:[SerialDevice] = [] 36 | while case let serialPort = IOIteratorNext(iterator), serialPort != 0 { 37 | guard let calloutDevice = getDeviceProperty(device: serialPort, key: kIOCalloutDeviceKey) as? String else { 38 | continue 39 | } 40 | 41 | var sd = SerialDevice(path: calloutDevice) 42 | sd.name = getParentProperty(device: serialPort, key: "USB Product Name") as? String 43 | sd.vendorName = getParentProperty(device: serialPort, key: "USB Vendor Name") as? String 44 | sd.serialNumber = getParentProperty(device: serialPort, key: "USB Serial Number") as? String 45 | sd.vendorId = getParentProperty(device: serialPort, key: "idVendor") as? Int 46 | sd.productId = getParentProperty(device: serialPort, key: "idProduct") as? Int 47 | 48 | newSerialDevices.append(sd) 49 | IOObjectRelease(serialPort) 50 | } 51 | IOObjectRelease(iterator) 52 | 53 | if (filterDevices != nil) { 54 | newSerialDevices = filterDevices!(newSerialDevices) 55 | } 56 | 57 | let oldSet = Set(serialDevices) 58 | let newSet = Set(newSerialDevices) 59 | 60 | 61 | 62 | for sd in oldSet.subtracting(newSet) { 63 | NotificationCenter.default.post(name: .SerialDeviceRemoved, object: ["device": sd]) 64 | } 65 | 66 | for sd in newSet.subtracting(oldSet) { 67 | NotificationCenter.default.post(name: .SerialDeviceAdded, object: ["device": sd]) 68 | } 69 | 70 | serialDevices = newSerialDevices 71 | } 72 | 73 | @objc open func start() { 74 | while true { 75 | var portIterator: io_iterator_t = 0 76 | var result: kern_return_t = KERN_FAILURE 77 | let classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue) as NSMutableDictionary 78 | classesToMatch[kIOSerialBSDTypeKey] = kIOSerialBSDAllTypes 79 | result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, &portIterator) 80 | if result == KERN_SUCCESS { 81 | getSerialDevices(iterator: portIterator) 82 | } 83 | usleep(UInt32(portUsageIntervalTime*1000000)) 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/USBDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // USBDevice.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import IOKit 11 | import IOKit.usb 12 | import IOKit.usb.IOUSBLib 13 | 14 | //from IOUSBLib.h 15 | public let kIOUSBDeviceUserClientTypeID = CFUUIDGetConstantUUIDWithBytes(nil, 16 | 0x9d, 0xc7, 0xb7, 0x80, 0x9e, 0xc0, 0x11, 0xD4, 17 | 0xa5, 0x4f, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) 18 | public let kIOUSBDeviceInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, 19 | 0x5c, 0x81, 0x87, 0xd0, 0x9e, 0xf3, 0x11, 0xD4, 20 | 0x8b, 0x45, 0x00, 0x0a, 0x27, 0x05, 0x28, 0x61) 21 | 22 | //from IOCFPlugin.h 23 | public let kIOCFPlugInInterfaceID = CFUUIDGetConstantUUIDWithBytes(nil, 24 | 0xC2, 0x44, 0xE8, 0x58, 0x10, 0x9C, 0x11, 0xD4, 25 | 0x91, 0xD4, 0x00, 0x50, 0xE4, 0xC6, 0x42, 0x6F) 26 | 27 | 28 | /*! 29 | @defined USBmakebmRequestType 30 | @discussion Macro to encode the bRequest field of a Device Request. It is used when constructing an IOUSBDevRequest. 31 | */ 32 | 33 | public func USBmakebmRequestType(direction:Int, type:Int, recipient:Int) -> UInt8 { 34 | return UInt8((direction & kUSBRqDirnMask) << kUSBRqDirnShift)|UInt8((type & kUSBRqTypeMask) << kUSBRqTypeShift)|UInt8(recipient & kUSBRqRecipientMask) 35 | } 36 | 37 | public extension Notification.Name { 38 | static let USBDeviceConnected = Notification.Name("USBDeviceConnected") 39 | static let USBDeviceDisconnected = Notification.Name("USBDeviceDisconnected") 40 | } 41 | 42 | public struct USBMonitorData { 43 | public let vendorId:UInt16 44 | public let productId:UInt16 45 | 46 | public init (vendorId:UInt16, productId:UInt16) { 47 | self.vendorId = vendorId 48 | self.productId = productId 49 | } 50 | } 51 | 52 | public struct USBDevice { 53 | public let id:UInt64 54 | public let vendorId:UInt16 55 | public let productId:UInt16 56 | public let name:String 57 | 58 | public let deviceInterfacePtrPtr:UnsafeMutablePointer?>? 59 | public let plugInInterfacePtrPtr:UnsafeMutablePointer?>? 60 | 61 | public init(id:UInt64, 62 | vendorId:UInt16, 63 | productId:UInt16, 64 | name:String, 65 | deviceInterfacePtrPtr:UnsafeMutablePointer?>?, 66 | plugInInterfacePtrPtr:UnsafeMutablePointer?>?) { 67 | self.id = id 68 | self.vendorId = vendorId 69 | self.productId = productId 70 | self.name = name 71 | self.deviceInterfacePtrPtr = deviceInterfacePtrPtr 72 | self.plugInInterfacePtrPtr = plugInInterfacePtrPtr 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/USBDeviceMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceMonitor.swift 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/12/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | 12 | open class USBDeviceMonitor { 13 | public let vp:[USBMonitorData] 14 | 15 | public init(_ vp:[USBMonitorData]) { 16 | self.vp = vp 17 | } 18 | 19 | @objc open func start() { 20 | for vp in self.vp { 21 | var matchedIterator:io_iterator_t = 0 22 | var removalIterator:io_iterator_t = 0 23 | let notifyPort:IONotificationPortRef = IONotificationPortCreate(kIOMasterPortDefault) 24 | IONotificationPortSetDispatchQueue(notifyPort, DispatchQueue(label: "IODetector")) 25 | let matchingDict = IOServiceMatching(kIOUSBDeviceClassName) 26 | as NSMutableDictionary 27 | matchingDict[kUSBVendorID] = NSNumber(value: vp.vendorId) 28 | matchingDict[kUSBProductID] = NSNumber(value: vp.productId) 29 | 30 | let matchingCallback:IOServiceMatchingCallback = { (userData, iterator) in 31 | // Convert self to a void pointer, store that in the context, and convert it 32 | let this = Unmanaged.fromOpaque(userData!).takeUnretainedValue() 33 | this.rawDeviceAdded(iterator: iterator) 34 | } 35 | 36 | let removalCallback: IOServiceMatchingCallback = { 37 | (userData, iterator) in 38 | let this = Unmanaged.fromOpaque(userData!).takeUnretainedValue() 39 | this.rawDeviceRemoved(iterator: iterator) 40 | } 41 | 42 | let selfPtr = Unmanaged.passUnretained(self).toOpaque() 43 | 44 | IOServiceAddMatchingNotification(notifyPort, kIOFirstMatchNotification, matchingDict, matchingCallback, selfPtr, &matchedIterator) 45 | IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matchingDict, removalCallback, selfPtr, &removalIterator) 46 | 47 | self.rawDeviceAdded(iterator: matchedIterator) 48 | self.rawDeviceRemoved(iterator: removalIterator) 49 | 50 | } 51 | 52 | RunLoop.current.run() 53 | } 54 | 55 | open func rawDeviceAdded(iterator: io_iterator_t) { 56 | 57 | while case let usbDevice = IOIteratorNext(iterator), usbDevice != 0 { 58 | var score:Int32 = 0 59 | var kr:Int32 = 0 60 | var did:UInt64 = 0 61 | var vid:UInt16 = 0 62 | var pid:UInt16 = 0 63 | 64 | var deviceInterfacePtrPtr: UnsafeMutablePointer?>? 65 | var plugInInterfacePtrPtr: UnsafeMutablePointer?>? 66 | 67 | kr = IORegistryEntryGetRegistryEntryID(usbDevice, &did) 68 | 69 | if(kr != kIOReturnSuccess) { 70 | print("Error getting device id") 71 | } 72 | 73 | // io_name_t imports to swift as a tuple (Int8, ..., Int8) 128 ints 74 | // although in device_types.h it's defined: 75 | // typedef char io_name_t[128]; 76 | var deviceNameCString:[CChar] = [CChar](repeating: 0, count: 128) 77 | kr = IORegistryEntryGetName(usbDevice, &deviceNameCString) 78 | 79 | if(kr != kIOReturnSuccess) { 80 | print("Error getting device name") 81 | } 82 | 83 | let name = String.init(cString: &deviceNameCString) 84 | 85 | // Get plugInInterface for current USB device 86 | kr = IOCreatePlugInInterfaceForService( 87 | usbDevice, 88 | kIOUSBDeviceUserClientTypeID, 89 | kIOCFPlugInInterfaceID, 90 | &plugInInterfacePtrPtr, 91 | &score) 92 | 93 | // USB device object is no longer needed. 94 | IOObjectRelease(usbDevice) 95 | 96 | // Dereference pointer for the plug-in interface 97 | if (kr != kIOReturnSuccess) { 98 | continue 99 | } 100 | 101 | guard let plugInInterface = plugInInterfacePtrPtr?.pointee?.pointee else { 102 | print("Unable to get Plug-In Interface") 103 | continue 104 | } 105 | 106 | // use plug in interface to get a device interface 107 | kr = withUnsafeMutablePointer(to: &deviceInterfacePtrPtr) { 108 | $0.withMemoryRebound(to: Optional.self, capacity: 1) { 109 | plugInInterface.QueryInterface( 110 | plugInInterfacePtrPtr, 111 | CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), 112 | $0) 113 | } 114 | } 115 | 116 | // dereference pointer for the device interface 117 | if (kr != kIOReturnSuccess) { 118 | continue 119 | } 120 | 121 | guard let deviceInterface = deviceInterfacePtrPtr?.pointee?.pointee else { 122 | print("Unable to get Device Interface") 123 | continue 124 | } 125 | 126 | kr = deviceInterface.USBDeviceOpen(deviceInterfacePtrPtr) 127 | 128 | // kIOReturnExclusiveAccess is not a problem as we can still do some things 129 | if (kr != kIOReturnSuccess && kr != kIOReturnExclusiveAccess) { 130 | print("Could not open device (error: \(kr))") 131 | continue 132 | } 133 | 134 | kr = deviceInterface.GetDeviceVendor(deviceInterfacePtrPtr, &vid) 135 | if (kr != kIOReturnSuccess) { 136 | continue 137 | } 138 | 139 | kr = deviceInterface.GetDeviceProduct(deviceInterfacePtrPtr, &pid) 140 | if (kr != kIOReturnSuccess) { 141 | continue 142 | } 143 | 144 | let device = USBDevice( 145 | id: did, 146 | vendorId: vid, 147 | productId: pid, 148 | name:name, 149 | deviceInterfacePtrPtr:deviceInterfacePtrPtr, 150 | plugInInterfacePtrPtr:plugInInterfacePtrPtr 151 | ) 152 | 153 | NotificationCenter.default.post(name: .USBDeviceConnected, object: [ 154 | "device": device 155 | ]) 156 | } 157 | } 158 | 159 | open func rawDeviceRemoved(iterator: io_iterator_t) { 160 | while case let usbDevice = IOIteratorNext(iterator), usbDevice != 0 { 161 | var kr:Int32 = 0 162 | var did:UInt64 = 0 163 | 164 | kr = IORegistryEntryGetRegistryEntryID(usbDevice, &did) 165 | 166 | if(kr != kIOReturnSuccess) { 167 | print("Error getting device id") 168 | } 169 | 170 | // USB device object is no longer needed. 171 | kr = IOObjectRelease(usbDevice) 172 | 173 | if (kr != kIOReturnSuccess) 174 | { 175 | print("Couldn’t release raw device object (error: \(kr))") 176 | continue 177 | } 178 | 179 | NotificationCenter.default.post(name: .USBDeviceDisconnected, object: [ 180 | "id": did 181 | ]) 182 | } 183 | } 184 | } 185 | 186 | -------------------------------------------------------------------------------- /Pods/USBDeviceSwift/Sources/USBDeviceSwift.h: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceSwift.h 3 | // USBDeviceSwift 4 | // 5 | // Created by Artem Hruzd on 6/11/17. 6 | // Copyright © 2017 Artem Hruzd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for USBDeviceSwift. 12 | FOUNDATION_EXPORT double USBDeviceSwiftVersionNumber; 13 | 14 | //! Project version string for USBDeviceSwift. 15 | FOUNDATION_EXPORT const unsigned char USBDeviceSwiftVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # USB Detective 2 | 3 | This tiny tool for MacOS will detect Human Interface devices being inserted, warning for devices like Rubber Ducky. 4 | 5 | -------------------------------------------------------------------------------- /UsbDetective.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4054498B21E35B48004C64DB /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4054498A21E35B48004C64DB /* AboutWindowController.swift */; }; 11 | 405D62D921DF906600A0842F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62D821DF906600A0842F /* AppDelegate.swift */; }; 12 | 405D62DB21DF906600A0842F /* NewDeviceViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62DA21DF906600A0842F /* NewDeviceViewController.swift */; }; 13 | 405D62DD21DF906700A0842F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 405D62DC21DF906700A0842F /* Assets.xcassets */; }; 14 | 405D62E021DF906700A0842F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 405D62DE21DF906700A0842F /* Main.storyboard */; }; 15 | 405D62EB21DFBC2700A0842F /* NewDeviceWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62EA21DFBC2700A0842F /* NewDeviceWindowController.swift */; }; 16 | 405D62ED21E015A000A0842F /* BBUSBDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62EC21E015A000A0842F /* BBUSBDevice.swift */; }; 17 | 405D62F221E016F300A0842F /* USBInterfaceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 405D62F121E016F300A0842F /* USBInterfaceInterface.m */; }; 18 | 405D62F521E016FF00A0842F /* USBDeviceInterface.m in Sources */ = {isa = PBXBuildFile; fileRef = 405D62F421E016FF00A0842F /* USBDeviceInterface.m */; }; 19 | 405D62F821E0175100A0842F /* BBBUSBKitCore.m in Sources */ = {isa = PBXBuildFile; fileRef = 405D62F721E0175100A0842F /* BBBUSBKitCore.m */; }; 20 | 405D62FD21E0183A00A0842F /* BBBUSBDeviceDescriptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62FC21E0183A00A0842F /* BBBUSBDeviceDescriptor.swift */; }; 21 | 405D62FF21E0186D00A0842F /* BBBUSBInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D62FE21E0186D00A0842F /* BBBUSBInterface.swift */; }; 22 | 405D630121E018A100A0842F /* BBBUSBEndpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D630021E018A100A0842F /* BBBUSBEndpoint.swift */; }; 23 | 405D630321E0190000A0842F /* BBBUSBKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405D630221E0190000A0842F /* BBBUSBKit.swift */; }; 24 | F68BEF3C62FA94ADB2230635 /* Pods_UsbDetective.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C777F451F3A40C11999B3C1 /* Pods_UsbDetective.framework */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | 0AD82CA5BB719C0B22CD2DB7 /* Pods-UsbDetective.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UsbDetective.release.xcconfig"; path = "Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective.release.xcconfig"; sourceTree = ""; }; 29 | 4054498A21E35B48004C64DB /* AboutWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutWindowController.swift; sourceTree = ""; }; 30 | 405D62D521DF906600A0842F /* UsbDetective.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = UsbDetective.app; sourceTree = BUILT_PRODUCTS_DIR; }; 31 | 405D62D821DF906600A0842F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 32 | 405D62DA21DF906600A0842F /* NewDeviceViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewDeviceViewController.swift; sourceTree = ""; }; 33 | 405D62DC21DF906700A0842F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 34 | 405D62DF21DF906700A0842F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 35 | 405D62E121DF906700A0842F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 36 | 405D62E221DF906700A0842F /* UsbDetective.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = UsbDetective.entitlements; sourceTree = ""; }; 37 | 405D62EA21DFBC2700A0842F /* NewDeviceWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewDeviceWindowController.swift; sourceTree = ""; }; 38 | 405D62EC21E015A000A0842F /* BBUSBDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBUSBDevice.swift; sourceTree = ""; }; 39 | 405D62F121E016F300A0842F /* USBInterfaceInterface.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = USBInterfaceInterface.m; sourceTree = ""; }; 40 | 405D62F321E016FF00A0842F /* UsbDetective-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UsbDetective-Bridging-Header.h"; sourceTree = ""; }; 41 | 405D62F421E016FF00A0842F /* USBDeviceInterface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = USBDeviceInterface.m; sourceTree = ""; }; 42 | 405D62F621E0171100A0842F /* USBInterfaceInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = USBInterfaceInterface.h; sourceTree = ""; }; 43 | 405D62F721E0175100A0842F /* BBBUSBKitCore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BBBUSBKitCore.m; sourceTree = ""; }; 44 | 405D62F921E0175B00A0842F /* BBBUSBKitCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BBBUSBKitCore.h; sourceTree = ""; }; 45 | 405D62FA21E0178900A0842F /* BBUSBKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BBUSBKit.h; sourceTree = ""; }; 46 | 405D62FB21E017F100A0842F /* USBDeviceInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = USBDeviceInterface.h; sourceTree = ""; }; 47 | 405D62FC21E0183A00A0842F /* BBBUSBDeviceDescriptor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBBUSBDeviceDescriptor.swift; sourceTree = ""; }; 48 | 405D62FE21E0186D00A0842F /* BBBUSBInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBBUSBInterface.swift; sourceTree = ""; }; 49 | 405D630021E018A100A0842F /* BBBUSBEndpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBBUSBEndpoint.swift; sourceTree = ""; }; 50 | 405D630221E0190000A0842F /* BBBUSBKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BBBUSBKit.swift; sourceTree = ""; }; 51 | 44E794BBBEE68B1C7254920D /* Pods-UsbDetective.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UsbDetective.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective.debug.xcconfig"; sourceTree = ""; }; 52 | 9C777F451F3A40C11999B3C1 /* Pods_UsbDetective.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UsbDetective.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | /* End PBXFileReference section */ 54 | 55 | /* Begin PBXFrameworksBuildPhase section */ 56 | 405D62D221DF906600A0842F /* Frameworks */ = { 57 | isa = PBXFrameworksBuildPhase; 58 | buildActionMask = 2147483647; 59 | files = ( 60 | F68BEF3C62FA94ADB2230635 /* Pods_UsbDetective.framework in Frameworks */, 61 | ); 62 | runOnlyForDeploymentPostprocessing = 0; 63 | }; 64 | /* End PBXFrameworksBuildPhase section */ 65 | 66 | /* Begin PBXGroup section */ 67 | 0302E1FC2E42CF573489A261 /* Pods */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 44E794BBBEE68B1C7254920D /* Pods-UsbDetective.debug.xcconfig */, 71 | 0AD82CA5BB719C0B22CD2DB7 /* Pods-UsbDetective.release.xcconfig */, 72 | ); 73 | name = Pods; 74 | sourceTree = ""; 75 | }; 76 | 405D62CC21DF906600A0842F = { 77 | isa = PBXGroup; 78 | children = ( 79 | 405D62D721DF906600A0842F /* UsbDetective */, 80 | 405D62D621DF906600A0842F /* Products */, 81 | 0302E1FC2E42CF573489A261 /* Pods */, 82 | 7D7C27D53B688D0599BE6DC3 /* Frameworks */, 83 | ); 84 | sourceTree = ""; 85 | }; 86 | 405D62D621DF906600A0842F /* Products */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 405D62D521DF906600A0842F /* UsbDetective.app */, 90 | ); 91 | name = Products; 92 | sourceTree = ""; 93 | }; 94 | 405D62D721DF906600A0842F /* UsbDetective */ = { 95 | isa = PBXGroup; 96 | children = ( 97 | 4084964821E2AA520016277B /* BBUSBKit */, 98 | 405D62F321E016FF00A0842F /* UsbDetective-Bridging-Header.h */, 99 | 405D62D821DF906600A0842F /* AppDelegate.swift */, 100 | 405D62DA21DF906600A0842F /* NewDeviceViewController.swift */, 101 | 405D62EA21DFBC2700A0842F /* NewDeviceWindowController.swift */, 102 | 4054498A21E35B48004C64DB /* AboutWindowController.swift */, 103 | 405D62DC21DF906700A0842F /* Assets.xcassets */, 104 | 405D62DE21DF906700A0842F /* Main.storyboard */, 105 | 405D62E121DF906700A0842F /* Info.plist */, 106 | 405D62E221DF906700A0842F /* UsbDetective.entitlements */, 107 | ); 108 | path = UsbDetective; 109 | sourceTree = ""; 110 | }; 111 | 4084964821E2AA520016277B /* BBUSBKit */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | 405D62F421E016FF00A0842F /* USBDeviceInterface.m */, 115 | 405D62EC21E015A000A0842F /* BBUSBDevice.swift */, 116 | 405D62F121E016F300A0842F /* USBInterfaceInterface.m */, 117 | 405D62F621E0171100A0842F /* USBInterfaceInterface.h */, 118 | 405D62F721E0175100A0842F /* BBBUSBKitCore.m */, 119 | 405D62F921E0175B00A0842F /* BBBUSBKitCore.h */, 120 | 405D62FA21E0178900A0842F /* BBUSBKit.h */, 121 | 405D62FB21E017F100A0842F /* USBDeviceInterface.h */, 122 | 405D62FC21E0183A00A0842F /* BBBUSBDeviceDescriptor.swift */, 123 | 405D62FE21E0186D00A0842F /* BBBUSBInterface.swift */, 124 | 405D630021E018A100A0842F /* BBBUSBEndpoint.swift */, 125 | 405D630221E0190000A0842F /* BBBUSBKit.swift */, 126 | ); 127 | path = BBUSBKit; 128 | sourceTree = ""; 129 | }; 130 | 7D7C27D53B688D0599BE6DC3 /* Frameworks */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 9C777F451F3A40C11999B3C1 /* Pods_UsbDetective.framework */, 134 | ); 135 | name = Frameworks; 136 | sourceTree = ""; 137 | }; 138 | /* End PBXGroup section */ 139 | 140 | /* Begin PBXNativeTarget section */ 141 | 405D62D421DF906600A0842F /* UsbDetective */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 405D62E521DF906700A0842F /* Build configuration list for PBXNativeTarget "UsbDetective" */; 144 | buildPhases = ( 145 | A5C71685C4498252CD1A586F /* [CP] Check Pods Manifest.lock */, 146 | 405D62D121DF906600A0842F /* Sources */, 147 | 405D62D221DF906600A0842F /* Frameworks */, 148 | 405D62D321DF906600A0842F /* Resources */, 149 | 6F78FD42A9B399A2906B4ED3 /* [CP] Embed Pods Frameworks */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | ); 155 | name = UsbDetective; 156 | productName = UsbDetective; 157 | productReference = 405D62D521DF906600A0842F /* UsbDetective.app */; 158 | productType = "com.apple.product-type.application"; 159 | }; 160 | /* End PBXNativeTarget section */ 161 | 162 | /* Begin PBXProject section */ 163 | 405D62CD21DF906600A0842F /* Project object */ = { 164 | isa = PBXProject; 165 | attributes = { 166 | LastSwiftUpdateCheck = 1010; 167 | LastUpgradeCheck = 1010; 168 | ORGANIZATIONNAME = DutchSec; 169 | TargetAttributes = { 170 | 405D62D421DF906600A0842F = { 171 | CreatedOnToolsVersion = 10.1; 172 | LastSwiftMigration = 1010; 173 | }; 174 | }; 175 | }; 176 | buildConfigurationList = 405D62D021DF906600A0842F /* Build configuration list for PBXProject "UsbDetective" */; 177 | compatibilityVersion = "Xcode 9.3"; 178 | developmentRegion = en; 179 | hasScannedForEncodings = 0; 180 | knownRegions = ( 181 | en, 182 | Base, 183 | ); 184 | mainGroup = 405D62CC21DF906600A0842F; 185 | productRefGroup = 405D62D621DF906600A0842F /* Products */; 186 | projectDirPath = ""; 187 | projectRoot = ""; 188 | targets = ( 189 | 405D62D421DF906600A0842F /* UsbDetective */, 190 | ); 191 | }; 192 | /* End PBXProject section */ 193 | 194 | /* Begin PBXResourcesBuildPhase section */ 195 | 405D62D321DF906600A0842F /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 405D62DD21DF906700A0842F /* Assets.xcassets in Resources */, 200 | 405D62E021DF906700A0842F /* Main.storyboard in Resources */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXResourcesBuildPhase section */ 205 | 206 | /* Begin PBXShellScriptBuildPhase section */ 207 | 6F78FD42A9B399A2906B4ED3 /* [CP] Embed Pods Frameworks */ = { 208 | isa = PBXShellScriptBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | ); 212 | inputPaths = ( 213 | "${SRCROOT}/Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-frameworks.sh", 214 | "${BUILT_PRODUCTS_DIR}/USBDeviceSwift/USBDeviceSwift.framework", 215 | ); 216 | name = "[CP] Embed Pods Frameworks"; 217 | outputPaths = ( 218 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/USBDeviceSwift.framework", 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | shellPath = /bin/sh; 222 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-UsbDetective/Pods-UsbDetective-frameworks.sh\"\n"; 223 | showEnvVarsInLog = 0; 224 | }; 225 | A5C71685C4498252CD1A586F /* [CP] Check Pods Manifest.lock */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputPaths = ( 231 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 232 | "${PODS_ROOT}/Manifest.lock", 233 | ); 234 | name = "[CP] Check Pods Manifest.lock"; 235 | outputPaths = ( 236 | "$(DERIVED_FILE_DIR)/Pods-UsbDetective-checkManifestLockResult.txt", 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 241 | showEnvVarsInLog = 0; 242 | }; 243 | /* End PBXShellScriptBuildPhase section */ 244 | 245 | /* Begin PBXSourcesBuildPhase section */ 246 | 405D62D121DF906600A0842F /* Sources */ = { 247 | isa = PBXSourcesBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | 405D62F821E0175100A0842F /* BBBUSBKitCore.m in Sources */, 251 | 405D630321E0190000A0842F /* BBBUSBKit.swift in Sources */, 252 | 405D62F521E016FF00A0842F /* USBDeviceInterface.m in Sources */, 253 | 405D630121E018A100A0842F /* BBBUSBEndpoint.swift in Sources */, 254 | 405D62DB21DF906600A0842F /* NewDeviceViewController.swift in Sources */, 255 | 405D62D921DF906600A0842F /* AppDelegate.swift in Sources */, 256 | 405D62ED21E015A000A0842F /* BBUSBDevice.swift in Sources */, 257 | 405D62EB21DFBC2700A0842F /* NewDeviceWindowController.swift in Sources */, 258 | 405D62FF21E0186D00A0842F /* BBBUSBInterface.swift in Sources */, 259 | 4054498B21E35B48004C64DB /* AboutWindowController.swift in Sources */, 260 | 405D62FD21E0183A00A0842F /* BBBUSBDeviceDescriptor.swift in Sources */, 261 | 405D62F221E016F300A0842F /* USBInterfaceInterface.m in Sources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXSourcesBuildPhase section */ 266 | 267 | /* Begin PBXVariantGroup section */ 268 | 405D62DE21DF906700A0842F /* Main.storyboard */ = { 269 | isa = PBXVariantGroup; 270 | children = ( 271 | 405D62DF21DF906700A0842F /* Base */, 272 | ); 273 | name = Main.storyboard; 274 | sourceTree = ""; 275 | }; 276 | /* End PBXVariantGroup section */ 277 | 278 | /* Begin XCBuildConfiguration section */ 279 | 405D62E321DF906700A0842F /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | ALWAYS_SEARCH_USER_PATHS = NO; 283 | CLANG_ANALYZER_NONNULL = YES; 284 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 285 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 286 | CLANG_CXX_LIBRARY = "libc++"; 287 | CLANG_ENABLE_MODULES = YES; 288 | CLANG_ENABLE_OBJC_ARC = YES; 289 | CLANG_ENABLE_OBJC_WEAK = YES; 290 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 291 | CLANG_WARN_BOOL_CONVERSION = YES; 292 | CLANG_WARN_COMMA = YES; 293 | CLANG_WARN_CONSTANT_CONVERSION = YES; 294 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 295 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 296 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 297 | CLANG_WARN_EMPTY_BODY = YES; 298 | CLANG_WARN_ENUM_CONVERSION = YES; 299 | CLANG_WARN_INFINITE_RECURSION = YES; 300 | CLANG_WARN_INT_CONVERSION = YES; 301 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 302 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 303 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 304 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 305 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 306 | CLANG_WARN_STRICT_PROTOTYPES = YES; 307 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 308 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 309 | CLANG_WARN_UNREACHABLE_CODE = YES; 310 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 311 | CODE_SIGN_IDENTITY = "Mac Developer"; 312 | COPY_PHASE_STRIP = NO; 313 | DEBUG_INFORMATION_FORMAT = dwarf; 314 | ENABLE_STRICT_OBJC_MSGSEND = YES; 315 | ENABLE_TESTABILITY = YES; 316 | GCC_C_LANGUAGE_STANDARD = gnu11; 317 | GCC_DYNAMIC_NO_PIC = NO; 318 | GCC_NO_COMMON_BLOCKS = YES; 319 | GCC_OPTIMIZATION_LEVEL = 0; 320 | GCC_PREPROCESSOR_DEFINITIONS = ( 321 | "DEBUG=1", 322 | "$(inherited)", 323 | ); 324 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 325 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 326 | GCC_WARN_UNDECLARED_SELECTOR = YES; 327 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 328 | GCC_WARN_UNUSED_FUNCTION = YES; 329 | GCC_WARN_UNUSED_VARIABLE = YES; 330 | MACOSX_DEPLOYMENT_TARGET = 10.14; 331 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 332 | MTL_FAST_MATH = YES; 333 | ONLY_ACTIVE_ARCH = YES; 334 | SDKROOT = macosx; 335 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 336 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 337 | }; 338 | name = Debug; 339 | }; 340 | 405D62E421DF906700A0842F /* Release */ = { 341 | isa = XCBuildConfiguration; 342 | buildSettings = { 343 | ALWAYS_SEARCH_USER_PATHS = NO; 344 | CLANG_ANALYZER_NONNULL = YES; 345 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 346 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 347 | CLANG_CXX_LIBRARY = "libc++"; 348 | CLANG_ENABLE_MODULES = YES; 349 | CLANG_ENABLE_OBJC_ARC = YES; 350 | CLANG_ENABLE_OBJC_WEAK = YES; 351 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 352 | CLANG_WARN_BOOL_CONVERSION = YES; 353 | CLANG_WARN_COMMA = YES; 354 | CLANG_WARN_CONSTANT_CONVERSION = YES; 355 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 356 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 357 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 358 | CLANG_WARN_EMPTY_BODY = YES; 359 | CLANG_WARN_ENUM_CONVERSION = YES; 360 | CLANG_WARN_INFINITE_RECURSION = YES; 361 | CLANG_WARN_INT_CONVERSION = YES; 362 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 363 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 364 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 365 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 366 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 367 | CLANG_WARN_STRICT_PROTOTYPES = YES; 368 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 369 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 370 | CLANG_WARN_UNREACHABLE_CODE = YES; 371 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 372 | CODE_SIGN_IDENTITY = "Mac Developer"; 373 | COPY_PHASE_STRIP = NO; 374 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 375 | ENABLE_NS_ASSERTIONS = NO; 376 | ENABLE_STRICT_OBJC_MSGSEND = YES; 377 | GCC_C_LANGUAGE_STANDARD = gnu11; 378 | GCC_NO_COMMON_BLOCKS = YES; 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | MACOSX_DEPLOYMENT_TARGET = 10.14; 386 | MTL_ENABLE_DEBUG_INFO = NO; 387 | MTL_FAST_MATH = YES; 388 | SDKROOT = macosx; 389 | SWIFT_COMPILATION_MODE = wholemodule; 390 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 391 | }; 392 | name = Release; 393 | }; 394 | 405D62E621DF906700A0842F /* Debug */ = { 395 | isa = XCBuildConfiguration; 396 | baseConfigurationReference = 44E794BBBEE68B1C7254920D /* Pods-UsbDetective.debug.xcconfig */; 397 | buildSettings = { 398 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 399 | CLANG_ENABLE_MODULES = YES; 400 | CODE_SIGN_ENTITLEMENTS = UsbDetective/UsbDetective.entitlements; 401 | CODE_SIGN_STYLE = Automatic; 402 | COMBINE_HIDPI_IMAGES = YES; 403 | DEVELOPMENT_TEAM = JV6YYK93WA; 404 | INFOPLIST_FILE = UsbDetective/Info.plist; 405 | LD_RUNPATH_SEARCH_PATHS = ( 406 | "$(inherited)", 407 | "@executable_path/../Frameworks", 408 | ); 409 | PRODUCT_BUNDLE_IDENTIFIER = dutchsec.UsbDetective; 410 | PRODUCT_NAME = "$(TARGET_NAME)"; 411 | SWIFT_OBJC_BRIDGING_HEADER = "UsbDetective/UsbDetective-Bridging-Header.h"; 412 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 413 | SWIFT_VERSION = 4.2; 414 | }; 415 | name = Debug; 416 | }; 417 | 405D62E721DF906700A0842F /* Release */ = { 418 | isa = XCBuildConfiguration; 419 | baseConfigurationReference = 0AD82CA5BB719C0B22CD2DB7 /* Pods-UsbDetective.release.xcconfig */; 420 | buildSettings = { 421 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 422 | CLANG_ENABLE_MODULES = YES; 423 | CODE_SIGN_ENTITLEMENTS = UsbDetective/UsbDetective.entitlements; 424 | CODE_SIGN_STYLE = Automatic; 425 | COMBINE_HIDPI_IMAGES = YES; 426 | DEVELOPMENT_TEAM = JV6YYK93WA; 427 | INFOPLIST_FILE = UsbDetective/Info.plist; 428 | LD_RUNPATH_SEARCH_PATHS = ( 429 | "$(inherited)", 430 | "@executable_path/../Frameworks", 431 | ); 432 | PRODUCT_BUNDLE_IDENTIFIER = dutchsec.UsbDetective; 433 | PRODUCT_NAME = "$(TARGET_NAME)"; 434 | SWIFT_OBJC_BRIDGING_HEADER = "UsbDetective/UsbDetective-Bridging-Header.h"; 435 | SWIFT_VERSION = 4.2; 436 | }; 437 | name = Release; 438 | }; 439 | /* End XCBuildConfiguration section */ 440 | 441 | /* Begin XCConfigurationList section */ 442 | 405D62D021DF906600A0842F /* Build configuration list for PBXProject "UsbDetective" */ = { 443 | isa = XCConfigurationList; 444 | buildConfigurations = ( 445 | 405D62E321DF906700A0842F /* Debug */, 446 | 405D62E421DF906700A0842F /* Release */, 447 | ); 448 | defaultConfigurationIsVisible = 0; 449 | defaultConfigurationName = Release; 450 | }; 451 | 405D62E521DF906700A0842F /* Build configuration list for PBXNativeTarget "UsbDetective" */ = { 452 | isa = XCConfigurationList; 453 | buildConfigurations = ( 454 | 405D62E621DF906700A0842F /* Debug */, 455 | 405D62E721DF906700A0842F /* Release */, 456 | ); 457 | defaultConfigurationIsVisible = 0; 458 | defaultConfigurationName = Release; 459 | }; 460 | /* End XCConfigurationList section */ 461 | }; 462 | rootObject = 405D62CD21DF906600A0842F /* Project object */; 463 | } 464 | -------------------------------------------------------------------------------- /UsbDetective.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /UsbDetective.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UsbDetective.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /UsbDetective.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /UsbDetective/AboutWindowController.swift: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | import Foundation 19 | import Cocoa 20 | 21 | class AboutWindowController: NSWindowController, NSWindowDelegate { 22 | override func windowDidLoad() { 23 | super.windowDidLoad() 24 | 25 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 26 | self.window?.center() 27 | self.window?.makeKeyAndOrderFront(nil) 28 | // NSApp.activateIgnoringOtherApps(true) 29 | } 30 | 31 | override var windowNibName: String! { 32 | return "About" 33 | } 34 | 35 | func windowWillClose(_ notification: Notification) { 36 | if (NSApplication.shared.modalWindow == self.window) { 37 | NSApplication.shared.stopModal() 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /UsbDetective/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | // https://developer.apple.com/library/archive/samplecode/USBPrivateDataSample/Listings/USBPrivateDataSample_c.html 19 | 20 | import Cocoa 21 | import USBDeviceSwift 22 | import AppKit 23 | 24 | import IOKit 25 | import IOKit.hid 26 | import IOKit.usb 27 | 28 | class USBDevice { 29 | var Name: String = "" 30 | var PrimaryUsage: Int = 0 31 | var Category: String = "" 32 | var Manufacturer: String = "" 33 | var TransportKey: String = "" 34 | var ManufacturerKey: String = "" 35 | var ProductID: Int = 0 36 | var VendorID: Int = 0 37 | var SerialNumber: String = "" 38 | var UniqueIdentifier: Int = 0 39 | 40 | init(device: IOHIDDevice) { 41 | self.Name = IOHIDDeviceGetProperty(device, kIOHIDProductKey as CFString) as? String ?? "HID Device" 42 | self.VendorID = IOHIDDeviceGetProperty(device, kIOHIDVendorIDKey as CFString) as? Int ?? 0 43 | self.ProductID = IOHIDDeviceGetProperty(device, kIOHIDProductIDKey as CFString) as? Int ?? 0 44 | self.UniqueIdentifier = IOHIDDeviceGetProperty(device, kIOHIDUniqueIDKey as CFString) as? Int ?? 0 45 | self.TransportKey = IOHIDDeviceGetProperty(device, kIOHIDTransportKey as CFString) as? String ?? "" 46 | self.ManufacturerKey = IOHIDDeviceGetProperty(device, kIOHIDManufacturerKey as CFString) as? String ?? "" 47 | self.SerialNumber = IOHIDDeviceGetProperty(device, kIOHIDSerialNumberKey as CFString) as? String ?? "" 48 | self.PrimaryUsage = IOHIDDeviceGetProperty(device, kIOHIDPrimaryUsageKey as CFString) as? Int ?? 0 49 | // self.ReportDescriptorKey = IOHIDDeviceGetProperty(device, kIOHIDReportDescriptorKey as CFString) as? String ?? "" 50 | // self.LocationIDKey = IOHIDDeviceGetProperty(device, kIOHIDLocationIDKey as CFString) as? String ?? "" 51 | // self.ModelNumberKey = IOHIDDeviceGetProperty(device, kIOHIDModelNumberKey as CFString) as? String ?? "" 52 | } 53 | 54 | func Signature() -> String { 55 | return "\(self.Name)#\(self.VendorID)#\(self.ProductID)#\(self.SerialNumber)#\(self.TransportKey)#\(self.ManufacturerKey)" 56 | } 57 | } 58 | 59 | @NSApplicationMain 60 | class AppDelegate: NSObject, NSApplicationDelegate { 61 | let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) 62 | 63 | var devices: [Int: USBDevice] = [:] 64 | 65 | let hidTypes = [ 66 | 1: "Pointer", 67 | 2: "Mouse", 68 | 4: "Joystick", 69 | 5: "Game Pad", 70 | 6: "Keyboard", 71 | 7: "Keypad", 72 | 8: "Multi-axis Controller", 73 | ] 74 | 75 | lazy var newDeviceWindowController: NSWindowController = { 76 | return (NSStoryboard(name: "Main",bundle: nil).instantiateController(withIdentifier: "NewDevice") as? NSWindowController)! 77 | }() 78 | 79 | lazy var aboutWindowController: NSWindowController = { 80 | return (NSStoryboard(name: "Main",bundle: nil).instantiateController(withIdentifier: "About") as? NSWindowController)! 81 | }() 82 | 83 | lazy var manager: IOHIDManager = { 84 | return IOHIDManagerCreate(nil, 0) 85 | }() 86 | 87 | let aboutItem: NSMenuItem = NSMenuItem(title: "About", action: #selector(doAbout), keyEquivalent: "") 88 | let resetItem: NSMenuItem = NSMenuItem(title: "Reset", action: #selector(doReset), keyEquivalent: "") 89 | let quitItem: NSMenuItem = NSMenuItem(title: "Quit", action: #selector(doQuit), keyEquivalent: "") 90 | 91 | @objc func doAbout(sender: AnyObject){ 92 | NSApplication.shared.runModal(for: aboutWindowController.window!) 93 | aboutWindowController.close() 94 | } 95 | 96 | @objc func doQuit(sender: AnyObject){ 97 | NSApplication.shared.terminate(nil) 98 | } 99 | 100 | @objc func doReset(sender: AnyObject){ 101 | let whitelist = [String]() 102 | UserDefaults.standard.set(whitelist, forKey: "whitelist") 103 | 104 | let alert:NSAlert = NSAlert(); 105 | alert.messageText = "USBDetective"; 106 | alert.alertStyle = NSAlert.Style.warning 107 | alert.informativeText = "USBDetective has been resetted." 108 | alert.runModal(); 109 | } 110 | 111 | private func updateMenu() { 112 | statusItem.menu?.removeAllItems() 113 | 114 | let keys = devices.keys.sorted { (a, b) -> Bool in 115 | let nameA = devices[a]!.Name 116 | let nameB = devices[b]!.Name 117 | return nameA.compare(nameB) == ComparisonResult.orderedAscending 118 | } 119 | 120 | let types = [ 121 | "Pointer": 1, 122 | "Mouse": 2, 123 | "Keyboard ⌨": 6, 124 | ] 125 | 126 | for (name) in types.keys.sorted() { 127 | let type = types[name] 128 | 129 | let newItem : NSMenuItem = NSMenuItem(title: "\(name)" , action: nil, keyEquivalent: "") 130 | newItem.indentationLevel = 0 131 | self.statusItem.menu?.addItem(newItem) 132 | 133 | for (key) in keys { 134 | let device = devices[key]!; 135 | 136 | let name = device.Name 137 | let primaryUsageKey = device.PrimaryUsage 138 | 139 | if (primaryUsageKey != type) { 140 | continue 141 | } 142 | 143 | let newItem : NSMenuItem = NSMenuItem(title: "\u{2022} \(name)" , action: nil, keyEquivalent: "") 144 | newItem.indentationLevel = 1 145 | newItem.representedObject = device 146 | self.statusItem.menu?.addItem(newItem) 147 | } 148 | } 149 | 150 | let newItem : NSMenuItem = NSMenuItem(title: "Other" , action: nil, keyEquivalent: "") 151 | newItem.indentationLevel = 0 152 | self.statusItem.menu?.addItem(newItem) 153 | 154 | for (key) in keys { 155 | let device = devices[key]!; 156 | 157 | let name = device.Name 158 | let primaryUsageKey = device.PrimaryUsage 159 | 160 | if (types.contains(where: { (arg0) -> Bool in 161 | let (_, value) = arg0 162 | return (value == primaryUsageKey) 163 | })) { 164 | continue 165 | } 166 | 167 | let newItem : NSMenuItem = NSMenuItem(title: "\u{2022} \(name)" , action: nil, keyEquivalent: "") 168 | newItem.indentationLevel = 1 169 | newItem.representedObject = device 170 | self.statusItem.menu?.addItem(newItem) 171 | } 172 | 173 | statusItem.menu?.addItem(NSMenuItem.separator()) 174 | statusItem.menu?.addItem(resetItem) 175 | statusItem.menu?.addItem(NSMenuItem.separator()) 176 | statusItem.menu?.addItem(aboutItem) 177 | statusItem.menu?.addItem(quitItem) 178 | } 179 | 180 | private func removedDevice(_ device: IOHIDDevice) { 181 | let uniqueIdentifier = IOHIDDeviceGetProperty(device, kIOHIDUniqueIDKey as CFString) as? Int ?? 0 182 | let ub = devices[uniqueIdentifier]! 183 | 184 | defer { 185 | devices.removeValue(forKey: uniqueIdentifier) 186 | self.updateMenu() 187 | } 188 | 189 | let whitelist = UserDefaults.standard.array(forKey: "whitelist") as? [String] ?? [String]() 190 | if (whitelist.contains(ub.Signature())) { 191 | return 192 | } 193 | 194 | let usageKeyText = hidTypes[ub.PrimaryUsage] ?? "Unknown Device(\(ub.PrimaryUsage))" 195 | 196 | let notification = NSUserNotification() 197 | // notification.identifier = "unique-id" 198 | notification.title = "Device removal detected: \(ub.Name)" 199 | notification.subtitle = "" 200 | notification.informativeText = "Removal of device (\(usageKeyText)) interface has been detected. Usage=\(usageKeyText) Vendor: 0x\(String(format:"0x%04X", ub.VendorID)) Product: \(String(format:"0x%04X", ub.ProductID)) Serial=\(ub.SerialNumber) " 201 | 202 | notification.soundName = NSUserNotificationDefaultSoundName 203 | notification.contentImage = NSImage(contentsOf: NSURL(string: "https://placehold.it/300")! as URL) 204 | 205 | // Manually display the notification 206 | let notificationCenter = NSUserNotificationCenter.default 207 | notificationCenter.deliver(notification) 208 | } 209 | 210 | private func foundDevice(_ device: IOHIDDevice) { 211 | var whitelist = UserDefaults.standard.array(forKey: "whitelist") as? [String] ?? [String]() 212 | 213 | let ub = USBDevice(device: device) 214 | 215 | defer { 216 | devices[ub.UniqueIdentifier] = ub 217 | self.updateMenu() 218 | } 219 | 220 | if (whitelist.contains(ub.Signature())) { 221 | return 222 | } 223 | 224 | let viewController = newDeviceWindowController.contentViewController as! NewDeviceViewController 225 | 226 | viewController.representedObject = ub 227 | 228 | switch (newDeviceWindowController as! NewDeviceWindowController).runModal() { 229 | case .Whitelist: 230 | whitelist.append(ub.Signature()) 231 | UserDefaults.standard.set(whitelist, forKey: "whitelist") 232 | break 233 | case .Close: 234 | break 235 | } 236 | 237 | newDeviceWindowController.close() 238 | 239 | let usageKeyText = hidTypes[ub.PrimaryUsage] ?? "Unknown Device(\(ub.PrimaryUsage))" 240 | 241 | let notification = NSUserNotification() 242 | notification.identifier = "\(ub.UniqueIdentifier)" 243 | notification.title = "New device detected: \(ub.Name)" 244 | notification.subtitle = "" 245 | notification.informativeText = "New device (\(usageKeyText)) interface has been detected. Usage=\(usageKeyText) Vendor: 0x\(String(format:"0x%04X", ub.VendorID)) Product: \(String(format:"0x%04X", ub.ProductID)) Serial=\(ub.SerialNumber) " 246 | 247 | // notification.soundName = NSUserNotificationDefaultSoundName 248 | // notification.contentImage = NSImage(contentsOf: NSURL(string: "https://placehold.it/300")! as URL) 249 | 250 | // Manually display the notification 251 | let notificationCenter = NSUserNotificationCenter.default 252 | notificationCenter.deliver(notification) 253 | } 254 | 255 | func applicationDidFinishLaunching(_ aNotification: Notification) { 256 | IOHIDManagerSetDeviceMatching(manager, nil) 257 | 258 | IOHIDManagerRegisterDeviceMatchingCallback(manager, { context, result, other, device in 259 | let selfPointer = unsafeBitCast(context, to: AppDelegate.self) 260 | selfPointer.foundDevice(device) 261 | }, UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())) 262 | 263 | IOHIDManagerRegisterDeviceRemovalCallback(manager, { context, result, other, device in 264 | let selfPointer = unsafeBitCast(context, to: AppDelegate.self) 265 | selfPointer.removedDevice(device) 266 | }, UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())) 267 | 268 | IOHIDManagerScheduleWithRunLoop(manager, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue) 269 | 270 | let result = IOHIDManagerOpen(manager, 0) 271 | guard result == kIOReturnSuccess else { 272 | let alert:NSAlert = NSAlert(); 273 | alert.messageText = "Could not open IOHIDManager"; 274 | alert.alertStyle = NSAlert.Style.warning 275 | alert.informativeText = "IOHIDManagerOpen returned error: \(result)" 276 | alert.runModal(); 277 | return 278 | } 279 | 280 | guard statusItem.button != nil else { 281 | NSLog("Can't get menuButton") 282 | return 283 | } 284 | 285 | statusItem.highlightMode = true 286 | statusItem.menu = NSMenu() 287 | 288 | let newItem : NSMenuItem = NSMenuItem(title: "Loading device list..." , action: nil, keyEquivalent: "") 289 | self.statusItem.menu?.addItem(newItem) 290 | 291 | statusItem.menu?.addItem(NSMenuItem.separator()) 292 | statusItem.menu?.addItem(quitItem) 293 | 294 | // nice icon here 295 | statusItem.button?.title = "Usb 🔍" 296 | 297 | updateMenu() 298 | 299 | let matchingDict = IOServiceMatching(kIOUSBDeviceClassName) 300 | 301 | let notifyPort = IONotificationPortCreate(kIOMasterPortDefault) 302 | 303 | let notifyQueue = DispatchQueue.global()// (label: "com.georgwacker.discrotate.notifyQueue") 304 | IONotificationPortSetDispatchQueue(notifyPort, notifyQueue) 305 | 306 | let selfPtr = Unmanaged.passUnretained(self).toOpaque() 307 | 308 | var newDevicesIterator: io_iterator_t = 0; 309 | 310 | let usbDeviceAppeared: IOServiceMatchingCallback = { (refcon, iterator) in 311 | print("Matching USB device appeared") 312 | } 313 | 314 | // https://github.com/georgwacker/DiscRotate/blob/f13156c72595160f752ae4d952e47ff92f9d31b5/DiscRotate/OpticalMediaDetector.swift 315 | // https://pastebin.com/icyAAUzZ 316 | IOServiceAddMatchingNotification(notifyPort, kIOMatchedNotification, matchingDict, usbDeviceAppeared, selfPtr, &newDevicesIterator) 317 | 318 | var lostDevicesIterator: io_iterator_t = 0; 319 | 320 | let usbDeviceDisappeared: IOServiceMatchingCallback = { (refcon, iterator) in 321 | print("Matching USB device disappeared") 322 | } 323 | 324 | IOServiceAddMatchingNotification(notifyPort, kIOTerminatedNotification, matchingDict, usbDeviceDisappeared, selfPtr, &lostDevicesIterator) 325 | 326 | _ = self.listDevices() 327 | } 328 | 329 | public func listDevices() -> [String]? { 330 | var iterator: io_iterator_t = io_iterator_t() 331 | 332 | let matchingInformation = IOServiceMatching(kIOUSBDeviceClassName) 333 | let kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingInformation, &iterator) 334 | if kr != kIOReturnSuccess { 335 | print("Error") 336 | return nil 337 | } 338 | defer { 339 | IOObjectRelease(iterator) 340 | } 341 | 342 | var devices: [String] = [] 343 | 344 | for service in IOServiceSequence(iterator) { 345 | if let device = BBBUSBDevice(service: service) { // move service 346 | devices.append(device.name) 347 | } 348 | } 349 | 350 | return devices 351 | } 352 | 353 | 354 | func applicationWillTerminate(_ aNotification: Notification) { 355 | IOHIDManagerUnscheduleFromRunLoop(manager, CFRunLoopGetCurrent(), CFRunLoopMode.defaultMode.rawValue) 356 | IOHIDManagerClose(manager, 0) 357 | } 358 | } 359 | 360 | -------------------------------------------------------------------------------- /UsbDetective/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /UsbDetective/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBDeviceDescriptor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBDescriptor.swift 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/11. 6 | // Copyright © 2016 OTAKE Takayoshi. All rights reserved. 7 | // 8 | 9 | // 10 | // Refer to "Universal Serial Bus Specification Revision 2.0 (April 27, 2000)" for more information. 11 | // 12 | 13 | import Cocoa 14 | 15 | public struct BBBUSBDeviceDescriptor { 16 | public var bLength: UInt8 = 0 17 | public var bDescriptorType: UInt8 = 0 18 | public var bcdUSB: UInt16 = 0 19 | public var bDeviceClass: UInt8 = 0 20 | public var bDeviceSubClass: UInt8 = 0 21 | public var bDeviceProtocol: UInt8 = 0 22 | public var bMaxPacketSize0: UInt8 = 0 23 | public var idVendor: UInt16 = 0 24 | public var idProduct: UInt16 = 0 25 | public var bcdDevice: UInt16 = 0 26 | public var iManufacturer: UInt8 = 0 27 | public var iProduct: UInt8 = 0 28 | public var iSerialNumber: UInt8 = 0 29 | public var bNumConfigurations: UInt8 = 0 30 | 31 | public var manufacturerString: String? = nil 32 | public var productString: String? = nil 33 | public var serialNumberString: String? = nil 34 | 35 | init() { 36 | } 37 | } 38 | 39 | public struct BBBUSBConfigurationDescriptor { 40 | public var bLength: UInt8 = 0 41 | public var bDescriptorType: UInt8 = 0 42 | public var wTotalLength: UInt16 = 0 43 | public var bNumInterfaces: UInt8 = 0 44 | public var bConfigurationValue: UInt8 = 0 45 | public var iConfiguration: UInt8 = 0 46 | public var bmAttributes: UInt8 = 0 47 | public var bMaxPower: UInt8 = 0 48 | 49 | public var configurationString: String? = nil 50 | public var interfaces: [BBBUSBInterfaceDescriptor] = [] 51 | 52 | // [descriptorType : bytes] 53 | public var descriptors: [UInt8 : [UInt8]] = [:] 54 | 55 | init() { 56 | } 57 | } 58 | 59 | public struct BBBUSBInterfaceDescriptor { 60 | public var bLength: UInt8 = 0 61 | public var bDescriptorType: UInt8 = 0 62 | public var bInterfaceNumber: UInt8 = 0 63 | public var bAlternateSetting: UInt8 = 0 64 | public var bNumEndpoints: UInt8 = 0 65 | public var bInterfaceClass: UInt8 = 0 66 | public var bInterfaceSubClass: UInt8 = 0 67 | public var bInterfaceProtocol: UInt8 = 0 68 | public var iInterface: UInt8 = 0 69 | 70 | public var interfaceString: String? = nil 71 | public var endpoints: [BBBUSBEndpointDescriptor] = [] 72 | 73 | // [descriptorType : bytes] 74 | public var descriptors: [UInt8 : [UInt8]] = [:] 75 | 76 | init() { 77 | } 78 | } 79 | 80 | public struct BBBUSBEndpointDescriptor { 81 | public var bLength: UInt8 = 0 82 | public var bDescriptorType: UInt8 = 0 83 | public var bEndpointAddress: UInt8 = 0 84 | public var bmAttributes: UInt8 = 0 85 | public var wMaxPacketSize: UInt16 = 0 86 | public var bInterval: UInt8 = 0 87 | 88 | init() { 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBEndpoint.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBEndpoint.swift 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/12/03. 6 | // 7 | // 8 | 9 | import Cocoa 10 | 11 | public class BBBUSBEndpoint { 12 | 13 | public enum Direction { 14 | case out 15 | case `in` 16 | 17 | init(bEndpointAddressBit7: UInt8) { 18 | switch bEndpointAddressBit7 { 19 | case 0b0: 20 | self = .out 21 | case 0b1: 22 | self = .in 23 | default: 24 | fatalError() 25 | } 26 | } 27 | } 28 | 29 | public enum TransferType { 30 | case control 31 | case isochronous 32 | case bulk 33 | case interrupt 34 | 35 | init(bmAttributesBits1_0: UInt8) { 36 | switch bmAttributesBits1_0 { 37 | case 0b00: 38 | self = .control 39 | case 0b01: 40 | self = .isochronous 41 | case 0b10: 42 | self = .bulk 43 | case 0b11: 44 | self = .interrupt 45 | default: 46 | fatalError() 47 | } 48 | } 49 | } 50 | 51 | public let descriptor: BBBUSBEndpointDescriptor 52 | public let direction: Direction 53 | public let transferType: TransferType 54 | weak var interface: BBBUSBInterface! 55 | 56 | init(interface: BBBUSBInterface, descriptor: BBBUSBEndpointDescriptor) { 57 | self.interface = interface 58 | self.descriptor = descriptor 59 | direction = Direction(bEndpointAddressBit7: descriptor.bEndpointAddress >> 7) 60 | transferType = TransferType(bmAttributesBits1_0: descriptor.bmAttributes & 0x03) 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBInterface.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBInterface.swift 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/07. 6 | // 7 | // 8 | 9 | import Foundation 10 | // import BBBUSBKitPrivate 11 | 12 | public class BBBUSBInterface { 13 | public let descriptor: BBBUSBInterfaceDescriptor 14 | 15 | let service: io_service_t 16 | let interface: USBInterfaceInterface 17 | weak var device: BBBUSBDevice! 18 | 19 | init?(service: io_service_t, device: BBBUSBDevice, descriptor: BBBUSBInterfaceDescriptor) { 20 | self.service = service 21 | 22 | guard let interface = USBInterfaceInterface(service: service) else { 23 | IOObjectRelease(service) 24 | return nil // `deinit` is not called 25 | } 26 | self.interface = interface 27 | self.device = device 28 | self.descriptor = descriptor 29 | } 30 | 31 | deinit { 32 | IOObjectRelease(service) 33 | } 34 | 35 | 36 | public func open() throws { 37 | let err = interface.open() 38 | if err != kIOReturnSuccess { 39 | throw BBBUSBDeviceError.IOReturnError(err: Int(err)) 40 | } 41 | } 42 | 43 | public func close() throws { 44 | let err = interface.close() 45 | if (err == kIOReturnNotOpen) { 46 | // Ignore 47 | } 48 | else if (err != kIOReturnSuccess) { 49 | throw BBBUSBDeviceError.IOReturnError(err: Int(err)) 50 | } 51 | } 52 | 53 | public func listEndpoints() -> [BBBUSBEndpoint] { 54 | var endpoints: [BBBUSBEndpoint] = [] 55 | for epDesc in descriptor.endpoints { 56 | endpoints.append(BBBUSBEndpoint(interface: self, descriptor: epDesc)) 57 | } 58 | return endpoints 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBKit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBKit.swift 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/07. 6 | // 7 | // 8 | 9 | import Foundation 10 | //import BBBUSBKitPrivate 11 | 12 | #if false // because "Swift Compiler Error" has occured 13 | extension io_iterator_t: Sequence { 14 | // Swift Compiler Error: Method 'makeIterator()' must be declared public because it matches a requirement in public protocol 'Sequence' 15 | // Swift Compiler Error: Method must be declared internal because its result uses a internal type 16 | func makeIterator() -> IOServiceGenerator { 17 | return IOServiceGenerator(self) 18 | } 19 | } 20 | #else 21 | class IOServiceSequence: Sequence { 22 | let iterator: io_iterator_t 23 | 24 | init(_ iterator: io_iterator_t) { 25 | self.iterator = iterator 26 | } 27 | 28 | func makeIterator() -> IOServiceGenerator { 29 | return IOServiceGenerator(iterator) 30 | } 31 | } 32 | #endif 33 | 34 | class IOServiceGenerator: IteratorProtocol { 35 | let iterator: io_iterator_t 36 | 37 | init(_ iterator: io_iterator_t) { 38 | self.iterator = iterator 39 | } 40 | 41 | func next() -> io_service_t? { 42 | let service = IOIteratorNext(iterator) 43 | if service == 0 { 44 | return nil 45 | } 46 | return service 47 | } 48 | } 49 | 50 | func withBridgingIOReturnError(block: () throws -> T) throws -> T { 51 | do { 52 | return try block() 53 | } 54 | catch let error as NSError where error.domain == kBBBUSBKitIOReturnErrorDomain { 55 | throw BBBUSBDeviceError.IOReturnError(err: error.code) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBKitCore.h: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBKitCore.h 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #import 12 | #import 13 | #import 14 | 15 | typedef IOUSBDeviceInterface650 IOUSBDeviceInterfaceLatest; 16 | #define kIOUSBDeviceInterfaceIDLatest kIOUSBDeviceInterfaceID650 17 | 18 | typedef IOUSBInterfaceInterface800 IOUSBInterfaceInterfaceLatest; 19 | #define kIOUSBInterfaceInterfaceIDLatest kIOUSBInterfaceInterfaceID800 20 | 21 | 22 | static const NSErrorDomain kBBBUSBKitIOReturnErrorDomain = @"com.bigbamboo.BBBUSBKit.IOReturn"; 23 | @interface NSError (BBBUSBKit_IOReturn) 24 | + (NSError *)BBBUSBKitErrorWithIOReturnError:(IOReturn)err; 25 | @end 26 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBBUSBKitCore.m: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBKitCore.m 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/07. 6 | // 7 | // 8 | 9 | #import "BBBUSBKitCore.h" 10 | 11 | @implementation NSError (BBBUSBKit_IOReturn) 12 | + (NSError *)BBBUSBKitErrorWithIOReturnError:(IOReturn)err { 13 | return [NSError errorWithDomain:kBBBUSBKitIOReturnErrorDomain code:err userInfo:nil]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBUSBDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBDevice.swift 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | import Foundation 10 | // import BBBUSBKitPrivate 11 | 12 | public enum BBBUSBDeviceError: Error { 13 | case IOReturnError(err: Int) 14 | case illegalDescriptor 15 | } 16 | 17 | enum USBDescriptorType : UInt8 { 18 | case device = 1 19 | case configuration = 2 20 | case string = 3 21 | case interface = 4 22 | case endpoint = 5 23 | case deviceQualifier = 6 24 | case otherSpeedConfiguration = 7 25 | case interfacePower = 8 26 | } 27 | 28 | enum DeviceRequestRequestTypeDirection: UInt8 { 29 | case toDevice = 0 30 | case toHost = 1 31 | } 32 | 33 | enum DeviceRequestRequestTypeType: UInt8 { 34 | case standard = 0 35 | case `class` = 1 36 | case vendor = 2 37 | } 38 | 39 | enum DeviceRequestRequestTypeRecipient: UInt8 { 40 | case device = 0 41 | case interface = 1 42 | case endpoint = 2 43 | case other = 3 44 | } 45 | 46 | enum DeviceRequestRequestType { 47 | case requestType(DeviceRequestRequestTypeDirection, DeviceRequestRequestTypeType, DeviceRequestRequestTypeRecipient) 48 | var rawValue: UInt8 { 49 | get { 50 | switch self { 51 | case let .requestType(d7, d6_5, d4_0): 52 | return d7.rawValue << 7 | d6_5.rawValue << 5 | d4_0.rawValue 53 | } 54 | } 55 | } 56 | } 57 | 58 | enum DeviceRequestParticularRequest: UInt8 { 59 | case getDescriptor = 6 60 | } 61 | 62 | 63 | public class BBBUSBDevice: CustomStringConvertible { 64 | let service: io_service_t 65 | let device: USBDeviceInterface 66 | public let name: String 67 | public let path: String 68 | 69 | public var descriptor: BBBUSBDeviceDescriptor 70 | public var configurationDescriptor: BBBUSBConfigurationDescriptor 71 | 72 | init?(service: io_service_t) { 73 | self.service = service 74 | name = { () -> String in 75 | let nameBytes = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) 76 | _ = IORegistryEntryGetName(service, nameBytes) 77 | defer { 78 | nameBytes.deallocate(capacity: MemoryLayout.size) 79 | } 80 | return String(cString: nameBytes) 81 | }() 82 | path = { () -> String in 83 | let pathBytes = UnsafeMutablePointer.allocate(capacity: MemoryLayout.size) 84 | _ = IORegistryEntryGetPath(service, kIOUSBPlane, pathBytes) 85 | defer { 86 | pathBytes.deallocate(capacity: MemoryLayout.size) 87 | } 88 | return String(cString: pathBytes) 89 | }() 90 | 91 | guard let device = USBDeviceInterface(service: service) else { 92 | IOObjectRelease(service) 93 | return nil // `deinit` is not called 94 | } 95 | self.device = device 96 | 97 | do { 98 | descriptor = try BBBUSBDevice.requestDeviceDescriptor(device: device) 99 | // FIXME: iterate by descriptor.bNumConfigurations 100 | configurationDescriptor = try BBBUSBDevice.requestConfigurationDescriptor(device: device) 101 | } 102 | catch { 103 | IOObjectRelease(service) 104 | return nil // `deinit` is not called 105 | } 106 | } 107 | 108 | private class func requestDeviceDescriptor(device: USBDeviceInterface) throws -> BBBUSBDeviceDescriptor { 109 | return try withBridgingIOReturnError { 110 | var rawDevDesc = IOUSBDeviceDescriptor() 111 | var request = IOUSBDevRequest() 112 | request.bmRequestType = DeviceRequestRequestType.requestType(.toHost, .standard, .device).rawValue 113 | request.bRequest = DeviceRequestParticularRequest.getDescriptor.rawValue 114 | request.wValue = UInt16(USBDescriptorType.device.rawValue) << 8 115 | request.wIndex = 0 116 | request.wLength = 18 117 | request.pData = UnsafeMutableRawPointer(&rawDevDesc) 118 | try device.deviceRequest(&request) 119 | 120 | var devDesc = BBBUSBDeviceDescriptor() 121 | devDesc.bLength = rawDevDesc.bLength 122 | devDesc.bDescriptorType = rawDevDesc.bDescriptorType 123 | devDesc.bcdUSB = rawDevDesc.bcdUSB 124 | devDesc.bDeviceClass = rawDevDesc.bDeviceClass 125 | devDesc.bDeviceSubClass = rawDevDesc.bDeviceSubClass 126 | devDesc.bDeviceProtocol = rawDevDesc.bDeviceProtocol 127 | devDesc.bMaxPacketSize0 = rawDevDesc.bMaxPacketSize0 128 | devDesc.idVendor = rawDevDesc.idVendor 129 | devDesc.idProduct = rawDevDesc.idProduct 130 | devDesc.bcdDevice = rawDevDesc.bcdDevice 131 | devDesc.iManufacturer = rawDevDesc.iManufacturer 132 | devDesc.iProduct = rawDevDesc.iProduct 133 | devDesc.iSerialNumber = rawDevDesc.iSerialNumber 134 | devDesc.bNumConfigurations = rawDevDesc.bNumConfigurations 135 | if devDesc.iManufacturer != 0 { 136 | devDesc.manufacturerString = try device.getStringDescriptor(at: devDesc.iManufacturer) 137 | } 138 | if devDesc.iProduct != 0 { 139 | devDesc.productString = try device.getStringDescriptor(at: devDesc.iProduct) 140 | } 141 | if devDesc.iSerialNumber != 0 { 142 | devDesc.serialNumberString = try device.getStringDescriptor(at: devDesc.iSerialNumber) 143 | } 144 | return devDesc 145 | } 146 | } 147 | 148 | private class func requestConfigurationDescriptor(device: USBDeviceInterface) throws -> BBBUSBConfigurationDescriptor { 149 | return try withBridgingIOReturnError { 150 | var rawConfigDesc = IOUSBConfigurationDescriptor() 151 | var request = IOUSBDevRequest() 152 | request.bmRequestType = DeviceRequestRequestType.requestType(.toHost, .standard, .device).rawValue 153 | request.bRequest = DeviceRequestParticularRequest.getDescriptor.rawValue 154 | request.wValue = UInt16(USBDescriptorType.configuration.rawValue) << 8 155 | request.wIndex = 0 156 | request.wLength = 9 157 | request.pData = UnsafeMutableRawPointer(&rawConfigDesc) 158 | try device.deviceRequest(&request) 159 | 160 | var configDesc = BBBUSBConfigurationDescriptor() 161 | configDesc.bLength = rawConfigDesc.bLength 162 | configDesc.bDescriptorType = rawConfigDesc.bDescriptorType 163 | configDesc.wTotalLength = rawConfigDesc.wTotalLength 164 | configDesc.bNumInterfaces = rawConfigDesc.bNumInterfaces 165 | configDesc.bConfigurationValue = rawConfigDesc.bConfigurationValue 166 | configDesc.iConfiguration = rawConfigDesc.iConfiguration 167 | configDesc.bmAttributes = rawConfigDesc.bmAttributes 168 | configDesc.bMaxPower = rawConfigDesc.MaxPower 169 | if configDesc.iConfiguration != 0 { 170 | configDesc.configurationString = try device.getStringDescriptor(at: configDesc.iConfiguration) 171 | } 172 | 173 | if configDesc.wTotalLength > 9 { 174 | var configDescBytes = [UInt8](repeating: 0, count: Int(configDesc.wTotalLength)) 175 | request.wLength = configDesc.wTotalLength 176 | request.pData = UnsafeMutableRawPointer(&configDescBytes[0]) 177 | try device.deviceRequest(&request) 178 | 179 | var ptr = withUnsafePointer(to: &configDescBytes[9]) { $0 } 180 | var available = Int(configDesc.wTotalLength) - 9 181 | 182 | // optional descriptor(s) 183 | while available >= 2 { 184 | if ptr[1] == USBDescriptorType.interface.rawValue { 185 | break // reach interfaceDescriptor 186 | } 187 | 188 | let bLength = Int(ptr[0]) 189 | guard available >= bLength else { 190 | throw BBBUSBDeviceError.illegalDescriptor 191 | } 192 | 193 | var bytes = [UInt8](repeating: 0, count: bLength) 194 | for i in 0..= 9 && ptr[0] == 9 && ptr[1] == USBDescriptorType.interface.rawValue else { 205 | throw BBBUSBDeviceError.illegalDescriptor 206 | } 207 | var ifDesc = BBBUSBInterfaceDescriptor() 208 | ifDesc.bLength = ptr[0] 209 | ifDesc.bDescriptorType = ptr[1] 210 | ifDesc.bInterfaceNumber = ptr[2] 211 | ifDesc.bAlternateSetting = ptr[3] 212 | ifDesc.bNumEndpoints = ptr[4] 213 | ifDesc.bInterfaceClass = ptr[5] 214 | ifDesc.bInterfaceSubClass = ptr[6] 215 | ifDesc.bInterfaceProtocol = ptr[7] 216 | ifDesc.iInterface = ptr[8] 217 | ptr = ptr.advanced(by: 9) 218 | available -= 9 219 | 220 | // optional descriptor(s) 221 | while available >= 2 { 222 | if ptr[1] == USBDescriptorType.endpoint.rawValue { 223 | break // reach endpointDescriptor 224 | } 225 | 226 | // classSpecificDescriptor 227 | let bLength = Int(ptr[0]) 228 | guard available >= bLength else { 229 | throw BBBUSBDeviceError.illegalDescriptor 230 | } 231 | 232 | var bytes = [UInt8](repeating: 0, count: bLength) 233 | for i in 0..= 7 && ptr[0] == 7 && ptr[1] == USBDescriptorType.endpoint.rawValue else { 243 | throw BBBUSBDeviceError.illegalDescriptor 244 | } 245 | var epDesc = BBBUSBEndpointDescriptor() 246 | epDesc.bLength = ptr[0] 247 | epDesc.bDescriptorType = ptr[1] 248 | epDesc.bEndpointAddress = ptr[2] 249 | epDesc.bmAttributes = ptr[3] 250 | epDesc.wMaxPacketSize = UInt16(ptr[4]) | UInt16(ptr[5]) << 8 251 | epDesc.bInterval = ptr[6] 252 | ptr = ptr.advanced(by: 7) 253 | available -= 7 254 | 255 | ifDesc.endpoints.append(epDesc) 256 | } 257 | 258 | configDesc.interfaces.append(ifDesc) 259 | } 260 | 261 | if available != 0 { 262 | throw BBBUSBDeviceError.illegalDescriptor 263 | } 264 | } 265 | 266 | return configDesc 267 | } 268 | } 269 | 270 | 271 | deinit { 272 | IOObjectRelease(service) 273 | } 274 | 275 | 276 | public func open() throws { 277 | let err = device.open() 278 | if err != kIOReturnSuccess { 279 | throw BBBUSBDeviceError.IOReturnError(err: Int(err)) 280 | } 281 | } 282 | 283 | public func close() throws { 284 | let err = device.close() 285 | if (err == kIOReturnNotOpen) { 286 | // Ignore 287 | } 288 | else if (err != kIOReturnSuccess) { 289 | throw BBBUSBDeviceError.IOReturnError(err: Int(err)) 290 | } 291 | } 292 | 293 | public func listInterfaces() throws -> [BBBUSBInterface] { 294 | var iterator = io_iterator_t() 295 | let err = device.getUSBInterfaceIterator(&iterator) 296 | if err != kIOReturnSuccess { 297 | throw BBBUSBDeviceError.IOReturnError(err: Int(err)) 298 | } 299 | defer { 300 | IOObjectRelease(iterator) 301 | } 302 | 303 | var interfaces: [BBBUSBInterface] = [] 304 | var interfaceCount = 0 305 | for service in IOServiceSequence(iterator) { 306 | let ifDesc = configurationDescriptor.interfaces[interfaceCount] // without range check 307 | if let interface = BBBUSBInterface(service: service, device: self, descriptor: ifDesc) { // move service 308 | interfaces.append(interface) 309 | } 310 | interfaceCount += 1 311 | } 312 | return interfaces 313 | } 314 | 315 | public var description: String { 316 | get { 317 | return String(format: "BBBUSBKit.BBBUSBDevice = { name=\"\(name)\", path=\"\(path)\", vendorID=0x%04x, productID=0x%04x }", descriptor.idVendor, descriptor.idProduct) 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/BBUSBKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // BBBUSBKit.h 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | @import Foundation; 10 | 11 | //! Project version number for BBBUSBKit. 12 | FOUNDATION_EXPORT double BBBUSBKitVersionNumber; 13 | 14 | //! Project version string for BBBUSBKit. 15 | FOUNDATION_EXPORT const unsigned char BBBUSBKitVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/USBDeviceInterface.h: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceInterface.h 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #import "BBBUSBKitCore.h" 12 | 13 | @interface USBDeviceInterface : NSObject 14 | 15 | @property (assign, nonatomic, readonly) IOUSBDeviceInterfaceLatest ** device; 16 | 17 | - (instancetype)initWithService:(io_service_t)service; 18 | - (instancetype)initWithDevice:(IOUSBDeviceInterfaceLatest **)device; 19 | 20 | - (IOUSBConfigurationDescriptor *)getConfigurationDescriptor:(NSError **)error; 21 | - (IOReturn)open; 22 | - (IOReturn)close; 23 | - (IOReturn)getUSBInterfaceIterator:(io_iterator_t *)iterator; 24 | 25 | /// Control transfer on default pipe (endpoint0) 26 | - (IOReturn)deviceRequestWithRequestType:(UInt8)bmRequestType request:(UInt8)bRequest value:(UInt16)wValue index:(UInt16)wIndex length:(UInt16)wLength data:(void *)pData __deprecated; 27 | 28 | /// Control transfer on default pipe (endpoint0) 29 | /// 30 | /// the `request.wLenData` will be updated of after requested 31 | - (BOOL)deviceRequest:(IOUSBDevRequest *)request error:(NSError **)error; 32 | - (NSString *)getStringDescriptorAtIndex:(UInt8)index error:(NSError **)error; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/USBDeviceInterface.m: -------------------------------------------------------------------------------- 1 | // 2 | // USBDeviceInterface.m 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | #import "USBDeviceInterface.h" 10 | 11 | @interface USBDeviceInterface () 12 | 13 | @property (assign, nonatomic, readwrite) IOUSBDeviceInterfaceLatest ** device; 14 | 15 | @end 16 | 17 | @implementation USBDeviceInterface 18 | 19 | - (instancetype)initWithService:(io_service_t)service { 20 | self = [super init]; 21 | if (self) { 22 | IOCFPlugInInterface ** plugInInterface; 23 | SInt32 score; 24 | 25 | // Use IOReturn instead kern_return_t 26 | IOReturn err; 27 | err = IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); 28 | if (err != kIOReturnSuccess) { 29 | return nil; // `dealloc` will be called 30 | } 31 | err = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceIDLatest), (LPVOID)&_device); 32 | if (err != kIOReturnSuccess) { 33 | // Ignore result 34 | IODestroyPlugInInterface(plugInInterface); 35 | return nil; // `dealloc` will be called 36 | } 37 | 38 | // Ignore result 39 | IODestroyPlugInInterface(plugInInterface); 40 | } 41 | return self; 42 | } 43 | 44 | - (instancetype)initWithDevice:(IOUSBDeviceInterfaceLatest **)device { 45 | self = [super init]; 46 | if (self) { 47 | _device = device; 48 | [self setup]; 49 | } 50 | return self; 51 | } 52 | 53 | - (void)dealloc { 54 | [self close]; 55 | IOReturn err = (*_device)->Release(_device); 56 | if (err != kIOReturnSuccess) { 57 | NSLog(@"Warning: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 58 | } 59 | } 60 | 61 | - (void)setup { 62 | // DEBUG: 63 | UInt32 locationID; 64 | (*_device)->GetLocationID(_device, &locationID); 65 | } 66 | 67 | - (IOUSBConfigurationDescriptor *)getConfigurationDescriptor:(NSError **)error { 68 | UInt8 configIndex = 0; 69 | IOUSBConfigurationDescriptorPtr configurationDescriptor; 70 | IOReturn err = (*_device)->GetConfigurationDescriptorPtr(_device, configIndex, &configurationDescriptor); 71 | if (err != kIOReturnSuccess) { 72 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 73 | *error = [NSError BBBUSBKitErrorWithIOReturnError: err]; 74 | return nil; 75 | } 76 | return configurationDescriptor; 77 | } 78 | 79 | - (IOReturn)open { 80 | IOReturn err = (*_device)->USBDeviceOpenSeize(_device); 81 | if (err != kIOReturnSuccess) { 82 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 83 | } 84 | return err; 85 | } 86 | 87 | - (IOReturn)close { 88 | IOReturn err = (*_device)->USBDeviceClose(_device); 89 | if (err == kIOReturnNotOpen) { 90 | // Ignore 91 | } 92 | else if (err != kIOReturnSuccess) { 93 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 94 | } 95 | return err; 96 | } 97 | 98 | - (IOReturn)getUSBInterfaceIterator:(io_iterator_t *)iterator { 99 | IOUSBFindInterfaceRequest request; 100 | request.bInterfaceClass = kIOUSBFindInterfaceDontCare; 101 | request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; 102 | request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; 103 | request.bAlternateSetting = kIOUSBFindInterfaceDontCare; 104 | IOReturn err = (*_device)->CreateInterfaceIterator(_device, &request, iterator); 105 | if (err != kIOReturnSuccess) { 106 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 107 | } 108 | return err; 109 | } 110 | 111 | /// MARK: - advanced 112 | 113 | - (IOReturn)deviceRequestWithRequestType:(UInt8)bmRequestType request:(UInt8)bRequest value:(UInt16)wValue index:(UInt16)wIndex length:(UInt16)wLength data:(void *)pData { 114 | return [self deviceRequest:(IOUSBDevRequest){ bmRequestType, bRequest, wValue, wIndex, wLength, pData }]; 115 | } 116 | 117 | - (IOReturn)deviceRequest:(IOUSBDevRequest)request { 118 | IOReturn err = (*_device)->DeviceRequest(_device, &request); 119 | if (err != kIOReturnSuccess) { 120 | return err; 121 | } 122 | // TODO: compare request.wLength and request.wLenDone 123 | return kIOReturnSuccess; 124 | } 125 | 126 | - (BOOL)deviceRequest:(IOUSBDevRequest *)request error:(NSError **)error { 127 | IOReturn err = (*_device)->DeviceRequest(_device, request); 128 | if (err != kIOReturnSuccess) { 129 | *error = [NSError BBBUSBKitErrorWithIOReturnError:err]; 130 | return false; 131 | } 132 | return true; 133 | } 134 | 135 | - (NSString *)getStringDescriptorAtIndex:(UInt8)index error:(NSError **)error { 136 | UInt8 temp[2]; 137 | IOUSBDevRequest request; 138 | request.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); 139 | request.bRequest = kUSBRqGetDescriptor; 140 | request.wValue = (kUSBStringDesc << 8) | index; 141 | request.wIndex = 0; 142 | request.wLength = 2; 143 | request.pData = &temp; 144 | if (![self deviceRequest:&request error:error]) { 145 | return false; 146 | } 147 | 148 | UInt8 string[temp[0]]; 149 | request.wLength = temp[0]; 150 | request.pData = &string; 151 | if (![self deviceRequest:&request error:error]) { 152 | return false; 153 | } 154 | 155 | return [[NSString alloc] initWithBytes:&string[2] length:string[0] - 2 encoding:NSUTF16LittleEndianStringEncoding]; 156 | } 157 | 158 | @end 159 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/USBInterfaceInterface.h: -------------------------------------------------------------------------------- 1 | // 2 | // USBInterfaceInterface.h 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/08. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #import "BBBUSBKitCore.h" 12 | #import "USBDeviceInterface.h" 13 | 14 | @interface USBInterfaceInterface : NSObject 15 | 16 | @property (assign, nonatomic, readonly) IOUSBInterfaceInterfaceLatest ** interface; 17 | 18 | - (instancetype)initWithService:(io_service_t)service; 19 | - (IOReturn)open; 20 | - (IOReturn)close; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /UsbDetective/BBUSBKit/USBInterfaceInterface.m: -------------------------------------------------------------------------------- 1 | // 2 | // USBInterfaceInterface.m 3 | // BBBUSBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/08. 6 | // 7 | // 8 | 9 | #import "USBInterfaceInterface.h" 10 | 11 | @interface USBInterfaceInterface () 12 | 13 | @property (assign, nonatomic, readwrite) IOUSBInterfaceInterfaceLatest ** interface; 14 | 15 | @end 16 | 17 | @implementation USBInterfaceInterface 18 | 19 | - (instancetype)initWithService:(io_service_t)service { 20 | self = [super init]; 21 | if (self) { 22 | IOCFPlugInInterface ** plugInInterface; 23 | SInt32 score; 24 | 25 | // Use IOReturn instead kern_return_t 26 | IOReturn err; 27 | err = IOCreatePlugInInterfaceForService(service, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugInInterface, &score); 28 | if (err != kIOReturnSuccess) { 29 | return nil; // `dealloc` will be called 30 | } 31 | err = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceIDLatest), (LPVOID)&_interface); 32 | if (err != kIOReturnSuccess) { 33 | // Ignore result 34 | IODestroyPlugInInterface(plugInInterface); 35 | return nil; // `dealloc` will be called 36 | } 37 | 38 | // Ignore result 39 | IODestroyPlugInInterface(plugInInterface); 40 | } 41 | return self; 42 | } 43 | 44 | - (void)dealloc { 45 | IOReturn err = (*_interface)->Release(_interface); 46 | if (err != kIOReturnSuccess) { 47 | NSLog(@"Warning: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 48 | } 49 | } 50 | 51 | - (IOReturn)open { 52 | IOReturn err = (*_interface)->USBInterfaceOpen(_interface); 53 | if (err != kIOReturnSuccess) { 54 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 55 | } 56 | return err; 57 | } 58 | 59 | - (IOReturn)close { 60 | IOReturn err = (*_interface)->USBInterfaceClose(_interface); 61 | if (err == kIOReturnNotOpen) { 62 | // Ignore 63 | } 64 | else if (err != kIOReturnSuccess) { 65 | NSLog(@"Error: 0x%08x at %s, line %d", err, __PRETTY_FUNCTION__, __LINE__); 66 | } 67 | return err; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /UsbDetective/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2019 DutchSec. All rights reserved. 27 | NSMainStoryboardFile 28 | Main 29 | LSUIElement 30 | 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /UsbDetective/NewDeviceViewController.swift: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | import Cocoa 19 | 20 | class NewDeviceViewController: NSViewController { 21 | @IBOutlet weak var Category: NSTextField! 22 | @IBOutlet weak var VendorIdentifier: NSTextField! 23 | @IBOutlet weak var ProductIdentifier: NSTextField! 24 | @IBOutlet weak var Serial: NSTextField! 25 | @IBOutlet weak var Name: NSTextField! 26 | @IBOutlet weak var Manufacturer: NSTextField! 27 | 28 | let hidTypes = [ 29 | 1: "Pointer", 30 | 2: "Mouse", 31 | 4: "Joystick", 32 | 5: "Game Pad", 33 | 6: "Keyboard", 34 | 7: "Keypad", 35 | 8: "Multi-axis Controller", 36 | ] 37 | 38 | let vendors = [ 39 | 0x05AC: "Apple, Inc.", 40 | ] 41 | 42 | let products = [ 43 | 0x030E: "MC380Z/A [Magic Trackpad]" 44 | ] 45 | 46 | override func viewDidLoad() { 47 | super.viewDidLoad() 48 | } 49 | 50 | override var representedObject: Any? { 51 | didSet { 52 | // Update the view, if already loaded. 53 | Name.stringValue = (representedObject as! USBDevice).Name 54 | 55 | let primaryUsageKey = (representedObject as! USBDevice).PrimaryUsage 56 | let usageKeyText = hidTypes[primaryUsageKey] ?? "Unknown Device (\(primaryUsageKey))" 57 | Category.stringValue = usageKeyText 58 | 59 | let vendorID = (representedObject as! USBDevice).VendorID 60 | VendorIdentifier.stringValue = "\(vendors[vendorID] ?? "Unknown") (\(String(format:"0x%04X", vendorID)))" 61 | 62 | let productID = (representedObject as! USBDevice).ProductID 63 | ProductIdentifier.stringValue = "\(products[productID] ?? "Unknown") (\(String(format:"0x%04X", productID)))" 64 | Serial.stringValue = "\((representedObject as! USBDevice).SerialNumber)" 65 | 66 | Manufacturer.stringValue = "\((representedObject as! USBDevice).Manufacturer)" 67 | 68 | self.view.window!.title = "USB Detective 🔍" 69 | } 70 | } 71 | 72 | @IBAction func whitelistButton(_ sender: Any) { 73 | let application = NSApplication.shared 74 | application.stopModal(withCode: NSApplication.ModalResponse(ModalResult.Whitelist.rawValue)) 75 | } 76 | 77 | @IBAction func dismiss(_ sender: Any) { 78 | let application = NSApplication.shared 79 | application.stopModal() 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /UsbDetective/NewDeviceWindowController.swift: -------------------------------------------------------------------------------- 1 | // Licensed to the Apache Software Foundation (ASF) under one 2 | // or more contributor license agreements. See the NOTICE file 3 | // distributed with this work for additional information 4 | // regarding copyright ownership. The ASF licenses this file 5 | // to you under the Apache License, Version 2.0 (the 6 | // "License"); you may not use this file except in compliance 7 | // with the License. You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, 12 | // software distributed under the License is distributed on an 13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | // KIND, either express or implied. See the License for the 15 | // specific language governing permissions and limitations 16 | // under the License. 17 | 18 | import Foundation 19 | import Cocoa 20 | 21 | enum ModalResult: Int { 22 | case Whitelist 23 | case Close 24 | } 25 | 26 | class NewDeviceWindowController: NSWindowController, NSWindowDelegate { 27 | @IBOutlet weak var TestWindow: NSWindow! 28 | 29 | override func windowDidLoad() { 30 | super.windowDidLoad() 31 | 32 | // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file. 33 | self.window?.center() 34 | self.window?.makeKeyAndOrderFront(nil) 35 | // NSApp.activateIgnoringOtherApps(true) 36 | } 37 | 38 | override var windowNibName: String! { 39 | return "NewDevice" 40 | } 41 | 42 | func runModal() -> ModalResult { 43 | let returnCode = NSApplication.shared.runModal(for: self.window!) 44 | if let result = ModalResult(rawValue: returnCode.rawValue) { 45 | return result 46 | }else { 47 | return ModalResult.Close 48 | } 49 | } 50 | 51 | /* 52 | @IBAction func dismiss(sender: NSButton) { 53 | let app = NSApplication.shared 54 | app.stopModal() 55 | } 56 | */ 57 | 58 | func windowWillClose(_ notification: Notification) { 59 | if (NSApplication.shared.modalWindow == self.window) { 60 | NSApplication.shared.stopModal() 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /UsbDetective/UsbDetective-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // USBKit-Bridging-Header.h 3 | // USBKit 4 | // 5 | // Created by OTAKE Takayoshi on 2016/11/06. 6 | // 7 | // 8 | 9 | #import "BBBUSBKitCore.h" 10 | 11 | #import "USBDeviceInterface.h" 12 | #import "USBInterfaceInterface.h" 13 | -------------------------------------------------------------------------------- /UsbDetective/UsbDetective.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | --------------------------------------------------------------------------------