//////////////////////////////////////////////////////////////////////////////////////
// W2K TIF files import support
//

#include "stdafx.h"
#include <tiff.h>
#include <Sddl.h>
#include <shlobjp.h> // LinkWindow control

#define __FILE_ID__     75

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifdef UNICODE

#define WM_IMPORT_PROGRESS_INC     WM_APP + 3 // Increment Import progress bar
#define WM_IMPORT_SET_FILE_COUNT   WM_APP + 4 // Set the file number to import

extern CClientConsoleApp theApp;

//
// Structure passed to the ImportArchiveFolder thread
//
struct ImportFolderParam
{
    LPCWSTR cszImportFolder; // Import folder name
    BOOL    bSentItems;      // TRUE if the folder contains outbound faxes
    HWND    hImportDlg;      // Handle to the Import progress dialog
    BOOL    bCancel;         // TRUE if the Cancel button has been pressed
};


DWORD 
ImportArchiveFile(
    LPCWSTR    pszFile, 
    LPWSTR     pszArchiveFolder, 
    BOOL       bSentItems,
    WCHAR*     pszUserSid,
    DWORDLONG* pdwlUniqueId
)
/*++

Routine name : ImportArchiveFile

Routine description:

    Imports pszFile file to the pszArchiveFolder folder.
    The pszFile should be generated by W2K MS Fax

Arguments:

    pszFile            - [in]  Imported file name
    pszArchiveFolder   - [in]  MS Fax archive folder name
    bSentItems         - [in]  TRUE if the file from the sent archive, FALSE if it from receive one
    pszUserSid         - [in]  The user string SID, can be NULL if(bSentItems == FALSE)
    pdwlUniqueId       - [out] Unique id for the file

Return Value:

    Standard Win32 error code

--*/
{
    DWORD dwRes = ERROR_SUCCESS;
    DBG_ENTER(TEXT("ImportArchive"), dwRes);

    WCHAR* pszFileExt = FAX_TIF_FILE_EXT;
    WCHAR  szArchFile[MAX_PATH] = {0};

    MS_TAG_INFO  msTags = {0};

    //
    // Generate unique file name in the archive folder
    // 
    *pdwlUniqueId = GenerateUniqueFileName(pszArchiveFolder, 
                                           pszFileExt, 
                                           szArchFile, 
                                           ARR_SIZE(szArchFile));
    if(*pdwlUniqueId == 0)
    {
        dwRes = GetLastError();
        CALL_FAIL (GENERAL_ERR, TEXT ("GenerateUniqueFileName"), dwRes);
        goto exit;
    }

    if(bSentItems)
    {
        //
        // Add user user SID to the file name for the outbound archive
        //
        // Delete generated file without the user SID in the name
        //
        if(!DeleteFile(szArchFile))
        {
            CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
        }

        //
        // Add the user SID to the file name
        //
        if (_sntprintf(szArchFile,
                       ARR_SIZE(szArchFile),
                       TEXT("%s\\%s$%I64X%s"),
                       pszArchiveFolder,
                       pszUserSid,
                       *pdwlUniqueId,
                       FAX_TIF_FILE_DOT_EXT) < 0)
        {
            dwRes = ERROR_BUFFER_OVERFLOW;
            CALL_FAIL (GENERAL_ERR, TEXT ("Insufficient szArchFile buffer"), dwRes);
            goto exit;
        }
    }

    if(!CopyFile(pszFile, szArchFile, FALSE))
    {
        dwRes = GetLastError();
        CALL_FAIL (GENERAL_ERR, TEXT ("CopyFile"), dwRes);
        goto exit;
    }

    //
    // Read W2K MS TIF tags from the file
    //
    dwRes = GetW2kMsTiffTags(szArchFile, &msTags, bSentItems);
    if(ERROR_SUCCESS == dwRes)
    {
        //
        // Add new (XP) MS TIF tags to the file
        //
        if(!TiffAddMsTags(szArchFile, &msTags, bSentItems))
        {
            dwRes = GetLastError();
            CALL_FAIL (GENERAL_ERR, TEXT ("TiffAddMsTags"), dwRes);

            if(!DeleteFile(szArchFile))
            {
                CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
            }
            goto exit;
        }
    }
    else if(ERROR_XP_TIF_FILE_FORMAT == dwRes)
    {
        //
        // The TIF file already has new (XP) TIF tags
        //
        dwRes = ERROR_SUCCESS;
    }
    else
    {
        //
        // The tiff file was not created by MS fax
        //
        if(!DeleteFile(szArchFile))
        {
            CALL_FAIL (GENERAL_ERR, TEXT ("DeleteFile"), GetLastError());
        }
    }

exit:    

    FreeMsTagInfo(&msTags);

    return dwRes;

} // ImportArchiveFile


