windows-nt/Source/XPSP1/NT/printscan/print/spooler/spoolss/client/clusspl.c
2020-09-26 16:20:57 +08:00

252 lines
4.4 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
All rights reserved.
Module Name:
cluster.c
Abstract:
Cluster support.
Note: there is no handle revalidation support in the module because
the cluster software should be informed when a group goes offline.
Author:
Albert Ting (AlbertT) 1-Oct-96
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include "client.h"
BOOL
ClusterSplOpen(
LPCTSTR pszServer,
LPCTSTR pszResource,
PHANDLE phSpooler,
LPCTSTR pszName,
LPCTSTR pszAddress
)
/*++
Routine Description:
Client side stub for opening a cluster resource.
Arguments:
pszServer - Server to open--currently must be NULL (local).
pszResource - Spooler resource.
phSpooler - Receives handle on success; recevies NULL otherwise.
pszName - Comma delimited alternate netbios/computer names.
pszAddress - Comma delimited tcpip address names.
Return Value:
TRUE - Success, phHandle must be closed with ClusterSplClose.
FALSE - Failed--use GetLastError. *phSpooler is NULL.
--*/
{
DWORD Status = ERROR_SUCCESS;
BOOL bReturnValue = TRUE;
PSPOOL pSpool = NULL;
//
// Preinitialize the spooler handle return to NULL.
//
__try {
*phSpooler = NULL;
} __except( EXCEPTION_EXECUTE_HANDLER ){
SetLastError( ERROR_INVALID_PARAMETER );
phSpooler = NULL;
}
if( !phSpooler ){
goto Fail;
}
//
// Disallow remote servers in this release.
//
if( pszServer ){
SetLastError( ERROR_INVALID_PARAMETER );
goto Fail;
}
//
// Preallocate the handle.
//
pSpool = AllocSpool();
if (pSpool)
{
RpcTryExcept {
Status = RpcClusterSplOpen( (LPTSTR)pszServer,
(LPTSTR)pszResource,
&pSpool->hPrinter,
(LPTSTR)pszName,
(LPTSTR)pszAddress );
if( Status ){
SetLastError( Status );
bReturnValue = FALSE;
}
} RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())){
SetLastError( TranslateExceptionCode( RpcExceptionCode() ));
bReturnValue = FALSE;
} RpcEndExcept
}
else
{
SetLastError( ERROR_OUTOFMEMORY );
bReturnValue = FALSE;
}
if( bReturnValue ){
//
// pSpool is orphaned to *phSpooler.
//
*phSpooler = (HANDLE)pSpool;
pSpool = NULL;
}
Fail:
FreeSpool( pSpool );
return bReturnValue;
}
BOOL
ClusterSplClose(
HANDLE hSpooler
)
/*++
Routine Description:
Close the spooler.
Arguments:
hSpooler - Spooler to close.
Return Value:
Note: this function always returns TRUE, although it's spec'd out
to return FALSE if the call fails.
--*/
{
PSPOOL pSpool = (PSPOOL)hSpooler;
HANDLE hSpoolerRPC;
DWORD Status;
switch( eProtectHandle( hSpooler, TRUE )){
case kProtectHandlePendingDeletion:
return TRUE;
case kProtectHandleInvalid:
return FALSE;
default:
break;
}
hSpoolerRPC = pSpool->hPrinter;
RpcTryExcept {
Status = RpcClusterSplClose( &hSpoolerRPC );
} RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) {
Status = TranslateExceptionCode( RpcExceptionCode() );
} RpcEndExcept
if( hSpoolerRPC ){
RpcSmDestroyClientContext(&hSpoolerRPC);
}
FreeSpool( pSpool );
return TRUE;
}
BOOL
ClusterSplIsAlive(
HANDLE hSpooler
)
/*++
Routine Description:
Determines whether a spooler is still alive.
Arguments:
hSpooler - Spooler to check.
Return Value:
TRUE - Success
FALSE - Fail; LastError set.
--*/
{
PSPOOL pSpool = (PSPOOL)hSpooler;
BOOL bReturnValue = TRUE;
if( eProtectHandle( hSpooler, FALSE )){
return FALSE;
}
RpcTryExcept {
DWORD Status;
Status = RpcClusterSplIsAlive( pSpool->hPrinter );
if( Status ){
SetLastError( Status );
bReturnValue = FALSE;
}
} RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) {
SetLastError( TranslateExceptionCode( RpcExceptionCode() ));
bReturnValue = FALSE;
} RpcEndExcept
vUnprotectHandle( hSpooler );
return bReturnValue;
}