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.

1009 lines
26 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001, Microsoft Corporation All rights reserved.
  4. //
  5. // Module Name:
  6. //
  7. // util.c
  8. //
  9. // Abstract:
  10. //
  11. // This file contains the accessory function of the euroconv.exe utility.
  12. //
  13. // Revision History:
  14. //
  15. // 2001-07-30 lguindon Created.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // Include Files.
  21. //
  22. ///////////////////////////////////////////////////////////////////////////////
  23. #include "euroconv.h"
  24. #include "util.h"
  25. ///////////////////////////////////////////////////////////////////////////////
  26. //
  27. // Global Variables.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. ///////////////////////////////////////////////////////////////////////////////
  31. //
  32. // AddExceptionOverride
  33. //
  34. // Add locale to the exception locale list. The memory referenced by elem
  35. // is initialized to zero so, don't worry to return something correct when
  36. // failling.
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. void AddExceptionOverride(PEURO_EXCEPTION elem, LPSTR strBuf)
  40. {
  41. LPSTR szLocale = NULL;
  42. LCID locale;
  43. LPSTR szSeparator = NULL;
  44. LPSTR szThouSeparator = NULL;
  45. LPSTR szDigits = NULL;
  46. BOOL bInsideQuote = FALSE;
  47. //
  48. // Change the separator used between each block in order to avoid
  49. // mistake with the data itself inside the double quote.
  50. //
  51. szLocale = strBuf;
  52. while (*szLocale)
  53. {
  54. if (*szLocale == '"')
  55. {
  56. bInsideQuote = bInsideQuote ? FALSE : TRUE;
  57. }
  58. else if (*szLocale == ',')
  59. {
  60. if (!bInsideQuote)
  61. {
  62. *szLocale = '#';
  63. }
  64. }
  65. szLocale++;
  66. }
  67. //
  68. // Scan the string and validate substrings
  69. //
  70. szLocale = strBuf;
  71. if (szSeparator = strchr(strBuf,'#'))
  72. {
  73. *szSeparator = '\0';
  74. szSeparator++;
  75. if (szDigits = strchr(szSeparator,'#'))
  76. {
  77. *szDigits = '\0';
  78. szDigits++;
  79. if (szThouSeparator = strchr(szDigits,'#'))
  80. {
  81. *szThouSeparator = '\0';
  82. szThouSeparator++;
  83. }
  84. else
  85. {
  86. return;
  87. }
  88. }
  89. else
  90. {
  91. return;
  92. }
  93. }
  94. else
  95. {
  96. return;
  97. }
  98. //
  99. // Remove quotes.
  100. //
  101. szLocale = RemoveQuotes(szLocale);
  102. szSeparator = RemoveQuotes(szSeparator);
  103. szDigits = RemoveQuotes(szDigits);
  104. szThouSeparator = RemoveQuotes(szThouSeparator);
  105. //
  106. // Check if the locale contains 0x in it.
  107. //
  108. if ((szLocale[0] == '0') && ((szLocale[1] == 'X') || (szLocale[1] == 'x')))
  109. {
  110. locale = (LCID)TransNum(szLocale+2); // skip 0x
  111. }
  112. else
  113. {
  114. locale = (LCID)TransNum(szLocale);
  115. }
  116. //
  117. // Validate
  118. //
  119. if ( IsValidLocale(locale, LCID_INSTALLED) &&
  120. (strlen(szSeparator) <= MAX_SMONDECSEP) &&
  121. (strlen(szDigits) <= MAX_ICURRDIGITS) &&
  122. (strlen(szThouSeparator) <= MAX_SMONTHOUSEP))
  123. {
  124. elem->dwLocale = locale;
  125. //strcpy(elem->chThousandSep, szThouSeparator);
  126. //strcpy(elem->chDecimalSep, szSeparator);
  127. //strcpy(elem->chDigits, szDigits);
  128. StringCbCopy(elem->chDigits, MAX_ICURRDIGITS + 1, szDigits);
  129. StringCbCopy(elem->chDecimalSep, MAX_SMONDECSEP + 1, szSeparator);
  130. StringCbCopy(elem->chThousandSep, MAX_SMONTHOUSEP + 1, szThouSeparator);
  131. }
  132. }
  133. ///////////////////////////////////////////////////////////////////////////////
  134. //
  135. // CleanUp
  136. //
  137. // Free memory represented by the handle.
  138. //
  139. ///////////////////////////////////////////////////////////////////////////////
  140. void CleanUp(HGLOBAL handle)
  141. {
  142. if (handle != NULL)
  143. {
  144. GlobalUnlock(handle);
  145. GlobalFree(handle);
  146. }
  147. }
  148. ///////////////////////////////////////////////////////////////////////////////
  149. //
  150. // IsAdmin
  151. //
  152. // Verify is the user has administrative rights.
  153. //
  154. ///////////////////////////////////////////////////////////////////////////////
  155. BOOL IsAdmin()
  156. {
  157. BOOL bRet = FALSE;
  158. HKEY hKey;
  159. //
  160. // No security on the registry for Windows 9x platfom.
  161. //
  162. if (IsWindows9x())
  163. {
  164. return (TRUE);
  165. }
  166. //
  167. // See if the user has Administrative privileges by checking for
  168. // write permission to the registry key.
  169. //
  170. if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  171. "System\\CurrentControlSet\\Control\\Nls",
  172. 0UL,
  173. KEY_WRITE,
  174. &hKey ) == ERROR_SUCCESS)
  175. {
  176. //
  177. // See if the user can write into the registry. Due to a registry
  178. // modification, we can open a registry key with write access and
  179. // be unable to write to the key... thanks to terminal server.
  180. //
  181. if (RegSetValueEx( hKey,
  182. "Test",
  183. 0UL,
  184. REG_SZ,
  185. (LPBYTE)"Test",
  186. (DWORD)(lstrlen("Test") + 1) * sizeof(TCHAR) ) == ERROR_SUCCESS)
  187. {
  188. //
  189. // Delete the value created.
  190. //
  191. RegDeleteValue(hKey, "Test");
  192. //
  193. // We can write to the HKEY_LOCAL_MACHINE key, so the user
  194. // has Admin privileges.
  195. //
  196. bRet = TRUE;
  197. }
  198. //
  199. // Clean up.
  200. //
  201. RegCloseKey(hKey);
  202. }
  203. //
  204. // Return the value
  205. //
  206. return (bRet);
  207. }
  208. ///////////////////////////////////////////////////////////////////////////////
  209. //
  210. // IsEuroPatchInstalled
  211. //
  212. // Verify if the Euro patch is installed. Check if the symbol for the Euro
  213. // currency is part of different locale.
  214. //
  215. ///////////////////////////////////////////////////////////////////////////////
  216. BOOL IsEuroPatchInstalled()
  217. {
  218. WCHAR baseStr[] = L"\x20AC";
  219. CHAR ansiStr[8] = {0};
  220. WCHAR retStr[8] = {0};
  221. #ifdef DEBUG
  222. //
  223. // Patch detection override
  224. //
  225. if (!gbPatchCheck)
  226. {
  227. return (TRUE);
  228. }
  229. #endif // DEBUG
  230. //
  231. // Convert the string to ANSI.
  232. //
  233. WideCharToMultiByte( 1252,
  234. WC_COMPOSITECHECK | WC_SEPCHARS,
  235. baseStr,
  236. -1,
  237. ansiStr,
  238. 8,
  239. NULL,
  240. NULL);
  241. //
  242. // Convert back the base string to Unicode.
  243. //
  244. MultiByteToWideChar( 1252,
  245. MB_PRECOMPOSED,
  246. ansiStr,
  247. 8,
  248. retStr,
  249. 8 );
  250. //
  251. // Compare if the result is the same.
  252. //
  253. if (_wcsicmp(retStr, baseStr) == 0)
  254. {
  255. return (TRUE);
  256. }
  257. //
  258. // Return default value.
  259. //
  260. return (FALSE);
  261. }
  262. ///////////////////////////////////////////////////////////////////////////////
  263. //
  264. // IsWindows9x
  265. //
  266. // Verify the operating system is Windows 9x.
  267. //
  268. ///////////////////////////////////////////////////////////////////////////////
  269. BOOL IsWindows9x()
  270. {
  271. //
  272. // Check if the value have been already initialized.
  273. //
  274. if (gdwVersion == (-1))
  275. {
  276. DWORD dwVersion = GetVersion();
  277. if(dwVersion >= 0x80000000)
  278. {
  279. //
  280. // GetVersion claims its Win9x, lets see if it is truthful.
  281. // (gets around App Compat stuff that would claim Win9x-ness).
  282. //
  283. if((INVALID_FILE_ATTRIBUTES == GetFileAttributesW(L"???.???")) &&
  284. (ERROR_INVALID_NAME == GetLastError()))
  285. {
  286. //
  287. // If GetFileAttributesW is functional, then it is *not* Win9x.
  288. // It could be any version of NT, we'll call it XP for grins since
  289. // it does not matter what kind of NT it is for our purposes.
  290. //
  291. dwVersion = 0x0A280105;
  292. }
  293. }
  294. //
  295. // Check for Windows 9x flavor
  296. //
  297. if (dwVersion >= 0x80000000)
  298. {
  299. gdwVersion = 1;
  300. }
  301. else
  302. {
  303. gdwVersion = 0;
  304. }
  305. }
  306. return (BOOL)gdwVersion;
  307. }
  308. ////////////////////////////////////////////////////////////////////////////
  309. //
  310. // ShowMsg
  311. //
  312. // Display an error message to the display.
  313. //
  314. ////////////////////////////////////////////////////////////////////////////
  315. int ShowMsg(HWND hDlg, UINT iMsg, UINT iTitle, UINT iType)
  316. {
  317. TCHAR szTitle[MAX_PATH] = {0};
  318. TCHAR szErrMsg[MAX_PATH*8] = {0};
  319. LPTSTR pTitle = NULL;
  320. if (iTitle)
  321. {
  322. if (LoadString(ghInstance, iTitle, szTitle, MAX_PATH))
  323. {
  324. pTitle = szTitle;
  325. }
  326. }
  327. if (LoadString(ghInstance, iMsg, szErrMsg, MAX_PATH*8))
  328. {
  329. return (MessageBox(hDlg, szErrMsg, pTitle, iType));
  330. }
  331. return (FALSE);
  332. }
  333. ////////////////////////////////////////////////////////////////////////////
  334. //
  335. // TransNum
  336. //
  337. // Converts a number string to a dword value (in hex).
  338. //
  339. ////////////////////////////////////////////////////////////////////////////
  340. DWORD TransNum(LPTSTR lpsz)
  341. {
  342. DWORD dw = 0L;
  343. TCHAR c;
  344. while (*lpsz)
  345. {
  346. c = *lpsz++;
  347. if (c >= TEXT('A') && c <= TEXT('F'))
  348. {
  349. c -= TEXT('A') - 0xa;
  350. }
  351. else if (c >= TEXT('0') && c <= TEXT('9'))
  352. {
  353. c -= TEXT('0');
  354. }
  355. else if (c >= TEXT('a') && c <= TEXT('f'))
  356. {
  357. c -= TEXT('a') - 0xa;
  358. }
  359. else
  360. {
  361. break;
  362. }
  363. dw *= 0x10;
  364. dw += c;
  365. }
  366. return (dw);
  367. }
  368. ////////////////////////////////////////////////////////////////////////////////////
  369. //
  370. // NextCommandArg
  371. //
  372. // pointing to next command argument (TEXT('-') or TEXT('/')
  373. //
  374. ////////////////////////////////////////////////////////////////////////////////////
  375. LPTSTR NextCommandArg(LPTSTR lpCmdLine)
  376. {
  377. LPTSTR strPtr=NULL;
  378. if(!lpCmdLine)
  379. {
  380. return (strPtr);
  381. }
  382. while(*lpCmdLine)
  383. {
  384. if ((*lpCmdLine == TEXT('-')) || (*lpCmdLine == TEXT('/')))
  385. {
  386. // Skip to the character after the '-','/'.
  387. strPtr = lpCmdLine + 1;
  388. break;
  389. }
  390. lpCmdLine++;
  391. }
  392. return (strPtr);
  393. }
  394. ////////////////////////////////////////////////////////////////////////////
  395. //
  396. // LoadHive
  397. //
  398. // The caller of this function needs to call UnloadHive() when
  399. // the function succeeds in order to properly release the handle on the
  400. // NTUSER.DAT file.
  401. //
  402. ////////////////////////////////////////////////////////////////////////////
  403. HKEY LoadHive(LPCTSTR szProfile, LPCTSTR lpRoot, LPCTSTR lpKeyName, BOOLEAN *lpWasEnabled)
  404. {
  405. HKEY hKey = NULL;
  406. LONG rc = 0L;
  407. BOOL bRet = TRUE;
  408. TCHAR szKeyName[REGSTR_MAX_VALUE_LENGTH] = {0};
  409. //
  410. // Set the value in the Default User hive.
  411. //
  412. rc = (*pfnRtlAdjustPrivilege)(SE_RESTORE_PRIVILEGE, TRUE, FALSE, lpWasEnabled);
  413. if (NT_SUCCESS(rc))
  414. {
  415. //
  416. // Load the hive and restore the privilege to its previous state.
  417. //
  418. rc = RegLoadKey(HKEY_USERS, lpRoot, szProfile);
  419. (*pfnRtlAdjustPrivilege)(SE_RESTORE_PRIVILEGE, *lpWasEnabled, FALSE, lpWasEnabled);
  420. //
  421. // If the hive loaded properly, set the value.
  422. //
  423. if (NT_SUCCESS(rc))
  424. {
  425. //
  426. // Get the temporary key name.
  427. //
  428. //sprintf(szKeyName, "%s\\%s", lpRoot, lpKeyName);
  429. StringCchPrintf(szKeyName, ARRAYSIZE(szKeyName), "%s\\%s", lpRoot, lpKeyName);
  430. if ((rc = RegOpenKeyEx( HKEY_USERS,
  431. szKeyName,
  432. 0L,
  433. KEY_READ | KEY_WRITE,
  434. &hKey )) == ERROR_SUCCESS)
  435. {
  436. return (hKey);
  437. }
  438. else
  439. {
  440. UnloadHive(lpRoot, lpWasEnabled);
  441. return (NULL);
  442. }
  443. }
  444. }
  445. return (NULL);
  446. }
  447. ////////////////////////////////////////////////////////////////////////////
  448. //
  449. // UnloadHive
  450. //
  451. ////////////////////////////////////////////////////////////////////////////
  452. void UnloadHive( LPCTSTR lpRoot, BOOLEAN *lpWasEnabled)
  453. {
  454. if (NT_SUCCESS((*pfnRtlAdjustPrivilege)( SE_RESTORE_PRIVILEGE,
  455. TRUE,
  456. FALSE,
  457. lpWasEnabled )))
  458. {
  459. RegUnLoadKey(HKEY_USERS, lpRoot);
  460. (*pfnRtlAdjustPrivilege)( SE_RESTORE_PRIVILEGE,
  461. *lpWasEnabled,
  462. FALSE,
  463. lpWasEnabled );
  464. }
  465. }
  466. ///////////////////////////////////////////////////////////////////////////////
  467. //
  468. // LoadLibraries
  469. //
  470. // Load libraries specifically used on Windows NTx for the default users case.
  471. //
  472. ///////////////////////////////////////////////////////////////////////////////
  473. BOOL LoadLibraries()
  474. {
  475. //
  476. // Load the userenv.dll library.
  477. //
  478. if (!hUserenvDLL)
  479. {
  480. hUserenvDLL = LoadLibrary("userenv.dll");
  481. }
  482. //
  483. // Initialize functions from the userenv.dll.
  484. //
  485. if (hUserenvDLL)
  486. {
  487. //
  488. // Initialize Install function.
  489. //
  490. pfnGetProfilesDirectory = (BOOL (*)(LPSTR, LPDWORD))
  491. GetProcAddress(hUserenvDLL, "GetProfilesDirectoryA");
  492. }
  493. else
  494. {
  495. return (FALSE);
  496. }
  497. //
  498. // Load the user32.dll library.
  499. //
  500. if (!hUser32DLL)
  501. {
  502. hUser32DLL = LoadLibrary("user32.dll");
  503. }
  504. //
  505. // Initialize functions from the user32.dll.
  506. //
  507. if (hUser32DLL)
  508. {
  509. //
  510. // Initialize Install function.
  511. //
  512. pfnBroadcastSystemMessage = (long (*)(DWORD, LPDWORD, UINT, WPARAM, LPARAM))
  513. GetProcAddress(hUser32DLL, "BroadcastSystemMessageA");
  514. }
  515. else
  516. {
  517. return (FALSE);
  518. }
  519. //
  520. // Load the ntdll.dll library.
  521. //
  522. if (!hNtdllDLL)
  523. {
  524. hNtdllDLL = LoadLibrary("ntdll.dll");
  525. }
  526. //
  527. // Initialize functions from the userenv.dll.
  528. //
  529. if (hNtdllDLL)
  530. {
  531. //
  532. // Initialize Install function.
  533. //
  534. pfnRtlAdjustPrivilege = (LONG (*)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN))
  535. GetProcAddress(hNtdllDLL, "RtlAdjustPrivilege");
  536. }
  537. else
  538. {
  539. return (FALSE);
  540. }
  541. return (TRUE);
  542. }
  543. ///////////////////////////////////////////////////////////////////////////////
  544. //
  545. // UnloadLibraries
  546. //
  547. // Unload used libraries.
  548. //
  549. ///////////////////////////////////////////////////////////////////////////////
  550. void UnloadLibraries()
  551. {
  552. //
  553. // Unload the userenv.dll library.
  554. //
  555. if (hUserenvDLL)
  556. {
  557. FreeLibrary(hUserenvDLL);
  558. hUserenvDLL = NULL;
  559. pfnGetProfilesDirectory = NULL;
  560. }
  561. //
  562. // Unload the user32.dll library.
  563. //
  564. if (hUser32DLL)
  565. {
  566. FreeLibrary(hUser32DLL);
  567. hUser32DLL = NULL;
  568. pfnBroadcastSystemMessage = NULL;
  569. }
  570. //
  571. // Unload the ntdll.dll library.
  572. //
  573. if (hNtdllDLL)
  574. {
  575. FreeLibrary(hNtdllDLL);
  576. hNtdllDLL = NULL;
  577. pfnRtlAdjustPrivilege = NULL;
  578. }
  579. }
  580. ///////////////////////////////////////////////////////////////////////////////
  581. //
  582. // GetDocumentAndSettingsFolder
  583. //
  584. // Return the Document and Settings folder.
  585. //
  586. ///////////////////////////////////////////////////////////////////////////////
  587. BOOL GetDocumentAndSettingsFolder(LPSTR buffer)
  588. {
  589. DWORD cchDir = MAX_PATH;
  590. if (IsWindows9x())
  591. {
  592. //
  593. // Not applicable.
  594. //
  595. buffer[0] = '\0';
  596. return (FALSE);
  597. }
  598. else
  599. {
  600. //
  601. // Get the directory.
  602. //
  603. if (pfnGetProfilesDirectory)
  604. {
  605. return ((*pfnGetProfilesDirectory)(buffer, &cchDir));
  606. }
  607. }
  608. return (FALSE);
  609. }
  610. ////////////////////////////////////////////////////////////////////////////
  611. //
  612. // IsValidUserDataFile
  613. //
  614. // Determines if the user data file exists and is accessible.
  615. //
  616. ////////////////////////////////////////////////////////////////////////////
  617. BOOL IsValidUserDataFile(LPSTR pFileName)
  618. {
  619. WIN32_FIND_DATA FindData;
  620. HANDLE FindHandle;
  621. BOOL bRet;
  622. UINT OldMode;
  623. OldMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  624. FindHandle = FindFirstFile(pFileName, &FindData);
  625. if (FindHandle == INVALID_HANDLE_VALUE)
  626. {
  627. bRet = FALSE;
  628. }
  629. else
  630. {
  631. FindClose(FindHandle);
  632. bRet = TRUE;
  633. }
  634. SetErrorMode(OldMode);
  635. return (bRet);
  636. }
  637. ///////////////////////////////////////////////////////////////////////////////
  638. //
  639. // GetLocaleFromRegistry
  640. //
  641. // Return locale used by a specific user.
  642. //
  643. ///////////////////////////////////////////////////////////////////////////////
  644. LCID GetLocaleFromRegistry(HKEY hKey)
  645. {
  646. HKEY hIntlKey;
  647. CHAR szLocale[REGSTR_MAX_VALUE_LENGTH] = {0};
  648. DWORD dwLocale = REGSTR_MAX_VALUE_LENGTH;
  649. LCID locale = 0x00000000;
  650. //
  651. // Open the appropriate key.
  652. //
  653. if(RegOpenKeyEx( hKey,
  654. c_szCPanelIntl,
  655. 0,
  656. KEY_READ,
  657. &hIntlKey) == ERROR_SUCCESS)
  658. {
  659. //
  660. // Query the value.
  661. //
  662. if( RegQueryValueEx( hIntlKey,
  663. c_szLocale,
  664. NULL,
  665. NULL,
  666. szLocale,
  667. &dwLocale) == ERROR_SUCCESS)
  668. {
  669. //
  670. // Convert the string value to hex value.
  671. //
  672. if (szLocale[0] != '\0')
  673. {
  674. locale = TransNum(szLocale);
  675. }
  676. }
  677. //
  678. // Close registry handle.
  679. //
  680. RegCloseKey(hIntlKey);
  681. }
  682. //
  683. // Return value.
  684. //
  685. return (locale);
  686. }
  687. ////////////////////////////////////////////////////////////////////////////
  688. //
  689. // GetLocaleFromFile
  690. //
  691. // Gets the Locale for the user data file. The user data file is
  692. // corresponding to the NTUSER.DAT file.
  693. //
  694. ////////////////////////////////////////////////////////////////////////////
  695. LCID GetLocaleFromFile(LPSTR szProfile)
  696. {
  697. HKEY hHive;
  698. CHAR szLocale[REGSTR_MAX_VALUE_LENGTH] = {0};
  699. DWORD dwLocale = REGSTR_MAX_VALUE_LENGTH;
  700. LCID locale = 0x00000000;
  701. BOOLEAN wasEnabled;
  702. //
  703. // Load hive.
  704. //
  705. if ((hHive = LoadHive( szProfile,
  706. "TempKey",
  707. c_szCPanelIntl,
  708. &wasEnabled )) != NULL)
  709. {
  710. //
  711. // Query the value.
  712. //
  713. if( RegQueryValueEx( hHive,
  714. c_szLocale,
  715. NULL,
  716. NULL,
  717. szLocale,
  718. &dwLocale) == ERROR_SUCCESS)
  719. {
  720. //
  721. // Convert the string value to hex value.
  722. //
  723. if (szLocale[0] != '\0')
  724. {
  725. locale = TransNum(szLocale);
  726. }
  727. }
  728. //
  729. // Unload hive.
  730. //
  731. RegCloseKey(hHive);
  732. UnloadHive("TempKey", &wasEnabled);
  733. }
  734. return locale;
  735. }
  736. ////////////////////////////////////////////////////////////////////////////
  737. //
  738. // RebootTheSystem
  739. //
  740. // This routine enables all privileges in the token, calls ExitWindowsEx
  741. // to reboot the system, and then resets all of the privileges to their
  742. // old state.
  743. //
  744. ////////////////////////////////////////////////////////////////////////////
  745. VOID RebootTheSystem()
  746. {
  747. if (IsWindows9x())
  748. {
  749. //
  750. // Enumerate all windows end ask them to close
  751. //
  752. EnumWindows((WNDENUMPROC)EnumWindowsProc, 0);
  753. //
  754. // Exit normally.
  755. //
  756. ExitWindowsEx(EWX_REBOOT, 0);
  757. }
  758. else
  759. {
  760. HANDLE Token = NULL;
  761. ULONG ReturnLength, Index;
  762. PTOKEN_PRIVILEGES NewState = NULL;
  763. PTOKEN_PRIVILEGES OldState = NULL;
  764. BOOL Result;
  765. Result = OpenProcessToken( GetCurrentProcess(),
  766. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  767. &Token );
  768. if (Result)
  769. {
  770. ReturnLength = 4096;
  771. NewState = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, ReturnLength);
  772. OldState = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, ReturnLength);
  773. Result = (BOOL)((NewState != NULL) && (OldState != NULL));
  774. if (Result)
  775. {
  776. Result = GetTokenInformation( Token, // TokenHandle
  777. TokenPrivileges, // TokenInformationClass
  778. NewState, // TokenInformation
  779. ReturnLength, // TokenInformationLength
  780. &ReturnLength ); // ReturnLength
  781. if (Result)
  782. {
  783. //
  784. // Set the state settings so that all privileges are
  785. // enabled...
  786. //
  787. if (NewState->PrivilegeCount > 0)
  788. {
  789. for (Index = 0; Index < NewState->PrivilegeCount; Index++)
  790. {
  791. NewState->Privileges[Index].Attributes = SE_PRIVILEGE_ENABLED;
  792. }
  793. }
  794. Result = AdjustTokenPrivileges( Token, // TokenHandle
  795. FALSE, // DisableAllPrivileges
  796. NewState, // NewState
  797. ReturnLength, // BufferLength
  798. OldState, // PreviousState
  799. &ReturnLength ); // ReturnLength
  800. if (Result)
  801. {
  802. ExitWindowsEx(EWX_REBOOT, 0);
  803. AdjustTokenPrivileges( Token,
  804. FALSE,
  805. OldState,
  806. 0,
  807. NULL,
  808. NULL );
  809. }
  810. }
  811. }
  812. }
  813. if (NewState != NULL)
  814. {
  815. LocalFree(NewState);
  816. }
  817. if (OldState != NULL)
  818. {
  819. LocalFree(OldState);
  820. }
  821. if (Token != NULL)
  822. {
  823. CloseHandle(Token);
  824. }
  825. }
  826. }
  827. ////////////////////////////////////////////////////////////////////////////
  828. //
  829. // RemoveQuotes
  830. //
  831. // Remove quotes from a string.
  832. //
  833. ////////////////////////////////////////////////////////////////////////////
  834. LPSTR RemoveQuotes(LPSTR lpString)
  835. {
  836. LPSTR strPtr = lpString;
  837. if (lpString && *lpString)
  838. {
  839. if (*strPtr == '"')
  840. {
  841. lpString++;
  842. strPtr++;
  843. }
  844. while (*strPtr)
  845. {
  846. if (*strPtr == '"')
  847. {
  848. *strPtr = '\0';
  849. }
  850. strPtr++;
  851. }
  852. }
  853. return (lpString);
  854. }
  855. ////////////////////////////////////////////////////////////////////////////
  856. //
  857. // EnumWindowsProc
  858. //
  859. // Function used to reboot the system (Windows 9x only).
  860. //
  861. ////////////////////////////////////////////////////////////////////////////
  862. BOOL CALLBACK EnumWindowsProc(HWND hwnd, DWORD lParam)
  863. {
  864. DWORD pid = 0;
  865. LRESULT lResult;
  866. HANDLE hProcess;
  867. DWORD dwResult;
  868. lResult = SendMessageTimeout(hwnd,
  869. WM_QUERYENDSESSION,
  870. 0,
  871. ENDSESSION_LOGOFF,
  872. SMTO_ABORTIFHUNG,
  873. 2000,
  874. (PDWORD_PTR)(&dwResult));
  875. if (lResult)
  876. {
  877. //
  878. // Application will terminate nicely, so let it.
  879. //
  880. lResult = SendMessageTimeout(hwnd,
  881. WM_ENDSESSION,
  882. TRUE,
  883. ENDSESSION_LOGOFF,
  884. SMTO_ABORTIFHUNG,
  885. 2000,
  886. (PDWORD_PTR)(&dwResult));
  887. }
  888. else // You have to take more forceful measures.
  889. {
  890. //
  891. // Get the ProcessId for this window.
  892. //
  893. GetWindowThreadProcessId(hwnd, &pid);
  894. //
  895. // Open the process with all access.
  896. //
  897. hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
  898. //
  899. // Terminate the process.
  900. //
  901. TerminateProcess(hProcess, 0);
  902. }
  903. //
  904. // Continue the enumeration.
  905. //
  906. return TRUE;
  907. }