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.

383 lines
9.3 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // RegistryValueName.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CRegistryValueName class.
  10. //
  11. // Maintained by:
  12. // George Potts (GPotts) 22-APR-2002
  13. // Vijayendra Vasu (vvasu) 05-FEB-1999
  14. //
  15. // Revision History:
  16. // None.
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #define UNICODE 1
  20. #define _UNICODE 1
  21. #pragma warning( push ) // Make sure the includes don't change our pragmas.
  22. #include "clusrtlp.h"
  23. #include <string.h>
  24. #include <tchar.h>
  25. #include "RegistryValueName.h"
  26. #include <strsafe.h>
  27. #pragma warning( pop )
  28. /////////////////////////////////////////////////////////////////////////////
  29. //
  30. // Set the file's warning level to 4. We can't yet do this
  31. // for the whole directory.
  32. //
  33. /////////////////////////////////////////////////////////////////////////////
  34. #pragma warning( push, 4 )
  35. /////////////////////////////////////////////////////////////////////////////
  36. //++
  37. //
  38. // ScReallocateString
  39. //
  40. // Routine Description:
  41. // Delete the old buffer, allocate a new one, and copy in the new string.
  42. //
  43. // Arguments:
  44. // ppszOldStringInout
  45. // pcchOldStringInout [IN/OUT]
  46. // pszNewString [IN]
  47. //
  48. // Return Value:
  49. // ERROR_NOT_ENOUGH_MEMORY Error allocating memory.
  50. //
  51. // Win32 Error
  52. //
  53. //--
  54. /////////////////////////////////////////////////////////////////////////////
  55. DWORD
  56. ScReallocateString(
  57. LPWSTR * ppszOldStringInout
  58. , size_t * pcchOldStringInout
  59. , LPCWSTR pszNewString
  60. )
  61. {
  62. DWORD sc = ERROR_SUCCESS;
  63. HRESULT hr;
  64. LPWSTR pszTemp = NULL;
  65. size_t cchString;
  66. //
  67. // If is safe to do this without checking since
  68. // we control the args that are sent to this
  69. // function.
  70. //
  71. delete [] *ppszOldStringInout;
  72. *ppszOldStringInout = NULL;
  73. *pcchOldStringInout = 0;
  74. //
  75. // If pszNewString is NULL then the it is appropriate
  76. // the ppszOldStringInout remain NULL too.
  77. //
  78. if ( pszNewString == NULL )
  79. {
  80. sc = ERROR_SUCCESS;
  81. goto Cleanup;
  82. } // if:
  83. cchString = wcslen( pszNewString ) + 1;
  84. pszTemp = new WCHAR[ cchString ];
  85. if ( pszTemp == NULL )
  86. {
  87. sc = ERROR_NOT_ENOUGH_MEMORY;
  88. goto Cleanup;
  89. } // if:
  90. hr = StringCchCopyW( pszTemp, cchString, pszNewString );
  91. if ( FAILED( hr ) )
  92. {
  93. sc = HRESULT_CODE( hr );
  94. goto Cleanup;
  95. } // if:
  96. *ppszOldStringInout = pszTemp;
  97. *pcchOldStringInout = cchString;
  98. pszTemp = NULL;
  99. Cleanup:
  100. delete [] pszTemp;
  101. return sc;
  102. } //*** ScReallocateString
  103. /////////////////////////////////////////////////////////////////////////////
  104. //++
  105. //
  106. // CRegistryValueName::ScAssignName
  107. //
  108. // Routine Description:
  109. // Deallocates the old buffer, allocates a new one, and initialize
  110. // it to the string in the pszNewNameIn buffer.
  111. //
  112. // Arguments:
  113. // pszName [IN] Name to assign to the value
  114. //
  115. // Return Value:
  116. // ERROR_NOT_ENOUGH_MEMORY Error allocating memory.
  117. //
  118. //--
  119. /////////////////////////////////////////////////////////////////////////////
  120. DWORD
  121. CRegistryValueName::ScAssignName(
  122. LPCWSTR pszNewNameIn
  123. )
  124. {
  125. return ScReallocateString( &m_pszName, &m_cchName, pszNewNameIn );
  126. } //*** ScAssignName
  127. /////////////////////////////////////////////////////////////////////////////
  128. //++
  129. //
  130. // CRegistryValueName::ScAssignKeyName
  131. //
  132. // Routine Description:
  133. // Deallocates the old buffer, allocates a new one, and initialize
  134. // it to the string in the pszNewNameIn buffer.
  135. //
  136. // Arguments:
  137. // pszName [IN] Name to assign to the value
  138. //
  139. // Return Value:
  140. // ERROR_NOT_ENOUGH_MEMORY Error allocating memory.
  141. //
  142. //--
  143. /////////////////////////////////////////////////////////////////////////////
  144. DWORD
  145. CRegistryValueName::ScAssignKeyName(
  146. LPCWSTR pszNewNameIn
  147. )
  148. {
  149. return ScReallocateString( &m_pszKeyName, &m_cchKeyName, pszNewNameIn );
  150. } //*** ScAssignKeyName
  151. /////////////////////////////////////////////////////////////////////////////
  152. //++
  153. //
  154. // CRegistryValueName::ScInit
  155. //
  156. // Routine Description:
  157. // Initialize the class.
  158. //
  159. // Arguments:
  160. // pszNameIn [IN] Old value name.
  161. // pszKeyNameIn [IN] Old key name.
  162. //
  163. // Return Value:
  164. // ERROR_NOT_ENOUGH_MEMORY Error allocating memory.
  165. //
  166. //--
  167. /////////////////////////////////////////////////////////////////////////////
  168. DWORD CRegistryValueName::ScInit(
  169. LPCWSTR pszNameIn
  170. , LPCWSTR pszKeyNameIn
  171. )
  172. {
  173. DWORD sc = ERROR_SUCCESS;
  174. LPWSTR pszBackslashPointer;
  175. size_t cchTemp = 0;
  176. HRESULT hr;
  177. //
  178. // pszNameIn corresponds to the value name, and pszKeyNameIn corresponds to
  179. // the key name. If the value name is null we just store the key name.
  180. // If the key name doesn't contain a backslash we just store each
  181. // of the values. If the value name contains a backslash we pull out
  182. // everything before it and slap it on the key name.
  183. //
  184. // Example:
  185. //
  186. // { "x\\y", "a\\b" } => { "y", "a\\b\\x" }
  187. //
  188. //
  189. //
  190. // Start with a clean slate.
  191. //
  192. FreeBuffers();
  193. if ( pszNameIn == NULL )
  194. {
  195. sc = ScAssignKeyName( pszKeyNameIn );
  196. goto Cleanup;
  197. } // if: no value name specified
  198. //
  199. // Look for a backslash in the name.
  200. //
  201. pszBackslashPointer = wcsrchr( pszNameIn, L'\\' );
  202. if ( pszBackslashPointer == NULL )
  203. {
  204. //
  205. // The name does not contain a backslash.
  206. // No memory allocation need be made.
  207. //
  208. sc = ScAssignName( pszNameIn );
  209. if ( sc != ERROR_SUCCESS )
  210. {
  211. goto Cleanup;
  212. } // if:
  213. sc = ScAssignKeyName( pszKeyNameIn );
  214. if ( sc != ERROR_SUCCESS )
  215. {
  216. goto Cleanup;
  217. } // if:
  218. goto Cleanup;
  219. } // if: no backslash found
  220. //
  221. // Copy everything past the backslash to m_pszName.
  222. //
  223. sc = ScAssignName( pszBackslashPointer + 1 );
  224. if ( sc != ERROR_SUCCESS )
  225. {
  226. goto Cleanup;
  227. } // if:
  228. //
  229. // Count up how much buffer we need - pszKeyNameIn + everything
  230. // before the backslash.
  231. //
  232. m_cchKeyName = 0;
  233. if ( pszKeyNameIn != NULL )
  234. {
  235. m_cchKeyName = wcslen( pszKeyNameIn );
  236. } // if: key name specified
  237. m_cchKeyName += ( pszBackslashPointer - pszNameIn );
  238. //
  239. // If pszKeyNameIn wasn't specified and there's nothing before the backslash
  240. // then there's nothing to do - we already assigned m_pszName.
  241. //
  242. if ( m_cchKeyName == 0 )
  243. {
  244. goto Cleanup;
  245. } // if:
  246. //
  247. // Add one for a possible separating backslash and another for NULL.
  248. //
  249. m_cchKeyName += 2;
  250. m_pszKeyName = new WCHAR[ m_cchKeyName ];
  251. if ( m_pszKeyName == NULL )
  252. {
  253. sc = ERROR_NOT_ENOUGH_MEMORY;
  254. goto Cleanup;
  255. } // if:
  256. //
  257. // If we have pszKeyNameIn then copy that to the beginning of the buffer.
  258. //
  259. if ( pszKeyNameIn != NULL )
  260. {
  261. WCHAR * pwch = NULL;
  262. //
  263. // Copy the old key name if it exists into the new buffer and
  264. // append a backslash character to it.
  265. //
  266. hr = StringCbCopyExW( m_pszKeyName, m_cchKeyName, pszKeyNameIn, &pwch, NULL, 0 );
  267. if ( FAILED( hr ) )
  268. {
  269. sc = HRESULT_CODE( hr );
  270. goto Cleanup;
  271. } // if:
  272. //
  273. // Make sure we don't append a second backslash.
  274. //
  275. cchTemp = wcslen( m_pszKeyName );
  276. if ( ( cchTemp > 0 ) && ( m_pszKeyName[ cchTemp - 1 ] != L'\\' ) )
  277. {
  278. *pwch = L'\\';
  279. pwch++;
  280. *pwch = L'\0';
  281. } // if:
  282. } // if: key name specified
  283. else
  284. {
  285. //
  286. // Make sure we're null-terminated for the concatenation.
  287. //
  288. m_pszKeyName[ 0 ] = L'\0';
  289. } // else: no key name specified
  290. //
  291. // Concatenate all the characters of pszNameIn up to (but not including)
  292. // the last backslash character.
  293. //
  294. cchTemp = pszBackslashPointer - pszNameIn;
  295. hr = StringCchCatNW( m_pszKeyName, m_cchKeyName, pszNameIn, cchTemp );
  296. if ( FAILED( hr ) )
  297. {
  298. sc = HRESULT_CODE( hr );
  299. goto Cleanup;
  300. } // if:
  301. Cleanup:
  302. if ( sc != ERROR_SUCCESS )
  303. {
  304. FreeBuffers();
  305. } // if:
  306. return sc;
  307. } //*** CRegistryValueName::ScInit
  308. /////////////////////////////////////////////////////////////////////////////
  309. //++
  310. //
  311. // CRegistryValueName::FreeBuffers
  312. //
  313. // Routine Description:
  314. // Cleanup our allocations.
  315. //
  316. // Arguments:
  317. // None.
  318. //
  319. // Return Value:
  320. // None.
  321. //
  322. //--
  323. /////////////////////////////////////////////////////////////////////////////
  324. void
  325. CRegistryValueName::FreeBuffers( void )
  326. {
  327. delete [] m_pszName;
  328. m_pszName = NULL;
  329. m_cchName = 0;
  330. delete [] m_pszKeyName;
  331. m_pszKeyName = NULL;
  332. m_cchKeyName = 0;
  333. } //*** CRegistryValueName::FreeBuffers
  334. #pragma warning( pop ) // Reset the pragma level.