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.

919 lines
30 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. srvini.c
  5. Abstract:
  6. This is the initialization file for the Windows 32-bit Base Ini File
  7. Mapping code. It loads the INI file mapping data from the registry and
  8. places it in a data structure stored in the shared memory section that is
  9. visible as read-only data to all Win32 applications.
  10. Author:
  11. Steve Wood (stevewo) 10-Nov-1993
  12. Revision History:
  13. --*/
  14. #include "basesrv.h"
  15. PINIFILE_MAPPING BaseSrvIniFileMapping;
  16. PINIFILE_MAPPING_TARGET BaseSrvMappingTargetHead;
  17. NTSTATUS
  18. BaseSrvSaveIniFileMapping(
  19. IN PINIFILE_MAPPING_FILENAME FileNameMapping,
  20. IN HANDLE Key
  21. );
  22. BOOLEAN
  23. BaseSrvSaveFileNameMapping(
  24. IN PUNICODE_STRING FileName,
  25. OUT PINIFILE_MAPPING_FILENAME *ReturnedFileNameMapping
  26. );
  27. BOOLEAN
  28. BaseSrvSaveAppNameMapping(
  29. IN OUT PINIFILE_MAPPING_FILENAME FileNameMapping,
  30. IN PUNICODE_STRING ApplicationName OPTIONAL,
  31. OUT PINIFILE_MAPPING_APPNAME *ReturnedAppNameMapping
  32. );
  33. BOOLEAN
  34. BaseSrvSaveVarNameMapping(
  35. IN PINIFILE_MAPPING_FILENAME FileNameMapping,
  36. IN OUT PINIFILE_MAPPING_APPNAME AppNameMapping,
  37. IN PUNICODE_STRING VariableName OPTIONAL,
  38. IN PWSTR RegistryPath,
  39. OUT PINIFILE_MAPPING_VARNAME *ReturnedVarNameMapping
  40. );
  41. PINIFILE_MAPPING_TARGET
  42. BaseSrvSaveMappingTarget(
  43. IN PWSTR RegistryPath,
  44. OUT PULONG MappingFlags
  45. );
  46. NTSTATUS
  47. BaseSrvInitializeIniFileMappings(
  48. PBASE_STATIC_SERVER_DATA StaticServerData
  49. )
  50. {
  51. NTSTATUS Status;
  52. HANDLE IniFileMappingRoot;
  53. PINIFILE_MAPPING_FILENAME FileNameMapping, *pp;
  54. PINIFILE_MAPPING_APPNAME AppNameMapping;
  55. PINIFILE_MAPPING_VARNAME VarNameMapping;
  56. UNICODE_STRING KeyName;
  57. OBJECT_ATTRIBUTES ObjectAttributes;
  58. WCHAR Buffer[ 512 ];
  59. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  60. PKEY_BASIC_INFORMATION KeyInformation;
  61. ULONG ResultLength;
  62. HANDLE SubKeyHandle;
  63. ULONG SubKeyIndex;
  64. UNICODE_STRING ValueName;
  65. UNICODE_STRING SubKeyName;
  66. UNICODE_STRING WinIniFileName;
  67. UNICODE_STRING NullString;
  68. RtlInitUnicodeString( &WinIniFileName, L"win.ini" );
  69. RtlInitUnicodeString( &NullString, NULL );
  70. BaseSrvIniFileMapping = RtlAllocateHeap( BaseSrvSharedHeap,
  71. MAKE_SHARED_TAG( INI_TAG ) | HEAP_ZERO_MEMORY,
  72. sizeof( *BaseSrvIniFileMapping )
  73. );
  74. if (BaseSrvIniFileMapping == NULL) {
  75. KdPrint(( "BASESRV: Unable to allocate memory in shared heap for IniFileMapping\n" ));
  76. return STATUS_NO_MEMORY;
  77. }
  78. StaticServerData->IniFileMapping = BaseSrvIniFileMapping;
  79. RtlInitUnicodeString( &KeyName,
  80. L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping"
  81. );
  82. InitializeObjectAttributes( &ObjectAttributes,
  83. &KeyName,
  84. OBJ_CASE_INSENSITIVE,
  85. NULL,
  86. NULL
  87. );
  88. Status = NtOpenKey( &IniFileMappingRoot,
  89. GENERIC_READ,
  90. &ObjectAttributes
  91. );
  92. if (!NT_SUCCESS( Status )) {
  93. KdPrint(( "BASESRV: Unable to open %wZ key - Status == %0x\n", &KeyName, Status ));
  94. return Status;
  95. }
  96. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)Buffer;
  97. RtlInitUnicodeString( &ValueName, NULL );
  98. Status = NtQueryValueKey( IniFileMappingRoot,
  99. &ValueName,
  100. KeyValuePartialInformation,
  101. KeyValueInformation,
  102. sizeof( Buffer ),
  103. &ResultLength
  104. );
  105. if (NT_SUCCESS( Status )) {
  106. if (BaseSrvSaveFileNameMapping( &NullString, &BaseSrvIniFileMapping->DefaultFileNameMapping )) {
  107. if (BaseSrvSaveAppNameMapping( BaseSrvIniFileMapping->DefaultFileNameMapping, &NullString, &AppNameMapping )) {
  108. if (BaseSrvSaveVarNameMapping( BaseSrvIniFileMapping->DefaultFileNameMapping,
  109. AppNameMapping,
  110. &NullString,
  111. (PWSTR)(KeyValueInformation->Data),
  112. &VarNameMapping
  113. )
  114. ) {
  115. VarNameMapping->MappingFlags |= INIFILE_MAPPING_APPEND_BASE_NAME |
  116. INIFILE_MAPPING_APPEND_APPLICATION_NAME;
  117. }
  118. }
  119. }
  120. }
  121. else {
  122. Status = STATUS_SUCCESS;
  123. }
  124. //
  125. // Enumerate node's children and load mappings for each one
  126. //
  127. pp = &BaseSrvIniFileMapping->FileNames;
  128. *pp = NULL;
  129. KeyInformation = (PKEY_BASIC_INFORMATION)Buffer;
  130. for (SubKeyIndex = 0; TRUE; SubKeyIndex++) {
  131. Status = NtEnumerateKey( IniFileMappingRoot,
  132. SubKeyIndex,
  133. KeyBasicInformation,
  134. KeyInformation,
  135. sizeof( Buffer ),
  136. &ResultLength
  137. );
  138. if (Status == STATUS_NO_MORE_ENTRIES) {
  139. Status = STATUS_SUCCESS;
  140. break;
  141. }
  142. else
  143. if (!NT_SUCCESS( Status )) {
  144. KdPrint(( "BASESRV: NtEnumerateKey failed - Status == %08lx\n", Status ));
  145. break;
  146. }
  147. SubKeyName.Buffer = (PWSTR)&(KeyInformation->Name[0]);
  148. SubKeyName.Length = (USHORT)KeyInformation->NameLength;
  149. SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
  150. InitializeObjectAttributes( &ObjectAttributes,
  151. &SubKeyName,
  152. OBJ_CASE_INSENSITIVE,
  153. IniFileMappingRoot,
  154. NULL
  155. );
  156. Status = NtOpenKey( &SubKeyHandle,
  157. GENERIC_READ,
  158. &ObjectAttributes
  159. );
  160. if (NT_SUCCESS( Status )) {
  161. if (!BaseSrvSaveFileNameMapping( &SubKeyName, &FileNameMapping )) {
  162. Status = STATUS_NO_MEMORY;
  163. }
  164. else {
  165. Status = BaseSrvSaveIniFileMapping( FileNameMapping, SubKeyHandle );
  166. if (NT_SUCCESS( Status )) {
  167. if (RtlEqualUnicodeString( &FileNameMapping->Name, &WinIniFileName, TRUE )) {
  168. BaseSrvIniFileMapping->WinIniFileMapping = FileNameMapping;
  169. }
  170. *pp = FileNameMapping;
  171. pp = &FileNameMapping->Next;
  172. }
  173. else {
  174. KdPrint(( "BASESRV: Unable to load mappings for %wZ - Status == %x\n",
  175. &FileNameMapping->Name, Status
  176. ));
  177. RtlFreeHeap( BaseSrvSharedHeap, 0, FileNameMapping );
  178. FileNameMapping = NULL;
  179. }
  180. }
  181. NtClose( SubKeyHandle );
  182. }
  183. }
  184. NtClose( IniFileMappingRoot );
  185. //
  186. // NT64: this function used to fall off the end without explicitly returning
  187. // a value. from examining the object code generated, the returned
  188. // value was typically the result of NtClose(), e.g. STATUS_SUCCESS.
  189. //
  190. // In order to get the compiler to stop complaining *and* to avoid
  191. // changing existing functionality, I've made this return value
  192. // explicit. However it is almost certainly the case that the
  193. // intention was to return the value of Status.
  194. //
  195. // At any rate this should be reviewed by someone more familiar
  196. // with the code.
  197. //
  198. return STATUS_SUCCESS;
  199. }
  200. NTSTATUS
  201. BaseSrvSaveIniFileMapping(
  202. IN PINIFILE_MAPPING_FILENAME FileNameMapping,
  203. IN HANDLE Key
  204. )
  205. {
  206. NTSTATUS Status;
  207. WCHAR Buffer[ 512 ];
  208. PKEY_BASIC_INFORMATION KeyInformation;
  209. PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
  210. OBJECT_ATTRIBUTES ObjectAttributes;
  211. PINIFILE_MAPPING_APPNAME AppNameMapping;
  212. PINIFILE_MAPPING_VARNAME VarNameMapping;
  213. HANDLE SubKeyHandle;
  214. ULONG SubKeyIndex;
  215. UNICODE_STRING ValueName;
  216. UNICODE_STRING SubKeyName;
  217. UNICODE_STRING NullString;
  218. ULONG ResultLength;
  219. ULONG ValueIndex;
  220. RtlInitUnicodeString( &NullString, NULL );
  221. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
  222. for (ValueIndex = 0; TRUE; ValueIndex++) {
  223. Status = NtEnumerateValueKey( Key,
  224. ValueIndex,
  225. KeyValueFullInformation,
  226. KeyValueInformation,
  227. sizeof( Buffer ),
  228. &ResultLength
  229. );
  230. if (Status == STATUS_NO_MORE_ENTRIES) {
  231. break;
  232. }
  233. else
  234. if (!NT_SUCCESS( Status )) {
  235. KdPrint(( "BASESRV: NtEnumerateValueKey failed - Status == %08lx\n", Status ));
  236. break;
  237. }
  238. ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
  239. ValueName.Length = (USHORT)KeyValueInformation->NameLength;
  240. ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
  241. if (KeyValueInformation->Type != REG_SZ) {
  242. KdPrint(( "BASESRV: Ignoring %wZ mapping, invalid type == %u\n",
  243. &ValueName, KeyValueInformation->Type
  244. ));
  245. }
  246. else
  247. if (BaseSrvSaveAppNameMapping( FileNameMapping, &ValueName, &AppNameMapping )) {
  248. if (BaseSrvSaveVarNameMapping( FileNameMapping,
  249. AppNameMapping,
  250. &NullString,
  251. (PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset),
  252. &VarNameMapping
  253. )
  254. ) {
  255. if (ValueName.Length == 0) {
  256. VarNameMapping->MappingFlags |= INIFILE_MAPPING_APPEND_APPLICATION_NAME;
  257. }
  258. }
  259. }
  260. }
  261. //
  262. // Enumerate node's children and apply ourselves to each one
  263. //
  264. KeyInformation = (PKEY_BASIC_INFORMATION)Buffer;
  265. for (SubKeyIndex = 0; TRUE; SubKeyIndex++) {
  266. Status = NtEnumerateKey( Key,
  267. SubKeyIndex,
  268. KeyBasicInformation,
  269. KeyInformation,
  270. sizeof( Buffer ),
  271. &ResultLength
  272. );
  273. if (Status == STATUS_NO_MORE_ENTRIES) {
  274. Status = STATUS_SUCCESS;
  275. break;
  276. }
  277. else
  278. if (!NT_SUCCESS( Status )) {
  279. KdPrint(( "BASESRV: NtEnumerateKey failed - Status == %08lx\n", Status ));
  280. break;
  281. }
  282. SubKeyName.Buffer = (PWSTR)&(KeyInformation->Name[0]);
  283. SubKeyName.Length = (USHORT)KeyInformation->NameLength;
  284. SubKeyName.MaximumLength = (USHORT)KeyInformation->NameLength;
  285. InitializeObjectAttributes( &ObjectAttributes,
  286. &SubKeyName,
  287. OBJ_CASE_INSENSITIVE,
  288. Key,
  289. NULL
  290. );
  291. Status = NtOpenKey( &SubKeyHandle,
  292. GENERIC_READ,
  293. &ObjectAttributes
  294. );
  295. if (NT_SUCCESS( Status ) &&
  296. BaseSrvSaveAppNameMapping( FileNameMapping, &SubKeyName, &AppNameMapping )
  297. ) {
  298. KeyValueInformation = (PKEY_VALUE_FULL_INFORMATION)Buffer;
  299. for (ValueIndex = 0; AppNameMapping != NULL; ValueIndex++) {
  300. Status = NtEnumerateValueKey( SubKeyHandle,
  301. ValueIndex,
  302. KeyValueFullInformation,
  303. KeyValueInformation,
  304. sizeof( Buffer ),
  305. &ResultLength
  306. );
  307. if (Status == STATUS_NO_MORE_ENTRIES) {
  308. break;
  309. }
  310. else
  311. if (!NT_SUCCESS( Status )) {
  312. KdPrint(( "BASESRV: NtEnumerateValueKey failed - Status == %08lx\n", Status ));
  313. break;
  314. }
  315. ValueName.Buffer = (PWSTR)&(KeyValueInformation->Name[0]);
  316. ValueName.Length = (USHORT)KeyValueInformation->NameLength;
  317. ValueName.MaximumLength = (USHORT)KeyValueInformation->NameLength;
  318. if (KeyValueInformation->Type != REG_SZ) {
  319. KdPrint(( "BASESRV: Ignoring %wZ mapping, invalid type == %u\n",
  320. &ValueName, KeyValueInformation->Type
  321. ));
  322. }
  323. else {
  324. BaseSrvSaveVarNameMapping( FileNameMapping,
  325. AppNameMapping,
  326. &ValueName,
  327. (PWSTR)((PCHAR)KeyValueInformation + KeyValueInformation->DataOffset),
  328. &VarNameMapping
  329. );
  330. }
  331. }
  332. NtClose( SubKeyHandle );
  333. }
  334. }
  335. return Status;
  336. }
  337. BOOLEAN
  338. BaseSrvSaveFileNameMapping(
  339. IN PUNICODE_STRING FileName,
  340. OUT PINIFILE_MAPPING_FILENAME *ReturnedFileNameMapping
  341. )
  342. {
  343. PINIFILE_MAPPING_FILENAME FileNameMapping;
  344. FileNameMapping = RtlAllocateHeap( BaseSrvSharedHeap,
  345. MAKE_SHARED_TAG( INI_TAG ) | HEAP_ZERO_MEMORY,
  346. sizeof( *FileNameMapping ) +
  347. FileName->MaximumLength
  348. );
  349. if (FileNameMapping == NULL) {
  350. return FALSE;
  351. }
  352. if (FileName->Length != 0) {
  353. FileNameMapping->Name.Buffer = (PWSTR)(FileNameMapping + 1);
  354. FileNameMapping->Name.MaximumLength = FileName->MaximumLength;
  355. RtlCopyUnicodeString( &FileNameMapping->Name, FileName );
  356. }
  357. *ReturnedFileNameMapping = FileNameMapping;
  358. return TRUE;
  359. }
  360. BOOLEAN
  361. BaseSrvSaveAppNameMapping(
  362. IN OUT PINIFILE_MAPPING_FILENAME FileNameMapping,
  363. IN PUNICODE_STRING ApplicationName,
  364. OUT PINIFILE_MAPPING_APPNAME *ReturnedAppNameMapping
  365. )
  366. {
  367. PINIFILE_MAPPING_APPNAME AppNameMapping, *pp;
  368. if (ApplicationName->Length != 0) {
  369. pp = &FileNameMapping->ApplicationNames;
  370. while (AppNameMapping = *pp) {
  371. if (RtlEqualUnicodeString( ApplicationName, &AppNameMapping->Name, TRUE )) {
  372. break;
  373. }
  374. pp = &AppNameMapping->Next;
  375. }
  376. }
  377. else {
  378. pp = &FileNameMapping->DefaultAppNameMapping;
  379. AppNameMapping = *pp;
  380. }
  381. if (AppNameMapping != NULL) {
  382. KdPrint(( "BASESRV: Duplicate application name mapping [%ws] %ws\n",
  383. &FileNameMapping->Name,
  384. &AppNameMapping->Name
  385. ));
  386. return FALSE;
  387. }
  388. AppNameMapping = RtlAllocateHeap( BaseSrvSharedHeap,
  389. MAKE_SHARED_TAG( INI_TAG ) | HEAP_ZERO_MEMORY,
  390. sizeof( *AppNameMapping ) +
  391. ApplicationName->MaximumLength
  392. );
  393. if (AppNameMapping == NULL) {
  394. return FALSE;
  395. }
  396. if (ApplicationName->Length != 0) {
  397. AppNameMapping->Name.Buffer = (PWSTR)(AppNameMapping + 1);
  398. AppNameMapping->Name.MaximumLength = ApplicationName->MaximumLength;
  399. RtlCopyUnicodeString( &AppNameMapping->Name, ApplicationName );
  400. }
  401. *pp = AppNameMapping;
  402. *ReturnedAppNameMapping = AppNameMapping;
  403. return TRUE;
  404. }
  405. BOOLEAN
  406. BaseSrvSaveVarNameMapping(
  407. IN PINIFILE_MAPPING_FILENAME FileNameMapping,
  408. IN OUT PINIFILE_MAPPING_APPNAME AppNameMapping,
  409. IN PUNICODE_STRING VariableName,
  410. IN PWSTR RegistryPath,
  411. OUT PINIFILE_MAPPING_VARNAME *ReturnedVarNameMapping
  412. )
  413. {
  414. PINIFILE_MAPPING_TARGET MappingTarget;
  415. PINIFILE_MAPPING_VARNAME VarNameMapping, *pp;
  416. ULONG MappingFlags;
  417. if (VariableName->Length != 0) {
  418. pp = &AppNameMapping->VariableNames;
  419. while (VarNameMapping = *pp) {
  420. if (RtlEqualUnicodeString( VariableName, &VarNameMapping->Name, TRUE )) {
  421. break;
  422. }
  423. pp = &VarNameMapping->Next;
  424. }
  425. }
  426. else {
  427. pp = &AppNameMapping->DefaultVarNameMapping;
  428. VarNameMapping = *pp;
  429. }
  430. if (VarNameMapping != NULL) {
  431. KdPrint(( "BASESRV: Duplicate variable name mapping [%ws] %ws . %ws\n",
  432. &FileNameMapping->Name,
  433. &AppNameMapping->Name,
  434. &VarNameMapping->Name
  435. ));
  436. return FALSE;
  437. }
  438. MappingTarget = BaseSrvSaveMappingTarget( RegistryPath, &MappingFlags );
  439. if (MappingTarget == NULL) {
  440. return FALSE;
  441. }
  442. VarNameMapping = RtlAllocateHeap( BaseSrvSharedHeap,
  443. MAKE_SHARED_TAG( INI_TAG ) | HEAP_ZERO_MEMORY,
  444. sizeof( *VarNameMapping ) +
  445. VariableName->MaximumLength
  446. );
  447. if (VarNameMapping == NULL) {
  448. return FALSE;
  449. }
  450. VarNameMapping->MappingFlags = MappingFlags;
  451. VarNameMapping->MappingTarget = MappingTarget;
  452. if (VariableName->Length != 0) {
  453. VarNameMapping->Name.Buffer = (PWSTR)(VarNameMapping + 1);
  454. VarNameMapping->Name.MaximumLength = VariableName->MaximumLength;
  455. RtlCopyUnicodeString( &VarNameMapping->Name, VariableName );
  456. }
  457. *pp = VarNameMapping;
  458. *ReturnedVarNameMapping = VarNameMapping;
  459. return TRUE;
  460. }
  461. PINIFILE_MAPPING_TARGET
  462. BaseSrvSaveMappingTarget(
  463. IN PWSTR RegistryPath,
  464. OUT PULONG MappingFlags
  465. )
  466. {
  467. BOOLEAN RelativePath;
  468. UNICODE_STRING RegistryPathString;
  469. PWSTR SaveRegistryPath;
  470. PINIFILE_MAPPING_TARGET MappingTarget, *pp;
  471. ULONG Flags;
  472. Flags = 0;
  473. SaveRegistryPath = RegistryPath;
  474. while (TRUE) {
  475. if (*RegistryPath == L'!') {
  476. Flags |= INIFILE_MAPPING_WRITE_TO_INIFILE_TOO;
  477. RegistryPath += 1;
  478. }
  479. else
  480. if (*RegistryPath == L'#') {
  481. Flags |= INIFILE_MAPPING_INIT_FROM_INIFILE;
  482. RegistryPath += 1;
  483. }
  484. else
  485. if (*RegistryPath == L'@') {
  486. Flags |= INIFILE_MAPPING_READ_FROM_REGISTRY_ONLY;
  487. RegistryPath += 1;
  488. }
  489. else
  490. if (!_wcsnicmp( RegistryPath, L"USR:", 4 )) {
  491. Flags |= INIFILE_MAPPING_USER_RELATIVE;
  492. RegistryPath += 4;
  493. break;
  494. }
  495. else
  496. if (!_wcsnicmp( RegistryPath, L"SYS:", 4 )) {
  497. Flags |= INIFILE_MAPPING_SOFTWARE_RELATIVE;
  498. RegistryPath += 4;
  499. break;
  500. }
  501. else {
  502. break;
  503. }
  504. }
  505. if (Flags & (INIFILE_MAPPING_USER_RELATIVE | INIFILE_MAPPING_SOFTWARE_RELATIVE)) {
  506. RelativePath = TRUE;
  507. }
  508. else {
  509. RelativePath = FALSE;
  510. }
  511. if ((RelativePath && *RegistryPath != OBJ_NAME_PATH_SEPARATOR) ||
  512. (!RelativePath && *RegistryPath == OBJ_NAME_PATH_SEPARATOR)
  513. ) {
  514. RtlInitUnicodeString( &RegistryPathString, RegistryPath );
  515. }
  516. else
  517. if (!RelativePath && *RegistryPath == UNICODE_NULL) {
  518. RtlInitUnicodeString( &RegistryPathString, NULL );
  519. }
  520. else {
  521. KdPrint(( "BASESRV: Ignoring invalid mapping target - %ws\n",
  522. SaveRegistryPath
  523. ));
  524. return NULL;
  525. }
  526. pp = &BaseSrvMappingTargetHead;
  527. while (MappingTarget = *pp) {
  528. if (RtlEqualUnicodeString( &RegistryPathString, &MappingTarget->RegistryPath, TRUE )) {
  529. *MappingFlags = Flags;
  530. return MappingTarget;
  531. }
  532. pp = &MappingTarget->Next;
  533. }
  534. MappingTarget = RtlAllocateHeap( BaseSrvSharedHeap,
  535. MAKE_SHARED_TAG( INI_TAG ) | HEAP_ZERO_MEMORY,
  536. sizeof( *MappingTarget ) +
  537. RegistryPathString.MaximumLength
  538. );
  539. if (MappingTarget != NULL) {
  540. *MappingFlags = Flags;
  541. *pp = MappingTarget;
  542. if (RegistryPathString.Length != 0) {
  543. MappingTarget->RegistryPath.Buffer = (PWSTR)(MappingTarget + 1);
  544. MappingTarget->RegistryPath.Length = 0;
  545. MappingTarget->RegistryPath.MaximumLength = RegistryPathString.MaximumLength;
  546. RtlCopyUnicodeString( &MappingTarget->RegistryPath, &RegistryPathString );
  547. }
  548. }
  549. else {
  550. KdPrint(( "BASESRV: Unable to allocate memory for mapping target - %ws\n", RegistryPath ));
  551. }
  552. return MappingTarget;
  553. }
  554. BOOLEAN
  555. BaseSrvEqualVarNameMappings(
  556. PINIFILE_MAPPING_VARNAME VarNameMapping1,
  557. PINIFILE_MAPPING_VARNAME VarNameMapping2
  558. )
  559. {
  560. if (VarNameMapping1 == NULL) {
  561. if (VarNameMapping2 == NULL) {
  562. return TRUE;
  563. }
  564. else {
  565. return FALSE;
  566. }
  567. }
  568. else
  569. if (VarNameMapping2 == NULL) {
  570. return FALSE;
  571. }
  572. if (RtlEqualUnicodeString( &VarNameMapping1->Name,
  573. &VarNameMapping2->Name,
  574. TRUE
  575. ) &&
  576. VarNameMapping1->MappingFlags == VarNameMapping2->MappingFlags &&
  577. VarNameMapping1->MappingTarget == VarNameMapping2->MappingTarget &&
  578. BaseSrvEqualVarNameMappings( VarNameMapping1->Next,
  579. VarNameMapping2->Next
  580. )
  581. ) {
  582. return TRUE;
  583. }
  584. else {
  585. return FALSE;
  586. }
  587. }
  588. BOOLEAN
  589. BaseSrvEqualAppNameMappings(
  590. PINIFILE_MAPPING_APPNAME AppNameMapping1,
  591. PINIFILE_MAPPING_APPNAME AppNameMapping2
  592. )
  593. {
  594. if (AppNameMapping1 == NULL) {
  595. if (AppNameMapping2 == NULL) {
  596. return TRUE;
  597. }
  598. else {
  599. return FALSE;
  600. }
  601. }
  602. else
  603. if (AppNameMapping2 == NULL) {
  604. return FALSE;
  605. }
  606. if (RtlEqualUnicodeString( &AppNameMapping1->Name,
  607. &AppNameMapping2->Name,
  608. TRUE
  609. ) &&
  610. BaseSrvEqualVarNameMappings( AppNameMapping1->VariableNames,
  611. AppNameMapping2->VariableNames
  612. ) &&
  613. BaseSrvEqualVarNameMappings( AppNameMapping1->DefaultVarNameMapping,
  614. AppNameMapping2->DefaultVarNameMapping
  615. ) &&
  616. BaseSrvEqualAppNameMappings( AppNameMapping1->Next,
  617. AppNameMapping2->Next
  618. )
  619. ) {
  620. return TRUE;
  621. }
  622. else {
  623. return FALSE;
  624. }
  625. }
  626. BOOLEAN
  627. BaseSrvEqualFileMappings(
  628. PINIFILE_MAPPING_FILENAME FileNameMapping1,
  629. PINIFILE_MAPPING_FILENAME FileNameMapping2
  630. )
  631. {
  632. if (RtlEqualUnicodeString( &FileNameMapping1->Name,
  633. &FileNameMapping2->Name,
  634. TRUE
  635. ) &&
  636. BaseSrvEqualAppNameMappings( FileNameMapping1->ApplicationNames,
  637. FileNameMapping2->ApplicationNames
  638. ) &&
  639. BaseSrvEqualAppNameMappings( FileNameMapping1->DefaultAppNameMapping,
  640. FileNameMapping2->DefaultAppNameMapping
  641. )
  642. ) {
  643. return TRUE;
  644. }
  645. else {
  646. return FALSE;
  647. }
  648. }
  649. VOID
  650. BaseSrvFreeVarNameMapping(
  651. PINIFILE_MAPPING_VARNAME VarNameMapping
  652. )
  653. {
  654. if (VarNameMapping != NULL) {
  655. BaseSrvFreeVarNameMapping( VarNameMapping->Next );
  656. RtlFreeHeap( BaseSrvSharedHeap, HEAP_NO_SERIALIZE, VarNameMapping );
  657. }
  658. return;
  659. }
  660. VOID
  661. BaseSrvFreeAppNameMapping(
  662. PINIFILE_MAPPING_APPNAME AppNameMapping
  663. )
  664. {
  665. if (AppNameMapping != NULL) {
  666. BaseSrvFreeVarNameMapping( AppNameMapping->VariableNames );
  667. BaseSrvFreeVarNameMapping( AppNameMapping->DefaultVarNameMapping );
  668. BaseSrvFreeAppNameMapping( AppNameMapping->Next );
  669. RtlFreeHeap( BaseSrvSharedHeap, HEAP_NO_SERIALIZE, AppNameMapping );
  670. }
  671. return;
  672. }
  673. VOID
  674. BaseSrvFreeFileMapping(
  675. PINIFILE_MAPPING_FILENAME FileNameMapping
  676. )
  677. {
  678. if (FileNameMapping != NULL) {
  679. BaseSrvFreeAppNameMapping( FileNameMapping->ApplicationNames );
  680. BaseSrvFreeAppNameMapping( FileNameMapping->DefaultAppNameMapping );
  681. RtlFreeHeap( BaseSrvSharedHeap, HEAP_NO_SERIALIZE, FileNameMapping );
  682. }
  683. return;
  684. }
  685. ULONG
  686. BaseSrvRefreshIniFileMapping(
  687. IN OUT PCSR_API_MSG m,
  688. IN OUT PCSR_REPLY_STATUS ReplyStatus
  689. )
  690. {
  691. PBASE_REFRESHINIFILEMAPPING_MSG a = (PBASE_REFRESHINIFILEMAPPING_MSG)&m->u.ApiMessageData;
  692. NTSTATUS Status;
  693. HANDLE IniFileMappingRoot;
  694. PINIFILE_MAPPING_FILENAME FileNameMapping, FileNameMapping1, *pp;
  695. UNICODE_STRING KeyName;
  696. OBJECT_ATTRIBUTES ObjectAttributes;
  697. HANDLE SubKeyHandle;
  698. UNICODE_STRING WinIniFileName;
  699. UNICODE_STRING NullString;
  700. Status = STATUS_SUCCESS;
  701. if (!CsrValidateMessageBuffer(m, &a->IniFileName.Buffer, a->IniFileName.Length, sizeof(BYTE))) {
  702. return STATUS_INVALID_PARAMETER;
  703. }
  704. RtlInitUnicodeString( &WinIniFileName, L"win.ini" );
  705. RtlInitUnicodeString( &NullString, NULL );
  706. RtlInitUnicodeString( &KeyName,
  707. L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping"
  708. );
  709. InitializeObjectAttributes( &ObjectAttributes,
  710. &KeyName,
  711. OBJ_CASE_INSENSITIVE,
  712. NULL,
  713. NULL
  714. );
  715. Status = NtOpenKey( &IniFileMappingRoot,
  716. GENERIC_READ,
  717. &ObjectAttributes
  718. );
  719. if (!NT_SUCCESS( Status )) {
  720. KdPrint(( "BASESRV: Unable to open %wZ key - Status == %0x\n", &KeyName, Status ));
  721. return (ULONG)Status;
  722. }
  723. InitializeObjectAttributes( &ObjectAttributes,
  724. &a->IniFileName,
  725. OBJ_CASE_INSENSITIVE,
  726. IniFileMappingRoot,
  727. NULL
  728. );
  729. Status = NtOpenKey( &SubKeyHandle,
  730. GENERIC_READ,
  731. &ObjectAttributes
  732. );
  733. if (NT_SUCCESS( Status )) {
  734. if (!BaseSrvSaveFileNameMapping( &a->IniFileName, &FileNameMapping )) {
  735. Status = STATUS_NO_MEMORY;
  736. }
  737. else {
  738. Status = BaseSrvSaveIniFileMapping( FileNameMapping, SubKeyHandle );
  739. if (NT_SUCCESS( Status )) {
  740. RtlLockHeap( BaseSrvSharedHeap );
  741. try {
  742. pp = &BaseSrvIniFileMapping->FileNames;
  743. while (FileNameMapping1 = *pp) {
  744. if (RtlEqualUnicodeString( &FileNameMapping1->Name, &a->IniFileName, TRUE )) {
  745. if (BaseSrvEqualFileMappings( FileNameMapping, FileNameMapping1 )) {
  746. //
  747. // If old and new mappings the same, free up new and return
  748. //
  749. BaseSrvFreeFileMapping( FileNameMapping );
  750. FileNameMapping = NULL;
  751. }
  752. else {
  753. //
  754. // Remove found mapping from list
  755. //
  756. *pp = FileNameMapping1->Next;
  757. FileNameMapping1->Next = NULL;
  758. }
  759. break;
  760. }
  761. else {
  762. pp = &FileNameMapping1->Next;
  763. }
  764. }
  765. if (FileNameMapping != NULL) {
  766. //
  767. // Insert new (or different) mapping into list (at end if not found)
  768. //
  769. FileNameMapping->Next = *pp;
  770. *pp = FileNameMapping;
  771. }
  772. }
  773. except( EXCEPTION_EXECUTE_HANDLER ) {
  774. Status = GetExceptionCode();
  775. }
  776. RtlUnlockHeap( BaseSrvSharedHeap );
  777. if (NT_SUCCESS( Status ) && FileNameMapping != NULL) {
  778. if (RtlEqualUnicodeString( &FileNameMapping->Name, &WinIniFileName, TRUE )) {
  779. BaseSrvIniFileMapping->WinIniFileMapping = FileNameMapping;
  780. }
  781. }
  782. }
  783. else {
  784. KdPrint(( "BASESRV: Unable to load mappings for %wZ - Status == %x\n",
  785. &FileNameMapping->Name, Status
  786. ));
  787. RtlFreeHeap( BaseSrvSharedHeap, 0, FileNameMapping );
  788. }
  789. }
  790. NtClose( SubKeyHandle );
  791. }
  792. NtClose( IniFileMappingRoot );
  793. return (ULONG)Status;
  794. ReplyStatus; // get rid of unreferenced parameter warning message
  795. }
  796. ULONG
  797. BaseSrvSetTermsrvAppInstallMode(IN OUT PCSR_API_MSG m,
  798. IN OUT PCSR_REPLY_STATUS ReplyStatus)
  799. {
  800. PBASE_SET_TERMSRVAPPINSTALLMODE b = (PBASE_SET_TERMSRVAPPINSTALLMODE)&m->u.ApiMessageData;
  801. if ( b->bState )
  802. BaseSrvpStaticServerData->fTermsrvAppInstallMode = TRUE;
  803. else
  804. BaseSrvpStaticServerData->fTermsrvAppInstallMode = FALSE;
  805. return( STATUS_SUCCESS );
  806. }