Find DeviceInterface (SP_DEVICE_INTERFACE_DATA) for DeviceInfo (SP_DEVINFO_DATA) - winapi

I am trying to communicate with a USB printer using c-function CreateFile and therefore i need the device path. I know that i can get the device path by SetupDiEnumDeviceInterfaces and SetupDiGetDeviceInterfaceDetail, but for SetupDiEnumDeviceInterfaces i need to give an InterfaceClassGuid as third parameter which I don't know.
My current approach is:
OpenPrinter with the "user friendly" name of the Printer
GetPrinterDataEx with "PnpData" and "DeviceInstanceId" as parameters 2 and 3 which gives me the DeviceInstanceId
ClosePrinter
SetupDiCreateDeviceInfoList (with NULL-parameters)
SetupDiOpenDeviceInfo with the DeviceInstanceId obtained in step 2. Now I have the DeviceInfo of the printer
CM_Get_Parent with the DevInst of the printer (obtained in step 5).
CM_Get_Device_ID of the parent (obtained in step 6)
SetupDiOpenDeviceInfo with the device id obtained in step 7. Now I have the DeviceInfo of the USB-Interface (but not the interface itself) and am almost at the end.
The only missing thing is to get the device interface (SP_DEVICE_INTERFACE_DATA) when I have the SP_DEVINFO_DATA. The other way would be easy: Having the SP_DEVICE_INTERFACE_DATA, I could call SetupDiGetDeviceInterfaceDetail, so basically I am looking for the opposite function of SetupDiGetDeviceInterfaceDetail.
If it would be possible to enumerate ALL interfaces without having to know the InterfaceClassGuid, I could iterate through the list of interfaces and look for the one that is pointing to my device, but unfortunately, this is not possible.
The following articles were very helpful on my way:
Figuring which printer name corresponds to which device ID AND
http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/51449be7-a4fa-476b-8cd2-b8933bfa3294/enumerate-multifunction-printer-in-vc?forum=wdk
Am I missing something?

It's been awhile, so I imagine you already found the answer. I'll answer it anyway for someone who may find this question later. I believe the answer is to call SetupDiEnumDeviceInterfaces passing in your SP_DEVINFO_DATA as the second parameter. From the documentation:
A pointer to an SP_DEVINFO_DATA
structure that specifies a device information element in
DeviceInfoSet.
This parameter is optional and can be NULL. If this parameter is
specified, SetupDiEnumDeviceInterfaces constrains the enumeration to
the interfaces that are supported by the specified device. If this
parameter is NULL, repeated calls to SetupDiEnumDeviceInterfaces
return information about the interfaces that are associated with all
the device information elements in DeviceInfoSet. This pointer is
typically returned by SetupDiEnumDeviceInfo.

Related

What is the name 0x41 (65) in a snmp variable bindings reply?

