Virbox SDK  2.1
函数
Virbox Runtime 接口说明

函数

SS_UINT32 SSAPI slm_init (IN ST_INIT_PARAM *pst_init)
 Runtime API 初始化函数,调用所有 Runtime API 必须先调用此函数进行初始化 更多...
 
SS_UINT32 SSAPI slm_find_license (IN SS_UINT32 license_id, IN INFO_FORMAT_TYPE format, OUT char **license_desc)
 查找许可信息(仅对硬件锁有效) 更多...
 
SS_UINT32 SSAPI slm_get_cloud_token (OUT SS_CHAR **access_token)
 枚举已登录的用户 token 更多...
 
SS_UINT32 SSAPI slm_login (IN const ST_LOGIN_PARAM *license_param, IN INFO_FORMAT_TYPE param_format, OUT SLM_HANDLE_INDEX *slm_handle, IN OUT void *auth)
 安全登录许可,用 JSON 传递参数,并且检查时间(是否到期或者是否早于开始时间)、次数、并发数是否归零, 如果有计数器,则永久性减少对应的计数器,对于网络锁则临时增加网络并发计数器。 更多...
 
SS_UINT32 SSAPI slm_logout (SLM_HANDLE_INDEX slm_handle)
 许可登出,并且释放许可句柄等资源 更多...
 
SS_UINT32 SSAPI slm_keep_alive (SLM_HANDLE_INDEX slm_handle)
 保持登录会话心跳,避免变为“僵尸句柄”。 更多...
 
SS_UINT32 SSAPI slm_encrypt (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *inbuffer, OUT SS_BYTE *outbuffer, IN SS_UINT32 len)
 许可加密,相同的许可ID相同的开发者加密结果相同 更多...
 
SS_UINT32 SSAPI slm_decrypt (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *inbuffer, OUT SS_BYTE *outbuffer, IN SS_UINT32 len)
 许可解密,相同的许可ID相同的开发者加密结果相同 更多...
 
SS_UINT32 SSAPI slm_user_data_getsize (IN SLM_HANDLE_INDEX slm_handle, IN LIC_USER_DATA_TYPE type, OUT SS_UINT32 *pmem_size)
 获得许可的用户数据区大小 更多...
 
SS_UINT32 SSAPI slm_user_data_read (IN SLM_HANDLE_INDEX slm_handle, IN LIC_USER_DATA_TYPE type, OUT SS_BYTE *readbuf, IN SS_UINT32 offset, IN SS_UINT32 len)
 读许可数据,可以读取 #PUB、#RAW 和 ROM 更多...
 
SS_UINT32 SSAPI slm_user_data_write (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *writebuf, IN SS_UINT32 offset, IN SS_UINT32 len)
 写许可的读写数据区 ,数据区操作之前请先确认锁内读写区的大小,可以使用 slm_user_data_getsize 获得 更多...
 
SS_UINT32 SSAPI slm_pub_data_getsize (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 license_id, OUT SS_UINT32 *pmem_size)
 获得指定许可的公开区数据区大小,需要登录 0号许可 更多...
 
SS_UINT32 SSAPI slm_pub_data_read (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 license_id, OUT SS_BYTE *readbuf, IN SS_UINT32 offset, IN SS_UINT32 len)
 读取许可公开区,需要登录 0号许可 更多...
 
SS_UINT32 SSAPI slm_get_info (IN SLM_HANDLE_INDEX slm_handle, IN INFO_TYPE type, IN INFO_FORMAT_TYPE format, OUT char **result)
 获取已登录许可的状态信息,例如许可信息、硬件锁信息等 更多...
 
SS_UINT32 SSAPI slm_execute_static (IN SLM_HANDLE_INDEX slm_handle, IN const char *exfname, IN SS_BYTE *inbuf, IN SS_UINT32 insize, OUT SS_BYTE *poutbuf, IN SS_UINT32 outsize, OUT SS_UINT32 *pretsize)
 开发者自定义算法,锁内可执行算法,锁内静态代码执行(仅支持硬件锁), 由开发者调用 D2CAPI 库中的 d2c_add_pkg 签发可执行代码接口生成,提前将可执行算法下载到锁内 更多...
 
SS_UINT32 SSAPI slm_execute_dynamic (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *exf_buffer, IN SS_UINT32 exf_size, IN SS_BYTE *inbuf, IN SS_UINT32 insize, OUT SS_BYTE *poutbuf, IN SS_UINT32 outsize, OUT SS_UINT32 *pretsize)
 开发者自定义算法,锁内可执行算法,锁内动态执行代码(仅支持硬件锁),在应用程序运行过程中下载到锁内进行执行 更多...
 
SS_UINT32 SSAPI slm_mem_alloc (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 size, OUT SS_UINT32 *mem_id)
 Virbox许可服务 内存托管内存申请 更多...
 
SS_UINT32 SSAPI slm_mem_free (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 mem_id)
 释放托管内存 更多...
 
SS_UINT32 SSAPI slm_mem_read (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 mem_id, IN SS_UINT32 offset, IN SS_UINT32 len, IN SS_BYTE *readbuff, OUT SS_UINT32 *readlen)
 Virbox许可服务 内存托管读 更多...
 
SS_UINT32 SSAPI slm_mem_write (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 mem_id, IN SS_UINT32 offset, IN SS_UINT32 len, IN SS_BYTE *writebuff, OUT SS_UINT32 *numberofbyteswritten)
 Virbox许可服务 内存托管内存写入 更多...
 
SS_UINT32 SSAPI slm_is_debug (IN void *auth)
 检测是否正在调试 更多...
 
SS_UINT32 SSAPI slm_get_cert (IN SLM_HANDLE_INDEX slm_handle, IN CERT_TYPE cert_type, OUT SS_BYTE *cert, IN SS_UINT32 cert_size, OUT SS_UINT32 *cert_len)
 通过证书类型,获取已登录许可的设备证书 更多...
 
SS_UINT32 SSAPI slm_get_device_cert (IN SLM_HANDLE_INDEX slm_handle, OUT SS_BYTE *device_cert, IN SS_UINT32 buff_size, OUT SS_UINT32 *return_size)
 获取已登录的加密锁证书 更多...
 
SS_UINT32 SSAPI slm_sign_by_device (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *verify_data, IN SS_UINT32 verify_data_size, OUT SS_BYTE *signature, IN SS_UINT32 signature_buf_size, OUT SS_UINT32 *signature_size)
 设备正版验证(仅支持硬件锁) 更多...
 
SS_UINT32 SSAPI slm_adjust_time_request (IN SLM_HANDLE_INDEX slm_handle, OUT SS_BYTE rand[SLM_FIXTIME_RAND_LENGTH], OUT SS_UINT32 *lock_time, IN OUT SS_UINT32 *pc_time)
 获取时间修复数据,用于生成时钟校准请求 更多...
 
SS_UINT32 SSAPI slm_led_control (IN SLM_HANDLE_INDEX slm_handle, IN ST_LED_CONTROL *led_ctrl)
 闪烁指示灯 更多...
 
SS_UINT32 SSAPI slm_get_version (OUT SS_UINT32 *api_version, OUT SS_UINT32 *ss_version)
 获得 Runtime 库 和 Virbox许可服务 的版本信息. 更多...
 
void SSAPI slm_free (IN void *buffer)
 释放API内分配堆区域 更多...
 
SS_UINT32 SSAPI slm_update (IN char *d2c_pkg, OUT char **error_msg)
 将D2C包进行升级,d2c包 由 D2CAPI 生成 更多...
 
