Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

261 lines
7.1 KiB

/*++
Copyright (c) 1991-1993 Microsoft Corporation
Module Name:
NetRpc.c
Abstract:
This header file contains macros which are used by the Net (NT/LAN) code
to remote APIs. These macros try using RPC, and have a fallback which
allows the use of RpcXlate (RPC translate) to a downlevel server.
There are three macros:
NET_REMOTE_TRY_RPC
Sets up to allow a call to an RPC routine in the context of an
exception handler. It then falls into code provided by the caller,
which must actually attempt the RPC call. This code must, in any
case, set a NET_API_STATUS variable.
NET_REMOTE_RPC_FAILED
Handles the exception. It then determines whether or not it is
worthwhile attempting to invoke a downlevel API. If so, it falls
into code provided by the caller, which may call the appropriate
downlevel routine. In any event, the code which is "fallen-into"
must set the same NET_API_STATUS variable as above.
For all but the service controller APIs, this gets passed a flag
of NET_REMOTE_FLAG_NORMAL. The service controller APIs must give
NET_REMOTE_FLAG_SVC_CTRL to ensure that the correct error codes are
generated and to avoid possible infinite loops.
NET_REMOTE_END
Indicates the end of the exception handler code. Falls into code
with the NET_API_STATUS variable set.
The caller *must* invoke all three macros, in the order given in these
examples. Also, the macros must not be followed by semicolons; they are
*not* statements.
Example:
NET_API_STATUS NET_API_FUNCTION
NetServerGetInfo(
IN LPTSTR UncServerName,
IN DWORD Level,
OUT LPBYTE *BufPtr
{
NET_API_STATUS apiStatus;
*BufPtr = NULL; // Must be NULL so RPC knows to fill it in.
NET_REMOTE_TRY_RPC
//
// Call RPC version of the API.
//
apiStatus = NetrServerGetInfo (
UncServerName,
Level,
(LPSERVER_INFO) BufPtr);
//
// Handle RPC failures. This will set apiStatus if it can't
// call the downlevel code.
//
NET_REMOTE_RPC_FAILED(
"NetServerGetInfo",
UncServerName,
apiStatus,
NET_REMOTE_FLAG_NORMAL,
SERVICE_SERVER )
//
// Call downlevel version of the API.
//
apiStatus = RxNetServerGetInfo (
UncServerName,
Level,
BufPtr);
NET_REMOTE_END
return (apiStatus);
} // NetServerGetInfo
Note that the calling code must set the same status variable in two
places:
- Between NET_REMOTE_TRY_RPC and NET_REMOTE_RPC_FAILED.
- Between NET_REMOTE_RPC_FAILED and NET_REMOTE_END.
The NET_REMOTE_RPC_FAILED macro will also set the status variable if
RPC failed and the remote machine doesn't support remoting of downlevel
APIs.
Another example, of an API without downlevel support:
NET_API_STATUS
NetSomeNewApi( IN LPTSTR UncServerName )
{
NET_API_STATUS stat;
NET_REMOTE_TRY_RPC
//
// Call RPC version of the API.
//
stat = NetrSomeNewApi( UncServerName );
NET_REMOTE_RPC_FAILED(
"NetSomeNewApi",
UncServerName,
stat,
NET_REMOTE_FLAG_NORMAL,
SERVICE_WORKSTATION )
//
// This API doesn't exist in downlevel servers.
//
stat = ERROR_NOT_SUPPORTED;
NET_REMOTE_END
return (stat);
} // NetSomeNewApi
Author:
John Rogers (JohnRo) 10-Jul-1991
Environment:
User mode - WIN32
Requires RPC support and exception handlers.
Requires ANSI C extensions: slash-slash comments, long external names.
Notes:
This file requires WinDef.h, NetDebug.h, Rpc.h, and
possibly others.
Revision History:
10-Jul-1991 JohnRo
Created these macros by copying code which I worked on in
SvcDlls/SrvSvc/Client/SrvStubs.c.
23-Jul-1991 JohnRo
Really use ServiceName parameter.
25-Jul-1991 JohnRo
Quiet DLL stub debug output.
31-Oct-1991 JohnRo
RAID 3414: handle explicit local server name.
Also move RPC error handling code from these macros to netlib routine.
Expanded Environmeent comments above.
07-Nov-1991 JohnRo
RAID 4186: assert in RxNetShareAdd and other DLL stub problems.
17-Jan-1992 JohnRo
Added NET_REMOTE_RPC_FAILED_W for UNICODE-only server names.
08-Apr-1992 JohnRo
Clarify that ServiceName parameter is OPTIONAL.
12-Jan-1993 JohnRo
RAID 1586: incorporated DanL's loop change as workaround for MIDL
bug which causes NetReplSetInfo to fail after the service stops.
??-???-1993 RajA
Added NERR_TryDownLevel for LM/UNIX support.
19-Apr-1993 JohnRo
Fixed a bug in RajA's version of NET_REMOTE_RPC_FAILED_W.
Added change history entry on behalf of RajA.
Changed to NT tab convention (no hard tabs; spaces every 4 cols).
Made changes suggested by PC-LINT 5.0
--*/
#ifndef _NETRPC_
#define _NETRPC_
#include <lmerr.h> // NERR_TryDownLevel.
// Values for Flags below:
#define NET_REMOTE_FLAG_NORMAL 0x00000000
#define NET_REMOTE_FLAG_SVC_CTRL 0x00000001
NET_API_STATUS
NetpHandleRpcFailure(
IN LPDEBUG_STRING DebugName,
IN RPC_STATUS RpcStatus,
IN LPTSTR ServerNameValue OPTIONAL,
IN LPTSTR ServiceName OPTIONAL,
IN DWORD Flags, // NET_REMOTE_FLAG_ stuff.
OUT LPBOOL TryDownLevel
);
#define NET_REMOTE_TRY_RPC \
{ \
INT RetryCount = 1; \
BOOL TryDownLevel = FALSE; \
Retry: \
RpcTryExcept {
/*
** Fall into code which tries RPC call to remote machine.
*/
#define NET_REMOTE_RPC_FAILED(DebugName, \
ServerNameValue, \
ApiStatusVar, \
Flags, \
ServiceName ) \
if (ApiStatusVar == NERR_TryDownLevel) \
TryDownLevel = TRUE; \
} \
RpcExcept (1) { /* exception handler */ \
\
RPC_STATUS RpcStatus; \
\
RpcStatus = RpcExceptionCode(); \
\
if (RpcStatus == RPC_S_CALL_FAILED_DNE) { \
RetryCount--; \
if (RetryCount == 0) { \
goto Retry; \
} \
} \
RetryCount = 1; \
\
ApiStatusVar = NetpHandleRpcFailure( \
DebugName, \
RpcStatus, \
(LPTSTR) ServerNameValue, \
ServiceName, \
Flags, \
& TryDownLevel); \
\
} /* exception handler */ \
RpcEndExcept \
if (TryDownLevel) {
/*
** Caller would insert a call to some RxNet routine
** here, for downlevel support.
*/
#define NET_REMOTE_END \
} /* If TryDownLevel */ \
} /* global scope */
/*
** Fall into code with ApiStatusVar set.
*/
#endif // _NETRPC_