DWORD 
WINAPI 
ImportArchiveFolder(
    LPVOID lpParameter   // thread data
)
/*++

Routine name : ImportArchiveFolder

Routine description:

    Imports fax (tif) files from the cstrImportFolder folder to the MS Fax archive.
    Returns ERROR_FILE_NOT_FOUND if the folder does not contain TIF files

Arguments:

    lpParameter   - [in] pointer to ImportFolderParam structure

Return Value:

    Standard Win32 error code

--*/
{
    ImportFolderParam* pParam = (ImportFolderParam*)lpParameter;

    DWORD dwRes = ERROR_SUCCESS;
    DWORD dwError;
    int   nRes;
    WCHAR szFindMask[MAX_PATH] = {0};
    WCHAR szImportFile[MAX_PATH] = {0};
    WIN32_FIND_DATA findData = {0};
    HANDLE hFile = INVALID_HANDLE_VALUE;

    HANDLE hFax = NULL;
    PFAX_ARCHIVE_CONFIG pArchiveCfg = NULL;

    PSID   pUserSid   = NULL;
    WCHAR* pszUserSid = NULL;

    DWORDLONG dwlUniqueId;
    DWORD     dwFileCount = 0;
    DWORD     dwNotifyMsgID = 0; // Windows message id used for notification


    DBG_ENTER(TEXT("ImportFolderThread"), dwRes);

    //
    // Compose find mask: path\*.tif
    //
    _snwprintf(szFindMask, MAX_PATH-1, TEXT("%s\\%s"), pParam->cszImportFolder, FAX_TIF_FILE_MASK);

    //
    // Count TIF files in the pParam->cszImportFolder folder
    //
    // Find the first tif file in the cstrImportFolder
    //
    hFile = FindFirstFile(szFindMask, &findData);
    if(INVALID_HANDLE_VALUE == hFile)
    {
        dwRes = GetLastError();
        CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), dwRes);
        goto exit;
    }

    dwFileCount = 1;
    for(;;)
    {
        //
        // Find Next File
        //
        if(!FindNextFile(hFile, &findData))
        {
            dwError = GetLastError();
            if(ERROR_NO_MORE_FILES != dwError)
            {
                dwRes = dwError;
                CALL_FAIL (GENERAL_ERR, TEXT ("FindNextFile"), dwRes);
            }
            break;
        }
        dwFileCount += 1;
    }

    if(INVALID_HANDLE_VALUE != hFile)
    {
        FindClose(hFile);
    }

    if(pParam->hImportDlg)
    {
        //
        // Set progress bar range
        //
        SendMessage(pParam->hImportDlg, WM_IMPORT_SET_FILE_COUNT, dwFileCount, 0);
    }


    //
    // Find the first tif file in the cstrImportFolder
    //
    hFile = FindFirstFile(szFindMask, &findData);
    if(INVALID_HANDLE_VALUE == hFile)
    {
        dwRes = GetLastError();
        CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), dwRes);
        goto exit;
    }

    //
    // Get fax server archive configuration
    //
    if(!FaxConnectFaxServer(NULL, &hFax))
    {
        dwRes = GetLastError();
        CALL_FAIL (RPC_ERR, TEXT ("FaxConnectFaxServer"), dwRes);
        goto exit;
    }

    //
    // Get pointer to the Client Console archive folder
    //
    if(theApp.m_pMainWnd)
    {   
        CClientConsoleDoc* pDoc = NULL;
        pDoc = (CClientConsoleDoc*)((CFrameWnd*)theApp.m_pMainWnd)->GetActiveDocument();
        if(pDoc)
        {
            //
            // find local fax server
            //
            CServerNode* pServer = NULL;
            pServer = pDoc->FindServerByName(NULL);
            if(pServer)
            {
                //
                // Get archive folder
                //
                CFolder* pFolder = NULL;
                pFolder = pServer->GetFolder(pParam->bSentItems ? FOLDER_TYPE_SENT_ITEMS : FOLDER_TYPE_INBOX);
                if(pFolder && pFolder->IsValid())
                {
                    dwNotifyMsgID = pServer->GetNotifyMsgID();
                }
            }
        }
    }

    //
    // Access check
    //
    DWORD dwAccessRights;
    if (!FaxAccessCheckEx(hFax, 
                          pParam->bSentItems ? FAX_ACCESS_MANAGE_OUT_ARCHIVE : FAX_ACCESS_MANAGE_IN_ARCHIVE, 
                          &dwAccessRights))
    {
        dwRes = GetLastError();
        CALL_FAIL (RPC_ERR, TEXT ("FaxAccessCheckEx"), dwRes);

        AlignedAfxMessageBox(IDS_IMPORT_NO_ACCESS, MB_OK | MB_ICONSTOP | MB_APPLMODAL);

        goto exit;
    }

    if(!FaxGetArchiveConfiguration(hFax, 
                                   pParam->bSentItems ? FAX_MESSAGE_FOLDER_SENTITEMS : FAX_MESSAGE_FOLDER_INBOX,
                                   &pArchiveCfg))
    {
        dwRes = GetLastError();
        CALL_FAIL (RPC_ERR, TEXT ("FaxGetArchiveConfiguration"), dwRes);
        goto exit;
    }

    if(pParam->bSentItems)
    {
        //
        // Get the user string SID for the outbound archive
        //
        pUserSid = GetCurrentThreadSID();
        if (!pUserSid)
        {
            dwRes = GetLastError ();
            CALL_FAIL (GENERAL_ERR, TEXT ("GetCurrentThreadSID"), dwRes);
            goto exit;
        }

        if (!ConvertSidToStringSid(pUserSid, &pszUserSid))
        {
            dwRes = GetLastError ();
            CALL_FAIL (GENERAL_ERR, TEXT ("ConvertSidToStringSid"), dwRes);
            goto exit;
        }
    }

    while(!pParam->bCancel)
    {
        //
        // Compose full path 
        //
        _snwprintf(szImportFile, MAX_PATH-1, TEXT("%s\\%s\0"), pParam->cszImportFolder, findData.cFileName);

        nRes = IDOK;
        do
        {
            //
            // Import the file
            //
            dwError = ImportArchiveFile(szImportFile, 
                                        pArchiveCfg->lpcstrFolder, 
                                        pParam->bSentItems, 
                                        pszUserSid, 
                                        &dwlUniqueId);
            if(ERROR_SUCCESS != dwError)
            {
                CALL_FAIL (GENERAL_ERR, TEXT ("ImportArchiveFile"), dwRes);

                //
                // Popup "Cancel, Try Again, Continue" dialog
                //
                DWORD dwResId = IDS_IMPORT_ERROR; 
                WCHAR szFormat[MAX_PATH] = {0};
                WCHAR szMsg[MAX_PATH] = {0};

                if(ERROR_BAD_FORMAT == dwError)
                {
                    dwResId = IDS_IMPORT_BAD_FORMAT;
                }

                if(LoadString(GetResourceHandle(), 
                              dwResId,
                              szFormat, 
                              ARR_SIZE(szFormat)))
                {
                    _snwprintf(szMsg, MAX_PATH-1, szFormat, findData.cFileName);

                    nRes = AlignedAfxMessageBox(szMsg, MB_CANCELTRYCONTINUE | MB_ICONSTOP | MB_APPLMODAL);  

                    if(IDCANCEL == nRes)
                    {
                        pParam->bCancel = TRUE;
                    }
                }
                else
                {
                    CALL_FAIL (GENERAL_ERR, TEXT ("LoadString(IDS_IMPORT_ERROR)"), GetLastError());
                }
            }
        }
        while(nRes == IDTRYAGAIN);

        if(dwNotifyMsgID)
        {
            //
            // Add the message to the archive folder
            // We simulate the server notification handled by the application main thread
            // The notification handler should free the event data
            //
            FAX_EVENT_EX* pEvent = (FAX_EVENT_EX*)MemAlloc(sizeof(FAX_EVENT_EX));
            if(!pEvent)
            {
                dwRes = ERROR_NOT_ENOUGH_MEMORY;
                CALL_FAIL (GENERAL_ERR, TEXT ("MemAlloc"), dwRes);
                goto exit;
            }
            ZeroMemory(pEvent, sizeof(FAX_EVENT_EX));

            pEvent->dwSizeOfStruct = sizeof(FAX_EVENT_EX);
            pEvent->EventType = pParam->bSentItems ? FAX_EVENT_TYPE_OUT_ARCHIVE : FAX_EVENT_TYPE_IN_ARCHIVE;
            pEvent->EventInfo.JobInfo.Type = FAX_JOB_EVENT_TYPE_ADDED;
            pEvent->EventInfo.JobInfo.dwlMessageId = dwlUniqueId;

            theApp.m_pMainWnd->SendMessage(dwNotifyMsgID, 0, (LPARAM)pEvent);
        }

        if(pParam->hImportDlg)
        {
            //
            // Increment progress bar
            //
            SendMessage(pParam->hImportDlg, WM_IMPORT_PROGRESS_INC, 0, 0);
        }

        //
        // Find Next File
        //
        if(!FindNextFile(hFile, &findData))
        {
            dwError = GetLastError();
            if(ERROR_NO_MORE_FILES != dwError)
            {
                dwRes = dwError;
                CALL_FAIL (GENERAL_ERR, TEXT ("FindNextFile"), dwRes);
            }
            break;
        }
    } // while

    //
    // Notify the fax service
    //
    if(!FaxRefreshArchive(hFax, 
                          pParam->bSentItems ? FAX_MESSAGE_FOLDER_SENTITEMS : FAX_MESSAGE_FOLDER_INBOX))
    {
        dwRes = GetLastError();
        CALL_FAIL (GENERAL_ERR, TEXT ("FaxArchiveMessageAdded"), dwRes);
    }


