<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>rss.livelink.threads-in-node</title>
    <link>https://techcommunity.microsoft.com/t5/microsoft-usb/ct-p/MicrosoftUSB</link>
    <description>rss.livelink.threads-in-node</description>
    <pubDate>Sat, 25 Apr 2026 03:06:00 GMT</pubDate>
    <dc:creator>MicrosoftUSB</dc:creator>
    <dc:date>2026-04-25T03:06:00Z</dc:date>
    <item>
      <title>USB Driver Documentation Updates on UCSI, USB4 Testing</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/usb-driver-documentation-updates-on-ucsi-usb4-testing/ba-p/4497683</link>
      <description>&lt;P data-line="4"&gt;Over the past few months, we've been running a freshness pass across the &lt;A href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/"&gt;USB driver documentation on Microsoft Learn&lt;/A&gt;&amp;nbsp;and the&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/universal-serial-bus-4" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/universal-serial-bus-4"&gt;USB4 design guidelines&lt;/A&gt;. The goal is straightforward: make sure the docs match the current Windows 11 driver stack, read clearly, and get you to the answer faster. Here's what changed.&lt;/P&gt;
&lt;H2 data-line="18"&gt;USB4 required testing: new Basic Validation Tests&lt;/H2&gt;
&lt;P data-line="12"&gt;The USB4 ecosystem has grown significantly. As the number of USB4 router implementations grows, so does the need for a clear, repeatable validation baseline. We added a new &lt;A href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-required-testing#basic-validation-tests" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-required-testing#basic-validation-tests"&gt;Basic Validation Tests&lt;/A&gt;&amp;nbsp;section to the&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-required-testing" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-required-testing"&gt;USB4 Required Testing&lt;/A&gt;&amp;nbsp;page.&lt;/P&gt;
&lt;P data-line="14"&gt;The existing page already listed the recommended end-to-end test scenarios: driver verifier, domain power-down, wake replay, interdomain connections, and so on. What was missing was a concise set of smoke tests that OEMs and IHVs could run quickly to catch regressions in incremental USB4 firmware and driver updates without needing a full test pass. The new section fills that gap with nine concrete test scenarios:&lt;/P&gt;
&lt;OL data-line="16"&gt;
&lt;LI data-line="16"&gt;&lt;STRONG&gt;USB4 HLK Tests&lt;/STRONG&gt;: run all&amp;nbsp;System.Fundamentals.SystemUSB.USB4.*&amp;nbsp;and&amp;nbsp;Device.BusController.USB4.*&amp;nbsp;tests.&lt;/LI&gt;
&lt;LI data-line="17"&gt;&lt;STRONG&gt;Basic Enumeration&lt;/STRONG&gt;: attach a USB4 dock and a Thunderbolt 3 dock, each with a display, USB3 storage, and USB2 input. Verify clean enumeration in Device Manager, functional input, file copy, and display extension.&lt;/LI&gt;
&lt;LI data-line="18"&gt;&lt;STRONG&gt;Display&lt;/STRONG&gt;: verify two 4K displays at 60 Hz concurrently, both tunneled through a USB4 dock and directly via DisplayPort Alt Mode.&lt;/LI&gt;
&lt;LI data-line="19"&gt;&lt;STRONG&gt;Camera (Isochronous) Streaming&lt;/STRONG&gt;: stream from a USB3 camera through a USB4 dock for at least one minute with no visible glitches.&lt;/LI&gt;
&lt;LI data-line="20"&gt;&lt;STRONG&gt;System Standby&lt;/STRONG&gt;: attach a full dock topology, cycle standby five times with 30-second to 2-minute waits, and verify all devices survive each transition.&lt;/LI&gt;
&lt;LI data-line="21"&gt;&lt;STRONG&gt;System Reboot&lt;/STRONG&gt;: same topology, same verification, but with a full reboot instead of standby.&lt;/LI&gt;
&lt;LI data-line="22"&gt;&lt;STRONG&gt;System Hibernate&lt;/STRONG&gt;: same again, with hibernate.&lt;/LI&gt;
&lt;LI data-line="23"&gt;&lt;STRONG&gt;Minimal Compatibility and Interoperability&lt;/STRONG&gt;: test at least 3 display models and at least 10 USB4 dock or device models spanning Intel Thunderbolt 4, Intel Thunderbolt 5, Via USB4, Asmedia USB4, Realtek USB4, Intel Thunderbolt 3 Titan Ridge, and Intel Thunderbolt 3 Alpine Ridge.&lt;/LI&gt;
&lt;LI data-line="24"&gt;&lt;STRONG&gt;Basic Plug/Unplug with USB4 Switch&lt;/STRONG&gt;: configure the USB4 Switch with a USB4 dock on port 1 and a Thunderbolt 3 dock on port 2, run&amp;nbsp;ConnExUtil.exe /cxstress&amp;nbsp;for a minimum of 15 minutes (24+ hours for long-term stability), then verify the port still enumerates and charges after the test.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P data-line="26"&gt;Each test includes explicit pass criteria: no yellow bangs, no visual glitches, expected resolution and refresh rates confirmed in the Advanced Display settings. The interoperability test (test 8) is particularly important as USB4 matures: it ensures your platform works across the full range of silicon vendors, not just the one on your bench.&lt;/P&gt;
&lt;P data-line="36"&gt;If you're validating USB4 firmware or driver updates and need a quick confidence check before a broader test pass, this is the list to start with.&lt;/P&gt;
&lt;H2 data-line="6"&gt;UCSI driver docs: cleaned up and refocused on Windows 11&lt;/H2&gt;
&lt;P data-line="8"&gt;The&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/ucsi" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/ucsi"&gt;UCSI driver&lt;/A&gt; article got a thorough refresh: updated architecture diagram, clearer UCSI 2.0&amp;nbsp;_DSM&amp;nbsp;backward-compatibility guidance, reformatted UCSIControl.exe test instructions with proper inline code for registry paths, and consistent code-style formatting across the DRP role detection and charger mismatch example flows. We also removed outdated Windows 10 Mobile references so the article now focuses exclusively on Windows 10 desktop and Windows 11.&lt;/P&gt;
&lt;H2 data-line="38"&gt;USB generic parent driver (Usbccgp.sys): plain language rewrite&lt;/H2&gt;
&lt;P data-line="32"&gt;The&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-common-class-generic-parent-driver" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-common-class-generic-parent-driver"&gt;Usbccgp.sys&lt;/A&gt;&amp;nbsp;article, the starting point for anyone building composite USB devices, was rewritten for clarity. We simplified jargon-heavy sentences, expanded abbreviations on first use (e.g., "information (INF) file"), updated cross-references to sentence case per the Microsoft Learn style guide, and added customer-intent metadata for better search discoverability.&lt;/P&gt;
&lt;H2 data-line="34"&gt;Community fix: interrupt endpoint direction&lt;/H2&gt;
&lt;P data-line="36"&gt;Here's a small one that matters more than it looks. In the&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/how-to-send-a-usb-interrupt-transfer--uwp-app-" target="_blank" rel="noopener" data-href="https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/how-to-send-a-usb-interrupt-transfer--uwp-app-"&gt;How to send a USB interrupt transfer (UWP app)&lt;/A&gt;&amp;nbsp;article, the Interrupt IN transfers section incorrectly stated that HID devices like keyboards "support interrupt&amp;nbsp;&lt;STRONG&gt;OUT&lt;/STRONG&gt;&amp;nbsp;endpoints." Endpoint direction is fundamental (IN means device-to-host, OUT means host-to-device) and getting that wrong in official documentation can send you down entirely the wrong debugging path.&lt;/P&gt;
&lt;P data-line="38"&gt;A community contributor&amp;nbsp;&lt;A href="https://github.com/MicrosoftDocs/windows-driver-docs/pull/4007/changes" target="_blank" rel="noopener" data-href="https://github.com/MicrosoftDocs/windows-driver-docs/pull/4007/changes"&gt;spotted the error and submitted the fix&lt;/A&gt;. It now correctly reads "interrupt&amp;nbsp;&lt;STRONG&gt;IN&lt;/STRONG&gt;&amp;nbsp;endpoints." If you've ever stared at a USB trace wondering why your interrupt transfer wasn't behaving, this might have been part of the confusion.&lt;/P&gt;
&lt;P data-line="40"&gt;Thank you to everyone who submits pull requests. This is exactly the kind of contribution that makes the docs better for all of us.&lt;/P&gt;
&lt;H2 data-line="54"&gt;What's next&lt;/H2&gt;
&lt;P data-line="56"&gt;These updates are part of a broader freshness initiative across the Windows Hardware driver documentation.&amp;nbsp;&lt;/P&gt;
&lt;P data-line="58"&gt;If you spot something that looks outdated or confusing, our documentation is open source. Submit a PR on the&amp;nbsp;&lt;A href="https://github.com/MicrosoftDocs/windows-driver-docs" target="_blank" rel="noopener" data-href="https://github.com/MicrosoftDocs/windows-driver-docs"&gt;windows-driver-docs&lt;/A&gt; GitHub repository. You can also drop a comment below.&lt;/P&gt;</description>
      <pubDate>Fri, 27 Feb 2026 00:17:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/usb-driver-documentation-updates-on-ucsi-usb4-testing/ba-p/4497683</guid>
      <dc:creator>Ugan-Sivagnanenthirarajah</dc:creator>
      <dc:date>2026-02-27T00:17:38Z</dc:date>
    </item>
    <item>
      <title>WINDOWS MEDIA CREATION TOOL SEVERELY LIMITS YOUR USB FLASH DRIVE</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/windows-media-creation-tool-severely-limits-your-usb-flash-drive/m-p/4473908#M17</link>
      <description>&lt;P&gt;I have been having ZERO luck at creating a Recovery Drive on my Win 11 laptop.&lt;/P&gt;&lt;P&gt;So I tried the Windows Media Creation Tool.&lt;/P&gt;&lt;P&gt;It converted my 126 GB USB flash drive to a USELESS 31.9 GB drive.&amp;nbsp; After using up a lot of space for inbuilt files, it reduced to far less capacity.&amp;nbsp; THERE WAS NO WARNING ON THE MICROSOFT WEBSITE THAT THIS WOULD HAPPEN.&lt;/P&gt;&lt;P&gt;Microsoft claimed "Installation media, such as a USB flash drive, can be used to install a new copy of Windows, perform a clean installation of Windows, or reinstall Windows." &amp;nbsp;&lt;A class="lia-external-url" href="https://support.microsoft.com/en-au/windows/create-installation-media-for-windows-99a58364-8c02-206f-aa6f-40c3b507420d" target="_blank"&gt;https://support.microsoft.com/en-au/windows/create-installation-media-for-windows-99a58364-8c02-206f-aa6f-40c3b507420d&lt;/A&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The Media Creation Tool didn't have the sense to leave a FULL 32 GB or more free.&lt;/P&gt;&lt;P&gt;So my expensive 126 GB flash drive has been converted to a far less item and it's NOT EVEN GOOD ENOUGH TO create a Recovery Drive.&lt;/P&gt;&lt;P&gt;COMPLAINT TO MICROSOFT:&amp;nbsp;&lt;/P&gt;&lt;P&gt;(1)&amp;nbsp; Why didn't the Tool leave my USB flash drive at over at least 100 GB?&lt;/P&gt;&lt;P&gt;(2)&amp;nbsp; Why no warning on what would happen?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 30 Nov 2025 00:16:10 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/windows-media-creation-tool-severely-limits-your-usb-flash-drive/m-p/4473908#M17</guid>
      <dc:creator>IDAnnoyed55</dc:creator>
      <dc:date>2025-11-30T00:16:10Z</dc:date>
    </item>
    <item>
      <title>RECOVERY DRIVE FOR WINDOWS 11</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/recovery-drive-for-windows-11/m-p/4473901#M16</link>
      <description>&lt;P&gt;After creating a System Image, the system next asks if you want to create a System Repair Disk, but demands that you have a CD / DVD drive.&amp;nbsp; I have that and have tried to create a System Repair Disk on brand new, fresh out of the box CDs and DVDs and it just won’t work.&lt;/P&gt;&lt;P&gt;So I’ve been trying to create a Recovery Drive for Windows 11, and have tried using various USB flash drives of sizes 32 GB and 128 GB.&amp;nbsp; The flashes are not being recognised and the message is to use a USB Flash of at least 32 GB.&amp;nbsp; A whopping 128 GB and still not good enough!&lt;/P&gt;&lt;P&gt;I have also tried USB flashes of the formats FAT32, exFAT and NTFS.&amp;nbsp; Still can’t create a Recovery Drive.&amp;nbsp; Ditto flashes that are USB 3.1 Gen 1 and the more basic/older USB 3.0.&amp;nbsp; And yes, I’ve tried the various ports on my laptop.&lt;/P&gt;&lt;P&gt;Additionally I tried a FAT32 flash drive 32 GB that has previously been acceptable for creating a recovery drive – fresh out of the packet. &amp;nbsp;But now it won’t do a Recovery Drive – even after I have used Format to clear it.&lt;/P&gt;&lt;P&gt;It seems ridiculous that the Recovery Drive process demands a flash of “at least” 32GB when USB 32 GB flash drives are NOT a full 32 GB free.&amp;nbsp; After inbuilt system files, they only have a capacity of about 28.7 GB.&amp;nbsp; AND does not recognise higher capacity flash drives.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The only thing I’ve been able to create is a “Recovery Drive” on a FAT32 USB flash, where I DESELECTED “include system files to reinstall Windows”.&amp;nbsp; But then this really worries me that I don’t have those system files.&lt;/P&gt;&lt;P&gt;I am extremely concerned that I now don’t have an up-to-date Recovery Drive.&lt;/P&gt;&lt;P&gt;NOTES TO MICROSOFT:&amp;nbsp; (1)&amp;nbsp; Don’t state that you can create System Repair Disks on CDs and/or DVDs when you cannot.&amp;nbsp; (2)&amp;nbsp; Please make the Recovery Drive process FAR more straightforward so that it actually works.&lt;/P&gt;&lt;P&gt;HELP:&amp;nbsp; Why can’t my Windows 11 laptop create a Recovery Drive including the system files to reinstall Windows?&amp;nbsp; It shouldn’t be as impossible as I’m now finding.&lt;/P&gt;&lt;P&gt;HELP:&amp;nbsp; How do I set up a Recovery Drive.&amp;nbsp; What flash drive, size and format is to be used?&lt;/P&gt;</description>
      <pubDate>Sat, 29 Nov 2025 23:48:45 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/recovery-drive-for-windows-11/m-p/4473901#M16</guid>
      <dc:creator>IDAnnoyed55</dc:creator>
      <dc:date>2025-11-29T23:48:45Z</dc:date>
    </item>
    <item>
      <title>Exploring USB4 in Windows Device Portal</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/exploring-usb4-in-windows-device-portal/ba-p/4473357</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Overview&lt;/STRONG&gt;&lt;BR /&gt;USB4™ brings high-speed connectivity and advanced tunneling capabilities to modern Windows devices. To help developers and IT professionals visualize and manage USB4 topologies, Windows provides the USB4 domain viewer via the &lt;A href="https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/device-portal" target="_blank" rel="noopener" data-linktype="absolute-path"&gt;Windows device portal&lt;/A&gt;.&lt;/P&gt;
&lt;img&gt;A demo of USB4 Domain Viewer in Windows Device Portal.&lt;/img&gt;
&lt;H4&gt;&lt;STRONG&gt;Key Features of the USB4 Domain Viewer&lt;/STRONG&gt;&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Topology Visualization&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;Displays &lt;STRONG&gt;USB4 host routers&lt;/STRONG&gt; (in green) and &lt;STRONG&gt;device routers&lt;/STRONG&gt; (in blue).&lt;/LI&gt;
&lt;LI&gt;Supports &lt;STRONG&gt;click-and-drag navigation&lt;/STRONG&gt; and &lt;STRONG&gt;zooming&lt;/STRONG&gt; for detailed inspection.&lt;/LI&gt;
&lt;LI&gt;Automatically updates as the topology changes.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Host Router Details&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;Each host router includes &lt;STRONG&gt;Name&lt;/STRONG&gt;, &lt;STRONG&gt;VendorId&lt;/STRONG&gt;, and &lt;STRONG&gt;DeviceId&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Selecting a router reveals additional details in the sidebar.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Device Router Details&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;Shows adapters and ports, distinguishing &lt;STRONG&gt;in-use adapters&lt;/STRONG&gt; from unused ones.&lt;/LI&gt;
&lt;LI&gt;Selecting an adapter highlights it with a red circle for quick identification.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Tunnel Visualization&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;Tunnels between device routers are illustrated clearly.&lt;/LI&gt;
&lt;LI&gt;Each tunnel uses a &lt;STRONG&gt;colon-separated unique ID&lt;/STRONG&gt; (e.g., 8:1:1:9) for easy reference.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Context-Specific Sidebar&lt;/STRONG&gt;
&lt;UL&gt;
&lt;LI&gt;Updates dynamically based on selected elements (routers, adapters, tunnels).&lt;/LI&gt;
&lt;LI&gt;Allows collapsing or expanding details for streamlined viewing.&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;img&gt;A Legend of the different areas of USB4 Domain Viewer&lt;/img&gt;
&lt;H4&gt;&lt;STRONG&gt;Why It Matters&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;The USB4 Domain Viewer simplifies troubleshooting and topology analysis for OEMs, IHVs, and developers. By providing real-time visualization and granular details, it accelerates debugging and ensures compliance with USB4 standards.&lt;/P&gt;
&lt;H4&gt;&lt;STRONG&gt;Getting Started&lt;/STRONG&gt;&lt;/H4&gt;
&lt;P&gt;Access the USB4 Domain Viewer through the &lt;STRONG&gt;Windows Device Portal&lt;/STRONG&gt; on supported devices. For more details, visit the official &lt;A href="https://learn.microsoft.com/en-us/windows-hardware/design/component-guidelines/usb4-windows-device-portal" target="_blank" rel="noopener"&gt;Microsoft Learn documentation&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;©&lt;/EM&gt;&lt;EM&gt; 2025 Microsoft. USB4®, USB Type-C® and USB-C®, USB 2.0 Type-C™ are registered trademarks of USB Implementers Forum, Inc. Thunderbolt™ is a trademark of Intel Corporation.&lt;/EM&gt;&amp;nbsp;&lt;EM&gt;This article is not endorsed by or affiliated with USB-IF.&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Nov 2025 02:25:37 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/exploring-usb4-in-windows-device-portal/ba-p/4473357</guid>
      <dc:creator>Ugan-Sivagnanenthirarajah</dc:creator>
      <dc:date>2025-11-27T02:25:37Z</dc:date>
    </item>
    <item>
      <title>USB 128GB flash drive only works in Win 10 safe mode--not normal Win 10 mode</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-128gb-flash-drive-only-works-in-win-10-safe-mode-not-normal/m-p/4458724#M15</link>
      <description>&lt;P&gt;I have a Lexar 128GB flash drive that only works properly in Win 10 safe mode on my two Win 10 desktop machines. In normal Win 10 the flash drive, when inserted, shows up for roughly 3 - 5 seconds in File Explorer (and the PC dings that an external device was inserted), then the flash drive disappears from File Explorer and doesn't appear in Disk Management anymore. The Windows Explorer message "USB device not recognized" keeps appearing. Other flash drives of different make and sizes work fine in the normal Win 10 of both my Win 10 PCs. So it must be just this particular flash drive for a reason I can't figure out. I have watched countless YouTube videos on getting your flash drive recognized and nothing I've tried works. I've disabled my Norton 360 and that didn't help. Wondering if anyone can think of an new way to get this flash drive to work in normal Win 10? Again, tried all kinds of recommended things in YouTube videos and articles--in Disk Management, Disk Manager, CMD prompt, DiskPart, Windows PowerShell, disabled Norton 360, talked to Lexar tech support (told me to talk to Microsoft), reformatted the drive in multiple ways, disabled USB Selective Suspend settings, used Rufus to format in nonbootable mode, and through one of the attempts (maybe the attrib -h -s -r /s /d *&lt;EM&gt;.*&lt;/EM&gt; command) found autorun.inf and autorun.ico on the drive and deleted those. The crazy part is it works perfectly fine in safe mode, but is only briefly recognized before disappearing in normal Win 10. Thanks in advance for any ideas!&lt;/P&gt;</description>
      <pubDate>Fri, 03 Oct 2025 00:05:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-128gb-flash-drive-only-works-in-win-10-safe-mode-not-normal/m-p/4458724#M15</guid>
      <dc:creator>rrkrrk99</dc:creator>
      <dc:date>2025-10-03T00:05:38Z</dc:date>
    </item>
    <item>
      <title>USB Type-C Notifications in Windows: What OEMs Need to Know</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/usb-type-c-notifications-in-windows-what-oems-need-to-know/ba-p/4446175</link>
      <description>&lt;P&gt;Windows 11 includes built-in USB Type-C troubleshooting notifications designed to help users identify and resolve issues like slow charging, unsupported accessories, and faulty connections. These notifications are part of a broader effort to improve device reliability and user experience.&lt;/P&gt;
