mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-11 14:30:20 -05:00
Merge from dev-FireflyShell branch
This commit is contained in:
142
win32/FireflyShell/ServerEvents.cpp
Normal file
142
win32/FireflyShell/ServerEvents.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
*(C) 2006 Roku LLC
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License Version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* without any warranty; without even the implied warranty of
|
||||
* merchantability or fitness for a particular purpose. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* Please read README.txt in the same directory as this source file for
|
||||
* further license information.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "ServerEvents.h"
|
||||
|
||||
ServerEvents::ServerEvents(Observer *obs) :
|
||||
m_thread(INVALID_HANDLE_VALUE),
|
||||
m_mailslot(INVALID_HANDLE_VALUE),
|
||||
m_obs(obs)
|
||||
{
|
||||
}
|
||||
|
||||
ServerEvents::~ServerEvents()
|
||||
{
|
||||
ATLASSERT(m_mailslot == INVALID_HANDLE_VALUE);
|
||||
ATLASSERT(m_thread == INVALID_HANDLE_VALUE);
|
||||
}
|
||||
|
||||
bool ServerEvents::Start()
|
||||
{
|
||||
ATLASSERT(m_mailslot == INVALID_HANDLE_VALUE);
|
||||
ATLASSERT(m_thread == INVALID_HANDLE_VALUE);
|
||||
ATLASSERT(m_obs != NULL);
|
||||
|
||||
m_mailslot = ::CreateMailslot(_T("\\\\.\\mailslot\\FireflyMediaServer--67A72768-4154-417e-BFA0-FA9B50C342DE"), 0, MAILSLOT_WAIT_FOREVER, NULL);
|
||||
|
||||
if (m_mailslot != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
//m_thread = ::CreateThread(NULL, 0, &StaticThreadProc, this, 0, &thread_id);
|
||||
m_thread = (HANDLE)_beginthreadex(NULL, 0, &StaticThreadProc, this, 0, NULL);
|
||||
if (m_thread == NULL)
|
||||
{
|
||||
// Failed
|
||||
ATLTRACE("beginthreadex failed: %d\n", errno);
|
||||
::CloseHandle(m_mailslot);
|
||||
m_mailslot = INVALID_HANDLE_VALUE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServerEvents::Stop()
|
||||
{
|
||||
ATLASSERT(m_mailslot != INVALID_HANDLE_VALUE);
|
||||
ATLASSERT(m_thread != INVALID_HANDLE_VALUE);
|
||||
|
||||
// Force the thread to give up. This could be done with a separate event
|
||||
// and overlapped IO but this is cheap.
|
||||
CloseHandle(m_mailslot);
|
||||
m_mailslot = INVALID_HANDLE_VALUE;
|
||||
|
||||
// Wait for it to finish.
|
||||
WaitForSingleObject(m_thread, INFINITE);
|
||||
CloseHandle(m_thread);
|
||||
m_thread = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
//DWORD ServerEvents::StaticThreadProc(LPVOID param)
|
||||
unsigned ServerEvents::StaticThreadProc(void *param)
|
||||
{
|
||||
return reinterpret_cast<ServerEvents *>(param)->ThreadProc();
|
||||
}
|
||||
|
||||
DWORD ServerEvents::ThreadProc()
|
||||
{
|
||||
const size_t BUFFER_SIZE = 65536;
|
||||
void *buffer = operator new(BUFFER_SIZE);
|
||||
|
||||
bool finished = false;
|
||||
while (!finished)
|
||||
{
|
||||
DWORD bytes_read;
|
||||
if (ReadFile(m_mailslot, buffer, BUFFER_SIZE, &bytes_read, NULL))
|
||||
{
|
||||
TCHAR *b = (TCHAR *)buffer;
|
||||
b[bytes_read/sizeof(TCHAR)] = 0;
|
||||
ATLTRACE("%ls\n", b);
|
||||
|
||||
OnEvent(buffer, bytes_read);
|
||||
}
|
||||
else
|
||||
{
|
||||
ATLTRACE("Read failed: error %d\n", GetLastError());
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ServerEvents::OnEvent(const void *buffer, size_t bytes_received)
|
||||
{
|
||||
const BYTE *received = reinterpret_cast<const BYTE *>(buffer);
|
||||
|
||||
if (bytes_received >= 12)
|
||||
{
|
||||
UINT32 packet_size = received[0] | (received[1] << 8) | (received[2] << 16) | (received[3] << 24);
|
||||
UINT32 id = received[4] | (received[5] << 8) | (received[6] << 16) | (received[7] << 24);
|
||||
UINT32 intval = received[8] | (received[9] << 8) | (received[10] << 16) | (received[11] << 24);
|
||||
|
||||
size_t string_length = bytes_received - 12;
|
||||
|
||||
if ((packet_size < bytes_received) && (packet_size >= 12))
|
||||
string_length = packet_size - 12;
|
||||
|
||||
CString str;
|
||||
if (string_length > 0)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
// It might be less that string_length long after conversion but it shouldn't be more unless
|
||||
// our codepage is extremely weird.
|
||||
|
||||
str.ReleaseBuffer(MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, reinterpret_cast<const char *>(received + 12),
|
||||
string_length, str.GetBufferSetLength(string_length), string_length));
|
||||
#else
|
||||
SafeStringCopy(str.GetBufferSetLength(string_length), received + 12, string_length);
|
||||
#endif
|
||||
str.ReleaseBuffer(string_length);
|
||||
}
|
||||
|
||||
m_obs->OnServerEvent(id, intval, str);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user