exit:

    if(pParam->hImportDlg)
    {
        //
        // Close the Progress dialog
        //
        SendMessage(pParam->hImportDlg, WM_CLOSE, 0, 0);
    }

    if(0 == dwFileCount)
    {
        //
        // The folder does not contain faxes
        //
        AlignedAfxMessageBox(IDS_IMPORT_EMPTY_FOLDER, MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL);
    }

    if(INVALID_HANDLE_VALUE != hFile)
    {
        FindClose(hFile);
    }

    if(pArchiveCfg)
    {
        FaxFreeBuffer(pArchiveCfg);
    }

    if(hFax)
    {
        FaxClose(hFax);
    }

    if(pUserSid)
    {
        MemFree(pUserSid);
    }

    if(pszUserSid)
    {
        LocalFree(pszUserSid);
    }

    return dwRes;

} // ImportArchiveFolder


INT_PTR 
CALLBACK 
ImportDlgProc(
  HWND hwndDlg,  // handle to dialog box
  UINT uMsg,     // message
  WPARAM wParam, // first message parameter
  LPARAM lParam  // second message parameter
)
/*++

Routine description:

    Import fax dialog procedure

Arguments:

  HWND hwndDlg,  // handle to dialog box
  UINT uMsg,     // message
  WPARAM wParam, // first message parameter
  LPARAM lParam  // second message parameter

Return Value:

    return TRUE if it processed the message

--*/

