SCardGetCardTypeProviderName возвращает пустые результаты

Я пытаюсь использовать SCardGetCardTypeProviderName, используя взаимодействие в C#. Одним из параметров является ссылка, которая должна возвращать имя провайдера для смарт-карты в соответствии с передаваемым контекстом карты. Это код, который я использую:

IntPtr hSC = { value comes from call using SCardEstablishContext }
string cardName = { value comes from SCardUIDlgSelectCard }
int providerNameLength = 256;
string providerName = string.Empty;  //doesn't matter how I initialize this

[DllImport("winscard.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern Int32 SCardGetCardTypeProviderName(IntPtr hContext, string szCardName, uint dwProviderId, ref string szProvider, ref int pcchProvider);

int lReturn = SCardGetCardTypeProviderName(hSC, cardName, SCARD_PROVIDER_CSP, ref providerName, ref providerNameLength);

Но providerName всегда возвращается пустым, в то время как providerNameLength меняется на 43, что заставляет меня думать, что это проблема сортировки. Но я попытался упорядочить имя провайдера как:

  • LPWSTR
  • LPTSTR
  • LPSTR

В случае последних двух, вместо пустой строки, я снова получаю строку странных символов, заставляя меня думать, что это проблема сортировки / перевода.

1 ответ

Решение

Объявите строковый параметр как StringBuilder:

[DllImport("winscard.dll"]
public static extern int SCardGetCardTypeProviderName(
    IntPtr hContext,
    string szCardName, 
    uint dwProviderId, 
    StringBuilder szProvider, 
    ref int pcchProvider
);
....
StringBuilder providerName = new StringBuilder(providerNameLength);
int lReturn = SCardGetCardTypeProviderName(
    hSC, 
    cardName, 
    SCARD_PROVIDER_CSP, 
    providerName, 
    ref providerNameLength
);

Нет необходимости повторять значение по умолчанию CharSet, и эти функции API не используют механизм последней ошибки Win32.

Другие вопросы по тегам