&lt;P&gt;While our &lt;A href="https://techcommunity.microsoft.com/blog/microsoftusbblog/discover-usb-settings-and-notifications-in-windows-11/4387341" target="_blank" rel="noopener"&gt;previous post&lt;/A&gt; focused on the user experience, this update is for &lt;STRONG&gt;OEMs&lt;/STRONG&gt; highlighting what’s required to ensure these notifications function correctly on your platforms.&lt;/P&gt;
&lt;H2&gt;Why Notifications Might Not Appear&lt;/H2&gt;
&lt;P&gt;USB Type-C notifications rely on accurate platform configuration. If notifications aren’t showing up, it’s often due to:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Missing or incorrect ACPI markup&lt;/STRONG&gt;: Windows uses ACPI descriptors to identify USB Type-C ports and their capabilities. If the port isn’t correctly marked as user-accessible or Type-C, notifications may not trigger.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Incorrect connector type reporting&lt;/STRONG&gt;: Mislabeling a Type-A port as Type-C (or vice versa) can lead to unexpected behavior or missed alerts.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Internal vs. external port confusion&lt;/STRONG&gt;: Ports marked as internal may suppress notifications even if they’re physically accessible to users.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Validation and Testing&lt;/H2&gt;
&lt;P&gt;To ensure compatibility:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Use the &lt;STRONG&gt;Windows Hardware Lab Kit (HLK)&lt;/STRONG&gt; to validate USB port descriptors.&lt;/LI&gt;
&lt;LI&gt;Confirm that &lt;STRONG&gt;_UPC (USB Port Capabilities)&lt;/STRONG&gt; and &lt;STRONG&gt;_PLD (Physical Location of Device)&lt;/STRONG&gt; ACPI methods are correctly implemented.&lt;/LI&gt;
&lt;LI&gt;Test with various charging scenarios, including underpowered chargers and hubs, to verify that notifications appear as expected. The link below has a table of the notifications and expected behaviours.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;H2&gt;Security Considerations&lt;/H2&gt;
&lt;P&gt;Some OEMs may choose to disable data over USB Type-C in untrusted environments. If implementing such features:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Ensure the policy applies only to externally accessible ports.&lt;/LI&gt;
&lt;LI&gt;Consider offering user toggles for data disablement.&lt;/LI&gt;
&lt;LI&gt;Validate that disabling data doesn’t interfere with critical internal devices (e.g., touchpad, keyboard).&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Recommendations for OEMs&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Audit ACPI descriptors and USB Device-Specific Method&lt;/STRONG&gt; for all USB ports. See &lt;A href="https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm-#function-7-query-if-_upc-supports-usb-c-port-capabilities-as-defined-in-acpi-specification-65" target="_blank"&gt;https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm-#function-7-query-if-_upc-supports-usb-c-port-capabilities-as-defined-in-acpi-specification-65&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Validate notification behavior&lt;/STRONG&gt; across all supported configurations.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Coordinate with &lt;/STRONG&gt;&lt;A href="http://www.aka.ms/whcp" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Microsoft WHCP&lt;/STRONG&gt;&lt;/A&gt; to ensure new platforms meet testing requirements.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Document exceptions&lt;/STRONG&gt; clearly if certain ports or configurations are unsupported.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&amp;nbsp;Learn More&lt;/H2&gt;
&lt;P&gt;For technical details and troubleshooting guidance, refer to the official documentation:&lt;BR /&gt;&lt;A href="https://learn.microsoft.com/windows-hardware/drivers/usbcon/usb-type-c-troubleshooting-notifications" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/windows-hardware/drivers/usbcon/usb-type-c-troubleshooting-notifications&lt;/A&gt; &amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 29 Aug 2025 23:00:00 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/usb-type-c-notifications-in-windows-what-oems-need-to-know/ba-p/4446175</guid>
      <dc:creator>Ugan-Sivagnanenthirarajah</dc:creator>
      <dc:date>2025-08-29T23:00:00Z</dc:date>
    </item>
    <item>
      <title>USB Camera fails to initialize on startup</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-camera-fails-to-initialize-on-startup/m-p/4439989#M13</link>
      <description>&lt;P&gt;Current setup:&lt;BR /&gt;- Tablet with a Windows 10 IoT Enterprise image&lt;BR /&gt;- Application communicates to a USB camera on startup&lt;BR /&gt;- Application setup with as the custom shell (instead of explorer.exe)&lt;BR /&gt;- USB camera uses the pre-installed usbvideo.sys driver.&lt;/P&gt;&lt;P&gt;Issue:&lt;BR /&gt;I have an issue with a USB camera video system that is permanently connected to a tablet (via an internal USB hub). On some tablets the camera is correctly initialized and the application can see a video stream but on others it does not initialize. Only by manually re-installing the drivers via device manager does it seem to fix it. In some cases, the tablet ends up failing again and the drivers need to be re-installed again. What could be the issue and how could I fix it? Does this happen to anyone else?&lt;/P&gt;</description>
      <pubDate>Tue, 05 Aug 2025 01:17:14 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-camera-fails-to-initialize-on-startup/m-p/4439989#M13</guid>
      <dc:creator>TiONSewm</dc:creator>
      <dc:date>2025-08-05T01:17:14Z</dc:date>
    </item>
    <item>
      <title>Ending USB-C® Port Confusion</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/ending-usb-c-port-confusion/ba-p/4410479</link>
      <description>&lt;P&gt;&lt;EM&gt;The Blank Display (and Why It Can Still Happen)&amp;nbsp;&lt;/EM&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;EM&gt;Five minutes before a customer demo, I plug my 4K monitor into the USB-C port on a brand-new laptop. The display doesn’t light up, and now I’m scratching my head—the cable fit, so why isn’t it working?&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;USB4® carries the promise of a single USB Type-C® port that can do it all – charging, high speed data, multiple displays, and compatibility with Thunderbolt™ peripherals. However, Windows Diagnostics Data shows that 27% of PCs with USB4 have encountered a &lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/microsoftusbblog/discover-usb-settings-and-notifications-in-windows-11/4387341" target="_blank" rel="noopener" data-lia-auto-title="limited functionality notification" data-lia-auto-title-active="0"&gt;limited functionality notification&lt;/A&gt;, meaning that a customer plugged a USB-C device in, but a feature (alternate mode) that device needs was not implemented on the PC and Windows notified the user. The reversible USB Type-C connector isn’t the problem, the inconsistent implementations of USB-C port capabilities across the PC ecosystem is.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;USB Power Delivery on USB-C ports can deliver up to &lt;STRONG&gt;240&lt;/STRONG&gt;&lt;STRONG&gt; W of power&lt;/STRONG&gt;, and USB4 (which is only available over USB-C) can deliver up to &lt;STRONG&gt;80Gbps&lt;/STRONG&gt; bandwidth (up to &lt;STRONG&gt;120Gbps for Displays&lt;/STRONG&gt;), DisplayPort Alt Mode, DisplayPort and PCIe tunneling, and support for Thunderbolt™ peripherals – all through one connector. But the promise of 'universal' in Universal Serial Bus (USB) only matches user expectations if every port delivers a consistent experience, regardless of laptop manufacturer implementation choices.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So why does the demo fail? Because not all USB-C ports are created equal. You can’t tell which ones deliver the full experience just by looking at them. In this case, if the PC doesn’t support DisplayPort Alternate Mode functionality, that monitor won’t light up even though the cable fits. PC manufacturers can implement ports that look identical but differ wildly in functionality: one may charge your laptop and run a 4K display; another might only deliver USB 2.0 data speeds. The USB specification allows this, and without clear enforcement, the consumer experiences frustration, guesswork, and endless troubleshooting.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;This isn’t new. As USB specification versions have evolved and added new capabilities, the complexity has sometimes left consumers in the dark, especially when ports aren’t labeled clearly. Most people don’t know what “USB 3.2 Gen 2x2” means or which port supports what features. That’s why we’re pleased to see the USB-IF introduce simpler,&amp;nbsp;&lt;A href="https://www.usb.org/logo-license" target="_blank" rel="noopener"&gt;clearer branding guidelines&lt;/A&gt; like “USB 40Gbps” and “USB 80Gbps”, making it much easier for everyone to understand exactly what each port can do.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;We think it’s important for this clear branding to carry through to the actual customer experience with USB-C ports on Windows 11 PCs. While the USB specifications give PC manufacturers the ability to choose which optional features the port supports, we set out to establish a minimum bar for USB-C port capabilities on PCs.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P class="lia-align-center"&gt;Figure 1 Table of the capabilities required by WHCP for mobile Windows systems&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The Windows Hardware Compatibility Program (WHCP) comes in to turn this table into reality – turning optional features into mandatory ones, and ensure a consistent level of performance you can count on. The table above reflects what you can reliably expect from USB-C ports on WHCP-certified mobile PCs.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Some USB 40Gbps and USB 80Gbps ports on Windows 11 PCs are also certified by Intel under the Thunderbolt™ brand, allowing them to be labeled as Thunderbolt™ 4 or Thunderbolt™ 5, respectively. You can rest assured that Thunderbolt™-branded ports meet all the rigorous requirements of both Microsoft’s WHCP program and Intel’s Thunderbolt™ program. Additionally, to qualify to use the Thunderbolt™ brand from Intel, the product must first be certified by the USB-IF.&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Two Firm Promises of USB-C on Windows 11&amp;nbsp;&lt;/H1&gt;
&lt;P&gt;When we set out to improve the USB-C experience with WHCP, we started by defining the customer promises that we wanted to achieve. This came down to two simple goals:&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;USB Data, Charging and Display “just works” on &lt;U&gt;all&lt;/U&gt; USB-C ports: &lt;/STRONG&gt;Your favorite USB 1, USB 2, and USB 3 peripherals, chargers and displays will work exactly as advertised on any USB-C port on your WHCP-certified Windows 11 device.&amp;nbsp;&amp;nbsp;&lt;/LI&gt;
&lt;/OL&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Systems that support USB 40Gbps also give full compatibility with USB4 and Thunderbolt&lt;/STRONG&gt;™&lt;STRONG&gt; 3 peripherals: &lt;/STRONG&gt;On a WHCP-certified USB 40Gbps system, you can also plug in any USB4 or Thunderbolt™ 3 device and trust it will work every time on every port.&amp;nbsp;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;To ensure that certified Windows 11 PCs deliver on these goals, we introduced new and updated WHCP requirements alongside the release of Windows 11, version 24H2, that are laser focused on them.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;What every USB-C port needs to nail WHCP compliance&amp;nbsp;&lt;/H1&gt;
&lt;H2&gt;All mobile systems with USB-C ports&amp;nbsp;&lt;/H2&gt;
&lt;P&gt;Meeting our first customer promise, that USB Data, Charging and Display “just works” on all USB-C ports, requires any WHCP compliant mobile PC with USB-C to support a baseline set of requirements. No matter what speeds your USB-C ports support, every port can be expected to deliver the following:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;You can trust that your devices will work flawlessly, avoiding the frustration of unreliable connections, as we require USB-IF &lt;STRONG&gt;certified silicon&lt;/STRONG&gt; in the PC.&lt;STRONG&gt; &lt;/STRONG&gt;This guarantees that every connection is robust and reliable &lt;A href="https://www.usb.org/compliance" target="_blank" rel="noopener"&gt;through USB-IF certification&lt;/A&gt; or equivalent electrical compliance, rigorously tested for compatibility in a lab.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;Your devices will charge efficiently and consistently as &lt;STRONG&gt;every USB-C port on a certified PC needs to support USB Power Delivery charging&lt;/STRONG&gt;.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;DisplayPort Alt-Mode &lt;/STRONG&gt;is required&lt;STRONG&gt; &lt;/STRONG&gt;for all USB-C ports to support connecting monitors.&amp;nbsp; When you plug a display in, you can feel confident it will work well because the ports have to be VESA certified.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;The &lt;STRONG&gt;Microsoft driver stack requirement&lt;/STRONG&gt; means PCs are validated using Microsoft’s built-in USB controller drivers. This ensures that security and feature updates arrive via Windows Update, keeping your system secure and up-to-date without any hassle.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;All Mobile Systems Advertising USB 40Gbps or 80Gbps Support&amp;nbsp;&amp;nbsp;&lt;/H2&gt;
&lt;P&gt;WHCP qualified systems with USB 40Gbps or 80Gbps also deliver the second customer promise, full compatibility with USB4 and Thunderbolt™ 3 peripherals, ensuring top-tier performance and compatibility:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;This ensures lightning-fast data transfers, making large file transfers and high-speed internet connections a breeze.&amp;nbsp;&lt;STRONG&gt; &lt;/STRONG&gt;Baseline bandwidth means every certified Windows 11 PC advertising USB 40Gbps must sustain full speed 40Gbps links on all USB-C ports.&amp;nbsp;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;To enable you to expand your system’s capabilities without any compatibility issues, we require &lt;STRONG&gt;PCI Express tunnelling&lt;/STRONG&gt; that allows external GPUs and NVMe enclosures to work seamlessly because host routers tunnel PCIe on every port.&amp;nbsp;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;You can continue using your favorite peripherals without any interruptions as we require &lt;STRONG&gt;Thunderbolt&lt;/STRONG&gt;™&lt;STRONG&gt; compatibility&lt;/STRONG&gt; ensures that existing Thunderbolt™ docks remain plug and play.&amp;nbsp;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;DisplayPort requirements&lt;/STRONG&gt; ensure support for up to two 4K monitors at 60Hz, providing a stunning visual experience for your work and entertainment.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;Finally, &lt;STRONG&gt;sleep and resume resilience&lt;/STRONG&gt; ensures that host routers survive low-power states without dropping tunnels. This means your system remains reliable and connected, even when it’s in sleep mode.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;WHCP eliminates the worry of powering devices you plug-in by requiring &lt;STRONG&gt;uniform port power requirements&lt;/STRONG&gt; ensures that each USB 40Gbps port sources at least 15 W (7.5 W on tablets).&amp;nbsp; Note: USB4 ports on the system must support sourcing at 15W from all ports but not all at the same time. Tablet form factor systems are not required to support 15W but must support at least 7.5W. Systems may limit individual port power below 15W when total requested power across multiple ports exceeds the system’s power budget.&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;WHCP already covers the next spec bump. Any PC that advertises USB 80 Gbps must meet all the above requirements, while also supporting operation in symmetric 80 / 80 Gbps mode and asymmetric 120 / 40 Gbps mode for increased display bandwidth.&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;How we enforce it: The Hardware Lab Kit&amp;nbsp;&lt;/H2&gt;
&lt;P&gt;That “it just works” moment isn’t magic; it’s the result of a tightly choreographed process:&amp;nbsp;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Translate Pain into Policy&lt;/STRONG&gt;&amp;nbsp;&lt;BR /&gt;We reflect on user feedback, telemetry, and field failures—like the left-port-only monitor issue—and convert each into a discrete WHCP requirement with acceptance criteria.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Author Automated Tests&lt;/STRONG&gt;&amp;nbsp;&lt;BR /&gt;Our team writes reproducible, automated Windows Hardware Lab Kit (HLK) test cases for every requirement: signaling timing, speed negotiation, power delivery, DisplayPort/PCIe tunnels, sleep/resume resilience, and more.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Partner-Led Validation&lt;/STRONG&gt;&amp;nbsp;&lt;BR /&gt;OEMs, silicon vendors, and accessory brands run these HLK tests and submit logs to Microsoft. Any failure halts certification until the issue is resolved in hardware or firmware.&amp;nbsp;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Continuous Evolution&lt;/STRONG&gt;&amp;nbsp;&lt;BR /&gt;WHCP updates with every Windows release. New tests and criteria flow via Windows Update—so fixes and feature enhancements reach end users without new hardware.&amp;nbsp;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Learn how to &lt;A href="https://learn.microsoft.com/en-us/windows-hardware/test/hlk/user/windows-hardware-lab-kit-user-s-guide" target="_blank" rel="noopener"&gt;run HLK tests&lt;/A&gt; and meet the USB4 requirements at &lt;A href="https://aka.ms/whcp" target="_blank" rel="noopener"&gt;aka.ms/whcp&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;If You’re an OEM or Accessory Maker&amp;nbsp;&lt;/H1&gt;
&lt;P&gt;Robust USB on Windows requires end-to-end testing—protocol compliance, signal integrity, power negotiation and security—and Microsoft’s USB Test Tool (MUTT) suite of hardware and automated scripts streamlines WHCP certification. Download MUTT and dive into the full device-, silicon-, and system-level requirements (including test collateral) for USB4 on Microsoft Learn:&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;MUTT suite: &lt;A href="https://learn.microsoft.com/windows-hardware/drivers/usbcon/microsoft-usb-test-tool--mutt--devices" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/windows-hardware/drivers/usbcon/microsoft-usb-test-tool--mutt--devices&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI&gt;USB4 requirements: &lt;A href="https://learn.microsoft.com/windows-hardware/design/component-guidelines/usb4-required-testing" target="_blank" rel="noopener"&gt;https://learn.microsoft.com/windows-hardware/design/component-guidelines/usb4-required-testing&lt;/A&gt;&amp;nbsp;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;PC manufacturers are on track to achieve WHCP compliance across most systems in the coming years.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;©&lt;/EM&gt;&lt;EM&gt; 2025 Microsoft. USB Type-C® and USB-C®, USB 2.0 Type-C™ are registered trademarks of USB Implementers Forum, Inc. Thunderbolt™ is a trademark of Intel Corporation.&lt;/EM&gt; &lt;EM&gt;This article is not endorsed by or affiliated with USB-IF.&lt;/EM&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 23 Sep 2025 22:58:46 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/ending-usb-c-port-confusion/ba-p/4410479</guid>
      <dc:creator>Ugan-Sivagnanenthirarajah</dc:creator>
      <dc:date>2025-09-23T22:58:46Z</dc:date>
    </item>
    <item>
      <title>Discover USB Settings and Notifications in Windows 11</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/discover-usb-settings-and-notifications-in-windows-11/ba-p/4387341</link>
      <description>&lt;P&gt;USB 40Gbps (also known as USB4) is the latest USB standard, offering faster data transfer speeds, improved power delivery, and better performance. The second revision, USB 80Gbps, (also known as USB4 V2) doubles the maximum data transfer rate to 80Gbps and supports 120Gbps in certain configurations, ensuring faster file transfers and enhanced video output. The benefits include full backwards compatibility with all USB peripherals, compatibility with Thunderbolt peripherals, and support for multiple DisplayPort streams.&lt;/P&gt;
