1990 lines
60 KiB
C++
1990 lines
60 KiB
C++
|
//
|
||
|
// privacyui.cpp - Implements the UI for IE's privacy features
|
||
|
//
|
||
|
// The privacy dialog is managed from this sourcefile.
|
||
|
// The privacy view dialog is also managed from this sourcefile.
|
||
|
|
||
|
#include "priv.h"
|
||
|
#include "resource.h"
|
||
|
#include "privacyui.hpp"
|
||
|
#include <mluisupp.h>
|
||
|
#include "richedit.h"
|
||
|
|
||
|
#include "SmallUtil.hpp"
|
||
|
|
||
|
|
||
|
#define REGSTR_PRIVACYPS_PATHEDIT TEXT("Software\\Policies\\Microsoft\\Internet Explorer")
|
||
|
#define REGSTR_PRIVACYPS_VALUEDIT TEXT("PrivacyAddRemoveSites") // this key is duplicated in cpls\inetcpl\privacyui.cpp
|
||
|
|
||
|
#define REGSTR_PRIVACYPS_PATHPANE TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
|
||
|
#define REGSTR_PRIVACYPS_VALUPANE TEXT("Privacy Settings") // this key is duplicated in cpls\inetcpl\privacyui.cpp
|
||
|
|
||
|
#define REGSTR_PRIVACYPS_PATHTAB TEXT("Software\\Policies\\Microsoft\\Internet Explorer\\Control Panel")
|
||
|
#define REGSTR_PRIVACYPS_VALUTAB TEXT("PrivacyTab") // this key is duplicated somewhere else
|
||
|
|
||
|
|
||
|
BOOL allowPerSiteModify()
|
||
|
{
|
||
|
DWORD dwSize, dwRet, dwType, dwValue;
|
||
|
dwSize = sizeof(dwValue);
|
||
|
|
||
|
dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHEDIT,
|
||
|
REGSTR_PRIVACYPS_VALUEDIT, &dwType, &dwValue, &dwSize);
|
||
|
|
||
|
if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
dwSize = sizeof(dwValue);
|
||
|
dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHPANE,
|
||
|
REGSTR_PRIVACYPS_VALUPANE, &dwType, &dwValue, &dwSize);
|
||
|
|
||
|
if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
dwSize = sizeof(dwValue);
|
||
|
dwRet = SHGetValue(HKEY_CURRENT_USER, REGSTR_PRIVACYPS_PATHTAB,
|
||
|
REGSTR_PRIVACYPS_VALUTAB, &dwType, &dwValue, &dwSize);
|
||
|
|
||
|
if (ERROR_SUCCESS == dwRet && dwValue && REG_DWORD == dwType)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
struct SPerSiteData;
|
||
|
typedef SPerSiteData* PSPerSiteData;
|
||
|
|
||
|
class CPolicyHunt;
|
||
|
|
||
|
struct SPrivacyDialogData;
|
||
|
typedef SPrivacyDialogData* PSPrivacyDialogData;
|
||
|
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: HyperlinkSubclass
|
||
|
//
|
||
|
// Synopsis: subclass for the makeshift hyperlink control
|
||
|
//
|
||
|
// Arguments: [hwnd] -- window handle
|
||
|
// [uMsg] -- message id
|
||
|
// [wParam] -- parameter 1
|
||
|
// [lParam] -- parameter 2
|
||
|
//
|
||
|
// Returns: TRUE if message handled, FALSE otherwise
|
||
|
//
|
||
|
// Notes:
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
LRESULT CALLBACK HyperlinkSubclass (
|
||
|
HWND hwnd,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam
|
||
|
)
|
||
|
{
|
||
|
WNDPROC wndproc;
|
||
|
static BOOL fMouseCaptured;
|
||
|
|
||
|
wndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||
|
|
||
|
switch ( uMsg )
|
||
|
{
|
||
|
|
||
|
case WM_SETCURSOR:
|
||
|
|
||
|
if (!fMouseCaptured)
|
||
|
{
|
||
|
SetCapture(hwnd);
|
||
|
fMouseCaptured = TRUE;
|
||
|
}
|
||
|
|
||
|
SetCursor(LoadHandCursor(0));
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_GETDLGCODE:
|
||
|
{
|
||
|
MSG* pmsg;
|
||
|
LRESULT lRet = DLGC_STATIC;
|
||
|
if (((pmsg = (MSG*)lParam)) && ((WM_KEYDOWN == pmsg->message || WM_KEYUP == pmsg->message)))
|
||
|
{
|
||
|
switch(pmsg->wParam)
|
||
|
{
|
||
|
case VK_RETURN:
|
||
|
case VK_SPACE:
|
||
|
lRet |= DLGC_WANTALLKEYS;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return lRet;
|
||
|
}
|
||
|
|
||
|
case WM_KEYDOWN:
|
||
|
if ((wParam!=VK_SPACE)&&(wParam!=VK_RETURN))
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case WM_LBUTTONUP:
|
||
|
SetFocus(hwnd);
|
||
|
PostMessage( GetParent(hwnd), WM_APP, (WPARAM)GetDlgCtrlID( hwnd), (LPARAM)hwnd);
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_LBUTTONDBLCLK:
|
||
|
case WM_MBUTTONDBLCLK:
|
||
|
case WM_RBUTTONDBLCLK:
|
||
|
case WM_RBUTTONUP:
|
||
|
case WM_MBUTTONUP:
|
||
|
case WM_RBUTTONDOWN:
|
||
|
case WM_MBUTTONDOWN:
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
case EM_SETSEL:
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_SETFOCUS:
|
||
|
|
||
|
if ( hwnd == GetFocus() )
|
||
|
{
|
||
|
InvalidateRect(hwnd, NULL, FALSE);
|
||
|
UpdateWindow(hwnd);
|
||
|
SetCursor(LoadHandCursor(0));
|
||
|
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_KILLFOCUS:
|
||
|
|
||
|
InvalidateRect(hwnd, NULL, TRUE);
|
||
|
UpdateWindow(hwnd);
|
||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||
|
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_PAINT:
|
||
|
|
||
|
CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam);
|
||
|
if ( hwnd == GetFocus() )
|
||
|
{
|
||
|
DrawFocusRectangle(hwnd, NULL);
|
||
|
}
|
||
|
return( TRUE );
|
||
|
|
||
|
case WM_MOUSEMOVE:
|
||
|
|
||
|
RECT rect;
|
||
|
int xPos, yPos;
|
||
|
|
||
|
// check to see if the mouse is in this windows rect, if not, then reset
|
||
|
// the cursor to an arrow and release the mouse
|
||
|
GetClientRect(hwnd, &rect);
|
||
|
xPos = LOWORD(lParam);
|
||
|
yPos = HIWORD(lParam);
|
||
|
if ((xPos < 0) ||
|
||
|
(yPos < 0) ||
|
||
|
(xPos > (rect.right - rect.left)) ||
|
||
|
(yPos > (rect.bottom - rect.top)))
|
||
|
{
|
||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||
|
ReleaseCapture();
|
||
|
fMouseCaptured = FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
return(CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// Data structure associated with each site the privacy dialog may show
|
||
|
struct SPerSiteData : public IDispatch
|
||
|
{
|
||
|
BSTR bstrUrl;
|
||
|
BSTR bstrCookieDomain;
|
||
|
BSTR bstrHeaderPolicyRef;
|
||
|
BSTR bstrLinkTagPolicyRef;
|
||
|
DWORD dwFlags;
|
||
|
int iPrivacyImpactResource;
|
||
|
CPolicyHunt* pPolicyHunt;
|
||
|
|
||
|
SPerSiteData();
|
||
|
~SPerSiteData();
|
||
|
|
||
|
BOOL ReadyForPolicyHunt();
|
||
|
|
||
|
// here is overhead for IDispatch:
|
||
|
virtual ULONG __stdcall AddRef( void );
|
||
|
virtual ULONG __stdcall Release( void );
|
||
|
virtual HRESULT __stdcall
|
||
|
QueryInterface( REFIID iid, void ** ppv);
|
||
|
|
||
|
virtual HRESULT __stdcall
|
||
|
GetTypeInfoCount( unsigned int FAR* pctinfo);
|
||
|
|
||
|
virtual HRESULT __stdcall
|
||
|
GetTypeInfo( unsigned int iTInfo,
|
||
|
LCID lcid,
|
||
|
ITypeInfo FAR* FAR* ppTInfo);
|
||
|
|
||
|
virtual HRESULT __stdcall
|
||
|
GetIDsOfNames( REFIID riid,
|
||
|
OLECHAR FAR* FAR* rgszNames,
|
||
|
unsigned int cNames,
|
||
|
LCID lcid,
|
||
|
DISPID FAR* rgDispId);
|
||
|
|
||
|
virtual HRESULT __stdcall
|
||
|
Invoke( DISPID dispIdMember,
|
||
|
REFIID riid,
|
||
|
LCID lcid,
|
||
|
WORD wFlags,
|
||
|
DISPPARAMS FAR* pDispParams,
|
||
|
VARIANT FAR* pVarResult,
|
||
|
EXCEPINFO FAR* pExcepInfo,
|
||
|
unsigned int FAR* puArgErr);
|
||
|
};
|
||
|
|
||
|
|
||
|
enum enumPolicyHuntResult
|
||
|
{
|
||
|
POLICYHUNT_INPROGRESS,
|
||
|
POLICYHUNT_NOTFOUND,
|
||
|
POLICYHUNT_FOUND,
|
||
|
POLICYHUNT_ERROR,
|
||
|
POLICYHUNT_FORMATERROR,
|
||
|
POLICYHUNT_CANCELLED,
|
||
|
};
|
||
|
|
||
|
class CPolicyHunt : public CCancellableThread
|
||
|
{
|
||
|
public:
|
||
|
CPolicyHunt();
|
||
|
~CPolicyHunt();
|
||
|
BOOL Initialize( PSPerSiteData pSite);
|
||
|
|
||
|
//BOOL Run(); defined in CCancelableThread
|
||
|
//BOOL IsFinished(); defined in CCancelableThread
|
||
|
//BOOL WaitForNotRunning( DWORD dwMilliseconds, PBOOL pfFinished); defined in CCancelableThread
|
||
|
BOOL GetResult( PDWORD pdwResult); // special handling wraps CCancelableThread::GetResult
|
||
|
LPCWSTR GetResultFilename();
|
||
|
|
||
|
//BOOL NotifyCancel(); defined in CCancelableThread
|
||
|
|
||
|
private:
|
||
|
virtual DWORD run();
|
||
|
|
||
|
P3PSignal _p3pSignal;
|
||
|
P3PResource _resourceSite;
|
||
|
CHAR _szPolicy[MAX_URL_STRING];
|
||
|
WCHAR _wszPolicy[MAX_URL_STRING];
|
||
|
WCHAR _wszResultsFile[ MAX_PATH];
|
||
|
HANDLE _hPolicyFile;
|
||
|
|
||
|
PCHAR allocCharFromWChar( LPCWSTR pOriginal);
|
||
|
|
||
|
static BSTR s_pwszPrivacyPolicyTransform;
|
||
|
// the transform is loaded from a resource and does not need
|
||
|
//to be deallocated..
|
||
|
|
||
|
public:
|
||
|
LPCWSTR GetPolicyUrl() { return _wszPolicy;};
|
||
|
|
||
|
static void FreePrivacyPolicyTransform()
|
||
|
{
|
||
|
if( s_pwszPrivacyPolicyTransform != NULL)
|
||
|
{
|
||
|
SysFreeString( s_pwszPrivacyPolicyTransform);
|
||
|
s_pwszPrivacyPolicyTransform = NULL;
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
BSTR CPolicyHunt::s_pwszPrivacyPolicyTransform = NULL;
|
||
|
|
||
|
|
||
|
//
|
||
|
// data used by privacy dialog
|
||
|
//
|
||
|
struct SPrivacyDialogData
|
||
|
{
|
||
|
// parameters set when initiating the privacy dialog..
|
||
|
IEnumPrivacyRecords *pEnumPrivacyRecords; // enumerator from Trident
|
||
|
LPOLESTR pszName; // site name
|
||
|
BOOL fReportAllSites; // flag: Report all sites? Otherwise, only report impacted
|
||
|
// and their parent sites.
|
||
|
|
||
|
// parameters set within the privacy dialog code.
|
||
|
|
||
|
// listAllSites lists pointers to SPerSiteData for sites
|
||
|
//return from IEnumPrivacyRecords::enum
|
||
|
CQueueSortOf listAllSites;
|
||
|
ULONG countRecordsEnumerated;
|
||
|
|
||
|
SPrivacyDialogData()
|
||
|
{
|
||
|
countRecordsEnumerated = 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
SPerSiteData::SPerSiteData()
|
||
|
{
|
||
|
bstrUrl = NULL;
|
||
|
bstrCookieDomain = NULL;
|
||
|
bstrHeaderPolicyRef = NULL;
|
||
|
bstrLinkTagPolicyRef = NULL;
|
||
|
dwFlags = 0;
|
||
|
iPrivacyImpactResource = 0;
|
||
|
pPolicyHunt = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
SPerSiteData::~SPerSiteData()
|
||
|
{
|
||
|
if( bstrUrl != NULL)
|
||
|
SysFreeString( bstrUrl);
|
||
|
|
||
|
if( bstrCookieDomain != NULL)
|
||
|
SysFreeString( bstrCookieDomain);
|
||
|
|
||
|
if( bstrHeaderPolicyRef != NULL)
|
||
|
SysFreeString( bstrHeaderPolicyRef);
|
||
|
|
||
|
if( bstrLinkTagPolicyRef != NULL)
|
||
|
SysFreeString( bstrLinkTagPolicyRef);
|
||
|
|
||
|
if( pPolicyHunt != NULL)
|
||
|
delete pPolicyHunt;
|
||
|
}
|
||
|
|
||
|
|
||
|
CPolicyHunt::CPolicyHunt()
|
||
|
{
|
||
|
memset( &_p3pSignal, 0, sizeof(P3PSignal));
|
||
|
memset( &_resourceSite, 0, sizeof(P3PResource));
|
||
|
_szPolicy[0] = '\0';
|
||
|
_wszPolicy[0] = L'\0';
|
||
|
_wszResultsFile[0] = L'\0';
|
||
|
_hPolicyFile = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
CPolicyHunt::~CPolicyHunt()
|
||
|
{
|
||
|
if( _hPolicyFile != INVALID_HANDLE_VALUE)
|
||
|
CloseHandle( _hPolicyFile);
|
||
|
|
||
|
if( _wszResultsFile[0] != L'\0')
|
||
|
{
|
||
|
DeleteFile( _wszResultsFile);
|
||
|
}
|
||
|
|
||
|
if( _p3pSignal.hEvent != NULL)
|
||
|
CloseHandle( _p3pSignal.hEvent);
|
||
|
|
||
|
if( _resourceSite.pszLocation != NULL)
|
||
|
delete [] _resourceSite.pszLocation;
|
||
|
if( _resourceSite.pszVerb != NULL)
|
||
|
delete [] _resourceSite.pszVerb;
|
||
|
if( _resourceSite.pszP3PHeaderRef != NULL)
|
||
|
delete [] _resourceSite.pszP3PHeaderRef;
|
||
|
if( _resourceSite.pszLinkTagRef != NULL)
|
||
|
delete [] _resourceSite.pszLinkTagRef;
|
||
|
}
|
||
|
|
||
|
|
||
|
PCHAR CPolicyHunt::allocCharFromWChar( LPCWSTR pOriginal)
|
||
|
{
|
||
|
PCHAR pResult;
|
||
|
|
||
|
if( pOriginal == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
int iSize = 1 + lstrlen( pOriginal);
|
||
|
|
||
|
pResult = new CHAR[ iSize];
|
||
|
|
||
|
if( pResult == NULL)
|
||
|
return NULL;
|
||
|
|
||
|
SHTCharToAnsi( pOriginal, pResult, iSize);
|
||
|
|
||
|
return pResult;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CPolicyHunt::Initialize( PSPerSiteData pSite)
|
||
|
{
|
||
|
if( TRUE != CCancellableThread::Initialize())
|
||
|
return FALSE;
|
||
|
|
||
|
_resourceSite.pszLocation = allocCharFromWChar( pSite->bstrUrl);
|
||
|
_resourceSite.pszVerb = allocCharFromWChar(
|
||
|
(pSite->dwFlags & PRIVACY_URLHASPOSTDATA) ? L"POST" : L"GET");
|
||
|
_resourceSite.pszP3PHeaderRef = allocCharFromWChar( pSite->bstrHeaderPolicyRef);
|
||
|
_resourceSite.pszLinkTagRef = allocCharFromWChar( pSite->bstrLinkTagPolicyRef);
|
||
|
_resourceSite.pContainer = NULL;
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CPolicyHunt::GetResult( PDWORD pdwResult)
|
||
|
{
|
||
|
if( IsFinished())
|
||
|
{
|
||
|
return CCancellableThread::GetResult( pdwResult);
|
||
|
}
|
||
|
|
||
|
*pdwResult = POLICYHUNT_INPROGRESS;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
LPCWSTR CPolicyHunt::GetResultFilename()
|
||
|
{
|
||
|
return _wszResultsFile;
|
||
|
}
|
||
|
|
||
|
|
||
|
// used only in CPolicyHunt::run..
|
||
|
// This the fetched transform need never be deallocated,
|
||
|
//and need only be allocated once.
|
||
|
BSTR LoadPrivacyPolicyTransform()
|
||
|
{
|
||
|
BSTR returnValue = NULL;
|
||
|
DWORD dwByteSizeOfResource;
|
||
|
|
||
|
HRSRC hrsrc = FindResource( MLGetHinst(),
|
||
|
TEXT("privacypolicytransform.xsl"),
|
||
|
MAKEINTRESOURCE(RT_HTML));
|
||
|
|
||
|
if( hrsrc == NULL)
|
||
|
goto doneLoadPrivacyPolicyTransform;
|
||
|
|
||
|
dwByteSizeOfResource = SizeofResource( MLGetHinst(), hrsrc);
|
||
|
|
||
|
if( dwByteSizeOfResource == 0)
|
||
|
goto doneLoadPrivacyPolicyTransform;
|
||
|
|
||
|
HGLOBAL hGlobal = LoadResource( MLGetHinst(), hrsrc); // Loaded resources do not need to be unloaded
|
||
|
|
||
|
if( hGlobal == NULL)
|
||
|
goto doneLoadPrivacyPolicyTransform;
|
||
|
|
||
|
LPVOID pLockedResource = LockResource( hGlobal); // Locked resources do not need to be unlocked
|
||
|
|
||
|
if( pLockedResource == NULL)
|
||
|
goto doneLoadPrivacyPolicyTransform;
|
||
|
|
||
|
// Skip first WCHAR when allocating BSTR copy of the transform,
|
||
|
// since unicode resource starts with an extra 0xFF 0xFE
|
||
|
int cwCount = (dwByteSizeOfResource/sizeof(WCHAR)) - 1;
|
||
|
returnValue = SysAllocStringLen( 1+(LPCWSTR)pLockedResource, cwCount);
|
||
|
|
||
|
doneLoadPrivacyPolicyTransform:
|
||
|
|
||
|
return returnValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD CPolicyHunt::run()
|
||
|
{
|
||
|
DWORD retVal = POLICYHUNT_ERROR;
|
||
|
int iTemp;
|
||
|
DWORD dw;
|
||
|
|
||
|
if( IsFinished())
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
// MapResourceToPolicy phase
|
||
|
|
||
|
// ... need an event..
|
||
|
_p3pSignal.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL);
|
||
|
if( _p3pSignal.hEvent == NULL)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
// ... now call MapResourceToPolicy
|
||
|
iTemp = MapResourceToPolicy(&(_resourceSite),
|
||
|
_szPolicy,
|
||
|
ARRAYSIZE(_szPolicy),
|
||
|
&(_p3pSignal));
|
||
|
if( iTemp != P3P_InProgress)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
// ... now wait for MapResourceToPolicy to finish
|
||
|
do
|
||
|
{
|
||
|
if( IsCancelled())
|
||
|
{
|
||
|
retVal = POLICYHUNT_CANCELLED;
|
||
|
goto doneCPolicyHuntRun;
|
||
|
}
|
||
|
} while ( WAIT_TIMEOUT == (dw = WaitForSingleObject( _p3pSignal.hEvent, 100)));
|
||
|
if( WAIT_OBJECT_0 != dw)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
FreeP3PObject( _p3pSignal.hRequest);
|
||
|
_p3pSignal.hRequest = NULL;
|
||
|
|
||
|
// ... check if MapResourceToPolicy found anything..
|
||
|
if( _szPolicy[0] == '\0')
|
||
|
{
|
||
|
retVal = POLICYHUNT_NOTFOUND;
|
||
|
goto doneCPolicyHuntRun;
|
||
|
}
|
||
|
|
||
|
// prepare a WCHAR copy of the policy
|
||
|
SHAnsiToUnicode( _szPolicy, _wszPolicy, ARRAYSIZE( _wszPolicy));
|
||
|
|
||
|
// Now we need to prepare a temp file for our result.
|
||
|
// ... get the path for the result file
|
||
|
WCHAR szPathBuffer[ MAX_PATH];
|
||
|
dw = GetTempPath( ARRAYSIZE( szPathBuffer), szPathBuffer);
|
||
|
if( dw == 0 || dw+1 > MAX_PATH)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
// ... get a .tmp filename for the result file
|
||
|
dw = GetTempFileName( szPathBuffer, L"IE", 0, _wszResultsFile);
|
||
|
if( dw == 0)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
DeleteFile( _wszResultsFile);
|
||
|
|
||
|
// ... make the .tmp filename a .htm filename
|
||
|
dw = lstrlen( _wszResultsFile);
|
||
|
while( dw > 0 && _wszResultsFile[dw] != L'.')
|
||
|
{
|
||
|
dw--;
|
||
|
}
|
||
|
StrCpyNW( _wszResultsFile + dw, L".htm", ARRAYSIZE(L".htm"));
|
||
|
|
||
|
// ... open the file
|
||
|
_hPolicyFile = CreateFile( _wszResultsFile,
|
||
|
GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
if( _hPolicyFile == INVALID_HANDLE_VALUE)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
if( s_pwszPrivacyPolicyTransform == NULL)
|
||
|
s_pwszPrivacyPolicyTransform = LoadPrivacyPolicyTransform();
|
||
|
|
||
|
if( s_pwszPrivacyPolicyTransform == NULL)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
ResetEvent( _p3pSignal.hEvent);
|
||
|
|
||
|
iTemp = GetP3PPolicy( _szPolicy, _hPolicyFile,
|
||
|
s_pwszPrivacyPolicyTransform, &_p3pSignal);
|
||
|
if( iTemp != P3P_InProgress)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
// ... now wait for GetP3PPolicy to finish
|
||
|
do
|
||
|
{
|
||
|
if( IsCancelled())
|
||
|
{
|
||
|
retVal = POLICYHUNT_CANCELLED;
|
||
|
goto doneCPolicyHuntRun;
|
||
|
}
|
||
|
} while ( WAIT_TIMEOUT == (dw = WaitForSingleObject( _p3pSignal.hEvent, 100)));
|
||
|
if( WAIT_OBJECT_0 != dw)
|
||
|
goto doneCPolicyHuntRun;
|
||
|
|
||
|
int iGetP3PPolicyResult;
|
||
|
iGetP3PPolicyResult = GetP3PRequestStatus( _p3pSignal.hRequest);
|
||
|
|
||
|
switch( iGetP3PPolicyResult)
|
||
|
{
|
||
|
case P3P_Done:
|
||
|
retVal = POLICYHUNT_FOUND;
|
||
|
break;
|
||
|
case P3P_NoPolicy:
|
||
|
case P3P_NotFound:
|
||
|
retVal = POLICYHUNT_NOTFOUND;
|
||
|
break;
|
||
|
case P3P_Failed:
|
||
|
retVal = POLICYHUNT_ERROR;
|
||
|
break;
|
||
|
case P3P_FormatErr:
|
||
|
retVal = POLICYHUNT_FORMATERROR;
|
||
|
break;
|
||
|
case P3P_Cancelled:
|
||
|
retVal = POLICYHUNT_CANCELLED;
|
||
|
break;
|
||
|
default:
|
||
|
retVal = POLICYHUNT_ERROR;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
doneCPolicyHuntRun:
|
||
|
if( _hPolicyFile != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
CloseHandle( _hPolicyFile);
|
||
|
_hPolicyFile = INVALID_HANDLE_VALUE;
|
||
|
}
|
||
|
|
||
|
if( _p3pSignal.hRequest != NULL)
|
||
|
{
|
||
|
FreeP3PObject( _p3pSignal.hRequest);
|
||
|
_p3pSignal.hRequest = NULL;
|
||
|
}
|
||
|
|
||
|
if( _p3pSignal.hEvent != NULL)
|
||
|
{
|
||
|
CloseHandle( _p3pSignal.hEvent);
|
||
|
_p3pSignal.hEvent = NULL;
|
||
|
}
|
||
|
|
||
|
memset( &_p3pSignal, 0, sizeof(P3PSignal));
|
||
|
|
||
|
return retVal;
|
||
|
}
|
||
|
|
||
|
|
||
|
// be warned: a NULL BSTR is equivalent to a "" BSTR..
|
||
|
// This function returns the cookie domain from an http:// or https:// style Url.
|
||
|
BSTR GetCookieDomainFromUrl( LPCWSTR bstrFullUrl)
|
||
|
{
|
||
|
BSTR returnValue = NULL;
|
||
|
|
||
|
if( bstrFullUrl == NULL)
|
||
|
goto doneGetMinimizedCookieDomain;
|
||
|
|
||
|
WCHAR wszUrl[MAX_URL_STRING], *pMinimizedDomain;
|
||
|
wszUrl[0] = L'\0';
|
||
|
StrCpyNW( wszUrl, bstrFullUrl, lstrlen( bstrFullUrl)+1);
|
||
|
|
||
|
if( wszUrl[0] == '\0')
|
||
|
goto doneGetMinimizedCookieDomain;
|
||
|
|
||
|
WCHAR *pBeginUrl = wszUrl; // pBeginUrl will be 'http://full.domain.com/path/path...'
|
||
|
while( *pBeginUrl != L'\0' && *pBeginUrl != L'/')
|
||
|
pBeginUrl++;
|
||
|
if( *pBeginUrl == L'/')
|
||
|
pBeginUrl++;
|
||
|
while( *pBeginUrl != L'\0' && *pBeginUrl != L'/')
|
||
|
pBeginUrl++;
|
||
|
if( *pBeginUrl == L'/')
|
||
|
pBeginUrl++; // now pBeginUrl is 'full.domain.com/path/path'..
|
||
|
WCHAR *pEndUrl = pBeginUrl; // pEndUrl will find the '/path/path..' and clip it from pBeginUrl
|
||
|
while( *pEndUrl != L'\0' && *pEndUrl != L'/')
|
||
|
pEndUrl++;
|
||
|
*pEndUrl = L'\0';
|
||
|
pMinimizedDomain = pEndUrl;
|
||
|
// pBeginUrl is now like 'full.domain.com'
|
||
|
// pMinimizedDomain will reduce pBeginUrl to a domain minimized to still allow cookies..
|
||
|
|
||
|
do
|
||
|
{
|
||
|
pMinimizedDomain--;
|
||
|
while( pBeginUrl < pMinimizedDomain
|
||
|
&& *(pMinimizedDomain-1) != L'.')
|
||
|
{
|
||
|
pMinimizedDomain--;
|
||
|
}
|
||
|
} while( !IsDomainLegalCookieDomain( pMinimizedDomain, pBeginUrl)
|
||
|
&& pBeginUrl < pMinimizedDomain);
|
||
|
|
||
|
returnValue = SysAllocString( pMinimizedDomain);
|
||
|
|
||
|
doneGetMinimizedCookieDomain:
|
||
|
return returnValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
void PrivacyDlgDeallocSiteList( PSPrivacyDialogData pData)
|
||
|
{
|
||
|
void* iterator = NULL;
|
||
|
while( NULL != (iterator = pData->listAllSites.StepEnumerate(iterator)))
|
||
|
{
|
||
|
PSPerSiteData pCurrent =
|
||
|
(PSPerSiteData)(pData->listAllSites.Get( iterator));
|
||
|
delete pCurrent;
|
||
|
}
|
||
|
|
||
|
CPolicyHunt::FreePrivacyPolicyTransform();
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL PrivacyDialogExtendSiteList( PSPrivacyDialogData pData)
|
||
|
{
|
||
|
BOOL returnValue = FALSE;
|
||
|
|
||
|
BSTR bstrUrl = NULL, bstrPolicyRef = NULL;
|
||
|
DWORD dwFlags;
|
||
|
ULONG ulPrivacyRecordsTotal;
|
||
|
|
||
|
if( FAILED(pData->pEnumPrivacyRecords->GetSize( &ulPrivacyRecordsTotal)))
|
||
|
ulPrivacyRecordsTotal = 0;
|
||
|
|
||
|
DWORD dwTemp;
|
||
|
|
||
|
// Enumerate the sites in IEnumPrivacyRecords::enum
|
||
|
PSPerSiteData pCurrentSite = NULL, pCurrentSiteInList = NULL;
|
||
|
while( pData->countRecordsEnumerated < ulPrivacyRecordsTotal
|
||
|
&& SUCCEEDED( dwTemp = pData->pEnumPrivacyRecords->
|
||
|
Next(&bstrUrl, &bstrPolicyRef,
|
||
|
NULL, &dwFlags)))
|
||
|
{
|
||
|
pData->countRecordsEnumerated++;
|
||
|
pCurrentSite = NULL;
|
||
|
pCurrentSiteInList = NULL;
|
||
|
void* iterator = NULL;
|
||
|
|
||
|
if(NULL == bstrUrl || 0 == *bstrUrl)
|
||
|
{
|
||
|
// every time we pass a blank token,
|
||
|
//we begin processing a higher navigation level.
|
||
|
SysFreeString( bstrUrl);
|
||
|
bstrUrl = NULL;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if( 0 != StrNCmpI( bstrUrl, L"http", ARRAYSIZE(L"http")-1))
|
||
|
{
|
||
|
// we ignore non http stuff... like ftp, local files..
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Test if the current site is already in the list.
|
||
|
iterator = NULL;
|
||
|
while( pCurrentSiteInList == NULL
|
||
|
&& NULL !=
|
||
|
(iterator = pData->listAllSites.StepEnumerate(iterator)))
|
||
|
{
|
||
|
PSPerSiteData pCurrent =
|
||
|
(PSPerSiteData)(pData->listAllSites.Get( iterator));
|
||
|
if( 0 == StrCmp( bstrUrl, pCurrent->bstrUrl))
|
||
|
pCurrentSiteInList = pCurrent;
|
||
|
}
|
||
|
|
||
|
// If the site is not in the list, add it.
|
||
|
// If the site isn't in the list, add the information given by enum.
|
||
|
if( pCurrentSiteInList == NULL)
|
||
|
{
|
||
|
pCurrentSite = new SPerSiteData();
|
||
|
|
||
|
if( pCurrentSite == NULL)
|
||
|
goto donePrivacyDialogExtendSiteList;
|
||
|
|
||
|
pCurrentSite->bstrUrl = bstrUrl;
|
||
|
bstrUrl = NULL;
|
||
|
pCurrentSite->dwFlags = dwFlags;
|
||
|
// Now find the minimized cookie domain..
|
||
|
pCurrentSite->bstrCookieDomain =
|
||
|
GetCookieDomainFromUrl( pCurrentSite->bstrUrl);
|
||
|
|
||
|
if( pData->listAllSites.InsertAtEnd( pCurrentSite))
|
||
|
pCurrentSiteInList = pCurrentSite;
|
||
|
else
|
||
|
goto donePrivacyDialogExtendSiteList;
|
||
|
}
|
||
|
else // else we have a duplicate list item
|
||
|
{
|
||
|
pCurrentSite = pCurrentSiteInList;
|
||
|
// pCurrentSite->bstrUrl is correct
|
||
|
// pCurrentSite->bstrCookieDomain is correct
|
||
|
pCurrentSite->dwFlags |= dwFlags;
|
||
|
}
|
||
|
|
||
|
if( bstrPolicyRef != NULL && dwFlags & PRIVACY_URLHASPOLICYREFHEADER)
|
||
|
{ // We have the policy ref from the header..
|
||
|
SysFreeString( pCurrentSite->bstrHeaderPolicyRef); // NULLs are ignored..
|
||
|
pCurrentSite->bstrHeaderPolicyRef = bstrPolicyRef;
|
||
|
bstrPolicyRef = NULL;
|
||
|
}
|
||
|
else if ( bstrPolicyRef != NULL && dwFlags & PRIVACY_URLHASPOLICYREFLINK)
|
||
|
{ // We have the policy ref from the link tag..
|
||
|
SysFreeString( pCurrentSite->bstrLinkTagPolicyRef); // NULLs are ignored..
|
||
|
pCurrentSite->bstrLinkTagPolicyRef = bstrPolicyRef;
|
||
|
bstrPolicyRef = NULL;
|
||
|
}
|
||
|
else if( bstrPolicyRef != NULL)
|
||
|
{ // We have a policy ref with an unknown source.. bug in IEnumPrivacyRecords
|
||
|
ASSERT(0);
|
||
|
SysFreeString( pCurrentSite->bstrHeaderPolicyRef); // NULLs are ignored..
|
||
|
pCurrentSite->bstrHeaderPolicyRef = bstrPolicyRef;
|
||
|
bstrPolicyRef = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
// now to determine the privacy impact of the site..
|
||
|
// precedence: IDS_PRIVACY_BLOCKED > IDS_PRIVACY_RESTRICTED > IDS_PRIVACY_ACCEPTED > nothing
|
||
|
if( dwFlags & (COOKIEACTION_ACCEPT | COOKIEACTION_LEASH))
|
||
|
{
|
||
|
pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
|
||
|
IDS_PRIVACY_ACCEPTED);
|
||
|
}
|
||
|
|
||
|
if( dwFlags & COOKIEACTION_DOWNGRADE)
|
||
|
{
|
||
|
pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
|
||
|
IDS_PRIVACY_RESTRICTED);
|
||
|
}
|
||
|
|
||
|
if( dwFlags & (COOKIEACTION_REJECT | COOKIEACTION_SUPPRESS))
|
||
|
{
|
||
|
pCurrentSite->iPrivacyImpactResource = max( pCurrentSite->iPrivacyImpactResource,
|
||
|
IDS_PRIVACY_BLOCKED);
|
||
|
}
|
||
|
|
||
|
SysFreeString( bstrUrl);
|
||
|
bstrUrl = NULL;
|
||
|
SysFreeString( bstrPolicyRef);
|
||
|
bstrPolicyRef = NULL;
|
||
|
}
|
||
|
|
||
|
returnValue = TRUE;
|
||
|
|
||
|
donePrivacyDialogExtendSiteList:
|
||
|
if( bstrUrl != NULL)
|
||
|
SysFreeString( bstrUrl);
|
||
|
|
||
|
if( bstrPolicyRef != NULL)
|
||
|
SysFreeString( bstrUrl);
|
||
|
|
||
|
if( pCurrentSite != NULL && pCurrentSiteInList == NULL)
|
||
|
delete pCurrentSite;
|
||
|
|
||
|
return returnValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL PrivacyDlgBuildSiteList( PSPrivacyDialogData pData)
|
||
|
{
|
||
|
PrivacyDlgDeallocSiteList( pData);
|
||
|
|
||
|
return PrivacyDialogExtendSiteList( pData);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL InitializePrivacyDlg(HWND hDlg, PSPrivacyDialogData pData)
|
||
|
{
|
||
|
WCHAR szBuffer[256];
|
||
|
HWND hwndListView = GetDlgItem(hDlg, IDC_SITE_LIST);
|
||
|
RECT rc;
|
||
|
|
||
|
// Set the privacy status caption text
|
||
|
BOOL fImpacted;
|
||
|
if( SUCCEEDED(pData->pEnumPrivacyRecords->GetPrivacyImpacted(&fImpacted)) && fImpacted)
|
||
|
{
|
||
|
MLLoadStringW( IDS_PRIVACY_STATUSIMPACTED, szBuffer, ARRAYSIZE( szBuffer));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
MLLoadStringW( IDS_PRIVACY_STATUSNOIMPACT, szBuffer, ARRAYSIZE( szBuffer));
|
||
|
}
|
||
|
SendMessage( GetDlgItem( hDlg, IDC_PRIVACY_STATUSTEXT), WM_SETTEXT,
|
||
|
0, (LPARAM)szBuffer);
|
||
|
|
||
|
//Initialize the list view..
|
||
|
// ..Empty the list in list view.
|
||
|
ListView_DeleteAllItems (hwndListView);
|
||
|
|
||
|
// ..Initialize the columns in the list view.
|
||
|
LV_COLUMN lvColumn;
|
||
|
lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
|
||
|
lvColumn.fmt = LVCFMT_LEFT;
|
||
|
lvColumn.pszText = szBuffer;
|
||
|
|
||
|
lvColumn.cx = 300;
|
||
|
if( 0 != GetClientRect( hwndListView, &rc))
|
||
|
lvColumn.cx = rc.right - rc.left - 150 - GetSystemMetrics( SM_CXVSCROLL);
|
||
|
// 15 is an arbitrary number to prevent the horizontal scrollbar from appearing
|
||
|
MLLoadStringW(IDS_PRIVACY_COLUMN1, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
ListView_InsertColumn(hwndListView, 1, &lvColumn);
|
||
|
|
||
|
lvColumn.cx = 150;
|
||
|
MLLoadStringW(IDS_PRIVACY_COLUMN2, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
ListView_InsertColumn(hwndListView, 2, &lvColumn);
|
||
|
|
||
|
// Initialize the view all/restricted combo box
|
||
|
HWND hwndComboBox = GetDlgItem( hDlg, IDC_PRIVACY_VIEWCOMBO);
|
||
|
|
||
|
ComboBox_ResetContent( hwndComboBox);
|
||
|
int iComboPosition;
|
||
|
|
||
|
MLLoadStringW(IDS_PRIVACY_VIEWIMPACTED, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
iComboPosition = ComboBox_AddString(hwndComboBox, szBuffer);
|
||
|
ComboBox_SetItemData(hwndComboBox, iComboPosition, 0);
|
||
|
MLLoadStringW(IDS_PRIVACY_VIEWALL, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
iComboPosition = ComboBox_AddString(hwndComboBox, szBuffer);
|
||
|
ComboBox_SetItemData(hwndComboBox, iComboPosition, 1);
|
||
|
|
||
|
ComboBox_SetCurSel( hwndComboBox, pData->fReportAllSites);
|
||
|
|
||
|
GetDlgItemText( hDlg, IDC_PRIVACY_HELP, szBuffer, ARRAYSIZE( szBuffer));
|
||
|
MLLoadStringW(IDS_PRIVACY_LEARNMOREABOUTPRIVACY, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
RenderStringToEditControlW(hDlg,
|
||
|
szBuffer,
|
||
|
(WNDPROC)HyperlinkSubclass,
|
||
|
IDC_PRIVACY_HELP);
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// add items to the privacy dialog's listview..
|
||
|
BOOL PopulatePrivacyDlgListView(HWND hDlg, PSPrivacyDialogData pData, bool fMaintainSelectedItem)
|
||
|
{
|
||
|
HWND hwndListView = GetDlgItem( hDlg, IDC_SITE_LIST);
|
||
|
void* iterator = NULL;
|
||
|
int iCurrentPosition = 0;
|
||
|
int iSelectedItem = ListView_GetSelectionMark( hwndListView);
|
||
|
PSPerSiteData pSelectedItem = NULL;
|
||
|
|
||
|
if( fMaintainSelectedItem && iSelectedItem != -1)
|
||
|
{
|
||
|
LVITEM lvi;
|
||
|
lvi.mask = LVIF_PARAM;
|
||
|
lvi.iItem = iSelectedItem;
|
||
|
if( FALSE != ListView_GetItem( hwndListView, &lvi)
|
||
|
&& lvi.lParam != (LPARAM)NULL)
|
||
|
{
|
||
|
pSelectedItem = (PSPerSiteData)lvi.lParam;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Empty the list in list view.
|
||
|
ListView_DeleteAllItems (hwndListView);
|
||
|
|
||
|
iSelectedItem = -1;
|
||
|
|
||
|
while( NULL != (iterator = pData->listAllSites.StepEnumerate(iterator)))
|
||
|
{
|
||
|
PSPerSiteData pCurrent =
|
||
|
(PSPerSiteData)(pData->listAllSites.Get(iterator));
|
||
|
|
||
|
BOOL fAddItem = pData->fReportAllSites
|
||
|
|| pCurrent->iPrivacyImpactResource == IDS_PRIVACY_SUPPRESSED
|
||
|
|| pCurrent->iPrivacyImpactResource == IDS_PRIVACY_RESTRICTED
|
||
|
|| pCurrent->iPrivacyImpactResource == IDS_PRIVACY_BLOCKED;
|
||
|
|
||
|
if( fAddItem == TRUE)
|
||
|
{
|
||
|
LVITEM lvitem;
|
||
|
lvitem.mask = LVIF_TEXT | LVIF_PARAM;
|
||
|
lvitem.pszText = pCurrent->bstrUrl;
|
||
|
lvitem.iItem = iCurrentPosition++;
|
||
|
lvitem.iSubItem = 0;
|
||
|
lvitem.lParam = (LPARAM)pCurrent;
|
||
|
ListView_InsertItem(hwndListView, &lvitem);
|
||
|
|
||
|
if( pCurrent->iPrivacyImpactResource != 0)
|
||
|
{
|
||
|
WCHAR wszTemp[128];
|
||
|
|
||
|
// set cookie string
|
||
|
lvitem.iSubItem = 1;
|
||
|
lvitem.mask = LVIF_TEXT;
|
||
|
lvitem.pszText = wszTemp;
|
||
|
if( MLLoadString(pCurrent->iPrivacyImpactResource,
|
||
|
wszTemp, ARRAYSIZE(wszTemp)))
|
||
|
{
|
||
|
SendMessage(hwndListView, LVM_SETITEMTEXT,
|
||
|
(WPARAM)lvitem.iItem, (LPARAM)&lvitem);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// We either keep the last item selected as selected,
|
||
|
//or select the last top-level item.
|
||
|
if( fMaintainSelectedItem)
|
||
|
{
|
||
|
if( pSelectedItem == pCurrent)
|
||
|
iSelectedItem = lvitem.iItem;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if( fMaintainSelectedItem && iSelectedItem != -1)
|
||
|
// {
|
||
|
// ListView_SetItemState( hwndListView, iSelectedItem, LVIS_SELECTED, LVIS_SELECTED);
|
||
|
// ListView_SetSelectionMark( hwndListView, iSelectedItem);
|
||
|
// ListView_EnsureVisible( hwndListView, iSelectedItem, FALSE);
|
||
|
// }
|
||
|
|
||
|
PostMessage( hDlg, WM_APP, IDC_SITE_LIST, 0); // notifies the dialog that a listview item has been selected
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
typedef BOOL (*PFNPRIVACYSETTINGS)(HWND);
|
||
|
|
||
|
void LaunchPrivacySettings(HWND hwndParent)
|
||
|
{
|
||
|
HMODULE hmodInetcpl;
|
||
|
PFNPRIVACYSETTINGS pfnPriv;
|
||
|
|
||
|
hmodInetcpl = LoadLibrary(TEXT("inetcpl.cpl"));
|
||
|
if(hmodInetcpl)
|
||
|
{
|
||
|
pfnPriv = (PFNPRIVACYSETTINGS)GetProcAddress(hmodInetcpl, "LaunchPrivacyDialog");
|
||
|
if(pfnPriv)
|
||
|
{
|
||
|
pfnPriv(hwndParent);
|
||
|
}
|
||
|
|
||
|
FreeLibrary(hmodInetcpl);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL PrivacyPolicyHtmlDlg( HWND hDlg, HWND hwndListView, int iItemIndex)
|
||
|
{
|
||
|
BOOL returnValue = FALSE;
|
||
|
HRESULT hr;
|
||
|
DWORD dw;
|
||
|
PSPerSiteData pListViewData;
|
||
|
WCHAR* pwchHtmlDialogInput = NULL;
|
||
|
IMoniker * pmk = NULL;
|
||
|
VARIANT varArg, varOut;
|
||
|
VariantInit( &varArg);
|
||
|
VariantInit( &varOut);
|
||
|
|
||
|
LVITEM lvi;
|
||
|
lvi.mask = LVIF_PARAM;
|
||
|
lvi.iItem = iItemIndex;
|
||
|
if( FALSE == ListView_GetItem( hwndListView, &lvi)
|
||
|
|| lvi.lParam == (LPARAM)NULL)
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
pListViewData = (PSPerSiteData)lvi.lParam;
|
||
|
|
||
|
WCHAR szResURL[MAX_URL_STRING];
|
||
|
|
||
|
// fetch the HTML for the dialog box..
|
||
|
hr = MLBuildResURLWrap(TEXT("shdoclc.dll"),
|
||
|
HINST_THISDLL,
|
||
|
ML_CROSSCODEPAGE,
|
||
|
TEXT("privacypolicy.dlg"),
|
||
|
szResURL,
|
||
|
ARRAYSIZE(szResURL),
|
||
|
TEXT("shdocvw.dll"));
|
||
|
|
||
|
if( FAILED( hr))
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
|
||
|
hr = CreateURLMoniker(NULL, szResURL, &pmk);
|
||
|
if( FAILED( hr))
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
|
||
|
varArg.vt = VT_DISPATCH;
|
||
|
varArg.pdispVal = (IDispatch*)pListViewData;
|
||
|
|
||
|
// Show the dialog..
|
||
|
hr = ShowHTMLDialog( hDlg, pmk, &varArg, L"help:no; resizable:1", &varOut);
|
||
|
|
||
|
if( FAILED( hr))
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
|
||
|
hr = VariantChangeType( &varOut, &varOut, NULL, VT_I4);
|
||
|
|
||
|
if( FAILED( hr))
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
|
||
|
if( allowPerSiteModify())
|
||
|
{
|
||
|
switch( varOut.lVal)
|
||
|
{
|
||
|
default:
|
||
|
hr = TRUE;
|
||
|
break;
|
||
|
case 1:
|
||
|
hr = InternetSetPerSiteCookieDecision(
|
||
|
pListViewData->bstrCookieDomain, COOKIE_STATE_UNKNOWN);
|
||
|
break;
|
||
|
case 2:
|
||
|
hr = InternetSetPerSiteCookieDecision(
|
||
|
pListViewData->bstrCookieDomain, COOKIE_STATE_ACCEPT);
|
||
|
break;
|
||
|
case 3:
|
||
|
hr = InternetSetPerSiteCookieDecision(
|
||
|
pListViewData->bstrCookieDomain, COOKIE_STATE_REJECT);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( hr != TRUE)
|
||
|
goto donePrivacyPolicyHtmlDlg;
|
||
|
|
||
|
returnValue = TRUE;
|
||
|
|
||
|
donePrivacyPolicyHtmlDlg:
|
||
|
|
||
|
if( pListViewData->pPolicyHunt != NULL)
|
||
|
{
|
||
|
// no-op if already finished
|
||
|
pListViewData->pPolicyHunt->NotifyCancel();
|
||
|
pListViewData->pPolicyHunt->WaitForNotRunning( INFINITE);
|
||
|
}
|
||
|
|
||
|
if( pListViewData->pPolicyHunt != NULL
|
||
|
&& pListViewData->pPolicyHunt->GetResult( &dw) == TRUE
|
||
|
&& dw != POLICYHUNT_FOUND)
|
||
|
{
|
||
|
delete pListViewData->pPolicyHunt;
|
||
|
pListViewData->pPolicyHunt = NULL;
|
||
|
}
|
||
|
|
||
|
if( pwchHtmlDialogInput != NULL)
|
||
|
delete[] pwchHtmlDialogInput;
|
||
|
|
||
|
if( pmk != NULL)
|
||
|
ATOMICRELEASE( pmk);
|
||
|
|
||
|
VariantClear( &varArg);
|
||
|
VariantClear( &varOut);
|
||
|
|
||
|
return returnValue;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL PrivacyDlgContextMenuHandler( HWND hDlg, HWND hwndListView,
|
||
|
int iSelectedListItem, int x, int y)
|
||
|
{
|
||
|
//user has initiated opening the context menu..
|
||
|
// if the user right-clicked a non-list item, we do nothing
|
||
|
if( iSelectedListItem == -1
|
||
|
|| !allowPerSiteModify())
|
||
|
return TRUE;
|
||
|
|
||
|
SPerSiteData *psSiteData = NULL;
|
||
|
LVITEM lvi;
|
||
|
lvi.mask = LVIF_PARAM;
|
||
|
lvi.iItem = iSelectedListItem;
|
||
|
if( FALSE == ListView_GetItem( hwndListView, &lvi)
|
||
|
|| lvi.lParam == (LPARAM)NULL)
|
||
|
return FALSE;
|
||
|
psSiteData = (PSPerSiteData)(lvi.lParam);
|
||
|
|
||
|
HMENU hmenu0 = LoadMenu( MLGetHinst(), MAKEINTRESOURCE(IDD_PRIVACY_CNTXTMN_PERSITE_ADD_REM));
|
||
|
HMENU hmenu1 = GetSubMenu( hmenu0, 0);
|
||
|
if( hmenu0 == NULL || hmenu1 == NULL)
|
||
|
{
|
||
|
DestroyMenu(hmenu0);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Check the appropriate option..
|
||
|
unsigned long ulResult;
|
||
|
MENUITEMINFO menuiteminfo;
|
||
|
menuiteminfo.cbSize = sizeof(menuiteminfo);
|
||
|
menuiteminfo.fMask = MIIM_STATE;
|
||
|
menuiteminfo.fState = MFS_CHECKED;
|
||
|
if( InternetGetPerSiteCookieDecision( psSiteData->bstrCookieDomain, &ulResult) == TRUE)
|
||
|
{
|
||
|
switch( ulResult)
|
||
|
{
|
||
|
case COOKIE_STATE_ACCEPT:
|
||
|
SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_ACCEPT, FALSE, &menuiteminfo);
|
||
|
break;
|
||
|
case COOKIE_STATE_REJECT:
|
||
|
SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_REJECT, FALSE, &menuiteminfo);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SetMenuItemInfo( hmenu1, IDM_PRIVACY_PAR_DEFAULT, FALSE, &menuiteminfo);
|
||
|
}
|
||
|
|
||
|
// the target location of the context window depends on whether or not the user
|
||
|
//right-clicked the mouse or used the context menu button..
|
||
|
if( x == -1 && y == -1)
|
||
|
{ // context menu was opened through keyboard, not mouse..
|
||
|
RECT rectListRect;
|
||
|
RECT rectSelectionRect;
|
||
|
if( 0 != GetWindowRect( hwndListView, &rectListRect)
|
||
|
&& TRUE == ListView_GetItemRect( hwndListView, iSelectedListItem,
|
||
|
&rectSelectionRect, LVIR_LABEL))
|
||
|
{
|
||
|
x = rectListRect.left + (rectSelectionRect.left + rectSelectionRect.right) / 2;
|
||
|
y = rectListRect.top + (rectSelectionRect.top + rectSelectionRect.bottom) / 2;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// now we know enough to open the conext menu.
|
||
|
BOOL userSelection = TrackPopupMenu( hmenu1, TPM_RETURNCMD, x, y, 0, hDlg, NULL);
|
||
|
DestroyMenu( hmenu1);
|
||
|
DestroyMenu( hmenu0);
|
||
|
|
||
|
switch( userSelection)
|
||
|
{
|
||
|
case 0:
|
||
|
// User cancelled context menu, do nothing.
|
||
|
break;
|
||
|
case IDM_PRIVACY_PAR_ACCEPT:
|
||
|
// User chose to add site to per-site exclusion list.
|
||
|
InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_ACCEPT);
|
||
|
break;
|
||
|
case IDM_PRIVACY_PAR_REJECT:
|
||
|
// User chose to add site per-site inclusion list.
|
||
|
InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_REJECT);
|
||
|
break;
|
||
|
case IDM_PRIVACY_PAR_DEFAULT:
|
||
|
// User chose to have site use default behavior.
|
||
|
InternetSetPerSiteCookieDecision( psSiteData->bstrCookieDomain, COOKIE_STATE_UNKNOWN);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
LRESULT CALLBACK PrivacyDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
PSPrivacyDialogData pData = (PSPrivacyDialogData)GetWindowLongPtr(hDlg, GWLP_USERDATA);
|
||
|
|
||
|
switch (message)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
SetWindowLongPtr(hDlg, GWLP_USERDATA, (LONG_PTR)lParam);
|
||
|
pData = (PSPrivacyDialogData)lParam;
|
||
|
InitializePrivacyDlg( hDlg, pData);
|
||
|
PrivacyDlgBuildSiteList( pData);
|
||
|
PopulatePrivacyDlgListView(hDlg, pData, false);
|
||
|
|
||
|
if( IsOS(OS_WHISTLERORGREATER))
|
||
|
{
|
||
|
HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
|
||
|
if( hIcon != NULL)
|
||
|
SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
|
||
|
// icons loaded with LoadIcon never need to be released
|
||
|
}
|
||
|
|
||
|
PostMessage( hDlg, WM_NEXTDLGCTL,
|
||
|
(WPARAM)GetDlgItem( hDlg, IDC_SITE_LIST),
|
||
|
MAKELPARAM( TRUE, 0));
|
||
|
SetTimer( hDlg, NULL, 500, NULL);
|
||
|
return TRUE;
|
||
|
|
||
|
case WM_DESTROY:
|
||
|
PrivacyDlgDeallocSiteList( pData);
|
||
|
|
||
|
break;
|
||
|
|
||
|
case WM_TIMER:
|
||
|
{
|
||
|
ULONG oldCount = pData->countRecordsEnumerated;
|
||
|
if( pData != NULL
|
||
|
&& TRUE == PrivacyDialogExtendSiteList( pData)
|
||
|
&& oldCount < pData->countRecordsEnumerated)
|
||
|
{
|
||
|
PopulatePrivacyDlgListView( hDlg, pData, true);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case WM_COMMAND:
|
||
|
switch(LOWORD(wParam))
|
||
|
{
|
||
|
case IDOK:
|
||
|
switch( GetDlgCtrlID(GetFocus()))
|
||
|
{
|
||
|
case IDC_SITE_LIST:
|
||
|
{
|
||
|
PostMessage( hDlg, WM_COMMAND,
|
||
|
(WPARAM)IDC_PRIVACY_SHOWPOLICY,
|
||
|
(LPARAM)GetDlgItem(hDlg, IDC_PRIVACY_SHOWPOLICY));
|
||
|
return 0; // return 0 to indicate message was handled
|
||
|
}
|
||
|
case IDC_PRIVACY_HELP:
|
||
|
{
|
||
|
PostMessage( hDlg, WM_APP, (WPARAM)IDC_PRIVACY_HELP, (LPARAM)GetDlgItem(hDlg, IDC_PRIVACY_HELP));
|
||
|
return 0;
|
||
|
}
|
||
|
case IDC_PRIVACY_VIEWCOMBO:
|
||
|
{
|
||
|
PostMessage( hDlg, WM_NEXTDLGCTL,
|
||
|
(WPARAM)GetDlgItem( hDlg, IDC_SITE_LIST),
|
||
|
MAKELPARAM( TRUE, 0));
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
// fall through if IDOK was actually due to hitting IDOK with defaulting on an enter..
|
||
|
case IDCANCEL:
|
||
|
EndDialog(hDlg, LOWORD(wParam));
|
||
|
return 0;
|
||
|
case IDC_SETTINGS:
|
||
|
LaunchPrivacySettings(hDlg);
|
||
|
return 0;
|
||
|
case IDC_PRIVACY_VIEWCOMBO:
|
||
|
if( CBN_SELCHANGE == HIWORD(wParam))
|
||
|
{
|
||
|
HWND hwndComboBox = (HWND)lParam;
|
||
|
|
||
|
int iIndex = ComboBox_GetCurSel(hwndComboBox);
|
||
|
|
||
|
if( iIndex != CB_ERR)
|
||
|
{
|
||
|
pData->fReportAllSites = (iIndex == 1) ? TRUE : FALSE;
|
||
|
|
||
|
PopulatePrivacyDlgListView(hDlg, pData, true);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
break;
|
||
|
case IDC_PRIVACY_SHOWPOLICY:
|
||
|
{
|
||
|
// Catching the default return and seeing if the site list is
|
||
|
//selected was the only way to detect a return on the listview.
|
||
|
HWND hwndSiteList = GetDlgItem( hDlg, IDC_SITE_LIST);
|
||
|
int iSelectedItem = ListView_GetSelectionMark( hwndSiteList);
|
||
|
if( iSelectedItem != -1)
|
||
|
{
|
||
|
PrivacyPolicyHtmlDlg( hDlg, hwndSiteList, iSelectedItem);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case WM_APP:
|
||
|
if( LOWORD(wParam) == IDC_PRIVACY_HELP)
|
||
|
{
|
||
|
SHHtmlHelpOnDemandWrap(hDlg, TEXT("iexplore.chm > iedefault"),
|
||
|
HH_DISPLAY_TOPIC, (DWORD_PTR) L"sec_cook.htm", ML_CROSSCODEPAGE);
|
||
|
}
|
||
|
else if ( LOWORD( wParam) == IDC_SITE_LIST)
|
||
|
{
|
||
|
// We post an WM_APP to the dialog everytime the selected list view item
|
||
|
//is changed.. By handling the change in a posted message, we insure the
|
||
|
//list view's selected item is updated.
|
||
|
|
||
|
// Whenever the selected privacy report list item is changed, we have to enable/disable
|
||
|
//the show site policy button.
|
||
|
|
||
|
int iSelectedItem = ListView_GetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST));
|
||
|
|
||
|
EnableWindow( GetDlgItem( hDlg, IDC_PRIVACY_SHOWPOLICY), (-1 != iSelectedItem));
|
||
|
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
case WM_CONTEXTMENU:
|
||
|
// If the user hits the context menu button on the list view, we handle it here,
|
||
|
//because its the only place to check for that keypress.
|
||
|
// If the user clicks the right mouse button for the context menu, we handle it in
|
||
|
//WM__NOTIFY::NM_RCLICK, because the NM_RCLICK gives the correct seleceted item.
|
||
|
if( GET_X_LPARAM(lParam) == -1
|
||
|
&& (HWND)wParam == GetDlgItem( hDlg, IDC_SITE_LIST))
|
||
|
{
|
||
|
int iSelectedItem = ListView_GetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST));
|
||
|
PrivacyDlgContextMenuHandler( hDlg, (HWND)wParam,
|
||
|
iSelectedItem,
|
||
|
GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
|
||
|
}
|
||
|
break;
|
||
|
case WM_NOTIFY:
|
||
|
if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
|
||
|
&& NM_DBLCLK == ((LPNMHDR)lParam)->code
|
||
|
&& ((LPNMITEMACTIVATE)lParam)->iItem != -1)
|
||
|
{
|
||
|
PrivacyPolicyHtmlDlg( hDlg, ((LPNMHDR)lParam)->hwndFrom,
|
||
|
((LPNMITEMACTIVATE)lParam)->iItem);
|
||
|
}
|
||
|
else if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
|
||
|
&& NM_RCLICK == ((LPNMHDR)lParam)->code)
|
||
|
{
|
||
|
int iRightClickedItem = ((LPNMITEMACTIVATE)lParam)->iItem;
|
||
|
if( iRightClickedItem != -1)
|
||
|
{
|
||
|
POINT pointClick = ((LPNMITEMACTIVATE)lParam)->ptAction;
|
||
|
RECT rc;
|
||
|
if( 0 != GetWindowRect( GetDlgItem( hDlg, IDC_SITE_LIST), &rc))
|
||
|
{
|
||
|
pointClick.x += rc.left;
|
||
|
pointClick.y += rc.top;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Strange error case.. but its alright since we can place the context menu
|
||
|
//as if the context-menu button was clicked, instead of the mouse
|
||
|
pointClick.x = -1;
|
||
|
pointClick.y = -1;
|
||
|
}
|
||
|
PrivacyDlgContextMenuHandler( hDlg, GetDlgItem( hDlg, IDC_SITE_LIST),
|
||
|
iRightClickedItem,
|
||
|
pointClick.x, pointClick.y);
|
||
|
}
|
||
|
}
|
||
|
else if( IDC_SITE_LIST == ((LPNMHDR)lParam)->idFrom
|
||
|
&& LVN_ITEMCHANGED == ((LPNMHDR)lParam)->code)
|
||
|
{
|
||
|
if( ((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE)
|
||
|
{
|
||
|
// For some unknown reason the selection mark does not move with
|
||
|
//the selected item.. We have to update it.
|
||
|
if( ((LPNMLISTVIEW)lParam)->uNewState & LVIS_SELECTED)
|
||
|
{
|
||
|
ListView_SetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST),
|
||
|
((LPNMLISTVIEW)lParam)->iItem);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ListView_SetSelectionMark( GetDlgItem( hDlg, IDC_SITE_LIST),
|
||
|
-1);
|
||
|
}
|
||
|
|
||
|
// Now that the selection mark is in sync, the UI can update
|
||
|
//related items
|
||
|
PostMessage( hDlg, WM_APP, IDC_SITE_LIST, 0);
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Exported entry point to show privacy dialog
|
||
|
//
|
||
|
SHDOCAPI
|
||
|
DoPrivacyDlg(
|
||
|
HWND hwndParent, // parent window
|
||
|
LPOLESTR pszUrl, // base URL
|
||
|
IEnumPrivacyRecords *pPrivacyEnum, // enum of all affected dependant URLs
|
||
|
BOOL fReportAllSites // show all or just show bad
|
||
|
)
|
||
|
{
|
||
|
HINSTANCE hRichEditDll;
|
||
|
|
||
|
SPrivacyDialogData p; // data to send to dialogbox
|
||
|
|
||
|
if(NULL == pszUrl || NULL == pPrivacyEnum)
|
||
|
{
|
||
|
return E_INVALIDARG;
|
||
|
}
|
||
|
|
||
|
// We need to load richedit
|
||
|
hRichEditDll = LoadLibrary(TEXT("RICHED20.DLL"));
|
||
|
if (!hRichEditDll)
|
||
|
{
|
||
|
ASSERT(FALSE); //can't load richedit, complain to akabir
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
p.pszName = pszUrl;
|
||
|
p.pEnumPrivacyRecords = pPrivacyEnum;
|
||
|
p.fReportAllSites = fReportAllSites;
|
||
|
|
||
|
SHFusionDialogBoxParam(MLGetHinst(),
|
||
|
MAKEINTRESOURCE(IDD_PRIVACY_DIALOG),
|
||
|
hwndParent,
|
||
|
(DLGPROC)PrivacyDlgProc,
|
||
|
(LPARAM)&p);
|
||
|
|
||
|
FreeLibrary( hRichEditDll);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
#define DISPID_URL 10
|
||
|
#define DISPID_COOKIEURL 11
|
||
|
#define DISPID_ARD 12
|
||
|
#define DISPID_ARD_FIXED 13
|
||
|
#define DISPID_POLICYHUNT_DONE 14
|
||
|
#define DISPID_POLICYHUNT_VIEW 15
|
||
|
#define DISPID_CREATEABSOLUTEURL 16
|
||
|
|
||
|
struct SPropertyTable
|
||
|
{
|
||
|
WCHAR* pName;
|
||
|
DISPID dispid;
|
||
|
} const g_SPerSiteDataDisptable[] =
|
||
|
{
|
||
|
L"url", DISPID_URL,
|
||
|
L"cookieUrl", DISPID_COOKIEURL,
|
||
|
L"acceptRejectOrDefault", DISPID_ARD,
|
||
|
L"fixedAcceptRejectOrDefault", DISPID_ARD_FIXED,
|
||
|
L"flagPolicyHuntDone", DISPID_POLICYHUNT_DONE,
|
||
|
L"urlPolicyHuntView", DISPID_POLICYHUNT_VIEW,
|
||
|
L"CreateAbsoluteUrl", DISPID_CREATEABSOLUTEURL
|
||
|
};
|
||
|
|
||
|
const DWORD g_cSPerSiteDataDisptableSize = ARRAYSIZE( g_SPerSiteDataDisptable);
|
||
|
|
||
|
ULONG SPerSiteData::AddRef( void )
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
ULONG SPerSiteData::Release( void )
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
HRESULT SPerSiteData::QueryInterface( REFIID iid, void ** ppv)
|
||
|
{
|
||
|
if( ppv == NULL) return E_POINTER;
|
||
|
|
||
|
if (IsEqualIID(iid, IID_IUnknown)
|
||
|
|| IsEqualIID(iid, IID_IDispatch))
|
||
|
{
|
||
|
*ppv = (void *)this;
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
HRESULT SPerSiteData::GetTypeInfoCount( unsigned int FAR* pctinfo)
|
||
|
{
|
||
|
if( pctinfo == NULL)
|
||
|
return E_POINTER;
|
||
|
|
||
|
*pctinfo = 0;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT SPerSiteData::GetTypeInfo( unsigned int iTInfo,
|
||
|
LCID lcid,
|
||
|
ITypeInfo FAR* FAR* ppTInfo)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
HRESULT SPerSiteData::GetIDsOfNames( REFIID riid,
|
||
|
OLECHAR FAR* FAR* rgszNames,
|
||
|
unsigned int cNames,
|
||
|
LCID lcid,
|
||
|
DISPID FAR* rgDispId)
|
||
|
{
|
||
|
if( !IsEqualIID(riid, IID_NULL) )
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if( cNames != 1)
|
||
|
return E_INVALIDARG; // none of the objects we ID have arguments..
|
||
|
|
||
|
int i;
|
||
|
|
||
|
for( i = 0; i < g_cSPerSiteDataDisptableSize; i++)
|
||
|
{
|
||
|
if( 0 == StrCmp( rgszNames[0], g_SPerSiteDataDisptable[i].pName))
|
||
|
{
|
||
|
rgDispId[0] = g_SPerSiteDataDisptable[i].dispid;
|
||
|
return S_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
rgDispId[0] = DISPID_UNKNOWN;
|
||
|
return DISP_E_UNKNOWNNAME;
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT SPerSiteData::Invoke( DISPID dispIdMember,
|
||
|
REFIID riid,
|
||
|
LCID lcid,
|
||
|
WORD wFlags,
|
||
|
DISPPARAMS FAR* pDispParams,
|
||
|
VARIANT FAR* pVarResult,
|
||
|
EXCEPINFO FAR* pExcepInfo,
|
||
|
unsigned int FAR* puArgErr)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DWORD dw;
|
||
|
|
||
|
if( !IsEqualIID(riid, IID_NULL) )
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
if( pDispParams == NULL
|
||
|
|| pDispParams->cNamedArgs != 0)
|
||
|
return DISP_E_BADPARAMCOUNT;
|
||
|
|
||
|
switch( dispIdMember)
|
||
|
{
|
||
|
case DISPID_CREATEABSOLUTEURL:
|
||
|
if( pDispParams->cArgs != 1)
|
||
|
return DISP_E_BADPARAMCOUNT;
|
||
|
if( pVarResult == NULL)
|
||
|
return S_OK;
|
||
|
break;
|
||
|
case DISPID_COOKIEURL:
|
||
|
case DISPID_URL:
|
||
|
case DISPID_ARD:
|
||
|
case DISPID_ARD_FIXED:
|
||
|
case DISPID_POLICYHUNT_DONE:
|
||
|
case DISPID_POLICYHUNT_VIEW:
|
||
|
if( pDispParams->cArgs != 0)
|
||
|
return DISP_E_BADPARAMCOUNT;
|
||
|
if( !(wFlags & DISPATCH_PROPERTYGET))
|
||
|
return DISP_E_MEMBERNOTFOUND;
|
||
|
if( pVarResult == NULL)
|
||
|
return S_OK;
|
||
|
break;
|
||
|
default:
|
||
|
return DISP_E_MEMBERNOTFOUND;
|
||
|
}
|
||
|
|
||
|
pVarResult->vt = VT_BSTR;
|
||
|
|
||
|
switch( dispIdMember)
|
||
|
{
|
||
|
case DISPID_COOKIEURL:
|
||
|
pVarResult->bstrVal = SysAllocString(bstrCookieDomain);
|
||
|
return S_OK;
|
||
|
case DISPID_URL:
|
||
|
{
|
||
|
BSTR bstrResult = SysAllocString( bstrUrl);
|
||
|
|
||
|
if( bstrResult == NULL)
|
||
|
return ERROR_OUTOFMEMORY;
|
||
|
|
||
|
// Cut of query info from end of URL..
|
||
|
PWCHAR pCursor = bstrResult;
|
||
|
while( pCursor[0] != L'\0' && pCursor[0] != L'?')
|
||
|
pCursor++;
|
||
|
pCursor[0] = L'\0';
|
||
|
|
||
|
pVarResult->bstrVal = bstrResult;
|
||
|
return S_OK;
|
||
|
}
|
||
|
case DISPID_ARD:
|
||
|
{
|
||
|
unsigned long ulResult;
|
||
|
if( InternetGetPerSiteCookieDecision(
|
||
|
bstrCookieDomain, &ulResult)
|
||
|
== TRUE)
|
||
|
{
|
||
|
switch( ulResult)
|
||
|
{
|
||
|
case COOKIE_STATE_ACCEPT:
|
||
|
pVarResult->bstrVal = SysAllocString( L"a");
|
||
|
break;
|
||
|
case COOKIE_STATE_REJECT:
|
||
|
pVarResult->bstrVal = SysAllocString( L"r");
|
||
|
break;
|
||
|
default:
|
||
|
pVarResult->bstrVal = SysAllocString( L"d");
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pVarResult->bstrVal = SysAllocString( L"d");
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
case DISPID_ARD_FIXED:
|
||
|
{
|
||
|
pVarResult->vt = VT_BOOL;
|
||
|
pVarResult->boolVal = !allowPerSiteModify();
|
||
|
return S_OK;
|
||
|
}
|
||
|
case DISPID_POLICYHUNT_DONE:
|
||
|
{
|
||
|
// try to start the policy hunt..
|
||
|
if( pPolicyHunt == NULL)
|
||
|
{
|
||
|
CPolicyHunt* pNewHunt = new CPolicyHunt();
|
||
|
|
||
|
if( !pNewHunt
|
||
|
|| TRUE != pNewHunt->Initialize( this)
|
||
|
|| TRUE != pNewHunt->Run())
|
||
|
{
|
||
|
goto doneTryToStartPolicyHunt;
|
||
|
}
|
||
|
|
||
|
pPolicyHunt = pNewHunt;
|
||
|
pNewHunt = NULL;
|
||
|
doneTryToStartPolicyHunt:
|
||
|
if( pNewHunt != NULL)
|
||
|
delete pNewHunt;
|
||
|
}
|
||
|
pVarResult->vt = VT_BOOL;
|
||
|
pVarResult->boolVal = pPolicyHunt != NULL
|
||
|
&& pPolicyHunt->IsFinished();
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
case DISPID_POLICYHUNT_VIEW:
|
||
|
{
|
||
|
pVarResult->vt = VT_BSTR;
|
||
|
LPWSTR szResultHtm = L"policyerror.htm";
|
||
|
|
||
|
if( pPolicyHunt == NULL
|
||
|
|| FALSE == pPolicyHunt->IsFinished())
|
||
|
{
|
||
|
szResultHtm = L"policylooking.htm";
|
||
|
}
|
||
|
else if( TRUE == pPolicyHunt->GetResult( &dw))
|
||
|
{
|
||
|
switch( dw)
|
||
|
{
|
||
|
case POLICYHUNT_FOUND:
|
||
|
pVarResult->bstrVal = SysAllocString( pPolicyHunt->GetResultFilename());
|
||
|
return pVarResult->bstrVal ? S_OK : E_UNEXPECTED;
|
||
|
case POLICYHUNT_NOTFOUND:
|
||
|
szResultHtm = L"policynone.htm";
|
||
|
break;
|
||
|
case POLICYHUNT_INPROGRESS:
|
||
|
szResultHtm = L"policylooking.htm";
|
||
|
break;
|
||
|
case POLICYHUNT_FORMATERROR:
|
||
|
szResultHtm = L"policysyntaxerror.htm";
|
||
|
break;
|
||
|
case POLICYHUNT_ERROR:
|
||
|
case POLICYHUNT_CANCELLED:
|
||
|
szResultHtm = L"policyerror.htm";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
szResultHtm = L"policyerror.htm";
|
||
|
}
|
||
|
|
||
|
WCHAR szResURL[MAX_URL_STRING];
|
||
|
|
||
|
hr = MLBuildResURLWrap(L"shdoclc.dll",
|
||
|
HINST_THISDLL,
|
||
|
ML_CROSSCODEPAGE,
|
||
|
szResultHtm,
|
||
|
szResURL,
|
||
|
ARRAYSIZE(szResURL),
|
||
|
L"shdocvw.dll");
|
||
|
|
||
|
if( FAILED(hr))
|
||
|
return E_UNEXPECTED;
|
||
|
|
||
|
pVarResult->bstrVal = SysAllocString( szResURL);
|
||
|
return S_OK;
|
||
|
}
|
||
|
case DISPID_CREATEABSOLUTEURL:
|
||
|
{
|
||
|
WCHAR szBuffer[ MAX_URL_STRING];
|
||
|
DWORD dwBufferSize = ARRAYSIZE( szBuffer);
|
||
|
pVarResult->bstrVal = NULL;
|
||
|
|
||
|
if( pDispParams == NULL)
|
||
|
{
|
||
|
return E_UNEXPECTED;
|
||
|
}
|
||
|
|
||
|
if( pDispParams->rgvarg[0].vt != VT_BSTR
|
||
|
|| pDispParams->rgvarg[0].bstrVal == NULL)
|
||
|
{
|
||
|
// when pVarResult->bstrVal == NULL and we return S_OK,
|
||
|
// we are returning an empty string.
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
HRESULT hr = UrlCombine( pPolicyHunt->GetPolicyUrl(),
|
||
|
pDispParams->rgvarg[0].bstrVal,
|
||
|
szBuffer, &dwBufferSize,
|
||
|
URL_ESCAPE_UNSAFE );
|
||
|
|
||
|
if( hr != S_OK)
|
||
|
return E_UNEXPECTED;
|
||
|
|
||
|
pVarResult->bstrVal = SysAllocString( szBuffer);
|
||
|
if( pVarResult->bstrVal == NULL)
|
||
|
return E_UNEXPECTED;
|
||
|
else
|
||
|
return S_OK;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Privacy record implementation
|
||
|
//
|
||
|
HRESULT CPrivacyRecord::Init( LPTSTR * ppszUrl, LPTSTR * ppszPolicyRef, LPTSTR * ppszP3PHeader,
|
||
|
DWORD dwFlags)
|
||
|
{
|
||
|
unsigned long len = 0;
|
||
|
TCHAR * pUrl = NULL;
|
||
|
|
||
|
if (!ppszUrl || !*ppszUrl || !**ppszUrl || !ppszP3PHeader || !ppszPolicyRef )
|
||
|
return E_POINTER;
|
||
|
|
||
|
_pszUrl = *ppszUrl;
|
||
|
_pszP3PHeader = *ppszP3PHeader;
|
||
|
_pszPolicyRefUrl = *ppszPolicyRef;
|
||
|
|
||
|
// The record will own the memory from now for these
|
||
|
*ppszUrl = NULL;
|
||
|
*ppszP3PHeader = NULL;
|
||
|
*ppszPolicyRef = NULL;
|
||
|
|
||
|
_dwPrivacyFlags = dwFlags;
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
CPrivacyRecord::~CPrivacyRecord()
|
||
|
{
|
||
|
delete [] _pszUrl;
|
||
|
delete [] _pszPolicyRefUrl;
|
||
|
delete [] _pszP3PHeader;
|
||
|
}
|
||
|
|
||
|
HRESULT CPrivacyRecord::SetNext( CPrivacyRecord * pNextRec )
|
||
|
{
|
||
|
if (!pNextRec)
|
||
|
return E_POINTER;
|
||
|
|
||
|
_pNextNode = pNextRec;
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Privacy queue implementation
|
||
|
//
|
||
|
CPrivacyQueue::~CPrivacyQueue()
|
||
|
{
|
||
|
Reset();
|
||
|
}
|
||
|
|
||
|
void CPrivacyQueue::Reset()
|
||
|
{
|
||
|
while (_pHeadRec)
|
||
|
{
|
||
|
delete Dequeue();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CPrivacyQueue::Queue(CPrivacyRecord *pRecord)
|
||
|
{
|
||
|
ASSERT(pRecord);
|
||
|
|
||
|
if (!_ulSize)
|
||
|
{
|
||
|
_pHeadRec = _pTailRec = pRecord;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(_pTailRec);
|
||
|
_pTailRec->SetNext(pRecord);
|
||
|
_pTailRec = pRecord;
|
||
|
}
|
||
|
_ulSize++;
|
||
|
}
|
||
|
|
||
|
CPrivacyRecord* CPrivacyQueue::Dequeue()
|
||
|
{
|
||
|
CPrivacyRecord *headRec = NULL;
|
||
|
|
||
|
if (_ulSize)
|
||
|
{
|
||
|
ASSERT(_pHeadRec);
|
||
|
headRec = _pHeadRec;
|
||
|
_pHeadRec = headRec->GetNext();
|
||
|
--_ulSize;
|
||
|
}
|
||
|
|
||
|
return headRec;
|
||
|
}
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// One time privacy discovery dialog proc
|
||
|
//
|
||
|
////////////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
LRESULT CALLBACK PrivacyDiscoveryDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
BOOL fDontShowNextTime = FALSE;
|
||
|
WCHAR szBuffer[256];
|
||
|
|
||
|
switch (message)
|
||
|
{
|
||
|
case WM_INITDIALOG:
|
||
|
{
|
||
|
CheckDlgButton( hDlg, IDC_PRIV_DISCOVER_DONTSHOW, BST_CHECKED);
|
||
|
MLLoadStringW(IDS_PRIVACY_LEARNMOREABOUTCOOKIES, szBuffer, ARRAYSIZE(szBuffer));
|
||
|
RenderStringToEditControlW(hDlg,
|
||
|
szBuffer,
|
||
|
(WNDPROC)HyperlinkSubclass,
|
||
|
IDC_PRIVACY_HELP);
|
||
|
|
||
|
if( IsOS(OS_WHISTLERORGREATER))
|
||
|
{
|
||
|
HICON hIcon = LoadIcon(MLGetHinst(), MAKEINTRESOURCE(IDI_PRIVACY_XP));
|
||
|
if( hIcon != NULL)
|
||
|
SendDlgItemMessage(hDlg, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
|
||
|
// icons loaded with LoadIcon never need to be released
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
case WM_COMMAND:
|
||
|
switch(LOWORD(wParam))
|
||
|
{
|
||
|
case IDOK:
|
||
|
if(IsDlgButtonChecked(hDlg, IDC_PRIV_DISCOVER_DONTSHOW))
|
||
|
fDontShowNextTime = TRUE;
|
||
|
else
|
||
|
fDontShowNextTime = FALSE;
|
||
|
|
||
|
// fall through
|
||
|
case IDCANCEL:
|
||
|
|
||
|
EndDialog(hDlg, fDontShowNextTime);
|
||
|
return 0;
|
||
|
case IDC_SETTINGS:
|
||
|
LaunchPrivacySettings(hDlg);
|
||
|
return 0;
|
||
|
}
|
||
|
break;
|
||
|
case WM_APP:
|
||
|
switch( LOWORD( wParam))
|
||
|
{
|
||
|
case IDC_PRIVACY_HELP:
|
||
|
SHHtmlHelpOnDemandWrap(hDlg, TEXT("iexplore.chm > iedefault"),
|
||
|
HH_DISPLAY_TOPIC, (DWORD_PTR) L"sec_cook.htm", ML_CROSSCODEPAGE);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
// returns boolean indicating if dialog should be shown again.
|
||
|
BOOL DoPrivacyFirstTimeDialog( HWND hwndParent)
|
||
|
{
|
||
|
HINSTANCE hRichEditDll;
|
||
|
BOOL returnValue;
|
||
|
|
||
|
// We need to load richedit
|
||
|
hRichEditDll = LoadLibrary(TEXT("RICHED20.DLL"));
|
||
|
if (!hRichEditDll)
|
||
|
{
|
||
|
ASSERT(FALSE); //can't load richedit, complain to akabir
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
returnValue = (BOOL)SHFusionDialogBoxParam(MLGetHinst(),
|
||
|
MAKEINTRESOURCE(IDD_PRIV_DISCOVER),
|
||
|
hwndParent,
|
||
|
(DLGPROC)PrivacyDiscoveryDlgProc,
|
||
|
NULL);
|
||
|
|
||
|
FreeLibrary( hRichEditDll);
|
||
|
|
||
|
return returnValue;
|
||
|
}
|