Valhalla Legends Forums Archive | General Programming | Web Page + Windows API?

AuthorMessageTime
Barabajagal
I'm working on a project for a company that calls some APIs which eject a cashier drawer via a web page. It's an educational thing, so it doesn't have to be perfectly secure, but it has to work pretty seamlessly. Basically, they want it so that if you click a link or button or something on this web page, it ejects the drawer, and it has to work on IE and Firefox. Here's some code I wrote to control the drawer in VB6:
[code]Option Explicit
Public Enum USBStatus
    IsOpen
    IsClosed
    IsError
End Enum
#If False Then
Private IsOpen, IsClosed, IsError
#End If
Private Declare Function OpenDrawer Lib "MSPOS_USB.dll" (ByVal DeviceHandle As Long) As Integer
Private Declare Function GetDrawerStatus Lib "MSPOS_USB.dll" (ByVal DeviceHandle As Long) As Integer
Private Declare Function ReleaseDrawerHandle Lib "MSPOS_USB.dll" (ByVal DeviceHandle As Long) As Integer
Private Declare Function GetDrawerHandle Lib "MSPOS_USB.dll" (ByVal DrawerNumber As Byte) As Long

Public Function USB_GetStatus(ByVal Drawer As Byte) As USBStatus
Dim Handle As Long
Dim Result As Integer
    On Error GoTo Erred
    Handle = GetDrawerHandle(Drawer)
    If Handle = 0 Then
        USB_GetStatus = IsError
    Else
        Result = GetDrawerStatus(Handle)
        Select Case Result
            Case 1
                USB_GetStatus = IsClosed
            Case 2
                USB_GetStatus = IsOpen
            Case Else
                USB_GetStatus = IsError
        End Select
        ReleaseDrawerHandle Handle
    End If
    Exit Function
Erred:
    USB_GetStatus = IsError
End Function
Public Function USB_OpenDrawer(ByVal Drawer As Byte) As USBStatus
Dim Handle As Long
Dim Result As Integer
    On Error GoTo Erred
    Select Case USB_GetStatus(Drawer)
        Case IsClosed
            Handle = GetDrawerHandle(Drawer)
            If Handle = 0 Then
                USB_OpenDrawer = IsError
            Else
                Result = OpenDrawer(Handle)
                Select Case Result
                    Case 1
                        USB_OpenDrawer = IsOpen
                    Case Else
                        USB_OpenDrawer = IsError
                End Select
                ReleaseDrawerHandle Handle
            End If
        Case IsOpen
            USB_OpenDrawer = IsOpen
        Case IsError
            USB_OpenDrawer = IsError
    End Select
    Exit Function
Erred:
    USB_OpenDrawer = IsError
End Function[/code]

Is there any way to either make a link run a local application on the computer? Perhaps call a local API via Java Applet or something? It seems like this kind of thing would normally be a security hole (running local programs via a web page), but it needs to be done. Any ideas would be appreciated.
July 13, 2007, 9:28 PM
warz
What web language are you using? I don't see why this couldn't be done in Python.
July 14, 2007, 2:17 AM
Barabajagal
I don't know python, or any web based programming languages.
July 14, 2007, 4:58 AM
warz
Well, Python isn't a web based programming language - that's why it's as powerful as it is when it comes to web based programming. Unlike PHP, Python was a programming language that existed prior to being used for web back ends. Similar to Ruby, and other languages used.
July 14, 2007, 6:26 AM
Myndfyr
If it's an ASP page, it seems that your best bet would be to write an ActiveX DLL in Visual Basic and then utilize the COM object it exposes via ASP (Server.CreateObject('Object.Name')). 
July 14, 2007, 6:59 AM
Barabajagal
I thought ActiveX didn't work through Firefox. I'm not even sure of the webserver's capabilities. I just need a way to call a local API from a remote web page. I'll see if it can run ASP, and then try to learn enough to write something that'll work. betawarz, I don't feel like learning any new languages for a one-time job.
July 14, 2007, 7:49 AM
Grok
I'm pretty sure he's meaning the client when he says local.  He's wanting the webpage to be a client application controlling the client hardware (cash register drawer).  This wouldn't have anything to do with the web server other than providing the page to the client.

