Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

594 lines
12 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. /*++
  4. Copyright (c) 1990 Microsoft Corporation
  5. Module Name:
  6. registry.c
  7. Abstract:
  8. Registry related functions in the setupdll
  9. Detect Routines:
  10. ----------------
  11. 1. GetEnvVar <SYSTEM | USER> <VARNAME> returns
  12. List <ValueName, ValueTitle, ValueRegType, ValueData>
  13. The value data is decomposed into a list of the elements:
  14. e.g. val1;val2;val3 becomes {val1, val2, val3}
  15. 2. GetMyComputerName
  16. Install Routines Workers:
  17. -------------------------
  18. 2. SetEnvVarWorker: To set a USER or SYSTEM environment variable
  19. 3. ExpandSzWorker: To expand all the expand sz components in an
  20. environment string.
  21. General Subroutines:
  22. --------------------
  23. 1. GetValueEntry: To fetch a value entry given a key and a value name
  24. This is useful when we don't know the size of the
  25. value entry.
  26. 2. GetMaxSizeValueInKey: This is to find the maximum size needed to
  27. query a value in the key.
  28. Author:
  29. Sunil Pai (sunilp) April 1992
  30. --*/
  31. extern CHAR ReturnTextBuffer[];
  32. //
  33. // Detect Routines
  34. //
  35. CB
  36. GetEnvVar(
  37. IN RGSZ Args,
  38. IN USHORT cArgs,
  39. OUT SZ ReturnBuffer,
  40. IN CB cbReturnBuffer
  41. )
  42. {
  43. SZ sz, sz1, szEnv;
  44. HKEY hKey, hRootKey;
  45. DWORD cbData;
  46. CB Length;
  47. LONG Status;
  48. DWORD ValueType;
  49. PVOID ValueData;
  50. CHAR szValueType[25];
  51. RGSZ rgsz;
  52. #define UNDEF_VAR_VALUE "{}"
  53. Unused( cbReturnBuffer );
  54. //
  55. // If the environment variable cannot be determine we
  56. // return the empty list as the value of this call.
  57. // Initialise this anyway to avoid doing this at a
  58. // a number of places.
  59. //
  60. lstrcpy( ReturnBuffer, UNDEF_VAR_VALUE );
  61. Length = lstrlen( UNDEF_VAR_VALUE ) + 1;
  62. //
  63. // Do parameter validation
  64. //
  65. if( cArgs < 2 ) {
  66. return( Length );
  67. }
  68. //
  69. // Check to see if the user wants a system environment variable or
  70. // a user environment variable. Accordingly find out the right
  71. // place in the registry to look.
  72. //
  73. if ( !lstrcmpi( Args[0], "SYSTEM" ) ) {
  74. hRootKey = HKEY_LOCAL_MACHINE;
  75. szEnv = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
  76. }
  77. else if ( !lstrcmpi( Args[0], "USER" ) ) {
  78. hRootKey = HKEY_CURRENT_USER;
  79. szEnv = "Environment";
  80. }
  81. else {
  82. return( Length );
  83. }
  84. //
  85. // Open the environment variable key.
  86. //
  87. Status = RegOpenKeyEx(
  88. hRootKey,
  89. szEnv,
  90. 0,
  91. KEY_READ,
  92. &hKey
  93. );
  94. if( Status != ERROR_SUCCESS ) {
  95. return( Length );
  96. }
  97. //
  98. // Get the environment variable value
  99. //
  100. if( !GetMaxSizeValueInKey( hKey, &cbData ) ||
  101. ( ValueData = SAlloc( cbData ) ) == NULL
  102. ) {
  103. RegCloseKey( hKey );
  104. return( Length );
  105. }
  106. Status = RegQueryValueEx(
  107. hKey,
  108. Args[1],
  109. NULL,
  110. &ValueType,
  111. ValueData,
  112. &cbData
  113. );
  114. RegCloseKey( hKey );
  115. if (Status != ERROR_SUCCESS) {
  116. SFree( ValueData );
  117. return( Length );
  118. }
  119. if ( ( sz = SzListValueFromPath( (SZ)ValueData ) ) == NULL ) {
  120. SFree( ValueData );
  121. return( Length );
  122. }
  123. SFree( ValueData );
  124. _ultoa( ValueType, szValueType, 10 );
  125. //
  126. // Allocate an Rgsz structure: (Note same style as internal registry usage)
  127. //
  128. // Field 0: EnvVarValueName
  129. // Field 1: EnvVarTitleIndex "0"
  130. // Field 2: EnvVarValueType
  131. // Field 3: EnvVarValue
  132. //
  133. if ( rgsz = RgszAlloc( 5 ) ) {
  134. rgsz[0] = Args[1];
  135. rgsz[1] = "0";
  136. rgsz[2] = szValueType;
  137. rgsz[3] = sz;
  138. rgsz[4] = NULL;
  139. sz1 = SzListValueFromRgsz( rgsz );
  140. if( sz1 ) {
  141. lstrcpy( ReturnBuffer, sz1 );
  142. Length = lstrlen( sz1 ) + 1;
  143. SFree( sz1 );
  144. }
  145. SFree( rgsz );
  146. }
  147. SFree( sz );
  148. return( Length );
  149. }
  150. CB
  151. GetMyComputerName(
  152. IN RGSZ Args,
  153. IN USHORT cArgs,
  154. OUT SZ ReturnBuffer,
  155. IN CB cbReturnBuffer
  156. )
  157. /*++
  158. Routine Description:
  159. DetectRoutine for GetComputerName. This finds out the computername of
  160. this machine in the current control set.
  161. Arguments:
  162. Args - C argument list to this detect routine (None exist)
  163. cArgs - Number of arguments.
  164. ReturnBuffer - Buffer in which detected value is returned.
  165. cbReturnBuffer - Buffer Size.
  166. Return value:
  167. Returns length of detected value.
  168. --*/
  169. {
  170. CHAR ComputerName[MAX_PATH];
  171. DWORD nSize = MAX_PATH;
  172. BOOL bStatus = FALSE;
  173. CB Length;
  174. #define DEFAULT_COMPUTERNAME ""
  175. Unused(Args);
  176. Unused(cArgs);
  177. Unused(cbReturnBuffer);
  178. if( GetComputerName( ComputerName, &nSize ) ) {
  179. lstrcpy( ReturnBuffer, ComputerName );
  180. Length = lstrlen( ComputerName ) + 1;
  181. }
  182. else {
  183. lstrcpy( ReturnBuffer, DEFAULT_COMPUTERNAME );
  184. Length = lstrlen( DEFAULT_COMPUTERNAME ) + 1;
  185. }
  186. return( Length );
  187. }
  188. //
  189. // Install Routines
  190. //
  191. BOOL
  192. SetEnvVarWorker(
  193. LPSTR UserOrSystem,
  194. LPSTR Name,
  195. LPSTR Title,
  196. LPSTR RegType,
  197. LPSTR Data
  198. )
  199. {
  200. HKEY hKey, hRootKey;
  201. SZ szEnv;
  202. LONG Status;
  203. Unused(Title);
  204. //
  205. // Check to see if the user wants to modify a system environment variable
  206. // or a user environment variable. Accordingly find out the right
  207. // place in the registry to look.
  208. //
  209. if ( !lstrcmpi( UserOrSystem, "SYSTEM" ) ) {
  210. hRootKey = HKEY_LOCAL_MACHINE;
  211. szEnv = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment";
  212. }
  213. else if ( !lstrcmpi( UserOrSystem, "USER" ) ) {
  214. hRootKey = HKEY_CURRENT_USER;
  215. szEnv = "Environment";
  216. }
  217. else {
  218. return( FALSE );
  219. }
  220. //
  221. // Open the environment variable key.
  222. //
  223. Status = RegOpenKeyEx(
  224. hRootKey,
  225. szEnv,
  226. 0,
  227. KEY_WRITE,
  228. &hKey
  229. );
  230. if( Status != ERROR_SUCCESS ) {
  231. SetErrorText( IDS_ERROR_REGOPEN );
  232. return( FALSE );
  233. }
  234. //
  235. // Write the value given
  236. //
  237. Status = RegSetValueEx(
  238. hKey,
  239. Name,
  240. 0,
  241. (DWORD)atol( RegType ),
  242. (LPBYTE)Data,
  243. lstrlen( Data ) + 1
  244. );
  245. RegCloseKey( hKey );
  246. if( Status != ERROR_SUCCESS ) {
  247. SetErrorText( IDS_ERROR_REGSETVALUE );
  248. return( FALSE );
  249. }
  250. //
  251. // Send a WM_WININICHANGE message so that progman picks up the new
  252. // variable
  253. //
  254. SendMessageTimeout(
  255. (HWND)-1,
  256. WM_WININICHANGE,
  257. 0,
  258. (LPARAM)"Environment",
  259. SMTO_ABORTIFHUNG,
  260. 1000,
  261. NULL
  262. );
  263. return( TRUE );
  264. }
  265. BOOL
  266. ExpandSzWorker(
  267. LPSTR EnvironmentString,
  268. LPSTR ReturnBuffer,
  269. DWORD cbReturnBuffer
  270. )
  271. {
  272. DWORD cbBuffer;
  273. cbBuffer = ExpandEnvironmentStrings(
  274. (LPCSTR)EnvironmentString,
  275. ReturnBuffer,
  276. cbReturnBuffer
  277. );
  278. if ( cbBuffer > cbReturnBuffer ) {
  279. SetErrorText( IDS_BUFFER_OVERFLOW );
  280. return( FALSE );
  281. }
  282. return( TRUE );
  283. }
  284. BOOL
  285. SetMyComputerNameWorker(
  286. LPSTR ComputerName
  287. )
  288. /*++
  289. Routine Description:
  290. To set the computername value in the services tree.
  291. Arguments:
  292. ComputerName - Value to set as the computername
  293. Return value:
  294. TRUE if successful, FALSE otherwise.
  295. --*/
  296. {
  297. if( !SetComputerName( ComputerName ) ) {
  298. SetErrorText(IDS_ERROR_SETCOMPUTERNAME);
  299. return( FALSE );
  300. }
  301. return( TRUE );
  302. }
  303. //=====================================================================
  304. // The following are registry access subroutines..
  305. //=====================================================================
  306. BOOL
  307. GetMaxSizeValueInKey(
  308. HKEY hKey,
  309. LPDWORD cbData
  310. )
  311. {
  312. LONG Status;
  313. CHAR szKClass[ MAX_PATH ];
  314. DWORD cbKClass = MAX_PATH;
  315. DWORD KSubKeys;
  316. DWORD cbKMaxSubKeyLen;
  317. DWORD cbKMaxClassLen;
  318. DWORD KValues;
  319. DWORD cbKMaxValueNameLen;
  320. DWORD SizeSecurityDescriptor;
  321. FILETIME KLastWriteTime;
  322. Status = RegQueryInfoKey (
  323. hKey,
  324. szKClass,
  325. &cbKClass,
  326. NULL,
  327. &KSubKeys,
  328. &cbKMaxSubKeyLen,
  329. &cbKMaxClassLen,
  330. &KValues,
  331. &cbKMaxValueNameLen,
  332. cbData,
  333. &SizeSecurityDescriptor,
  334. &KLastWriteTime
  335. );
  336. if (Status != ERROR_SUCCESS) {
  337. return( FALSE );
  338. }
  339. return( TRUE );
  340. }
  341. PVOID
  342. GetValueEntry(
  343. HKEY hKey,
  344. LPSTR szValueName
  345. )
  346. {
  347. LONG Status;
  348. CHAR szKClass[ MAX_PATH ];
  349. DWORD cbKClass = MAX_PATH;
  350. DWORD KSubKeys;
  351. DWORD cbKMaxSubKeyLen;
  352. DWORD cbKMaxClassLen;
  353. DWORD KValues;
  354. DWORD cbKMaxValueNameLen;
  355. DWORD cbData;
  356. DWORD SizeSecurityDescriptor;
  357. FILETIME KLastWriteTime;
  358. DWORD ValueType;
  359. PVOID ValueData;
  360. Status = RegQueryInfoKey (
  361. hKey,
  362. szKClass,
  363. &cbKClass,
  364. NULL,
  365. &KSubKeys,
  366. &cbKMaxSubKeyLen,
  367. &cbKMaxClassLen,
  368. &KValues,
  369. &cbKMaxValueNameLen,
  370. &cbData,
  371. &SizeSecurityDescriptor,
  372. &KLastWriteTime
  373. );
  374. if (Status != ERROR_SUCCESS) {
  375. return( NULL );
  376. }
  377. if ( ( ValueData = SAlloc( cbData ) ) == NULL ) {
  378. return( NULL );
  379. }
  380. Status = RegQueryValueEx(
  381. hKey,
  382. szValueName,
  383. NULL,
  384. &ValueType,
  385. ValueData,
  386. &cbData
  387. );
  388. if (Status != ERROR_SUCCESS) {
  389. SFree( ValueData );
  390. return( NULL );
  391. }
  392. else {
  393. return( ValueData );
  394. }
  395. }
  396. BOOL
  397. GenerateUniqueFileName(
  398. IN LPSTR TempPath,
  399. IN LPSTR Prefix,
  400. IN OUT LPSTR TempFile
  401. )
  402. /*++
  403. Routine Description:
  404. To generate a unique filename (with no extension) in the TempPath
  405. Directory with the Prefix given and digits from 1 to 99999
  406. Arguments:
  407. TempPath - string containing a valid directory path ending
  408. in a backslash.
  409. Prefix - a prefix string no longer than 3 characters.
  410. TempFile - buffer to return the full path to the temp file
  411. Return value:
  412. TRUE if succeds in finding, FALSE otherwise. If TRUE, TempFile buffer
  413. has the full path to the temp file.
  414. --*/
  415. {
  416. CHAR Number[6];
  417. DWORD i;
  418. //
  419. // Check parameters
  420. //
  421. if ( TempPath == (LPSTR)NULL
  422. || Prefix == (LPSTR)NULL
  423. || TempFile == (LPSTR)NULL
  424. || lstrlen( Prefix ) > 3
  425. ) {
  426. return( FALSE );
  427. }
  428. //
  429. // go through all numbers upto 5 digits long looking
  430. // for file which doesn't exist
  431. //
  432. for( i = 1; i <99999; i++ ) {
  433. lstrcpy( TempFile, TempPath);
  434. lstrcat( TempFile, "\\" );
  435. lstrcat( TempFile, Prefix );
  436. sprintf( Number, "%d", i );
  437. lstrcat( TempFile, Number );
  438. if (!FFileExist( TempFile ) ) {
  439. return( TRUE );
  440. }
  441. }
  442. //
  443. // not found, return false
  444. //
  445. return( FALSE );
  446. }