Win32 API 日本語リファレンス
ホームSecurity.Cryptography › NCryptImportKey

NCryptImportKey

関数
BLOB形式のキーをストレージプロバイダーにインポートする。
DLLncrypt.dll呼出規約winapi対応OSWindows Vista 以降

シグネチャ

// ncrypt.dll
#include <windows.h>

HRESULT NCryptImportKey(
    NCRYPT_PROV_HANDLE hProvider,
    NCRYPT_KEY_HANDLE hImportKey,   // optional
    LPCWSTR pszBlobType,
    BCryptBufferDesc* pParameterList,   // optional
    NCRYPT_KEY_HANDLE* phKey,
    BYTE* pbData,
    DWORD cbData,
    NCRYPT_FLAGS dwFlags
);

パラメーター

名前方向説明
hProviderNCRYPT_PROV_HANDLEinキーストレージプロバイダーのハンドル。
hImportKeyNCRYPT_KEY_HANDLEinoptionalインポートする キー BLOB 内のキーデータの暗号化に使用された 暗号化キー のハンドル。これは NCryptExportKey 関数の hExportKey パラメーターに渡したキーと同じキーへのハンドルである必要があります。このパラメーターが NULL の場合、キー BLOB は暗号化されていないものとみなされます。
pszBlobTypeLPCWSTRinキー BLOB の形式を指定する識別子を含む、NULL で終わる Unicode 文字列。これらの形式は特定のキーストレージプロバイダーに固有です。Microsoft プロバイダーがサポートする BLOB 形式については、解説 を参照してください。
pParameterListBCryptBufferDesc*inoptionalキーのパラメーター情報を含むバッファーの配列を指す NCryptBufferDesc 構造体のアドレス。
phKeyNCRYPT_KEY_HANDLE*outキーのハンドルを受け取る NCRYPT_KEY_HANDLE 変数のアドレス。このハンドルの使用を終えたら、NCryptFreeObject 関数に渡して解放してください。
pbDataBYTE*inインポートするキー BLOB を含むバッファーのアドレス。cbData パラメーターにはこのバッファーのサイズが入ります。
cbDataDWORDinpbData バッファーのサイズ (バイト単位)。
dwFlagsNCRYPT_FLAGSin

関数の動作を変更するフラグ。ゼロ、または以下の値のうち 1 つ以上の組み合わせを指定できます。有効なフラグの組み合わせは各キーストレージプロバイダーに固有です。

意味
NCRYPT_SILENT_FLAG キーストレージプロバイダー (KSP) がユーザーインターフェイスを一切表示しないよう要求します。プロバイダーが動作のために UI を表示する必要がある場合、呼び出しは失敗し、KSP は最後のエラーとして NTE_SILENT_CONTEXT エラーコードを設定します。
NCRYPT_REQUIRE_VBS_FLAG キーを仮想化ベースのセキュリティ (VBS) で保護する必要があることを示します。既定では、再起動サイクルをまたいで保持される、ディスクに格納されたクロスブート永続キーを作成します。

VBS が利用できない場合、操作は失敗します。(*解説を参照)
NCRYPT_PREFER_VBS_FLAG キーを仮想化ベースのセキュリティ (VBS) で保護すべきであることを示します。既定では、再起動サイクルをまたいで保持される、ディスクに格納されたクロスブート永続キーを作成します。

VBS が利用できない場合は、ソフトウェアで分離されたキーを生成します。(*解説を参照)
NCRYPT_USE_PER_BOOT_KEY_FLAG NCRYPT_REQUIRE_VBS_FLAG または NCRYPT_PREFER_VBS_FLAG と併用できる追加のフラグ。クライアントキーを、ディスクに格納されるがブートサイクルをまたいで再利用できないブートごとのキーで保護するよう、仮想化ベースのセキュリティ (VBS) に指示します。(*解説を参照)

戻り値の型: HRESULT

公式ドキュメント

Cryptography API - Next Generation (CNG) のキーをメモリ BLOB からインポートします。

戻り値

