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.

1099 lines
35 KiB

  1. //--------------------------------------------------------------------------
  2. // OE5Imp.cpp
  3. //--------------------------------------------------------------------------
  4. #include "pch.hxx"
  5. #include "dllmain.h"
  6. #include "oe5imp.h"
  7. #include <impapi.h>
  8. #include "resource.h"
  9. #include <msident.h>
  10. #include <oestore.h>
  11. #include <shlwapi.h>
  12. //--------------------------------------------------------------------------
  13. // String Constants
  14. //--------------------------------------------------------------------------
  15. const static char c_szFoldersFile[] = "folders.dbx";
  16. const static char c_szEmpty[]= "";
  17. //--------------------------------------------------------------------------
  18. // USERINFO
  19. //--------------------------------------------------------------------------
  20. typedef struct tagUSERINFO {
  21. CHAR szIdNameA[CCH_IDENTITY_NAME_MAX_LENGTH];
  22. GUID guidCookie;
  23. HKEY hKey;
  24. } USERINFO, *LPUSERINFO;
  25. //--------------------------------------------------------------------------
  26. // Prototypes
  27. //--------------------------------------------------------------------------
  28. INT_PTR CALLBACK ImportOptionsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  29. //--------------------------------------------------------------------------
  30. // COE5Import_CreateInstance
  31. //--------------------------------------------------------------------------
  32. COE5Import_CreateInstance(IUnknown *pUnkOuter, IUnknown **ppUnknown)
  33. {
  34. // Trace
  35. TraceCall("COE5Import_CreateInstance");
  36. // Initialize
  37. *ppUnknown = NULL;
  38. // Create me
  39. COE5Import *pNew=NULL;
  40. pNew = new COE5Import();
  41. if (NULL == pNew)
  42. return TraceResult(E_OUTOFMEMORY);
  43. // Cast to unknown
  44. *ppUnknown = SAFECAST(pNew, IMailImport *);
  45. // Done
  46. return(S_OK);
  47. }
  48. //--------------------------------------------------------------------------
  49. // COE5Import::COE5Import
  50. //--------------------------------------------------------------------------
  51. COE5Import::COE5Import(void)
  52. {
  53. TraceCall("COE5Import::COE5Import");
  54. m_cRef = 1;
  55. m_pList = NULL;
  56. *m_szDirectory = '\0';
  57. m_cFolders = 0;
  58. m_prgFolder = NULL;
  59. m_fGotMeSomeFolders = FALSE;
  60. m_pFolderDB = NULL;
  61. m_pSession = NULL;
  62. m_hwndParent = NULL;
  63. ZeroMemory(&m_Options, sizeof(IMPORTOPTIONS));
  64. }
  65. //--------------------------------------------------------------------------
  66. // COE5Import::~COE5Import
  67. //--------------------------------------------------------------------------
  68. COE5Import::~COE5Import(void)
  69. {
  70. TraceCall("COE5Import::~COE5Import");
  71. _FreeFolderList(m_pList);
  72. if (m_pFolderDB)
  73. {
  74. for (DWORD i=0;i<m_cFolders; i++)
  75. {
  76. m_pFolderDB->FreeRecord(&m_prgFolder[i]);
  77. }
  78. }
  79. SafeMemFree(m_prgFolder);
  80. SafeRelease(m_pFolderDB);
  81. SafeRelease(m_pSession);
  82. }
  83. //--------------------------------------------------------------------------
  84. // COE5Import::_FreeFolderList
  85. //--------------------------------------------------------------------------
  86. void COE5Import::_FreeFolderList(IMPFOLDERNODE *pNode)
  87. {
  88. // Locals
  89. IMPFOLDERNODE *pNext;
  90. IMPFOLDERNODE *pCurrent=pNode;
  91. // Loop
  92. while (pCurrent)
  93. {
  94. // Save next
  95. pNext = pCurrent->pnext;
  96. // Free Children ?
  97. if (pCurrent->pchild)
  98. {
  99. // Free
  100. _FreeFolderList(pCurrent->pchild);
  101. }
  102. // Free szName
  103. g_pMalloc->Free(pCurrent->szName);
  104. // Free pCurrent
  105. g_pMalloc->Free(pCurrent);
  106. // Set Current
  107. pCurrent = pNext;
  108. }
  109. }
  110. //--------------------------------------------------------------------------
  111. // COE5Import::QueryInterface
  112. //--------------------------------------------------------------------------
  113. STDMETHODIMP COE5Import::QueryInterface(REFIID riid, LPVOID *ppv)
  114. {
  115. // Locals
  116. HRESULT hr=S_OK;
  117. // Stack
  118. TraceCall("COE5Import::QueryInterface");
  119. // Find IID
  120. if (IID_IUnknown == riid)
  121. *ppv = (IUnknown *)this;
  122. else if (IID_IMailImport == riid)
  123. *ppv = (IMailImport *)this;
  124. else
  125. {
  126. *ppv = NULL;
  127. hr = TraceResult(E_NOINTERFACE);
  128. goto exit;
  129. }
  130. // AddRef It
  131. ((IUnknown *)*ppv)->AddRef();
  132. exit:
  133. // Done
  134. return(hr);
  135. }
  136. //--------------------------------------------------------------------------
  137. // COE5Import::AddRef
  138. //--------------------------------------------------------------------------
  139. STDMETHODIMP_(ULONG) COE5Import::AddRef(void)
  140. {
  141. TraceCall("COE5Import::AddRef");
  142. return InterlockedIncrement(&m_cRef);
  143. }
  144. //--------------------------------------------------------------------------
  145. // COE5Import::Release
  146. //--------------------------------------------------------------------------
  147. STDMETHODIMP_(ULONG) COE5Import::Release(void)
  148. {
  149. TraceCall("COE5Import::Release");
  150. LONG cRef = InterlockedDecrement(&m_cRef);
  151. if (0 == cRef)
  152. delete this;
  153. return (ULONG)cRef;
  154. }
  155. //--------------------------------------------------------------------------
  156. // COE5Import::InitializeImport
  157. //--------------------------------------------------------------------------
  158. STDMETHODIMP COE5Import::InitializeImport(HWND hwnd)
  159. {
  160. // Save this handle
  161. m_hwndParent = hwnd;
  162. // Do my UI
  163. return(IDOK == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_IMPORTOE5), hwnd, ImportOptionsDlgProc, (LPARAM)&m_Options) ? S_OK : E_FAIL);
  164. }
  165. //--------------------------------------------------------------------------
  166. // COE5Import::GetDirectory
  167. //--------------------------------------------------------------------------
  168. STDMETHODIMP COE5Import::GetDirectory(LPSTR pszDir, UINT cch)
  169. {
  170. // Let Importer Ask for the Directory
  171. StrCpyN(pszDir, m_Options.szStoreRoot, cch);
  172. return(S_OK);
  173. }
  174. //--------------------------------------------------------------------------
  175. // COE5Import::SetDirectory
  176. //--------------------------------------------------------------------------
  177. STDMETHODIMP COE5Import::SetDirectory(LPSTR pszDir)
  178. {
  179. // Trace
  180. TraceCall("COE5Import::SetDirectory");
  181. // Save the Directory
  182. StrCpyN(m_szDirectory, pszDir, ARRAYSIZE(m_szDirectory));
  183. // Done
  184. return(S_OK);
  185. }
  186. //--------------------------------------------------------------------------
  187. // COE5Import::EnumerateFolders
  188. //--------------------------------------------------------------------------
  189. STDMETHODIMP COE5Import::EnumerateFolders(DWORD_PTR dwCookie, IEnumFOLDERS **ppEnum)
  190. {
  191. // Locals
  192. HRESULT hr=S_OK;
  193. DWORD cchDir;
  194. DWORD cRows;
  195. CHAR szFilePath[MAX_PATH + MAX_PATH];
  196. IMPFOLDERNODE *pList;
  197. IMPFOLDERNODE *pNode=(IMPFOLDERNODE *)dwCookie;
  198. COE5EnumFolders *pEnum=NULL;
  199. HROWSET hRowset=NULL;
  200. // Trace
  201. TraceCall("COE5Import::EnumerateFolders");
  202. // Invalid Args
  203. Assert(ppEnum);
  204. // Get Folders ?
  205. if (NULL == m_prgFolder && 0 == m_cFolders && FALSE == m_fGotMeSomeFolders)
  206. {
  207. // Append \Mail onto m_szDirectory
  208. cchDir = lstrlen(m_szDirectory);
  209. // Need a Wack ?
  210. if (m_szDirectory[cchDir - 1] != '\\')
  211. StrCatBuff(m_szDirectory, "\\", ARRAYSIZE(m_szDirectory));
  212. // Make Path to folders.nch file
  213. IF_FAILEXIT(hr = MakeFilePath(m_szDirectory, c_szFoldersFile, c_szEmpty, szFilePath, ARRAYSIZE(szFilePath)));
  214. // Create an IDatabase
  215. IF_FAILEXIT(hr = CoCreateInstance(CLSID_DatabaseSession, NULL, CLSCTX_INPROC_SERVER, IID_IDatabaseSession, (LPVOID *)&m_pSession));
  216. // Open an IDatabase
  217. IF_FAILEXIT(hr = m_pSession->OpenDatabase(szFilePath, OPEN_DATABASE_NOCREATE | OPEN_DATABASE_NORESET | OPEN_DATABASE_NOEXTENSION | OPEN_DATABASE_EXCLUSEIVE, &g_FolderTableSchema, NULL, &m_pFolderDB));
  218. // Get Record Count
  219. IF_FAILEXIT(hr = m_pFolderDB->GetRecordCount(IINDEX_SUBSCRIBED, &m_cFolders));
  220. // Allocate Folder Array
  221. IF_NULLEXIT(m_prgFolder = (LPFOLDERINFO)ZeroAllocate(sizeof(FOLDERINFO) * m_cFolders));
  222. // Create a Rowset
  223. IF_FAILEXIT(hr = m_pFolderDB->CreateRowset(IINDEX_SUBSCRIBED, 0, &hRowset));
  224. // Read all the rows
  225. IF_FAILEXIT(hr = m_pFolderDB->QueryRowset(hRowset, m_cFolders, (LPVOID *)m_prgFolder, &cRows));
  226. // Validate
  227. Assert(m_cFolders == cRows);
  228. // Build Hierarchy
  229. IF_FAILEXIT(hr = _BuildFolderHierarchy(0, FOLDERID_LOCAL_STORE, NULL));
  230. // Got me some folders
  231. m_fGotMeSomeFolders = TRUE;
  232. }
  233. // Not Folders ?
  234. else if (NULL == m_prgFolder)
  235. {
  236. hr = TraceResult(E_FAIL);
  237. goto exit;
  238. }
  239. // What should I
  240. if (dwCookie == COOKIE_ROOT)
  241. pList = m_pList;
  242. else
  243. pList = pNode->pchild;
  244. // Create Folder Enumerator
  245. IF_NULLEXIT(pEnum = new COE5EnumFolders(pList));
  246. // Return Enumerator
  247. *ppEnum = (IEnumFOLDERS *)pEnum;
  248. // Don't Free
  249. pEnum = NULL;
  250. exit:
  251. // Cleanup
  252. if (hRowset && m_pFolderDB)
  253. m_pFolderDB->CloseRowset(&hRowset);
  254. SafeRelease(pEnum);
  255. // Try to show a good error....
  256. if (DB_E_ACCESSDENIED == hr)
  257. {
  258. // Locals
  259. CHAR szTitle[255];
  260. CHAR szError[255];
  261. // Get the error
  262. LoadString(g_hInst, IDS_ACCESS_DENIED, szError, 255);
  263. // Get tht title
  264. LoadString(g_hInst, IDS_TITLE, szTitle, 255);
  265. // Show the error
  266. MessageBox(m_hwndParent, szError, szTitle, MB_OK | MB_ICONEXCLAMATION);
  267. }
  268. // Done
  269. return(hr);
  270. }
  271. //--------------------------------------------------------------------------
  272. // COE5Import::_BuildFolderHierarchy
  273. //--------------------------------------------------------------------------
  274. HRESULT COE5Import::_BuildFolderHierarchy(DWORD cDepth, FOLDERID idParent,
  275. IMPFOLDERNODE *pParent)
  276. {
  277. // Locals
  278. HRESULT hr=S_OK;
  279. DWORD i;
  280. DWORD cchName;
  281. IMPFOLDERNODE *pPrevious=NULL;
  282. IMPFOLDERNODE *pNode;
  283. // Trace
  284. TraceCall("COE5Import::_BuildFolderHierarchy");
  285. // Walk through prgFolder and find items with parent of idParent
  286. for (i=0; i<m_cFolders; i++)
  287. {
  288. // Correct Parent ?
  289. if (idParent == m_prgFolder[i].idParent && m_prgFolder[i].pszFile && m_prgFolder[i].pszName)
  290. {
  291. // Allocate the Root
  292. IF_NULLEXIT(pNode = (IMPFOLDERNODE *)ZeroAllocate(sizeof(IMPFOLDERNODE)));
  293. // Set Parent
  294. pNode->pparent = pParent;
  295. // Set Depth
  296. pNode->depth = cDepth;
  297. // Get Length of Name
  298. cchName = lstrlen(m_prgFolder[i].pszName);
  299. // Copy name
  300. IF_NULLEXIT(pNode->szName = (LPSTR)g_pMalloc->Alloc(cchName + 1));
  301. // Copy name
  302. CopyMemory(pNode->szName, m_prgFolder[i].pszName, cchName + 1);
  303. // Count of Messages
  304. pNode->cMsg = m_prgFolder[i].cMessages;
  305. // Handle Non-special folder
  306. if (m_prgFolder[i].tySpecial > FOLDER_DRAFT)
  307. pNode->type = FOLDER_TYPE_NORMAL;
  308. // Otherwise, map to type
  309. else
  310. pNode->type = (IMPORTFOLDERTYPE)(m_prgFolder[i].tySpecial);
  311. // Set lParam
  312. pNode->lparam = i;
  313. // Link pNode into List
  314. if (pPrevious)
  315. pPrevious->pnext = pNode;
  316. else if (pParent)
  317. pParent->pchild = pNode;
  318. else
  319. {
  320. Assert(NULL == m_pList);
  321. m_pList = pNode;
  322. }
  323. // Set pPrevious
  324. pPrevious = pNode;
  325. // Enumerate Children
  326. IF_FAILEXIT(hr = _BuildFolderHierarchy(cDepth + 1, m_prgFolder[i].idFolder, pNode));
  327. }
  328. }
  329. exit:
  330. // Done
  331. return(hr);
  332. }
  333. //--------------------------------------------------------------------------
  334. // COE5Import::ImportFolder
  335. //--------------------------------------------------------------------------
  336. STDMETHODIMP COE5Import::ImportFolder(DWORD_PTR dwCookie, IFolderImport *pImport)
  337. {
  338. // Locals
  339. HRESULT hr=S_OK;
  340. LPFOLDERINFO pFolder;
  341. CHAR szFilePath[MAX_PATH + MAX_PATH];
  342. IMPFOLDERNODE *pNode=(IMPFOLDERNODE *)dwCookie;
  343. IDatabaseSession *pSession=NULL;
  344. IDatabase *pDB=NULL;
  345. DWORD cRecords;
  346. HROWSET hRowset=NULL;
  347. MESSAGEINFO Message;
  348. DWORD dwMsgState = 0;
  349. IStream *pStream=NULL;
  350. // Trace
  351. TraceCall("COE5Import::ImportFolder");
  352. // Set pFolder
  353. pFolder = &m_prgFolder[pNode->lparam];
  354. // path
  355. IF_FAILEXIT(hr = MakeFilePath(m_szDirectory, pFolder->pszFile, c_szEmpty, szFilePath, ARRAYSIZE(szFilePath)));
  356. // Open an IDatabase
  357. Assert(m_pSession);
  358. IF_FAILEXIT(hr = m_pSession->OpenDatabase(szFilePath, OPEN_DATABASE_NORESET | OPEN_DATABASE_NOEXTENSION | OPEN_DATABASE_EXCLUSEIVE, &g_MessageTableSchema, NULL, &pDB));
  359. // Get the Record Count
  360. IF_FAILEXIT(hr = pDB->GetRecordCount(IINDEX_PRIMARY, &cRecords));
  361. // Set Message Count
  362. pImport->SetMessageCount(cRecords);
  363. // Create a Rowset
  364. IF_FAILEXIT(hr = pDB->CreateRowset(IINDEX_PRIMARY, 0, &hRowset));
  365. // Walk the Rowset
  366. while (S_OK == pDB->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL))
  367. {
  368. // Import it ?
  369. if (FALSE == m_Options.fOE5Only || !ISFLAGSET(Message.dwFlags, 0x00000010) && Message.faStream)
  370. {
  371. // Open the Stream
  372. if (SUCCEEDED(pDB->OpenStream(ACCESS_READ, Message.faStream, &pStream)))
  373. {
  374. // State
  375. dwMsgState = 0; // set initially to 0
  376. if (!ISFLAGSET(Message.dwFlags, ARF_READ))
  377. FLAGSET(dwMsgState, MSG_STATE_UNREAD);
  378. if (ISFLAGSET(Message.dwFlags, ARF_UNSENT))
  379. FLAGSET(dwMsgState, MSG_STATE_UNSENT);
  380. if (ISFLAGSET(Message.dwFlags, ARF_SUBMITTED))
  381. FLAGSET(dwMsgState, MSG_STATE_SUBMITTED);
  382. if (IMSG_PRI_LOW == Message.wPriority)
  383. FLAGSET(dwMsgState, MSG_PRI_LOW);
  384. else if (IMSG_PRI_HIGH == Message.wPriority)
  385. FLAGSET(dwMsgState, MSG_PRI_HIGH);
  386. else
  387. FLAGSET(dwMsgState, MSG_PRI_NORMAL);
  388. // Import It
  389. pImport->ImportMessage(MSG_TYPE_MAIL, dwMsgState, pStream, NULL, 0);
  390. // Cleanup
  391. SafeRelease(pStream);
  392. }
  393. }
  394. // Free It
  395. pDB->FreeRecord(&Message);
  396. }
  397. exit:
  398. // Done
  399. if (pDB && hRowset)
  400. pDB->CloseRowset(&hRowset);
  401. SafeRelease(pStream);
  402. SafeRelease(pDB);
  403. SafeRelease(pSession);
  404. // Done
  405. return(hr);
  406. }
  407. //--------------------------------------------------------------------------
  408. // COE5EnumFolders::COE5EnumFolders
  409. //--------------------------------------------------------------------------
  410. COE5EnumFolders::COE5EnumFolders(IMPFOLDERNODE *pList)
  411. {
  412. TraceCall("COE5EnumFolders::COE5EnumFolders");
  413. m_cRef = 1;
  414. m_pList = pList;
  415. m_pNext = pList;
  416. }
  417. //--------------------------------------------------------------------------
  418. // COE5EnumFolders::COE5EnumFolders
  419. //--------------------------------------------------------------------------
  420. COE5EnumFolders::~COE5EnumFolders(void)
  421. {
  422. TraceCall("COE5EnumFolders::~COE5EnumFolders");
  423. }
  424. //--------------------------------------------------------------------------
  425. // COE5EnumFolders::COE5EnumFolders
  426. //--------------------------------------------------------------------------
  427. STDMETHODIMP COE5EnumFolders::QueryInterface(REFIID riid, LPVOID *ppv)
  428. {
  429. // Locals
  430. HRESULT hr=S_OK;
  431. // Stack
  432. TraceCall("COE5EnumFolders::QueryInterface");
  433. // Find IID
  434. if (IID_IUnknown == riid)
  435. *ppv = (IUnknown *)this;
  436. else if (IID_IEnumFOLDERS == riid)
  437. *ppv = (IEnumFOLDERS *)this;
  438. else
  439. {
  440. *ppv = NULL;
  441. hr = TraceResult(E_NOINTERFACE);
  442. goto exit;
  443. }
  444. // AddRef It
  445. ((IUnknown *)*ppv)->AddRef();
  446. exit:
  447. // Done
  448. return(hr);
  449. }
  450. //--------------------------------------------------------------------------
  451. // COE5EnumFolders::AddRef
  452. //--------------------------------------------------------------------------
  453. STDMETHODIMP_(ULONG) COE5EnumFolders::AddRef(void)
  454. {
  455. TraceCall("COE5EnumFolders::AddRef");
  456. return InterlockedIncrement(&m_cRef);
  457. }
  458. //--------------------------------------------------------------------------
  459. // COE5EnumFolders::Release
  460. //--------------------------------------------------------------------------
  461. STDMETHODIMP_(ULONG) COE5EnumFolders::Release(void)
  462. {
  463. TraceCall("COE5EnumFolders::Release");
  464. LONG cRef = InterlockedDecrement(&m_cRef);
  465. if (0 == cRef)
  466. delete this;
  467. return (ULONG)cRef;
  468. }
  469. //--------------------------------------------------------------------------
  470. // COE5EnumFolders::Next
  471. //--------------------------------------------------------------------------
  472. STDMETHODIMP COE5EnumFolders::Next(IMPORTFOLDER *pFolder)
  473. {
  474. // Locals
  475. HRESULT hr=S_OK;
  476. // Trace
  477. TraceCall("COE5EnumFolders::Next");
  478. // Invalid Args
  479. Assert(pFolder != NULL);
  480. // Done
  481. if (NULL == m_pNext)
  482. return(S_FALSE);
  483. // Zero
  484. ZeroMemory(pFolder, sizeof(IMPORTFOLDER));
  485. // Store pNext into dwCookie
  486. pFolder->dwCookie = (DWORD_PTR)m_pNext;
  487. // Copy Folder Name
  488. StrCpyN(pFolder->szName, m_pNext->szName, ARRAYSIZE(pFolder->szName));
  489. // Copy Type
  490. pFolder->type = m_pNext->type;
  491. // Has Sub Folders ?
  492. pFolder->fSubFolders = (m_pNext->pchild != NULL);
  493. // Goto Next
  494. m_pNext = m_pNext->pnext;
  495. // Done
  496. return(S_OK);
  497. }
  498. //--------------------------------------------------------------------------
  499. // COE5EnumFolders::Reset
  500. //--------------------------------------------------------------------------
  501. STDMETHODIMP COE5EnumFolders::Reset(void)
  502. {
  503. // Trace
  504. TraceCall("COE5EnumFolders::Reset");
  505. // Reset
  506. m_pNext = m_pList;
  507. // Done
  508. return(S_OK);
  509. }
  510. //--------------------------------------------------------------------------
  511. // GetPasswordDlgProc
  512. //--------------------------------------------------------------------------
  513. #define CCHMAX_PASSWORDID 255
  514. INT_PTR CALLBACK GetPasswordDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  515. {
  516. // Locals
  517. HRESULT hr;
  518. CHAR szPrompt[255];
  519. CHAR szTitle[255 + CCH_IDENTITY_NAME_MAX_LENGTH];
  520. LPUSERINFO pUserInfo=(LPUSERINFO)GetWndThisPtr(hwnd);
  521. IUserIdentityManager *pManager;
  522. IPrivateIdentityManager *pPrivate;
  523. // Handle the Message
  524. switch(uMsg)
  525. {
  526. // Dialog Init
  527. case WM_INITDIALOG:
  528. // Store lParam...
  529. Assert(0 != lParam);
  530. pUserInfo = (LPUSERINFO)lParam;
  531. SetWndThisPtr(hwnd, lParam);
  532. // Get the title
  533. GetWindowText(GetDlgItem(hwnd, IDS_PROMPT), szPrompt, ARRAYSIZE(szPrompt) - 1);
  534. // Format the title
  535. wnsprintf(szTitle, ARRAYSIZE(szTitle), szPrompt, pUserInfo->szIdNameA);
  536. // Set the text
  537. SetWindowText(GetDlgItem(hwnd, IDS_PROMPT), szTitle);
  538. // Set Text Length
  539. SendMessage(GetDlgItem(hwnd, IDE_PASSWORD), EM_SETLIMITTEXT, 0, CCHMAX_PASSWORDID - 1);
  540. // Set the Focus
  541. SetFocus(GetDlgItem(hwnd, IDE_PASSWORD));
  542. // Done
  543. return(0);
  544. // Command
  545. case WM_COMMAND:
  546. // Handle ControlId
  547. switch(LOWORD(wParam))
  548. {
  549. // Ok
  550. case IDOK:
  551. // Create an Id Manager
  552. hr = CoCreateInstance(CLSID_UserIdentityManager, NULL, CLSCTX_INPROC_SERVER, IID_IUserIdentityManager, (LPVOID *)&pManager);
  553. if (SUCCEEDED(hr))
  554. {
  555. // Get the Private
  556. hr = pManager->QueryInterface(IID_IPrivateIdentityManager, (LPVOID *)&pPrivate);
  557. if (SUCCEEDED(hr))
  558. {
  559. // Locals
  560. CHAR szPassword[CCHMAX_PASSWORDID];
  561. WCHAR wszPassword[CCHMAX_PASSWORDID];
  562. // Get the password
  563. GetWindowText(GetDlgItem(hwnd, IDE_PASSWORD), szPassword, ARRAYSIZE(szPassword));
  564. // Convert to Unicode
  565. hr = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPassword, -1, wszPassword, CCHMAX_PASSWORDID);
  566. if (SUCCEEDED(hr))
  567. {
  568. // Confirm the password
  569. hr = pPrivate->ConfirmPassword(&pUserInfo->guidCookie, wszPassword);
  570. }
  571. // Release
  572. pPrivate->Release();
  573. }
  574. // Release
  575. pManager->Release();
  576. }
  577. // Failure
  578. if (FAILED(hr))
  579. {
  580. // Locals
  581. CHAR szRes[255];
  582. CHAR szTitle[255];
  583. // Get the error
  584. LoadString(g_hInst, IDS_PASSWORD_ERROR, szRes, 255);
  585. // Get tht title
  586. LoadString(g_hInst, IDS_TITLE, szTitle, 255);
  587. // Show the error
  588. MessageBox(hwnd, szRes, szTitle, MB_OK | MB_ICONEXCLAMATION);
  589. }
  590. // Otherwise, all good
  591. else
  592. EndDialog(hwnd, IDOK);
  593. // Done
  594. return(1);
  595. // Cancel
  596. case IDCANCEL:
  597. EndDialog(hwnd, IDCANCEL);
  598. return(1);
  599. }
  600. }
  601. // Not Handled
  602. return(0);
  603. }
  604. //--------------------------------------------------------------------------
  605. // ImportOptionsDlgProc
  606. //--------------------------------------------------------------------------
  607. INT_PTR CALLBACK ImportOptionsDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  608. {
  609. // Locals
  610. HRESULT hr;
  611. IUserIdentityManager *pManager;
  612. DWORD cIds=0;
  613. LPIMPORTOPTIONS pOptions=(LPIMPORTOPTIONS)GetWndThisPtr(hwnd);
  614. // Handle the Message
  615. switch(uMsg)
  616. {
  617. // Dialog Init
  618. case WM_INITDIALOG:
  619. {
  620. // Store lParam...
  621. Assert(0 != lParam);
  622. SetWndThisPtr(hwnd, lParam);
  623. // Create an Id Manager
  624. hr = CoCreateInstance(CLSID_UserIdentityManager, NULL, CLSCTX_INPROC_SERVER, IID_IUserIdentityManager, (LPVOID *)&pManager);
  625. if (SUCCEEDED(hr))
  626. {
  627. // Enumerator
  628. IEnumUserIdentity *pEnum;
  629. // Enumerate Ids
  630. hr = pManager->EnumIdentities(&pEnum);
  631. if (SUCCEEDED(hr))
  632. {
  633. // Locals
  634. IUnknown *pUnk;
  635. ULONG cFetched;
  636. // Walk the ids
  637. while (S_OK == pEnum->Next(1, &pUnk, &cFetched))
  638. {
  639. // Locals
  640. IUserIdentity *pId;
  641. // Get IUserIdentity
  642. hr = pUnk->QueryInterface(IID_IUserIdentity, (LPVOID *)&pId);
  643. if (SUCCEEDED(hr))
  644. {
  645. // Locals
  646. WCHAR szIdNameW[CCH_IDENTITY_NAME_MAX_LENGTH];
  647. // Get the Name
  648. hr = pId->GetName(szIdNameW, CCH_IDENTITY_NAME_MAX_LENGTH);
  649. if (SUCCEEDED(hr))
  650. {
  651. // Locals
  652. CHAR szIdNameA[CCH_IDENTITY_NAME_MAX_LENGTH];
  653. // Convert to ansi
  654. hr = WideCharToMultiByte(CP_ACP, 0, (WCHAR *)szIdNameW, -1, szIdNameA, CCH_IDENTITY_NAME_MAX_LENGTH, NULL, NULL);
  655. if (SUCCEEDED(hr))
  656. {
  657. // Locals
  658. HKEY hKey=NULL;
  659. // Get the hKey for this user...
  660. hr = pId->OpenIdentityRegKey(KEY_READ, &hKey);
  661. if (SUCCEEDED(hr))
  662. {
  663. // Locals
  664. GUID guidCookie;
  665. // Get the Id Cookie
  666. hr = pId->GetCookie(&guidCookie);
  667. if (SUCCEEDED(hr))
  668. {
  669. // Locals
  670. LPUSERINFO pUserInfo;
  671. // Allocate it
  672. pUserInfo = (LPUSERINFO)CoTaskMemAlloc(sizeof(USERINFO));
  673. // Allocate a Place to store this
  674. if (pUserInfo)
  675. {
  676. // Locals
  677. LRESULT iItem;
  678. // Store the Data
  679. pUserInfo->hKey = hKey;
  680. pUserInfo->guidCookie = guidCookie;
  681. StrCpyN(pUserInfo->szIdNameA, szIdNameA, ARRAYSIZE(pUserInfo->szIdNameA));
  682. // Add the String
  683. iItem = SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_ADDSTRING, 0, (LPARAM)szIdNameA);
  684. // Store the key as item data...
  685. SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_SETITEMDATA, iItem, (LPARAM)pUserInfo);
  686. // Increment Count
  687. cIds++;
  688. // Don't Close It
  689. hKey = NULL;
  690. }
  691. }
  692. // Close the Key
  693. if (hKey)
  694. RegCloseKey(hKey);
  695. }
  696. }
  697. }
  698. // Release pId
  699. pId->Release();
  700. }
  701. // Release pUnk
  702. pUnk->Release();
  703. // Done
  704. if (FAILED(hr))
  705. break;
  706. }
  707. // Release
  708. pEnum->Release();
  709. }
  710. // Release
  711. pManager->Release();
  712. }
  713. // If there are ids
  714. if (cIds > 0)
  715. {
  716. CheckDlgButton(hwnd, IDC_FROM_ID, BST_CHECKED);
  717. SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_SETSEL, TRUE, 0);
  718. SetFocus(GetDlgItem(hwnd, IDC_IDLIST));
  719. return(0);
  720. }
  721. // Otherwise...
  722. else
  723. {
  724. CheckDlgButton(hwnd, IDC_FROM_DIRECTORY, BST_CHECKED);
  725. EnableWindow(GetDlgItem(hwnd, IDC_FROM_ID), FALSE);
  726. EnableWindow(GetDlgItem(hwnd, IDC_IDLIST), FALSE);
  727. return(1);
  728. }
  729. }
  730. // Command
  731. case WM_COMMAND:
  732. // Handle ControlId
  733. switch(LOWORD(wParam))
  734. {
  735. // Ok
  736. case IDOK:
  737. case IDCANCEL:
  738. // Ok ?
  739. if (IDOK == LOWORD(wParam))
  740. {
  741. // Option Checked to get oe5 only mail?
  742. pOptions->fOE5Only = IsDlgButtonChecked(hwnd, IDC_OE5ONLY);
  743. // Importing form Ids
  744. if (IsDlgButtonChecked(hwnd, IDC_FROM_ID))
  745. {
  746. // Locals
  747. HKEY hOE;
  748. LRESULT iSel;
  749. LONG lResult;
  750. DWORD dwType;
  751. LPUSERINFO pUserInfo;
  752. // Get the Selected Item
  753. iSel = SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_GETCURSEL, 0, 0);
  754. if (LB_ERR == iSel)
  755. {
  756. // Locals
  757. CHAR szRes[255];
  758. CHAR szTitle[255];
  759. // Get the error
  760. LoadString(g_hInst, IDS_SELECT_ID, szRes, 255);
  761. // Get tht title
  762. LoadString(g_hInst, IDS_TITLE, szTitle, 255);
  763. // Show the error
  764. MessageBox(hwnd, szRes, szTitle, MB_OK | MB_ICONEXCLAMATION);
  765. // Put focus where the user should correct their mistake
  766. SetFocus(GetDlgItem(hwnd, IDC_IDLIST));
  767. // Done
  768. return(1);
  769. }
  770. // Get the hKey
  771. pUserInfo = (LPUSERINFO)SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_GETITEMDATA, iSel, 0);
  772. // Create an Id Manager
  773. hr = CoCreateInstance(CLSID_UserIdentityManager, NULL, CLSCTX_INPROC_SERVER, IID_IUserIdentityManager, (LPVOID *)&pManager);
  774. if (SUCCEEDED(hr))
  775. {
  776. // Locals
  777. IPrivateIdentityManager *pPrivate;
  778. // Get the Private
  779. hr = pManager->QueryInterface(IID_IPrivateIdentityManager, (LPVOID *)&pPrivate);
  780. if (SUCCEEDED(hr))
  781. {
  782. // Locals
  783. WCHAR wszPassword[CCHMAX_PASSWORDID];
  784. // Init
  785. *wszPassword = L'\0';
  786. // Confirm the password
  787. hr = pPrivate->ConfirmPassword(&pUserInfo->guidCookie, wszPassword);
  788. // Release
  789. pPrivate->Release();
  790. }
  791. // Release
  792. pManager->Release();
  793. }
  794. // Set hr
  795. if (S_OK != hr)
  796. {
  797. // Get the password...
  798. if (IDCANCEL == DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_PASSWORD), hwnd, GetPasswordDlgProc, (LPARAM)pUserInfo))
  799. {
  800. // Don't Import
  801. return(1);
  802. }
  803. }
  804. // Format path to the OE key...
  805. lResult = RegOpenKeyEx(pUserInfo->hKey, "Software\\Microsoft\\Outlook Express\\5.0", 0, KEY_READ, &hOE);
  806. if (ERROR_SUCCESS == lResult)
  807. {
  808. // Set cb
  809. DWORD cb = ARRAYSIZE(pOptions->szStoreRoot);
  810. // Get the Store Root
  811. lResult = RegQueryValueEx(hOE, "Store Root", NULL, &dwType, (LPBYTE)pOptions->szStoreRoot, &cb);
  812. // Success
  813. if (ERROR_SUCCESS == lResult)
  814. {
  815. // Expand the string's enviroment vars
  816. if (dwType == REG_EXPAND_SZ)
  817. {
  818. // Locals
  819. CHAR szExpanded[MAX_PATH + MAX_PATH];
  820. // Expand enviroment strings
  821. ExpandEnvironmentStrings(pOptions->szStoreRoot, szExpanded, ARRAYSIZE(szExpanded));
  822. // Copy into szRoot
  823. StrCpyN(pOptions->szStoreRoot, szExpanded, ARRAYSIZE(pOptions->szStoreRoot));
  824. }
  825. }
  826. // Close the Key
  827. RegCloseKey(hOE);
  828. }
  829. // Failure ?
  830. if (ERROR_SUCCESS != lResult)
  831. {
  832. // Locals
  833. CHAR szRes[255];
  834. CHAR szTitle[255];
  835. // Get the error
  836. LoadString(g_hInst, IDS_CANT_IMPORT_ID, szRes, 255);
  837. // Get tht title
  838. LoadString(g_hInst, IDS_TITLE, szTitle, 255);
  839. // Show the error
  840. MessageBox(hwnd, szRes, szTitle, MB_OK | MB_ICONEXCLAMATION);
  841. // Put focus where the user should correct their mistake
  842. SetFocus(GetDlgItem(hwnd, IDC_IDLIST));
  843. // Done
  844. return(1);
  845. }
  846. }
  847. }
  848. // Delete all the hkey
  849. cIds = (int) SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_GETCOUNT, 0, 0);
  850. if (LB_ERR != cIds)
  851. {
  852. // Loop through the items
  853. for (LRESULT iItem=0; iItem<(LRESULT)cIds; iItem++)
  854. {
  855. // Get the hKey
  856. LPUSERINFO pUserInfo = (LPUSERINFO)SendMessage(GetDlgItem(hwnd, IDC_IDLIST), LB_GETITEMDATA, iItem, 0);
  857. // Close the Reg Key
  858. RegCloseKey(pUserInfo->hKey);
  859. // Free pUserInfo
  860. CoTaskMemFree(pUserInfo);
  861. }
  862. }
  863. // Fone with dialog
  864. EndDialog(hwnd, LOWORD(wParam));
  865. // Done
  866. return(1);
  867. // Id List
  868. case IDC_FROM_DIRECTORY:
  869. case IDC_FROM_ID:
  870. {
  871. BOOL f = IsDlgButtonChecked(hwnd, IDC_FROM_ID);
  872. EnableWindow(GetDlgItem(hwnd, IDC_IDLIST), f);
  873. }
  874. return(1);
  875. }
  876. // Done
  877. break;
  878. }
  879. // Not Handled
  880. return(0);
  881. }
  882. IMailImport *OE5SimpleCreate(PSTR pszDir)
  883. {
  884. HRESULT hr = S_OK;
  885. // Trace
  886. TraceCall("OE5SimpleCreate");
  887. // Create me
  888. COE5Import *pNew=NULL;
  889. pNew = new COE5Import();
  890. IF_NULLEXIT(pNew);
  891. hr = pNew->SetDirectory(pszDir);
  892. if (FAILED(hr)) {
  893. pNew->Release();
  894. pNew = NULL;
  895. }
  896. exit:
  897. return (IMailImport *)pNew;
  898. }