SS_UINT32 SSAPI slm_update_ex (IN SS_BYTE *lock_sn, IN char *d2c_pkg, OUT char **error_msg)
 将D2C包进行升级,需指定加密锁唯一序列号,d2c包 由 D2CAPI 生成 更多...
 
SS_UINT32 SSAPI slm_d2c_update_inside (IN char *lock_sn, IN char *inside_file)
 锁内短码升级,需指定加密锁唯一序列号,需锁内可执行算法配合(仅支持硬件锁) 更多...
 
SS_UINT32 SSAPI slm_enum_device (OUT char **device_info)
 枚举本地锁信息 更多...
 
SS_UINT32 SSAPI slm_enum_device_ex (IN INFO_FORMAT_TYPE format, OUT void **device_info)
 枚举本地锁信息,支持按返回值类型获取 更多...
 
SS_UINT32 SSAPI slm_enum_license_id (IN const char *device_info, OUT char **license_ids)
 枚举指定设备下所有许可ID 更多...
 
SS_UINT32 SSAPI slm_enum_license_id_ex (IN ST_DEV_INFO *device_info, IN INFO_FORMAT_TYPE format, OUT void **license_ids)
 枚举指定设备下所有许可ID,支持按返回值类型获取 更多...
 
SS_UINT32 SSAPI slm_get_license_info (IN const char *device_info, IN SS_UINT32 license_id, OUT char **license_info)
 获取指定设备下指定许可的全部信息 更多...
 
SS_UINT32 SSAPI slm_get_license_info_ex (IN ST_DEV_INFO *device_info, IN SS_UINT32 license_id, IN INFO_FORMAT_TYPE format, OUT void **license_info)
 获取指定设备下指定许可的全部信息,支持按返回值类型获取 更多...
 
SS_UINT32 SSAPI slm_check_module (IN SLM_HANDLE_INDEX slm_handle, IN SS_UINT32 module_id)
 检查模块 更多...
 
SS_UINT32 SSAPI slm_snippet_execute (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *snippet_code, IN SS_UINT32 code_size, IN SS_BYTE *input, IN SS_UINT32 input_size, OUT SS_BYTE *output, IN SS_UINT32 outbuf_size, OUT SS_UINT32 *output_size)
 碎片代码执行(开发者不必关心) 更多...
 
SS_UINT32 SSAPI slm_get_developer_id (OUT SS_BYTE developer_id[SLM_DEVELOPER_ID_SIZE])
 获取 Runtime 库对应的开发商ID 更多...
 
SS_UINT32 SSAPI slm_license_sign (IN SLM_HANDLE_INDEX slm_handle, IN SS_BYTE *sign_data, IN SS_UINT32 sign_length, OUT SS_BYTE *signature, IN SS_UINT32 max_buf_size, OUT SS_UINT32 *signature_length)
 使用已登录的云许可进行签名(仅支持云锁) 更多...
 
SS_UINT32 SSAPI slm_license_verify (IN SS_BYTE *sign_data, IN SS_UINT32 sign_length, IN SS_BYTE *signature, IN SS_UINT32 signature_length, OUT char **sign_info)
 对云许可签名后的数据进行验签(仅支持云锁) 更多...
 
const SS_CHAR *SSAPI slm_error_format (IN SS_UINT32 error_code, IN SS_UINT32 language_id)
 通过错误码获得错误信息 更多...
 
SS_UINT32 SSAPI slm_cleanup (void)
 反初始化函数,与 slm_init 对应 更多...
 
SS_UINT32 SSAPI slm_extensions_config (IN const char *config)
 扩展配置接口 更多...
 

详细描述

此文档是 Virbox Runtime 用户运行时库,包含许可访问,许可加密,锁内代码执行等接口

函数说明

SS_UINT32 SSAPI slm_adjust_time_request ( IN SLM_HANDLE_INDEX  slm_handle,
OUT SS_BYTE  rand[SLM_FIXTIME_RAND_LENGTH],
OUT SS_UINT32 *  lock_time,
IN OUT SS_UINT32 *  pc_time 
)

获取时间修复数据,用于生成时钟校准请求

参数
[in]slm_handle许可句柄,由 slm_login 得到
[out]rand随机数
[out]lock_time锁时间
[in,out]pc_timePC时间,返回的PC时间(传入0则取当时时间)
返回
成功返回 SS_OK ,失败则返回相应错误码
SS_UINT32 SSAPI slm_check_module ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  module_id 
)

检查模块

参数
[in]slm_handle许可句柄,由 slm_login 得到
[in]module_id模块ID,范围由(1 ~ 64)
返回
模块存在返回 SS_OK ,不存在返回 SS_ERROR_LICENSE_MODULE_NOT_EXISTS , 否则返回其它错误码
SS_UINT32 SSAPI slm_cleanup ( void  )

反初始化函数,与 slm_init 对应

参见
slm_init
备注
slm_cleanup 是非线程安全的,此函数不建议开发者调用,因为程序退出时系统会自动回收没有释放的内存, 若开发者调用,为了保证多线程调用 Runtime API 的安全性,此函数建议在程序退出时调用。 一旦调用了此函数,以上所有API(除 slm_init )均不可使用。
SS_UINT32 SSAPI slm_d2c_update_inside ( IN char *  lock_sn,
IN char *  inside_file 
)

锁内短码升级,需指定加密锁唯一序列号,需锁内可执行算法配合(仅支持硬件锁)

参数
[in]lock_sn锁号(唯一序列号,十六进制字符串)
[in]inside_file锁内短码文件名
返回
成功返回 SS_OK ,失败返回错误码
备注
Virbox 提供的通过短码激活功能在硬件锁内生成一条 Virbox许可,该功能需要通过可执行算法的配合,简单的步骤描述为: 第一步、在锁内下载支持短码激活的使能文件 slac_enable.evd,文件内容任意,大小最好不超过 256字节; 第二步、编写锁内可执行算法,调用深思提供的 h5ses.lib 和 h5ses_lm.lib 库,实现短码转换的过程; 第三步、通过执行锁内可执行算法,即调用 slm_execute_static , 并传入短码内容,促使锁内可执行算法在锁内将短码转化为 硬件锁可识别的中间文件(文件名开发者设定)。 第四步、通过调用 slm_d2c_update_inside 接口,将锁内生成的中间文件转化为正式的 Virbox许可。

特别说明:短码激活方案使用较为复杂,需要写锁内代码的技术要求,若开发者需要使用此功能,可联系深思技术服务进行支持。

{
SS_UINT32 status = SS_OK;
SS_BYTE data_buf[1024] = { 0 };
SS_UINT32 data_size = 0;
char *sn = "9733c80100070205106100030015000c";
memcpy(data_buf, "1234567890", 10);
status = slm_execute_static(slm_handle, "test.evx", NULL, 0, data_buf, 10, &data_size);
if(status != SS_OK)
{
// todo: deal error code
}
status = slm_d2c_update_inside(sn, "test.evd");
if(status != SS_OK)
{
// todo: deal error code
}
}
参见
slm_execute_static
SS_UINT32 SSAPI slm_decrypt ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  inbuffer,
OUT SS_BYTE *  outbuffer,
IN SS_UINT32  len 
)

