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.

280 lines
6.7 KiB

  1. /*++
  2. Copyright (c) 1990-92 Microsoft Corporation
  3. Module Name:
  4. client.c
  5. Abstract:
  6. This file contains commonly used client-side RPC control functions.
  7. Author:
  8. Dan Lafferty danl 06-Feb-1991
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. 06-Feb-1991 danl
  13. Created
  14. 26-Apr-1991 JohnRo
  15. Split out MIDL user (allocate,free) so linker doesn't get confused.
  16. Deleted tabs.
  17. 03-July-1991 JimK
  18. Copied from LM specific file.
  19. 27-Feb-1992 JohnRo
  20. Fixed heap trashing bug in RpcpBindRpc().
  21. --*/
  22. // These must be included first:
  23. #include <nt.h> // needed for NTSTATUS
  24. #include <ntrtl.h> // needed for nturtl.h
  25. #include <nturtl.h> // needed for windows.h
  26. #include <windows.h> // win32 typedefs
  27. #include <rpc.h> // rpc prototypes
  28. #include <ntrpcp.h>
  29. #include <stdlib.h> // for wcscpy wcscat
  30. #include <tstr.h> // WCSSIZE
  31. #define NT_PIPE_PREFIX TEXT("\\PIPE\\")
  32. #define NT_PIPE_PREFIX_W L"\\PIPE\\"
  33. NTSTATUS
  34. RpcpBindRpc(
  35. IN LPWSTR ServerName,
  36. IN LPWSTR ServiceName,
  37. IN LPWSTR NetworkOptions,
  38. OUT RPC_BINDING_HANDLE * pBindingHandle
  39. )
  40. /*++
  41. Routine Description:
  42. Binds to the RPC server if possible.
  43. Arguments:
  44. ServerName - Name of server to bind with.
  45. ServiceName - Name of service to bind with.
  46. pBindingHandle - Location where binding handle is to be placed
  47. Return Value:
  48. STATUS_SUCCESS - The binding has been successfully completed.
  49. STATUS_INVALID_COMPUTER_NAME - The ServerName syntax is invalid.
  50. STATUS_NO_MEMORY - There is not sufficient memory available to the
  51. caller to perform the binding.
  52. --*/
  53. {
  54. NTSTATUS Status;
  55. RPC_STATUS RpcStatus;
  56. LPWSTR StringBinding;
  57. LPWSTR Endpoint;
  58. WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  59. DWORD bufLen;
  60. LPWSTR AllocatedServerName = NULL;
  61. LPWSTR UncServerName = NULL;
  62. *pBindingHandle = NULL;
  63. if ( ServerName != NULL ) {
  64. DWORD ServerNameLength = wcslen(ServerName);
  65. //
  66. // Canonicalize the server name
  67. //
  68. if ( ServerName[0] == L'\0' ) {
  69. ServerName = NULL;
  70. UncServerName = NULL;
  71. } else if ( ServerName[0] == L'\\' && ServerName[1] == L'\\' ) {
  72. UncServerName = ServerName;
  73. ServerName += 2;
  74. ServerNameLength -= 2;
  75. if ( ServerNameLength == 0 ) {
  76. Status = STATUS_INVALID_COMPUTER_NAME;
  77. goto Cleanup;
  78. }
  79. } else {
  80. AllocatedServerName = LocalAlloc( 0, (ServerNameLength+2+1) * sizeof(WCHAR) );
  81. if ( AllocatedServerName == NULL ) {
  82. Status = STATUS_NO_MEMORY;
  83. goto Cleanup;
  84. }
  85. AllocatedServerName[0] = L'\\';
  86. AllocatedServerName[1] = L'\\';
  87. RtlCopyMemory( &AllocatedServerName[2],
  88. ServerName,
  89. (ServerNameLength+1) * sizeof(WCHAR) );
  90. UncServerName = AllocatedServerName;
  91. }
  92. //
  93. // If the passed in computer name is the netbios name of this machine,
  94. // drop the computer name so we can avoid the overhead of the redir/server/authentication.
  95. //
  96. if ( ServerName != NULL && ServerNameLength <= MAX_COMPUTERNAME_LENGTH ) {
  97. bufLen = MAX_COMPUTERNAME_LENGTH + 1;
  98. if (GetComputerNameW( ComputerName, &bufLen )) {
  99. if ( ServerNameLength == bufLen &&
  100. _wcsnicmp( ComputerName, ServerName, ServerNameLength) == 0 ) {
  101. ServerName = NULL;
  102. UncServerName = NULL;
  103. }
  104. }
  105. }
  106. //
  107. // If the passed in computer name is the DNS host name of this machine,
  108. // drop the computer name so we can avoid the overhead of the redir/server/authentication.
  109. //
  110. if ( ServerName != NULL ) {
  111. LPWSTR DnsHostName;
  112. //
  113. // Further canonicalize the ServerName.
  114. //
  115. if ( ServerName[ServerNameLength-1] == L'.' ) {
  116. ServerNameLength -= 1;
  117. }
  118. DnsHostName = LocalAlloc( 0, (MAX_PATH+1) * sizeof(WCHAR));
  119. if ( DnsHostName == NULL) {
  120. Status = STATUS_NO_MEMORY;
  121. goto Cleanup;
  122. }
  123. bufLen = MAX_PATH + 1;
  124. if ( GetComputerNameExW(
  125. ComputerNameDnsFullyQualified,
  126. DnsHostName,
  127. &bufLen ) ) {
  128. if ( ServerNameLength == bufLen &&
  129. _wcsnicmp( DnsHostName, ServerName, ServerNameLength) == 0 ) {
  130. ServerName = NULL;
  131. UncServerName = NULL;
  132. }
  133. }
  134. LocalFree( DnsHostName );
  135. }
  136. }
  137. // We need to concatenate \pipe\ to the front of the service
  138. // name.
  139. Endpoint = (LPWSTR)LocalAlloc(
  140. 0,
  141. sizeof(NT_PIPE_PREFIX_W) + WCSSIZE(ServiceName));
  142. if (Endpoint == 0) {
  143. Status = STATUS_NO_MEMORY;
  144. goto Cleanup;
  145. }
  146. wcscpy(Endpoint,NT_PIPE_PREFIX_W);
  147. wcscat(Endpoint,ServiceName);
  148. RpcStatus = RpcStringBindingComposeW(0, L"ncacn_np", UncServerName,
  149. Endpoint, NetworkOptions, &StringBinding);
  150. LocalFree(Endpoint);
  151. if ( RpcStatus != RPC_S_OK ) {
  152. Status = STATUS_NO_MEMORY;
  153. goto Cleanup;
  154. }
  155. //
  156. // Get an actual binding handle.
  157. //
  158. RpcStatus = RpcBindingFromStringBindingW(StringBinding, pBindingHandle);
  159. RpcStringFreeW(&StringBinding);
  160. if ( RpcStatus != RPC_S_OK ) {
  161. *pBindingHandle = NULL;
  162. if ( RpcStatus == RPC_S_INVALID_ENDPOINT_FORMAT ||
  163. RpcStatus == RPC_S_INVALID_NET_ADDR ) {
  164. Status = STATUS_INVALID_COMPUTER_NAME;
  165. } else {
  166. Status = STATUS_NO_MEMORY;
  167. }
  168. goto Cleanup;
  169. }
  170. Status = STATUS_SUCCESS;
  171. Cleanup:
  172. if ( AllocatedServerName != NULL ) {
  173. LocalFree( AllocatedServerName );
  174. }
  175. return Status;
  176. }
  177. NTSTATUS
  178. RpcpUnbindRpc(
  179. IN RPC_BINDING_HANDLE BindingHandle
  180. )
  181. /*++
  182. Routine Description:
  183. Unbinds from the RPC interface.
  184. If we decide to cache bindings, this routine will do something more
  185. interesting.
  186. Arguments:
  187. BindingHandle - This points to the binding handle that is to be closed.
  188. Return Value:
  189. STATUS_SUCCESS - the unbinding was successful.
  190. --*/
  191. {
  192. RPC_STATUS RpcStatus;
  193. if (BindingHandle != NULL) {
  194. RpcStatus = RpcBindingFree(&BindingHandle);
  195. // ASSERT(RpcStatus == RPC_S_OK);
  196. }
  197. return(STATUS_SUCCESS);
  198. }