[REVIEW] Amazebreak

FranScorpions escribió:¿Es que no ha salido aún la actualización para el online en este aparato? creí haber leído unos hilos antes que sí estaba ya.

Si que ha salido, pero no funciona en consolas con 3.41, ponen que es para consolas con 3.15, aunque no conozco a ningun usuario con este firmware que pueda confirmarlo.
quecon escribió: en la pagina de este Mod el que ahi del dia 12 no valen para la el firm 3.41 igual ahi que actulizarla a la version 3.50 para que funcione no????

Ni se te ocurra actualizar a las 3.50... si lo haces adiós a los backups....

FranScorpions escribió:¿Es que no ha salido aún la actualización para el online en este aparato? creí haber leído unos hilos antes que sí estaba ya.


Solo funciona para los que tienen la versión 3.15 en la ps3, para la 3.41 todavia no hay nada

Un saludo
Aquiles81 escribió:
quecon escribió: en la pagina de este Mod el que ahi del dia 12 no valen para la el firm 3.41 igual ahi que actulizarla a la version 3.50 para que funcione no????

Ni se te ocurra actualizar a las 3.50... si lo haces adiós a los backups....

FranScorpions escribió:¿Es que no ha salido aún la actualización para el online en este aparato? creí haber leído unos hilos antes que sí estaba ya.


Solo funciona para los que tienen la versión 3.15 en la ps3, para la 3.41 todavia no hay nada

Un saludo


Joder, ¿y a qué esperan para sacarlo para ese firmware? si es el que más se usa de todos, no lo entiendo. Al final me veo comprándome otro cacharro para ese tema, porque me han dejado un PSGroopic y va de fábula, al menos lo de la Store, no he probado a jugar online.
Señores a 8 dolares en dealxtreme... y ellos le tienen k sacar beneficio, cuanto les costara? 4 dolares o 5 dolares como mucho, vamos, 3 eurillos...

he aqui uno de los negocios mas rentables del ultimo año...

De no tenerlo, lo pillaria xD

Saludos
Hola:


Me quiero pillar el dispositivo, pero lo que no comprendo en que versión debo de tner la consola con amazebreak. ¿3.15 o 3.41? Es que leo eso en las discursiones pero no lo saco claro.

Me pillaría el de $8 de Dealextreme pues no me importaría esperar pues estoy de examenes
Funciona con ambas, solo que el ultimo avance de la scene para poder entrar a la store de momento solo lo funciona si tienes 3.15, aunque de aqui a que te llegue de dealextreme seguro que ya esta apañado para la 3.41

saludos
Bueno, ya tengo el mio y tras un fin de semana de pruebas, todos los juegos que he probado van de maravilla.
He probado pasarlos del hd externo al interno y viceversa y todo correcto.
Sólo me lie un poco a la hora de actualizarlo y es que hay que tener el programa abierto y después enchufar el amaze. También se me olvidó darle al eject cuando lo puse, pero sólo la primera ves [+risas]

Recomendable 100% y más con ese precio.
Ya tengo pedido mi amazebreak,por lo que espero tenerlo en un par de dias , me gustaria que me dijerais que pasos son los que debo seguir una vez que lo tenga,ya que hablais de tanto programas y tantas cosas,que ya estoy hecho un lio, echadme una mano por favor !!
zar_69 escribió:Ya tengo pedido mi amazebreak,por lo que espero tenerlo en un par de dias , me gustaria que me dijerais que pasos son los que debo seguir una vez que lo tenga,ya que hablais de tanto programas y tantas cosas,que ya estoy hecho un lio, echadme una mano por favor !!


En estos dias empapate, lee y bueno en la primera pagina tienes como se actualiza y tal, no te asustes por mucho que leas que es mas simple que el mecanimo de un chupete.
yeyoX escribió:
zar_69 escribió:Ya tengo pedido mi amazebreak,por lo que espero tenerlo en un par de dias , me gustaria que me dijerais que pasos son los que debo seguir una vez que lo tenga,ya que hablais de tanto programas y tantas cosas,que ya estoy hecho un lio, echadme una mano por favor !!


En estos dias empapate, lee y bueno en la primera pagina tienes como se actualiza y tal, no te asustes por mucho que leas que es mas simple que el mecanimo de un chupete.


Vamos a ver,lo de como se actualiza y eso,por eso no hay problema,esta todo muy bien explicado en la primera pagina, pero lo que dudo es con respecto a cosas como las que veo de que si hermes y cosas asi, de ahi que os pida ayuda, ck estoy muy perdido.
En la misma pagina web de amazebreak salen las actualizaciones, te bajas la ultima que esté ahi y listo.
Sabeis si podrán sacar actualizaciones compatibles con la última versión?? Si no al final habrá que actualizar la ps3 y se acabó. Ya que los últimos juegos piden actualizaciones solo para jugar....
Estan tardando lo suyo en sacar la versión para poder conectarte al psn en la 3.41...
a lo mejor la van a unir en una sola, con la actualización para las versiones de firm 3.42 y 3.50 =D
los demas clones ya se pueden enchufar a PSN hace dias y este trasto todavia no sera mejor cambiar
a ps3Key o alguno de esos
frran1967 escribió:los demas clones ya se pueden enchufar a PSN hace dias y este trasto todavia no sera mejor cambiar
a ps3Key o alguno de esos


Pa eso pillate uno ke se le pueda meter cualkier hex xk kon el ps3key ese tb dependes de los firmwares del fabricante. Yo tengo el psjailbreak2 y va de lujo, tipo eclips3
imanol25 escribió:
frran1967 escribió:los demas clones ya se pueden enchufar a PSN hace dias y este trasto todavia no sera mejor cambiar
a ps3Key o alguno de esos


Pa eso pillate uno ke se le pueda meter cualkier hex xk kon el ps3key ese tb dependes de los firmwares del fabricante. Yo tengo el psjailbreak2 y va de lujo, tipo eclips3


donde lo compraste y cual es el precio??
que tal sera el X3MAX??
A ver si a lo largo de esta semana me lo traen , que cargador de backups usuaus? en la página española recomiendan usar el GAIA , pero de ver cosas por el foro casi todo el mundo usa el OPEN 2.1H, se puede tener instalados los 2 ? , osea yo meto mi cd de final 13 y tengo instaldo el GAIA hago la copia con él y luego "abro " el open y tb me lo reconoce? o tengo que hacer otra copia en el drectorio donde trabaje el OPEN?.

Igual es una chorrada del 15 pero , como unos usan uno y otros otros ... pos no sé :\
zar_69 escribió:
yeyoX escribió:
zar_69 escribió:Ya tengo pedido mi amazebreak,por lo que espero tenerlo en un par de dias , me gustaria que me dijerais que pasos son los que debo seguir una vez que lo tenga,ya que hablais de tanto programas y tantas cosas,que ya estoy hecho un lio, echadme una mano por favor !!


En estos dias empapate, lee y bueno en la primera pagina tienes como se actualiza y tal, no te asustes por mucho que leas que es mas simple que el mecanimo de un chupete.


Vamos a ver,lo de como se actualiza y eso,por eso no hay problema,esta todo muy bien explicado en la primera pagina, pero lo que dudo es con respecto a cosas como las que veo de que si hermes y cosas asi, de ahi que os pida ayuda, ck estoy muy perdido.


Me autocito para ver si me aclarais un poco,por que cuanto mas leo mas me lio, al ser tantas cosas.
zar_69 escribió:
yeyoX escribió:
zar_69 escribió:Ya tengo pedido mi amazebreak,por lo que espero tenerlo en un par de dias , me gustaria que me dijerais que pasos son los que debo seguir una vez que lo tenga,ya que hablais de tanto programas y tantas cosas,que ya estoy hecho un lio, echadme una mano por favor !!


En estos dias empapate, lee y bueno en la primera pagina tienes como se actualiza y tal, no te asustes por mucho que leas que es mas simple que el mecanimo de un chupete.


Vamos a ver,lo de como se actualiza y eso,por eso no hay problema,esta todo muy bien explicado en la primera pagina, pero lo que dudo es con respecto a cosas como las que veo de que si hermes y cosas asi, de ahi que os pida ayuda, ck estoy muy perdido.



Ok, el problema con este chip, es que no podemos usar las actualizaciones que salen así no mas ( como en otros chips), ya que el fabricante de este, empaqueta los archivos de un modo distinto.. entonces resumiendo.. tenemos que esperar hasta que se les de la gana de incluir las funciones nuevas... lo cual en este momento es una gran cagada...porque nadie con este chip y FW 3.41 puede entrar al PSN.
esto es de risa todos jugan online y avanzando y nosotros con el 3.41 nada de nada, algo pasa o esperan para hacerlo porque sino no es normal
pues sí.. empezaron muy bien pero se van quedando atrás. Ya sabéis, dadles la coña via email. Mientras tanto recomiendo no comprar ningún cacharro al que no se le peuda meter el código que queramos. Eso sí, olvidáos de garantías en los que dejen meter el código que quieras, si te lo cargas es cosa tuya.

Por otro lado, y para daros una pequeña esperanza, creo que tengo localizado el chip que usan, y en efecto no es ni Atmel, ni PIC, ni Silabs... estoy luchando con el traductor de chino, para conseguir el código fuente del software para actualziar. Cuando lo tenga ya veremos que se puede hacer, pero tengo UN sólo Amaze v2... si cae en combate, adios esperanzas.

quecon escribió:esto es de risa todos jugan online y avanzando y nosotros con el 3.41 nada de nada, algo pasa o esperan para hacerlo porque sino no es normal
c0d3m4st4 escribió:pues sí.. empezaron muy bien pero se van quedando atrás. Ya sabéis, dadles la coña via email. Mientras tanto recomiendo no comprar ningún cacharro al que no se le peuda meter el código que queramos. Eso sí, olvidáos de garantías en los que dejen meter el código que quieras, si te lo cargas es cosa tuya.

Por otro lado, y para daros una pequeña esperanza, creo que tengo localizado el chip que usan, y en efecto no es ni Atmel, ni PIC, ni Silabs... estoy luchando con el traductor de chino, para conseguir el código fuente del software para actualziar. Cuando lo tenga ya veremos que se puede hacer, pero tengo UN sólo Amaze v2... si cae en combate, adios esperanzas.

quecon escribió:esto es de risa todos jugan online y avanzando y nosotros con el 3.41 nada de nada, algo pasa o esperan para hacerlo porque sino no es normal


confio mas en ti que en los propios creadores del amaze , espero que tenga suerte y des con la tecla , en todo lo que te pueda ayudar hazmelo saber.

un saludo.
jeje.. gracias hombre :)

Pues ya os diré, de momento no puedo bajar los fuentes que busco, sólo están en webs chinas y son de pago :\ He barrido Google, Baidu, y Yahoo, y no hay cojones.

Os dejo aquí lo que busco, a ver si vostros tenéis suerte.

El fichero en cuestión se llama: HID_ReadWrite.rar (que no quiere decir que sirva tal cual, posiblemente no sirva para nada, pero lleva implementadas una por una todas las funciones que hay en el Amaze.dll y por eso quiero echarlo un ojo, y probar el código) y el chip que estoy casi seguro que lleva dentro es de Cypress Semiconductor aunque mirando un poco por su web, no localizo el modelo exacto. Los hay de 48 patas, pero en otro formato, quizá este del Amaze pueda ser algún modelo anterior ya descatalogado.


almeria27 escribió:
c0d3m4st4 escribió:pues sí.. empezaron muy bien pero se van quedando atrás. Ya sabéis, dadles la coña via email. Mientras tanto recomiendo no comprar ningún cacharro al que no se le peuda meter el código que queramos. Eso sí, olvidáos de garantías en los que dejen meter el código que quieras, si te lo cargas es cosa tuya.

Por otro lado, y para daros una pequeña esperanza, creo que tengo localizado el chip que usan, y en efecto no es ni Atmel, ni PIC, ni Silabs... estoy luchando con el traductor de chino, para conseguir el código fuente del software para actualziar. Cuando lo tenga ya veremos que se puede hacer, pero tengo UN sólo Amaze v2... si cae en combate, adios esperanzas.

quecon escribió:esto es de risa todos jugan online y avanzando y nosotros con el 3.41 nada de nada, algo pasa o esperan para hacerlo porque sino no es normal


confio mas en ti que en los propios creadores del amaze , espero que tenga suerte y des con la tecla , en todo lo que te pueda ayudar hazmelo saber.

un saludo.
He estado buscando lo que has puesto , te comento lo que tengo , supongo que ya lo abras visto aun asi , te lo paso.

