Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2344 lines
68 KiB

  1. // *********************************************************************************
  2. //
  3. // Copyright (c) Microsoft Corporation
  4. //
  5. // Module Name:
  6. //
  7. // SystemInfo.cpp
  8. //
  9. // Abstract:
  10. //
  11. // This module displays the system information of local / remote system.
  12. //
  13. // Author:
  14. //
  15. // Sunil G.V.N. Murali ([email protected]) 27-Dec-2000
  16. //
  17. // Revision History:
  18. //
  19. // Sunil G.V.N. Murali ([email protected]) 27-Dec-2000 : Created It.
  20. //
  21. // *********************************************************************************
  22. #include "pch.h"
  23. #include "wmi.h"
  24. #include "SystemInfo.h"
  25. //
  26. // private function prototype(s)
  27. //
  28. BOOL TranslateLocaleCode( CHString& strLocale );
  29. BOOL FormatNumber( LPCWSTR strValue, CHString& strFmtValue );
  30. BOOL FormatNumberEx( LPCWSTR pwszValue, CHString& strFmtValue );
  31. VOID PrintProgressMsg( HANDLE hOutput, LPCWSTR pwszMsg, const CONSOLE_SCREEN_BUFFER_INFO& csbi );
  32. DWORD __cdecl
  33. wmain(
  34. IN DWORD argc,
  35. IN LPCTSTR argv[]
  36. )
  37. /*++
  38. // Routine Description:
  39. // This the entry point to this utility.
  40. //
  41. // Arguments:
  42. // [ in ] argc : argument(s) count specified at the command prompt
  43. // [ in ] argv : argument(s) specified at the command prompt
  44. //
  45. // Return Value:
  46. // The below are actually not return values but are the exit values
  47. // returned to the OS by this application
  48. // 0 : utility is successfull
  49. // 1 : utility failed
  50. --*/
  51. {
  52. // local variables
  53. CSystemInfo sysinfo;
  54. BOOL bResult = FALSE;
  55. // initialize the systeminfo utility
  56. if ( sysinfo.Initialize() == FALSE )
  57. {
  58. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  59. EXIT_PROCESS( 1 );
  60. }
  61. // now do parse the command line options
  62. if ( sysinfo.ProcessOptions( argc, argv ) == FALSE )
  63. {
  64. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  65. EXIT_PROCESS( 1 );
  66. }
  67. // check whether usage has to be displayed or not
  68. if ( sysinfo.m_bUsage == TRUE )
  69. {
  70. // show the usage of the utility
  71. sysinfo.ShowUsage();
  72. // quit from the utility
  73. EXIT_PROCESS( 0 );
  74. }
  75. // connect to the WMI
  76. bResult = sysinfo.Connect();
  77. if ( bResult == FALSE )
  78. {
  79. // show the error message
  80. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  81. EXIT_PROCESS( 1 );
  82. }
  83. // load the data
  84. if ( sysinfo.LoadData() == FALSE )
  85. {
  86. // show the error message
  87. ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
  88. EXIT_PROCESS( 1 );
  89. }
  90. #ifdef _FAST_LIST
  91. // NOTE: for list for output will be shown while loading itself.
  92. // so show the output incase of table and csv formats only
  93. if ( (sysinfo.m_dwFormat & SR_FORMAT_MASK) != SR_FORMAT_LIST )
  94. #endif
  95. // show the system configuration information
  96. sysinfo.ShowOutput();
  97. // exit from the program
  98. EXIT_PROCESS( 0 );
  99. }
  100. BOOL
  101. CSystemInfo::Connect()
  102. /*++
  103. // Routine Description:
  104. // Connects to WMI
  105. //
  106. // Arguments:
  107. // None
  108. //
  109. // Return Value:
  110. // TRUE on success
  111. // FALSE oni failure
  112. --*/
  113. {
  114. // local variables
  115. BOOL bResult = FALSE;
  116. BOOL bLocalSystem = FALSE;
  117. // connect to WMI
  118. bResult = ConnectWmiEx( m_pWbemLocator,
  119. &m_pWbemServices, m_strServer, m_strUserName, m_strPassword,
  120. &m_pAuthIdentity, m_bNeedPassword, WMI_NAMESPACE_CIMV2, &bLocalSystem );
  121. // check the result of connection
  122. if ( bResult == FALSE )
  123. {
  124. return FALSE;
  125. }
  126. // check the local credentials and if need display warning
  127. if ( GetLastError() == WBEM_E_LOCAL_CREDENTIALS )
  128. {
  129. WMISaveError( WBEM_E_LOCAL_CREDENTIALS );
  130. ShowLastErrorEx( stderr, SLE_TYPE_WARNING | SLE_INTERNAL );
  131. // get the new screen co-ordinates
  132. if ( m_hOutput != NULL )
  133. {
  134. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  135. }
  136. }
  137. // check the remote system version and its compatiblity
  138. if ( bLocalSystem == FALSE )
  139. {
  140. DWORD dwVersion = 0;
  141. dwVersion = GetTargetVersionEx( m_pWbemServices, m_pAuthIdentity );
  142. if ( IsCompatibleOperatingSystem( dwVersion ) == FALSE )
  143. {
  144. SetReason( ERROR_REMOTE_INCOMPATIBLE );
  145. return FALSE;
  146. }
  147. }
  148. // return the result
  149. return bResult;
  150. }
  151. BOOL
  152. CSystemInfo::LoadData()
  153. /*++
  154. // Routine Description:
  155. // Loads the system data
  156. //
  157. // Arguments:
  158. //
  159. // Return Value:
  160. // FALSE on failure
  161. // TRUE on success
  162. //
  163. --*/
  164. {
  165. // local variables
  166. BOOL bResult = FALSE;
  167. //
  168. // load os information
  169. bResult = LoadOSInfo();
  170. if ( bResult == FALSE )
  171. {
  172. return FALSE;
  173. }
  174. #ifdef _FAST_LIST
  175. // ***********************************************
  176. // show the paritial output .. only in list format
  177. // ***********************************************
  178. // Columns Shown here:
  179. // Host Name, OS Name, OS Version, OS Manufacturer
  180. // ***********************************************
  181. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  182. {
  183. // erase the last status message
  184. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  185. ShowOutput( CI_HOSTNAME, CI_OS_MANUFACTURER );
  186. if ( m_hOutput != NULL )
  187. {
  188. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  189. }
  190. }
  191. #endif
  192. //
  193. // load computer information
  194. bResult = LoadComputerInfo();
  195. if ( bResult == FALSE )
  196. {
  197. return FALSE;
  198. }
  199. #ifdef _FAST_LIST
  200. // ***********************************************
  201. // show the paritial output .. only in list format
  202. // ***********************************************
  203. // Columns Shown here:
  204. // OS Configuration, OS Build Type, Registered Owner,
  205. // Registered Organization, Product ID, Original Install Date
  206. // ***********************************************
  207. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  208. {
  209. // erase the last status message
  210. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  211. ShowOutput( CI_OS_CONFIG, CI_INSTALL_DATE );
  212. if ( m_hOutput != NULL )
  213. {
  214. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  215. }
  216. }
  217. #endif
  218. //
  219. // load systemuptime information from perf data
  220. bResult = LoadPerformanceInfo();
  221. if ( bResult == FALSE )
  222. {
  223. // return FALSE;
  224. }
  225. #ifdef _FAST_LIST
  226. // ***********************************************
  227. // show the paritial output .. only in list format
  228. // ***********************************************
  229. // Columns Shown here:
  230. // System Up Time, System Manufacturer, System Model, System type
  231. // ***********************************************
  232. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  233. {
  234. // erase the last status message
  235. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  236. ShowOutput( CI_SYSTEM_UPTIME, CI_SYSTEM_TYPE );
  237. if ( m_hOutput != NULL )
  238. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  239. }
  240. #endif
  241. //
  242. // load processor information
  243. bResult = LoadProcessorInfo();
  244. if ( bResult == FALSE )
  245. {
  246. return FALSE;
  247. }
  248. #ifdef _FAST_LIST
  249. // ***********************************************
  250. // show the paritial output .. only in list format
  251. // ***********************************************
  252. // Columns Shown here:
  253. // Processor(s)
  254. // ***********************************************
  255. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  256. {
  257. // erase the last status message
  258. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  259. ShowOutput( CI_PROCESSOR, CI_PROCESSOR );
  260. if ( m_hOutput != NULL )
  261. {
  262. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  263. }
  264. }
  265. #endif
  266. //
  267. // load bios information
  268. bResult = LoadBiosInfo();
  269. if ( bResult == FALSE )
  270. {
  271. return FALSE;
  272. }
  273. #ifdef _FAST_LIST
  274. // ***********************************************
  275. // show the paritial output .. only in list format
  276. // ***********************************************
  277. // Columns Shown here:
  278. // BIOS Version, Windows Directory, System Directory, Boot Device, System Locale
  279. // ***********************************************
  280. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  281. {
  282. // erase the last status message
  283. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  284. ShowOutput( CI_BIOS_VERSION, CI_SYSTEM_LOCALE );
  285. if ( m_hOutput != NULL )
  286. {
  287. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  288. }
  289. }
  290. #endif
  291. //
  292. // load input locale information from keyboard class
  293. bResult = LoadKeyboardInfo();
  294. if ( bResult == FALSE )
  295. {
  296. return FALSE;
  297. }
  298. //
  299. // load timezone information
  300. bResult = LoadTimeZoneInfo();
  301. if ( bResult == FALSE )
  302. {
  303. return FALSE;
  304. }
  305. #ifdef _FAST_LIST
  306. // ***********************************************
  307. // show the paritial output .. only in list format
  308. // ***********************************************
  309. // Columns Shown here:
  310. // Input Locale, Time Zone, Total Physical Memory, Available Physical Memory,
  311. // Virtual Memory: Max Size, Virtual Memory: Available, Virtual Memory: In Use
  312. // ***********************************************
  313. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  314. {
  315. // erase the last status message
  316. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  317. ShowOutput( CI_INPUT_LOCALE, CI_VIRTUAL_MEMORY_INUSE );
  318. if ( m_hOutput != NULL )
  319. {
  320. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  321. }
  322. }
  323. #endif
  324. // load the logon server information
  325. bResult = LoadProfileInfo();
  326. if ( bResult == FALSE )
  327. {
  328. return FALSE;
  329. }
  330. //
  331. // load pagefile information
  332. bResult = LoadPageFileInfo();
  333. if ( bResult == FALSE )
  334. {
  335. return FALSE;
  336. }
  337. //
  338. // load hotfix information from quick fix engineering class
  339. bResult = LoadHotfixInfo();
  340. if ( bResult == FALSE )
  341. {
  342. return FALSE;
  343. }
  344. //
  345. // load n/w card information from network adapter class
  346. bResult = LoadNetworkCardInfo();
  347. if ( bResult == FALSE )
  348. {
  349. return FALSE;
  350. }
  351. #ifdef _FAST_LIST
  352. // ***********************************************
  353. // show the paritial output .. only in list format
  354. // ***********************************************
  355. // Columns Shown here:
  356. // Page File Location(s), Domain, Logon Server, Hotfix(s), NetWork Card(s)
  357. // ***********************************************
  358. if ( (m_dwFormat & SR_FORMAT_MASK) == SR_FORMAT_LIST )
  359. {
  360. // erase the last status message
  361. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  362. ShowOutput( CI_PAGEFILE_LOCATION, CI_NETWORK_CARD );
  363. if ( m_hOutput != NULL )
  364. {
  365. GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
  366. }
  367. }
  368. #endif
  369. // erase the last status message
  370. PrintProgressMsg( m_hOutput, NULL, m_csbi );
  371. // return
  372. return TRUE;
  373. }
  374. BOOL
  375. CSystemInfo::LoadOSInfo()
  376. /*++
  377. // Routine Description:
  378. // Loads OS information
  379. //
  380. // Arguments: None
  381. //
  382. // Return Value:
  383. // TRUE on success
  384. // FALSE on failure
  385. --*/
  386. {
  387. // local variables
  388. HRESULT hr;
  389. ULONG ulReturned = 0;
  390. CHString strInstallDate;
  391. CHString strVirtualMemoryInUse; // totalvirtualmemorysize - freevirtualmemory
  392. IWbemClassObject* pWbemObject = NULL;
  393. IEnumWbemClassObject* pWbemEnum = NULL;
  394. // property values
  395. CHString strHostName; // csname
  396. CHString strName; // caption
  397. CHString strVersion; // version
  398. CHString strServicePack; // csdversion
  399. CHString strBuildNumber; // buildnumber
  400. CHString strManufacturer; // manufacturer
  401. CHString strBuildType; // buildtype
  402. CHString strOwner; // registereduser
  403. CHString strOrganization; // organization
  404. CHString strSerialNumber; // serialnumber
  405. CHString strWindowsDir; // windowsdirectory
  406. CHString strSystemDir; // systemdirectory
  407. CHString strBootDevice; // bootdevice
  408. CHString strFreePhysicalMemory; // freephysicalmemory
  409. CHString strTotalVirtualMemory; // totalvirtualmemorysize
  410. CHString strFreeVirtualMemory; // freevirtualmemory
  411. CHString strLocale; // locale
  412. SYSTEMTIME systimeInstallDate; // installdate
  413. // display the status message
  414. PrintProgressMsg( m_hOutput, MSG_OSINFO, m_csbi );
  415. try
  416. {
  417. // enumerate the instances of Win32_OperatingSystem class
  418. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_OPERATINGSYSTEM ),
  419. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  420. // check the result of enumeration
  421. if ( FAILED( hr ) )
  422. {
  423. WMISaveError( hr );
  424. return FALSE;
  425. }
  426. }
  427. catch( _com_error& e )
  428. {
  429. WMISaveError( e );
  430. return FALSE;
  431. }
  432. // set the security on the obtained interface
  433. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  434. if ( FAILED( hr ) )
  435. {
  436. WMISaveError( hr );
  437. SAFE_RELEASE( pWbemEnum );
  438. return FALSE;
  439. }
  440. // get the enumerated objects information
  441. // NOTE: This needs to be traversed only one time.
  442. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  443. if ( FAILED( hr ) )
  444. {
  445. // some error has occured ... oooppps
  446. WMISaveError( hr );
  447. SAFE_RELEASE( pWbemEnum );
  448. return FALSE;
  449. }
  450. // get the propert information
  451. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_CAPTION, strName );
  452. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_CSNAME, strHostName );
  453. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_VERSION, strVersion );
  454. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_CSDVERSION, strServicePack );
  455. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_BUILDNUMBER, strBuildNumber );
  456. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_MANUFACTURER, strManufacturer );
  457. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_BUILDTYPE, strBuildType );
  458. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_REGUSER, strOwner );
  459. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_ORGANIZATION, strOrganization );
  460. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_SERIALNUMBER, strSerialNumber );
  461. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_WINDOWSDIR, strWindowsDir );
  462. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_SYSTEMDIR, strSystemDir );
  463. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_BOOTDEVICE, strBootDevice );
  464. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_LOCALE, strLocale );
  465. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_FREEPHYSICALMEMORY, strFreePhysicalMemory );
  466. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_TOTALVIRTUALMEMORY, strTotalVirtualMemory );
  467. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_FREEVIRTUALMEMORY, strFreeVirtualMemory );
  468. PropertyGet( pWbemObject, WIN32_OPERATINGSYSTEM_P_INSTALLDATE, systimeInstallDate );
  469. // relase the interfaces
  470. SAFE_RELEASE( pWbemEnum );
  471. SAFE_RELEASE( pWbemObject );
  472. //
  473. // do the needed formatting the information obtained
  474. //
  475. // convert the system locale into appropriate code
  476. TranslateLocaleCode( strLocale );
  477. //
  478. // format the version info
  479. try
  480. {
  481. // sub-local variable
  482. CHString str;
  483. // attach the service pack info
  484. str = strVersion;
  485. if ( strServicePack.IsEmpty() == FALSE )
  486. {
  487. str.Format( L"%s %s", strVersion, strServicePack );
  488. }
  489. // attach the build number
  490. strVersion.Format( FMT_OSVERSION, str, strBuildNumber );
  491. }
  492. catch( ... )
  493. {
  494. SetLastError((DWORD) E_OUTOFMEMORY );
  495. SaveLastError();
  496. return FALSE;
  497. }
  498. //
  499. // get the formatted date and time
  500. {
  501. // sub-local variables
  502. LCID lcid;
  503. CHString strTime;
  504. CHString strDate;
  505. BOOL bLocaleChanged = FALSE;
  506. // verify whether console supports the current locale 100% or not
  507. lcid = GetSupportedUserLocale( &bLocaleChanged );
  508. // get the formatted date
  509. try
  510. {
  511. // get the size of buffer that is needed
  512. DWORD dwCount = 0;
  513. dwCount = GetDateFormat( lcid, 0, &systimeInstallDate,
  514. ((bLocaleChanged == TRUE) ? L"MM/dd/yyyy" : NULL), NULL, 0 );
  515. // get the required buffer
  516. LPWSTR pwszTemp = NULL;
  517. pwszTemp = strDate.GetBufferSetLength( dwCount + 1 );
  518. // now format the date
  519. GetDateFormat( lcid, 0, &systimeInstallDate,
  520. ((bLocaleChanged == TRUE) ? L"MM/dd/yyyy" : NULL), pwszTemp, dwCount );
  521. // release the buffer
  522. strDate.ReleaseBuffer();
  523. }
  524. catch( ... )
  525. {
  526. SetLastError( (DWORD)E_OUTOFMEMORY );
  527. SaveLastError();
  528. return FALSE;
  529. }
  530. // get the formatted time
  531. try
  532. {
  533. // get the size of buffer that is needed
  534. DWORD dwCount = 0;
  535. dwCount = GetTimeFormat( LOCALE_USER_DEFAULT, 0, &systimeInstallDate,
  536. ((bLocaleChanged == TRUE) ? L"HH:mm:ss" : NULL), NULL, 0 );
  537. // get the required buffer
  538. LPWSTR pwszTemp = NULL;
  539. pwszTemp = strTime.GetBufferSetLength( dwCount + 1 );
  540. // now format the date
  541. GetTimeFormat( LOCALE_USER_DEFAULT, 0, &systimeInstallDate,
  542. ((bLocaleChanged == TRUE) ? L"HH:mm:ss" : NULL), pwszTemp, dwCount );
  543. // release the buffer
  544. strTime.ReleaseBuffer();
  545. }
  546. catch( ... )
  547. {
  548. SetLastError( (DWORD)E_OUTOFMEMORY );
  549. SaveLastError();
  550. return FALSE;
  551. }
  552. // prepare the
  553. try
  554. {
  555. // prepare the datetime
  556. strInstallDate.Format( L"%s, %s", strDate, strTime );
  557. }
  558. catch( ... )
  559. {
  560. SetLastError( (DWORD)E_OUTOFMEMORY );
  561. SaveLastError();
  562. return FALSE;
  563. }
  564. }
  565. // format the numeric data
  566. try
  567. {
  568. // sub-local variables
  569. CHString str;
  570. WCHAR wszBuffer[ 33 ] = L"\0";
  571. //
  572. // first determine the virtual memory in use
  573. ULONGLONG ullAvailablePhysicalMemory = 0;
  574. ULONGLONG ullTotal = 0;
  575. ULONGLONG ullFree = 0;
  576. ULONGLONG ullInUse = 0;
  577. ullFree = (ULONGLONG) ( ((( float ) _wtoi64( strFreeVirtualMemory )) / 1024.0f) + 0.5f );
  578. ullTotal = (ULONGLONG) ( ((( float ) _wtoi64( strTotalVirtualMemory )) / 1024.0f) + 0.5f );
  579. ullAvailablePhysicalMemory = (ULONGLONG) ( ((( float ) _wtoi64( strFreePhysicalMemory )) / 1024.0f) + 0.5f );
  580. ullInUse = ullTotal - ullFree;
  581. //
  582. // format the virtual memory in use
  583. _ui64tow( ullInUse, wszBuffer, 10 ); // convert the ulonglong value into string
  584. if ( FormatNumberEx( wszBuffer, str ) == FALSE )
  585. {
  586. return FALSE;
  587. }
  588. // ...
  589. strVirtualMemoryInUse.Format( FMT_MEGABYTES, str );
  590. //
  591. // format the available physical memory
  592. _ui64tow( ullAvailablePhysicalMemory, wszBuffer, 10 ); // convert the ulonglong value into string
  593. if ( FormatNumberEx( wszBuffer, str ) == FALSE )
  594. return FALSE;
  595. // ...
  596. strFreePhysicalMemory.Format( FMT_MEGABYTES, str );
  597. //
  598. // format the virtual memory max.
  599. _ui64tow( ullTotal, wszBuffer, 10 ); // convert the ulonglong value into string
  600. if ( FormatNumberEx( wszBuffer, str ) == FALSE )
  601. return FALSE;
  602. // ...
  603. strTotalVirtualMemory.Format( FMT_MEGABYTES, str );
  604. //
  605. // format the virtual memory free
  606. _ui64tow( ullFree, wszBuffer, 10 ); // convert the ulonglong value into string
  607. if ( FormatNumberEx( wszBuffer, str ) == FALSE )
  608. {
  609. return FALSE;
  610. }
  611. // ...
  612. strFreeVirtualMemory.Format( FMT_MEGABYTES, str );
  613. }
  614. catch( ... )
  615. {
  616. SetLastError( (DWORD)E_OUTOFMEMORY );
  617. SaveLastError();
  618. return FALSE;
  619. }
  620. //
  621. // save the info in dynamic array
  622. DynArraySetString2( m_arrData, 0, CI_HOSTNAME, strHostName, 0 );
  623. DynArraySetString2( m_arrData, 0, CI_OS_NAME, strName, 0 );
  624. DynArraySetString2( m_arrData, 0, CI_OS_VERSION, strVersion, 0 );
  625. DynArraySetString2( m_arrData, 0, CI_OS_MANUFACTURER, strManufacturer, 0 );
  626. DynArraySetString2( m_arrData, 0, CI_OS_BUILDTYPE, strBuildType, 0 );
  627. DynArraySetString2( m_arrData, 0, CI_REG_OWNER, strOwner, 0 );
  628. DynArraySetString2( m_arrData, 0, CI_REG_ORG, strOrganization, 0 );
  629. DynArraySetString2( m_arrData, 0, CI_PRODUCT_ID, strSerialNumber, 0 );
  630. DynArraySetString2( m_arrData, 0, CI_INSTALL_DATE, strInstallDate, 0 );
  631. DynArraySetString2( m_arrData, 0, CI_WINDOWS_DIRECTORY, strWindowsDir, 0 );
  632. DynArraySetString2( m_arrData, 0, CI_SYSTEM_DIRECTORY, strSystemDir, 0 );
  633. DynArraySetString2( m_arrData, 0, CI_BOOT_DEVICE, strBootDevice, 0 );
  634. DynArraySetString2( m_arrData, 0, CI_SYSTEM_LOCALE, strLocale, 0 );
  635. DynArraySetString2( m_arrData, 0, CI_AVAILABLE_PHYSICAL_MEMORY, strFreePhysicalMemory, 0 );
  636. DynArraySetString2( m_arrData, 0, CI_VIRTUAL_MEMORY_MAX, strTotalVirtualMemory, 0 );
  637. DynArraySetString2( m_arrData, 0, CI_VIRTUAL_MEMORY_AVAILABLE, strFreeVirtualMemory, 0 );
  638. DynArraySetString2( m_arrData, 0, CI_VIRTUAL_MEMORY_INUSE, strVirtualMemoryInUse, 0 );
  639. // return success
  640. return TRUE;
  641. }
  642. BOOL
  643. CSystemInfo::LoadComputerInfo()
  644. /*++
  645. // Routine Description:
  646. // Loads computer information
  647. //
  648. // Arguments:
  649. // None
  650. // Return Value:
  651. // FALSE on failure
  652. // TRUE on success
  653. //
  654. --*/
  655. {
  656. // local variables
  657. HRESULT hr;
  658. ULONG ulReturned = 0;
  659. CHString strDomainRole;
  660. CHString strTotalPhysicalMemory;
  661. IWbemClassObject* pWbemObject = NULL;
  662. IEnumWbemClassObject* pWbemEnum = NULL;
  663. // property values
  664. CHString strModel;
  665. DWORD dwDomainRole;
  666. CHString strDomain;
  667. CHString strSystemType;
  668. CHString strManufacturer;
  669. ULONGLONG ullTotalPhysicalMemory;
  670. // display the status message
  671. PrintProgressMsg( m_hOutput, MSG_COMPINFO, m_csbi );
  672. try
  673. {
  674. // enumerate the instances of Win32_ComputerSystem class
  675. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_COMPUTERSYSTEM ),
  676. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  677. // check the result of enumeration
  678. if ( FAILED( hr ) )
  679. {
  680. WMISaveError( hr );
  681. return FALSE;
  682. }
  683. }
  684. catch( _com_error& e )
  685. {
  686. WMISaveError( e );
  687. return FALSE;
  688. }
  689. // set the security on the obtained interface
  690. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  691. if ( FAILED( hr ) )
  692. {
  693. WMISaveError( hr );
  694. SAFE_RELEASE( pWbemEnum );
  695. return FALSE;
  696. }
  697. // get the enumerated objects information
  698. // NOTE: This needs to be traversed only one time.
  699. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  700. if ( FAILED( hr ) )
  701. {
  702. // some error has occured ... oooppps
  703. WMISaveError( hr );
  704. SAFE_RELEASE( pWbemEnum );
  705. return FALSE;
  706. }
  707. // get the propert information
  708. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_MODEL, strModel );
  709. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_DOMAIN, strDomain );
  710. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_USERNAME, m_strLogonUser );
  711. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_DOMAINROLE, dwDomainRole );
  712. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_SYSTEMTYPE, strSystemType );
  713. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_MANUFACTURER, strManufacturer );
  714. PropertyGet( pWbemObject, WIN32_COMPUTERSYSTEM_P_TOTALPHYSICALMEMORY, ullTotalPhysicalMemory );
  715. // relase the interfaces
  716. SAFE_RELEASE( pWbemEnum );
  717. SAFE_RELEASE( pWbemObject );
  718. //
  719. // do the needed formatting the information obtained
  720. //
  721. // convert the total physical memory from KB into MB
  722. try
  723. {
  724. // NOTE:
  725. // ----
  726. // The max. value of
  727. // (2 ^ 64) - 1 = "18,446,744,073,709,600,000 K" (29 chars).
  728. // = "18,014,398,509,482,031 M" (22 chars).
  729. //
  730. // so, the buffer size to store the number is fixed as 32 characters
  731. // which is more than the 29 characters in actuals
  732. // sub-local variables
  733. CHString str;
  734. WCHAR wszBuffer[ 33 ] = L"\0";
  735. // convert the value first ( take care of rounding )
  736. ullTotalPhysicalMemory =
  737. (ULONGLONG) (( ((float) ullTotalPhysicalMemory) / (1024.0f * 1024.0f)) + 0.5f);
  738. // now ULONGLONG to string
  739. _ui64tow( ullTotalPhysicalMemory, wszBuffer, 10 );
  740. // get the formatted number
  741. if ( FormatNumberEx( wszBuffer, str ) == FALSE )
  742. return FALSE;
  743. // ...
  744. strTotalPhysicalMemory.Format( FMT_MEGABYTES, str );
  745. }
  746. catch( ... )
  747. {
  748. SetLastError( (DWORD)E_OUTOFMEMORY );
  749. SaveLastError();
  750. return FALSE;
  751. }
  752. // map the domain role from numeric value to appropriate text value
  753. try
  754. {
  755. //
  756. // Mapping information of Win32_ComputerSystem's DomainRole property
  757. // NOTE: Refer to the _DSROLE_MACHINE_ROLE enumeration values in DsRole.h header file
  758. switch( dwDomainRole )
  759. {
  760. case DsRole_RoleStandaloneWorkstation:
  761. strDomainRole = VALUE_STANDALONEWORKSTATION;
  762. break;
  763. case DsRole_RoleMemberWorkstation:
  764. strDomainRole = VALUE_MEMBERWORKSTATION;
  765. break;
  766. case DsRole_RoleStandaloneServer:
  767. strDomainRole = VALUE_STANDALONESERVER;
  768. break;
  769. case DsRole_RoleMemberServer:
  770. strDomainRole = VALUE_MEMBERSERVER;
  771. break;
  772. case DsRole_RoleBackupDomainController:
  773. strDomainRole = VALUE_BACKUPDOMAINCONTROLLER;
  774. break;
  775. case DsRole_RolePrimaryDomainController:
  776. strDomainRole = VALUE_PRIMARYDOMAINCONTROLLER;
  777. break;
  778. }
  779. }
  780. catch( ... )
  781. {
  782. SetLastError( (DWORD)E_OUTOFMEMORY );
  783. SaveLastError();
  784. return FALSE;
  785. }
  786. //
  787. // save the info in dynamic array
  788. DynArraySetString2( m_arrData, 0, CI_DOMAIN, strDomain, 0 );
  789. DynArraySetString2( m_arrData, 0, CI_SYSTEM_MODEL, strModel, 0 );
  790. DynArraySetString2( m_arrData, 0, CI_OS_CONFIG, strDomainRole, 0 );
  791. DynArraySetString2( m_arrData, 0, CI_SYSTEM_TYPE, strSystemType, 0 );
  792. DynArraySetString2( m_arrData, 0, CI_SYSTEM_MANUFACTURER, strManufacturer, 0 );
  793. DynArraySetString2( m_arrData, 0, CI_TOTAL_PHYSICAL_MEMORY, strTotalPhysicalMemory, 0 );
  794. // return success
  795. return TRUE;
  796. }
  797. BOOL
  798. CSystemInfo::LoadBiosInfo()
  799. /*++
  800. // Routine Description:
  801. // Loads BIOS information
  802. //
  803. // Arguments:
  804. // None
  805. //
  806. // Return Value:
  807. // FALSE on failure
  808. // TRUE on success
  809. //
  810. --*/
  811. {
  812. // local variables
  813. HRESULT hr;
  814. ULONG ulReturned = 0;
  815. IWbemClassObject* pWbemObject = NULL;
  816. IEnumWbemClassObject* pWbemEnum = NULL;
  817. // property values
  818. CHString strVersion;
  819. // display the status message
  820. PrintProgressMsg( m_hOutput, MSG_BIOSINFO, m_csbi );
  821. try
  822. {
  823. // enumerate the instances of Win32_BIOS class
  824. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_BIOS ),
  825. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  826. // check the result of enumeration
  827. if ( FAILED( hr ) )
  828. {
  829. WMISaveError( hr );
  830. return FALSE;
  831. }
  832. }
  833. catch( _com_error& e )
  834. {
  835. WMISaveError( e );
  836. return FALSE;
  837. }
  838. // set the security on the obtained interface
  839. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  840. if ( FAILED( hr ) )
  841. {
  842. WMISaveError( hr );
  843. SAFE_RELEASE( pWbemEnum );
  844. return FALSE;
  845. }
  846. // get the enumerated objects information
  847. // NOTE: This needs to be traversed only one time.
  848. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  849. if ( FAILED( hr ) )
  850. {
  851. // some error has occured ... oooppps
  852. WMISaveError( hr );
  853. SAFE_RELEASE( pWbemEnum );
  854. return FALSE;
  855. }
  856. // get the propert information
  857. PropertyGet( pWbemObject, WIN32_BIOS_P_VERSION, strVersion );
  858. // relase the interfaces
  859. SAFE_RELEASE( pWbemEnum );
  860. SAFE_RELEASE( pWbemObject );
  861. //
  862. // save the info in dynamic array
  863. DynArraySetString2( m_arrData, 0, CI_BIOS_VERSION, strVersion, 0 );
  864. // return success
  865. return TRUE;
  866. }
  867. BOOL
  868. CSystemInfo::LoadTimeZoneInfo()
  869. /*++
  870. // Routine Description:
  871. // Loads time-zone information
  872. //
  873. // Arguments: None
  874. //
  875. // Return Value:
  876. // FALSE on failure
  877. // TRUE on success
  878. //
  879. --*/
  880. {
  881. // local variables
  882. HRESULT hr;
  883. ULONG ulReturned = 0;
  884. IWbemClassObject* pWbemObject = NULL;
  885. IEnumWbemClassObject* pWbemEnum = NULL;
  886. // property values
  887. CHString strCaption;
  888. // display the status message
  889. PrintProgressMsg( m_hOutput, MSG_TZINFO, m_csbi );
  890. try
  891. {
  892. // enumerate the instances of Win32_TimeZone class
  893. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_TIMEZONE ),
  894. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  895. // check the result of enumeration
  896. if ( FAILED( hr ) )
  897. {
  898. WMISaveError( hr );
  899. return FALSE;
  900. }
  901. }
  902. catch( _com_error& e )
  903. {
  904. WMISaveError( e );
  905. return FALSE;
  906. }
  907. // set the security on the obtained interface
  908. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  909. if ( FAILED( hr ) )
  910. {
  911. WMISaveError( hr );
  912. SAFE_RELEASE( pWbemEnum );
  913. return FALSE;
  914. }
  915. // get the enumerated objects information
  916. // NOTE: This needs to be traversed only one time.
  917. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  918. if ( FAILED( hr ) )
  919. {
  920. // some error has occured ... oooppps
  921. WMISaveError( hr );
  922. SAFE_RELEASE( pWbemEnum );
  923. return FALSE;
  924. }
  925. // get the propert information
  926. PropertyGet( pWbemObject, WIN32_TIMEZONE_P_CAPTION, strCaption );
  927. // relase the interfaces
  928. SAFE_RELEASE( pWbemEnum );
  929. SAFE_RELEASE( pWbemObject );
  930. //
  931. // save the info in dynamic array
  932. DynArraySetString2( m_arrData, 0, CI_TIME_ZONE, strCaption, 0 );
  933. // return success
  934. return TRUE;
  935. }
  936. BOOL
  937. CSystemInfo::LoadPageFileInfo()
  938. /*++
  939. // Routine Description:
  940. // Loads page file information
  941. //
  942. // Arguments: none
  943. //
  944. // Return Value:
  945. // FALSE on failure
  946. // TRUE on success
  947. //
  948. --*/
  949. {
  950. // local variables
  951. HRESULT hr;
  952. ULONG ulReturned = 0;
  953. TARRAY arrValues = NULL;
  954. IWbemClassObject* pWbemObject = NULL;
  955. IEnumWbemClassObject* pWbemEnum = NULL;
  956. BOOL bNoBreak = TRUE;
  957. // property values
  958. CHString strCaption;
  959. // display the status message
  960. PrintProgressMsg( m_hOutput, MSG_PAGEFILEINFO, m_csbi );
  961. try
  962. {
  963. // enumerate the instances of Win32_PageFile class
  964. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_PAGEFILE ),
  965. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  966. // check the result of enumeration
  967. if ( FAILED( hr ) )
  968. {
  969. WMISaveError( hr );
  970. return FALSE;
  971. }
  972. }
  973. catch( _com_error& e )
  974. {
  975. WMISaveError( e );
  976. return FALSE;
  977. }
  978. // set the security on the obtained interface
  979. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  980. if ( FAILED( hr ) )
  981. {
  982. WMISaveError( hr );
  983. SAFE_RELEASE( pWbemEnum );
  984. return FALSE;
  985. }
  986. // get the enumerated objects information
  987. // NOTE: This needs to be traversed only one time.
  988. do
  989. {
  990. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  991. if ( hr == (HRESULT) WBEM_S_FALSE )
  992. {
  993. bNoBreak = FALSE;
  994. // we've reached the end of enumeration .. go out of the loop
  995. break;
  996. }
  997. else if ( FAILED( hr ) )
  998. {
  999. // some error has occured ... oooppps
  1000. WMISaveError( hr );
  1001. SAFE_RELEASE( pWbemEnum );
  1002. return FALSE;
  1003. }
  1004. // get the propert information
  1005. PropertyGet( pWbemObject, WIN32_PAGEFILE_P_NAME, strCaption );
  1006. // release the current object
  1007. SAFE_RELEASE( pWbemObject );
  1008. // add the values to the data
  1009. if ( arrValues == NULL )
  1010. {
  1011. arrValues = DynArrayItem2( m_arrData, 0, CI_PAGEFILE_LOCATION );
  1012. if ( arrValues == NULL )
  1013. {
  1014. SetLastError((DWORD) E_UNEXPECTED );
  1015. SaveLastError();
  1016. SAFE_RELEASE( pWbemEnum );
  1017. return FALSE;
  1018. }
  1019. // remove all the existing entries
  1020. DynArrayRemoveAll( arrValues );
  1021. }
  1022. // add the data
  1023. DynArrayAppendString( arrValues, strCaption, 0 );
  1024. } while ( TRUE == bNoBreak );
  1025. // release the enumerated object
  1026. SAFE_RELEASE( pWbemEnum );
  1027. // return
  1028. return TRUE;
  1029. }
  1030. BOOL
  1031. CSystemInfo::LoadProcessorInfo()
  1032. /*++
  1033. // Routine Description:
  1034. // Loads processor information
  1035. //
  1036. // Arguments:none
  1037. //
  1038. // Return Value:
  1039. // FALSE on failure
  1040. // TRUE on success
  1041. --*/
  1042. {
  1043. // local variables
  1044. HRESULT hr;
  1045. CHString str;
  1046. DWORD dwCount = 0;
  1047. ULONG ulReturned = 0;
  1048. TARRAY arrValues = NULL;
  1049. IWbemClassObject* pWbemObject = NULL;
  1050. IEnumWbemClassObject* pWbemEnum = NULL;
  1051. BOOL bNoBreak = TRUE;
  1052. // property values
  1053. DWORD dwClockSpeed;
  1054. CHString strCaption;
  1055. CHString strManufacturer;
  1056. // display the status message
  1057. PrintProgressMsg( m_hOutput, MSG_PROCESSORINFO, m_csbi );
  1058. try
  1059. {
  1060. // enumerate the instances of Win32_Processor class
  1061. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_PROCESSOR ),
  1062. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  1063. // check the result of enumeration
  1064. if ( FAILED( hr ) )
  1065. {
  1066. WMISaveError( hr );
  1067. return FALSE;
  1068. }
  1069. }
  1070. catch( _com_error& e )
  1071. {
  1072. WMISaveError( e );
  1073. return FALSE;
  1074. }
  1075. // set the security on the obtained interface
  1076. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  1077. if ( FAILED( hr ) )
  1078. {
  1079. WMISaveError( hr );
  1080. SAFE_RELEASE( pWbemEnum );
  1081. return FALSE;
  1082. }
  1083. // get the enumerated objects information
  1084. try
  1085. {
  1086. do
  1087. {
  1088. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  1089. if ( hr == (HRESULT) WBEM_S_FALSE )
  1090. {
  1091. bNoBreak = FALSE;
  1092. // we've reached the end of enumeration .. go out of the loop
  1093. break;
  1094. }
  1095. else if ( FAILED( hr ) )
  1096. {
  1097. // some error has occured ... oooppps
  1098. WMISaveError( hr );
  1099. SAFE_RELEASE( pWbemEnum );
  1100. return FALSE;
  1101. }
  1102. // update the counter
  1103. dwCount++;
  1104. // get the propert information
  1105. PropertyGet( pWbemObject, WIN32_PROCESSOR_P_CAPTION, strCaption );
  1106. PropertyGet( pWbemObject, WIN32_PROCESSOR_P_MANUFACTURER, strManufacturer );
  1107. PropertyGet( pWbemObject, WIN32_PROCESSOR_P_CURRENTCLOCKSPEED, dwClockSpeed );
  1108. // check whether we got the clock speed correctly or not
  1109. // if not, get the max. clock speed
  1110. if ( dwClockSpeed == 0 )
  1111. PropertyGet( pWbemObject, WIN32_PROCESSOR_P_MAXCLOCKSPEED, dwClockSpeed );
  1112. // release the current object
  1113. SAFE_RELEASE( pWbemObject );
  1114. // add the values to the data
  1115. if ( arrValues == NULL )
  1116. {
  1117. arrValues = DynArrayItem2( m_arrData, 0, CI_PROCESSOR );
  1118. if ( arrValues == NULL )
  1119. {
  1120. SetLastError( (DWORD)E_UNEXPECTED );
  1121. SaveLastError();
  1122. SAFE_RELEASE( pWbemEnum );
  1123. return FALSE;
  1124. }
  1125. // remove all the existing entries
  1126. DynArrayRemoveAll( arrValues );
  1127. }
  1128. //
  1129. // prepare the processor info
  1130. str.Format( FMT_PROCESSOR_INFO, dwCount, strCaption, strManufacturer, dwClockSpeed );
  1131. // add the data
  1132. DynArrayAppendString( arrValues, str, 0 );
  1133. } while ( TRUE == bNoBreak );
  1134. // release the enumerated object
  1135. SAFE_RELEASE( pWbemEnum );
  1136. // update the total no. of processors info
  1137. if ( arrValues != NULL )
  1138. {
  1139. // NOTE: this should appear at the first line
  1140. str.Format( FMT_PROCESSOR_TOTAL, dwCount );
  1141. DynArrayInsertString( arrValues, 0, str, 0 );
  1142. }
  1143. }
  1144. catch( ... )
  1145. {
  1146. SetLastError( (DWORD)E_OUTOFMEMORY );
  1147. SaveLastError();
  1148. return FALSE;
  1149. }
  1150. // return
  1151. return TRUE;
  1152. }
  1153. BOOL
  1154. CSystemInfo::LoadKeyboardInfo()
  1155. /*++
  1156. // Routine Description:
  1157. // Loads keyboard information
  1158. //
  1159. // Arguments: none
  1160. //
  1161. // Return Value:
  1162. // FALSE on failure
  1163. // TRUE on success
  1164. --*/
  1165. {
  1166. // local variables
  1167. HRESULT hr;
  1168. ULONG ulReturned = 0;
  1169. IWbemClassObject* pWbemObject = NULL;
  1170. IEnumWbemClassObject* pWbemEnum = NULL;
  1171. // property values
  1172. CHString strLayout;
  1173. // display the status message
  1174. PrintProgressMsg( m_hOutput, MSG_INPUTLOCALEINFO, m_csbi );
  1175. try
  1176. {
  1177. // enumerate the instances of Win32_Keyboard class
  1178. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_KEYBOARD ),
  1179. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  1180. // check the result of enumeration
  1181. if ( FAILED( hr ) )
  1182. {
  1183. WMISaveError( hr );
  1184. return FALSE;
  1185. }
  1186. }
  1187. catch( _com_error& e )
  1188. {
  1189. WMISaveError( e );
  1190. return FALSE;
  1191. }
  1192. // set the security on the obtained interface
  1193. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  1194. if ( FAILED( hr ) )
  1195. {
  1196. WMISaveError( hr );
  1197. SAFE_RELEASE( pWbemEnum );
  1198. return FALSE;
  1199. }
  1200. // get the enumerated objects information
  1201. // NOTE: This needs to be traversed only one time.
  1202. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  1203. if ( FAILED( hr ) )
  1204. {
  1205. // some error has occured ... oooppps
  1206. WMISaveError( hr );
  1207. SAFE_RELEASE( pWbemEnum );
  1208. return FALSE;
  1209. }
  1210. // get the propert information
  1211. PropertyGet( pWbemObject, WIN32_KEYBOARD_P_LAYOUT, strLayout );
  1212. // relase the interfaces
  1213. SAFE_RELEASE( pWbemEnum );
  1214. SAFE_RELEASE( pWbemObject );
  1215. // convert the code page into appropriate text
  1216. TranslateLocaleCode( strLayout );
  1217. //
  1218. // save the info in dynamic array
  1219. DynArraySetString2( m_arrData, 0, CI_INPUT_LOCALE, strLayout, 0 );
  1220. // return
  1221. return TRUE;
  1222. }
  1223. BOOL
  1224. CSystemInfo::LoadHotfixInfo()
  1225. /*++
  1226. // Routine Description:
  1227. // Loads hot fix information
  1228. //
  1229. // Arguments: None
  1230. //
  1231. // Return Value:
  1232. // FALSE on failure
  1233. // TRUE on success
  1234. //
  1235. --*/
  1236. {
  1237. // local variables
  1238. HRESULT hr;
  1239. CHString str;
  1240. DWORD dwCount = 0;
  1241. ULONG ulReturned = 0;
  1242. TARRAY arrValues = NULL;
  1243. IWbemClassObject* pWbemObject = NULL;
  1244. IEnumWbemClassObject* pWbemEnum = NULL;
  1245. BOOL bNoBreak = TRUE;
  1246. // property values
  1247. CHString strHotFix;
  1248. CHString strComments;
  1249. // display the status message
  1250. PrintProgressMsg( m_hOutput, MSG_HOTFIXINFO, m_csbi );
  1251. try
  1252. {
  1253. // enumerate the instances of Win32_QuickFixEngineering class
  1254. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_QUICKFIXENGINEERING ),
  1255. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  1256. // check the result of enumeration
  1257. if ( FAILED( hr ) )
  1258. {
  1259. WMISaveError( hr );
  1260. return FALSE;
  1261. }
  1262. }
  1263. catch( _com_error& e )
  1264. {
  1265. WMISaveError( e );
  1266. return FALSE;
  1267. }
  1268. // set the security on the obtained interface
  1269. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  1270. if ( FAILED( hr ) )
  1271. {
  1272. WMISaveError( hr );
  1273. SAFE_RELEASE( pWbemEnum );
  1274. return FALSE;
  1275. }
  1276. // get the enumerated objects information
  1277. try
  1278. {
  1279. do
  1280. {
  1281. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  1282. if ( hr == (HRESULT) WBEM_S_FALSE )
  1283. {
  1284. bNoBreak = FALSE;
  1285. // we've reached the end of enumeration .. go out of the loop
  1286. break;
  1287. }
  1288. else if ( FAILED( hr ) )
  1289. {
  1290. // some error has occured ... oooppps
  1291. WMISaveError( hr );
  1292. SAFE_RELEASE( pWbemEnum );
  1293. return FALSE;
  1294. }
  1295. // update the counter
  1296. dwCount++;
  1297. // get the propert information
  1298. PropertyGet( pWbemObject, WIN32_QUICKFIXENGINEERING_P_HOTFIXID, strHotFix );
  1299. PropertyGet( pWbemObject, WIN32_QUICKFIXENGINEERING_P_FIXCOMMENTS, strComments );
  1300. // release the current object
  1301. SAFE_RELEASE( pWbemObject );
  1302. // add the values to the data
  1303. if ( arrValues == NULL )
  1304. {
  1305. arrValues = DynArrayItem2( m_arrData, 0, CI_HOTFIX );
  1306. if ( arrValues == NULL )
  1307. {
  1308. SetLastError( (DWORD)E_UNEXPECTED );
  1309. SaveLastError();
  1310. SAFE_RELEASE( pWbemEnum );
  1311. return FALSE;
  1312. }
  1313. // remove all the existing entries
  1314. DynArrayRemoveAll( arrValues );
  1315. }
  1316. // check if fix comments were available or not
  1317. // if available, append that to the the hot fix number
  1318. if ( strComments.GetLength() != 0 )
  1319. strHotFix += L" - " + strComments;
  1320. // prepare the hot fix info
  1321. str.Format( FMT_HOTFIX_INFO, dwCount, strHotFix );
  1322. // add the data
  1323. DynArrayAppendString( arrValues, str, 0 );
  1324. } while ( TRUE == bNoBreak );
  1325. // release the enumerated object
  1326. SAFE_RELEASE( pWbemEnum );
  1327. // update the total no. of hotfix's info
  1328. if ( arrValues != NULL )
  1329. {
  1330. // NOTE: this should appear at the first line
  1331. str.Format( FMT_HOTFIX_TOTAL, dwCount );
  1332. DynArrayInsertString( arrValues, 0, str, 0 );
  1333. }
  1334. }
  1335. catch( ... )
  1336. {
  1337. SetLastError((DWORD) E_OUTOFMEMORY );
  1338. SaveLastError();
  1339. return FALSE;
  1340. }
  1341. // return
  1342. return TRUE;
  1343. }
  1344. BOOL
  1345. CSystemInfo::LoadPerformanceInfo()
  1346. /*++
  1347. // Routine Description:
  1348. // Loads performance information
  1349. //
  1350. // Arguments: None
  1351. //
  1352. // Return Value:
  1353. // FALSE on failure
  1354. // TRUE on success
  1355. //
  1356. --*/
  1357. {
  1358. // local variables
  1359. HRESULT hr;
  1360. CHString strUpTime;
  1361. ULONG ulReturned = 0;
  1362. ULONGLONG ullSysUpTime = 0;
  1363. ULONGLONG ullElapsedTime = 0;
  1364. ULONGLONG ullFrequencyObject = 0;
  1365. ULONGLONG ullTimestampObject = 0;
  1366. IWbemClassObject* pWbemObject = NULL;
  1367. IEnumWbemClassObject* pWbemEnum = NULL;
  1368. DWORD dwDays = 0, dwHours = 0, dwMinutes = 0, dwSeconds = 0;
  1369. // display the status message
  1370. PrintProgressMsg( m_hOutput, MSG_PERFINFO, m_csbi );
  1371. try
  1372. {
  1373. // enumerate the instances of Win32_PerfRawData_PerfOS_System class
  1374. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_PERFRAWDATA_PERFOS_SYSTEM ),
  1375. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  1376. // check the result of enumeration
  1377. if ( FAILED( hr ) )
  1378. {
  1379. WMISaveError( hr );
  1380. return FALSE;
  1381. }
  1382. }
  1383. catch( _com_error& e )
  1384. {
  1385. WMISaveError( e );
  1386. return FALSE;
  1387. }
  1388. // set the security on the obtained interface
  1389. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  1390. if ( FAILED( hr ) )
  1391. {
  1392. WMISaveError( hr );
  1393. SAFE_RELEASE( pWbemEnum );
  1394. return FALSE;
  1395. }
  1396. // get the enumerated objects information
  1397. // NOTE: This needs to be traversed only one time.
  1398. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  1399. if ( FAILED( hr ) )
  1400. {
  1401. // some error has occured ... oooppps
  1402. WMISaveError( hr );
  1403. SAFE_RELEASE( pWbemEnum );
  1404. return FALSE;
  1405. }
  1406. // get the performance information
  1407. PropertyGet( pWbemObject, WIN32_PERFRAWDATA_PERFOS_SYSTEM_P_SYSUPTIME, ullSysUpTime );
  1408. PropertyGet( pWbemObject, WIN32_PERFRAWDATA_PERFOS_SYSTEM_P_TIMESTAMP, ullTimestampObject );
  1409. PropertyGet( pWbemObject, WIN32_PERFRAWDATA_PERFOS_SYSTEM_P_FREQUENCY, ullFrequencyObject );
  1410. // release the interfaces
  1411. SAFE_RELEASE( pWbemObject );
  1412. SAFE_RELEASE( pWbemEnum );
  1413. // ( performance_time_object - system_up_time ) / frequency_object = elapsed_time
  1414. // NOTE: take care of divide by zero errors.
  1415. if ( ullFrequencyObject == 0 )
  1416. {
  1417. SetLastError( (DWORD)STG_E_UNKNOWN );
  1418. SaveLastError();
  1419. return FALSE;
  1420. }
  1421. // ...
  1422. ullElapsedTime = ( ullTimestampObject - ullSysUpTime ) / ullFrequencyObject;
  1423. //
  1424. // in calculations currently assuming as differences will not cross 2 ^ 32 value
  1425. //
  1426. // no. of days = elapsed_time / 86400
  1427. // update with elapsed_time %= 86400
  1428. dwDays = (DWORD) (ullElapsedTime / 86400);
  1429. ullElapsedTime %= 86400;
  1430. // no. of hours = elapsed_time / 3600
  1431. // update with elapsed_time %= 3600
  1432. dwHours = (DWORD) (ullElapsedTime / 3600);
  1433. ullElapsedTime %= 3600;
  1434. // no. of minutes = elapsed_time / 60
  1435. // no. of seconds = elapsed_time % 60
  1436. dwMinutes = (DWORD) (ullElapsedTime / 60);
  1437. dwSeconds = (DWORD) (ullElapsedTime % 60);
  1438. try
  1439. {
  1440. // now prepare the system up time information
  1441. strUpTime.Format( FMT_UPTIME, dwDays, dwHours, dwMinutes, dwSeconds );
  1442. }
  1443. catch( ... )
  1444. {
  1445. SetLastError( (DWORD)E_OUTOFMEMORY );
  1446. SaveLastError();
  1447. return FALSE;
  1448. }
  1449. // save the info
  1450. DynArraySetString2( m_arrData, 0, CI_SYSTEM_UPTIME, strUpTime, 0 );
  1451. // return
  1452. return TRUE;
  1453. }
  1454. BOOL
  1455. CSystemInfo::LoadNetworkCardInfo()
  1456. /*++
  1457. // Routine Description:
  1458. // Loads network card information
  1459. //
  1460. // Arguments: none
  1461. //
  1462. // Return Value:
  1463. // FALSE on failure
  1464. // TRUE on success
  1465. //
  1466. --*/
  1467. {
  1468. // local variables
  1469. HRESULT hr;
  1470. CHString str;
  1471. DWORD dwCount = 0;
  1472. DWORD dwNicCount = 0;
  1473. DWORD dwStatus = 0;
  1474. BOOL bResult = FALSE;
  1475. ULONG ulReturned = 0;
  1476. TARRAY arrValues = NULL;
  1477. IWbemClassObject* pWbemObject = NULL;
  1478. IEnumWbemClassObject* pWbemEnum = NULL;
  1479. BOOL bNoBreak = TRUE;
  1480. // property values
  1481. DWORD dwIndex = 0;
  1482. CHString strConnection;
  1483. CHString strDescription;
  1484. // display the status message
  1485. PrintProgressMsg( m_hOutput, MSG_NICINFO, m_csbi );
  1486. try
  1487. {
  1488. // enumerate the instances of Win32_NetworkAdapter class
  1489. hr = m_pWbemServices->CreateInstanceEnum( _bstr_t( WIN32_NETWORKADAPTER ),
  1490. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pWbemEnum );
  1491. // check the result of enumeration
  1492. if ( FAILED( hr ) )
  1493. {
  1494. WMISaveError( hr );
  1495. return FALSE;
  1496. }
  1497. }
  1498. catch( _com_error& e )
  1499. {
  1500. WMISaveError( e );
  1501. return FALSE;
  1502. }
  1503. // set the security on the obtained interface
  1504. hr = SetInterfaceSecurity( pWbemEnum, m_pAuthIdentity );
  1505. if ( FAILED( hr ) )
  1506. {
  1507. WMISaveError( hr );
  1508. SAFE_RELEASE( pWbemEnum );
  1509. return FALSE;
  1510. }
  1511. // get the enumerated objects information
  1512. try
  1513. {
  1514. do
  1515. {
  1516. hr = pWbemEnum->Next( WBEM_INFINITE, 1, &pWbemObject, &ulReturned );
  1517. if ( hr == (HRESULT) WBEM_S_FALSE )
  1518. {
  1519. bNoBreak = FALSE;
  1520. // we've reached the end of enumeration .. go out of the loop
  1521. break;
  1522. }
  1523. else if ( FAILED( hr ) )
  1524. {
  1525. // some error has occured ... oooppps
  1526. WMISaveError( (DWORD) hr );
  1527. SAFE_RELEASE( pWbemEnum );
  1528. return FALSE;
  1529. }
  1530. // get the property information
  1531. // NOTE: get the result of getting status property information
  1532. PropertyGet( pWbemObject, WIN32_NETWORKADAPTER_P_INDEX, dwIndex );
  1533. PropertyGet( pWbemObject, WIN32_NETWORKADAPTER_P_DESCRIPTION, strDescription );
  1534. PropertyGet( pWbemObject, WIN32_NETWORKADAPTER_P_NETCONNECTIONID, strConnection );
  1535. bResult = PropertyGet( pWbemObject, WIN32_NETWORKADAPTER_P_STATUS, dwStatus, 0 );
  1536. // release the current object
  1537. SAFE_RELEASE( pWbemObject );
  1538. // add the values to the data
  1539. // NOTE: do this only if either we couldn't find the property or status is not -1
  1540. // FOR WINDOWS 2000 MACHINES 'NetConnectionStatus' PROPERT IS NOT EXISTED IN
  1541. // WMI 'Win32_NetworkAdapter' CLASS. SO WE WILL BE DISPLAYING THE N/W CARD
  1542. // INFORMATION IF PROPERTY DOESN'T EXIST OR IF EXISTS AND THE STATUS IS NOT -1
  1543. if ( bResult == FALSE || dwStatus != 0 )
  1544. {
  1545. // update the counter
  1546. dwCount++;
  1547. if ( arrValues == NULL )
  1548. {
  1549. arrValues = DynArrayItem2( m_arrData, 0, CI_NETWORK_CARD );
  1550. if ( arrValues == NULL )
  1551. {
  1552. SetLastError( (DWORD)E_UNEXPECTED );
  1553. SaveLastError();
  1554. SAFE_RELEASE( pWbemEnum );
  1555. return FALSE;
  1556. }
  1557. // remove all the existing entries
  1558. DynArrayRemoveAll( arrValues );
  1559. }
  1560. // prepare the n/w card info
  1561. str.Format( FMT_NIC_INFO, dwCount, strDescription );
  1562. // add the data
  1563. DynArrayAppendString( arrValues, str, 0 );
  1564. // now check the status in detail ... only if the property exists
  1565. if ( bResult == TRUE )
  1566. {
  1567. //
  1568. // property do exists ... so determine the status
  1569. // display the status of the NIC except it is connected
  1570. // if the NIC is connected, display the ipaddress and its other information
  1571. // add the connection name
  1572. str.Format( FMT_CONNECTION, strConnection );
  1573. DynArrayAppendString( arrValues, str, 0 );
  1574. // ...
  1575. if ( dwStatus != 2 )
  1576. {
  1577. // sub-local variables
  1578. CHString strValues[] = {
  1579. VALUE_DISCONNECTED, VALUE_CONNECTING,
  1580. VALUE_CONNECTED, VALUE_DISCONNECTING, VALUE_HWNOTPRESENT,
  1581. VALUE_HWDISABLED, VALUE_HWMALFUNCTION, VALUE_MEDIADISCONNECTED,
  1582. VALUE_AUTHENTICATING, VALUE_AUTHSUCCEEDED, VALUE_AUTHFAILED };
  1583. // prepare the status info
  1584. if ( dwStatus > 0 && dwStatus < SIZE_OF_ARRAY( strValues ) )
  1585. {
  1586. // ...
  1587. str.Format( FMT_NIC_STATUS, strValues[ dwStatus ] );
  1588. // save the info
  1589. DynArrayAppendString( arrValues, str, 0 );
  1590. }
  1591. }
  1592. else
  1593. {
  1594. //
  1595. // get the adapter configuration
  1596. // sub-local variables
  1597. CHString strTemp;
  1598. CHString strDhcpServer;
  1599. DWORD dwDhcpEnabled = 0;
  1600. TARRAY arrIPAddress = NULL;
  1601. // create the ipaddress array
  1602. arrIPAddress = CreateDynamicArray();
  1603. if ( arrIPAddress == NULL )
  1604. {
  1605. WMISaveError( E_OUTOFMEMORY );
  1606. SAFE_RELEASE( pWbemEnum );
  1607. return FALSE;
  1608. }
  1609. // prepare the object path
  1610. str.Format( WIN32_NETWORKADAPTERCONFIGURATION_GET, dwIndex );
  1611. // get the nic config info object
  1612. hr = m_pWbemServices->GetObject( _bstr_t( str ),
  1613. WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pWbemObject, NULL );
  1614. // check the result .. proceed furthur only if successfull
  1615. if ( SUCCEEDED( hr ) )
  1616. {
  1617. // get the needed property values
  1618. PropertyGet( pWbemObject, WIN32_NETWORKADAPTERCONFIGURATION_P_IPADDRESS, arrIPAddress );
  1619. PropertyGet( pWbemObject, WIN32_NETWORKADAPTERCONFIGURATION_P_DHCPSERVER, strDhcpServer );
  1620. PropertyGet( pWbemObject, WIN32_NETWORKADAPTERCONFIGURATION_P_DHCPENABLED, dwDhcpEnabled );
  1621. // check and add the dhcp information
  1622. // NOTE: CIM_BOOLEAN -> TRUE = -1, FALSE = 0
  1623. strTemp = FMT_DHCP_STATUS;
  1624. str.Format( strTemp, ( ( dwDhcpEnabled == -1 ) ? VALUE_YES : VALUE_NO ) );
  1625. DynArrayAppendString( arrValues, str, 0 );
  1626. // add the dhcp server info ( if needed )
  1627. if ( dwDhcpEnabled == -1 )
  1628. {
  1629. str.Format( FMT_DHCP_SERVER, strDhcpServer );
  1630. DynArrayAppendString( arrValues, str, 0 );
  1631. }
  1632. //
  1633. // add the IP Address information
  1634. DynArrayAppendString( arrValues, FMT_IPADDRESS_TOTAL, 0 );
  1635. dwNicCount = DynArrayGetCount( arrIPAddress );
  1636. for( DWORD dw = 0; dw < dwNicCount; dw++ )
  1637. {
  1638. // get the info
  1639. LPCWSTR pwsz = NULL;
  1640. pwsz = DynArrayItemAsString( arrIPAddress, dw );
  1641. if ( pwsz == NULL )
  1642. continue;
  1643. // prepare and add the info
  1644. str.Format( FMT_IPADDRESS_INFO, dw + 1, pwsz );
  1645. DynArrayAppendString( arrValues, str, 0 );
  1646. }
  1647. }
  1648. // release the object
  1649. SAFE_RELEASE( pWbemObject );
  1650. // destroy the dynamic array created for storing ip address info
  1651. DestroyDynamicArray( &arrIPAddress );
  1652. }
  1653. }
  1654. }
  1655. } while ( TRUE == bNoBreak );
  1656. // release the enumerated object
  1657. SAFE_RELEASE( pWbemEnum );
  1658. // update the total no. of hotfix's info
  1659. if ( arrValues != NULL )
  1660. {
  1661. // NOTE: this should appear at the first line
  1662. str.Format( FMT_NIC_TOTAL, dwCount );
  1663. DynArrayInsertString( arrValues, 0, str, 0 );
  1664. }
  1665. }
  1666. catch( ... )
  1667. {
  1668. WMISaveError( (DWORD)E_OUTOFMEMORY );
  1669. SAFE_RELEASE( pWbemObject );
  1670. SAFE_RELEASE( pWbemEnum );
  1671. return FALSE;
  1672. }
  1673. // return success
  1674. return TRUE;
  1675. }
  1676. BOOL
  1677. CSystemInfo::LoadProfileInfo()
  1678. /*++
  1679. // Routine Description:
  1680. // Loads profile information
  1681. //
  1682. // Arguments:none
  1683. //
  1684. // Return Value:
  1685. // FALSE on failure
  1686. // TRUE on success
  1687. //
  1688. --*/
  1689. {
  1690. // local variables
  1691. BOOL bResult = FALSE;
  1692. CHString strLogonServer;
  1693. LPCWSTR pwszPassword = NULL;
  1694. IWbemServices* pDefaultNamespace = NULL;
  1695. // display the status message
  1696. PrintProgressMsg( m_hOutput, MSG_PROFILEINFO, m_csbi );
  1697. // determine the password with which connection to default name has to be made
  1698. pwszPassword = NULL;
  1699. if ( m_pAuthIdentity != NULL )
  1700. {
  1701. pwszPassword = m_pAuthIdentity->Password;
  1702. }
  1703. // we need to establish connection to the remote system's registry
  1704. // for this connect to the default namespace of the WMI using the credentials available with us
  1705. bResult = ConnectWmi( m_pWbemLocator, &pDefaultNamespace,
  1706. m_strServer, m_strUserName, pwszPassword, &m_pAuthIdentity, FALSE, WMI_NAMESPACE_DEFAULT );
  1707. if ( bResult == FALSE )
  1708. {
  1709. return FALSE;
  1710. }
  1711. // get the value of the LOGONSERVER
  1712. RegQueryValueWMI( pDefaultNamespace, WMI_HKEY_CURRENT_USER,
  1713. SUBKEY_VOLATILE_ENVIRONMENT, KEY_LOGONSERVER, strLogonServer );
  1714. // release the interface
  1715. SAFE_RELEASE( pDefaultNamespace );
  1716. //
  1717. // save the info
  1718. DynArraySetString2( m_arrData, 0, CI_LOGON_SERVER, strLogonServer, 0 );
  1719. // return
  1720. return TRUE;
  1721. }
  1722. VOID
  1723. PrintProgressMsg(
  1724. IN HANDLE hOutput,
  1725. IN LPCWSTR pwszMsg,
  1726. IN const CONSOLE_SCREEN_BUFFER_INFO& csbi
  1727. )
  1728. /*++
  1729. // Routine Description:
  1730. // Prints the message on console
  1731. //
  1732. // Arguments:
  1733. // [in] hOutput : output handle
  1734. // [in] pwszMsg : Message to be printed
  1735. // [in] csbi : console screen buffer structure
  1736. //
  1737. //
  1738. // Return Value: none
  1739. //
  1740. --*/
  1741. {
  1742. // local variables
  1743. COORD coord;
  1744. DWORD dwSize = 0;
  1745. WCHAR wszSpaces[ 80 ] = L"";
  1746. // check the handle. if it is null, it means that output is being redirected. so return
  1747. if ( hOutput == NULL )
  1748. {
  1749. return;
  1750. }
  1751. // set the cursor position
  1752. coord.X = 0;
  1753. coord.Y = csbi.dwCursorPosition.Y;
  1754. // first erase contents on the current line
  1755. SecureZeroMemory( wszSpaces, SIZE_OF_ARRAY(wszSpaces) );
  1756. SetConsoleCursorPosition( hOutput, coord );
  1757. WriteConsoleW( hOutput, Replicate( wszSpaces, L" ", 79, 79 ), 79, &dwSize, NULL );
  1758. // now display the message ( if exists )
  1759. SetConsoleCursorPosition( hOutput, coord );
  1760. if ( pwszMsg != NULL )
  1761. {
  1762. WriteConsoleW( hOutput, pwszMsg, StringLength( pwszMsg, 0 ), &dwSize, NULL );
  1763. }
  1764. }
  1765. BOOL
  1766. TranslateLocaleCode( CHString& strLocale )
  1767. /*++
  1768. // Routine Description:
  1769. // Translates locale code
  1770. //
  1771. // Arguments:
  1772. // [in] strLocale : locale
  1773. //
  1774. // Return Value:
  1775. // TRUE on success
  1776. // FALSE on failure
  1777. //
  1778. --*/
  1779. {
  1780. // local variables
  1781. CHString str;
  1782. HKEY hKey = NULL;
  1783. DWORD dwSize = 0;
  1784. LONG lRegReturn = 0;
  1785. HKEY hMainKey = NULL;
  1786. WCHAR wszValue[ 64 ] = L"\0";
  1787. //
  1788. // THIS IS A TYPICAL THING WHICH WE ARE DOING HERE
  1789. // BECAUSE WE DONT KNOW WHAT LANGUAGE TARGET MACHINE IS USING
  1790. // SO WE GET THE LOCALE CODE PAGE BEING USED BY THE TARGET MACHINE
  1791. // AND GET THE APPROPRIATE NAME FOR THAT LOCALE FROM THE CURRENT SYSTEM
  1792. // REGISTRY DATABASE. IF THE REGISTRY IS CORRUPTED THEN THERE IS NO WAY
  1793. // TO JUDGE THE OUTPUT THAT DISPLAYED BY THIS UTILITY IS VALID OR INVALID
  1794. //
  1795. try
  1796. {
  1797. // get the reference to the promary hive
  1798. lRegReturn = RegConnectRegistry( NULL, HKEY_CLASSES_ROOT, &hMainKey );
  1799. if ( lRegReturn != ERROR_SUCCESS )
  1800. {
  1801. SaveLastError();
  1802. return FALSE;
  1803. }
  1804. else if ( hMainKey == NULL )
  1805. {
  1806. // THIS IS MEANING LESS IN DOING
  1807. // BUT JUST TO AVOID PREfix BUG THIS PART IS WRITTEN
  1808. SetLastError( (DWORD)E_OUTOFMEMORY );
  1809. SaveLastError();
  1810. return FALSE;
  1811. }
  1812. // now get the reference to the database path
  1813. lRegReturn = RegOpenKeyEx( hMainKey, LOCALE_PATH, 0, KEY_QUERY_VALUE, &hKey);
  1814. if ( lRegReturn != ERROR_SUCCESS )
  1815. {
  1816. switch( lRegReturn )
  1817. {
  1818. case ERROR_FILE_NOT_FOUND:
  1819. SetLastError( ERROR_REGISTRY_CORRUPT );
  1820. break;
  1821. default:
  1822. // save the error information and return FAILURE
  1823. SetLastError( lRegReturn );
  1824. break;
  1825. }
  1826. // close the key and return
  1827. SaveLastError();
  1828. RegCloseKey( hMainKey );
  1829. return FALSE;
  1830. }
  1831. else if ( hKey == NULL )
  1832. {
  1833. // THIS IS MEANING LESS IN DOING
  1834. // BUT JUST TO AVOID PREfix BUG THIS PART IS WRITTEN
  1835. SetLastError( (DWORD)E_OUTOFMEMORY );
  1836. SaveLastError();
  1837. return FALSE;
  1838. }
  1839. // we are interested in the last 4 characters of the code page info
  1840. str = strLocale.Right( 4 );
  1841. //copy the last four charecters in to the string to get the locale
  1842. dwSize = SIZE_OF_ARRAY( wszValue );
  1843. lRegReturn = RegQueryValueExW( hKey, str, NULL, NULL, ( LPBYTE ) wszValue, &dwSize);
  1844. // first close the registry handles
  1845. if ( NULL != hKey )
  1846. {
  1847. RegCloseKey( hKey );
  1848. }
  1849. if ( NULL != hMainKey )
  1850. {
  1851. RegCloseKey( hMainKey );
  1852. }
  1853. // now check the return value
  1854. if( lRegReturn != ERROR_SUCCESS )
  1855. return FALSE;
  1856. // save the value
  1857. strLocale = wszValue;
  1858. }
  1859. catch( ... )
  1860. {
  1861. WMISaveError( E_OUTOFMEMORY );
  1862. // release the registry handles
  1863. if ( NULL != hKey )
  1864. {
  1865. RegCloseKey( hKey );
  1866. hKey = NULL;
  1867. }
  1868. if ( NULL != hMainKey )
  1869. {
  1870. RegCloseKey( hMainKey );
  1871. hMainKey = NULL;
  1872. }
  1873. return FALSE;
  1874. }
  1875. // return
  1876. return TRUE;
  1877. }
  1878. BOOL
  1879. FormatNumber(
  1880. IN LPCWSTR pwszValue,
  1881. IN CHString& strFmtValue
  1882. )
  1883. /*++
  1884. // Routine Description:
  1885. //
  1886. // Arguments:
  1887. // [in] pwszValue : value
  1888. // [in] strFmtValue : format value
  1889. //
  1890. // Return Value:
  1891. // TRUE on success
  1892. // FALSE on failure
  1893. //
  1894. --*/
  1895. {
  1896. try
  1897. {
  1898. // get the size of buffer that is needed
  1899. DWORD dwCount = 0;
  1900. if( NULL == pwszValue )
  1901. {
  1902. SetLastError( ERROR_INVALID_PARAMETER );
  1903. SaveLastError();
  1904. return FALSE;
  1905. }
  1906. dwCount = GetNumberFormat( LOCALE_USER_DEFAULT, 0, pwszValue, NULL, L"", 0 );
  1907. // get the required buffer
  1908. LPWSTR pwszTemp = NULL;
  1909. pwszTemp = strFmtValue.GetBufferSetLength( dwCount + 1 );
  1910. // now format the date
  1911. dwCount = GetNumberFormat( LOCALE_USER_DEFAULT, 0, pwszValue, NULL, pwszTemp, dwCount );
  1912. if( 0 == dwCount )
  1913. {
  1914. SaveLastError();
  1915. return FALSE;
  1916. }
  1917. // release the buffer
  1918. strFmtValue.ReleaseBuffer();
  1919. }
  1920. catch( ... )
  1921. {
  1922. SetLastError((DWORD) E_OUTOFMEMORY );
  1923. SaveLastError();
  1924. return FALSE;
  1925. }
  1926. // return
  1927. return TRUE;
  1928. }
  1929. BOOL
  1930. FormatNumberEx(
  1931. IN LPCWSTR pwszValue,
  1932. OUT CHString& strFmtValue
  1933. )
  1934. /*++
  1935. // Routine Description:
  1936. // Formats the number
  1937. //
  1938. // Arguments:
  1939. // [in] pwszValue: Value string
  1940. // [in] strFmtValue : format value
  1941. //
  1942. // Return Value:
  1943. // TRUE on success
  1944. // FALSE on failure
  1945. //
  1946. --*/
  1947. {
  1948. // local variables
  1949. CHString str;
  1950. LONG lTemp = 0;
  1951. NUMBERFMTW nfmtw;
  1952. DWORD dwGroupSep = 0;
  1953. LPWSTR pwszTemp = NULL;
  1954. CHString strGroupThousSep;
  1955. try
  1956. {
  1957. //
  1958. // get the group seperator character
  1959. lTemp = GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, NULL, 0 );
  1960. if ( lTemp == 0 )
  1961. {
  1962. // we don't know how to resolve this
  1963. return FALSE;
  1964. }
  1965. else
  1966. {
  1967. // get the group seperation character
  1968. pwszTemp = str.GetBufferSetLength( lTemp + 2 );
  1969. SecureZeroMemory( pwszTemp, ( lTemp + 2 ) * sizeof( WCHAR ) );
  1970. GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SGROUPING, pwszTemp, lTemp );
  1971. // change the group info into appropriate number
  1972. lTemp = 0;
  1973. dwGroupSep = 0;
  1974. while ( lTemp < str.GetLength() )
  1975. {
  1976. if ( AsLong( str.Mid( lTemp, 1 ), 10 ) != 0 )
  1977. dwGroupSep = dwGroupSep * 10 + AsLong( str.Mid( lTemp, 1 ), 10 );
  1978. // increment by 2
  1979. lTemp += 2;
  1980. }
  1981. }
  1982. //
  1983. // get the thousand seperator character
  1984. lTemp = GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, NULL, 0 );
  1985. if ( lTemp == 0 )
  1986. {
  1987. // we don't know how to resolve this
  1988. return FALSE;
  1989. }
  1990. else
  1991. {
  1992. // get the thousand sepeartion charactor
  1993. pwszTemp = strGroupThousSep.GetBufferSetLength( lTemp + 2 );
  1994. SecureZeroMemory( pwszTemp, ( lTemp + 2 ) * sizeof( WCHAR ) );
  1995. GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, pwszTemp, lTemp );
  1996. }
  1997. // release the CHStrig buffers
  1998. str.ReleaseBuffer();
  1999. strGroupThousSep.ReleaseBuffer();
  2000. }
  2001. catch( ... )
  2002. {
  2003. SetLastError( (DWORD)E_OUTOFMEMORY );
  2004. SaveLastError();
  2005. return FALSE;
  2006. }
  2007. // format the number
  2008. try
  2009. {
  2010. nfmtw.NumDigits = 0;
  2011. nfmtw.LeadingZero = 0;
  2012. nfmtw.NegativeOrder = 0;
  2013. nfmtw.Grouping = dwGroupSep;
  2014. nfmtw.lpDecimalSep = L"";
  2015. nfmtw.lpThousandSep = strGroupThousSep.GetBuffer( strGroupThousSep.GetLength() );
  2016. // get the size of buffer that is needed
  2017. lTemp = GetNumberFormatW( LOCALE_USER_DEFAULT, 0, pwszValue, &nfmtw, NULL, 0 );
  2018. // get/allocate the required buffer
  2019. pwszTemp = strFmtValue.GetBufferSetLength( lTemp + 1 );
  2020. // now format the date
  2021. GetNumberFormat( LOCALE_USER_DEFAULT, 0, pwszValue, &nfmtw, pwszTemp, lTemp );
  2022. // release the buffer
  2023. strFmtValue.ReleaseBuffer();
  2024. }
  2025. catch( ... )
  2026. {
  2027. SetLastError( (DWORD)E_OUTOFMEMORY );
  2028. SaveLastError();
  2029. return FALSE;
  2030. }
  2031. // return
  2032. return TRUE;
  2033. }