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.

230 lines
6.5 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 _MULTISZA_HXX_
  12. #define _MULTISZA_HXX_
  13. #include <stringa.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 MULTISZA : public BUFFER
  34. {
  35. public:
  36. MULTISZA()
  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. MULTISZA(CHAR * pbInit, DWORD cbInit)
  44. : BUFFER( (BYTE *) pbInit, cbInit),
  45. m_cchLen (0),
  46. m_cStrings(0)
  47. {}
  48. MULTISZA( const CHAR * pchInit )
  49. : BUFFER (),
  50. m_cchLen ( 0),
  51. m_cStrings(0)
  52. { AuxInit( (const BYTE * ) pchInit); }
  53. MULTISZA( const MULTISZA & str )
  54. : BUFFER (),
  55. m_cchLen ( 0),
  56. m_cStrings(0)
  57. { AuxInit( (const BYTE * ) str.QueryStr()); }
  58. BOOL IsValid() 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() == '\0'); }
  63. BOOL Append( const CHAR * pchInit ) {
  64. return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
  65. (DWORD)strlen(pchInit) + 1)) :
  66. TRUE);
  67. }
  68. BOOL AppendW(const WCHAR * pchInit) {
  69. return ((pchInit != NULL) ? (AuxAppendW(pchInit,
  70. (DWORD)wcslen(pchInit) + 1)) :
  71. TRUE);
  72. }
  73. BOOL Append( const CHAR * pchInit, DWORD cchLen ) {
  74. return ((pchInit != NULL) ? (AuxAppend( (const BYTE * ) pchInit,
  75. cchLen)) :
  76. TRUE);
  77. }
  78. BOOL AppendW(const WCHAR * pchInit, DWORD cchLen) {
  79. return ((pchInit != NULL) ? (AuxAppendW(pchInit,
  80. cchLen)) :
  81. TRUE);
  82. }
  83. BOOL Append( STRA & str )
  84. { return AuxAppend( (const BYTE * ) str.QueryStr(),
  85. (str.QueryCCH() + 1)); }
  86. // Resets the internal string to be NULL string. Buffer remains cached.
  87. VOID Reset( VOID)
  88. { DBG_ASSERT( QueryPtr() != NULL);
  89. QueryStr()[0] = '\0';
  90. QueryStr()[1] = '\0';
  91. m_cchLen = 2;
  92. m_cStrings = 0;
  93. }
  94. BOOL Copy( const CHAR * pchInit, IN DWORD cbLen ) {
  95. if ( QueryPtr() ) { Reset(); }
  96. return ( (pchInit != NULL) ?
  97. AuxAppend( (const BYTE *) pchInit, cbLen, FALSE ):
  98. TRUE);
  99. }
  100. BOOL Copy( const MULTISZA & str )
  101. { return ( Copy(str.QueryStr(), str.QueryCCH())); }
  102. //
  103. // Returns the number of bytes in the string including the terminating
  104. // NULLs
  105. //
  106. UINT QueryCB( VOID ) const
  107. { return m_cchLen; }
  108. //
  109. // Returns # of characters in the string including the terminating NULLs
  110. //
  111. UINT QueryCCH( VOID ) const { return m_cchLen; }
  112. //
  113. // Returns # of strings in the multisz.
  114. //
  115. DWORD QueryStringCount( VOID ) const { return m_cStrings; }
  116. //
  117. // Makes a copy of the stored string in given buffer
  118. //
  119. BOOL CopyToBuffer( CHAR * lpszBuffer, LPDWORD lpcch) const;
  120. //
  121. // Return the string buffer
  122. //
  123. CHAR * QueryStr( VOID ) const { return ((CHAR *) QueryPtr()); }
  124. //
  125. // Makes a clone of the current string in the string pointer passed in.
  126. //
  127. BOOL
  128. Clone( OUT MULTISZA * pstrClone) const
  129. {
  130. return ((pstrClone == NULL) ?
  131. (SetLastError(ERROR_INVALID_PARAMETER), FALSE) :
  132. (pstrClone->Copy( *this))
  133. );
  134. } // MULTISZA::Clone()
  135. //
  136. // Recalculates the length of *this because we've modified the buffers
  137. // directly
  138. //
  139. VOID RecalcLen( VOID )
  140. { m_cchLen = CalcLength( QueryStr(), &m_cStrings ); }
  141. //
  142. // Calculate total character length of a MULTI_SZ, including the
  143. // terminating NULLs.
  144. //
  145. static DWORD CalcLength( const CHAR * str,
  146. LPDWORD pcStrings = NULL );
  147. //
  148. // Determine if the MULTISZ contains a specific string.
  149. //
  150. BOOL FindString( const CHAR * str );
  151. BOOL FindString( STRA & str )
  152. { return FindString( str.QueryStr() ); }
  153. //
  154. // Used for scanning a multisz.
  155. //
  156. const CHAR * First( VOID ) const
  157. { return *QueryStr() == '\0' ? NULL : QueryStr(); }
  158. const CHAR * Next( const CHAR * Current ) const
  159. { Current += strlen( Current ) + 1;
  160. return *Current == '\0' ? NULL : Current; }
  161. private:
  162. DWORD m_cchLen;
  163. DWORD m_cStrings;
  164. VOID AuxInit( const BYTE * pInit );
  165. BOOL AuxAppend( const BYTE * pInit,
  166. UINT cbStr,
  167. BOOL fAddSlop = TRUE );
  168. BOOL AuxAppendW(LPCWSTR pInit,
  169. UINT cbStr,
  170. BOOL fAddSlop = TRUE );
  171. };
  172. //
  173. // Quick macro for declaring a MULTISZ that will use stack memory of <size>
  174. // bytes. If the buffer overflows then a heap buffer will be allocated
  175. //
  176. #define STACK_MULTISZA(name, size) CHAR __ach##name[size]; \
  177. MULTISZA name(__ach##name, sizeof(__ach##name))
  178. #endif // !_MULTISZ_HXX_