⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 一些汇编例子
💻
字号:
//////////// 文件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 + -