我正在使用从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:用于接收返回数据的数据缓冲区对于返回数据而言太小。
答案 0 :(得分:0)
好吧,我找到了解决方案。我已经从其GitHub页面下载了PC / SC-Sharp的源代码并开始进行分析,问题出在方法SCardListReaders中,该方法的参数为pcchReaders
,该参数太小并导致异常,来自MSDN:
在pcsc-sharp的mszReaders缓冲区的长度,以字符为单位。此参数接收多字符串结构的实际长度,包括所有结尾的空字符。如果将缓冲区长度指定为SCARD_AUTOALLOCATE,则mszReaders将转换为指向字节指针的指针,并接收包含多字符串结构的内存块的地址。必须使用SCardFreeMemory释放此内存块。
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”解决方案,也许我做错了什么,或者它应该通过瘦客户端工作的方式有所不同,并且它是一个错误之类的东西,请感到免费发表评论!