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.

399 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. cmname.c
  5. Abstract:
  6. Provides routines for handling name comparisons and converting to/from the registry
  7. compressed name format.
  8. Author:
  9. John Vert (jvert) 28-Oct-1993
  10. Revision History:
  11. --*/
  12. #include "cmp.h"
  13. #ifdef ALLOC_PRAGMA
  14. #pragma alloc_text(PAGE,CmpNameSize)
  15. #pragma alloc_text(PAGE,CmpCopyName)
  16. #pragma alloc_text(PAGE,CmpCompressedNameSize)
  17. #pragma alloc_text(PAGE,CmpCopyCompressedName)
  18. #pragma alloc_text(PAGE,CmpCompareCompressedName)
  19. #pragma alloc_text(PAGE,CmpCompareUnicodeString)
  20. #pragma alloc_text(PAGE,CmpCompareTwoCompressedNames)
  21. #endif
  22. USHORT
  23. CmpNameSize(
  24. IN PHHIVE Hive,
  25. IN PUNICODE_STRING Name
  26. )
  27. /*++
  28. Routine Description:
  29. Determines the space needed to store a given string in the registry. May apply
  30. any relevant compression to compute the length, but the compression used is
  31. guaranteed to be the same as CmpCopyName.
  32. Arguments:
  33. Hive - supplies the hive control structure (for version checking)
  34. Name - Supplies the unicode string to be copied into the registry.
  35. Return Value:
  36. The number of bytes of storage required to store this name.
  37. --*/
  38. {
  39. ULONG i;
  40. if (Hive->Version == 1) {
  41. return(Name->Length);
  42. }
  43. for (i=0;i<Name->Length/sizeof(WCHAR);i++) {
  44. if ((USHORT)Name->Buffer[i] > (UCHAR)-1) {
  45. return(Name->Length);
  46. }
  47. }
  48. return(Name->Length / sizeof(WCHAR));
  49. }
  50. USHORT
  51. CmpCopyName(
  52. IN PHHIVE Hive,
  53. IN PWCHAR Destination,
  54. IN PUNICODE_STRING Source
  55. )
  56. /*++
  57. Routine Description:
  58. Copies the given unicode name into the registry, applying any relevant compression
  59. at the same time.
  60. Arguments:
  61. Hive - supplies the hive control structure (For version checking)
  62. Destination - Supplies the destination of the given string.
  63. Source - Supplies the unicode string to copy into the registry.
  64. Return Value:
  65. Number of bytes of storage copied
  66. --*/
  67. {
  68. ULONG i;
  69. if (Hive->Version==1) {
  70. RtlCopyMemory(Destination,Source->Buffer, Source->Length);
  71. return(Source->Length);
  72. }
  73. for (i=0;i<Source->Length/sizeof(WCHAR);i++) {
  74. if ((USHORT)Source->Buffer[i] > (UCHAR)-1) {
  75. RtlCopyMemory(Destination,Source->Buffer, Source->Length);
  76. return(Source->Length);
  77. }
  78. ((PUCHAR)Destination)[i] = (UCHAR)(Source->Buffer[i]);
  79. }
  80. return(Source->Length / sizeof(WCHAR));
  81. }
  82. USHORT
  83. CmpCompressedNameSize(
  84. IN PWCHAR Name,
  85. IN ULONG Length
  86. )
  87. /*++
  88. Routine Description:
  89. Computes the length of the unicode string that the given compressed name
  90. expands into.
  91. Arguments:
  92. Name - Supplies the compressed name.
  93. Length - Supplies the length in bytes of the compressed name
  94. Return Value:
  95. The number of bytes of storage required to hold the Unicode expanded name.
  96. --*/
  97. {
  98. UNREFERENCED_PARAMETER (Name);
  99. return((USHORT)Length*sizeof(WCHAR));
  100. }
  101. VOID
  102. CmpCopyCompressedName(
  103. IN PWCHAR Destination,
  104. IN ULONG DestinationLength,
  105. IN PWCHAR Source,
  106. IN ULONG SourceLength
  107. )
  108. /*++
  109. Routine Description:
  110. Copies a compressed name from the registry and expands it to Unicode.
  111. Arguments:
  112. Destination - Supplies the destination Unicode buffer
  113. DestinationLength - Supplies the max length of the destination buffer in bytes
  114. Source - Supplies the compressed string.
  115. SourceLength - Supplies the length of the compressed string in bytes
  116. Return Value:
  117. None.
  118. --*/
  119. {
  120. ULONG i;
  121. ULONG Chars;
  122. Chars = (DestinationLength/sizeof(WCHAR) < SourceLength)
  123. ? DestinationLength/sizeof(WCHAR)
  124. : SourceLength;
  125. for (i=0;i<Chars;i++) {
  126. Destination[i] = (WCHAR)(((PUCHAR)Source)[i]);
  127. }
  128. }
  129. LONG
  130. CmpCompareCompressedName(
  131. IN PUNICODE_STRING SearchName,
  132. IN PWCHAR CompressedName,
  133. IN ULONG NameLength,
  134. IN ULONG CompareFlags
  135. )
  136. /*++
  137. Routine Description:
  138. Compares a compressed registry string to a Unicode string. Does a case-insensitive
  139. comparison.
  140. Arguments:
  141. SearchName - Supplies the Unicode string to be compared
  142. CompressedName - Supplies the compressed string to be compared
  143. NameLength - Supplies the length of the compressed string
  144. Return Value:
  145. 0 = SearchName == CompressedName (of Cell)
  146. < 0 = SearchName < CompressedName
  147. > 0 = SearchName > CompressedName
  148. --*/
  149. {
  150. WCHAR *s1;
  151. UCHAR *s2;
  152. USHORT n1, n2;
  153. WCHAR c1;
  154. WCHAR c2;
  155. LONG cDiff;
  156. s1 = SearchName->Buffer;
  157. s2 = (UCHAR *)CompressedName;
  158. n1 = (USHORT )(SearchName->Length / sizeof(WCHAR));
  159. n2 = (USHORT )(NameLength);
  160. while (n1 && n2) {
  161. c1 = *s1++;
  162. c2 = (WCHAR)(*s2++);
  163. //
  164. // there is a 2/3 chance they match without doing the upercase comparison.
  165. //
  166. if( c1 != c2 ) {
  167. c1 = (CompareFlags&CMP_SOURCE_UP)?c1:CmUpcaseUnicodeChar(c1);
  168. c2 = (CompareFlags&CMP_DEST_UP)?c2:CmUpcaseUnicodeChar(c2);
  169. if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
  170. return( cDiff );
  171. }
  172. }
  173. n1--;
  174. n2--;
  175. }
  176. return( n1 - n2 );
  177. }
  178. LONG
  179. CmpCompareUnicodeString(
  180. IN PUNICODE_STRING SourceName,
  181. IN PUNICODE_STRING DestName,
  182. IN ULONG CompareFlags
  183. )
  184. /*++
  185. Routine Description:
  186. Compares 2 unicode strings; Case insensitive comparison.
  187. Uses flags to avoid UpCasing strings again.
  188. Arguments:
  189. SourceName - Supplies the Unicode string to be compared
  190. DestName - Supplies the compressed string to be compared
  191. CompareFlags - Supplies the flags to control comparison (see cmp.h)
  192. Return Value:
  193. 0 = SearchName == CompressedName (of Cell)
  194. < 0 = SearchName < CompressedName
  195. > 0 = SearchName > CompressedName
  196. --*/
  197. {
  198. WCHAR *s1, *s2;
  199. USHORT n1, n2;
  200. WCHAR c1, c2;
  201. LONG cDiff;
  202. s1 = SourceName->Buffer;
  203. s2 = DestName->Buffer;
  204. n1 = (USHORT )(SourceName->Length / sizeof(WCHAR));
  205. n2 = (USHORT )(DestName->Length / sizeof(WCHAR));
  206. while (n1 && n2) {
  207. c1 = *s1++;
  208. c2 = *s2++;
  209. //
  210. // there is a 2/3 chance of being the same case
  211. //
  212. if( c1 != c2 ){
  213. c1 = (CompareFlags&CMP_SOURCE_UP)?c1:CmUpcaseUnicodeChar(c1);
  214. c2 = (CompareFlags&CMP_DEST_UP)?c2:CmUpcaseUnicodeChar(c2);
  215. if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
  216. return( cDiff );
  217. }
  218. }
  219. n1--;
  220. n2--;
  221. }
  222. return( n1 - n2 );
  223. }
  224. LONG
  225. CmpCompareTwoCompressedNames(
  226. IN PWCHAR CompressedName1,
  227. IN ULONG NameLength1,
  228. IN PWCHAR CompressedName2,
  229. IN ULONG NameLength2
  230. )
  231. /*++
  232. Routine Description:
  233. Compares 2 compressed registry strings. Does a case-insensitive
  234. comparison.
  235. Arguments:
  236. CompressedName1 - Supplies the compressed string to be compared
  237. NameLength2 - Supplies the length of the compressed string
  238. CompressedName1 - Supplies the compressed string to be compared
  239. NameLength2 - Supplies the length of the compressed string
  240. Return Value:
  241. 0 = CompressedName1 == CompressedName2 (of Cell)
  242. < 0 = CompressedName1 < CompressedName2
  243. > 0 = CompressedName1 > CompressedName2
  244. --*/
  245. {
  246. UCHAR *s1;
  247. UCHAR *s2;
  248. USHORT n1, n2;
  249. WCHAR c1;
  250. WCHAR c2;
  251. LONG cDiff;
  252. s1 = (UCHAR *)CompressedName1;
  253. s2 = (UCHAR *)CompressedName2;
  254. n1 = (USHORT )(NameLength1);
  255. n2 = (USHORT )(NameLength2);
  256. while (n1 && n2) {
  257. c1 = (WCHAR)(*s1++);
  258. c2 = (WCHAR)(*s2++);
  259. //
  260. // there is a 2/3 chance they match without doing the upercase comparison.
  261. //
  262. if( c1 != c2 ) {
  263. c1 = CmUpcaseUnicodeChar(c1);
  264. c2 = CmUpcaseUnicodeChar(c2);
  265. if ((cDiff = ((LONG)c1 - (LONG)c2)) != 0) {
  266. return( cDiff );
  267. }
  268. }
  269. n1--;
  270. n2--;
  271. }
  272. return( n1 - n2 );
  273. }