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.

342 lines
11 KiB

  1. //------------------------------------------------------------------------------------
  2. //
  3. // File: REGUTILS.CPP
  4. //
  5. // Helper functions that handle reading and writing strings to the system registry.
  6. //
  7. //------------------------------------------------------------------------------------
  8. #include "precomp.hxx"
  9. #pragma hdrstop
  10. #define MAX_VALUELEN 16
  11. const TCHAR c_szSoftwareClassesFmt[] = TEXT("Software\\Classes\\%s");
  12. // our own atoi function so we don't have to link to the C runtimes...
  13. INT AtoI( LPTSTR pValue )
  14. {
  15. INT i = 0;
  16. INT iSign = 1;
  17. while( pValue && *pValue )
  18. {
  19. if (*pValue == TEXT('-'))
  20. {
  21. iSign = -1;
  22. }
  23. else
  24. {
  25. i = (i*10) + (*pValue - TEXT('0'));
  26. }
  27. pValue++;
  28. }
  29. return (i * iSign);
  30. }
  31. void ItoA ( INT val, LPTSTR buf, UINT radix )
  32. {
  33. LPTSTR p; /* pointer to traverse string */
  34. LPTSTR firstdig; /* pointer to first digit */
  35. TCHAR temp; /* temp char */
  36. INT digval; /* value of digit */
  37. p = buf;
  38. if (val < 0) {
  39. /* negative, so output '-' and negate */
  40. *p++ = TEXT('-');
  41. val = -val;
  42. }
  43. firstdig = p; /* save pointer to first digit */
  44. do {
  45. digval = (val % radix);
  46. val /= radix; /* get next digit */
  47. /* convert to ascii and store */
  48. if (digval > 9)
  49. *p++ = (TCHAR) (digval - 10 + TEXT('a')); /* a letter */
  50. else
  51. *p++ = (TCHAR) (digval + TEXT('0')); /* a digit */
  52. } while (val > 0);
  53. /* We now have the digit of the number in the buffer, but in reverse
  54. order. Thus we reverse them now. */
  55. *p-- = TEXT('\0'); /* terminate string; p points to last digit */
  56. do {
  57. temp = *p;
  58. *p = *firstdig;
  59. *firstdig = temp; /* swap *p and *firstdig */
  60. --p;
  61. ++firstdig; /* advance to next two digits */
  62. } while (firstdig < p); /* repeat until halfway */
  63. }
  64. //------------------------------------------------------------------------------------
  65. //
  66. // IconSet/GetRegValueString()
  67. //
  68. // Versions of Get/SetRegValueString that go to the user classes section.
  69. // This can be overridden by the bClasses flag, which will only write the
  70. // value to the HKEY_CLASSES_ROOT section.
  71. //
  72. // Returns: success of string setting / retrieval
  73. //
  74. //------------------------------------------------------------------------------------
  75. BOOL IconSetRegValueString(LPSTR lpszSubKey, LPSTR lpszValName, LPSTR lpszValue ) {
  76. TCHAR szRegPath[MAX_PATH];
  77. wsprintf( szRegPath, c_szSoftwareClassesFmt, lpszSubKey );
  78. return SetRegValueString(HKEY_CURRENT_USER, szRegPath, lpszValName, lpszValue );
  79. }
  80. BOOL IconGetRegValueString(LPSTR lpszSubKey, LPSTR lpszValName, LPSTR lpszValue, int iMaxSize ) {
  81. TCHAR szRegPath[MAX_PATH];
  82. wsprintf( szRegPath, c_szSoftwareClassesFmt, lpszSubKey );
  83. if (!GetRegValueString(HKEY_CURRENT_USER, szRegPath, lpszValName, lpszValue, iMaxSize ))
  84. return GetRegValueString(HKEY_CLASSES_ROOT, lpszSubKey, lpszValName, lpszValue, iMaxSize );
  85. return TRUE;
  86. }
  87. //------------------------------------------------------------------------------------
  88. //
  89. // GetRegValueString()
  90. //
  91. // Just a little helper routine, gets an individual string value from the
  92. // registry and returns it to the caller. Takes care of registry headaches,
  93. // including a paranoid length check before getting the string.
  94. //
  95. // Returns: success of string retrieval
  96. //
  97. //------------------------------------------------------------------------------------
  98. BOOL GetRegValueString( HKEY hMainKey, LPSTR lpszSubKey, LPSTR lpszValName, LPSTR lpszValue, int iMaxSize )
  99. {
  100. LONG lRet;
  101. HKEY hKey; // cur open key
  102. BOOL bOK = TRUE;
  103. DWORD dwSize, dwType;
  104. // get subkey
  105. lRet = RegOpenKeyEx( hMainKey, lpszSubKey, (DWORD)0, KEY_QUERY_VALUE, (PHKEY)&hKey );
  106. if( lRet != ERROR_SUCCESS )
  107. {
  108. // Assert(FALSE, "problem on RegOpenKeyEx in GetRegValue\n");
  109. return FALSE;
  110. }
  111. // now do our paranoid check of data size
  112. lRet = RegQueryValueEx( hKey, lpszValName,(LPDWORD)NULL,(LPDWORD)&dwType, (LPBYTE)NULL,/* null for size info only */ (LPDWORD)&dwSize );
  113. if( ERROR_SUCCESS == lRet )
  114. { // saw something there
  115. // here's the size check before getting the data
  116. if( dwSize > (DWORD)iMaxSize )
  117. { // if string too big
  118. // Assert(FALSE, "Humongous registry string; can't GetRegValue...\n");
  119. bOK = FALSE; // can't read, so very bad news
  120. }
  121. else
  122. { // size is OK to continue
  123. // now really get the value
  124. lRet = RegQueryValueEx( hKey, lpszValName, (LPDWORD)NULL,(LPDWORD)&dwType, (LPBYTE)lpszValue, /* getting actual value */ (LPDWORD)&dwSize );
  125. // Assert(lret == ERROR_SUCCESS, "bad return GetRegValue query\n");
  126. // Assert(dwType == (DWORD)REG_SZ, "non-string type in GetValue!\n");
  127. if( ERROR_SUCCESS != lRet )
  128. bOK = FALSE;
  129. }
  130. }
  131. else
  132. {
  133. bOK = FALSE;
  134. }
  135. // close subkey
  136. RegCloseKey( hKey );
  137. return (bOK);
  138. }
  139. //------------------------------------------------------------------------------------
  140. //
  141. // GetRegValueInt()
  142. //
  143. // Just a little helper routine, gets an individual string value from the
  144. // registry and returns it to the caller as an int. Takes care of registry headaches,
  145. // including a paranoid length check before getting the string.
  146. //
  147. // Returns: success of string retrieval
  148. //
  149. //------------------------------------------------------------------------------------
  150. BOOL GetRegValueInt( HKEY hMainKey, LPSTR lpszSubKey, LPSTR lpszValName, int* piValue )
  151. {
  152. char lpszValue[16];
  153. BOOL bOK = TRUE;
  154. bOK = GetRegValueString( hMainKey, lpszSubKey, lpszValName, lpszValue, MAX_VALUELEN );
  155. *piValue = AtoI( lpszValue );
  156. return bOK;
  157. }
  158. //------------------------------------------------------------------------------------
  159. //
  160. // SetRegValueString()
  161. //
  162. // Just a little helper routine that takes string and writes it to the registry.
  163. //
  164. // Returns: success writing to Registry, should be always TRUE.
  165. //
  166. //------------------------------------------------------------------------------------
  167. BOOL SetRegValueString( HKEY hMainKey, LPSTR lpszSubKey, LPSTR lpszValName, LPSTR lpszValue )
  168. {
  169. HKEY hKey; // cur open key
  170. LONG lRet;
  171. BOOL bOK = TRUE;
  172. // open this subkey
  173. lRet = RegOpenKeyEx( hMainKey, (LPSTR)lpszSubKey, (DWORD)0, KEY_SET_VALUE, (PHKEY)&hKey );
  174. // check that you got a good key here
  175. if( lRet != ERROR_SUCCESS )
  176. {
  177. DWORD dwDisposition;
  178. // Assert(FALSE, "problem on RegOpenKeyEx (write) of subkey ");
  179. // Assert(FALSE, szSubKey);
  180. // Assert(FALSE, "\n");
  181. // OK, you couldn't even open the key !!!
  182. // **********************************************************************************
  183. // based on the sketchy documentation we have for this Reg* and Error stuff, we're
  184. // guessing that you've ended up here because this totally standard, Windows-defined
  185. // subkey name just doesn't happen to be defined for the current user.
  186. // **********************************************************************************
  187. // SO: Just create this subkey for this user, and maybe it will get used after you create and set it.
  188. // still successful so long as can create new subkey to write to
  189. lRet = RegCreateKeyEx( hMainKey, (LPSTR)lpszSubKey, (DWORD)0, (LPSTR)NULL, REG_OPTION_NON_VOLATILE,
  190. KEY_SET_VALUE, (LPSECURITY_ATTRIBUTES)NULL, (PHKEY)&hKey, (LPDWORD)&dwDisposition );
  191. if( lRet != ERROR_SUCCESS )
  192. {
  193. // Assert(FALSE, "problem even with RegCreateKeyEx (write) of subkey ");
  194. // Assert(FALSE, szSubKey);
  195. // Assert(FALSE, "\n");
  196. // oh, oh, couldn't create the key
  197. bOK = FALSE;
  198. }
  199. }
  200. lRet = RegSetValueEx( hKey, lpszValName, (DWORD)NULL,(DWORD)REG_SZ,(LPBYTE)lpszValue, (DWORD)( lstrlen( lpszValue) + 1 ) );
  201. bOK = bOK && (lRet == ERROR_SUCCESS);
  202. // Assert(bOK, "couldn't write a string value to registry!\n");
  203. // close this key
  204. RegCloseKey( hKey );
  205. // Assert(bOK, "didn't SetRegValue well\n");
  206. return (bOK);
  207. }
  208. //------------------------------------------------------------------------------------
  209. //
  210. // SetRegValueInt()
  211. //
  212. // Just a little helper routine that takes an int and writes it as a string to the
  213. // registry.
  214. //
  215. // Returns: success writing to Registry, should be always TRUE.
  216. //
  217. //------------------------------------------------------------------------------------
  218. BOOL SetRegValueInt( HKEY hMainKey, LPSTR lpszSubKey, LPSTR lpszValName, int iValue )
  219. {
  220. char lpszValue[16];
  221. ItoA( iValue, lpszValue, 10 );
  222. return SetRegValueString( hMainKey, lpszSubKey, lpszValName, lpszValue );
  223. }
  224. //------------------------------------------------------------------------------------
  225. //
  226. // SetRegValueDword()
  227. //
  228. // Just a little helper routine that takes an dword and writes it to the
  229. // supplied location.
  230. //
  231. // Returns: success writing to Registry, should be always TRUE.
  232. //
  233. //------------------------------------------------------------------------------------
  234. BOOL SetRegValueDword( HKEY hk, LPTSTR pSubKey, LPTSTR pValue, DWORD dwVal )
  235. {
  236. HKEY hkey = NULL;
  237. BOOL bRet = FALSE;
  238. if (ERROR_SUCCESS == RegOpenKey( hk, pSubKey, &hkey ))
  239. {
  240. if (ERROR_SUCCESS == RegSetValueEx( hkey, pValue, 0,
  241. REG_DWORD, (LPBYTE)&dwVal,
  242. sizeof(DWORD)
  243. )
  244. )
  245. {
  246. bRet = TRUE;
  247. }
  248. }
  249. if (hkey)
  250. {
  251. RegCloseKey( hkey );
  252. }
  253. return bRet;
  254. }
  255. //------------------------------------------------------------------------------------
  256. //
  257. // GetRegValueDword()
  258. //
  259. // Just a little helper routine that takes an dword and writes it to the
  260. // supplied location.
  261. //
  262. // Returns: success writing to Registry, should be always TRUE.
  263. //
  264. //------------------------------------------------------------------------------------
  265. DWORD GetRegValueDword( HKEY hk, LPTSTR pSubKey, LPTSTR pValue )
  266. {
  267. HKEY hkey = NULL;
  268. DWORD dwVal = REG_BAD_DWORD;
  269. if (ERROR_SUCCESS == RegOpenKey( hk, pSubKey, &hkey ))
  270. {
  271. DWORD dwType, dwSize = sizeof(DWORD);
  272. RegQueryValueEx( hkey, pValue, NULL, &dwType, (LPBYTE)&dwVal, &dwSize );
  273. }
  274. if (hkey)
  275. {
  276. RegCloseKey( hkey );
  277. }
  278. return dwVal;
  279. }