<%
'SUBROUTINES DEFINED:
'"""""""""""""""""""
'SetupSessionVariables(AuthUser)		Sets up the session variables
'GetSessionStatusStr()					Returns the error string associated with the session error code
'SetError(Message)						Sets the text of the main error message
'SetReason(Message)						Sets the text of the reason paragraph
'AddFix(Message)						Adds an item to the bulleted list of suggestions
'Check_Browser_Capabilities()			Sets error if the Client browser lacks Tables and JavaScript support
'Invalid_Password()						Sets an error due to an invalid password
'IsConfID()								Sets error if the Conference ID is not set (inConfID)
'ValidateMeetingID()					Sets error if the DCS Meeting ID is not valid (inMeetingID)
'Verify_ConfLocator()					Verifies ConfLocator points to the Conference Locator
'DisplayErrorPage()						Setup the error page when we have an error
'
'FUNCTIONS DEFINED:
'"""""""""""""""""
'CheckSetError(Source, Description) Checks for error values in Result/Err and adds error messages if appropriate
'
' ================================ CONSTANTS =================================================
'ERROR CONSTANTS:
'C++ returns HRESULTS as 4-byte signed ints, so the bit pattern
'0x81000203 comes out as a negative number.
'VBScript also uses 4-byte signed ints, so assigning the bit patterns
'as below makes for better readability while still giving the 
'same negative numbers.
'If VBScript ever changes to use ints larger than 4 bytes, the
'bit patterns below will be interpreted as positive numbers and
'will have to be changed to explicitly reference the negative
'number returned by C++.
CONST E_CMS_EVENTMANAGER_NOT_INITIALIZED                = &H8004100A
CONST E_CMS_CONFERENCE_NOT_SCHEDULED                    = &H8004100B
CONST E_CMS_CONFERENCE_NOT_STARTED                      = &H8004100C
CONST E_CMS_CONFERENCE_NOT_RUNNING                      = &H8004100D
CONST E_CMS_CONFERENCE_NOT_FOUND                        = &H8004100E
CONST E_CMS_INVALID_CONFERENCE_PASSWORD                 = &H8004100F
CONST E_CMS_ANONYMOUS_USER_DENIED_ACCESS                = &H80041010
CONST E_CMS_USER_DENIED_ACCESS                          = &H80041011
CONST E_CMS_CTP_JOIN_REQUEST_FAILED                     = &H80041012
CONST E_CMS_PROVIDER_NOT_INITIALIZED                    = &H80041013
CONST E_CMS_PROVIDER_NOT_FOUND                          = &H80041014
CONST E_CMS_E_CONFERENCE_NOT_EXIST                      = &H80041015
CONST E_CMS_RECURRING_CONFERENCE_NOT_FOUND              = &H80041016
CONST E_CMS_NOT_HOST_SERVER                             = &H80041017
CONST E_CMS_RECURRING_INSTANCE_NOT_WITHIN_TIME_BOUND    = &H80041018
CONST E_CMS_AMBIGUOUS_RECURRING_JOIN                    = &H80041019
CONST E_CMS_TIME_EXTENSIONS_NOT_ALLOWED                 = &H8004101B
CONST E_CMS_RESOURCE_EXTENSIONS_NOT_ALLOWED             = &H8004101C
CONST E_CMS_SERVER_NOT_INITIALIZED                      = &H80041037
CONST E_CMS_PROFILE_STORE_NOT_INITIALIZED               = &H80041038
CONST E_CMS_SHUTTING_DOWN                               = &H4101E

CONST E_DCS_NO_MCUS_AVAILABLE                           = &H8004F001
CONST E_DCS_CONFERENCE_NOT_RUNNING                      = &H8004F002
CONST E_DCS_CONFERENCE_ALREADY_ENDED                    = &H8004F003
CONST E_DCS_ACCESS_DENIED_CAPACITY_LIMIT                = &H8004F004
CONST E_DCS_NO_PROXY_MCUS_AVAILABLE                     = &H8004F005
CONST E_DCS_NO_INTERNET_MCUS_AVAILABLE                  = &H8004F006
CONST E_DCS_NOT_RUNNING                                 = &H8004F007
CONST E_DCS_NOT_INIT                                    = &H8004F008

CONST E_NETMEETING_ERRORS_MASK                          = &H80040300
CONST E_NETMEETING_INVITE_FAILURE                       = &H8004036A
CONST E_NETMEETING_INVITE_TIMEOUT                       = &H80040372

CONST E_PKCS7_NO_CERT_STORE                             = &H80043000
CONST E_SESSION_UNAVAILABLE                             = &H80043001
CONST E_NO_DISPLAY_STATE                                = &H80043002
CONST E_UNSUPPORTED_TABLES_BROWSER                      = &H80043003
CONST E_UNSUPPORTED_JAVASCRIPT_BROWSER                  = &H80043004

CONST E_ACCESS_DENIED                                   = 70 '&H80070005 comes across as error 70 if returned
CONST E_ACCESS_DENIED_HRESULT                           = &H80070005 'if passed back as a result
CONST E_SERVER_CREATE_OBJECT                            = &H800401F3 'Server.CreateObject() error
CONST NM_E_NOT_ACTIVE                                   = &H81000203 'NetMeeting was closed since last use
CONST E_NO_GLOBAL_CONF_CALENDAR                         = &H80010105
CONST E_DSGETSITENAME_NO_SITE                           = &H8007077F
CONST E_MANUAL_JOIN_INSTRUCTIONS                        = &H80040100
CONST E_CMS_RESTARTED                                   = &H1CE

CONST E_MCU_HANG                                        = &H800706BA
CONST E_MCU_NO_SERVER_CERTIFICATE                       = &H80070546

'DISPLAY STATE CONTANTS:
'These define the various display states that can be used
'The quotes are required because the state is passed as a string
'The DCS programmatically uses {0,7,8} so those cannot easily be changed
CONST DISPLAY_JOIN                      = "0"
CONST DISPLAY_JOIN_PASSWORD             = "6"
CONST DISPLAY_PREJOIN                   = "7"
CONST DISPLAY_POSTJOIN                  = "8"
CONST DISPLAY_NO_MADCAP_SERVERS         = "9"
CONST DISPLAY_TOO_MANY_USERS            = "10"
CONST DISPLAY_ALL_MADCAP_SERVERS_FAILED = "11"
CONST DISPLAY_NO_MADCAP_SERVERS_MATCH_SCOPE = "12"
CONST DISPLAY_NO_MADCAP_SCOPES_FOUND    = "13"
CONST DISPLAY_NO_SCOPES_IN_RESOURCE     = "14"
CONST DISPLAY_MAX_JOIN_TYPES            = "14"
CONST DISPLAY_MULTICAST_CLIENT          = "15"
CONST DISPLAY_H323_CLIENT               = "16"
CONST DISPLAY_OLDER_H323_CLIENT         = "51"
CONST DISPLAY_NO_AUDIOVIDEO_CLIENT      = "52"
CONST DISPLAY_NO_AUDIOVIDEO_ACTIVEX     = "53"