许可解密,相同的许可ID相同的开发者加密结果相同

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]inbuffer解密输入缓冲区,需要 16字节 对齐。最大不能超过 1520个字节。
[out]outbuffer解密输出缓冲区,需要 16字节 对齐
[in]len加密缓冲区大小,为 16 的整数倍。
返回
成功返回 SS_OK,失败返回相应的错误码
备注
加密方式采用 AES对称加密,密钥在加密锁内(指硬件锁、云锁、软锁,下同)生成,且没有任何机会能出锁,在保证效率的同时,也最大化的加强了安全性。 由于硬件锁最大传输字节数有限,因此加解密时一次传入的字节不得超过 1520个字节,若需要加解密的字节数大于此最大限制,可采用截取数据流,循环调用 接口的方式进行加解密,加解密结果不会受到任何影响。
//see slm_encrypt
参见
slm_encrypt slm_login
SS_UINT32 SSAPI slm_encrypt ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  inbuffer,
OUT SS_BYTE *  outbuffer,
IN SS_UINT32  len 
)

许可加密,相同的许可ID相同的开发者加密结果相同

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]inbuffer加密输入缓冲区,需要 16字节 对齐,最大不能超过 1520个字节。
[out]outbuffer加密输出缓冲区,需要 16字节 对齐
[in]len加密缓冲区大小,为 16 的整数倍。
返回
成功返回 SS_OK,失败返回相应的错误码
备注
由于硬件锁最大传输字节数有限,因此加解密时一次传入的字节不得超过 1520个字节,若需要加解密的字节数大于此最大限制, 可采用截取数据流,循环调用的方式进行加解密,加解密结果不会受到任何影响。
{
SS_UINT32 status = SS_OK;
SS_BYTE plain[32] = { 0 }; // 加解密使用AES对称加密,明文数据必须16字节对齐
SS_BYTE enc[32] = { 0 };
SS_BYTE dec[32] = { 0 };
memcpy(data, "test data...", strlen("test data..."));
status = slm_encrypt(slm_handle, plain, enc, sizeof(enc));
if(status != SS_OK)
{
// todo: deal error code
return ;
}
status = slm_decrypt(slm_handle, enc, dec, sizeof(dec));
if(status != SS_OK)
{
// todo: deal error code
return ;
}
//对比解密后的数据是否和明文相等
//if(plain == dec)
//{
// SUCCESS;
//}
//else
//{
// FAILURE;
//}
}
参见
slm_encrypt slm_decrypt slm_login
SS_UINT32 SSAPI slm_enum_device ( OUT char **  device_info)

枚举本地锁信息

参数
[out]device_info设备描述信息,不再使用时,需调用 slm_free 释放
返回
成功返回 SS_OK ,失败返回相应错误码
备注
此接口可以枚举到本地锁的设备信息,此处的设备信息内容可参考 slm_get_info LOCK_INFO 中的结构内容
// 参考 slm_get_license_info 的示例代码
参见
slm_enum_device slm_enum_license_id slm_get_license_info
SS_UINT32 SSAPI slm_enum_device_ex ( IN INFO_FORMAT_TYPE  format,
OUT void **  device_info 
)

枚举本地锁信息,支持按返回值类型获取

参数
[in]format信息格式,参考 INFO_FORMAT_TYPE ,当前仅支持 JSONSTRUCT
[out]device_info设备描述信息,不再使用时,需调用 slm_free 释放
返回
成功返回 SS_OK ,失败返回相应错误码
备注
此接口可以枚举到本地锁的设备信息,此处的设备信息内容可参考 slm_get_info LOCK_INFO 中的结构内容
// format = JSON
device_info 内容和 slm_enum_device 返回内容一致, 参考 slm_get_license_info 的示例代码
// format = STRUCT
device_info 内容参考 ST_DEV_INFO_LIST,参考 slm_get_license_info_ex 示例代码
参见
slm_enum_device slm_enum_license_id slm_get_license_info
SS_UINT32 SSAPI slm_enum_license_id ( IN const char *  device_info,
OUT char **  license_ids 
)

枚举指定设备下所有许可ID

参数
[in]device_info指定某个锁登陆
[out]license_ids返回所有许可的ID数组,::JSON 格式,需要调用 slm_free 释放 license_ids
返回
成功返回 SS_OK ,失败返回相应错误码
备注
slm_enum_device 获取到当前设备信息,通过设备信息获取许可信息,主要实现不用登录许可,便可查看许可内容的功能
// 参考 slm_get_license_info 示例代码
参见
slm_enum_device slm_enum_license_id slm_get_license_info
SS_UINT32 SSAPI slm_enum_license_id_ex ( IN ST_DEV_INFO device_info,
IN INFO_FORMAT_TYPE  format,
OUT void **  license_ids 
)

枚举指定设备下所有许可ID,支持按返回值类型获取

参数
[in]device_info指定某个锁信息
[in]format信息格式,参考 INFO_FORMAT_TYPE ,当前仅支持 JSONSTRUCT
[out]license_ids返回所有许可的ID数组,JSON格式,需要调用 slm_free 释放 license_ids
返回
成功返回SS_OK,失败返回相应错误码
备注
slm_enum_device 获取到当前设备信息,通过设备信息获取许可信息,主要实现不用登录许可,便可查看许可内容的功能
// 参考 slm_get_license_info_ex 示例代码
参见
slm_enum_device slm_enum_license_id slm_get_license_info
const SS_CHAR* SSAPI slm_error_format ( IN SS_UINT32  error_code,
IN SS_UINT32  language_id 
)

通过错误码获得错误信息

参数
[in]error_code通过各 API 调用失败后返回的错误码值
[in]language_id要返回字符串的语言,见 LANGUAGE_CHINESE_ASCII
返回
成功返回错误码文本描述信息(不需要调用 slm_free 释放),失败返回空指针 NULL
备注
特别注意:错误码文本描述信息,不需要调用 slm_free 释放
SS_UINT32 SSAPI slm_execute_dynamic ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  exf_buffer,
IN SS_UINT32  exf_size,
IN SS_BYTE *  inbuf,
IN SS_UINT32  insize,
OUT SS_BYTE *  poutbuf,
IN SS_UINT32  outsize,
OUT SS_UINT32 *  pretsize 
)

开发者自定义算法,锁内可执行算法,锁内动态执行代码(仅支持硬件锁),在应用程序运行过程中下载到锁内进行执行

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]exf_buffer动态exf 算法缓冲区,由开发者调用 D2CAPI 库中的 gen_dynamic_code 接口生成的 D2C数据
[in]exf_size动态exf 文件大小
[in]inbuf要传给锁内可执行算法的数据,输入缓冲区
[in]insize输入数据长度(最大支持缓冲区大小参考宏: SLM_MAX_INPUT_SIZE )
[out]poutbuf锁内可执行算法的返回数据,输出缓存区
[in]outsize输出缓存长度
[out]pretsize实际返回缓存长度(最大支持缓冲区大小参考宏: SLM_MAX_OUTPUT_SIZE )
返回
成功返回 SS_OK,失败返回相应的错误码
备注
区别于 slm_execute_static 锁内静态代码执行。锁内静态代码执行,是在初始化硬件锁时,通过签发文件将可执行代码下载到锁内,代码永久保存在锁内。 而 slm_execute_dynamic 锁内动态代码执行,是提前通过 D2CAPI 签好可执行代码包,随应用程序一起,当需要执行时下载到锁内,执行完成后锁内会删除此程序,不在锁内长时间保留。
{
SS_BYTE exf_buff[MAX_BUFFER_SIZE] = { 0 }; // 动态代码升级包缓冲区
SS_UINT32 exf_size = 0; // 动态代码升级包大小
SS_BYTE inbuff[MAX_BUFFER_SIZE] = { 0 };
SS_BYTE outbuff[MAX_BUFFER_SIZE] = { 0 };
SS_UINT32 retlen = 0;
SS_UINT32 status = 0;
// 1、给动态代码缓冲区赋值。
// {...}
memcpy(inbuff, "1234567890", 10);
status = slm_execute_static(slm_handle, exf_buff, exf_size, inbuff, 10, outbuff, MAX_BUFFER_SIZE, &retlen);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
// todo: 处理锁内程序的返回数据
}
参见
slm_login slm_execute_static slm_snippet_execute
SS_UINT32 SSAPI slm_execute_static ( IN SLM_HANDLE_INDEX  slm_handle,
IN const char *  exfname,
IN SS_BYTE *  inbuf,
IN SS_UINT32  insize,
OUT SS_BYTE *  poutbuf,
IN SS_UINT32  outsize,
OUT SS_UINT32 *  pretsize 
)

