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.

1987 lines
62 KiB

  1. //
  2. // privacyui.cpp - Implements the UI for IE's privacy features
  3. //
  4. // The privacy dialog is managed from this sourcefile.
  5. // The privacy view dialog is also managed from this sourcefile.
  6. #include "priv.h"
  7. #include "resource.h"
  8. #include "privacyui.hpp"
  9. #include <mluisupp.h>
  10. #include "richedit.h"
  11. #include "SmallUtil.hpp"
  12. #define REGSTR_PRIVACYPS_PATHEDIT TEXT("Software\\Policies\\Microsoft\\Internet Explorer")
  13. #define REGSTR_PRIVACYPS_VALUEDIT TEXT("PrivacyAddRemoveSites") // this key is duplicated in cpls\inetcpl\privacyui.cpp
  14. #define REGSTR_PRIVACYPS_PATHPANE TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
  15. #define REGSTR_PRIVACYPS_VALUPANE TEXT("Privacy Settings") // this key is duplicated in cpls\inetcpl\privacyui.cpp
  16. #define REGSTR_PRIVACYPS_PATHTAB TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
  17. #define REGSTR_PRIVACYPS_VALUTAB TEXT("PrivacyTab") // this key is duplicated somewhere else
  18. BOOL allowPerSiteModify()
  19. {
  20. DWORD dwSize, dwRet, dwType, dwValue;
  21. dwSize = sizeof(dwValue);
  22. dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHEDIT,
  23. REGSTR_PRIVACYPS_VALUEDIT, &dwType, &dwValue, &dwSize);
  24. if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
  25. {
  26. return FALSE;
  27. }
  28. dwSize = sizeof(dwValue);
  29. dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHPANE,
  30. REGSTR_PRIVACYPS_VALUPANE, &dwType, &dwValue, &dwSize);
  31. if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
  32. {
  33. return FALSE;
  34. }
  35. dwSize = sizeof(dwValue);
  36. dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHTAB,
  37. REGSTR_PRIVACYPS_VALUTAB, &dwType, &dwValue, &dwSize);
  38. if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
  39. {
  40. return FALSE;
  41. }
  42. return TRUE;
  43. }
  44. struct SPerSiteData;
  45. typedef SPerSiteData* PSPerSiteData;
  46. class CPolicyHunt;
  47. struct SPrivacyDialogData;
  48. typedef SPrivacyDialogData* PSPrivacyDialogData;
  49. //+---------------------------------------------------------------------------
  50. //
  51. // Function: HyperlinkSubclass
  52. //
  53. // Synopsis: subclass for the makeshift hyperlink control
  54. //
  55. // Arguments: [hwnd] -- window handle
  56. // [uMsg] -- message id
  57. // [wParam] -- parameter 1
  58. // [lParam] -- parameter 2
  59. //
  60. // Returns: TRUE if message handled, FALSE otherwise
  61. //
  62. // Notes:
  63. //
  64. //----------------------------------------------------------------------------
  65. LRESULT CALLBACK HyperlinkSubclass (
  66. HWND hwnd,
  67. UINT uMsg,
  68. WPARAM wParam,
  69. LPARAM lParam
  70. )
  71. {
  72. WNDPROC wndproc;
  73. static BOOL fMouseCaptured;
  74. wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
  75. switch ( uMsg )
  76. {
  77. case WM_SETCURSOR:
  78. if (!fMouseCaptured)
  79. {
  80. SetCapture(hwnd);
  81. fMouseCaptured = TRUE;
  82. }
  83. SetCursor(LoadHandCursor(0));
  84. return( TRUE );
  85. case WM_GETDLGCODE:
  86. {
  87. MSG* pmsg;
  88. LRESULT lRet = DLGC_STATIC;
  89. if (((pmsg = (MSG*)lParam)) && ((WM_KEYDOWN == pmsg->message || WM_KEYUP == pmsg->message)))
  90. {
  91. switch(pmsg->wParam)
  92. {
  93. case VK_RETURN:
  94. case VK_SPACE:
  95. lRet |= DLGC_WANTALLKEYS;
  96. break;
  97. default:
  98. break;
  99. }
  100. }
  101. return lRet;
  102. }
  103. case WM_KEYDOWN:
  104. if ((wParam!=VK_SPACE)&&(wParam!=VK_RETURN))
  105. {
  106. break;
  107. }
  108. case WM_LBUTTONUP:
  109. SetFocus(hwnd);
  110. PostMessage( GetParent(hwnd), WM_APP, (WPARAM)GetDlgCtrlID( hwnd), (LPARAM)hwnd);
  111. return( TRUE );
  112. case WM_LBUTTONDBLCLK:
  113. case WM_MBUTTONDBLCLK:
  114. case WM_RBUTTONDBLCLK:
  115. case WM_RBUTTONUP:
  116. case WM_MBUTTONUP:
  117. case WM_RBUTTONDOWN:
  118. case WM_MBUTTONDOWN:
  119. return( TRUE );
  120. case EM_SETSEL:
  121. return( TRUE );
  122. case WM_SETFOCUS:
  123. if ( hwnd == GetFocus() )
  124. {
  125. InvalidateRect(hwnd, NULL, FALSE);
  126. UpdateWindow(hwnd);
  127. SetCursor(LoadHandCursor(0));
  128. return( TRUE );
  129. }
  130. break;
  131. case WM_KILLFOCUS:
  132. InvalidateRect(hwnd, NULL, TRUE);
  133. UpdateWindow(hwnd);
  134. SetCursor(LoadCursor(NULL, IDC_ARROW));
  135. return( TRUE );
  136. case WM_PAINT:
  137. CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam);
  138. if ( hwnd == GetFocus() )
  139. {
  140. DrawFocusRectangle(hwnd, NULL);
  141. }
  142. return( TRUE );
  143. case WM_MOUSEMOVE:
  144. RECT rect;
  145. int xPos, yPos;
  146. // check to see if the mouse is in this windows rect, if not, then reset
  147. // the cursor to an arrow and release the mouse
  148. GetClientRect(hwnd, &rect);
  149. xPos = LOWORD(lParam);
  150. yPos = HIWORD(lParam);
  151. if ((xPos < 0) ||
  152. (yPos < 0) ||
  153. (xPos > (rect.right - rect.left)) ||
  154. (yPos > (rect.bottom - rect.top)))
  155. {
  156. SetCursor(LoadCursor(NULL, IDC_ARROW));
  157. ReleaseCapture();
  158. fMouseCaptured = FALSE;
  159. }
  160. }
  161. return(CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam));
  162. }
  163. // Data structure associated with each site the privacy dialog may show
  164. struct SPerSiteData : public IDispatch
  165. {
  166. BSTR bstrUrl;
  167. BSTR bstrCookieDomain;
  168. BSTR bstrHeaderPolicyRef;
  169. BSTR bstrLinkTagPolicyRef;
  170. DWORD dwFlags;
  171. int iPrivacyImpactResource;
  172. CPolicyHunt* pPolicyHunt;
  173. SPerSiteData();
  174. ~SPerSiteData();
  175. BOOL ReadyForPolicyHunt();
  176. // here is overhead for IDispatch:
  177. virtual ULONG __stdcall AddRef( void );
  178. virtual ULONG __stdcall Release( void );
  179. virtual HRESULT __stdcall
  180. QueryInterface( REFIID iid, void ** ppv);
  181. virtual HRESULT __stdcall
  182. GetTypeInfoCount( unsigned int FAR* pctinfo);
  183. virtual HRESULT __stdcall
  184. GetTypeInfo( unsigned int iTInfo,
  185. LCID lcid,
  186. ITypeInfo FAR* FAR* ppTInfo);
  187. virtual HRESULT __stdcall
  188. GetIDsOfNames( REFIID riid,
  189. OLECHAR FAR* FAR* rgszNames,
  190. unsigned int cNames,
  191. LCID lcid,
  192. DISPID FAR* rgDispId);
  193. virtual HRESULT __stdcall
  194. Invoke( DISPID dispIdMember,
  195. REFIID riid,
  196. LCID lcid,
  197. WORD wFlags,
  198. DISPPARAMS FAR* pDispParams,
  199. VARIANT FAR* pVarResult,
  200. EXCEPINFO FAR* pExcepInfo,
  201. unsigned int FAR* puArgErr);
  202. };
  203. enum enumPolicyHuntResult
  204. {
  205. POLICYHUNT_INPROGRESS,
  206. POLICYHUNT_NOTFOUND,
  207. POLICYHUNT_FOUND,
  208. POLICYHUNT_ERROR,
  209. POLICYHUNT_FORMATERROR,
  210. POLICYHUNT_CANCELLED,
  211. };
  212. class CPolicyHunt : public CCancellableThread
  213. {
  214. public:
  215. CPolicyHunt();
  216. ~CPolicyHunt();
  217. BOOL Initialize( PSPerSiteData pSite);
  218. //BOOL Run(); defined in CCancelableThread
  219. //BOOL IsFinished(); defined in CCancelableThread
  220. //BOOL WaitForNotRunning( DWORD dwMilliseconds, PBOOL pfFinished); defined in CCancelableThread
  221. BOOL GetResult( PDWORD pdwResult); // special handling wraps CCancelableThread::GetResult
  222. LPCWSTR GetResultFilename();
  223. private:
  224. virtual DWORD run();
  225. P3PSignal _p3pSignal;
  226. P3PResource _resourceSite;
  227. CHAR _szPolicy[MAX_URL_STRING];
  228. WCHAR _wszPolicy[MAX_URL_STRING];
  229. WCHAR _wszResultsFile[ MAX_PATH];
  230. HANDLE _hPolicyFile;
  231. PCHAR allocCharFromWChar( LPCWSTR pOriginal);
  232. static BSTR s_pwszPrivacyPolicyTransform;
  233. // the transform is loaded from a resource and does not need
  234. //to be deallocated..
  235. public:
  236. LPCWSTR GetPolicyUrl() { return _wszPolicy;};
  237. static void FreePrivacyPolicyTransform()
  238. {
  239. if( s_pwszPrivacyPolicyTransform != NULL)
  240. {
  241. SysFreeString( s_pwszPrivacyPolicyTransform);
  242. s_pwszPrivacyPolicyTransform = NULL;
  243. }
  244. }
  245. };
  246. BSTR CPolicyHunt::s_pwszPrivacyPolicyTransform = NULL;
  247. //
  248. // data used by privacy dialog
  249. //
  250. struct SPrivacyDialogData
  251. {
  252. // parameters set when initiating the privacy dialog..
  253. IEnumPrivacyRecords *pEnumPrivacyRecords; // enumerator from Trident
  254. LPOLESTR pszName; // site name
  255. BOOL fReportAllSites; // flag: Report all sites? Otherwise, only report impacted
  256. // and their parent sites.
  257. // parameters set within the privacy dialog code.
  258. // listAllSites lists pointers to SPerSiteData for sites
  259. //return from IEnumPrivacyRecords::enum
  260. CQueueSortOf listAllSites;
  261. ULONG countRecordsEnumerated;
  262. SPrivacyDialogData()
  263. {
  264. countRecordsEnumerated = 0;
  265. }
  266. };
  267. SPerSiteData::SPerSiteData()
  268. {
  269. bstrUrl = NULL;
  270. bstrCookieDomain = NULL;
  271. bstrHeaderPolicyRef = NULL;
  272. bstrLinkTagPolicyRef = NULL;
  273. dwFlags = 0;
  274. iPrivacyImpactResource = 0;
  275. pPolicyHunt = NULL;
  276. }
  277. SPerSiteData::~SPerSiteData()
  278. {
  279. if( bstrUrl != NULL)
  280. SysFreeString( bstrUrl);
  281. if( bstrCookieDomain != NULL)
  282. SysFreeString( bstrCookieDomain);
  283. if( bstrHeaderPolicyRef != NULL)
  284. SysFreeString( bstrHeaderPolicyRef);
  285. if( bstrLinkTagPolicyRef != NULL)
  286. SysFreeString( bstrLinkTagPolicyRef);
  287. if( pPolicyHunt != NULL)
  288. delete pPolicyHunt;
  289. }
  290. CPolicyHunt::CPolicyHunt()
  291. {
  292. memset( &_p3pSignal, 0, sizeof(P3PSignal));
  293. memset( &_resourceSite, 0, sizeof(P3PResource));
  294. _szPolicy[0] = '\0';
  295. _wszPolicy[0] = L'\0';
  296. _wszResultsFile[0] = L'\0';
  297. _hPolicyFile = INVALID_HANDLE_VALUE;
  298. }
  299. CPolicyHunt::~CPolicyHunt()
  300. {
  301. if( _hPolicyFile != INVALID_HANDLE_VALUE)
  302. CloseHandle( _hPolicyFile);
  303. if( _wszResultsFile[0] != L'\0')
  304. {
  305. DeleteFile( _wszResultsFile);
  306. }
  307. if( _p3pSignal.hEvent != NULL)
  308. CloseHandle( _p3pSignal.hEvent);
  309. if( _resourceSite.pszLocation != NULL)
  310. delete [] _resourceSite.pszLocation;
  311. if( _resourceSite.pszVerb != NULL)
  312. delete [] _resourceSite.pszVerb;
  313. if( _resourceSite.pszP3PHeaderRef != NULL)
  314. delete [] _resourceSite.pszP3PHeaderRef;
  315. if( _resourceSite.pszLinkTagRef != NULL)
  316. delete [] _resourceSite.pszLinkTagRef;
  317. }
  318. PCHAR CPolicyHunt::allocCharFromWChar( LPCWSTR pOriginal)
  319. {
  320. PCHAR pResult;
  321. if( pOriginal == NULL)
  322. return NULL;
  323. int iSize = 1 + lstrlen( pOriginal);
  324. pResult = new CHAR[ iSize];
  325. if( pResult == NULL)
  326. return NULL;
  327. SHTCharToAnsi( pOriginal, pResult, iSize);
  328. return pResult;
  329. }
  330. BOOL CPolicyHunt::Initialize( PSPerSiteData pSite)
  331. {
  332. if( TRUE != CCancellableThread::Initialize())
  333. return FALSE;
  334. _resourceSite.pszLocation = allocCharFromWChar( pSite->bstrUrl);
  335. _resourceSite.pszVerb = allocCharFromWChar(
  336. (pSite->dwFlags & PRIVACY_URLHASPOSTDATA) ? L"POST" : L"GET");
  337. _resourceSite.pszP3PHeaderRef = allocCharFromWChar( pSite->bstrHeaderPolicyRef);
  338. _resourceSite.pszLinkTagRef = allocCharFromWChar( pSite->bstrLinkTagPolicyRef);
  339. _resourceSite.pContainer = NULL;
  340. return TRUE;
  341. }
  342. BOOL CPolicyHunt::GetResult( PDWORD pdwResult)
  343. {
  344. if( IsFinished())
  345. {
  346. return CCancellableThread::GetResult( pdwResult);
  347. }
  348. *pdwResult = POLICYHUNT_INPROGRESS;
  349. return TRUE;
  350. }
  351. LPCWSTR CPolicyHunt::GetResultFilename()
  352. {
  353. return _wszResultsFile;
  354. }
  355. // used only in CPolicyHunt::run..
  356. // This the fetched transform need never be deallocated,
  357. //and need only be allocated once.
  358. BSTR LoadPrivacyPolicyTransform()
  359. {
  360. BSTR returnValue = NULL;
  361. DWORD dwByteSizeOfResource;
  362. HRSRC hrsrc = FindResource( MLGetHinst(),
  363. TEXT("privacypolicytransform.xsl"),
  364. MAKEINTRESOURCE(RT_HTML));
  365. if( hrsrc == NULL)
  366. goto doneLoadPrivacyPolicyTransform;
  367. dwByteSizeOfResource = SizeofResource( MLGetHinst(), hrsrc);
  368. if( dwByteSizeOfResource == 0)
  369. goto doneLoadPrivacyPolicyTransform;
  370. HGLOBAL hGlobal = LoadResource( MLGetHinst(), hrsrc); // Loaded resources do not need to be unloaded
  371. if( hGlobal == NULL)
  372. goto doneLoadPrivacyPolicyTransform;
  373. LPVOID pLockedResource = LockResource( hGlobal); // Locked resources do not need to be unlocked
  374. if( pLockedResource == NULL)
  375. goto doneLoadPrivacyPolicyTransform;
  376. // Skip first WCHAR when allocating BSTR copy of the transform,
  377. // since unicode resource starts with an extra 0xFF 0xFE
  378. int cwCount = (dwByteSizeOfResource/sizeof(WCHAR)) - 1;
  379. returnValue = SysAllocStringLen( 1+(LPCWSTR)pLockedResource, cwCount);
  380. doneLoadPrivacyPolicyTransform:
  381. return returnValue;
  382. }
  383. DWORD CPolicyHunt::run()
  384. {
  385. DWORD retVal = POLICYHUNT_ERROR;
  386. int iTemp;
  387. DWORD dw;
  388. if( IsFinished())
  389. goto doneCPolicyHuntRun;
  390. // MapResourceToPolicy phase
  391. // ... need an event..
  392. _p3pSignal.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);
  393. if( _p3pSignal.hEvent == NULL)
  394. goto doneCPolicyHuntRun;
  395. // ... now call MapResourceToPolicy
  396. iTemp = MapResourceToPolicy(&(_resourceSite),
  397. _szPolicy,
  398. ARRAYSIZE(_szPolicy),
  399. &(_p3pSignal));
  400. if( iTemp != P3P_InProgress)
  401. goto doneCPolicyHuntRun;
  402. // ... now wait for MapResourceToPolicy to finish
  403. do
  404. {
  405. if( IsCancelled())
  406. {
  407. retVal = POLICYHUNT_CANCELLED;
  408. goto doneCPolicyHuntRun;
  409. }
  410. } while ( WAIT_TIMEOUT == (dw = WaitForSingleObject( _p3pSignal.hEvent, 100)));
  411. if( WAIT_OBJECT_0 != dw)
  412. goto doneCPolicyHuntRun;
  413. FreeP3PObject( _p3pSignal.hRequest);
  414. _p3pSignal.hRequest = NULL;
  415. // ... check if MapResourceToPolicy found anything..
  416. if( _szPolicy[0] == '\0')
  417. {
  418. retVal = POLICYHUNT_NOTFOUND;
  419. goto doneCPolicyHuntRun;
  420. }
  421. // prepare a WCHAR copy of the policy
  422. SHAnsiToUnicode( _szPolicy, _wszPolicy, ARRAYSIZE( _wszPolicy));
  423. // Now we need to prepare a temp file for our result.
  424. // ... get the path for the result file
  425. WCHAR szPathBuffer[ MAX_PATH];
  426. dw = GetTempPath( ARRAYSIZE( szPathBuffer), szPathBuffer);
  427. if( dw == 0 || dw+1 > MAX_PATH)
  428. goto doneCPolicyHuntRun;
  429. // ... get a .tmp filename for the result file
  430. dw = GetTempFileName( szPathBuffer, L"IE", 0, _wszResultsFile);
  431. if( dw == 0)
  432. goto doneCPolicyHuntRun;
  433. DeleteFile( _wszResultsFile);
  434. // ... make the .tmp filename a .htm filename
  435. dw = lstrlen( _wszResultsFile);
  436. while( dw > 0 && _wszResultsFile[dw] != L'.')
  437. {
  438. dw--;
  439. }
  440. StrCpyNW( _wszResultsFile + dw, L".htm", ARRAYSIZE(L".htm"));
  441. // ... open the file
  442. _hPolicyFile = CreateFile( _wszResultsFile,
  443. GENERIC_WRITE, FILE_SHARE_READ, NULL,
  444. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  445. if( _hPolicyFile == INVALID_HANDLE_VALUE)
  446. goto doneCPolicyHuntRun;
  447. if( s_pwszPrivacyPolicyTransform == NULL)
  448. s_pwszPrivacyPolicyTransform = LoadPrivacyPolicyTransform();
  449. if( s_pwszPrivacyPolicyTransform == NULL)
  450. goto doneCPolicyHuntRun;
  451. ResetEvent( _p3pSignal.hEvent);
  452. iTemp = GetP3PPolicy( _szPolicy, _hPolicyFile,
  453. s_pwszPrivacyPolicyTransform, &_p3pSignal);
  454. if( iTemp != P3P_InProgress)
  455. goto doneCPolicyHuntRun;
  456. // ... now wait for GetP3PPolicy to finish
  457. do
  458. {
  459. if( IsCancelled())
  460. {
  461. retVal = POLICYHUNT_CANCELLED;
  462. goto doneCPolicyHuntRun;
  463. }
  464. } while ( WAIT_TIMEOUT == (dw = WaitForSingleObject( _p3pSignal.hEvent, 100)));
  465. if( WAIT_OBJECT_0 != dw)
  466. goto doneCPolicyHuntRun;
  467. int iGetP3PPolicyResult;
  468. iGetP3PPolicyResult = GetP3PRequestStatus( _p3pSignal.hRequest);
  469. switch( iGetP3PPolicyResult)
  470. {
  471. case P3P_Done:
  472. retVal = POLICYHUNT_FOUND;
  473. break;
  474. case P3P_NoPolicy:
  475. case P3P_NotFound:
  476. retVal = POLICYHUNT_NOTFOUND;
  477. break;
  478. case P3P_Failed:
  479. retVal = POLICYHUNT_ERROR;
  480. break;
  481. case P3P_FormatErr:
  482. retVal = POLICYHUNT_FORMATERROR;
  483. break;
  484. case P3P_Cancelled:
  485. retVal = POLICYHUNT_CANCELLED;
  486. break;
  487. default:
  488. retVal = POLICYHUNT_ERROR;
  489. break;
  490. }
  491. doneCPolicyHuntRun:
  492. if( _hPolicyFile != INVALID_HANDLE_VALUE)
  493. {
  494. CloseHandle( _hPolicyFile);
  495. _hPolicyFile = INVALID_HANDLE_VALUE;
  496. }
  497. if( _p3pSignal.hRequest != NULL)
  498. {
  499. FreeP3PObject( _p3pSignal.hRequest);
  500. _p3pSignal.hRequest = NULL;
  501. }
  502. if( _p3pSignal.hEvent != NULL)
  503. {
  504. CloseHandle( _p3pSignal.hEvent);
  505. _p3pSignal.hEvent = NULL;
  506. }
  507. memset( &_p3pSignal, 0, sizeof(P3PSignal));
  508. return retVal;
  509. }
  510. // be warned: a NULL BSTR is equivalent to a "" BSTR..
  511. // This function returns the cookie domain from an http:// or https:// style Url.
  512. BSTR GetCookieDomainFromUrl( LPCWSTR bstrFullUrl)
  513. {
  514. BSTR returnValue = NULL;
  515. if( bstrFullUrl == NULL)
  516. goto doneGetMinimizedCookieDomain;
  517. WCHAR wszUrl[MAX_URL_STRING], *pMinimizedDomain;
  518. wszUrl[0] = L'\0';
  519. StrCpyNW( wszUrl, bstrFullUrl, lstrlen( bstrFullUrl)+1);
  520. if( wszUrl[0] == '\0')
  521. goto doneGetMinimizedCookieDomain;
  522. WCHAR *pBeginUrl = wszUrl; // pBeginUrl will be 'http://full.domain.com/path/path...'
  523. while( *pBeginUrl != L'\0' && *pBeginUrl != L'/')
  524. pBeginUrl++;
  525. if( *pBeginUrl == L'/')
  526. pBeginUrl++;
  527. while( *pBeginUrl != L'\0' && *pBeginUrl != L'/')
  528. pBeginUrl++;
  529. if( *pBeginUrl == L'/')
  530. pBeginUrl++; // now pBeginUrl is 'full.domain.com/path/path'..
  531. WCHAR *pEndUrl = pBeginUrl; // pEndUrl will find the '/path/path..' and clip it from pBeginUrl
  532. while( *pEndUrl != L'\0' && *pEndUrl != L'/')
  533. pEndUrl++;
  534. *pEndUrl = L'\0';
  535. pMinimizedDomain = pEndUrl;
  536. // pBeginUrl is now like 'full.domain.com'
  537. // pMinimizedDomain will reduce pBeginUrl to a domain minimized to still allow cookies..
  538. do
  539. {
  540. pMinimizedDomain--;
  541. while( pBeginUrl < pMinimizedDomain
  542. && *(pMinimizedDomain-1) != L'.')
  543. {
  544. pMinimizedDomain--;
  545. }
  546. } while( !IsDomainLegalCookieDomain( pMinimizedDomain, pBeginUrl)
  547. && pBeginUrl < pMinimizedDomain);
  548. returnValue = SysAllocString( pMinimizedDomain);
  549. doneGetMinimizedCookieDomain:
  550. return returnValue;
  551. }
  552. void PrivacyDlgDeallocSiteList( PSPrivacyDialogData pData)
  553. {
  554. void* iterator = NULL;
  555. while( NULL != (iterator = pData->listAllSites.StepEnumerate(iterator)))
  556. {
  557. PSPerSiteData pCurrent =
  558. (PSPerSiteData)(pData->listAllSites.Get( iterator));
  559. delete pCurrent;
  560. }
  561. CPolicyHunt::FreePrivacyPolicyTransform();
  562. }
  563. BOOL PrivacyDialogExtendSiteList( PSPrivacyDialogData pData)
  564. {
  565. BOOL returnValue = FALSE;
  566. BSTR bstrUrl = NULL, bstrPolicyRef = NULL;
  567. DWORD dwFlags;
  568. ULONG ulPrivacyRecordsTotal;
  569. if( FAILED(pData->pEnumPrivacyRecords->GetSize( &ulPrivacyRecordsTotal)))
  570. ulPrivacyRecordsTotal = 0;
  571. DWORD dwTemp;
  572. // Enumerate the sites in IEnumPrivacyRecords::enum
  573. PSPerSiteData pCurrentSite = NULL, pCurrentSiteInList = NULL;
  574. while( pData->countRecordsEnumerated < ulPrivacyRecordsTotal
  575. && SUCCEEDED( dwTemp = pData->pEnumPrivacyRecords->
  576. Next(&bstrUrl, &bstrPolicyRef,
  577. NULL, &dwFlags)))
  578. {
  579. pData->countRecordsEnumerated++;
  580. pCurrentSite = NULL;
  581. pCurrentSiteInList = NULL;
  582. void* iterator = NULL;
  583. if(NULL == bstrUrl || 0 == *bstrUrl)
  584. {
  585. // every time we pass a blank token,
  586. //we begin processing a higher navigation level.
  587. SysFreeString( bstrUrl);
  588. bstrUrl = NULL;
  589. continue;
  590. }
  591. if( 0 != StrNCmpI( bstrUrl, L"http", ARRAYSIZE(L"http")-1))
  592. {
  593. // we ignore non http stuff... like ftp, local files..
  594. continue;
  595. }
  596. // Test if the current site is already in the list.
  597. iterator = NULL;
  598. while( pCurrentSiteInList == NULL
  599. && NULL !=
  600. (iterator = pData->listAllSites.StepEnumerate(iterator)))
  601. {
  602. PSPerSiteData pCurrent =
  603. (PSPerSiteData)(pData->listAllSites.Get( iterator));
  604. if( 0 == StrCmp( bstrUrl, pCurrent->bstrUrl))
  605. pCurrentSiteInList = pCurrent;
  606. }
  607. // If the site is not in the list, add it.
  608. // If the site isn't in the list, add the information given by enum.
  609. if( pCurrentSiteInList == NULL)
  610. {
  611. pCurrentSite = new SPerSiteData();
  612. if( pCurrentSite == NULL)
  613. goto donePrivacyDialogExtendSiteList;
  614. pCurrentSite->bstrUrl = bstrUrl;
  615. bstrUrl = NULL;
  616. pCurrentSite->dwFlags = dwFlags;
  617. // Now find the minimized cookie domain..
  618. pCurrentSite->bstrCookieDomain =
  619. GetCookieDomainFromUrl( pCurrentSite->bstrUrl);
  620. if( pData->listAllSites.InsertAtEnd( pCurrentSite))
  621. pCurrentSiteInList = pCurrentSite;
  622. else
  623. goto donePrivacyDialogExtendSiteList;
  624. }
  625. else // else we have a duplicate list item
  626. {
  627. pCurrentSite = pCurrentSiteInList;
  628. // pCurrentSite->bstrUrl is correct
  629. // pCurrentSite->bstrCookieDomain is correct
  630. pCurrentSite->dwFlags |= dwFlags;
  631. }
  632. if( bstrPolicyRef != NULL && dwFlags & PRIVACY_URLHASPOLICYREFHEADER)
  633. { // We have the policy ref from the header..
  634. SysFreeString( pCurrentSite->bstrHeaderPolicyRef); // NULLs are ignored..
  635. pCurrentSite->bstrHeaderPolicyRef = bstrPolicyRef;
  636. bstrPolicyRef = NULL;
  637. }
  638. else if ( bstrPolicyRef != NULL && dwFlags & PRIVACY_URLHASPOLICYREFLINK)
  639. { // We have the policy ref from the link tag..
  640. SysFreeString( pCurrentSite->bstrLinkTagPolicyRef); // NULLs are ignored..
  641. pCurrentSite->bstrLinkTagPolicyRef = bstrPolicyRef;
  642. bstrPolicyRef = NULL;
  643. }
  644. else if( bstrPolicyRef != NULL)
  645. { // We have a policy ref with an unknown source.. bug in IEnumPrivacyRecords
  646. ASSERT(0);
  647. SysFreeString( pCurrentSite->bstrHeaderPolicyRef); // NULLs are ignored..
  648. pCurrentSite->bstrHeaderPolicyRef = bstrPolicyRef;
  649. bstrPolicyRef = NULL;
  650. }
  651. // now to determine the privacy impact of the site..
  652. // precedence: IDS_PRIVACY_BLOCKED > IDS_PRIVACY_RESTRICTED > IDS_PRIVACY_ACCEPTED > nothing
  653. if( dwFlags & (COOKIEACTION_ACCEPT | COOKIEACTION_LEASH))
  654. {
  655. pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
  656. IDS_PRIVACY_ACCEPTED);
  657. }
  658. if( dwFlags & COOKIEACTION_DOWNGRADE)
  659. {
  660. pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
  661. IDS_PRIVACY_RESTRICTED);
  662. }
  663. if( dwFlags & (COOKIEACTION_REJECT | COOKIEACTION_SUPPRESS))
  664. {
  665. pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
  666. IDS_PRIVACY_BLOCKED);
  667. }
  668. SysFreeString( bstrUrl);
  669. bstrUrl = NULL;
  670. SysFreeString( bstrPolicyRef);
  671. bstrPolicyRef = NULL;
  672. }
  673. returnValue = TRUE;
  674. donePrivacyDialogExtendSiteList:
  675. if( bstrUrl != NULL)
  676. SysFreeString( bstrUrl);
  677. if( bstrPolicyRef != NULL)
  678. SysFreeString( bstrUrl);
  679. if( pCurrentSite != NULL && pCurrentSiteInList == NULL)
  680. delete pCurrentSite;
  681. return returnValue;
  682. }
  683. BOOL PrivacyDlgBuildSiteList( PSPrivacyDialogData pData)
  684. {
  685. PrivacyDlgDeallocSiteList( pData);
  686. return PrivacyDialogExtendSiteList( pData);
  687. }
  688. BOOL InitializePrivacyDlg(HWND hDlg, PSPrivacyDialogData pData)
  689. {
  690. WCHAR szBuffer[256];
  691. HWND hwndListView = GetDlgItem(hDlg, IDC_SITE_LIST);
  692. RECT rc;
  693. // Set the privacy status caption text
  694. BOOL fImpacted;
  695. if( SUCCEEDED(pData->pEnumPrivacyRecords->GetPrivacyImpacted(&fImpacted)) && fImpacted)
  696. {
  697. MLLoadStringW( IDS_PRIVACY_STATUSIMPACTED, szBuffer, ARRAYSIZE( szBuffer));
  698. }
  699. else
  700. {
  701. MLLoadStringW( IDS_PRIVACY_STATUSNOIMPACT, szBuffer, ARRAYSIZE( szBuffer));
  702. }
  703. SendMessage( GetDlgItem( hDlg, IDC_PRIVACY_STATUSTEXT), WM_SETTEXT,
  704. 0, (LPARAM)szBuffer);
  705. //Initialize the list view..
  706. // ..Empty the list in list view.
  707. ListView_DeleteAllItems (hwndListView);
  708. // ..Initialize the columns in the list view.
  709. LV_COLUMN lvColumn;
  710. lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
  711. lvColumn.fmt = LVCFMT_LEFT;
  712. lvColumn.pszText = szBuffer;
  713. lvColumn.cx = 300;
  714. if( 0 != GetClientRect( hwndListView, &rc))
  715. lvColumn.cx = rc.right - rc.left - 150 - GetSystemMetrics( SM_CXVSCROLL);
  716. // 15 is an arbitrary number to prevent the horizontal scrollbar from appearing
  717. MLLoadStringW(IDS_PRIVACY_COLUMN1, szBuffer, ARRAYSIZE(szBuffer));
  718. ListView_InsertColumn(hwndListView, 1, &lvColumn);
  719. lvColumn.cx = 150;
  720. MLLoadStringW(IDS_PRIVACY_COLUMN2, szBuffer, ARRAYSIZE(szBuffer));
  721. ListView_InsertColumn(hwndListView, 2, &lvColumn);
  722. // Initialize the view all/restricted combo box
  723. HWND hwndComboBox = GetDlgItem( hDlg, IDC_PRIVACY_VIEWCOMBO);
  724. ComboBox_ResetContent( hwndComboBox);
  725. int iComboPosition;
  726. MLLoadStringW(IDS_PRIVACY_VIEWIMPACTED, szBuffer, ARRAYSIZE(szBuffer));
  727. iComboPosition = ComboBox_AddString(hwndComboBox, szBuffer);
  728. ComboBox_SetItemData(hwndComboBox, iComboPosition, 0);
  729. MLLoadStringW(IDS_PRIVACY_VIEWALL, szBuffer, ARRAYSIZE(szBuffer));
  730. iComboPosition = ComboBox_AddString(hwndComboBox, szBuffer);
  731. ComboBox_SetItemData(hwndComboBox, iComboPosition, 1);
  732. ComboBox_SetCurSel( hwndComboBox, pData->fReportAllSites);
  733. GetDlgItemText( hDlg, IDC_PRIVACY_HELP, szBuffer, ARRAYSIZE( szBuffer));
  734. MLLoadStringW(IDS_PRIVACY_LEARNMOREABOUTPRIVACY, szBuffer, ARRAYSIZE(szBuffer));
  735. RenderStringToEditControlW(hDlg,
  736. szBuffer,
  737. (WNDPROC)HyperlinkSubclass,
  738. IDC_PRIVACY_HELP);
  739. return TRUE;
  740. }
  741. // add items to the privacy dialog's listview..
  742. BOOL PopulatePrivacyDlgListView(HWND hDlg, PSPrivacyDialogData pData, bool fMaintainSelectedItem)
  743. {
  744. HWND hwndListView = GetDlgItem( hDlg, IDC_SITE_LIST);
  745. void* iterator = NULL;
  746. int iCurrentPosition = 0;
  747. int iSelectedItem = ListView_GetSelectionMark( hwndListView);
  748. PSPerSiteData pSelectedItem = NULL;
  749. if( fMaintainSelectedItem && iSelectedItem != -1)
  750. {
  751. LVITEM lvi;
  752. lvi.mask = LVIF_PARAM;
  753. lvi.iItem = iSelectedItem;
  754. if( FALSE != ListView_GetItem( hwndListView, &lvi)
  755. && lvi.lParam != (LPARAM)NULL)
  756. {
  757. pSelectedItem = (PSPerSiteData)lvi.lParam;
  758. }
  759. }
  760. // Empty the list in list view.
  761. ListView_DeleteAllItems (hwndListView);
  762. iSelectedItem = -1;
  763. while( NULL != (iterator = pData->listAllSites.StepEnumerate(iterator)))
  764. {
  765. PSPerSiteData pCurrent =
  766. (PSPerSiteData)(pData->listAllSites.Get(iterator));
  767. BOOL fAddItem = pData->fReportAllSites
  768. || pCurrent->iPrivacyImpactResource == IDS_PRIVACY_SUPPRESSED
  769. || pCurrent->iPrivacyImpactResource == IDS_PRIVACY_RESTRICTED
  770. || pCurrent->iPrivacyImpactResource == IDS_PRIVACY_BLOCKED;
  771. if( fAddItem == TRUE)
  772. {
  773. LVITEM lvitem;
  774. lvitem.mask = LVIF_TEXT | LVIF_PARAM;
  775. lvitem.pszText = pCurrent->bstrUrl;
  776. lvitem.iItem = iCurrentPosition++;
  777. lvitem.iSubItem = 0;
  778. lvitem.lParam = (LPARAM)pCurrent;
  779. ListView_InsertItem(hwndListView, &lvitem);
  780. if( pCurrent->iPrivacyImpactResource != 0)
  781. {
  782. WCHAR wszTemp[128];
  783. // set cookie string
  784. lvitem.iSubItem = 1;
  785. lvitem.mask = LVIF_TEXT;
  786. lvitem.pszText = wszTemp;
  787. if( MLLoadString(pCurrent->iPrivacyImpactResource,
  788. wszTemp, ARRAYSIZE(wszTemp)))
  789. {
  790. SendMessage(hwndListView, LVM_SETITEMTEXT,
  791. (WPARAM)lvitem.iItem, (LPARAM)&lvitem);
  792. }
  793. }
  794. // We either keep the last item selected as selected,
  795. //or select the last top-level item.
  796. if( fMaintainSelectedItem)
  797. {
  798. if( pSelectedItem == pCurrent)
  799. iSelectedItem = lvitem.iItem;
  800. }
  801. }
  802. }
  803. // if( fMaintainSelectedItem && iSelectedItem != -1)
  804. // {
  805. // ListView_SetItemState( hwndListView, iSelectedItem, LVIS_SELECTED, LVIS_SELECTED);
  806. // ListView_SetSelectionMark( hwndListView, iSelectedItem);
  807. // ListView_EnsureVisible( hwndListView, iSelectedItem, FALSE);
  808. // }
  809. PostMessage( hDlg, WM_APP, IDC_SITE_LIST, 0); // notifies the dialog that a listview item has been selected
  810. return TRUE;
  811. }
  812. typedef BOOL (*PFNPRIVACYSETTINGS)(HWND);
  813. void LaunchPrivacySettings(HWND hwndParent)
  814. {
  815. HMODULE hmodInetcpl;
  816. PFNPRIVACYSETTINGS pfnPriv;
  817. hmodInetcpl = LoadLibrary(TEXT("inetcpl.cpl"));
  818. if(hmodInetcpl)
  819. {
  820. pfnPriv = (PFNPRIVACYSETTINGS)GetProcAddress(hmodInetcpl, "LaunchPrivacyDialog");
  821. if(pfnPriv)
  822. {
  823. pfnPriv(hwndParent);
  824. }
  825. FreeLibrary(hmodInetcpl);
  826. }
  827. }
  828. BOOL PrivacyPolicyHtmlDlg( HWND hDlg, HWND hwndListView, int iItemIndex)
  829. {
  830. BOOL returnValue = FALSE;
  831. HRESULT hr;
  832. DWORD dw;
  833. PSPerSiteData pListViewData;
  834. WCHAR* pwchHtmlDialogInput = NULL;
  835. IMoniker * pmk = NULL;
  836. VARIANT varArg, varOut;
  837. VariantInit( &varArg);
  838. VariantInit( &varOut);
  839. LVITEM lvi;
  840. lvi.mask = LVIF_PARAM;
  841. lvi.iItem = iItemIndex;
  842. if( FALSE == ListView_GetItem( hwndListView, &lvi)
  843. || lvi.lParam == (LPARAM)NULL)
  844. goto donePrivacyPolicyHtmlDlg;
  845. pListViewData = (PSPerSiteData)lvi.lParam;
  846. WCHAR szResURL[MAX_URL_STRING];
  847. // fetch the HTML for the dialog box..
  848. hr = MLBuildResURLWrap(TEXT("shdoclc.dll"),
  849. HINST_THISDLL,
  850. ML_CROSSCODEPAGE,
  851. TEXT("privacypolicy.dlg"),
  852. szResURL,
  853. ARRAYSIZE(szResURL),
  854. TEXT("shdocvw.dll"));
  855. if( FAILED( hr))
  856. goto donePrivacyPolicyHtmlDlg;
  857. hr = CreateURLMoniker(NULL, szResURL, &pmk);
  858. if( FAILED( hr))
  859. goto donePrivacyPolicyHtmlDlg;
  860. varArg.vt = VT_DISPATCH;
  861. varArg.pdispVal = (IDispatch*)pListViewData;
  862. // Show the dialog..
  863. hr = ShowHTMLDialog( hDlg, pmk, &varArg, L"help:no; resizable:1", &varOut);
  864. if( FAILED( hr))
  865. goto donePrivacyPolicyHtmlDlg;
  866. hr = VariantChangeType( &varOut, &varOut, NULL, VT_I4);
  867. if( FAILED( hr))
  868. goto donePrivacyPolicyHtmlDlg;
  869. if( allowPerSiteModify())
  870. {
  871. switch( varOut.lVal)
  872. {
  873. default:
  874. hr = TRUE;
  875. break;
  876. case 1:
  877. hr = InternetSetPerSiteCookieDecision(
  878. pListViewData->bstrCookieDomain, COOKIE_STATE_UNKNOWN);
  879. break;
  880. case 2:
  881. hr = InternetSetPerSiteCookieDecision(
  882. pListViewData->bstrCookieDomain, COOKIE_STATE_ACCEPT);
  883. break;
  884. case 3:
  885. hr = InternetSetPerSiteCookieDecision(
  886. pListViewData->bstrCookieDomain, COOKIE_STATE_REJECT);
  887. break;
  888. }
  889. }
  890. if( hr != TRUE)
  891. goto donePrivacyPolicyHtmlDlg;
  892. returnValue = TRUE;
  893. donePrivacyPolicyHtmlDlg:
  894. if( pListViewData->pPolicyHunt != NULL)
  895. {
  896. // no-op if already finished
  897. pListViewData->pPolicyHunt->NotifyCancel();
  898. pListViewData->pPolicyHunt->WaitForNotRunning( INFINITE);
  899. }
  900. if( pListViewData->pPolicyHunt != NULL
  901. && pListViewData->pPolicyHunt->GetResult( &dw) == TRUE
  902. && dw != POLICYHUNT_FOUND)
  903. {
  904. delete pListViewData->pPolicyHunt;
  905. pListViewData->pPolicyHunt = NULL;
  906. }
  907. if( pwchHtmlDialogInput != NULL)
  908. delete[] pwchHtmlDialogInput;
  909. if( pmk != NULL)
  910. ATOMICRELEASE( pmk);
  911. VariantClear( &varArg);
  912. VariantClear( &varOut);
  913. return returnValue;
  914. }
  915. BOOL PrivacyDlgContextMenuHandler( HWND hDlg, HWND hwndListView,
  916. int iSelectedListItem, int x, int y)
  917. {
  918. //user has initiated opening the context menu..
  919. // if the user right-clicked a non-list item, we do nothing
  920. if( iSelectedListItem == -1
  921. || !allowPerSiteModify())
  922. return TRUE;
  923. SPerSiteData *psSiteData = NULL;
  924. LVITEM lvi;
  925. lvi.mask = LVIF_PARAM;
  926. lvi.iItem = iSelectedListItem;
  927. if( FALSE == ListView_GetItem( hwndListView, &lvi)
  928. || lvi.lParam == (LPARAM)NULL)
  929. return FALSE;
  930. psSiteData = (PSPerSiteData)(lvi.lParam);
  931. HMENU hmenu0 = LoadMenu( MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_CNTXTMN_PERSITE_ADD_REM));
  932. HMENU hmenu1 = GetSubMenu( hmenu0, 0);
  933. if( hmenu0 == NULL || hmenu1 == NULL)
  934. {
  935. DestroyMenu(hmenu0);
  936. return FALSE;
  937. }
  938. // Check the appropriate option..
  939. unsigned long ulResult;
  940. MENUITEMINFO menuiteminfo;
  941. menuiteminfo.cbSize = sizeof(menuiteminfo);
  942. menuiteminfo.fMask = MIIM_STATE;
  943. menuiteminfo.fState = MFS_CHECKED;
  944. if( InternetGetPerSiteCookieDecision( psSiteData->bstrCookieDomain, &ulResult) == TRUE)
  945. {
  946. switch( ulResult)
  947. {
  948. case COOKIE_STATE_ACCEPT:
  949. SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_ACCEPT, FALSE, &menuiteminfo);
  950. break;
  951. case COOKIE_STATE_REJECT:
  952. SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_REJECT, FALSE, &menuiteminfo);
  953. break;
  954. }
  955. }
  956. else
  957. {
  958. SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_DEFAULT, FALSE, &menuiteminfo);
  959. }
  960. // the target location of the context window depends on whether or not the user
  961. //right-clicked the mouse or used the context menu button..
  962. if( x == -1 && y == -1)
  963. { // context menu was opened through keyboard, not mouse..
  964. RECT rectListRect;
  965. RECT rectSelectionRect;
  966. if( 0 != GetWindowRect( hwndListView, &rectListRect)
  967. && TRUE == ListView_GetItemRect( hwndListView, iSelectedListItem,
  968. &rectSelectionRect, LVIR_LABEL))
  969. {
  970. x = rectListRect.left + (rectSelectionRect.left + rectSelectionRect.right) / 2;
  971. y = rectListRect.top + (rectSelectionRect.top + rectSelectionRect.bottom) / 2;
  972. }
  973. }
  974. // now we know enough to open the conext menu.
  975. BOOL userSelection = TrackPopupMenu( hmenu1, TPM_RETURNCMD, x, y, 0, hDlg, NULL);
  976. DestroyMenu( hmenu1);
  977. DestroyMenu( hmenu0);
  978. switch( userSelection)
  979. {
  980. case 0:
  981. // User cancelled context menu, do nothing.
  982. break;
  983. case IDM_PRIVACY_PAR_ACCEPT:
  984. // User chose to add site to per-site exclusion list.
  985. InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_ACCEPT);
  986. break;
  987. case IDM_PRIVACY_PAR_REJECT:
  988. // User chose to add site per-site inclusion list.
  989. InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_REJECT);
  990. break;
  991. case IDM_PRIVACY_PAR_DEFAULT:
  992. // User chose to have site use default behavior.
  993. InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_UNKNOWN);
  994. break;
  995. }
  996. return TRUE;
  997. }
  998. INT_PTR CALLBACK PrivacyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  999. {
  1000. PSPrivacyDialogData pData = (PSPrivacyDialogData)GetWindowLongPtr(hDlg, GWLP_USERDATA);
  1001. switch (message)
  1002. {
  1003. case WM_INITDIALOG:
  1004. SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)lParam);
  1005. pData = (PSPrivacyDialogData)lParam;
  1006. InitializePrivacyDlg( hDlg, pData);
  1007. PrivacyDlgBuildSiteList( pData);
  1008. PopulatePrivacyDlgListView(hDlg, pData, false);
  1009. if( IsOS(OS_WHISTLERORGREATER))
  1010. {
  1011. HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
  1012. if( hIcon != NULL)
  1013. SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  1014. // icons loaded with LoadIcon never need to be released
  1015. }
  1016. PostMessage( hDlg, WM_NEXTDLGCTL,
  1017. (WPARAM)GetDlgItem( hDlg, IDC_SITE_LIST),
  1018. MAKELPARAM( TRUE, 0));
  1019. SetTimer( hDlg, NULL, 500, NULL);
  1020. return TRUE;
  1021. case WM_DESTROY:
  1022. PrivacyDlgDeallocSiteList( pData);
  1023. break;
  1024. case WM_TIMER:
  1025. {
  1026. ULONG oldCount = pData->countRecordsEnumerated;
  1027. if( pData != NULL
  1028. && TRUE == PrivacyDialogExtendSiteList( pData)
  1029. && oldCount < pData->countRecordsEnumerated)
  1030. {
  1031. PopulatePrivacyDlgListView( hDlg, pData, true);
  1032. }
  1033. }
  1034. case WM_COMMAND:
  1035. switch(LOWORD(wParam))
  1036. {
  1037. case IDOK:
  1038. switch( GetDlgCtrlID(GetFocus()))
  1039. {
  1040. case IDC_SITE_LIST:
  1041. {
  1042. PostMessage( hDlg, WM_COMMAND,
  1043. (WPARAM)IDC_PRIVACY_SHOWPOLICY,
  1044. (LPARAM)GetDlgItem(hDlg, IDC_PRIVACY_SHOWPOLICY));
  1045. return 0; // return 0 to indicate message was handled
  1046. }
  1047. case IDC_PRIVACY_HELP:
  1048. {
  1049. PostMessage( hDlg, WM_APP, (WPARAM)IDC_PRIVACY_HELP, (LPARAM)GetDlgItem(hDlg, IDC_PRIVACY_HELP));
  1050. return 0;
  1051. }
  1052. case IDC_PRIVACY_VIEWCOMBO:
  1053. {
  1054. PostMessage( hDlg, WM_NEXTDLGCTL,
  1055. (WPARAM)GetDlgItem( hDlg, IDC_SITE_LIST),
  1056. MAKELPARAM( TRUE, 0));
  1057. return 0;
  1058. }
  1059. }
  1060. // fall through if IDOK was actually due to hitting IDOK with defaulting on an enter..
  1061. case IDCANCEL:
  1062. EndDialog(hDlg, LOWORD(wParam));
  1063. return 0;
  1064. case IDC_SETTINGS:
  1065. LaunchPrivacySettings(hDlg);
  1066. return 0;
  1067. case IDC_PRIVACY_VIEWCOMBO:
  1068. if( CBN_SELCHANGE == HIWORD(wParam))
  1069. {
  1070. HWND hwndComboBox = (HWND)lParam;
  1071. int iIndex = ComboBox_GetCurSel(hwndComboBox);
  1072. if( iIndex != CB_ERR)
  1073. {
  1074. pData->fReportAllSites = (iIndex == 1) ? TRUE : FALSE;
  1075. PopulatePrivacyDlgListView(hDlg, pData, true);
  1076. }
  1077. return 0;
  1078. }
  1079. break;
  1080. case IDC_PRIVACY_SHOWPOLICY:
  1081. {
  1082. // Catching the default return and seeing if the site list is
  1083. //selected was the only way to detect a return on the listview.
  1084. HWND hwndSiteList = GetDlgItem( hDlg, IDC_SITE_LIST);
  1085. int iSelectedItem = ListView_GetSelectionMark( hwndSiteList);
  1086. if( iSelectedItem != -1)
  1087. {
  1088. PrivacyPolicyHtmlDlg( hDlg, hwndSiteList, iSelectedItem);
  1089. }
  1090. return 0;
  1091. }
  1092. }
  1093. break;
  1094. case WM_APP:
  1095. if( LOWORD(wParam) == IDC_PRIVACY_HELP)
  1096. {
  1097. SHHtmlHelpOnDemandWrap(hDlg, TEXT("iexplore.chm > iedefault"),
  1098. HH_DISPLAY_TOPIC, (DWORD_PTR) L"sec_cook.htm", ML_CROSSCODEPAGE);
  1099. }
  1100. else if ( LOWORD( wParam) == IDC_SITE_LIST)
  1101. {
  1102. // We post an WM_APP to the dialog everytime the selected list view item
  1103. //is changed.. By handling the change in a posted message, we insure the
  1104. //list view's selected item is updated.
  1105. // Whenever the selected privacy report list item is changed, we have to enable/disable
  1106. //the show site policy button.
  1107. int iSelectedItem = ListView_GetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST));
  1108. EnableWindow( GetDlgItem( hDlg, IDC_PRIVACY_SHOWPOLICY), (-1 != iSelectedItem));
  1109. }
  1110. return 0;
  1111. case WM_CONTEXTMENU:
  1112. // If the user hits the context menu button on the list view, we handle it here,
  1113. //because its the only place to check for that keypress.
  1114. // If the user clicks the right mouse button for the context menu, we handle it in
  1115. //WM__NOTIFY::NM_RCLICK, because the NM_RCLICK gives the correct seleceted item.
  1116. if( GET_X_LPARAM(lParam) == -1
  1117. && (HWND)wParam == GetDlgItem( hDlg, IDC_SITE_LIST))
  1118. {
  1119. int iSelectedItem = ListView_GetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST));
  1120. PrivacyDlgContextMenuHandler( hDlg, (HWND)wParam,
  1121. iSelectedItem,
  1122. GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
  1123. }
  1124. break;
  1125. case WM_NOTIFY:
  1126. if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
  1127. && NM_DBLCLK == ((LPNMHDR)lParam)->code
  1128. && ((LPNMITEMACTIVATE)lParam)->iItem != -1)
  1129. {
  1130. PrivacyPolicyHtmlDlg( hDlg, ((LPNMHDR)lParam)->hwndFrom,
  1131. ((LPNMITEMACTIVATE)lParam)->iItem);
  1132. }
  1133. else if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
  1134. && NM_RCLICK == ((LPNMHDR)lParam)->code)
  1135. {
  1136. int iRightClickedItem = ((LPNMITEMACTIVATE)lParam)->iItem;
  1137. if( iRightClickedItem != -1)
  1138. {
  1139. POINT pointClick = ((LPNMITEMACTIVATE)lParam)->ptAction;
  1140. RECT rc;
  1141. if( 0 != GetWindowRect( GetDlgItem( hDlg, IDC_SITE_LIST), &rc))
  1142. {
  1143. pointClick.x += rc.left;
  1144. pointClick.y += rc.top;
  1145. }
  1146. else
  1147. {
  1148. // Strange error case.. but its alright since we can place the context menu
  1149. //as if the context-menu button was clicked, instead of the mouse
  1150. pointClick.x = -1;
  1151. pointClick.y = -1;
  1152. }
  1153. PrivacyDlgContextMenuHandler( hDlg, GetDlgItem( hDlg, IDC_SITE_LIST),
  1154. iRightClickedItem,
  1155. pointClick.x, pointClick.y);
  1156. }
  1157. }
  1158. else if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
  1159. && LVN_ITEMCHANGED == ((LPNMHDR)lParam)->code)
  1160. {
  1161. if( ((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE)
  1162. {
  1163. // For some unknown reason the selection mark does not move with
  1164. //the selected item.. We have to update it.
  1165. if( ((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED)
  1166. {
  1167. ListView_SetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST),
  1168. ((LPNMLISTVIEW)lParam)->iItem);
  1169. }
  1170. else
  1171. {
  1172. ListView_SetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST),
  1173. -1);
  1174. }
  1175. // Now that the selection mark is in sync, the UI can update
  1176. //related items
  1177. PostMessage( hDlg, WM_APP, IDC_SITE_LIST, 0);
  1178. }
  1179. }
  1180. break;
  1181. }
  1182. return FALSE;
  1183. }
  1184. //
  1185. // Exported entry point to show privacy dialog
  1186. //
  1187. SHDOCAPI
  1188. DoPrivacyDlg(
  1189. HWND hwndParent, // parent window
  1190. LPOLESTR pszUrl, // base URL
  1191. IEnumPrivacyRecords *pPrivacyEnum, // enum of all affected dependant URLs
  1192. BOOL fReportAllSites // show all or just show bad
  1193. )
  1194. {
  1195. HINSTANCE hRichEditDll;
  1196. SPrivacyDialogData p; // data to send to dialogbox
  1197. if(NULL == pszUrl || NULL == pPrivacyEnum)
  1198. {
  1199. return E_INVALIDARG;
  1200. }
  1201. // We need to load richedit
  1202. hRichEditDll = LoadLibrary(TEXT("RICHED20.DLL"));
  1203. if (!hRichEditDll)
  1204. {
  1205. ASSERT(FALSE); //can't load richedit, complain to akabir
  1206. return E_UNEXPECTED;
  1207. }
  1208. p.pszName = pszUrl;
  1209. p.pEnumPrivacyRecords = pPrivacyEnum;
  1210. p.fReportAllSites = fReportAllSites;
  1211. SHFusionDialogBoxParam(MLGetHinst(),
  1212. MAKEINTRESOURCE(IDD_PRIVACY_DIALOG),
  1213. hwndParent,
  1214. PrivacyDlgProc,
  1215. (LPARAM)&p);
  1216. FreeLibrary( hRichEditDll);
  1217. return S_OK;
  1218. }
  1219. #define DISPID_URL 10
  1220. #define DISPID_COOKIEURL 11
  1221. #define DISPID_ARD 12
  1222. #define DISPID_ARD_FIXED 13
  1223. #define DISPID_POLICYHUNT_DONE 14
  1224. #define DISPID_POLICYHUNT_VIEW 15
  1225. #define DISPID_CREATEABSOLUTEURL 16
  1226. struct SPropertyTable
  1227. {
  1228. WCHAR* pName;
  1229. DISPID dispid;
  1230. } const g_SPerSiteDataDisptable[] =
  1231. {
  1232. L"url", DISPID_URL,
  1233. L"cookieUrl", DISPID_COOKIEURL,
  1234. L"acceptRejectOrDefault", DISPID_ARD,
  1235. L"fixedAcceptRejectOrDefault", DISPID_ARD_FIXED,
  1236. L"flagPolicyHuntDone", DISPID_POLICYHUNT_DONE,
  1237. L"urlPolicyHuntView", DISPID_POLICYHUNT_VIEW,
  1238. L"CreateAbsoluteUrl", DISPID_CREATEABSOLUTEURL
  1239. };
  1240. const DWORD g_cSPerSiteDataDisptableSize = ARRAYSIZE( g_SPerSiteDataDisptable);
  1241. ULONG SPerSiteData::AddRef( void )
  1242. {
  1243. return 1;
  1244. }
  1245. ULONG SPerSiteData::Release( void )
  1246. {
  1247. return 1;
  1248. }
  1249. HRESULT SPerSiteData::QueryInterface( REFIID iid, void ** ppv)
  1250. {
  1251. if( ppv == NULL) return E_POINTER;
  1252. if (IsEqualIID(iid, IID_IUnknown)
  1253. || IsEqualIID(iid, IID_IDispatch))
  1254. {
  1255. *ppv = (void *)this;
  1256. return S_OK;
  1257. }
  1258. else
  1259. {
  1260. *ppv = NULL;
  1261. return E_NOINTERFACE;
  1262. }
  1263. }
  1264. HRESULT SPerSiteData::GetTypeInfoCount( unsigned int FAR* pctinfo)
  1265. {
  1266. if( pctinfo == NULL)
  1267. return E_POINTER;
  1268. *pctinfo = 0;
  1269. return S_OK;
  1270. }
  1271. HRESULT SPerSiteData::GetTypeInfo( unsigned int iTInfo,
  1272. LCID lcid,
  1273. ITypeInfo FAR* FAR* ppTInfo)
  1274. {
  1275. return E_NOTIMPL;
  1276. }
  1277. HRESULT SPerSiteData::GetIDsOfNames( REFIID riid,
  1278. OLECHAR FAR* FAR* rgszNames,
  1279. unsigned int cNames,
  1280. LCID lcid,
  1281. DISPID FAR* rgDispId)
  1282. {
  1283. if( !IsEqualIID(riid, IID_NULL) )
  1284. return E_INVALIDARG;
  1285. if( cNames != 1)
  1286. return E_INVALIDARG; // none of the objects we ID have arguments..
  1287. int i;
  1288. for( i = 0; i < g_cSPerSiteDataDisptableSize; i++)
  1289. {
  1290. if( 0 == StrCmp( rgszNames[0], g_SPerSiteDataDisptable[i].pName))
  1291. {
  1292. rgDispId[0] = g_SPerSiteDataDisptable[i].dispid;
  1293. return S_OK;
  1294. }
  1295. }
  1296. rgDispId[0] = DISPID_UNKNOWN;
  1297. return DISP_E_UNKNOWNNAME;
  1298. }
  1299. HRESULT SPerSiteData::Invoke( DISPID dispIdMember,
  1300. REFIID riid,
  1301. LCID lcid,
  1302. WORD wFlags,
  1303. DISPPARAMS FAR* pDispParams,
  1304. VARIANT FAR* pVarResult,
  1305. EXCEPINFO FAR* pExcepInfo,
  1306. unsigned int FAR* puArgErr)
  1307. {
  1308. HRESULT hr;
  1309. DWORD dw;
  1310. if( !IsEqualIID(riid, IID_NULL) )
  1311. return E_INVALIDARG;
  1312. if( pDispParams == NULL
  1313. || pDispParams->cNamedArgs != 0)
  1314. return DISP_E_BADPARAMCOUNT;
  1315. switch( dispIdMember)
  1316. {
  1317. case DISPID_CREATEABSOLUTEURL:
  1318. if( pDispParams->cArgs != 1)
  1319. return DISP_E_BADPARAMCOUNT;
  1320. if( pVarResult == NULL)
  1321. return S_OK;
  1322. break;
  1323. case DISPID_COOKIEURL:
  1324. case DISPID_URL:
  1325. case DISPID_ARD:
  1326. case DISPID_ARD_FIXED:
  1327. case DISPID_POLICYHUNT_DONE:
  1328. case DISPID_POLICYHUNT_VIEW:
  1329. if( pDispParams->cArgs != 0)
  1330. return DISP_E_BADPARAMCOUNT;
  1331. if( !(wFlags & DISPATCH_PROPERTYGET))
  1332. return DISP_E_MEMBERNOTFOUND;
  1333. if( pVarResult == NULL)
  1334. return S_OK;
  1335. break;
  1336. default:
  1337. return DISP_E_MEMBERNOTFOUND;
  1338. }
  1339. pVarResult->vt = VT_BSTR;
  1340. switch( dispIdMember)
  1341. {
  1342. case DISPID_COOKIEURL:
  1343. pVarResult->bstrVal = SysAllocString(bstrCookieDomain);
  1344. return S_OK;
  1345. case DISPID_URL:
  1346. {
  1347. BSTR bstrResult = SysAllocString( bstrUrl);
  1348. if( bstrResult == NULL)
  1349. return ERROR_OUTOFMEMORY;
  1350. // Cut of query info from end of URL..
  1351. PWCHAR pCursor = bstrResult;
  1352. while( pCursor[0] != L'\0' && pCursor[0] != L'?')
  1353. pCursor++;
  1354. pCursor[0] = L'\0';
  1355. pVarResult->bstrVal = bstrResult;
  1356. return S_OK;
  1357. }
  1358. case DISPID_ARD:
  1359. {
  1360. unsigned long ulResult;
  1361. if( InternetGetPerSiteCookieDecision(
  1362. bstrCookieDomain, &ulResult)
  1363. == TRUE)
  1364. {
  1365. switch( ulResult)
  1366. {
  1367. case COOKIE_STATE_ACCEPT:
  1368. pVarResult->bstrVal = SysAllocString( L"a");
  1369. break;
  1370. case COOKIE_STATE_REJECT:
  1371. pVarResult->bstrVal = SysAllocString( L"r");
  1372. break;
  1373. default:
  1374. pVarResult->bstrVal = SysAllocString( L"d");
  1375. break;
  1376. }
  1377. }
  1378. else
  1379. {
  1380. pVarResult->bstrVal = SysAllocString( L"d");
  1381. }
  1382. return S_OK;
  1383. }
  1384. case DISPID_ARD_FIXED:
  1385. {
  1386. pVarResult->vt = VT_BOOL;
  1387. pVarResult->boolVal = !allowPerSiteModify();
  1388. return S_OK;
  1389. }
  1390. case DISPID_POLICYHUNT_DONE:
  1391. {
  1392. // try to start the policy hunt..
  1393. if( pPolicyHunt == NULL)
  1394. {
  1395. CPolicyHunt* pNewHunt = new CPolicyHunt();
  1396. if( !pNewHunt
  1397. || TRUE != pNewHunt->Initialize( this)
  1398. || TRUE != pNewHunt->Run())
  1399. {
  1400. goto doneTryToStartPolicyHunt;
  1401. }
  1402. pPolicyHunt = pNewHunt;
  1403. pNewHunt = NULL;
  1404. doneTryToStartPolicyHunt:
  1405. if( pNewHunt != NULL)
  1406. delete pNewHunt;
  1407. }
  1408. pVarResult->vt = VT_BOOL;
  1409. pVarResult->boolVal = pPolicyHunt != NULL
  1410. && pPolicyHunt->IsFinished();
  1411. return S_OK;
  1412. }
  1413. case DISPID_POLICYHUNT_VIEW:
  1414. {
  1415. pVarResult->vt = VT_BSTR;
  1416. LPWSTR szResultHtm = L"policyerror.htm";
  1417. if( pPolicyHunt == NULL
  1418. || FALSE == pPolicyHunt->IsFinished())
  1419. {
  1420. szResultHtm = L"policylooking.htm";
  1421. }
  1422. else if( TRUE == pPolicyHunt->GetResult( &dw))
  1423. {
  1424. switch( dw)
  1425. {
  1426. case POLICYHUNT_FOUND:
  1427. pVarResult->bstrVal = SysAllocString( pPolicyHunt->GetResultFilename());
  1428. return pVarResult->bstrVal ? S_OK : E_UNEXPECTED;
  1429. case POLICYHUNT_NOTFOUND:
  1430. szResultHtm = L"policynone.htm";
  1431. break;
  1432. case POLICYHUNT_INPROGRESS:
  1433. szResultHtm = L"policylooking.htm";
  1434. break;
  1435. case POLICYHUNT_FORMATERROR:
  1436. szResultHtm = L"policysyntaxerror.htm";
  1437. break;
  1438. case POLICYHUNT_ERROR:
  1439. case POLICYHUNT_CANCELLED:
  1440. szResultHtm = L"policyerror.htm";
  1441. break;
  1442. }
  1443. }
  1444. else
  1445. {
  1446. szResultHtm = L"policyerror.htm";
  1447. }
  1448. WCHAR szResURL[MAX_URL_STRING];
  1449. hr = MLBuildResURLWrap(L"shdoclc.dll",
  1450. HINST_THISDLL,
  1451. ML_CROSSCODEPAGE,
  1452. szResultHtm,
  1453. szResURL,
  1454. ARRAYSIZE(szResURL),
  1455. L"shdocvw.dll");
  1456. if( FAILED(hr))
  1457. return E_UNEXPECTED;
  1458. pVarResult->bstrVal = SysAllocString( szResURL);
  1459. return S_OK;
  1460. }
  1461. case DISPID_CREATEABSOLUTEURL:
  1462. {
  1463. WCHAR szBuffer[ MAX_URL_STRING];
  1464. DWORD dwBufferSize = ARRAYSIZE( szBuffer);
  1465. pVarResult->bstrVal = NULL;
  1466. if( pDispParams == NULL)
  1467. {
  1468. return E_UNEXPECTED;
  1469. }
  1470. if( pDispParams->rgvarg[0].vt != VT_BSTR
  1471. || pDispParams->rgvarg[0].bstrVal == NULL)
  1472. {
  1473. // when pVarResult->bstrVal == NULL and we return S_OK,
  1474. // we are returning an empty string.
  1475. return S_OK;
  1476. }
  1477. HRESULT hr = UrlCombine( pPolicyHunt->GetPolicyUrl(),
  1478. pDispParams->rgvarg[0].bstrVal,
  1479. szBuffer, &dwBufferSize,
  1480. URL_ESCAPE_UNSAFE );
  1481. if( hr != S_OK)
  1482. return E_UNEXPECTED;
  1483. pVarResult->bstrVal = SysAllocString( szBuffer);
  1484. if( pVarResult->bstrVal == NULL)
  1485. return E_UNEXPECTED;
  1486. else
  1487. return S_OK;
  1488. }
  1489. }
  1490. return S_OK;
  1491. }
  1492. //
  1493. // Privacy record implementation
  1494. //
  1495. HRESULT CPrivacyRecord::Init( LPTSTR * ppszUrl, LPTSTR * ppszPolicyRef, LPTSTR * ppszP3PHeader,
  1496. DWORD dwFlags)
  1497. {
  1498. unsigned long len = 0;
  1499. TCHAR * pUrl = NULL;
  1500. if (!ppszUrl || !*ppszUrl || !**ppszUrl || !ppszP3PHeader || !ppszPolicyRef )
  1501. return E_POINTER;
  1502. _pszUrl = *ppszUrl;
  1503. _pszP3PHeader = *ppszP3PHeader;
  1504. _pszPolicyRefUrl = *ppszPolicyRef;
  1505. // The record will own the memory from now for these
  1506. *ppszUrl = NULL;
  1507. *ppszP3PHeader = NULL;
  1508. *ppszPolicyRef = NULL;
  1509. _dwPrivacyFlags = dwFlags;
  1510. return S_OK;
  1511. }
  1512. CPrivacyRecord::~CPrivacyRecord()
  1513. {
  1514. delete [] _pszUrl;
  1515. delete [] _pszPolicyRefUrl;
  1516. delete [] _pszP3PHeader;
  1517. }
  1518. HRESULT CPrivacyRecord::SetNext( CPrivacyRecord * pNextRec )
  1519. {
  1520. if (!pNextRec)
  1521. return E_POINTER;
  1522. _pNextNode = pNextRec;
  1523. return S_OK;
  1524. }
  1525. //
  1526. // Privacy queue implementation
  1527. //
  1528. CPrivacyQueue::~CPrivacyQueue()
  1529. {
  1530. Reset();
  1531. }
  1532. void CPrivacyQueue::Reset()
  1533. {
  1534. while (_pHeadRec)
  1535. {
  1536. delete Dequeue();
  1537. }
  1538. }
  1539. void CPrivacyQueue::Queue(CPrivacyRecord *pRecord)
  1540. {
  1541. ASSERT(pRecord);
  1542. if (!_ulSize)
  1543. {
  1544. _pHeadRec = _pTailRec = pRecord;
  1545. }
  1546. else
  1547. {
  1548. ASSERT(_pTailRec);
  1549. _pTailRec->SetNext(pRecord);
  1550. _pTailRec = pRecord;
  1551. }
  1552. _ulSize++;
  1553. }
  1554. CPrivacyRecord* CPrivacyQueue::Dequeue()
  1555. {
  1556. CPrivacyRecord *headRec = NULL;
  1557. if (_ulSize)
  1558. {
  1559. ASSERT(_pHeadRec);
  1560. headRec = _pHeadRec;
  1561. _pHeadRec = headRec->GetNext();
  1562. --_ulSize;
  1563. }
  1564. return headRec;
  1565. }
  1566. ////////////////////////////////////////////////////////////////////////////////////
  1567. //
  1568. // One time privacy discovery dialog proc
  1569. //
  1570. ////////////////////////////////////////////////////////////////////////////////////
  1571. INT_PTR CALLBACK PrivacyDiscoveryDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  1572. {
  1573. BOOL fDontShowNextTime = FALSE;
  1574. WCHAR szBuffer[256];
  1575. switch (message)
  1576. {
  1577. case WM_INITDIALOG:
  1578. {
  1579. CheckDlgButton( hDlg, IDC_PRIV_DISCOVER_DONTSHOW, BST_CHECKED);
  1580. MLLoadStringW(IDS_PRIVACY_LEARNMOREABOUTCOOKIES, szBuffer, ARRAYSIZE(szBuffer));
  1581. RenderStringToEditControlW(hDlg,
  1582. szBuffer,
  1583. (WNDPROC)HyperlinkSubclass,
  1584. IDC_PRIVACY_HELP);
  1585. if( IsOS(OS_WHISTLERORGREATER))
  1586. {
  1587. HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
  1588. if( hIcon != NULL)
  1589. SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  1590. // icons loaded with LoadIcon never need to be released
  1591. }
  1592. return TRUE;
  1593. }
  1594. case WM_COMMAND:
  1595. switch(LOWORD(wParam))
  1596. {
  1597. case IDOK:
  1598. if(IsDlgButtonChecked(hDlg, IDC_PRIV_DISCOVER_DONTSHOW))
  1599. fDontShowNextTime = TRUE;
  1600. else
  1601. fDontShowNextTime = FALSE;
  1602. // fall through
  1603. case IDCANCEL:
  1604. EndDialog(hDlg, fDontShowNextTime);
  1605. return 0;
  1606. case IDC_SETTINGS:
  1607. LaunchPrivacySettings(hDlg);
  1608. return 0;
  1609. }
  1610. break;
  1611. case WM_APP:
  1612. switch( LOWORD( wParam))
  1613. {
  1614. case IDC_PRIVACY_HELP:
  1615. SHHtmlHelpOnDemandWrap(hDlg, TEXT("iexplore.chm > iedefault"),
  1616. HH_DISPLAY_TOPIC, (DWORD_PTR) L"sec_cook.htm", ML_CROSSCODEPAGE);
  1617. }
  1618. }
  1619. return FALSE;
  1620. }
  1621. // returns boolean indicating if dialog should be shown again.
  1622. BOOL DoPrivacyFirstTimeDialog( HWND hwndParent)
  1623. {
  1624. HINSTANCE hRichEditDll;
  1625. BOOL returnValue;
  1626. // We need to load richedit
  1627. hRichEditDll = LoadLibrary(TEXT("RICHED20.DLL"));
  1628. if (!hRichEditDll)
  1629. {
  1630. ASSERT(FALSE); //can't load richedit, complain to akabir
  1631. return TRUE;
  1632. }
  1633. returnValue = (BOOL)SHFusionDialogBoxParam(MLGetHinst(),
  1634. MAKEINTRESOURCE(IDD_PRIV_DISCOVER),
  1635. hwndParent,
  1636. PrivacyDiscoveryDlgProc,
  1637. NULL);
  1638. FreeLibrary( hRichEditDll);
  1639. return returnValue;
  1640. }