Leaked source code of windows server 2003
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

  1. /***************************************************************************
  2. *
  3. * Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dp8simuimain.cpp
  6. *
  7. * Content: DP8SIM UI executable entry point.
  8. *
  9. * History:
  10. * Date By Reason
  11. * ======== ======== =========
  12. * 04/23/01 VanceO Created.
  13. *
  14. ***************************************************************************/
  15. #include "dp8simuii.h"
  16. //=============================================================================
  17. // Defines
  18. //=============================================================================
  19. #define MAX_RESOURCE_STRING_LENGTH _MAX_PATH
  20. #define DISPLAY_PRECISION 4
  21. #define AUTOREFRESH_TIMERID 1
  22. #define AUTOREFRESH_INTERVAL 1000
  23. #define REG_KEY_DP8SIMROOT _T("Software\\Microsoft\\DirectPlay8\\DP8Sim")
  24. #define REG_KEY_CUSTOMSETTINGS REG_KEY_DP8SIMROOT _T("\\CustomSettings")
  25. //=============================================================================
  26. // Structures
  27. //=============================================================================
  28. typedef struct _SIMSETTINGS
  29. {
  30. UINT uiNameStringResourceID; // resource ID of name string, or 0 if not built-in
  31. WCHAR * pwszName; // pointer to name string
  32. DP8SIM_PARAMETERS dp8spSend; // send DP8Sim settings
  33. DP8SIM_PARAMETERS dp8spReceive; // receive DP8Sim settings
  34. } SIMSETTINGS, * PSIMSETTINGS;
  35. //=============================================================================
  36. // Dynamically loaded function prototypes
  37. //=============================================================================
  38. typedef HRESULT (WINAPI * PFN_DLLREGISTERSERVER)(void);
  39. //=============================================================================
  40. // Prototypes
  41. //=============================================================================
  42. HRESULT InitializeApplication(const HINSTANCE hInstance,
  43. const LPSTR lpszCmdLine,
  44. const int iShowCmd);
  45. HRESULT CleanupApplication(const HINSTANCE hInstance);
  46. HRESULT BuildSimSettingsTable(const HINSTANCE hInstance);
  47. void FreeSimSettingsTable(void);
  48. HRESULT AddSimSettingsToTable(const SIMSETTINGS * const pSimSettings);
  49. HRESULT SaveSimSettings(HWND hWnd, SIMSETTINGS * const pSimSettings);
  50. HRESULT InitializeUserInterface(const HINSTANCE hInstance,
  51. const int iShowCmd);
  52. HRESULT CleanupUserInterface(void);
  53. void DoErrorBox(const HINSTANCE hInstance,
  54. const HWND hWndParent,
  55. const UINT uiCaptionStringRsrcID,
  56. const UINT uiTextStringRsrcID);
  57. void FloatToString(const FLOAT fValue,
  58. const int iPrecision,
  59. char * const szBuffer,
  60. const int iBufferLength);
  61. void GetParametersFromWindow(HWND hWnd,
  62. DP8SIM_PARAMETERS * pdp8spSend,
  63. DP8SIM_PARAMETERS * pdp8spReceive);
  64. void SetParametersInWindow(HWND hWnd,
  65. DP8SIM_PARAMETERS * pdp8spSend,
  66. DP8SIM_PARAMETERS * pdp8spReceive);
  67. void DisplayCurrentStatistics(HWND hWnd);
  68. INT_PTR CALLBACK MainWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  69. INT_PTR CALLBACK NameSettingsWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  70. HRESULT LoadAndAllocString(HINSTANCE hInstance, UINT uiResourceID, WCHAR ** pwszString);
  71. //=============================================================================
  72. // Constants
  73. //=============================================================================
  74. const SIMSETTINGS c_BuiltInSimSettings[] =
  75. {
  76. { IDS_SETTING_NONE, NULL, // resource ID and string initialization
  77. { // dp8spSend
  78. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  79. 0, // dp8spSend.dwFlags
  80. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  81. 0, // dp8spSend.dwBandwidthBPS
  82. 0.0, // dp8spSend.fPacketLossPercent
  83. 0, // dp8spSend.dwMinLatencyMS
  84. 0 // dp8spSend.dwMaxLatencyMS
  85. },
  86. { // dp8spReceive
  87. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  88. 0, // dp8spReceive.dwFlags
  89. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  90. 0, // dp8spReceive.dwBandwidthBPS
  91. 0.0, // dp8spReceive.fPacketLossPercent
  92. 0, // dp8spReceive.dwMinLatencyMS
  93. 0 // dp8spReceive.dwMaxLatencyMS
  94. }
  95. },
  96. { IDS_SETTING_336MODEM1, NULL, // resource ID and string initialization
  97. { // dp8spSend
  98. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  99. 0, // dp8spSend.dwFlags
  100. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  101. 3500, // dp8spSend.dwBandwidthBPS
  102. 2.0, // dp8spSend.fPacketLossPercent
  103. 55, // dp8spSend.dwMinLatencyMS
  104. 75 // dp8spSend.dwMaxLatencyMS
  105. },
  106. { // dp8spReceive
  107. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  108. 0, // dp8spReceive.dwFlags
  109. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  110. 3500, // dp8spReceive.dwBandwidthBPS
  111. 2.0, // dp8spReceive.fPacketLossPercent
  112. 55, // dp8spReceive.dwMinLatencyMS
  113. 75 // dp8spReceive.dwMaxLatencyMS
  114. }
  115. },
  116. { IDS_SETTING_336MODEM2, NULL, // resource ID and string initialization
  117. { // dp8spSend
  118. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  119. 0, // dp8spSend.dwFlags
  120. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  121. 4000, // dp8spSend.dwBandwidthBPS
  122. 0.75, // dp8spSend.fPacketLossPercent
  123. 50, // dp8spSend.dwMinLatencyMS
  124. 70 // dp8spSend.dwMaxLatencyMS
  125. },
  126. { // dp8spReceive
  127. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  128. 0, // dp8spReceive.dwFlags
  129. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  130. 4000, // dp8spReceive.dwBandwidthBPS
  131. 0.75, // dp8spReceive.fPacketLossPercent
  132. 50, // dp8spReceive.dwMinLatencyMS
  133. 70 // dp8spReceive.dwMaxLatencyMS
  134. }
  135. },
  136. { IDS_SETTING_56KMODEM1, NULL, // resource ID and string initialization
  137. { // dp8spSend
  138. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  139. 0, // dp8spSend.dwFlags
  140. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  141. 3500, // dp8spSend.dwBandwidthBPS
  142. 2.0, // dp8spSend.fPacketLossPercent
  143. 55, // dp8spSend.dwMinLatencyMS
  144. 75 // dp8spSend.dwMaxLatencyMS
  145. },
  146. { // dp8spReceive
  147. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  148. 0, // dp8spReceive.dwFlags
  149. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  150. 5000, // dp8spReceive.dwBandwidthBPS
  151. 2.0, // dp8spReceive.fPacketLossPercent
  152. 55, // dp8spReceive.dwMinLatencyMS
  153. 75 // dp8spReceive.dwMaxLatencyMS
  154. }
  155. },
  156. { IDS_SETTING_56KMODEM2, NULL, // resource ID and string initialization
  157. { // dp8spSend
  158. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  159. 0, // dp8spSend.dwFlags
  160. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  161. 4000, // dp8spSend.dwBandwidthBPS
  162. 0.75, // dp8spSend.fPacketLossPercent
  163. 50, // dp8spSend.dwMinLatencyMS
  164. 70 // dp8spSend.dwMaxLatencyMS
  165. },
  166. { // dp8spReceive
  167. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  168. 0, // dp8spReceive.dwFlags
  169. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  170. 7000, // dp8spReceive.dwBandwidthBPS
  171. 0.75, // dp8spReceive.fPacketLossPercent
  172. 50, // dp8spReceive.dwMinLatencyMS
  173. 70 // dp8spReceive.dwMaxLatencyMS
  174. }
  175. },
  176. { IDS_SETTING_256KBPSDSL, NULL, // resource ID and string initialization
  177. { // dp8spSend
  178. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  179. 0, // dp8spSend.dwFlags
  180. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  181. 32000, // dp8spSend.dwBandwidthBPS
  182. 0.5, // dp8spSend.fPacketLossPercent
  183. 25, // dp8spSend.dwMinLatencyMS
  184. 30 // dp8spSend.dwMaxLatencyMS
  185. },
  186. { // dp8spReceive
  187. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  188. 0, // dp8spReceive.dwFlags
  189. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  190. 32000, // dp8spReceive.dwBandwidthBPS
  191. 0.5, // dp8spReceive.fPacketLossPercent
  192. 25, // dp8spReceive.dwMinLatencyMS
  193. 30 // dp8spReceive.dwMaxLatencyMS
  194. }
  195. },
  196. { IDS_SETTING_DISCONNECTED, NULL, // resource ID and string initialization
  197. { // dp8spSend
  198. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  199. 0, // dp8spSend.dwFlags
  200. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  201. 0, // dp8spSend.dwBandwidthBPS
  202. 100.0, // dp8spSend.fPacketLossPercent
  203. 0, // dp8spSend.dwMinLatencyMS
  204. 0 // dp8spSend.dwMaxLatencyMS
  205. },
  206. { // dp8spReceive
  207. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  208. 0, // dp8spReceive.dwFlags
  209. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  210. 0, // dp8spReceive.dwBandwidthBPS
  211. 100.0, // dp8spReceive.fPacketLossPercent
  212. 0, // dp8spReceive.dwMinLatencyMS
  213. 0 // dp8spReceive.dwMaxLatencyMS
  214. }
  215. },
  216. { IDS_SETTING_HIGHPACKETLOSS, NULL, // resource ID and string initialization
  217. { // dp8spSend
  218. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  219. 0, // dp8spSend.dwFlags
  220. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  221. 0, // dp8spSend.dwBandwidthBPS
  222. 10.0, // dp8spSend.fPacketLossPercent
  223. 0, // dp8spSend.dwMinLatencyMS
  224. 0 // dp8spSend.dwMaxLatencyMS
  225. },
  226. { // dp8spReceive
  227. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  228. 0, // dp8spReceive.dwFlags
  229. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  230. 0, // dp8spReceive.dwBandwidthBPS
  231. 10.0, // dp8spReceive.fPacketLossPercent
  232. 0, // dp8spReceive.dwMinLatencyMS
  233. 0 // dp8spReceive.dwMaxLatencyMS
  234. }
  235. },
  236. { IDS_SETTING_HIGHLATENCYVARIANCE, NULL, // resource ID and string initialization
  237. { // dp8spSend
  238. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  239. 0, // dp8spSend.dwFlags
  240. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  241. 0, // dp8spSend.dwBandwidthBPS
  242. 0.0, // dp8spSend.fPacketLossPercent
  243. 100, // dp8spSend.dwMinLatencyMS
  244. 400 // dp8spSend.dwMaxLatencyMS
  245. },
  246. { // dp8spReceive
  247. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  248. 0, // dp8spReceive.dwFlags
  249. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  250. 0, // dp8spReceive.dwBandwidthBPS
  251. 0.0, // dp8spReceive.fPacketLossPercent
  252. 100, // dp8spReceive.dwMinLatencyMS
  253. 400 // dp8spReceive.dwMaxLatencyMS
  254. }
  255. },
  256. //
  257. // Custom must always be the last item.
  258. //
  259. { IDS_SETTING_CUSTOM, NULL, // resource ID and string initialization
  260. { // dp8spSend
  261. sizeof(DP8SIM_PARAMETERS), // dp8spSend.dwSize
  262. 0, // dp8spSend.dwFlags
  263. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spSend.dwPacketHeaderSize
  264. 0, // dp8spSend.dwBandwidthBPS
  265. 0.0, // dp8spSend.fPacketLossPercent
  266. 0, // dp8spSend.dwMinLatencyMS
  267. 0 // dp8spSend.dwMaxLatencyMS
  268. },
  269. { // dp8spReceive
  270. sizeof(DP8SIM_PARAMETERS), // dp8spReceive.dwSize
  271. 0, // dp8spReceive.dwFlags
  272. DP8SIMPACKETHEADERSIZE_IP_UDP, // dp8spReceive.dwPacketHeaderSize
  273. 0, // dp8spReceive.dwBandwidthBPS
  274. 0.0, // dp8spReceive.fPacketLossPercent
  275. 0, // dp8spReceive.dwMinLatencyMS
  276. 0 // dp8spReceive.dwMaxLatencyMS
  277. }
  278. }
  279. };
  280. //=============================================================================
  281. // Globals
  282. //=============================================================================
  283. HWND g_hWndMainWindow = NULL;
  284. IDP8SimControl * g_pDP8SimControl = NULL;
  285. UINT_PTR g_uiAutoRefreshTimer = 0;
  286. SIMSETTINGS * g_paSimSettings = NULL;
  287. DWORD g_dwNumSimSettings = 0;
  288. DWORD g_dwMaxNumSimSettings = 0;
  289. #undef DPF_MODNAME
  290. #define DPF_MODNAME "WinMain"
  291. //=============================================================================
  292. // WinMain
  293. //-----------------------------------------------------------------------------
  294. //
  295. // Description: Executable entry point.
  296. //
  297. // Arguments:
  298. // HINSTANCE hInstance - Handle to current application instance.
  299. // HINSTANCE hPrevInstance - Handle to previous application instance.
  300. // LPSTR lpszCmdLine - Command line string for application.
  301. // int iShowCmd - Show state of window.
  302. //
  303. // Returns: HRESULT
  304. //=============================================================================
  305. int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int iShowCmd)
  306. {
  307. HRESULT hr;
  308. HRESULT hrTemp;
  309. MSG msg;
  310. DPFX(DPFPREP, 2, "===> Parameters: (0x%p, 0x%p, \"%s\", %i)",
  311. hInstance, hPrevInstance, lpszCmdLine, iShowCmd);
  312. //
  313. // Initialize the application
  314. //
  315. hr = InitializeApplication(hInstance, lpszCmdLine, iShowCmd);
  316. if (hr != S_OK)
  317. {
  318. DPFX(DPFPREP, 0, "Couldn't initialize the application!");
  319. goto Exit;
  320. }
  321. //
  322. // Do the Windows message loop until we're told to quit.
  323. //
  324. while (GetMessage(&msg, NULL, 0, 0))
  325. {
  326. TranslateMessage(&msg);
  327. DispatchMessage(&msg);
  328. }
  329. //
  330. // Retrieve the result code for the window closing.
  331. //
  332. hr = (HRESULT) msg.wParam;
  333. if (hr != S_OK)
  334. {
  335. DPFX(DPFPREP, 0, "Window closed with failure (err = 0x%lx)!", hr);
  336. } // end if (failure)
  337. //
  338. // Cleanup the application
  339. //
  340. hrTemp = CleanupApplication(hInstance);
  341. if (hrTemp != S_OK)
  342. {
  343. DPFX(DPFPREP, 0, "Failed cleaning up the application (err = 0x%lx)!", hrTemp);
  344. if (hr == S_OK)
  345. {
  346. hr = hrTemp;
  347. }
  348. //
  349. // Continue.
  350. //
  351. }
  352. Exit:
  353. DPFX(DPFPREP, 2, "<=== Returning [0x%lx]", hr);
  354. return hr;
  355. } // WinMain
  356. #undef DPF_MODNAME
  357. #define DPF_MODNAME "InitializeApplication"
  358. //=============================================================================
  359. // InitializeApplication
  360. //-----------------------------------------------------------------------------
  361. //
  362. // Description: Initializes the application.
  363. //
  364. // Arguments:
  365. // HINSTANCE hInstance - Handle to current application instance.
  366. // LPSTR lpszCmdLine - Command line string for application.
  367. // int iShowCmd - Show state of window.
  368. //
  369. // Returns: HRESULT
  370. //=============================================================================
  371. HRESULT InitializeApplication(const HINSTANCE hInstance,
  372. const LPSTR lpszCmdLine,
  373. const int iShowCmd)
  374. {
  375. HRESULT hr = S_OK;
  376. BOOL fOSIndirectionInitted = FALSE;
  377. BOOL fCOMInitted = FALSE;
  378. HMODULE hDP8SIM = NULL;
  379. PFN_DLLREGISTERSERVER pfnDllRegisterServer;
  380. WCHAR * pwszFriendlyName = NULL;
  381. BOOL fEnabledControlForSP = FALSE;
  382. BOOL fBuiltSimSettingsTable = FALSE;
  383. DPFX(DPFPREP, 5, "Parameters: (0x%p, \"%s\", %i)",
  384. hInstance, lpszCmdLine, iShowCmd);
  385. //
  386. // Attempt to initialize the OS abstraction layer.
  387. //
  388. if (! DNOSIndirectionInit(0))
  389. {
  390. DPFX(DPFPREP, 0, "Failed to initialize OS indirection layer!");
  391. hr = E_FAIL;
  392. goto Failure;
  393. }
  394. fOSIndirectionInitted = TRUE;
  395. //
  396. // Attempt to initialize COM.
  397. //
  398. hr = CoInitialize(NULL);
  399. if (hr != S_OK)
  400. {
  401. DPFX(DPFPREP, 0, "Failed to initialize COM!");
  402. goto Failure;
  403. }
  404. fCOMInitted = TRUE;
  405. //
  406. // Attempt to create a DP8Sim control object.
  407. //
  408. hr = CoCreateInstance(CLSID_DP8SimControl,
  409. NULL,
  410. CLSCTX_INPROC_SERVER,
  411. IID_IDP8SimControl,
  412. (LPVOID*) (&g_pDP8SimControl));
  413. if (hr == REGDB_E_CLASSNOTREG)
  414. {
  415. //
  416. // The object wasn't registered. Attempt to load the DLL and manually
  417. // register it.
  418. //
  419. hDP8SIM = LoadLibrary( _T("dp8sim.dll") );
  420. if (hDP8SIM == NULL)
  421. {
  422. hr = GetLastError();
  423. DPFX(DPFPREP, 0, "Couldn't load \"dp8sim.dll\"!");
  424. goto Failure;
  425. }
  426. pfnDllRegisterServer = (PFN_DLLREGISTERSERVER) GetProcAddress(hDP8SIM,
  427. "DllRegisterServer");
  428. if (pfnDllRegisterServer == NULL)
  429. {
  430. hr = GetLastError();
  431. DPFX(DPFPREP, 0, "Couldn't get \"DllRegisterServer\" function from DP8Sim DLL!");
  432. goto Failure;
  433. }
  434. //
  435. // Register the DLL.
  436. //
  437. hr = pfnDllRegisterServer();
  438. if (hr != S_OK)
  439. {
  440. DPFX(DPFPREP, 0, "Couldn't register DP8Sim DLL!");
  441. goto Failure;
  442. }
  443. FreeLibrary(hDP8SIM);
  444. hDP8SIM = NULL;
  445. //
  446. // Try to create the DP8Sim control object again.
  447. //
  448. hr = CoCreateInstance(CLSID_DP8SimControl,
  449. NULL,
  450. CLSCTX_INPROC_SERVER,
  451. IID_IDP8SimControl,
  452. (LPVOID*) (&g_pDP8SimControl));
  453. }
  454. if (hr != S_OK)
  455. {
  456. //
  457. // Some error prevented creation of the object.
  458. //
  459. DPFX(DPFPREP, 0, "Failed creating DP8Sim Control object (err = 0x%lx)!", hr);
  460. DoErrorBox(hInstance,
  461. NULL,
  462. IDS_ERROR_CAPTION_COULDNTCREATEDP8SIMCONTROL,
  463. IDS_ERROR_TEXT_COULDNTCREATEDP8SIMCONTROL);
  464. goto Failure;
  465. }
  466. //
  467. // If we're here, we successfully created the object.
  468. //
  469. DPFX(DPFPREP, 1, "Successfully created DP8Sim Control object 0x%p.",
  470. &g_pDP8SimControl);
  471. //
  472. // Initialize the control object.
  473. //
  474. hr = g_pDP8SimControl->Initialize(0);
  475. if (hr != DP8SIM_OK)
  476. {
  477. DPFX(DPFPREP, 0, "Couldn't initialize DP8Sim Control object!");
  478. g_pDP8SimControl->Release();
  479. g_pDP8SimControl = NULL;
  480. goto Failure;
  481. }
  482. //
  483. // Load the list of settings.
  484. //
  485. hr = BuildSimSettingsTable(hInstance);
  486. if (hr != S_OK)
  487. {
  488. DPFX(DPFPREP, 0, "Failed building list of sim settings!");
  489. goto Failure;
  490. }
  491. fBuiltSimSettingsTable = TRUE;
  492. //
  493. // Initialize the user interface.
  494. //
  495. hr = InitializeUserInterface(hInstance, iShowCmd);
  496. if (hr != S_OK)
  497. {
  498. DPFX(DPFPREP, 0, "Failed initializing user interface!");
  499. goto Failure;
  500. }
  501. Exit:
  502. DPFX(DPFPREP, 5, "Returning [0x%lx]", hr);
  503. return hr;
  504. Failure:
  505. if (fBuiltSimSettingsTable)
  506. {
  507. FreeSimSettingsTable();
  508. fBuiltSimSettingsTable = FALSE;
  509. }
  510. if (hDP8SIM != NULL)
  511. {
  512. FreeLibrary(hDP8SIM);
  513. hDP8SIM = NULL;
  514. }
  515. if (pwszFriendlyName != NULL)
  516. {
  517. DNFree(pwszFriendlyName);
  518. pwszFriendlyName = NULL;
  519. }
  520. if (g_pDP8SimControl != NULL)
  521. {
  522. g_pDP8SimControl->Close(0); // ignore error
  523. g_pDP8SimControl->Release();
  524. g_pDP8SimControl = NULL;
  525. }
  526. if (fCOMInitted)
  527. {
  528. CoUninitialize();
  529. fCOMInitted = FALSE;
  530. }
  531. if (fOSIndirectionInitted)
  532. {
  533. DNOSIndirectionDeinit();
  534. fOSIndirectionInitted = FALSE;
  535. }
  536. goto Exit;
  537. } // InitializeApplication
  538. #undef DPF_MODNAME
  539. #define DPF_MODNAME "CleanupApplication"
  540. //=============================================================================
  541. // CleanupApplication
  542. //-----------------------------------------------------------------------------
  543. //
  544. // Description: Cleans up the application.
  545. //
  546. // Arguments:
  547. // HINSTANCE hInstance - Handle to current application instance.
  548. //
  549. // Returns: HRESULT
  550. //=============================================================================
  551. HRESULT CleanupApplication(const HINSTANCE hInstance)
  552. {
  553. HRESULT hr = S_OK;
  554. HRESULT temphr;
  555. DPFX(DPFPREP, 5, "Enter");
  556. //
  557. // Free the control object interface.
  558. //
  559. temphr = g_pDP8SimControl->Close(0);
  560. if (temphr != DP8SIM_OK)
  561. {
  562. DPFX(DPFPREP, 0, "Failed closing DP8Sim Control object (err = 0x%lx)!",
  563. temphr);
  564. if (hr != S_OK)
  565. {
  566. hr = temphr;
  567. }
  568. //
  569. // Continue...
  570. //
  571. }
  572. g_pDP8SimControl->Release();
  573. g_pDP8SimControl = NULL;
  574. //
  575. // Cleanup the user interface.
  576. //
  577. temphr = CleanupUserInterface();
  578. if (temphr != S_OK)
  579. {
  580. DPFX(DPFPREP, 0, "Couldn't cleanup user interface (err = 0x%lx)!", temphr);
  581. if (hr != S_OK)
  582. {
  583. hr = temphr;
  584. }
  585. //
  586. // Continue...
  587. //
  588. }
  589. FreeSimSettingsTable();
  590. CoUninitialize();
  591. DNOSIndirectionDeinit();
  592. DPFX(DPFPREP, 5, "Returning [0x%lx]", hr);
  593. return hr;
  594. } // CleanupApplication
  595. #undef DPF_MODNAME
  596. #define DPF_MODNAME "BuildSimSettingsTable()"
  597. //=============================================================================
  598. // BuildSimSettingsTable
  599. //-----------------------------------------------------------------------------
  600. //
  601. // Description: Builds the table of sim settings.
  602. //
  603. // Arguments:
  604. // HINSTANCE hInstance - Handle to current application instance.
  605. //
  606. // Returns: HRESULT
  607. //=============================================================================
  608. HRESULT BuildSimSettingsTable(HINSTANCE hInstance)
  609. {
  610. HRESULT hr = S_OK;
  611. DWORD dwTemp;
  612. HKEY hKey = NULL;
  613. DWORD dwNumValues;
  614. DWORD dwMaxValueNameLength;
  615. TCHAR * ptszValue = NULL;
  616. DWORD dwValueNameLength;
  617. DWORD dwType;
  618. SIMSETTINGS SimSettings;
  619. DWORD dwDataSize;
  620. DPFX(DPFPREP, 6, "Parameters: (0x%p)", hInstance);
  621. //
  622. // Start with the built-in settings.
  623. //
  624. g_dwMaxNumSimSettings = sizeof(c_BuiltInSimSettings) / sizeof(SIMSETTINGS);
  625. g_dwNumSimSettings = g_dwMaxNumSimSettings;
  626. g_paSimSettings = (SIMSETTINGS*) DNMalloc(g_dwNumSimSettings * sizeof(SIMSETTINGS));
  627. if (g_paSimSettings == NULL)
  628. {
  629. hr = DP8SIMERR_OUTOFMEMORY;
  630. goto Failure;
  631. }
  632. memcpy(g_paSimSettings, c_BuiltInSimSettings, sizeof(c_BuiltInSimSettings));
  633. //
  634. // Load the names of all the built-in settings from a resource.
  635. //
  636. for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
  637. {
  638. hr = LoadAndAllocString(hInstance,
  639. g_paSimSettings[dwTemp].uiNameStringResourceID,
  640. &(g_paSimSettings[dwTemp].pwszName));
  641. if (hr != DP8SIM_OK)
  642. {
  643. DPFX(DPFPREP, 0, "Couldn't load and allocate built-in setting name #%u!",
  644. dwTemp);
  645. goto Failure;
  646. }
  647. }
  648. //
  649. // Now walk the list of custom entries in the registry and add those.
  650. //
  651. hr = RegOpenKeyEx(HKEY_CURRENT_USER,
  652. REG_KEY_CUSTOMSETTINGS,
  653. 0,
  654. KEY_READ,
  655. &hKey);
  656. if (hr == ERROR_SUCCESS)
  657. {
  658. //
  659. // Find out the number of values, and max value name length.
  660. //
  661. hr = RegQueryInfoKey(hKey,
  662. NULL,
  663. NULL,
  664. NULL,
  665. NULL,
  666. NULL,
  667. NULL,
  668. &dwNumValues,
  669. &dwMaxValueNameLength,
  670. NULL,
  671. NULL,
  672. NULL);
  673. if (hr == ERROR_SUCCESS)
  674. {
  675. dwMaxValueNameLength++; // include room for NULL termination
  676. ptszValue = (TCHAR*) DNMalloc(dwMaxValueNameLength * sizeof(TCHAR));
  677. if (ptszValue == NULL)
  678. {
  679. DPFX(DPFPREP, 0, "Couldn't allocate memory for custom settings key names!");
  680. hr = DP8SIMERR_OUTOFMEMORY;
  681. goto Failure;
  682. }
  683. //
  684. // Loop through each value.
  685. //
  686. for(dwTemp = 0; dwTemp < dwNumValues; dwTemp++)
  687. {
  688. dwValueNameLength = dwMaxValueNameLength;
  689. dwDataSize = sizeof(SIMSETTINGS);
  690. hr = RegEnumValue(hKey,
  691. dwTemp,
  692. ptszValue,
  693. &dwValueNameLength,
  694. NULL,
  695. &dwType,
  696. (BYTE*) (&SimSettings),
  697. &dwDataSize);
  698. if (hr == ERROR_SUCCESS)
  699. {
  700. dwValueNameLength++; // include room for NULL termination
  701. //
  702. // Validate the data that was read.
  703. //
  704. if ((dwType == REG_BINARY) &&
  705. (dwDataSize == sizeof(SIMSETTINGS)) &&
  706. (SimSettings.uiNameStringResourceID == 0) &&
  707. (SimSettings.dp8spSend.dwSize == sizeof(DP8SIM_PARAMETERS)) &&
  708. (SimSettings.dp8spReceive.dwSize == sizeof(DP8SIM_PARAMETERS)))
  709. {
  710. SimSettings.pwszName = (WCHAR*) DNMalloc(dwValueNameLength * sizeof(WCHAR));
  711. if (SimSettings.pwszName == NULL)
  712. {
  713. DPFX(DPFPREP, 0, "Couldn't allocate memory for settings name!");
  714. hr = DP8SIMERR_OUTOFMEMORY;
  715. goto Failure;
  716. }
  717. #ifdef UNICODE
  718. memcpy(SimSettings.pwszName, ptszValue, dwValueNameLength * sizeof(WCHAR));
  719. #else // ! UNICODE
  720. hr = STR_jkAnsiToWide(SimSettings.pwszName, ptszValue, dwValueNameLength);
  721. if (hr != DPN_OK)
  722. {
  723. DPFX(DPFPREP, 0, "Unable to convert from ANSI to Unicode (err = 0x%lx)!", hr);
  724. DNFree(SimSettings.pwszName);
  725. SimSettings.pwszName = NULL;
  726. goto Failure;
  727. }
  728. #endif // ! UNICODE
  729. hr = AddSimSettingsToTable(&SimSettings);
  730. if (hr != DP8SIM_OK)
  731. {
  732. DPFX(DPFPREP, 0, "Couldn't add sim settings to table!");
  733. hr = DP8SIMERR_OUTOFMEMORY;
  734. goto Failure;
  735. }
  736. }
  737. else
  738. {
  739. DPFX(DPFPREP, 0, "Registry value is not valid (type = %u, data size = %u, resource ID = %u, send size = %u, receive size = %u)! Ignoring.",
  740. dwType,
  741. dwDataSize,
  742. SimSettings.uiNameStringResourceID,
  743. SimSettings.dp8spSend.dwSize,
  744. SimSettings.dp8spReceive.dwSize);
  745. }
  746. }
  747. else
  748. {
  749. DPFX(DPFPREP, 0, "Couldn't enumerate value %u (err = 0x%lx)! Continuing.",
  750. dwTemp, hr);
  751. }
  752. }
  753. DNFree(ptszValue);
  754. ptszValue = NULL;
  755. }
  756. else
  757. {
  758. DPFX(DPFPREP, 0, "Couldn't get custom settings key info! Continuing.");
  759. }
  760. RegCloseKey(hKey);
  761. hKey = NULL;
  762. }
  763. else
  764. {
  765. DPFX(DPFPREP, 2, "Couldn't open custom settings key, continuing.");
  766. }
  767. //
  768. // If we're here, everything is ready.
  769. //
  770. hr = DP8SIM_OK;
  771. Exit:
  772. DPFX(DPFPREP, 6, "Returning [0x%lx]", hr);
  773. return hr;
  774. Failure:
  775. if (ptszValue != NULL)
  776. {
  777. DNFree(ptszValue);
  778. ptszValue = NULL;
  779. }
  780. if (ptszValue != NULL)
  781. {
  782. RegCloseKey(hKey);
  783. hKey = NULL;
  784. }
  785. //
  786. // Free the names of all the settings that got loaded.
  787. //
  788. for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
  789. {
  790. if (g_paSimSettings[dwTemp].pwszName != NULL)
  791. {
  792. DNFree(g_paSimSettings[dwTemp].pwszName);
  793. g_paSimSettings[dwTemp].pwszName = NULL;
  794. }
  795. }
  796. goto Exit;
  797. } // BuildSimSettingsTable
  798. #undef DPF_MODNAME
  799. #define DPF_MODNAME "FreeSimSettingsTable()"
  800. //=============================================================================
  801. // FreeSimSettingsTable
  802. //-----------------------------------------------------------------------------
  803. //
  804. // Description: Releases resources allocated for the sim settings table.
  805. //
  806. // Arguments: None.
  807. //
  808. // Returns: HRESULT
  809. //=============================================================================
  810. void FreeSimSettingsTable(void)
  811. {
  812. DWORD dwTemp;
  813. DPFX(DPFPREP, 6, "Enter");
  814. //
  815. // Free the names of all the settings.
  816. //
  817. for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
  818. {
  819. DNFree(g_paSimSettings[dwTemp].pwszName);
  820. g_paSimSettings[dwTemp].pwszName = NULL;
  821. }
  822. DNFree(g_paSimSettings);
  823. g_paSimSettings = NULL;
  824. DPFX(DPFPREP, 6, "Leave");
  825. } // FreeSimSettingsTable
  826. #undef DPF_MODNAME
  827. #define DPF_MODNAME "AddSimSettingsToTable()"
  828. //=============================================================================
  829. // AddSimSettingsToTable
  830. //-----------------------------------------------------------------------------
  831. //
  832. // Description: Adds a new sim settings entry to the table.
  833. //
  834. // Arguments:
  835. // SIMSETTINGS * pSimSettings - Pointer to new sim settings to add.
  836. //
  837. // Returns: HRESULT
  838. //=============================================================================
  839. HRESULT AddSimSettingsToTable(const SIMSETTINGS * const pSimSettings)
  840. {
  841. PVOID pvTemp;
  842. DWORD dwNewMaxNumSettings;
  843. DNASSERT(pSimSettings->pwszName != NULL);
  844. DPFX(DPFPREP, 4, "Adding settings \"%ls\".", pSimSettings->pwszName);
  845. //
  846. // If there's not enough room in the settings array, double it.
  847. //
  848. if (g_dwNumSimSettings >= g_dwMaxNumSimSettings)
  849. {
  850. dwNewMaxNumSettings = g_dwMaxNumSimSettings * 2;
  851. pvTemp = DNMalloc(dwNewMaxNumSettings * sizeof(SIMSETTINGS));
  852. if (pvTemp == NULL)
  853. {
  854. DPFX(DPFPREP, 0, "Couldn't allocate memory for new settings table!");
  855. return DP8SIMERR_OUTOFMEMORY;
  856. }
  857. //
  858. // Copy the existing settings and free the old array.
  859. //
  860. memcpy(pvTemp, g_paSimSettings, (g_dwNumSimSettings * sizeof(SIMSETTINGS)));
  861. DNFree(g_paSimSettings);
  862. g_paSimSettings = (SIMSETTINGS*) pvTemp;
  863. pvTemp = NULL;
  864. g_dwMaxNumSimSettings = dwNewMaxNumSettings;
  865. }
  866. //
  867. // Now there's enough room to insert the new item. Move "Custom" down one
  868. // slot and add the new settings.
  869. //
  870. memcpy(&g_paSimSettings[g_dwNumSimSettings],
  871. &g_paSimSettings[g_dwNumSimSettings - 1],
  872. sizeof(SIMSETTINGS));
  873. memcpy(&g_paSimSettings[g_dwNumSimSettings - 1],
  874. pSimSettings,
  875. sizeof(SIMSETTINGS));
  876. g_dwNumSimSettings++;
  877. return DP8SIM_OK;
  878. } // AddSimSettingsToTable
  879. #undef DPF_MODNAME
  880. #define DPF_MODNAME "SaveSimSettings()"
  881. //=============================================================================
  882. // SaveSimSettings
  883. //-----------------------------------------------------------------------------
  884. //
  885. // Description: Saves a sim settings entry to the window and registry. If an
  886. // entry by that name already exists, it is replaced.
  887. //
  888. // Arguments:
  889. // SIMSETTINGS * pSimSettings - Pointer to sim settings to save.
  890. //
  891. // Returns: HRESULT
  892. //=============================================================================
  893. HRESULT SaveSimSettings(HWND hWnd, SIMSETTINGS * const pSimSettings)
  894. {
  895. HRESULT hr;
  896. WCHAR * pwszName = NULL;
  897. char * pszName = NULL;
  898. HKEY hKey = NULL;
  899. DWORD dwTemp;
  900. DWORD dwNameSize;
  901. //
  902. // Look for an existing item to replace.
  903. //
  904. for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
  905. {
  906. if (_wcsicmp(g_paSimSettings[dwTemp].pwszName, pSimSettings->pwszName) == 0)
  907. {
  908. DNASSERT(g_paSimSettings[dwTemp].uiNameStringResourceID == 0);
  909. //
  910. // Free the duplicate name string.
  911. //
  912. DNFree(pSimSettings->pwszName);
  913. //
  914. // Save the string pointer, copy the whole blob, then point to
  915. // the existing item.
  916. //
  917. pwszName = g_paSimSettings[dwTemp].pwszName;
  918. pSimSettings->pwszName = pwszName;
  919. memcpy(&g_paSimSettings[dwTemp], pSimSettings, sizeof(SIMSETTINGS));
  920. pSimSettings->pwszName = NULL;
  921. //
  922. // Select this item.
  923. //
  924. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  925. CB_SETCURSEL,
  926. (WPARAM) dwTemp,
  927. 0);
  928. break;
  929. }
  930. }
  931. //
  932. // If we're not replacing, add the item to the table.
  933. //
  934. if (dwTemp >= g_dwNumSimSettings)
  935. {
  936. hr = AddSimSettingsToTable(pSimSettings);
  937. if (hr != DP8SIM_OK)
  938. {
  939. DPFX(DPFPREP, 0, "Couldn't add sim settings to table!");
  940. goto Failure;
  941. }
  942. //
  943. // Make our caller forget about the string in case we fail since the
  944. // table owns the reference now. Keep a local copy, though.
  945. //
  946. pwszName = pSimSettings->pwszName;
  947. pSimSettings->pwszName = NULL;
  948. //
  949. // Insert the string into the list.
  950. //
  951. if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
  952. {
  953. SendMessageW(GetDlgItem(hWnd, IDCB_SETTINGS),
  954. CB_INSERTSTRING,
  955. (WPARAM) (g_dwNumSimSettings - 2),
  956. (LPARAM) pwszName);
  957. }
  958. else
  959. {
  960. dwNameSize = wcslen(pwszName) + 1;
  961. pszName = (char*) DNMalloc(dwNameSize);
  962. if (pszName != NULL)
  963. {
  964. hr = STR_WideToAnsi(pwszName,
  965. -1,
  966. pszName,
  967. &dwNameSize);
  968. if (hr == DPN_OK)
  969. {
  970. SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
  971. CB_INSERTSTRING,
  972. (WPARAM) (g_dwNumSimSettings - 2),
  973. (LPARAM) pszName);
  974. }
  975. else
  976. {
  977. SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
  978. CB_INSERTSTRING,
  979. (WPARAM) (g_dwNumSimSettings - 2),
  980. (LPARAM) "???");
  981. }
  982. }
  983. else
  984. {
  985. SendMessageA(GetDlgItem(hWnd, IDCB_SETTINGS),
  986. CB_INSERTSTRING,
  987. (WPARAM) (g_dwNumSimSettings - 2),
  988. (LPARAM) "???");
  989. }
  990. }
  991. //
  992. // Select this new item.
  993. //
  994. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  995. CB_SETCURSEL,
  996. (WPARAM) (g_dwNumSimSettings - 2),
  997. 0);
  998. //
  999. // Disable Save As, since we just did.
  1000. //
  1001. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
  1002. }
  1003. //
  1004. // Write this item to the registry (overwrites anything that existed).
  1005. //
  1006. hr = RegCreateKey(HKEY_CURRENT_USER, REG_KEY_CUSTOMSETTINGS, &hKey);
  1007. if (hr != ERROR_SUCCESS)
  1008. {
  1009. DPFX(DPFPREP, 0, "Couldn't create custom settings key!");
  1010. goto Failure;
  1011. }
  1012. #ifdef UNICODE
  1013. hr = RegSetValueExW(hKey,
  1014. pwszName,
  1015. 0,
  1016. REG_BINARY,
  1017. (BYTE*) pSimSettings,
  1018. sizeof(SIMSETTINGS));
  1019. #else // ! UNICODE
  1020. hr = RegSetValueExA(hKey,
  1021. pszName,
  1022. 0,
  1023. REG_BINARY,
  1024. (BYTE*) pSimSettings,
  1025. sizeof(SIMSETTINGS));
  1026. #endif // ! UNICODE
  1027. if (hr != ERROR_SUCCESS)
  1028. {
  1029. DPFX(DPFPREP, 0, "Couldn't write value!");
  1030. goto Failure;
  1031. }
  1032. RegCloseKey(hKey);
  1033. hKey = NULL;
  1034. hr = DP8SIM_OK;
  1035. Exit:
  1036. if (pszName != NULL)
  1037. {
  1038. DNFree(pszName);
  1039. pszName = NULL;
  1040. }
  1041. return hr;
  1042. Failure:
  1043. if (hKey != NULL)
  1044. {
  1045. RegCloseKey(hKey);
  1046. hKey = NULL;
  1047. }
  1048. goto Exit;
  1049. } // SaveSimSettings
  1050. #undef DPF_MODNAME
  1051. #define DPF_MODNAME "InitializeUserInterface()"
  1052. //=============================================================================
  1053. // InitializeUserInterface
  1054. //-----------------------------------------------------------------------------
  1055. //
  1056. // Description: Prepares the user interface.
  1057. //
  1058. // Arguments:
  1059. // HINSTANCE hInstance - Handle to current application instance.
  1060. // int iShowCmd - Show state of window.
  1061. //
  1062. // Returns: HRESULT
  1063. //=============================================================================
  1064. HRESULT InitializeUserInterface(HINSTANCE hInstance, int iShowCmd)
  1065. {
  1066. HRESULT hr = S_OK;
  1067. WNDCLASSEX wcex;
  1068. DPFX(DPFPREP, 6, "Parameters: (0x%p, %i)", hInstance, iShowCmd);
  1069. /*
  1070. //
  1071. // Setup common controls (we need the listview item).
  1072. //
  1073. InitCommonControls();
  1074. */
  1075. //
  1076. // Register the main window class
  1077. //
  1078. ZeroMemory(&wcex, sizeof (WNDCLASSEX));
  1079. wcex.cbSize = sizeof(wcex);
  1080. GetClassInfoEx(NULL, WC_DIALOG, &wcex);
  1081. wcex.lpfnWndProc = MainWindowDlgProc;
  1082. wcex.hInstance = hInstance;
  1083. wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1084. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  1085. wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  1086. wcex.lpszMenuName = NULL;
  1087. wcex.lpszClassName = WINDOWCLASS_MAIN;
  1088. wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  1089. if (! RegisterClassEx(&wcex))
  1090. {
  1091. hr = GetLastError();
  1092. DPFX(DPFPREP, 0, "Couldn't register main window class (err = 0x%lx)!", hr);
  1093. if (hr == S_OK)
  1094. hr = E_FAIL;
  1095. goto Failure;
  1096. }
  1097. //
  1098. // Register the Save As/Name Settings window class
  1099. //
  1100. ZeroMemory(&wcex, sizeof (WNDCLASSEX));
  1101. wcex.cbSize = sizeof(wcex);
  1102. GetClassInfoEx(NULL, WC_DIALOG, &wcex);
  1103. wcex.lpfnWndProc = NameSettingsWindowDlgProc;
  1104. wcex.hInstance = hInstance;
  1105. wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  1106. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  1107. wcex.hbrBackground = GetSysColorBrush(COLOR_3DFACE);
  1108. wcex.lpszMenuName = NULL;
  1109. wcex.lpszClassName = WINDOWCLASS_NAMESETTINGS;
  1110. wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
  1111. if (! RegisterClassEx(&wcex))
  1112. {
  1113. hr = GetLastError();
  1114. DPFX(DPFPREP, 0, "Couldn't register name settings window class (err = 0x%lx)!", hr);
  1115. if (hr == S_OK)
  1116. hr = E_FAIL;
  1117. goto Failure;
  1118. }
  1119. //
  1120. // Create the main window.
  1121. //
  1122. g_hWndMainWindow = CreateDialog(hInstance,
  1123. MAKEINTRESOURCE(IDD_MAIN),
  1124. NULL,
  1125. MainWindowDlgProc);
  1126. if (g_hWndMainWindow == NULL)
  1127. {
  1128. hr = GetLastError();
  1129. DPFX(DPFPREP, 0, "Couldn't create window (err = 0x%lx)!", hr);
  1130. if (hr == S_OK)
  1131. hr = E_FAIL;
  1132. goto Failure;
  1133. }
  1134. UpdateWindow(g_hWndMainWindow);
  1135. ShowWindow(g_hWndMainWindow, iShowCmd);
  1136. Exit:
  1137. DPFX(DPFPREP, 6, "Returning [0x%lx]", hr);
  1138. return hr;
  1139. Failure:
  1140. goto Exit;
  1141. } // InitializeUserInterface
  1142. #undef DPF_MODNAME
  1143. #define DPF_MODNAME "CleanupUserInterface()"
  1144. //=============================================================================
  1145. // CleanupUserInterface
  1146. //-----------------------------------------------------------------------------
  1147. //
  1148. // Description: Cleans up the user interface.
  1149. //
  1150. // Arguments: None.
  1151. //
  1152. // Returns: HRESULT
  1153. //=============================================================================
  1154. HRESULT CleanupUserInterface(void)
  1155. {
  1156. DPFX(DPFPREP, 6, "Enter");
  1157. DPFX(DPFPREP, 6, "Returning [S_OK]");
  1158. return S_OK;
  1159. } // CleanupUserInterface
  1160. #undef DPF_MODNAME
  1161. #define DPF_MODNAME "DoErrorBox()"
  1162. //=============================================================================
  1163. // DoErrorBox
  1164. //-----------------------------------------------------------------------------
  1165. //
  1166. // Description: Loads error strings from the given resources, and displays an
  1167. // error dialog with that text.
  1168. //
  1169. // Arguments:
  1170. // HINSTANCE hInstance - Handle to current application instance.
  1171. // HWND hWndParent - Parent window, or NULL if none.
  1172. // UINT uiCaptionStringRsrcID - ID of caption string resource.
  1173. // UINT uiTextStringRsrcID - ID of text string resource.
  1174. //
  1175. // Returns: None.
  1176. //=============================================================================
  1177. void DoErrorBox(const HINSTANCE hInstance,
  1178. const HWND hWndParent,
  1179. const UINT uiCaptionStringRsrcID,
  1180. const UINT uiTextStringRsrcID)
  1181. {
  1182. HRESULT hr;
  1183. WCHAR * pwszCaption = NULL;
  1184. WCHAR * pwszText = NULL;
  1185. DWORD dwStringLength;
  1186. char * pszCaption = NULL;
  1187. char * pszText = NULL;
  1188. int iReturn;
  1189. DPFX(DPFPREP, 6, "Parameters: (0x%p, 0x%p, %u, %u)",
  1190. hInstance, hWndParent, uiCaptionStringRsrcID, uiTextStringRsrcID);
  1191. //
  1192. // Load the dialog caption string.
  1193. //
  1194. hr = LoadAndAllocString(hInstance, uiCaptionStringRsrcID, &pwszCaption);
  1195. if (FAILED(hr))
  1196. {
  1197. DPFX(DPFPREP, 0, "Couldn't load caption string (err = 0x%lx)!", hr);
  1198. goto Exit;
  1199. }
  1200. //
  1201. // Load the dialog text string.
  1202. //
  1203. hr = LoadAndAllocString(hInstance, uiTextStringRsrcID, &pwszText);
  1204. if (FAILED(hr))
  1205. {
  1206. DPFX(DPFPREP, 0, "Couldn't load text string (err = 0x%lx)!", hr);
  1207. goto Exit;
  1208. }
  1209. //
  1210. // Convert the text to ANSI, if required, otherwise display the Unicode
  1211. // message box.
  1212. //
  1213. if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
  1214. {
  1215. //
  1216. // Convert caption string to ANSI.
  1217. //
  1218. dwStringLength = wcslen(pwszCaption) + 1;
  1219. pszCaption = (char*) DNMalloc(dwStringLength);
  1220. if (pszCaption == NULL)
  1221. {
  1222. DPFX(DPFPREP, 0, "Couldn't allocate memory for caption string!");
  1223. goto Exit;
  1224. }
  1225. hr = STR_WideToAnsi(pwszCaption, dwStringLength, pszCaption, &dwStringLength);
  1226. if (hr != S_OK)
  1227. {
  1228. DPFX(DPFPREP, 0, "Couldn't convert wide string to ANSI (err = 0x%lx)!", hr);
  1229. goto Exit;
  1230. }
  1231. //
  1232. // Convert caption string to ANSI.
  1233. //
  1234. dwStringLength = wcslen(pwszText) + 1;
  1235. pszText = (char*) DNMalloc(dwStringLength);
  1236. if (pszText == NULL)
  1237. {
  1238. DPFX(DPFPREP, 0, "Couldn't allocate memory for text string!");
  1239. goto Exit;
  1240. }
  1241. hr = STR_WideToAnsi(pwszText, dwStringLength, pszText, &dwStringLength);
  1242. if (hr != S_OK)
  1243. {
  1244. DPFX(DPFPREP, 0, "Couldn't convert wide string to ANSI (err = 0x%lx)!", hr);
  1245. goto Exit;
  1246. }
  1247. iReturn = MessageBoxA(hWndParent,
  1248. pszText,
  1249. pszCaption,
  1250. (MB_OK | MB_ICONERROR | MB_APPLMODAL));
  1251. DNFree(pszText);
  1252. pszText = NULL;
  1253. DNFree(pszCaption);
  1254. pszCaption = NULL;
  1255. }
  1256. else
  1257. {
  1258. iReturn = MessageBoxW(hWndParent,
  1259. pwszText,
  1260. pwszCaption,
  1261. (MB_OK | MB_ICONERROR | MB_APPLMODAL));
  1262. }
  1263. if (iReturn != IDOK)
  1264. {
  1265. //
  1266. // Something bad happened.
  1267. //
  1268. hr = GetLastError();
  1269. DPFX(DPFPREP, 0, "Got unexpected return value %i when displaying message box (err = 0x%lx)!",
  1270. iReturn, hr);
  1271. }
  1272. Exit:
  1273. if (pszText != NULL)
  1274. {
  1275. DNFree(pszText);
  1276. pszText = NULL;
  1277. }
  1278. if (pszCaption != NULL)
  1279. {
  1280. DNFree(pszCaption);
  1281. pszCaption = NULL;
  1282. }
  1283. if (pwszText != NULL)
  1284. {
  1285. DNFree(pwszText);
  1286. pwszText = NULL;
  1287. }
  1288. if (pwszCaption != NULL)
  1289. {
  1290. DNFree(pwszCaption);
  1291. pwszCaption = NULL;
  1292. }
  1293. DPFX(DPFPREP, 6, "Leave");
  1294. } // DoErrorBox
  1295. #undef DPF_MODNAME
  1296. #define DPF_MODNAME "FloatToString"
  1297. //=============================================================================
  1298. // FloatToString
  1299. //-----------------------------------------------------------------------------
  1300. //
  1301. // Description: Converts a FLOAT into a string, using the buffer supplied.
  1302. // The value must be non-negative, and the precision must be at
  1303. // least 1.
  1304. // In some cases, the value may get rounded down incorrectly, so
  1305. // a reasonably large precision is recommended.
  1306. //
  1307. // Arguments:
  1308. // FLOAT fValue - Value to convert.
  1309. // int iPrecision - Number of digits to retain after the decimal
  1310. // point.
  1311. // char * szBuffer - Buffer in which to store resulting string.
  1312. // int iBufferLength - Maximum number of characters in buffer, including
  1313. // NULL termination.
  1314. //
  1315. // Returns: HRESULT
  1316. //=============================================================================
  1317. void FloatToString(const FLOAT fValue,
  1318. const int iPrecision,
  1319. char * const szBuffer,
  1320. const int iBufferLength)
  1321. {
  1322. char * pszDigitString;
  1323. int iDecimal;
  1324. int iTemp;
  1325. char * pSource;
  1326. char * pDest;
  1327. //
  1328. // The value must be non-negative.
  1329. //
  1330. DNASSERT(fValue >= 0.0);
  1331. //
  1332. // The precision must be at least 1.
  1333. //
  1334. DNASSERT(iPrecision >= 1);
  1335. //
  1336. // The buffer needs to be large enough to hold "0.", plus room for the
  1337. // precision requested, plus NULL termination.
  1338. //
  1339. DNASSERT(iBufferLength >= (2 + iPrecision + 1));
  1340. pszDigitString = _ecvt(fValue, (iBufferLength - 2), &iDecimal, &iTemp);
  1341. DNASSERT(iTemp == 0);
  1342. //
  1343. // Treat the number differently if it's 0.0, or between 0.0 and 1.0.
  1344. //
  1345. if (iDecimal <= 0)
  1346. {
  1347. pSource = pszDigitString;
  1348. pDest = szBuffer;
  1349. //
  1350. // Get the absolute decimal point position.
  1351. //
  1352. iDecimal *= -1;
  1353. //
  1354. // Use a leading "0." followed by the digit string.
  1355. //
  1356. (*pDest) = '0';
  1357. pDest++;
  1358. (*pDest) = '.';
  1359. pDest++;
  1360. //
  1361. // Make sure we can even display this number. If not, round the value
  1362. // down to 0.0.
  1363. //
  1364. if (iDecimal >= iPrecision)
  1365. {
  1366. (*pDest) = '0';
  1367. pDest++;
  1368. }
  1369. else
  1370. {
  1371. //
  1372. // Fill in the appropriate number of 0s
  1373. //
  1374. for(iTemp = 0; iTemp < iDecimal; iTemp++)
  1375. {
  1376. (*pDest) = '0';
  1377. pDest++;
  1378. }
  1379. //
  1380. // Copy the non-zero digits indicated by _ecvt.
  1381. // Note that this truncates down, which may cause rounding errors.
  1382. //
  1383. do
  1384. {
  1385. (*pDest) = (*pSource);
  1386. pSource++;
  1387. pDest++;
  1388. iTemp++;
  1389. }
  1390. while (iTemp < iPrecision);
  1391. }
  1392. }
  1393. else
  1394. {
  1395. //
  1396. // Make sure the value isn't too large to display properly.
  1397. //
  1398. DNASSERT(iDecimal < (iBufferLength - 2));
  1399. pSource = pszDigitString;
  1400. pDest = szBuffer;
  1401. //
  1402. // Copy the digits to the left of the decimal.
  1403. //
  1404. memcpy(pDest, pSource, (iDecimal * sizeof(char)));
  1405. pSource += iDecimal;
  1406. pDest += iDecimal;
  1407. //
  1408. // Add the decimal.
  1409. //
  1410. (*pDest) = '.';
  1411. pDest++;
  1412. //
  1413. // Copy the digits to the right of the decimal up to the precision.
  1414. // Note that this truncates down, which may cause rounding errors.
  1415. //
  1416. memcpy(pDest, pSource, (iPrecision * sizeof(char)));
  1417. pDest += iPrecision;
  1418. }
  1419. //
  1420. // Remove all trailing '0' characters, unless there's nothing to the
  1421. // right of the decimal point, in which case leave a single '0'.
  1422. //
  1423. do
  1424. {
  1425. pDest--;
  1426. }
  1427. while ((*pDest) == '0');
  1428. if ((*pDest) == '.')
  1429. {
  1430. *(pDest + 2) = 0; // NULL terminate after a '0'
  1431. }
  1432. else
  1433. {
  1434. *(pDest + 1) = 0; // NULL terminate after this character
  1435. }
  1436. } // FloatToString
  1437. #undef DPF_MODNAME
  1438. #define DPF_MODNAME "GetParametersFromWindow"
  1439. //=============================================================================
  1440. // GetParametersFromWindow
  1441. //-----------------------------------------------------------------------------
  1442. //
  1443. // Description: Reads in the DP8Sim parameters from the given window.
  1444. //
  1445. // Arguments:
  1446. // HWND hWnd - Window with parameters to read.
  1447. // DP8SIM_PARAMETERS * pdp8spSend - Place to store send parameters.
  1448. // DP8SIM_PARAMETERS * pdp8spReceive - Place to store receive parameters.
  1449. //
  1450. // Returns: HRESULT
  1451. //=============================================================================
  1452. void GetParametersFromWindow(HWND hWnd,
  1453. DP8SIM_PARAMETERS * pdp8spSend,
  1454. DP8SIM_PARAMETERS * pdp8spReceive)
  1455. {
  1456. char szNumber[32];
  1457. //
  1458. // Retrieve the send settings from the window.
  1459. //
  1460. ZeroMemory(pdp8spSend, sizeof(*pdp8spSend));
  1461. pdp8spSend->dwSize = sizeof(*pdp8spSend);
  1462. //pdp8spSend->dwFlags = 0;
  1463. pdp8spSend->dwPacketHeaderSize = DP8SIMPACKETHEADERSIZE_IP_UDP;
  1464. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_BANDWIDTH), szNumber, 32);
  1465. pdp8spSend->dwBandwidthBPS = (DWORD) atoi(szNumber);
  1466. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_DROP), szNumber, 32);
  1467. pdp8spSend->fPacketLossPercent = (FLOAT) atof(szNumber);
  1468. if (pdp8spSend->fPacketLossPercent > 100.0)
  1469. {
  1470. pdp8spSend->fPacketLossPercent = 100.0;
  1471. }
  1472. else if (pdp8spSend->fPacketLossPercent < 0.0)
  1473. {
  1474. pdp8spSend->fPacketLossPercent = 0.0;
  1475. }
  1476. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MINLATENCY), szNumber, 32);
  1477. pdp8spSend->dwMinLatencyMS = (DWORD) atoi(szNumber);
  1478. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MAXLATENCY), szNumber, 32);
  1479. pdp8spSend->dwMaxLatencyMS = (DWORD) atoi(szNumber);
  1480. if (pdp8spSend->dwMaxLatencyMS < pdp8spSend->dwMinLatencyMS)
  1481. {
  1482. pdp8spSend->dwMaxLatencyMS = pdp8spSend->dwMinLatencyMS;
  1483. }
  1484. //
  1485. // Retrieve the receive settings from the window.
  1486. //
  1487. ZeroMemory(pdp8spReceive, sizeof(*pdp8spReceive));
  1488. pdp8spReceive->dwSize = sizeof(*pdp8spReceive);
  1489. //pdp8spReceive->dwFlags = 0;
  1490. pdp8spReceive->dwPacketHeaderSize = DP8SIMPACKETHEADERSIZE_IP_UDP;
  1491. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_BANDWIDTH), szNumber, 32);
  1492. pdp8spReceive->dwBandwidthBPS = (DWORD) atoi(szNumber);
  1493. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_DROP), szNumber, 32);
  1494. pdp8spReceive->fPacketLossPercent = (FLOAT) atof(szNumber);
  1495. if (pdp8spReceive->fPacketLossPercent > 100.0)
  1496. {
  1497. pdp8spReceive->fPacketLossPercent = 100.0;
  1498. }
  1499. else if (pdp8spReceive->fPacketLossPercent < 0.0)
  1500. {
  1501. pdp8spReceive->fPacketLossPercent = 0.0;
  1502. }
  1503. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MINLATENCY), szNumber, 32);
  1504. pdp8spReceive->dwMinLatencyMS = (DWORD) atoi(szNumber);
  1505. GetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MAXLATENCY), szNumber, 32);
  1506. pdp8spReceive->dwMaxLatencyMS = (DWORD) atoi(szNumber);
  1507. if (pdp8spReceive->dwMaxLatencyMS < pdp8spReceive->dwMinLatencyMS)
  1508. {
  1509. pdp8spReceive->dwMaxLatencyMS = pdp8spReceive->dwMinLatencyMS;
  1510. }
  1511. } // GetParametersFromWindow
  1512. #undef DPF_MODNAME
  1513. #define DPF_MODNAME "SetParametersInWindow"
  1514. //=============================================================================
  1515. // SetParametersInWindow
  1516. //-----------------------------------------------------------------------------
  1517. //
  1518. // Description: Writes the DP8Sim parameters to the given window.
  1519. //
  1520. // Arguments:
  1521. // HWND hWnd - Window in which to store parameters.
  1522. // DP8SIM_PARAMETERS * pdp8spSend - Pointer to new send parameters.
  1523. // DP8SIM_PARAMETERS * pdp8spReceive - Pointer to new receive parameters.
  1524. //
  1525. // Returns: HRESULT
  1526. //=============================================================================
  1527. void SetParametersInWindow(HWND hWnd,
  1528. DP8SIM_PARAMETERS * pdp8spSend,
  1529. DP8SIM_PARAMETERS * pdp8spReceive)
  1530. {
  1531. char szNumber[32];
  1532. //
  1533. // Write the values to the window.
  1534. //
  1535. wsprintfA(szNumber, "%u", pdp8spSend->dwBandwidthBPS);
  1536. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_BANDWIDTH), szNumber);
  1537. FloatToString(pdp8spSend->fPacketLossPercent, DISPLAY_PRECISION, szNumber, 32);
  1538. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_DROP), szNumber);
  1539. wsprintfA(szNumber, "%u", pdp8spSend->dwMinLatencyMS);
  1540. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MINLATENCY), szNumber);
  1541. wsprintfA(szNumber, "%u", pdp8spSend->dwMaxLatencyMS);
  1542. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_SEND_MAXLATENCY), szNumber);
  1543. wsprintfA(szNumber, "%u", pdp8spReceive->dwBandwidthBPS);
  1544. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_BANDWIDTH), szNumber);
  1545. FloatToString(pdp8spReceive->fPacketLossPercent, DISPLAY_PRECISION, szNumber, 32);
  1546. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_DROP), szNumber);
  1547. wsprintfA(szNumber, "%u", pdp8spReceive->dwMinLatencyMS);
  1548. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MINLATENCY), szNumber);
  1549. wsprintfA(szNumber, "%u", pdp8spReceive->dwMaxLatencyMS);
  1550. SetWindowTextA(GetDlgItem(hWnd, IDE_SETTINGS_RECV_MAXLATENCY), szNumber);
  1551. } // SetParametersInWindow
  1552. #undef DPF_MODNAME
  1553. #define DPF_MODNAME "DisplayCurrentStatistics"
  1554. //=============================================================================
  1555. // DisplayCurrentStatistics
  1556. //-----------------------------------------------------------------------------
  1557. //
  1558. // Description: Retrieves the current DP8Sim statistics and displays them in
  1559. // the given window.
  1560. //
  1561. // Arguments:
  1562. // HWND hWnd - Window in which to write statistics.
  1563. //
  1564. // Returns: HRESULT
  1565. //=============================================================================
  1566. void DisplayCurrentStatistics(HWND hWnd)
  1567. {
  1568. HRESULT hr;
  1569. DP8SIM_STATISTICS dp8ssSend;
  1570. DP8SIM_STATISTICS dp8ssReceive;
  1571. char szNumber[32];
  1572. //
  1573. // Retrieve the current statistics.
  1574. //
  1575. ZeroMemory(&dp8ssSend, sizeof(dp8ssSend));
  1576. dp8ssSend.dwSize = sizeof(dp8ssSend);
  1577. ZeroMemory(&dp8ssReceive, sizeof(dp8ssReceive));
  1578. dp8ssReceive.dwSize = sizeof(dp8ssReceive);
  1579. hr = g_pDP8SimControl->GetAllStatistics(&dp8ssSend, &dp8ssReceive, 0);
  1580. if (hr != DP8SIM_OK)
  1581. {
  1582. DPFX(DPFPREP, 0, "Getting all statistics failed (err = 0x%lx)!", hr);
  1583. }
  1584. else
  1585. {
  1586. //
  1587. // Write the values to the window.
  1588. //
  1589. wsprintfA(szNumber, "%u", dp8ssSend.dwTransmittedPackets);
  1590. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITPACKETS), szNumber);
  1591. wsprintfA(szNumber, "%u", dp8ssSend.dwTransmittedBytes);
  1592. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITBYTES), szNumber);
  1593. wsprintfA(szNumber, "%u", dp8ssSend.dwDroppedPackets);
  1594. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPPACKETS), szNumber);
  1595. wsprintfA(szNumber, "%u", dp8ssSend.dwDroppedBytes);
  1596. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPBYTES), szNumber);
  1597. wsprintfA(szNumber, "%u", dp8ssSend.dwTotalDelayMS);
  1598. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_TOTALDELAY), szNumber);
  1599. wsprintfA(szNumber, "%u", dp8ssReceive.dwTransmittedPackets);
  1600. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITPACKETS), szNumber);
  1601. wsprintfA(szNumber, "%u", dp8ssReceive.dwTransmittedBytes);
  1602. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITBYTES), szNumber);
  1603. wsprintfA(szNumber, "%u", dp8ssReceive.dwDroppedPackets);
  1604. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPPACKETS), szNumber);
  1605. wsprintfA(szNumber, "%u", dp8ssReceive.dwDroppedBytes);
  1606. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPBYTES), szNumber);
  1607. wsprintfA(szNumber, "%u", dp8ssReceive.dwTotalDelayMS);
  1608. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_TOTALDELAY), szNumber);
  1609. }
  1610. } // DisplayCurrentStatistics
  1611. #undef DPF_MODNAME
  1612. #define DPF_MODNAME "MainWindowDlgProc()"
  1613. //=============================================================================
  1614. // MainWindowDlgProc
  1615. //-----------------------------------------------------------------------------
  1616. //
  1617. // Description: Main dialog window message handling.
  1618. //
  1619. // Arguments:
  1620. // HWND hWnd Window handle.
  1621. // UINT uMsg Message identifier.
  1622. // WPARAM wParam Depends on message.
  1623. // LPARAM lParam Depends on message.
  1624. //
  1625. // Returns: Depends on message.
  1626. //=============================================================================
  1627. INT_PTR CALLBACK MainWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  1628. {
  1629. HRESULT hr;
  1630. //HMENU hSysMenu;
  1631. HWND hWndSubItem;
  1632. int iIndex;
  1633. DP8SIM_PARAMETERS dp8spSend;
  1634. DP8SIM_PARAMETERS dp8spReceive;
  1635. BOOL fTemp;
  1636. switch (uMsg)
  1637. {
  1638. case WM_INITDIALOG:
  1639. {
  1640. /*
  1641. //
  1642. // Disable 'maximize' and 'size' on the system menu.
  1643. //
  1644. hSysMenu = GetSystemMenu(hWnd, FALSE);
  1645. EnableMenuItem(hSysMenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED);
  1646. EnableMenuItem(hSysMenu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED);
  1647. */
  1648. //
  1649. // Fill in the list of built-in settings.
  1650. //
  1651. hWndSubItem = GetDlgItem(hWnd, IDCB_SETTINGS);
  1652. for(iIndex = 0; iIndex < (int) g_dwNumSimSettings; iIndex++)
  1653. {
  1654. if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
  1655. {
  1656. SendMessageW(hWndSubItem,
  1657. CB_INSERTSTRING,
  1658. (WPARAM) -1,
  1659. (LPARAM) g_paSimSettings[iIndex].pwszName);
  1660. }
  1661. else
  1662. {
  1663. char * pszName;
  1664. DWORD dwNameSize;
  1665. dwNameSize = wcslen(g_paSimSettings[iIndex].pwszName) + 1;
  1666. pszName = (char*) DNMalloc(dwNameSize);
  1667. if (pszName != NULL)
  1668. {
  1669. hr = STR_WideToAnsi(g_paSimSettings[iIndex].pwszName,
  1670. -1,
  1671. pszName,
  1672. &dwNameSize);
  1673. if (hr == DPN_OK)
  1674. {
  1675. SendMessageA(hWndSubItem,
  1676. CB_INSERTSTRING,
  1677. (WPARAM) -1,
  1678. (LPARAM) pszName);
  1679. }
  1680. else
  1681. {
  1682. SendMessageA(hWndSubItem,
  1683. CB_INSERTSTRING,
  1684. (WPARAM) -1,
  1685. (LPARAM) "???");
  1686. }
  1687. DNFree(pszName);
  1688. }
  1689. else
  1690. {
  1691. SendMessageA(hWndSubItem,
  1692. CB_INSERTSTRING,
  1693. (WPARAM) -1,
  1694. (LPARAM) "???");
  1695. }
  1696. }
  1697. }
  1698. //
  1699. // Select the last item.
  1700. //
  1701. SendMessage(hWndSubItem, CB_SETCURSEL, (WPARAM) (iIndex - 1), 0);
  1702. //
  1703. // Retrieve the current settings.
  1704. //
  1705. ZeroMemory(&dp8spSend, sizeof(dp8spSend));
  1706. dp8spSend.dwSize = sizeof(dp8spSend);
  1707. ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
  1708. dp8spReceive.dwSize = sizeof(dp8spReceive);
  1709. hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
  1710. if (hr != DP8SIM_OK)
  1711. {
  1712. DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
  1713. }
  1714. else
  1715. {
  1716. //
  1717. // Write the values to the window.
  1718. //
  1719. SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
  1720. //
  1721. // SetParametersInWindow updated the edit boxes, and thus
  1722. // caused the "Custom" settings item to get selected.
  1723. // See if these settings match any of the presets, and if
  1724. // so, politely reset the combo box back to the appropriate
  1725. // item.
  1726. //
  1727. for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
  1728. {
  1729. if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
  1730. (memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
  1731. {
  1732. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  1733. CB_SETCURSEL,
  1734. (WPARAM) iIndex,
  1735. 0);
  1736. break;
  1737. }
  1738. }
  1739. //
  1740. // Enable "Save As" if on the Custom setting.
  1741. //
  1742. if (iIndex == (int) (g_dwNumSimSettings - 1))
  1743. {
  1744. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
  1745. }
  1746. else
  1747. {
  1748. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
  1749. }
  1750. }
  1751. //
  1752. // Display the current statistics.
  1753. //
  1754. DisplayCurrentStatistics(hWnd);
  1755. //
  1756. // Turn on auto-refresh by default.
  1757. //
  1758. Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH), BST_CHECKED);
  1759. g_uiAutoRefreshTimer = SetTimer(hWnd,
  1760. AUTOREFRESH_TIMERID,
  1761. AUTOREFRESH_INTERVAL,
  1762. NULL);
  1763. if (g_uiAutoRefreshTimer == 0)
  1764. {
  1765. DPFX(DPFPREP, 0, "Couldn't initially start auto-refresh timer!", 0);
  1766. Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
  1767. BST_UNCHECKED);
  1768. }
  1769. break;
  1770. }
  1771. case WM_SIZE:
  1772. {
  1773. /*
  1774. //
  1775. // Fix a bug in the windows dialog handler.
  1776. //
  1777. if ((wParam == SIZE_RESTORED) || (wParam == SIZE_MINIMIZED))
  1778. {
  1779. hSysMenu = GetSystemMenu(hWnd, FALSE);
  1780. EnableMenuItem(hSysMenu, SC_MINIMIZE, MF_BYCOMMAND | (wParam == SIZE_RESTORED) ? MF_ENABLED : MF_GRAYED);
  1781. EnableMenuItem(hSysMenu, SC_RESTORE, MF_BYCOMMAND | (wParam == SIZE_MINIMIZED) ? MF_ENABLED : MF_GRAYED);
  1782. }
  1783. */
  1784. break;
  1785. }
  1786. case WM_CLOSE:
  1787. {
  1788. //
  1789. // Save the result code for how we quit.
  1790. //
  1791. hr = (HRESULT) wParam;
  1792. //
  1793. // Kill the auto-refresh timer, if it was running.
  1794. //
  1795. if (g_uiAutoRefreshTimer != 0)
  1796. {
  1797. KillTimer(hWnd, g_uiAutoRefreshTimer);
  1798. g_uiAutoRefreshTimer = 0;
  1799. }
  1800. DPFX(DPFPREP, 1, "Closing main window (hresult = 0x%lx).", hr);
  1801. PostQuitMessage(hr);
  1802. break;
  1803. }
  1804. case WM_COMMAND:
  1805. {
  1806. switch (LOWORD(wParam))
  1807. {
  1808. case IDCB_SETTINGS:
  1809. {
  1810. DPFX(DPFPREP, 0, "IDCB_SETTINGS, selection = %i",
  1811. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS), CB_GETCURSEL, 0, 0));
  1812. //
  1813. // If the settings selection has been modified, update the
  1814. // data with the new settings (if control is enabled).
  1815. //
  1816. if (HIWORD(wParam) == CBN_SELCHANGE)
  1817. {
  1818. //
  1819. // Find out what is now selected. Casting is okay,
  1820. // there should not be more than an int's worth of
  1821. // built-in items in 64-bit.
  1822. //
  1823. iIndex = (int) SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  1824. CB_GETCURSEL,
  1825. 0,
  1826. 0);
  1827. //
  1828. // Only use the index if it's valid.
  1829. //
  1830. if ((iIndex >= 0) && (iIndex < (int) g_dwNumSimSettings))
  1831. {
  1832. //
  1833. // Copy in the item's settings.
  1834. //
  1835. memcpy(&dp8spSend, &g_paSimSettings[iIndex].dp8spSend, sizeof(dp8spSend));
  1836. memcpy(&dp8spReceive, &g_paSimSettings[iIndex].dp8spReceive, sizeof(dp8spReceive));
  1837. //
  1838. // If it's the custom item, use the current
  1839. // settings and enable the Save As button.
  1840. //
  1841. if (iIndex == (int) (g_dwNumSimSettings - 1))
  1842. {
  1843. //
  1844. // Retrieve the current settings.
  1845. //
  1846. ZeroMemory(&dp8spSend, sizeof(dp8spSend));
  1847. dp8spSend.dwSize = sizeof(dp8spSend);
  1848. ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
  1849. dp8spReceive.dwSize = sizeof(dp8spReceive);
  1850. hr = g_pDP8SimControl->GetAllParameters(&dp8spSend,
  1851. &dp8spReceive,
  1852. 0);
  1853. if (hr != DP8SIM_OK)
  1854. {
  1855. DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
  1856. //
  1857. // Oh well, just use whatever we have.
  1858. //
  1859. }
  1860. }
  1861. //
  1862. // Write the values to the window.
  1863. //
  1864. SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
  1865. //
  1866. // The apply and revert buttons got enabled
  1867. // automatically when SetParametersInWindow set the
  1868. // edit boxes' values.
  1869. //
  1870. //EnableWindow(GetDlgItem(hWnd, IDB_APPLY), TRUE);
  1871. //EnableWindow(GetDlgItem(hWnd, IDB_REVERT), TRUE);
  1872. //
  1873. // Reselect the item that got us here, since
  1874. // setting the edit boxes' values automatically
  1875. // selected the "Custom" item.
  1876. //
  1877. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  1878. CB_SETCURSEL,
  1879. (WPARAM) iIndex,
  1880. 0);
  1881. //
  1882. // Reset the Save As status depending on whether
  1883. // we reselected the Custom or not.
  1884. //
  1885. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS),
  1886. ((iIndex == (int) (g_dwNumSimSettings - 1)) ? TRUE : FALSE));
  1887. }
  1888. else
  1889. {
  1890. DPFX(DPFPREP, 0, "Settings selection is invalid (%i)!",
  1891. iIndex);
  1892. }
  1893. }
  1894. break;
  1895. }
  1896. case IDE_SETTINGS_SEND_BANDWIDTH:
  1897. case IDE_SETTINGS_SEND_DROP:
  1898. case IDE_SETTINGS_SEND_MINLATENCY:
  1899. case IDE_SETTINGS_SEND_MAXLATENCY:
  1900. case IDE_SETTINGS_RECV_BANDWIDTH:
  1901. case IDE_SETTINGS_RECV_DROP:
  1902. case IDE_SETTINGS_RECV_MINLATENCY:
  1903. case IDE_SETTINGS_RECV_MAXLATENCY:
  1904. {
  1905. //
  1906. // If the edit boxes have been modified, enable the Apply
  1907. // and Revert buttons (if control is enabled and the data
  1908. // actually changed).
  1909. //
  1910. if (HIWORD(wParam) == EN_UPDATE)
  1911. {
  1912. //
  1913. // Retrieve the current settings.
  1914. //
  1915. ZeroMemory(&dp8spSend, sizeof(dp8spSend));
  1916. dp8spSend.dwSize = sizeof(dp8spSend);
  1917. ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
  1918. dp8spReceive.dwSize = sizeof(dp8spReceive);
  1919. hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
  1920. if (hr != DP8SIM_OK)
  1921. {
  1922. DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
  1923. }
  1924. else
  1925. {
  1926. DP8SIM_PARAMETERS dp8spSendFromUI;
  1927. DP8SIM_PARAMETERS dp8spReceiveFromUI;
  1928. GetParametersFromWindow(hWnd,
  1929. &dp8spSendFromUI,
  1930. &dp8spReceiveFromUI);
  1931. //
  1932. // Enable the buttons if any data is different from
  1933. // what is currently applied.
  1934. //
  1935. fTemp = FALSE;
  1936. if (memcmp(&dp8spSendFromUI, &dp8spSend, sizeof(dp8spSend)) != 0)
  1937. {
  1938. fTemp = TRUE;
  1939. }
  1940. if (memcmp(&dp8spReceiveFromUI, &dp8spReceive, sizeof(dp8spReceive)) != 0)
  1941. {
  1942. fTemp = TRUE;
  1943. }
  1944. EnableWindow(GetDlgItem(hWnd, IDB_APPLY), fTemp);
  1945. EnableWindow(GetDlgItem(hWnd, IDB_REVERT), fTemp);
  1946. }
  1947. //
  1948. // Select the "Custom" settings item, which must be the
  1949. // last item.
  1950. //
  1951. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  1952. CB_SETCURSEL,
  1953. (WPARAM) (g_dwNumSimSettings - 1),
  1954. 0);
  1955. //
  1956. // Enable Save As, since Custom is now selected.
  1957. //
  1958. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
  1959. }
  1960. break;
  1961. }
  1962. case IDB_APPLY:
  1963. {
  1964. //
  1965. // Retrieve the settings from the window.
  1966. //
  1967. GetParametersFromWindow(hWnd, &dp8spSend, &dp8spReceive);
  1968. //
  1969. // Parsing in the parameters may have corrected some errors
  1970. // in user entry, so write the settings we're really using
  1971. // back out to the window.
  1972. //
  1973. SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
  1974. //
  1975. // SetParametersInWindow updated the edit boxes, and thus
  1976. // caused the "Custom" settings item to get selected.
  1977. // See if these settings match any of the presets, and if
  1978. // so, politely reset the combo box back to the appropriate
  1979. // item.
  1980. //
  1981. for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
  1982. {
  1983. if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
  1984. (memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
  1985. {
  1986. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  1987. CB_SETCURSEL,
  1988. (WPARAM) iIndex,
  1989. 0);
  1990. break;
  1991. }
  1992. }
  1993. //
  1994. // If the custom item is selected, enable Save As,
  1995. // otherwise, disable it.
  1996. //
  1997. if (iIndex >= (int) (g_dwNumSimSettings - 1))
  1998. {
  1999. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
  2000. }
  2001. else
  2002. {
  2003. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
  2004. }
  2005. //
  2006. // Store those settings.
  2007. //
  2008. hr = g_pDP8SimControl->SetAllParameters(&dp8spSend, &dp8spReceive, 0);
  2009. if (hr != DP8SIM_OK)
  2010. {
  2011. DPFX(DPFPREP, 0, "Setting all parameters failed (err = 0x%lx)!", hr);
  2012. }
  2013. //
  2014. // Disable the Apply and Revert buttons
  2015. //
  2016. EnableWindow(GetDlgItem(hWnd, IDB_APPLY), FALSE);
  2017. EnableWindow(GetDlgItem(hWnd, IDB_REVERT), FALSE);
  2018. break;
  2019. }
  2020. case IDB_REVERT:
  2021. {
  2022. //
  2023. // Retrieve the current settings.
  2024. //
  2025. ZeroMemory(&dp8spSend, sizeof(dp8spSend));
  2026. dp8spSend.dwSize = sizeof(dp8spSend);
  2027. ZeroMemory(&dp8spReceive, sizeof(dp8spReceive));
  2028. dp8spReceive.dwSize = sizeof(dp8spReceive);
  2029. hr = g_pDP8SimControl->GetAllParameters(&dp8spSend, &dp8spReceive, 0);
  2030. if (hr != DP8SIM_OK)
  2031. {
  2032. DPFX(DPFPREP, 0, "Getting all parameters failed (err = 0x%lx)!", hr);
  2033. }
  2034. else
  2035. {
  2036. //
  2037. // Write the values to the window.
  2038. //
  2039. SetParametersInWindow(hWnd, &dp8spSend, &dp8spReceive);
  2040. //
  2041. // SetParametersInWindow updated the edit boxes, and
  2042. // thus caused the "Custom" settings item to get
  2043. // selected. See if these settings match any of the
  2044. // presets, and if so, politely reset the combo box
  2045. // back to the appropriate item.
  2046. //
  2047. for(iIndex = 0; iIndex < (int) (g_dwNumSimSettings - 1); iIndex++)
  2048. {
  2049. if ((memcmp(&dp8spSend, &(g_paSimSettings[iIndex].dp8spSend), sizeof(dp8spSend)) == 0) &&
  2050. (memcmp(&dp8spReceive, &(g_paSimSettings[iIndex].dp8spReceive), sizeof(dp8spReceive)) == 0))
  2051. {
  2052. SendMessage(GetDlgItem(hWnd, IDCB_SETTINGS),
  2053. CB_SETCURSEL,
  2054. (WPARAM) iIndex,
  2055. 0);
  2056. break;
  2057. }
  2058. }
  2059. }
  2060. //
  2061. // If the custom item is selected, enable Save As,
  2062. // otherwise, disable it.
  2063. //
  2064. if (iIndex >= (int) (g_dwNumSimSettings - 1))
  2065. {
  2066. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), TRUE);
  2067. }
  2068. else
  2069. {
  2070. EnableWindow(GetDlgItem(hWnd, IDB_SAVEAS), FALSE);
  2071. }
  2072. //
  2073. // Disable the Apply and Revert buttons
  2074. //
  2075. EnableWindow(GetDlgItem(hWnd, IDB_APPLY), FALSE);
  2076. EnableWindow(GetDlgItem(hWnd, IDB_REVERT), FALSE);
  2077. break;
  2078. }
  2079. case IDB_SAVEAS:
  2080. {
  2081. SIMSETTINGS SimSettings;
  2082. DPFX(DPFPREP, 2, "Saving current sim settings.");
  2083. //
  2084. // Retrieve the settings from the window.
  2085. //
  2086. memset(&SimSettings, 0, sizeof(SimSettings));
  2087. GetParametersFromWindow(hWnd,
  2088. &SimSettings.dp8spSend,
  2089. &SimSettings.dp8spReceive);
  2090. //
  2091. // Prompt the user to name the current custom settings.
  2092. //
  2093. hr = (HRESULT) (INT_PTR) DialogBoxParam((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
  2094. MAKEINTRESOURCE(IDD_NAMESETTINGS),
  2095. hWnd,
  2096. NameSettingsWindowDlgProc,
  2097. (LPARAM) (&SimSettings));
  2098. if (hr != (HRESULT) -1)
  2099. {
  2100. //
  2101. // If we got a name, insert it into the table.
  2102. //
  2103. if (SimSettings.pwszName != NULL)
  2104. {
  2105. hr = SaveSimSettings(hWnd, &SimSettings);
  2106. if (hr != DP8SIM_OK)
  2107. {
  2108. DPFX(DPFPREP, 0, "Couldn't add sim settings to table (err = 0x%lx)!",
  2109. hr);
  2110. if (SimSettings.pwszName != NULL)
  2111. {
  2112. DNFree(SimSettings.pwszName);
  2113. SimSettings.pwszName = NULL;
  2114. }
  2115. }
  2116. }
  2117. }
  2118. else
  2119. {
  2120. hr = GetLastError();
  2121. DPFX(DPFPREP, 0, "Displaying name settings dialog failed (err = %u)!",
  2122. hr);
  2123. }
  2124. break;
  2125. }
  2126. case IDCHK_AUTOREFRESH:
  2127. {
  2128. if (Button_GetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH)) == BST_CHECKED)
  2129. {
  2130. //
  2131. // Set the timer, if it wasn't already.
  2132. //
  2133. if (g_uiAutoRefreshTimer == 0)
  2134. {
  2135. g_uiAutoRefreshTimer = SetTimer(hWnd,
  2136. AUTOREFRESH_TIMERID,
  2137. AUTOREFRESH_INTERVAL,
  2138. NULL);
  2139. if (g_uiAutoRefreshTimer == 0)
  2140. {
  2141. DPFX(DPFPREP, 0, "Couldn't start auto-refresh timer!", 0);
  2142. Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
  2143. BST_UNCHECKED);
  2144. }
  2145. }
  2146. }
  2147. else
  2148. {
  2149. //
  2150. // Kill the timer, if it was running.
  2151. //
  2152. if (g_uiAutoRefreshTimer != 0)
  2153. {
  2154. KillTimer(hWnd, g_uiAutoRefreshTimer);
  2155. g_uiAutoRefreshTimer = 0;
  2156. }
  2157. }
  2158. break;
  2159. }
  2160. case IDB_REFRESH:
  2161. {
  2162. //
  2163. // Display the current statistics.
  2164. //
  2165. DisplayCurrentStatistics(hWnd);
  2166. break;
  2167. }
  2168. case IDB_CLEAR:
  2169. {
  2170. //
  2171. // Clear the statistics.
  2172. //
  2173. hr = g_pDP8SimControl->ClearAllStatistics(0);
  2174. if (hr != DP8SIM_OK)
  2175. {
  2176. DPFX(DPFPREP, 0, "Clearing all statistics failed (err = 0x%lx)!", hr);
  2177. }
  2178. else
  2179. {
  2180. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITPACKETS), "0");
  2181. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_XMITBYTES), "0");
  2182. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPPACKETS), "0");
  2183. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_DROPBYTES), "0");
  2184. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_SEND_TOTALDELAY), "0");
  2185. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITPACKETS), "0");
  2186. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_XMITBYTES), "0");
  2187. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPPACKETS), "0");
  2188. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_DROPBYTES), "0");
  2189. SetWindowTextA(GetDlgItem(hWnd, IDT_STATS_RECV_TOTALDELAY), "0");
  2190. }
  2191. break;
  2192. }
  2193. case IDOK:
  2194. {
  2195. PostMessage(hWnd, WM_CLOSE, 0, 0);
  2196. break;
  2197. }
  2198. } // end switch (on the button pressed/control changed)
  2199. break;
  2200. }
  2201. case WM_TIMER:
  2202. {
  2203. //
  2204. // Display the current statistics.
  2205. //
  2206. DisplayCurrentStatistics(hWnd);
  2207. //
  2208. // Reset the timer to update again.
  2209. //
  2210. g_uiAutoRefreshTimer = SetTimer(hWnd,
  2211. AUTOREFRESH_TIMERID,
  2212. AUTOREFRESH_INTERVAL,
  2213. NULL);
  2214. if (g_uiAutoRefreshTimer == 0)
  2215. {
  2216. DPFX(DPFPREP, 0, "Couldn't reset auto-refresh timer!", 0);
  2217. Button_SetCheck(GetDlgItem(hWnd, IDCHK_AUTOREFRESH),
  2218. BST_UNCHECKED);
  2219. }
  2220. break;
  2221. }
  2222. } // end switch (on the type of window message)
  2223. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  2224. } // MainWindowDlgProc
  2225. #undef DPF_MODNAME
  2226. #define DPF_MODNAME "NameSettingsWindowDlgProc()"
  2227. //=============================================================================
  2228. // NameSettingsWindowDlgProc
  2229. //-----------------------------------------------------------------------------
  2230. //
  2231. // Description: Name settings dialog window message handling.
  2232. //
  2233. // Arguments:
  2234. // HWND hWnd Window handle.
  2235. // UINT uMsg Message identifier.
  2236. // WPARAM wParam Depends on message.
  2237. // LPARAM lParam Depends on message.
  2238. //
  2239. // Returns: Depends on message.
  2240. //=============================================================================
  2241. INT_PTR CALLBACK NameSettingsWindowDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  2242. {
  2243. SIMSETTINGS * pSimSettings;
  2244. int iTextLength;
  2245. DWORD dwTemp;
  2246. #ifndef UNICODE
  2247. char * pszName;
  2248. #endif // ! UNICODE
  2249. switch (uMsg)
  2250. {
  2251. case WM_INITDIALOG:
  2252. {
  2253. //
  2254. // Retrieve the settings to be saved.
  2255. //
  2256. pSimSettings = (SIMSETTINGS*) lParam;
  2257. //
  2258. // Store the pointer off the window.
  2259. //
  2260. SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR) pSimSettings);
  2261. //
  2262. // Set focus on the name edit text box.
  2263. //
  2264. SetFocus(GetDlgItem(hWnd, IDE_NAME));
  2265. break;
  2266. }
  2267. case WM_COMMAND:
  2268. {
  2269. switch (LOWORD(wParam))
  2270. {
  2271. case IDE_NAME:
  2272. {
  2273. //
  2274. // If the edit box has text, enable the OK button.
  2275. //
  2276. if (HIWORD(wParam) == EN_UPDATE)
  2277. {
  2278. if (GetWindowTextLength(GetDlgItem(hWnd, IDE_NAME)) > 0)
  2279. {
  2280. EnableWindow(GetDlgItem(hWnd, IDOK), TRUE);
  2281. }
  2282. else
  2283. {
  2284. EnableWindow(GetDlgItem(hWnd, IDOK), FALSE);
  2285. }
  2286. }
  2287. break;
  2288. }
  2289. case IDOK:
  2290. {
  2291. pSimSettings = (SIMSETTINGS*) GetWindowLongPtr(hWnd, DWLP_USER);
  2292. DNASSERT(pSimSettings != NULL);
  2293. DNASSERT(pSimSettings->dp8spSend.dwSize == sizeof(DP8SIM_PARAMETERS));
  2294. DNASSERT(pSimSettings->dp8spReceive.dwSize == sizeof(DP8SIM_PARAMETERS));
  2295. //
  2296. // Save the name into the sim settings object.
  2297. //
  2298. iTextLength = GetWindowTextLength(GetDlgItem(hWnd, IDE_NAME)) + 1; // include NULL termination
  2299. pSimSettings->pwszName = (WCHAR*) DNMalloc(iTextLength * sizeof(WCHAR));
  2300. if (pSimSettings->pwszName != NULL)
  2301. {
  2302. #ifdef UNICODE
  2303. GetWindowTextW(GetDlgItem(hWnd, IDE_NAME),
  2304. pSimSettings->pwszName,
  2305. iTextLength);
  2306. #else // ! UNICODE
  2307. pszName = (char*) DNMalloc(iTextLength * sizeof(char));
  2308. if (pSimSettings->pwszName == NULL)
  2309. {
  2310. DPFX(DPFPREP, 0, "Couldn't allocate memory to hold ANSI name!");
  2311. DNFree(pSimSettings->pwszName);
  2312. pSimSettings->pwszName = NULL;
  2313. break;
  2314. }
  2315. GetWindowTextA(GetDlgItem(hWnd, IDE_NAME),
  2316. pszName,
  2317. iTextLength);
  2318. if (STR_jkAnsiToWide(pSimSettings->pwszName, pszName, iTextLength) != DPN_OK)
  2319. {
  2320. DPFX(DPFPREP, 0, "Couldn't convert ANSI name to Unicode!");
  2321. DNFree(pszName);
  2322. pszName = NULL;
  2323. DNFree(pSimSettings->pwszName);
  2324. pSimSettings->pwszName = NULL;
  2325. break;
  2326. }
  2327. DNFree(pszName);
  2328. pszName = NULL;
  2329. #endif // ! UNICODE
  2330. //
  2331. // Look for a built-in item with that name.
  2332. //
  2333. for(dwTemp = 0; dwTemp < g_dwNumSimSettings; dwTemp++)
  2334. {
  2335. //
  2336. // If we found it, display an error, free the
  2337. // string.
  2338. //
  2339. if ((g_paSimSettings[dwTemp].uiNameStringResourceID != 0) &&
  2340. (_wcsicmp(g_paSimSettings[dwTemp].pwszName, pSimSettings->pwszName) == 0))
  2341. {
  2342. DPFX(DPFPREP, 0, "Found existing built-in settings with name \"%ls\"!",
  2343. pSimSettings->pwszName);
  2344. DoErrorBox((HINSTANCE) GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
  2345. hWnd,
  2346. IDS_ERROR_CAPTION_BUILTINSETTINGSWITHSAMENAME,
  2347. IDS_ERROR_TEXT_BUILTINSETTINGSWITHSAMENAME);
  2348. DNFree(pSimSettings->pwszName);
  2349. pSimSettings->pwszName = NULL;
  2350. break;
  2351. }
  2352. }
  2353. //
  2354. // If we didn't find an existing item, close the
  2355. // dialog.
  2356. //
  2357. if (dwTemp >= g_dwNumSimSettings)
  2358. {
  2359. EndDialog(hWnd, IDOK);
  2360. }
  2361. }
  2362. else
  2363. {
  2364. DPFX(DPFPREP, 0, "Couldn't allocate memory to hold name!");
  2365. }
  2366. break;
  2367. }
  2368. case IDCANCEL:
  2369. {
  2370. //
  2371. // Do nothing.
  2372. //
  2373. EndDialog(hWnd, IDCANCEL);
  2374. break;
  2375. }
  2376. } // end switch (on the button pressed/control changed)
  2377. break;
  2378. }
  2379. } // end switch (on the type of window message)
  2380. return DefWindowProc(hWnd, uMsg, wParam, lParam);
  2381. } // NameSettingsWindowDlgProc
  2382. #undef DPF_MODNAME
  2383. #define DPF_MODNAME "LoadAndAllocString"
  2384. //=============================================================================
  2385. // LoadAndAllocString
  2386. //-----------------------------------------------------------------------------
  2387. //
  2388. // Description: DNMallocs a wide character string from the given resource ID.
  2389. //
  2390. // Arguments:
  2391. // HINSTANCE hInstance - Module instance handle.
  2392. // UINT uiResourceID - Resource ID to load.
  2393. // WCHAR ** pwszString - Place to store pointer to allocated string.
  2394. //
  2395. // Returns: HRESULT
  2396. //=============================================================================
  2397. HRESULT LoadAndAllocString(HINSTANCE hInstance, UINT uiResourceID, WCHAR ** pwszString)
  2398. {
  2399. HRESULT hr = DPN_OK;
  2400. int iLength;
  2401. #ifdef DEBUG
  2402. DWORD dwError;
  2403. #endif // DEBUG
  2404. if (DNGetOSType() == VER_PLATFORM_WIN32_NT)
  2405. {
  2406. WCHAR wszTmpBuffer[MAX_RESOURCE_STRING_LENGTH];
  2407. iLength = LoadStringW(hInstance, uiResourceID, wszTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
  2408. if (iLength == 0)
  2409. {
  2410. #ifdef DEBUG
  2411. dwError = GetLastError();
  2412. DPFX(DPFPREP, 0, "Unable to load resource ID %d (err = %u)", uiResourceID, dwError);
  2413. #endif // DEBUG
  2414. (*pwszString) = NULL;
  2415. hr = DPNERR_GENERIC;
  2416. goto Exit;
  2417. }
  2418. (*pwszString) = (WCHAR*) DNMalloc((iLength + 1) * sizeof(WCHAR));
  2419. if ((*pwszString) == NULL)
  2420. {
  2421. DPFX(DPFPREP, 0, "Memory allocation failure!");
  2422. hr = DPNERR_OUTOFMEMORY;
  2423. goto Exit;
  2424. }
  2425. wcscpy((*pwszString), wszTmpBuffer);
  2426. }
  2427. else
  2428. {
  2429. char szTmpBuffer[MAX_RESOURCE_STRING_LENGTH];
  2430. iLength = LoadStringA(hInstance, uiResourceID, szTmpBuffer, MAX_RESOURCE_STRING_LENGTH );
  2431. if (iLength == 0)
  2432. {
  2433. #ifdef DEBUG
  2434. dwError = GetLastError();
  2435. DPFX(DPFPREP, 0, "Unable to load resource ID %u (err = %u)!", uiResourceID, dwError);
  2436. #endif // DEBUG
  2437. (*pwszString) = NULL;
  2438. hr = DPNERR_GENERIC;
  2439. goto Exit;
  2440. }
  2441. (*pwszString) = (WCHAR*) DNMalloc((iLength + 1) * sizeof(WCHAR));
  2442. if ((*pwszString) == NULL)
  2443. {
  2444. DPFX(DPFPREP, 0, "Memory allocation failure!");
  2445. hr = DPNERR_OUTOFMEMORY;
  2446. goto Exit;
  2447. }
  2448. hr = STR_jkAnsiToWide((*pwszString), szTmpBuffer, (iLength + 1));
  2449. if (hr != DPN_OK)
  2450. {
  2451. DPFX(DPFPREP, 0, "Unable to convert from ANSI to Unicode (err = 0x%lx)!", hr);
  2452. goto Exit;
  2453. }
  2454. }
  2455. Exit:
  2456. return hr;
  2457. } // LoadAndAllocString