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.

690 lines
20 KiB

  1. /*****************************************************************************
  2. *
  3. * $Workfile: TCPMonUI.cpp $
  4. *
  5. * Copyright (C) 1997 Hewlett-Packard Company.
  6. * All rights reserved.
  7. *
  8. * 11311 Chinden Blvd.
  9. * Boise, Idaho 83714
  10. *
  11. *****************************************************************************/
  12. #include "precomp.h"
  13. #include "TCPMonUI.h"
  14. #include "UIMgr.h"
  15. #include "resource.h"
  16. #include "splcom.h"
  17. #include "helpids.h"
  18. HINSTANCE g_hInstance = NULL;
  19. MONITORUI g_monitorUI;
  20. // library handles:
  21. HINSTANCE g_hWinSpoolLib = NULL;
  22. HINSTANCE g_hPortMonLib = NULL;
  23. HINSTANCE g_hTcpMibLib = NULL;
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // LoadGlobalLibraries
  26. //
  27. BOOL LoadGlobalLibraries()
  28. {
  29. BOOL bReturn = TRUE;
  30. g_hWinSpoolLib = ::LoadLibrary(TEXT("WinSpool.drv"));
  31. if(g_hWinSpoolLib == NULL)
  32. {
  33. DisplayErrorMessage(NULL, IDS_STRING_ERROR_TITLE, IDS_STRING_ERROR_LOADING_WINSPOOL_LIB);
  34. bReturn = FALSE;
  35. }
  36. // In either case load the tcpmib dll.
  37. g_hTcpMibLib = ::LoadLibrary(TCPMIB_DLL_NAME);
  38. if(g_hTcpMibLib == NULL)
  39. {
  40. DisplayErrorMessage(NULL, IDS_STRING_ERROR_TITLE, IDS_STRING_ERROR_LOADING_TCPMIB_LIB);
  41. bReturn = FALSE;
  42. }
  43. return(bReturn);
  44. } // LoadGlobalLibraries
  45. ///////////////////////////////////////////////////////////////////////////////
  46. // DllMain
  47. //
  48. BOOL APIENTRY
  49. DllMain ( HANDLE in hInst,
  50. DWORD in dwReason,
  51. LPVOID in lpReserved )
  52. {
  53. switch (dwReason)
  54. {
  55. case DLL_PROCESS_ATTACH:
  56. //
  57. // Initialize common controls.
  58. //
  59. INITCOMMONCONTROLSEX icc;
  60. InitCommonControls();
  61. icc.dwSize = sizeof(INITCOMMONCONTROLSEX);
  62. icc.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES;
  63. InitCommonControlsEx(&icc);
  64. DisableThreadLibraryCalls( hInst );
  65. InitDebug(MONUI_DEBUG_FILE); // initialize debug file
  66. g_hInstance = (HINSTANCE) hInst;
  67. memset(&g_monitorUI, 0, sizeof(g_monitorUI));
  68. return TRUE;
  69. case DLL_PROCESS_DETACH:
  70. {
  71. // The UI sets the last error for the spooler to use later
  72. // we are keeping a copy to make sure that it is not over
  73. // written by the dlls as they unload
  74. //
  75. DWORD dwLastError = GetLastError();
  76. if( g_hWinSpoolLib != NULL )
  77. {
  78. ::FreeLibrary(g_hWinSpoolLib);
  79. }
  80. if( g_hPortMonLib != NULL )
  81. {
  82. ::FreeLibrary(g_hPortMonLib);
  83. }
  84. if( g_hTcpMibLib != NULL )
  85. {
  86. ::FreeLibrary(g_hTcpMibLib);
  87. }
  88. if (WSACleanup() == SOCKET_ERROR)
  89. {
  90. _RPT0(_CRT_WARN,"\t> Unable to clean up windows sockets\n");
  91. }
  92. // This resets the application last error if one
  93. // exists. We cannot allow the UI last error to
  94. // be overwritten by the dlls being unloaded
  95. //
  96. if( dwLastError != NO_ERROR ) {
  97. SetLastError( dwLastError );
  98. }
  99. }
  100. // perform any necessary clean up process
  101. return TRUE;
  102. case DLL_THREAD_ATTACH:
  103. return TRUE;
  104. case DLL_THREAD_DETACH:
  105. return TRUE;
  106. }
  107. return FALSE;
  108. } // DllMain
  109. ///////////////////////////////////////////////////////////////////////////////
  110. // InitializePrintMonitorUI
  111. // Returns a MONITOREX structure or NULL if failure
  112. //
  113. PMONITORUI WINAPI
  114. InitializePrintMonitorUI(VOID)
  115. {
  116. DWORD dwRetCode = NO_ERROR;
  117. PMONITORUI pMonitorUI = NULL;
  118. WSADATA wsaData;
  119. if(! LoadGlobalLibraries())
  120. return NULL;
  121. // Start up Winsock.
  122. if ( WSAStartup(WS_VERSION_REQUIRED, (LPWSADATA)&wsaData) != NO_ERROR)
  123. {
  124. _RPT1(_CRT_WARN, "CSSOCKET -- CStreamSocket() WSAStartup failed! Error( %d )\n", WSAGetLastError());
  125. return NULL;
  126. }
  127. g_monitorUI.dwMonitorUISize = sizeof(MONITORUI);
  128. g_monitorUI.pfnAddPortUI = ::AddPortUI;
  129. g_monitorUI.pfnConfigurePortUI = ::ConfigurePortUI;
  130. g_monitorUI.pfnDeletePortUI = ::DeletePortUI;
  131. pMonitorUI = &g_monitorUI;
  132. return (pMonitorUI);
  133. } // InitializePrintMonitorUI
  134. ///////////////////////////////////////////////////////////////////////////////
  135. // RemoteAddPortUI
  136. // Returns TRUE if success, FALSE otherwise
  137. //
  138. extern "C" BOOL WINAPI
  139. AddPortUI(PCWSTR pszServer, HWND hWnd, PCWSTR pszMonitorNameIn, PWSTR *ppszPortNameOut)
  140. {
  141. CUIManager manager;
  142. HANDLE hXcvPrinter = NULL;
  143. PRINTER_DEFAULTS Default = { NULL, NULL, SERVER_ACCESS_ADMINISTER };
  144. DWORD dwRetCode = NO_ERROR;
  145. BOOL bReturn = TRUE;
  146. TCHAR szServerName[MAX_NETWORKNAME_LEN] = {0};
  147. if ( ppszPortNameOut )
  148. *ppszPortNameOut = NULL;
  149. if (hWnd == NULL)
  150. {
  151. return TRUE;
  152. }
  153. TCHAR *psztPortName = (TCHAR *)malloc(sizeof(TCHAR) * MAX_PORTNAME_LEN);
  154. if( psztPortName == NULL )
  155. {
  156. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  157. return( FALSE );
  158. }
  159. if(pszServer != NULL)
  160. {
  161. lstrcpyn(szServerName, pszServer, MAX_NETWORKNAME_LEN);
  162. }
  163. // Construct the OpenPrinter String
  164. TCHAR OpenPrinterString[MAX_UNC_PRINTER_NAME];
  165. if(pszServer == NULL)
  166. {
  167. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT(",XcvMonitor %s"), pszMonitorNameIn);
  168. }
  169. else
  170. {
  171. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT("%s\\,XcvMonitor %s"), pszServer, pszMonitorNameIn);
  172. }
  173. bReturn = OpenPrinter(OpenPrinterString, &hXcvPrinter, &Default);
  174. if(bReturn)
  175. {
  176. if(hXcvPrinter != NULL)
  177. {
  178. dwRetCode = manager.AddPortUI(hWnd,
  179. hXcvPrinter,
  180. szServerName,
  181. psztPortName);
  182. }
  183. if ( ppszPortNameOut )
  184. {
  185. _ASSERTE(psztPortName != NULL);
  186. *ppszPortNameOut = psztPortName;
  187. psztPortName = NULL;
  188. }
  189. }
  190. else
  191. {
  192. dwRetCode = GetLastError();
  193. }
  194. if( psztPortName != NULL)
  195. {
  196. free( psztPortName );
  197. psztPortName = NULL;
  198. }
  199. if( hXcvPrinter != NULL )
  200. {
  201. ClosePrinter(hXcvPrinter);
  202. }
  203. if( dwRetCode != NO_ERROR )
  204. {
  205. // something went wrong
  206. bReturn = FALSE;
  207. }
  208. SetLastError( dwRetCode );
  209. return bReturn;
  210. } // ExtAddPortUI
  211. ///////////////////////////////////////////////////////////////////////////////
  212. // Load and Call XcvData in order to get Configuration Information.
  213. // Returns TRUE if success, FALSE otherwise
  214. //
  215. DWORD GetConfigInfo(PORT_DATA_1 *pData, HANDLE hXcvPrinter, PCWSTR pszPortName)
  216. {
  217. XCVDATAPARAM pfnXcvData = NULL;
  218. DWORD dwRet = NO_ERROR;
  219. DWORD dwDataSize = 0;
  220. DWORD dwOutputNeeded = 0;
  221. DWORD dwStatus = 0;
  222. BOOL bReturn = TRUE;
  223. CONFIG_INFO_DATA_1 cfgData;
  224. memset( &cfgData, 0, sizeof( cfgData ));
  225. cfgData.dwVersion = 1;
  226. // load & assign the function pointer
  227. if(g_hWinSpoolLib != NULL)
  228. {
  229. // initialize the library
  230. pfnXcvData = (XCVDATAPARAM)::GetProcAddress(g_hWinSpoolLib, "XcvDataW");
  231. if(pfnXcvData != NULL)
  232. {
  233. dwDataSize = sizeof(PORT_DATA_1);
  234. //
  235. // Set the UI version
  236. //
  237. pData->dwVersion = 1;
  238. // here's the call we've all been waiting for:
  239. bReturn = (*pfnXcvData)(hXcvPrinter,
  240. (PCWSTR)TEXT("GetConfigInfo"),
  241. (LPBYTE)&cfgData, // Input Data
  242. sizeof( cfgData ), // Input Data Size
  243. (LPBYTE)pData, // Output Data
  244. dwDataSize, // Output Data Size
  245. &dwOutputNeeded, // size of output buffer server wants to return
  246. &dwStatus // return status value from remote component
  247. );
  248. if(!bReturn)
  249. {
  250. dwRet = GetLastError();
  251. DisplayErrorMessage(NULL, dwRet);
  252. }
  253. else
  254. {
  255. if(dwStatus != NO_ERROR)
  256. {
  257. DisplayErrorMessage(NULL, dwStatus);
  258. }
  259. }
  260. }
  261. else
  262. {
  263. dwRet = ERROR_DLL_NOT_FOUND; // TODO: change to an appropriate error code.
  264. }
  265. }
  266. else
  267. {
  268. dwRet = ERROR_DLL_NOT_FOUND;
  269. }
  270. return(dwRet);
  271. } // GetConfigInfo
  272. ///////////////////////////////////////////////////////////////////////////////
  273. // RemoteConfigurePortUI
  274. // Returns TRUE if success, FALSE otherwise
  275. //
  276. extern "C" BOOL WINAPI
  277. ConfigurePortUI(PCWSTR pszServer, HWND hWnd, PCWSTR pszPortName)
  278. {
  279. PORT_DATA_1 Data;
  280. memset(&Data, 0, sizeof(PORT_DATA_1));
  281. CUIManager manager;
  282. HANDLE hXcvPrinter = NULL;
  283. PRINTER_DEFAULTS Default = { NULL, NULL, SERVER_ACCESS_ADMINISTER };
  284. DWORD dwResult = NO_ERROR;
  285. BOOL bReturn = TRUE;
  286. TCHAR OpenPrinterString[MAX_UNC_PRINTER_NAME];
  287. TCHAR szServerName[MAX_NETWORKNAME_LEN] = {0};
  288. if(pszServer && *pszServer)
  289. {
  290. lstrcpyn(szServerName, pszServer, MAX_NETWORKNAME_LEN);
  291. }
  292. if(hWnd == NULL)
  293. {
  294. return bReturn;
  295. }
  296. // Construct the OpenPrinter String
  297. if(pszServer && *pszServer)
  298. {
  299. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT("%s\\,XcvPort %s"), pszServer, pszPortName);
  300. }
  301. else
  302. {
  303. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT(",XcvPort %s"), pszPortName);
  304. }
  305. bReturn = OpenPrinter(OpenPrinterString, &hXcvPrinter, &Default);
  306. if(bReturn != FALSE && hXcvPrinter != NULL)
  307. {
  308. HCURSOR hNewCursor = NULL;
  309. HCURSOR hOldCursor = NULL;
  310. hNewCursor = LoadCursor(NULL, IDC_WAIT);
  311. if( hNewCursor )
  312. {
  313. hOldCursor = SetCursor(hNewCursor);
  314. }
  315. dwResult = GetConfigInfo(&Data, hXcvPrinter, pszPortName);
  316. if( hNewCursor )
  317. {
  318. SetCursor(hOldCursor);
  319. }
  320. if(dwResult != NO_ERROR)
  321. {
  322. SetLastError(dwResult);
  323. bReturn = FALSE;
  324. }
  325. if(bReturn == TRUE)
  326. {
  327. dwResult = manager.ConfigPortUI(hWnd, &Data, hXcvPrinter, szServerName);
  328. if(dwResult != NO_ERROR)
  329. {
  330. SetLastError(dwResult);
  331. bReturn = FALSE;
  332. }
  333. }
  334. }
  335. if( hXcvPrinter != NULL )
  336. {
  337. ClosePrinter(hXcvPrinter);
  338. }
  339. if (!bReturn && dwResult != NO_ERROR)
  340. {
  341. SetLastError (dwResult);
  342. }
  343. return(bReturn);
  344. } // ConfigurePortUI
  345. ///////////////////////////////////////////////////////////////////////////////
  346. // RemoteDeletePortUI
  347. // Returns TRUE if success, FALSE otherwise
  348. //
  349. extern "C" BOOL WINAPI
  350. DeletePortUI(PCWSTR pszServer,
  351. HWND hwnd,
  352. PCWSTR pszPortName)
  353. {
  354. HANDLE hXcvPrinter = NULL;
  355. PRINTER_DEFAULTS Default = { NULL, NULL, SERVER_ACCESS_ADMINISTER };
  356. BOOL bReturn = TRUE;
  357. XCVDATAPARAM pfnXcvData = NULL;
  358. DELETE_PORT_DATA_1 delData;
  359. memset(&delData, 0, sizeof(DELETE_PORT_DATA_1));
  360. DWORD dwDataSize = 0;
  361. DWORD dwOutputNeeded = 0;
  362. DWORD dwStatus = 0;
  363. TCHAR OpenPrinterString[MAX_UNC_PRINTER_NAME];
  364. // Construct the OpenPrinter String
  365. if(pszServer == NULL || pszServer[0] == TEXT('\0'))
  366. {
  367. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT(",XcvPort %s"), pszPortName);
  368. }
  369. else
  370. {
  371. StringCchPrintf (OpenPrinterString, COUNTOF (OpenPrinterString), TEXT("%s\\,XcvPort %s"), pszServer, pszPortName);
  372. }
  373. bReturn = OpenPrinter(OpenPrinterString, &hXcvPrinter, &Default);
  374. if(bReturn)
  375. {
  376. // load & assign the function pointer
  377. if(g_hWinSpoolLib != NULL)
  378. {
  379. // initialize the library
  380. pfnXcvData = (XCVDATAPARAM)::GetProcAddress(g_hWinSpoolLib, "XcvDataW");
  381. if(pfnXcvData != NULL)
  382. {
  383. // Set the data members of delData.
  384. if(pszServer && *pszServer )
  385. {
  386. lstrcpyn(delData.psztName, pszServer, MAX_NETWORKNAME_LEN);
  387. }
  388. else
  389. {
  390. delData.psztName[0] = '\0';
  391. }
  392. //delData.hWnd = 0; This field si not used anywhere
  393. delData.dwVersion = 1;
  394. if(pszPortName != NULL)
  395. {
  396. lstrcpyn(delData.psztPortName, pszPortName, MAX_PORTNAME_LEN);
  397. }
  398. else
  399. {
  400. delData.psztPortName[0] = '\0';
  401. }
  402. dwDataSize = sizeof(DELETE_PORT_DATA_1);
  403. // here's the call we've all been waiting for:
  404. bReturn = (*pfnXcvData)(hXcvPrinter,
  405. (PCWSTR)TEXT("DeletePort"),
  406. (BYTE *)(& delData), // Input Data
  407. dwDataSize, // Input Data Size
  408. NULL, // Output Data
  409. 0, // Output Data Size
  410. &dwOutputNeeded, // size of output buffer server wants to return
  411. &dwStatus // return status value from remote component
  412. );
  413. if(bReturn)
  414. {
  415. if(dwStatus != NO_ERROR)
  416. {
  417. DisplayErrorMessage(NULL, dwStatus);
  418. //
  419. // The call actually failed. Since we already displayed the error message
  420. // we need to disable the popup from printui.
  421. //
  422. SetLastError (ERROR_CANCELLED);
  423. bReturn = FALSE;
  424. }
  425. }
  426. else {
  427. DisplayErrorMessage(NULL, GetLastError ());
  428. //
  429. // The call actually failed. Since we already displayed the error message
  430. // we need to disable the popup from printui.
  431. //
  432. SetLastError (ERROR_CANCELLED);
  433. bReturn = FALSE;
  434. }
  435. }
  436. else // pfnXcvData == NULL
  437. {
  438. bReturn = FALSE;
  439. SetLastError(ERROR_DLL_NOT_FOUND);
  440. }
  441. }
  442. else // g_hWinSpoolLib == NULL
  443. {
  444. SetLastError(ERROR_DLL_NOT_FOUND);
  445. }
  446. if( hXcvPrinter != NULL )
  447. {
  448. DWORD dwLastError = GetLastError ();
  449. ClosePrinter(hXcvPrinter);
  450. SetLastError (dwLastError);
  451. }
  452. }
  453. return(bReturn);
  454. } // DeletePortUI
  455. ///////////////////////////////////////////////////////////////////////////////
  456. // LocalAddPortUI
  457. // Returns TRUE if success, FALSE otherwise
  458. //
  459. extern "C" BOOL WINAPI
  460. LocalAddPortUI(HWND in hWnd)
  461. {
  462. DWORD dwRetCode = NO_ERROR;
  463. CUIManager manager;
  464. dwRetCode = manager.AddPortUI(hWnd, NULL, NULL, NULL);
  465. if (dwRetCode != NO_ERROR)
  466. {
  467. SetLastError(dwRetCode);
  468. return FALSE;
  469. }
  470. return TRUE;
  471. } // LocalAddPortUI
  472. ///////////////////////////////////////////////////////////////////////////////
  473. // LocalConfigurePortUI
  474. // Returns TRUE if success, FALSE otherwise
  475. //
  476. extern "C" BOOL WINAPI
  477. LocalConfigurePortUI(HWND in hWnd,
  478. PORT_DATA_1 in *pConfigPortData)
  479. {
  480. DWORD dwRetCode = NO_ERROR;
  481. CUIManager manager;
  482. // call ConfigurePortUI()
  483. dwRetCode = manager.ConfigPortUI(hWnd, pConfigPortData, NULL, NULL);
  484. if (dwRetCode != NO_ERROR)
  485. {
  486. SetLastError(dwRetCode);
  487. return FALSE;
  488. }
  489. return TRUE;
  490. } // LocalConfigurePortUI
  491. ///////////////////////////////////////////////////////////////////////////////
  492. // FUNCTION: DisplayErrorMessage()
  493. //
  494. // PURPOSE: To load a string resource, the error message, and put up a message box.
  495. //
  496. void DisplayErrorMessage(HWND hDlg, UINT uErrorTitleResource, UINT uErrorStringResource)
  497. {
  498. TCHAR ptcsErrorTitle[MAX_PATH];
  499. TCHAR ptcsErrorMessage[MAX_PATH];
  500. LoadString(g_hInstance, uErrorTitleResource, ptcsErrorTitle, MAX_PATH);
  501. LoadString(g_hInstance, uErrorStringResource, ptcsErrorMessage, MAX_PATH);
  502. MessageBox(hDlg, ptcsErrorMessage, ptcsErrorTitle, MB_ICONERROR);
  503. } // DisplayErrorMessage
  504. ///////////////////////////////////////////////////////////////////////////////
  505. // FUNCTION: DisplayErrorMessage()
  506. //
  507. // PURPOSE: To load a string resource, the error message, and put up a message box.
  508. //
  509. void DisplayErrorMessage(HWND hDlg, DWORD dwLastError)
  510. {
  511. const int iMaxErrorMsgSize = 75;
  512. TCHAR ptcsErrorTitle[iMaxErrorMsgSize];
  513. LoadString(g_hInstance, IDS_STRING_ERROR_TITLE, ptcsErrorTitle, iMaxErrorMsgSize);
  514. LPVOID lpMsgBuf = NULL;
  515. DWORD NumCharsInBuffer;
  516. NumCharsInBuffer = FormatMessage(
  517. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  518. FORMAT_MESSAGE_FROM_SYSTEM |
  519. FORMAT_MESSAGE_IGNORE_INSERTS,
  520. NULL,
  521. dwLastError,
  522. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
  523. (LPTSTR) &lpMsgBuf,
  524. 0,
  525. NULL
  526. );
  527. if(NumCharsInBuffer <= 0)
  528. {
  529. DisplayErrorMessage(NULL, IDS_STRING_ERROR_TITLE, IDS_STRING_ERROR_ERRMSG);
  530. }
  531. else
  532. {
  533. // Process any inserts in lpMsgBuf.
  534. // ...
  535. // Display the string.
  536. MessageBox( hDlg, (TCHAR *)lpMsgBuf, ptcsErrorTitle, MB_OK | MB_ICONERROR );
  537. }
  538. // Free the buffer.
  539. LocalFree( lpMsgBuf );
  540. } // DisplayErrorMessage
  541. ///////////////////////////////////////////////////////////////////////////////
  542. // FUNCTION: OnHelp()
  543. //
  544. // PURPOSE: Process WM_HELP and WM_CONTEXTMENU messages
  545. //
  546. BOOL OnHelp(UINT iDlgID, HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  547. {
  548. BOOL bStatus = TRUE;
  549. switch( uMsg )
  550. {
  551. case WM_HELP:
  552. {
  553. bStatus = WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  554. PORTMONITOR_HELP_FILE,
  555. HELP_WM_HELP,
  556. (ULONG_PTR)g_a110HelpIDs );
  557. }
  558. break;
  559. case WM_CONTEXTMENU:
  560. {
  561. bStatus = WinHelp( (HWND)wParam,
  562. PORTMONITOR_HELP_FILE,
  563. HELP_CONTEXTMENU,
  564. (ULONG_PTR)g_a110HelpIDs );
  565. }
  566. break;
  567. default:
  568. bStatus= FALSE;
  569. break;
  570. }
  571. return bStatus;
  572. } // OnHelp