📄 mp4process.cpp
字号:
#include "stdafx.h"
#include <windows.h>
#include "wmp4player.h"
#include "mp4process.h"
#include "our_msg_queue.h"
static DWORD __stdcall c_receive_thread (LPVOID lpThreadParameter)
{
CMP4Process *mp4 = (CMP4Process *)lpThreadParameter;
mp4->receive_thread();
ExitThread(0);
return 0;
}
CMP4Process::CMP4Process(CString &name)
{
init();
start_process(name);
}
CMP4Process::~CMP4Process(void)
{
m_terminating = 1;
if (kill_process() == FALSE) {
TerminateProcess(m_piProcInfo.hProcess, -1);
}
clean_up_process();
}
void CMP4Process::init(void)
{
m_terminating = 0;
m_receive_thread = NULL;
m_thread_created = FALSE;
m_map_file_write = NULL;
m_to_client_event = NULL;
m_to_client_resp_event = NULL;
m_from_client_event = NULL;
m_from_client_resp_event = NULL;
m_map_file = NULL;
ZeroMemory(&m_piProcInfo, sizeof(m_piProcInfo));
// Set up security attributes for all handles/files
m_saAttr.nLength = sizeof(m_saAttr);
m_saAttr.bInheritHandle = TRUE;
m_saAttr.lpSecurityDescriptor = NULL;
}
BOOL CMP4Process::start_process (CString &name)
{
if (m_thread_created != FALSE) {
return FALSE;
}
ZeroMemory( &m_siStartInfo, sizeof(STARTUPINFO) );
m_siStartInfo.cb = sizeof(STARTUPINFO);
m_map_file = CreateFileMapping((HANDLE)0xFFFFFFFF,
NULL,
PAGE_READWRITE,
0,
2048,
"MP4ThreadToEventFileMap");
if (m_map_file == NULL) {
OutputDebugString("Can't CreateFileMapping\n");
clean_up_process();
return FALSE;
}
m_map_file_write = MapViewOfFile(m_map_file,
FILE_MAP_ALL_ACCESS,
0, 0, 0);
if (m_map_file_write == NULL) {
OutputDebugString("Can't MapViewOfFile");
clean_up_process();
return FALSE;
}
m_to_client_event =
CreateEvent(&m_saAttr, FALSE, FALSE, "MP4GuiToClient");
m_from_client_event =
CreateEvent(&m_saAttr, FALSE, FALSE, "MP4ClientToGui");
m_to_client_resp_event =
CreateEvent(&m_saAttr, FALSE, FALSE, "MP4GuiToClientResp");
m_from_client_resp_event =
CreateEvent(&m_saAttr, FALSE, FALSE, "MP4ClientToGuiResp");
m_stop_receive_thread = 0;
m_receive_thread = CreateThread(NULL, 0, c_receive_thread, this,
0, &m_receive_thread_id);
char buffer[512];
_snprintf(buffer, sizeof(buffer), "%swmp4client.exe \"%s\"",
#ifdef _DEBUG
"win_client\\debug\\",
#else
"",
#endif
name);
m_thread_created = CreateProcess(
#ifdef _DEBUG
"win_client\\debug\\wmp4client.exe",
#else
"wmp4client.exe",
#endif
buffer, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&m_siStartInfo, // STARTUPINFO pointer
&m_piProcInfo); // receives PROCESS_INFORMATION
if (m_thread_created == FALSE) {
char buffer[512];
sprintf(buffer, "Thread error is %d", GetLastError());
AfxMessageBox(buffer);
}
return m_thread_created;
}
int CMP4Process::get_initial_response (msg_initial_resp_t *init_resp,
CString &errmsg)
{
int ret;
ret = WaitForSingleObject(m_to_client_resp_event, 30 * 1000);
if (ret != WAIT_OBJECT_0) {
errmsg = "No response from client process";
} else {
msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
memcpy(init_resp,
pmbox->to_client_mbox,
sizeof(msg_initial_resp_t));
errmsg = ((char *)pmbox->to_client_mbox) + sizeof(msg_initial_resp_t);
return pmbox->from_client_response;
}
return -1;
}
#define CLOSE_AND_CLEAR(a) if ((a) != NULL) { CloseHandle(a); (a) = NULL; }
void CMP4Process::clean_up_process(void)
{
if (m_receive_thread != NULL) {
m_stop_receive_thread = 1;
SetEvent(m_from_client_event);
SetThreadPriority(m_receive_thread, THREAD_PRIORITY_HIGHEST);
WaitForSingleObject(m_receive_thread, INFINITE);
CloseHandle(m_receive_thread);
m_receive_thread = NULL;
}
if (m_thread_created) {
CLOSE_AND_CLEAR(m_to_client_event);
CLOSE_AND_CLEAR(m_to_client_resp_event);
CLOSE_AND_CLEAR(m_from_client_event);
CLOSE_AND_CLEAR(m_from_client_resp_event);
CLOSE_AND_CLEAR(m_piProcInfo.hThread);
CLOSE_AND_CLEAR(m_piProcInfo.hProcess);
if (m_map_file_write != NULL) {
UnmapViewOfFile(m_map_file_write);
m_map_file_write = NULL;
}
CLOSE_AND_CLEAR(m_map_file);
m_thread_created = FALSE;
}
}
bool CMP4Process::send_message (unsigned __int32 message,
unsigned __int64 *retval,
const char *msg_body,
int msg_len)
{
msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
pmbox->to_client_command = message;
if (msg_body != NULL) {
memcpy(pmbox->to_client_mbox,
msg_body,
MIN(msg_len, MBOX_SIZE));
}
pmbox->from_client_response = MBOX_RESP_EMPTY;
ResetEvent(m_to_client_resp_event);
SetEvent(m_to_client_event);
// Now wait for response.
WaitForSingleObject(m_to_client_resp_event, 2 * 1000);
if (pmbox->from_client_response != MBOX_RESP_EMPTY) {
if (retval != NULL) *retval = pmbox->from_client_response;
return (TRUE);
}
return (FALSE);
}
bool CMP4Process::kill_process (void)
{
bool ret;
DWORD timeout;
unsigned __int64 ret_from_client;
if (m_thread_created == FALSE)
return TRUE;
ret = send_message(CLIENT_MSG_TERMINATE, &ret_from_client);
if (ret == FALSE) {
return FALSE;
}
timeout = WaitForSingleObject(m_piProcInfo.hProcess, 10 * 1000);
if (timeout != WAIT_OBJECT_0) {
OutputDebugString("Process didn't terminate\n");
return FALSE;
}
clean_up_process();
return TRUE;
}
void CMP4Process::receive_thread (void)
{
HANDLE wait_handle[2];
int ret;
msg_mbox_t *pmbox = (msg_mbox_t *)m_map_file_write;
while (m_stop_receive_thread == 0) {
wait_handle[0] = m_from_client_event;
wait_handle[1] = m_piProcInfo.hProcess;
ret = WaitForMultipleObjects(2,
wait_handle,
FALSE,
INFINITE);
switch (ret) {
case WAIT_OBJECT_0:
// This sends messages to theApp
char buffer[80];
sprintf(buffer, "Received Message %x from client\n",
pmbox->to_gui_command);
OutputDebugString(buffer);
switch (pmbox->to_gui_command) {
case GUI_MSG_RECEIVED_QUIT:
// Don't use this - release version crashes.
//theApp.PostThreadMessage(WM_CLOSED_SESSION, 0, 0);
theApp.m_pMainWnd->PostMessage(WM_CLOSED_SESSION);
break;
case GUI_MSG_SDL_KEY:
const sdl_event_msg_t *ptr;
ptr = (const sdl_event_msg_t *)pmbox->to_gui_mbox;
((CFrameWnd*) AfxGetApp()->m_pMainWnd)->GetActiveView()->PostMessage(WM_SDL_KEY,
ptr->sym, ptr->mod);
default:
//theApp.PostThreadMessage(WM_USER, 0, 0);
break;
}
pmbox->to_gui_command = BLANK_MSG;
SetEvent(m_from_client_resp_event);
break;
case WAIT_OBJECT_0 + 1:
if (m_terminating == 0)
theApp.m_pMainWnd->PostMessage(WM_SESSION_DIED);
break;
default:
TRACE1("Illegal code %d received in receive thread\n",
ret);
break;
}
#if 0
((CFrameWnd*) AfxGetApp()->m_pMainWnd)->GetActiveView()->PostMessage(WM_CLOSED_SESSION); // This sends messages to MainFrm
if (!theApp.m_pMainWnd->PostMessage(WM_USER)) {
DWORD error = GetLastError();
TRACE1("Can't post message - error %d\n", error);
}
#endif
}
OutputDebugString("Exiting process receive thread\n");
ExitThread(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -