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.
777 lines
22 KiB
777 lines
22 KiB
/*****************************************************************************\
|
|
* MODULE: inet.cxx
|
|
*
|
|
* The module contains routines for the setting up the WWW Printer Service during spooler start up.
|
|
*
|
|
* The entry point here should be called by localspl\init.c\InitializePrintProvidor() once it is done
|
|
* with its work.
|
|
*
|
|
* Copyright (C) 1996 Microsoft Corporation
|
|
*
|
|
* History:
|
|
* Dec-1996 BabakJ Wrote it for IIS 2.0.
|
|
* June-1997 BabakJ Rewrote to use IIS 4.0's new Metabase interface
|
|
* Feb-1998 Weihaic Modify the URL in default.htm
|
|
* Feb 1999 BabakJ Made metabase interface a global to avoi calling too many CoCreateInstance() for perfrmance.
|
|
\*****************************************************************************/
|
|
|
|
//
|
|
//
|
|
// Note: We cannot use precomp.h here since we requrie ATL which can only be included in C++ source files.
|
|
//
|
|
//
|
|
|
|
|
|
#define INITGUID // Needed to do it to get GUID_NULL defined.
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include <iadmw.h> // Interface header
|
|
#include <iiscnfg.h> // MD_ & IIS_MD_ defines
|
|
|
|
#define MY_META_TIMEOUT 1000
|
|
|
|
TCHAR const cszW3SvcRootPath[] = TEXT("/LM/W3svc/1/Root");
|
|
TCHAR const cszPrinters[] = TEXT("Printers");
|
|
TCHAR const cszW3SvcReg[] = TEXT("System\\CurrentControlSet\\Services\\W3SVC");
|
|
|
|
|
|
typedef enum
|
|
{
|
|
kWebPrintingStateUnknown,
|
|
kWebPrintingStateNotInstalled,
|
|
kWebPrintingStateInstalled
|
|
} EWebPrintingState;
|
|
|
|
EWebPrintingState WebPrintingInstalled = kWebPrintingStateUnknown; // Gobal flag telling if WebPrinting is currently installed
|
|
|
|
|
|
class CWebShareData
|
|
{
|
|
public:
|
|
LPWSTR m_pszShareName;
|
|
BOOL m_bSharePrinter;
|
|
BOOL m_bValid;
|
|
public:
|
|
CWebShareData (LPWSTR pszShareName, BOOL bSharePrinter);
|
|
~CWebShareData ();
|
|
int Compare (CWebShareData *pSecond)
|
|
{
|
|
return 0;
|
|
};
|
|
};
|
|
|
|
class CWebShareList :
|
|
public CSingleList<CWebShareData*>
|
|
{
|
|
public:
|
|
CWebShareList ()
|
|
{
|
|
};
|
|
~CWebShareList ()
|
|
{
|
|
};
|
|
|
|
void WebSharePrinterList (IMSAdminBase *pIMetaBase);
|
|
};
|
|
|
|
HRESULT
|
|
AccessMetaBase(
|
|
OUT IMSAdminBase** ppIMetaBase
|
|
);
|
|
|
|
void
|
|
ReleaseMetaBase(
|
|
IN IMSAdminBase** ppIMetaBase
|
|
);
|
|
|
|
DWORD
|
|
ManageAllWebShares(
|
|
IN IMSAdminBase* pIMetaBase,
|
|
IN PINISPOOLER pIniSpooler,
|
|
IN BOOL bEnableWebShares
|
|
);
|
|
|
|
void
|
|
WebShareManagement(
|
|
IN LPWSTR pShareName,
|
|
IN BOOL bShare // If TRUE, will share it, else unshare it.
|
|
);
|
|
|
|
HRESULT
|
|
IsWebPrintingInstalled(
|
|
IN IMSAdminBase* pIMetaBase
|
|
);
|
|
|
|
HRESULT
|
|
ProcessWebShare(
|
|
IN IMSAdminBase* pIMetaBase,
|
|
IN LPWSTR pShareName,
|
|
IN BOOL bCreateShare
|
|
);
|
|
|
|
HRESULT
|
|
CreateVirtualDirForPrinterShare(
|
|
IN IMSAdminBase *pIMetaBase,
|
|
IN LPWSTR pShareName
|
|
);
|
|
|
|
HRESULT
|
|
RemoveVirtualDirForPrinterShare(
|
|
IN IMSAdminBase *pIMetaBase,
|
|
IN LPWSTR pShareName
|
|
);
|
|
|
|
DWORD
|
|
CheckWebPrinting(
|
|
BOOL* pbWebPrintingInstalled
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IMSAdminBase* pIMetaBase = NULL;
|
|
*pbWebPrintingInstalled = FALSE;
|
|
|
|
//
|
|
// If this is the first time we have called a Web function
|
|
// init the installed variable.
|
|
//
|
|
if (WebPrintingInstalled == kWebPrintingStateUnknown)
|
|
{
|
|
//
|
|
// First get a MetaBase interface
|
|
//
|
|
hr = AccessMetaBase( &pIMetaBase );
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = IsWebPrintingInstalled(pIMetaBase);
|
|
}
|
|
|
|
//
|
|
// If we have a MetaBase interface free it and uninit COM.
|
|
//
|
|
ReleaseMetaBase(&pIMetaBase);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pbWebPrintingInstalled = (WebPrintingInstalled == kWebPrintingStateInstalled);
|
|
}
|
|
else
|
|
{
|
|
// Something failed so just set thstate to uninstalled but don't change the saved state,
|
|
// so we will look again the next time this function is called
|
|
*pbWebPrintingInstalled = FALSE;
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WebShareManager(
|
|
IN PINISPOOLER pIniSpooler,
|
|
IN BOOL bEnableWebShares
|
|
)
|
|
{
|
|
IMSAdminBase* pIMetaBase = NULL;
|
|
HRESULT hr;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
|
|
//
|
|
// The IniSpooler needs to be from the local server
|
|
//
|
|
if ((pIniSpooler != NULL) &&
|
|
(pIniSpooler != pLocalIniSpooler) )
|
|
{
|
|
dwRet = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Get an interface for the MetaBase
|
|
//
|
|
hr = AccessMetaBase( &pIMetaBase );
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
dwRet = ManageAllWebShares( pIMetaBase, pIniSpooler, bEnableWebShares );
|
|
if (dwRet == ERROR_SUCCESS)
|
|
{
|
|
if (bEnableWebShares)
|
|
WebPrintingInstalled = kWebPrintingStateInstalled;
|
|
else
|
|
WebPrintingInstalled = kWebPrintingStateNotInstalled;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Did we fail beause the WWW Service is gone??
|
|
//
|
|
HKEY hKey;
|
|
if( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, cszW3SvcReg, 0, KEY_READ, &hKey))
|
|
{
|
|
RegCloseKey( hKey );
|
|
dwRet = HRESULT_CODE(hr);
|
|
}
|
|
else
|
|
{
|
|
WebPrintingInstalled = kWebPrintingStateNotInstalled;
|
|
dwRet = ERROR_SUCCESS;
|
|
}
|
|
}
|
|
|
|
ReleaseMetaBase(&pIMetaBase);
|
|
}
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
AccessMetaBase
|
|
|
|
Routine Description:
|
|
Open an interface handle to the IIS MetaBase
|
|
|
|
Arguments:
|
|
ppIMetaBase - The Address of a MetaBase Interface pointer
|
|
|
|
Return Value:
|
|
HRESULT
|
|
|
|
--*/
|
|
HRESULT
|
|
AccessMetaBase(
|
|
OUT IMSAdminBase** ppIMetaBase
|
|
)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
hr = ::CoCreateInstance(CLSID_MSAdminBase,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IMSAdminBase,
|
|
(void **)ppIMetaBase);
|
|
if (FAILED(hr))
|
|
{
|
|
CoUninitialize();
|
|
*ppIMetaBase = NULL;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Routine Name:
|
|
ReleaseMetaBase
|
|
|
|
Routine Description:
|
|
Release an open interface handle to the IIS MetaBase and
|
|
uninit COM.
|
|
|
|
Arguments:
|
|
pIMetaBase - A MetaBase Interface pointer
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
void
|
|
ReleaseMetaBase(
|
|
IN OUT IMSAdminBase** ppIMetaBase
|
|
)
|
|
{
|
|
if (*ppIMetaBase)
|
|
{
|
|
(*ppIMetaBase)->Release();
|
|
*ppIMetaBase = NULL;
|
|
|
|
CoUninitialize();
|
|
}
|
|
}
|
|
|
|
DWORD
|
|
ManageAllWebShares(
|
|
IMSAdminBase* pIMetaBase,
|
|
PINISPOOLER pIniSpooler,
|
|
BOOL bEnableWebShares
|
|
)
|
|
{
|
|
CWebShareList *pWebShareList = NULL;
|
|
BOOL bProcessedEntry = FALSE;
|
|
PINIPRINTER pIniPrinter;
|
|
DWORD dwRet = ERROR_SUCCESS;
|
|
|
|
|
|
if ( pWebShareList = new CWebShareList () )
|
|
{
|
|
|
|
EnterSplSem();
|
|
|
|
//
|
|
// Update VDIRs for each shared printers.
|
|
// Either add or delete the VDIRS based on bEnableWebShares
|
|
//
|
|
|
|
for ( pIniPrinter = pIniSpooler->pIniPrinter;
|
|
pIniPrinter;
|
|
pIniPrinter = pIniPrinter->pNext )
|
|
{
|
|
if ( pIniPrinter->Attributes & PRINTER_ATTRIBUTE_SHARED )
|
|
{
|
|
CWebShareData *pData = new CWebShareData (pIniPrinter->pShareName, bEnableWebShares);
|
|
|
|
if ( pData && pData->m_bValid &&
|
|
pWebShareList->Insert (pData) )
|
|
{
|
|
bProcessedEntry = TRUE;
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
if ( pData )
|
|
{
|
|
delete pData;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
LeaveSplSem ();
|
|
|
|
if ( bProcessedEntry )
|
|
{
|
|
pWebShareList->WebSharePrinterList (pIMetaBase);
|
|
}
|
|
|
|
delete pWebShareList;
|
|
}
|
|
else
|
|
dwRet = GetLastError();
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//
|
|
// Adding printer shares:
|
|
//
|
|
// To support http://<server>/<share>, we create a virtual directory with a redirect property.
|
|
//
|
|
//
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
|
|
//=====================================================================================================
|
|
//
|
|
// This function may be called during initialization time after fW3SvcInstalled is set,
|
|
// which means, a printer maybe webshared twice (once in InstallWebPrnSvcWorkerThread,
|
|
// and the other time when WebShare () is calleb by ShareThisPrinter() in net.c by
|
|
// FinalInitAfterRouterInitCompleteThread () during localspl initialization time.
|
|
//
|
|
//=====================================================================================================
|
|
|
|
void
|
|
WebShare(
|
|
LPWSTR pShareName
|
|
)
|
|
{
|
|
WebShareManagement( pShareName, TRUE );
|
|
}
|
|
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//
|
|
// Removing printer shares
|
|
//
|
|
//
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
//=====================================================================================================
|
|
|
|
void
|
|
WebUnShare(
|
|
LPWSTR pShareName
|
|
)
|
|
{
|
|
WebShareManagement( pShareName, FALSE );
|
|
}
|
|
|
|
|
|
void
|
|
WebShareManagement(
|
|
LPWSTR pShareName,
|
|
BOOL bShare // If TRUE, will share it, else unshare it.
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
IMSAdminBase* pIMetaBase = NULL;
|
|
|
|
//
|
|
// If this is the first time we have called a Web function
|
|
// init the installed variable.
|
|
//
|
|
if (WebPrintingInstalled == kWebPrintingStateUnknown)
|
|
{
|
|
//
|
|
// First get a MetaBase interface
|
|
//
|
|
hr = AccessMetaBase( &pIMetaBase );
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = IsWebPrintingInstalled( pIMetaBase );
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr) &&
|
|
(WebPrintingInstalled == kWebPrintingStateInstalled))
|
|
{
|
|
// If we don't have a metabase interface yet
|
|
if (!pIMetaBase)
|
|
hr = AccessMetaBase( &pIMetaBase );
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = ProcessWebShare( pIMetaBase, pShareName, bShare );
|
|
}
|
|
|
|
//
|
|
// If we have a MetaBase interface free it and uninit COM.
|
|
//
|
|
ReleaseMetaBase(&pIMetaBase);
|
|
}
|
|
|
|
HRESULT
|
|
IsWebPrintingInstalled(
|
|
IMSAdminBase* pIMetaBase
|
|
)
|
|
{
|
|
BOOL bInstalled = FALSE;
|
|
|
|
WCHAR szVirPath[MAX_PATH];
|
|
HRESULT hr; // com error status
|
|
METADATA_HANDLE hMeta = NULL; // handle to metabase
|
|
DWORD dwMDRequiredDataLen;
|
|
METADATA_RECORD mr;
|
|
|
|
|
|
// open key to ROOT on website #1 (default)
|
|
hr = pIMetaBase->OpenKey(METADATA_MASTER_ROOT_HANDLE,
|
|
cszW3SvcRootPath,
|
|
METADATA_PERMISSION_READ,
|
|
MY_META_TIMEOUT,
|
|
&hMeta);
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
mr.dwMDIdentifier = MD_VR_PATH;
|
|
mr.dwMDAttributes = 0;
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = sizeof( szVirPath );
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szVirPath);
|
|
|
|
// Read LM/W3Svc/1/Root/Printers see if MD_VR_PATH exists.
|
|
hr = pIMetaBase->GetData( hMeta, cszPrinters, &mr, &dwMDRequiredDataLen );
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
WebPrintingInstalled = kWebPrintingStateInstalled;
|
|
}
|
|
else if ( HRESULT_CODE(hr) == ERROR_PATH_NOT_FOUND )
|
|
{
|
|
WebPrintingInstalled = kWebPrintingStateNotInstalled;
|
|
hr = S_OK;
|
|
}
|
|
|
|
//
|
|
// Close the Web Server Key
|
|
//
|
|
pIMetaBase->CloseKey( hMeta );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
ProcessWebShare(
|
|
IMSAdminBase* pIMetaBase,
|
|
LPWSTR pShareName,
|
|
BOOL bCreateShare
|
|
)
|
|
{
|
|
HRESULT hr; // com error status
|
|
|
|
if (bCreateShare)
|
|
hr = CreateVirtualDirForPrinterShare( pIMetaBase, pShareName );
|
|
else
|
|
hr = RemoveVirtualDirForPrinterShare( pIMetaBase, pShareName );
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Flush out the changes and close
|
|
// Call SaveData() after making bulk changes, do not call it on each update
|
|
hr = pIMetaBase->SaveData();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CreateVirtualDirForPrinterShare(
|
|
IMSAdminBase *pIMetaBase,
|
|
LPWSTR pShareName
|
|
)
|
|
{
|
|
METADATA_HANDLE hMeta = NULL; // handle to metabase
|
|
WCHAR szOldURL[MAX_PATH];
|
|
WCHAR szPath[MAX_PATH];
|
|
DWORD dwMDRequiredDataLen;
|
|
DWORD dwAccessPerm;
|
|
METADATA_RECORD mr;
|
|
HRESULT hr;
|
|
BOOL fRet;
|
|
|
|
|
|
// Attempt to open the virtual dir set on Web server #1 (default server)
|
|
hr = pIMetaBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
|
|
cszW3SvcRootPath,
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
|
MY_META_TIMEOUT,
|
|
&hMeta );
|
|
|
|
// Create the key if it does not exist.
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
mr.dwMDIdentifier = MD_HTTP_REDIRECT;
|
|
mr.dwMDAttributes = 0;
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = sizeof( szOldURL );
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szOldURL);
|
|
|
|
// Read LM/W3Svc/1/Root/Printers to see if MD_HTTP_REDIRECT exists.
|
|
// Note that we are only concerned with the presence of the vir dir,
|
|
// not any properties it might have.
|
|
//
|
|
hr = pIMetaBase->GetData( hMeta, pShareName, &mr, &dwMDRequiredDataLen );
|
|
|
|
if ( FAILED( hr ) )
|
|
{
|
|
// Notice if the virtual dir exists, we won't touch it. One scenario is
|
|
// if there is a name collision between a printer sharename and an existing,
|
|
// unrelated virtual dir.
|
|
if ( HRESULT_CODE(hr) == ERROR_PATH_NOT_FOUND )
|
|
{
|
|
|
|
// Write both the key and the values if GetData() failed with any of the two errors.
|
|
pIMetaBase->AddKey( hMeta, pShareName );
|
|
|
|
|
|
dwAccessPerm = MD_ACCESS_READ;
|
|
|
|
mr.dwMDIdentifier = MD_ACCESS_PERM;
|
|
mr.dwMDAttributes = 0; // no need for inheritence
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = DWORD_METADATA;
|
|
mr.dwMDDataLen = sizeof(DWORD);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(&dwAccessPerm);
|
|
|
|
// Write MD_ACCESS_PERM value
|
|
hr = pIMetaBase->SetData( hMeta, pShareName, &mr );
|
|
|
|
if (SUCCEEDED( hr ))
|
|
{
|
|
PWCHAR szKeyType = IIS_CLASS_WEB_VDIR_W;
|
|
|
|
mr.dwMDIdentifier = MD_KEY_TYPE;
|
|
mr.dwMDAttributes = 0; // no need for inheritence
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = (wcslen(szKeyType) + 1) * sizeof(WCHAR);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szKeyType);
|
|
|
|
// Write MD_DEFAULT_LOAD_FILE value
|
|
hr = pIMetaBase->SetData( hMeta, pShareName, &mr );
|
|
}
|
|
|
|
if (SUCCEEDED( hr ))
|
|
{
|
|
WCHAR szURL[MAX_PATH];
|
|
|
|
hr = StringCchPrintf(szURL, COUNTOF(szURL), L"/printers/%ws/.printer", pShareName );
|
|
|
|
if ( SUCCEEDED(hr) )
|
|
{
|
|
mr.dwMDIdentifier = MD_HTTP_REDIRECT;
|
|
mr.dwMDAttributes = 0; // no need for inheritence
|
|
mr.dwMDUserType = IIS_MD_UT_FILE;
|
|
mr.dwMDDataType = STRING_METADATA;
|
|
mr.dwMDDataLen = (wcslen(szURL) + 1) * sizeof(WCHAR);
|
|
mr.pbMDData = reinterpret_cast<unsigned char *>(szURL);
|
|
|
|
// Write MD_DEFAULT_LOAD_FILE value
|
|
hr = pIMetaBase->SetData( hMeta, pShareName, &mr );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pIMetaBase->CloseKey( hMeta );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
RemoveVirtualDirForPrinterShare(
|
|
IMSAdminBase *pIMetaBase,
|
|
LPWSTR pShareName
|
|
)
|
|
{
|
|
METADATA_HANDLE hMeta = NULL; // handle to metabase
|
|
HRESULT hr;
|
|
|
|
|
|
// Attempt to open the virtual dir set on Web server #1 (default server)
|
|
hr = pIMetaBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
|
|
cszW3SvcRootPath,
|
|
METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
|
|
MY_META_TIMEOUT,
|
|
&hMeta );
|
|
|
|
// Create the key if it does not exist.
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
pIMetaBase->DeleteKey( hMeta, pShareName ); // We don't check the retrun value since the key may already not exist and we could get an error for that reason.
|
|
pIMetaBase->CloseKey( hMeta );
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
CWebShareData::CWebShareData (LPWSTR pszShareName, BOOL bSharePrinter)
|
|
{
|
|
m_bValid = FALSE;
|
|
m_pszShareName = NULL;
|
|
m_bSharePrinter = bSharePrinter;
|
|
|
|
DWORD cchShareLen = lstrlen (pszShareName) +1;
|
|
|
|
if ( m_pszShareName = new WCHAR[cchShareLen] )
|
|
{
|
|
|
|
StringCchCopy(m_pszShareName, cchShareLen, pszShareName);
|
|
m_bValid = TRUE;
|
|
}
|
|
}
|
|
|
|
|
|
CWebShareData::~CWebShareData ()
|
|
{
|
|
if ( m_pszShareName )
|
|
{
|
|
delete [] m_pszShareName;
|
|
}
|
|
}
|
|
|
|
|
|
void CWebShareList::WebSharePrinterList ( IMSAdminBase *pIMetaBase )
|
|
{
|
|
CSingleItem<CWebShareData*> * pItem = m_Dummy.GetNext();
|
|
|
|
CWebShareData * pData = NULL;
|
|
|
|
while ( pItem && (pData = pItem->GetData ()) && pData->m_bValid )
|
|
{
|
|
(VOID) ProcessWebShare(pIMetaBase, pData->m_pszShareName, pData->m_bSharePrinter);
|
|
pItem = pItem->GetNext ();
|
|
}
|
|
}
|
|
|
|
|
|
PWSTR
|
|
GetPrinterUrl(
|
|
PSPOOL pSpool
|
|
)
|
|
{
|
|
PINIPRINTER pIniPrinter = pSpool->pIniPrinter;
|
|
DWORD cb;
|
|
PWSTR pszURL = NULL;
|
|
PWSTR pszServerName = NULL;
|
|
LPWSTR pszMachineName = NULL;
|
|
HRESULT hr;
|
|
|
|
|
|
SplInSem();
|
|
|
|
// http://machine/share
|
|
if ( !pIniPrinter->pShareName )
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
|
|
// Get FQDN of this machine
|
|
|
|
//
|
|
// Since we should not make a network call while holding the critical section, we
|
|
// shall save all the needed variables and leave the CS, make the call and take it
|
|
// back.
|
|
//
|
|
|
|
pszMachineName = AllocSplStr(pIniPrinter->pIniSpooler->pMachineName);
|
|
if ( !pszMachineName )
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
LeaveSplSem();
|
|
SplOutSem();
|
|
|
|
hr = GetDNSMachineName(pszMachineName+2, &pszServerName);
|
|
|
|
EnterSplSem();
|
|
|
|
if ( FAILED(hr) )
|
|
{
|
|
SetLastError(HRESULT_CODE(hr));
|
|
goto error;
|
|
}
|
|
|
|
cb = 7 + wcslen(pszServerName); // http://machine
|
|
cb += 1 + wcslen(pIniPrinter->pShareName) + 1; // /share + NULL
|
|
cb *= sizeof(WCHAR);
|
|
|
|
if ( pszURL = (PWSTR) AllocSplMem(cb) )
|
|
{
|
|
StringCbPrintf(pszURL, cb, L"http://%ws/%ws", pszServerName, pIniPrinter->pShareName);
|
|
}
|
|
|
|
error:
|
|
|
|
FreeSplStr(pszServerName);
|
|
FreeSplStr(pszMachineName);
|
|
|
|
return pszURL;
|
|
}
|
|
|
|
|