Stephen Warren wrote:
> Phil Dibowitz wrote:
>> ...
>> So I plan to switch this. Everywhere a USB message is constructed I'll NOT
>> include the extra 0-byte and then I'll ADD a 0-byte in the Windows code.
>>
>> Does anyone have any objections to this or concerns?
> 
> Sounds like a great idea to me - I was a little confused by the extra
> bytes at first.

Wow, that got a bit messy in parts. Here's a patch. It works for me for all
actions, but I'd like a bit more testing before I commit it.

In particular, I need windows testing since I don't even know if my Windows
code here compiles (I don't have any of the APIs to even attempt).

This does the aforementioned conversion and also cleans up most of the style
issues with winhid.cpp.

-- 
Phil Dibowitz                             [EMAIL PROTECTED]
Open Source software and tech docs        Insanity Palace of Metallica
http://www.phildev.net/                   http://www.ipom.com/

"Never write it in C if you can do it in 'awk';
 Never do it in 'awk' if 'sed' can handle it;
 Never use 'sed' when 'tr' can do the job;
 Never invoke 'tr' when 'cat' is sufficient;
 Avoid using 'cat' whenever possible" -- Taylor's Laws of Programming

? libconcord/.deps
? libconcord/.libs
? libconcord/Makefile
? libconcord/Makefile.in
? libconcord/aclocal.m4
? libconcord/autom4te.cache
? libconcord/binaryfile.lo
? libconcord/bindings
? libconcord/concord.i.array
? libconcord/concord.i.global
? libconcord/config.guess
? libconcord/config.h
? libconcord/config.h.in
? libconcord/config.log
? libconcord/config.status
? libconcord/config.sub
? libconcord/configure
? libconcord/depcomp
? libconcord/install-sh
? libconcord/libconcord.la
? libconcord/libconcord.lo
? libconcord/libtool
? libconcord/libusbhid.lo
? libconcord/ltmain.sh
? libconcord/missing
? libconcord/pm_to_blib
? libconcord/remote.lo
? libconcord/remote_z.lo
? libconcord/stamp-h1
? libconcord/test.pl
? libconcord/usblan.lo
? libconcord/web.lo
Index: libconcord/libconcord.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libconcord.cpp,v
retrieving revision 1.23
diff -u -r1.23 libconcord.cpp
--- libconcord/libconcord.cpp	3 Apr 2008 07:01:46 -0000	1.23
+++ libconcord/libconcord.cpp	3 Apr 2008 09:43:19 -0000
@@ -945,12 +945,19 @@
 			return LC_ERROR;
 	} else {
 		data[0] = 0x02;
-		if ((err = rmt->WriteRam(0, 1, data)))
+		if ((err = rmt->WriteRam(0, 1, data))) {
+			debug("Failed to write 2 to RAM 0");
 			return LC_ERROR_WRITE;
-		if ((err = rmt->ReadRam(0, 1, data)))
+		}
+		if ((err = rmt->ReadRam(0, 1, data))) {
+			debug("Failed to from RAM 0");
 			return LC_ERROR_WRITE;
-		if (data[0] != 2)
+		}
+		if (data[0] != 2) {
+			printf("byte is %d\n",data[0]);
+			debug("Finalize byte didn't match");
 			return LC_ERROR_VERIFY;
+		}
 	}
 
 	return 0;
Index: libconcord/remote.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/remote.cpp,v
retrieving revision 1.29
diff -u -r1.29 remote.cpp
--- libconcord/remote.cpp	3 Apr 2008 07:01:46 -0000	1.29
+++ libconcord/remote.cpp	3 Apr 2008 09:43:19 -0000
@@ -68,7 +68,7 @@
 
 int CRemote::Reset(uint8_t kind)
 {
-	uint8_t reset_cmd[] = { 0, COMMAND_RESET, kind };
+	uint8_t reset_cmd[] = { COMMAND_RESET, kind };
 
 	return HID_WriteReport(reset_cmd);
 }
@@ -84,7 +84,7 @@
 	int err = 0;
 	uint32_t cb_count = 0;
 
