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.

304 lines
7.3 KiB

  1. /*++
  2. Copyright (c) 1995-1996 Microsoft Corporation
  3. Module Name :
  4. svmap.cpp
  5. Abstract:
  6. Provides name/id mapping for server variables. Used
  7. to allow server variable values to be cached by out
  8. of process applications.
  9. Author:
  10. Taylor Weiss ( TaylorW ) 19-Apr-1999
  11. Environment:
  12. Project:
  13. w3svc.dll private\inet\iis\svcs\w3\server
  14. wam.dll private\inet\iis\svcs\wam\object
  15. Functions Exported:
  16. Revision History:
  17. --*/
  18. #include <windows.h>
  19. #include <dbgutil.h>
  20. #include <svmap.h>
  21. // Define a table of name, len pairs for each cachable server variable
  22. #define DEFINE_SV( token ) { #token, sizeof(#token) - 1 },
  23. SV_CACHE_MAP::SV_NAME
  24. SV_CACHE_MAP::sm_rgNames[] =
  25. {
  26. ALL_SERVER_VARIABLES()
  27. };
  28. #undef DEFINE_SV
  29. BOOL
  30. SV_CACHE_MAP::Initialize( VOID )
  31. /*++
  32. Routine Description:
  33. Fills our hash table with name, id pairs.
  34. --*/
  35. {
  36. BOOL fInitialized = TRUE;
  37. DWORD dwHashValue;
  38. for( int i = 0; i < SV_COUNT; ++i )
  39. {
  40. dwHashValue = HashString( FindName(i) );
  41. DBG_ASSERT( dwHashValue < TABLE_SIZE );
  42. // It really isn't bad if we collide, it just means that
  43. // this particular server variable will not be cachable
  44. DBG_REQUIRE( m_rgHashTable[dwHashValue].InsertValue( i ) );
  45. }
  46. return fInitialized;
  47. }
  48. BOOL
  49. SV_CACHE_MAP::FindOrdinal(
  50. IN LPCSTR pszName,
  51. IN INT cchName,
  52. OUT DWORD * pdwOrdinal
  53. ) const
  54. /*++
  55. Routine Description:
  56. Lookup the server variable specified by name and return it's
  57. ordinal if found.
  58. NOTE - We should provide method that doesn't require the
  59. length!
  60. Return Value
  61. FALSE == Not found
  62. TRUE == Found - pdwOrdinal contains the server variable id.
  63. --*/
  64. {
  65. BOOL fFoundIt = FALSE;
  66. DBG_ASSERT( pdwOrdinal );
  67. DWORD dwHashValue = HashString(pszName);
  68. const HASH_TABLE_ENTRY &hte = m_rgHashTable[dwHashValue];
  69. if( !hte.IsSlotEmpty(0) )
  70. {
  71. // Hashed to a non empty entry
  72. if( hte.IsSlotEmpty(1) )
  73. {
  74. // It's the only one.
  75. *pdwOrdinal = hte.GetSlotValue(0);
  76. fFoundIt = StringMatches( pszName, cchName, *pdwOrdinal );
  77. }
  78. else
  79. {
  80. // Collision, need to compare strings with all
  81. // the non empty slots or until we get a hit
  82. DBG_ASSERT( !hte.IsSlotEmpty(0) );
  83. DBG_ASSERT( !hte.IsSlotEmpty(1) );
  84. if( StringMatches(pszName, cchName, hte.GetSlotValue(0)) )
  85. {
  86. *pdwOrdinal = hte.GetSlotValue(0);
  87. fFoundIt = TRUE;
  88. }
  89. else if( StringMatches(pszName, cchName, hte.GetSlotValue(1)) )
  90. {
  91. *pdwOrdinal = hte.GetSlotValue(1);
  92. fFoundIt = TRUE;
  93. }
  94. else if( !hte.IsSlotEmpty(2) &&
  95. StringMatches( pszName, cchName, hte.GetSlotValue(2) )
  96. )
  97. {
  98. *pdwOrdinal = hte.GetSlotValue(2);
  99. fFoundIt = TRUE;
  100. }
  101. else if( !hte.IsSlotEmpty(3) &&
  102. StringMatches( pszName, cchName, hte.GetSlotValue(3) )
  103. )
  104. {
  105. *pdwOrdinal = hte.GetSlotValue(3);
  106. fFoundIt = TRUE;
  107. }
  108. }
  109. }
  110. return fFoundIt;
  111. }
  112. VOID
  113. SV_CACHE_MAP::PrintToBuffer(
  114. IN CHAR * pchBuffer,
  115. IN OUT LPDWORD pcch
  116. ) const
  117. /*++
  118. Routine Description:
  119. Dump the hash table to pchBuffer.
  120. Note: We really aren't checking pcch as an in parameter. If
  121. the buffer is too small we will overwrite it.
  122. --*/
  123. {
  124. DWORD cb = 0;
  125. DBG_ASSERT( NULL != pchBuffer);
  126. cb += wsprintfA( pchBuffer + cb,
  127. "SV_CACHE_MAP(%p): sizeof(SV_CACHE_MAP)=%08x\n",
  128. this,
  129. sizeof(SV_CACHE_MAP)
  130. );
  131. DBG_ASSERT( cb < *pcch );
  132. // Gather some stats on the hash table
  133. DWORD dwEmptyEntries = 0;
  134. DWORD dwFilledEntries = 0;
  135. DWORD dwCollisions = 0;
  136. for( int i = 0; i < TABLE_SIZE; ++i )
  137. {
  138. if( m_rgHashTable[i].IsSlotEmpty(0) )
  139. {
  140. ++dwEmptyEntries;
  141. }
  142. else
  143. {
  144. ++dwFilledEntries;
  145. if( !m_rgHashTable[i].IsSlotEmpty(1) )
  146. {
  147. ++dwCollisions;
  148. }
  149. if( !m_rgHashTable[i].IsSlotEmpty(2) )
  150. {
  151. ++dwCollisions;
  152. }
  153. if( !m_rgHashTable[i].IsSlotEmpty(3) )
  154. {
  155. ++dwCollisions;
  156. }
  157. }
  158. }
  159. cb += wsprintfA( pchBuffer + cb,
  160. "Table Size = %d; Hashed Items = %d; Empty Entries = %d; "
  161. "Filled Entries = %d; Collisions = %d;\n",
  162. TABLE_SIZE, SV_COUNT, dwEmptyEntries, dwFilledEntries,
  163. dwCollisions
  164. );
  165. DBG_ASSERT( cb < *pcch );
  166. for( int j = 0; j < TABLE_SIZE; ++j )
  167. {
  168. if( !m_rgHashTable[j].IsSlotEmpty(0) )
  169. {
  170. cb += wsprintfA( pchBuffer + cb, "%03d", j );
  171. DBG_ASSERT( cb < *pcch );
  172. int k = 0;
  173. while( k < HASH_TABLE_ENTRY::MAX_ITEMS && !m_rgHashTable[j].IsSlotEmpty(k) )
  174. {
  175. cb += wsprintfA( pchBuffer + cb,
  176. " - %d (%s)",
  177. m_rgHashTable[j].GetSlotValue(k),
  178. sm_rgNames[m_rgHashTable[j].GetSlotValue(k)]
  179. );
  180. DBG_ASSERT( cb < *pcch );
  181. k++;
  182. }
  183. cb += wsprintfA( pchBuffer + cb, "\n" );
  184. DBG_ASSERT( cb < *pcch );
  185. }
  186. }
  187. *pcch = cb;
  188. return;
  189. }
  190. VOID
  191. SV_CACHE_MAP::Print( VOID ) const
  192. /*++
  193. Routine Description:
  194. --*/
  195. {
  196. // DANGER - This buffer size is much larger then necessary, but
  197. // changes to the PrintToBuffer or the underlying size of the
  198. // SV_CACHE_MAP may make this buffer insufficient.
  199. CHAR pchBuffer[ 10000 ];
  200. DWORD cb = sizeof( pchBuffer );
  201. PrintToBuffer( pchBuffer, &cb );
  202. DBG_ASSERT( cb < sizeof(pchBuffer) );
  203. DBGDUMP(( DBG_CONTEXT, pchBuffer ));
  204. }
  205. VOID
  206. SV_CACHE_LIST::GetBufferItems
  207. (
  208. IN OUT BUFFER_ITEM * pBufferItems,
  209. IN OUT DWORD * pdwBufferItemCount
  210. )
  211. /*++
  212. Routine Description:
  213. Initialize pBufferItems with the server variable ids that
  214. should be cached.
  215. --*/
  216. {
  217. DBG_ASSERT( pdwBufferItemCount && *pdwBufferItemCount >= SVID_COUNT );
  218. DWORD dwCount = 0;
  219. for( DWORD svid = 0; svid < SVID_COUNT; ++svid )
  220. {
  221. if( m_rgItems[svid].fCached )
  222. {
  223. if( dwCount < *pdwBufferItemCount )
  224. {
  225. pBufferItems[dwCount].svid = svid;
  226. pBufferItems[dwCount].dwOffset = 0;
  227. }
  228. ++dwCount;
  229. }
  230. }
  231. *pdwBufferItemCount = dwCount;
  232. }