Windows NTのログオンダイアログボックスをカスタマイズする方法

戻る

WindowsNTのログオンダイアログボックスは,ログオンを行うときに必ず [Ctl]+[Alt]+[Del]キーを入力しなければログオンすることができません. この仕様は,悪意をもった利用者がログオンダイアログボックスを偽装した アプリケーションを起動させて,他のユーザのパスワードを盗み取ることを防ぐことを 目的としています.しかし,ログオンが必ずキー入力を伴うのは大変困ります.
たとえば,IDカードを利用してログオンする必要があるときや,キーボードなしで ログオンする必要があるシステムでは,ログオンの方法をカスタマイズしてシステム にあわせる必要があります.
また,一般家庭でWindowsNTを利用するときには,ログオンの度に [Ctl]+[Alt]+[Del]キーを入力するのを面倒だと思われる方が多いのではないかと 思われます.もっとも簡単にログオンするには,自動ログオン設定を行うとよい のですが,処理する内容によってユーザを変える必要があるときには利用できません.  そこで,[Ctl]+[Alt]+[Del]キーを入力せずにログオンできるように する方法を考えます.ただし,複数の人が操作する必要があるような環境では, 面倒でも[Ctl]+[Alt]+[Del]キーを入力してログオンするほうが安全ですので, むやみにカスタマイズをすることはお勧めできません.

6-1 ログオンダイアログボックスを拡張するGINA

●GINAの登場
WindowsNT3.5以前でログオンダイアログボックスを,ユーザの用途に合わせて作り直す には,Microsoft社と特別な関係を持っているベンダーでなければ,WINLOGON.EXE を カスタマイズできるだけの情報を入手することができませんでした.
このため,ユーザーがデスクトップからシステムにログオンするには,あらかじめ用意 された手順でしか行うことができませんでした.しかし,WindowsNT3.5x以降では, GINA(Graphical Identification aNd Authentication) と呼ばれる機能が追加され ました.これにより,IDカードなどの外部に接続された装置を利用してユーザの 認証をすることが可能になりました.
 この機能と共に,Win32 API LogonUser や Win32 API CreateProcessAsUser も 追加され,ソケットインターフェースを利用したリモートログオンも可能に なりました.
(* LogonUser, CreateProcessAsUser に関しては,Win32 サブルーチンズ 第5章で説明していますので,詳しくはそちらを参照してください.)

●GINAの概要
GINA は,標準で提供される WINLOGON.EXE が持つログオン管理機能を拡張するための 機能であり,GINA API の関数名の先頭には Wxl(WinLogon eXtension)が付加して ありますので容易に識別することができます.
GINA API は,ユーザが処理を行うために利用する API と,システム(WinLogon)から 呼び出されるコールバック関数から構成されます.ログオンダイアログボックスを, カスタマイズする必要があるときには,コールバック関数を含むDLLを作成し,その DLLをレジストリに登録する必要があります.GINA が行う処理は,標準のシステム では,MSGINA.DLL に含まれ,ユーザが作成したGINAの処理を持つDLLがレジストリに 登録されていなければ,このDLLが持つダイアログボックスを表示させます.

●WINLOGON.EXEとSAS
 WindowsNTマシンへのログオンは,WINLOGON.EXEのみが管理し,システムにログオンが 可能になると,WINLOGON.EXE が起動されます.
 WINLOGON.EXE には SAS(Secure Attention Sequence)と呼ばれる機能があります. [Ctl]+[Alt]+[Del] キーの組み合わせが押下されたことを感知できるアプリケーション は,SAS をサポートしている WINLOGON.EXE だけです.
したがって,他のアプリケーションが WINLOGON.EXE に成り代って,ログオンしようと しているユーザのパスワードを盗み取る,悪意を持った「トロイの木馬」 アプリケーション(パスワードコレクター)からシステムを守るための重要な役目を 果たしています.初期のWindowsNTで,WINLOGON.EXE をカスタマイズする手段を公開 していなかったのは,悪用されることを防ぐという意図があったの かもしれません.