&lt;P&gt;USB4's tunneling technology efficiently transfers multiple data and display protocols over a single cable, making it ideal for high-performance applications. The USB4 settings page in Windows 11 provides a centralized location for users to view and manage their USB4 hubs and devices, simplifying the user experience and ensuring optimal performance. This blog post introduces the new USB4 settings page and provides an overview of the various USB settings available in Windows 11.&lt;/P&gt;
&lt;H2&gt;How can Windows help me with USB?&lt;/H2&gt;
&lt;P&gt;Windows has features that make using USB devices easy and user-friendly. It handles things like device power management automatically and lets you know if there’s an error. You can tweak these settings in USB Settings. While most users won’t need to change anything, this blog post will help you understand why some of these settings exist. Here are the details.&lt;/P&gt;
&lt;img&gt;The options that show under the Windows 11 USB Settings page&lt;/img&gt;
&lt;H3&gt;Connection Notifications&lt;/H3&gt;
&lt;P&gt;We’ve designed Windows 11 to be your vigilant assistant, notifying you if there’s an issue connecting a USB device. This feature ensures you’re always in the know and can take immediate action. This lets Windows notify you when it detects a problem with a USB connection. You can learn more about the specific notifications that Windows sends, and what you can do in response to them here: &lt;A href="https://support.microsoft.com/windows/fix-usb-c-problems-in-windows-f4e0e529-74f5-cdae-3194-43743f30eed2" target="_blank" rel="noopener"&gt;https://support.microsoft.com/windows/fix-usb-c-problems-in-windows-f4e0e529-74f5-cdae-3194-43743f30eed2&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;Show a notification if this PC is charging slowly over USB&lt;/H3&gt;
&lt;P&gt;Did you know? Using an incompatible charger can slow down your PC’s charging speed. Always use the charger that supports the required power levels for your PC the fastest charging. This setting lets Windows notify you when your PC’s hardware indicates that it is charging slowly over USB. This could be due to a number of reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The charger isn’t compatible with your PC.&lt;/LI&gt;
&lt;LI&gt;The charger isn’t powerful enough to charge your PC.&lt;/LI&gt;
&lt;LI&gt;The charger isn’t connected to a charging port on your PC.&lt;/LI&gt;
&lt;LI&gt;The charging cable isn't powerful enough for the charger or PC.&lt;/LI&gt;
&lt;LI&gt;Dust or dirt inside the USB port on your device prevented the charger from being inserted correctly.&lt;/LI&gt;
&lt;LI&gt;The charger is connected through an external hub or dock.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;You can resolve it by using making sure your charger and cable also support the power levels your PC requires for the faster charging. For example, if your PC requires 12V and 3A for the fastest charging, a 5V, 3A charger won’t give you the fastest charging.&lt;/P&gt;
&lt;H3&gt;USB Battery Saver&lt;/H3&gt;
&lt;P&gt;The USB battery saver is a feature designed to help conserve power by stopping USB devices that do not power down by themselves when the system enters standby. Most USB devices are well behaved and tend to power down or suspend when the system enters modern standby. When the feature is enabled, the USB bus will temporarily eject misbehaving devices (i.e. those that do not suspend) for the duration of the standby session. Not doing so would prevent the system from entering a low power standby state and significantly reduce battery life. Hence, this is particularly useful for extending battery life on devices that are battery-powered and support modern standby. When the USB battery saver is on, it prevents unnecessary battery usage from high-power-consuming USB devices by stopping them when the screen is off.&lt;/P&gt;
&lt;P&gt;However, some older USB peripherals may have compatibility issues with low-power states, which is why the option to turn off the USB battery saver exists. Turning it off can have a significant impact on the system's battery life, as it may prevent the system from fully going to standby due to some USB devices still running.&lt;/P&gt;
&lt;H6&gt;&lt;STRONG&gt;&lt;EM&gt;Caution: &amp;nbsp;Microsoft strongly recommends leaving the feature in its default-on enabled state.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;H3&gt;USB4 Hubs and devices&lt;/H3&gt;
&lt;P&gt;Imagine plugging in your USB4 device and instantly accessing a world of faster data transfer and improved power delivery. If your PC supports USB4, here’s what you can expect to see in your settings. &lt;S&gt;C&lt;/S&gt; This page is intended to give users insights into their system and device/dock’s USB4 capabilities. It is also meant to support IT administrators and /or customer-support channels when troubleshooting certain problems. (Note: The page is designed to only show USB4 and Thunderbolt 3 devices/hubs attached to your system. If you do not see a device here, it indicates that you do not have a USB4 hub/device attached or that the device operating is not operating in USB4 mode.). Here’s an example of this page:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;The USB hubs and devices pages provide useful information on your USB4 devices.&lt;/img&gt;
&lt;H2&gt;How do I adjust USB settings?&lt;/H2&gt;
&lt;P&gt;You can manage USB Settings on any Windows 11 device by opening the Settings app, and navigating to Bluetooth &amp;amp; devices &amp;gt; USB.&lt;/P&gt;
&lt;img /&gt;
&lt;H2&gt;How do I know which USB Settings are available?&lt;/H2&gt;
&lt;P&gt;The following settings are available on all PCs:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Connection notifications&lt;/STRONG&gt;: Show a notification if there are issues connecting a USB device&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;USB battery saver:&lt;/STRONG&gt; Stop USB devices when my screen is off to help save battery&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If your PC supports charging over a USB-C port you will see the following option:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Show a notification if this PC is charging slowly over USB&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If your PC is a mobile system that supports USB &amp;nbsp; you will see the following Settings available when using USB4 devices on a PC with USB4 ports):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;USB4 hubs and devices&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Conclusion&lt;/H2&gt;
&lt;P&gt;At the end of the day, our goal is to make USB technologies in Windows seamless and intuitive. We hope this blog post has given you a glimpse into the thought and care we put into every feature, making your experience as smooth as possible. While we don’t expect most users to have to tinker with their USB Settings, we hope this blog post gave you some useful insights into the motivation behind some of the USB settings.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Feb 2025 23:38:59 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/discover-usb-settings-and-notifications-in-windows-11/ba-p/4387341</guid>
      <dc:creator>Ugan-Sivagnanenthirarajah</dc:creator>
      <dc:date>2025-02-28T23:38:59Z</dc:date>
    </item>
    <item>
      <title>USB Audio 2.0 Mixer Unit control</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-audio-2-0-mixer-unit-control/m-p/3282969#M10</link>
      <description>&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;Hi,&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;I am developing a USB audio 2.0 (UAC2) device.&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;This device has a USB mixer unit (as defined by the usb audio 2.0 standard) and I was wondering how I can control/set it with the default usbaudio2.sys driver?&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;According to the official docs:&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;&lt;A href="https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers" target="_blank" rel="noopener nofollow ugc"&gt;https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers&lt;/A&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;I should be able to send a SET request to a mixer unit with the default drivers.&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;I extracted some logs from the usbaudio2.sys driver and can see that it recognizes the Mixer unit:&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;USBAudio2] MixerUnit ID=0x50 'MY MIXER'&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] Controls=0x0001&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] NumInputPins=1&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] [0] --&amp;gt; SourceID=0x20 'USB AUDIO DEMO' InputChannelCount=2&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] OutputChannelCount=2&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] AudioChannelCluster: NrChannels=2 ChanConfig=0x00000003 FirstStringIndex=0 NumStrings=0&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] NumInputPins=1 TotalNumInputChannels=2 NumOutputChannels=2&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] Mixer Controls:&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] MCN 0 PROGRAMMABLE min=-18176 (0xb900) max=0 (0x0000) res=256 (0x0100)&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] MCN 1 PROGRAMMABLE min=-18176 (0xb900) max=0 (0x0000) res=256 (0x0100)&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] MCN 2 PROGRAMMABLE min=-18176 (0xb900) max=0 (0x0000) res=256 (0x0100)&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT color="#000000"&gt;[2]0004.29B0::04/11/2022-15:46:32.392 [USBAudio2] MCN 3 PROGRAMMABLE min=-18176 (0xb900) max=0 (0x0000) res=256 (0x0100)&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;I can also see GET requests for this mixer unit in the logs on my device so the windows usb audio2 driver does seem to recognize it and the min/max/res above are indeed the ones I programmed.&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;I can confirm that I can control the mixer unit from a Linux machine through alsamixer but would like to be able to do this from a Windows PC as well (preferably with the default driver since it has support for it). I don't see anything in the default sound control panel window or anything to actually control a mixer unit?&lt;/FONT&gt;&lt;/P&gt;&lt;P class=""&gt;&amp;nbsp;&lt;/P&gt;&lt;P class=""&gt;&lt;FONT color="#000000"&gt;Thanks for any info!&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Tue, 12 Apr 2022 10:00:04 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-audio-2-0-mixer-unit-control/m-p/3282969#M10</guid>
      <dc:creator>Myrmidon</dc:creator>
      <dc:date>2022-04-12T10:00:04Z</dc:date>
    </item>
    <item>
      <title>Enumerated USB Audio CODEC</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/enumerated-usb-audio-codec/m-p/3062493#M8</link>
      <description>&lt;P&gt;In Windows 10 (and I assume 7 and earlier) if I plug a USB hardware device into several different USB ports on my computer running Windows 10, a new enumeration results even though the same driver is used.&amp;nbsp; Example; if I plug the hardware into my computer's left most USB port on the front panel the hardware is enumerated as USB Audio CODEC.&amp;nbsp; When I plug the same hardware into my computer's right most USB port on the front panel the hardware is enumerated as USB- 1 USB Audio CODEC.&amp;nbsp; The saga continues especially when using USB hubs and the enumeration could easily get to be double digit enumeration names.&amp;nbsp; 3rd party software that uses this hardware depends on seeing consist naming of the hardware that is plugged in, so the user must go to the software setup section and verify the correct hardware is selected in case the hardware was plugged into a different USB port on the computer.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'd like to be able to wipe the USB enumeration table from my Windows 10 installation since I've now decided what exact USB port the hardware will always be connected to (so the only enumeration name would be USB Audio CODEC).&amp;nbsp; The Microsoft Community (non tech) suggested I use the USBDeview utility to delete the table.&amp;nbsp; I have tried that and it did not work.&amp;nbsp; As a test I deleted the last two enumerated devices;&amp;nbsp; USB- 8 Audio CODEC and USB- 9 Audio CODEC from the list, rebooted.&amp;nbsp; I then plugged the hardware into a new USB port on my computer, the OS enumerated the hardware as USB- 10 Audio CODEC.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there a way to fix this issue or should I just live with the problem?&amp;nbsp; Is there a limit to the number of enumerated names?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Steve&lt;/P&gt;</description>
      <pubDate>Sat, 15 Jan 2022 12:42:06 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/enumerated-usb-audio-codec/m-p/3062493#M8</guid>
      <dc:creator>EEByDesign</dc:creator>
      <dc:date>2022-01-15T12:42:06Z</dc:date>
    </item>
    <item>
      <title>High speed USB printer device communication issue on WINDOWS 11</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/high-speed-usb-printer-device-communication-issue-on-windows-11/m-p/3061522#M7</link>
      <description>&lt;P&gt;I encountered an issue that windows 11 keeps enumerating the high speed usb printer based on LPC546 mcu, until the OS switched to full speed mode and the enumeration successed. I used ellisys USB protocol analyzer to capture the enumeration process, the result shows as the picture below. It's wired that the OS suspended the device after getting device ID, and resumed and started over the enumeration multiple times until the OS enumerated in full speed mode.&lt;/P&gt;&lt;P&gt;&lt;img /&gt;&lt;/P&gt;&lt;P&gt;I tested the same printer on WINDOWS 10, and it worked perfectly in high speed mode.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;So, does anyone have encountered the same problem and solution to it, please tell me.&lt;/P&gt;&lt;P&gt;Much appreciate!!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Jason&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 14 Jan 2022 06:04:14 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/high-speed-usb-printer-device-communication-issue-on-windows-11/m-p/3061522#M7</guid>
      <dc:creator>JasonNotMe</dc:creator>
      <dc:date>2022-01-14T06:04:14Z</dc:date>
    </item>
    <item>
      <title>winusb driver - isochronous endpoint not working</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/winusb-driver-isochronous-endpoint-not-working/m-p/3004392#M6</link>
      <description>&lt;P&gt;Hi&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We have a usb device that working with our WDM driver written about 15 years ago .&lt;/P&gt;&lt;P&gt;It works on Windows XP to Windows 10 32 and 64 bit.&lt;/P&gt;&lt;P&gt;Device sends analog data of 2 bytes every 1ms to PC ( Data sample rate = 1000)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried to switch working with Microsoft winusb driver in Windows 10.&lt;/P&gt;&lt;P&gt;Driver installed OK;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I write some wrapper code (So my Application will work as is) to use winusb driver on&lt;/P&gt;&lt;P&gt;isochronous pipe streaming and get very strange behave ...&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I am missing packets , on All empty packets i get Status of&amp;nbsp;USBD_STATUS_ISO_NOT_ACCESSED_BY_HW&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;USBD_STATUS_ISO_NOT_ACCESSED_BY_HW&lt;/P&gt;&lt;P&gt;Extended isochronous error codes returned by USBD.&lt;BR /&gt;These errors appear in the packet status field of an isochronous transfer. [0xC0020000]&lt;BR /&gt;For some reason the controller did not access the TD associated with this packet:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="applescript"&gt;/* -----       IF Using WinUSB.sys driver   --------------- */
#ifdef USE_WINUSB_DRIVER

#include &amp;lt;tchar.h&amp;gt;
#include &amp;lt;strsafe.h&amp;gt;
#include &amp;lt;winusb.h&amp;gt;
#include &amp;lt;usb.h&amp;gt;
#include &amp;lt;cstdlib&amp;gt;
#include &amp;lt;initguid.h&amp;gt;
#include &amp;lt;cfgmgr32.h&amp;gt;
#include &amp;lt;combaseapi.h&amp;gt;

//
// Device Interface GUID.
// Used by all WinUsb devices that this application talks to.
// Must match "DeviceInterfaceGUIDs" registry value specified in the INF file.
// yyyyyy-yyyy-yyyy-xxxx-yyyyyyyy
//
DEFINE_GUID(GUID_DEVINTERFACE_ECGUSB1, 0xyyyyyyyy, 0xyyyy, 0xyyy, 0xxx, 0xxx, 0xyy, 0xyy, 0xyy, 0xyy, 0xyy, 0xyy);



#define ISOCH_DATA_SIZE_MS	10
#define ISOCH_TRANSFER_COUNT	2		//will need to be at least 2

/*
*  My device sends one sample of 2 bytes every 1ms .. =&amp;gt; data sample rate = 1000s/s
* 
*  Problem !!
*  Only Transfer 1 has the data all next (ISOCH_TRANSFER_COUNT) are empty
*  As a result i see data arriving at sample rate of 1000 / ISOCH_TRANSFER_COUNT  in Read application
* 
*  Why ?????
* 
nvUSB.lib: Current Frame number=261744397
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.
nvUSB.lib: Current Frame number=261744447
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes.					&amp;lt;-- ??
nvUSB.lib: Current Frame number=261744497
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.
nvUSB.lib: Current Frame number=261744547
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes.					&amp;lt;--- ??
nvUSB.lib: Current Frame number=261744597
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.
nvUSB.lib: Current Frame number=261744647
nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.
nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes.
nvUSB.lib: Current Frame number=261744697


*/





typedef struct _PCECG_PIPE_INFORMATION_EX {
	USBD_PIPE_TYPE PipeType;
	UCHAR          PipeId;
	USHORT         MaximumPacketSize;
	UCHAR          Interval;
	ULONG          MaximumBytesPerInterval;
	int			   index;
} PCECG_PIPE_INFORMATION_EX, * PPCECG_PIPE_INFORMATION_EX;