This is definitely a use for the <OBJECT> tag to define an existing runnable code module on the client computer.  You will control it with javascript.  The question someone asked you which languages you know is a valid one and pertinent.  You'll need to write a scriptable object in some language that supports COM.  After writing the module and embedding it in your webpage, you'll need to reduce the security for the domain so scriptable objects are allowed.

I've done this before, where I created a TIFF viewer/manipulator which I scripted from the webpage to enter indices for the document.  As the user would tab through the index fields, the javascript would manipulate the TIFF viewer object to zoom the image to the next field.  The image was manipulated on the client, and written in ActiveX, so had the ability to call any client Windows API for which the running user had permissions.

So first question, have you written anything (stand-alone application) that can open the cash register drawer?  That's the first thing I would do, make sure the client API to open the drawer is perfect.  Then worry about packaging it into COM followed by scripting in a web page.
July 14, 2007, 11:32 AM
Myndfyr
Ah, I might have totally missed that it was a request for something strictly client-side.
July 14, 2007, 7:21 PM
Barabajagal
The person just got the drawer a few days ago, and we haven't been able to test my program yet, but the APIs are right off the drawer company's website, so it should work. And the guy who hired me got a good idea. The web page will set a variable on a server (either in a database, or, much easier to deal with, in a text file). The program sits in the system tray and waits for that variable to be set to "1" or something. It then ejects the drawer and sets the variable to the current drawer's state.

Edit: there's a few changes... we're gonna use php pages to interact with a SQL database. The php page will be requested like... ?t=5555 where 5555 is the serial number of the drawer. The page returns 1 or 0, open the drawer, or idle. A rather simple system. It will also be over https for added security ;)
July 14, 2007, 7:23 PM
Grok
Can you clarify the physical architecture being used here?  We are unclear as to the location of your physical components (cash register, person using web browser, server, database).  If you prefer I will describe it the way I think you are intending.  Read this and change for your actual scenario.

There are cash register drawers at some number of remote locations.
Each cash register drawer is connected to a computer.
Each remote computer is running a web browser (the client).
A drawer API allows causing the cash register drawer to be opened.
There is a computer running a web server to which all the clients can connect via http.
The web server should record whether a cash register drawer is open or shut.

Are all those statements correct?  If so then we know where your components exist.  Now, as to the requirements of your client and server, I do suggest a couple things.  Using https is meaningless here unless you are going to send information you want transmitted securely.  So far you are only sending a "1" indicating the drawer has been opened.  Hardly worth encryption.  I don't see when you would ever send a "0" indicating the drawer is shut.  How would you know?  Does the API detect an event when the drawer is closed, or do you have to poll some flags for drawer state?

What about the server?  Have you thought about client logins?  Unique cash register drawer id's?  Recording a history of each login, and each drawer event?  It might be vital to a theft investigation to know the date, time, userid of each login, as well as date, time, userId and cashregisterId for each drawer opening and closing.
July 16, 2007, 1:04 PM
Barabajagal
Everything's already been sorted out. The statements are correct. Each drawer has a Serial Number which is prompted for in the local application. Instead of returning a 1, it returns a "cookie" or random number, which must be returned for setting the state. The drawer is polled constantly to detect its current state, and the information is returned to the server promptly. HTTPS is used so that someone can't use something like WPE Pro to edit the packets and open the drawer. Users can enter a username and password to open the drawer if they have access, without using the site. It logs the ID, date, time, and user every time already as well. My employer wanted to do the website part himself, so I'm just in charge of the application that "interfaces" (eww... i sound like some crappy pseudo-technologist) with it. Everything's been done and it works just dandy. Thanks anyway, though ;)
July 16, 2007, 8:09 PM

Search