ホーム 主筆 その他ソフト その他情報 Syuhitu.org English

Windows関連

スクリーンセーバー作成法

半透明ウインドウの性能

bootfont.bin

キャビネット形式

ウインドウスタイルをいじる

Java製ソフトをServiceに登録する

イベントログにメッセージを出力する

コントロールパネルにアイコンを追加する

スクリプトによる拡張1

スクリプトによる拡張2

ガジェットの作成

大容量メモリ

メモリ搭載量の下限に挑む

スパースファイルにする

表示されるアイコンの種類を調べてみた

メモリマップIOとエラー処理

ファイルを作る順番と速度の関係

Cryptography API: Next Generationを使う

Windows 10のアクセントカラー

iSCSIディスクにバックアップを取る

サーバプロセスを分離して実装する

サーバプロセスを分離して実装する - F#

レジストリに大量に書き込む

Solaris関連

OpenGL

Solaris設定

ディレクトリの読み込み

主筆プラグイン開発

マルチスレッドでの開発

door

音を出す

Blade100の正しい虐め方

パッケージの作成

画像入出力

BMPファイル

ICOファイル

ANIファイル

JPEGファイル

減色アルゴリズム

減色アルゴリズムの並列化

その他アルゴリズムなど

自由軸回転

Base64

文字列操作

CPU利用率の取得

正規表現ライブラリ

メタボールを作る

メタボールを作る2

正規表現とNFA・DFA

C言語の構文解析

液晶ディスプレイを解体してみた

iSCSIの理論と実装

単一フォルダにファイルを沢山作る

USB-HUBのカスケード接続

SafeIntの性能

VHDファイルのフォーマット

USBメモリに書き込み続けてみた

CNG:アルゴリズムプロバイダのコンパイル・リンク

2016年2月27日公開

CNGで利用できるアルゴリズムプロバイダを自分で実装することを考える。しかしその前に、プログラムをコンパイル・リンクする上での留意事項について述べる。

なお、このページでは、今となっては大分古くなってしまったVisual Studio 2010で開発することを前提に記載している。おそらくだが、最新版のVisual Studioを使えばここに書いてある苦労のほとんどは関係なくなるのではないかと考えてる。

SDKのダウンロード

CNGのアルゴリズムプロバイダを実装するためには、下記2つのSDKを用意する必要がある。

Cryptographic Provider Development Kit

CNGのSDKは下記から取得できる。

https://www.microsoft.com/en-us/download/details.aspx?id=30688

しかし実際のところ、SDKと言ったところで入っているのはサンプルのプログラムとヘルプファイルぐらいのものである。インストールしたところでスタートメニューに登録され実行するような何かがあるわけでもない。

だから、インストール時にインストール先のパス名を控えておかないと、どこにブツが入ったのかが分からなくなってしまう。

一応、何も考えないでインストールすると下記の場所に入る。

C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit

Windows 10 SDK

多分、使用しているのがVisual Studio 2010だからいけないのだろう。後述するが、Windows.h等のヘッダが古くてコンパイルが通らなかった。最新版はWindows 10 SDKとしてダウンロードできる。

https://dev.windows.com/ja-jp/downloads/windows-10-sdk

ヘッダやライブラリのパスについては後述する。

プロジェクトの作成

アルゴリズムプロバイダはDLLとして実装されるので、当然DLLを作成することになる。ここではTestCAPという名前でプロジェクトを作っている。

ここでVisual Studioの使い方を逐一示しても仕方がないので省略する。とりあえず、下記にアプリケーションウィザードによりデフォルトで作成されるファイルを示す。

stdafx.h

// stdafx.h : 標準のシステム インクルード ファイルのインクルード ファイル、または
// 参照回数が多く、かつあまり変更されない、プロジェクト専用のインクルード ファイル
// を記述します。
//
 
#pragma once
 
#include "targetver.h"
 
#define WIN32_LEAN_AND_MEAN   // Windows ヘッダーから使用されていない部分を除外します。
// Windows ヘッダー ファイル:
#include <windows.h>
 
 
 
// TODO: プログラムに必要な追加ヘッダーをここで参照してください。

targetver.h

