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.

873 lines
26 KiB

  1. #include "stdafx.h"
  2. #include "RemoteEnv.h"
  3. typedef LONG NTSTATUS;
  4. #define MAX_ENV_VALUE_LEN 1024
  5. #define DEFAULT_ROOT_KEY HKEY_LOCAL_MACHINE
  6. #define REG_PATH_TO_SYSROOT TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion")
  7. #define REG_PATH_TO_COMMON_FOLDERS TEXT("Software\\Microsoft\\Windows\\CurrentVersion")
  8. #define REG_PATH_TO_ENV TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Environment")
  9. #define PATH_VARIABLE TEXT("Path")
  10. #define LIBPATH_VARIABLE TEXT("LibPath")
  11. #define OS2LIBPATH_VARIABLE TEXT("Os2LibPath")
  12. #define AUTOEXECPATH_VARIABLE TEXT("AutoexecPath")
  13. #define ENV_KEYWORD_SYSTEMROOT TEXT("SystemRoot")
  14. #define ENV_KEYWORD_PROGRAMFILESDIR TEXT("ProgramFilesDir")
  15. #define ENV_KEYWORD_COMMONFILESDIR TEXT("CommonFilesDir")
  16. #define ENV_KEYWORD_PROGRAMFILESDIR_X86 TEXT("ProgramFilesDir (x86)")
  17. #define ENV_KEYWORD_COMMONFILESDIR_X86 TEXT("CommonFilesDir (x86)")
  18. #define PROGRAMFILES_VARIABLE TEXT("ProgramFiles")
  19. #define COMMONPROGRAMFILES_VARIABLE TEXT("CommonProgramFiles")
  20. #define PROGRAMFILESX86_VARIABLE TEXT("ProgramFiles(x86)")
  21. #define COMMONPROGRAMFILESX86_VARIABLE TEXT("CommonProgramFiles(x86)")
  22. CRemoteExpandEnvironmentStrings::CRemoteExpandEnvironmentStrings()
  23. {
  24. m_pEnvironment = NULL;
  25. m_lpszUncServerName = NULL;
  26. return;
  27. }
  28. CRemoteExpandEnvironmentStrings::~CRemoteExpandEnvironmentStrings()
  29. {
  30. DeleteRemoteEnvironment();
  31. if (m_lpszUncServerName)
  32. {
  33. LocalFree(m_lpszUncServerName);
  34. m_lpszUncServerName = NULL;
  35. }
  36. return;
  37. }
  38. BOOL
  39. CRemoteExpandEnvironmentStrings::NewRemoteEnvironment()
  40. {
  41. BOOL bReturn = FALSE;
  42. // already have a cached one, use that...
  43. if (m_pEnvironment)
  44. {
  45. bReturn = TRUE;
  46. }
  47. else
  48. {
  49. //
  50. // Create a temporary environment, which we'll fill in and let RTL
  51. // routines do the expansion for us.
  52. //
  53. if ( !NT_SUCCESS(RtlCreateEnvironment((BOOLEAN) FALSE,&m_pEnvironment)) )
  54. {
  55. bReturn = FALSE;
  56. goto NewRemoteEnvironment_Exit;
  57. }
  58. SetOtherEnvironmentValues(&m_pEnvironment);
  59. SetEnvironmentVariables(&m_pEnvironment);
  60. bReturn = TRUE;
  61. }
  62. NewRemoteEnvironment_Exit:
  63. return bReturn;
  64. }
  65. void
  66. CRemoteExpandEnvironmentStrings::DeleteRemoteEnvironment()
  67. {
  68. if (m_pEnvironment != NULL)
  69. {
  70. RtlDestroyEnvironment(m_pEnvironment);
  71. m_pEnvironment = NULL;
  72. }
  73. return;
  74. }
  75. BOOL CRemoteExpandEnvironmentStrings::IsLocalMachine(LPCTSTR psz)
  76. {
  77. CString szLocal;
  78. DWORD cch = MAX_COMPUTERNAME_LENGTH + 1;
  79. BOOL bAnswer;
  80. if (_tcsicmp(psz,_T("")) == 0)
  81. {
  82. // it's empty,
  83. // yeah it's local machine
  84. return TRUE;
  85. }
  86. // get the actual name of the local machine
  87. bAnswer = GetComputerName(szLocal.GetBuffer(cch), &cch);
  88. szLocal.ReleaseBuffer();
  89. if ( !bAnswer )
  90. return FALSE;
  91. // compare and return
  92. bAnswer = (szLocal.CompareNoCase( psz ) == 0);
  93. return bAnswer;
  94. }
  95. BOOL
  96. CRemoteExpandEnvironmentStrings::SetMachineName(IN LPCTSTR szMachineName)
  97. {
  98. BOOL bReturn = FALSE;
  99. DWORD dwSize = 0;
  100. LPTSTR lpszUncServerNameOriginal = NULL;
  101. // free any previous thing we had...
  102. if (m_lpszUncServerName)
  103. {
  104. // Make a copy of it before we delete it
  105. dwSize = (_tcslen(m_lpszUncServerName) + 1) * sizeof(TCHAR);
  106. lpszUncServerNameOriginal = (LPTSTR) LocalAlloc(LMEM_ZEROINIT,dwSize);
  107. if (lpszUncServerNameOriginal)
  108. {
  109. _tcscpy(lpszUncServerNameOriginal, m_lpszUncServerName);
  110. }
  111. // free up anything we had before
  112. LocalFree(m_lpszUncServerName);
  113. m_lpszUncServerName = NULL;
  114. }
  115. if (_tcsicmp(szMachineName,_T("")) == 0)
  116. {
  117. bReturn = TRUE;
  118. goto CRemoteExpandEnvironmentStrings_Exit;
  119. }
  120. // if it's the localmachine name
  121. // then set it to NULL
  122. // so that it will be treated as localmachine.
  123. if (IsLocalMachine(szMachineName))
  124. {
  125. m_lpszUncServerName = NULL;
  126. bReturn = TRUE;
  127. goto CRemoteExpandEnvironmentStrings_Exit;
  128. }
  129. dwSize = (_tcslen(szMachineName) + 1 + 2) * sizeof(TCHAR);
  130. m_lpszUncServerName = (LPTSTR) LocalAlloc(LMEM_ZEROINIT,dwSize);
  131. if (m_lpszUncServerName)
  132. {
  133. // check if szMachineName already starts with "\\"
  134. if (szMachineName[0] == _T('\\') && szMachineName[1] == _T('\\'))
  135. {
  136. _tcscpy(m_lpszUncServerName, szMachineName);
  137. }
  138. else
  139. {
  140. _tcscpy(m_lpszUncServerName, _T("\\\\"));
  141. _tcscat(m_lpszUncServerName, szMachineName);
  142. }
  143. bReturn = TRUE;
  144. }
  145. // if the machine name is different from what it was before
  146. // then delete the current environment if any...
  147. if (m_lpszUncServerName && lpszUncServerNameOriginal)
  148. {
  149. if (0 != _tcsicmp(lpszUncServerNameOriginal,m_lpszUncServerName))
  150. {
  151. DeleteRemoteEnvironment();
  152. }
  153. }
  154. else
  155. {
  156. DeleteRemoteEnvironment();
  157. }
  158. CRemoteExpandEnvironmentStrings_Exit:
  159. if (lpszUncServerNameOriginal)
  160. {LocalFree(lpszUncServerNameOriginal);lpszUncServerNameOriginal=NULL;}
  161. return bReturn;
  162. }
  163. DWORD
  164. CRemoteExpandEnvironmentStrings::GetRegKeyMaxSizes(
  165. IN HKEY WinRegHandle,
  166. OUT LPDWORD MaxKeywordSize OPTIONAL,
  167. OUT LPDWORD MaxValueSize OPTIONAL
  168. )
  169. {
  170. LONG Error;
  171. DWORD MaxValueNameLength;
  172. DWORD MaxValueDataLength;
  173. Error = RegQueryInfoKey(
  174. WinRegHandle,
  175. NULL,
  176. NULL,
  177. NULL,
  178. NULL,
  179. NULL,
  180. NULL,
  181. NULL,
  182. &MaxValueNameLength,
  183. &MaxValueDataLength,
  184. NULL,
  185. NULL
  186. );
  187. if (ERROR_SUCCESS == Error)
  188. {
  189. //
  190. // MaxValueNameLength is a count of TCHARs.
  191. // MaxValueDataLength is a count of bytes already.
  192. //
  193. MaxValueNameLength = (MaxValueNameLength + 1) * sizeof(TCHAR);
  194. if (MaxKeywordSize)
  195. {
  196. *MaxKeywordSize = MaxValueNameLength;
  197. }
  198. if (MaxValueSize)
  199. {
  200. *MaxValueSize = MaxValueDataLength;
  201. }
  202. }
  203. return (Error);
  204. }
  205. NET_API_STATUS
  206. CRemoteExpandEnvironmentStrings::RemoteExpandEnvironmentStrings(
  207. IN LPCTSTR UnexpandedString,
  208. OUT LPTSTR * ValueBufferPtr // Must be freed by LocalFree().
  209. )
  210. /*++
  211. Routine Description:
  212. This function expands a value string (which may include references to
  213. environment variables). For instance, an unexpanded string might be:
  214. %SystemRoot%\System32\Repl\Export
  215. This could be expanded to:
  216. c:\nt\System32\Repl\Export
  217. The expansion makes use of environment variables on m_lpszUncServerName,
  218. if given. This allows remote administration of the directory
  219. replicator.
  220. Arguments:
  221. m_lpszUncServerName - assumed to NOT BE EXPLICIT LOCAL SERVER NAME.
  222. UnexpandedString - points to source string to be expanded.
  223. ValueBufferPtr - indicates a pointer which will be set by this routine.
  224. This routine will allocate memory for a null-terminated string.
  225. The caller must free this with LocalFree() or equivalent.
  226. Return Value:
  227. NET_API_STATUS
  228. --*/
  229. {
  230. NET_API_STATUS ApiStatus = NO_ERROR;
  231. LPTSTR ExpandedString = NULL;
  232. DWORD LastAllocationSize = 0;
  233. NTSTATUS NtStatus;
  234. //
  235. // Check for caller errors.
  236. //
  237. if (ValueBufferPtr == NULL) {
  238. // Can't goto Cleanup here, as it assumes this pointer is valid
  239. return (ERROR_INVALID_PARAMETER);
  240. }
  241. *ValueBufferPtr = NULL; // assume error until proven otherwise.
  242. if (UnexpandedString == NULL)
  243. {
  244. ApiStatus = ERROR_INVALID_PARAMETER;
  245. goto Cleanup;
  246. }
  247. //
  248. // This is probably just a constant string.
  249. //
  250. if (wcschr( UnexpandedString, _T('%') ) == NULL)
  251. {
  252. // Just need to allocate a copy of the input string.
  253. DWORD dwSize = (_tcslen(UnexpandedString) + 1) * sizeof(TCHAR);
  254. ExpandedString = (LPTSTR) LocalAlloc(LMEM_ZEROINIT,dwSize);
  255. if (ExpandedString == NULL)
  256. {
  257. ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
  258. goto Cleanup;
  259. }
  260. else
  261. {
  262. RtlCopyMemory(ExpandedString, UnexpandedString, dwSize);
  263. }
  264. // That's all, folks!
  265. ApiStatus = NO_ERROR;
  266. //
  267. // Otherwise, is this local? Maybe we can
  268. // handle local expansion the easy (fast) way: using win32 API.
  269. //
  270. }
  271. else if (m_lpszUncServerName == NULL)
  272. {
  273. DWORD CharsRequired = wcslen(UnexpandedString)+1;
  274. do {
  275. // Clean up from previous pass.
  276. if (ExpandedString){LocalFree(ExpandedString);ExpandedString = NULL;}
  277. // Allocate the memory.
  278. ExpandedString = (LPTSTR) LocalAlloc(LMEM_FIXED, CharsRequired * sizeof(TCHAR));
  279. if (ExpandedString == NULL)
  280. {
  281. ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
  282. goto Cleanup;
  283. }
  284. LastAllocationSize = CharsRequired * sizeof(TCHAR);
  285. // Expand string using local env vars.
  286. CharsRequired = ExpandEnvironmentStrings(UnexpandedString,ExpandedString,LastAllocationSize / sizeof(TCHAR));
  287. if (CharsRequired == 0)
  288. {
  289. ApiStatus = (NET_API_STATUS) GetLastError();
  290. goto Cleanup;
  291. }
  292. } while ((CharsRequired*sizeof(TCHAR)) > LastAllocationSize);
  293. ApiStatus = NO_ERROR;
  294. //
  295. // Oh well, remote expansion required.
  296. //
  297. }
  298. else
  299. {
  300. DWORD DataType;
  301. LONG Error;
  302. UNICODE_STRING ExpandedUnicode;
  303. DWORD SizeRequired;
  304. UNICODE_STRING UnexpandedUnicode;
  305. //
  306. // Create a temporary environment, which we'll fill in and let RTL
  307. // routines do the expansion for us.
  308. //
  309. if (FALSE == NewRemoteEnvironment())
  310. {
  311. ApiStatus = E_FAIL;
  312. goto Cleanup;
  313. }
  314. //
  315. // Loop until we have enough storage.
  316. // Expand the string.
  317. //
  318. SizeRequired = (_tcslen(UnexpandedString) + 1) * sizeof(TCHAR); // First pass, try same size
  319. RtlInitUnicodeString(&UnexpandedUnicode,(PCWSTR) UnexpandedString);
  320. do {
  321. // Clean up from previous pass.
  322. if (ExpandedString){LocalFree(ExpandedString);ExpandedString = NULL;}
  323. // Allocate the memory.
  324. ExpandedString = (LPTSTR) LocalAlloc(LMEM_FIXED, SizeRequired);
  325. if (ExpandedString == NULL)
  326. {
  327. ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
  328. goto Cleanup;
  329. }
  330. LastAllocationSize = SizeRequired;
  331. ExpandedUnicode.MaximumLength = (USHORT)SizeRequired;
  332. ExpandedUnicode.Buffer = ExpandedString;
  333. NtStatus = RtlExpandEnvironmentStrings_U(
  334. m_pEnvironment, // env to use
  335. &UnexpandedUnicode, // source
  336. &ExpandedUnicode, // dest
  337. (PULONG) &SizeRequired ); // dest size needed next time.
  338. if ( NtStatus == STATUS_BUFFER_TOO_SMALL )
  339. {
  340. continue; // try again with larger buffer.
  341. }
  342. else if ( !NT_SUCCESS( NtStatus ) )
  343. {
  344. ApiStatus = E_FAIL;;
  345. goto Cleanup;
  346. }
  347. else
  348. {
  349. break; // All done.
  350. }
  351. } while (SizeRequired > LastAllocationSize);
  352. ApiStatus = NO_ERROR;
  353. }
  354. Cleanup:
  355. if (ApiStatus == NO_ERROR)
  356. {
  357. *ValueBufferPtr = ExpandedString;
  358. }
  359. else
  360. {
  361. *ValueBufferPtr = NULL;
  362. if (ExpandedString){LocalFree(ExpandedString);ExpandedString = NULL;}
  363. }
  364. return (ApiStatus);
  365. }
  366. BOOL CRemoteExpandEnvironmentStrings::BuildEnvironmentPath(void **pEnv, LPTSTR lpPathVariable, LPTSTR lpPathValue)
  367. {
  368. NTSTATUS Status;
  369. UNICODE_STRING Name;
  370. UNICODE_STRING Value;
  371. WCHAR lpTemp[1025];
  372. DWORD cb;
  373. if (!*pEnv) {
  374. return(FALSE);
  375. }
  376. RtlInitUnicodeString(&Name, lpPathVariable);
  377. cb = 1024;
  378. Value.Buffer = (PWCHAR)LocalAlloc(LPTR, cb*sizeof(WCHAR));
  379. if (!Value.Buffer) {
  380. return(FALSE);
  381. }
  382. Value.Length = (USHORT)(sizeof(WCHAR) * cb);
  383. Value.MaximumLength = (USHORT)(sizeof(WCHAR) * cb);
  384. Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value);
  385. if (!NT_SUCCESS(Status)) {
  386. LocalFree(Value.Buffer);
  387. Value.Length = 0;
  388. *lpTemp = 0;
  389. }
  390. if (Value.Length) {
  391. lstrcpy(lpTemp, Value.Buffer);
  392. if ( *( lpTemp + lstrlen(lpTemp) - 1) != TEXT(';') ) {
  393. lstrcat(lpTemp, TEXT(";"));
  394. }
  395. LocalFree(Value.Buffer);
  396. }
  397. if (lpPathValue && ((lstrlen(lpTemp) + lstrlen(lpPathValue) + 1) < (INT)cb)) {
  398. lstrcat(lpTemp, lpPathValue);
  399. RtlInitUnicodeString(&Value, lpTemp);
  400. Status = RtlSetEnvironmentVariable(pEnv, &Name, &Value);
  401. }
  402. if (NT_SUCCESS(Status)) {
  403. return(TRUE);
  404. }
  405. return(FALSE);
  406. }
  407. DWORD CRemoteExpandEnvironmentStrings::ExpandUserEnvironmentStrings(void *pEnv, LPTSTR lpSrc, LPTSTR lpDst, DWORD nSize)
  408. {
  409. NTSTATUS Status;
  410. UNICODE_STRING Source, Destination;
  411. ULONG Length;
  412. RtlInitUnicodeString( &Source, lpSrc );
  413. Destination.Buffer = lpDst;
  414. Destination.Length = 0;
  415. Destination.MaximumLength = (USHORT)(nSize* sizeof(WCHAR));
  416. Length = 0;
  417. Status = RtlExpandEnvironmentStrings_U(pEnv,
  418. (PUNICODE_STRING)&Source,
  419. (PUNICODE_STRING)&Destination,
  420. &Length
  421. );
  422. if (NT_SUCCESS( Status ) || Status == STATUS_BUFFER_TOO_SMALL) {
  423. return( Length );
  424. }
  425. else {
  426. return( 0 );
  427. }
  428. }
  429. BOOL CRemoteExpandEnvironmentStrings::SetUserEnvironmentVariable(void **pEnv, LPTSTR lpVariable, LPTSTR lpValue, BOOL bOverwrite)
  430. {
  431. NTSTATUS Status;
  432. UNICODE_STRING Name;
  433. UNICODE_STRING Value;
  434. DWORD cb;
  435. TCHAR szValue[1024];
  436. if (!*pEnv || !lpVariable || !*lpVariable) {
  437. return(FALSE);
  438. }
  439. RtlInitUnicodeString(&Name, lpVariable);
  440. cb = 1024;
  441. Value.Buffer = (PTCHAR)LocalAlloc(LPTR, cb*sizeof(WCHAR));
  442. if (Value.Buffer) {
  443. Value.Length = (USHORT)cb;
  444. Value.MaximumLength = (USHORT)cb;
  445. Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value);
  446. LocalFree(Value.Buffer);
  447. if (NT_SUCCESS(Status) && !bOverwrite) {
  448. return(TRUE);
  449. }
  450. }
  451. if (lpValue && *lpValue) {
  452. //
  453. // Special case TEMP and TMP and shorten the path names
  454. //
  455. if ((!_tcsicmp(lpVariable, TEXT("TEMP"))) ||
  456. (!_tcsicmp(lpVariable, TEXT("TMP")))) {
  457. if (!GetShortPathName (lpValue, szValue, 1024)) {
  458. lstrcpyn (szValue, lpValue, 1024);
  459. }
  460. } else {
  461. lstrcpyn (szValue, lpValue, 1024);
  462. }
  463. RtlInitUnicodeString(&Value, szValue);
  464. Status = RtlSetEnvironmentVariable(pEnv, &Name, &Value);
  465. }
  466. else {
  467. Status = RtlSetEnvironmentVariable( pEnv, &Name, NULL);
  468. }
  469. return NT_SUCCESS(Status);
  470. }
  471. // Reads the system environment variables from the registry
  472. // and adds them to the environment block at pEnv.
  473. BOOL CRemoteExpandEnvironmentStrings::SetEnvironmentVariables(void **pEnv)
  474. {
  475. WCHAR lpValueName[MAX_PATH];
  476. LPBYTE lpDataBuffer;
  477. DWORD cbDataBuffer;
  478. LPBYTE lpData;
  479. LPTSTR lpExpandedValue = NULL;
  480. DWORD cbValueName = MAX_PATH;
  481. DWORD cbData;
  482. DWORD dwType;
  483. DWORD dwIndex = 0;
  484. HKEY hkey;
  485. BOOL bResult;
  486. HKEY RootKey = DEFAULT_ROOT_KEY;
  487. if (ERROR_SUCCESS != RegConnectRegistry((LPTSTR) m_lpszUncServerName,DEFAULT_ROOT_KEY,& RootKey ))
  488. {
  489. return(FALSE);
  490. }
  491. if (RegOpenKeyExW(RootKey,REG_PATH_TO_ENV,REG_OPTION_NON_VOLATILE,KEY_READ,& hkey))
  492. {
  493. return(FALSE);
  494. }
  495. cbDataBuffer = 4096;
  496. lpDataBuffer = (LPBYTE)LocalAlloc(LPTR, cbDataBuffer*sizeof(WCHAR));
  497. if (lpDataBuffer == NULL) {
  498. RegCloseKey(hkey);
  499. return(FALSE);
  500. }
  501. lpData = lpDataBuffer;
  502. cbData = cbDataBuffer;
  503. bResult = TRUE;
  504. while (!RegEnumValue(hkey, dwIndex, lpValueName, &cbValueName, 0, &dwType,
  505. lpData, &cbData)) {
  506. if (cbValueName) {
  507. //
  508. // Limit environment variable length
  509. //
  510. lpData[MAX_ENV_VALUE_LEN-1] = TEXT('\0');
  511. if (dwType == REG_SZ) {
  512. //
  513. // The path variables PATH, LIBPATH and OS2LIBPATH must have
  514. // their values apppended to the system path.
  515. //
  516. if ( !_tcsicmp(lpValueName, PATH_VARIABLE) ||
  517. !_tcsicmp(lpValueName, LIBPATH_VARIABLE) ||
  518. !_tcsicmp(lpValueName, OS2LIBPATH_VARIABLE) ) {
  519. BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpData);
  520. }
  521. else {
  522. //
  523. // the other environment variables are just set.
  524. //
  525. SetUserEnvironmentVariable(pEnv, lpValueName, (LPTSTR)lpData, TRUE);
  526. }
  527. }
  528. }
  529. dwIndex++;
  530. cbData = cbDataBuffer;
  531. cbValueName = MAX_PATH;
  532. }
  533. dwIndex = 0;
  534. cbData = cbDataBuffer;
  535. cbValueName = MAX_PATH;
  536. while (!RegEnumValue(hkey, dwIndex, lpValueName, &cbValueName, 0, &dwType,
  537. lpData, &cbData)) {
  538. if (cbValueName) {
  539. //
  540. // Limit environment variable length
  541. //
  542. lpData[MAX_ENV_VALUE_LEN-1] = TEXT('\0');
  543. if (dwType == REG_EXPAND_SZ) {
  544. DWORD cb, cbNeeded;
  545. cb = 1024;
  546. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cb*sizeof(WCHAR));
  547. if (lpExpandedValue) {
  548. cbNeeded = ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cb);
  549. if (cbNeeded > cb) {
  550. LocalFree(lpExpandedValue);
  551. cb = cbNeeded;
  552. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cb*sizeof(WCHAR));
  553. if (lpExpandedValue) {
  554. ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cb);
  555. }
  556. }
  557. }
  558. if (lpExpandedValue == NULL) {
  559. bResult = FALSE;
  560. break;
  561. }
  562. //
  563. // The path variables PATH, LIBPATH and OS2LIBPATH must have
  564. // their values apppended to the system path.
  565. //
  566. if ( !_tcsicmp(lpValueName, PATH_VARIABLE) ||
  567. !_tcsicmp(lpValueName, LIBPATH_VARIABLE) ||
  568. !_tcsicmp(lpValueName, OS2LIBPATH_VARIABLE) ) {
  569. BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpExpandedValue);
  570. }
  571. else {
  572. //
  573. // the other environment variables are just set.
  574. //
  575. SetUserEnvironmentVariable(pEnv, lpValueName, (LPTSTR)lpExpandedValue, TRUE);
  576. }
  577. LocalFree(lpExpandedValue);
  578. }
  579. }
  580. dwIndex++;
  581. cbData = cbDataBuffer;
  582. cbValueName = MAX_PATH;
  583. }
  584. LocalFree(lpDataBuffer);
  585. RegCloseKey(hkey);
  586. return(bResult);
  587. }
  588. //*************************************************************
  589. //
  590. // SetEnvironmentVariableInBlock()
  591. //
  592. // Purpose: Sets the environment variable in the given block
  593. //
  594. // Parameters: pEnv - Environment block
  595. // lpVariable - Variables
  596. // lpValue - Value
  597. // bOverwrite - Overwrite
  598. //
  599. //
  600. // Return: TRUE if successful
  601. // FALSE if an error occurs
  602. //
  603. // Comments:
  604. //
  605. // History: Date Author Comment
  606. // 6/21/96 ericflo Ported
  607. //
  608. //*************************************************************
  609. BOOL CRemoteExpandEnvironmentStrings::SetEnvironmentVariableInBlock(PVOID *pEnv, LPTSTR lpVariable,LPTSTR lpValue, BOOL bOverwrite)
  610. {
  611. NTSTATUS Status;
  612. UNICODE_STRING Name, Value;
  613. DWORD cb;
  614. LPTSTR szValue = NULL;
  615. if (!*pEnv || !lpVariable || !*lpVariable) {
  616. return(FALSE);
  617. }
  618. RtlInitUnicodeString(&Name, lpVariable);
  619. cb = 1025 * sizeof(WCHAR);
  620. Value.Buffer = (PWSTR) LocalAlloc(LPTR, cb);
  621. if (Value.Buffer) {
  622. Value.Length = 0;
  623. Value.MaximumLength = (USHORT)cb;
  624. Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value);
  625. LocalFree(Value.Buffer);
  626. if ( NT_SUCCESS(Status) && !bOverwrite) {
  627. return(TRUE);
  628. }
  629. }
  630. szValue = (LPTSTR)LocalAlloc(LPTR, 1024*sizeof(TCHAR));
  631. if (!szValue)
  632. {
  633. return FALSE;
  634. }
  635. if (lpValue && *lpValue) {
  636. //
  637. // Special case TEMP and TMP and shorten the path names
  638. //
  639. if ((!_tcsicmp(lpVariable, TEXT("TEMP"))) ||
  640. (!_tcsicmp(lpVariable, TEXT("TMP")))) {
  641. if (!GetShortPathName (lpValue, szValue, 1024)) {
  642. lstrcpyn (szValue, lpValue, 1024);
  643. }
  644. } else {
  645. lstrcpyn (szValue, lpValue, 1024);
  646. }
  647. RtlInitUnicodeString(&Value, szValue);
  648. Status = RtlSetEnvironmentVariable(pEnv, &Name, &Value);
  649. }
  650. else {
  651. Status = RtlSetEnvironmentVariable(pEnv, &Name, NULL);
  652. }
  653. LocalFree(szValue);
  654. if (NT_SUCCESS(Status)) {
  655. return(TRUE);
  656. }
  657. return(FALSE);
  658. }
  659. // Just set the environmental variables that we can
  660. // if we can't set them because of no access, no biggie
  661. DWORD CRemoteExpandEnvironmentStrings::SetOtherEnvironmentValues(void **pEnv)
  662. {
  663. DWORD dwResult = ERROR_SUCCESS;
  664. HKEY hKey = NULL;
  665. HKEY RootKey = DEFAULT_ROOT_KEY;
  666. DWORD dwType, dwSize;
  667. TCHAR szValue[MAX_ENV_VALUE_LEN + 1];
  668. TCHAR szExpValue[MAX_ENV_VALUE_LEN + 1];
  669. DWORD RandomValueSize = 0;
  670. LPTSTR RandomValueW = NULL;
  671. // try to connect to remote registry (or local registry if Null)
  672. dwResult = RegConnectRegistry((LPTSTR) m_lpszUncServerName,DEFAULT_ROOT_KEY,& RootKey);
  673. if (ERROR_SUCCESS != dwResult)
  674. {
  675. goto SetOtherEnvironmentValues_Exit;
  676. }
  677. dwResult = RegOpenKeyEx(RootKey,REG_PATH_TO_SYSROOT,REG_OPTION_NON_VOLATILE,KEY_READ,&hKey);
  678. if (ERROR_SUCCESS == dwResult)
  679. {
  680. dwResult = GetRegKeyMaxSizes(
  681. hKey,
  682. NULL, // don't need keyword size
  683. &RandomValueSize ); // set max value size.
  684. if (ERROR_SUCCESS != dwResult)
  685. {
  686. goto SetOtherEnvironmentValues_Exit;
  687. }
  688. RandomValueW = (LPTSTR) LocalAlloc(LMEM_FIXED, RandomValueSize);
  689. if (RandomValueW == NULL)
  690. {
  691. dwResult = ERROR_NOT_ENOUGH_MEMORY;
  692. }
  693. else
  694. {
  695. if (RegQueryValueEx(hKey,(LPTSTR)ENV_KEYWORD_SYSTEMROOT,REG_OPTION_NON_VOLATILE,&dwType,(LPBYTE) RandomValueW,&RandomValueSize) == ERROR_SUCCESS)
  696. {
  697. SetEnvironmentVariableInBlock(pEnv, ENV_KEYWORD_SYSTEMROOT, RandomValueW, TRUE);
  698. }
  699. }
  700. if (hKey) {RegCloseKey(hKey);}
  701. }
  702. dwResult = RegOpenKeyEx (RootKey, REG_PATH_TO_COMMON_FOLDERS, REG_OPTION_NON_VOLATILE, KEY_READ, &hKey);
  703. if (ERROR_SUCCESS == dwResult)
  704. {
  705. dwSize = (MAX_ENV_VALUE_LEN+1) * sizeof(TCHAR);
  706. if (RegQueryValueEx (hKey, ENV_KEYWORD_PROGRAMFILESDIR, NULL, &dwType,(LPBYTE) szValue, &dwSize) == ERROR_SUCCESS)
  707. {
  708. ExpandEnvironmentStrings (szValue, szExpValue, (MAX_ENV_VALUE_LEN+1));
  709. SetEnvironmentVariableInBlock(pEnv, PROGRAMFILES_VARIABLE, szExpValue, TRUE);
  710. }
  711. dwSize = (MAX_ENV_VALUE_LEN+1) * sizeof(TCHAR);
  712. if (RegQueryValueEx (hKey, ENV_KEYWORD_COMMONFILESDIR, NULL, &dwType,(LPBYTE) szValue, &dwSize) == ERROR_SUCCESS)
  713. {
  714. ExpandEnvironmentStrings (szValue, szExpValue, (MAX_ENV_VALUE_LEN+1));
  715. SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILES_VARIABLE, szExpValue, TRUE);
  716. }
  717. dwSize = (MAX_ENV_VALUE_LEN+1)*sizeof(TCHAR);
  718. if (RegQueryValueEx (hKey, ENV_KEYWORD_PROGRAMFILESDIR_X86, NULL, &dwType,(LPBYTE) szValue, &dwSize) == ERROR_SUCCESS)
  719. {
  720. ExpandEnvironmentStrings (szValue, szExpValue, (MAX_ENV_VALUE_LEN+1));
  721. SetEnvironmentVariableInBlock(pEnv, PROGRAMFILESX86_VARIABLE, szExpValue, TRUE);
  722. }
  723. dwSize = (MAX_ENV_VALUE_LEN+1)*sizeof(TCHAR);
  724. if (RegQueryValueEx (hKey, ENV_KEYWORD_COMMONFILESDIR_X86, NULL, &dwType,(LPBYTE) szValue, &dwSize) == ERROR_SUCCESS)
  725. {
  726. ExpandEnvironmentStrings (szValue, szExpValue, (MAX_ENV_VALUE_LEN+1));
  727. SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILESX86_VARIABLE, szExpValue, TRUE);
  728. }
  729. }
  730. SetOtherEnvironmentValues_Exit:
  731. if (RootKey != DEFAULT_ROOT_KEY)
  732. {RegCloseKey(RootKey);}
  733. if (hKey) {RegCloseKey(hKey);}
  734. return dwResult;
  735. }