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.

352 lines
8.4 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. devfcb.c
  5. Abstract:
  6. This module implements all the passthru stuff from the wrapper. currently there is only one such
  7. functions:
  8. statistics
  9. Revision History:
  10. Balan Sethu Raman [SethuR] 16-July-1995
  11. Notes:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "fsctlbuf.h"
  16. //
  17. // The local trace mask for this part of the module
  18. //
  19. #define Dbg (DEBUG_TRACE_DEVFCB)
  20. typedef enum _MRXPROXY_STATE_ {
  21. MRXPROXY_STARTABLE,
  22. MRXPROXY_START_IN_PROGRESS,
  23. MRXPROXY_STARTED
  24. } MRXPROXY_STATE,*PMRXPROXY_STATE;
  25. MRXPROXY_STATE MRxProxyState = MRXPROXY_STARTABLE;
  26. NTSTATUS
  27. MRxProxyTestDevIoctl(
  28. IN PRX_CONTEXT RxContext
  29. );
  30. NTSTATUS
  31. MRxProxyExternalStart (
  32. IN PRX_CONTEXT RxContext
  33. );
  34. NTSTATUS
  35. MRxProxySetupClaimedServerList(
  36. IN PRX_CONTEXT RxContext
  37. );
  38. VOID
  39. MRxProxyDereferenceClaimedServers(void);
  40. NTSTATUS
  41. MRxProxyDevFcbXXXControlFile (
  42. IN OUT PRX_CONTEXT RxContext
  43. )
  44. /*++
  45. Routine Description:
  46. This routine handles all the device FCB related FSCTL's in the mini rdr
  47. Arguments:
  48. RxContext - Describes the Fsctl and Context.
  49. Return Value:
  50. RxStatus(SUCCESS) -- the Startup sequence was successfully completed.
  51. any other value indicates the appropriate error in the startup sequence.
  52. Notes:
  53. --*/
  54. {
  55. NTSTATUS Status;
  56. RxCaptureFobx;
  57. UCHAR MajorFunctionCode = RxContext->MajorFunction;
  58. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  59. ULONG ControlCode = LowIoContext->ParamsFor.FsCtl.FsControlCode;
  60. RxDbgTrace(+1, Dbg, ("MRxProxyDevFcb\n"));
  61. switch (MajorFunctionCode) {
  62. case IRP_MJ_FILE_SYSTEM_CONTROL: {
  63. switch (LowIoContext->ParamsFor.FsCtl.MinorFunction) {
  64. case IRP_MN_USER_FS_REQUEST:
  65. switch (ControlCode) {
  66. case FSCTL_PROXY_START:
  67. ASSERT (!capFobx);
  68. Status = MRxProxyExternalStart( RxContext );
  69. break;
  70. case FSCTL_PROXY_STOP:
  71. ASSERT (!capFobx);
  72. MRxProxyDereferenceClaimedServers();
  73. Status = RxStopMinirdr( RxContext, &RxContext->PostRequest );
  74. break;
  75. default:
  76. Status = STATUS_INVALID_DEVICE_REQUEST;
  77. }
  78. break;
  79. default : //minor function != IRP_MN_USER_FS_REQUEST
  80. Status = STATUS_INVALID_DEVICE_REQUEST;
  81. } // end of switch
  82. } // end of FSCTL case
  83. break;
  84. case IRP_MJ_DEVICE_CONTROL:
  85. case IRP_MJ_INTERNAL_DEVICE_CONTROL: {
  86. switch (ControlCode) {
  87. #if DBG
  88. case IOCTL_LMMR_TEST:
  89. Status = MRxProxyTestDevIoctl(RxContext);
  90. break;
  91. #endif //if DBG
  92. default :
  93. Status = STATUS_INVALID_DEVICE_REQUEST;
  94. } // end of switch
  95. } //end of IOCTL cases
  96. break;
  97. default:
  98. ASSERT(!"unimplemented major function");
  99. Status = STATUS_INVALID_DEVICE_REQUEST;
  100. }
  101. RxDbgTrace(-1, Dbg, ("MRxProxyDevFcb st,info=%08lx,%08lx\n",
  102. Status,RxContext->InformationToReturn));
  103. return(Status);
  104. }
  105. #if DBG
  106. NTSTATUS
  107. MRxProxyTestDevIoctl(
  108. IN PRX_CONTEXT RxContext
  109. )
  110. {
  111. NTSTATUS Status = STATUS_SUCCESS;
  112. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  113. PSZ InputString = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  114. PSZ OutputString = LowIoContext->ParamsFor.FsCtl.pOutputBuffer;
  115. ULONG OutputBufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  116. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  117. ULONG i;
  118. //BUGBUG because this is a method neither, the buffers have not been probed. since this is debug
  119. //only i am foregoing that currently. when we do more here...we'll have to probe.
  120. RxDbgTrace(0, Dbg,("MRxProxyTestDevIoctl %s, obl = %08lx\n",InputString, OutputBufferLength));
  121. RxContext->InformationToReturn = (InputBufferLength-1)*(InputBufferLength-1);
  122. for (i=0;i<InputBufferLength;i++) {
  123. UCHAR c = InputString[i];
  124. if (c==0) { break; }
  125. OutputString[i] = c;
  126. if ((i&3)==2) {
  127. OutputString[i] = '@';
  128. }
  129. }
  130. OutputString[i] = 0;
  131. return(Status);
  132. }
  133. #endif //if DBG
  134. NTSTATUS
  135. MRxProxyExternalStart (
  136. IN PRX_CONTEXT RxContext
  137. )
  138. /*++
  139. Routine Description:
  140. This routine starts up the proxy minirdr if it hasn't been started already.
  141. Arguments:
  142. RxContext - Describes the Fsctl and Context.
  143. Return Value:
  144. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  145. any other value indicates the appropriate error in the startup sequence.
  146. --*/
  147. {
  148. NTSTATUS Status;
  149. BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
  150. PAGED_CODE();
  151. //DbgBreakPoint();
  152. RxDbgTrace(0, Dbg, ("MRxProxyExternalStart [Start] -> %08lx\n", 0));
  153. Status = RxStartMinirdr( RxContext, &RxContext->PostRequest );
  154. if (Status == STATUS_SUCCESS) {
  155. MRXPROXY_STATE State;
  156. MRxProxySetupClaimedServerList(RxContext);
  157. State = (MRXPROXY_STATE)InterlockedCompareExchange(
  158. (PVOID *)&MRxProxyState,
  159. (PVOID)MRXPROXY_STARTED,
  160. (PVOID)MRXPROXY_START_IN_PROGRESS);
  161. if (State != MRXPROXY_START_IN_PROGRESS) {
  162. Status = STATUS_REDIRECTOR_STARTED;
  163. }
  164. }
  165. return Status;
  166. }
  167. //CODE.IMPROVEMENT we should get this from the registry........
  168. struct {
  169. PWCHAR ServerName;
  170. PSRV_CALL SrvCall;
  171. ULONG Flags;
  172. } MRxProxyClaimedServerList[] =
  173. {
  174. {MRXPROXY_CLAIMED_SERVERNAME_U,NULL,0},
  175. NULL
  176. };
  177. NTSTATUS
  178. MRxProxySetupClaimedServerList(
  179. IN PRX_CONTEXT RxContext
  180. )
  181. /*++
  182. Routine Description:
  183. This routine claims servers for this module.
  184. Arguments:
  185. none
  186. Return Value:
  187. RXSTATUS - could return an error if an allocation fails or something
  188. --*/
  189. {
  190. ULONG i;
  191. PAGED_CODE();
  192. RxAcquirePrefixTableLockExclusive( &RxNetNameTable, TRUE);
  193. try {
  194. for (i=0;MRxProxyClaimedServerList[i].ServerName!=NULL;i++) {
  195. PWCHAR ServerNameText = MRxProxyClaimedServerList[i].ServerName;
  196. ULONG Flags = MRxProxyClaimedServerList[i].Flags;
  197. UNICODE_STRING SrvCallName,UnmatchedName;
  198. PVOID Container = NULL;
  199. PSRV_CALL SrvCall;
  200. RtlInitUnicodeString(&SrvCallName,ServerNameText);
  201. DbgPrint("CLAIMEDSERVER %wZ %08lx\n",&SrvCallName,Flags);
  202. Container = RxPrefixTableLookupName( &RxNetNameTable, &SrvCallName, &UnmatchedName );
  203. if (Container!=NULL) {
  204. ASSERT ( NodeType(Container) == RDBSS_NTC_SRVCALL);
  205. SrvCall = (PSRV_CALL)Container;
  206. //this leaves a reference!
  207. } else {
  208. //here we have to create the srvcall
  209. SrvCall = RxCreateSrvCall(RxContext,&SrvCallName,NULL);
  210. if (SrvCall == NULL) {
  211. return(STATUS_INSUFFICIENT_RESOURCES);
  212. }
  213. RxReferenceSrvCall(SrvCall);
  214. //leave this reference
  215. }
  216. SrvCall->Flags |= Flags;
  217. SrvCall->RxDeviceObject = &MRxProxyDeviceObject->RxDeviceObject;
  218. if (FlagOn(SrvCall->Flags,SRVCALL_FLAG_NO_CONNECTION_ALLOWED)) {
  219. SrvCall->Condition = Condition_Bad;
  220. } else {
  221. SrvCall->Condition = Condition_Good;
  222. }
  223. MRxProxyClaimedServerList[i].SrvCall = SrvCall; //remember this for later
  224. }
  225. } finally {
  226. RxReleasePrefixTableLock( &RxNetNameTable );
  227. }
  228. return(STATUS_SUCCESS);
  229. }
  230. VOID
  231. MRxProxyDereferenceClaimedServers(
  232. void
  233. )
  234. /*++
  235. Routine Description:
  236. This routine tears down the list of claimed servers.
  237. it does this by just removing a reference; this will make the servers
  238. eligible for finalization in finalizenettable.
  239. Arguments:
  240. none
  241. Return Value:
  242. none
  243. --*/
  244. {
  245. ULONG i;
  246. LOCK_HOLDING_STATE LockHoldingState = LHS_LockNotHeld;
  247. PAGED_CODE();
  248. for (i=0;MRxProxyClaimedServerList[i].ServerName!=NULL;i++) {
  249. PSRV_CALL SrvCall = MRxProxyClaimedServerList[i].SrvCall;
  250. if (SrvCall != NULL) {
  251. DbgPrint("Claimed Srvcall deref %wZ\n",&SrvCall->PrefixEntry.Prefix);
  252. MRxProxyClaimedServerList[i].SrvCall = NULL;
  253. RxDereferenceSrvCall(SrvCall,LockHoldingState);
  254. }
  255. }
  256. }
  257.