I would really really appreciate some help with winUSB.
I followed all the steps that were listed in msdn website
http://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540174(v=vs.85).aspx
I tried to run it on Windows 7 with Visual Studio 2010. Even though it compiles with no errors, I cannot pass the function
SetupDiEnumDeviceInfo, and it errors out (I think error #259).
I don't know how to pass this error.
However I am not sure of the few steps in the process:
What does msdn talk about with "A signed catalog file for the package. This file is required to install WinUSB on x64 versions"? What is a signed catalog package? How do I set this?
It also talks about making some directory (For example, c:\UsbDevice) to put the .inf file in there ! But how does my VS project know that I am pointing to c:\UsbDevice, and how does it know what the name of the ".inf' file should be? what should I call the .inf file? And how to point the project to it?
Inside the .inf file there are two GUID numbers. I can get the Class GUID number by going to the Device Manager. But how do I set the Device Interface GUID?
Please help.
Is is possible that the error that I am getting is because I don't have one of the following items set up correctly?
Thanks,
--Rudy
I developed an application about 2 years ago that I needed to use WinUSB, it's not fresh in my mind but looking at my code now I can see that I did use this function: SetupDiEnumDeviceInfo, but as I remember it wasn't a problem for me.
As you probably know, the WinUSB is an API of Windows for you to communicate with an usb hardware. The hardware must have it's driver already, so, you have to know the GUID of your device
Answering your steps:
1. Signed catalog is the .cat file generated from an inf, you can genarate it using inf2cat.exe, it's somwhere in your machine. This is just a step for signing your winusb driver. To sign it you will need to submit your .inf and the .cat files for the WHQL (windows hardware quality labs) http://www.microsoft.com/whdc/whql/ , this is not important at this moment, I've never signed my WinUSB driver, and it works in the x64 machines with a inelegant warning saying that my WinUSB driver might be dangerous (despite it's not!)
2. The application you are developing doens't need to know where the .inf file is, the .inf file is meant to install the WinUSB driver, the application will communicate with the driver trough the GUID number of the device after the driver is properly installed. Here is part of the code that is necessary to connect to the device after the WinUSB driver is correctly installed.
LPGUID _lpGuid = (LPGUID) malloc (sizeof(GUID));
HRESULT result = CLSIDFromString (L"{A54E04AD-E06A-4A03-95BB-25AACC4E6CCA}", _lpGuid);
...
bResult = SetupDiEnumDeviceInterfaces(deviceInfo,
NULL,
_lpGuid,
0,
&interfaceData); //If the function succeeds
//the return value is nonzero.
// [1]
deviceInfo = SetupDiGetClassDevs(_lpGuid,
NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (deviceInfo == INVALID_HANDLE_VALUE)
{
//lblDispStatus->Caption = "Erro 1 - deviceInfo";
return false;
}
// [2]
interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
bResult = SetupDiEnumDeviceInterfaces(deviceInfo,
NULL,
_lpGuid,
0,
&interfaceData); //If the function succeeds
//the return value is nonzero.
InterfaceData is passed as reference, so you will have the ability to call the next function, that is SetupDiGetDeviceInterfaceDetail
3.Who developed the driver? He must know the GUIDs you need.
All I know from WinUSB I fount at the poor WinUSB documentation, you will need tons of patiante to read all their messy information. And for your unlucky, it's not fresh in my mind right know, I would have to take a deep look at this subject to help you more.
This page seems important at the point you are, take a look at this: http://msdn.microsoft.com/en-us/library/windows/hardware/ff540174%28v=vs.85%29.aspx
Related
I'm trying to have WDK7 Toaster's bus device and child devices share a same .sys driver file. I combine the busenum.sys and toaster.sys into a single Nls_ufcom.sys(bus.inf and toaster.inf both refer to the same Nls_ufcom.sys as service binary), but Windows reports error 38(CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD) for the child device after I assign toaster.inf as the driver from Device Manager. So, the AddDevice() callback is even not called for the child device.
I'm not sure whether I have done something wrong, or Windows really don't allow this. Wish to get some idea from you, Thank you.
I find out the reason. The reason is: I use different service name in bus.inf and toaster.inf . Apparent conclusion from my case, Windows does not allow two driver services to have [ the same service binary but difference service name ] .
The driver service name is the sub-key under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services .
Assigning the same service name in bus.inf and toaster.inf, then the driver is loaded successfully by both devices.
MSDN CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD's statement is so vague and misleading(since Vista era), which says:
Additionally, this message can appear if a driver is referenced by multiple INF AddService directives in one or more INF files.
-- It does not point out the key problem.
[2017-07-01] Ten months later, I come back to make a confirmation, this sharing sys trick work great from Windows XP SP2 to latest Windows 10.1703, no problem identified until now. I apply this trick in my UFCOM virtual COM port driver so successfully.
In my application, I am using the following Win32 API to before loading the mapi32.dll.
win32 API: ::GetProfileInt(_T("MAIL"), _T("MAPI"), 0);
This API is consistently failing on Windows 8.1 Italian 64-Bit PC.
But, this API is succeeding on all other PCs like Windows 8.1 English(US) 64-Bit PC, Windows 8.1 Japanese 64-Bit PC.
Kindly provide your kind help for fixing the above issue.
To find MAPI32.dll look in either of these paths:
C:\Windows\SysWOW64\mapi32.dll
C:\Windows\System32\mapi32.dll
or use this
GetWindowsDirectory(buf, 260);
lstrcat(buf, TEXT("\\SysWOW64\\mapi32.dll"));
...
To access old win.ini settings, look in this registry key:
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\IniFileMapping\win.ini
But there is probably nothing there about MAPI, it's about 20 years out of date.
The code you originally got this from was probably very old and is no longer supported. If you read the documentation for GetProfileInt, you'll see that its purpose is to support 16-bit applications.
I recommend removing the call. I have also observed it failing on Windows 7 machines while succeeding on Windows 10 machines. I think the more appropriate calls are to use SearchPath(nullptr, L"MAPI32.DLL", nullptr, 0, nullptr, nullptr) to see if MAPI32.DLL would even be found. An alternative is to just attempt the LoadLibrary(L"MAPI32.DLL") and check the returned handle.
An even better solution might be to change your code to call MAPISendMailHelper as it will do the LoadLibrary, GetProcAddress, etc. for you.
I'm working on a device which communicates with a PC through a (virtual) serial port. The problem is that the data we are sending occasionally gets incorrectly identified by Windows as a bus mouse, after which the "Microsoft Serial Ballpoint" driver is loaded and the mouse pointer starts jumping around on the screen and randomly clicking on things.
A bit of Googling reveals that is an old and well-known problem with serial devices where the usual work-around is a bit of registry hacking to disable the offending driver. That it is a lot to demand from our users however and I'd rather not have our application messing around with the user's registry. Especially not when the fix is dependent on the Windows version and the user may well be using a bus mouse.
Instead I'd like to avoid the problem by changing our protocol to not send any data which may get us misidentified as a mouse. The only problem is that I'm not quite certain what patterns to avoid.
Apparently Microsoft's Mouse protocol consists of packets of four bytes where the MSB of the first is set and that of the last three is clear.
Would sending only 7-bit ASCII suffice? Are there any other devices I need to worry about being detected as?
I just encountered this problem myself on Windows 7 Professional x64, and a solution that worked for me was to go into the registry and edit the following value:
Location: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\sermouse
Key: Start
Value: 3
Change Value to 4 and it will stop this problem occurring.
Here is a list of all valid Start values:
0 Boot (loaded by kernel loader). Components of the driver stack for the boot (startup) volume must be loaded by the kernel loader.
1 System (loaded by I/O subsystem). Specifies that the driver is loaded at kernel initialization.
2 Automatic (loaded by Service Control Manager). Specifies that the service is loaded or started automatically.
3 Manual. Specifies that the service does not start until the user starts it manually, such as by using Device Manager.
4 Disabled. Specifies that the service should not be started.
A reg edit command would be as follows:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\sermouse" /V Start /T REG_DWORD /F /D 4
You then need to restart the computer, which should now start correctly and not attempt to discover a serial mouse.
good luck.
It turns out that mouse detection in Windows is normally handled by the serenum.sys filter driver. This driver implements support for legacy serial mice along with serial plug-and-play. Microsoft has even provided the sourcecode as a WDK sample.
During detection the ports switches to 1200-7-N-1 mode while asserting DTR+RTS to which a response is expected within 200 ms, with a couple of retries in case of failure. Unfortunately for a legacy mouse a single M or B character suffices as identification.
In our case the protocol was reworked to avoid these characters and now appears not to be misidentified anymore.
However we were using a virtual USB serial port and for a traditional serial port this approach may be somewhat difficult as anything sent at a different baud rate is liable to look like line noise. In this case I suppose the easiest workaround is probably, as has already been suggested, to avoid making any unsolicited transmissions.
Alternatively with the serial control signals actually hooked up, or intercepted by a USB CDC device, processing the DTR or RTS signals and holding off on output. Actually implementing the plug-and-play protocol would be an even niftier option. Supposedly there are cheap RS232 cables around without a full complement of control signals though so this approach might still fail.
I also encountered this problem, fixed it by disabling "serial enumerator" in the advanced properties of the FTDI driver (properties of COM ports in Device Manager). This is described in http://www.ftdichip.com/Support/Documents/AppNotes/AN_107_AdvancedDriverOptions_AN_000073.pdf.
I have encountered this Windows bug myself. Here is my own research on the topic:
Microsoft acknowledges this bug: http://support.microsoft.com/kb/819036
Start with downloading their tool and see if it solves the issue.
Download & install their program.
Run it from the command prompt from C:\program\Microsoft comdisable\
Write comdisable /list when executing the program.
All ports on the computer will be shown.
Write comdisable /disable COMx where x is the port number.
Do this for all ports on the computer.
Reboot.
This should hopefully work as an universal solution.
Alternatively, you can hack in boot.ini but I don't believe this works in Vista/Win 7. I have some app note from Cisco systems describing how to do this. If the above doesn't solve your problem, please let me know.
In my development environment, I've simply disabled Microsoft Serial Mouse from the Device Manager.
This seems to solve the culprit of my problem. Before doing so, the CH340G chip I've used in my design used to lower the DTR five times before initiating the connection, effectively rebooting my Arduino-based board and render it useless.
Maybe this helps:
We had the same problem with FTDI FT232RL.We found out, that it was a hardware issue of our PCB.
FTDI-Datasheet says about #RESET-Pin: Active low reset pin. This can be used by an external device to reset the FT232R. If not required can be left unconnected, or pulled up to VCC.
RESET-Pin was not required in our application, so we connected it to Vcc via 1k Pull-Up.
It seemed that the pull-up of #RESET-Pin caused an undefined start-up of the FT232RL, at least every second converter, we connected to a USB-socket caused a serial-ball-point in the devive manager. We removed the pull-up-resistor at #RESET-Pin, therewith the #RESET-Pin is unconnected. Since then every interface worked proberly and didn't any longer create serial-ball-points in the Windows device manager.
If you have a "true" serial port, or an USB dongle (RS-232, RS-485, it does not matter) this problem can be worked around by first opening the serial port in question with a terminal, or whatever application you want to monitor it with, and only then plugging the device in. For your own sake, you should also pay attention to remove the device before terminating the connection.
With FTDI chips soldered on the device itself, you are busted. It took a few rounds for me to explain the management that a device communicating on it's own paired with an FTDI chip soldered on the PCB meeting Windows computers won't likely pass for user-friendliness, no matter how slick an USB socket may look like on the cabinet... (Thankfully, all these conditions coming together are quite rare and unusual)
I had this problem since 2010 with serial scale heads connected to the pc. Usb to serial converter or not.. I use onkly SILABS device's CP2102 or the like.. I worked around it by simply allowing the driver to install and then in device manager look for the ballpoint driver under mouse/HIDA and then simply DISABLE the driver, DO NOT UNINSTALL IT simply disable it. Then when you reboot even with the driver instaled it seems windows ignores the comport as serial mouse and uses the data from the input. You will also find that if the ballpoint driver is active then that COMport is in use and sometimes returns a COM PORT not accessible... hope this helps some one out there :) Tx Ben
Code tot stop GPS from being detected as serial mouse.
Below is the code for a subroutine in C#.net. It checks if the registry key is set to 4 and if not it issues the configuration command to disable sermouse.
Embed this subroutine in a program which runs at startup and it will correct the setting after a windows update.
Maybe useful if you get annoyed when this problem happens time and again
private void Stop_sermouse()
{
string k =
"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\sermouse";
object v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
if (v==null)
{
MessageBox.Show("No Registry Key for sermouse");
}
else
{
string sr = v.ToString();
if (sr == "4")
{; }
else
{
DialogResult mbox = MessageBox.Show("disable sermouse ? " + v.ToString(), "Found sermouse enabled! ", MessageBoxButtons.YesNo);
if (mbox == DialogResult.Yes)
{
// prepare a small job to issue confuguration command
ProcessStartInfo s = new ProcessStartInfo("cmd.exe", "/c sc config sermouse start=disabled");
Process p = new Process();
s.Verb = "runas"; // Must run as administrator
s.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.StartInfo = s;
// and run the command
p.Start();
//check if the registry is modified indeed
v = Microsoft.Win32.Registry.GetValue(k, "Start", null);
sr = v.ToString();
if (sr == "4")
{
MessageBox.Show("finished ''sc config sermouse start=disabled'' but not succesfull in registry!");
}
else
{
MessageBox.Show("sermouse is disabled");
}
}
}
}
}
Turns out there is a setting to stop windows trying to enmumerate devices that connect as a COM port.
Make sure that "Serial Enumerator" is unchecked under "Miscellaneous Options"
In this document,
http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#paths
To make these device objects accessible by Windows applications, the device drivers create a symbolic link (symlink) in the Win32 namespace, "Global??", to their respective device objects. For example, COM0 and COM1 under the "Global??" subdirectory are simply symlinks to Serial0 and Serial1, "C:" is a symlink to HarddiskVolume1, "Physicaldrive0" is a symlink to DR0, and so on. Without a symlink, a specified device "Xxx" will not be available to any Windows application using Win32 namespace conventions as described previously. However, a handle could be opened to that device using any APIs that support the NT namespace absolute path of the format "\Device\Xxx".
What are the APIs? Let me know some such functions please.
For example, we can have a device sitting in the GLOBAL?? namespace:
GLOBAL??\
COM227
This device we can successfully open using CreateFile:
//Note: we have to prefix it with \\.\ in order to tell CreateFile that
//we want to open something from the Global device namespace.
//Otherwise it will try to open a file
HANDLE hdev = CreateFile("\\.\COM227", GENERIC_READ, 0, null, OPEN_EXISTING, 0, 0);
if (hdev == INVALID_HANDLE_VALUE)
raise new EWin32Exception(GetLastError);
This device (along with every other device in the Win32 Global?? namespace), actually a symbolic link to the "real" device:
GLOBAL??\
COM227 (SymbolicLink) ==> \Device\VCP0
Device\
VCP0 (Device)
So we try to open this real device:
HANDLE hdev = CreateFile("\\.\Device\VCP0", GENERIC_READ, 0, null, OPEN_EXISTING, 0, 0);
if (hdev == INVALID_HANDLE_VALUE)
raise new EWin32Exception(GetLastError);
But it fails with error code 3 (The system cannot find the specified file).
Short:
Works: COM227 (which is an alias of \Device\VCP0)
Fails: \Device\VCP0
The problem is that
#paulsm4 says that CreateFile should work
#larryostermm agrees, and even gives the device path syntax (e.g. \Device\Xxx)
except that it doesn't work
Which means that CreateFile is not one of the "APIs that support the NT namespace absolute path format of \Device\Xxx".
However, a handle could be opened to that device using any APIs that support the NT namespace absolute path of the format "\Device\Xxx".
What are the APIs?
The answers provided so far are misleading at best. They do not answer your question or cover the important distinction between the NT namespace and the other namespaces.
When accessing the NT namespace you need to use the API calls that start with Nt, such as NtOpenFile, if you want to access devices that are only found in the NT namespace of the kernel. For example, a device in \Devices with no symbolic link in \GLOBAL??.
The other calls mentioned above work fine if you are accessing the Win32 device namespace but these require the driver to create a symbolic link in that namespace.
If you want to access a device that is only found in the NT namespace then use NtOpenFile. This is really a very old API call and has drifted in and out of the userpace header files. It is available again and works just fine.
Benjamin -
The simple fact is that you CAN open a "special device file" in Windows, very much as you do in *nix. This is what I tried to say in my original reply. I stand by everything I said in my first post. And I believe the MSDN link I referred to there does a very good job of explaining this, too.
The syntax for a *nix device file is "/dev/SOME_DEVICE". Multiple devices are (by convention, not necessity) distinguished as "/dev/SOME_DEVICE0", "/dev/SOME_DEVICE1", etc. Device files can also be "aliased" using *nix "symbolic links".
The syntax for a Windows device file is a UNC name.
I'm sure you're familiar with UNC shares (for example, "\\myserver\c$").
In all the examples we've discussed above, the server happens to be the local host. Hence "\\.\SOME_RESOURCE_NAME".
It's really as simple as that.
And it DOES work.
Please let me know if you have any further questions.
Thank you in advance .. PSM
The concept of treating a "device" as a "file" is common in *nix (Unix, Linux, Mac OS, etc).
Basically, the MSDN article means that any Win32 API that opens a "file" (either a local disk file, or a UNC resource) could just as easily open a "special device".
A couple of examples:
http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx
CreateFile
WriteFile
ReadFile
CloseHandle
I want to install a driver for Ext2 partitions under Windows XP, the installation will be done with a self written Inno Setup script. Which API functions do I need to call for this? From what I googled so far I don't seem to be needing an inf file, and therefore no call to SetupCopyOEMInf. But I don't know what to do instead...
Please enlighten me!
As you asked which API functions are required to install a driver here is some code I use to load a driver in C:
bool LoadDriver( const char * cpDriverPath, const char * cpDriverName )
{
SC_HANDLE hSCService;
SC_HANDLE hSCManager;
hSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if( hSCManager == NULL )
return false;
hSCService = CreateService( hSCManager, cpDriverName, cpDriverName,
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
cpDriverPath, NULL, NULL, NULL, NULL, NULL );
if( hSCService == NULL && GetLastError() == ERROR_SERVICE_EXISTS )
hSCService = OpenService( hSCManager, cpDriverName, SERVICE_ALL_ACCESS );
if( hSCService == NULL )
return false;
if( !StartService( hSCService, 0, NULL ) )
{
if( GetLastError() != ERROR_SERVICE_ALREADY_RUNNING )
return false;
}
CloseServiceHandle( hSCManager );
CloseServiceHandle( hSCService );
return true;
}
You probably want to use SERVICE_ BOOT_ START for a file system driver instead of SERVICE_ DEMAND_ START. If you cant write an Inno script to do the above you could always make a small EXE from the above and have Inno run that as a post installation.
If you want to go down the INF route, check out this Microsoft article.
All right, I found some more information:
The MSDN states that 'you should install your file system drivers by using an INF file' (by calling SetupCopyOEMInf etc), but also notes that on Win2k and older systems, 'file system drivers were commonly installed by the Service Control Manager'
And I found another Ext2 driver at sourceforge that comes with an Inno Setup installation script. There they just add a few registry entries under HKLM\SYSTEM\CurrentControlSet\Services\.
I believe that adding these entries is equal to creating a service with the sc.exe tool, which internally calls the OpenSCManager and CreateService api. I prefer the registry way, because it is easier and I see no advantage in using the api calls, since a reboot is always required.
So I ended up with this solution:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\YourService]
"ErrorControl"=dword:00000001
"Start"=dword:00000003
"Type"=dword:00000001
"DisplayName"="YourServiceDisplayName"
"ImagePath"="System32\Drivers\YourService.sys"
Of course depending on the specifics of the driver in question, some more entries in a Parameters subkey may be required.
I am still hoping that someone will be able to shed some more light on this question, specifically some details on how to use an inf file for the installation, since this is the way recommended by MS.
Come on, folks! There's a nice bounty to catch here!
There are a number of ways you could approach this.
1/ See if the product has a silent install mode (e.g., using a configuration file to install). Then you just incorporate that into your own install.
2/ There are programs that can emulate a user, such as Rational Robot (I wouldn't suggest that one since it's commercial, but there's likely to be free ones around). We mostly use these for automated testing of graphical applications but they can just as easily use it to run an installer.
3/ Contact the developer to see what the actual install process entails, then copy that.
4/ Microsoft has a number of system tools (here) that can track changes to the filesystem, registry and so on. You could use these to reverse-engineer the install process and do those same things in your own install.
Personally, I'd go with number 3 first. The developer would be happy to know their product is being used and may provide the information readily. They may even write a silent installer for you as this would be an extra selling point for their product in a corporate environment (suggest this to them).
I wrote a TDI filter driver.
When I came to write the .inf file, it took two weeks of sheer pain to get something working and I still didn't really understand it, because it didn't really make sense; what you had to do seemed very arbitrary. INF files were, when I was trying to use them, almost wholly undocumented and bizzarely complex.