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.

695 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation
  6. //
  7. // File: miscutil.c
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "HdwWiz.h"
  11. /* ----------------------------------------------------------------------
  12. * SetDlgText - Set Dialog Text Field
  13. *
  14. * Concatenates a number of string resources and does a SetWindowText()
  15. * for a dialog text control.
  16. *
  17. * Parameters:
  18. *
  19. * hDlg - Dialog handle
  20. * iControl - Dialog control ID to receive text
  21. * nStartString - ID of first string resource to concatenate
  22. * nEndString - ID of last string resource to concatenate
  23. *
  24. * Note: the string IDs must be consecutive.
  25. */
  26. void
  27. SetDlgText(HWND hDlg, int iControl, int nStartString, int nEndString)
  28. {
  29. int iX;
  30. TCHAR szText[MAX_PATH*4];
  31. szText[0] = '\0';
  32. for (iX = nStartString; iX<= nEndString; iX++) {
  33. LoadString(hHdwWiz,
  34. iX,
  35. szText + lstrlen(szText),
  36. SIZECHARS(szText) - lstrlen(szText)
  37. );
  38. }
  39. if (iControl) {
  40. SetDlgItemText(hDlg, iControl, szText);
  41. } else {
  42. SetWindowText(hDlg, szText);
  43. }
  44. }
  45. VOID
  46. HdwWizPropagateMessage(
  47. HWND hWnd,
  48. UINT uMessage,
  49. WPARAM wParam,
  50. LPARAM lParam
  51. )
  52. {
  53. while ((hWnd = GetWindow(hWnd, GW_CHILD)) != NULL) {
  54. SendMessage(hWnd, uMessage, wParam, lParam);
  55. }
  56. }
  57. LONG
  58. HdwBuildClassInfoList(
  59. PHARDWAREWIZ HardwareWiz,
  60. DWORD ClassListFlags
  61. )
  62. {
  63. LONG Error;
  64. while (!SetupDiBuildClassInfoListEx(ClassListFlags,
  65. HardwareWiz->ClassGuidList,
  66. HardwareWiz->ClassGuidSize,
  67. &HardwareWiz->ClassGuidNum,
  68. NULL,
  69. NULL
  70. )) {
  71. Error = GetLastError();
  72. if (HardwareWiz->ClassGuidList) {
  73. LocalFree(HardwareWiz->ClassGuidList);
  74. HardwareWiz->ClassGuidList = NULL;
  75. }
  76. if (Error == ERROR_INSUFFICIENT_BUFFER &&
  77. HardwareWiz->ClassGuidNum > HardwareWiz->ClassGuidSize) {
  78. HardwareWiz->ClassGuidList = LocalAlloc(LPTR, HardwareWiz->ClassGuidNum*sizeof(GUID));
  79. if (!HardwareWiz->ClassGuidList) {
  80. HardwareWiz->ClassGuidSize = 0;
  81. HardwareWiz->ClassGuidNum = 0;
  82. return ERROR_NOT_ENOUGH_MEMORY;
  83. }
  84. HardwareWiz->ClassGuidSize = HardwareWiz->ClassGuidNum;
  85. } else {
  86. if (HardwareWiz->ClassGuidList) {
  87. LocalFree(HardwareWiz->ClassGuidList);
  88. }
  89. HardwareWiz->ClassGuidSize = 0;
  90. HardwareWiz->ClassGuidNum = 0;
  91. return Error;
  92. }
  93. }
  94. return ERROR_SUCCESS;
  95. }
  96. int
  97. HdwMessageBox(
  98. HWND hWnd,
  99. LPTSTR szIdText,
  100. LPTSTR szIdCaption,
  101. UINT Type
  102. )
  103. {
  104. TCHAR szText[MAX_PATH];
  105. TCHAR szCaption[MAX_PATH];
  106. if (!HIWORD(szIdText)) {
  107. *szText = TEXT('\0');
  108. LoadString(hHdwWiz, LOWORD(szIdText), szText, MAX_PATH);
  109. szIdText = szText;
  110. }
  111. if (!HIWORD(szIdCaption)) {
  112. *szCaption = TEXT('\0');
  113. LoadString(hHdwWiz, LOWORD(szIdCaption), szCaption, MAX_PATH);
  114. szIdCaption = szCaption;
  115. }
  116. return MessageBox(hWnd, szIdText, szIdCaption, Type);
  117. }
  118. LONG
  119. HdwUnhandledExceptionFilter(
  120. struct _EXCEPTION_POINTERS *ExceptionPointers
  121. )
  122. {
  123. LONG lRet;
  124. BOOL BeingDebugged;
  125. lRet = UnhandledExceptionFilter(ExceptionPointers);
  126. BeingDebugged = IsDebuggerPresent();
  127. //
  128. // Normal code path is to handle the exception.
  129. // However, if a debugger is present, and the system's unhandled
  130. // exception filter returns continue search, we let it go
  131. // thru to allow the debugger a chance at it.
  132. //
  133. if (lRet == EXCEPTION_CONTINUE_SEARCH && !BeingDebugged) {
  134. lRet = EXCEPTION_EXECUTE_HANDLER;
  135. }
  136. return lRet;
  137. }
  138. BOOL
  139. NoPrivilegeWarning(
  140. HWND hWnd
  141. )
  142. /*++
  143. This function checks to see if the user is an Adminstrator
  144. If the user is NOT an Administrator then a warning is displayed telling
  145. them that they have insufficient privileges to install hardware on
  146. this machine.
  147. NOTE: In order for a user to install a driver then have to have the
  148. SE_LOAD_DRIVER_NAME privilege, as well as privilege to write to the registry
  149. and copy files into the system32\drivers directory
  150. Arguments
  151. hWnd - Parent window handle
  152. Return Value:
  153. TRUE if the user is NOT an adminstrator on this machine and
  154. FALSE if the user is an administrator on this machine.
  155. --*/
  156. {
  157. TCHAR szMsg[MAX_PATH];
  158. TCHAR szCaption[MAX_PATH];
  159. if (!pSetupIsUserAdmin()) {
  160. if (LoadString(hHdwWiz,
  161. IDS_HDWUNINSTALL_NOPRIVILEGE,
  162. szMsg,
  163. SIZECHARS(szMsg)) &&
  164. LoadString(hHdwWiz,
  165. IDS_HDWWIZNAME,
  166. szCaption,
  167. SIZECHARS(szCaption)))
  168. {
  169. MessageBox(hWnd, szMsg, szCaption, MB_OK | MB_ICONEXCLAMATION);
  170. }
  171. return TRUE;
  172. }
  173. return FALSE;
  174. }
  175. VOID
  176. _OnSysColorChange(
  177. HWND hWnd,
  178. WPARAM wParam,
  179. LPARAM lParam
  180. )
  181. {
  182. HWND hChildWnd;
  183. hChildWnd = GetWindow(hWnd, GW_CHILD);
  184. while (hChildWnd != NULL) {
  185. SendMessage(hChildWnd, WM_SYSCOLORCHANGE, wParam, lParam);
  186. hChildWnd = GetWindow(hChildWnd, GW_HWNDNEXT);
  187. }
  188. }
  189. void
  190. LoadText(
  191. PTCHAR szText,
  192. int SizeText,
  193. int nStartString,
  194. int nEndString
  195. )
  196. {
  197. int iX;
  198. for (iX = nStartString; iX<= nEndString; iX++) {
  199. LoadString(hHdwWiz,
  200. iX,
  201. szText + lstrlen(szText),
  202. SizeText - lstrlen(szText)
  203. );
  204. }
  205. return;
  206. }
  207. /* InstallFailedWarning
  208. *
  209. * Displays device install failed warning in a message box. For use
  210. * when device registration fails.
  211. *
  212. */
  213. void
  214. InstallFailedWarning(
  215. HWND hDlg,
  216. PHARDWAREWIZ HardwareWiz
  217. )
  218. {
  219. int len;
  220. TCHAR szMsg[MAX_MESSAGE_STRING];
  221. TCHAR szTitle[MAX_MESSAGE_TITLE];
  222. PTCHAR ErrorMsg;
  223. LoadString(hHdwWiz,
  224. IDS_ADDNEWDEVICE,
  225. szTitle,
  226. SIZECHARS(szTitle)
  227. );
  228. if ((len = LoadString(hHdwWiz, IDS_HDW_ERRORFIN1, szMsg, SIZECHARS(szMsg))) != 0) {
  229. LoadString(hHdwWiz, IDS_HDW_ERRORFIN2, szMsg+len, SIZECHARS(szMsg)-len);
  230. }
  231. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  232. NULL,
  233. HRESULT_FROM_SETUPAPI(HardwareWiz->LastError),
  234. 0,
  235. (LPTSTR)&ErrorMsg,
  236. 0,
  237. NULL
  238. ))
  239. {
  240. StringCchCat(szMsg, SIZECHARS(szMsg), TEXT("\n\n"));
  241. if ((lstrlen(szMsg) + lstrlen(ErrorMsg)) < SIZECHARS(szMsg)) {
  242. StringCchCat(szMsg, SIZECHARS(szMsg), ErrorMsg);
  243. }
  244. LocalFree(ErrorMsg);
  245. }
  246. MessageBox(hDlg, szMsg, szTitle, MB_OK | MB_TASKMODAL | MB_ICONEXCLAMATION);
  247. }
  248. void
  249. SetDriverDescription(
  250. HWND hDlg,
  251. int iControl,
  252. PHARDWAREWIZ HardwareWiz
  253. )
  254. {
  255. PTCHAR FriendlyName;
  256. SP_DRVINFO_DATA DriverInfoData;
  257. //
  258. // If there is a selected driver use its driver description,
  259. // since this is what the user is going to install.
  260. //
  261. DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
  262. if (SetupDiGetSelectedDriver(HardwareWiz->hDeviceInfo,
  263. &HardwareWiz->DeviceInfoData,
  264. &DriverInfoData
  265. )
  266. &&
  267. *DriverInfoData.Description) {
  268. StringCchCopy(HardwareWiz->DriverDescription,
  269. SIZECHARS(HardwareWiz->DriverDescription),
  270. DriverInfoData.Description);
  271. SetDlgItemText(hDlg, iControl, HardwareWiz->DriverDescription);
  272. return;
  273. }
  274. FriendlyName = BuildFriendlyName(HardwareWiz->DeviceInfoData.DevInst);
  275. if (FriendlyName) {
  276. SetDlgItemText(hDlg, iControl, FriendlyName);
  277. LocalFree(FriendlyName);
  278. return;
  279. }
  280. SetDlgItemText(hDlg, iControl, szUnknown);
  281. return;
  282. }
  283. HPROPSHEETPAGE
  284. CreateWizExtPage(
  285. int PageResourceId,
  286. DLGPROC pfnDlgProc,
  287. PHARDWAREWIZ HardwareWiz
  288. )
  289. {
  290. PROPSHEETPAGE psp;
  291. memset(&psp, 0, sizeof(psp));
  292. psp.dwSize = sizeof(PROPSHEETPAGE);
  293. psp.dwFlags = PSP_DEFAULT;
  294. psp.hInstance = hHdwWiz;
  295. psp.lParam = (LPARAM)HardwareWiz;
  296. psp.pszTemplate = MAKEINTRESOURCE(PageResourceId);
  297. psp.pfnDlgProc = pfnDlgProc;
  298. return CreatePropertySheetPage(&psp);
  299. }
  300. BOOL
  301. AddClassWizExtPages(
  302. HWND hwndParentDlg,
  303. PHARDWAREWIZ HardwareWiz,
  304. PSP_NEWDEVICEWIZARD_DATA DeviceWizardData,
  305. DI_FUNCTION InstallFunction
  306. )
  307. {
  308. DWORD NumPages;
  309. BOOL bRet = FALSE;
  310. memset(DeviceWizardData, 0, sizeof(SP_NEWDEVICEWIZARD_DATA));
  311. DeviceWizardData->ClassInstallHeader.InstallFunction = InstallFunction;
  312. DeviceWizardData->ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
  313. DeviceWizardData->hwndWizardDlg = hwndParentDlg;
  314. if (SetupDiSetClassInstallParams(HardwareWiz->hDeviceInfo,
  315. &HardwareWiz->DeviceInfoData,
  316. &DeviceWizardData->ClassInstallHeader,
  317. sizeof(SP_NEWDEVICEWIZARD_DATA)
  318. )
  319. &&
  320. (SetupDiCallClassInstaller(InstallFunction,
  321. HardwareWiz->hDeviceInfo,
  322. &HardwareWiz->DeviceInfoData
  323. )
  324. ||
  325. (ERROR_DI_DO_DEFAULT == GetLastError()))
  326. &&
  327. SetupDiGetClassInstallParams(HardwareWiz->hDeviceInfo,
  328. &HardwareWiz->DeviceInfoData,
  329. &DeviceWizardData->ClassInstallHeader,
  330. sizeof(SP_NEWDEVICEWIZARD_DATA),
  331. NULL
  332. )
  333. &&
  334. DeviceWizardData->NumDynamicPages)
  335. {
  336. NumPages = 0;
  337. while (NumPages < DeviceWizardData->NumDynamicPages) {
  338. PropSheet_AddPage(hwndParentDlg, DeviceWizardData->DynamicPages[NumPages++]);
  339. }
  340. bRet = TRUE;
  341. }
  342. //
  343. // Clear the class install parameters.
  344. //
  345. SetupDiSetClassInstallParams(HardwareWiz->hDeviceInfo,
  346. &HardwareWiz->DeviceInfoData,
  347. NULL,
  348. 0
  349. );
  350. return bRet;
  351. }
  352. void
  353. RemoveClassWizExtPages(
  354. HWND hwndParentDlg,
  355. PSP_NEWDEVICEWIZARD_DATA DeviceWizardData
  356. )
  357. {
  358. DWORD NumPages;
  359. NumPages = DeviceWizardData->NumDynamicPages;
  360. while (NumPages--) {
  361. PropSheet_RemovePage(hwndParentDlg,
  362. (WPARAM)-1,
  363. DeviceWizardData->DynamicPages[NumPages]
  364. );
  365. }
  366. memset(DeviceWizardData, 0, sizeof(SP_NEWDEVICEWIZARD_DATA));
  367. return;
  368. }
  369. BOOL
  370. IsDeviceHidden(
  371. PSP_DEVINFO_DATA DeviceInfoData
  372. )
  373. {
  374. BOOL bHidden = FALSE;
  375. ULONG DevNodeStatus, DevNodeProblem;
  376. HKEY hKeyClass;
  377. //
  378. // If the DN_NO_SHOW_IN_DM status bit is set
  379. // then we should hide this device.
  380. //
  381. if ((CM_Get_DevNode_Status(&DevNodeStatus,
  382. &DevNodeProblem,
  383. DeviceInfoData->DevInst,
  384. 0) == CR_SUCCESS) &&
  385. (DevNodeStatus & DN_NO_SHOW_IN_DM)) {
  386. bHidden = TRUE;
  387. goto HiddenDone;
  388. }
  389. //
  390. // If the devices class has the NoDisplayClass value then
  391. // don't display this device.
  392. //
  393. hKeyClass = SetupDiOpenClassRegKeyEx(&DeviceInfoData->ClassGuid,
  394. KEY_READ,
  395. DIOCR_INSTALLER,
  396. NULL,
  397. NULL);
  398. if (hKeyClass != INVALID_HANDLE_VALUE) {
  399. if (RegQueryValueEx(hKeyClass, REGSTR_VAL_NODISPLAYCLASS, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
  400. bHidden = TRUE;
  401. }
  402. RegCloseKey(hKeyClass);
  403. }
  404. HiddenDone:
  405. return bHidden;
  406. }
  407. DWORD
  408. SetPrivilegeAttribute(
  409. LPCTSTR PrivilegeName,
  410. DWORD NewPrivilegeAttribute,
  411. DWORD *OldPrivilegeAttribute
  412. )
  413. /*++
  414. sets the security attributes for a given privilege.
  415. Arguments:
  416. PrivilegeName - Name of the privilege we are manipulating.
  417. NewPrivilegeAttribute - The new attribute value to use.
  418. OldPrivilegeAttribute - Pointer to receive the old privilege value. OPTIONAL
  419. Return value:
  420. NO_ERROR or WIN32 error.
  421. --*/
  422. {
  423. LUID PrivilegeValue;
  424. TOKEN_PRIVILEGES TokenPrivileges, OldTokenPrivileges;
  425. DWORD ReturnLength;
  426. HANDLE TokenHandle;
  427. //
  428. // First, find out the LUID Value of the privilege
  429. //
  430. if (!LookupPrivilegeValue(NULL, PrivilegeName, &PrivilegeValue))
  431. {
  432. return GetLastError();
  433. }
  434. //
  435. // Get the token handle
  436. //
  437. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle))
  438. {
  439. return GetLastError();
  440. }
  441. //
  442. // Set up the privilege set we will need
  443. //
  444. TokenPrivileges.PrivilegeCount = 1;
  445. TokenPrivileges.Privileges[0].Luid = PrivilegeValue;
  446. TokenPrivileges.Privileges[0].Attributes = NewPrivilegeAttribute;
  447. ReturnLength = sizeof( TOKEN_PRIVILEGES );
  448. if (!AdjustTokenPrivileges (
  449. TokenHandle,
  450. FALSE,
  451. &TokenPrivileges,
  452. sizeof( TOKEN_PRIVILEGES ),
  453. &OldTokenPrivileges,
  454. &ReturnLength
  455. ))
  456. {
  457. CloseHandle(TokenHandle);
  458. return GetLastError();
  459. }
  460. else
  461. {
  462. if (OldPrivilegeAttribute != NULL)
  463. {
  464. *OldPrivilegeAttribute = OldTokenPrivileges.Privileges[0].Attributes;
  465. }
  466. CloseHandle(TokenHandle);
  467. return NO_ERROR;
  468. }
  469. }
  470. BOOL
  471. ShutdownMachine(
  472. HWND hWnd
  473. )
  474. {
  475. BOOL fOk;
  476. DWORD dwExitWinCode = EWX_SHUTDOWN;
  477. DWORD OldState;
  478. DWORD dwError;
  479. if (IsPwrShutdownAllowed()) {
  480. dwExitWinCode |= EWX_POWEROFF;
  481. }
  482. dwError = SetPrivilegeAttribute(SE_SHUTDOWN_NAME, SE_PRIVILEGE_ENABLED, &OldState);
  483. if (GetKeyState(VK_CONTROL) < 0) {
  484. dwExitWinCode |= EWX_FORCE;
  485. }
  486. fOk = ExitWindowsEx(dwExitWinCode, REASON_PLANNED_FLAG | REASON_HWINSTALL);
  487. //
  488. // If we were able to set the privilege, then reset it.
  489. //
  490. if (dwError == ERROR_SUCCESS) {
  491. SetPrivilegeAttribute(SE_SHUTDOWN_NAME, OldState, NULL);
  492. }
  493. else
  494. {
  495. //
  496. // Otherwise, if we failed, then it must have been some
  497. // security stuff.
  498. //
  499. if (!fOk)
  500. {
  501. TCHAR Title[MAX_PATH], Message[MAX_PATH];
  502. if (LoadString(hHdwWiz, IDS_NO_PERMISSION_SHUTDOWN, Message, SIZECHARS(Message)) &&
  503. LoadString(hHdwWiz, IDS_SHUTDOWN, Title, SIZECHARS(Title))) {
  504. MessageBox(hWnd, Message, Title, MB_OK | MB_ICONSTOP);
  505. }
  506. }
  507. }
  508. return fOk;
  509. }
  510. int
  511. DeviceProperties(
  512. HWND hWnd,
  513. DEVNODE DevNode,
  514. ULONG Flags
  515. )
  516. {
  517. TCHAR DeviceID[MAX_DEVICE_ID_LEN];
  518. PDEVICEPROPERTIESEX pDevicePropertiesEx = NULL;
  519. int iRet = 0;
  520. if (!hDevMgr) {
  521. return 0;
  522. }
  523. pDevicePropertiesEx = (PDEVICEPROPERTIESEX)GetProcAddress(hDevMgr, "DevicePropertiesExW");
  524. if (!pDevicePropertiesEx) {
  525. return 0;
  526. }
  527. if (CM_Get_Device_ID(DevNode,
  528. DeviceID,
  529. SIZECHARS(DeviceID),
  530. 0
  531. ) == CR_SUCCESS) {
  532. iRet = pDevicePropertiesEx(hWnd,
  533. NULL,
  534. (LPCSTR)DeviceID,
  535. Flags,
  536. FALSE);
  537. }
  538. return iRet;
  539. }
  540. #if DBG
  541. //
  542. // Debugging aids
  543. //
  544. void
  545. Trace(
  546. LPCTSTR format,
  547. ...
  548. )
  549. {
  550. // according to wsprintf specification, the max buffer size is
  551. // 1024
  552. TCHAR Buffer[1024];
  553. va_list arglist;
  554. va_start(arglist, format);
  555. StringCchVPrintf(Buffer, SIZECHARS(Buffer), format, arglist);
  556. va_end(arglist);
  557. OutputDebugString(TEXT("HDWWIZ: "));
  558. OutputDebugString(Buffer);
  559. OutputDebugString(TEXT("\n"));
  560. }
  561. #endif