CONST DISPLAY_WELCOME                   = "11"
CONST DISPLAY_RECURRING                 = "14"
CONST DISPLAY_AGENDA                    = "17"
CONST DISPLAY_MODIFY                    = "18"
CONST DISPLAY_MAX_NO_JOIN_TYPES         = "19"

CONST DISPLAY_MIN_ERR_TYPES             = "20"
CONST DISPLAY_ERR_CONFID                = "22"
CONST DISPLAY_ERR_CTP_STARTUP           = "23"
CONST DISPLAY_ERR_VALUE                 = "38"
CONST DISPLAY_MAX_ERR_TYPES             = "39"

'SESSION VARIABLE CONSTANTS
CONST SESSION_CONFPROFILE            = "ConfProfile"
CONST SESSION_CONFLOCATOR            = "ConfLocator"
CONST SESSION_CMSZONE                = "CMSZone"
CONST SESSION_CMSCONFIG              = "CMSConfig"
CONST SESSION_MEETINGID              = "MeetingID"
CONST SESSION_RESULT                 = "Result"
CONST SESSION_ERRNUMBER              = "ErrNumber"
CONST SESSION_ERRSOURCE              = "ErrSource"
CONST SESSION_ERRDESCRIPTION         = "ErrDescription"
CONST SESSION_STATUS                 = "Status"
CONST SESSION_ATTENDEE               = "Attendee"
CONST SESSION_PASSWORD				 = "Password"

CONST L_Page_HTMLTitle       = "Microsoft Exchange Conferencing"
CONST L_ErrorPage_HTMLTitle  = "Microsoft Exchange Conferencing - 錯誤"
CONST L_TryTheFollowing_Text = "請嘗試下列:"

'Session debugging/status information strings (must stay the same as global.asa)
CONST L_OK_Text                 = "確定"
CONST L_GetConfLocator_Text     = "無法自會議管理區取得會議定址器"
CONST L_GetZone_Text            = "無法從會議管理設定物件找到時區"
CONST L_CreateObject_Text       = "無法起始會議管理設定物件"
CONST L_Unknown_Text            = "未知"
CONST L_Uninitialized_Text      = "未起始"

'Common strings
CONST L_MCUProxyInvite_ErrorMessage     = "若您試著透過 proxy 伺服器參加會議，Data Conferencing Service 可能無法連接到您的用戶端程式。要手動連接您的資料會議用戶端，請使用下列資訊:"
CONST L_ManualJoinServer_ErrorMessage   = "Data Conferencing Server: "
CONST L_ManualJoinID_ErrorMessage       = "會議 ID: "
CONST L_ManualJoinPassword_ErrorMessage = "會議密碼:"
CONST L_NetMeetingInviteTitle_ErrorMessage  = "資料會議邀請失敗"
CONST L_NetMeetingInviteReason_ErrorMessage = "Data Conferencing Service 無法邀請您的 T.120 資料會議用戶端程式 (例如 Microsoft NetMeeting) 參加會議。"
CONST L_NetMeetingInviteFix1_ErrorMessage   = "請檢查您是否已經啟動會議用戶端程式，再試著加入會議。"
CONST L_LinkToConferenceListsFix_ErrorMessage  = "請從可用的會議清單"
CONST L_LinkToConferenceListsFix2_ErrorMessage = "選擇目前的會議。"

CONST PR_SUBJECT             = "subject"   'Defines the subject property code for user properties
CONST PR_BODY                = "268435487" 'Defines the body text property code for user properties
CONST PR_BODY_HTML           = "269680670" 'Defines the body text (in HTML) property code for user properties
CONST MAPI_RESOURCE          = "MAPI"      'Defines the resource used when getting user properties

CONST CONF_ID_CODED_LENGTH   = 255 'Length of the Base-64 encoded conference ID
CONST CONF_ID_DECODED_LENGTH = 22 'Conference ID must be 22 digits

' ================================ VARIABLES =================================================
'ERROR VARIABLES:
DIM ErrorMsg        'Holds the main error message (displayed at the top of the error page)
DIM Reason          'Holds the paragraph description of the error (displayed below the main message)
DIM Fixes()         'Holds the suggested remedies (displayed in the bulleted list below the paragraph)
DIM HiddenError     'Holds the system-level error message (displayed in small print at the bottom)
DIM ErrorCount      'Counts the errors encountered (0 or 1)
DIM Result          'Global variable used for function return values
DIM SessionErr(5)   'Holds the error messages that are defined in the session variables code to allow localization

' =============================== INITIALIZATION ==============================================
ErrorMsg        = ""
HiddenError     = ""
Reason          = ""
ErrorCount      = 0
Result          = 0
SessionErr(0)   = L_OK_Text
SessionErr(1)   = L_GetConfLocator_Text
SessionErr(2)   = L_GetZone_Text
SessionErr(3)   = L_CreateObject_Text
SessionErr(4)   = L_Unknown_Text
SessionErr(5)   = L_Uninitialized_Text
REDIM Fixes(0)                          'Puts the array Fixes in a known state

' ================================ FUNCTIONS =================================================
'== SUB: Sets up the session variables (GetSessionStatusStr() is used for SESSION_STATUS strings)
SUB SetupSessionVariables(AuthUser)
    ON ERROR RESUME NEXT

    DIM CMSConfiguration
    DIM CMSZone
    DIM ConfLocator
    
    Session(SESSION_RESULT)          = 0
    Session(SESSION_ERRNUMBER)       = 0
    Session(SESSION_ERRSOURCE)       = 0
    Session(SESSION_ERRDESCRIPTION)  = 0
    Session(SESSION_STATUS)          = 5 'L_Uninitialized_Text
    
    'Create the CMS Configuration object (dllhost will create this from xcmsadm)
    SET CMSConfiguration = Server.CreateObject("XCMSCOM.CMSConfiguration")
    
    IF (0 <> Err.Number) THEN
        Session(SESSION_ERRNUMBER)      = Err.Number
        Session(SESSION_ERRSOURCE)      = Err.Source
        Session(SESSION_ERRDESCRIPTION) = Err.Description
        Err.Clear()
        Session(SESSION_STATUS)         = 3 'L_CreateObject_Text
        EXIT SUB
    END IF
    
    SET Session(SESSION_CMSCONFIG) = CMSConfiguration 'Save the singleton CMSConfig for up to 20 mins
    
    'Create the CMS Zone object (dllhost will create this from xcmsadm)
    CALL CMSConfiguration.GetZone("", CMSZone)
    
    IF (0 <> Err.Number) THEN
        Session(SESSION_RESULT)         = Err.Number
        Session(SESSION_ERRNUMBER)      = Err.Number
        Session(SESSION_ERRSOURCE)      = Err.Source
        Session(SESSION_ERRDESCRIPTION) = Err.Description
        Err.Clear()
        Session(SESSION_STATUS)         = 2 'L_GetZone_Text
        EXIT SUB
    END IF
    
    SET Session(SESSION_CMSZONE) = CMSZone 'Save the CMS Zone object for use later
    
    'Create the Conference Locator object (dllhost will create this from the xconfmgr service)
    CALL CMSZone.GetConferenceLocator(ConfLocator)
    
    IF (0 <> Err.Number) THEN
        Session(SESSION_RESULT)         = Err.Number
        Session(SESSION_ERRNUMBER)      = Err.Number
        Session(SESSION_ERRSOURCE)      = Err.Source
        Session(SESSION_ERRDESCRIPTION) = Err.Description
        Err.Clear()
        Session(SESSION_STATUS)         = 1 'L_GetConfLocator_Text
        EXIT SUB
    END IF

	Session(SESSION_ATTENDEE)		 = AuthUser
	    
    SET Session(SESSION_CONFLOCATOR) = ConfLocator 'Save the Conference Locator for use later
    Session(SESSION_STATUS)          = 0 'L_OK_Text
