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.

609 lines
14 KiB

  1. /*++
  2. Copyright (c) 1990-1994 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. monitor.c
  6. Abstract:
  7. Author:
  8. Environment:
  9. User Mode -Win32
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "local.h"
  15. BOOL
  16. GetPortInfo2UsingPortInfo1(
  17. LPPROVIDOR pProvidor,
  18. LPWSTR pName,
  19. LPBYTE pPorts,
  20. DWORD cbBuf,
  21. LPDWORD pcbNeeded,
  22. LPDWORD pcReturned
  23. )
  24. {
  25. BOOL bRet;
  26. LPPORT_INFO_1 pPortInfo1;
  27. LPPORT_INFO_2 pPortInfo2;
  28. DWORD cReturned;
  29. bRet = (*pProvidor->PrintProvidor.fpEnumPorts) (pName, 1, pPorts, cbBuf,
  30. pcbNeeded, pcReturned);
  31. if ( !bRet ) {
  32. //
  33. // This is the upperbound
  34. //
  35. if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER )
  36. *pcbNeeded += (*pcbNeeded / sizeof(PORT_INFO_1)) *
  37. (sizeof(PORT_INFO_2) - sizeof(PORT_INFO_1));
  38. } else {
  39. *pcbNeeded += *pcReturned * (sizeof(PORT_INFO_2) - sizeof(PORT_INFO_1));
  40. if ( *pcbNeeded <= cbBuf ) {
  41. cReturned = *pcReturned;
  42. while ( cReturned-- ) {
  43. pPortInfo1 = (LPPORT_INFO_1) (pPorts + cReturned * sizeof(PORT_INFO_1));
  44. pPortInfo2 = (LPPORT_INFO_2) (pPorts + cReturned * sizeof(PORT_INFO_2));
  45. pPortInfo2->pPortName = pPortInfo1->pName;
  46. pPortInfo2->pMonitorName = NULL;
  47. pPortInfo2->pDescription = NULL;
  48. pPortInfo2->fPortType = 0;
  49. pPortInfo2->Reserved = 0;
  50. }
  51. } else {
  52. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  53. *pcReturned = 0;
  54. bRet = FALSE;
  55. }
  56. }
  57. return bRet;
  58. }
  59. BOOL
  60. EnumPortsW(
  61. LPWSTR pName,
  62. DWORD Level,
  63. LPBYTE pPort,
  64. DWORD cbBuf,
  65. LPDWORD pcbNeeded,
  66. LPDWORD pcReturned
  67. )
  68. {
  69. DWORD cReturned, TotalcbNeeded;
  70. DWORD Error = ERROR_SUCCESS, TempError = ERROR_SUCCESS;
  71. PROVIDOR *pProvidor;
  72. DWORD BufferSize=cbBuf;
  73. BOOL bPartialSuccess = FALSE;
  74. DWORD rc;
  75. if ((pPort == NULL) && (cbBuf != 0)) {
  76. SetLastError(ERROR_INVALID_USER_BUFFER);
  77. return FALSE;
  78. }
  79. WaitForSpoolerInitialization();
  80. pProvidor = pLocalProvidor;
  81. TotalcbNeeded = cReturned = 0;
  82. while (pProvidor) {
  83. *pcReturned = 0;
  84. *pcbNeeded = 0;
  85. //
  86. // CLS
  87. //
  88. rc = (*pProvidor->PrintProvidor.fpEnumPorts)(pName, Level,
  89. pPort, BufferSize,
  90. pcbNeeded, pcReturned);
  91. if( !rc ){
  92. TempError = GetLastError();
  93. //
  94. // Netware providor returns INVALID_NAME and not INVALID_LEVEL
  95. // So if Level = 2 and error always try a Level 1 query
  96. //
  97. if ( Level == 2 &&
  98. ( TempError == ERROR_INVALID_LEVEL ||
  99. TempError == ERROR_INVALID_NAME) ) {
  100. TempError = ERROR_SUCCESS;
  101. if ( !GetPortInfo2UsingPortInfo1(pProvidor,
  102. pName,
  103. pPort,
  104. BufferSize,
  105. pcbNeeded,
  106. pcReturned) ) {
  107. TempError = GetLastError();
  108. } else {
  109. bPartialSuccess = TRUE;
  110. }
  111. }
  112. //
  113. // HACK FIX:
  114. //
  115. // NT 3.51 returns bogus pcbNeeded/pcReturned data if the
  116. // Level is invalid (i.e., PORT_INFO_2). So we should zero
  117. // these vars if the level is bad, otherwise the error returned
  118. // is ERROR_INSUFFICIENT_BUFFER.
  119. //
  120. if ( TempError ) {
  121. *pcReturned = 0;
  122. Error = TempError;
  123. if ( Error != ERROR_INSUFFICIENT_BUFFER )
  124. *pcbNeeded = 0;
  125. }
  126. } else {
  127. bPartialSuccess = TRUE;
  128. }
  129. cReturned += *pcReturned;
  130. switch (Level) {
  131. case 1:
  132. pPort += *pcReturned * sizeof(PORT_INFO_1);
  133. break;
  134. case 2:
  135. pPort += *pcReturned * sizeof(PORT_INFO_2);
  136. break;
  137. default:
  138. DBGMSG(DBG_ERROR,
  139. ("EnumPortsW: invalid level %d", Level));
  140. SetLastError(ERROR_INVALID_LEVEL);
  141. return FALSE;
  142. }
  143. if (*pcbNeeded <= BufferSize)
  144. BufferSize -= *pcbNeeded;
  145. else
  146. BufferSize = 0;
  147. TotalcbNeeded += *pcbNeeded;
  148. //
  149. // CLS
  150. //
  151. // Stop routing if the provider tells us to.
  152. //
  153. if( rc == ROUTER_STOP_ROUTING ){
  154. break;
  155. }
  156. pProvidor = pProvidor->pNext;
  157. }
  158. *pcbNeeded = TotalcbNeeded;
  159. *pcReturned = cReturned;
  160. if (TotalcbNeeded > cbBuf) {
  161. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  162. return FALSE;
  163. } else if (bPartialSuccess) {
  164. SetLastError(ERROR_SUCCESS);
  165. } else if (Error != ERROR_SUCCESS) {
  166. SetLastError(Error);
  167. return FALSE;
  168. }
  169. return TRUE;
  170. }
  171. BOOL
  172. EnumMonitorsW(
  173. LPWSTR pName,
  174. DWORD Level,
  175. LPBYTE pMonitor,
  176. DWORD cbBuf,
  177. LPDWORD pcbNeeded,
  178. LPDWORD pcReturned
  179. )
  180. {
  181. DWORD cReturned, cbStruct, TotalcbNeeded;
  182. DWORD Error;
  183. PROVIDOR *pProvidor;
  184. DWORD BufferSize=cbBuf;
  185. BOOL bPartialSuccess = FALSE;
  186. DWORD rc;
  187. if ((pMonitor == NULL) && (cbBuf != 0)) {
  188. SetLastError(ERROR_INVALID_USER_BUFFER);
  189. return FALSE;
  190. }
  191. WaitForSpoolerInitialization();
  192. switch (Level) {
  193. case 1:
  194. cbStruct = sizeof(MONITOR_INFO_1);
  195. break;
  196. case 2:
  197. cbStruct = sizeof(MONITOR_INFO_2);
  198. break;
  199. default:
  200. DBGMSG(DBG_ERROR,
  201. ("EnumMonitorsW: invalid level %d", Level));
  202. SetLastError(ERROR_INVALID_LEVEL);
  203. return FALSE;
  204. }
  205. pProvidor = pLocalProvidor;
  206. TotalcbNeeded = cReturned = 0;
  207. Error = ERROR_SUCCESS;
  208. while (pProvidor) {
  209. *pcReturned = 0;
  210. *pcbNeeded = 0;
  211. rc = (*pProvidor->PrintProvidor.fpEnumMonitors) (pName,
  212. Level,
  213. pMonitor,
  214. BufferSize,
  215. pcbNeeded,
  216. pcReturned);
  217. cReturned += *pcReturned;
  218. pMonitor += *pcReturned * cbStruct;
  219. if (*pcbNeeded <= BufferSize)
  220. BufferSize -= *pcbNeeded;
  221. else
  222. BufferSize = 0;
  223. TotalcbNeeded += *pcbNeeded;
  224. if( rc == ROUTER_UNKNOWN ){
  225. Error = GetLastError();
  226. } else {
  227. bPartialSuccess = TRUE;
  228. if( rc == ROUTER_STOP_ROUTING ){
  229. break;
  230. }
  231. }
  232. pProvidor = pProvidor->pNext;
  233. }
  234. *pcbNeeded = TotalcbNeeded;
  235. *pcReturned = cReturned;
  236. if (TotalcbNeeded > cbBuf) {
  237. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  238. return FALSE;
  239. } else if (bPartialSuccess) {
  240. SetLastError(ERROR_SUCCESS);
  241. } else if (Error != ERROR_SUCCESS) {
  242. SetLastError(Error);
  243. return FALSE;
  244. }
  245. return TRUE;
  246. }
  247. BOOL
  248. AddPortExW(
  249. LPWSTR pName,
  250. DWORD Level,
  251. LPBYTE pBuffer,
  252. LPWSTR pMonitorName
  253. )
  254. {
  255. LPPROVIDOR pProvidor;
  256. WaitForSpoolerInitialization();
  257. pProvidor = pLocalProvidor;
  258. while (pProvidor) {
  259. if (pProvidor->PrintProvidor.fpAddPortEx) {
  260. if ((*pProvidor->PrintProvidor.fpAddPortEx) (pName, Level, pBuffer, pMonitorName)) {
  261. return TRUE;
  262. }
  263. }
  264. pProvidor = pProvidor->pNext;
  265. }
  266. SetLastError(ERROR_INVALID_PARAMETER);
  267. return FALSE;
  268. }
  269. BOOL
  270. AddPortW(
  271. LPWSTR pName,
  272. HWND hWnd,
  273. LPWSTR pMonitorName
  274. )
  275. {
  276. LPPROVIDOR pProvidor;
  277. DWORD Error = NO_ERROR;
  278. WaitForSpoolerInitialization();
  279. pProvidor = pLocalProvidor;
  280. while (pProvidor) {
  281. if (!pProvidor->PrintProvidor.fpAddPort)
  282. break;
  283. if ((*pProvidor->PrintProvidor.fpAddPort)(pName, hWnd, pMonitorName)) {
  284. return TRUE;
  285. } else {
  286. DWORD LastError = GetLastError();
  287. /* If the function is not supported, don't return yet
  288. * in case there's a print provider that does support it.
  289. */
  290. if (LastError == ERROR_NOT_SUPPORTED)
  291. Error = ERROR_NOT_SUPPORTED;
  292. else if (LastError != ERROR_INVALID_NAME)
  293. return FALSE;
  294. }
  295. pProvidor = pProvidor->pNext;
  296. }
  297. SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
  298. return FALSE;
  299. }
  300. BOOL
  301. ConfigurePortW(
  302. LPWSTR pName,
  303. HWND hWnd,
  304. LPWSTR pPortName
  305. )
  306. {
  307. LPPROVIDOR pProvidor;
  308. DWORD Error = NO_ERROR;
  309. WaitForSpoolerInitialization();
  310. pProvidor = pLocalProvidor;
  311. while (pProvidor) {
  312. if (!pProvidor->PrintProvidor.fpConfigurePort)
  313. break;
  314. if ((*pProvidor->PrintProvidor.fpConfigurePort) (pName, hWnd, pPortName)) {
  315. return TRUE;
  316. } else {
  317. DWORD LastError = GetLastError();
  318. /* If the function is not supported, don't return yet
  319. * in case there's a print provider that does support it.
  320. */
  321. if (LastError == ERROR_NOT_SUPPORTED)
  322. Error = ERROR_NOT_SUPPORTED;
  323. else if ((LastError != ERROR_INVALID_NAME) && (LastError != ERROR_UNKNOWN_PORT))
  324. return FALSE;
  325. }
  326. pProvidor = pProvidor->pNext;
  327. }
  328. SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
  329. return FALSE;
  330. }
  331. BOOL
  332. DeletePortW(
  333. LPWSTR pName,
  334. HWND hWnd,
  335. LPWSTR pPortName
  336. )
  337. {
  338. LPPROVIDOR pProvidor;
  339. DWORD Error = NO_ERROR;
  340. WaitForSpoolerInitialization();
  341. pProvidor = pLocalProvidor;
  342. while (pProvidor) {
  343. if (!pProvidor->PrintProvidor.fpDeletePort)
  344. break;
  345. if ((*pProvidor->PrintProvidor.fpDeletePort) (pName, hWnd, pPortName)) {
  346. return TRUE;
  347. } else {
  348. DWORD LastError = GetLastError();
  349. /* If the function is not supported, don't return yet
  350. * in case there's a print provider that does support it.
  351. */
  352. if (LastError == ERROR_NOT_SUPPORTED)
  353. Error = ERROR_NOT_SUPPORTED;
  354. else if ((LastError != ERROR_INVALID_NAME) && (LastError != ERROR_UNKNOWN_PORT))
  355. return FALSE;
  356. }
  357. pProvidor = pProvidor->pNext;
  358. }
  359. SetLastError(Error == NO_ERROR ? ERROR_INVALID_PARAMETER : Error);
  360. return FALSE;
  361. }
  362. BOOL
  363. AddMonitorW(
  364. LPWSTR pName,
  365. DWORD Level,
  366. LPBYTE pMonitorInfo
  367. )
  368. {
  369. LPPROVIDOR pProvidor;
  370. WaitForSpoolerInitialization();
  371. pProvidor = pLocalProvidor;
  372. while (pProvidor) {
  373. if ((*pProvidor->PrintProvidor.fpAddMonitor) (pName, Level, pMonitorInfo)) {
  374. return TRUE;
  375. } else if (GetLastError() != ERROR_INVALID_NAME) {
  376. return FALSE;
  377. }
  378. pProvidor = pProvidor->pNext;
  379. }
  380. SetLastError(ERROR_INVALID_PARAMETER);
  381. return FALSE;
  382. }
  383. BOOL
  384. DeleteMonitorW(
  385. LPWSTR pName,
  386. LPWSTR pEnvironment,
  387. LPWSTR pMonitorName
  388. )
  389. {
  390. LPPROVIDOR pProvidor;
  391. DWORD Error;
  392. WaitForSpoolerInitialization();
  393. if (!pEnvironment || !*pEnvironment)
  394. pEnvironment = szEnvironment;
  395. pProvidor = pLocalProvidor;
  396. while (pProvidor) {
  397. if ((*pProvidor->PrintProvidor.fpDeleteMonitor)
  398. (pName, pEnvironment, pMonitorName)) {
  399. return TRUE;
  400. } else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
  401. return FALSE;
  402. }
  403. pProvidor = pProvidor->pNext;
  404. }
  405. return FALSE;
  406. }
  407. BOOL
  408. SetPortW(
  409. LPWSTR pszName,
  410. LPWSTR pszPortName,
  411. DWORD dwLevel,
  412. LPBYTE pPortInfo
  413. )
  414. {
  415. LPPROVIDOR pProvidor;
  416. DWORD dwLastError;
  417. WaitForSpoolerInitialization();
  418. pProvidor = pLocalProvidor;
  419. while (pProvidor) {
  420. if ( (*pProvidor->PrintProvidor.fpSetPort)(pszName,
  421. pszPortName,
  422. dwLevel,
  423. pPortInfo) ) {
  424. return TRUE;
  425. }
  426. dwLastError = GetLastError();
  427. if ( dwLastError != ERROR_INVALID_NAME &&
  428. dwLastError != ERROR_UNKNOWN_PORT &&
  429. dwLastError != ERROR_NOT_SUPPORTED ) {
  430. return FALSE;
  431. }
  432. pProvidor = pProvidor->pNext;
  433. }
  434. return FALSE;
  435. }