{
    static ImportFolderParam* pIpmParam = NULL;
    static DWORD dwFileCount;   // The number of the files to import
    static DWORD dwCurrentFile; // The number of the currently imported file

    switch ( uMsg )
    {
        case WM_INITDIALOG:
            {
                HANDLE hImportThread = NULL;
                pIpmParam = (ImportFolderParam*)lParam;
                TCHAR szFolder[MAX_PATH] = {0};

                DBG_ENTER(TEXT("ImportDlgProc(WM_INITDIALOG)"));


                dwFileCount = 0;
                dwCurrentFile = 0;

                //
                // Set import folder name
                //
                if(LoadString(GetResourceHandle(), 
                              pIpmParam->bSentItems ? IDS_IMPORT_TO_SENT_ITEMS : IDS_IMPORT_TO_INBOX,
                              szFolder, 
                              ARR_SIZE(szFolder)))
                {
                    SetDlgItemText(hwndDlg, IDC_IMPORT_FOLDER, szFolder);
                }
                else
                {
                    CALL_FAIL (GENERAL_ERR, TEXT ("LoadString() for IDC_IMPORT_FOLDER"), GetLastError());
                }

                pIpmParam->hImportDlg   = hwndDlg;

                hImportThread = CreateThread(NULL,                // SD
                                             0,                   // initial stack size
                                             ImportArchiveFolder, // thread function
                                             (LPVOID)pIpmParam,   // thread argument
                                             0,                   // creation option
                                             NULL);               // thread identifier
                if(!hImportThread)
                {
                    CALL_FAIL (GENERAL_ERR, TEXT ("CreateThread"), GetLastError());
                }
                else
                {
                    CloseHandle(hImportThread);
                }
                return TRUE;
            }

        case WM_IMPORT_PROGRESS_INC:
            {
                //
                // Increment progress bar
                //
                SendDlgItemMessage(hwndDlg, IDC_IMPORT_PROGRESS_BAR, PBM_STEPIT, 0, 0);

                //
                // Compose and set currently imported fax number
                //
                ++dwCurrentFile;

                TCHAR szFormat[MAX_PATH] = {0};
                TCHAR szText[MAX_PATH] = {0};
                DWORD dwParam[2];

                DBG_ENTER(TEXT("ImportDlgProc(WM_IMPORT_PROGRESS_INC)"));


                dwParam[0] = dwCurrentFile;
                dwParam[1] = dwFileCount;

                if(!LoadString(GetResourceHandle(), 
                               IDS_IMPORT_NUMBER,
                               szFormat, 
                               ARR_SIZE(szFormat)))
                {
                    CALL_FAIL (GENERAL_ERR, TEXT ("LoadString(IDS_IMPORT_NUMBER)"), GetLastError());
                    return TRUE;
                }

                if(FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                                (LPCVOID)szFormat,
                                0,
                                0,
                                szText,
                                ARR_SIZE(szText),
                                (va_list*)dwParam))
                {
                    SetDlgItemText(hwndDlg, IDC_PROGRESS_NUMBER, szText);
                }

                return TRUE;
            }
        case WM_IMPORT_SET_FILE_COUNT:
            //
            // Set the pange and step of the proggress bar
            //
            dwFileCount = wParam;
            dwCurrentFile = 1;

            SendDlgItemMessage(hwndDlg, IDC_IMPORT_PROGRESS_BAR, PBM_SETRANGE32, 0, dwFileCount);
            SendDlgItemMessage(hwndDlg, IDC_IMPORT_PROGRESS_BAR, PBM_SETSTEP, 1, 0);
            return TRUE;

        case WM_CLOSE:

            EndDialog(hwndDlg, IDCANCEL);

            return TRUE;

        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                case IDCANCEL:
                        
                    //
                    // Mark cancel, don't close the dialog
                    //
                    pIpmParam->bCancel = TRUE;
                    EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);

                    return TRUE;
            } 

            break;


    } // switch ( uMsg )

    return FALSE;

} // ImportDlgProc


