diff --git a/edge-ai-platform/tools/test_driver_install/main.go b/edge-ai-platform/tools/test_driver_install/main.go index f81e3c5..40d66de 100644 --- a/edge-ai-platform/tools/test_driver_install/main.go +++ b/edge-ai-platform/tools/test_driver_install/main.go @@ -1,13 +1,15 @@ // Test tool for Windows USB driver installation. // Build: GOOS=windows GOARCH=amd64 go build -o test_driver_install.exe . // Run on Windows (as admin): -// .\test_driver_install.exe "C:\Users\User\AppData\Local\EdgeAIPlatform\drivers\kneron_winusb.inf" +// .\test_driver_install.exe "C:\Users\User\AppData\Local\EdgeAIPlatform\drivers" package main import ( "fmt" "os" + "os/exec" + "path/filepath" "strings" "syscall" "unsafe" @@ -15,7 +17,6 @@ import ( var ( setupapi = syscall.MustLoadDLL("setupapi.dll") - newdev = syscall.MustLoadDLL("newdev.dll") procSetupDiGetClassDevsW = setupapi.MustFindProc("SetupDiGetClassDevsW") procSetupDiEnumDeviceInfo = setupapi.MustFindProc("SetupDiEnumDeviceInfo") @@ -25,18 +26,14 @@ var ( procSetupDiCallClassInstaller = setupapi.MustFindProc("SetupDiCallClassInstaller") procSetupDiDestroyDevInfoList = setupapi.MustFindProc("SetupDiDestroyDeviceInfoList") procSetupDiBuildDriverInfoList = setupapi.MustFindProc("SetupDiBuildDriverInfoList") - - procUpdateDriverForPlugAndPlayDevicesW = newdev.MustFindProc("UpdateDriverForPlugAndPlayDevicesW") - procDiInstallDriverW = newdev.MustFindProc("DiInstallDriverW") ) const ( DIGCF_PRESENT = 0x00000002 DIGCF_ALLCLASSES = 0x00000004 - SPDRP_HARDWAREID = 0x00000001 - SPDRP_COMPATIBLEIDS = 0x00000002 - SPDRP_DEVICEDESC = 0x00000000 + SPDRP_HARDWAREID = 0x00000001 + SPDRP_DEVICEDESC = 0x00000000 DIF_SELECTBESTCOMPATDRV = 0x00000017 DIF_INSTALLDEVICE = 0x00000002 @@ -44,8 +41,6 @@ const ( DI_FLAGSEX_ALLOWEXCLUDEDDRVS = 0x00000800 DI_ENUMSINGLEINF = 0x00010000 - INSTALLFLAG_FORCE = 0x00000001 - DIIRFLAG_FORCE_INF = 0x00000002 SPDIT_COMPATDRIVER = 0x00000002 INVALID_HANDLE_VALUE = ^uintptr(0) @@ -71,10 +66,9 @@ type SP_DEVINSTALL_PARAMS_W struct { DriverPath [260]uint16 } -// multiSzToStrings parses a REG_MULTI_SZ buffer into individual strings func multiSzToStrings(buf []uint16, size uint32) []string { var result []string - count := size / 2 // byte count to uint16 count + count := size / 2 if count == 0 { return result } @@ -92,50 +86,237 @@ func multiSzToStrings(buf []uint16, size uint32) []string { func main() { if len(os.Args) < 2 { - fmt.Println("Usage: test_driver_install.exe ") - fmt.Println(" test_driver_install.exe --list") + fmt.Println("Usage: test_driver_install.exe ") + fmt.Println(" The directory should contain kneron_winusb.inf and amd64\\ co-installers") + os.Exit(1) + } + + driverDir := os.Args[1] + infPath := filepath.Join(driverDir, "kneron_winusb.inf") + fmt.Printf("Driver dir: %s\n", driverDir) + fmt.Printf("INF path: %s\n", infPath) + + if _, err := os.Stat(infPath); err != nil { + fmt.Printf("ERROR: %s not found: %v\n", infPath, err) os.Exit(1) } targetHWID := "USB\\VID_3231&PID_0100" - if os.Args[1] == "--list" { - listAllDevices(targetHWID) - return - } + // Step 1: List devices + fmt.Println("\n=== Step 1: List Kneron USB devices ===") + listKneronDevices(targetHWID) - infPath := os.Args[1] - fmt.Printf("INF path: %s\n", infPath) + // Step 2: Self-sign approach — create cert, create cat, sign, install + fmt.Println("\n=== Step 2: Create self-signed cert + catalog, then install ===") + certPath := filepath.Join(driverDir, "kneron_selfsign.cer") - if _, err := os.Stat(infPath); err != nil { - fmt.Printf("ERROR: file not found: %v\n", err) + // 2a: Create self-signed code signing cert via PowerShell + fmt.Println("[2a] Creating self-signed code signing certificate...") + thumbprint, err := createSelfSignedCert(certPath) + if err != nil { + fmt.Printf(" FAILED: %v\n", err) os.Exit(1) } + fmt.Printf(" Thumbprint: %s\n", thumbprint) - fmt.Println("") - fmt.Println("=== Step 1: List USB devices matching VID_3231 ===") - listAllDevices(targetHWID) + // 2b: Install cert to TrustedPublisher store + fmt.Println("[2b] Installing cert to TrustedPublisher + Root stores...") + installCertToStore(certPath, "TrustedPublisher") + installCertToStore(certPath, "Root") - fmt.Println("") - fmt.Println("=== Step 2: UpdateDriverForPlugAndPlayDevicesW ===") - tryUpdateDriver(infPath, targetHWID) + // 2c: Create .cat file using makecat.exe (from system) or manual approach + catPath := filepath.Join(driverDir, "kneron_winusb.cat") + fmt.Println("[2c] Creating catalog file...") + err = createCatalog(driverDir, infPath, catPath) + if err != nil { + fmt.Printf(" Catalog creation failed: %v\n", err) + fmt.Println(" Trying alternative approach without catalog...") + } - fmt.Println("") - fmt.Println("=== Step 3: DiInstallDriverW ===") - tryDiInstallDriver(infPath) + // 2d: Sign the catalog + if _, err := os.Stat(catPath); err == nil { + fmt.Println("[2d] Signing catalog file...") + signCatalog(catPath, thumbprint) + } - fmt.Println("") - fmt.Println("=== Step 4: SetupAPI direct device node install ===") - trySetupAPIInstall(infPath, targetHWID) + // 2e: Try pnputil with signed catalog + fmt.Println("[2e] Installing driver with pnputil...") + cmd := exec.Command("pnputil", "/add-driver", infPath, "/install") + out, err := cmd.CombinedOutput() + fmt.Printf(" pnputil: %s\n", strings.TrimSpace(string(out))) + if err != nil { + fmt.Printf(" pnputil error: %v\n", err) + // Fallback: try SetupAPI + fmt.Println("\n[2f] Fallback: SetupAPI DIF_INSTALLDEVICE...") + trySetupAPIInstall(infPath, targetHWID) + } else { + fmt.Println(" SUCCESS via pnputil!") + } + + fmt.Println("\n=== Done ===") } -func listAllDevices(targetHWID string) { - hDevInfo, _, err := procSetupDiGetClassDevsW.Call( - 0, 0, 0, - DIGCF_PRESENT|DIGCF_ALLCLASSES, - ) +func createSelfSignedCert(certPath string) (string, error) { + psScript := fmt.Sprintf(` +$ErrorActionPreference = 'Stop' +# Remove old cert if exists +Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Subject -eq 'CN=Kneron Edge AI Platform' } | Remove-Item -Force -ErrorAction SilentlyContinue +# Create new self-signed code signing cert +$cert = New-SelfSignedCertificate -Type CodeSigningCert -Subject "CN=Kneron Edge AI Platform" -CertStoreLocation Cert:\LocalMachine\My -NotAfter (Get-Date).AddYears(10) -FriendlyName "Kneron Edge AI Platform Driver Signing" +# Export DER cert +Export-Certificate -Cert $cert -FilePath '%s' -Force | Out-Null +Write-Output $cert.Thumbprint +`, certPath) + + cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psScript) + out, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("powershell: %v\nOutput: %s", err, string(out)) + } + + thumbprint := strings.TrimSpace(string(out)) + // Extract just the thumbprint (last line) + lines := strings.Split(thumbprint, "\n") + for i := len(lines) - 1; i >= 0; i-- { + line := strings.TrimSpace(lines[i]) + if len(line) == 40 { // SHA1 thumbprint length + return line, nil + } + } + return thumbprint, nil +} + +func installCertToStore(certPath, storeName string) { + cmd := exec.Command("certutil", "-addstore", storeName, certPath) + out, err := cmd.CombinedOutput() + outStr := strings.TrimSpace(string(out)) + if err != nil { + fmt.Printf(" certutil %s: FAILED - %v\n %s\n", storeName, err, outStr) + } else { + fmt.Printf(" certutil %s: OK\n", storeName) + } +} + +func createCatalog(driverDir, infPath, catPath string) error { + // Method 1: Try inf2cat from Windows SDK + sdkBases := []string{ + `C:\Program Files (x86)\Windows Kits\10\bin`, + } + sdkVersions := []string{ + "10.0.26100.0", "10.0.22621.0", "10.0.22000.0", "10.0.19041.0", "10.0.18362.0", + } + + for _, base := range sdkBases { + for _, ver := range sdkVersions { + inf2cat := filepath.Join(base, ver, "x86", "inf2cat.exe") + if _, err := os.Stat(inf2cat); err == nil { + fmt.Printf(" Found inf2cat: %s\n", inf2cat) + cmd := exec.Command(inf2cat, "/driver:"+driverDir, "/os:10_X64", "/verbose") + out, err := cmd.CombinedOutput() + outStr := strings.TrimSpace(string(out)) + fmt.Printf(" inf2cat output: %s\n", outStr) + if err == nil { + if _, err := os.Stat(catPath); err == nil { + return nil + } + } + fmt.Printf(" inf2cat error: %v\n", err) + } + } + } + + // Method 2: Create a minimal catalog using MakeCat.exe definition file + fmt.Println(" inf2cat not found, trying MakeCat approach...") + cdfPath := filepath.Join(driverDir, "kneron_winusb.cdf") + cdfContent := fmt.Sprintf(`[CatalogHeader] +Name=%s +PublicVersion=0x0000001 +EncodingType=0x00010001 +CATATTR1=0x10010001:OSAttr:2:10.0 + +[CatalogFiles] +kneron_winusb.inf=%s +`, catPath, infPath) + + if err := os.WriteFile(cdfPath, []byte(cdfContent), 0644); err != nil { + return fmt.Errorf("write CDF: %w", err) + } + defer os.Remove(cdfPath) + + cmd := exec.Command("makecat", "-v", cdfPath) + out, err := cmd.CombinedOutput() + outStr := strings.TrimSpace(string(out)) + fmt.Printf(" makecat output: %s\n", outStr) + if err != nil { + fmt.Printf(" makecat error: %v\n", err) + + // Method 3: Use PowerShell to create catalog via .NET + fmt.Println(" Trying PowerShell New-FileCatalog...") + psCmd := fmt.Sprintf(`New-FileCatalog -Path '%s' -CatalogFilePath '%s' -CatalogVersion 2.0`, driverDir, catPath) + cmd = exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psCmd) + out, err = cmd.CombinedOutput() + outStr = strings.TrimSpace(string(out)) + fmt.Printf(" New-FileCatalog: %s\n", outStr) + if err != nil { + return fmt.Errorf("all catalog creation methods failed") + } + } + + if _, err := os.Stat(catPath); err == nil { + return nil + } + return fmt.Errorf("catalog file not created") +} + +func signCatalog(catPath, thumbprint string) { + // Try signtool from Windows SDK + sdkBases := []string{`C:\Program Files (x86)\Windows Kits\10\bin`} + sdkVersions := []string{ + "10.0.26100.0", "10.0.22621.0", "10.0.22000.0", "10.0.19041.0", "10.0.18362.0", + } + + for _, base := range sdkBases { + for _, ver := range sdkVersions { + signtool := filepath.Join(base, ver, "x64", "signtool.exe") + if _, err := os.Stat(signtool); err == nil { + fmt.Printf(" Found signtool: %s\n", signtool) + cmd := exec.Command(signtool, "sign", "/sha1", thumbprint, "/fd", "SHA256", + "/s", "My", "/sm", "/v", catPath) + out, err := cmd.CombinedOutput() + outStr := strings.TrimSpace(string(out)) + fmt.Printf(" signtool: %s\n", outStr) + if err != nil { + fmt.Printf(" signtool error: %v\n", err) + } else { + return + } + } + } + } + + // Fallback: PowerShell Set-AuthenticodeSignature + fmt.Println(" signtool not found, trying Set-AuthenticodeSignature...") + psCmd := fmt.Sprintf(` +$cert = Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.Thumbprint -eq '%s' } +if ($cert) { + Set-AuthenticodeSignature -FilePath '%s' -Certificate $cert -HashAlgorithm SHA256 +} else { + Write-Error "Certificate not found" +} +`, thumbprint, catPath) + cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", psCmd) + out, err := cmd.CombinedOutput() + fmt.Printf(" PowerShell sign: %s\n", strings.TrimSpace(string(out))) + if err != nil { + fmt.Printf(" PowerShell sign error: %v\n", err) + } +} + +func listKneronDevices(targetHWID string) { + hDevInfo, _, err := procSetupDiGetClassDevsW.Call(0, 0, 0, DIGCF_PRESENT|DIGCF_ALLCLASSES) if hDevInfo == INVALID_HANDLE_VALUE { - fmt.Printf("ERROR: SetupDiGetClassDevsW: %v\n", err) + fmt.Printf("ERROR: %v\n", err) return } defer procSetupDiDestroyDevInfoList.Call(hDevInfo) @@ -143,41 +324,28 @@ func listAllDevices(targetHWID string) { var devInfoData SP_DEVINFO_DATA devInfoData.cbSize = uint32(unsafe.Sizeof(devInfoData)) - total := 0 - matched := 0 + total, matched := 0, 0 for i := uint32(0); ; i++ { - ret, _, _ := procSetupDiEnumDeviceInfo.Call( - hDevInfo, uintptr(i), - uintptr(unsafe.Pointer(&devInfoData)), - ) + ret, _, _ := procSetupDiEnumDeviceInfo.Call(hDevInfo, uintptr(i), uintptr(unsafe.Pointer(&devInfoData))) if ret == 0 { break } total++ - // Get hardware IDs (REG_MULTI_SZ) var buf [2048]uint16 var dataType, reqSize uint32 ret, _, _ = procSetupDiGetDeviceRegistryPropW.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - SPDRP_HARDWAREID, - uintptr(unsafe.Pointer(&dataType)), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(len(buf)*2), - uintptr(unsafe.Pointer(&reqSize)), + hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), SPDRP_HARDWAREID, + uintptr(unsafe.Pointer(&dataType)), uintptr(unsafe.Pointer(&buf[0])), + uintptr(len(buf)*2), uintptr(unsafe.Pointer(&reqSize)), ) if ret == 0 { continue } - hwids := multiSzToStrings(buf[:], reqSize) - - // Check if any HWID contains "VID_3231" or matches target isKneron := false for _, id := range hwids { - upper := strings.ToUpper(id) - if strings.Contains(upper, "VID_3231") { + if strings.Contains(strings.ToUpper(id), "VID_3231") { isKneron = true break } @@ -185,95 +353,34 @@ func listAllDevices(targetHWID string) { if !isKneron { continue } - matched++ - // Get device description var descBuf [512]uint16 ret, _, _ = procSetupDiGetDeviceRegistryPropW.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - SPDRP_DEVICEDESC, - uintptr(unsafe.Pointer(&dataType)), - uintptr(unsafe.Pointer(&descBuf[0])), - uintptr(len(descBuf)*2), - uintptr(unsafe.Pointer(&reqSize)), + hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), SPDRP_DEVICEDESC, + uintptr(unsafe.Pointer(&dataType)), uintptr(unsafe.Pointer(&descBuf[0])), + uintptr(len(descBuf)*2), uintptr(unsafe.Pointer(&reqSize)), ) - desc := "(no description)" + desc := "(unknown)" if ret != 0 { desc = syscall.UTF16ToString(descBuf[:]) } - - fmt.Printf("\n Device #%d (DevInst: %d)\n", matched, devInfoData.DevInst) - fmt.Printf(" Description: %s\n", desc) - fmt.Printf(" Hardware IDs:\n") + fmt.Printf(" #%d: %s (DevInst: %d)\n", matched, desc, devInfoData.DevInst) for _, id := range hwids { - match := "" + tag := "" if strings.EqualFold(id, targetHWID) { - match = " <== MATCH" + tag = " <== MATCH" } - fmt.Printf(" - %s%s\n", id, match) + fmt.Printf(" %s%s\n", id, tag) } } - - fmt.Printf("\nTotal devices enumerated: %d, Kneron devices found: %d\n", total, matched) -} - -func tryUpdateDriver(infPath, hardwareID string) { - infUTF16, _ := syscall.UTF16PtrFromString(infPath) - hwIDUTF16, _ := syscall.UTF16PtrFromString(hardwareID) - var needReboot int32 - - fmt.Printf("Hardware ID: %s\n", hardwareID) - fmt.Println("Calling UpdateDriverForPlugAndPlayDevicesW...") - - ret, _, lastErr := procUpdateDriverForPlugAndPlayDevicesW.Call( - 0, - uintptr(unsafe.Pointer(hwIDUTF16)), - uintptr(unsafe.Pointer(infUTF16)), - INSTALLFLAG_FORCE, - uintptr(unsafe.Pointer(&needReboot)), - ) - - fmt.Printf("Return value: %d\n", ret) - if ret == 0 { - errno := lastErr.(syscall.Errno) - fmt.Printf("FAILED - error: %v (code: %d / 0x%08X)\n", lastErr, uint32(errno), uint32(errno)) - } else { - fmt.Println("SUCCESS!") - } -} - -func tryDiInstallDriver(infPath string) { - infUTF16, _ := syscall.UTF16PtrFromString(infPath) - var needReboot int32 - - fmt.Println("Calling DiInstallDriverW...") - ret, _, lastErr := procDiInstallDriverW.Call( - 0, - uintptr(unsafe.Pointer(infUTF16)), - DIIRFLAG_FORCE_INF, - uintptr(unsafe.Pointer(&needReboot)), - ) - - fmt.Printf("Return value: %d\n", ret) - if ret == 0 { - errno := lastErr.(syscall.Errno) - fmt.Printf("FAILED - error: %v (code: %d / 0x%08X)\n", lastErr, uint32(errno), uint32(errno)) - } else { - fmt.Println("SUCCESS!") - } + fmt.Printf(" Total: %d, Kneron: %d\n", total, matched) } func trySetupAPIInstall(infPath, targetHWID string) { - fmt.Println("Enumerating present USB devices...") - - hDevInfo, _, err := procSetupDiGetClassDevsW.Call( - 0, 0, 0, - DIGCF_PRESENT|DIGCF_ALLCLASSES, - ) + hDevInfo, _, err := procSetupDiGetClassDevsW.Call(0, 0, 0, DIGCF_PRESENT|DIGCF_ALLCLASSES) if hDevInfo == INVALID_HANDLE_VALUE { - fmt.Printf("ERROR: SetupDiGetClassDevsW: %v\n", err) + fmt.Printf(" ERROR: %v\n", err) return } defer procSetupDiDestroyDevInfoList.Call(hDevInfo) @@ -281,124 +388,67 @@ func trySetupAPIInstall(infPath, targetHWID string) { var devInfoData SP_DEVINFO_DATA devInfoData.cbSize = uint32(unsafe.Sizeof(devInfoData)) - found := false for i := uint32(0); ; i++ { - ret, _, _ := procSetupDiEnumDeviceInfo.Call( - hDevInfo, uintptr(i), - uintptr(unsafe.Pointer(&devInfoData)), - ) + ret, _, _ := procSetupDiEnumDeviceInfo.Call(hDevInfo, uintptr(i), uintptr(unsafe.Pointer(&devInfoData))) if ret == 0 { - break + fmt.Println(" Target device not found") + return } var buf [2048]uint16 var dataType, reqSize uint32 ret, _, _ = procSetupDiGetDeviceRegistryPropW.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - SPDRP_HARDWAREID, - uintptr(unsafe.Pointer(&dataType)), - uintptr(unsafe.Pointer(&buf[0])), - uintptr(len(buf)*2), - uintptr(unsafe.Pointer(&reqSize)), + hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), SPDRP_HARDWAREID, + uintptr(unsafe.Pointer(&dataType)), uintptr(unsafe.Pointer(&buf[0])), + uintptr(len(buf)*2), uintptr(unsafe.Pointer(&reqSize)), ) if ret == 0 { continue } - hwids := multiSzToStrings(buf[:], reqSize) - matchFound := false + match := false for _, id := range hwids { if strings.EqualFold(id, targetHWID) { - matchFound = true + match = true break } } - if !matchFound { + if !match { continue } - fmt.Printf("FOUND target device (DevInst: %d)\n", devInfoData.DevInst) - found = true + fmt.Printf(" Found device (DevInst: %d)\n", devInfoData.DevInst) - // Set install params: use our specific INF var installParams SP_DEVINSTALL_PARAMS_W installParams.cbSize = uint32(unsafe.Sizeof(installParams)) - - ret, _, err = procSetupDiGetDevInstallParamsW.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - uintptr(unsafe.Pointer(&installParams)), - ) - if ret == 0 { - fmt.Printf("ERROR: GetDeviceInstallParams: %v\n", err) - return - } - - fmt.Printf("Current Flags: 0x%08X, FlagsEx: 0x%08X\n", installParams.Flags, installParams.FlagsEx) + procSetupDiGetDevInstallParamsW.Call(hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), uintptr(unsafe.Pointer(&installParams))) infUTF16, _ := syscall.UTF16FromString(infPath) copy(installParams.DriverPath[:], infUTF16) installParams.Flags |= DI_ENUMSINGLEINF installParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS - ret, _, err = procSetupDiSetDevInstallParamsW.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - uintptr(unsafe.Pointer(&installParams)), - ) + procSetupDiSetDevInstallParamsW.Call(hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), uintptr(unsafe.Pointer(&installParams))) + + ret, _, _ = procSetupDiBuildDriverInfoList.Call(hDevInfo, uintptr(unsafe.Pointer(&devInfoData)), SPDIT_COMPATDRIVER) if ret == 0 { - fmt.Printf("ERROR: SetDeviceInstallParams: %v\n", err) + fmt.Println(" BuildDriverInfoList failed") return } - fmt.Println("Install params set OK") - // Build compatible driver list - fmt.Println("Building driver info list...") - ret, _, err = procSetupDiBuildDriverInfoList.Call( - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - SPDIT_COMPATDRIVER, - ) + ret, _, _ = procSetupDiCallClassInstaller.Call(DIF_SELECTBESTCOMPATDRV, hDevInfo, uintptr(unsafe.Pointer(&devInfoData))) if ret == 0 { - errno := err.(syscall.Errno) - fmt.Printf("ERROR: BuildDriverInfoList: %v (0x%08X)\n", err, uint32(errno)) + fmt.Println(" DIF_SELECTBESTCOMPATDRV failed") return } - fmt.Println("Driver info list built OK") - // Select best compatible driver - fmt.Println("Selecting best compatible driver...") - ret, _, err = procSetupDiCallClassInstaller.Call( - DIF_SELECTBESTCOMPATDRV, - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - ) + ret, _, err = procSetupDiCallClassInstaller.Call(DIF_INSTALLDEVICE, hDevInfo, uintptr(unsafe.Pointer(&devInfoData))) if ret == 0 { errno := err.(syscall.Errno) - fmt.Printf("ERROR: DIF_SELECTBESTCOMPATDRV: %v (0x%08X)\n", err, uint32(errno)) - return - } - fmt.Println("Best driver selected OK") - - // Install device - fmt.Println("Installing driver on device...") - fmt.Println("(Windows Security dialog may appear)") - ret, _, err = procSetupDiCallClassInstaller.Call( - DIF_INSTALLDEVICE, - hDevInfo, - uintptr(unsafe.Pointer(&devInfoData)), - ) - if ret == 0 { - errno := err.(syscall.Errno) - fmt.Printf("ERROR: DIF_INSTALLDEVICE: %v (0x%08X)\n", err, uint32(errno)) + fmt.Printf(" DIF_INSTALLDEVICE FAILED: %v (0x%08X)\n", err, uint32(errno)) } else { - fmt.Println("SUCCESS - driver installed!") + fmt.Println(" SUCCESS - driver installed!") } - break - } - - if !found { - fmt.Println("Target device NOT found among present devices") + return } } diff --git a/edge-ai-platform/tools/test_driver_install/test_driver_install.exe b/edge-ai-platform/tools/test_driver_install/test_driver_install.exe index af002f5..0ec9ea1 100755 Binary files a/edge-ai-platform/tools/test_driver_install/test_driver_install.exe and b/edge-ai-platform/tools/test_driver_install/test_driver_install.exe differ