関数の成功または失敗を示すステータスコードを返します。

返される可能性のあるコードには、以下のものが含まれますが、これらに限定されません。

戻り値コード 説明
ERROR_SUCCESS 関数は成功しました。
NTE_BAD_FLAGS dwFlags パラメーターに無効な値が含まれています。
NTE_EXISTS 指定された名前のキーが既に存在し、NCRYPT_OVERWRITE_KEY_FLAG が指定されていませんでした。
NTE_INVALID_HANDLE hProvider パラメーターが無効です。
NTE_INVALID_PARAMETER 1 つ以上のパラメーターが無効です。
NTE_NO_MEMORY メモリ割り当てに失敗しました。
NTE_VBS_UNAVAILABLE VBS が利用できません。
NTE_VBS_CANNOT_DECRYPT_KEY VBS の復号化操作が失敗しました。

解説(Remarks)

重要

VBS フラグに関する情報は、商用リリース前に大幅に変更される可能性があるプレリリース製品に関するものです。Microsoft は、ここで提供される情報について、明示または黙示を問わず、いかなる保証も行いません。

サービスは、その StartService 関数 からこの関数を呼び出してはなりません。サービスが StartService 関数からこの関数を呼び出すと、デッドロックが発生し、サービスが応答しなくなる可能性があります。

以下のセクションでは、Microsoft のキーストレージプロバイダーに固有の動作について説明します。

Microsoft Software KSP

Microsoft software KSP がサポートするほとんどの pszBlobType パラメーターの詳細については、NCryptImportKey を参照してください。

キー名が指定されない場合、Microsoft Software KSP はそのキーを一時的なものとして扱い、永続的に格納しません。NCRYPT_OPAQUETRANSPORT_BLOB タイプの場合、キー名はエクスポート時に BLOB 内に格納されます。その他の BLOB 形式の場合、名前は pParameterList パラメーター内の NCRYPTBUFFER_PKCS_KEY_NAME バッファーパラメーターで指定できます。

Windows Server 2008 および Windows Vista では、PKCS #7 エンベロープ BLOB (NCRYPT_PKCS7_ENVELOPE_BLOB) または PKCS #8 秘密キー BLOB (NCRYPT_PKCS8_PRIVATE_KEY_BLOB) としてインポートされたキーのみが、上記の方法で永続化できます。これらのプラットフォームで他の BLOB タイプを通じてインポートされたキーを永続化するには、キーのインポートとエクスポート に記載された方法を使用してください。

この KSP は以下のフラグをサポートします。

用語 説明
NCRYPT_NO_KEY_VALIDATION キーペアの公開部分を検証しません。このフラグは公開鍵/秘密鍵のペアにのみ適用されます。
NCRYPT_DO_NOT_FINALIZE_FLAG キーをファイナライズしません。このオプションは、インポート後にキーのプロパティを追加または変更する必要がある場合に役立ちます。キーを使用できるようにする前に、キーハンドルを NCryptFinalizeKey 関数に渡してファイナライズする必要があります。このフラグは PKCS #7 および PKCS #8 の秘密鍵ではサポートされますが、公開鍵ではサポートされません。
NCRYPT_MACHINE_KEY_FLAG キーはローカルコンピューターに適用されます。このフラグが存在しない場合、キーは現在のユーザーに適用されます。
NCRYPT_OVERWRITE_KEY_FLAG 指定された名前のキーがコンテナーに既に存在する場合、既存のキーが上書きされます。このフラグが指定されておらず、指定された名前のキーが既に存在する場合、この関数は NTE_EXISTS を返します。
NCRYPT_WRITE_KEY_TO_LEGACY_STORE_FLAG キーをレガシーストレージにも保存します。これにより、キーを CryptoAPI で使用できるようになります。このフラグは RSA キーにのみ適用されます。

Microsoft Smart Card KSP

この KSP がサポートするキー BLOB 形式とフラグの組み合わせは、Microsoft Software KSP がサポートするものと同一です。

