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
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.
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'. :'(
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.
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. :(
For HP Computers, there are a number of registry entries that contain the make and model.
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.
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.
Forgot to attach the project, here it is with source and executable:
Edgar,
It identifies my Intel board fine.
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.
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
Mine says "To Be Filled By O.E.M." :lol
To be fair, I think the BIOS setup tells me the same.
mine reports "VGC-RB42G" which is correct however, you'd have to know that was a Sony model number
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.
mine says nothing (see the picture).
My mobo is Asus P8P67 Pro.
my bad Edgar :lol
i didn't notice that it says "Sony Corporation" in the title bar
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.
<post removed>
Hi donkey,
Your code works fine on my Intel board.
Hi,
Screenshot of result. Not sure if that's what you wouls expect
from Windows 2000
Regards,
Steve
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.
Hi,
I ran both with the same result. And yes it was built about
ten years ago.
Regards,
Steve N.
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.
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.
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
Hi,
Given Michael's results, the wonders of Google, and DEBUG
I think I have a SMBIOS version 2.2.
Regards,
Steve N.
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
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.
Hi,
Well that would certainly explain that dull result of mine.
Thanks,
Steve
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
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
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.
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
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.
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.
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.
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
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
"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)...
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.)
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.