END SUB

'== SUB: Creates the session status string that we use on the bottom of the error pages
FUNCTION GetSessionStatusStr(errVal)
    IF (errVal >= 0 AND errVal <= 5) THEN
        GetSessionStatusStr = SessionErr(errVal)
    ELSE
        GetSessionStatusStr = errVal
    END IF
END FUNCTION

'== SUB: Sets the text of the main error message
SUB SetError(Message, Value, Source, Description)
    IF (0 = ErrorCount) THEN
        ErrorCount  = ErrorCount + 1
        ErrorMsg    = ErrorMsg & Message
        HiddenError = HiddenError & Source & " Error #" & Hex(Value) & ": " & Description & vbNewLine
    END IF
END SUB

'== SUB: Sets the text of the reason paragraph
SUB SetReason(Message)
    Reason = Message
END SUB

'== SUB: Adds an item to the bulleted list of suggestions
SUB AddFix(Message)
    DIM NewSize
    
    NewSize = UBound(Fixes) + 1
    REDIM PRESERVE Fixes(NewSize)
    
    Fixes(NewSize) = Message
END SUB

'== FUNCTION: Checks for error values in Result/Err and adds error messages if appropriate
FUNCTION CheckSetError(ResultSource, ResultDescription)
    DIM Value, Source, Description
    
    IF (0 <> Err.Number) THEN
        Value       = Err.Number
        Source      = Err.Source & " / [" & ResultSource & "]"
        Description = Err.Description & " / [" & ResultDescription & "]"
        Err.Clear()
    ELSEIF (0 <> Result) THEN
        IF (IsNumeric(Result)) THEN
            Value = CDbl(Result)
        ELSE
            Value = Result
        END IF
        Source      = ResultSource
        Description = ResultDescription
        Result      = 0
    ELSE
        CheckSetError = FALSE
        EXIT FUNCTION
    END IF

    'Bitwise-AND to detect all NetMeeting errors
    IF (E_NETMEETING_ERRORS_MASK = (E_NETMEETING_ERRORS_MASK AND Value)) THEN

        IF (E_NETMEETING_INVITE_FAILURE = Value) THEN
            
            CALL SetError(L_NetMeetingInviteTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NetMeetingInviteReason_ErrorMessage)
            CALL AddFix(L_NetMeetingInviteFix1_ErrorMessage)
            CALL AddFix(L_MCUProxyInvite_ErrorMessage)
            CALL AddFix(L_ManualJoinServer_ErrorMessage & Session("MCUAddress"))
            CALL AddFix(L_ManualJoinID_ErrorMessage & Request.QueryString("ID"))
            CALL AddFix(L_ManualJoinPassword_ErrorMessage & Session(SESSION_PASSWORD))
        ELSEIF (E_NETMEETING_INVITE_TIMEOUT = Value) THEN
            CONST L_NetMeetingInviteTimeoutTitle_ErrorMessage  = "資料會議邀請逾時"
            CONST L_NetMeetingInviteTimeoutReason_ErrorMessage = "在伺服器嘗試邀請您的會議用戶端程式 (例如 Microsoft NetMeeting) 加入會議的過程中，這個資料會議伺服器送出的邀請已過期。"
            CONST L_NetMeetingInviteTimeoutFix1_ErrorMessage   = "請重新加入會議並接受伺服器的邀請。由於桌面上的邀請可能被使用中的視窗遮住，請將邀請視窗移至最上層。"
            
            CALL SetError(L_NetMeetingInviteTimeoutTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NetMeetingInviteTimeoutReason_ErrorMessage)
            CALL AddFix(L_NetMeetingInviteTimeoutFix1_ErrorMessage)
            CALL AddFix(L_MCUProxyInvite_ErrorMessage)
            CALL AddFix(L_ManualJoinServer_ErrorMessage & Session("MCUAddress"))
            CALL AddFix(L_ManualJoinID_ErrorMessage & Request.QueryString("ID"))
            CALL AddFix(L_ManualJoinPassword_ErrorMessage & Session(SESSION_PASSWORD))
        ELSE
            CONST L_NetMeetingMaskTitle_ErrorMessage  = "NetMeeting 衝突"
            CONST L_NetMeetingMaskReason_ErrorMessage = "NetMeeting 正控制您電腦上的資源，否則可能是其運作不正常。"
            CONST L_NetMeetingMaskFix1_ErrorMessage   = "請關閉其他可能與 NetMeeting 發生衝突的視訊、音訊或網路程式。"
            
            CALL SetError(L_NetMeetingMaskTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NetMeetingMaskReason_ErrorMessage)
            CALL AddFix(L_NetMeetingMaskFix1_ErrorMessage)
            CALL AddFix(L_MCUProxyInvite_ErrorMessage)
            CALL AddFix(L_ManualJoinServer_ErrorMessage & Session("MCUAddress"))
            CALL AddFix(L_ManualJoinID_ErrorMessage & Request.QueryString("ID"))
            CALL AddFix(L_ManualJoinPassword_ErrorMessage & Session(SESSION_PASSWORD))
        END IF

        EXIT FUNCTION
    END IF

    SELECT CASE Value
        CASE E_CMS_EVENTMANAGER_NOT_INITIALIZED,E_CMS_SERVER_NOT_INITIALIZED
            CONST L_EventManagerNotInitializedTitle_ErrorMessage  = "伺服器未起始"
            CONST L_EventManagerNotInitializedReason_ErrorMessage = "Exchange Conferencing Service 正在啟動，程序尚未完成。"
            CONST L_EventManagerNotInitializedFix1_ErrorMessage   = "請稍後再試。"
            
            CALL SetError(L_EventManagerNotInitializedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_EventManagerNotInitializedReason_ErrorMessage)
            CALL AddFix(L_EventManagerNotInitializedFix1_ErrorMessage)
        
        CASE E_CMS_PROFILE_STORE_NOT_INITIALIZED
            CONST L_ServerOrProfileStoreNotInitializedTitle_ErrorMessage    = "伺服器存放區未起始"
            CONST L_ServerOrProfileStoreNotInitializedReason_ErrorMessage   = "Exchange Conferencing Server 未起始。"
            CONST L_ProfileStoreNotInitializedFix1_ErrorMessage             = "請與您的系統管理員聯繫。會議行事曆信箱存放可能無法使用。"
                        
            CALL SetError(L_ServerOrProfileStoreNotInitializedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ServerOrProfileStoreNotInitializedReason_ErrorMessage)
            CALL AddFix(L_ProfileStoreNotInitializedFix1_ErrorMessage)

        CASE E_CMS_CONFERENCE_NOT_RUNNING
            CONST L_ConferenceNotRunningCMSTitle_ErrorMessage  = "未進行的會議"
            CONST L_ConferenceNotRunningCMSReason_ErrorMessage = "要存取的會議尚未就緒或者會議技術提供程式不允許會議開始。"
            CONST L_ConferenceNotRunningCMSFix1_ErrorMessage   = "請等候數分鐘，然後再試一次。"
            
            CALL SetError(L_ConferenceNotRunningCMSTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceNotRunningCMSReason_ErrorMessage)
            CALL AddFix(L_ConferenceNotRunningCMSFix1_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")

        CASE E_CMS_CONFERENCE_NOT_SCHEDULED
            CONST L_ConferenceNotScheduledTitle_ErrorMessage  = "未排定的會議"
            CONST L_ConferenceNotScheduledReason_ErrorMessage = "這個會議 (依照 URL 中的會議 ID 所認定) 並非由 Exchange Conferencing Service 所排定。"
            CONST L_ConferenceNotScheduledFix1_ErrorMessage   = "會議可能已經刪除，或會議 ID 可能損毀。"
            CONST L_ConferenceNotScheduledFix2_ErrorMessage   = "請與您的會議召集人或系統管理員聯繫。"
            
            CALL SetError(L_ConferenceNotScheduledTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceNotScheduledReason_ErrorMessage)
            CALL AddFix(L_ConferenceNotScheduledFix1_ErrorMessage)
            CALL AddFix(L_ConferenceNotScheduledFix2_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")
        
        CASE E_CMS_CONFERENCE_NOT_STARTED
            CONST L_ConferenceNotStartedTitle_ErrorMessage  = "會議尚未開始"
            CONST L_ConferenceNotStartedReason_ErrorMessage = "會議正要開始，但是尚未完成啟動程序。"
            CONST L_ConferenceNotStartedFix1_ErrorMessage   = "請稍後再試。"
            
            CALL SetError(L_ConferenceNotStartedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceNotStartedReason_ErrorMessage)
            CALL AddFix(L_ConferenceNotStartedFix1_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")

        CASE E_CMS_CONFERENCE_NOT_FOUND,E_CMS_RECURRING_INSTANCE_NOT_WITHIN_TIME_BOUND,E_CMS_AMBIGUOUS_RECURRING_JOIN,E_CMS_E_CONFERENCE_NOT_EXIST,1 'S_FALSE
            CONST L_ConferenceNotFoundTitle_ErrorMessage  = "找不到會議"
            CONST L_ConferenceNotFoundReason_ErrorMessage = "Conference Management Service 找不到您要加入的會議。"
            CONST L_ConferenceNotFoundFix1_ErrorMessage   = "如果會議才剛排定，請稍後再試。"
            CONST L_ConferenceNotFoundFix2_ErrorMessage   = "請與會議召集人聯繫；會議可能已經取消。"
            CONST L_ConferenceNotFoundFix3_ErrorMessage   = "請查驗瀏覽器 URL 所顯示的會議 ID 與您的會議 ID 是否相同。"
            CONST L_ConferenceNotFoundFix4_ErrorMessage   = "如果這是週期性會議，可能是解析個別場次時發生問題。"
            
            CALL SetError(L_ConferenceNotFoundTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceNotFoundReason_ErrorMessage)
            CALL AddFix(L_ConferenceNotFoundFix1_ErrorMessage)
            CALL AddFix(L_ConferenceNotFoundFix2_ErrorMessage)
            CALL AddFix(L_ConferenceNotFoundFix3_ErrorMessage)
            CALL AddFix(L_ConferenceNotFoundFix4_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")

        CASE E_CMS_SHUTTING_DOWN
            CONST L_ConfServerShuttingDownTitle_ErrorMessage  = "Conference Management Service 關閉"
            CONST L_ConfServerShuttingDownReason_ErrorMessage = "Conference Management Service 正在關閉。"
            CONST L_ConfServerShuttingDownFix1_ErrorMessage   = "請稍候幾分鐘讓服務重新開始，會議就可以繼續進行。"
            CONST L_ConfServerShuttingDownFix2_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_ConfServerShuttingDownTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConfServerShuttingDownReason_ErrorMessage)
            CALL AddFix(L_ConfServerShuttingDownFix1_ErrorMessage)
            CALL AddFix(L_ConfServerShuttingDownFix2_ErrorMessage)

        CASE E_CMS_INVALID_CONFERENCE_PASSWORD
            CONST L_InvalidConferencePasswordTitle_ErrorMessage  = "無效的會議密碼"
            CONST L_InvalidConferencePasswordReason_ErrorMessage = "由於您的密碼無效，Conference Management Service 拒絕您加入會議的要求。"
            CONST L_InvalidConferencePasswordFix1_ErrorMessage   = "請查驗輸入的密碼是否正確。"

            CALL SetError(L_InvalidConferencePasswordTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_InvalidConferencePasswordReason_ErrorMessage)
            CALL AddFix(L_InvalidConferencePasswordFix1_ErrorMessage)
        
        CASE E_CMS_ANONYMOUS_USER_DENIED_ACCESS
            CONST L_AnonymousUserDeniedAccessTitle_ErrorMessage  = "拒絕匿名使用者存取"
            CONST L_AnonymousUserDeniedAccessReason_ErrorMessage = "由於無法識別您的身分，Conference Management Service 拒絕您加入會議的要求。"
            CONST L_AnonymousUserDeniedAccessFix1_ErrorMessage   = "請查驗您是否受邀參加私人會議。"
            CONST L_AnonymousUserDeniedAccessFix2_ErrorMessage   = "請查驗您是以自己的身分登入網路，才能識別您的身分。"

            CALL SetError(L_AnonymousUserDeniedAccessTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_AnonymousUserDeniedAccessReason_ErrorMessage)
            CALL AddFix(L_AnonymousUserDeniedAccessFix1_ErrorMessage)
            CALL AddFix(L_AnonymousUserDeniedAccessFix2_ErrorMessage)
        
        CASE E_CMS_USER_DENIED_ACCESS
            CONST L_UserDeniedAccessTitle_ErrorMessage  = "存取遭拒"
            CONST L_UserDeniedAccessReason_ErrorMessage = "由於您沒有必要的權限加入，所以 Conference Management Service 拒絕您加入會議的要求。您認證的身分為："
            CONST L_UserDeniedAccessFix1_ErrorMessage   = "請查驗您是否受邀參加此私人會議。請看原始會議邀請上是否核取 [允許外界人員參加]。請查看您的使用者名稱是否列於原始會議邀請的 [收件者] 或 [副本] 清單中，並確認您在該伺服器是否被認證為該使用者。"
            CONST L_UserDeniedAccessFix2_ErrorMessage   = "請與您的系統管理員聯繫。會議虛擬根目錄可能未正確設定，或是 Conference Management Service 對於私人會議要求用戶端認證 (也就是核取了 [私人會議認證存取] 頁面)。"

            CALL SetError(L_UserDeniedAccessTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_UserDeniedAccessReason_ErrorMessage & Request.ServerVariables("AUTH_USER"))
            CALL AddFix(L_UserDeniedAccessFix1_ErrorMessage)
            CALL AddFix(L_UserDeniedAccessFix2_ErrorMessage)

        CASE E_CMS_CTP_JOIN_REQUEST_FAILED
            CONST L_CTPJoinRequestFailedTitle_ErrorMessage  = "CTP 加入要求失敗"
            CONST L_CTPJoinRequestFailedReason_ErrorMessage = "由於會議技術提供程式不允許會議加入，Conference Management Service 拒絕您的要求。"
            CONST L_CTPJoinRequestFailedFix1_ErrorMessage   = "請與您的系統管理員聯繫。"

            CALL SetError(L_CTPJoinRequestFailedTitle_ErrorMessage, Value, Replace(Request.QueryString("PNAME"), "+"," "), Description)
            CALL SetReason(L_CTPJoinRequestFailedReason_ErrorMessage)
            CALL AddFix(L_CTPJoinRequestFailedFix1_ErrorMessage)
        
        CASE E_CMS_PROVIDER_NOT_INITIALIZED
            CONST L_ProviderNotInitializedTitle_ErrorMessage  = "提供程式未起始"
            CONST L_ProviderNotInitializedReason_ErrorMessage = "由於會議技術提供程式尚未完成起始， Conference Management Service 拒絕您的要求。"
            CONST L_ProviderNotInitializedFix1_ErrorMessage   = "請與您的系統管理員聯繫。"

            CALL SetError(L_ProviderNotInitializedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ProviderNotInitializedReason_ErrorMessage)
            CALL AddFix(L_ProviderNotInitializedFix1_ErrorMessage)
        
        CASE E_CMS_PROVIDER_NOT_FOUND
            CONST L_ProviderNotFoundTitle_ErrorMessage  = "找不到提供程式"
            CONST L_ProviderNotFoundReason_ErrorMessage = "由於無法聯繫會議技術提供程式，Conference Management Service 拒絕您的要求。"
            CONST L_ProviderNotFoundFix1_ErrorMessage   = "請與您的系統管理員聯繫。"

            CALL SetError(L_ProviderNotFoundTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ProviderNotFoundReason_ErrorMessage)
            CALL AddFix(L_ProviderNotFoundFix1_ErrorMessage)
        
        CASE E_CMS_RECURRING_CONFERENCE_NOT_FOUND
            CONST L_RecurringConferenceNotFoundTitle_ErrorMessage  = "找不到週期性會議"
            CONST L_RecurringConferenceNotFoundReason_ErrorMessage = "由於找不到您要加入的週期性會議，Conference Management Service 拒絕您的要求。"
            CONST L_RecurringConferenceNotFoundFix1_ErrorMessage   = "請與您的系統管理員聯繫。"

            CALL SetError(L_RecurringConferenceNotFoundTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_RecurringConferenceNotFoundReason_ErrorMessage)
            CALL AddFix(L_RecurringConferenceNotFoundFix1_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")
        
        CASE E_CMS_NOT_HOST_SERVER
            CONST L_NotHostServerTitle_ErrorMessage  = "無效的主機 URL"
            CONST L_NotHostServerReason_ErrorMessage = "由於這個伺服器不是主機伺服器，Conference Management Service 拒絕您的要求。"
            CONST L_NotHostServerFix1_ErrorMessage   = "請與您的系統管理員聯繫。"

            CALL SetError(L_NotHostServerTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NotHostServerReason_ErrorMessage)
            CALL AddFix(L_NotHostServerFix1_ErrorMessage)

        CASE E_DCS_NO_MCUS_AVAILABLE
            CONST L_NoAvailableMCUsTitle_ErrorMessage  = "沒有可用的 T.120 MCU 伺服器"
            CONST L_NoAvailableMCUsReason_ErrorMessage = "無法使用 Data Conferencing Service，或是未設定允許自您的位址連線 T.120 MCU 伺服器。若要加入會議，您的資料會議用戶端 (像是 NetMeeting ) 必須連線至 T.120 MCU 伺服器。"
            CONST L_NoAvailableMCUsFix1_ErrorMessage   = "如果這個問題持續發生，請與您的系統管理員聯繫。"
            
            CALL SetError(L_NoAvailableMCUsTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoAvailableMCUsReason_ErrorMessage)
            CALL AddFix(L_NoAvailableMCUsFix1_ErrorMessage)

        CASE E_DCS_NO_PROXY_MCUS_AVAILABLE
            CONST L_NoAvailableProxyMCUsTitle_ErrorMessage  = "沒有可用的 Proxy T.120 MCU 伺服器"
            CONST L_NoAvailableProxyMCUsReason_ErrorMessage = "Data Conferencing Service 無法使用，或是未設定允許自您的 Windows 2000 站台連線至 proxy T.120 MCU 伺服器。要參加在另一個站台上的會議需要連線至 proxy T.120 MCU 伺服器。"
            CONST L_NoAvailableProxyMCUsFix1_ErrorMessage   = "如果這個問題持續發生，請與您的系統管理員聯繫。"
            
            CALL SetError(L_NoAvailableProxyMCUsTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoAvailableProxyMCUsReason_ErrorMessage)
            CALL AddFix(L_NoAvailableProxyMCUsFix1_ErrorMessage)

        CASE E_DCS_NO_INTERNET_MCUS_AVAILABLE
            CONST L_NoAvailableInternetMCUsTitle_ErrorMessage  = "沒有可用的 Internet T.120 MCU 伺服器"
            CONST L_NoAvailableInternetMCUsReason_ErrorMessage = "Data Conferencing Service 無法使用，或是未設定允許來自組織外的 internet T.120 MCU 伺服器連線。要加入在另一個組織內的會議需要 internet T.120 MCU 伺服器連線。"
            CONST L_NoAvailableInternetMCUsFix1_ErrorMessage   = "如果這個問題持續發生，請與您的系統管理員聯繫。"
            
            CALL SetError(L_NoAvailableInternetMCUsTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoAvailableInternetMCUsReason_ErrorMessage)
            CALL AddFix(L_NoAvailableInternetMCUsFix1_ErrorMessage)

        CASE E_DCS_CONFERENCE_NOT_RUNNING
            CONST L_ConferenceNotRunningDCSTitle_ErrorMessage  = "未進行的會議"
            CONST L_ConferenceNotRunningDCSReason_ErrorMessage = "T.120 MCU 伺服器目前並未執行該會議。"
            CONST L_ConferenceNotRunningDCSFix1_ErrorMessage   = "如果這個問題持續發生，請與您的系統管理員聯繫。"
            
            CALL SetError(L_ConferenceNotRunningDCSTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceNotRunningDCSReason_ErrorMessage)
            CALL AddFix(L_ConferenceNotRunningDCSFix1_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")
            
        CASE E_DCS_CONFERENCE_ALREADY_ENDED
            CONST L_ConferenceAlreadyEndedTitle_ErrorMessage  = "會議已經結束"
            CONST L_ConferenceAlreadyEndedReason_ErrorMessage = "您要加入的資料會議已經結束。"
            CONST L_ConferenceAlreadyEndedFix1_ErrorMessage   = "如果這個問題持續發生，請與您的系統管理員聯繫。"
            
            CALL SetError(L_ConferenceAlreadyEndedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ConferenceAlreadyEndedReason_ErrorMessage)
            CALL AddFix(L_ConferenceAlreadyEndedFix1_ErrorMessage)
            CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")
            
        CASE E_DCS_ACCESS_DENIED_CAPACITY_LIMIT
            CONST L_CapacityLimitTitle_ErrorMessage  = "資料會議容量限制"
            CONST L_CapacityLimitReason_ErrorMessage = "資料會議的容量已滿，現在無法再接受任何新的使用者。"
            CONST L_CapacityLimitFix1_ErrorMessage   = "請稍待幾分鐘後，試著再次加入會議。在您上次嘗試加入會議後，可能有其他使用者已經離開會議。"
            CONST L_CapacityLimitFix2_ErrorMessage   = "請與會議召集人聯繫。"
            
            CALL SetError(L_CapacityLimitTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_CapacityLimitReason_ErrorMessage)
            CALL AddFix(L_CapacityLimitFix1_ErrorMessage)
            CALL AddFix(L_CapacityLimitFix2_ErrorMessage)

        CASE E_DCS_NOT_RUNNING
            CONST L_DCSNotRunningTitle_ErrorMessage  = "Data Conference Service 未執行"
            CONST L_DCSNotRunningReason_ErrorMessage = "目前並未執行 Data Conferencing Service。"
            CONST L_DCSNotRunningFix1_ErrorMessage   = "請稍待幾分鐘後，試著再次加入會議。服務可能正在重新啟動。"
            CONST L_DCSNotRunningFix2_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_DCSNotRunningTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_DCSNotRunningReason_ErrorMessage)
            CALL AddFix(L_DCSNotRunningFix1_ErrorMessage)
            CALL AddFix(L_DCSNotRunningFix2_ErrorMessage)

        CASE E_DCS_NOT_INIT
            CONST L_DCSNotInitTitle_ErrorMessage  = "Data Conference Service 未起始"
            CONST L_DCSNotInitReason_ErrorMessage = "Data Conferencing Service 尚未完成起始工作。"
            CONST L_DCSNotInitFix1_ErrorMessage   = "請稍待幾分鐘後，試著再次加入會議。"
            CONST L_DCSNotInitFix2_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_DCSNotInitTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_DCSNotInitReason_ErrorMessage)
            CALL AddFix(L_DCSNotInitFix1_ErrorMessage)
            CALL AddFix(L_DCSNotInitFix2_ErrorMessage)

        CASE E_PKCS7_NO_CERT_STORE
            CONST L_NoCertStoreTitle_ErrorMessage    = "開啟憑證存放區錯誤"
            CONST L_NoCertStoreReason_ErrorMessage   = "在您要加入的會議管理伺服器上，開啟憑證存放區時發生錯誤。"
            CONST L_NoCertStoreFix1_ErrorMessage     = "請與您的系統管理員聯繫。"

            CALL SetError(L_NoCertStoreTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoCertStoreReason_ErrorMessage)
            CALL AddFix(L_NoCertStoreFix1_ErrorMessage)
        
        CASE E_MCU_NO_SERVER_CERTIFICATE
            CONST L_NoServerCertificateTitle_ErrorMessage    = "沒有 Data Conferencing Server 憑證"
            CONST L_NoServerCertificateReason_ErrorMessage   = "Exchange Data Conferencing 伺服器現在無法提供私人會議。"
            CONST L_NoServerCertificateFix1_ErrorMessage     = "請與您的系統管理員聯繫，確認 Data Conferencing Server 上已經安裝機器憑證。"

            CALL SetError(L_NoServerCertificateTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoServerCertificateReason_ErrorMessage)
            CALL AddFix(L_NoServerCertificateFix1_ErrorMessage)

        CASE E_MANUAL_JOIN_INSTRUCTIONS            
            CONST L_ManualJoinInstructionsTitle_ErrorMessage  = "參加的指示"
            CALL SetError(L_ManualJoinInstructionsTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NetMeetingInviteReason_ErrorMessage)
            CALL AddFix(L_MCUProxyInvite_ErrorMessage)
            CALL AddFix(L_ManualJoinServer_ErrorMessage & Session("MCUAddress"))
            CALL AddFix(L_ManualJoinID_ErrorMessage & Request.QueryString("ID"))
            CALL AddFix(L_ManualJoinPassword_ErrorMessage & Session(SESSION_PASSWORD))


        CASE E_SESSION_UNAVAILABLE
        
            SELECT CASE Session(SESSION_RESULT)

                CASE &H8007000E
                    CONST L_SessionUnavailableResoveHostTitle_ErrorMessage    = "無法解析主機"
                    CONST L_SessionUnavailableResoveHostReason_ErrorMessage   = "Exchange Conferencing Web 伺服器發生錯誤。伺服器無法解析目錄伺服器的主機名稱。"
                    CONST L_SessionUnavailableResoveHostFix1_ErrorMessage     = "請與您的系統管理員聯繫。"

                    CALL SetError(L_SessionUnavailableResoveHostTitle_ErrorMessage, Value, Source, Description)
                    CALL SetReason(L_SessionUnavailableResoveHostReason_ErrorMessage)
                    CALL AddFix(L_SessionUnavailableResoveHostFix1_ErrorMessage)

                CASE &H8000FFFF
                    CONST L_SessionUnavailableNoRightsTitle_ErrorMessage    = "權限不足"
                    CONST L_SessionUnavailableNoRightsReason_ErrorMessage   = "Exchange Conferencing Web 伺服器發生錯誤。您沒有足夠的權限存取目錄伺服器。預設的 IIS 帳號設定或目錄伺服器的安全性設定可能未正確設定。"
                    CONST L_SessionUnavailableNoRightsFix1_ErrorMessage     = "請與您的系統管理員聯繫。"

                    CALL SetError(L_SessionUnavailableNoRightsTitle_ErrorMessage, Value, Source, Description)
                    CALL SetReason(L_SessionUnavailableNoRightsReason_ErrorMessage)
                    CALL AddFix(L_SessionUnavailableNoRightsFix1_ErrorMessage)

                CASE &H800704E1
                    CONST L_SessionUnavailableBadSiteTitle_ErrorMessage    = "無效的站台"
                    CONST L_SessionUnavailableBadSiteReason_ErrorMessage   = "Exchange Conferencing Web 伺服器發生錯誤。服務試圖為找不到的站台尋找某個區域。"
                    CONST L_SessionUnavailableBadSiteFix1_ErrorMessage     = "請與您的系統管理員聯繫。"

                    CALL SetError(L_SessionUnavailableBadSiteTitle_ErrorMessage, Value, Source, Description)
                    CALL SetReason(L_SessionUnavailableBadSiteReason_ErrorMessage)
                    CALL AddFix(L_SessionUnavailableBadSiteFix1_ErrorMessage)
            
                CASE ELSE
                    CONST L_SessionUnavailableTitle_ErrorMessage    = "伺服器無法使用"
                    CONST L_SessionUnavailableReason_ErrorMessage   = "Exchange Conferencing Web 伺服器無法使用。"
                    CONST L_SessionUnavailableFix1_ErrorMessage     = "請關閉您的瀏覽器，然後重試作業。"
                    CONST L_SessionUnavailableFix2_ErrorMessage     = "請與您的系統管理員聯繫。"

                    CALL SetError(L_SessionUnavailableTitle_ErrorMessage, Value, Source, Description)
                    CALL SetReason(L_SessionUnavailableReason_ErrorMessage)
                    CALL AddFix(L_SessionUnavailableFix1_ErrorMessage)
                    CALL AddFix(L_SessionUnavailableFix2_ErrorMessage)
        
            END SELECT
        
        CASE E_SERVER_CREATE_OBJECT
            CONST L_ServerCreateObjectTitle_ErrorMessage  = "Web 伺服器設定錯誤"
            CONST L_ServerCreateObjectReason_ErrorMessage = "您要連線的 Web 伺服器並未設定搭配 Exchange Conferencing Service 元件進行作業。"
            CONST L_ServerCreateObjectFix1_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_ServerCreateObjectTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_ServerCreateObjectReason_ErrorMessage)
            CALL AddFix(L_ServerCreateObjectFix1_ErrorMessage)

        CASE E_UNSUPPORTED_JAVASCRIPT_BROWSER
            CONST L_JavaScriptRequiredTitle_ErrorMessage  = "需要能夠支援 Javascript"
            CONST L_JavaScriptRequiredReason_ErrorMessage = "若要檢視這個網頁，您必須使用支援 Javascript 的瀏覽器，例如 Internet Explorer 5.0。"
            CONST L_JavaScriptRequiredFix1_ErrorMessage   = "<A HREF=""http://www.microsoft.com/windows/ie_intl/tw/download/"">取得 Internet Explorer</A>。"
        
            CALL SetError(L_JavaScriptRequiredTitle_ErrorMessage, 0, "Browser", "Browser doesn't support javascript")
            CALL SetReason(L_JavaScriptRequiredReason_ErrorMessage)
            CALL AddFix(L_JavaScriptRequiredFix1_ErrorMessage)

        CASE E_UNSUPPORTED_TABLES_BROWSER
            CONST L_TablesRequiredTitle_ErrorMessage  = "需要能夠支援表格"
            CONST L_TablesRequiredReason_ErrorMessage = "若要檢視這個網頁，您必須使用支援表格的瀏覽器，例如 Internet Explorer 5.0。"
            CONST L_TablesRequiredFix1_ErrorMessage   = "<A HREF=""http://www.microsoft.com/windows/ie_intl/tw/download/"">取得 Internet Explorer</A>。"
        
            CALL SetError(L_TablesRequiredTitle_ErrorMessage, 0, "Browser", "Browser doesn't support tables")
            CALL SetReason(L_TablesRequiredReason_ErrorMessage)
            CALL AddFix(L_TablesRequiredFix1_ErrorMessage)

        CASE E_ACCESS_DENIED
            CONST L_AccessDeniedTitle_ErrorMessage  = "存取遭拒"
            CONST L_AccessDeniedReason_ErrorMessage = "由於缺少權限，所以 Conference Management Service 拒絕您的要求。"
            CONST L_AccessDeniedFix1_ErrorMessage   = "如果會議需要密碼，請檢查您是否使用正確的密碼。"
            CONST L_AccessDeniedFix2_ErrorMessage   = "請檢查您要加入的私人會議是否邀請您。"
            CONST L_AccessDeniedFix3_ErrorMessage   = "請與您的系統管理員聯繫。"

            Err.Number = E_ACCESS_DENIED_HRESULT 'Set for better display
            CALL SetError(L_AccessDeniedTitle_ErrorMessage, Value, Source, Description)
            Err.Number = E_ACCESS_DENIED 'Reset for no complications
            CALL SetReason(L_AccessDeniedReason_ErrorMessage)
            CALL AddFix(L_AccessDeniedFix1_ErrorMessage)
            CALL AddFix(L_AccessDeniedFix2_ErrorMessage)
            CALL AddFix(L_AccessDeniedFix3_ErrorMessage)

        CASE E_CMS_RESTARTED
            CONST L_CMSRestartedTitle_ErrorMessage  = "與 Exchange Conferencing Service 的連線發生錯誤"
            CONST L_CMSRestartedReason_ErrorMessage = "沒有可用的 Exchange Conferencing Service。"
            CONST L_CMSRestartedFix1_ErrorMessage   = "關閉您的瀏覽器並開啟新的連線至 Exchange Conferencing Service。"
            CONST L_CMSRestartedFix2_ErrorMessage   = "如果您仍然無法連線，請與管理員聯繫。該服務可能並未執行。"
            
            CALL SetError(L_CMSRestartedTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_CMSRestartedReason_ErrorMessage)
            CALL AddFix(L_CMSRestartedFix1_ErrorMessage)
            CALL AddFix(L_CMSRestartedFix2_ErrorMessage)
        
        CASE E_MCU_HANG
            CONST L_MCUHangTitle_ErrorMessage  = "與 Data Conferencing Server 的連線發生錯誤"
            CONST L_MCUHangReason_ErrorMessage = "Exchange Conferencing Service 與 Data Conferencing Server 搭配工作時發生錯誤。"
            CONST L_MCUHangFix1_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_MCUHangTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_MCUHangReason_ErrorMessage)
            CALL AddFix(L_MCUHangFix1_ErrorMessage)

        CASE E_NO_GLOBAL_CONF_CALENDAR
            CONST L_NoGlobalConfCalTitle_ErrorMessage  = "Exchange Conferencing Service 未正確設定"
            CONST L_NoGlobalConfCalReason_ErrorMessage = "Exchange Conferencing Service 可能未具有為它設定的預設會議信箱。"
            CONST L_NoGlobalConfCalFix1_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_NoGlobalConfCalTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_NoGlobalConfCalReason_ErrorMessage)
            CALL AddFix(L_NoGlobalConfCalFix1_ErrorMessage)

        CASE E_DSGETSITENAME_NO_SITE
            CONST L_DsGetSiteNameTitle_ErrorMessage  = "找不到站台"
            CONST L_DsGetSiteNameReason_ErrorMessage = "Exchange Conferencing Service 找不到它的 Active Directory 伺服器。"
            CONST L_DsGetSiteNameFix1_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_DsGetSiteNameTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_DsGetSiteNameReason_ErrorMessage)
            CALL AddFix(L_DsGetSiteNameFix1_ErrorMessage)

        CASE ELSE 'OTHER ERRORS
                    
            CONST L_DefaultTitle_ErrorMessage  = "伺服器錯誤"
            CONST L_DefaultReason_ErrorMessage = "Exchange Conferencing Service 發生伺服器錯誤。"
            CONST L_DefaultFix1_ErrorMessage   = "請與您的系統管理員聯繫。"
            
            CALL SetError(L_DefaultTitle_ErrorMessage, Value, Source, Description)
            CALL SetReason(L_DefaultReason_ErrorMessage)
            CALL AddFix(L_DefaultFix1_ErrorMessage)

    END SELECT

    CheckSetError = Value