DWORD 
ImportArchiveFolderUI(
    LPCWSTR cstrImportFolder, 
    BOOL    bSentItems,
    HWND    hWnd
)
/*++

Routine name : ImportArchiveFolderUI

Routine description:

    Opens the Import Progress dialog

Arguments:

    cstrImportFolder   - [in]  Import folder name
    bSentItems         - [in]  TRUE if the folder is the sent archive, FALSE if it is receive one
    hWnd               - [in]  Parent window

Return Value:

    Standard Win32 error code

--*/
{
    DWORD dwRes = ERROR_SUCCESS;

    ImportFolderParam impParam = {0};
    impParam.cszImportFolder   = cstrImportFolder;
    impParam.bSentItems        = bSentItems;

    DBG_ENTER(TEXT("ImportArchiveFolderUI"), dwRes);

    DialogBoxParam(GetResourceHandle(),          // handle to module
                   MAKEINTRESOURCE(IDD_IMPORT),  // dialog box template
                   hWnd,                         // handle to owner window
                   ImportDlgProc,                // dialog box procedure
                   (LPARAM)&impParam);           // initialization value

    return dwRes;

} // ImportArchiveFolderUI


BOOL
IsFaxArchive(
    WCHAR* szFolder
)
/*++

Routine name : IsFaxArchive

Routine description:

    Determine if the folder contains at least one TIF file

Arguments:

    szFolder   - [in]  folder name

Return Value:

    TRUE if if the folder contains at least one TIF file
    FALSE otherwise

--*/
{
    WCHAR szFindMask[MAX_PATH] = {0};
    WIN32_FIND_DATA findData = {0};
    HANDLE hFile = INVALID_HANDLE_VALUE;

    DBG_ENTER(TEXT("IsFaxArchive"));

    //
    // Compose find mask: path\*.tif
    //
    _snwprintf(szFindMask, MAX_PATH-1, TEXT("%s\\%s"), szFolder, FAX_TIF_FILE_MASK);

    //
    // Find the first tif file in the cstrImportFolder
    //
    hFile = FindFirstFile(szFindMask, &findData);
    if(INVALID_HANDLE_VALUE == hFile)
    {
        CALL_FAIL (GENERAL_ERR, TEXT ("FindFirstFile"), GetLastError());
        return FALSE;
    }

    FindClose(hFile);
    return TRUE;
}

