#include "StdAfx.h"
#include "MemoryServer.h"
#include <tlhelp32.h>
#include <Shlwapi.h>
#pragma comment(lib, "shlwapi.lib")

#ifdef __TESET__
DWORD IsAppRunning(LPCTSTR lpszAppDir)
{
	if (!lpszAppDir || !PathFileExists(lpszAppDir))
		return 0;

	TString strAppDir = lpszAppDir;
	int nIndex = strAppDir.find_last_of(_T('\\'));
	if (nIndex != TString::npos )
		strAppDir = strAppDir.substr(nIndex+1);

	DWORD dwProcessID = 0;
	PROCESSENTRY32 pe32 = { 0 };

	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (hProcessSnap == NULL)
	{
		ShowSystemErrorInfo(_T("获取进程快照失败"),GetLastError());
		return 0;
	}
	pe32.dwSize = sizeof(PROCESSENTRY32);

	if (Process32First(hProcessSnap, &pe32))
	{
		do
		{
			// szExeFile只是文件名，不知道是否只有win10才这样;
			if (_tcsicmp(strAppDir.c_str(), pe32.szExeFile) == 0)
			{
				dwProcessID = pe32.th32ProcessID;
				break;
			}
		} while (Process32Next(hProcessSnap, &pe32));
	}
	CloseHandle(hProcessSnap);

	return dwProcessID;
}

bool CloseApp(DWORD dwAppId)
{
	if ( dwAppId == 0 )
		return false;

	HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwAppId);
	if (hProcess == NULL)
	{
		ShowSystemErrorInfo(_T("打开进程失败"),GetLastError());
		return false;
	}

	DWORD dwError;
	if (!TerminateProcess(hProcess, 0))
	{
		dwError = GetLastError();
		CloseHandle(hProcess);
		hProcess = NULL;
		return false;
	}

	// 等待进程结束响应;
	if (WAIT_OBJECT_0 != WaitForSingleObject(hProcess, INFINITE))
	{
		CloseHandle(hProcess);
		return false;
	}

	CloseHandle(hProcess);
	hProcess = NULL;

	return true;
}

#endif

CMemoryServer::CMemoryServer(void)
{
}

CMemoryServer::~CMemoryServer(void)
{
}


BOOL CMemoryServer::GetResult()
{
	// 获取返回结果;
	Sleep(50); // 等待客户端响应;
	CMD_Result result;
	do 
	{
		Lock(INFINITE);
		memcpy(&result, m_pMemory, sizeof(CMD_Result));
		Unlock();
		//Sleep(100);
	} while (result.cmdHead.cmdUser != FALSE);
	//WriteTextLog("result:%d",result.bResult);

	return result.bResult;
}

BOOL CMemoryServer::StartApp(LPCTSTR lpAppDir)
{
	if (!lpAppDir || !PathFileExists(lpAppDir))
		return FALSE;

	if ( IsAppRunning(lpAppDir) != 0)
		return TRUE;

	// 启动应用程序;
	//ShellExecute(NULL, "open", pszExePath, NULL, NULL, SW_SHOWNORMAL);
	SHELLEXECUTEINFO sei;
	memset(&sei, 0, sizeof(SHELLEXECUTEINFO));
	sei.cbSize = sizeof(SHELLEXECUTEINFO);
	sei.hwnd = NULL;
	// 普通打开方式：open；若想以管理员身份运行：runas
	sei.lpVerb = _T("runas");
	//sei.fMask = SEE_MASK_NOCLOSEPROCESS;//不设置，则使用默认值;
	sei.lpFile = lpAppDir;
	sei.lpParameters = NULL;
	sei.lpDirectory = NULL;
	sei.nShow = SW_SHOWNORMAL;
	sei.hInstApp = NULL;

	if ( !ShellExecuteEx(&sei) )
	{
		DWORD dw = GetLastError();
		return FALSE;
	}

	if (sei.hProcess)
		CloseHandle(sei.hProcess);

	return TRUE;
}

BOOL CMemoryServer::ShowApp()
{
	Lock(INFINITE);
	// 命令;
	CommandHead cmdHead;
	cmdHead.cmdFlag = 0x7F;
	cmdHead.cmdType = SHOW_APP;
	cmdHead.cmdUser = TRUE;
	cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmdHead, sizeof(CommandHead));
	Unlock();

	return TRUE;
}

BOOL CMemoryServer::HideApp()
{
	Lock(INFINITE);
	// 命令;
	CommandHead cmdHead;
	cmdHead.cmdFlag = 0x7F;
	cmdHead.cmdType = HIDE_APP;
	cmdHead.cmdUser = TRUE;
	cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmdHead, sizeof(CommandHead));
	Unlock();

	return TRUE;
}

