The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Shooter on March 20, 2011, 02:33:05 PM

Title: Computer Make and Model identifier
Post by: Shooter on March 20, 2011, 02:33:05 PM
Is there an API that is simple to use to identify the computer's make and model, or perhaps a place in the system registry (consistent for all Windows versions)?

Thanks,
-Shooter
Title: Re: Computer Make and Model identifier
Post by: donkey on March 20, 2011, 02:47:27 PM
That's done using WMI's Win32_ComputerSystem Class (http://msdn.microsoft.com/en-us/library/aa394102%28v=vs.85%29.aspx) and though it is straight forward, it is not "simple" to use.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 20, 2011, 04:09:43 PM
Quote from: donkey on March 20, 2011, 02:47:27 PM
That's done using WMI's Win32_ComputerSystem Class (http://msdn.microsoft.com/en-us/library/aa394102%28v=vs.85%29.aspx) and though it is straight forward, it is not "simple" to use.

Yeah, I saw that earlier and was blown away. It certainly don't look 'simple'.  :'(
Title: Re: Computer Make and Model identifier
Post by: donkey on March 20, 2011, 04:16:18 PM
You can query the registry or  look for an oeminfo.ini file, but they can be altered so they're unreliable or you can go the complicated route of writing a driver to query the SMBIOS directly. Its those or WMI.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 20, 2011, 04:23:40 PM
Quote from: donkey on March 20, 2011, 04:16:18 PM
You can query the registry or  look for an oeminfo.ini file, but they can be altered so they're unreliable or you can go the complicated route of writing a driver to query the SMBIOS directly. Its those or WMI.

Since my program is dependent on the model I guess I'm gonna have to go the long route.  I've never dealt directly with a class like that before, so I guess I might be callin' on some help in the future on this one, particularly in converting it to MASM code. :(
Title: Re: Computer Make and Model identifier
Post by: Magnum on March 20, 2011, 06:42:27 PM
For HP Computers, there are a number of registry entries that contain the make and model.

Title: Re: Computer Make and Model identifier
Post by: Shooter on March 20, 2011, 07:01:41 PM
Quote from: Magnum on March 20, 2011, 06:42:27 PM
For HP Computers, there are a number of registry entries that contain the make and model.

The same holds true for SOME Dell models, but not all.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 12:22:39 AM
Seriously, don't dick around with the registry, it can be changed by any user who can type RegEdit and use the FIND function. If you want to do a professional application then use the right interfaces and in this case that means using WMI to read the SMBIOS. Here's a quick demo of getting the manufacturer, you can always add anything else you want from the Win32_ComputerSystem Class (http://msdn.microsoft.com/en-us/library/aa394102%28v=vs.85%29.aspx) object. Note that this is COM so be sure to call CoInitialize.

// Headers available at
// http://www.quickersoft.com/donkey/index.html

// NOTE: INCLUDE Environment variable must be set to headers path

#DEFINE WINVER NTDDI_WIN7
#DEFINE FILTERAPI
#DEFINE LINKFILES

#include "WINDOWS.H"
#include "macros.h"
#include "wbemcli.h"

DATA SECTION
// Classes
CLSID_WbemLocator GUID GUID_CLSID_WbemLocator

// Interfaces
IID_IUnknown GUID GUID_IID_IUnknown
IID_IWbemLocator GUID GUID_IID_IWbemLocator
IID_IWbemServices GUID GUID_IID_IWbemServices

// Pointers >> in X64 builds do not store any pointers in LOCAL data !
pNameSpace PTR ?
pWbemLocator PTR ?
pUnk PTR ?
pObj PTR ?
pEnum PTR ?

// Results
szManufacturer CHAR 256 DUP (?)
szModel CHAR 256 DUP (?)

CODE SECTION

invoke CoInitialize,NULL

invoke GetManufacturer,offset szManufacturer,offset szModel

invoke MessageBox,NULL,offset szModel,offset szManufacturer,NULL

invoke CoUninitialize

invoke ExitProcess,0

GetManufacturer FRAME pManufacturer, pModel
LOCAL hres :%HANDLE
LOCAL bstrNameSpace :%PTR
LOCAL variant :%PTR

// Connect to the desired namespace
invoke SysAllocString,L"\\.\root\cimv2"
mov [bstrNameSpace], eax

invoke CoInitializeSecurity, 0,-1,0,0,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,0,EOAC_NONE,0
mov [hres],eax

invoke CoCreateInstance,offset CLSID_WbemLocator,NULL,CLSCTX_INPROC_SERVER,offset IID_IWbemLocator, offset pWbemLocator
test eax,eax
jnz >>.EXIT

CoInvoke(pWbemLocator,IWbemLocator.ConnectServer,[bstrNameSpace],0,0,0,0,0,0,offset pNameSpace)
test eax,eax
jnz >>.EXIT1
CoInvoke(pNameSpace,IWbemServices.IUnknown.QueryInterface,offset IID_IUnknown,offset pUnk)
test eax,eax

// Set the security for our proxy
invoke CoSetProxyBlanket,[pNameSpace],RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,0,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,0,EOAC_NONE
invoke CoSetProxyBlanket,[pUnk],RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,0,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,0,EOAC_NONE
CoInvoke(pUnk,Unknown.Release)

// Execute the query, just pull all of the information
CoInvoke(pNameSpace,IWbemServices.ExecQuery, L"WQL", L'Select * from Win32_ComputerSystem',WBEM_FLAG_RETURN_IMMEDIATELY,NULL,offset pEnum)
test eax,eax
jnz >>.EXIT2

// Step the enumeration through the class object
CoInvoke(pEnum,IEnumWbemClassObject.Next,WBEM_INFINITE,1,offset pObj,offset hres)
test eax,eax
jnz >.EXIT3

// Get the information we want
CoInvoke(pObj,IWbemClassObject.Get,L"Manufacturer",0,offset variant,0,0)
test eax,eax
jnz >.EXIT4
// The information is in UNICODE so convert it
invoke WideCharToMultiByte,CP_ACP,NULL,[variant+8],-1,[pManufacturer],256,NULL,NULL
invoke VariantClear,offset variant

CoInvoke(pObj,IWbemClassObject.Get,L"Model",0,offset variant,0,0)
test eax,eax
jnz >.EXIT4
// The information is in UNICODE so convert it
invoke WideCharToMultiByte,CP_ACP,NULL,[variant+8],-1,[pModel],256,NULL,NULL
invoke VariantClear,offset variant

.EXIT4
CoInvoke(pObj,IWbemClassObject.Release)
.EXIT3
CoInvoke(pEnum,IEnumWbemClassObject.Release)
.EXIT2
CoInvoke(pNameSpace,IWbemServices.Release)
.EXIT1
CoInvoke(pWbemLocator,IWbemLocator.Release)
.EXIT
invoke SysFreeString,[bstrNameSpace]
ret
endf


PS don't even bother to ask me to translate this, I program in GoAsm and on occasion I will translate things to MASM but this is too much work since MASM does not have intrinsic inline strings or UNICODE support.

edit: added VariantClear to free up resources.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 12:56:01 AM
Forgot to attach the project, here it is with source and executable:

Title: Re: Computer Make and Model identifier
Post by: hutch-- on March 21, 2011, 01:37:14 AM
Edgar,

It identifies my Intel board fine.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 02:35:37 AM
Thanks Steve,

I neglected to call VariantClear after each of the WideCharToMultiByte calls:

invoke WideCharToMultiByte,CP_ACP,NULL,[variant+8],-1,[pModel],256,NULL,NULL
invoke VariantClear,offset variant


It should be called to free the variants resources.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 21, 2011, 10:24:29 AM
Edgar,
It identified my Dell Latitude D600 just fine. I'll try it at work to see how it does there too.

Thanks a ton. Now I just gotta integrate it into my project somehow. I'm not at all familiar with the Windows COM objects, and going from GoASM to MASM might be a bit of a challenge for this newby, but I think I can work with this code you provided. Handy little code too.

-Shooter
Title: Re: Computer Make and Model identifier
Post by: sinsi on March 21, 2011, 10:36:53 AM
Mine says "To Be Filled By O.E.M."  :lol

To be fair, I think the BIOS setup tells me the same.
Title: Re: Computer Make and Model identifier
Post by: dedndave on March 21, 2011, 01:53:21 PM
mine reports "VGC-RB42G" which is correct however, you'd have to know that was a Sony model number
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 02:40:07 PM
Quote from: dedndave on March 21, 2011, 01:53:21 PM
mine reports "VGC-RB42G" which is correct however, you'd have to know that was a Sony model number

Hi Dave,

No "Sony" as the MessageBox title ? I would have thought they would have adhered to the specs.
Title: Re: Computer Make and Model identifier
Post by: lingo on March 21, 2011, 02:54:33 PM
mine says nothing (see the picture).
My mobo is Asus P8P67 Pro.
Title: Re: Computer Make and Model identifier
Post by: dedndave on March 21, 2011, 03:12:50 PM
my bad Edgar   :lol
i didn't notice that it says "Sony Corporation" in the title bar
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 03:25:48 PM
Quote from: lingo on March 21, 2011, 02:54:33 PM
mine says nothing (see the picture).
My mobo is Asus P8P67 Pro.

:bg

Its not that it says nothing, that would be a blank in both the title and the message. It says "System Manufacturer" and "System Product Name", guess they couldn't be bothered to enter the information and left it at SMBIOS defaults or something. Probably left the fields like that so OEM system builders could change them later, bet you the SMBIOS is FLASH on your mobo.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 05:21:38 PM
<post removed>
Title: Re: Computer Make and Model identifier
Post by: Vortex on March 21, 2011, 06:23:00 PM
Hi donkey,

Your code works fine on my Intel board.

Title: Re: Computer Make and Model identifier
Post by: FORTRANS on March 21, 2011, 06:46:00 PM
Hi,

   Screenshot of result.  Not sure if that's what you wouls expect
from Windows 2000

Regards,

Steve
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 07:26:37 PM
Hi Steve,

Not completely sure it's Win2K compatible but it should work from Win2k pro. If it is then there are 2 possibilities, first that the PC was built more than 8 or 9 years ago, second that it just doesn't have any information stored in the SMBIOS section. Be sure you use the first version in this thread, I've removed the second one so there is no confusion.
Title: Re: Computer Make and Model identifier
Post by: FORTRANS on March 21, 2011, 07:30:38 PM
Hi,

   I ran both with the same result.  And yes it was built about
ten years ago.

Regards,

Steve N.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 07:31:36 PM
Quote from: FORTRANS on March 21, 2011, 07:30:38 PM
Hi,

   I ran both with the same result.  And yes it was built about
ten years ago.

Regards,

Steve N.

No SMBIOS is the most likely answer then.
Title: Re: Computer Make and Model identifier
Post by: MichaelW on March 21, 2011, 08:18:45 PM
I get the same result on my ~11-year old Windows 2000 Pro system, and it definitely has an SMBIOS. Here is the output for an unfinished application that accesses the SMBIOS data:

SMBIOS version: 2.3
structure table length: 1392
structure table address: 000F1F30
structure table number of structures: 48

BCD revision: 00000023

Linear address: 007C1F30

SMB_BIOS_INFO structure address: 007C1F30
vendor: Award Software, Inc.
version: ASUS P3V4X ACPI BIOS Revision 1005
release date: 06/12/2000

SMB_TYPE_SYSTEM_INFO serial number SYS-1234567890

SMB_PROCESSOR_INFO structure address: 007C2077
socket: SLOT 1
type: PITYPE_CENTRAL
family: Pentium III processor
manufacturer: genuine intel


It's a Win32 application that uses WinIo to access memory. I abandoned it after I determined that the method does not work under Windows XP. Where under Windows 2000 WinIo can access the bottom 1MB, under Windows XP it can access only the bottom 4KB.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 21, 2011, 08:57:59 PM
Hi Michael,

I am not sure why WMI is unable to read the information but this was never a project for me personally so I didn't go too deeply into it, it was just a way to get the information without using the registry or oeminfo.ini file which can be modified by the user. I expect that you can use GetSystemFirmwareTable (http://msdn.microsoft.com/en-us/library/ms724379%28v=vs.85%29.aspx) for older SMBIOS versions though parsing the data might be difficult and I am not completely clear as to whether it can be used on newer versions of Windows outside of Kernel mode. This is the article I used from Ray Chen's blog when I was writing the snippet:

http://blogs.msdn.com/b/oldnewthing/archive/2008/12/18/9233149.aspx
Title: Re: Computer Make and Model identifier
Post by: FORTRANS on March 21, 2011, 09:20:59 PM
Hi,

   Given Michael's results, the wonders of Google, and DEBUG
I think I have a SMBIOS version 2.2.

Regards,

Steve N.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 21, 2011, 10:42:57 PM
Edgar,
I used your program on the server and three of the computers I replaced today (old and new)... seems to work fine on the new and old computers, but it didn't work on the server (there's a chance I have that backwards). I snapped a pic of it but forgot to put the bitmap on my thumbdrive before leaving the base, so I can't tell exactly what it's reading in. I suppose it could be possible that the 'computer in question' is too old as it's going to be replaced. I'll try to remember tomorrow to grab the bitmap (I caught a head cold and my mind is a little, ok a lot wondering this evening).

-Shooter
Title: Re: Computer Make and Model identifier
Post by: donkey on March 22, 2011, 01:44:10 AM
Quote from: FORTRANS on March 21, 2011, 09:20:59 PM
Hi,

   Given Michael's results, the wonders of Google, and DEBUG
I think I have a SMBIOS version 2.2.

Regards,

Steve N.

From what I have read support starts with SMBIOS version 2.4 (July 2004) and XP SP2.

http://msdn.microsoft.com/en-us/windows/hardware/gg463136

Quote from: From the attached file in the link aboveSystem identification using the Microsoft SMBIOS driver depends on specific features of SMBIOS. The requirements for system identification are:
·   System SMBIOS implementation must be Version 2.4 or greater.
Title: Re: Computer Make and Model identifier
Post by: FORTRANS on March 22, 2011, 12:25:22 PM
Hi,

   Well that would certainly explain that dull result of mine.

Thanks,

Steve
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 22, 2011, 09:29:42 PM
Edgar,
Correction... the set of computers it seemed not to work on WERE the new computers. I got "INTEL_" as the caption, and "D945GLF2", neither of which is very helpful considering I can't seem to find anything anywhere what "D945GLF2" means. Outside of that, it's a great tiny program.  :clap:

-Shooter
Title: Re: Computer Make and Model identifier
Post by: donkey on March 22, 2011, 10:25:28 PM
Intel D945GLF2 is the computers model number, should be on the back of the box, if not then its a custom build and they never updated the mobo's SMBIOS. In the end it would be the same as an Intel D945GLF2:

http://browse.geekbench.ca/geekbench2/view/91733
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 22, 2011, 10:38:33 PM
Quote from: donkey on March 22, 2011, 10:25:28 PM
Intel D945GLF2 is the computers model number, should be on the back of the box, if not then its a custom build and they never updated the mobo's SMBIOS. In the end it would be the same as an Intel D945GLF2:

http://browse.geekbench.ca/geekbench2/view/91733

How did you find that? I used several different search engines and not one of them came back with squat. However, that page doesn't say that it's a Dell computer, or even what model, but it's still cool that you found something on it.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 22, 2011, 11:18:52 PM
Quote from: Shooter on March 22, 2011, 10:38:33 PM
How did you find that? I used several different search engines and not one of them came back with squat.

http://www.google.ca/search?q=Intel+D945GLF2

1,700 results
Title: Re: Computer Make and Model identifier
Post by: donkey on March 23, 2011, 12:43:00 AM
There is an alternate way that at least under Win7 appears to work.

invoke GetSystemFirmwareTable,0x52534D42,0,0,0 // Setting buffer and size to zero returns the bytes needed
// Round up to 1K boundary
add rax,1023
and rax,-1024
mov rbx,rax
invoke GlobalAlloc,GMEM_FIXED,rbx
mov [pSMB_Buffer],rax

invoke GetSystemFirmwareTable,0x52534D42,0,[pSMB_Buffer],ebx


This is what I've figured out so far (mostly guesses)

0059CA38:  00 02 05 25-E8 05 00 00-00 18 00 00-01 02 00 E0   ...%è..........à
0059CA48:  03 1F 90 9E-CB 7F 00 00-00 00 33 07-01 00 FF FF   ..?žË....3...ÿÿ
0059CA58:  44 65 6C 6C-20 49 6E 63-2E 00 31 2E-30 2E 31 31   Dell Inc..1.0.11
0059CA68:  00 30 31 2F-33 31 2F 32-30 30 38 00-00 01 1B 01   .01/31/2008.....
0059CA78:  00 01 02 03-04 44 45 4C-4C 44 00 10-46 80 35 B8   .....DELLD..F€5¸
0059CA88:  C0 4F 59 46-31 06 05 06-44 65 6C 6C-20 49 6E 63   ÀOYF1...Dell Inc


Byte 1 = 0 ???
Byte 2&3 = SMBIOS 2.5
Byte 4 = ??? DMI revision (according to docs)
dword = Size of data
Byte 9 = 0 ???
Byte 10 = offset to start of data starting from Byte 9


That would put the first field at the string "Dell Inc." which is the first in the spec followed by BIOS revision and release date.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 23, 2011, 01:05:28 AM
Quote from: donkey on March 22, 2011, 11:18:52 PM
http://www.google.ca/search?q=Intel+D945GLF2

1,700 results

I only googled the "D945GLF2" and it didn't come up with anything before, but with the "INTEL_" I got about 1700 hits. Strange.
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 23, 2011, 01:06:44 AM
Quote from: donkey on March 23, 2011, 12:43:00 AM
There is an alternate way that at least under Win7 appears to work.

invoke GetSystemFirmwareTable,0x52534D42,0,0,0 // Setting buffer and size to zero returns the bytes needed
// Round up to 1K boundary
add rax,1023
and rax,-1024
mov rbx,rax
invoke GlobalAlloc,GMEM_FIXED,rbx
mov [pSMB_Buffer],rax

invoke GetSystemFirmwareTable,0x52534D42,0,[pSMB_Buffer],ebx


This is what I've figured out so far (mostly guesses)

0059CA38:  00 02 05 25-E8 05 00 00-00 18 00 00-01 02 00 E0   ...%è..........à
0059CA48:  03 1F 90 9E-CB 7F 00 00-00 00 33 07-01 00 FF FF   ..?žË....3...ÿÿ
0059CA58:  44 65 6C 6C-20 49 6E 63-2E 00 31 2E-30 2E 31 31   Dell Inc..1.0.11
0059CA68:  00 30 31 2F-33 31 2F 32-30 30 38 00-00 01 1B 01   .01/31/2008.....
0059CA78:  00 01 02 03-04 44 45 4C-4C 44 00 10-46 80 35 B8   .....DELLD..F€5¸
0059CA88:  C0 4F 59 46-31 06 05 06-44 65 6C 6C-20 49 6E 63   ÀOYF1...Dell Inc


Byte 1 = 0 ???
Byte 2&3 = SMBIOS 2.5
Byte 4 = ??? DMI revision (according to docs)
dword = Size of data
Byte 9 = 0 ???
Byte 10 = offset to start of data starting from Byte 9


That would put the first field at the string "Dell Inc." which is the first in the spec followed by BIOS revision and release date.


I was wondering if I could 'peek' into the BIOS and read it that way, but I wasn't sure A) If that was always possible, and B) If every computer placed the mfg data in the exact same location.
Title: Re: Computer Make and Model identifier
Post by: donkey on March 23, 2011, 01:12:31 AM
Quote from: Shooter on March 23, 2011, 01:06:44 AM
I was wondering if I could 'peek' into the BIOS and read it that way, but I wasn't sure A) If that was always possible, and B) If every computer placed the mfg data in the exact same location.

A) As you can see yes, you can, though the header is altered the data is consistent with the raw SMBIOS data
B) Yes, the structure of the SMBIOS has to be the same, otherwise the OS vendors would have to write thousands of special case handlers. However the structure contains inline variable length string data so its not just a simple offset, you have to parse the data to find what you want.. The white papers for the standards are found at http://dmtf.org/standards/smbios
Title: Re: Computer Make and Model identifier
Post by: MichaelW on March 23, 2011, 03:53:41 AM
The attachment contains what I have. Note that the EXE will not work under Windows XP, or probably any later version. To run the EXE under Windows 2000 you will need WinIo.dll and WinIo.sys, available from the Internals web site, link in the post here:

http://www.masm32.com/board/index.php?topic=3894.0

Title: Re: Computer Make and Model identifier
Post by: lingo on March 26, 2011, 07:02:59 PM
"Since my program is dependent on the model I guess I'm gonna have to go the long route.  I've never dealt directly with a class like that before, so I guess I might be callin' on some help in the future on this one, particularly in converting it to MASM code." by Shooter

Shooter,
I rewrote it in MASM and now it is easier to use... :wink
Pls, download and use WMI Code Creator v1.0 too, from link (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2cc30a64-ea15-4661-8da4-55bbc145c30e&displaylang=en)...
Title: Re: Computer Make and Model identifier
Post by: Shooter on March 27, 2011, 01:40:17 PM
Quote from: lingo on March 26, 2011, 07:02:59 PM
I rewrote it in MASM and now it is easier to use... :wink
Pls, download and use WMI Code Creator v1.0 too, from link (http://www.microsoft.com/downloads/en/details.aspx?FamilyID=2cc30a64-ea15-4661-8da4-55bbc145c30e&displaylang=en)...

Lingo,
I'm a little confused... are you saying that your code will convert the WMI Code Creator v1.0's output to MASM, or did I misunderstand something there?

-Shooter

(By the way, NICE little program there, the WMI Code Creator.)
Title: Re: Computer Make and Model identifier
Post by: donkey on March 27, 2011, 02:16:17 PM
Quote from: Shooter on March 27, 2011, 01:40:17 PM
Lingo,
I'm a little confused... are you saying that your code will convert the WMI Code Creator v1.0's output to MASM, or did I misunderstand something there?

-Shooter

You use the Code Creator to get the sever name and namespace then copy and paste them into his source and re-assemble, it does not convert any code, that much is evident in the source he attached.