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.

1095 lines
28 KiB

  1. // bllist.cpp : Implementation of the CMsgrList
  2. // Messenger integration to OE
  3. // Created 05/07/98 by YST
  4. //
  5. #include "pch.hxx"
  6. #include "bllist.h"
  7. #include "basicim2.h"
  8. #include "msoert.h"
  9. #include "blobevnt.h"
  10. #include <string.h>
  11. #include "shlwapi.h"
  12. #include "shlwapip.h"
  13. static CMsgrList * sg_pMsgrList = NULL; // global for buddy list
  14. int const CCHMAX = 512;
  15. CMsgrList::CMsgrList()
  16. {
  17. m_pblInfRoot = NULL;
  18. m_pblInfLast = NULL;
  19. m_pWndLRoot = NULL;
  20. m_pWndLLast = NULL;
  21. m_nRef = 1;
  22. m_spMsgrObject = NULL;
  23. m_pMsgrObjectEvents = NULL;
  24. m_MsgrCookie = 0xffffffff;
  25. }
  26. CMsgrList::~CMsgrList()
  27. {
  28. Assert(m_nRef == 0);
  29. if(m_pblInfRoot)
  30. {
  31. FreeMsgrInfoList(m_pblInfRoot);
  32. m_pblInfRoot = NULL;
  33. m_pblInfLast = NULL;
  34. }
  35. if(m_pWndLRoot)
  36. FreeWndList(m_pWndLRoot);
  37. if(m_pMsgrObjectEvents)
  38. {
  39. m_pMsgrObjectEvents->DelListOfBuddies();
  40. if (m_MsgrCookie != 0xffffffff && m_spMsgrObject != NULL)
  41. m_spMsgrObject->UnadviseOE(m_MsgrCookie);
  42. m_pMsgrObjectEvents->Release();
  43. m_pMsgrObjectEvents = NULL;
  44. }
  45. }
  46. void CMsgrList::Release()
  47. {
  48. Assert(m_nRef > 0);
  49. m_nRef--;
  50. if(m_nRef == 0)
  51. {
  52. DelAllEntries(NULL);
  53. delete this;
  54. sg_pMsgrList = NULL;
  55. }
  56. }
  57. // Check and Init Msgr
  58. HRESULT CMsgrList::CheckAndInitMsgr()
  59. {
  60. if(m_pblInfRoot)
  61. return(S_OK);
  62. else
  63. {
  64. // Do Initialization again
  65. if(!m_pMsgrObjectEvents)
  66. {
  67. if(HrInitMsgr() == S_OK)
  68. return(FillList());
  69. else
  70. return S_FALSE;
  71. }
  72. else
  73. return(FillList());
  74. }
  75. return S_FALSE; //???
  76. }
  77. // Free list of client UI window
  78. void CMsgrList::FreeWndList(LPMWNDLIST pWndEntry)
  79. {
  80. if(pWndEntry->pNext)
  81. FreeWndList(pWndEntry->pNext);
  82. MemFree(pWndEntry);
  83. pWndEntry = NULL;
  84. }
  85. // Free list buddies
  86. void CMsgrList::FreeMsgrInfoList(LPMINFO pEntry)
  87. {
  88. if(pEntry == NULL)
  89. return;
  90. if(pEntry->pNext)
  91. FreeMsgrInfoList(pEntry->pNext);
  92. MemFree(pEntry->pchMsgrName);
  93. MemFree(pEntry->pchID);
  94. MemFree(pEntry->pchHomePhone);
  95. MemFree(pEntry->pchWorkPhone);
  96. MemFree(pEntry->pchMobilePhone);
  97. MemFree(pEntry);
  98. pEntry = NULL;
  99. }
  100. // Remove buddy from list
  101. void CMsgrList::RemoveMsgrInfoEntry(LPMINFO pEntry)
  102. {
  103. if(m_pblInfLast == pEntry)
  104. m_pblInfLast = pEntry->pPrev;
  105. if(m_pblInfRoot == pEntry)
  106. m_pblInfRoot = pEntry->pNext;
  107. MemFree(pEntry->pchMsgrName);
  108. MemFree(pEntry->pchID);
  109. MemFree(pEntry->pchHomePhone);
  110. MemFree(pEntry->pchWorkPhone);
  111. MemFree(pEntry->pchMobilePhone);
  112. if(pEntry->pPrev)
  113. (pEntry->pPrev)->pNext = pEntry->pNext;
  114. if(pEntry->pNext)
  115. (pEntry->pNext)->pPrev = pEntry->pPrev;
  116. MemFree(pEntry);
  117. pEntry = NULL;
  118. }
  119. // Check that item is Online starting point for search is pEntry
  120. BOOL CMsgrList::IsContactOnline(WCHAR *pchID, LPMINFO pEntry)
  121. {
  122. if(!pEntry)
  123. return(FALSE);
  124. if(!lstrcmpiW(pEntry->pchID, pchID))
  125. {
  126. if((pEntry->nStatus != BIMSTATE_OFFLINE) && (pEntry->nStatus != BIMSTATE_INVISIBLE))
  127. return(TRUE);
  128. else
  129. return(FALSE);
  130. }
  131. else if(pEntry->pNext)
  132. return(IsContactOnline(pchID, pEntry->pNext));
  133. else
  134. return(FALSE);
  135. }
  136. // Find entry with ID == szID and remove this from list
  137. void CMsgrList::FindAndRemoveBlEntry(WCHAR *szID, LPMINFO pEntry)
  138. {
  139. if(!pEntry)
  140. pEntry = m_pblInfRoot;
  141. if(!pEntry)
  142. return;
  143. if(!lstrcmpiW(pEntry->pchID, szID))
  144. {
  145. RemoveMsgrInfoEntry(pEntry);
  146. }
  147. else if(pEntry->pNext)
  148. FindAndRemoveBlEntry(szID, pEntry->pNext);
  149. }
  150. // Send message to all registred client UI windows
  151. void CMsgrList::SendMsgToAllUIWnd(UINT msg, WPARAM wParam, LPARAM lParam, LPMWNDLIST pWndEntry)
  152. {
  153. if(!pWndEntry)
  154. pWndEntry = m_pWndLRoot;
  155. if(!pWndEntry)
  156. return;
  157. if(pWndEntry->pNext)
  158. SendMsgToAllUIWnd(msg, wParam, lParam, pWndEntry->pNext);
  159. ::SendMessage(pWndEntry->hWndUI, msg, wParam, lParam);
  160. }
  161. // Add client Window to list
  162. void CMsgrList::AddWndEntry(HWND hWnd)
  163. {
  164. if(m_pWndLLast == NULL)
  165. {
  166. // Really first entry
  167. Assert(!m_pWndLRoot);
  168. if (!MemAlloc((LPVOID *) &m_pWndLLast, sizeof(MsgrWndList)))
  169. return;
  170. m_pWndLRoot = m_pWndLLast;
  171. m_pWndLLast->pPrev = NULL;
  172. }
  173. else
  174. {
  175. if (!MemAlloc((LPVOID *) &(m_pWndLLast->pNext), sizeof(MsgrWndList)))
  176. return;
  177. (m_pWndLLast->pNext)->pPrev = m_pWndLLast;
  178. m_pWndLLast = m_pWndLLast->pNext;
  179. }
  180. m_pWndLLast->pNext = NULL;
  181. m_pWndLLast->hWndUI = hWnd;
  182. }
  183. // remove entry from WND list
  184. void CMsgrList::RemoveWndEntry(LPMWNDLIST pWndEntry)
  185. {
  186. if(m_pWndLLast == pWndEntry)
  187. m_pWndLLast = pWndEntry->pPrev;
  188. if(m_pWndLRoot == pWndEntry)
  189. m_pWndLRoot = pWndEntry->pNext;
  190. if(pWndEntry->pPrev)
  191. (pWndEntry->pPrev)->pNext = pWndEntry->pNext;
  192. if(pWndEntry->pNext)
  193. (pWndEntry->pNext)->pPrev = pWndEntry->pPrev;
  194. MemFree(pWndEntry);
  195. pWndEntry = NULL;
  196. }
  197. // Find entry and remove it from list
  198. void CMsgrList::FindAndDelEntry(HWND hWnd, LPMWNDLIST pWndEntry)
  199. {
  200. if(!pWndEntry)
  201. pWndEntry = m_pWndLRoot;
  202. if(!pWndEntry)
  203. return;
  204. if(pWndEntry->hWndUI == hWnd)
  205. {
  206. RemoveWndEntry(pWndEntry);
  207. }
  208. else if(pWndEntry->pNext)
  209. FindAndDelEntry(hWnd, pWndEntry->pNext);
  210. }
  211. void CMsgrList::DelAllEntries(LPMWNDLIST pWndEntry)
  212. {
  213. if(pWndEntry == NULL)
  214. pWndEntry = m_pWndLRoot;
  215. if(pWndEntry == NULL)
  216. return;
  217. if(pWndEntry->pNext)
  218. DelAllEntries(pWndEntry->pNext);
  219. RemoveWndEntry(pWndEntry);
  220. }
  221. HRESULT CMsgrList::HrInitMsgr(void)
  222. {
  223. //create the COM server and connect to it
  224. HRESULT hr = S_OK;
  225. Assert(m_pMsgrObjectEvents == NULL);
  226. m_spMsgrObject = NULL;
  227. hr = CoCreateInstance(CLSID_BasicIMObject, NULL,CLSCTX_LOCAL_SERVER,
  228. IID_IBasicIM, (LPVOID *)&m_spMsgrObject);
  229. if(FAILED(hr))
  230. {
  231. return(hr);
  232. }
  233. m_pMsgrObjectEvents = new CMsgrObjectEvents();
  234. if (m_pMsgrObjectEvents == NULL)
  235. {
  236. hr = E_OUTOFMEMORY;
  237. }
  238. else
  239. {
  240. hr = m_spMsgrObject->AdviseOE(m_pMsgrObjectEvents, &m_MsgrCookie);
  241. //We, of course, have to release m_pMsgrObjectEvents when we are finished with it
  242. if(FAILED(hr))
  243. {
  244. m_pMsgrObjectEvents->Release();
  245. m_pMsgrObjectEvents = NULL;
  246. }
  247. else
  248. m_pMsgrObjectEvents->SetListOfBuddies(this);
  249. }
  250. return(hr);
  251. }
  252. // Set new buddy status (online/ofline/etc. and redraw list view entry)
  253. HRESULT CMsgrList::EventUserStateChanged(IBasicIMUser * pUser)
  254. {
  255. BSTR bstrID;
  256. HRESULT hr = pUser->get_LogonName(&bstrID);
  257. BOOL fFinded = FALSE;
  258. if (SUCCEEDED(hr))
  259. {
  260. BIMSTATE nState = BIMSTATE_UNKNOWN;
  261. if(SUCCEEDED(pUser->get_State(&nState)))
  262. {
  263. LPMINFO pInf = m_pblInfRoot;
  264. if(!pInf)
  265. {
  266. // MemFree(pszID);
  267. SysFreeString(bstrID);
  268. return(hr);
  269. }
  270. // Find buddy in our list
  271. do
  272. {
  273. if(!lstrcmpiW(pInf->pchID, bstrID))
  274. {
  275. fFinded = TRUE;
  276. break;
  277. }
  278. } while ((pInf = pInf->pNext) != NULL);
  279. if(fFinded)
  280. {
  281. pInf->nStatus = nState;
  282. SendMsgToAllUIWnd(WM_USER_STATUS_CHANGED, (WPARAM) nState, (LPARAM) bstrID);
  283. }
  284. }
  285. }
  286. SysFreeString(bstrID);
  287. return(hr);
  288. }
  289. // Baddy was removed
  290. HRESULT CMsgrList::EventUserRemoved(IBasicIMUser * pUser)
  291. {
  292. BSTR bstrID;
  293. HRESULT hr = pUser->get_LogonName(&bstrID);
  294. if (SUCCEEDED(hr))
  295. {
  296. Assert(m_nRef > 0);
  297. SendMsgToAllUIWnd(WM_USER_MUSER_REMOVED, (WPARAM) 0, (LPARAM) bstrID);
  298. FindAndRemoveBlEntry(bstrID);
  299. }
  300. SysFreeString(bstrID);
  301. return(hr);
  302. }
  303. // Event: buddy name was changed
  304. // Add buddy to our list and send message to UI windows about this.
  305. HRESULT CMsgrList::EventUserNameChanged(IBasicIMUser * pUser)
  306. {
  307. BSTR bstrName;
  308. BSTR bstrID;
  309. BOOL fFinded = FALSE;
  310. HRESULT hr = pUser->get_LogonName(&bstrID);
  311. hr = pUser->get_FriendlyName(&bstrName);
  312. if (SUCCEEDED(hr))
  313. {
  314. LPMINFO pInf = m_pblInfRoot;
  315. // Find buddy in our list
  316. do
  317. {
  318. if(!lstrcmpiW(pInf->pchID, bstrID))
  319. {
  320. fFinded = TRUE;
  321. break;
  322. }
  323. } while ((pInf = pInf->pNext) != NULL);
  324. if(fFinded)
  325. {
  326. if(pInf->pchMsgrName)
  327. MemFree(pInf->pchMsgrName); // Free prev name
  328. pInf->pchMsgrName = bstrName;
  329. SendMsgToAllUIWnd(WM_USER_NAME_CHANGED, (WPARAM) 0, (LPARAM) pInf);
  330. }
  331. }
  332. SysFreeString(bstrName);
  333. SysFreeString(bstrID);
  334. return(hr);
  335. }
  336. // Event: local state changed
  337. HRESULT CMsgrList::EventLocalStateChanged(BIMSTATE State)
  338. {
  339. SendMsgToAllUIWnd(WM_LOCAL_STATUS_CHANGED, (WPARAM) 0, (LPARAM) State);
  340. return(S_OK);
  341. }
  342. // Event: buddy was added
  343. // Add buddy to our list and send message to UI windows about this.
  344. HRESULT CMsgrList::EventUserAdded(IBasicIMUser * pUser)
  345. {
  346. BSTR bstrName;
  347. BSTR bstrID;
  348. WCHAR wszHome[CCHMAX] = {0};
  349. WCHAR wszWork[CCHMAX] = {0};
  350. WCHAR wszMobile[CCHMAX] = {0};
  351. WCHAR *pH, *pW, *pM;
  352. HRESULT hr = pUser->get_LogonName(&bstrID);
  353. hr = pUser->get_FriendlyName(&bstrName);
  354. if (SUCCEEDED(hr))
  355. {
  356. BIMSTATE nState = BIMSTATE_UNKNOWN;
  357. if(SUCCEEDED(pUser->get_State(&nState)))
  358. {
  359. CComPtr<IBasicIMUser2> spUser2;
  360. if(SUCCEEDED(pUser->QueryInterface(IID_IBasicIMUser2, (void **) &spUser2)))
  361. {
  362. VARIANT var;
  363. var.vt = VT_BSTR;
  364. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_HOME_PHONE_NUMBER, &var)))
  365. {
  366. StrCpyNW(wszHome, var.bstrVal, CCHMAX - 1);
  367. wszHome[CCHMAX - 1] = L'\0';
  368. pH = wszHome;
  369. }
  370. else
  371. pH = NULL;
  372. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_WORK_PHONE_NUMBER, &var)))
  373. {
  374. StrCpyNW(wszWork, var.bstrVal, CCHMAX - 1);
  375. wszWork[CCHMAX - 1] = L'\0';
  376. pW = wszWork;
  377. }
  378. else
  379. pW = NULL;
  380. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_MOBILE_PHONE_NUMBER, &var)))
  381. {
  382. StrCpyNW(wszMobile, var.bstrVal, CCHMAX - 1);
  383. wszMobile[CCHMAX - 1] = L'\0';
  384. pM = wszMobile;
  385. }
  386. else
  387. pM = NULL;
  388. }
  389. AddMsgrListEntry(bstrName, bstrID, nState,pH, pW, pM);
  390. SendMsgToAllUIWnd(WM_USER_MUSER_ADDED, (WPARAM) 0, (LPARAM) m_pblInfLast);
  391. }
  392. }
  393. SysFreeString(bstrName);
  394. SysFreeString(bstrID);
  395. return(hr);
  396. }
  397. HRESULT CMsgrList::EventLogoff()
  398. {
  399. SendMsgToAllUIWnd(WM_MSGR_LOGOFF, (WPARAM) 0, (LPARAM) 0);
  400. FreeMsgrInfoList(m_pblInfRoot);
  401. m_pblInfRoot = NULL;
  402. m_pblInfLast = NULL;
  403. return(S_OK);
  404. }
  405. HRESULT CMsgrList::EventAppShutdown()
  406. {
  407. SendMsgToAllUIWnd(WM_MSGR_SHUTDOWN, (WPARAM) 0, (LPARAM) 0);
  408. return(S_OK);
  409. }
  410. HRESULT CMsgrList::EventLogonResult(long lResult)
  411. {
  412. if(!m_pblInfRoot && SUCCEEDED(lResult))
  413. FillList();
  414. else if(SUCCEEDED(lResult))
  415. {
  416. // EnterCriticalSection(&g_csMsgrList);
  417. FreeMsgrInfoList(m_pblInfRoot);
  418. m_pblInfRoot = NULL;
  419. m_pblInfLast = NULL;
  420. FillList();
  421. // LeaveCriticalSection(&g_csMsgrList);
  422. }
  423. SendMsgToAllUIWnd(WM_MSGR_LOGRESULT, (WPARAM) 0, (LPARAM) lResult);
  424. return(S_OK);
  425. }
  426. // return number of buddies
  427. long CMsgrList::GetCount()
  428. {
  429. HRESULT hr = E_FAIL;
  430. long lCount = 0;
  431. CComPtr<IBasicIMUsers> spBuddies;
  432. if (!m_spMsgrObject)
  433. goto Exit;
  434. hr = m_spMsgrObject->get_ContactList(&spBuddies);
  435. if( FAILED(hr) )
  436. {
  437. // g_AddToLog(LOG_LEVEL_COM, _T("Buddies() failed, hr = %s"), g_GetErrorString(hr));
  438. Assert(FALSE);
  439. goto Exit;
  440. }
  441. //Iterate through the MsgrList make sure that the buddy we wish to remove is effectively in the list
  442. hr = spBuddies->get_Count(&lCount);
  443. Assert(SUCCEEDED(hr));
  444. Exit:
  445. return(lCount);
  446. }
  447. HRESULT CMsgrList::FillList()
  448. {
  449. long lCount = 0;
  450. IBasicIMUser* pUser = NULL;
  451. WCHAR wszHome[CCHMAX] = {0};
  452. WCHAR wszWork[CCHMAX] = {0};
  453. WCHAR wszMobile[CCHMAX] = {0};
  454. //process the Buddies list
  455. IBasicIMUsers *pBuddies = NULL;
  456. if(!m_spMsgrObject)
  457. return S_FALSE;
  458. HRESULT hr = m_spMsgrObject->get_ContactList(&pBuddies);
  459. if(FAILED(hr))
  460. {
  461. FilErr:
  462. if(m_pMsgrObjectEvents)
  463. {
  464. m_pMsgrObjectEvents->DelListOfBuddies();
  465. if (m_MsgrCookie != 0xffffffff)
  466. {
  467. if (m_spMsgrObject)
  468. m_spMsgrObject->UnadviseOE(m_MsgrCookie);
  469. m_MsgrCookie = 0xffffffff;
  470. }
  471. m_pMsgrObjectEvents->Release();
  472. m_pMsgrObjectEvents = NULL;
  473. }
  474. return(hr);
  475. }
  476. //Check the current state (in case the client was already running and was
  477. //not in the logoff state
  478. BIMSTATE lState = BIMSTATE_OFFLINE;
  479. if (m_spMsgrObject)
  480. hr = m_spMsgrObject->get_LocalState(&lState);
  481. if(FAILED(hr) /*|| lState == BIMSTATE_OFFLINE !(lState == BIMSTATE_ONLINE || lState == BIMSTATE_BUSY || lState == BIMSTATE_INVISIBLE)*/)
  482. {
  483. Err2:
  484. pBuddies->Release();
  485. pBuddies = NULL;
  486. goto FilErr;
  487. }
  488. else if(lState == BIMSTATE_OFFLINE)
  489. {
  490. if(FAILED(AutoLogon()))
  491. goto Err2;
  492. }
  493. if(!SUCCEEDED(pBuddies->get_Count(&lCount)))
  494. goto Err2;
  495. for (int i = 0; i < lCount; i++)
  496. {
  497. hr = pBuddies->Item(i, &pUser);
  498. if(SUCCEEDED(hr))
  499. {
  500. // EventUserAdded(pUser);
  501. BSTR bstrName;
  502. BSTR bstrID;
  503. hr = pUser->get_LogonName(&bstrID);
  504. hr = pUser->get_FriendlyName(&bstrName);
  505. if (SUCCEEDED(hr))
  506. {
  507. BIMSTATE nState = BIMSTATE_UNKNOWN;
  508. if(SUCCEEDED(pUser->get_State(&nState)))
  509. {
  510. CComPtr<IBasicIMUser2> spUser2;
  511. WCHAR *pH, *pW, *pM;
  512. if(SUCCEEDED(pUser->QueryInterface(IID_IBasicIMUser2, (void **) &spUser2)))
  513. {
  514. VARIANT var;
  515. var.vt = VT_BSTR;
  516. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_HOME_PHONE_NUMBER, &var)))
  517. {
  518. StrCpyNW(wszHome, var.bstrVal, CCHMAX - 1);
  519. wszHome[CCHMAX - 1] = L'\0';
  520. pH = wszHome;
  521. }
  522. else
  523. pH = NULL;
  524. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_WORK_PHONE_NUMBER, &var)))
  525. {
  526. StrCpyNW(wszWork, var.bstrVal, CCHMAX - 1);
  527. wszWork[CCHMAX - 1] = L'\0';
  528. pW = wszWork;
  529. }
  530. else
  531. pW = NULL;
  532. if(SUCCEEDED(spUser2->get_Property(BIMUSERPROP_MOBILE_PHONE_NUMBER, &var)))
  533. {
  534. StrCpyNW(wszMobile, var.bstrVal, CCHMAX - 1);
  535. wszMobile[CCHMAX - 1] = L'\0';
  536. pM = wszMobile;
  537. }
  538. else
  539. pM = NULL;
  540. }
  541. AddMsgrListEntry(bstrName, bstrID, nState,pH, pW, pM);
  542. }
  543. }
  544. SysFreeString(bstrName);
  545. SysFreeString(bstrID);
  546. pUser->Release();
  547. }
  548. }
  549. pBuddies->Release();
  550. return(S_OK);
  551. }
  552. // Add entry to list of buddies
  553. void CMsgrList::AddMsgrListEntry(WCHAR *szName, WCHAR *szID, int nState, WCHAR *wszHomePhone, WCHAR *wszWorkPhone, WCHAR *wszMobilePhone)
  554. {
  555. if(m_pblInfLast == NULL)
  556. {
  557. // Really first entry
  558. Assert(!m_pblInfRoot);
  559. if (!MemAlloc((LPVOID *) &m_pblInfLast, sizeof(oeMsgrInfo)))
  560. return;
  561. m_pblInfRoot = m_pblInfLast;
  562. m_pblInfLast->pPrev = NULL;
  563. }
  564. else
  565. {
  566. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pNext), sizeof(oeMsgrInfo)))
  567. return;
  568. (m_pblInfLast->pNext)->pPrev = m_pblInfLast;
  569. m_pblInfLast = m_pblInfLast->pNext;
  570. }
  571. m_pblInfLast->pNext = NULL;
  572. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pchMsgrName), (lstrlenW(szName) + 1)*sizeof(WCHAR)))
  573. return;
  574. StrCpyNW(m_pblInfLast->pchMsgrName, szName, lstrlenW(szName) + 1);
  575. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pchID), (lstrlenW(szID) + 1)*sizeof(WCHAR)))
  576. return;
  577. StrCpyNW(m_pblInfLast->pchID, szID, lstrlenW(szID) + 1);
  578. m_pblInfLast->nStatus = nState;
  579. if(wszHomePhone)
  580. {
  581. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pchHomePhone), (lstrlenW(wszHomePhone) + 1)*sizeof(WCHAR)))
  582. return;
  583. StrCpyNW(m_pblInfLast->pchHomePhone, wszHomePhone, lstrlenW(wszHomePhone) + 1);
  584. }
  585. else
  586. m_pblInfLast->pchHomePhone = NULL;
  587. if(wszWorkPhone)
  588. {
  589. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pchWorkPhone), (lstrlenW(wszWorkPhone) + 1)*sizeof(WCHAR)))
  590. return;
  591. StrCpyNW(m_pblInfLast->pchWorkPhone, wszWorkPhone, lstrlenW(wszWorkPhone) + 1);
  592. }
  593. else
  594. m_pblInfLast->pchWorkPhone = NULL;
  595. if(wszMobilePhone)
  596. {
  597. if (!MemAlloc((LPVOID *) &(m_pblInfLast->pchMobilePhone), (lstrlenW(wszMobilePhone) + 1)*sizeof(WCHAR)))
  598. return;
  599. StrCpyNW(m_pblInfLast->pchMobilePhone, wszMobilePhone, lstrlenW(wszMobilePhone) + 1);
  600. }
  601. else
  602. m_pblInfLast->pchMobilePhone = NULL;
  603. }
  604. // register ui window in list
  605. void CMsgrList::RegisterUIWnd(HWND hWndUI)
  606. {
  607. CheckAndInitMsgr();
  608. AddWndEntry(hWndUI);
  609. }
  610. // remove UI window from list
  611. void CMsgrList::UnRegisterUIWnd(HWND hWndUI)
  612. {
  613. if(hWndUI)
  614. FindAndDelEntry(hWndUI);
  615. }
  616. // This call Messenger UI for instant message.
  617. HRESULT CMsgrList::SendInstMessage(WCHAR *pchID)
  618. {
  619. Assert(m_spMsgrObject);
  620. BSTRING bstrName(pchID);
  621. VARIANT var;
  622. var.bstrVal = bstrName;
  623. var.vt = VT_BSTR;
  624. HRESULT hr = S_OK;
  625. if(m_spMsgrObject)
  626. hr = m_spMsgrObject->LaunchIMUI(var);
  627. return(hr);
  628. }
  629. HRESULT CMsgrList::AutoLogon()
  630. {
  631. if(m_spMsgrObject)
  632. {
  633. // if(DwGetOption(OPT_BUDDYLIST_CHECK))
  634. m_spMsgrObject->AutoLogon();
  635. }
  636. else
  637. return(E_FAIL);
  638. return S_OK;
  639. }
  640. HRESULT CMsgrList::UserLogon()
  641. {
  642. if(m_spMsgrObject)
  643. return(m_spMsgrObject->LaunchLogonUI());
  644. else
  645. return(S_FALSE);
  646. }
  647. // Logoff call
  648. HRESULT CMsgrList::UserLogoff()
  649. {
  650. if(!m_spMsgrObject)
  651. return E_UNEXPECTED;
  652. return(m_spMsgrObject->Logoff());
  653. }
  654. // Get/Set local states.
  655. HRESULT CMsgrList::GetLocalState(BIMSTATE *pState)
  656. {
  657. if(m_spMsgrObject && SUCCEEDED(m_spMsgrObject->get_LocalState(pState)))
  658. return(S_OK);
  659. else
  660. return(S_FALSE);
  661. }
  662. // Check name: this is local name?
  663. BOOL CMsgrList::IsLocalName(WCHAR *pchName)
  664. {
  665. CComBSTR cbstrID;
  666. HRESULT hr;
  667. BOOL fRes = FALSE;
  668. if(m_spMsgrObject)
  669. {
  670. hr = m_spMsgrObject->get_LocalLogonName(&cbstrID);
  671. if(FAILED(hr))
  672. return FALSE;
  673. if(!lstrcmpiW(pchName, (LPWSTR)cbstrID))
  674. fRes = TRUE;
  675. }
  676. return(fRes);
  677. }
  678. // Check current state
  679. BOOL CMsgrList::IsLocalOnline(void)
  680. {
  681. BIMSTATE State;
  682. if(m_spMsgrObject && SUCCEEDED(m_spMsgrObject->get_LocalState(&State)))
  683. {
  684. switch(State)
  685. {
  686. case BIMSTATE_ONLINE:
  687. case BIMSTATE_INVISIBLE:
  688. case BIMSTATE_BUSY:
  689. case BIMSTATE_BE_RIGHT_BACK:
  690. case BIMSTATE_IDLE:
  691. case BIMSTATE_AWAY:
  692. case BIMSTATE_ON_THE_PHONE:
  693. case BIMSTATE_OUT_TO_LUNCH:
  694. return(TRUE);
  695. default:
  696. return(FALSE);
  697. }
  698. }
  699. return(FALSE);
  700. }
  701. HRESULT CMsgrList::SetLocalState(BIMSTATE State)
  702. {
  703. if(m_spMsgrObject && State != BIMSTATE_UNKNOWN)
  704. {
  705. m_spMsgrObject->put_LocalState(State);
  706. return S_OK;
  707. }
  708. else
  709. return S_FALSE;
  710. }
  711. HRESULT CMsgrList::NewOnlineContact()
  712. {
  713. if(m_spMsgrObject)
  714. return(m_spMsgrObject-> LaunchAddContactUI(NULL));
  715. else
  716. return(S_FALSE);
  717. }
  718. HRESULT CMsgrList::LaunchOptionsUI(void)
  719. {
  720. if(m_spMsgrObject)
  721. return(m_spMsgrObject-> LaunchOptionsUI());
  722. else
  723. return(S_FALSE);
  724. }
  725. HRESULT CMsgrList::LaunchPhoneUI(WCHAR *Phone)
  726. {
  727. BSTRING bstrPhone(Phone);
  728. HRESULT hr = S_FALSE;
  729. if(m_spMsgrObject)
  730. hr = m_spMsgrObject->LaunchPhoneUI(bstrPhone);
  731. return(hr);
  732. }
  733. //****************************************************************************
  734. //
  735. // void CMsgrList::DeleteUser
  736. //
  737. // This function finds
  738. // the buddy to be removed in the MsgrList and then calls the Remove method.
  739. //
  740. //****************************************************************************
  741. HRESULT CMsgrList::FindAndDeleteUser(WCHAR * pchID, BOOL fDelete)
  742. {
  743. USES_CONVERSION;
  744. HRESULT hr = E_FAIL;
  745. INT i;
  746. LONG lCount = 0;
  747. BOOL bFound = FALSE;
  748. CComPtr<IBasicIMUser> spUser;
  749. CComPtr<IBasicIMUsers> spBuddies;
  750. // BSTRING bstrName(pchID);
  751. // get an interface pointer to the MsgrList, so we can call the method Remove after
  752. if (!m_spMsgrObject)
  753. {
  754. hr = E_FAIL;
  755. goto Exit;
  756. }
  757. hr = m_spMsgrObject->get_ContactList(&spBuddies);
  758. if( FAILED(hr) )
  759. {
  760. // g_AddToLog(LOG_LEVEL_COM, _T("Buddies() failed, hr = %s"), g_GetErrorString(hr));
  761. Assert(FALSE);
  762. goto Exit;
  763. }
  764. //Iterate through the MsgrList make sure that the buddy we wish to remove is effectively in the list
  765. hr = spBuddies->get_Count(&lCount);
  766. Assert(SUCCEEDED(hr));
  767. for(i = 0; ((i<lCount) && (!bFound)); i++)
  768. {
  769. CComBSTR cbstrID;
  770. spUser.Release();
  771. hr = spBuddies->Item(i, &spUser);
  772. if (SUCCEEDED(hr))
  773. {
  774. // g_AddToLog(LOG_LEVEL_COM, _T("Item : %i succeeded"), i);
  775. hr = spUser->get_LogonName(&cbstrID);
  776. Assert(SUCCEEDED(hr));
  777. if (lstrcmpiW((LPCWSTR) cbstrID, pchID) == 0)
  778. bFound = TRUE;
  779. if (bFound)
  780. break;
  781. }
  782. else
  783. {
  784. // g_AddToLog(LOG_LEVEL_COM, _T("Item : %i failed, hr = %s"), i, g_GetErrorString(hr));
  785. Assert(FALSE);
  786. }
  787. }
  788. // if we found the buddy in the list
  789. if( bFound )
  790. {
  791. if(fDelete)
  792. //finally, make the request to remove the buddy to the MsgrList
  793. hr = spBuddies->Remove(spUser);
  794. else
  795. // just search
  796. hr = S_OK;
  797. }
  798. else // Not found
  799. hr = DISP_E_MEMBERNOTFOUND;
  800. Exit:
  801. // SysFreeString(bstrName);
  802. return(hr);
  803. }
  804. HRESULT CMsgrList::AddUser(WCHAR * pchID)
  805. {
  806. CComPtr<IBasicIMUser> spUser;
  807. CComPtr<IBasicIMUsers> spUsers;
  808. BSTRING bstrName(pchID);
  809. HRESULT hr = FindAndDeleteUser(pchID, FALSE /*fDelete*/);
  810. if(hr != DISP_E_MEMBERNOTFOUND)
  811. return(hr);
  812. // if not found, add buddy
  813. // get an interface pointer to the MsgrList, so we can call the method Remove after
  814. if (!m_spMsgrObject)
  815. return E_FAIL;
  816. hr = m_spMsgrObject->LaunchAddContactUI(bstrName);
  817. return(hr);
  818. }
  819. // Global functions available for everybody
  820. // Entrance to MsgrList
  821. CMsgrList *OE_OpenMsgrList(void)
  822. {
  823. // if(!sg_pMsgrList)
  824. // {
  825. // this first call, create class
  826. CMsgrList *pMsgrList = new(CMsgrList);
  827. if(pMsgrList)
  828. {
  829. // Init of User List
  830. if(pMsgrList->HrInitMsgr() == S_OK)
  831. {
  832. if(pMsgrList->FillList() != S_OK)
  833. goto ErrEx;
  834. }
  835. else
  836. {
  837. ErrEx:
  838. pMsgrList->Release();
  839. return(NULL);
  840. }
  841. }
  842. // }
  843. // else
  844. // sg_pMsgrList->AddRef();
  845. // LeaveCriticalSection(&g_csMsgrList);
  846. return(pMsgrList);
  847. }
  848. // Close entrance to MsgrList
  849. void OE_CloseMsgrList(CMsgrList *pCMsgrList)
  850. {
  851. // Assert(pCMsgrList == sg_pMsgrList);
  852. // EnterCriticalSection(&g_csMsgrList);
  853. pCMsgrList->EventLocalStateChanged(BIMSTATE_OFFLINE);
  854. pCMsgrList->Release();
  855. // LeaveCriticalSection(&g_csMsgrList);
  856. }
  857. HRESULT OE_Msgr_Logoff(void)
  858. {
  859. BIMSTATE State;
  860. HRESULT hr = S_OK;
  861. #ifdef LATER
  862. if(!sg_pMsgrList)
  863. {
  864. // EnterCriticalSection(&g_csMsgrList);
  865. sg_pMsgrList = new(CMsgrList);
  866. // LeaveCriticalSection(&g_csMsgrList);
  867. if(!sg_pMsgrList)
  868. return(E_UNEXPECTED);
  869. // Init of User List
  870. if(FAILED(hr = sg_pMsgrList->HrInitMsgr()))
  871. goto logoff_end;
  872. else if(FAILED(hr = sg_pMsgrList->GetLocalState(&State)) || State == BIMSTATE_OFFLINE)
  873. goto logoff_end;
  874. else
  875. hr = sg_pMsgrList->UserLogoff();
  876. }
  877. else
  878. {
  879. return(sg_pMsgrList->UserLogoff()); // we cannot delete sg_pMsgrList in this case!
  880. }
  881. logoff_end:
  882. if(sg_pMsgrList)
  883. {
  884. OE_CloseMsgrList(sg_pMsgrList);
  885. }
  886. #endif
  887. return(hr);
  888. }
  889. HRESULT InstallMessenger(HWND hWnd)
  890. {
  891. HRESULT hr = REGDB_E_CLASSNOTREG;
  892. #ifdef LATER
  893. uCLSSPEC classpec;
  894. TCHAR szBuff[CCHMAX];
  895. classpec.tyspec=TYSPEC_CLSID;
  896. classpec.tagged_union.clsid = CLSID_MessengerApp;
  897. // See below for parameter definitions and return values
  898. hr = FaultInIEFeature(hWnd, &classpec, NULL, FIEF_FLAG_FORCE_JITUI);
  899. if (hr != S_OK) {
  900. if(hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED))
  901. {
  902. AthLoadString(idsJITErrDenied, szBuff, ARRAYSIZE(szBuff));
  903. AthMessageBox(hWnd, MAKEINTRESOURCE(idsAthena), szBuff,
  904. NULL, MB_OK | MB_ICONSTOP);
  905. }
  906. else
  907. {
  908. AthLoadString(idsBAErrJITFail, szBuff, ARRAYSIZE(szBuff));
  909. MenuUtil_BuildMessengerString(szBuff);
  910. AthMessageBox(hWnd, MAKEINTRESOURCE(idsAthena), szBuff,
  911. NULL, MB_OK | MB_ICONSTOP);
  912. }
  913. hr = REGDB_E_CLASSNOTREG;
  914. }
  915. #else
  916. hr= S_OK;
  917. #endif // LATER
  918. return hr;
  919. }
  920. #ifdef NEEDED
  921. HRESULT OE_Msgr_Logon(void)
  922. {
  923. if(!sg_pMsgrList)
  924. return S_FALSE;
  925. else
  926. return(sg_pMsgrList->UserLogon());
  927. }
  928. #endif