开发者自定义算法,锁内可执行算法,锁内静态代码执行(仅支持硬件锁), 由开发者调用 D2CAPI 库中的 d2c_add_pkg 签发可执行代码接口生成,提前将可执行算法下载到锁内

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]exfname锁内可执行算法的文件名
[in]inbuf要传给锁内可执行算法的数据,输入缓冲区
[in]insize输入数据长度(最大支持缓冲区大小参考宏: SLM_MAX_INPUT_SIZE )
[out]poutbuf锁内可执行算法的返回数据,输出缓存区
[in]outsize输出缓存长度
[out]pretsize实际返回缓存长度(最大支持缓冲区大小参考宏: SLM_MAX_OUTPUT_SIZE )
返回
成功返回 SS_OK,失败返回相应的错误码
备注
软件开发商可以从 APP 软件端移植关键代码到锁内,这个过程跟传统 精锐4 与 精锐5 没有太大的区别。(移植代码相关理念对于精锐系列的老客户可以跳过,开发商可以把真正的行业代码或者加密算法移植,并且在锁内执行)。 区别在于需要跟许可绑定。

许可绑定的好处:

  1. 客户不需要自己写代码来判断授权情况。
  2. 移植的代码可以结合灵活的许可授权,透明的使用限时或限次失效,管理及其方便。
  3. 当许可失效之后,该算法不可执行,并且整个过程都在锁内判断,非常安全。
{
SS_BYTE inbuff[MAX_BUFFER_SIZE] = { 0 };
SS_BYTE outbuff[MAX_BUFFER_SIZE] = { 0 };
char *dongle_exe = "dongle.evx" // 锁内可执行程序文件名
SS_UINT32 retlen = 0;
SS_UINT32 status = 0;
memcpy(inbuff, "1234567890", 10);
status = slm_execute_static(slm_handle, dongle_exe, inbuff, 10, outbuff, MAX_BUFFER_SIZE, &retlen);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
// todo: 处理锁内程序的返回数据
}
参见
slm_login slm_execute_dynamic slm_snippet_execute
SS_UINT32 SSAPI slm_extensions_config ( IN const char *  config)

扩展配置接口

参数
[in]config配置参数( JSON
  1. slm_login 扩展参数,指定许可登录云锁、软锁服务地址,注意服务地址 URL 长度不得超过 SLM_MAX_CLOUD_SERVER_LENGTH 宏定义长度。 {"api_slm_login":{"cloud_runtime_url":"http://rt.senseyun.com", "slock_url":"http://sl.senseyun.com"}}
返回
成功返回 SS_OK ,失败返回相应错误码
备注
不支持多线程调用,非线程安全,请保证配置在相关功能运行之前执行。
SS_UINT32 SSAPI slm_find_license ( IN SS_UINT32  license_id,
IN INFO_FORMAT_TYPE  format,
OUT char **  license_desc 
)

查找许可信息(仅对硬件锁有效)

参数
[in]license_id要查找的许可ID(0–0xFFFFFFFF)
[in]format参数格式,参考 INFO_FORMAT_TYPE ,目前仅支持 JSONSTRUCT
[out]license_desc许可描述信息的指针,格式由 format 指定,需调用 slm_free 释放
返回
成功返回 SS_OK,失败返回相应的错误码
备注
此函数用于查找本地锁和网络锁的许可信息,如果成功,需要调用 slm_free 释放 license_desc。 当 format = STRUCT 时 license_desc 的内容 参考 ST_DEV_INFO_LIST
参见
INFO_FORMAT_TYPE
void SSAPI slm_free ( IN void *  buffer)

释放API内分配堆区域

参数
[in]bufferAPI 生成的堆
SS_UINT32 SSAPI slm_get_cert ( IN SLM_HANDLE_INDEX  slm_handle,
IN CERT_TYPE  cert_type,
OUT SS_BYTE *  cert,
IN SS_UINT32  cert_size,
OUT SS_UINT32 *  cert_len 
)

通过证书类型,获取已登录许可的设备证书

参数
[in]slm_handle许可句柄,由 slm_login 得到
[in]cert_type证书类型,参考 CERT_TYPE
[out]cert证书缓冲区
[in]cert_size缓冲区大小
[out]cert_len返回的设备证书大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
获取设备证书,此处的设备指硬件锁、云锁。 如果 cert_type = #CERT_TYPE_DEVICE_CERT,其功能与 slm_get_device_cert 完全一致; 如果为其他类型,则仅支持硬件锁。 通过此接口可以获取加密锁的根证书、设备子CA 和设备,方便合成设备证书链。
参见
slm_login slm_get_device_cert
SS_UINT32 SSAPI slm_get_cloud_token ( OUT SS_CHAR **  access_token)

枚举已登录的用户 token

参数
[out]access_token默认用户的 token,需调用 slm_free 释放
返回
成功返回 SS_OK,如果 oauth 后台进程未启动,则返回 SS_ERROR_BAD_CONNECT
备注
如果成功,需要调用 slm_free 释放 access_token
SS_UINT32 SSAPI slm_get_developer_id ( OUT SS_BYTE  developer_id[SLM_DEVELOPER_ID_SIZE])

获取 Runtime 库对应的开发商ID

参数
[out]developer_id输出开发商ID,二进制数组
返回
成功返回 SS_OK ,失败返回相应错误码
备注
如果 developer_id 的缓冲区小于 SLM_DEVELOPER_ID_SIZE ,则势必会造成淹栈的情况
SS_UINT32 SSAPI slm_get_device_cert ( IN SLM_HANDLE_INDEX  slm_handle,
OUT SS_BYTE *  device_cert,
IN SS_UINT32  buff_size,
OUT SS_UINT32 *  return_size 
)

获取已登录的加密锁证书

参数
[in]slm_handle许可句柄,由 slm_login 得到
[out]device_cert设备证书缓冲区
[in]buff_size缓冲区大小
[out]return_size返回的设备证书大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
获取已登录的加密锁证书,此处的加密锁指硬件锁、云锁、软锁
参见
slm_login
SS_UINT32 SSAPI slm_get_info ( IN SLM_HANDLE_INDEX  slm_handle,
IN INFO_TYPE  type,
IN INFO_FORMAT_TYPE  format,
OUT char **  result 
)

获取已登录许可的状态信息,例如许可信息、硬件锁信息等

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]type信息类型,参考 INFO_TYPE
[in]format信息格式,参考 INFO_FORMAT_TYPE ,当前仅支持 JSONSTRUCT
[out]result返回结果,如果函数返回成功,需要调用slm_free释放
返回
成功返回 SS_OK,失败返回相应的错误码
备注
通过调用此接口,可以获取当前登录许可的:许可信息、会话信息、硬件锁信息(仅支持硬件锁)、锁内文件列表(仅支持硬件锁)
// JSON 参数说明:
- type = LICENSE_INFO (如果字段不存在,则表示没有该许可限制)
{
"rom_size" :number(云锁不支持)
"raw_size" :number(云锁不支持)
"pub_size" :number(云锁不支持)
"type": "local"/"remote"/"cloud"
"sn":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"guid":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
"developer_id": "xxxxxxxxxxxxxxxx"
"license_id": number
"enable": bool
"start_time": number
"end_time": number
"first_use_time": number
"span_time": number
"counter": number
"concurrent_type": "process" / "win_user_session" // 并发类型
"concurrent": number //并发数
"version": number
"module":number
"last_update_timestamp": number
"last_update_timesn": number
"lock_time": number // 许可被锁定的时间,正常许可不含此字段
}
- type = SESSION_INFO
{
"app_process_id": number,
"app_time_out": number,
"session_id": (只支持云锁)
"bios": "BIOS information", (云锁不支持)
"cpuinfo": "CPU name", (云锁不支持)
"sn": ""(HEX16 String), (只支持硬件锁)
"user_guid": ""(HEX16 String) (只支持软锁)
"mac":"00-00-00-00-00-00" (云锁不支持)
}
- type = LOCK_INFO (云锁不支持)
{
"avaliable_space": number(Bytes),
"communication_protocol": number,
"lock_firmware_version": "0.0.0.0",
"lm_firmware_version": "1.1.1.1",
"h5_device_type": number,
"hardware_version": "2.2.2.2",
"manufacture_date": "2000-01-01 00:00:00",
"lock_sn": ""(HEX16 String),
"slave_addr": number,
"clock": number(UTC Time),
"user_info": ""(HEX16 String)(128字节)
"inner_info": ""(HEX16 String)(128字节)
}
- type = FILE_LIST
[
{
"validate":0, (标志哪些域有效,不必关心)
"type":0, (文件类型。二进制文件=0;可执行文件(evx)=1;密钥文件=2)
"privilege":0, (文件访问权限,最大权限为 0xFF)
"size":123, (文件大小,单位:字节)
"time":12345678, (文件创建时间,UTC时间秒)
"name":"file1.evx" (文件名称)
},
{...}
]
// STRUCT 参数说明
- type = LICENSE_INFO
result 参考结构 ST_SLM_LICENSE_INFO
- type = SESSION_INFO
result 参考结构 ST_SESSION_INFO
- type = LOCK_INFO
result 参考结构 ST_LOCK_INFO
- type = FILE_LIST
result 参考结构 ST_FILE_INFO_LIST
参见
INFO_TYPE INFO_FORMAT_TYPE SLM_HANDLE_INDEX slm_login
SS_UINT32 SSAPI slm_get_license_info ( IN const char *  device_info,
IN SS_UINT32  license_id,
OUT char **  license_info 
)

