如题.请指教, 谢谢.......

解决方案 »

  1.   

    和读写com一样,用createfile, readfile, writefile那些api可以做
      

  2.   

    /*
    Module : PARALLEL.CPP
    Purpose: Implementation for an MFC class to encapsulate parallel ports
    Created: PJN / 28-12-1999
    History: PJN / 06-03-2000 Code now throws an exception if no Win32 parallel ports are available
             PJN / 04-04-2000 Code handles the case where it is run on NT / Windows 2000 by throwing
                              an exception                 
             PJN / 19-07-2000 1. Now works on NT / Windows 2000 thanks to DriverLINX Port I/O Driver
                              2. Made all typedefs and enums local to the appropiate class rather
                              than polluting the global namespace
    Copyright (c) 1999 - 2000 by PJ Naughter.  
    All rights reserved.*//////////////////////////////////  Includes  //////////////////////////////////
    #include "stdafx.h"
    #include "ParallelPort.h"
    #include <winerror.h>
    #include <conio.h>
    #include <afxpriv.h>
    ///////////////////////////////// Defines / Statics ///////////////////////////#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endifint CParallelPort::sm_nRefCount = 0;
    BOOL CParallelPort::sm_bRunningOnNT = FALSE;
    HINSTANCE CParallelPort::sm_hDLINX = NULL;
    CParallelPort::LPDLPORTREADPORTUCHAR CParallelPort::sm_lpfnDlPortReadUchar = NULL;
    CParallelPort::LPDLPORTWRITEPORTUCHAR CParallelPort::sm_lpfnDlPortWriteUchar = NULL;
    CArray<CParallelPortSettings, CParallelPortSettings&> CParallelPort::sm_Ports;
    //////////////////////////////// Implementation ///////////////////////////////
    ////////// Exception handling codevoid AfxThrowParallelException(DWORD dwError /* = 0 */)
    {
    if (dwError == 0)
    dwError = ::GetLastError(); CParallelException* pException = new CParallelException(dwError); TRACE(_T("Warning: throwing CParallelException for error %d\n"), dwError);
    THROW(pException);
    }BOOL CParallelException::GetErrorMessage(LPTSTR pstrError, UINT nMaxError, PUINT pnHelpContext)
    {
    ASSERT(pstrError != NULL && AfxIsValidString(pstrError, nMaxError)); if (pnHelpContext != NULL)
    *pnHelpContext = 0; LPTSTR lpBuffer;
    BOOL bRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                          NULL,  m_dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT),
                          (LPTSTR) &lpBuffer, 0, NULL); if (bRet == FALSE)
    *pstrError = '\0';
    else
    {
    lstrcpyn(pstrError, lpBuffer, nMaxError);
    bRet = TRUE; LocalFree(lpBuffer);
    } return bRet;
    }CString CParallelException::GetErrorMessage()
    {
      CString rVal;
      LPTSTR pstrError = rVal.GetBuffer(4096);
      GetErrorMessage(pstrError, 4096, NULL);
      rVal.ReleaseBuffer();
      return rVal;
    }CParallelException::CParallelException(DWORD dwError)
    {
    m_dwError = dwError;
    }CParallelException::~CParallelException()
    {
    }IMPLEMENT_DYNAMIC(CParallelException, CException)#ifdef _DEBUG
    void CParallelException::Dump(CDumpContext& dc) const
    {
    CObject::Dump(dc); dc << "m_dwError = " << m_dwError;
    }
    #endif
      

  3.   

    ////////// Settings classCParallelPortSettings::CParallelPortSettings()
    {
      m_nBaseAddress = 0;
      m_Type         = ParallelTypeUndefined;
      m_ECPMode      = ECPModeUndefined;
    }CParallelPortSettings::CParallelPortSettings(const CParallelPortSettings& state)
    {
      *this = state;
    }CParallelPortSettings& CParallelPortSettings::operator=(const CParallelPortSettings& state)
    {
      m_nBaseAddress = state.m_nBaseAddress;
      m_Type         = state.m_Type;   
      m_ECPMode      = state.m_ECPMode;  return *this;
    }////////// The actual parallel port classCParallelPort::CParallelPort()
    {
      m_hPort = INVALID_HANDLE_VALUE;
      m_nPortIndex = -1;
      m_nBaseAddress = 0;
      m_dwTimeout = 1000;  //Default timeout is 1 second  //Test for presence of parallel ports at the standard addresses of 0x3BC, 0x378 and 0x278
      if (sm_nRefCount == 0)
      {
        ++sm_nRefCount;    //Initialize the DriverLINX driver if on NT / Windows 2000
        sm_bRunningOnNT = RunningOnNT();
        if (sm_bRunningOnNT)
        {
          if (!InitializeDriverLINX())
          {
            TRACE(_T("Running on Windows NT / Windows 2000 and the DriverLINX PORTIO driver is not installed, aborting !!\n"));
            AfxThrowParallelException();
          }
        }    //Open LPT1 - LPT3 as a precaution against other processes trying to write 
        //to the port while we are detecting them
        HANDLE hPort1 = CreateFile(_T("\\\\.\\LPT1"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        HANDLE hPort2 = CreateFile(_T("\\\\.\\LPT2"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        HANDLE hPort3 = CreateFile(_T("\\\\.\\LPT3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);    //Must have at least one port available in Win32 to continue to attempt
        //detection of the ports
        int nWin32Ports = 0;
        if (hPort1 != INVALID_HANDLE_VALUE)
          ++nWin32Ports;
        if (hPort2 != INVALID_HANDLE_VALUE)
          ++nWin32Ports;
        if (hPort3 != INVALID_HANDLE_VALUE)
          ++nWin32Ports;
        if (nWin32Ports == 0)
        {
          TRACE(_T("No parallel ports are available to Win32, aborting !!\n"));
          AfxThrowParallelException(ERROR_DEV_NOT_EXIST);
        }    //Try to detect the details of the 3 standard ports
        CParallelPortSettings settings;
        if (GetPort(0x3BC, settings))
          sm_Ports.Add(settings);    if (sm_Ports.GetSize() < nWin32Ports) 
          if (GetPort(0x378, settings))
            sm_Ports.Add(settings);    if (sm_Ports.GetSize() < nWin32Ports) 
          if (GetPort(0x278, settings))
            sm_Ports.Add(settings);    if (sm_Ports.GetSize() == 0)
          TRACE(_T("Could not detect any parallel ports on this machine\n"));    //Don't forget to close the 3 SDK handles we had open
        CloseHandle(hPort3);
        CloseHandle(hPort2);
        CloseHandle(hPort1);
      }
    }
      

  4.   

    [email protected]
    万分感谢.:)  急啊兄弟.
      

  5.   

    CParallelPort::~CParallelPort()
    {
      //decrement the reference count and 
      //free the DriverLINX pointers if necessary
      --sm_nRefCount;
      if (sm_nRefCount == 0)
        DeInitializeDriverLINX();  Close();
    }IMPLEMENT_DYNAMIC(CParallelPort, CObject)#ifdef _DEBUG
    void CParallelPort::Dump(CDumpContext& dc) const
    {
    CObject::Dump(dc); dc << _T("m_hPort = ") << m_hPort << _T("\n");
    }
    #endifvoid CParallelPort::Open(int nPort)
    {
      //Call Close just in case we already have the port open
      Close();  m_nPortIndex = nPort - 1;
      if (m_nPortIndex < sm_Ports.GetSize())
      {
        //Cache the base address of the port for performance reasons
        m_nBaseAddress = sm_Ports.ElementAt(m_nPortIndex).m_nBaseAddress;    //Call CreateFile to open up the parallel port. This prevents other apps 
        //causing problems when we do the Port IO directly.
        CString sPort;
        sPort.Format(_T("\\\\.\\LPT%d"), nPort);
        m_hPort = CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
        if (m_hPort == INVALID_HANDLE_VALUE)
        {
          TRACE(_T("Failed to open parallel port, LPT%d\n"), nPort);
          Close();
          AfxThrowParallelException();
        }
      }
      else
      {
        TRACE(_T("Could not find the parallel port, LPT%d\n"), nPort);
        Close();
        AfxThrowParallelException(ERROR_FILE_NOT_FOUND);
      }
    }BOOL CParallelPort::IsOpen() const
    {
      return (m_hPort != INVALID_HANDLE_VALUE);
    }void CParallelPort::Close()
    {
      if (IsOpen())
      {
        BOOL bSuccess = CloseHandle(m_hPort);
        m_hPort = INVALID_HANDLE_VALUE;
        m_nPortIndex = -1;
        m_nBaseAddress = 0;
        if (!bSuccess)
          TRACE(_T("Failed to close the parallel port, GetLastError:%d\n"), GetLastError());
      }
    }void CParallelPort::SetECPMode(CParallelPortSettings::ECPPortMode mode)
    {
      ASSERT(IsOpen()); //Port must be open 
      CParallelPortSettings& settings = sm_Ports.ElementAt(m_nPortIndex);
      ASSERT(settings.m_Type == CParallelPortSettings::ParallelTypeECP); //Must be an ECP port
      ASSERT(mode != CParallelPortSettings::ECPModeUndefined);  unsigned short nEcrAddress = (unsigned short)(m_nBaseAddress + 0x402);  //Read the ECR & clear bits 5, 6 & 7
      int nEcrData = _inp(nEcrAddress) & 0x1F;
      
      //Write the selected value to bits 5, 6 & 7
      switch (mode)
      {
        case CParallelPortSettings::ECPModeSPP:            nEcrData |= (0 << 5); break;
        case CParallelPortSettings::ECPModePS2:            nEcrData |= (1 << 5); break;
        case CParallelPortSettings::ECPModeFastCentronics: nEcrData |= (2 << 5); break;
        case CParallelPortSettings::ECPModeECP:            nEcrData |= (3 << 5); break;
        case CParallelPortSettings::ECPModeEPP:            nEcrData |= (4 << 5); break;
        case CParallelPortSettings::ECPModeTest:           nEcrData |= (6 << 5); break;
        case CParallelPortSettings::ECPModeConfiguration:  nEcrData |= (7 << 5); break;
        default: ASSERT(FALSE);                           break;
      }
      _outp(nEcrAddress, nEcrData);  //Update the value in our cached array
      settings.m_ECPMode = mode;
    }CParallelPortSettings::ECPPortMode CParallelPort::GetECPMode()
    {
      ASSERT(IsOpen()); //Port must be open 
      CParallelPortSettings& settings = sm_Ports.ElementAt(m_nPortIndex);
      ASSERT(settings.m_Type == CParallelPortSettings::ParallelTypeECP); //Must be an ECP port  CParallelPortSettings::ECPPortMode t = ReadECPMode(settings.m_nBaseAddress);
      ASSERT(t == settings.m_ECPMode);  return settings.m_ECPMode;
    }
      

  6.   

    CParallelPortSettings::ECPPortMode CParallelPort::ReadECPMode(unsigned short nBaseAddress)
    {
      CParallelPortSettings::ECPPortMode mode = CParallelPortSettings::ECPModeUndefined;
      int nEcrData = _inp((unsigned short)(nBaseAddress+0x402));
      nEcrData = (nEcrData & 0xE0) >> 5;
      switch (nEcrData)
      { 
        case 0: mode = CParallelPortSettings::ECPModeSPP;            break;
        case 1: mode = CParallelPortSettings::ECPModePS2;            break;
        case 2: mode = CParallelPortSettings::ECPModeFastCentronics; break;
        case 3: mode = CParallelPortSettings::ECPModeECP;            break;
        case 4: mode = CParallelPortSettings::ECPModeEPP;            break;
        case 6: mode = CParallelPortSettings::ECPModeTest;           break;
        case 7: mode = CParallelPortSettings::ECPModeConfiguration;  break;
        default: break;
      }
      return mode;
    }BOOL CParallelPort::GetPort(unsigned short nBaseAddress, CParallelPortSettings& settings)
    {
      BOOL bSuccess = FALSE;  //First try to detect an ECP port
      if (GetECPPort(nBaseAddress))
      {
        settings.m_nBaseAddress = nBaseAddress;
        settings.m_Type = CParallelPortSettings::ParallelTypeECP;
        settings.m_ECPMode = ReadECPMode(nBaseAddress);
        bSuccess = TRUE;
      }
      else
      {
        //If its not an ECP, look for an EPP.
        //If the baseaddress is 3BCh, skip the EPP test.
        //EPPs aren't allowed at 3BCh due to possible conflicts
        //with video memory
        BOOL bFoundEPP = FALSE;    if (nBaseAddress != 0x3BC)
        {
          bFoundEPP = GetEPPPort(nBaseAddress);
          if (bFoundEPP)
          {
            settings.m_nBaseAddress = nBaseAddress;
            settings.m_Type = CParallelPortSettings::ParallelTypeEPP;
            settings.m_ECPMode = CParallelPortSettings::ECPModeUndefined;
            bSuccess = TRUE;
          }
        }    if (!bFoundEPP)
        {
          //If its not an EPP, look for an SPP.
          if (GetSPPPort(nBaseAddress))
          {
            //Test for a PS/2 port only if the SPP exists.
            //because if the port doesn't exist, it will 
            //pass the PS/2 test!
            if (GetPS2Port(nBaseAddress))
              settings.m_Type = CParallelPortSettings::ParallelTypePS2;
            else
              settings.m_Type = CParallelPortSettings::ParallelTypeSPP;        settings.m_nBaseAddress = nBaseAddress;
            settings.m_ECPMode = CParallelPortSettings::ECPModeUndefined;
            bSuccess = TRUE;
          }
        }
      }  if (!bSuccess)
      {
        settings.m_nBaseAddress = 0;
        settings.m_Type = CParallelPortSettings::ParallelTypeUndefined;
        settings.m_ECPMode = CParallelPortSettings::ECPModeUndefined;
      }    return bSuccess;
    }
      

  7.   

    BOOL CParallelPort::GetECPPort(unsigned short nBaseAddress)
    {
      //If the ECP is idle and the FIFO empty,
      //in the ECP's Ecp (at base address+402h),
      //bit 1 (Fifo full)=0, and bit 0 (Fifo empty)=1.
      //The first test is to see if these bits differ from the
      //corresponding bits in the control port (at base address+2).
      //If so a further test is to write 34h to the Ecr, 
      //then read it back. Bit 1 is read/write and bit 0 is read-only.
      //If the value read is 35h, the port is an ECP.
      BOOL bSuccess = FALSE;
     
      unsigned short nEcrAddress = (unsigned short)(nBaseAddress+0x402);
      int nEcrData = _inp(nEcrAddress);
      
      //Read bits 0 and 1 and control port bit 1
      int nEcrBit0 = nEcrData & 0x1;
      int nEcrBit1 = (nEcrData & 0x2) >> 1;
      int nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;  if (nEcrBit0 == 1 && nEcrBit1 == 0)
      {
        //Compare control bit 1 to ECR bit 1
        //Toggle the control bit if necessary
        //to be sure the two registers are different.
        if (nControlBit1 == 0)
        {
          WriteControl(nBaseAddress, 0xF);
          nControlBit1 = (ReadControl(nBaseAddress) & 0x2) >> 1;
        }    if (nEcrBit1 != nControlBit1)
        {
          int nOriginalEcrData = nEcrData;
          _outp(nEcrAddress, 0x34);
          if (_inp(nEcrAddress) == 0x35)
            bSuccess = TRUE;      //Restore the ECR to its original value
          _outp(nEcrAddress, nOriginalEcrData);
        }
      }  return bSuccess;
    }BOOL CParallelPort::GetEPPPort(unsigned short nBaseAddress)
    {
      //Write to an EPP register, then read it back.
      //If the read matches the write, it's probably an EPP
      BOOL bSuccess = FALSE;  //Use nEppAddressPort for testing, SPP's, ECP's and PS/2 ports
      //do not have this register
      unsigned short nEppAddressPort = (unsigned short) (nBaseAddress+3);
      _outp(nEppAddressPort, 0x55);  //Clear the timeout bit after each EPP operation
      int nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
      int nRead = _inp(nEppAddressPort);
      nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
      if (nRead == 0x55)
      {
        _outp(nEppAddressPort, 0xAA);
        nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
        nRead = _inp(nEppAddressPort);
        nTimeoutBit = GetEPPTimeoutBit(nBaseAddress);
        if (nRead == 0xAA)
          bSuccess = TRUE;
      }    return bSuccess;
    }
      

  8.   

    Try treating the LPT port as a file
    //Here is some code:
    CFile PRNFile;
    CString PRNFilename;
    int Printed = 0;
    char PortName[100];
    BYTE Buffer[100];
    int *written;
    UINT read;
    HANDLE hPort;hPort = CreateFile(PortName, GENERIC_WRITE, NULL, NULL, OPEN_EXISTING,
    NULL, NULL);
    if(INVALID_HANDLE_VALUE != hPort)
    {
    do
    {
    read = PRNFile.Read(Buffer, 100);
    WriteFile(hPort, Buffer, read, (LPDWORD) written, NULL);
    Printed += *written;
    } while(read == 100); CloseHandle(hPort);
    }
    else
    {
    AfxMessageBox("Could not open " + theApp.LPTString);
    }
      

  9.   

    void CParallelPort::WriteControl(unsigned short nBaseAddress, int nData)
    {
      //The control port is at offset nBaseAddress + 2.
      //Bits 0, 1 & 3 need to be inverted  
      _outp((unsigned short)(nBaseAddress+2), nData ^ 0xB);
    }int CParallelPort::ReadControl(unsigned short nBaseAddress)
    {
      //The control port is at offset nBaseAddress + 2.
      //Bits 0, 1 & 3 need to be inverted  
      return (_inp((unsigned short)(nBaseAddress+2)) ^ 0xB);
    }void CParallelPort::WriteData(unsigned short nBaseAddress, int nData)
    {
      //The data port is at offset nBaseAddress.
      _outp(nBaseAddress, nData);
    }int CParallelPort::ReadData(unsigned short nBaseAddress)
    {
      //The data port is at offset nBaseAddress.
      return _inp(nBaseAddress);
    }int CParallelPort::ReadStatus(unsigned short nBaseAddress)
    {
      //The status port is at offset nBaseAddress + 1.
      //Bit 7 need to be inverted  
      return (_inp((unsigned short)(nBaseAddress+1)) ^ 0x80);
    }void CParallelPort::WriteControl(int nData)
    {
      ASSERT(IsOpen()); //Port must be open
      WriteControl(m_nBaseAddress, nData);  
    }int CParallelPort::ReadControl()
    {
      ASSERT(IsOpen()); //Port must be open
      return ReadControl(m_nBaseAddress);  
    }void CParallelPort::WriteData(int nData)
    {
      ASSERT(IsOpen()); //Port must be open
      WriteData(m_nBaseAddress, nData);  
    }int CParallelPort::ReadData()
    {
      ASSERT(IsOpen()); //Port must be open
      return ReadData(m_nBaseAddress);  
    }int CParallelPort::ReadStatus()
    {
      ASSERT(IsOpen()); //Port must be open
      return ReadStatus(m_nBaseAddress);  
    }BOOL CParallelPort::ReadByteUsingNibbleMode(BYTE& byData)
    {
      ASSERT(IsOpen()); //Port must be open  //Read a byte of data at the status port, in 2 nibbles  //When S6 = 0, set D3 to 0
      int S6;
      DWORD dwStartTicks = GetTickCount();
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 1);
      WriteData(m_nBaseAddress, 0);  //When the peripheral responds by setting S6=1, Set D3=1
      //nLowNibble then holds 4 bits of data
      int nLowNibble;
      do
      {
        nLowNibble = ReadStatus(m_nBaseAddress);
        S6 = (nLowNibble & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 0);
      WriteData(m_nBaseAddress, 8);  //When S6 = 0, set D3 to 0
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 1);
      WriteData(m_nBaseAddress, 0);  //When the peripheral responds by setting S6=1, Set D3=1
      //nHighNibble then holds 4 bits of data
      int nHighNibble;
      do
      {
        nHighNibble = ReadStatus(m_nBaseAddress);
        S6 = (nHighNibble & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 0);
      WriteData(m_nBaseAddress, 8);  //Recombine the two nibbles back into the byte
      byData = (BYTE) (((nLowNibble & 0x8) >> 3) +
                       ((nLowNibble & 0x10) >> 3) +
                       ((nLowNibble & 0x20) >> 3) +
                       ((nLowNibble & 0x80) >> 4) +
                       ((nHighNibble & 0x8) << 1) +
                       ((nHighNibble & 0x10) << 1) +
                       ((nHighNibble & 0x20) << 1) +
                       ((nHighNibble & 0x80)));   return TRUE;
    }
      

  10.   

    BOOL CParallelPort::WriteByteUsingNibbleMode(BYTE byData)
    {
      ASSERT(IsOpen()); //Port must be open  //Write a byte to the data port, in 2 nibbles.
      //The remote system reads the data at its status port.
      //The data bits are D0, D1, D2 and D4.
      //D3 is the strobe
      int nLowNibble = byData & 0x07;
      nLowNibble |= (byData & 0x08) << 1;
      int nHighNibble = (byData & 0x70) >> 4;
      nHighNibble |= (byData & 0x80) >> 3;  //When S6=1 (not busy), write the low nibble and set D3=0.
      int S6;
      DWORD dwStartTicks = GetTickCount();  
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 0);
      WriteData(m_nBaseAddress, nLowNibble);  //When the peripheral responds by setting S6=0, Set D3=1.
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 1);
      WriteData(m_nBaseAddress, nLowNibble | 0x8);  //When S6=1, write the high nibble and set D3=0
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 0);
      WriteData(m_nBaseAddress, nHighNibble);  //When the peripheral responds by setting S6=0, Set D3=1.
      do
      {
        S6 = (ReadStatus(m_nBaseAddress) & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
          return FALSE;
      }
      while (S6 == 1);
      WriteData(m_nBaseAddress, nHighNibble | 0x8);  return TRUE;
    }BOOL CParallelPort::ReadUsingNibbleMode(void* lpBuf, DWORD dwBytes)
    {
      //Validate the parameters
      ASSERT(lpBuf);  //Read each byte into lpBuf  
      BYTE* lpByteBuf = (BYTE*) lpBuf;
      for (DWORD i=0; i<dwBytes; i++)
      {
        if (!ReadByteUsingNibbleMode(lpByteBuf[i]))
          return FALSE;
      }
      return TRUE;
    }BOOL CParallelPort::WriteUsingNibbleMode(const void* lpBuf, DWORD dwBytes)
    {
      //Validate the parameters
      ASSERT(lpBuf);  //Write each byte from lpBuf  
      const BYTE* lpByteBuf = (const BYTE*) lpBuf;
      for (DWORD i=0; i<dwBytes; i++)
      {
        if (!WriteByteUsingNibbleMode(lpByteBuf[i]))
          return FALSE;
      }
      return TRUE;
    }int CParallelPort::_inp(unsigned short port)
    {
      if (sm_bRunningOnNT)
      {
        ASSERT(sm_lpfnDlPortReadUchar);
        return sm_lpfnDlPortReadUchar(port);
      }
      else
        return ::_inp(port);
    }int CParallelPort::_outp(unsigned short port, int databyte)
    {
      if (sm_bRunningOnNT)
      {
        ASSERT(sm_lpfnDlPortWriteUchar);
        sm_lpfnDlPortWriteUchar(port, (UCHAR) databyte);
        return databyte;
      }
      else
        return ::_outp(port, databyte);
    }BOOL CParallelPort::InitializeDriverLINX()
    {
      //Load up the DriverLINX dll and get the function pointers we are interested in
      ASSERT(sm_hDLINX == NULL);
      BOOL bSuccess = FALSE;
      sm_hDLINX = LoadLibrary(_T("DLPORTIO.DLL"));
      if (sm_hDLINX)
      {
        //Get the function pointers
        sm_lpfnDlPortReadUchar = (LPDLPORTREADPORTUCHAR) GetProcAddress(sm_hDLINX, "DlPortReadPortUchar");
        sm_lpfnDlPortWriteUchar = (LPDLPORTWRITEPORTUCHAR) GetProcAddress(sm_hDLINX, "DlPortWritePortUchar");    //If any of the functions are not installed then fail the load
        if (sm_lpfnDlPortReadUchar == NULL ||
            sm_lpfnDlPortWriteUchar == NULL)
        {
          TRACE(_T("Failed to get one of the function pointer`s in the DriverLINX dll\n"));
          DeInitializeDriverLINX();
        }
        else
          bSuccess = TRUE;
      }
      else
        TRACE(_T("Could not find the load the DriverLINX dll, please ensure DriverLINX driver is installed\n"));  return bSuccess;
    }
      

  11.   

    void CParallelPort::DeInitializeDriverLINX()
    {
      if (sm_hDLINX)
      {
        //Unload the dll and reset the function pointers to NULL    
        FreeLibrary(sm_hDLINX);
        sm_hDLINX = NULL;
        sm_lpfnDlPortReadUchar = NULL;
        sm_lpfnDlPortWriteUchar = NULL;
      }
    }BOOL CParallelPort::PortPresent(int nPort)
    {
      BOOL bSuccess = FALSE;  //Try to open the port 
      CString sPort;
      sPort.Format(_T("\\\\.\\LPT%d"), nPort);
      HANDLE hPort = ::CreateFile(sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
      if (hPort != INVALID_HANDLE_VALUE)
      {
        bSuccess = TRUE;    //Close the port, now that we don't need it anymore
        ::CloseHandle(hPort);
      }
      else
      {
        //Determine if the port exists based on the error code.
        DWORD dwError = GetLastError();    //Check to see if the error was because some other app had the port open or a general failure
        if (dwError == ERROR_ACCESS_DENIED || dwError == ERROR_GEN_FAILURE)
          bSuccess = TRUE;
      }  return bSuccess;
    }BOOL CParallelPort::RunningOnNT()
    {
      OSVERSIONINFO osvi;
      memset(&osvi, 0, sizeof(OSVERSIONINFO));
      osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
      VERIFY(GetVersionEx(&osvi));
      return (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
    }CParallelPortSettings CParallelPort::GetSettings() const
    {
      ASSERT(IsOpen()); //Port must be open 
      return sm_Ports.GetAt(m_nPortIndex);
    }////////// The file transfer classCParallelPortFileTransfer::CParallelPortFileTransfer(CParallelPort* pPort)
    {
      m_pPort = NULL;
      ASSERT(pPort != NULL);
      ASSERT(pPort->IsOpen());  //Ensure the Port is set to SPP mode if it is an ECP port
      CParallelPortSettings settings = pPort->GetSettings();
      if (settings.m_Type == CParallelPortSettings::ParallelTypeECP)
        pPort->SetECPMode(CParallelPortSettings::ECPModeSPP);  //Initialize D3 (strobe) to 1
      pPort->WriteData(0x8);  //Wait for the opposite end to set D3=1 (not busy)
      int S6;
      DWORD dwStartTicks = GetTickCount();
      do
      {
        S6 = (pPort->ReadStatus() & 0x40) >> 6;    //Check the timeout has not elapsed
        if ((GetTickCount() - dwStartTicks) > pPort->GetTimeout())
        {
          TRACE(_T("Could not setup file transfer, other end busy\n"));
          AfxThrowParallelException(ERROR_TIMEOUT);
        }
      }
      while (S6 == 0);  //Store away the port pointer for use in other class methods
      m_pPort = pPort;
    }CParallelPortFileTransfer::~CParallelPortFileTransfer()
    {
      m_pPort = NULL;
    }void CParallelPortFileTransfer::SendFile(const CString& sLocalFile)
    {
      ASSERT(m_pPort); //Initialize failed //For correct operation of the T2A macro, see MFC Tech Note 59
    USES_CONVERSION;  //First try to open the file to send
      CFile file;
      if (file.Open(sLocalFile, CFile::modeRead | CFile::shareDenyWrite))
      {
        //first send the filename (excluding the path) (size if _MAX_PATH)
        TCHAR pszPath[_MAX_PATH];
        TCHAR pszFname[_MAX_FNAME];
        TCHAR pszExt[_MAX_EXT];
        _tsplitpath(sLocalFile, NULL, NULL, pszFname, pszExt);
        _tmakepath(pszPath, NULL, NULL, pszFname, pszExt);    //Now need to convert the filename to ASCII so that a UNICODE
        //client can take to an ASCII server
        char pszAsciiPath[_MAX_PATH];
        char* pszTemp = T2A(pszPath);
        ZeroMemory(pszAsciiPath, _MAX_PATH);
        strcpy(pszAsciiPath, pszTemp);    //Do the actual send of the filename
        if (!m_pPort->WriteUsingNibbleMode(pszAsciiPath, _MAX_PATH))
        {
          TRACE(_T("Failed to send the filename\n"));
          AfxThrowParallelException(ERROR_TIMEOUT);
        }    try
        {
          //Then send the size of the file (as 4 bytes).
          DWORD dwLength = file.GetLength();
          if (!m_pPort->WriteUsingNibbleMode(&dwLength, sizeof(DWORD)))
          {
            TRACE(_T("Failed to send the file length\n"));
            AfxThrowParallelException(ERROR_TIMEOUT);
          }      //Then the actual file contents ifself (4k at a time)
          BYTE byData[4096];
          int nBytesRead;
          do
          {
            nBytesRead = file.Read(byData, 4096);
            if (!m_pPort->WriteUsingNibbleMode(byData, nBytesRead))
            {
              TRACE(_T("Failed to send the file contents\n"));
              AfxThrowParallelException(ERROR_TIMEOUT);
            }
          }
          while (nBytesRead);
        }
        catch(CFileException* pEx)
        {
          TRACE(_T("An error occurred reading from the file to send\n"));
          delete pEx;
          AfxThrowParallelException();
        }
      }
      else
      {
        TRACE(_T("Could not open the file to send, %s\n"), sLocalFile);
        AfxThrowParallelException();
      }
    }void CParallelPortFileTransfer::ReceiveFile(const CString& sLocalFile)
    {
    //For correct operation of the T2A macro, see MFC Tech Note 59
    USES_CONVERSION;  //First try to open the file to send
      CFile file;
      if (file.Open(sLocalFile, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite))
      {
        //Receive the filename
        char pszAsciiPath[_MAX_PATH];
        if (!m_pPort->ReadUsingNibbleMode(pszAsciiPath, _MAX_PATH))
        {
          TRACE(_T("Failed to receive the filename\n"));      //Delete the local file
          file.Close();
          DeleteFile(sLocalFile);      //Throw the exception
          AfxThrowParallelException(ERROR_TIMEOUT);
        }    try
        {
          //Receive the size of the file (as 4 bytes).
          DWORD dwLength;
          if (!m_pPort->ReadUsingNibbleMode(&dwLength, sizeof(DWORD)))
          {
            TRACE(_T("Failed to receive the file length\n"));
      
            //Delete the local file
            file.Close();
            DeleteFile(sLocalFile);        //Throw the exception
            AfxThrowParallelException(ERROR_TIMEOUT);
          }      //Then the actual file contents ifself (4k at a time)
          BYTE byData[4096];
          DWORD dwBytesLeft = dwLength;
          do
          {
            DWORD dwBytesToRead;
            if (dwBytesLeft > 4096)
              dwBytesToRead = 4096;
            else
              dwBytesToRead = dwBytesLeft;
              
            if (!m_pPort->ReadUsingNibbleMode(byData, dwBytesToRead))
            {
              TRACE(_T("Failed to receive the file contents\n"));          //Delete the local file
              file.Close();
              DeleteFile(sLocalFile);          //Throw the exception
              AfxThrowParallelException(ERROR_TIMEOUT);
            }        file.Write(byData, dwBytesToRead);
            dwBytesLeft -= dwBytesToRead;
          }
          while (dwBytesLeft);
        }
        catch(CFileException* pEx)
        {
          TRACE(_T("An error occurred writing the file which was being received\n"));
          delete pEx;
          AfxThrowParallelException();
        }
      }
      else
      {
        TRACE(_T("Could not open the file to receive into, %s\n"), sLocalFile);
        AfxThrowParallelException();
      }
    }
      

  12.   

    http://www.programsalon.com/download.asp?type_id=28&pos=20