BOOL CMemoryServer::ConnectDevice()
{
	Lock(INFINITE);
	// 命令;
	CMD_ConnectDevice cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = CONNECT_DEVICE;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_ConnectDevice));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::DisconnectDevice()
{
	Lock(INFINITE);
	// 命令;
	CMD_ConnectDevice cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = DIS_CONNECT_DEVICE;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_ConnectDevice));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::StreamOpt(BOOL bStartStreaming)
{
	Lock(INFINITE);
	// 命令;
	CMD_StreamOpt cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = bStartStreaming?START_STREAMING:STOP_STREAMING;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.bStartStreaming = bStartStreaming;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_StreamOpt));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::CaptureImageByCount( int nKeepTime, LPCTSTR lpszSaveDir, LPCTSTR lpszPrefix,unsigned short dwImageType )
{
	Lock(INFINITE);
	// 命令;
	CMD_CaputerImage cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = CAPTURE_IMAGE_COUNT;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.dwImageType = dwImageType;
	
	cmd.bContinuType = FALSE;
	cmd.nKeepTime = nKeepTime;
	cmd.nCaputerCount = 0;
	_stprintf_s(cmd.szSaveDir, _T("%s"), lpszSaveDir == NULL ? _T("") : lpszSaveDir);
	_stprintf_s(cmd.szPrefix, _T("%s"), lpszPrefix == NULL ? _T("CD750") : lpszPrefix);
	Replacepath(cmd.szSaveDir);

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_CaputerImage));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::CaptureSingleImage( LPCTSTR lpszSaveDir, unsigned short dwImageType, BOOL IsAutoName )
{
	Lock(INFINITE);
	// 命令;
	CMD_CaputerImage cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = CAPTURE_IMAGE_SINGLE;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.dwImageType = dwImageType;
	
	cmd.IsAutoName = IsAutoName;
	cmd.nKeepTime = 1;
	cmd.nCaputerCount = 0;
	_stprintf_s(cmd.szSaveDir, _T("%s"), lpszSaveDir == NULL ? _T("") : lpszSaveDir);
	Replacepath(cmd.szSaveDir);

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_CaputerImage));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::CaptureImageByTime( int nKeepTime, int nCaputerCount, LPCTSTR lpszSaveDir, LPCTSTR lpszPrefix, unsigned short dwImageType)
{
	Lock(INFINITE);
	// 命令;
	CMD_CaputerImage cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = CAPTURE_IMAGE_TIME;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.dwImageType = dwImageType;
	
	cmd.bContinuType = TRUE;
	cmd.nKeepTime = nKeepTime;
	cmd.nCaputerCount = nCaputerCount;
	_stprintf_s(cmd.szSaveDir, _T("%s"), lpszSaveDir == NULL ? _T("") : lpszSaveDir);
	_stprintf_s(cmd.szPrefix, _T("%s"), lpszPrefix == NULL ? _T("CD750") : lpszPrefix);
	Replacepath(cmd.szSaveDir);

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_CaputerImage));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::StopCaptureImage()
{
	Lock(INFINITE);
	// 命令;
	CommandHead cmdHead;
	cmdHead.cmdFlag = 0x7F;
	cmdHead.cmdType = STOP_CAPTUREIMAGE;
	cmdHead.cmdUser = TRUE;
	cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmdHead, sizeof(CommandHead));
	Unlock();

	// 等待结果;
	// 未实现;

	return TRUE;
}

BOOL CMemoryServer::SynCaptureAudio(LPCTSTR lpszSaveDir)
{
	Lock(INFINITE);
	// 命令;
	CMD_CaputerAudio cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = SYN_CAPTURE_AUDIO;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.dwDuration = 0;
	_stprintf_s(cmd.szSaveDir, _T("%s"), lpszSaveDir);
	Replacepath(cmd.szSaveDir);

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_CaputerAudio));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::AsyCaptureAudio(DWORD dwDuration, LPCTSTR lpszSaveDir)
{
	Lock(INFINITE);
	// 命令;
	CMD_CaputerAudio cmd;
	cmd.cmdHead.cmdFlag = 0x7F;
	cmd.cmdHead.cmdType = ASY_CAPTURE_AUDIO;
	cmd.cmdHead.cmdUser = TRUE;
	cmd.cmdHead.cmdCRC32 = 0;
	cmd.dwDuration = dwDuration;
	_stprintf_s(cmd.szSaveDir, _T("%s"), lpszSaveDir);
	Replacepath(cmd.szSaveDir);

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmd, sizeof(CMD_CaputerAudio));
	Unlock();

	return GetResult();
}

BOOL CMemoryServer::StopCaptureAudio()
{
	Lock(INFINITE);
	// 命令;
	CommandHead cmdHead;
	cmdHead.cmdFlag = 0x7F;
	cmdHead.cmdType = STOP_CAPTUREAUDIO;
	cmdHead.cmdUser = TRUE;
	cmdHead.cmdCRC32 = 0;

	// 清空内存;
	memset(m_pMemory, 0, MEMERY_SIZE);
	// 写入共享内存;
	memcpy(m_pMemory, &cmdHead, sizeof(CommandHead));
	Unlock();

	// 等待结果;
	// 未实现;

	return TRUE;
}