获取指定设备下指定许可的全部信息

参数
[in]device_info指定某个锁登陆
[in]license_id指定许可ID
[out]license_info返回许可的信息 JSON 格式 等同于 slm_get_infoLICENSE_INFO
返回
成功返回 SS_OK ,失败返回相应错误码
备注
获取到指定设备的 许可ID 列表,方便统计锁内许可总数
{
char *lic_id = NULL;
char *dev_desc = NULL;
char *lic_info = NULL;
SS_UINT32 status = SS_OK;
Json::Reader reader; // 此处选择jsoncpp处理json数据
Json::Value root;
Json::Value lic;
status = slm_enum_device(&dev_desc); // 首先要先遍历所有设备
if ( status == SS_OK && dev_desc != NULL && reader.parse(dev_desc, root))
{
for (int i = 0; i < root.size(); i++)
{
status = slm_enum_license_id(root[i].toStyledString().c_str(), &lic_id); // 其次获取每个设备的许可ID
if (status == SS_OK && lic_id != NULL)
{
printf(lic_id);
printf("\n");
if (reader.parse(lic_id, lic))
{
for (int j = 0; j < lic.size(); j++)
{
status = slm_get_license_info(root[i].toStyledString().c_str(), lic[j].asInt(), &lic_info); // 最后获取许可的详细信息
if (lic_info)
{
printf(lic_info);
printf("\n");
slm_free(lic_info);
lic_info = NULL;
}
}
}
slm_free(lic_id);
lic_id = NULL;
}
}
slm_free(dev_desc);
dev_desc = NULL;
}
}
参见
slm_enum_device slm_enum_license_id slm_get_license_info
SS_UINT32 SSAPI slm_get_license_info_ex ( IN ST_DEV_INFO device_info,
IN SS_UINT32  license_id,
IN INFO_FORMAT_TYPE  format,
OUT void **  license_info 
)

获取指定设备下指定许可的全部信息,支持按返回值类型获取

参数
[in]device_info指定某个锁登陆
[in]format信息格式,参考 INFO_FORMAT_TYPE ,当前仅支持 JSONSTRUCT
[in]license_id指定许可ID
[out]license_info返回许可的信息 JSON 格式 等同于 slm_get_infoLICENSE_INFO
返回
成功返回 SS_OK,失败返回相应错误码
备注
获取到指定设备的许可ID列表,方便统计锁内许可总数
{
void *dev_desc = NULL;
SS_UINT32 dev_count = 0;
void *lic_desc = NULL;
void *lic_info = NULL;
int status = SS_OK;
status = slm_enum_device_ex(STRUCT, &dev_desc);
if (status == SS_OK && dev_desc != NULL)
{
//printf("DEV LIST COUNT:%d\n", dl->count);
for (int i = 0; i != dl->count; ++i)
{
status = slm_enum_license_id_ex(&dl->info[i].dev_info, STRUCT, &lic_desc);
if (status == SS_OK && lic_desc != NULL)
{
ST_LICENSE_IDS *lic = (ST_LICENSE_IDS*)lic_desc;
//printf("License Count : %d\n", lic->count);
for (int j = 0; j != lic->count; ++j)
{
status = slm_get_license_info_ex(&dl->info[i].dev_info, lic->lic_ids[j], STRUCT, &lic_info);
if (status == SS_OK && lic_info != NULL)
{
//printf("LicenseID = %d; first use time = %d\n", ((ST_SLM_LICENSE_INFO*)lic_info)->lic_id, ((ST_SLM_LICENSE_INFO*)lic_info)->first_use_time);
slm_free(lic_info);
lic_info = NULL;
}
}
slm_free(lic_desc);
lic_desc = NULL;
}
}
slm_free(dev_desc);
dev_desc = NULL;
}
}
参见
slm_enum_device slm_enum_license_id slm_get_license_info
SS_UINT32 SSAPI slm_get_version ( OUT SS_UINT32 *  api_version,
OUT SS_UINT32 *  ss_version 
)

获得 Runtime 库 和 Virbox许可服务 的版本信息.

参数
[out]api_versionAPI的版本(总是成功)
[out]ss_versionVirbox许可服务 的版本
返回
成功返回 SS_OK ,失败则返回相应的错误码
SS_UINT32 SSAPI slm_init ( IN ST_INIT_PARAM pst_init)

Runtime API 初始化函数,调用所有 Runtime API 必须先调用此函数进行初始化

参数
[in]pst_init初始化参数,见 ST_INIT_PARAM 结构声明
返回
成功返回SS_OK,失败返回相应的错误码
备注
slm_init 函数是 Virbox Runtime API 的初始化函数,在使用其他 Virbox Runtime API 之前,必须要先调用此函数, 初始化函数主要是对 Runtime 环境的初始化,并且启动反调试机制。
参见
ST_INIT_PARAM slm_cleanup
SS_UINT32 SSAPI slm_is_debug ( IN void *  auth)

检测是否正在调试

