Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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