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.

352 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. netroot.c
  5. Abstract:
  6. This module implements the routines for creating the net root.
  7. --*/
  8. #include "precomp.h"
  9. #pragma hdrstop
  10. //
  11. // The local debug trace level
  12. //
  13. RXDT_DefineCategory(NETROOT);
  14. #define Dbg (DEBUG_TRACE_NETROOT)
  15. //
  16. // Forward declarations ...
  17. //
  18. NTSTATUS
  19. NullMiniInitializeNetRootEntry(
  20. IN PMRX_NET_ROOT pNetRoot
  21. );
  22. NTSTATUS
  23. NulMRxUpdateNetRootState(
  24. IN OUT PMRX_NET_ROOT pNetRoot)
  25. /*++
  26. Routine Description:
  27. This routine updates the mini redirector state associated with a net root.
  28. Arguments:
  29. pNetRoot - the net root instance.
  30. Return Value:
  31. NTSTATUS - The return status for the operation
  32. Notes:
  33. By diffrentiating the mini redirector state from the net root condition it is possible
  34. to permit a variety of reconnect strategies. It is conceivable that the RDBSS considers
  35. a net root to be good while the underlying mini redirector might mark it as invalid
  36. and reconnect on the fly.
  37. --*/
  38. {
  39. NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
  40. RxDbgTrace(0, Dbg, ("NulMRxUpdateNetRootState \n"));
  41. return(Status);
  42. }
  43. NTSTATUS
  44. NulMRxInitializeNetRootEntry(
  45. IN PMRX_NET_ROOT pNetRoot
  46. )
  47. /*++
  48. Routine Description:
  49. This routine initializes a new net root.
  50. It also validates rootnames. Eg: attempts to create a
  51. file in a root that has not been created will fail.
  52. Arguments:
  53. pNetRoot - the net root
  54. Return Value:
  55. NTSTATUS - The return status for the operation
  56. Notes:
  57. --*/
  58. {
  59. NTSTATUS Status = STATUS_SUCCESS;
  60. PMRX_SRV_CALL pSrvCall = pNetRoot->pSrvCall;
  61. UNICODE_STRING RootName;
  62. PNULMRX_NETROOT_EXTENSION pNetRootExtension =
  63. (PNULMRX_NETROOT_EXTENSION)pNetRoot->Context;
  64. //
  65. // A valid new NetRoot is being created
  66. //
  67. RxResetNetRootExtension(pNetRootExtension);
  68. return Status;
  69. }
  70. NTSTATUS
  71. NulMRxCreateVNetRoot(
  72. IN PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext
  73. )
  74. /*++
  75. Routine Description:
  76. This routine patches the RDBSS created net root instance with the information required
  77. by the mini redirector.
  78. Arguments:
  79. pVNetRoot - the virtual net root instance.
  80. pCreateNetRootContext - the net root context for calling back
  81. Return Value:
  82. NTSTATUS - The return status for the operation
  83. Notes:
  84. --*/
  85. {
  86. NTSTATUS Status;
  87. PRX_CONTEXT pRxContext = pCreateNetRootContext->RxContext;
  88. PMRX_V_NET_ROOT pVNetRoot = (PMRX_V_NET_ROOT)pCreateNetRootContext->pVNetRoot;
  89. PMRX_SRV_CALL pSrvCall;
  90. PMRX_NET_ROOT pNetRoot;
  91. BOOLEAN Verifyer = FALSE;
  92. BOOLEAN fTreeConnectOpen = TRUE; // RxContext->Create.ThisIsATreeConnectOpen;
  93. BOOLEAN fInitializeNetRoot;
  94. RxDbgTrace(0, Dbg, ("NulMRxCreateVNetRoot\n"));
  95. pNetRoot = pVNetRoot->pNetRoot;
  96. pSrvCall = pNetRoot->pSrvCall;
  97. // The V_NET_ROOT is associated with a NET_ROOT. The two cases of interest are as
  98. // follows
  99. // 1) the V_NET_ROOT and the associated NET_ROOT are being newly created.
  100. // 2) a new V_NET_ROOT associated with an existing NET_ROOT is being created.
  101. //
  102. // These two cases can be distinguished by checking if the context associated with
  103. // NET_ROOT is NULL. Since the construction of NET_ROOT's/V_NET_ROOT's are serialized
  104. // by the wrapper this is a safe check.
  105. // ( The wrapper cannot have more then one thread tryingto initialize the same
  106. // NET_ROOT).
  107. //
  108. // The above is not really true in our case. Since we have asked the wrapper,
  109. // to manage our netroot extension, the netroot context will always be non-NULL.
  110. // We will distinguish the cases by checking our root state in the context...
  111. //
  112. if(pNetRoot->Context == NULL) {
  113. fInitializeNetRoot = TRUE;
  114. } else {
  115. {NulMRxGetNetRootExtension(pNetRoot,pNetRootExtension);
  116. fInitializeNetRoot = TRUE;
  117. }
  118. }
  119. ASSERT((NodeType(pNetRoot) == RDBSS_NTC_NETROOT) &&
  120. (NodeType(pNetRoot->pSrvCall) == RDBSS_NTC_SRVCALL));
  121. Status = STATUS_SUCCESS;
  122. // update the net root state to be good.
  123. if (fInitializeNetRoot) {
  124. PWCHAR pRootName;
  125. ULONG RootNameLength;
  126. pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
  127. // validate the fixed netroot name
  128. RootNameLength = pNetRoot->pNetRootName->Length - pSrvCall->pSrvCallName->Length;
  129. if ( RootNameLength >= 12 )
  130. {
  131. pRootName = (PWCHAR) (pNetRoot->pNetRootName->Buffer +
  132. (pSrvCall->pSrvCallName->Length / sizeof(WCHAR)));
  133. Verifyer = ( pRootName[0] == L'\\' );
  134. Verifyer &= ( pRootName[1] == L'S' ) || ( pRootName[1] == L's' );
  135. Verifyer &= ( pRootName[2] == L'H' ) || ( pRootName[2] == L'h' );
  136. Verifyer &= ( pRootName[3] == L'A' ) || ( pRootName[3] == L'a' );
  137. Verifyer &= ( pRootName[4] == L'R' ) || ( pRootName[4] == L'r' );
  138. Verifyer &= ( pRootName[5] == L'E' ) || ( pRootName[5] == L'e' );
  139. Verifyer &= ( pRootName[6] == L'\\' ) || ( pRootName[6] == L'\0' );
  140. }
  141. if ( !Verifyer )
  142. {
  143. Status = STATUS_BAD_NETWORK_NAME;
  144. }
  145. } else {
  146. DbgPrint("Creating V_NET_ROOT on existing NET_ROOT\n");
  147. }
  148. if( (Status == STATUS_SUCCESS) && fInitializeNetRoot )
  149. {
  150. //
  151. // A new NET_ROOT and associated V_NET_ROOT are being created !
  152. //
  153. Status = NulMRxInitializeNetRootEntry(pNetRoot);
  154. RxDbgTrace(0, Dbg, ("NulMRXInitializeNetRootEntry %lx\n",Status));
  155. }
  156. if (Status != STATUS_PENDING) {
  157. pCreateNetRootContext->VirtualNetRootStatus = Status;
  158. if (fInitializeNetRoot) {
  159. pCreateNetRootContext->NetRootStatus = Status;
  160. } else {
  161. pCreateNetRootContext->NetRootStatus = Status;
  162. }
  163. // Callback the RDBSS for resumption.
  164. pCreateNetRootContext->Callback(pCreateNetRootContext);
  165. // Map the error code to STATUS_PENDING since this triggers
  166. // the synchronization mechanism in the RDBSS.
  167. Status = STATUS_PENDING;
  168. }
  169. return Status;
  170. }
  171. NTSTATUS
  172. NulMRxFinalizeVNetRoot(
  173. IN PMRX_V_NET_ROOT pVNetRoot,
  174. IN PBOOLEAN ForceDisconnect)
  175. /*++
  176. Routine Description:
  177. Arguments:
  178. pVNetRoot - the virtual net root
  179. ForceDisconnect - disconnect is forced
  180. Return Value:
  181. NTSTATUS - The return status for the operation
  182. --*/
  183. {
  184. RxDbgTrace(0, Dbg, ("NulMRxFinalizeVNetRoot %lx\n",pVNetRoot));
  185. return STATUS_SUCCESS;
  186. }
  187. NTSTATUS
  188. NulMRxFinalizeNetRoot(
  189. IN PMRX_NET_ROOT pNetRoot,
  190. IN PBOOLEAN ForceDisconnect)
  191. /*++
  192. Routine Description:
  193. Arguments:
  194. pVirtualNetRoot - the virtual net root
  195. ForceDisconnect - disconnect is forced
  196. Return Value:
  197. NTSTATUS - The return status for the operation
  198. --*/
  199. {
  200. NTSTATUS Status = STATUS_SUCCESS;
  201. NulMRxGetNetRootExtension(pNetRoot,pNetRootExtension);
  202. RxDbgTrace(0, Dbg, ("NulMRxFinalizeNetRoot \n"));
  203. //
  204. // This is called when all outstanding handles on this
  205. // root have been cleaned up ! We can now zap the netroot
  206. // extension...
  207. //
  208. return(Status);
  209. }
  210. VOID
  211. NulMRxExtractNetRootName(
  212. IN PUNICODE_STRING FilePathName,
  213. IN PMRX_SRV_CALL SrvCall,
  214. OUT PUNICODE_STRING NetRootName,
  215. OUT PUNICODE_STRING RestOfName OPTIONAL
  216. )
  217. /*++
  218. Routine Description:
  219. This routine parses the input name into srv, netroot, and the
  220. rest.
  221. Arguments:
  222. --*/
  223. {
  224. UNICODE_STRING xRestOfName;
  225. ULONG length = FilePathName->Length;
  226. PWCH w = FilePathName->Buffer;
  227. PWCH wlimit = (PWCH)(((PCHAR)w)+length);
  228. PWCH wlow;
  229. RxDbgTrace(0, Dbg, ("NulMRxExtractNetRootName \n"));
  230. w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR));
  231. NetRootName->Buffer = wlow = w;
  232. for (;;) {
  233. if (w>=wlimit) break;
  234. if ( (*w == OBJ_NAME_PATH_SEPARATOR) && (w!=wlow) ){
  235. break;
  236. }
  237. w++;
  238. }
  239. NetRootName->Length = NetRootName->MaximumLength
  240. = (USHORT)((PCHAR)w - (PCHAR)wlow);
  241. //w = FilePathName->Buffer;
  242. //NetRootName->Buffer = w++;
  243. if (!RestOfName) RestOfName = &xRestOfName;
  244. RestOfName->Buffer = w;
  245. RestOfName->Length = (USHORT)RestOfName->MaximumLength
  246. = (USHORT)((PCHAR)wlimit - (PCHAR)w);
  247. RxDbgTrace(0, Dbg, (" NulMRxExtractNetRootName FilePath=%wZ\n",FilePathName));
  248. RxDbgTrace(0, Dbg, (" Srv=%wZ,Root=%wZ,Rest=%wZ\n",
  249. SrvCall->pSrvCallName,NetRootName,RestOfName));
  250. return;
  251. }