END FUNCTION

'== SUB: Verifies ConfLocator points to the Conference Locator
SUB Verify_ConfLocator()
    ON ERROR RESUME NEXT

	DIM AuthUser
    
	AuthUser	=  Request.ServerVariables("AUTH_USER")
    IF (L_OK_Text <> GetSessionStatusStr(Session(SESSION_STATUS)) OR 0 <> Session(SESSION_ERRNUMBER) OR NOT IsObject(Session(SESSION_CONFLOCATOR)) OR NOT IsObject(Session(SESSION_CMSZONE)) OR (AuthUser <> "" AND LCase(AuthUser) <> LCase(Session(SESSION_ATTENDEE)))) THEN
        CALL SetupSessionVariables(AuthUser)
    END IF
    
    IF (L_OK_Text <> GetSessionStatusStr(Session(SESSION_STATUS)) AND 0 <> Session(SESSION_ERRNUMBER)) THEN
        Err.Number      = Session(SESSION_ERRNUMBER)
        Err.Description = Session(SESSION_ERRDESCRIPTION)
        Err.Source      = Session(SESSION_ERRSOURCE)
    ELSEIF (L_OK_Text <> GetSessionStatusStr(Session(SESSION_STATUS)) OR NOT IsObject(Session(SESSION_CONFLOCATOR)) OR NOT IsObject(Session(SESSION_CMSZONE))) THEN
        Result          = E_SESSION_UNAVAILABLE
    END IF
