Source code of Windows XP (NT5)
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.

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