Changeset 9986 for trunk/src/NTDLL/rtlstr.c
- Timestamp:
- Apr 7, 2003, 8:40:53 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/NTDLL/rtlstr.c
r9684 r9986 30 30 #include "wine/unicode.h" 31 31 #include "wine/debug.h" 32 #include "winnt.h" 32 33 33 34 WINE_DEFAULT_DEBUG_CHANNEL(ntdll); … … 155 156 memcpy( target->Buffer, src, len ); 156 157 target->MaximumLength = len; 157 target->Length = len - 2;158 target->Length = len - sizeof(WCHAR); 158 159 return TRUE; 159 160 } … … 336 337 } 337 338 339 /************************************************************************** 340 * RtlEqualComputerName (NTDLL.@) 341 * 342 * Determine if two computer names are the same. 343 * 344 * PARAMS 345 * left [I] First computer name 346 * right [I] Second computer name 347 * 348 * RETURNS 349 * 0 if the names are equal, non-zero otherwise. 350 * 351 * NOTES 352 * The comparason is case insensitive. 353 */ 354 NTSTATUS WINAPI RtlEqualComputerName(const UNICODE_STRING *left, 355 const UNICODE_STRING *right) 356 { 357 NTSTATUS ret; 358 STRING upLeft, upRight; 359 360 if (!(ret = RtlUpcaseUnicodeStringToOemString( &upLeft, left, TRUE ))) 361 { 362 if (!(ret = RtlUpcaseUnicodeStringToOemString( &upRight, right, TRUE ))) 363 { 364 ret = RtlEqualString( &upLeft, &upRight, FALSE ); 365 RtlFreeOemString( &upRight ); 366 } 367 RtlFreeOemString( &upLeft ); 368 } 369 return ret; 370 } 371 372 /************************************************************************** 373 * RtlEqualDomainName (NTDLL.@) 374 * 375 * Determine if two domain names are the same. 376 * 377 * PARAMS 378 * left [I] First domain name 379 * right [I] Second domain name 380 * 381 * RETURNS 382 * 0 if the names are equal, non-zero otherwise. 383 * 384 * NOTES 385 * The comparason is case insensitive. 386 */ 387 NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING *left, 388 const UNICODE_STRING *right) 389 { 390 return RtlEqualComputerName(left, right); 391 } 392 338 393 339 394 /* … … 527 582 528 583 /************************************************************************** 584 * RtlUpperChar (NTDLL.@) 585 * 586 * Converts an Ascii character to uppercase. 587 * 588 * PARAMS 589 * ch [I] Character to convert 590 * 591 * RETURNS 592 * The uppercase character value. 593 * 594 * NOTES 595 * For the input characters from 'a' .. 'z' it returns 'A' .. 'Z'. 596 * All other input characters are returned unchanged. The locale and 597 * multibyte characters are not taken into account (as native DLL). 598 */ 599 CHAR WINAPI RtlUpperChar( CHAR ch ) 600 { 601 if (ch >= 'a' && ch <= 'z') { 602 return ch - 'a' + 'A'; 603 } else { 604 return ch; 605 } /* if */ 606 } 607 608 /************************************************************************** 529 609 * RtlUpperString (NTDLL.@) 610 * 611 * Converts an Ascii string to uppercase. 612 * 613 * PARAMS 614 * dst [O] Destination for converted string 615 * src [I] Source string to convert 616 * 617 * RETURNS 618 * Nothing. 619 * 620 * NOTES 621 * For the src characters from 'a' .. 'z' it assigns 'A' .. 'Z' to dst. 622 * All other src characters are copied unchanged to dst. The locale and 623 * multibyte characters are not taken into account (as native DLL). 624 * The number of character copied is the minimum of src->Length and 625 * the dst->MaximumLength. 530 626 */ 531 627 void WINAPI RtlUpperString( STRING *dst, const STRING *src ) … … 533 629 unsigned int i, len = min(src->Length, dst->MaximumLength); 534 630 535 for (i = 0; i < len; i++) dst->Buffer[i] = toupper(src->Buffer[i]);631 for (i = 0; i < len; i++) dst->Buffer[i] = RtlUpperChar(src->Buffer[i]); 536 632 dst->Length = len; 537 633 } 538 634 635 636 /************************************************************************** 637 * RtlUpcaseUnicodeChar (NTDLL.@) 638 * 639 * Converts an Unicode character to uppercase. 640 * 641 * PARAMS 642 * wch [I] Character to convert 643 * 644 * RETURNS 645 * The uppercase character value. 646 */ 647 WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch ) 648 { 649 return toupperW(wch); 650 } 651 652 /************************************************************************** 653 * RtlDowncaseUnicodeChar (NTDLL.@) 654 * 655 * Converts an Unicode character to lowercase. 656 * 657 * PARAMS 658 * wch [I] Character to convert 659 * 660 * RETURNS 661 * The lowercase character value. 662 */ 663 WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR wch) 664 { 665 return tolowerW(wch); 666 } 539 667 540 668 /************************************************************************** … … 564 692 } 565 693 694 695 /************************************************************************** 696 * RtlDowncaseUnicodeString (NTDLL.@) 697 * 698 * Converts an Unicode string to lowercase. 699 * 700 * PARAMS 701 * dest [O] Destination for converted string 702 * src [I] Source string to convert 703 * doalloc [I] TRUE=Allocate a buffer for dest if it doesn't have one 704 * 705 * RETURNS 706 * Success: STATUS_SUCCESS. dest contains the converted string. 707 * Failure: STATUS_NO_MEMORY, if doalloc is TRUE and memory allocation fails, or 708 * STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and dest is too small. 709 * 710 * NOTES 711 * dest is never NUL terminated because it may be equal to src, and src 712 * might not be NUL terminated. dest->Length is only set upon success. 713 */ 714 NTSTATUS WINAPI RtlDowncaseUnicodeString( 715 UNICODE_STRING *dest, 716 const UNICODE_STRING *src, 717 BOOLEAN doalloc) 718 { 719 DWORD i; 720 DWORD len = src->Length; 721 722 if (doalloc) { 723 dest->MaximumLength = len; 724 if (!(dest->Buffer = RtlAllocateHeap( GetProcessHeap(), 0, len ))) { 725 return STATUS_NO_MEMORY; 726 } /* if */ 727 } else if (len > dest->MaximumLength) { 728 return STATUS_BUFFER_OVERFLOW; 729 } /* if */ 730 731 for (i = 0; i < len/sizeof(WCHAR); i++) { 732 dest->Buffer[i] = tolowerW(src->Buffer[i]); 733 } /* for */ 734 dest->Length = len; 735 return STATUS_SUCCESS; 736 } 566 737 567 738 /************************************************************************** … … 788 959 { 789 960 unsigned int len = src->Length + dst->Length; 961 if (src->Length == 0) return STATUS_SUCCESS; 790 962 if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL; 791 963 memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src->Buffer, src->Length ); … … 848 1020 849 1021 /************************************************************************** 850 * RtlUnicodeStringToInteger (NTDLL.@) 851 * 852 * Convert a text buffer into its integer form 1022 * RtlCharToInteger (NTDLL.@) 1023 * 1024 * Converts a character string into its integer equivalent. 1025 * 1026 * RETURNS 1027 * Success: STATUS_SUCCESS. value contains the converted number 1028 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16. 1029 * STATUS_ACCESS_VIOLATION, if value is NULL. 1030 * 1031 * NOTES 1032 * For base 0 it uses 10 as base and the string should be in the format 1033 * "{whitespace} [+|-] [0[x|o|b]] {digits}". 1034 * For other bases the string should be in the format 1035 * "{whitespace} [+|-] {digits}". 1036 * No check is made for value overflow, only the lower 32 bits are assigned. 1037 * If str is NULL it crashes, as the native function does. 1038 * 1039 * DIFFERENCES 1040 * This function does not read garbage behind '\0' as the native version does. 1041 */ 1042 NTSTATUS WINAPI RtlCharToInteger( 1043 PCSZ str, /* [I] '\0' terminated single-byte string containing a number */ 1044 ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */ 1045 ULONG *value) /* [O] Destination for the converted value */ 1046 { 1047 CHAR chCurrent; 1048 int digit; 1049 ULONG RunningTotal = 0; 1050 char bMinus = 0; 1051 1052 while (*str != '\0' && *str <= ' ') { 1053 str++; 1054 } /* while */ 1055 1056 if (*str == '+') { 1057 str++; 1058 } else if (*str == '-') { 1059 bMinus = 1; 1060 str++; 1061 } /* if */ 1062 1063 if (base == 0) { 1064 base = 10; 1065 if (str[0] == '0') { 1066 if (str[1] == 'b') { 1067 str += 2; 1068 base = 2; 1069 } else if (str[1] == 'o') { 1070 str += 2; 1071 base = 8; 1072 } else if (str[1] == 'x') { 1073 str += 2; 1074 base = 16; 1075 } /* if */ 1076 } /* if */ 1077 } else if (base != 2 && base != 8 && base != 10 && base != 16) { 1078 return STATUS_INVALID_PARAMETER; 1079 } /* if */ 1080 1081 if (value == NULL) { 1082 return STATUS_ACCESS_VIOLATION; 1083 } /* if */ 1084 1085 while (*str != '\0') { 1086 chCurrent = *str; 1087 if (chCurrent >= '0' && chCurrent <= '9') { 1088 digit = chCurrent - '0'; 1089 } else if (chCurrent >= 'A' && chCurrent <= 'Z') { 1090 digit = chCurrent - 'A' + 10; 1091 } else if (chCurrent >= 'a' && chCurrent <= 'z') { 1092 digit = chCurrent - 'a' + 10; 1093 } else { 1094 digit = -1; 1095 } /* if */ 1096 if (digit < 0 || digit >= base) { 1097 *value = bMinus ? -RunningTotal : RunningTotal; 1098 return STATUS_SUCCESS; 1099 } /* if */ 1100 1101 RunningTotal = RunningTotal * base + digit; 1102 str++; 1103 } /* while */ 1104 1105 *value = bMinus ? -RunningTotal : RunningTotal; 1106 return STATUS_SUCCESS; 1107 } 1108 1109 /************************************************************************** 1110 * RtlIntegerToChar (NTDLL.@) 1111 * 1112 * Converts an unsigned integer to a character string. 1113 * 1114 * RETURNS 1115 * Success: STATUS_SUCCESS. str contains the converted number 1116 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16. 1117 * STATUS_BUFFER_OVERFLOW, if str would be larger than length. 1118 * STATUS_ACCESS_VIOLATION, if str is NULL. 1119 * 1120 * NOTES 1121 * Instead of base 0 it uses 10 as base. 1122 * Writes at most length characters to the string str. 1123 * Str is '\0' terminated when length allowes it. 1124 * When str fits exactly in length characters the '\0' is ommitted. 1125 */ 1126 NTSTATUS WINAPI RtlIntegerToChar( 1127 ULONG value, /* [I] Value to be converted */ 1128 ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */ 1129 ULONG length, /* [I] Length of the str buffer in bytes */ 1130 PCHAR str) /* [O] Destination for the converted value */ 1131 { 1132 CHAR buffer[33]; 1133 PCHAR pos; 1134 CHAR digit; 1135 ULONG len; 1136 1137 if (base == 0) { 1138 base = 10; 1139 } else if (base != 2 && base != 8 && base != 10 && base != 16) { 1140 return STATUS_INVALID_PARAMETER; 1141 } /* if */ 1142 1143 pos = &buffer[32]; 1144 *pos = '\0'; 1145 1146 do { 1147 pos--; 1148 digit = value % base; 1149 value = value / base; 1150 if (digit < 10) { 1151 *pos = '0' + digit; 1152 } else { 1153 *pos = 'A' + digit - 10; 1154 } /* if */ 1155 } while (value != 0L); 1156 1157 len = &buffer[32] - pos; 1158 if (len > length) { 1159 return STATUS_BUFFER_OVERFLOW; 1160 } else if (str == NULL) { 1161 return STATUS_ACCESS_VIOLATION; 1162 } else if (len == length) { 1163 memcpy(str, pos, len); 1164 } else { 1165 memcpy(str, pos, len + 1); 1166 } /* if */ 1167 return STATUS_SUCCESS; 1168 } 1169 1170 /************************************************************************** 1171 * RtlUnicodeStringToInteger (NTDLL.@) 1172 * 1173 * Converts an unicode string into its integer equivalent. 1174 * 1175 * RETURNS 1176 * Success: STATUS_SUCCESS. value contains the converted number 1177 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16. 1178 * STATUS_ACCESS_VIOLATION, if value is NULL. 1179 * 1180 * NOTES 1181 * For base 0 it uses 10 as base and the string should be in the format 1182 * "{whitespace} [+|-] [0[x|o|b]] {digits}". 1183 * For other bases the string should be in the format 1184 * "{whitespace} [+|-] {digits}". 1185 * No check is made for value overflow, only the lower 32 bits are assigned. 1186 * If str is NULL it crashes, as the native function does. 1187 * 1188 * DIFFERENCES 1189 * This function does not read garbage on string length 0 as the native 1190 * version does. 853 1191 */ 854 1192 NTSTATUS WINAPI RtlUnicodeStringToInteger( 855 const UNICODE_STRING *str, 856 int base, 857 int * pdest) 858 { 859 LPWSTR lpwstr = str->Buffer; 860 WCHAR wchCurrent = 0; 861 int CharsParsed = 0; 862 int RunningTotal = 0; 863 char bMinus = 0; 864 865 /* no checking done on UNICODE_STRING and int* in native DLL either */ 866 TRACE("(%p, %d, %p)", str, base, pdest); 867 868 switch (base) 869 { 870 case 0: 871 base = 10; 872 break; 873 case 2: 874 case 8: 875 case 10: 876 case 16: 877 break; 878 default: 879 return STATUS_INVALID_PARAMETER; 880 } 881 882 if ((str->Length) >= 4 && (base == 10) && (*lpwstr == '0') && (*(lpwstr+1) == 'x')) 883 { 884 lpwstr+=2; 1193 const UNICODE_STRING *str, /* [I] Unicode string to be converted */ 1194 ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */ 1195 ULONG *value) /* [O] Destination for the converted value */ 1196 { 1197 LPWSTR lpwstr = str->Buffer; 1198 USHORT CharsRemaining = str->Length / sizeof(WCHAR); 1199 WCHAR wchCurrent; 1200 int digit; 1201 ULONG RunningTotal = 0; 1202 char bMinus = 0; 1203 1204 while (CharsRemaining >= 1 && *lpwstr <= ' ') { 1205 lpwstr++; 1206 CharsRemaining--; 1207 } /* while */ 1208 1209 if (CharsRemaining >= 1) { 1210 if (*lpwstr == '+') { 1211 lpwstr++; 1212 CharsRemaining--; 1213 } else if (*lpwstr == '-') { 1214 bMinus = 1; 1215 lpwstr++; 1216 CharsRemaining--; 1217 } /* if */ 1218 } /* if */ 1219 1220 if (base == 0) { 1221 base = 10; 1222 if (CharsRemaining >= 2 && lpwstr[0] == '0') { 1223 if (lpwstr[1] == 'b') { 1224 lpwstr += 2; 1225 CharsRemaining -= 2; 1226 base = 2; 1227 } else if (lpwstr[1] == 'o') { 1228 lpwstr += 2; 1229 CharsRemaining -= 2; 1230 base = 8; 1231 } else if (lpwstr[1] == 'x') { 1232 lpwstr += 2; 1233 CharsRemaining -= 2; 885 1234 base = 16; 886 } 887 888 *pdest = 0; 889 for (; (CharsParsed*sizeof(WCHAR) < str->Length) && (*lpwstr <= ' '); lpwstr++) 890 CharsParsed++; 891 892 if (*lpwstr == '+') 893 lpwstr++; 894 else if (*lpwstr == '-') 895 { 896 bMinus = 1; 897 lpwstr++; 898 } 899 900 for (; (CharsParsed*sizeof(WCHAR) < str->Length) && (*lpwstr != '\0'); lpwstr++) 901 { 902 CharsParsed++; 903 wchCurrent = *lpwstr; 904 if (wchCurrent >= 'A') 905 wchCurrent = '0' + 10 + wchCurrent - 'A'; 906 if ((wchCurrent - '0') >= base || wchCurrent < '0') 907 { 908 *pdest = bMinus ? -RunningTotal: RunningTotal; 909 return STATUS_SUCCESS; 910 } 911 /* 912 * increase significance of previous digits each time 913 * we find another valid one and add on this valid one 914 */ 915 RunningTotal = wchCurrent - '0' + RunningTotal * base; 916 } 917 918 *pdest = bMinus ? -RunningTotal : RunningTotal; 919 return STATUS_SUCCESS; 920 } 1235 } /* if */ 1236 } /* if */ 1237 } else if (base != 2 && base != 8 && base != 10 && base != 16) { 1238 return STATUS_INVALID_PARAMETER; 1239 } /* if */ 1240 1241 if (value == NULL) { 1242 return STATUS_ACCESS_VIOLATION; 1243 } /* if */ 1244 1245 while (CharsRemaining >= 1) { 1246 wchCurrent = *lpwstr; 1247 if (wchCurrent >= '0' && wchCurrent <= '9') { 1248 digit = wchCurrent - '0'; 1249 } else if (wchCurrent >= 'A' && wchCurrent <= 'Z') { 1250 digit = wchCurrent - 'A' + 10; 1251 } else if (wchCurrent >= 'a' && wchCurrent <= 'z') { 1252 digit = wchCurrent - 'a' + 10; 1253 } else { 1254 digit = -1; 1255 } /* if */ 1256 if (digit < 0 || digit >= base) { 1257 *value = bMinus ? -RunningTotal : RunningTotal; 1258 return STATUS_SUCCESS; 1259 } /* if */ 1260 1261 RunningTotal = RunningTotal * base + digit; 1262 lpwstr++; 1263 CharsRemaining--; 1264 } /* while */ 1265 1266 *value = bMinus ? -RunningTotal : RunningTotal; 1267 return STATUS_SUCCESS; 1268 } 1269 1270 /************************************************************************** 1271 * RtlIntegerToUnicodeString (NTDLL.@) 1272 * 1273 * Converts an unsigned integer to a '\0' terminated unicode string. 1274 * 1275 * RETURNS 1276 * Success: STATUS_SUCCESS. str contains the converted number 1277 * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16. 1278 * STATUS_BUFFER_OVERFLOW, if str is too small to hold the string 1279 * (with the '\0' termination). In this case str->Length 1280 * is set to the length, the string would have (which can 1281 * be larger than the MaximumLength). 1282 * 1283 * NOTES 1284 * Instead of base 0 it uses 10 as base. 1285 * If str is NULL it crashes, as the native function does. 1286 * 1287 * DIFFERENCES 1288 * Do not return STATUS_BUFFER_OVERFLOW when the string is long enough. 1289 * The native function does this when the string would be longer than 16 1290 * characters even when the string parameter is long enough. 1291 */ 1292 NTSTATUS WINAPI RtlIntegerToUnicodeString( 1293 ULONG value, /* [I] Value to be converted */ 1294 ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */ 1295 UNICODE_STRING *str) /* [O] Destination for the converted value */ 1296 { 1297 WCHAR buffer[33]; 1298 PWCHAR pos; 1299 WCHAR digit; 1300 1301 if (base == 0) { 1302 base = 10; 1303 } else if (base != 2 && base != 8 && base != 10 && base != 16) { 1304 return STATUS_INVALID_PARAMETER; 1305 } /* if */ 1306 1307 pos = &buffer[32]; 1308 *pos = '\0'; 1309 1310 do { 1311 pos--; 1312 digit = value % base; 1313 value = value / base; 1314 if (digit < 10) { 1315 *pos = '0' + digit; 1316 } else { 1317 *pos = 'A' + digit - 10; 1318 } /* if */ 1319 } while (value != 0L); 1320 1321 str->Length = (&buffer[32] - pos) * sizeof(WCHAR); 1322 if (str->Length >= str->MaximumLength) { 1323 return STATUS_BUFFER_OVERFLOW; 1324 } else { 1325 memcpy(str->Buffer, pos, str->Length + sizeof(WCHAR)); 1326 } /* if */ 1327 return STATUS_SUCCESS; 1328 }
Note:
See TracChangeset
for help on using the changeset viewer.