EternalWindows
GINA / バージョン

今回から実際にフルGINAを開発するためのコードについて説明していきます。 フルGINAはGINAスタブやGINAフックのコードと異なり、 各エクスポート関数の実装を完全に自分で行わなければなりませんから、 とにかく関数の引数を正しく理解することが重要といえるでしょう。 そのうえで、最低限実装に必要なコードについて説明し、 最後に完成したGINAのサンプルを紹介したいと思います。 まず、今回はWlxNegotiateです。

BOOL WlxNegotiate(
  DWORD dwWinLogonVersion,
  PDWORD pdwDllVersion
);

dwWinLogonVersionは、Winlogonのバージョンです。 WinlogonのバージョンはWindows自体のバージョンにある程度比例するもので、 エクスポート関数やディスパッチテーブルのサポートの度合いを知る目安になります。 pdwDllVersionは、GINAのバージョンを格納します。 戻り値は、TRUEならば関数は成功となり後続の関数が呼ばれ、 FALSEを返した場合、次のようなダイアログが表示されシステムは再起動します。

GINAの開発者は、それをロードするWinlogonのバージョンが一定でないこと意識すべきです。 たとえば、GINAがver1.3のエクスポート関数やディスパッチテーブルを扱う設計である場合、 当然ながら、Winlogonはそれらの機能をサポートしていなければなりません。 しかし、WinlogonにもGINAと同じように1.0から1.4までのバージョンが存在し、 そのバージョンはGINAのバージョンとサポート機能の面で対応しています。 つまり、GINAがver1.3の関数を呼び出すならば、Winlogonのバージョンも1.3、 またはそれ以上でなければならず、Winlogonのバージョンが1.0〜1.2である場合は、 ロードされたGINAが正常に動作される保障はありません。 したがって、WlxNegotiateではdwWinLogonVersionでWinlogonのバージョンを確認し、 その値が希望するGINAのバージョンを下回っていないかを調べる必要あります。

BOOL WINAPI WlxNegotiate(DWORD dwWinLogonVersion, PDWORD pdwDllVersion)
{
	DWORD dwDllVersion = WLX_VERSION_1_0;

	ReplaceDefaultGina();

	if (dwWinLogonVersion < dwDllVersion)
		return FALSE;
	
	*pdwDllVersion = dwDllVersion;

	return TRUE;
}

WLX_VERSION_1_0は、バージョンを表す専用の定数でver1.0を意味します。 ver1.0は最っとも低いバージョンですから、dwWinLogonVersionがこの値を下回ることは 実際にはありませんが、調べる癖は付けておくべきでしょう。 pdwDllVersionに格納するのはGINAのバージョンですから、 必ず先のif文で使用したバージョンを代入することになります。 Winlogonはこの値を参照することによって、呼び出すべきエクスポート関数、 及びWlxInitializeに指定するディスパッチテーブルを決定します。


戻る