END SUB

'== SUB: Sets error if the Client browser lacks Tables and JavaScript support
SUB Check_Browser_Capabilities()
    DIM Browscap
    
    SET Browscap = Server.CreateObject("MSWC.BrowserType")

    ' No longer trying to detect javascript from the browser (wasn't working with Navigator)
    'IF (0 = Browscap.JavaScript) THEN
    '    displayState = DISPLAY_ERR_VALUE
    '    Err.Number   = E_UNSUPPORTED_JAVASCRIPT_BROWSER
    'ELSE
    IF (0 = Browscap.tables) THEN
        displayState = DISPLAY_ERR_VALUE
        Err.Number   = E_UNSUPPORTED_TABLES_BROWSER
    END IF
END SUB

'== SUB: Sets an error due to an invalid password
SUB Invalid_Password()
    CONST L_IncorrectPasswordTitle_ErrorMessage  = "不正確的密碼"
    CONST L_IncorrectPasswordReason_ErrorMessage = "您並未輸入加入這個會議所需的密碼。如果您鍵入上列的 URL，請檢查拼字是否正確，您可能拼錯了密碼。"
    CONST L_IncorrectPasswordFix1_ErrorMessage   = "請檢查您的拼字。"
    CONST L_IncorrectPasswordFix2_ErrorMessage   = "請與會議召集人或您的系統管理員聯繫。"
        
    CALL SetError(L_IncorrectPasswordTitle_ErrorMessage, 0, "Security", "Invalid Password")
    CALL SetReason(L_IncorrectPasswordReason_ErrorMessage)
    CALL AddFix(L_IncorrectPasswordFix1_ErrorMessage)
    CALL AddFix(L_IncorrectPasswordFix2_ErrorMessage)