Windows Server 2008 および Windows Vista では、Microsoft Smart Card KSP はすべてのキーを Microsoft Software KSP にインポートします。したがって、この API を使用してキーをスマートカードに永続化することはできず、Microsoft Software KSP 内にキーを永続化しようとする場合は上記セクションのガイダンスが適用されます。

Windows Server 2008 R2 および Windows 7 では、以下の条件を満たす場合に限り、Microsoft Smart Card Key Storage Provider は秘密鍵をスマートカードにインポートできます。

キーコンテナー名が NULL の場合、Microsoft Smart Card KSP はそのキーを一時的なものとして扱い、Microsoft Software KSP にインポートします。

VBS キーの追加ハードウェア要件

お使いのマシンに適切な OS がインストールされていても、VBS を使用してキーを生成および保護するには、以下の追加のハードウェア要件を満たす必要があります。

ハードウェア要件の詳細については、以下を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// ncrypt.dll
#include <windows.h>

HRESULT NCryptImportKey(
    NCRYPT_PROV_HANDLE hProvider,
    NCRYPT_KEY_HANDLE hImportKey,   // optional
    LPCWSTR pszBlobType,
    BCryptBufferDesc* pParameterList,   // optional
    NCRYPT_KEY_HANDLE* phKey,
    BYTE* pbData,
    DWORD cbData,
    NCRYPT_FLAGS dwFlags
);
[DllImport("ncrypt.dll", ExactSpelling = true)]
static extern int NCryptImportKey(
    UIntPtr hProvider,   // NCRYPT_PROV_HANDLE
    UIntPtr hImportKey,   // NCRYPT_KEY_HANDLE optional
    [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType,   // LPCWSTR
    IntPtr pParameterList,   // BCryptBufferDesc* optional
    out UIntPtr phKey,   // NCRYPT_KEY_HANDLE* out
    IntPtr pbData,   // BYTE*
    uint cbData,   // DWORD
    uint dwFlags   // NCRYPT_FLAGS
);
<DllImport("ncrypt.dll", ExactSpelling:=True)>
Public Shared Function NCryptImportKey(
    hProvider As UIntPtr,   ' NCRYPT_PROV_HANDLE
    hImportKey As UIntPtr,   ' NCRYPT_KEY_HANDLE optional
    <MarshalAs(UnmanagedType.LPWStr)> pszBlobType As String,   ' LPCWSTR
    pParameterList As IntPtr,   ' BCryptBufferDesc* optional
    <Out> ByRef phKey As UIntPtr,   ' NCRYPT_KEY_HANDLE* out
    pbData As IntPtr,   ' BYTE*
    cbData As UInteger,   ' DWORD
    dwFlags As UInteger   ' NCRYPT_FLAGS
) As Integer
End Function
' hProvider : NCRYPT_PROV_HANDLE
' hImportKey : NCRYPT_KEY_HANDLE optional
' pszBlobType : LPCWSTR
' pParameterList : BCryptBufferDesc* optional
' phKey : NCRYPT_KEY_HANDLE* out
' pbData : BYTE*
' cbData : DWORD
' dwFlags : NCRYPT_FLAGS
Declare PtrSafe Function NCryptImportKey Lib "ncrypt" ( _
    ByVal hProvider As LongPtr, _
    ByVal hImportKey As LongPtr, _
    ByVal pszBlobType As LongPtr, _
    ByVal pParameterList As LongPtr, _
    ByRef phKey As LongPtr, _
    ByVal pbData As LongPtr, _
    ByVal cbData As Long, _
    ByVal dwFlags As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

NCryptImportKey = ctypes.windll.ncrypt.NCryptImportKey
NCryptImportKey.restype = ctypes.c_int
NCryptImportKey.argtypes = [
    ctypes.c_size_t,  # hProvider : NCRYPT_PROV_HANDLE
    ctypes.c_size_t,  # hImportKey : NCRYPT_KEY_HANDLE optional
    wintypes.LPCWSTR,  # pszBlobType : LPCWSTR
    ctypes.c_void_p,  # pParameterList : BCryptBufferDesc* optional
    ctypes.c_void_p,  # phKey : NCRYPT_KEY_HANDLE* out
    ctypes.POINTER(ctypes.c_ubyte),  # pbData : BYTE*
    wintypes.DWORD,  # cbData : DWORD
    wintypes.DWORD,  # dwFlags : NCRYPT_FLAGS
]
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('ncrypt.dll')
NCryptImportKey = Fiddle::Function.new(
  lib['NCryptImportKey'],
  [
    Fiddle::TYPE_UINTPTR_T,  # hProvider : NCRYPT_PROV_HANDLE
    Fiddle::TYPE_UINTPTR_T,  # hImportKey : NCRYPT_KEY_HANDLE optional
    Fiddle::TYPE_VOIDP,  # pszBlobType : LPCWSTR
    Fiddle::TYPE_VOIDP,  # pParameterList : BCryptBufferDesc* optional
    Fiddle::TYPE_VOIDP,  # phKey : NCRYPT_KEY_HANDLE* out
    Fiddle::TYPE_VOIDP,  # pbData : BYTE*
    -Fiddle::TYPE_INT,  # cbData : DWORD
    -Fiddle::TYPE_INT,  # dwFlags : NCRYPT_FLAGS
  ],
  Fiddle::TYPE_INT)
#[link(name = "ncrypt")]
extern "system" {
    fn NCryptImportKey(
        hProvider: usize,  // NCRYPT_PROV_HANDLE
        hImportKey: usize,  // NCRYPT_KEY_HANDLE optional
        pszBlobType: *const u16,  // LPCWSTR
        pParameterList: *mut BCryptBufferDesc,  // BCryptBufferDesc* optional
        phKey: *mut usize,  // NCRYPT_KEY_HANDLE* out
        pbData: *mut u8,  // BYTE*
        cbData: u32,  // DWORD
        dwFlags: u32  // NCRYPT_FLAGS
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[DllImport("ncrypt.dll")]
public static extern int NCryptImportKey(UIntPtr hProvider, UIntPtr hImportKey, [MarshalAs(UnmanagedType.LPWStr)] string pszBlobType, IntPtr pParameterList, out UIntPtr phKey, IntPtr pbData, uint cbData, uint dwFlags);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ncrypt_NCryptImportKey' -Namespace Win32 -PassThru
# $api::NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
#uselib "ncrypt.dll"
#func global NCryptImportKey "NCryptImportKey" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; NCryptImportKey hProvider, hImportKey, pszBlobType, varptr(pParameterList), varptr(phKey), varptr(pbData), cbData, dwFlags   ; 戻り値は stat
; hProvider : NCRYPT_PROV_HANDLE -> "sptr"
; hImportKey : NCRYPT_KEY_HANDLE optional -> "sptr"
; pszBlobType : LPCWSTR -> "sptr"
; pParameterList : BCryptBufferDesc* optional -> "sptr"
; phKey : NCRYPT_KEY_HANDLE* out -> "sptr"
; pbData : BYTE* -> "sptr"
; cbData : DWORD -> "sptr"
; dwFlags : NCRYPT_FLAGS -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "ncrypt.dll"
#cfunc global NCryptImportKey "NCryptImportKey" sptr, sptr, wstr, var, var, var, int, int
; res = NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
; hProvider : NCRYPT_PROV_HANDLE -> "sptr"
; hImportKey : NCRYPT_KEY_HANDLE optional -> "sptr"
; pszBlobType : LPCWSTR -> "wstr"
; pParameterList : BCryptBufferDesc* optional -> "var"
; phKey : NCRYPT_KEY_HANDLE* out -> "var"
; pbData : BYTE* -> "var"
; cbData : DWORD -> "int"
; dwFlags : NCRYPT_FLAGS -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; HRESULT NCryptImportKey(NCRYPT_PROV_HANDLE hProvider, NCRYPT_KEY_HANDLE hImportKey, LPCWSTR pszBlobType, BCryptBufferDesc* pParameterList, NCRYPT_KEY_HANDLE* phKey, BYTE* pbData, DWORD cbData, NCRYPT_FLAGS dwFlags)
#uselib "ncrypt.dll"
#cfunc global NCryptImportKey "NCryptImportKey" intptr, intptr, wstr, var, var, var, int, int
; res = NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
; hProvider : NCRYPT_PROV_HANDLE -> "intptr"
; hImportKey : NCRYPT_KEY_HANDLE optional -> "intptr"
; pszBlobType : LPCWSTR -> "wstr"
; pParameterList : BCryptBufferDesc* optional -> "var"
; phKey : NCRYPT_KEY_HANDLE* out -> "var"
; pbData : BYTE* -> "var"
; cbData : DWORD -> "int"
; dwFlags : NCRYPT_FLAGS -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	ncrypt = windows.NewLazySystemDLL("ncrypt.dll")
	procNCryptImportKey = ncrypt.NewProc("NCryptImportKey")
)

// hProvider (NCRYPT_PROV_HANDLE), hImportKey (NCRYPT_KEY_HANDLE optional), pszBlobType (LPCWSTR), pParameterList (BCryptBufferDesc* optional), phKey (NCRYPT_KEY_HANDLE* out), pbData (BYTE*), cbData (DWORD), dwFlags (NCRYPT_FLAGS)
r1, _, err := procNCryptImportKey.Call(
	uintptr(hProvider),
	uintptr(hImportKey),
	uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(pszBlobType))),
	uintptr(pParameterList),
	uintptr(phKey),
	uintptr(pbData),
	uintptr(cbData),
	uintptr(dwFlags),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // HRESULT
function NCryptImportKey(
  hProvider: NativeUInt;   // NCRYPT_PROV_HANDLE
  hImportKey: NativeUInt;   // NCRYPT_KEY_HANDLE optional
  pszBlobType: PWideChar;   // LPCWSTR
  pParameterList: Pointer;   // BCryptBufferDesc* optional
  phKey: Pointer;   // NCRYPT_KEY_HANDLE* out
  pbData: Pointer;   // BYTE*
  cbData: DWORD;   // DWORD
  dwFlags: DWORD   // NCRYPT_FLAGS
): Integer; stdcall;
  external 'ncrypt.dll' name 'NCryptImportKey';
result := DllCall("ncrypt\NCryptImportKey"
    , "UPtr", hProvider   ; NCRYPT_PROV_HANDLE
    , "UPtr", hImportKey   ; NCRYPT_KEY_HANDLE optional
    , "WStr", pszBlobType   ; LPCWSTR
    , "Ptr", pParameterList   ; BCryptBufferDesc* optional
    , "Ptr", phKey   ; NCRYPT_KEY_HANDLE* out
    , "Ptr", pbData   ; BYTE*
    , "UInt", cbData   ; DWORD
    , "UInt", dwFlags   ; NCRYPT_FLAGS
    , "Int")   ; return: HRESULT
●NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags) = DLL("ncrypt.dll", "int NCryptImportKey(int, int, char*, void*, void*, void*, dword, dword)")
# 呼び出し: NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
# hProvider : NCRYPT_PROV_HANDLE -> "int"
# hImportKey : NCRYPT_KEY_HANDLE optional -> "int"
# pszBlobType : LPCWSTR -> "char*"
# pParameterList : BCryptBufferDesc* optional -> "void*"
# phKey : NCRYPT_KEY_HANDLE* out -> "void*"
# pbData : BYTE* -> "void*"
# cbData : DWORD -> "dword"
# dwFlags : NCRYPT_FLAGS -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "ncrypt" fn NCryptImportKey(
    hProvider: usize, // NCRYPT_PROV_HANDLE
    hImportKey: usize, // NCRYPT_KEY_HANDLE optional
    pszBlobType: [*c]const u16, // LPCWSTR
    pParameterList: [*c]BCryptBufferDesc, // BCryptBufferDesc* optional
    phKey: [*c]usize, // NCRYPT_KEY_HANDLE* out
    pbData: [*c]u8, // BYTE*
    cbData: u32, // DWORD
    dwFlags: u32 // NCRYPT_FLAGS
) callconv(std.os.windows.WINAPI) i32;
proc NCryptImportKey(
    hProvider: uint,  # NCRYPT_PROV_HANDLE
    hImportKey: uint,  # NCRYPT_KEY_HANDLE optional
    pszBlobType: WideCString,  # LPCWSTR
    pParameterList: ptr BCryptBufferDesc,  # BCryptBufferDesc* optional
    phKey: ptr uint,  # NCRYPT_KEY_HANDLE* out
    pbData: ptr uint8,  # BYTE*
    cbData: uint32,  # DWORD
    dwFlags: uint32  # NCRYPT_FLAGS
): int32 {.importc: "NCryptImportKey", stdcall, dynlib: "ncrypt.dll".}
pragma(lib, "ncrypt");
extern(Windows)
int NCryptImportKey(
    size_t hProvider,   // NCRYPT_PROV_HANDLE
    size_t hImportKey,   // NCRYPT_KEY_HANDLE optional
    const(wchar)* pszBlobType,   // LPCWSTR
    BCryptBufferDesc* pParameterList,   // BCryptBufferDesc* optional
    size_t* phKey,   // NCRYPT_KEY_HANDLE* out
    ubyte* pbData,   // BYTE*
    uint cbData,   // DWORD
    uint dwFlags   // NCRYPT_FLAGS
);
ccall((:NCryptImportKey, "ncrypt.dll"), stdcall, Int32,
      (Csize_t, Csize_t, Cwstring, Ptr{BCryptBufferDesc}, Ptr{Csize_t}, Ptr{UInt8}, UInt32, UInt32),
      hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
# hProvider : NCRYPT_PROV_HANDLE -> Csize_t
# hImportKey : NCRYPT_KEY_HANDLE optional -> Csize_t
# pszBlobType : LPCWSTR -> Cwstring
# pParameterList : BCryptBufferDesc* optional -> Ptr{BCryptBufferDesc}
# phKey : NCRYPT_KEY_HANDLE* out -> Ptr{Csize_t}
# pbData : BYTE* -> Ptr{UInt8}
# cbData : DWORD -> UInt32
# dwFlags : NCRYPT_FLAGS -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t NCryptImportKey(
    uintptr_t hProvider,
    uintptr_t hImportKey,
    const uint16_t* pszBlobType,
    void* pParameterList,
    uintptr_t* phKey,
    uint8_t* pbData,
    uint32_t cbData,
    uint32_t dwFlags);
]]
local ncrypt = ffi.load("ncrypt")
-- ncrypt.NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
-- hProvider : NCRYPT_PROV_HANDLE
-- hImportKey : NCRYPT_KEY_HANDLE optional
-- pszBlobType : LPCWSTR
-- pParameterList : BCryptBufferDesc* optional
-- phKey : NCRYPT_KEY_HANDLE* out
-- pbData : BYTE*
-- cbData : DWORD
-- dwFlags : NCRYPT_FLAGS
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('ncrypt.dll');
const NCryptImportKey = lib.func('__stdcall', 'NCryptImportKey', 'int32_t', ['uintptr_t', 'uintptr_t', 'str16', 'void *', 'uintptr_t *', 'uint8_t *', 'uint32_t', 'uint32_t']);
// NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
// hProvider : NCRYPT_PROV_HANDLE -> 'uintptr_t'
// hImportKey : NCRYPT_KEY_HANDLE optional -> 'uintptr_t'
// pszBlobType : LPCWSTR -> 'str16'
// pParameterList : BCryptBufferDesc* optional -> 'void *'
// phKey : NCRYPT_KEY_HANDLE* out -> 'uintptr_t *'
// pbData : BYTE* -> 'uint8_t *'
// cbData : DWORD -> 'uint32_t'
// dwFlags : NCRYPT_FLAGS -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("ncrypt.dll", {
  NCryptImportKey: { parameters: ["usize", "usize", "buffer", "pointer", "pointer", "pointer", "u32", "u32"], result: "i32" },
});
// lib.symbols.NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags)
// hProvider : NCRYPT_PROV_HANDLE -> "usize"
// hImportKey : NCRYPT_KEY_HANDLE optional -> "usize"
// pszBlobType : LPCWSTR -> "buffer"
// pParameterList : BCryptBufferDesc* optional -> "pointer"
// phKey : NCRYPT_KEY_HANDLE* out -> "pointer"
// pbData : BYTE* -> "pointer"
// cbData : DWORD -> "u32"
// dwFlags : NCRYPT_FLAGS -> "u32"
// 文字列引数は "buffer"(NUL 終端のバイト列を Uint8Array で渡す)。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t NCryptImportKey(
    size_t hProvider,
    size_t hImportKey,
    const uint16_t* pszBlobType,
    void* pParameterList,
    size_t* phKey,
    uint8_t* pbData,
    uint32_t cbData,
    uint32_t dwFlags);
