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.

514 lines
16 KiB

  1. //
  2. // about.c
  3. //
  4. //
  5. // common about dialog for File Manager, Program Manager, Control Panel
  6. //
  7. #include "shellprv.h"
  8. #pragma hdrstop
  9. #include <common.ver> // for VER_LEGALCOPYRIGHT_YEARS
  10. #include "ids.h" // for IDD_EULA
  11. #include <xpsp1res.h> // for added XPSP1 resources
  12. #include <winbrand.h> // for added branding resources
  13. #define STRING_SEPARATOR TEXT('#')
  14. #define MAX_REG_VALUE 256
  15. #define BytesToK(pDW) (*(pDW) = (*(pDW) + 512) / 1024) // round up
  16. typedef struct {
  17. HICON hIcon;
  18. LPCTSTR szApp;
  19. LPCTSTR szOtherStuff;
  20. } ABOUT_PARAMS, *LPABOUT_PARAMS;
  21. #define REG_SETUP TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion")
  22. BOOL_PTR CALLBACK AboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  23. int WINAPI ShellAboutW(HWND hWnd, LPCTSTR szApp, LPCTSTR szOtherStuff, HICON hIcon)
  24. {
  25. ABOUT_PARAMS ap;
  26. static HMODULE s_hmodXPSP1Res = (HMODULE)-1;
  27. if (s_hmodXPSP1Res == (HMODULE)-1)
  28. {
  29. s_hmodXPSP1Res = LoadLibraryExA("xpsp1res.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
  30. }
  31. ap.hIcon = hIcon;
  32. ap.szApp = (LPWSTR)szApp;
  33. ap.szOtherStuff = szOtherStuff;
  34. return (int)DialogBoxParam(s_hmodXPSP1Res ? s_hmodXPSP1Res : HINST_THISDLL,
  35. (LPTSTR)MAKEINTRESOURCE(DLG_ABOUT),
  36. hWnd,
  37. AboutDlgProc,
  38. (LPARAM)&ap);
  39. }
  40. INT APIENTRY ShellAboutA( HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
  41. {
  42. DWORD cchLen;
  43. DWORD dwRet;
  44. LPWSTR lpszAppW;
  45. LPWSTR lpszOtherStuffW;
  46. if (szApp)
  47. {
  48. cchLen = lstrlenA(szApp)+1;
  49. if (!(lpszAppW = (LPWSTR)LocalAlloc(LMEM_FIXED, (cchLen * sizeof(WCHAR)))))
  50. {
  51. return(0);
  52. }
  53. else
  54. {
  55. MultiByteToWideChar(CP_ACP, 0, (LPSTR)szApp, -1,
  56. lpszAppW, cchLen);
  57. }
  58. }
  59. else
  60. {
  61. lpszAppW = NULL;
  62. }
  63. if (szOtherStuff)
  64. {
  65. cchLen = lstrlenA(szOtherStuff)+1;
  66. if (!(lpszOtherStuffW = (LPWSTR)LocalAlloc(LMEM_FIXED,
  67. (cchLen * sizeof(WCHAR)))))
  68. {
  69. if (lpszAppW)
  70. {
  71. LocalFree(lpszAppW);
  72. }
  73. return(0);
  74. }
  75. else
  76. {
  77. MultiByteToWideChar(CP_ACP, 0, (LPSTR)szOtherStuff, -1,
  78. lpszOtherStuffW, cchLen);
  79. }
  80. }
  81. else
  82. {
  83. lpszOtherStuffW = NULL;
  84. }
  85. dwRet=ShellAboutW(hWnd, lpszAppW, lpszOtherStuffW, hIcon);
  86. if (lpszAppW)
  87. {
  88. LocalFree(lpszAppW);
  89. }
  90. if (lpszOtherStuffW)
  91. {
  92. LocalFree(lpszOtherStuffW);
  93. }
  94. return(dwRet);
  95. }
  96. DWORD RegGetStringAndRealloc( HKEY hkey, LPCTSTR lpszValue, LPTSTR *lplpsz, LPDWORD lpSize )
  97. {
  98. DWORD err;
  99. DWORD dwSize;
  100. DWORD dwType;
  101. LPTSTR lpszNew;
  102. *lplpsz[0] = TEXT('\0'); // In case of error
  103. dwSize = *lpSize;
  104. err = SHQueryValueEx(hkey, (LPTSTR)lpszValue, 0, &dwType,
  105. (LPBYTE)*lplpsz, &dwSize);
  106. if (err == ERROR_MORE_DATA)
  107. {
  108. lpszNew = (LPTSTR)LocalReAlloc((HLOCAL)*lplpsz, dwSize, LMEM_MOVEABLE);
  109. if (lpszNew)
  110. {
  111. *lplpsz = lpszNew;
  112. *lpSize = dwSize;
  113. err = SHQueryValueEx(hkey, (LPTSTR)lpszValue, 0, &dwType,
  114. (LPBYTE)*lplpsz, &dwSize);
  115. }
  116. }
  117. return err;
  118. }
  119. // Some Static strings that we use to read from the registry
  120. // const char c_szAboutCurrentBuild[] = "CurrentBuild";
  121. const TCHAR c_szAboutRegisteredUser[] = TEXT("RegisteredOwner");
  122. const TCHAR c_szAboutRegisteredOrganization[] = TEXT("RegisteredOrganization");
  123. const TCHAR c_szAboutProductID[] = TEXT("ProductID");
  124. const TCHAR c_szAboutOEMID[] = TEXT("OEMID");
  125. void _InitAboutDlg(HWND hDlg, LPABOUT_PARAMS lpap)
  126. {
  127. HKEY hkey;
  128. TCHAR szldK[16];
  129. TCHAR szBuffer[64];
  130. TCHAR szTemp[64];
  131. TCHAR szTitle[64];
  132. TCHAR szMessage[200];
  133. TCHAR szNumBuf1[32];
  134. LPTSTR lpTemp;
  135. LPTSTR lpszValue = NULL;
  136. DWORD cb;
  137. DWORD err;
  138. /*
  139. * Display app title
  140. */
  141. // REVIEW Note the const ->nonconst cast here
  142. for (lpTemp = (LPTSTR)lpap->szApp; 1 ; lpTemp = CharNext(lpTemp))
  143. {
  144. if (*lpTemp == TEXT('\0'))
  145. {
  146. GetWindowText(hDlg, szBuffer, ARRAYSIZE(szBuffer));
  147. wsprintf(szTitle, szBuffer, (LPTSTR)lpap->szApp);
  148. SetWindowText(hDlg, szTitle);
  149. break;
  150. }
  151. if (*lpTemp == STRING_SEPARATOR)
  152. {
  153. *lpTemp++ = TEXT('\0');
  154. SetWindowText(hDlg, lpap->szApp);
  155. lpap->szApp = lpTemp;
  156. break;
  157. }
  158. }
  159. GetDlgItemText(hDlg, IDD_APPNAME, szBuffer, ARRAYSIZE(szBuffer));
  160. wsprintf(szTitle, szBuffer, lpap->szApp);
  161. SetDlgItemText(hDlg, IDD_APPNAME, szTitle);
  162. // other stuff goes here...
  163. SetDlgItemText(hDlg, IDD_OTHERSTUFF, lpap->szOtherStuff);
  164. SendDlgItemMessage(hDlg, IDD_ICON, STM_SETICON, (WPARAM)lpap->hIcon, 0L);
  165. if (!lpap->hIcon)
  166. ShowWindow(GetDlgItem(hDlg, IDD_ICON), SW_HIDE);
  167. GetDlgItemText(hDlg, IDD_COPYRIGHTSTRING, szTemp, ARRAYSIZE(szTemp));
  168. wnsprintf(szBuffer, ARRAYSIZE(szBuffer), szTemp, TEXT(VER_LEGALCOPYRIGHT_YEARS));
  169. SetDlgItemText(hDlg, IDD_COPYRIGHTSTRING, szBuffer);
  170. /*
  171. * Display memory statistics
  172. */
  173. {
  174. MEMORYSTATUSEX MemoryStatus;
  175. DWORDLONG ullTotalPhys;
  176. MemoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
  177. GlobalMemoryStatusEx(&MemoryStatus);
  178. ullTotalPhys = MemoryStatus.ullTotalPhys;
  179. BytesToK(&ullTotalPhys);
  180. LoadString(HINST_THISDLL, IDS_LDK, szldK, ARRAYSIZE(szldK));
  181. wsprintf(szBuffer, szldK, AddCommas64(ullTotalPhys, szNumBuf1, ARRAYSIZE(szNumBuf1)));
  182. SetDlgItemText(hDlg, IDD_CONVENTIONAL, szBuffer);
  183. }
  184. // Lets get the version and user information from the registry
  185. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_SETUP, 0, KEY_READ, &hkey) == ERROR_SUCCESS)
  186. {
  187. cb = MAX_REG_VALUE;
  188. if (NULL != (lpszValue = (LPTSTR)LocalAlloc(LPTR, cb)))
  189. {
  190. /*
  191. * Determine version information
  192. */
  193. OSVERSIONINFO Win32VersionInformation;
  194. Win32VersionInformation.dwOSVersionInfoSize = sizeof(Win32VersionInformation);
  195. if (!GetVersionEx(&Win32VersionInformation))
  196. {
  197. Win32VersionInformation.dwMajorVersion = 0;
  198. Win32VersionInformation.dwMinorVersion = 0;
  199. Win32VersionInformation.dwBuildNumber = 0;
  200. Win32VersionInformation.szCSDVersion[0] = TEXT('\0');
  201. }
  202. LoadString(HINST_THISDLL, IDS_VERSIONMSG, szBuffer, ARRAYSIZE(szBuffer));
  203. szTitle[0] = TEXT('\0');
  204. if (Win32VersionInformation.szCSDVersion[0] != TEXT('\0'))
  205. {
  206. wsprintf(szTitle, TEXT(": %s"), Win32VersionInformation.szCSDVersion);
  207. }
  208. // Extra Whistler code to get the VBL version info
  209. {
  210. DWORD dwSize;
  211. DWORD dwType;
  212. // save off the current szTitle string
  213. lstrcpy(szTemp, szTitle);
  214. dwSize = sizeof(szTitle);
  215. if ((SHGetValue(HKEY_LOCAL_MACHINE,
  216. TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion"),
  217. TEXT("BuildLab"),
  218. &dwType,
  219. szTitle,
  220. &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ))
  221. {
  222. // Now szTitle contains the buildnumber in the format: "2204.reinerf.010700"
  223. // Since we are sprintf'ing the buildnumber again below, we remove it first
  224. memmove((void*)szTitle, (void*)&szTitle[4], (lstrlen(szTitle) + 1) * sizeof(TCHAR));
  225. if (szTemp[0] != TEXT('\0'))
  226. {
  227. // add back on the Service Pack version string
  228. lstrcatn(szTitle, TEXT(" "), ARRAYSIZE(szTitle));
  229. lstrcatn(szTitle, szTemp, ARRAYSIZE(szTitle));
  230. }
  231. }
  232. }
  233. szNumBuf1[0] = TEXT('\0');
  234. if (GetSystemMetrics(SM_DEBUG))
  235. {
  236. szNumBuf1[0] = TEXT(' ');
  237. LoadString(HINST_THISDLL, IDS_DEBUG, &szNumBuf1[1], ARRAYSIZE(szNumBuf1) - 1);
  238. }
  239. wnsprintf(szMessage,
  240. ARRAYSIZE(szMessage),
  241. szBuffer,
  242. Win32VersionInformation.dwMajorVersion,
  243. Win32VersionInformation.dwMinorVersion,
  244. Win32VersionInformation.dwBuildNumber,
  245. (LPTSTR)szTitle,
  246. (LPTSTR)szNumBuf1);
  247. SetDlgItemText(hDlg, IDD_VERSION, szMessage);
  248. /*
  249. * Display the User name.
  250. */
  251. err = RegGetStringAndRealloc(hkey, c_szAboutRegisteredUser, &lpszValue, &cb);
  252. if (!err)
  253. SetDlgItemText(hDlg, IDD_USERNAME, lpszValue);
  254. /*
  255. * Display the Organization name.
  256. */
  257. err = RegGetStringAndRealloc(hkey, c_szAboutRegisteredOrganization, &lpszValue, &cb);
  258. if (!err)
  259. SetDlgItemText(hDlg, IDD_COMPANYNAME, lpszValue);
  260. /*
  261. * Display the OEM or Product ID.
  262. */
  263. err = RegGetStringAndRealloc(hkey, c_szAboutOEMID, &lpszValue, &cb);
  264. if (!err)
  265. {
  266. /*
  267. * We have an OEM ID, so hide the product ID controls,
  268. * and display the text.
  269. */
  270. ShowWindow (GetDlgItem(hDlg, IDD_PRODUCTID), SW_HIDE);
  271. ShowWindow (GetDlgItem(hDlg, IDD_SERIALNUM), SW_HIDE);
  272. SetDlgItemText(hDlg, IDD_OEMID, lpszValue);
  273. }
  274. else if (err == ERROR_FILE_NOT_FOUND)
  275. {
  276. /*
  277. * OEM ID didn't exist, so look for the Product ID
  278. */
  279. ShowWindow (GetDlgItem(hDlg, IDD_OEMID), SW_HIDE);
  280. err = RegGetStringAndRealloc(hkey, c_szAboutProductID, &lpszValue, &cb);
  281. if (!err)
  282. {
  283. SetDlgItemText(hDlg, IDD_SERIALNUM, lpszValue);
  284. }
  285. }
  286. LocalFree(lpszValue);
  287. }
  288. RegCloseKey(hkey);
  289. }
  290. }
  291. BOOL_PTR CALLBACK AboutDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
  292. {
  293. BOOL_PTR bReturn = TRUE;
  294. switch (wMsg)
  295. {
  296. case WM_INITDIALOG:
  297. _InitAboutDlg(hDlg, (LPABOUT_PARAMS)lParam);
  298. break;
  299. case WM_PAINT:
  300. {
  301. PAINTSTRUCT ps;
  302. HDC hdc = BeginPaint(hDlg, &ps);
  303. // We draw the product banner and a blue strip. In order to support high DPI monitors
  304. // and scaled fonts we must scale the image and the strip to the proportions of the dialog.
  305. //
  306. // +-----------------------------+
  307. // | Product Banner (413x72) |
  308. // | |
  309. // +-----------------------------+
  310. // | Blue Strip (413x5) |
  311. // +-----------------------------+
  312. HDC hdcMem = CreateCompatibleDC(hdc);
  313. int cxDlg;
  314. {
  315. RECT rc;
  316. GetClientRect(hDlg, &rc);
  317. cxDlg = rc.right;
  318. }
  319. if (hdcMem)
  320. {
  321. BOOL fDeep = (SHGetCurColorRes() > 8);
  322. HBITMAP hbmBand, hbmAbout;
  323. int cxDest = MulDiv(413,cxDlg,413);
  324. int cyDest = MulDiv(72,cxDlg,413);
  325. UINT uID;
  326. UINT uXpSpLevel = 0;
  327. HMODULE hResourceDll = HINST_THISDLL;
  328. if (IsOS(OS_PERSONAL))
  329. {
  330. uID = (fDeep ? IDB_ABOUTPERSONAL256 : IDB_ABOUTPERSONAL16);
  331. }
  332. #ifndef _WIN64
  333. else if (IsOS(OS_EMBEDDED))
  334. {
  335. uID = (fDeep ? IDB_ABOUTEMBEDDED256 : IDB_ABOUTEMBEDDED16);
  336. }
  337. else if (IsOS(OS_TABLETPC))
  338. {
  339. uXpSpLevel = 1;
  340. uID = (fDeep ? IDB_ABOUTTABLETPC256_SHELL32_DLL : IDB_ABOUTTABLETPC16_SHELL32_DLL);
  341. }
  342. else if (IsOS(OS_MEDIACENTER))
  343. {
  344. uXpSpLevel = 1;
  345. uID = (fDeep ? IDB_ABOUTMEDIACENTER256_SHELL32_DLL : IDB_ABOUTMEDIACENTER16_SHELL32_DLL);
  346. }
  347. #endif // !_WIN64
  348. else
  349. {
  350. uID = (fDeep ? IDB_ABOUT256 : IDB_ABOUT16);
  351. }
  352. // If this bitmap was added for a Windows XP service pack,
  353. // and lives in a special resource DLL, attempt to load it
  354. // now. If this fails, revert to the Professional bitmaps.
  355. if (uXpSpLevel > 0)
  356. {
  357. hResourceDll = LoadLibraryEx(TEXT("winbrand.dll"),
  358. NULL,
  359. LOAD_LIBRARY_AS_DATAFILE);
  360. if (hResourceDll == NULL)
  361. {
  362. hResourceDll = HINST_THISDLL;
  363. uID = (fDeep ? IDB_ABOUT256 : IDB_ABOUT16);
  364. }
  365. }
  366. // paint the bitmap for the windows product
  367. hbmAbout = LoadImage(hResourceDll,
  368. MAKEINTRESOURCE(uID),
  369. IMAGE_BITMAP,
  370. 0, 0,
  371. LR_LOADMAP3DCOLORS);
  372. if (hResourceDll != HINST_THISDLL)
  373. {
  374. FreeLibrary(hResourceDll);
  375. }
  376. if ( hbmAbout )
  377. {
  378. HBITMAP hbmOld = SelectObject(hdcMem, hbmAbout);
  379. if (hbmOld)
  380. {
  381. StretchBlt(hdc, 0, 0, cxDest, cyDest, hdcMem, 0,0,413,72, SRCCOPY);
  382. SelectObject(hdcMem, hbmOld);
  383. }
  384. DeleteObject(hbmAbout);
  385. }
  386. // paint the blue band below it
  387. hbmBand = LoadImage(HINST_THISDLL,
  388. MAKEINTRESOURCE(fDeep ? IDB_ABOUTBAND256:IDB_ABOUTBAND16),
  389. IMAGE_BITMAP,
  390. 0, 0,
  391. LR_LOADMAP3DCOLORS);
  392. if ( hbmBand )
  393. {
  394. HBITMAP hbmOld = SelectObject(hdcMem, hbmBand);
  395. if (hbmOld)
  396. {
  397. StretchBlt(hdc, 0, cyDest, cxDest, MulDiv(5,cxDlg,413), hdcMem, 0,0,413,5, SRCCOPY);
  398. SelectObject(hdcMem, hbmOld);
  399. }
  400. DeleteObject(hbmBand);
  401. }
  402. DeleteDC(hdcMem);
  403. }
  404. EndPaint(hDlg, &ps);
  405. break;
  406. }
  407. case WM_COMMAND:
  408. EndDialog(hDlg, TRUE);
  409. break;
  410. case WM_NOTIFY:
  411. if ((IDD_EULA == (int)wParam) &&
  412. (NM_CLICK == ((LPNMHDR)lParam)->code))
  413. {
  414. SHELLEXECUTEINFO sei = { 0 };
  415. sei.cbSize = sizeof(SHELLEXECUTEINFO);
  416. sei.fMask = SEE_MASK_DOENVSUBST;
  417. sei.hwnd = hDlg;
  418. sei.nShow = SW_SHOWNORMAL;
  419. sei.lpFile = TEXT("%windir%\\system32\\eula.txt");
  420. ShellExecuteEx(&sei);
  421. }
  422. else
  423. {
  424. // WM_NOTIFY not handled.
  425. bReturn = FALSE;
  426. }
  427. break;
  428. default:
  429. // Not handled.
  430. bReturn = FALSE;
  431. }
  432. return bReturn;
  433. }