参数
[in]auth验证数据(保留参数,填 NULL 即可)
返回
SS_UINT32 错误码, 返回 SS_OK 代表未调试
备注
必须调用 slm_init 之后才可使用,否则有可能会造成程序崩溃
参见
slm_init
SS_UINT32 SSAPI slm_keep_alive ( SLM_HANDLE_INDEX  slm_handle)

保持登录会话心跳,避免变为“僵尸句柄”。

参数
[in]slm_handle许可句柄值
返回
成功返回 SS_OK,失败返回相应的错误码
备注
僵尸句柄:如果进程死循环或者崩溃,slm_handle 不会自动被释放,造成 Runtime 库中内存和资源浪费
DWORD WINAPI __stdcall _ThreadKeepalive(void *pVoid)
{
SLM_HANDLE_INDEX slm_handle = *(SLM_HANDLE_INDEX *)(pVoid);
SS_UINT32 status = SS_OK;
while (1)
{
status = slm_keep_alive(slm_handle);
if(status != SS_OK)
{
//todo do: deal error code
}
Sleep(1000 * 10); // 十秒钟进行一次心跳连接,保证会话的有效性
}
}
{
SS_UINT32 status = SS_OK;
SLM_HANDLE_INDEX slm_handle = 0;
ST_LOGIN_PARAM login_param = { 0 };
HANDLE hThread;
DWORD id = 0;
login_param.license_id = 0;
login_param.size = sizeof(ST_LOGIN_PARAM);
login_param.login_mode = SLM_LOGIN_MODE_LOCAL;
login_param.time_out = 30; // 设置会话为30秒超时
status = slm_login(&login_param, STRUCT, &slm_handle, NULL);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
hThread = CreateThread(NULL, 0, _ThreadKeepalive, &slm_handle, 0, &id);
if (hThread == NULL)
{
//todo: deal error
}
}
参见
slm_login
SS_UINT32 SSAPI slm_led_control ( IN SLM_HANDLE_INDEX  slm_handle,
IN ST_LED_CONTROL led_ctrl 
)

闪烁指示灯

参数
[in]slm_handle许可句柄,由 slm_login 得到
[in]led_ctrl闪灯控制结构( ST_LED_CONTROL )
返回
成功返回 SS_OK ,失败返回相应的错误码
备注
{
ST_LED_CONTROL led = { 0 };
SS_UINT32 status = SS_OK;
led.index = 0; // 0表示蓝色LED,1表示红色LED
led.state = 2; // 0代表关闭,1代表打开, 2代表闪烁
led.interval = 1000; // 闪烁间隔(毫秒)
status = slm_led_control(slm_handle, &led);
if(status != SS_OK)
{
// todo: deal error code
}
}
参见
slm_login ST_LED_CONTROL
SS_UINT32 SSAPI slm_license_sign ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  sign_data,
IN SS_UINT32  sign_length,
OUT SS_BYTE *  signature,
IN SS_UINT32  max_buf_size,
OUT SS_UINT32 *  signature_length 
)

使用已登录的云许可进行签名(仅支持云锁)

参数
[in]slm_handle许可句柄,由 slm_login 得到
[in]sign_data要签名的数据(最少16字节,最大64字节)
[in]sign_length要签名的数据长度
[out]signature签名结果缓冲区
[in]max_buf_size签名结果缓冲区大小
[out]signature_length签名结果实际长度
返回
成功返回 SS_OK ,失败返回错误码
备注
不同开发者、不同许可的签名结果是不一样的。
参见
slm_license_verify
SS_UINT32 SSAPI slm_license_verify ( IN SS_BYTE *  sign_data,
IN SS_UINT32  sign_length,
IN SS_BYTE *  signature,
IN SS_UINT32  signature_length,
OUT char **  sign_info 
)

对云许可签名后的数据进行验签(仅支持云锁)

参数
[in]sign_data要签名的数据(最少 16字节,最大 64字节)
[in]sign_length要签名的数据长度
[in]signature签名结果数据
[in]signature_length签名结果长度
[out]sign_info签名数据信息,json结构,不再使用时,需要调用 slm_free 释放
返回
验签成功返回 SS_OK ,失败返回错误码
备注
-如果成功,需要调用 slm_free 释放 sign_info -验签过程可以不登录许可
//json参数
{
"type":2, // 2表示云锁
"developer_id":0000000000000000, // 开发商ID
"license_id":0, // 许可ID
"guid":xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, // 用户guid(由类型决定)
"sn":00000000000000000000000000000000, // 锁号(由类型决定)
"rand":0, // 随机数
}
参见
slm_license_sign slm_free
SS_UINT32 SSAPI slm_login ( IN const ST_LOGIN_PARAM license_param,
IN INFO_FORMAT_TYPE  param_format,
OUT SLM_HANDLE_INDEX slm_handle,
IN OUT void *  auth 
)

安全登录许可,用 JSON 传递参数,并且检查时间(是否到期或者是否早于开始时间)、次数、并发数是否归零, 如果有计数器,则永久性减少对应的计数器,对于网络锁则临时增加网络并发计数器。

参数
[in]license_param登录许可描述参数,可以用来描述 licenseid,或者指定登录特性等。
[in]param_format许可描述字符串类型,仅支持 #STRUCT(为确保安全,SDK版本号2.1.0.15128之后的许可登录将不再支持 json 登录的方法)
[out]slm_handle返回登录之后许可句柄index值,范围在 0-256 之间。
[out]auth认证 login 函数返回是否正确,含有 ECC签名 和返回值加密,不使用可以填 NULL。
返回
成功返回 SS_OK,失败返回相应的错误码
备注
  • slm_login 函数详细说明:
    1. 会自动查找跨锁查找许可句柄。
    2. 在 Runtime 库里面分配管理内存与进程线程信息。
    3. 对与调用者需要定期监控会话进程,如果进程死锁或者崩溃,自己释放对应的内存和其它资源。
    4. LM库属于客户定制自动编译,包含 RSA公钥、认证设备ID、开发商编号等一切认证手段。
    5. LM后续操作必须都要 login 之后才能有权限操作 比如读写、加解密等操作。
  • 功能参数说明:
    • 采用结构体:
    1. 参考 ST_LOGIN_PARAM 结构详细描述
    2. ST_LOGIN_PARAM::size 参数结构体大小,必填项,必须为传入结构体的大小,否则会返回错误 SS_ERROR_RUNTIME_VERSION
    3. ST_LOGIN_PARAM::license_id 许可ID,为32位长整数,取值范围 0-4294967295,必写参数
    4. ST_LOGIN_PARAM::login_mode 许可登录模式,分为自动模式,以及本地锁、网络锁、云锁、软锁等组合
    5. ST_LOGIN_PARAM::sn 指定登录锁号 为二进制硬件锁芯片号(16字节)。
    6. ST_LOGIN_PARAM::access_token 如果登录云锁,则需要指定通过 oauth 认证的 access token
    7. ST_LOGIN_PARAM::timeout 指定登录会话超时 单位为秒。如果不填写,默认为600秒,硬件锁、软锁许可默认最小不低于 60s,最大不得超过 12小时(12 * 60 * 60 秒)。
    8. ST_LOGIN_PARAM::user_guid 登录用户的 guid,最大长度为 #SLM_CLOUD_MAX_USER_GUID_SIZE。一般不使用 guid
      {
      SS_UINT32 status = SS_OK;
      ST_INIT_PARAM init_param = { SLM_CALLBACK_VERSION02, 0, 0, 20000 };
      SLM_HANDLE_INDEX slm_handle = 0;
      ST_LOGIN_PARAM login_param = { 0 };
      // psd是必传参数,每个开发者私有,不可泄露,请从 VirboxLM 云开发者中心获取:https://developer.lm.virbox.com
      const char psd[] = { 0xDB, 0x3B, 0x83, 0x8B, 0x2E, 0x4F, 0x08, 0xF5, 0xC9, 0xEF, 0xCD, 0x1A, 0x5D, 0xD1, 0x63, 0x41};
      memcpy(init_param.password, psd, sizeof(init_param.password));
      status = slm_init(&init_param);
      if(status != SS_OK)
      {
      return ;
      }
      login_param.license_id = 0;
      login_param.size = sizeof(ST_LOGIN_PARAM); // 结构体长度必须赋值为正确的长度,否则会出错
      login_param.login_mode = SLM_LOGIN_MODE_LOCAL;
      status = slm_login(&login_param, STRUCT, &slm_handle, NULL);
      if(status != SS_OK)
      {
      //todo do: deal error code
      return ;
      }
      slm_logout(slm_handle);
      }
