PC / SC-Sharp GetReaders()引发InsufficientBuffer异常

时间:2018-07-03 05:52:42

标签: c# windows-server-2008-r2 pcsc thin-client

我正在使用从NuGet下载的PC/SC Sharp软件包,有一种方法GetReaders(),该方法返回连接到计算机的活动阅读器。

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);
    }
}

当我从本地计算机(Windows 10 Pro x64)调用它时,它可以正常工作并返回可用的读者名称。无论如何,当通过瘦客户端连接到Windows Server 2008 R2时,它会引发InsufficientBuffer异常

  

InsufficientBuffer:用于接收返回数据的数据缓冲区对于返回数据而言太小。

1 个答案:

答案 0 :(得分:0)

好吧,我找到了解决方案。我已经从其GitHub页面下载了PC / SC-Sharp的源代码并开始进行分析,问题出在方法SCardListReaders中,该方法的参数为pcchReaders,该参数太小并导致异常,来自MSDN:

  

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

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

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中提供的缓冲区长度,如果该参数非NULL则将返回的缓冲区长度写入pcchReaders中,并返回成功代码。 / p>

因此,它应该已经为dwReaders分配了正确的缓冲区大小,该大小将用于获取已连接的阅读器列表。很好,它在我的Windows 10专业版计算机上正常工作,直接连接了读取器,但是通过瘦客户端连接到Windows 2008 r2服务器,它返回的是相同的值(它是37),但是那个值导致了{{1 }}例外。

因此,我开始调整该值并手动进行设置(在Windows 2008 r2服务器中调试),我发现如果将该值设置为InsufficientBuffer(及更高),它将起作用。我不知道是什么原因引起的,48方法返回的参数值不足,但是我设法在第二次传递之前手动将该值加倍,因此看起来SCardListReaders的新版本像这样:

ListReaders()

因此,它现在可以正常工作,如果您有任何想法并且少了一些“ hacky”解决方案,也许我做错了什么,或者它应该通过瘦客户端工作的方式有所不同,并且它是一个错误之类的东西,请感到免费发表评论!