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.

2784 lines
82 KiB

  1. //
  2. // COPSProfile implementation
  3. //
  4. #include "priv.h"
  5. #include "sccls.h"
  6. #include "hlframe.h"
  7. #include "mshtmdid.h"
  8. #include "wtypes.h"
  9. #include "shlwapi.h"
  10. #include "resource.h"
  11. #include "iehelpid.h"
  12. #include <mluisupp.h>
  13. // Definitions copied from WININET
  14. #define COOKIES_WARN 0 // warn with a dlg if using cookies
  15. #define COOKIES_ALLOW 1 // allow cookies without any warning
  16. #define COOKIES_DENY 2 // disable cookies completely
  17. #ifndef VARIANT_TRUE
  18. #define VARIANT_TRUE ((VARIANT_BOOL)-1) // TRUE for VARIANT_BOOL
  19. #endif
  20. #ifndef VARIANT_FALSE
  21. #define VARIANT_FALSE ((VARIANT_BOOL)0) // FALSE for VARIANT_BOOL
  22. #endif
  23. #define EMPTY_STRINGA(s) ( !s || (s)[0] == '\0' )
  24. #define EMPTY_STRINGW(s) ( !s || (s)[0] == L'\0' )
  25. #ifdef UNICODE
  26. #define EMPTY_STRING(s) EMPTY_STRINGW(s)
  27. #else
  28. #define EMPTY_STRING(s) EMPTY_STRINGA(s)
  29. #endif
  30. // Max number of characters in a friendly OPS attribute name.
  31. const int MAX_PROFILE_NAME = 128;
  32. // Constant non-localizable string definitions
  33. const TCHAR rgszP3Global[] = TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Security\\P3Global");
  34. const TCHAR rgszP3Sites[] = TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\Security\\P3Sites");
  35. const TCHAR rgszInetKey[] = TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
  36. const TCHAR rgszPathTxt[] = TEXT("Path");
  37. const TCHAR rgszDomainTxt[] = TEXT("Domain");
  38. const TCHAR rgszAllowTxt[] = TEXT("Allow");
  39. const TCHAR rgszDenyTxt[] = TEXT("Deny");
  40. const TCHAR rgszExpireTxt[] = TEXT("Expiration");
  41. const TCHAR rgszCookieTxt[] = TEXT("AllowCookies");
  42. const TCHAR rgszEnabled[] = TEXT("Enabled");
  43. const TCHAR rgszRegKey[] = TEXT("SOFTWARE\\Microsoft\\Internet Explorer\\P3\\Write");
  44. const TCHAR rgszRegTxt[] = TEXT("Registration");
  45. const TCHAR GENDER_UNSPECIFIED[] = TEXT("U");
  46. const TCHAR GENDER_FEMALE[] = TEXT("F");
  47. const TCHAR GENDER_MALE[] = TEXT("M");
  48. const WCHAR GENDER_FEMALE_W[] = L"F";
  49. const WCHAR GENDER_MALE_W[] = L"M";
  50. #ifdef _USE_PSTORE_
  51. // {647EC150-DC4A-11d0-A02C-00C0DFA9C763}
  52. EXTERN_C const GUID GUID_PStoreType = { 0x647ec150, 0xdc4a, 0x11d0, { 0xa0, 0x2c, 0x0, 0xc0, 0xdf, 0xa9, 0xc7, 0x63 } };
  53. PST_KEY s_Key = PST_KEY_CURRENT_USER;
  54. #endif // _USE_PSTORE_
  55. // Static helper functions
  56. static WCHAR* _GetNameFromAttrIndex ( int index );
  57. static INT _GetResourceIdFromAttrIndex( int index );
  58. static ULONG _GetPropTagFromAttrIndex( int index );
  59. // This table maintains the list of the suffixes for the Standard OPS attributes
  60. // The names are intentionally kept here because these should not be localized.
  61. struct _ProfileAttribute
  62. {
  63. WCHAR * pwzName;
  64. int id; // resource ID for the friendly name of the attribute.
  65. ULONG ulPropTag;
  66. };
  67. const _ProfileAttribute rgProfAttr [] =
  68. {
  69. { L"Vcard.DisplayName", IDS_OPS_COMMONNAME, PR_DISPLAY_NAME },
  70. { L"Vcard.FirstName", IDS_OPS_GIVENNAME, PR_GIVEN_NAME },
  71. { L"Vcard.LastName", IDS_OPS_LASTNAME, PR_SURNAME },
  72. { L"Vcard.MiddleName", IDS_OPS_MIDDLENAME, PR_MIDDLE_NAME },
  73. // 0, 1, 2 for Unspecified, Female, Male
  74. { L"Vcard.Gender", IDS_OPS_GENDER, PR_GENDER },
  75. { L"Vcard.Cellular", IDS_OPS_CELLULAR, PR_CELLULAR_TELEPHONE_NUMBER},
  76. { L"Vcard.Email", IDS_OPS_EMAIL, PR_EMAIL_ADDRESS },
  77. { L"Vcard.HomePage", IDS_OPS_URL, PR_PERSONAL_HOME_PAGE },
  78. { L"Vcard.Company", IDS_OPS_COMPANY, PR_COMPANY_NAME },
  79. { L"Vcard.Department", IDS_OPS_DEPARTMENT, PR_DEPARTMENT_NAME },
  80. { L"Vcard.Office", IDS_OPS_OFFICE, PR_OFFICE_LOCATION, },
  81. { L"Vcard.JobTitle", IDS_OPS_JOBTITLE, PR_TITLE },
  82. { L"Vcard.Pager", IDS_OPS_PAGER, PR_PAGER_TELEPHONE_NUMBER },
  83. { L"Vcard.Home.StreetAddress", IDS_OPS_HOME_ADDRESS, PR_HOME_ADDRESS_STREET },
  84. { L"Vcard.Home.City", IDS_OPS_HOME_CITY, PR_HOME_ADDRESS_CITY },
  85. { L"Vcard.Home.ZipCode", IDS_OPS_HOME_ZIPCODE, PR_HOME_ADDRESS_POSTAL_CODE },
  86. { L"Vcard.Home.State", IDS_OPS_HOME_STATE, PR_HOME_ADDRESS_STATE_OR_PROVINCE },
  87. { L"Vcard.Home.Country", IDS_OPS_HOME_COUNTRY, PR_HOME_ADDRESS_COUNTRY },
  88. { L"Vcard.Home.Phone", IDS_OPS_HOME_PHONE, PR_HOME_TELEPHONE_NUMBER },
  89. { L"Vcard.Home.Fax", IDS_OPS_HOME_FAX, PR_HOME_FAX_NUMBER },
  90. { L"Vcard.Business.StreetAddress", IDS_OPS_BUSINESS_ADDRESS, PR_BUSINESS_ADDRESS_STREET },
  91. { L"Vcard.Business.City", IDS_OPS_BUSINESS_CITY, PR_BUSINESS_ADDRESS_CITY },
  92. { L"Vcard.Business.Zipcode", IDS_OPS_BUSINESS_ZIPCODE, PR_BUSINESS_ADDRESS_POSTAL_CODE},
  93. { L"Vcard.Business.State", IDS_OPS_BUSINESS_STATE, PR_BUSINESS_ADDRESS_STATE_OR_PROVINCE},
  94. { L"Vcard.Business.Country", IDS_OPS_BUSINESS_COUNTRY, PR_BUSINESS_ADDRESS_COUNTRY },
  95. { L"Vcard.Business.Phone", IDS_OPS_BUSINESS_PHONE, PR_BUSINESS_TELEPHONE_NUMBER},
  96. { L"Vcard.Business.Fax", IDS_OPS_BUSINESS_FAX, PR_BUSINESS_FAX_NUMBER },
  97. { L"Vcard.Business.URL", IDS_OPS_BUSINESS_URL, PR_BUSINESS_HOME_PAGE },
  98. };
  99. // A sentinel value returned for unsuccessful searches
  100. const int INVALID_ATTRIBUTE_INDEX = 0xFFFFFFFF;
  101. // Compute the number of bytes necessary to hold a bit-vector for the
  102. // Vcard schema where each attribute is represented by one bit.
  103. const DWORD dwVcardCount = ARRAYSIZE(rgProfAttr);
  104. const DWORD dwVcardBytes = (dwVcardCount+7) / 8;
  105. const DWORD defExpireDays = 7; // Default expiration time in days
  106. const DWORD maxExpireDays = 30; // Maximum allowed expiration period
  107. // Number of 100-ns intervals per day
  108. const __int64 intervalsPerDay = (__int64) 10000000 * 3600 * 24;
  109. // Default and maximum expiration time in units of 100 nanoseconds
  110. // (This is the format used for the FILETIME structure)
  111. const __int64 defExpiration = defExpireDays * intervalsPerDay;
  112. const __int64 maxExpiration = maxExpireDays * intervalsPerDay;
  113. // Context-sensitive help IDS
  114. const DWORD aHelpIDs[] =
  115. {
  116. IDC_OPS_INFO_REQUESTED, IDH_PA_OPS_REQUEST,
  117. IDC_OPS_URL, IDH_PA_OPS_REQUEST,
  118. IDC_SITE_IDENTITY, IDH_PA_OPS_REQUEST,
  119. IDC_OPS_LIST, IDH_PA_OPS_LIST,
  120. IDC_USAGE_STRING, IDH_PA_USAGE_STRING,
  121. IDC_VIEW_CERT, IDH_PA_VIEW_CERT,
  122. IDC_EDIT_PROFILE, IDH_EDIT_PROFILE_BTN,
  123. IDC_OPS_PRIVACY, IDH_PA_CONNECTION_SECURITY,
  124. IDC_SECURITY_ICON, IDH_PA_CONNECTION_SECURITY,
  125. IDC_SECURE_CONNECTION, IDH_PA_CONNECTION_SECURITY,
  126. IDC_UNSECURE_CONNECTION, IDH_PA_CONNECTION_SECURITY,
  127. IDC_KEEP_SETTINGS, IDH_PA_ALWAYS_SHARE,
  128. 0, 0
  129. };
  130. WCHAR* _GetNameFromAttrIndex ( int index )
  131. {
  132. // Assert that the index is valid.
  133. ASSERT(index>=0 && index<ARRAYSIZE(rgProfAttr));
  134. return rgProfAttr[index].pwzName;
  135. }
  136. INT _GetResourceIdFromAttrIndex( int index )
  137. {
  138. // Assert that the index is valid.
  139. ASSERT(index>=0 && index<ARRAYSIZE(rgProfAttr));
  140. return rgProfAttr[index].id;
  141. }
  142. ULONG _GetPropTagFromAttrIndex( int index )
  143. {
  144. // Assert that the index is valid.
  145. ASSERT(index>=0 && index<ARRAYSIZE(rgProfAttr));
  146. return rgProfAttr[index].ulPropTag;
  147. }
  148. //================================================
  149. // Implementation of the OPSRequestEntry object
  150. //------------------------------------------------
  151. int CIEFrameAuto::COpsProfile::OPSRequestEntry::destWrapper(void *pEntry, void *pUnused)
  152. {
  153. OPSRequestEntry *pReqEntry = (OPSRequestEntry*) pEntry;
  154. if ( pReqEntry )
  155. {
  156. delete pReqEntry;
  157. pReqEntry = NULL;
  158. }
  159. return TRUE;
  160. }
  161. int CIEFrameAuto::COpsProfile::OPSRequestEntry::grantRequest(void *pEntry, void *pUnused)
  162. {
  163. OPSRequestEntry *pReqEntry = (OPSRequestEntry*) pEntry;
  164. pReqEntry->grantRequest();
  165. return TRUE;
  166. }
  167. void CIEFrameAuto::COpsProfile::OPSRequestEntry::grantRequest()
  168. {
  169. m_fQuery = FALSE;
  170. m_fAnswer = TRUE;
  171. }
  172. void CIEFrameAuto::COpsProfile::OPSRequestEntry::denyRequest()
  173. {
  174. m_fQuery = FALSE;
  175. m_fAnswer = FALSE;
  176. }
  177. void CIEFrameAuto::COpsProfile::OPSRequestEntry::clearValue()
  178. {
  179. SysFreeString(m_bstrValue);
  180. m_bstrValue = NULL;
  181. }
  182. CIEFrameAuto::COpsProfile::OPSRequestEntry::OPSRequestEntry()
  183. {
  184. m_fQuery = TRUE;
  185. m_fAnswer = FALSE;
  186. m_bstrValue = NULL;
  187. m_bstrName = NULL;
  188. m_bstrOldVal = NULL;
  189. }
  190. CIEFrameAuto::COpsProfile::OPSRequestEntry::~OPSRequestEntry()
  191. {
  192. SysFreeString(m_bstrName);
  193. SysFreeString(m_bstrValue);
  194. SysFreeString(m_bstrOldVal);
  195. }
  196. //================================================
  197. // Implementation of the COpsProfile object
  198. //------------------------------------------------
  199. CIEFrameAuto::COpsProfile::COpsProfile()
  200. : CAutomationStub( MIN_BROWSER_DISPID, MAX_BROWSER_DISPID, TRUE )
  201. {
  202. #ifdef NEVER
  203. m_pCert = NULL;
  204. #endif // NEVER
  205. #ifdef _USE_PSTORE_
  206. m_provID = GUID_NULL;
  207. m_pStore = NULL;
  208. m_iStoreRef = 0;
  209. #else
  210. m_bWABInit = FALSE;
  211. m_hInstWAB = NULL;
  212. m_lpAdrBook = NULL;
  213. m_lpWABObject = NULL;
  214. m_hrWAB = E_UNEXPECTED;
  215. m_SBMe.cb = 0;
  216. m_SBMe.lpb = NULL;
  217. #endif // _USE_PSTORE_
  218. m_fEnabled = FALSE;
  219. m_bstrLastURL = NULL;
  220. m_hdpaRequests = DPA_Create(0);
  221. m_hdpaChanges = DPA_Create(0);
  222. m_hP3Global = NULL;
  223. m_hP3Sites = NULL;
  224. //Begin a-thkesa Initialize . See Windows BUG:589837.
  225. VariantInit(&m_vUsage);// a-thkesa.
  226. m_vUsage.vt = VT_I4;
  227. m_vUsage.lVal = 8;
  228. //End a-thkesa
  229. }
  230. CIEFrameAuto::COpsProfile::~COpsProfile()
  231. {
  232. clearRequest();
  233. #ifdef NEVER
  234. if (m_pCert)
  235. m_pCert->Release();
  236. #endif // NEVER
  237. for (unsigned i=m_iStoreRef; i>0; i--)
  238. _ReleaseStore();
  239. #ifdef _USE_PSTORE_
  240. if (m_pStore)
  241. ATOMICRELEASE(m_pStore);
  242. #else
  243. if (m_SBMe.lpb)
  244. m_lpWABObject->FreeBuffer(m_SBMe.lpb);
  245. if (m_lpAdrBook)
  246. ATOMICRELEASE(m_lpAdrBook);
  247. if (m_lpWABObject)
  248. ATOMICRELEASE(m_lpWABObject);
  249. if (m_hInstWAB)
  250. FreeLibrary(m_hInstWAB);
  251. #endif // _USE_PSTORE_
  252. // Prevent delay-loading of OLEAUT32.DLL if not necessary
  253. if (m_bstrLastURL)
  254. SysFreeString(m_bstrLastURL);
  255. RegCloseKey(m_hP3Global);
  256. RegCloseKey(m_hP3Sites);
  257. DPA_DestroyCallback(m_hdpaRequests, OPSRequestEntry::destWrapper, NULL);
  258. m_hdpaRequests = NULL;
  259. DPA_DestroyCallback(m_hdpaChanges, OPSRequestEntry::destWrapper, NULL);
  260. m_hdpaChanges = NULL;
  261. }
  262. HRESULT CIEFrameAuto::COpsProfile::_CreateStore()
  263. {
  264. #ifdef _USE_PSTORE_
  265. if (m_iStoreRef == 0)
  266. {
  267. HRESULT hr = PStoreCreateInstance( &m_pStore,
  268. IsEqualGUID(m_provID, GUID_NULL) ? NULL : &m_provID,
  269. NULL,
  270. 0);
  271. if (SUCCEEDED(hr))
  272. m_iStoreRef++;
  273. return hr;
  274. }
  275. m_iStoreRef++;
  276. return S_OK;
  277. #else
  278. if (!m_bWABInit)
  279. {
  280. ASSERT(NULL == m_hInstWAB);
  281. ASSERT(NULL == m_lpAdrBook && NULL == m_lpWABObject);
  282. // Don't try initializing the wab again and again
  283. m_bWABInit = TRUE;
  284. {
  285. // Figure out the location of the wab dll and try opening it.
  286. TCHAR szWABDllPath[MAX_PATH];
  287. DWORD dwType = 0;
  288. ULONG cbData = sizeof(szWABDllPath);
  289. HKEY hKey = NULL;
  290. *szWABDllPath = '\0';
  291. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
  292. RegQueryValueEx( hKey, TEXT(""), NULL, &dwType, (LPBYTE) szWABDllPath, &cbData);
  293. if(hKey) RegCloseKey(hKey);
  294. if (lstrlen(szWABDllPath) != 0 )
  295. m_hInstWAB = LoadLibrary (szWABDllPath);
  296. else
  297. m_hInstWAB = NULL;
  298. }
  299. HRESULT hr;
  300. if (m_hInstWAB)
  301. {
  302. LPWABOPEN lpfnWABOpen = (LPWABOPEN) GetProcAddress(m_hInstWAB, "WABOpen");
  303. if (lpfnWABOpen)
  304. {
  305. hr = lpfnWABOpen(&m_lpAdrBook, &m_lpWABObject, NULL, 0);
  306. if (NULL == m_lpAdrBook || NULL == m_lpWABObject)
  307. hr = E_UNEXPECTED;
  308. }
  309. else
  310. {
  311. hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND); // Not the right dll anyway!!
  312. }
  313. }
  314. else
  315. {
  316. hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND);
  317. }
  318. // Good so far, call GetMe.
  319. if (!hr)
  320. {
  321. m_SBMe.cb = 0;
  322. m_SBMe.lpb = NULL;
  323. hr = m_lpWABObject->GetMe(m_lpAdrBook, WABOBJECT_ME_NOCREATE | AB_NO_DIALOG, NULL, &m_SBMe, 0);
  324. if (0 == m_SBMe.cb || NULL == m_SBMe.lpb)
  325. hr = E_UNEXPECTED;
  326. }
  327. // Remember the return code for later.
  328. m_hrWAB = hr;
  329. }
  330. if (!m_hrWAB)
  331. m_iStoreRef++;
  332. return m_hrWAB;
  333. #endif
  334. }
  335. HRESULT CIEFrameAuto::COpsProfile::_ReleaseStore()
  336. {
  337. if (m_iStoreRef > 0)
  338. m_iStoreRef--;
  339. return S_OK;
  340. }
  341. HRESULT CIEFrameAuto::COpsProfile::Init()
  342. {
  343. DWORD dwError;
  344. DWORD dwAction;
  345. dwError = RegCreateKeyEx(HKEY_CURRENT_USER,
  346. rgszP3Global,
  347. 0,
  348. NULL,
  349. REG_OPTION_NON_VOLATILE,
  350. KEY_ALL_ACCESS,
  351. NULL,
  352. &m_hP3Global,
  353. &dwAction);
  354. dwError = RegCreateKeyEx(HKEY_CURRENT_USER,
  355. rgszP3Sites,
  356. 0,
  357. NULL,
  358. REG_OPTION_NON_VOLATILE,
  359. KEY_ALL_ACCESS,
  360. NULL,
  361. &m_hP3Sites,
  362. &dwAction);
  363. m_fEnabled = _IsP3Enabled();
  364. CIEFrameAuto* pauto = IToClass(CIEFrameAuto, _profile, this);
  365. return CAutomationStub::Init( SAFECAST(this, IHTMLOpsProfile*), IID_IHTMLOpsProfile,
  366. CLSID_COpsProfile, pauto );
  367. }
  368. HRESULT CIEFrameAuto::COpsProfile::addReadRequest(BSTR bstrName, VARIANT reserved, VARIANT_BOOL *pfSuccess)
  369. {
  370. if ( pfSuccess )
  371. *pfSuccess = VARIANT_FALSE;
  372. if (!m_fEnabled)
  373. return S_FALSE;
  374. if (bstrName==NULL)
  375. return E_POINTER;
  376. BSTR bstrURL = NULL;
  377. HRESULT hr = _pAuto->get_LocationURL(&bstrURL);
  378. if (_DifferentURL())
  379. clearRequest();
  380. SysFreeString(m_bstrLastURL);
  381. m_bstrLastURL = SysAllocString(bstrURL);
  382. if (NULL == m_bstrLastURL)
  383. {
  384. return E_OUTOFMEMORY;
  385. }
  386. int index = _GetAttrIndexFromName(bstrName);
  387. if (index==INVALID_ATTRIBUTE_INDEX)
  388. return S_FALSE;
  389. // If the attribute already exists on the list, return from this function
  390. for (int i=0; i<DPA_GetPtrCount(m_hdpaRequests); i++)
  391. {
  392. OPSRequestEntry *pEntry = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests, i);
  393. if (StrCmpIW(pEntry->m_bstrName,bstrName)==0)
  394. return S_OK;
  395. }
  396. OPSRequestEntry *pNewEntry = new OPSRequestEntry;
  397. if (pNewEntry==NULL)
  398. return E_OUTOFMEMORY;
  399. pNewEntry->m_bstrName = SysAllocString(_GetNameFromAttrIndex(index));
  400. if (pNewEntry->m_bstrName==NULL)
  401. {
  402. delete pNewEntry;
  403. return E_OUTOFMEMORY;
  404. }
  405. pNewEntry->m_bstrValue = NULL;
  406. int eIns = DPA_AppendPtr(m_hdpaRequests, (void*) pNewEntry);
  407. if (eIns==-1)
  408. {
  409. delete pNewEntry;
  410. return E_OUTOFMEMORY;
  411. }
  412. if ( pfSuccess )
  413. *pfSuccess = VARIANT_TRUE;
  414. return S_OK;
  415. }
  416. HRESULT CIEFrameAuto::COpsProfile::clearRequest()
  417. {
  418. m_fEnabled = _IsP3Enabled();
  419. if (!m_fEnabled)
  420. return S_FALSE;
  421. DPA_EnumCallback(m_hdpaRequests, OPSRequestEntry::destWrapper, NULL);
  422. DPA_DeleteAllPtrs(m_hdpaRequests);
  423. return S_OK;
  424. }
  425. HRESULT CIEFrameAuto::COpsProfile::doRequest(VARIANT usage, VARIANT fname,
  426. VARIANT vaDomain, VARIANT vaPath, VARIANT vaExpire,
  427. VARIANT reserved)
  428. {
  429. m_fEnabled = _IsP3Enabled();
  430. if (!m_fEnabled)
  431. return S_FALSE;
  432. int i, k;
  433. HRESULT hr;
  434. BOOL fShowUI = FALSE;
  435. BOOL fPersistent = FALSE;
  436. BSTR bstrURL;
  437. TCHAR rgchURL[MAX_URL_STRING];
  438. TCHAR rgchDomain[INTERNET_MAX_HOST_NAME_LENGTH+1];
  439. TCHAR rgchPath[MAX_PATH+1];
  440. TCHAR rgchScheme[16];
  441. URL_COMPONENTS uc;
  442. AccessSettings acSettings;
  443. HDPA hdpaConfirm = DPA_Create(0);
  444. if (_DifferentURL())
  445. {
  446. clearRequest();
  447. return S_FALSE;
  448. }
  449. hr = _pAuto->get_LocationURL(&bstrURL);
  450. if (FAILED(hr))
  451. return S_FALSE;
  452. _StringFromBSTR(bstrURL, rgchURL, ARRAYSIZE(rgchURL));
  453. ZeroMemory(&uc, sizeof(uc));
  454. uc.dwStructSize = sizeof(URL_COMPONENTS);
  455. uc.lpszHostName = rgchDomain;
  456. uc.dwHostNameLength = ARRAYSIZE(rgchDomain);
  457. uc.lpszUrlPath = rgchPath;
  458. uc.dwUrlPathLength = ARRAYSIZE(rgchPath);
  459. uc.lpszScheme = rgchScheme;
  460. uc.dwSchemeLength = ARRAYSIZE(rgchScheme);
  461. InternetCrackUrl(rgchURL, lstrlen(rgchURL), ICU_DECODE, &uc);
  462. _GetSiteSettings(&uc, vaDomain, vaPath, vaExpire, &acSettings);
  463. hr = _CreateStore();
  464. if (FAILED(hr))
  465. return S_FALSE;
  466. if (DPA_GetPtrCount(m_hdpaRequests)==0)
  467. return S_OK;
  468. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  469. {
  470. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  471. pCurrent->clearValue();
  472. }
  473. HWND hwnd = _pAuto->_GetHWND();
  474. INT_PTR nRet = -1;
  475. // #59340 - don't need special priviliges for local machine zone anymore.
  476. if (FALSE && _IsLocalMachine())
  477. {
  478. // If page is on the local machine, all requested information will be given
  479. DPA_EnumCallback(m_hdpaRequests, OPSRequestEntry::grantRequest, NULL);
  480. nRet = TRUE;
  481. }
  482. else
  483. {
  484. // Process the request list and mark attributes according to the configuration
  485. _ApplyPreferences(&uc, m_hdpaRequests);
  486. // Go through the request list and for each attribute that was not marked as
  487. // grant/deny according to the preferences, add it to the list
  488. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  489. {
  490. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  491. if (pCurrent->m_fQuery)
  492. DPA_AppendPtr(hdpaConfirm, pCurrent);
  493. }
  494. // Determine whether there are any attributes to query
  495. fShowUI = DPA_GetPtrCount(hdpaConfirm)>0;
  496. if (!fShowUI)
  497. {
  498. nRet = TRUE;
  499. goto HandleRequest;
  500. }
  501. // If a UI is going to be shown, all attributes that were going to be
  502. // given or denied silently should also be shown
  503. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  504. {
  505. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  506. if (!pCurrent->m_fQuery &&
  507. (pCurrent->m_fAnswer || (!pCurrent->m_fAnswer && pCurrent->m_dwDecision==P3_SITELEVEL)))
  508. {
  509. DPA_AppendPtr(hdpaConfirm, pCurrent);
  510. pCurrent->m_fQuery = TRUE;
  511. }
  512. }
  513. OPSDlgInfo opsDlgInfo;
  514. opsDlgInfo.m_hdpa = hdpaConfirm;
  515. StrCpyN(opsDlgInfo.m_rgchURL, rgchURL, ARRAYSIZE(opsDlgInfo.m_rgchURL));
  516. opsDlgInfo.m_pOpsProfile = this;
  517. opsDlgInfo.m_pacSettings = &acSettings;
  518. opsDlgInfo.m_fRemember = (_GetCookieSettings()==COOKIES_ALLOW);
  519. if (fname.vt == VT_BSTR && fname.bstrVal && lstrlenW(fname.bstrVal)>0)
  520. opsDlgInfo.m_bstrFName = SysAllocString(fname.bstrVal);
  521. else
  522. opsDlgInfo.m_bstrFName = NULL;
  523. _GetUsageCode(usage, opsDlgInfo.m_rgchUsage, ARRAYSIZE(opsDlgInfo.m_rgchUsage));
  524. //Beign a-thkesa to solve Windows BUG:589837. Assigne the usage member for the next use.
  525. {
  526. m_vUsage.vt = usage.vt;
  527. m_vUsage.lVal = usage.lVal;
  528. }
  529. // End.
  530. OSVERSIONINFOA osvi;
  531. ZeroMemory(&osvi, sizeof(osvi));
  532. osvi.dwOSVersionInfoSize = sizeof(osvi);
  533. if (GetVersionExA((OSVERSIONINFOA*)&osvi) && (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId &&
  534. (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 && LOWORD(osvi.dwBuildNumber) == 2600)))
  535. {
  536. HMODULE hmod = LoadLibrary(TEXT("xpsp1res.dll"));
  537. if (hmod)
  538. {
  539. nRet = (UINT) DialogBoxParam(hmod, MAKEINTRESOURCE(IDD_OPS_CONSENT),
  540. hwnd,
  541. _OPSConsent_DlgProc,
  542. (LPARAM) &opsDlgInfo);
  543. FreeLibrary(hmod);
  544. }
  545. }
  546. if(nRet == -1)
  547. nRet = DialogBoxParam(MLGetHinst(),
  548. MAKEINTRESOURCE(IDD_OPS_CONSENT),
  549. hwnd,
  550. _OPSConsent_DlgProc,
  551. (LPARAM) &opsDlgInfo);
  552. fPersistent = opsDlgInfo.m_fRemember;
  553. }
  554. HandleRequest:
  555. if (nRet==-1)
  556. return E_FAIL;
  557. if (!nRet)
  558. {
  559. fPersistent = FALSE;
  560. goto Cleanup;
  561. }
  562. for (i=0; i<DPA_GetPtrCount(m_hdpaRequests); i++)
  563. {
  564. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,i);
  565. if (pCurrent->m_fQuery)
  566. {
  567. pCurrent->m_prefs.m_lastRequest = pCurrent->m_fAnswer ? P3_ACCEPT : P3_REJECT;
  568. _PutUserPreference(pCurrent->m_bstrName, pCurrent->m_prefs);
  569. }
  570. if (pCurrent->m_fAnswer)
  571. {
  572. hr = _GetFieldValue(pCurrent->m_bstrName, & (pCurrent->m_bstrValue));
  573. if (FAILED(hr))
  574. pCurrent->clearValue();
  575. }
  576. }
  577. if (fShowUI && fPersistent &&
  578. (uc.nScheme==INTERNET_SCHEME_HTTP || uc.nScheme==INTERNET_SCHEME_HTTPS))
  579. {
  580. _UpdateSiteSettings(&acSettings, m_hdpaRequests);
  581. }
  582. Cleanup:
  583. DPA_Destroy(hdpaConfirm);
  584. hdpaConfirm = NULL;
  585. _ReleaseStore();
  586. return S_OK;
  587. }
  588. HRESULT CIEFrameAuto::COpsProfile::getAttribute(BSTR bstrAttribName, BSTR *pbstrAttribValue)
  589. {
  590. if (!m_fEnabled)
  591. return S_FALSE;
  592. if (pbstrAttribValue==NULL || bstrAttribName==NULL)
  593. return E_POINTER;
  594. *pbstrAttribValue = NULL;
  595. //
  596. // SECURITY: Since shdocvw has no notion of frames,
  597. // we now prompt on every attempt to get attributes.
  598. // See Windows bugs 536637 & 549409 for details.
  599. //
  600. VARIANT_BOOL vbSuccess;
  601. VARIANT vError, vUsage, vName;
  602. VariantInit(&vError);
  603. VariantInit(&vUsage);
  604. VariantInit(&vName);
  605. vError.vt = VT_ERROR;
  606. vError.scode = DISP_E_PARAMNOTFOUND;
  607. //a-thkesa to solve Windows BUG:589837. Assign the usage member for the this use.
  608. //Begin comment a-thkesa
  609. //vUsage.vt = VT_I4;
  610. //vUsage.lVal = 8;
  611. //End
  612. vUsage = m_vUsage ;// a-thkesa to solve Windows BUG:589837
  613. vName.vt = VT_EMPTY;
  614. clearRequest();
  615. addReadRequest(bstrAttribName, vError, &vbSuccess);
  616. if (vbSuccess == VARIANT_FALSE)
  617. return E_FAIL;
  618. doReadRequest(vUsage, vName, vError, vError, vError, vError);
  619. for (int i=0; i<DPA_GetPtrCount(m_hdpaRequests); i++)
  620. {
  621. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,i);
  622. if (StrCmpIW(bstrAttribName,pCurrent->m_bstrName) == 0)
  623. {
  624. if (pCurrent->m_bstrValue == NULL)
  625. {
  626. *pbstrAttribValue = SysAllocString(L"");
  627. }
  628. else
  629. {
  630. *pbstrAttribValue = SysAllocString(pCurrent->m_bstrValue);
  631. }
  632. return (*pbstrAttribValue == NULL) ? E_OUTOFMEMORY : S_OK;
  633. }
  634. }
  635. return S_FALSE;
  636. }
  637. HRESULT CIEFrameAuto::COpsProfile::setAttribute(BSTR bstrAttribName, BSTR bstrAttribValue, VARIANT vaPrefs,
  638. VARIANT_BOOL *pfSuccess)
  639. {
  640. BSTR bstrStdName = NULL;
  641. HRESULT hr = S_FALSE;
  642. if (pfSuccess)
  643. *pfSuccess = VARIANT_FALSE;
  644. if (!m_fEnabled)
  645. return S_FALSE;
  646. if (bstrAttribName==NULL)
  647. return E_POINTER;
  648. // If this is a new URL, flush the change queue.
  649. if (_DifferentURL())
  650. {
  651. DPA_EnumCallback(m_hdpaChanges,OPSRequestEntry::destWrapper,NULL);
  652. DPA_DeleteAllPtrs(m_hdpaChanges);
  653. }
  654. // Load the name of the current URL into the last visited URL
  655. SysFreeString(m_bstrLastURL);
  656. _pAuto->get_LocationURL(&m_bstrLastURL);
  657. int index = _GetAttrIndexFromName(bstrAttribName);
  658. if (index==INVALID_ATTRIBUTE_INDEX)
  659. return S_FALSE;
  660. OPSRequestEntry *pNewEntry = new OPSRequestEntry;
  661. if (pNewEntry == NULL)
  662. return E_OUTOFMEMORY;
  663. pNewEntry->m_bstrName = SysAllocString(_GetNameFromAttrIndex(index));
  664. if (pNewEntry->m_bstrName==NULL)
  665. {
  666. delete pNewEntry;
  667. return E_OUTOFMEMORY;
  668. }
  669. if (bstrAttribValue != NULL)
  670. pNewEntry->m_bstrValue = SysAllocString(bstrAttribValue);
  671. else
  672. pNewEntry->m_bstrValue = SysAllocString(L"");
  673. if (pNewEntry->m_bstrValue==NULL)
  674. {
  675. delete pNewEntry;
  676. return E_OUTOFMEMORY;
  677. }
  678. for (int i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  679. {
  680. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges,i);
  681. if (StrCmpIW(pCurrent->m_bstrName, bstrAttribName) == 0)
  682. {
  683. SysFreeString(pCurrent->m_bstrValue);
  684. pCurrent->m_bstrValue = SysAllocString(bstrAttribName);
  685. if (*pfSuccess)
  686. *pfSuccess = (pCurrent->m_bstrValue!=NULL) ? VARIANT_TRUE : VARIANT_FALSE;
  687. delete pNewEntry;
  688. return S_OK;
  689. }
  690. }
  691. int eIns = DPA_AppendPtr(m_hdpaChanges, pNewEntry);
  692. if (eIns==-1)
  693. {
  694. delete pNewEntry;
  695. return E_OUTOFMEMORY;
  696. }
  697. if (pfSuccess)
  698. *pfSuccess = VARIANT_TRUE;
  699. return S_OK;
  700. }
  701. HRESULT CIEFrameAuto::COpsProfile::commitChanges(VARIANT_BOOL *pfSuccess) {
  702. if ( pfSuccess )
  703. *pfSuccess = VARIANT_FALSE;
  704. if (!m_fEnabled)
  705. return S_FALSE;
  706. HRESULT hr;
  707. HWND hwnd;
  708. int i;
  709. INT_PTR nRet;
  710. OPSDlgInfo opsDlgInfo;
  711. BSTR bstrURL = NULL;
  712. TCHAR rgchURL[MAX_URL_STRING];
  713. _pAuto->get_LocationURL(&bstrURL);
  714. _StringFromBSTR(bstrURL, rgchURL, ARRAYSIZE(rgchURL));
  715. SysFreeString(bstrURL);
  716. // Crack the URL and get the hostname
  717. TCHAR rgchHostName[INTERNET_MAX_HOST_NAME_LENGTH] = { TEXT('\0') };
  718. DWORD dwcbHostLen = ARRAYSIZE(rgchHostName);
  719. UrlGetPart(rgchURL, rgchHostName, &dwcbHostLen, URL_PART_HOSTNAME, 0);
  720. // Read the hostname for the registration page from the registry
  721. TCHAR rgchRegDomain[INTERNET_MAX_HOST_NAME_LENGTH];
  722. DWORD dwcbReg = sizeof(rgchRegDomain);
  723. HKEY hWriteKey = NULL;
  724. DWORD dwError;
  725. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, rgszRegKey, 0, KEY_READ, &hWriteKey);
  726. if (dwError==ERROR_SUCCESS)
  727. {
  728. dwError = RegQueryValueEx(hWriteKey, rgszRegTxt, NULL, NULL, (LPBYTE) rgchRegDomain, &dwcbReg);
  729. RegCloseKey(hWriteKey);
  730. }
  731. BOOL fRegDomain = (dwError==ERROR_SUCCESS && _DomainMatch(rgchHostName, rgchRegDomain));
  732. BOOL fCanWrite = _IsLocalMachine() || fRegDomain;
  733. if (!fCanWrite || _DifferentURL())
  734. goto Cleanup;
  735. hr = _CreateStore();
  736. if (hr)
  737. goto Cleanup;
  738. // Look up the old values from the store
  739. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  740. {
  741. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  742. // Default case: the attribute will be updated
  743. pCurrent->m_fAnswer = TRUE;
  744. hr = _GetFieldValue (pCurrent->m_bstrName, &(pCurrent->m_bstrOldVal));
  745. if (hr)
  746. {
  747. SysFreeString(pCurrent->m_bstrOldVal);
  748. pCurrent->m_bstrOldVal = NULL;
  749. }
  750. }
  751. // Delete nodes in the list if the new value is the same as the old one
  752. // NOTE: The loop counter will remain stationary or increment depending on whether
  753. // the current node in the list is deleted
  754. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); )
  755. {
  756. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  757. if (StrCmpW(pCurrent->m_bstrValue, pCurrent->m_bstrOldVal)==0)
  758. DPA_DeletePtr(m_hdpaChanges, i);
  759. else
  760. i++;
  761. }
  762. // If nothing has changed, then we do not need to write data back to the storage
  763. if (DPA_GetPtrCount(m_hdpaChanges)==0)
  764. goto Cleanup;
  765. // The registration domain can write profile information silently.
  766. // For all other cases, a UI will be displayed.
  767. if (!fRegDomain)
  768. {
  769. // Pop up a UI to show the items that are being changes and allow the user to
  770. // confirm the changes by selecting check-boxes for each attribute
  771. opsDlgInfo.m_hdpa = m_hdpaChanges;
  772. opsDlgInfo.m_pOpsProfile = this;
  773. hwnd = _pAuto->_GetHWND();
  774. nRet = DialogBoxParam(MLGetHinst(),
  775. MAKEINTRESOURCE(IDD_OPS_UPDATE),
  776. hwnd,
  777. _OPSUpdate_DlgProc,
  778. (LPARAM) &opsDlgInfo
  779. );
  780. // Unrecoverable error: failed to show the dialog box
  781. if (nRet==-1)
  782. return S_FALSE;
  783. // If the user clicked "CANCEL", then no changes will be performed
  784. if (nRet==0)
  785. goto Cleanup;
  786. }
  787. if ( pfSuccess )
  788. *pfSuccess = VARIANT_TRUE;
  789. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  790. {
  791. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  792. // Registration page should not overwrite existing entries
  793. if (fRegDomain && ! EMPTY_STRINGW(pCurrent->m_bstrOldVal))
  794. continue;
  795. // Update only if the user allowed in the UI
  796. // For the registration page, this condition will hold for all attributes
  797. if (pCurrent->m_fAnswer)
  798. {
  799. hr = _SetFieldValue(pCurrent->m_bstrName, pCurrent->m_bstrValue);
  800. if (hr && pfSuccess)
  801. *pfSuccess = VARIANT_FALSE;
  802. }
  803. }
  804. Cleanup:
  805. // Clear the queue that holds the changes
  806. DPA_EnumCallback(m_hdpaChanges,OPSRequestEntry::destWrapper,NULL);
  807. DPA_DeleteAllPtrs(m_hdpaChanges);
  808. return S_OK;
  809. }
  810. // *** IOpsProfileSimple members ***
  811. STDMETHODIMP CIEFrameAuto::COpsProfile::ReadProperties(long lNumProperties, const LPCWSTR szProperties[], LPWSTR szReturnValues[])
  812. {
  813. HRESULT hr=S_OK;
  814. for (int i=0; i<lNumProperties; i++)
  815. {
  816. BSTR bstrValue=NULL;
  817. LPWSTR pwszRet=NULL;
  818. if (szProperties[i])
  819. {
  820. _GetFieldValue(szProperties[i], &bstrValue);
  821. if (bstrValue)
  822. {
  823. // FEATURE change _GetFieldValue so we don't reallocate twice unnecessarily
  824. int cch = (1 + lstrlenW(bstrValue));
  825. pwszRet = (LPWSTR) CoTaskMemAlloc(sizeof(WCHAR) * cch);
  826. if (pwszRet)
  827. StrCpyNW(pwszRet, bstrValue, cch);
  828. SysFreeString(bstrValue);
  829. }
  830. else
  831. {
  832. hr = S_FALSE;
  833. }
  834. }
  835. szReturnValues[i] = pwszRet;
  836. }
  837. return hr;
  838. }
  839. STDMETHODIMP CIEFrameAuto::COpsProfile::WriteProperties(long lNumProperties, const LPCWSTR szProperties[], const LPCWSTR szValues[])
  840. {
  841. return E_NOTIMPL;
  842. }
  843. #ifdef _USE_PSTORE_
  844. HRESULT CIEFrameAuto::COpsProfile::_GetFieldValue(const OLECHAR *pszField, BSTR * pbstrValue)
  845. {
  846. GUID itemType = GUID_NULL;
  847. GUID itemSubtype = GUID_NULL;
  848. BSTR bstrName = NULL;
  849. DWORD cbData;
  850. BYTE * pbData = NULL;
  851. PST_PROMPTINFO promptInfo;
  852. HRESULT hr;
  853. BOOL fOpen = FALSE;
  854. if (pszField==NULL || pbstrValue==NULL)
  855. return E_POINTER;
  856. ZeroMemory(&promptInfo,sizeof(promptInfo));
  857. promptInfo.cbSize = sizeof(promptInfo);
  858. promptInfo.szPrompt = pszField;
  859. promptInfo.dwPromptFlags = 0;
  860. promptInfo.hwndApp = _pAuto->_GetHWND();
  861. hr = _CreateStore();
  862. if (hr)
  863. goto Cleanup;
  864. hr = _GetPStoreTypes(pszField, &itemType, &itemSubtype, &bstrName);
  865. if (hr)
  866. goto Cleanup;
  867. hr = m_pStore->ReadItem(
  868. s_Key,
  869. &itemType,
  870. &itemSubtype,
  871. bstrName,
  872. &cbData,
  873. &pbData,
  874. &promptInfo,
  875. 0);
  876. if (FAILED(hr))
  877. {
  878. *pbstrValue = SysAllocString(L"");
  879. hr = S_OK;
  880. goto Cleanup;
  881. }
  882. *pbstrValue = SysAllocString((OLECHAR *) pbData);
  883. Cleanup:
  884. _ReleaseStore();
  885. CoTaskMemFree(pbData);
  886. SysFreeString(bstrName);
  887. return hr;
  888. }
  889. HRESULT CIEFrameAuto::COpsProfile::_SetFieldValue(const OLECHAR *pszField, BSTR bstrValue)
  890. {
  891. HRESULT hr;
  892. PST_TYPEINFO typeInfo;
  893. PST_PROMPTINFO promptInfo;
  894. WCHAR * szValue = bstrValue ? bstrValue : L"";
  895. TCHAR szDisplayName[MAX_PATH];
  896. WCHAR wzDisplayName[MAX_PATH];
  897. if (pszField==NULL)
  898. return E_POINTER;
  899. MLLoadString(IDS_PROFILE_ASSISTANT, szDisplayName, ARRAYSIZE(szDisplayName));
  900. typeInfo.cbSize = sizeof(typeInfo);
  901. int cch = MultiByteToWideChar( CP_ACP, 0, szDisplayName, -1,
  902. wzDisplayName, ARRAYSIZE(wzDisplayName));
  903. ASSERT(cch != 0);
  904. typeInfo.szDisplayName = wzDisplayName;
  905. promptInfo.cbSize = sizeof(promptInfo);
  906. promptInfo.dwPromptFlags = 0;
  907. promptInfo.hwndApp = _pAuto->_GetHWND();
  908. promptInfo.szPrompt = pszField;
  909. hr = _CreateStore();
  910. if (hr)
  911. goto Cleanup;
  912. hr = m_pStore->CreateType(s_Key, &GUID_PStoreType, &typeInfo, 0);
  913. if (hr && (hr != PST_E_TYPE_EXISTS))
  914. goto Cleanup;
  915. hr = m_pStore->CreateSubtype(
  916. s_Key,
  917. &GUID_PStoreType,
  918. &GUID_NULL,
  919. &typeInfo,
  920. NULL,
  921. 0);
  922. if (hr && (hr != PST_E_TYPE_EXISTS))
  923. goto Cleanup;
  924. hr = m_pStore->WriteItem(
  925. s_Key,
  926. &GUID_PStoreType,
  927. &GUID_NULL,
  928. pszField,
  929. (lstrlenW(szValue) + 1) * sizeof(WCHAR),
  930. (BYTE *) szValue,
  931. &promptInfo,
  932. PST_CF_NONE,
  933. 0);
  934. Cleanup:
  935. _ReleaseStore();
  936. return hr;
  937. }
  938. #else // _USE_PSTORE_
  939. HRESULT CIEFrameAuto::COpsProfile::_GetFieldValue(const OLECHAR *pszField, BSTR * pbstrValue)
  940. {
  941. LPMAILUSER lpMailUser = NULL;
  942. ULONG ulPropTag;
  943. ULONG ulObjType = 0;
  944. WCHAR * pwzValue = NULL;
  945. BOOL bStoreCreated = FALSE;
  946. HRESULT hr;
  947. if (pszField==NULL || pbstrValue==NULL)
  948. return E_POINTER;
  949. hr = _CreateStore();
  950. if (hr)
  951. goto Cleanup;
  952. else
  953. bStoreCreated = TRUE;
  954. INT index;
  955. index = INVALID_ATTRIBUTE_INDEX;
  956. if (!_ValidateElemName(pszField, &index))
  957. {
  958. hr = E_INVALIDARG;
  959. goto Cleanup;
  960. }
  961. // Open the entry in the address book.
  962. hr = m_lpAdrBook->OpenEntry(m_SBMe.cb,
  963. (LPENTRYID) m_SBMe.lpb,
  964. NULL,
  965. 0,
  966. &ulObjType,
  967. (LPUNKNOWN *)&lpMailUser);
  968. if (hr)
  969. goto Cleanup;
  970. if (lpMailUser)
  971. {
  972. ulPropTag = _GetPropTagFromAttrIndex(index);
  973. SPropTagArray SPTA;
  974. SPTA.cValues = 1;
  975. SPTA.aulPropTag[0] = ulPropTag;
  976. if (PROP_TYPE(ulPropTag) == PT_TSTRING || ulPropTag == PR_GENDER)
  977. {
  978. DWORD cValues = 0;
  979. LPSPropValue lpSPropValue = NULL;
  980. hr = lpMailUser->GetProps(&SPTA, 0, &cValues, &lpSPropValue);
  981. if (!hr)
  982. {
  983. ASSERT(1 == cValues);
  984. ASSERT(NULL != lpSPropValue);
  985. int cch = 0;
  986. LPCTSTR pszPropStr = NULL;
  987. if (ulPropTag == PR_GENDER)
  988. {
  989. switch (lpSPropValue->Value.i)
  990. {
  991. case 1:
  992. pszPropStr = GENDER_FEMALE;
  993. break;
  994. case 2:
  995. pszPropStr = GENDER_MALE;
  996. break;
  997. default:
  998. pszPropStr = GENDER_UNSPECIFIED;
  999. break;
  1000. }
  1001. }
  1002. else
  1003. {
  1004. ASSERT(PROP_TYPE(lpSPropValue->ulPropTag) == PT_TSTRING);
  1005. pszPropStr = lpSPropValue->Value.LPSZ;
  1006. }
  1007. if (pszPropStr)
  1008. {
  1009. #ifdef _UNICODE
  1010. cch = lstrlen(pszPropStr) + 1;
  1011. #else
  1012. // We get the string back in ANSI convert to Unicode.
  1013. cch = MultiByteToWideChar(CP_ACP, 0, pszPropStr, -1, NULL, 0);
  1014. #endif
  1015. pwzValue = new WCHAR [cch];
  1016. if (NULL == pwzValue)
  1017. {
  1018. hr = E_OUTOFMEMORY;
  1019. }
  1020. else
  1021. {
  1022. #ifdef _UNICODE
  1023. StrCpyN(pwzValue, pszPropStr, cch);
  1024. #else
  1025. cch = MultiByteToWideChar(CP_ACP, 0, pszPropStr, -1, pwzValue, cch);
  1026. ASSERT(0 != cch);
  1027. #endif
  1028. }
  1029. }
  1030. else
  1031. {
  1032. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); // This will cause us to just return the NULL string.
  1033. }
  1034. }
  1035. m_lpWABObject->FreeBuffer(lpSPropValue);
  1036. }
  1037. else
  1038. {
  1039. // If this assert fires you are probably adding a new PR_* mapping to the OPS code.
  1040. // You will need to write code to convert the returned value to a string meaningfully.
  1041. // See the example for GENDER above.
  1042. ASSERT(FALSE);
  1043. hr = E_NOTIMPL ;
  1044. }
  1045. }
  1046. else
  1047. {
  1048. hr = E_UNEXPECTED;
  1049. }
  1050. if (hr)
  1051. {
  1052. *pbstrValue = SysAllocString(L"");
  1053. hr = (NULL != pbstrValue) ? S_OK : E_OUTOFMEMORY;
  1054. goto Cleanup;
  1055. }
  1056. *pbstrValue = SysAllocString((OLECHAR *) pwzValue);
  1057. Cleanup:
  1058. if (bStoreCreated)
  1059. _ReleaseStore();
  1060. if (lpMailUser)
  1061. lpMailUser->Release();
  1062. delete [] pwzValue;
  1063. return hr;
  1064. }
  1065. HRESULT CIEFrameAuto::COpsProfile::_SetFieldValue(const OLECHAR *pszField, BSTR bstrValue)
  1066. {
  1067. HRESULT hr;
  1068. LPMAILUSER lpMailUser = NULL;
  1069. ULONG ulPropTag;
  1070. ULONG ulObjType = 0;
  1071. BOOL bStoreCreated = FALSE;
  1072. if (pszField==NULL)
  1073. return E_POINTER;
  1074. hr = _CreateStore();
  1075. if (hr)
  1076. goto Cleanup;
  1077. else
  1078. bStoreCreated = TRUE;
  1079. INT index;
  1080. index = INVALID_ATTRIBUTE_INDEX;
  1081. if (!_ValidateElemName(pszField, &index))
  1082. {
  1083. hr = E_INVALIDARG;
  1084. goto Cleanup;
  1085. }
  1086. // Open the entry in the address book.
  1087. hr = m_lpAdrBook->OpenEntry(m_SBMe.cb,
  1088. (LPENTRYID) m_SBMe.lpb,
  1089. NULL,
  1090. MAPI_MODIFY,
  1091. &ulObjType,
  1092. (LPUNKNOWN *)&lpMailUser);
  1093. if (hr)
  1094. goto Cleanup;
  1095. if (lpMailUser)
  1096. {
  1097. ulPropTag = _GetPropTagFromAttrIndex(index);
  1098. if (PROP_TYPE(ulPropTag) == PT_TSTRING || ulPropTag == PR_GENDER)
  1099. {
  1100. // First remove the existing entry
  1101. SPropTagArray SPTA;
  1102. SPTA.cValues = 1;
  1103. SPTA.aulPropTag[0] = ulPropTag;
  1104. lpMailUser->DeleteProps(&SPTA, NULL);
  1105. SPropValue prop;
  1106. prop.ulPropTag = ulPropTag;
  1107. CHAR *pszValue = NULL;
  1108. if (ulPropTag == PR_GENDER)
  1109. {
  1110. short int i = 0; // unspecified.
  1111. if (0 == StrCmpIW(bstrValue, GENDER_FEMALE_W))
  1112. i = 1;
  1113. else if (0 == StrCmpIW(bstrValue, GENDER_MALE_W))
  1114. i = 2;
  1115. prop.Value.i = i;
  1116. }
  1117. else
  1118. {
  1119. prop.Value.LPSZ = bstrValue;
  1120. }
  1121. if (!hr)
  1122. {
  1123. hr = lpMailUser->SetProps(1, &prop, NULL);
  1124. lpMailUser->SaveChanges(0);
  1125. }
  1126. delete [] pszValue;
  1127. }
  1128. else
  1129. {
  1130. hr = E_NOTIMPL ; // FIX THIS BEFORE CHECKING IN.
  1131. }
  1132. }
  1133. else
  1134. {
  1135. hr = E_UNEXPECTED;
  1136. }
  1137. Cleanup:
  1138. if (bStoreCreated)
  1139. _ReleaseStore();
  1140. if (lpMailUser)
  1141. lpMailUser->Release();
  1142. return hr;
  1143. }
  1144. #endif // ! _USE_PSTORE_
  1145. HRESULT CIEFrameAuto::COpsProfile::_GetIDispatchExDelegate(IDispatchEx ** const delegate)
  1146. {
  1147. if( !delegate )
  1148. return E_POINTER;
  1149. *delegate = NULL; // We do not handle expandos yet
  1150. return DISP_E_MEMBERNOTFOUND;
  1151. }
  1152. HRESULT CIEFrameAuto::COpsProfile::_InternalQueryInterface(REFIID riid, void ** const ppvObjOut)
  1153. {
  1154. ASSERT( this );
  1155. ASSERT( !IsEqualIID(riid, IID_IUnknown) );
  1156. if (IsEqualIID(riid, IID_IHTMLOpsProfile))
  1157. {
  1158. *ppvObjOut = SAFECAST(this,IHTMLOpsProfile*);
  1159. }
  1160. else if (IsEqualIID(riid, IID_IOpsProfileSimple))
  1161. {
  1162. *ppvObjOut = SAFECAST(this,IOpsProfileSimple*);
  1163. }
  1164. else
  1165. {
  1166. *ppvObjOut = NULL;
  1167. return E_NOINTERFACE;
  1168. }
  1169. AddRef( );
  1170. return S_OK;
  1171. }
  1172. #ifdef _USE_PSTORE_
  1173. HRESULT
  1174. CIEFrameAuto::COpsProfile::_GetPStoreTypes(
  1175. BSTR bstrField,
  1176. GUID * pguidType,
  1177. GUID * pguidSub,
  1178. BSTR * pbstrName)
  1179. {
  1180. *pguidType = GUID_PStoreType;
  1181. *pguidSub = GUID_NULL;
  1182. *pbstrName = SysAllocString(bstrField);
  1183. return S_OK;
  1184. }
  1185. #endif // _USE_PSTORE_
  1186. // Functions to display the consent dialog.
  1187. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_OnInitDlg(HWND hDlg)
  1188. {
  1189. const int cbMaxStringDisplay = 24;
  1190. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1191. COpsProfile *pProfile = lpOpsDlgInfo->m_pOpsProfile;
  1192. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1193. return FALSE;
  1194. // Get the hostname
  1195. TCHAR rgSiteName[MAX_URL_STRING];
  1196. DWORD dwchOut = ARRAYSIZE(rgSiteName);
  1197. HRESULT hr;
  1198. hr = UrlGetPart(lpOpsDlgInfo->m_rgchURL, rgSiteName, &dwchOut, URL_PART_HOSTNAME, 0);
  1199. if (FAILED(hr) || dwchOut == 0 )
  1200. StrCpyN(rgSiteName, lpOpsDlgInfo->m_rgchURL, ARRAYSIZE(rgSiteName));
  1201. // Display site identity information
  1202. HWND hwndReq = GetDlgItem(hDlg, IDC_SITE_IDENTITY);
  1203. TCHAR rgRequestInfo[MAX_URL_STRING];
  1204. TCHAR rgFormat[MAX_URL_STRING];
  1205. BSTR bstrFName = lpOpsDlgInfo->m_bstrFName;
  1206. TCHAR rgFName[MAX_URL_STRING];
  1207. MLLoadString(IDS_DEFAULT_FNAME, rgFName, ARRAYSIZE(rgFName));
  1208. MLLoadString(IDS_OPS_REQUEST, rgFormat, ARRAYSIZE(rgFormat));
  1209. wnsprintf(rgRequestInfo, ARRAYSIZE(rgRequestInfo), rgFormat, rgFName);
  1210. SetWindowText(hwndReq, rgRequestInfo);
  1211. // Display the access settings
  1212. TCHAR rgchAccessPath[MAX_URL_STRING];
  1213. HWND hwndURL = GetDlgItem(hDlg, IDC_OPS_URL);
  1214. _FormatSiteSettings(lpOpsDlgInfo->m_pacSettings, rgchAccessPath, ARRAYSIZE(rgchAccessPath));
  1215. SetWindowText(hwndURL, rgchAccessPath);
  1216. // Display the usage information
  1217. HWND hwndUsage = GetDlgItem(hDlg, IDC_USAGE_STRING);
  1218. SetWindowText(hwndUsage, lpOpsDlgInfo->m_rgchUsage);
  1219. // Detect SSL and inform user in the lower pane
  1220. BOOL fUsingSSL = pProfile->_IsUsingSSL();
  1221. if (fUsingSSL)
  1222. {
  1223. // If the connection is SSL, the default is to remember the settings
  1224. lpOpsDlgInfo->m_fRemember = TRUE;
  1225. // Hide the unsecure connection text.
  1226. HWND hwndStatic = GetDlgItem(hDlg, IDC_UNSECURE_CONNECTION);
  1227. ASSERT(hwndStatic != NULL);
  1228. ShowWindow(hwndStatic, SW_HIDE);
  1229. HICON hicon = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_LOCK));
  1230. if (hicon != NULL)
  1231. {
  1232. HICON hiconOld = (HICON)SendDlgItemMessage(hDlg, IDC_SECURITY_ICON, STM_SETICON,
  1233. (WPARAM)hicon, 0);
  1234. if (hiconOld)
  1235. {
  1236. DestroyIcon(hiconOld);
  1237. }
  1238. }
  1239. }
  1240. else
  1241. {
  1242. // Hide the view certificate button and the secure connection text.
  1243. HWND hwndViewCert = GetDlgItem(hDlg, IDC_VIEW_CERT);
  1244. ASSERT(hwndViewCert != NULL);
  1245. ShowWindow(hwndViewCert, SW_HIDE);
  1246. HWND hwndStatic = GetDlgItem(hDlg, IDC_SECURE_CONNECTION);
  1247. ASSERT(hwndStatic != NULL);
  1248. ShowWindow(hwndStatic, SW_HIDE);
  1249. }
  1250. // Hide the Edit Profile button if we are using the PStore.
  1251. #ifdef _USE_PSTORE
  1252. HWND hwndEditProf = GetDlgItem(hDlg, IDC_EDIT_PROFILE);
  1253. ASSERT(hwndEditProf != NULL);
  1254. ShowWindow(hwndEditProf, SW_HIDE);
  1255. #endif
  1256. Button_SetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS), lpOpsDlgInfo->m_fRemember);
  1257. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1258. ASSERT(hwndLV);
  1259. // Initialize the list view control
  1260. ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_CHECKBOXES);
  1261. // Setup the columns for the list view control.
  1262. LV_COLUMN lvc = { LVCF_FMT , LVCFMT_LEFT };
  1263. ListView_InsertColumn(hwndLV, 0, &lvc);
  1264. ListView_InsertColumn(hwndLV, 1, &lvc);
  1265. // Add elements to the list view.
  1266. _OPSConsent_ShowRequestedItems(hDlg);
  1267. // show the items.
  1268. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1269. UpdateWindow(hwndLV);
  1270. return TRUE;
  1271. }
  1272. BOOL
  1273. CIEFrameAuto::COpsProfile::_OPSConsent_ShowRequestedItems(HWND hDlg)
  1274. {
  1275. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1276. COpsProfile *pProfile = lpOpsDlgInfo->m_pOpsProfile;
  1277. HDPA hdpaList = lpOpsDlgInfo->m_hdpa;
  1278. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1279. ASSERT(hwndLV);
  1280. BOOL fAllBlank = TRUE;
  1281. TCHAR szName[MAX_PROFILE_NAME];
  1282. // Initialize the common parts of the LVI
  1283. LV_ITEM lvi = { 0 };
  1284. for (int i=DPA_GetPtrCount(hdpaList)-1; i>=0; i--)
  1285. {
  1286. OPSRequestEntry * pOpsEntry = (OPSRequestEntry*) DPA_FastGetPtr(hdpaList,i);
  1287. MLLoadString(_GetResourceIdFromAttrName(pOpsEntry->m_bstrName), szName, MAX_PATH);
  1288. BSTR bstrValue = NULL;
  1289. TCHAR rgchValue[1024];
  1290. pProfile->_GetFieldValue(pOpsEntry->m_bstrName, &bstrValue);
  1291. _StringFromBSTR(bstrValue, rgchValue, ARRAYSIZE(rgchValue));
  1292. fAllBlank = fAllBlank && EMPTY_STRING(rgchValue);
  1293. TCHAR *pchNewLine = StrPBrk(rgchValue, TEXT("\r\n"));
  1294. if (pchNewLine)
  1295. *pchNewLine = '\0';
  1296. if (lstrlen(rgchValue)==0)
  1297. {
  1298. MLLoadString(IDS_OPS_BLANK, rgchValue, ARRAYSIZE(rgchValue));
  1299. }
  1300. SysFreeString(bstrValue);
  1301. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  1302. lvi.iItem = 0;
  1303. lvi.iSubItem = 0;
  1304. lvi.pszText = szName;
  1305. lvi.cchTextMax = MAX_PROFILE_NAME;
  1306. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1307. lvi.state = pOpsEntry->m_fAnswer ? 0x00002000 : 0x00001000;
  1308. lvi.lParam = (LPARAM)pOpsEntry;
  1309. int iItem = ListView_InsertItem(hwndLV, &lvi);
  1310. lvi.mask = LVIF_TEXT;
  1311. lvi.iItem = iItem;
  1312. lvi.iSubItem = 1;
  1313. lvi.pszText = rgchValue;
  1314. ListView_SetItem(hwndLV, &lvi);
  1315. // APPCOMPAT: There is a problem with the listview implementation because of which
  1316. // the check box is not displayed even though lvi.state is set correctly.
  1317. // We have to find the item and set it again.
  1318. ListView_SetItemState(hwndLV, iItem, pOpsEntry->m_fAnswer ? 0x00002000 : 0x00001000, LVIS_STATEIMAGEMASK);
  1319. }
  1320. lpOpsDlgInfo->m_fAllBlank = fAllBlank;
  1321. // Autosize the columns
  1322. ListView_SetColumnWidth(hwndLV, 0, LVSCW_AUTOSIZE);
  1323. ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE);
  1324. return TRUE;
  1325. }
  1326. BOOL CIEFrameAuto::COpsProfile::_OPSDlg_OnClose(HWND hDlg)
  1327. {
  1328. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1329. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1330. int nItems = ListView_GetItemCount(hwndLV);
  1331. LV_ITEM lvi = {0};
  1332. lvi.mask = LVIF_PARAM ;
  1333. for (int i = 0; i < nItems ; i++ )
  1334. {
  1335. lvi.iItem = i;
  1336. lvi.lParam = 0;
  1337. ListView_GetItem(hwndLV, &lvi);
  1338. ASSERT(lvi.lParam != NULL)
  1339. if (lvi.lParam)
  1340. {
  1341. OPSRequestEntry * pOpsEntry = (OPSRequestEntry *)lvi.lParam;
  1342. pOpsEntry->m_fAnswer = ListView_GetCheckState(hwndLV, i);
  1343. }
  1344. }
  1345. lpOpsDlgInfo->m_fRemember = Button_GetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS));
  1346. return TRUE;
  1347. }
  1348. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_EditProfile(HWND hDlg)
  1349. {
  1350. #ifdef _USE_PSTORE
  1351. return FALSE;
  1352. #else
  1353. HRESULT hr;
  1354. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1355. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1356. return FALSE;
  1357. CIEFrameAuto::COpsProfile * pOpsProfile = lpOpsDlgInfo->m_pOpsProfile;
  1358. if (pOpsProfile == NULL || pOpsProfile->m_lpAdrBook == NULL)
  1359. {
  1360. ASSERT(FALSE);
  1361. return FALSE;
  1362. }
  1363. if (pOpsProfile->m_SBMe.cb == 0)
  1364. return FALSE;
  1365. LPSBinary lpSB = &(pOpsProfile->m_SBMe);
  1366. // Display the WAB dialog for the me entry.
  1367. hr = pOpsProfile->m_lpAdrBook->Details( (LPULONG) &hDlg,
  1368. NULL,
  1369. NULL,
  1370. lpSB->cb,
  1371. (LPENTRYID)lpSB->lpb,
  1372. NULL,
  1373. NULL,
  1374. NULL,
  1375. 0);
  1376. return (hr) ? FALSE : TRUE;
  1377. #endif
  1378. }
  1379. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_OnCommand(HWND hDlg, UINT id, UINT nCmd)
  1380. {
  1381. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1382. switch (id)
  1383. {
  1384. case IDOK:
  1385. if (lpOpsDlgInfo->m_fAllBlank)
  1386. {
  1387. // The user has agreed to share information but all the entries in the
  1388. // profile are blank. This is probably due to user oversight, since the
  1389. // easier way to achieve the same effect would be to select "DENY"
  1390. TCHAR rgchHeading[256];
  1391. MLLoadShellLangString(IDS_PROFILE_ASSISTANT, rgchHeading, ARRAYSIZE(rgchHeading));
  1392. TCHAR rgchConfirm[1024];
  1393. MLLoadShellLangString(IDS_OPS_NO_INFORMATION, rgchConfirm, ARRAYSIZE(rgchConfirm));
  1394. ULONG_PTR uCookie = 0;
  1395. SHActivateContext(&uCookie);
  1396. DWORD msgRet = MessageBox(hDlg, rgchConfirm, rgchHeading, MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING);
  1397. if (uCookie)
  1398. {
  1399. SHDeactivateContext(uCookie);
  1400. }
  1401. if (msgRet==IDYES)
  1402. goto FallThrough;
  1403. }
  1404. if (! Button_GetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS)) &&
  1405. (_GetCookieSettings()==COOKIES_ALLOW))
  1406. {
  1407. // The user wants to share information for one time only but cookies
  1408. // are enabled, allowing sites to store profile information in a cookie
  1409. DWORD dwConfirm = 0;
  1410. TCHAR rgchHeading[256];
  1411. TCHAR rgchConfirm[1024];
  1412. AccessSettings *pac = lpOpsDlgInfo->m_pacSettings;
  1413. MLLoadShellLangString(IDS_PROFILE_ASSISTANT, rgchHeading, ARRAYSIZE(rgchHeading));
  1414. MLLoadShellLangString(IDS_OPS_CONFIRM, rgchConfirm, ARRAYSIZE(rgchConfirm));
  1415. ULONG_PTR uCookie = 0;
  1416. SHActivateContext(&uCookie);
  1417. dwConfirm = MessageBox(hDlg, rgchConfirm, rgchHeading, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2);
  1418. if (uCookie)
  1419. {
  1420. SHDeactivateContext(uCookie);
  1421. }
  1422. if (dwConfirm!=IDOK)
  1423. break;
  1424. }
  1425. _OPSDlg_OnClose(hDlg);
  1426. EndDialog(hDlg, TRUE);
  1427. break;
  1428. FallThrough:
  1429. case IDC_EDIT_PROFILE:
  1430. {
  1431. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1432. ListView_DeleteAllItems(hwndLV);
  1433. _OPSConsent_EditProfile(hDlg);
  1434. _OPSConsent_ShowRequestedItems(hDlg);
  1435. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1436. UpdateWindow(hwndLV);
  1437. break;
  1438. }
  1439. case IDCANCEL:
  1440. EndDialog(hDlg, FALSE);
  1441. break;
  1442. case IDC_VIEW_CERT:
  1443. _OPSConsent_ViewCertificate(hDlg);
  1444. break;
  1445. default:
  1446. return FALSE;
  1447. }
  1448. return TRUE;
  1449. }
  1450. BOOL
  1451. CIEFrameAuto::COpsProfile::_OPSConsent_ViewCertificate(HWND hDlg)
  1452. {
  1453. OPSDlgInfo *pDlgInfo = (OPSDlgInfo*) GetWindowLongPtr(hDlg, DWLP_USER);
  1454. InternetShowSecurityInfoByURL(pDlgInfo->m_rgchURL, hDlg);
  1455. return TRUE;
  1456. }
  1457. INT_PTR CIEFrameAuto::COpsProfile::_OPSConsent_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1458. {
  1459. switch (uMsg)
  1460. {
  1461. case WM_INITDIALOG:
  1462. ASSERT(NULL != lParam);
  1463. SetWindowLongPtr(hDlg, DWLP_USER, lParam); // save the list.
  1464. return _OPSConsent_OnInitDlg(hDlg);
  1465. case WM_COMMAND:
  1466. return _OPSConsent_OnCommand(hDlg, LOWORD(wParam), HIWORD(wParam));
  1467. case WM_HELP:
  1468. SHWinHelpOnDemandWrap((HWND) ((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile,
  1469. HELP_WM_HELP, (DWORD_PTR)(LPTSTR) aHelpIDs);
  1470. break;
  1471. case WM_CONTEXTMENU:
  1472. SHWinHelpOnDemandWrap((HWND) wParam, c_szHelpFile, HELP_CONTEXTMENU,
  1473. (DWORD_PTR)(LPTSTR) aHelpIDs);
  1474. break;
  1475. case WM_DESTROY:
  1476. break;
  1477. }
  1478. return FALSE;
  1479. }
  1480. // Update dialog functions.
  1481. BOOL CIEFrameAuto::COpsProfile::_OPSUpdate_OnInitDlg(HWND hDlg)
  1482. {
  1483. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1484. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1485. return FALSE;
  1486. HDPA hdpaList = lpOpsDlgInfo->m_hdpa;
  1487. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1488. ASSERT(hwndLV);
  1489. // Add elements to the list view.
  1490. ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_CHECKBOXES);
  1491. // Initialize the common parts of the LVI
  1492. TCHAR szName[MAX_PROFILE_NAME];
  1493. LV_ITEM lvi = { 0 };
  1494. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  1495. lvi.iItem = 0;
  1496. lvi.pszText = szName;
  1497. lvi.cchTextMax = MAX_PROFILE_NAME;
  1498. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1499. LV_FINDINFO lvfi = { 0 };
  1500. lvfi.flags = LVFI_STRING;
  1501. lvfi.psz = szName;
  1502. for (int i=0; i<DPA_GetPtrCount(hdpaList); i++)
  1503. {
  1504. OPSRequestEntry * pOpsEntry = (OPSRequestEntry*) DPA_FastGetPtr(hdpaList,i);
  1505. MLLoadString(_GetResourceIdFromAttrName(pOpsEntry->m_bstrName), szName, MAX_PATH);
  1506. pOpsEntry->m_fAnswer = TRUE;
  1507. lvi.state = 0x00002000;
  1508. lvi.lParam = (LPARAM)pOpsEntry;
  1509. ListView_InsertItem(hwndLV, &lvi);
  1510. // APPCOMPAT: There is a problem with the listview implementation because of which
  1511. // the check box is not displayed even though lvi.state is set correctly.
  1512. // We have to find the item and set it again.
  1513. ListView_SetItemState(hwndLV, ListView_FindItem(hwndLV, -1, &lvfi), 0x00002000, LVIS_STATEIMAGEMASK);
  1514. }
  1515. // show the items.
  1516. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1517. UpdateWindow(hwndLV);
  1518. return TRUE;
  1519. }
  1520. BOOL CIEFrameAuto::COpsProfile::_OPSUpdate_OnCommand(HWND hDlg, UINT id, UINT nCmd)
  1521. {
  1522. switch (id)
  1523. {
  1524. case IDOK:
  1525. _OPSDlg_OnClose(hDlg);
  1526. EndDialog(hDlg, TRUE);
  1527. break;
  1528. case IDCANCEL:
  1529. EndDialog(hDlg, FALSE);
  1530. break;
  1531. default:
  1532. return FALSE;
  1533. }
  1534. return TRUE;
  1535. }
  1536. INT_PTR CIEFrameAuto::COpsProfile::_OPSUpdate_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1537. {
  1538. switch (uMsg)
  1539. {
  1540. case WM_INITDIALOG:
  1541. ASSERT(NULL != lParam);
  1542. SetWindowLongPtr(hDlg, DWLP_USER, lParam); // save the list.
  1543. return _OPSUpdate_OnInitDlg(hDlg);
  1544. case WM_COMMAND:
  1545. return _OPSUpdate_OnCommand(hDlg, LOWORD(wParam), HIWORD(wParam));
  1546. case WM_HELP:
  1547. break;
  1548. case WM_CONTEXTMENU:
  1549. break;
  1550. case WM_DESTROY:
  1551. break;
  1552. }
  1553. return FALSE;
  1554. }
  1555. BOOL
  1556. CIEFrameAuto::COpsProfile ::_ValidateElemName(LPCWSTR szIn, INT *pIndex /* = NULL */)
  1557. {
  1558. int index = _GetAttrIndexFromName(szIn);
  1559. if ( INVALID_ATTRIBUTE_INDEX != index )
  1560. {
  1561. if (pIndex)
  1562. *pIndex = index;
  1563. return TRUE;
  1564. }
  1565. return FALSE;
  1566. }
  1567. INT CIEFrameAuto::COpsProfile::_GetAttrIndexFromName (LPCWSTR pwzName )
  1568. {
  1569. INT index = INVALID_ATTRIBUTE_INDEX;
  1570. if ( pwzName != NULL )
  1571. {
  1572. for ( int i = 0 ; i < ARRAYSIZE(rgProfAttr) ; i++ )
  1573. {
  1574. if (0 == StrCmpIW(rgProfAttr[i].pwzName, pwzName ))
  1575. {
  1576. index = i;
  1577. break;
  1578. }
  1579. }
  1580. }
  1581. return index;
  1582. }
  1583. INT CIEFrameAuto::COpsProfile::_GetResourceIdFromAttrName( WCHAR * pwzName)
  1584. {
  1585. return _GetResourceIdFromAttrIndex(_GetAttrIndexFromName(pwzName));
  1586. }
  1587. BOOL
  1588. CIEFrameAuto::COpsProfile::_IsLocalMachine() {
  1589. IInternetSecurityManager *pIScManager = NULL;
  1590. BSTR bstrURL;
  1591. HRESULT hr;
  1592. BOOL fLocal = FALSE;
  1593. DWORD dwZone;
  1594. hr = _pAuto->get_LocationURL(&bstrURL);
  1595. if ( FAILED(hr) )
  1596. goto Cleanup;
  1597. hr = CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_INPROC_SERVER, IID_IInternetSecurityManager, (void **)&pIScManager);
  1598. if ( FAILED(hr) )
  1599. goto Cleanup;
  1600. hr = pIScManager->MapUrlToZone(bstrURL, &dwZone, 0);
  1601. if ( FAILED(hr) )
  1602. goto Cleanup;
  1603. fLocal = (dwZone == URLZONE_LOCAL_MACHINE);
  1604. Cleanup:
  1605. SAFERELEASE(pIScManager);
  1606. SysFreeString(bstrURL);
  1607. return fLocal;
  1608. }
  1609. HRESULT
  1610. CIEFrameAuto::COpsProfile::_GetUserPreference(BSTR bstrName, P3UserPref *pUsrPref) {
  1611. TCHAR rgszName[MAX_PROFILE_NAME];
  1612. DWORD dwType;
  1613. DWORD dwPrefSize;
  1614. DWORD dwError;
  1615. _StringFromBSTR(bstrName, rgszName, ARRAYSIZE(rgszName));
  1616. dwPrefSize = sizeof(struct P3UserPref);
  1617. dwError = RegQueryValueEx(m_hP3Global, rgszName, 0, &dwType,
  1618. (LPBYTE) pUsrPref, &dwPrefSize);
  1619. if (dwError == ERROR_MORE_DATA)
  1620. {
  1621. BYTE *pBuffer;
  1622. pBuffer = new BYTE [dwPrefSize];
  1623. if (pBuffer == NULL)
  1624. {
  1625. return E_OUTOFMEMORY;
  1626. }
  1627. dwError = RegQueryValueEx(m_hP3Global, rgszName, 0, &dwType, pBuffer, &dwPrefSize);
  1628. memcpy(pUsrPref, pBuffer, sizeof(struct P3UserPref));
  1629. delete [] pBuffer;
  1630. }
  1631. // If a preference for this attribute is not found, create a default one and
  1632. // write it back to persistent storage
  1633. if (dwError != ERROR_SUCCESS)
  1634. {
  1635. P3UserPref defPrefs;
  1636. defPrefs.m_access = P3_QUERY;
  1637. defPrefs.m_lastRequest = P3_ACCEPT;
  1638. _PutUserPreference(bstrName, defPrefs);
  1639. *pUsrPref = defPrefs;
  1640. }
  1641. return S_OK;
  1642. }
  1643. HRESULT
  1644. CIEFrameAuto::COpsProfile::_PutUserPreference(BSTR bstrName, P3UserPref usrPref) {
  1645. TCHAR rgszName[MAX_PROFILE_NAME];
  1646. DWORD dwError;
  1647. _StringFromBSTR(bstrName, rgszName, ARRAYSIZE(rgszName));
  1648. dwError = RegSetValueEx(m_hP3Global, rgszName, 0, REG_BINARY,
  1649. (LPBYTE) &usrPref,
  1650. sizeof(struct P3UserPref));
  1651. return HRESULT_FROM_WIN32(dwError);
  1652. }
  1653. BOOL
  1654. CIEFrameAuto::COpsProfile::_IsUsingSSL()
  1655. {
  1656. BOOL fSecure = FALSE;
  1657. BSTR bstrUrl;
  1658. TCHAR rgchUrl[MAX_URL_STRING+1];
  1659. _pAuto->get_LocationURL(&bstrUrl);
  1660. _StringFromBSTR(bstrUrl, rgchUrl, ARRAYSIZE(rgchUrl));
  1661. SysFreeString(bstrUrl);
  1662. fSecure = GetUrlScheme(rgchUrl)==URL_SCHEME_HTTPS;
  1663. return fSecure;
  1664. }
  1665. HRESULT
  1666. CIEFrameAuto::COpsProfile::_ApplyPreferences(URL_COMPONENTS *pucURL, HDPA hdpaReqList)
  1667. {
  1668. for (int k=0; k<DPA_GetPtrCount(hdpaReqList); k++)
  1669. {
  1670. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,k);
  1671. pCurrent->m_fQuery = TRUE;
  1672. pCurrent->m_fAnswer = FALSE;
  1673. pCurrent->m_dwDecision = P3_NONE;
  1674. }
  1675. _ApplySiteSettings(pucURL, hdpaReqList);
  1676. _ApplyGlobalSettings(hdpaReqList);
  1677. return S_OK;
  1678. }
  1679. HRESULT
  1680. CIEFrameAuto::COpsProfile::_ApplyGlobalSettings(HDPA hdpaReqList)
  1681. {
  1682. for (int k=0; k<DPA_GetPtrCount(hdpaReqList); k++)
  1683. {
  1684. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,k);
  1685. P3UserPref userInfo;
  1686. _GetUserPreference(pCurrent->m_bstrName, &userInfo);
  1687. switch (userInfo.m_access)
  1688. {
  1689. case P3_GRANT: if (pCurrent->m_fQuery)
  1690. {
  1691. pCurrent->grantRequest();
  1692. pCurrent->m_dwDecision = P3_GLOBAL;
  1693. }
  1694. break;
  1695. case P3_DENY: pCurrent->denyRequest();
  1696. pCurrent->m_dwDecision = P3_GLOBAL;
  1697. break;
  1698. case P3_REQSSL: // This resolves to P3_QUERY at the moment
  1699. case P3_QUERY: if (pCurrent->m_fQuery)
  1700. pCurrent->m_fAnswer = (userInfo.m_lastRequest == P3_ACCEPT);
  1701. break;
  1702. default: ;
  1703. }
  1704. }
  1705. return S_OK;
  1706. }
  1707. HRESULT
  1708. CIEFrameAuto::COpsProfile::_ApplySiteSettings(URL_COMPONENTS *pucURL, HDPA hdpaReqList)
  1709. {
  1710. if (pucURL->nScheme!=INTERNET_SCHEME_HTTP && pucURL->nScheme!=INTERNET_SCHEME_HTTPS)
  1711. return S_OK;
  1712. TCHAR *pszSubDomain = pucURL->lpszHostName;
  1713. // For a given hostname such as "www.foo.bar.com", this loop will iterate over all possible
  1714. // domains such as "www.foo.bar.com", ".foo.bar.com" and ".bar.com" but NOT ".com"
  1715. while (pszSubDomain!=NULL && _LegalDomain(pucURL->lpszHostName, pszSubDomain))
  1716. {
  1717. HKEY hkey = NULL;
  1718. if (ERROR_SUCCESS == RegOpenKeyEx(m_hP3Sites, pszSubDomain, 0, KEY_ALL_ACCESS, &hkey))
  1719. {
  1720. _ApplyDomainSettings(pucURL, hkey, hdpaReqList);
  1721. RegCloseKey(hkey);
  1722. }
  1723. pszSubDomain = StrChr(pszSubDomain+1, TEXT('.')); // Find the next embedded dot
  1724. }
  1725. return S_OK;
  1726. }
  1727. HRESULT
  1728. CIEFrameAuto::COpsProfile::_ApplyDomainSettings(URL_COMPONENTS *pucComp, HKEY hkey, HDPA hdpaReqList)
  1729. {
  1730. DWORD dwError;
  1731. DWORD dwIndex = 0;
  1732. TCHAR rgchName[MAX_PATH];
  1733. int iReqCount = DPA_GetPtrCount(hdpaReqList);
  1734. DWORD *pdwLastApplied = new DWORD[iReqCount];
  1735. if (pdwLastApplied == NULL)
  1736. {
  1737. return E_OUTOFMEMORY;
  1738. }
  1739. for (int i=0; i<iReqCount; i++)
  1740. pdwLastApplied[i] = 0;
  1741. do
  1742. {
  1743. DWORD dwcbVal = ARRAYSIZE(rgchName);
  1744. dwError = RegEnumKeyEx(hkey, dwIndex, rgchName, &dwcbVal, NULL, NULL, NULL, NULL);
  1745. if (dwError==ERROR_SUCCESS)
  1746. {
  1747. HKEY hPathKey;
  1748. AccessSettings ac;
  1749. dwError = RegOpenKeyEx(hkey, rgchName, 0, KEY_READ, &hPathKey);
  1750. _ReadSettingsFromRegistry(hPathKey, &ac);
  1751. _ApplySettings(&ac, pucComp, hdpaReqList, pdwLastApplied);
  1752. RegCloseKey(hPathKey);
  1753. }
  1754. dwIndex++;
  1755. }
  1756. while (dwError==ERROR_SUCCESS);
  1757. delete [] pdwLastApplied;
  1758. return S_OK;
  1759. }
  1760. HRESULT
  1761. CIEFrameAuto::COpsProfile::_UpdateSiteSettings(AccessSettings *pSettings, HDPA hdpaReqList)
  1762. {
  1763. DWORD dwError;
  1764. DWORD dwAction;
  1765. HKEY hDomainKey = NULL;
  1766. HKEY hPathKey = NULL;
  1767. // Clear the allow and deny vectors
  1768. ZeroMemory(pSettings->m_rgbStdAllow, sizeof(pSettings->m_rgbStdAllow));
  1769. ZeroMemory(pSettings->m_rgbStdDeny, sizeof(pSettings->m_rgbStdDeny));
  1770. // Fill out the vectors based on the user responses on the request list
  1771. for (int i=0; i<DPA_GetPtrCount(hdpaReqList); i++)
  1772. {
  1773. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,i);
  1774. int iVcardIndex = _GetAttrIndexFromName(pCurrent->m_bstrName);
  1775. // At the moment we do not handle custom attributes
  1776. if (iVcardIndex!=INVALID_ATTRIBUTE_INDEX)
  1777. _WriteBitVector(pCurrent->m_fAnswer ? pSettings->m_rgbStdAllow : pSettings->m_rgbStdDeny, iVcardIndex);
  1778. }
  1779. // Create a key for the given domain or open it if one already exists
  1780. dwError = RegCreateKeyEx(m_hP3Sites, pSettings->m_rgchDomain,
  1781. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL,
  1782. &hDomainKey, &dwAction);
  1783. if (dwError!=ERROR_SUCCESS)
  1784. return E_FAIL;
  1785. TCHAR rgchName[16];
  1786. DWORD dwcbName = 0;
  1787. DWORD dwIndex = 0;
  1788. do
  1789. {
  1790. AccessSettings ac;
  1791. dwcbName = ARRAYSIZE(rgchName);
  1792. if (ERROR_SUCCESS != RegEnumKeyEx(hDomainKey, dwIndex, rgchName, &dwcbName, NULL, NULL, NULL, NULL))
  1793. break;
  1794. if (ERROR_SUCCESS != RegOpenKeyEx(hDomainKey, rgchName, 0, KEY_READ, &hPathKey))
  1795. break;
  1796. _ReadSettingsFromRegistry(hPathKey, &ac);
  1797. // If there are existing settings for this domain and path, merge the permissions
  1798. if (StrCmp(ac.m_rgchPath, pSettings->m_rgchPath) == 0)
  1799. {
  1800. // An attribute is allowed if it has been allowed explicitly by the user from
  1801. // the current UI or it was previously allowed and it has not been denied
  1802. // in the current UI. Similarly, an attribute is denied if it is denied in the
  1803. // current UI or it was denied previously and it has not been granted this time.
  1804. for (int i=0; i<ARRAYSIZE(pSettings->m_rgbStdAllow); i++)
  1805. {
  1806. pSettings->m_rgbStdAllow[i] |= ac.m_rgbStdAllow[i] & ~(pSettings->m_rgbStdDeny[i]);
  1807. pSettings->m_rgbStdDeny[i] |= ac.m_rgbStdDeny[i] & ~(pSettings->m_rgbStdAllow[i]);
  1808. }
  1809. break;
  1810. }
  1811. RegCloseKey(hPathKey);
  1812. dwIndex++;
  1813. }
  1814. while (dwError==ERROR_SUCCESS);
  1815. wnsprintf(rgchName, ARRAYSIZE(rgchName), TEXT("%03d"), dwIndex);
  1816. if (ERROR_SUCCESS == RegCreateKeyEx(hDomainKey, rgchName, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hPathKey, &dwAction))
  1817. _WriteSettingsToRegistry(hPathKey, pSettings);
  1818. RegCloseKey(hPathKey);
  1819. RegCloseKey(hDomainKey);
  1820. return S_OK;
  1821. }
  1822. BOOL
  1823. CIEFrameAuto::COpsProfile::_ReadBitVector(LPCBYTE ucBitVector, DWORD dwIndex)
  1824. {
  1825. DWORD dwByte = dwIndex/8;
  1826. DWORD dwMask = 0x80 >> (dwIndex & 0x07);
  1827. return (ucBitVector[dwByte]&dwMask) != 0;
  1828. }
  1829. VOID
  1830. CIEFrameAuto::COpsProfile::_WriteBitVector(LPBYTE ucBitVector, DWORD dwIndex)
  1831. {
  1832. DWORD dwByte = dwIndex/8;
  1833. DWORD dwMask = 0x80 >> (dwIndex & 0x07);
  1834. ucBitVector[dwByte] |= dwMask;
  1835. }
  1836. // The path matching is done on a character-level, which is the way cookies are
  1837. // implemented in IE4 and in Navigator
  1838. // Note that this is different from the RFC-2109
  1839. BOOL
  1840. CIEFrameAuto::COpsProfile::_PathMatch(TCHAR *pszDocumentPath, TCHAR *pszAccessPath)
  1841. {
  1842. return StrStr(pszDocumentPath,pszAccessPath) == pszDocumentPath;
  1843. }
  1844. // Domain name matching is done on the character level except that a leading
  1845. // period is added to the access domain if necessary
  1846. // Refer to "cookie.cxx" in MSHTML for details
  1847. BOOL
  1848. CIEFrameAuto::COpsProfile::_DomainMatch(TCHAR *pszHostName, TCHAR *pszDomain)
  1849. {
  1850. // If domain is the same as hostname, matching is successful
  1851. if (StrCmp(pszHostName, pszDomain) == 0)
  1852. return TRUE;
  1853. // Fail if the domain is not a legal subdomain of the hostname
  1854. // This prevents matching against invaid domains such as ".com" or ".edu"
  1855. if (! _LegalDomain(pszHostName, pszDomain))
  1856. return FALSE;
  1857. // Find the matching part of the domain on the access path
  1858. TCHAR *pszMatchingPart = StrStr(pszHostName, pszDomain);
  1859. // If the domain is not a substring of the hostname, it does not match
  1860. if (pszMatchingPart==NULL)
  1861. return FALSE;
  1862. // Otherwise the domain must be a suffix and it should either contain a period
  1863. // at the beginning or should match following a period
  1864. if (StrCmp(pszMatchingPart, pszDomain) != 0)
  1865. return FALSE;
  1866. if (*pszMatchingPart!='.' && pszMatchingPart[-1]!='.')
  1867. return FALSE;
  1868. return TRUE;
  1869. }
  1870. BOOL
  1871. CIEFrameAuto::COpsProfile::_LegalDomain(TCHAR *pszHostName, TCHAR *pszDomain)
  1872. {
  1873. // Fail if either of the strings are invalid
  1874. if (pszHostName==NULL || pszDomain==NULL ||
  1875. EMPTY_STRING(pszHostName) || EMPTY_STRING(pszDomain))
  1876. return FALSE;
  1877. // If domain is the same as hostname, it is always valid
  1878. if (!StrCmpI(pszHostName, pszDomain))
  1879. return TRUE;
  1880. int iEmbeddedPeriods = 0;
  1881. // Count the number of embedded periods, defined as the number of dots after
  1882. // the first character of the domain
  1883. for(int i=1; pszDomain[i]!=0; i++)
  1884. if (pszDomain[i]=='.')
  1885. iEmbeddedPeriods++;
  1886. // Require that the domain name has at least one embedded period
  1887. if (iEmbeddedPeriods==0)
  1888. return FALSE;
  1889. // Find the requested domain name in the host name
  1890. TCHAR *pszMatchingPart = StrStr(pszHostName, pszDomain);
  1891. // Require that this search succeed
  1892. if (pszMatchingPart==NULL)
  1893. return FALSE;
  1894. // Require furthermore that the domain name be a suffix of the hostname
  1895. if (StrCmp(pszMatchingPart, pszDomain) != 0)
  1896. return FALSE;
  1897. // If all the above criteria has been satisfied, then the domain is valid
  1898. return TRUE;
  1899. }
  1900. // Path matching is done at a character-level; this is to be compliant with Netscape
  1901. // Navigator and the original cookie specification.
  1902. // This has the surprising result that "/foo" matches "/foo/doc" as well as "/foobar/doc"
  1903. BOOL
  1904. CIEFrameAuto::COpsProfile::_LegalPath(TCHAR *pszActualPath, TCHAR *pszAccessPath)
  1905. {
  1906. return StrStr(pszActualPath, pszAccessPath) == pszActualPath;
  1907. }
  1908. // For the ANSI<-->UNICODE transition
  1909. HRESULT
  1910. CIEFrameAuto::COpsProfile::_StringFromBSTR(BSTR bstrSource, TCHAR *pszDest, DWORD dwDestSize)
  1911. {
  1912. StrCpyNW(pszDest, bstrSource, dwDestSize-1);
  1913. return S_OK;
  1914. }
  1915. HRESULT
  1916. CIEFrameAuto::COpsProfile::_StringFromVariant(VARIANT *vaSource, TCHAR *pszDest, DWORD dwDestSize)
  1917. {
  1918. VARIANT vaTemp;
  1919. HRESULT hr;
  1920. VariantInit(&vaTemp);
  1921. hr = VariantChangeType(&vaTemp, vaSource, 0, VT_BSTR);
  1922. if (SUCCEEDED(hr))
  1923. _StringFromBSTR(vaTemp.bstrVal, pszDest, dwDestSize);
  1924. else
  1925. ZeroMemory(pszDest, dwDestSize);
  1926. VariantClear(&vaTemp);
  1927. return hr;
  1928. }
  1929. INT
  1930. CIEFrameAuto::COpsProfile::_GetCookieSettings()
  1931. {
  1932. HKEY hInetKey = NULL;
  1933. DWORD dwCookiePref;
  1934. DWORD dwDataRead = sizeof(dwCookiePref);
  1935. DWORD dwError = RegOpenKeyEx(HKEY_CURRENT_USER, rgszInetKey, 0, KEY_READ, &hInetKey);
  1936. if (dwError !=ERROR_SUCCESS)
  1937. return COOKIES_DENY;
  1938. dwError = RegQueryValueEx(hInetKey, rgszCookieTxt, NULL, NULL, (LPBYTE) &dwCookiePref, &dwDataRead);
  1939. RegCloseKey(hInetKey);
  1940. if (dwError==ERROR_SUCCESS)
  1941. return dwCookiePref;
  1942. else
  1943. return COOKIES_ALLOW;
  1944. }
  1945. HRESULT
  1946. CIEFrameAuto::COpsProfile::_GetUsageCode(VARIANT vaUsage, LPTSTR rgchUsage, int cLen)
  1947. {
  1948. LONG lUsage;
  1949. VARIANT varDest;
  1950. VariantInit(&varDest);
  1951. HRESULT hr = VariantChangeType(&varDest, &vaUsage, 0, VT_I4);
  1952. if (SUCCEEDED(hr))
  1953. {
  1954. lUsage = varDest.lVal;
  1955. // If lUsage is not within range just display unknown usage.
  1956. if (lUsage < 0 || lUsage > (IDS_OPS_USAGEMAX - IDS_OPS_USAGE0))
  1957. lUsage = -1;
  1958. }
  1959. else
  1960. lUsage = -1;
  1961. VariantClear(&varDest);
  1962. MLLoadString(lUsage + IDS_OPS_USAGE0, rgchUsage, cLen);
  1963. return S_OK;
  1964. }
  1965. BOOL
  1966. CIEFrameAuto::COpsProfile::_IsP3Enabled()
  1967. {
  1968. DWORD dwEnabled;
  1969. DWORD dwDataOut = sizeof(dwEnabled);
  1970. DWORD dwError = RegQueryValueEx(m_hP3Global, rgszEnabled,
  1971. NULL, NULL,
  1972. (LPBYTE) &dwEnabled, &dwDataOut);
  1973. if (dwError!=ERROR_SUCCESS)
  1974. {
  1975. dwEnabled = TRUE;
  1976. RegSetValueEx( m_hP3Global, rgszEnabled, 0, REG_DWORD,
  1977. (LPBYTE) &dwEnabled, sizeof(dwEnabled));
  1978. return TRUE;
  1979. }
  1980. else
  1981. return dwEnabled;
  1982. }
  1983. // The script can specify domain, path and expiration date for the settings.
  1984. // If these are not provided, the domain defaults to the hostname, the path to the current
  1985. // document and the expiration to a specified number of days in the future
  1986. HRESULT
  1987. CIEFrameAuto::COpsProfile::_GetSiteSettings(URL_COMPONENTS *pucComp,
  1988. VARIANT vaDomain, VARIANT vaPath, VARIANT vaExpire,
  1989. AccessSettings *pSettings)
  1990. {
  1991. SYSTEMTIME st;
  1992. TCHAR rgchExpire[32];
  1993. HRESULT hr;
  1994. BOOL bRet;
  1995. // Note: For IE4, the domain name has to be hostname.
  1996. StrCpyN(pSettings->m_rgchDomain, pucComp->lpszHostName, ARRAYSIZE(pSettings->m_rgchDomain));
  1997. hr = _StringFromVariant(&vaPath, pSettings->m_rgchPath, ARRAYSIZE(pSettings->m_rgchPath));
  1998. if (FAILED(hr))
  1999. StrCpyN(pSettings->m_rgchPath, pucComp->lpszUrlPath, ARRAYSIZE(pSettings->m_rgchPath));
  2000. // If the path is different from the page, add a "/" if necessary at the end
  2001. DWORD dwPathLen = lstrlen(pSettings->m_rgchPath);
  2002. if (StrCmp(pSettings->m_rgchPath, pucComp->lpszUrlPath) &&
  2003. pSettings->m_rgchPath[dwPathLen-1] != TEXT('/'))
  2004. {
  2005. StrCatBuff(pSettings->m_rgchPath, TEXT("/"), ARRAYSIZE(pSettings->m_rgchPath));
  2006. }
  2007. FILETIME ftNow;
  2008. LARGE_INTEGER *pqwNow = (LARGE_INTEGER*) & ftNow;
  2009. LARGE_INTEGER *pftime = (LARGE_INTEGER*) & pSettings->m_ftExpire;
  2010. GetSystemTimeAsFileTime(&ftNow);
  2011. hr = _StringFromVariant(&vaExpire, rgchExpire, ARRAYSIZE(rgchExpire));
  2012. if (SUCCEEDED(hr))
  2013. {
  2014. bRet = InternetTimeToSystemTime(rgchExpire, &st, 0);
  2015. SystemTimeToFileTime(&st, & pSettings->m_ftExpire);
  2016. }
  2017. if (FAILED(hr) || !bRet)
  2018. {
  2019. QUAD_PART(*pftime) = QUAD_PART(*pqwNow) + defExpiration;
  2020. }
  2021. // Enforce the limit on expiration time
  2022. __int64 qwDelta = (QUAD_PART(*pftime)) - (QUAD_PART(*pqwNow));
  2023. if (qwDelta<0 || qwDelta>maxExpiration)
  2024. QUAD_PART(*pftime) = QUAD_PART(*pqwNow) + maxExpiration;
  2025. // Make sure that the domain and path are valid
  2026. // The criteria is a mix of the cookie semantics as defined by RFC-2109 and Navigator
  2027. // compliant behaviour as implemented elsewhere in IE4
  2028. if (! _LegalPath(pucComp->lpszUrlPath, pSettings->m_rgchPath) )
  2029. StrCpyN(pSettings->m_rgchPath, pucComp->lpszUrlPath, ARRAYSIZE(pSettings->m_rgchPath));
  2030. if (! _LegalDomain(pucComp->lpszHostName, pSettings->m_rgchDomain) )
  2031. StrCpyN(pSettings->m_rgchDomain, pucComp->lpszHostName, ARRAYSIZE(pSettings->m_rgchDomain));
  2032. // Add a period at the beginning of the domain name if it is not equal to
  2033. // the host name
  2034. if (StrCmpI(pucComp->lpszHostName, pSettings->m_rgchDomain) &&
  2035. pSettings->m_rgchDomain[0] != '.')
  2036. {
  2037. StrCpyN(1+pSettings->m_rgchDomain, pSettings->m_rgchDomain, lstrlen(pSettings->m_rgchDomain));
  2038. pSettings->m_rgchDomain[0] = '.';
  2039. }
  2040. pSettings->m_fExactDomain = ! StrCmpI(pSettings->m_rgchDomain, pucComp->lpszHostName);
  2041. if (StrCmp(pSettings->m_rgchPath, pucComp->lpszUrlPath))
  2042. {
  2043. pSettings->m_fExactPath = FALSE;
  2044. }
  2045. else
  2046. {
  2047. pSettings->m_fExactPath = pSettings->m_rgchPath[dwPathLen-1]!=TEXT('/');
  2048. }
  2049. return S_OK;
  2050. }
  2051. HRESULT
  2052. CIEFrameAuto::COpsProfile::_FormatSiteSettings(AccessSettings *pSettings, LPTSTR rgchOut, int cLimit)
  2053. {
  2054. TCHAR rgchFullName[MAX_URL_STRING];
  2055. TCHAR rgchTemp[MAX_URL_STRING];
  2056. wnsprintf(rgchFullName,
  2057. ARRAYSIZE(rgchFullName),
  2058. TEXT("http://%s%s"),
  2059. pSettings->m_rgchDomain,
  2060. pSettings->m_rgchPath);
  2061. FormatUrlForDisplay(rgchFullName, rgchTemp, cLimit, NULL, 0, FALSE, CP_ACP, NULL);
  2062. TCHAR *pchSiteName = StrStr(rgchTemp, TEXT("//"));
  2063. if (pchSiteName==NULL)
  2064. pchSiteName = rgchTemp;
  2065. else
  2066. pchSiteName += 2;
  2067. StrCpyN(rgchOut, pchSiteName, cLimit);
  2068. return S_OK;
  2069. }
  2070. // Attempts to use the given settings to determine the user response to the requests
  2071. // in the given list. If the domain and path for the settings is not applicable to
  2072. // for the given URL, returns FALSE.
  2073. BOOL
  2074. CIEFrameAuto::COpsProfile::_ApplySettings(AccessSettings *pac, URL_COMPONENTS *puc, HDPA hdpaReqList, DWORD *pdwLast)
  2075. {
  2076. if (!_DomainMatch(puc->lpszHostName, pac->m_rgchDomain) ||
  2077. !_PathMatch(puc->lpszUrlPath, pac->m_rgchPath))
  2078. return FALSE;
  2079. DWORD dwPathLen = lstrlen(pac->m_rgchPath);
  2080. for (int i=0; i<DPA_GetPtrCount(hdpaReqList); i++)
  2081. {
  2082. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,i);
  2083. int iVcIndex = _GetAttrIndexFromName(pCurrent->m_bstrName);
  2084. if (iVcIndex==INVALID_ATTRIBUTE_INDEX)
  2085. continue;
  2086. if (pdwLast[i]>=dwPathLen)
  2087. continue;
  2088. else
  2089. pdwLast[i] = dwPathLen;
  2090. BOOL fAllow = _ReadBitVector(pac->m_rgbStdAllow, iVcIndex);
  2091. BOOL fDeny = _ReadBitVector(pac->m_rgbStdDeny, iVcIndex);
  2092. if (fDeny)
  2093. {
  2094. pCurrent->denyRequest();
  2095. pCurrent->m_dwDecision = P3_SITELEVEL;
  2096. }
  2097. else if (fAllow)
  2098. {
  2099. pCurrent->grantRequest();
  2100. pCurrent->m_dwDecision = P3_SITELEVEL;
  2101. }
  2102. }
  2103. return TRUE;
  2104. }
  2105. BOOL
  2106. CIEFrameAuto::COpsProfile::_ReadSettingsFromRegistry(HKEY hkey, AccessSettings *pac)
  2107. {
  2108. DWORD dwError;
  2109. DWORD dwcb;
  2110. ZeroMemory(pac, sizeof(struct AccessSettings));
  2111. dwcb = sizeof(pac->m_rgbStdAllow);
  2112. dwError = RegQueryValueEx(hkey, rgszAllowTxt, NULL, NULL, (LPBYTE) pac->m_rgbStdAllow, &dwcb);
  2113. dwcb = sizeof(pac->m_rgbStdDeny);
  2114. dwError = RegQueryValueEx(hkey, rgszDenyTxt, NULL, NULL, (LPBYTE) pac->m_rgbStdDeny, &dwcb);
  2115. dwcb = sizeof(pac->m_rgchPath);
  2116. dwError = RegQueryValueEx(hkey, rgszPathTxt, NULL, NULL, (LPBYTE) pac->m_rgchPath, &dwcb);
  2117. dwcb = sizeof(pac->m_rgchDomain);
  2118. dwError = RegQueryValueEx(hkey, rgszDomainTxt, NULL, NULL, (LPBYTE) pac->m_rgchDomain, &dwcb);
  2119. return (dwError==ERROR_SUCCESS);
  2120. }
  2121. BOOL
  2122. CIEFrameAuto::COpsProfile::_WriteSettingsToRegistry(HKEY hkey, AccessSettings *pac)
  2123. {
  2124. RegSetValueEx(hkey, rgszAllowTxt, 0, REG_BINARY, pac->m_rgbStdAllow, sizeof(pac->m_rgbStdAllow));
  2125. RegSetValueEx(hkey, rgszDenyTxt, 0, REG_BINARY, pac->m_rgbStdDeny, sizeof(pac->m_rgbStdDeny));
  2126. RegSetValueEx(hkey, rgszPathTxt, 0, REG_SZ, (LPBYTE) pac->m_rgchPath, sizeof(pac->m_rgchPath));
  2127. RegSetValueEx(hkey, rgszDomainTxt, 0, REG_SZ, (LPBYTE) pac->m_rgchDomain, sizeof(pac->m_rgchDomain));
  2128. return TRUE;
  2129. }
  2130. // This function revokes all site permission given previously by deleting
  2131. // the registry entries for all the domains under the "P3Sites" key
  2132. // It is not a good idea to invoke recursive delete on the P3Sites key because
  2133. // the running instance of the navigator will end up with an invalid handle
  2134. HRESULT
  2135. CIEFrameAuto::COpsProfile::_ClearAllSettings(HWND hwnd)
  2136. {
  2137. DWORD dwAction;
  2138. DWORD dwError;
  2139. HKEY hP3Sites;
  2140. dwError = RegCreateKeyEx(HKEY_CURRENT_USER, rgszP3Sites, 0, NULL, REG_OPTION_NON_VOLATILE,
  2141. KEY_ALL_ACCESS, NULL, &hP3Sites, &dwAction);
  2142. DWORD dwIndex = 0;
  2143. DWORD dwcbVal;
  2144. TCHAR rgchName[MAX_PATH];
  2145. HDPA hdpaKeys = DPA_Create(0);
  2146. do
  2147. {
  2148. dwcbVal = ARRAYSIZE(rgchName);
  2149. dwError = RegEnumKeyEx(hP3Sites, dwIndex, rgchName, &dwcbVal, NULL, NULL, NULL, NULL);
  2150. if (dwError==ERROR_SUCCESS)
  2151. {
  2152. LPTSTR pszSiteName = new TCHAR[MAX_PATH];
  2153. if (pszSiteName)
  2154. {
  2155. StrCpyN(pszSiteName, rgchName, MAX_PATH);
  2156. DPA_AppendPtr(hdpaKeys, pszSiteName);
  2157. }
  2158. }
  2159. dwIndex++;
  2160. }
  2161. while (dwError==ERROR_SUCCESS);
  2162. for (int i=0; i<DPA_GetPtrCount(hdpaKeys); i++)
  2163. {
  2164. LPTSTR pszSiteName = (LPTSTR) DPA_FastGetPtr(hdpaKeys, i);
  2165. SHDeleteKey(hP3Sites, pszSiteName);
  2166. delete pszSiteName;
  2167. }
  2168. DPA_Destroy(hdpaKeys);
  2169. hdpaKeys = NULL;
  2170. return S_OK;
  2171. }
  2172. BOOL
  2173. CIEFrameAuto::COpsProfile::_DifferentURL()
  2174. {
  2175. BSTR bstrCurrentURL = NULL;
  2176. HRESULT hr = _pAuto->get_LocationURL(&bstrCurrentURL);
  2177. BOOL fDifferent = (m_bstrLastURL!=NULL) && StrCmpW(bstrCurrentURL, m_bstrLastURL);
  2178. SysFreeString(bstrCurrentURL);
  2179. return fDifferent;
  2180. }
  2181. STDAPI ResetProfileSharing(HWND hwin)
  2182. {
  2183. return CIEFrameAuto::COpsProfile::_ClearAllSettings(hwin);
  2184. }