図6-1:GINA
+-----------------------------------------+
|                                         |
|           WINLOGON.EXE                  |
|                                         |
|                                         |
+----------+------------+------------+----+
| GINA.DLL |ネットワーク|ネットワーク|    |
|          |プロバイダ  |プロバイダ  |... |
|          |DLL         |DLL         |    |
+----------+------------+------------+----+
●WINLOGON.EXEのレジストリと動作
WINLOGON.EXE (MSGINA.DLL)が,実行するときに利用するパラメータは,以下の レジストリに格納されており,
HKEY_LOCAL_MACHINE
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
その値によりダイアログボックスを表示せずに「自動ログオン」を 行うといったことも可能になります.
(* Win32 サブルーチンズ第9章を参照)
ユーザーが作成する GINA DLLでも,レジストリに固有の値を設定することで,独自の 機能をサポートすることが可能になります.WINLOGON.EXE は,WindowsNTの起動と同時 に起動され,シャットダウンされるまで動作し続けます.このため,デスクトップから ユーザがログオンしている状態を完全に把握することができる唯一のアプリケーション であるといえます.WINLOGON.EXEはユーザのログオンのみを管理しているだけでなく, ログオン後のデスクトップ上で発生した[Ctl]+[Alt]+[Del]キーを検出し,タスク マネージャを表示したり,ログオフやシャットダウンを行うための機能も 持っています.GINA DLLがこれらのイベントを受信されたときに,デスクトップ上の アプリケーションに通知する機能を持たせることにより,アプリケーションでそれらの イベントに対する処理を行わせることができるようになります.

●GINA.DLLのログオンダイアログボックス表示機能
GINA DLLは,ユーザーがログオンするために必要な情報を入力させるための ダイアログボックスを表示させる機能を持ちます.
このダイアログボックスは直接 Win32 API を利用するわけではなく,GINA で提供 される関数を利用します.ダイアログボックスから入力されたユーザ名とパスワード (ドメイン名)を利用して,Win32 API LogonUser を利用して,認証を行います. ログオンが認められると,そのユーザのトークンハンドルを利用して,ユーザーの デスクトップに必要なプロセスを Win32 API CreateProcessAsUser で 起動させます.

図6-2:WINLOGON.EXEの起動
                                        +---------------+
                                        |               |
                                        | エクスプローラ|
                                        |               |
                                        +---------------+
                                               ↑
                                               |ユーザーのシェル
                                               |を起動する
+---------------+  ログオンした         +---------------+
|               |  ユーザがサブシステム | Win32         |
|  WinLogon     |−−−−−−−−−−→ |  サブシステム |
|               |  を利用する環境を     |               |
+---------------+  生成する             +---------------+
      ↑
      |認証
      ↓
+---------------+
| セキュリティ  |
| サブシステム  |
|               |
+---------------+

6-2 GINA API

●GINA DLLがエクスポートするAPI
GINA DLLがエクスポートするAPIは,WINLOGON.EXE が持つ機能のカスタマイズを行う 手段として,提供されます.標準では,MSGINA.DLL がそれらの処理を持っています. GINA API は,ver1.0 と ver1.1 が存在し,WindowsNT3.5xと4.0の両方で動作させる 必要があるときには,ver1.0の範囲で実装する必要があります.
ver1.0のAPIは必ずすべて実装する必要があります.DLLに実装しているver1.0のAPIが 1つでも欠けていると,WINLOGON.EXEの起動時にシステムクラッシュが発生します. ver1.1のAPIは,必ずしも実装する必要はなく,必要に応じて追加することができます. 実装しないときには,WINLOGON.EXE が内部で適当な処理を行います.

表6-1:GINA DLLがエクスポートするAPI
WlxNegotiate GINA DLLが利用可能なバージョンであるかを返す
WlxInitialize GINA DLLの初期化処理を行う
WlxDisplayLockedNotice ディスプレイがロックされたときに呼び出される
WlxDisplaySASNotice ユーザがログオンできないようにするときに呼び出される
WlxIsLockOk ワークステーションをロックする前に呼び出される
WlxWkstaLockedSAS ワークステーションがロックされたときに呼び出される
WlxLoggedOnSAS ログオン中にSASイベントが発生すると呼び出される
WlxLoggedOutSAS ログオンが可能なときSASイベントが発生すると呼び出される
WlxActivateUserShell ログオンが認証されたときに呼び出される
WlxIsLogoffOk ExitWindowsExでログオフを始めたとき呼び出される
WlxLogoff ログオフの直前に呼び出される
WlxShutdown システムがシャットダウンされる直前に呼び出される
(a)Ver1.0 の API

WLXScreenSaverNotify スクリーンセーバが起動される前に呼び出される
WlxStartApplication エクスプローラが不意に終了したことを検出したときに呼び出される
(b)Ver1.1 の API

