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.

301 lines
7.5 KiB

  1. /****************************************************************************/
  2. // valinfo.h
  3. //
  4. // Copyright (C) 1997-1999 Microsoft Corp.
  5. /****************************************************************************/
  6. #include "ValInfo.h"
  7. ValueFullInfo::ValueFullInfo( KeyNode *pKey ) :
  8. pInfo(NULL), pSzName(NULL), pKeyNode(NULL)
  9. {
  10. pKeyNode = pKey;
  11. KeyFullInfo *pKeyInfo;
  12. if ( NT_SUCCESS ( status = pKeyNode->GetFullInfo( &pKeyInfo) ) )
  13. {
  14. size = sizeof(KEY_VALUE_FULL_INFORMATION) +
  15. (pKeyInfo->Ptr()->MaxValueNameLen + 1)*sizeof(WCHAR) +
  16. pKeyInfo->Ptr()->MaxValueDataLen;
  17. pInfo = ( KEY_VALUE_FULL_INFORMATION *)RtlAllocateHeap(RtlProcessHeap(), 0, size );
  18. if (!pInfo) {
  19. status = STATUS_NO_MEMORY;
  20. }
  21. else
  22. status = STATUS_SUCCESS;
  23. }
  24. }
  25. PCWSTR ValueFullInfo::SzName()
  26. {
  27. if (!pSzName)
  28. {
  29. ULONG size = pInfo->NameLength + sizeof(WCHAR);
  30. pSzName = (PWSTR) RtlAllocateHeap(RtlProcessHeap(), 0, size );
  31. if (!pSzName)
  32. {
  33. status = STATUS_NO_MEMORY;
  34. }
  35. else
  36. {
  37. wcsncpy( pSzName, pInfo->Name, pInfo->NameLength/sizeof(WCHAR) );
  38. pSzName[ pInfo->NameLength/sizeof( WCHAR) ] = L'\0';
  39. status = STATUS_SUCCESS;
  40. }
  41. }
  42. return pSzName;
  43. }
  44. BOOLEAN ValueFullInfo::Compare( ValueFullInfo *pOther )
  45. {
  46. status = STATUS_SUCCESS; // we don't expect errors in here
  47. if ( pOther->Ptr()->Type != Ptr()->Type)
  48. {
  49. return FALSE;
  50. }
  51. if ( pOther->Ptr()->DataLength != Ptr()->DataLength)
  52. {
  53. return FALSE;
  54. }
  55. if ( pOther->Ptr()->NameLength != Ptr()->NameLength)
  56. {
  57. return FALSE;
  58. }
  59. for (ULONG i = 0; i < Ptr()->NameLength / sizeof( WCHAR) ; i++)
  60. {
  61. if ( Ptr()->Name[i] != pOther->Ptr()->Name[i])
  62. {
  63. return FALSE;
  64. }
  65. }
  66. for (i = 0; i < Ptr()->DataLength; i++)
  67. {
  68. if ( ((PCHAR)( (PCHAR)Ptr() + Ptr()->DataOffset ))[i] !=
  69. ((PCHAR) ( (PCHAR)(pOther->Ptr()) +
  70. pOther->Ptr()->DataOffset) )[i] )
  71. return FALSE;
  72. }
  73. return TRUE;
  74. }
  75. ValueFullInfo::~ValueFullInfo()
  76. {
  77. if (pInfo)
  78. {
  79. RtlFreeHeap( RtlProcessHeap(), 0, pInfo);
  80. }
  81. if ( pSzName )
  82. {
  83. RtlFreeHeap( RtlProcessHeap(), 0, pSzName );
  84. }
  85. }
  86. NTSTATUS ValueFullInfo::Query(PCWSTR pValueName )
  87. {
  88. ULONG resultSize;
  89. ULONG numberOfAttempts=0;
  90. if ( NT_SUCCESS( pKeyNode->Status() ) )
  91. {
  92. UNICODE_STRING tmpName;
  93. RtlInitUnicodeString( &tmpName, pValueName);
  94. status = NtQueryValueKey( pKeyNode->Key() ,
  95. &tmpName,
  96. Type(),
  97. Ptr(),
  98. Size(),
  99. &resultSize);
  100. if ( (status == STATUS_BUFFER_OVERFLOW ) ||
  101. ( status == STATUS_BUFFER_TOO_SMALL ) )
  102. {
  103. // @@@ this can never happen right?
  104. // Since the key param imposes a max size on any valule
  105. // under the key.
  106. }
  107. }
  108. else
  109. status = STATUS_OBJECT_NAME_NOT_FOUND; // need to call open or key is not found
  110. return status;
  111. }
  112. NTSTATUS ValueFullInfo::Delete(PCWSTR pValueName )
  113. {
  114. UNICODE_STRING tmpName;
  115. RtlInitUnicodeString( &tmpName, pValueName);
  116. if (NT_SUCCESS( status = pKeyNode->Status() ) )
  117. {
  118. status = NtDeleteValueKey( pKeyNode->Key(), &tmpName );
  119. }
  120. return status;
  121. }
  122. NTSTATUS ValueFullInfo::Create( ValueFullInfo *pNew )
  123. {
  124. UNICODE_STRING uniString;
  125. uniString.Buffer = pNew->Ptr()->Name;
  126. uniString.Length = (USHORT)pNew->Ptr()->NameLength;
  127. uniString.MaximumLength = uniString.Length + 2;
  128. if (NT_SUCCESS( status = pKeyNode->Status() ) )
  129. {
  130. status = NtSetValueKey( pKeyNode->Key(),
  131. &uniString,
  132. 0,
  133. pNew->Ptr()->Type,
  134. (PCHAR)pNew->Ptr()+
  135. pNew->Ptr()->DataOffset,
  136. pNew->Ptr()->DataLength);
  137. }
  138. return status;
  139. }
  140. void ValueFullInfo::Print( FILE *fp )
  141. {
  142. fwprintf( fp, L"name=%ws, size= %d, type=%d \n",
  143. SzName(), Size(), Type() );
  144. fwprintf( fp, L"DataOffset=%d, DataLength=%d, NameLength=%d \n",
  145. Ptr()->DataOffset, Ptr()->DataLength, Ptr()->NameLength );
  146. for ( ULONG i =0; i < Ptr()->NameLength + Ptr()->DataLength; i++)
  147. {
  148. if ( !(i % 32) )
  149. {
  150. fwprintf(fp,L"\n");
  151. fwprintf(fp,L"i=%3d ,",i);
  152. }
  153. fwprintf( fp, L"%2x ", ((BYTE *)(Ptr()->Name))[i] );
  154. }
  155. fwprintf(fp,L"\n");
  156. fflush( fp );
  157. }
  158. ValuePartialInfo::ValuePartialInfo( KeyNode *pKey , ULONG defaultSize ):
  159. pInfo(NULL), pKeyNode(NULL)
  160. {
  161. pKeyNode = pKey;
  162. if (defaultSize)
  163. {
  164. size = defaultSize;
  165. }
  166. else
  167. {
  168. size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG);
  169. pInfo = ( KEY_VALUE_PARTIAL_INFORMATION *)RtlAllocateHeap(
  170. RtlProcessHeap(), 0, size );
  171. }
  172. if (!pInfo) {
  173. status = STATUS_NO_MEMORY;
  174. pInfo=NULL;
  175. }
  176. else
  177. status = STATUS_SUCCESS;
  178. }
  179. ValuePartialInfo::~ValuePartialInfo()
  180. {
  181. if (pInfo)
  182. {
  183. RtlFreeHeap( RtlProcessHeap(), 0, pInfo);
  184. }
  185. }
  186. NTSTATUS ValuePartialInfo::Query( PCWSTR pValueName )
  187. {
  188. ULONG resultSize;
  189. ULONG numberOfAttempts=0;
  190. UNICODE_STRING tmpName;
  191. if (!pKeyNode->Key())
  192. {
  193. // not having a key associated with this registry should mean that any further operation
  194. // must return an expected error status without calling the underlying nt apis, since
  195. // appverifier will detect such as a potential bug.
  196. status = STATUS_INVALID_HANDLE;
  197. return status;
  198. }
  199. RtlInitUnicodeString( &tmpName, pValueName);
  200. tryAgain:
  201. status = NtQueryValueKey(pKeyNode->Key(),
  202. &tmpName,
  203. Type(),
  204. Ptr(),
  205. Size(),
  206. &resultSize);
  207. if ( (status == STATUS_BUFFER_OVERFLOW ) ||
  208. ( status == STATUS_BUFFER_TOO_SMALL ) )
  209. {
  210. RtlFreeHeap( RtlProcessHeap(), 0, pInfo);
  211. size = resultSize;
  212. pInfo = ( KEY_VALUE_PARTIAL_INFORMATION *)RtlAllocateHeap(
  213. RtlProcessHeap(), 0, size );
  214. numberOfAttempts++;
  215. if ( numberOfAttempts < 10 )
  216. {
  217. goto tryAgain;
  218. }
  219. // else, we bail out, don't want to hang here, let the caller worry about this.
  220. }
  221. return status;
  222. }
  223. NTSTATUS ValuePartialInfo::Delete(PCWSTR pValueName )
  224. {
  225. UNICODE_STRING tmpName;
  226. RtlInitUnicodeString( &tmpName, pValueName);
  227. if (!pKeyNode->Key())
  228. {
  229. // not having a key associated with this registry should mean that any further operation
  230. // must return an expected error status without calling the underlying nt apis, since
  231. // appverifier will detect such as a potential bug.
  232. status = STATUS_INVALID_HANDLE;
  233. return status;
  234. }
  235. status = NtDeleteValueKey( pKeyNode->Key(), &tmpName );
  236. return status;
  237. }