mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-24 13:13:17 -05:00
Merge from dev-FireflyShell branch
This commit is contained in:
parent
0a14704fd9
commit
7f08580a24
@ -11,6 +11,9 @@ void plugin_handler(int, int, void *, int);
|
||||
|
||||
#define PIPE_BUFFER_SIZE 4096
|
||||
|
||||
#define USE_UDP 0
|
||||
#define USE_MAILSLOT 1
|
||||
|
||||
/* Globals */
|
||||
PLUGIN_EVENT_FN _pefn = { plugin_handler };
|
||||
PLUGIN_INPUT_FN *_ppi;
|
||||
@ -40,6 +43,7 @@ PLUGIN_INFO *plugin_info(PLUGIN_INPUT_FN *ppi) {
|
||||
return &_pi;
|
||||
}
|
||||
|
||||
#if USE_UDP
|
||||
/** NO LOG IN HERE! We'll go into an endless loop. :) */
|
||||
void plugin_handler(int event_id, int intval, void *vp, int len) {
|
||||
int total_len = 3 * sizeof(int) + len + 1;
|
||||
@ -76,3 +80,44 @@ void plugin_handler(int event_id, int intval, void *vp, int len) {
|
||||
free(pmsg);
|
||||
return;
|
||||
}
|
||||
#endif /* USE_UDP */
|
||||
|
||||
#if USE_MAILSLOT
|
||||
#define MAILSLOT_NAME "\\\\.\\mailslot\\FireflyMediaServer--67A72768-4154-417e-BFA0-FA9B50C342DE"
|
||||
/** NO LOG IN HERE! We'll go into an endless loop. :) */
|
||||
void plugin_handler(int event_id, int intval, void *vp, int len) {
|
||||
HANDLE h = CreateFile(MAILSLOT_NAME, GENERIC_WRITE,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (h != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD bytes_written;
|
||||
const int packet_size = 12 + len;
|
||||
unsigned char *buffer = (unsigned char *)malloc(packet_size);
|
||||
if(!buffer)
|
||||
return;
|
||||
memset(buffer, 0, packet_size);
|
||||
|
||||
buffer[0] = packet_size & 0xff;
|
||||
buffer[1] = (packet_size >> 8) & 0xff;
|
||||
buffer[2] = (packet_size >> 16) & 0xff;
|
||||
buffer[3] = (packet_size >> 24) & 0xff;
|
||||
|
||||
buffer[4] = event_id & 0xff;
|
||||
buffer[5] = (event_id >> 8) & 0xff;
|
||||
buffer[6] = (event_id >> 16) & 0xff;
|
||||
buffer[7] = (event_id >> 24) & 0xff;
|
||||
|
||||
buffer[8] = intval & 0xff;
|
||||
buffer[9] = (intval >> 8) & 0xff;
|
||||
buffer[10] = (intval >> 16) & 0xff;
|
||||
buffer[11] = (intval >> 24) & 0xff;
|
||||
|
||||
memcpy(buffer + 12, vp, len);
|
||||
|
||||
/* If this fails then there's nothing we can do about it anyway. */
|
||||
WriteFile(h, buffer, packet_size, &bytes_written, NULL);
|
||||
CloseHandle(h);
|
||||
}
|
||||
}
|
||||
#endif /* USE_MAILSLOT */
|
||||
|
133
win32/FireflyShell/AboutPage.cpp
Normal file
133
win32/FireflyShell/AboutPage.cpp
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
*(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 "AboutPage.h"
|
||||
#include "FireflyShell.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "DosPath.h"
|
||||
|
||||
LRESULT CAboutPage::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
// Do this before we try and use the controls.
|
||||
DoDataExchange(false);
|
||||
|
||||
FillVersionList();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAboutPage::FillVersionList()
|
||||
{
|
||||
m_versions.Empty();
|
||||
|
||||
// Initialise the list control
|
||||
CString str;
|
||||
str.LoadString(IDS_VERSIONINFO_DESCRIPTION);
|
||||
m_list.AddColumn(str, SUBITEM_DESCRIPTION);
|
||||
str.LoadString(IDS_VERSIONINFO_VERSION);
|
||||
m_list.AddColumn(str, SUBITEM_VERSION, 1);
|
||||
str.LoadString(IDS_VERSIONINFO_PATH);
|
||||
m_list.AddColumn(str, SUBITEM_PATH, 2);
|
||||
|
||||
m_list.SetColumnWidth(SUBITEM_DESCRIPTION, 40);
|
||||
m_list.SetColumnWidth(SUBITEM_VERSION, 40);
|
||||
|
||||
CDosPath server_path(GetApplication()->GetServiceBinaryPath());
|
||||
AddEntry(server_path.GetPath(), _T("Firefly server"));
|
||||
AddEntry(CDosPath::AppPath().GetPath(), _T("FireflyShell"));
|
||||
|
||||
CString plugins_path = server_path.GetPathOnly() + _T("plugins\\");
|
||||
CString plugins_pattern = plugins_path + _T("*.dll");
|
||||
WIN32_FIND_DATA find;
|
||||
HANDLE hFind = FindFirstFile(plugins_pattern, &find);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
AddEntry(plugins_path + find.cFileName, CString(find.cFileName) + _T(" plugin"));
|
||||
} while (FindNextFile(hFind, &find));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
||||
for(int i = 0; i < SUBITEM_COUNT; ++i)
|
||||
{
|
||||
m_list.SetColumnWidth(i, m_column_widths[i] + 16);
|
||||
}
|
||||
}
|
||||
|
||||
void CAboutPage::AddEntry(const TCHAR *path, const TCHAR *fallback_description)
|
||||
{
|
||||
VersionInfo vi;
|
||||
|
||||
CString description = fallback_description;
|
||||
CString version;
|
||||
|
||||
if (vi.Open(path))
|
||||
{
|
||||
description = vi.GetFileDescription();
|
||||
version = vi.GetFileVersion();
|
||||
}
|
||||
|
||||
int item = m_list.GetItemCount();
|
||||
AddItem(item, SUBITEM_DESCRIPTION, description);
|
||||
AddItem(item, SUBITEM_VERSION, version);
|
||||
AddItem(item, SUBITEM_PATH, path);
|
||||
|
||||
CString line;
|
||||
line.Format(_T("%s\t%s\t%s\r\n"), description, version, path);
|
||||
m_versions += line;
|
||||
}
|
||||
|
||||
void CAboutPage::AddItem(int item, int subitem, const TCHAR *text)
|
||||
{
|
||||
m_list.AddItem(item, subitem, text);
|
||||
const int width = m_list.GetStringWidth(text);
|
||||
if (width > m_column_widths[subitem])
|
||||
m_column_widths[subitem] = width;
|
||||
}
|
||||
|
||||
LRESULT CAboutPage::OnWebsite(WORD, WORD, HWND, BOOL &)
|
||||
{
|
||||
const TCHAR *url = _T("http://www.fireflymediaserver.org/");
|
||||
::ShellExecute(m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CAboutPage::OnCopy(WORD, WORD, HWND, BOOL &)
|
||||
{
|
||||
if (OpenClipboard())
|
||||
{
|
||||
const size_t len = m_versions.GetLength() * sizeof(TCHAR);
|
||||
|
||||
HGLOBAL h = ::GlobalAlloc(GMEM_MOVEABLE, len);
|
||||
if (h)
|
||||
{
|
||||
void *buffer = ::GlobalLock(h);
|
||||
memcpy(buffer, static_cast<const TCHAR *>(m_versions), len);
|
||||
::GlobalUnlock(h);
|
||||
|
||||
EmptyClipboard();
|
||||
#if defined(UNICODE)
|
||||
SetClipboardData(CF_UNICODETEXT, h);
|
||||
#else
|
||||
SetClipboardData(CF_TEXT, h);
|
||||
#endif
|
||||
}
|
||||
CloseClipboard();
|
||||
}
|
||||
return 0;
|
||||
}
|
72
win32/FireflyShell/AboutPage.h
Normal file
72
win32/FireflyShell/AboutPage.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef ABOUTPAGE_H
|
||||
#define ABOUTPAGE_H 1
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
class CAboutPage :
|
||||
public CPropertyPageImpl<CAboutPage>,
|
||||
public CWinDataExchange<CAboutPage>
|
||||
{
|
||||
typedef CPropertyPageImpl<CAboutPage> base;
|
||||
CListViewCtrl m_list;
|
||||
enum
|
||||
{
|
||||
SUBITEM_DESCRIPTION = 0,
|
||||
SUBITEM_VERSION = 1,
|
||||
SUBITEM_PATH = 2,
|
||||
SUBITEM_COUNT = 3
|
||||
};
|
||||
|
||||
int m_column_widths[SUBITEM_COUNT];
|
||||
|
||||
// String version of information ready to write to the clipboard
|
||||
CString m_versions;
|
||||
|
||||
public:
|
||||
CAboutPage()
|
||||
{
|
||||
::ZeroMemory(m_column_widths, sizeof(m_column_widths));
|
||||
}
|
||||
enum { IDD = IDD_PAGE_ABOUT };
|
||||
|
||||
private:
|
||||
|
||||
// Message Handlers
|
||||
BEGIN_MSG_MAP(CAboutPage)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_ID_HANDLER(IDC_WEBSITE, OnWebsite)
|
||||
COMMAND_ID_HANDLER(IDC_COPY, OnCopy)
|
||||
CHAIN_MSG_MAP(base)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DDX_MAP(CAboutPage)
|
||||
DDX_CONTROL_HANDLE(IDC_VERSIONLIST, m_list)
|
||||
END_DDX_MAP()
|
||||
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnWebsite(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnCopy(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
|
||||
void FillVersionList();
|
||||
void AddEntry(const TCHAR *path, const TCHAR *fallback_description);
|
||||
|
||||
void AddItem(int item, int subitem, const TCHAR *text);
|
||||
};
|
||||
|
||||
#endif // ABOUTPAGE_H
|
167
win32/FireflyShell/AdvancedPage.cpp
Normal file
167
win32/FireflyShell/AdvancedPage.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
*(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 "AdvancedPage.h"
|
||||
#include "IniFile.h"
|
||||
#include "FireflyShell.h"
|
||||
|
||||
LRESULT CAdvancedPage::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
IniFile ini(GetApplication()->GetConfigPath());
|
||||
m_server_port = ini.GetInteger(_T("general"), _T("port"), 9999);
|
||||
|
||||
DoDataExchange(false);
|
||||
m_port_spin.SetRange32(1, 65535);
|
||||
|
||||
switch (GetApplication()->IsAutoStartEnabled())
|
||||
{
|
||||
case 0:
|
||||
m_autostart_check.SetCheck(BST_UNCHECKED);
|
||||
break;
|
||||
case 1:
|
||||
m_autostart_check.SetCheck(BST_CHECKED);
|
||||
break;
|
||||
case 2:
|
||||
// Be sneaky here. Make it capable of showing indeterminate but
|
||||
// don't make it automatically change on click. We'll revert
|
||||
// to a normal checkbox when the click happens.
|
||||
m_autostart_check.SetButtonStyle(BS_3STATE);
|
||||
m_autostart_check.SetCheck(BST_INDETERMINATE);
|
||||
break;
|
||||
}
|
||||
UpdateControls();
|
||||
|
||||
GetApplication()->ServiceStatusSubscribe(this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAdvancedPage::OnDestroy()
|
||||
{
|
||||
GetApplication()->ServiceStatusUnsubscribe(this);
|
||||
}
|
||||
|
||||
void CAdvancedPage::UpdateControls()
|
||||
{
|
||||
Service::Status status = GetApplication()->GetServiceStatus();
|
||||
UpdateControls(status);
|
||||
}
|
||||
|
||||
void CAdvancedPage::UpdateControls(Service::Status status)
|
||||
{
|
||||
UINT state_id;
|
||||
if (status.IsPending())
|
||||
{
|
||||
state_id = IDS_SERVER_PENDING;
|
||||
GetDlgItem(IDC_STARTSERVICE).ShowWindow(SW_HIDE);
|
||||
GetDlgItem(IDC_STOPSERVICE).ShowWindow(SW_HIDE);
|
||||
}
|
||||
else if (status.IsRunning())
|
||||
{
|
||||
state_id = IDS_SERVER_RUNNING;
|
||||
GetDlgItem(IDC_STARTSERVICE).ShowWindow(SW_HIDE);
|
||||
GetDlgItem(IDC_STOPSERVICE).ShowWindow(SW_SHOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
state_id = IDS_SERVER_STOPPED;
|
||||
GetDlgItem(IDC_STARTSERVICE).ShowWindow(SW_SHOW);
|
||||
GetDlgItem(IDC_STOPSERVICE).ShowWindow(SW_HIDE);
|
||||
}
|
||||
|
||||
const bool can_configure = GetApplication()->CanConfigure();
|
||||
GetDlgItem(IDC_SERVERPORT).EnableWindow(can_configure);
|
||||
GetDlgItem(IDC_PORTSPIN).EnableWindow(can_configure);
|
||||
|
||||
// If we can't control the service then don't give the user
|
||||
// the impression that we can.
|
||||
const bool can_control = GetApplication()->CanControlService();
|
||||
GetDlgItem(IDC_STARTSERVICE).EnableWindow(can_control);
|
||||
GetDlgItem(IDC_STOPSERVICE).EnableWindow(can_control);
|
||||
GetDlgItem(IDC_AUTOSTART).EnableWindow(can_control);
|
||||
|
||||
CString state;
|
||||
state.LoadString(state_id);
|
||||
if (!can_control)
|
||||
{
|
||||
CString s;
|
||||
s.LoadString(IDS_NOT_ADMIN);
|
||||
state += " ";
|
||||
state += s;
|
||||
}
|
||||
|
||||
GetDlgItem(IDC_SERVERSTATE).SetWindowText(state);
|
||||
}
|
||||
|
||||
int CAdvancedPage::OnApply()
|
||||
{
|
||||
ATLTRACE("CAdvancedPage::OnApply\n");
|
||||
|
||||
if (!DoDataExchange(true))
|
||||
return false;
|
||||
|
||||
IniFile ini(GetApplication()->GetConfigPath());
|
||||
ini.SetInteger(_T("general"), _T("port"), m_server_port);
|
||||
|
||||
switch (m_autostart_check.GetCheck())
|
||||
{
|
||||
case BST_CHECKED:
|
||||
GetApplication()->EnableAutoStart(m_hWnd, true);
|
||||
break;
|
||||
case BST_UNCHECKED:
|
||||
GetApplication()->EnableAutoStart(m_hWnd, false);
|
||||
break;
|
||||
case BST_INDETERMINATE:
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
|
||||
// Incorrectly documented in WTL
|
||||
return true;
|
||||
}
|
||||
|
||||
LRESULT CAdvancedPage::OnStartService(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
GetApplication()->StartService(m_hWnd);
|
||||
UpdateControls();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CAdvancedPage::OnStopService(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
GetApplication()->StopService(m_hWnd);
|
||||
UpdateControls();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CAdvancedPage::OnWebAdmin(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
// Go to the config file because we might not have committed a change yet.
|
||||
IniFile ini(GetApplication()->GetConfigPath());
|
||||
unsigned int port = ini.GetInteger(_T("general"), _T("port"), 9999);
|
||||
|
||||
CString url;
|
||||
url.Format(_T("http://localhost:%u/"), port);
|
||||
|
||||
::ShellExecute(m_hWnd, _T("open"), url, NULL, NULL, SW_SHOWNORMAL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CAdvancedPage::OnServiceStatus(Service::Status old_status, Service::Status new_status)
|
||||
{
|
||||
UpdateControls(new_status);
|
||||
}
|
||||
|
98
win32/FireflyShell/AdvancedPage.h
Normal file
98
win32/FireflyShell/AdvancedPage.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef ADVANCEDPAGE_H
|
||||
#define ADVANCEDPAGE_H 1
|
||||
|
||||
#include "resource.h"
|
||||
#include "ServiceControl.h"
|
||||
|
||||
/// @todo Users shouldn't be able to paste non-numbers into the port number.
|
||||
|
||||
class CAdvancedPage :
|
||||
public CPropertyPageImpl<CAdvancedPage>,
|
||||
public CWinDataExchange<CAdvancedPage>,
|
||||
public ServiceStatusObserver
|
||||
{
|
||||
public:
|
||||
enum { IDD = IDD_PAGE_ADVANCED };
|
||||
|
||||
private:
|
||||
typedef CPropertyPageImpl<CAdvancedPage> base;
|
||||
|
||||
enum ServiceState
|
||||
{
|
||||
Pending = 0,
|
||||
Running = 1,
|
||||
Stopped = 2
|
||||
};
|
||||
|
||||
enum { TIMER_ID = 42 };
|
||||
|
||||
unsigned int m_server_port;
|
||||
CUpDownCtrl m_port_spin;
|
||||
CButton m_autostart_check;
|
||||
|
||||
void UpdateControls(Service::Status status);
|
||||
void UpdateControls();
|
||||
|
||||
// ServiceStatusObserver
|
||||
void OnServiceStatus(Service::Status old_status, Service::Status new_status);
|
||||
|
||||
BEGIN_MSG_MAP(CAdvancedPage)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_HANDLER_EX(IDC_SERVERPORT, EN_CHANGE, OnChange)
|
||||
COMMAND_HANDLER_EX(IDC_AUTOSTART, BN_CLICKED, OnClickAutostart)
|
||||
COMMAND_ID_HANDLER(IDC_STARTSERVICE, OnStartService)
|
||||
COMMAND_ID_HANDLER(IDC_STOPSERVICE, OnStopService)
|
||||
COMMAND_ID_HANDLER(IDC_WEBADMIN, OnWebAdmin)
|
||||
MSG_WM_DESTROY(OnDestroy)
|
||||
CHAIN_MSG_MAP(base)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DDX_MAP(CAdvancedPage)
|
||||
DDX_UINT(IDC_SERVERPORT, m_server_port);
|
||||
DDX_CONTROL_HANDLE(IDC_PORTSPIN, m_port_spin);
|
||||
DDX_CONTROL_HANDLE(IDC_AUTOSTART, m_autostart_check);
|
||||
END_DDX_MAP()
|
||||
|
||||
// MessageHandlers;
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnStartService(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnStopService(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnWebAdmin(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
void OnDestroy();
|
||||
void OnTimer(UINT id, TIMERPROC proc);
|
||||
int OnApply();
|
||||
void OnChange(UINT uCode, int nCtrlID, HWND hwndCtrl)
|
||||
{
|
||||
// Lots of things could have changed.
|
||||
SetModified();
|
||||
}
|
||||
void OnClickAutostart(UINT uCode, int nCtrlID, HWND hwndCtrl)
|
||||
{
|
||||
// When clicked revert to being a normal checkbox in case
|
||||
// we were intermediate.
|
||||
if (m_autostart_check.GetButtonStyle() != BS_AUTOCHECKBOX)
|
||||
{
|
||||
m_autostart_check.SetButtonStyle(BS_AUTOCHECKBOX);
|
||||
m_autostart_check.SetCheck(TRUE);
|
||||
}
|
||||
OnChange(uCode, nCtrlID, hwndCtrl);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ADVANCEDPAGE_H
|
90
win32/FireflyShell/ConfigPage.cpp
Normal file
90
win32/FireflyShell/ConfigPage.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
*(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 "ConfigPage.h"
|
||||
#include "FireflyShell.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
LRESULT CConfigPage::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
IniFile ini(GetApplication()->GetConfigPath());
|
||||
|
||||
m_server_name = ini.GetString(_T("general"), _T("servername"), _T("Firefly media server"));
|
||||
m_media_path = ini.GetString(_T("general"), _T("mp3_dir"), _T("C:\\Music"));
|
||||
m_password = ini.GetString(_T("general"), _T("password"), _T(""));
|
||||
|
||||
// Do this before we try and use the controls.
|
||||
DoDataExchange(false);
|
||||
|
||||
const bool enable_password = !m_password.IsEmpty();
|
||||
m_protect_checkbox.SetCheck(enable_password);
|
||||
EnableControls();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CConfigPage::EnableControls()
|
||||
{
|
||||
const bool enable = GetApplication()->CanConfigure();
|
||||
GetDlgItem(IDC_SERVERNAME).EnableWindow(enable);
|
||||
GetDlgItem(IDC_PATH).EnableWindow(enable);
|
||||
GetDlgItem(IDC_PROTECT).EnableWindow(enable);
|
||||
GetDlgItem(IDC_BROWSE).EnableWindow(enable);
|
||||
|
||||
const bool enable_password = (m_protect_checkbox.GetCheck() != 0) && enable;
|
||||
GetDlgItem(IDC_PASSWORD).EnableWindow(enable_password);
|
||||
GetDlgItem(IDC_PASSWORD_PROMPT).EnableWindow(enable_password);
|
||||
|
||||
}
|
||||
|
||||
int CConfigPage::OnApply()
|
||||
{
|
||||
ATLTRACE("CConfigPage::OnApply\n");
|
||||
if (!DoDataExchange(true))
|
||||
return false;
|
||||
|
||||
IniFile ini(GetApplication()->GetConfigPath());
|
||||
ini.SetString(_T("general"), _T("servername"), m_server_name);
|
||||
ini.SetString(_T("general"), _T("mp3_dir"), m_media_path);
|
||||
ini.SetString(_T("general"), _T("password"), m_password);
|
||||
|
||||
// Incorrectly documented in WTL
|
||||
return true;
|
||||
}
|
||||
|
||||
LRESULT CConfigPage::OnBrowse(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
CFolderDialog folder;
|
||||
|
||||
// Who cares if it fails.
|
||||
DoDataExchange(true);
|
||||
|
||||
folder.SetInitialFolder(m_media_path);
|
||||
|
||||
if (folder.DoModal() == IDOK)
|
||||
{
|
||||
m_media_path = folder.GetFolderPath();
|
||||
DoDataExchange(false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CConfigPage::OnClickProtect(UINT uCode, int nCtrlID, HWND hwndCtrl)
|
||||
{
|
||||
EnableControls();
|
||||
SetModified();
|
||||
}
|
70
win32/FireflyShell/ConfigPage.h
Normal file
70
win32/FireflyShell/ConfigPage.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef CONFIGPAGE_H
|
||||
#define CONFIGPAGE_H 1
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
class CMainDlg;
|
||||
|
||||
class CConfigPage :
|
||||
public CPropertyPageImpl<CConfigPage>,
|
||||
public CWinDataExchange<CConfigPage>
|
||||
{
|
||||
typedef CPropertyPageImpl<CConfigPage> base;
|
||||
|
||||
public:
|
||||
enum { IDD = IDD_PAGE_BASIC };
|
||||
|
||||
private:
|
||||
CString m_media_path;
|
||||
CString m_server_name;
|
||||
CString m_password;
|
||||
CButton m_protect_checkbox;
|
||||
|
||||
void EnableControls();
|
||||
|
||||
BEGIN_MSG_MAP(thisClass)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
COMMAND_ID_HANDLER(IDC_BROWSE, OnBrowse)
|
||||
COMMAND_HANDLER_EX(IDC_PROTECT, BN_CLICKED, OnClickProtect)
|
||||
COMMAND_HANDLER_EX(IDC_PASSWORD, EN_CHANGE, OnChange)
|
||||
COMMAND_HANDLER_EX(IDC_SERVERNAME, EN_CHANGE, OnChange)
|
||||
COMMAND_HANDLER_EX(IDC_PATH, EN_CHANGE, OnChange)
|
||||
CHAIN_MSG_MAP(base)
|
||||
END_MSG_MAP()
|
||||
|
||||
BEGIN_DDX_MAP(CConfigPage)
|
||||
DDX_TEXT(IDC_PATH, m_media_path);
|
||||
DDX_TEXT(IDC_SERVERNAME, m_server_name);
|
||||
DDX_TEXT(IDC_PASSWORD, m_password);
|
||||
DDX_CONTROL_HANDLE(IDC_PROTECT, m_protect_checkbox);
|
||||
END_DDX_MAP()
|
||||
|
||||
// Message handlers
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnBrowse(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
void OnClickProtect(UINT uCode, int nCtrlID, HWND hwndCtrl);
|
||||
int OnApply();
|
||||
void OnChange(UINT uCode, int nCtrlID, HWND hwndCtrl)
|
||||
{
|
||||
// Lots of things could have changed.
|
||||
SetModified();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONFIGPAGE_H
|
173
win32/FireflyShell/DosPath.cpp
Normal file
173
win32/FireflyShell/DosPath.cpp
Normal file
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* (C) 1997, 2006 Mike Crowe
|
||||
*
|
||||
* License: Do what you like with it except claim that you wrote it.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "dospath.h"
|
||||
#include <stdlib.h>
|
||||
#include <direct.h>
|
||||
|
||||
CDosPath::CDosPath(const TCHAR *pszPath, int nFlags)
|
||||
{
|
||||
SetPath(pszPath, nFlags);
|
||||
}
|
||||
|
||||
CDosPath::CDosPath(const CDosPath &old)
|
||||
{
|
||||
m_drive = old.m_drive;
|
||||
m_dir = old.m_dir;
|
||||
m_file = old.m_file;
|
||||
m_ext = old.m_ext;
|
||||
}
|
||||
|
||||
CDosPath &CDosPath::operator=(const CDosPath &old)
|
||||
{
|
||||
m_drive = old.m_drive;
|
||||
m_dir = old.m_dir;
|
||||
m_file = old.m_file;
|
||||
m_ext = old.m_ext;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDosPath::~CDosPath()
|
||||
{
|
||||
}
|
||||
|
||||
void CDosPath::SplitPath(const TCHAR *path)
|
||||
{
|
||||
#if USE_SECURE
|
||||
_tsplitpath_s(path, m_drive.GetBufferSetLength(_MAX_DRIVE), _MAX_DRIVE,
|
||||
m_dir.GetBufferSetLength(_MAX_DIR), _MAX_DIR,
|
||||
m_file.GetBufferSetLength(_MAX_FNAME), _MAX_FNAME,
|
||||
m_ext.GetBufferSetLength(_MAX_EXT), _MAX_EXT);
|
||||
#else
|
||||
_tsplitpath(path, m_drive.GetBufferSetLength(_MAX_DRIVE),
|
||||
m_dir.GetBufferSetLength(_MAX_DIR),
|
||||
m_file.GetBufferSetLength(_MAX_FNAME),
|
||||
m_ext.GetBufferSetLength(_MAX_EXT));
|
||||
#endif
|
||||
|
||||
m_ext.ReleaseBuffer();
|
||||
m_file.ReleaseBuffer();
|
||||
m_dir.ReleaseBuffer();
|
||||
m_drive.ReleaseBuffer();
|
||||
}
|
||||
|
||||
void CDosPath::SetPath(const TCHAR *pszPath, int nFlags)
|
||||
{
|
||||
if (nFlags & PATH_ONLY)
|
||||
{
|
||||
CString temp(pszPath);
|
||||
temp += '\\';
|
||||
SplitPath(temp);
|
||||
}
|
||||
else
|
||||
SplitPath(pszPath);
|
||||
}
|
||||
|
||||
CDosPath &CDosPath::operator|=(CDosPath &fullpath)
|
||||
{
|
||||
if (m_drive.IsEmpty())
|
||||
{
|
||||
// TRACE1("Inserting drive %s\n", fullpath.m_szDrive);
|
||||
m_drive = fullpath.m_drive;
|
||||
}
|
||||
if (m_dir.IsEmpty())
|
||||
{
|
||||
// TRACE1("Inserting directory %s\n", fullpath.m_szDir);
|
||||
m_dir = fullpath.m_dir;
|
||||
}
|
||||
if (m_file.IsEmpty())
|
||||
{
|
||||
// TRACE1("Inserting file %s\n", fullpath.m_szFile);
|
||||
m_file = fullpath.m_file;
|
||||
}
|
||||
if (m_ext.IsEmpty())
|
||||
{
|
||||
// TRACE1("Inserting extension %s\n", fullpath.m_szExt);
|
||||
m_ext = fullpath.m_ext;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CDosPath CDosPath::operator|(CDosPath &fullpath)
|
||||
{
|
||||
CDosPath temp(GetPath());
|
||||
temp |= fullpath;
|
||||
return temp;
|
||||
}
|
||||
|
||||
CString CDosPath::GetPath() const
|
||||
{
|
||||
CString temp;
|
||||
#if USE_SECURE
|
||||
_tmakepath_s(temp.GetBufferSetLength(_MAX_PATH), _MAX_PATH, m_drive, m_dir, m_file, m_ext);
|
||||
#else
|
||||
_tmakepath(temp.GetBufferSetLength(_MAX_PATH), m_drive, m_dir, m_file, m_ext);
|
||||
#endif
|
||||
temp.ReleaseBuffer();
|
||||
return temp;
|
||||
}
|
||||
|
||||
CString CDosPath::GetPathOnly() const
|
||||
{
|
||||
CString temp;
|
||||
#if USE_SECURE
|
||||
_tmakepath_s(temp.GetBufferSetLength(_MAX_PATH), _MAX_PATH, m_drive, m_dir, NULL, NULL);
|
||||
#else
|
||||
_tmakepath(temp.GetBufferSetLength(_MAX_PATH), m_drive, m_dir, NULL, NULL);
|
||||
#endif
|
||||
temp.ReleaseBuffer();
|
||||
return temp;
|
||||
}
|
||||
|
||||
CDosPath CDosPath::CurrentPath()
|
||||
{
|
||||
TCHAR szBuffer[_MAX_PATH];
|
||||
_tgetcwd(szBuffer, _MAX_PATH);
|
||||
return CDosPath(szBuffer, PATH_ONLY);
|
||||
}
|
||||
|
||||
CDosPath CDosPath::AppPath()
|
||||
{
|
||||
TCHAR szBuffer[_MAX_PATH];
|
||||
#ifdef _MFC
|
||||
GetModuleFileName(AfxGetApp()->m_hInstance, szBuffer, _MAX_PATH);
|
||||
#else
|
||||
GetModuleFileName(GetModuleHandle(NULL), szBuffer, _MAX_PATH);
|
||||
#endif
|
||||
return CDosPath(szBuffer);
|
||||
}
|
||||
|
||||
CDosPath CDosPath::WindowsPath()
|
||||
{
|
||||
TCHAR szBuffer[_MAX_PATH];
|
||||
GetWindowsDirectory(szBuffer, _MAX_PATH);
|
||||
return CDosPath(szBuffer, PATH_ONLY);
|
||||
}
|
||||
|
||||
#ifdef MAKE_EXE
|
||||
#include <stdio.h>
|
||||
|
||||
void main(int ac, char *av[])
|
||||
{
|
||||
if (ac != 3)
|
||||
{
|
||||
printf("Usage: dospath incomplete complete\n");
|
||||
return;
|
||||
}
|
||||
CDosPath a = av[1];
|
||||
CDosPath b = av[2];
|
||||
a |= b;
|
||||
printf("%s |= %s = %s\n", av[1], av[2], (const char *) a.GetPath());
|
||||
printf("\n\n\n\n");
|
||||
a = CDosPath::CurrentPath();
|
||||
printf("Current = %s\n", (const char *)a.GetPath());
|
||||
a = CDosPath::AppPath();
|
||||
printf("App = %s\n", (const char *)a.GetPath());
|
||||
a = CDosPath::TempPath();
|
||||
printf("Temp = %s\n", (const char *)a.GetPath());
|
||||
}
|
||||
#endif
|
51
win32/FireflyShell/DosPath.h
Normal file
51
win32/FireflyShell/DosPath.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* (C) 1997, 2006 Mike Crowe
|
||||
*
|
||||
* License: Do what you like with it except claim that you wrote it.
|
||||
*/
|
||||
|
||||
#ifndef DOSPATH_H
|
||||
#define DOSPATH_H
|
||||
|
||||
class CDosPath
|
||||
{
|
||||
CString m_drive;
|
||||
CString m_dir;
|
||||
CString m_file;
|
||||
CString m_ext;
|
||||
|
||||
void SplitPath(const TCHAR *buffer);
|
||||
|
||||
public:
|
||||
enum { PATH_ONLY = 1 };
|
||||
|
||||
CDosPath(const TCHAR *pszPath, int nFlags = 0);
|
||||
CDosPath(const CDosPath &old);
|
||||
~CDosPath();
|
||||
|
||||
CDosPath &operator|=(CDosPath &fullpath);
|
||||
CDosPath operator|(CDosPath &fullpath);
|
||||
|
||||
CDosPath &operator=(const CDosPath &old);
|
||||
CString GetPath() const;
|
||||
CString GetPathOnly() const;
|
||||
void SetPath(const TCHAR *pszBuffer, int nFlags = 0);
|
||||
|
||||
static CDosPath CurrentPath();
|
||||
static CDosPath AppPath();
|
||||
static CDosPath TempPath();
|
||||
#ifdef _WINDOWS
|
||||
static CDosPath WindowsPath();
|
||||
#endif
|
||||
|
||||
CString GetFile()
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
CString GetExt()
|
||||
{
|
||||
return m_ext;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DOSPATH_H
|
373
win32/FireflyShell/FireflyShell.cpp
Normal file
373
win32/FireflyShell/FireflyShell.cpp
Normal file
@ -0,0 +1,373 @@
|
||||
/*
|
||||
*(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 "resource.h"
|
||||
#include "FireflyShell.h"
|
||||
#include "DosPath.h"
|
||||
#include "ServiceControl.h"
|
||||
#include "MainDlg.h"
|
||||
#include "ServerEvents.h"
|
||||
#include "IniFile.h"
|
||||
|
||||
CAppModule _Module;
|
||||
|
||||
#define RUN_KEY _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run")
|
||||
#define RUN_VALUE _T("FireflyShell")
|
||||
|
||||
Application::Application()
|
||||
: m_dlg(NULL), m_server_events(&m_icon)
|
||||
{
|
||||
CDosPath path = CDosPath::AppPath();
|
||||
CDosPath filename(_T("mt-daapd.conf"));
|
||||
filename |= path;
|
||||
m_config_path = filename.GetPath();
|
||||
ATLTRACE("Config path: %s\n", (const TCHAR *)m_config_path);
|
||||
|
||||
// We don't care if this fails. We can deal with that later.
|
||||
m_service.Open(_T("Firefly Media Server"));
|
||||
|
||||
CheckCanConfigure();
|
||||
|
||||
m_unique_name = GenerateUniqueName();
|
||||
m_registered_activation_message = ::RegisterWindowMessage(m_unique_name);
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
ATLASSERT(m_dlg == NULL);
|
||||
}
|
||||
|
||||
void Application::CheckCanConfigure()
|
||||
{
|
||||
IniFile ini(m_config_path);
|
||||
m_configurable = ini.IsWritable();
|
||||
}
|
||||
|
||||
int Application::Run(LPCTSTR lpstrCmdLine, int nCmdShow)
|
||||
{
|
||||
if (ActivatePreviousInstance(lpstrCmdLine, nCmdShow))
|
||||
{
|
||||
ATLTRACE(_T("Already running\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMessageLoop theLoop;
|
||||
_Module.AddMessageLoop(&theLoop);
|
||||
|
||||
if (!m_icon.Create())
|
||||
{
|
||||
ATLTRACE(_T("Icon creation failed!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EnableServerEvents(true);
|
||||
|
||||
if (ShowDialogAtStart(lpstrCmdLine, nCmdShow))
|
||||
Configure();
|
||||
|
||||
int nRet = theLoop.Run();
|
||||
|
||||
EnableServerEvents(false);
|
||||
|
||||
m_icon.Destroy();
|
||||
|
||||
_Module.RemoveMessageLoop();
|
||||
return nRet;
|
||||
}
|
||||
|
||||
void Application::Exit()
|
||||
{
|
||||
if (m_dlg)
|
||||
{
|
||||
m_dlg->DestroyWindow();
|
||||
delete m_dlg;
|
||||
m_dlg = NULL;
|
||||
}
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void Application::Configure()
|
||||
{
|
||||
if (m_dlg)
|
||||
{
|
||||
m_dlg->ShowWindow(SW_RESTORE);
|
||||
SetForegroundWindow(m_dlg->m_hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckCanConfigure();
|
||||
|
||||
// Other people may need to talk to the dialog while it exists.
|
||||
CMainDlg dlg;
|
||||
m_dlg = &dlg;
|
||||
dlg.DoModal();
|
||||
m_dlg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::StartService(HWND hwndParent)
|
||||
{
|
||||
CWaitCursor wc;
|
||||
ATLASSERT(m_service.CanControl());
|
||||
if (!m_service.CanControl())
|
||||
return;
|
||||
|
||||
if (!m_service.StartAndWait())
|
||||
{
|
||||
MessageBox(hwndParent, IDS_SERVERSTARTFAIL, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::StopService(HWND hwndParent)
|
||||
{
|
||||
CWaitCursor wc;
|
||||
ATLASSERT(m_service.CanControl());
|
||||
if (!m_service.CanControl())
|
||||
return;
|
||||
|
||||
if (!m_service.StopAndWait())
|
||||
{
|
||||
MessageBox(hwndParent, IDS_SERVERSTOPFAIL, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::RestartService(HWND hwndParent)
|
||||
{
|
||||
CWaitCursor wc;
|
||||
StopService(hwndParent);
|
||||
StartService(hwndParent);
|
||||
}
|
||||
|
||||
bool Application::ShowDialogAtStart(LPCTSTR cmdline, int nCmdShow)
|
||||
{
|
||||
if ((cmdline[0] == '-') && (cmdline[1] == 'q'))
|
||||
return false;
|
||||
|
||||
switch (nCmdShow)
|
||||
{
|
||||
case SW_RESTORE:
|
||||
case SW_SHOW:
|
||||
case SW_SHOWMAXIMIZED:
|
||||
case SW_SHOWNORMAL:
|
||||
case SW_SHOWDEFAULT:
|
||||
case SW_MAX:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CALLBACK Application::StaticWindowSearcher(HWND hwnd, LPARAM lparam)
|
||||
{
|
||||
DWORD result;
|
||||
LRESULT ok = ::SendMessageTimeout(hwnd,
|
||||
lparam,
|
||||
0, 0,
|
||||
SMTO_BLOCK |
|
||||
SMTO_ABORTIFHUNG,
|
||||
200,
|
||||
&result);
|
||||
if (ok == 0)
|
||||
return TRUE; // ignore this and continue
|
||||
|
||||
// If we get the magic response then we must have found our Window
|
||||
// so we can give up.
|
||||
if (result == lparam)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool Application::ActivatePreviousInstance(LPCTSTR lpstrCmdLine, int nCmdShow)
|
||||
{
|
||||
HANDLE h = ::CreateMutex(NULL, TRUE, m_unique_name);
|
||||
const bool running = (GetLastError() == ERROR_ALREADY_EXISTS);
|
||||
|
||||
if (h != NULL)
|
||||
{
|
||||
::ReleaseMutex(h);
|
||||
}
|
||||
|
||||
// It seems that getting the other window to activate itself does
|
||||
// actually work even though Windows anti-focus-stealing stuff
|
||||
// could try and stop it.
|
||||
if (running && ShowDialogAtStart(lpstrCmdLine, nCmdShow))
|
||||
{
|
||||
EnumWindows(StaticWindowSearcher, m_registered_activation_message);
|
||||
return true;
|
||||
}
|
||||
|
||||
return running;
|
||||
}
|
||||
|
||||
CString Application::GenerateUniqueName()
|
||||
{
|
||||
// We need to allow one instance to run per desktop. See
|
||||
// http://www.codeproject.com/cpp/avoidmultinstance.asp
|
||||
|
||||
// First start with some application unique
|
||||
CString s(_T("Firefly-67A72768-4154-417e-BFA0-FA9B50C342DE"));
|
||||
|
||||
// Now append something desktop unique
|
||||
DWORD len;
|
||||
HDESK desktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
BOOL result = GetUserObjectInformation(desktop, UOI_NAME, NULL, 0, &len);
|
||||
DWORD err = ::GetLastError();
|
||||
if(!result && err == ERROR_INSUFFICIENT_BUFFER)
|
||||
{ /* NT/2000/XP */
|
||||
LPBYTE data = new BYTE[len];
|
||||
result = GetUserObjectInformation(desktop, UOI_NAME, data, len, &len);
|
||||
s += _T("-");
|
||||
s += (LPCTSTR)data;
|
||||
delete [ ] data;
|
||||
} /* NT/2000/XP */
|
||||
else
|
||||
{ /* Win9x */
|
||||
s += _T("-Win9x");
|
||||
} /* Win9x */
|
||||
return s;
|
||||
}
|
||||
|
||||
void Application::EnableServerEvents(bool b)
|
||||
{
|
||||
if (b)
|
||||
m_server_events.Start();
|
||||
else
|
||||
m_server_events.Stop();
|
||||
}
|
||||
|
||||
CString Application::MakeRunKeyValue()
|
||||
{
|
||||
CString required_path("\"");
|
||||
required_path += CDosPath::AppPath().GetPath();
|
||||
required_path += "\" -q";
|
||||
return required_path;
|
||||
}
|
||||
|
||||
void Application::EnableAutoStart(HWND hwnd, bool enable)
|
||||
{
|
||||
// First let's control the service.
|
||||
int required_startup = enable ? SERVICE_AUTO_START : SERVICE_DISABLED;
|
||||
|
||||
if (m_service.GetStartup() != required_startup)
|
||||
{
|
||||
if (!m_service.ConfigureStartup(required_startup))
|
||||
{
|
||||
MessageBox(hwnd, IDS_FAILED_CONFIGURE_SERVICE, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
// Now let's set up the Run key.
|
||||
HKEY hkey;
|
||||
LONG result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, RUN_KEY, 0, KEY_SET_VALUE | STANDARD_RIGHTS_WRITE, &hkey);
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// We need to quote it because the path may contain spaces.
|
||||
CString str = MakeRunKeyValue();
|
||||
result = RegSetValueEx(hkey, RUN_VALUE, 0UL, REG_SZ, reinterpret_cast<LPCBYTE>(static_cast<LPCTSTR>(str)), (str.GetLength() + 1) * sizeof(TCHAR));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = RegDeleteValue(hkey, RUN_VALUE);
|
||||
if (result == ERROR_FILE_NOT_FOUND)
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (result != ERROR_SUCCESS)
|
||||
{
|
||||
ATLTRACE("Error:%u\n", result);
|
||||
MessageBox(hwnd, IDS_FAILED_CONFIGURE_STARTUP, MB_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Application::IsAutoStartEnabled() const
|
||||
{
|
||||
// Look at the service
|
||||
int service_result = 2;
|
||||
switch (m_service.GetStartup())
|
||||
{
|
||||
case SERVICE_AUTO_START:
|
||||
service_result = true;
|
||||
break;
|
||||
case SERVICE_DISABLED:
|
||||
service_result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Look at the Run key
|
||||
int run_result = 2;
|
||||
HKEY hkey;
|
||||
if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, RUN_KEY, 0, KEY_QUERY_VALUE | STANDARD_RIGHTS_READ, &hkey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD dwType, cbData;
|
||||
TCHAR buffer[_MAX_PATH + 1];
|
||||
cbData = (_MAX_PATH + 1) * sizeof(TCHAR);
|
||||
if (::RegQueryValueEx(hkey, RUN_VALUE, NULL, &dwType, reinterpret_cast<LPBYTE>(buffer), &cbData) == ERROR_SUCCESS)
|
||||
{
|
||||
CString path(buffer, cbData - sizeof(TCHAR));
|
||||
ATLTRACE("Registry run key path: %s\n", (const TCHAR *)path);
|
||||
|
||||
if (path == MakeRunKeyValue())
|
||||
run_result = true;
|
||||
else
|
||||
{
|
||||
// It's there - but it isn't us that it will start.
|
||||
run_result = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The key doesn't exist.
|
||||
run_result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
run_result = false;
|
||||
}
|
||||
|
||||
// If the answers agree then return them. Otherwise we're indeterminate.
|
||||
if (run_result == service_result)
|
||||
return run_result;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
|
||||
{
|
||||
// this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used
|
||||
::DefWindowProc(NULL, 0, 0, 0L);
|
||||
|
||||
AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls
|
||||
|
||||
HRESULT hRes = _Module.Init(NULL, hInstance);
|
||||
ATLASSERT(SUCCEEDED(hRes));
|
||||
|
||||
int nRet;
|
||||
{
|
||||
// Application object is destroyed prior to undoing everything above.
|
||||
Application app;
|
||||
nRet = app.Run(lpstrCmdLine, nCmdShow);
|
||||
}
|
||||
|
||||
_Module.Term();
|
||||
return nRet;
|
||||
}
|
154
win32/FireflyShell/FireflyShell.h
Normal file
154
win32/FireflyShell/FireflyShell.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef FIREFLYSHELL_H
|
||||
#define FIREFLYSHELL_H 1
|
||||
|
||||
#include "singleton.h"
|
||||
#include "NotifyIcon.h"
|
||||
#include "ServiceControl.h"
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "ServerEvents.h"
|
||||
|
||||
class CMainDlg;
|
||||
|
||||
/// The main application. Not a window.
|
||||
class Application : public Singleton<Application>
|
||||
{
|
||||
CNotifyIcon m_icon;
|
||||
CMainDlg *m_dlg;
|
||||
CString m_config_path;
|
||||
Service m_service;
|
||||
ServiceStatusMonitor m_service_monitor;
|
||||
ServerEvents m_server_events;
|
||||
CString m_unique_name;
|
||||
UINT m_registered_activation_message;
|
||||
bool m_configurable;
|
||||
|
||||
/// Returns true if a previous instance was found. Only
|
||||
/// actually activates a previous instance if nCmdShow
|
||||
/// indicates so.
|
||||
bool ActivatePreviousInstance(LPCTSTR cmdline, int nCmdShow);
|
||||
|
||||
/// Helper for ActivatePreviousInstance.
|
||||
static BOOL CALLBACK Application::StaticWindowSearcher(HWND hwnd, LPARAM lparam);
|
||||
|
||||
/// Generate a unique name that can be used to detect multiple instances.
|
||||
static CString GenerateUniqueName();
|
||||
|
||||
// Depending on how the application was launched we display the dialog or not.
|
||||
static bool ShowDialogAtStart(LPCTSTR cmdline, int nCmdShow);
|
||||
|
||||
static CString MakeRunKeyValue();
|
||||
|
||||
public:
|
||||
Application();
|
||||
~Application();
|
||||
|
||||
/// Gets the application going
|
||||
int Run(LPCTSTR lpstrCmdLine, int nCmdShow);
|
||||
|
||||
/// mt-daapd.conf path
|
||||
CString GetConfigPath()
|
||||
{
|
||||
return m_config_path;
|
||||
}
|
||||
|
||||
/// Registered message used to activate other instances
|
||||
UINT GetRegisteredActivationMessage() const
|
||||
{
|
||||
return m_registered_activation_message;
|
||||
}
|
||||
|
||||
// User actions
|
||||
void Configure();
|
||||
void Exit();
|
||||
|
||||
// Service control
|
||||
void StartService(HWND hwndParent);
|
||||
void StopService(HWND hwndParent);
|
||||
void RestartService(HWND hwndParent);
|
||||
|
||||
Service::Status GetServiceStatus()
|
||||
{
|
||||
Service::Status status;
|
||||
if (m_service.IsOpen())
|
||||
{
|
||||
m_service.GetStatus(&status);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// Expensive - only do it just before displaying the dialog box.
|
||||
void CheckCanConfigure();
|
||||
|
||||
// Cheap.
|
||||
bool CanConfigure() const
|
||||
{
|
||||
// We need to both rewrite the config file and
|
||||
// control the service if we're going to be
|
||||
// useful.
|
||||
return m_configurable && m_service.CanControl();
|
||||
}
|
||||
|
||||
bool CanControlService() const
|
||||
{
|
||||
return m_service.CanControl();
|
||||
}
|
||||
|
||||
void CheckServiceStatus()
|
||||
{
|
||||
m_service_monitor.Poll(&m_service);
|
||||
}
|
||||
|
||||
void ServiceStatusSubscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
m_service_monitor.Subscribe(obs);
|
||||
}
|
||||
|
||||
void ServiceStatusUnsubscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
m_service_monitor.Unsubscribe(obs);
|
||||
}
|
||||
|
||||
CString GetServiceBinaryPath() const
|
||||
{
|
||||
return m_service.GetBinaryPath();
|
||||
}
|
||||
|
||||
/// Used to disable listening for events from the server when this user is
|
||||
/// not active.
|
||||
void EnableServerEvents(bool);
|
||||
|
||||
/// Enable/disable automatic startup of service and FireflyShell.
|
||||
void EnableAutoStart(HWND, bool);
|
||||
|
||||
/// Reports 0 for disabled, 1 for enabled, 2 for indeterminate
|
||||
int IsAutoStartEnabled() const;
|
||||
|
||||
int MessageBox(HWND hwnd, UINT id, UINT flags)
|
||||
{
|
||||
CString title, text;
|
||||
ATLVERIFY(title.LoadString(IDR_MAINFRAME));
|
||||
ATLVERIFY(text.LoadString(id));
|
||||
return ::MessageBox(hwnd, text, title, flags);
|
||||
}
|
||||
};
|
||||
|
||||
inline Application *GetApplication() { return Application::GetInstance(); }
|
||||
|
||||
#endif // FIREFLYSHELL_H
|
301
win32/FireflyShell/FireflyShell.rc
Normal file
301
win32/FireflyShell/FireflyShell.rc
Normal file
@ -0,0 +1,301 @@
|
||||
// Microsoft Visual C++ generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "atlres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""atlres.h""\r\n"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#ifndef APSTUDIO_INVOKED\r\n"
|
||||
"#include ""version.rc""\r\n"
|
||||
"#endif // !APSTUDIO_INVOKED\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDR_MAINFRAME ICON "res\\FireflyShell.ico"
|
||||
IDI_SHELL_RUNNING ICON "res\\shellrunning.ico"
|
||||
IDI_SHELL_STOPPED ICON "res\\shellstopped.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_PAGE_ABOUT DIALOGEX 0, 0, 221, 223
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "About"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,93,18,20,20
|
||||
CTEXT "Firefly Media Server",IDC_STATIC,7,41,207,11
|
||||
LTEXT "For help, tips and troubleshooting advice visit the Firefly Media Server website.",IDC_STATIC,12,79,119,23
|
||||
PUSHBUTTON "Visit &Website...",IDC_WEBSITE,139,82,70,14
|
||||
GROUPBOX "Version information",IDC_STATIC,7,114,207,102
|
||||
CONTROL "",IDC_VERSIONLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,12,126,197,63
|
||||
PUSHBUTTON "&Copy to Clipboard",IDC_COPY,139,194,70,14
|
||||
END
|
||||
|
||||
IDD_PAGE_BASIC DIALOGEX 0, 0, 222, 230
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Library"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "Library &Name",IDC_STATIC,7,24,72,8
|
||||
EDITTEXT IDC_SERVERNAME,61,21,152,14,ES_AUTOHSCROLL
|
||||
LTEXT "Media &Location",IDC_STATIC,7,60,48,8
|
||||
EDITTEXT IDC_PATH,61,57,152,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Browse...",IDC_BROWSE,163,76,50,14
|
||||
GROUPBOX "Security",IDC_STATIC,7,113,206,113
|
||||
CONTROL "&Protect Firefly media library with a password",IDC_PROTECT,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,128,187,10
|
||||
LTEXT "Password:",IDC_PASSWORD_PROMPT,18,157,34,8
|
||||
EDITTEXT IDC_PASSWORD,61,156,148,14,ES_PASSWORD | ES_AUTOHSCROLL
|
||||
LTEXT "Explanatory text about passwords go here. Why you'd want a password and what are the implications 'n' stuff.",IDC_STATIC,18,180,188,39,SS_NOPREFIX
|
||||
END
|
||||
|
||||
IDD_PAGE_LOG DIALOGEX 0, 0, 222, 220
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Log"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
EDITTEXT IDC_LOG,4,4,214,212,ES_AUTOHSCROLL | ES_READONLY
|
||||
END
|
||||
|
||||
IDD_PAGE_ADVANCED DIALOGEX 0, 0, 222, 220
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Server"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Server Status",IDC_STATIC,6,7,210,82
|
||||
LTEXT "Current state of the server goes here",IDC_SERVERSTATE,12,24,200,25
|
||||
PUSHBUTTON "&Stop Server",IDC_STOPSERVICE,160,49,50,14
|
||||
PUSHBUTTON "&Start Server",IDC_STARTSERVICE,160,49,50,14
|
||||
CONTROL "&Start Firefly when Windows starts",IDC_AUTOSTART,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,73,196,10
|
||||
GROUPBOX "Advanced",IDC_STATIC,6,93,210,61
|
||||
LTEXT "Server port number",IDC_STATIC,12,108,122,11
|
||||
EDITTEXT IDC_SERVERPORT,155,106,42,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
CONTROL "",IDC_PORTSPIN,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS | UDS_HOTTRACK,197,106,11,14
|
||||
LTEXT "You may need to change this if another program is already using this port.",IDC_STATIC,12,129,196,23
|
||||
GROUPBOX "Web administration",IDC_STATIC,6,159,210,54
|
||||
LTEXT "Firefly Media Server also provides a web administration interface.",IDC_STATIC,12,177,140,20
|
||||
PUSHBUTTON "&Open",IDC_WEBADMIN,160,194,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_PAGE_ABOUT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 214
|
||||
VERTGUIDE, 12
|
||||
VERTGUIDE, 131
|
||||
VERTGUIDE, 139
|
||||
VERTGUIDE, 209
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 216
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Accelerator
|
||||
//
|
||||
|
||||
IDR_MAINFRAME ACCELERATORS
|
||||
BEGIN
|
||||
"N", ID_FILE_NEW, VIRTKEY, CONTROL
|
||||
"O", ID_FILE_OPEN, VIRTKEY, CONTROL
|
||||
"S", ID_FILE_SAVE, VIRTKEY, CONTROL
|
||||
"P", ID_FILE_PRINT, VIRTKEY, CONTROL
|
||||
"Z", ID_EDIT_UNDO, VIRTKEY, CONTROL
|
||||
"X", ID_EDIT_CUT, VIRTKEY, CONTROL
|
||||
"C", ID_EDIT_COPY, VIRTKEY, CONTROL
|
||||
"V", ID_EDIT_PASTE, VIRTKEY, CONTROL
|
||||
VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT
|
||||
VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT
|
||||
VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL
|
||||
VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT
|
||||
VK_F6, ID_NEXT_PANE, VIRTKEY
|
||||
VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDM_CONTEXT MENU
|
||||
BEGIN
|
||||
POPUP ""
|
||||
BEGIN
|
||||
MENUITEM "&Configure Firefly Media Server...", ID_CONFIGURE
|
||||
MENUITEM "E&xit", ID_EXIT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDR_MAINFRAME "Firefly Media Server"
|
||||
IDS_SERVER_RUNNING "The Firefly media server is currently running."
|
||||
IDS_SERVER_STOPPED "The Firefly media server is not currently running."
|
||||
IDS_SERVERSTARTFAIL "Failed to start Firefly Media Server."
|
||||
IDS_SERVERSTOPFAIL "Failed to stop Firefly Media Server."
|
||||
IDS_SERVER_PENDING "The Firefly media server is currently busy."
|
||||
IDS_SERVER_START "&Start"
|
||||
IDS_SERVER_STOP "&Stop"
|
||||
IDS_SCAN_START "Scanning for media is in progress\n\nThis may take some time."
|
||||
IDS_SCAN_STOP "Scanning for media is complete."
|
||||
IDS_NOT_ADMIN "You must be logged in as a local administrator to start and stop the server."
|
||||
IDS_QUERYSERVERRESTART "Changing the configuration will require a restart of the Firefly Media Server. Are you sure you want to do this?"
|
||||
IDS_VERSIONINFO_DESCRIPTION "Description"
|
||||
IDS_VERSIONINFO_VERSION "Version"
|
||||
IDS_VERSIONINFO_PATH "Path"
|
||||
IDS_FAILED_CONFIGURE_SERVICE "Failed to reconfigure service."
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_FILE_NEW "Create a new document\nNew"
|
||||
ID_FILE_OPEN "Open an existing document\nOpen"
|
||||
ID_FILE_CLOSE "Close the active document\nClose"
|
||||
ID_FILE_SAVE "Save the active document\nSave"
|
||||
ID_FILE_SAVE_AS "Save the active document with a new name\nSave As"
|
||||
ID_FILE_PAGE_SETUP "Change the printing options\nPage Setup"
|
||||
ID_FILE_PRINT_SETUP "Change the printer and printing options\nPrint Setup"
|
||||
ID_FILE_PRINT "Print the active document\nPrint"
|
||||
ID_FILE_PRINT_PREVIEW "Display full pages\nPrint Preview"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_APP_ABOUT "Display program information, version number and copyright\nAbout"
|
||||
ID_APP_EXIT "Quit the application; prompts to save documents\nExit"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_NEXT_PANE "Switch to the next window pane\nNext Pane"
|
||||
ID_PREV_PANE "Switch back to the previous window pane\nPrevious Pane"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_WINDOW_NEW "Open another window for the active document\nNew Window"
|
||||
ID_WINDOW_ARRANGE "Arrange icons at the bottom of the window\nArrange Icons"
|
||||
ID_WINDOW_CASCADE "Arrange windows so they overlap\nCascade Windows"
|
||||
ID_WINDOW_TILE_HORZ "Arrange windows as non-overlapping tiles\nTile Windows"
|
||||
ID_WINDOW_TILE_VERT "Arrange windows as non-overlapping tiles\nTile Windows"
|
||||
ID_WINDOW_SPLIT "Split the active window into panes\nSplit"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ID_EDIT_CLEAR "Erase the selection\nErase"
|
||||
ID_EDIT_CLEAR_ALL "Erase everything\nErase All"
|
||||
ID_EDIT_COPY "Copy the selection and put it on the Clipboard\nCopy"
|
||||
ID_EDIT_CUT "Cut the selection and put it on the Clipboard\nCut"
|
||||
ID_EDIT_FIND "Find the specified text\nFind"
|
||||
ID_EDIT_PASTE "Insert Clipboard contents\nPaste"
|
||||
ID_EDIT_REPEAT "Repeat the last action\nRepeat"
|
||||
ID_EDIT_REPLACE "Replace specific text with different text\nReplace"
|
||||
ID_EDIT_SELECT_ALL "Select the entire document\nSelect All"
|
||||
ID_EDIT_UNDO "Undo the last action\nUndo"
|
||||
ID_EDIT_REDO "Redo the previously undone action\nRedo"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ATL_IDS_SCSIZE "Change the window size"
|
||||
ATL_IDS_SCMOVE "Change the window position"
|
||||
ATL_IDS_SCMINIMIZE "Reduce the window to an icon"
|
||||
ATL_IDS_SCMAXIMIZE "Enlarge the window to full size"
|
||||
ATL_IDS_SCNEXTWINDOW "Switch to the next document window"
|
||||
ATL_IDS_SCPREVWINDOW "Switch to the previous document window"
|
||||
ATL_IDS_SCCLOSE "Close the active window and prompts to save the documents"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ATL_IDS_SCRESTORE "Restore the window to normal size"
|
||||
ATL_IDS_SCTASKLIST "Activate Task List"
|
||||
ATL_IDS_MDICHILD "Activate this window"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ATL_IDS_IDLEMESSAGE "Ready"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
ATL_IDS_MRU_FILE "Open this document"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_FAILED_CONFIGURE_STARTUP "Failed to reconfigure startup application."
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
370
win32/FireflyShell/FireflyShell.vcproj
Normal file
370
win32/FireflyShell/FireflyShell.vcproj
Normal file
@ -0,0 +1,370 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="FireflyShell"
|
||||
ProjectGUID="{FC91423E-33F6-4037-95AC-A8BAD7DF599F}"
|
||||
RootNamespace="FireflyShell"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\versionize.bat"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="false"
|
||||
TargetEnvironment="1"
|
||||
GenerateStublessProxies="true"
|
||||
TypeLibraryName="$(IntDir)/FireflyShell.tlb"
|
||||
HeaderFileName="FireflyShell.h"
|
||||
DLLDataFileName=""
|
||||
InterfaceIdentifierFileName="FireflyShell_i.c"
|
||||
ProxyFileName="FireflyShell_p.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;STRICT;_DEBUG"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="$(IntDir)"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
UseOfATL="1"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
CommandLine="..\versionize.bat"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="false"
|
||||
TargetEnvironment="1"
|
||||
GenerateStublessProxies="true"
|
||||
TypeLibraryName="$(IntDir)/FireflyShell.tlb"
|
||||
HeaderFileName="FireflyShell.h"
|
||||
DLLDataFileName=""
|
||||
InterfaceIdentifierFileName="FireflyShell_i.c"
|
||||
ProxyFileName="FireflyShell_p.c"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;_WINDOWS;STRICT;NDEBUG"
|
||||
ExceptionHandling="1"
|
||||
RuntimeLibrary="0"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
AdditionalIncludeDirectories="$(IntDir)"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
LinkIncremental="1"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AboutPage.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AdvancedPage.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigPage.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DosPath.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FireflyShell.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LogPage.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MainDlg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NotifyIcon.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerEvents.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServiceControl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VersionInfo.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\AboutPage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\AdvancedPage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ConfigPage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\DosPath.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FireflyShell.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\IniFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\LogPage.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MainDlg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\NotifyIcon.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServerEvents.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ServiceControl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\singleton.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\VersionInfo.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\res\FireflyShell.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\FireflyShell.rc"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\res\shellrunning.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\res\shellstopped.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\version.rc"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\README.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
68
win32/FireflyShell/IniFile.h
Normal file
68
win32/FireflyShell/IniFile.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef INIFILE_H
|
||||
#define INIFILE_H
|
||||
#include "DosPath.h"
|
||||
|
||||
class IniFile
|
||||
{
|
||||
CString m_path;
|
||||
|
||||
public:
|
||||
explicit IniFile(const CString &path)
|
||||
: m_path(path)
|
||||
{
|
||||
}
|
||||
|
||||
CString GetString(const TCHAR *section, const TCHAR *key, const TCHAR *defstring)
|
||||
{
|
||||
CString str;
|
||||
::GetPrivateProfileString(section, key, defstring, str.GetBuffer(512), 512, m_path);
|
||||
str.ReleaseBuffer();
|
||||
return str;
|
||||
}
|
||||
|
||||
bool SetString(const TCHAR *section, const TCHAR *key, const TCHAR *value)
|
||||
{
|
||||
return ::WritePrivateProfileString(section, key, value, m_path) != 0;
|
||||
}
|
||||
|
||||
int GetInteger(const TCHAR *section, const TCHAR *key, int defvalue)
|
||||
{
|
||||
return ::GetPrivateProfileInt(section, key, defvalue, m_path);
|
||||
}
|
||||
|
||||
bool SetInteger(const TCHAR *section, const TCHAR *key, int value)
|
||||
{
|
||||
CString str;
|
||||
str.Format(_T("%d"), value);
|
||||
return ::WritePrivateProfileString(section, key, str, m_path) != 0;
|
||||
}
|
||||
|
||||
bool IsWritable() const
|
||||
{
|
||||
if (::WritePrivateProfileString(_T("Writability Test"), _T("Writability Test"), _T("Test"), m_path))
|
||||
{
|
||||
// Remove it then.
|
||||
::WritePrivateProfileString(_T("Writability Test"), NULL, NULL, m_path);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
#endif // INIFILE_H
|
23
win32/FireflyShell/LogPage.cpp
Normal file
23
win32/FireflyShell/LogPage.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
*(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 "LogPage.h"
|
||||
|
||||
LRESULT CLogPage::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
41
win32/FireflyShell/LogPage.h
Normal file
41
win32/FireflyShell/LogPage.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef LOGPAGE_H
|
||||
#define LOGPAGE_H 1
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
class CLogPage :
|
||||
public CPropertyPageImpl<CLogPage>
|
||||
{
|
||||
typedef CPropertyPageImpl<CLogPage> base;
|
||||
|
||||
public:
|
||||
enum { IDD = IDD_PAGE_LOG };
|
||||
|
||||
private:
|
||||
|
||||
// Message Handlers
|
||||
BEGIN_MSG_MAP(CLogPage)
|
||||
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
|
||||
CHAIN_MSG_MAP(base)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
};
|
||||
|
||||
#endif // LOGPAGE_H
|
59
win32/FireflyShell/MainDlg.cpp
Normal file
59
win32/FireflyShell/MainDlg.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
*(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 "resource.h"
|
||||
|
||||
#include "MainDlg.h"
|
||||
#include "FireflyShell.h"
|
||||
|
||||
CMainDlg::CMainDlg()
|
||||
{
|
||||
this->AddPage(m_pageConfig);
|
||||
this->AddPage(m_pageAdvanced);
|
||||
//this->AddPage(m_pageLog);
|
||||
this->AddPage(m_pageAbout);
|
||||
|
||||
ATLVERIFY(m_strTitle.LoadString(IDR_MAINFRAME));
|
||||
this->SetTitle(m_strTitle);
|
||||
}
|
||||
|
||||
LRESULT CMainDlg::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
|
||||
{
|
||||
bool restart_service = false;
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
{
|
||||
const UINT id = LOWORD(wParam);
|
||||
|
||||
if ((id == IDOK || id == ID_APPLY_NOW)
|
||||
&& GetDlgItem(ID_APPLY_NOW).IsWindowEnabled()
|
||||
&& GetApplication()->GetServiceStatus().IsRunning())
|
||||
{
|
||||
CString title, text;
|
||||
title.LoadString(IDR_MAINFRAME);
|
||||
text.LoadString(IDS_QUERYSERVERRESTART);
|
||||
if (MessageBox(text, title, MB_YESNO) != IDYES)
|
||||
return 0;
|
||||
restart_service = true;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT result = base::OnCommand(uMsg, wParam, lParam, bHandled);
|
||||
if (restart_service)
|
||||
GetApplication()->RestartService(m_hWnd);
|
||||
|
||||
return result;
|
||||
}
|
47
win32/FireflyShell/MainDlg.h
Normal file
47
win32/FireflyShell/MainDlg.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef MAINDLG_H
|
||||
#define MAINDLG_H 1
|
||||
|
||||
#include "ConfigPage.h"
|
||||
#include "AdvancedPage.h"
|
||||
#include "LogPage.h"
|
||||
#include "AboutPage.h"
|
||||
|
||||
class CMainDlg : public CPropertySheetImpl<CMainDlg>
|
||||
{
|
||||
typedef CPropertySheetImpl<CMainDlg> base;
|
||||
|
||||
CString m_strTitle;
|
||||
|
||||
CConfigPage m_pageConfig;
|
||||
CAdvancedPage m_pageAdvanced;
|
||||
CLogPage m_pageLog;
|
||||
CAboutPage m_pageAbout;
|
||||
|
||||
BEGIN_MSG_MAP(CMainDlg)
|
||||
MESSAGE_HANDLER(WM_COMMAND, OnCommand)
|
||||
CHAIN_MSG_MAP(base)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled);
|
||||
|
||||
public:
|
||||
CMainDlg();
|
||||
};
|
||||
|
||||
#endif // MAINDLG_H
|
270
win32/FireflyShell/NotifyIcon.cpp
Normal file
270
win32/FireflyShell/NotifyIcon.cpp
Normal file
@ -0,0 +1,270 @@
|
||||
/*
|
||||
*(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 "resource.h"
|
||||
#include "NotifyIcon.h"
|
||||
#include "FireflyShell.h"
|
||||
|
||||
CNotifyIcon::CNotifyIcon()
|
||||
{
|
||||
ZeroMemory(&m_nid, sizeof(NOTIFYICONDATA));
|
||||
m_nid.cbSize = sizeof(NOTIFYICONDATA);
|
||||
m_nid.uID = ID_SHELLNOTIFY;
|
||||
|
||||
m_running_icon = AtlLoadIcon(IDI_SHELL_RUNNING);
|
||||
m_stopped_icon = AtlLoadIcon(IDI_SHELL_STOPPED);
|
||||
}
|
||||
|
||||
BOOL CNotifyIcon::Create()
|
||||
{
|
||||
m_registered_activation_message = GetApplication()->GetRegisteredActivationMessage();
|
||||
|
||||
RECT rect = {0, 0, 0, 0};
|
||||
|
||||
// Hidden window.
|
||||
if (base::Create(NULL, rect, _T("FireflyShellNotifyIconHidden"), WS_POPUP))
|
||||
{
|
||||
m_nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
|
||||
|
||||
InflictIconState();
|
||||
|
||||
//wcsncpy(niData.szTip, TEXT("Foo?"), sizeof(niData.szTip));
|
||||
m_nid.hWnd = m_hWnd;
|
||||
m_nid.uCallbackMessage = PRIVATE_WM_NOTIFYICON;
|
||||
|
||||
Shell_NotifyIcon(NIM_ADD, &m_nid);
|
||||
|
||||
SetTimer(TIMER_ID, 5000, NULL);
|
||||
|
||||
GetApplication()->ServiceStatusSubscribe(this);
|
||||
|
||||
EnableUserSwitchNotifications();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void CNotifyIcon::Destroy()
|
||||
{
|
||||
GetApplication()->ServiceStatusUnsubscribe(this);
|
||||
KillTimer(TIMER_ID);
|
||||
Shell_NotifyIcon(NIM_DELETE, &m_nid);
|
||||
DestroyIcon(m_nid.hIcon);
|
||||
|
||||
|
||||
base::DestroyWindow();
|
||||
}
|
||||
|
||||
void CNotifyIcon::PopupBalloon(UINT title_id, UINT text_id, DWORD flags)
|
||||
{
|
||||
CString title, text;
|
||||
title.LoadString(title_id);
|
||||
text.LoadString(text_id);
|
||||
|
||||
m_nid.uFlags |= NIF_INFO;
|
||||
|
||||
SafeStringCopy(m_nid.szInfoTitle, title, 64);
|
||||
SafeStringCopy(m_nid.szInfo, text, 256);
|
||||
|
||||
m_nid.dwInfoFlags = flags;
|
||||
m_nid.uTimeout = 10000;
|
||||
Shell_NotifyIcon(NIM_MODIFY, &m_nid);
|
||||
}
|
||||
|
||||
void CNotifyIcon::Update()
|
||||
{
|
||||
InflictIconState();
|
||||
// I suspect we'll need this line too.
|
||||
// m_nid.uFlags &= ~NIF_INFO;
|
||||
Shell_NotifyIcon(NIM_MODIFY, &m_nid);
|
||||
}
|
||||
|
||||
void CNotifyIcon::InflictIconState()
|
||||
{
|
||||
// Will the icons leak?
|
||||
Service::Status status = GetApplication()->GetServiceStatus();
|
||||
UINT state_id;
|
||||
if (status.IsPending())
|
||||
{
|
||||
state_id = IDS_SERVER_PENDING;
|
||||
m_nid.hIcon = m_stopped_icon; // As good as any?
|
||||
}
|
||||
else if (status.IsRunning())
|
||||
{
|
||||
state_id = IDS_SERVER_RUNNING;
|
||||
m_nid.hIcon = m_running_icon;
|
||||
}
|
||||
else
|
||||
{
|
||||
state_id = IDS_SERVER_STOPPED;
|
||||
m_nid.hIcon = m_stopped_icon;
|
||||
}
|
||||
|
||||
CString tip;
|
||||
tip.LoadString(state_id);
|
||||
SafeStringCopy(m_nid.szTip, tip, 64);
|
||||
}
|
||||
|
||||
void CNotifyIcon::OnServiceStatus(Service::Status old_status, Service::Status new_status)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
void CNotifyIcon::OnTimer(UINT id, TIMERPROC proc)
|
||||
{
|
||||
if (id == TIMER_ID)
|
||||
{
|
||||
GetApplication()->CheckServiceStatus();
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnNotifyIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
switch (lParam)
|
||||
{
|
||||
case WM_LBUTTONDBLCLK:
|
||||
GetApplication()->Configure();
|
||||
bHandled = true;
|
||||
return 0L;
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_CONTEXTMENU:
|
||||
OnContextMenu();
|
||||
bHandled = true;
|
||||
return 0L;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
void CNotifyIcon::OnContextMenu()
|
||||
{
|
||||
HMENU hMenu;
|
||||
|
||||
HINSTANCE hInstance = _Module.GetResourceInstance();
|
||||
hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDM_CONTEXT));
|
||||
|
||||
POINT pt;
|
||||
GetCursorPos(&pt);
|
||||
|
||||
// See TrackPopupMenu in MSDN.
|
||||
SetForegroundWindow(m_hWnd);
|
||||
//::SetForegroundWindow(m_hWnd);
|
||||
HMENU hPopup = GetSubMenu(hMenu, 0);
|
||||
::SetMenuDefaultItem(hPopup, ID_CONFIGURE, FALSE);
|
||||
TrackPopupMenu(hPopup, TPM_LEFTALIGN | TPM_BOTTOMALIGN, pt.x, pt.y, 0, m_hWnd, NULL);
|
||||
::PostMessage(m_hWnd, WM_NULL, 0, 0);
|
||||
|
||||
::DestroyMenu(hMenu);
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnConfigure(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
GetApplication()->Configure();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnExit(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
|
||||
{
|
||||
/// @todo
|
||||
Application::GetInstance()->Exit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnRegisteredActivation(UINT, WPARAM, LPARAM, BOOL &bHandled)
|
||||
{
|
||||
ATLTRACE(_T("Activate\n"));
|
||||
bHandled = true;
|
||||
GetApplication()->Configure();
|
||||
|
||||
// We return a magic number so that the caller knows we've been found
|
||||
// and can give up.
|
||||
return m_registered_activation_message;
|
||||
}
|
||||
|
||||
void CNotifyIcon::OnServerEvent(UINT32 id, UINT32 intval, const CString &strval)
|
||||
{
|
||||
// Note that we're running on a different thread here. We need to punt
|
||||
// the event over to the main thread using SendMessage.
|
||||
switch (id)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
SendMessage(WM_SERVEREVENT, id);
|
||||
break;
|
||||
default:
|
||||
ATLASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnServerEvent(UINT, WPARAM wparam, LPARAM, BOOL &bHandled)
|
||||
{
|
||||
bHandled = true;
|
||||
switch (wparam)
|
||||
{
|
||||
case 1:
|
||||
PopupBalloon(IDR_MAINFRAME, IDS_SCAN_START);
|
||||
break;
|
||||
case 2:
|
||||
PopupBalloon(IDR_MAINFRAME, IDS_SCAN_STOP);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CNotifyIcon::EnableUserSwitchNotifications()
|
||||
{
|
||||
HMODULE h = ::LoadLibrary(_T("WtsApi32.dll"));
|
||||
if (h)
|
||||
{
|
||||
typedef BOOL (WINAPI *Proc)(HWND, DWORD);
|
||||
Proc fn = reinterpret_cast<Proc>(GetProcAddress(h, "WTSRegisterSessionNotification"));
|
||||
if (fn)
|
||||
{
|
||||
(*fn)(m_hWnd, NOTIFY_FOR_THIS_SESSION);
|
||||
}
|
||||
::FreeLibrary(h);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CNotifyIcon::OnSessionChange(UINT, WPARAM wparam, LPARAM, BOOL &bHandled)
|
||||
{
|
||||
// Because only one process can get events through the mailslot we
|
||||
// disconnect from it when the user uses XP fast user switching to
|
||||
// switch to a different user.
|
||||
switch (wparam)
|
||||
{
|
||||
case WTS_CONSOLE_CONNECT:
|
||||
case WTS_REMOTE_CONNECT:
|
||||
ATLTRACE("SESSION CONNECT\n");
|
||||
GetApplication()->EnableServerEvents(true);
|
||||
break;
|
||||
|
||||
case WTS_CONSOLE_DISCONNECT:
|
||||
case WTS_REMOTE_DISCONNECT:
|
||||
ATLTRACE("SESSION DISCONNECT\n");
|
||||
GetApplication()->EnableServerEvents(false);
|
||||
break;
|
||||
}
|
||||
bHandled = true;
|
||||
return 0;
|
||||
}
|
||||
|
81
win32/FireflyShell/NotifyIcon.h
Normal file
81
win32/FireflyShell/NotifyIcon.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef NOTIFYICON_H
|
||||
#define NOTIFYICON_H
|
||||
|
||||
#include "ServiceControl.h"
|
||||
#include "ServerEvents.h"
|
||||
|
||||
class CNotifyIcon
|
||||
: public CWindowImpl<CNotifyIcon>,
|
||||
public ServiceStatusObserver,
|
||||
public ServerEvents::Observer
|
||||
{
|
||||
typedef CWindowImpl<CNotifyIcon> base;
|
||||
|
||||
NOTIFYICONDATA m_nid;
|
||||
HICON m_running_icon;
|
||||
HICON m_stopped_icon;
|
||||
UINT m_registered_activation_message;
|
||||
|
||||
enum { TIMER_ID = 43 };
|
||||
enum { WM_SERVEREVENT = WM_APP + 42 };
|
||||
|
||||
enum { PRIVATE_WM_NOTIFYICON = WM_USER + 42 };
|
||||
|
||||
BEGIN_MSG_MAP(CNotifyIcon)
|
||||
MESSAGE_HANDLER(PRIVATE_WM_NOTIFYICON, OnNotifyIconMessage)
|
||||
COMMAND_ID_HANDLER(ID_CONFIGURE, OnConfigure)
|
||||
COMMAND_ID_HANDLER(ID_EXIT, OnExit)
|
||||
MESSAGE_HANDLER(m_registered_activation_message, OnRegisteredActivation)
|
||||
MESSAGE_HANDLER(WM_SERVEREVENT, OnServerEvent)
|
||||
MESSAGE_HANDLER(WM_WTSSESSION_CHANGE, OnSessionChange)
|
||||
MSG_WM_TIMER(OnTimer)
|
||||
END_MSG_MAP()
|
||||
|
||||
// Message handlers
|
||||
void OnContextMenu();
|
||||
LRESULT OnNotifyIconMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnConfigure(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnExit(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
|
||||
LRESULT OnRegisteredActivation(UINT, WPARAM, LPARAM, BOOL &bHandled);
|
||||
LRESULT OnServerEvent(UINT, WPARAM, LPARAM, BOOL &bHandled);
|
||||
LRESULT OnSessionChange(UINT, WPARAM, LPARAM, BOOL &bHandled);
|
||||
void OnTimer(UINT id, TIMERPROC proc);
|
||||
|
||||
void PopupBalloon(UINT title_id, UINT text_id, DWORD flags = NIIF_INFO);
|
||||
|
||||
void InflictIconState();
|
||||
void Update();
|
||||
|
||||
// Terminal services stuff on XP.
|
||||
void EnableUserSwitchNotifications();
|
||||
|
||||
// ServiceStatusObserver
|
||||
void OnServiceStatus(Service::Status old_status, Service::Status new_status);
|
||||
|
||||
// ServerEvents::Observer
|
||||
void OnServerEvent(UINT32 id, UINT32 intval, const CString &str);
|
||||
|
||||
public:
|
||||
CNotifyIcon();
|
||||
BOOL Create();
|
||||
void Destroy();
|
||||
|
||||
};
|
||||
|
||||
#endif // NOTIFYICON_H
|
17
win32/FireflyShell/README.txt
Normal file
17
win32/FireflyShell/README.txt
Normal file
@ -0,0 +1,17 @@
|
||||
The FireflyShell source code is distributed under the terms of the GNU
|
||||
General Public License Version 2 as published by the Free Software
|
||||
Foundation. You can find a copy of this license in the LICENSE.txt
|
||||
file.
|
||||
|
||||
This program uses the Microsoft Windows Template Library which is released
|
||||
under the Common Public License. The copyright holders of FireflyShell
|
||||
explicitly grant the additional right to distribute binaries produced from
|
||||
source code derived from FireflyShell that are linked with the Microsoft
|
||||
Windows Template Library.
|
||||
|
||||
Note that you may not be able to incorporate third party GNU General Public
|
||||
Licensed code into FireflyShell and then distribute binaries unless you have
|
||||
a similar additional right from the copyright holder.
|
||||
|
||||
You can find the Windows Template Library at
|
||||
http://sourceforge.net/projects/wtl/
|
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);
|
||||
}
|
||||
}
|
55
win32/FireflyShell/ServerEvents.h
Normal file
55
win32/FireflyShell/ServerEvents.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef SERVEREVENTS_H
|
||||
#define SERVEREVENTS_H
|
||||
|
||||
class ServerEvents
|
||||
{
|
||||
public:
|
||||
/// Note that the observer is called on the wrong thread.
|
||||
class Observer
|
||||
{
|
||||
public:
|
||||
virtual void OnServerEvent(UINT32 id, UINT32 intval, const CString &str) = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
HANDLE m_thread;
|
||||
HANDLE m_mailslot;
|
||||
Observer *m_obs;
|
||||
|
||||
static unsigned __stdcall StaticThreadProc(void *);
|
||||
DWORD ThreadProc();
|
||||
|
||||
void OnEvent(const void *buffer, size_t length);
|
||||
|
||||
public:
|
||||
ServerEvents(Observer *obs);
|
||||
~ServerEvents();
|
||||
|
||||
void SetObserver(Observer *obs)
|
||||
{
|
||||
ATLASSERT(m_obs == NULL);
|
||||
m_obs = obs;
|
||||
}
|
||||
|
||||
bool Start();
|
||||
void Stop();
|
||||
};
|
||||
|
||||
#endif // SERVICE
|
205
win32/FireflyShell/ServiceControl.cpp
Normal file
205
win32/FireflyShell/ServiceControl.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
*(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 "ServiceControl.h"
|
||||
|
||||
bool Service::Open(const TCHAR *name)
|
||||
{
|
||||
Close();
|
||||
|
||||
const DWORD ADMIN_ACCESS = SC_MANAGER_ALL_ACCESS;
|
||||
const DWORD USER_ACCESS = SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE | STANDARD_RIGHTS_READ;
|
||||
|
||||
DWORD dwDesiredAccess = ADMIN_ACCESS;
|
||||
|
||||
m_sc_manager = ::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, dwDesiredAccess);
|
||||
if (!m_sc_manager)
|
||||
{
|
||||
dwDesiredAccess = USER_ACCESS;
|
||||
m_sc_manager = ::OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, dwDesiredAccess);
|
||||
m_can_control = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_can_control = true;
|
||||
}
|
||||
|
||||
if (m_sc_manager)
|
||||
{
|
||||
m_sc_service = ::OpenService(m_sc_manager, name, dwDesiredAccess);
|
||||
if (m_sc_service)
|
||||
return true;
|
||||
}
|
||||
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
void Service::Close()
|
||||
{
|
||||
if (m_sc_service)
|
||||
{
|
||||
::CloseServiceHandle(m_sc_service);
|
||||
m_sc_service = NULL;
|
||||
}
|
||||
if (m_sc_manager)
|
||||
{
|
||||
::CloseServiceHandle(m_sc_manager);
|
||||
m_sc_manager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool Service::GetStatus(Status *status) const
|
||||
{
|
||||
if (::QueryServiceStatus(m_sc_service, status))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::Start()
|
||||
{
|
||||
if (::StartService(m_sc_service, 0, NULL))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::StartAndWait()
|
||||
{
|
||||
if (Start())
|
||||
{
|
||||
Status status;
|
||||
return WaitPending(&status, SERVICE_START_PENDING);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::Stop()
|
||||
{
|
||||
Status status;
|
||||
if (::ControlService(m_sc_service, SERVICE_CONTROL_STOP, &status))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::StopAndWait()
|
||||
{
|
||||
Status status;
|
||||
if (::ControlService(m_sc_service, SERVICE_CONTROL_STOP, &status))
|
||||
{
|
||||
return WaitPending(&status, SERVICE_STOP_PENDING);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Service::WaitPending(Status *status, DWORD existing_state)
|
||||
{
|
||||
if (GetStatus(status))
|
||||
{
|
||||
DWORD dwStartTickCount = GetTickCount();
|
||||
DWORD dwOldCheckPoint = status->dwCheckPoint;
|
||||
|
||||
while (status->dwCurrentState == existing_state)
|
||||
{
|
||||
ATLTRACE(_T("WaitPending\n"));
|
||||
DWORD dwWaitTime = status->dwWaitHint / 10;
|
||||
if (dwWaitTime < 1000)
|
||||
dwWaitTime = 1000;
|
||||
else if (dwWaitTime > 10000)
|
||||
dwWaitTime = 10000;
|
||||
|
||||
::Sleep(dwWaitTime);
|
||||
|
||||
if (!GetStatus(status))
|
||||
return false;
|
||||
|
||||
if (status->dwCheckPoint != dwOldCheckPoint)
|
||||
{
|
||||
// The service is making progress
|
||||
dwStartTickCount = GetTickCount();
|
||||
dwOldCheckPoint = status->dwCheckPoint;
|
||||
}
|
||||
else if (GetTickCount() - dwStartTickCount > status->dwWaitHint)
|
||||
{
|
||||
/// Hmm. No progress
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CString Service::GetBinaryPath() const
|
||||
{
|
||||
CString path;
|
||||
|
||||
DWORD bytes_required;
|
||||
::QueryServiceConfig(m_sc_service, NULL, 0, &bytes_required);
|
||||
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
void *buffer = operator new(bytes_required);
|
||||
LPQUERY_SERVICE_CONFIG config = reinterpret_cast<LPQUERY_SERVICE_CONFIG>(buffer);
|
||||
|
||||
if (::QueryServiceConfig(m_sc_service, config, bytes_required, &bytes_required))
|
||||
{
|
||||
path = config->lpBinaryPathName;
|
||||
}
|
||||
|
||||
delete buffer;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
DWORD Service::GetStartup() const
|
||||
{
|
||||
DWORD result = 0xffffffff;
|
||||
const size_t BUFFER_SIZE = 8192;
|
||||
void *buffer = operator new(BUFFER_SIZE);
|
||||
LPQUERY_SERVICE_CONFIG config = reinterpret_cast<LPQUERY_SERVICE_CONFIG>(buffer);
|
||||
|
||||
DWORD bytes_required;
|
||||
if (::QueryServiceConfig(m_sc_service, config, BUFFER_SIZE, &bytes_required))
|
||||
result = config->dwStartType;
|
||||
|
||||
delete buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Service::ConfigureStartup(DWORD startup)
|
||||
{
|
||||
if (::ChangeServiceConfig(m_sc_service, SERVICE_NO_CHANGE, startup, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServiceStatusMonitor::Poll(Service *service)
|
||||
{
|
||||
Service::Status new_status;
|
||||
if (service->GetStatus(&new_status))
|
||||
{
|
||||
if (!m_service_status.IsValid() || (m_service_status != new_status))
|
||||
{
|
||||
FireServiceStatus(m_service_status, new_status);
|
||||
m_service_status = new_status;
|
||||
}
|
||||
}
|
||||
}
|
171
win32/FireflyShell/ServiceControl.h
Normal file
171
win32/FireflyShell/ServiceControl.h
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef SERVICECONTROL_H
|
||||
#define SERVICECONTROL_H
|
||||
|
||||
class Service
|
||||
{
|
||||
SC_HANDLE m_sc_manager;
|
||||
SC_HANDLE m_sc_service;
|
||||
bool m_can_control;
|
||||
|
||||
public:
|
||||
|
||||
class Status : public SERVICE_STATUS
|
||||
{
|
||||
bool WaitPending();
|
||||
|
||||
public:
|
||||
Status()
|
||||
{
|
||||
SERVICE_STATUS *clearable_this = this;
|
||||
ZeroMemory(clearable_this, sizeof(SERVICE_STATUS));
|
||||
}
|
||||
|
||||
bool operator==(const Status &r) const
|
||||
{
|
||||
const SERVICE_STATUS *lhs = this;
|
||||
const SERVICE_STATUS *rhs = &r;
|
||||
return memcmp(lhs, rhs, sizeof(SERVICE_STATUS)) == 0;
|
||||
}
|
||||
|
||||
bool operator!=(const Status &r) const
|
||||
{
|
||||
const SERVICE_STATUS *lhs = this;
|
||||
const SERVICE_STATUS *rhs = &r;
|
||||
return memcmp(lhs, rhs, sizeof(SERVICE_STATUS)) != 0;
|
||||
}
|
||||
|
||||
void AssertValid() const
|
||||
{
|
||||
// If we've been written then this shouldn't be zero.
|
||||
ATLASSERT(dwCurrentState != 0);
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return dwCurrentState != 0;
|
||||
}
|
||||
|
||||
bool IsRunning() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_RUNNING;
|
||||
}
|
||||
|
||||
bool IsStopped() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_STOPPED;
|
||||
}
|
||||
|
||||
bool IsPaused() const
|
||||
{
|
||||
AssertValid();
|
||||
return dwCurrentState == SERVICE_PAUSED;
|
||||
}
|
||||
|
||||
bool IsPending() const
|
||||
{
|
||||
AssertValid();
|
||||
switch (dwCurrentState)
|
||||
{
|
||||
case SERVICE_CONTINUE_PENDING:
|
||||
case SERVICE_PAUSE_PENDING:
|
||||
case SERVICE_START_PENDING:
|
||||
case SERVICE_STOP_PENDING:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Service() : m_sc_manager(NULL), m_sc_service(NULL), m_can_control(false) {}
|
||||
~Service() { Close(); }
|
||||
|
||||
bool IsOpen() const
|
||||
{
|
||||
return m_sc_service != NULL;
|
||||
}
|
||||
bool Open(const TCHAR *name);
|
||||
void Close();
|
||||
|
||||
bool GetStatus(Status *status) const;
|
||||
|
||||
bool Start();
|
||||
bool StartAndWait();
|
||||
bool Stop();
|
||||
bool StopAndWait();
|
||||
bool WaitPending(Status *status, DWORD existing_state);
|
||||
bool PollPending(Status *status, DWORD existing_state);
|
||||
|
||||
bool CanControl() const
|
||||
{
|
||||
// For the time being - need to deal with running as a user that can't control.
|
||||
return IsOpen() && m_can_control;
|
||||
}
|
||||
|
||||
CString GetBinaryPath() const;
|
||||
|
||||
/// Pass SERVICE_AUTO_START, SERVICE_BOOT_START, SERVICE_DEMAND_START,
|
||||
/// SERVICE_DISABLED or SERVICE_SYSTEM_START.
|
||||
bool ConfigureStartup(DWORD dwStartup);
|
||||
|
||||
DWORD GetStartup() const;
|
||||
};
|
||||
|
||||
class ServiceStatusObserver
|
||||
{
|
||||
public:
|
||||
virtual void OnServiceStatus(Service::Status old_status, Service::Status new_status) = 0;
|
||||
};
|
||||
|
||||
class ServiceStatusMonitor
|
||||
{
|
||||
Service::Status m_service_status;
|
||||
std::vector<ServiceStatusObserver *> m_service_observers;
|
||||
|
||||
void FireServiceStatus(Service::Status old_status, Service::Status new_status)
|
||||
{
|
||||
std::vector<ServiceStatusObserver *>::iterator i = m_service_observers.begin();
|
||||
while (i != m_service_observers.end())
|
||||
{
|
||||
(*i)->OnServiceStatus(old_status, new_status);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void Poll(Service *service);
|
||||
void Subscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
m_service_observers.push_back(obs);
|
||||
}
|
||||
|
||||
void Unsubscribe(ServiceStatusObserver *obs)
|
||||
{
|
||||
std::vector<ServiceStatusObserver *>::iterator i = std::find(m_service_observers.begin(), m_service_observers.end(), obs);
|
||||
ATLASSERT(i != m_service_observers.end());
|
||||
if (i != m_service_observers.end())
|
||||
{
|
||||
m_service_observers.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
#endif // SERVICECONTROL_H
|
111
win32/FireflyShell/VersionInfo.cpp
Normal file
111
win32/FireflyShell/VersionInfo.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
*(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 "VersionInfo.h"
|
||||
|
||||
bool VersionInfo::Open(const TCHAR *filename)
|
||||
{
|
||||
Close();
|
||||
|
||||
DWORD useless;
|
||||
m_size = GetFileVersionInfoSize(filename, &useless);
|
||||
if (m_size)
|
||||
{
|
||||
m_buffer = operator new(m_size);
|
||||
::ZeroMemory(m_buffer, m_size);
|
||||
if (GetFileVersionInfo(filename, 0, m_size, m_buffer))
|
||||
{
|
||||
return IdentifySubBlock();
|
||||
}
|
||||
else
|
||||
Close();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VersionInfo::IdentifySubBlock()
|
||||
{
|
||||
m_subblock.Empty();
|
||||
WORD required_langid = LANGIDFROMLCID(GetUserDefaultLCID());
|
||||
|
||||
UINT cbTranslate;
|
||||
struct LANGANDCODEPAGE
|
||||
{
|
||||
WORD wLanguage;
|
||||
WORD wCodePage;
|
||||
} *lpTranslate;
|
||||
|
||||
|
||||
if (VerQueryValue(m_buffer, _T("\\VarFileInfo\\Translation"),
|
||||
reinterpret_cast<LPVOID*>(&lpTranslate),
|
||||
&cbTranslate))
|
||||
{
|
||||
// Try and find the user's language, but if we can't then just use the
|
||||
// first one in the file.
|
||||
int lang_index = -1;
|
||||
for(unsigned i=0; i < (cbTranslate/sizeof(struct LANGANDCODEPAGE)); i++ )
|
||||
{
|
||||
// If we have an exact match then great.
|
||||
if (lpTranslate[i].wLanguage == required_langid)
|
||||
{
|
||||
lang_index = i;
|
||||
break;
|
||||
}
|
||||
// Otherwise settle for a primary language match and keep looking
|
||||
else if ((PRIMARYLANGID(lpTranslate[i].wLanguage) == PRIMARYLANGID(required_langid)) && (lang_index < 0))
|
||||
{
|
||||
lang_index = i;
|
||||
}
|
||||
}
|
||||
if (lang_index < 0)
|
||||
{
|
||||
ATLTRACE("Failed to find a matching language. Just using the first one.\n");
|
||||
lang_index = 0;
|
||||
}
|
||||
|
||||
m_subblock.Format(_T("\\StringFileInfo\\%04x%04x\\"), lpTranslate[lang_index].wLanguage, lpTranslate[lang_index].wCodePage);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void VersionInfo::Close()
|
||||
{
|
||||
if (m_buffer)
|
||||
{
|
||||
delete m_buffer;
|
||||
m_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CString VersionInfo::GetString(const TCHAR *name) const
|
||||
{
|
||||
CString path = m_subblock + name;
|
||||
|
||||
LPVOID buffer;
|
||||
UINT cb;
|
||||
if (VerQueryValue(m_buffer, const_cast<LPTSTR>(static_cast<LPCTSTR>(path)), &buffer, &cb))
|
||||
{
|
||||
return CString(static_cast<LPCTSTR>(buffer), cb);
|
||||
}
|
||||
return CString();
|
||||
}
|
||||
|
||||
//CString VersionInfo::GetStringFileVersion()
|
||||
//{
|
||||
// VerQueryValue(m_buffer,
|
||||
//}
|
46
win32/FireflyShell/VersionInfo.h
Normal file
46
win32/FireflyShell/VersionInfo.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef VERSIONINFO_H
|
||||
#define VERSIONINFO_H
|
||||
|
||||
class VersionInfo
|
||||
{
|
||||
size_t m_size;
|
||||
void *m_buffer;
|
||||
CString m_subblock;
|
||||
|
||||
bool IdentifySubBlock();
|
||||
|
||||
CString GetString(const TCHAR *name) const;
|
||||
|
||||
public:
|
||||
VersionInfo() : m_size(0), m_buffer(NULL) {}
|
||||
|
||||
bool Open(const TCHAR *filename);
|
||||
void Close();
|
||||
|
||||
CString GetFileDescription() const
|
||||
{
|
||||
return GetString(_T("FileDescription"));
|
||||
}
|
||||
|
||||
CString GetFileVersion() const
|
||||
{
|
||||
return GetString(_T("FileVersion"));
|
||||
}
|
||||
};
|
||||
#endif // VERSIONINFO_H
|
BIN
win32/FireflyShell/res/FireflyShell.ico
Normal file
BIN
win32/FireflyShell/res/FireflyShell.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
win32/FireflyShell/res/ShellRunning.ico
Normal file
BIN
win32/FireflyShell/res/ShellRunning.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
win32/FireflyShell/res/ShellStopped.ico
Normal file
BIN
win32/FireflyShell/res/ShellStopped.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
59
win32/FireflyShell/resource.h
Normal file
59
win32/FireflyShell/resource.h
Normal file
@ -0,0 +1,59 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by FireflyShell.rc
|
||||
//
|
||||
#define IDR_MAINFRAME 128
|
||||
#define IDS_SERVER_RUNNING 129
|
||||
#define IDS_SERVER_STOPPED 130
|
||||
#define IDS_SERVERSTARTFAIL 131
|
||||
#define IDS_SERVERSTOPFAIL 132
|
||||
#define IDS_SERVER_PENDING 133
|
||||
#define IDS_SERVER_START 134
|
||||
#define IDS_SERVER_STOP 135
|
||||
#define IDS_SCAN_START 136
|
||||
#define IDS_SCAN_STOP 137
|
||||
#define IDS_NOT_ADMIN 138
|
||||
#define IDS_QUERYSERVERRESTART 139
|
||||
#define IDS_VERSIONINFO_DESCRIPTION 140
|
||||
#define IDS_VERSIONINFO_VERSION 141
|
||||
#define IDS_VERSIONINFO_PATH 142
|
||||
#define IDS_FAILED_CONFIGURE_SERVICE 143
|
||||
#define IDS_FAILED_CONFIGURE_STARTUP 144
|
||||
#define IDD_PAGE_BASIC 201
|
||||
#define IDD_PAGE_ADVANCED 202
|
||||
#define IDD_PAGE_LOG 203
|
||||
#define IDD_PAGE_ABOUT 204
|
||||
#define IDI_SHELL_STOPPED 207
|
||||
#define IDC_SERVERNAME 1000
|
||||
#define IDC_PATH 1001
|
||||
#define IDC_BROWSE 1002
|
||||
#define IDI_SHELL_RUNNING 1003
|
||||
#define IDM_CONTEXT 1003
|
||||
#define IDC_LOG 1003
|
||||
#define ID_CONFIGURE 1004
|
||||
#define IDC_PROTECT 1004
|
||||
#define IDC_PASSWORD 1005
|
||||
#define IDC_PASSWORD_PROMPT 1006
|
||||
#define ID_EXIT 1007
|
||||
#define IDC_PORTSPIN 1007
|
||||
#define IDC_STARTSERVICE 1008
|
||||
#define IDC_SERVERPORT 1009
|
||||
#define IDC_STOPSERVICE 1010
|
||||
#define IDC_SERVERSTATE 1011
|
||||
#define IDC_AUTOSTART 1012
|
||||
#define IDC_WEBADMIN 1013
|
||||
#define IDC_WEBSITE 1014
|
||||
#define IDC_VERSIONLIST 1015
|
||||
#define IDC_COPY 1016
|
||||
#define ID_SHELLNOTIFY 4242
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 208
|
||||
#define _APS_NEXT_COMMAND_VALUE 32773
|
||||
#define _APS_NEXT_CONTROL_VALUE 1017
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
49
win32/FireflyShell/singleton.h
Normal file
49
win32/FireflyShell/singleton.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#ifndef SINGLETON_H
|
||||
#define SINGLETON_H
|
||||
|
||||
template <class T>
|
||||
class Singleton
|
||||
{
|
||||
static T *sm_instance;
|
||||
|
||||
public:
|
||||
Singleton()
|
||||
{
|
||||
T *instance = static_cast<T *>(this);
|
||||
ATLASSERT(sm_instance == NULL);
|
||||
sm_instance = instance;
|
||||
}
|
||||
|
||||
virtual ~Singleton()
|
||||
{
|
||||
ATLASSERT(sm_instance != NULL);
|
||||
sm_instance = NULL;
|
||||
}
|
||||
|
||||
static T *GetInstance()
|
||||
{
|
||||
ATLASSERT(sm_instance != NULL);
|
||||
return sm_instance;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
T *Singleton<T>::sm_instance;
|
||||
|
||||
#endif // SINGLETON_H
|
21
win32/FireflyShell/stdafx.cpp
Normal file
21
win32/FireflyShell/stdafx.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
*(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"
|
||||
|
||||
#if (_ATL_VER < 0x0700)
|
||||
#include <atlimpl.cpp>
|
||||
#endif //(_ATL_VER < 0x0700)
|
77
win32/FireflyShell/stdafx.h
Normal file
77
win32/FireflyShell/stdafx.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Change these values to use different versions
|
||||
#define WINVER 0x0400
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define _WIN32_IE 0x0500
|
||||
#define _RICHEDIT_VER 0x0100
|
||||
|
||||
#define _UNICODE
|
||||
#define UNICODE
|
||||
|
||||
#include <atlbase.h>
|
||||
#include <atlapp.h>
|
||||
|
||||
extern CAppModule _Module;
|
||||
|
||||
#include <atlwin.h>
|
||||
#include <atlframe.h>
|
||||
#include <atlctrls.h>
|
||||
#include <atldlgs.h>
|
||||
#include <atlmisc.h>
|
||||
#include <atlddx.h>
|
||||
#include <atlcrack.h>
|
||||
#include <atlctrlx.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// WtsApi32.h is only in the latest platform SDK. Don't rely
|
||||
// on everyone having it.
|
||||
#if !defined(NOTIFY_FOR_THIS_SESSION)
|
||||
#define NOTIFY_FOR_THIS_SESSION 0
|
||||
#endif
|
||||
|
||||
#if defined _M_IX86
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#elif defined _M_IA64
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#elif defined _M_X64
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#else
|
||||
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
|
||||
#endif
|
||||
|
||||
// Visual C++ 2005's new secure string operations
|
||||
#define USE_SECURE 0
|
||||
#if defined(_MSC_VER)
|
||||
#if _MSC_VER >= 1400
|
||||
#undef USE_SECURE
|
||||
#define USE_SECURE 1
|
||||
#endif // _MSC_VER >= 1400
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
inline void SafeStringCopy(TCHAR *dest, const TCHAR *source, size_t len)
|
||||
{
|
||||
#if USE_SECURE
|
||||
_tcsncpy_s(dest, len, source, len);
|
||||
#else
|
||||
_tcsncpy(dest, source, len);
|
||||
dest[len - 1] = 0;
|
||||
#endif
|
||||
}
|
13
win32/FireflyShell/version.h.templ
Normal file
13
win32/FireflyShell/version.h.templ
Normal file
@ -0,0 +1,13 @@
|
||||
/* Version number of package */
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MID 1
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_BUILD $WCREV$
|
||||
|
||||
#define VERSION_LOCAL "$WCMODS? (LOCAL):$"
|
||||
#define BUILD_DATE "$WCNOW$"
|
||||
#define REPO_DATE "$WCDATE$"
|
||||
|
||||
#define VERSION_STRIZE2(x) #x
|
||||
#define VERSION_STRIZE(x) VERSION_STRIZE2(x)
|
||||
#define VERSION_STRING VERSION_STRIZE(VERSION_MAJOR) "." VERSION_STRIZE(VERSION_MID) "-svn" VERSION_STRIZE(VERSION_BUILD) VERSION_LOCAL
|
44
win32/FireflyShell/version.rc
Normal file
44
win32/FireflyShell/version.rc
Normal file
@ -0,0 +1,44 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "version.h"
|
||||
#include "winver.h"
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VERSION_MAJOR, VERSION_MID, VERSION_MINOR, VERSION_BUILD
|
||||
PRODUCTVERSION VERSION_MAJOR, VERSION_MID, VERSION_MINOR, VERSION_BUILD
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS VS_FF_DEBUG
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Roku LLC"
|
||||
VALUE "FileDescription", "FireflyShell"
|
||||
VALUE "FileVersion", VERSION_STRING
|
||||
VALUE "InternalName", "FireflyShell"
|
||||
VALUE "LegalCopyright", "Copyright 2006 Roku LLC"
|
||||
VALUE "OriginalFilename", "FireflyShell.exe"
|
||||
VALUE "ProductName", "Firefly Media Server"
|
||||
VALUE "ProductVersion", VERSION_STRING
|
||||
VALUE "Comments", "Build date: " BUILD_DATE "\r\nRepository date: " REPO_DATE "\r\n"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif //APSTUDIO_INVOKED
|
@ -8,6 +8,7 @@ echo Fixing version info...
|
||||
%SUBWC% %0\..\.. %0\..\FireflyConfig\AssemblyInfo.cs.templ %0\..\FireflyConfig\AssemblyInfo.cs
|
||||
%SUBWC% %0\..\.. %0\..\nsi\mt-daapd.nsi.templ %0\..\nsi\mt-daapd.nsi
|
||||
%SUBWC% %0\..\.. %0\..\ssc-ffmpeg.rc.templ %0\..\ssc-ffmpeg.rc
|
||||
%SUBWC% %0\..\.. %0\..\FireflyShell\version.h.templ %0\..\FireflyShell\version.h
|
||||
goto END
|
||||
|
||||
:NOSUBWC
|
||||
@ -15,4 +16,5 @@ copy %0\..\config.h.templ %0\..\config.h
|
||||
copy %0\..\FireflyConfig\AssemblyInfo.cs.templ %0\..\FireflyConfig\AssemblyInfo.cs
|
||||
copy %0\..\nsi\mt-daapd.nsi.templ %0\..\nsi\mt-daapd.nsi
|
||||
copy %0\..\.. %0\..\ssc-ffmpeg.rc.templ %0\..\ssc-ffmpeg.rc
|
||||
copy %0\..\FireflyShell\version.h.templ %0\..\version.h
|
||||
:END
|
||||
|
Loading…
x
Reference in New Issue
Block a user