??
字號:
//////////// 文件Parallel.h內容如下://////////////
#ifndef __PARALLEL_H__
#define __PARALLEL_H__
#include "stdio.h"
#include "conio.h"
#include "windows.h"
class CParallel
{
// 構造/析構函數
public:
CParallel();
virtual ~CParallel() {};
// 成員函數
public:
// 打開并口函數,參數傳入設備名,如"LPT1"
virtual LONG Open(LPCTSTR lpszDevice);
// 關閉并口
virtual LONG Close(void);
// 打印數據
virtual LONG PrintString(const void* pData, size_t iLen, DWORD* pdwWritten = 0, DWORD dwTimeout = INFINITE);
virtual LONG PrintString(LPCSTR pString, DWORD* pdwWritten = 0, DWORD dwTimeout = INFINITE);
LONG PrintByte(char data);
// 檢測并口是否已經打開
bool IsOpen(void) const
{
return (m_hFile != 0 && m_hFile != INVALID_HANDLE_VALUE);
}
// 取出最后的錯誤代碼
LONG GetLastError(void) const { return m_lLastError; }
void WriteControl(int nData);
int ReadControl();
void WriteData(int nData);
int ReadData();
int ReadStatus();
protected:
static BOOL RunningOnNT();
inline static void WriteControl(unsigned short nBaseAddress, int nData);
inline static int ReadControl(unsigned short nBaseAddress);
inline static void WriteData(unsigned short nBaseAddress, int nData);
inline static int ReadData(unsigned short nBaseAddress);
inline static int ReadStatus(unsigned short nBaseAddress);
int GetParallelControllerKey(char* parKey);
int GetAddressLptPortInTheRegistry(int myPort);
int GetAddressLptPortInTheMemory(int myPort);
int GetAddressLptPort(int nPort);
// 成員變量
protected:
LONG m_lLastError; // 錯誤代碼
HANDLE m_hFile; // 并口設備句柄
DWORD m_dwTimeout; // 讀寫超時控制(毫秒)
unsigned short m_nBaseAddress; // 并口的基地址
};
#endif // __PARALLEL_H__
///////////// 文件Parallel.cpp內容如下://///////////////////
#include "stdafx.h"
#include "Parallel.h"
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "user32.lib")
CParallel::CParallel()
{
// 初始化成員變量
m_lLastError = ERROR_SUCCESS;
m_hFile = NULL;
m_nBaseAddress = 0;
m_dwTimeout = 1000;
// 如果是Windows NT則打開端口訪問權限
if (RunningOnNT())
{
HANDLE hDriver = CreateFile("\\\\.\\giveio", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hDriver == INVALID_HANDLE_VALUE)
{
m_lLastError = ::GetLastError();
return;
}
CloseHandle(hDriver);
hDriver = NULL;
}
}
LONG CParallel::Open(LPCTSTR lpszDevice)
{
m_lLastError = ERROR_SUCCESS;
// 檢查并口是否已經打開
if (m_hFile)
{
m_lLastError = ERROR_ALREADY_INITIALIZED;
return m_lLastError;
}
// 取得并口的基地址
if (!stricmp(lpszDevice, "LPT1"))
m_nBaseAddress = GetAddressLptPort(1);
else if (!stricmp(lpszDevice, "LPT2"))
m_nBaseAddress = GetAddressLptPort(2);
else if (!stricmp(lpszDevice, "LPT3"))
m_nBaseAddress = GetAddressLptPort(3);
else
{
m_lLastError = ERROR_FILE_NOT_FOUND;
return m_lLastError;
}
// 調用CreateFile 函數打開并口設備,防止其他設備在我們直接操作端口時打開并口
m_hFile = CreateFile(lpszDevice, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
m_hFile = 0;
m_lLastError = ::GetLastError();
return m_lLastError;
}
return m_lLastError;
}
LONG CParallel::Close()
{
m_lLastError = ERROR_SUCCESS;
if (m_hFile == 0)
return m_lLastError;
// 關閉并口設備句柄
::CloseHandle(m_hFile);
m_hFile = 0;
m_nBaseAddress = 0;
return m_lLastError;
}
void CParallel::WriteControl(unsigned short nBaseAddress, int nData)
{
// 控制寄存器偏移量為 nBaseAddress + 2.
// 第 0, 1 & 3 位必須取反
_outp((unsigned short)(nBaseAddress + 2), nData ^ 0xB);
}
int CParallel::ReadControl(unsigned short nBaseAddress)
{
// 控制寄存器偏移量為 nBaseAddress + 2.
// 第 0, 1 & 3 位必須取反
return (_inp((unsigned short)(nBaseAddress + 2)) ^ 0xB);
}
void CParallel::WriteData(unsigned short nBaseAddress, int nData)
{
// 數據寄存器的偏移量即是 nBaseAddress.
_outp(nBaseAddress, nData);
}
int CParallel::ReadData(unsigned short nBaseAddress)
{
// 數據寄存器的偏移量即是 nBaseAddress.
return _inp(nBaseAddress);
}
int CParallel::ReadStatus(unsigned short nBaseAddress)
{
// 狀態寄存器偏移量為 nBaseAddress + 1.
// 第 7 位必須取反
return (_inp((unsigned short)(nBaseAddress + 1)) ^ 0x80);
}
void CParallel::WriteControl(int nData)
{
WriteControl(m_nBaseAddress, nData);
}
int CParallel::ReadControl()
{
return ReadControl(m_nBaseAddress);
}
void CParallel::WriteData(int nData)
{
WriteData(m_nBaseAddress, nData);
}
int CParallel::ReadData()
{
return ReadData(m_nBaseAddress);
}
int CParallel::ReadStatus()
{
return ReadStatus(m_nBaseAddress);
}
LONG CParallel::PrintString(const void* pData, size_t iLen, DWORD* pdwWritten /*= 0*/, DWORD dwTimeout /*= INFINITE*/ )
{
DWORD dwStartTicks = GetTickCount();
for (unsigned int i = 0; i < iLen; i++)
{
// 檢查是否超時
if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
{
m_lLastError = ERROR_TIMEOUT;
return m_lLastError;
}
m_lLastError = PrintByte(((unsigned char*)pData)[i]);
if (ERROR_SUCCESS != m_lLastError)
return m_lLastError;
if (pdwWritten != NULL)
*pdwWritten = i + 1;
}
m_lLastError = ERROR_SUCCESS;
return m_lLastError;
}
LONG CParallel::PrintString(LPCSTR pString, DWORD* pdwWritten /*= 0*/, DWORD dwTimeout /*= INFINITE*/ )
{
return PrintString(pString, strlen(pString), pdwWritten, dwTimeout);
}
LONG CParallel::PrintByte(char data)
{
// 檢測設備是否已經打開
if (m_hFile == 0)
{
m_lLastError = ERROR_INVALID_HANDLE;
return m_lLastError;
}
// 檢測BUSY線是否忙,忙則等待
int S7;
DWORD dwStartTicks = GetTickCount();
do
{
S7 = (ReadStatus() & 0x80) >> 7;
if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
{
m_lLastError = ERROR_TIMEOUT;
return m_lLastError;
}
} while (S7 == 0x1);
// 發數據
WriteData(data);
// 置數據發送完畢Strobe線
int C0 = ReadControl();
C0 &= 0xfe;
WriteControl(C0);
for (int i = 0; i < 1000; i++)
;
C0 |= 0x01;
WriteControl(C0);
// 檢測ACK線
int S6;
do
{
S6 = (ReadStatus() & 0x40) >> 6;
if ((GetTickCount() - dwStartTicks) > m_dwTimeout)
{
m_lLastError = ERROR_TIMEOUT;
return m_lLastError;
}
} while (S6 == 0);
m_lLastError = ERROR_SUCCESS;
return m_lLastError;
}
BOOL CParallel::RunningOnNT()
{
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
return (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
// 以下代碼用于獲取并口的基地址
int CParallel::GetParallelControllerKey(char* parKey)
{
HKEY hKey;
char myData[255];
LONG res;
DWORD mySize;
FILETIME ftLastWriteTime;
if (NULL == parKey)
return (-1);
*parKey = 0;
char myKey[255];
sprintf(myKey, "HARDWARE\\DESCRIPTION\\System");
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, myKey, 0, KEY_READ, &hKey);
if (res != ERROR_SUCCESS)
return (-1);
DWORD dwIndex1;
char myKey1[255];
for (dwIndex1 = 0; dwIndex1 <= 10; dwIndex1++)
{
mySize = sizeof(myData);
res = RegEnumKeyEx(hKey, dwIndex1, myData, &mySize, NULL, NULL, NULL, &ftLastWriteTime);
if (res == ERROR_SUCCESS)
{
strcpy(myKey1, myKey);
strcat(myKey1, "\\");
strcat(myKey1, myData);
HKEY hKey1;
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, myKey1, 0, KEY_READ, &hKey1);
if (res != ERROR_SUCCESS)
return (-1);
DWORD dwIndex2;
char myKey2[255];
for (dwIndex2 = 0; dwIndex2 <= 10; dwIndex2++)
{
mySize = sizeof(myData);
res = RegEnumKeyEx(hKey1, dwIndex2, myData, &mySize, NULL, NULL, NULL, &ftLastWriteTime);
if (res == ERROR_SUCCESS)
{
strcpy(myKey2, myKey1);
strcat(myKey2, "\\");
strcat(myKey2, myData);
HKEY hKey2;
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, myKey2, 0, KEY_READ, &hKey2);
if (res != ERROR_SUCCESS)
return (-1);
DWORD dwIndex3;
for (dwIndex3 = 0; dwIndex3 <= 10; dwIndex3++)
{
mySize = sizeof(myData);
res = RegEnumKeyEx(hKey2, dwIndex3, myData, &mySize, NULL, NULL, NULL, &ftLastWriteTime);
if (res == ERROR_SUCCESS)
{
if (0 == strcmp(myData, "ParallelController"))
{
strcpy(parKey, myKey2);
strcat(parKey, "\\");
strcat(parKey, myData);
return (0);
}
}
}
}
}
}
}
return (-1);
}
int CParallel::GetAddressLptPortInTheRegistry(int myPort)
{
HKEY phkResult;
char myKey[255];
char myData[255];
LONG res;
DWORD mySize;
DWORD myType;
res = GetParallelControllerKey(myKey);
if (res < 0)
return (-1);
sprintf(myData, "%s\\%d", myKey, myPort - 1);
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, myData, 0, KEY_READ, &phkResult);
if (res != ERROR_SUCCESS)
return (-1);
mySize = sizeof(myData);
myType = REG_BINARY;
res = RegQueryValueEx(phkResult, "Configuration Data", NULL, &myType,
(unsigned char*)myData, &mySize);
if (res != ERROR_SUCCESS)
return (-1);
return (myData[0x14] | myData[0x15] << 8);
}
typedef BOOL (CALLBACK *PROCTYPE_Toolhelp32ReadProcessMemory) (DWORD, LPCVOID, LPVOID, DWORD, LPDWORD);
int CParallel::GetAddressLptPortInTheMemory(int myPort)
{
HINSTANCE hDLL = NULL; // Handle to DLL
PROCTYPE_Toolhelp32ReadProcessMemory myProcPointer = NULL;
hDLL = LoadLibrary("kernel32");
if (hDLL == NULL)
return (-1);
myProcPointer = (PROCTYPE_Toolhelp32ReadProcessMemory) GetProcAddress(hDLL, "Toolhelp32ReadProcessMemory");
if (myProcPointer == NULL) /*handle the error*/
{
FreeLibrary(hDLL);
return -1;
}
int portAddresses[] = { 0, 0, 0, 0, 0 };
BOOL rtn = 0;
DWORD cbLen = 0;
rtn = myProcPointer(0, (LPCVOID*)0x408, portAddresses, 8, NULL);
FreeLibrary(hDLL);
if (rtn == 0)
return (-1);
if (portAddresses[myPort - 1] <= 0)
return (-1);
if (portAddresses[myPort - 1] >= 0x1000)
return (-1);
return (portAddresses[myPort - 1]);
}
int CParallel::GetAddressLptPort(int nPort)
{
if ((nPort < 1) || (nPort > 3))
return (-1);
if (RunningOnNT())
return (GetAddressLptPortInTheRegistry(nPort));
return (GetAddressLptPortInTheMemory(nPort));
}
/////////// test.cpp內容如下://////////////////////
#include "parallel.h"
void main()
{
CParallel port;
port.Open("LPT1");
if (port.IsOpen())
{
port.PrintString("abc\n");
port.Close();
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -