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.

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