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.

231 lines
6.5 KiB

  1. /*
  2. this program is based on the following information
  3. HOWTO: Enumerate Hardware Devices by Using SetupDi Calls
  4. ID: Q259695
  5. --------------------------------------------------------------------------------
  6. The information in this article applies to:
  7. Microsoft Windows 2000 Driver Development Kit (DDK)
  8. Microsoft Windows NT 4.0 Driver Development Kit (DDK)
  9. --------------------------------------------------------------------------------
  10. SUMMARY
  11. To get a list of installed hardware devices in Windows 2000, applications can employ the SetupDi class of API functions.
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <tchar.h> // Make program ansi AND unicode safe
  16. #include <windows.h> // Most Windows functions
  17. #include <setupapi.h> // Used for SetupDiXxx functions
  18. #include <cfgmgr32.h> // Used for CM_Xxxx functions
  19. #include <regstr.h> // Extract Registry Strings
  20. #include "devcfg.rc"
  21. void EnableDisableCard(BOOL bEnable, HDEVINFO hDevInfo, SP_DEVINFO_DATA * pDeviceInfoData)
  22. {
  23. SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)};
  24. //
  25. // Set the PropChangeParams structure.
  26. //
  27. PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
  28. PropChangeParams.Scope = DICS_FLAG_GLOBAL;
  29. if(bEnable) {
  30. PropChangeParams.StateChange = DICS_ENABLE;
  31. }
  32. else {
  33. PropChangeParams.StateChange = DICS_DISABLE;
  34. }
  35. if (!SetupDiSetClassInstallParams(hDevInfo,
  36. pDeviceInfoData,
  37. (SP_CLASSINSTALL_HEADER *)&PropChangeParams,
  38. sizeof(PropChangeParams)))
  39. {
  40. _tprintf(_T("failed SetClassInstallParams\n"));
  41. return;
  42. }
  43. //
  44. // Call the ClassInstaller and perform the change.
  45. // this function is not remote-callable
  46. if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE,
  47. hDevInfo,
  48. pDeviceInfoData))
  49. {
  50. _tprintf(_T("failed CallClassInstaller\n"));
  51. return;
  52. }
  53. _tprintf(_T("succeded\n"));
  54. }
  55. void Usage()
  56. {
  57. _tprintf(_T("\n"));
  58. _tprintf(_T("devcfg ") _T(VER_PRODUCTVERSION_STR) _T(" - Usage:\n\n"));
  59. _tprintf(_T(" devcfg [ <DeviceName> <e[nable]|d[isable]> [cardnumber] ]\n"));
  60. _tprintf(_T("\n"));
  61. _tprintf(_T(" without a parameter you'll get a list of all Devices\n"));
  62. _tprintf(_T(" installed on your computer (even the hidden ones).\n\n"));
  63. _tprintf(_T(" <DeviceName> must be a DeviceName as shown in the listmode\n"));
  64. _tprintf(_T(" (without the squarebraces), enclosed in quotation-marks(\"\")\n"));
  65. _tprintf(_T(" the default value for [number] is one (the first installed)\n"));
  66. _tprintf(_T("\n"));
  67. _tprintf(_T("Samples:\n"));
  68. _tprintf(_T(" devcfg\n"));
  69. _tprintf(_T(" shows all Devices installed on the machine and there status\n\n"));
  70. _tprintf(_T(" devcfg \"Card\" d\n"));
  71. _tprintf(_T(" disables the (first) installed \"Card\"\n\n"));
  72. _tprintf(_T(" devcfg \"Card\" e 2\n"));
  73. _tprintf(_T(" enables the second installed \"Card\"\n"));
  74. }
  75. //
  76. // standard main entry-point
  77. //
  78. int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  79. {
  80. HDEVINFO hDevInfo;
  81. SP_DEVINFO_DATA DeviceInfoData;
  82. DWORD i;
  83. BOOL bEnable;
  84. int iCardNumber = 1;
  85. if(argc == 2) // Usage
  86. {
  87. Usage();
  88. return 0;
  89. }
  90. if(argc == 3 || argc == 4) // enable/disable Card
  91. {
  92. if(_tcsicmp( argv[2],_T("e") ) == 0)
  93. bEnable = TRUE;
  94. else
  95. if(_tcsicmp( argv[2], _T("d") ) == 0)
  96. {
  97. bEnable = FALSE;
  98. }
  99. if(argc == 4) {
  100. iCardNumber = _ttoi( argv[3] );
  101. if(0 == iCardNumber)
  102. {
  103. _tprintf( _T("Error: The specified card-number is invalid.\n") );
  104. return 1;
  105. }
  106. }
  107. }
  108. // Create a HDEVINFO with all present devices.
  109. hDevInfo = SetupDiGetClassDevs(
  110. 0,
  111. 0,
  112. 0,
  113. DIGCF_PRESENT | DIGCF_ALLCLASSES
  114. );
  115. if (hDevInfo == INVALID_HANDLE_VALUE)
  116. {
  117. _tprintf( _T("SetupDiGetClassDevEx failed: %lx.\n"), GetLastError() );
  118. return 1;
  119. }
  120. // Enumerate through all devices in Set.
  121. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  122. for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,
  123. &DeviceInfoData);i++)
  124. {
  125. DWORD DataT, dwStatus1, dwStatus2;
  126. LPTSTR buffer = NULL;
  127. DWORD buffersize = 0;
  128. // Get status of device
  129. if(CR_SUCCESS != CM_Get_DevNode_Status(&dwStatus1,
  130. &dwStatus2,
  131. DeviceInfoData.DevInst, 0))
  132. {
  133. _tprintf( _T("CM_Get_DevNode_Status failed: %lx.\n"), GetLastError() );
  134. }
  135. //
  136. // Call function with null to begin with,
  137. // then use the returned buffer size
  138. // to Alloc the buffer. Keep calling until
  139. // success or an unknown failure.
  140. //
  141. while (!SetupDiGetDeviceRegistryProperty(
  142. hDevInfo,
  143. &DeviceInfoData,
  144. SPDRP_DEVICEDESC,
  145. &DataT,
  146. (PBYTE)buffer,
  147. buffersize,
  148. &buffersize))
  149. {
  150. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  151. {
  152. // Change the buffer size.
  153. if (buffer) LocalFree(buffer);
  154. buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);
  155. }
  156. else
  157. {
  158. // Insert error handling here.
  159. _tprintf( _T("SetupDiGetClassDevEx failed: %lx.\n"), GetLastError() );
  160. break;
  161. }
  162. }
  163. if(argc == 3 || argc == 4)
  164. {
  165. if(iCardNumber > 0 && _tcsicmp(argv[1],buffer) == 0)
  166. {
  167. if(iCardNumber == 1) {
  168. _tprintf(_T("working on: [%s]\n"),buffer);
  169. EnableDisableCard(bEnable, hDevInfo, &DeviceInfoData);
  170. }
  171. //else { _tprintf(_T("skipping: [%s]\n"),buffer); }
  172. --iCardNumber;
  173. }
  174. //else { _tprintf(_T("skipping: [%s]\n"),buffer); }
  175. }
  176. else
  177. {
  178. if(dwStatus2 == CM_PROB_DISABLED) {
  179. _tprintf(_T("Result:[%s] -- disabled\n"),buffer);
  180. }
  181. else if(dwStatus2) {
  182. _tprintf(_T("Result:[%s] -- unknown\n"),buffer);
  183. }
  184. else {
  185. _tprintf(_T("Result:[%s] -- enabled\n"),buffer);
  186. }
  187. }
  188. if (buffer) LocalFree(buffer);
  189. }
  190. if ( GetLastError()!=NO_ERROR &&
  191. GetLastError()!=ERROR_NO_MORE_ITEMS )
  192. {
  193. // Insert error handling here.
  194. _tprintf(_T("Unknown Error. GetLastError returned: %lx.\n"), GetLastError() );
  195. return 1;
  196. }
  197. // Cleanup
  198. SetupDiDestroyDeviceInfoList(hDevInfo);
  199. return 0;
  200. }