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.

1368 lines
41 KiB

  1. /*++
  2. Copyright (c) 1989 - 1999 Microsoft Corporation
  3. Module Name:
  4. Init.c
  5. Abstract:
  6. This module implements the DRIVER_INITIALIZATION routine for the SMB mini rdr.
  7. --*/
  8. #include "precomp.h"
  9. #pragma hdrstop
  10. #include "smbmrx.h"
  11. #ifdef ALLOC_PRAGMA
  12. #pragma alloc_text(PAGE, DriverEntry)
  13. #pragma alloc_text(PAGE, MRxSmbInitUnwind)
  14. #pragma alloc_text(PAGE, MRxSmbUnload)
  15. #pragma alloc_text(PAGE, MRxSmbInitializeTables)
  16. #pragma alloc_text(PAGE, MRxSmbStart)
  17. #pragma alloc_text(PAGE, MRxSmbStop)
  18. #pragma alloc_text(PAGE, MRxSmbInitializeSecurity)
  19. #pragma alloc_text(PAGE, MRxSmbUninitializeSecurity)
  20. #pragma alloc_text(PAGE, SmbCeGetConfigurationInformation)
  21. #pragma alloc_text(PAGE, MRxSmbFsdDispatch)
  22. #pragma alloc_text(PAGE, MRxSmbDeallocateForFcb)
  23. #pragma alloc_text(PAGE, MRxSmbDeallocateForFobx)
  24. #pragma alloc_text(PAGE, MRxSmbGetUlongRegistryParameter)
  25. #endif
  26. extern ERESOURCE s_SmbCeDbResource;
  27. //
  28. // Global data declarations .
  29. //
  30. PVOID MRxSmbPoRegistrationState = NULL;
  31. FAST_MUTEX MRxSmbSerializationMutex;
  32. MRXSMB_CONFIGURATION MRxSmbConfiguration;
  33. MRXSMB_STATE MRxSmbState = MRXSMB_STARTABLE;
  34. SMBCE_CONTEXT SmbCeContext;
  35. PMDL s_pEchoSmbMdl = NULL;
  36. ULONG s_EchoSmbLength = 0;
  37. #ifdef EXPLODE_POOLTAGS
  38. ULONG MRxSmbExplodePoolTags = 1;
  39. #else
  40. ULONG MRxSmbExplodePoolTags = 0;
  41. #endif
  42. //
  43. // Mini Redirector global variables.
  44. //
  45. struct _MINIRDR_DISPATCH MRxSmbDispatch;
  46. PRDBSS_DEVICE_OBJECT MRxSmbDeviceObject;
  47. MRXSMB_GLOBAL_PADDING MrxSmbCeGlobalPadding;
  48. //
  49. // If this flag is TRUE, we strictly obey the transport binding order. If it is FALSE,
  50. // we can use whatever transport we want to connect to the remote server.
  51. //
  52. BOOLEAN MRxSmbObeyBindingOrder = FALSE;
  53. //
  54. // MRxSmbSecurityInitialized indicates whether MRxSmbInitializeSecurity
  55. // has been called.
  56. //
  57. BOOLEAN MRxSmbSecurityInitialized = FALSE;
  58. LIST_ENTRY MRxSmbPagingFilesSrvOpenList;
  59. //declare the shadow debugtrace controlpoints
  60. RXDT_DefineCategory(CREATE);
  61. RXDT_DefineCategory(CLEANUP);
  62. RXDT_DefineCategory(CLOSE);
  63. RXDT_DefineCategory(READ);
  64. RXDT_DefineCategory(WRITE);
  65. RXDT_DefineCategory(LOCKCTRL);
  66. RXDT_DefineCategory(FLUSH);
  67. RXDT_DefineCategory(PREFIX);
  68. RXDT_DefineCategory(FCBSTRUCTS);
  69. RXDT_DefineCategory(DISPATCH);
  70. RXDT_DefineCategory(EA);
  71. RXDT_DefineCategory(DEVFCB);
  72. RXDT_DefineCategory(CONNECT);
  73. typedef enum _MRXSMB_INIT_STATES {
  74. MRXSMBINIT_ALL_INITIALIZATION_COMPLETED,
  75. MRXSMBINIT_MINIRDR_REGISTERED,
  76. MRXSMBINIT_START
  77. } MRXSMB_INIT_STATES;
  78. VOID
  79. MRxSmbInitUnwind(
  80. IN PDRIVER_OBJECT DriverObject,
  81. IN MRXSMB_INIT_STATES MRxSmbInitState
  82. );
  83. NTSTATUS
  84. MRxSmbFsdDispatch (
  85. IN PDEVICE_OBJECT DeviceObject,
  86. IN PIRP Irp
  87. );
  88. NTSTATUS
  89. DriverEntry(
  90. IN PDRIVER_OBJECT DriverObject,
  91. IN PUNICODE_STRING RegistryPath
  92. )
  93. /*++
  94. Routine Description:
  95. This is the initialization routine for the SMB mini redirector
  96. Arguments:
  97. DriverObject - Pointer to driver object created by the system.
  98. Return Value:
  99. RXSTATUS - The function value is the final status from the initialization
  100. operation.
  101. --*/
  102. {
  103. NTSTATUS Status;
  104. MRXSMB_INIT_STATES MRxSmbInitState = 0;
  105. UNICODE_STRING SmbMiniRedirectorName;
  106. UNICODE_STRING UserModeDeviceName;
  107. ULONG Controls = 0;
  108. PAGED_CODE();
  109. #ifdef MONOLITHIC_MINIRDR
  110. Status = RxDriverEntry(DriverObject, RegistryPath);
  111. if (Status != STATUS_SUCCESS) {
  112. DbgPrint("Wrapper failed to initialize. Status = %08lx\n",Status);
  113. return(Status);
  114. }
  115. #endif
  116. RtlZeroMemory(&MRxSmbStatistics,sizeof(MRxSmbStatistics));
  117. RtlZeroMemory(&MRxSmbConfiguration,sizeof(MRxSmbConfiguration));
  118. KeQuerySystemTime(&MRxSmbStatistics.StatisticsStartTime);
  119. RtlZeroMemory(&MrxSmbCeGlobalPadding,sizeof(MrxSmbCeGlobalPadding));
  120. MmInitializeMdl(&MrxSmbCeGlobalPadding.Mdl,&MrxSmbCeGlobalPadding.Pad[0],SMBCE_PADDING_DATA_SIZE);
  121. MmBuildMdlForNonPagedPool(&MrxSmbCeGlobalPadding.Mdl);
  122. ExInitializeFastMutex(&MRxSmbSerializationMutex);
  123. Status = MRxSmbInitializeTransport();
  124. if (Status != STATUS_SUCCESS) {
  125. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry failed to init transport data structures: %08lx\n", Status ));
  126. return(STATUS_UNSUCCESSFUL);
  127. }
  128. try {
  129. ExInitializeResourceLite(&s_SmbCeDbResource);
  130. MRxSmbInitState = MRXSMBINIT_START;
  131. RtlInitUnicodeString(&SmbMiniRedirectorName, DD_SMBMRX_FS_DEVICE_NAME_U);
  132. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry: DriverObject =%p\n", DriverObject ));
  133. SetFlag(Controls,RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS);
  134. Status = RxRegisterMinirdr(&MRxSmbDeviceObject,
  135. DriverObject,
  136. &MRxSmbDispatch,
  137. Controls,
  138. &SmbMiniRedirectorName,
  139. 0,
  140. FILE_DEVICE_NETWORK_FILE_SYSTEM,
  141. FILE_REMOTE_DEVICE
  142. );
  143. if (Status!=STATUS_SUCCESS) {
  144. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbDriverEntry failed: %08lx\n", Status ));
  145. try_return(Status);
  146. }
  147. MRxSmbInitState = MRXSMBINIT_MINIRDR_REGISTERED;
  148. RtlInitUnicodeString(&UserModeDeviceName, DD_SMBMRX_USERMODE_SHADOW_DEV_NAME_U);
  149. Status = IoCreateSymbolicLink( &UserModeDeviceName, &SmbMiniRedirectorName);
  150. //for all this stuff, there's no undo.....so no extra state
  151. Status = MRxSmbInitializeTables();
  152. if (!NT_SUCCESS( Status )) {
  153. try_return(Status);
  154. }
  155. RtlInitUnicodeString(&SmbCeContext.ComputerName,NULL);
  156. RtlInitUnicodeString(&SmbCeContext.OperatingSystem, NULL);
  157. RtlInitUnicodeString(&SmbCeContext.LanmanType, NULL);
  158. RtlInitUnicodeString(&SmbCeContext.Transports, NULL);
  159. MRxSmbConfiguration.SessionTimeoutInterval = MRXSMB_DEFAULT_TIMED_EXCHANGE_EXPIRY_TIME;
  160. MRxSmbConfiguration.LockIncrement = 0;
  161. MRxSmbConfiguration.MaximumLock = 1000;
  162. SmbCeGetConfigurationInformation();
  163. SmbCeGetComputerName();
  164. SmbCeGetOperatingSystemInformation();
  165. try_exit: NOTHING;
  166. } finally {
  167. if (Status != STATUS_SUCCESS) {
  168. MRxSmbInitUnwind(DriverObject,MRxSmbInitState);
  169. }
  170. }
  171. if (Status != STATUS_SUCCESS) {
  172. DbgPrint("MRxSmb failed to start with %08lx %08lx\n",Status,MRxSmbInitState);
  173. return(Status);
  174. }
  175. // Setup Unload Routine
  176. DriverObject->DriverUnload = MRxSmbUnload;
  177. // set all IRR_MJ to the dispatch point
  178. {
  179. ULONG i;
  180. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  181. DriverObject->MajorFunction[i] = (PDRIVER_DISPATCH)MRxSmbFsdDispatch;
  182. }
  183. }
  184. //and get out
  185. return STATUS_SUCCESS;
  186. }
  187. VOID
  188. MRxSmbInitUnwind(
  189. IN PDRIVER_OBJECT DriverObject,
  190. IN MRXSMB_INIT_STATES MRxSmbInitState
  191. )
  192. /*++
  193. Routine Description:
  194. This routine does the common uninit work for unwinding from a bad driver entry or for unloading.
  195. Arguments:
  196. RxInitState - tells how far we got into the intialization
  197. Return Value:
  198. None
  199. --*/
  200. {
  201. PAGED_CODE();
  202. switch (MRxSmbInitState) {
  203. case MRXSMBINIT_ALL_INITIALIZATION_COMPLETED:
  204. //Nothing extra to do...this is just so that the constant in RxUnload doesn't change.......
  205. //lack of break intentional
  206. case MRXSMBINIT_MINIRDR_REGISTERED:
  207. RxUnregisterMinirdr(MRxSmbDeviceObject);
  208. //lack of break intentional
  209. case MRXSMBINIT_START:
  210. // Deallocate the configuration strings ....
  211. if (SmbCeContext.ComputerName.Buffer != NULL) {
  212. RxFreePool(SmbCeContext.ComputerName.Buffer);
  213. }
  214. if (SmbCeContext.OperatingSystem.Buffer != NULL) {
  215. RxFreePool(SmbCeContext.OperatingSystem.Buffer);
  216. }
  217. if (SmbCeContext.LanmanType.Buffer != NULL) {
  218. RxFreePool(SmbCeContext.LanmanType.Buffer);
  219. }
  220. if (SmbCeContext.Transports.Buffer != NULL) {
  221. // the transports buffer is at the end of a larger buffer (by 12 bytes)
  222. // allocated to read the value from the registry. recover the original buffer
  223. // pointer in order to free.
  224. PKEY_VALUE_PARTIAL_INFORMATION TransportsValueFromRegistry;
  225. TransportsValueFromRegistry = CONTAINING_RECORD(
  226. SmbCeContext.Transports.Buffer,
  227. KEY_VALUE_PARTIAL_INFORMATION,
  228. Data[0]
  229. );
  230. //DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,SmbCeContext.Transports.Buffer);
  231. RxFreePool(TransportsValueFromRegistry);
  232. SmbCeContext.Transports.Buffer = NULL;
  233. SmbCeContext.Transports.Length = 0;
  234. SmbCeContext.Transports.MaximumLength = 0;
  235. }
  236. MRxSmbUninitializeTransport();
  237. ExDeleteResourceLite(&s_SmbCeDbResource);
  238. break;
  239. }
  240. }
  241. VOID
  242. MRxSmbUnload(
  243. IN PDRIVER_OBJECT DriverObject
  244. )
  245. /*++
  246. Routine Description:
  247. This is the unload routine for the SMB mini redirector.
  248. Arguments:
  249. DriverObject - pointer to the driver object for the MRxSmb
  250. Return Value:
  251. None
  252. --*/
  253. {
  254. UNICODE_STRING UserModeDeviceName;
  255. PAGED_CODE();
  256. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbUnload: DriverObject =%p\n", DriverObject) );
  257. MRxSmbInitUnwind(DriverObject,MRXSMBINIT_ALL_INITIALIZATION_COMPLETED);
  258. RtlInitUnicodeString(&UserModeDeviceName, DD_SMBMRX_USERMODE_SHADOW_DEV_NAME_U);
  259. IoDeleteSymbolicLink( &UserModeDeviceName);
  260. #ifdef MONOLITHIC_MINIRDR
  261. RxUnload(DriverObject);
  262. #endif
  263. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("MRxSmbUnload exit: DriverObject =%p\n", DriverObject) );
  264. }
  265. NTSTATUS
  266. MRxSmbInitializeTables(
  267. void
  268. )
  269. /*++
  270. Routine Description:
  271. This routine sets up the mini redirector dispatch vector and also calls to initialize any other tables needed.
  272. Return Value:
  273. RXSTATUS - The return status for the operation
  274. --*/
  275. {
  276. PAGED_CODE();
  277. // Ensure that the SMB mini redirector context satisfies the size constraints
  278. ASSERT(sizeof(MRXSMB_RX_CONTEXT) <= MRX_CONTEXT_SIZE);
  279. //local minirdr dispatch table init
  280. ZeroAndInitializeNodeType( &MRxSmbDispatch, RDBSS_NTC_MINIRDR_DISPATCH, sizeof(MINIRDR_DISPATCH));
  281. // SMB mini redirector extension sizes and allocation policies.
  282. MRxSmbDispatch.MRxFlags = (RDBSS_MANAGE_FCB_EXTENSION |
  283. RDBSS_MANAGE_SRV_OPEN_EXTENSION |
  284. RDBSS_MANAGE_FOBX_EXTENSION);
  285. MRxSmbDispatch.MRxSrvCallSize = 0;
  286. MRxSmbDispatch.MRxNetRootSize = 0;
  287. MRxSmbDispatch.MRxVNetRootSize = 0;
  288. MRxSmbDispatch.MRxFcbSize = sizeof(MRX_SMB_FCB);
  289. MRxSmbDispatch.MRxSrvOpenSize = sizeof(MRX_SMB_SRV_OPEN);
  290. MRxSmbDispatch.MRxFobxSize = sizeof(MRX_SMB_FOBX);
  291. // Mini redirector cancel routine ..
  292. MRxSmbDispatch.MRxCancel = NULL;
  293. // Mini redirector Start/Stop
  294. MRxSmbDispatch.MRxStart = MRxSmbStart;
  295. MRxSmbDispatch.MRxStop = MRxSmbStop;
  296. MRxSmbDispatch.MRxDevFcbXXXControlFile = MRxSmbDevFcbXXXControlFile;
  297. // Mini redirector name resolution
  298. MRxSmbDispatch.MRxCreateSrvCall = MRxSmbCreateSrvCall;
  299. MRxSmbDispatch.MRxSrvCallWinnerNotify = MRxSmbSrvCallWinnerNotify;
  300. MRxSmbDispatch.MRxCreateVNetRoot = MRxSmbCreateVNetRoot;
  301. MRxSmbDispatch.MRxUpdateNetRootState = MRxSmbUpdateNetRootState;
  302. MRxSmbDispatch.MRxExtractNetRootName = MRxSmbExtractNetRootName;
  303. MRxSmbDispatch.MRxFinalizeSrvCall = MRxSmbFinalizeSrvCall;
  304. MRxSmbDispatch.MRxFinalizeNetRoot = MRxSmbFinalizeNetRoot;
  305. MRxSmbDispatch.MRxFinalizeVNetRoot = MRxSmbFinalizeVNetRoot;
  306. // File System Object Creation/Deletion.
  307. MRxSmbDispatch.MRxCreate = MRxSmbCreate;
  308. MRxSmbDispatch.MRxCollapseOpen = MRxSmbCollapseOpen;
  309. MRxSmbDispatch.MRxShouldTryToCollapseThisOpen
  310. = MRxSmbShouldTryToCollapseThisOpen;
  311. MRxSmbDispatch.MRxExtendForCache = MRxSmbExtendForCache;
  312. MRxSmbDispatch.MRxExtendForNonCache = MRxSmbExtendForNonCache;
  313. MRxSmbDispatch.MRxTruncate = MRxSmbTruncate;
  314. MRxSmbDispatch.MRxCleanupFobx = MRxSmbCleanupFobx;
  315. MRxSmbDispatch.MRxCloseSrvOpen = MRxSmbCloseSrvOpen;
  316. MRxSmbDispatch.MRxFlush = MRxSmbFlush;
  317. MRxSmbDispatch.MRxForceClosed = MRxSmbForcedClose;
  318. MRxSmbDispatch.MRxDeallocateForFcb = MRxSmbDeallocateForFcb;
  319. MRxSmbDispatch.MRxDeallocateForFobx = MRxSmbDeallocateForFobx;
  320. MRxSmbDispatch.MRxIsLockRealizable = MRxSmbIsLockRealizable;
  321. // File System Objects query/Set
  322. MRxSmbDispatch.MRxQueryDirectory = MRxSmbQueryDirectory;
  323. MRxSmbDispatch.MRxQueryVolumeInfo = MRxSmbQueryVolumeInformation;
  324. MRxSmbDispatch.MRxSetVolumeInfo = MRxSmbSetVolumeInformation;
  325. MRxSmbDispatch.MRxQueryEaInfo = MRxSmbQueryEaInformation;
  326. MRxSmbDispatch.MRxSetEaInfo = MRxSmbSetEaInformation;
  327. MRxSmbDispatch.MRxQuerySdInfo = MRxSmbQuerySecurityInformation;
  328. MRxSmbDispatch.MRxSetSdInfo = MRxSmbSetSecurityInformation;
  329. MRxSmbDispatch.MRxQueryQuotaInfo = MRxSmbQueryQuotaInformation;
  330. MRxSmbDispatch.MRxSetQuotaInfo = MRxSmbSetQuotaInformation;
  331. MRxSmbDispatch.MRxQueryFileInfo = MRxSmbQueryFileInformation;
  332. MRxSmbDispatch.MRxSetFileInfo = MRxSmbSetFileInformation;
  333. MRxSmbDispatch.MRxSetFileInfoAtCleanup
  334. = MRxSmbSetFileInformationAtCleanup;
  335. MRxSmbDispatch.MRxIsValidDirectory= MRxSmbIsValidDirectory;
  336. // Buffering state change
  337. MRxSmbDispatch.MRxComputeNewBufferingState = MRxSmbComputeNewBufferingState;
  338. // File System Object I/O
  339. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_READ] = MRxSmbRead;
  340. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_WRITE] = MRxSmbWrite;
  341. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = MRxSmbLocks;
  342. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_EXCLUSIVELOCK] = MRxSmbLocks;
  343. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = MRxSmbLocks;
  344. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_UNLOCK_MULTIPLE] = MRxSmbLocks;
  345. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_FSCTL] = MRxSmbFsCtl;
  346. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_IOCTL] = MRxSmbIoCtl;
  347. MRxSmbDispatch.MRxLowIOSubmit[LOWIO_OP_NOTIFY_CHANGE_DIRECTORY] = MRxSmbNotifyChangeDirectory;
  348. // Miscellanous
  349. MRxSmbDispatch.MRxCompleteBufferingStateChangeRequest = MRxSmbCompleteBufferingStateChangeRequest;
  350. // initialize the paging file list
  351. InitializeListHead(&MRxSmbPagingFilesSrvOpenList);
  352. // now callout to initialize other tables
  353. SmbPseInitializeTables();
  354. return(STATUS_SUCCESS);
  355. }
  356. NTSTATUS
  357. MRxSmbStart(
  358. PRX_CONTEXT RxContext,
  359. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  360. )
  361. /*++
  362. Routine Description:
  363. This routine completes the initialization of the mini redirector fromn the
  364. RDBSS perspective. Note that this is different from the initialization done
  365. in DriverEntry. Any initialization that depends on RDBSS should be done as
  366. part of this routine while the initialization that is independent of RDBSS
  367. should be done in the DriverEntry routine.
  368. Arguments:
  369. RxContext - Supplies the Irp that was used to startup the rdbss
  370. Return Value:
  371. RXSTATUS - The return status for the operation
  372. --*/
  373. {
  374. NTSTATUS Status;
  375. MRXSMB_STATE CurrentState;
  376. PAGED_CODE();
  377. CurrentState = (MRXSMB_STATE)
  378. InterlockedCompareExchange(
  379. (PLONG)&MRxSmbState,
  380. MRXSMB_STARTED,
  381. MRXSMB_START_IN_PROGRESS);
  382. if (CurrentState == MRXSMB_START_IN_PROGRESS) {
  383. MRxSmbPoRegistrationState = PoRegisterSystemState(
  384. NULL,0);
  385. // Initialize the SMB connection engine data structures
  386. Status = SmbCeDbInit();
  387. if (NT_SUCCESS(Status)) {
  388. Status = MRxSmbInitializeSecurity();
  389. if (NT_SUCCESS(Status)) {
  390. Status = SmbMrxInitializeStufferFacilities();
  391. } else {
  392. RxLogFailure (
  393. MRxSmbDeviceObject,
  394. NULL,
  395. EVENT_RDR_UNEXPECTED_ERROR,
  396. Status);
  397. }
  398. if (NT_SUCCESS(Status)) {
  399. Status = MRxSmbInitializeRecurrentServices();
  400. } else {
  401. RxLogFailure (
  402. MRxSmbDeviceObject,
  403. NULL,
  404. EVENT_RDR_UNEXPECTED_ERROR,
  405. Status);
  406. }
  407. if (NT_SUCCESS(Status)) {
  408. Status = MRxSmbRegisterForPnpNotifications();
  409. } else {
  410. RxLogFailure (
  411. MRxSmbDeviceObject,
  412. NULL,
  413. EVENT_RDR_UNEXPECTED_ERROR,
  414. Status);
  415. }
  416. if (Status == STATUS_SUCCESS) {
  417. if (Status != STATUS_SUCCESS) {
  418. RxLogFailure (
  419. MRxSmbDeviceObject,
  420. NULL,
  421. EVENT_RDR_UNEXPECTED_ERROR,
  422. Status);
  423. }
  424. } else {
  425. RxLogFailure (
  426. MRxSmbDeviceObject,
  427. NULL,
  428. EVENT_RDR_UNEXPECTED_ERROR,
  429. Status);
  430. }
  431. }
  432. } else if (MRxSmbState == MRXSMB_STARTED) {
  433. Status = STATUS_REDIRECTOR_STARTED;
  434. } else {
  435. Status = STATUS_UNSUCCESSFUL;
  436. }
  437. return Status;
  438. }
  439. NTSTATUS
  440. MRxSmbStop(
  441. PRX_CONTEXT RxContext,
  442. IN OUT PRDBSS_DEVICE_OBJECT RxDeviceObject
  443. )
  444. /*++
  445. Routine Description:
  446. This routine is used to activate the mini redirector from the RDBSS perspective
  447. Arguments:
  448. RxContext - the context that was used to start the mini redirector
  449. pContext - the SMB mini rdr context passed in at registration time.
  450. Return Value:
  451. RXSTATUS - The return status for the operation
  452. --*/
  453. {
  454. NTSTATUS Status;
  455. PAGED_CODE();
  456. // Tear down the registration for notifications
  457. MRxSmbDeregisterForPnpNotifications();
  458. // tear down the recurrent services
  459. MRxSmbTearDownRecurrentServices();
  460. SmbMrxFinalizeStufferFacilities();
  461. MRxSmbUninitializeSecurity();
  462. // Tear down the connection engine database
  463. SmbCeDbTearDown();
  464. PoUnregisterSystemState(
  465. MRxSmbPoRegistrationState);
  466. if (s_pNegotiateSmb != NULL) {
  467. RxFreePool(s_pNegotiateSmb - TRANSPORT_HEADER_SIZE);
  468. s_pNegotiateSmb = NULL;
  469. }
  470. return(STATUS_SUCCESS);
  471. }
  472. NTSTATUS
  473. MRxSmbInitializeSecurity (VOID)
  474. /*++
  475. Routine Description:
  476. This routine initializes the SMB miniredirector security .
  477. Arguments:
  478. None.
  479. Return Value:
  480. None.
  481. Note:
  482. This API can only be called from a FS process.
  483. --*/
  484. {
  485. NTSTATUS Status = STATUS_SUCCESS;
  486. PAGED_CODE();
  487. if (MRxSmbSecurityInitialized)
  488. return STATUS_SUCCESS;
  489. if ( NULL == InitSecurityInterfaceW() ) {
  490. ASSERT(FALSE);
  491. Status = STATUS_INVALID_PARAMETER;
  492. } else {
  493. MRxSmbSecurityInitialized = TRUE;
  494. Status = STATUS_SUCCESS;
  495. }
  496. ASSERT(IoGetCurrentProcess() == RxGetRDBSSProcess());
  497. return Status;
  498. }
  499. NTSTATUS
  500. MRxSmbUninitializeSecurity(VOID)
  501. /*++
  502. Routine Description:
  503. Arguments:
  504. None.
  505. Return Value:
  506. None.
  507. Note:
  508. This API can only be called from a FS process.
  509. --*/
  510. {
  511. NTSTATUS Status = STATUS_SUCCESS;
  512. PAGED_CODE();
  513. return Status;
  514. }
  515. #define SMBMRX_CONFIG_COMPUTER_NAME \
  516. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName"
  517. #define COMPUTERNAME L"ComputerName"
  518. #define SMBMRX_CONFIG_TRANSPORTS \
  519. L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanWorkStation\\Linkage"
  520. #define TRANSPORT_BINDINGS L"Bind"
  521. NTSTATUS
  522. SmbCeGetConfigurationInformation()
  523. {
  524. ULONG Storage[256];
  525. UNICODE_STRING UnicodeString;
  526. HANDLE hRegistryKey;
  527. NTSTATUS Status;
  528. ULONG BytesRead;
  529. OBJECT_ATTRIBUTES ObjectAttributes;
  530. PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
  531. KEY_VALUE_PARTIAL_INFORMATION InitialPartialInformationValue;
  532. ULONG AllocationLength;
  533. PKEY_VALUE_PARTIAL_INFORMATION TransportsValueFromRegistry;
  534. PAGED_CODE();
  535. // Obtain the list of transports associated with SMB redirector. This is stored
  536. // as a multivalued string and is used subsequently to weed out the
  537. // appropriate transports. This is a two step process; first we try to find out
  538. // how much space we need; then we allocate; then we read in. unfortunately, the kind of
  539. // structure that we have to use to get the value has a header on it, so we have to offset the
  540. // returned pointer both here and in the free routine.
  541. RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_TRANSPORTS);
  542. InitializeObjectAttributes(
  543. &ObjectAttributes,
  544. &UnicodeString, // name
  545. OBJ_CASE_INSENSITIVE, // attributes
  546. NULL, // root
  547. NULL); // security descriptor
  548. Status = ZwOpenKey (&hRegistryKey, KEY_READ, &ObjectAttributes);
  549. if (!NT_SUCCESS(Status)) {
  550. return Status;
  551. }
  552. RtlInitUnicodeString(&UnicodeString, TRANSPORT_BINDINGS);
  553. Status = ZwQueryValueKey(
  554. hRegistryKey,
  555. &UnicodeString,
  556. KeyValuePartialInformation,
  557. &InitialPartialInformationValue,
  558. sizeof(InitialPartialInformationValue),
  559. &BytesRead);
  560. if (Status== STATUS_BUFFER_OVERFLOW) {
  561. Status = STATUS_SUCCESS;
  562. }
  563. if (!NT_SUCCESS(Status)) {
  564. ZwClose(hRegistryKey);
  565. return Status;
  566. }
  567. AllocationLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION)
  568. + InitialPartialInformationValue.DataLength;
  569. if (0) {
  570. DbgPrint("SizeofBindingInfo=%08lx %08lx\n",
  571. AllocationLength,
  572. InitialPartialInformationValue.DataLength);
  573. }
  574. if (AllocationLength > 0xFFFF) {
  575. //
  576. // Don't allow registry value to consume too much memory
  577. //
  578. return STATUS_INSUFFICIENT_RESOURCES;
  579. }
  580. //RtlInitUnicodeString(&UnicodeString, TRANSPORT_BINDINGS);
  581. if (SmbCeContext.Transports.Buffer != NULL) {
  582. // the transports buffer is at the end of a larger buffer (by 12 bytes)
  583. // allocated to read the value from the registry. recover the original buffer
  584. // pointer in orer to free.
  585. TransportsValueFromRegistry = CONTAINING_RECORD(
  586. SmbCeContext.Transports.Buffer,
  587. KEY_VALUE_PARTIAL_INFORMATION,
  588. Data[0]
  589. );
  590. //DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,SmbCeContext.Transports.Buffer);
  591. RxFreePool(TransportsValueFromRegistry);
  592. SmbCeContext.Transports.Buffer = NULL;
  593. SmbCeContext.Transports.Length = 0;
  594. SmbCeContext.Transports.MaximumLength = 0;
  595. }
  596. (PBYTE)TransportsValueFromRegistry = RxAllocatePoolWithTag(
  597. PagedPool,
  598. AllocationLength,
  599. MRXSMB_MISC_POOLTAG);
  600. if (TransportsValueFromRegistry == NULL) {
  601. ZwClose(hRegistryKey);
  602. return(STATUS_INSUFFICIENT_RESOURCES);
  603. }
  604. Status = ZwQueryValueKey(
  605. hRegistryKey,
  606. &UnicodeString,
  607. KeyValuePartialInformation,
  608. TransportsValueFromRegistry,
  609. AllocationLength,
  610. &BytesRead);
  611. if (NT_SUCCESS(Status) &&
  612. (TransportsValueFromRegistry->DataLength > 0) &&
  613. (TransportsValueFromRegistry->Type == REG_MULTI_SZ)) {
  614. SmbCeContext.Transports.MaximumLength =
  615. SmbCeContext.Transports.Length = (USHORT)TransportsValueFromRegistry->DataLength;
  616. SmbCeContext.Transports.Buffer = (PWCHAR)(&TransportsValueFromRegistry->Data[0]);
  617. //DbgPrint("b1 %08lx b2 %08lx\n", TransportsValueFromRegistry,SmbCeContext.Transports.Buffer);
  618. } else {
  619. RxLog(("Invalid Transport Binding string... using all transports"));
  620. RxFreePool(TransportsValueFromRegistry);
  621. TransportsValueFromRegistry = NULL;
  622. }
  623. ZwClose(hRegistryKey);
  624. return Status;
  625. }
  626. NTSTATUS
  627. SmbCeGetComputerName(
  628. VOID
  629. )
  630. {
  631. ULONG Storage[256];
  632. UNICODE_STRING UnicodeString;
  633. HANDLE hRegistryKey;
  634. NTSTATUS Status;
  635. ULONG BytesRead;
  636. OBJECT_ATTRIBUTES ObjectAttributes;
  637. PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
  638. KEY_VALUE_PARTIAL_INFORMATION InitialPartialInformationValue;
  639. ULONG AllocationLength;
  640. PAGED_CODE();
  641. ASSERT(SmbCeContext.ComputerName.Buffer == NULL);
  642. // Obtain the computer name. This is used in formulating the local NETBIOS address
  643. RtlInitUnicodeString(&SmbCeContext.ComputerName, NULL);
  644. RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_COMPUTER_NAME);
  645. InitializeObjectAttributes(
  646. &ObjectAttributes,
  647. &UnicodeString, // name
  648. OBJ_CASE_INSENSITIVE, // attributes
  649. NULL, // root
  650. NULL); // security descriptor
  651. Status = ZwOpenKey (&hRegistryKey, KEY_READ, &ObjectAttributes);
  652. if (!NT_SUCCESS(Status)) {
  653. return Status;
  654. }
  655. RtlInitUnicodeString(&UnicodeString, COMPUTERNAME);
  656. Status = ZwQueryValueKey(
  657. hRegistryKey,
  658. &UnicodeString,
  659. KeyValueFullInformation,
  660. Value,
  661. sizeof(Storage),
  662. &BytesRead);
  663. if (NT_SUCCESS(Status)) {
  664. // Rtl conversion routines require NULL char to be excluded from the
  665. // length.
  666. SmbCeContext.ComputerName.MaximumLength =
  667. SmbCeContext.ComputerName.Length = (USHORT)Value->DataLength - sizeof(WCHAR);
  668. SmbCeContext.ComputerName.Buffer = RxAllocatePoolWithTag(
  669. PagedPool,
  670. SmbCeContext.ComputerName.Length,
  671. MRXSMB_MISC_POOLTAG);
  672. if (SmbCeContext.ComputerName.Buffer != NULL) {
  673. RtlCopyMemory(SmbCeContext.ComputerName.Buffer,
  674. (PCHAR)Value+Value->DataOffset,
  675. Value->DataLength - sizeof(WCHAR));
  676. } else {
  677. Status = STATUS_INSUFFICIENT_RESOURCES;
  678. }
  679. }
  680. ZwClose(hRegistryKey);
  681. return Status;
  682. }
  683. NTSTATUS
  684. SmbCeGetOperatingSystemInformation(
  685. VOID
  686. )
  687. {
  688. ULONG Storage[256];
  689. UNICODE_STRING UnicodeString;
  690. HANDLE hRegistryKey;
  691. NTSTATUS Status;
  692. ULONG BytesRead;
  693. OBJECT_ATTRIBUTES ObjectAttributes;
  694. PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage;
  695. KEY_VALUE_PARTIAL_INFORMATION InitialPartialInformationValue;
  696. ULONG AllocationLength;
  697. PAGED_CODE();
  698. ASSERT(SmbCeContext.OperatingSystem.Buffer == NULL);
  699. ASSERT(SmbCeContext.LanmanType.Buffer == NULL);
  700. RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_CURRENT_WINDOWS_VERSION);
  701. InitializeObjectAttributes(
  702. &ObjectAttributes,
  703. &UnicodeString, // name
  704. OBJ_CASE_INSENSITIVE, // attributes
  705. NULL, // root
  706. NULL); // security descriptor
  707. Status = ZwOpenKey (&hRegistryKey, KEY_READ, &ObjectAttributes);
  708. if (!NT_SUCCESS(Status)) {
  709. return Status;
  710. }
  711. RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_OPERATING_SYSTEM);
  712. Status = ZwQueryValueKey(
  713. hRegistryKey,
  714. &UnicodeString,
  715. KeyValueFullInformation,
  716. Value,
  717. sizeof(Storage),
  718. &BytesRead);
  719. if (NT_SUCCESS(Status)) {
  720. SmbCeContext.OperatingSystem.MaximumLength =
  721. (USHORT)Value->DataLength + sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME) - sizeof(WCHAR);
  722. SmbCeContext.OperatingSystem.Length = SmbCeContext.OperatingSystem.MaximumLength - sizeof(WCHAR);
  723. SmbCeContext.OperatingSystem.Buffer = RxAllocatePoolWithTag(
  724. PagedPool,
  725. SmbCeContext.OperatingSystem.MaximumLength,
  726. MRXSMB_MISC_POOLTAG);
  727. if (SmbCeContext.OperatingSystem.Buffer != NULL) {
  728. RtlCopyMemory(SmbCeContext.OperatingSystem.Buffer,
  729. SMBMRX_CONFIG_OPERATING_SYSTEM_NAME,
  730. sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME));
  731. RtlCopyMemory((SmbCeContext.OperatingSystem.Buffer +
  732. (sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME)/sizeof(WCHAR)) - 1),
  733. (PCHAR)Value+Value->DataOffset,
  734. Value->DataLength);
  735. } else {
  736. Status = STATUS_INSUFFICIENT_RESOURCES;
  737. }
  738. }
  739. if (NT_SUCCESS(Status)) {
  740. RtlInitUnicodeString(&UnicodeString, SMBMRX_CONFIG_OPERATING_SYSTEM_VERSION);
  741. Status = ZwQueryValueKey(
  742. hRegistryKey,
  743. &UnicodeString,
  744. KeyValueFullInformation,
  745. Value,
  746. sizeof(Storage),
  747. &BytesRead);
  748. if (NT_SUCCESS(Status)) {
  749. SmbCeContext.LanmanType.MaximumLength =
  750. SmbCeContext.LanmanType.Length = (USHORT)Value->DataLength +
  751. sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME) -
  752. sizeof(WCHAR);
  753. SmbCeContext.LanmanType.Buffer = RxAllocatePoolWithTag(
  754. PagedPool,
  755. SmbCeContext.LanmanType.Length,
  756. MRXSMB_MISC_POOLTAG);
  757. if (SmbCeContext.LanmanType.Buffer != NULL) {
  758. RtlCopyMemory(
  759. SmbCeContext.LanmanType.Buffer,
  760. SMBMRX_CONFIG_OPERATING_SYSTEM_NAME,
  761. sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME));
  762. RtlCopyMemory(
  763. (SmbCeContext.LanmanType.Buffer +
  764. (sizeof(SMBMRX_CONFIG_OPERATING_SYSTEM_NAME)/sizeof(WCHAR)) - 1),
  765. (PCHAR)Value+Value->DataOffset,
  766. Value->DataLength);
  767. } else {
  768. Status = STATUS_INSUFFICIENT_RESOURCES;
  769. }
  770. }
  771. }
  772. ZwClose(hRegistryKey);
  773. return Status;
  774. }
  775. NTSTATUS
  776. MRxSmbPnpIrpCompletion(
  777. PDEVICE_OBJECT pDeviceObject,
  778. PIRP pIrp,
  779. PVOID pContext)
  780. /*++
  781. Routine Description:
  782. This routine completes the PNP irp for SMB mini redirector.
  783. Arguments:
  784. DeviceObject - Supplies the device object for the packet being processed.
  785. pIrp - Supplies the Irp being processed
  786. pContext - the completion context
  787. --*/
  788. {
  789. PKEVENT pCompletionEvent = pContext;
  790. KeSetEvent(
  791. pCompletionEvent,
  792. IO_NO_INCREMENT,
  793. FALSE);
  794. return STATUS_MORE_PROCESSING_REQUIRED;
  795. }
  796. NTSTATUS
  797. MRxSmbProcessPnpIrp(
  798. PIRP pIrp)
  799. /*++
  800. Routine Description:
  801. This routine initiates the processing of PNP irps for SMB mini redirector.
  802. Arguments:
  803. pIrp - Supplies the Irp being processed
  804. Notes:
  805. The query target device relation is the only call that is implemented
  806. currently. This is done by returing the PDO associated with the transport
  807. connection object. In any case this routine assumes the responsibility of
  808. completing the IRP and return STATUS_PENDING.
  809. This routine also writes an error log entry when the underlying transport
  810. fails the request. This should help us isolate the responsibility.
  811. --*/
  812. {
  813. NTSTATUS Status;
  814. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( pIrp );
  815. IoMarkIrpPending(pIrp);
  816. if ((IrpSp->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS) &&
  817. (IrpSp->Parameters.QueryDeviceRelations.Type==TargetDeviceRelation)) {
  818. PIRP pAssociatedIrp;
  819. PFILE_OBJECT pConnectionFileObject = NULL;
  820. PMRX_FCB pFcb = NULL;
  821. PSMBCEDB_SERVER_ENTRY pServerEntry = NULL;
  822. BOOLEAN ServerTransportReferenced = FALSE;
  823. // Locate the transport connection object for the associated file object
  824. // and forward the query to that device.
  825. if ((IrpSp->FileObject != NULL) &&
  826. ((pFcb = IrpSp->FileObject->FsContext) != NULL) &&
  827. (NodeTypeIsFcb(pFcb))) {
  828. PMRX_SRV_CALL pSrvCall;
  829. PMRX_NET_ROOT pNetRoot;
  830. if (((pNetRoot = pFcb->pNetRoot) != NULL) &&
  831. ((pSrvCall = pNetRoot->pSrvCall) != NULL)) {
  832. pServerEntry = pSrvCall->Context;
  833. if (pServerEntry != NULL) {
  834. SmbCeAcquireResource();
  835. Status = SmbCeReferenceServerTransport(&pServerEntry->pTransport);
  836. if (Status == STATUS_SUCCESS) {
  837. pConnectionFileObject = SmbCepReferenceEndpointFileObject(
  838. pServerEntry->pTransport);
  839. ServerTransportReferenced = TRUE;
  840. }
  841. SmbCeReleaseResource();
  842. }
  843. }
  844. }
  845. if (pConnectionFileObject != NULL) {
  846. PDEVICE_OBJECT pRelatedDeviceObject;
  847. PIO_STACK_LOCATION pIrpStackLocation,
  848. pAssociatedIrpStackLocation;
  849. pRelatedDeviceObject = IoGetRelatedDeviceObject(pConnectionFileObject);
  850. pAssociatedIrp = IoAllocateIrp(
  851. pRelatedDeviceObject->StackSize,
  852. FALSE);
  853. if (pAssociatedIrp != NULL) {
  854. KEVENT CompletionEvent;
  855. KeInitializeEvent( &CompletionEvent,
  856. SynchronizationEvent,
  857. FALSE );
  858. // Fill up the associated IRP and call the underlying driver.
  859. pAssociatedIrpStackLocation = IoGetNextIrpStackLocation(pAssociatedIrp);
  860. pIrpStackLocation = IoGetCurrentIrpStackLocation(pIrp);
  861. *pAssociatedIrpStackLocation = *pIrpStackLocation;
  862. pAssociatedIrpStackLocation->FileObject = pConnectionFileObject;
  863. pAssociatedIrpStackLocation->DeviceObject = pRelatedDeviceObject;
  864. IoSetCompletionRoutine(
  865. pAssociatedIrp,
  866. MRxSmbPnpIrpCompletion,
  867. &CompletionEvent,
  868. TRUE,TRUE,TRUE);
  869. pAssociatedIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
  870. Status = IoCallDriver(pRelatedDeviceObject,pAssociatedIrp);
  871. if (Status == STATUS_PENDING) {
  872. (VOID) KeWaitForSingleObject(
  873. &CompletionEvent,
  874. Executive,
  875. KernelMode,
  876. FALSE,
  877. (PLARGE_INTEGER) NULL );
  878. }
  879. pIrp->IoStatus = pAssociatedIrp->IoStatus;
  880. Status = pIrp->IoStatus.Status;
  881. ObDereferenceObject(pConnectionFileObject);
  882. IoFreeIrp(pAssociatedIrp);
  883. } else {
  884. Status = STATUS_INSUFFICIENT_RESOURCES;
  885. }
  886. } else {
  887. Status = STATUS_INVALID_DEVICE_REQUEST;
  888. }
  889. if (ServerTransportReferenced) {
  890. SmbCeDereferenceServerTransport(&pServerEntry->pTransport);
  891. }
  892. } else {
  893. Status = STATUS_INVALID_DEVICE_REQUEST;
  894. }
  895. if (Status != STATUS_PENDING) {
  896. pIrp->IoStatus.Status = Status;
  897. IoCompleteRequest(pIrp,IO_NO_INCREMENT);
  898. Status = STATUS_PENDING;
  899. }
  900. return STATUS_PENDING;
  901. }
  902. NTSTATUS
  903. MRxSmbFsdDispatch (
  904. IN PDEVICE_OBJECT DeviceObject,
  905. IN PIRP Irp
  906. )
  907. /*++
  908. Routine Description:
  909. This routine implements the FSD dispatch for the smbmini DRIVER object.
  910. Arguments:
  911. DeviceObject - Supplies the device object for the packet being processed.
  912. Irp - Supplies the Irp being processed
  913. Return Value:
  914. RXSTATUS - The Fsd status for the Irp
  915. --*/
  916. {
  917. PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); //ok4ioget
  918. UCHAR MajorFunctionCode = IrpSp->MajorFunction;
  919. ULONG MinorFunctionCode = IrpSp->MinorFunction;
  920. BOOLEAN ForwardRequestToWrapper = TRUE;
  921. PSMBCEDB_SERVER_ENTRY pServerEntry = NULL;
  922. NTSTATUS Status;
  923. PAGED_CODE();
  924. ASSERT(DeviceObject==(PDEVICE_OBJECT)MRxSmbDeviceObject);
  925. if (DeviceObject!=(PDEVICE_OBJECT)MRxSmbDeviceObject) {
  926. Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  927. Irp->IoStatus.Information = 0;
  928. IoCompleteRequest(Irp, IO_NO_INCREMENT );
  929. return (STATUS_INVALID_DEVICE_REQUEST);
  930. }
  931. Status = STATUS_SUCCESS;
  932. FsRtlEnterFileSystem();
  933. // PnP IRPs are handled outside of the wrapper
  934. if (IrpSp->MajorFunction == IRP_MJ_PNP) {
  935. ForwardRequestToWrapper = FALSE;
  936. Status = MRxSmbProcessPnpIrp(Irp);
  937. }
  938. FsRtlExitFileSystem();
  939. if ((Status == STATUS_SUCCESS) &&
  940. ForwardRequestToWrapper){
  941. Status = RxFsdDispatch((PRDBSS_DEVICE_OBJECT)MRxSmbDeviceObject,Irp);
  942. } else if (Status != STATUS_PENDING) {
  943. Irp->IoStatus.Status = Status;
  944. Irp->IoStatus.Information = 0;
  945. IoCompleteRequest(Irp, IO_NO_INCREMENT );
  946. }
  947. if (pServerEntry != NULL ) {
  948. FsRtlEnterFileSystem();
  949. pServerEntry->TransportSpecifiedByUser = 0;
  950. SmbCeDereferenceServerEntry(pServerEntry);
  951. FsRtlExitFileSystem();
  952. }
  953. return Status;
  954. }
  955. NTSTATUS
  956. MRxSmbDeallocateForFcb (
  957. IN OUT PMRX_FCB pFcb
  958. )
  959. {
  960. PAGED_CODE();
  961. return(STATUS_SUCCESS);
  962. }
  963. NTSTATUS
  964. MRxSmbDeallocateForFobx (
  965. IN OUT PMRX_FOBX pFobx
  966. )
  967. {
  968. PAGED_CODE();
  969. IF_DEBUG {
  970. PMRX_SMB_FOBX smbFobx = MRxSmbGetFileObjectExtension(pFobx);
  971. PMRX_SRV_OPEN SrvOpen = pFobx->pSrvOpen;
  972. PMRX_FCB Fcb = SrvOpen->pFcb;
  973. if (smbFobx && FlagOn(smbFobx->Enumeration.Flags,SMBFOBX_ENUMFLAG_LOUD_FINALIZE)) {
  974. DbgPrint("Finalizobx side buffer %p %p %p %pon %wZ\n",
  975. 0, 0, // sidebuffer, count
  976. smbFobx,pFobx,GET_ALREADY_PREFIXED_NAME(SrvOpen,Fcb)
  977. );
  978. }
  979. }
  980. return(STATUS_SUCCESS);
  981. }
  982. NTSTATUS
  983. MRxSmbGetUlongRegistryParameter(
  984. HANDLE ParametersHandle,
  985. PWCHAR ParameterName,
  986. PULONG ParamUlong,
  987. BOOLEAN LogFailure
  988. )
  989. {
  990. ULONG Storage[16];
  991. PKEY_VALUE_PARTIAL_INFORMATION Value;
  992. ULONG ValueSize;
  993. UNICODE_STRING UnicodeString;
  994. NTSTATUS Status;
  995. ULONG BytesRead;
  996. PAGED_CODE(); //INIT
  997. Value = (PKEY_VALUE_PARTIAL_INFORMATION)Storage;
  998. ValueSize = sizeof(Storage);
  999. RtlInitUnicodeString(&UnicodeString, ParameterName);
  1000. Status = ZwQueryValueKey(ParametersHandle,
  1001. &UnicodeString,
  1002. KeyValuePartialInformation,
  1003. Value,
  1004. ValueSize,
  1005. &BytesRead);
  1006. if (NT_SUCCESS(Status)) {
  1007. if (Value->Type == REG_DWORD) {
  1008. PULONG ConfigValue = (PULONG)&Value->Data[0];
  1009. *ParamUlong = *((PULONG)ConfigValue);
  1010. return(STATUS_SUCCESS);
  1011. } else {
  1012. Status = STATUS_INVALID_PARAMETER;
  1013. }
  1014. }
  1015. if (!LogFailure) { return Status; }
  1016. RxLogFailureWithBuffer(
  1017. MRxSmbDeviceObject,
  1018. NULL,
  1019. EVENT_RDR_CANT_READ_REGISTRY,
  1020. Status,
  1021. ParameterName,
  1022. (USHORT)(wcslen(ParameterName)*sizeof(WCHAR))
  1023. );
  1024. return Status;
  1025. }