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.

311 lines
8.7 KiB

  1. #include <windows.h>
  2. #include <setupapi.h>
  3. #define PNP_NEW_HW_PIPE TEXT("\\\\.\\pipe\\PNP_New_HW_Found")
  4. #define PNP_CREATE_PIPE_EVENT TEXT("PNP_Create_Pipe_Event")
  5. #define PNP_PIPE_TIMEOUT 180000
  6. typedef BOOL (WINAPI *FP_DEVINSTALLW)(HDEVINFO, PSP_DEVINFO_DATA);
  7. typedef HDEVINFO (WINAPI *FP_CREATEDEVICEINFOLIST)(LPGUID, HWND);
  8. typedef BOOL (WINAPI *FP_OPENDEVICEINFO)(HDEVINFO, PCWSTR, HWND, DWORD, PSP_DEVINFO_DATA);
  9. typedef BOOL (WINAPI *FP_DESTROYDEVICEINFOLIST)(HDEVINFO);
  10. typedef BOOL (WINAPI *FP_GETDEVICEINSTALLPARAMS)(HDEVINFO, PSP_DEVINFO_DATA, PSP_DEVINSTALL_PARAMS_W);
  11. typedef BOOL (WINAPI *FP_ENUMDEVICEINFO)(HDEVINFO, DWORD, PSP_DEVINFO_DATA);
  12. typedef INT (WINAPI *FP_PROMPTREBOOT)(HSPFILEQ, HWND, BOOL);
  13. VOID
  14. InstallNewHardware(
  15. IN HMODULE hSysSetup
  16. );
  17. int
  18. __cdecl
  19. main(
  20. IN int argc,
  21. IN char *argv[]
  22. )
  23. {
  24. BOOL NewSetup = TRUE, NewHardware = FALSE;
  25. INT i;
  26. HMODULE h = NULL;
  27. FARPROC p = NULL;
  28. CHAR FileName[MAX_PATH];
  29. //
  30. // Scan Command Line for -newsetup flag
  31. //
  32. for(i = 0; i < argc; i++) {
  33. if(argv[i][0] == '-') {
  34. if(!_stricmp(argv[i],"-newsetup")) {
  35. NewSetup = TRUE;
  36. } else if (!_stricmp(argv[i], "-plugplay")) {
  37. NewHardware = TRUE;
  38. } else if (!_stricmp(argv[i], "-asr")) {
  39. ; // do nothing
  40. } else if (!_stricmp(argv[i], "-asrquicktest")) {
  41. ; // do nothing
  42. } else if (!_stricmp(argv[i], "-mini")) {
  43. ; // do nothing
  44. } else
  45. return ERROR_INVALID_PARAMETER;
  46. }
  47. }
  48. //
  49. // Load the Appropriate Libary and function pointer
  50. //
  51. h = LoadLibrary("syssetup");
  52. if( h ){
  53. if (NewHardware) {
  54. InstallNewHardware(h);
  55. } else {
  56. //
  57. // Call the target function.
  58. //
  59. p=GetProcAddress(h,"InstallWindowsNt");
  60. if(p) {
  61. i = (int) p(argc,argv);
  62. }
  63. }
  64. }
  65. //
  66. // Make sure that the library goes away
  67. //
  68. while(h && GetModuleFileName(h,FileName,MAX_PATH)) {
  69. FreeLibrary(h);
  70. }
  71. return i;
  72. }
  73. VOID
  74. InstallNewHardware(
  75. IN HMODULE hSysSetup
  76. )
  77. {
  78. FP_DEVINSTALLW fpDevInstallW = NULL;
  79. FP_CREATEDEVICEINFOLIST fpCreateDeviceInfoList = NULL;
  80. FP_OPENDEVICEINFO fpOpenDeviceInfoW = NULL;
  81. FP_DESTROYDEVICEINFOLIST fpDestroyDeviceInfoList;
  82. FP_GETDEVICEINSTALLPARAMS fpGetDeviceInstallParams;
  83. FP_ENUMDEVICEINFO fpEnumDeviceInfo;
  84. FP_PROMPTREBOOT fpPromptReboot;
  85. HMODULE hSetupApi = NULL;
  86. WCHAR szBuffer[MAX_PATH];
  87. ULONG ulSize = 0, Index;
  88. HANDLE hPipe = INVALID_HANDLE_VALUE;
  89. HANDLE hEvent = NULL;
  90. HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
  91. SP_DEVINFO_DATA DeviceInfoData;
  92. SP_DEVINSTALL_PARAMS_W DeviceInstallParams;
  93. BOOL bReboot = FALSE;
  94. BOOL Status = FALSE;
  95. //
  96. // retrieve a proc address of the DevInstallW procedure in syssetup
  97. //
  98. if (!(fpDevInstallW =
  99. (FP_DEVINSTALLW)GetProcAddress(hSysSetup, "DevInstallW"))) {
  100. goto Clean0;
  101. }
  102. //
  103. // also load setupapi and retrieve following proc addresses
  104. //
  105. hSetupApi = LoadLibrary("setupapi");
  106. if (!(fpCreateDeviceInfoList =
  107. (FP_CREATEDEVICEINFOLIST)GetProcAddress(hSetupApi,
  108. "SetupDiCreateDeviceInfoList"))) {
  109. goto Clean0;
  110. }
  111. if (!(fpOpenDeviceInfoW =
  112. (FP_OPENDEVICEINFO)GetProcAddress(hSetupApi,
  113. "SetupDiOpenDeviceInfoW"))) {
  114. goto Clean0;
  115. }
  116. if (!(fpDestroyDeviceInfoList =
  117. (FP_DESTROYDEVICEINFOLIST)GetProcAddress(hSetupApi,
  118. "SetupDiDestroyDeviceInfoList"))) {
  119. goto Clean0;
  120. }
  121. if (!(fpGetDeviceInstallParams =
  122. (FP_GETDEVICEINSTALLPARAMS)GetProcAddress(hSetupApi,
  123. "SetupDiGetDeviceInstallParamsW"))) {
  124. goto Clean0;
  125. }
  126. if (!(fpEnumDeviceInfo =
  127. (FP_ENUMDEVICEINFO)GetProcAddress(hSetupApi,
  128. "SetupDiEnumDeviceInfo"))) {
  129. goto Clean0;
  130. }
  131. if (!(fpPromptReboot =
  132. (FP_PROMPTREBOOT)GetProcAddress(hSetupApi,
  133. "SetupPromptReboot"))) {
  134. goto Clean0;
  135. }
  136. //
  137. // open the event that will be used to signal the successful
  138. // creation of the named pipe (event should have been created
  139. // before I was called but if this process is started by anyone
  140. // else then it will go away now safely)
  141. //
  142. hEvent = OpenEvent(EVENT_MODIFY_STATE,
  143. FALSE,
  144. PNP_CREATE_PIPE_EVENT);
  145. if (hEvent == NULL) {
  146. goto Clean0;
  147. }
  148. //
  149. // create the named pipe, umpnpmgr will write requests to
  150. // this pipe if new hardware is found
  151. //
  152. hPipe = CreateNamedPipe(PNP_NEW_HW_PIPE,
  153. PIPE_ACCESS_INBOUND,
  154. PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
  155. 1, // only one connection
  156. MAX_PATH * sizeof(WCHAR), // out buffer size
  157. MAX_PATH * sizeof(WCHAR), // in buffer size
  158. PNP_PIPE_TIMEOUT, // default timeout
  159. NULL // default security
  160. );
  161. //
  162. // signal the event now, whether the pipe was successfully created
  163. // or not (don't keep userinit/cfgmgr32 waiting)
  164. //
  165. SetEvent(hEvent);
  166. if (hPipe == INVALID_HANDLE_VALUE) {
  167. goto Clean0;
  168. }
  169. //
  170. // connect to the newly created named pipe
  171. //
  172. if (ConnectNamedPipe(hPipe, NULL)) {
  173. //
  174. // create a devinfo handle and device info data set to
  175. // pass to DevInstall
  176. //
  177. if((hDevInfo = (fpCreateDeviceInfoList)(NULL, NULL))
  178. == INVALID_HANDLE_VALUE) {
  179. goto Clean0;
  180. }
  181. while (TRUE) {
  182. //
  183. // listen to the named pipe by submitting read
  184. // requests until the named pipe is broken on the
  185. // other end.
  186. //
  187. if (!ReadFile(hPipe,
  188. (LPBYTE)szBuffer, // device instance id
  189. MAX_PATH * sizeof(WCHAR),
  190. &ulSize,
  191. NULL)) {
  192. if (GetLastError() != ERROR_BROKEN_PIPE) {
  193. // Perhaps Log an Event
  194. }
  195. goto Clean0;
  196. }
  197. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  198. if(!(fpOpenDeviceInfoW)(hDevInfo, szBuffer, NULL, 0, &DeviceInfoData)) {
  199. goto Clean0;
  200. }
  201. //
  202. // call syssetup, DevInstallW
  203. //
  204. if ((fpDevInstallW)(hDevInfo, &DeviceInfoData)) {
  205. Status = TRUE; // at least one device installed successfully
  206. }
  207. }
  208. }
  209. Clean0:
  210. //
  211. // If at least one device was successfully installed, then determine
  212. // whether a reboot prompt is necessary.
  213. //
  214. if (Status && hDevInfo != INVALID_HANDLE_VALUE) {
  215. //
  216. // Enumerate each device that is associated with the device info set.
  217. //
  218. Index = 0;
  219. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  220. while ((fpEnumDeviceInfo)(hDevInfo,
  221. Index,
  222. &DeviceInfoData)) {
  223. //
  224. // Get device install params, keep track if any report needing
  225. // a reboot.
  226. //
  227. DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
  228. if ((fpGetDeviceInstallParams)(hDevInfo,
  229. &DeviceInfoData,
  230. &DeviceInstallParams)) {
  231. if ((DeviceInstallParams.Flags & DI_NEEDREBOOT) ||
  232. (DeviceInstallParams.Flags & DI_NEEDRESTART)) {
  233. bReboot = TRUE;
  234. }
  235. }
  236. Index++;
  237. }
  238. (fpDestroyDeviceInfoList)(hDevInfo);
  239. //
  240. // If any devices need reboot, prompt for reboot now.
  241. //
  242. if (bReboot) {
  243. (fpPromptReboot)(NULL, NULL, FALSE);
  244. }
  245. }
  246. if (hSetupApi != NULL) {
  247. FreeLibrary(hSetupApi);
  248. }
  249. if (hPipe != INVALID_HANDLE_VALUE) {
  250. DisconnectNamedPipe(hPipe);
  251. CloseHandle(hPipe);
  252. }
  253. if (hEvent != NULL) {
  254. CloseHandle(hEvent);
  255. }
  256. return;
  257. } // InstallNewHardware