mirror of
https://github.com/owntone/owntone-server.git
synced 2025-11-09 21:49:48 -05:00
Make fireflyshell drop a drive mapping ini file, so that the server can convert network drive letters to unc paths.
This commit is contained in:
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
*(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.
|
||||
*/
|
||||
*(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"
|
||||
@@ -29,167 +29,188 @@ CAppModule _Module;
|
||||
#define RUN_VALUE _T("FireflyShell")
|
||||
|
||||
Application::Application()
|
||||
: m_dlg(NULL), m_server_events(&m_icon)
|
||||
: m_dlg(NULL), m_server_events(&m_icon)
|
||||
{
|
||||
CDosPath path = CDosPath::AppPath();
|
||||
CDosPath path = CDosPath::AppPath();
|
||||
SetCurrentDirectory(path.GetPathOnly());
|
||||
CDosPath filename(_T("mt-daapd.conf"));
|
||||
filename |= path;
|
||||
m_config_path = filename.GetPath();
|
||||
ATLTRACE("Config path: %s\n", (const TCHAR *)m_config_path);
|
||||
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"));
|
||||
// Dump an ini file with drive mappings
|
||||
CDosPath mapfile(_T("mapping.ini"));
|
||||
mapfile |= path;
|
||||
|
||||
CheckCanConfigure();
|
||||
TCHAR inbuffer[4];
|
||||
TCHAR outbuffer[2048]; /* as max_path is unreliable */
|
||||
DWORD size;
|
||||
UNIVERSAL_NAME_INFO * puni = (UNIVERSAL_NAME_INFO *) &outbuffer;
|
||||
|
||||
m_unique_name = GenerateUniqueName();
|
||||
m_registered_activation_message = ::RegisterWindowMessage(m_unique_name);
|
||||
for(int x='A'; x<='Z'; x++) {
|
||||
wsprintf(inbuffer,_T("%c:\\"),x);
|
||||
memset(outbuffer,0,sizeof(outbuffer));
|
||||
size = sizeof(outbuffer);
|
||||
WNetGetUniversalName(inbuffer,UNIVERSAL_NAME_INFO_LEVEL,outbuffer,
|
||||
&size);
|
||||
wsprintf(inbuffer,_T("%c"),x);
|
||||
WritePrivateProfileString(_T("mapping"),inbuffer,puni->lpUniversalName,
|
||||
mapfile.GetPath());
|
||||
}
|
||||
|
||||
|
||||
// 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);
|
||||
ATLASSERT(m_dlg == NULL);
|
||||
}
|
||||
|
||||
void Application::CheckCanConfigure()
|
||||
{
|
||||
IniFile ini(m_config_path);
|
||||
m_configurable = ini.IsWritable();
|
||||
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;
|
||||
}
|
||||
if (ActivatePreviousInstance(lpstrCmdLine, nCmdShow))
|
||||
{
|
||||
ATLTRACE(_T("Already running\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMessageLoop theLoop;
|
||||
_Module.AddMessageLoop(&theLoop);
|
||||
CMessageLoop theLoop;
|
||||
_Module.AddMessageLoop(&theLoop);
|
||||
|
||||
if (!m_icon.Create())
|
||||
{
|
||||
ATLTRACE(_T("Icon creation failed!\n"));
|
||||
return 0;
|
||||
}
|
||||
if (!m_icon.Create())
|
||||
{
|
||||
ATLTRACE(_T("Icon creation failed!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
EnableServerEvents(true);
|
||||
EnableServerEvents(true);
|
||||
|
||||
if (ShowDialogAtStart(lpstrCmdLine, nCmdShow))
|
||||
Configure(false);
|
||||
if (ShowDialogAtStart(lpstrCmdLine, nCmdShow))
|
||||
Configure(false);
|
||||
|
||||
int nRet = theLoop.Run();
|
||||
int nRet = theLoop.Run();
|
||||
|
||||
EnableServerEvents(false);
|
||||
EnableServerEvents(false);
|
||||
|
||||
m_icon.Destroy();
|
||||
m_icon.Destroy();
|
||||
|
||||
_Module.RemoveMessageLoop();
|
||||
return nRet;
|
||||
_Module.RemoveMessageLoop();
|
||||
return nRet;
|
||||
}
|
||||
|
||||
void Application::Exit()
|
||||
{
|
||||
if (m_dlg)
|
||||
{
|
||||
m_dlg->DestroyWindow();
|
||||
}
|
||||
::PostQuitMessage(0);
|
||||
if (m_dlg)
|
||||
{
|
||||
m_dlg->DestroyWindow();
|
||||
}
|
||||
::PostQuitMessage(0);
|
||||
}
|
||||
|
||||
void Application::Configure(bool move_window)
|
||||
{
|
||||
if (m_dlg)
|
||||
{
|
||||
m_dlg->ShowWindow(SW_RESTORE);
|
||||
SetForegroundWindow(m_dlg->m_hWnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckCanConfigure();
|
||||
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(move_window);
|
||||
m_dlg = &dlg;
|
||||
dlg.DoModal();
|
||||
m_dlg = NULL;
|
||||
}
|
||||
// Other people may need to talk to the dialog while it exists.
|
||||
CMainDlg dlg(move_window);
|
||||
m_dlg = &dlg;
|
||||
dlg.DoModal();
|
||||
m_dlg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::StartService(HWND hwndParent)
|
||||
{
|
||||
CWaitCursor wc;
|
||||
ATLASSERT(m_service.CanControl());
|
||||
if (!m_service.CanControl())
|
||||
return;
|
||||
CWaitCursor wc;
|
||||
ATLASSERT(m_service.CanControl());
|
||||
if (!m_service.CanControl())
|
||||
return;
|
||||
|
||||
if (!m_service.StartAndWait())
|
||||
{
|
||||
MessageBox(hwndParent, IDS_SERVERSTARTFAIL, MB_OK);
|
||||
}
|
||||
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;
|
||||
CWaitCursor wc;
|
||||
ATLASSERT(m_service.CanControl());
|
||||
if (!m_service.CanControl())
|
||||
return;
|
||||
|
||||
if (!m_service.StopAndWait())
|
||||
{
|
||||
MessageBox(hwndParent, IDS_SERVERSTOPFAIL, MB_OK);
|
||||
}
|
||||
if (!m_service.StopAndWait())
|
||||
{
|
||||
MessageBox(hwndParent, IDS_SERVERSTOPFAIL, MB_OK);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::RestartService(HWND hwndParent)
|
||||
{
|
||||
CWaitCursor wc;
|
||||
StopService(hwndParent);
|
||||
StartService(hwndParent);
|
||||
CWaitCursor wc;
|
||||
StopService(hwndParent);
|
||||
StartService(hwndParent);
|
||||
}
|
||||
|
||||
bool Application::ShowDialogAtStart(LPCTSTR cmdline, int nCmdShow)
|
||||
{
|
||||
if ((cmdline[0] == '-') && (cmdline[1] == 'q'))
|
||||
return false;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL CALLBACK Application::StaticWindowSearcher(HWND hwnd, LPARAM lparam)
|
||||
{
|
||||
DWORD result;
|
||||
DWORD result;
|
||||
LRESULT ok = ::SendMessageTimeout(hwnd,
|
||||
static_cast<UINT>(lparam),
|
||||
0, 0,
|
||||
SMTO_BLOCK |
|
||||
SMTO_ABORTIFHUNG,
|
||||
200,
|
||||
&result);
|
||||
static_cast<UINT>(lparam),
|
||||
0, 0,
|
||||
SMTO_BLOCK |
|
||||
SMTO_ABORTIFHUNG,
|
||||
200,
|
||||
&result);
|
||||
if (ok == 0)
|
||||
return TRUE; // ignore this and continue
|
||||
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 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;
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool Application::ActivatePreviousInstance(LPCTSTR lpstrCmdLine, int nCmdShow)
|
||||
@@ -202,27 +223,27 @@ bool Application::ActivatePreviousInstance(LPCTSTR lpstrCmdLine, int nCmdShow)
|
||||
::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))
|
||||
{
|
||||
// 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 true;
|
||||
}
|
||||
|
||||
return running;
|
||||
return running;
|
||||
}
|
||||
|
||||
CString Application::GenerateUniqueName()
|
||||
{
|
||||
// We need to allow one instance to run per desktop. See
|
||||
// http://www.codeproject.com/cpp/avoidmultinstance.asp
|
||||
// We need to allow one instance to run per desktop. See
|
||||
// http://www.codeproject.com/cpp/avoidmultinstance.asp
|
||||
|
||||
// First start with some application unique
|
||||
// First start with some application unique
|
||||
CString s(_T("Firefly-67A72768-4154-417e-BFA0-FA9B50C342DE"));
|
||||
|
||||
// Now append something desktop unique
|
||||
// Now append something desktop unique
|
||||
DWORD len;
|
||||
HDESK desktop = GetThreadDesktop(GetCurrentThreadId());
|
||||
BOOL result = GetUserObjectInformation(desktop, UOI_NAME, NULL, 0, &len);
|
||||
@@ -244,129 +265,129 @@ CString Application::GenerateUniqueName()
|
||||
|
||||
void Application::EnableServerEvents(bool b)
|
||||
{
|
||||
if (b)
|
||||
m_server_events.Start();
|
||||
else
|
||||
m_server_events.Stop();
|
||||
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;
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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 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);
|
||||
// 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 (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;
|
||||
// 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);
|
||||
// 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
|
||||
AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls
|
||||
|
||||
HRESULT hRes = _Module.Init(NULL, hInstance);
|
||||
ATLASSERT(SUCCEEDED(hRes));
|
||||
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);
|
||||
}
|
||||
int nRet;
|
||||
{
|
||||
// Application object is destroyed prior to undoing everything above.
|
||||
Application app;
|
||||
nRet = app.Run(lpstrCmdLine, nCmdShow);
|
||||
}
|
||||
|
||||
_Module.Term();
|
||||
return nRet;
|
||||
_Module.Term();
|
||||
return nRet;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
AdditionalDependencies="version.lib mpr.lib"
|
||||
OutputFile="$(OutDir)/FireflyShell.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
@@ -77,7 +77,7 @@
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="version.lib"
|
||||
AdditionalDependencies="version.lib mpr.lib"
|
||||
OutputFile="$(OutDir)/FireflyShell.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
|
||||
Reference in New Issue
Block a user