struct PIPE_ID
{
	// Note:
	// Each USB device can define up to 32 endpoints(16 inputs and 16 outputs though one must be a control endpoint)
	// Here i assume that we will use maximum 2 for each type..
	PCECG_PIPE_INFORMATION_EX  Bulk_Pipe[2]; // [0] -for IN type ; [1] -for OUT type 
	PCECG_PIPE_INFORMATION_EX  Int_Pipe[2];
	PCECG_PIPE_INFORMATION_EX  Iso_Pipe[2];
};


typedef struct _RING_BUFFER
{
	PUCHAR      buffer;
	PUCHAR      inPtr;
	PUCHAR      outPtr;
	SIZE_T      totalSize;
	SIZE_T      currentSize;
	KSPIN_LOCK	spinLock;

	SIZE_T      Size;
	PUCHAR      Base;
	PUCHAR      End;
	PUCHAR      Head;
	PUCHAR      Tail;

} RING_BUFFER, * PRING_BUFFER;



class CUsbPCECGHelper
{
public:
	//  constructor
	CUsbPCECGHelper();
	// destructor
	virtual ~CUsbPCECGHelper();

	BOOL GetDeviceHandle(GUID guidDeviceInterface, PHANDLE hDeviceHandle);
	BOOL GetWinUSBHandle(HANDLE hDeviceHandle, PWINUSB_INTERFACE_HANDLE phWinUSBHandle);
	BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed);
	BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid);

	void ClearIsobuffers(void);
	void ClearDeviceHandles(void);
	void ClearThreadHandles(void);
	DWORD StartThreadHandles(void);

	HANDLE						m_hDeviceHandle ;
	WINUSB_INTERFACE_HANDLE		m_hWinUSBHandle[2];
	PIPE_ID						PipeID;
	DRIVER_VERSION				drvver;
	BOOL						RealTimeInProgress;

	ULONG						IsochInTransferSize;
	ULONG						IsochInPacketCount;
	PUCHAR						readBuffer;
	LPOVERLAPPED				overlapped;
	WINUSB_ISOCH_BUFFER_HANDLE	isochReadBufferHandle;
	PUSBD_ISO_PACKET_DESCRIPTOR isochPacketDescriptors;


	//reading execution thread handle
	HANDLE						m_hEventThread;
	//event handle to close execution thread
	HANDLE						m_hCloseThread;
	//event handle for read 
	HANDLE						m_hReadAsync[ISOCH_TRANSFER_COUNT];
	DWORD						m_dwInterval;
	BOOL						m_bResult;

	DWORD ReadIsoBuffer(DWORD eventIndex);

	// Data Event thread procedure.
	static DWORD WINAPI AsyncReadThreadProc(__in LPVOID pvData);


	PRING_BUFFER	m_DataRingBuffer;

	PRING_BUFFER	AllocRingBuffer( SIZE_T    Size	);
	VOID			FreeRingBuffer(	PRING_BUFFER   ringBuffer);
	SIZE_T			ReadRingBuffer(	PRING_BUFFER   ringBuffer,	PUCHAR    readBuffer,	SIZE_T   numberOfBytesToRead );
	SIZE_T			WriteRingBuffer(PRING_BUFFER   ringBuffer,	PUCHAR    writeBuffer,	SIZE_T   numberOfBytesToWrite);
	VOID			RingBufferGetAvailableSpace(PRING_BUFFER      ringBuffer,	SIZE_T* AvailableSpace );
	VOID			RingBufferGetAvailableData(	PRING_BUFFER      ringBuffer,	SIZE_T* AvailableData	);

};


CUsbPCECGHelper		helperfunctionsc_class;


#endif

#ifdef USE_WINUSB_DRIVER

CUsbPCECGHelper::CUsbPCECGHelper()
{
	m_hDeviceHandle	   = INVALID_HANDLE_VALUE;
	m_hWinUSBHandle[0] = INVALID_HANDLE_VALUE;
	m_hWinUSBHandle[1] = INVALID_HANDLE_VALUE;

	drvver.MajorVersion = 0;
	drvver.MinorVersion = 0;
	drvver.BuildVersion = 0;

	PipeID.Bulk_Pipe[0].index = -1;
	PipeID.Int_Pipe [0].index = -1;
	PipeID.Iso_Pipe [0].index = -1;

	PipeID.Bulk_Pipe[1].index = -1;
	PipeID.Int_Pipe [1].index = -1;
	PipeID.Iso_Pipe [1].index = -1;

	RealTimeInProgress = FALSE;

	readBuffer = NULL;
	isochPacketDescriptors = NULL;
	overlapped = NULL;
	isochReadBufferHandle = INVALID_HANDLE_VALUE;

	m_hEventThread = NULL;
	m_hCloseThread = NULL;
	m_bResult = FALSE;


	m_DataRingBuffer = NULL;
	m_DataRingBuffer = AllocRingBuffer(64 * 1024);
}

CUsbPCECGHelper::~CUsbPCECGHelper()
{
	ClearThreadHandles();
	ClearIsobuffers();
	ClearDeviceHandles();

	FreeRingBuffer(m_DataRingBuffer);
}


void  CUsbPCECGHelper::ClearThreadHandles(void)
{
	if (NULL != m_hCloseThread)
	{
		// Stop the event thread.
		::SetEvent(m_hCloseThread);

		// Wait for the thread to end.
		::WaitForSingleObject(m_hEventThread, INFINITE);

		if (NULL != m_hEventThread)
		{
			CloseHandle(m_hEventThread);
			m_hEventThread = NULL;
		}

		CloseHandle(m_hCloseThread);
		m_hCloseThread = NULL;
	}
}

void CUsbPCECGHelper::ClearIsobuffers(void)
{
	//ULONG i;

	if (isochReadBufferHandle != INVALID_HANDLE_VALUE)
	{
		WinUsb_UnregisterIsochBuffer(isochReadBufferHandle);
		isochReadBufferHandle = INVALID_HANDLE_VALUE;
	}

	if (readBuffer != NULL)
	{
		delete[] readBuffer;
		readBuffer = NULL;
	}

	if (isochPacketDescriptors != NULL)
	{
		delete[] isochPacketDescriptors;
		isochPacketDescriptors = NULL;
	}

/*	for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
	{
		if (overlapped[i].hEvent != NULL)
		{
			CloseHandle(overlapped[i].hEvent);
			overlapped[i].hEvent = NULL;
		}
	}*/

	if (overlapped != NULL)
	{
		delete[] overlapped;
		overlapped = NULL;
	}
}

void CUsbPCECGHelper::ClearDeviceHandles(void)
{
	if (m_hWinUSBHandle[0] != INVALID_HANDLE_VALUE)
	{
		WinUsb_Free(m_hWinUSBHandle[0]);
		m_hWinUSBHandle[0] = INVALID_HANDLE_VALUE;
	}

	if (m_hWinUSBHandle[1] != INVALID_HANDLE_VALUE)
	{
		WinUsb_Free(m_hWinUSBHandle[1]);
		m_hWinUSBHandle[1] = INVALID_HANDLE_VALUE;
	}

	if (m_hDeviceHandle != INVALID_HANDLE_VALUE)
	{
		CloseHandle(m_hDeviceHandle);
		m_hDeviceHandle = INVALID_HANDLE_VALUE;
	}

}

DWORD CUsbPCECGHelper::StartThreadHandles(void)
{
	DWORD result = S_OK;

	if (m_hWinUSBHandle[0] == INVALID_HANDLE_VALUE)
	{
		return E_HANDLE;
	}


	// Create the event used to close the thread.
	if (NULL == m_hCloseThread)
	{
		m_hCloseThread = ::CreateEvent(NULL, FALSE, FALSE, TEXT("CloseThreadEvent"));
	}
	if (NULL == m_hCloseThread)
	{
		result=E_UNEXPECTED;
	}

	if (SUCCEEDED(result) &amp;amp;&amp;amp; (m_hEventThread == NULL))
	{
		m_hEventThread = ::CreateThread(NULL,        // Cannot be inherited by child process
			0,                                       // Default stack size
			&amp;amp;CUsbPCECGHelper::AsyncReadThreadProc,	 // Thread proc
			(LPVOID)this,                            // Thread proc argument
			0,                                       // Starting state = running
			NULL);                                   // No thread identifier

		if (NULL == m_hEventThread)
		{
			result = E_UNEXPECTED;
		}
		else
		{
			//DWORD dwError, dwThreadPri;
			if (!SetThreadPriority(m_hEventThread, THREAD_PRIORITY_HIGHEST))
			{
				//dwError = GetLastError();
				result = E_UNEXPECTED;
			}
			//dwThreadPri = GetThreadPriority(m_hEventThread);
		}
	}

	return result;
}


DWORD WINAPI CUsbPCECGHelper::AsyncReadThreadProc(__in LPVOID pvData)
{

#if(1)

	//--------------

	HANDLE hEvents[ISOCH_TRANSFER_COUNT+1];
	DWORD dwWait = 0;
	DWORD dwNum = 0;
	USHORT headerSize = 3;
	ULONG bytesRead = 0;
	BOOL b = FALSE;
	ULONG i;
	BOOL result = FALSE;

	// Cast the argument to the correct type
	CUsbPCECGHelper* pThis = static_cast&amp;lt;CUsbPCECGHelper*&amp;gt;(pvData);

	// New threads must always CoInitialize
	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

	ULONG totalTransferSize = pThis-&amp;gt;IsochInTransferSize * ISOCH_TRANSFER_COUNT;

	pThis-&amp;gt;readBuffer = new UCHAR[totalTransferSize];
	if (pThis-&amp;gt;readBuffer == NULL)
	{
		//sprintf_s(s, sizeof(s), "nvUSB.lib: bStart() Unable to allocate memory\n");
		//OutputDebugString((LPCSTR)s);
		hr = E_UNEXPECTED;
	}
	else
	{
		ZeroMemory(pThis-&amp;gt;readBuffer, totalTransferSize);
	}

	hEvents[0] = pThis-&amp;gt;m_hCloseThread;

	for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
	{
		pThis-&amp;gt;m_hReadAsync[i] = CreateEvent(
			NULL,    // default security attribute
			TRUE,    // manual-reset event
			FALSE,   // initial state = not signaled
			NULL);   // unnamed event object
	}

	for (i = 1; i &amp;lt; (ISOCH_TRANSFER_COUNT+1); i++)
		hEvents[i] = pThis-&amp;gt;m_hReadAsync[i-1];

	if (SUCCEEDED(hr))
	{
		pThis-&amp;gt;overlapped = new OVERLAPPED[ISOCH_TRANSFER_COUNT];
		ZeroMemory(pThis-&amp;gt;overlapped, (sizeof(OVERLAPPED) * ISOCH_TRANSFER_COUNT));
		for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
		{
//			pThis-&amp;gt;overlapped[i].hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

			pThis-&amp;gt;overlapped[i].hEvent = pThis-&amp;gt;m_hReadAsync[i];
			// Initialize the rest of the OVERLAPPED structure to zero.
			pThis-&amp;gt;overlapped[i].Internal = 0;
			pThis-&amp;gt;overlapped[i].InternalHigh = 0;
			pThis-&amp;gt;overlapped[i].Offset = 0;
			pThis-&amp;gt;overlapped[i].OffsetHigh = 0;

			if (pThis-&amp;gt;overlapped[i].hEvent == NULL)
			{
				//sprintf_s(s, sizeof(s), "nvUSB.lib: bStart() Unable to set event for overlapped operation\n");
				//OutputDebugString((LPCSTR)s);
				hr = E_UNEXPECTED;
			}
		}
	}

	if (SUCCEEDED(hr))
	{
		result = WinUsb_RegisterIsochBuffer(
			pThis-&amp;gt;m_hWinUSBHandle[0],			// An opaque handle to an interface in the selected configuration. That handle must be created by a previous call to WinUsb_Initialize or WinUsb_GetAssociatedInterface.
			pThis-&amp;gt;PipeID.Iso_Pipe[0].PipeId,	// Derived from Bit 3...0 of the bEndpointAddress field in the endpoint descriptor.
			pThis-&amp;gt;readBuffer,					// Pointer to the transfer buffer to be registered.
			totalTransferSize,					// Length, in bytes, of the transfer buffer pointed to by Buffer.
			&amp;amp;pThis-&amp;gt;isochReadBufferHandle);		// Receives an opaque handle to the registered buffer. This handle is required by other WinUSB functions that perform isochronous transfers. To release the handle, call the WinUsb_UnregisterIsochBuffer function.

		if (!result)
		{
			//sprintf_s(s, sizeof(s), "nvUSB.lib: bStart() Isoch buffer registration failed.\n");
			//OutputDebugString((LPCSTR)s);

			hr = E_UNEXPECTED;
		}
	}

	if (SUCCEEDED(hr))
	{
		pThis-&amp;gt;isochPacketDescriptors = new USBD_ISO_PACKET_DESCRIPTOR[pThis-&amp;gt;IsochInPacketCount * ISOCH_TRANSFER_COUNT];
		ZeroMemory(pThis-&amp;gt;isochPacketDescriptors, pThis-&amp;gt;IsochInPacketCount * ISOCH_TRANSFER_COUNT);


		//for iso endpoints read this
		//https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/getting-set-up-to-use-windows-devices-usb
		//

		for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
		{
			result = WinUsb_ReadIsochPipeAsap(
				pThis-&amp;gt;isochReadBufferHandle,			// An opaque handle to the transfer buffer that was registered by a previous call to WinUsb_RegisterIsochBuffer.
				pThis-&amp;gt;IsochInTransferSize * i,			// Offset into the buffer relative to the start the transfer.
				pThis-&amp;gt;IsochInTransferSize,				// Length in bytes of the transfer buffer.
				(i == 0) ? FALSE : TRUE,				// Indicates that the transfer should only be submitted if it can be scheduled in the first frame after the last pending transfer.
				pThis-&amp;gt;IsochInPacketCount,				// Total number of isochronous packets required to hold the transfer buffer.Also indicates the number of elements in the array pointed to by IsoPacketDescriptors.
				&amp;amp;pThis-&amp;gt;isochPacketDescriptors[i * pThis-&amp;gt;IsochInPacketCount], //An array of USBD_ISO_PACKET_DESCRIPTOR that receives the details of each isochronous packet in the transfer.
				&amp;amp;pThis-&amp;gt;overlapped[i]);					// Pointer to an OVERLAPPED structure used for asynchronous operations.

			if (!result)
			{
				DWORD  lastError = GetLastError();

				if (lastError != ERROR_IO_PENDING)
				{
					//sprintf_s(s, sizeof(s), "nvUSB.lib: bStart() Failed to start a read operation with error %x\n", lastError);
					//OutputDebugString((LPCSTR)s);
					hr = E_UNEXPECTED;
				}
			}
		}
	}
	//--------------


	if (SUCCEEDED(hr))
	{
		while (true)
		{	
			for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
				pThis-&amp;gt;m_bResult = ResetEvent(pThis-&amp;gt;m_hReadAsync[i]);

			dwWait = WaitForMultipleObjects(ISOCH_TRANSFER_COUNT+1,			   // number of event objects 
				hEvents,      // array of event objects 
				FALSE,        // does not wait for all 
				INFINITE	   // waits indefinitely 
			);
	

			if (dwWait == WAIT_OBJECT_0) //STOP_THREAD
			{
				CoUninitialize();

				for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
					CloseHandle(pThis-&amp;gt;m_hReadAsync[i]);

				return 0;
			}
			else
			{
				for (i = 1; i &amp;lt; (ISOCH_TRANSFER_COUNT + 1); i++)
				{
					if (dwWait == (WAIT_OBJECT_0 + i))
					{
						pThis-&amp;gt;ReadIsoBuffer((i-1));
					}
				}
			}
		}
	}

#endif


#if(0)

	OVERLAPPED oOverlap;
	HANDLE hEvents[2];
	DWORD dwWait = 0;
	DWORD dwNum = 0;
	const DWORD STOP_THREAD = WAIT_OBJECT_0;
	const DWORD READ_EVENT  = WAIT_OBJECT_0 + 1;
	USHORT headerSize = 3;
	UCHAR buffer[3];
	ULONG bytesRead = 0;
	BOOL b = FALSE;
	


	// Cast the argument to the correct type
	CUsbPCECGHelper* pThis = static_cast&amp;lt;CUsbPCECGHelper*&amp;gt;(pvData);

	// New threads must always CoInitialize
	HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

	
	hEvents[0] = pThis-&amp;gt;m_hCloseThread;

	pThis-&amp;gt;m_hReadAsync = CreateEvent(
		NULL,    // default security attribute
		TRUE,    // manual-reset event
		FALSE,   // initial state = not signaled
		NULL);   // unnamed event object


	hEvents[1] = pThis-&amp;gt;m_hReadAsync;

/*
	oOverlap.hEvent = pThis-&amp;gt;m_hReadAsync;
	// Initialize the rest of the OVERLAPPED structure to zero.
	oOverlap.Internal = 0;
	oOverlap.InternalHigh = 0;
	oOverlap.Offset = 0;
	oOverlap.OffsetHigh = 0;
*/

	

	if (SUCCEEDED(hr))
	{
		while (true)
		{
			/*
			pThis-&amp;gt;m_bResult = ResetEvent(pThis-&amp;gt;m_hReadAsync);
			pThis-&amp;gt;ReadHeader(buffer, headerSize, &amp;amp;bytesRead, &amp;amp;oOverlap);
			dwWait = WaitForMultipleObjects(2,			   // number of event objects 
				hEvents,      // array of event objects 
				FALSE,        // does not wait for all 
				INFINITE	   // waits indefinitely 
			);
			b = WinUsb_GetOverlappedResult(pThis-&amp;gt;m_UsbHandle[1], &amp;amp;oOverlap, &amp;amp;dwNum, FALSE);
			*/

			pThis-&amp;gt;m_bResult = ResetEvent(pThis-&amp;gt;m_hReadAsync);
			dwWait = WaitForMultipleObjects(2,			   // number of event objects 
				hEvents,      // array of event objects 
				FALSE,        // does not wait for all 
				INFINITE	   // waits indefinitely 
			);

			switch (dwWait)
			{
			case STOP_THREAD:
				CoUninitialize();
				CloseHandle(pThis-&amp;gt;m_hReadAsync);
				return 0;
				//break;
			case READ_EVENT:
				/*
				//reads the rest of the message if exist, throws events if needed
				if (b)
				{
					pThis-&amp;gt;ParseDataMessage(buffer);
				}
				else
				{
					//error
					WinUsb_FlushPipe(pThis-&amp;gt;m_UsbHandle[1], pThis-&amp;gt;m_bulkInPipe);
				}
				break;
				*/
			default:
				break;
			}
		}
	}

#endif

	//code not reached
	return 1;
}