例6-1:GINA DLLの実行シーケンス
WlxNegotiate           ... MSGINA.DLLの実行が開始された
WlxInitialize
WlxDisplaySASNotice    ... [Ctl]+[Alt]+[Del]を待つダイアログボックスを表示
      ↓
WlxLoggedOutSAS        ... ログオン情報ダイアログボックス
WlxActivateUserShell
      ↓
WlxIsLockOk
WlxWkstaLockedSAS
WlxDisplayLockedNotice ... ロックしたことを知らせるダイアログボックスを表示
      :
WlxLoggedOnSAS          ... ログオン中にSASイベントを受信
      :
 WlxIsLogoffOk          ... ログオフを指定された
 WlxLogoff                  (Win32 API ExitWindowsExの実行)
      ↓
 WlxShutdown            ... シャットダウンが開始された
                             (ログオンしているときには先にログオフされる)

●GINA DLLがインポート(利用する)API
インポートといっても,実際にライブラリファイルリンクしたり Win32 API LoadLibrary を利用してリンクする必要はありません.
GINA API WlxInitialize が WINLOGON.EXE から呼び出されると,このAPIの引数から PWLX_DISPATCH_VERSION_1_0 または PWLX_DISPATCH_VERSION_1_1 構造体のポインタを 取得することができます.この構造体に利用できるAPIのポインタが設定されています. WlxInitialize で取得したポインタはDLLが終了するまで利用しますので,スタティック変数や,コンテキスト(GINA DLLの作業用変数を格納するためにWlxInitialize で確保 するユーザ定義領域)に格納しておく必要があります.
 これらのAPIは,Win32 API を単純に呼び出すだけでは実現できない,GINA に特化 した機能を GINA DLL の開発者に提供します.
このAPI にも,ver1.0 と ver1.1 があり,WindowsNT3.5x で実行させる必要がある ときには ver1.0 の API のみを利用する必要があります.
ダイアログボックスを表示させるためのAPIは,GINA専用のものが用意されています. これらのAPIは,GINA DLLでなければ取得できないメッセージの処理をサポートしている ため,Win32 API を利用せず,これらのAPIでダイアログボックスを表示させる必要が あります.

●SASイベント
ダイアログボックスのコールバック関数は,WLX_WM_SASメッセージで,SASイベントを 取得することができます.このメッセージの wParam に発生したイベントが設定され, 状態に応じて処理を行うことができます.
wParam の値は,あらかじめ定義されている値以外に,GINA API WlxSasNotify に通知 される GINA DLL で独自に定義した SASタイプも設定することができます. SASタイプに任意の値を設定するときには,WLX_SAS_TYPE_MAX_MSFT_VALUE より大きい 値を設定する必要があります.

●ダイアログボックスでのSASイベントの受信
ダイアログボックスのコールバック関数が処理を終えると,ダイアログボックスは 自動的に破棄され,ダイアログボックスを表示するために利用したGINA API (WlxDialogBox など) の戻り値に受信したイベントに対応した値を返却します.
任意の値を返却させるには,コールバック関数内で Win32 API EndDialog に戻り値を 設定して呼び出します.このとき,WLX_DLG_XXXXXXX の値とぶつからないように注意 する必要があります.


表6-2:PWLX_DISPATCH_VERSION_1_0のAPI
int WlxAssignShellProtection(
 HANDLE hWlx, HANDLE hToken, HANDLE hProcess, HANDLE hThread)
GINA DLLがWinlogonに最近ログオンしたユーザーの
シェルプログラムに保護を割り当てる

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hToken ... プライマリプロセストークン
HANDLE hProcess ... プロセスハンドル
HANDLE hThread ... スレッドハンドル

戻り値
正常終了 0
異常終了 エラーコード
int WlxChangePasswordNotify(
 HANDLE hWlx, PWLX_MPR_NOTIFY_INFO pMprInfo, DWORD dwChangeInfo)
パスワードの変更を行う

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
PWLX_MPR_NOTIFY_INFO pMprInfo ... パスワード情報構造体
DWORD dwChangeInfo ... 変更情報フラグ

戻り値
正常終了 0
異常終了 エラーコード
int WlxDialogBox(HANDLE hWlx, HANDLE hInst,
 LPWSTR lpwszTemplate, HWND hWndOwner, DLGPROC lpDlgProc)