INT_PTR 
CALLBACK 
ImportInfoDlgProc(
  HWND hwndDlg,  // handle to dialog box
  UINT uMsg,     // message
  WPARAM wParam, // first message parameter
  LPARAM lParam  // second message parameter
)
/*++

Routine description:

    Import inforamtion fax dialog procedure

Arguments:

  HWND hwndDlg,  // handle to dialog box
  UINT uMsg,     // message
  WPARAM wParam, // first message parameter
  LPARAM lParam  // second message parameter

Return Value:

    return TRUE if it processed the message

--*/

{
    switch (uMsg)
    {
        case WM_INITDIALOG:
            //
            // Set focus on the OK button
            //
            SetFocus(GetDlgItem(hwndDlg, IDOK));
            return FALSE;

        case WM_NOTIFY :
            {
                LPNMHDR lpnm = (LPNMHDR) lParam;
                if(lpnm->code   == NM_CLICK  && 
                   lpnm->idFrom == IDC_IMPORT_HELP_LINK)
                {
                    //
                    // Display import help
                    //
                    HtmlHelpTopic(hwndDlg, FAX_HELP_IMPORT);
                    return TRUE;
                }
            }
            break;

        case WM_COMMAND:
            switch (LOWORD(wParam))
            {
                case IDOK:
                case IDCANCEL:
                    EndDialog(hwndDlg, IDOK);
                    return TRUE;
            }                
            break;
    }
    return FALSE;
} // ImportInfoDlgProc

