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

📄 wceloaderdlg.cpp

📁 evc下的程序加载器
💻 CPP
字号:
// WCELoaderDlg.cpp : implementation file
//

#include "stdafx.h"
#include "WCELoader.h"
#include "WCELoaderDlg.h"
#include "Tlhelp32.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CWCELoaderDlg dialog

CWCELoaderDlg::CWCELoaderDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CWCELoaderDlg::IDD, pParent)
	, WCEReadMWD("\\FlashDisk\\NGN\\WCEReadMWD.exe")
	, TempFileCOM("\\FlashDisk\\NGN\\WCEReadMWD_COM.exe")
	, USBFile("\\硬盘\\WCEReadMWD.exe")
	, CFFile("\\存储卡\\WCEReadMWD.exe")
	, Comx("COM1:")
{
	//{{AFX_DATA_INIT(CWCELoaderDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CWCELoaderDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CWCELoaderDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CWCELoaderDlg, CDialog)
	//{{AFX_MSG_MAP(CWCELoaderDlg)
	ON_WM_TIMER()
	ON_WM_CANCELMODE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWCELoaderDlg message handlers

BOOL CWCELoaderDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	CRect r;
	GetDlgItem(IDC_STATIC_BACK)->GetClientRect(&r);
	MoveWindow(&r);

	CenterWindow(GetDesktopWindow());	// center to the hpc screen

#ifdef _DEBUG
	SetTimer(1, 3000, NULL);	// WinCE不能使用0号
#else
	SetTimer(2, 1000, NULL);	// WinCE不能使用0号
#endif

	return TRUE;  // return TRUE  unless you set the focus to a control
}

BOOL CWCELoaderDlg::Update()
{
	// 检测U盘文件版本
	if (GetFileVersion(USBFile) > GetFileVersion(WCEReadMWD))
	{
		UpdateFile(WCEReadMWD, USBFile);
		return TRUE;
	}
	else
	{
		// 检测CF卡文件版本
		if (GetFileVersion(CFFile) > GetFileVersion(WCEReadMWD))
		{
			UpdateFile(WCEReadMWD, CFFile);
			return TRUE;
		}
		else
		{
			// 检测COM1更新信号
			if (UpdateFromCOM(TempFileCOM))
			{
				UpdateFile(WCEReadMWD, TempFileCOM);
				DeleteFile(TempFileCOM);		// 删除临时文件
				return TRUE;
			}
		}
	}
	return FALSE;
}

BOOL CWCELoaderDlg::UpdateFile(CString FileName, CString srcFile)
{
	// 如果正在运行,则结束进程
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
	PROCESSENTRY32 uProcess;

	uProcess.dwSize = sizeof(uProcess);
	BOOL b = Process32First(hSnapShot, &uProcess);
	while (b)
	{
		if (wcsstr(FileName,uProcess.szExeFile))		// TODO:这个方法不是太好,szExeFile不保险。但由于一般不会误杀进程(除非同名),故先用着。
		{
			HANDLE hProcess = OpenProcess(PROCESS_TERMINATE,FALSE,uProcess.th32ProcessID);
			TerminateProcess(hProcess, 0);
		}
		b = Process32Next(hSnapShot, &uProcess);
	}
	Sleep(1000);		// 结束进程后,等待1秒钟,给系统时间清理垃圾。
	
	SetFileAttributes(FileName, GetFileAttributes(FileName) & ~FILE_ATTRIBUTE_READONLY);	// 去掉只读属性

	// 覆盖文件
	if (!CopyFile(srcFile, FileName, FALSE))
	{
		return FALSE;
	}

	return TRUE;
}

