WriteFile auf USB-Handle schlägt fehl



  • Hallo C++-Forum,

    das ist dann wohl mein erster Post hier. Gleich vorweg: Ich komm aus der Java-Welt, habe zwar Erfahrung mit C und C++, das allerdings nur unter Linux. Entwicklung unter Windows und .NET ist etwas neues für mich, von daher bitte mit Nachsicht reagieren wenn ich dumme Fragen stelle / mich dumm ausdrücke ^^

    Ich versuche gerade über USB mit einem HID-PIC zu kommunizieren. Ich habe mich durch die API-Dokumentation durchgearbeitet und alles schaut eigentlich sehr gut aus, ich kann den Geräte-Pfad auslesen und ein Datei-Handle erzeugen - alles bestens.

    Nur bei dem Versuch auf das Gerät zu schreiben tritt der Fehler 87 - "Falscher Parameter" auf. Ich hab im Netz ein paar Tutorials zum Thema USB/HID-Kommunikation durchlesen und keine nennenswerten Unterschiede zu meinem Code gefunden - ich bin also ratlos wo der Fehler liegen könnte.

    Wenn ich das USB-Handle testweise durch ein gewöhnliches Festplatten-Datei-Handle ersetze, bleibt zwar der Fehler aus, die Datei suche ich jedoch vergebens auf der Platte.

    Der Code zum öffnen der Datei und zum Schreiben:

    //.... 
    if ((gcnew String((WCHAR*) DeviceInterfaceDetailData->DevicePath))->Contains("vid_04d8&pid_0064")) {
    			printf("Thermosnake gefunden!\n");
    
    			HANDLE UsbHandle = CreateFile(DeviceInterfaceDetailData->DevicePath,
    					                    GENERIC_READ | GENERIC_WRITE,
    					                    FILE_SHARE_READ | FILE_SHARE_WRITE,
    										NULL,
    										OPEN_EXISTING,
    										FILE_ATTRIBUTE_NORMAL,
    										NULL);
    
    			if (UsbHandle == INVALID_HANDLE_VALUE)
    				error(L"Invalid Handle Value.");
    
    			DWORD written = 0;
    
    			if (!WriteFile(UsbHandle,
    						   "test",
    				           4,
    						   &written,
    				           NULL))
    			{
    				error(L"Fehler beim Schreiben!");
    			}
    
    			if (!CloseHandle(UsbHandle))
    				error(L"Fehler beim Schließen des Datei-Handles.");
    }
    //....
    

    Ich hoffe, jemand kann mir bei dieser Sache weiterhelfen, ich bin zumindest mit meinem Latein am Ende 😞

    Viele Grüße und gute Nacht,
    Robs!



  • Falsches Forum: besser wäre Win32

    Obwohl Du .NET verwendest hängt das Problem mit den nativen Win32 API Funktionen CreateFile(..), etc. zusammen.

    BTW: http://www.c-plusplus.net/forum/viewtopic-var-t-is-263084.html

    Simon



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • theta schrieb:

    Falsches Forum: besser wäre Win32

    Obwohl Du .NET verwendest hängt das Problem mit den nativen Win32 API Funktionen CreateFile(..), etc. zusammen.

    BTW: http://www.c-plusplus.net/forum/viewtopic-var-t-is-263084.html

    Simon

    Ja, falsches Forum, sehe ich ein.

    Mit dem Link willst du mir vermutlich sagen, dass du die Wahl der Sprache fragwürdig findest. Zur Kenntniss genommen - hatte ohnehin vor mich gegebener Zeit auf C-Sharp zu stürzen.

    Aber mit meinem WinAPI-Problem hat das ja alles nix zu tun.
    Vielleicht besteht der Fehler ja in der Deklaration der API-Aufrufe?

    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiGetClassDevs")]		
    extern "C" HDEVINFO  SetupDiGetClassDevsUM(
    	GUID *  ClassGuid,				
    	PCTSTR  Enumerator,				
    	HWND  hwndParent,				
    	DWORD  Flags);					
    
    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiEnumDeviceInterfaces")]				
    extern "C" WINSETUPAPI BOOL WINAPI  SetupDiEnumDeviceInterfacesUM(
    	HDEVINFO  DeviceInfoSet,				
    	PSP_DEVINFO_DATA  DeviceInfoData,		
    	GUID *  InterfaceClassGuid,				
    	DWORD  MemberIndex,						
    
    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiEnumDeviceInfo")]
    extern "C" WINSETUPAPI BOOL WINAPI  SetupDiEnumDeviceInfoUM(
    	HDEVINFO  DeviceInfoSet,
    	DWORD  MemberIndex,
    	PSP_DEVINFO_DATA  DeviceInfoData);
    
    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiDestroyDeviceInfoList")]
    extern "C" WINSETUPAPI BOOL WINAPI  SetupDiDestroyDeviceInfoListUM(			
    	HDEVINFO  DeviceInfoSet);				
    
    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiGetDeviceRegistryProperty")]
    extern "C"	WINSETUPAPI BOOL WINAPI  SetupDiGetDeviceRegistryPropertyUM(
    	HDEVINFO  DeviceInfoSet,
    	PSP_DEVINFO_DATA  DeviceInfoData,
    	DWORD  Property,
    	PDWORD  PropertyRegDataType,
    	PBYTE  PropertyBuffer,   
    	DWORD  PropertyBufferSize,  
    	PDWORD  RequiredSize);
    
    [DllImport("user32.dll" , EntryPoint="RegisterDeviceNotification")]					
    extern "C" HDEVNOTIFY WINAPI RegisterDeviceNotificationUM(
    	HANDLE hRecipient,
    	LPVOID NotificationFilter,
    	DWORD Flags);
    
    [DllImport("setupapi.dll" , CharSet = CharSet::Seeifdef, EntryPoint="SetupDiGetDeviceInterfaceDetail")]
    extern "C" WINSETUPAPI BOOL WINAPI SetupDiGetDeviceInterfaceDetailUM(
        HDEVINFO  DeviceInfoSet,
        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
        PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData,
        DWORD DeviceInterfaceDetailDataSize,
        PDWORD RequiredSize,
        PSP_DEVINFO_DATA DeviceInfoData);
    
    [DllImport("hid.dll" , EntryPoint="HidD_GetHidGuid")]					
    extern "C" void WINAPI HidD_GetHidGuidUM(
    	GUID * HidClassGuid);
    
    // .... 
    
    int _tmain(int argc, _TCHAR* argv[])
    {	
    	GUID HidClassGuid;
    	HDEVINFO DeviceInfoSet	= NULL;	
    	SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
    
    	ZeroMemory(&DeviceInterfaceData, sizeof(DeviceInterfaceData));
    	DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData);
    
    	HidD_GetHidGuidUM(&HidClassGuid);		
    	DeviceInfoSet = SetupDiGetClassDevsUM(&HidClassGuid,
    								   NULL,
    								   NULL,
    								   DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    
    	if (DeviceInfoSet == INVALID_HANDLE_VALUE) 
    		error(L"SetupDiGetClassDevs");
    
    	for(int index = 0; (SetupDiEnumDeviceInterfacesUM(DeviceInfoSet, NULL, &HidClassGuid, index, &DeviceInterfaceData)) ; index++) {
    
    		SP_DEVINFO_DATA DeviceInfoData;
    		DeviceInfoData.cbSize = sizeof(DeviceInfoData);
    
    		DWORD RequiredSize;
    
    		SetupDiGetDeviceInterfaceDetailUM(
    			DeviceInfoSet,
    			&DeviceInterfaceData,
    			NULL,
    			0,
    			&RequiredSize,
    			&DeviceInfoData
    		);
    
    		SP_DEVICE_INTERFACE_DETAIL_DATA *DeviceInterfaceDetailData = 
    			(SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(RequiredSize);
    
    		ZeroMemory(DeviceInterfaceDetailData, RequiredSize);
    
    		DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
    		if (!SetupDiGetDeviceInterfaceDetailUM(
    			DeviceInfoSet,
    			&DeviceInterfaceData,
    			DeviceInterfaceDetailData,
    			RequiredSize,
    			&RequiredSize,
    			&DeviceInfoData
    			)) {
    			error(L"SetupDiGetDeviceInterfaceDetail");
    		}
    
    		if ((gcnew String((WCHAR*) DeviceInterfaceDetailData->DevicePath))->Contains("vid_04d8&pid_0064")) {
    			printf("Thermosnake gefunden!\n");
    
    			HANDLE UsbHandle = CreateFile(DeviceInterfaceDetailData->DevicePath,
    					                    GENERIC_READ | GENERIC_WRITE,
    					                    FILE_SHARE_READ | FILE_SHARE_WRITE,
    										NULL,
    										OPEN_EXISTING,
    										FILE_ATTRIBUTE_NORMAL,
    										NULL);
    
    			if (UsbHandle == INVALID_HANDLE_VALUE)
    				error(L"Invalid Handle Value.");
    
    			DWORD written = 0;
    
    			if (!WriteFile(UsbHandle,
    						   "test",
    				           4,
    						   &written,
    				           NULL))
    			{
    				error(L"Fehler beim Schreiben!");
    			}
    
    			if (!CloseHandle(UsbHandle))
    				error(L"Fehler beim Schließen des Datei-Handles.");
    		}
    
    		free(DeviceInterfaceDetailData);
    	}
    
    	SetupDiDestroyDeviceInfoListUM(DeviceInfoSet);
    
    	#ifdef _DEBUG
    	printf("Alles okay!\nTaste druecken...");
    	wait();
    	#endif
    
    	return 0;
    }
    

    Hoffe, jemand hat eine Idee zur Problemlösung. Danke schonmal.

    Grüße,
    Robs!



  • Ist mein Problem zu trivial oder weiss wirklich keiner ne Antwort?? 😕



  • Der Problem hat sich erledigt - nun klappt alles. Mein Fehler. Nicht ordentlich nachgelesen. Für den Fall dass es jemandem mal ähnlich geht und derjenige dies hier liest: Die Buffergrößen und der Bufferinhalt müssen exakt den Eigenschaften des USB-Gerätes entsprechen (in Länge und Inhalt). Der Report bei meinem PIC ist zwar 8 Bytes lang, es wird jedoch ein führendes Nullbyte verlangt (kein Plan warum).

    / . . . 
    
    byte buffer[] = {0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    
    			if (!WriteFile(
    				UsbHandle,
    				buffer,
    				8+1,
    				&written,
    				NULL
    			)) {				
    				error(L"Fehler beim Schreiben!");
    			}
    
    / . . .
    

    Genaueres unter: http://www.mikrocontroller.net/topic/34052


Anmelden zum Antworten