In-Context勾點函式預防措施

基於效能考慮,用戶端開發人員會註冊內容內攔截函式。 不過,由於這些攔截函式會對應到伺服器的位址空間,因此用戶端和伺服器開發人員必須採取預防措施,以確保事件處理順暢。

用戶端開發人員的預防措施

用戶端開發人員應該注意下列問題:

  • 內容攔截函式不應該使用許多處理器時間,因為攔截函式必須在伺服器應用程式繼續之前傳回。
  • 觸發事件之後,呼叫攔截函式時,與事件相關聯的視窗可能已不存在。 用戶端必須先確認與事件相關聯的視窗仍然存在,再採取與事件相關的任何其他動作。 為了確保視窗仍然存在,用戶端會使用 Microsoft Win32 IsWindow 函式。
  • 如果攔截函式定義連結至另一個 DLL 的 DLL,用戶端開發人員必須確保系統載入其他 DLL。 如果使用 .def 檔案隱含連結 (並匯入) ,則額外的 DLL 必須位於 Windows 目錄或其中一個系統目錄,例如 Windows\System、Windows\System32 或 Windows\SysWOW64。 如果使用 LoadLibrary) 明確連結 (,則必須在呼叫 LoadLibrary時指定其他 DLL 所在目錄的完整路徑。
  • 當包含攔截函式的 DLL 載入至 16 位應用程式時,內容攔截函式可能會導致堆疊溢位。 發生此問題的原因是 16 位應用程式會使用不足以容納導致攔截函式呼叫的系統函式鏈結的固定堆疊大小。

伺服器開發人員的預防措施

伺服器開發人員必須注意用戶端應用程式可能會註冊內容內攔截函式。 當伺服器呼叫 NotifyWinEvent時,必須準備好處理 WM_GETOBJECT 和其他 IAccessible 方法。

不正確介面指標

當用戶端在內容攔截函式內呼叫 AccessibleObjectFromEvent 時,傳回的 IAccessible 介面指標會直接指向伺服器位址空間中的程式碼。 如果用戶端使用此指標呼叫介面屬性,則元件物件模型 (COM) 程式庫與封送處理 (封裝和跨進程界限傳送介面參數) 或取消包裝 (已跨進程界限傳送的參數) ,而且不會偵測物件是否已終結。

如果用戶端對終結的物件呼叫介面屬性,除非伺服器偵測到這種情況,否則不正確介面指標會導致伺服器的位址空間發生一般保護錯誤。

為了防止介面指標無效,伺服器 會建立 Proxy 物件 ,以包裝可存取的物件並監視可存取物件的生命週期。 例如,當用戶端呼叫 IAccessible 屬性以取得物件的相關資訊時,Proxy 會檢查可存取的物件是否仍然可用,如果是的話,會將用戶端的要求轉送至可存取的物件。 如果可存取的物件已終結,Proxy 會將錯誤傳回給用戶端。