How to identify USB Card Reader - windows

I am trying to detect programmatically existence of USB Card Reader, which identifies itself as keyboard device. In Device Manager it looks like this:
The difference between real keyboard and card reader is only in device IDs. I have the following C# WMI code:
ManagementObjectSearcher managementObjectSearcher = new ManagementObjectSearcher(#"Select * from Win32_Keyboard");
ManagementObjectCollection keyboards = managementObjectSearcher.Get();
foreach (ManagementBaseObject keyboard in keyboards)
{
Console.WriteLine();
foreach (var property in keyboard.Properties)
{
Console.WriteLine(string.Format("{0}: {1}", property.Name, property.Value));
}
}
The output, like in Device Manager, differs only by device IDs:
Availability:
Caption: Enhanced (101- or 102-key)
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_Keyboard
Description: USB Input Device
DeviceID: USB\VID_04B3&PID_3025\5&DC4A972&0&3
ErrorCleared:
ErrorDescription:
InstallDate:
IsLocked:
LastErrorCode:
Layout: 00000409
Name: Enhanced (101- or 102-key)
NumberOfFunctionKeys: 12
Password:
PNPDeviceID: USB\VID_04B3&PID_3025\5&DC4A972&0&3
PowerManagementCapabilities:
PowerManagementSupported: False
Status: OK
StatusInfo:
SystemCreationClassName: Win32_ComputerSystem
SystemName: ALEX19
Availability:
Caption: Enhanced (101- or 102-key)
ConfigManagerErrorCode: 0
ConfigManagerUserConfig: False
CreationClassName: Win32_Keyboard
Description: USB Input Device
DeviceID: USB\VID_0804&PID_0040\5&DC4A972&0&6
ErrorCleared:
ErrorDescription:
InstallDate:
IsLocked:
LastErrorCode:
Layout: 00000409
Name: Enhanced (101- or 102-key)
NumberOfFunctionKeys: 12
Password:
PNPDeviceID: USB\VID_0804&PID_0040\5&DC4A972&0&6
PowerManagementCapabilities:
PowerManagementSupported: False
Status: OK
StatusInfo:
SystemCreationClassName: Win32_ComputerSystem
SystemName: ALEX19
However, Windows Settings shows this device as USB Card Reader:
How can I do the same, using .NET or native Windows API? OS is Windows 10 x64.
Note: this answer How do I get all the smart card readers on my system via WMI? suggests to use SmartCardReader class, but it doesn't work for me, card reader is not recognized.

Related

IAsyncOperation<SerialDevice> FromIdAsync(string deviceId) returns null

I have Windows IoT Core 10 17744 running over Raspberry Pi 3.
I try to initialize COM port from UWP application using following code:
string aqs = SerialDevice.GetDeviceSelector();
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(aqs);
List<DeviceInformation> list = devices.ToList();
DeviceInformation di = list.First();
_serial_port = await SerialDevice.FromIdAsync(di.Id);
I have di.Id -> \\?\ACPI#BCM2836#0#{86e0d1e0-8089-11d0-9ce4-08003e301f73}
Full represintation of di variable as follow:
- di {Windows.Devices.Enumeration.DeviceInformation} Windows.Devices.Enumeration.DeviceInformation
EnclosureLocation null Windows.Devices.Enumeration.EnclosureLocation
Id "\\\\?\\ACPI#BCM2836#0#{86e0d1e0-8089-11d0-9ce4-08003e301f73}" string
IsDefault false bool
IsEnabled true bool
Kind DeviceInterface Windows.Devices.Enumeration.DeviceInformationKind
Name "MINWINPC" string
- Pairing {Windows.Devices.Enumeration.DeviceInformationPairing} Windows.Devices.Enumeration.DeviceInformationPairing
CanPair false bool
+ Custom {Windows.Devices.Enumeration.DeviceInformationCustomPairing} Windows.Devices.Enumeration.DeviceInformationCustomPairing
IsPaired false bool
ProtectionLevel None Windows.Devices.Enumeration.DevicePairingProtectionLevel
Native View To inspect the native object, enable native code debugging.
+ Properties {System.__ComObject} System.Collections.Generic.IReadOnlyDictionary<string, object> {System.__ComObject}
Native View To inspect the native object, enable native code debugging.
But after await operation I have null in _serial_port.
UPDATE
It is null even if I connect Raspberry UART interface to working node:
8th pin as TX to paired RX line.
10th pin as RX to paired TX line.
UPDATE
I have DeviceCapability in manifest:
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort" />
</Device>
</DeviceCapability>
You need add serial device capability in the Package.appxmanifest:
<DeviceCapability Name="serialcommunication">
<Device Id="any">
<Function Type="name:serialPort" />
</Device>
</DeviceCapability>
It is null even if I connect Raspberry UART interface to working node:
8th pin as TX to paired RX line. 10th pin as RX to paired TX line.
This is not required for SerialDevice.FromIdAsync() success. Even if you don't connect these pins the SerialDevice.FromIdAsync() can get the valid device if the code and setting correctly. You can refer to Serial UART Sample.

touchscreen ft5x06 not responding?

I am using kontron smarc-samx6i board run with nxp imx6q processor. I am currently working with yocto In that I need to interface a touch screen of ft5316 through I2C . For that I edited the device tree as follows:
polytouch: edt_ft5x06#39 {
compatible = "edt","edt_ft5x06","edt-ft5x06";
reg = <0x39>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_smx6_i2c_gpio_1>;
irq_pin=<&gpio3 1 0>;
interrupt-parent = <&gpio3>;
interrupts = <0 70 0x04>;
};
When I am using i2cdump command the touchscreen responds successfully, but when I am working with module it won't respond.
When I am using the below command i am getting following output
root#smarc-samx6i:~# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="gpio-keys.27"
P: Phys=gpio-keys/input0
S: Sysfs=/devices/soc0/gpio-keys.27/input/input0
U: Uniq=
H: Handlers=kbd event0 evbug
B: PROP=0
B: EV=23
B: KEY=4000 100000 0 0 0
B: SW=1
My device did not probe and i am not getting any error while instantiating the device using the command:
echo edt_ft5x06 0x39> /sys/bus/i2c/devices/i2c-1/new_device
Instantiated device edt_ft5x06 at 0x39 device
How can i make it work!!
I assume that by "when working with the module it won't respond" you mean it won't respond to any touch events on the touchscreen. Did the driver module correctly load? Is it built-in or used as a loadable module? Did you check "dmesg" for confirming the driver loaded properly or output of lsmod? If the driver loaded properly, are you getting interrupts?
What is the output of "cat /proc/interrupts"? Do you see the interrupt requests increasing when you press the touchscreen? If not then, then you have a problem with interrupts. If you see the interrupts, can you check with an utility like "evtest" to see if you get touchscreen events?