DWORD CUsbPCECGHelper::ReadIsoBuffer(DWORD eventIndex)
{
#if(1)

	/*
		//for iso endpoints read this
		//https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/getting-set-up-to-use-windows-devices-usb
		//https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/transfer-data-to-isochronous-endpoints
		//
	*/


	char	s[256];
	DWORD	Status = UsbPCECG_ERR_SUCCESS;
	ULONG	i, j;
	BOOL	result;
	DWORD	lastError;
	ULONG	numBytes = 0;
	BOOL    ContinueStream = TRUE;

	ULONG				frameNumber;
	ULONG				startFrame;
	LARGE_INTEGER		timeStamp;

	if (helperfunctionsc_class.m_hWinUSBHandle[0] == INVALID_HANDLE_VALUE)
	{
		return UsbPCECG_ERR_READISOBUFF;
	}


	result = WinUsb_GetCurrentFrameNumber(
		helperfunctionsc_class.m_hWinUSBHandle[0],
		&amp;amp;frameNumber,
		&amp;amp;timeStamp);

	if (!result)
	{
		sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() WinUsb_GetCurrentFrameNumber failed. \n");
		OutputDebugString((LPCSTR)s);

		return UsbPCECG_ERR_READISOBUFF;
	}

	sprintf_s(s, sizeof(s), "nvUSB.lib: Current Frame number=%d\n", frameNumber);
	OutputDebugString((LPCSTR)s);


	startFrame = frameNumber + 10;

	i = eventIndex;
//	for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
	{
		if (helperfunctionsc_class.RealTimeInProgress == FALSE)
		{
			return UsbPCECG_ERR_READISOBUFF;
		}

		result = WinUsb_GetOverlappedResult(
			helperfunctionsc_class.m_hWinUSBHandle[0],
			&amp;amp;helperfunctionsc_class.overlapped[i],
			&amp;amp;numBytes,
			TRUE);

		if (!result || numBytes == 0)
		{
			//0x1F  = ERROR_GEN_FAILURE				A device attached to the system is not functioning.
			//0x7A  = ERROR_INSUFFICIENT_BUFFER     The data area passed to a system call is too small.
			//0x57  = ERROR_INVALID_PARAMETER       The parameter is incorrect.
			//0x3E5 = ERROR_IO_PENDING              Overlapped I/O operation is in progress.

			lastError = GetLastError();

			if (lastError == ERROR_IO_PENDING) //The transfer is pending..
			{
				// try again..
				if (i &amp;gt; 0) i--;
//				continue;
			}

			sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Failed to read with error %x \n", lastError);
			OutputDebugString((LPCSTR)s);

			return UsbPCECG_ERR_READISOBUFF;
		}
		else
		{
			numBytes = 0;
			for (j = 0; j &amp;lt; helperfunctionsc_class.IsochInPacketCount; j++)
			{
				numBytes += helperfunctionsc_class.isochPacketDescriptors[j].Length;

				//sprintf_s(s, sizeof(s), "%d-%d-%d\n", helperfunctionsc_class.isochPacketDescriptors[j].Length, helperfunctionsc_class.isochPackets[j].Offset, helperfunctionsc_class.isochPackets[j].Status);
				//OutputDebugString((LPCSTR)s);

				/*
				if (helperfunctionsc_class.isochPacketDescriptors[j].Length != 0 &amp;amp;&amp;amp; helperfunctionsc_class.isochPackets[j].Status == 0)
				{
					memcpy(inBuffer, helperfunctionsc_class.readBuffer + helperfunctionsc_class.isochPacketDescriptors[j].Offset, helperfunctionsc_class.isochPacketDescriptors[j].Length);
					*nWriten += helperfunctionsc_class.isochPacketDescriptors[j].Length;
					inBuffer += helperfunctionsc_class.isochPacketDescriptors[j].Length;
				}
				*/

				/*

				!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

				sprintf_s(s, sizeof(s), "nvUSB.lib: desc.lenght=%d bytes descr.status=%x\n", helperfunctionsc_class.isochPacketDescriptors[j].Length, helperfunctionsc_class.isochPacketDescriptors[j].Status);
				OutputDebugString((LPCSTR)s);

				for ECGUSB1D-EX get
				nvUSB.lib: desc.lenght=2 bytes descr.status=0           if OK
				nvUSB.lib: desc.lenght=0 bytes descr.status=c0020000    if empty packet

				WD_USBD_STATUS_ISO_NOT_ACCESSED_BY_HW

				Extended isochronous error codes returned by USBD.
				These errors appear in the packet status field of an isochronous transfer. [0xC0020000]
				For some reason the controller did not access the TD associated with this packet:


				!
				When the USB driver stack processes the URB, the driver discards all isochronous packets in the URB whose frame numbers are lower than the current frame number.
				The driver stack sets the Status member of the packet descriptor for each discarded packet to USBD_STATUS_ISO_NA_LATE_USBPORT, USBD_STATUS_ISO_NOT_ACCESSED_BY_HW,
				or USBD_STATUS_ISO_NOT_ACCESSED_LATE. Even though some packets in the URB are discarded, the driver stack attempts to transmit only those packets whose frame numbers
				are higher than the current frame number.
				!!

				*/
				/*
				if (helperfunctionsc_class.isochPacketDescriptors[j].Length == 0 &amp;amp;&amp;amp; helperfunctionsc_class.isochPacketDescriptors[j].Status == USBD_STATUS_ISO_NOT_ACCESSED_BY_HW)
				{
					if (!(WinUsb_FlushPipe(helperfunctionsc_class.m_hWinUSBHandle[0], helperfunctionsc_class.PipeID.Iso_Pipe[0].PipeId)))
					{
						sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() error flush pipe %d.\n", GetLastError());
						OutputDebugString((LPCSTR)s);

						return	UsbPCECG_ERR_RESETPIPE;
					}
				}
				*/

				if (helperfunctionsc_class.isochPacketDescriptors[j].Length != 0 &amp;amp;&amp;amp; helperfunctionsc_class.isochPacketDescriptors[j].Status == 0)
				{
					WriteRingBuffer(
						helperfunctionsc_class.m_DataRingBuffer,
						(helperfunctionsc_class.readBuffer + helperfunctionsc_class.isochPacketDescriptors[j].Offset),
						helperfunctionsc_class.isochPacketDescriptors[j].Length
					);
				}
			}

			sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Requested %d bytes in %d packets per transfer.\n", helperfunctionsc_class.IsochInTransferSize, helperfunctionsc_class.IsochInPacketCount);
			OutputDebugString((LPCSTR)s);
		}

		sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Transfer %d completed. Read %d bytes. \n", i + 1, numBytes);
		OutputDebugString((LPCSTR)s);


		result = WinUsb_ReadIsochPipeAsap(
			helperfunctionsc_class.isochReadBufferHandle,
			helperfunctionsc_class.IsochInTransferSize * i,
			helperfunctionsc_class.IsochInTransferSize,
			ContinueStream,
			helperfunctionsc_class.IsochInPacketCount,
			&amp;amp;helperfunctionsc_class.isochPacketDescriptors[i * helperfunctionsc_class.IsochInPacketCount],
			&amp;amp;helperfunctionsc_class.overlapped[i]);


		/*
		// not working
		// return with nvUSB.lib: bRead() Failed to read with error 1f  after first time..
		result = WinUsb_ReadIsochPipe(
			helperfunctionsc_class.isochReadBufferHandle,
			helperfunctionsc_class.IsochInTransferSize * i,
			helperfunctionsc_class.IsochInTransferSize,
			&amp;amp;startFrame,
			helperfunctionsc_class.IsochInPacketCount,
			&amp;amp;helperfunctionsc_class.isochPacketDescriptors[i * helperfunctionsc_class.IsochInPacketCount],
			&amp;amp;helperfunctionsc_class.overlapped[i]);
		*/

		if (!result)
		{
			lastError = GetLastError();

			if (lastError == ERROR_INVALID_PARAMETER &amp;amp;&amp;amp; ContinueStream)
			{
				ContinueStream = FALSE;
//				continue;
			}

			if (lastError != ERROR_IO_PENDING)
			{
				sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Failed to start a read operation with error %x\n", lastError);
				OutputDebugString((LPCSTR)s);

				return UsbPCECG_ERR_READISOBUFF;
			}

			ContinueStream = TRUE;
		}

	}

	return(Status);

#endif


#if(0)

	/*
		//for iso endpoints read this
		//https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/getting-set-up-to-use-windows-devices-usb
		//https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/transfer-data-to-isochronous-endpoints
		//
	*/


	char	s[256];
	DWORD	Status = UsbPCECG_ERR_SUCCESS;
	ULONG	i, j;
	BOOL	result;
	DWORD	lastError;
	ULONG	numBytes=0;
	BOOL    ContinueStream = TRUE;

	ULONG				frameNumber;
	ULONG				startFrame;
	LARGE_INTEGER		timeStamp;

	if (helperfunctionsc_class.m_hWinUSBHandle[0] == INVALID_HANDLE_VALUE)
	{
		return UsbPCECG_ERR_READISOBUFF;
	}


	result = WinUsb_GetCurrentFrameNumber(
		helperfunctionsc_class.m_hWinUSBHandle[0],
		&amp;amp;frameNumber,
		&amp;amp;timeStamp);

	if (!result)
	{
		sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() WinUsb_GetCurrentFrameNumber failed. \n");
		OutputDebugString((LPCSTR)s);

		return UsbPCECG_ERR_READISOBUFF;
	}

	startFrame = frameNumber + 10;


	for (i = 0; i &amp;lt; ISOCH_TRANSFER_COUNT; i++)
	{
		if (helperfunctionsc_class.RealTimeInProgress == FALSE)
		{
			return UsbPCECG_ERR_READISOBUFF;
		}

		result = WinUsb_GetOverlappedResult(
			helperfunctionsc_class.m_hWinUSBHandle[0],
			&amp;amp;helperfunctionsc_class.overlapped[i],
			&amp;amp;numBytes,
			TRUE);

		if (!result || numBytes==0)
		{
			//0x1F  = ERROR_GEN_FAILURE				A device attached to the system is not functioning.
			//0x7A  = ERROR_INSUFFICIENT_BUFFER     The data area passed to a system call is too small.
			//0x57  = ERROR_INVALID_PARAMETER       The parameter is incorrect.
			//0x3E5 = ERROR_IO_PENDING              Overlapped I/O operation is in progress.

			lastError = GetLastError();

			if (lastError == ERROR_IO_PENDING) //The transfer is pending..
			{
				// try again..
				if (i &amp;gt; 0) i--; 
				continue;
			}

			sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Failed to read with error %x \n", lastError);
			OutputDebugString((LPCSTR)s);

			return UsbPCECG_ERR_READISOBUFF;
		}
		else
		{
			numBytes = 0;
			for (j = 0; j &amp;lt; helperfunctionsc_class.IsochInPacketCount; j++)
			{
				numBytes += helperfunctionsc_class.isochPacketDescriptors[j].Length;

				//sprintf_s(s, sizeof(s), "%d-%d-%d\n", helperfunctionsc_class.isochPacketDescriptors[j].Length, helperfunctionsc_class.isochPackets[j].Offset, helperfunctionsc_class.isochPackets[j].Status);
				//OutputDebugString((LPCSTR)s);

				/*
				if (helperfunctionsc_class.isochPacketDescriptors[j].Length != 0 &amp;amp;&amp;amp; helperfunctionsc_class.isochPackets[j].Status == 0)
				{
					memcpy(inBuffer, helperfunctionsc_class.readBuffer + helperfunctionsc_class.isochPacketDescriptors[j].Offset, helperfunctionsc_class.isochPacketDescriptors[j].Length);
					*nWriten += helperfunctionsc_class.isochPacketDescriptors[j].Length;
					inBuffer += helperfunctionsc_class.isochPacketDescriptors[j].Length;
				}
				*/

				/*
				 
				!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
				
				sprintf_s(s, sizeof(s), "nvUSB.lib: desc.lenght=%d bytes descr.status=%x\n", helperfunctionsc_class.isochPacketDescriptors[j].Length, helperfunctionsc_class.isochPacketDescriptors[j].Status);
				OutputDebugString((LPCSTR)s);

				for ECGUSB1D-EX get
				nvUSB.lib: desc.lenght=2 bytes descr.status=0           if OK
				nvUSB.lib: desc.lenght=0 bytes descr.status=c0020000    if empty packet

				WD_USBD_STATUS_ISO_NOT_ACCESSED_BY_HW

				Extended isochronous error codes returned by USBD.
				These errors appear in the packet status field of an isochronous transfer. [0xC0020000] 
				For some reason the controller did not access the TD associated with this packet:


				!
				When the USB driver stack processes the URB, the driver discards all isochronous packets in the URB whose frame numbers are lower than the current frame number. 
				The driver stack sets the Status member of the packet descriptor for each discarded packet to USBD_STATUS_ISO_NA_LATE_USBPORT, USBD_STATUS_ISO_NOT_ACCESSED_BY_HW, 
				or USBD_STATUS_ISO_NOT_ACCESSED_LATE. Even though some packets in the URB are discarded, the driver stack attempts to transmit only those packets whose frame numbers 
				are higher than the current frame number.
				!!

				*/

				if (helperfunctionsc_class.isochPacketDescriptors[j].Length != 0 &amp;amp;&amp;amp; helperfunctionsc_class.isochPacketDescriptors[j].Status == 0)
				{
					WriteRingBuffer(
						helperfunctionsc_class.m_DataRingBuffer,
						(helperfunctionsc_class.readBuffer + helperfunctionsc_class.isochPacketDescriptors[j].Offset),
						helperfunctionsc_class.isochPacketDescriptors[j].Length
					);
				}
			}

			sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Requested %d bytes in %d packets per transfer.\n", helperfunctionsc_class.IsochInTransferSize, helperfunctionsc_class.IsochInPacketCount);
			OutputDebugString((LPCSTR)s);
		}

		sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Transfer %d completed. Read %d bytes. \n", i + 1, numBytes);
		OutputDebugString((LPCSTR)s);

		
		result = WinUsb_ReadIsochPipeAsap(
			helperfunctionsc_class.isochReadBufferHandle,
			helperfunctionsc_class.IsochInTransferSize * i,
			helperfunctionsc_class.IsochInTransferSize,
			ContinueStream,
			helperfunctionsc_class.IsochInPacketCount,
			&amp;amp;helperfunctionsc_class.isochPacketDescriptors[i * helperfunctionsc_class.IsochInPacketCount],
			&amp;amp;helperfunctionsc_class.overlapped[i]);
		

		/*
		// not working 
		// return with nvUSB.lib: bRead() Failed to read with error 1f  after first time..
		result = WinUsb_ReadIsochPipe(
			helperfunctionsc_class.isochReadBufferHandle,
			helperfunctionsc_class.IsochInTransferSize * i,
			helperfunctionsc_class.IsochInTransferSize,
			&amp;amp;startFrame,
			helperfunctionsc_class.IsochInPacketCount,
			&amp;amp;helperfunctionsc_class.isochPacketDescriptors[i * helperfunctionsc_class.IsochInPacketCount],
			&amp;amp;helperfunctionsc_class.overlapped[i]);
		*/

		if (!result)
		{
			lastError = GetLastError();

			if (lastError == ERROR_INVALID_PARAMETER &amp;amp;&amp;amp; ContinueStream)
			{
				ContinueStream = FALSE;
				continue;
			}

			if (lastError != ERROR_IO_PENDING)
			{
				sprintf_s(s, sizeof(s), "nvUSB.lib: bRead() Failed to start a read operation with error %x\n", lastError);
				OutputDebugString((LPCSTR)s);

				return UsbPCECG_ERR_READISOBUFF;
			}

			ContinueStream = TRUE;
		}

	}

	return(Status);

#endif

}


/*
//-----------------------------------------------------------------------------
// GetDeviceHandle()
//
// Parameters:
//        guidDeviceInterface: DEVICE GUID defined in WinUSB inf file
//        hDeviceHandle		 : device handle returned
//
// Return Values:
//        true : success
//        false: fail
//
// Remarks:
//        Function to create file handle for USB device
//-----------------------------------------------------------------------------
*/

