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.

225 lines
6.4 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1994 **/
  4. /**********************************************************************/
  5. /*
  6. multisz.hxx
  7. This module contains a light weight multi-string class
  8. FILE HISTORY:
  9. KeithMo 20-Jan-1997 Created from string.hxx.
  10. */
  11. #ifndef _MULTISZ_HXX_
  12. #define _MULTISZ_HXX_
  13. # include <string.hxx>
  14. /*++
  15. class MULTISZ:
  16. Intention:
  17. A light-weight multi-string class supporting encapsulated string class.
  18. This object is derived from BUFFER class.
  19. It maintains following state:
  20. m_fValid - whether this object is valid -
  21. used only by MULTISZ() init functions
  22. * NYI: I need to kill this someday *
  23. m_cchLen - string length cached when we update the string.
  24. m_cStrings - number of strings.
  25. Member Functions:
  26. There are two categories of functions:
  27. 1) Safe Functions - which do integrity checking of state
  28. 2) UnSafe Functions - which do not do integrity checking, but
  29. enable writing to the data stream freely.
  30. (someday this will be enabled as Safe versions without
  31. problem for users)
  32. --*/
  33. class IRTL_DLLEXP MULTISZ : public BUFFER
  34. {
  35. public:
  36. MULTISZ()
  37. : BUFFER (),
  38. m_cchLen ( 0),
  39. m_cStrings(0)
  40. { Reset(); }
  41. // creates a stack version of the MULTISZ object - uses passed in stack buffer
  42. // MULTISZ does not free this pbInit on its own.
  43. MULTISZ( WCHAR * pbInit, DWORD cbInit)
  44. : BUFFER( (BYTE *) pbInit, cbInit),
  45. m_cchLen (0),
  46. m_cStrings(0)
  47. {}
  48. MULTISZ( const WCHAR * pchInit )
  49. : BUFFER (),
  50. m_cchLen ( 0),
  51. m_cStrings(0)
  52. { AuxInit(pchInit); }
  53. MULTISZ( const MULTISZ & str )
  54. : BUFFER (),
  55. m_cchLen ( 0),
  56. m_cStrings(0)
  57. { AuxInit( str.QueryStr()); }
  58. BOOL IsValid(VOID) const { return ( BUFFER::IsValid()) ; }
  59. //
  60. // Checks and returns TRUE if this string has no valid data else FALSE
  61. //
  62. BOOL IsEmpty( VOID) const { return ( *QueryStr() == L'\0'); }
  63. BOOL Append( const WCHAR * pchInit ) {
  64. return ((pchInit != NULL) ? (AuxAppend( pchInit,
  65. (DWORD) (::wcslen(pchInit) + 1) * sizeof(WCHAR)
  66. )) :
  67. TRUE);
  68. }
  69. BOOL Append( const WCHAR * pchInit, DWORD cchLen ) {
  70. return ((pchInit != NULL) ? (AuxAppend( pchInit,
  71. cchLen * sizeof(WCHAR))) :
  72. TRUE);
  73. }
  74. BOOL Append( STRU & str )
  75. { return AuxAppend( str.QueryStr(),
  76. (str.QueryCCH() + 1) * sizeof(WCHAR)); }
  77. // Resets the internal string to be NULL string. Buffer remains cached.
  78. VOID Reset( VOID)
  79. { DBG_ASSERT( QueryPtr() != NULL);
  80. QueryStr()[0] = L'\0';
  81. QueryStr()[1] = L'\0';
  82. m_cchLen = 2;
  83. m_cStrings = 0;
  84. }
  85. BOOL Copy( const WCHAR * pchInit, IN DWORD cbLen ) {
  86. if ( QueryPtr() ) { Reset(); }
  87. return ( (pchInit != NULL) ?
  88. AuxAppend( pchInit, cbLen, FALSE ):
  89. TRUE);
  90. }
  91. BOOL Copy( const MULTISZ & str )
  92. { return ( Copy(str.QueryStr(), str.QueryCB())); }
  93. //
  94. // Returns the number of bytes in the string including the terminating
  95. // NULLs
  96. //
  97. UINT QueryCB( VOID ) const
  98. { return ( m_cchLen * sizeof(WCHAR)); }
  99. //
  100. // Returns # of characters in the string including the terminating NULLs
  101. //
  102. UINT QueryCCH( VOID ) const { return (m_cchLen); }
  103. //
  104. // Returns # of strings in the multisz.
  105. //
  106. DWORD QueryStringCount( VOID ) const { return m_cStrings; }
  107. //
  108. // Makes a copy of the stored string in given buffer
  109. //
  110. BOOL CopyToBuffer( WCHAR * lpszBuffer, LPDWORD lpcch) const;
  111. //
  112. // Return the string buffer
  113. //
  114. WCHAR * QueryStrA( VOID ) const { return ( QueryStr()); }
  115. WCHAR * QueryStr( VOID ) const { return ((WCHAR *) QueryPtr()); }
  116. //
  117. // Makes a clone of the current string in the string pointer passed in.
  118. //
  119. BOOL
  120. Clone( OUT MULTISZ * pstrClone) const
  121. {
  122. return ((pstrClone == NULL) ?
  123. (SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
  124. (pstrClone->Copy( *this))
  125. );
  126. } // MULTISZ::Clone()
  127. //
  128. // Recalculates the length of *this because we've modified the buffers
  129. // directly
  130. //
  131. VOID RecalcLen( VOID )
  132. { m_cchLen = MULTISZ::CalcLength( QueryStr(), &m_cStrings ); }
  133. //
  134. // Calculate total character length of a MULTI_SZ, including the
  135. // terminating NULLs.
  136. //
  137. static DWORD CalcLength( const WCHAR * str,
  138. LPDWORD pcStrings = NULL );
  139. //
  140. // Determine if the MULTISZ contains a specific string.
  141. //
  142. BOOL FindString( const WCHAR * str );
  143. BOOL FindString( STRU & str )
  144. { return FindString( str.QueryStr() ); }
  145. //
  146. // Determine if the MULTISZ contains a specific string - case-insensitive
  147. //
  148. BOOL FindStringNoCase( const WCHAR * str );
  149. BOOL FindStringNoCase( STRU & str )
  150. { return FindStringNoCase( str.QueryStr() ); }
  151. //
  152. // Used for scanning a multisz.
  153. //
  154. const WCHAR * First( VOID ) const
  155. { return *QueryStr() == L'\0' ? NULL : QueryStr(); }
  156. const WCHAR * Next( const WCHAR * Current ) const
  157. { Current += ::wcslen( Current ) + 1;
  158. return *Current == L'\0' ? NULL : Current; }
  159. private:
  160. DWORD m_cchLen;
  161. DWORD m_cStrings;
  162. VOID AuxInit( const WCHAR * pInit );
  163. BOOL AuxAppend( const WCHAR * pInit,
  164. UINT cbStr, BOOL fAddSlop = TRUE );
  165. };
  166. //
  167. // Quick macro for declaring a MULTISZ that will use stack memory of <size>
  168. // bytes. If the buffer overflows then a heap buffer will be allocated
  169. //
  170. #define STACK_MULTISZ( name, size ) WCHAR __ach##name[size]; \
  171. MULTISZ name( __ach##name, sizeof( __ach##name ))
  172. #endif // !_MULTISZ_HXX_