//--------------------------------------------------------------------------
// TSmPort.h     =   Header for the TSmPort class in C++
//                   (for Borland C++ Builder V4).
//    Date:    2005-11-05  (YYYY-MM-DD)
//    Author:  Wolfgang Buescher (www.qsl.net/DL4YHF,  dl4yhf@qsl.net)
//    Path:    \\Wobu_p4\c\CBproj\SMPORT\TSmPort.cpp
//             ("master", everything else is just a COPY)
//
//  Based on the DELPHI COMPONENT "SmallPort.pas" :
//   > SmallPort ver 1.4 for Delphi 4 modified 21-August-2000
//   >  Windows NT/2000 compatible
//   >  Author: Alexander Weitzman (alweit1@hotmail.com)
//  This was later (2005-11) changed to support the PortAccess driver
//     by Craig Peacock, which works faster because of a different principle.
//
//  This unit allows direct hardware access under Win95/98/NT/ME/2000 .
//
//  Copy file "smport.vxd" to "Windows\System" directory or to directory
//                         of your application for Win 9x
//         or "smport.sys" to "WinNT\SYSTEM32" (or to application folder).
//
//
//  History: see  TSmPort.cpp
//
//--------------------------------------------------------------------------

#ifndef   SMPORT_INCLUDED
 #define  SMPORT_INCLUDED 1

#include <Windows.h>

//--------------------------------------------------------------------------
// Constants
//--------------------------------------------------------------------------
  #define  SMALLPORT_TYPE    61696

  // WoBu, 2004-01-14: 'Redefinition .. not identical' when compiled with BCB V6 ?!?
  // Here is a VERY VERY UGLY fix:
#ifdef FILE_READ_ACCESS       /* this happens under BCB 6 */
 #undef FILE_READ_ACCESS
#endif
#ifdef FILE_WRITE_ACCESS
 #undef FILE_WRITE_ACCESS
#endif

  #define  METHOD_BUFFERED   0
  #define  FILE_READ_ACCESS  1
  #define  FILE_WRITE_ACCESS 2

  #define  VER_WINDOWS_UNKNOWN  0
  #define  VER_WINDOWS_31       1
  #define  VER_WINDOWS_95       2
  #define  VER_WINDOWS_98       3
  #define  VER_WINDOWS_NT       4
  #define  VER_WINDOWS_2000     5 /* + Windows XP */
  #define  VER_WINDOWS_ME       6

// Since 2005-11-06 :  Which port-driver to use ? There's more besides SMPORT...
#define PORTACCESS_SMPORT   0  /* this was the default port access method */
#define PORTACCESS_PORTTALK 1  /* open PortTalk driver to grant access    */
#define PORTACCESS_NO_DRIVER 2 /* no driver needed, something "external" allowed I/O for us */


//---------------------------------------------------------------------------
// Definition of the TSmPort Class.
//    This is not supposed to be compatible with anything ;-)
//---------------------------------------------------------------------------
class TSmPort
{
 private:
    DWORD dwLastError;
    DWORD m_dwWinVer;
    DWORD dwReadByteCode;
    DWORD dwWriteByteCode;
    DWORD dwReadWordCode;
    DWORD dwWriteWordCode;
    DWORD dwReadDWordCode;
    DWORD dwWriteDWordCode;
    TCHAR m_sz64DriverName[65];
    TCHAR szAlternativeDriverPath[MAX_PATH+1];  // by WoBu, from OpenDriver(), for ReOpen()
    bool  fRemoveDevice;
    bool  fStopService;

    SC_HANDLE hManager;   // For use with WinNT Service Control Manager..
    void* m_hSmPortDevice;  // handle to SmallPort device
    int   m_iUseWhichDriver;    // which driver to use: PORTACCESS_SMPORT, PORTACCESS_PORTTALK, ...
#ifdef USE_PORTTALK  /* AllowIoWrapper.cpp included ? (see Compiler Options..Cond'l Defines) */
    bool  m_fUseDirectAccess;   // true = direct port access (without DeviceIoControl) possible
    bool  m_fDirectAccessFailed; // true= "tried to access the port, but threw an exception"
#endif

    TCHAR sz255LastErrorString[256];

    void  ReOpen(bool fValue);
    void  OpenServiceManager(void);
    void  CloseServiceManager(void);
    void  InstallSmallPortDriver(void);
    void  RemoveSmallPortDriver(void);
    void  StartSmallPortService(void);
    void  StopSmallPortService(void);
    DWORD GetDriverHandle(void);   // once public, but who needs this ?


 public:
    TSmPort();  // Constructor (without incompatible "TComponent" stuff)
    ~TSmPort(); // Destructor  (automagically closes the driver if needed)

    bool  OpenDriver(    // you must call this ONCE before accessing a port
           int iUseNewDriver,            // 0=SMPORT, 1=PortTalk, ...
          const TCHAR * szOneMorePathToDriver); // .. if driver neither found in current nor in system directory

    void  CloseDriver(void);  // you MAY call this if you don't need port access
    bool  IsOpen(void);       // used to check if the driver has been opened successfully
    bool  AccessFailed(void); // tell the application if an access failed
    DWORD GetWindowsVersion(void); // returns VER_WINDOWS_xxxx for testing

    WORD  ReadByte(WORD wPort);                 // reads from an 8-bit I/O port
    void  WriteByte(WORD wPort, WORD wValue);   // writes to  an 8-bit I/O port
    WORD  ReadWord(WORD wPort);                 // reads from a 16-bit I/O port
    void  WriteWord(WORD wPort, WORD wValue);   // writes to  a 16-bit I/O port
    DWORD ReadDWord(WORD wPort);                // reads from a 32-bit I/O port
    void  WriteDWord(WORD wPort,DWORD dwValue); // writes to a 32-bit I/O port

    // void  Sound(WORD wFreq, WORD wDelay); // removed because of ugly "Sleep"
    void  SpeakerOn(WORD wFrequencyInHz);  // starts a tone on the PC speaker
    void  SpeakerOff(void);         // turns the tone from the PC speaker off

    // Ex: "properties"... (looked like variables but cannot set a pointer to them - rubbish)
    DWORD GetLastError(void);
    TCHAR *GetLastErrorString(void);


}; // end class TSmPort


#endif // SMPORT_INCLUDED

// EOF <TSmPort.cpp>