BOOL CUsbPCECGHelper::GetDeviceHandle(GUID guidDeviceInterface, PHANDLE hDeviceHandle)
{
	char s[256];

#if(1)
	HRESULT								result;
	HDEVINFO							deviceInfo;
	SP_DEVINFO_DATA						deviceInfoData;
	SP_DEVICE_INTERFACE_DATA			deviceInterfaceData;
	SP_DRVINFO_DATA_A					DriverInfo;
	PSP_DEVICE_INTERFACE_DETAIL_DATA	interfaceDetailData;
	ULONG								requiredLength;
	LPTSTR								devicePath;
	size_t								length;
	BOOL								ret = FALSE;

	result = S_OK;
	interfaceDetailData = NULL;
	requiredLength = 0;
	devicePath = NULL;

	deviceInfo = SetupDiGetClassDevs(
		&amp;amp;guidDeviceInterface,
		NULL,
		NULL, 
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
	);

	if (deviceInfo == INVALID_HANDLE_VALUE)
	{
		result = E_HANDLE;
	}

	if (SUCCEEDED(result))
	{
		// Check that a query for a second interface fails, but that the
		// first interface succeeds
		deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
		if (  !SetupDiEnumDeviceInfo(deviceInfo, 1, &amp;amp;deviceInfoData) 
			&amp;amp;&amp;amp; SetupDiEnumDeviceInfo(deviceInfo, 0, &amp;amp;deviceInfoData))
		{

			// Get the specific device interface
			deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
			if (!SetupDiEnumDeviceInterfaces(deviceInfo, &amp;amp;deviceInfoData,&amp;amp;guidDeviceInterface, 0, &amp;amp;deviceInterfaceData) )
			{
				result = HRESULT_FROM_WIN32(GetLastError());

				sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiEnumDeviceInterfaces failed %d.\n", result);
				OutputDebugString((LPCSTR)s);
			}

			// Check the size needed for the device interface details and 
			// allocate the data needed to get the details
			if (   SUCCEEDED(result) 
				&amp;amp;&amp;amp; !SetupDiGetDeviceInterfaceDetail(deviceInfo,&amp;amp;deviceInterfaceData, NULL, 0, &amp;amp;requiredLength, NULL))
			{
				if     (GetLastError() == ERROR_INSUFFICIENT_BUFFER 
					&amp;amp;&amp;amp; requiredLength &amp;gt; 0)
				{
					interfaceDetailData =(PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, (SIZE_T)requiredLength);
					if (interfaceDetailData == NULL)
					{
						result = E_OUTOFMEMORY;
					}
					else
					{
						result = S_OK;
					}
				}
				else
				{
					result = HRESULT_FROM_WIN32(GetLastError());
				}
			}

			// Get the device interface details
			if (SUCCEEDED(result) &amp;amp;&amp;amp; interfaceDetailData != NULL)
			{
				interfaceDetailData-&amp;gt;cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
				if (!SetupDiGetDeviceInterfaceDetail(deviceInfo,&amp;amp;deviceInterfaceData, interfaceDetailData,requiredLength, NULL, &amp;amp;deviceInfoData))
				{
					result = HRESULT_FROM_WIN32(GetLastError());

					sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiGetDeviceInterfaceDetail failed %d.\n", result);
					OutputDebugString((LPCSTR)s);
				}
			}
			if (SUCCEEDED(result) &amp;amp;&amp;amp; interfaceDetailData != NULL)
			{
				// Build the null terminated device path for the device
				length = _tcslen(interfaceDetailData-&amp;gt;DevicePath) + 1;
				devicePath = (TCHAR*)LocalAlloc(LPTR, length * sizeof(TCHAR));
				if (devicePath != NULL)
				{
					StringCchCopy(devicePath, length,interfaceDetailData-&amp;gt;DevicePath);
					devicePath[length - 1] = 0;

					sprintf_s(s, sizeof(s), "nvUSB.lib: Device path:  %s\n", devicePath);
					OutputDebugString((LPCSTR)s);

					//This what i get on Windows 10 as output:
					// nvUSB.lib: Device path:  \\?\usb#vid_10c4&amp;amp;pid_825f#7&amp;amp;1b060a7f&amp;amp;0&amp;amp;3#{93bd88a4-eb10-4706-8304-c512f18b8e42}

					//------------------ Get winusb driver version -----------------------------------------------------------
					if (!SetupDiBuildDriverInfoList(deviceInfo, &amp;amp;deviceInfoData, SPDIT_COMPATDRIVER))
					{
						result = HRESULT_FROM_WIN32(GetLastError());

						sprintf_s(s, sizeof(s), "nvUSB.lib:  SetupDiBuildDriverInfoList failed %d.\n", result);
						OutputDebugString((LPCSTR)s);

					}
					else
					{
						DriverInfo.cbSize = sizeof(SP_DRVINFO_DATA_A);
						if ((SetupDiEnumDriverInfoA(deviceInfo, &amp;amp;deviceInfoData, SPDIT_COMPATDRIVER, 0, &amp;amp;DriverInfo)))
						{
							sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiEnumDriverInfoA \n");
							OutputDebugString((LPCSTR)s);

							sprintf_s(s, sizeof(s), "nvUSB.lib: winusb driver version %s v.%u.%u.%u.%u\n",
								DriverInfo.Description,
								(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 48) &amp;amp; 0xFFFF,
								(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFF,
								(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF,
								(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 0) &amp;amp; 0xFFFF

							);
							OutputDebugString((LPCSTR)s);

							drvver.MajorVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 48) &amp;amp; 0xFFFF;
							drvver.MinorVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFF;
							drvver.BuildVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF;
						}
						else
						{
							result = HRESULT_FROM_WIN32(GetLastError());

							sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiEnumDriverInfoA failed %d.\n", result);
							OutputDebugString((LPCSTR)s);
						}
					}
					//-------------------------------------------------------------------------------------------------------------
				}
				else
				{
					result = E_OUTOFMEMORY;
				}
			}
		}
	}

	if (SUCCEEDED(result) &amp;amp;&amp;amp; devicePath != NULL)
	{
		ret = TRUE;

		// Open the device handle
		*hDeviceHandle = CreateFile(
			devicePath, 
			GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 
			FILE_FLAG_OVERLAPPED, 
			NULL
		);
		if (*hDeviceHandle == INVALID_HANDLE_VALUE)
		{
			result = HRESULT_FROM_WIN32(GetLastError());

			sprintf_s(s, sizeof(s), "nvUSB.lib: CreateFile failed %d.\n", result);
			OutputDebugString((LPCSTR)s);

			ret = FALSE;
		}
	}

	// Perform cleanup of the allocated data
	if (devicePath != NULL)
	{
		LocalFree(devicePath);
	}
	if (interfaceDetailData != NULL)
	{
		LocalFree(interfaceDetailData);
	}
	if (deviceInfo != INVALID_HANDLE_VALUE)
	{
		(void)SetupDiDestroyDeviceInfoList(deviceInfo);
	}

	
	return ret;

#endif

#if(0)
	
	BOOL bResult = TRUE;
	HDEVINFO hDeviceInfo;
	SP_DEVINFO_DATA DeviceInfoData;
	SP_DRVINFO_DATA_A DriverInfo;
	DriverInfo.cbSize = sizeof(SP_DRVINFO_DATA_A);

	SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
	PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL;

	ULONG requiredLength = 0;

	LPTSTR lpDevicePath = NULL;

	DWORD index = 0;


	sprintf_s(s, sizeof(s), "nvUSB.lib: Enter to GetDeviceHandle\n");
	OutputDebugString((LPCSTR)s);

//	if (guidDeviceInterface == GUID_NULL) {
//		return FALSE;
//	}


	// Get information about all the installed devices for the specified
	// device interface class.
	hDeviceInfo = SetupDiGetClassDevs(
		&amp;amp;guidDeviceInterface,
		NULL,
		NULL,
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	if (hDeviceInfo == INVALID_HANDLE_VALUE) {
		// ERROR 
		sprintf_s(s, sizeof(s), "nvUSB.lib: Error SetupDiGetClassDevs: %d.\n", GetLastError());
		OutputDebugString((LPCSTR)s);

		bResult = FALSE;
		goto done;
	}

	//Enumerate all the device interfaces in the device information set.
	DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);



	for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &amp;amp;DeviceInfoData); index++) {
		
		//Reset for this iteration
		if (lpDevicePath) 
		{
			LocalFree(lpDevicePath);
			lpDevicePath = NULL;
		}

		if (pInterfaceDetailData) 
		{
			LocalFree(pInterfaceDetailData);
			pInterfaceDetailData = NULL;
		}

		// Check if last item
		if (GetLastError() == ERROR_NO_MORE_ITEMS) 
		{
			break;
		}

		deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);

		//Get information about the device interface.
		bResult = SetupDiEnumDeviceInterfaces(
			hDeviceInfo,
			&amp;amp;DeviceInfoData,
			&amp;amp;guidDeviceInterface,
			index,
			&amp;amp;deviceInterfaceData);

		bResult = SetupDiEnumDeviceInterfaces(
			hDeviceInfo,
			&amp;amp;DeviceInfoData,
			&amp;amp;guidDeviceInterface,
			index,
			&amp;amp;deviceInterfaceData);


		// Check if last item
		if (GetLastError() == ERROR_NO_MORE_ITEMS) 
		{
			sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiEnumDeviceInterfaces ERROR_NO_MORE_ITEMS (%d) \n", index);
			OutputDebugString((LPCSTR)s);

			break;
		}

		//Check for some other error
		if (!bResult) {

			sprintf_s(s, sizeof(s), "nvUSB.lib: Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
			OutputDebugString((LPCSTR)s);

			bResult = FALSE;
			goto done;
		}

		//Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA
		//which we need to allocate, so we have to call this function twice.
		//First to get the size so that we know how much to allocate
		//Second, the actual call with the allocated buffer

		bResult = SetupDiGetDeviceInterfaceDetail(
			hDeviceInfo,
			&amp;amp;deviceInterfaceData,
			NULL, 0,
			&amp;amp;requiredLength,
			NULL);


		//Check for some other error
		if (!bResult) {
			if ((ERROR_INSUFFICIENT_BUFFER == GetLastError()) &amp;amp;&amp;amp; (requiredLength &amp;gt; 0)) {
				//we got the size, allocate buffer
				pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength);

				if (!pInterfaceDetailData) {
					// ERROR 
					//printf("Error allocating memory for the device detail buffer.\n");
					sprintf_s(s, sizeof(s), "nvUSB.lib: Error allocating memory for the device detail buffer.\n");
					OutputDebugString((LPCSTR)s);

					bResult = FALSE;
					goto done;
				}
			}
			else {
				//printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
				sprintf_s(s, sizeof(s), "nvUSB.lib: Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError());
				OutputDebugString((LPCSTR)s);

				bResult = FALSE;
				goto done;
			}
		}

		//get the interface detailed data
		pInterfaceDetailData-&amp;gt;cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

		//Now call it with the correct size and allocated buffer
		bResult = SetupDiGetDeviceInterfaceDetail(
			hDeviceInfo,
			&amp;amp;deviceInterfaceData,
			pInterfaceDetailData,
			requiredLength,
			NULL,
			&amp;amp;DeviceInfoData);


		//Check for some other error
		if (!bResult) {
			//printf("Error SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError());
			sprintf_s(s, sizeof(s), "nvUSB.lib: Error SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError());
			OutputDebugString((LPCSTR)s);

			bResult = FALSE;
			goto done;
		}

		if (!SetupDiBuildDriverInfoList(hDeviceInfo, &amp;amp;DeviceInfoData, SPDIT_COMPATDRIVER))
		{
			sprintf_s(s, sizeof(s), "nvUSB.lib: Error SetupDiBuildDriverInfoList: %d.\n", GetLastError());
			OutputDebugString((LPCSTR)s);

		}
		else
		{
			if ((SetupDiEnumDriverInfoA(hDeviceInfo, &amp;amp;DeviceInfoData, SPDIT_COMPATDRIVER, index, &amp;amp;DriverInfo)) != FALSE)
			{
				sprintf_s(s, sizeof(s), "nvUSB.lib: SetupDiEnumDriverInfoA \n");
				OutputDebugString((LPCSTR)s);

				sprintf_s(s, sizeof(s), "nvUSB.lib: winusb driver version %s v.%u.%u.%u.%u\n",
					DriverInfo.Description,
					(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 48) &amp;amp; 0xFFFF,
					(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFF,
					(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF,
					(DWORD32)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 0) &amp;amp; 0xFFFF

				);
				OutputDebugString((LPCSTR)s);

				drvver.MajorVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 48) &amp;amp; 0xFFFF;
				drvver.MinorVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFF;
				drvver.BuildVersion = (WORD)(DriverInfo.DriverVersion &amp;gt;&amp;gt; 16) &amp;amp; 0xFFFF;

				//copy device path
				size_t nLength = _tcslen(pInterfaceDetailData-&amp;gt;DevicePath) + 1;
				lpDevicePath = (TCHAR*)LocalAlloc(LPTR, nLength * sizeof(TCHAR));
				StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData-&amp;gt;DevicePath);
				lpDevicePath[nLength - 1] = 0;

				sprintf_s(s, sizeof(s), "nvUSB.lib: Device path:  %s\n", lpDevicePath);
				OutputDebugString((LPCSTR)s);
				
				//This what i get on Windows 10 as output:
				// nvUSB.lib: Device path:  \\?\usb#vid_10c4&amp;amp;pid_825f#7&amp;amp;1b060a7f&amp;amp;0&amp;amp;3#{93bd88a4-eb10-4706-8304-c512f18b8e42}


				break; //connect to to only one device
			}
		}

	}//for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &amp;amp;DeviceInfoData); index++)

	if (!lpDevicePath) {
		//Error.
		//printf("Error %d.", GetLastError());
		sprintf_s(s, sizeof(s), "nvUSB.lib: lpDevicePath Error %d.\n", GetLastError());
		OutputDebugString((LPCSTR)s);

		bResult = FALSE;
		goto done;
	}

	//Open the device
	*hDeviceHandle = CreateFile(
		lpDevicePath,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_OVERLAPPED,
		NULL);

	if (*hDeviceHandle == INVALID_HANDLE_VALUE) {
		//Error.
		//printf("Error %d.", GetLastError());
		sprintf_s(s, sizeof(s), "nvUSB.lib: CreateFile Error %d.\n", GetLastError());
		OutputDebugString((LPCSTR)s);

		bResult = FALSE;
		goto done;
	}



done:

	if (lpDevicePath) {
		LocalFree(lpDevicePath);
	}

	if (pInterfaceDetailData) {
		LocalFree(pInterfaceDetailData);
	}


	if (!bResult)
	{
		if (hDeviceInfo != INVALID_HANDLE_VALUE)
			SetupDiDestroyDeviceInfoList(hDeviceInfo);
	}
	else
	{
		if (hDeviceInfo != INVALID_HANDLE_VALUE)
			bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo);
	}

	sprintf_s(s, sizeof(s), "nvUSB.lib: Exit from GetDeviceHandle\n");
	OutputDebugString((LPCSTR)s);

	return bResult;

#endif

} // End of GetDeviceHandle()


/*
//-----------------------------------------------------------------------------
// GetWinUSBHandle()
//
// Parameters:
//        hDeviceHandle  : device handle created for the USB device
//        phWinUSBHandle : WinUSB Interface handle returned
//
// Return Values:
//        true : success
//        false: fail
//
// Remarks:
//        Function to get WinUSB Interface Handle for the device
//-----------------------------------------------------------------------------
*/

BOOL CUsbPCECGHelper::GetWinUSBHandle(HANDLE hDeviceHandle, PWINUSB_INTERFACE_HANDLE phWinUSBHandle)
{
	char s[256];
	BOOL bResult = FALSE;

	sprintf_s(s, sizeof(s), "nvUSB.lib: Enter to GetWinUSBHandle\n");
	OutputDebugString((LPCSTR)s);

	if (hDeviceHandle == INVALID_HANDLE_VALUE) 
	{
		sprintf_s(s, sizeof(s), "nvUSB.lib: Exit from GetWinUSBHandle (hDeviceHandle not valid) \n");
		OutputDebugString((LPCSTR)s);
		return FALSE;
	}

	/*
	[in] DeviceHandle
	The handle to the device that CreateFile returned.WinUSB uses overlapped I / O, so FILE_FLAG_OVERLAPPED must be specified in 
	the dwFlagsAndAttributes parameter of CreateFile call for DeviceHandle to have the characteristics necessary for 
	WinUsb_Initialize to function properly.

	[out] InterfaceHandle
	Receives an opaque handle to the first(default) interface on the device.This handle is required by other WinUSB routines that 
	perform operations on the default interface.To release the handle, call the WinUSB_Free function.

	WinUsb_Initialize returns TRUE if the operation succeeds. Otherwise, this routine returns FALSE, and the caller can retrieve the logged 
	error by calling GetLastError.
	*/

	bResult = WinUsb_Initialize(hDeviceHandle, phWinUSBHandle);
	if (!bResult) 
	{
		//Error.
		//printf("WinUsb_Initialize Error %d.", GetLastError());
		sprintf_s(s, sizeof(s), "nvUSB.lib: WinUsb_Initialize Error %d.", GetLastError());
		OutputDebugString((LPCSTR)s);
		return FALSE;
	}


	sprintf_s(s, sizeof(s), "nvUSB.lib: Exit from GetWinUSBHandle \n");
	OutputDebugString((LPCSTR)s);

	return bResult;
} // End of GetWinUSBHandle()



/*
//-----------------------------------------------------------------------------
// GetUSBDeviceSpeed()
//
// Parameters:
//        hDeviceHandle  : WinUSB Interface Handle
//        pDeviceSpeed   : Device Speed returned
//
// Return Values:
//        true : success
//        false: fail
//
// Remarks:
//        Function to get device speed
//-----------------------------------------------------------------------------
*/

BOOL CUsbPCECGHelper::GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed)
{
	char s[256];

	sprintf_s(s, sizeof(s), "nvUSB.lib: Enter to GetUSBDeviceSpeed() \n");
	OutputDebugString((LPCSTR)s);

	if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE) {
		return FALSE;
	}

	BOOL bResult = TRUE;

	ULONG length = sizeof(UCHAR);

	bResult = WinUsb_QueryDeviceInformation(hDeviceHandle, DEVICE_SPEED, &amp;amp;length, pDeviceSpeed);
	if (!bResult) {

		sprintf_s(s, sizeof(s), "nvUSB.lib: Error getting device speed: %d.\n", GetLastError());
		OutputDebugString((LPCSTR)s);

		goto done;
	}

	/*
	if (*pDeviceSpeed == LowSpeed) {

		sprintf_s(s, sizeof(s), "nvUSB.lib: Device speed: %d (Low speed).\n", *pDeviceSpeed);
		OutputDebugString((LPCSTR)s);

		goto done;
	}

	if (*pDeviceSpeed == FullSpeed) {

		sprintf_s(s, sizeof(s), "nvUSB.lib: Device speed: %d (Full speed).\n", *pDeviceSpeed);
		OutputDebugString((LPCSTR)s);

		goto done;
	}
	*/

	if (*pDeviceSpeed == 1) {

		//---!! printf("Device speed: %d - Full speed or lower (initial documentation on MSDN was wrong).\n", *pDeviceSpeed);
		sprintf_s(s, sizeof(s), "nvUSB.lib: Device speed: %d (Full speed or lower).\n", *pDeviceSpeed);
		OutputDebugString((LPCSTR)s);

		goto done;
	}

	if (*pDeviceSpeed == HighSpeed) {

		sprintf_s(s, sizeof(s), "nvUSB.lib: Device speed: %d (High speed).\n", *pDeviceSpeed);
		OutputDebugString((LPCSTR)s);

		goto done;
	}

	sprintf_s(s, sizeof(s), "nvUSB.lib: Exit from GetUSBDeviceSpeed() \n");
	OutputDebugString((LPCSTR)s);
done:
	return bResult;
} // End of GetUSBDeviceSpeed()



/*
//-----------------------------------------------------------------------------
// QueryDeviceEndpoints()
//
// Parameters:
//        hDeviceHandle  : WinUSB Interface Handle
//        pipeid		 : Pipe ID returned
//
// Return Values:
//        true : success
//        false: fail
//
// Remarks:
//        Function to check end points and get pipe ID
//-----------------------------------------------------------------------------
*/