-	const uint8_t qid[] = { 0x00, COMMAND_GET_VERSION };
+	const uint8_t qid[] = { COMMAND_GET_VERSION };
 
 	if ((err = HID_WriteReport(qid))) {
 		debug("Failed to write to remote");
@@ -100,31 +100,31 @@
 	/*
  	 * See specs/protocol.txt for format
  	 */
-	const unsigned int rx_len = rsp[1] & 0x0F;
+	const unsigned int rx_len = rsp[0] & 0x0F;
 
-	if ((rsp[1] & 0xF0) != RESPONSE_VERSION_DATA ||
+	if ((rsp[0] & 0xF0) != RESPONSE_VERSION_DATA ||
 	    (rx_len != 7 && rx_len != 5)) {
 		debug("Bogus ident response: %02X", rsp[1]);
 		return LC_ERROR_INVALID_DATA_FROM_REMOTE;
 	}
 
-	ri.fw_ver_major = rsp[2] >> 4;
-	ri.fw_ver_minor = rsp[2] & 0x0F;
-	ri.hw_ver_major = rsp[3] >> 4;
-	ri.hw_ver_minor = rsp[3] & 0x0F;
-	ri.flash_id = rsp[4];
-	ri.flash_mfg = rsp[5];
-	ri.architecture = rx_len < 6 ? 2 : rsp[6] >> 4;
-	ri.fw_type = rx_len < 6 ? 0 : rsp[6] & 0x0F;
-	ri.skin = rx_len < 6 ? 2 : rsp[7];
-	ri.protocol = rx_len < 7 ? 0 : rsp[8];
+	ri.fw_ver_major = rsp[1] >> 4;
+	ri.fw_ver_minor = rsp[1] & 0x0F;
+	ri.hw_ver_major = rsp[2] >> 4;
+	ri.hw_ver_minor = rsp[2] & 0x0F;
+	ri.flash_id = rsp[3];
+	ri.flash_mfg = rsp[4];
+	ri.architecture = rx_len < 6 ? 2 : rsp[5] >> 4;
+	ri.fw_type = rx_len < 6 ? 0 : rsp[5] & 0x0F;
+	ri.skin = rx_len < 6 ? 2 : rsp[6];
+	ri.protocol = rx_len < 7 ? 0 : rsp[7];
 
 	setup_ri_pointers(ri);
 
-	//printf("Reading Flash... ");
 	uint8_t rd[1024];
 	if ((err=ReadFlash(ri.arch->config_base, 1024, rd, ri.protocol,
 								false))) {
+		debug("Error reading first k of config data");
 		return LC_ERROR_READ;
 	}
 	if (cb) {
@@ -162,6 +162,7 @@
 			COMMAND_MISC_EEPROM, rsp)
 		// All newer models store it in Flash
 		: ReadFlash(FLASH_SERIAL_ADDR, 48, rsp, ri.protocol))) {
+		debug("Couldn't read serial\n");
 		return LC_ERROR_READ;
 	}
 
