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.

584 lines
14 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. svcxport.c
  5. Abstract:
  6. This module contains routines for supporting the transport APIs in the
  7. server service, NetServerTransportAdd, NetServerTransportDel,
  8. and NetServerTransportEnum.
  9. Author:
  10. David Treadwell (davidtr) 6-Mar-1991
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #include "svcxport.tmh"
  15. #pragma hdrstop
  16. //
  17. // Forward declarations.
  18. //
  19. VOID
  20. FillTransportInfoBuffer (
  21. IN PSERVER_REQUEST_PACKET Srp,
  22. IN PVOID Block,
  23. IN OUT PVOID *FixedStructure,
  24. IN LPWSTR *EndOfVariableData
  25. );
  26. BOOLEAN
  27. FilterTransports (
  28. IN PSERVER_REQUEST_PACKET Srp,
  29. IN PVOID Block
  30. );
  31. ULONG
  32. SizeTransports (
  33. IN PSERVER_REQUEST_PACKET Srp,
  34. IN PVOID Block
  35. );
  36. #ifdef ALLOC_PRAGMA
  37. #pragma alloc_text( PAGE, SrvNetServerTransportAdd )
  38. #pragma alloc_text( PAGE, SrvNetServerTransportDel )
  39. #pragma alloc_text( PAGE, SrvNetServerTransportEnum )
  40. #pragma alloc_text( PAGE, FillTransportInfoBuffer )
  41. #pragma alloc_text( PAGE, FilterTransports )
  42. #pragma alloc_text( PAGE, SizeTransports )
  43. #endif
  44. NTSTATUS
  45. SrvNetServerTransportAdd (
  46. IN PSERVER_REQUEST_PACKET Srp,
  47. IN PVOID Buffer,
  48. IN ULONG BufferLength
  49. )
  50. /*++
  51. Routine Description:
  52. This routine processes the NetServerTransportAdd API in the server
  53. FSP. Because it opens an object (the transport device object) it
  54. must be done in the server FSP, not the FSD.
  55. Arguments:
  56. Srp - a pointer to the server request packet that contains all
  57. the information necessary to satisfy the request. This includes:
  58. INPUT:
  59. None.
  60. OUTPUT:
  61. None.
  62. Buffer - a pointer to a TRANSPORT_INFO_0 structure for the new
  63. transport. All pointers should have been changed to offsets
  64. within the buffer.
  65. BufferLength - total length of this buffer.
  66. Return Value:
  67. NTSTATUS - result of operation to return to the server service.
  68. --*/
  69. {
  70. NTSTATUS status;
  71. PSERVER_TRANSPORT_INFO_3 svti3;
  72. UNICODE_STRING transportName;
  73. UNICODE_STRING domainName;
  74. ANSI_STRING transportAddress;
  75. UNICODE_STRING netName;
  76. PAGED_CODE( );
  77. //
  78. // Convert the offsets in the transport data structure to pointers.
  79. // Also make sure that all the pointers are within the specified
  80. // buffer.
  81. //
  82. svti3 = Buffer;
  83. OFFSET_TO_POINTER( svti3->svti3_transportname, svti3 );
  84. OFFSET_TO_POINTER( svti3->svti3_transportaddress, svti3 );
  85. OFFSET_TO_POINTER( svti3->svti3_domain, svti3 );
  86. if ( !POINTER_IS_VALID( svti3->svti3_transportname, svti3, BufferLength ) ||
  87. !POINTER_IS_VALID( svti3->svti3_transportaddress, svti3, BufferLength ) ||
  88. !POINTER_IS_VALID( svti3->svti3_domain, svti3, BufferLength ) ) {
  89. IF_DEBUG( ERRORS ) {
  90. KdPrint(( "SrvNetServerTransportAdd: Bad pointers\n" ));
  91. }
  92. return STATUS_ACCESS_VIOLATION;
  93. }
  94. if( svti3->svti3_passwordlength > sizeof( svti3->svti3_password ) ) {
  95. IF_DEBUG( ERRORS ) {
  96. KdPrint(( "SrvNetServerTransportAdd: svti3_passwordlength %d\n", svti3->svti3_passwordlength ));
  97. }
  98. return STATUS_INVALID_PARAMETER;
  99. }
  100. //
  101. // Set up the transport name, server name, domain name, and net name.
  102. //
  103. RtlInitUnicodeString( &transportName, (PWCH)svti3->svti3_transportname );
  104. netName.Buffer = NULL;
  105. netName.Length = 0;
  106. netName.MaximumLength = 0;
  107. RtlInitUnicodeString( &domainName, (PWCH)svti3->svti3_domain );
  108. transportAddress.Buffer = svti3->svti3_transportaddress;
  109. transportAddress.Length = (USHORT)svti3->svti3_transportaddresslength;
  110. transportAddress.MaximumLength = (USHORT)svti3->svti3_transportaddresslength;
  111. //
  112. // Attempt to add the new transport to the server.
  113. //
  114. IF_DEBUG( PNP ) {
  115. KdPrint(( "SRV: SrvNetServerTransportAdd: %wZ\n", &transportName ));
  116. }
  117. status = SrvAddServedNet( &netName,
  118. &transportName,
  119. &transportAddress,
  120. &domainName,
  121. Srp->Flags & SRP_XADD_FLAGS,
  122. svti3->svti3_passwordlength,
  123. svti3->svti3_password
  124. );
  125. IF_DEBUG( PNP ) {
  126. KdPrint(( "SRV: SrvNetServerTransportAdd: %wZ, status %X\n", &transportName, status ));
  127. }
  128. return status;
  129. } // SrvNetServerTransportAdd
  130. NTSTATUS
  131. SrvNetServerTransportDel (
  132. IN PSERVER_REQUEST_PACKET Srp,
  133. IN PVOID Buffer,
  134. IN ULONG BufferLength
  135. )
  136. /*++
  137. Routine Description:
  138. This routine processes the NetServerTransportEnum API in the server
  139. FSD.
  140. Arguments:
  141. Srp - a pointer to the server request packet that contains all
  142. the information necessary to satisfy the request. This includes:
  143. Buffer - a pointer to a TRANSPORT_INFO_0 structure for the
  144. transport. All pointers should have been changed to offsets
  145. within the buffer.
  146. BufferLength - total length of this buffer.
  147. Return Value:
  148. NTSTATUS - result of operation to return to the server service.
  149. --*/
  150. {
  151. NTSTATUS status;
  152. PSERVER_TRANSPORT_INFO_3 svti3;
  153. UNICODE_STRING transportName;
  154. ANSI_STRING transportAddress;
  155. PAGED_CODE( );
  156. Srp;
  157. //
  158. // Convert the offsets in the transport data structure to pointers.
  159. // Also make sure that all the pointers are within the specified
  160. // buffer.
  161. //
  162. svti3 = Buffer;
  163. OFFSET_TO_POINTER( svti3->svti3_transportname, svti3 );
  164. if ( !POINTER_IS_VALID( svti3->svti3_transportname, svti3, BufferLength ) ) {
  165. IF_DEBUG( ERRORS ) {
  166. KdPrint(("SrvNetServerTransportDel: STATUS_ACCESS_VIOLATION at %u\n", __LINE__ ));
  167. }
  168. return STATUS_ACCESS_VIOLATION;
  169. }
  170. RtlInitUnicodeString( &transportName, (PWCH)svti3->svti3_transportname );
  171. transportAddress.Length = (USHORT)svti3->svti3_transportaddresslength;
  172. transportAddress.MaximumLength = (USHORT)svti3->svti3_transportaddresslength;
  173. if( transportAddress.Length != 0 ) {
  174. OFFSET_TO_POINTER( svti3->svti3_transportaddress, svti3 );
  175. if( !POINTER_IS_VALID( svti3->svti3_transportaddress, svti3, BufferLength ) ) {
  176. IF_DEBUG( ERRORS ) {
  177. KdPrint(("SrvNetServerTransportDel: STATUS_ACCESS_VIOLATION at %u\n", __LINE__ ));
  178. }
  179. return STATUS_ACCESS_VIOLATION;
  180. }
  181. transportAddress.Buffer = svti3->svti3_transportaddress;
  182. }
  183. //
  184. // Attempt to delete the transport endpoint from the server.
  185. //
  186. status = SrvDeleteServedNet( &transportName, &transportAddress );
  187. IF_DEBUG( ERRORS ) {
  188. if( !NT_SUCCESS( status ) ) {
  189. KdPrint(( "SrvNetServerTransportDel: SrvDeleteServedNet status %X\n", status ));
  190. }
  191. }
  192. return status;
  193. } // SrvNetServerTransportDel
  194. NTSTATUS
  195. SrvNetServerTransportEnum (
  196. IN PSERVER_REQUEST_PACKET Srp,
  197. IN PVOID Buffer,
  198. IN ULONG BufferLength
  199. )
  200. /*++
  201. Routine Description:
  202. This routine processes the NetServerTransportEnum API in the server
  203. FSD.
  204. Arguments:
  205. Srp - a pointer to the server request packet that contains all
  206. the information necessary to satisfy the request. This includes:
  207. INPUT:
  208. None.
  209. OUTPUT:
  210. Parameters.Get.EntriesRead - the number of entries that fit in
  211. the output buffer.
  212. Parameters.Get.TotalEntries - the total number of entries that
  213. would be returned with a large enough buffer.
  214. Parameters.Get.TotalBytesNeeded - the buffer size that would be
  215. required to hold all the entries.
  216. Buffer - a pointer to a TRANSPORT_INFO_0 structure for the new
  217. transport. All pointers should have been changed to offsets
  218. within the buffer.
  219. BufferLength - total length of this buffer.
  220. Return Value:
  221. NTSTATUS - result of operation to return to the server service.
  222. --*/
  223. {
  224. PAGED_CODE( );
  225. return SrvEnumApiHandler(
  226. Srp,
  227. Buffer,
  228. BufferLength,
  229. &SrvEndpointList,
  230. FilterTransports,
  231. SizeTransports,
  232. FillTransportInfoBuffer
  233. );
  234. } // SrvNetServerTransportEnum
  235. VOID
  236. FillTransportInfoBuffer (
  237. IN PSERVER_REQUEST_PACKET Srp,
  238. IN PVOID Block,
  239. IN OUT PVOID *FixedStructure,
  240. IN LPWSTR *EndOfVariableData
  241. )
  242. /*++
  243. Routine Description:
  244. This routine puts a single fixed transport structure and, if it fits,
  245. associated variable data, into a buffer. Fixed data goes at the
  246. beginning of the buffer, variable data at the end.
  247. Arguments:
  248. Endpoint - the endpoint from which to get information.
  249. FixedStructure - where the in the buffer to place the fixed structure.
  250. This pointer is updated to point to the next available
  251. position for a fixed structure.
  252. EndOfVariableData - the last position on the buffer that variable
  253. data for this structure can occupy. The actual variable data
  254. is written before this position as long as it won't overwrite
  255. fixed structures. It is would overwrite fixed structures, it
  256. is not written.
  257. Return Value:
  258. None.
  259. --*/
  260. {
  261. PENDPOINT endpoint = Block;
  262. PSERVER_TRANSPORT_INFO_1 svti1 = *FixedStructure;
  263. ULONG TransportAddressLength;
  264. PAGED_CODE( );
  265. //
  266. // Update FixedStructure to point to the next structure location.
  267. //
  268. *FixedStructure = (PCHAR)*FixedStructure +
  269. (Srp->Level ? sizeof( SERVER_TRANSPORT_INFO_1 ) : sizeof( SERVER_TRANSPORT_INFO_0 ));
  270. ASSERT( (ULONG_PTR)*EndOfVariableData >= (ULONG_PTR)*FixedStructure );
  271. //
  272. // The number of VCs on the endpoint is equal to the total number
  273. // of connections on the endpoint less the free connections.
  274. //
  275. ACQUIRE_LOCK_SHARED( &SrvEndpointLock );
  276. svti1->svti1_numberofvcs =
  277. endpoint->TotalConnectionCount - endpoint->FreeConnectionCount;
  278. RELEASE_LOCK( &SrvEndpointLock );
  279. //
  280. // Copy over the transport name.
  281. //
  282. SrvCopyUnicodeStringToBuffer(
  283. &endpoint->TransportName,
  284. *FixedStructure,
  285. EndOfVariableData,
  286. &svti1->svti1_transportname
  287. );
  288. //
  289. // Copy over the network name.
  290. //
  291. SrvCopyUnicodeStringToBuffer(
  292. &endpoint->NetworkAddress,
  293. *FixedStructure,
  294. EndOfVariableData,
  295. &svti1->svti1_networkaddress
  296. );
  297. //
  298. // Copy over the domain name
  299. //
  300. if( Srp->Level > 0 ) {
  301. SrvCopyUnicodeStringToBuffer(
  302. &endpoint->DomainName,
  303. *FixedStructure,
  304. EndOfVariableData,
  305. &svti1->svti1_domain
  306. );
  307. }
  308. //
  309. // Copy over the transport address. We have to manually check here
  310. // whether it will fit in the output buffer.
  311. //
  312. //
  313. // Don't copy the trailing blanks of the transport address.
  314. //
  315. for ( TransportAddressLength = endpoint->TransportAddress.Length;
  316. TransportAddressLength > 0 && endpoint->TransportAddress.Buffer[TransportAddressLength-1] == ' ' ;
  317. TransportAddressLength-- ) ;
  318. *EndOfVariableData = (LPWSTR)( (PCHAR)*EndOfVariableData - TransportAddressLength );
  319. //
  320. // Ensure we remain byte aligned, so knock off the low bit if necessary. Remember, we
  321. // are filling backwards from the end of the buffer so we want to round the address down
  322. //
  323. *EndOfVariableData = (LPWSTR)( (ULONG_PTR)*EndOfVariableData & ~1 );
  324. if ( (ULONG_PTR)*EndOfVariableData > (ULONG_PTR)*FixedStructure ) {
  325. //
  326. // The address will fit. Copy it over to the output buffer.
  327. //
  328. RtlCopyMemory(
  329. *EndOfVariableData,
  330. endpoint->TransportAddress.Buffer,
  331. TransportAddressLength
  332. );
  333. svti1->svti1_transportaddress = (LPBYTE)*EndOfVariableData;
  334. svti1->svti1_transportaddresslength = TransportAddressLength;
  335. } else {
  336. svti1->svti1_transportaddress = NULL;
  337. svti1->svti1_transportaddresslength = 0;
  338. }
  339. return;
  340. } // FillTransportInfoBuffer
  341. BOOLEAN
  342. FilterTransports (
  343. IN PSERVER_REQUEST_PACKET Srp,
  344. IN PVOID Block
  345. )
  346. /*++
  347. Routine Description:
  348. This routine just returns TRUE since we always want to place
  349. information about all transports in the output buffer for a
  350. NetServerTransportEnum.
  351. Arguments:
  352. Srp - not used.
  353. Block - not used.
  354. Return Value:
  355. TRUE.
  356. --*/
  357. {
  358. PENDPOINT endpoint = Block;
  359. PAGED_CODE( );
  360. Srp, Block;
  361. //
  362. // We filter out AlternateEndpoint since they are endpoints we've
  363. // created ourselves.
  364. //
  365. if (endpoint->AlternateAddressFormat) {
  366. return FALSE;
  367. }
  368. //
  369. // We always return information about all transports.
  370. //
  371. return TRUE;
  372. } // FilterFiles
  373. ULONG
  374. SizeTransports (
  375. IN PSERVER_REQUEST_PACKET Srp,
  376. IN PVOID Block
  377. )
  378. /*++
  379. Routine Description:
  380. This routine returns the size the passed-in endpoint would take up
  381. in an API output buffer.
  382. Arguments:
  383. Srp - not used.
  384. Block - a pointer to the endpoint to size.
  385. Return Value:
  386. ULONG - The number of bytes the endpoint would take up in the
  387. output buffer.
  388. --*/
  389. {
  390. PENDPOINT endpoint = Block;
  391. ULONG size;
  392. PAGED_CODE( );
  393. size = Srp->Level ? sizeof( SERVER_TRANSPORT_INFO_1 ) : sizeof( SERVER_TRANSPORT_INFO_0 );
  394. size += SrvLengthOfStringInApiBuffer(&(endpoint)->TransportName);
  395. size += (endpoint)->TransportAddress.Length + sizeof(TCHAR);
  396. size += SrvLengthOfStringInApiBuffer(&(endpoint)->NetworkAddress);
  397. if( Srp->Level ) {
  398. size += SrvLengthOfStringInApiBuffer( &(endpoint)->DomainName );
  399. }
  400. return size;
  401. } // SizeTransports