BOOL CUsbPCECGHelper::QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid)
{
	char s[256];

	sprintf_s(s, sizeof(s), "nvUSB.lib: Enter to QueryDeviceEndpoints() \n");
	OutputDebugString((LPCSTR)s);

	if (hDeviceHandle == INVALID_HANDLE_VALUE) {
		return FALSE;
	}

	BOOL bResult = TRUE;

	USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
	ZeroMemory(&amp;amp;InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));

	WINUSB_PIPE_INFORMATION_EX Pipe; ZeroMemory(&amp;amp;Pipe, sizeof(WINUSB_PIPE_INFORMATION_EX));
	//WINUSB_PIPE_INFORMATION  Pipe;	 ZeroMemory(&amp;amp;Pipe, sizeof(WINUSB_PIPE_INFORMATION));
	
	bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &amp;amp;InterfaceDescriptor);

	if (bResult) {
		for (int index = 0; index &amp;lt; InterfaceDescriptor.bNumEndpoints; index++) {
			bResult = WinUsb_QueryPipeEx(hDeviceHandle, 0, index, &amp;amp;Pipe);
			//bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &amp;amp;Pipe);

			if (bResult) {
				if (Pipe.PipeType == UsbdPipeTypeControl) {

					if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Control IN Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						
					}

					if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Control OUT Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						
					}
				}

				if (Pipe.PipeType == UsbdPipeTypeIsochronous) {

					if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) {

						//Printout for ECGUSB1D-EX :
						//nvUSB.lib: Endpoint index: 0 Pipe type: Isochronous IN Pipe ID: 129.
						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Isochronous IN Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Iso_Pipe[0].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Iso_Pipe[0].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Iso_Pipe[0].Interval = Pipe.Interval;
						pipeid-&amp;gt;Iso_Pipe[0].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Iso_Pipe[0].index = index;
						pipeid-&amp;gt;Iso_Pipe[0].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;

						//Printout for ECGUSB1D-EX :
						//nvUSB.lib: Type=1 , Interval=1 , MaximumPacketSize=24 ,MaximumBytesPerInterval=24
						sprintf_s(s, sizeof(s), "nvUSB.lib: Type=%d , Interval=%d , MaximumPacketSize=%d ,MaximumBytesPerInterval=%d\n", 
						Pipe.PipeType,
						Pipe.Interval,
						Pipe.MaximumPacketSize,
						Pipe.MaximumBytesPerInterval
						);
						OutputDebugString((LPCSTR)s);

						/*
						MaximumPacketSize
						The maximum size, in bytes, of the packets that are transmitted on the pipe.

						MaximumBytesPerInterval
						The maximum number of bytes that can be transmitted in single interval. This value may be a larger than 
						the MaximumPacketSize value on high-bandwidth, high-speed periodic endpoints and SuperSpeed periodic endpoints, 
						such as isochronous endpoints.
						*/

					}

					if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Isochronous OUT Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Iso_Pipe[1].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Iso_Pipe[1].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Iso_Pipe[1].Interval = Pipe.Interval;
						pipeid-&amp;gt;Iso_Pipe[1].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Iso_Pipe[1].index = index;
						pipeid-&amp;gt;Iso_Pipe[1].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;
					}

				}

				if (Pipe.PipeType == UsbdPipeTypeBulk) {

					if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Bulk IN Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Bulk_Pipe[0].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Bulk_Pipe[0].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Bulk_Pipe[0].Interval = Pipe.Interval;
						pipeid-&amp;gt;Bulk_Pipe[0].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Bulk_Pipe[0].index = index;
						pipeid-&amp;gt;Bulk_Pipe[0].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;
					}

					if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Bulk OUT Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Bulk_Pipe[1].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Bulk_Pipe[1].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Bulk_Pipe[1].Interval = Pipe.Interval;
						pipeid-&amp;gt;Bulk_Pipe[1].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Bulk_Pipe[1].index = index;
						pipeid-&amp;gt;Bulk_Pipe[1].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;
					}

				}

				if (Pipe.PipeType == UsbdPipeTypeInterrupt) {

					if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Int IN Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Int_Pipe[0].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Int_Pipe[0].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Int_Pipe[0].Interval = Pipe.Interval;
						pipeid-&amp;gt;Int_Pipe[0].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Int_Pipe[0].index = index;
						pipeid-&amp;gt;Int_Pipe[0].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;
					}

					if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId)) {

						sprintf_s(s, sizeof(s), "nvUSB.lib: Endpoint index: %d Pipe type: Int OUT Pipe ID: %d.\n", index,  Pipe.PipeId);
						OutputDebugString((LPCSTR)s);

						pipeid-&amp;gt;Int_Pipe[1].PipeType = Pipe.PipeType;
						pipeid-&amp;gt;Int_Pipe[1].PipeId = Pipe.PipeId;
						pipeid-&amp;gt;Int_Pipe[1].Interval = Pipe.Interval;
						pipeid-&amp;gt;Int_Pipe[1].MaximumPacketSize = Pipe.MaximumPacketSize;
						pipeid-&amp;gt;Int_Pipe[1].index = index;
						pipeid-&amp;gt;Int_Pipe[1].MaximumBytesPerInterval = Pipe.MaximumBytesPerInterval;
					}
				}
			}
			else {
				continue;
			}
		}
	}

	//done:
	return bResult;
} // End of QueryDeviceEndpoints()



PRING_BUFFER
CUsbPCECGHelper::AllocRingBuffer(
	SIZE_T    Size
)
{
	PRING_BUFFER   ringBuffer = NULL;


	ringBuffer = new RING_BUFFER[sizeof(RING_BUFFER)];

	if (!ringBuffer)
		return NULL;

	ringBuffer-&amp;gt;buffer = new UCHAR[Size];

	if (!ringBuffer-&amp;gt;buffer)
	{
		free(ringBuffer);
		return NULL;
	}


	ringBuffer-&amp;gt;Size = Size;
	ringBuffer-&amp;gt;Base = ringBuffer-&amp;gt;buffer;
	ringBuffer-&amp;gt;End = ringBuffer-&amp;gt;buffer + Size;
	ringBuffer-&amp;gt;Head = ringBuffer-&amp;gt;buffer;
	ringBuffer-&amp;gt;Tail = ringBuffer-&amp;gt;buffer;

	ringBuffer-&amp;gt;inPtr = ringBuffer-&amp;gt;buffer;
	ringBuffer-&amp;gt;outPtr = ringBuffer-&amp;gt;buffer;
	ringBuffer-&amp;gt;totalSize = Size;
	ringBuffer-&amp;gt;currentSize = 0;

//	KeInitializeSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock);

	return ringBuffer;
}

VOID
CUsbPCECGHelper::FreeRingBuffer(
	PRING_BUFFER   ringBuffer
)
{
	free(ringBuffer-&amp;gt;buffer);
	free(ringBuffer);
}


VOID
CUsbPCECGHelper::RingBufferGetAvailableSpace(
	PRING_BUFFER      ringBuffer,
	SIZE_T* AvailableSpace
)
{
	PUCHAR headSnapshot = NULL;
	PUCHAR tailSnapshot = NULL;
	PUCHAR tailPlusOne = NULL;

	if (!AvailableSpace)   return;
	//   ASSERT(AvailableSpace);

	   //
	   // Take a snapshot of the head and tail pointers. We will compute the
	   // available space based on this snapshot. This is safe to do in a
	   // single-producer, single-consumer model, because -
	   //     * A producer will call GetAvailableSpace() to determine whether
	   //       there is enough space to write the data it is trying to write.
	   //       The only other thread that could modify the amount of space
	   //       available is the consumer thread, which can only increase the
	   //       amount of space available. Hence it is safe for the producer
	   //       to write based on this snapshot.
	   //     * A consumer thread will call GetAvailableSpace() to determine
	   //       whether there is enough data in the buffer for it to read.
	   //       (Available data = Buffer size - Available space). The only
	   //       other thread that could modify the amount of space available
	   //       is the producer thread, which can only decrease the amount of
	   //       space available (thereby increasing the amount of data
	   //       available. Hence it is safe for the consumer to read based on
	   //       this snapshot.
	   //
	headSnapshot = ringBuffer-&amp;gt;Head;
	tailSnapshot = ringBuffer-&amp;gt;Tail;

	//
	// In order to distinguish between a full buffer and an empty buffer,
	// we always leave the last byte of the buffer unused. So, an empty
	// buffer is denoted by -
	//      tail == head
	// ... and a full buffer is denoted by -
	//      (tail+1) == head
	//
	tailPlusOne = ((tailSnapshot + 1) == ringBuffer-&amp;gt;End) ? ringBuffer-&amp;gt;Base : (tailSnapshot + 1);

	if (tailPlusOne == headSnapshot)
	{
		//
		// Buffer full
		//
		*AvailableSpace = 0;
	}
	else if (tailSnapshot == headSnapshot)
	{
		//
		// Buffer empty
		// The -1 in the computation below is to account for the fact that
		// we always leave the last byte of the ring buffer unused in order
		// to distinguish between an empty buffer and a full buffer.
		//
		*AvailableSpace = ringBuffer-&amp;gt;Size - 1;
	}
	else
	{
		if (tailSnapshot &amp;gt; headSnapshot)
		{
			//
			// Data has not wrapped around the end of the buffer
			// The -1 in the computation below is to account for the fact
			// that we always leave the last byte of the ring buffer unused
			// in order to distinguish between an empty buffer and a full
			// buffer.
			//
			*AvailableSpace = ringBuffer-&amp;gt;Size - (tailSnapshot - headSnapshot) - 1;
		}
		else
		{
			//
			// Data has wrapped around the end of the buffer
			// The -1 in the computation below is to account for the fact
			// that we always leave the last byte of the ring buffer unused
			// in order to distinguish between an empty buffer and a full
			// buffer.
			//
			*AvailableSpace = (headSnapshot - tailSnapshot) - 1;
		}
	}
}


VOID
CUsbPCECGHelper::RingBufferGetAvailableData(
	PRING_BUFFER      ringBuffer,
	SIZE_T* AvailableData
)
{
	SIZE_T   availableSpace;
//	KIRQL    oldIrql;

	if (!AvailableData)   return;
	//ASSERT(AvailableData);

//	KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
	RingBufferGetAvailableSpace(ringBuffer, &amp;amp;availableSpace);
//	KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);

	//
	// The -1 in the arithmetic below accounts for the fact that we always
	// keep 1 byte of the ring buffer unused in order to distinguish
	// between a full buffer and an empty buffer.
	//
	*AvailableData = ringBuffer-&amp;gt;Size - availableSpace - 1;
}








SIZE_T
CUsbPCECGHelper::ReadRingBuffer(
	PRING_BUFFER   ringBuffer,
	PUCHAR         readBuffer,
	SIZE_T        numberOfBytesToRead
)
/*
   Routine Description:
   This routine reads data from a ring buffer.

   Arguments:
   ringBuffer - pointer to a ring buffer structure
   readBuffer - pointer to a user supplied buffer to transfer data into
   numberOfBytesToRead - number of bytes to read from the ring buffer

   Return Value:
   ULONG - number of bytes read.  May be smaller than requested number of bytes.
*/
{

	SIZE_T   byteCount;
//	KIRQL    oldIrql;
	SIZE_T   l_currentsize;

//	KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
	l_currentsize = ringBuffer-&amp;gt;currentSize;
//	KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);

//	MarlinUSB_DbgPrint(1, ("Marlin.sys: ReadRingBuffer() enter\n"));

	if (numberOfBytesToRead &amp;gt; ringBuffer-&amp;gt;totalSize)
		return 0;

	if (l_currentsize == 0)
		return 0;

	if (numberOfBytesToRead &amp;gt; l_currentsize)
		byteCount = l_currentsize;
	else
		byteCount = numberOfBytesToRead;

	//
	// two cases.  Read either wraps or it doesn't.
	// Handle the non-wrapped case first
	//
	if ((ringBuffer-&amp;gt;outPtr + byteCount - 1) &amp;lt; (ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize))
	{
//		MarlinUSB_DbgPrint(1, ("Marlin.sys: ReadRingBuffer() about to copy a\n"));
		RtlCopyMemory(readBuffer, ringBuffer-&amp;gt;outPtr, byteCount);
		ringBuffer-&amp;gt;outPtr += byteCount;
		if (ringBuffer-&amp;gt;outPtr == ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize)
			ringBuffer-&amp;gt;outPtr = ringBuffer-&amp;gt;buffer;
	}
	// now handle the wrapped case
	else
	{
		//ULONG    fragSize;
		 //Boris, 18.04.2021 (Get error: conversion from '__int64' to 'ULONG', possible loss of data)
		SIZE_T    fragSize;

//		MarlinUSB_DbgPrint(1, ("Marlin.sys: ReadRingBuffer() about to copy b\n"));

		// get the first half of the read
		//Boris, 16.02.2009 ,WDK 6001.18002 build
		//fragSize = ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize - ringBuffer-&amp;gt;outPtr;
		//fragSize = ringBuffer-&amp;gt;totalSize + (ULONG)(ringBuffer-&amp;gt;buffer - ringBuffer-&amp;gt;outPtr);
		//Boris, 18.04.2021 
		fragSize = (ringBuffer-&amp;gt;totalSize + ringBuffer-&amp;gt;buffer) - ringBuffer-&amp;gt;outPtr;

		RtlCopyMemory(readBuffer, ringBuffer-&amp;gt;outPtr, fragSize);

		// now get the rest
		RtlCopyMemory(readBuffer + fragSize, ringBuffer-&amp;gt;buffer, byteCount - fragSize);

		ringBuffer-&amp;gt;outPtr = ringBuffer-&amp;gt;buffer + byteCount - fragSize;
	}

	//
	// update the current size of the ring buffer.  Use spinlock to insure
	// atomic operation.
	//
//	KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
	ringBuffer-&amp;gt;currentSize -= byteCount;
//	KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);

//	MarlinUSB_DbgPrint(1, ("Marlin.sys: ReadRingBuffer() exit\n"));

	return byteCount;


	/*
		SIZE_T                  availableData=0;
		SIZE_T                  dataFromCurrToEnd;
		SIZE_T                  DataSize=0;
		SIZE_T                  BytesCopied = 0;

		if(!readBuffer)                                             return 0;
		if (numberOfBytesToRead == 0)                               return 0;
		if (ringBuffer-&amp;gt;Head &amp;gt;= ringBuffer-&amp;gt;End)                    return 0;

		//
		// Get the amount of data available in the buffer
		//
		RingBufferGetAvailableData(ringBuffer, &amp;amp;availableData);

		if (availableData == 0)                                    return 0;

		DataSize = numberOfBytesToRead;

		if (DataSize &amp;gt; availableData)
		{
			DataSize = availableData;
		}

		BytesCopied = DataSize;

		if ((ringBuffer-&amp;gt;Head + DataSize) &amp;gt; ringBuffer-&amp;gt;End)
		{
			//
			// The data requested by the caller is wrapped around the end of the
			// buffer. So we'll do the copy in two steps -
			//    * Copy X bytes from the current position to the end buffer into
			//      the caller's buffer
			//    * Copy (DataSize - X) bytes from the beginning to the buffer into
			//      the caller's buffer
			//

			//
			// The first step of the copy ...
			//
			dataFromCurrToEnd = ringBuffer-&amp;gt;End - ringBuffer-&amp;gt;Head;
			RtlCopyMemory(readBuffer, ringBuffer-&amp;gt;Head, dataFromCurrToEnd);
			readBuffer += dataFromCurrToEnd;
			DataSize   -= dataFromCurrToEnd;

			//
			// The second step of the copy ...
			//
			RtlCopyMemory(readBuffer, ringBuffer-&amp;gt;Base, DataSize);

			//
			// Advance the head pointer
			//
			ringBuffer-&amp;gt;Head = ringBuffer-&amp;gt;Base + DataSize;
		}
		else
		{
			//
			// The data in the buffer is NOT wrapped around the end of the buffer.
			// Simply copy the data over to the caller's buffer in a single step.
			//
			RtlCopyMemory(readBuffer, ringBuffer-&amp;gt;Head, DataSize);

			//
			// Advance the head pointer
			//
			ringBuffer-&amp;gt;Head += DataSize;
			if (ringBuffer-&amp;gt;Head == ringBuffer-&amp;gt;End)
			{
				//
				// We have exactly reached the end of the buffer. The next
				// read should wrap around and start from the beginning.
				//
				ringBuffer-&amp;gt;Head = ringBuffer-&amp;gt;Base;
			}
		}

		if (!(ringBuffer-&amp;gt;Head &amp;lt; ringBuffer-&amp;gt;End))                  return 0;

		return BytesCopied;

	*/
}

