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.

1652 lines
46 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. env.c
  5. Abstract:
  6. Implements ISM environment variable support
  7. Author:
  8. Jim Schmidt (jimschm) 01-Mar-2000
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. //
  13. // Includes
  14. //
  15. #include "pch.h"
  16. #include "ism.h"
  17. #include "ismp.h"
  18. #define DBG_ISMENV "IsmEnv"
  19. //
  20. // Strings
  21. //
  22. #define S_MEMDB_ENV_ROOT_SRC TEXT("EnvSrc")
  23. #define S_MEMDB_ENV_ROOT_DEST TEXT("EnvDest")
  24. //
  25. // Constants
  26. //
  27. // None
  28. //
  29. // Macros
  30. //
  31. // None
  32. //
  33. // Types
  34. //
  35. typedef struct {
  36. ENVENTRY_TYPE Type;
  37. UINT DataSize;
  38. BYTE Data[];
  39. } ENVIRONMENT_ENTRY, *PENVIRONMENT_ENTRY;
  40. //
  41. // Globals
  42. //
  43. GROWBUFFER g_AppendBuffer = INIT_GROWBUFFER;
  44. //
  45. // Macro expansion list
  46. //
  47. // None
  48. //
  49. // Private function prototypes
  50. //
  51. BOOL
  52. pGetEnvironmentValue (
  53. IN UINT Platform,
  54. IN OUT KEYHANDLE *KeyHandle, OPTIONAL
  55. IN PCTSTR Group, OPTIONAL
  56. IN PCTSTR VariableName,
  57. OUT PBYTE Data, OPTIONAL
  58. IN UINT DataSize,
  59. OUT PUINT DataSizeNeeded, OPTIONAL
  60. OUT PENVENTRY_TYPE DataType OPTIONAL
  61. );
  62. //
  63. // Macro expansion definition
  64. //
  65. // None
  66. //
  67. // Code
  68. //
  69. BOOL
  70. InitializeEnv (
  71. VOID
  72. )
  73. {
  74. return TRUE;
  75. }
  76. VOID
  77. TerminateEnv (
  78. VOID
  79. )
  80. {
  81. GbFree (&g_AppendBuffer);
  82. }
  83. BOOL
  84. EnvEnumerateFirstEntry (
  85. OUT PENV_ENTRY_ENUM EnvEntryEnum,
  86. IN MIG_PLATFORMTYPEID Platform,
  87. IN PCTSTR Pattern
  88. )
  89. {
  90. PCTSTR pattern = NULL;
  91. PENVIRONMENT_ENTRY envEntry;
  92. UINT dataSize;
  93. BOOL result = FALSE;
  94. if (Platform == PLATFORM_CURRENT) {
  95. Platform = g_IsmCurrentPlatform;
  96. }
  97. if (Platform == PLATFORM_SOURCE) {
  98. pattern = JoinPaths (S_MEMDB_ENV_ROOT_SRC, Pattern);
  99. } else {
  100. pattern = JoinPaths (S_MEMDB_ENV_ROOT_DEST, Pattern);
  101. }
  102. ZeroMemory (EnvEntryEnum, sizeof (PENV_ENTRY_ENUM));
  103. EnvEntryEnum->Platform = Platform;
  104. if (MemDbEnumFirst (&EnvEntryEnum->Handle, pattern, ENUMFLAG_NORMAL, 1, ENUMLEVEL_ALLLEVELS)) {
  105. envEntry = (PENVIRONMENT_ENTRY) MemDbGetUnorderedBlob (EnvEntryEnum->Handle.FullKeyName, 0, NULL);
  106. EnvEntryEnum->EnvEntryType = envEntry->Type;
  107. EnvEntryEnum->EnvEntryGroup = DuplicatePathString (EnvEntryEnum->Handle.KeyName, 0);
  108. EnvEntryEnum->EnvEntryName = _tcschr (EnvEntryEnum->EnvEntryGroup, TEXT('\\'));
  109. if (EnvEntryEnum->EnvEntryName) {
  110. *((PTSTR)(EnvEntryEnum->EnvEntryName)) = 0;
  111. EnvEntryEnum->EnvEntryName ++;
  112. } else {
  113. EnvEntryEnum->EnvEntryName = EnvEntryEnum->EnvEntryGroup;
  114. EnvEntryEnum->EnvEntryGroup = NULL;
  115. }
  116. #ifdef UNICODE
  117. EnvEntryEnum->EnvEntryDataSize = envEntry->DataSize;
  118. if (envEntry->DataSize) {
  119. EnvEntryEnum->EnvEntryData = IsmGetMemory (envEntry->DataSize);
  120. CopyMemory (EnvEntryEnum->EnvEntryData, envEntry->Data, envEntry->DataSize);
  121. } else {
  122. EnvEntryEnum->EnvEntryData = NULL;
  123. }
  124. #else
  125. if (envEntry->Type == ENVENTRY_STRING) {
  126. dataSize = SizeOfStringA ((PCSTR)envEntry->Data) * 2;
  127. EnvEntryEnum->EnvEntryData = IsmGetMemory (dataSize);
  128. ZeroMemory (EnvEntryEnum->EnvEntryData, dataSize);
  129. DirectDbcsToUnicodeN (
  130. (PWSTR)EnvEntryEnum->EnvEntryData,
  131. (PSTR)envEntry->Data,
  132. SizeOfStringA ((PCSTR)envEntry->Data)
  133. );
  134. EnvEntryEnum->EnvEntryDataSize = SizeOfStringW ((PWSTR)EnvEntryEnum->EnvEntryData);
  135. } else if (envEntry->Type == ENVENTRY_MULTISZ) {
  136. dataSize = SizeOfMultiSzA ((PCSTR)envEntry->Data) * 2;
  137. EnvEntryEnum->EnvEntryData = IsmGetMemory (dataSize);
  138. ZeroMemory (EnvEntryEnum->EnvEntryData, dataSize);
  139. DirectDbcsToUnicodeN (
  140. (PWSTR)EnvEntryEnum->EnvEntryData,
  141. (PSTR)envEntry->Data,
  142. SizeOfMultiSzA ((PCSTR)envEntry->Data)
  143. );
  144. EnvEntryEnum->EnvEntryDataSize = SizeOfMultiSzW ((PWSTR)EnvEntryEnum->EnvEntryData);
  145. } else {
  146. EnvEntryEnum->EnvEntryDataSize = envEntry->DataSize;
  147. if (envEntry->DataSize) {
  148. EnvEntryEnum->EnvEntryData = IsmGetMemory (envEntry->DataSize);
  149. CopyMemory (EnvEntryEnum->EnvEntryData, envEntry->Data, envEntry->DataSize);
  150. } else {
  151. EnvEntryEnum->EnvEntryData = NULL;
  152. }
  153. }
  154. #endif
  155. MemDbReleaseMemory (envEntry);
  156. result = TRUE;
  157. }
  158. FreePathString (pattern);
  159. return result;
  160. }
  161. BOOL
  162. EnvEnumerateNextEntry (
  163. IN OUT PENV_ENTRY_ENUM EnvEntryEnum
  164. )
  165. {
  166. PENVIRONMENT_ENTRY envEntry;
  167. UINT dataSize;
  168. BOOL result = FALSE;
  169. if (EnvEntryEnum->EnvEntryData) {
  170. IsmReleaseMemory (EnvEntryEnum->EnvEntryData);
  171. EnvEntryEnum->EnvEntryData = NULL;
  172. }
  173. if (EnvEntryEnum->EnvEntryGroup) {
  174. FreePathString (EnvEntryEnum->EnvEntryGroup);
  175. EnvEntryEnum->EnvEntryGroup = NULL;
  176. EnvEntryEnum->EnvEntryName = NULL;
  177. }
  178. if (EnvEntryEnum->EnvEntryName) {
  179. FreePathString (EnvEntryEnum->EnvEntryName);
  180. EnvEntryEnum->EnvEntryName = NULL;
  181. }
  182. if (MemDbEnumNext (&EnvEntryEnum->Handle)) {
  183. envEntry = (PENVIRONMENT_ENTRY) MemDbGetUnorderedBlob (EnvEntryEnum->Handle.FullKeyName, 0, NULL);
  184. EnvEntryEnum->EnvEntryType = envEntry->Type;
  185. EnvEntryEnum->EnvEntryGroup = DuplicatePathString (EnvEntryEnum->Handle.KeyName, 0);
  186. EnvEntryEnum->EnvEntryName = _tcschr (EnvEntryEnum->EnvEntryGroup, TEXT('\\'));
  187. if (EnvEntryEnum->EnvEntryName) {
  188. *((PTSTR)(EnvEntryEnum->EnvEntryName)) = 0;
  189. EnvEntryEnum->EnvEntryName ++;
  190. } else {
  191. EnvEntryEnum->EnvEntryName = EnvEntryEnum->EnvEntryGroup;
  192. EnvEntryEnum->EnvEntryGroup = NULL;
  193. }
  194. #ifdef UNICODE
  195. EnvEntryEnum->EnvEntryDataSize = envEntry->DataSize;
  196. if (envEntry->DataSize) {
  197. EnvEntryEnum->EnvEntryData = IsmGetMemory (envEntry->DataSize);
  198. CopyMemory (EnvEntryEnum->EnvEntryData, envEntry->Data, envEntry->DataSize);
  199. } else {
  200. EnvEntryEnum->EnvEntryData = NULL;
  201. }
  202. #else
  203. if (envEntry->Type == ENVENTRY_STRING) {
  204. dataSize = SizeOfStringW ((PCWSTR)envEntry->Data) * 2;
  205. EnvEntryEnum->EnvEntryData = IsmGetMemory (dataSize);
  206. ZeroMemory (EnvEntryEnum->EnvEntryData, dataSize);
  207. DirectUnicodeToDbcsN (
  208. (PSTR)EnvEntryEnum->EnvEntryData,
  209. (PWSTR)envEntry->Data,
  210. SizeOfStringW ((PCWSTR)envEntry->Data)
  211. );
  212. EnvEntryEnum->EnvEntryDataSize = SizeOfStringW ((PWSTR)EnvEntryEnum->EnvEntryData);
  213. } else if (envEntry->Type == ENVENTRY_MULTISZ) {
  214. dataSize = SizeOfMultiSzW ((PCWSTR)envEntry->Data) * 2;
  215. EnvEntryEnum->EnvEntryData = IsmGetMemory (dataSize);
  216. ZeroMemory (EnvEntryEnum->EnvEntryData, dataSize);
  217. DirectUnicodeToDbcsN (
  218. (PSTR)EnvEntryEnum->EnvEntryData,
  219. (PWSTR)envEntry->Data,
  220. SizeOfMultiSzW ((PCWSTR)envEntry->Data)
  221. );
  222. EnvEntryEnum->EnvEntryDataSize = SizeOfMultiSzW ((PWSTR)EnvEntryEnum->EnvEntryData);
  223. } else {
  224. EnvEntryEnum->EnvEntryDataSize = envEntry->DataSize;
  225. if (envEntry->DataSize) {
  226. EnvEntryEnum->EnvEntryData = IsmGetMemory (envEntry->DataSize);
  227. CopyMemory (EnvEntryEnum->EnvEntryData, envEntry->Data, envEntry->DataSize);
  228. } else {
  229. EnvEntryEnum->EnvEntryData = NULL;
  230. }
  231. }
  232. #endif
  233. MemDbReleaseMemory (envEntry);
  234. result = TRUE;
  235. } else {
  236. MemDbAbortEnum (&EnvEntryEnum->Handle);
  237. }
  238. return result;
  239. }
  240. VOID
  241. AbortEnvEnumerateEntry (
  242. IN OUT PENV_ENTRY_ENUM EnvEntryEnum
  243. )
  244. {
  245. if (EnvEntryEnum->EnvEntryData) {
  246. IsmReleaseMemory (EnvEntryEnum->EnvEntryData);
  247. EnvEntryEnum->EnvEntryData = NULL;
  248. }
  249. if (EnvEntryEnum->EnvEntryGroup) {
  250. FreePathString (EnvEntryEnum->EnvEntryGroup);
  251. EnvEntryEnum->EnvEntryGroup = NULL;
  252. EnvEntryEnum->EnvEntryName = NULL;
  253. }
  254. if (EnvEntryEnum->EnvEntryName) {
  255. FreePathString (EnvEntryEnum->EnvEntryName);
  256. EnvEntryEnum->EnvEntryName = NULL;
  257. }
  258. MemDbAbortEnum (&EnvEntryEnum->Handle);
  259. ZeroMemory (EnvEntryEnum, sizeof (PENV_ENTRY_ENUM));
  260. }
  261. VOID
  262. EnvInvalidateCallbacks (
  263. VOID
  264. )
  265. {
  266. GROWBUFFER envBuff = INIT_GROWBUFFER;
  267. PCTSTR pattern = NULL;
  268. MEMDB_ENUM e;
  269. MULTISZ_ENUM se;
  270. BOOL toDelete = FALSE;
  271. PENVIRONMENT_ENTRY envEntry;
  272. pattern = JoinPaths (S_MEMDB_ENV_ROOT_SRC, TEXT("*"));
  273. if (MemDbEnumFirst (&e, pattern, ENUMFLAG_NORMAL, 0, ENUMLEVEL_ALLLEVELS)) {
  274. do {
  275. envEntry = (PENVIRONMENT_ENTRY) MemDbGetUnorderedBlob (e.FullKeyName, 0, NULL);
  276. if (envEntry->Type == ENVENTRY_CALLBACK) {
  277. GbMultiSzAppend (&envBuff, e.FullKeyName);
  278. toDelete = TRUE;
  279. }
  280. MemDbReleaseMemory (envEntry);
  281. } while (MemDbEnumNext (&e));
  282. MemDbAbortEnum (&e);
  283. }
  284. if (toDelete && EnumFirstMultiSz (&se, (PCTSTR) envBuff.Buf)) {
  285. do {
  286. MemDbDeleteKey (se.CurrentString);
  287. } while (EnumNextMultiSz (&se));
  288. }
  289. FreePathString (pattern);
  290. }
  291. VOID
  292. pEnvSave (
  293. IN PCTSTR Pattern,
  294. IN OUT PGROWLIST GrowList
  295. )
  296. {
  297. MEMDB_ENUM e;
  298. PENVIRONMENT_ENTRY envEntry;
  299. UINT strSize;
  300. PBYTE listStruct;
  301. if (MemDbEnumFirst (&e, Pattern, ENUMFLAG_NORMAL, 0, ENUMLEVEL_ALLLEVELS)) {
  302. do {
  303. envEntry = (PENVIRONMENT_ENTRY) MemDbGetUnorderedBlob (e.FullKeyName, 0, NULL);
  304. strSize = SizeOfString (e.FullKeyName);
  305. listStruct = PmGetMemory (g_IsmPool, strSize + sizeof (ENVIRONMENT_ENTRY) + envEntry->DataSize);
  306. CopyMemory (listStruct, e.FullKeyName, strSize);
  307. CopyMemory (listStruct + strSize, envEntry, sizeof (ENVIRONMENT_ENTRY) + envEntry->DataSize);
  308. GlAppend (GrowList, listStruct, strSize + sizeof (ENVIRONMENT_ENTRY) + envEntry->DataSize);
  309. PmReleaseMemory (g_IsmPool, listStruct);
  310. MemDbReleaseMemory (envEntry);
  311. } while (MemDbEnumNext (&e));
  312. }
  313. }
  314. BOOL
  315. EnvSaveEnvironment (
  316. IN OUT PGROWLIST GrowList
  317. )
  318. {
  319. pEnvSave (S_MEMDB_ENV_ROOT_SRC TEXT("\\*"), GrowList);
  320. pEnvSave (S_MEMDB_ENV_ROOT_DEST TEXT("\\*"), GrowList);
  321. return TRUE;
  322. }
  323. BOOL
  324. EnvRestoreEnvironment (
  325. IN PGROWLIST GrowList
  326. )
  327. {
  328. UINT listSize, i;
  329. PBYTE listStruct;
  330. PCTSTR memdbName;
  331. PENVIRONMENT_ENTRY envEntry;
  332. listSize = GlGetSize (GrowList);
  333. for (i = 0; i < listSize; i ++) {
  334. listStruct = GlGetItem (GrowList, i);
  335. memdbName = (PCTSTR) listStruct;
  336. if (!MemDbTestKey (memdbName)) {
  337. envEntry = (PENVIRONMENT_ENTRY) (GetEndOfString ((PCTSTR) listStruct) + 1);
  338. if (!MemDbSetUnorderedBlob (
  339. memdbName,
  340. 0,
  341. (PBYTE) envEntry,
  342. sizeof (ENVIRONMENT_ENTRY) + envEntry->DataSize
  343. )) {
  344. EngineError ();
  345. }
  346. }
  347. }
  348. return TRUE;
  349. }
  350. BOOL
  351. IsmSetEnvironmentValue (
  352. IN MIG_PLATFORMTYPEID Platform,
  353. IN PCTSTR Group, OPTIONAL
  354. IN PCTSTR VariableName,
  355. IN PENVENTRY_STRUCT VariableData OPTIONAL
  356. )
  357. {
  358. PCTSTR memdbName = NULL;
  359. BOOL result = FALSE;
  360. KEYHANDLE kh;
  361. PENVIRONMENT_ENTRY envEntry = NULL;
  362. UINT dataSize;
  363. PCVOID dataPtr;
  364. DATAHANDLE dh;
  365. BOOL destPlatform = FALSE;
  366. #ifndef UNICODE
  367. PWSTR unicodeData = NULL;
  368. #endif
  369. if ((Platform != PLATFORM_SOURCE) &&
  370. (Platform != PLATFORM_DESTINATION)
  371. ) {
  372. DEBUGMSG ((DBG_ERROR, "Environment variable specified with no platform."));
  373. return FALSE;
  374. }
  375. destPlatform = (Platform == PLATFORM_DESTINATION);
  376. __try {
  377. //
  378. // Validate arguments
  379. //
  380. if (!VariableName || !(*VariableName)) {
  381. DEBUGMSG ((DBG_ERROR, "Invalid variable name"));
  382. SetLastError (ERROR_INVALID_PARAMETER);
  383. __leave;
  384. }
  385. //
  386. // Build decorated name by joining current group with variable name,
  387. // then build memdb key
  388. //
  389. memdbName = JoinPathsInPoolEx ((
  390. NULL,
  391. destPlatform?S_MEMDB_ENV_ROOT_DEST:S_MEMDB_ENV_ROOT_SRC,
  392. Group?Group:VariableName,
  393. Group?VariableName:NULL,
  394. NULL
  395. ));
  396. kh = MemDbSetKey (memdbName);
  397. if (!kh) {
  398. DEBUGMSG ((DBG_ERROR, "Error while adding environment variable into database"));
  399. EngineError ();
  400. __leave;
  401. }
  402. MemDbDeleteUnorderedBlobByKeyHandle (kh, 0);
  403. if (VariableData->Type == ENVENTRY_STRING) {
  404. if (VariableData->EnvString == NULL) {
  405. dataSize = sizeof (TCHAR);
  406. dataPtr = TEXT("");
  407. } else {
  408. #ifdef UNICODE
  409. dataSize = SizeOfStringW (VariableData->EnvString);
  410. dataPtr = VariableData->EnvString;
  411. #else
  412. dataSize = SizeOfStringA (VariableData->EnvString) * 2;
  413. unicodeData = IsmGetMemory (dataSize);
  414. if (unicodeData) {
  415. ZeroMemory (unicodeData, dataSize);
  416. DirectDbcsToUnicodeN (
  417. unicodeData,
  418. VariableData->EnvString,
  419. SizeOfStringA (VariableData->EnvString)
  420. );
  421. dataSize = SizeOfStringW (unicodeData);
  422. dataPtr = unicodeData;
  423. } else {
  424. dataSize = sizeof (WCHAR);
  425. dataPtr = L"";
  426. }
  427. #endif
  428. }
  429. } else if (VariableData->Type == ENVENTRY_MULTISZ) {
  430. if (VariableData->MultiSz == NULL) {
  431. dataSize = sizeof (TCHAR);
  432. dataPtr = TEXT("");
  433. } else {
  434. #ifdef UNICODE
  435. dataSize = SizeOfMultiSzW (VariableData->MultiSz);
  436. dataPtr = VariableData->MultiSz;
  437. #else
  438. dataSize = SizeOfMultiSzA (VariableData->MultiSz) * 2;
  439. unicodeData = IsmGetMemory (dataSize);
  440. if (unicodeData) {
  441. ZeroMemory (unicodeData, dataSize);
  442. DirectDbcsToUnicodeN (
  443. unicodeData,
  444. VariableData->MultiSz,
  445. SizeOfMultiSzA (VariableData->MultiSz)
  446. );
  447. dataSize = SizeOfMultiSzW (unicodeData);
  448. dataPtr = unicodeData;
  449. } else {
  450. dataSize = sizeof (WCHAR);
  451. dataPtr = L"";
  452. }
  453. #endif
  454. }
  455. } else if (VariableData->Type == ENVENTRY_CALLBACK) {
  456. dataSize = sizeof (PENVENTRYCALLBACK);
  457. dataPtr = (&VariableData->EnvCallback);
  458. } else if (VariableData->Type == ENVENTRY_BINARY) {
  459. dataSize = VariableData->EnvBinaryDataSize;
  460. dataPtr = VariableData->EnvBinaryData;
  461. } else {
  462. DEBUGMSG ((DBG_ERROR, "Invalid variable data type"));
  463. SetLastError (ERROR_INVALID_PARAMETER);
  464. __leave;
  465. }
  466. envEntry = (PENVIRONMENT_ENTRY) MemAllocUninit (sizeof (ENVIRONMENT_ENTRY) + dataSize);
  467. envEntry->Type = VariableData->Type;
  468. envEntry->DataSize = dataSize;
  469. if (envEntry->DataSize) {
  470. CopyMemory (envEntry->Data, dataPtr, envEntry->DataSize);
  471. }
  472. dh = MemDbSetUnorderedBlob (memdbName, 0, (PBYTE) envEntry, sizeof (ENVIRONMENT_ENTRY) + envEntry->DataSize);
  473. result = (dh != 0);
  474. if (!result) {
  475. EngineError ();
  476. }
  477. }
  478. __finally {
  479. if (memdbName) {
  480. FreePathString (memdbName);
  481. memdbName = NULL;
  482. }
  483. if (envEntry) {
  484. FreeAlloc (envEntry);
  485. envEntry = NULL;
  486. }
  487. #ifndef UNICODE
  488. if (unicodeData) {
  489. IsmReleaseMemory (unicodeData);
  490. unicodeData = NULL;
  491. }
  492. #endif
  493. }
  494. return result;
  495. }
  496. BOOL
  497. IsmSetEnvironmentString (
  498. IN MIG_PLATFORMTYPEID Platform,
  499. IN PCTSTR Group, OPTIONAL
  500. IN PCTSTR VariableName,
  501. IN PCTSTR VariableValue
  502. )
  503. {
  504. ENVENTRY_STRUCT envEntry;
  505. envEntry.Type = ENVENTRY_STRING;
  506. envEntry.EnvString = VariableValue;
  507. return IsmSetEnvironmentValue (
  508. Platform,
  509. Group,
  510. VariableName,
  511. &envEntry
  512. );
  513. }
  514. BOOL
  515. IsmSetEnvironmentMultiSz (
  516. IN MIG_PLATFORMTYPEID Platform,
  517. IN PCTSTR Group, OPTIONAL
  518. IN PCTSTR VariableName,
  519. IN PCTSTR VariableValue
  520. )
  521. {
  522. ENVENTRY_STRUCT envEntry;
  523. envEntry.Type = ENVENTRY_MULTISZ;
  524. envEntry.MultiSz = VariableValue;
  525. return IsmSetEnvironmentValue (
  526. Platform,
  527. Group,
  528. VariableName,
  529. &envEntry
  530. );
  531. }
  532. BOOL
  533. IsmAppendEnvironmentString (
  534. IN MIG_PLATFORMTYPEID Platform,
  535. IN PCTSTR Group, OPTIONAL
  536. IN PCTSTR VariableName,
  537. IN PCTSTR VariableValue
  538. )
  539. {
  540. ENVENTRY_STRUCT envEntry;
  541. ENVENTRY_TYPE type;
  542. KEYHANDLE kh = 0;
  543. UINT multiSzNeeded;
  544. if (pGetEnvironmentValue (
  545. Platform,
  546. &kh,
  547. Group,
  548. VariableName,
  549. NULL,
  550. 0,
  551. &multiSzNeeded,
  552. &type
  553. )) {
  554. if (type != ENVENTRY_MULTISZ) {
  555. return FALSE;
  556. }
  557. g_AppendBuffer.End = 0;
  558. GbGrow (&g_AppendBuffer, multiSzNeeded);
  559. if (pGetEnvironmentValue (
  560. Platform,
  561. &kh,
  562. Group,
  563. VariableName,
  564. g_AppendBuffer.Buf,
  565. multiSzNeeded,
  566. NULL,
  567. NULL
  568. )) {
  569. if (g_AppendBuffer.End) {
  570. g_AppendBuffer.End -= sizeof (TCHAR);
  571. }
  572. GbMultiSzAppend (&g_AppendBuffer, VariableValue);
  573. envEntry.Type = ENVENTRY_MULTISZ;
  574. envEntry.MultiSz = (PCTSTR) g_AppendBuffer.Buf;
  575. return IsmSetEnvironmentValue (
  576. Platform,
  577. Group,
  578. VariableName,
  579. &envEntry
  580. );
  581. }
  582. } else {
  583. g_AppendBuffer.End = 0;
  584. GbMultiSzAppend (&g_AppendBuffer, VariableValue);
  585. envEntry.Type = ENVENTRY_MULTISZ;
  586. envEntry.MultiSz = (PCTSTR) g_AppendBuffer.Buf;
  587. return IsmSetEnvironmentValue (
  588. Platform,
  589. Group,
  590. VariableName,
  591. &envEntry
  592. );
  593. }
  594. return FALSE;
  595. }
  596. BOOL
  597. IsmAppendEnvironmentMultiSz (
  598. IN MIG_PLATFORMTYPEID Platform,
  599. IN PCTSTR Group, OPTIONAL
  600. IN PCTSTR VariableName,
  601. IN PCTSTR VariableValue
  602. )
  603. {
  604. ENVENTRY_STRUCT envEntry;
  605. ENVENTRY_TYPE type;
  606. KEYHANDLE kh = 0;
  607. UINT multiSzNeeded;
  608. MULTISZ_ENUM multiSzEnum;
  609. if (pGetEnvironmentValue (
  610. Platform,
  611. &kh,
  612. Group,
  613. VariableName,
  614. NULL,
  615. 0,
  616. &multiSzNeeded,
  617. &type
  618. )) {
  619. if (type != ENVENTRY_MULTISZ) {
  620. return FALSE;
  621. }
  622. g_AppendBuffer.End = 0;
  623. GbGrow (&g_AppendBuffer, multiSzNeeded);
  624. if (pGetEnvironmentValue (
  625. Platform,
  626. &kh,
  627. Group,
  628. VariableName,
  629. g_AppendBuffer.Buf,
  630. multiSzNeeded,
  631. NULL,
  632. NULL
  633. )) {
  634. if (g_AppendBuffer.End) {
  635. g_AppendBuffer.End -= sizeof (TCHAR);
  636. }
  637. if (EnumFirstMultiSz (&multiSzEnum, VariableValue)) {
  638. do {
  639. GbMultiSzAppend (&g_AppendBuffer, multiSzEnum.CurrentString);
  640. } while (EnumNextMultiSz (&multiSzEnum));
  641. }
  642. envEntry.Type = ENVENTRY_MULTISZ;
  643. envEntry.MultiSz = (PCTSTR) g_AppendBuffer.Buf;
  644. return IsmSetEnvironmentValue (
  645. Platform,
  646. Group,
  647. VariableName,
  648. &envEntry
  649. );
  650. }
  651. } else {
  652. envEntry.Type = ENVENTRY_MULTISZ;
  653. envEntry.MultiSz = VariableValue;
  654. return IsmSetEnvironmentValue (
  655. Platform,
  656. Group,
  657. VariableName,
  658. &envEntry
  659. );
  660. }
  661. return FALSE;
  662. }
  663. BOOL
  664. IsmSetEnvironmentCallback (
  665. IN MIG_PLATFORMTYPEID Platform,
  666. IN PCTSTR Group, OPTIONAL
  667. IN PCTSTR VariableName,
  668. IN PENVENTRYCALLBACK VariableCallback
  669. )
  670. {
  671. ENVENTRY_STRUCT envEntry;
  672. envEntry.Type = ENVENTRY_CALLBACK;
  673. envEntry.EnvCallback = VariableCallback;
  674. return IsmSetEnvironmentValue (
  675. Platform,
  676. Group,
  677. VariableName,
  678. &envEntry
  679. );
  680. }
  681. BOOL
  682. IsmSetEnvironmentData (
  683. IN MIG_PLATFORMTYPEID Platform,
  684. IN PCTSTR Group, OPTIONAL
  685. IN PCTSTR VariableName,
  686. IN PCBYTE VariableData,
  687. IN UINT VariableDataSize
  688. )
  689. {
  690. ENVENTRY_STRUCT envEntry;
  691. envEntry.Type = ENVENTRY_BINARY;
  692. envEntry.EnvBinaryData = VariableData;
  693. envEntry.EnvBinaryDataSize = VariableDataSize;
  694. return IsmSetEnvironmentValue (
  695. Platform,
  696. Group,
  697. VariableName,
  698. &envEntry
  699. );
  700. }
  701. BOOL
  702. IsmSetEnvironmentFlag (
  703. IN MIG_PLATFORMTYPEID Platform,
  704. IN PCTSTR Group, OPTIONAL
  705. IN PCTSTR VariableName
  706. )
  707. {
  708. ENVENTRY_STRUCT envEntry;
  709. envEntry.Type = ENVENTRY_BINARY;
  710. envEntry.EnvBinaryData = NULL;
  711. envEntry.EnvBinaryDataSize = 0;
  712. return IsmSetEnvironmentValue (
  713. Platform,
  714. Group,
  715. VariableName,
  716. &envEntry
  717. );
  718. }
  719. BOOL
  720. pGetEnvironmentValue (
  721. IN MIG_PLATFORMTYPEID Platform,
  722. IN OUT KEYHANDLE *KeyHandle, OPTIONAL
  723. IN PCTSTR Group, OPTIONAL
  724. IN PCTSTR VariableName,
  725. OUT PBYTE Data, OPTIONAL
  726. IN UINT DataSize,
  727. OUT PUINT DataSizeNeeded, OPTIONAL
  728. OUT PENVENTRY_TYPE DataType OPTIONAL
  729. )
  730. {
  731. PCTSTR memdbName = NULL;
  732. BOOL result = FALSE;
  733. KEYHANDLE kh = 0;
  734. PENVIRONMENT_ENTRY envEntry;
  735. UINT sizeNeeded;
  736. GROWBUFFER tempBuffer = INIT_GROWBUFFER;
  737. BOOL destPlatform = FALSE;
  738. UINT dataSize;
  739. #ifndef UNICODE
  740. PSTR ansiData = NULL;
  741. #endif
  742. if ((Platform != PLATFORM_SOURCE) &&
  743. (Platform != PLATFORM_DESTINATION)
  744. ) {
  745. DEBUGMSG ((DBG_ERROR, "Environment variable specified with no platform."));
  746. return FALSE;
  747. }
  748. destPlatform = (Platform == PLATFORM_DESTINATION);
  749. __try {
  750. //
  751. // IsmGetEnvironmentValue will call this worker with KeyHandle set to NULL, but
  752. // IsmGetEnvironmentString will call this worker with a valid KeyHandle. This
  753. // is done to eliminate double-validation and double-lookup of the memdb key.
  754. //
  755. if (!KeyHandle || !(*KeyHandle)) {
  756. //
  757. // Validate arguments
  758. //
  759. if (!VariableName || !(*VariableName)) {
  760. DEBUGMSG ((DBG_ERROR, "Can't get value of invalid variable name"));
  761. SetLastError (ERROR_INVALID_PARAMETER);
  762. __leave;
  763. }
  764. memdbName = JoinPathsInPoolEx ((
  765. NULL,
  766. destPlatform?S_MEMDB_ENV_ROOT_DEST:S_MEMDB_ENV_ROOT_SRC,
  767. Group?Group:VariableName,
  768. Group?VariableName:NULL,
  769. NULL
  770. ));
  771. kh = MemDbGetHandleFromKey (memdbName);
  772. if (KeyHandle) {
  773. *KeyHandle = kh;
  774. }
  775. } else {
  776. kh = *KeyHandle;
  777. }
  778. //
  779. // If no variable exists, return FALSE
  780. //
  781. if (!kh) {
  782. SetLastError (ERROR_SUCCESS);
  783. __leave;
  784. }
  785. //
  786. // Otherwise get the binary data
  787. //
  788. envEntry = NULL;
  789. if (!MemDbGetUnorderedBlobByKeyHandleEx (kh, 0, &tempBuffer, &sizeNeeded)) {
  790. //
  791. // No variable exists, return FALSE
  792. //
  793. if (DataSizeNeeded) {
  794. *DataSizeNeeded = 0;
  795. }
  796. if (DataType) {
  797. *DataType = ENVENTRY_NONE;
  798. }
  799. SetLastError (ERROR_SUCCESS);
  800. __leave;
  801. }
  802. envEntry = (PENVIRONMENT_ENTRY) tempBuffer.Buf;
  803. if (DataType) {
  804. *DataType = envEntry->Type;
  805. }
  806. #ifdef UNICODE
  807. if (DataSizeNeeded) {
  808. *DataSizeNeeded = envEntry->DataSize;
  809. }
  810. if (DataSize) {
  811. if (DataSize < envEntry->DataSize) {
  812. SetLastError (ERROR_INSUFFICIENT_BUFFER);
  813. } else {
  814. CopyMemory (Data, envEntry->Data, envEntry->DataSize);
  815. }
  816. }
  817. #else
  818. if (envEntry->Type == ENVENTRY_STRING) {
  819. dataSize = SizeOfStringW ((PCWSTR)envEntry->Data);
  820. ansiData = IsmGetMemory (dataSize);
  821. if (ansiData) {
  822. ZeroMemory (ansiData, dataSize);
  823. DirectUnicodeToDbcsN (
  824. ansiData,
  825. (PWSTR)envEntry->Data,
  826. SizeOfStringW ((PCWSTR)envEntry->Data)
  827. );
  828. dataSize = SizeOfStringA (ansiData);
  829. if (DataSizeNeeded) {
  830. *DataSizeNeeded = dataSize;
  831. }
  832. if (DataSize) {
  833. if (DataSize < dataSize) {
  834. SetLastError (ERROR_INSUFFICIENT_BUFFER);
  835. } else {
  836. CopyMemory (Data, ansiData, dataSize);
  837. }
  838. }
  839. IsmReleaseMemory (ansiData);
  840. ansiData = NULL;
  841. }
  842. } else if (envEntry->Type == ENVENTRY_MULTISZ) {
  843. dataSize = SizeOfMultiSzW ((PCWSTR)envEntry->Data);
  844. ansiData = IsmGetMemory (dataSize);
  845. if (ansiData) {
  846. ZeroMemory (ansiData, dataSize);
  847. DirectUnicodeToDbcsN (
  848. ansiData,
  849. (PWSTR)envEntry->Data,
  850. SizeOfMultiSzW ((PCWSTR)envEntry->Data)
  851. );
  852. dataSize = SizeOfMultiSzA (ansiData);
  853. if (DataSizeNeeded) {
  854. *DataSizeNeeded = dataSize;
  855. }
  856. if (DataSize) {
  857. if (DataSize < dataSize) {
  858. SetLastError (ERROR_INSUFFICIENT_BUFFER);
  859. } else {
  860. CopyMemory (Data, ansiData, dataSize);
  861. }
  862. }
  863. IsmReleaseMemory (ansiData);
  864. ansiData = NULL;
  865. }
  866. } else {
  867. if (DataSizeNeeded) {
  868. *DataSizeNeeded = envEntry->DataSize;
  869. }
  870. if (DataSize) {
  871. if (DataSize < envEntry->DataSize) {
  872. SetLastError (ERROR_INSUFFICIENT_BUFFER);
  873. } else {
  874. CopyMemory (Data, envEntry->Data, envEntry->DataSize);
  875. }
  876. }
  877. }
  878. #endif
  879. result = TRUE;
  880. }
  881. __finally {
  882. if (memdbName) {
  883. FreePathString (memdbName);
  884. memdbName = NULL;
  885. }
  886. GbFree (&tempBuffer);
  887. }
  888. return result;
  889. }
  890. BOOL
  891. IsmGetEnvironmentValue (
  892. IN MIG_PLATFORMTYPEID Platform,
  893. IN PCTSTR Group, OPTIONAL
  894. IN PCTSTR VariableName,
  895. OUT PBYTE Data, OPTIONAL
  896. IN UINT DataSize,
  897. OUT PUINT DataSizeNeeded, OPTIONAL
  898. OUT PENVENTRY_TYPE DataType OPTIONAL
  899. )
  900. {
  901. return pGetEnvironmentValue (
  902. Platform,
  903. NULL,
  904. Group,
  905. VariableName,
  906. Data,
  907. DataSize,
  908. DataSizeNeeded,
  909. DataType
  910. );
  911. }
  912. BOOL
  913. IsmGetEnvironmentString (
  914. IN MIG_PLATFORMTYPEID Platform,
  915. IN PCTSTR Group, OPTIONAL
  916. IN PCTSTR VariableName,
  917. OUT PTSTR VariableValue, OPTIONAL
  918. IN UINT DataSize,
  919. OUT PUINT DataSizeNeeded OPTIONAL
  920. )
  921. {
  922. KEYHANDLE kh = 0;
  923. ENVENTRY_TYPE type;
  924. if (pGetEnvironmentValue (
  925. Platform,
  926. &kh,
  927. Group,
  928. VariableName,
  929. NULL,
  930. 0,
  931. NULL,
  932. &type
  933. )) {
  934. if (type != ENVENTRY_STRING) {
  935. return FALSE;
  936. }
  937. if (pGetEnvironmentValue (
  938. Platform,
  939. &kh,
  940. Group,
  941. VariableName,
  942. (PBYTE) VariableValue,
  943. DataSize,
  944. DataSizeNeeded,
  945. NULL
  946. )) {
  947. return TRUE;
  948. }
  949. }
  950. return FALSE;
  951. }
  952. BOOL
  953. IsmGetEnvironmentMultiSz (
  954. IN MIG_PLATFORMTYPEID Platform,
  955. IN PCTSTR Group, OPTIONAL
  956. IN PCTSTR VariableName,
  957. OUT PTSTR VariableValue, OPTIONAL
  958. IN UINT DataSize,
  959. OUT PUINT DataSizeNeeded OPTIONAL
  960. )
  961. {
  962. KEYHANDLE kh = 0;
  963. ENVENTRY_TYPE type;
  964. if (pGetEnvironmentValue (
  965. Platform,
  966. &kh,
  967. Group,
  968. VariableName,
  969. NULL,
  970. 0,
  971. NULL,
  972. &type
  973. )) {
  974. if (type != ENVENTRY_MULTISZ) {
  975. return FALSE;
  976. }
  977. if (pGetEnvironmentValue (
  978. Platform,
  979. &kh,
  980. Group,
  981. VariableName,
  982. (PBYTE) VariableValue,
  983. DataSize,
  984. DataSizeNeeded,
  985. NULL
  986. )) {
  987. return TRUE;
  988. }
  989. }
  990. return FALSE;
  991. }
  992. BOOL
  993. IsmGetEnvironmentCallback (
  994. IN MIG_PLATFORMTYPEID Platform,
  995. IN PCTSTR Group, OPTIONAL
  996. IN PCTSTR VariableName,
  997. OUT PENVENTRYCALLBACK *VariableCallback OPTIONAL
  998. )
  999. {
  1000. KEYHANDLE kh = 0;
  1001. ENVENTRY_TYPE type;
  1002. if (pGetEnvironmentValue (
  1003. Platform,
  1004. &kh,
  1005. Group,
  1006. VariableName,
  1007. NULL,
  1008. 0,
  1009. NULL,
  1010. &type
  1011. )) {
  1012. if (type != ENVENTRY_CALLBACK) {
  1013. return FALSE;
  1014. }
  1015. if (pGetEnvironmentValue (
  1016. Platform,
  1017. &kh,
  1018. Group,
  1019. VariableName,
  1020. (PBYTE)VariableCallback,
  1021. sizeof (PENVENTRYCALLBACK),
  1022. NULL,
  1023. NULL
  1024. )) {
  1025. return TRUE;
  1026. }
  1027. }
  1028. return FALSE;
  1029. }
  1030. BOOL
  1031. IsmGetEnvironmentData (
  1032. IN MIG_PLATFORMTYPEID Platform,
  1033. IN PCTSTR Group, OPTIONAL
  1034. IN PCTSTR VariableName,
  1035. OUT PBYTE VariableData, OPTIONAL
  1036. IN UINT DataSize,
  1037. OUT PUINT DataSizeNeeded OPTIONAL
  1038. )
  1039. {
  1040. KEYHANDLE kh = 0;
  1041. ENVENTRY_TYPE type;
  1042. if (pGetEnvironmentValue (
  1043. Platform,
  1044. &kh,
  1045. Group,
  1046. VariableName,
  1047. NULL,
  1048. 0,
  1049. NULL,
  1050. &type
  1051. )) {
  1052. if (type != ENVENTRY_BINARY) {
  1053. return FALSE;
  1054. }
  1055. if (pGetEnvironmentValue (
  1056. Platform,
  1057. &kh,
  1058. Group,
  1059. VariableName,
  1060. VariableData,
  1061. DataSize,
  1062. DataSizeNeeded,
  1063. NULL
  1064. )) {
  1065. return TRUE;
  1066. }
  1067. }
  1068. return FALSE;
  1069. }
  1070. BOOL
  1071. IsmIsEnvironmentFlagSet (
  1072. IN MIG_PLATFORMTYPEID Platform,
  1073. IN PCTSTR Group, OPTIONAL
  1074. IN PCTSTR VariableName
  1075. )
  1076. {
  1077. KEYHANDLE kh = 0;
  1078. if (pGetEnvironmentValue (
  1079. Platform,
  1080. &kh,
  1081. Group,
  1082. VariableName,
  1083. NULL,
  1084. 0,
  1085. NULL,
  1086. NULL
  1087. )) {
  1088. return TRUE;
  1089. }
  1090. return FALSE;
  1091. }
  1092. BOOL
  1093. IsmDeleteEnvironmentVariable (
  1094. IN MIG_PLATFORMTYPEID Platform,
  1095. IN PCTSTR Group, OPTIONAL
  1096. IN PCTSTR VariableName
  1097. )
  1098. {
  1099. BOOL result = FALSE;
  1100. PCTSTR memdbName = NULL;
  1101. BOOL destPlatform = FALSE;
  1102. if ((Platform != PLATFORM_SOURCE) &&
  1103. (Platform != PLATFORM_DESTINATION)
  1104. ) {
  1105. DEBUGMSG ((DBG_ERROR, "Environment variable specified with no platform."));
  1106. return FALSE;
  1107. }
  1108. destPlatform = (Platform == PLATFORM_DESTINATION);
  1109. __try {
  1110. //
  1111. // Validate arguments
  1112. //
  1113. if (!(*VariableName)) {
  1114. DEBUGMSG ((DBG_ERROR, "Invalid variable name"));
  1115. SetLastError (ERROR_INVALID_PARAMETER);
  1116. __leave;
  1117. }
  1118. //
  1119. // Build decorated name by joining current group with variable name,
  1120. // then build memdb key
  1121. //
  1122. memdbName = JoinPathsInPoolEx ((
  1123. NULL,
  1124. destPlatform?S_MEMDB_ENV_ROOT_DEST:S_MEMDB_ENV_ROOT_SRC,
  1125. Group?Group:VariableName,
  1126. Group?VariableName:NULL,
  1127. NULL
  1128. ));
  1129. //
  1130. // Now delete the memdb key
  1131. //
  1132. result = MemDbDeleteKey (memdbName);
  1133. }
  1134. __finally {
  1135. if (memdbName) {
  1136. FreePathString (memdbName);
  1137. memdbName = NULL;
  1138. }
  1139. }
  1140. return result;
  1141. }
  1142. BOOL
  1143. pGetEnvironmentString (
  1144. IN MIG_PLATFORMTYPEID Platform,
  1145. IN PCTSTR Group, OPTIONAL
  1146. IN PCTSTR EnvString,
  1147. OUT PTSTR EnvValue, OPTIONAL
  1148. IN UINT EnvValueSize,
  1149. OUT PUINT EnvValueSizeNeeded, OPTIONAL
  1150. IN PCTSTR EnvStringContext OPTIONAL
  1151. )
  1152. {
  1153. KEYHANDLE kh = 0;
  1154. ENVENTRY_TYPE type;
  1155. PENVENTRYCALLBACK callback = NULL;
  1156. TCHAR buffer[1024];
  1157. UINT sizeNeeded;
  1158. if (pGetEnvironmentValue (
  1159. Platform,
  1160. &kh,
  1161. Group,
  1162. EnvString,
  1163. (PBYTE) buffer,
  1164. sizeof (buffer),
  1165. &sizeNeeded,
  1166. &type
  1167. )) {
  1168. if (type == ENVENTRY_STRING) {
  1169. if (!EnvValue) {
  1170. if (EnvValueSizeNeeded) {
  1171. *EnvValueSizeNeeded = sizeNeeded;
  1172. }
  1173. return TRUE;
  1174. }
  1175. if ((sizeNeeded <= sizeof (buffer)) && (sizeNeeded <= EnvValueSize)) {
  1176. StringCopy (EnvValue, buffer);
  1177. if (EnvValueSizeNeeded) {
  1178. *EnvValueSizeNeeded = sizeNeeded;
  1179. }
  1180. return TRUE;
  1181. }
  1182. return pGetEnvironmentValue (
  1183. Platform,
  1184. &kh,
  1185. Group,
  1186. EnvString,
  1187. (PBYTE)EnvValue,
  1188. EnvValueSize,
  1189. EnvValueSizeNeeded,
  1190. NULL
  1191. );
  1192. } else if (type == ENVENTRY_CALLBACK) {
  1193. if (sizeNeeded == sizeof (PENVENTRYCALLBACK)) {
  1194. callback = (PENVENTRYCALLBACK) buffer;
  1195. return callback (
  1196. EnvString,
  1197. EnvValue,
  1198. EnvValueSize,
  1199. EnvValueSizeNeeded,
  1200. EnvStringContext
  1201. );
  1202. }
  1203. }
  1204. return FALSE;
  1205. }
  1206. return FALSE;
  1207. }
  1208. PCTSTR
  1209. TrackedIsmExpandEnvironmentString (
  1210. IN MIG_PLATFORMTYPEID Platform,
  1211. IN PCTSTR Group, OPTIONAL
  1212. IN PCTSTR SrcString,
  1213. IN PCTSTR Context
  1214. TRACKING_DEF
  1215. )
  1216. {
  1217. UINT ch;
  1218. PTSTR strCopy;
  1219. PTSTR srcString;
  1220. PTSTR envBegin = NULL;
  1221. PTSTR envStrBegin;
  1222. PTSTR envEnd;
  1223. CHARTYPE savedCh;
  1224. BOOL envMode = FALSE;
  1225. UINT strSize;
  1226. UINT maxSize;
  1227. GROWBUFFER envBuff = INIT_GROWBUFFER;
  1228. PCTSTR result = NULL;
  1229. TRACK_ENTER();
  1230. strCopy = PmDuplicateString (g_IsmPool, SrcString);
  1231. srcString = strCopy;
  1232. while (*srcString) {
  1233. ch = _tcsnextc (srcString);
  1234. if (ch == TEXT('%')) {
  1235. if (envMode) {
  1236. envEnd = srcString;
  1237. envStrBegin = _tcsinc (envBegin);
  1238. savedCh = *envEnd;
  1239. *envEnd = 0;
  1240. maxSize = (UINT) ((envBuff.Size - envBuff.End) * sizeof (TCHAR));
  1241. if (pGetEnvironmentString (Platform, Group, envStrBegin, (PTSTR) (envBuff.Buf + envBuff.End), maxSize, &strSize, Context)) {
  1242. if (maxSize < strSize) {
  1243. pGetEnvironmentString (Platform, Group, envStrBegin, (PTSTR) GbGrow (&envBuff, strSize), strSize, &strSize, Context);
  1244. } else {
  1245. envBuff.End += strSize;
  1246. }
  1247. if (strSize) {
  1248. //we know that the routine above also adds the terminating null character
  1249. //so we need to pull it out.
  1250. envBuff.End -= sizeof (TCHAR);
  1251. }
  1252. *envEnd = (TCHAR) savedCh;
  1253. } else {
  1254. *envEnd = (TCHAR) savedCh;
  1255. envEnd = _tcsinc (envEnd);
  1256. strSize = (UINT) ((envEnd - envBegin) * sizeof (TCHAR));
  1257. CopyMemory (GbGrow (&envBuff, strSize), envBegin, strSize);
  1258. }
  1259. envMode = FALSE;
  1260. } else {
  1261. envBegin = srcString;
  1262. envMode = TRUE;
  1263. }
  1264. srcString = _tcsinc (srcString);
  1265. } else {
  1266. envEnd = _tcsinc (srcString);
  1267. if (!envMode) {
  1268. strSize = (UINT) ((envEnd - srcString) * sizeof (TCHAR));
  1269. CopyMemory (GbGrow (&envBuff, strSize), srcString, strSize);
  1270. }
  1271. srcString = envEnd;
  1272. }
  1273. }
  1274. if (envMode && envBegin) {
  1275. strSize = (UINT) ((srcString - envBegin) * sizeof (TCHAR));
  1276. CopyMemory (GbGrow (&envBuff, strSize), envBegin, strSize);
  1277. }
  1278. CopyMemory (GbGrow (&envBuff, sizeof (TCHAR)), srcString, sizeof (TCHAR));
  1279. PmReleaseMemory (g_IsmPool, strCopy);
  1280. result = PmDuplicateString (g_IsmPool, (PCTSTR) envBuff.Buf);
  1281. GbFree (&envBuff);
  1282. TRACK_LEAVE();
  1283. return result;
  1284. }
  1285. BOOL
  1286. pDoesEnvExistOnOtherPlatform (
  1287. IN PCTSTR Group,
  1288. IN PCTSTR VariableName,
  1289. IN MIG_PLATFORMTYPEID Platform
  1290. )
  1291. {
  1292. BOOL result = FALSE;
  1293. if (Platform == PLATFORM_SOURCE) {
  1294. Platform = PLATFORM_DESTINATION;
  1295. } else {
  1296. Platform = PLATFORM_SOURCE;
  1297. }
  1298. result = pGetEnvironmentValue (
  1299. Platform,
  1300. NULL,
  1301. Group,
  1302. VariableName,
  1303. NULL,
  1304. 0,
  1305. NULL,
  1306. NULL
  1307. );
  1308. return result;
  1309. }
  1310. PCTSTR
  1311. TrackedIsmCompressEnvironmentString (
  1312. IN MIG_PLATFORMTYPEID Platform,
  1313. IN PCTSTR Group, OPTIONAL
  1314. IN PCTSTR SrcString,
  1315. IN PCTSTR Context,
  1316. IN BOOL MustExistOnOtherPlatform
  1317. TRACKING_DEF
  1318. )
  1319. {
  1320. ENV_ENTRY_ENUM envEntryEnum;
  1321. PCTSTR pattern = NULL;
  1322. BOOL match = FALSE;
  1323. DWORD matchLen = 0;
  1324. DWORD matchLenTmp;
  1325. PCTSTR envWack = NULL;
  1326. PCTSTR varName = NULL;
  1327. PCTSTR varValue = NULL;
  1328. DWORD resultSize;
  1329. PTSTR result = NULL;
  1330. TRACK_ENTER();
  1331. // let's enumerate all environment variables
  1332. pattern = JoinPathsInPoolEx ((
  1333. NULL,
  1334. Group?Group:TEXT("*"),
  1335. Group?TEXT("*"):NULL,
  1336. NULL
  1337. ));
  1338. if (EnvEnumerateFirstEntry (
  1339. &envEntryEnum,
  1340. Platform,
  1341. pattern
  1342. )) {
  1343. do {
  1344. switch (envEntryEnum.EnvEntryType) {
  1345. case ENVENTRY_STRING:
  1346. match = FALSE;
  1347. if (StringIMatch (SrcString, (PCTSTR)envEntryEnum.EnvEntryData)) {
  1348. match = TRUE;
  1349. }
  1350. if (!match) {
  1351. envWack = JoinPaths (SrcString, TEXT("\\"));
  1352. if (envWack) {
  1353. if (StringIMatch (envWack, (PCTSTR)envEntryEnum.EnvEntryData)) {
  1354. match = TRUE;
  1355. }
  1356. FreePathString (envWack);
  1357. }
  1358. }
  1359. if (!match) {
  1360. envWack = JoinPaths ((PCTSTR)envEntryEnum.EnvEntryData, TEXT("\\"));
  1361. if (envWack) {
  1362. if (StringIPrefix (SrcString, envWack)) {
  1363. match = TRUE;
  1364. }
  1365. }
  1366. FreePathString (envWack);
  1367. }
  1368. if (match) {
  1369. // we have a match, let's see how big is the match and,
  1370. // if we need to, write down the env variable and its value
  1371. matchLenTmp = ByteCount ((PCTSTR)envEntryEnum.EnvEntryData);
  1372. if (matchLenTmp > matchLen) {
  1373. // Let's check if this env variable must exist on the other platform
  1374. if (!MustExistOnOtherPlatform ||
  1375. (pDoesEnvExistOnOtherPlatform (Group, envEntryEnum.EnvEntryName, Platform))
  1376. ) {
  1377. matchLen = matchLenTmp;
  1378. if (varName) {
  1379. IsmReleaseMemory (varName);
  1380. }
  1381. if (varValue) {
  1382. IsmReleaseMemory (varValue);
  1383. }
  1384. varName = IsmDuplicateString (envEntryEnum.EnvEntryName);
  1385. varValue = IsmDuplicateString ((PCTSTR)envEntryEnum.EnvEntryData);
  1386. }
  1387. }
  1388. }
  1389. break;
  1390. default:
  1391. break;
  1392. }
  1393. } while (EnvEnumerateNextEntry (&envEntryEnum));
  1394. }
  1395. if (matchLen && varName && varValue) {
  1396. resultSize = ByteCount (TEXT("%")) +
  1397. ByteCount (varName) +
  1398. ByteCount (TEXT("%")) +
  1399. ByteCount (SrcString) -
  1400. matchLen +
  1401. 2 * sizeof (TCHAR);
  1402. result = (PTSTR)IsmGetMemory (resultSize);
  1403. if (result) {
  1404. StringCopy (result, TEXT("%"));
  1405. StringCat (result, varName);
  1406. StringCat (result, TEXT("%"));
  1407. StringCat (result, (PCTSTR)((PBYTE)SrcString + matchLen));
  1408. }
  1409. }
  1410. TRACK_LEAVE();
  1411. return result;
  1412. }
  1413. BOOL
  1414. IsmSetTransportVariable (
  1415. IN MIG_PLATFORMTYPEID Platform,
  1416. IN PCTSTR Section,
  1417. IN PCTSTR Key,
  1418. IN PCTSTR KeyData
  1419. )
  1420. {
  1421. PCTSTR variable;
  1422. BOOL result = FALSE;
  1423. if (!Section || !Key || !KeyData) {
  1424. DEBUGMSG ((DBG_ERROR, "Section, key and key data are required for IsmSetTransportVariable"));
  1425. return FALSE;
  1426. }
  1427. variable = JoinPaths (Section, Key);
  1428. result = IsmSetEnvironmentString (Platform, S_TRANSPORT_PREFIX, variable, KeyData);
  1429. FreePathString (variable);
  1430. return result;
  1431. }
  1432. BOOL
  1433. IsmGetTransportVariable (
  1434. IN MIG_PLATFORMTYPEID Platform,
  1435. IN PCTSTR Section,
  1436. IN PCTSTR Key,
  1437. OUT PTSTR KeyData, OPTIONAL
  1438. IN UINT KeyDataBufferSizeInBytes
  1439. )
  1440. {
  1441. PCTSTR variable;
  1442. BOOL result = FALSE;
  1443. if (!Section || !Key) {
  1444. DEBUGMSG ((DBG_ERROR, "Section, key and key data are required for IsmSetTransportVariable"));
  1445. return FALSE;
  1446. }
  1447. variable = JoinPaths (Section, Key);
  1448. result = IsmGetEnvironmentString (
  1449. Platform,
  1450. S_TRANSPORT_PREFIX,
  1451. variable,
  1452. KeyData,
  1453. KeyDataBufferSizeInBytes,
  1454. NULL
  1455. );
  1456. FreePathString (variable);
  1457. return result;
  1458. }