|
|
/*****************************************************************************\
* MODULE: portmgr.cxx * * The module contains routines for handling the http port connection * for internet priting * * Copyright (C) 1996-1998 Microsoft Corporation * * History: * 22-Jul-1996 WeihaiC Created * \*****************************************************************************/
#include "precomp.h"
#include "priv.h"
// This the length used to fetch the authentication scheme. I don't see any reason
// that the authentication scheme could be longer.
#define MAX_SCHEME_LEN 255
CPortMgr::CPortMgr (): // Put all the private member variable here
m_hSession (NULL), m_hConnect (NULL), m_lpszPassword (NULL), m_lpszUserName (NULL), m_lpszHostName (NULL), m_lpszUri (NULL), m_lpszPortName (NULL), m_bPortCreate (FALSE), m_bForceAuthSupported (TRUE), //We set it to be TRUE so that we will always try it.
m_pPortSettingMgr (NULL), m_bSecure (FALSE), m_nPort (0), m_bValid (FALSE)
{ }
CPortMgr::~CPortMgr () { LocalFree (m_lpszPassword); LocalFree (m_lpszUserName); LocalFree (m_lpszHostName); LocalFree (m_lpszUri); LocalFree (m_lpszPortName);
m_hSession = NULL; m_hConnect = NULL; }
HINTERNET CPortMgr::_OpenRequest ( CAnyConnection *pConnection) { HINTERNET hReq = NULL;
if (pConnection && pConnection->OpenSession ()) {
if (pConnection->Connect (m_lpszHostName)) { hReq = pConnection->OpenRequest (m_lpszUri); } }
return hReq; }
BOOL CPortMgr::_CloseRequest ( CAnyConnection *pConnection, HINTERNET hReq) { BOOL bRet = FALSE;
if (pConnection->CloseRequest (hReq)) { if (pConnection->Disconnect ()) { bRet = pConnection->CloseSession(); } } return bRet; }
/*****************************************************************************\
* Function: SendRequest * * This function is to send an IPP request to an established connection * * The intension of the function is to send the request with specified * authentication instead of anonymous even if anonymous is enabled. * The alogortihm is as following * 1. If it is anonymous, just send the request and return * 2. Otherwise, * 3. If m_bForceAuthSupported, send ForceAuth to turn off anonymous, otherwise, goto 4 * 3.a. Issue Force Authentication * 3.b. If the return value is 401 access denied, perform proper retry and return * 3.c. Otherwise, (We don't get 401 access denied). If we get other errors, return FALSE * 3.d. Check the IPP response of the Forth Authentication * 3.e. If the IPP response is OK, we return TRUE * 3.f. Otherwise, (Not Supported), we assume that the server does not * support Force Authentication, so we marek m_bForceAuthSupported as FALSE * and move on by returning a FALSE. * * 4. Send the real IPP request. * \*****************************************************************************/
BOOL CPortMgr::_SendRequest ( CAnyConnection *pConnection, HINTERNET hJobReq, CStream *pStream) { BOOL bRet = FALSE;
DWORD cbData;
// Generate the Http header and indicate the size
// of the data we're sending.
//
if (pStream->GetTotalSize (&cbData) && cbData) {
DWORD dwLE = ERROR_SUCCESS; DWORD dwAuthMethod = pConnection->GetAuthMethod ();
// We need to force authentication if the method is NTLM or others
if (m_bForceAuthSupported && ( dwAuthMethod == AUTH_OTHER || dwAuthMethod == AUTH_NT)) {
HINTERNET hReq; // Open a request and send force authentication IPP request
if (hReq = pConnection->OpenRequest (m_lpszUri)) {
bRet = _IppForceAuth (pConnection, hReq, m_lpszPortName, &dwAuthMethod);
if (!bRet) { dwLE = GetLastError (); }
pConnection->CloseRequest (hReq); }
if (m_bForceAuthSupported && !bRet && dwLE == ERROR_ACCESS_DENIED) { // If forth authentication is supported but the server authentication fails, we return an error
DBG_MSG(DBG_LEV_ERROR, (TEXT("CPortMgr::_SendRequest : Failed (lasterror=%d)"), dwLE));
SetLastError (dwLE); return bRet; } }
if (pConnection->SendRequest (hJobReq, g_szContentType, pStream)) { bRet = TRUE; } else {
DBG_MSG(DBG_LEV_ERROR, (TEXT("CPortMgr::_SendRequest : pConnection->SendRequest Failed (lasterror=%d)"), GetLastError ()));
} }
return bRet; }
BOOL CPortMgr::ReadFile ( CAnyConnection *pConnection, HINTERNET hReq, LPVOID lpvBuffer, DWORD cbBuffer, LPDWORD lpcbRd) { BOOL bRet = FALSE;
if (m_bValid && pConnection) { bRet = pConnection->ReadFile (hReq, lpvBuffer, cbBuffer, lpcbRd); }
return bRet; }
/*****************************************************************************\
* _IppForceAuthRsp (Local Callback Routine) * * Retrieves a forth-authentication response from the IPP server * \*****************************************************************************/ BOOL CPortMgr::_IppForceAuthRsp( CAnyConnection *pConnection, HINTERNET hReq, LPARAM lParam) { HANDLE hIpp; DWORD dwRet; DWORD cbRd; LPBYTE lpDta; DWORD cbDta; LPIPPRET_PRN lpRsp; DWORD cbRsp; BYTE bBuf[MAX_IPP_BUFFER]; BOOL bRet = FALSE;
if (hIpp = WebIppRcvOpen(IPP_RET_FORCEAUTH)) {
while (TRUE) {
cbRd = 0; if (pConnection->ReadFile (hReq, (LPVOID)bBuf, sizeof(bBuf), &cbRd) && cbRd) {
dwRet = WebIppRcvData(hIpp, bBuf, cbRd, (LPBYTE*)&lpRsp, &cbRsp, &lpDta, &cbDta);
switch (dwRet) {
case WEBIPP_OK:
if (!lpRsp) { SetLastError (ERROR_INVALID_DATA); } else if ((bRet = lpRsp->bRet) == TRUE) // This is from our server. We have already had the authentication
// established
bRet = TRUE;
else SetLastError(lpRsp->dwLastError);
WebIppFreeMem(lpRsp);
goto EndValRsp;
case WEBIPP_MOREDATA:
// Need to do another read to fullfill our header-response.
//
break;
default:
DBG_MSG(DBG_LEV_ERROR, (TEXT("CPortMgr::_IppForceAuthRsp Err : Receive Data Error (dwRet=%d, LE=%d)"), dwRet, WebIppGetError(hIpp)));
SetLastError(ERROR_INVALID_DATA);
goto EndValRsp; }
} else {
goto EndValRsp; } }
EndValRsp:
WebIppRcvClose(hIpp);
} else {
SetLastError(ERROR_OUTOFMEMORY); }
return bRet; }
BOOL CPortMgr::_IppForceAuth ( CAnyConnection *pConnection, HINTERNET hReq, LPCTSTR lpszPortName, PDWORD pdwAuthMethod) { LPIPPREQ_GETPRN pgp; REQINFO ri; DWORD dwRet; LPBYTE lpIpp; DWORD cbIpp; DWORD dwLE = ERROR_SUCCESS; BOOL bRet = FALSE; DWORD dwAuthMethod = pConnection->GetAuthMethod ();
if (pgp = WebIppCreateGetPrnReq(0, lpszPortName)) {
// Convert the request to IPP, and perform the
// post.
//
ZeroMemory(&ri, sizeof(REQINFO)); ri.cpReq = CP_UTF8; ri.idReq = IPP_REQ_FORCEAUTH;
ri.fReq[0] = IPP_REQALL; ri.fReq[1] = IPP_REQALL;
dwRet = WebIppSndData(IPP_REQ_FORCEAUTH, &ri, (LPBYTE)pgp, pgp->cbSize, &lpIpp, &cbIpp);
// The request-structure has been converted
// to IPP format, so it is ready to go to
// the server.
//
//
if (dwRet == WEBIPP_OK) {
bRet = pConnection->SendRequest (hReq, g_szContentType, cbIpp, lpIpp);
if (!bRet) { // Check if it is an access denied or some other error
dwLE = GetLastError();
if (dwLE == ERROR_ACCESS_DENIED && dwAuthMethod == AUTH_UNKNOWN) { CHAR szAuthScheme[MAX_SCHEME_LEN]; static CHAR szNTLM[] = "NTLM"; static CHAR szKerbero[] = "Kerbero"; static CHAR szNegotiate[] = "Negotiate";
if (pConnection->GetAuthSchem (hReq, szAuthScheme, MAX_SCHEME_LEN)) { // We've got the scheme
if (! (*szAuthScheme)) { // It does not have authentication enabled, only Anonymous is supported
*pdwAuthMethod = AUTH_ANONYMOUS; } if (strstr (szAuthScheme, szNTLM) || strstr (szAuthScheme, szKerbero) || strstr (szAuthScheme, szNegotiate)) {
// We have authentication scheme that can authentication with no
// popup, let's use it.
*pdwAuthMethod = AUTH_NT;
} else { // We have an authentications scheme, but we need to popup for username
// and password
*pdwAuthMethod = AUTH_OTHER; } bRet = TRUE; } } } else { // It means somehow, either the authentication is done,
// or we get unsupported operation
bRet = _IppForceAuthRsp(pConnection, hReq, 0L);
if (!bRet) { // the response from the server does not seem to be OK, so
// we mark m_bForceAuthSupported as FALSE so that we will not
// send the ForceAuth request to the server again.
m_bForceAuthSupported = FALSE; }
if (bRet && dwAuthMethod == AUTH_UNKNOWN) { // The authentication is done, so let's use NTLM authentication
*pdwAuthMethod = AUTH_NT; } // else degrade to old logic
}
WebIppFreeMem(lpIpp);
}
WebIppFreeMem(pgp); }
if (dwLE == ERROR_INVALID_DATA) { dwLE = ERROR_INVALID_PRINTER_NAME; }
if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS)) SetLastError(dwLE);
return bRet; } BOOL CPortMgr::_ForceAuth ( CAnyConnection *pConnection, LPCTSTR lpszPortName, LPTSTR lpszHost, LPTSTR lpszUri, PDWORD pdwAuthMethod) { HINTERNET hReq; DWORD dwLE = ERROR_SUCCESS; BOOL bRet = FALSE;
if (pConnection->OpenSession()) {
if (pConnection->Connect (lpszHost)) {
// Make the request.
//
if (hReq = pConnection->OpenRequest (lpszUri)) {
// If request handle is established, then all
// is OK so far.
//
bRet = _IppForceAuth (pConnection, hReq, lpszPortName, pdwAuthMethod); dwLE = GetLastError();
pConnection->CloseRequest (hReq); }
pConnection->Disconnect (); }
pConnection->CloseSession (); }
if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS)) SetLastError(dwLE);
return bRet; }
/*****************************************************************************\
* _IppValRsp (Local Callback Routine) * * Retrieves a get-printer-attributes response from the IPP server * \*****************************************************************************/ BOOL CPortMgr::_IppValRsp( CAnyConnection *pConnection, HINTERNET hReq, LPARAM lParam) { HANDLE hIpp; DWORD dwRet; DWORD cbRd; LPBYTE lpDta; DWORD cbDta; LPIPPRET_PRN lpRsp; DWORD cbRsp; BYTE bBuf[MAX_IPP_BUFFER]; BOOL bRet = FALSE;
if (hIpp = WebIppRcvOpen(IPP_RET_GETPRN)) {
while (TRUE) {
cbRd = 0; if (pConnection->ReadFile (hReq, (LPVOID)bBuf, sizeof(bBuf), &cbRd) && cbRd) {
dwRet = WebIppRcvData(hIpp, bBuf, cbRd, (LPBYTE*)&lpRsp, &cbRsp, &lpDta, &cbDta);
switch (dwRet) {
case WEBIPP_OK:
if (!lpRsp) { SetLastError (ERROR_INVALID_DATA); } else if ((bRet = lpRsp->bRet) == FALSE) SetLastError(lpRsp->dwLastError);
WebIppFreeMem(lpRsp);
goto EndValRsp;
case WEBIPP_MOREDATA:
// Need to do another read to fullfill our header-response.
//
break;
default:
DBG_MSG(DBG_LEV_ERROR, (TEXT("CPortMgr::_IppValRsp - Err : Receive Data Error (dwRet=%d, LE=%d)"), dwRet, WebIppGetError(hIpp)));
SetLastError(ERROR_INVALID_DATA);
goto EndValRsp; }
} else {
goto EndValRsp; } }
EndValRsp:
WebIppRcvClose(hIpp);
} else {
SetLastError(ERROR_OUTOFMEMORY); }
return bRet; }
BOOL CPortMgr::_IppValidate ( CAnyConnection *pConnection, HINTERNET hReq, LPCTSTR lpszPortName) { LPIPPREQ_GETPRN pgp; REQINFO ri; DWORD dwRet; LPBYTE lpIpp; DWORD cbIpp; DWORD dwLE = ERROR_SUCCESS; BOOL bRet = FALSE;
if (pgp = WebIppCreateGetPrnReq(0, lpszPortName)) {
// Convert the request to IPP, and perform the
// post.
//
ZeroMemory(&ri, sizeof(REQINFO)); ri.cpReq = CP_UTF8; ri.idReq = IPP_REQ_GETPRN;
ri.fReq[0] = IPP_REQALL; ri.fReq[1] = IPP_REQALL;
dwRet = WebIppSndData(IPP_REQ_GETPRN, &ri, (LPBYTE)pgp, pgp->cbSize, &lpIpp, &cbIpp);
// The request-structure has been converted
// to IPP format, so it is ready to go to
// the server.
//
//
if (dwRet == WEBIPP_OK) {
CMemStream *pStream = new CMemStream (lpIpp, cbIpp);
if (pStream) { bRet = _SendRequest (pConnection, hReq, pStream);
delete pStream; }
if (bRet) bRet = _IppValRsp(pConnection, hReq, 0L);
if (!bRet) {
dwLE = GetLastError();
}
WebIppFreeMem(lpIpp);
}
WebIppFreeMem(pgp); }
if (dwLE == ERROR_INVALID_DATA) { dwLE = ERROR_INVALID_PRINTER_NAME; }
if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS)) SetLastError(dwLE);
return bRet; }
BOOL CPortMgr::_CheckConnection ( CAnyConnection *pConnection, LPCTSTR lpszPortName, LPTSTR lpszHost, LPTSTR lpszUri) { HINTERNET hReq; DWORD dwLE = ERROR_SUCCESS; BOOL bRet = FALSE;
if (pConnection->OpenSession()) {
if (pConnection->Connect (lpszHost)) {
// Make the request.
//
if (hReq = pConnection->OpenRequest (lpszUri)) {
// If request handle is established, then all
// is OK so far.
//
bRet = _IppValidate (pConnection, hReq, lpszPortName); dwLE = GetLastError();
pConnection->CloseRequest (hReq); }
pConnection->Disconnect (); }
pConnection->CloseSession (); }
if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS)) SetLastError(dwLE);
return bRet; }
BOOL CPortMgr::CheckConnection (void) { HINTERNET hReq; BOOL bRet = FALSE; DWORD dwLE = ERROR_SUCCESS; CAnyConnection *pConnection = NULL;
DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Enter CheckConnection")));
if (m_bValid) { pConnection = _GetCurrentConnection ();
if (hReq = _OpenRequest (pConnection)) { bRet = _IppValidate (pConnection, hReq, m_lpszPortName);
if (!bRet) { dwLE = GetLastError(); }
_CloseRequest (pConnection, hReq); }
if (pConnection) { delete pConnection; }
if (!bRet && dwLE != ERROR_SUCCESS) {
DBG_MSG(DBG_LEV_ERROR, (TEXT("CPortMgr::CheckConnection : Failed (lasterror=%d)"), dwLE));
SetLastError (dwLE); } } else SetLastError (ERROR_INVALID_HANDLE);
DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Leave CheckConnection ret=%d, lasterror=%d"), bRet, GetLastError ()));
return bRet; }
/*****************************************************************************\
* Function: Create * * This function is to establish the network connection with the given port name * * The intension of the function is to establish a network connection with * authentication instead of anonymous. The alogortihm is as following * 1. Try Anonymous * 2. If anonymous connection is NOT possible, go to step 5 * 3. Try Force Authentication (Call _ForceAuth) * 3.a. Issue Force Authentication * 3.b. If the return value is 401 access denied, we start to check the * authentication scheme, otherwise, mark m_dwAuthMethod * as AUTH_ANONYMOUS and return TRUE * 3.c. If either NTLM, Kerbero or Negotiate is in the scheme, we mark * m_dwAuthMethod as AUTH_NT * Otherwise, we mark it as AUTH_OTHER * return TRUE * 3.d. (We don't get 401 access denied). If we get other errors, return FALSE * 3.e. Check the IPP response of the Forth Authentication * 3.f. If the IPP response is OK, we know we have established authentication * (This should not happen in the first time, but will happen afterward) * but we will mark m_dwAuthMethod as AUTH_NT anyway and return TRUE. * 3.g. Otherwise, (Not Supported), we assume that the server does not * support Force Authentication, so we move on by returning a FALSE. * * 4. If it returns OK, we start to use the authentication method indicated * in m_dwAuthMethod * 5. Try NTLM or other no-popup authentication * 6. Try Other popup authentications * * If the connection is established, the function returns TRUE. * \*****************************************************************************/
BOOL CPortMgr::Create ( LPCTSTR lpszPortName) { LPTSTR lpszHost = NULL; LPTSTR lpszShare = NULL; INTERNET_PORT nPort; CAnyConnection *pConnection = NULL; BOOL bRet = FALSE; DWORD dwLE = 0; BOOL bDone; BOOL bSecure; BOOL bAnonymous = FALSE; DWORD dwAuthMethod;
// Try to find out if the server can be accessed without going
// through Proxy Server
//
if ( utlParseHostShare(lpszPortName, &lpszHost, &lpszShare, &nPort, &bSecure)) {
bDone = ! (AssignString (m_lpszHostName, lpszHost) && AssignString (m_lpszUri, lpszShare) && AssignString (m_lpszPortName, lpszPortName));
m_bSecure = bSecure; m_nPort = nPort;
// Set the flag to indicate it is creation time.
//
m_bPortCreate = TRUE;
// Try connect and the get the proxy
if (!bDone) {
// We don't care about if the reset succeeded or not
EndBrowserSession (); }
// Try anonymous with/without proxy
if (!bDone && (pConnection = new CAnonymousConnection (bSecure, nPort, FALSE)) && pConnection->IsValid ()) {
bDone = TRUE;
if (_CheckConnection(pConnection, lpszPortName, lpszHost, lpszShare)) { bAnonymous = TRUE; } else { dwLE = GetLastError ();
if (dwLE == ERROR_INTERNET_NAME_NOT_RESOLVED) {
// The server name is wrong, reset tht last error
// to invalid printer name
//
SetLastError (ERROR_INVALID_PRINTER_NAME); } else if (dwLE == HTTP_STATUS_FORBIDDEN) { SetLastError (ERROR_ACCESS_DENIED); } else if (dwLE != ERROR_INVALID_PRINTER_NAME) bDone = FALSE; // Cont to the next mode
}
if (bAnonymous) {
// We've got an anonymous authentication
if (_ForceAuth(pConnection, lpszPortName, lpszHost, lpszShare, &dwAuthMethod)) {
// We've got an authentication method
if (dwAuthMethod != AUTH_ANONYMOUS) { bDone = FALSE; SetLastError (ERROR_ACCESS_DENIED);
if (dwAuthMethod == AUTH_OTHER) { bDone = TRUE; //weihaic goto TryOther;
} } else bRet = TRUE; } else { // We've got anonymous, and the serve does not support FORCE_AUTH
// so let us use it.
dwAuthMethod = AUTH_ANONYMOUS; bRet = TRUE; } } }
// You must have got access denied in this case
// Let's try again without any password, it will work if the server has NTLM/Kerbero enabled.
//
if (!bDone && GetLastError () == ERROR_ACCESS_DENIED) {
if (pConnection) { delete (pConnection); pConnection = NULL; } bDone = TRUE;
if ( (pConnection = new CNTConnection (bSecure, nPort, FALSE) ) && pConnection->IsValid ()) {
if (_CheckConnection(pConnection, lpszPortName, lpszHost, lpszShare)) { dwAuthMethod = AUTH_NT; bRet = TRUE; } else { dwLE = GetLastError ();
if (dwLE != ERROR_INVALID_PRINTER_NAME) bDone = FALSE; // Cont to the next mode
} } }
if (!bDone && GetLastError () == ERROR_ACCESS_DENIED && bAnonymous) { // We know that anonymous is enabled, so let us degrade the connection to anonymous
if (pConnection) { delete (pConnection); pConnection = NULL; }
// We must reset m_dwAuthMethod since when we try other authentication
// m_dwAuthMethod is set to AUTH_OTHER, if we do not reset the value
// when we try to send request to the server, it will fail with access
// denied.
//
dwAuthMethod = AUTH_UNKNOWN;
if (!bDone && (pConnection = new CAnonymousConnection (bSecure, nPort, FALSE)) && pConnection->IsValid ()) {
bDone = TRUE;
if (_CheckConnection(pConnection, lpszPortName, lpszHost, lpszShare)) { bRet = TRUE; dwAuthMethod = AUTH_ANONYMOUS; } } } } // Exit point
//
// We need to create the port at first if we get access denied
// then users can configure the port using a different user name
// and password
//
if (!bRet && GetLastError () == ERROR_ACCESS_DENIED) { //
// Force anonymous connection. This will fail anyway.
//
dwAuthMethod = AUTH_ACCESS_DENIED; bRet = TRUE; }
if (bRet) { m_bValid = TRUE;
m_pPortSettingMgr = new CPortConfigDataMgr (lpszPortName);
if (m_pPortSettingMgr && m_pPortSettingMgr->bValid ()) {
CPortConfigData ConfigData;
ConfigData.SetAuthMethod (dwAuthMethod);
bRet = m_pPortSettingMgr->SetPerPortSettings (ConfigData); } else bRet = FALSE; }
if (lpszHost) { memFreeStr (lpszHost); }
if (lpszShare) { memFreeStr (lpszShare); }
if (!bRet) { // Clean up the connection class
if (pConnection) { delete (pConnection); pConnection = NULL; }
if (GetLastError () != ERROR_ACCESS_DENIED) { // Invalid Printer Name
// The NT router expects inetpp to returen ERROR_INVALID_NAME,
// if we return ERROR_INVALID_PRINTER_NAME, the router will return
// this error back to the user
//
SetLastError (ERROR_INVALID_NAME); }
}
m_bPortCreate = FALSE;
return bRet;
}
BOOL CPortMgr::ConfigurePort ( PINET_XCV_CONFIGURATION pXcvConfigurePortReqData, PINET_CONFIGUREPORT_RESPDATA pXcvAddPortRespData, DWORD cbSize, PDWORD cbSizeNeeded) { LPTSTR lpszHost = NULL; LPTSTR lpszShare = NULL; INTERNET_PORT nPort; CAnyConnection *pConnection = NULL; BOOL bRet = FALSE; DWORD dwLE = 0; BOOL bDone; BOOL bSecure; BOOL bAnonymous = FALSE; CPortConfigData OldConfigData; LPCTSTR pPassword = NULL;
// Reset everything
EndBrowserSession ();
//
// We must retry force authentication when configuration changes
//
m_bForceAuthSupported = TRUE;
BOOL bIgnoreSecurityDlg = pXcvConfigurePortReqData->bIgnoreSecurityDlg; DWORD dwAuthMethod = pXcvConfigurePortReqData->dwAuthMethod;
switch (dwAuthMethod) { case AUTH_ANONYMOUS: pConnection = new CAnonymousConnection (m_bSecure, m_nPort, bIgnoreSecurityDlg); break; case AUTH_NT: pConnection = new CNTConnection (m_bSecure, m_nPort, bIgnoreSecurityDlg); break; case AUTH_OTHER:
if (m_pPortSettingMgr->GetCurrentSettings (&OldConfigData)) pPassword = OldConfigData.GetPassword();
pPassword = (pXcvConfigurePortReqData->bPasswordChanged)?pXcvConfigurePortReqData->szPassword:pPassword;
pConnection = new COtherConnection (m_bSecure, m_nPort, pXcvConfigurePortReqData->szUserName, pPassword, bIgnoreSecurityDlg); default: break; }
if (pConnection && pConnection->IsValid()) {
if (_CheckConnection(pConnection, m_lpszPortName, m_lpszHostName, m_lpszUri)) {
bRet = TRUE; } else { dwLE = GetLastError ();
if (dwLE == ERROR_INTERNET_NAME_NOT_RESOLVED) {
// The server name is wrong, reset tht last error
// to invalid printer name
//
SetLastError (ERROR_INVALID_PRINTER_NAME); } else if (dwLE == HTTP_STATUS_FORBIDDEN) { SetLastError (ERROR_ACCESS_DENIED); } else if (dwLE != ERROR_INVALID_PRINTER_NAME) SetLastError (dwLE); } } // Exit point
if (bRet) { m_bValid = TRUE;
CPortConfigData ConfigData;
bRet = ConfigData.SetAuthMethod (dwAuthMethod);
if (bRet) {
if (dwAuthMethod == AUTH_OTHER) { bRet = ConfigData.SetUserName (pXcvConfigurePortReqData->szUserName) && ConfigData.SetPassword (pPassword); } else bRet = ConfigData.SetUserName(NULL) && ConfigData.SetPassword(NULL);
if (bRet) { bRet = m_pPortSettingMgr->SetPerUserSettings (ConfigData); }
if (bRet && pXcvConfigurePortReqData->bSettingForAll) bRet = m_pPortSettingMgr->SetPerPortSettings (ConfigData); } } return bRet;
}
BOOL CPortMgr::GetCurrentConfiguration ( PINET_XCV_CONFIGURATION pXcvConfiguration) { CPortConfigData ConfigData;
ZeroMemory (pXcvConfiguration, sizeof (INET_XCV_CONFIGURATION));
m_pPortSettingMgr->GetCurrentSettings (&ConfigData);
pXcvConfiguration->dwVersion = 1; pXcvConfiguration->dwAuthMethod = ConfigData.GetAuthMethod (); if (pXcvConfiguration->dwAuthMethod == AUTH_OTHER) { if (ConfigData.GetUserName()) { StringCchCopy(pXcvConfiguration->szUserName, COUNTOF(pXcvConfiguration->szUserName), ConfigData.GetUserName()); } } pXcvConfiguration->bIgnoreSecurityDlg = ConfigData.GetIgnoreSecurityDlg();
return TRUE;
}
BOOL CPortMgr::Init ( LPCTSTR lpszPortName) { LPTSTR lpszHost = NULL; LPTSTR lpszShare = NULL; INTERNET_PORT nPort; BOOL bRet = FALSE; BOOL bSecure = FALSE;
if ( utlParseHostShare(lpszPortName, &lpszHost, &lpszShare, &nPort, &bSecure)) {
m_pPortSettingMgr = new CPortConfigDataMgr (lpszPortName);
if (m_pPortSettingMgr && m_pPortSettingMgr->bValid ()) { bRet = TRUE; } }
if (bRet) {
m_bValid = TRUE;
m_bSecure = bSecure; m_nPort = nPort;
bRet = AssignString (m_lpszHostName, lpszHost) && AssignString (m_lpszUri, lpszShare) && AssignString (m_lpszPortName, lpszPortName); }
if (lpszHost) { memFreeStr (lpszHost); }
if (lpszShare) { memFreeStr (lpszShare); }
return bRet;
}
BOOL CPortMgr::Remove (void) { if (m_pPortSettingMgr) { m_pPortSettingMgr->DeleteAllSettings ();
} return TRUE; }
CAnyConnection * CPortMgr::_GetCurrentConnection () { CPortConfigData ConfigData; CAnyConnection *pConnection = NULL;
if (m_pPortSettingMgr->GetCurrentSettings (&ConfigData)) {
switch (ConfigData.GetAuthMethod ()) { case AUTH_ANONYMOUS:
pConnection = new CAnonymousConnection (m_bSecure, m_nPort, ConfigData.GetIgnoreSecurityDlg()); break;
case AUTH_NT: pConnection = new CNTConnection (m_bSecure, m_nPort, ConfigData.GetIgnoreSecurityDlg()); break;
case AUTH_OTHER: pConnection = new COtherConnection (m_bSecure, m_nPort, ConfigData.GetUserName(), ConfigData.GetPassword(), ConfigData.GetIgnoreSecurityDlg());
break; case AUTH_ACCESS_DENIED: SetLastError (ERROR_ACCESS_DENIED); break; default: SetLastError (ERROR_INVALID_HANDLE); break; } } else {
DBG_MSG(DBG_LEV_ERROR, (TEXT("_GetCurrentConnection - Err GetCurrentSettings failed (LE=%d)"), GetLastError ()));
SetLastError (ERROR_INVALID_HANDLE); } return pConnection;
}
BOOL CPortMgr::SendRequest( PCINETMONPORT pIniPort, LPBYTE lpIpp, DWORD cbIpp, IPPRSPPROC pfnRsp, LPARAM lParam) { BOOL bRet = FALSE; CMemStream *pStream;
pStream = new CMemStream (lpIpp, cbIpp);
if (pStream && pStream->bValid ()){ bRet = SendRequest (pIniPort, pStream, pfnRsp, lParam); }
if (pStream) { delete pStream; } return bRet;
}
BOOL CPortMgr::SendRequest( PCINETMONPORT pIniPort, CStream *pStream, IPPRSPPROC pfnRsp, LPARAM lParam) { HINTERNET hReq; DWORD dwLE = ERROR_SUCCESS; BOOL bRet = FALSE;
if (m_bValid) {
CAnyConnection * pConnection;
pConnection = _GetCurrentConnection ();
if (pConnection) {
hReq = _OpenRequest (pConnection);
// If succeeded, then build the content-length-header.
//
if (hReq) {
bRet = _SendRequest (pConnection, hReq, pStream);
if (bRet) bRet = (pfnRsp ? (*pfnRsp)(pConnection, hReq, pIniPort, lParam) : TRUE);
dwLE = GetLastError();
_CloseRequest (pConnection, hReq); } } else dwLE = GetLastError ();
if ((bRet == FALSE) && (dwLE != ERROR_SUCCESS)) {
if (dwLE == HTTP_STATUS_FORBIDDEN) { SetLastError (ERROR_ACCESS_DENIED); } else SetLastError(dwLE);
} } else { SetLastError (ERROR_INVALID_HANDLE); }
return bRet;
}
DWORD CPortMgr::IncreaseUserRefCount( CLogonUserData *pUser) /*++
Routine Description: Increase the Ref Count for the current user in the Port Manager.
Arguments: pUser - The user that we want to increment the RefCount for.
Return Value: The current refcount for the user, or MAXDWORD if the user could not be found.
--*/ { CLogonUserData *pPortUser = NULL; CLogonUserData *pNewUser = NULL; DWORD dwRefCount = MAXDWORD;
DBG_ASSERT( pUser , (TEXT("CPortMgr::IncreaseUserRefCount - pUser is NULL.")) ); DBG_ASSERT( pUser->bValid(), (TEXT("CPortMgr::IncreaseUserRefCount - pUser is invalid.")) );
m_UserList.Lock(); // We need to be sure only one CurUser is considered per port per time.
if (pPortUser = m_UserList.Find( pUser )) {
// We have found the port user, increment their refcount.
dwRefCount = pPortUser->IncRefCount();
DBG_MSG(DBG_LEV_INFO, (TEXT("Info: IncRef to (%d), User (%p)"), dwRefCount, pPortUser ) ); } else {
pNewUser = new CLogonUserData; // A new user automatically has a ref-count of 1.
if (pNewUser != NULL) {
*pNewUser = *pUser; // Assign data across
if (!pNewUser->bValid() || !m_UserList.Insert( pNewUser )) { delete pNewUser; pNewUser = NULL;
SetLastError( ERROR_INVALID_PARAMETER ); } else dwRefCount = 1; } }
m_UserList.Unlock();
return dwRefCount; }
CLogonUserData* CPortMgr::GetUserIfLastDecRef( CLogonUserData *pUser) /*++
Routine Description: This routine finds the reference count for the current user. If the reference count is zero we return a pointer to the user, otherwise we return NULL. This will be used by the Cache Manager to invalid the cache for the particular user.
NOTE: Caller must Free the pUser.
Arguments: None
Return Value: A pointer to the user if their RefCount has gone to Zero, NULL otherwise.
--*/ { CLogonUserData *pPortUser = NULL; CLogonUserData *pNewUser = NULL; DWORD dwRefCount;
DBG_ASSERT( pUser , (TEXT("CPortMgr::GetUserIfLastDecRef - pUser is NULL.")) ); DBG_ASSERT( pUser->bValid(), (TEXT("CPortMgr::GetUserIfLastDecRef - pUser is invalid.")) );
m_UserList.Lock();
if (pPortUser = m_UserList.Find( pUser )) { // We have found the port user, increment their refcount.
// Make sure that two threads aren't handling the RefCount at the same
// time
dwRefCount = pPortUser->DecRefCount();
DBG_MSG(DBG_LEV_INFO, (TEXT("Info: DecRef to (%d), User (%p)"), dwRefCount, pPortUser ) );
if (dwRefCount == 0) { pNewUser = new CLogonUserData;
if (pNewUser != NULL) { *pNewUser = *pPortUser; }
m_UserList.Delete( pPortUser ); // We don't need him in the list anymore
} }
m_UserList.Unlock();
return pNewUser; }
|