2012-12-11 114 views
1

我參與開發Mac OS自定義HID設備支持。 但它不是HID投訴,即被IOUSBCompositeDriver抓住。Mac OS X:自定義HID驅動程序

該設備應該用作輸入設備(鍵盤,鼠標),因此我試圖實現驅動程序爲kext。我試着子類IOUSBHIDDriver和IOHIDDevice從newReportDescriptor返回以下報告描述符(從Windows團隊採取的)()方法:

#define KBD_KEY_CODES  6 

#pragma pack(1) 
typedef struct _VHID_KEYBOARD_REPORT 
{ 
    UInt8  ReportID; 
    // Left Control, Left Shift, Left Alt, Left GUI 
    // Right Control, Right Shift, Right Alt, Right GUI 
    UInt8  ShiftKeyFlags; 
    UInt8  Reserved; 
    UInt8  KeyCodes[KBD_KEY_CODES]; 
} VHID_KEYBOARD_REPORT; 

VHID_KEYBOARD_REPORT keyboardReport; 

bzero(&keyboardReport, sizeof(keyboardReport)); 
keyboardReport.ReportID = REPORTID_KEYBOARD; 
keyboardReport.ShiftKeyFlags = 0; 
keyboardReport.KeyCodes[0] = kHIDUsage_KeyboardA; 

IOBufferMemoryDescriptor *report = IOBufferMemoryDescriptor::withBytes(&keyboardReport, sizeof(keyboardReport), kIODirectionInOut); 

handleReport(report); 

const unsigned char g_ReportDescriptor[] = { 
// Keyboard report 
0x05, 0x01,       // USAGE_PAGE (Generic Desktop) 
0x09, 0x06,       // USAGE (Keyboard) 
0xa1, 0x01,       // COLLECTION (Application) 
0x85, REPORTID_KEYBOARD,   // REPORT_ID (Keyboard)  
0x05, 0x07,       // USAGE_PAGE (Keyboard) 
0x19, 0xe0,       // USAGE_MINIMUM (Keyboard LeftControl) 
0x29, 0xe7,       // USAGE_MAXIMUM (Keyboard Right GUI) 
0x15, 0x00,       // LOGICAL_MINIMUM (0) 
0x25, 0x01,       // LOGICAL_MAXIMUM (1) 
0x75, 0x01,       // REPORT_SIZE (1) 
0x95, 0x08,       // REPORT_COUNT (8) 
0x81, 0x02,       // INPUT (Data,Var,Abs) 
0x95, 0x01,       // REPORT_COUNT (1) 
0x75, 0x08,       // REPORT_SIZE (8) 
0x81, 0x03,       // INPUT (Cnst,Var,Abs) 
0x95, 0x05,       // REPORT_COUNT (5) 
0x75, 0x01,       // REPORT_SIZE (1) 
0x05, 0x08,       // USAGE_PAGE (LEDs) 
0x19, 0x01,       // USAGE_MINIMUM (Num Lock) 
0x29, 0x05,       // USAGE_MAXIMUM (Kana) 
0x91, 0x02,       // OUTPUT (Data,Var,Abs) 
0x95, 0x01,       // REPORT_COUNT (1) 
0x75, 0x03,       // REPORT_SIZE (3) 
0x91, 0x03,       // OUTPUT (Cnst,Var,Abs) 
0x95, 0x06,       // REPORT_COUNT (6) 
0x75, 0x08,       // REPORT_SIZE (8) 
0x15, 0x00,       // LOGICAL_MINIMUM (0) 
0x25, 0x65,       // LOGICAL_MAXIMUM (101) 
0x05, 0x07,       // USAGE_PAGE (Keyboard) 
0x19, 0x00,       // USAGE_MINIMUM (Reserved (no event indicated)) 
0x29, 0x65,       // USAGE_MAXIMUM (Keyboard Application) 
0x81, 0x00,       // INPUT (Data,Ary,Abs) 
0xc0,        // END_COLLECTION 

// Relative Mouse report 
0x05, 0x01,       // USAGE_PAGE (Generic Desktop) 
0x09, 0x02,       // USAGE (Mouse) 
0xa1, 0x01,       // COLLECTION (Application) 
0x85, REPORTID_RELATIVE_MOUSE,  // REPORT_ID (Mouse) 
0x09, 0x01,       // USAGE (Pointer) 
0xa1, 0x00,       // COLLECTION (Physical) 
0x05, 0x09,       //  USAGE_PAGE (Button) 
0x19, 0x01,       //  USAGE_MINIMUM (Button 1) 
0x29, 0x05,       //  USAGE_MAXIMUM (Button 5) 
0x15, 0x00,       //  LOGICAL_MINIMUM (0) 
0x25, 0x01,       //  LOGICAL_MAXIMUM (1) 
0x75, 0x01,       //  REPORT_SIZE (1) 
0x95, 0x05,       //  REPORT_COUNT (5) 
0x81, 0x02,       //  INPUT (Data,Var,Abs) 
0x95, 0x03,       //  REPORT_COUNT (3) 
0x81, 0x03,       //  INPUT (Cnst,Var,Abs) 
0x05, 0x01,       //  USAGE_PAGE (Generic Desktop) 
0x09, 0x30,       //  USAGE (X) 
0x09, 0x31,       //  USAGE (Y) 
0x15, 0x81,       //  Logical Minimum (-127) 
0x25, 0x7F,       //  Logical Maximum (127) 
0x75, 0x08,       //  REPORT_SIZE (8) 
0x95, 0x02,       //  REPORT_COUNT (2) 
0x81, 0x06,       //  INPUT (Data,Var,Rel) 
0x05, 0x01,       //  Usage Page (Generic Desktop) 
0x09, 0x38,       //  Usage (Wheel) 
0x15, 0x81,       //  Logical Minimum (-127) 
0x25, 0x7F,       //  Logical Maximum (127) 
0x75, 0x08,       //  Report Size (8) 
0x95, 0x01,       //  Report Count (1) 
0x81, 0x06,       //  Input (Data, Variable, Relative) 
0xc0,        // END_COLLECTION 
0xc0,        // END_COLLECTION 


// Control report 
0x06, 0x00, 0xff,    // USAGE_PAGE (Vendor Defined Page 1) 
0x09, 0x01,     // USAGE (Vendor Usage 1) 
0xa1, 0x01,     // COLLECTION (Application) 
0x85, REPORTID_VXYCONTROL,  // REPORT_ID() 
0x15, 0x00,     // LOGICAL_MINIMUM (0) 
0x26, 0xff, 0x7f,    // LOGICAL_MAXIMUM (32767) 
0x75, 0x10,     // REPORT_SIZE (16) 
0x95, 0x02,     // REPORT_COUNT (2) 
0x09, 0x01,     // USAGE (Vendor Usage 1) 
0x91, 0x00,     // OUTPUT (Data,Ary,Abs) 
0xc0,       // END_COLLECTION 

// Trigger Macro report 
0x06, 0x00, 0xff,    // USAGE_PAGE (Vendor Defined Page 1) 
0x09, 0x02,     // USAGE (Vendor Usage 2) 
0xa1, 0x01,     // COLLECTION (Application) 
0x85, REPORTID_MACROTRIG,  // REPORT_ID (5) 
0x15, 0x00,     // LOGICAL_MINIMUM (0) 
0x26, 0xff, 0x00,    // LOGICAL_MAXIMUM (255) 
0x75, 0x08,     // REPORT_SIZE (8) 
0x95, 0x01,     // REPORT_COUNT (1) 
0x09, 0x02,     // USAGE (Vendor Usage 2) 
0x81, 0x02,     // INPUT (Data,Var,Abs) 
0xc0       // END_COLLECTION 

}; 