BOOL CWCELoaderDlg::UpdateFromCOM(CString file)
{
	HANDLE hCom;
	hCom = CreateFile(Comx, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
	if (hCom == INVALID_HANDLE_VALUE)
		return FALSE;

	DCB dcb;
	GetCommState(hCom, &dcb);
	dcb.BaudRate = 9600;		// 波特率:9600 (For 485总线)
	dcb.ByteSize = 8;			// 数据位数:8位
	dcb.Parity = NOPARITY;		// 奇偶校验:无
	dcb.StopBits = 1;			// 停止位:1
	SetCommState(hCom, &dcb);
	SetupComm(hCom, 1024, 1024);
	PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);

	COMMTIMEOUTS tout;
	memset(&tout, 0, sizeof(tout));
	tout.ReadTotalTimeoutConstant = 100;		// 读超时100毫秒
	SetCommTimeouts(hCom, &tout);

	char readBuffer[1024];
	char writeBuffer[1024];
	DWORD wCount;		// 读取的字节数

	memset(readBuffer, 0, sizeof(readBuffer));
	memset(writeBuffer, 0, sizeof(writeBuffer));

	if (!ReadFile(hCom, readBuffer, 50, &wCount, NULL))
	{
		CloseHandle(hCom);
		return FALSE;
	}

	if(wCount > 0)		// 收到数据
	{
		if (strstr(readBuffer, "UPDATE"))
		{
			// 同步
			tout.ReadTotalTimeoutConstant = 60000;		// 读超时60秒
			SetCommTimeouts(hCom, &tout);

			DWORD stime = GetTickCount();
			while (TRUE)
			{
				if (GetTickCount() - stime > 60000)	//	60秒放弃
				{
					CloseHandle(hCom);
					return FALSE;
				}

				// 接收ACK信号
				PurgeComm(hCom, PURGE_RXCLEAR);
				ReadFile(hCom,readBuffer,3,&wCount,NULL);
				if (wCount == 3)
				{
					readBuffer[3] = '\0';
					if (strcmp(readBuffer, "ACK") == 0)
					{
						break;						// 接收到ACK后跳出while,准备接收文件
					}
				}

				// 发送SYN信号
				strcpy(writeBuffer,"SYN\r\n");
				WriteFile(hCom,writeBuffer,4,&wCount,NULL);
			}

			// 同步成功,发送READY,接收文件
			strcpy(writeBuffer,"READY\r\n");
			WriteFile(hCom,writeBuffer,5,&wCount,NULL);

			// 创建临时文件
			HANDLE hFile = CreateFile(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hFile == INVALID_HANDLE_VALUE)
			{
				CloseHandle(hCom);
				return FALSE;
			}

			// 清空输入缓冲
			PurgeComm(hCom, PURGE_RXCLEAR);
			while (TRUE)
			{
				if (!ReadFile(hCom, readBuffer, 1024, &wCount, NULL))
				{
					CloseHandle(hFile);
					CloseHandle(hCom);
					return FALSE;
				}
				if (wCount > 0)
				{
					tout.ReadTotalTimeoutConstant = 100;		// 读超时100毫秒
					SetCommTimeouts(hCom, &tout);

					DWORD wWritten;
					WriteFile(hFile, readBuffer, wCount, &wWritten, NULL);
				}
				else
				{
					break;		// 不管是否发送了文件,都可以返回TRUE
				}
			}

			CloseHandle(hFile);
			CloseHandle(hCom);
			return TRUE;
		}
	}

	CloseHandle(hCom);
	return FALSE;
}

INT64 CWCELoaderDlg::GetFileVersion(CString strFileName)
{
	DWORD dwLen = GetFileVersionInfoSize(strFileName.GetBuffer(256),NULL);
	if (dwLen == 0)
	{
		return 0;
	}

	LPVOID lpData = new wchar_t[dwLen +1];
	if (!GetFileVersionInfo(strFileName.GetBuffer(256),NULL,dwLen,lpData))
	{
		delete lpData;
		return 0;
	}

	unsigned int len;
	VS_FIXEDFILEINFO *lpVerInfo;
	if (!VerQueryValue(lpData,_T("\\"),(void **)&lpVerInfo,&len))
	{
		delete lpData;
		return 0;
	}

	INT64 FileVer = lpVerInfo->dwFileVersionMS;
	FileVer <<= 32;
	FileVer += lpVerInfo->dwFileVersionLS;

	delete lpData;

	return FileVer;
}

void CWCELoaderDlg::RunExec(unsigned short *sExe)
{
	STARTUPINFO si={0};
	si.cb = sizeof(si);
	PROCESS_INFORMATION pi;
	if (!CreateProcess(sExe, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
	{
		DWORD dwError;
		dwError = GetLastError();
		CString strErrorCause;
		strErrorCause.Format(_T("启动错误:%d"), dwError);
#ifdef _DEBUG
		SetTimer(4,1000,NULL);		// 1秒后模拟回车
#else
		SetTimer(3,3000,NULL);		// 3秒后退出
#endif
		MessageBox(strErrorCause);
		return;
	}
	ShowWindow(SW_HIDE);
}

void CWCELoaderDlg::OnTimer(UINT nIDEvent) 
{
	switch (nIDEvent)
	{
	case 1:		// DEBUG版
		{
			KillTimer(1);

			// 加载目标程序
			RunExec(WCEReadMWD.GetBuffer(256));

			SetTimer(5,3000,NULL);		// 不断检测更新
		}
		break;
	case 2:		// Release版
		{
			KillTimer(2);

			// 更新文件
			Update();

			// 加载目标程序
			RunExec(WCEReadMWD.GetBuffer(256));

			// 退出
			PostQuitMessage(0);
		}
		break;
	case 3:		// 退出程序
		{
			PostQuitMessage(0);
		}
		break;
	case 4:		// 模拟回车
		{
			KillTimer(4);
			keybd_event(VK_RETURN, 0, 0, 0); 
			keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0); 
		}
		break;
	case 5:
		{
			// 更新文件
			if (Update())
			{
				RunExec(WCEReadMWD.GetBuffer(256));
			}
		}
		break;
	default:
		break;
	}

	CDialog::OnTimer(nIDEvent);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -