4.7 セッション 0 の分離

4. 新機能や機能変更に伴う互換性問題

この章では、以下のような新機能や機能変更に伴う、互換性問題について紹介します。

セッション 0 の分離とは

Windows XP、Windows Vista や Windows 7 では、ユーザーの切り替え機能をサポートしているため、複数のユーザーが同時に 1 台のコンピューターにログオンできます。ユーザーは Windows やプログラムを終了せずに、セッションを切り替えることができます。たとえば、ユーザー A がログオンして Word でドキュメントの編集作業をおこなっている時、ユーザー B が電子メールをチェックする必要があるなら、ユーザー A の Word は実行したまま、ユーザー B がログオンして電子メール アプリケーションを起動することができます。そして、電子メールのチェックが済んだら、再びユーザー A は、Word が実行されたセッションに戻ることができ、ドキュメントの編集作業を続けることができます。

図 4-24 にもあるように、Windows XP や Windows Server 2003、およびそれ以前の Windows では、すべてのサービスはログオンした最初のユーザーと同じセッションで実行されます。このセッションは、セッション 0 と呼ばれます。ただ、サービスをユーザー アプリケーションと同じセッションで実行することは、セキュリティ上危険です。通常、サービスはユーザー アプリケーションより高い権限で実行されているため、悪意のあるプログラムが、自身の権限レベルを昇格させる手段に利用する可能性があるからです。

そこで、Windows Vista と Windows 7 では、セッション 0 ではサービスのみを実行するよう分離しました。これにより、セッション 0 とユーザー アプリケーションは対話することができなくなるため、セキュリティ上の危険が軽減されます。つまり、セッション 0 では、システム プロセスとサービスのみを実行します。そして、最初のユーザーはセッション 1 にログオンし、その後のユーザーはそれに続くセッションにログオンします。

図 4-24: Windows XP と Windows Vista/Windows 7 のセッションの違い

図 4-24: Windows XP と Windows Vista/Windows 7 のセッションの違い

図 4-25: タスク マネージャーによるセッション ID の表示

図 4-25: タスク マネージャーによるセッション ID の表示

ページのトップへ


互換性への影響と検証のポイント

ユーザーがセッション 0 にいると決めつけているドライバーやサービスなどは、セッション 0 の分離により、問題が起こる可能性があります。たとえば、以下のようなサービスが考えられます。

  • ユーザー インターフェイス (UI) を作成しているサービス

    セッション 0 に対して UI が作成されてしまうため、別のセッションを利用するユーザーからレスポンスを受信することはできません。

  • ウィンドウ メッセージを送信しているアプリケーションやサービス

    セッションが異なるため、ユーザーがメッセージを受け取ることはできません。

  • 画面のプロパティ情報を取得しているサービス

    セッション 0 にグラフィックス能力がないため、正しい情報を得ることができません。

  • ローカル オブジェクトでサービスと同期をとるアプリケーション

    セッションが異なるため、ローカル オブジェクトで同期をとることはできません。

影響を受けるプログラムの具体例は、以下のようなものがあります。

  • Print Spooler サービスにロードされるプリンタドライバー
  • User-Mode Driver Framework (UMDF) に準拠したドライバー

これらのドライバーは、セッション 0 のプロセスでホストされています。

互換性を維持するため、Windows Vista や Windows 7 では「対話型サービス検出」サービスを提供しています。このサービスは、セッション 0 へのダイアログやウィンドウの作成が検出されると、別セッションのユーザーに通知し、ユーザーのデスクトップに図 4-26 のようなダイアログ ボックスを表示します。ここで、[要求の確認] ボタンをクリックすると、セッション 0 に切り替わるため、サービスからのメッセージを読んだり、ダイアログなどを処理したりことができます。「対話型サービスダイアログの検出」ダイアログが表示された後、処理がおこなわれないと、5 分以内にユーザーに再度通知されます。

図 4-26: 「対話型サービスの検出」ダイアログ

図 4-26: 「対話型サービスの検出」ダイアログ

この機能はあくまで、既存サービスとの互換性のために用意された一時的な回避策です。新たにサービスを提供する際には、この機能に依存せず、正しい対策をとることが重要です。正しい対策については、この節の「セッション 0 の分離への対応」を参照してください。

問題がセッション 0 の分離に起因するものなのかどうかを検証するためには、以下の動作を確認します。

  • 「対話型サービス ダイアログ ボックスの検出」ダイアログが表示された場合

    セッション 0 へのウィンドウ作成が試みられたことを意味します。セッション 0 の分離の影響を受けている可能性が高いです。

  • Windows XP で、2 人目以降のログオン ユーザーで問題が発生

    Windows XP のユーザー切り替え機能を使って実行し、1 人目のログオン ユーザーでは問題が起こらずに、2 人目以降のログオン ユーザーで発生するなら、セッション 0 の分離の影響を受けている可能性が高いといえます。

ページのトップへ


セッション 0 の分離への対応

  • アプリケーションとの通信

    アプリケーション間の通信は、リモート プロシージャ コール (RPC) や名前付きパイプなど、クライアント サーバ型の通信メカニズムを使用するようにします。また、サービスからのメッセージの提示に、ウィンドウ メッセージは使わないようにします。たとえば、ユーザーがログオンした直後からサービスと通信をおこなう場合、アプリケーションをスタート アップ メニューに登録するか、Run レジストリに登録し、ログオン直後に自動的に起動されるようにします。このアプリケーションを利用して複雑な UI を表示することで、サービスとユーザー インターフェイスを分離することができます。  

  • WTSSendMessage() によるメッセージ ボックスの作成

    簡単なメッセージ ボックスをユーザーのデスクトップに表示する際には、WTSSendMessage 関数を使用します。この関数を使用すると、サービスはユーザーに通知を送信し、ユーザーからのレスポンスを取得することができます。

  • CreateProcessAsUser() による複雑な UI の作成

    複雑な UI を作成したいときには、CreateProcessAsUser 関数を使用します。この関数の使い方は、以下の通りです。

    • 1. CreateProcessAsUser 関数を呼び出し、ユーザーのセッションにプロセスを作成します。
    • 2. 作成したプロセスから、UI を表示します。
    • 3. クライアントサーバ型の通信メカニズムで、レスポンスを取得します。

    「CreateProcessAsUser」を使用する方法は、「アプリケーションとの通信」で紹介したような、ユーザー セッション内にアプリケーションを起動しておく手間を必要としません。しかし、ユーザーがログオンしているかどうか、また、複数のユーザーがログオンしている場合にはどのユーザーに対して UI を表示するかなど、複雑な判断が必要となるため、推奨されません。

  • サービスとオブジェクトを共有

    サービスで利用可能なイベントやマッピングされたメモリなどのオブジェクトには、明示的にローカルまたはグローバルのいずれかの名前空間を指定します。

ページのトップへ