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.

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