通用查询(C/C++)
===========

从API 22开始，huksExternalCrypto提供通用查询功能接口。从Ukey获取通用属性信息，完成属性查询操作。具体的场景介绍请参考[获取属性介绍及规格](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/huks-ukey-general-query-overview)。

#### 在CMake脚本中链接相关动态库

target\_link\_libraries(entry PUBLIC libhuks\_ndk.z.so libhuks\_external\_crypto.z.so)

#### 开发步骤

**获取属性**

1.  构造resourceId和propertyId，先调用[OH\_Huks\_OpenResource](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_openresource)打开资源。
    
2.  初始化参数集：通过[OH\_Huks\_InitExternalCryptoParamSet](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_initexternalcryptoparamset)、[OH\_Huks\_AddExternalCryptoParams](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_addexternalcryptoparams)、[OH\_Huks\_BuildExternalCryptoParamSet](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_buildexternalcryptoparamset)构造参数集paramSet。
    
3.  调用[OH\_Huks\_GetProperty](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_getproperty)获取属性信息。
    
4.  调用[OH\_Huks\_GetExternalCryptoParam](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_getexternalcryptoparam)从输出参数集中提取结果。
    
5.  调用[OH\_Huks\_FreeExternalCryptoParamSet](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-native-huks-external-crypto-api-h#oh_huks_freeexternalcryptoparamset)释放参数集资源。
    

#### 开发案例

#include "huks/native\_huks\_external\_crypto\_api.h"
#include "huks/native\_huks\_external\_crypto\_type.h"
#include "napi/native\_api.h"
#include <string.h>

OH\_Huks\_Result InitExternalCryptoParamSet(
    OH\_Huks\_ExternalCryptoParamSet \*\*paramSet,
    const OH\_Huks\_ExternalCryptoParam \*params,
    uint32\_t paramCount)
{
    OH\_Huks\_Result ret = OH\_Huks\_InitExternalCryptoParamSet(paramSet);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        return ret;
    }
    ret = OH\_Huks\_AddExternalCryptoParams(\*paramSet, params, paramCount);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        OH\_Huks\_FreeExternalCryptoParamSet(paramSet);
        return ret;
    }
    ret = OH\_Huks\_BuildExternalCryptoParamSet(paramSet);
    if (ret.errorCode != OH\_HUKS\_SUCCESS) {
        OH\_Huks\_FreeExternalCryptoParamSet(paramSet);
        return ret;
    }
    return ret;
}

static napi\_value GetProperty(napi\_env env, napi\_callback\_info info)
{
    /\* 1.假设已经打开了resourceId \*/
    const char \*resourceIdStr = "{\\"providerName\\":\\"testProviderName\\",\\"abilityName\\":\\"CryptoExtension\\","
                              "\\"bundleName\\":\\"com.example.cryptoapplication\\",\\"index\\":{\\"key\\":\\"testKey\\"}}";
    const char \*propertyIdStr = "SKF\_GetDevInfo"; // 定义在GMT 0016-2023标准中的属性函数名称
    
    struct OH\_Huks\_Blob resourceId = {
        (uint32\_t)strlen(resourceIdStr),
        (uint8\_t \*)resourceIdStr
    };
    struct OH\_Huks\_Blob propertyId = {
        (uint32\_t)strlen(propertyIdStr),
        (uint8\_t \*)propertyIdStr
    };
    
    /\* 2.构造输入参数 \*/
    OH\_Huks\_ExternalCryptoParam params\[\] = {};
    OH\_Huks\_ExternalCryptoParamSet \*paramSetIn = nullptr;
    OH\_Huks\_ExternalCryptoParamSet \*paramSetOut = nullptr;
    OH\_Huks\_Result ohResult;
    
    do {
        /\* 3.初始化并构建输入参数集 \*/
        ohResult = InitExternalCryptoParamSet(&paramSetIn, params,
            sizeof(params) / sizeof(OH\_Huks\_ExternalCryptoParam));
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 4.调用OH\_Huks\_GetProperty获取属性 \*/
        ohResult = OH\_Huks\_GetProperty(&resourceId, &propertyId, paramSetIn, &paramSetOut);
        if (ohResult.errorCode != OH\_HUKS\_SUCCESS) {
            break;
        }
        
        /\* 5.从输出参数集中提取结果
         \* 输出参数集由函数内部分配，查询到的属性数据放在 OH\_HUKS\_EXT\_CRYPTO\_TAG\_EXTRA\_DATA TAG 中。
         \* 下面展示如何遍历返回的 params 并安全提取返回的属性字符串（示例）。
         \*/
        if (paramSetOut != nullptr && paramSetOut->paramsCnt > 0) {
            for (uint32\_t i = 0; i < paramSetOut->paramsCnt; i++) {
                OH\_Huks\_ExternalCryptoParam \*param = &paramSetOut->params\[i\];
                /\* 返回数据约定：GetProperty 的结果放在 OH\_HUKS\_EXT\_CRYPTO\_TAG\_EXTRA\_DATA TAG 中（示例使用 JSON 文本） \*/
                if (param->tag == OH\_HUKS\_EXT\_CRYPTO\_TAG\_EXTRA\_DATA) {
                    /\* 注意：param->blob.data 可能不是以 '\\0' 结尾，需拷贝并手动添加终止符 \*/
                    char \*outStr = (char \*)malloc(param->blob.size + 1);
                    if (outStr != NULL) {
                        memcpy(outStr, param->blob.data, param->blob.size);
                        outStr\[param->blob.size\] = '\\0';
                        // 解析 outStr（例如使用 JSON 解析库），示例：
                        // parse\_json(outStr);
                        free(outStr);
                    }
                }
            }
        }
    } while (0);
    
    /\* 6.释放资源 \*/
    OH\_Huks\_FreeExternalCryptoParamSet(&paramSetIn);
    OH\_Huks\_FreeExternalCryptoParamSet(&paramSetOut);
    
    napi\_value ret;
    napi\_create\_int32(env, ohResult.errorCode, &ret);
    return ret;
}