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.

687 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996-2000 Microsoft Corporation
  3. Module Name:
  4. table.c
  5. Abstract:
  6. Domain Name System (DNS) Library
  7. Routines to handle general table lookup.
  8. Author:
  9. Jim Gilroy (jamesg) December 1996
  10. Revision History:
  11. --*/
  12. #include "local.h"
  13. #include "time.h"
  14. //
  15. // Comparison function
  16. //
  17. typedef INT (__cdecl * COMPARISON_FUNCTION)(
  18. const CHAR *,
  19. const CHAR *,
  20. size_t );
  21. //
  22. // Table lookup.
  23. //
  24. // Many DNS Records have human readable mnemonics for given data values.
  25. // These are used for data file formats, and display in nslookup or debug
  26. // output or cmdline tools.
  27. //
  28. // To simplify this process, have a single mapping functionality that
  29. // supports DWORD \ LPSTR mapping tables. Tables for indivual types
  30. // may then be layered on top of this.
  31. //
  32. // Support two table types.
  33. // VALUE_TABLE_ENTRY is simple value-string mapping
  34. // FLAG_TABLE_ENTRY is designed for bit field flag mappings where
  35. // several flag strings might be contained in flag; this table
  36. // contains additional mask field to allow multi-bit fields
  37. // within the flag
  38. //
  39. #if 0
  40. //
  41. // Defined in local.h here only for reference
  42. //
  43. typedef struct
  44. {
  45. DWORD dwValue; // flag value
  46. PCHAR pszString; // string representation of value
  47. }
  48. DNS_VALUE_TABLE_ENTRY;
  49. typedef struct
  50. {
  51. DWORD dwFlag; // flag value
  52. DWORD dwMask; // flag value mask
  53. PCHAR pszString; // string representation of value
  54. }
  55. DNS_FLAG_TABLE_ENTRY;
  56. // Error return on unmatched string
  57. #define DNS_TABLE_LOOKUP_ERROR (-1)
  58. #endif
  59. DWORD
  60. Dns_ValueForString(
  61. IN DNS_VALUE_TABLE_ENTRY * Table,
  62. IN BOOL fIgnoreCase,
  63. IN PCHAR pchName,
  64. IN INT cchNameLength
  65. )
  66. /*++
  67. Routine Description:
  68. Retrieve value for given string.
  69. Arguments:
  70. Table - table with value\string mapping
  71. fIgnoreCase - TRUE if case-insensitive string lookup
  72. pchName - ptr to string
  73. cchNameLength - length of string
  74. Return Value:
  75. Flag value corresponding to string, if found.
  76. DNS_TABLE_LOOKUP_ERROR otherwise.
  77. --*/
  78. {
  79. INT i = 0;
  80. // INT (* pcompareFunction)( const char *, const char *, size_t );
  81. COMPARISON_FUNCTION pcompareFunction;
  82. //
  83. // if not given get string length
  84. //
  85. if ( !cchNameLength )
  86. {
  87. cchNameLength = strlen( pchName );
  88. }
  89. //
  90. // determine comparison routine
  91. //
  92. if ( fIgnoreCase )
  93. {
  94. pcompareFunction = _strnicmp;
  95. }
  96. else
  97. {
  98. pcompareFunction = strncmp;
  99. }
  100. //
  101. // find value matching name
  102. //
  103. while( Table[i].pszString != NULL )
  104. {
  105. if ( pcompareFunction( pchName, Table[i].pszString, cchNameLength ) == 0 )
  106. {
  107. return( Table[i].dwValue );
  108. }
  109. i++;
  110. }
  111. return( (DWORD)DNS_TABLE_LOOKUP_ERROR );
  112. }
  113. DWORD
  114. Dns_ValueForStringEx(
  115. IN DNS_VALUE_TABLE_ENTRY * Table,
  116. IN BOOL fIgnoreCase,
  117. IN DNS_CHARSET InCharSet,
  118. IN PCHAR pchName,
  119. IN INT cchNameLength
  120. )
  121. /*++
  122. Routine Description:
  123. Retrieve value for given string.
  124. Arguments:
  125. Table - table with value\string mapping
  126. fIgnoreCase - TRUE if case-insensitive string lookup
  127. InCharSet - input string char set
  128. pchName - ptr to string
  129. cchNameLength - length of string
  130. Return Value:
  131. Flag value corresponding to string, if found.
  132. DNS_TABLE_LOOKUP_ERROR otherwise.
  133. --*/
  134. {
  135. DWORD result;
  136. PSTR pnameAlloc;
  137. //
  138. // convert
  139. //
  140. #if 0
  141. if ( InCharSet != 0 &&
  142. InCharSet != DnsCharSetAnsi )
  143. {
  144. #endif
  145. pnameAlloc = Dns_StringCopyAllocate(
  146. pchName,
  147. cchNameLength,
  148. InCharSet,
  149. DnsCharSetAnsi );
  150. //
  151. // do the lookup
  152. //
  153. result = Dns_ValueForString(
  154. Table,
  155. fIgnoreCase,
  156. pnameAlloc,
  157. 0 // null terminated
  158. );
  159. //
  160. // cleanup
  161. //
  162. FREE_HEAP( pnameAlloc );
  163. return result;
  164. }
  165. PCHAR
  166. Dns_GetStringForValue(
  167. IN DNS_VALUE_TABLE_ENTRY * Table,
  168. IN DWORD dwValue
  169. )
  170. /*++
  171. Routine Description:
  172. Retrieve string representation of given value.
  173. Arguments:
  174. Table - table with value\string mapping
  175. dwValue - value to map to strings
  176. Return Value:
  177. Ptr to mapping mneumonic string.
  178. NULL if unknown mapping type.
  179. --*/
  180. {
  181. INT i = 0;
  182. //
  183. // check all supported values for match
  184. //
  185. while( Table[i].pszString != NULL )
  186. {
  187. if ( dwValue == Table[i].dwValue )
  188. {
  189. return( Table[i].pszString );
  190. }
  191. i++;
  192. }
  193. return( NULL );
  194. }
  195. DWORD
  196. Dns_FlagForString(
  197. IN DNS_FLAG_TABLE_ENTRY * Table,
  198. IN BOOL fIgnoreCase,
  199. IN PCHAR pchName,
  200. IN INT cchNameLength
  201. )
  202. /*++
  203. Routine Description:
  204. Retrieve flag value for given string.
  205. This may be called repeatedly with additional strings and OR the result
  206. together to build flag with independent bit settings.
  207. Arguments:
  208. Table - table with value\string mapping
  209. fIgnoreCase - TRUE if case-insensitive string lookup
  210. pchName - ptr to string
  211. cchNameLength - length of string
  212. Return Value:
  213. Flag value corresponding to string, if found.
  214. DNS_TABLE_LOOKUP_ERROR otherwise.
  215. --*/
  216. {
  217. INT i = 0;
  218. //
  219. // if not given get string length
  220. //
  221. if ( !cchNameLength )
  222. {
  223. cchNameLength = strlen( pchName );
  224. }
  225. //
  226. // check all supported values for name match
  227. //
  228. if ( fIgnoreCase )
  229. {
  230. while( Table[i].pszString != NULL )
  231. {
  232. if ( cchNameLength == (INT)strlen( Table[i].pszString )
  233. &&
  234. ! _strnicmp( pchName, Table[i].pszString, cchNameLength ) )
  235. {
  236. return( Table[i].dwFlag );
  237. }
  238. i++;
  239. }
  240. }
  241. else
  242. {
  243. while( Table[i].pszString != NULL )
  244. {
  245. if ( cchNameLength == (INT)strlen( Table[i].pszString )
  246. &&
  247. ! strncmp( pchName, Table[i].pszString, cchNameLength ) )
  248. {
  249. return( Table[i].dwFlag );
  250. }
  251. i++;
  252. }
  253. }
  254. return( (DWORD) DNS_TABLE_LOOKUP_ERROR );
  255. }
  256. VOID
  257. DnsPrint_ValueTable(
  258. IN PRINT_ROUTINE PrintRoutine,
  259. IN PPRINT_CONTEXT pPrintContext,
  260. IN LPSTR pszHeader,
  261. IN PDNS_VALUE_TABLE Table
  262. )
  263. /*++
  264. Routine Description:
  265. Print value table.
  266. Arguments:
  267. PrintRoutine - routine to print with
  268. pPrintContext - print context
  269. pszHeader - header to print
  270. Table - value table to print
  271. Return Value:
  272. None
  273. --*/
  274. {
  275. DWORD i = 0;
  276. if ( !pszHeader )
  277. {
  278. pszHeader = "Table";
  279. }
  280. if ( ! pszHeader )
  281. {
  282. PrintRoutine(
  283. pPrintContext,
  284. "%s NULL value table to print",
  285. pszHeader );
  286. }
  287. //
  288. // print each value in table
  289. //
  290. DnsPrint_Lock();
  291. PrintRoutine(
  292. pPrintContext,
  293. "%s\n",
  294. pszHeader );
  295. while( Table[i].pszString != NULL )
  296. {
  297. PrintRoutine(
  298. pPrintContext,
  299. "\t%40s\t\t%08x\n",
  300. Table[i].pszString,
  301. Table[i].dwValue );
  302. i++;
  303. }
  304. DnsPrint_Unlock();
  305. }
  306. PCHAR
  307. Dns_WriteStringsForFlag(
  308. IN DNS_FLAG_TABLE_ENTRY * Table,
  309. IN DWORD dwFlag,
  310. IN OUT PCHAR pchFlag
  311. )
  312. /*++
  313. Routine Description:
  314. Retrieve flag string(s) corresponding to a given flag value.
  315. This function is specifically for mapping a flag value into the
  316. corresponding flag mnemonics.
  317. No attempt is made to insure that every bit of dwValue is mapped,
  318. nor are bits eliminated as they are mapped. Every value in table
  319. that exactly matches bits in the table is returned.
  320. Arguments:
  321. Table - table with value\string mapping
  322. dwFlag - flag value to map to strings
  323. pchFlag - buffer to write flag to
  324. Return Value:
  325. Ptr to next location in pchFlag buffer.
  326. If this is same as input, then no strings were written.
  327. --*/
  328. {
  329. INT i = 0;
  330. // init buffer for no-match
  331. DNS_ASSERT( pchFlag != NULL );
  332. *pchFlag = 0;
  333. //
  334. // check all supported flags types for name match
  335. // - note comparing flag within mask to allow match of multi-bit
  336. // flags
  337. //
  338. while( Table[i].pszString != NULL )
  339. {
  340. if ( (dwFlag & Table[i].dwMask) == Table[i].dwFlag )
  341. {
  342. pchFlag += sprintf( pchFlag, "%s ", Table[i].pszString );
  343. }
  344. i++;
  345. }
  346. return( pchFlag );
  347. }
  348. //
  349. // Specific simple tables
  350. //
  351. //
  352. // RnR Flag mappings
  353. //
  354. DNS_VALUE_TABLE_ENTRY RnrLupFlagTable[] =
  355. {
  356. LUP_DEEP , "LUP_DEEP" ,
  357. LUP_CONTAINERS , "LUP_CONTAINERS" ,
  358. LUP_NOCONTAINERS , "LUP_NOCONTAINERS" ,
  359. LUP_RETURN_NAME , "LUP_RETURN_NAME" ,
  360. LUP_RETURN_TYPE , "LUP_RETURN_TYPE" ,
  361. LUP_RETURN_VERSION , "LUP_RETURN_VERSION" ,
  362. LUP_RETURN_COMMENT , "LUP_RETURN_COMMENT" ,
  363. LUP_RETURN_ADDR , "LUP_RETURN_ADDR" ,
  364. LUP_RETURN_BLOB , "LUP_RETURN_BLOB" ,
  365. LUP_RETURN_ALIASES , "LUP_RETURN_ALIASES" ,
  366. LUP_RETURN_QUERY_STRING , "LUP_RETURN_QUERY_STRING" ,
  367. LUP_RETURN_ALL , "LUP_RETURN_ALL" ,
  368. LUP_RES_SERVICE , "LUP_RES_SERVICE" ,
  369. LUP_FLUSHCACHE , "LUP_FLUSHCACHE" ,
  370. LUP_FLUSHPREVIOUS , "LUP_FLUSHPREVIOUS" ,
  371. 0, NULL,
  372. };
  373. DWORD
  374. Dns_RnrLupFlagForString(
  375. IN PCHAR pchName,
  376. IN INT cchNameLength
  377. )
  378. /*++
  379. Routine Description:
  380. Retrieve RnR LUP flag corresponding to string.
  381. Arguments:
  382. pchName - ptr to string
  383. cchNameLength - length of string
  384. Return Value:
  385. Flag corresponding to string, if found.
  386. Zero otherwise.
  387. --*/
  388. {
  389. return Dns_ValueForString(
  390. RnrLupFlagTable,
  391. FALSE, // always upper case
  392. pchName,
  393. cchNameLength );
  394. }
  395. PCHAR
  396. Dns_GetRnrLupFlagString(
  397. IN DWORD dwFlag
  398. )
  399. /*++
  400. Routine Description:
  401. Get string corresponding to a given RnR LUP flag.
  402. Arguments:
  403. dwFlag -- flag
  404. Return Value:
  405. Ptr to flag mneumonic string.
  406. NULL if unknown flag.
  407. --*/
  408. {
  409. return Dns_GetStringForValue(
  410. RnrLupFlagTable,
  411. dwFlag );
  412. }
  413. //
  414. // RnR Name Space ID mappings
  415. //
  416. DNS_VALUE_TABLE_ENTRY RnrNameSpaceMappingTable[] =
  417. {
  418. NS_ALL , "NS_ALL" ,
  419. //NS_DEFAULT , "NS_DEFAULT" ,
  420. NS_SAP , "NS_SAP" ,
  421. NS_NDS , "NS_NDS" ,
  422. NS_PEER_BROWSE , "NS_PEER_BROWSEE" ,
  423. NS_SLP , "NS_SLP" ,
  424. NS_DHCP , "NS_DHCP" ,
  425. NS_TCPIP_LOCAL , "NS_TCPIP_LOCAL" ,
  426. NS_TCPIP_HOSTS , "NS_TCPIP_HOSTS" ,
  427. NS_DNS , "NS_DNS" ,
  428. NS_NETBT , "NS_NETBT" ,
  429. NS_WINS , "NS_WINS" ,
  430. NS_NLA , "NS_NLA" ,
  431. NS_NBP , "NS_NBP" ,
  432. NS_MS , "NS_MS" ,
  433. NS_STDA , "NS_STDA" ,
  434. NS_NTDS , "NS_NTDS" ,
  435. NS_X500 , "NS_X500" ,
  436. NS_NIS , "NS_NIS" ,
  437. NS_NISPLUS , "NS_NISPLUS" ,
  438. NS_WRQ , "NS_WRQ" ,
  439. NS_NETDES , "NS_NETDES" ,
  440. 0, NULL,
  441. };
  442. DWORD
  443. Dns_RnrNameSpaceIdForString(
  444. IN PCHAR pchName,
  445. IN INT cchNameLength
  446. )
  447. /*++
  448. Routine Description:
  449. Retrieve RnR Name Space Id corresponding to string.
  450. Arguments:
  451. pchName - ptr to string
  452. cchNameLength - length of string
  453. Return Value:
  454. Name space ID corresponding to string, if found.
  455. Zero otherwise.
  456. --*/
  457. {
  458. return Dns_ValueForString(
  459. RnrNameSpaceMappingTable,
  460. FALSE, // always upper case
  461. pchName,
  462. cchNameLength );
  463. }
  464. DWORD
  465. Dns_RnrNameSpaceIdForStringW(
  466. IN PWSTR pwsName
  467. )
  468. {
  469. return Dns_ValueForStringEx(
  470. RnrNameSpaceMappingTable,
  471. FALSE, // always upper case
  472. DnsCharSetUnicode,
  473. (PCHAR) pwsName,
  474. 0 );
  475. }
  476. PCHAR
  477. Dns_GetRnrNameSpaceIdString(
  478. IN DWORD dwFlag
  479. )
  480. /*++
  481. Routine Description:
  482. Get string corresponding to a given RnR name space id.
  483. Arguments:
  484. dwFlag -- flag
  485. Return Value:
  486. Ptr to name space mneumonic string.
  487. NULL if unknown flag.
  488. --*/
  489. {
  490. return Dns_GetStringForValue(
  491. RnrNameSpaceMappingTable,
  492. dwFlag );
  493. }
  494. //
  495. // End table.c
  496. //