SIZE_T
CUsbPCECGHelper::WriteRingBuffer(
	PRING_BUFFER   ringBuffer,
	PUCHAR         writeBuffer,
	SIZE_T         numberOfBytesToWrite
)
/*
   Routine Description:
   This routine writes data to a ring buffer.  If the requested write size exceeds
   available space in the ring buffer, then the write is rejected.

   Arguments:
   ringBuffer - pointer to a ring buffer structure
   readBuffer - pointer to a user supplied buffer of data to copy to the ring buffer
   numberOfBytesToRead - number of bytes to write to the ring buffer

   Return Value:
   ULONG - number of bytes written.
*/
{
	SIZE_T   byteCount;
//	KIRQL    oldIrql;
	SIZE_T   l_currentsize;

//	KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
	l_currentsize = ringBuffer-&amp;gt;currentSize;
//	KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);


	if (numberOfBytesToWrite &amp;gt; (ringBuffer-&amp;gt;totalSize - l_currentsize))
	{
		//MarlinUSB_DbgPrint(1, ("Marlin.sys: WriteRingBuffer() OVERFLOW\n"));
		return 0;
	}

	byteCount = numberOfBytesToWrite;

	//
	// two cases.  Write either wraps or it doesn't.
	// Handle the non-wrapped case first
	//
	if ((ringBuffer-&amp;gt;inPtr + byteCount - 1) &amp;lt; (ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize))
	{
		RtlCopyMemory(ringBuffer-&amp;gt;inPtr, writeBuffer, byteCount);
		ringBuffer-&amp;gt;inPtr += byteCount;
		if (ringBuffer-&amp;gt;inPtr == ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize)
			ringBuffer-&amp;gt;inPtr = ringBuffer-&amp;gt;buffer;
	}
	// now handle the wrapped case
	else
	{
		//ULONG    fragSize;
		//Boris, 18.04.2021 (Get error: conversion from '__int64' to 'ULONG', possible loss of data)
		SIZE_T    fragSize;

		// write the first fragment
		//Boris, 16.02.2009 ,WDK 6001.18002 build
		//fragSize = ringBuffer-&amp;gt;buffer + ringBuffer-&amp;gt;totalSize - ringBuffer-&amp;gt;inPtr;
		//fragSize = ringBuffer-&amp;gt;totalSize + (ULONG)(ringBuffer-&amp;gt;buffer - ringBuffer-&amp;gt;inPtr);

		//Boris, 18.04.2021 (Get error: conversion from '__int64' to 'ULONG', possible loss of data)
		fragSize = (ringBuffer-&amp;gt;totalSize + ringBuffer-&amp;gt;buffer) - ringBuffer-&amp;gt;inPtr;

		RtlCopyMemory(ringBuffer-&amp;gt;inPtr, writeBuffer, fragSize);

		// now write the rest
		RtlCopyMemory(ringBuffer-&amp;gt;buffer, writeBuffer + fragSize, byteCount - fragSize);

		ringBuffer-&amp;gt;inPtr = ringBuffer-&amp;gt;buffer + byteCount - fragSize;

	}

	//
	// update the current size of the ring buffer.  Use spinlock to insure
	// atomic operation.
	//
//	KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
	ringBuffer-&amp;gt;currentSize += byteCount;
//	KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);

	//MarlinUSB_DbgPrint(1, ("Marlin.sys: WriteRingBuffer() %d bytes\n", byteCount));

	return byteCount;



	/*
		SIZE_T   availableSpace = 0;
		SIZE_T   spaceFromCurrToEnd;
		SIZE_T   bytesToCopy;
		SIZE_T   bytesCopied=0;
		KIRQL    oldIrql;

		if (!writeBuffer)                                           return 0;
		if (numberOfBytesToWrite == 0)                              return 0;
		if (ringBuffer-&amp;gt;Tail &amp;gt;= ringBuffer-&amp;gt;End)                    return 0;

		//
		// Get the amount of space available in the buffer
		//
		KeAcquireSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, &amp;amp;oldIrql);
		RingBufferGetAvailableSpace(ringBuffer, &amp;amp;availableSpace);
		KeReleaseSpinLock(&amp;amp;ringBuffer-&amp;gt;spinLock, oldIrql);

		//
		// If there is not enough space to fit in all the data passed in by the
		// caller then copy as much as possible and throw away the rest
		//
		if (availableSpace &amp;lt; numberOfBytesToWrite)
		{
			bytesToCopy = availableSpace;
		}
		else
		{
			bytesToCopy = numberOfBytesToWrite;
		}

		bytesCopied = bytesToCopy;

		if (bytesToCopy)
		{
			//
			// The buffer has some space at least
			//
			if ((ringBuffer-&amp;gt;Tail + bytesToCopy) &amp;gt; ringBuffer-&amp;gt;End)
			{
				//
				// The data being written will wrap around the end of the buffer.
				// So the copy has to be done in two steps -
				// * X bytes from current position to end of the buffer
				// * the remaining (bytesToCopy - X) from the start of the buffer
				//

				//
				// The first step of the copy ...
				//
				spaceFromCurrToEnd = ringBuffer-&amp;gt;End - ringBuffer-&amp;gt;Tail;

				RtlCopyMemory(ringBuffer-&amp;gt;Tail, writeBuffer, spaceFromCurrToEnd);

				writeBuffer += spaceFromCurrToEnd;

				bytesToCopy -= spaceFromCurrToEnd;

				//
				// The second step of the copy ...
				//
				RtlCopyMemory(ringBuffer-&amp;gt;Base, writeBuffer, bytesToCopy);

				//
				// Advance the tail pointer
				//
				ringBuffer-&amp;gt;Tail = ringBuffer-&amp;gt;Base + bytesToCopy;
			}
			else
			{
				//
				// Data does NOT wrap around the end of the buffer. Just copy it
				// over in a single step
				//
				RtlCopyMemory(ringBuffer-&amp;gt;Tail, writeBuffer, bytesToCopy);

				//
				// Advance the tail pointer
				//
				ringBuffer-&amp;gt;Tail += bytesToCopy;
				if (ringBuffer-&amp;gt;Tail == ringBuffer-&amp;gt;End)
				{
					//
					// We have exactly reached the end of the buffer. The next
					// write should wrap around and start from the beginning.
					//
					ringBuffer-&amp;gt;Tail = ringBuffer-&amp;gt;Base;
				}
			}

		   if (!(ringBuffer-&amp;gt;Tail &amp;lt; ringBuffer-&amp;gt;End))                  return 0;

		}

		return bytesCopied;

		*/
}














//==========================================================================================================================================================
&lt;/LI-CODE&gt;&lt;P&gt;#define ISOCH_DATA_SIZE_MS 10&lt;BR /&gt;#define ISOCH_TRANSFER_COUNT 2&amp;nbsp; &amp;nbsp; //will need to be at least 2&lt;/P&gt;&lt;P&gt;/*&lt;BR /&gt;* My device sends one sample of 2 bytes every 1ms .. =&amp;gt; data sample rate = 1000s/s&lt;BR /&gt;*&lt;BR /&gt;* Problem !!&lt;BR /&gt;* Only Transfer 1 has the data all next (ISOCH_TRANSFER_COUNT) are empty&lt;BR /&gt;* As a result i see data arriving at sample rate of 1000 / ISOCH_TRANSFER_COUNT in Read application&lt;BR /&gt;*&lt;BR /&gt;* Why ?????&lt;BR /&gt;*&lt;BR /&gt;nvUSB.lib: Current Frame number=261744397&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.&lt;BR /&gt;nvUSB.lib: Current Frame number=261744447&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes. &amp;lt;-- ??&lt;BR /&gt;nvUSB.lib: Current Frame number=261744497&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.&lt;BR /&gt;nvUSB.lib: Current Frame number=261744547&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes. &amp;lt;--- ??&lt;BR /&gt;nvUSB.lib: Current Frame number=261744597&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 1 completed. Read 100 bytes.&lt;BR /&gt;nvUSB.lib: Current Frame number=261744647&lt;BR /&gt;nvUSB.lib: bRead() Requested 1200 bytes in 50 packets per transfer.&lt;BR /&gt;nvUSB.lib: bRead() Transfer 2 completed. Read 0 bytes.&lt;BR /&gt;nvUSB.lib: Current Frame number=261744697&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 25 Nov 2021 07:42:27 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/winusb-driver-isochronous-endpoint-not-working/m-p/3004392#M6</guid>
      <dc:creator>BorisW560</dc:creator>
      <dc:date>2021-11-25T07:42:27Z</dc:date>
    </item>
    <item>
      <title>USB Companion Controller Problem</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-companion-controller-problem/m-p/2153638#M5</link>
      <description>&lt;P&gt;I'm hoping I can find some help here.&amp;nbsp; I have multiple USB 3.0 controllers, both on my motherboard and on two PCI-E 1.0 boards, and all of them recognize USB 3.0 devices as USB 2.0.&amp;nbsp; I am including two USB Viewer snapshots that show the device (Samsung Odyssey Plus WMR headset) plugged into two different USB sources.&amp;nbsp; The tree viewer does show the companion USB 3.0 ports, but neither the motherboard nor the PCI-E boards will connect my device to the USB 3.0 controllers.&amp;nbsp; I don't think its a hardware issue because this issue is happening on two different types of hardware.&amp;nbsp; This has effectively made the USB 3.0 audio headphones on the WMR headset unusable.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I have updated my BIOS and all of my drivers, and cannot find the problem.&amp;nbsp; I've also found posts like this (&lt;A href="https://techcommunity.microsoft.com/t5/microsoft-usb-blog/reasons-to-avoid-companion-controllers/ba-p/270710" target="_blank"&gt;Reasons to avoid companion controllers - Microsoft Tech Community&lt;/A&gt;) that urge hardware developers not to use companion controllers.&amp;nbsp; Any suggested solutions would be very much appreciated.&amp;nbsp; Thank you!&lt;/P&gt;</description>
      <pubDate>Sun, 21 Feb 2021 17:15:17 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/usb-companion-controller-problem/m-p/2153638#M5</guid>
      <dc:creator>Paul_Gregg</dc:creator>
      <dc:date>2021-02-21T17:15:17Z</dc:date>
    </item>
    <item>
      <title>Capturing HID data in ETW traces</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/capturing-hid-data-in-etw-traces/m-p/2125306#M4</link>
      <description>&lt;P&gt;Can someone give some current hints on how to capture HID data for a USB device?&lt;/P&gt;&lt;P&gt;I started this quest using Logman to create an ETW session using the Microsoft-Windows-USB-USBPORT and Microsoft-Windows-USB-USBHUB providers from Windows 10, but although I get a ETL file with USB information in it I'm not seeing the actual data going to/from the device.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I then found a blog recommending to use the GUIDs for HidClass and HidUSB, but I get the same result then as well.&amp;nbsp; This article (&lt;A href="https://techcommunity.microsoft.com/t5/microsoft-usb-blog/how-to-capture-and-read-hid-traces-in-windows-8-1/ba-p/270839)" target="_blank"&gt;https://techcommunity.microsoft.com/t5/microsoft-usb-blog/how-to-capture-and-read-hid-traces-in-windows-8-1/ba-p/270839)&lt;/A&gt; doesn't go into much depth on viewing the ETL file, and I see that both Network Monitor and Message Analyser have been EOLd. Is TraceView really the only way we're meant to view the files now? And where does one go in 2021 to get the most recent copy?&lt;/P&gt;</description>
      <pubDate>Fri, 12 Feb 2021 01:39:59 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/capturing-hid-data-in-etw-traces/m-p/2125306#M4</guid>
      <dc:creator>PaulAttryde</dc:creator>
      <dc:date>2021-02-12T01:39:59Z</dc:date>
    </item>
    <item>
      <title>No admin rights for external hard drives and USB</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/no-admin-rights-for-external-hard-drives-and-usb/m-p/1635353#M3</link>
      <description>&lt;PRE&gt;&lt;SPAN&gt;I have a USB drive on the laptop. Strangely, I have no access to external drives. Keyboard and connection with the mobile phone via drive is possible. I have the latest Windows update. I suspected the problem was with the security settings or registers. Unfortunately, I have no idea what I can do to solve the problem. Windows support couldn't help either.&lt;/SPAN&gt;&lt;/PRE&gt;</description>
      <pubDate>Fri, 04 Sep 2020 11:48:16 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/no-admin-rights-for-external-hard-drives-and-usb/m-p/1635353#M3</guid>
      <dc:creator>ChleeN</dc:creator>
      <dc:date>2020-09-04T11:48:16Z</dc:date>
    </item>
    <item>
      <title>slow USB 2.0 bulk transfer on Windows 10</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/slow-usb-2-0-bulk-transfer-on-windows-10/m-p/1223102#M2</link>
      <description>&lt;P&gt;We are moving our USB 2.0 device from a custom driver to WinUSB. The device must continue to work with both the older driver and the new WinUSB approach so changing to isochronous for example would not be possible.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In our testing we are seeing significantly slower bulk transfer speeds on Windows 10 vs Windows 7 - Windows 10 takes approximately 60% longer to transfer.&amp;nbsp; This same slowdown occurs whether we use the older custom driver or WinUSB.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Our data is not large = ~10 Mb/s (1 Mb every 10 Hz revolution, i.e. 100 ms)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In our base tests, we transfer two blocks of 470K, one block of 54k, and a final block of 107k.&lt;/P&gt;&lt;P&gt;On Windows 7, each 470k blocks take just over 18 ms to transfer - overall ~43 ms for 1.1 Mb transfer&lt;/P&gt;&lt;P&gt;On Windows 10, each 470k blocks take just over 29 ms to transfer == 61% longer - overall ~70 ms&amp;nbsp;for 1.1 Mb transfer&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;These times were verified using tracing on the device running under JTAG control as well as a USB 3 analyzer.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there any knowledge, any information, any suggestions for the cause and possible solution for this significant difference in bulk transfer speeds?&amp;nbsp; TIA!&lt;/P&gt;</description>
      <pubDate>Wed, 11 Mar 2020 19:05:44 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/slow-usb-2-0-bulk-transfer-on-windows-10/m-p/1223102#M2</guid>
      <dc:creator>megabite</dc:creator>
      <dc:date>2020-03-11T19:05:44Z</dc:date>
    </item>
    <item>
      <title>slow USB bulk transfers on Windows 10</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb/slow-usb-bulk-transfers-on-windows-10/m-p/1222723#M1</link>
      <description>&lt;P&gt;We are moving our USB 2.0 device from a custom driver to WinUSB. The device must continue to work with both the older driver and the new WinUSB approach so changing to isochronous for example would not be possible.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In our testing we are seeing significantly slower bulk transfer speeds on Windows 10 vs Windows 7 - Windows 10 takes approximately 60% longer to transfer.&amp;nbsp; This same slowdown occurs whether we use the older custom driver or WinUSB. That seems to point to something in the OS implementation or interpretation.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Our data is not large = ~10 Mb/s (1 Mb every 10 Hz revolution, i.e. 100 ms)&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;In our base tests, we transfer two blocks of 470K, one block of 54k, and a final block of 107k.&lt;/P&gt;&lt;P&gt;On Windows 7, each 470k blocks take just over 18 ms to transfer - overall transfer of 1.1 Mb takes about 43 ms&lt;/P&gt;&lt;P&gt;On Windows 10, each 470k blocks take just over 29 ms to transfer == 61% longer - overall transfer of 1.1 Mb takes about 70 ms&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Is there any knowledge, any information, any suggestions for the cause and possible solution for this significant difference in bulk transfer speeds?&amp;nbsp; TIA!&lt;/P&gt;</description>
      <pubDate>Wed, 11 Mar 2020 18:53:22 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb/slow-usb-bulk-transfers-on-windows-10/m-p/1222723#M1</guid>
      <dc:creator>megabite</dc:creator>
      <dc:date>2020-03-11T18:53:22Z</dc:date>
    </item>
    <item>
      <title>Introducing the USB4™ Switch</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/introducing-the-usb4-switch/ba-p/859656</link>
      <description>&lt;P&gt;As part of the MUTT (Microsoft USB Test Tool) family and a follow-on to the USB Type-C Connection Exerciser, we are excited to introduce the USB4 Switch: a USB Type-C 1:2 programmable switch, compatible with USB4 as well as older protocols such as Thunderbolt™ 3, USB 3.2, USB Type-C Alternate Modes, and of course Power Delivery.&lt;/P&gt;
&lt;P&gt;&lt;img /&gt;&lt;/P&gt;
&lt;P&gt;The USB4 Switch automates connect-disconnect of a USB Type-C port and will be used in stress testing, switching between peripherals (for example, a dock and a display), or any automated reconfiguration of a USB Type-C port.&amp;nbsp; It is compatible with the &lt;A href="https://github.com/microsoft/busiotools/tree/master/usb/tools/ConnectionExerciser" target="_self"&gt;Connection Exerciser&lt;/A&gt; &lt;A href="https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-usb-test-tool--mutt--devices#usb-type-c-connex" target="_self"&gt;tools and scripts&lt;/A&gt; and integrates with the Hardware Lab Kit (HLK) test content.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It will be a required test device for Windows Certification through the HLK but is highly recommended for use much earlier in your hardware development cycle as well.&amp;nbsp; In our experience, long-run randomized switching on a USB Type-C port is highly effective in exposing bugs in the hardware-firmware-software stack, both in the USB Type-C controller as well as the underlying data protocols.&amp;nbsp; We expect the USB4 Switch to have similar value in the development and validation of USB4 hardware and software.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The device is available to purchase from our partners at MCCI at&amp;nbsp;&lt;A href="https://mcci.com/usb/dev-tools/model-3141/" target="_self"&gt;https://mcci.com/usb/dev-tools/model-3141/&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;For UCSI based systems we recommended to perform testing with some additional settings to help discover firmware bugs. Please see “Converting firmware failures to bugchecks” in &lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2FMicrosoft-USB-Blog%2FDebugging-UCSI-firmware-failures%2Fba-p%2F283226&amp;amp;data=02%7C01%7CPhilip.Froese%40microsoft.com%7C55231dc0e2f6491e53fb08d73b8c4a32%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637043346032414544&amp;amp;sdata=kltqX%2FXflEVkMJKT6XzzW9e%2BzoszxbV2o%2Fgi5%2B0zc2c%3D&amp;amp;reserved=0" target="_blank" rel="noopener"&gt;this blog post&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Fri, 10 Jan 2020 17:44:32 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/introducing-the-usb4-switch/ba-p/859656</guid>
      <dc:creator>Philip Froese</dc:creator>
      <dc:date>2020-01-10T17:44:32Z</dc:date>
    </item>
    <item>
      <title>UCSI based USB Type-C systems may see a shutdown delay if connect changes race with power transition</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/ucsi-based-usb-type-c-systems-may-see-a-shutdown-delay-if/ba-p/718602</link>
      <description>&lt;P&gt;&lt;STRONG&gt;My system takes a long time to power down if a USB Type-C device, dock, or charger is plugged in or unplugged during the power transition.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A bug in the USB Type-C Connector System Software Interface (UCSI) software implementation in Windows 10, version 1809 can cause a 60 second delay in the system sleep or shutdown process if the power-down happens while the UCSI software is busy handling a new connect or disconnect event on a USB Type-C port. Apart from the extra one minute the sleep or shutdown process takes in this circumstance, this bug does not affect normal functionality of USB Type-C on your machine. The system and the USB Type-C ports should continue to function properly after the next wake or restart of the system.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edits based on feedback:&lt;/P&gt;
&lt;P&gt;1) This is resolved in Windows 10 version 1903, please update to the latest released build if you are impacted by this bug.&lt;/P&gt;
&lt;P&gt;2) The issue described only affects Windows 10 version 1809 (17763) and is fixed in 1903.&lt;/P&gt;
&lt;P&gt;3) Please use the &lt;A href="https://support.microsoft.com/en-us/help/4021566/windows-10-send-feedback-to-microsoft-with-feedback-hub" target="_self"&gt;Feedback Hub&lt;/A&gt; for further feedback or questions.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Jun 2019 18:42:50 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-usb-blog/ucsi-based-usb-type-c-systems-may-see-a-shutdown-delay-if/ba-p/718602</guid>
      <dc:creator>Philip Froese</dc:creator>
      <dc:date>2019-06-25T18:42:50Z</dc:date>
    </item>
  </channel>
</rss>

