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.

539 lines
12 KiB

  1. /*++
  2. Copyright (c) 1990-2003 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. config.c
  6. Abstract:
  7. Handles spooler entry points for adding, deleting, and configuring
  8. localui ports.
  9. // @@BEGIN_DDKSPLIT
  10. Environment:
  11. User Mode -Win32
  12. Revision History:
  13. // @@END_DDKSPLIT
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "spltypes.h"
  18. #include "localui.h"
  19. #include "local.h"
  20. #include "lmon.h"
  21. /* From Control Panel's control.h:
  22. */
  23. #define CHILD_PORTS 0
  24. /* From cpl.h:
  25. */
  26. #define CPL_INIT 1
  27. #define CPL_DBLCLK 5
  28. #define CPL_EXIT 7
  29. // @@BEGIN_DDKSPLIT
  30. /* Hack:
  31. */
  32. // @@END_DDKSPLIT
  33. #define CHILD_PORTS_HELPID 0
  34. /* ConfigCOMPort
  35. *
  36. * Calls the Control Panel Ports applet
  37. * to permit user to set Baud rate etc.
  38. */
  39. typedef void (WINAPI *CFGPROC)(HWND, ULONG, ULONG, ULONG);
  40. BOOL
  41. ConfigLPTPort(
  42. HWND hWnd,
  43. HANDLE hXcv
  44. );
  45. BOOL
  46. ConfigCOMPort(
  47. HWND hWnd,
  48. HANDLE hXcv,
  49. PCWSTR pszServer,
  50. PCWSTR pszPortName
  51. );
  52. LPWSTR
  53. GetPortName(
  54. HWND hWnd,
  55. HANDLE hXcv
  56. );
  57. BOOL
  58. AddPortUI(
  59. PCWSTR pszServer,
  60. HWND hWnd,
  61. PCWSTR pszMonitorNameIn,
  62. PWSTR *ppszPortNameOut
  63. )
  64. {
  65. PWSTR pszPortName = NULL;
  66. BOOL rc = TRUE;
  67. WCHAR szLocalMonitor[MAX_PATH+1];
  68. DWORD dwReturn, dwStatus;
  69. DWORD cbNeeded;
  70. PRINTER_DEFAULTS Default;
  71. PWSTR pszServerName = NULL;
  72. HANDLE hXcv = NULL;
  73. DWORD dwLastError = ERROR_SUCCESS;
  74. //
  75. //
  76. //
  77. if (hWnd && !IsWindow (hWnd))
  78. {
  79. //
  80. // Invalid parent window handle causes problems in function with DialogBoxParam call.
  81. // That function when the handle is bad returns ZERO, the same value as ERROR_SUCCEED.
  82. // PortNameDlg function calls EndDialog (ERROR_SUCCEES) if everything is alright.
  83. //
  84. SetLastError (ERROR_INVALID_WINDOW_HANDLE);
  85. if (ppszPortNameOut)
  86. {
  87. *ppszPortNameOut = NULL;
  88. }
  89. return FALSE;
  90. }
  91. //
  92. //
  93. //
  94. /* Get the user to enter a port name:
  95. */
  96. if (!(pszServerName = ConstructXcvName(pszServer, pszMonitorNameIn, L"XcvMonitor"))) {
  97. rc = FALSE;
  98. goto Done;
  99. }
  100. Default.pDatatype = NULL;
  101. Default.pDevMode = NULL;
  102. Default.DesiredAccess = SERVER_ACCESS_ADMINISTER;
  103. if (!(rc = OpenPrinter((PWSTR) pszServerName, &hXcv, &Default))) {
  104. rc = FALSE;
  105. goto Done;
  106. }
  107. if (!(pszPortName = GetPortName(hWnd, hXcv))) {
  108. rc = FALSE;
  109. goto Done;
  110. }
  111. // We can't Add, Configure, or Delete Remote COM ports
  112. if (IS_COM_PORT(pszPortName) || IS_LPT_PORT(pszPortName)) {
  113. SetLastError(ERROR_NOT_SUPPORTED);
  114. rc = FALSE;
  115. goto Done;
  116. }
  117. if(IS_COM_PORT(pszPortName))
  118. CharUpperBuff(pszPortName, 3);
  119. else if(IS_LPT_PORT(pszPortName))
  120. CharUpperBuff(pszPortName, 3);
  121. rc = XcvData( hXcv,
  122. L"AddPort",
  123. (PBYTE) pszPortName,
  124. (wcslen(pszPortName) + 1)*sizeof(WCHAR),
  125. (PBYTE) &dwReturn,
  126. 0,
  127. &cbNeeded,
  128. &dwStatus);
  129. if (rc) {
  130. if(dwStatus == ERROR_SUCCESS) {
  131. if(ppszPortNameOut)
  132. *ppszPortNameOut = AllocSplStr(pszPortName);
  133. if(IS_LPT_PORT(pszPortName))
  134. rc = ConfigLPTPort(hWnd, hXcv);
  135. else if(IS_COM_PORT(pszPortName))
  136. rc = ConfigCOMPort(hWnd, hXcv, pszServer, pszPortName);
  137. } else if (dwStatus == ERROR_ALREADY_EXISTS) {
  138. Message( hWnd, MSG_ERROR, IDS_LOCALMONITOR, IDS_PORTALREADYEXISTS_S, pszPortName );
  139. } else {
  140. SetLastError(dwStatus);
  141. rc = FALSE;
  142. }
  143. }
  144. Done:
  145. dwLastError = GetLastError ();
  146. FreeSplStr(pszPortName);
  147. FreeSplMem(pszServerName);
  148. if (hXcv)
  149. ClosePrinter(hXcv);
  150. SetLastError (dwLastError);
  151. return rc;
  152. }
  153. BOOL
  154. DeletePortUI(
  155. PCWSTR pszServer,
  156. HWND hWnd,
  157. PCWSTR pszPortName
  158. )
  159. {
  160. PRINTER_DEFAULTS Default;
  161. PWSTR pszServerName = NULL;
  162. DWORD dwOutput;
  163. DWORD cbNeeded;
  164. BOOL bRet;
  165. HANDLE hXcv = NULL;
  166. DWORD dwStatus;
  167. DWORD dwLastError = ERROR_SUCCESS;
  168. //
  169. //
  170. //
  171. if (hWnd && !IsWindow (hWnd))
  172. {
  173. SetLastError (ERROR_INVALID_WINDOW_HANDLE);
  174. return FALSE;
  175. }
  176. //
  177. //
  178. //
  179. if (!(pszServerName = ConstructXcvName(pszServer, pszPortName, L"XcvPort"))) {
  180. bRet = FALSE;
  181. goto Done;
  182. }
  183. Default.pDatatype = NULL;
  184. Default.pDevMode = NULL;
  185. Default.DesiredAccess = SERVER_ACCESS_ADMINISTER;
  186. if (!(bRet = OpenPrinter((PWSTR) pszServerName, &hXcv, &Default)))
  187. goto Done;
  188. // Since we can't Add or Configure Remote COM ports, let's not allow deletion either
  189. if (IS_COM_PORT(pszPortName) || IS_LPT_PORT(pszPortName)) {
  190. SetLastError(ERROR_NOT_SUPPORTED);
  191. bRet = FALSE;
  192. } else {
  193. bRet = XcvData( hXcv,
  194. L"DeletePort",
  195. (PBYTE) pszPortName,
  196. (wcslen(pszPortName) + 1)*sizeof(WCHAR),
  197. (PBYTE) &dwOutput,
  198. 0,
  199. &cbNeeded,
  200. &dwStatus);
  201. if (!bRet && (ERROR_BUSY == dwStatus))
  202. {
  203. //
  204. // Port cannot be deleted cause it is in use.
  205. //
  206. ErrorMessage (
  207. hWnd,
  208. dwStatus
  209. );
  210. //
  211. // Error is handled here and caller does not need to do anything
  212. //
  213. SetLastError (ERROR_CANCELLED);
  214. }
  215. else if (bRet && (ERROR_SUCCESS != dwStatus))
  216. {
  217. SetLastError(dwStatus);
  218. bRet = FALSE;
  219. }
  220. }
  221. Done:
  222. dwLastError = GetLastError ();
  223. if (hXcv)
  224. ClosePrinter(hXcv);
  225. FreeSplMem(pszServerName);
  226. SetLastError (dwLastError);
  227. return bRet;
  228. }
  229. /* ConfigurePortUI
  230. *
  231. */
  232. BOOL
  233. ConfigurePortUI(
  234. PCWSTR pName,
  235. HWND hWnd,
  236. PCWSTR pPortName
  237. )
  238. {
  239. BOOL bRet;
  240. PRINTER_DEFAULTS Default;
  241. PWSTR pServerName = NULL;
  242. HANDLE hXcv = NULL;
  243. DWORD dwLastError = ERROR_SUCCESS;
  244. //
  245. //
  246. //
  247. if (hWnd && !IsWindow (hWnd))
  248. {
  249. SetLastError (ERROR_INVALID_WINDOW_HANDLE);
  250. return FALSE;
  251. }
  252. //
  253. //
  254. //
  255. if (!(pServerName = ConstructXcvName(pName, pPortName, L"XcvPort"))) {
  256. bRet = FALSE;
  257. goto Done;
  258. }
  259. Default.pDatatype = NULL;
  260. Default.pDevMode = NULL;
  261. Default.DesiredAccess = SERVER_ACCESS_ADMINISTER;
  262. if (!(bRet = OpenPrinter((PWSTR) pServerName, &hXcv, &Default)))
  263. goto Done;
  264. if( IS_LPT_PORT( (PWSTR) pPortName ) )
  265. bRet = ConfigLPTPort(hWnd, hXcv);
  266. else if( IS_COM_PORT( (PWSTR) pPortName ) )
  267. bRet = ConfigCOMPort(hWnd, hXcv, pName, pPortName);
  268. else {
  269. Message( hWnd, MSG_INFORMATION, IDS_LOCALMONITOR,
  270. IDS_NOTHING_TO_CONFIGURE );
  271. SetLastError(ERROR_CANCELLED);
  272. bRet = FALSE;
  273. }
  274. Done:
  275. dwLastError = GetLastError ();
  276. FreeSplMem(pServerName);
  277. if (hXcv) {
  278. ClosePrinter(hXcv);
  279. hXcv = NULL;
  280. }
  281. SetLastError (dwLastError);
  282. return bRet;
  283. }
  284. /* ConfigLPTPort
  285. *
  286. * Calls a dialog box which prompts the user to enter timeout and retry
  287. * values for the port concerned.
  288. * The dialog writes the information to the registry (win.ini for now).
  289. */
  290. BOOL
  291. ConfigLPTPort(
  292. HWND hWnd,
  293. HANDLE hXcv
  294. )
  295. {
  296. PORTDIALOG Port;
  297. INT iRet;
  298. //
  299. //
  300. ZeroMemory (&Port, sizeof (Port));
  301. iRet = -1;
  302. //
  303. //
  304. Port.hXcv = hXcv;
  305. iRet = (INT)DialogBoxParam(hInst, MAKEINTRESOURCE( DLG_CONFIGURE_LPT ),
  306. hWnd, ConfigureLPTPortDlg, (LPARAM) &Port);
  307. if (iRet == ERROR_SUCCESS)
  308. {
  309. //
  310. // DialogBoxParam returns zero if hWnd is invalid.
  311. // ERROR_SUCCESS is equal to zero.
  312. // => We need to check LastError too.
  313. //
  314. return ERROR_SUCCESS == GetLastError ();
  315. }
  316. if (iRet == -1)
  317. return FALSE;
  318. SetLastError(iRet);
  319. return FALSE;
  320. }
  321. /* ConfigCOMPort
  322. *
  323. */
  324. BOOL
  325. ConfigCOMPort(
  326. HWND hWnd,
  327. HANDLE hXcv,
  328. PCWSTR pszServer,
  329. PCWSTR pszPortName
  330. )
  331. {
  332. DWORD dwStatus;
  333. BOOL bRet = FALSE;
  334. COMMCONFIG CommConfig;
  335. COMMCONFIG *pCommConfig = &CommConfig;
  336. COMMCONFIG *pCC = NULL;
  337. PWSTR pszPort = NULL;
  338. DWORD cbNeeded;
  339. // GetDefaultCommConfig can't handle trailing :, so remove it!
  340. if (!(pszPort = (PWSTR) AllocSplStr(pszPortName)))
  341. goto Done;
  342. pszPort[wcslen(pszPort) - 1] = L'\0';
  343. cbNeeded = sizeof CommConfig;
  344. if (!XcvData( hXcv,
  345. L"GetDefaultCommConfig",
  346. (PBYTE) pszPort,
  347. (wcslen(pszPort) + 1)*sizeof *pszPort,
  348. (PBYTE) pCommConfig,
  349. cbNeeded,
  350. &cbNeeded,
  351. &dwStatus))
  352. goto Done;
  353. if (dwStatus != ERROR_SUCCESS) {
  354. if (dwStatus != ERROR_INSUFFICIENT_BUFFER) {
  355. SetLastError(dwStatus);
  356. goto Done;
  357. }
  358. if (!(pCommConfig = pCC = AllocSplMem(cbNeeded)))
  359. goto Done;
  360. if (!XcvData( hXcv,
  361. L"GetDefaultCommConfig",
  362. (PBYTE) pszPort,
  363. (wcslen(pszPort) + 1)*sizeof *pszPort,
  364. (PBYTE) pCommConfig,
  365. cbNeeded,
  366. &cbNeeded,
  367. &dwStatus))
  368. goto Done;
  369. if (dwStatus != ERROR_SUCCESS) {
  370. SetLastError(dwStatus);
  371. goto Done;
  372. }
  373. }
  374. if (CommConfigDialog(pszPort, hWnd, pCommConfig)) {
  375. if (!XcvData( hXcv,
  376. L"SetDefaultCommConfig",
  377. (PBYTE) pCommConfig,
  378. pCommConfig->dwSize,
  379. (PBYTE) NULL,
  380. 0,
  381. &cbNeeded,
  382. &dwStatus))
  383. goto Done;
  384. if (dwStatus != ERROR_SUCCESS) {
  385. SetLastError(dwStatus);
  386. goto Done;
  387. }
  388. bRet = TRUE;
  389. }
  390. Done:
  391. FreeSplMem(pCC);
  392. FreeSplStr(pszPort);
  393. return bRet;
  394. }
  395. //
  396. // Support routines
  397. //
  398. /* GetPortName
  399. *
  400. * Puts up a dialog containing a free entry field.
  401. * The dialog allocates a string for the name, if a selection is made.
  402. */
  403. LPWSTR
  404. GetPortName(
  405. HWND hWnd,
  406. HANDLE hXcv
  407. )
  408. {
  409. PORTDIALOG Port;
  410. INT Result;
  411. LPWSTR pszPort = NULL;
  412. //
  413. //
  414. ZeroMemory (&Port, sizeof (Port));
  415. Result = -1;
  416. //
  417. //
  418. Port.hXcv = hXcv;
  419. Result = (INT)DialogBoxParam(hInst,
  420. MAKEINTRESOURCE(DLG_PORTNAME),
  421. hWnd,
  422. PortNameDlg,
  423. (LPARAM)&Port);
  424. if (Result == ERROR_SUCCESS)
  425. {
  426. //
  427. // DialogBoxParam returns zero if hWnd is invalid.
  428. // ERROR_SUCCESS is equal to zero.
  429. // => We need to check LastError too.
  430. //
  431. if (ERROR_SUCCESS == GetLastError ())
  432. {
  433. //
  434. // DialogBoxParam executed successfully and a port name was retrieved
  435. //
  436. pszPort = Port.pszPortName;
  437. }
  438. }
  439. else if (Result != -1)
  440. {
  441. //
  442. // DialogBoxParam executed successfully, but the user canceled the dialog
  443. //
  444. SetLastError(Result);
  445. }
  446. return pszPort;
  447. }