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.

1385 lines
47 KiB

  1. //+---------------------------------------------------------------------------
  2. /////////////////////////////////////////////////////////////////////////////////
  3. //
  4. // Microsoft Windows
  5. // Copyright (C) Microsoft Corporation, 2000-2002.
  6. //
  7. // File: SaferEntryHashPropertyPage.cpp
  8. //
  9. // Contents: Implementation of CSaferEntryHashPropertyPage
  10. //
  11. //----------------------------------------------------------------------------
  12. // SaferEntryHashPropertyPage.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include <gpedit.h>
  16. #include <Imagehlp.h>
  17. #include "certmgr.h"
  18. #include "compdata.h"
  19. #include "SaferEntryHashPropertyPage.h"
  20. #include "SaferUtil.h"
  21. #ifdef _DEBUG
  22. #define new DEBUG_NEW
  23. #undef THIS_FILE
  24. static char THIS_FILE[] = __FILE__;
  25. #endif
  26. PCWSTR pcszNEWLINE = L"\x00d\x00a";
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CSaferEntryHashPropertyPage property page
  29. CSaferEntryHashPropertyPage::CSaferEntryHashPropertyPage(
  30. CSaferEntry& rSaferEntry,
  31. LONG_PTR lNotifyHandle,
  32. LPDATAOBJECT pDataObject,
  33. bool bReadOnly,
  34. CCertMgrComponentData* pCompData,
  35. bool bIsMachine,
  36. bool* pbObjectCreated /* = 0 */)
  37. : CSaferPropertyPage(CSaferEntryHashPropertyPage::IDD, pbObjectCreated,
  38. pCompData, rSaferEntry, false, lNotifyHandle, pDataObject, bReadOnly,
  39. bIsMachine),
  40. m_cbFileHash (0),
  41. m_hashAlgid (0),
  42. m_bFirst (true)
  43. {
  44. // security review 2/25/2002 BryanWal ok
  45. ::ZeroMemory (&m_nFileSize, sizeof (m_nFileSize));
  46. ::ZeroMemory (m_rgbFileHash, sizeof (m_rgbFileHash));
  47. //{{AFX_DATA_INIT(CSaferEntryHashPropertyPage)
  48. // NOTE: the ClassWizard will add member initialization here
  49. //}}AFX_DATA_INIT
  50. m_rSaferEntry.GetHash (m_rgbFileHash, m_cbFileHash, m_nFileSize,
  51. m_hashAlgid);
  52. }
  53. CSaferEntryHashPropertyPage::~CSaferEntryHashPropertyPage()
  54. {
  55. }
  56. void CSaferEntryHashPropertyPage::DoDataExchange(CDataExchange* pDX)
  57. {
  58. CSaferPropertyPage::DoDataExchange(pDX);
  59. //{{AFX_DATA_MAP(CSaferEntryHashPropertyPage)
  60. DDX_Control(pDX, IDC_HASH_ENTRY_HASHFILE_DETAILS, m_hashFileDetailsEdit);
  61. DDX_Control(pDX, IDC_HASH_ENTRY_DESCRIPTION, m_descriptionEdit);
  62. DDX_Control(pDX, IDC_HASH_ENTRY_SECURITY_LEVEL, m_securityLevelCombo);
  63. //}}AFX_DATA_MAP
  64. }
  65. BEGIN_MESSAGE_MAP(CSaferEntryHashPropertyPage, CSaferPropertyPage)
  66. //{{AFX_MSG_MAP(CSaferEntryHashPropertyPage)
  67. ON_BN_CLICKED(IDC_HASH_ENTRY_BROWSE, OnHashEntryBrowse)
  68. ON_EN_CHANGE(IDC_HASH_ENTRY_DESCRIPTION, OnChangeHashEntryDescription)
  69. ON_CBN_SELCHANGE(IDC_HASH_ENTRY_SECURITY_LEVEL, OnSelchangeHashEntrySecurityLevel)
  70. ON_EN_CHANGE(IDC_HASH_HASHED_FILE_PATH, OnChangeHashHashedFilePath)
  71. ON_EN_SETFOCUS(IDC_HASH_HASHED_FILE_PATH, OnSetfocusHashHashedFilePath)
  72. ON_EN_CHANGE(IDC_HASH_ENTRY_HASHFILE_DETAILS, OnChangeHashEntryHashfileDetails)
  73. //}}AFX_MSG_MAP
  74. END_MESSAGE_MAP()
  75. /////////////////////////////////////////////////////////////////////////////
  76. // CSaferEntryHashPropertyPage message handlers
  77. void CSaferEntryHashPropertyPage::DoContextHelp (HWND hWndControl)
  78. {
  79. _TRACE (1, L"Entering CSaferEntryHashPropertyPage::DoContextHelp\n");
  80. static const DWORD help_map[] =
  81. {
  82. IDC_HASH_ENTRY_HASHFILE_DETAILS, IDH_HASH_ENTRY_APPLICATION_NAME,
  83. IDC_HASH_ENTRY_BROWSE, IDH_HASH_ENTRY_BROWSE,
  84. IDC_HASH_ENTRY_DESCRIPTION, IDH_HASH_ENTRY_DESCRIPTION,
  85. IDC_HASH_ENTRY_LAST_MODIFIED, IDH_HASH_ENTRY_LAST_MODIFIED,
  86. IDC_HASH_HASHED_FILE_PATH, IDH_HASH_HASHED_FILE_PATH,
  87. IDC_HASH_ENTRY_SECURITY_LEVEL, IDH_HASH_ENTRY_SECURITY_LEVEL,
  88. 0, 0
  89. };
  90. switch (::GetDlgCtrlID (hWndControl))
  91. {
  92. case IDC_HASH_ENTRY_HASHFILE_DETAILS:
  93. case IDC_HASH_ENTRY_BROWSE:
  94. case IDC_HASH_ENTRY_DESCRIPTION:
  95. case IDC_HASH_ENTRY_LAST_MODIFIED:
  96. case IDC_HASH_HASHED_FILE_PATH:
  97. case IDC_HASH_ENTRY_SECURITY_LEVEL:
  98. if ( !::WinHelp (
  99. hWndControl,
  100. GetF1HelpFilename(),
  101. HELP_WM_HELP,
  102. (DWORD_PTR) help_map) )
  103. {
  104. _TRACE (0, L"WinHelp () failed: 0x%x\n", GetLastError ());
  105. }
  106. break;
  107. default:
  108. break;
  109. }
  110. _TRACE (-1, L"Leaving CSaferEntryHashPropertyPage::DoContextHelp\n");
  111. }
  112. BOOL CSaferEntryHashPropertyPage::OnInitDialog()
  113. {
  114. CSaferPropertyPage::OnInitDialog();
  115. DWORD dwFlags = 0;
  116. m_rSaferEntry.GetFlags (dwFlags);
  117. ASSERT (m_pCompData);
  118. if ( m_pCompData )
  119. {
  120. CPolicyKey policyKey (m_pCompData->m_pGPEInformation,
  121. SAFER_HKLM_REGBASE,
  122. m_bIsMachine);
  123. InitializeSecurityLevelComboBox (m_securityLevelCombo, false,
  124. m_rSaferEntry.GetLevel (), policyKey.GetKey (),
  125. m_pCompData->m_pdwSaferLevels,
  126. m_bIsMachine);
  127. m_hashFileDetailsEdit.SetWindowText (m_rSaferEntry.GetHashFriendlyName ());
  128. m_descriptionEdit.SetLimitText (SAFER_MAX_DESCRIPTION_SIZE-1);
  129. m_descriptionEdit.SetWindowText (m_rSaferEntry.GetDescription ());
  130. SetDlgItemText (IDC_HASH_ENTRY_LAST_MODIFIED, m_rSaferEntry.GetLongLastModified ());
  131. SendDlgItemMessage (IDC_HASH_HASHED_FILE_PATH, EM_LIMITTEXT, 64);
  132. if ( m_bReadOnly )
  133. {
  134. SendDlgItemMessage (IDC_HASH_HASHED_FILE_PATH, EM_SETREADONLY, TRUE);
  135. m_securityLevelCombo.EnableWindow (FALSE);
  136. GetDlgItem (IDC_HASH_ENTRY_BROWSE)->EnableWindow (FALSE);
  137. m_descriptionEdit.SendMessage (EM_SETREADONLY, TRUE);
  138. m_hashFileDetailsEdit.SendMessage (EM_SETREADONLY, TRUE);
  139. }
  140. if ( m_cbFileHash )
  141. {
  142. // Only allow editing on the creation of a new hash
  143. SendDlgItemMessage (IDC_HASH_HASHED_FILE_PATH, EM_SETREADONLY, TRUE);
  144. FormatAndDisplayHash ();
  145. CString szText;
  146. VERIFY (szText.LoadString (IDS_HASH_TITLE));
  147. SetDlgItemText (IDC_HASH_TITLE, szText);
  148. SetDlgItemText (IDC_HASH_INSTRUCTIONS, L"");
  149. }
  150. else
  151. {
  152. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->ShowWindow (SW_HIDE);
  153. GetDlgItem (IDC_HASH_ENTRY_LAST_MODIFIED)->ShowWindow (SW_HIDE);
  154. }
  155. }
  156. return TRUE; // return TRUE unless you set the focus to a control
  157. // EXCEPTION: OCX Property Pages should return FALSE
  158. }
  159. typedef struct tagVERHEAD {
  160. WORD wTotLen;
  161. WORD wValLen;
  162. WORD wType; /* always 0 */
  163. WCHAR szKey[(sizeof("VS_VERSION_INFO")+3)&~03];
  164. VS_FIXEDFILEINFO vsf;
  165. } VERHEAD ;
  166. /*
  167. * [alanau]
  168. *
  169. * MyGetFileVersionInfo: Maps a file directly without using LoadLibrary. This ensures
  170. * that the right version of the file is examined without regard to where the loaded image
  171. * is. Since this is a local function, it allocates the memory which is freed by the caller.
  172. * This makes it slightly more efficient than a GetFileVersionInfoSize/GetFileVersionInfo pair.
  173. */
  174. BOOL CSaferEntryHashPropertyPage::MyGetFileVersionInfo(PCWSTR lpszFilename, PVOID *lpVersionInfo)
  175. {
  176. HINSTANCE hinst = 0;
  177. HRSRC hVerRes = 0;
  178. HANDLE hFile = NULL;
  179. HANDLE hMapping = NULL;
  180. LPVOID pDllBase = NULL;
  181. VERHEAD *pVerHead = 0;
  182. BOOL bResult = FALSE;
  183. DWORD dwHandle = 0;
  184. DWORD dwLength = 0;
  185. ASSERT (lpszFilename);
  186. if ( !lpszFilename )
  187. return FALSE;
  188. ASSERT (lpVersionInfo);
  189. if (!lpVersionInfo)
  190. return FALSE;
  191. *lpVersionInfo = NULL;
  192. // security review 2/25/2002 BryanWal ok - we're only opening this to read
  193. // We shouldn't have to worry about file name canonicalization here since
  194. // we're only opening the file to read and the user can only do this by
  195. // hand here.
  196. __try {
  197. hFile = ::CreateFile( lpszFilename,
  198. GENERIC_READ,
  199. FILE_SHARE_READ,
  200. NULL,
  201. OPEN_EXISTING,
  202. 0,
  203. NULL);
  204. if (hFile != INVALID_HANDLE_VALUE)
  205. {
  206. // security review 2/25/2002 BryanWal ok - file path is from GetOpenFileName
  207. hMapping = ::CreateFileMapping (hFile,
  208. NULL,
  209. PAGE_READONLY,
  210. 0,
  211. 0,
  212. NULL);
  213. if ( hMapping )
  214. {
  215. // NTRAID - 554171 Safer: MapViewOfFileEx should be protected with SEH - potential exception
  216. pDllBase = ::MapViewOfFileEx( hMapping,
  217. FILE_MAP_READ,
  218. 0,
  219. 0,
  220. 0,
  221. NULL);
  222. if ( pDllBase )
  223. {
  224. hinst = (HMODULE)((ULONG_PTR)pDllBase | 0x00000001);
  225. hVerRes = FindResource(hinst, MAKEINTRESOURCE(VS_VERSION_INFO), VS_FILE_INFO);
  226. if (hVerRes == NULL)
  227. {
  228. // Probably a 16-bit file. Fall back to system APIs.
  229. dwLength = GetFileVersionInfoSize(lpszFilename, &dwHandle);
  230. if( !dwLength )
  231. {
  232. if(!GetLastError())
  233. SetLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
  234. __leave;
  235. }
  236. *lpVersionInfo = ::LocalAlloc (LPTR, dwLength);
  237. if ( !(*lpVersionInfo) )
  238. __leave;
  239. if(!GetFileVersionInfo(lpszFilename, 0, dwLength, *lpVersionInfo))
  240. __leave;
  241. bResult = TRUE;
  242. __leave;
  243. }
  244. pVerHead = (VERHEAD*)LoadResource(hinst, hVerRes);
  245. if ( pVerHead )
  246. {
  247. // security review 2/25/2002 BryanWal
  248. *lpVersionInfo = ::LocalAlloc (LPTR, pVerHead->wTotLen);
  249. if ( *lpVersionInfo )
  250. {
  251. // security review 2/25/2002 BryanWal ok
  252. memcpy(*lpVersionInfo, (PVOID)pVerHead, pVerHead->wTotLen);
  253. bResult = TRUE;
  254. }
  255. }
  256. }
  257. }
  258. }
  259. }
  260. __finally
  261. {
  262. if (hFile)
  263. CloseHandle(hFile);
  264. if (hMapping)
  265. CloseHandle(hMapping);
  266. if (pDllBase)
  267. UnmapViewOfFile(pDllBase);
  268. if (*lpVersionInfo && bResult == FALSE)
  269. ::LocalFree (*lpVersionInfo);
  270. }
  271. return bResult;
  272. }
  273. ///////////////////////////////////////////////////////////////////////////////
  274. //
  275. // Method: OnHashEntryBrowse
  276. //
  277. // Purpose: Allow the user to browse for a file, then create a hash and an
  278. // output string for use as the friendly name, using the following
  279. // rules:
  280. //
  281. // If either the product name or description information is found in
  282. // the version resource, provide the following (in order):
  283. //
  284. // Description
  285. // Product name
  286. // Company name
  287. // File name
  288. // Fixed file version
  289. //
  290. // Details:
  291. // 1) Use the fixed file version, since that is what is shown in the
  292. // Windows Explorer properties.
  293. // 2) Prefer the long file name to the 8.3 name.
  294. // 3) Delimit the fields with '\n'.
  295. // 4) If the field is missing, don't output the field or the delimiter
  296. // 5) Instead of displaying the file version on a new line, display
  297. // it after the file name in parens, as in "Filename (1.0.0.0)"
  298. // 6) Since we are limited to 256 TCHARs, we have to accomodate long
  299. // text. First, format the text as described above to determine
  300. // its length. If it is too long, truncate one field at a time in
  301. // the following order: Company name, Description, Product name.
  302. // To truncate a field, set it to a maximum of 60 TCHARs, then
  303. // append a "...\n" to visually indicate that the field was
  304. // truncated. Lastly, if the text is still to long, use the 8.3
  305. // file name instead of the long filename.
  306. //
  307. // If neither the product name nor description information is found,
  308. // provide the following (in order):
  309. //
  310. // File name
  311. // File size
  312. // File last modified date
  313. //
  314. // Details:
  315. // 1) If the file size is < 1 KB, display the number in bytes, as in
  316. // "123 bytes". If the file size is >= 1 KB, display in KB, as in
  317. // "123 KB". Of course, 1 KB is 1024 bytes. Note that the older
  318. // style format "123K" is no longer used in Windows.
  319. // 2) For the last modified date, use the short format version in the
  320. // user's current locale.
  321. // 3) Delimit the fields with '\n'.
  322. // 4) If the field is missing, don't output the field or the delimiter
  323. //
  324. ///////////////////////////////////////////////////////////////////////////////
  325. void CSaferEntryHashPropertyPage::OnHashEntryBrowse()
  326. {
  327. CString szFileFilter;
  328. VERIFY (szFileFilter.LoadString (IDS_SAFER_PATH_ENTRY_FILE_FILTER));
  329. // replace "|" with 0;
  330. // security review 2/25/2002 BryanWal ok
  331. const size_t nFilterLen = wcslen (szFileFilter) + 1; // + 1 for null term.
  332. PWSTR pszFileFilter = new WCHAR [nFilterLen];
  333. if ( pszFileFilter )
  334. {
  335. // security review 2/25/2002 BryanWal ok
  336. wcscpy (pszFileFilter, szFileFilter);
  337. for (int nIndex = 0; nIndex < nFilterLen; nIndex++)
  338. {
  339. if ( L'|' == pszFileFilter[nIndex] )
  340. pszFileFilter[nIndex] = 0;
  341. }
  342. WCHAR szFile[MAX_PATH];
  343. // security review 2/25/2002 BryanWal ok
  344. ::ZeroMemory (szFile, sizeof (szFile));
  345. ASSERT (wcslen (m_szLastOpenedFile) < MAX_PATH);
  346. // security review 2/25/2002 BryanWal ok - m_szLastOpenedFile always comes from GetOpenFileName ()
  347. wcsncpy (szFile, m_szLastOpenedFile, MAX_PATH - 1);
  348. OPENFILENAME ofn;
  349. // security review 2/25/2002 BryanWal ok
  350. ::ZeroMemory (&ofn, sizeof (ofn));
  351. ofn.lStructSize = sizeof (OPENFILENAME);
  352. ofn.hwndOwner = m_hWnd;
  353. ofn.lpstrFilter = (PCWSTR) pszFileFilter;
  354. ofn.lpstrFile = szFile;
  355. ofn.nMaxFile = MAX_PATH;
  356. ofn.Flags = OFN_DONTADDTORECENT |
  357. OFN_FORCESHOWHIDDEN | OFN_HIDEREADONLY;
  358. CThemeContextActivator activator;
  359. BOOL bResult = ::GetOpenFileName (&ofn);
  360. if ( bResult )
  361. {
  362. m_szLastOpenedFile = ofn.lpstrFile;
  363. // security review 2/25/2002 BryanWal ok - filename is from GetOpenFileName ()
  364. HANDLE hFile = ::CreateFile(
  365. ofn.lpstrFile, // file name
  366. GENERIC_READ, // access mode
  367. FILE_SHARE_READ, // share mode
  368. 0, // SD
  369. OPEN_EXISTING, // how to create
  370. FILE_ATTRIBUTE_NORMAL, // file attributes
  371. 0 ); // handle to template file
  372. if ( INVALID_HANDLE_VALUE != hFile )
  373. {
  374. bResult = GetFileSizeEx(
  375. hFile, // handle to file
  376. (PLARGE_INTEGER) &m_nFileSize); // file size
  377. if ( !bResult )
  378. {
  379. DWORD dwErr = GetLastError ();
  380. CloseHandle (hFile);
  381. _TRACE (0, L"GetFileSizeEx () failed: 0x%x\n", dwErr);
  382. CString text;
  383. CString caption;
  384. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  385. text.FormatMessage (IDS_CANNOT_GET_FILESIZE, ofn.lpstrFile,
  386. GetSystemMessage (dwErr));
  387. MessageBox (text, caption, MB_OK);
  388. return;
  389. }
  390. if ( 0 == m_nFileSize )
  391. {
  392. CString text;
  393. CString caption;
  394. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  395. text.FormatMessage (IDS_ZERO_BYTE_FILE_CANNOT_HASH, ofn.lpstrFile);
  396. MessageBox (text, caption, MB_OK);
  397. return;
  398. }
  399. FILETIME ftLastModified;
  400. HRESULT hr = S_OK;
  401. bResult = ::GetFileTime (hFile, // handle to file
  402. 0, // creation time
  403. 0, // last access time
  404. &ftLastModified); // last write time
  405. // security review 2/25/2002 BryanWal ok
  406. ::ZeroMemory (m_rgbFileHash, sizeof (m_rgbFileHash));
  407. // NTRAID 622838 SAFER UI: Always use MD5 hash on DLLs.
  408. if ( FileIsDLL (ofn.lpstrFile) )
  409. {
  410. // File is DLL - look for MD5 hash
  411. m_hashAlgid = 0;
  412. hr = ComputeMD5Hash (hFile, m_rgbFileHash, m_cbFileHash);
  413. if ( SUCCEEDED (hr) )
  414. {
  415. if ( SHA1_HASH_LEN == m_cbFileHash )
  416. m_hashAlgid = CALG_SHA;
  417. else if ( MD5_HASH_LEN == m_cbFileHash )
  418. m_hashAlgid = CALG_MD5;
  419. else
  420. {
  421. ASSERT (0);
  422. }
  423. }
  424. }
  425. else
  426. {
  427. hr = GetSignedFileHash (ofn.lpstrFile, m_rgbFileHash,
  428. &m_cbFileHash, &m_hashAlgid);
  429. if ( FAILED (hr) )
  430. {
  431. if ( TRUST_E_NOSIGNATURE == hr )
  432. {
  433. // File is not signed - look for MD5 hash
  434. m_hashAlgid = 0;
  435. hr = ComputeMD5Hash (hFile, m_rgbFileHash, m_cbFileHash);
  436. if ( SUCCEEDED (hr) )
  437. {
  438. if ( SHA1_HASH_LEN == m_cbFileHash )
  439. m_hashAlgid = CALG_SHA;
  440. else if ( MD5_HASH_LEN == m_cbFileHash )
  441. m_hashAlgid = CALG_MD5;
  442. else
  443. {
  444. ASSERT (0);
  445. }
  446. }
  447. }
  448. else
  449. {
  450. // NTRAID #476946 SAFER UI: If hash of signed file
  451. // fails, MD5 hash should not be called
  452. CString text;
  453. CString caption;
  454. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  455. text.FormatMessage (IDS_SIGNED_FILE_HASH_FAILURE,
  456. ofn.lpstrFile, GetSystemMessage (hr));
  457. MessageBox (text, caption, MB_OK);
  458. return;
  459. }
  460. }
  461. }
  462. VERIFY (CloseHandle (hFile));
  463. hFile = 0;
  464. if ( SUCCEEDED (hr) )
  465. {
  466. FormatAndDisplayHash ();
  467. PBYTE pData = 0;
  468. bResult = MyGetFileVersionInfo (ofn.lpstrFile, (LPVOID*) &pData);
  469. if ( bResult )
  470. {
  471. CString infoString = BuildHashFileInfoString (pData);
  472. m_hashFileDetailsEdit.SetWindowText (infoString);
  473. m_bDirty = true;
  474. SetModified ();
  475. }
  476. else
  477. {
  478. CString infoString (wcsrchr(ofn.lpstrFile, L'\\') + 1);
  479. CString szDate;
  480. infoString += pcszNEWLINE;
  481. WCHAR szBuffer[32];
  482. CString szText;
  483. if ( m_nFileSize < 1024 )
  484. {
  485. // ISSUE - convert to strsafe, wsnprintf?
  486. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  487. wsprintf (szBuffer, L"%u", m_nFileSize);
  488. infoString += szBuffer;
  489. VERIFY (szText.LoadString (IDS_BYTES));
  490. infoString += L" ";
  491. infoString += szText;
  492. }
  493. else
  494. {
  495. __int64 nFileSize = m_nFileSize;
  496. nFileSize += 1024; // this causes us to round up
  497. nFileSize /= 1024;
  498. // ISSUE - convert to strsafe, wsnprintf?
  499. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  500. wsprintf (szBuffer, L"%u ", nFileSize);
  501. infoString += szBuffer;
  502. VERIFY (szText.LoadString (IDS_KB));
  503. infoString += L" ";
  504. infoString += szText;
  505. }
  506. hr = FormatDate (ftLastModified, szDate,
  507. DATE_SHORTDATE, true);
  508. if ( SUCCEEDED (hr) )
  509. {
  510. infoString += pcszNEWLINE;
  511. infoString += szDate;
  512. }
  513. m_hashFileDetailsEdit.SetWindowText (infoString);
  514. m_bDirty = true;
  515. SetModified ();
  516. }
  517. if ( pData )
  518. ::LocalFree (pData);
  519. }
  520. else
  521. {
  522. CString text;
  523. CString caption;
  524. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  525. text.FormatMessage (IDS_CANNOT_HASH_FILE, ofn.lpstrFile,
  526. GetSystemMessage (hr));
  527. MessageBox (text, caption, MB_OK);
  528. }
  529. }
  530. else
  531. {
  532. DWORD dwErr = GetLastError ();
  533. _TRACE (0, L"CreateFile (%s, OPEN_EXISTING) failed: 0x%x\n",
  534. ofn.lpstrFile, dwErr);
  535. CString text;
  536. CString caption;
  537. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  538. text.FormatMessage (IDS_FILE_CANNOT_BE_READ, ofn.lpstrFile,
  539. GetSystemMessage (dwErr));
  540. MessageBox (text, caption, MB_OK);
  541. }
  542. }
  543. delete [] pszFileFilter;
  544. }
  545. }
  546. bool CSaferEntryHashPropertyPage::FileIsDLL (const CString& szFilePath)
  547. {
  548. _TRACE (1, L"Entering CSaferEntryHashPropertyPage::FileIsDLL (%s)\n", (PCWSTR) szFilePath);
  549. bool bFileIsDLL = false;
  550. int nLen = ::WideCharToMultiByte (
  551. ::GetACP (), // code page
  552. 0, // flags
  553. szFilePath, // widechar string to convert
  554. -1, // length of widechar string, -1 means assume null termination
  555. 0, // char buffer to receive string - ignored if next parameter is 0
  556. 0, // length of buffer, 0 means return needed length
  557. 0,
  558. 0);
  559. if ( nLen > 0 )
  560. {
  561. PSTR pszFilePath = new char[nLen];
  562. if ( pszFilePath )
  563. {
  564. nLen = ::WideCharToMultiByte (
  565. ::GetACP (), // code page
  566. 0, // flags
  567. szFilePath, // widechar string to convert
  568. -1, // length of widechar string, -1 means assume null termination
  569. pszFilePath, // char buffer to receive string
  570. nLen, // length of buffer
  571. 0,
  572. 0);
  573. if ( nLen > 0 )
  574. {
  575. PLOADED_IMAGE pLoadedImage = ::ImageLoad (pszFilePath, NULL);
  576. if ( pLoadedImage )
  577. {
  578. if ( IMAGE_FILE_DLL & pLoadedImage->Characteristics )
  579. bFileIsDLL = true;
  580. VERIFY (::ImageUnload (pLoadedImage));
  581. }
  582. else
  583. {
  584. _TRACE (0, L"ImageLoad (%s) failed: 0x%x\n", (PCWSTR) szFilePath, GetLastError ());
  585. }
  586. }
  587. else
  588. {
  589. _TRACE (0, L"WideCharToMultiByte (%s) failed: 0x%x\n", szFilePath,
  590. GetLastError ());
  591. }
  592. delete [] pszFilePath;
  593. }
  594. }
  595. else
  596. {
  597. _TRACE (0, L"WideCharToMultiByte (%s) failed: 0x%x\n", szFilePath,
  598. GetLastError ());
  599. }
  600. _TRACE (-1, L"Leaving CSaferEntryHashPropertyPage::FileIsDLL (%s): %s\n",
  601. (PCWSTR) szFilePath, bFileIsDLL ? L"true" : L"false");
  602. return bFileIsDLL;
  603. }
  604. /***************************************************************************\
  605. *
  606. * BuildHashFileInfoString()
  607. *
  608. * Given a file name, GetVersion retrieves the version
  609. * information from the specified file.
  610. *
  611. *
  612. \***************************************************************************/
  613. const PWSTR VERSION_INFO_KEY_ROOT = L"\\StringFileInfo\\";
  614. CString CSaferEntryHashPropertyPage::BuildHashFileInfoString (const PVOID pData)
  615. {
  616. CString szInfoString;
  617. PVOID lpInfo = 0;
  618. UINT cch = 0;
  619. CString key;
  620. WCHAR szBuffer[10];
  621. CString keyBase;
  622. // ISSUE - convert to strsafe, wsnprintf?
  623. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  624. wsprintf (szBuffer, L"%04X", GetUserDefaultLangID ());
  625. wcscat (szBuffer, L"04B0");
  626. keyBase = VERSION_INFO_KEY_ROOT;
  627. keyBase += szBuffer;
  628. keyBase += L"\\";
  629. CString productName;
  630. CString description;
  631. CString companyName;
  632. CString fileName;
  633. CString fileVersion;
  634. CString internalName;
  635. key = keyBase + L"ProductName";
  636. if ( VerQueryValue (pData, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) )
  637. {
  638. productName = (PWSTR) lpInfo;
  639. }
  640. else
  641. {
  642. productName = GetAlternateLanguageVersionInfo (pData, L"ProductName");
  643. }
  644. key = keyBase + L"FileDescription";
  645. if ( VerQueryValue (pData, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) )
  646. {
  647. description = (PWSTR) lpInfo;
  648. }
  649. else
  650. {
  651. description = GetAlternateLanguageVersionInfo (pData, L"FileDescription");
  652. }
  653. key = keyBase + L"CompanyName";
  654. if ( VerQueryValue (pData, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) )
  655. {
  656. companyName = (PWSTR) lpInfo;
  657. }
  658. else
  659. {
  660. companyName = GetAlternateLanguageVersionInfo (pData, L"CompanyName");
  661. }
  662. key = keyBase + L"OriginalFilename";
  663. if ( VerQueryValue (pData, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) )
  664. {
  665. fileName = (PWSTR) lpInfo;
  666. }
  667. else
  668. {
  669. fileName = GetAlternateLanguageVersionInfo (pData, L"OriginalFilename");
  670. }
  671. key = keyBase + L"InternalName";
  672. if ( VerQueryValue (pData, const_cast <PWSTR>((PCWSTR) key), &lpInfo, &cch) )
  673. {
  674. internalName = (PWSTR) lpInfo;
  675. }
  676. else
  677. {
  678. internalName = GetAlternateLanguageVersionInfo (pData, L"InternalName");
  679. }
  680. // Get Fixedlength fileInfo
  681. VS_FIXEDFILEINFO *pFixedFileInfo = 0;
  682. if ( VerQueryValue (pData, L"\\", (PVOID*) &pFixedFileInfo, &cch) )
  683. {
  684. WCHAR szFileVer[32];
  685. // ISSUE - convert to strsafe, wsnprintf?
  686. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  687. wsprintf(szFileVer, L"%u.%u.%u.%u",
  688. HIWORD(pFixedFileInfo->dwFileVersionMS),
  689. LOWORD(pFixedFileInfo->dwFileVersionMS),
  690. HIWORD(pFixedFileInfo->dwFileVersionLS),
  691. LOWORD(pFixedFileInfo->dwFileVersionLS));
  692. fileVersion = szFileVer;
  693. }
  694. int nLen = 0;
  695. do {
  696. szInfoString = ConcatStrings (productName, description, companyName,
  697. fileName, fileVersion, internalName);
  698. nLen = szInfoString.GetLength ();
  699. if ( nLen >= SAFER_MAX_FRIENDLYNAME_SIZE )
  700. {
  701. if ( CheckLengthAndTruncateToken (companyName) )
  702. continue;
  703. if ( CheckLengthAndTruncateToken (description) )
  704. continue;
  705. if ( CheckLengthAndTruncateToken (productName) )
  706. continue;
  707. szInfoString.SetAt (SAFER_MAX_FRIENDLYNAME_SIZE-4, 0);
  708. szInfoString += L"...";
  709. }
  710. } while (nLen >= SAFER_MAX_FRIENDLYNAME_SIZE);
  711. return szInfoString;
  712. }
  713. CString CSaferEntryHashPropertyPage::GetAlternateLanguageVersionInfo (PVOID pData, PCWSTR pszVersionField)
  714. {
  715. PVOID lpInfo = 0;
  716. UINT cch = 0;
  717. CString szInfo;
  718. UINT cbTranslate = 0;
  719. struct LANGANDCODEPAGE {
  720. WORD wLanguage;
  721. WORD wCodePage;
  722. } *lpTranslate;
  723. // Read the list of languages and code pages.
  724. VerQueryValue(pData,
  725. L"\\VarFileInfo\\Translation",
  726. (LPVOID*)&lpTranslate,
  727. &cbTranslate);
  728. // Read the file description for each language and code page.
  729. for (UINT i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
  730. {
  731. WCHAR SubBlock[256];
  732. // ISSUE - convert to strsafe, wsnprintf?
  733. // NTRAID Bug9 538774 Security: certmgr.dll : convert to strsafe string functions
  734. wsprintf( SubBlock,
  735. L"\\StringFileInfo\\%04x%04x\\%s",
  736. lpTranslate[i].wLanguage,
  737. lpTranslate[i].wCodePage,
  738. pszVersionField);
  739. // Retrieve file description for language and code page "i".
  740. if ( VerQueryValue(pData,
  741. SubBlock,
  742. &lpInfo,
  743. &cch) )
  744. {
  745. szInfo = (PWSTR) lpInfo;
  746. break;
  747. }
  748. }
  749. return szInfo;
  750. }
  751. bool CSaferEntryHashPropertyPage::CheckLengthAndTruncateToken (CString& token)
  752. {
  753. bool bResult = false;
  754. const int nMAX_ITEM_LEN = 60;
  755. int nItemLen = token.GetLength ();
  756. if ( nItemLen > nMAX_ITEM_LEN )
  757. {
  758. token.SetAt (nMAX_ITEM_LEN-5, 0);
  759. token += L"...";
  760. token += pcszNEWLINE;
  761. bResult = true;
  762. }
  763. return bResult;
  764. }
  765. CString CSaferEntryHashPropertyPage::ConcatStrings (
  766. const CString& productName,
  767. const CString& description,
  768. const CString& companyName,
  769. const CString& fileName,
  770. const CString& fileVersion,
  771. const CString& internalName)
  772. {
  773. CString szInfoString;
  774. // format to be as follows:
  775. //
  776. // ATTRIB.EXE (5.1.2600.0)
  777. // InternalModuleName (if present. If not present just skip)
  778. // Attribute Utility
  779. // Microsoft� Windows� Operating System
  780. // Microsoft Corporation
  781. if ( !fileName.IsEmpty () )
  782. szInfoString += fileName;
  783. if ( !fileVersion.IsEmpty () )
  784. {
  785. szInfoString += L" (";
  786. szInfoString += fileVersion + L")";
  787. }
  788. if ( !szInfoString.IsEmpty () )
  789. szInfoString += pcszNEWLINE;
  790. if ( !internalName.IsEmpty () )
  791. szInfoString += internalName + pcszNEWLINE;
  792. if ( !description.IsEmpty () )
  793. szInfoString += description + pcszNEWLINE;
  794. if ( !productName.IsEmpty () )
  795. szInfoString += productName + pcszNEWLINE;
  796. if ( !companyName.IsEmpty () )
  797. szInfoString += companyName;
  798. return szInfoString;
  799. }
  800. BOOL CSaferEntryHashPropertyPage::OnApply()
  801. {
  802. CString szText;
  803. CThemeContextActivator activator;
  804. GetDlgItemText (IDC_HASH_HASHED_FILE_PATH, szText);
  805. if ( szText.IsEmpty () )
  806. {
  807. CString szCaption;
  808. VERIFY (szCaption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  809. VERIFY (szText.LoadString (IDS_USER_MUST_ENTER_HASH));
  810. MessageBox (szText, szCaption, MB_OK);
  811. GetDlgItem (IDC_HASH_HASHED_FILE_PATH)->SetFocus ();
  812. return FALSE;
  813. }
  814. if ( !m_bReadOnly && m_bDirty )
  815. {
  816. if ( !ConvertStringToHash ((PCWSTR) szText) )
  817. {
  818. GetDlgItem (IDC_HASH_HASHED_FILE_PATH)->SetFocus ();
  819. return FALSE;
  820. }
  821. // Get image size and hash type
  822. bool bBadFormat = false;
  823. int nFirstColon = szText.Find (L":", 0);
  824. if ( -1 != nFirstColon )
  825. {
  826. int nSecondColon = szText.Find (L":", nFirstColon+1);
  827. if ( -1 != nSecondColon )
  828. {
  829. CString szImageSize = szText.Mid (nFirstColon+1, nSecondColon - (nFirstColon + 1));
  830. // security review 2/25/2002 BryanWal ok
  831. CString szHashType = szText.Right (((int) wcslen (szText)) - (nSecondColon + 1));
  832. m_nFileSize = wcstol (szImageSize, 0, 10);
  833. m_hashAlgid = wcstol (szHashType, 0, 10);
  834. }
  835. else
  836. bBadFormat = true;
  837. }
  838. else
  839. bBadFormat = true;
  840. if ( bBadFormat )
  841. {
  842. CString caption;
  843. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  844. VERIFY (szText.LoadString (IDS_HASH_STRING_BAD_FORMAT));
  845. MessageBox (szText, caption, MB_OK);
  846. return FALSE;
  847. }
  848. if ( !m_cbFileHash )
  849. {
  850. CString caption;
  851. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  852. VERIFY (szText.LoadString (IDS_NO_APPLICATION_SELECTED));
  853. MessageBox (szText, caption, MB_OK);
  854. GetDlgItem (IDC_HASH_ENTRY_BROWSE)->SetFocus ();
  855. return FALSE;
  856. }
  857. if ( m_bDirty )
  858. {
  859. // Set the level
  860. int nCurSel = m_securityLevelCombo.GetCurSel ();
  861. ASSERT (CB_ERR != nCurSel);
  862. m_rSaferEntry.SetLevel ((DWORD) m_securityLevelCombo.GetItemData (nCurSel));
  863. // Set description
  864. m_descriptionEdit.GetWindowText (szText);
  865. m_rSaferEntry.SetDescription (szText);
  866. // Set friendly name
  867. m_hashFileDetailsEdit.GetWindowText (szText);
  868. m_rSaferEntry.SetHashFriendlyName (szText);
  869. // Get and save flags
  870. DWORD dwFlags = 0;
  871. m_rSaferEntry.SetFlags (dwFlags);
  872. m_rSaferEntry.SetHash (m_rgbFileHash, m_cbFileHash, m_nFileSize, m_hashAlgid);
  873. HRESULT hr = m_rSaferEntry.Save ();
  874. if ( SUCCEEDED (hr) )
  875. {
  876. if ( m_lNotifyHandle )
  877. MMCPropertyChangeNotify (
  878. m_lNotifyHandle, // handle to a notification
  879. (LPARAM) m_pDataObject); // unique identifier
  880. if ( m_pbObjectCreated )
  881. *m_pbObjectCreated = true;
  882. m_rSaferEntry.Refresh ();
  883. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->ShowWindow (SW_SHOW);
  884. GetDlgItem (IDC_HASH_ENTRY_LAST_MODIFIED)->ShowWindow (SW_SHOW);
  885. GetDlgItem (IDC_DATE_LAST_MODIFIED_LABEL)->UpdateWindow ();
  886. GetDlgItem (IDC_HASH_ENTRY_LAST_MODIFIED)->UpdateWindow ();
  887. SetDlgItemText (IDC_HASH_ENTRY_LAST_MODIFIED, m_rSaferEntry.GetLongLastModified ());
  888. m_bDirty = false;
  889. }
  890. else
  891. {
  892. CString caption;
  893. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  894. if ( HRESULT_FROM_WIN32 (ERROR_INVALID_PARAMETER) != hr )
  895. szText.FormatMessage (IDS_ERROR_SAVING_ENTRY, GetSystemMessage (hr));
  896. else
  897. VERIFY (szText.LoadString (IDS_HASH_STRING_BAD_FORMAT));
  898. MessageBox (szText, caption, MB_OK);
  899. return FALSE;
  900. }
  901. }
  902. }
  903. return CSaferPropertyPage::OnApply();
  904. }
  905. void CSaferEntryHashPropertyPage::OnChangeHashEntryDescription()
  906. {
  907. m_bDirty = true;
  908. SetModified ();
  909. }
  910. void CSaferEntryHashPropertyPage::OnSelchangeHashEntrySecurityLevel()
  911. {
  912. m_bDirty = true;
  913. SetModified ();
  914. }
  915. void CSaferEntryHashPropertyPage::OnChangeHashHashedFilePath()
  916. {
  917. m_bDirty = true;
  918. SetModified ();
  919. }
  920. bool CSaferEntryHashPropertyPage::FormatMemBufToString(PWSTR *ppString, PBYTE pbData, DWORD cbData)
  921. {
  922. const WCHAR RgwchHex[] = {'0', '1', '2', '3', '4', '5', '6', '7',
  923. '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
  924. DWORD i = 0;
  925. PBYTE pb;
  926. *ppString = (LPWSTR) LocalAlloc (LPTR, ((cbData * 3) * sizeof(WCHAR)));
  927. if ( !*ppString )
  928. {
  929. return false;
  930. }
  931. //
  932. // copy to the buffer
  933. //
  934. pb = pbData;
  935. while (pb <= &(pbData[cbData-1]))
  936. {
  937. (*ppString)[i++] = RgwchHex[(*pb & 0xf0) >> 4];
  938. (*ppString)[i++] = RgwchHex[*pb & 0x0f];
  939. pb++;
  940. }
  941. (*ppString)[i] = 0;
  942. return true;
  943. }
  944. bool CSaferEntryHashPropertyPage::ConvertStringToHash (PCWSTR pszString)
  945. {
  946. _TRACE (1, L"Entering CSaferEntryHashPropertyPage::ConvertStringToHash (%s)\n", pszString);
  947. bool bRetVal = true;
  948. BYTE rgbFileHash[SAFER_MAX_HASH_SIZE];
  949. // security review 2/25/2002 BryanWal ok
  950. ::ZeroMemory (rgbFileHash, sizeof (rgbFileHash));
  951. DWORD cbFileHash = 0;
  952. DWORD dwNumHashChars = 0;
  953. bool bFirst = true;
  954. bool bEndOfHash = false;
  955. CThemeContextActivator activator;
  956. for (int nIndex = 0; !bEndOfHash && pszString[nIndex] && bRetVal; nIndex++)
  957. {
  958. if ( cbFileHash >= SAFER_MAX_HASH_SIZE )
  959. {
  960. CString caption;
  961. CString text;
  962. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  963. text.FormatMessage (IDS_HASH_STRING_TOO_LONG, SAFER_MAX_HASH_SIZE, SAFER_MAX_HASH_SIZE/4);
  964. _TRACE (0, L"%s", (PCWSTR) text);
  965. VERIFY (text.LoadString (IDS_HASH_STRING_BAD_FORMAT));
  966. MessageBox (text, caption, MB_ICONWARNING | MB_OK);
  967. bRetVal = false;
  968. break;
  969. }
  970. dwNumHashChars++;
  971. switch (pszString[nIndex])
  972. {
  973. case L'0':
  974. bFirst = !bFirst;
  975. break;
  976. case L'1':
  977. if ( bFirst )
  978. rgbFileHash[cbFileHash] |= 0x10;
  979. else
  980. rgbFileHash[cbFileHash] |= 0x01;
  981. bFirst = !bFirst;
  982. break;
  983. case L'2':
  984. if ( bFirst )
  985. rgbFileHash[cbFileHash] |= 0x20;
  986. else
  987. rgbFileHash[cbFileHash] |= 0x02;
  988. bFirst = !bFirst;
  989. break;
  990. case L'3':
  991. if ( bFirst )
  992. rgbFileHash[cbFileHash] |= 0x30;
  993. else
  994. rgbFileHash[cbFileHash] |= 0x03;
  995. bFirst = !bFirst;
  996. break;
  997. case L'4':
  998. if ( bFirst )
  999. rgbFileHash[cbFileHash] |= 0x40;
  1000. else
  1001. rgbFileHash[cbFileHash] |= 0x04;
  1002. bFirst = !bFirst;
  1003. break;
  1004. case L'5':
  1005. if ( bFirst )
  1006. rgbFileHash[cbFileHash] |= 0x50;
  1007. else
  1008. rgbFileHash[cbFileHash] |= 0x05;
  1009. bFirst = !bFirst;
  1010. break;
  1011. case L'6':
  1012. if ( bFirst )
  1013. rgbFileHash[cbFileHash] |= 0x60;
  1014. else
  1015. rgbFileHash[cbFileHash] |= 0x06;
  1016. bFirst = !bFirst;
  1017. break;
  1018. case L'7':
  1019. if ( bFirst )
  1020. rgbFileHash[cbFileHash] |= 0x70;
  1021. else
  1022. rgbFileHash[cbFileHash] |= 0x07;
  1023. bFirst = !bFirst;
  1024. break;
  1025. case L'8':
  1026. if ( bFirst )
  1027. rgbFileHash[cbFileHash] |= 0x80;
  1028. else
  1029. rgbFileHash[cbFileHash] |= 0x08;
  1030. bFirst = !bFirst;
  1031. break;
  1032. case L'9':
  1033. if ( bFirst )
  1034. rgbFileHash[cbFileHash] |= 0x90;
  1035. else
  1036. rgbFileHash[cbFileHash] |= 0x09;
  1037. bFirst = !bFirst;
  1038. break;
  1039. case L'a':
  1040. case L'A':
  1041. if ( bFirst )
  1042. rgbFileHash[cbFileHash] |= 0xA0;
  1043. else
  1044. rgbFileHash[cbFileHash] |= 0x0A;
  1045. bFirst = !bFirst;
  1046. break;
  1047. case L'b':
  1048. case L'B':
  1049. if ( bFirst )
  1050. rgbFileHash[cbFileHash] |= 0xB0;
  1051. else
  1052. rgbFileHash[cbFileHash] |= 0x0B;
  1053. bFirst = !bFirst;
  1054. break;
  1055. case L'c':
  1056. case L'C':
  1057. if ( bFirst )
  1058. rgbFileHash[cbFileHash] |= 0xC0;
  1059. else
  1060. rgbFileHash[cbFileHash] |= 0x0C;
  1061. bFirst = !bFirst;
  1062. break;
  1063. case L'd':
  1064. case L'D':
  1065. if ( bFirst )
  1066. rgbFileHash[cbFileHash] |= 0xD0;
  1067. else
  1068. rgbFileHash[cbFileHash] |= 0x0D;
  1069. bFirst = !bFirst;
  1070. break;
  1071. case L'e':
  1072. case L'E':
  1073. if ( bFirst )
  1074. rgbFileHash[cbFileHash] |= 0xE0;
  1075. else
  1076. rgbFileHash[cbFileHash] |= 0x0E;
  1077. bFirst = !bFirst;
  1078. break;
  1079. case L'f':
  1080. case L'F':
  1081. if ( bFirst )
  1082. rgbFileHash[cbFileHash] |= 0xF0;
  1083. else
  1084. rgbFileHash[cbFileHash] |= 0x0F;
  1085. bFirst = !bFirst;
  1086. break;
  1087. case L':':
  1088. // end of hash
  1089. bEndOfHash = true;
  1090. bFirst = !bFirst;
  1091. dwNumHashChars--; // ':' already counted, subtract it
  1092. break;
  1093. default:
  1094. bRetVal = false;
  1095. {
  1096. CString caption;
  1097. CString text;
  1098. WCHAR szChar[2];
  1099. szChar[0] = pszString[nIndex];
  1100. szChar[1] = 0;
  1101. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  1102. text.FormatMessage (IDS_HASH_STRING_INVALID_CHAR, szChar);
  1103. _TRACE (0, L"%s", (PCWSTR) text);
  1104. VERIFY (text.LoadString (IDS_HASH_STRING_BAD_FORMAT));
  1105. MessageBox (text, caption, MB_ICONWARNING | MB_OK);
  1106. }
  1107. break;
  1108. }
  1109. if ( bFirst )
  1110. cbFileHash++;
  1111. }
  1112. if ( bRetVal )
  1113. {
  1114. // 2 characters map to 1 each byte in the hash
  1115. if ( MD5_HASH_LEN != dwNumHashChars/2 && SHA1_HASH_LEN != dwNumHashChars/2 )
  1116. {
  1117. CString caption;
  1118. CString text;
  1119. VERIFY (caption.LoadString (IDS_SAFER_WINDOWS_NODE_NAME));
  1120. VERIFY (text.LoadString (IDS_HASH_INVALID_LENGTH));
  1121. _TRACE (0, L"%s", (PCWSTR) text);
  1122. VERIFY (text.LoadString (IDS_HASH_STRING_BAD_FORMAT));
  1123. MessageBox (text, caption, MB_ICONWARNING | MB_OK);
  1124. bRetVal = false;
  1125. }
  1126. else
  1127. {
  1128. m_cbFileHash = cbFileHash;
  1129. // security review 2/25/2002 BryanWal ok
  1130. memcpy (m_rgbFileHash, rgbFileHash, sizeof (m_rgbFileHash));
  1131. }
  1132. }
  1133. _TRACE (-1, L"Leaving CSaferEntryHashPropertyPage::ConvertStringToHash (): %s\n",
  1134. bRetVal ? L"true" : L"false");
  1135. return bRetVal;
  1136. }
  1137. void CSaferEntryHashPropertyPage::OnSetfocusHashHashedFilePath()
  1138. {
  1139. if ( m_bFirst )
  1140. {
  1141. if ( true == m_bReadOnly )
  1142. SendDlgItemMessage (IDC_HASH_HASHED_FILE_PATH, EM_SETSEL, (WPARAM) 0, 0);
  1143. m_bFirst = false;
  1144. }
  1145. }
  1146. void CSaferEntryHashPropertyPage::FormatAndDisplayHash ()
  1147. {
  1148. PWSTR pwszText = 0;
  1149. if ( FormatMemBufToString (&pwszText, m_rgbFileHash, m_cbFileHash) && pwszText )
  1150. {
  1151. // security review 2/25/2002 BryanWal ok -
  1152. // NOTICE: MSDN indicates result can be up to 33 bytes (for ltoa, so
  1153. // I assume it's 33 wide-chars for ltow)
  1154. WCHAR szAlgID[34];
  1155. _ltow (m_hashAlgid, szAlgID, 10);
  1156. PCWSTR szFormat = L"%s:%ld:";
  1157. static size_t cchWidthFormat = wcslen (szFormat); // no need to recalculate every time
  1158. PCWSTR szInt64Max = L"18,446,744,073,709,551,615"; // from MSDN
  1159. static size_t cchWidthInt64Max = wcslen (szInt64Max); // no need to recalculate every time
  1160. // security review 2/25/2002 BryanWal ok
  1161. // NTRAID# 554409 Security: Safer: buffer overflow: need to alloc string buf dynamically
  1162. PWSTR pszFormattedText = new WCHAR[wcslen (pwszText) + cchWidthFormat + wcslen (szAlgID) + cchWidthInt64Max + 1];
  1163. if ( pszFormattedText )
  1164. {
  1165. // security review 2/25/2002 BryanWal
  1166. wsprintf (pszFormattedText, szFormat, pwszText,
  1167. m_nFileSize);
  1168. wcscat (pszFormattedText, szAlgID);
  1169. SetDlgItemText (IDC_HASH_HASHED_FILE_PATH,
  1170. pszFormattedText);
  1171. delete [] pszFormattedText;
  1172. }
  1173. ::LocalFree (pwszText);
  1174. }
  1175. }
  1176. void CSaferEntryHashPropertyPage::OnChangeHashEntryHashfileDetails()
  1177. {
  1178. SetModified ();
  1179. m_bDirty = true;
  1180. }