C, "ncrypt.dll");
// $ffi->NCryptImportKey(hProvider, hImportKey, pszBlobType, pParameterList, phKey, pbData, cbData, dwFlags);
// hProvider : NCRYPT_PROV_HANDLE
// hImportKey : NCRYPT_KEY_HANDLE optional
// pszBlobType : LPCWSTR
// pParameterList : BCryptBufferDesc* optional
// phKey : NCRYPT_KEY_HANDLE* out
// pbData : BYTE*
// cbData : DWORD
// dwFlags : NCRYPT_FLAGS
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;

public interface Ncrypt extends StdCallLibrary {
    Ncrypt INSTANCE = Native.load("ncrypt", Ncrypt.class);
    int NCryptImportKey(
        long hProvider,   // NCRYPT_PROV_HANDLE
        long hImportKey,   // NCRYPT_KEY_HANDLE optional
        WString pszBlobType,   // LPCWSTR
        Pointer pParameterList,   // BCryptBufferDesc* optional
        LongByReference phKey,   // NCRYPT_KEY_HANDLE* out
        byte[] pbData,   // BYTE*
        int cbData,   // DWORD
        int dwFlags   // NCRYPT_FLAGS
    );
}
@[Link("ncrypt")]
lib Libncrypt
  fun NCryptImportKey = NCryptImportKey(
    hProvider : LibC::SizeT,   # NCRYPT_PROV_HANDLE
    hImportKey : LibC::SizeT,   # NCRYPT_KEY_HANDLE optional
    pszBlobType : UInt16*,   # LPCWSTR
    pParameterList : BCryptBufferDesc*,   # BCryptBufferDesc* optional
    phKey : LibC::SizeT*,   # NCRYPT_KEY_HANDLE* out
    pbData : UInt8*,   # BYTE*
    cbData : UInt32,   # DWORD
    dwFlags : UInt32   # NCRYPT_FLAGS
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef NCryptImportKeyNative = Int32 Function(UintPtr, UintPtr, Pointer<Utf16>, Pointer<Void>, Pointer<UintPtr>, Pointer<Uint8>, Uint32, Uint32);
typedef NCryptImportKeyDart = int Function(int, int, Pointer<Utf16>, Pointer<Void>, Pointer<UintPtr>, Pointer<Uint8>, int, int);
final NCryptImportKey = DynamicLibrary.open('ncrypt.dll')
    .lookupFunction<NCryptImportKeyNative, NCryptImportKeyDart>('NCryptImportKey');
// hProvider : NCRYPT_PROV_HANDLE -> UintPtr
// hImportKey : NCRYPT_KEY_HANDLE optional -> UintPtr
// pszBlobType : LPCWSTR -> Pointer<Utf16>
// pParameterList : BCryptBufferDesc* optional -> Pointer<Void>
// phKey : NCRYPT_KEY_HANDLE* out -> Pointer<UintPtr>
// pbData : BYTE* -> Pointer<Uint8>
// cbData : DWORD -> Uint32
// dwFlags : NCRYPT_FLAGS -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function NCryptImportKey(
  hProvider: NativeUInt;   // NCRYPT_PROV_HANDLE
  hImportKey: NativeUInt;   // NCRYPT_KEY_HANDLE optional
  pszBlobType: PWideChar;   // LPCWSTR
  pParameterList: Pointer;   // BCryptBufferDesc* optional
  phKey: Pointer;   // NCRYPT_KEY_HANDLE* out
  pbData: Pointer;   // BYTE*
  cbData: DWORD;   // DWORD
  dwFlags: DWORD   // NCRYPT_FLAGS
): Integer; stdcall;
  external 'ncrypt.dll' name 'NCryptImportKey';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "NCryptImportKey"
  c_NCryptImportKey :: CUIntPtr -> CUIntPtr -> CWString -> Ptr () -> Ptr CUIntPtr -> Ptr Word8 -> Word32 -> Word32 -> IO Int32
