Source code of Windows XP (NT5)
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.

454 lines
9.5 KiB

  1. //============================================================================
  2. // Copyright (C) Microsoft Corporation, 1996 - 1999
  3. //
  4. // File: msgdlg.cpp
  5. //
  6. // History:
  7. // 10/23/96 Abolade Gbadegesin Created.
  8. //
  9. // Implementation of the "Send Message" dialogs.
  10. //============================================================================
  11. #include "stdafx.h"
  12. #include "dialog.h"
  13. #include "rtrstr.h"
  14. extern "C" {
  15. //nclude "dim.h"
  16. //nclude "ras.h"
  17. //nclude "lm.h"
  18. }
  19. #include "msgdlg.h"
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. //----------------------------------------------------------------------------
  26. // Class: CMessageDlg
  27. //
  28. //----------------------------------------------------------------------------
  29. //----------------------------------------------------------------------------
  30. // Function: CMessageDlg::CMessageDlg
  31. //
  32. // Constructor.
  33. //----------------------------------------------------------------------------
  34. CMessageDlg::CMessageDlg(
  35. LPCTSTR pszServerName,
  36. LPCTSTR pszUserName,
  37. LPCTSTR pszComputer,
  38. HANDLE hConnection,
  39. CWnd* pParent
  40. ) : CBaseDialog(IDD_DDM_MESSAGE, pParent),
  41. m_fUser(TRUE),
  42. m_sServerName(pszServerName ? pszServerName : c_szEmpty),
  43. m_sUserName(pszUserName ? pszUserName : c_szEmpty),
  44. m_sTarget(pszComputer ? pszComputer : c_szEmpty),
  45. m_hConnection(hConnection)
  46. {
  47. }
  48. CMessageDlg::CMessageDlg(
  49. LPCTSTR pszServerName,
  50. LPCTSTR pszTarget,
  51. CWnd* pParent
  52. ) : CBaseDialog(IDD_DDM_MESSAGE, pParent),
  53. m_fUser(FALSE),
  54. m_sServerName(pszServerName ? pszServerName: c_szEmpty),
  55. m_sUserName(c_szEmpty),
  56. m_sTarget(pszTarget ? pszTarget : c_szEmpty)
  57. {
  58. }
  59. //----------------------------------------------------------------------------
  60. // Function: CMessageDlg::DoDataExchange
  61. //
  62. // DDX handler.
  63. //----------------------------------------------------------------------------
  64. VOID
  65. CMessageDlg::DoDataExchange(
  66. CDataExchange* pDX
  67. ) {
  68. CBaseDialog::DoDataExchange(pDX);
  69. }
  70. BEGIN_MESSAGE_MAP(CMessageDlg, CBaseDialog)
  71. END_MESSAGE_MAP()
  72. DWORD CMessageDlg::m_dwHelpMap[] =
  73. {
  74. // IDC_DM_TO, HIDC_DM_TO,
  75. // IDC_DM_MESSAGE, HIDC_DM_MESSAGE,
  76. 0,0
  77. };
  78. //----------------------------------------------------------------------------
  79. // Function: CMessageDlg::OnInitDialog
  80. //
  81. // Performs dialog initialization.
  82. //----------------------------------------------------------------------------
  83. BOOL
  84. CMessageDlg::OnInitDialog(
  85. ) {
  86. CBaseDialog::OnInitDialog();
  87. //
  88. // Set the 'To' text to indicate who the message is going to
  89. //
  90. CString sText;
  91. if (m_fUser) {
  92. //
  93. // We're sending to a client
  94. //
  95. AfxFormatString2(sText, IDS_DM_TO_USER_FORMAT, m_sUserName, m_sTarget);
  96. }
  97. else {
  98. CString stTarget;
  99. // Windows NT Bug : 285468
  100. // Need to adjust for the local machine case. (if we are
  101. // a local machine, then we will get a NULL name).
  102. stTarget = m_sTarget;
  103. if (stTarget.IsEmpty())
  104. {
  105. stTarget.LoadString(IDS_DM_LOCAL_MACHINE);
  106. }
  107. //
  108. // We're sending to all RAS users in a domain or server
  109. //
  110. AfxFormatString1(
  111. sText, IDS_DM_TO_SERVER_FORMAT,
  112. stTarget
  113. );
  114. }
  115. SetDlgItemText(IDC_DM_EDIT_TO, sText);
  116. return FALSE;
  117. }
  118. //----------------------------------------------------------------------------
  119. // Function: CMessageDlg::OnOK
  120. //
  121. //----------------------------------------------------------------------------
  122. VOID
  123. CMessageDlg::OnOK(
  124. ) {
  125. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  126. CString sText;
  127. DWORD err = ERROR_SUCCESS;
  128. SPMprServerHandle sphMprServer;
  129. USES_CONVERSION;
  130. GetDlgItemText(IDC_DM_EDIT_MESSAGE, sText);
  131. if (!sText.GetLength() &&
  132. AfxMessageBox(IDS_ERR_NO_TEXT, MB_YESNO|MB_ICONQUESTION) != IDYES)
  133. {
  134. return;
  135. }
  136. if (m_fUser)
  137. {
  138. CWaitCursor wait;
  139. // Need to get a connection to the server (to get the server handle)
  140. err = ::MprAdminServerConnect(T2W((LPTSTR)(LPCTSTR)m_sServerName),
  141. &sphMprServer);
  142. if (err == ERROR_SUCCESS)
  143. err = SendToClient(m_sServerName,
  144. m_sTarget,
  145. sphMprServer,
  146. m_hConnection,
  147. sText);
  148. sphMprServer.Release();
  149. }
  150. else
  151. {
  152. err = SendToServer(m_sServerName, sText);
  153. }
  154. if (err == NERR_Success)
  155. {
  156. CBaseDialog::OnOK();
  157. }
  158. }
  159. /*!--------------------------------------------------------------------------
  160. CMessageDlg::SendToServer
  161. -
  162. Author: KennT
  163. ---------------------------------------------------------------------------*/
  164. DWORD
  165. CMessageDlg::SendToServer(
  166. LPCTSTR pszServer,
  167. LPCTSTR pszText,
  168. BOOL* pbCancel
  169. ) {
  170. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  171. DWORD dwErr = ERROR_SUCCESS;
  172. CString sText;
  173. TCHAR szServer[MAX_COMPUTERNAME_LENGTH+3];
  174. DWORD i, dwTotal = 0, rc0Count = 0;
  175. RAS_CONNECTION_0 *rc0Table = NULL, *prc0;
  176. WCHAR wszServer[MAX_COMPUTERNAME_LENGTH+3];
  177. HRESULT hr = hrOK;
  178. SPMprServerHandle sphMprServer;
  179. SPMprAdminBuffer spMprBuffer;
  180. Assert(pszServer);
  181. Assert(pszText);
  182. COM_PROTECT_TRY
  183. {
  184. StrCpy(szServer, pszServer);
  185. StrCpyWFromT(wszServer, pszServer);
  186. //
  187. // See if the router is installed on the machine;
  188. //
  189. if (!::MprAdminIsServiceRunning(wszServer))
  190. {
  191. goto Error;
  192. }
  193. //
  194. // Connect to the server
  195. //
  196. {
  197. CWaitCursor wait;
  198. dwErr = ::MprAdminServerConnect(wszServer, &sphMprServer);
  199. }
  200. if (dwErr != NO_ERROR) {
  201. TCHAR szText[2048];
  202. FormatSystemError(HRESULT_FROM_WIN32(dwErr),
  203. szText, DimensionOf(szText), 0,
  204. FSEFLAG_ANYMESSAGE);
  205. AfxFormatString2(sText, IDS_ERR_CONNECT_ERROR, szServer, szText);
  206. AfxMessageBox(sText, MB_OK|MB_ICONINFORMATION);
  207. goto Error;
  208. }
  209. //
  210. // Retrieve an array of the connections on the server
  211. //
  212. {
  213. CWaitCursor wait;
  214. rc0Table = NULL;
  215. dwErr = ::MprAdminConnectionEnum(
  216. sphMprServer,
  217. 0,
  218. (BYTE**)&spMprBuffer,
  219. (DWORD)-1,
  220. &rc0Count,
  221. &dwTotal,
  222. NULL
  223. );
  224. rc0Table = (RAS_CONNECTION_0 *) (BYTE *) spMprBuffer;
  225. }
  226. if (dwErr != NO_ERROR) {
  227. TCHAR szText[2048];
  228. FormatSystemError(HRESULT_FROM_WIN32(dwErr),
  229. szText, DimensionOf(szText), 0,
  230. FSEFLAG_ANYMESSAGE);
  231. AfxFormatString2(sText, IDS_ERR_CONNENUM_ERROR, szServer, szText);
  232. AfxMessageBox(sText, MB_OK|MB_ICONINFORMATION);
  233. goto Error;
  234. }
  235. //
  236. // For each one which is a client with RAS_FLAGS_MESSENGER_PRESENT,
  237. // send the message
  238. //
  239. for (i = 0; i < rc0Count; i++)
  240. {
  241. prc0 = rc0Table + i;
  242. if (prc0->dwInterfaceType != ROUTER_IF_TYPE_CLIENT ||
  243. !lstrlenW(prc0->wszRemoteComputer) ||
  244. !(prc0->dwConnectionFlags & RAS_FLAGS_MESSENGER_PRESENT)){
  245. continue;
  246. }
  247. dwErr = SendToClient(pszServer,
  248. prc0->wszRemoteComputer,
  249. sphMprServer,
  250. prc0->hConnection,
  251. pszText);
  252. if (!dwErr) { continue; }
  253. AfxFormatString1(sText, IDS_PROMPT_SERVER_CONTINUE, szServer);
  254. if (AfxMessageBox(sText, MB_YESNO|MB_ICONQUESTION) == IDNO)
  255. {
  256. if (pbCancel) { *pbCancel = TRUE; }
  257. break;
  258. }
  259. }
  260. COM_PROTECT_ERROR_LABEL;
  261. }
  262. COM_PROTECT_CATCH;
  263. if ((dwErr == ERROR_SUCCESS) && !FHrSucceeded(hr))
  264. {
  265. // Assume that the failure was an out of memory
  266. dwErr = ERROR_OUTOFMEMORY;
  267. }
  268. sphMprServer.Release();
  269. return dwErr;
  270. }
  271. /*!--------------------------------------------------------------------------
  272. CMessageDlg::SendToClient
  273. -
  274. Author: KennT
  275. ---------------------------------------------------------------------------*/
  276. DWORD CMessageDlg::SendToClient(LPCTSTR pszServerName,
  277. LPCTSTR pszTarget,
  278. MPR_SERVER_HANDLE hMprServer,
  279. HANDLE hConnection,
  280. LPCTSTR pszText)
  281. {
  282. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  283. WCHAR *pswzText = NULL;
  284. CString sText;
  285. DWORD dwErr;
  286. HKEY hkMachine = NULL;
  287. HRESULT hr = hrOK;
  288. RouterVersionInfo verInfo;
  289. USES_CONVERSION;
  290. Assert(pszTarget);
  291. Assert(pszServerName);
  292. Assert(hMprServer);
  293. Assert(hConnection);
  294. COM_PROTECT_TRY
  295. {
  296. // Windows NT Bug : 158746
  297. // Note, if the target machine is NT5, then we can use the
  298. // new APIs
  299. // ------------------------------------------------------------
  300. // setup a default of NT5
  301. // ------------------------------------------------------------
  302. verInfo.dwRouterVersion = 5;
  303. dwErr = ConnectRegistry(pszServerName, &hkMachine);
  304. hr = HRESULT_FROM_WIN32(dwErr);
  305. if (FHrSucceeded(hr) && hkMachine)
  306. {
  307. QueryRouterVersionInfo(hkMachine, &verInfo);
  308. DisconnectRegistry(hkMachine);
  309. }
  310. // For NT4, call the old NetMessageBufferSend
  311. // ------------------------------------------------------------
  312. if (verInfo.dwRouterVersion == 4)
  313. {
  314. CWaitCursor wait;
  315. pswzText = StrDupWFromT(pszText);
  316. dwErr = ::NetMessageBufferSend(
  317. NULL,
  318. T2W((LPTSTR) pszTarget),
  319. NULL,
  320. (BYTE *) pswzText,
  321. CbStrLenW(pswzText));
  322. }
  323. else
  324. {
  325. // For NT5 and up, Use the MprAdminXXX api. This will
  326. // work correctly for the Appletalk case
  327. // --------------------------------------------------------
  328. CWaitCursor wait;
  329. dwErr = ::MprAdminSendUserMessage(hMprServer,
  330. hConnection,
  331. T2W((LPTSTR) pszText));
  332. }
  333. if (dwErr != ERROR_SUCCESS)
  334. {
  335. TCHAR szText[2048];
  336. FormatSystemError(HRESULT_FROM_WIN32(dwErr),
  337. szText, DimensionOf(szText), 0,
  338. FSEFLAG_ANYMESSAGE);
  339. AfxFormatString2(sText, IDS_ERR_SEND_FAILED, pszTarget, szText);
  340. AfxMessageBox(sText, MB_OK|MB_ICONINFORMATION);
  341. }
  342. }
  343. COM_PROTECT_CATCH;
  344. delete pswzText;
  345. if ((dwErr == ERROR_SUCCESS) && !FHrSucceeded(hr))
  346. {
  347. dwErr = ERROR_OUTOFMEMORY;
  348. }
  349. return dwErr;
  350. }