#pragma once
 
// SDKDDKVer.h をインクルードすると、利用できる最も上位の Windows プラットフォームが定義されます。
 
// 以前の Windows プラットフォーム用にアプリケーションをビルドする場合は、WinSDKVer.h をインクルードし、
// SDKDDKVer.h をインクルードする前に、サポート対象とするプラットフォームを示すように _WIN32_WINNT マクロを設定します。
 
#include <SDKDDKVer.h>

dllmain.cpp

// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。
#include "stdafx.h"
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                       )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
} 

stdafx.cpp

// stdafx.cpp : 標準インクルード TestCAP.pch のみを
// 含むソース ファイルは、プリコンパイル済みヘッダーになります。
// stdafx.obj にはプリコンパイル済み型情報が含まれます。
 
#include "stdafx.h"
 
// TODO: このファイルではなく、STDAFX.H で必要な
// 追加ヘッダーを参照してください。

TestCAP.cpp

// TestCAP.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//
 
#include "stdafx.h"
 
 

ここで気に入らないのは、stdafx.hにある「#define WIN32_LEAN_AND_MEAN」の記述である。なぜか知らんが、これがあるとNTSTATUS等の必要な宣言がいろいろと抜け落ちるので、事前に削除しておかなければならない。

それ以外のstdafx.cpp、stdafx.h、targetver.hにはほとんど何も手を加える必要はない。

defファイルの追加

あらかじめ決まった名前でエントリポイントをエクスポートする必要があるのでDEFファイルを作成して、プロジェクトに追加する必要がある。

LIBRARY	"TestCAP"
 
EXPORTS
 
	GetCipherInterface = GetCipherInterface

もっとも、こんなものは何も考えずにCryptographic Provider Development Kitに含まれるサンプルからパクってきてLIBRARYの記述だけ修正してやれば充分である。

ヘッダ・ライブラリの追加

微妙に苦労したのがこれである。

まずはヘッダファイルのインクルードを記述する。

TestCAP.cpp

// TestCAP.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//
 
#include "stdafx.h"

#include <windows.h>
#include <bcrypt.h>
#include <bcrypt_provider.h>

黄色に塗っている部分を追記している。別にstdafx.hに書いてはいけない理由はない。

プロジェクトのプロパティで、インクルードディレクトリとして下記を指定する。

  1. C:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\shared;
  2. C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Include;
  3. $(VCInstallDir)include;
  4. $(VCInstallDir)atlmfc\include;
  5. $(WindowsSdkDir)include;
  6. $(FrameworkSDKDir)\include;

問題は指定する順番である。

つい、入力する欄の末尾に追記したくなるのだが、そうするとWindows 10 SDKとしてダウンロードしてきたWindows.hが参照されずに、古いVisual Studio 2010についてきたヘッダが優先して使用されてしまう。そうするといろいろとコンパイルが通らなくなるので、少なくともC:\Program Files (x86)\Windows Kits\10\Include\10.0.10586.0\shared;については一番前に持ってこなければならない。

ライブラリについてはそういった競合の問題はなさそうである。

とりあえず以下を指定している。

  1. $(VCInstallDir)lib;
  2. $(VCInstallDir)atlmfc\lib;
  3. $(WindowsSdkDir)lib;
  4. $(FrameworkSDKDir)\lib;
  5. C:\Program Files (x86)\Windows Kits\8.0\Cryptographic Provider Development Kit\Lib\win8\x86

エントリポイントの追加

とりあえずコンパイルだけできるようにするため、空のエントリポイントを追記してみる。

NTSTATUS WINAPI GetCipherInterface(
	__in LPWSTR pszProviderName,
	__in LPWSTR pszAlgId,
	__out BCRYPT_CIPHER_FUNCTION_TABLE **ppFunctionTable,
	__in DWORD dwFlags
)
{
  return 0;
}

この状態でコンパイルが通り、目的のDLLが作れるかどうかが最初の関門になる。

 

<< 「Cryptography API: Next Generationを使う」に戻る


連絡先 - サイトマップ - 更新履歴
Copyright (C)  2000 - 2016 nabiki_t All Rights Reserved.