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.

432 lines
15 KiB

  1. // File: wabme.cpp
  2. #include "precomp.h"
  3. #include "wabme.h"
  4. #include "wabtags.h"
  5. #include "wabiab.h"
  6. BOOL GetKeyDataForProp(long nmProp, HKEY * phkey, LPTSTR * ppszSubKey, LPTSTR * ppszValue, BOOL *pfString)
  7. {
  8. // Default to ULS registry key
  9. *phkey = HKEY_CURRENT_USER;
  10. *ppszSubKey = ISAPI_KEY "\\" REGKEY_USERDETAILS;
  11. *pfString = TRUE;
  12. switch (nmProp)
  13. {
  14. default:
  15. WARNING_OUT(("GetKeyDataForProp - invalid argument %d", nmProp));
  16. return FALSE;
  17. case NM_SYSPROP_EMAIL_NAME: *ppszValue = REGVAL_ULS_EMAIL_NAME; break;
  18. case NM_SYSPROP_SERVER_NAME: *ppszValue = REGVAL_SERVERNAME; break;
  19. case NM_SYSPROP_RESOLVE_NAME: *ppszValue = REGVAL_ULS_RES_NAME; break;
  20. case NM_SYSPROP_FIRST_NAME: *ppszValue = REGVAL_ULS_FIRST_NAME; break;
  21. case NM_SYSPROP_LAST_NAME: *ppszValue = REGVAL_ULS_LAST_NAME; break;
  22. case NM_SYSPROP_USER_NAME: *ppszValue = REGVAL_ULS_NAME; break;
  23. case NM_SYSPROP_USER_LOCATION: *ppszValue = REGVAL_ULS_LOCATION_NAME; break;
  24. case NM_SYSPROP_USER_COMMENTS: *ppszValue = REGVAL_ULS_COMMENTS_NAME; break;
  25. } /* switch (nmProp) */
  26. return TRUE;
  27. }
  28. /* W A B R E A D M E */
  29. /*-------------------------------------------------------------------------
  30. %%Function: WabReadMe
  31. Prep the NetMeeting registry settings with the data from the WAB "Me" entry.
  32. This function is also used by the main UI wizard.
  33. -------------------------------------------------------------------------*/
  34. int WabReadMe(void)
  35. {
  36. CWABME * pWab = new CWABME;
  37. if (NULL == pWab)
  38. return FALSE;
  39. HRESULT hr = pWab->ReadMe();
  40. delete pWab;
  41. return SUCCEEDED(hr);
  42. }
  43. /* R E A D M E */
  44. /*-------------------------------------------------------------------------
  45. %%Function: ReadMe
  46. Read the WAB data, if it exists (but don't create a default "ME")
  47. -------------------------------------------------------------------------*/
  48. HRESULT CWABME::ReadMe(void)
  49. {
  50. if (NULL == m_pWabObject)
  51. {
  52. return E_FAIL; // no wab installed?
  53. }
  54. SBinary eid;
  55. HRESULT hr = m_pWabObject->GetMe(m_pAdrBook, AB_NO_DIALOG | WABOBJECT_ME_NOCREATE, NULL, &eid, 0);
  56. if (SUCCEEDED(hr))
  57. {
  58. ULONG ulObjType = 0;
  59. LPMAPIPROP pMapiProp = NULL;
  60. hr = m_pAdrBook->OpenEntry(eid.cb, (LPENTRYID) eid.lpb, NULL, 0,
  61. &ulObjType, (LPUNKNOWN *)&pMapiProp);
  62. if (SUCCEEDED(hr))
  63. {
  64. if (NULL != pMapiProp)
  65. {
  66. EnsurePropTags(pMapiProp);
  67. UpdateRegEntry(pMapiProp, NM_SYSPROP_EMAIL_NAME, PR_EMAIL_ADDRESS);
  68. UpdateRegEntry(pMapiProp, NM_SYSPROP_FIRST_NAME, PR_GIVEN_NAME);
  69. UpdateRegEntry(pMapiProp, NM_SYSPROP_LAST_NAME, PR_SURNAME);
  70. UpdateRegEntry(pMapiProp, NM_SYSPROP_USER_NAME, PR_DISPLAY_NAME);
  71. UpdateRegEntry(pMapiProp, NM_SYSPROP_USER_LOCATION, PR_LOCALITY);
  72. UpdateRegEntry(pMapiProp, NM_SYSPROP_USER_COMMENTS, PR_COMMENT);
  73. UpdateRegEntryCategory(pMapiProp);
  74. UpdateRegEntryServer(pMapiProp);
  75. pMapiProp->Release();
  76. }
  77. }
  78. }
  79. return hr;
  80. }
  81. /* U P D A T E R E G E N T R Y */
  82. /*-------------------------------------------------------------------------
  83. %%Function: UpdateRegEntry
  84. -------------------------------------------------------------------------*/
  85. HRESULT CWABME::UpdateRegEntry(LPMAPIPROP pMapiProp, NM_SYSPROP nmProp, ULONG uProp)
  86. {
  87. HKEY hkey;
  88. LPTSTR pszSubKey;
  89. LPTSTR pszValue;
  90. BOOL fString;
  91. ULONG cValues;
  92. LPSPropValue pData;
  93. SPropTagArray prop;
  94. prop.cValues = 1;
  95. prop.aulPropTag[0] = uProp;
  96. HRESULT hr = pMapiProp->GetProps(&prop, 0, &cValues, &pData);
  97. if (S_OK == hr)
  98. {
  99. if ((1 == cValues) && !FEmptySz(pData->Value.lpszA))
  100. {
  101. if (GetKeyDataForProp(nmProp, &hkey, &pszSubKey, &pszValue, &fString))
  102. {
  103. ASSERT((HKEY_CURRENT_USER == hkey) && fString);
  104. RegEntry re(pszSubKey, hkey);
  105. re.SetValue(pszValue, pData->Value.lpszA);
  106. WARNING_OUT(("Updated - %s to [%s]", pszValue, pData->Value.lpszA));
  107. }
  108. }
  109. m_pWabObject->FreeBuffer(pData);
  110. }
  111. return hr;
  112. }
  113. // Update the user's server and resolved names in the registry
  114. // based on the "ME" data
  115. HRESULT CWABME::UpdateRegEntryServer(LPMAPIPROP pMapiProp)
  116. {
  117. HRESULT hr;
  118. HKEY hkey;
  119. LPTSTR pszSubKey;
  120. LPTSTR pszValue;
  121. BOOL fString;
  122. ULONG cValues;
  123. LPSPropValue pData;
  124. SPropTagArray propTag;
  125. propTag.cValues = 1;
  126. propTag.aulPropTag[0] = Get_PR_NM_DEFAULT();
  127. ULONG iDefault = 0; // the default server
  128. hr = pMapiProp->GetProps(&propTag, 0, &cValues, &pData);
  129. if (S_OK == hr)
  130. {
  131. iDefault = pData->Value.ul;
  132. m_pWabObject->FreeBuffer(pData);
  133. }
  134. // ILS server data is in an array of strings like "callto://server/email@address"
  135. propTag.aulPropTag[0] = Get_PR_NM_ADDRESS();
  136. hr = pMapiProp->GetProps(&propTag, 0, &cValues, &pData);
  137. if (S_OK == hr)
  138. {
  139. SLPSTRArray * pMVszA = &(pData->Value.MVszA);
  140. if ((0 != cValues) && (0 != pMVszA->cValues))
  141. {
  142. ASSERT(iDefault < pMVszA->cValues);
  143. LPCTSTR pszAddr = pMVszA->lppszA[iDefault];
  144. pszAddr = PszSkipCallTo(pszAddr);
  145. // Resolve Name is "server/email@address"
  146. if (GetKeyDataForProp(NM_SYSPROP_RESOLVE_NAME, &hkey, &pszSubKey, &pszValue, &fString))
  147. {
  148. ASSERT((HKEY_CURRENT_USER == hkey) && fString);
  149. RegEntry re(pszSubKey, hkey);
  150. re.SetValue(pszValue, pszAddr);
  151. WARNING_OUT(("Updated - %s to [%s]", pszValue, pszAddr));
  152. }
  153. LPCTSTR pszSlash = _StrChr(pszAddr, _T('/'));
  154. if (NULL != pszSlash)
  155. {
  156. pszSlash++;
  157. TCHAR szServer[CCHMAXSZ_SERVER];
  158. lstrcpyn(szServer, pszAddr, (int)min(CCHMAX(szServer), pszSlash - pszAddr));
  159. if (GetKeyDataForProp(NM_SYSPROP_SERVER_NAME, &hkey, &pszSubKey, &pszValue, &fString))
  160. {
  161. ASSERT((HKEY_CURRENT_USER == hkey) && fString);
  162. RegEntry re(pszSubKey, hkey);
  163. re.SetValue(pszValue, szServer);
  164. WARNING_OUT(("Updated - %s to [%s]", pszValue, szServer));
  165. }
  166. }
  167. }
  168. m_pWabObject->FreeBuffer(pData);
  169. }
  170. return hr;
  171. }
  172. // Update the user's category in the registry
  173. // based on the WAB value for the "ME" NetMeeting user category
  174. HRESULT CWABME::UpdateRegEntryCategory(LPMAPIPROP pMapiProp)
  175. {
  176. HKEY hkey;
  177. LPTSTR pszSubKey;
  178. LPTSTR pszValue;
  179. BOOL fString;
  180. ULONG cValues;
  181. LPSPropValue pData;
  182. SPropTagArray prop;
  183. prop.cValues = 1;
  184. prop.aulPropTag[0] = Get_PR_NM_CATEGORY();
  185. HRESULT hr = pMapiProp->GetProps(&prop, 0, &cValues, &pData);
  186. if (S_OK == hr)
  187. {
  188. if (1 == cValues)
  189. {
  190. if (GetKeyDataForProp(NM_SYSPROP_USER_CATEGORY, &hkey, &pszSubKey, &pszValue, &fString))
  191. {
  192. ASSERT((HKEY_CURRENT_USER == hkey) && !fString);
  193. RegEntry re(pszSubKey, hkey);
  194. re.SetValue(pszValue, pData->Value.l);
  195. WARNING_OUT(("Updated - category to %d", pData->Value.l));
  196. }
  197. }
  198. m_pWabObject->FreeBuffer(pData);
  199. }
  200. return hr;
  201. }
  202. /* W A B W R I T E M E */
  203. /*-------------------------------------------------------------------------
  204. %%Function: WabWriteMe
  205. Write the current NM settings to the WAB "Me" entry.
  206. This function is also used by the main UI wizard.
  207. -------------------------------------------------------------------------*/
  208. int WabWriteMe(void)
  209. {
  210. CWABME * pWab = new CWABME;
  211. if (NULL == pWab)
  212. return FALSE;
  213. HRESULT hr = pWab->WriteMe();
  214. delete pWab;
  215. return SUCCEEDED(hr);
  216. }
  217. /* W R I T E M E */
  218. /*-------------------------------------------------------------------------
  219. %%Function: WriteMe
  220. Write the "ME" data only if no entry already exists.
  221. -------------------------------------------------------------------------*/
  222. HRESULT CWABME::WriteMe(void)
  223. {
  224. return( S_OK );
  225. if (NULL == m_pWabObject)
  226. {
  227. return E_FAIL; // no wab installed?
  228. }
  229. SBinary eid;
  230. HRESULT hr = m_pWabObject->GetMe(m_pAdrBook, AB_NO_DIALOG, NULL, &eid, 0);
  231. if (SUCCEEDED(hr))
  232. {
  233. ULONG ulObjType = 0;
  234. LPMAPIPROP pMapiProp = NULL;
  235. hr = m_pAdrBook->OpenEntry(eid.cb, (LPENTRYID) eid.lpb, NULL, MAPI_MODIFY,
  236. &ulObjType, (LPUNKNOWN *)&pMapiProp);
  237. if (SUCCEEDED(hr))
  238. {
  239. if (NULL != pMapiProp)
  240. {
  241. EnsurePropTags(pMapiProp);
  242. UpdateProp(pMapiProp, NM_SYSPROP_FIRST_NAME, PR_GIVEN_NAME);
  243. UpdateProp(pMapiProp, NM_SYSPROP_LAST_NAME, PR_SURNAME);
  244. UpdateProp(pMapiProp, NM_SYSPROP_USER_NAME, PR_DISPLAY_NAME);
  245. UpdateProp(pMapiProp, NM_SYSPROP_USER_CITY, PR_LOCALITY); // Business
  246. UpdateProp(pMapiProp, NM_SYSPROP_USER_CITY, PR_HOME_ADDRESS_CITY); // Personal
  247. UpdateProp(pMapiProp, NM_SYSPROP_USER_COMMENTS, PR_COMMENT);
  248. UpdatePropServer(pMapiProp);
  249. hr = pMapiProp->SaveChanges(FORCE_SAVE);
  250. pMapiProp->Release();
  251. }
  252. }
  253. }
  254. return hr;
  255. }
  256. /* U P D A T E P R O P */
  257. /*-------------------------------------------------------------------------
  258. %%Function: UpdateProp
  259. Update a WAB properly based on the corresponding registry string.
  260. -------------------------------------------------------------------------*/
  261. HRESULT CWABME::UpdateProp(LPMAPIPROP pMapiProp, NM_SYSPROP nmProp, ULONG uProp)
  262. {
  263. HKEY hkey;
  264. LPTSTR pszSubKey;
  265. LPTSTR pszValue;
  266. BOOL fString;
  267. HRESULT hr = GetKeyDataForProp(nmProp, &hkey, &pszSubKey, &pszValue, &fString) ? S_OK : E_FAIL;
  268. if (SUCCEEDED(hr))
  269. {
  270. ASSERT((HKEY_CURRENT_USER == hkey) && fString);
  271. RegEntry re(pszSubKey, hkey);
  272. LPTSTR psz = re.GetString(pszValue);
  273. if (!FEmptySz(psz))
  274. {
  275. hr = UpdatePropSz(pMapiProp, uProp, psz, FALSE);
  276. }
  277. }
  278. return hr;
  279. }
  280. // Update a WAB property to the given string.
  281. // Replace existing data only if fReplace is TRUE
  282. HRESULT CWABME::UpdatePropSz(LPMAPIPROP pMapiProp, ULONG uProp, LPTSTR psz, BOOL fReplace)
  283. {
  284. HRESULT hr;
  285. if (!fReplace)
  286. { // Don't replace existing data
  287. ULONG cValues;
  288. LPSPropValue pData;
  289. SPropTagArray propTag;
  290. propTag.cValues = 1;
  291. propTag.aulPropTag[0] = uProp;
  292. hr = pMapiProp->GetProps(&propTag, 0, &cValues, &pData);
  293. if (S_OK == hr)
  294. {
  295. if ((1 == cValues) && !FEmptySz(pData->Value.lpszA))
  296. {
  297. hr = S_FALSE;
  298. }
  299. m_pWabObject->FreeBuffer(pData);
  300. if (S_OK != hr)
  301. return hr;
  302. }
  303. }
  304. SPropValue propVal;
  305. propVal.ulPropTag = uProp;
  306. propVal.Value.lpszA = psz;
  307. hr = pMapiProp->SetProps(1, &propVal, NULL);
  308. WARNING_OUT(("Updated - property %08X to [%s]", uProp, propVal.Value.lpszA));
  309. return hr;
  310. }
  311. static const TCHAR g_pcszSMTP[] = TEXT("SMTP"); // value for PR_ADDRTYPE
  312. // Update the default WAB "callto" information
  313. HRESULT CWABME::UpdatePropServer(LPMAPIPROP pMapiProp)
  314. {
  315. HKEY hkey;
  316. LPTSTR pszSubKey;
  317. LPTSTR pszValue;
  318. BOOL fString;
  319. TCHAR szServer[CCHMAXSZ_SERVER];
  320. GetKeyDataForProp(NM_SYSPROP_SERVER_NAME, &hkey, &pszSubKey, &pszValue, &fString);
  321. RegEntry re(pszSubKey, hkey);
  322. lstrcpyn(szServer, re.GetString(pszValue), CCHMAXSZ_SERVER);
  323. // Save the email address
  324. LPTSTR pszEmail = re.GetString(REGVAL_ULS_EMAIL_NAME);
  325. if (S_OK == UpdatePropSz(pMapiProp, PR_EMAIL_ADDRESS, pszEmail, FALSE))
  326. {
  327. UpdatePropSz(pMapiProp, PR_ADDRTYPE, (LPTSTR) g_pcszSMTP, FALSE);
  328. }
  329. // Create the full "callto://server/[email protected]"
  330. TCHAR sz[MAX_PATH*2];
  331. if (!FCreateCallToSz(szServer, pszEmail, sz, CCHMAX(sz)))
  332. return E_OUTOFMEMORY;
  333. LPTSTR psz = sz;
  334. SPropValue propVal;
  335. propVal.ulPropTag = Get_PR_NM_ADDRESS();
  336. propVal.Value.MVszA.cValues = 1;
  337. propVal.Value.MVszA.lppszA = &psz;
  338. HRESULT hr = pMapiProp->SetProps(1, &propVal, NULL);
  339. WARNING_OUT(("Updated - NM server [%s]", sz));
  340. if (SUCCEEDED(hr))
  341. {
  342. // Set this as the default
  343. propVal.ulPropTag = Get_PR_NM_DEFAULT();
  344. propVal.Value.ul = 0;
  345. hr = pMapiProp->SetProps(1, &propVal, NULL);
  346. }
  347. return hr;
  348. }