END SUB

'== SUB: Sets error if the Conference ID is not set
SUB IsConfID()
    IF ("" = inConfID OR CONF_ID_CODED_LENGTH < Len(inConfID)) THEN
        displayState = DISPLAY_ERR_CONFID
    END IF
END SUB

'== SUB: Sets error if the DCS Meeting ID is not valid
SUB ValidateMeetingID()
    IF (CONF_ID_DECODED_LENGTH <> Len(inMeetingID)) THEN
        CONST L_NoConferenceIDTitle_ErrorMessage  = "無效的會議存取 URL"
        CONST L_NoConferenceIDReason_ErrorMessage = "您只能從有效的會議存取 URL 加入會議。"
        CONST L_NoConferenceIDFix1_ErrorMessage   = "如果您複製 URL，請檢查拼字是否正確。或透過邀請您參加會議的電子郵件加入會議。"

        Err.Number      = Len(inMeetingID)
        Err.Description = "Invalid conference ID"
        Err.Source      = "Exchange Conferencing Service"
        CALL SetError(L_NoConferenceIDTitle_ErrorMessage, 0, "Validate Meeting ID", "Invalid Conference ID")
        CALL SetReason(L_NoConferenceIDReason_ErrorMessage)
        CALL AddFix(L_NoConferenceIDFix1_ErrorMessage)
        CALL AddFix(L_LinkToConferenceListsFix_ErrorMessage & "<A HREF=""list.asp"">" & L_LinkToConferenceListsFix2_ErrorMessage & "</A>")
    END IF