-- hProvider : NCRYPT_PROV_HANDLE -> CUIntPtr
-- hImportKey : NCRYPT_KEY_HANDLE optional -> CUIntPtr
-- pszBlobType : LPCWSTR -> CWString
-- pParameterList : BCryptBufferDesc* optional -> Ptr ()
-- phKey : NCRYPT_KEY_HANDLE* out -> Ptr CUIntPtr
-- pbData : BYTE* -> Ptr Word8
-- cbData : DWORD -> Word32
-- dwFlags : NCRYPT_FLAGS -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let ncryptimportkey =
  foreign "NCryptImportKey"
    (size_t @-> size_t @-> (ptr uint16_t) @-> (ptr void) @-> (ptr size_t) @-> (ptr uint8_t) @-> uint32_t @-> uint32_t @-> returning int32_t)
(* hProvider : NCRYPT_PROV_HANDLE -> size_t *)
(* hImportKey : NCRYPT_KEY_HANDLE optional -> size_t *)
(* pszBlobType : LPCWSTR -> (ptr uint16_t) *)
(* pParameterList : BCryptBufferDesc* optional -> (ptr void) *)
(* phKey : NCRYPT_KEY_HANDLE* out -> (ptr size_t) *)
(* pbData : BYTE* -> (ptr uint8_t) *)
(* cbData : DWORD -> uint32_t *)
(* dwFlags : NCRYPT_FLAGS -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library ncrypt (t "ncrypt.dll"))
(cffi:use-foreign-library ncrypt)

