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

677 lines
25 KiB

  1. //
  2. // MyCfgMgr.cpp
  3. //
  4. // Config Manager functions, and simulations of config manager functions
  5. //
  6. // History:
  7. //
  8. // 1/13/2000 KenSh Created
  9. //
  10. #include "stdafx.h"
  11. #include "NetConn.h"
  12. #include "nconnwrap.h"
  13. #include "TheApp.h"
  14. // Define this if you want to use CFGMGR32.DLL (requires Win98 or later)
  15. //
  16. #define USE_CFGMGR32
  17. // Definitions used by config manager API's
  18. //
  19. // (Taken from Millennium\root\dev\ddk\inc\cfgmgr32.h -ks 1/13/2000)
  20. //
  21. #define CMAPI // DECLSPEC_IMPORT
  22. typedef DWORD RETURN_TYPE;
  23. typedef RETURN_TYPE CONFIGRET;
  24. #define CR_SUCCESS (0x00000000)
  25. #define CR_FAILURE (0x00000013)
  26. #ifndef USE_CFGMGR32
  27. // Internal Config Manager definitions
  28. //
  29. // (Taken from Millennium\root\pnp\dll\cfgmgr32\cm32api.h -ks 1/13/2000)
  30. //
  31. #define CM32_WARNS(_x_)
  32. #define CONFIGMG_W32IOCTL_RANGE 0x80000000
  33. #define CONFIGMG_DEVICE_ID 0x00033 /* Configuration manager (Plug&Play) */
  34. #define GetVxDServiceOrdinal(service) __##service
  35. #define Begin_Service_Table(device, seg) \
  36. enum device##_SERVICES { \
  37. device##_dummy = (device##_DEVICE_ID << 16) - 1,
  38. #define Declare_Service(service, local) \
  39. GetVxDServiceOrdinal(service),
  40. #define End_Service_Table(device, seg) \
  41. Num_##device##_Services};
  42. #define CONFIGMG_Service Declare_Service
  43. Begin_Service_Table(CONFIGMG, VxD)
  44. CONFIGMG_Service (_CONFIGMG_Get_Version, VxD_CODE)
  45. CONFIGMG_Service (_CONFIGMG_Initialize, VxD_CODE)
  46. CONFIGMG_Service (_CONFIGMG_Locate_DevNode, VxD_CODE)
  47. CONFIGMG_Service (_CONFIGMG_Get_Parent, VxD_CODE)
  48. CONFIGMG_Service (_CONFIGMG_Get_Child, VxD_CODE)
  49. CONFIGMG_Service (_CONFIGMG_Get_Sibling, VxD_CODE)
  50. CONFIGMG_Service (_CONFIGMG_Get_Device_ID_Size, VxD_CODE)
  51. CONFIGMG_Service (_CONFIGMG_Get_Device_ID, VxD_CODE)
  52. CONFIGMG_Service (_CONFIGMG_Get_Depth, VxD_CODE)
  53. CONFIGMG_Service (_CONFIGMG_Get_Private_DWord, VxD_CODE)
  54. CONFIGMG_Service (_CONFIGMG_Set_Private_DWord, VxD_CODE)
  55. CONFIGMG_Service (_CONFIGMG_Create_DevNode, VxD_CODE)
  56. CONFIGMG_Service (_CONFIGMG_Query_Remove_SubTree, VxD_CODE)
  57. CONFIGMG_Service (_CONFIGMG_Remove_SubTree, VxD_CODE)
  58. CONFIGMG_Service (_CONFIGMG_Register_Device_Driver, VxD_CODE)
  59. CONFIGMG_Service (_CONFIGMG_Register_Enumerator, VxD_CODE)
  60. CONFIGMG_Service (_CONFIGMG_Register_Arbitrator, VxD_CODE)
  61. CONFIGMG_Service (_CONFIGMG_Deregister_Arbitrator, VxD_CODE)
  62. CONFIGMG_Service (_CONFIGMG_Query_Arbitrator_Free_Size, VxD_CODE)
  63. CONFIGMG_Service (_CONFIGMG_Query_Arbitrator_Free_Data, VxD_CODE)
  64. CONFIGMG_Service (_CONFIGMG_Sort_NodeList, VxD_CODE)
  65. CONFIGMG_Service (_CONFIGMG_Yield, VxD_CODE)
  66. CONFIGMG_Service (_CONFIGMG_Lock, VxD_CODE)
  67. CONFIGMG_Service (_CONFIGMG_Unlock, VxD_CODE)
  68. CONFIGMG_Service (_CONFIGMG_Add_Empty_Log_Conf, VxD_CODE)
  69. CONFIGMG_Service (_CONFIGMG_Free_Log_Conf, VxD_CODE)
  70. CONFIGMG_Service (_CONFIGMG_Get_First_Log_Conf, VxD_CODE)
  71. CONFIGMG_Service (_CONFIGMG_Get_Next_Log_Conf, VxD_CODE)
  72. CONFIGMG_Service (_CONFIGMG_Add_Res_Des, VxD_CODE)
  73. CONFIGMG_Service (_CONFIGMG_Modify_Res_Des, VxD_CODE)
  74. CONFIGMG_Service (_CONFIGMG_Free_Res_Des, VxD_CODE)
  75. CONFIGMG_Service (_CONFIGMG_Get_Next_Res_Des, VxD_CODE)
  76. CONFIGMG_Service (_CONFIGMG_Get_Performance_Info, VxD_CODE)
  77. CONFIGMG_Service (_CONFIGMG_Get_Res_Des_Data_Size, VxD_CODE)
  78. CONFIGMG_Service (_CONFIGMG_Get_Res_Des_Data, VxD_CODE)
  79. CONFIGMG_Service (_CONFIGMG_Process_Events_Now, VxD_CODE)
  80. CONFIGMG_Service (_CONFIGMG_Create_Range_List, VxD_CODE)
  81. CONFIGMG_Service (_CONFIGMG_Add_Range, VxD_CODE)
  82. CONFIGMG_Service (_CONFIGMG_Delete_Range, VxD_CODE)
  83. CONFIGMG_Service (_CONFIGMG_Test_Range_Available, VxD_CODE)
  84. CONFIGMG_Service (_CONFIGMG_Dup_Range_List, VxD_CODE)
  85. CONFIGMG_Service (_CONFIGMG_Free_Range_List, VxD_CODE)
  86. CONFIGMG_Service (_CONFIGMG_Invert_Range_List, VxD_CODE)
  87. CONFIGMG_Service (_CONFIGMG_Intersect_Range_List, VxD_CODE)
  88. CONFIGMG_Service (_CONFIGMG_First_Range, VxD_CODE)
  89. CONFIGMG_Service (_CONFIGMG_Next_Range, VxD_CODE)
  90. CONFIGMG_Service (_CONFIGMG_Dump_Range_List, VxD_CODE)
  91. CONFIGMG_Service (_CONFIGMG_Load_DLVxDs, VxD_CODE)
  92. CONFIGMG_Service (_CONFIGMG_Get_DDBs, VxD_CODE)
  93. CONFIGMG_Service (_CONFIGMG_Get_CRC_CheckSum, VxD_CODE)
  94. CONFIGMG_Service (_CONFIGMG_Register_DevLoader, VxD_CODE)
  95. CONFIGMG_Service (_CONFIGMG_Reenumerate_DevNode, VxD_CODE)
  96. CONFIGMG_Service (_CONFIGMG_Setup_DevNode, VxD_CODE)
  97. CONFIGMG_Service (_CONFIGMG_Reset_Children_Marks, VxD_CODE)
  98. CONFIGMG_Service (_CONFIGMG_Get_DevNode_Status, VxD_CODE)
  99. CONFIGMG_Service (_CONFIGMG_Remove_Unmarked_Children, VxD_CODE)
  100. CONFIGMG_Service (_CONFIGMG_ISAPNP_To_CM, VxD_CODE)
  101. CONFIGMG_Service (_CONFIGMG_CallBack_Device_Driver, VxD_CODE)
  102. CONFIGMG_Service (_CONFIGMG_CallBack_Enumerator, VxD_CODE)
  103. CONFIGMG_Service (_CONFIGMG_Get_Alloc_Log_Conf, VxD_CODE)
  104. CONFIGMG_Service (_CONFIGMG_Get_DevNode_Key_Size, VxD_CODE)
  105. CONFIGMG_Service (_CONFIGMG_Get_DevNode_Key, VxD_CODE)
  106. CONFIGMG_Service (_CONFIGMG_Read_Registry_Value, VxD_CODE)
  107. CONFIGMG_Service (_CONFIGMG_Write_Registry_Value, VxD_CODE)
  108. CONFIGMG_Service (_CONFIGMG_Disable_DevNode, VxD_CODE)
  109. CONFIGMG_Service (_CONFIGMG_Enable_DevNode, VxD_CODE)
  110. CONFIGMG_Service (_CONFIGMG_Move_DevNode, VxD_CODE)
  111. CONFIGMG_Service (_CONFIGMG_Set_Bus_Info, VxD_CODE)
  112. CONFIGMG_Service (_CONFIGMG_Get_Bus_Info, VxD_CODE)
  113. CONFIGMG_Service (_CONFIGMG_Set_HW_Prof, VxD_CODE)
  114. CONFIGMG_Service (_CONFIGMG_Recompute_HW_Prof, VxD_CODE)
  115. CONFIGMG_Service (_CONFIGMG_Query_Change_HW_Prof, VxD_CODE)
  116. CONFIGMG_Service (_CONFIGMG_Get_Device_Driver_Private_DWord, VxD_CODE)
  117. CONFIGMG_Service (_CONFIGMG_Set_Device_Driver_Private_DWord, VxD_CODE)
  118. CONFIGMG_Service (_CONFIGMG_Get_HW_Prof_Flags, VxD_CODE)
  119. CONFIGMG_Service (_CONFIGMG_Set_HW_Prof_Flags, VxD_CODE)
  120. CONFIGMG_Service (_CONFIGMG_Read_Registry_Log_Confs, VxD_CODE)
  121. CONFIGMG_Service (_CONFIGMG_Run_Detection, VxD_CODE)
  122. CONFIGMG_Service (_CONFIGMG_Call_At_Appy_Time, VxD_CODE)
  123. CONFIGMG_Service (_CONFIGMG_Fail_Change_HW_Prof, VxD_CODE)
  124. CONFIGMG_Service (_CONFIGMG_Set_Private_Problem, VxD_CODE)
  125. CONFIGMG_Service (_CONFIGMG_Debug_DevNode, VxD_CODE)
  126. CONFIGMG_Service (_CONFIGMG_Get_Hardware_Profile_Info, VxD_CODE)
  127. CONFIGMG_Service (_CONFIGMG_Register_Enumerator_Function, VxD_CODE)
  128. CONFIGMG_Service (_CONFIGMG_Call_Enumerator_Function, VxD_CODE)
  129. CONFIGMG_Service (_CONFIGMG_Add_ID, VxD_CODE)
  130. CONFIGMG_Service (_CONFIGMG_Find_Range, VxD_CODE)
  131. CONFIGMG_Service (_CONFIGMG_Get_Global_State, VxD_CODE)
  132. CONFIGMG_Service (_CONFIGMG_Broadcast_Device_Change_Message, VxD_CODE)
  133. CONFIGMG_Service (_CONFIGMG_Call_DevNode_Handler, VxD_CODE)
  134. CONFIGMG_Service (_CONFIGMG_Remove_Reinsert_All, VxD_CODE)
  135. //
  136. // 4.0 OPK2 Services
  137. //
  138. CONFIGMG_Service (_CONFIGMG_Change_DevNode_Status, VxD_CODE)
  139. CONFIGMG_Service (_CONFIGMG_Reprocess_DevNode, VxD_CODE)
  140. CONFIGMG_Service (_CONFIGMG_Assert_Structure, VxD_CODE)
  141. CONFIGMG_Service (_CONFIGMG_Discard_Boot_Log_Conf, VxD_CODE)
  142. CONFIGMG_Service (_CONFIGMG_Set_Dependent_DevNode, VxD_CODE)
  143. CONFIGMG_Service (_CONFIGMG_Get_Dependent_DevNode, VxD_CODE)
  144. CONFIGMG_Service (_CONFIGMG_Refilter_DevNode, VxD_CODE)
  145. CONFIGMG_Service (_CONFIGMG_Merge_Range_List, VxD_CODE)
  146. CONFIGMG_Service (_CONFIGMG_Substract_Range_List, VxD_CODE)
  147. CONFIGMG_Service (_CONFIGMG_Set_DevNode_PowerState, VxD_CODE)
  148. CONFIGMG_Service (_CONFIGMG_Get_DevNode_PowerState, VxD_CODE)
  149. CONFIGMG_Service (_CONFIGMG_Set_DevNode_PowerCapabilities, VxD_CODE)
  150. CONFIGMG_Service (_CONFIGMG_Get_DevNode_PowerCapabilities, VxD_CODE)
  151. CONFIGMG_Service (_CONFIGMG_Read_Range_List, VxD_CODE)
  152. CONFIGMG_Service (_CONFIGMG_Write_Range_List, VxD_CODE)
  153. CONFIGMG_Service (_CONFIGMG_Get_Log_Conf_Priority, VxD_CODE)
  154. CONFIGMG_Service (_CONFIGMG_Support_Share_Irq, VxD_CODE)
  155. CONFIGMG_Service (_CONFIGMG_Get_Parent_Structure, VxD_CODE)
  156. //
  157. // 4.1 Services
  158. //
  159. CONFIGMG_Service (_CONFIGMG_Register_DevNode_For_Idle_Detection, VxD_CODE)
  160. CONFIGMG_Service (_CONFIGMG_CM_To_ISAPNP, VxD_CODE)
  161. CONFIGMG_Service (_CONFIGMG_Get_DevNode_Handler, VxD_CODE)
  162. CONFIGMG_Service (_CONFIGMG_Detect_Resource_Conflict, VxD_CODE)
  163. CONFIGMG_Service (_CONFIGMG_Get_Device_Interface_List, VxD_CODE)
  164. CONFIGMG_Service (_CONFIGMG_Get_Device_Interface_List_Size, VxD_CODE)
  165. CONFIGMG_Service (_CONFIGMG_Get_Conflict_Info, VxD_CODE)
  166. CONFIGMG_Service (_CONFIGMG_Add_Remove_DevNode_Property, VxD_CODE)
  167. CONFIGMG_Service (_CONFIGMG_CallBack_At_Appy_Time, VxD_CODE)
  168. CONFIGMG_Service (_CONFIGMG_Register_Device_Interface, VxD_CODE)
  169. CONFIGMG_Service (_CONFIGMG_System_Device_Power_State_Mapping, VxD_CODE)
  170. CONFIGMG_Service (_CONFIGMG_Get_Arbitrator_Info, VxD_CODE)
  171. CONFIGMG_Service (_CONFIGMG_Waking_Up_From_DevNode, VxD_CODE)
  172. CONFIGMG_Service (_CONFIGMG_Set_DevNode_Problem, VxD_CODE)
  173. CONFIGMG_Service (_CONFIGMG_Get_Device_Interface_Alias, VxD_CODE)
  174. End_Service_Table(CONFIGMG, VxD)
  175. //
  176. // struct pass to ConfigMG DeviceIOCTLs
  177. //
  178. // (Taken from Millennium\root\pnp\dll\cfgmgr32\cm32api.h -ks 1/13/2000)
  179. //
  180. struct _WIN32CMIOCTLPACKET {
  181. DWORD dwStack;
  182. DWORD dwServiceNumber;
  183. };
  184. typedef struct _WIN32CMIOCTLPACKET WIN32CMIOCTLPACKET;
  185. typedef WIN32CMIOCTLPACKET *PWIN32CMIOCTLPACKET;
  186. // call into ConfigMG using the handle we obtained at process_attach
  187. //
  188. // (Taken from Millennium\root\pnp\dll\cfgmgr32\cfgmgr32.c -ks 1/13/2000)
  189. //
  190. CONFIGRET static WINAPI WIN32CMIOCTLHandler(PWIN32CMIOCTLPACKET pPacket)
  191. {
  192. CONFIGRET crReturnValue = CR_FAILURE;
  193. DWORD dwReturnSize = 0;
  194. HANDLE hCONFIGMG;
  195. hCONFIGMG = CreateFile("\\\\.\\CONFIGMG",
  196. GENERIC_READ | GENERIC_WRITE,
  197. FILE_SHARE_READ | FILE_SHARE_WRITE,
  198. NULL, OPEN_EXISTING, 0, NULL);
  199. if (INVALID_HANDLE_VALUE == hCONFIGMG)
  200. {
  201. // MessageBox(NULL, "Could not get a handle to CONFIGMG.VXD returning CR_FAILURE!\n", "DEBUG", 0);
  202. CM32_WARNS(("Could not get a handle to CONFIGMG.VXD returning CR_FAILURE!\n"));
  203. return CR_FAILURE;
  204. }
  205. if (!DeviceIoControl(hCONFIGMG, pPacket->dwServiceNumber,
  206. &(pPacket->dwStack), sizeof(pPacket->dwStack),
  207. &crReturnValue, sizeof(crReturnValue), &dwReturnSize, NULL))
  208. {
  209. // char szDebug[1024];
  210. // wsprintf(szDebug, "ERROR: DeviceIoControl() failed with error 0x%X on service 0x%X\n",
  211. // GetLastError(), pPacket->dwServiceNumber);
  212. // MessageBox(NULL, szDebug, "DEBUG", 0);
  213. CM32_WARNS(("ERROR: DeviceIoControl() failed with error 0x%X on service 0x%X\n",
  214. GetLastError(), pPacket->dwServiceNumber));
  215. crReturnValue = CR_FAILURE;
  216. }
  217. if (dwReturnSize != sizeof(crReturnValue))
  218. {
  219. // char szDebug[1024];
  220. // wsprintf(szDebug, "ERROR: DeviceIoControl() only returned %d bytes, expected %d!\n",
  221. // dwReturnSize, sizeof(crReturnValue));
  222. // MessageBox(NULL, szDebug, "DEBUG", 0);
  223. CM32_WARNS(("ERROR: DeviceIoControl() only returned %d bytes, expected %d!\n",
  224. dwReturnSize, sizeof(crReturnValue)));
  225. crReturnValue = CR_FAILURE;
  226. }
  227. CloseHandle(hCONFIGMG);
  228. // {
  229. // char szDebug[1024];
  230. // wsprintf(szDebug, "WIN32CMIOCTLHandler returning with code 0x%08X", (LONG)crReturnValue);
  231. // MessageBox(NULL, szDebug, "DEBUG", 0);
  232. // }
  233. return(crReturnValue);
  234. }
  235. // CMWorker call ConfigMG on the original thread.
  236. //
  237. // (Taken from Millennium\root\pnp\dll\cfgmgr32\cfgmgr32.c -ks 1/13/2000)
  238. //
  239. CONFIGRET WINAPI CMWorker(DWORD dwStack, DWORD dwServiceNumber)
  240. {
  241. WIN32CMIOCTLPACKET Packet;
  242. Packet.dwStack = dwStack;
  243. Packet.dwServiceNumber = dwServiceNumber;
  244. return(WIN32CMIOCTLHandler(&Packet));
  245. }
  246. //
  247. // WORKER will call ConfigMG on the original thread which is much faster but cannot be used for services which require
  248. // configmg to do a system broadcast.
  249. //
  250. // (Taken from Millennium\root\pnp\dll\cfgmgr32\cfgmgr32.c -ks 1/13/2000)
  251. //
  252. #define WORKER(NAME) \
  253. \
  254. DWORD dwStack; \
  255. _asm {mov dwStack, ebp}; \
  256. dwStack+=8; \
  257. return(CMWorker(dwStack, CONFIGMG_W32IOCTL_RANGE+(GetVxDServiceOrdinal(_CONFIGMG_##NAME) & 0xFFFF)));
  258. #endif // !defined(USE_CFGMGR32)
  259. //////////////////////////////////////////////////////////////////////////////
  260. #define CM_DISABLE_POLITE (0x00000000) // Ask the driver
  261. #define CM_DISABLE_ABSOLUTE (0x00000001) // Don't ask the driver
  262. #define CM_DISABLE_HARDWARE (0x00000002) // Don't ask the driver, and won't be restarteable
  263. #define CM_DISABLE_BITS (0x00000003) // The bits for the disable function
  264. #define DN_ROOT_ENUMERATED (0x00000001) // Was enumerated by ROOT
  265. #define DN_DRIVER_LOADED (0x00000002) // Has Register_Device_Driver
  266. #define DN_ENUM_LOADED (0x00000004) // Has Register_Enumerator
  267. #define DN_STARTED (0x00000008) // Is currently configured
  268. #define DN_MANUAL (0x00000010) // Manually installed
  269. #define DN_NEED_TO_ENUM (0x00000020) // May need reenumeration
  270. #define DN_NOT_FIRST_TIME (0x00000040) // Has received a config
  271. #define DN_HARDWARE_ENUM (0x00000080) // Enum generates hardware ID
  272. #define DN_LIAR (0x00000100) // Lied about can reconfig once
  273. #define DN_HAS_MARK (0x00000200) // Not CM_Create_DevInst lately
  274. #define DN_HAS_PROBLEM (0x00000400) // Need device installer
  275. #define DN_FILTERED (0x00000800) // Is filtered
  276. #define DN_MOVED (0x00001000) // Has been moved
  277. #define DN_DISABLEABLE (0x00002000) // Can be rebalanced
  278. #define DN_REMOVABLE (0x00004000) // Can be removed
  279. #define DN_PRIVATE_PROBLEM (0x00008000) // Has a private problem
  280. #define DN_MF_PARENT (0x00010000) // Multi function parent
  281. #define DN_MF_CHILD (0x00020000) // Multi function child
  282. #define DN_WILL_BE_REMOVED (0x00040000) // DevInst is being removed
  283. #define CM_PROB_NOT_CONFIGURED 0x00000001
  284. #define CM_PROB_DEVLOADER_FAILED 0x00000002
  285. #define CM_PROB_OUT_OF_MEMORY 0x00000003
  286. #define CM_PROB_ENTRY_IS_WRONG_TYPE 0x00000004
  287. #define CM_PROB_LACKED_ARBITRATOR 0x00000005
  288. #define CM_PROB_BOOT_CONFIG_CONFLICT 0x00000006
  289. #define CM_PROB_FAILED_FILTER 0x00000007
  290. #define CM_PROB_DEVLOADER_NOT_FOUND 0x00000008
  291. #define CM_PROB_INVALID_DATA 0x00000009
  292. #define CM_PROB_FAILED_START 0x0000000A
  293. #define CM_PROB_LIAR 0x0000000B
  294. #define CM_PROB_NORMAL_CONFLICT 0x0000000C
  295. #define CM_PROB_NOT_VERIFIED 0x0000000D
  296. #define CM_PROB_NEED_RESTART 0x0000000E
  297. #define CM_PROB_REENUMERATION 0x0000000F
  298. #define CM_PROB_PARTIAL_LOG_CONF 0x00000010
  299. #define CM_PROB_UNKNOWN_RESOURCE 0x00000011
  300. #define CM_PROB_REINSTALL 0x00000012
  301. #define CM_PROB_REGISTRY 0x00000013
  302. #define CM_PROB_VXDLDR 0x00000014
  303. #define CM_PROB_WILL_BE_REMOVED 0x00000015
  304. #define CM_PROB_DISABLED 0x00000016
  305. #define CM_PROB_DEVLOADER_NOT_READY 0x00000017
  306. #define CM_PROB_DEVICE_NOT_THERE 0x00000018
  307. #define CM_PROB_MOVED 0x00000019
  308. #define CM_PROB_TOO_EARLY 0x0000001A
  309. #define CM_PROB_NO_VALID_LOG_CONF 0x0000001B
  310. #define CM_PROB_FAILED_INSTALL 0x0000001C
  311. #define CM_PROB_HARDWARE_DISABLED 0x0000001D
  312. #define CM_PROB_CANT_SHARE_IRQ 0x0000001E
  313. #define NUM_CM_PROB 0x0000001F
  314. //////////////////////////////////////////////////////////////////////////////
  315. //////////////////////////////////////////////////////////////////////////////
  316. extern "C" CMAPI CONFIGRET WINAPI CM_Get_DevNode_Status(
  317. OUT PULONG pulStatus,
  318. OUT PULONG pulProblemNumber,
  319. IN DEVINST dnDevInst,
  320. IN ULONG ulFlags
  321. )
  322. {
  323. #ifdef USE_CFGMGR32
  324. typedef CMAPI CONFIGRET (WINAPI * PROC_GetDevNodeStatus)(PULONG, PULONG, DEVINST, ULONG);
  325. CONFIGRET retval = CR_FAILURE;
  326. HINSTANCE hInstCfgMgr = LoadLibrary("cfgmgr32");
  327. if (hInstCfgMgr != NULL)
  328. {
  329. PROC_GetDevNodeStatus pfn = (PROC_GetDevNodeStatus)GetProcAddress(hInstCfgMgr, "CM_Get_DevNode_Status");
  330. if (pfn != NULL)
  331. {
  332. retval = (*pfn)(pulStatus, pulProblemNumber, dnDevInst, ulFlags);
  333. }
  334. FreeLibrary(hInstCfgMgr);
  335. }
  336. return retval;
  337. #else // !defined(USE_CFGMGR32)
  338. WORKER(Get_DevNode_Status)
  339. #endif
  340. }
  341. DWORD GetChildDevice(
  342. OUT DWORD* pdnChildInst,
  343. IN DWORD dnDevInst,
  344. IN OUT HINSTANCE* phInstance,
  345. IN ULONG ulFlags
  346. )
  347. {
  348. typedef CMAPI CONFIGRET (WINAPI * PFNGETCHILD)(DEVINST*, DEVINST, ULONG);
  349. CONFIGRET retval = CR_FAILURE;
  350. if ( NULL == *phInstance )
  351. {
  352. *phInstance = LoadLibrary("cfgmgr32");
  353. }
  354. if ( NULL != *phInstance )
  355. {
  356. PFNGETCHILD pfn = (PFNGETCHILD)GetProcAddress(*phInstance, "CM_Get_Child");
  357. if (pfn != NULL)
  358. {
  359. retval = (*pfn)(pdnChildInst, dnDevInst, ulFlags);
  360. }
  361. }
  362. return retval;
  363. }
  364. DWORD GetSiblingDevice(
  365. OUT DWORD* pdnChildInst,
  366. IN DWORD dnDevInst,
  367. IN HINSTANCE hInstance,
  368. IN ULONG ulFlags
  369. )
  370. {
  371. typedef CMAPI CONFIGRET (WINAPI * PFNGETSIBLING)(DEVINST*, DEVINST, ULONG);
  372. CONFIGRET retval = CR_FAILURE;
  373. if ( NULL != hInstance )
  374. {
  375. PFNGETSIBLING pfn = (PFNGETSIBLING)GetProcAddress(hInstance, "CM_Get_Sibling");
  376. if (pfn != NULL)
  377. {
  378. retval = (*pfn)(pdnChildInst, dnDevInst, ulFlags);
  379. }
  380. }
  381. return retval;
  382. }
  383. DWORD GetDevNodeRegistryPropertyA(
  384. IN DWORD dnDevInst,
  385. IN ULONG ulProperty,
  386. OUT PULONG pulRegDataType,
  387. OUT PVOID Buffer,
  388. IN OUT PULONG pulLength,
  389. IN ULONG ulFlags
  390. )
  391. {
  392. typedef CMAPI CONFIGRET (WINAPI * PFNGetDevNodeRegistryPropertyA)(DEVINST, ULONG, PULONG, PVOID, PULONG, ULONG);
  393. CONFIGRET retval = CR_FAILURE;
  394. HINSTANCE hInstCfgMgr = LoadLibrary("cfgmgr32");
  395. if (hInstCfgMgr != NULL)
  396. {
  397. PFNGetDevNodeRegistryPropertyA pfn = (PFNGetDevNodeRegistryPropertyA)GetProcAddress(hInstCfgMgr, "CM_Get_DevNode_Registry_PropertyA");
  398. if (pfn != NULL)
  399. {
  400. retval = (*pfn)(dnDevInst, ulProperty, pulRegDataType, Buffer, pulLength, ulFlags);
  401. }
  402. FreeLibrary(hInstCfgMgr);
  403. }
  404. return retval;
  405. }
  406. DWORD GetDeviceIdA(
  407. IN DWORD dnDevInst,
  408. OUT char** Buffer,
  409. OUT ULONG* pLength,
  410. IN ULONG ulFlags
  411. )
  412. {
  413. typedef CMAPI CONFIGRET (WINAPI * PFNGETDEVICEIDSIZE)(ULONG*, DEVINST, ULONG);
  414. typedef CMAPI CONFIGRET (WINAPI * PFNGETDEVICEID)(DEVINST, TCHAR*, ULONG, ULONG);
  415. CONFIGRET retval = CR_FAILURE;
  416. if ( Buffer ) *Buffer = NULL;
  417. if ( pLength ) *pLength = 0L;
  418. if ( Buffer && pLength )
  419. {
  420. HINSTANCE hInstCfgMgr = LoadLibrary("cfgmgr32");
  421. if (hInstCfgMgr != NULL)
  422. {
  423. PFNGETDEVICEIDSIZE pfn = (PFNGETDEVICEIDSIZE)GetProcAddress(hInstCfgMgr, "CM_Get_Device_ID_Size");
  424. if ( pfn )
  425. {
  426. ULONG ulLen = 0;
  427. retval = (*pfn)(&ulLen, dnDevInst, 0);
  428. if ( CR_SUCCESS == retval )
  429. {
  430. TCHAR* DeviceIdBuffer = new TCHAR[ ulLen ];
  431. retval = CR_FAILURE;
  432. if ( DeviceIdBuffer )
  433. {
  434. PFNGETDEVICEID pfnGet = (PFNGETDEVICEID)GetProcAddress(hInstCfgMgr, "CM_Get_Device_IDA");
  435. if ( pfnGet )
  436. {
  437. retval = (*pfnGet)(dnDevInst, DeviceIdBuffer, ulLen, ulFlags);
  438. if ( CR_SUCCESS == retval )
  439. {
  440. *Buffer = DeviceIdBuffer;
  441. *pLength = ulLen;
  442. }
  443. }
  444. if ( CR_SUCCESS != retval )
  445. {
  446. delete [] DeviceIdBuffer;
  447. }
  448. }
  449. }
  450. }
  451. FreeLibrary(hInstCfgMgr);
  452. }
  453. }
  454. return retval;
  455. }
  456. BOOL WINAPI IsNetAdapterBroken(const NETADAPTER* pAdapter)
  457. {
  458. BOOL bBroken = FALSE;
  459. DWORD dwStatus, dwProblemNumber;
  460. if (GetNetAdapterStatus(pAdapter, &dwStatus, &dwProblemNumber))
  461. {
  462. UINT nProblem = LOWORD(dwProblemNumber);
  463. if (nProblem != 0)
  464. bBroken = TRUE;
  465. }
  466. return bBroken;
  467. }
  468. BOOL WINAPI GetNetAdapterStatus(const NETADAPTER* pAdapter, DWORD* pdwStatus, DWORD* pdwProblemNumber)
  469. {
  470. BOOL bGotStatus = FALSE;
  471. DEVNODE dn = pAdapter->devnode;
  472. ULONG Status = 0L;
  473. ULONG Problem = 0L;
  474. if ( NULL != dn )
  475. {
  476. if ( CM_Get_DevNode_Status(&Status, &Problem, dn, 0) == CR_SUCCESS )
  477. {
  478. bGotStatus = TRUE;
  479. }
  480. else
  481. {
  482. Status = 0L;
  483. Problem = 0L;
  484. }
  485. }
  486. if ( pdwStatus ) *pdwStatus = Status;
  487. if ( pdwProblemNumber ) *pdwProblemNumber = Problem;
  488. return bGotStatus;
  489. }
  490. DWORD WINAPI GetNetAdapterDevNode(NETADAPTER* pAdapter)
  491. {
  492. HRESULT hr;
  493. DEVNODE dn;
  494. DWORD dwFreePointer;
  495. // REVIEW: this is not robust if there is more than one matching device
  496. hr = LookupDevNode16(NULL, _T("Net"), pAdapter->szEnumKey, &dn, &dwFreePointer);
  497. if ( SUCCEEDED(hr) )
  498. {
  499. pAdapter->devnode = dn;
  500. FreeDevNode16(dwFreePointer);
  501. }
  502. return dn;
  503. }
  504. HRESULT WINAPI RestartNetAdapter(DWORD devnode)
  505. {
  506. HRESULT hr = E_FAIL;
  507. typedef CMAPI CONFIGRET (WINAPI* PFNDISABLEDEVNODE)(DEVINST, ULONG);
  508. typedef CMAPI CONFIGRET (WINAPI* PFNENABLEDEVNODE)(DEVINST, ULONG);
  509. typedef CMAPI CONFIGRET (WINAPI* PFNGETDEVNODESTATUS)(PULONG, PULONG, DEVINST, ULONG);
  510. typedef CMAPI CONFIGRET (WINAPI* PFNGETGLOBALSTATE)(PULONG, ULONG);
  511. HINSTANCE hInstCfgMgr = LoadLibrary("cfgmgr32");
  512. if ( hInstCfgMgr )
  513. {
  514. PFNDISABLEDEVNODE pfnDisableDevnode =
  515. (PFNDISABLEDEVNODE)GetProcAddress(hInstCfgMgr, "CM_Disable_DevNode");
  516. PFNENABLEDEVNODE pfnEnableDevnode =
  517. (PFNDISABLEDEVNODE)GetProcAddress(hInstCfgMgr, "CM_Enable_DevNode");
  518. PFNGETDEVNODESTATUS pfnGetDevNodeStatus =
  519. (PFNGETDEVNODESTATUS)GetProcAddress(hInstCfgMgr, "CM_Get_DevNode_Status");
  520. PFNGETGLOBALSTATE pfnGetGlobalState =
  521. (PFNGETGLOBALSTATE)GetProcAddress(hInstCfgMgr, "CM_Get_Global_State");
  522. if ( pfnDisableDevnode && pfnEnableDevnode && pfnGetDevNodeStatus )
  523. {
  524. CONFIGRET retval;
  525. retval = (*pfnDisableDevnode)( devnode, CM_DISABLE_ABSOLUTE );
  526. if ( CR_SUCCESS == retval )
  527. {
  528. ULONG Status = 0L;
  529. ULONG Problem = 0L;
  530. ULONG TimeToWait = 60L;
  531. do
  532. {
  533. Sleep( 1000 );
  534. retval = (*pfnGetDevNodeStatus)( &Status, &Problem, devnode, 0 );
  535. }
  536. while ( (CR_SUCCESS == retval) && (CM_PROB_DISABLED != Problem) && (--TimeToWait) );
  537. if ( CR_SUCCESS == retval )
  538. {
  539. retval = pfnEnableDevnode( devnode, 0 );
  540. if ( CR_SUCCESS == retval )
  541. {
  542. TimeToWait = 60L;
  543. do
  544. {
  545. Sleep( 1000 );
  546. if ( pfnGetGlobalState )
  547. {
  548. retval = pfnGetGlobalState( &Status, 0 );
  549. }
  550. else
  551. {
  552. retval = (*pfnGetDevNodeStatus)( &Status, &Problem, devnode, 0 );
  553. }
  554. }
  555. while ( (CR_SUCCESS == retval) && (DN_HAS_PROBLEM & Status) && (--TimeToWait) );
  556. if ( CR_SUCCESS == retval )
  557. {
  558. hr = S_OK;
  559. }
  560. }
  561. }
  562. }
  563. }
  564. FreeLibrary( hInstCfgMgr );
  565. }
  566. return hr;
  567. }