DWORD 
DetectImportFiles()
/*++

Routine name : DetectImportFiles

Routine description:

    Determine if the system has W2K fax archives.
    If yes warning dialog will be displayed for the first time.

Return Value:

    Standard Win32 error code

--*/
{
    DWORD dwRes = ERROR_SUCCESS;
    HKEY  hRegKey;
    DWORD dwImportWrn = 0; // 1 if the import warning has been displayed

    WCHAR* pszInbox = NULL;
    WCHAR* pszSentItems = NULL;
    DWORD  dwSize = 0;
    BOOL   bHaveFax = FALSE; // TRUE if the archives contain at least one TIF file

    DBG_ENTER(TEXT("DetectImportFiles"), dwRes);

    if(!IsWinXPOS())
    {
        return dwRes;
    }

    //
    // Check if the Import warning has been displayed
    //
    if ((hRegKey = OpenRegistryKey(HKEY_CURRENT_USER, REGKEY_FAX_SETUP, TRUE, KEY_ALL_ACCESS)))
    {
        dwImportWrn = GetRegistryDword(hRegKey, REGVAL_IMPORT_INFO);

        if(!dwImportWrn)
        {
            SetRegistryDword(hRegKey, REGVAL_IMPORT_INFO, TRUE);
        }
            
        RegCloseKey(hRegKey);
    }
    else
    {
        CALL_FAIL (GENERAL_ERR, TEXT ("OpenRegistryKey"), GetLastError());
    }

    if(dwImportWrn)
    {
        //
        // Import warning has been displayed
        //
        return dwRes;
    }

    //
    // Read W2K archives location
    //
    if (!(hRegKey = OpenRegistryKey(HKEY_LOCAL_MACHINE, REGKEY_FAX_SETUP, TRUE, KEY_QUERY_VALUE)))
    {
        CALL_FAIL (GENERAL_ERR, TEXT ("OpenRegistryKey"), GetLastError());
        return dwRes;
    }

    pszInbox = GetRegistryStringMultiSz(hRegKey, REGVAL_W2K_INBOX, NULL, &dwSize);
    pszSentItems = GetRegistryString(hRegKey, REGVAL_W2K_SENT_ITEMS, NULL);
        
    RegCloseKey(hRegKey);

    //
    // Determine if the archives have at least one TIF file
    //
    bHaveFax = IsFaxArchive(pszSentItems);

    WCHAR* pszFolder = pszInbox;
    while(!bHaveFax && pszFolder && *pszFolder)
    {
        //
        // Walk though the multiline pszInbox string
        //
        bHaveFax = IsFaxArchive(pszFolder);

        pszFolder = _wcsninc(pszFolder, wcslen(pszFolder)+1);
    }

    MemFree(pszInbox);
    MemFree(pszSentItems);

    if(bHaveFax)
    {
        if(!LinkWindow_RegisterClass())
        {
            dwRes = ERROR_CAN_NOT_COMPLETE;
            CALL_FAIL (GENERAL_ERR, TEXT ("LinkWindow_RegisterClass"), dwRes);
            return dwRes;
        }

        DialogBoxParam(GetResourceHandle(),               // handle to module
                       MAKEINTRESOURCE(IDD_IMPORT_INFO),  // dialog box template
                       theApp.m_pMainWnd->m_hWnd,         // handle to owner window
                       ImportInfoDlgProc,                 // dialog box procedure
                       NULL);                             // initialization value

        LinkWindow_UnregisterClass(theApp.m_hInstance);
    }

    return dwRes;
}

#endif //UNICODE