参见
slm_logout SS_UINT32 INFO_FORMAT_TYPE ST_LOGIN_PARAM
SS_UINT32 SSAPI slm_logout ( SLM_HANDLE_INDEX  slm_handle)

许可登出,并且释放许可句柄等资源

参数
[in]slm_handle许可句柄值,由 slm_login 得到
返回
成功返回 SS_OK,失败返回相应的错误码
备注
不再使用许可时,需要调用 slm_logout 退出登录许可,以免其占用 Runtime 库中的内存和资源。 例如,由于 Runtime 库只支持最多256个登录句柄,若只登录许可而不登出许可,一旦超出 256 个登录点将占满所有 Runtime 库中的资源,导致后续的登录失败
参见
slm_login
SS_UINT32 SSAPI slm_mem_alloc ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  size,
OUT SS_UINT32 *  mem_id 
)

Virbox许可服务 内存托管内存申请

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]size申请内存大小,最大 SLM_MEM_MAX_SIZE
[out]mem_id返回托管内存id
返回
成功返回 SS_OK,失败返回相应的错误码
备注
Virbox许可服务 的托管内存原理是 APP 利用有效的许可作为凭证,在 Virbox许可服务 模块内数据加密且数据校验,其内存二进制数据没有明文, 并且无法非法修改。黑客极难查看与篡改使用。

用户可以把自己 APP 的一些敏感数据保存到 Virbox许可服务 的托管内存,比如帐号口令,数据库的帐号与密码,涉及到操作权限的临时数据放到 Virbox许可服务 内存托管里面。 另外一方面 APP 跟 Virbox许可服务 耦合度极大的提高,防止黑客脱离 Virbox许可服务 调试与运行。

内存托管的好处:

  1. 敏感数据内存不泄密、无法篡改。
  2. 可以跨线程安全交互数据。
  3. APP软件、许可、Virbox许可服务 三者强耦合,软件防止被破解能力极高。(黑客需要手工剥离和重建才能使软件)
{
SS_UINT32 status = SS_OK;
SS_UINT32 mem_index = 0;
SS_UINT32 mem_size = 1024;
SS_BYTE data[] = "test data....";
SS_BYTE read[100] = { 0 };
SS_UINT32 write_len = 0;
SS_UINT32 read_len = 0;
status = slm_mem_alloc(slm_handle, mem_size, &mem_index);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
status = slm_mem_write(slm_handle, mem_index, 0, strlen((char *)data), data, &write_len);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
status = slm_mem_read(slm_handle, mem_index, 0, write_len, read, &read_len);
if(status != SS_OK)
{
//todo do: deal error code
return ;
}
//对比原始数据和读取到的数据是否相等
//if(data == read)
//{
// SUCCESS;
//}
//else
//{
// FAILURE;
//}
status = slm_mem_free(slm_handle, mem_index);
}
参见
slm_mem_free slm_mem_read slm_mem_write
SS_UINT32 SSAPI slm_mem_free ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  mem_id 
)

释放托管内存

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]mem_id托管内存id
返回
成功返回 SS_OK,失败返回相应的错误码
备注
//see slm_mem_alloc
参见
slm_mem_alloc slm_mem_free slm_mem_read slm_mem_write
SS_UINT32 SSAPI slm_mem_read ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  mem_id,
IN SS_UINT32  offset,
IN SS_UINT32  len,
IN SS_BYTE *  readbuff,
OUT SS_UINT32 *  readlen 
)

Virbox许可服务 内存托管读

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]mem_id托管内存id
[in]offset读取托管数据偏移
[in]len读取托管数据长度
[out]readbuff外部存储托管数据缓存
[out]readlen返回实际读取长度
返回
成功返回 SS_OK,失败返回相应的错误码
备注
//see slm_mem_alloc
参见
slm_mem_alloc slm_mem_free slm_mem_write
SS_UINT32 SSAPI slm_mem_write ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  mem_id,
IN SS_UINT32  offset,
IN SS_UINT32  len,
IN SS_BYTE *  writebuff,
OUT SS_UINT32 *  numberofbyteswritten 
)

Virbox许可服务 内存托管内存写入

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]mem_id托管内存id
[in]offset托管数据偏移
[in]len写入的托管数据长度
[in]writebuff需要写入托管内存区域的数据缓存
[out]numberofbyteswritten返回实际写的长度
返回
成功返回 SS_OK,失败则返回相应的错误码
备注
//see slm_mem_alloc
参见
slm_mem_alloc slm_mem_free slm_mem_read
SS_UINT32 SSAPI slm_pub_data_getsize ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  license_id,
OUT SS_UINT32 *  pmem_size 
)

获得指定许可的公开区数据区大小,需要登录 0号许可

参数
[in]slm_handle0号许可句柄值,其他许可句柄无法通过此方式得到公开区大小,由 slm_login 得到
[in]license_id要获取数据区大小的 许可ID
[out]pmem_size返回数据区大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
某些情况下,用户希望在不登录许可的情况下,获取到许可的公开区数据,例如许可已经不可用(许可到期、次数用尽等)。 此时用户可用通过调用此接口进行获取,前提是需要登录 0号许可,然后将 0号许可 句柄和要查询公开区的 许可ID 传入参数,获取该许可的公开区数据。 备注:有关 0号许可 的介绍,可参考《Virbox 许可体系与许可管理》文档中关于 0号许可 的描述
参见
slm_user_data_read_pub
SS_UINT32 SSAPI slm_pub_data_read ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_UINT32  license_id,
OUT SS_BYTE *  readbuf,
IN SS_UINT32  offset,
IN SS_UINT32  len 
)

读取许可公开区,需要登录 0号许可

参数
[in]slm_handle0号许可 句柄值,其他许可句柄无法通过此方式得到公开区内容,由 slm_login 得到
[in]license_id要获取数据区内容的 许可ID
[out]readbuf外部存储要读取数据区内容的缓冲区
[in]offset要读取数据区的数据偏移
[in]len外部存储缓冲区大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
某些情况下,用户希望在不登录许可的情况下,获取到许可的公开区数据,例如许可已经不可用(许可到期、次数用尽等)。 此时用户可用通过调用此接口进行获取,前提是需要登录 0号许可,然后将 0号许可 句柄和要查询公开区的 许可ID 传入参数,获取该许可的公开区数据。 备注:有关 0号许可 的介绍,可参考《Virbox 许可体系与许可管理》文档中关于 0号许可 的描述
{
SS_UINT32 size = 0;
SS_BYTE *buff = 0;
SS_UINT32 status = SS_OK;
SS_UINT32 license_id = 1; // 需要获取数据区的许可ID
// 此处需要登录零号许可,请参考 slm_login 的 code 示例
status = slm_pub_data_getsize(slm_handle, license_id, &size); // 获取指定许可的公开区内容
if (status == SS_OK && size > 0)
{
buff = (SS_BYTE *)calloc(sizeof(SS_BYTE), size);
status = slm_user_data_read(slm_handle, license_id, buff, 0, size);
if(status != SS_OK)
{
// todo: deal error code
}
// 可在此处理获取到的数据
free(buff);
buff = 0;
}
}
参见
slm_user_data_pub_getsize
SS_UINT32 SSAPI slm_sign_by_device ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  verify_data,
IN SS_UINT32  verify_data_size,
OUT SS_BYTE *  signature,
IN SS_UINT32  signature_buf_size,
OUT SS_UINT32 *  signature_size 
)

