Blog de ILINFO

Trucs et astuces

Blog ILINFO Active DIrectory MIIS LDAP ADAM PCA PRA BCP DRP

Log in

SetupDiOpenDeviceInterface returns ERROR_INVALID_USER_BUFFER in C#

by Emmanuel Dreux avril 16, 2009 00:30

Lors du développement de l'outil USBLIST disponible en téléchargement sur mon site, je me suis arraché les cheveux pendant un bon moment sur l'appel de SetupDiOpenDeviceInterface en CSHARP  (C#). En effet cette API n'est pas exposée dans ce langage et il faut appeler la fonction native de setupapi.dll par pinvoke. Cependant tous mes appels se sont soldés par une erreur ERROR_INVALID_USER_BUFFER sans comprendre pourquoi. Les recheches sur Internet et les questions sur les forums se sont révélées infructueuses et aucun exemple de code source fonctionnel n'était disponible pour s'en inspirer.

Le seul moyen de trouver la cause du problème a été de développer un exemple en C++ et de comparer son exécution en assembleur avec le programme en C# pour comprendre les différences.

Voici les extraits clés de la session de debugging:

SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
DeviceInterfaceData.cbSize =
sizeof(DeviceInterfaceData);[...]
if (SetupDiOpenDeviceInterface(
 DeviceInfoSet,
 lpdbv2->dbcc_name,
 0,
 &DeviceInterfaceData
 )== 0)

Au breakpoint suivant, l'instruction compare la taille de DeviceInterfaceData.cbSize. Le registre ecx contient la valeur de la donnée.

eax=76d9c680 ebx=76d9c65c ecx=0012fa14 edx=00000000 esi=00000000 edi=001e2c28
eip=76cbca46 esp=0012f460 ebp=0012f464 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SETUPAPI!DeviceInterfaceDataFromNode+0x3a:
76cbca46 83391c          cmp     dword ptr [ecx],1Ch  ds:0023:0012fa14=0000001c
0:000> dd ecx
0012fa14  0000001c cccccccc cccccccc cccccccc
0012fa24  cccccccc cccccccc cccccccc cccccccc
0012fa34  cccccccc 001e2c28 cccccccc cccccccc
0012fa44  001e22f8 cccccccc cccccccc cccccccc
0012fa54  cccccccc cccccccc 001e22f8 cccccccc
0012fa64  cccccccc cccccccc cccccccc cccccccc
0012fa74  cccccccc cccccccc cccccccc cccccccc
0012fa84  cccccccc cccccccc cccccccc cccccccc


Le même code en # (apparemment)!

SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA(); // Note it should be SP_DEVICE_INTERFACE_DATA but the structures are identical
// DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);
DeviceInfoData.cbSize = 28;
if (!SetupDiOpenDeviceInterfaceA(
    hDev,
    // dvi.dbcc_name,
    @"\\?\USB#VID_07AB&PID_FCCA#FW520_200000000000B703#{a5dcbf10-6530-11d2-901f-00c04fb951ed}",
    0,
    ref DeviceInfoData))

Le breakpoint à la même instruction:

0:000> t
Breakpoint 1 hit
eax=76d9c680 ebx=76d9c65c ecx=002aeaac edx=00000000 esi=00000000 edi=005f70c0
eip=76cbca46 esp=002ae820 ebp=002ae824 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
setupapi!DeviceInterfaceDataFromNode+0x3a:
76cbca46 83391c          cmp     dword ptr [ecx],1Ch  ds:0023:002aeaac=00612a18

0:000> dd 002aeaac
002aeaac  00612a18 00196fd8 5c3f5c5c 23425355
002aeabc  5f444956 42413730 44495026 4343465f
002aeacc  57462341 5f303235 30303032 30303030
002aeadc  30303030 33303742 35617b23 66626364
002aeaec  362d3031 2d303335 32643131 3130392d
002aeafc  30302d66 66343063 31353962 007d6465
002aeb0c  00196c00 002aeb24 79e7b080 00000006
002aeb1c  00196ca8 00000006 002aeb30 79e7b06b
0:000> dd poi(ecx)
00612a18  0000001c 00000000 00000000 00000000
00612a28  00000000 00000000 00000000 abababab
00612a38  abababab feeefeee 00000000 00000000
00612a48  63574a97 00000e3e 00612ae0 00581fc0

Forcément, ça plante  car ecx ne contient pas 0000001C mais l'adresse mémoire où est stocké 1C. La fonction sort donc en erreur et retourne 0x6f8 ERROR_INVALID_USER_BUFFER

Pour résumer,
En C++ , ecx contient la longueur de la structure.

En c#, par contre, ecx contient l'adresse mémoire de la longueur de la structure.

Pour résoudre le problème, il a suffit de remplacer la classe SP_DEVINFO_DATA par une structure qui n'a donc pas besoin d'être instanciée.

Le code source est disponible ici: http://www.ilinfo.fr/docs/DeviceInformation.cs

Post Original : http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/2eca9b5d-fd96-4181-943f-3157a09020f0

 

 

 

 

Soyez le premier à noter ce billet

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

c# | Développement

Partenaires
Assurez votre plan de continuit� d'activit� avec BCPAnywhere
Votre poste de travail partout dans le monde.

Mig6 votre solution de migration de vos postes de travail vers Windows 7
Migrez de XP vers Windows 7 avec Mig6.

Auteur

Freelance, Indépendant, expert Active Directory, Domaine et Sécurité.

Expert MIIS, ILM, FIM 2010,Kerberos, NTLM, SSL, PKI et chiffrement.