`
java-mans
  • 浏览: 11711159 次
文章分类
社区版块
存档分类
最新评论

《ASCE1885的信息安全》のWindows下智能卡应用程序的开发(二)

 
阅读更多

1SCardListReaders函数用来获取系统中在指定读卡器组集合中的读卡器名字列表(去掉重复的)。调用者提供一读卡器组列表,函数返回这些指定组里面的读卡器名字列表;无法标识的组名将被忽略。

LONG WINAPI SCardListReaders(

__in SCARDCONTEXT hContext, //SCardEstablishContext()建立的资源管理器上下文,

//不能为NULL

__in_opt LPCTSTR mszGroups, //读卡器组名,为NULL时表示列出系统中所有读卡器

__out LPTSTR mszReaders, //系统中指定读卡器组中的读卡器的名字,这是一个多重字符串

//各个名字之间用‘/0’分隔,最后一个名字后面是两个连续的‘/0

//当该参数为NULL时,函数在pcchReaders中返回实际所需长度

__inout LPDWORD pcchReaders //mszReaders的有效字符长度,包括所有的‘/0’。当该参数指定

//SCARD_AUTOALLOCATE时,mszReaders将被转为指向字节指针的

//指针,用于接收包含多重字符串的内存块地址,该内存块必须使用函数

//SCardFreeMemory来释放

);

返回值:成功时是SCARD_S_SUCCESS;当指定组中没有读卡器时,返回SCARD_E_NO_READERS_AVAILABLE;否则返回其他智能卡错误码。

下面是该函数的实例代码:

LPTSTR pmszReaders = NULL;

LPTSTR pReader;

LONG lReturn, lReturn2;

DWORD cch = SCARD_AUTOALLOCATE;

// Retrieve the list the readers.

// hSC was set by a previous call to SCardEstablishContext.

lReturn = SCardListReaders(hSC,

NULL,

(LPTSTR)&pmszReaders,

&cch );

switch( lReturn )

{

case SCARD_E_NO_READERS_AVAILABLE:

printf("Reader is not in groups./n");

// Take appropriate action.

// ...

break;

case SCARD_S_SUCCESS:

// Do something with the multi string of readers.

// Output the values.

// A double-null terminates the list of values.

pReader = pmszReaders;

while ( '/0' != *pReader )

{

// Display the value.

printf("Reader: %S/n", pReader );

// Advance to the next value.

pReader = pReader + wcslen((wchar_t *)pReader) + 1;

}

// Free the memory.

lReturn2 = SCardFreeMemory( hSC,

pmszReaders );

if ( SCARD_S_SUCCESS != lReturn2 )

printf("Failed SCardFreeMemory/n");

break;

default:

printf("Failed SCardListReaders/n");

// Take appropriate action.

// ...

break;

}

2SCardGetStatusChange函数阻塞程序的运行直到指定的智能卡的可用性发生改变。调用者以SCARD_READERSTAT数组的形式提供需要监控的读卡器列表,以及最长等待的时间(ms)。

LONG WINAPI SCardGetStatusChange(

__in SCARDCONTEXT hContext, //SCardEstablishContext()建立的资源管理器上下文

__in DWORD dwTimeout, //最长等待的毫秒数,0表示函数立即返回;INFINITE表示一直等待

__inout LPSCARD_READERSTATE rgReaderStates, //SCARD_READERSTATE结构数组,指定监控的

//读卡器,同时用于接收返回结果。为了接收新的智能卡到来的通知,需要将

//SCARD_READERSTATE结构中的szReader参数设为////?PnP?//Notification,其他成员

//设为0;注意:该结构数组中的每个结构的所有成员必须初始化为0后再根据需要设置

//其他值,否则,函数将在包含远程读卡器的情况下返回失败

__in DWORD cReaders //rgReaderStates结构中的元素个数

);

返回值:成功时:SCARD_S_SUCCESS;失败时:智能卡错误码。

3SCardLocateCards函数在参数rgReaderStates中指定的读卡器列表中查找由参数mszCards指定的智能卡,并立即返回结果:

LONG WINAPI SCardLocateCards(

__in SCARDCONTEXT hContext, //SCardEstablishContext()建立的资源管理器上下文

__in LPCTSTR mszCards, //包含要查找的智能卡的多重字符串

__inout LPSCARD_READERSTATE rgReaderStates, //SCARD_READERSTATE结构数组,作为输入参数

//时,指定在其中查找的读卡器列表;作为输出参数时,接收查找结果

__in DWORD cReaders //rgReaderStates结构中元素个数

);

返回值:成功时:SCARD_S_SUCCESS;失败时:智能卡错误码。

该函数和SCardGetStatusChange函数一起使用时特别有用,当调用SCardLocateCards函数找不到匹配的智能卡时,应用程序可以使用SCardGetStatusChange函数来等待智能卡可用性的改变。

实例代码如下:

// Copyright (c) Microsoft Corporation. All rights reserved.

#include <stdio.h>

#include <winscard.h>

#include <tchar.h>

#pragma comment(lib, "winscard.lib")

HRESULT __cdecl main()

{

HRESULT hr = S_OK;

LPTSTR szReaders, szRdr;

DWORD cchReaders = SCARD_AUTOALLOCATE;

DWORD dwI, dwRdrCount;

SCARD_READERSTATE rgscState[MAXIMUM_SMARTCARD_READERS];

TCHAR szCard[MAX_PATH];

SCARDCONTEXT hSC;

LONG lReturn;

// Establish the card to watch for.

// Multiple cards can be looked for, but

// this sample looks for only one card.

_tcscat_s ( szCard, MAX_PATH * sizeof(TCHAR), TEXT("GemSAFE"));

szCard[lstrlen(szCard) + 1] = 0; // Double trailing zero.

// Establish a context.

lReturn = SCardEstablishContext(SCARD_SCOPE_USER,

NULL,

NULL,

&hSC );

if ( SCARD_S_SUCCESS != lReturn )

{

printf("Failed SCardEstablishContext/n");

exit(1);

}

// Determine which readers are available.

lReturn = SCardListReaders(hSC,

NULL,

(LPTSTR)&szReaders,

&cchReaders );

if ( SCARD_S_SUCCESS != lReturn )

{

printf("Failed SCardListReaders/n");

exit(1);

}

// Place the readers into the state array.

szRdr = szReaders;

for ( dwI = 0; dwI < MAXIMUM_SMARTCARD_READERS; dwI++ )

{

if ( 0 == *szRdr )

break;

rgscState[dwI].szReader = szRdr;

rgscState[dwI].dwCurrentState = SCARD_STATE_UNAWARE;

szRdr += lstrlen(szRdr) + 1;

}

dwRdrCount = dwI;

// If any readers are available, proceed.

if ( 0 != dwRdrCount )

{

for (;;)

{

// Look for the card.

lReturn = SCardLocateCards(hSC,

szCard,

rgscState,

dwRdrCount );

if ( SCARD_S_SUCCESS != lReturn )

{

printf("Failed SCardLocateCards/n");

exit(1);

}

// Look through the array of readers.

for ( dwI=0; dwI < dwRdrCount; dwI++)

{

if ( 0 != ( SCARD_STATE_ATRMATCH &

rgscState[dwI].dwEventState))

{

_tprintf( TEXT("Card '%s' found in reader '%s'./n"),

szCard,

rgscState[dwI].szReader );

SCardFreeMemory( hSC,

szReaders );

return 0; // Context will be release automatically.

}

// Update the state.

rgscState[dwI].dwCurrentState = rgscState[dwI].dwEventState;

}

// Card not found yet; wait until there is a change.

lReturn = SCardGetStatusChange(hSC,

INFINITE, // infinite wait

rgscState,

dwRdrCount );

if ( SCARD_S_SUCCESS != lReturn )

{

printf("Failed SCardGetStatusChange/n");

exit(1);

}

} // for (;;)

}

else

printf("No readers available/n");

// Release the context.

lReturn = SCardReleaseContext(hSC);

if ( SCARD_S_SUCCESS != lReturn )

{

printf("Failed SCardReleaseContext/n");

exit(1);

}

SCardFreeMemory( hSC,

szReaders );

return hr;

}

4SCARD_READERSTATE结构用于智能卡跟踪函数中,定义如下:

typedef struct {

LPCTSTR szReader; //要监控的读卡器名字的指针,将该参数设为////?PnP?//Notification,其他参数均

//设为0,可用于通知新的读卡器的到来

LPVOID pvUserData; //智能卡子系统不使用该参数,该参数被应用程序使用

DWORD dwCurrentState; //被应用程序感知的读卡器当前的状态

DWORD dwEventState; //被智能卡资源管理器感知的读卡器当前状态

DWORD cbAtr; //返回的ATR的字节个数

BYTE rgbAtr[36]; //插入的智能卡的ATR(包含额外对齐的字节)

} SCARD_READERSTATE, *PSCARD_READERSTATE, *LPSCARD_READERSTATE;

参数dwCurrentState取值组合如下:

SCARD_STATE_UNAWARE---应用程序对当前状态一无所知,但想知道;使用该参数,状态转移监视服

务将立即返回;

SCARD_STATE_IGNORE---应用程序对这个读卡器不感兴趣,在监控期间不考虑该读卡器,设置该参数将

忽略其他位掩码;

SCARD_STATE_UNAVAILABLE---应用程序希望该读卡器当前不可用,设置该参数将忽略其他后续位掩码

SCARD_STATE_EMPTY---应用程序希望读卡器中没有智能卡,设置该参数将忽略其他后续位掩码;

SCARD_STATE_PRESENT---应用程序希望读卡器中有一个智能卡;

SCARD_STATE_ATRMATCH---应用程序希望读卡器中有一个匹配目标智能卡的智能卡

SCARD_STATE_EXCLUSIVE---应用程序希望读卡器中的智能卡不被共享

SCARD_STATE_INUSE---应用程序希望读卡器中的智能卡正被一个或多个应用程序使用,但使用共享连接

SCARD_STATE_MUTE---应用程序希望读卡器中有一个不响应的智能卡

参数dwEventState取值组合如下:

SCARD_STATE_IGNORE---该读卡器应该被忽略;

SCARD_STATE_CHANGED---该位被设置时,应用程序假设读卡器发生了明显的状态改变;

SCARD_STATE_UNKNOWN---给定的读卡器名字不被资源管理器识别;

SCARD_STATE_UNAVAILABLE---读卡器的实际状态是不可用的;

SCARD_STATE_EMPTY---读卡器中没有智能卡;

SCARD_STATE_PRESENT---读卡器中有一个智能卡;

SCARD_STATE_ATRMATCH---读卡器中有一个匹配目标智能卡的智能卡;

SCARD_STATE_EXCLUSIVE---读卡器中的智能卡不被共享;

SCARD_STATE_INUSE---读卡器中的智能卡正被一个或多个应用程序使用,但使用共享连接

SCARD_STATE_MUTE---读卡器中有一个不响应的智能卡

5SCardFreeMemory函数释放由资源管理器使用SCARD_AUTOALLOCATE分配的内存:

LONG WINAPI SCardFreeMemory(

__in SCARDCONTEXT hContext, //SCardEstablishContext()返回的资源管理器上下文

__in LPCVOID pvMem //要释放的内存块

);

返回值:成功时:SCARD_S_SUCCESS;失败时:智能卡错误代码。

代码片段:

lReturn = SCardFreeMemory(hSC,

pmszReaders );

if ( SCARD_S_SUCCESS != lReturn )

printf("Failed SCardFreeMemory/n");

分享到:
评论

相关推荐

    asce1885-blog:asce1885的博客

    asce1885-blogasce1885的博客

    PHASE II OF THE ASCE BENCHMARK STUDY ON SHM.rar_BENCHMARK ASCE_a

    PHASE II OF THE ASCE BENCHMARK STUDY ON SHM

    asce.zip_ASCE_list

    ASCE(American Society of ...通过研究这个项目,开发者可以学习到如何利用MFC高效地构建用户界面,尤其是如何利用List控件来展示和管理数据,这对于任何需要处理大量信息的Windows应用程序开发都具有很高的参考价值。

    《ASCE使用指南》

    ASCE为全球最大的土木工程信息知识的出版机构,每年出版超过5万页的出版物,包括专业和技术期刊、专业会议录、图书、实践手册、标准专论等。 ASCE期刊是土木工程学科的主要核心期刊,包括30种专业技术期刊,由专业...

    原版第三代benchmark代码.rar_ASCE-Benchmark_BENCHMARK ASCE_benchmark_dri

    此为ASCE的第三代基准模型代码,可供土木工程领域学者使用。

    ASCE Latex Guide

    ASCE LaTeX 指南主要介绍了土木工程学会(American Society of Civil Engineers,简称ASCE)期刊的LaTeX投稿流程和注意事项。由于ASCE期刊接受LaTeX格式的投稿,因此作者需要按照特定的模板和格式要求提交论文。本文...

    ASCE7-10-建筑物和其他结构最小设计荷载-中文版.pdf

    ### ASCE7-10《建筑物和其他结构最小设计荷载》关键知识点解析 #### 一、规范内容简介 美国土木工程师学会(American Society of Civil Engineers, ASCE)发布的ASCE7-10标准《建筑物和其他结构最小设计荷载》,...

    土木工程几个著名期刊ASCE和Science direct中输出格式

    EndNote软件提供了各种预设的样式模板,用户可以根据需要选择对应的期刊格式,如ASCE Journals或APA,将引用的文献信息导入后,EndNote会自动按照选定的样式格式化引用。用户还可以自定义样式,以满足特定期刊的特殊...

    ASCE全文数据库培训iGroup公司.ppt

    在功能上,ASCE Research Library提供了多种检索方式,用户可以按期刊、作者、主题进行检索,甚至进行二次检索以精确定位所需信息。例如,如果研究方向是“遥感技术在环境中的应用”,可以使用关键词如“遥感技术”...

    门户网站Web及应用服务器加速及负载均衡方案.docx

    第二层是应用服务器,负责处理后台程序;第三层是数据库,负责存放网站数据。 为了提高门户网站的性能和可扩展性,需要对网站的架构进行改造,包括使用专门的应用服务器提供应用程序服务和页面发布服务,使用专门的...

    ASCE-7-2005-美国荷载规范-(中文版)

    ASCE-7-2005美国荷载规范中文版知识点总结 ASCE-7-2005美国荷载规范中文版是美国 土木工程师协会(ASCE)发布的一份最小设计荷载规范。该规范涵盖了建筑和其他结构的设计荷载要求,旨在确保建筑和结构的安全和可靠...

    Android研发工程师高级进阶

    根据给定文件信息,本篇文档是关于Android研发工程师高级进阶技能的介绍,涉及了函数响应式编程、Android Support Annotations、RxJava、Android应用性能优化、Fragment使用、依赖注入、ASCE1885动态启发技术等技术...

    ASCE_7-10美国建筑荷载规范(中文版);.pdf

    ASCE 7-10美国建筑荷载规范(中文版) ASCE 7-10《建筑物和其他结构最小设计荷载》(Minimum Design Loads for Buildings and Other Structures)是由美国土木工程学会(ASCE)发布的一份重要的建筑荷载规范。该...

    ANSI ASCE CI 71-21 Identifying, Quantifying, and Proving Loss of

    ANSI ASCE CI 71-21 Identifying, Quantifying, and Proving Loss of Productivity.pdf

    matlab开发-VUKinect

    6. **ASEE AC 2012-4751.pdf** - 这可能是一篇学术论文或会议报告,详细描述了VUKinect项目在2012年美国土木工程师学会(ASCE)活动中的应用或成果。 7. **license.txt** - 包含项目的许可信息,规定了使用、修改和...

    IES_VisualFoundation_v10.00.0001.rar

    IES VisualFoundation是结构工程师和专业人员分析和设计复杂的席式基础和组合基础的强大应用程序。它是一个全面的套件,提供了各种先进和强大的工具,用于分析复杂的结构组件。这是一个有效的应用程序,为结构工程师...

    03NPE-ASCE00-EM4

    结构安全和结构动力学有许多领域,通常需要计算随机变量函数的前几个统计矩。 通常的近似是泰勒展开法。 这种方法需要计算导数。 为了避免导数的计算,已经提出了概率矩的点估计。 然而,准确度非常低,并且有时,...

    人工智能-机器学习-基于Benchmark模型的隔震省略相关参数和地震反应计算分析与研究.pdf

    【人工智能与机器学习在隔震技术中的应用】 隔震技术是一种有效的抗震策略,它通过在建筑结构底部设置...通过深入理解和应用这些技术,未来可以实现更加智能化的隔震系统设计,以更好地保护建筑物及其内部人员的安全。

Global site tag (gtag.js) - Google Analytics