我使用的是从PC/SC Sharp下载的NuGet包,有一种方法是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);
}
}当我从本地机器(Windows10Pro x64)调用它时,它工作正常,并返回可用的读取器名称。无论如何,当通过瘦客户机连接到Windows 2008 R2时,它会引发一个InsufficientBuffer异常
InsufficientBuffer:接收返回数据的数据缓冲区对于返回的数据来说太小了。
发布于 2018-07-04 10:17:02
我找到了解决办法。我从他们的GitHub页面下载了PC/SC-Sharp的源代码,并开始分析,问题是在具有参数pcchReaders的SCardListReaders方法中,该参数很小,并导致异常,来自MSDN:
mszReaders缓冲区长度(以字符为单位)。此参数接收多字符串结构的实际长度,包括所有尾随空字符。如果缓冲区长度指定为SCARD_AUTOALLOCATE,则mszReaders被转换为指向字节指针的指针,并接收包含多字符串结构的内存块的地址。这个内存块必须用SCardFreeMemory来释放。
在pcsc的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中提供的缓冲区长度,将如果该参数不为空将返回的缓冲区长度写入pcchReaders,并返回成功代码。
因此,它应该为dwReaders分配正确的缓冲区大小,用于获取连接的读取器列表。它在我的Windows10Pro机器上正常工作,读取器直接连接,但是通过瘦客户机连接到Windows2008PRO服务器--它返回相同的值(是r2 ),但是这个值导致了InsufficientBuffer异常。
因此,我已经开始调整该值并手动设置(在Windows2008Web服务器中调试),我发现如果将该值设置为48 (以及更高的值),它就会工作。我不知道是什么原因导致SCardListReaders方法返回该参数的值不足,但在第二次传递之前,我已经手动将该值加倍,因此新版本的ListReaders()如下所示:
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或什么,请随时评论!
https://stackoverflow.com/questions/51147469
复制相似问题