ダイアログボックスを表示する
GINA版 Win32 API DialogBox

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hInst ... モジュールインスタンスハンドル
LPWSTR lpszTemplate ... ダイアログボックス名を指すポインタ
HWND hWndOwner ... 親ウィンドウハンドル
DLGPROC lpDlgProc ... ダイアログプロシジャ

戻り値
正常終了 Win32 API EndDialog で設定された戻り値
異常終了 -1
int WlxDialogBoxIndirect(HANDLE hWlx, HANDLE hInst,
 LPDLGTEMPLATE hTemplate, HWND hWndOwner, DLGPROC lpDlgProc)
ダイアログボックスを表示する
GINA版 Win32 API DialogBoxIndirect

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hInst ... モジュールインスタンスハンドル
LPCDLGTEMPLATE hTemplate ... テンプレート
HWND hWndOwner ... 親ウィンドウハンドル
DLGPROC lpDlgProc ... ダイアログプロシジャ

戻り値
正常終了 Win32 API EndDialog で設定された戻り値
異常終了 -1
int WlxDialogBoxIndirectParam(HANDLE hWlx, HANDLE hInst,
 LPDLGTEMPLATE hTemplate, HWND hWndOwner, DLGPROC lpDlgProc,
 LPARAM lInitParam)
ダイアログボックスを表示する
GINA版 Win32 API DialogBoxIndirectParam

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hInst ... モジュールインスタンスハンドル
LPCDLGTEMPLATE hTemplate ... テンプレート
HWND hWndOwner ... 親ウィンドウハンドル
DLGPROC lpDlgProc ... ダイアログプロシジャ
LPARAM lInitParam ... 初期化値

戻り値
正常終了 Win32 API EndDialog で設定された戻り値
異常終了 -1
int WlxDialogBoxParam(HANDLE hWlx, HANDLE hInst,
 LPWSTR lpwszTemplate, HWND hWndOwner, DLGPROC lpDlgProc,
 LPARAM lInitParam)
ダイアログボックスを表示する
GINA版 Win32 API DialogBoxParam

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hInst ... モジュールインスタンスハンドル
LPWSTR lpwszTemplate ... テンプレート
HWND hWndOwner ... 親ウィンドウハンドル
DLGPROC lpDlgProc ... ダイアログプロシジャ
LPARAM lInitParam ... 初期化値

戻り値
正常終了 Win32 API EndDialog で設定された戻り値
異常終了 -1
int WlxMessageBox(HANDLE hWlx, HWND hWndOwner,
 LPWSTR lpwszText, LPWSTR lpwszTitle, UINT uStyle)
ダイアログボックスを表示する
GINA版 Win32 API MessageBox

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HWND hWndOwner ... 親ウィンドウハンドル
LPWSTR lpwszText ... テキスト文字列
LPWSTR lpwszTitle ... タイトル文字列
UINT uStyle ... スタイル

戻り値
正常終了 メニュー項目の値
異常終了 0
VOID WlxSasNotify(HANDLE hWlx, DWORD dwSasType)
SASイベントをWinLogonに通知する

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
DWORD dwSasType ... SASイベントタイプ

戻り値
 なし
VOID WlxSetContextPointer(HANDLE hWlx, LPVOID lpWlxContext)
GINAコンテキストを設定する
WlxInitializeが呼び出される前にWlxSasNotifyを利用する必要があるとき に利用する

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
LPVOID lpWlxContext ... コンテキストポインタ

戻り値
 なし
BOOL WlxSetTimeout(HANDLE hWlx, DWORD dwTimeout)
ダイアログボックスのタイムアウト時間を設定する(既定値は 2分)
引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
DWORD dwTimeout ... タイムアウト時間[sec]

戻り値
正常終了 TRUE
異常終了 FALSE
int WlxSwitchDesktopToUser(HANDLE hWlx)
カレントスレッドの仮想デスクトップを切り替える

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル

戻り値
正常終了 0
異常終了 エラーコード
VOID WlxUseCtrlAltDel(HANDLE hWlx)
GINA DLLが[CTL]+[ALT]+[DEL]キーを利用できるようにする

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル

戻り値
正常終了 0
異常終了 エラーコード

