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.

484 lines
12 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // MISCFUNC.CPP / Tuneup
  4. //
  5. // Microsoft Confidential
  6. // Copyright (c) Microsoft Corporation 1998
  7. // All rights reserved
  8. //
  9. // Contains misc. functions used throughout the program. All these functions
  10. // are externally exported and defined in MISCFUNC.H.
  11. //
  12. // 7/98 - Jason Cohen (JCOHEN)
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. // Include files.
  16. //
  17. #include <windows.h>
  18. #include <tchar.h>
  19. #include <shellapi.h>
  20. #include "jcohen.h"
  21. #include "registry.h"
  22. VOID CenterWindow(HWND hWnd, HWND hWndParent, BOOL bRightTop)
  23. {
  24. RECT rcWndParent,
  25. rcWnd;
  26. // Get the window rect for the parent window.
  27. //
  28. if (hWndParent == NULL)
  29. GetWindowRect(GetDesktopWindow(), &rcWndParent);
  30. else
  31. GetWindowRect(hWndParent, &rcWndParent);
  32. // Get the window rect for the window to be centered.
  33. //
  34. GetWindowRect(hWnd, &rcWnd);
  35. // Now center the window.
  36. //
  37. if (bRightTop)
  38. {
  39. SetWindowPos(hWnd, HWND_TOPMOST,
  40. rcWndParent.right - (rcWnd.right - rcWnd.left) - 5,
  41. GetSystemMetrics(SM_CYCAPTION) * 2,
  42. 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW);
  43. }
  44. else
  45. {
  46. SetWindowPos(hWnd, NULL,
  47. rcWndParent.left + (rcWndParent.right - rcWndParent.left - (rcWnd.right - rcWnd.left)) / 2,
  48. rcWndParent.top + (rcWndParent.bottom - rcWndParent.top - (rcWnd.bottom - rcWnd.top)) / 2,
  49. 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
  50. }
  51. }
  52. VOID ShowEnableWindow(HWND hWnd, BOOL bEnable)
  53. {
  54. EnableWindow(hWnd, bEnable);
  55. ShowWindow(hWnd, bEnable ? SW_SHOW : SW_HIDE);
  56. }
  57. LPTSTR AllocateString(HINSTANCE hInstance, UINT uID)
  58. {
  59. TCHAR szBuffer[512];
  60. LPTSTR lpBuffer = NULL;
  61. if ( ( LoadString(hInstance, uID, szBuffer, sizeof(szBuffer) / sizeof(TCHAR)) ) &&
  62. ( lpBuffer = (LPTSTR) MALLOC(sizeof(TCHAR) * (lstrlen(szBuffer) + 1)) ) )
  63. lstrcpy(lpBuffer, szBuffer);
  64. return lpBuffer;
  65. }
  66. //////////////////////////////////////////////////////////////////////////////
  67. //
  68. // EXTERNAL:
  69. // IsUserAdmin()
  70. //
  71. // This routine returns TRUE if the caller's process is a
  72. // member of the Administrators local group.
  73. //
  74. // Caller is NOT expected to be impersonating anyone and IS
  75. // expected to be able to open their own process and process
  76. // token.
  77. //
  78. // ENTRY:
  79. // None.
  80. //
  81. // EXIT:
  82. // BOOL
  83. // TRUE - Caller has Administrators local group.
  84. // FALSE - Caller does not have Administrators local group.
  85. //
  86. //////////////////////////////////////////////////////////////////////////////
  87. BOOL IsUserAdmin(VOID)
  88. {
  89. HANDLE hToken = INVALID_HANDLE_VALUE;
  90. PTOKEN_GROUPS pGroups = NULL;
  91. DWORD dwSize,
  92. i;
  93. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  94. PSID AdministratorsGroup;
  95. static DWORD dwReturn = 0;
  96. // Save the admin status so that we don't have to
  97. // do all this work everytime we call this function.
  98. //
  99. if (dwReturn)
  100. return (dwReturn == 1); // 1 = TRUE, 2 = FALSE, 0 = Unknown yet.
  101. // Open the process token.
  102. //
  103. if ( OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken) )
  104. {
  105. // Get group information.
  106. //
  107. if ( !GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwSize) &&
  108. (GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&
  109. (pGroups = (PTOKEN_GROUPS) LocalAlloc(LPTR, dwSize)) &&
  110. (GetTokenInformation(hToken, TokenGroups, pGroups, dwSize, &dwSize)) )
  111. {
  112. if ( AllocateAndInitializeSid(
  113. &NtAuthority,
  114. 2,
  115. SECURITY_BUILTIN_DOMAIN_RID,
  116. DOMAIN_ALIAS_RID_ADMINS,
  117. 0, 0, 0, 0, 0, 0,
  118. &AdministratorsGroup)
  119. )
  120. {
  121. // See if the user has the administrator group.
  122. //
  123. for(i = 0; (dwReturn != 1) && (i < pGroups->GroupCount); i++)
  124. if ( EqualSid(pGroups->Groups[i].Sid, AdministratorsGroup) ) dwReturn = 1;
  125. // If we didn't find the user in the
  126. // admin group, set the return option to
  127. // 2 (meaning we looked already but the
  128. // user isn't an admin.
  129. //
  130. if (dwReturn != 1)
  131. dwReturn = 2;
  132. FreeSid(AdministratorsGroup);
  133. }
  134. }
  135. // Clean up.
  136. //
  137. if (pGroups) {
  138. LocalFree((HLOCAL) pGroups);
  139. }
  140. CloseHandle(hToken);
  141. }
  142. return (dwReturn == 1); // 1 = TRUE, 2 = FALSE, 0 = Unknown yet.
  143. }
  144. VOID ExecAndWait(HWND hOrgWnd, LPTSTR lpExe, LPTSTR lpCmd, LPTSTR lpDir, BOOL fShowOrgWnd, BOOL fNoWait)
  145. {
  146. SHELLEXECUTEINFO sei;
  147. ZeroMemory((PVOID) &sei, sizeof(SHELLEXECUTEINFO));
  148. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  149. sei.hwnd = hOrgWnd;
  150. sei.fMask = SEE_MASK_NOCLOSEPROCESS;
  151. sei.lpFile = (LPCTSTR) lpExe;
  152. sei.lpDirectory = lpDir;
  153. sei.lpParameters = lpCmd;
  154. sei.nShow = SW_SHOW;
  155. if (ShellExecuteEx(&sei)) {
  156. // Hide/disable Tuneup.
  157. //
  158. WaitForInputIdle(sei.hProcess, INFINITE);
  159. ShowEnableWindow(hOrgWnd, FALSE);
  160. //ShowEnableWindow(g_hwndMain, FALSE);
  161. // Wait until the launched app stop.
  162. //
  163. if (!fNoWait)
  164. WaitForSingleObjectEx(sei.hProcess, INFINITE, FALSE);
  165. // Enable Tuneup.
  166. //
  167. EnableWindow(hOrgWnd, TRUE);
  168. //EnableWindow(g_hwndMain, TRUE);
  169. // Don't show it?
  170. //
  171. if (fShowOrgWnd) {
  172. ShowWindow(hOrgWnd, SW_SHOW);
  173. //ShowWindow(g_hwndMain, SW_SHOW);
  174. SetForegroundWindow(hOrgWnd);
  175. }
  176. }
  177. #ifdef DEBUG
  178. else {
  179. LPTSTR lpMsgBuf;
  180. FormatMessage(
  181. FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  182. NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  183. &lpMsgBuf, 0, NULL
  184. );
  185. MessageBox(NULL, (LPCTSTR) lpMsgBuf, (LPCTSTR) _T("GetLastError()"), MB_OK | MB_ICONINFORMATION);
  186. LocalFree(lpMsgBuf);
  187. }
  188. #endif
  189. }
  190. BOOL ErrMsg(HWND hWnd, INT nStringID)
  191. {
  192. LPTSTR lpString;
  193. // Load the string and display the message box.
  194. //
  195. if ( lpString = AllocateString(NULL, nStringID) )
  196. {
  197. MessageBox(hWnd, lpString, NULL, MB_OK | MB_ICONEXCLAMATION);
  198. FREE(lpString);
  199. }
  200. // Always return TRUE.
  201. //
  202. return TRUE;
  203. }
  204. DWORD StartScheduler()
  205. {
  206. TCHAR szRegKeyServices[] = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunServies"),
  207. szRegValSched[] = _T("SchedulingAgent"),
  208. szSchedClass[] = _T("SAGEWINDOWCLASS"),
  209. szSchedTitle[] = _T("SYSTEM AGENT COM WINDOW"),
  210. szSchedExe[] = _T("MSTASK.EXE");
  211. STARTUPINFO si;
  212. PROCESS_INFORMATION pi;
  213. TCHAR szApp[MAX_PATH] = NULLSTR;
  214. LPTSTR lpFilePart;
  215. // Check to see if it is already running.
  216. //
  217. if ( FindWindow(szSchedClass, szSchedTitle) != NULL )
  218. return ERROR_SUCCESS;
  219. // Get the full path to where MSTASK is.
  220. //
  221. if ( ( SearchPath(NULL, _T("MSTASK.EXE"), NULL, sizeof(szApp), szApp, &lpFilePart) == 0 ) ||
  222. ( szApp[0] == _T('\0') ) )
  223. return GetLastError();
  224. // Add the key so the Scheduling service will start each time
  225. // the computer is restarted.
  226. //
  227. RegSetString(HKLM, szRegKeyServices, szRegValSched, szApp);
  228. // Execute the task scheduler process.
  229. //
  230. ZeroMemory(&si, sizeof(STARTUPINFO));
  231. si.cb = sizeof(STARTUPINFO);
  232. if ( !CreateProcess(szApp, NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi) )
  233. return GetLastError();
  234. CloseHandle(pi.hProcess);
  235. CloseHandle(pi.hThread);
  236. return ERROR_SUCCESS;
  237. }
  238. HFONT GetFont(HWND hWndCtrl, LPTSTR lpFontName, DWORD dwFontSize, LONG lFontWeight, BOOL bSymbol)
  239. {
  240. HFONT hFont;
  241. LOGFONT lFont;
  242. BOOL bGetFont;
  243. // If the font name is passed in, then try to use that
  244. // first before getting the font of the control.
  245. //
  246. if ( lpFontName )
  247. {
  248. // Make sure the font name is not longer than
  249. // 32 characters (including the NULL terminator).
  250. //
  251. if ( lstrlen(lpFontName) >= sizeof(lFont.lfFaceName) )
  252. return NULL;
  253. // Setup the structure to use to get the
  254. // font we want.
  255. //
  256. ZeroMemory(&lFont, sizeof(LOGFONT));
  257. lstrcpy(lFont.lfFaceName, lpFontName);
  258. }
  259. // First try to get the font that we wanted.
  260. //
  261. if ( ( lpFontName == NULL ) ||
  262. ( (hFont = CreateFontIndirect((LPLOGFONT) &lFont)) == NULL ) )
  263. {
  264. // Couldn't get the font we wanted, try the font of the control
  265. // if a valid window handle was passed in.
  266. //
  267. if ( ( hWndCtrl == NULL ) ||
  268. ( (hFont = (HFONT) (WORD) SendMessage(hWndCtrl, WM_GETFONT, 0, 0L)) == NULL ) )
  269. {
  270. // All atempts to get the font failed. We must return NULL.
  271. //
  272. return NULL;
  273. }
  274. }
  275. // Return the font we have now if we don't need to
  276. // change the size or weight.
  277. //
  278. if ( (lFontWeight == 0) && (dwFontSize == 0) )
  279. return hFont;
  280. // We must have a valid HFONT now. Fill in the structure
  281. // and setup the size and weight we wanted for it.
  282. //
  283. bGetFont = GetObject(hFont, sizeof(LOGFONT), (LPVOID) &lFont);
  284. DeleteObject(hFont);
  285. if (bGetFont)
  286. {
  287. // Set the bold and point size of the font.
  288. //
  289. if (lFontWeight)
  290. lFont.lfWeight = lFontWeight;
  291. if (dwFontSize)
  292. lFont.lfHeight = -MulDiv(dwFontSize, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
  293. if (bSymbol)
  294. lFont.lfCharSet = SYMBOL_CHARSET;
  295. // Create the font.
  296. //
  297. hFont = CreateFontIndirect((LPLOGFONT) &lFont);
  298. }
  299. else
  300. hFont = NULL;
  301. return hFont;
  302. }
  303. //***************************************************************************
  304. //
  305. // EXTERNAL:
  306. // CreatePath()
  307. // - Creates the whole path, not just the last directory.
  308. //
  309. // ENTRY:
  310. // lpPath - Path to create.
  311. //
  312. // EXIT:
  313. // VOID
  314. //
  315. //***************************************************************************
  316. BOOL CreatePath(LPTSTR lpPath) {
  317. LPTSTR lpFind = lpPath;
  318. while ( lpFind = _tcschr(lpFind + 1, _T('\\')) )
  319. {
  320. if ( !( ( lpFind - lpPath <= 2 ) && ( *(lpFind - 1) == _T(':') ) ) )
  321. {
  322. *lpFind = _T('\0');
  323. if (!EXIST(lpPath))
  324. CreateDirectory(lpPath, NULL);
  325. *lpFind = _T('\\');
  326. }
  327. }
  328. if (!EXIST(lpPath))
  329. return CreateDirectory(lpPath, NULL);
  330. else
  331. return TRUE;
  332. }
  333. DWORD GetCommandLineOptions(LPTSTR **lpArgs)
  334. {
  335. TCHAR cParse;
  336. LPTSTR lpSearch,
  337. lpCommandLine;
  338. DWORD dwArgs = 0,
  339. dwMaxArgs = 0xFFFFFFFF;
  340. // Make sure we get the command line.
  341. //
  342. if ( (lpSearch = lpCommandLine = GetCommandLine()) == NULL )
  343. return 0;
  344. // Get the number of arguments so we can allocate
  345. // the memory for the array of command line options.
  346. //
  347. if ( lpArgs )
  348. {
  349. if ( (dwMaxArgs = GetCommandLineOptions(NULL)) == 0 )
  350. return 0;
  351. if ( (*lpArgs = (LPTSTR *) MALLOC(sizeof(LPTSTR) * dwMaxArgs)) == NULL )
  352. return 0;
  353. }
  354. // Now lets parse the arguments.
  355. //
  356. while ( *lpSearch && (dwArgs < dwMaxArgs) )
  357. {
  358. // Eat all preceeding spaces.
  359. //
  360. while ( *lpSearch == _T(' ') )
  361. lpSearch++;
  362. // Check to see if we need to look for a space or a quote
  363. // to separate the next argument.
  364. //
  365. if ( *lpSearch == _T('"') )
  366. cParse = *lpSearch++;
  367. else
  368. cParse = _T(' ');
  369. // This is be the beginning of the next argument, but
  370. // it isn't NULL terminated yet.
  371. //
  372. if ( lpArgs )
  373. *(*lpArgs + dwArgs) = lpSearch;
  374. dwArgs++;
  375. // Go through all the characters until we hit a separator.
  376. //
  377. do
  378. {
  379. // Once we get to a quote, we just want to keep going
  380. // until we get to a space.
  381. //
  382. if ( *lpSearch == _T('"') )
  383. cParse = _T(' ');
  384. // Only end when we reach the parsing character, which will
  385. // always be the space by this time (but the space won't trigger
  386. // the end until we hit a quote, if that is what we were originally
  387. // looking for). We also need to make sure that we don't increment
  388. // past the NULL terminator.
  389. //
  390. }
  391. while ( ( *lpSearch != cParse ) && ( *lpSearch ) && ( *lpSearch++ ) );
  392. // If the preceeding character is a quote, that is were we want to
  393. // place the NULL terminator.
  394. //
  395. if ( ( lpSearch > lpCommandLine ) &&
  396. ( *(lpSearch - 1) == _T('"') ) )
  397. lpSearch--;
  398. // Set and increment past the NULL terminator only if we aren't already at
  399. // the end if the string.
  400. //
  401. if ( lpArgs && *lpSearch )
  402. *lpSearch++ = _T('\0');
  403. else
  404. if ( *lpSearch ) lpSearch++;
  405. }
  406. return dwArgs;
  407. }