I am attempting to understand SNMP (in general, and v3). The goal is to include an snmp agent in an embedded device running an RTOS.
I've already been through over a dozen RFCs with at least another dozen more to go. Each one creates more questions than it answers. (1052, 1065, 1067, 1155, 1156, 1157, 1212, 1213, 1592, 1905, 2578, 2579, 2580, 3410, 3411, 3412, 3413, 3414, 3415, 3416, 3417, 3418, 3584... )
I implemented mDNS-SD and 802.1X EAPOL with just a couple RFCs and it wasn't this confusing.
Many of the reviews of books I considered all complain of the same inconsistent and vagueness of the material. I bought a couple books that had better reviews.
Searching online isn't getting anywhere largely because the keywords aren't finding things I want answers to. So I must not even know the best keywords to search with.
Eventually, I decided to just try to reverse engineer what's going on, I installed WireShark on a Linux PC, and the snmpd and snmp tools, so I could sniff it. Here is what I have, and can't align what I see with what I read.
This is a v3 sniff, It's a reply to the first request from a manager. This question is just zeroing in on one of the things that I want to understand. I can't decode and examine a plaintext PDU, because I can't get a request in v2 or v1.
Wireshark shows this reply to a manager. It's apparently the first step in whatever authentication it to be used.
The book I have shows this as the protocol on the wire. And I am trying to parse out the variable bindings.
Here are the variable bindings from Wireshark
A "sequence" that is 15 bytes long (x30 x0f)
This, from the RFC, says that the list is a SEQUENCE of VarBinds, where each VarBind is the object name, and the value in ObjectSyntax. So it's looking okay so far.
Here is the next segment inside the SEQUENCE (Wireshark highlighted all 14 bytes)
An object ID that is 10 bytes long (x06, x0a)
Here is the actual object:
The objectName is the object ID, and it is x2b x6 x1 x6 x3 xf x1 x1 xx4 x0 or (1.3).6.1.6.3.15.1.1.4.0
Given that this is ISO, ORG, DOD, INTERNET, 6?... I have to assume "6" is an object under internet branch I've not yet come across. Likely something to do with the v3 security.
Next, is the value.
This is a type x41 (65), with a length of 1, and a value of 7.
Well, in "ObjectSyntax" what is x41? I can't find it defined anywhere.
For that matter, all these RFCs use words for identifiers, and I can find only a fraction of what their actual numeric values are.
Wireshark knew what it was... It's saying "Counter32"... is that what x41 is supposed to be? If so, it's nowhere near 32 bits. It's only one byte. Again, I'd like to find it's definition.
Also, somewhere, (I can't even recall which RFC) it said the reply to an OID request is to append the value to the requested object, not replace the zero (example: request: 1.3.6.1.4.300.1 -> reply 1.3.6.1.4.300.1.15 so it is a value of 15 ). This OID has a trailing zero, nad I'm not sure why.
Can anyone point me to some useful, concise, condensed information explaining this material? Every RFC requires that I go back and read some previous (and sometimes obsoleted) RFC, and I've now got over 25 of them already. I don't think it should take this many RFCs to be able to write an "simple" snmp agent. A month of researching, and most of what I have to show for it is how to read MIB files. Although that take some mental gymnastics too.
"Simple" is rather deceptive (as more than one book reviewer has stated).
RFC 1157 specifies that SNMP messages are encoded with "a subset of the basic encoding rules of ASN.1". I don't think the official basic encoding rules (BER) specification is available for free, but it's not hard to find explainers online (here's one I found with a simple search). To your question about the 0x41 byte, this is a BER identifier. The 2 most-significant bits (01) tell you the "class" (i.e. something like a namespace) is "application". The "form" bit (0) tells you that it's a primitive type (i.e. not a sequence). Finally the "tag" is 1. Consulting the SNMPv2-SMI MIB (RFC 2578) you can find this definition:
Counter32 ::=
[APPLICATION 1]
IMPLICIT INTEGER (0..4294967295)
You also asked about why a 32-bit integer is encoded with a single byte. This requires you to distinguish between the scope of the SNMP standard versus the ASN.1 standard. ASN.1 only has a single INTEGER type, which 1) has an unlimited range, 2) is always signed (two's complement), and 3) should be encoded in the least number of octets possible. This actually means that a Counter32 (or any other 32-bit unsigned integer type) might use up to 5 bytes for its encoding (see this answer I gave to a question about that).
Finally, you asked about the way the replies are modifying the requested OID. I was confused about this for a long time, but when I figured it out, I realized it's actually pretty simple. I think the best place to start is with this excerpt from RFC 1157:
Each instance of any object type defined in the MIB is identified in
SNMP operations by a unique name called its "variable name." In
general, the name of an SNMP variable is an OBJECT IDENTIFIER of the
form x.y, where x is the name of a non-aggregate object type defined
in the MIB and y is an OBJECT IDENTIFIER fragment that, in a way
specific to the named object type, identifies the desired instance.
This naming strategy admits the fullest exploitation of the semantics
of the GetNextRequest-PDU (see Section 4), because it assigns names
for related variables so as to be contiguous in the lexicographical
ordering of all variable names known in the MIB.
The type-specific naming of object instances is defined below for a
number of classes of object types. Instances of an object type to
which none of the following naming conventions are applicable are
named by OBJECT IDENTIFIERs of the form x.0, where x is the name of
said object type in the MIB definition.
For example, suppose one wanted to identify an instance of the
variable sysDescr The object class for sysDescr is:
iso org dod internet mgmt mib system sysDescr
1 3 6 1 2 1 1 1
Hence, the object type, x, would be 1.3.6.1.2.1.1.1 to which is
appended an instance sub-identifier of 0. That is, 1.3.6.1.2.1.1.1.0
identifies the one and only instance of sysDescr.
So, to summarize, the OID that comes from the MIB doesn't refer to a concrete object, but to the "object type". Each concrete object (i.e. "instance") is identified by a suffix of one or more sub-identifiers (i.e. the y in this explanation). For singleton objects, this suffix is always 0. However, I think most SNMP objects are found in tables, not in singleton objects. I don't actually know of a good explanation of this in the standards, so I'll give it my best shot.
Like any table, SNMP tables are made up of rows and columns. In SNMP, however, the rows are called "entries", and each entry defines a custom type to describe the columns. Here's a simple example from the IF-MIB:
ifTable OBJECT-TYPE
SYNTAX SEQUENCE OF IfEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"A list of interface entries. The number of entries is
given by the value of ifNumber."
::= { interfaces 2 }
ifEntry OBJECT-TYPE
SYNTAX IfEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry containing management information applicable to a
particular interface."
INDEX { ifIndex }
::= { ifTable 1 }
IfEntry ::=
SEQUENCE {
ifIndex InterfaceIndex,
ifDescr DisplayString,
ifType IANAifType,
ifMtu Integer32,
ifSpeed Gauge32,
ifPhysAddress PhysAddress,
ifAdminStatus INTEGER,
ifOperStatus INTEGER,
ifLastChange TimeTicks,
ifInOctets Counter32,
ifInUcastPkts Counter32,
ifInNUcastPkts Counter32, -- deprecated
ifInDiscards Counter32,
ifInErrors Counter32,
ifInUnknownProtos Counter32,
ifOutOctets Counter32,
ifOutUcastPkts Counter32,
ifOutNUcastPkts Counter32, -- deprecated
ifOutDiscards Counter32,
ifOutErrors Counter32,
ifOutQLen Gauge32, -- deprecated
ifSpecific OBJECT IDENTIFIER -- deprecated
}
So, ifTable has an OID of 1.3.6.1.2.1.2.2, and ifEntry has an OID of 1.3.6.1.2.1.2.2.1. Each item in IfEntry also has its own definition, which includes the OID relative to ifEntry. Generally they match up with the entry's data type, so, for example, ifIndex, as the first column in IfEntry, has an OID of ifEntry.1. Confusingly, when you do a simple Get-Next walk, you will traverse in column-major order, meaning you will get all the ifIndexes, followed by all the ifDescrs, and so on.
So, with all that explained, I'm now prepared to explain the instance identifiers for these tables. Notice above that ifEntry defines
INDEX { ifIndex }
This means, first, that each row is guaranteed to have a unique ifIndex, and, more importantly, that the ifIndex is used as the instance identifier for the entire entry. For example, you can pick any column in the IfEntry data type, let's say ifOperStatus (1.3.6.1.2.1.2.2.1.8), and use Get-Next to find the first instance of that column. Let's say its OID is 1.3.6.1.2.1.2.2.1.8.1, and it's value is 1 (up). The last sub-identifier tells you that it belongs to the row whose ifIndex is 1. To find the name of that interface, you can then query ifDescr.1, and to find its speed setting, you can query ifSpeed.1, and so forth. In this case, it is possible to query ifIndex.1, which will just return 1, but in many tables, the INDEX columns are not-accessible, meaning you can only find out what instances there are by walking some other column. Some tables also use multiple indices, or use OCTET STRING or even OBJECT IDENTIFIER rather than INTEGER typed indices. The rules for encoding and decoding those are in RFC 2578 section 7.7.

driver doesnt find property in device tree during linux init

I try to bring up Cortex A9 (Arria V) based board.
During the init the cadence-qspi driver complains that it cannot find the property of the correspondent node int he device tree and fails to initialize. When I look at the representation of the DT, and specifically at /sys/bus/patform/devices/ff705000.qspi/of_node/fifo-depth - I see that it keeps correct value.
What can be the reason for such behavior?
kernel 4.14.130-ltsi from linux-socfpga.git
Thanks,
Ilya
During the init the cadence-qspi driver complains that it cannot find the property of the correspondent node int he device tree
...
I see that it keeps correct value.
The value of the property is irrelevant when the issue is the driver "cannot find the property".
"Finding" a property relates to the name of that property, rather than its value.
What can be the reason for such behavior?
The likeliest reason is the property name (that you used) in your Device Tree does not match the required property name (specified by a character string) in the kernel driver.
The file Documentation/devicetree/bindings/mtd/cadence-quadspi.txt states that the actual name of the property in question is:
cdns,fifo-depth
whereas you report that your Device Tree uses just fifo-depth (and is obviously not a string match).
Beware that there are other required and optional properties for this node that utilize the cdns, prefix, so other lines in your Device Tree may need correction.

What's the difference between event's Unique-ID and Channel-Call-UUID?

Freeswitch events contain two variables (Unique-ID and Channel-Call-UUID) that seem to always be set to the exact same value: the leg's unique identifier.
I don't see the purpose of this and while Unique-ID has a one-line documentation on FS's wiki ("uuid of this channel's call leg"), Channel-Call-UUID doesn't.
Even worse: I came accross two examples where their values were different:
[...]
Channel-Call-UUID: c9bbde8b-379b-45d4-b193-3f761a44f3e2
Unique-ID: 81273088-c31f-4469-85a6-c878e42210e5
[...]
[...]
Channel-Call-UUID: ada7f3de-2374-4144-9b1d-eade29df0779
Unique-ID: f3ebca6c-d9cd-4f89-ae12-748e6c479dda
[...]
I need to be able to clearly identify a leg in my code, so I'd like to know
which one is the most accurate and
what's the purpose of the other one
"Unique-ID" identifies the leg of the current channel (this value seems to always be identical to "Caller-Unique-ID", documented as "This channel's uuid").
"Channel-Call-UUID" is an ID that can be used to identify answered/bridged channels. It seems to be derived from the "Unique-ID" of the channel's creator.
The value of "Channel-Call-UUID" of the b-leg (the callee) differs from its "Unique-ID", but it is identical to the value of the "Other-Leg-Unique-ID" header.
The source code (src/switch_channel.c) supports my previous claims:
if ((v = switch_channel_get_variable(channel, "call_uuid"))) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", v);
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Channel-Call-UUID", switch_core_session_get_uuid(channel->session));
}