Map USB disk BSD Name to actual mounted drive(s) in OSX

I am trying to get from the USB device BSD Name to the actual mounted volume(s) for that device e.g. device has BSD name "disk2" and mounts a single volume with BSD name "disk2s1" at "/Volumes/USBSTICK".
Here is what I have been doing so far. Using
NSNotificationCenter NSWorkspaceDidMountNotification
I detect when a drive has been added. I then scan through all the USB devices and use
IORegistryEntrySearchCFProperty kIOBSDNameKey
to get the BSD name of the device.
For my USB stick this returns "disk2". Running
system_profiler SPUSBDataTypesystem_profiler SPUSBDataType
shows
Product ID: 0x5607
Vendor ID: 0x03f0 (Hewlett Packard)
Serial Number: AA04012700008687
Speed: Up to 480 Mb/sec
Manufacturer: HP
Location ID: 0x14200000 / 25
Current Available (mA): 500
Current Required (mA): 500
Capacity: 16.04 GB (16,039,018,496 bytes)
Removable Media: Yes
Detachable Drive: Yes
BSD Name: disk2
Partition Map Type: MBR (Master Boot Record)
S.M.A.R.T. status: Not Supported
Volumes:
USBSTICK:
Capacity: 16.04 GB (16,037,879,808 bytes)
Available: 5.22 GB (5,224,095,744 bytes)
Writable: Yes
File System: MS-DOS FAT32
BSD Name: disk2s1
Mount Point: /Volumes/USBSTICK
Content: Windows_FAT_32
which makes sense since there could be multiple volumes for a single USB device.
I assumed I could use DiskArbitration to find the actual volumes, but
DASessionRef session = DASessionCreate(NULL);
if (session)
{
DADiskRef disk = DADiskCreateFromBSDName(NULL,session,"disk2");
if (disk)
{
CFDictionaryRef dict = DADiskCopyDescription(disk);
if (dict)
always returns a NULL dictionary.
So, how do I get from the BSD name for a USB device to the actual mounted volume(s) for that device? I guess it should be possible to get iterate over all the volumes, get their BSD name and check if it starts with the string e.g. /Volumes/USBSTICK above is "disk2s1", but that's hacky and what if there is a disk20 etc.
Found a solution using IOBSDNameMatching will create a dictionary to match the service with a given BSD name. Then the children of that service can be searched for their BSD names.
NOTE: This is my first time doing anything on OSX. Also, the 'dict' in the above code was NULL because of bug, but that dictionary is of no use for this anyway.
Here's some cut down code with no error checking etc.
CFMutableDictionaryRef matchingDict;
matchingDict = IOBSDNameMatching(kIOMasterPortDefault, 0, "disk2");
io_iterator_t itr;
// Might only ever be one service so, MatchingService could be used. No sure though
IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &itr);
io_object_t service;
while ((service = IOIteratorNext(itr)))
{
io_iterator_t children;
io_registry_entry_t child;
// Obtain the service's children.
IORegistryEntryGetChildIterator(service, kIOServicePlane, &children);
while ((child = IOIteratorNext(children)))
{
CFTypeRef name = IORegistryEntrySearchCFProperty(child,
kIOServicePlane,
CFSTR(kIOBSDNameKey),
kCFAllocatorDefault,
kIORegistryIterateRecursively);
if (name)
{
// Got child BSD Name e.g. "disk2s1"
}
}
}

pci_driver.probe function not called so pci_device_id wrong?

I am moving my first steps into Linux Kernel Device Driver development.
I learnt that for pci-e cards I have to call pci_register_driver providing information via an object of type pci_driver ( below an example ).
When I load my module ( via insmod ) If the information passed via .id_table is found than the .probe function is called.
As I am now I cannot see my .probe function called at all ( I added some logging via printk ) so I must assume that the information contained in pci_device_id must be wrong, right?
Is there any way to retrieve this information directly from the hardware itself?
Once I plug my PCI-E card on my Linux box, where I can find all information about it?
Maybe reading BIOS or some file in sys?
Any help is appreciated.
AFG
static struct pci_driver my_driver = {
// other here
.id_table = pci_datatable,
.probe = driver_add
//
};
static struct pci_device_id pci_datatable[] __devinitdata =
{
{ VendorID, PciExp_0041, PCI_ANY_ID, PCI_ANY_ID },
{ 0 },
};
int __devinit DmaDriverAdd(
struct pci_dev * pPciDev,
const struct pci_device_id * pPciEntry
)
{
// my stuff!
}
While the accepted answer does indeed answer the question, I want to elaborate a bit about the probe function not being called.
According to the Documentation/PCI/pci.txt (How To Write Linux PCI Drivers) the probing function is called for all existing PCI devices that are not owned by the other drivers yet. So, even if you have the correct vendor and device IDs you will not see the function being called if the device is owned by another driver.
To see which drivers own which devices run:
lspci -knn
If you temporarily change both vendor ID and device ID to PCI_ANY_ID your probe function will be called for every available (i.e. not owned) device.
The command you want is lspci.
With no arguments it will give you a list of all PCI devices, eg:
$ lspci
00:00.0 Host bridge: Intel Corporation 2nd Generation Core Processor Family DRAM Controller (rev 09)
00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family
03:00.0 Network controller: Intel Corporation Centrino Advanced-N 6205 (rev 34)
...
Then to get the ids, use:
$ lspci -v -n -s 03:00.0
03:00.0 0280: 8086:0085 (rev 34)
Subsystem: 8086:1311
Flags: bus master, fast devsel, latency 0, IRQ 52
You can also find the same information in /sys:
$ cd /sys/bus/pci/devices/0000:03:00.0
$ cat vendor device
0x8086
0x0085
$ cat subsystem_vendor subsystem_device
0x8086
0x1311

What is Target Device of IOCTL_USB_GET_ROOT_HUB_NAME (USB driver specific IOCTL IRQ)

I am a bit confused by the USB IOCTL IOCTL_USB_GET_ROOT_HUB_NAME. What is the target device of it? Although the MSDN WDK doc clearly indicates the target device, I am still confused by the USBVIEW sample provided by the WDK. The reason I'm confused is as follows:
I am new to kernel mode and USB driver writing in Windows and is now studying the USBVIEW sample from the windows driver kit http://msdn.microsoft.com/en-us/library/ff558728(v=vs.85).aspx. The MSDN describes the first step the USBVIEW sample performs as:
Enumerate host controllers and root
hubs. Host controllers have symbolic
link names of the form "HCDx", where x
starts at 0.
Use CreateFile() to open each host
controller symbolic link.
Create a node in the tree view to
represent each host controller.
After a host controller has been
opened, send the host controller an
IOCTL_USB_GET_ROOT_HUB_NAME request to
get the symbolic link name of the root
hub that is part of the host
controller
But, I double checked the usage of IOCTL_USB_GET_ROOT_HUB_NAME in MSDN http://msdn.microsoft.com/en-us/library/ff537326(v=VS.85).aspx
which says:
IOCTL_USB_GET_ROOT_HUB_NAME is a
user-mode I/O control request. This
request targets the USB hub FDO.
Note that the target of the IOCTL_USB_GET_ROOT_HUB_NAME IRP is a USB Hub FDO. However, as described by the USBVIEW sample, we just retreived the host controller symbolic link which means the device object is a host controller device object. How could we send it a IOCTL_USB_GET_ROOT_HUB_NAME IRP? Should we retreive a USB hub FDO somehow first?
I would guess it's an unfortunate copy-paste error. IOCTL_USB_GET_ROOT_HUB_NAME is indeed sent to the host controller and therefore handled by the USB Host Controller FDO.
By the way, just to put you in context:
The term "FDO" only loosely concerns user mode -- it's not like you can access any other "xDO" anyway. If you were to send this IOCTL in kernel mode, then sure, you can send an IOCTL to any specific device object in the device stack ("can" doesn't mean "should", mind you). However, a DeviceIoControl from a user mode application always sends IOCTLs to the top of the device stack (therefore it passes all the filters, the FDO and down to the PDO).
This question was asked on March 28, so I really hope you've solved it by now :)
As the documentation states you will need a handle to the USB host controller but it is not very clear on how you are supposed to get such a handle. In USBView something similar to this function is used to get the device path name by passing GUID_DEVINTERFACE_USB_HOST_CONTROLLER (include initguid.h and usbiodef.h):
vector<wstring> EnumDevices(
_In_ const GUID Guid
)
{
vector<wstring> r;
int index = 0;
HDEVINFO hDevInfo = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_DEVINFO_DATA DevInfoData;
memset(&DevInfoData, 0, sizeof(SP_DEVINFO_DATA));
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
while (SetupDiEnumDeviceInfo(hDevInfo, index, &DevInfoData)) {
index++;
int jndex = 0;
SP_DEVICE_INTERFACE_DATA DevIntData;
memset(&DevIntData, 0, sizeof(SP_DEVICE_INTERFACE_DATA));
DevIntData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
while (SetupDiEnumDeviceInterfaces(
hDevInfo,
&DevInfoData, &Guid, jndex, &DevIntData
)) {
jndex++;
// Get the size required for the structure.
DWORD RequiredSize;
SetupDiGetDeviceInterfaceDetail(
hDevInfo, &DevIntData, NULL, NULL, &RequiredSize, NULL
);
PSP_DEVICE_INTERFACE_DETAIL_DATA pDevIntDetData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(
sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + RequiredSize
);
memset(pDevIntDetData, 0, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + RequiredSize);
pDevIntDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(
hDevInfo,
&DevIntData,
pDevIntDetData, RequiredSize,
NULL,
&DevInfoData
);
r.push_back(wstring(pDevIntDetData->DevicePath));
free(pDevIntDetData);
}
}
return r;
}
Keep in mind using the above function you can also request devices of type GUID_DEVINTERFACE_USB_HUB and GUID_DEVINTERFACE_USB_DEVICE which may eliminate any need to interact with the host controller or hubs directly.

Resources