Esto creo que es el codigo fuente del HID_ReadWrite, pero no lo tengo claro:

   1. `//--------------------------------------------------------------------------   
   2. //   
   3. // USB HID Device and USB HID Device Manager Helper Classes   
   4. //   
   5. // The building blocks for this code was derived from the HCLIENT sample code   
   6. // provided by Microsoft in the Windows XP DDK.     
   7. //   
   8. //--------------------------------------------------------------------------   
   9. // $Archive: /WirelessUSB/LS2/Firmware/LP KBM RDK/Software/Source Code/CUSBHidAPI/HidAPI.cpp $   
  10. // $Modtime: 10/01/04 2:03p $   
  11. // $Revision: 2 $   
  12. //--------------------------------------------------------------------------   
  13. //   
  14. // Copyright 2003-2004, Cypress Semiconductor Corporation.   
  15. //   
  16. // This software is owned by Cypress Semiconductor Corporation (Cypress)   
  17. // and is protected by and subject to worldwide patent protection (United   
  18. // States and foreign), United States copyright laws and international   
  19. // treaty provisions. Cypress hereby grants to licensee a personal,   
  20. // non-exclusive, non-transferable license to copy, use, modify, create   
  21. // derivative works of, and compile the Cypress Source Code and derivative   
  22. // works for the sole purpose of creating custom software in support of   
  23. // licensee product to be used only in conjunction with a Cypress integrated   
  24. // circuit as specified in the applicable agreement. Any reproduction,   
  25. // modification, translation, compilation, or representation of this   
  26. // software except as specified above is prohibited without the express   
  27. // written permission of Cypress.   
  28. //   
  29. // Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   
  30. // WITH REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED   
  31. // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.   
  32. // Cypress reserves the right to make changes without further notice to the   
  33. // materials described herein. Cypress does not assume any liability arising   
  34. // out of the application or use of any product or circuit described herein.   
  35. // Cypress does not authorize its products for use as critical components in   
  36. // life-support systems where a malfunction or failure may reasonably be   
  37. // expected to result in significant injury to the user. The inclusion of   
  38. // Cypress?product in a life-support systems application implies that the   
  39. // manufacturer assumes all risk of such use and in doing so indemnifies   
  40. // Cypress against all charges.   
  41. //   
  42. // Use may be limited by and subject to the applicable Cypress software   
  43. // license agreement.   
  44. //   
  45. //--------------------------------------------------------------------------   
  46. #include "StdAfx.h"   
  47. #include <dbt.h>   
  48.   
  49. #include "hidapi.h"   
  50.   
  51.   
  52. #define HIDMANAGER_CLASS _T("CHidManager")   
  53. CHidManager* CHidManager::m_pThis = NULL;   
  54. OSVERSIONINFO m_OS;   
  55.   
  56. bool CHidDevice::InitializeHidDevice(PCHAR pDevicePath, USHORT uID)   
  57. {   
  58.     nextHidDevice = NULL;   
  59.   
  60.     m_bOpened = false;   
  61.   
  62.     m_hDevice = NULL;   
  63.     m_hDeviceRegistered = NULL;   
  64.     m_hWnd = NULL;   
  65.   
  66.     m_bOpenedForRead = false;   
  67.     m_bOpenedForWrite = false;   
  68.     m_bOpenedOverlapped = false;   
  69.     m_bOpenedExclusive = false;   
  70.   
  71.     m_uDeviceID = uID;   
  72.   
  73.     m_pHidDevicePath = NULL;   
  74.     m_pHidPpd = NULL;   
  75.     ::ZeroMemory(&m_HidCaps, sizeof(m_HidCaps));   
  76.     ::ZeroMemory(&m_HidAttributes, sizeof(m_HidAttributes));   
  77.   
  78.     m_pInputReportBuffer = NULL;   
  79.     m_pInputData = NULL;   
  80.     m_ulInputDataLength = 0;   
  81.     m_pInputButtonCaps = NULL;   
  82.     m_pInputValueCaps = NULL;   
  83.   
  84.     m_pOutputReportBuffer = NULL;   
  85.     m_pOutputData = NULL;   
  86.     m_ulOutputDataLength = 0;   
  87.     m_pOutputButtonCaps = NULL;   
  88.     m_pOutputValueCaps = NULL;   
  89.   
  90.     m_pFeatureReportBuffer = NULL;   
  91.     m_pFeatureData = NULL;   
  92.     m_ulFeatureDataLength = 0;   
  93.     m_pFeatureButtonCaps = NULL;   
  94.     m_pFeatureValueCaps = NULL;   
  95.   
  96.     m_pHidDevicePath = new CHAR[lstrlen(pDevicePath)+1];   
  97.     if (!m_pHidDevicePath)   
  98.         return false;   
  99.   
100.     ::strcpy(m_pHidDevicePath, pDevicePath);   
101.   
102.     return true;   
103. }   
104.   
105. void CHidDevice::DestroyHidDevice()   
106. {   
107.     if (m_bOpened)   
108.     {   
109.         CloseHidDevice();   
110.     }   
111.   
112.     if (m_pHidDevicePath)   
113.         delete [] m_pHidDevicePath;   
114.       
115.     m_uDeviceID = 0xFFFF;   
116. }   
117.   
118. // sets appropriate access rights, attempts to open a   
119. // handle to the HID device, obtains the top collection data, and   
120. // makes a call to setup input, output, and feature data buffers.   
121. bool CHidDevice::OpenHidDevice( bool bReadAccess,   
122.                                 bool bWriteAccess,   
123.                                 bool bUseOverlapped,   
124.                                 bool bExclusive)   
125. {   
126.     DWORD   accessFlags = 0;   
127.     DWORD   sharingFlags = 0;   
128.   
129.     // Check for valid device path   
130.     if (!m_pHidDevicePath)   
131.     {   
132.         return false;   
133.     }   
134.   
135.     // setup access flag values   
136.     if (bReadAccess)   
137.     {   
138.         accessFlags |= GENERIC_READ;   
139.     }   
140.   
141.     if (bWriteAccess)   
142.     {   
143.         accessFlags |= GENERIC_WRITE;   
144.     }   
145.   
146.     if (!bExclusive)   
147.     {   
148.         sharingFlags = FILE_SHARE_READ | FILE_SHARE_WRITE;   
149.     }   
150.       
151.     //   
152.     //  The hid.dll api's do not pass the overlapped structure into deviceiocontrol   
153.     //  so to use them we must have a non overlapped device.  If the request is for   
154.     //  an overlapped device we will close the device below and get a handle to an   
155.     //  overlapped device   
156.     //   
157.       
158.     m_hDevice = ::CreateFile (m_pHidDevicePath,   
159.                               accessFlags,   
160.                               sharingFlags,   
161.                               NULL,        // no SECURITY_ATTRIBUTES structure   
162.                               OPEN_EXISTING, // No special create flags   
163.                               0,   // Open device as non-overlapped so we can get data   
164.                               NULL);       // No template file   
165.   
166.     if (m_hDevice == INVALID_HANDLE_VALUE)   
167.     {   
168.         return false;   
169.     }   
170.   
171.     // open was successful   
172.     m_bOpened = true;   
173.   
174.     // set access booleans appropriately   
175.     m_bOpenedForRead = bReadAccess;   
176.     m_bOpenedForWrite = bWriteAccess;   
177.     m_bOpenedOverlapped = bUseOverlapped;   
178.     m_bOpenedExclusive = bExclusive;   
179.       
180.     // obtain the top level collection's preparsed data from the HID device.     
181.     // the top level collection is a HID collection that is not nested with   
182.     // other collections.  a HID collection is a meaningful group of HID controls   
183.     // and their respective HID usages.   
184.     if (!::HidD_GetPreparsedData (m_hDevice, &m_pHidPpd))   
185.     {   
186.         // if failure, close HID handle and return failure   
187.         CloseHidDevice();   
188.         return false;   
189.     }   
190.   
191.     // get the attributes of the top level collection   
192.     if (!::HidD_GetAttributes (m_hDevice, &m_HidAttributes))   
193.     {   
194.         // if failure, close HID handle, free preparsed data   
195.         // and return failure   
196.         ::HidD_FreePreparsedData (m_pHidPpd);   
197.         m_pHidPpd = NULL;   
198.   
199.         CloseHidDevice();   
200.         return false;   
201.     }   
202.   
203.     // get the top level collections capability   
204.     if (!::HidP_GetCaps (m_pHidPpd, &m_HidCaps))   
205.     {   
206.         // if failure, close HID handle, free preparsed data   
207.         // and return failure   
208.         ::HidD_FreePreparsedData (m_pHidPpd);   
209.         m_pHidPpd = NULL;   
210.   
211.         CloseHidDevice();   
212.         return false;   
213.     }   
214.   
215.     // attempt to setup the HID device   
216.     if (!SetupHidDevice())   
217.     {   
218.         // if failure, close HID handle, free preparsed data   
219.         // and return failure   
220.         ::HidD_FreePreparsedData (m_pHidPpd);   
221.         m_pHidPpd = NULL;   
222.   
223.         CloseHidDevice();   
224.         return false;   
225.     }   
226.   
227.     //   
228.     // At this point the client has a choice.  It may chose to look at the   
229.     // Usage and Page of the top level collection found in the HIDP_CAPS   
230.     // structure.  In this way it could just use the usages it knows about.   
231.     // If either HidP_GetUsages or HidP_GetUsageValue return an error then   
232.     // that particular usage does not exist in the report.   
233.     //   
234.   
235.     // verify that this is a HID device we care about   
236.     if (!VerifyHidDevice())   
237.     {   
238.         // if failure, close HID handle, free preparsed data   
239.         // and return failure   
240.         ::HidD_FreePreparsedData (m_pHidPpd);   
241.         m_pHidPpd = NULL;   
242.   
243.         CloseHidDevice();   
244.         return false;   
245.     }   
246.   
247.     // if overlapped I/O requested, close handle and reopen using overlapped I/O   
248.     if (bUseOverlapped)   
249.     {   
250.         ::CloseHandle(m_hDevice);   
251.   
252.         m_hDevice = ::CreateFile (m_pHidDevicePath,   
253.                                   accessFlags,   
254.                                   sharingFlags,   
255.                                   NULL,        // no SECURITY_ATTRIBUTES structure   
256.                                   OPEN_EXISTING, // No special create flags   
257.                                   FILE_FLAG_OVERLAPPED, // Now we open the device as overlapped   
258.                                   NULL);       // No template file   
259.       
260.         if (m_hDevice == INVALID_HANDLE_VALUE)   
261.         {   
262.             // if failure, close HID handle, free preparsed data   
263.             // and return failure   
264.             ::HidD_FreePreparsedData (m_pHidPpd);   
265.             m_pHidPpd = NULL;   
266.   
267.             CloseHidDevice();   
268.             return false;   
269.         }   
270.     }   
271.   
272.     return true;   
273. }   
274.   
275. // registers the HID device handle for event notification, mainly to get   
276. // notified when the device is removed   
277. bool CHidDevice::RegisterHidDevice(HWND hWnd)   
278. {   
279.     DEV_BROADCAST_HANDLE broadcastHandle;   
280.   
281.     broadcastHandle.dbch_size = sizeof(DEV_BROADCAST_HANDLE);   
282.     broadcastHandle.dbch_devicetype = DBT_DEVTYP_HANDLE;   
283.     broadcastHandle.dbch_handle = m_hDevice;   
284.       
285.     m_hDeviceRegistered = ::RegisterDeviceNotification(hWnd, (PVOID) &broadcastHandle, DEVICE_NOTIFY_WINDOW_HANDLE);   
286.     if (!m_hDeviceRegistered)   
287.         return false;   
288.   
289.     m_hWnd = hWnd;   
290.   
291.     return true;   
292. }   
293.   
294. // sets up HID input, output and feature data buffers   
295. // used to simplify communication with HID devices   
296. bool CHidDevice::SetupHidDevice()   
297. {   
298.     USHORT              numCaps;   
299.     ULONG               i;   
300.     USAGE               usage;   
301.   
302.     PHIDP_VALUE_CAPS valueCaps;   
303.     PHIDP_BUTTON_CAPS buttonCaps;   
304.     PHID_DATA data;   
305.     USHORT numValues;   
306.   
307.     //   
308.     // setup Input Data buffers.   
309.     //   
310.   
311.     //   
312.     // Allocate memory to hold on input report   
313.     //   
314.   
315.     if (m_HidCaps.InputReportByteLength)   
316.     {   
317.         m_pInputReportBuffer = new CHAR[m_HidCaps.InputReportByteLength];   
318.         if (m_pInputReportBuffer)   
319.             ZeroMemory (m_pInputReportBuffer, m_HidCaps.InputReportByteLength);   
320.     }   
321.   
322.     //   
323.     // Allocate memory to hold the button and value capabilities.   
324.     // NumberXXCaps is in terms of array elements.   
325.     //   
326.       
327.     if (m_HidCaps.NumberInputButtonCaps)   
328.     {   
329.         m_pInputButtonCaps = new HIDP_BUTTON_CAPS[m_HidCaps.NumberInputButtonCaps];   
330.         if (!m_pInputButtonCaps)   
331.             return false;   
332.   
333.         ZeroMemory (m_pInputButtonCaps, m_HidCaps.NumberInputButtonCaps * sizeof(HIDP_BUTTON_CAPS));   
334.   
335.         numCaps = m_HidCaps.NumberInputButtonCaps;   
336.         ::HidP_GetButtonCaps (HidP_Input,   
337.                             m_pInputButtonCaps,   
338.                             &numCaps,   
339.                             m_pHidPpd);   
340.     }   
341.   
342.     if (m_HidCaps.NumberInputValueCaps)   
343.     {   
344.         m_pInputValueCaps = new HIDP_VALUE_CAPS[m_HidCaps.NumberInputValueCaps];   
345.         if (!m_pInputValueCaps)   
346.             return false;   
347.   
348.         ZeroMemory (m_pInputValueCaps, m_HidCaps.NumberInputValueCaps * sizeof(HIDP_VALUE_CAPS));   
349.   
350.         numCaps = m_HidCaps.NumberInputValueCaps;   
351.         ::HidP_GetValueCaps (HidP_Input,   
352.                             m_pInputValueCaps,   
353.                             &numCaps,   
354.                             m_pHidPpd);   
355.     }   
356.   
357.     //   
358.     // Depending on the device, some value caps structures may represent more   
359.     // than one value.  (A range).  In the interest of being verbose, over   
360.     // efficient, we will expand these so that we have one and only one   
361.     // struct _HID_DATA for each value.   
362.     //   
363.     // To do this we need to count up the total number of values are listed   
364.     // in the value caps structure.  For each element in the array we test   
365.     // for range if it is a range then UsageMax and UsageMin describe the   
366.     // usages for this range INCLUSIVE.   
367.     //   
368.   
369.     valueCaps = m_pInputValueCaps;   
370.     numValues = 0;   
371.   
372.     if (valueCaps)   
373.     {   
374.         for (i = 0; i < m_HidCaps.NumberInputValueCaps; i++, valueCaps++)   
375.         {   
376.             if (valueCaps->IsRange)   
377.             {   
378.                 numValues += valueCaps->Range.UsageMax - valueCaps->Range.UsageMin + 1;   
379.             }   
380.             else   
381.             {   
382.                 numValues++;   
383.             }   
384.         }   
385.     }   
386.   
387.     //   
388.     // Allocate a buffer to hold the struct _HID_DATA structures.   
389.     // One element for each set of buttons, and one element for each value   
390.     // found.   
391.     //   
392.   
393.     m_ulInputDataLength = m_HidCaps.NumberInputButtonCaps + numValues;   
394.   
395.     if (m_ulInputDataLength)   
396.     {   
397.         m_pInputData = new HID_DATA[m_ulInputDataLength];   
398.         if (!m_pInputData)   
399.             return false;   
400.   
401.         ZeroMemory (m_pInputData, m_ulInputDataLength * sizeof(HID_DATA));   
402.     }   
403.   
404.     //   
405.     // Fill in the button data   
406.     //   
407.   
408.     buttonCaps = m_pInputButtonCaps;   
409.     data = m_pInputData;   
410.   
411.     if (buttonCaps && data)   
412.     {   
413.         for (i = 0;   
414.             i < m_HidCaps.NumberInputButtonCaps;   
415.             i++, data++, buttonCaps++)   
416.         {   
417.             data->IsButtonData = true;   
418.             data->Status = HIDP_STATUS_SUCCESS;   
419.             data->UsagePage = buttonCaps->UsagePage;   
420.             if (buttonCaps->IsRange)   
421.             {   
422.                 data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;   
423.                 data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;   
424.             }   
425.             else   
426.             {   
427.                 data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;   
428.             }   
429.               
430.             data->ButtonData.MaxUsageLength = ::HidP_MaxUsageListLength (   
431.                                                     HidP_Input,   
432.                                                     buttonCaps->UsagePage,   
433.                                                     m_pHidPpd);   
434.           
435.             data->ButtonData.Usages = new USAGE[data->ButtonData.MaxUsageLength];   
436.             ZeroMemory (data->ButtonData.Usages, data->ButtonData.MaxUsageLength * sizeof(USAGE));   
437.   
438.             data->ReportID = buttonCaps->ReportID;   
439.         }   
440.     }   
441.   
442.     //   
443.     // Fill in the value data   
444.     //   
445.   
446.     valueCaps = m_pInputValueCaps;   
447.   
448.     if (valueCaps)   
449.     {   
450.         for (i = 0; i < numValues; i++, valueCaps++)   
451.         {   
452.             if (valueCaps->IsRange)   
453.             {   
454.                 for (usage = valueCaps->Range.UsageMin;   
455.                     usage <= valueCaps->Range.UsageMax;   
456.                     usage++)   
457.                 {   
458.                     data->IsButtonData = false;   
459.                     data->Status = HIDP_STATUS_SUCCESS;   
460.                     data->UsagePage = valueCaps->UsagePage;   
461.                     data->ValueData.Usage = usage;   
462.                     data->ReportID = valueCaps->ReportID;   
463.                     data++;   
464.                 }   
465.             }   
466.             else   
467.             {   
468.                 data->IsButtonData = false;   
469.                 data->Status = HIDP_STATUS_SUCCESS;   
470.                 data->UsagePage = valueCaps->UsagePage;   
471.                 data->ValueData.Usage = valueCaps->NotRange.Usage;   
472.                 data->ReportID = valueCaps->ReportID;   
473.                 data++;   
474.             }   
475.         }   
476.     }   
477.   
478.     //   
479.     // setup Output Data buffers.   
480.     //   
481.   
482.     if (m_HidCaps.OutputReportByteLength)   
483.     {   
484.         m_pOutputReportBuffer = new CHAR[m_HidCaps.OutputReportByteLength];   
485.         if (m_pOutputReportBuffer)   
486.             ZeroMemory (m_pOutputReportBuffer, m_HidCaps.OutputReportByteLength);   
487.     }   
488.   
489.     if (m_HidCaps.NumberOutputButtonCaps)   
490.     {   
491.         m_pOutputButtonCaps = new HIDP_BUTTON_CAPS[m_HidCaps.NumberOutputButtonCaps];   
492.         if (!m_pOutputButtonCaps)   
493.             return false;   
494.   
495.         ZeroMemory (m_pOutputButtonCaps, m_HidCaps.NumberOutputButtonCaps * sizeof(HIDP_BUTTON_CAPS));   
496.   
497.         numCaps = m_HidCaps.NumberOutputButtonCaps;   
498.         ::HidP_GetButtonCaps (HidP_Output,   
499.                             m_pOutputButtonCaps,   
500.                             &numCaps,   
501.                             m_pHidPpd);   
502.     }   
503.   
504.     if (m_HidCaps.NumberOutputValueCaps)   
505.     {   
506.         m_pOutputValueCaps = new HIDP_VALUE_CAPS[m_HidCaps.NumberOutputValueCaps];   
507.         if (!m_pOutputValueCaps)   
508.             return false;   
509.   
510.         ZeroMemory (m_pOutputValueCaps, m_HidCaps.NumberOutputValueCaps * sizeof(HIDP_VALUE_CAPS));   
511.   
512.         numCaps = m_HidCaps.NumberOutputValueCaps;   
513.         ::HidP_GetValueCaps (HidP_Output,   
514.                             m_pOutputValueCaps,   
515.                             &numCaps,   
516.                             m_pHidPpd);   
517.     }   
518.   
519.     valueCaps = m_pOutputValueCaps;   
520.     numValues = 0;   
521.   
522.     if (valueCaps)   
523.     {   
524.         for (i = 0; i < m_HidCaps.NumberOutputValueCaps; i++, valueCaps++)   
525.         {   
526.             if (valueCaps->IsRange)   
527.             {   
528.                 numValues += valueCaps->Range.UsageMax   
529.                         - valueCaps->Range.UsageMin + 1;   
530.             }   
531.             else   
532.             {   
533.                 numValues++;   
534.             }   
535.         }   
536.     }   
537.   
538.     m_ulOutputDataLength = m_HidCaps.NumberOutputButtonCaps + numValues;   
539.   
540.     if (m_ulOutputDataLength)   
541.     {   
542.         m_pOutputData = new HID_DATA[m_ulOutputDataLength];   
543.         if (!m_pOutputData)   
544.             return false;   
545.   
546.         ZeroMemory (m_pOutputData, m_ulOutputDataLength * sizeof(HID_DATA));   
547.     }   
548.   
549.     buttonCaps = m_pOutputButtonCaps;   
550.     data = m_pOutputData;   
551.   
552.     if (buttonCaps && data)   
553.     {   
554.         for (i = 0;   
555.             i < m_HidCaps.NumberOutputButtonCaps;   
556.             i++, data++, buttonCaps++)   
557.         {   
558.             data->IsButtonData = true;   
559.             data->Status = HIDP_STATUS_SUCCESS;   
560.             data->UsagePage = buttonCaps->UsagePage;   
561.   
562.             if (buttonCaps->IsRange)   
563.             {   
564.                 data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;   
565.                 data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;   
566.             }   
567.             else   
568.             {   
569.                 data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;   
570.             }   
571.   
572.             data->ButtonData.MaxUsageLength = ::HidP_MaxUsageListLength (   
573.                                                         HidP_Output,   
574.                                                         buttonCaps->UsagePage,   
575.                                                         m_pHidPpd);   
576.   
577.             data->ButtonData.Usages = new USAGE[data->ButtonData.MaxUsageLength];   
578.             ZeroMemory (data->ButtonData.Usages, data->ButtonData.MaxUsageLength * sizeof(USAGE));   
579.   
580.             data->ReportID = buttonCaps->ReportID;   
581.         }   
582.     }   
583.   
584.     valueCaps = m_pOutputValueCaps;   
585.   
586.     if (valueCaps)   
587.     {   
588.         for (i = 0; i < numValues; i++, valueCaps++)   
589.         {   
590.             if (valueCaps->IsRange)   
591.             {   
592.                 for (usage = valueCaps->Range.UsageMin;   
593.                     usage <= valueCaps->Range.UsageMax;   
594.                     usage++)   
595.                 {   
596.                     data->IsButtonData = false;   
597.                     data->Status = HIDP_STATUS_SUCCESS;   
598.                     data->UsagePage = valueCaps->UsagePage;   
599.                     data->ValueData.Usage = usage;   
600.                     data->ReportID = valueCaps->ReportID;   
601.                     data++;   
602.                 }   
603.             }   
604.             else   
605.             {   
606.                 data->IsButtonData = false;   
607.                 data->Status = HIDP_STATUS_SUCCESS;   
608.                 data->UsagePage = valueCaps->UsagePage;   
609.                 data->ValueData.Usage = valueCaps->NotRange.Usage;   
610.                 data->ReportID = valueCaps->ReportID;   
611.                 data++;   
612.             }   
613.         }   
614.     }   
615.   
616.     //   
617.     // setup Feature Data buffers.   
618.     //   
619.   
620.     if (m_HidCaps.FeatureReportByteLength)   
621.     {   
622.         m_pFeatureReportBuffer = new CHAR[m_HidCaps.FeatureReportByteLength];   
623.         if (m_pFeatureReportBuffer)   
624.             ZeroMemory (m_pFeatureReportBuffer, m_HidCaps.FeatureReportByteLength);   
625.     }   
626.   
627.     if (m_HidCaps.NumberFeatureButtonCaps)   
628.     {   
629.         m_pFeatureButtonCaps = new HIDP_BUTTON_CAPS[m_HidCaps.NumberFeatureButtonCaps];   
630.         if (!m_pFeatureButtonCaps)   
631.             return false;   
632.   
633.         ZeroMemory (m_pFeatureButtonCaps, m_HidCaps.NumberFeatureButtonCaps * sizeof(HIDP_BUTTON_CAPS));   
634.   
635.         numCaps = m_HidCaps.NumberFeatureButtonCaps;   
636.         ::HidP_GetButtonCaps (HidP_Feature,   
637.                             m_pFeatureButtonCaps,   
638.                             &numCaps,   
639.                             m_pHidPpd);   
640.     }   
641.   
642.     if (m_HidCaps.NumberFeatureValueCaps)   
643.     {   
644.         m_pFeatureValueCaps = new HIDP_VALUE_CAPS[m_HidCaps.NumberFeatureValueCaps];   
645.         if (!m_pFeatureValueCaps)   
646.             return false;   
647.   
648.         ZeroMemory (m_pFeatureValueCaps, m_HidCaps.NumberFeatureValueCaps * sizeof(HIDP_VALUE_CAPS));   
649.   
650.         numCaps = m_HidCaps.NumberFeatureValueCaps;   
651.         ::HidP_GetValueCaps (HidP_Feature,   
652.                             m_pFeatureValueCaps,   
653.                             &numCaps,   
654.                             m_pHidPpd);   
655.     }   
656.   
657.     valueCaps = m_pFeatureValueCaps;   
658.     numValues = 0;   
659.   
660.     if (valueCaps)   
661.     {   
662.         for (i = 0; i < m_HidCaps.NumberFeatureValueCaps; i++, valueCaps++)   
663.         {   
664.             if (valueCaps->IsRange)   
665.             {   
666.                 numValues += valueCaps->Range.UsageMax   
667.                         - valueCaps->Range.UsageMin + 1;   
668.             }   
669.             else   
670.             {   
671.                 numValues++;   
672.             }   
673.         }   
674.     }   
675.   
676.     m_ulFeatureDataLength = m_HidCaps.NumberFeatureButtonCaps + numValues;   
677.   
678.     if (m_ulFeatureDataLength)   
679.     {   
680.         m_pFeatureData = new HID_DATA[m_ulFeatureDataLength];   
681.         if (!m_pFeatureData)   
682.             return false;   
683.   
684.         ZeroMemory (m_pFeatureData, m_ulFeatureDataLength * sizeof(HID_DATA));   
685.     }   
686.   
687.     buttonCaps = m_pFeatureButtonCaps;   
688.     data = m_pFeatureData;   
689.   
690.     if (buttonCaps && data)   
691.     {   
692.         for (i = 0;   
693.             i < m_HidCaps.NumberFeatureButtonCaps;   
694.             i++, data++, buttonCaps++)   
695.         {   
696.             data->IsButtonData = true;   
697.             data->Status = HIDP_STATUS_SUCCESS;   
698.             data->UsagePage = buttonCaps->UsagePage;   
699.   
700.             if (buttonCaps->IsRange)   
701.             {   
702.                 data->ButtonData.UsageMin = buttonCaps->Range.UsageMin;   
703.                 data->ButtonData.UsageMax = buttonCaps->Range.UsageMax;   
704.             }   
705.             else   
706.             {   
707.                 data->ButtonData.UsageMin = data->ButtonData.UsageMax = buttonCaps->NotRange.Usage;   
708.             }   
709.               
710.             data->ButtonData.MaxUsageLength = ::HidP_MaxUsageListLength (   
711.                                                     HidP_Feature,   
712.                                                     buttonCaps->UsagePage,   
713.                                                     m_pHidPpd);   
714.   
715.             data->ButtonData.Usages = new USAGE[data->ButtonData.MaxUsageLength];   
716.             ZeroMemory (data->ButtonData.Usages, data->ButtonData.MaxUsageLength * sizeof(USAGE));   
717.   
718.             data->ReportID = buttonCaps->ReportID;   
719.         }   
720.     }   
721.   
722.     valueCaps = m_pFeatureValueCaps;   
723.   
724.     if (valueCaps)   
725.     {   
726.         for (i = 0; i < numValues; i++, valueCaps++)   
727.         {   
728.             if (valueCaps->IsRange)   
729.             {   
730.                 for (usage = valueCaps->Range.UsageMin;   
731.                     usage <= valueCaps->Range.UsageMax;   
732.                     usage++)   
733.                 {   
734.                     data->IsButtonData = false;   
735.                     data->Status = HIDP_STATUS_SUCCESS;   
736.                     data->UsagePage = valueCaps->UsagePage;   
737.                     data->ValueData.Usage = usage;   
738.                     data->ReportID = valueCaps->ReportID;   
739.                     data++;   
740.                 }   
741.             }   
742.             else   
743.             {   
744.                 data->IsButtonData = false;   
745.                 data->Status = HIDP_STATUS_SUCCESS;   
746.                 data->UsagePage = valueCaps->UsagePage;   
747.                 data->ValueData.Usage = valueCaps->NotRange.Usage;   
748.                 data->ReportID = valueCaps->ReportID;   
749.                 data++;   
750.             }   
751.         }   
752.     }   
753.   
754.     return true;   
755. }   
756.   
757. // closes HID device handle, unregisters HID device notification,   
758. // frees prepased data and data/report buffers   
759. bool CHidDevice::CloseHidDevice()   
760. {   
761.     // close handle, if valid   
762.     if (m_hDevice != INVALID_HANDLE_VALUE)   
763.     {   
764.         ::CloseHandle(m_hDevice);   
765.         m_hDevice = INVALID_HANDLE_VALUE;   
766.     }   
767.   
768.     // if HID device is registered, then unregister   
769.     if (m_hDeviceRegistered)   
770.     {   
771.         PostMessage(m_hWnd, WM_UNREGISTER_HANDLE, 0, (LPARAM) m_hDeviceRegistered);   
772.         m_hDeviceRegistered = NULL;   
773.         m_hWnd = NULL;   
774.     }   
775.       
776.     // free preparsed data   
777.     if (m_pHidPpd)   
778.     {   
779.         ::HidD_FreePreparsedData(m_pHidPpd);   
780.         m_pHidPpd = NULL;   
781.     }   
782.   
783.     // free input report buffer   
784.     if (m_pInputReportBuffer)   
785.     {   
786.         delete [] m_pInputReportBuffer;   
787.         m_pInputReportBuffer = NULL;   
788.     }   
789.   
790.     // free input data buffer   
791.     if (m_pInputData)   
792.     {   
793.         PHID_DATA data = m_pInputData;   
794.   
795.         if (data->ButtonData.Usages)   
796.         {   
797.             delete [] data->ButtonData.Usages;   
798.         }   
799.   
800.         delete [] m_pInputData;   
801.         m_pInputData = NULL;   
802.     }   
803.   
804.     // free input button caps   
805.     if (m_pInputButtonCaps)   
806.     {   
807.         delete [] m_pInputButtonCaps;   
808.         m_pInputButtonCaps = NULL;   
809.     }   
810.   
811.     // free input value caps   
812.     if (m_pInputValueCaps)   
813.     {   
814.         delete [] m_pInputValueCaps;   
815.         m_pInputValueCaps = NULL;   
816.     }   
817.   
818.     // free output report buffer   
819.     if (m_pOutputReportBuffer)   
820.     {   
821.         delete [] m_pOutputReportBuffer;   
822.         m_pOutputReportBuffer = NULL;   
823.     }   
824.   
825.     // free output data buffer   
826.     if (m_pOutputData)   
827.     {   
828.         PHID_DATA data = m_pOutputData;   
829.   
830.         if (data->ButtonData.Usages)   
831.         {   
832.             delete [] data->ButtonData.Usages;   
833.         }   
834.   
835.         delete [] m_pOutputData;   
836.         m_pOutputData = NULL;   
837.     }   
838.   
839.     // free output button caps   
840.     if (m_pOutputButtonCaps)   
841.     {   
842.         delete [] m_pOutputButtonCaps;   
843.         m_pOutputButtonCaps = NULL;   
844.     }   
845.   
846.     // free output value caps   
847.     if (m_pOutputValueCaps)   
848.     {   
849.         delete [] m_pOutputValueCaps;   
850.         m_pOutputValueCaps = NULL;   
851.     }   
852.   
853.     // free feature report buffer   
854.     if (m_pFeatureReportBuffer)   
855.     {   
856.         delete [] m_pFeatureReportBuffer;   
857.         m_pFeatureReportBuffer = NULL;   
858.     }   
859.   
860.     // free feature data buffer   
861.     if (m_pFeatureData)   
862.     {   
863.         PHID_DATA data = m_pFeatureData;   
864.   
865.         if (data->ButtonData.Usages)   
866.         {   
867.             delete [] data->ButtonData.Usages;   
868.         }   
869.   
870.         delete [] m_pFeatureData;   
871.         m_pFeatureData = NULL;   
872.     }   
873.   
874.     // free feature button caps   
875.     if (m_pFeatureButtonCaps)   
876.     {   
877.         delete [] m_pFeatureButtonCaps;   
878.         m_pFeatureButtonCaps = NULL;   
879.     }   
880.   
881.     // free feature values caps   
882.     if (m_pFeatureValueCaps)   
883.     {   
884.         delete [] m_pFeatureValueCaps;   
885.         m_pFeatureValueCaps = NULL;   
886.     }   
887.   
888.     // set open to false   
889.     m_bOpened = false;   
890.   
891.     return true;   
892. }   
893.   
894. // reads an input report from the HID device, performs   
895. // a validity check, and unpacks the report data   
896. bool CHidDevice::Read()   
897. {   
898.     DWORD    bytesRead;   
899.   
900.     // read the input report data   
901.     if (!ReadFile (m_hDevice,   
902.                   m_pInputReportBuffer,   
903.                   m_HidCaps.InputReportByteLength,   
904.                   &bytesRead,   
905.                   NULL)) // no overlapped   
906.     {   
907.         return false;   
908.     }   
909.   
910.     // make sure it was valid, ensure bytes read is what   
911.     // is expected for this report   
912.     ASSERT (bytesRead == m_HidCaps.InputReportByteLength);   
913.     if (bytesRead != m_HidCaps.InputReportByteLength)   
914.     {   
915.         return false;   
916.     }   
917.   
918.     // unpack the report data into a more useful form   
919.     return UnpackReport (HidP_Input,   
920.                          m_pInputReportBuffer,   
921.                          m_HidCaps.InputReportByteLength,   
922.                          m_pInputData,   
923.                          m_ulInputDataLength,   
924.                          m_pHidPpd);   
925. }   
926.   
927. // for every report ID, pack a report buffer and write the report data to the HID device   
928. bool CHidDevice::Write()   
929. {   
930.     DWORD     bytesWritten;   
931.     PHID_DATA pData;   
932.     ULONG     Index;   
933.     bool      Status;   
934.     bool      WriteStatus;   
935.   
936.     // Begin by looping through the HID_DEVICE's HID_DATA structure and setting   
937.     //   the IsDataSet field to false to indicate that each structure has   
938.     //   not yet been set for this Write call.   
939.   
940.     pData = m_pOutputData;   
941.     if (!pData)   
942.         return false;   
943.   
944.     for (Index = 0; Index < m_ulOutputDataLength; Index++, pData++)   
945.     {   
946.         pData->IsDataSet = false;   
947.     }   
948.   
949.     // In setting all the data in the reports, we need to pack a report buffer   
950.     //   and call WriteFile for each report ID that is represented by the   
951.     //   device structure.  To do so, the IsDataSet field will be used to   
952.     //   determine if a given report field has already been set.   
953.   
954.     Status = true;   
955.   
956.     pData = m_pOutputData;   
957.     if (!pData)   
958.         return false;   
959.   
960.     for (Index = 0; Index < m_ulOutputDataLength; Index++, pData++)   
961.     {   
962.         if (!pData->IsDataSet)   
963.         {   
964.             // Package the report for this data structure.  PackReport will   
965.             //    set the IsDataSet fields of this structure and any other   
966.             //    structures that it includes in the report with this structure   
967.   
968.             PackReport (HidP_Output,   
969.                      m_pOutputReportBuffer,   
970.                      m_HidCaps.OutputReportByteLength,   
971.                      pData,   
972.                      m_ulOutputDataLength - Index,   
973.                      m_pHidPpd);   
974.   
975.             // Now a report has been packaged up...Send it down to the device   
976.   
977.             WriteStatus = WriteFile (m_hDevice,   
978.                                   m_pOutputReportBuffer,   
979.                                   m_HidCaps.OutputReportByteLength,   
980.                                   &bytesWritten,   
981.                                   NULL) && (bytesWritten == m_HidCaps.OutputReportByteLength);   
982.   
983.             Status = Status && WriteStatus;                           
984.         }   
985.     }   
986.   
987.     return Status;   
988. }   
989.   
990. // obtains the feature report from each report ID exposed by the HID device   
991. bool CHidDevice::GetFeature()   
992. {   
993.     ULONG     Index;   
994.     PHID_DATA pData;   
995.     BOOLEAN   bReportStatus;   
996.     bool      bStatus;   
997.   
998.     // Begin by looping through the HID_DEVICE's HID_DATA structure and setting   
999.     //   the IsDataSet field to false to indicate that each structure has   
1000.     //   not yet been set for this SetFeature() call.   
1001.   
1002.     pData = m_pFeatureData;   
1003.     if (!pData)   
1004.         return false;   
1005.   
1006.     for (Index = 0; Index < m_ulFeatureDataLength; Index++, pData++)   
1007.     {   
1008.         pData->IsDataSet = false;   
1009.     }   
1010.   
1011.     // Next, each structure in the HID_DATA buffer is filled in with a value   
1012.     //   that is retrieved from one or more calls to HidD_GetFeature.  The   
1013.     //   number of calls is equal to the number of reportIDs on the device   
1014.   
1015.     bStatus = true;   
1016.   
1017.     pData = m_pFeatureData;   
1018.     if (!pData)   
1019.         return false;   
1020.   
1021.     for (Index = 0; Index < m_ulFeatureDataLength; Index++, pData++)   
1022.     {   
1023.         // If a value has yet to have been set for this structure, build a report   
1024.         //    buffer with its report ID as the first byte of the buffer and pass   
1025.         //    it in the HidD_GetFeature call.  Specifying the report ID in the   
1026.         //    first specifies which report is actually retrieved from the device.   
1027.         //    The rest of the buffer should be zeroed before the call   
1028.   
1029.         if (!pData->IsDataSet)   
1030.         {   
1031.             memset(m_pFeatureReportBuffer, 0x00, m_HidCaps.FeatureReportByteLength);   
1032.   
1033.             m_pFeatureReportBuffer[0] = (UCHAR) pData->ReportID;   
1034.   
1035.             bReportStatus = HidD_GetFeature (m_hDevice,   
1036.                                             m_pFeatureReportBuffer,   
1037.                                             m_HidCaps.FeatureReportByteLength);   
1038.   
1039.             // If the return value is true, scan through the rest of the HID_DATA   
1040.             //    structures and fill whatever values we can from this report   
1041.   
1042.             if (bReportStatus)   
1043.             {   
1044.                 bReportStatus = UnpackReport (HidP_Feature,   
1045.                                               m_pFeatureReportBuffer,   
1046.                                               m_HidCaps.FeatureReportByteLength,   
1047.                                               m_pFeatureData,   
1048.                                               m_ulFeatureDataLength,   
1049.                                               m_pHidPpd);   
1050.             }   
1051.   
1052.             bStatus = bStatus && bReportStatus;   
1053.         }   
1054.    }   
1055.   
1056.    return bStatus;   
1057. }   
1058.   
1059. // send a feature report for each report ID exposed by the HID device   
1060. bool CHidDevice::SetFeature()   
1061. {   
1062.     PHID_DATA pData;   
1063.     ULONG     Index;   
1064.     BOOLEAN   bReportStatus;   
1065.     bool      bStatus;   
1066.   
1067.     // Begin by looping through the HID_DEVICE's HID_DATA structure and setting   
1068.     //   the IsDataSet field to false to indicate that each structure has   
1069.     //   not yet been set for this SetFeature() call.   
1070.   
1071.     pData = m_pFeatureData;   
1072.     if (!pData)   
1073.         return false;   
1074.   
1075.     for (Index = 0; Index < m_ulFeatureDataLength; Index++, pData++)   
1076.     {   
1077.         pData->IsDataSet = false;   
1078.     }   
1079.   
1080.     // In setting all the data in the reports, we need to pack a report buffer   
1081.     //   and call WriteFile for each report ID that is represented by the   
1082.     //   device structure.  To do so, the IsDataSet field will be used to   
1083.     //   determine if a given report field has already been set.   
1084.   
1085.     bStatus = true;   
1086.   
1087.     pData = m_pFeatureData;   
1088.     if (!pData)   
1089.         return false;   
1090.   
1091.     for (Index = 0; Index < m_ulFeatureDataLength; Index++, pData++)   
1092.     {   
1093.         if (!pData->IsDataSet)   
1094.         {   
1095.             // Package the report for this data structure.  PackReport will   
1096.             //    set the IsDataSet fields of this structure and any other   
1097.             //    structures that it includes in the report with this structure   
1098.   
1099.             PackReport (HidP_Feature,   
1100.                         m_pFeatureReportBuffer,   
1101.                         m_HidCaps.FeatureReportByteLength,   
1102.                         m_pFeatureData,   
1103.                         m_ulFeatureDataLength - Index,   
1104.                         m_pHidPpd);   
1105.   
1106.             bReportStatus =(HidD_SetFeature (m_hDevice,   
1107.                                                 m_pFeatureReportBuffer,   
1108.                                                 m_HidCaps.FeatureReportByteLength));   
1109.   
1110.             bStatus = bStatus && bReportStatus;   
1111.         }   
1112.     }   
1113.   
1114.     return bStatus;   
1115. }   
1116.   
1117. // scans though the HID data report and fills in any values it can   
1118. bool CHidDevice::UnpackReport(   
1119.                               HIDP_REPORT_TYPE ReportType,   
1120.                               PCHAR ReportBuffer,   
1121.                               USHORT ReportBufferLength,   
1122.                               PHID_DATA Data,   
1123.                               ULONG DataLength,   
1124.                               PHIDP_PREPARSED_DATA Ppd   
1125.                              )   
1126. {   
1127.     ULONG       numUsages; // Number of usages returned from GetUsages.   
1128.     ULONG       i;   
1129.     UCHAR       reportID;   
1130.     ULONG       Index;   
1131.     ULONG       nextUsage;   
1132.   
1133.     reportID = ReportBuffer[0];   
1134.   
1135.     for (i = 0; i < DataLength; i++, Data++)   
1136.     {   
1137.         if (reportID == Data->ReportID)   
1138.         {   
1139.             if (Data->IsButtonData)   
1140.             {   
1141.                 numUsages = Data->ButtonData.MaxUsageLength;   
1142.   
1143.                 Data->Status = HidP_GetUsages (ReportType,   
1144.                                                Data->UsagePage,   
1145.                                                0, // All collections   
1146.                                                Data->ButtonData.Usages,   
1147.                                                &numUsages,   
1148.                                                Ppd,   
1149.                                                ReportBuffer,   
1150.                                                ReportBufferLength);   
1151.   
1152.   
1153.                 // Get usages writes the list of usages into the buffer   
1154.                 // Data->ButtonData.Usages newUsage is set to the number of usages   
1155.                 // written into this array.   
1156.                 // A usage cannot not be defined as zero, so we'll mark a zero   
1157.                 // following the list of usages to indicate the end of the list of   
1158.                 // usages   
1159.                 //   
1160.                 // NOTE: One anomaly of the GetUsages function is the lack of ability   
1161.                 //        to distinguish the data for one ButtonCaps from another   
1162.                 //        if two different caps structures have the same UsagePage   
1163.                 //        For instance:   
1164.                 //          Caps1 has UsagePage 07 and UsageRange of 0x00 - 0x167   
1165.                 //          Caps2 has UsagePage 07 and UsageRange of 0xe0 - 0xe7   
1166.                 //   
1167.                 //        However, calling GetUsages for each of the data structs   
1168.                 //          will return the same list of usages.  It is the   
1169.                 //          responsibility of the caller to set in the HID_DEVICE   
1170.                 //          structure which usages actually are valid for the   
1171.                 //          that structure.   
1172.                 //         
1173.   
1174.                 // Search through the usage list and remove those that   
1175.                 //    correspond to usages outside the define ranged for this   
1176.                 //    data structure.   
1177.                   
1178.                 for (Index = 0, nextUsage = 0; Index < numUsages; Index++)   
1179.                 {   
1180.                     if (Data->ButtonData.UsageMin <= Data->ButtonData.Usages[Index] &&   
1181.                             Data->ButtonData.Usages[Index] <= Data->ButtonData.UsageMax)   
1182.                     {   
1183.                         Data->ButtonData.Usages[nextUsage++] = Data->ButtonData.Usages[Index];   
1184.                     }   
1185.                 }   
1186.   
1187.                 if (nextUsage < Data->ButtonData.MaxUsageLength)   
1188.                 {   
1189.                     Data->ButtonData.Usages[nextUsage] = 0;   
1190.                 }   
1191.             }   
1192.             else   
1193.             {   
1194.                 Data->Status = HidP_GetUsageValue (   
1195.                                                 ReportType,   
1196.                                                 Data->UsagePage,   
1197.                                                 0,               // All Collections.   
1198.                                                 Data->ValueData.Usage,   
1199.                                                 &Data->ValueData.Value,   
1200.                                                 Ppd,   
1201.                                                 ReportBuffer,   
1202.                                                 ReportBufferLength);   
1203.   
1204.                 if (HIDP_STATUS_SUCCESS != Data->Status)   
1205.                 {   
1206.                     return false;   
1207.                 }   
1208.   
1209.                 Data->Status = HidP_GetScaledUsageValue (   
1210.                                                        ReportType,   
1211.                                                        Data->UsagePage,   
1212.                                                        0, // All Collections.   
1213.                                                        Data->ValueData.Usage,   
1214.                                                        &Data->ValueData.ScaledValue,   
1215.                                                        Ppd,   
1216.                                                        ReportBuffer,   
1217.                                                        ReportBufferLength);   
1218.             }   
1219.   
1220.             Data->IsDataSet = true;   
1221.         }   
1222.     }   
1223.   
1224.     return true;   
1225. }   
1226.   
1227. // packages the HID report based on the data in the structures   
1228. bool CHidDevice::PackReport(   
1229.                             HIDP_REPORT_TYPE ReportType,   
1230.                             PCHAR ReportBuffer,   
1231.                             USHORT ReportBufferLength,   
1232.                             PHID_DATA Data,   
1233.                             ULONG DataLength,   
1234.                             PHIDP_PREPARSED_DATA Ppd   
1235.                            )   
1236. {   
1237.     ULONG       numUsages; // Number of usages to set for a given report.   
1238.     ULONG       i;   
1239.     ULONG       CurrReportID;   
1240.   
1241.     // All report buffers that are initially sent need to be zero'd out   
1242.   
1243.     memset (ReportBuffer, (UCHAR) 0, ReportBufferLength);   
1244.   
1245.     // Go through the data structures and set all the values that correspond to   
1246.     //   the CurrReportID which is obtained from the first data structure   
1247.     //   in the list   
1248.   
1249.     CurrReportID = Data->ReportID;   
1250.   
1251.     for (i = 0; i < DataLength; i++, Data++)   
1252.     {   
1253.         // There are two different ways to determine if we set the current data   
1254.         //    structure:   
1255.         //    1) Store the report ID were using and only attempt to set those   
1256.         //        data structures that correspond to the given report ID.  This   
1257.         //        example shows this implementation.   
1258.         //   
1259.         //    2) Attempt to set all of the data structures and look for the   
1260.         //        returned status value of HIDP_STATUS_INVALID_REPORT_ID.  This   
1261.         //        error code indicates that the given usage exists but has a   
1262.         //        different report ID than the report ID in the current report   
1263.         //        buffer   
1264.   
1265.         if (Data->ReportID == CurrReportID)   
1266.         {   
1267.             if (Data->IsButtonData)   
1268.             {   
1269.                 numUsages = Data->ButtonData.MaxUsageLength;   
1270.                 Data->Status = HidP_SetUsages (ReportType,   
1271.                                                Data->UsagePage,   
1272.                                                0, // All collections   
1273.                                                Data->ButtonData.Usages,   
1274.                                                &numUsages,   
1275.                                                Ppd,   
1276.                                                ReportBuffer,   
1277.                                                ReportBufferLength);   
1278.             }   
1279.             else   
1280.             {   
1281.                 Data->Status = HidP_SetUsageValue (ReportType,   
1282.                                                    Data->UsagePage,   
1283.                                                    0, // All Collections.   
1284.                                                    Data->ValueData.Usage,   
1285.                                                    Data->ValueData.Value,   
1286.                                                    Ppd,   
1287.                                                    ReportBuffer,   
1288.                                                    ReportBufferLength);   
1289.             }   
1290.   
1291.             if (HIDP_STATUS_SUCCESS != Data->Status)   
1292.             {   
1293.                 return false;   
1294.             }   
1295.   
1296.             Data->IsDataSet = true;   
1297.         }   
1298.     }     
1299.   
1300.     return true;   
1301. }   
1302.   
1303. // obtains the manufacturer string from the HID device   
1304. bool CHidDevice::GetManufacturerString(PCHAR szManufacturerString, ULONG ulManufacturerStringLength)   
1305. {   
1306.     PWCHAR str = new WCHAR[ulManufacturerStringLength];   
1307.   
1308.     if (str)   
1309.     {   
1310.         // attempt to get the manufacturer string, which is in Unicode format   
1311.         BOOLEAN result = HidD_GetManufacturerString(m_hDevice, str, ulManufacturerStringLength*sizeof(WCHAR));   
1312.   
1313.         if (result)   
1314.         {   
1315.             // converts the wide character string (Unicode) to multi-byte string   
1316.             SIZE_T nBytes = wcstombs(szManufacturerString, str, ulManufacturerStringLength-1);   
1317.             if ((SIZE_T) -1 != nBytes)   
1318.             {   
1319.                 delete str;   
1320.                 return true;   
1321.             }   
1322.         }   
1323.   
1324.         delete str;   
1325.     }   
1326.   
1327.     return false;   
1328. }   
1329.   
1330. // obtains the product string from the HID device   
1331. bool CHidDevice::GetProductString(PCHAR szProductString, ULONG ulProductStringLength)   
1332. {   
1333.     PWCHAR str = new WCHAR[ulProductStringLength];   
1334.   
1335.     if (str)   
1336.     {   
1337.         // attempt to get the product string, which is in Unicode format   
1338.         BOOLEAN result = HidD_GetProductString(m_hDevice, str, ulProductStringLength*sizeof(WCHAR));   
1339.   
1340.         if (result)   
1341.         {   
1342.             // converts the wide character string (Unicode) to multi-byte string   
1343.             SIZE_T nBytes = wcstombs(szProductString, str, ulProductStringLength-1);   
1344.             if ((SIZE_T) -1 != nBytes)   
1345.             {   
1346.                 delete str;   
1347.                 return true;   
1348.             }   
1349.         }   
1350.   
1351.         delete str;   
1352.     }   
1353.   
1354.     return false;   
1355. }   
1356.   
1357. // obtains the serial numbert string from the HID device   
1358. bool CHidDevice::GetSerialNumberString(PCHAR szSerialNumberString, ULONG ulSerialNumberStringLength)   
1359. {   
1360.     PWCHAR str = new WCHAR[ulSerialNumberStringLength];   
1361.   
1362.     if (str)   
1363.     {   
1364.         // attempt to get the serial number string, which is in Unicode format   
1365.         BOOLEAN result = HidD_GetSerialNumberString(m_hDevice, str, ulSerialNumberStringLength*sizeof(WCHAR));   
1366.   
1367.         if (result)   
1368.         {   
1369.             // converts the wide character string (Unicode) to multi-byte string   
1370.             SIZE_T nBytes = wcstombs(szSerialNumberString, str, ulSerialNumberStringLength-1);   
1371.             if ((SIZE_T) -1 != nBytes)   
1372.             {   
1373.                 delete str;   
1374.                 return true;   
1375.             }   
1376.         }   
1377.   
1378.         delete str;   
1379.     }   
1380.   
1381.     return false;   
1382. }   
1383.   
1384. // attempts to get a registry value from the registry key where the   
1385. // device-specific configuration information is stored for the HID device   
1386. bool CHidDevice::RegQueryValue(LPCTSTR lpValueName,   
1387.                                 LPDWORD lpType,   
1388.                                 LPBYTE lpData,   
1389.                                 LPDWORD lpcbData)   
1390. {   
1391.     bool ret = false;   
1392.   
1393.     HDEVINFO hwDeviceInfo;   
1394.     SP_DEVICE_INTERFACE_DATA devInterfaceData;   
1395.     GUID hidGuid;   
1396.   
1397.   
1398.     // get a copy of the HID GUID to be used below   
1399.     HidD_GetHidGuid (&hidGuid);   
1400.   
1401.     // get a list of all HID devices present in the system   
1402.     hwDeviceInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);   
1403.     if (hwDeviceInfo != INVALID_HANDLE_VALUE)           
1404.     {   
1405.         HKEY hkEnum;               
1406.   
1407.         // loop through all HID devices, looking for a match for this specific HID device   
1408.         int iEnumInfo = 0;         
1409.         devInterfaceData.cbSize = sizeof(devInterfaceData);   
1410.         while ( SetupDiEnumDeviceInterfaces(hwDeviceInfo, 0, (CONST LPGUID)&hidGuid, iEnumInfo++, &devInterfaceData) )   
1411.         {   
1412.             SP_DEVINFO_DATA devInfoData;   
1413.             PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData;   
1414.             ULONG requiredLength = 0;   
1415.             ULONG predictedLength = 0;   
1416.   
1417.             SetupDiGetInterfaceDeviceDetail (   
1418.                     hwDeviceInfo,   
1419.                     &devInterfaceData,   
1420.                     NULL,   
1421.                     0,   
1422.                     &requiredLength,   
1423.                     NULL);   
1424.   
1425.             predictedLength = requiredLength;   
1426.   
1427.             // allocate the device data   
1428.             devInfoData.cbSize = sizeof(devInfoData);   
1429.             functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new UCHAR[predictedLength];   
1430.             functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);   
1431.   
1432.             // retrieve the information from Plug and Play   
1433.             if (SetupDiGetInterfaceDeviceDetail(hwDeviceInfo, &devInterfaceData, functionClassDeviceData, predictedLength, &requiredLength, &devInfoData))   
1434.             {   
1435.                 // check to see if this HID device is a match   
1436.                 if (strcmpi(functionClassDeviceData->DevicePath, m_pHidDevicePath) == 0)   
1437.                 {   
1438.                     // found a match, open a handle to the registry   
1439.                     // where device-specific configuration information   
1440.                     // is stored   
1441.                     hkEnum = SetupDiOpenDevRegKey ( hwDeviceInfo,   
1442.                         &devInfoData,   
1443.                         DICS_FLAG_GLOBAL,   
1444.                         0,   
1445.                         DIREG_DEV,   
1446.                         KEY_ALL_ACCESS );   
1447.   
1448.                     if (hkEnum != INVALID_HANDLE_VALUE)   
1449.                     {   
1450.                         // if the reg handle was open, attempt to obtain   
1451.                         // the registry value   
1452.                         if (RegQueryValueEx(hkEnum,   
1453.                             lpValueName,   
1454.                             NULL,   
1455.                             lpType,   
1456.                             lpData,   
1457.                             lpcbData   
1458.                             ) == ERROR_SUCCESS)   
1459.                         {   
1460.                             // indicate success   
1461.                             ret = true;   
1462.                         }   
1463.   
1464.                         // close the reg handle   
1465.                         RegCloseKey ( hkEnum );   
1466.                     }   
1467.       
1468.                     // release the allocated device data and   
1469.                     // leave the loop   
1470.                     delete [] functionClassDeviceData;   
1471.                     break;   
1472.                 }   
1473.             }   
1474.   
1475.             // release the allocated device data   
1476.             delete [] functionClassDeviceData;   
1477.         }   
1478.   
1479.         // destroy the list that was created above   
1480.         SetupDiDestroyDeviceInfoList(hwDeviceInfo);   
1481.     }   
1482.   
1483.     return ret;   
1484. }   
1485.   
1486. // attempts to set a registry value in the registry key where the   
1487. // device-specific configuration information is stored for the HID device   
1488. bool CHidDevice::RegSetValue(LPCTSTR lpValueName,   
1489.                                 DWORD Type,   
1490.                                 LPBYTE lpData,   
1491.                                 DWORD cbData)   
1492. {   
1493.     bool ret = false;   
1494.   
1495.     HDEVINFO hwDeviceInfo;   
1496.     SP_DEVICE_INTERFACE_DATA devInterfaceData;   
1497.     GUID hidGuid;   
1498.   
1499.   
1500.     // get a copy of the HID GUID to be used below   
1501.     HidD_GetHidGuid (&hidGuid);   
1502.   
1503.     // get a list of all HID devices present in the system   
1504.     hwDeviceInfo = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);   
1505.     if (hwDeviceInfo != INVALID_HANDLE_VALUE)           
1506.     {   
1507.         HKEY hkEnum;               
1508.   
1509.         // loop through all HID devices, looking for a match for this specific HID device   
1510.         int iEnumInfo = 0;         
1511.         devInterfaceData.cbSize = sizeof(devInterfaceData);   
1512.         while ( SetupDiEnumDeviceInterfaces(hwDeviceInfo, 0, (CONST LPGUID)&hidGuid, iEnumInfo++, &devInterfaceData) )   
1513.         {   
1514.             SP_DEVINFO_DATA devInfoData;   
1515.             PSP_INTERFACE_DEVICE_DETAIL_DATA functionClassDeviceData;   
1516.             ULONG requiredLength = 0;   
1517.             ULONG predictedLength = 0;   
1518.   
1519.             SetupDiGetInterfaceDeviceDetail (   
1520.                     hwDeviceInfo,   
1521.                     &devInterfaceData,   
1522.                     NULL,   
1523.                     0,   
1524.                     &requiredLength,   
1525.                     NULL);   
1526.   
1527.             predictedLength = requiredLength;   
1528.   
1529.             // allocate the device data   
1530.             devInfoData.cbSize = sizeof(devInfoData);   
1531.             functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new UCHAR[predictedLength];   
1532.             functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);   
1533.   
1534.             // retrieve the information from Plug and Play   
1535.             if (SetupDiGetInterfaceDeviceDetail(hwDeviceInfo, &devInterfaceData, functionClassDeviceData, predictedLength, &requiredLength, &devInfoData))   
1536.             {   
1537.                 // check to see if this HID device is a match   
1538.                 if (strcmpi(functionClassDeviceData->DevicePath, m_pHidDevicePath) == 0)   
1539.                 {   
1540.                     // found a match, open a handle to the registry   
1541.                     // where device-specific configuration information   
1542.                     // is stored   
1543.                     hkEnum = SetupDiOpenDevRegKey ( hwDeviceInfo,   
1544.                         &devInfoData,   
1545.                         DICS_FLAG_GLOBAL,   
1546.                         0,   
1547.                         DIREG_DEV,   
1548.                         KEY_ALL_ACCESS );   
1549.   
1550.                     if (hkEnum != INVALID_HANDLE_VALUE)   
1551.                     {   
1552.                         if (RegSetValueEx(hkEnum,   
1553.                             lpValueName,   
1554.                             NULL,   
1555.                             Type,   
1556.                             lpData,   
1557.                             cbData   
1558.                             ) == ERROR_SUCCESS)   
1559.                         {   
1560.                             // indicate success   
1561.                             ret = true;   
1562.                         }   
1563.   
1564.                         // close the reg handle   
1565.                         RegCloseKey ( hkEnum );   
1566.                     }   
1567.   
1568.                     // release the allocated device data and   
1569.                     // leave the loop   
1570.                     delete [] functionClassDeviceData;   
1571.                     break;   
1572.                 }   
1573.             }   
1574.   
1575.             // release the allocated device data   
1576.             delete [] functionClassDeviceData;   
1577.         }   
1578.   
1579.         // destroy the list that was created above   
1580.         SetupDiDestroyDeviceInfoList(hwDeviceInfo);   
1581.     }   
1582.   
1583.     return ret;   
1584. }   
1585.   
1586.   
1587. CHidManager::CHidManager()   
1588. {   
1589.     m_OS.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);   
1590.     GetVersionEx( &m_OS );   
1591.   
1592.     InitializeHidManager();   
1593. }   
1594.   
1595. CHidManager::~CHidManager(void)   
1596. {   
1597.     // remove all HID devices in the maintained list   
1598.     RemoveAllHidDevices();   
1599.   
1600.     // destroy the invisible window, if it exists   
1601.     if (m_hWnd)   
1602.     {   
1603.         ::DestroyWindow(m_hWnd);   
1604.         m_hWnd = NULL;   
1605.     }   
1606.   
1607.     // if we registered for notificiation for this device, then clean up   
1608.     if (m_hDeviceNotification)   
1609.     {   
1610.         // issue callback indicating the device notification is being unregistered   
1611.         if (m_pHidCallback) (*m_pHidCallback)(m_pHidCallbackParam, NULL, HIDCB_NOTIFY_DEVICE_UNREGISTERED);   
1612.   
1613.         // unregister device notification   
1614.         // NOTE: for Windows 98x, it can become unstable if you unregister the device notification   
1615.         if (m_OS.dwMajorVersion > 4)   
1616.         {   
1617.             ::UnregisterDeviceNotification(m_hDeviceNotification);   
1618.         }   
1619.         m_hDeviceNotification = NULL;   
1620.     }   
1621.   
1622.     // NULL callback function and parameter pointers   
1623.     m_pHidCallback = NULL;   
1624.     m_pHidCallbackParam = NULL;   
1625. }   
1626.   
1627. // standard initialization   
1628. void CHidManager::InitializeHidManager()   
1629. {   
1630.     m_pThis = this;   
1631.   
1632.     m_bEnabled = false;   
1633.     m_hWnd = NULL;   
1634.     m_hDeviceNotification = NULL;   
1635.     m_pHidCallback = NULL;   
1636.     m_pHidCallbackParam = NULL;   
1637.   
1638.     m_pHidDeviceListHead = NULL;   
1639.     m_pCurrentHidDevice = NULL;   
1640.     m_nHidDevices = 0;   
1641.   
1642.     ZeroMemory(m_bUniqueIDs, HIDMGR_SUPPORTED_HID_DEVICES);   
1643. }   
1644.   
1645.   
1646. // registers for notification of events for all HID class devices and   
1647. // calls HID callback function to indicate registration was completed   
1648. bool CHidManager::RegisterHidNotification(HWND hWnd)   
1649. {   
1650.     DEV_BROADCAST_DEVICEINTERFACE broadcastInterface = {0};   
1651.   
1652.     broadcastInterface.dbcc_size = sizeof(broadcastInterface);   
1653.     broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;   
1654.   
1655.     // get HID GUID   
1656.     ::HidD_GetHidGuid(&broadcastInterface.dbcc_classguid);   
1657.   
1658.     m_hDeviceNotification = ::RegisterDeviceNotification(hWnd, (PVOID) &broadcastInterface, DEVICE_NOTIFY_WINDOW_HANDLE);   
1659.     if (!m_hDeviceNotification) return false;   
1660.   
1661.     if (m_pHidCallback) (*m_pHidCallback)(m_pHidCallbackParam, NULL, HIDCB_NOTIFY_DEVICE_REGISTERED);   
1662.   
1663.     return true;   
1664. }   
1665.   
1666.   
1667. // registers a window class for subsequent use in calls to CreateWindow, used below   
1668. ATOM CHidManager::RegisterClass(HINSTANCE hInstance)   
1669. {   
1670.     WNDCLASSEX wcex;   
1671.   
1672.     wcex.cbSize = sizeof(WNDCLASSEX);   
1673.   
1674.     wcex.style          = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;   
1675.     //wcex.lpfnWndProc  = (WNDPROC)WindowProc;                                  /////////////////////////////////////////////   
1676.     wcex.cbClsExtra     = 0;   
1677.     wcex.cbWndExtra     = 0;   
1678.     wcex.hInstance      = hInstance;   
1679.     wcex.hIcon          = 0;   
1680.     wcex.hCursor        = 0;   
1681.     wcex.hbrBackground  = 0;   
1682.     wcex.lpszMenuName   = 0;   
1683.     wcex.lpszClassName  = HIDMANAGER_CLASS;   
1684.     wcex.hIconSm        = 0;   
1685.   
1686.     return ::RegisterClassEx(&wcex);   
1687. }   
1688.   
1689. // creates an invisible window and uses the returned window handle   
1690. // to register for HID device notification events, then it creates   
1691. // a list of existing HID devices that will be maintained by the   
1692. // HID manager   
1693. bool CHidManager::Create(HINSTANCE hInst, HWND hParentWnd, PHidCallback pHidCallback, void *pHidCallbackParam)   
1694. {   
1695.     bool bResult = true;   
1696.   
1697.     m_pHidCallback = pHidCallback;   
1698.     m_pHidCallbackParam = pHidCallbackParam;   
1699.   
1700.     // class so WindowProc function is called   
1701.     RegisterClass(hInst);   
1702.   
1703.     // Create an invisible window   
1704.     m_hWnd = ::CreateWindow(HIDMANAGER_CLASS, _T(""), WS_POPUP,   
1705.                             CW_USEDEFAULT,CW_USEDEFAULT,   
1706.                             CW_USEDEFAULT,CW_USEDEFAULT,   
1707.                             NULL, 0,   
1708.                             hInst, 0);   
1709.       
1710.     if (!RegisterHidNotification(m_hWnd))   
1711.     {   
1712.         bResult = false;   
1713.     }   
1714.       
1715.     if (bResult)   
1716.     {   
1717.         // setup all existing and valid HID devices   
1718.         RefreshHidDevices();   
1719.   
1720.         // everything was created successfully   
1721.         m_bEnabled = true;   
1722.     }   
1723.   
1724.     return bResult;   
1725. }   
1726.   
1727. // attempts to open a handle to the HID device to determine   
1728. // if it is present (or not) and returns the result   
1729. bool CHidManager::IsHidDevicePresent(CHidDevice *pHidDevice)   
1730. {   
1731.     // attempt to open a handle to the HID device, if the device   
1732.     // is present then this should return success   
1733.     HANDLE h = ::CreateFile(pHidDevice->m_pHidDevicePath,   
1734.                             GENERIC_WRITE | GENERIC_READ,   
1735.                             FILE_SHARE_WRITE | FILE_SHARE_READ,   
1736.                             NULL,   
1737.                             OPEN_EXISTING,   
1738.                             0,   
1739.                             NULL);   
1740.   
1741.     if (h != INVALID_HANDLE_VALUE)   
1742.     {   
1743.         // close handle and indicate device is present   
1744.         ::CloseHandle(h);   
1745.         return true;   
1746.     }   
1747.   
1748.     return false;   
1749. }   
1750.   
1751. // attempts to create and maintain a unique ID for the associated HID device   
1752. USHORT CHidManager::CreateUniqueDeviceID()   
1753. {   
1754.     USHORT i;   
1755.   
1756.     for (i=0;i<hidmgr_supported_hid_devices;i++) (!m_buniqueids[i])="" m_buniqueids[i]="true;" i;="" return="" 0xffff;="" }="" frees="" the="" specified="" unique="" id="" void="" chidmanager::freeuniquedeviceid(ushort="" uid)="" {="" if="" (uid="">< HIDMGR_SUPPORTED_HID_DEVICES)   
1757.     {   
1758.         m_bUniqueIDs[uID] = false;   
1759.     }   
1760. }   
1761.   
1762. // returns a pointer to the first HID device in the list   
1763. CHidDevice* CHidManager::GetFirstHidDevice()   
1764. {   
1765.     m_pCurrentHidDevice = m_pHidDeviceListHead;   
1766.     return m_pCurrentHidDevice;   
1767. }   
1768.   
1769. // returns a pointer to the next HID device in the list   
1770. CHidDevice* CHidManager::GetNextHidDevice()   
1771. {   
1772.     if (m_pCurrentHidDevice)   
1773.         m_pCurrentHidDevice = m_pCurrentHidDevice->nextHidDevice;   
1774.   
1775.     return m_pCurrentHidDevice;   
1776. }   
1777.   
1778. // returns a pointer to the current HID device in the list   
1779. CHidDevice* CHidManager::GetCurrentHidDevice()   
1780. {   
1781.     return m_pCurrentHidDevice;   
1782. }   
1783.   
1784. // scans the current list of HID devices and returns a pointer   
1785. // to the HID device that matches the device path provided   
1786. CHidDevice* CHidManager::GetHidDeviceWithPath(PCHAR pDevicePath)   
1787. {   
1788.     CHidDevice * pCurHidDevice = m_pHidDeviceListHead;   
1789.   
1790.     while (pCurHidDevice)   
1791.     {   
1792.         if (!lstrcmpi(pCurHidDevice->m_pHidDevicePath, pDevicePath))   
1793.             break;   
1794.   
1795.         pCurHidDevice = pCurHidDevice->nextHidDevice;   
1796.     }   
1797.   
1798.     return pCurHidDevice;   
1799. }   
1800.   
1801. // scans the current list of HID devices and returns a pointer   
1802. // to the HID device that matches the device handle provided   
1803. CHidDevice* CHidManager::GetHidDeviceWithHandle(HANDLE hHidDevice)   
1804. {   
1805.     CHidDevice * pCurHidDevice = m_pHidDeviceListHead;   
1806.   
1807.     while (pCurHidDevice)   
1808.     {   
1809.         if (pCurHidDevice->GetDeviceHandle() == hHidDevice)   
1810.             break;   
1811.   
1812.         pCurHidDevice = pCurHidDevice->nextHidDevice;   
1813.     }   
1814.   
1815.     return pCurHidDevice;   
1816. }   
1817.   
1818. // determines if the HID device already exists in the list   
1819. bool CHidManager::HidDeviceAlreadyExist(CHidDevice *pHidDevice)   
1820. {   
1821.     CHidDevice * pCurHidDevice = m_pHidDeviceListHead;   
1822.   
1823.     while (pCurHidDevice)   
1824.     {   
1825.         if (pCurHidDevice == pHidDevice)   
1826.             return true;   
1827.   
1828.         pCurHidDevice = pCurHidDevice->nextHidDevice;   
1829.     }   
1830.   
1831.     return false;   
1832. }   
1833.   
1834. // checks if the provided HID device already exists, and if not,   
1835. // adds the new HID device to the end of the list, increments the   
1836. // HID device counter, and call the HID callback function to indicate   
1837. // a new HID device was added   
1838. bool CHidManager::AddHidDevice(CHidDevice *pHidDevice)   
1839. {   
1840.     // determine if HID device already exists   
1841.     if (HidDeviceAlreadyExist(pHidDevice))   
1842.         return false;   
1843.   
1844.     // add HID device to end of list, if first device   
1845.     // then set it as the first device in the list   
1846.     if (m_pHidDeviceListHead == NULL)   
1847.     {   
1848.         m_pHidDeviceListHead = pHidDevice;   
1849.     }   
1850.     else   
1851.     {   
1852.         CHidDevice * pHidTemp = m_pHidDeviceListHead;   
1853.   
1854.         while (pHidTemp->nextHidDevice != NULL)   
1855.         {   
1856.             pHidTemp = pHidTemp->nextHidDevice;   
1857.         }   
1858.   
1859.         pHidTemp->nextHidDevice = pHidDevice;   
1860.     }   
1861.   
1862.     // increment HID device counter   
1863.     m_nHidDevices++;   
1864.   
1865.     // call HID callback function to indicate HID device was added   
1866.     if (m_pHidCallback) (*m_pHidCallback)(m_pHidCallbackParam, pHidDevice, HIDCB_NOTIFY_DEVICE_ADDED);   
1867.   
1868.     return true;   
1869. }   
1870.   
1871. // closes outstanding handle to the HID device, call HID   
1872. // callback function to indicate HID device is being removed,   
1873. // removes the HID device from the list, and deletes the HID device   
1874. bool CHidManager::RemoveHidDevice(CHidDevice *pHidDevice)   
1875. {   
1876.     // check for valid HID device pointer   
1877.     if (pHidDevice)   
1878.     {   
1879.         // close handle to HID device   
1880.         pHidDevice->CloseHidDevice();   
1881.   
1882.         CHidDevice * pHidTemp = m_pHidDeviceListHead;   
1883.         CHidDevice * pHidPrev = NULL;   
1884.   
1885.         // loop through all HID devices in the list to find the   
1886.         // matching HID device to be removed   
1887.         while (pHidTemp)   
1888.         {   
1889.             // check if HID device was found   
1890.             if (pHidTemp == pHidDevice)   
1891.             {   
1892.                 // found, so decrement HID device counter   
1893.                 m_nHidDevices--;   
1894.   
1895.                 // call HID callback function to indicate HID device is   
1896.                 // being removed   
1897.                 if (m_pHidCallback) (*m_pHidCallback)(m_pHidCallbackParam, pHidDevice, HIDCB_NOTIFY_DEVICE_REMOVED);   
1898.   
1899.                 // remove HID device from list   
1900.                 if (pHidPrev)   
1901.                 {   
1902.                     pHidPrev->nextHidDevice = pHidTemp->nextHidDevice;   
1903.                 }   
1904.   
1905.                 if (pHidTemp == m_pHidDeviceListHead)   
1906.                 {   
1907.                     m_pHidDeviceListHead = pHidTemp->nextHidDevice;   
1908.                 }   
1909.   
1910.                 // delete HID device   
1911.                 DeleteHidDevice(pHidTemp);   
1912.   
1913.                 // end loop   
1914.                 pHidTemp = NULL;   
1915.             }   
1916.             else   
1917.             {   
1918.                 // get next HID device in list   
1919.                 pHidPrev = pHidTemp;   
1920.                 pHidTemp = pHidTemp->nextHidDevice;   
1921.             }   
1922.         }   
1923.     }   
1924.       
1925.     return true;   
1926. }   
1927.   
1928. // scans though all HID devices in the list and removes them   
1929. void CHidManager::RemoveAllHidDevices()   
1930. {   
1931.     CHidDevice * pCurHidDevice = m_pHidDeviceListHead;   
1932.   
1933.     while (pCurHidDevice)   
1934.     {   
1935.         CHidDevice * pNextHidDevice = pCurHidDevice->nextHidDevice;   
1936.   
1937.         RemoveHidDevice(pCurHidDevice);   
1938.   
1939.         pCurHidDevice = pNextHidDevice;   
1940.     }   
1941.   
1942.     m_pHidDeviceListHead = NULL;   
1943. }   
1944.   
1945. // validates that all HID devices in the list are still present,   
1946. // removes those from the list that are currently not present,   
1947. // scans the list of all existing HID devices present, and then   
1948. // attempts to add the existing HID devices to the list   
1949. bool CHidManager::RefreshHidDevices(void)   
1950. {   
1951.     bool                     bRetVal = false;   
1952.     CHidDevice               *pCurHidDevice = m_pHidDeviceListHead;   
1953.   
1954.     // first check that all devices are still valid   
1955.     // remove if not   
1956.     while (pCurHidDevice)   
1957.     {   
1958.         CHidDevice * pNextHidDevice = pCurHidDevice->nextHidDevice;   
1959.   
1960.         if (!IsHidDevicePresent(pCurHidDevice))   
1961.         {   
1962.             RemoveHidDevice(pCurHidDevice);   
1963.             bRetVal = true;   
1964.         }   
1965.   
1966.         pCurHidDevice = pNextHidDevice;   
1967.     }   
1968.   
1969.   
1970.     // open a handle to the plug and play dev node, SetupDiGetClassDevs()   
1971.     // returns a device information set that contains info on all installed   
1972.     // devices of a specified class.   
1973.     GUID                             hidGuid;   
1974.     HDEVINFO                         hardwareDeviceInfo;   
1975.     SP_DEVICE_INTERFACE_DATA         deviceInfoData;   
1976.     PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL;   
1977.     ULONG                            predictedLength = 0;   
1978.     ULONG                            requiredLength = 0;   
1979.     ULONG                            i = 0;   
1980.     bool                             bDone = false;   
1981.   
1982.     HidD_GetHidGuid (&hidGuid);   
1983.   
1984.     hardwareDeviceInfo = SetupDiGetClassDevs (&hidGuid,   
1985.                                                 NULL, // define no enumerator (all HID devices)   
1986.                                                 NULL, // define no   
1987.                                                 (DIGCF_PRESENT | // only devices present   
1988.                                                 DIGCF_INTERFACEDEVICE)); // function class devices.   
1989.   
1990.     if (hardwareDeviceInfo == INVALID_HANDLE_VALUE)   
1991.     {   
1992.         // return true to indicate something may have changed   
1993.         return true;   
1994.     }   
1995.   
1996.     deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);   
1997.   
1998.     while (!bDone)   
1999.     {   
2000.         if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,   
2001.                                             0, // don't care about specific PDOs   
2002.                                             &hidGuid,   
2003.                                             i,   
2004.                                             &deviceInfoData))   
2005.         {   
2006.             //   
2007.             // allocate a function class device data structure to receive the   
2008.             // goods about this particular device.   
2009.   
2010.             SetupDiGetDeviceInterfaceDetail (   
2011.                     hardwareDeviceInfo,   
2012.                     &deviceInfoData,   
2013.                     NULL, // probing so no output buffer yet   
2014.                     0, // probing so output buffer length of zero   
2015.                     &requiredLength,   
2016.                     NULL); // not interested in the specific dev-node   
2017.   
2018.   
2019.             predictedLength = requiredLength;   
2020.   
2021.             functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new UCHAR[predictedLength];   
2022.             if (functionClassDeviceData)   
2023.             {   
2024.                 ZeroMemory (functionClassDeviceData, predictedLength);   
2025.                 functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);   
2026.             }   
2027.             else   
2028.             {   
2029.                 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);   
2030.   
2031.                 // return true to indicate something may have changed   
2032.                 return true;   
2033.             }   
2034.   
2035.             //   
2036.             // retrieve the information from Plug and Play.   
2037.             //   
2038.   
2039.             if (! SetupDiGetDeviceInterfaceDetail (   
2040.                         hardwareDeviceInfo,   
2041.                         &deviceInfoData,   
2042.                         functionClassDeviceData,   
2043.                         predictedLength,   
2044.                         &requiredLength,   
2045.                         NULL))   
2046.             {   
2047.                 SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);   
2048.                 delete [] functionClassDeviceData;   
2049.   
2050.                 // return true to indicate something may have changed   
2051.                 return true;   
2052.             }   
2053.   
2054.             HidDeviceArrival(functionClassDeviceData->DevicePath);   
2055.   
2056.             delete [] functionClassDeviceData;   
2057.         }   
2058.         else   
2059.         {   
2060.             if (GetLastError() == ERROR_NO_MORE_ITEMS)   
2061.             {   
2062.                 bDone = true;   
2063.             }   
2064.         }   
2065.           
2066.         i++;   
2067.     }   
2068.   
2069.     return bRetVal;   
2070. }   
2071.   
2072. // makes sure the HID device does not already exist in the list,   
2073. // and then creates a new HID device device, opens a handle to   
2074. // the device, adds the new HID device to the list, and registers   
2075. // event notification for this new HID device   
2076. void CHidManager::HidDeviceArrival(PCHAR pDevicePath)   
2077. {   
2078.     // attempt to match a HID device in the list   
2079.     // based on the device path provided, if not then   
2080.     // it is okay to add this HID device to the list   
2081.     // otherwise the HID device already exists in our   
2082.     // list   
2083.     if (!GetHidDeviceWithPath(pDevicePath))   
2084.     {   
2085.         // this HID device is not in our list, so create   
2086.         // a new one and attempt to add it to the list   
2087.         CHidDevice *pNewHidDevice = NewHidDevice(pDevicePath);   
2088.   
2089.         if (pNewHidDevice)   
2090.         {   
2091.             // make sure we can open a handle to   
2092.             // the HID device before we add it   
2093.             // to the list   
2094.             if (pNewHidDevice->OpenHidDevice())   
2095.             {   
2096.                 // handle to the HID device open, so   
2097.                 // now add it to the list and register   
2098.                 // it for event notification   
2099.                 AddHidDevice(pNewHidDevice);   
2100.                 pNewHidDevice->RegisterHidDevice(m_hWnd);   
2101.             }   
2102.             else   
2103.             {   
2104.                 // could not open handle, so just delete   
2105.                 // the HID device craeated   
2106.                 DeleteHidDevice(pNewHidDevice);   
2107.             }   
2108.         }   
2109.     }   
2110. }   
2111.   
2112. // readies the HID device for removal by making sure the handle is closed,   
2113. // this version expects the device path   
2114. void CHidManager::HidDeviceQueryRemoval(PCHAR pDevicePath)   
2115. {   
2116.     CHidDevice *pHidDevice = GetHidDeviceWithPath(pDevicePath);   
2117.   
2118.     if (pHidDevice)   
2119.     {   
2120.         pHidDevice->CloseHidDevice();   
2121.     }   
2122. }   
2123.   
2124. // readies the HID device for removal by making sure the handle is closed,   
2125. // this version expects a handle to the device   
2126. void CHidManager::HidDeviceQueryRemoval(HANDLE hHidDevice)   
2127. {   
2128.     CHidDevice *pHidDevice = GetHidDeviceWithHandle(hHidDevice);   
2129.   
2130.     if (pHidDevice)   
2131.     {   
2132.         pHidDevice->CloseHidDevice();   
2133.     }   
2134. }   
2135.   
2136. // removes the HID device, this version expects the   
2137. // device path   
2138. void CHidManager::HidDeviceRemoval(PCHAR pDevicePath)   
2139. {   
2140.     CHidDevice *pHidDevice = GetHidDeviceWithPath(pDevicePath);   
2141.   
2142.     if (pHidDevice)   
2143.     {   
2144.         RemoveHidDevice(pHidDevice);   
2145.     }   
2146. }   
2147.   
2148. // removes the HID device, this version expects a   
2149. // handle to the device   
2150. void CHidManager::HidDeviceRemoval(HANDLE hHidDevice)   
2151. {   
2152.     CHidDevice *pHidDevice = GetHidDeviceWithHandle(hHidDevice);   
2153.   
2154.     if (pHidDevice)   
2155.     {   
2156.         RemoveHidDevice(pHidDevice);   
2157.     }   
2158. }   
2159.   
2160. /* 
2161. // the global (static) callback function for the CHidManager window 
2162. LRESULT PASCAL CHidManager::WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
2163. { 
2164.     CHidManager* pHidManager = m_pThis; 
2165.   
2166.     // make sure our window is the target for this message 
2167.     if (pHidManager->GetSafeHwnd() == hWnd) 
2168.     {   
2169.         if (message == WM_DEVICECHANGE) 
2170.         { 
2171.             PDEV_BROADCAST_HDR broadcastHdr = (PDEV_BROADCAST_HDR) lParam; 
2172.   
2173.             if (wParam == DBT_DEVICEARRIVAL) 
2174.             { 
2175.                 if (broadcastHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 
2176.                 { 
2177.                     PDEV_BROADCAST_DEVICEINTERFACE pBroadcastInterface = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; 
2178.   
2179.                     // HID device arrival 
2180.                     pHidManager->HidDeviceArrival(pBroadcastInterface->dbcc_name); 
2181.                 } 
2182.             } 
2183.             else if (wParam == DBT_DEVICEQUERYREMOVE) 
2184.             { 
2185.                 // if this message is received, the device is either 
2186.                 // being disabled or removed through device manager. 
2187.                 // To properly handle this request, we need to close 
2188.                 // the handle to the device. 
2189.   
2190.                 if (broadcastHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 
2191.                 { 
2192.                     PDEV_BROADCAST_DEVICEINTERFACE pBroadcastInterface = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; 
2193.   
2194.                     // HID device query removal 
2195.                     pHidManager->HidDeviceQueryRemoval(pBroadcastInterface->dbcc_name); 
2196.                 } 
2197.                 else if (broadcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) 
2198.                 { 
2199.                     PDEV_BROADCAST_HANDLE pBroadcastDevice = (PDEV_BROADCAST_HANDLE) lParam; 
2200.   
2201.                     // HID device query removal 
2202.                     pHidManager->HidDeviceQueryRemoval(pBroadcastDevice->dbch_handle); 
2203.                 } 
2204.             } 
2205.             else if ((wParam == DBT_DEVICEREMOVEPENDING) || (wParam == DBT_DEVICEREMOVECOMPLETE)) 
2206.             { 
2207.                 // do the same steps for DBT_DEVICEREMOVEPENDING and   
2208.                 // DBT_DEVICEREMOVECOMPLETE   
2209.                   
2210.                 // the DBT_DEVICEREMOVECOMPLETE request is not called 
2211.                 // for a device if it is disabled or removed via   
2212.                 // the Device Manager, however, in this case it will   
2213.                 // receive the DBT_DEVICEREMOVEPENDING   
2214.   
2215.                 // remove the device from our currently displayed 
2216.                 // list of devices and unregister notification 
2217.   
2218.                 if (broadcastHdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) 
2219.                 { 
2220.                     PDEV_BROADCAST_DEVICEINTERFACE pBroadcastInterface = (PDEV_BROADCAST_DEVICEINTERFACE) lParam; 
2221.   
2222.                     // HID device removal 
2223.                     pHidManager->HidDeviceRemoval(pBroadcastInterface->dbcc_name); 
2224.                 } 
2225.                 else if (broadcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) 
2226.                 { 
2227.                     PDEV_BROADCAST_HANDLE pBroadcastDevice = (PDEV_BROADCAST_HANDLE) lParam; 
2228.   
2229.                     // HID device removal 
2230.                     pHidManager->HidDeviceRemoval(pBroadcastDevice->dbch_handle); 
2231.                 } 
2232.             } 
2233.         } 
2234.         else if (message == WM_UNREGISTER_HANDLE) 
2235.         { 
2236.             ::UnregisterDeviceNotification ( (HDEVNOTIFY) lParam );   
2237.         } 
2238.     } 
2239.   
2240.     // now the process the message, just default it 
2241.     return ::DefWindowProc(hWnd, message, wParam, lParam); 
2242. } 
2243. */ </hidmgr_supported_hid_devices;i++)></dbt.h> 


Por otro lado , en la pagina de Cypress Semiconductor hay unos programas , no se si servira alguno de ellos:

http://www.cypress.com/?rID=39531&source=header


Espero que sea algo de ayuda.
sip... hasta eso mismo había llegado yo, pero me gustaría el fuente completo, que por otro lado debería estar en la web que indicas, pero he mirado antes, y no he localizado nada, al menos no por las referencias que se ven en el fuente, lo de lWirelessUSB.... blah, blah.. blah...

almeria27 escribió:He estado buscando lo que has puesto (...)
bueno, como ya le dije al usuario que los vende, esto estara bien para empezar, y eso es lo que ha sido. Depender de gente para que te saquen los firms es lo que tiene, que cuando han vendido demasiado, ya les da bastante igual. Pero bueno, yo lo que pague, ya lo he amortizado.
Os recomiendo a todos que os pilleis algun otro en dealextreme o paginas asi, que os cuesta 4 duras y mientras llega, unas cuatro semanas, sigais tirando del amaze.
Joder.. ya hay hasta update para la mayoría de chips con 3.50 Spoofing.... y nosotros mirando al techo [+furioso]

Abra que bombardearl3s el mail pidiéndoles el update por narices !
Por si alguien aun busca un amazebreak barato, en DX lo tienen a 8 dolares. Según comentan la gente que ya lo ha recibido de DX es original, o si no lo es almenos es totalmente compatible con las actus oficiales de amazebreak. Lo malo es lo que tardan en mandarlo de DX, HongKong Post está saturado estos días, parece.

Un saludo!
Así es, lo mejor ahora mismo lo mejor es pillar cualquier plaquita de desarrollo que permita meterle tu propio código (ojo, que de los dongles conocidos, muy pocos permiten que les metas tu propio código, y acabará pasando lo que con el amaze a pesar de ser más caros). Al final la metjor solución son los Amaze v1 tuneados para meterles bootloader :)

Yo ya me he cansado de los chinos, ya ni me responden a los mails, así que que los den por culo.

imanol25 escribió:bueno, como ya le dije al usuario que los vende, esto estara bien para empezar, y eso es lo que ha sido. Depender de gente para que te saquen los firms es lo que tiene, que cuando han vendido demasiado, ya les da bastante igual. Pero bueno, yo lo que pague, ya lo he amortizado.
Os recomiendo a todos que os pilleis algun otro en dealextreme o paginas asi, que os cuesta 4 duras y mientras llega, unas cuatro semanas, sigais tirando del amaze.
c0d3m4st4 escribió:Así es, lo mejor ahora mismo lo mejor es pillar cualquier plaquita de desarrollo que permita meterle tu propio código (ojo, que de los dongles conocidos, muy pocos permiten que les metas tu propio código, y acabará pasando lo que con el amaze a pesar de ser más caros).


Estaba a punto de pedirme una amaze de DX por el precio q tienen, pero vistos estos problemas de actualizacion, mejor miro otra cosa, q plaquita me recomendarias?
Haber si no tardan demasiado que la que hay me acabo de dar cuenta que es para la 3.15
Joder, y yo que me he pillado uno de estos que aún no me ha llegado con la esperanza de que lo actualizaran ...

Al final he caído y me he comprado un PSGroopic que funciona muy bien, y tiene online e incluso el spoof del 3.50, y a todo esto esperando aún a que me llegue el amazebreak.
Si se consigue poder , meterles nosotros mismo , hex a este dongle , que no sea dependiendo de ellos , seria todo un logro, y creo que como codemaster o yo , es mas una causa de investigar que otra cosa, yo al online no le he doy a la ps3, pero si que me gustaria poder utilizarlo cuando quiera , yo sigo buscnado mas informacion sobre el amaze.

Por cierto el problema que veo con el HID_ReadWrite , en las paginas que he puesto es que es de pago, para poder descargar algo , tienes que ser VIP, previo pago .


Un saludo.
c0d3m4st4 creo haber dado con el chip que lleva nuestro aparatito y considero que es un avance bastante importante, el modelo en cuestion es Cypress Semiconductor SL811HST-AXC.
Aqui dejo una imagen:
Imagen
Juraria que es el nuestro, mirarlo y decirme que os parece.
Con lo bien q va el psgroopic y nsotros sufriendo con este cacharro.Esperemos q se solucione rapido y no hayams pagado parea nada macho.
podría ser, aunque el precio tumba un poco la teoría... $8.57 por unidad, más que el amazebreak completo xD

aiitooreet escribió:c0d3m4st4 creo haber dado con el chip que lleva nuestro aparatito y considero que es un avance bastante importante, el modelo en cuestion es Cypress Semiconductor SL811HST-AXC.
Aqui dejo una imagen:
Imagen
Juraria que es el nuestro, mirarlo y decirme que os parece.
c0d3m4st4 escribió:podría ser, aunque el precio tumba un poco la teoría... $8.57 por unidad, más que el amazebreak completo xD

aiitooreet escribió:c0d3m4st4 creo haber dado con el chip que lleva nuestro aparatito y considero que es un avance bastante importante, el modelo en cuestion es Cypress Semiconductor SL811HST-AXC.
Aqui dejo una imagen:
Imagen
Juraria que es el nuestro, mirarlo y decirme que os parece.

En esto tienes razon, pero nose, a simple vista parece el mismo [sonrisa]
Jus, pues vaya putada que estos no actualicen. Lo que no entiendo es que puedan sacarlo para las 3.15 y no para la 3.41.

saludos
Y si este cacharro no funciona on line cual me recomendarian que me comprara??!?
LordJohn escribió:a lo mejor la van a unir en una sola, con la actualización para las versiones de firm 3.42 y 3.50 =D


Puedes esperar sentado, una actualización con soporte 3.42 y 3.50... Nadie ha dicho que las vayan a sacar, son pajas mentales de algunos.
lol me acaba de llegar , nada sólo queda esperar a ver si lo actualizan , mmm a una mala se podía pedir que liberaran o explicaran su software :\ q mala noticia, aunque bueno personamente no juego online a la ps3.
aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.



--
Jose A. Merino





ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.
Hombre, en el fondo, tiene razón, las tiendas no son las que sacan el software, aunque deberían ser las primeras en presionar al fabricante.

Redlm1986 escribió:aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, http://www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.



--
Jose A. Merino





ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.
Redlm1986 escribió:aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, http://www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.

--
Jose A. Merino


ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.


A mi lo que me parece una verguenza es que te dirijas así a un simple distribuidor, él no es el fabricante, el no desarrolla el software, él sólamente distribuye el producto, y hace una cosa que ni debería hacer que es poner las descargas del software a tu disposión y no está obligado a ello.

Como ya he dicho, no se pasan la pelota si no que ellos no son quienes tienen que solucionar ese tema.

Por otro lado que muestres tanta indignación y que te dirijas a ellos de tan malas formas no lo veo ni medio lógico. Este team no está dejando tirado a nadie, tarden más tarden menos van solucionando los problemas y actualizando su software para la satisfacción del cliente.

Seguramente si no presionarais tanto y fuérais más cordiales las atualizaciones serían mejores ya que si trabajas con presión para que salga rápido y los nenes se callen la boca muy bien no puede salir...

Un saludo
Diego_Sanchez escribió:
Redlm1986 escribió:aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, http://www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.

--
Jose A. Merino


ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.


A mi lo que me parece una verguenza es que te dirijas así a un simple distribuidor, él no es el fabricante, el no desarrolla el software, él sólamente distribuye el producto, y hace una cosa que ni debería hacer que es poner las descargas del software a tu disposión y no está obligado a ello.

Como ya he dicho, no se pasan la pelota si no que ellos no son quienes tienen que solucionar ese tema.

Por otro lado que muestres tanta indignación y que te dirijas a ellos de tan malas formas no lo veo ni medio lógico. Este team no está dejando tirado a nadie, tarden más tarden menos van solucionando los problemas y actualizando su software para la satisfacción del cliente.

Seguramente si no presionarais tanto y fuérais más cordiales las atualizaciones serían mejores ya que si trabajas con presión para que salga rápido y los nenes se callen la boca muy bien no puede salir...

Un saludo

+1 ellos no tienen nada que ver con software solo distribuyen el amaze en españa.
Redlm1986 escribió:aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, http://www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.



--
Jose A. Merino





ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.



http://www.amazebreak.cc/Download.asp

2010-11-12
Amazebreak upgradefile08
Connect PSN without upgrade your console to FW3.50 (for 3.15, not for 3.41).
Notice: maybe BAN your console with this file, pls be careful to use it.
新升级文件,有被锁机的可能,建议不用


ya salio
mlorenzo escribió:
Redlm1986 escribió:aqui teneis lo q me han dixo los desgraciaos de amazebreak españa esta mañana.

Asunto*: reclamacion
>
> Mensaje*: Me parece una verguenza el soporte que estais dando todos los dongles estan actualizados en cuestion de horas para poder usar el online encima q vuestro dongle lo unico q hace es usar el trabajo realizado por hermes y lucraros de ello no sois capaces de portar el parxe para jugar online de manera eficaz para q funcione en la version 3.41.espero una contestacion a mail sobre si estais trabajando en ello o realmente lo unico q haceis es copiar el trabajo de terceros q hacen de manera desinteresada y gratuita.
>
>
>
>
>
>
>
>
>
Muy buenas,

Nosotros somos simples distribuidores en España, no tenemos nada que ver
ni en el hardware ni en el software. Si tienes alguna queja respecto al
software o al hardware de amazebreak dirígete directamente al
fabricante, http://www.amazebreak.cc

Nosotros no podemos hacer otra cosa, esperemos que salga la
actualizacion pronto.

Un saludo.



--
Jose A. Merino





ESTOS tios se pasan la pelota y se cagan no tienen verguenza a mi punto de ver un saludo y espero q deis vuestra opinion.



http://www.amazebreak.cc/Download.asp

2010-11-12
Amazebreak upgradefile08
Connect PSN without upgrade your console to FW3.50 (for 3.15, not for 3.41).
Notice: maybe BAN your console with this file, pls be careful to use it.
新升级文件,有被锁机的可能,建议不用


ya salio


Fijate que pone para 3.15 no para 3.41 , y que no es el que viene con lo de 3.50 Spoofing.
La actualizacion llegará, mientras tanto disfrutemos de nuestros backups.
No echemos la culpa a los distribuidores, que no tienen nada que ver con el software,
gracias a ellos tenemos el amaze aquí,... y barato.

Saludos, juguemos y.... un poco de paciencia .
.
Amigo Redlm1986 , esta muy bien que te sientas indignado, por haber realizado una compra de un dongle, que su fabricante , no esta siendo capaz (en breve tiempo) satisfacer a sus clientes con las actualizaciones, pero creo que ese mismo email deberias de mandarselo a : support@amazebreak.cc que son los que realmnete deberian de solucionar el tema de las actualizaciones.


Un saludo.
1082 respuestas