设备正版验证(仅支持硬件锁)

参数
[in]slm_handle许可句柄,由 slm_login 得到
[in]verify_data验证数据(必须以字符"SENSELOCK"(9字节)开头)
[in]verify_data_size验证数据大小,大小必须为 SLM_VERIFY_DATA_SIZE (41)个字节
[out]signature返回的签名结果
[in]signature_buf_size缓冲区大小
[out]signature_size签名结果大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
锁内使用设备私钥签名,需要用硬件锁证书公钥验签
{
SS_UINT32 status = SS_OK;
SS_BYTE verify_data[41] = {0};
SS_BYTE my_data[32] = {"verify data..."};
const SS_BYTE header[9] = {"SENSELOCK"};
SS_BYTE signature[2048] = {0};
SS_UINT32 signature_size = 0;
memcpy(verify_data, header, sizeof(header));
memcpy(verify_data + sizeof(header), my_data, sizeof(my_data));
status = slm_sign_by_device(slm_handle, verify_data, sizeof(verify_data), signature, sizeof(signature), &signature_size);
if(status != SS_OK)
{
// todo: deal error code
}
}
参见
slm_login
SS_UINT32 SSAPI slm_snippet_execute ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  snippet_code,
IN SS_UINT32  code_size,
IN SS_BYTE *  input,
IN SS_UINT32  input_size,
OUT SS_BYTE *  output,
IN SS_UINT32  outbuf_size,
OUT SS_UINT32 *  output_size 
)

碎片代码执行(开发者不必关心)

参数
[in]slm_handle许可句柄
[in]snippet_code碎片代码
[in]code_size碎片代码大小
[in]input输入数据
[in]input_size输入数据长度
[out]output输出缓冲区
[in]outbuf_size输出缓冲区长度
[out]output_size输出数据长度
返回
成功返回SS_OK,失败返回相应的错误码
参见
slm_login slm_execute_static slm_execute_dynamic
SS_UINT32 SSAPI slm_update ( IN char *  d2c_pkg,
OUT char **  error_msg 
)

将D2C包进行升级,d2c包 由 D2CAPI 生成

参数
[in]d2c_pkgd2c文件数据
[out]error_msg错误信息,需要调用slm_free释放
返回
成功返回 SS_OK ,失败返回错误码
备注
: D2C包内可能包含多条数据,因此返回的错误码信息也是 json 数组结构,需要分别解析
[
{"pkg_order":1, "pkg_desc":"package decription.", "status": 0},
{"pkg_order":2, "pkg_desc":"package decription.", "status": 0}
]
SS_UINT32 SSAPI slm_update_ex ( IN SS_BYTE *  lock_sn,
IN char *  d2c_pkg,
OUT char **  error_msg 
)

将D2C包进行升级,需指定加密锁唯一序列号,d2c包 由 D2CAPI 生成

参数
[in]lock_sn锁号(唯一序列号,十六进制字符串)
[in]d2c_pkgd2c文件数据
[out]error_msg错误信息,不使用需要调用 slm_free 释放
返回
成功返回 SS_OK ,失败返回错误码
备注
: D2C包内可能包含多条数据,因此返回的错误码信息也是 json 数组结构,需要分别解析
[
{"pkg_order":1, "pkg_desc":"package decription.", "status": 0},
{"pkg_order":2, "pkg_desc":"package decription.", "status": 0}
]
参见
slm_update
SS_UINT32 SSAPI slm_user_data_getsize ( IN SLM_HANDLE_INDEX  slm_handle,
IN LIC_USER_DATA_TYPE  type,
OUT SS_UINT32 *  pmem_size 
)

获得许可的用户数据区大小

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]type用户数据区类型,类型定义见 LIC_USER_DATA_TYPE
[out]pmem_size返回用户数据区大小
返回
成功返回 SS_OK,失败返回相应的错误码
参见
LIC_USER_DATA_TYPE slm_user_data_getsize slm_user_data_read slm_user_data_write
SS_UINT32 SSAPI slm_user_data_read ( IN SLM_HANDLE_INDEX  slm_handle,
IN LIC_USER_DATA_TYPE  type,
OUT SS_BYTE *  readbuf,
IN SS_UINT32  offset,
IN SS_UINT32  len 
)

读许可数据,可以读取 #PUB、#RAW 和 ROM

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]type用户数据区类型,参考 LIC_USER_DATA_TYPE
[out]readbuf用户数据区读取缓存区
[in]offset读取的用户数据区的数据偏移
[in]len外部使用的存储缓存区大小
返回
成功返回 SS_OK,失败返回相应的错误码
备注
读数据区最大支持 64k 数据的读取。
{
SS_UINT32 size = 0;
SS_BYTE *buff = 0;
SS_UINT32 status = SS_OK;
status = slm_user_data_getsize(slm_handle, ROM, &size); // 获取只读区数据
if (status == SS_OK && size > 0)
{
buff = (SS_BYTE *)calloc(sizeof(SS_BYTE), size);
status = slm_user_data_read(slm_handle, ROM, buff, 0, size);
if(status != SS_OK)
{
// todo: deal error code
}
// 可在此处理获取到的只读区数据
free(buff);
buff = 0;
}
}
参见
LIC_USER_DATA_TYPE slm_user_data_getsize slm_user_data_read slm_user_data_write
SS_UINT32 SSAPI slm_user_data_write ( IN SLM_HANDLE_INDEX  slm_handle,
IN SS_BYTE *  writebuf,
IN SS_UINT32  offset,
IN SS_UINT32  len 
)

写许可的读写数据区 ,数据区操作之前请先确认锁内读写区的大小,可以使用 slm_user_data_getsize 获得

参数
[in]slm_handle许可句柄值,由 slm_login 得到
[in]writebuf要写入的数据内容存区
[in]offset加密锁内数据区的偏移,即锁内数据区的写入位置
[in]len要写入数据的长度(数据最大长度 = min(slm_user_data_getsize, SLM_MAX_WRITE_SIZE)
返回
成功返回 SS_OK,失败返回相应的错误码
备注
仅读写区可以通过应用程序写入数据,因此此接口不需要传入数据区类型,接口会直接将数据写入读写区。 数据区写入时,如果数据长度大于 SLM_MAX_WRITE_SIZE ,需要开发商自行进行分包写入。
{
SS_UINT32 size = 0;
SS_BYTE write[20] = { "write data" };
SS_UINT32 status = SS_OK;
SS_UINT32 offset = 0
status = slm_user_data_getsize(slm_handle, RAW, &size); // 仅读写区可写入数据
if (status == SS_OK && size > 0)
{
size = min( offset + sizeof(write), size); // 写入数据不得超过获取到的数据长度
status = slm_user_data_write(slm_handle, write, offset, size);
if(status != SS_OK)
{
// todo: deal error code
}
}
}
参见
LIC_USER_DATA_TYPE slm_user_data_getsize slm_user_data_read slm_user_data_write