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.

404 lines
10 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. lpc.c
  5. Abstract:
  6. This module contains the code necessary to support sites using
  7. lpc upcalls from the dfs driver.
  8. Author:
  9. Jim Harper (JHarper) 11-Dec-97
  10. Revision History:
  11. --*/
  12. #include "dfsprocs.h"
  13. #include "dfslpc.h"
  14. #include <dfssrv.h>
  15. #pragma hdrstop
  16. #include "fsctrl.h"
  17. #include "ipsup.h"
  18. typedef struct {
  19. WORK_QUEUE_ITEM WorkQueueItem;
  20. } DFS_CONNECT_ARG, *PDFS_CONNECT_ARG;
  21. typedef struct {
  22. WORK_QUEUE_ITEM WorkQueueItem;
  23. DFS_IPADDRESS IpAddress;
  24. } DFS_REQUEST_ARG, *PDFS_REQUEST_ARG;
  25. VOID
  26. DfsLpcConnect (
  27. IN PDFS_CONNECT_ARG DfsConnectArg
  28. );
  29. #define Dbg 0x2000
  30. #ifdef ALLOC_PRAGMA
  31. #pragma alloc_text( PAGE, DfsLpcConnect )
  32. #pragma alloc_text( PAGE, DfsLpcIpRequest )
  33. #pragma alloc_text( PAGE, DfsLpcDomRequest )
  34. #pragma alloc_text( PAGE, DfsLpcDisconnect )
  35. #endif
  36. VOID
  37. DfsLpcConnect (
  38. IN PDFS_CONNECT_ARG DfsConnectArg)
  39. {
  40. NTSTATUS status = STATUS_SUCCESS;
  41. SECURITY_QUALITY_OF_SERVICE dynamicQos;
  42. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  43. DebugTrace(+1, Dbg, "DfsLpcConnect(Name=%wZ)\n",
  44. &pLpcInfo->LpcPortName);
  45. DebugTrace( 0, Dbg, "DfsLpcConnect(Handle=0x%x)\n",
  46. &pLpcInfo->LpcPortHandle);
  47. PAGED_CODE();
  48. dynamicQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  49. dynamicQos.ImpersonationLevel = SecurityAnonymous;
  50. dynamicQos.ContextTrackingMode = SECURITY_STATIC_TRACKING;
  51. dynamicQos.EffectiveOnly = TRUE;
  52. ExAcquireResourceExclusiveLite( &pLpcInfo->LpcPortResource, TRUE );
  53. ASSERT(pLpcInfo->LpcPortName.Buffer != NULL);
  54. pLpcInfo->LpcPortState = LPC_STATE_INITIALIZED;
  55. status = NtConnectPort(
  56. &pLpcInfo->LpcPortHandle,
  57. &pLpcInfo->LpcPortName,
  58. &dynamicQos,
  59. NULL, // ClientView
  60. NULL, // ServerView
  61. NULL, // MaxMessageLength
  62. NULL, // ConnectionInformation
  63. NULL // ConnectionInformationLength
  64. );
  65. DebugTrace(-1, Dbg, "DfsLpcConnect: NtConnectPort returned 0x%x\n", ULongToPtr( status ));
  66. if (!NT_SUCCESS(status)) {
  67. pLpcInfo->LpcPortState = LPC_STATE_UNINITIALIZED;
  68. if ( pLpcInfo->LpcPortHandle != NULL ) {
  69. NtClose( pLpcInfo->LpcPortHandle);
  70. pLpcInfo->LpcPortHandle = NULL;
  71. }
  72. if (pLpcInfo->LpcPortName.Buffer != NULL) {
  73. ExFreePool(pLpcInfo->LpcPortName.Buffer);
  74. RtlInitUnicodeString(&pLpcInfo->LpcPortName, NULL);
  75. }
  76. }
  77. ExReleaseResourceLite( &pLpcInfo->LpcPortResource );
  78. ExFreePool(DfsConnectArg);
  79. return;
  80. }
  81. NTSTATUS
  82. DfsLpcIpRequest (
  83. PDFS_IPADDRESS pIpAddress)
  84. {
  85. NTSTATUS status;
  86. DFSSRV_REQUEST_MESSAGE requestMessage;
  87. DFSSRV_REPLY_MESSAGE replyMessage;
  88. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  89. PAGED_CODE();
  90. requestMessage.Message.GetSiteName.IpAddress = *pIpAddress;
  91. //
  92. // Set up the message to send over the port.
  93. //
  94. requestMessage.PortMessage.u1.s1.DataLength =
  95. (USHORT)( sizeof(requestMessage) - sizeof(PORT_MESSAGE) );
  96. requestMessage.PortMessage.u1.s1.TotalLength = sizeof(requestMessage);
  97. requestMessage.PortMessage.u2.ZeroInit = 0;
  98. requestMessage.MessageType = DFSSRV_MESSAGE_GET_SITE_NAME;
  99. //
  100. // Send the message and wait for a response message.
  101. //
  102. status = NtRequestWaitReplyPort(
  103. pLpcInfo->LpcPortHandle,
  104. (PPORT_MESSAGE)&requestMessage,
  105. (PPORT_MESSAGE)&replyMessage
  106. );
  107. if ( !NT_SUCCESS(status) ) {
  108. goto exit;
  109. }
  110. //
  111. // Check the status returned in the reply.
  112. //
  113. status = replyMessage.Message.Result.Status;
  114. exit:
  115. return status;
  116. }
  117. NTSTATUS
  118. DfsLpcDomRequest (
  119. PUNICODE_STRING pFtName)
  120. {
  121. NTSTATUS status;
  122. DFSSRV_REQUEST_MESSAGE requestMessage;
  123. DFSSRV_REPLY_MESSAGE replyMessage;
  124. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  125. PAGED_CODE();
  126. if ( pFtName->Length > ((MAX_FTNAME_LEN - 1) * sizeof(WCHAR))) {
  127. return STATUS_INSUFFICIENT_RESOURCES;
  128. }
  129. RtlZeroMemory(requestMessage.Message.GetFtDfs.FtName, MAX_FTNAME_LEN * sizeof(WCHAR));
  130. RtlCopyMemory(requestMessage.Message.GetFtDfs.FtName, pFtName->Buffer, pFtName->Length);
  131. //
  132. // Set up the message to send over the port.
  133. //
  134. requestMessage.PortMessage.u1.s1.DataLength =
  135. (USHORT)( sizeof(requestMessage) - sizeof(PORT_MESSAGE) );
  136. requestMessage.PortMessage.u1.s1.TotalLength = sizeof(requestMessage);
  137. requestMessage.PortMessage.u2.ZeroInit = 0;
  138. requestMessage.MessageType = DFSSRV_MESSAGE_GET_DOMAIN_REFERRAL;
  139. //
  140. // Send the message and wait for a response message.
  141. //
  142. status = NtRequestWaitReplyPort(
  143. pLpcInfo->LpcPortHandle,
  144. (PPORT_MESSAGE)&requestMessage,
  145. (PPORT_MESSAGE)&replyMessage
  146. );
  147. if ( !NT_SUCCESS(status) ) {
  148. goto exit;
  149. }
  150. //
  151. // Check the status returned in the reply.
  152. //
  153. status = replyMessage.Message.Result.Status;
  154. exit:
  155. return status;
  156. }
  157. NTSTATUS
  158. DfsLpcSpcRequest(
  159. PUNICODE_STRING pSpcName,
  160. ULONG TypeFlags)
  161. {
  162. NTSTATUS status;
  163. DFSSRV_REQUEST_MESSAGE requestMessage;
  164. DFSSRV_REPLY_MESSAGE replyMessage;
  165. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  166. PAGED_CODE();
  167. if ( pSpcName->Length > ((MAX_SPCNAME_LEN - 1) * sizeof(WCHAR))) {
  168. pSpcName = NULL;
  169. }
  170. RtlZeroMemory(requestMessage.Message.GetSpcName.SpcName, MAX_SPCNAME_LEN * sizeof(WCHAR));
  171. if (pSpcName != NULL) {
  172. RtlCopyMemory(requestMessage.Message.GetSpcName.SpcName, pSpcName->Buffer, pSpcName->Length);
  173. }
  174. requestMessage.Message.GetSpcName.Flags = TypeFlags;
  175. //
  176. // Set up the message to send over the port.
  177. //
  178. requestMessage.PortMessage.u1.s1.DataLength =
  179. (USHORT)( sizeof(requestMessage) - sizeof(PORT_MESSAGE) );
  180. requestMessage.PortMessage.u1.s1.TotalLength = sizeof(requestMessage);
  181. requestMessage.PortMessage.u2.ZeroInit = 0;
  182. requestMessage.MessageType = DFSSRV_MESSAGE_GET_SPC_ENTRY;
  183. //
  184. // Send the message and wait for a response message.
  185. //
  186. status = NtRequestWaitReplyPort(
  187. pLpcInfo->LpcPortHandle,
  188. (PPORT_MESSAGE)&requestMessage,
  189. (PPORT_MESSAGE)&replyMessage
  190. );
  191. if ( !NT_SUCCESS(status) ) {
  192. goto exit;
  193. }
  194. //
  195. // Check the status returned in the reply.
  196. //
  197. status = replyMessage.Message.Result.Status;
  198. exit:
  199. return status;
  200. }
  201. VOID
  202. DfsLpcDisconnect ( )
  203. {
  204. NTSTATUS status;
  205. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  206. PAGED_CODE();
  207. //
  208. // Acquire exclusive access to the port resource, to prevent new
  209. // requests from being started.
  210. //
  211. ExAcquireResourceExclusiveLite( &pLpcInfo->LpcPortResource, TRUE );
  212. pLpcInfo->LpcPortState = LPC_STATE_UNINITIALIZED;
  213. if (pLpcInfo->LpcPortHandle != NULL) {
  214. NtClose( pLpcInfo->LpcPortHandle);
  215. pLpcInfo->LpcPortHandle = NULL;
  216. }
  217. if (pLpcInfo->LpcPortName.Buffer != NULL) {
  218. ExFreePool(pLpcInfo->LpcPortName.Buffer);
  219. RtlInitUnicodeString(&pLpcInfo->LpcPortName, NULL);
  220. }
  221. ExReleaseResourceLite( &pLpcInfo->LpcPortResource );
  222. return;
  223. }
  224. NTSTATUS
  225. PktFsctrlDfsSrvConnect(
  226. IN PIRP Irp,
  227. IN PVOID InputBuffer,
  228. IN ULONG InputBufferLength)
  229. {
  230. NTSTATUS status = STATUS_SUCCESS;
  231. PDFS_SRV_DFSSRV_CONNECT_ARG arg;
  232. PDFS_CONNECT_ARG DfsConnectArg = NULL;
  233. PDFS_LPC_INFO pLpcInfo = &DfsData.DfsLpcInfo;
  234. STD_FSCTRL_PROLOGUE(DfsFsctrlDfsSrvConnect, TRUE, FALSE);
  235. if (InputBufferLength < sizeof(DFS_SRV_DFSSRV_CONNECT_ARG)) {
  236. status = STATUS_INVALID_PARAMETER;
  237. goto exit_with_status;
  238. }
  239. //
  240. // unmarshal the arguments...
  241. //
  242. arg = (PDFS_SRV_DFSSRV_CONNECT_ARG) InputBuffer;
  243. OFFSET_TO_POINTER(arg->PortName.Buffer, arg);
  244. if (!UNICODESTRING_IS_VALID(arg->PortName, InputBuffer, InputBufferLength)) {
  245. status = STATUS_INVALID_PARAMETER;
  246. goto exit_with_status;
  247. }
  248. DfsConnectArg = ExAllocatePoolWithTag(
  249. NonPagedPool,
  250. sizeof(DFS_CONNECT_ARG),
  251. ' sfD');
  252. if (DfsConnectArg == NULL) {
  253. status = STATUS_INSUFFICIENT_RESOURCES;
  254. goto exit_with_status;
  255. }
  256. ExAcquireResourceExclusiveLite( &pLpcInfo->LpcPortResource, TRUE );
  257. #if 0
  258. if (pLpcInfo->LpcPortName.Buffer != NULL) {
  259. ExFreePool(pLpcInfo->LpcPortName.Buffer);
  260. RtlInitUnicodeString(&pLpcInfo->LpcPortName, NULL);
  261. }
  262. if ( pLpcInfo->LpcPortHandle != NULL ) {
  263. NtClose( pLpcInfo->LpcPortHandle);
  264. pLpcInfo->LpcPortHandle = NULL;
  265. }
  266. #endif
  267. pLpcInfo->LpcPortName.Buffer = ExAllocatePoolWithTag(
  268. PagedPool,
  269. arg->PortName.Length,
  270. ' sfD');
  271. if (pLpcInfo->LpcPortName.Buffer == NULL) {
  272. status = STATUS_INSUFFICIENT_RESOURCES;
  273. ExFreePool(DfsConnectArg);
  274. ExReleaseResourceLite( &pLpcInfo->LpcPortResource );
  275. goto exit_with_status;
  276. }
  277. pLpcInfo->LpcPortName.Length = arg->PortName.Length;
  278. pLpcInfo->LpcPortName.MaximumLength = arg->PortName.Length;
  279. RtlCopyMemory(
  280. pLpcInfo->LpcPortName.Buffer,
  281. arg->PortName.Buffer,
  282. arg->PortName.Length);
  283. ExInitializeWorkItem(
  284. &DfsConnectArg->WorkQueueItem,
  285. DfsLpcConnect,
  286. DfsConnectArg);
  287. ExQueueWorkItem( &DfsConnectArg->WorkQueueItem, CriticalWorkQueue );
  288. pLpcInfo->LpcPortState = LPC_STATE_INITIALIZING;
  289. ExReleaseResourceLite( &pLpcInfo->LpcPortResource );
  290. exit_with_status:
  291. DfsCompleteRequest( Irp, status );
  292. DebugTrace(-1, Dbg, "DfsFsctrlDfsSrvConnect: Exit -> %08lx\n", ULongToPtr( status ) );
  293. return status;
  294. }