END SUB

'== SUB: Setup the error page when we have an error
SUB DisplayErrorPage() %>
<TITLE><%=L_ErrorPage_HTMLTitle%></TITLE>
</HEAD>
<body BGCOLOR="#FFFFFF" BACKGROUND="filespw.gif" LEFTMARGIN="40" RIGHTMARGIN="40" TEXT="#000000" LINK="#000000" ALINK="#FFCC66" VLINK="#0080FF" STYLE="background-color:#FFFFFF; background-image:url(filespw.gif); background-attachment:fixed; background-repeat:no-repeat; background-position:bottom right;">

<center>
<table CELLSPACING="12">
<tr><td COLSPAN="2" ROWSPAN="1" ALIGN="LEFT"><b><font FACE="verdana" SIZE="+3"><%=ErrorMsg%></font></b></td></tr>
<tr><td COLSPAN="2" ROWSPAN="1" ALIGN="LEFT"><font FACE="verdana" SIZE="-1">
    <%=Reason%>
    <P><%=L_TryTheFollowing_Text%></P>
    <UL>
        <%
            DIM count
            FOR count = 1 TO UBound(Fixes)
                Response.write("<LI>" + Fixes(count) + "</LI>")
            NEXT
        %>
    </UL>
    <P>
    <SMALL>
        <%=HiddenError%>
        <BR>
        <%=L_Page_HTMLTitle%>
    </SMALL>
</font></td></tr>
</table>
</center>
</body>
</HTML>
<% END SUB %>
