0

I wrote an intentional infinite loop to identify if card is detected or removed on the reader using vb.net. Because I don't know if there is something like waitForCardPresent in winscard.

So the concept is once the button Connect was clicked, the ifinite loop, to check for card, will start.

So my code in backgroundworker looks like this:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Do
        Dim ret As Integer
        Dim rs As WinscardFun.SCARDREADER_STATE
        rs.dwEventState = Nothing
        rs.rgbAtr = Nothing
        rs.pvUserData = Nothing
        rs.cbAtr = Nothing
        rs.szReader = rdr
        rs.dwCurrentState = &H0
        ret = WinscardFun.SCardGetStatusChange(hcontext, -1, rs, 1)
        If ret = 0 And rs.cbAtr > 0 And rs.rgbAtr IsNot Nothing Then

            ReDim atr(rs.cbAtr)
            Array.Copy(rs.rgbAtr, atr, rs.cbAtr)
            If status = "Connected" Then
                'Do nothing
            Else
                test = "Connected"
                Console.Write(test)
            End If

        Else
            If test = "Remove" Then
                'Do nothing
            Else
                status = "Remove"
                Console.Write(test)
            End If
        End If
    Loop

End Sub

This code explains that the program will continuously check for card status in background. I wrote the:

If status = "Connected" Then
                'Do nothing
            Else
                test = "Connected"
                Console.Write(test)
            End If

        Else
            If test = "Remove" Then
                'Do nothing
            Else
                status = "Removed"
                Console.Write(test)
            End If
End If

So my program won't flood with status and will only print connected or removed once.

So my questions are:

  1. Does the concept of javaxx smartcardio's waitforcardpresent() and waitForCardAbsent() is same with my idea?
  2. Are there much better code to detect for card status using vb.net/winscard? If yes, how?
  3. How can I stop this infinite loop? let's say the user click the Disconnect button?
  4. Does my infinite loop bad?

EDIT Infinite loop is not a good idea. So how can I detect a card status in background without consuming resources? or How should I properly use the scardgetstatuschange?

I though that the -1 in

WinscardFun.SCardGetStatusChange(hcontext, -1, rs, 1)

means it will loop infinite based on

    ''' <summary>
''' The SCardGetStatusChange function blocks execution until the current availability of the cards in a specific set of readers changes.
''' </summary>
''' <param name="hContext">A handle that identifies the resource manager context. The resource manager context is set by a previous call to the SCardEstablishContext function.</param>
''' <param name="TimeOut">The maximum amount of time, in milliseconds, to wait for an action. A value of zero causes the function to return immediately. A value of INFINITE causes this function never to time out.</param>
''' <param name="ReaderState">
''' An array of SCARD_READERSTATE structures that specify the readers to watch, and that receives the result.
''' To be notified of the arrival of a new smart card reader, set the szReader member of a SCARD_READERSTATE structure to "\\\\?PnP?\\Notification", and set all of the other members of that structure to zero.
''' Important  Each member of each structure in this array must be initialized to zero and then set to specific values as necessary. If this is not done, the function will fail in situations that involve remote card readers.
''' </param>
''' <param name="ReaderCount">The number of elements in the rgReaderStates array.</param>
''' <returns></returns>
<DllImport("winscard.dll", EntryPoint:="SCardGetStatusChangeA", CharSet:=CharSet.Ansi)> _
Public Shared Function SCardGetStatusChange(ByVal hContext As IntPtr, ByVal TimeOut As Integer, ByRef ReaderState As SCARD_READERSTATE, ByVal ReaderCount As Integer) As Integer
End Function
  • 2
    1. No clue. 2. Probably. 3. Don't use an infinite loop. 4. Yes. – Elliott Frisch Sep 28 '17 at 01:40
  • 1
    5. Please read [ask] and take the [tour] – Ňɏssa Pøngjǣrdenlarp Sep 28 '17 at 01:44
  • @ElliottFrisch I can't seem to find how to automatically identify card status using winscard, so I intentionally added this infinite loop. I read that infinite loop is useful and not that bad. Kindly explain to me how my infinite loop is bad? or when can i make the infinite loop not that bad? Any feed back would greatly appreciated. thanks – Anonymouse24 Sep 28 '17 at 01:52
  • You use an [event handler](https://cgeers.wordpress.com/2008/02/03/monitoring-a-smartcard-reader/). Your method is going to consume a great deal of resources, and may well cause the application to become slow and unresponsive. Please do not ask such broad questions here. "Bad" can be subjective. – Elliott Frisch Sep 28 '17 at 02:01
  • Thanks @elliottFrisch I am newbie in .net programming, so I need to understand first the link you sent. – Anonymouse24 Sep 28 '17 at 02:28
  • Use a Timer instead of a infinite loop. Use a short interval depending how often you need to check for the card. This will also give a break to your main thread (UI thread). Doing a infinite loop like you do or like the answer down below will affect performance of your application and you will loose multi-tasking functions because your main thread is busy looping. give a break to your UI to do other stuff so add application.doevents() somewhere in your loop. I would put it just after this line ret = WinscardFun.SCardGetStatusChange –  Sep 28 '17 at 02:39
  • sorry not after before the line. so you get new events before check for the status –  Sep 28 '17 at 02:50
  • To get out the loop if you are not using a timer the set up something at the top of your class so you can change the flag and get out the loop. Dim Exitloop as Boolean = False. Then change it to true on click and add a IF in your loop to get out or loop until ExitLoop=True –  Sep 28 '17 at 02:54
  • I would like to try that suggestion, @ElliotFrish is this valid? I just want a second opinion though. hehe – Anonymouse24 Sep 28 '17 at 02:54
  • @Anonymouse24 - This is using the `"Winscard.dll"`? If so this is not a .NET assembly so you'd have to have some external references to invoke the library. Can you post a [mcve]? – Enigmativity Sep 28 '17 at 02:56
  • @ElliottFrisch Using event handler usually works good but could be unstable. Using it the right way by adding the references and making safe calls is a much better way. –  Sep 28 '17 at 03:01
  • There, I added the scardgetstatuschange @mutedDisk – Anonymouse24 Sep 28 '17 at 03:08
  • @Anonymouse24 It's state on your post the function block execution until the status of the reader changes. does it actually blocks your loop or it goes right away to IF block? –  Sep 28 '17 at 03:22
  • @MutedDisk I guess it's not blocking, that's why i intentionally add the infinite loop to call the scardgetstatuschange() – Anonymouse24 Sep 28 '17 at 03:33
  • @Anonymouse24 is adding application.doevents to your loop fixed your isssue? MSDN say it does blocks until the status changes.. https://msdn.microsoft.com/en-us/library/aa374731(v=VS.85).aspx#smart_card_functions –  Sep 28 '17 at 03:37
  • Hi @MutedDisk, slr I have note yet tried the application.doevents, I first tried the code from the link sent by ellitioFrisch. Which uses `while !e.cancel`. Thanks by the way. – Anonymouse24 Sep 28 '17 at 06:04

0 Answers0