表6-3:PWLX_DISPATCH_VERSION_1_1で追加されたAPI
BOOL WlxGetSourceDesktop(HANDLE hWlx, PWLX_DESKTOP *lplpDesktop)
以前のデスクトップの情報を取得する

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
PWLX_DESKTOP *lplpDesttop ... WLX_DESKTOP構造体の格納域を指す
戻り値
正常終了 TRUE
異常終了 FALSE
VOID WlxSetReturnDesktop(HANDLE hWlx, PWLX_DESKTOP lpDesktop)
Winlogonが切り換えるデスクトップを設定する

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
PWLX_DESKTOP lpDesttop ... WLX_DESKTOP構造体を指す

戻り値
 なし
VOID WlxCreateUserDesktop(HANDLE hWlx, HANDLE hToken,
 DWORD dwFlags, LPWSTR lpwszDesktopName,
 PWLX_DESKTOP *lplpDesktop)
Winlogonが切り換えるデスクトップを設定する

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
HANDLE hToken ... トークンハンドル
DWORD dwFlags ... デスクトップ生成フラグ
LPWSTR lpwszDesktopName ... デスクトップ名
PWLX_DESKTOP *lplpDesttop ... WLX_DESKTOP構造体の領域を指す

戻り値
 なし
int WlxChangePasswordNotifyEx(HANDLE hWlx,
 PWLX_MPR_NOTIFY_INFO lpMprInfo, DWORD dwChangeInfo,
 LPWSTR lpwszProviderName, LPVOID lpReserved)
パスワードの変更を行う

引数
HANDLE hWlx ... WlxInitializeで取得したWinLogonハンドル
PWLX_MPR_NOTIFY_INFO lpMprInfo ... WLX_MPR_NOTIFY_INFO構造体
DWORD dwChangeInfo ... 変更情報フラグ
LPWSTR lpwszProviderName ... プロバイダ名
LPVOID lpReserved ... 予約

戻り値
正常終了 0
異常終了 エラーコード

表6-4:GINA DLLで独自に定義したSASタイプ
WLX_SAS_TYPE_TIMEOUT ユーザからのキー入力が一定時間無かった
WLX_SAS_TYPE_CTRL_ALT_DEL [CTL]+[ALT]+[DEL]キーの入力を受信した
WLX_SAS_TYPE_SCRNSVR_TIMEOUT スクリーンセーバが起動された
WLX_SAS_TYPE_USER_LOGOFF ユーザがログオフした

表6-5:WlxDialogBoxXXXXXX が返却するコード
WLX_DLG_SAS ダイアログボックスがSASメッセージを受信した
WLX_DLG_INPUT_TIMEOUT ユーザからのキー入力が一定時間無かった
WLX_DLG_SCREEN_SAVER_TIMEOUT スクリーンセーバが起動された
WLX_DLG_USER_LOGOFF ユーザがログオフする
その他 Win32 API EndDialog で設定された値

6-3 GINA DLLを開発するときの注意点

WINLOGON.EXE が 呼び出すGINA DLL は,通常のDLLと変わるところはありません. しかし,呼び出される環境は,ユーザーデスクトップが機能する以前であるため, システムの一部であることを十分に理解して行う必要があります.
少なくとも次のような点に注意し,対策をとるする必要があります.なお,対策を していない状態でシステムクラッシュを発生すると,残念ながらOSを再インストール (上書きインストール不可)しなければならなくなります.

