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.

1995 lines
54 KiB

  1. //*************************************************************
  2. // File name: envvar.c
  3. //
  4. // Description: Contains the environment variable functions
  5. //
  6. //
  7. // Microsoft Confidential
  8. // Copyright (c) Microsoft Corporation 1996
  9. // All rights reserved
  10. //
  11. //*************************************************************
  12. #include "uenv.h"
  13. #include "strsafe.h"
  14. //
  15. // Max environment variable length
  16. //
  17. #define MAX_VALUE_LEN 1024
  18. //
  19. // Environment variables
  20. //
  21. #define COMPUTERNAME_VARIABLE TEXT("COMPUTERNAME")
  22. #define HOMEDRIVE_VARIABLE TEXT("HOMEDRIVE")
  23. #define HOMESHARE_VARIABLE TEXT("HOMESHARE")
  24. #define HOMEPATH_VARIABLE TEXT("HOMEPATH")
  25. #define SYSTEMDRIVE_VARIABLE TEXT("SystemDrive")
  26. #define SYSTEMROOT_VARIABLE TEXT("SystemRoot")
  27. #define USERNAME_VARIABLE TEXT("USERNAME")
  28. #define USERDOMAIN_VARIABLE TEXT("USERDOMAIN")
  29. #define USERDNSDOMAIN_VARIABLE TEXT("USERDNSDOMAIN")
  30. #define USERPROFILE_VARIABLE TEXT("USERPROFILE")
  31. #define ALLUSERSPROFILE_VARIABLE TEXT("ALLUSERSPROFILE")
  32. #define PATH_VARIABLE TEXT("Path")
  33. #define LIBPATH_VARIABLE TEXT("LibPath")
  34. #define OS2LIBPATH_VARIABLE TEXT("Os2LibPath")
  35. #define PROGRAMFILES_VARIABLE TEXT("ProgramFiles")
  36. #define COMMONPROGRAMFILES_VARIABLE TEXT("CommonProgramFiles")
  37. #if defined(WX86) || defined(_WIN64)
  38. #define PROGRAMFILESX86_VARIABLE TEXT("ProgramFiles(x86)")
  39. #define COMMONPROGRAMFILESX86_VARIABLE TEXT("CommonProgramFiles(x86)")
  40. #endif
  41. #define USER_ENV_SUBKEY TEXT("Environment")
  42. #define USER_VOLATILE_ENV_SUBKEY TEXT("Volatile Environment")
  43. //
  44. // Parsing information for autoexec.bat
  45. //
  46. #define AUTOEXECPATH_VARIABLE TEXT("AutoexecPath")
  47. #define PARSE_AUTOEXEC_KEY TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon")
  48. #define PARSE_AUTOEXEC_ENTRY TEXT("ParseAutoexec")
  49. #define PARSE_AUTOEXEC_DEFAULT TEXT("1")
  50. #define MAX_PARSE_AUTOEXEC_BUFFER 2
  51. #define SYS_ENVVARS TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Environment")
  52. BOOL UpdateSystemEnvironment(PVOID *pEnv);
  53. BOOL GetUserNameAndDomain(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain);
  54. BOOL GetUserNameAndDomainSlowly(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain);
  55. LPTSTR GetUserDNSDomainName(LPTSTR lpDomain, HANDLE hUserToken);
  56. LONG GetHKeyCU(HANDLE hToken, HKEY *hKeyCU);
  57. BOOL ProcessAutoexec(PVOID *pEnv);
  58. BOOL AppendNTPathWithAutoexecPath(PVOID *pEnv, LPTSTR lpPathVariable, LPTSTR lpAutoexecPath);
  59. BOOL SetEnvironmentVariables(PVOID *pEnv, LPTSTR lpRegSubKey, HKEY hKeyCU);
  60. #ifdef _X86_
  61. BOOL IsPathIncludeRemovable(LPTSTR lpValue);
  62. #endif
  63. __inline BOOL SafeGetEnvironmentVariable(LPCTSTR lpName, LPTSTR lpBuffer, DWORD nSize)
  64. {
  65. DWORD dwRet = GetEnvironmentVariable(lpName, lpBuffer, nSize);
  66. return (dwRet > 0) && (dwRet < nSize);
  67. }
  68. //*************************************************************
  69. //
  70. // CreateEnvironmentBlock()
  71. //
  72. // Purpose: Creates the environment variables for the
  73. // specificed hToken. If hToken is NULL, the
  74. // environment block will only contain system
  75. // variables.
  76. //
  77. // Parameters: pEnv - Receives the environment block
  78. // hToken - User's token or NULL
  79. // bInherit - Inherit the current process environment
  80. //
  81. // Return: TRUE if successful
  82. // FALSE if not
  83. //
  84. // Comments: The pEnv value must be destroyed by
  85. // calling DestroyEnvironmentBlock
  86. //
  87. // History: Date Author Comment
  88. // 6/19/96 ericflo Created
  89. //
  90. //*************************************************************
  91. BOOL WINAPI CreateEnvironmentBlock (LPVOID *pEnv, HANDLE hToken, BOOL bInherit)
  92. {
  93. LPTSTR szBuffer = NULL;
  94. LPTSTR szValue = NULL;
  95. LPTSTR szExpValue = NULL;
  96. DWORD dwBufferSize = MAX_PATH+1;
  97. NTSTATUS Status;
  98. LPTSTR UserName = NULL;
  99. LPTSTR UserDomain = NULL;
  100. LPTSTR UserDNSDomain = NULL;
  101. HKEY hKey, hKeyCU;
  102. DWORD dwDisp, dwType, dwSize;
  103. TCHAR szParseAutoexec[MAX_PARSE_AUTOEXEC_BUFFER];
  104. LONG dwError;
  105. BOOL bRetVal = FALSE;
  106. //
  107. // Arg check
  108. //
  109. if (!pEnv) {
  110. SetLastError (ERROR_INVALID_PARAMETER);
  111. goto Exit;
  112. }
  113. Status = RtlCreateEnvironment((BOOLEAN)bInherit, pEnv);
  114. if (!NT_SUCCESS(Status)) {
  115. goto Exit;
  116. }
  117. //
  118. // Allocate memory for Local variables to avoid stack overflow
  119. //
  120. szBuffer = (LPTSTR)LocalAlloc(LPTR, (MAX_PATH+1)*sizeof(TCHAR));
  121. if (!szBuffer) {
  122. DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory")));
  123. goto Exit;
  124. }
  125. szValue = (LPTSTR)LocalAlloc(LPTR, (MAX_VALUE_LEN+1)*sizeof(TCHAR));
  126. if (!szValue) {
  127. DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory")));
  128. goto Exit;
  129. }
  130. szExpValue = (LPTSTR)LocalAlloc(LPTR, (MAX_VALUE_LEN+1)*sizeof(TCHAR));
  131. if (!szExpValue) {
  132. DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Out of memory")));
  133. goto Exit;
  134. }
  135. //
  136. // First start by getting the systemroot and systemdrive values and
  137. // setting it in the new environment.
  138. //
  139. if ( SafeGetEnvironmentVariable(SYSTEMROOT_VARIABLE, szBuffer, dwBufferSize) )
  140. {
  141. SetEnvironmentVariableInBlock(pEnv, SYSTEMROOT_VARIABLE, szBuffer, TRUE);
  142. }
  143. if ( SafeGetEnvironmentVariable(SYSTEMDRIVE_VARIABLE, szBuffer, dwBufferSize) )
  144. {
  145. SetEnvironmentVariableInBlock(pEnv, SYSTEMDRIVE_VARIABLE, szBuffer, TRUE);
  146. }
  147. //
  148. // Set the all users profile location.
  149. //
  150. dwBufferSize = MAX_PATH+1;
  151. if (GetAllUsersProfileDirectory(szBuffer, &dwBufferSize)) {
  152. SetEnvironmentVariableInBlock(pEnv, ALLUSERSPROFILE_VARIABLE, szBuffer, TRUE);
  153. }
  154. //
  155. // We must examine the registry directly to pull out
  156. // the system environment variables, because they
  157. // may have changed since the system was booted.
  158. //
  159. if (!UpdateSystemEnvironment(pEnv)) {
  160. RtlDestroyEnvironment(*pEnv);
  161. goto Exit;
  162. }
  163. //
  164. // Set the computername
  165. //
  166. dwBufferSize = MAX_PATH+1;
  167. if (GetComputerName (szBuffer, &dwBufferSize)) {
  168. SetEnvironmentVariableInBlock(pEnv, COMPUTERNAME_VARIABLE, szBuffer, TRUE);
  169. }
  170. //
  171. // Set the default user profile location
  172. //
  173. dwBufferSize = MAX_PATH+1;
  174. if (GetDefaultUserProfileDirectory(szBuffer, &dwBufferSize)) {
  175. SetEnvironmentVariableInBlock(pEnv, USERPROFILE_VARIABLE, szBuffer, TRUE);
  176. }
  177. //
  178. // Set the Program Files environment variable
  179. //
  180. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("Software\\Microsoft\\Windows\\CurrentVersion"),
  181. 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
  182. dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR);
  183. if (RegQueryValueEx (hKey, TEXT("ProgramFilesDir"), NULL, &dwType,
  184. (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
  185. if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1))))
  186. SetEnvironmentVariableInBlock(pEnv, PROGRAMFILES_VARIABLE, szExpValue, TRUE);
  187. }
  188. dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR);
  189. if (RegQueryValueEx (hKey, TEXT("CommonFilesDir"), NULL, &dwType,
  190. (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
  191. if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1))))
  192. SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILES_VARIABLE, szExpValue, TRUE);
  193. }
  194. #if defined(WX86) || defined(_WIN64)
  195. dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR);
  196. if (RegQueryValueEx (hKey, TEXT("ProgramFilesDir (x86)"), NULL, &dwType,
  197. (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
  198. if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1))))
  199. SetEnvironmentVariableInBlock(pEnv, PROGRAMFILESX86_VARIABLE, szExpValue, TRUE);
  200. }
  201. dwSize = (MAX_VALUE_LEN+1)*sizeof(TCHAR);
  202. if (RegQueryValueEx (hKey, TEXT("CommonFilesDir (x86)"), NULL, &dwType,
  203. (LPBYTE) szValue, &dwSize) == ERROR_SUCCESS) {
  204. if (SUCCEEDED(SafeExpandEnvironmentStrings (szValue, szExpValue, (MAX_VALUE_LEN+1))))
  205. SetEnvironmentVariableInBlock(pEnv, COMMONPROGRAMFILESX86_VARIABLE, szExpValue, TRUE);
  206. }
  207. #endif
  208. RegCloseKey (hKey);
  209. }
  210. //
  211. // If hToken is NULL, we can exit now since the caller only wants
  212. // system environment variables.
  213. //
  214. if (!hToken) {
  215. bRetVal = TRUE;
  216. goto Exit;
  217. }
  218. //
  219. // Open the HKEY_CURRENT_USER for this token.
  220. //
  221. dwError = GetHKeyCU(hToken, &hKeyCU);
  222. //
  223. // if the hive is not found assume that the caller just needs the system attribute.
  224. //
  225. if ((!hKeyCU) && (dwError == ERROR_FILE_NOT_FOUND)) {
  226. bRetVal = TRUE;
  227. goto Exit;
  228. }
  229. if (!hKeyCU) {
  230. RtlDestroyEnvironment(*pEnv);
  231. DebugMsg((DM_WARNING, TEXT("CreateEnvironmentBlock: Failed to open HKEY_CURRENT_USER, error = %d"), dwError));
  232. goto Exit;
  233. }
  234. //
  235. // Set the user's name and domain.
  236. //
  237. if (!GetUserNameAndDomain(hToken, &UserName, &UserDomain)) {
  238. GetUserNameAndDomainSlowly(hToken, &UserName, &UserDomain);
  239. }
  240. UserDNSDomain = GetUserDNSDomainName(UserDomain, hToken);
  241. SetEnvironmentVariableInBlock( pEnv, USERNAME_VARIABLE, UserName, TRUE);
  242. SetEnvironmentVariableInBlock( pEnv, USERDOMAIN_VARIABLE, UserDomain, TRUE);
  243. SetEnvironmentVariableInBlock( pEnv, USERDNSDOMAIN_VARIABLE, UserDNSDomain, TRUE);
  244. LocalFree(UserName);
  245. LocalFree(UserDomain);
  246. LocalFree(UserDNSDomain);
  247. //
  248. // Set the user's profile location.
  249. //
  250. dwBufferSize = MAX_PATH+1;
  251. if (GetUserProfileDirectory(hToken, szBuffer, &dwBufferSize)) {
  252. SetEnvironmentVariableInBlock(pEnv, USERPROFILE_VARIABLE, szBuffer, TRUE);
  253. }
  254. //
  255. // Process autoexec.bat
  256. //
  257. StringCchCopy (szParseAutoexec, ARRAYSIZE(szParseAutoexec), PARSE_AUTOEXEC_DEFAULT);
  258. if (RegCreateKeyEx (hKeyCU, PARSE_AUTOEXEC_KEY, 0, 0,
  259. REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
  260. NULL, &hKey, &dwDisp) == ERROR_SUCCESS) {
  261. //
  262. // Query the current value. If it doesn't exist, then add
  263. // the entry for next time.
  264. //
  265. dwBufferSize = sizeof (TCHAR) * MAX_PARSE_AUTOEXEC_BUFFER;
  266. if (RegQueryValueEx (hKey, PARSE_AUTOEXEC_ENTRY, NULL, &dwType,
  267. (LPBYTE) szParseAutoexec, &dwBufferSize)
  268. != ERROR_SUCCESS) {
  269. //
  270. // Set the default value
  271. //
  272. RegSetValueEx (hKey, PARSE_AUTOEXEC_ENTRY, 0, REG_SZ,
  273. (LPBYTE) szParseAutoexec,
  274. sizeof (TCHAR) * lstrlen (szParseAutoexec) + 1);
  275. }
  276. //
  277. // Close key
  278. //
  279. RegCloseKey (hKey);
  280. }
  281. //
  282. // Process autoexec if appropriate
  283. //
  284. if (szParseAutoexec[0] == TEXT('1')) {
  285. ProcessAutoexec(pEnv);
  286. }
  287. //
  288. // Set User environment variables.
  289. //
  290. SetEnvironmentVariables(pEnv, USER_ENV_SUBKEY, hKeyCU);
  291. //
  292. // Set User volatile environment variables.
  293. //
  294. SetEnvironmentVariables(pEnv, USER_VOLATILE_ENV_SUBKEY, hKeyCU);
  295. //
  296. // Merge the paths
  297. //
  298. AppendNTPathWithAutoexecPath(pEnv, PATH_VARIABLE, AUTOEXECPATH_VARIABLE);
  299. RegCloseKey (hKeyCU);
  300. bRetVal = TRUE;
  301. Exit:
  302. if (szBuffer) {
  303. LocalFree(szBuffer);
  304. }
  305. if (szValue) {
  306. LocalFree(szValue);
  307. }
  308. if (szExpValue) {
  309. LocalFree(szExpValue);
  310. }
  311. return bRetVal;
  312. }
  313. //*************************************************************
  314. //
  315. // DestroyEnvironmentBlock()
  316. //
  317. // Purpose: Frees the environment block created by
  318. // CreateEnvironmentBlock
  319. //
  320. // Parameters: lpEnvironment - Pointer to variables
  321. //
  322. // Return: TRUE if successful
  323. // FALSE if an error occurs
  324. //
  325. // Comments:
  326. //
  327. // History: Date Author Comment
  328. // 6/19/96 ericflo Created
  329. //
  330. //*************************************************************
  331. BOOL WINAPI DestroyEnvironmentBlock (LPVOID lpEnvironment)
  332. {
  333. if (!lpEnvironment) {
  334. SetLastError (ERROR_INVALID_PARAMETER);
  335. return FALSE;
  336. }
  337. RtlDestroyEnvironment(lpEnvironment);
  338. return TRUE;
  339. }
  340. //*************************************************************
  341. //
  342. // UpdateSystemEnvironment()
  343. //
  344. // Purpose: Reads the system environment variables from the
  345. // registry.
  346. //
  347. // Parameters: pEnv - Environment block pointer
  348. //
  349. // Return: TRUE if successful
  350. // FALSE if an error occurs
  351. //
  352. // Comments:
  353. //
  354. // History: Date Author Comment
  355. // 6/21/96 ericflo Ported
  356. //
  357. //*************************************************************
  358. BOOL UpdateSystemEnvironment(PVOID *pEnv)
  359. {
  360. HKEY KeyHandle = NULL;
  361. DWORD Result;
  362. DWORD ValueNameLength;
  363. DWORD Type;
  364. DWORD DataLength;
  365. DWORD cValues; /* address of buffer for number of value identifiers */
  366. DWORD chMaxValueName; /* address of buffer for longest value name length */
  367. DWORD cbMaxValueData; /* address of buffer for longest value data length */
  368. FILETIME FileTime;
  369. PTCHAR ValueName = NULL;
  370. PTCHAR ValueData = NULL;
  371. DWORD i;
  372. BOOL Bool;
  373. PTCHAR ExpandedValue;
  374. BOOL rc = TRUE;
  375. Result = RegOpenKeyEx (
  376. HKEY_LOCAL_MACHINE,
  377. SYS_ENVVARS,
  378. 0,
  379. KEY_QUERY_VALUE,
  380. &KeyHandle
  381. );
  382. if ( Result != ERROR_SUCCESS ) {
  383. DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: RegOpenKeyEx failed, error = %d"),Result));
  384. return( TRUE );
  385. }
  386. Result = RegQueryInfoKey(
  387. KeyHandle,
  388. NULL, /* address of buffer for class string */
  389. NULL, /* address of size of class string buffer */
  390. NULL, /* reserved */
  391. NULL, /* address of buffer for number of subkeys */
  392. NULL, /* address of buffer for longest subkey */
  393. NULL, /* address of buffer for longest class string length */
  394. &cValues, /* address of buffer for number of value identifiers */
  395. &chMaxValueName, /* address of buffer for longest value name length */
  396. &cbMaxValueData, /* address of buffer for longest value data length */
  397. NULL, /* address of buffer for descriptor length */
  398. &FileTime /* address of buffer for last write time */
  399. );
  400. if ( Result != NO_ERROR && Result != ERROR_MORE_DATA ) {
  401. DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: RegQueryInfoKey failed, error = %d"),Result));
  402. rc = TRUE;
  403. goto Cleanup;
  404. }
  405. //
  406. // No need to adjust the datalength for TCHAR issues
  407. //
  408. ValueData = LocalAlloc(LPTR, cbMaxValueData);
  409. if ( ValueData == NULL ) {
  410. rc = FALSE;
  411. goto Cleanup;
  412. }
  413. //
  414. // The maximum value name length comes back in characters, convert to bytes
  415. // before allocating storage. Allow for trailing NULL also.
  416. //
  417. ValueName = LocalAlloc(LPTR, (++chMaxValueName) * sizeof( TCHAR ) );
  418. if ( ValueName == NULL ) {
  419. rc = FALSE;
  420. goto Cleanup;
  421. }
  422. //
  423. // To exit from here on, set rc and jump to Cleanup
  424. //
  425. for (i=0; i<cValues ; i++) {
  426. ValueNameLength = chMaxValueName;
  427. DataLength = cbMaxValueData;
  428. Result = RegEnumValue (
  429. KeyHandle,
  430. i,
  431. ValueName,
  432. &ValueNameLength, // Size in TCHARs
  433. NULL,
  434. &Type,
  435. (LPBYTE)ValueData,
  436. &DataLength // Size in bytes
  437. );
  438. if ( Result != ERROR_SUCCESS ) {
  439. //
  440. // Problem getting the value. We can either try
  441. // the rest or punt completely.
  442. //
  443. goto Cleanup;
  444. }
  445. //
  446. // If the buffer size is greater than the max allowed,
  447. // terminate the string at MAX_VALUE_LEN - 1.
  448. //
  449. if (DataLength >= (MAX_VALUE_LEN * sizeof(TCHAR))) {
  450. ValueData[MAX_VALUE_LEN-1] = TEXT('\0');
  451. }
  452. switch ( Type ) {
  453. case REG_SZ:
  454. {
  455. Bool = SetEnvironmentVariableInBlock(
  456. pEnv,
  457. ValueName,
  458. ValueData,
  459. TRUE
  460. );
  461. if ( !Bool ) {
  462. DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: Failed to set environment variable <%s> to <%s> with %d."),
  463. ValueName, ValueData, GetLastError()));
  464. }
  465. break;
  466. }
  467. default:
  468. {
  469. continue;
  470. }
  471. }
  472. }
  473. //
  474. // To exit from here on, set rc and jump to Cleanup
  475. //
  476. for (i=0; i<cValues ; i++) {
  477. ValueNameLength = chMaxValueName;
  478. DataLength = cbMaxValueData;
  479. Result = RegEnumValue (
  480. KeyHandle,
  481. i,
  482. ValueName,
  483. &ValueNameLength, // Size in TCHARs
  484. NULL,
  485. &Type,
  486. (LPBYTE)ValueData,
  487. &DataLength // Size in bytes
  488. );
  489. if ( Result != ERROR_SUCCESS ) {
  490. //
  491. // Problem getting the value. We can either try
  492. // the rest or punt completely.
  493. //
  494. goto Cleanup;
  495. }
  496. //
  497. // If the buffer size is greater than the max allowed,
  498. // terminate the string at MAX_VALUE_LEN - 1.
  499. //
  500. if (DataLength >= (MAX_VALUE_LEN * sizeof(TCHAR))) {
  501. ValueData[MAX_VALUE_LEN-1] = TEXT('\0');
  502. }
  503. switch ( Type ) {
  504. case REG_EXPAND_SZ:
  505. {
  506. ExpandedValue = AllocAndExpandEnvironmentStrings( ValueData );
  507. Bool = SetEnvironmentVariableInBlock(
  508. pEnv,
  509. ValueName,
  510. ExpandedValue,
  511. TRUE
  512. );
  513. LocalFree( ExpandedValue );
  514. if ( !Bool ) {
  515. DebugMsg((DM_WARNING, TEXT("UpdateSystemEnvironment: Failed to set environment variable <%s> to <%s> with %d."),
  516. ValueName, ValueData, GetLastError()));
  517. }
  518. break;
  519. }
  520. default:
  521. {
  522. continue;
  523. }
  524. }
  525. }
  526. Cleanup:
  527. if (KeyHandle)
  528. RegCloseKey(KeyHandle);
  529. if (ValueName)
  530. LocalFree( ValueName );
  531. if (ValueData)
  532. LocalFree( ValueData );
  533. return( rc );
  534. }
  535. //*************************************************************
  536. //
  537. // GetUserNameAndDomain()
  538. //
  539. // Purpose: Gets the user's name and domain
  540. //
  541. // Parameters: hToken - User's token
  542. // UserName - Receives pointer to user's name
  543. // UserDomain - Receives pointer to user's domain
  544. //
  545. // Return: TRUE if successful
  546. // FALSE if an error occurs
  547. //
  548. // Comments:
  549. //
  550. // History: Date Author Comment
  551. // 6/21/96 ericflo Ported
  552. //
  553. //*************************************************************
  554. BOOL GetUserNameAndDomain(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain)
  555. {
  556. BOOL bResult = FALSE;
  557. LPTSTR lpTemp, lpDomain = NULL;
  558. LPTSTR lpUserName, lpUserDomain;
  559. HANDLE hOldToken;
  560. DWORD dwSize;
  561. //
  562. // Impersonate the user
  563. //
  564. if (!ImpersonateUser(hToken, &hOldToken)) {
  565. DebugMsg((DM_VERBOSE, TEXT("GetUserNameAndDomain Failed to impersonate user")));
  566. goto Exit;
  567. }
  568. //
  569. // Get the username in NT4 format
  570. //
  571. lpDomain = MyGetUserNameEx (NameSamCompatible);
  572. RevertToUser(&hOldToken);
  573. if (!lpDomain) {
  574. DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain: MyGetUserNameEx failed for NT4 style name with %d"),
  575. GetLastError()));
  576. goto Exit;
  577. }
  578. //
  579. // Look for the \ between the domain and username and replace
  580. // it with a NULL
  581. //
  582. lpTemp = lpDomain;
  583. while (*lpTemp && ((*lpTemp) != TEXT('\\')))
  584. lpTemp++;
  585. if (*lpTemp != TEXT('\\')) {
  586. DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to find slash in NT4 style name: <%s>"),
  587. lpDomain));
  588. goto Exit;
  589. }
  590. *lpTemp = TEXT('\0');
  591. lpTemp++;
  592. //
  593. // Allocate space for the results
  594. //
  595. dwSize = lstrlen(lpTemp) + 1;
  596. lpUserName = LocalAlloc (LPTR, dwSize * sizeof(TCHAR));
  597. if (!lpUserName) {
  598. DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to allocate memory with %d"),
  599. GetLastError()));
  600. goto Exit;
  601. }
  602. StringCchCopy (lpUserName, dwSize, lpTemp);
  603. dwSize = lstrlen(lpDomain) + 1;
  604. lpUserDomain = LocalAlloc (LPTR, dwSize * sizeof(TCHAR));
  605. if (!lpUserDomain) {
  606. DebugMsg((DM_WARNING, TEXT("GetUserNameAndDomain Failed to allocate memory with %d"),
  607. GetLastError()));
  608. LocalFree (lpUserName);
  609. goto Exit;
  610. }
  611. StringCchCopy (lpUserDomain, dwSize, lpDomain);
  612. //
  613. // Save the results in the outbound arguments
  614. //
  615. *UserName = lpUserName;
  616. *UserDomain = lpUserDomain;
  617. //
  618. // Success
  619. //
  620. bResult = TRUE;
  621. Exit:
  622. if (lpDomain) {
  623. LocalFree (lpDomain);
  624. }
  625. return(bResult);
  626. }
  627. //*************************************************************
  628. //
  629. // GetUserNameAndDomainSlowly()
  630. //
  631. // Purpose: Gets the user's name and domain from a DC
  632. //
  633. // Parameters: hToken - User's token
  634. // UserName - Receives pointer to user's name
  635. // UserDomain - Receives pointer to user's domain
  636. //
  637. // Return: TRUE if successful
  638. // FALSE if an error occurs
  639. //
  640. // Comments:
  641. //
  642. // History: Date Author Comment
  643. // 6/21/96 ericflo Ported
  644. //
  645. //*************************************************************
  646. BOOL GetUserNameAndDomainSlowly(HANDLE hToken, LPTSTR *UserName, LPTSTR *UserDomain)
  647. {
  648. LPTSTR lpUserName = NULL;
  649. LPTSTR lpUserDomain = NULL;
  650. DWORD cbAccountName = 0;
  651. DWORD cbUserDomain = 0;
  652. SID_NAME_USE SidNameUse;
  653. BOOL bRet = FALSE;
  654. PSID pSid;
  655. //
  656. // Get the user's sid
  657. //
  658. pSid = GetUserSid (hToken);
  659. if (!pSid) {
  660. return FALSE;
  661. }
  662. //
  663. // Get the space needed for the User name and the Domain name
  664. //
  665. if (!LookupAccountSid(NULL,
  666. pSid,
  667. NULL, &cbAccountName,
  668. NULL, &cbUserDomain,
  669. &SidNameUse
  670. ) ) {
  671. if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
  672. goto Error;
  673. }
  674. }
  675. lpUserName = (LPTSTR)LocalAlloc(LPTR, cbAccountName*sizeof(TCHAR));
  676. if (!lpUserName) {
  677. goto Error;
  678. }
  679. lpUserDomain = (LPTSTR)LocalAlloc(LPTR, cbUserDomain*sizeof(WCHAR));
  680. if (!lpUserDomain) {
  681. LocalFree(lpUserName);
  682. goto Error;
  683. }
  684. //
  685. // Now get the user name and domain name
  686. //
  687. if (!LookupAccountSid(NULL,
  688. pSid,
  689. lpUserName, &cbAccountName,
  690. lpUserDomain, &cbUserDomain,
  691. &SidNameUse
  692. ) ) {
  693. LocalFree(lpUserName);
  694. LocalFree(lpUserDomain);
  695. goto Error;
  696. }
  697. *UserName = lpUserName;
  698. *UserDomain = lpUserDomain;
  699. bRet = TRUE;
  700. Error:
  701. DeleteUserSid (pSid);
  702. return(bRet);
  703. }
  704. //*************************************************************
  705. //
  706. // GetUserDNSDomainName()
  707. //
  708. // Purpose: Gets the DNS domain name for the user
  709. //
  710. // Parameters: lpDomain - User's flat domain name
  711. // hUserToken - User's token
  712. //
  713. //
  714. // Return: DNS domain name if successful
  715. // NULL if an error occurs
  716. //
  717. //*************************************************************
  718. LPTSTR GetUserDNSDomainName(LPTSTR lpDomain, HANDLE hUserToken)
  719. {
  720. LPTSTR lpDnsDomain = NULL, lpTemp = NULL;
  721. DWORD dwBufferSize;
  722. TCHAR szBuffer[MAX_PATH];
  723. INT iRole;
  724. HANDLE hOldToken;
  725. BOOL bResult = FALSE;
  726. //
  727. // Check if this machine is running standalone, if so, there won't be
  728. // a DNS domain name
  729. //
  730. if (!GetMachineRole (&iRole)) {
  731. DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: Failed to get the role of the computer.")));
  732. return NULL;
  733. }
  734. if (iRole == 0) {
  735. DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Computer is running standalone. No DNS domain name available.")));
  736. return NULL;
  737. }
  738. //
  739. // Get the computer name to see if the user logged on locally
  740. //
  741. dwBufferSize = ARRAYSIZE(szBuffer);
  742. if (GetComputerName (szBuffer, &dwBufferSize)) {
  743. if (!lstrcmpi(lpDomain, szBuffer)) {
  744. DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Local user account. No DNS domain name available.")));
  745. return NULL;
  746. }
  747. }
  748. if (LoadString (g_hDllInstance, IDS_NT_AUTHORITY, szBuffer, ARRAYSIZE(szBuffer))) {
  749. if (!lstrcmpi(lpDomain, szBuffer)) {
  750. DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Domain name is NT Authority. No DNS domain name available.")));
  751. return NULL;
  752. }
  753. }
  754. if (LoadString (g_hDllInstance, IDS_BUILTIN, szBuffer, ARRAYSIZE(szBuffer))) {
  755. if (!lstrcmpi(lpDomain, szBuffer)) {
  756. DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Domain name is BuiltIn. No DNS domain name available.")));
  757. return NULL;
  758. }
  759. }
  760. //
  761. // Impersonate the user
  762. //
  763. if (!ImpersonateUser(hUserToken, &hOldToken)) {
  764. DebugMsg((DM_VERBOSE, TEXT("GetUserDNSDomainName: Failed to impersonate user")));
  765. goto Exit;
  766. }
  767. //
  768. // Get the username in DnsDomainName format
  769. //
  770. lpDnsDomain = MyGetUserNameEx (NameDnsDomain);
  771. RevertToUser(&hOldToken);
  772. if (!lpDnsDomain) {
  773. DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: MyGetUserNameEx failed for NameDnsDomain style name with %d"),
  774. GetLastError()));
  775. goto Exit;
  776. }
  777. //
  778. // Look for the \ between the domain and username and replace
  779. // it with a NULL
  780. //
  781. lpTemp = lpDnsDomain;
  782. while (*lpTemp && (*lpTemp != TEXT('\\')))
  783. lpTemp++;
  784. if (*lpTemp != TEXT('\\')) {
  785. DebugMsg((DM_WARNING, TEXT("GetUserDNSDomainName: Failed to find slash in NameDnsDomain style name: <%s>"),
  786. lpDnsDomain));
  787. goto Exit;
  788. }
  789. *lpTemp = TEXT('\0');
  790. bResult = TRUE;
  791. Exit:
  792. if (!bResult && lpDnsDomain) {
  793. LocalFree(lpDnsDomain);
  794. lpDnsDomain = NULL;
  795. }
  796. return lpDnsDomain;
  797. }
  798. //*************************************************************
  799. //
  800. // GetHKeyCU()
  801. //
  802. // Purpose: Get HKEY_CURRENT_USER for the given hToken
  803. //
  804. // Parameters: hToken - token handle
  805. //
  806. // Return: hKey if successful
  807. // NULL if an error occurs
  808. //
  809. // Comments:
  810. //
  811. // History: Date Author Comment
  812. // 6/21/96 ericflo Created
  813. //
  814. //*************************************************************
  815. LONG GetHKeyCU(HANDLE hToken, HKEY *hKeyCU)
  816. {
  817. LPTSTR lpSidString;
  818. LONG dwError;
  819. *hKeyCU = NULL;
  820. lpSidString = GetSidString (hToken);
  821. if (!lpSidString) {
  822. return GetLastError();
  823. }
  824. dwError = RegOpenKeyEx (HKEY_USERS, lpSidString, 0, KEY_READ, hKeyCU);
  825. if (dwError != ERROR_SUCCESS)
  826. DebugMsg((DM_VERBOSE, TEXT("GetHkeyCU: RegOpenKey failed with error %d"), dwError));
  827. DeleteSidString(lpSidString);
  828. return dwError;
  829. }
  830. /***************************************************************************\
  831. * ProcessAutoexecPath
  832. *
  833. * Creates AutoexecPath environment variable using autoexec.bat
  834. * LpValue may be freed by this routine.
  835. *
  836. * History:
  837. * 06-02-92 Johannec Created.
  838. *
  839. \***************************************************************************/
  840. LPTSTR ProcessAutoexecPath(PVOID pEnv, LPTSTR lpValue, DWORD cb)
  841. {
  842. LPTSTR lpt;
  843. LPTSTR lpStart;
  844. LPTSTR lpPath;
  845. DWORD ccht;
  846. UNICODE_STRING Name;
  847. UNICODE_STRING Value;
  848. BOOL bPrevAutoexecPath;
  849. WCHAR ch;
  850. DWORD dwTemp, dwCount = 0;
  851. ccht = 1024;
  852. lpt = (LPTSTR)LocalAlloc(LPTR, ccht*sizeof(WCHAR));
  853. if (!lpt) {
  854. return(lpValue);
  855. }
  856. *lpt = 0;
  857. lpStart = lpValue;
  858. RtlInitUnicodeString(&Name, AUTOEXECPATH_VARIABLE);
  859. Value.Buffer = (PWCHAR)LocalAlloc(LPTR, ccht*sizeof(WCHAR));
  860. if (!Value.Buffer) {
  861. goto Fail;
  862. }
  863. while (NULL != (lpPath = wcsstr (lpValue, TEXT("%")))) {
  864. if (!_wcsnicmp(lpPath+1, TEXT("PATH%"), 5)) {
  865. //
  866. // check if we have an autoexecpath already set, if not just remove
  867. // the %path%
  868. //
  869. Value.Length = (USHORT)ccht * sizeof(WCHAR);
  870. Value.MaximumLength = (USHORT)ccht * sizeof(WCHAR);
  871. bPrevAutoexecPath = (BOOL)!RtlQueryEnvironmentVariable_U(pEnv, &Name, &Value);
  872. *lpPath = 0;
  873. dwTemp = dwCount + lstrlen (lpValue);
  874. if (dwTemp < ccht) {
  875. StringCchCat(lpt, ccht, lpValue);
  876. dwCount = dwTemp;
  877. }
  878. if (bPrevAutoexecPath) {
  879. dwTemp = dwCount + lstrlen (Value.Buffer);
  880. if (dwTemp < ccht) {
  881. StringCchCat(lpt, ccht, Value.Buffer);
  882. dwCount = dwTemp;
  883. }
  884. }
  885. *lpPath++ = TEXT('%');
  886. lpPath += 5; // go passed %path%
  887. lpValue = lpPath;
  888. }
  889. else {
  890. lpPath = wcsstr(lpPath+1, TEXT("%"));
  891. if (!lpPath) {
  892. lpStart = NULL;
  893. goto Fail;
  894. }
  895. lpPath++;
  896. ch = *lpPath;
  897. *lpPath = 0;
  898. dwTemp = dwCount + lstrlen (lpValue);
  899. if (dwTemp < ccht) {
  900. StringCchCat(lpt, ccht, lpValue);
  901. dwCount = dwTemp;
  902. }
  903. *lpPath = ch;
  904. lpValue = lpPath;
  905. }
  906. }
  907. if (*lpValue) {
  908. dwTemp = dwCount + lstrlen (lpValue);
  909. if (dwTemp < ccht) {
  910. StringCchCat(lpt, ccht, lpValue);
  911. dwCount = dwTemp;
  912. }
  913. }
  914. LocalFree(Value.Buffer);
  915. LocalFree(lpStart);
  916. return(lpt);
  917. Fail:
  918. LocalFree(lpt);
  919. return(lpStart);
  920. }
  921. /***************************************************************************\
  922. * ProcessCommand
  923. *
  924. * History:
  925. * 01-24-92 Johannec Created.
  926. *
  927. \***************************************************************************/
  928. BOOL ProcessCommand(LPSTR lpStart, PVOID *pEnv)
  929. {
  930. LPTSTR lpt, lptt;
  931. LPTSTR lpVariable;
  932. LPTSTR lpValue;
  933. LPTSTR lpExpandedValue = NULL;
  934. WCHAR c;
  935. DWORD cch, cchNeeded;
  936. LPTSTR lpu;
  937. DWORD cchVariable, cchValue;
  938. //
  939. // convert to Unicode
  940. //
  941. lpu = (LPTSTR)LocalAlloc(LPTR, (cch=lstrlenA(lpStart)+1)*sizeof(WCHAR));
  942. if (!lpu) {
  943. return FALSE;
  944. }
  945. if (!MultiByteToWideChar(CP_OEMCP, 0, lpStart, -1, lpu, cch)) {
  946. LocalFree(lpu);
  947. return FALSE;
  948. }
  949. //
  950. // Find environment variable.
  951. //
  952. for (lpt = lpu; *lpt && *lpt == TEXT(' '); lpt++) //skip spaces
  953. ;
  954. if (!*lpt) {
  955. LocalFree (lpu);
  956. return(FALSE);
  957. }
  958. lptt = lpt;
  959. for (; *lpt && *lpt != TEXT(' ') && *lpt != TEXT('='); lpt++) //find end of variable name
  960. ;
  961. c = *lpt;
  962. *lpt = 0;
  963. cchVariable = lstrlen(lptt) + 1;
  964. lpVariable = (LPTSTR)LocalAlloc(LPTR, cchVariable*sizeof(WCHAR));
  965. if (!lpVariable) {
  966. LocalFree (lpu);
  967. return(FALSE);
  968. }
  969. StringCchCopy(lpVariable, cchVariable, lptt);
  970. *lpt = c;
  971. //
  972. // Find environment variable value.
  973. //
  974. for (; *lpt && (*lpt == TEXT(' ') || *lpt == TEXT('=')); lpt++)
  975. ;
  976. if (!*lpt) {
  977. // if we have a blank path statement in the autoexec file,
  978. // then we don't want to pass "PATH" as the environment
  979. // variable because it trashes the system's PATH. Instead
  980. // we want to change the variable AutoexecPath. This would have
  981. // be handled below if a value had been assigned to the
  982. // environment variable.
  983. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL)
  984. {
  985. SetEnvironmentVariableInBlock(pEnv, AUTOEXECPATH_VARIABLE, TEXT(""), TRUE);
  986. }
  987. else
  988. {
  989. SetEnvironmentVariableInBlock(pEnv, lpVariable, TEXT(""), TRUE);
  990. }
  991. LocalFree (lpVariable);
  992. LocalFree (lpu);
  993. return(FALSE);
  994. }
  995. lptt = lpt;
  996. for (; *lpt; lpt++) //find end of varaible value
  997. ;
  998. c = *lpt;
  999. *lpt = 0;
  1000. cchValue = lstrlen(lptt) + 1;
  1001. lpValue = (LPTSTR)LocalAlloc(LPTR, cchValue*sizeof(WCHAR));
  1002. if (!lpValue) {
  1003. LocalFree (lpu);
  1004. LocalFree(lpVariable);
  1005. return(FALSE);
  1006. }
  1007. StringCchCopy(lpValue, cchValue, lptt);
  1008. *lpt = c;
  1009. #ifdef _X86_
  1010. // NEC98
  1011. //
  1012. // If the path includes removable drive,
  1013. // it is assumed that the drive assignment has changed from DOS.
  1014. //
  1015. if (IsNEC_98 &&
  1016. (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL) &&
  1017. IsPathIncludeRemovable(lpValue))
  1018. {
  1019. LocalFree (lpu);
  1020. LocalFree(lpVariable);
  1021. LocalFree(lpValue);
  1022. return(FALSE);
  1023. }
  1024. #endif
  1025. cch = 1024;
  1026. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1027. if (lpExpandedValue) {
  1028. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL)
  1029. {
  1030. lpValue = ProcessAutoexecPath(*pEnv, lpValue, (lstrlen(lpValue)+1)*sizeof(WCHAR));
  1031. }
  1032. cchNeeded = ExpandUserEnvironmentStrings(*pEnv, lpValue, lpExpandedValue, cch);
  1033. if (cchNeeded > cch) {
  1034. LocalFree(lpExpandedValue);
  1035. cch = cchNeeded;
  1036. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1037. if (lpExpandedValue) {
  1038. ExpandUserEnvironmentStrings(*pEnv, lpValue, lpExpandedValue, cch);
  1039. }
  1040. }
  1041. }
  1042. if (!lpExpandedValue) {
  1043. lpExpandedValue = lpValue;
  1044. }
  1045. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpVariable, -1, PATH_VARIABLE, -1) == CSTR_EQUAL)
  1046. {
  1047. SetEnvironmentVariableInBlock(pEnv, AUTOEXECPATH_VARIABLE, lpExpandedValue, TRUE);
  1048. }
  1049. else {
  1050. SetEnvironmentVariableInBlock(pEnv, lpVariable, lpExpandedValue, FALSE);
  1051. }
  1052. if (lpExpandedValue != lpValue) {
  1053. LocalFree(lpExpandedValue);
  1054. }
  1055. LocalFree(lpVariable);
  1056. LocalFree(lpValue);
  1057. LocalFree (lpu);
  1058. return(TRUE);
  1059. }
  1060. /***************************************************************************\
  1061. * ProcessSetCommand
  1062. *
  1063. * History:
  1064. * 01-24-92 Johannec Created.
  1065. *
  1066. \***************************************************************************/
  1067. BOOL ProcessSetCommand(LPSTR lpStart, PVOID *pEnv)
  1068. {
  1069. LPSTR lpt;
  1070. //
  1071. // Find environment variable.
  1072. //
  1073. for (lpt = lpStart; *lpt && *lpt != TEXT(' '); lpt++)
  1074. ;
  1075. if (!*lpt)
  1076. return(FALSE);
  1077. return (ProcessCommand(lpt, pEnv));
  1078. }
  1079. /***************************************************************************\
  1080. * ProcessAutoexec
  1081. *
  1082. * History:
  1083. * 01-24-92 Johannec Created.
  1084. *
  1085. \***************************************************************************/
  1086. BOOL
  1087. ProcessAutoexec(
  1088. PVOID *pEnv
  1089. )
  1090. {
  1091. HANDLE fh = NULL;
  1092. DWORD dwFileSize;
  1093. DWORD dwBytesRead;
  1094. CHAR *lpBuffer = NULL;
  1095. CHAR *token;
  1096. CHAR Seps[] = "&\n\r"; // Seperators for tokenizing autoexec.bat
  1097. BOOL Status = FALSE;
  1098. TCHAR szAutoExecBat [] = TEXT("c:\\autoexec.bat");
  1099. #ifdef _X86_
  1100. TCHAR szTemp[3];
  1101. #endif
  1102. UINT uiErrMode;
  1103. // There is a case where the OS might not be booting from drive
  1104. // C, so we can not assume that the autoexec.bat file is on c:\.
  1105. // Set the error mode so the user doesn't see the critical error
  1106. // popup and attempt to open the file on c:\.
  1107. uiErrMode = SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
  1108. #ifdef _X86_
  1109. if (IsNEC_98) {
  1110. if (GetEnvironmentVariable (TEXT("SystemDrive"), szTemp, 3)) {
  1111. szAutoExecBat[0] = szTemp[0];
  1112. }
  1113. }
  1114. #endif
  1115. // if autoexec.bat is encrypted then ignore it as it creates cyclic-dependency
  1116. // and don't allow any user to logon
  1117. if (GetFileAttributes(szAutoExecBat) & FILE_ATTRIBUTE_ENCRYPTED) {
  1118. SetErrorMode(uiErrMode);
  1119. goto Exit;
  1120. }
  1121. fh = CreateFile (szAutoExecBat, GENERIC_READ, FILE_SHARE_READ,
  1122. NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  1123. SetErrorMode (uiErrMode);
  1124. if (fh == INVALID_HANDLE_VALUE) {
  1125. goto Exit; //could not open autoexec.bat file, we're done.
  1126. }
  1127. dwFileSize = GetFileSize(fh, NULL);
  1128. if (dwFileSize == -1) {
  1129. goto Exit; // can't read the file size
  1130. }
  1131. lpBuffer = (PCHAR)LocalAlloc(LPTR, dwFileSize+1);
  1132. if (!lpBuffer) {
  1133. goto Exit;
  1134. }
  1135. Status = ReadFile(fh, lpBuffer, dwFileSize, &dwBytesRead, NULL);
  1136. if (!Status) {
  1137. goto Exit; // error reading file
  1138. }
  1139. //
  1140. // Zero terminate the buffer so we don't walk off the end
  1141. //
  1142. DmAssert(dwBytesRead <= dwFileSize);
  1143. lpBuffer[dwBytesRead] = 0;
  1144. //
  1145. // Search for SET and PATH commands
  1146. //
  1147. token = strtok(lpBuffer, Seps);
  1148. while (token != NULL) {
  1149. for (;*token && *token == ' ';token++) //skip spaces
  1150. ;
  1151. if (*token == TEXT('@'))
  1152. token++;
  1153. for (;*token && *token == ' ';token++) //skip spaces
  1154. ;
  1155. if (!_strnicmp(token, "Path", 4)) {
  1156. ProcessCommand(token, pEnv);
  1157. }
  1158. if (!_strnicmp(token, "SET", 3)) {
  1159. ProcessSetCommand(token, pEnv);
  1160. }
  1161. token = strtok(NULL, Seps);
  1162. }
  1163. Exit:
  1164. if (fh) {
  1165. CloseHandle(fh);
  1166. }
  1167. if (lpBuffer) {
  1168. LocalFree(lpBuffer);
  1169. }
  1170. if (!Status) {
  1171. DebugMsg((DM_WARNING, TEXT("ProcessAutoexec: Cannot process autoexec.bat.")));
  1172. }
  1173. return(Status);
  1174. }
  1175. /***************************************************************************\
  1176. * BuildEnvironmentPath
  1177. *
  1178. *
  1179. * History:
  1180. * 2-28-92 Johannec Created
  1181. *
  1182. \***************************************************************************/
  1183. BOOL BuildEnvironmentPath(PVOID *pEnv,
  1184. LPTSTR lpPathVariable,
  1185. LPTSTR lpPathValue)
  1186. {
  1187. NTSTATUS Status;
  1188. UNICODE_STRING Name;
  1189. UNICODE_STRING Value;
  1190. WCHAR lpTemp[1025];
  1191. DWORD cch;
  1192. if (!*pEnv) {
  1193. return(FALSE);
  1194. }
  1195. RtlInitUnicodeString(&Name, lpPathVariable);
  1196. cch = 1024;
  1197. Value.Buffer = (PWCHAR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1198. if (!Value.Buffer) {
  1199. return(FALSE);
  1200. }
  1201. Value.Length = (USHORT)(sizeof(WCHAR) * cch);
  1202. Value.MaximumLength = (USHORT)(sizeof(WCHAR) * cch);
  1203. Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value);
  1204. if (!NT_SUCCESS(Status)) {
  1205. LocalFree(Value.Buffer);
  1206. Value.Length = 0;
  1207. *lpTemp = 0;
  1208. }
  1209. if (Value.Length) {
  1210. StringCchCopy(lpTemp, ARRAYSIZE(lpTemp), Value.Buffer);
  1211. if ( *( lpTemp + lstrlen(lpTemp) - 1) != TEXT(';') ) {
  1212. StringCchCat(lpTemp, ARRAYSIZE(lpTemp), TEXT(";"));
  1213. }
  1214. LocalFree(Value.Buffer);
  1215. }
  1216. if (lpPathValue && ((lstrlen(lpTemp) + lstrlen(lpPathValue) + 1) < (INT)cch)) {
  1217. StringCchCat(lpTemp, ARRAYSIZE(lpTemp), lpPathValue);
  1218. RtlInitUnicodeString(&Value, lpTemp);
  1219. Status = RtlSetEnvironmentVariable(pEnv, &Name, &Value);
  1220. }
  1221. if (NT_SUCCESS(Status)) {
  1222. return(TRUE);
  1223. }
  1224. return(FALSE);
  1225. }
  1226. /***************************************************************************\
  1227. * AppendNTPathWithAutoexecPath
  1228. *
  1229. * Gets the AutoexecPath created in ProcessAutoexec, and appends it to
  1230. * the NT path.
  1231. *
  1232. * History:
  1233. * 05-28-92 Johannec Created.
  1234. *
  1235. \***************************************************************************/
  1236. BOOL
  1237. AppendNTPathWithAutoexecPath(
  1238. PVOID *pEnv,
  1239. LPTSTR lpPathVariable,
  1240. LPTSTR lpAutoexecPath
  1241. )
  1242. {
  1243. NTSTATUS Status;
  1244. UNICODE_STRING Name;
  1245. UNICODE_STRING Value;
  1246. WCHAR AutoexecPathValue[1024];
  1247. DWORD cch;
  1248. BOOL Success;
  1249. if (!*pEnv) {
  1250. return(FALSE);
  1251. }
  1252. RtlInitUnicodeString(&Name, lpAutoexecPath);
  1253. cch = 1024;
  1254. Value.Buffer = (PWCHAR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1255. if (!Value.Buffer) {
  1256. return(FALSE);
  1257. }
  1258. Value.Length = (USHORT)cch*sizeof(WCHAR);
  1259. Value.MaximumLength = (USHORT)cch*sizeof(WCHAR);
  1260. Status = RtlQueryEnvironmentVariable_U(*pEnv, &Name, &Value);
  1261. if (!NT_SUCCESS(Status)) {
  1262. LocalFree(Value.Buffer);
  1263. return(FALSE);
  1264. }
  1265. if (Value.Length) {
  1266. StringCchCopy(AutoexecPathValue, ARRAYSIZE(AutoexecPathValue), Value.Buffer);
  1267. }
  1268. LocalFree(Value.Buffer);
  1269. Success = BuildEnvironmentPath(pEnv, lpPathVariable, AutoexecPathValue);
  1270. RtlSetEnvironmentVariable( pEnv, &Name, NULL);
  1271. return(Success);
  1272. }
  1273. /***************************************************************************\
  1274. * SetEnvironmentVariables
  1275. *
  1276. * Reads the user-defined environment variables from the user registry
  1277. * and adds them to the environment block at pEnv.
  1278. *
  1279. * History:
  1280. * 2-28-92 Johannec Created
  1281. *
  1282. \***************************************************************************/
  1283. BOOL
  1284. SetEnvironmentVariables(
  1285. PVOID *pEnv,
  1286. LPTSTR lpRegSubKey,
  1287. HKEY hKeyCU
  1288. )
  1289. {
  1290. WCHAR lpValueName[MAX_PATH];
  1291. LPBYTE lpDataBuffer;
  1292. DWORD cchDataBuffer;
  1293. LPBYTE lpData;
  1294. LPTSTR lpExpandedValue = NULL;
  1295. DWORD cchValueName = MAX_PATH;
  1296. DWORD cbData;
  1297. DWORD dwType;
  1298. DWORD dwIndex = 0;
  1299. HKEY hkey;
  1300. BOOL bResult;
  1301. if (RegOpenKeyExW(hKeyCU, lpRegSubKey, 0, KEY_READ, &hkey)) {
  1302. return(FALSE);
  1303. }
  1304. cchDataBuffer = 4096;
  1305. lpDataBuffer = (LPBYTE)LocalAlloc(LPTR, cchDataBuffer*sizeof(WCHAR));
  1306. if (lpDataBuffer == NULL) {
  1307. RegCloseKey(hkey);
  1308. return(FALSE);
  1309. }
  1310. lpData = lpDataBuffer;
  1311. cbData = cchDataBuffer * sizeof(WCHAR);
  1312. bResult = TRUE;
  1313. while (!RegEnumValue(hkey, dwIndex, lpValueName, &cchValueName, 0, &dwType,
  1314. lpData, &cbData)) {
  1315. if (cchValueName) {
  1316. //
  1317. // Limit environment variable length
  1318. //
  1319. lpData[MAX_VALUE_LEN-1] = TEXT('\0');
  1320. if (dwType == REG_SZ) {
  1321. //
  1322. // The path variables PATH, LIBPATH and OS2LIBPATH must have
  1323. // their values apppended to the system path.
  1324. //
  1325. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, PATH_VARIABLE, -1) == CSTR_EQUAL ||
  1326. CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, LIBPATH_VARIABLE, -1) == CSTR_EQUAL ||
  1327. CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, OS2LIBPATH_VARIABLE, -1) == CSTR_EQUAL ) {
  1328. BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpData);
  1329. }
  1330. else {
  1331. //
  1332. // the other environment variables are just set.
  1333. //
  1334. SetEnvironmentVariableInBlock(pEnv, lpValueName, (LPTSTR)lpData, TRUE);
  1335. }
  1336. }
  1337. }
  1338. dwIndex++;
  1339. cbData = cchDataBuffer * sizeof(WCHAR);
  1340. cchValueName = MAX_PATH;
  1341. }
  1342. dwIndex = 0;
  1343. cbData = cchDataBuffer * sizeof(WCHAR);
  1344. cchValueName = MAX_PATH;
  1345. while (!RegEnumValue(hkey, dwIndex, lpValueName, &cchValueName, 0, &dwType,
  1346. lpData, &cbData)) {
  1347. if (cchValueName) {
  1348. //
  1349. // Limit environment variable length
  1350. //
  1351. lpData[MAX_VALUE_LEN-1] = TEXT('\0');
  1352. if (dwType == REG_EXPAND_SZ) {
  1353. DWORD cch, cchNeeded;
  1354. cch = 1024;
  1355. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1356. if (lpExpandedValue) {
  1357. cchNeeded = ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cch);
  1358. if (cchNeeded > cch) {
  1359. LocalFree(lpExpandedValue);
  1360. cch = cchNeeded;
  1361. lpExpandedValue = (LPTSTR)LocalAlloc(LPTR, cch*sizeof(WCHAR));
  1362. if (lpExpandedValue) {
  1363. ExpandUserEnvironmentStrings(*pEnv, (LPTSTR)lpData, lpExpandedValue, cch);
  1364. }
  1365. }
  1366. }
  1367. if (lpExpandedValue == NULL) {
  1368. bResult = FALSE;
  1369. break;
  1370. }
  1371. //
  1372. // The path variables PATH, LIBPATH and OS2LIBPATH must have
  1373. // their values apppended to the system path.
  1374. //
  1375. if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, PATH_VARIABLE, -1) == CSTR_EQUAL ||
  1376. CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, LIBPATH_VARIABLE, -1) == CSTR_EQUAL ||
  1377. CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, lpValueName, -1, OS2LIBPATH_VARIABLE, -1) == CSTR_EQUAL ) {
  1378. BuildEnvironmentPath(pEnv, lpValueName, (LPTSTR)lpExpandedValue);
  1379. }
  1380. else {
  1381. //
  1382. // the other environment variables are just set.
  1383. //
  1384. SetEnvironmentVariableInBlock(pEnv, lpValueName, (LPTSTR)lpExpandedValue, TRUE);
  1385. }
  1386. LocalFree(lpExpandedValue);
  1387. }
  1388. }
  1389. dwIndex++;
  1390. cbData = cchDataBuffer * sizeof(WCHAR);
  1391. cchValueName = MAX_PATH;
  1392. }
  1393. LocalFree(lpDataBuffer);
  1394. RegCloseKey(hkey);
  1395. return(bResult);
  1396. }
  1397. //*************************************************************
  1398. //
  1399. // ExpandEnvironmentStringsForUser()
  1400. //
  1401. // Purpose: Expands the source string using the environment block for the
  1402. // specified user. If hToken is null, the system environment block
  1403. // will be used (no user environment variables).
  1404. //
  1405. // Parameters: hToken - User's token (or null for system env vars)
  1406. // lpSrc - String to be expanded
  1407. // lpDest - Buffer to receive string
  1408. // dwSize - Size of dest buffer
  1409. //
  1410. // Return: TRUE if successful
  1411. // FALSE if an error occurs
  1412. //
  1413. //*************************************************************
  1414. BOOL WINAPI ExpandEnvironmentStringsForUser(HANDLE hToken, LPCTSTR lpSrc,
  1415. LPTSTR lpDest, DWORD dwSize)
  1416. {
  1417. LPVOID pEnv;
  1418. DWORD dwNeeded;
  1419. BOOL bResult = FALSE;
  1420. //
  1421. // Arg check
  1422. //
  1423. if ( !lpDest || !lpSrc )
  1424. {
  1425. SetLastError (ERROR_INVALID_PARAMETER);
  1426. return FALSE;
  1427. }
  1428. //
  1429. // Get the user's environment block
  1430. //
  1431. if (!CreateEnvironmentBlock (&pEnv, hToken, FALSE)) {
  1432. DebugMsg((DM_WARNING, TEXT("ExpandEnvironmentStringsForUser: CreateEnvironmentBlock failed with = %d"),
  1433. GetLastError()));
  1434. return FALSE;
  1435. }
  1436. //
  1437. // Expand the string
  1438. //
  1439. dwNeeded = ExpandUserEnvironmentStrings(pEnv, lpSrc, lpDest, dwSize);
  1440. if (dwNeeded && (dwNeeded < dwSize)) {
  1441. bResult = TRUE;
  1442. } else {
  1443. SetLastError(ERROR_INSUFFICIENT_BUFFER );
  1444. }
  1445. //
  1446. // Free the environment block
  1447. //
  1448. DestroyEnvironmentBlock (pEnv);
  1449. return bResult;
  1450. }
  1451. //*************************************************************
  1452. //
  1453. // GetSystemTempDirectory()
  1454. //
  1455. // Purpose: Gets the system temp directory in short form
  1456. //
  1457. // Parameters: lpDir - Receives the directory
  1458. // lpcchSize - Size of the lpDir buffer
  1459. //
  1460. //
  1461. // Return: TRUE if successful
  1462. // FALSE if an error occurs
  1463. //
  1464. //*************************************************************
  1465. BOOL WINAPI GetSystemTempDirectory(LPTSTR lpDir, LPDWORD lpcchSize)
  1466. {
  1467. TCHAR szTemp[MAX_PATH];
  1468. TCHAR szDirectory[MAX_PATH];
  1469. DWORD dwLength;
  1470. HKEY hKey;
  1471. LONG lResult;
  1472. DWORD dwSize, dwType;
  1473. BOOL bRetVal = FALSE;
  1474. WIN32_FILE_ATTRIBUTE_DATA fad;
  1475. HRESULT hr;
  1476. szTemp[0] = TEXT('\0');
  1477. szDirectory[0] = TEXT('\0');
  1478. //
  1479. // Look in the system environment variables
  1480. //
  1481. if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, SYS_ENVVARS, 0,
  1482. KEY_READ, &hKey) == ERROR_SUCCESS) {
  1483. //
  1484. // Check for TEMP
  1485. //
  1486. dwSize = sizeof(szTemp);
  1487. if (RegQueryValueEx (hKey, TEXT("TEMP"), NULL, &dwType,
  1488. (LPBYTE) szTemp, &dwSize) == ERROR_SUCCESS) {
  1489. RegCloseKey (hKey);
  1490. goto FoundTemp;
  1491. }
  1492. //
  1493. // Check for TMP
  1494. //
  1495. dwSize = sizeof(szTemp);
  1496. if (RegQueryValueEx (hKey, TEXT("TMP"), NULL, &dwType,
  1497. (LPBYTE) szTemp, &dwSize) == ERROR_SUCCESS) {
  1498. RegCloseKey (hKey);
  1499. goto FoundTemp;
  1500. }
  1501. RegCloseKey (hKey);
  1502. }
  1503. //
  1504. // Check if %SystemRoot%\Temp exists
  1505. //
  1506. StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), TEXT("%SystemRoot%\\Temp"));
  1507. if (FAILED(hr = SafeExpandEnvironmentStrings (szDirectory, szTemp, ARRAYSIZE (szTemp))))
  1508. {
  1509. SetLastError(HRESULT_CODE(hr));
  1510. goto Exit;
  1511. }
  1512. if (GetFileAttributesEx (szTemp, GetFileExInfoStandard, &fad) &&
  1513. fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  1514. goto FoundTemp;
  1515. }
  1516. //
  1517. // Check if %SystemDrive%\Temp exists
  1518. //
  1519. StringCchCopy (szDirectory, ARRAYSIZE(szDirectory), TEXT("%SystemDrive%\\Temp"));
  1520. if (FAILED(hr = SafeExpandEnvironmentStrings (szDirectory, szTemp, ARRAYSIZE (szTemp))))
  1521. {
  1522. SetLastError(HRESULT_CODE(hr));
  1523. goto Exit;
  1524. }
  1525. if (GetFileAttributesEx (szTemp, GetFileExInfoStandard, &fad) &&
  1526. fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  1527. goto FoundTemp;
  1528. }
  1529. //
  1530. // Last resort is %SystemRoot%
  1531. //
  1532. StringCchCopy (szTemp, ARRAYSIZE (szTemp), TEXT("%SystemRoot%"));
  1533. FoundTemp:
  1534. if (FAILED(hr = SafeExpandEnvironmentStrings (szTemp, szDirectory, ARRAYSIZE (szDirectory))))
  1535. {
  1536. SetLastError(HRESULT_CODE(hr));
  1537. goto Exit;
  1538. }
  1539. dwLength = GetShortPathName (szDirectory, szTemp, ARRAYSIZE(szTemp));
  1540. if (dwLength > ARRAYSIZE(szTemp) || dwLength == 0)
  1541. {
  1542. goto Exit;
  1543. }
  1544. dwLength = lstrlen(szTemp) + 1;
  1545. if (lpDir) {
  1546. if (*lpcchSize >= dwLength) {
  1547. StringCchCopy (lpDir, *lpcchSize, szTemp);
  1548. bRetVal = TRUE;
  1549. } else {
  1550. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1551. }
  1552. } else {
  1553. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  1554. }
  1555. *lpcchSize = dwLength;
  1556. Exit:
  1557. return bRetVal;
  1558. }
  1559. #ifdef _X86_
  1560. BOOL
  1561. IsPathIncludeRemovable(LPTSTR lpValue)
  1562. {
  1563. LPTSTR lpt, tmp;
  1564. BOOL ret = FALSE;
  1565. WCHAR c;
  1566. DWORD cchTmp;
  1567. cchTmp = lstrlen(lpValue) + 1;
  1568. tmp = LocalAlloc(LPTR, cchTmp * sizeof(WCHAR));
  1569. if (!tmp) {
  1570. DebugMsg((DM_WARNING, TEXT("IsPathIncludeRemovable : Failed to LocalAlloc (%d)"), GetLastError()));
  1571. }
  1572. else {
  1573. StringCchCopy(tmp, cchTmp, lpValue);
  1574. lpt = tmp;
  1575. while (*lpt) {
  1576. // skip spaces
  1577. for ( ; *lpt && *lpt == TEXT(' '); lpt++)
  1578. ;
  1579. // check if the drive is removable
  1580. if (lpt[0] && lpt[1] && lpt[1] == TEXT(':') && lpt[2]) { // ex) "A:\"
  1581. c = lpt[3];
  1582. lpt[3] = 0;
  1583. if (GetDriveType(lpt) == DRIVE_REMOVABLE) {
  1584. lpt[3] = c;
  1585. ret = TRUE;
  1586. break;
  1587. }
  1588. lpt[3] = c;
  1589. }
  1590. // skip to the next path
  1591. for ( ; *lpt && *lpt != TEXT(';'); lpt++)
  1592. ;
  1593. if (*lpt)
  1594. lpt++;
  1595. }
  1596. LocalFree(tmp);
  1597. }
  1598. return(ret);
  1599. }
  1600. #endif