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.

266 lines
7.5 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. NetRpc.c
  5. Abstract:
  6. This header file contains macros which are used by the Net (NT/LAN) code
  7. to remote APIs. These macros try using RPC, and have a fallback which
  8. allows the use of RpcXlate (RPC translate) to a downlevel server.
  9. There are three macros:
  10. NET_REMOTE_TRY_RPC
  11. Sets up to allow a call to an RPC routine in the context of an
  12. exception handler. It then falls into code provided by the caller,
  13. which must actually attempt the RPC call. This code must, in any
  14. case, set a NET_API_STATUS variable.
  15. NET_REMOTE_RPC_FAILED
  16. Handles the exception. It then determines whether or not it is
  17. worthwhile attempting to invoke a downlevel API. If so, it falls
  18. into code provided by the caller, which may call the appropriate
  19. downlevel routine. In any event, the code which is "fallen-into"
  20. must set the same NET_API_STATUS variable as above.
  21. For all but the service controller APIs, this gets passed a flag
  22. of NET_REMOTE_FLAG_NORMAL. The service controller APIs must give
  23. NET_REMOTE_FLAG_SVC_CTRL to ensure that the correct error codes are
  24. generated and to avoid possible infinite loops.
  25. NET_REMOTE_END
  26. Indicates the end of the exception handler code. Falls into code
  27. with the NET_API_STATUS variable set.
  28. The caller *must* invoke all three macros, in the order given in these
  29. examples. Also, the macros must not be followed by semicolons; they are
  30. *not* statements.
  31. Example:
  32. NET_API_STATUS NET_API_FUNCTION
  33. NetServerGetInfo(
  34. IN LPTSTR UncServerName,
  35. IN DWORD Level,
  36. OUT LPBYTE *BufPtr
  37. {
  38. NET_API_STATUS apiStatus;
  39. *BufPtr = NULL; // Must be NULL so RPC knows to fill it in.
  40. NET_REMOTE_TRY_RPC
  41. //
  42. // Call RPC version of the API.
  43. //
  44. apiStatus = NetrServerGetInfo (
  45. UncServerName,
  46. Level,
  47. (LPSERVER_INFO) BufPtr);
  48. //
  49. // Handle RPC failures. This will set apiStatus if it can't
  50. // call the downlevel code.
  51. //
  52. NET_REMOTE_RPC_FAILED(
  53. "NetServerGetInfo",
  54. UncServerName,
  55. apiStatus,
  56. NET_REMOTE_FLAG_NORMAL,
  57. SERVICE_SERVER )
  58. //
  59. // Call downlevel version of the API.
  60. //
  61. apiStatus = RxNetServerGetInfo (
  62. UncServerName,
  63. Level,
  64. BufPtr);
  65. NET_REMOTE_END
  66. return (apiStatus);
  67. } // NetServerGetInfo
  68. Note that the calling code must set the same status variable in two
  69. places:
  70. - Between NET_REMOTE_TRY_RPC and NET_REMOTE_RPC_FAILED.
  71. - Between NET_REMOTE_RPC_FAILED and NET_REMOTE_END.
  72. The NET_REMOTE_RPC_FAILED macro will also set the status variable if
  73. RPC failed and the remote machine doesn't support remoting of downlevel
  74. APIs.
  75. Another example, of an API without downlevel support:
  76. NET_API_STATUS
  77. NetSomeNewApi( IN LPTSTR UncServerName )
  78. {
  79. NET_API_STATUS stat;
  80. NET_REMOTE_TRY_RPC
  81. //
  82. // Call RPC version of the API.
  83. //
  84. stat = NetrSomeNewApi( UncServerName );
  85. NET_REMOTE_RPC_FAILED(
  86. "NetSomeNewApi",
  87. UncServerName,
  88. stat,
  89. NET_REMOTE_FLAG_NORMAL,
  90. SERVICE_WORKSTATION )
  91. //
  92. // This API doesn't exist in downlevel servers.
  93. //
  94. stat = ERROR_NOT_SUPPORTED;
  95. NET_REMOTE_END
  96. return (stat);
  97. } // NetSomeNewApi
  98. Author:
  99. John Rogers (JohnRo) 10-Jul-1991
  100. Environment:
  101. User mode - WIN32
  102. Requires RPC support and exception handlers.
  103. Requires ANSI C extensions: slash-slash comments, long external names.
  104. Notes:
  105. This file requires WinDef.h, NetDebug.h, Rpc.h, and
  106. possibly others.
  107. Revision History:
  108. 10-Jul-1991 JohnRo
  109. Created these macros by copying code which I worked on in
  110. SvcDlls/SrvSvc/Client/SrvStubs.c.
  111. 23-Jul-1991 JohnRo
  112. Really use ServiceName parameter.
  113. 25-Jul-1991 JohnRo
  114. Quiet DLL stub debug output.
  115. 31-Oct-1991 JohnRo
  116. RAID 3414: handle explicit local server name.
  117. Also move RPC error handling code from these macros to netlib routine.
  118. Expanded Environmeent comments above.
  119. 07-Nov-1991 JohnRo
  120. RAID 4186: assert in RxNetShareAdd and other DLL stub problems.
  121. 17-Jan-1992 JohnRo
  122. Added NET_REMOTE_RPC_FAILED_W for UNICODE-only server names.
  123. 08-Apr-1992 JohnRo
  124. Clarify that ServiceName parameter is OPTIONAL.
  125. 12-Jan-1993 JohnRo
  126. RAID 1586: incorporated DanL's loop change as workaround for MIDL
  127. bug which causes NetReplSetInfo to fail after the service stops.
  128. ??-???-1993 RajA
  129. Added NERR_TryDownLevel for LM/UNIX support.
  130. 19-Apr-1993 JohnRo
  131. Fixed a bug in RajA's version of NET_REMOTE_RPC_FAILED_W.
  132. Added change history entry on behalf of RajA.
  133. Changed to NT tab convention (no hard tabs; spaces every 4 cols).
  134. Made changes suggested by PC-LINT 5.0
  135. --*/
  136. #ifndef _NETRPC_
  137. #define _NETRPC_
  138. #include <nt.h>
  139. #include <ntrtl.h>
  140. #include <nturtl.h>
  141. #include <windows.h>
  142. #include <lmerr.h> // NERR_TryDownLevel
  143. #include <rpcasync.h> // I_RpcExceptionFilter
  144. // Values for Flags below:
  145. #define NET_REMOTE_FLAG_NORMAL 0x00000000
  146. #define NET_REMOTE_FLAG_SVC_CTRL 0x00000001
  147. NET_API_STATUS
  148. NetpHandleRpcFailure(
  149. IN LPDEBUG_STRING DebugName,
  150. IN RPC_STATUS RpcStatus,
  151. IN LPTSTR ServerNameValue OPTIONAL,
  152. IN LPTSTR ServiceName OPTIONAL,
  153. IN DWORD Flags, // NET_REMOTE_FLAG_ stuff.
  154. OUT LPBOOL TryDownLevel
  155. );
  156. #define NET_REMOTE_TRY_RPC \
  157. { \
  158. INT RetryCount = 1; \
  159. BOOL TryDownLevel = FALSE; \
  160. Retry: \
  161. RpcTryExcept {
  162. /*
  163. ** Fall into code which tries RPC call to remote machine.
  164. */
  165. #define NET_REMOTE_RPC_FAILED(DebugName, \
  166. ServerNameValue, \
  167. ApiStatusVar, \
  168. Flags, \
  169. ServiceName ) \
  170. if (ApiStatusVar == NERR_TryDownLevel) \
  171. TryDownLevel = TRUE; \
  172. } \
  173. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { \
  174. \
  175. RPC_STATUS RpcStatus; \
  176. \
  177. RpcStatus = RpcExceptionCode(); \
  178. \
  179. if (RpcStatus == RPC_S_CALL_FAILED_DNE) { \
  180. RetryCount--; \
  181. if (RetryCount == 0) { \
  182. goto Retry; \
  183. } \
  184. } \
  185. RetryCount = 1; \
  186. \
  187. ApiStatusVar = NetpHandleRpcFailure( \
  188. DebugName, \
  189. RpcStatus, \
  190. (LPTSTR) ServerNameValue, \
  191. ServiceName, \
  192. Flags, \
  193. & TryDownLevel); \
  194. \
  195. } /* exception handler */ \
  196. RpcEndExcept \
  197. if (TryDownLevel) {
  198. /*
  199. ** Caller would insert a call to some RxNet routine
  200. ** here, for downlevel support.
  201. */
  202. #define NET_REMOTE_END \
  203. } /* If TryDownLevel */ \
  204. } /* global scope */
  205. /*
  206. ** Fall into code with ApiStatusVar set.
  207. */
  208. #endif // _NETRPC_