(1)通常のデバッガは使えない
  • 作成したDLLが異常終了すると,システムがクラッシュします.
  • 机上デバックを十分に行い,必要であればファイルにログを出力する 機能を用意しておく.
    (2)レジストリに設定するDLLのファイル名絶対に間違えてはならない
  • WINLOGON.EXEが起動されると同時に無条件にシステムがクラッシュします.
    (3)DLLの異常動作に対する対策を行う
  • 少なくともデバックを行っている間は,DLLが実行を開始した時点で, レジストリの設定を削除して,実行中にシステムがクラッシュしても 次の起動でMSGINA.DLLで起動できるようにしておく.
  • システム修復ディスクは最新の状態に更新しておく.
  • 可能であれば,デバック用の環境(破壊されても惜しくない環境)を 用意する.(リモートデバックができる環境が好ましい)
  • FATファイルシステムでインストールしたNTを利用し, DLLが異常終了したときにはFDから起動して,MSGINA.DLLを GinaDLLに設定したファイル名にリネーム(コピー)して再起動する.

    とは,いうもののある程度動作が安定すると,通常のアプリケーションと同様に 開発を行うことができますので,チャレンジしてみてください.

    6-4 Windows95/98で[Crl]+[Alt]+[Del]の動作を制御するには

    WindowsNTで[Crl]+[Alt]+[Del]を制御するにはGINAを利用するしかありませんが, Windows95/98には,そのような機能はありません.
    しかし,Win32 API SystemParametersInfo(SPI_SCREENSAVERRUNNING) を利用する ことで簡単に,[Ctl]+[Alt]+[Del]や[Alt]+[Tab]の動作を制御することができます. なぜ,スクリーンセーバーの設定でそのようなことが起こるのでしょうか? Windowsは,スクリーンセーバーが動作している間,それらのキーを受け付けません. そこで,スクリーンセーバーが動作中であるかのように見せかける設定を行うことに より,システムはそれらのキーを受け付けなくなります.
    ただし,この方法はWindows95/98で利用できますが,WindowsNTでは利用できません.

    リスト6-1:Win32 API SystemParametersInfo で[Ctrl]+[Alt]+[Del]を制御
    
    BOOL fNew, fOld, fResult;
    fNew = TRUE;    /* TRUE: キーを効かなくする FALSE: キーを効くようにする */
    fResult = SystemParametersInfo(SPI_SCREENSAVERRUNNING, fNew, &fOld, 0);
    

    6-5 プログラムについて
    WindowsNT4.0で動作する GINA DLL のサンプルです. (* 実際の処理で,ver1.1の APIは利用していませんので,初期化時に ver1.0を サポートするDLLであることを返却し,PWLX_DISPATCH_VERSION_1_0でAPIへの ポインタを指す構造体へのポインタを取得するように修正することで, WindowsNT3.5xでも利用可能になります.)
    [Ctl]+[Alt]+[Del]を入力しなくてもログオンすることができる,GINAを利用した DLLのサンプルです.通常は,このような使い方をするのは好ましくありませんが, 複数のユーザが1台のマシンを共有する必要がない環境(一般家庭での利用など) では,自動ログオン設定で利用される方も多いのではないでしょうか?
    ログオンの認証を全くしないよりは,自分の都合のよい形態でログオン認証を行う ことで,セキュリティが向上するのではないでしょうか?

    ●注意点
    このDLLは,基本的な機能しかなく,ドメイン名の入力はできません. ログオン中に[Ctl]+[Alt]+[Del]キーを押下すると,タスクマネージャを表示させます. もう少し高度な機能は必要なときには,カスタマイズが必要になります.
    ユーザーが作成したGINA DLLを動作させるには,WinLogon のオプションパラメータを 設定するレジストリキーに値を設定し,システムを再起動させる必要があります. GINA DLL のレジストリ設定を間違えると,システムをクラッシュさせてしまいます. そこで,レジストリ設定用のツールも作成しました.実際の設定処理は, サンプルDLL(GINA.DLL)内にあり,REGGINA.EXE はDLLを呼び出しています.
    このため,ファイル名を変更するときには,GINA.H の SZGINADLLVAL に設定されている ファイル名も必ず変更してください.

    表6-6:GINA DLL を指定するレジストリキー
    名前GinaDLL
    説明任意のGINA DLLを使用する.
    タイプREG_SZ
    ファイル名 (例:GINA.DLL)

    ●インストール方法
    まず,「Admininistrators」グループのユーザでログオンし, システムディレクトリ(C:\Winnt\System32)にGINA.DLLをコピーして, REGGINA.EXE を起動してレジストリの設定を行います.
    GINA.DLLをデバックバージョン*でビルドを行った場合,システムのルートディレクトリ (NTがC:\Winntにインストールされているときには,C:\)に GINA.LOG を生成しログを 出力します.そして,GINA.DLLの初期化時に,レジストリの GinaDLL キーが削除 されます.このため,次に再起動するときに実行させるときには,REGGINA.EXEで再度 設定する必要があります.ただし,DLL自身はレジストリキーを削除後にシステムを 再起動しなければ解放されません.
    (* デバッグビルドを行うときはメイクファイルの"cdebug=" ,"linkdebug=" を削除 またはコメントにします.)

    ●ソースファイル
    GINA.DLL(非デバック版)
     GINA.C (GINA DLL本体)
     GINA.H (本体ヘッダファイル)
     RESOURCE.H (リソースヘッダ)
     GINA.DEF (モジュール定義ファイル)
     GINA.RC (リソースファイル)
     MAKEFILE (メイクファイル)
    REGGINA\REGGINA.EXE
     REGGINA.C (レジストリ設定ツール)
     MAKEFILE (メイクファイル)