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.

1879 lines
61 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
  7. there is only one such function:
  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. #include "usrcnnct.h"
  17. #include "remboot.h"
  18. #include "rdrssp\secret.h"
  19. #include "windns.h"
  20. #ifdef MRXSMB_BUILD_FOR_CSC
  21. #include "csc.h"
  22. #endif //ifdef MRXSMB_BUILD_FOR_CSC
  23. //
  24. // Forward declarations.
  25. //
  26. NTSTATUS
  27. MRxSmbInitializeRemoteBootParameters(
  28. PRX_CONTEXT RxContext
  29. );
  30. NTSTATUS
  31. MRxSmbRemoteBootInitializeSecret(
  32. PRX_CONTEXT RxContext
  33. );
  34. #if defined(REMOTE_BOOT)
  35. NTSTATUS
  36. MRxSmbRemoteBootCheckForNewPassword(
  37. PRX_CONTEXT RxContext
  38. );
  39. NTSTATUS
  40. MRxSmbRemoteBootIsPasswordSettable(
  41. PRX_CONTEXT RxContext
  42. );
  43. NTSTATUS
  44. MRxSmbRemoteBootSetNewPassword(
  45. PRX_CONTEXT RxContext
  46. );
  47. NTSTATUS
  48. MRxSmbStartRbr(
  49. PRX_CONTEXT RxContext
  50. );
  51. //
  52. // This function is in ea.c.
  53. //
  54. VOID
  55. MRxSmbInitializeExtraAceArray(
  56. VOID
  57. );
  58. #endif // defined(REMOTE_BOOT)
  59. #ifdef ALLOC_PRAGMA
  60. #pragma alloc_text(PAGE, MRxSmbGetStatistics)
  61. #pragma alloc_text(PAGE, MRxSmbDevFcbXXXControlFile)
  62. #pragma alloc_text(PAGE, MRxSmbSetConfigurationInformation)
  63. #pragma alloc_text(PAGE, MRxSmbGetConfigurationInformation)
  64. #pragma alloc_text(PAGE, MRxSmbExternalStart)
  65. #pragma alloc_text(PAGE, MRxSmbTestDevIoctl)
  66. #pragma alloc_text(PAGE, MRxSmbInitializeRemoteBootParameters)
  67. #pragma alloc_text(PAGE, MRxSmbRemoteBootInitializeSecret)
  68. #if defined(REMOTE_BOOT)
  69. #pragma alloc_text(PAGE, MRxSmbRemoteBootCheckForNewPassword)
  70. #pragma alloc_text(PAGE, MRxSmbRemoteBootIsPasswordSettable)
  71. #pragma alloc_text(PAGE, MRxSmbRemoteBootSetNewPassword)
  72. #pragma alloc_text(PAGE, MRxSmbStartRbr)
  73. #endif // defined(REMOTE_BOOT)
  74. #endif
  75. //
  76. // The local trace mask for this part of the module
  77. //
  78. #define Dbg (DEBUG_TRACE_DEVFCB)
  79. MRX_SMB_STATISTICS MRxSmbStatistics;
  80. NTSTATUS
  81. MRxSmbGetStatistics(
  82. IN OUT PRX_CONTEXT RxContext
  83. )
  84. /*++
  85. Routine Description:
  86. This routine gathers the statistics from the mini redirector
  87. Arguments:
  88. RxContext - Describes the Fsctl and Context.
  89. Return Value:
  90. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  91. any other value indicates the appropriate error.
  92. Notes:
  93. --*/
  94. {
  95. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  96. PMRX_SMB_STATISTICS pStatistics;
  97. ULONG BufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  98. PAGED_CODE();
  99. pStatistics = (PMRX_SMB_STATISTICS)(LowIoContext->ParamsFor.FsCtl.pOutputBuffer);
  100. if (BufferLength < sizeof(MRX_SMB_STATISTICS)) {
  101. return STATUS_INVALID_PARAMETER;
  102. }
  103. RxContext->InformationToReturn = sizeof(MRX_SMB_STATISTICS);
  104. MRxSmbStatistics.SmbsReceived.QuadPart++;
  105. //some stuff we have to copy from the device object......
  106. MRxSmbStatistics.PagingReadBytesRequested = MRxSmbDeviceObject->PagingReadBytesRequested;
  107. MRxSmbStatistics.NonPagingReadBytesRequested = MRxSmbDeviceObject->NonPagingReadBytesRequested;
  108. MRxSmbStatistics.CacheReadBytesRequested = MRxSmbDeviceObject->CacheReadBytesRequested;
  109. MRxSmbStatistics.NetworkReadBytesRequested = MRxSmbDeviceObject->NetworkReadBytesRequested;
  110. MRxSmbStatistics.PagingWriteBytesRequested = MRxSmbDeviceObject->PagingWriteBytesRequested;
  111. MRxSmbStatistics.NonPagingWriteBytesRequested = MRxSmbDeviceObject->NonPagingWriteBytesRequested;
  112. MRxSmbStatistics.CacheWriteBytesRequested = MRxSmbDeviceObject->CacheWriteBytesRequested;
  113. MRxSmbStatistics.NetworkWriteBytesRequested = MRxSmbDeviceObject->NetworkWriteBytesRequested;
  114. MRxSmbStatistics.ReadOperations = MRxSmbDeviceObject->ReadOperations;
  115. MRxSmbStatistics.RandomReadOperations = MRxSmbDeviceObject->RandomReadOperations;
  116. MRxSmbStatistics.WriteOperations = MRxSmbDeviceObject->WriteOperations;
  117. MRxSmbStatistics.RandomWriteOperations = MRxSmbDeviceObject->RandomWriteOperations;
  118. MRxSmbStatistics.LargeReadSmbs = MRxSmbStatistics.ReadSmbs - MRxSmbStatistics.SmallReadSmbs;
  119. MRxSmbStatistics.LargeWriteSmbs = MRxSmbStatistics.WriteSmbs - MRxSmbStatistics.SmallWriteSmbs;
  120. MRxSmbStatistics.CurrentCommands = SmbCeStartStopContext.ActiveExchanges;
  121. *pStatistics = MRxSmbStatistics;
  122. return STATUS_SUCCESS;
  123. }
  124. NTSTATUS
  125. MRxSmbDevFcbXXXControlFile (
  126. IN OUT PRX_CONTEXT RxContext
  127. )
  128. /*++
  129. Routine Description:
  130. This routine handles all the device FCB related FSCTL's in the mini rdr
  131. Arguments:
  132. RxContext - Describes the Fsctl and Context.
  133. Return Value:
  134. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  135. any other value indicates the appropriate error in the startup sequence.
  136. Notes:
  137. There are some dependencies between the browser service and the redirector
  138. service that have implications regarding the sequence of actions for starting
  139. the mini redirector.
  140. The current LANMAN workstation service opens the LANMAN and BROWSER device
  141. objects, issues the LMR_START and LMDR_START IOCTL's and subsequently
  142. issues the BIND_TO_TRANSPORT IOCTL.
  143. In the multiple mini rdr/wrapper design for PNP the TDI registration is done
  144. at wrapper load time and the mini rdrs are notified of the existing transports
  145. at START time ( LMR_START ). Since there are no BIND_TO_TRANSPORT IOCTL in
  146. PNP the rdr is responsible for issuing the BIND_TO_TRANSPORT IOCTL to the \
  147. browser.
  148. This should be changed by having the BROWSER gave its own TDI registration
  149. but till then the invocatioon of RxStartMiniRdr routine must be deferred to
  150. FSCTL_LMR_BIND_TO_TRANSPORT so that the browser has been initialized correctly.
  151. The reason for this convoluted change is that there is a code freeze for checking
  152. in changes to the workstation service/browser.
  153. --*/
  154. {
  155. NTSTATUS Status;
  156. RxCaptureFobx;
  157. UCHAR MajorFunctionCode = RxContext->MajorFunction;
  158. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  159. ULONG ControlCode = LowIoContext->ParamsFor.FsCtl.FsControlCode;
  160. LUID ClientLogonID;
  161. LUID SystemLogonID = SYSTEM_LUID;
  162. BOOLEAN IsInServicesProcess = FALSE;
  163. SECURITY_SUBJECT_CONTEXT ClientContext;
  164. PAGED_CODE();
  165. SeCaptureSubjectContext(&ClientContext);
  166. SeLockSubjectContext(&ClientContext);
  167. Status = SeQueryAuthenticationIdToken(
  168. SeQuerySubjectContextToken(&ClientContext),
  169. &ClientLogonID);
  170. if (Status == STATUS_SUCCESS) {
  171. IsInServicesProcess = RtlEqualLuid(&ClientLogonID,&SystemLogonID);
  172. }
  173. SeUnlockSubjectContext(&ClientContext);
  174. SeReleaseSubjectContext(&ClientContext);
  175. RxDbgTrace(+1, Dbg, ("MRxSmbDevFcb\n"));
  176. switch (MajorFunctionCode) {
  177. case IRP_MJ_FILE_SYSTEM_CONTROL:
  178. {
  179. switch (LowIoContext->ParamsFor.FsCtl.MinorFunction) {
  180. case IRP_MN_USER_FS_REQUEST:
  181. switch (ControlCode) {
  182. case FSCTL_LMR_START: // normal start from wkssvc
  183. case FSCTL_LMR_START | 0x80000000: // remote boot start from ioinit
  184. switch (MRxSmbState) {
  185. case MRXSMB_STARTABLE:
  186. // The correct sequence of start events issued by the workstation
  187. // service would have avoided this. We can recover from this
  188. // by actually invoking RxStartMiniRdr.
  189. // Note that a start from ioinit for remote boot leaves the
  190. // redirector in the STARTABLE state.
  191. if (capFobx) {
  192. Status = STATUS_INVALID_DEVICE_REQUEST;
  193. goto FINALLY;
  194. }
  195. if (ControlCode != FSCTL_LMR_START) {
  196. //
  197. // Set a flag indicating that we are doing a remote boot.
  198. //
  199. MRxSmbBootedRemotely = TRUE;
  200. }
  201. //
  202. // Now is the time to read the registry to get the
  203. // computer name. We need to know whether this is
  204. // a remote boot before doing this in order to know
  205. // whether to read the computer name from the
  206. // ActiveComputerName key or the ComputerName key.
  207. // See the comment in init.c\SmbCeGetComputerName().
  208. //
  209. if (SmbCeContext.ComputerName.Buffer == NULL) {
  210. Status = SmbCeGetComputerName();
  211. } else {
  212. Status = STATUS_SUCCESS;
  213. }
  214. if (Status == STATUS_SUCCESS) {
  215. Status = MRxSmbExternalStart( RxContext );
  216. }
  217. if (Status != STATUS_SUCCESS) {
  218. return(Status);
  219. }
  220. //lack of break is intentional
  221. case MRXSMB_START_IN_PROGRESS:
  222. {
  223. Status = RxStartMinirdr(RxContext,&RxContext->PostRequest);
  224. if (Status == STATUS_REDIRECTOR_STARTED) {
  225. Status = STATUS_SUCCESS;
  226. }
  227. //
  228. // If we're initializing remote boot, store
  229. // certain parameters now.
  230. //
  231. if ((Status == STATUS_SUCCESS) &&
  232. (ControlCode != FSCTL_LMR_START)) {
  233. Status = MRxSmbInitializeRemoteBootParameters(RxContext);
  234. }
  235. //
  236. // If we are a remote boot client, and this start
  237. // comes from the workstation service, now is the
  238. // time to initialize the security package.
  239. //
  240. if (MRxSmbBootedRemotely &&
  241. (Status == STATUS_SUCCESS) &&
  242. (ControlCode == FSCTL_LMR_START)) {
  243. Status = MRxSmbInitializeSecurity();
  244. }
  245. }
  246. break;
  247. case MRXSMB_STARTED:
  248. Status = STATUS_SUCCESS;
  249. break;
  250. default:
  251. break;
  252. }
  253. break;
  254. case FSCTL_LMR_STOP:
  255. if (!IsInServicesProcess) {
  256. Status = STATUS_ACCESS_DENIED;
  257. goto FINALLY;
  258. }
  259. if (capFobx) {
  260. Status = STATUS_INVALID_DEVICE_REQUEST;
  261. goto FINALLY;
  262. }
  263. IF_NOT_MRXSMB_CSC_ENABLED{
  264. NOTHING;
  265. } else {
  266. if (!FlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP)) {
  267. MRxSmbCscAgentSynchronizationOnStop(RxContext);
  268. }
  269. }
  270. //
  271. // The redirector cannot be stopped on a remote boot machine.
  272. // Ignore (don't fail) the stop request.
  273. //
  274. if (!MRxSmbBootedRemotely) {
  275. if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0) {
  276. return STATUS_REDIRECTOR_HAS_OPEN_HANDLES;
  277. } else {
  278. MRXSMB_STATE CurrentState;
  279. CurrentState = (MRXSMB_STATE)
  280. InterlockedCompareExchange(
  281. (PLONG)&MRxSmbState,
  282. MRXSMB_STOPPED,
  283. MRXSMB_STARTED);
  284. // Only allow mrxsmb to be unloaded from workstation services
  285. MRxSmbDeviceObject->DriverObject->DriverUnload = MRxSmbUnload;
  286. //if (CurrentState == MRXSMB_STARTED) {
  287. Status = RxStopMinirdr(
  288. RxContext,
  289. &RxContext->PostRequest );
  290. if (Status == STATUS_SUCCESS)
  291. {
  292. MRxSmbPreUnload();
  293. }
  294. //} else {
  295. // Status = STATUS_REDIRECTOR_NOT_STARTED;
  296. //}
  297. }
  298. } else {
  299. Status = STATUS_SUCCESS;
  300. }
  301. break;
  302. case FSCTL_LMR_BIND_TO_TRANSPORT: // normal bind from wkssvc
  303. Status = STATUS_SUCCESS;
  304. break;
  305. case FSCTL_LMR_BIND_TO_TRANSPORT | 0x80000000: // remote boot bind from ioinit
  306. Status = MRxSmbRegisterForPnpNotifications();
  307. break;
  308. case FSCTL_LMR_UNBIND_FROM_TRANSPORT:
  309. Status = STATUS_SUCCESS;
  310. break;
  311. case FSCTL_LMR_ENUMERATE_TRANSPORTS:
  312. if (capFobx) {
  313. Status = STATUS_INVALID_DEVICE_REQUEST;
  314. goto FINALLY;
  315. }
  316. Status = MRxEnumerateTransports(
  317. RxContext,
  318. &RxContext->PostRequest);
  319. break;
  320. case FSCTL_LMR_ENUMERATE_CONNECTIONS:
  321. if (capFobx) {
  322. Status = STATUS_INVALID_DEVICE_REQUEST;
  323. goto FINALLY;
  324. }
  325. Status = MRxSmbEnumerateConnections(
  326. RxContext,
  327. &RxContext->PostRequest );
  328. break;
  329. case FSCTL_LMR_GET_CONNECTION_INFO:
  330. if (!capFobx) {
  331. Status = STATUS_INVALID_DEVICE_REQUEST;
  332. goto FINALLY;
  333. }
  334. Status = MRxSmbGetConnectionInfo(
  335. RxContext,
  336. &RxContext->PostRequest );
  337. break;
  338. case FSCTL_LMR_DELETE_CONNECTION:
  339. if (!capFobx) {
  340. Status = STATUS_INVALID_DEVICE_REQUEST;
  341. goto FINALLY;
  342. }
  343. Status = MRxSmbDeleteConnection(
  344. RxContext,
  345. &RxContext->PostRequest );
  346. break;
  347. case FSCTL_LMR_GET_STATISTICS:
  348. Status = MRxSmbGetStatistics(RxContext);
  349. break;
  350. case FSCTL_LMR_GET_CONFIG_INFO:
  351. if (!IsInServicesProcess) {
  352. Status = STATUS_ACCESS_DENIED;
  353. goto FINALLY;
  354. }
  355. Status = MRxSmbGetConfigurationInformation(RxContext);
  356. break;
  357. case FSCTL_LMR_SET_CONFIG_INFO:
  358. if (!IsInServicesProcess) {
  359. Status = STATUS_ACCESS_DENIED;
  360. goto FINALLY;
  361. }
  362. Status = MRxSmbSetConfigurationInformation(RxContext);
  363. break;
  364. case FSCTL_LMR_SET_DOMAIN_NAME:
  365. if (!IsInServicesProcess) {
  366. Status = STATUS_ACCESS_DENIED;
  367. goto FINALLY;
  368. }
  369. Status = MRxSmbSetDomainName(RxContext);
  370. break;
  371. #if 0
  372. case FSCTL_LMMR_STFFTEST:
  373. Status = MRxSmbStufferDebug(RxContext);
  374. break;
  375. #endif //if 0
  376. #if defined(REMOTE_BOOT)
  377. case FSCTL_LMR_START_RBR:
  378. Status = MRxSmbStartRbr(RxContext);
  379. break;
  380. #endif // defined(REMOTE_BOOT)
  381. case FSCTL_LMMR_RI_INITIALIZE_SECRET:
  382. Status = MRxSmbRemoteBootInitializeSecret(RxContext);
  383. break;
  384. #if defined(REMOTE_BOOT)
  385. case FSCTL_LMMR_RI_CHECK_FOR_NEW_PASSWORD:
  386. Status = MRxSmbRemoteBootCheckForNewPassword(RxContext);
  387. break;
  388. case FSCTL_LMMR_RI_IS_PASSWORD_SETTABLE:
  389. Status = MRxSmbRemoteBootIsPasswordSettable(RxContext);
  390. break;
  391. case FSCTL_LMMR_RI_SET_NEW_PASSWORD:
  392. Status = MRxSmbRemoteBootSetNewPassword(RxContext);
  393. break;
  394. #endif // defined(REMOTE_BOOT)
  395. case FSCTL_LMR_SET_SERVER_GUID:
  396. Status = MRxSmbSetServerGuid(RxContext);
  397. break;
  398. case FSCTL_LMR_GET_VERSIONS:
  399. case FSCTL_LMR_GET_HINT_SIZE:
  400. case FSCTL_LMR_ENUMERATE_PRINT_INFO:
  401. case FSCTL_LMR_START_SMBTRACE:
  402. case FSCTL_LMR_END_SMBTRACE:
  403. RxDbgTrace(-1, Dbg, ("RxCommonDevFCBFsCtl -> unimplemented rdr1 fsctl\n"));
  404. //lack of break intentional
  405. default:
  406. Status = STATUS_INVALID_DEVICE_REQUEST;
  407. }
  408. break;
  409. default : //minor function != IRP_MN_USER_FS_REQUEST
  410. Status = STATUS_INVALID_DEVICE_REQUEST;
  411. } // end of switch
  412. } // end of FSCTL case
  413. break;
  414. case IRP_MJ_DEVICE_CONTROL:
  415. case IRP_MJ_INTERNAL_DEVICE_CONTROL:
  416. {
  417. switch (ControlCode) {
  418. #if DBG
  419. case IOCTL_LMMR_TEST:
  420. Status = MRxSmbTestDevIoctl(RxContext);
  421. break;
  422. #endif //if DBG
  423. case IOCTL_LMMR_USEKERNELSEC:
  424. if (MRxSmbBootedRemotely) {
  425. MRxSmbUseKernelModeSecurity = TRUE;
  426. Status = STATUS_SUCCESS;
  427. } else {
  428. Status = STATUS_UNSUCCESSFUL;
  429. }
  430. break;
  431. default :
  432. Status = MRxSmbCscIoCtl(RxContext);
  433. } // end of switch
  434. } //end of IOCTL cases
  435. break;
  436. default:
  437. ASSERT(!"unimplemented major function");
  438. Status = STATUS_INVALID_DEVICE_REQUEST;
  439. }
  440. FINALLY:
  441. RxDbgTrace(
  442. -1,
  443. Dbg,
  444. ("MRxSmbDevFcb st,info=%08lx,%08lx\n",
  445. Status,
  446. RxContext->InformationToReturn));
  447. return(Status);
  448. }
  449. NTSTATUS
  450. MRxSmbSetConfigurationInformation(
  451. IN PRX_CONTEXT RxContext
  452. )
  453. /*++
  454. Routine Description:
  455. This routine sets the configuration information associated with the
  456. redirector
  457. Arguments:
  458. RxContext - Describes the Fsctl and Context.
  459. Return Value:
  460. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  461. any other value indicates the appropriate error in the startup sequence.
  462. --*/
  463. {
  464. NTSTATUS Status;
  465. RxCaptureFobx;
  466. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  467. PWKSTA_INFO_502 pWorkStationConfiguration = LowIoContext->ParamsFor.FsCtl.pOutputBuffer;
  468. PLMR_REQUEST_PACKET pLmrRequestBuffer = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  469. ULONG BufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  470. PAGED_CODE();
  471. RxDbgTrace(0, Dbg, ("RxCommonDevFCBFsCtl -> FSCTL_LMR_GET_CONFIG_INFO\n"));
  472. if (BufferLength < sizeof(WKSTA_INFO_502)) {
  473. return STATUS_BUFFER_TOO_SMALL;
  474. }
  475. RxContext->InformationToReturn = sizeof(WKSTA_INFO_502);
  476. // Initialize the configuration information .....
  477. MRxSmbConfiguration.NamedPipeDataCollectionTimeInterval
  478. = pWorkStationConfiguration->wki502_collection_time;
  479. MRxSmbConfiguration.NamedPipeDataCollectionSize
  480. = pWorkStationConfiguration->wki502_maximum_collection_count;
  481. MRxSmbConfiguration.MaximumNumberOfCommands
  482. = pWorkStationConfiguration->wki502_max_cmds;
  483. MRxSmbConfiguration.SessionTimeoutInterval
  484. = pWorkStationConfiguration->wki502_sess_timeout;
  485. MRxSmbConfiguration.LockQuota
  486. = pWorkStationConfiguration->wki502_lock_quota;
  487. MRxSmbConfiguration.LockIncrement
  488. = pWorkStationConfiguration->wki502_lock_increment;
  489. MRxSmbConfiguration.MaximumLock
  490. = pWorkStationConfiguration->wki502_lock_maximum;
  491. MRxSmbConfiguration.PipeIncrement
  492. = pWorkStationConfiguration->wki502_pipe_increment;
  493. MRxSmbConfiguration.PipeMaximum
  494. = pWorkStationConfiguration->wki502_pipe_maximum;
  495. MRxSmbConfiguration.CachedFileTimeout
  496. = pWorkStationConfiguration->wki502_cache_file_timeout;
  497. MRxSmbConfiguration.DormantFileLimit
  498. = pWorkStationConfiguration->wki502_dormant_file_limit;
  499. MRxSmbConfiguration.NumberOfMailslotBuffers
  500. = pWorkStationConfiguration->wki502_num_mailslot_buffers;
  501. MRxSmbConfiguration.UseOplocks
  502. = pWorkStationConfiguration->wki502_use_opportunistic_locking != FALSE;
  503. MRxSmbConfiguration.UseUnlocksBehind
  504. = pWorkStationConfiguration->wki502_use_unlock_behind != FALSE;
  505. MRxSmbConfiguration.UseCloseBehind
  506. = pWorkStationConfiguration->wki502_use_close_behind != FALSE;
  507. MRxSmbConfiguration.BufferNamedPipes
  508. = pWorkStationConfiguration->wki502_buf_named_pipes != FALSE;
  509. MRxSmbConfiguration.UseLockReadUnlock
  510. = pWorkStationConfiguration->wki502_use_lock_read_unlock != FALSE;
  511. MRxSmbConfiguration.UtilizeNtCaching
  512. = pWorkStationConfiguration->wki502_utilize_nt_caching != FALSE;
  513. MRxSmbConfiguration.UseRawRead
  514. = pWorkStationConfiguration->wki502_use_raw_read != FALSE;
  515. MRxSmbConfiguration.UseRawWrite
  516. = pWorkStationConfiguration->wki502_use_raw_write != FALSE;
  517. MRxSmbConfiguration.UseEncryption
  518. = pWorkStationConfiguration->wki502_use_encryption != FALSE;
  519. MRxSmbConfiguration.MaximumNumberOfThreads
  520. = pWorkStationConfiguration->wki502_max_threads;
  521. MRxSmbConfiguration.ConnectionTimeoutInterval
  522. = pWorkStationConfiguration->wki502_keep_conn;
  523. MRxSmbConfiguration.CharBufferSize
  524. = pWorkStationConfiguration->wki502_siz_char_buf;
  525. #define printit(x) {DbgPrint("%s %x %x %d\n",#x,&x,x,x);}
  526. if (0) {
  527. printit(MRxSmbConfiguration.LockIncrement);
  528. printit(MRxSmbConfiguration.MaximumLock);
  529. printit(MRxSmbConfiguration.PipeIncrement);
  530. printit(MRxSmbConfiguration.PipeMaximum);
  531. }
  532. return(STATUS_SUCCESS);
  533. }
  534. NTSTATUS
  535. MRxSmbGetConfigurationInformation(
  536. IN PRX_CONTEXT RxContext
  537. )
  538. /*++
  539. Routine Description:
  540. This routine retrieves the configuration information associated with the
  541. redirector
  542. Arguments:
  543. RxContext - Describes the Fsctl and Context.
  544. Return Value:
  545. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  546. any other value indicates the appropriate error in the startup sequence.
  547. --*/
  548. {
  549. RxCaptureFobx;
  550. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  551. PWKSTA_INFO_502 pWorkStationConfiguration = LowIoContext->ParamsFor.FsCtl.pOutputBuffer;
  552. PLMR_REQUEST_PACKET pLmrRequestBuffer = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  553. ULONG BufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  554. PAGED_CODE();
  555. RxDbgTrace(0, Dbg, ("MRxSmbGetConfigurationInformation\n"));
  556. if (BufferLength < sizeof(WKSTA_INFO_502)) {
  557. return STATUS_INVALID_PARAMETER;
  558. }
  559. RxContext->InformationToReturn = sizeof(WKSTA_INFO_502);
  560. // Initialize the configuration information .....
  561. pWorkStationConfiguration->wki502_collection_time
  562. = MRxSmbConfiguration.NamedPipeDataCollectionTimeInterval;
  563. pWorkStationConfiguration->wki502_maximum_collection_count
  564. = MRxSmbConfiguration.NamedPipeDataCollectionSize;
  565. pWorkStationConfiguration->wki502_max_cmds
  566. = MRxSmbConfiguration.MaximumNumberOfCommands;
  567. pWorkStationConfiguration->wki502_sess_timeout
  568. = MRxSmbConfiguration.SessionTimeoutInterval;
  569. pWorkStationConfiguration->wki502_lock_quota
  570. = MRxSmbConfiguration.LockQuota;
  571. pWorkStationConfiguration->wki502_lock_increment
  572. = MRxSmbConfiguration.LockIncrement;
  573. pWorkStationConfiguration->wki502_lock_maximum
  574. = MRxSmbConfiguration.MaximumLock;
  575. pWorkStationConfiguration->wki502_pipe_increment
  576. = MRxSmbConfiguration.PipeIncrement;
  577. pWorkStationConfiguration->wki502_pipe_maximum
  578. = MRxSmbConfiguration.PipeMaximum;
  579. pWorkStationConfiguration->wki502_cache_file_timeout
  580. = MRxSmbConfiguration.CachedFileTimeout;
  581. pWorkStationConfiguration->wki502_dormant_file_limit
  582. = MRxSmbConfiguration.DormantFileTimeout;
  583. pWorkStationConfiguration->wki502_num_mailslot_buffers
  584. = MRxSmbConfiguration.NumberOfMailslotBuffers;
  585. pWorkStationConfiguration->wki502_use_opportunistic_locking
  586. = MRxSmbConfiguration.UseOplocks;
  587. pWorkStationConfiguration->wki502_use_unlock_behind
  588. = MRxSmbConfiguration.UseUnlocksBehind;
  589. pWorkStationConfiguration->wki502_use_close_behind
  590. = MRxSmbConfiguration.UseCloseBehind;
  591. pWorkStationConfiguration->wki502_buf_named_pipes
  592. = MRxSmbConfiguration.BufferNamedPipes;
  593. pWorkStationConfiguration->wki502_use_lock_read_unlock
  594. = MRxSmbConfiguration.UseLockReadUnlock;
  595. pWorkStationConfiguration->wki502_utilize_nt_caching
  596. = MRxSmbConfiguration.UtilizeNtCaching;
  597. pWorkStationConfiguration->wki502_use_raw_read
  598. = MRxSmbConfiguration.UseRawRead;
  599. pWorkStationConfiguration->wki502_use_raw_write
  600. = MRxSmbConfiguration.UseRawWrite;
  601. pWorkStationConfiguration->wki502_use_encryption
  602. = MRxSmbConfiguration.UseEncryption;
  603. pWorkStationConfiguration->wki502_max_threads
  604. = MRxSmbConfiguration.MaximumNumberOfThreads;
  605. pWorkStationConfiguration->wki502_keep_conn
  606. = MRxSmbConfiguration.ConnectionTimeoutInterval;
  607. pWorkStationConfiguration->wki502_siz_char_buf
  608. = MRxSmbConfiguration.CharBufferSize;
  609. return(STATUS_SUCCESS);
  610. }
  611. NTSTATUS
  612. MRxSmbExternalStart (
  613. IN PRX_CONTEXT RxContext
  614. )
  615. /*++
  616. Routine Description:
  617. This routine starts up the smb minirdr if it hasn't been started already. It also fills in
  618. the initial configuration.
  619. Arguments:
  620. RxContext - Describes the Fsctl and Context.
  621. Return Value:
  622. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  623. any other value indicates the appropriate error in the startup sequence.
  624. --*/
  625. {
  626. NTSTATUS Status = STATUS_SUCCESS;
  627. BOOLEAN InFSD = !BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_IN_FSP);
  628. MRXSMB_STATE State;
  629. PAGED_CODE();
  630. RxDbgTrace(0, Dbg, ("MRxSmbExternalStart [Start] -> %08lx\n", 0));
  631. //
  632. // If this is a normal start (from the workstation service), change state from
  633. // STARTABLE to START_IN_PROGRESS. If this is a remote boot start (from ioinit),
  634. // don't change state. This is necessary to allow the workstation service to
  635. // initialize correctly when it finally comes up.
  636. //
  637. if ( RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode == FSCTL_LMR_START ) {
  638. State = (MRXSMB_STATE)InterlockedCompareExchange(
  639. (PLONG)&MRxSmbState,
  640. MRXSMB_START_IN_PROGRESS,
  641. MRXSMB_STARTABLE);
  642. } else {
  643. State = MRxSmbState;
  644. }
  645. if (State == MRXSMB_STARTABLE) {
  646. IF_NOT_MRXSMB_CSC_ENABLED{
  647. NOTHING;
  648. } else {
  649. if (InFSD) {
  650. MRxSmbCscAgentSynchronizationOnStart(RxContext);
  651. }
  652. }
  653. // Owing to the peculiarities associated with starting the browser and the
  654. // redirector in the workstation service the following call has been
  655. // moved to the routine for handling FSCTL's for binding to transports.
  656. // Status = RxStartMinirdr( RxContext, &RxContext->PostRequest );
  657. if (InFSD) {
  658. RxCaptureFobx;
  659. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  660. PLMR_REQUEST_PACKET pLmrRequestBuffer = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  661. if ( RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode == FSCTL_LMR_START ) {
  662. //
  663. // Now is the time to read the registry to get the OS version
  664. // and build number. The workstation service issued this request,
  665. // so we know that the software hive has been loaded (a long time
  666. // ago, actually).
  667. //
  668. Status = SmbCeGetOperatingSystemInformation();
  669. if (Status != STATUS_SUCCESS) {
  670. return(Status);
  671. }
  672. }
  673. SmbCeContext.DomainName.Length = (USHORT)pLmrRequestBuffer->Parameters.Start.DomainNameLength;
  674. SmbCeContext.DomainName.MaximumLength = SmbCeContext.DomainName.Length;
  675. if (SmbCeContext.DomainName.Buffer != NULL) {
  676. RxFreePool(SmbCeContext.DomainName.Buffer);
  677. SmbCeContext.DomainName.Buffer = NULL;
  678. }
  679. if (SmbCeContext.DomainName.Length > 0) {
  680. SmbCeContext.DomainName.Buffer = RxAllocatePoolWithTag(
  681. PagedPool,
  682. SmbCeContext.DomainName.Length,
  683. MRXSMB_MISC_POOLTAG);
  684. if (SmbCeContext.DomainName.Buffer == NULL) {
  685. return STATUS_INSUFFICIENT_RESOURCES;
  686. } else {
  687. // The computer name and the domain name are concatenated together in the
  688. // request packet.
  689. RtlCopyMemory(
  690. SmbCeContext.DomainName.Buffer,
  691. &(pLmrRequestBuffer->Parameters.Start.RedirectorName[
  692. pLmrRequestBuffer->Parameters.Start.RedirectorNameLength / sizeof(WCHAR)]),
  693. SmbCeContext.DomainName.Length);
  694. }
  695. }
  696. Status = MRxSmbSetConfigurationInformation(RxContext);
  697. if (Status!=STATUS_SUCCESS) {
  698. return(Status);
  699. }
  700. if (SmbCeContext.DomainName.Length > 0) {
  701. Status = RxSetDomainForMailslotBroadcast(&SmbCeContext.DomainName);
  702. if (Status != STATUS_SUCCESS) {
  703. return(Status);
  704. }
  705. }
  706. }
  707. } else {
  708. Status = STATUS_REDIRECTOR_STARTED;
  709. }
  710. return Status;
  711. }
  712. #if DBG
  713. NTSTATUS
  714. MRxSmbTestDevIoctl(
  715. IN PRX_CONTEXT RxContext
  716. )
  717. {
  718. NTSTATUS Status = STATUS_SUCCESS;
  719. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  720. PSZ InputString = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  721. PSZ OutputString = LowIoContext->ParamsFor.FsCtl.pOutputBuffer;
  722. ULONG OutputBufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  723. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  724. ULONG i;
  725. PAGED_CODE();
  726. RxDbgTrace(0, Dbg,("MRxSmbTestDevIoctl %s, obl = %08lx\n",InputString, OutputBufferLength));
  727. RxContext->InformationToReturn = (InputBufferLength-1)*(InputBufferLength-1);
  728. try {
  729. if (InputString != NULL && OutputString != NULL) {
  730. ProbeForRead(InputString,InputBufferLength,1);
  731. ProbeForWrite(OutputString,OutputBufferLength,1);
  732. for (i=0;i<InputBufferLength;i++) {
  733. UCHAR c = InputString[i];
  734. if (c==0) { break; }
  735. OutputString[i] = c;
  736. if ((i&3)==2) {
  737. OutputString[i] = '@';
  738. }
  739. }
  740. if (OutputBufferLength > 0)
  741. OutputString[i] = 0;
  742. } else {
  743. Status = STATUS_INVALID_USER_BUFFER;
  744. }
  745. } except(EXCEPTION_EXECUTE_HANDLER) {
  746. Status=STATUS_INVALID_PARAMETER;
  747. }
  748. return(Status);
  749. }
  750. #endif //if DBG
  751. #define SMBMRX_CONFIG_CONTROL \
  752. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control"
  753. #define SMBMRX_CONFIG_REMOTEBOOTROOT \
  754. L"RemoteBootRoot"
  755. #define SMBMRX_CONFIG_REMOTEBOOTMACHINEDIRECTORY \
  756. L"RemoteBootMachineDirectory"
  757. PWCHAR
  758. SafeWcschr(
  759. PWCHAR String,
  760. WCHAR Char,
  761. PWCHAR End
  762. )
  763. {
  764. while ( (String < End) && (*String != Char) && (*String != 0) ) {
  765. String++;
  766. }
  767. if ( (String < End) && (*String == Char) ) {
  768. return String;
  769. }
  770. return NULL;
  771. }
  772. NTSTATUS
  773. MRxSmbInitializeRemoteBootParameters(
  774. PRX_CONTEXT RxContext
  775. )
  776. {
  777. NTSTATUS status;
  778. OBJECT_ATTRIBUTES objectAttributes;
  779. UNICODE_STRING unicodeString;
  780. HANDLE hRegistryKey;
  781. ULONG bytesRead;
  782. KEY_VALUE_PARTIAL_INFORMATION initialPartialInformationValue;
  783. ULONG allocationLength;
  784. PWCHAR pServer;
  785. PWCHAR pServerEnd;
  786. PWCHAR pPath;
  787. PWCHAR pPathEnd;
  788. PWCHAR pSetup;
  789. PWCHAR pSetupEnd;
  790. PWCHAR pEnd;
  791. RI_SECRET Secret;
  792. UCHAR Domain[RI_SECRET_DOMAIN_SIZE + 1];
  793. UCHAR User[RI_SECRET_USER_SIZE + 1];
  794. UCHAR LmOwfPassword1[LM_OWF_PASSWORD_SIZE];
  795. UCHAR NtOwfPassword1[NT_OWF_PASSWORD_SIZE];
  796. #if defined(REMOTE_BOOT)
  797. UCHAR LmOwfPassword2[LM_OWF_PASSWORD_SIZE];
  798. UCHAR NtOwfPassword2[NT_OWF_PASSWORD_SIZE];
  799. #endif // defined(REMOTE_BOOT)
  800. STRING DomainString, UserString, PasswordString;
  801. //
  802. // Read the RemoteBootRoot parameter from the registry. This tells us
  803. // the path to the boot server.
  804. //
  805. RtlInitUnicodeString( &unicodeString, SMBMRX_CONFIG_CONTROL );
  806. InitializeObjectAttributes(
  807. &objectAttributes,
  808. &unicodeString, // name
  809. OBJ_CASE_INSENSITIVE, // attributes
  810. NULL, // root
  811. NULL); // security descriptor
  812. status = ZwOpenKey( &hRegistryKey, KEY_READ, &objectAttributes );
  813. if ( !NT_SUCCESS(status) ) {
  814. return status;
  815. }
  816. RtlInitUnicodeString( &unicodeString, SMBMRX_CONFIG_REMOTEBOOTROOT );
  817. status = ZwQueryValueKey(
  818. hRegistryKey,
  819. &unicodeString,
  820. KeyValuePartialInformation,
  821. &initialPartialInformationValue,
  822. sizeof(initialPartialInformationValue),
  823. &bytesRead);
  824. if (status != STATUS_BUFFER_OVERFLOW) {
  825. if (NT_SUCCESS(status)) {
  826. status = STATUS_INVALID_PARAMETER;
  827. }
  828. ZwClose( hRegistryKey );
  829. return status;
  830. }
  831. allocationLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
  832. initialPartialInformationValue.DataLength;
  833. MRxSmbRemoteBootRootValue = RxAllocatePoolWithTag(
  834. NonPagedPool,
  835. allocationLength,
  836. MRXSMB_MISC_POOLTAG);
  837. if ( MRxSmbRemoteBootRootValue == NULL ) {
  838. ZwClose( hRegistryKey );
  839. return STATUS_INSUFFICIENT_RESOURCES;
  840. }
  841. status = ZwQueryValueKey(
  842. hRegistryKey,
  843. &unicodeString,
  844. KeyValuePartialInformation,
  845. MRxSmbRemoteBootRootValue,
  846. allocationLength,
  847. &bytesRead);
  848. if ( !NT_SUCCESS(status) ) {
  849. RxFreePool( MRxSmbRemoteBootRootValue );
  850. MRxSmbRemoteBootRootValue = NULL;
  851. ZwClose( hRegistryKey );
  852. return status;
  853. }
  854. if ( (MRxSmbRemoteBootRootValue->DataLength == 0) ||
  855. (MRxSmbRemoteBootRootValue->Type != REG_SZ)) {
  856. RxFreePool( MRxSmbRemoteBootRootValue );
  857. MRxSmbRemoteBootRootValue = NULL;
  858. ZwClose( hRegistryKey );
  859. return STATUS_INVALID_PARAMETER;
  860. }
  861. //
  862. // Read the RemoteBootMachineDirectory parameter from the registry. If
  863. // this value exists, then we are in textmode setup, and RemoteBootRoot
  864. // point to the setup source, while RemoteBootMachineDirectory points
  865. // to the client's machine directory. If RemoteBootMachineDirectory
  866. // doesn't exist, then RemoteBootRoot points to the machine directory.
  867. //
  868. RtlInitUnicodeString( &unicodeString, SMBMRX_CONFIG_REMOTEBOOTMACHINEDIRECTORY );
  869. status = ZwQueryValueKey(
  870. hRegistryKey,
  871. &unicodeString,
  872. KeyValuePartialInformation,
  873. &initialPartialInformationValue,
  874. sizeof(initialPartialInformationValue),
  875. &bytesRead);
  876. if (status == STATUS_BUFFER_OVERFLOW) {
  877. allocationLength = sizeof(KEY_VALUE_PARTIAL_INFORMATION) +
  878. initialPartialInformationValue.DataLength;
  879. MRxSmbRemoteBootMachineDirectoryValue = RxAllocatePoolWithTag(
  880. NonPagedPool,
  881. allocationLength,
  882. MRXSMB_MISC_POOLTAG);
  883. if ( MRxSmbRemoteBootMachineDirectoryValue == NULL ) {
  884. RxFreePool( MRxSmbRemoteBootRootValue );
  885. MRxSmbRemoteBootRootValue = NULL;
  886. ZwClose( hRegistryKey );
  887. return STATUS_INSUFFICIENT_RESOURCES;
  888. }
  889. status = ZwQueryValueKey(
  890. hRegistryKey,
  891. &unicodeString,
  892. KeyValuePartialInformation,
  893. MRxSmbRemoteBootMachineDirectoryValue,
  894. allocationLength,
  895. &bytesRead);
  896. if ( !NT_SUCCESS(status) ) {
  897. RxFreePool( MRxSmbRemoteBootMachineDirectoryValue );
  898. MRxSmbRemoteBootMachineDirectoryValue = NULL;
  899. RxFreePool( MRxSmbRemoteBootRootValue );
  900. MRxSmbRemoteBootRootValue = NULL;
  901. ZwClose( hRegistryKey );
  902. return status;
  903. }
  904. if ( (MRxSmbRemoteBootMachineDirectoryValue->DataLength == 0) ||
  905. (MRxSmbRemoteBootMachineDirectoryValue->Type != REG_SZ)) {
  906. RxFreePool( MRxSmbRemoteBootMachineDirectoryValue );
  907. MRxSmbRemoteBootMachineDirectoryValue = NULL;
  908. RxFreePool( MRxSmbRemoteBootRootValue );
  909. MRxSmbRemoteBootRootValue = NULL;
  910. ZwClose( hRegistryKey );
  911. return STATUS_INVALID_PARAMETER;
  912. }
  913. }
  914. ZwClose( hRegistryKey );
  915. if ( MRxSmbRemoteBootMachineDirectoryValue != NULL) {
  916. //
  917. // Textmode setup. MachineDirectory gives the machine directory and
  918. // Root gives the setup source.
  919. //
  920. // The setup source path in the registry is of the form:
  921. // \Device\LanmanRedirector\server\IMirror\Setup\English\MirroredOSes\build\i386
  922. //
  923. // We need to extract the \Setup\... part.
  924. //
  925. pSetup = (PWCHAR)MRxSmbRemoteBootRootValue->Data;
  926. pEnd = (PWCHAR)((PUCHAR)pSetup + MRxSmbRemoteBootRootValue->DataLength);
  927. pSetup = SafeWcschr( pSetup + 1, L'\\', pEnd ); // find \ before LanmanRedirector
  928. if ( pSetup != NULL ) {
  929. pSetup = SafeWcschr( pSetup + 1, L'\\', pEnd ); // find \ before server
  930. if ( pSetup != NULL ) {
  931. pSetup = SafeWcschr( pSetup + 1, L'\\', pEnd ); // find \ before IMirror
  932. if ( pSetup != NULL ) {
  933. pSetup = SafeWcschr( pSetup + 1, L'\\', pEnd ); // find \ before Setup
  934. }
  935. }
  936. }
  937. if ( *(pEnd-1) == 0 ) {
  938. pEnd--;
  939. }
  940. if ( *(pEnd-1) == '\\' ) {
  941. pEnd--;
  942. }
  943. pSetupEnd = pEnd;
  944. //
  945. // The machine directory path in the registry is of the form:
  946. // \Device\LanmanRedirector\server\IMirror\Clients\machine
  947. //
  948. pServer = (PWCHAR)MRxSmbRemoteBootMachineDirectoryValue->Data;
  949. pEnd = (PWCHAR)((PUCHAR)pServer + MRxSmbRemoteBootMachineDirectoryValue->DataLength);
  950. } else {
  951. //
  952. // Not textmode setup. Root gives the machine directory.
  953. //
  954. // The path in the registry is of the form:
  955. // \Device\LanmanRedirector\server\IMirror\Clients\machine
  956. //
  957. pSetup = NULL;
  958. pServer = (PWCHAR)MRxSmbRemoteBootRootValue->Data;
  959. pEnd = (PWCHAR)((PUCHAR)pServer + MRxSmbRemoteBootRootValue->DataLength);
  960. }
  961. //
  962. // We need to extract the \server\Imirror part and the \Clients\machine part.
  963. //
  964. pServer = SafeWcschr( pServer + 1, L'\\', pEnd ); // skip leading \, find next
  965. if ( pServer != NULL) {
  966. pServer = SafeWcschr( pServer + 1, L'\\', pEnd ); // find \ before server name
  967. if ( pServer != NULL ) {
  968. pPath = SafeWcschr( pServer + 1, L'\\', pEnd ); // find \ before IMirror
  969. if ( pPath != NULL ) {
  970. pPath = SafeWcschr( pPath + 1, L'\\', pEnd ); // find \ before Clients
  971. }
  972. }
  973. }
  974. if ( (pServer == NULL) || (pPath == NULL) ||
  975. ((MRxSmbRemoteBootMachineDirectoryValue != NULL) && (pSetup == NULL)) ) {
  976. if ( MRxSmbRemoteBootMachineDirectoryValue != NULL ) {
  977. RxFreePool( MRxSmbRemoteBootMachineDirectoryValue );
  978. MRxSmbRemoteBootMachineDirectoryValue = NULL;
  979. }
  980. RxFreePool( MRxSmbRemoteBootRootValue );
  981. MRxSmbRemoteBootRootValue = NULL;
  982. return STATUS_INVALID_PARAMETER;
  983. }
  984. if ( *(pEnd-1) == 0 ) {
  985. pEnd--;
  986. }
  987. pServerEnd = pPath;
  988. pPathEnd = pEnd;
  989. //
  990. // Make strings for the various parts that we need to remember.
  991. //
  992. MRxSmbRemoteBootShare.Buffer = pServer;
  993. MRxSmbRemoteBootShare.Length = (USHORT)(pServerEnd - pServer) * sizeof(WCHAR);
  994. MRxSmbRemoteBootShare.MaximumLength = MRxSmbRemoteBootShare.Length;
  995. MRxSmbRemoteBootPath.Buffer = pPath;
  996. MRxSmbRemoteBootPath.Length = (USHORT)(pPathEnd - pPath) * sizeof(WCHAR);
  997. MRxSmbRemoteBootPath.MaximumLength = MRxSmbRemoteBootPath.Length;
  998. //
  999. // Use the secret that IO init passed in with the LMMR_RI_INITIALIZE_SECRET
  1000. // FSCTL to set the user, domain, and password. If successful, we set
  1001. // MRxSmbRemoteBootDoMachineLogon to TRUE.
  1002. //
  1003. RtlFreeUnicodeString(&MRxSmbRemoteBootMachineName);
  1004. RtlFreeUnicodeString(&MRxSmbRemoteBootMachineDomain);
  1005. RtlFreeUnicodeString(&MRxSmbRemoteBootMachinePassword);
  1006. #if defined(REMOTE_BOOT)
  1007. MRxSmbRemoteBootDoMachineLogon = FALSE;
  1008. if (MRxSmbRemoteBootSecretValid) {
  1009. #endif // defined(REMOTE_BOOT)
  1010. RdrParseSecret(
  1011. Domain,
  1012. User,
  1013. LmOwfPassword1,
  1014. NtOwfPassword1,
  1015. #if defined(REMOTE_BOOT)
  1016. LmOwfPassword2,
  1017. NtOwfPassword2,
  1018. #endif // defined(REMOTE_BOOT)
  1019. MRxSmbRemoteBootMachineSid,
  1020. &MRxSmbRemoteBootSecret);
  1021. //
  1022. // Convert the ANSI user and domain name
  1023. // to Unicode strings.
  1024. //
  1025. RtlInitAnsiString(&UserString, User);
  1026. status = RtlAnsiStringToUnicodeString(&MRxSmbRemoteBootMachineName, &UserString, TRUE);
  1027. if ( !NT_SUCCESS(status) ) {
  1028. return status;
  1029. }
  1030. RtlInitAnsiString(&DomainString, Domain);
  1031. status = RtlAnsiStringToUnicodeString(&MRxSmbRemoteBootMachineDomain, &DomainString, TRUE);
  1032. if ( !NT_SUCCESS(status) ) {
  1033. RtlFreeUnicodeString(&MRxSmbRemoteBootMachineName);
  1034. return status;
  1035. }
  1036. //
  1037. // Use the correct password based on the hint we were given.
  1038. //
  1039. // The "Unicode string" for the password is actually the
  1040. // LM and NT OWF passwords concatenated together.
  1041. //
  1042. PasswordString.Buffer = ExAllocatePool(NonPagedPool, LM_OWF_PASSWORD_SIZE+NT_OWF_PASSWORD_SIZE);
  1043. if (PasswordString.Buffer == NULL) {
  1044. RtlFreeUnicodeString(&MRxSmbRemoteBootMachineDomain);
  1045. RtlFreeUnicodeString(&MRxSmbRemoteBootMachineName);
  1046. return STATUS_INSUFFICIENT_RESOURCES;
  1047. } else {
  1048. #if defined(REMOTE_BOOT)
  1049. if (MRxSmbRemoteBootUsePassword2) {
  1050. RtlCopyMemory(PasswordString.Buffer, LmOwfPassword2, LM_OWF_PASSWORD_SIZE);
  1051. RtlCopyMemory(PasswordString.Buffer + LM_OWF_PASSWORD_SIZE, NtOwfPassword2, NT_OWF_PASSWORD_SIZE);
  1052. } else
  1053. #endif // defined(REMOTE_BOOT)
  1054. {
  1055. RtlCopyMemory(PasswordString.Buffer, LmOwfPassword1, LM_OWF_PASSWORD_SIZE);
  1056. RtlCopyMemory(PasswordString.Buffer + LM_OWF_PASSWORD_SIZE, NtOwfPassword1, NT_OWF_PASSWORD_SIZE);
  1057. }
  1058. PasswordString.Length = LM_OWF_PASSWORD_SIZE+NT_OWF_PASSWORD_SIZE;
  1059. PasswordString.MaximumLength = LM_OWF_PASSWORD_SIZE+NT_OWF_PASSWORD_SIZE;
  1060. //
  1061. // Copy the string as-is, it's really just
  1062. // a buffer, not an ANSI string.
  1063. //
  1064. MRxSmbRemoteBootMachinePassword = *((PUNICODE_STRING)&PasswordString);
  1065. #if defined(REMOTE_BOOT)
  1066. MRxSmbRemoteBootDoMachineLogon = TRUE;
  1067. #endif // defined(REMOTE_BOOT)
  1068. KdPrint(("Redirector will log on to <%s><%s>\n", Domain, User));
  1069. }
  1070. #if defined(REMOTE_BOOT)
  1071. } else {
  1072. KdPrint(("MRxSmbRemoteBootSecretValid is FALSE, will use NULL session\n", status));
  1073. }
  1074. #endif // defined(REMOTE_BOOT)
  1075. if ( pSetup != NULL) {
  1076. MRxSmbRemoteSetupPath.Buffer = pSetup;
  1077. MRxSmbRemoteSetupPath.Length = (USHORT)(pSetupEnd - pSetup) * sizeof(WCHAR);
  1078. MRxSmbRemoteSetupPath.MaximumLength = MRxSmbRemoteSetupPath.Length;
  1079. } else {
  1080. RtlInitUnicodeString( &MRxSmbRemoteSetupPath, L"unused" );
  1081. }
  1082. #if defined(REMOTE_BOOT)
  1083. //
  1084. // This calls prepares us for modifying ACLs on server files.
  1085. //
  1086. MRxSmbInitializeExtraAceArray();
  1087. #endif // defined(REMOTE_BOOT)
  1088. return STATUS_SUCCESS;
  1089. }
  1090. #if defined(REMOTE_BOOT)
  1091. NTSTATUS
  1092. MRxSmbStartRbr(
  1093. PRX_CONTEXT RxContext
  1094. )
  1095. {
  1096. NTSTATUS status;
  1097. HANDLE handle;
  1098. OBJECT_ATTRIBUTES objectAttributes;
  1099. IO_STATUS_BLOCK ioStatusBlock;
  1100. ULONG localBufferLength;
  1101. PWCH localBuffer;
  1102. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1103. PSZ InputString = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  1104. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  1105. //
  1106. // Set up for remote boot redirection (to the local disk).
  1107. //
  1108. // The NT name of the local disk partition is passed in to the FSCTL.
  1109. // Allocate a buffer to allow us to append "\IntelliMirror Cache\RBR"
  1110. // to that string.
  1111. //
  1112. localBufferLength = InputBufferLength +
  1113. (wcslen(REMOTE_BOOT_IMIRROR_PATH_W REMOTE_BOOT_RBR_SUBDIR_W) * sizeof(WCHAR));
  1114. localBuffer = RxAllocatePoolWithTag(
  1115. NonPagedPool,
  1116. localBufferLength,
  1117. MRXSMB_MISC_POOLTAG);
  1118. if ( localBuffer == NULL ) {
  1119. return STATUS_INSUFFICIENT_RESOURCES;
  1120. }
  1121. //
  1122. // Create a string descriptor for the NT partition name.
  1123. //
  1124. RtlCopyMemory( localBuffer, InputString, InputBufferLength );
  1125. MRxSmbRemoteBootRedirectionPrefix.Buffer = localBuffer;
  1126. MRxSmbRemoteBootRedirectionPrefix.Length = (USHORT)InputBufferLength;
  1127. MRxSmbRemoteBootRedirectionPrefix.MaximumLength = (USHORT)localBufferLength;
  1128. InitializeObjectAttributes(
  1129. &objectAttributes,
  1130. &MRxSmbRemoteBootRedirectionPrefix,
  1131. OBJ_CASE_INSENSITIVE,
  1132. NULL,
  1133. NULL
  1134. );
  1135. //
  1136. // Append "\Intellimirror Cache" and create/open that directory.
  1137. //
  1138. RtlAppendUnicodeToString( &MRxSmbRemoteBootRedirectionPrefix, REMOTE_BOOT_IMIRROR_PATH_W );
  1139. status = ZwCreateFile(
  1140. &handle,
  1141. FILE_GENERIC_READ | FILE_GENERIC_WRITE,
  1142. &objectAttributes,
  1143. &ioStatusBlock,
  1144. NULL,
  1145. FILE_ATTRIBUTE_DIRECTORY,
  1146. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  1147. FILE_OPEN_IF,
  1148. FILE_DIRECTORY_FILE,
  1149. NULL,
  1150. 0
  1151. );
  1152. if (!NT_SUCCESS(status)) {
  1153. RxFreePool( localBuffer );
  1154. MRxSmbRemoteBootRedirectionPrefix.Buffer = NULL;
  1155. MRxSmbRemoteBootRedirectionPrefix.Length = 0;
  1156. return status;
  1157. }
  1158. ZwClose(handle);
  1159. //
  1160. // Append \RBR and create/open that directory.
  1161. //
  1162. RtlAppendUnicodeToString( &MRxSmbRemoteBootRedirectionPrefix, REMOTE_BOOT_RBR_SUBDIR_W );
  1163. status = ZwCreateFile(
  1164. &handle,
  1165. FILE_GENERIC_READ | FILE_GENERIC_WRITE,
  1166. &objectAttributes,
  1167. &ioStatusBlock,
  1168. NULL,
  1169. FILE_ATTRIBUTE_DIRECTORY,
  1170. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  1171. FILE_OPEN_IF,
  1172. FILE_DIRECTORY_FILE,
  1173. NULL,
  1174. 0
  1175. );
  1176. if (!NT_SUCCESS(status)) {
  1177. RxFreePool( localBuffer );
  1178. MRxSmbRemoteBootRedirectionPrefix.Buffer = NULL;
  1179. MRxSmbRemoteBootRedirectionPrefix.Length = 0;
  1180. return status;
  1181. }
  1182. ZwClose(handle);
  1183. return STATUS_SUCCESS;
  1184. }
  1185. #endif // defined(REMOTE_BOOT)
  1186. NTSTATUS
  1187. MRxSmbRemoteBootInitializeSecret(
  1188. PRX_CONTEXT RxContext
  1189. )
  1190. {
  1191. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1192. PLMMR_RI_INITIALIZE_SECRET InputBuffer = (PLMMR_RI_INITIALIZE_SECRET)(LowIoContext->ParamsFor.FsCtl.pInputBuffer);
  1193. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  1194. //
  1195. // Store the secret passed in from above.
  1196. //
  1197. if (InputBufferLength != sizeof(LMMR_RI_INITIALIZE_SECRET)) {
  1198. return STATUS_INVALID_PARAMETER;
  1199. }
  1200. RtlCopyMemory(&MRxSmbRemoteBootSecret, &(InputBuffer->Secret), sizeof(RI_SECRET));
  1201. #if defined(REMOTE_BOOT)
  1202. MRxSmbRemoteBootSecretValid = TRUE;
  1203. MRxSmbRemoteBootUsePassword2 = InputBuffer->UsePassword2;
  1204. #endif // defined(REMOTE_BOOT)
  1205. return STATUS_SUCCESS;
  1206. }
  1207. #if defined(REMOTE_BOOT)
  1208. NTSTATUS
  1209. MRxSmbRemoteBootCheckForNewPassword(
  1210. PRX_CONTEXT RxContext
  1211. )
  1212. {
  1213. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1214. PLMMR_RI_CHECK_FOR_NEW_PASSWORD OutputBuffer = (PLMMR_RI_CHECK_FOR_NEW_PASSWORD)(LowIoContext->ParamsFor.FsCtl.pOutputBuffer);
  1215. ULONG OutputBufferLength = LowIoContext->ParamsFor.FsCtl.OutputBufferLength;
  1216. ULONG SecretPasswordLength;
  1217. //
  1218. // If we are not a remote boot machine or were not given a secret
  1219. // (which implies we are diskless), then we don't support this.
  1220. //
  1221. if (!MRxSmbBootedRemotely ||
  1222. !MRxSmbRemoteBootSecretValid) {
  1223. return STATUS_NOT_SUPPORTED;
  1224. }
  1225. //
  1226. // See if we have a cleartext password in the secret.
  1227. //
  1228. SecretPasswordLength = *(UNALIGNED ULONG *)(MRxSmbRemoteBootSecret.Reserved);
  1229. if (SecretPasswordLength == 0) {
  1230. return STATUS_NOT_SUPPORTED;
  1231. }
  1232. //
  1233. // Make sure the output buffer is big enough.
  1234. //
  1235. if (OutputBufferLength < (sizeof(ULONG) + SecretPasswordLength)) {
  1236. return STATUS_BUFFER_OVERFLOW;
  1237. }
  1238. //
  1239. // Copy the cleartext password.
  1240. //
  1241. OutputBuffer->Length = SecretPasswordLength;
  1242. RtlCopyMemory(OutputBuffer->Data, MRxSmbRemoteBootSecret.Reserved + sizeof(ULONG), SecretPasswordLength);
  1243. RxContext->InformationToReturn =
  1244. SecretPasswordLength + FIELD_OFFSET(LMMR_RI_CHECK_FOR_NEW_PASSWORD, Data[0]);
  1245. #if DBG
  1246. {
  1247. ULONG i;
  1248. KdPrint(("MRxSmbRemoteBootCheckForNewPassword: found one, length %d\n", SecretPasswordLength));
  1249. for (i = 0; i < SecretPasswordLength; i++) {
  1250. KdPrint(("%2.2x ", OutputBuffer->Data[i]));
  1251. }
  1252. KdPrint(("\n"));
  1253. }
  1254. #endif
  1255. return STATUS_SUCCESS;
  1256. }
  1257. NTSTATUS
  1258. MRxSmbRemoteBootIsPasswordSettable(
  1259. PRX_CONTEXT RxContext
  1260. )
  1261. {
  1262. NTSTATUS status;
  1263. HANDLE RawDiskHandle;
  1264. //
  1265. // If we are not a remote boot machine, then we don't support this.
  1266. //
  1267. if (!MRxSmbBootedRemotely) {
  1268. return STATUS_NOT_SUPPORTED;
  1269. }
  1270. //
  1271. // If we were not given a secret, then we are diskless, and we
  1272. // can't write this either.
  1273. //
  1274. if (!MRxSmbRemoteBootSecretValid) {
  1275. return STATUS_NOT_SUPPORTED;
  1276. }
  1277. //
  1278. // If we are not diskless, make sure that the redir can open
  1279. // the raw disk -- it may be that the loader can but
  1280. // we can't. In this case we need to fail with a different
  1281. // error, since this is the case the caller probably cares
  1282. // about most.
  1283. //
  1284. status = RdrOpenRawDisk(&RawDiskHandle);
  1285. if (!NT_SUCCESS(status)) {
  1286. KdPrint(("MRxSmbRemoteBootIsPasswordSettable: can't open disk, returning STATUS_UNSUCCESSFUL\n"));
  1287. return STATUS_UNSUCCESSFUL; // we can't support password set on this boot
  1288. }
  1289. RdrCloseRawDisk(RawDiskHandle);
  1290. return STATUS_SUCCESS;
  1291. }
  1292. NTSTATUS
  1293. MRxSmbRemoteBootSetNewPassword(
  1294. PRX_CONTEXT RxContext
  1295. )
  1296. {
  1297. NTSTATUS status;
  1298. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1299. PLMMR_RI_SET_NEW_PASSWORD InputBuffer = (PLMMR_RI_SET_NEW_PASSWORD)(LowIoContext->ParamsFor.FsCtl.pInputBuffer);
  1300. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  1301. RI_SECRET Secret;
  1302. HANDLE RawDiskHandle;
  1303. UCHAR LmOwf1[LM_OWF_PASSWORD_SIZE];
  1304. UCHAR LmOwf2[LM_OWF_PASSWORD_SIZE];
  1305. UCHAR NtOwf1[NT_OWF_PASSWORD_SIZE];
  1306. UCHAR NtOwf2[NT_OWF_PASSWORD_SIZE];
  1307. UNICODE_STRING PasswordString;
  1308. //
  1309. // If we are not a remote boot machine, then we don't support this.
  1310. //
  1311. if (!MRxSmbBootedRemotely) {
  1312. return STATUS_NOT_SUPPORTED;
  1313. }
  1314. //
  1315. // If we were not given a secret, then we are diskless, and we
  1316. // can't write this either.
  1317. //
  1318. if (!MRxSmbRemoteBootSecretValid) {
  1319. return STATUS_NOT_SUPPORTED;
  1320. }
  1321. //
  1322. // Open the raw disk.
  1323. //
  1324. status = RdrOpenRawDisk(&RawDiskHandle);
  1325. if (!NT_SUCCESS(status)) {
  1326. return status;
  1327. }
  1328. //
  1329. // OWF the passwords.
  1330. //
  1331. #if 0
  1332. {
  1333. ULONG i;
  1334. KdPrint(("MRxSmbRemoteBootSetNewPassword: password 1 is length %d\n", InputBuffer->Length1));
  1335. for (i = 0; i < InputBuffer->Length1; i++) {
  1336. KdPrint(("%2.2x ", InputBuffer->Data[i]));
  1337. }
  1338. KdPrint(("\n"));
  1339. }
  1340. #endif
  1341. PasswordString.Buffer = (PWCHAR)InputBuffer->Data;
  1342. PasswordString.Length = (USHORT)(InputBuffer->Length1);
  1343. PasswordString.MaximumLength = (USHORT)(InputBuffer->Length1);
  1344. RdrOwfPassword(
  1345. &PasswordString,
  1346. LmOwf1,
  1347. NtOwf1);
  1348. if (InputBuffer->Length2 != 0) {
  1349. #if 0
  1350. {
  1351. ULONG i;
  1352. KdPrint(("MRxSmbRemoteBootSetNewPassword: password 2 is length %d\n", InputBuffer->Length2));
  1353. for (i = 0; i < InputBuffer->Length2; i++) {
  1354. KdPrint(("%2.2x ", InputBuffer->Data[i + InputBuffer->Length1]));
  1355. }
  1356. KdPrint(("\n"));
  1357. }
  1358. #endif
  1359. //
  1360. // If password 2 is the same as password 1, then grab the
  1361. // current password to store in password 2 (the current password
  1362. // is the one we used to log on for this boot -- generally this
  1363. // will be password 1 unless UsePassword2 is TRUE). This is
  1364. // what happens during GUI-mode setup.
  1365. //
  1366. if ((InputBuffer->Length1 == InputBuffer->Length2) &&
  1367. RtlEqualMemory(
  1368. InputBuffer->Data,
  1369. InputBuffer->Data + InputBuffer->Length1,
  1370. InputBuffer->Length1)) {
  1371. RtlCopyMemory(LmOwf2, MRxSmbRemoteBootMachinePassword.Buffer, LM_OWF_PASSWORD_SIZE);
  1372. RtlCopyMemory(NtOwf2, MRxSmbRemoteBootMachinePassword.Buffer + LM_OWF_PASSWORD_SIZE, NT_OWF_PASSWORD_SIZE);
  1373. } else {
  1374. PasswordString.Buffer = (PWCHAR)(InputBuffer->Data + InputBuffer->Length1);
  1375. PasswordString.Length = (USHORT)(InputBuffer->Length2);
  1376. PasswordString.MaximumLength = (USHORT)(InputBuffer->Length2);
  1377. RdrOwfPassword(
  1378. &PasswordString,
  1379. LmOwf2,
  1380. NtOwf2);
  1381. }
  1382. } else {
  1383. RtlZeroMemory(LmOwf2, LM_OWF_PASSWORD_SIZE);
  1384. RtlZeroMemory(NtOwf2, NT_OWF_PASSWORD_SIZE);
  1385. }
  1386. //
  1387. // Initialize the secret. The data except for the new passwords
  1388. // comes from the current secret.
  1389. //
  1390. RdrInitializeSecret(
  1391. MRxSmbRemoteBootSecret.Domain,
  1392. MRxSmbRemoteBootSecret.User,
  1393. LmOwf1,
  1394. NtOwf1,
  1395. LmOwf2,
  1396. NtOwf2,
  1397. MRxSmbRemoteBootSecret.Sid,
  1398. &Secret);
  1399. //
  1400. // Write the secret.
  1401. //
  1402. status = RdrWriteSecret(RawDiskHandle, &Secret);
  1403. if (!NT_SUCCESS(status)) {
  1404. KdPrint(("MRxSmbRemoteBootSetNewPassword: RdrWriteSecret failed %lx\n", status));
  1405. (PVOID)RdrCloseRawDisk(RawDiskHandle);
  1406. return status;
  1407. }
  1408. //
  1409. // Since we wrote it successfully, it is now the current one. Note
  1410. // that this means any new cleartext password in the current secret
  1411. // will be erased.
  1412. //
  1413. RtlCopyMemory(&MRxSmbRemoteBootSecret, &Secret, sizeof(RI_SECRET));
  1414. //
  1415. // Any future connections we do need to use the new password.
  1416. //
  1417. RtlCopyMemory(MRxSmbRemoteBootMachinePassword.Buffer, LmOwf1, LM_OWF_PASSWORD_SIZE);
  1418. RtlCopyMemory(MRxSmbRemoteBootMachinePassword.Buffer + LM_OWF_PASSWORD_SIZE, NtOwf1, NT_OWF_PASSWORD_SIZE);
  1419. MRxSmbRemoteBootUsePassword2 = FALSE;
  1420. (PVOID)RdrCloseRawDisk(RawDiskHandle);
  1421. return STATUS_SUCCESS;
  1422. }
  1423. #endif // defined(REMOTE_BOOT)
  1424. NTSTATUS
  1425. MRxSmbSetDomainName(
  1426. IN PRX_CONTEXT RxContext
  1427. )
  1428. /*++
  1429. Routine Description:
  1430. This routine sets the configuration information associated with the
  1431. redirector
  1432. Arguments:
  1433. RxContext - Describes the Fsctl and Context.
  1434. Return Value:
  1435. STATUS_SUCCESS -- the Startup sequence was successfully completed.
  1436. any other value indicates the appropriate error in the startup sequence.
  1437. --*/
  1438. {
  1439. NTSTATUS Status = STATUS_SUCCESS;
  1440. RxCaptureFobx;
  1441. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1442. PLMR_REQUEST_PACKET pLmrRequestBuffer = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  1443. try {
  1444. if (pLmrRequestBuffer == NULL ||
  1445. (USHORT)pLmrRequestBuffer->Parameters.Start.DomainNameLength > DNS_MAX_NAME_LENGTH) {
  1446. return STATUS_INVALID_PARAMETER;
  1447. }
  1448. } except(EXCEPTION_EXECUTE_HANDLER ) {
  1449. Status = STATUS_INVALID_PARAMETER;
  1450. }
  1451. SmbCeContext.DomainName.Length = (USHORT)pLmrRequestBuffer->Parameters.Start.DomainNameLength;
  1452. SmbCeContext.DomainName.MaximumLength = SmbCeContext.DomainName.Length;
  1453. if (SmbCeContext.DomainName.Buffer != NULL) {
  1454. RxFreePool(SmbCeContext.DomainName.Buffer);
  1455. SmbCeContext.DomainName.Buffer = NULL;
  1456. }
  1457. if (SmbCeContext.DomainName.Length > 0) {
  1458. SmbCeContext.DomainName.Buffer = RxAllocatePoolWithTag(
  1459. PagedPool,
  1460. SmbCeContext.DomainName.Length,
  1461. MRXSMB_MISC_POOLTAG);
  1462. if (SmbCeContext.DomainName.Buffer == NULL) {
  1463. Status = STATUS_INSUFFICIENT_RESOURCES;
  1464. } else {
  1465. try {
  1466. // The request packet only contains the domain name on this FSCTL call.
  1467. RtlCopyMemory(
  1468. SmbCeContext.DomainName.Buffer,
  1469. &(pLmrRequestBuffer->Parameters.Start.RedirectorName[0]),
  1470. SmbCeContext.DomainName.Length);
  1471. } except(EXCEPTION_EXECUTE_HANDLER ) {
  1472. Status = STATUS_INVALID_PARAMETER;
  1473. }
  1474. }
  1475. }
  1476. if (Status == STATUS_SUCCESS) {
  1477. Status = RxSetDomainForMailslotBroadcast(&SmbCeContext.DomainName);
  1478. }
  1479. return Status;
  1480. }
  1481. extern GUID CachedServerGuid;
  1482. NTSTATUS
  1483. MRxSmbSetServerGuid(
  1484. IN PRX_CONTEXT RxContext
  1485. )
  1486. /*++
  1487. Routine Description:
  1488. This routine sets the server GUID used in loopback detection
  1489. Arguments:
  1490. RxContext - Describes the Fsctl and Context.
  1491. Return Value:
  1492. STATUS_SUCCESS -- the GUID was set correctly
  1493. STATUS_INVALID_PARAMETER -- the GUID was not passed correctly
  1494. --*/
  1495. {
  1496. PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
  1497. PVOID pInputBuffer = LowIoContext->ParamsFor.FsCtl.pInputBuffer;
  1498. ULONG InputBufferLength = LowIoContext->ParamsFor.FsCtl.InputBufferLength;
  1499. if(InputBufferLength != sizeof(GUID)) {
  1500. return STATUS_INVALID_PARAMETER;
  1501. }
  1502. try {
  1503. RtlCopyMemory(&CachedServerGuid,pInputBuffer,sizeof(GUID));
  1504. } except(EXCEPTION_EXECUTE_HANDLER ) {
  1505. return STATUS_INVALID_PARAMETER;
  1506. }
  1507. return STATUS_SUCCESS;
  1508. }