You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3046 lines
76 KiB
3046 lines
76 KiB
/***************************************************************************
|
|
*
|
|
* Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: dp8simuimain.cpp
|
|
*
|
|
* Content: DP8SIM UI executable entry point.
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ======== ======== =========
|
|
* 04/23/01 VanceO Created.
|
|
*
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "dp8simuii.h"
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Defines
|
|
//=============================================================================
|
|
#define MAX_RESOURCE_STRING_LENGTH _MAX_PATH
|
|
#define DISPLAY_PRECISION 4
|
|
#define AUTOREFRESH_TIMERID 1
|
|
#define AUTOREFRESH_INTERVAL 1000
|
|
|
|
#define REG_KEY_DP8SIMROOT _T("Software\\Microsoft\\DirectPlay8\\DP8Sim")
|
|
#define REG_KEY_CUSTOMSETTINGS REG_KEY_DP8SIMROOT _T("\\CustomSettings")
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Structures
|
|
//=============================================================================
|
|
typedef struct _SIMSETTINGS
|
|
{
|
|
UINT uiNameStringResourceID; // resource ID of name string, or 0 if not built-in
|
|
WCHAR * pwszName; // pointer to name string
|
|
DP8SIM_PARAMETERS dp8spSend; // send DP8Sim settings
|
|
DP8SIM_PARAMETERS dp8spReceive; // receive DP8Sim settings
|
|
} SIMSETTINGS, * PSIMSETTINGS;
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Dynamically loaded function prototypes
|
|
//=============================================================================
|
|
typedef HRESULT (WINAPI * PFN_DLLREGISTERSERVER)(void);
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Prototypes
|
|
//=============================================================================
|
|
HRESULT InitializeApplication(const HINSTANCE hInstance,
|
|
const LPSTR lpszCmdLine,
|
|
const int iShowCmd);
|
|
|
|
HRESULT CleanupApplication(const HINSTANCE hInstance);
|
|
|
|
HRESULT BuildSimSettingsTable(const HINSTANCE hInstance);
|
|
|
|
void FreeSimSettingsTable(void);
|
|
|
|
HRESULT AddSimSettingsToTable(const SIMSETTINGS * const pSimSettings);
|
|
|
|
HRESULT SaveSimSettings(HWND hWnd, SIMSETTINGS * const pSimSettings);
|
|
|
|
HRESULT InitializeUserInterface(const HINSTANCE hInstance,
|
|
const int iShowCmd);
|
|
|
|
HRESULT CleanupUserInterface(void);
|
|
|
|
void DoErrorBox(const HINSTANCE hInstance,
|
|
const HWND hWndParent,
|
|
const UINT uiCaptionStringRsrcID,
|
|
const UINT uiTextStringRsrcID);
|
|
|
|
void FloatToString(const FLOAT fValue,
|
|
const int iPrecision,
|
|
char * const szBuffer,
|
|
const int iBufferLength);
|
|
|
|
void GetParametersFromWindow(HWND hWnd,
|
|
DP8SIM_PARAMETERS * pdp8spSend,
|
|
DP8SIM_PARAMETERS * pdp8spReceive);
|
|
|
|
void SetParametersInWindow(HWND hWnd,
|
|
DP8SIM_PARAMETERS * pdp8spSend,
|
|
DP8SIM_PARAMETERS * pdp8spReceive);
|
|
|
|
void DisplayCurrentStatistics(HWND hWnd);
|
|
|
|
|
|
|
|
INT_PTR CALLBACK MainWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
INT_PTR CALLBACK NameSettingsWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
|
|
|
|
HRESULT LoadAndAllocString(HINSTANCE hInstance, UINT uiResourceID, WCHAR ** pwszString);
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Constants
|
|
//=============================================================================
|
|
const SIMSETTINGS c_BuiltInSimSettings[] =
|
|
{
|
|
{ IDS_SETTING_NONE, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
0, // dp8spSend.dwBandwidthBPS
|
|
0.0, // dp8spSend.fPacketLossPercent
|
|
0, // dp8spSend.dwMinLatencyMS
|
|
0 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
0, // dp8spReceive.dwBandwidthBPS
|
|
0.0, // dp8spReceive.fPacketLossPercent
|
|
0, // dp8spReceive.dwMinLatencyMS
|
|
0 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_336MODEM1, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
3500, // dp8spSend.dwBandwidthBPS
|
|
2.0, // dp8spSend.fPacketLossPercent
|
|
55, // dp8spSend.dwMinLatencyMS
|
|
75 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
3500, // dp8spReceive.dwBandwidthBPS
|
|
2.0, // dp8spReceive.fPacketLossPercent
|
|
55, // dp8spReceive.dwMinLatencyMS
|
|
75 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_336MODEM2, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
4000, // dp8spSend.dwBandwidthBPS
|
|
0.75, // dp8spSend.fPacketLossPercent
|
|
50, // dp8spSend.dwMinLatencyMS
|
|
70 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
4000, // dp8spReceive.dwBandwidthBPS
|
|
0.75, // dp8spReceive.fPacketLossPercent
|
|
50, // dp8spReceive.dwMinLatencyMS
|
|
70 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_56KMODEM1, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
3500, // dp8spSend.dwBandwidthBPS
|
|
2.0, // dp8spSend.fPacketLossPercent
|
|
55, // dp8spSend.dwMinLatencyMS
|
|
75 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
5000, // dp8spReceive.dwBandwidthBPS
|
|
2.0, // dp8spReceive.fPacketLossPercent
|
|
55, // dp8spReceive.dwMinLatencyMS
|
|
75 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_56KMODEM2, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
4000, // dp8spSend.dwBandwidthBPS
|
|
0.75, // dp8spSend.fPacketLossPercent
|
|
50, // dp8spSend.dwMinLatencyMS
|
|
70 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
7000, // dp8spReceive.dwBandwidthBPS
|
|
0.75, // dp8spReceive.fPacketLossPercent
|
|
50, // dp8spReceive.dwMinLatencyMS
|
|
70 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_256KBPSDSL, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
32000, // dp8spSend.dwBandwidthBPS
|
|
0.5, // dp8spSend.fPacketLossPercent
|
|
25, // dp8spSend.dwMinLatencyMS
|
|
30 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
32000, // dp8spReceive.dwBandwidthBPS
|
|
0.5, // dp8spReceive.fPacketLossPercent
|
|
25, // dp8spReceive.dwMinLatencyMS
|
|
30 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_DISCONNECTED, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
0, // dp8spSend.dwBandwidthBPS
|
|
100.0, // dp8spSend.fPacketLossPercent
|
|
0, // dp8spSend.dwMinLatencyMS
|
|
0 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
0, // dp8spReceive.dwBandwidthBPS
|
|
100.0, // dp8spReceive.fPacketLossPercent
|
|
0, // dp8spReceive.dwMinLatencyMS
|
|
0 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_HIGHPACKETLOSS, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
0, // dp8spSend.dwBandwidthBPS
|
|
10.0, // dp8spSend.fPacketLossPercent
|
|
0, // dp8spSend.dwMinLatencyMS
|
|
0 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
0, // dp8spReceive.dwBandwidthBPS
|
|
10.0, // dp8spReceive.fPacketLossPercent
|
|
0, // dp8spReceive.dwMinLatencyMS
|
|
0 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
{ IDS_SETTING_HIGHLATENCYVARIANCE, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
0, // dp8spSend.dwBandwidthBPS
|
|
0.0, // dp8spSend.fPacketLossPercent
|
|
100, // dp8spSend.dwMinLatencyMS
|
|
400 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
0, // dp8spReceive.dwBandwidthBPS
|
|
0.0, // dp8spReceive.fPacketLossPercent
|
|
100, // dp8spReceive.dwMinLatencyMS
|
|
400 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
},
|
|
|
|
//
|
|
// Custom must always be the last item.
|
|
//
|
|
{ IDS_SETTING_CUSTOM, NULL, // resource ID and string initialization
|
|
|
|
{ // dp8spSend
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
|
|
0, // dp8spSend.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
|
|
0, // dp8spSend.dwBandwidthBPS
|
|
0.0, // dp8spSend.fPacketLossPercent
|
|
0, // dp8spSend.dwMinLatencyMS
|
|
0 // dp8spSend.dwMaxLatencyMS
|
|
},
|
|
{ // dp8spReceive
|
|
sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
|
|
0, // dp8spReceive.dwFlags
|
|
DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
|
|
0, // dp8spReceive.dwBandwidthBPS
|
|
0.0, // dp8spReceive.fPacketLossPercent
|
|
0, // dp8spReceive.dwMinLatencyMS
|
|
0 // dp8spReceive.dwMaxLatencyMS
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Globals
|
|
//=============================================================================
|
|
HWND g_hWndMainWindow = NULL;
|
|
IDP8SimControl * g_pDP8SimControl = NULL;
|
|
UINT_PTR g_uiAutoRefreshTimer = 0;
|
|
SIMSETTINGS * g_paSimSettings = NULL;
|
|
DWORD g_dwNumSimSettings = 0;
|
|
DWORD g_dwMaxNumSimSettings = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "WinMain"
|
|
//=============================================================================
|
|
// WinMain
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Executable entry point.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
// HINSTANCE hPrevInstance - Handle to previous application instance.
|
|
// LPSTR lpszCmdLine - Command line string for application.
|
|
// int iShowCmd - Show state of window.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iShowCmd)
|
|
{
|
|
HRESULT hr;
|
|
HRESULT hrTemp;
|
|
MSG msg;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "===> Parameters: (0x%p, 0x%p, \"%s\", %i)",
|
|
hInstance, hPrevInstance, lpszCmdLine, iShowCmd);
|
|
|
|
|
|
//
|
|
// Initialize the application
|
|
//
|
|
hr = InitializeApplication(hInstance, lpszCmdLine, iShowCmd);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't initialize the application!");
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Do the Windows message loop until we're told to quit.
|
|
//
|
|
while (GetMessage(&msg, NULL, 0, 0))
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
}
|
|
|
|
//
|
|
// Retrieve the result code for the window closing.
|
|
//
|
|
hr = (HRESULT) msg.wParam;
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Window closed with failure (err = 0x%lx)!", hr);
|
|
} // end if (failure)
|
|
|
|
|
|
|
|
//
|
|
// Cleanup the application
|
|
//
|
|
hrTemp = CleanupApplication(hInstance);
|
|
if (hrTemp != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed cleaning up the application (err = 0x%lx)!", hrTemp);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = hrTemp;
|
|
}
|
|
|
|
//
|
|
// Continue.
|
|
//
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
|
|
DPFX(DPFPREP, 2, "<=== Returning [0x%lx]", hr);
|
|
|
|
return hr;
|
|
} // WinMain
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "InitializeApplication"
|
|
//=============================================================================
|
|
// InitializeApplication
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Initializes the application.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
// LPSTR lpszCmdLine - Command line string for application.
|
|
// int iShowCmd - Show state of window.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT InitializeApplication(const HINSTANCE hInstance,
|
|
const LPSTR lpszCmdLine,
|
|
const int iShowCmd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fOSIndirectionInitted = FALSE;
|
|
BOOL fCOMInitted = FALSE;
|
|
HMODULE hDP8SIM = NULL;
|
|
PFN_DLLREGISTERSERVER pfnDllRegisterServer;
|
|
WCHAR * pwszFriendlyName = NULL;
|
|
BOOL fEnabledControlForSP = FALSE;
|
|
BOOL fBuiltSimSettingsTable = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 5, "Parameters: (0x%p, \"%s\", %i)",
|
|
hInstance, lpszCmdLine, iShowCmd);
|
|
|
|
|
|
//
|
|
// Attempt to initialize the OS abstraction layer.
|
|
//
|
|
if (! DNOSIndirectionInit(0))
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to initialize OS indirection layer!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
fOSIndirectionInitted = TRUE;
|
|
|
|
|
|
//
|
|
// Attempt to initialize COM.
|
|
//
|
|
hr = CoInitialize(NULL);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed to initialize COM!");
|
|
goto Failure;
|
|
}
|
|
|
|
fCOMInitted = TRUE;
|
|
|
|
|
|
//
|
|
// Attempt to create a DP8Sim control object.
|
|
//
|
|
hr = CoCreateInstance(CLSID_DP8SimControl,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDP8SimControl,
|
|
(LPVOID*) (&g_pDP8SimControl));
|
|
|
|
if (hr == REGDB_E_CLASSNOTREG)
|
|
{
|
|
//
|
|
// The object wasn't registered. Attempt to load the DLL and manually
|
|
// register it.
|
|
//
|
|
|
|
hDP8SIM = LoadLibrary( _T("dp8sim.dll") );
|
|
if (hDP8SIM == NULL)
|
|
{
|
|
hr = GetLastError();
|
|
DPFX(DPFPREP, 0, "Couldn't load \"dp8sim.dll\"!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
pfnDllRegisterServer = (PFN_DLLREGISTERSERVER) GetProcAddress(hDP8SIM,
|
|
"DllRegisterServer");
|
|
if (pfnDllRegisterServer == NULL)
|
|
{
|
|
hr = GetLastError();
|
|
DPFX(DPFPREP, 0, "Couldn't get \"DllRegisterServer\" function from DP8Sim DLL!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Register the DLL.
|
|
//
|
|
hr = pfnDllRegisterServer();
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't register DP8Sim DLL!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
FreeLibrary(hDP8SIM);
|
|
hDP8SIM = NULL;
|
|
|
|
|
|
//
|
|
// Try to create the DP8Sim control object again.
|
|
//
|
|
hr = CoCreateInstance(CLSID_DP8SimControl,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDP8SimControl,
|
|
(LPVOID*) (&g_pDP8SimControl));
|
|
}
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
//
|
|
// Some error prevented creation of the object.
|
|
//
|
|
DPFX(DPFPREP, 0, "Failed creating DP8Sim Control object (err = 0x%lx)!", hr);
|
|
|
|
DoErrorBox(hInstance,
|
|
NULL,
|
|
IDS_ERROR_CAPTION_COULDNTCREATEDP8SIMCONTROL,
|
|
IDS_ERROR_TEXT_COULDNTCREATEDP8SIMCONTROL);
|
|
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// If we're here, we successfully created the object.
|
|
//
|
|
DPFX(DPFPREP, 1, "Successfully created DP8Sim Control object 0x%p.",
|
|
&g_pDP8SimControl);
|
|
|
|
|
|
//
|
|
// Initialize the control object.
|
|
//
|
|
hr = g_pDP8SimControl->Initialize(0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't initialize DP8Sim Control object!");
|
|
|
|
g_pDP8SimControl->Release();
|
|
g_pDP8SimControl = NULL;
|
|
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Load the list of settings.
|
|
//
|
|
hr = BuildSimSettingsTable(hInstance);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed building list of sim settings!");
|
|
goto Failure;
|
|
}
|
|
|
|
fBuiltSimSettingsTable = TRUE;
|
|
|
|
|
|
//
|
|
// Initialize the user interface.
|
|
//
|
|
hr = InitializeUserInterface(hInstance, iShowCmd);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed initializing user interface!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 5, "Returning [0x%lx]", hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
if (fBuiltSimSettingsTable)
|
|
{
|
|
FreeSimSettingsTable();
|
|
fBuiltSimSettingsTable = FALSE;
|
|
}
|
|
|
|
if (hDP8SIM != NULL)
|
|
{
|
|
FreeLibrary(hDP8SIM);
|
|
hDP8SIM = NULL;
|
|
}
|
|
|
|
if (pwszFriendlyName != NULL)
|
|
{
|
|
DNFree(pwszFriendlyName);
|
|
pwszFriendlyName = NULL;
|
|
}
|
|
|
|
if (g_pDP8SimControl != NULL)
|
|
{
|
|
g_pDP8SimControl->Close(0); // ignore error
|
|
|
|
g_pDP8SimControl->Release();
|
|
g_pDP8SimControl = NULL;
|
|
}
|
|
|
|
if (fCOMInitted)
|
|
{
|
|
CoUninitialize();
|
|
fCOMInitted = FALSE;
|
|
}
|
|
|
|
if (fOSIndirectionInitted)
|
|
{
|
|
DNOSIndirectionDeinit();
|
|
fOSIndirectionInitted = FALSE;
|
|
}
|
|
|
|
goto Exit;
|
|
} // InitializeApplication
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CleanupApplication"
|
|
//=============================================================================
|
|
// CleanupApplication
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Cleans up the application.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT CleanupApplication(const HINSTANCE hInstance)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT temphr;
|
|
|
|
|
|
DPFX(DPFPREP, 5, "Enter");
|
|
|
|
|
|
//
|
|
// Free the control object interface.
|
|
//
|
|
temphr = g_pDP8SimControl->Close(0);
|
|
if (temphr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Failed closing DP8Sim Control object (err = 0x%lx)!",
|
|
temphr);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
hr = temphr;
|
|
}
|
|
|
|
//
|
|
// Continue...
|
|
//
|
|
}
|
|
|
|
g_pDP8SimControl->Release();
|
|
g_pDP8SimControl = NULL;
|
|
|
|
|
|
//
|
|
// Cleanup the user interface.
|
|
//
|
|
temphr = CleanupUserInterface();
|
|
if (temphr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't cleanup user interface (err = 0x%lx)!", temphr);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
hr = temphr;
|
|
}
|
|
|
|
//
|
|
// Continue...
|
|
//
|
|
}
|
|
|
|
FreeSimSettingsTable();
|
|
|
|
CoUninitialize();
|
|
|
|
DNOSIndirectionDeinit();
|
|
|
|
|
|
|
|
DPFX(DPFPREP, 5, "Returning [0x%lx]", hr);
|
|
|
|
return hr;
|
|
} // CleanupApplication
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "BuildSimSettingsTable()"
|
|
//=============================================================================
|
|
// BuildSimSettingsTable
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Builds the table of sim settings.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT BuildSimSettingsTable(HINSTANCE hInstance)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwTemp;
|
|
HKEY hKey = NULL;
|
|
DWORD dwNumValues;
|
|
DWORD dwMaxValueNameLength;
|
|
TCHAR * ptszValue = NULL;
|
|
DWORD dwValueNameLength;
|
|
DWORD dwType;
|
|
SIMSETTINGS SimSettings;
|
|
DWORD dwDataSize;
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Parameters: (0x%p)", hInstance);
|
|
|
|
|
|
//
|
|
// Start with the built-in settings.
|
|
//
|
|
g_dwMaxNumSimSettings = sizeof(c_BuiltInSimSettings) / sizeof(SIMSETTINGS);
|
|
g_dwNumSimSettings = g_dwMaxNumSimSettings;
|
|
|
|
g_paSimSettings = (SIMSETTINGS*) DNMalloc(g_dwNumSimSettings * sizeof(SIMSETTINGS));
|
|
if (g_paSimSettings == NULL)
|
|
{
|
|
hr = DP8SIMERR_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
memcpy(g_paSimSettings, c_BuiltInSimSettings, sizeof(c_BuiltInSimSettings));
|
|
|
|
|
|
//
|
|
// Load the names of all the built-in settings from a resource.
|
|
//
|
|
for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
|
|
{
|
|
hr = LoadAndAllocString(hInstance,
|
|
g_paSimSettings[dwTemp].uiNameStringResourceID,
|
|
&(g_paSimSettings[dwTemp].pwszName));
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't load and allocate built-in setting name #%u!",
|
|
dwTemp);
|
|
goto Failure;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Now walk the list of custom entries in the registry and add those.
|
|
//
|
|
hr = RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
REG_KEY_CUSTOMSETTINGS,
|
|
0,
|
|
KEY_READ,
|
|
&hKey);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
//
|
|
// Find out the number of values, and max value name length.
|
|
//
|
|
hr = RegQueryInfoKey(hKey,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&dwNumValues,
|
|
&dwMaxValueNameLength,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
dwMaxValueNameLength++; // include room for NULL termination
|
|
|
|
ptszValue = (TCHAR*) DNMalloc(dwMaxValueNameLength * sizeof(TCHAR));
|
|
if (ptszValue == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory for custom settings key names!");
|
|
hr = DP8SIMERR_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Loop through each value.
|
|
//
|
|
for(dwTemp = 0; dwTemp < dwNumValues; dwTemp++)
|
|
{
|
|
dwValueNameLength = dwMaxValueNameLength;
|
|
dwDataSize = sizeof(SIMSETTINGS);
|
|
hr = RegEnumValue(hKey,
|
|
dwTemp,
|
|
ptszValue,
|
|
&dwValueNameLength,
|
|
NULL,
|
|
&dwType,
|
|
(BYTE*) (&SimSettings),
|
|
&dwDataSize);
|
|
if (hr == ERROR_SUCCESS)
|
|
{
|
|
dwValueNameLength++; // include room for NULL termination
|
|
|
|
//
|
|
// Validate the data that was read.
|
|
//
|
|
if ((dwType == REG_BINARY) &&
|
|
(dwDataSize == sizeof(SIMSETTINGS)) &&
|
|
(SimSettings.uiNameStringResourceID == 0) &&
|
|
(SimSettings.dp8spSend.dwSize == sizeof(DP8SIM_PARAMETERS)) &&
|
|
(SimSettings.dp8spReceive.dwSize == sizeof(DP8SIM_PARAMETERS)))
|
|
{
|
|
SimSettings.pwszName = (WCHAR*) DNMalloc(dwValueNameLength * sizeof(WCHAR));
|
|
if (SimSettings.pwszName == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory for settings name!");
|
|
hr = DP8SIMERR_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
#ifdef UNICODE
|
|
memcpy(SimSettings.pwszName, ptszValue, dwValueNameLength * sizeof(WCHAR));
|
|
#else // ! UNICODE
|
|
hr = STR_jkAnsiToWide(SimSettings.pwszName, ptszValue, dwValueNameLength);
|
|
if (hr != DPN_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Unable to convert from ANSI to Unicode (err = 0x%lx)!", hr);
|
|
DNFree(SimSettings.pwszName);
|
|
SimSettings.pwszName = NULL;
|
|
goto Failure;
|
|
}
|
|
#endif // ! UNICODE
|
|
|
|
hr = AddSimSettingsToTable(&SimSettings);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't add sim settings to table!");
|
|
hr = DP8SIMERR_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 0, "Registry value is not valid (type = %u, data size = %u, resource ID = %u, send size = %u, receive size = %u)! Ignoring.",
|
|
dwType,
|
|
dwDataSize,
|
|
SimSettings.uiNameStringResourceID,
|
|
SimSettings.dp8spSend.dwSize,
|
|
SimSettings.dp8spReceive.dwSize);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't enumerate value %u (err = 0x%lx)! Continuing.",
|
|
dwTemp, hr);
|
|
}
|
|
}
|
|
|
|
DNFree(ptszValue);
|
|
ptszValue = NULL;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't get custom settings key info! Continuing.");
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 2, "Couldn't open custom settings key, continuing.");
|
|
}
|
|
|
|
|
|
//
|
|
// If we're here, everything is ready.
|
|
//
|
|
hr = DP8SIM_OK;
|
|
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 6, "Returning [0x%lx]", hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
if (ptszValue != NULL)
|
|
{
|
|
DNFree(ptszValue);
|
|
ptszValue = NULL;
|
|
}
|
|
|
|
if (ptszValue != NULL)
|
|
{
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
//
|
|
// Free the names of all the settings that got loaded.
|
|
//
|
|
for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
|
|
{
|
|
if (g_paSimSettings[dwTemp].pwszName != NULL)
|
|
{
|
|
DNFree(g_paSimSettings[dwTemp].pwszName);
|
|
g_paSimSettings[dwTemp].pwszName = NULL;
|
|
}
|
|
}
|
|
|
|
goto Exit;
|
|
} // BuildSimSettingsTable
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "FreeSimSettingsTable()"
|
|
//=============================================================================
|
|
// FreeSimSettingsTable
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Releases resources allocated for the sim settings table.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
void FreeSimSettingsTable(void)
|
|
{
|
|
DWORD dwTemp;
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Enter");
|
|
|
|
|
|
//
|
|
// Free the names of all the settings.
|
|
//
|
|
for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
|
|
{
|
|
DNFree(g_paSimSettings[dwTemp].pwszName);
|
|
g_paSimSettings[dwTemp].pwszName = NULL;
|
|
}
|
|
|
|
DNFree(g_paSimSettings);
|
|
g_paSimSettings = NULL;
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Leave");
|
|
} // FreeSimSettingsTable
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "AddSimSettingsToTable()"
|
|
//=============================================================================
|
|
// AddSimSettingsToTable
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Adds a new sim settings entry to the table.
|
|
//
|
|
// Arguments:
|
|
// SIMSETTINGS * pSimSettings - Pointer to new sim settings to add.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT AddSimSettingsToTable(const SIMSETTINGS * const pSimSettings)
|
|
{
|
|
PVOID pvTemp;
|
|
DWORD dwNewMaxNumSettings;
|
|
|
|
|
|
DNASSERT(pSimSettings->pwszName != NULL);
|
|
DPFX(DPFPREP, 4, "Adding settings \"%ls\".", pSimSettings->pwszName);
|
|
|
|
//
|
|
// If there's not enough room in the settings array, double it.
|
|
//
|
|
if (g_dwNumSimSettings >= g_dwMaxNumSimSettings)
|
|
{
|
|
dwNewMaxNumSettings = g_dwMaxNumSimSettings * 2;
|
|
pvTemp = DNMalloc(dwNewMaxNumSettings * sizeof(SIMSETTINGS));
|
|
if (pvTemp == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory for new settings table!");
|
|
return DP8SIMERR_OUTOFMEMORY;
|
|
}
|
|
|
|
//
|
|
// Copy the existing settings and free the old array.
|
|
//
|
|
memcpy(pvTemp, g_paSimSettings, (g_dwNumSimSettings * sizeof(SIMSETTINGS)));
|
|
DNFree(g_paSimSettings);
|
|
g_paSimSettings = (SIMSETTINGS*) pvTemp;
|
|
pvTemp = NULL;
|
|
g_dwMaxNumSimSettings = dwNewMaxNumSettings;
|
|
}
|
|
|
|
|
|
//
|
|
// Now there's enough room to insert the new item. Move "Custom" down one
|
|
// slot and add the new settings.
|
|
//
|
|
|
|
memcpy(&g_paSimSettings[g_dwNumSimSettings],
|
|
&g_paSimSettings[g_dwNumSimSettings - 1],
|
|
sizeof(SIMSETTINGS));
|
|
|
|
memcpy(&g_paSimSettings[g_dwNumSimSettings - 1],
|
|
pSimSettings,
|
|
sizeof(SIMSETTINGS));
|
|
|
|
g_dwNumSimSettings++;
|
|
|
|
return DP8SIM_OK;
|
|
} // AddSimSettingsToTable
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "SaveSimSettings()"
|
|
//=============================================================================
|
|
// SaveSimSettings
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Saves a sim settings entry to the window and registry. If an
|
|
// entry by that name already exists, it is replaced.
|
|
//
|
|
// Arguments:
|
|
// SIMSETTINGS * pSimSettings - Pointer to sim settings to save.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT SaveSimSettings(HWND hWnd, SIMSETTINGS * const pSimSettings)
|
|
{
|
|
HRESULT hr;
|
|
WCHAR * pwszName = NULL;
|
|
char * pszName = NULL;
|
|
HKEY hKey = NULL;
|
|
DWORD dwTemp;
|
|
DWORD dwNameSize;
|
|
|
|
|
|
//
|
|
// Look for an existing item to replace.
|
|
//
|
|
for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
|
|
{
|
|
if (_wcsicmp(g_paSimSettings[dwTemp].pwszName, pSimSettings->pwszName) == 0)
|
|
{
|
|
DNASSERT(g_paSimSettings[dwTemp].uiNameStringResourceID == 0);
|
|
|
|
//
|
|
// Free the duplicate name string.
|
|
//
|
|
DNFree(pSimSettings->pwszName);
|
|
|
|
//
|
|
// Save the string pointer, copy the whole blob, then point to
|
|
// the existing item.
|
|
//
|
|
pwszName = g_paSimSettings[dwTemp].pwszName;
|
|
pSimSettings->pwszName = pwszName;
|
|
memcpy(&g_paSimSettings[dwTemp], pSimSettings, sizeof(SIMSETTINGS));
|
|
pSimSettings->pwszName = NULL;
|
|
|
|
//
|
|
// Select this item.
|
|
//
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) dwTemp,
|
|
0);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If we're not replacing, add the item to the table.
|
|
//
|
|
if (dwTemp >= g_dwNumSimSettings)
|
|
{
|
|
hr = AddSimSettingsToTable(pSimSettings);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't add sim settings to table!");
|
|
goto Failure;
|
|
}
|
|
|
|
//
|
|
// Make our caller forget about the string in case we fail since the
|
|
// table owns the reference now. Keep a local copy, though.
|
|
//
|
|
pwszName = pSimSettings->pwszName;
|
|
pSimSettings->pwszName = NULL;
|
|
|
|
|
|
//
|
|
// Insert the string into the list.
|
|
//
|
|
if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
SendMessageW(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_INSERTSTRING,
|
|
(WPARAM) (g_dwNumSimSettings - 2),
|
|
(LPARAM) pwszName);
|
|
}
|
|
else
|
|
{
|
|
dwNameSize = wcslen(pwszName) + 1;
|
|
|
|
pszName = (char*) DNMalloc(dwNameSize);
|
|
if (pszName != NULL)
|
|
{
|
|
hr = STR_WideToAnsi(pwszName,
|
|
-1,
|
|
pszName,
|
|
&dwNameSize);
|
|
if (hr == DPN_OK)
|
|
{
|
|
SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_INSERTSTRING,
|
|
(WPARAM) (g_dwNumSimSettings - 2),
|
|
(LPARAM) pszName);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_INSERTSTRING,
|
|
(WPARAM) (g_dwNumSimSettings - 2),
|
|
(LPARAM) "???");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_INSERTSTRING,
|
|
(WPARAM) (g_dwNumSimSettings - 2),
|
|
(LPARAM) "???");
|
|
}
|
|
}
|
|
|
|
//
|
|
// Select this new item.
|
|
//
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) (g_dwNumSimSettings - 2),
|
|
0);
|
|
|
|
|
|
//
|
|
// Disable Save As, since we just did.
|
|
//
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Write this item to the registry (overwrites anything that existed).
|
|
//
|
|
|
|
hr = RegCreateKey(HKEY_CURRENT_USER, REG_KEY_CUSTOMSETTINGS, &hKey);
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't create custom settings key!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
#ifdef UNICODE
|
|
hr = RegSetValueExW(hKey,
|
|
pwszName,
|
|
0,
|
|
REG_BINARY,
|
|
(BYTE*) pSimSettings,
|
|
sizeof(SIMSETTINGS));
|
|
#else // ! UNICODE
|
|
hr = RegSetValueExA(hKey,
|
|
pszName,
|
|
0,
|
|
REG_BINARY,
|
|
(BYTE*) pSimSettings,
|
|
sizeof(SIMSETTINGS));
|
|
#endif // ! UNICODE
|
|
if (hr != ERROR_SUCCESS)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't write value!");
|
|
goto Failure;
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
|
|
hr = DP8SIM_OK;
|
|
|
|
|
|
Exit:
|
|
|
|
if (pszName != NULL)
|
|
{
|
|
DNFree(pszName);
|
|
pszName = NULL;
|
|
}
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
if (hKey != NULL)
|
|
{
|
|
RegCloseKey(hKey);
|
|
hKey = NULL;
|
|
}
|
|
|
|
goto Exit;
|
|
} // SaveSimSettings
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "InitializeUserInterface()"
|
|
//=============================================================================
|
|
// InitializeUserInterface
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Prepares the user interface.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
// int iShowCmd - Show state of window.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT InitializeUserInterface(HINSTANCE hInstance, int iShowCmd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WNDCLASSEX wcex;
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Parameters: (0x%p, %i)", hInstance, iShowCmd);
|
|
|
|
|
|
/*
|
|
//
|
|
// Setup common controls (we need the listview item).
|
|
//
|
|
InitCommonControls();
|
|
*/
|
|
|
|
|
|
//
|
|
// Register the main window class
|
|
//
|
|
ZeroMemory(&wcex, sizeof (WNDCLASSEX));
|
|
wcex.cbSize = sizeof(wcex);
|
|
GetClassInfoEx(NULL, WC_DIALOG, &wcex);
|
|
wcex.lpfnWndProc = MainWindowDlgProc;
|
|
wcex.hInstance = hInstance;
|
|
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
|
|
wcex.lpszMenuName = NULL;
|
|
wcex.lpszClassName = WINDOWCLASS_MAIN;
|
|
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
|
if (! RegisterClassEx(&wcex))
|
|
{
|
|
hr = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Couldn't register main window class (err = 0x%lx)!", hr);
|
|
|
|
if (hr == S_OK)
|
|
hr = E_FAIL;
|
|
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Register the Save As/Name Settings window class
|
|
//
|
|
ZeroMemory(&wcex, sizeof (WNDCLASSEX));
|
|
wcex.cbSize = sizeof(wcex);
|
|
GetClassInfoEx(NULL, WC_DIALOG, &wcex);
|
|
wcex.lpfnWndProc = NameSettingsWindowDlgProc;
|
|
wcex.hInstance = hInstance;
|
|
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
|
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
|
|
wcex.lpszMenuName = NULL;
|
|
wcex.lpszClassName = WINDOWCLASS_NAMESETTINGS;
|
|
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
|
if (! RegisterClassEx(&wcex))
|
|
{
|
|
hr = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Couldn't register name settings window class (err = 0x%lx)!", hr);
|
|
|
|
if (hr == S_OK)
|
|
hr = E_FAIL;
|
|
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Create the main window.
|
|
//
|
|
g_hWndMainWindow = CreateDialog(hInstance,
|
|
MAKEINTRESOURCE(IDD_MAIN),
|
|
NULL,
|
|
MainWindowDlgProc);
|
|
if (g_hWndMainWindow == NULL)
|
|
{
|
|
hr = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Couldn't create window (err = 0x%lx)!", hr);
|
|
|
|
if (hr == S_OK)
|
|
hr = E_FAIL;
|
|
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
UpdateWindow(g_hWndMainWindow);
|
|
ShowWindow(g_hWndMainWindow, iShowCmd);
|
|
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 6, "Returning [0x%lx]", hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
goto Exit;
|
|
} // InitializeUserInterface
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CleanupUserInterface()"
|
|
//=============================================================================
|
|
// CleanupUserInterface
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Cleans up the user interface.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT CleanupUserInterface(void)
|
|
{
|
|
DPFX(DPFPREP, 6, "Enter");
|
|
|
|
DPFX(DPFPREP, 6, "Returning [S_OK]");
|
|
|
|
return S_OK;
|
|
} // CleanupUserInterface
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DoErrorBox()"
|
|
//=============================================================================
|
|
// DoErrorBox
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Loads error strings from the given resources, and displays an
|
|
// error dialog with that text.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Handle to current application instance.
|
|
// HWND hWndParent - Parent window, or NULL if none.
|
|
// UINT uiCaptionStringRsrcID - ID of caption string resource.
|
|
// UINT uiTextStringRsrcID - ID of text string resource.
|
|
//
|
|
// Returns: None.
|
|
//=============================================================================
|
|
void DoErrorBox(const HINSTANCE hInstance,
|
|
const HWND hWndParent,
|
|
const UINT uiCaptionStringRsrcID,
|
|
const UINT uiTextStringRsrcID)
|
|
{
|
|
HRESULT hr;
|
|
WCHAR * pwszCaption = NULL;
|
|
WCHAR * pwszText = NULL;
|
|
DWORD dwStringLength;
|
|
char * pszCaption = NULL;
|
|
char * pszText = NULL;
|
|
int iReturn;
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Parameters: (0x%p, 0x%p, %u, %u)",
|
|
hInstance, hWndParent, uiCaptionStringRsrcID, uiTextStringRsrcID);
|
|
|
|
|
|
//
|
|
// Load the dialog caption string.
|
|
//
|
|
hr = LoadAndAllocString(hInstance, uiCaptionStringRsrcID, &pwszCaption);
|
|
if (FAILED(hr))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't load caption string (err = 0x%lx)!", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Load the dialog text string.
|
|
//
|
|
hr = LoadAndAllocString(hInstance, uiTextStringRsrcID, &pwszText);
|
|
if (FAILED(hr))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't load text string (err = 0x%lx)!", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Convert the text to ANSI, if required, otherwise display the Unicode
|
|
// message box.
|
|
//
|
|
if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
//
|
|
// Convert caption string to ANSI.
|
|
//
|
|
|
|
dwStringLength = wcslen(pwszCaption) + 1;
|
|
|
|
pszCaption = (char*) DNMalloc(dwStringLength);
|
|
if (pszCaption == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory for caption string!");
|
|
goto Exit;
|
|
}
|
|
|
|
hr = STR_WideToAnsi(pwszCaption, dwStringLength, pszCaption, &dwStringLength);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't convert wide string to ANSI (err = 0x%lx)!", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
//
|
|
// Convert caption string to ANSI.
|
|
//
|
|
|
|
dwStringLength = wcslen(pwszText) + 1;
|
|
|
|
pszText = (char*) DNMalloc(dwStringLength);
|
|
if (pszText == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory for text string!");
|
|
goto Exit;
|
|
}
|
|
|
|
hr = STR_WideToAnsi(pwszText, dwStringLength, pszText, &dwStringLength);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't convert wide string to ANSI (err = 0x%lx)!", hr);
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
iReturn = MessageBoxA(hWndParent,
|
|
pszText,
|
|
pszCaption,
|
|
(MB_OK | MB_ICONERROR | MB_APPLMODAL));
|
|
|
|
DNFree(pszText);
|
|
pszText = NULL;
|
|
|
|
DNFree(pszCaption);
|
|
pszCaption = NULL;
|
|
}
|
|
else
|
|
{
|
|
iReturn = MessageBoxW(hWndParent,
|
|
pwszText,
|
|
pwszCaption,
|
|
(MB_OK | MB_ICONERROR | MB_APPLMODAL));
|
|
}
|
|
|
|
if (iReturn != IDOK)
|
|
{
|
|
//
|
|
// Something bad happened.
|
|
//
|
|
|
|
hr = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Got unexpected return value %i when displaying message box (err = 0x%lx)!",
|
|
iReturn, hr);
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
if (pszText != NULL)
|
|
{
|
|
DNFree(pszText);
|
|
pszText = NULL;
|
|
}
|
|
|
|
if (pszCaption != NULL)
|
|
{
|
|
DNFree(pszCaption);
|
|
pszCaption = NULL;
|
|
}
|
|
|
|
if (pwszText != NULL)
|
|
{
|
|
DNFree(pwszText);
|
|
pwszText = NULL;
|
|
}
|
|
|
|
if (pwszCaption != NULL)
|
|
{
|
|
DNFree(pwszCaption);
|
|
pwszCaption = NULL;
|
|
}
|
|
|
|
|
|
DPFX(DPFPREP, 6, "Leave");
|
|
} // DoErrorBox
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "FloatToString"
|
|
//=============================================================================
|
|
// FloatToString
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Converts a FLOAT into a string, using the buffer supplied.
|
|
// The value must be non-negative, and the precision must be at
|
|
// least 1.
|
|
// In some cases, the value may get rounded down incorrectly, so
|
|
// a reasonably large precision is recommended.
|
|
//
|
|
// Arguments:
|
|
// FLOAT fValue - Value to convert.
|
|
// int iPrecision - Number of digits to retain after the decimal
|
|
// point.
|
|
// char * szBuffer - Buffer in which to store resulting string.
|
|
// int iBufferLength - Maximum number of characters in buffer, including
|
|
// NULL termination.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
void FloatToString(const FLOAT fValue,
|
|
const int iPrecision,
|
|
char * const szBuffer,
|
|
const int iBufferLength)
|
|
{
|
|
char * pszDigitString;
|
|
int iDecimal;
|
|
int iTemp;
|
|
char * pSource;
|
|
char * pDest;
|
|
|
|
|
|
//
|
|
// The value must be non-negative.
|
|
//
|
|
DNASSERT(fValue >= 0.0);
|
|
|
|
//
|
|
// The precision must be at least 1.
|
|
//
|
|
DNASSERT(iPrecision >= 1);
|
|
|
|
//
|
|
// The buffer needs to be large enough to hold "0.", plus room for the
|
|
// precision requested, plus NULL termination.
|
|
//
|
|
DNASSERT(iBufferLength >= (2 + iPrecision + 1));
|
|
|
|
|
|
|
|
pszDigitString = _ecvt(fValue, (iBufferLength - 2), &iDecimal, &iTemp);
|
|
DNASSERT(iTemp == 0);
|
|
|
|
//
|
|
// Treat the number differently if it's 0.0, or between 0.0 and 1.0.
|
|
//
|
|
if (iDecimal <= 0)
|
|
{
|
|
pSource = pszDigitString;
|
|
pDest = szBuffer;
|
|
|
|
|
|
//
|
|
// Get the absolute decimal point position.
|
|
//
|
|
iDecimal *= -1;
|
|
|
|
|
|
//
|
|
// Use a leading "0." followed by the digit string.
|
|
//
|
|
(*pDest) = '0';
|
|
pDest++;
|
|
(*pDest) = '.';
|
|
pDest++;
|
|
|
|
|
|
//
|
|
// Make sure we can even display this number. If not, round the value
|
|
// down to 0.0.
|
|
//
|
|
if (iDecimal >= iPrecision)
|
|
{
|
|
(*pDest) = '0';
|
|
pDest++;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Fill in the appropriate number of 0s
|
|
//
|
|
for(iTemp = 0; iTemp < iDecimal; iTemp++)
|
|
{
|
|
(*pDest) = '0';
|
|
pDest++;
|
|
}
|
|
|
|
//
|
|
// Copy the non-zero digits indicated by _ecvt.
|
|
// Note that this truncates down, which may cause rounding errors.
|
|
//
|
|
do
|
|
{
|
|
(*pDest) = (*pSource);
|
|
pSource++;
|
|
pDest++;
|
|
iTemp++;
|
|
}
|
|
while (iTemp < iPrecision);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Make sure the value isn't too large to display properly.
|
|
//
|
|
DNASSERT(iDecimal < (iBufferLength - 2));
|
|
|
|
|
|
pSource = pszDigitString;
|
|
pDest = szBuffer;
|
|
|
|
|
|
//
|
|
// Copy the digits to the left of the decimal.
|
|
//
|
|
memcpy(pDest, pSource, (iDecimal * sizeof(char)));
|
|
pSource += iDecimal;
|
|
pDest += iDecimal;
|
|
|
|
|
|
//
|
|
// Add the decimal.
|
|
//
|
|
(*pDest) = '.';
|
|
pDest++;
|
|
|
|
|
|
//
|
|
// Copy the digits to the right of the decimal up to the precision.
|
|
// Note that this truncates down, which may cause rounding errors.
|
|
//
|
|
memcpy(pDest, pSource, (iPrecision * sizeof(char)));
|
|
pDest += iPrecision;
|
|
}
|
|
|
|
|
|
//
|
|
// Remove all trailing '0' characters, unless there's nothing to the
|
|
// right of the decimal point, in which case leave a single '0'.
|
|
//
|
|
|
|
do
|
|
{
|
|
pDest--;
|
|
}
|
|
while ((*pDest) == '0');
|
|
|
|
if ((*pDest) == '.')
|
|
{
|
|
*(pDest + 2) = 0; // NULL terminate after a '0'
|
|
}
|
|
else
|
|
{
|
|
*(pDest + 1) = 0; // NULL terminate after this character
|
|
}
|
|
} // FloatToString
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "GetParametersFromWindow"
|
|
//=============================================================================
|
|
// GetParametersFromWindow
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Reads in the DP8Sim parameters from the given window.
|
|
//
|
|
// Arguments:
|
|
// HWND hWnd - Window with parameters to read.
|
|
// DP8SIM_PARAMETERS * pdp8spSend - Place to store send parameters.
|
|
// DP8SIM_PARAMETERS * pdp8spReceive - Place to store receive parameters.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
void GetParametersFromWindow(HWND hWnd,
|
|
DP8SIM_PARAMETERS * pdp8spSend,
|
|
DP8SIM_PARAMETERS * pdp8spReceive)
|
|
{
|
|
char szNumber[32];
|
|
|
|
|
|
//
|
|
// Retrieve the send settings from the window.
|
|
//
|
|
|
|
ZeroMemory(pdp8spSend, sizeof(*pdp8spSend));
|
|
pdp8spSend->dwSize = sizeof(*pdp8spSend);
|
|
//pdp8spSend->dwFlags = 0;
|
|
pdp8spSend->dwPacketHeaderSize = DP8SIMPACKETHEADERSIZE_IP_UDP;
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_BANDWIDTH), szNumber, 32);
|
|
pdp8spSend->dwBandwidthBPS = (DWORD) atoi(szNumber);
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_DROP), szNumber, 32);
|
|
pdp8spSend->fPacketLossPercent = (FLOAT) atof(szNumber);
|
|
if (pdp8spSend->fPacketLossPercent > 100.0)
|
|
{
|
|
pdp8spSend->fPacketLossPercent = 100.0;
|
|
}
|
|
else if (pdp8spSend->fPacketLossPercent < 0.0)
|
|
{
|
|
pdp8spSend->fPacketLossPercent = 0.0;
|
|
}
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MINLATENCY), szNumber, 32);
|
|
pdp8spSend->dwMinLatencyMS = (DWORD) atoi(szNumber);
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MAXLATENCY), szNumber, 32);
|
|
pdp8spSend->dwMaxLatencyMS = (DWORD) atoi(szNumber);
|
|
if (pdp8spSend->dwMaxLatencyMS < pdp8spSend->dwMinLatencyMS)
|
|
{
|
|
pdp8spSend->dwMaxLatencyMS = pdp8spSend->dwMinLatencyMS;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Retrieve the receive settings from the window.
|
|
//
|
|
|
|
ZeroMemory(pdp8spReceive, sizeof(*pdp8spReceive));
|
|
pdp8spReceive->dwSize = sizeof(*pdp8spReceive);
|
|
//pdp8spReceive->dwFlags = 0;
|
|
pdp8spReceive->dwPacketHeaderSize = DP8SIMPACKETHEADERSIZE_IP_UDP;
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_BANDWIDTH), szNumber, 32);
|
|
pdp8spReceive->dwBandwidthBPS = (DWORD) atoi(szNumber);
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_DROP), szNumber, 32);
|
|
pdp8spReceive->fPacketLossPercent = (FLOAT) atof(szNumber);
|
|
if (pdp8spReceive->fPacketLossPercent > 100.0)
|
|
{
|
|
pdp8spReceive->fPacketLossPercent = 100.0;
|
|
}
|
|
else if (pdp8spReceive->fPacketLossPercent < 0.0)
|
|
{
|
|
pdp8spReceive->fPacketLossPercent = 0.0;
|
|
}
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MINLATENCY), szNumber, 32);
|
|
pdp8spReceive->dwMinLatencyMS = (DWORD) atoi(szNumber);
|
|
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MAXLATENCY), szNumber, 32);
|
|
pdp8spReceive->dwMaxLatencyMS = (DWORD) atoi(szNumber);
|
|
if (pdp8spReceive->dwMaxLatencyMS < pdp8spReceive->dwMinLatencyMS)
|
|
{
|
|
pdp8spReceive->dwMaxLatencyMS = pdp8spReceive->dwMinLatencyMS;
|
|
}
|
|
} // GetParametersFromWindow
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "SetParametersInWindow"
|
|
//=============================================================================
|
|
// SetParametersInWindow
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Writes the DP8Sim parameters to the given window.
|
|
//
|
|
// Arguments:
|
|
// HWND hWnd - Window in which to store parameters.
|
|
// DP8SIM_PARAMETERS * pdp8spSend - Pointer to new send parameters.
|
|
// DP8SIM_PARAMETERS * pdp8spReceive - Pointer to new receive parameters.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
void SetParametersInWindow(HWND hWnd,
|
|
DP8SIM_PARAMETERS * pdp8spSend,
|
|
DP8SIM_PARAMETERS * pdp8spReceive)
|
|
{
|
|
char szNumber[32];
|
|
|
|
|
|
//
|
|
// Write the values to the window.
|
|
//
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spSend->dwBandwidthBPS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_BANDWIDTH), szNumber);
|
|
|
|
FloatToString(pdp8spSend->fPacketLossPercent, DISPLAY_PRECISION, szNumber, 32);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_DROP), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spSend->dwMinLatencyMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MINLATENCY), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spSend->dwMaxLatencyMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MAXLATENCY), szNumber);
|
|
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spReceive->dwBandwidthBPS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_BANDWIDTH), szNumber);
|
|
|
|
FloatToString(pdp8spReceive->fPacketLossPercent, DISPLAY_PRECISION, szNumber, 32);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_DROP), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spReceive->dwMinLatencyMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MINLATENCY), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", pdp8spReceive->dwMaxLatencyMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MAXLATENCY), szNumber);
|
|
} // SetParametersInWindow
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DisplayCurrentStatistics"
|
|
//=============================================================================
|
|
// DisplayCurrentStatistics
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Retrieves the current DP8Sim statistics and displays them in
|
|
// the given window.
|
|
//
|
|
// Arguments:
|
|
// HWND hWnd - Window in which to write statistics.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
void DisplayCurrentStatistics(HWND hWnd)
|
|
{
|
|
HRESULT hr;
|
|
DP8SIM_STATISTICS dp8ssSend;
|
|
DP8SIM_STATISTICS dp8ssReceive;
|
|
char szNumber[32];
|
|
|
|
|
|
//
|
|
// Retrieve the current statistics.
|
|
//
|
|
|
|
ZeroMemory(&dp8ssSend, sizeof(dp8ssSend));
|
|
dp8ssSend.dwSize = sizeof(dp8ssSend);
|
|
|
|
ZeroMemory(&dp8ssReceive, sizeof(dp8ssReceive));
|
|
dp8ssReceive.dwSize = sizeof(dp8ssReceive);
|
|
|
|
hr = g_pDP8SimControl->GetAllStatistics(&dp8ssSend, &dp8ssReceive, 0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Getting all statistics failed (err = 0x%lx)!", hr);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Write the values to the window.
|
|
//
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssSend.dwTransmittedPackets);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITPACKETS), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssSend.dwTransmittedBytes);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITBYTES), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssSend.dwDroppedPackets);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPPACKETS), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssSend.dwDroppedBytes);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPBYTES), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssSend.dwTotalDelayMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_TOTALDELAY), szNumber);
|
|
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssReceive.dwTransmittedPackets);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITPACKETS), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssReceive.dwTransmittedBytes);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITBYTES), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssReceive.dwDroppedPackets);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPPACKETS), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssReceive.dwDroppedBytes);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPBYTES), szNumber);
|
|
|
|
wsprintfA(szNumber, "%u", dp8ssReceive.dwTotalDelayMS);
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_TOTALDELAY), szNumber);
|
|
}
|
|
} // DisplayCurrentStatistics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "MainWindowDlgProc()"
|
|
//=============================================================================
|
|
// MainWindowDlgProc
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Main dialog window message handling.
|
|
//
|
|
// Arguments:
|
|
// HWND hWnd Window handle.
|
|
// UINT uMsg Message identifier.
|
|
// WPARAM wParam Depends on message.
|
|
// LPARAM lParam Depends on message.
|
|
//
|
|
// Returns: Depends on message.
|
|
//=============================================================================
|
|
INT_PTR CALLBACK MainWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HRESULT hr;
|
|
//HMENU hSysMenu;
|
|
HWND hWndSubItem;
|
|
int iIndex;
|
|
DP8SIM_PARAMETERS dp8spSend;
|
|
DP8SIM_PARAMETERS dp8spReceive;
|
|
BOOL fTemp;
|
|
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
/*
|
|
//
|
|
// Disable 'maximize' and 'size' on the system menu.
|
|
//
|
|
hSysMenu = GetSystemMenu(hWnd, FALSE);
|
|
|
|
EnableMenuItem(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
|
|
EnableMenuItem(hSysMenu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
|
|
*/
|
|
|
|
|
|
//
|
|
// Fill in the list of built-in settings.
|
|
//
|
|
hWndSubItem = GetDlgItem(hWnd, IDCB_SETTINGS);
|
|
for(iIndex = 0; iIndex < (int) g_dwNumSimSettings; iIndex++)
|
|
{
|
|
if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
SendMessageW(hWndSubItem,
|
|
CB_INSERTSTRING,
|
|
(WPARAM) -1,
|
|
(LPARAM) g_paSimSettings[iIndex].pwszName);
|
|
}
|
|
else
|
|
{
|
|
char * pszName;
|
|
DWORD dwNameSize;
|
|
|
|
|
|
dwNameSize = wcslen(g_paSimSettings[iIndex].pwszName) + 1;
|
|
|
|
pszName = (char*) DNMalloc(dwNameSize);
|
|
if (pszName != NULL)
|
|
{
|
|
hr = STR_WideToAnsi(g_paSimSettings[iIndex].pwszName,
|
|
-1,
|
|
pszName,
|
|
&dwNameSize);
|
|
if (hr == DPN_OK)
|
|
{
|
|
SendMessageA(hWndSubItem,
|
|
CB_INSERTSTRING,
|
|
(WPARAM) -1,
|
|
(LPARAM) pszName);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(hWndSubItem,
|
|
CB_INSERTSTRING,
|
|
(WPARAM) -1,
|
|
(LPARAM) "???");
|
|
}
|
|
|
|
DNFree(pszName);
|
|
}
|
|
else
|
|
{
|
|
SendMessageA(hWndSubItem,
|
|
CB_INSERTSTRING,
|
|
(WPARAM) -1,
|
|
(LPARAM) "???");
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Select the last item.
|
|
//
|
|
SendMessage(hWndSubItem, CB_SETCURSEL, (WPARAM) (iIndex - 1), 0);
|
|
|
|
|
|
//
|
|
// Retrieve the current settings.
|
|
//
|
|
|
|
ZeroMemory(&dp8spSend, sizeof(dp8spSend));
|
|
dp8spSend.dwSize = sizeof(dp8spSend);
|
|
|
|
ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
|
|
dp8spReceive.dwSize = sizeof(dp8spReceive);
|
|
|
|
hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Write the values to the window.
|
|
//
|
|
SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
|
|
|
|
|
|
//
|
|
// SetParametersInWindow updated the edit boxes, and thus
|
|
// caused the "Custom" settings item to get selected.
|
|
// See if these settings match any of the presets, and if
|
|
// so, politely reset the combo box back to the appropriate
|
|
// item.
|
|
//
|
|
for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
|
|
{
|
|
if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
|
|
(memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
|
|
{
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) iIndex,
|
|
0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Enable "Save As" if on the Custom setting.
|
|
//
|
|
if (iIndex == (int) (g_dwNumSimSettings - 1))
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Display the current statistics.
|
|
//
|
|
DisplayCurrentStatistics(hWnd);
|
|
|
|
|
|
//
|
|
// Turn on auto-refresh by default.
|
|
//
|
|
|
|
Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH), BST_CHECKED);
|
|
|
|
g_uiAutoRefreshTimer = SetTimer(hWnd,
|
|
AUTOREFRESH_TIMERID,
|
|
AUTOREFRESH_INTERVAL,
|
|
NULL);
|
|
if (g_uiAutoRefreshTimer == 0)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't initially start auto-refresh timer!", 0);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
|
|
BST_UNCHECKED);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case WM_SIZE:
|
|
{
|
|
/*
|
|
//
|
|
// Fix a bug in the windows dialog handler.
|
|
//
|
|
if ((wParam == SIZE_RESTORED) || (wParam == SIZE_MINIMIZED))
|
|
{
|
|
hSysMenu = GetSystemMenu(hWnd, FALSE);
|
|
|
|
EnableMenuItem(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND | (wParam == SIZE_RESTORED) ? MF_ENABLED : MF_GRAYED);
|
|
EnableMenuItem(hSysMenu, SC_RESTORE, MF_BYCOMMAND | (wParam == SIZE_MINIMIZED) ? MF_ENABLED : MF_GRAYED);
|
|
}
|
|
*/
|
|
break;
|
|
}
|
|
|
|
case WM_CLOSE:
|
|
{
|
|
//
|
|
// Save the result code for how we quit.
|
|
//
|
|
hr = (HRESULT) wParam;
|
|
|
|
|
|
//
|
|
// Kill the auto-refresh timer, if it was running.
|
|
//
|
|
if (g_uiAutoRefreshTimer != 0)
|
|
{
|
|
KillTimer(hWnd, g_uiAutoRefreshTimer);
|
|
g_uiAutoRefreshTimer = 0;
|
|
}
|
|
|
|
|
|
DPFX(DPFPREP, 1, "Closing main window (hresult = 0x%lx).", hr);
|
|
|
|
PostQuitMessage(hr);
|
|
break;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDCB_SETTINGS:
|
|
{
|
|
DPFX(DPFPREP, 0, "IDCB_SETTINGS, selection = %i",
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS), CB_GETCURSEL, 0, 0));
|
|
|
|
//
|
|
// If the settings selection has been modified, update the
|
|
// data with the new settings (if control is enabled).
|
|
//
|
|
if (HIWORD(wParam) == CBN_SELCHANGE)
|
|
{
|
|
//
|
|
// Find out what is now selected. Casting is okay,
|
|
// there should not be more than an int's worth of
|
|
// built-in items in 64-bit.
|
|
//
|
|
iIndex = (int) SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_GETCURSEL,
|
|
0,
|
|
0);
|
|
|
|
//
|
|
// Only use the index if it's valid.
|
|
//
|
|
if ((iIndex >= 0) && (iIndex < (int) g_dwNumSimSettings))
|
|
{
|
|
//
|
|
// Copy in the item's settings.
|
|
//
|
|
memcpy(&dp8spSend, &g_paSimSettings[iIndex].dp8spSend, sizeof(dp8spSend));
|
|
memcpy(&dp8spReceive, &g_paSimSettings[iIndex].dp8spReceive, sizeof(dp8spReceive));
|
|
|
|
|
|
//
|
|
// If it's the custom item, use the current
|
|
// settings and enable the Save As button.
|
|
//
|
|
if (iIndex == (int) (g_dwNumSimSettings - 1))
|
|
{
|
|
//
|
|
// Retrieve the current settings.
|
|
//
|
|
|
|
ZeroMemory(&dp8spSend, sizeof(dp8spSend));
|
|
dp8spSend.dwSize = sizeof(dp8spSend);
|
|
|
|
ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
|
|
dp8spReceive.dwSize = sizeof(dp8spReceive);
|
|
|
|
hr = g_pDP8SimControl->GetAllParameters(&dp8spSend,
|
|
&dp8spReceive,
|
|
0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
|
|
|
|
//
|
|
// Oh well, just use whatever we have.
|
|
//
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Write the values to the window.
|
|
//
|
|
SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
|
|
|
|
|
|
//
|
|
// The apply and revert buttons got enabled
|
|
// automatically when SetParametersInWindow set the
|
|
// edit boxes' values.
|
|
//
|
|
//EnableWindow(GetDlgItem(hWnd, IDB_APPLY), TRUE);
|
|
//EnableWindow(GetDlgItem(hWnd, IDB_REVERT), TRUE);
|
|
|
|
|
|
//
|
|
// Reselect the item that got us here, since
|
|
// setting the edit boxes' values automatically
|
|
// selected the "Custom" item.
|
|
//
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) iIndex,
|
|
0);
|
|
|
|
//
|
|
// Reset the Save As status depending on whether
|
|
// we reselected the Custom or not.
|
|
//
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS),
|
|
((iIndex == (int) (g_dwNumSimSettings - 1)) ? TRUE : FALSE));
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 0, "Settings selection is invalid (%i)!",
|
|
iIndex);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDE_SETTINGS_SEND_BANDWIDTH:
|
|
case IDE_SETTINGS_SEND_DROP:
|
|
case IDE_SETTINGS_SEND_MINLATENCY:
|
|
case IDE_SETTINGS_SEND_MAXLATENCY:
|
|
|
|
case IDE_SETTINGS_RECV_BANDWIDTH:
|
|
case IDE_SETTINGS_RECV_DROP:
|
|
case IDE_SETTINGS_RECV_MINLATENCY:
|
|
case IDE_SETTINGS_RECV_MAXLATENCY:
|
|
{
|
|
//
|
|
// If the edit boxes have been modified, enable the Apply
|
|
// and Revert buttons (if control is enabled and the data
|
|
// actually changed).
|
|
//
|
|
if (HIWORD(wParam) == EN_UPDATE)
|
|
{
|
|
//
|
|
// Retrieve the current settings.
|
|
//
|
|
|
|
ZeroMemory(&dp8spSend, sizeof(dp8spSend));
|
|
dp8spSend.dwSize = sizeof(dp8spSend);
|
|
|
|
ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
|
|
dp8spReceive.dwSize = sizeof(dp8spReceive);
|
|
|
|
hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
|
|
}
|
|
else
|
|
{
|
|
DP8SIM_PARAMETERS dp8spSendFromUI;
|
|
DP8SIM_PARAMETERS dp8spReceiveFromUI;
|
|
|
|
|
|
GetParametersFromWindow(hWnd,
|
|
&dp8spSendFromUI,
|
|
&dp8spReceiveFromUI);
|
|
|
|
|
|
//
|
|
// Enable the buttons if any data is different from
|
|
// what is currently applied.
|
|
//
|
|
|
|
fTemp = FALSE;
|
|
if (memcmp(&dp8spSendFromUI, &dp8spSend, sizeof(dp8spSend)) != 0)
|
|
{
|
|
fTemp = TRUE;
|
|
}
|
|
if (memcmp(&dp8spReceiveFromUI, &dp8spReceive, sizeof(dp8spReceive)) != 0)
|
|
{
|
|
fTemp = TRUE;
|
|
}
|
|
|
|
EnableWindow(GetDlgItem(hWnd, IDB_APPLY), fTemp);
|
|
EnableWindow(GetDlgItem(hWnd, IDB_REVERT), fTemp);
|
|
}
|
|
|
|
|
|
//
|
|
// Select the "Custom" settings item, which must be the
|
|
// last item.
|
|
//
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) (g_dwNumSimSettings - 1),
|
|
0);
|
|
|
|
//
|
|
// Enable Save As, since Custom is now selected.
|
|
//
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDB_APPLY:
|
|
{
|
|
//
|
|
// Retrieve the settings from the window.
|
|
//
|
|
GetParametersFromWindow(hWnd, &dp8spSend, &dp8spReceive);
|
|
|
|
|
|
//
|
|
// Parsing in the parameters may have corrected some errors
|
|
// in user entry, so write the settings we're really using
|
|
// back out to the window.
|
|
//
|
|
SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
|
|
|
|
|
|
//
|
|
// SetParametersInWindow updated the edit boxes, and thus
|
|
// caused the "Custom" settings item to get selected.
|
|
// See if these settings match any of the presets, and if
|
|
// so, politely reset the combo box back to the appropriate
|
|
// item.
|
|
//
|
|
for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
|
|
{
|
|
if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
|
|
(memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
|
|
{
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) iIndex,
|
|
0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If the custom item is selected, enable Save As,
|
|
// otherwise, disable it.
|
|
//
|
|
if (iIndex >= (int) (g_dwNumSimSettings - 1))
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Store those settings.
|
|
//
|
|
hr = g_pDP8SimControl->SetAllParameters(&dp8spSend, &dp8spReceive, 0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Setting all parameters failed (err = 0x%lx)!", hr);
|
|
}
|
|
|
|
|
|
//
|
|
// Disable the Apply and Revert buttons
|
|
//
|
|
EnableWindow(GetDlgItem(hWnd, IDB_APPLY), FALSE);
|
|
EnableWindow(GetDlgItem(hWnd, IDB_REVERT), FALSE);
|
|
|
|
break;
|
|
}
|
|
|
|
case IDB_REVERT:
|
|
{
|
|
//
|
|
// Retrieve the current settings.
|
|
//
|
|
|
|
ZeroMemory(&dp8spSend, sizeof(dp8spSend));
|
|
dp8spSend.dwSize = sizeof(dp8spSend);
|
|
|
|
ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
|
|
dp8spReceive.dwSize = sizeof(dp8spReceive);
|
|
|
|
hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Write the values to the window.
|
|
//
|
|
SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
|
|
|
|
|
|
//
|
|
// SetParametersInWindow updated the edit boxes, and
|
|
// thus caused the "Custom" settings item to get
|
|
// selected. See if these settings match any of the
|
|
// presets, and if so, politely reset the combo box
|
|
// back to the appropriate item.
|
|
//
|
|
for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
|
|
{
|
|
if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
|
|
(memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
|
|
{
|
|
SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
|
|
CB_SETCURSEL,
|
|
(WPARAM) iIndex,
|
|
0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// If the custom item is selected, enable Save As,
|
|
// otherwise, disable it.
|
|
//
|
|
if (iIndex >= (int) (g_dwNumSimSettings - 1))
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Disable the Apply and Revert buttons
|
|
//
|
|
EnableWindow(GetDlgItem(hWnd, IDB_APPLY), FALSE);
|
|
EnableWindow(GetDlgItem(hWnd, IDB_REVERT), FALSE);
|
|
|
|
break;
|
|
}
|
|
|
|
case IDB_SAVEAS:
|
|
{
|
|
SIMSETTINGS SimSettings;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "Saving current sim settings.");
|
|
|
|
//
|
|
// Retrieve the settings from the window.
|
|
//
|
|
memset(&SimSettings, 0, sizeof(SimSettings));
|
|
GetParametersFromWindow(hWnd,
|
|
&SimSettings.dp8spSend,
|
|
&SimSettings.dp8spReceive);
|
|
|
|
|
|
//
|
|
// Prompt the user to name the current custom settings.
|
|
//
|
|
hr = (HRESULT) (INT_PTR) DialogBoxParam((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
|
|
MAKEINTRESOURCE(IDD_NAMESETTINGS),
|
|
hWnd,
|
|
NameSettingsWindowDlgProc,
|
|
(LPARAM) (&SimSettings));
|
|
if (hr != (HRESULT) -1)
|
|
{
|
|
//
|
|
// If we got a name, insert it into the table.
|
|
//
|
|
if (SimSettings.pwszName != NULL)
|
|
{
|
|
hr = SaveSimSettings(hWnd, &SimSettings);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't add sim settings to table (err = 0x%lx)!",
|
|
hr);
|
|
|
|
if (SimSettings.pwszName != NULL)
|
|
{
|
|
DNFree(SimSettings.pwszName);
|
|
SimSettings.pwszName = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = GetLastError();
|
|
DPFX(DPFPREP, 0, "Displaying name settings dialog failed (err = %u)!",
|
|
hr);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDCHK_AUTOREFRESH:
|
|
{
|
|
if (Button_GetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH)) == BST_CHECKED)
|
|
{
|
|
//
|
|
// Set the timer, if it wasn't already.
|
|
//
|
|
if (g_uiAutoRefreshTimer == 0)
|
|
{
|
|
g_uiAutoRefreshTimer = SetTimer(hWnd,
|
|
AUTOREFRESH_TIMERID,
|
|
AUTOREFRESH_INTERVAL,
|
|
NULL);
|
|
if (g_uiAutoRefreshTimer == 0)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't start auto-refresh timer!", 0);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
|
|
BST_UNCHECKED);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Kill the timer, if it was running.
|
|
//
|
|
if (g_uiAutoRefreshTimer != 0)
|
|
{
|
|
KillTimer(hWnd, g_uiAutoRefreshTimer);
|
|
g_uiAutoRefreshTimer = 0;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDB_REFRESH:
|
|
{
|
|
//
|
|
// Display the current statistics.
|
|
//
|
|
DisplayCurrentStatistics(hWnd);
|
|
break;
|
|
}
|
|
|
|
case IDB_CLEAR:
|
|
{
|
|
//
|
|
// Clear the statistics.
|
|
//
|
|
hr = g_pDP8SimControl->ClearAllStatistics(0);
|
|
if (hr != DP8SIM_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Clearing all statistics failed (err = 0x%lx)!", hr);
|
|
}
|
|
else
|
|
{
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITPACKETS), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITBYTES), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPPACKETS), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPBYTES), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_TOTALDELAY), "0");
|
|
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITPACKETS), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITBYTES), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPPACKETS), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPBYTES), "0");
|
|
SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_TOTALDELAY), "0");
|
|
}
|
|
break;
|
|
}
|
|
|
|
case IDOK:
|
|
{
|
|
PostMessage(hWnd, WM_CLOSE, 0, 0);
|
|
break;
|
|
}
|
|
} // end switch (on the button pressed/control changed)
|
|
|
|
break;
|
|
}
|
|
|
|
case WM_TIMER:
|
|
{
|
|
//
|
|
// Display the current statistics.
|
|
//
|
|
DisplayCurrentStatistics(hWnd);
|
|
|
|
|
|
//
|
|
// Reset the timer to update again.
|
|
//
|
|
g_uiAutoRefreshTimer = SetTimer(hWnd,
|
|
AUTOREFRESH_TIMERID,
|
|
AUTOREFRESH_INTERVAL,
|
|
NULL);
|
|
if (g_uiAutoRefreshTimer == 0)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't reset auto-refresh timer!", 0);
|
|
Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
|
|
BST_UNCHECKED);
|
|
}
|
|
break;
|
|
}
|
|
} // end switch (on the type of window message)
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
} // MainWindowDlgProc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "NameSettingsWindowDlgProc()"
|
|
//=============================================================================
|
|
// NameSettingsWindowDlgProc
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Name settings dialog window message handling.
|
|
//
|
|
// Arguments:
|
|
// HWND hWnd Window handle.
|
|
// UINT uMsg Message identifier.
|
|
// WPARAM wParam Depends on message.
|
|
// LPARAM lParam Depends on message.
|
|
//
|
|
// Returns: Depends on message.
|
|
//=============================================================================
|
|
INT_PTR CALLBACK NameSettingsWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SIMSETTINGS * pSimSettings;
|
|
int iTextLength;
|
|
DWORD dwTemp;
|
|
#ifndef UNICODE
|
|
char * pszName;
|
|
#endif // ! UNICODE
|
|
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
//
|
|
// Retrieve the settings to be saved.
|
|
//
|
|
pSimSettings = (SIMSETTINGS*) lParam;
|
|
|
|
//
|
|
// Store the pointer off the window.
|
|
//
|
|
SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR) pSimSettings);
|
|
|
|
//
|
|
// Set focus on the name edit text box.
|
|
//
|
|
SetFocus(GetDlgItem(hWnd, IDE_NAME));
|
|
break;
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDE_NAME:
|
|
{
|
|
//
|
|
// If the edit box has text, enable the OK button.
|
|
//
|
|
if (HIWORD(wParam) == EN_UPDATE)
|
|
{
|
|
if (GetWindowTextLength(GetDlgItem(hWnd, IDE_NAME)) > 0)
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
|
|
}
|
|
else
|
|
{
|
|
EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDOK:
|
|
{
|
|
pSimSettings = (SIMSETTINGS*) GetWindowLongPtr(hWnd, DWLP_USER);
|
|
DNASSERT(pSimSettings != NULL);
|
|
DNASSERT(pSimSettings->dp8spSend.dwSize == sizeof(DP8SIM_PARAMETERS));
|
|
DNASSERT(pSimSettings->dp8spReceive.dwSize == sizeof(DP8SIM_PARAMETERS));
|
|
|
|
//
|
|
// Save the name into the sim settings object.
|
|
//
|
|
iTextLength = GetWindowTextLength(GetDlgItem(hWnd, IDE_NAME)) + 1; // include NULL termination
|
|
pSimSettings->pwszName = (WCHAR*) DNMalloc(iTextLength * sizeof(WCHAR));
|
|
if (pSimSettings->pwszName != NULL)
|
|
{
|
|
#ifdef UNICODE
|
|
GetWindowTextW(GetDlgItem(hWnd, IDE_NAME),
|
|
pSimSettings->pwszName,
|
|
iTextLength);
|
|
#else // ! UNICODE
|
|
pszName = (char*) DNMalloc(iTextLength * sizeof(char));
|
|
if (pSimSettings->pwszName == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory to hold ANSI name!");
|
|
DNFree(pSimSettings->pwszName);
|
|
pSimSettings->pwszName = NULL;
|
|
break;
|
|
}
|
|
|
|
GetWindowTextA(GetDlgItem(hWnd, IDE_NAME),
|
|
pszName,
|
|
iTextLength);
|
|
|
|
if (STR_jkAnsiToWide(pSimSettings->pwszName, pszName, iTextLength) != DPN_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't convert ANSI name to Unicode!");
|
|
DNFree(pszName);
|
|
pszName = NULL;
|
|
DNFree(pSimSettings->pwszName);
|
|
pSimSettings->pwszName = NULL;
|
|
break;
|
|
}
|
|
|
|
DNFree(pszName);
|
|
pszName = NULL;
|
|
#endif // ! UNICODE
|
|
|
|
//
|
|
// Look for a built-in item with that name.
|
|
//
|
|
for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
|
|
{
|
|
//
|
|
// If we found it, display an error, free the
|
|
// string.
|
|
//
|
|
if ((g_paSimSettings[dwTemp].uiNameStringResourceID != 0) &&
|
|
(_wcsicmp(g_paSimSettings[dwTemp].pwszName, pSimSettings->pwszName) == 0))
|
|
{
|
|
DPFX(DPFPREP, 0, "Found existing built-in settings with name \"%ls\"!",
|
|
pSimSettings->pwszName);
|
|
|
|
DoErrorBox((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
|
|
hWnd,
|
|
IDS_ERROR_CAPTION_BUILTINSETTINGSWITHSAMENAME,
|
|
IDS_ERROR_TEXT_BUILTINSETTINGSWITHSAMENAME);
|
|
|
|
DNFree(pSimSettings->pwszName);
|
|
pSimSettings->pwszName = NULL;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we didn't find an existing item, close the
|
|
// dialog.
|
|
//
|
|
if (dwTemp >= g_dwNumSimSettings)
|
|
{
|
|
EndDialog(hWnd, IDOK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't allocate memory to hold name!");
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case IDCANCEL:
|
|
{
|
|
//
|
|
// Do nothing.
|
|
//
|
|
EndDialog(hWnd, IDCANCEL);
|
|
break;
|
|
}
|
|
} // end switch (on the button pressed/control changed)
|
|
|
|
break;
|
|
}
|
|
} // end switch (on the type of window message)
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
} // NameSettingsWindowDlgProc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "LoadAndAllocString"
|
|
//=============================================================================
|
|
// LoadAndAllocString
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: DNMallocs a wide character string from the given resource ID.
|
|
//
|
|
// Arguments:
|
|
// HINSTANCE hInstance - Module instance handle.
|
|
// UINT uiResourceID - Resource ID to load.
|
|
// WCHAR ** pwszString - Place to store pointer to allocated string.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
HRESULT LoadAndAllocString(HINSTANCE hInstance, UINT uiResourceID, WCHAR ** pwszString)
|
|
{
|
|
HRESULT hr = DPN_OK;
|
|
int iLength;
|
|
#ifdef DEBUG
|
|
DWORD dwError;
|
|
#endif // DEBUG
|
|
|
|
|
|
if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
WCHAR wszTmpBuffer[MAX_RESOURCE_STRING_LENGTH];
|
|
|
|
|
|
iLength = LoadStringW(hInstance, uiResourceID, wszTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
|
|
if (iLength == 0)
|
|
{
|
|
#ifdef DEBUG
|
|
dwError = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Unable to load resource ID %d (err = %u)", uiResourceID, dwError);
|
|
#endif // DEBUG
|
|
|
|
(*pwszString) = NULL;
|
|
hr = DPNERR_GENERIC;
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
(*pwszString) = (WCHAR*) DNMalloc((iLength + 1) * sizeof(WCHAR));
|
|
if ((*pwszString) == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Memory allocation failure!");
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
wcscpy((*pwszString), wszTmpBuffer);
|
|
}
|
|
else
|
|
{
|
|
char szTmpBuffer[MAX_RESOURCE_STRING_LENGTH];
|
|
|
|
|
|
iLength = LoadStringA(hInstance, uiResourceID, szTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
|
|
if (iLength == 0)
|
|
{
|
|
#ifdef DEBUG
|
|
dwError = GetLastError();
|
|
|
|
DPFX(DPFPREP, 0, "Unable to load resource ID %u (err = %u)!", uiResourceID, dwError);
|
|
#endif // DEBUG
|
|
|
|
(*pwszString) = NULL;
|
|
hr = DPNERR_GENERIC;
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
(*pwszString) = (WCHAR*) DNMalloc((iLength + 1) * sizeof(WCHAR));
|
|
if ((*pwszString) == NULL)
|
|
{
|
|
DPFX(DPFPREP, 0, "Memory allocation failure!");
|
|
hr = DPNERR_OUTOFMEMORY;
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
hr = STR_jkAnsiToWide((*pwszString), szTmpBuffer, (iLength + 1));
|
|
if (hr != DPN_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Unable to convert from ANSI to Unicode (err = 0x%lx)!", hr);
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
|
|
Exit:
|
|
|
|
return hr;
|
|
} // LoadAndAllocString
|