@@ -204,16 +205,15 @@
 
 	do {
 		static uint8_t cmd[8];
-		cmd[0] = 0;
-		cmd[1] = COMMAND_READ_FLASH | 0x05;
-		cmd[2] = (addr >> 16) & 0xFF;
-		cmd[3] = (addr >> 8) & 0xFF;
-		cmd[4] = addr & 0xFF;
+		cmd[0] = COMMAND_READ_FLASH | 0x05;
+		cmd[1] = (addr >> 16) & 0xFF;
+		cmd[2] = (addr >> 8) & 0xFF;
+		cmd[3] = addr & 0xFF;
 		unsigned int chunk_len = end-addr;
 		if (chunk_len > max_chunk_len) 
 			chunk_len = max_chunk_len;
-		cmd[5] = (chunk_len >> 8) & 0xFF;
-		cmd[6] = chunk_len & 0xFF;
+		cmd[4] = (chunk_len >> 8) & 0xFF;
+		cmd[5] = chunk_len & 0xFF;
 
 		if ((err = HID_WriteReport(cmd)))
 			break;
@@ -225,26 +225,27 @@
 			if ((err = HID_ReadReport(rsp)))
 				break;
 
-			const uint8_t r = rsp[1]&COMMAND_MASK;
+			const uint8_t r = rsp[0] & COMMAND_MASK;
 
 			if (r == RESPONSE_READ_FLASH_DATA) {
-				if (seq != rsp[2]) {
+				if (seq != rsp[1]) {
 					err = LC_ERROR;
 					debug("Invalid sequence %02X %02x",
-						seq, rsp[2]);
+						seq, rsp[1]);
 					break;
 				}
-				seq+=0x11;
+				seq += 0x11;
 				const unsigned int rxlen =
-					rxlenmap[rsp[1] & LENGTH_MASK];
+					rxlenmap[rsp[0] & LENGTH_MASK];
 				if (rxlen) {
 					if (verify) {
-						if (memcmp(pr, rsp+3, rxlen)) {
+						if (memcmp(pr, rsp+2, rxlen)) {
+							debug("Verify fail");
 							err = LC_ERROR_VERIFY;
 							break;
 						}
 					} else {
-						memcpy(pr, rsp+3, rxlen);
+						memcpy(pr, rsp+2, rxlen);
 					}
 					pr += rxlen;
 					addr += rxlen;
@@ -253,7 +254,7 @@
 			} else if (r == RESPONSE_DONE) {
 				break;
 			} else {
-				debug("Invalid response [%02X]", rsp[1]);
+				debug("Invalid response [%02X]", rsp[0]);
 				err = LC_ERROR;
 			}
 		} while (err == 0);
@@ -268,7 +269,7 @@
 
 int CRemote::InvalidateFlash(void)
 {
-	const uint8_t ivf[]={ 0x00, COMMAND_WRITE_MISC | 0x01, 
+	const uint8_t ivf[]={ COMMAND_WRITE_MISC | 0x01, 
 				COMMAND_MISC_INVALIDATE_FLASH };
 	int err;
 
@@ -279,8 +280,8 @@
 	if ((err = HID_ReadReport(rsp)))
 		return err;
 
-	if ((rsp[1] & COMMAND_MASK) != RESPONSE_DONE ||
-		(rsp[2] & COMMAND_MASK) != COMMAND_WRITE_MISC) {
+	if ((rsp[0] & COMMAND_MASK) != RESPONSE_DONE ||
+		(rsp[1] & COMMAND_MASK) != COMMAND_WRITE_MISC) {
 		return 1;
 	}
 
@@ -319,11 +320,10 @@
 
 	for (uint32_t i = 0; i < num_sectors; i++) {
 		static uint8_t erase_cmd[8];
-		erase_cmd[0] = 0;
-		erase_cmd[1] = COMMAND_ERASE_FLASH;
-		erase_cmd[2] = (sector_begin >> 16) & 0xFF;
-		erase_cmd[3] = (sector_begin >> 8) & 0xFF;
-		erase_cmd[4] = sector_begin & 0xFF;
+		erase_cmd[0] = COMMAND_ERASE_FLASH;
+		erase_cmd[1] = (sector_begin >> 16) & 0xFF;
+		erase_cmd[2] = (sector_begin >> 8) & 0xFF;
+		erase_cmd[3] = sector_begin & 0xFF;
 
 		if ((err = HID_WriteReport(erase_cmd)))
 			break;
@@ -383,16 +383,15 @@
 
 	do {
 		static uint8_t write_setup_cmd[8];
-		write_setup_cmd[0] = 0;
-		write_setup_cmd[1] = COMMAND_WRITE_FLASH | 0x05;
-		write_setup_cmd[2] = (addr >> 16) & 0xFF;
-		write_setup_cmd[3] = (addr >> 8) & 0xFF;
-		write_setup_cmd[4] = addr & 0xFF;
+		write_setup_cmd[0] = COMMAND_WRITE_FLASH | 0x05;
+		write_setup_cmd[1] = (addr >> 16) & 0xFF;
+		write_setup_cmd[2] = (addr >> 8) & 0xFF;
+		write_setup_cmd[3] = addr & 0xFF;
 		uint32_t chunk_len = end - addr;
 		if (chunk_len > max_chunk_len)
 			chunk_len = max_chunk_len;
-		write_setup_cmd[5] = (chunk_len >> 8) & 0xFF;
-		write_setup_cmd[6] = chunk_len & 0xFF;
+		write_setup_cmd[4] = (chunk_len >> 8) & 0xFF;
+		write_setup_cmd[5] = chunk_len & 0xFF;
 
 		if ((err = HID_WriteReport(write_setup_cmd)))
 			break;
@@ -406,9 +405,8 @@
 			}
 			unsigned int block_len = txlenmap[i];
 			uint8_t wd[68];
-			wd[0] = 0;
-			wd[1] = COMMAND_WRITE_FLASH_DATA | n;
-			memcpy(wd+2, pw, block_len);
+			wd[0] = COMMAND_WRITE_FLASH_DATA | n;
+			memcpy(wd+1, pw, block_len);
 			HID_WriteReport(wd);
 			pw += block_len;
 			addr += block_len;
@@ -416,7 +414,7 @@
 			chunk_len -= block_len;
 		}
 		
-		uint8_t end_cmd[3] = { 0, COMMAND_DONE, COMMAND_WRITE_FLASH };
+		uint8_t end_cmd[] = { COMMAND_DONE, COMMAND_WRITE_FLASH };
 		HID_WriteReport(end_cmd);
 
 		uint8_t rsp[68];
@@ -433,10 +431,10 @@
 
 int CRemote::ReadMiscByte(uint8_t addr, uint32_t len, uint8_t kind, uint8_t *rd)
 {
-	uint8_t rmb[] = { 0, COMMAND_READ_MISC | 0x02, kind, 0 };
+	uint8_t rmb[] = { COMMAND_READ_MISC | 0x02, kind, 0 };
 
 	while (len--) {
-		rmb[3] = addr++;
+		rmb[2] = addr++;
 
 		int err;
 		if ((err = HID_WriteReport(rmb)))
@@ -446,22 +444,22 @@
 		if ((err = HID_ReadReport(rsp)))
 			return err;
 
-		if (rsp[1] != (RESPONSE_READ_MISC_DATA | 0x02) ||
-			rsp[2] != kind)
+		if (rsp[0] != (RESPONSE_READ_MISC_DATA | 0x02) ||
+			rsp[1] != kind)
 			return 1;
 
-		*rd++ = rsp[3];
+		*rd++ = rsp[2];
 	}
 	return 0;
 }
 
 int CRemote::ReadMiscWord(uint16_t addr, uint32_t len, uint8_t kind, uint16_t *rd)
 {
-	uint8_t rmw[] = { 0, COMMAND_READ_MISC | 0x03, kind, 0, 0 };
+	uint8_t rmw[] = { COMMAND_READ_MISC | 0x03, kind, 0, 0 };
 
 	while (len--) {
-		rmw[3] = addr >> 8;
-		rmw[4] = addr & 0xFF;
+		rmw[2] = addr >> 8;
+		rmw[3] = addr & 0xFF;
 		++addr;
 
 		int err;
@@ -473,12 +471,12 @@
 			return err;
 
 		// WARNING: The 880 responds with C2 rather than C3
-		if ((rsp[1] & COMMAND_MASK) != RESPONSE_READ_MISC_DATA ||
-			rsp[2] != kind) {
+		if ((rsp[0] & COMMAND_MASK) != RESPONSE_READ_MISC_DATA ||
+			rsp[1] != kind) {
 			return 1;
 		}
 
-		*rd++ = (rsp[3] << 8) | rsp[4];
+		*rd++ = (rsp[2] << 8) | rsp[3];
 	}
 	return 0;
 }
@@ -486,13 +484,12 @@
 int CRemote::WriteMiscByte(uint8_t addr, uint32_t len, uint8_t kind, uint8_t *wr)
 {
 	uint8_t wmb[8];
-	wmb[0] = 0;
-	wmb[1] = COMMAND_WRITE_MISC | 0x03;
-	wmb[2] = kind;
+	wmb[0] = COMMAND_WRITE_MISC | 0x03;
+	wmb[1] = kind;
 
 	while (len--) {
-		wmb[3] = addr++;
-		wmb[4] = *wr++;
+		wmb[2] = addr++;
+		wmb[3] = *wr++;
 
 		int err;
 		if ((err = HID_WriteReport(wmb)))
@@ -501,8 +498,8 @@
 		uint8_t rsp[68];
 		if ((err = HID_ReadReport(rsp)))
 			return err;
-		if ((rsp[1] & COMMAND_MASK) != RESPONSE_DONE ||
-			rsp[2] != COMMAND_WRITE_MISC) {
+		if ((rsp[0] & COMMAND_MASK) != RESPONSE_DONE ||
+			rsp[1] != COMMAND_WRITE_MISC) {
 			return 1;
 		}
 	}
@@ -512,16 +509,15 @@
 int CRemote::WriteMiscWord(uint16_t addr, uint32_t len, uint8_t kind, uint16_t *wr)
 {
 	uint8_t wmw[8];
-	wmw[0] = 0;
-	wmw[1] = COMMAND_WRITE_MISC | 0x05;
-	wmw[2] = kind;
+	wmw[0] = COMMAND_WRITE_MISC | 0x05;
+	wmw[1] = kind;
 
 	while (len--) {
-		wmw[3] = addr >> 8;
-		wmw[4] = addr & 0xFF;
+		wmw[2] = addr >> 8;
+		wmw[3] = addr & 0xFF;
 		++addr;
-		wmw[5] = *wr >> 8;
-		wmw[6] = *wr & 0xFF;
+		wmw[4] = *wr >> 8;
+		wmw[5] = *wr & 0xFF;
 		++wr;
 
 		int err;
@@ -531,8 +527,8 @@
 		uint8_t rsp[68];
 		if ((err = HID_ReadReport(rsp)))
 			return err;
-		if ((rsp[1] & COMMAND_MASK) != RESPONSE_DONE ||
-			rsp[2] != COMMAND_WRITE_MISC) {
+		if ((rsp[0] & COMMAND_MASK) != RESPONSE_DONE ||
+			rsp[1] != COMMAND_WRITE_MISC) {
 			return 1;
 		}
 	}
@@ -605,7 +601,7 @@
 
 		// Send Recalc Clock command for 880 only (not 360/520/550)
 		if (ri.architecture == 8) {
-			static const uint8_t rcc[] = { 0,
+			static const uint8_t rcc[] = {
 				COMMAND_WRITE_MISC | 0x01,
 				COMMAND_MISC_CLOCK_RECALCULATE };
 			err = HID_WriteReport(rcc);
@@ -645,7 +641,7 @@
 	const unsigned int len = rsp[64];
 	if ((len & 1) == 0) {
 		for (unsigned int u = 2; u < len; u += 2) {
-			const unsigned int t = rsp[1+u] << 8 | rsp[2+u];
+			const unsigned int t = rsp[0+u] << 8 | rsp[1+u];
 			if (ir_word > 2) {
 				/*
 				 * For ODD words, t is the total time, we'll
@@ -728,7 +724,7 @@
 	int err = 0;
 	uint8_t rsp[68];
 
-	const static uint8_t start_ir_learn[] = { 0, COMMAND_START_IRCAP };
+	const static uint8_t start_ir_learn[] = { COMMAND_START_IRCAP };
 	if ((err = HID_WriteReport(start_ir_learn)))
 		return err;
 
@@ -752,9 +748,9 @@
 	while (err == 0 && t_off < 500000) {
 		if ((err = HID_ReadReport(rsp, ir_word ? 500 : 4000)))
 			break;
-		const uint8_t r = rsp[1] & COMMAND_MASK;
+		const uint8_t r = rsp[0] & COMMAND_MASK;
 		if (r == RESPONSE_IRCAP_DATA) {
-			if (!check_seq(rsp[2], seq)) {
+			if (!check_seq(rsp[1], seq)) {
 				err = 1;
 				break;
  			}
@@ -784,13 +780,13 @@
 	if (pulse_count < MAX_PULSE_COUNT)
 		pulses[pulse_count++] = t_off;
 
-	const static uint8_t stop_ir_learn[] = { 0x00, COMMAND_STOP_IRCAP };
+	const static uint8_t stop_ir_learn[] = { COMMAND_STOP_IRCAP };
 	HID_WriteReport(stop_ir_learn);
 
 	/* read returned RESPONSE_DONE, otherwise next command wil fail! */
 	err = HID_ReadReport(rsp);
 	if (err == 0) {
-		if ((rsp[1] & COMMAND_MASK) != RESPONSE_DONE) {
+		if ((rsp[0] & COMMAND_MASK) != RESPONSE_DONE) {
 			err = 1;
 		}
 	}
Index: libconcord/libusb/libusbhid.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/libusb/libusbhid.cpp,v
retrieving revision 1.15
diff -u -r1.15 libusbhid.cpp
--- libconcord/libusb/libusbhid.cpp	3 Apr 2008 07:01:46 -0000	1.15
+++ libconcord/libusb/libusbhid.cpp	3 Apr 2008 09:43:19 -0000
@@ -207,7 +207,7 @@
 	 * every command, so we data+1 here to skip that.
 	 */
 	const int err=usb_interrupt_write(h_hid, ep_write,
-		reinterpret_cast<char *>(const_cast<uint8_t*>(data+1)),
+		reinterpret_cast<char *>(const_cast<uint8_t*>(data)),
 		orl, 500);
 
 	if (err < 0) {
@@ -222,7 +222,7 @@
 int HID_ReadReport(uint8_t *data, unsigned int timeout)
 {
 	const int err=usb_interrupt_read(h_hid, ep_read,
-		reinterpret_cast<char *>(data+1), irl, timeout);
+		reinterpret_cast<char *>(data), irl, timeout);
 
 	if (err < 0) {
 		debug("Failed to read from device: %d (%s)", err,
Index: libconcord/win/winhid.cpp
===================================================================
RCS file: /cvsroot/concordance/concordance/libconcord/win/winhid.cpp,v
retrieving revision 1.8
diff -u -r1.8 winhid.cpp
--- libconcord/win/winhid.cpp	3 Apr 2008 07:01:46 -0000	1.8
+++ libconcord/win/winhid.cpp	3 Apr 2008 09:43:19 -0000
@@ -43,71 +43,95 @@
 {
 	debug("Using Windows HID stack");
 
-	ol.Offset=ol.OffsetHigh=0;
-	ol.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
+	ol.Offset = ol.OffsetHigh = 0;
+	ol.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
 
 	return LinkUSB();
 }
 
 void ShutdownUSB()
 {
-	if(h_hid) {
+	if (h_hid) {
 		CloseHandle(h_hid);
-		h_hid=NULL;
+		h_hid = NULL;
 	}
 
 	UnlinkUSB();
 
 	CloseHandle(ol.hEvent);
-	ol.hEvent=NULL;
+	ol.hEvent = NULL;
 }
 
 int FindRemote(THIDINFO &hid_info)
 {
-	if(h_hid) { CloseHandle(h_hid); h_hid=NULL; }
+	if (h_hid) {
+		CloseHandle(h_hid);
+		h_hid=NULL;
+	}
 
 	GUID guid;
 	HidD_GetHidGuid(&guid);
 
 	const HDEVINFO HardwareDeviceInfo = rtlSetupDiGetClassDevs (
 		&guid,
-		NULL,						// Define no enumerator (global)
-		NULL,						// Define no parent window
-		(DIGCF_PRESENT |			// Only Devices present
-		DIGCF_DEVICEINTERFACE));	// Function class devices.
+		// Define no enumerator (global)
+		NULL,
+		// Define no parent window
+		NULL,
+		// Only Devices present
+		(DIGCF_PRESENT |
+		// Function class devices.
+		DIGCF_DEVICEINTERFACE));
 
 	/*
-		SetupDiEnumDeviceInterfaces() returns information about device interfaces
-		exposed by one or more devices. Each call returns information about one interface;
-		the routine can be called repeatedly to get information about several interfaces
-		exposed by one or more devices.
-	*/
-	if(HardwareDeviceInfo!=INVALID_HANDLE_VALUE) {
+	 * SetupDiEnumDeviceInterfaces() returns information about device
+	 * interfaces exposed by one or more devices. Each call returns
+	 * information about one interface; the routine can be called repeatedly
+	 * to get information about several interfaces exposed by one or more
+	 * devices.
+	 */
+	if (HardwareDeviceInfo != INVALID_HANDLE_VALUE) {
 		SP_DEVICE_INTERFACE_DATA DeviceInfoData;
 		DeviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
-		int i=0;
-		while(rtlSetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, &guid, i, &DeviceInfoData)) {
+		int i = 0;
+		while (rtlSetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0,
+						&guid, i, &DeviceInfoData)) {
 
-			TRACE1("\n\nInterface # %i\n",i);
+			TRACE1("\n\nInterface # %i\n", i);
 
 			ULONG device_data_length = 0;
 			rtlSetupDiGetDeviceInterfaceDetail(
 				HardwareDeviceInfo,
 				&DeviceInfoData,
-				NULL,	// probing so no output buffer yet
-				0,		// probing so output buffer length of zero
+				// probing so no output buffer yet
+				NULL,
+				// probing so output buffer length of zero
+				0,
 				&device_data_length,
-				NULL); // not interested in the specific dev-node
-
-			PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData=
-				(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(device_data_length);
-			if(functionClassDeviceData==NULL) return FALSE;
-			functionClassDeviceData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);	// This is correct - strange but true
-
-			ULONG required_length=0;
+				// not interested in the specific dev-node
+				NULL);
 
-			if(!rtlSetupDiGetDeviceInterfaceDetail(HardwareDeviceInfo, &DeviceInfoData, functionClassDeviceData,
-				device_data_length, &required_length, NULL) || (device_data_length < required_length)) {
+			PSP_DEVICE_INTERFACE_DETAIL_DATA
+				functionClassDeviceData =
+				(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(
+							device_data_length);
+
+			if (functionClassDeviceData == NULL)
+				return FALSE;
+
+			// This is correct - strange but true
+			functionClassDeviceData->cbSize =
+				sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+			ULONG required_length = 0;
+
+			if (!rtlSetupDiGetDeviceInterfaceDetail(
+					HardwareDeviceInfo, &DeviceInfoData,
+					functionClassDeviceData,
+					device_data_length, &required_length,
+					NULL) ||
+					(device_data_length < required_length)) 
+									{
 
 				TRACE0("Call to SetupDiGetDeviceInterfaceDetail failed!\n");
 
@@ -116,7 +140,8 @@
 				return -1;
 			}
 
-			TRACE1("Attempting to open %s\n", functionClassDeviceData->DevicePath);
+			TRACE1("Attempting to open %s\n",
+				functionClassDeviceData->DevicePath);
 
 			const HANDLE h = CreateFile(
 				functionClassDeviceData->DevicePath,
@@ -127,29 +152,38 @@
 				0,
 				NULL);
 
-			if(h==INVALID_HANDLE_VALUE) {
-				TRACE1( "FAILED to open %s\n", functionClassDeviceData->DevicePath);
+			if (h == INVALID_HANDLE_VALUE) {
+				TRACE1("FAILED to open %s\n",
+					functionClassDeviceData->DevicePath);
 			} else {
 				HIDD_ATTRIBUTES attr;
 				HidD_GetAttributes(h,&attr);
-				TRACE1("            Vendor ID: %04X\n",attr.VendorID);
-				TRACE1("           Product ID: %04X\n",attr.ProductID);
-				TRACE1("       Version Number: %04X\n",attr.VersionNumber);
-
-				if((attr.VendorID==0x046D && attr.ProductID>=0xC110 && attr.ProductID<=0xC14F) ||
-						(attr.VendorID==0x0400 && attr.ProductID==0xC359)) {
+				TRACE1("            Vendor ID: %04X\n", attr.VendorID);
+				TRACE1("           Product ID: %04X\n", attr.ProductID);
+				TRACE1("       Version Number: %04X\n", attr.VersionNumber);
+
+				if ((attr.VendorID == 0x046D
+				     && attr.ProductID >= 0xC110
+				     && attr.ProductID<=0xC14F)
+				          || (attr.VendorID==0x0400
+					      && attr.ProductID==0xC359)) {
 					WCHAR s[127];
 					char ts[128];
 
-					HidD_GetManufacturerString(h, s, sizeof(s));
-					WideCharToMultiByte(CP_ACP,0,s,-1,ts,sizeof(ts),NULL,NULL);
-					TRACE1("  Manufacturer String: %s\n",ts);
-					hid_info.mfg=ts;
+					HidD_GetManufacturerString(h, s,
+						sizeof(s));
+					WideCharToMultiByte(CP_ACP, 0, s, -1,
+						ts, sizeof(ts), NULL, NULL);
+					TRACE1("  Manufacturer String: %s\n",
+						ts);
+					hid_info.mfg = ts;
 
 					HidD_GetProductString(h, s, sizeof(s));
-					WideCharToMultiByte(CP_ACP,0,s,-1,ts,sizeof(ts),NULL,NULL);
-					TRACE1("       Product String: %s\n",ts);
-					hid_info.prod=ts;
+					WideCharToMultiByte(CP_ACP, 0, s, -1,
+						ts, sizeof(ts), NULL, NULL);
+					TRACE1("       Product String: %s\n",
+						ts);
+					hid_info.prod = ts;
 
 #if 0
 					HidD_GetSerialNumberString(h, s, sizeof(s));
@@ -164,33 +198,46 @@
 #endif
 
 					PHIDP_PREPARSED_DATA ppd;
-					HidD_GetPreparsedData(h,&ppd);
-					UINT u=HidP_GetCaps(ppd,&caps);
+					HidD_GetPreparsedData(h, &ppd);
+					UINT u=HidP_GetCaps(ppd, &caps);
 					HidD_FreePreparsedData(ppd);
 
-					TRACE1("  Input Report Length: %i\n",caps.InputReportByteLength);
-					TRACE1(" Output Report Length: %i\n",caps.OutputReportByteLength);
-					TRACE1("Feature Report Length: %i\n",caps.FeatureReportByteLength);
-					TRACE1("  LinkCollectionNodes: %i\n",caps.NumberLinkCollectionNodes);
-					TRACE1("      InputButtonCaps: %i\n",caps.NumberInputButtonCaps);
-					TRACE1("       InputValueCaps: %i\n",caps.NumberInputValueCaps);
-					TRACE1("     InputDataIndices: %i\n",caps.NumberInputDataIndices);
-					TRACE1("     OutputButtonCaps: %i\n",caps.NumberOutputButtonCaps);
-					TRACE1("      OutputValueCaps: %i\n",caps.NumberOutputValueCaps);
-					TRACE1("    OutputDataIndices: %i\n",caps.NumberOutputDataIndices);
-					TRACE1("    FeatureButtonCaps: %i\n",caps.NumberFeatureButtonCaps);
-					TRACE1("     FeatureValueCaps: %i\n",caps.NumberFeatureValueCaps);
-					TRACE1("   FeatureDataIndices: %i\n",caps.NumberFeatureDataIndices);
+					TRACE1("  Input Report Length: %i\n",
+						caps.InputReportByteLength);
+					TRACE1(" Output Report Length: %i\n",
+						caps.OutputReportByteLength);
+					TRACE1("Feature Report Length: %i\n",
+						caps.FeatureReportByteLength);
+					TRACE1("  LinkCollectionNodes: %i\n",
+						caps.NumberLinkCollectionNodes);
+					TRACE1("      InputButtonCaps: %i\n",
+						caps.NumberInputButtonCaps);
+					TRACE1("       InputValueCaps: %i\n",
+						caps.NumberInputValueCaps);
+					TRACE1("     InputDataIndices: %i\n",
+						caps.NumberInputDataIndices);
+					TRACE1("     OutputButtonCaps: %i\n",
+						caps.NumberOutputButtonCaps);
+					TRACE1("      OutputValueCaps: %i\n",
+						caps.NumberOutputValueCaps);
+					TRACE1("    OutputDataIndices: %i\n",
+						caps.NumberOutputDataIndices);
+					TRACE1("    FeatureButtonCaps: %i\n",
+						caps.NumberFeatureButtonCaps);
+					TRACE1("     FeatureValueCaps: %i\n",
+						caps.NumberFeatureValueCaps);
+					TRACE1("   FeatureDataIndices: %i\n",
+						caps.NumberFeatureDataIndices);
 
 					CloseHandle(h);
 
-					hid_info.vid=attr.VendorID;
-					hid_info.pid=attr.ProductID;
-					hid_info.ver=attr.VersionNumber;
-
-					hid_info.irl=caps.InputReportByteLength;
-					hid_info.orl=caps.OutputReportByteLength;
-					hid_info.frl=caps.FeatureReportByteLength;
+					hid_info.vid = attr.VendorID;
+					hid_info.pid = attr.ProductID;
+					hid_info.ver = attr.VersionNumber;
+
+					hid_info.irl = caps.InputReportByteLength;
+					hid_info.orl = caps.OutputReportByteLength;
+					hid_info.frl = caps.FeatureReportByteLength;
 
 					h_hid = CreateFile(
 						functionClassDeviceData->DevicePath,
@@ -203,7 +250,8 @@
 
 					free(functionClassDeviceData);
 
-					return (h_hid==INVALID_HANDLE_VALUE)?-2:0;
+					return (h_hid == INVALID_HANDLE_VALUE)
+						? -2 : 0;
 				}
 
 				CloseHandle(h);
@@ -215,7 +263,7 @@
 			++i;
 		}
 
-		TRACE1("Interface enum ended with error %u\n",GetLastError());
+		TRACE1("Interface enum ended with error %u\n", GetLastError());
 
 		// SetupDiDestroyDeviceInfoList() destroys a device information set and frees all associated memory.
 		rtlSetupDiDestroyDeviceInfoList(HardwareDeviceInfo);
@@ -229,7 +277,12 @@
 int HID_WriteReport(const uint8_t *data)
 {
 	DWORD err,dw;
-	if (!WriteFile(h_hid,data,caps.OutputReportByteLength,&dw,&ol)) {
+	uint8_t windata[caps.OutputReportByteLength];
+
+	// Add an initial 0-byte for the Windows USB stack
+	windata[0] = 0;
+	memcpy(windata + 1, data, caps.OutputReportByteLength - 1);
+	if (!WriteFile(h_hid, windata, caps.OutputReportByteLength, &dw, &ol)) {
 		err = GetLastError();
 		if (err != ERROR_IO_PENDING) {
 			debug("WriteFile() failed with error %i", err);
@@ -237,17 +290,17 @@
 		}
 	}
 
-	const DWORD ws=WaitForSingleObject(ol.hEvent,500);
+	const DWORD ws = WaitForSingleObject(ol.hEvent, 500);
 
-	if (ws==WAIT_TIMEOUT) {
+	if (ws == WAIT_TIMEOUT) {
 		debug("Write failed to complete within alloted time");
 		CancelIo(h_hid);
-		err=1;
-	} else if(ws!=WAIT_OBJECT_0) {
+		err = 1;
+	} else if(ws != WAIT_OBJECT_0) {
 		debug("Wait failed with code %i", ws);
-		err=2;
+		err = 2;
 	} else {
-		err=0;
+		err = 0;
 	}
 
 	return err;
@@ -255,8 +308,9 @@
 
 int HID_ReadReport(uint8_t *data, unsigned int timeout)
 {
+	uint8_t *tmp;
 	DWORD err,dw;
-	if(!ReadFile(h_hid,data,caps.InputReportByteLength,&dw,&ol)) {
+	if(!ReadFile(h_hid,tmp, caps.InputReportByteLength,&dw,&ol)) {
 		err=GetLastError();
 		if(err!=ERROR_IO_PENDING) {
 			debug("ReadFile() failed with error %i", err);
@@ -266,15 +320,18 @@
 
 	const DWORD ws=WaitForSingleObject(ol.hEvent,timeout);
 
-	if(ws==WAIT_TIMEOUT) {
+	// Remove the initial 0-byte the Windows USB stack adds
+	data = tmp + 1;
+
+	if (ws == WAIT_TIMEOUT) {
 		debug("No response from remote");
 		CancelIo(h_hid);
-		err=1;
-	} else if(ws!=WAIT_OBJECT_0) {
+		err = 1;
+	} else if (ws != WAIT_OBJECT_0) {
 		debug("Wait failed with code %i", ws);
-		err=2;
+		err = 2;
 	} else {
-		err=0;
+		err = 0;
 	}
 	return err;
 }

Attachment: signature.asc
Description: OpenPGP digital signature

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to