If I can get a handle to a monitor and get the monitor's info using the handle and the "GetMonitorInfo" function from the windows API, is there some way I can determine more info like whether that monitor is using the DVI or the VGA port? Or what that device's name is?
Thanks.
I don't know of a direct way to retrieve the type of port used. About the best I know of is that you can use WMI to enumerate objects of the Win32_DesktopMonitor class, and guess at the connection based on the bandwidth property.
If you're willing to do a fair amount of work, you can sometimes improve your guess by enumerating Win32_VideoController objects. Some controllers only have VGA, and others only have DVI -- but if you get a controller that supports both, you're probably back to guessing based on the stated bandwidth (which may not be supplied either).
Now I'am working on a MFC program. What I want to know is the speed a process receive/send to the network. Suppose I have a process named chrome.exe, it may receive 1008B/s, send 2987B/s. I know I can get what I want in the Win 7 Resource Monitor. But how can I get those data in my program. Dose MFC or Win32api support this?
You can obtain this information, as well as a wealth of other performance data using WMI:
Monitoring Performance Data
This class is probably what you are looking for:
Win32_PerfFormattedData_Tcpip_NetworkInterface
From a native C++/MFC application, you'll access WMI through some COM interfaces
Have fun!
We're porting our USB device dll's to use the generic WinUsb.
However, WinUsb doesn't support multiple concurrent application accss to the same device (Same VID & PID).
I wanted to know if there is a way to implement this concurrent access using WinUsb?
I read about filter drivers & services.
1. I don't want to use a filter driver because, as I understand, this will have to pass WHQL, and I rather not go this path.
2. Regarding a windows service: How exactly should I implement it? should the service get all of the calls to WinUsb, and if a different application tries to access the same device, it will close the connection to the first application, open a new connection, and back again?
Is the service the right correct solution in this case? Is there another way to implement the solution other that what I wrote?
Thanks.
A filter driver does not need to pass WHQL. You only need to sign the catalog file, needed by the driver package. This only needs a code signing certigficate from verising/... . This should be a good starting place to get to know this.
Nevertheless, a kernel driver can be hard to develop. So maybe a COM server would be a better approach. You implement this sharing from a service, by allowing COM-clients to create objects from your service and then implement some kind of sharing/mutual exclusion in your COM-server.
A COM-exe servers can be written relativly fast.
There are any advantages or disadvantages of using the WMI instead of Windows API to access to the information of the system? as speed, additional permissions, memory usage.
or depends on the WMI class and how the WMI implements the access to the information?
The main disadvantage of WMI is speed, it is slow to query data and if you are trying to use it during start up it can delay you starting as the WMI service takes a long time to come up.
However, WMI information is richer, as in you need to sometimes make several API calls to get the same amount, some information is a lot easier to get at and the filtering syntax can dramatically reduce the amount code you have to write.
If speed isn't a massive issue, I would always lean towards WMI.
Disadvantage: Speed
Advantage: Wraps the native API, so as API calls change, unless the WMI changed also you will (might) get the benefits. It will also save you some coding.
And richer data. Since programmers can write their own WMI providers, you can get data from third party software. That's what Microsoft is doing in their security center interface-getting data from third-party antivirus and firewall softwares.
Advantage of WMI: Can get info about remote machines as easily as current machine
And impersonation!
You may have your program run with a non-proviledged user, but access a remote machine by specifying credentials.
If it is for system scope
Advantage of WMI:
Do not need to implement additional driver efforts
Disadvantage of WMI:
Need BIOS to wrap code
it is only for Windows. there's no Linux inbox driver.
I need to write a function that generates an id that is unique for a given machine running a Windows OS.
Currently, I'm using WMI to query various hardware parameters and concatenate them together and hash them to derive the unique id. My question is, what are the suggested parameters I should use?
Currently, I'm using a combination of bios\cpu\disk data to generate the unique id. And am using the first result if multiple results are there for each metric.
However, I ran into an issue where a machine that dual boots into 2 different Windows OS generates different site codes on each OS, which should ideally not happen.
For reference, these are the metrics I'm currently using:
Win32_Processor:UniqueID,ProcessorID,Name,Manufacturer,MaxClockSpeed
Win32_BIOS:Manufacturer
Win32_BIOS:SMBIOSBIOSVersion,IdentificationCode,SerialNumber,ReleaseDate,Version
Win32_DiskDrive:Model, Manufacturer, Signature, TotalHeads
Win32_BaseBoard:Model, Manufacturer, Name, SerialNumber
Win32_VideoController:DriverVersion, Name
I had the same problem and after a little research I decided the best would be to read MachineGuid in registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography, as #Agnus suggested. It is generated during OS installation and won't change unless you make another fresh OS install. Depending on the OS version it may contain the network adapter MAC address embedded (plus some other numbers, including random), or a pseudorandom number, the later for newer OS versions (after XP SP2, I believe, but not sure). If it's a pseudorandom theoretically it can be forged - if two machines have the same initial state, including real time clock. In practice, this will be rare, but be aware if you expect it to be a base for security that can be attacked by hardcore hackers.
Of course a registry entry can also be easily changed by anyone to forge a machine GUID, but what I found is that this would disrupt normal operation of so many components of Windows that in most cases no regular user would do it (again, watch out for hardcore hackers).
With our licensing tool we consider the following components
MAC Address
CPU (Not the serial number, but the actual CPU profile like stepping and model)
System Drive Serial Number (Not Volume Label)
Memory
CD-ROM model & vendor
Video Card model & vendor
IDE Controller
SCSI Controller
However, rather than just hashing the components and creating a pass/fail system, we create a comparable fingerprint that can be used to determine how different two machine profiles are. If the difference rating is above a specified tolerance then ask the user to activate again.
We've found over the last 8 years in use with hundreds of thousands of end-user installs that this combination works well to provide a reliably unique machine id - even for virtual machines and cloned OS installs.
Parse the SMBIOS yourself and hash it to an arbitrary length. See the PDF specification for all SMBIOS structures available.
To query the SMBIOS info from Windows you could use EnumSystemFirmwareEntries, EnumSystemFirmwareTables and GetSystemFirmwareTable.
IIRC, the "unique id" from the CPUID instruction is deprecated from P3 and newer.
What about just using the UniqueID of the processor?
I hate to be the guy who says, "you're just doing it wrong" (I always hate that guy ;) but...
Does it have to be repeatably generated for the unique machine? Could you just assign the identifier or do a public/private key? Maybe if you could generate and store the value, you could access it from both OS installs on the same disk?
You've probably explored these options and they doesn't work for you, but if not, it's something to consider.
If it's not a matter of user trust, you could just use MAC addresses.
You should look into using the MAC address on the network card (if it exists). Those are usually unique but can be fabricated. I've used software that generates its license file based on your network adapter MAC address, so it's considered a fairly reliable way to distinguish between computers.
For one of my applications, I either use the computer name if it is non-domain computer, or the domain machine account SID for domain computers. Mark Russinovich talks about it in this blog post, Machine SID:
The final case where SID duplication would be an issue is if a distributed application used machine SIDs to uniquely identify computers. No Microsoft software does so and using the machine SID in that way doesn’t work just for the fact that all DC’s have the same machine SID. Software that relies on unique computer identities either uses computer names or computer Domain SIDs (the SID of the computer accounts in the Domain).
You can access the domain machine account SID via LDAP or System.DirectoryServices.
In my program I first check for Terminal Server and use the WTSClientHardwareId. Else the MAC address of the local PC should be adequate.
If you really want to use the list of properties you provided leave out things like Name and DriverVersion, Clockspeed, etc. since it's possibly OS dependent. Try outputting the same info on both operating systems and leave out that which differs between.
There is a library available for getting hardware specific informations: Hardware serial number extractor (CPU, RAM, HDD, BIOS)
Maybe cheating a little, but the MAC Address of a machines Ethernet adapter rarely changes without the motherboard changing these days.
Can you pull some kind of manufacturer serial number or service tag?
Our shop is a Dell shop, so we use the service tag which is unique to each machine to identify them. I know it can be queried from the BIOS, at least in Linux, but I don't know offhand how to do it in Windows.
I had an additional constraint, I was using .net express so I couldn't use the standard hardware query mechanism. So I decided to use power shell to do the query. The full code looks like this:
Private Function GetUUID() As String
Dim GetDiskUUID As String = "get-wmiobject Win32_ComputerSystemProduct | Select-Object -ExpandProperty UUID"
Dim X As String = ""
Dim oProcess As New Process()
Dim oStartInfo As New ProcessStartInfo("powershell.exe", GetDiskUUID)
oStartInfo.UseShellExecute = False
oStartInfo.RedirectStandardInput = True
oStartInfo.RedirectStandardOutput = True
oStartInfo.CreateNoWindow = True
oProcess.StartInfo = oStartInfo
oProcess.Start()
oProcess.WaitForExit()
X = oProcess.StandardOutput.ReadToEnd
Return X.Trim()
End Function
Look up CPUID for one option. There might be some issues with multi-CPU systems.
Try this one, it gives a unique hard disk ID: Port of DiskId32 for Delphi 7-2010.