{"id":2163,"date":"2014-01-06T07:00:00","date_gmt":"2014-01-06T07:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2014\/01\/06\/how-do-i-obtain-the-computer-manufacturers-name-via-c\/"},"modified":"2014-01-06T07:00:00","modified_gmt":"2014-01-06T07:00:00","slug":"how-do-i-obtain-the-computer-manufacturers-name-via-c","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20140106-00\/?p=2163","title":{"rendered":"How do I obtain the computer manufacturer&#039;s name via C++?"},"content":{"rendered":"<p>\nThe way to get the computer manufacturer and other information\nis to\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2008\/12\/18\/9233149.aspx\">\nask WMI<\/a>.\nWMI is much easier to use via scripting, but maybe you want to do it\nfrom C++.\nFortunately,\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa389762(v=vs.85).aspx\">\nMSDN takes you through it step by step<\/a>\nand even puts it together into\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa390418(v=vs.85).aspx\">\na sample program<\/a>.\n<\/p>\n<p>\nBut I&#8217;m going to write the code myself anyway.\n<\/p>\n<p>\nToday&#8217;s Little Program extracts the computer name,\nmanufacturer, and model from WMI.\nRemember that Little Programs do little or no error checking.\n<\/p>\n<p>\nAnd the smart pointer library we&#8217;ll use is\n(rolls dice) <code>_com_ptr_t<\/code>!\n<\/p>\n<pre>\n#include &lt;windows.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;ole2.h&gt;\n#include &lt;oleauto.h&gt;\n#include &lt;wbemidl.h&gt;\n#include &lt;comdef.h&gt;\n_COM_SMARTPTR_TYPEDEF(IWbemLocator, __uuidof(IWbemLocator));\n_COM_SMARTPTR_TYPEDEF(IWbemServices, __uuidof(IWbemServices));\n_COM_SMARTPTR_TYPEDEF(IWbemClassObject, __uuidof(IWbemClassObject));\n_COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, __uuidof(IEnumWbemClassObject));\n\/\/ <a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2004\/05\/20\/135841.aspx\">CCoInitialize class incorporated by reference<\/a>\n<\/pre>\n<p>\nThose include files and macros set things up so we can use\n<code>_com_ptr_t<\/code> to access WBEM interfaces.\n<\/p>\n<pre>\n_bstr_t GetProperty(IWbemClassObject *pobj, PCWSTR pszProperty)\n{\n  _variant_t var;\n  pobj-&gt;Get(pszProperty, 0, &amp;var, nullptr, nullptr);\n  return var;\n}\nvoid PrintProperty(IWbemClassObject *pobj, PCWSTR pszProperty)\n{\n printf(\"%ls = %ls\\n\", pszProperty,\n  static_cast&lt;PWSTR&gt;(GetProperty(pobj, pszProperty)));\n}\n<\/pre>\n<p>\nThe first helper function retrieves a string property from a WBEM object.\nThe second one prints it.\n(Exercise: Why do we need the <code>static_cast<\/code>?)\n<\/p>\n<pre>\nint __cdecl main(int, char**)\n{\n CCoInitialize init;\n IWbemLocatorPtr spLocator;\n CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_ALL,\n  IID_PPV_ARGS(&amp;spLocator));\n IWbemServicesPtr spServices;\n spLocator-&gt;ConnectServer(_bstr_t(L\"root\\\\cimv2\"),\n  nullptr, nullptr, 0, 0, nullptr, nullptr, &amp;spServices);\n CoSetProxyBlanket(spServices, RPC_C_AUTHN_DEFAULT,\n  RPC_C_AUTHZ_DEFAULT, COLE_DEFAULT_PRINCIPAL,\n  RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,\n  0, EOAC_NONE);\n IEnumWbemClassObjectPtr spEnum;\n spServices-&gt;ExecQuery(_bstr_t(L\"WQL\"),\n  _bstr_t(L\"select * from Win32_ComputerSystem\"),\n   WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,\n   nullptr, &amp;spEnum);\n IWbemClassObjectPtr spObject;\n ULONG cActual;\n while (spEnum-&gt;Next(WBEM_INFINITE, 1, &amp;spObject, &amp;cActual)\n                                    == WBEM_S_NO_ERROR) {\n  PrintProperty(spObject, L\"Name\");\n  PrintProperty(spObject, L\"Manufacturer\");\n  PrintProperty(spObject, L\"Model\");\n }\n return 0;\n}\n<\/pre>\n<p>\nAnd here is the actual guts of the program.\n<\/p>\n<p>\nWe initialize COM but we\ndo not call\n<code>Co&shy;Initialize&shy;Security<\/code>\nbecause\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa390885(v=vs.85).aspx\">\nthe checklist notes that<\/a>\nthe call sets the default security for the entire process,\nwhich would be\n<a HREF=\"http:\/\/blogs.msdn.com\/b\/oldnewthing\/archive\/2009\/12\/02\/9931183.aspx\">\na global solution to a local problem<\/a>.\nNow, in this case, we are in control of the process,\nbut I&#8217;m doing it this way because I know people are going to\ncopy\/paste the code (hopefully after adding some error checking),\nand the local solution is more appropriate in the general case.\n<\/p>\n<p>\nThe next step in the cookbook is\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa389749(v=vs.85).aspx\">\ncreating a connection to a WMI namespace<\/a>.\nWe create a <code>WbemLocator<\/code> and connect it to the desired\nnamespace.\n<\/p>\n<p>\nStep three in the cookbook is\n<a HREF=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/aa393619(v=vs.85).aspx\">\nsetting the security context on the interface<\/a>,\nwhich is done with the amusingly-named function\n<code>Co&shy;Set&shy;Proxy&shy;Blanket<\/code>.\n<\/p>\n<p>\nOnce we have a connection to the server,\nwe can ask it for all (<code>*<\/code>) the\ninformation from <code>Win32_Computer&shy;System<\/code>.\n<\/p>\n<p>\nWe know that there is only one computer in the query,\nbut I&#8217;m going to write a loop anyway,\nbecause somebody who copies this code may issue a query that\ncontains multiple results.\n<\/p>\n<p>\nFor each object, we print its Name, Manufacturer, and Model.\n<\/p>\n<p>\nAnd that&#8217;s it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The way to get the computer manufacturer and other information is to ask WMI. WMI is much easier to use via scripting, but maybe you want to do it from C++. Fortunately, MSDN takes you through it step by step and even puts it together into a sample program. But I&#8217;m going to write the [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-2163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The way to get the computer manufacturer and other information is to ask WMI. WMI is much easier to use via scripting, but maybe you want to do it from C++. Fortunately, MSDN takes you through it step by step and even puts it together into a sample program. But I&#8217;m going to write the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=2163"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/2163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=2163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=2163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=2163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}