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.

1385 lines
40 KiB

  1. /*********************************************************************
  2. * Hardware inventory check. Works with Register Wizard
  3. *
  4. * 02/20/97 - Denny Dong Take the code from Sysinv.cpp
  5. * Copyright (c) 1998 Microsoft Corporation
  6. * 7/20/98 - Modified to get driver file name for Mouse,Sound card along with device names
  7. SCSI Adapter is added to the system inventory list.
  8. List of Devices where Driver file info is gathered
  9. 1) Mouse ( Pointing Device)
  10. 2) Sound Card
  11. 3) SCSI Adapter
  12. Dispaly resolution is changed to give additional information about color depth
  13. * 8/6/98 Prefix the Display Adapter with Driver string in the color resolution
  14. 8/17/98 Display Color Depth bug if Color depth is 32 bits aor more is fixed.The value is increased to DWORD LONG for storing the value
  15. 3/9/99 GetSystemInformation() care is teken to release SetupAPI.Dll 's Buffer
  16. 5/27/99 ProcessType info for ALPHA will be taken from the folloeing Registry Key
  17. HKLM\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment
  18. - PROCESSOR_ARCHITECTURE"
  19. - PROCESSOR_IDENTIFIER
  20. *********************************************************************/
  21. #include <Windows.h>
  22. #include <stdio.h>
  23. #include "sysinv.h"
  24. #include "resource.h"
  25. #include "SETUPAPI.H"
  26. // The packed structures below get messed up with optimizations turned on
  27. #pragma optimize( _T(""), off )
  28. typedef struct _DEVIOCTL_REGISTERS
  29. {
  30. DWORD reg_EBX;
  31. DWORD_PTR reg_EDX;
  32. DWORD reg_ECX;
  33. DWORD reg_EAX;
  34. DWORD reg_EDI;
  35. DWORD reg_ESI;
  36. DWORD reg_Flags;
  37. } DEVIOCTL_REGISTERS, *PDEVIOCTL_REGISTERS;
  38. #define MAX_SEC_PER_TRACK 64
  39. #pragma pack(1)
  40. typedef struct _DEVICEPARAMS
  41. {
  42. TBYTE dpSpecFunc;
  43. TBYTE dpDevType;
  44. WORD dpDevAttr;
  45. WORD dpCylinders;
  46. TBYTE dpMediaType;
  47. WORD dpBytesPerSec;
  48. TBYTE dpSecPerClust;
  49. WORD dpResSectors;
  50. TBYTE dpFATS;
  51. WORD dpRootDirEnts;
  52. WORD dpSectors;
  53. TBYTE dpMedia;
  54. WORD dpFATsecs;
  55. WORD dpSecsPerTrack;
  56. WORD dpHeads;
  57. DWORD dpHiddenSecs;
  58. DWORD dpHugeSectors;
  59. TBYTE A_BPB_Reserved[6]; // Unused 6 BPB bytes
  60. TBYTE TrackLayout[MAX_SEC_PER_TRACK * 4 + 2];
  61. }DEVICEPARAMS,*PDEVICEPARAMS;
  62. #pragma pack()
  63. #define VWIN32_DIOC_DOS_IOCTL 1
  64. #define kDrive525_0360 0
  65. #define kDrive525_1200 1
  66. #define kDrive350_0720 2
  67. #define kDrive350_1440 7
  68. #define kDrive350_2880 9
  69. #define kDriveFIXED 5
  70. #define kDriveBadDrvNum 0xFF
  71. // Dynamic Registry enumeration declarations
  72. #define DYNDESC_BUFFERSIZE 128
  73. static _TCHAR vrgchDynDataKey[] = _T("Config Manager\\Enum");
  74. static _TCHAR vrgchLocalMachineEnumKey[] = _T("Enum");
  75. static _TCHAR vrgchHardWareKeyValueName[] = _T("HardWareKey");
  76. static _TCHAR vrgchDriverValueName[] = _T("Driver");
  77. static _TCHAR vrgchDeviceDescValueName[] = _T("DeviceDesc");
  78. static _TCHAR vrgchDynNetExclusion[] = _T("Dial-Up Adapter");
  79. static _TCHAR vrgchHardwareIDValueName[] = _T("HardwareID");
  80. static BOOL vfIsFPUAvailable = TRUE;
  81. static _TCHAR vrgchDynProcessorName[DYNDESC_BUFFERSIZE];
  82. typedef enum
  83. {
  84. dynNet = 0,
  85. dynModem = 1,
  86. dynMouse = 2,
  87. dynCDRom = 3,
  88. dynMedia = 4,
  89. dynSCSI = 5,
  90. dynSystem = 6,
  91. dynEnd
  92. }DYN;
  93. static _TCHAR vrgchDynKey[dynEnd][12] =
  94. {
  95. _T("Net"),
  96. _T("Modem"),
  97. _T("Mouse"),
  98. _T("CDROM"),
  99. _T("Media"),
  100. _T("SCSIAdapter"),
  101. _T("System")
  102. };
  103. static _TCHAR vrgchDynDesc[dynEnd][DYNDESC_BUFFERSIZE] =
  104. {
  105. _T(""),
  106. _T(""),
  107. _T(""),
  108. _T(""),
  109. _T(""),
  110. _T("")
  111. };
  112. static HANDLE hInstance = NULL;
  113. static TCHAR sszDriverFilename[256];
  114. // Private functions
  115. void EnumerateDynamicDevices( void );
  116. void ProcessSystemDevices(LPTSTR rgchSystemKey);
  117. BOOL GetProcessorTypeStringFromRegistry(LPTSTR);
  118. void GetProcessorTypeStringFromSystem(LPTSTR);
  119. UINT GetDriveTypeInv(UINT nDrive);
  120. BOOL GetDeviceParameters(PDEVICEPARAMS pDeviceParams, UINT nDrive);
  121. BOOL DoIOCTL(PDEVIOCTL_REGISTERS preg);
  122. void GetSystemInformation(LPCTSTR szDeviceID,LPTSTR szDeviceName, LPTSTR szDriverName);
  123. BOOL WINAPI GetSystemInventoryA(INT type, LPSTR szInventory);
  124. /*
  125. * Function:
  126. * BOOL DllMain(HINSTANCE, DWORD, LPVOID)
  127. *
  128. * Purpose:
  129. * Entry point of DLL.
  130. */
  131. BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  132. {
  133. if (dwReason == DLL_PROCESS_ATTACH)
  134. hInstance = hDll;
  135. return TRUE;
  136. }
  137. BOOL WINAPI GetSystemInventoryW(INT type, LPWSTR szInventory)
  138. {
  139. /*char szInventory[1024];
  140. wszInventory[0] = 0;
  141. if (!GetSystemInventoryA(type, szInventory))
  142. return FALSE;
  143. if (type == INV_COPRECESSOR)
  144. {
  145. wszInventory[0] = szInventory[0];
  146. return TRUE;
  147. }
  148. if (szInventory[0] == 0)
  149. return TRUE;
  150. if (MultiByteToWideChar(CP_ACP,0,szInventory,-1,wszInventory,256) == 0)
  151. return FALSE;
  152. return TRUE;
  153. */
  154. szInventory[0] = _T('\0');
  155. switch (type)
  156. {
  157. case INV_OEM:
  158. GetOEMString(szInventory);
  159. return TRUE;
  160. case INV_PROCESSORTYPE:
  161. GetProcessorTypeString(szInventory);
  162. return TRUE;
  163. case INV_TOTALMEMORY:
  164. GetTotalMemoryString(szInventory);
  165. return TRUE;
  166. case INV_TOTALHDSPACE:
  167. GetTotalHardDiskSpaceString(szInventory);
  168. return TRUE;
  169. case INV_DISPRESOLUTION:
  170. GetDisplayResolutionString(szInventory);
  171. return TRUE;
  172. case INV_DISPCOLORDEPTH:
  173. GetDisplayColorDepthString(szInventory);
  174. return TRUE;
  175. case INV_WINVERSION:
  176. GetWindowsVersionString(szInventory);
  177. return TRUE;
  178. case INV_NETCARD:
  179. GetNetworkCardString(szInventory);
  180. return TRUE;
  181. case INV_MODEM:
  182. GetModemString(szInventory);
  183. return TRUE;
  184. case INV_POINTDEVICE:
  185. GetPointingDeviceString(szInventory);
  186. return TRUE;
  187. case INV_CDROM:
  188. GetCDRomString(szInventory);
  189. return TRUE;
  190. case INV_SOUNDCARD:
  191. GetSoundCardString(szInventory);
  192. return TRUE;
  193. case INV_REMOVEABLEMEDIA:
  194. GetRemoveableMediaString(szInventory);
  195. return TRUE;
  196. case INV_COPRECESSOR:
  197. szInventory[0] = IsCoProcessorAvailable() ? 1 : 0;
  198. szInventory[1] = 0;
  199. return TRUE;
  200. case INV_SCSIADAPTER :
  201. GetScsiAdapterString(szInventory);
  202. return TRUE;
  203. case INV_DISPLAY_ADAPTER:
  204. GetDisplayAdapter(szInventory);
  205. return TRUE;
  206. break;
  207. case INV_DISPLAY_WITH_RESOLUTION:
  208. GetDisplayAdapterWithResolution(szInventory);
  209. return TRUE;
  210. break;
  211. default:
  212. break;
  213. }
  214. return FALSE;
  215. }
  216. BOOL WINAPI GetSystemInventoryA(INT type, LPSTR szInventory)
  217. {
  218. BOOL bRet;
  219. int iMaxOutStrLen;
  220. ULONG ulNoOfChars;
  221. WCHAR wszInventory[1024];
  222. iMaxOutStrLen = 256;
  223. bRet = GetSystemInventoryW(type, wszInventory);
  224. if(wszInventory[0]) {
  225. ulNoOfChars = wcslen(wszInventory)+1;
  226. memset((void *) szInventory,0,iMaxOutStrLen);
  227. if(WideCharToMultiByte(CP_ACP,0,wszInventory,ulNoOfChars,szInventory,
  228. iMaxOutStrLen,NULL,NULL) == 0) {
  229. //dwError = GetLastError();
  230. //
  231. }
  232. }else {
  233. // if empty string
  234. szInventory[0] = '\0';
  235. }
  236. return bRet;
  237. }
  238. /***************************************************************************
  239. Returns TRUE if the file specified by the given pathname actually exists.
  240. ****************************************************************************/
  241. BOOL FileExists(LPTSTR szPathName)
  242. {
  243. SECURITY_ATTRIBUTES sa;
  244. HANDLE fileHandle;
  245. BOOL retValue;
  246. sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  247. sa.lpSecurityDescriptor = NULL;
  248. sa.bInheritHandle = TRUE;
  249. fileHandle = CreateFile(szPathName,GENERIC_READ,0,&sa,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  250. if (fileHandle == INVALID_HANDLE_VALUE)
  251. {
  252. retValue = FALSE;
  253. }
  254. else
  255. {
  256. retValue = TRUE;
  257. CloseHandle(fileHandle);
  258. }
  259. return retValue;
  260. }
  261. /*********************************************************************
  262. Returns a string containing the name of the Original Equipment
  263. Manufacturer.
  264. **********************************************************************/
  265. void GetOEMString(LPTSTR szOEM)
  266. {
  267. _TCHAR szPathName[512];
  268. DWORD oemLen;
  269. UINT pathLen = GetSystemDirectory(szPathName, 256);
  270. szOEM[0] = 0;
  271. if (pathLen > 0)
  272. {
  273. _TCHAR szIniName[256];
  274. LoadString(hInstance,IDS_OEM_INIFILE,szIniName,256);
  275. _tcscat(szPathName,_T("\\"));
  276. _tcscat(szPathName,szIniName);
  277. if (FileExists(szPathName))
  278. {
  279. _TCHAR szIniSection[64];
  280. _TCHAR szIniKey[64];
  281. _TCHAR szDefault[28];
  282. _TCHAR szModelTmp[128];
  283. LoadString(hInstance,IDS_OEM_INISECTION,szIniSection,64);
  284. LoadString(hInstance,IDS_OEM_INIKEY,szIniKey,64);
  285. szDefault[0] = 0;
  286. oemLen = GetPrivateProfileString(szIniSection,szIniKey,szDefault,szOEM,sizeof(szOEM)/sizeof(TCHAR),szPathName);
  287. LoadString(hInstance,IDS_OEM_INIKEY2,szIniKey,64);
  288. szDefault[0] = 0;
  289. oemLen = GetPrivateProfileString(szIniSection,szIniKey,szDefault,szModelTmp,sizeof(szModelTmp)/sizeof(TCHAR),szPathName);
  290. if(oemLen)
  291. {
  292. _tcscat(szOEM,_T(" ,"));
  293. _tcscat(szOEM,szModelTmp);
  294. }
  295. }
  296. }
  297. }
  298. /*********************************************************************
  299. Returns a string that describes the processor in the user's system:
  300. - "80386"
  301. - "80486"
  302. - "PENTIUM"
  303. - "INTEL860"
  304. - "MIPS_R2000"
  305. - "MIPS_R3000"
  306. - "MIPS_R4000"
  307. - "ALPHA_21064"
  308. Note: you must allocate at least 64 bytes for the buffer pointed to
  309. by the szProcessor parameter.
  310. **********************************************************************/
  311. void GetProcessorTypeString(LPTSTR szProcessor)
  312. {
  313. _TCHAR szTmp[256];
  314. _TCHAR szData[256];
  315. _TCHAR szString[256];
  316. HKEY hKey;
  317. LONG regStatus;
  318. DWORD dwInfoSize;
  319. SYSTEM_INFO systemInfo;
  320. GetSystemInfo(&systemInfo);
  321. szProcessor[0] = 0;
  322. if( PROCESSOR_ALPHA_21064 == systemInfo.dwProcessorType) {
  323. // Alpha
  324. // Default Value
  325. LoadString(hInstance, IDS_PROCESSOR_ALPHA_21064,szProcessor,64);
  326. // Try to get from Registry
  327. LoadString(hInstance, IDS_ALPHA_PROCESSOR,szTmp,256);
  328. regStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szTmp, 0, KEY_READ, &hKey);
  329. if (regStatus != ERROR_SUCCESS)
  330. return;
  331. dwInfoSize = 256;
  332. LoadString(hInstance, IDS_ALPHA_ARCHITECTURE, szString, 256);
  333. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szData, &dwInfoSize);
  334. _tcscpy(szProcessor, szData);
  335. _tcscat(szProcessor, _T(", "));
  336. dwInfoSize = 256;
  337. LoadString(hInstance, IDS_ALPHA_IDENTIFIER, szString, 256);
  338. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szData, &dwInfoSize);
  339. _tcscat(szProcessor, szData);
  340. RegCloseKey(hKey);
  341. }else {
  342. if (!GetProcessorTypeStringFromRegistry(szProcessor))
  343. GetProcessorTypeStringFromSystem(szProcessor);
  344. }
  345. }
  346. /*********************************************************************
  347. Returns a string that describes the processor in the user's system:
  348. - "80386"
  349. - "80486"
  350. - "PENTIUM"
  351. - "INTEL860"
  352. - "MIPS_R2000"
  353. - "MIPS_R3000"
  354. - "MIPS_R4000"
  355. - "ALPHA_21064"
  356. Note: you must allocate at least 64 bytes for the buffer pointed to
  357. by the szProcessor parameter.
  358. **********************************************************************/
  359. void GetProcessorTypeStringFromSystem(LPTSTR szProcessor)
  360. {
  361. SYSTEM_INFO systemInfo;
  362. GetSystemInfo(&systemInfo);
  363. switch (systemInfo.dwProcessorType)
  364. {
  365. case PROCESSOR_INTEL_386:
  366. LoadString(hInstance, IDS_PROCESSOR_386,szProcessor,64);
  367. break;
  368. case PROCESSOR_INTEL_486:
  369. LoadString(hInstance, IDS_PROCESSOR_486,szProcessor,64);
  370. break;
  371. case PROCESSOR_INTEL_PENTIUM:
  372. LoadString(hInstance, IDS_PROCESSOR_PENTIUM,szProcessor,64);
  373. break;
  374. /* case PROCESSOR_INTEL_860:
  375. LoadString(hInstance, IDS_PROCESSOR_860,szProcessor,64);
  376. break;
  377. case PROCESSOR_MIPS_R2000:
  378. LoadString(hInstance, IDS_PROCESSOR_MIPS_R2000,szProcessor,64);
  379. break;
  380. case PROCESSOR_MIPS_R3000:
  381. LoadString(hInstance, IDS_PROCESSOR_MIPS_R3000,szProcessor,64);
  382. break; */
  383. case PROCESSOR_MIPS_R4000:
  384. LoadString(hInstance, IDS_PROCESSOR_MIPS_R4000,szProcessor,64);
  385. break;
  386. case PROCESSOR_ALPHA_21064:
  387. LoadString(hInstance, IDS_PROCESSOR_ALPHA_21064,szProcessor,64);
  388. break;
  389. default:
  390. szProcessor[0] = 0;
  391. break;
  392. }
  393. }
  394. /*********************************************************************
  395. Retrieves the name of the processor in use from the Registry.
  396. Returns:
  397. FALSE if the proper key in the Registry does not exist.
  398. **********************************************************************/
  399. BOOL GetProcessorTypeStringFromRegistry(LPTSTR szProcessor)
  400. {
  401. HKEY hKey;
  402. _TCHAR uszRegKey[256];
  403. LONG regStatus;
  404. DWORD dwInfoSize;
  405. LoadString(hInstance, IDS_PROCESSOR_ENTRY, uszRegKey, 256);
  406. regStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uszRegKey, 0, KEY_READ, &hKey);
  407. if (regStatus != ERROR_SUCCESS)
  408. return FALSE;
  409. else
  410. {
  411. _TCHAR szData[256];
  412. _TCHAR szString[256];
  413. dwInfoSize = 256;
  414. LoadString(hInstance, IDS_CPU_VENDOR_ENTRY, szString, 256);
  415. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szData, &dwInfoSize);
  416. _tcscpy(szProcessor, szData);
  417. _tcscat(szProcessor, _T(", "));
  418. dwInfoSize = 256;
  419. LoadString(hInstance, IDS_CPU_ENTRY, szString, 256);
  420. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szData, &dwInfoSize);
  421. _tcscat(szProcessor, szData);
  422. RegCloseKey(hKey);
  423. }
  424. return TRUE;
  425. }
  426. /*********************************************************************
  427. Returns a string that describes the amount of physical RAM available.
  428. Note: you must allocate at least 64 bytes for the buffer pointed to
  429. by the szTotalMemory parameter.
  430. **********************************************************************/
  431. void GetTotalMemoryString(LPTSTR szTotalMemory)
  432. {
  433. _TCHAR szSuffix[32];
  434. MEMORYSTATUS memoryStatus;
  435. DWORD_PTR totalRam;
  436. memoryStatus.dwLength = sizeof(MEMORYSTATUS);
  437. GlobalMemoryStatus(&memoryStatus);
  438. totalRam = memoryStatus.dwTotalPhys / 1024;
  439. LoadString(hInstance, IDS_SIZE_SUFFIX1, szSuffix, 31);
  440. _stprintf(szTotalMemory, _T("%li %s"), totalRam, szSuffix);
  441. }
  442. /*********************************************************************
  443. Returns a string that describes the total amount of disk space
  444. (in KB) available on all hard disk drives attached to the user's
  445. system.
  446. Note: you must allocate at least 64 bytes for the buffer pointed to
  447. by the szTotalMemory parameter.
  448. **********************************************************************/
  449. void GetTotalHardDiskSpaceString(LPTSTR szTotalHardDiskSpace)
  450. {
  451. _TCHAR szSuffix[32];
  452. LONG totalHardDiskSpace = GetTotalHardDiskSpace();
  453. LoadString(hInstance, IDS_SIZE_SUFFIX1, szSuffix, 31);
  454. _stprintf(szTotalHardDiskSpace, _T("%li %s"), totalHardDiskSpace, szSuffix);
  455. }
  456. /*********************************************************************
  457. Returns a string that describes the horizontal x vertical resolution
  458. (in pixels) of the user's main screen.
  459. It also prefixes teh Display adapter Name
  460. **********************************************************************/
  461. void GetDisplayResolutionString(LPTSTR szDisplayResolution)
  462. {
  463. int horizResolution, vertResolution;
  464. int colorBits;
  465. DWORDLONG colorDepth;
  466. _TCHAR szSuffix[24];
  467. char czDispAdapter[256];
  468. szSuffix[0] = _T('\0'); //
  469. GetDisplayCharacteristics(&horizResolution, &vertResolution, NULL);
  470. // Color Depth
  471. GetDisplayCharacteristics(NULL,NULL,&colorBits);
  472. colorDepth = (DWORDLONG) 1 << colorBits;
  473. szSuffix[0] = 0;
  474. if (colorBits > 15)
  475. {
  476. colorDepth = colorDepth / 1024;
  477. LoadString(hInstance,IDS_SIZE_SUFFIX2,szSuffix,24);
  478. }
  479. _stprintf(szDisplayResolution, _T("%i x %i x %I64d%s"), horizResolution, vertResolution, colorDepth,szSuffix);
  480. }
  481. void GetDisplayAdapterWithResolution( LPTSTR szDisplayWithResolution)
  482. {
  483. TCHAR czDispAdapter[256];
  484. TCHAR czResolution[128];
  485. GetDisplayAdapter(czDispAdapter);
  486. GetDisplayResolutionString(czResolution);
  487. if(czDispAdapter[0] != _T('\0') ) {
  488. _tcscpy(szDisplayWithResolution,czDispAdapter);
  489. _tcscat(szDisplayWithResolution,_T(" "));
  490. _tcscat(szDisplayWithResolution,czResolution);
  491. }else {
  492. szDisplayWithResolution[0] = '\0';
  493. }
  494. }
  495. /*********************************************************************
  496. Returns a string that describes the color depth (number of colors
  497. available).
  498. // We are getting the
  499. **********************************************************************/
  500. void GetDisplayColorDepthString(LPTSTR szDisplayColorDepth)
  501. {
  502. int colorBits;
  503. LONG colorDepth;
  504. _TCHAR szSuffix[24];
  505. GetDisplayCharacteristics(NULL,NULL,&colorBits);
  506. colorDepth = 1 << colorBits;
  507. szSuffix[0] = 0;
  508. if (colorBits > 15)
  509. {
  510. colorDepth = colorDepth / 1024;
  511. LoadString(hInstance,IDS_SIZE_SUFFIX2,szSuffix,24);
  512. }
  513. _stprintf(szDisplayColorDepth,_T("%li%s"),colorDepth,szSuffix);
  514. }
  515. /*********************************************************************
  516. Returns a string describing the platform and verson of the currently
  517. operating Windows OS.
  518. **********************************************************************/
  519. void GetWindowsVersionString(LPTSTR szVersion)
  520. {
  521. LONG platform, majorVersion, minorVersion, dwBuildNo;
  522. _TCHAR szPlatform[64];
  523. _TCHAR szOsName[128];
  524. HKEY hKey;
  525. _TCHAR uszRegKey[256];
  526. LONG dwStatus;
  527. DWORD dwInfoSize;
  528. _TCHAR szBuildNo[64];
  529. _TCHAR szString[64];
  530. int idsPlatform;
  531. GetWindowsVersion(&platform, &majorVersion, &minorVersion, &dwBuildNo);
  532. if (platform == VER_PLATFORM_WIN32_WINDOWS)
  533. idsPlatform = IDS_PLATFORM_WIN95;
  534. else if (platform == VER_PLATFORM_WIN32_NT)
  535. idsPlatform = IDS_PLATFORM_WINNT;
  536. else
  537. idsPlatform = IDS_PLATFORM_WIN;
  538. if( idsPlatform == IDS_PLATFORM_WIN95)
  539. {
  540. _tcscpy(uszRegKey, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion"));
  541. dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uszRegKey, 0, KEY_READ, &hKey);
  542. if (dwStatus != ERROR_SUCCESS)
  543. LoadString(hInstance, idsPlatform, szPlatform, sizeof(szPlatform));
  544. else
  545. {
  546. dwInfoSize = 64;
  547. LoadString(hInstance, IDS_PRODUCT_NAME, szString, 64);
  548. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szPlatform, &dwInfoSize);
  549. dwInfoSize = 64;
  550. LoadString(hInstance, IDS_PRODUCT_VERSION, szString, 64);
  551. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szBuildNo,&dwInfoSize);
  552. RegCloseKey(hKey);
  553. }
  554. LoadString(hInstance,IDS_PRODUCT_VERSION_DISPLAY,szString,64);
  555. _tcscpy(szVersion,szPlatform);
  556. _tcscat(szVersion,szString);
  557. _tcscat(szVersion,szBuildNo);
  558. }
  559. else
  560. {
  561. // get OS name from Registry
  562. _tcscpy(uszRegKey, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"));
  563. dwStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, uszRegKey, 0, KEY_READ, &hKey);
  564. if (dwStatus == ERROR_SUCCESS) {
  565. dwInfoSize = 128;
  566. LoadString(hInstance, IDS_PRODUCT_NAME, szString, 64);
  567. RegQueryValueEx(hKey, szString, NULL, 0, (LPBYTE)szOsName, &dwInfoSize);
  568. RegCloseKey(hKey);
  569. }
  570. LoadString(hInstance,idsPlatform,szPlatform,sizeof(szPlatform));
  571. _stprintf(szVersion,szPlatform,szOsName,dwBuildNo);
  572. }
  573. }
  574. /*********************************************************************
  575. Returns a string describing the network card installed. If no card
  576. is installed, an empty string will be returned.
  577. **********************************************************************/
  578. void GetNetworkCardString(LPTSTR szNetwork)
  579. {
  580. sszDriverFilename[0] = _T('\0');
  581. GetSystemInformation(_T("net"), szNetwork, sszDriverFilename);
  582. _tcscpy(vrgchDynDesc[dynNet],szNetwork);
  583. }
  584. /*********************************************************************
  585. Returns a string describing the modem (if any) installed. If no modem
  586. is installed, an empty string will be returned.
  587. **********************************************************************/
  588. void GetModemString(LPTSTR szModem)
  589. {
  590. sszDriverFilename[0] = _T('\0');
  591. GetSystemInformation(_T("modem"), vrgchDynDesc[dynModem],sszDriverFilename);
  592. _tcscpy(szModem, vrgchDynDesc[dynModem]);
  593. }
  594. /*********************************************************************
  595. Returns a string describing all pointing devices (mouse, tablet, etc.)
  596. available.
  597. **********************************************************************/
  598. void GetPointingDeviceString(LPTSTR szPointingDevice)
  599. {
  600. TCHAR czTemp[256];
  601. sszDriverFilename[0] = _T('\0');
  602. GetSystemInformation(_T("mouse"),vrgchDynDesc[dynMouse], sszDriverFilename);
  603. _tcscpy(szPointingDevice,vrgchDynDesc[dynMouse]);
  604. if( sszDriverFilename[0] != _T('\0')) {
  605. // Copy the Driver file Name
  606. _stprintf(czTemp,_T(" (%s.sys) "),sszDriverFilename);
  607. _tcscat(szPointingDevice,czTemp);
  608. }
  609. _tcscpy(vrgchDynDesc[dynModem],szPointingDevice);
  610. }
  611. /*********************************************************************
  612. Returns a string describing any CD-Rom devices installed. If no
  613. CD-ROM device is installed, an empty string will be returned.
  614. **********************************************************************/
  615. void GetCDRomString(LPTSTR szCDRom)
  616. {
  617. sszDriverFilename[0] = _T('\0');
  618. GetSystemInformation(_T("cdrom"),vrgchDynDesc[dynCDRom],sszDriverFilename);
  619. _tcscpy(szCDRom,vrgchDynDesc[dynCDRom]);
  620. }
  621. /*********************************************************************
  622. Returns a string describing any sound card with driver installed. If none are
  623. installed, an empty string will be returned.
  624. **********************************************************************/
  625. void GetSoundCardString(LPTSTR szSoundCard)
  626. {
  627. TCHAR czTemp[256];
  628. sszDriverFilename[0] = _T('\0');
  629. GetSystemInformation(_T("media"),vrgchDynDesc[dynMedia],sszDriverFilename);
  630. _tcscpy(szSoundCard,vrgchDynDesc[dynMedia]);
  631. if( sszDriverFilename[0] != _T('\0')) {
  632. // Copy the Driver file Name
  633. _stprintf(czTemp,_T(" (%s.sys) "),sszDriverFilename);
  634. _tcscat(szSoundCard,czTemp);
  635. }
  636. _tcscpy(vrgchDynDesc[dynMedia],szSoundCard);
  637. }
  638. void GetDisplayAdapter( LPTSTR szDisplayAdapter)
  639. {
  640. TCHAR czTemp[256];
  641. sszDriverFilename[0] = _T('\0');
  642. GetSystemInformation(_T("Display"),szDisplayAdapter,sszDriverFilename);
  643. if( sszDriverFilename[0] != _T('\0')) {
  644. // Copy the Driver file Name
  645. _stprintf(czTemp,_T(" (%s.sys) "),sszDriverFilename);
  646. _tcscat(szDisplayAdapter,czTemp);
  647. }
  648. }
  649. /*
  650. Returns SCSI Adapter with Driver name persent in the system
  651. */
  652. void GetScsiAdapterString(LPTSTR szScsiAdapter)
  653. {
  654. TCHAR czTemp[256];
  655. sszDriverFilename[0] = _T('\0');
  656. GetSystemInformation(vrgchDynKey[dynSCSI],vrgchDynDesc[dynSCSI], sszDriverFilename);
  657. _tcscpy(szScsiAdapter,vrgchDynDesc[dynSCSI]);
  658. if( sszDriverFilename[0] != _T('\0')) {
  659. // Copy the Driver file Name
  660. _stprintf(czTemp,_T(" (%s.sys) "),sszDriverFilename);
  661. _tcscat(szScsiAdapter,czTemp);
  662. }
  663. _tcscpy(vrgchDynDesc[dynSCSI],szScsiAdapter);
  664. }
  665. /* Value -- > "CurrentDriveLetterAssignment" Data -- > "A"
  666. Value -- > "Removable" Data -- > 01
  667. Value -- > "Class" Data -- > "DiskDrive"*/
  668. #define REGFIND_ERROR 1
  669. #define REGFIND_RECURSE 2
  670. #define REGFIND_FINISH 3
  671. int RegFindValueInAllSubKey(HKEY key, LPCTSTR szSubKeyNameToFind, LPCTSTR szValueToFind, LPTSTR szIdentifier, int nType)
  672. {
  673. DWORD dwRet = ERROR_PATH_NOT_FOUND, dwIndex, dwSubkeyLen;
  674. TCHAR szSubKey[256], szFloppy[256];
  675. BOOL bType = FALSE, bRemovable = FALSE, bPrevMassStorage, bPrevFloppy;
  676. HKEY hKey;
  677. static BOOL bMassStorage = FALSE;
  678. static BOOL bFloppy = FALSE;
  679. bPrevMassStorage = bMassStorage;
  680. bPrevFloppy = bFloppy;
  681. if (szSubKeyNameToFind != NULL)
  682. dwRet = RegOpenKeyEx(key, szSubKeyNameToFind, 0, KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE, &hKey);
  683. if (dwRet == ERROR_SUCCESS)
  684. {
  685. dwIndex = 0;
  686. while (dwRet == ERROR_SUCCESS )
  687. {
  688. dwSubkeyLen = 256;
  689. dwRet = RegEnumKeyEx(hKey, dwIndex, szSubKey, &dwSubkeyLen,
  690. NULL, NULL, NULL, NULL);
  691. if (dwRet == ERROR_NO_MORE_ITEMS)
  692. {
  693. _TCHAR valueName[80];
  694. DWORD valueNameSize,valueSize,n = 0;
  695. TBYTE value[80];
  696. do
  697. {
  698. valueNameSize=80* sizeof(_TCHAR);
  699. valueSize=80* sizeof(TBYTE);
  700. dwRet = RegEnumValue(hKey, n, valueName, &valueNameSize,
  701. NULL, NULL, (LPBYTE)value, &valueSize);
  702. if (dwRet == ERROR_SUCCESS)
  703. {
  704. if (nType == 1)
  705. {
  706. if (!_tcscmp(valueName,_T("Type")))
  707. {
  708. if (!_tcscmp(szValueToFind,(LPCTSTR)value))
  709. bType = TRUE;
  710. }
  711. if (!_tcscmp(valueName,_T("Identifier")))
  712. _tcscpy(szIdentifier,(LPCTSTR)value);
  713. }
  714. else if(nType == 2)
  715. {
  716. if (!_tcscmp(valueName,_T("Class")))
  717. {
  718. if (!_tcscmp(szValueToFind,(LPCTSTR)value))
  719. bType = TRUE;
  720. }
  721. if (!_tcscmp(valueName,_T("DeviceDesc")))
  722. {
  723. // bFloppy and bMassStorage are used for handling the conditions when there are multiple
  724. // Floppy and mass storage media present.
  725. _tcscpy(szFloppy,(LPCTSTR)value);
  726. _tcsupr(szFloppy);
  727. if(_tcsstr(szFloppy,_T("FLOPPY")) != NULL)
  728. {
  729. if(!bFloppy)
  730. {
  731. _tcscpy(szFloppy,(LPCTSTR)value);
  732. bFloppy = TRUE;
  733. }
  734. }
  735. else
  736. // if it is not removable or it is a cdrom the condition for type and removable
  737. // takes care of it.
  738. {
  739. if(!bMassStorage)
  740. bMassStorage = TRUE;
  741. }
  742. }
  743. if (!_tcscmp(valueName,_T("Removable")))
  744. {
  745. if (*value == 0x01 )
  746. bRemovable = TRUE;
  747. }
  748. }
  749. n++;
  750. }
  751. } while (dwRet == ERROR_SUCCESS);
  752. if (nType == 1)
  753. {
  754. if(bType)
  755. return REGFIND_FINISH;
  756. else
  757. return REGFIND_RECURSE;
  758. }
  759. else if (nType == 2)
  760. {
  761. if( bType && bRemovable )
  762. {
  763. if (bFloppy != bPrevFloppy )
  764. _tcscpy(szIdentifier,szFloppy);
  765. if (bFloppy && bMassStorage)
  766. {
  767. _TCHAR szMassString[64];
  768. LoadString(hInstance,IDS_MASS_STRORAGE_ENTRY,szMassString,64);
  769. _tcscat(szIdentifier,szMassString);
  770. return REGFIND_FINISH;
  771. }
  772. return REGFIND_RECURSE;
  773. }
  774. // The bMassStorage flag has to be reset to the previous state.
  775. else
  776. {
  777. bMassStorage = bPrevMassStorage;
  778. if(bFloppy != bPrevFloppy)
  779. bFloppy = bPrevFloppy;
  780. return REGFIND_RECURSE;
  781. }
  782. }
  783. }
  784. else
  785. {
  786. if (dwRet == ERROR_SUCCESS)
  787. {
  788. int nStatus;
  789. nStatus = RegFindValueInAllSubKey(hKey, szSubKey, szValueToFind, szIdentifier, nType);
  790. switch(nStatus)
  791. {
  792. case REGFIND_FINISH:
  793. return REGFIND_FINISH;
  794. case REGFIND_ERROR:
  795. return REGFIND_ERROR;
  796. default :
  797. if (bFloppy != bPrevFloppy)
  798. bPrevFloppy = bFloppy;
  799. break;
  800. }
  801. dwIndex++;
  802. }
  803. }
  804. }
  805. RegCloseKey(hKey);
  806. }
  807. return REGFIND_ERROR;
  808. }
  809. /*********************************************************************
  810. Returns a string describing the capacity and format of removeable
  811. drives.
  812. **********************************************************************/
  813. void GetRemoveableMediaString(LPTSTR szRemoveableMedia)
  814. {
  815. LONG platform, majorVersion, minorVersion, dwBuildNo;
  816. GetWindowsVersion(&platform, &majorVersion, &minorVersion, &dwBuildNo);
  817. if (platform != VER_PLATFORM_WIN32_NT)
  818. {
  819. _TCHAR szSubKey[64];
  820. _TCHAR szSubKeyValue[64];
  821. LoadString(hInstance, IDS_REMOVABLE_MEDIA_ENTRY, szSubKey, 64);
  822. LoadString(hInstance, IDS_REMOVABLE_MEDIA_VALUE, szSubKeyValue, 64);
  823. RegFindValueInAllSubKey(HKEY_LOCAL_MACHINE,szSubKey,szSubKeyValue,szRemoveableMedia,2);
  824. }
  825. else
  826. {
  827. UINT driveType;
  828. _TCHAR szDrive[64];
  829. UINT nDrive;
  830. const iBufSize = 256;
  831. szRemoveableMedia[0] = 0;
  832. for (nDrive = 1; nDrive <= 26; nDrive++)
  833. {
  834. szDrive[0] = 0;
  835. driveType = GetDriveTypeInv(nDrive);
  836. switch (driveType)
  837. {
  838. case kDrive525_0360:
  839. LoadString(hInstance, IDS_DRV525_0360, szDrive, 64);
  840. break;
  841. case kDrive525_1200:
  842. LoadString(hInstance, IDS_DRV525_1200, szDrive, 64);
  843. break;
  844. case kDrive350_0720:
  845. LoadString(hInstance, IDS_DRV350_0720, szDrive, 64);
  846. break;
  847. case kDrive350_1440:
  848. LoadString(hInstance, IDS_DRV350_1440, szDrive, 64);
  849. break;
  850. case kDrive350_2880:
  851. LoadString(hInstance, IDS_DRV350_2880, szDrive, 64);
  852. break;
  853. }
  854. if (szDrive[0])
  855. {
  856. _TCHAR szFormattedDrive[70];
  857. int iNewStrLen;
  858. wsprintf(szFormattedDrive,_T("%c: %s"),_T('A') + nDrive - 1,szDrive);
  859. iNewStrLen = (_tcslen(szRemoveableMedia) +1+ _tcslen(szFormattedDrive) + 1);
  860. if (iNewStrLen < iBufSize)
  861. {
  862. if (szRemoveableMedia[0])
  863. _tcscat(szRemoveableMedia,_T(", ")); // We added 2 to iNewStrLen above to account to this
  864. _tcscat(szRemoveableMedia,szFormattedDrive);
  865. }
  866. }
  867. }
  868. }
  869. }
  870. /*********************************************************************
  871. Returns TRUE if a co-processor is installed in the user's system.
  872. **********************************************************************/
  873. BOOL IsCoProcessorAvailable(void)
  874. {
  875. EnumerateDynamicDevices();
  876. return vfIsFPUAvailable;
  877. }
  878. /**********************************************************************
  879. Determines the value associated with the specified Registration
  880. Database key and value name.
  881. Returns:
  882. The cb of the key data if successful, 0 otherwise.
  883. Notes:
  884. If hRootKey is NULL, HKEY_CLASSES_ROOT is used for the root
  885. ***********************************************************************/
  886. UINT GetRegKeyValue32(HKEY hRootKey, LPTSTR const cszcSubKey, LPTSTR const cszcValueName,
  887. PDWORD pdwType, PTBYTE pbData, UINT cbData )
  888. {
  889. HKEY hSubKey;
  890. LONG lErr;
  891. DWORD cbSize = (DWORD)cbData;
  892. if (hRootKey == NULL)
  893. hRootKey = HKEY_CLASSES_ROOT;
  894. lErr = RegOpenKeyEx(hRootKey, cszcSubKey, 0, KEY_READ, &hSubKey);
  895. if (lErr != ERROR_SUCCESS)
  896. {
  897. pdwType[0] = 0;
  898. return 0; /* Return 0 if the key doesn't exist */
  899. }
  900. lErr = RegQueryValueEx(hSubKey, (LPTSTR)cszcValueName, NULL, pdwType, (LPBYTE)pbData,
  901. &cbSize);
  902. RegCloseKey(hSubKey);
  903. if (lErr != ERROR_SUCCESS)
  904. {
  905. pdwType[0] = 0;
  906. return 0; /* Return 0 if the value doesn't exist */
  907. }
  908. return (UINT)cbSize;
  909. }
  910. /*********************************************************************
  911. Enumerates through the HKEY_DYN_DATA\Config Manager\Enum branch of
  912. the registry, and retrieves device information for all currently
  913. installed Net cards, modems, pointing devices, CDROMs, and sound
  914. cards. All this information is stored in the static vrgchDynDesc
  915. global array.
  916. **********************************************************************/
  917. void EnumerateDynamicDevices(void)
  918. {
  919. HKEY hKey;
  920. // Open the "HKEY_DYN_DATA\Config Manager\Enum" subkey.
  921. LONG regStatus = RegOpenKeyEx(HKEY_DYN_DATA, vrgchDynDataKey, 0, KEY_READ, &hKey);
  922. if (regStatus == ERROR_SUCCESS)
  923. {
  924. DWORD dwIndex = 0;
  925. _TCHAR rgchSubkey[256];
  926. _TCHAR rgchValue[256];
  927. DWORD dwSubkeySize;
  928. LONG lEnumErr;
  929. DWORD dwType;
  930. DWORD dwValueSize;
  931. do
  932. {
  933. // Enumerate "HKEY_DYN_DATA\Config Manager\Enum\Cxxxxxxx"
  934. FILETIME ftLastWrite;
  935. dwSubkeySize = sizeof(rgchSubkey);
  936. lEnumErr = RegEnumKeyEx(hKey, dwIndex++, rgchSubkey, &dwSubkeySize,
  937. NULL,NULL,NULL,&ftLastWrite);
  938. if (lEnumErr == ERROR_SUCCESS)
  939. {
  940. // From each subkey, read the value from the "HardWareKey" value name,
  941. // and make a new HKEY_LOCAL_MACHINE subkey out of it.
  942. dwValueSize = GetRegKeyValue32(hKey, rgchSubkey, vrgchHardWareKeyValueName, &dwType,
  943. (PTBYTE)rgchValue, sizeof(rgchValue) );
  944. if (dwValueSize > 0 && dwType == REG_SZ)
  945. {
  946. _TCHAR rgchDriverKey[256];
  947. wsprintf(rgchDriverKey,_T("%s\\%s"),vrgchLocalMachineEnumKey,rgchValue);
  948. // From our HKEY_LOCAL_MACHINE subkey, read the value from the "Driver"
  949. // value name.
  950. dwValueSize = GetRegKeyValue32(HKEY_LOCAL_MACHINE, rgchDriverKey, vrgchDriverValueName,
  951. &dwType, (PTBYTE) rgchValue, sizeof(rgchValue) );
  952. if (dwValueSize > 0 && dwType == REG_SZ)
  953. {
  954. // Get the "main" subkey out of the "driver" value (which is of the
  955. // form "<main>\xxxx").
  956. LPTSTR sz = rgchValue;
  957. WORD wDynIndex = 0;
  958. BOOL fMatch = FALSE;
  959. while (*sz && *sz != _T('\\'))
  960. sz = _tcsinc(sz);
  961. *sz = 0;
  962. // If the "main" subkey matches any of our desired device types,
  963. // we get the description of that device from the "DriverDesc"
  964. // name value field, and save it in our device array.
  965. while (wDynIndex < dynEnd && fMatch == FALSE)
  966. {
  967. if (vrgchDynDesc[wDynIndex][0] == 0)
  968. {
  969. if (_tcsicmp(vrgchDynKey[wDynIndex], rgchValue) == 0)
  970. {
  971. if (wDynIndex == dynSystem)
  972. {
  973. ProcessSystemDevices(rgchDriverKey);
  974. fMatch = TRUE;
  975. }
  976. else
  977. {
  978. dwValueSize = GetRegKeyValue32(HKEY_LOCAL_MACHINE,rgchDriverKey,
  979. vrgchDeviceDescValueName, &dwType, (PTBYTE) rgchValue,
  980. sizeof(rgchValue) );
  981. if (dwValueSize > 0 && dwType == REG_SZ)
  982. {
  983. if (wDynIndex != dynNet || _tcsicmp(vrgchDynNetExclusion,
  984. rgchValue) != 0)
  985. {
  986. // In case the description value is bigger than our
  987. // buffer, truncate it to fit.
  988. if (DYNDESC_BUFFERSIZE < sizeof(rgchValue))
  989. rgchValue[DYNDESC_BUFFERSIZE - (1*sizeof(_TCHAR))] = 0;
  990. _tcscpy(vrgchDynDesc[wDynIndex],rgchValue);
  991. fMatch = TRUE;
  992. }
  993. }
  994. }
  995. }
  996. }
  997. wDynIndex++;
  998. }
  999. }
  1000. }
  1001. }
  1002. }while (lEnumErr == ERROR_SUCCESS);
  1003. }
  1004. }
  1005. /*********************************************************************
  1006. Called when EnumerateDynamicDevices detects a "system" device (i.e.
  1007. a processor or FPU entry). The string passed in rgchSystemKey is the
  1008. name of the HKEY_LOCAL_MACHINE subkey under which the "system" device
  1009. was found.
  1010. **********************************************************************/
  1011. void ProcessSystemDevices(LPTSTR rgchSystemKey)
  1012. {
  1013. _TCHAR rgchValue[256];
  1014. DWORD dwType, dwValueSize;
  1015. // If we've got all the information we can use, we can bail out immediately
  1016. if (vfIsFPUAvailable == TRUE && vrgchDynProcessorName[0] != 0)
  1017. return;
  1018. dwValueSize = GetRegKeyValue32(HKEY_LOCAL_MACHINE, rgchSystemKey, vrgchHardwareIDValueName,
  1019. &dwType, (PTBYTE) rgchValue, sizeof(rgchValue));
  1020. if (dwValueSize > 0 && dwType == REG_SZ)
  1021. {
  1022. if (_tcsstr(rgchValue,_T("*PNP0C04")))
  1023. {
  1024. vfIsFPUAvailable = TRUE;
  1025. }
  1026. else if (_tcsstr(rgchValue,_T("*PNP0C01")))
  1027. {
  1028. dwValueSize = GetRegKeyValue32(HKEY_LOCAL_MACHINE,rgchSystemKey,_T("CPU"),&dwType,
  1029. (PTBYTE) vrgchDynProcessorName, sizeof(vrgchDynProcessorName) );
  1030. }
  1031. }
  1032. }
  1033. /*********************************************************************
  1034. Returns a LONG value representing the total amount of disk space
  1035. (in KB) available on all hard disk drives attached to the user's
  1036. system.
  1037. **********************************************************************/
  1038. LONG GetTotalHardDiskSpace(void)
  1039. {
  1040. _TCHAR szDrivesBuffer[256];
  1041. DWORD bufferLen = GetLogicalDriveStrings(256, szDrivesBuffer);
  1042. LPTSTR szDrive = szDrivesBuffer;
  1043. LONG totalHardDiskSpace = 0;
  1044. while (szDrive[0] != 0)
  1045. {
  1046. UINT driveType = GetDriveType(szDrive);
  1047. if (driveType == DRIVE_FIXED)
  1048. {
  1049. DWORD sectorsPerCluster;
  1050. DWORD bytesPerSector;
  1051. DWORD freeClusters;
  1052. DWORD clusters;
  1053. LONG kilobytesPerCluster;
  1054. if (GetDiskFreeSpace(szDrive,&sectorsPerCluster,&bytesPerSector,&freeClusters,&clusters))
  1055. {
  1056. kilobytesPerCluster = (bytesPerSector * sectorsPerCluster)/1024;
  1057. totalHardDiskSpace += kilobytesPerCluster * clusters;
  1058. }
  1059. }
  1060. szDrive += ((_tcslen(szDrive)+1) );
  1061. }
  1062. return totalHardDiskSpace;
  1063. }
  1064. /*********************************************************************
  1065. Returns the horizontal and vertical resolution (in pixels) of the
  1066. user's main screen, as well as the color depth (bits per pixel).
  1067. Note: NULL can be passed for any parameter that is not of interest.
  1068. **********************************************************************/
  1069. void GetDisplayCharacteristics(PINT lpHorizResolution, PINT lpVertResolution,PINT lpColorDepth)
  1070. {
  1071. HWND hwnd = GetDesktopWindow();
  1072. HDC hdc = GetDC(hwnd);
  1073. if (lpHorizResolution) *lpHorizResolution = GetDeviceCaps(hdc,HORZRES);
  1074. if (lpVertResolution) *lpVertResolution = GetDeviceCaps(hdc,VERTRES);
  1075. if (lpColorDepth) *lpColorDepth = GetDeviceCaps(hdc,BITSPIXEL);
  1076. ReleaseDC(hwnd,hdc);
  1077. }
  1078. /*********************************************************************
  1079. Returns integers representing the platform, major version number, and
  1080. minor version number of the currently running Windows OS.
  1081. Platform:
  1082. VER_PLATFORM_WIN32_NT: Windows NT
  1083. VER_PLATFORM_WIN32s: Win32s with Windows 3.1
  1084. VER_PLATFORM_WIN32_WINDOWS: Win32 on Windows 4.0 or later
  1085. Note: NULL can be passed for any parameter that is not of interest.
  1086. **********************************************************************/
  1087. void GetWindowsVersion(LONG* lpPlatform, LONG* lpMajorVersion,LONG* lpMinorVersion,LONG* lpBuildNo)
  1088. {
  1089. OSVERSIONINFO osvi;
  1090. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1091. GetVersionEx(&osvi);
  1092. if (lpMajorVersion) *lpMajorVersion = osvi.dwMajorVersion;
  1093. if (lpMinorVersion) *lpMinorVersion = osvi.dwMinorVersion;
  1094. if (lpPlatform) *lpPlatform = osvi.dwPlatformId;
  1095. if (lpBuildNo) *lpBuildNo = osvi.dwBuildNumber;
  1096. }
  1097. /*********************************************************************
  1098. For the disk drive specified by the nDrive parameter (1 = A, 2 = B,
  1099. etc), GetDriveTypeInv returns a code specifying the drive format. The
  1100. returned value will be one of the following:
  1101. driveSize:
  1102. - kDrive525_0360: 5.25", 360K floppy
  1103. - kDrive525_0720: 5.25", 720K floppy
  1104. - kDrive350_0720: 3.5", 720K floppy
  1105. - kDrive350_1440: 3.5", 1.4M floppy
  1106. - kDrive350_2880: 3.5", 2.88M floppy
  1107. - kDriveFixed: Hard disk, any size
  1108. - kDriveBadDrvNum: Bad drive number
  1109. **********************************************************************/
  1110. UINT GetDriveTypeInv(UINT nDrive)
  1111. {
  1112. DEVICEPARAMS deviceParams;
  1113. // Must initialize dpDevType, because if nDrive refers to a network
  1114. // drive or a drive letter with no volume attached, DeviceIOControl
  1115. // does not return an error - it just doesn't change .dpDevType at
  1116. // all.
  1117. deviceParams.dpDevType = kDriveBadDrvNum;
  1118. GetDeviceParameters(&deviceParams,nDrive);
  1119. return deviceParams.dpDevType;
  1120. }
  1121. /*********************************************************************
  1122. Returns a block of device parameters for the drive specified by the
  1123. nDrive parameter (a zero-based index).
  1124. **********************************************************************/
  1125. BOOL GetDeviceParameters(PDEVICEPARAMS pDeviceParams, UINT nDrive)
  1126. {
  1127. DEVIOCTL_REGISTERS reg;
  1128. reg.reg_EAX = 0x440D; /* IOCTL for block devices */
  1129. reg.reg_EBX = nDrive; /* zero-based drive ID */
  1130. reg.reg_ECX = 0x0860; /* Get Device Parameters command */
  1131. reg.reg_EDX = (DWORD_PTR) pDeviceParams; /* receives device parameters info */
  1132. if (!DoIOCTL(&reg))
  1133. return FALSE;
  1134. if (reg.reg_Flags & 0x8000) /* error if carry flag set */
  1135. return FALSE;
  1136. return TRUE;
  1137. }
  1138. /*********************************************************************
  1139. Performs an IOCTL (Int21h) call via the System virtual device driver.
  1140. **********************************************************************/
  1141. BOOL DoIOCTL(PDEVIOCTL_REGISTERS preg)
  1142. {
  1143. HANDLE hDevice;
  1144. BOOL fResult;
  1145. DWORD cb;
  1146. preg->reg_Flags = 0x8000; /* assume error (carry flag set) */
  1147. hDevice = CreateFile(_T("\\\\.\\vxdfile"),
  1148. GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
  1149. (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING,
  1150. FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);
  1151. if (hDevice == (HANDLE) INVALID_HANDLE_VALUE)
  1152. return FALSE;
  1153. else
  1154. {
  1155. fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL,
  1156. preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0);
  1157. if (!fResult)
  1158. return FALSE;
  1159. }
  1160. CloseHandle(hDevice);
  1161. return TRUE;
  1162. }
  1163. void GetSystemInformation(LPCTSTR szDeviceID, LPTSTR szDeviceName, LPTSTR szDriverName)
  1164. {
  1165. HDEVINFO hDevInfo;
  1166. DWORD dwMemberIndex = 0;
  1167. SP_DEVINFO_DATA DeviceInfoData;
  1168. DWORD dwPropertyRegDataType;
  1169. DWORD dwPropertyBufferSize = 256;
  1170. _TCHAR szPropertyBuffer[256];
  1171. DWORD dwRequiredSize;
  1172. DWORD dwReqSize;
  1173. DWORD dwError = 0;
  1174. DWORD dwClassGuidListSize = 256;
  1175. GUID ClassGuidList[256];
  1176. GUID * pGUID;
  1177. DWORD i;
  1178. _tcscpy(szPropertyBuffer,_T(""));
  1179. SetupDiClassGuidsFromName(szDeviceID, ClassGuidList, dwClassGuidListSize, &dwRequiredSize);
  1180. pGUID = ClassGuidList;
  1181. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  1182. for (i = 0; i < dwRequiredSize; i++)
  1183. {
  1184. hDevInfo = NULL;
  1185. hDevInfo = SetupDiGetClassDevs(pGUID++, NULL, NULL, DIGCF_PRESENT);
  1186. dwMemberIndex = 0;
  1187. do
  1188. {
  1189. BOOL bRet = SetupDiEnumDeviceInfo(hDevInfo, dwMemberIndex++, &DeviceInfoData);
  1190. if (bRet == TRUE)
  1191. {
  1192. bRet = SetupDiGetDeviceRegistryProperty
  1193. (hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC,
  1194. &dwPropertyRegDataType, /* optional */
  1195. (PBYTE)szPropertyBuffer, dwPropertyBufferSize,
  1196. &dwReqSize /* optional */
  1197. );
  1198. if(!_tcscmp(szDeviceID,_T("net")))
  1199. {
  1200. if(!_tcsnicmp(szPropertyBuffer,_T("Dial-Up"),7))
  1201. continue;
  1202. if(!_tcsnicmp(szPropertyBuffer,_T("Microsoft Virtual Private Networking"),36))
  1203. continue;
  1204. }
  1205. bRet = SetupDiGetDeviceRegistryProperty
  1206. (hDevInfo, &DeviceInfoData, SPDRP_SERVICE,
  1207. &dwPropertyRegDataType, /* optional */
  1208. (PBYTE)szDriverName, dwPropertyBufferSize,
  1209. &dwReqSize /* optional */
  1210. );
  1211. break;
  1212. }
  1213. else
  1214. dwError = GetLastError();
  1215. }
  1216. while( dwError != ERROR_NO_MORE_ITEMS);
  1217. if(hDevInfo != NULL) {
  1218. SetupDiDestroyDeviceInfoList(hDevInfo);
  1219. }
  1220. }
  1221. _tcscpy(szDeviceName,szPropertyBuffer);
  1222. }
  1223. #pragma optimize( _T(""), on )