SetupDi API: Control Device Manager functionality programmatically - c#

Problem:
I have a PC with a bunch of network cards of the same type and two drivers that can service them. When I let Windows 7 decide which driver to load, each of them is loaded with the manufacturer's drivers, and for 3 out of 4 cards, that is the desired behaviour. But the last card needs to load a different driver than the others.
Manual solution:
This problem can be manually solved by going to the device manager, selecting "Update Driver" from the card's entry's context menu, choosing to list every available driver and then choosing the one that windows neglects (because the manufacturer's driver is signed, and mine isn't). To conduct this programmatically is the ultimate goal I pursue.
Tried approaches:
I already tried quite some things to solve this, but I still can't exactly solve the problem I am having.
The first idea was to disable the UPnP Service or similarly decline Windows' efforts to assign the drivers, but I can't because it is needed for the other cards, and the given circumstances dictate that the drivers will possibly have to be reassigned quite regularly.
I tried to use the DevCon tool, since it offers something that, at first glance, looks like an incredibly easy way to achieve my goal: A command line interface that is said to be as powerful as the device manager itself. From what the documentation says, it offers usable methods indeed, and I tried it thouroughly. But there seems to be a problem with identifying the card that I want to access uniquely. Using the DevCon Tool I can retrieve Device IDs of the following format:
PCI\VEN_XXXX&DEV_XXXX&SUBSYS_XXXXXXXX&REV_XX\X&XXXXXX&X&XXXX
This, sadly, does not help much. Until the second '\'-symbol, the IDs are the same for all four devices. I can use them to issue the commands that DevCon offers me (like listing compatibale hardware IDs or just finding them). But it seems that DevCon does not evaluate the part of the ID that follows the second '\', which means that I can not just disable one of the cards (I can indeed tell which of the cards is the one the driver of which I want to change, so no problem in that respect).
A very similar approach was to use the SetupDI Api of Windows. Actually, it is the exact API that the DevCon Tool uses (well, that's what they say, anyways). And while finding and identifying the device in questions is relatively easy (even for the C# person that I am, who never had to leave the managed world), I can not seem to find a way to do anything but enabling and disabling the device. I would most probably be able to construct a workaround if I had a way of removing the card (completely disassociate it with any driver), but I can't figure out how. Disabling the device is nice, but it preserves the driver association and therefore is not a help for me.
If you can help me refine my approaches or point me another route to try, please do so. Even if your answer does not solve my problem, your suggestion might hint me at approaches I have not yet tried, and I am desperate enough to try them all.

The exact problem can be solved using a combination of the setupapi.dll and newdev.dll. Note that the latter is only available on Win7 and later. Using the device and driver enumeration functions from the setupapi you can get handles to devices and appropriate drivers from the driver store. The newdev api then offers an install function that takes a device and a driver object (retrieved from the setupapis before) and install the specified driver on the device.

Related

DirectShow - how to determine what decompressor to use for preview stream (C#)?

I am working on existing software that needs an update. Disclaimer: this is my first time working with DirectShow.
Basically, our software allows users to connect several different video devices, including third party devices. Up until this point we have been able to get away with using just an AVIDecompressor. Our new device requires an MJPEGDecompressor. We need to continue supporting both.
I have considered simply detecting the presence of our new device outside of DirectShow and passing an argument that switches between the two decompressors, but I would like third party devices that require the MJPEGDecompressor to also work, so I'd prefer to do some sort of detection in the stream.
I would ideally like to be able to detect which decompressor is required before/during graph initialization. What is the best way to do that and have it work with any device using one of those two decompressors?
The technology you are asking about in DirectShow is Intelligent Connect: you are not sure which filters you need to connect the parts and DirectShow offers its services to supplies the missing links into the chain using its filter registry.
The referenced page above provides you with details on how exactly Intelligent Connect works, and a shorter answer is this: when you already have an output pin which needs a decompressor and you are not sure which filter is needed and you want to query this before filters are actually added and connected, you can use
... Finally, if no suitable filter has been found, the Filter Graph Manager searches the registry, using the IFilterMapper2::EnumMatchingFilters method. It tries to match the output pin's preferred media types against media types listed in the registry.
Most likely the Filter Graph Manager would use the same anyway, and it will go over the potential candidates trying one after another until connection is made. when you use this yourselves, you have finer control over the process and you can see the filters before actual connection attempts.

ManagedUPnP: Discovery search URI without version?

For an application, I've to discover all "my" devices that runs, and their version, to push them an update(via another protocol).
But I can't figure out how to specify to the discovery object the URI it has to search, without having to specify the object.
NOTE: I know that I can also discover with null URI string and then filter on the device that I receive, but since I've a huge(600+) number of UPnP device on the network, but a small number of UPnP device that I need to search(~20), it will takes a lot of time, and I'm searching an efficient way of doing it.
So, if my URN is the following: urn:upnp-org:device:TestDevice:2.2.5, and I want to have
urn:upnp-org:device:TestDevice:*, how should I proceed?
I tried
urn:upnp-org:device:TestDevice:
urn:upnp-org:device:TestDevice:*
Is there any wildcards? Placeholders?
I think you are misusing the versioning feature of M-SEARCH. ST version means interface version, not implementation version and higher versions are expected to be fully backwards comaptible. Hence you are capable of searching for any version of your device, by simply filling ST: with the lowest known version. All devices will respond you, but with the version you searched for, not their actual version (because they are backwards compatible). There is nothing like "wildcard", because devices are expected to do their best in matching the M-SEARCH requirement, not to be bragging about their actual version.
I suggest reading thoroughly the UPnP Device Architecture document, chapter 1.2.2 and 1.2.3 revolving around M-SEARCH request and response.
If you want to use UPnP for implementation version discovery (which is perfectly legal) i suggest implementing a custom service with a function returning that info. You already have a custom device, as i understand it.

Service codes in PhoneCallTask WP7?

I want to use PhoneCallTask for using some services from my cellular provider in other words I want to be able to dial #1234* within code
if this isn't available yet is there anyway to do that by any other way
I need it urgently
This is deliberately not available as part of the security considerations and principles designed into the phone.
If it were possible to get the response to such commands then it would be possible to get someones phone/cell and IMEI numbers without their knowledge or permission. With these you coudl do some very nefarious things.
If you really need this urgently then you're stuck. In future I'd recommend finding out what is possible with a platform before you starting building an application.
As you haven't included any code I'm going to assume that you've not tried anything yet.
So this code may help
PhoneCallTask phoneCallTask = new PhoneCallTask();
phoneCallTask.PhoneNumber = "#1234";
phoneCallTask.DisplayName = "Service Number";
phoneCallTask.Show();
I've not been able to try this to see if it works with that input, so it may be an issue with the "PhoneNumber" field if that does not work
EDIT:
Don't forget to add
using Microsoft.Phone.Tasks;
As far as I'm aware these are operations that are stored on the SIM card and have nothing to do with the layer of Windows Phone you have access to. In other words, the ISO standard (im guessing) for cellular interconnected devices will require a device to handle certain requests (such as typing *#06# to display the devices IMEI number). Thus it is likely that you will not be able to interact with these calls. You won't be able to make the phone think your App is making a request it knows can only come from the SIM card due to the way the OS sandboxes various services.

How can I get the MAC address of a wireless access point from C#?

I know there are other posts that dance around this a bit, but I'd like to know how (or if it's even possible) to, using C#, grab the MAC address of the wireless access point that a user is accessing a site or other HTTP-based API from. I work for a hospital and the location of all of our WAPs are known, and would like to move forward with setting up a wayfinding solution that doesn't rely on specific mobile device APIs to determine either MAC addresses or GPS (since I'd like this to work inside buildings as well). I'd also like to not have to use something like Skyhook.
If the MAC address can't be gotten, would assigning specific IP blocks to each WAP, followed by just looking at IPs be a better solution perhaps?
Thanks in advance
Depending on the WAP's you have you may be able to use SNMP to get the information. You'll need to look at what MIB's (Management Information Base) are supported to find the information you are looking for.
Using SharpSNMP API would be a good place to start (http://sharpsnmplib.codeplex.com/).
At this point i have to advise you that MAC addresses are not unique, making the process of using them problematic. Even within a hospital you will find that there are duplicate MAC addresses, making relying on this method of identification at best, inadvisable.
If your wayfinding app is predominantly for use within a building, then relying on WAP positioning will result in a high margin of error. This is caused by relatively long range of up to 150ft. So you can locate them with a margin of error of up to 150ft. Not necessarily what you're after, especially considering all those different levels.

How to reliably get the computer's on-board network adapter's MAC address?

I am trying to (more or less) uniquely identify a system for licensing purposes. I have chosen the computer's on-board network adapter's MAC address for this task, since I can be sure that every cmputer running this software actually has one, and this avoids re-activation when changing e.g. the harddrive.
I am having troubles reliably identifying the onboard network adapter, though.
Using the "Win32_NetworkAdapterConfiguration" ManagementClass, I can get a whole lot of MAC Addresses, including the address I like, but I have not found a way to distinguish the onboard one from virtual adapters installed by Windows or Virus Scanners.
This list seems to be ordered, though. The MAC Address I am interested in is (on my machine) listed before other (real) network adapters. (The list is ordered by interface index.)
Using NetworkInterface.GetAllNetworkInterfaces(), I think I can identify the real network adapters by filtering on .NetworkInterfaceType == NetworkInterfaceType.Ethernet, but this list seems to be unordered (an added network card appears before the onboards one).
Is first using the second method to get a list of real networks cards and then sorting them by the order of appearence in the first list a reliable way of identifying the MAC address I am looking for? Can the interface index in the first list change?
I'd be happy to hear your thoughts!
Thanks!
P.S.: I know that the MAC address can be rather easily changed, but I can live with that. I cannot live with the customer not being able to use the software after simply inserting a WLAN stick =)
A rather low-tech solution would be to invoke the netstat command and look for the MAC address of the adapter that has a valid IP address. I've never seen the netstat command fail on a machine whereas I've seen WMI give unexpected results numerous times.
In any case, I have done a similar activation system before and I used the MAC address as the identifying key. In the end, it wound up being more trouble than it was worth - both for me and the customer! What I found to be a far better balance and less hassle was to have the user "sign in" the first time the software was installed. With the user's consent, you could send some piece of identification to the server such as their MAC address.
Then you only need to periodically check your activation database for evidence of major license violations and deactivate the keys as necessary. As a customer that hates product activation, and an ISV that hates software piracy, I can see both sides of the argument and this way it avoids putting the customer in the uncomfortable position of having to convince you they are legit when something (inevitably) goes wrong.
Just to name a few reasons why MAC identification may not work... I use two NIC's (wired and wireless) in my laptop depending on whether I'm at work or home. One or the other may be disabled at any time. The other thing to note is that I use virtual machines quite a bit and not only do they get their own MAC but I could specify any MAC I want. Then of course one day you'll find out that you have like 100 people in your database with a MAC of all zeros. :) Nothing is guaranteed here.
you should consider some other properties from WMI in addition to MAC address.
The way that Windows Product Activation handles this, is to look at properties like the MAC address (as well as other identifying information about the card itself, such as PCI vendor info), as well as some common device properties (HDD controllers, display adapters), and base the need for reactivation on certain thresholds. If too many of these things change, then reactivation is required.
Here's a great article on the topic and should give you some food for thought on how to approach choosing good properties to look at for your own licensing/activation system:
http://aumha.org/win5/a/wpa.php
If your main requirement is to uniquely identify a PC, then I suggest you take a look at this question. The accepted answer talks about a solution as well as the pitfalls of using the MAC address identifier approach
Hope this helps
To access Network Interface details in .Net, refer to the NetworkInterface.GetPhysicalAddress method within the System.Net.NetworkInformation namespace.
Usage is detailed on MSDN.
I would definitely refer to the link Ryan has provided with regards to relying on a MAC address for identification.

Categories