首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PC/Sharp()抛出InsufficientBuffer异常

PC/Sharp()抛出InsufficientBuffer异常
EN

Stack Overflow用户
提问于 2018-07-03 05:52:42
回答 1查看 718关注 0票数 2

我使用的是从PC/SC Sharp下载的NuGet包,有一种方法是GetReaders(),它返回连接到机器的活动读取器。

代码语言:javascript
复制
var contextFactory = ContextFactory.Instance;
using (var context = contextFactory.Establish(SCardScope.System)) {
    Console.WriteLine("Currently connected readers: ");
    var readerNames = context.GetReaders();
    foreach (var readerName in readerNames) {
        Console.WriteLine("\t" + readerName);
    }
}

当我从本地机器(Windows10Pro x64)调用它时,它工作正常,并返回可用的读取器名称。无论如何,当通过瘦客户机连接到Windows 2008 R2时,它会引发一个InsufficientBuffer异常

InsufficientBuffer:接收返回数据的数据缓冲区对于返回的数据来说太小了。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-04 10:17:02

我找到了解决办法。我从他们的GitHub页面下载了PC/SC-Sharp的源代码,并开始分析,问题是在具有参数pcchReadersSCardListReaders方法中,该参数很小,并导致异常,来自MSDN:

mszReaders缓冲区长度(以字符为单位)。此参数接收多字符串结构的实际长度,包括所有尾随空字符。如果缓冲区长度指定为SCARD_AUTOALLOCATE,则mszReaders被转换为指向字节指针的指针,并接收包含多字符串结构的内存块的地址。这个内存块必须用SCardFreeMemory来释放。

在pcsc的ListReaders方法(WinSCardAPI)中这样调用:

代码语言:javascript
复制
public SCardError ListReaders(IntPtr hContext, string[] groups, out string[] readers) {
    var dwReaders = 0;

    // initialize groups array
    byte[] mszGroups = null;
    if (groups != null)
    mszGroups = SCardHelper.ConvertToByteArray(groups, TextEncoding);

    // determine the needed buffer size
    var rc = SCardHelper.ToSCardError(
        SCardListReaders(hContext,
        mszGroups,
        null,
        ref dwReaders));

    if (rc != SCardError.Success) {
        readers = null;
        return rc;
    }

    // initialize array
    var mszReaders = new byte[dwReaders * sizeof(char)];


    rc = SCardHelper.ToSCardError(
        SCardListReaders(hContext,
        mszGroups,
        mszReaders,
        ref dwReaders));

    readers = (rc == SCardError.Success)
              ? SCardHelper.ConvertToStringArray(mszReaders, TextEncoding)
              : null;

    return rc;
}

第一次,它调用SCardListReaders方法来确定所需的缓冲区大小,并将mszReaders参数设置为null,因此根据MSDN:

多字符串,在提供的读取器组中列出读卡器。如果此值为NULL,则SCardListReaders将忽略pcchReaders中提供的缓冲区长度,将如果该参数不为空将返回的缓冲区长度写入pcchReaders,并返回成功代码

因此,它应该为dwReaders分配正确的缓冲区大小,用于获取连接的读取器列表。它在我的Windows10Pro机器上正常工作,读取器直接连接,但是通过瘦客户机连接到Windows2008PRO服务器--它返回相同的值(是r2 ),但是这个值导致了InsufficientBuffer异常。

因此,我已经开始调整该值并手动设置(在Windows2008Web服务器中调试),我发现如果将该值设置为48 (以及更高的值),它就会工作。我不知道是什么原因导致SCardListReaders方法返回该参数的值不足,但在第二次传递之前,我已经手动将该值加倍,因此新版本的ListReaders()如下所示:

代码语言:javascript
复制
public SCardError ListReaders(IntPtr hContext, string[] groups, out string[] readers) {
    var dwReaders = 0;

    // initialize groups array
    byte[] mszGroups = null;
    if (groups != null)
    mszGroups = SCardHelper.ConvertToByteArray(groups, TextEncoding);            

    // determine the needed buffer size
    var rc = SCardHelper.ToSCardError(
        SCardListReaders(hContext,
        mszGroups,
        null,
        ref dwReaders));

    if (rc != SCardError.Success) {
        readers = null;
        return rc;
    }

    //doubling buffer size to work through thin clients
    dwReaders *= 2; // <------------------ New line

    // initialize array
    var mszReaders = new byte[dwReaders * sizeof(char)];

    rc = SCardHelper.ToSCardError(
        SCardListReaders(hContext,
        mszGroups,
        mszReaders,
        ref dwReaders));

    readers = (rc == SCardError.Success)
              ? SCardHelper.ConvertToStringArray(mszReaders, TextEncoding)
              : null;

    return rc;
}

所以,它现在正在工作,如果你有任何想法,少一点“黑客”解决方案,也许我做错了什么,或者它应该通过瘦客户端不同的工作方式,这是一个bug或什么,请随时评论!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51147469

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档