,然後喂以下結構handleReport()方法,但是我沒有看到任何影響。我預計會產生按鍵事件。

我錯過了什麼?這種驅動程序的一般工作流程是什麼?

回答

0

這裏有很多事情要做錯了...從你的info.plist的IOKitPersonalities ...和OSBundleLibraries開始(你的所有版本都匹配?)你知道你的kext匹配嗎? (你可以kextload/kextstat你的驅動程序?)假設這很好,你如何替換報告描述符?假設你正確地覆蓋:: newReportDescriptor(你是否調用super :: newReportDescriptor?),你如何返回你的新描述符?

IOBufferMemoryDescriptor* memDesc = IOBufferMemoryDescriptor::withBytes(& g_ReportDescriptor, sizeof(g_ReportDescriptor), kIODirectionOutIn, false); 

它可能有助於撒上一些IOLog通過您的代碼,以確保一切都如您所願地發生。

+0

是的!我的kext與OS匹配並加載。 我使用以下代碼重寫newReportDescriptor: '{ IOLog(「New Report Descriptor \ n」); * descriptor = IOBufferMemoryDe​​scriptor :: withBytes(&g_ReportDescriptor,sizeof(g_ReportDescriptor),kIODirectionInOut); return kIOReturnSuccess; } ' 此刻我只是試圖生成事件,因此我從start()方法調用handleReport()。我仍然期望這個事件會產生。 –

+0

我不認爲從start方法調用handleReport會起作用(因爲它沒有真正的報表來處理)。 – geowar

+0

我最好的建議是聯繫DTS @ apple.com(無空格)作爲'官方'答案。如果可能,發送您的項目。 – geowar