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.

486 lines
13 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. netroot.c
  5. Abstract:
  6. This module implements the routines for creating the PROXY net root.
  7. Author:
  8. Balan Sethu Raman [SethuR] 7-March-1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. //
  14. // The Bug check file id for this module
  15. //
  16. #define BugCheckFileId (RDBSS_BUG_CHECK_PROXY_NETROOT)
  17. //
  18. // The local debug trace level
  19. //
  20. #define Dbg (DEBUG_TRACE_DISPATCH)
  21. //
  22. // Forward declarations ...
  23. //
  24. NTSTATUS
  25. MRxProxyUpdateNetRootState(
  26. IN OUT PMRX_NET_ROOT pNetRoot)
  27. /*++
  28. Routine Description:
  29. This routine update the mini redirector state associated with a net root.
  30. Arguments:
  31. pNetRoot - the net root instance.
  32. Return Value:
  33. RXSTATUS - The return status for the operation
  34. Notes:
  35. --*/
  36. {
  37. if (pNetRoot->Context == NULL) {
  38. pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_ERROR;
  39. } else {
  40. pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
  41. }
  42. return STATUS_SUCCESS;
  43. }
  44. NTSTATUS
  45. MRxProxyCreateVNetRoot(
  46. IN OUT PMRX_V_NET_ROOT pVNetRoot,
  47. IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext
  48. )
  49. /*++
  50. Routine Description:
  51. This routine patches the RDBSS created net root instance with the information required
  52. by the mini redirector.
  53. Arguments:
  54. pVNetRoot - the virtual net root instance.
  55. pCreateNetRootContext - the net root context for calling back
  56. Return Value:
  57. RXSTATUS - The return status for the operation
  58. Notes:
  59. --*/
  60. {
  61. //NTSTATUS Status;
  62. PRX_CONTEXT pRxContext = pCreateNetRootContext->RxContext;
  63. PMRXPROXY_DEVICE_OBJECT MRxProxyDeviceObject = (PMRXPROXY_DEVICE_OBJECT)(pRxContext->RxDeviceObject);
  64. PMRX_SRV_CALL pSrvCall;
  65. PMRX_NET_ROOT pNetRoot;
  66. RxDbgTrace( 0, Dbg, ("MRxProxyCreateVNetRoot %lx\n",pVNetRoot));
  67. pNetRoot = pVNetRoot->pNetRoot;
  68. pSrvCall = pNetRoot->pSrvCall;
  69. ASSERT((NodeType(pNetRoot) == RDBSS_NTC_NETROOT) &&
  70. (NodeType(pSrvCall) == RDBSS_NTC_SRVCALL));
  71. pNetRoot->InnerNamePrefix = MRxProxyDeviceObject->InnerPrefixForOpens;
  72. pNetRoot->DiskParameters.RenameInfoOverallocationSize = MRxProxyDeviceObject->PrefixForRename.Length;
  73. pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS;
  74. pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS;
  75. // Callback the RDBSS for resumption.
  76. pCreateNetRootContext->Callback(pCreateNetRootContext);
  77. // Map the error code to STATUS_PENDING since this triggers the synchronization
  78. // mechanism in the RDBSS.
  79. return STATUS_PENDING;
  80. }
  81. NTSTATUS
  82. MRxProxyFinalizeVNetRoot(
  83. IN PMRX_V_NET_ROOT pVNetRoot,
  84. IN PBOOLEAN ForceDisconnect)
  85. /*++
  86. Routine Description:
  87. Arguments:
  88. pVNetRoot - the virtual net root
  89. ForceDisconnect - disconnect is forced
  90. Return Value:
  91. RXSTATUS - The return status for the operation
  92. --*/
  93. {
  94. RxDbgTrace( 0, Dbg, ("MRxProxyFinalizeVNetRoot %lx\n",pVNetRoot));
  95. //return STATUS_SUCCESS;
  96. return STATUS_NOT_IMPLEMENTED;
  97. }
  98. NTSTATUS
  99. MRxProxyFinalizeNetRoot(
  100. IN PMRX_NET_ROOT pNetRoot,
  101. IN PBOOLEAN ForceDisconnect)
  102. /*++
  103. Routine Description:
  104. Arguments:
  105. pVirtualNetRoot - the virtual net root
  106. ForceDisconnect - disconnect is forced
  107. Return Value:
  108. RXSTATUS - The return status for the operation
  109. --*/
  110. {
  111. RxDbgTrace( 0, Dbg, ("MRxProxyFinalizeNetRoot %lx\n",pNetRoot));
  112. //return STATUS_SUCCESS;
  113. return STATUS_NOT_IMPLEMENTED;
  114. }
  115. VOID
  116. ProxyCeReconnectCallback(
  117. PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext)
  118. /*++
  119. Routine Description:
  120. This routine signals the completion of a reconnect attempt
  121. Arguments:
  122. pCreateNetRootContext - the net root context
  123. Return Value:
  124. RXSTATUS - The return status for the operation
  125. --*/
  126. {
  127. KeSetEvent(&pCreateNetRootContext->FinishEvent, IO_NETWORK_INCREMENT, FALSE );
  128. }
  129. NTSTATUS
  130. ProxyCeReconnect(
  131. IN PMRX_V_NET_ROOT pVNetRoot)
  132. /*++
  133. Routine Description:
  134. This routine reconnects, i.e, establishes a new session and tree connect to a previously
  135. connected serverb share
  136. Arguments:
  137. pVNetRoot - the virtual net root instance.
  138. Return Value:
  139. RXSTATUS - The return status for the operation
  140. --*/
  141. {
  142. NTSTATUS Status;
  143. PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext;
  144. pCreateNetRootContext = (PMRX_CREATENETROOT_CONTEXT)
  145. RxAllocatePoolWithTag(
  146. NonPagedPool,
  147. sizeof(MRX_CREATENETROOT_CONTEXT),
  148. MRXPROXY_NETROOT_POOLTAG);
  149. if (pCreateNetRootContext != NULL) {
  150. pCreateNetRootContext->NetRootStatus = STATUS_SUCCESS;
  151. pCreateNetRootContext->VirtualNetRootStatus = STATUS_SUCCESS;
  152. pCreateNetRootContext->Callback = ProxyCeReconnectCallback;
  153. pCreateNetRootContext->RxContext = NULL;
  154. KeInitializeEvent( &pCreateNetRootContext->FinishEvent, SynchronizationEvent, FALSE );
  155. // Since this is a reconnect instance the net root initialization is not required
  156. #if 0
  157. Status = ProxyCeEstablishConnection(
  158. pVNetRoot,
  159. pCreateNetRootContext,
  160. FALSE);
  161. #endif
  162. Status = STATUS_SUCCESS;
  163. if (Status == STATUS_PENDING) {
  164. // Wait for the construction to be completed.
  165. KeWaitForSingleObject(&pCreateNetRootContext->FinishEvent, Executive, KernelMode, FALSE, NULL);
  166. Status = pCreateNetRootContext->VirtualNetRootStatus;
  167. }
  168. RxFreePool(pCreateNetRootContext);
  169. } else {
  170. Status = STATUS_INSUFFICIENT_RESOURCES;
  171. }
  172. return Status;
  173. }
  174. NTSTATUS
  175. ProxyCeEstablishConnection(
  176. IN OUT PMRX_V_NET_ROOT pVNetRoot,
  177. IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext,
  178. IN BOOLEAN fInitializeNetRoot
  179. )
  180. /*++
  181. Routine Description:
  182. This routine triggers off the connection attempt for initial establishment of a
  183. connection as well as subsequent reconnect attempts.
  184. Arguments:
  185. pVNetRoot - the virtual net root instance.
  186. pCreateNetRootContext - the net root context for calling back
  187. Return Value:
  188. RXSTATUS - The return status for the operation
  189. Notes:
  190. CODE.IMPROVEMENT -- The net root create context must supply the open mode in order
  191. to enable the mini redirector to implement a wide variety of reconnect strategies.
  192. --*/
  193. {
  194. NTSTATUS Status;
  195. #if 0
  196. PPROXYCEDB_SERVER_ENTRY pServerEntry;
  197. PPROXYCEDB_SESSION_ENTRY pSessionEntry;
  198. PPROXYCEDB_NET_ROOT_ENTRY pNetRootEntry;
  199. PPROXYCE_V_NET_ROOT_CONTEXT pVNetRootContext;
  200. pVNetRootContext = ProxyCeGetAssociatedVNetRootContext(pVNetRoot);
  201. if (pVNetRootContext == NULL) {
  202. Status = STATUS_BAD_NETWORK_PATH;
  203. } else {
  204. pServerEntry = pVNetRootContext->pServerEntry;
  205. pSessionEntry = pVNetRootContext->pSessionEntry;
  206. pNetRootEntry = pVNetRootContext->pNetRootEntry;
  207. Status = STATUS_SUCCESS;
  208. }
  209. if (Status != STATUS_SUCCESS) {
  210. return Status;
  211. }
  212. if ((pServerEntry->Server.DialectFlags & DF_EXTENDED_SECURITY) &&
  213. (pSessionEntry->Header.State != PROXYCEDB_ACTIVE)) {
  214. PPROXY_EXCHANGE pSessionSetupExchange;
  215. pSessionSetupExchange = ProxyMmAllocateExchange(EXTENDED_SESSION_SETUP_EXCHANGE,NULL);
  216. if (pSessionSetupExchange != NULL) {
  217. Status = ProxyCeInitializeExtendedSessionSetupExchange(
  218. &pSessionSetupExchange,
  219. pVNetRoot);
  220. if (Status == STATUS_SUCCESS) {
  221. PROXYCE_RESUMPTION_CONTEXT ExchangeResumptionContext;
  222. // Attempt to reconnect( In this case it amounts to establishing the
  223. // connection/session)
  224. pSessionSetupExchange->ProxyCeFlags |= PROXYCE_EXCHANGE_ATTEMPT_RECONNECTS;
  225. ProxyCeInitializeResumptionContext(&ExchangeResumptionContext);
  226. ((PPROXY_EXTENDED_SESSION_SETUP_EXCHANGE)pSessionSetupExchange)->pResumptionContext
  227. = &ExchangeResumptionContext;
  228. Status = ProxyCeInitiateExchange(pSessionSetupExchange);
  229. if (Status == STATUS_PENDING) {
  230. ProxyCeSuspend(
  231. &ExchangeResumptionContext);
  232. Status = ExchangeResumptionContext.Status;
  233. } else {
  234. ProxyCeDiscardExtendedSessionSetupExchange(
  235. (PPROXY_EXTENDED_SESSION_SETUP_EXCHANGE)pSessionSetupExchange);
  236. }
  237. } else {
  238. ProxyMmFreeExchange(pSessionSetupExchange);
  239. }
  240. } else {
  241. Status = STATUS_INSUFFICIENT_RESOURCES;
  242. }
  243. }
  244. if (Status == STATUS_SUCCESS) {
  245. //
  246. // The following code initializes the NetRootEntry, VNetRootContext and
  247. // the session entry under certain cases.
  248. //
  249. // The session entry to a doenlevel server needs to be initialized. This
  250. // is not handled by the previous code since the session entry and the
  251. // net root entry initialization can be combined into one exchange.
  252. //
  253. // The net root entry has not been initialized, i.e., this corresponds to
  254. // the construction of the first PROXYCE_V_NET_ROOT_CONTEXT instance for a
  255. // given NetRootEntry.
  256. //
  257. // Subsequent PROXYCE_V_NET_ROOT context constructions. In these cases the
  258. // construction of each context must obtain a new TID
  259. //
  260. BOOLEAN fNetRootExchangeRequired;
  261. fNetRootExchangeRequired = (
  262. ((pSessionEntry->Header.State != PROXYCEDB_ACTIVE) &&
  263. !(pServerEntry->Server.DialectFlags & DF_EXTENDED_SECURITY))
  264. ||
  265. !BooleanFlagOn(
  266. pVNetRootContext->Flags,
  267. PROXYCE_V_NET_ROOT_CONTEXT_FLAG_VALID_TID)
  268. );
  269. if (fNetRootExchangeRequired) {
  270. // This is a tree connect open which needs to be triggered immediately.
  271. PPROXY_EXCHANGE pProxyExchange;
  272. PPROXY_CONSTRUCT_NETROOT_EXCHANGE pNetRootExchange;
  273. pProxyExchange = ProxyMmAllocateExchange(CONSTRUCT_NETROOT_EXCHANGE,NULL);
  274. if (pProxyExchange != NULL) {
  275. Status = ProxyCeInitializeExchange(
  276. &pProxyExchange,
  277. pVNetRoot,
  278. CONSTRUCT_NETROOT_EXCHANGE,
  279. &ConstructNetRootExchangeDispatch);
  280. if (Status == RX_MAP_STATUS(SUCCESS)) {
  281. pNetRootExchange = (PPROXY_CONSTRUCT_NETROOT_EXCHANGE)pProxyExchange;
  282. // Attempt to reconnect( In this case it amounts to establishing the
  283. // connection/session)
  284. pNetRootExchange->ProxyCeFlags |= PROXYCE_EXCHANGE_ATTEMPT_RECONNECTS;
  285. // Initialize the continuation for resumption upon completion of the
  286. // tree connetcion.
  287. pNetRootExchange->NetRootCallback = pCreateNetRootContext->Callback;
  288. pNetRootExchange->pCreateNetRootContext = pCreateNetRootContext;
  289. pNetRootExchange->fInitializeNetRoot = fInitializeNetRoot;
  290. // Initiate the exchange.
  291. Status = ProxyCeInitiateExchange(pProxyExchange);
  292. if (Status != STATUS_PENDING) {
  293. ProxyCeDiscardExchange(pProxyExchange);
  294. }
  295. }
  296. } else {
  297. Status = STATUS_INSUFFICIENT_RESOURCES;
  298. }
  299. }
  300. }
  301. #endif
  302. Status = STATUS_SUCCESS;
  303. return Status;
  304. }
  305. VOID
  306. MRxProxyExtractNetRootName(
  307. IN PUNICODE_STRING FilePathName,
  308. IN PMRX_SRV_CALL SrvCall,
  309. OUT PUNICODE_STRING NetRootName,
  310. OUT PUNICODE_STRING RestOfName OPTIONAL
  311. )
  312. /*++
  313. Routine Description:
  314. This routine parses the input name into srv, netroot, and the
  315. rest.
  316. Arguments:
  317. --*/
  318. {
  319. UNICODE_STRING xRestOfName;
  320. ULONG length = FilePathName->Length;
  321. PWCH w = FilePathName->Buffer;
  322. PWCH wlimit = (PWCH)(((PCHAR)w)+length);
  323. PWCH wlow;
  324. w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR));
  325. NetRootName->Buffer = wlow = w;
  326. for (;;) {
  327. if (w>=wlimit) break;
  328. if ( (*w == OBJ_NAME_PATH_SEPARATOR) && (w!=wlow) ){
  329. #if ZZZ_MODE
  330. if (*(w-1) == L'z') {
  331. w++;
  332. continue;
  333. }
  334. #endif //if ZZZ_MODE
  335. break;
  336. }
  337. w++;
  338. }
  339. NetRootName->Length = NetRootName->MaximumLength
  340. = (PCHAR)w - (PCHAR)wlow;
  341. if (!RestOfName) RestOfName = &xRestOfName;
  342. RestOfName->Buffer = w;
  343. RestOfName->Length = RestOfName->MaximumLength
  344. = (PCHAR)wlimit - (PCHAR)w;
  345. RxDbgTrace( 0,Dbg,(" MRxProxyExtractNetRootName FilePath=%wZ\n",FilePathName));
  346. RxDbgTrace(0,Dbg,(" Srv=%wZ,Root=%wZ,Rest=%wZ\n",
  347. SrvCall->pSrvCallName,NetRootName,RestOfName));
  348. return;
  349. }
  350.