(cffi:defcfun ("NCryptImportKey" ncrypt-import-key :convention :stdcall) :int32
  (h-provider :uint64)   ; NCRYPT_PROV_HANDLE
  (h-import-key :uint64)   ; NCRYPT_KEY_HANDLE optional
  (psz-blob-type (:string :encoding :utf-16le))   ; LPCWSTR
  (p-parameter-list :pointer)   ; BCryptBufferDesc* optional
  (ph-key :pointer)   ; NCRYPT_KEY_HANDLE* out
  (pb-data :pointer)   ; BYTE*
  (cb-data :uint32)   ; DWORD
  (dw-flags :uint32))   ; NCRYPT_FLAGS
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $NCryptImportKey = Win32::API::More->new('ncrypt',
    'int NCryptImportKey(WPARAM hProvider, WPARAM hImportKey, LPCWSTR pszBlobType, LPVOID pParameterList, LPVOID phKey, LPVOID pbData, DWORD cbData, DWORD dwFlags)');
# my $ret = $NCryptImportKey->Call($hProvider, $hImportKey, $pszBlobType, $pParameterList, $phKey, $pbData, $cbData, $dwFlags);
# hProvider : NCRYPT_PROV_HANDLE -> WPARAM
# hImportKey : NCRYPT_KEY_HANDLE optional -> WPARAM
# pszBlobType : LPCWSTR -> LPCWSTR
# pParameterList : BCryptBufferDesc* optional -> LPVOID
# phKey : NCRYPT_KEY_HANDLE* out -> LPVOID
# pbData : BYTE* -> LPVOID
# cbData : DWORD -> DWORD
# dwFlags : NCRYPT_FLAGS -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

使用する型