Source code of Windows XP (NT5)
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.

246 lines
6.0 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // RegistryValueName.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CRegistryValueName class.
  10. //
  11. // Author:
  12. // Vijayendra Vasu (vvasu) February 5, 1999
  13. //
  14. // Revision History:
  15. // None.
  16. //
  17. /////////////////////////////////////////////////////////////////////////////
  18. #define UNICODE 1
  19. #define _UNICODE 1
  20. #include "clusrtlp.h"
  21. #include <string.h>
  22. #include <tchar.h>
  23. #include "RegistryValueName.h"
  24. /////////////////////////////////////////////////////////////////////////////
  25. // Type Definitions
  26. /////////////////////////////////////////////////////////////////////////////
  27. #define REGISTRY_SEPARATOR_CHAR L'\\'
  28. #define REGISTRY_SEPARATOR_STRING L"\\"
  29. /////////////////////////////////////////////////////////////////////////////
  30. //++
  31. //
  32. // CRegistryValueName::ScInit
  33. //
  34. // Routine Description:
  35. // Initialize the class.
  36. //
  37. // Arguments:
  38. // pszOldName [IN] Old value name.
  39. // pszOldKeyName [IN] Old key name.
  40. //
  41. // Return Value:
  42. // ERROR_NOT_ENOUGH_MEMORY Error allocating memory.
  43. //
  44. //--
  45. /////////////////////////////////////////////////////////////////////////////
  46. DWORD CRegistryValueName::ScInit(
  47. IN LPCWSTR pszOldName,
  48. IN LPCWSTR pszOldKeyName
  49. )
  50. {
  51. DWORD _sc = ERROR_SUCCESS;
  52. DWORD _cbBufSize;
  53. LPWSTR _pszBackslashPointer;
  54. // Dummy do to avoid goto
  55. do
  56. {
  57. if ( pszOldName == NULL )
  58. {
  59. FreeBuffers();
  60. m_pszKeyName = pszOldKeyName;
  61. break;
  62. } // if: no value name specified
  63. //
  64. // Look for a backslash in the name.
  65. //
  66. _pszBackslashPointer = ::wcsrchr( pszOldName, REGISTRY_SEPARATOR_CHAR );
  67. if ( _pszBackslashPointer == NULL )
  68. {
  69. //
  70. // The name does not contain a backslash.
  71. // No memory allocation need be made.
  72. //
  73. FreeBuffers();
  74. m_pszName = pszOldName;
  75. m_pszKeyName = pszOldKeyName;
  76. break;
  77. } // if: no backslash found
  78. //
  79. // Copy all characters after the last backslash into m_pszName.
  80. //
  81. _cbBufSize = ( ::lstrlenW( _pszBackslashPointer + 1 ) + 1 ) * sizeof( *m_pszName );
  82. //
  83. // Don't allocate memory if the existing buffer is already big enough to hold
  84. // the required string.
  85. //
  86. if ( _cbBufSize > m_cbNameBufferSize )
  87. {
  88. if ( m_cbNameBufferSize > 0 )
  89. {
  90. ::LocalFree( const_cast< LPWSTR >( m_pszName ) );
  91. m_cbNameBufferSize = 0;
  92. }
  93. m_pszName = static_cast< LPWSTR >( ::LocalAlloc( LMEM_FIXED, _cbBufSize ) );
  94. if ( m_pszName == NULL )
  95. {
  96. FreeBuffers();
  97. _sc = ERROR_NOT_ENOUGH_MEMORY;
  98. break;
  99. } // if: error allocating memory
  100. else
  101. {
  102. m_cbNameBufferSize = _cbBufSize;
  103. }
  104. } // if: the existing buffer is not big enough
  105. //
  106. // Copy everything past the last backslash to the name buffer.
  107. //
  108. ::lstrcpyW( const_cast< LPWSTR >( m_pszName ), _pszBackslashPointer + 1 );
  109. //
  110. // Everything before the last backslash is part of the key name path.
  111. // Append it to the specified key name.
  112. //
  113. {
  114. DWORD _cchNewKeyNameLength = 0;
  115. if ( pszOldKeyName != NULL )
  116. {
  117. _cchNewKeyNameLength = lstrlenW( pszOldKeyName );
  118. } // if: key name specified
  119. _cchNewKeyNameLength += static_cast< DWORD >( _pszBackslashPointer - pszOldName );
  120. //
  121. // nNewKeyNameLength is zero if pszOldKeyName is NULL and pszBackslashPointer
  122. // is the same as pszOldName (that is the backslash is the first character
  123. // of pszOldName). In this case, m_pszKeyName is to remain NULL.
  124. //
  125. if ( _cchNewKeyNameLength != 0 )
  126. {
  127. //
  128. // Allocate space for m_pszKeyName, the appended backslash character,
  129. // and the terminating '\0'.
  130. //
  131. _cbBufSize = _cchNewKeyNameLength * sizeof( *m_pszKeyName )
  132. + sizeof( REGISTRY_SEPARATOR_CHAR )
  133. + sizeof( L'\0' );
  134. //
  135. // Don't allocate memory if the existing buffer is already big enough to hold
  136. // the required string.
  137. //
  138. if ( _cbBufSize > m_cbKeyNameBufferSize )
  139. {
  140. if ( m_cbKeyNameBufferSize > 0 )
  141. {
  142. ::LocalFree( const_cast< LPWSTR >( m_pszKeyName ) );
  143. m_cbKeyNameBufferSize = 0;
  144. }
  145. m_pszKeyName = static_cast< LPWSTR >( ::LocalAlloc( LMEM_FIXED, _cbBufSize ) );
  146. if ( m_pszKeyName == NULL )
  147. {
  148. FreeBuffers();
  149. _sc = ERROR_NOT_ENOUGH_MEMORY;
  150. break;
  151. } // if: error allocating memory
  152. else
  153. {
  154. m_cbKeyNameBufferSize = _cbBufSize;
  155. }
  156. } // if: the existing buffer is not big enough
  157. if ( pszOldKeyName != NULL )
  158. {
  159. //
  160. // Copy the old key name if it exists into the new buffer and
  161. // append a backslash character to it.
  162. //
  163. ::lstrcpyW( const_cast< LPWSTR >( m_pszKeyName ), pszOldKeyName );
  164. ::lstrcatW( const_cast< LPWSTR >( m_pszKeyName ), REGISTRY_SEPARATOR_STRING );
  165. } // if: key name specified
  166. else
  167. {
  168. *(const_cast< LPWSTR >( m_pszKeyName )) = L'\0';
  169. } // if: no key name specified
  170. //
  171. // Concatenate all the characters of pszOldName upto (but not including)
  172. // the first backslash character.
  173. //
  174. ::wcsncat(
  175. const_cast< LPWSTR >( m_pszKeyName ),
  176. pszOldName,
  177. static_cast< DWORD >( _pszBackslashPointer - pszOldName )
  178. );
  179. } // if: cchNewKeyNameLength != 0
  180. }
  181. }
  182. while( FALSE ); // Dummy do-while
  183. return _sc;
  184. } //*** CRegistryValueName::ScInit()
  185. /////////////////////////////////////////////////////////////////////////////
  186. //++
  187. //
  188. // CRegistryValueName::FreeBuffers
  189. //
  190. // Routine Description:
  191. // Cleanup our allocations.
  192. //
  193. // Arguments:
  194. // None.
  195. //
  196. // Return Value:
  197. // None.
  198. //
  199. //--
  200. /////////////////////////////////////////////////////////////////////////////
  201. void CRegistryValueName::FreeBuffers( void )
  202. {
  203. if ( m_cbNameBufferSize > 0 )
  204. {
  205. ::LocalFree( const_cast< LPWSTR >( m_pszName ) );
  206. m_cbNameBufferSize = 0;
  207. }
  208. if ( m_cbKeyNameBufferSize > 0 )
  209. {
  210. ::LocalFree( const_cast< LPWSTR >( m_pszKeyName ) );
  211. m_cbKeyNameBufferSize = 0;
  212. }
  213. m_pszName = NULL;
  214. m_pszKeyName = NULL;
  215. } //*** CRegistryValueName::FreeBuffers()