How to programmatically trigger Flip 3D on Windows?

How do I programmatically trigger Flip 3D on Windows Vista and 7?
Is there an API for this and if so, what is it called and where can I find the relevant functions? (I need a specific answer, eg a web link to the actual functions, not something generic like "Oh, it's in DirectX.")
On a related node, I have a Logitech mouse that has a "Document Flip" button that invokes Flip 3D (and then I can press up/down keys to page through the results.) I am curious if they are using an official Windows API or if there is some low level hackery going on.
you need to run a function from dwmapi
Sadly there is no proper funktion name only the ord-number 105
You can try this by executing %WinDir%\System32\rundll32.exe dwmapi #105 from Run-dialog or cmd.
edit
ive found out the Windows' API GetProcAddress Function accepts ord-numbers (the 105) as second parameter as well as proper name
lpProcName [in]
The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.
so use this code
typedef vois (__cdecl *FlipProc)();
HINSTANCE hDwmApi = LoadLibrary(TEXT("dwmapi.dll"));
FlipProcAdd = (FlipProc) GetProcAddress(hDwmApi, (LPCSTR)105);
(FlipProcAdd)();

IOServiceMatching on AppleUSBCDCACMData IOClass: Anomaly?

I am trying to extract a list of all AppleUSBCDCACMData IOClass devices in my mac using the following code snippet (just some small scale modifications in apple sample code). The device is a usb modem which creates some 7 /dev/cu.usbmodemx device nodes.
error = IOMasterPort(MACH_PORT_NULL, &masterPort);
if(error){
return ;
}
else{
matchingDict = IOServiceMatching("AppleUSBCDCACMData");
IOServiceGetMatchingServices(masterPort,matchingDict,&modem_iterator);
while(usbDevice = IOIteratorNext(modem_iterator))
{
}
My observation is, the iterator returned by IOServiceGetMatchingServices is empty (ie nothing to iterate on). But if i pass "AppleUSBCDCACMControl" as the parameter to IOServiceMatching, i get a iterator of a list of 7 elements - which is in conformance with the IORegistryExplorer view. See a screenshot of IORegistryExplorer here, http://tumblr.deepak.dk/post/1666218968/ioregistryexplorer
It appears that it is not possible to query IORegistry with arbitrary IOClass name strings? Since i faced the same issues with some non-standard proprietary IOClasses as well.
This can be reproduced using any USB modem (3g/HSDPA) which loads AppleUSBCDC driver.
What am i doing wrong?
IOService objects can only be matched once registerService() has been called for them. AppleUSBCDCACMControl does this, but AppleUSBCDCACMData does not.

Resources