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.

919 lines
21 KiB

  1. /*****************************************************************************\
  2. * MODULE: inetport.cxx
  3. *
  4. * The module contains routines for handling the INETPP functionality. Use
  5. * of these routines require the locking/unlocking of a critical-section
  6. * to maninpulate the INIMONPORT list. All internal routines assume the
  7. * crit-sect is locked prior to executing. CheckMonCrit() is a debugging
  8. * call to verify the monitor-crit-sect is locked.
  9. *
  10. * NOTE: Each of the Inetmon*, InetMonPort calls must be protected by the
  11. * global-crit-sect.
  12. * If a new routine is added to this module which is to be called from
  13. * another module, be sure to include the call to (semCheckCrit), so
  14. * that the debug-code can catch unprotected access.
  15. *
  16. * Copyright (C) 1996-1997 Microsoft Corporation
  17. * Copyright (C) 1996-1997 Hewlett Packard
  18. *
  19. * History:
  20. * 07-Oct-1996 HWP-Guys Initiated port from win95 to winNT
  21. * 14-Nov-1997 ChrisWil Added local-spooling functionality.
  22. * 10-Jul-1998 WeihaiC Change Authentication Dialog Code
  23. *
  24. \*****************************************************************************/
  25. #include "precomp.h"
  26. #include "priv.h"
  27. CInetMonPort::CInetMonPort (
  28. LPCTSTR lpszPortName,
  29. LPCTSTR lpszDevDesc,
  30. PCPORTMGR pPortMgr):
  31. m_bValid (FALSE),
  32. m_pNext (NULL),
  33. m_cRef (0),
  34. m_cPrinterRef (0),
  35. m_bDeletePending (FALSE),
  36. m_lpszHost (NULL),
  37. m_lpszShare (NULL),
  38. m_pPortMgr (pPortMgr),
  39. m_pGetPrinterCache (NULL),
  40. m_pEnumJobsCache (NULL),
  41. m_bCheckConnection (TRUE),
  42. m_hTerminateEvent (NULL),
  43. m_pjmList (NULL)
  44. {
  45. PCINETMONPORT pIniPort;
  46. PCINETMONPORT pPort;
  47. LPTSTR lpszHost;
  48. LPTSTR lpszShare;
  49. INTERNET_PORT iPort;
  50. BOOL bSecure;
  51. // Parse out the host/share. This call returns allocated
  52. // string-buffers. It is our responsibility to free the
  53. // memory once we're done with it.
  54. //
  55. if (utlParseHostShare(lpszPortName, &lpszHost, &lpszShare, &iPort, &bSecure)) {
  56. // The (lpszDevDesc) could be NULL only if it's PP_REMOTE.
  57. //
  58. if (lpszDevDesc && *lpszDevDesc)
  59. m_lpszDesc = memAllocStr(lpszDevDesc);
  60. else
  61. m_lpszDesc = memAllocStr(lpszPortName);
  62. m_lpszName = memAllocStr (lpszPortName);
  63. // If succeeded, then continue to initialize the port.
  64. //
  65. if (m_lpszDesc && m_lpszName) {
  66. // Initialize the port-elements.
  67. //
  68. m_lpszHost = lpszHost;
  69. m_lpszShare = lpszShare;
  70. DBG_MSG(DBG_LEV_INFO, (TEXT("Info: _inet_create_port: Host(%s) Share(%s)"), lpszHost, lpszShare));
  71. m_pGetPrinterCache = new GetPrinterCache (this);
  72. m_pEnumJobsCache = new EnumJobsCache (this);
  73. if (m_pGetPrinterCache && m_pEnumJobsCache && m_pGetPrinterCache->bValid() && m_pEnumJobsCache->bValid ()) {
  74. m_bValid = TRUE;
  75. }
  76. }
  77. }
  78. }
  79. CInetMonPort::~CInetMonPort ()
  80. {
  81. FreeGetPrinterCache ();
  82. FreeEnumJobsCache ();
  83. // Free the entry and all memory allocated on
  84. // behalf of the entry.
  85. //
  86. memFreeStr(m_lpszDesc);
  87. memFreeStr(m_lpszHost);
  88. memFreeStr(m_lpszShare);
  89. // Remove any job-entries.
  90. //
  91. pjmDelList(m_pjmList);
  92. m_pPortMgr->Remove ();
  93. delete m_pPortMgr;
  94. if (m_hTerminateEvent)
  95. CloseHandle (m_hTerminateEvent);
  96. }
  97. VOID
  98. CInetMonPort::IncRef ()
  99. {
  100. m_cRef++;
  101. }
  102. VOID
  103. CInetMonPort::DecRef ()
  104. {
  105. m_cRef--;
  106. }
  107. VOID
  108. CInetMonPort::IncPrinterRef ()
  109. {
  110. m_cPrinterRef++;
  111. }
  112. VOID
  113. CInetMonPort::DecPrinterRef ()
  114. {
  115. m_cPrinterRef--;
  116. }
  117. /*****************************************************************************\
  118. * _inet_size_entry (Local Routine)
  119. *
  120. * Returns the size of an entry depending upon the print-level.
  121. *
  122. \*****************************************************************************/
  123. DWORD
  124. CInetMonPort::_inet_size_entry(
  125. DWORD dwLevel)
  126. {
  127. DWORD cb;
  128. switch (dwLevel) {
  129. case PRINT_LEVEL_1:
  130. cb = sizeof(PORT_INFO_1) + utlStrSize(m_lpszName);
  131. break;
  132. case PRINT_LEVEL_2:
  133. cb = sizeof(PORT_INFO_2) +
  134. utlStrSize(m_lpszName) +
  135. utlStrSize(m_lpszDesc) +
  136. utlStrSize(g_szLocalPort);
  137. break;
  138. default:
  139. cb = 0;
  140. break;
  141. }
  142. return cb;
  143. }
  144. /*****************************************************************************\
  145. * _inet_copy_entry (Local Routine)
  146. *
  147. * Returns a copy of the port-entry.
  148. *
  149. \*****************************************************************************/
  150. LPBYTE
  151. CInetMonPort::_inet_copy_entry(
  152. DWORD dwLevel,
  153. LPBYTE pPortInfo,
  154. LPBYTE pEnd)
  155. {
  156. LPTSTR SourceStrings[sizeof(PORT_INFO_2) / sizeof(LPTSTR)];
  157. LPTSTR *pSourceStrings=SourceStrings;
  158. DWORD *pOffsets;
  159. static DWORD s_dwPortInfo1Strings[] = {
  160. offsetof(LPPORT_INFO_1A, pName),
  161. 0xFFFFFFFF
  162. };
  163. static DWORD s_dwPortInfo2Strings[] = {
  164. offsetof(LPPORT_INFO_2A, pPortName),
  165. offsetof(LPPORT_INFO_2A, pMonitorName),
  166. offsetof(LPPORT_INFO_2A, pDescription),
  167. 0xFFFFFFFF
  168. };
  169. //
  170. //
  171. switch (dwLevel) {
  172. case PORT_LEVEL_1:
  173. pOffsets = s_dwPortInfo1Strings;
  174. break;
  175. case PORT_LEVEL_2:
  176. pOffsets = s_dwPortInfo2Strings;
  177. break;
  178. default:
  179. return pEnd;
  180. }
  181. //
  182. //
  183. switch (dwLevel) {
  184. case PORT_LEVEL_1:
  185. *pSourceStrings++ = m_lpszName;
  186. pEnd = utlPackStrings(SourceStrings, pPortInfo, pOffsets, pEnd);
  187. break;
  188. case PORT_LEVEL_2:
  189. *pSourceStrings++ = (LPTSTR)m_lpszName;
  190. *pSourceStrings++ = (LPTSTR)g_szLocalPort;
  191. *pSourceStrings++ = (LPTSTR)m_lpszDesc;
  192. #if 0
  193. ((PPORT_INFO_2)pPortInfo)->fPortType = PORT_TYPE_WRITE | PORT_TYPE_NET_ATTACHED;
  194. #else
  195. ((PPORT_INFO_2)pPortInfo)->fPortType = PORT_TYPE_WRITE | PORT_TYPE_REDIRECTED;
  196. #endif
  197. ((PPORT_INFO_2)pPortInfo)->Reserved = 0;
  198. pEnd = utlPackStrings(SourceStrings, pPortInfo, pOffsets, pEnd);
  199. break;
  200. }
  201. return pEnd;
  202. }
  203. /*****************************************************************************\
  204. * _inet_req_jobstart (Local Routine)
  205. *
  206. * Performs the job-start request. This writes out the header info to the
  207. * spool-job.
  208. *
  209. \*****************************************************************************/
  210. BOOL
  211. CInetMonPort::_inet_req_jobstart(
  212. PIPPREQ_PRTJOB ppj,
  213. PJOBMAP pjmJob)
  214. {
  215. LPBYTE lpIppHdr;
  216. REQINFO ri;
  217. DWORD cbIppHdr;
  218. DWORD dwRet;
  219. DWORD cbWr;
  220. BOOL bRet = FALSE;
  221. // Convert the IPPREQ_PRTJOB to a IPP-stream-header.
  222. //
  223. ZeroMemory(&ri, sizeof(REQINFO));
  224. ri.cpReq = CP_UTF8;
  225. ri.idReq = IPP_REQ_PRINTJOB;
  226. ri.fReq[0] = IPP_REQALL;
  227. ri.fReq[1] = IPP_REQALL;
  228. dwRet = WebIppSndData(IPP_REQ_PRINTJOB,
  229. &ri,
  230. (LPBYTE)ppj,
  231. ppj->cbSize,
  232. &lpIppHdr,
  233. &cbIppHdr);
  234. if (dwRet == WEBIPP_OK) {
  235. bRet = pjmSplWrite(pjmJob, lpIppHdr, cbIppHdr, &cbWr);
  236. WebIppFreeMem(lpIppHdr);
  237. }
  238. return bRet;
  239. }
  240. /*****************************************************************************\
  241. * _inet_IppPrtRsp (Local Routine)
  242. *
  243. * Retrieves a get response from the IPP server.
  244. *
  245. \*****************************************************************************/
  246. BOOL CALLBACK _inet_IppPrtRsp(
  247. CAnyConnection *pConnection,
  248. HINTERNET hJobReq,
  249. PCINETMONPORT pIniPort,
  250. PJOBMAP pjmJob)
  251. {
  252. HANDLE hIpp;
  253. DWORD dwRet;
  254. DWORD cbRd;
  255. LPBYTE lpDta;
  256. DWORD cbDta;
  257. LPIPPRET_JOB lpRsp;
  258. DWORD cbRsp;
  259. BYTE bBuf[MAX_IPP_BUFFER];
  260. BOOL bRet = FALSE;
  261. if (hIpp = WebIppRcvOpen(IPP_RET_PRINTJOB)) {
  262. while (TRUE) {
  263. cbRd = 0;
  264. if (pIniPort->ReadFile (pConnection, hJobReq, (LPVOID)bBuf, sizeof(bBuf), &cbRd) && cbRd) {
  265. dwRet = WebIppRcvData(hIpp, bBuf, cbRd, (LPBYTE*)&lpRsp, &cbRsp, &lpDta, &cbDta);
  266. switch (dwRet) {
  267. case WEBIPP_OK:
  268. if (bRet = lpRsp->bRet) {
  269. // Set the remote-job-id to the job-entry. This
  270. // entry was added at the time the spool-job-file
  271. // was created.
  272. //
  273. semEnterCrit();
  274. pjmSetJobRemote(pjmJob, lpRsp->ji.ji2.JobId, lpRsp->ji.ipp.pJobUri);
  275. semLeaveCrit();
  276. } else {
  277. // If the job failed to open on the server, then
  278. // we will set the last-error from the server
  279. // response.
  280. //
  281. SetLastError(lpRsp->dwLastError);
  282. }
  283. WebIppFreeMem(lpRsp);
  284. goto EndPrtRsp;
  285. case WEBIPP_MOREDATA:
  286. // Need to do another read to fullfill our header-response.
  287. //
  288. break;
  289. default:
  290. DBG_MSG(DBG_LEV_ERROR, (TEXT("_inet_IppPrtRsp - Err : Receive Data Error (dwRet=%d, LE=%d)"),
  291. dwRet, WebIppGetError(hIpp)));
  292. SetLastError(ERROR_INVALID_DATA);
  293. goto EndPrtRsp;
  294. }
  295. } else {
  296. goto EndPrtRsp;
  297. }
  298. }
  299. EndPrtRsp:
  300. WebIppRcvClose(hIpp);
  301. } else {
  302. SetLastError(ERROR_OUTOFMEMORY);
  303. }
  304. return bRet;
  305. }
  306. /*****************************************************************************\
  307. * InetmonSendReq
  308. *
  309. *
  310. \*****************************************************************************/
  311. BOOL
  312. CInetMonPort::SendReq(
  313. LPBYTE lpIpp,
  314. DWORD cbIpp,
  315. IPPRSPPROC pfnRsp,
  316. LPARAM lParam,
  317. BOOL bLeaveCrit)
  318. {
  319. BOOL bRet = FALSE;
  320. CMemStream *pStream;
  321. pStream = new CMemStream (lpIpp, cbIpp);
  322. if (pStream && pStream->bValid ()){
  323. bRet = SendReq (pStream, pfnRsp, lParam, bLeaveCrit);
  324. }
  325. if (pStream) {
  326. delete pStream;
  327. }
  328. return bRet;
  329. }
  330. BOOL
  331. CInetMonPort::SendReq(
  332. CStream *pStream,
  333. IPPRSPPROC pfnRsp,
  334. LPARAM lParam,
  335. BOOL bLeaveCrit)
  336. {
  337. DWORD dwLE = ERROR_SUCCESS;
  338. BOOL bRet = FALSE;
  339. semCheckCrit();
  340. if (bLeaveCrit)
  341. //
  342. // We must increaset the port ref count to make sure the
  343. // port is not deleted.
  344. //
  345. semSafeLeaveCrit(this);
  346. bRet = m_pPortMgr->SendRequest (this, pStream, pfnRsp, lParam);
  347. dwLE = GetLastError();
  348. if (bLeaveCrit)
  349. semSafeEnterCrit(this);
  350. if (!bRet) {
  351. // Need to check connection next time
  352. m_bCheckConnection = TRUE;
  353. }
  354. if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS))
  355. SetLastError(dwLE);
  356. return bRet;
  357. }
  358. /*****************************************************************************\
  359. * InetmonClosePort
  360. *
  361. * Close the internet connection.
  362. *
  363. \*****************************************************************************/
  364. BOOL
  365. CInetMonPort::ClosePort(
  366. HANDLE hPrinter)
  367. {
  368. CLogonUserData* pUser = NULL;
  369. semCheckCrit();
  370. // Now see if this is the last port handle that a user is closing
  371. if (hPrinter != NULL) { // This means we couldn't create the printer handle and
  372. // had to close the port
  373. pUser = m_pPortMgr->GetUserIfLastDecRef (((LPINET_HPRINTER)hPrinter)->hUser);
  374. if (pUser) {
  375. // We need to stop the Cache Manager thread if the same user owns it
  376. DBG_MSG(DBG_LEV_INFO, (TEXT("Info: Last User Close Printer %p."), pUser));
  377. InvalidateGetPrinterCacheForUser(pUser );
  378. InvalidateEnumJobsCacheForUser(pUser );
  379. semLeaveCrit ();
  380. //
  381. // In some cases, wininet takes a long time to clean up the
  382. // browser session, so we have to leave the CS when making
  383. // InternetSetOption calls to wininet
  384. //
  385. EndBrowserSession ();
  386. semEnterCrit ();
  387. delete ( pUser );
  388. }
  389. }
  390. //
  391. // We stop decrease the ref count since we don't increase the
  392. // refcount at Open
  393. //
  394. DecPrinterRef();
  395. return TRUE;
  396. }
  397. /*****************************************************************************\
  398. * InetmonStartDocPort
  399. *
  400. * Start the beginning of a StartDoc call.
  401. *
  402. \*****************************************************************************/
  403. BOOL
  404. CInetMonPort::StartDocPort(
  405. DWORD dwLevel,
  406. LPBYTE pDocInfo,
  407. PJOBMAP pjmJob)
  408. {
  409. LPTSTR lpszUser;
  410. PIPPREQ_PRTJOB ppj;
  411. BOOL bRet = FALSE;
  412. DWORD dwLE;
  413. semCheckCrit();
  414. // We are going to hit the network, so leave the critical section
  415. // To make sure the port will not be deleted, we increase the
  416. // ref count
  417. //
  418. semSafeLeaveCrit(this);
  419. bRet = m_pPortMgr->CheckConnection();
  420. dwLE = GetLastError();
  421. semSafeEnterCrit(this);
  422. if (bRet) {
  423. // Reset the value
  424. bRet = FALSE;
  425. // Get the username.
  426. //
  427. if (lpszUser = GetUserName()) {
  428. // Build a IPP_PRTJOB_REQ struct. This routine assures that
  429. // all strings are in Ascii format.
  430. //
  431. ppj = WebIppCreatePrtJobReq(FALSE,
  432. lpszUser,
  433. ((PDOC_INFO_2)pDocInfo)->pDocName,
  434. m_lpszName);
  435. if (ppj) {
  436. // Start the job. This writes out header info to the
  437. // spool-file.
  438. //
  439. bRet = _inet_req_jobstart(ppj, pjmJob);
  440. WebIppFreeMem(ppj);
  441. }
  442. memFreeStr(lpszUser);
  443. }
  444. } else {
  445. m_bCheckConnection = FALSE;
  446. SetLastError (dwLE);
  447. }
  448. if (bRet == FALSE) {
  449. DBG_MSG(DBG_LEV_ERROR, (TEXT("Err : InetmonStartDocPort: Failed %d"), GetLastError()));
  450. }
  451. return bRet;
  452. }
  453. /*****************************************************************************\
  454. * InetmonEndDocPort
  455. *
  456. * Signify the end of writing to a port. This is called after StartDocPort.
  457. *
  458. \*****************************************************************************/
  459. BOOL
  460. CInetMonPort::EndDocPort(
  461. PJOBMAP pjmJob)
  462. {
  463. BOOL bRet = FALSE;
  464. CFileStream *pStream = NULL;
  465. semCheckCrit();
  466. if (pStream = pjmSplLock(pjmJob)) {
  467. bRet = SendReq(pStream, (IPPRSPPROC)_inet_IppPrtRsp, (LPARAM)pjmJob, TRUE);
  468. pjmSplUnlock(pjmJob);
  469. }
  470. return bRet;
  471. }
  472. /*****************************************************************************\
  473. * InetmonWritePort
  474. *
  475. * Write bytes to the port. This goes to the spool-file until the
  476. * InetmonEndDocPort() is called.
  477. *
  478. \*****************************************************************************/
  479. BOOL
  480. CInetMonPort::WritePort(
  481. PJOBMAP pjmJob,
  482. LPBYTE lpData,
  483. DWORD cbData,
  484. LPDWORD pcbWr)
  485. {
  486. BOOL bRet;
  487. semCheckCrit();
  488. bRet = pjmSplWrite(pjmJob, lpData, cbData, pcbWr);
  489. return bRet;
  490. }
  491. /*****************************************************************************\
  492. * InetmonAbortPort
  493. *
  494. * Aborts our print-spooling process.
  495. *
  496. \*****************************************************************************/
  497. BOOL
  498. CInetMonPort::AbortPort(
  499. PJOBMAP pjmJob)
  500. {
  501. semCheckCrit();
  502. return TRUE; //(_inet_validate_port(hPort) ? TRUE : FALSE);
  503. }
  504. /*****************************************************************************\
  505. * InetmonGetPortName
  506. *
  507. * Return the name of the port.
  508. *
  509. \*****************************************************************************/
  510. LPCTSTR
  511. CInetMonPort::GetPortName(
  512. VOID)
  513. {
  514. LPCTSTR lpszName = NULL;
  515. semCheckCrit();
  516. lpszName = (LPCTSTR)m_lpszName;
  517. return lpszName;
  518. }
  519. /*****************************************************************************\
  520. * InetmonGetPJMList
  521. *
  522. *
  523. \*****************************************************************************/
  524. PJOBMAP*
  525. CInetMonPort::GetPJMList(
  526. VOID)
  527. {
  528. PJOBMAP* ppjmList = NULL;
  529. semCheckCrit();
  530. ppjmList = &m_pjmList;
  531. return ppjmList;
  532. }
  533. /*****************************************************************************\
  534. * InetmonIncUserRefCount
  535. *
  536. * Increases the reference count on the port for the given user
  537. *
  538. \*****************************************************************************/
  539. DWORD
  540. CInetMonPort::IncUserRefCount(
  541. PCLOGON_USERDATA hUser )
  542. {
  543. DWORD dwRet = (DWORD) -1;
  544. dwRet = m_pPortMgr->IncreaseUserRefCount (hUser);
  545. return dwRet;
  546. }
  547. VOID
  548. CInetMonPort::FreeGetPrinterCache (
  549. VOID)
  550. {
  551. if (m_pGetPrinterCache) {
  552. semLeaveCrit ();
  553. m_pGetPrinterCache->Shutdown ();
  554. semEnterCrit ();
  555. }
  556. }
  557. BOOL
  558. CInetMonPort::BeginReadGetPrinterCache (
  559. PPRINTER_INFO_2 *ppInfo2)
  560. {
  561. BOOL bRet = FALSE;
  562. if (m_pGetPrinterCache) {
  563. semLeaveCrit ();
  564. bRet = m_pGetPrinterCache->BeginReadCache (ppInfo2);
  565. semEnterCrit ();
  566. }
  567. return bRet;
  568. }
  569. VOID
  570. CInetMonPort::EndReadGetPrinterCache (
  571. VOID)
  572. {
  573. if (m_pGetPrinterCache) {
  574. m_pGetPrinterCache->EndReadCache ();
  575. }
  576. }
  577. VOID
  578. CInetMonPort::InvalidateGetPrinterCache (
  579. VOID)
  580. {
  581. if (m_pGetPrinterCache) {
  582. semLeaveCrit ();
  583. m_pGetPrinterCache->InvalidateCache ();
  584. semEnterCrit ();
  585. }
  586. }
  587. VOID
  588. CInetMonPort::InvalidateGetPrinterCacheForUser(
  589. HANDLE hUser)
  590. /*++
  591. Routine Description:
  592. Close the cache if the current user is currently controlling it.
  593. Arguments:
  594. hUser - The user for which we want to close the cache
  595. Return Value:
  596. None.
  597. --*/
  598. {
  599. CLogonUserData *pUser = (CLogonUserData *)hUser;
  600. if (m_pGetPrinterCache && pUser) {
  601. semLeaveCrit ();
  602. m_pGetPrinterCache->InvalidateCacheForUser (pUser);
  603. semEnterCrit ();
  604. }
  605. }
  606. VOID
  607. CInetMonPort::FreeEnumJobsCache (
  608. VOID)
  609. {
  610. semLeaveCrit ();
  611. m_pEnumJobsCache->Shutdown ();
  612. semEnterCrit ();
  613. }
  614. BOOL
  615. CInetMonPort::BeginReadEnumJobsCache (
  616. LPPPJOB_ENUM *ppje)
  617. {
  618. BOOL bRet = FALSE;
  619. if (m_pEnumJobsCache) {
  620. semLeaveCrit ();
  621. bRet = m_pEnumJobsCache->BeginReadCache(ppje);
  622. semEnterCrit ();
  623. }
  624. return bRet;
  625. }
  626. VOID
  627. CInetMonPort::EndReadEnumJobsCache (
  628. VOID)
  629. {
  630. if (m_pEnumJobsCache) {
  631. m_pEnumJobsCache->EndReadCache();
  632. }
  633. }
  634. VOID
  635. CInetMonPort::InvalidateEnumJobsCache (
  636. VOID)
  637. {
  638. if (m_pEnumJobsCache) {
  639. semLeaveCrit ();
  640. m_pEnumJobsCache->InvalidateCache ();
  641. semEnterCrit ();
  642. }
  643. }
  644. VOID
  645. CInetMonPort::InvalidateEnumJobsCacheForUser(
  646. HANDLE hUser)
  647. /*++
  648. Routine Description:
  649. Close the cache if the current user is currently controlling it.
  650. Arguments:
  651. hUser - The user for which we want to close the cache
  652. Return Value:
  653. None.
  654. --*/
  655. {
  656. if (m_pEnumJobsCache && hUser) {
  657. semLeaveCrit ();
  658. m_pEnumJobsCache->InvalidateCacheForUser ((CLogonUserData *)hUser);
  659. semEnterCrit ();
  660. }
  661. }
  662. BOOL
  663. CInetMonPort::ReadFile (
  664. CAnyConnection *pConnection,
  665. HINTERNET hReq,
  666. LPVOID lpvBuffer,
  667. DWORD cbBuffer,
  668. LPDWORD lpcbRd)
  669. {
  670. return m_pPortMgr->ReadFile (pConnection, hReq, lpvBuffer, cbBuffer, lpcbRd);
  671. }
  672. BOOL
  673. CInetMonPort::GetCurrentConfiguration (
  674. PINET_XCV_CONFIGURATION pXcvConfiguration)
  675. {
  676. return m_pPortMgr->GetCurrentConfiguration(pXcvConfiguration);
  677. }
  678. BOOL
  679. CInetMonPort::ConfigurePort (
  680. PINET_XCV_CONFIGURATION pXcvConfigurePortReqData,
  681. PINET_CONFIGUREPORT_RESPDATA pXcvAddPortRespData,
  682. DWORD cbSize,
  683. PDWORD cbSizeNeeded)
  684. {
  685. return m_pPortMgr->ConfigurePort (pXcvConfigurePortReqData,
  686. pXcvAddPortRespData,
  687. cbSize,
  688. cbSizeNeeded);
  689. }
  690. HANDLE
  691. CInetMonPort::CreateTerminateEvent (
  692. VOID)
  693. {
  694. if (!m_hTerminateEvent) {
  695. //
  696. // Craete a manual reset event since multiple threads may be waiting
  697. //
  698. m_hTerminateEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
  699. }
  700. return m_hTerminateEvent;
  701. }
  702. BOOL
  703. CInetMonPort::WaitForTermination (
  704. DWORD dwWaitTime)
  705. {
  706. BOOL bTerminate = FALSE;
  707. semLeaveCrit();
  708. DWORD dwRet = WaitForSingleObject (m_hTerminateEvent, dwWaitTime);
  709. if (dwRet == WAIT_OBJECT_0 || dwRet == WAIT_FAILED)
  710. bTerminate = TRUE;
  711. semEnterCrit();
  712. return bTerminate;
  713. }