Team Fortress 2 Source Code as on 22/4/2020
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.

436 lines
9.0 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // SYS_UTILS.C
  4. //
  5. //=====================================================================================//
  6. #include "sys_utils.h"
  7. //-----------------------------------------------------------------------------
  8. // Sys_SplitRegistryKey
  9. //
  10. //-----------------------------------------------------------------------------
  11. static BOOL Sys_SplitRegistryKey( const CHAR *key, CHAR *key0, int key0Len, CHAR *key1, int key1Len )
  12. {
  13. if ( !key )
  14. return false;
  15. int len = (int)strlen( key );
  16. if ( !len )
  17. return false;
  18. int Start = -1;
  19. for ( int i = len-1; i >= 0; i-- )
  20. {
  21. if ( key[i] == '\\' )
  22. break;
  23. else
  24. Start=i;
  25. }
  26. if ( Start == -1 )
  27. return false;
  28. _snprintf( key0, Start, key );
  29. key0[Start] = '\0';
  30. _snprintf( key1, ( len-Start )+1, key+Start );
  31. key1[( len-Start )+1] = '\0';
  32. return true;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Sys_SetRegistryString
  36. //
  37. //-----------------------------------------------------------------------------
  38. BOOL Sys_SetRegistryString( const CHAR *key, const CHAR *value )
  39. {
  40. HKEY hKey;
  41. CHAR key0[256];
  42. CHAR key1[256];
  43. HKEY hSlot = HKEY_CURRENT_USER;
  44. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  45. {
  46. hSlot = HKEY_LOCAL_MACHINE;
  47. key += 19;
  48. }
  49. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  50. {
  51. hSlot = HKEY_CURRENT_USER;
  52. key += 18;
  53. }
  54. if ( !Sys_SplitRegistryKey( key, key0, sizeof( key0 ), key1, sizeof( key1 ) ) )
  55. return false;
  56. if ( RegCreateKeyEx( hSlot,key0,NULL,NULL,REG_OPTION_NON_VOLATILE, value ? KEY_WRITE : KEY_ALL_ACCESS,NULL,&hKey,NULL )!=ERROR_SUCCESS )
  57. return false;
  58. if ( RegSetValueEx( hKey, key1, NULL, REG_SZ, ( UCHAR* )value, (int)strlen( value ) + 1 ) != ERROR_SUCCESS )
  59. {
  60. RegCloseKey( hKey );
  61. return false;
  62. }
  63. // success
  64. RegCloseKey( hKey );
  65. return true;
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Sys_GetRegistryString
  69. //
  70. //-----------------------------------------------------------------------------
  71. BOOL Sys_GetRegistryString( const CHAR *key, CHAR *value, const CHAR* defValue, int valueLen )
  72. {
  73. HKEY hKey;
  74. CHAR key0[256];
  75. CHAR key1[256];
  76. if ( defValue )
  77. _snprintf( value, valueLen, defValue );
  78. HKEY hSlot = HKEY_CURRENT_USER;
  79. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  80. {
  81. hSlot = HKEY_LOCAL_MACHINE;
  82. key += 19;
  83. }
  84. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  85. {
  86. hSlot = HKEY_CURRENT_USER;
  87. key += 18;
  88. }
  89. if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
  90. return false;
  91. if ( RegOpenKeyEx( hSlot,key0,NULL,KEY_READ,&hKey )!=ERROR_SUCCESS )
  92. return false;
  93. unsigned long len=valueLen;
  94. if ( RegQueryValueEx( hKey,key1,NULL,NULL,( UCHAR* )value,&len )!=ERROR_SUCCESS )
  95. {
  96. RegCloseKey( hKey );
  97. return false;
  98. }
  99. // success
  100. RegCloseKey( hKey );
  101. return true;
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Sys_SetRegistryInteger
  105. //
  106. //-----------------------------------------------------------------------------
  107. BOOL Sys_SetRegistryInteger( const CHAR *key, int value )
  108. {
  109. HKEY hKey;
  110. CHAR key0[256];
  111. CHAR key1[256];
  112. HKEY hSlot = HKEY_CURRENT_USER;
  113. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  114. {
  115. hSlot = HKEY_LOCAL_MACHINE;
  116. key += 19;
  117. }
  118. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  119. {
  120. hSlot = HKEY_CURRENT_USER;
  121. key += 18;
  122. }
  123. if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
  124. return false;
  125. if ( RegCreateKeyEx( hSlot, key0, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL )!=ERROR_SUCCESS )
  126. return false;
  127. if ( RegSetValueEx( hKey, key1, NULL, REG_DWORD, ( UCHAR* )&value, 4 )!=ERROR_SUCCESS )
  128. {
  129. RegCloseKey( hKey );
  130. return false;
  131. }
  132. // success
  133. RegCloseKey( hKey );
  134. return true;
  135. }
  136. //-----------------------------------------------------------------------------
  137. // Sys_GetRegistryInteger
  138. //
  139. //-----------------------------------------------------------------------------
  140. BOOL Sys_GetRegistryInteger( const CHAR *key, int defValue, int &value )
  141. {
  142. HKEY hKey;
  143. CHAR key0[256];
  144. CHAR key1[256];
  145. value = defValue;
  146. HKEY hSlot = HKEY_CURRENT_USER;
  147. if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
  148. {
  149. hSlot = HKEY_LOCAL_MACHINE;
  150. key += 19;
  151. }
  152. else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
  153. {
  154. hSlot = HKEY_CURRENT_USER;
  155. key += 18;
  156. }
  157. if ( !Sys_SplitRegistryKey( key, key0, 256, key1, 256 ) )
  158. return false;
  159. if ( RegOpenKeyEx( hSlot, key0, NULL, KEY_READ, &hKey ) != ERROR_SUCCESS )
  160. return false;
  161. unsigned long len=4;
  162. if ( RegQueryValueEx( hKey, key1, NULL, NULL, ( UCHAR* )&value, &len ) != ERROR_SUCCESS )
  163. {
  164. RegCloseKey( hKey );
  165. return false;
  166. }
  167. // success
  168. RegCloseKey( hKey );
  169. return true;
  170. }
  171. //-----------------------------------------------------------------------------
  172. // Sys_NormalizePath
  173. //
  174. //-----------------------------------------------------------------------------
  175. void Sys_NormalizePath( CHAR* path, bool forceToLower )
  176. {
  177. int srcLen = (int)strlen( path );
  178. for ( int i=0; i<srcLen; i++ )
  179. {
  180. if ( path[i] == '/' )
  181. path[i] = '\\';
  182. else if ( forceToLower && ( path[i] >= 'A' && path[i] <= 'Z' ) )
  183. path[i] = path[i] - 'A' + 'a';
  184. }
  185. }
  186. //-----------------------------------------------------------------------------
  187. // Sys_SkipWhitespace
  188. //
  189. //-----------------------------------------------------------------------------
  190. CHAR* Sys_SkipWhitespace( CHAR *data, BOOL *hasNewLines, int* pNumLines )
  191. {
  192. int c;
  193. while( ( c = *data ) <= ' ' )
  194. {
  195. if ( c == '\n' )
  196. {
  197. if ( pNumLines )
  198. (*pNumLines)++;
  199. if ( hasNewLines )
  200. *hasNewLines = true;
  201. }
  202. else if ( !c )
  203. return ( NULL );
  204. data++;
  205. }
  206. return ( data );
  207. }
  208. //-----------------------------------------------------------------------------
  209. // Sys_PeekToken
  210. //
  211. //-----------------------------------------------------------------------------
  212. CHAR* Sys_PeekToken( CHAR *dataptr, BOOL bAllowLineBreaks )
  213. {
  214. CHAR *saved;
  215. CHAR *pToken;
  216. saved = dataptr;
  217. pToken = Sys_GetToken( &saved, bAllowLineBreaks, NULL );
  218. return pToken;
  219. }
  220. //-----------------------------------------------------------------------------
  221. // Sys_GetToken
  222. //
  223. //-----------------------------------------------------------------------------
  224. CHAR* Sys_GetToken( CHAR** dataptr, BOOL allowLineBreaks, int* pNumLines )
  225. {
  226. CHAR c;
  227. int len;
  228. BOOL hasNewLines;
  229. CHAR* data;
  230. static CHAR token[MAX_SYSTOKENCHARS];
  231. c = 0;
  232. data = *dataptr;
  233. len = 0;
  234. token[0] = 0;
  235. hasNewLines = false;
  236. // make sure incoming data is valid
  237. if ( !data )
  238. {
  239. *dataptr = NULL;
  240. return ( token );
  241. }
  242. for ( ;; )
  243. {
  244. // skip whitespace
  245. data = Sys_SkipWhitespace( data, &hasNewLines, pNumLines );
  246. if ( !data )
  247. {
  248. *dataptr = NULL;
  249. return ( token );
  250. }
  251. if ( hasNewLines && !allowLineBreaks )
  252. {
  253. *dataptr = data;
  254. return ( token );
  255. }
  256. c = *data;
  257. if ( c == '/' && data[1] == '/' )
  258. {
  259. // skip double slash comments
  260. data += 2;
  261. while ( *data && *data != '\n' )
  262. data++;
  263. if ( *data && *data == '\n' )
  264. {
  265. data++;
  266. if ( pNumLines )
  267. (*pNumLines)++;
  268. }
  269. }
  270. else if ( c =='/' && data[1] == '*' )
  271. {
  272. // skip /* */ comments
  273. data += 2;
  274. while ( *data && ( *data != '*' || data[1] != '/' ) )
  275. {
  276. if ( *data == '\n' && pNumLines )
  277. (*pNumLines)++;
  278. data++;
  279. }
  280. if ( *data )
  281. data += 2;
  282. }
  283. else
  284. break;
  285. }
  286. // handle quoted strings
  287. if ( c == '\"' || c == '<' )
  288. {
  289. data++;
  290. for ( ;; )
  291. {
  292. c = *data++;
  293. if ( c == '\"' || c == '>' || !c )
  294. {
  295. token[len] = 0;
  296. *dataptr = ( CHAR* )data;
  297. return ( token );
  298. }
  299. if ( len < MAX_SYSTOKENCHARS )
  300. token[len++] = c;
  301. }
  302. }
  303. // parse a regular word
  304. do
  305. {
  306. if ( len < MAX_SYSTOKENCHARS )
  307. token[len++] = c;
  308. data++;
  309. c = *data;
  310. }
  311. while ( c > ' ' );
  312. if ( len >= MAX_SYSTOKENCHARS )
  313. len = 0;
  314. token[len] = '\0';
  315. *dataptr = (CHAR*)data;
  316. return token;
  317. }
  318. //-----------------------------------------------------------------------------
  319. // Sys_SkipBracedSection
  320. //
  321. // The next token should be an open brace.
  322. // Skips until a matching close brace is found.
  323. // Internal brace depths are properly skipped.
  324. //-----------------------------------------------------------------------------
  325. void Sys_SkipBracedSection( CHAR** dataptr, int* numlines )
  326. {
  327. CHAR* token;
  328. int depth;
  329. depth = 0;
  330. do
  331. {
  332. token = Sys_GetToken( dataptr, true, numlines );
  333. if ( token[1] == '\0' )
  334. {
  335. if ( token[0] == '{' )
  336. depth++;
  337. else if ( token[0] == '}' )
  338. depth--;
  339. }
  340. }
  341. while( depth && *dataptr );
  342. }
  343. //-----------------------------------------------------------------------------
  344. // Sys_SkipRestOfLine
  345. //
  346. //-----------------------------------------------------------------------------
  347. void Sys_SkipRestOfLine( CHAR** dataptr, int* numlines )
  348. {
  349. CHAR* p;
  350. int c;
  351. p = *dataptr;
  352. while ( ( c = *p++ ) != '\0' )
  353. {
  354. if ( c == '\n' )
  355. {
  356. if ( numlines )
  357. ( *numlines )++;
  358. break;
  359. }
  360. }
  361. *dataptr = p;
  362. }
  363. void Sys_StripQuotesFromToken( CHAR *pToken )
  364. {
  365. int len;
  366. len = (int)strlen( pToken );
  367. if ( len >= 2 && pToken[0] == '\"' )
  368. {
  369. memcpy( pToken, pToken+1, len-1 );
  370. pToken[len-2] = '\0';
  371. }
  372. }