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.

334 lines
7.8 KiB

  1. /*++
  2. Copyright (c) 1989-91 Microsoft Corporation
  3. Module Name:
  4. namecmp.c
  5. Abstract:
  6. Net name comparison functions:
  7. NetpwNameCompare
  8. CompareOemNames
  9. Author:
  10. Richard L Firth (rfirth) 06-Jan-1992
  11. Revision History:
  12. --*/
  13. #include "nticanon.h"
  14. //
  15. // prototypes
  16. //
  17. LONG
  18. CompareOemNames(
  19. IN LPWSTR Name1,
  20. IN LPWSTR Name2,
  21. IN BOOL CaseInsensitive
  22. );
  23. //
  24. // data
  25. //
  26. static TCHAR szShareTrailChars[] = TEXT(". ");
  27. //
  28. // routines
  29. //
  30. LONG
  31. NetpwNameCompare(
  32. IN LPTSTR Name1,
  33. IN LPTSTR Name2,
  34. IN DWORD NameType,
  35. IN DWORD Flags
  36. )
  37. /*++
  38. Routine Description:
  39. Compares two LANMAN object names to see if they are the same. If the
  40. supplied names are not canonicalized this function will do the
  41. canonicalization of the names.
  42. This function does not do name validation. It assumes that the two names
  43. have been validated separately.
  44. This function relies on the fact that the only difference between a
  45. canonicalized object name and an uncanonicalized object name is the case.
  46. (say what?...)
  47. Arguments:
  48. Name1 - The first name to compare.
  49. Name2 - The second name to compare.
  50. NameType - The type of the LANMAN object names. Valid values are
  51. specified by NAMETYPE_* manifests in ICANON.H.
  52. Flags - Flags to determine operation. Currently defined values are:
  53. Xrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrc
  54. where:
  55. X = LM 2.x Compatibility
  56. r = Reserved. MBZ.
  57. c = should be set if both of the names have already been
  58. canonicalized (using NetpwNameCanonicalize).
  59. Return Value:
  60. 0 if the two names match.
  61. Non-zero if they don't match, or if an invalid parameter is
  62. specified.
  63. --*/
  64. {
  65. LONG RetVal;
  66. NET_API_STATUS rc;
  67. TCHAR tName1[PATHLEN+1];
  68. TCHAR tName2[PATHLEN+1];
  69. #ifdef CANONDBG
  70. DbgPrint("NetpwNameCompare\n");
  71. #endif
  72. //
  73. // Parameter validation
  74. //
  75. if (Flags & INNC_FLAGS_RESERVED) {
  76. return ERROR_INVALID_PARAMETER;
  77. }
  78. //
  79. // Determine which of the canonicalization functions to use. We
  80. // use stricmp() if the names are not canonicalized and are not
  81. // case sensitive and strcmp() if the names are canonicalized or
  82. // if they are case sensitive.
  83. //
  84. switch (NameType) {
  85. //
  86. // Case insensitive name types
  87. //
  88. case NAMETYPE_USER:
  89. case NAMETYPE_GROUP:
  90. case NAMETYPE_COMPUTER:
  91. case NAMETYPE_EVENT:
  92. case NAMETYPE_DOMAIN:
  93. case NAMETYPE_SERVICE:
  94. case NAMETYPE_NET:
  95. case NAMETYPE_WORKGROUP:
  96. //
  97. // Use the case sensitive version if the names have been
  98. // canonicalized.
  99. //
  100. if (!(Flags & INNC_FLAGS_NAMES_CANONICALIZED)) {
  101. rc = NetpwNameCanonicalize(Name1,
  102. tName1,
  103. sizeof(tName1),
  104. NameType,
  105. Flags & LM2X_COMPATIBLE
  106. );
  107. if (rc != NERR_Success) {
  108. return rc;
  109. }
  110. rc = NetpwNameCanonicalize(Name2,
  111. tName2,
  112. sizeof(tName2),
  113. NameType,
  114. Flags & LM2X_COMPATIBLE
  115. );
  116. if (rc != NERR_Success) {
  117. return rc;
  118. }
  119. } else {
  120. LONG Name1Length, Name2Length;
  121. Name1Length = STRLEN(Name1);
  122. Name2Length = STRLEN(Name2);
  123. if ((Name1Length > PATHLEN) ||
  124. (Name2Length > PATHLEN)) {
  125. return ERROR_INVALID_PARAMETER;
  126. } else {
  127. STRCPY(tName1, Name1);
  128. STRCPY(tName2, Name2);
  129. }
  130. }
  131. if (Flags & (LM2X_COMPATIBLE)) {
  132. if (NameType == NAMETYPE_COMPUTER
  133. || NameType == NAMETYPE_DOMAIN
  134. || NameType == NAMETYPE_WORKGROUP) {
  135. return CompareOemNames(tName1, tName2, FALSE);
  136. } else {
  137. return STRCMP(tName1, tName2);
  138. }
  139. } else {
  140. if (NameType == NAMETYPE_COMPUTER
  141. || NameType == NAMETYPE_DOMAIN
  142. || NameType == NAMETYPE_WORKGROUP) {
  143. return CompareOemNames(tName1, tName2, TRUE);
  144. } else {
  145. return STRICMP(tName1, tName2);
  146. }
  147. }
  148. //
  149. // Case sensitive name types
  150. //
  151. case NAMETYPE_PASSWORD:
  152. case NAMETYPE_SHAREPASSWORD:
  153. case NAMETYPE_MESSAGE:
  154. case NAMETYPE_MESSAGEDEST:
  155. return STRCMP(Name1, Name2);
  156. //
  157. // Special handling for sharenames, since we mustn't consider
  158. // trailing dots and spaces in the comparison if the names haven't
  159. // been canonicalized.
  160. //
  161. case NAMETYPE_SHARE:
  162. if (Flags & INNC_FLAGS_NAMES_CANONICALIZED) {
  163. if (Flags & LM2X_COMPATIBLE) {
  164. return STRCMP(Name1, Name2);
  165. } else {
  166. return STRICMP(Name1, Name2);
  167. }
  168. } else {
  169. register DWORD RealLen1, RealLen2;
  170. RealLen1 = (DWORD)(strtail(Name1, szShareTrailChars) - Name1);
  171. RealLen2 = (DWORD)(strtail(Name2, szShareTrailChars) - Name2);
  172. //
  173. // If the lengths of the significant portions match, compare
  174. // these portions. Otherwise, return non-zero based on this
  175. // length.
  176. //
  177. if (RealLen1 == RealLen2) {
  178. return STRNICMP(Name1, Name2, RealLen1);
  179. } else {
  180. return RealLen1 > RealLen2 ? 1 : -1;
  181. }
  182. }
  183. default:
  184. //
  185. // The caller specified an invalid name type
  186. //
  187. return ERROR_INVALID_PARAMETER;
  188. }
  189. }
  190. LONG
  191. CompareOemNames(
  192. IN LPWSTR Name1,
  193. IN LPWSTR Name2,
  194. IN BOOL CaseInsensitive
  195. )
  196. /*++
  197. Routine Description:
  198. Converts 2 UNICODE name strings to corresponding OEM character set strings
  199. and then compares them
  200. Arguments:
  201. Name1 -
  202. Name2 -
  203. CaseInsensitive - TRUE if compare without case
  204. Return Value:
  205. LONG
  206. <0 Name1 less than Name2
  207. 0 Names match
  208. >0 Name1 greater than Name2
  209. --*/
  210. {
  211. CHAR oemName1[PATHLEN + 1];
  212. ULONG oemByteLength1;
  213. ULONG name1Length;
  214. CHAR oemName2[PATHLEN + 1];
  215. ULONG oemByteLength2;
  216. ULONG name2Length;
  217. NTSTATUS ntStatus;
  218. name1Length = wcslen(Name1);
  219. name2Length = wcslen(Name2);
  220. //
  221. // only prepared to consider names within our upper length limit
  222. //
  223. if (name1Length >= sizeof(oemName1) || name2Length >= sizeof(oemName2)) {
  224. return -1;
  225. }
  226. //
  227. // convert UNICODE names to OEM
  228. //
  229. ntStatus = RtlUpcaseUnicodeToOemN(oemName1,
  230. sizeof(oemName1) - 1,
  231. &oemByteLength1,
  232. Name1,
  233. name1Length * sizeof(*Name1)
  234. );
  235. if (!NT_SUCCESS(ntStatus)) {
  236. return -1;
  237. } else {
  238. oemName1[oemByteLength1] = 0;
  239. }
  240. ntStatus = RtlUpcaseUnicodeToOemN(oemName2,
  241. sizeof(oemName2) - 1,
  242. &oemByteLength2,
  243. Name2,
  244. name2Length * sizeof(*Name2)
  245. );
  246. if (!NT_SUCCESS(ntStatus)) {
  247. return -1;
  248. } else {
  249. oemName2[oemByteLength2] = 0;
  250. }
  251. if (CaseInsensitive) {
  252. return _stricmp(oemName1, oemName2);
  253. }
  254. else {
  255. return strcmp(oemName1, oemName2);
  256. }
  257. }
  258.