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.

646 lines
22 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. devfcb.c
  5. Abstract:
  6. This module implements all the passthru stuff from the wrapper. currently
  7. there is only one such function:
  8. statistics
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #include "smbmrx.h"
  13. //
  14. // Forward declarations.
  15. //
  16. NTSTATUS
  17. MRxSmbCreateConnection (
  18. IN PRX_CONTEXT RxContext,
  19. OUT PBOOLEAN PostToFsp
  20. );
  21. NTSTATUS
  22. MRxSmbDeleteConnection (
  23. IN PRX_CONTEXT RxContext,
  24. OUT PBOOLEAN PostToFsp
  25. );
  26. #ifdef ALLOC_PRAGMA
  27. #pragma alloc_text(PAGE, MRxSmbGetStatistics)
  28. #pragma alloc_text(PAGE, MRxSmbDevFcbXXXControlFile)
  29. #endif
  30. //
  31. // The local trace mask for this part of the module
  32. //
  33. #define Dbg (DEBUG_TRACE_DEVFCB)
  34. MRX_SMB_STATISTICS MRxSmbStatistics;
  35. NTSTATUS
  36. MRxSmbGetStatistics(
  37. IN OUT PRX_CONTEXT RxContext
  38. )
  39. /*++
  40. Routine Description:
  41. This routine gathers the statistics from the mini redirector
  42. Arguments:
  43. RxContext - Describes the Fsctl and Context.
  44. Return Value:
  45. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  46. any other value indicates the appropriate error.
  47. Notes:
  48. --*/
  49. {
  50. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  51. PMRX_SMB_STATISTICS pStatistics;
  52. ULONG BufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  53. PAGED_CODE();
  54. pStatistics = (PMRX_SMB_STATISTICS)(LowIoContext->ParamsFor.FsCtl.pOutputBuffer);
  55. if (BufferLength < sizeof(MRX_SMB_STATISTICS)) {
  56. return STATUS_INVALID_PARAMETER;
  57. }
  58. RxContext->InformationToReturn = sizeof(MRX_SMB_STATISTICS);
  59. MRxSmbStatistics.SmbsReceived.QuadPart++;
  60. //some stuff we have to copy from the device object......
  61. MRxSmbStatistics.PagingReadBytesRequested = MRxSmbDeviceObject->PagingReadBytesRequested;
  62. MRxSmbStatistics.NonPagingReadBytesRequested = MRxSmbDeviceObject->NonPagingReadBytesRequested;
  63. MRxSmbStatistics.CacheReadBytesRequested = MRxSmbDeviceObject->CacheReadBytesRequested;
  64. MRxSmbStatistics.NetworkReadBytesRequested = MRxSmbDeviceObject->NetworkReadBytesRequested;
  65. MRxSmbStatistics.PagingWriteBytesRequested = MRxSmbDeviceObject->PagingWriteBytesRequested;
  66. MRxSmbStatistics.NonPagingWriteBytesRequested = MRxSmbDeviceObject->NonPagingWriteBytesRequested;
  67. MRxSmbStatistics.CacheWriteBytesRequested = MRxSmbDeviceObject->CacheWriteBytesRequested;
  68. MRxSmbStatistics.NetworkWriteBytesRequested = MRxSmbDeviceObject->NetworkWriteBytesRequested;
  69. MRxSmbStatistics.ReadOperations = MRxSmbDeviceObject->ReadOperations;
  70. MRxSmbStatistics.RandomReadOperations = MRxSmbDeviceObject->RandomReadOperations;
  71. MRxSmbStatistics.WriteOperations = MRxSmbDeviceObject->WriteOperations;
  72. MRxSmbStatistics.RandomWriteOperations = MRxSmbDeviceObject->RandomWriteOperations;
  73. MRxSmbStatistics.LargeReadSmbs = MRxSmbStatistics.ReadSmbs - MRxSmbStatistics.SmallReadSmbs;
  74. MRxSmbStatistics.LargeWriteSmbs = MRxSmbStatistics.WriteSmbs - MRxSmbStatistics.SmallWriteSmbs;
  75. MRxSmbStatistics.CurrentCommands = SmbCeStartStopContext.ActiveExchanges;
  76. *pStatistics = MRxSmbStatistics;
  77. return STATUS_SUCCESS;
  78. }
  79. NTSTATUS
  80. MRxSmbDevFcbXXXControlFile (
  81. IN OUT PRX_CONTEXT RxContext
  82. )
  83. /*++
  84. Routine Description:
  85. This routine handles all the device FCB related FSCTL's in the mini rdr
  86. Arguments:
  87. RxContext - Describes the Fsctl and Context.
  88. Return Value:
  89. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  90. any other value indicates the appropriate error in the startup sequence.
  91. --*/
  92. {
  93. NTSTATUS Status;
  94. RxCaptureFobx;
  95. UCHAR MajorFunctionCode = RxContext->MajorFunction;
  96. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  97. ULONG ControlCode = LowIoContext->ParamsFor.FsCtl.FsControlCode;
  98. PAGED_CODE();
  99. RxDbgTrace(+1, Dbg, ("MRxSmbDevFcb\n"));
  100. switch (MajorFunctionCode) {
  101. case IRP_MJ_FILE_SYSTEM_CONTROL:
  102. {
  103. switch (LowIoContext->ParamsFor.FsCtl.MinorFunction) {
  104. case IRP_MN_USER_FS_REQUEST:
  105. {
  106. RxDbgTrace(-1, Dbg, ("RxCommonDevFCBFsCtl -> unimplemented fsctl\n"));
  107. Status = STATUS_INVALID_DEVICE_REQUEST;
  108. }
  109. break;
  110. default : //minor function != IRP_MN_USER_FS_REQUEST
  111. Status = STATUS_INVALID_DEVICE_REQUEST;
  112. } // end of switch
  113. } // end of FSCTL case
  114. break;
  115. case IRP_MJ_DEVICE_CONTROL:
  116. case IRP_MJ_INTERNAL_DEVICE_CONTROL:
  117. {
  118. switch (ControlCode) {
  119. case IOCTL_SMBMRX_ADDCONN:
  120. DbgPrint("Processing Create Connection IOCTL\n");
  121. Status = MRxSmbCreateConnection( RxContext, &RxContext->PostRequest );
  122. break;
  123. case IOCTL_SMBMRX_DELCONN:
  124. DbgPrint("Processing Delete Connection IOCTL\n");
  125. Status = MRxSmbDeleteConnection( RxContext, &RxContext->PostRequest );
  126. break;
  127. case IOCTL_SMBMRX_GETSTATE:
  128. {
  129. ULONG OutBufferLength = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
  130. PBYTE OutBuffer = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
  131. ULONG CurrentState = RDR_NULL_STATE;
  132. if ( OutBufferLength >= sizeof(ULONG) )
  133. {
  134. // map the states to control app's equivalents
  135. switch ( MRxSmbState )
  136. {
  137. case MRXSMB_STARTABLE:
  138. case MRXSMB_STOPPED:
  139. CurrentState = RDR_STOPPED;
  140. break;
  141. case MRXSMB_START_IN_PROGRESS:
  142. CurrentState = RDR_STARTING;
  143. break;
  144. case MRXSMB_STARTED:
  145. CurrentState = RDR_STARTED;
  146. break;
  147. }
  148. *(ULONG *)OutBuffer = CurrentState;
  149. RxContext->InformationToReturn = sizeof(ULONG);
  150. Status = STATUS_SUCCESS;
  151. }
  152. else
  153. {
  154. Status = STATUS_INVALID_PARAMETER;
  155. }
  156. }
  157. break;
  158. case IOCTL_SMBMRX_START:
  159. switch (MRxSmbState) {
  160. case MRXSMB_STARTABLE:
  161. // The correct sequence of start events issued by the workstation
  162. // service would have avoided this. We can recover from this
  163. // by actually invoking RxStartMiniRdr.
  164. if (capFobx) {
  165. Status = STATUS_INVALID_DEVICE_REQUEST;
  166. goto FINALLY;
  167. }
  168. (MRXSMB_STATE)InterlockedCompareExchange(
  169. (PLONG)&MRxSmbState,
  170. MRXSMB_START_IN_PROGRESS,
  171. MRXSMB_STARTABLE);
  172. //lack of break is intentional
  173. case MRXSMB_START_IN_PROGRESS:
  174. {
  175. Status = RxStartMinirdr(RxContext,&RxContext->PostRequest);
  176. if (Status == STATUS_REDIRECTOR_STARTED) {
  177. Status = STATUS_SUCCESS;
  178. }
  179. else if ( Status == STATUS_PENDING && RxContext->PostRequest == TRUE )
  180. {
  181. Status = STATUS_MORE_PROCESSING_REQUIRED;
  182. }
  183. }
  184. break;
  185. case MRXSMB_STARTED:
  186. Status = STATUS_SUCCESS;
  187. break;
  188. default:
  189. Status = STATUS_INVALID_PARAMETER;
  190. break;
  191. }
  192. break;
  193. case IOCTL_SMBMRX_STOP:
  194. if (capFobx) {
  195. Status = STATUS_INVALID_DEVICE_REQUEST;
  196. goto FINALLY;
  197. }
  198. if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0) {
  199. return STATUS_REDIRECTOR_HAS_OPEN_HANDLES;
  200. } else {
  201. MRXSMB_STATE CurrentState;
  202. CurrentState = (MRXSMB_STATE)
  203. InterlockedCompareExchange(
  204. (PLONG)&MRxSmbState,
  205. MRXSMB_STARTABLE,
  206. MRXSMB_STARTED);
  207. Status = RxStopMinirdr(
  208. RxContext,
  209. &RxContext->PostRequest );
  210. if ( Status == STATUS_PENDING && RxContext->PostRequest == TRUE )
  211. {
  212. Status = STATUS_MORE_PROCESSING_REQUIRED;
  213. }
  214. }
  215. break;
  216. default :
  217. Status = STATUS_INVALID_DEVICE_REQUEST;
  218. } // end of switch
  219. } //end of IOCTL cases
  220. break;
  221. default:
  222. ASSERT(!"unimplemented major function");
  223. Status = STATUS_INVALID_DEVICE_REQUEST;
  224. }
  225. FINALLY:
  226. RxDbgTrace(
  227. -1,
  228. Dbg,
  229. ("MRxSmbDevFcb st,info=%08lx,%08lx\n",
  230. Status,
  231. RxContext->InformationToReturn));
  232. return(Status);
  233. }
  234. #if 0
  235. // for ea testing
  236. ULONG BuildCustomEAData( PVOID EaPtr )
  237. {
  238. PFILE_FULL_EA_INFORMATION thisEa = (PFILE_FULL_EA_INFORMATION) EaPtr;
  239. PBYTE valuePtr;
  240. // Set the user name EA
  241. thisEa->Flags = 0;
  242. thisEa->EaNameLength = sizeof("UserName");
  243. RtlCopyMemory( thisEa->EaName, "UserName\0", thisEa->EaNameLength + 1 );
  244. valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
  245. //thisEa->EaNameLength--; // don't include the null in the EaName length
  246. thisEa->EaValueLength = sizeof(L"TestUser");
  247. RtlCopyMemory( valuePtr, L"TestUser", thisEa->EaValueLength );
  248. thisEa->NextEntryOffset = ((PBYTE) valuePtr + thisEa->EaValueLength ) -
  249. (PBYTE) thisEa;
  250. // Set the password EA
  251. thisEa = (PFILE_FULL_EA_INFORMATION) ((PBYTE) thisEa + thisEa->NextEntryOffset);
  252. thisEa->Flags = 0;
  253. thisEa->EaNameLength = sizeof("Password");
  254. RtlCopyMemory( thisEa->EaName, "Password\0", thisEa->EaNameLength + 1 );
  255. valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
  256. //thisEa->EaNameLength--; // don't include the null in the EaName length
  257. thisEa->EaValueLength = sizeof(WCHAR);
  258. RtlCopyMemory( valuePtr, L"\0", thisEa->EaValueLength );
  259. thisEa->NextEntryOffset = ((PBYTE) valuePtr + thisEa->EaValueLength ) -
  260. (PBYTE) thisEa;
  261. // Set the domain EA
  262. thisEa = (PFILE_FULL_EA_INFORMATION) ((PBYTE) thisEa + thisEa->NextEntryOffset);
  263. thisEa->Flags = 0;
  264. thisEa->EaNameLength = sizeof("Domain");
  265. RtlCopyMemory( thisEa->EaName, "Domain\0", thisEa->EaNameLength + 1 );
  266. valuePtr = (PBYTE) thisEa->EaName + thisEa->EaNameLength + 1;
  267. //thisEa->EaNameLength--; // don't include the null in the EaName length
  268. thisEa->EaValueLength = sizeof(L"WORKGROUP");
  269. RtlCopyMemory( valuePtr, L"WORKGROUP", thisEa->EaValueLength );
  270. thisEa->NextEntryOffset = 0;
  271. return ((PBYTE) valuePtr + thisEa->EaValueLength) - (PBYTE) EaPtr;
  272. }
  273. #endif
  274. NTSTATUS
  275. GetConnectionHandle(
  276. IN PUNICODE_STRING ConnectionName,
  277. PVOID EaBuffer,
  278. ULONG EaLength,
  279. PHANDLE Handle )
  280. {
  281. NTSTATUS Status;
  282. IO_STATUS_BLOCK IoStatusBlock;
  283. OBJECT_ATTRIBUTES ObjectAttributes;
  284. UNICODE_STRING FileName;
  285. InitializeObjectAttributes(
  286. &ObjectAttributes,
  287. ConnectionName,
  288. OBJ_CASE_INSENSITIVE,
  289. NULL,
  290. NULL);
  291. Status = ZwCreateFile(
  292. Handle,
  293. SYNCHRONIZE,
  294. &ObjectAttributes,
  295. &IoStatusBlock,
  296. NULL,
  297. FILE_ATTRIBUTE_NORMAL,
  298. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  299. FILE_OPEN_IF,
  300. FILE_CREATE_TREE_CONNECTION | FILE_SYNCHRONOUS_IO_NONALERT,
  301. EaBuffer,
  302. EaLength);
  303. DbgPrint("ZwCreateFile returned %lx\n",Status);
  304. if ( Status == STATUS_SUCCESS )
  305. {
  306. if ( *Handle != INVALID_HANDLE_VALUE ){
  307. DbgPrint("ZwCreateFile returned success\n");
  308. } else {
  309. DbgPrint("ZwCreateFile failed\n");
  310. }
  311. }
  312. return Status;
  313. }
  314. NTSTATUS
  315. MRxSmbCreateConnection (
  316. IN PRX_CONTEXT RxContext,
  317. OUT PBOOLEAN PostToFsp
  318. )
  319. /*++
  320. Routine Description:
  321. Arguments:
  322. IN PRX_CONTEXT RxContext - Describes the Fsctl and Context
  323. Return Value:
  324. RXSTATUS
  325. --*/
  326. {
  327. NTSTATUS Status = STATUS_SUCCESS;
  328. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  329. ULONG InBufferLength = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
  330. PBYTE InBuffer = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
  331. BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
  332. BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
  333. PAGED_CODE();
  334. RxDbgTrace(+1, Dbg, ("MRxSmbCreateConnection - entry\n"));
  335. if (!Wait) {
  336. //just post right now!
  337. *PostToFsp = TRUE;
  338. return(STATUS_PENDING);
  339. }
  340. Status = STATUS_INVALID_PARAMETER;
  341. try {
  342. PSMBMRX_CONNECTINFO ConnectInfo;
  343. UNICODE_STRING ConnectionName;
  344. PBYTE EaBuffer;
  345. ULONG EaLength;
  346. ULONG Validator;
  347. ULONG CompareLength;
  348. HANDLE Handle;
  349. if ( InBufferLength >= sizeof( PSMBMRX_CONNECTINFO ) )
  350. {
  351. ConnectInfo = (PSMBMRX_CONNECTINFO) InBuffer;
  352. if (((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->ConnectionNameOffset +
  353. (USHORT)ConnectInfo->ConnectionNameLength <= InBufferLength) &&
  354. ((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->EaDataOffset +
  355. (USHORT)ConnectInfo->EaDataLength <= InBufferLength))
  356. {
  357. ConnectionName.Buffer = (PWCHAR) ((PBYTE) ConnectInfo->InfoArea +
  358. ConnectInfo->ConnectionNameOffset);
  359. ConnectionName.Length = (USHORT) ConnectInfo->ConnectionNameLength;
  360. ConnectionName.MaximumLength = (USHORT) ConnectInfo->ConnectionNameLength;
  361. EaLength = ConnectInfo->EaDataLength;
  362. EaBuffer = ( EaLength > 0 ) ?
  363. ConnectInfo->InfoArea + ConnectInfo->EaDataOffset : NULL;
  364. // Validate the connection name. The name must start with our device name.
  365. // We can't allow a create on some rogue pathname outside our device
  366. CompareLength = sizeof(DD_SMBMRX_FS_DEVICE_NAME_U);
  367. CompareLength -= ( CompareLength > 0 ) ? sizeof(WCHAR) : 0;
  368. CompareLength = min( CompareLength, ConnectionName.Length );
  369. Validator = (ULONG) RtlCompareMemory( ConnectionName.Buffer, DD_SMBMRX_FS_DEVICE_NAME_U,
  370. CompareLength );
  371. if ( Validator == CompareLength )
  372. {
  373. Status = GetConnectionHandle( &ConnectionName, EaBuffer, EaLength, &Handle );
  374. if ( Status == STATUS_SUCCESS )
  375. {
  376. if ( Handle != INVALID_HANDLE_VALUE )
  377. {
  378. ZwClose( Handle );
  379. }
  380. else
  381. {
  382. Status = STATUS_BAD_NETWORK_NAME;
  383. }
  384. }
  385. }
  386. else
  387. {
  388. Status = STATUS_OBJECT_PATH_NOT_FOUND;
  389. }
  390. }
  391. }
  392. try_return(Status);
  393. try_exit:NOTHING;
  394. } finally {
  395. RxDbgTrace(0, Dbg, ("MRxSmbCreateConnection - exit Status = %08lx\n", Status));
  396. RxDbgTraceUnIndent(-1,Dbg);
  397. }
  398. return Status;
  399. }
  400. NTSTATUS
  401. MRxSmbDeleteConnection (
  402. IN PRX_CONTEXT RxContext,
  403. OUT PBOOLEAN PostToFsp
  404. )
  405. /*++
  406. Routine Description:
  407. Arguments:
  408. IN PRX_CONTEXT RxContext - Describes the Fsctl and Context
  409. Return Value:
  410. RXSTATUS
  411. --*/
  412. {
  413. NTSTATUS Status = STATUS_SUCCESS;
  414. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  415. ULONG InBufferLength = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
  416. PBYTE InBuffer = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
  417. BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
  418. BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
  419. PV_NET_ROOT VNetRoot;
  420. PFILE_OBJECT pFileObject;
  421. PAGED_CODE();
  422. RxDbgTrace(+1, Dbg, ("MRxSmbDeleteConnection - entry\n"));
  423. if (!Wait) {
  424. //just post right now!
  425. *PostToFsp = TRUE;
  426. return(STATUS_PENDING);
  427. }
  428. Status = STATUS_INVALID_PARAMETER;
  429. try {
  430. PSMBMRX_CONNECTINFO ConnectInfo;
  431. UNICODE_STRING ConnectionName;
  432. PBYTE EaBuffer;
  433. ULONG EaLength;
  434. ULONG Validator;
  435. ULONG CompareLength;
  436. HANDLE Handle;
  437. if ( InBufferLength >= sizeof( PSMBMRX_CONNECTINFO ) )
  438. {
  439. ConnectInfo = (PSMBMRX_CONNECTINFO) InBuffer;
  440. if (((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->ConnectionNameOffset +
  441. (USHORT)ConnectInfo->ConnectionNameLength <= InBufferLength) &&
  442. ((ULONG)(FIELD_OFFSET(SMBMRX_CONNECTINFO, InfoArea)) + (USHORT)ConnectInfo->EaDataOffset +
  443. (USHORT)ConnectInfo->EaDataLength <= InBufferLength))
  444. {
  445. ConnectionName.Buffer = (PWCHAR) ((PBYTE) ConnectInfo->InfoArea +
  446. ConnectInfo->ConnectionNameOffset);
  447. ConnectionName.Length = (USHORT) ConnectInfo->ConnectionNameLength;
  448. ConnectionName.MaximumLength = (USHORT) ConnectInfo->ConnectionNameLength;
  449. EaLength = ConnectInfo->EaDataLength;
  450. EaBuffer = ( EaLength > 0 ) ?
  451. ConnectInfo->InfoArea + ConnectInfo->EaDataOffset : NULL;
  452. // Validate the connection name. The name must start with our device name.
  453. // We can't allow a create on some rogue pathname outside our device
  454. CompareLength = sizeof(DD_SMBMRX_FS_DEVICE_NAME_U);
  455. CompareLength -= ( CompareLength > 0 ) ? sizeof(WCHAR) : 0;
  456. CompareLength = min( CompareLength, ConnectionName.Length );
  457. Validator = (ULONG) RtlCompareMemory( ConnectionName.Buffer, DD_SMBMRX_FS_DEVICE_NAME_U,
  458. CompareLength );
  459. if ( Validator == CompareLength )
  460. {
  461. Status = GetConnectionHandle( &ConnectionName, EaBuffer, EaLength, &Handle );
  462. if ( Status == STATUS_SUCCESS )
  463. {
  464. if ( Handle != INVALID_HANDLE_VALUE )
  465. {
  466. Status = ObReferenceObjectByHandle( Handle,
  467. 0L,
  468. NULL,
  469. KernelMode,
  470. (PVOID *)&pFileObject,
  471. NULL );
  472. if ( NT_SUCCESS(Status) )
  473. {
  474. // VNetRoot exists as FOBx in the FsContext2
  475. VNetRoot = (PV_NET_ROOT) pFileObject->FsContext2;
  476. // make sure the node looks right
  477. if (NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT)
  478. {
  479. RxDbgTrace(-1, Dbg, ("MRxSmbDeleteConnection - Calling RxFinalizeConnection"));
  480. Status = RxFinalizeConnection(VNetRoot->NetRoot, VNetRoot, TRUE);
  481. }
  482. else
  483. {
  484. Status = STATUS_BAD_NETWORK_NAME;
  485. }
  486. ObDereferenceObject(pFileObject);
  487. }
  488. ZwClose(Handle);
  489. }
  490. else
  491. {
  492. Status = STATUS_BAD_NETWORK_NAME;
  493. }
  494. }
  495. }
  496. else
  497. {
  498. Status =STATUS_OBJECT_PATH_NOT_FOUND;
  499. }
  500. }
  501. }
  502. try_return(Status);
  503. try_exit:NOTHING;
  504. } finally {
  505. RxDbgTrace(0, Dbg, ("MRxSmbDeleteConnection - exit Status = %08lx\n", Status));
  506. RxDbgTraceUnIndent(-1,Dbg);
  507. }
  508. return Status;
  509. }