DriverIteration MissMatch



  • Hallo,

    ich habe eine von ZDiag.exe erstellte *.inf Datei und diese enthält die GeräteGUID (MultiSerial) und die DriverGUID.

    Ausschnitt der Infdatei

    ;DigiUSB.inf
    ; Copyright (c) 2010-2014 libusb (GNU LGPL)
    [Strings]
    DeviceName = "DigiUSB"
    VendorName = "Van Ooijen Technische Informatica"
    SourceName = "DigiUSB Install Disk"
    DeviceID   = "VID_16C0&PID_05DF"
    DeviceGUID = "{23F89E5D-616F-4DA0-AA2B-D08123AFDF2C}"
    
    [Version]
    Signature   = "$Windows NT$"
    Class       = "Universal Serial Bus devices"
    ClassGuid   = {88bae032-5a81-49f0-bc3d-a4ff138216d6}
    Provider    = "libusb.info"
    CatalogFile = DigiUSB.cat
    DriverVer   = 06/18/2013, 6.1.7600.16385
    

    Nach der Installation des Treibers kann ich manuel den Key zum öffnen verwenden:

    AVROPENGUID {0x23F89E5D, 0x616F, 0x4DA0, {0xAA, 0x2B, 0xD0, 0x81, 0x23, 0xAF, 0xDF, 0x2C}}

    und erhalte unten den Path für den Treiber das Gerät kann dann verwendet werden.

    bool CAvrCtrl::RetrieveDevicePath(GUID avrguid)
    {
    	SP_DEVICE_INTERFACE_DATA         interfaceData = { 0 };
    	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
    	ULONG                            requiredLength = 0;
    
    	HDEVINFO deviceInfoSet(0);
    	interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    
    	if ((deviceInfoSet = SetupDiGetClassDevs(&avrguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE)
    		return false;
    
    	if (!SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &avrguid, 0, &interfaceData))
    	{
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	//Retrive the size
    	if(!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, NULL, 0, &requiredLength, NULL))
    	{
    		DWORD dwError = GetLastError();
    		if (dwError == ERROR_INSUFFICIENT_BUFFER || requiredLength == 0)
    		{
    			SetupDiDestroyDeviceInfoList(deviceInfoSet);
    			return false;
    		}
    	}
    
    	if (!(detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredLength)))
    	{
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
    	if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, detailData, requiredLength, &requiredLength, NULL))
    	{
    		LocalFree(detailData);
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	strcpy(&m_DevicePath[0], detailData->DevicePath);
    
    	LocalFree(detailData);
    	SetupDiDestroyDeviceInfoList(deviceInfoSet);
    
        return true;
    }
    

    Es ist so, das sich die DeviceGUID verändern kann in der *.inf Datei was immer bleibt ist die Product und Vendor ID.
    Also möchte ich über PID und VID den Treiber-Path finden, dazu verwende ich eine konforme getestete Deviceiteration von MicroSoft TechExample

    bool CAvrCtrl::EnumDriver(char *pVid, char *pPid)
    {
    	HDEVINFO        hDevInfo = 0L;
    	SP_DEVINFO_DATA spDevInfoData = { 0 };
    	short           wIndex = 0;
    
    	hDevInfo = SetupDiGetClassDevs(0L, 0L, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE);
    	if (hDevInfo == INVALID_HANDLE_VALUE)
    		return false;
    
    	spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    
    	while (SetupDiEnumDeviceInfo(hDevInfo, wIndex, &spDevInfoData))
    	{
    		char   szBuf[MAX_PATH] = { 0 };
    		char   szID[LINE_LEN]  = { 0 };
    		int    wImageIdx       = 0;
    		DWORD  dwRequireSize   = 0;
    
    		if (!SetupDiGetDeviceRegistryProperty(hDevInfo,&spDevInfoData,SPDRP_CLASS, 0L,(PBYTE)szBuf,2048,0))
    		{
    			wIndex++;
    			continue;
    		}
    
    		if (!SetupDiGetClassDescription(&spDevInfoData.ClassGuid,szBuf,MAX_PATH,&dwRequireSize))
    		{
    			wIndex++;
    			continue;
    		}
    
    		if (!SetupDiGetDeviceInstanceId(hDevInfo, &spDevInfoData, szID, LINE_LEN, 0))
    			;
    
    		SP_DEVICE_INTERFACE_DATA spDevInterfaceData = { 0 };
    
    		spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    		if (SetupDiCreateDeviceInterface(hDevInfo, &spDevInfoData, &spDevInfoData.ClassGuid, 0L, 0L, &spDevInterfaceData))
    		{
    			SP_DEVICE_INTERFACE_DETAIL_DATA *pspDevInterfaceDetail = 0L;
    			DWORD                           dwRequire = 0L;
    
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, 0L, 0, &dwRequire, 0L))
    			{
    				DWORD dwError = GetLastError();
    				if (dwError != ERROR_INSUFFICIENT_BUFFER)
    					return false;
    			}
    
    			pspDevInterfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA*)LocalAlloc(LPTR, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)*dwRequire);
    			pspDevInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, pspDevInterfaceDetail, dwRequire, &dwRequire, 0L))
    			{
    				DWORD dwError = GetLastError();
    				if (dwError != ERROR_INSUFFICIENT_BUFFER)
    					;
    			}
    			else
    			{
    				if (strstr(pspDevInterfaceDetail->DevicePath, pVid) && strstr(pspDevInterfaceDetail->DevicePath, pPid))
    				{
    					strcpy(&m_DevicePath[0], pspDevInterfaceDetail->DevicePath);
    					puts(&m_DevicePath[0]);
    				}
    			}
    
    			if (pspDevInterfaceDetail)
    				LocalFree(pspDevInterfaceDetail);
    		}
    
    		wIndex++;
    	}
    
    	SetupDiDestroyDeviceInfoList(hDevInfo);
    
    	return true;
    }
    

    Hier erhalte ich über PID und VID einen Path auf das Gerät, auch die Anschlussnummern stimmen.

    Was aber nicht stimmt ist die GeräteGUID am Ende des Pathe's diese unterscheidet sich zu der aus der *.inf Datei was zur Folge hat,
    das dieses Gerät mit CreateFile nicht geöffnet wird.

    Der über die GeräteGUID erzeugte Path :
    "\\\?\\usb#vid_16c0&pid_05df#5&1257636a&0&3#{23f89e5d-616f-4da0-aa2b-d08123afdf2c}"

    Der über die Iteration erzugte Path:
    "\\\?\\usb#vid_16c0&pid_05df#5&1257636a&0&3#{88bae032-5a81-49f0-bc3d-a4ff138216d6}"

    Warum ist die über die Iteration erzeugte GeräteGUID mit einem Key versehen den ich nicht kenne, und das System auch nicht ?

    Vielen Dank für Hinweise ich lege mir bereits die Karten...
    Karsten aus Berlin



  • {88bae032-5a81-49f0-bc3d-a4ff138216d6} ist die ClassGUID , die steht sogar in deinem .ini File.

    Und nachdem der Code als InterfaceClassGuid die ClassGUID an SetupDiCreateDeviceInterface übergibt, muss man sich nicht wundern dass SetupDiCreateDeviceInterface den Pfad mit der ClassGUID zurückgibt.



  • Hi Hustebär.

    Ja genau, die ID wird einfach an den Path angehangen.
    Was ich erwartet habe war, das die Funktion den Path auf das iterierte Objekt
    vollkommen herstellt.

    Diese GeräteGUID steht sogar in der Registry das hat die *.inf Datei beim
    Installieren gemacht. Immer wenn der Treiber mangels Certificate mit ZDiag neu erstellt wird, erzeugt dieser eine neue GUID in der *.Inf.

    Nun gibt es Iterationsmethoden die schauen direkt in die Registry, aber
    ich finde keine äqualEnz in den Beispielen via SetupDiGetDeviceRegistryProperty
    um genau diese DeviceGUID zu erlangen.

    Dann habe ich mir eine *.inf selber hergestellt, denn angeblich brauche ich keinen Treiber für ein "Universal Serial Bus device" dieses hat eine eigene
    Class GUID als Standard Gerät (23F89E5D-616F-4DA0-AA2B-D08123AFDF2C).

    Also sieht eine selber gemachte *.inf so aus:

    ;
    ;
    ; Installs WinUsb
    ;
    
    [Version]
    Signature = "$Windows NT$"
    Class     = USBDevice
    ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
    Provider  = %ManufacturerName%
    CatalogFile = WinUSBInstallation.cat
    DriverVer=09/04/2012,13.54.20.543
    
    ; ========== Manufacturer/Models sections ===========
    
    [Manufacturer]
    %ManufacturerName% = Standard,NTamd64
    
    [Standard.NTamd64]
    %DeviceName% =USB_Install, USB\VID_16C0&PID_05DF
    
    ; ========== Class definition ===========
    
    [ClassInstall32]
    AddReg = ClassInstall_AddReg
    
    [ClassInstall_AddReg]
    HKR,,,,%ClassName%
    HKR,,NoInstallClass,,1
    HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
    HKR,,LowerLogoVersion,,5.2
    
    ; =================== Installation ===================
    
    [USB_Install]
    Include = winusb.inf
    Needs   = WINUSB.NT
    
    [USB_Install.Services]
    Include =winusb.inf
    Needs   = WINUSB.NT.Services
    
    [USB_Install.HW]
    AddReg=Dev_AddReg
    
    [Dev_AddReg]
    HKR,,DeviceInterfaceGUIDs,0x10000,"{9f543223-cede-4fa3-b376-a25ce9a30e74}"
    
    ; [DestinationDirs]
    ; If your INF needs to copy files, you must not use the DefaultDestDir directive here.  
    ; You must explicitly reference all file-list-section names in this section.
    
    ; =================== Strings ===================
    
    [Strings]
    ManufacturerName="FlexxVision"
    ClassName="Universal Serial Bus devices"
    DeviceName="Fx2 Learning Kit Device"
    REG_MULTI_SZ = 0x00010000
    

    Hier fehlt mir schon die *.cat (Certificate Datei für ein WinUSB Treiber, ich weiß nicht woher die kommen soll, es gibt Tools im DDK , wie die nun das Certificate für ein WinUSB Device erstellen bleibt mir leider verborgen.

    Ich habe 3 Möglichkeiten, entweder der User Verwendet ZDiag.exe um ein TreiberKit zu erstellen, dann muss ich aber die besagte DeviceGUID in der Registry finden. Zb. mit : SetupDiGetDeviceRegistryProperty
    Das hat aber nicht funktioniert.

    Oder ich muss die TreiberCertifizierung abschalten um mit dem besagten Key direkt das Gerät zu öffnen, was auch funktiniert.

    Oder ich muss das bekannte libusb verwenden, was auf jeden neuen Rechner bei der Installation eine neue besagte GUID erzeugt.

    Ich wollte natürlich einfach auf das Standard Gerät über pid und vid die im bootloader meiner Hardware steht das Teil anrufen. (So wie ein JoyStick z.B.)

    Weißt Du ob das überhaupt geht mit einer *.inf ohne Treiber das Standard WinUsb Gerät zu öffnen ?

    Danke für deine Antwort,
    Grüße aus "The DriversHell"
    Karsten



  • Wenn du kein eigenes .sys File hast, brauchst du erstmal kein Zertifikat und musst nix signieren. Beim Installieren kommt dann ein grosser böser roter Warn-Dialog, aber wenn man da auf "trotzdem" klickt installiert Windows den Treiber.

    (Wenn alle beteiligten .sys Files passend von ihrem jeweiligen Ersteller signiert wurden, dann lädt Windows die auch wenn sie über ein nicht-signiertes .inf File installiert wurden.)

    Soviel 'mal dazu.

    Ansonsten...
    Leider verstehe ich bei vielen Sachen nicht was du eigentlich meinst. Und leider ist meine Erfahrung mit diesen Dingen auch schon etwas länger her. Heisst: ich kann dir nicht wirklich viel weiter helfen.

    Was "*.inf ohne Treiber" angeht: ja, klar, geht. Wenn Windows passende Treiber hat, und man Windows über das .inf File mitteilt dass es diese verwenden soll, dann haut das schon hin. Gibt z.B. einige USB-RS232 Chips die mit dem Treiber von Windows funktionieren aber ein .inf File brauchen damit Windows "versteht" dass dieser Treiber passt. z.B. sowas:
    http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=MCP2200EV-VCP
    Wenn du dir den "Treiber" von dem Ding anguckst, der besteht auch bloss aus einem .cat und einem .inf File das dann auf den "usbser" Treiber von Windows verweist.

    Hier fehlt mir schon die *.cat (Certificate Datei für ein WinUSB Treiber, ich weiß nicht woher die kommen soll, es gibt Tools im DDK , wie die nun das Certificate für ein WinUSB Device erstellen bleibt mir leider verborgen.

    Probier's mal ohne .cat File. Sollte, nach "trotzdem"-klicken im grossen bösen Warndialog auch so gehen. Oder erstell ein nicht-signiertes .cat File (Tools dazu sind im DDK enthalten - weiss den Filenamen aber grad nicht auswendig).
    Bzw. Tools zum Signieren, wenn du das willst/brauchst, sind natürlich auch im DDK enthalten. Bloss brauchst du dafür ein Zertifikat. Und das musst du kaufen. Kostenpunkt so um die €250 +/- für ein 1 Jahr gültiges Zertifikat.

    Dann habe ich mir eine *.inf selber hergestellt, denn angeblich brauche ich keinen Treiber für ein "Universal Serial Bus device" dieses hat eine eigene
    Class GUID als Standard Gerät (23F89E5D-616F-4DA0-AA2B-D08123AFDF2C).

    Was ist das denn für ein Gerät, und über welches Protokoll willst du mit dem plaudern?



  • Hallo,

    danke für deine Ausführung,

    Was ist das denn für ein Gerät, und über welches Protokoll willst du mit dem plaudern?

    Es gibt ca 32 Geräteklassen, darunter, GUID_DEVCLASS_MULTIPORTSERIAL
    definiert in devguide.h (Kits WDK's)

    Der Bootloader des USB -Gerätes sendet beim einstecken einen equalenten Gerätecode an Windowsder bestimmt in welcher klasse es gelistet wird, z.B Joystic maus keyborad. Das verwendete meldet sich als Standard Hid-Input.

    Nachdem ich nun eine ini selber erstellt habe, verweißt diese auf das Standard
    .sys und .dll System von WinUSB.

    diese inf ist aber mit einem Certificat verbunden, nach der Installation der inf Datei. Wird aus dem Hid-Input gerät ein Universal Serial device.

    Und das ohne eine fremde Software , alles von Windows.

    Hier die Inf.

    ;DigiUSB.inf
    ;Copyright (c) 2010-2014 libusb (GNU LGPL)
    [Strings]
    DeviceName = "DigiUSB"
    VendorName = "Van Ooijen Technische Informatica"
    SourceName = "DigiUSB Install Disk"
    DeviceID = "VID_16C0&PID_05DF"
    **DeviceGUID = "{AC7BF289-B241-493B-8E87-BB8F06763DA4}"
    **
    [Version]
    Signature = "WindowsNTWindows NT"
    Class = **"Universal Serial Bus devices"
    **ClassGuid = {88bae032-5a81-49f0-bc3d-a4ff138216d6}
    Provider = "libusb.info"
    CatalogFile = **DigiUSB.cat
    **DriverVer = 06/18/2013, 6.1.7600.16385

    [ClassInstall32]
    Addreg = WinUSBDeviceClassReg

    [WinUSBDeviceClassReg]
    HKR,,,0**,"Universal Serial Bus devices"**
    HKR,,Icon,,-20

    [Manufacturer]
    %VendorName% = libusbDevice_WinUSB,NTx86,NTamd64,NTia64

    [libusbDevice_WinUSB.NTx86]
    %DeviceName% = USB_Install, USB\%DeviceID%

    [libusbDevice_WinUSB.NTamd64]
    %DeviceName% = USB_Install, USB\%DeviceID%

    [libusbDevice_WinUSB.NTia64]
    %DeviceName% = USB_Install, USB\%DeviceID%

    [USB_Install]
    Include = winusb.inf
    Needs = WINUSB.NT

    [USB_Install.Services]
    **Include = winusb.inf
    **AddService = WinUSB,0x00000002,WinUSB_ServiceInstall

    [WinUSB_ServiceInstall]
    DisplayName = "WinUSB - Kernel Driver 06/18/2013 6.1.7600.16385"
    ServiceType = 1
    StartType = 3
    ErrorControl = 1
    **ServiceBinary = %12%\WinUSB.sys
    **
    [USB_Install.Wdf]
    KmdfService = WINUSB, WinUsb_Install

    [WinUSB_Install]
    KmdfLibraryVersion = 1.9

    [USB_Install.HW]
    AddReg = AddDeviceInterfaceGUID

    [NoDeviceInterfaceGUID]
    ; Avoids adding a DeviceInterfaceGUID for generic driver

    [AddDeviceInterfaceGUID]
    HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%

    [USB_Install.CoInstallers]
    AddReg = CoInstallers_AddReg
    CopyFiles = CoInstallers_CopyFiles

    [CoInstallers_AddReg]
    HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"

    [CoInstallers_CopyFiles]
    **WinUSBCoInstaller2.dll
    WdfCoInstaller01009.dll
    **
    [DestinationDirs]
    CoInstallers_CopyFiles = 11

    [SourceDisksNames]
    1 = %SourceName%

    [SourceDisksFiles.x86]
    WinUSBCoInstaller2.dll = 1,x86
    WdfCoInstaller01009.dll = 1,x86

    [SourceDisksFiles.amd64]
    WinUSBCoInstaller2.dll = 1,amd64
    WdfCoInstaller01009.dll = 1,amd64

    [SourceDisksFiles.ia64]
    WinUSBCoInstaller2.dll = 1,ia64
    WdfCoInstaller01009.dll = 1,ia64

    Aber.

    Die verbindet sich über den Eintrag :
    **DeviceGUID = "{AC7BF289-B241-493B-8E87-BB8F06763DA4}"
    **
    mit einem Zertifizierten Catalog.cat der im selben Ordner liegt und von einer Anwendung zdiag erstellt wird. (brauch ich eigentlich nicht)

    Über diese DeviceGUID kann ich direkt das Geraät öffnen wenn ich dessen pid und vid auch kenne, der logische Path ist dann:

    **"\\\?\\usb#vid_16c0&pid_05df#5&1257636a&0&3#{ac7bf289-b241-493b-8e87-bb8f06763da4}"
    **

    Dieser DeviceGUID wird in der registry in einem geschützten Bereich hinterlegt:

    Windows Registry Editor Version 5.00
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_16C0&PID_05DF\5&1257636a&0&3\Device Parameters]
    "DeviceInterfaceGUIDs"=hex(7):7b,00,41,00,43,00,37,00,42,00,46,00,32,00,38,00,\
      39,00,2d,00,42,00,32,00,34,00,31,00,2d,00,34,00,39,00,33,00,42,00,2d,00,38,\
      00,45,00,38,00,37,00,2d,00,42,00,42,00,38,00,46,00,30,00,36,00,37,00,36,00,\
      33,00,44,00,41,00,34,00,7d,00,00,00,00,00
    "EnumerationRetryCount"=dword:00000000
    "SymbolicName"="\\??\\USB#VID_16C0&PID_05DF#5&1257636a&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
    
    [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB[b]VID_16C0&PID_05DF[/b]\5&1257636a&0&3\Device Parameters\Ceip]
    "DeviceInformation"=dword:00000000
    

    Ich konnte den Key auch nicht mit OpenRegEx (read) öffnen, scheint gelockt zu sein.

    Ich bekomme diesen Key über keine der sämtlich vorhanden Iterationsmöglichkeiten, es sei denn ich würde die *.inf öffnen.

    Nur mit diesem Key kann ich also das Gerät öffnen, es kommuniziert über
    sogenannte Configurations -Messages die jeder Treiber inne hat:

    WinUsb_ControlTransfer(..);

    Ich kann nun fröhlich bis zu 1kb/s Daten mit dem Device tauschen. Alles wunderbar solange ich den Code
    **DeviceGUID = "{AC7BF289-B241-493B-8E87-BB8F06763DA4}"
    **
    Kenne. Jedwede Änderung über Provider oder Creator in der *.inf Datei
    führt dazu, das das Gerät wieder verschwindet und in Standard Hid-Input
    verfällt. Treiberinstallation wird ungültig. Auf fremden Rechnern
    erfolgt die Meldung Zertifizierung Fehlgeschlagen ,Ende der Installation.

    Lösche ich das *.cat file (dies ist es was zertifiziert ist) funktiniert
    die Treiberinstallation nicht mehr, ohne Warnung verschwindet das Gerät.

    Alle Verweise in der *.inf zeigen auf Windows system32 files. Die
    auf höhe der *.inf Datei als Kopie vorliegen in den Foldern
    x86 und amdx64

    Die rote Box mit dem "weiter" kommt immer dann, wenn alles wunderbar lief.

    Kommt sie nicht, fand auch nichts statt. (z.b wenn ich die Catalog.cat Datei lösche)

    Im Moment versuche ich ne konforme Methode zu finden diese DeviceGUID zu erlangen. Weil- Das Catalog.cat mit dieser verbunden scheint. Mein Generator für die "ur" *.inf von ZDiag. erzeugt diese cataloge, und jede neue *.inf hat ne andere DeviceID.
    Auf einem fremden Rechner kann ich den Treiber mit dem catalog.cat und der DeviceID nicht mehr installieren.

    Ich probiere Weiter, ein sehr übles, schwer durchschaubares Theater.

    Sollte man sich mit beschäftigen 🙂
    http://digistump.com/products/1

    Danke für deine Hinweise
    gruß
    Karsten

    So siehts aus gerade:

    Header:

    #pragma once
    
    #include <Windows.h>
    
    typedef unsigned long (*AVRGETCLASSPTR) (void);
    
    #ifndef AVR
    #define AVR
    
    #ifdef ACRSTATIC //use static usement without LoadLibrary
    	#ifdef _DEBUG
    	 #pragma comment(lib, "AvrOpenD.lib")
    	#else
    	 #pragma comment(lib, "AvrOpen.lib")
    	#endif
    	extern "C" __declspec(dllimport) unsigned long AvrGetClassPtr(void);
    #endif
    
    #endif
    
    typedef class CVTableAvrCtrl
    {
    public:
    	CVTableAvrCtrl() {};
    	~CVTableAvrCtrl() {};
    public:
    	virtual bool Create(char *pVid, char *pPid) { return false;}
    	virtual void Delete(void) {}
    	virtual bool PutCharacter(unsigned char bdat) { return false; }
    	virtual bool GetCharacter(unsigned char *pChar) { return false; }
    }CVAVRCTRL;
    
    typedef class CAvrCtrl : public CVTableAvrCtrl
    {
    public:
    	CAvrCtrl();
    	~CAvrCtrl();
    public:
    	bool Create(char *pVid, char *pPid);
    	void Delete(void);
    	bool PutCharacter(unsigned char bdat);
    	bool GetCharacter(unsigned char *pChar);
    private:
    	void          *m_WinusbHandle;
    	void          *m_DeviceHandle;
    	char           m_DevicePath[MAX_PATH];
    	bool           RetrieveDevicePath(GUID avrguid);
    	bool           EnumDriver(char *pVid, char *pPid);
    
    	unsigned char  m_dat;
    	unsigned long  m_cbLen;
    
    }AVRCTRL;
    

    Code:

    #include "AvrOpen.h"
    #include <winusb.h>
    #include <SetupAPI.h>
    #include <strsafe.h>
    #include <guiddef.h>
    #include <devguid.h>
    #include <regstr.h>
    
    //Digispark bootloader need packets to communicate
    WINUSB_SETUP_PACKET g_WritePacket = { (1 << 5) | 0x00,0x09,NULL,NULL,sizeof(UCHAR) };//form out SendPack sendchar comes into index!
    WINUSB_SETUP_PACKET g_ReadPacket  = { (1 << 5) | 0x80,0x01,NULL,NULL,sizeof(UCHAR) };//form out RecPack  
    
    /* visit
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\Vid_067b&Pid_2303
    */
    
    #ifdef _DEBUG
    void Error(void)//usefull to extract error text
    {
    	LPVOID lpMsgBuf;
    	LPVOID lpDisplayBuf;
    	DWORD  dw = GetLastError();
    	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
    	lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)"ERR") + 40) * sizeof(TCHAR));
    	StringCchPrintf((LPTSTR)lpDisplayBuf, LocalSize(lpDisplayBuf) / sizeof(TCHAR), TEXT("%s failed with error %d: %s"), "ERR", dw, lpMsgBuf);
    	MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
    	LocalFree(lpMsgBuf);
    	LocalFree(lpDisplayBuf);
    }
    #endif
    
    //this comes from DevMgr Example
    bool CAvrCtrl::EnumDriver(char *pVid, char *pPid)
    {
    	HDEVINFO        hDevInfo = 0L;
    	SP_DEVINFO_DATA spDevInfoData = { 0 };
    	short           wIndex = 0;
    
    	//iterate only device classes
    	//GUID devclass = GUID_DEVCLASS_MULTIPORTSERIAL;
    	//hDevInfo = SetupDiGetClassDevs(&devclass, 0L, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE | DIGCF_DEVICEINTERFACE);
    
    	//iterate all device classes
    	hDevInfo = SetupDiGetClassDevs(0, 0L, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE | DIGCF_DEVICEINTERFACE);
    	if (hDevInfo == INVALID_HANDLE_VALUE)
    		return false;
    
    	spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    
    	while(SetupDiEnumDeviceInfo(hDevInfo, wIndex, &spDevInfoData))
    	{
    		char   szBuf[MAX_PATH] = { 0 };
    		char   szID[LINE_LEN]  = { 0 };
    		int    wImageIdx       = 0;
    		DWORD  dwRequireSize   = 0;
    
    		if (!SetupDiGetDeviceRegistryProperty(hDevInfo,&spDevInfoData,SPDRP_CLASS, 0L,(PBYTE)szBuf,2048,0))
    		{
    			wIndex++;
    			continue;
    		}
    
    		if (!SetupDiGetClassDescription(&spDevInfoData.ClassGuid,szBuf,MAX_PATH,&dwRequireSize))
    		{
    			wIndex++;
    			continue;
    		}
    
    		if (!SetupDiGetDeviceInstanceId(hDevInfo, &spDevInfoData, szID, LINE_LEN, 0))
    			;
    
    		SP_DEVICE_INTERFACE_DATA spDevInterfaceData = { 0 };
    
    		spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    		if (SetupDiCreateDeviceInterface(hDevInfo, &spDevInfoData, &spDevInfoData.ClassGuid, 0L, 0L, &spDevInterfaceData))
    		{
    			SP_DEVICE_INTERFACE_DETAIL_DATA *pspDevInterfaceDetail = 0L;
    			DWORD                           dwRequire = 0L;
    
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, 0L, 0, &dwRequire, 0L))
    			{
    				DWORD dwError = GetLastError();
    				if (dwError != ERROR_INSUFFICIENT_BUFFER)
    					return false;
    			}
    
    			pspDevInterfaceDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA*)LocalAlloc(LPTR, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)*dwRequire);
    			pspDevInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    			if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, pspDevInterfaceDetail, dwRequire, &dwRequire, 0L))
    			{
    				DWORD dwError = GetLastError();
    				if (dwError == ERROR_INSUFFICIENT_BUFFER)
    					;
    			}
    
    			if (strstr(pspDevInterfaceDetail->DevicePath, pVid) && strstr(pspDevInterfaceDetail->DevicePath, pPid))
    			{
    				strcpy(&m_DevicePath[0], pspDevInterfaceDetail->DevicePath);
    
    				if (pspDevInterfaceDetail)
    					LocalFree(pspDevInterfaceDetail), pspDevInterfaceDetail = 0;
    
    				puts(&m_DevicePath[0]);
    				break;
    			}
    
    			if (pspDevInterfaceDetail)
    				LocalFree(pspDevInterfaceDetail), pspDevInterfaceDetail=0;
    		}
    
    		wIndex++;
    	}
    
    	// iterate some infos but the DriverGUID is not available
    	for (int n(SPDRP_DEVICEDESC); n <= SPCRP_MAXIMUM_PROPERTY; n++)
    	{
    		BYTE szName[MAX_PATH]; 
    		if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, n, 0L, (PBYTE)szName, MAX_PATH, 0))
    		{
    			puts((char *)&szName[0]);
    		}
    	}
    
    	SetupDiDestroyDeviceInfoList(hDevInfo);
    
    	return true;
    }
    
    CAvrCtrl::CAvrCtrl() : m_WinusbHandle(0),m_DeviceHandle(0),m_dat(0),m_cbLen(0)
    {
    }
    
    CAvrCtrl::~CAvrCtrl()
    {
    }
    
    void CAvrCtrl::Delete(void)
    {
    	memset(&m_DevicePath[0],0,sizeof(&m_DevicePath[0]));
    
    	if (m_WinusbHandle) WinUsb_Free(m_WinusbHandle),m_WinusbHandle=0;
    	if (m_DeviceHandle) CloseHandle(m_DeviceHandle), m_DeviceHandle=0;
    }
    
    bool CAvrCtrl::Create(char *pVid,char *pPid)
    {
    	Delete();
    
    	EnumDriver(pVid,pPid);//This dynamic generated Path is wrong, at end there give the ClassGUID need is the DeviceGUID from *.inf
    
    	//So we make the DeviceGuid direct from *.inf manual. Turn Of Windows Driver Certification!
    	#define AVROPENGUID {0xAC7BF289, 0xB241, 0x493B, {0x8E, 0x87, 0xBB, 0x8F, 0x06, 0x76, 0x3D, 0xA4}}
    	RetrieveDevicePath(AVROPENGUID);
    
    	if (!strlen(&m_DevicePath[0])) //No devicePath
    		return false;
    
    	if ((m_DeviceHandle = CreateFile(&m_DevicePath[0], GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL)) == INVALID_HANDLE_VALUE)
    	{
    		Delete();
    		return false;
    	}
    
    	if (WinUsb_Initialize(m_DeviceHandle, &m_WinusbHandle) == FALSE)
    	{
    		Delete();
    		return false;
    	}
    
    	return true;
    }
    
    bool CAvrCtrl::RetrieveDevicePath(GUID avrguid)
    {
    	SP_DEVICE_INTERFACE_DATA         interfaceData = { 0 };
    	PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL;
    	ULONG                            requiredLength = 0;
    
    	HDEVINFO deviceInfoSet(0);
    	interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
    
    	if ((deviceInfoSet = SetupDiGetClassDevs(&avrguid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)) == INVALID_HANDLE_VALUE)
    		return false;
    
    	if (!SetupDiEnumDeviceInterfaces(deviceInfoSet, NULL, &avrguid, 0, &interfaceData))
    	{
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	//Retrive the size
    	if(!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, NULL, 0, &requiredLength, NULL))
    	{
    		DWORD dwError = GetLastError();
    		if (dwError != ERROR_INSUFFICIENT_BUFFER || requiredLength == 0)
    		{
    			SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		    return false;
    		}
    	}
    
    	if (!(detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredLength)))
    	{
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
    	if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &interfaceData, detailData, requiredLength, &requiredLength, NULL))
    	{
    		LocalFree(detailData);
    		SetupDiDestroyDeviceInfoList(deviceInfoSet);
    		return false;
    	}
    
    	strcpy(&m_DevicePath[0], detailData->DevicePath);
    	LocalFree(detailData);
    	SetupDiDestroyDeviceInfoList(deviceInfoSet);
    
        return true;
    }
    
    bool CAvrCtrl::GetCharacter(unsigned char *pDat)
    {
    	//------------- Recieve -----------------
    
    	return WinUsb_ControlTransfer(m_WinusbHandle, g_ReadPacket, pDat, sizeof(UCHAR), &m_cbLen, 0) && m_cbLen == 1;
    }
    
    bool CAvrCtrl::PutCharacter(unsigned char bdat)
    {
    	//------------- Transmit -----------------
    	g_WritePacket.Index    = bdat; //to send information byte put it here
    
    	return WinUsb_ControlTransfer(m_WinusbHandle, g_WritePacket, &m_dat, sizeof(UCHAR), &m_cbLen, 0) && m_cbLen == 1;
    }
    


  • Jedwede Änderung über Provider oder Creator in der *.inf Datei
    führt dazu, das das Gerät wieder verschwindet und in Standard Hid-Input
    verfällt. Treiberinstallation wird ungültig. Auf fremden Rechnern
    erfolgt die Meldung Zertifizierung Fehlgeschlagen ,Ende der Installation.

    Lösche ich das *.cat file (dies ist es was zertifiziert ist) funktiniert
    die Treiberinstallation nicht mehr, ohne Warnung verschwindet das Gerät.

    Welche Windows Version verwendest du?

    Ich hab auf jeden Fall relativ problemlos Treiber unter Windows 7 x64 installiert bekommen, sofern alle .sys Files passend signiert waren - ohne .cat File!

    Und hast du probiert nicht nur das .cat File zu löschen sondern zusätzlich den Verweis auf das .cat File im .inf File zu löschen? Ich könnte mir nämlich gut vorstellen dass Windows verweigert wenn im .inf File drinnen steht dass es ein .cat File gibt, dieses dann aber nicht finden kann.

    Und ansonsten kannst du immer noch ein "self signed" Certificate erstellen, und das .cat File dann mit diesem signieren. Dabei kommt dann auch ne Warning, aber wenn man die bestätigt dann lässt sich das .inf File installieren.
    (Bzw. wenn du das selbst signierte Zertifikat als "trusted CA" installierst, dann sollte es auch ohne Warnung gehen.)

    Gibt haufenweise Anleitungen im Internet, z.B.
    http://woshub.com/how-to-sign-an-unsigned-driver-for-windows-7-x64/
    https://msdn.microsoft.com/en-us/library/windows/hardware/dn741535(v=vs.85).aspx
    https://technet.microsoft.com/en-us/library/dd919238(v=ws.10).aspx
    http://www.richud.com/wiki/Windows_7_Install_Unsigned_Drivers_CAT_fix

    Bei einigen steht dass du Windows in den "test signing mode" schalten musst. Das kannst du machen, ist aber nur nötig wenn du auch ein .sys File signieren musst. Wenns nur um das .inf File geht, frisst zumindest Windows 7 x64 selbst-signierte .cat Files auch so.
    Zu neueren Windows Versionen kann ich nichts definitives sagen - musst du ggf. selbst ausprobieren 🙂



  • Das werde ich gleich ausprobieren, der verweis auf das cat ist ja dumm.



  • Hi,

    Es ist Windows10 32

    also der versuch das catalogfile und den Verweis darauf zu entfernen
    führte dazu, das sich das Gerät als : HID-compilant vendor defined
    abbildet, das ist eine andere Geräteklasse, ich denke das hat keinen
    Treiber mehr, trotz (roter installer Box, aber nichts passiert)

    Ich forsche mal weiter da ist der Wurm drin.

    http://visiongrid.de/drv.jpg



  • Hallo,

    ich habe alle verweise auf catalog.cat entfernt.

    Normal verwende ich eine Batchdatei die den Treiber(*inf) dynamisch anmeldet.

    @echo off
    if "%PROCESSOR_ARCHITECTURE%" == "x86" (
      start "driver setup x86" "%~dp0\dpinst32.exe"
    
    ) else (
      start "driver setup x64" "%~dp0\dpinst64.exe"
    )
    

    Das funktioniert aber nur wenn der Treiber ein Certificat hat, ansonnsten
    wird zwar alles installiert, aber ohne Fehlermeldung fällt das Gerät im Anschluss in eine Treiberlose Hid-Gerätekalsse Installation also failed.

    Jetzt kommts:

    Nur wenn ich über den Gerätemanager als Admin das Gerät mit Auswahl der *.Inf Datei anmelde wird wieder ein Universal Standard Gerät daraus.

    Und alles funktioniert. Das heißt man kann unsignierte Treiber nur mit der Hand
    anmelden, soweit der Stand .. Das hat mich viele duzende Stunden gekostet.

    Manchmal ist es wichtig mit anderen zu reden, um neue Handlungen auszulösen, der gute Programmierer macht selten etwas anders als sonnst ^^

    Danke der Hinweise
    grüße und Erfolg
    Karsten



  • Oh, wenn ich geahnt hätte dass du den Treiber nicht mit Hand installierst hätte ich gleich 'was gesagt 😉

    Was automatisierte Installation angeht kannst du mal DevCon Update probieren:
    https://msdn.microsoft.com/en-us/library/windows/hardware/ff544832(v=vs.85).aspx

    The DevCon Update operation forces an update to the most appropriate drivers in the specified INF file, even if those drivers are older or less appropriate than the current drivers or the drivers in a different INF file.
    (...)
    DevCon prompts the user if the INF file specifies an unsigned driver or if it cannot find a required file, such as a driver file on removable media. To suppress prompts that require a response, use the noninteractive update operation, DevCon UpdateNI.

    Ganz ohne Nachfrage wird's vermutlich nicht gehen. Zumindest steht bei DevCon UpdateNI nix zum Verhalten bei unsignierten Treibern. Aber probier's einfach aus, vielleicht geht's ja doch.



  • Sehr gut,

    das werde ich noch erforschen, und die Zumutung über den HandJob erstmal
    sacken lassen ...

    Hier die Geniale *inf Datei mit der man irgendetwas am USB Port als
    Universal Serial Gerät registert , was man braucht ist is die PID/VID
    Und eine ausgedachte Geräte ID die man kennen muss. Da sie im System
    nicht iterierbar ist.

    Es bedarf keiner weiteren Dateien nur die *.inf muss man erstmal haben....

    Übrigens für Windows XP bis 10 gültig wegen : KmdfLibraryVersion = 1.0

    ; KeyMan.inf
    ; Copyright (c) 1998-2015 FlexxVision 
    [Strings]
    DeviceName = "KeyMan"
    VendorName = "FlexxVision"
    SourceName = "KeyMan Install Disk"
    DeviceID   = "VID_16C0&PID_05DF"
    DeviceGUID = "{EEBE3F79-3A2A-4304-9791-EBF0E998E93F}"
    
    [Version]
    Signature   = "$Windows NT$"
    Class       = "Universal Serial Bus devices"
    ClassGuid   = {88bae032-5a81-49f0-bc3d-a4ff138216d6}
    Provider    = "FlexxVision"
    DriverVer   = 06/18/2013, 6.1.7600.16385
    
    [ClassInstall32]
    Addreg = WinUSBDeviceClassReg
    
    [WinUSBDeviceClassReg]
    HKR,,,0,"Universal Serial Bus devices"
    HKR,,Icon,,-20
    
    [Manufacturer]
    %VendorName% = FlexxVision_WinUSB,NTx86,NTamd64,NTia64
    
    [FlexxVision_WinUSB.NTx86]
    %DeviceName% = USB_Install, USB\%DeviceID%
    
    [FlexxVision_WinUSB.NTamd64]
    %DeviceName% = USB_Install, USB\%DeviceID%
    
    [FlexxVision_WinUSB.NTia64]
    %DeviceName% = USB_Install, USB\%DeviceID%
    
    [USB_Install]
    Include = winusb.inf
    Needs   = WINUSB.NT
    
    [USB_Install.Services]
    Include    = winusb.inf
    AddService = WinUSB,0x00000002,WinUSB_ServiceInstall
    
    [WinUSB_ServiceInstall]
    DisplayName   = "WinUSB - Kernel Driver 06/18/2013 6.1.7600.16385"
    ServiceType   = 1
    StartType     = 3
    ErrorControl  = 1
    ServiceBinary = %12%\WinUSB.sys
    
    [USB_Install.Wdf]
    KmdfService = WINUSB, WinUsb_Install
    
    [WinUSB_Install]
    KmdfLibraryVersion = 1.0
    
    [USB_Install.HW]
    AddReg = AddDeviceInterfaceGUID
    
    [NoDeviceInterfaceGUID]
    ; Avoids adding a DeviceInterfaceGUID for generic driver
    
    [AddDeviceInterfaceGUID]
    HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID%
    HKR,,FriendlyName,,"KeyMan"   
    
    [USB_Install.CoInstallers]
    AddReg    = CoInstallers_AddReg
    CopyFiles = CoInstallers_CopyFiles
    
    [CoInstallers_AddReg]
    HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll"
    
    [CoInstallers_CopyFiles]
    WinUSBCoInstaller2.dll
    WdfCoInstaller01009.dll
    
    [DestinationDirs]
    CoInstallers_CopyFiles = 11
    


  • Achromat schrieb:

    was man braucht ist is die PID/VID
    Und eine ausgedachte Geräte ID die man kennen muss. Da sie im System
    nicht iterierbar ist.

    Ach doch, das muss irgendwie gehen, ich weiss bloss nicht wie 🕶


Log in to reply