Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2736 lines
84 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_READ | KEY_SET_VALUE,
  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_READ | KEY_CREATE_SUB_KEY,
  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. AccessSettings acSettings;
  442. HDPA hdpaConfirm = DPA_Create(0);
  443. if (_DifferentURL())
  444. {
  445. clearRequest();
  446. return S_FALSE;
  447. }
  448. hr = _pAuto->get_LocationURL(&bstrURL);
  449. if (FAILED(hr))
  450. return S_FALSE;
  451. _StringFromBSTR(bstrURL, rgchURL, ARRAYSIZE(rgchURL));
  452. URL_COMPONENTS uc = {0};
  453. uc.dwStructSize = sizeof(URL_COMPONENTS);
  454. uc.lpszHostName = rgchDomain;
  455. uc.dwHostNameLength = ARRAYSIZE(rgchDomain);
  456. uc.lpszUrlPath = rgchPath;
  457. uc.dwUrlPathLength = ARRAYSIZE(rgchPath);
  458. uc.lpszScheme = rgchScheme;
  459. uc.dwSchemeLength = ARRAYSIZE(rgchScheme);
  460. InternetCrackUrl(rgchURL, lstrlen(rgchURL), ICU_DECODE, &uc);
  461. _GetSiteSettings(&uc, vaDomain, vaPath, vaExpire, &acSettings);
  462. hr = _CreateStore();
  463. if (FAILED(hr))
  464. return S_FALSE;
  465. if (DPA_GetPtrCount(m_hdpaRequests)==0)
  466. return S_OK;
  467. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  468. {
  469. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  470. pCurrent->clearValue();
  471. }
  472. HWND hwnd = _pAuto->_GetHWND();
  473. INT_PTR nRet = -1;
  474. // #59340 - don't need special priviliges for local machine zone anymore.
  475. if (FALSE && _IsLocalMachine())
  476. {
  477. // If page is on the local machine, all requested information will be given
  478. DPA_EnumCallback(m_hdpaRequests, OPSRequestEntry::grantRequest, NULL);
  479. nRet = TRUE;
  480. }
  481. else
  482. {
  483. // Process the request list and mark attributes according to the configuration
  484. _ApplyPreferences(&uc, m_hdpaRequests);
  485. // Go through the request list and for each attribute that was not marked as
  486. // grant/deny according to the preferences, add it to the list
  487. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  488. {
  489. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  490. if (pCurrent->m_fQuery)
  491. DPA_AppendPtr(hdpaConfirm, pCurrent);
  492. }
  493. // Determine whether there are any attributes to query
  494. fShowUI = DPA_GetPtrCount(hdpaConfirm)>0;
  495. if (!fShowUI)
  496. {
  497. nRet = TRUE;
  498. goto HandleRequest;
  499. }
  500. // If a UI is going to be shown, all attributes that were going to be
  501. // given or denied silently should also be shown
  502. for (k=0; k<DPA_GetPtrCount(m_hdpaRequests); k++)
  503. {
  504. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,k);
  505. if (!pCurrent->m_fQuery &&
  506. (pCurrent->m_fAnswer || (!pCurrent->m_fAnswer && pCurrent->m_dwDecision==P3_SITELEVEL)))
  507. {
  508. DPA_AppendPtr(hdpaConfirm, pCurrent);
  509. pCurrent->m_fQuery = TRUE;
  510. }
  511. }
  512. OPSDlgInfo opsDlgInfo;
  513. opsDlgInfo.m_hdpa = hdpaConfirm;
  514. StrCpyN(opsDlgInfo.m_rgchURL, rgchURL, ARRAYSIZE(opsDlgInfo.m_rgchURL));
  515. opsDlgInfo.m_pOpsProfile = this;
  516. opsDlgInfo.m_pacSettings = &acSettings;
  517. opsDlgInfo.m_fRemember = (_GetCookieSettings()==COOKIES_ALLOW);
  518. if (fname.vt == VT_BSTR && fname.bstrVal && lstrlenW(fname.bstrVal)>0)
  519. opsDlgInfo.m_bstrFName = SysAllocString(fname.bstrVal);
  520. else
  521. opsDlgInfo.m_bstrFName = NULL;
  522. _GetUsageCode(usage, opsDlgInfo.m_rgchUsage, ARRAYSIZE(opsDlgInfo.m_rgchUsage));
  523. //Beign a-thkesa to solve Windows BUG:589837. Assigne the usage member for the next use.
  524. {
  525. m_vUsage.vt = usage.vt;
  526. m_vUsage.lVal = usage.lVal;
  527. }
  528. // End.
  529. nRet = DialogBoxParam(MLGetHinst(),
  530. MAKEINTRESOURCE(IDD_OPS_CONSENT),
  531. hwnd,
  532. _OPSConsent_DlgProc,
  533. (LPARAM) &opsDlgInfo);
  534. fPersistent = opsDlgInfo.m_fRemember;
  535. }
  536. HandleRequest:
  537. if (nRet==-1)
  538. return E_FAIL;
  539. if (!nRet)
  540. {
  541. fPersistent = FALSE;
  542. goto Cleanup;
  543. }
  544. for (i=0; i<DPA_GetPtrCount(m_hdpaRequests); i++)
  545. {
  546. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,i);
  547. if (pCurrent->m_fQuery)
  548. {
  549. pCurrent->m_prefs.m_lastRequest = pCurrent->m_fAnswer ? P3_ACCEPT : P3_REJECT;
  550. _PutUserPreference(pCurrent->m_bstrName, pCurrent->m_prefs);
  551. }
  552. if (pCurrent->m_fAnswer)
  553. {
  554. hr = _GetFieldValue(pCurrent->m_bstrName, & (pCurrent->m_bstrValue));
  555. if (FAILED(hr))
  556. pCurrent->clearValue();
  557. }
  558. }
  559. if (fShowUI && fPersistent &&
  560. (uc.nScheme==INTERNET_SCHEME_HTTP || uc.nScheme==INTERNET_SCHEME_HTTPS))
  561. {
  562. _UpdateSiteSettings(&acSettings, m_hdpaRequests);
  563. }
  564. Cleanup:
  565. DPA_Destroy(hdpaConfirm);
  566. hdpaConfirm = NULL;
  567. _ReleaseStore();
  568. return S_OK;
  569. }
  570. HRESULT CIEFrameAuto::COpsProfile::getAttribute(BSTR bstrAttribName, BSTR *pbstrAttribValue)
  571. {
  572. if (!m_fEnabled)
  573. return S_FALSE;
  574. if (pbstrAttribValue==NULL || bstrAttribName==NULL)
  575. return E_POINTER;
  576. *pbstrAttribValue = NULL;
  577. //
  578. // SECURITY: Since shdocvw has no notion of frames,
  579. // we now prompt on every attempt to get attributes.
  580. // See Windows bugs 536637 & 549409 for details.
  581. //
  582. VARIANT_BOOL vbSuccess;
  583. VARIANT vError, vUsage, vName;
  584. VariantInit(&vError);
  585. VariantInit(&vUsage);
  586. VariantInit(&vName);
  587. vError.vt = VT_ERROR;
  588. vError.scode = DISP_E_PARAMNOTFOUND;
  589. //a-thkesa to solve Windows BUG:589837. Assign the usage member for the this use.
  590. //Begin comment a-thkesa
  591. //vUsage.vt = VT_I4;
  592. //vUsage.lVal = 8;
  593. //End
  594. vUsage = m_vUsage ;// a-thkesa to solve Windows BUG:589837
  595. vName.vt = VT_EMPTY;
  596. clearRequest();
  597. addReadRequest(bstrAttribName, vError, &vbSuccess);
  598. if (vbSuccess == VARIANT_FALSE)
  599. return E_FAIL;
  600. doReadRequest(vUsage, vName, vError, vError, vError, vError);
  601. for (int i=0; i<DPA_GetPtrCount(m_hdpaRequests); i++)
  602. {
  603. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaRequests,i);
  604. if (StrCmpIW(bstrAttribName,pCurrent->m_bstrName) == 0)
  605. {
  606. if (pCurrent->m_bstrValue == NULL)
  607. {
  608. *pbstrAttribValue = SysAllocString(L"");
  609. }
  610. else
  611. {
  612. *pbstrAttribValue = SysAllocString(pCurrent->m_bstrValue);
  613. }
  614. return (*pbstrAttribValue == NULL) ? E_OUTOFMEMORY : S_OK;
  615. }
  616. }
  617. return S_FALSE;
  618. }
  619. HRESULT CIEFrameAuto::COpsProfile::setAttribute(BSTR bstrAttribName, BSTR bstrAttribValue, VARIANT vaPrefs,
  620. VARIANT_BOOL *pfSuccess)
  621. {
  622. BSTR bstrStdName = NULL;
  623. HRESULT hr = S_FALSE;
  624. if (pfSuccess)
  625. *pfSuccess = VARIANT_FALSE;
  626. if (!m_fEnabled)
  627. return S_FALSE;
  628. if (bstrAttribName==NULL)
  629. return E_POINTER;
  630. // If this is a new URL, flush the change queue.
  631. if (_DifferentURL())
  632. {
  633. DPA_EnumCallback(m_hdpaChanges,OPSRequestEntry::destWrapper,NULL);
  634. DPA_DeleteAllPtrs(m_hdpaChanges);
  635. }
  636. // Load the name of the current URL into the last visited URL
  637. SysFreeString(m_bstrLastURL);
  638. _pAuto->get_LocationURL(&m_bstrLastURL);
  639. int index = _GetAttrIndexFromName(bstrAttribName);
  640. if (index==INVALID_ATTRIBUTE_INDEX)
  641. return S_FALSE;
  642. OPSRequestEntry *pNewEntry = new OPSRequestEntry;
  643. if (pNewEntry == NULL)
  644. return E_OUTOFMEMORY;
  645. pNewEntry->m_bstrName = SysAllocString(_GetNameFromAttrIndex(index));
  646. if (pNewEntry->m_bstrName==NULL)
  647. {
  648. delete pNewEntry;
  649. return E_OUTOFMEMORY;
  650. }
  651. if (bstrAttribValue != NULL)
  652. pNewEntry->m_bstrValue = SysAllocString(bstrAttribValue);
  653. else
  654. pNewEntry->m_bstrValue = SysAllocString(L"");
  655. if (pNewEntry->m_bstrValue==NULL)
  656. {
  657. delete pNewEntry;
  658. return E_OUTOFMEMORY;
  659. }
  660. for (int i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  661. {
  662. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges,i);
  663. if (StrCmpIW(pCurrent->m_bstrName, bstrAttribName) == 0)
  664. {
  665. SysFreeString(pCurrent->m_bstrValue);
  666. pCurrent->m_bstrValue = SysAllocString(bstrAttribValue);
  667. if (*pfSuccess)
  668. *pfSuccess = (pCurrent->m_bstrValue!=NULL) ? VARIANT_TRUE : VARIANT_FALSE;
  669. delete pNewEntry;
  670. return S_OK;
  671. }
  672. }
  673. int eIns = DPA_AppendPtr(m_hdpaChanges, pNewEntry);
  674. if (eIns==-1)
  675. {
  676. delete pNewEntry;
  677. return E_OUTOFMEMORY;
  678. }
  679. if (pfSuccess)
  680. *pfSuccess = VARIANT_TRUE;
  681. return S_OK;
  682. }
  683. HRESULT CIEFrameAuto::COpsProfile::commitChanges(VARIANT_BOOL *pfSuccess)
  684. {
  685. if (pfSuccess)
  686. *pfSuccess = VARIANT_FALSE;
  687. if (!m_fEnabled)
  688. return S_FALSE;
  689. HRESULT hr;
  690. HWND hwnd;
  691. int i;
  692. INT_PTR nRet;
  693. OPSDlgInfo opsDlgInfo;
  694. BSTR bstrURL = NULL;
  695. TCHAR rgchURL[MAX_URL_STRING];
  696. _pAuto->get_LocationURL(&bstrURL);
  697. _StringFromBSTR(bstrURL, rgchURL, ARRAYSIZE(rgchURL));
  698. SysFreeString(bstrURL);
  699. // Crack the URL and get the hostname
  700. TCHAR rgchHostName[INTERNET_MAX_HOST_NAME_LENGTH] = { TEXT('\0') };
  701. DWORD dwcbHostLen = ARRAYSIZE(rgchHostName);
  702. UrlGetPart(rgchURL, rgchHostName, &dwcbHostLen, URL_PART_HOSTNAME, 0);
  703. // Read the hostname for the registration page from the registry
  704. TCHAR rgchRegDomain[INTERNET_MAX_HOST_NAME_LENGTH];
  705. DWORD dwcbReg = sizeof(rgchRegDomain);
  706. HKEY hWriteKey = NULL;
  707. DWORD dwError;
  708. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, rgszRegKey, 0, KEY_READ, &hWriteKey);
  709. if (dwError==ERROR_SUCCESS)
  710. {
  711. dwError = RegQueryValueEx(hWriteKey, rgszRegTxt, NULL, NULL, (LPBYTE) rgchRegDomain, &dwcbReg);
  712. RegCloseKey(hWriteKey);
  713. }
  714. BOOL fRegDomain = (dwError==ERROR_SUCCESS && _DomainMatch(rgchHostName, rgchRegDomain));
  715. BOOL fCanWrite = _IsLocalMachine() || fRegDomain;
  716. if (!fCanWrite || _DifferentURL())
  717. goto Cleanup;
  718. hr = _CreateStore();
  719. if (hr)
  720. goto Cleanup;
  721. // Look up the old values from the store
  722. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  723. {
  724. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  725. // Default case: the attribute will be updated
  726. pCurrent->m_fAnswer = TRUE;
  727. hr = _GetFieldValue (pCurrent->m_bstrName, &(pCurrent->m_bstrOldVal));
  728. if (hr)
  729. {
  730. SysFreeString(pCurrent->m_bstrOldVal);
  731. pCurrent->m_bstrOldVal = NULL;
  732. }
  733. }
  734. // Delete nodes in the list if the new value is the same as the old one
  735. // NOTE: The loop counter will remain stationary or increment depending on whether
  736. // the current node in the list is deleted
  737. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); )
  738. {
  739. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  740. if (StrCmpW(pCurrent->m_bstrValue, pCurrent->m_bstrOldVal)==0)
  741. DPA_DeletePtr(m_hdpaChanges, i);
  742. else
  743. i++;
  744. }
  745. // If nothing has changed, then we do not need to write data back to the storage
  746. if (DPA_GetPtrCount(m_hdpaChanges)==0)
  747. goto Cleanup;
  748. // The registration domain can write profile information silently.
  749. // For all other cases, a UI will be displayed.
  750. if (!fRegDomain)
  751. {
  752. // Pop up a UI to show the items that are being changes and allow the user to
  753. // confirm the changes by selecting check-boxes for each attribute
  754. opsDlgInfo.m_hdpa = m_hdpaChanges;
  755. opsDlgInfo.m_pOpsProfile = this;
  756. hwnd = _pAuto->_GetHWND();
  757. nRet = DialogBoxParam(MLGetHinst(),
  758. MAKEINTRESOURCE(IDD_OPS_UPDATE),
  759. hwnd,
  760. _OPSUpdate_DlgProc,
  761. (LPARAM) &opsDlgInfo
  762. );
  763. // Unrecoverable error: failed to show the dialog box
  764. if (nRet==-1)
  765. return S_FALSE;
  766. // If the user clicked "CANCEL", then no changes will be performed
  767. if (nRet==0)
  768. goto Cleanup;
  769. }
  770. if ( pfSuccess )
  771. *pfSuccess = VARIANT_TRUE;
  772. for (i=0; i<DPA_GetPtrCount(m_hdpaChanges); i++)
  773. {
  774. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(m_hdpaChanges, i);
  775. // Registration page should not overwrite existing entries
  776. if (fRegDomain && ! EMPTY_STRINGW(pCurrent->m_bstrOldVal))
  777. continue;
  778. // Update only if the user allowed in the UI
  779. // For the registration page, this condition will hold for all attributes
  780. if (pCurrent->m_fAnswer)
  781. {
  782. hr = _SetFieldValue(pCurrent->m_bstrName, pCurrent->m_bstrValue);
  783. if (hr && pfSuccess)
  784. *pfSuccess = VARIANT_FALSE;
  785. }
  786. }
  787. Cleanup:
  788. // Clear the queue that holds the changes
  789. DPA_EnumCallback(m_hdpaChanges,OPSRequestEntry::destWrapper,NULL);
  790. DPA_DeleteAllPtrs(m_hdpaChanges);
  791. return S_OK;
  792. }
  793. // *** IOpsProfileSimple members ***
  794. STDMETHODIMP CIEFrameAuto::COpsProfile::ReadProperties(long lNumProperties, const LPCWSTR szProperties[], LPWSTR szReturnValues[])
  795. {
  796. HRESULT hr=S_OK;
  797. for (int i=0; i<lNumProperties; i++)
  798. {
  799. BSTR bstrValue=NULL;
  800. LPWSTR pwszRet=NULL;
  801. if (szProperties[i])
  802. {
  803. _GetFieldValue(szProperties[i], &bstrValue);
  804. if (bstrValue)
  805. {
  806. // FEATURE change _GetFieldValue so we don't reallocate twice unnecessarily
  807. int cch = (1 + lstrlenW(bstrValue));
  808. pwszRet = (LPWSTR) CoTaskMemAlloc(sizeof(WCHAR) * cch);
  809. if (pwszRet)
  810. StrCpyNW(pwszRet, bstrValue, cch);
  811. SysFreeString(bstrValue);
  812. }
  813. else
  814. {
  815. hr = S_FALSE;
  816. }
  817. }
  818. szReturnValues[i] = pwszRet;
  819. }
  820. return hr;
  821. }
  822. STDMETHODIMP CIEFrameAuto::COpsProfile::WriteProperties(long lNumProperties, const LPCWSTR szProperties[], const LPCWSTR szValues[])
  823. {
  824. return E_NOTIMPL;
  825. }
  826. #ifdef _USE_PSTORE_
  827. HRESULT CIEFrameAuto::COpsProfile::_GetFieldValue(const OLECHAR *pszField, BSTR * pbstrValue)
  828. {
  829. GUID itemType = GUID_NULL;
  830. GUID itemSubtype = GUID_NULL;
  831. BSTR bstrName = NULL;
  832. DWORD cbData;
  833. BYTE * pbData = NULL;
  834. HRESULT hr;
  835. BOOL fOpen = FALSE;
  836. if (pszField==NULL || pbstrValue==NULL)
  837. return E_POINTER;
  838. PST_PROMPTINFO promptInfo = {0};
  839. promptInfo.cbSize = sizeof(promptInfo);
  840. promptInfo.szPrompt = pszField;
  841. promptInfo.dwPromptFlags = 0;
  842. promptInfo.hwndApp = _pAuto->_GetHWND();
  843. hr = _CreateStore();
  844. if (hr)
  845. goto Cleanup;
  846. hr = _GetPStoreTypes(pszField, &itemType, &itemSubtype, &bstrName);
  847. if (hr)
  848. goto Cleanup;
  849. hr = m_pStore->ReadItem(
  850. s_Key,
  851. &itemType,
  852. &itemSubtype,
  853. bstrName,
  854. &cbData,
  855. &pbData,
  856. &promptInfo,
  857. 0);
  858. if (FAILED(hr))
  859. {
  860. *pbstrValue = SysAllocString(L"");
  861. hr = S_OK;
  862. goto Cleanup;
  863. }
  864. *pbstrValue = SysAllocString((OLECHAR *) pbData);
  865. Cleanup:
  866. _ReleaseStore();
  867. CoTaskMemFree(pbData);
  868. SysFreeString(bstrName);
  869. return hr;
  870. }
  871. HRESULT CIEFrameAuto::COpsProfile::_SetFieldValue(const OLECHAR *pszField, BSTR bstrValue)
  872. {
  873. HRESULT hr;
  874. PST_TYPEINFO typeInfo;
  875. PST_PROMPTINFO promptInfo;
  876. WCHAR * szValue = bstrValue ? bstrValue : L"";
  877. TCHAR szDisplayName[MAX_PATH];
  878. WCHAR wzDisplayName[MAX_PATH];
  879. if (pszField==NULL)
  880. return E_POINTER;
  881. MLLoadString(IDS_PROFILE_ASSISTANT, szDisplayName, ARRAYSIZE(szDisplayName));
  882. typeInfo.cbSize = sizeof(typeInfo);
  883. int cch = MultiByteToWideChar(CP_ACP, 0, szDisplayName, -1,
  884. wzDisplayName, ARRAYSIZE(wzDisplayName));
  885. ASSERT(cch != 0);
  886. typeInfo.szDisplayName = wzDisplayName;
  887. promptInfo.cbSize = sizeof(promptInfo);
  888. promptInfo.dwPromptFlags = 0;
  889. promptInfo.hwndApp = _pAuto->_GetHWND();
  890. promptInfo.szPrompt = pszField;
  891. hr = _CreateStore();
  892. if (hr)
  893. goto Cleanup;
  894. hr = m_pStore->CreateType(s_Key, &GUID_PStoreType, &typeInfo, 0);
  895. if (hr && (hr != PST_E_TYPE_EXISTS))
  896. goto Cleanup;
  897. hr = m_pStore->CreateSubtype(
  898. s_Key,
  899. &GUID_PStoreType,
  900. &GUID_NULL,
  901. &typeInfo,
  902. NULL,
  903. 0);
  904. if (hr && (hr != PST_E_TYPE_EXISTS))
  905. goto Cleanup;
  906. hr = m_pStore->WriteItem(
  907. s_Key,
  908. &GUID_PStoreType,
  909. &GUID_NULL,
  910. pszField,
  911. (lstrlenW(szValue) + 1) * sizeof(WCHAR),
  912. (BYTE *) szValue,
  913. &promptInfo,
  914. PST_CF_NONE,
  915. 0);
  916. Cleanup:
  917. _ReleaseStore();
  918. return hr;
  919. }
  920. #else // _USE_PSTORE_
  921. HRESULT CIEFrameAuto::COpsProfile::_GetFieldValue(const OLECHAR *pszField, BSTR * pbstrValue)
  922. {
  923. LPMAILUSER lpMailUser = NULL;
  924. ULONG ulPropTag;
  925. ULONG ulObjType = 0;
  926. WCHAR * pwzValue = NULL;
  927. BOOL bStoreCreated = FALSE;
  928. HRESULT hr;
  929. if (pszField==NULL || pbstrValue==NULL)
  930. return E_POINTER;
  931. hr = _CreateStore();
  932. if (hr)
  933. goto Cleanup;
  934. else
  935. bStoreCreated = TRUE;
  936. INT index;
  937. index = INVALID_ATTRIBUTE_INDEX;
  938. if (!_ValidateElemName(pszField, &index))
  939. {
  940. hr = E_INVALIDARG;
  941. goto Cleanup;
  942. }
  943. // Open the entry in the address book.
  944. hr = m_lpAdrBook->OpenEntry(m_SBMe.cb,
  945. (LPENTRYID) m_SBMe.lpb,
  946. NULL,
  947. 0,
  948. &ulObjType,
  949. (LPUNKNOWN *)&lpMailUser);
  950. if (hr)
  951. goto Cleanup;
  952. if (lpMailUser)
  953. {
  954. ulPropTag = _GetPropTagFromAttrIndex(index);
  955. SPropTagArray SPTA;
  956. SPTA.cValues = 1;
  957. SPTA.aulPropTag[0] = ulPropTag;
  958. if (PROP_TYPE(ulPropTag) == PT_TSTRING || ulPropTag == PR_GENDER)
  959. {
  960. DWORD cValues = 0;
  961. LPSPropValue lpSPropValue = NULL;
  962. hr = lpMailUser->GetProps(&SPTA, 0, &cValues, &lpSPropValue);
  963. if (!hr)
  964. {
  965. ASSERT(1 == cValues);
  966. ASSERT(NULL != lpSPropValue);
  967. int cch = 0;
  968. LPCTSTR pszPropStr = NULL;
  969. if (ulPropTag == PR_GENDER)
  970. {
  971. switch (lpSPropValue->Value.i)
  972. {
  973. case 1:
  974. pszPropStr = GENDER_FEMALE;
  975. break;
  976. case 2:
  977. pszPropStr = GENDER_MALE;
  978. break;
  979. default:
  980. pszPropStr = GENDER_UNSPECIFIED;
  981. break;
  982. }
  983. }
  984. else
  985. {
  986. ASSERT(PROP_TYPE(lpSPropValue->ulPropTag) == PT_TSTRING);
  987. pszPropStr = lpSPropValue->Value.LPSZ;
  988. }
  989. if (pszPropStr)
  990. {
  991. cch = lstrlen(pszPropStr) + 1;
  992. pwzValue = new WCHAR [cch];
  993. if (NULL == pwzValue)
  994. {
  995. hr = E_OUTOFMEMORY;
  996. }
  997. else
  998. {
  999. StrCpyN(pwzValue, pszPropStr, cch);
  1000. }
  1001. }
  1002. else
  1003. {
  1004. hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); // This will cause us to just return the NULL string.
  1005. }
  1006. }
  1007. m_lpWABObject->FreeBuffer(lpSPropValue);
  1008. }
  1009. else
  1010. {
  1011. // If this assert fires you are probably adding a new PR_* mapping to the OPS code.
  1012. // You will need to write code to convert the returned value to a string meaningfully.
  1013. // See the example for GENDER above.
  1014. ASSERT(FALSE);
  1015. hr = E_NOTIMPL ;
  1016. }
  1017. }
  1018. else
  1019. {
  1020. hr = E_UNEXPECTED;
  1021. }
  1022. if (hr)
  1023. {
  1024. *pbstrValue = SysAllocString(L"");
  1025. hr = (NULL != pbstrValue) ? S_OK : E_OUTOFMEMORY;
  1026. goto Cleanup;
  1027. }
  1028. *pbstrValue = SysAllocString((OLECHAR *) pwzValue);
  1029. Cleanup:
  1030. if (bStoreCreated)
  1031. _ReleaseStore();
  1032. if (lpMailUser)
  1033. lpMailUser->Release();
  1034. delete [] pwzValue;
  1035. return hr;
  1036. }
  1037. HRESULT CIEFrameAuto::COpsProfile::_SetFieldValue(const OLECHAR *pszField, BSTR bstrValue)
  1038. {
  1039. HRESULT hr;
  1040. LPMAILUSER lpMailUser = NULL;
  1041. ULONG ulPropTag;
  1042. ULONG ulObjType = 0;
  1043. BOOL bStoreCreated = FALSE;
  1044. if (pszField==NULL)
  1045. return E_POINTER;
  1046. hr = _CreateStore();
  1047. if (hr)
  1048. goto Cleanup;
  1049. else
  1050. bStoreCreated = TRUE;
  1051. INT index;
  1052. index = INVALID_ATTRIBUTE_INDEX;
  1053. if (!_ValidateElemName(pszField, &index))
  1054. {
  1055. hr = E_INVALIDARG;
  1056. goto Cleanup;
  1057. }
  1058. // Open the entry in the address book.
  1059. hr = m_lpAdrBook->OpenEntry(m_SBMe.cb,
  1060. (LPENTRYID) m_SBMe.lpb,
  1061. NULL,
  1062. MAPI_MODIFY,
  1063. &ulObjType,
  1064. (LPUNKNOWN *)&lpMailUser);
  1065. if (hr)
  1066. goto Cleanup;
  1067. if (lpMailUser)
  1068. {
  1069. ulPropTag = _GetPropTagFromAttrIndex(index);
  1070. if (PROP_TYPE(ulPropTag) == PT_TSTRING || ulPropTag == PR_GENDER)
  1071. {
  1072. // First remove the existing entry
  1073. SPropTagArray SPTA;
  1074. SPTA.cValues = 1;
  1075. SPTA.aulPropTag[0] = ulPropTag;
  1076. lpMailUser->DeleteProps(&SPTA, NULL);
  1077. SPropValue prop;
  1078. prop.ulPropTag = ulPropTag;
  1079. CHAR *pszValue = NULL;
  1080. if (ulPropTag == PR_GENDER)
  1081. {
  1082. short int i = 0; // unspecified.
  1083. if (0 == StrCmpIW(bstrValue, GENDER_FEMALE_W))
  1084. i = 1;
  1085. else if (0 == StrCmpIW(bstrValue, GENDER_MALE_W))
  1086. i = 2;
  1087. prop.Value.i = i;
  1088. }
  1089. else
  1090. {
  1091. prop.Value.LPSZ = bstrValue;
  1092. }
  1093. if (!hr)
  1094. {
  1095. hr = lpMailUser->SetProps(1, &prop, NULL);
  1096. lpMailUser->SaveChanges(0);
  1097. }
  1098. delete [] pszValue;
  1099. }
  1100. else
  1101. {
  1102. hr = E_NOTIMPL ; // FIX THIS BEFORE CHECKING IN.
  1103. }
  1104. }
  1105. else
  1106. {
  1107. hr = E_UNEXPECTED;
  1108. }
  1109. Cleanup:
  1110. if (bStoreCreated)
  1111. _ReleaseStore();
  1112. if (lpMailUser)
  1113. lpMailUser->Release();
  1114. return hr;
  1115. }
  1116. #endif // ! _USE_PSTORE_
  1117. HRESULT CIEFrameAuto::COpsProfile::_GetIDispatchExDelegate(IDispatchEx ** const delegate)
  1118. {
  1119. if( !delegate )
  1120. return E_POINTER;
  1121. *delegate = NULL; // We do not handle expandos yet
  1122. return DISP_E_MEMBERNOTFOUND;
  1123. }
  1124. HRESULT CIEFrameAuto::COpsProfile::_InternalQueryInterface(REFIID riid, void ** const ppvObjOut)
  1125. {
  1126. ASSERT( this );
  1127. ASSERT( !IsEqualIID(riid, IID_IUnknown) );
  1128. if (IsEqualIID(riid, IID_IHTMLOpsProfile))
  1129. {
  1130. *ppvObjOut = SAFECAST(this,IHTMLOpsProfile*);
  1131. }
  1132. else if (IsEqualIID(riid, IID_IOpsProfileSimple))
  1133. {
  1134. *ppvObjOut = SAFECAST(this,IOpsProfileSimple*);
  1135. }
  1136. else
  1137. {
  1138. *ppvObjOut = NULL;
  1139. return E_NOINTERFACE;
  1140. }
  1141. AddRef( );
  1142. return S_OK;
  1143. }
  1144. #ifdef _USE_PSTORE_
  1145. HRESULT
  1146. CIEFrameAuto::COpsProfile::_GetPStoreTypes(
  1147. BSTR bstrField,
  1148. GUID * pguidType,
  1149. GUID * pguidSub,
  1150. BSTR * pbstrName)
  1151. {
  1152. *pguidType = GUID_PStoreType;
  1153. *pguidSub = GUID_NULL;
  1154. *pbstrName = SysAllocString(bstrField);
  1155. return S_OK;
  1156. }
  1157. #endif // _USE_PSTORE_
  1158. // Functions to display the consent dialog.
  1159. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_OnInitDlg(HWND hDlg)
  1160. {
  1161. const int cbMaxStringDisplay = 24;
  1162. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1163. COpsProfile *pProfile = lpOpsDlgInfo->m_pOpsProfile;
  1164. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1165. return FALSE;
  1166. // Get the hostname
  1167. TCHAR rgSiteName[MAX_URL_STRING];
  1168. DWORD dwchOut = ARRAYSIZE(rgSiteName);
  1169. HRESULT hr;
  1170. hr = UrlGetPart(lpOpsDlgInfo->m_rgchURL, rgSiteName, &dwchOut, URL_PART_HOSTNAME, 0);
  1171. if (FAILED(hr) || dwchOut == 0 )
  1172. StrCpyN(rgSiteName, lpOpsDlgInfo->m_rgchURL, ARRAYSIZE(rgSiteName));
  1173. // Display site identity information
  1174. HWND hwndReq = GetDlgItem(hDlg, IDC_SITE_IDENTITY);
  1175. TCHAR rgRequestInfo[MAX_URL_STRING];
  1176. TCHAR rgFormat[MAX_URL_STRING];
  1177. BSTR bstrFName = lpOpsDlgInfo->m_bstrFName;
  1178. TCHAR rgFName[MAX_URL_STRING];
  1179. MLLoadString(IDS_DEFAULT_FNAME, rgFName, ARRAYSIZE(rgFName));
  1180. MLLoadString(IDS_OPS_REQUEST, rgFormat, ARRAYSIZE(rgFormat));
  1181. StringCchPrintf(rgRequestInfo, ARRAYSIZE(rgRequestInfo), rgFormat, rgFName);
  1182. SetWindowText(hwndReq, rgRequestInfo);
  1183. // Display the access settings
  1184. TCHAR rgchAccessPath[MAX_URL_STRING];
  1185. HWND hwndURL = GetDlgItem(hDlg, IDC_OPS_URL);
  1186. _FormatSiteSettings(lpOpsDlgInfo->m_pacSettings, rgchAccessPath, ARRAYSIZE(rgchAccessPath));
  1187. SetWindowText(hwndURL, rgchAccessPath);
  1188. // Display the usage information
  1189. HWND hwndUsage = GetDlgItem(hDlg, IDC_USAGE_STRING);
  1190. SetWindowText(hwndUsage, lpOpsDlgInfo->m_rgchUsage);
  1191. // Detect SSL and inform user in the lower pane
  1192. BOOL fUsingSSL = pProfile->_IsUsingSSL();
  1193. if (fUsingSSL)
  1194. {
  1195. // If the connection is SSL, the default is to remember the settings
  1196. lpOpsDlgInfo->m_fRemember = TRUE;
  1197. // Hide the unsecure connection text.
  1198. HWND hwndStatic = GetDlgItem(hDlg, IDC_UNSECURE_CONNECTION);
  1199. ASSERT(hwndStatic != NULL);
  1200. ShowWindow(hwndStatic, SW_HIDE);
  1201. HICON hicon = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_LOCK));
  1202. if (hicon != NULL)
  1203. {
  1204. HICON hiconOld = (HICON)SendDlgItemMessage(hDlg, IDC_SECURITY_ICON, STM_SETICON,
  1205. (WPARAM)hicon, 0);
  1206. if (hiconOld)
  1207. {
  1208. DestroyIcon(hiconOld);
  1209. }
  1210. }
  1211. }
  1212. else
  1213. {
  1214. // Hide the view certificate button and the secure connection text.
  1215. HWND hwndViewCert = GetDlgItem(hDlg, IDC_VIEW_CERT);
  1216. ASSERT(hwndViewCert != NULL);
  1217. ShowWindow(hwndViewCert, SW_HIDE);
  1218. HWND hwndStatic = GetDlgItem(hDlg, IDC_SECURE_CONNECTION);
  1219. ASSERT(hwndStatic != NULL);
  1220. ShowWindow(hwndStatic, SW_HIDE);
  1221. }
  1222. // Hide the Edit Profile button if we are using the PStore.
  1223. #ifdef _USE_PSTORE
  1224. HWND hwndEditProf = GetDlgItem(hDlg, IDC_EDIT_PROFILE);
  1225. ASSERT(hwndEditProf != NULL);
  1226. ShowWindow(hwndEditProf, SW_HIDE);
  1227. #endif
  1228. Button_SetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS), lpOpsDlgInfo->m_fRemember);
  1229. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1230. ASSERT(hwndLV);
  1231. // Initialize the list view control
  1232. ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_CHECKBOXES);
  1233. // Setup the columns for the list view control.
  1234. LV_COLUMN lvc = { LVCF_FMT , LVCFMT_LEFT };
  1235. ListView_InsertColumn(hwndLV, 0, &lvc);
  1236. ListView_InsertColumn(hwndLV, 1, &lvc);
  1237. // Add elements to the list view.
  1238. _OPSConsent_ShowRequestedItems(hDlg);
  1239. // show the items.
  1240. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1241. UpdateWindow(hwndLV);
  1242. return TRUE;
  1243. }
  1244. BOOL
  1245. CIEFrameAuto::COpsProfile::_OPSConsent_ShowRequestedItems(HWND hDlg)
  1246. {
  1247. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO) GetWindowLongPtr(hDlg, DWLP_USER);
  1248. COpsProfile *pProfile = lpOpsDlgInfo->m_pOpsProfile;
  1249. HDPA hdpaList = lpOpsDlgInfo->m_hdpa;
  1250. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1251. ASSERT(hwndLV);
  1252. BOOL fAllBlank = TRUE;
  1253. TCHAR szName[MAX_PROFILE_NAME];
  1254. // Initialize the common parts of the LVI
  1255. LV_ITEM lvi = { 0 };
  1256. for (int i=DPA_GetPtrCount(hdpaList)-1; i>=0; i--)
  1257. {
  1258. OPSRequestEntry * pOpsEntry = (OPSRequestEntry*) DPA_FastGetPtr(hdpaList,i);
  1259. MLLoadString(_GetResourceIdFromAttrName(pOpsEntry->m_bstrName), szName, MAX_PATH);
  1260. BSTR bstrValue = NULL;
  1261. TCHAR rgchValue[1024];
  1262. pProfile->_GetFieldValue(pOpsEntry->m_bstrName, &bstrValue);
  1263. _StringFromBSTR(bstrValue, rgchValue, ARRAYSIZE(rgchValue));
  1264. fAllBlank = fAllBlank && EMPTY_STRING(rgchValue);
  1265. TCHAR *pchNewLine = StrPBrk(rgchValue, TEXT("\r\n"));
  1266. if (pchNewLine)
  1267. *pchNewLine = '\0';
  1268. if (lstrlen(rgchValue)==0)
  1269. {
  1270. MLLoadString(IDS_OPS_BLANK, rgchValue, ARRAYSIZE(rgchValue));
  1271. }
  1272. SysFreeString(bstrValue);
  1273. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  1274. lvi.iItem = 0;
  1275. lvi.iSubItem = 0;
  1276. lvi.pszText = szName;
  1277. lvi.cchTextMax = MAX_PROFILE_NAME;
  1278. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1279. lvi.state = pOpsEntry->m_fAnswer ? 0x00002000 : 0x00001000;
  1280. lvi.lParam = (LPARAM)pOpsEntry;
  1281. int iItem = ListView_InsertItem(hwndLV, &lvi);
  1282. lvi.mask = LVIF_TEXT;
  1283. lvi.iItem = iItem;
  1284. lvi.iSubItem = 1;
  1285. lvi.pszText = rgchValue;
  1286. ListView_SetItem(hwndLV, &lvi);
  1287. // APPCOMPAT: There is a problem with the listview implementation because of which
  1288. // the check box is not displayed even though lvi.state is set correctly.
  1289. // We have to find the item and set it again.
  1290. ListView_SetItemState(hwndLV, iItem, pOpsEntry->m_fAnswer ? 0x00002000 : 0x00001000, LVIS_STATEIMAGEMASK);
  1291. }
  1292. lpOpsDlgInfo->m_fAllBlank = fAllBlank;
  1293. // Autosize the columns
  1294. ListView_SetColumnWidth(hwndLV, 0, LVSCW_AUTOSIZE);
  1295. ListView_SetColumnWidth(hwndLV, 1, LVSCW_AUTOSIZE);
  1296. return TRUE;
  1297. }
  1298. BOOL CIEFrameAuto::COpsProfile::_OPSDlg_OnClose(HWND hDlg)
  1299. {
  1300. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1301. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1302. int nItems = ListView_GetItemCount(hwndLV);
  1303. LV_ITEM lvi = {0};
  1304. lvi.mask = LVIF_PARAM ;
  1305. for (int i = 0; i < nItems ; i++ )
  1306. {
  1307. lvi.iItem = i;
  1308. lvi.lParam = 0;
  1309. ListView_GetItem(hwndLV, &lvi);
  1310. ASSERT(lvi.lParam != NULL)
  1311. if (lvi.lParam)
  1312. {
  1313. OPSRequestEntry * pOpsEntry = (OPSRequestEntry *)lvi.lParam;
  1314. pOpsEntry->m_fAnswer = ListView_GetCheckState(hwndLV, i);
  1315. }
  1316. }
  1317. lpOpsDlgInfo->m_fRemember = Button_GetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS));
  1318. return TRUE;
  1319. }
  1320. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_EditProfile(HWND hDlg)
  1321. {
  1322. #ifdef _USE_PSTORE
  1323. return FALSE;
  1324. #else
  1325. HRESULT hr;
  1326. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1327. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1328. return FALSE;
  1329. CIEFrameAuto::COpsProfile * pOpsProfile = lpOpsDlgInfo->m_pOpsProfile;
  1330. if (pOpsProfile == NULL || pOpsProfile->m_lpAdrBook == NULL)
  1331. {
  1332. ASSERT(FALSE);
  1333. return FALSE;
  1334. }
  1335. if (pOpsProfile->m_SBMe.cb == 0)
  1336. return FALSE;
  1337. LPSBinary lpSB = &(pOpsProfile->m_SBMe);
  1338. // Display the WAB dialog for the me entry.
  1339. hr = pOpsProfile->m_lpAdrBook->Details( (LPULONG) &hDlg,
  1340. NULL,
  1341. NULL,
  1342. lpSB->cb,
  1343. (LPENTRYID)lpSB->lpb,
  1344. NULL,
  1345. NULL,
  1346. NULL,
  1347. 0);
  1348. return (hr) ? FALSE : TRUE;
  1349. #endif
  1350. }
  1351. BOOL CIEFrameAuto::COpsProfile::_OPSConsent_OnCommand(HWND hDlg, UINT id, UINT nCmd)
  1352. {
  1353. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1354. switch (id)
  1355. {
  1356. case IDOK:
  1357. if (lpOpsDlgInfo->m_fAllBlank)
  1358. {
  1359. // The user has agreed to share information but all the entries in the
  1360. // profile are blank. This is probably due to user oversight, since the
  1361. // easier way to achieve the same effect would be to select "DENY"
  1362. TCHAR rgchHeading[256];
  1363. MLLoadShellLangString(IDS_PROFILE_ASSISTANT, rgchHeading, ARRAYSIZE(rgchHeading));
  1364. TCHAR rgchConfirm[1024];
  1365. MLLoadShellLangString(IDS_OPS_NO_INFORMATION, rgchConfirm, ARRAYSIZE(rgchConfirm));
  1366. ULONG_PTR uCookie = 0;
  1367. SHActivateContext(&uCookie);
  1368. DWORD msgRet = MessageBox(hDlg, rgchConfirm, rgchHeading, MB_YESNO | MB_DEFBUTTON1 | MB_ICONWARNING);
  1369. if (uCookie)
  1370. {
  1371. SHDeactivateContext(uCookie);
  1372. }
  1373. if (msgRet==IDYES)
  1374. goto FallThrough;
  1375. }
  1376. if (! Button_GetCheck(GetDlgItem(hDlg, IDC_KEEP_SETTINGS)) &&
  1377. (_GetCookieSettings()==COOKIES_ALLOW))
  1378. {
  1379. // The user wants to share information for one time only but cookies
  1380. // are enabled, allowing sites to store profile information in a cookie
  1381. DWORD dwConfirm = 0;
  1382. TCHAR rgchHeading[256];
  1383. TCHAR rgchConfirm[1024];
  1384. AccessSettings *pac = lpOpsDlgInfo->m_pacSettings;
  1385. MLLoadShellLangString(IDS_PROFILE_ASSISTANT, rgchHeading, ARRAYSIZE(rgchHeading));
  1386. MLLoadShellLangString(IDS_OPS_CONFIRM, rgchConfirm, ARRAYSIZE(rgchConfirm));
  1387. ULONG_PTR uCookie = 0;
  1388. SHActivateContext(&uCookie);
  1389. dwConfirm = MessageBox(hDlg, rgchConfirm, rgchHeading, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2);
  1390. if (uCookie)
  1391. {
  1392. SHDeactivateContext(uCookie);
  1393. }
  1394. if (dwConfirm!=IDOK)
  1395. break;
  1396. }
  1397. _OPSDlg_OnClose(hDlg);
  1398. EndDialog(hDlg, TRUE);
  1399. break;
  1400. FallThrough:
  1401. case IDC_EDIT_PROFILE:
  1402. {
  1403. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1404. ListView_DeleteAllItems(hwndLV);
  1405. _OPSConsent_EditProfile(hDlg);
  1406. _OPSConsent_ShowRequestedItems(hDlg);
  1407. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1408. UpdateWindow(hwndLV);
  1409. break;
  1410. }
  1411. case IDCANCEL:
  1412. EndDialog(hDlg, FALSE);
  1413. break;
  1414. case IDC_VIEW_CERT:
  1415. _OPSConsent_ViewCertificate(hDlg);
  1416. break;
  1417. default:
  1418. return FALSE;
  1419. }
  1420. return TRUE;
  1421. }
  1422. BOOL
  1423. CIEFrameAuto::COpsProfile::_OPSConsent_ViewCertificate(HWND hDlg)
  1424. {
  1425. OPSDlgInfo *pDlgInfo = (OPSDlgInfo*) GetWindowLongPtr(hDlg, DWLP_USER);
  1426. InternetShowSecurityInfoByURL(pDlgInfo->m_rgchURL, hDlg);
  1427. return TRUE;
  1428. }
  1429. INT_PTR CIEFrameAuto::COpsProfile::_OPSConsent_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1430. {
  1431. switch (uMsg)
  1432. {
  1433. case WM_INITDIALOG:
  1434. ASSERT(NULL != lParam);
  1435. SetWindowLongPtr(hDlg, DWLP_USER, lParam); // save the list.
  1436. return _OPSConsent_OnInitDlg(hDlg);
  1437. case WM_COMMAND:
  1438. return _OPSConsent_OnCommand(hDlg, LOWORD(wParam), HIWORD(wParam));
  1439. case WM_HELP:
  1440. SHWinHelpOnDemandWrap((HWND) ((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile,
  1441. HELP_WM_HELP, (DWORD_PTR)(LPTSTR) aHelpIDs);
  1442. break;
  1443. case WM_CONTEXTMENU:
  1444. SHWinHelpOnDemandWrap((HWND) wParam, c_szHelpFile, HELP_CONTEXTMENU,
  1445. (DWORD_PTR)(LPTSTR) aHelpIDs);
  1446. break;
  1447. case WM_DESTROY:
  1448. break;
  1449. }
  1450. return FALSE;
  1451. }
  1452. // Update dialog functions.
  1453. BOOL CIEFrameAuto::COpsProfile::_OPSUpdate_OnInitDlg(HWND hDlg)
  1454. {
  1455. LPOPSDLGINFO lpOpsDlgInfo = (LPOPSDLGINFO)GetWindowLongPtr(hDlg, DWLP_USER);
  1456. if (!lpOpsDlgInfo || !lpOpsDlgInfo->m_hdpa)
  1457. return FALSE;
  1458. HDPA hdpaList = lpOpsDlgInfo->m_hdpa;
  1459. HWND hwndLV = GetDlgItem(hDlg, IDC_OPS_LIST);
  1460. ASSERT(hwndLV);
  1461. // Add elements to the list view.
  1462. ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_CHECKBOXES);
  1463. // Initialize the common parts of the LVI
  1464. TCHAR szName[MAX_PROFILE_NAME];
  1465. LV_ITEM lvi = { 0 };
  1466. lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
  1467. lvi.iItem = 0;
  1468. lvi.pszText = szName;
  1469. lvi.cchTextMax = MAX_PROFILE_NAME;
  1470. lvi.stateMask = LVIS_STATEIMAGEMASK;
  1471. LV_FINDINFO lvfi = { 0 };
  1472. lvfi.flags = LVFI_STRING;
  1473. lvfi.psz = szName;
  1474. for (int i=0; i<DPA_GetPtrCount(hdpaList); i++)
  1475. {
  1476. OPSRequestEntry * pOpsEntry = (OPSRequestEntry*) DPA_FastGetPtr(hdpaList,i);
  1477. MLLoadString(_GetResourceIdFromAttrName(pOpsEntry->m_bstrName), szName, MAX_PATH);
  1478. pOpsEntry->m_fAnswer = TRUE;
  1479. lvi.state = 0x00002000;
  1480. lvi.lParam = (LPARAM)pOpsEntry;
  1481. ListView_InsertItem(hwndLV, &lvi);
  1482. // APPCOMPAT: There is a problem with the listview implementation because of which
  1483. // the check box is not displayed even though lvi.state is set correctly.
  1484. // We have to find the item and set it again.
  1485. ListView_SetItemState(hwndLV, ListView_FindItem(hwndLV, -1, &lvfi), 0x00002000, LVIS_STATEIMAGEMASK);
  1486. }
  1487. // show the items.
  1488. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1489. UpdateWindow(hwndLV);
  1490. return TRUE;
  1491. }
  1492. BOOL CIEFrameAuto::COpsProfile::_OPSUpdate_OnCommand(HWND hDlg, UINT id, UINT nCmd)
  1493. {
  1494. switch (id)
  1495. {
  1496. case IDOK:
  1497. _OPSDlg_OnClose(hDlg);
  1498. EndDialog(hDlg, TRUE);
  1499. break;
  1500. case IDCANCEL:
  1501. EndDialog(hDlg, FALSE);
  1502. break;
  1503. default:
  1504. return FALSE;
  1505. }
  1506. return TRUE;
  1507. }
  1508. INT_PTR CIEFrameAuto::COpsProfile::_OPSUpdate_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1509. {
  1510. switch (uMsg)
  1511. {
  1512. case WM_INITDIALOG:
  1513. ASSERT(NULL != lParam);
  1514. SetWindowLongPtr(hDlg, DWLP_USER, lParam); // save the list.
  1515. return _OPSUpdate_OnInitDlg(hDlg);
  1516. case WM_COMMAND:
  1517. return _OPSUpdate_OnCommand(hDlg, LOWORD(wParam), HIWORD(wParam));
  1518. case WM_HELP:
  1519. break;
  1520. case WM_CONTEXTMENU:
  1521. break;
  1522. case WM_DESTROY:
  1523. break;
  1524. }
  1525. return FALSE;
  1526. }
  1527. BOOL
  1528. CIEFrameAuto::COpsProfile ::_ValidateElemName(LPCWSTR szIn, INT *pIndex /* = NULL */)
  1529. {
  1530. int index = _GetAttrIndexFromName(szIn);
  1531. if ( INVALID_ATTRIBUTE_INDEX != index )
  1532. {
  1533. if (pIndex)
  1534. *pIndex = index;
  1535. return TRUE;
  1536. }
  1537. return FALSE;
  1538. }
  1539. INT CIEFrameAuto::COpsProfile::_GetAttrIndexFromName (LPCWSTR pwzName )
  1540. {
  1541. INT index = INVALID_ATTRIBUTE_INDEX;
  1542. if ( pwzName != NULL )
  1543. {
  1544. for ( int i = 0 ; i < ARRAYSIZE(rgProfAttr) ; i++ )
  1545. {
  1546. if (0 == StrCmpIW(rgProfAttr[i].pwzName, pwzName ))
  1547. {
  1548. index = i;
  1549. break;
  1550. }
  1551. }
  1552. }
  1553. return index;
  1554. }
  1555. INT CIEFrameAuto::COpsProfile::_GetResourceIdFromAttrName( WCHAR * pwzName)
  1556. {
  1557. return _GetResourceIdFromAttrIndex(_GetAttrIndexFromName(pwzName));
  1558. }
  1559. BOOL
  1560. CIEFrameAuto::COpsProfile::_IsLocalMachine()
  1561. {
  1562. BOOL fLocal = FALSE;
  1563. BSTR bstrURL;
  1564. HRESULT hr = _pAuto->get_LocationURL(&bstrURL);
  1565. if (SUCCEEDED(hr))
  1566. {
  1567. DWORD dwZone;
  1568. hr = GetZoneFromUrl(bstrURL, _pAuto->_psp, &dwZone);
  1569. if (SUCCEEDED(hr))
  1570. {
  1571. fLocal = (dwZone == URLZONE_LOCAL_MACHINE);
  1572. }
  1573. SysFreeString(bstrURL);
  1574. }
  1575. return fLocal;
  1576. }
  1577. HRESULT
  1578. CIEFrameAuto::COpsProfile::_GetUserPreference(BSTR bstrName, P3UserPref *pUsrPref) {
  1579. TCHAR rgszName[MAX_PROFILE_NAME];
  1580. DWORD dwType;
  1581. DWORD dwPrefSize;
  1582. DWORD dwError;
  1583. _StringFromBSTR(bstrName, rgszName, ARRAYSIZE(rgszName));
  1584. dwPrefSize = sizeof(struct P3UserPref);
  1585. dwError = RegQueryValueEx(m_hP3Global, rgszName, 0, &dwType,
  1586. (LPBYTE) pUsrPref, &dwPrefSize);
  1587. if (dwError == ERROR_MORE_DATA)
  1588. {
  1589. BYTE *pBuffer;
  1590. pBuffer = new BYTE [dwPrefSize];
  1591. if (pBuffer == NULL)
  1592. {
  1593. return E_OUTOFMEMORY;
  1594. }
  1595. dwError = RegQueryValueEx(m_hP3Global, rgszName, 0, &dwType, pBuffer, &dwPrefSize);
  1596. memcpy(pUsrPref, pBuffer, sizeof(struct P3UserPref));
  1597. delete [] pBuffer;
  1598. }
  1599. // If a preference for this attribute is not found, create a default one and
  1600. // write it back to persistent storage
  1601. if (dwError != ERROR_SUCCESS)
  1602. {
  1603. P3UserPref defPrefs;
  1604. defPrefs.m_access = P3_QUERY;
  1605. defPrefs.m_lastRequest = P3_ACCEPT;
  1606. _PutUserPreference(bstrName, defPrefs);
  1607. *pUsrPref = defPrefs;
  1608. }
  1609. return S_OK;
  1610. }
  1611. HRESULT
  1612. CIEFrameAuto::COpsProfile::_PutUserPreference(BSTR bstrName, P3UserPref usrPref) {
  1613. TCHAR rgszName[MAX_PROFILE_NAME];
  1614. DWORD dwError;
  1615. _StringFromBSTR(bstrName, rgszName, ARRAYSIZE(rgszName));
  1616. dwError = RegSetValueEx(m_hP3Global, rgszName, 0, REG_BINARY,
  1617. (LPBYTE) &usrPref,
  1618. sizeof(struct P3UserPref));
  1619. return HRESULT_FROM_WIN32(dwError);
  1620. }
  1621. BOOL
  1622. CIEFrameAuto::COpsProfile::_IsUsingSSL()
  1623. {
  1624. BOOL fSecure = FALSE;
  1625. BSTR bstrUrl;
  1626. TCHAR rgchUrl[MAX_URL_STRING+1];
  1627. _pAuto->get_LocationURL(&bstrUrl);
  1628. _StringFromBSTR(bstrUrl, rgchUrl, ARRAYSIZE(rgchUrl));
  1629. SysFreeString(bstrUrl);
  1630. fSecure = GetUrlScheme(rgchUrl)==URL_SCHEME_HTTPS;
  1631. return fSecure;
  1632. }
  1633. HRESULT
  1634. CIEFrameAuto::COpsProfile::_ApplyPreferences(URL_COMPONENTS *pucURL, HDPA hdpaReqList)
  1635. {
  1636. for (int k=0; k<DPA_GetPtrCount(hdpaReqList); k++)
  1637. {
  1638. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,k);
  1639. pCurrent->m_fQuery = TRUE;
  1640. pCurrent->m_fAnswer = FALSE;
  1641. pCurrent->m_dwDecision = P3_NONE;
  1642. }
  1643. _ApplySiteSettings(pucURL, hdpaReqList);
  1644. _ApplyGlobalSettings(hdpaReqList);
  1645. return S_OK;
  1646. }
  1647. HRESULT
  1648. CIEFrameAuto::COpsProfile::_ApplyGlobalSettings(HDPA hdpaReqList)
  1649. {
  1650. for (int k=0; k<DPA_GetPtrCount(hdpaReqList); k++)
  1651. {
  1652. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,k);
  1653. P3UserPref userInfo;
  1654. _GetUserPreference(pCurrent->m_bstrName, &userInfo);
  1655. switch (userInfo.m_access)
  1656. {
  1657. case P3_GRANT: if (pCurrent->m_fQuery)
  1658. {
  1659. pCurrent->grantRequest();
  1660. pCurrent->m_dwDecision = P3_GLOBAL;
  1661. }
  1662. break;
  1663. case P3_DENY: pCurrent->denyRequest();
  1664. pCurrent->m_dwDecision = P3_GLOBAL;
  1665. break;
  1666. case P3_REQSSL: // This resolves to P3_QUERY at the moment
  1667. case P3_QUERY: if (pCurrent->m_fQuery)
  1668. pCurrent->m_fAnswer = (userInfo.m_lastRequest == P3_ACCEPT);
  1669. break;
  1670. default: ;
  1671. }
  1672. }
  1673. return S_OK;
  1674. }
  1675. HRESULT
  1676. CIEFrameAuto::COpsProfile::_ApplySiteSettings(URL_COMPONENTS *pucURL, HDPA hdpaReqList)
  1677. {
  1678. if (pucURL->nScheme!=INTERNET_SCHEME_HTTP && pucURL->nScheme!=INTERNET_SCHEME_HTTPS)
  1679. return S_OK;
  1680. TCHAR *pszSubDomain = pucURL->lpszHostName;
  1681. // For a given hostname such as "www.foo.bar.com", this loop will iterate over all possible
  1682. // domains such as "www.foo.bar.com", ".foo.bar.com" and ".bar.com" but NOT ".com"
  1683. while (pszSubDomain!=NULL && _LegalDomain(pucURL->lpszHostName, pszSubDomain))
  1684. {
  1685. HKEY hkey = NULL;
  1686. if (ERROR_SUCCESS == RegOpenKeyEx(m_hP3Sites, pszSubDomain, 0, KEY_ENUMERATE_SUB_KEYS, &hkey))
  1687. {
  1688. _ApplyDomainSettings(pucURL, hkey, hdpaReqList);
  1689. RegCloseKey(hkey);
  1690. }
  1691. pszSubDomain = StrChr(pszSubDomain+1, TEXT('.')); // Find the next embedded dot
  1692. }
  1693. return S_OK;
  1694. }
  1695. HRESULT
  1696. CIEFrameAuto::COpsProfile::_ApplyDomainSettings(URL_COMPONENTS *pucComp, HKEY hkey, HDPA hdpaReqList)
  1697. {
  1698. DWORD dwError;
  1699. DWORD dwIndex = 0;
  1700. TCHAR rgchName[MAX_PATH];
  1701. int iReqCount = DPA_GetPtrCount(hdpaReqList);
  1702. DWORD *pdwLastApplied = new DWORD[iReqCount];
  1703. if (pdwLastApplied == NULL)
  1704. {
  1705. return E_OUTOFMEMORY;
  1706. }
  1707. for (int i=0; i<iReqCount; i++)
  1708. pdwLastApplied[i] = 0;
  1709. do
  1710. {
  1711. DWORD dwcbVal = ARRAYSIZE(rgchName);
  1712. dwError = RegEnumKeyEx(hkey, dwIndex, rgchName, &dwcbVal, NULL, NULL, NULL, NULL);
  1713. if (dwError==ERROR_SUCCESS)
  1714. {
  1715. HKEY hPathKey;
  1716. AccessSettings ac;
  1717. dwError = RegOpenKeyEx(hkey, rgchName, 0, KEY_QUERY_VALUE, &hPathKey);
  1718. _ReadSettingsFromRegistry(hPathKey, &ac);
  1719. _ApplySettings(&ac, pucComp, hdpaReqList, pdwLastApplied);
  1720. RegCloseKey(hPathKey);
  1721. }
  1722. dwIndex++;
  1723. }
  1724. while (dwError==ERROR_SUCCESS);
  1725. delete [] pdwLastApplied;
  1726. return S_OK;
  1727. }
  1728. HRESULT
  1729. CIEFrameAuto::COpsProfile::_UpdateSiteSettings(AccessSettings *pSettings, HDPA hdpaReqList)
  1730. {
  1731. DWORD dwError;
  1732. DWORD dwAction;
  1733. // Clear the allow and deny vectors
  1734. ZeroMemory(pSettings->m_rgbStdAllow, sizeof(pSettings->m_rgbStdAllow));
  1735. ZeroMemory(pSettings->m_rgbStdDeny, sizeof(pSettings->m_rgbStdDeny));
  1736. // Fill out the vectors based on the user responses on the request list
  1737. for (int i=0; i<DPA_GetPtrCount(hdpaReqList); i++)
  1738. {
  1739. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,i);
  1740. int iVcardIndex = _GetAttrIndexFromName(pCurrent->m_bstrName);
  1741. // At the moment we do not handle custom attributes
  1742. if (iVcardIndex!=INVALID_ATTRIBUTE_INDEX)
  1743. _WriteBitVector(pCurrent->m_fAnswer ? pSettings->m_rgbStdAllow : pSettings->m_rgbStdDeny, iVcardIndex);
  1744. }
  1745. // Create a key for the given domain or open it if one already exists
  1746. HKEY hDomainKey;
  1747. dwError = RegCreateKeyEx(m_hP3Sites, pSettings->m_rgchDomain,
  1748. 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS,
  1749. NULL, &hDomainKey, &dwAction);
  1750. if (dwError != ERROR_SUCCESS)
  1751. return E_FAIL;
  1752. TCHAR rgchName[16];
  1753. DWORD dwIndex = 0;
  1754. do
  1755. {
  1756. DWORD dwcbName = ARRAYSIZE(rgchName);
  1757. if (ERROR_SUCCESS == RegEnumKeyEx(hDomainKey, dwIndex, rgchName, &dwcbName, NULL, NULL, NULL, NULL))
  1758. {
  1759. HKEY hPathKey;
  1760. if (ERROR_SUCCESS == RegOpenKeyEx(hDomainKey, rgchName, 0, KEY_QUERY_VALUE, &hPathKey))
  1761. {
  1762. AccessSettings ac;
  1763. _ReadSettingsFromRegistry(hPathKey, &ac);
  1764. RegCloseKey(hPathKey); // not needed below
  1765. // If there are existing settings for this domain and path, merge the permissions
  1766. if (StrCmp(ac.m_rgchPath, pSettings->m_rgchPath) == 0)
  1767. {
  1768. // An attribute is allowed if it has been allowed explicitly by the user from
  1769. // the current UI or it was previously allowed and it has not been denied
  1770. // in the current UI. Similarly, an attribute is denied if it is denied in the
  1771. // current UI or it was denied previously and it has not been granted this time.
  1772. for (int i=0; i<ARRAYSIZE(pSettings->m_rgbStdAllow); i++)
  1773. {
  1774. pSettings->m_rgbStdAllow[i] |= ac.m_rgbStdAllow[i] & ~(pSettings->m_rgbStdDeny[i]);
  1775. pSettings->m_rgbStdDeny[i] |= ac.m_rgbStdDeny[i] & ~(pSettings->m_rgbStdAllow[i]);
  1776. }
  1777. break;
  1778. }
  1779. dwIndex++;
  1780. }
  1781. }
  1782. }
  1783. while (dwError == ERROR_SUCCESS);
  1784. StringCchPrintf(rgchName, ARRAYSIZE(rgchName), TEXT("%03d"), dwIndex);
  1785. HKEY hPathKey;
  1786. if (ERROR_SUCCESS == RegCreateKeyEx(hDomainKey, rgchName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hPathKey, &dwAction))
  1787. {
  1788. _WriteSettingsToRegistry(hPathKey, pSettings);
  1789. RegCloseKey(hPathKey);
  1790. }
  1791. RegCloseKey(hDomainKey);
  1792. return S_OK;
  1793. }
  1794. BOOL
  1795. CIEFrameAuto::COpsProfile::_ReadBitVector(LPCBYTE ucBitVector, DWORD dwIndex)
  1796. {
  1797. DWORD dwByte = dwIndex/8;
  1798. DWORD dwMask = 0x80 >> (dwIndex & 0x07);
  1799. return (ucBitVector[dwByte]&dwMask) != 0;
  1800. }
  1801. VOID
  1802. CIEFrameAuto::COpsProfile::_WriteBitVector(LPBYTE ucBitVector, DWORD dwIndex)
  1803. {
  1804. DWORD dwByte = dwIndex/8;
  1805. DWORD dwMask = 0x80 >> (dwIndex & 0x07);
  1806. ucBitVector[dwByte] |= dwMask;
  1807. }
  1808. // The path matching is done on a character-level, which is the way cookies are
  1809. // implemented in IE4 and in Navigator
  1810. // Note that this is different from the RFC-2109
  1811. BOOL
  1812. CIEFrameAuto::COpsProfile::_PathMatch(TCHAR *pszDocumentPath, TCHAR *pszAccessPath)
  1813. {
  1814. return StrStr(pszDocumentPath,pszAccessPath) == pszDocumentPath;
  1815. }
  1816. // Domain name matching is done on the character level except that a leading
  1817. // period is added to the access domain if necessary
  1818. // Refer to "cookie.cxx" in MSHTML for details
  1819. BOOL
  1820. CIEFrameAuto::COpsProfile::_DomainMatch(TCHAR *pszHostName, TCHAR *pszDomain)
  1821. {
  1822. // If domain is the same as hostname, matching is successful
  1823. if (StrCmp(pszHostName, pszDomain) == 0)
  1824. return TRUE;
  1825. // Fail if the domain is not a legal subdomain of the hostname
  1826. // This prevents matching against invaid domains such as ".com" or ".edu"
  1827. if (! _LegalDomain(pszHostName, pszDomain))
  1828. return FALSE;
  1829. // Find the matching part of the domain on the access path
  1830. TCHAR *pszMatchingPart = StrStr(pszHostName, pszDomain);
  1831. // If the domain is not a substring of the hostname, it does not match
  1832. if (pszMatchingPart==NULL)
  1833. return FALSE;
  1834. // Otherwise the domain must be a suffix and it should either contain a period
  1835. // at the beginning or should match following a period
  1836. if (StrCmp(pszMatchingPart, pszDomain) != 0)
  1837. return FALSE;
  1838. if (*pszMatchingPart!='.' && pszMatchingPart[-1]!='.')
  1839. return FALSE;
  1840. return TRUE;
  1841. }
  1842. BOOL
  1843. CIEFrameAuto::COpsProfile::_LegalDomain(TCHAR *pszHostName, TCHAR *pszDomain)
  1844. {
  1845. // Fail if either of the strings are invalid
  1846. if (pszHostName==NULL || pszDomain==NULL ||
  1847. EMPTY_STRING(pszHostName) || EMPTY_STRING(pszDomain))
  1848. return FALSE;
  1849. // If domain is the same as hostname, it is always valid
  1850. if (!StrCmpI(pszHostName, pszDomain))
  1851. return TRUE;
  1852. int iEmbeddedPeriods = 0;
  1853. // Count the number of embedded periods, defined as the number of dots after
  1854. // the first character of the domain
  1855. for (int i=1; pszDomain[i]!=0; i++)
  1856. if (pszDomain[i]=='.')
  1857. iEmbeddedPeriods++;
  1858. // Require that the domain name has at least one embedded period
  1859. if (iEmbeddedPeriods==0)
  1860. return FALSE;
  1861. // Find the requested domain name in the host name
  1862. TCHAR *pszMatchingPart = StrStr(pszHostName, pszDomain);
  1863. // Require that this search succeed
  1864. if (pszMatchingPart==NULL)
  1865. return FALSE;
  1866. // Require furthermore that the domain name be a suffix of the hostname
  1867. if (StrCmp(pszMatchingPart, pszDomain) != 0)
  1868. return FALSE;
  1869. // If all the above criteria has been satisfied, then the domain is valid
  1870. return TRUE;
  1871. }
  1872. // Path matching is done at a character-level; this is to be compliant with Netscape
  1873. // Navigator and the original cookie specification.
  1874. // This has the surprising result that "/foo" matches "/foo/doc" as well as "/foobar/doc"
  1875. BOOL
  1876. CIEFrameAuto::COpsProfile::_LegalPath(TCHAR *pszActualPath, TCHAR *pszAccessPath)
  1877. {
  1878. return StrStr(pszActualPath, pszAccessPath) == pszActualPath;
  1879. }
  1880. // For the ANSI<-->UNICODE transition
  1881. HRESULT
  1882. CIEFrameAuto::COpsProfile::_StringFromBSTR(BSTR bstrSource, TCHAR *pszDest, DWORD cchDestSize)
  1883. {
  1884. StrCpyNW(pszDest, bstrSource, cchDestSize);
  1885. return S_OK;
  1886. }
  1887. HRESULT
  1888. CIEFrameAuto::COpsProfile::_StringFromVariant(VARIANT *vaSource, TCHAR *pszDest, DWORD cchDestSize)
  1889. {
  1890. VARIANT vaTemp;
  1891. HRESULT hr;
  1892. VariantInit(&vaTemp);
  1893. hr = VariantChangeType(&vaTemp, vaSource, 0, VT_BSTR);
  1894. if (SUCCEEDED(hr))
  1895. _StringFromBSTR(vaTemp.bstrVal, pszDest, cchDestSize);
  1896. else
  1897. ZeroMemory(pszDest, cchDestSize*sizeof(TCHAR));
  1898. VariantClear(&vaTemp);
  1899. return hr;
  1900. }
  1901. INT
  1902. CIEFrameAuto::COpsProfile::_GetCookieSettings()
  1903. {
  1904. HKEY hInetKey = NULL;
  1905. DWORD dwCookiePref;
  1906. DWORD dwDataRead = sizeof(dwCookiePref);
  1907. DWORD dwError = RegOpenKeyEx(HKEY_CURRENT_USER, rgszInetKey, 0, KEY_READ, &hInetKey);
  1908. if (dwError != ERROR_SUCCESS)
  1909. return COOKIES_DENY;
  1910. dwError = RegQueryValueEx(hInetKey, rgszCookieTxt, NULL, NULL, (LPBYTE) &dwCookiePref, &dwDataRead);
  1911. RegCloseKey(hInetKey);
  1912. if (dwError==ERROR_SUCCESS)
  1913. return dwCookiePref;
  1914. else
  1915. return COOKIES_ALLOW;
  1916. }
  1917. HRESULT
  1918. CIEFrameAuto::COpsProfile::_GetUsageCode(VARIANT vaUsage, LPTSTR rgchUsage, int cLen)
  1919. {
  1920. LONG lUsage;
  1921. VARIANT varDest;
  1922. VariantInit(&varDest);
  1923. HRESULT hr = VariantChangeType(&varDest, &vaUsage, 0, VT_I4);
  1924. if (SUCCEEDED(hr))
  1925. {
  1926. lUsage = varDest.lVal;
  1927. // If lUsage is not within range just display unknown usage.
  1928. if (lUsage < 0 || lUsage > (IDS_OPS_USAGEMAX - IDS_OPS_USAGE0))
  1929. lUsage = -1;
  1930. }
  1931. else
  1932. lUsage = -1;
  1933. VariantClear(&varDest);
  1934. MLLoadString(lUsage + IDS_OPS_USAGE0, rgchUsage, cLen);
  1935. return S_OK;
  1936. }
  1937. BOOL
  1938. CIEFrameAuto::COpsProfile::_IsP3Enabled()
  1939. {
  1940. DWORD dwEnabled;
  1941. DWORD dwDataOut = sizeof(dwEnabled);
  1942. DWORD dwError = RegQueryValueEx(m_hP3Global, rgszEnabled, NULL, NULL, (LPBYTE) &dwEnabled, &dwDataOut);
  1943. if (dwError != ERROR_SUCCESS)
  1944. {
  1945. dwEnabled = TRUE;
  1946. RegSetValueEx(m_hP3Global, rgszEnabled, 0, REG_DWORD, (LPBYTE)&dwEnabled, sizeof(dwEnabled));
  1947. }
  1948. return dwEnabled;
  1949. }
  1950. // The script can specify domain, path and expiration date for the settings.
  1951. // If these are not provided, the domain defaults to the hostname, the path to the current
  1952. // document and the expiration to a specified number of days in the future
  1953. HRESULT
  1954. CIEFrameAuto::COpsProfile::_GetSiteSettings(URL_COMPONENTS *pucComp,
  1955. VARIANT vaDomain, VARIANT vaPath, VARIANT vaExpire,
  1956. AccessSettings *pSettings)
  1957. {
  1958. SYSTEMTIME st;
  1959. TCHAR rgchExpire[32];
  1960. HRESULT hr;
  1961. BOOL bRet;
  1962. // Note: For IE4, the domain name has to be hostname.
  1963. StrCpyN(pSettings->m_rgchDomain, pucComp->lpszHostName, ARRAYSIZE(pSettings->m_rgchDomain));
  1964. hr = _StringFromVariant(&vaPath, pSettings->m_rgchPath, ARRAYSIZE(pSettings->m_rgchPath));
  1965. if (FAILED(hr))
  1966. StrCpyN(pSettings->m_rgchPath, pucComp->lpszUrlPath, ARRAYSIZE(pSettings->m_rgchPath));
  1967. // If the path is different from the page, add a "/" if necessary at the end
  1968. DWORD dwPathLen = lstrlen(pSettings->m_rgchPath);
  1969. if (StrCmp(pSettings->m_rgchPath, pucComp->lpszUrlPath) &&
  1970. pSettings->m_rgchPath[dwPathLen-1] != TEXT('/'))
  1971. {
  1972. StrCatBuff(pSettings->m_rgchPath, TEXT("/"), ARRAYSIZE(pSettings->m_rgchPath));
  1973. }
  1974. FILETIME ftNow;
  1975. LARGE_INTEGER *pqwNow = (LARGE_INTEGER*) & ftNow;
  1976. LARGE_INTEGER *pftime = (LARGE_INTEGER*) & pSettings->m_ftExpire;
  1977. GetSystemTimeAsFileTime(&ftNow);
  1978. hr = _StringFromVariant(&vaExpire, rgchExpire, ARRAYSIZE(rgchExpire));
  1979. if (SUCCEEDED(hr))
  1980. {
  1981. bRet = InternetTimeToSystemTime(rgchExpire, &st, 0);
  1982. SystemTimeToFileTime(&st, & pSettings->m_ftExpire);
  1983. }
  1984. if (FAILED(hr) || !bRet)
  1985. {
  1986. QUAD_PART(*pftime) = QUAD_PART(*pqwNow) + defExpiration;
  1987. }
  1988. // Enforce the limit on expiration time
  1989. __int64 qwDelta = (QUAD_PART(*pftime)) - (QUAD_PART(*pqwNow));
  1990. if (qwDelta<0 || qwDelta>maxExpiration)
  1991. QUAD_PART(*pftime) = QUAD_PART(*pqwNow) + maxExpiration;
  1992. // Make sure that the domain and path are valid
  1993. // The criteria is a mix of the cookie semantics as defined by RFC-2109 and Navigator
  1994. // compliant behaviour as implemented elsewhere in IE4
  1995. if (!_LegalPath(pucComp->lpszUrlPath, pSettings->m_rgchPath))
  1996. StrCpyN(pSettings->m_rgchPath, pucComp->lpszUrlPath, ARRAYSIZE(pSettings->m_rgchPath));
  1997. if (!_LegalDomain(pucComp->lpszHostName, pSettings->m_rgchDomain))
  1998. StrCpyN(pSettings->m_rgchDomain, pucComp->lpszHostName, ARRAYSIZE(pSettings->m_rgchDomain));
  1999. // Add a period at the beginning of the domain name if it is not equal to
  2000. // the host name
  2001. if (StrCmpI(pucComp->lpszHostName, pSettings->m_rgchDomain) &&
  2002. pSettings->m_rgchDomain[0] != '.')
  2003. {
  2004. StrCpyN(1+pSettings->m_rgchDomain, pSettings->m_rgchDomain, ARRAYSIZE(pSettings->m_rgchDomain)-1);
  2005. pSettings->m_rgchDomain[0] = '.';
  2006. }
  2007. pSettings->m_fExactDomain = ! StrCmpI(pSettings->m_rgchDomain, pucComp->lpszHostName);
  2008. if (StrCmp(pSettings->m_rgchPath, pucComp->lpszUrlPath))
  2009. {
  2010. pSettings->m_fExactPath = FALSE;
  2011. }
  2012. else
  2013. {
  2014. pSettings->m_fExactPath = pSettings->m_rgchPath[dwPathLen-1]!=TEXT('/');
  2015. }
  2016. return S_OK;
  2017. }
  2018. HRESULT
  2019. CIEFrameAuto::COpsProfile::_FormatSiteSettings(AccessSettings *pSettings, LPTSTR rgchOut, int cLimit)
  2020. {
  2021. TCHAR rgchFullName[MAX_URL_STRING];
  2022. TCHAR rgchTemp[MAX_URL_STRING];
  2023. StringCchPrintf(rgchFullName,
  2024. ARRAYSIZE(rgchFullName),
  2025. TEXT("http://%s%s"),
  2026. pSettings->m_rgchDomain,
  2027. pSettings->m_rgchPath);
  2028. FormatUrlForDisplay(rgchFullName, rgchTemp, cLimit, NULL, 0, FALSE, CP_ACP, NULL);
  2029. TCHAR *pchSiteName = StrStr(rgchTemp, TEXT("//"));
  2030. if (pchSiteName==NULL)
  2031. pchSiteName = rgchTemp;
  2032. else
  2033. pchSiteName += 2;
  2034. StrCpyN(rgchOut, pchSiteName, cLimit);
  2035. return S_OK;
  2036. }
  2037. // Attempts to use the given settings to determine the user response to the requests
  2038. // in the given list. If the domain and path for the settings is not applicable to
  2039. // for the given URL, returns FALSE.
  2040. BOOL
  2041. CIEFrameAuto::COpsProfile::_ApplySettings(AccessSettings *pac, URL_COMPONENTS *puc, HDPA hdpaReqList, DWORD *pdwLast)
  2042. {
  2043. if (!_DomainMatch(puc->lpszHostName, pac->m_rgchDomain) ||
  2044. !_PathMatch(puc->lpszUrlPath, pac->m_rgchPath))
  2045. return FALSE;
  2046. DWORD dwPathLen = lstrlen(pac->m_rgchPath);
  2047. for (int i=0; i<DPA_GetPtrCount(hdpaReqList); i++)
  2048. {
  2049. OPSRequestEntry *pCurrent = (OPSRequestEntry*) DPA_FastGetPtr(hdpaReqList,i);
  2050. int iVcIndex = _GetAttrIndexFromName(pCurrent->m_bstrName);
  2051. if (iVcIndex==INVALID_ATTRIBUTE_INDEX)
  2052. continue;
  2053. if (pdwLast[i]>=dwPathLen)
  2054. continue;
  2055. else
  2056. pdwLast[i] = dwPathLen;
  2057. BOOL fAllow = _ReadBitVector(pac->m_rgbStdAllow, iVcIndex);
  2058. BOOL fDeny = _ReadBitVector(pac->m_rgbStdDeny, iVcIndex);
  2059. if (fDeny)
  2060. {
  2061. pCurrent->denyRequest();
  2062. pCurrent->m_dwDecision = P3_SITELEVEL;
  2063. }
  2064. else if (fAllow)
  2065. {
  2066. pCurrent->grantRequest();
  2067. pCurrent->m_dwDecision = P3_SITELEVEL;
  2068. }
  2069. }
  2070. return TRUE;
  2071. }
  2072. BOOL
  2073. CIEFrameAuto::COpsProfile::_ReadSettingsFromRegistry(HKEY hkey, AccessSettings *pac)
  2074. {
  2075. DWORD dwError;
  2076. DWORD dwcb;
  2077. ZeroMemory(pac, sizeof(struct AccessSettings));
  2078. dwcb = sizeof(pac->m_rgbStdAllow);
  2079. dwError = RegQueryValueEx(hkey, rgszAllowTxt, NULL, NULL, (LPBYTE) pac->m_rgbStdAllow, &dwcb);
  2080. dwcb = sizeof(pac->m_rgbStdDeny);
  2081. dwError = RegQueryValueEx(hkey, rgszDenyTxt, NULL, NULL, (LPBYTE) pac->m_rgbStdDeny, &dwcb);
  2082. dwcb = sizeof(pac->m_rgchPath);
  2083. dwError = RegQueryValueEx(hkey, rgszPathTxt, NULL, NULL, (LPBYTE) pac->m_rgchPath, &dwcb);
  2084. dwcb = sizeof(pac->m_rgchDomain);
  2085. dwError = RegQueryValueEx(hkey, rgszDomainTxt, NULL, NULL, (LPBYTE) pac->m_rgchDomain, &dwcb);
  2086. return (dwError==ERROR_SUCCESS);
  2087. }
  2088. BOOL
  2089. CIEFrameAuto::COpsProfile::_WriteSettingsToRegistry(HKEY hkey, AccessSettings *pac)
  2090. {
  2091. RegSetValueEx(hkey, rgszAllowTxt, 0, REG_BINARY, pac->m_rgbStdAllow, sizeof(pac->m_rgbStdAllow));
  2092. RegSetValueEx(hkey, rgszDenyTxt, 0, REG_BINARY, pac->m_rgbStdDeny, sizeof(pac->m_rgbStdDeny));
  2093. RegSetValueEx(hkey, rgszPathTxt, 0, REG_SZ, (LPBYTE) pac->m_rgchPath, sizeof(pac->m_rgchPath));
  2094. RegSetValueEx(hkey, rgszDomainTxt, 0, REG_SZ, (LPBYTE) pac->m_rgchDomain, sizeof(pac->m_rgchDomain));
  2095. return TRUE;
  2096. }
  2097. // This function revokes all site permission given previously by deleting
  2098. // the registry entries for all the domains under the "P3Sites" key
  2099. // It is not a good idea to invoke recursive delete on the P3Sites key because
  2100. // the running instance of the navigator will end up with an invalid handle
  2101. HRESULT
  2102. CIEFrameAuto::COpsProfile::_ClearAllSettings(HWND hwnd)
  2103. {
  2104. DWORD dwAction;
  2105. DWORD dwError;
  2106. HKEY hP3Sites;
  2107. dwError = RegCreateKeyEx(HKEY_CURRENT_USER, rgszP3Sites, 0, NULL, REG_OPTION_NON_VOLATILE,
  2108. KEY_READ | DELETE, NULL, &hP3Sites, &dwAction);
  2109. DWORD dwIndex = 0;
  2110. DWORD dwcbVal;
  2111. TCHAR rgchName[MAX_PATH];
  2112. HDPA hdpaKeys = DPA_Create(0);
  2113. do
  2114. {
  2115. dwcbVal = ARRAYSIZE(rgchName);
  2116. dwError = RegEnumKeyEx(hP3Sites, dwIndex, rgchName, &dwcbVal, NULL, NULL, NULL, NULL);
  2117. if (dwError==ERROR_SUCCESS)
  2118. {
  2119. int cchSiteName = MAX_PATH;
  2120. LPTSTR pszSiteName = new TCHAR[cchSiteName];
  2121. if (pszSiteName)
  2122. {
  2123. StrCpyN(pszSiteName, rgchName, cchSiteName);
  2124. DPA_AppendPtr(hdpaKeys, pszSiteName);
  2125. }
  2126. }
  2127. dwIndex++;
  2128. }
  2129. while (dwError==ERROR_SUCCESS);
  2130. for (int i=0; i<DPA_GetPtrCount(hdpaKeys); i++)
  2131. {
  2132. LPTSTR pszSiteName = (LPTSTR) DPA_FastGetPtr(hdpaKeys, i);
  2133. SHDeleteKey(hP3Sites, pszSiteName);
  2134. delete pszSiteName;
  2135. }
  2136. DPA_Destroy(hdpaKeys);
  2137. hdpaKeys = NULL;
  2138. return S_OK;
  2139. }
  2140. BOOL
  2141. CIEFrameAuto::COpsProfile::_DifferentURL()
  2142. {
  2143. BSTR bstrCurrentURL = NULL;
  2144. HRESULT hr = _pAuto->get_LocationURL(&bstrCurrentURL);
  2145. BOOL fDifferent = (m_bstrLastURL!=NULL) && StrCmpW(bstrCurrentURL, m_bstrLastURL);
  2146. SysFreeString(bstrCurrentURL);
  2147. return fDifferent;
  2148. }
  2149. STDAPI ResetProfileSharing(HWND hwin)
  2150. {
  2151. return CIEFrameAuto::COpsProfile::_ClearAllSettings(hwin);
  2152. }