Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. 3rd Party Software
  4. [WIN API][WinSCard] - Stuck on an easy thing (Win Api Types and QString)
Forum Updated to NodeBB v4.3 + New Features

[WIN API][WinSCard] - Stuck on an easy thing (Win Api Types and QString)

Scheduled Pinned Locked Moved Unsolved 3rd Party Software
6 Posts 3 Posters 2.7k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    NicoFrom13
    wrote on last edited by
    #1

    Hi everybody,

    My question may be obvious for some of you but i'm stuck on an easy issue i guess.
    So i ask for someone help me.

    I'm trying to use winscard lib from windows SDK
    I have no probel to link it and compile.

    My problem is after usung SCardEstablishContext i try to call SCardListReaders() that gives a list of reades available.
    Here is my problems i'm stuck with f*** microsoft api type and maybe unicode.

    I don't know how to get the content of "mszReaders" variable.
    Here is my code :

    .pro

    #-------------------------------------------------
    #
    # Project created by QtCreator 2017-09-04T18:17:36
    #
    #-------------------------------------------------
    
    QT       += core gui
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    TARGET = SCL011_Reader
    TEMPLATE = app
    
    # The following define makes your compiler emit warnings if you use
    # any feature of Qt which as been marked as deprecated (the exact warnings
    # depend on your compiler). Please consult the documentation of the
    # deprecated API in order to know how to port your code away from it.
    DEFINES += QT_DEPRECATED_WARNINGS
    
    # You can also make your code fail to compile if you use deprecated APIs.
    # In order to do so, uncomment the following line.
    # You can also select to disable deprecated APIs only up to a certain version of Qt.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    INCLUDEPATH += "$$PWD/libs"
    LIBS += -L"$$PWD/libs" -lMCSCM
    LIBS += -L"D:/MicrosoftSDK/Lib/10.0.15063.0/um/x86/" -lwinscard
    
    #DEPENDPATH += "D:/MicrosoftSDK/Lib/10.0.15063.0/um/x86/"
    
    SOURCES += \
            main.cpp \
            mainwindow.cpp
    
    HEADERS += \
            mainwindow.h
    
    FORMS += \
            mainwindow.ui
    
    

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QDebug>
    #include "qt_windows.h"
    #include "winnt.h"
    
    
    #include "winscard.h"
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    mainwindow.cpp

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        SCARDCONTEXT cardContext;
        wchar_t *mszReaders;
        DWORD dwReaders;
    
    
        SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&cardContext);
        dwReaders = SCARD_AUTOALLOCATE;
        SCardListReadersW(cardContext,NULL,mszReaders,&dwReaders);
    
        QByteArray buffer;
        wchar_t *it = mszReaders;
    
        while(*it++)
        {
            buffer.append(QChar(*it));
        }
       qDebug()<<buffer;
    
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    

    Output of qDebug()<<buffer

    \xE6\x94\x80\xE7\x88\x80\xE6\xB8\x80\xE6\x8C\x80\xE6\xBC\x80\xE7\x88\x80\xE6\x94\x80\xE2\xB4\x80\xE7\x9C\x80\xE6\xA4\x80\xE6\xB8\x80\xE3\x8C\x80\xE3\x88\x80\xE6\xAC\x80\xE2\xB4\x80\xE6\x88\x80\xE6\x84\x80\xE7\x8C\x80\xE6\x94\x80\xE2\xB4\x80\xE6\xB8\x80\xE7\x90\x80\xE7\x94\x80\xE7\x8C\x80\xE6\x94\x80\xE7\x88\x80\xE2\xB4\x80\xE6\xB0\x80\xE3\x84\x80\xE2\xB4\x80\xE3\x84\x80\xE2\xB4\x80\xE3\x80\x80\x0
    

    Hope this clear, thanks in advance.
    Have a nice day

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Are you looking for QString:: fromWCharArray ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • hskoglundH Offline
        hskoglundH Offline
        hskoglund
        wrote on last edited by
        #3

        Hi, using SCARD_AUTOALLOCATE is tricky, because Windows then tries to return the pointer to the mszReaders variable, and without an "&" prefix your buffer will contain only gibberish :-(
        Try something like this:

        SCARDCONTEXT cardContext;
        LPTSTR mszReaders = NULL;
        DWORD dwReaders;
        
        SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&cardContext);
        dwReaders = SCARD_AUTOALLOCATE;
        SCardListReadersW(cardContext,NULL,(LPTSTR)&mszReaders,&dwReaders);
        
        QByteArray buffer;
        wchar_t *it = mszReaders;
        
        while (*it)
        {
            while(*it)
                buffer.append(QChar(*it++));
        
            qDebug() << buffer;
            buffer.clear();
            ++it;
        }
        
        

        Also your loop had a bug I think so it will throw away/skip the first char of the readers' name.

        P.S. You'll need a double loop to pick up more than one card reader name. Note: haven't tested the code!

        N 1 Reply Last reply
        2
        • hskoglundH hskoglund

          Hi, using SCARD_AUTOALLOCATE is tricky, because Windows then tries to return the pointer to the mszReaders variable, and without an "&" prefix your buffer will contain only gibberish :-(
          Try something like this:

          SCARDCONTEXT cardContext;
          LPTSTR mszReaders = NULL;
          DWORD dwReaders;
          
          SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&cardContext);
          dwReaders = SCARD_AUTOALLOCATE;
          SCardListReadersW(cardContext,NULL,(LPTSTR)&mszReaders,&dwReaders);
          
          QByteArray buffer;
          wchar_t *it = mszReaders;
          
          while (*it)
          {
              while(*it)
                  buffer.append(QChar(*it++));
          
              qDebug() << buffer;
              buffer.clear();
              ++it;
          }
          
          

          Also your loop had a bug I think so it will throw away/skip the first char of the readers' name.

          P.S. You'll need a double loop to pick up more than one card reader name. Note: haven't tested the code!

          N Offline
          N Offline
          NicoFrom13
          wrote on last edited by
          #4

          @hskoglund

          I update my code and it works but i don't understand the tricks about passing a casted referenced variable

          For who interest

          MainWindow::MainWindow(QWidget *parent) :
              QMainWindow(parent),
              ui(new Ui::MainWindow)
          {
              ui->setupUi(this);
          
              SCARDCONTEXT cardContext;
              LPWSTR mszReaders;
              DWORD dwReaders;
          
          
              SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&cardContext);
              dwReaders = SCARD_AUTOALLOCATE;
              SCardListReadersW(cardContext,NULL,(LPWSTR)&mszReaders,&dwReaders);
          
              QByteArray buffer;
              wchar_t *it = mszReaders;
          
              while(*it !='\0')
              {
                  buffer.append(QChar(*it));
                  *it++;
              }
             qDebug()<<buffer;
          
          
          }
          
          hskoglundH 1 Reply Last reply
          0
          • N NicoFrom13

            @hskoglund

            I update my code and it works but i don't understand the tricks about passing a casted referenced variable

            For who interest

            MainWindow::MainWindow(QWidget *parent) :
                QMainWindow(parent),
                ui(new Ui::MainWindow)
            {
                ui->setupUi(this);
            
                SCARDCONTEXT cardContext;
                LPWSTR mszReaders;
                DWORD dwReaders;
            
            
                SCardEstablishContext(SCARD_SCOPE_USER,NULL,NULL,&cardContext);
                dwReaders = SCARD_AUTOALLOCATE;
                SCardListReadersW(cardContext,NULL,(LPWSTR)&mszReaders,&dwReaders);
            
                QByteArray buffer;
                wchar_t *it = mszReaders;
            
                while(*it !='\0')
                {
                    buffer.append(QChar(*it));
                    *it++;
                }
               qDebug()<<buffer;
            
            
            }
            
            hskoglundH Offline
            hskoglundH Offline
            hskoglund
            wrote on last edited by
            #5

            @NicoFrom13 Why the trick? If you look at the API documentation it says that mszReaders is a pointer to a buffer which you allocate, i.e. you hand over a buffer pointer (LPWSTR) to Windows which then fills it with the card reader name(s).

            But then someone had a bright idea at Microsoft and decided that this wasn't enough and that Windows could give you a helping hand by allocating the buffer for you. This option you select by using SCARD_AUTOALLOCATE. Problem is that the API is already documented and fixed/not changeable. So that's why you have to give Windows a pointer to your pointer, so that it can return the actual pointer to you, but in order to conform the API and make the compiler happy you have to use the cast (not to a reference but a to pointer BTW).

            P.S. Note, with your code you'll only see the name of the first card reader. To see names of additional reader(s) you'll need the double loop.

            N 1 Reply Last reply
            1
            • hskoglundH hskoglund

              @NicoFrom13 Why the trick? If you look at the API documentation it says that mszReaders is a pointer to a buffer which you allocate, i.e. you hand over a buffer pointer (LPWSTR) to Windows which then fills it with the card reader name(s).

              But then someone had a bright idea at Microsoft and decided that this wasn't enough and that Windows could give you a helping hand by allocating the buffer for you. This option you select by using SCARD_AUTOALLOCATE. Problem is that the API is already documented and fixed/not changeable. So that's why you have to give Windows a pointer to your pointer, so that it can return the actual pointer to you, but in order to conform the API and make the compiler happy you have to use the cast (not to a reference but a to pointer BTW).

              P.S. Note, with your code you'll only see the name of the first card reader. To see names of additional reader(s) you'll need the double loop.

              N Offline
              N Offline
              NicoFrom13
              wrote on last edited by
              #6

              @hskoglund Thank you for your feedback

              I moved forward on my project and i have one more question.
              Could somebody explain me this ?

              When i switch the two unsigned char "receive" and "command" declaration line, i haven't the same result

              in the actual code below all things work i get all information as writen in the TAG.
              If i move up the command declaration above the receive declaration, all things messed up

              I think it's an problem about C++ understanding, sorry i'm beginner.

              here is the code

                  unsigned long proto=0;
                  const wchar_t rdName[] = L"SCM Microsystems Inc. SCL011G Contactless Reader 0";
              
                  QByteArray *myBuffer=new QByteArray();
                  resConnect = SCardConnectW(cardContext,rdName,SCARD_SHARE_SHARED,SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,&cardHandle,&proto);
                  qDebug()<<QString("Connect : %1").arg(resConnect,0,16);
              
              
                  unsigned char receive[4] = {0,0,0,0};
                  unsigned char command[] = {0xFF,0xB0,0x00,0x01,0x04};
              
                  SCARD_IO_REQUEST *senpci = new SCARD_IO_REQUEST;
                  senpci->cbPciLength = sizeof(SCARD_IO_REQUEST);
                  senpci->dwProtocol = SCARD_PROTOCOL_T1;
              
              
                  DWORD rcvLen;
              
                  for (int i(1); i<28; i++)
                  {
                      resConnect = SCardTransmit(cardHandle,senpci,command,sizeof(command),NULL,receive,&rcvLen);
                      myBuffer->append((char*)receive,4);
                      command[3]=i;
                  }
              
                  qDebug()<<*myBuffer;
                  SCardDisconnect(cardHandle,SCARD_LEAVE_CARD);
              
              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved