^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * collate.c - NTFS kernel collation handling. Part of the Linux-NTFS project.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2004 Anton Altaparmakov
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "collate.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "ntfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) static int ntfs_collate_binary(ntfs_volume *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) const void *data1, const int data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) const void *data2, const int data2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) rc = memcmp(data1, data2, min(data1_len, data2_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (!rc && (data1_len != data2_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) if (data1_len < data2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) ntfs_debug("Done, returning %i", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static int ntfs_collate_ntofs_ulong(ntfs_volume *vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const void *data1, const int data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) const void *data2, const int data2_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u32 d1, d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) // FIXME: We don't really want to bug here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) BUG_ON(data1_len != data2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) BUG_ON(data1_len != 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) d1 = le32_to_cpup(data1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) d2 = le32_to_cpup(data2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (d1 < d2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) rc = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (d1 == d2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) ntfs_debug("Done, returning %i", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) typedef int (*ntfs_collate_func_t)(ntfs_volume *, const void *, const int,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) const void *, const int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static ntfs_collate_func_t ntfs_do_collate0x0[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ntfs_collate_binary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) NULL/*ntfs_collate_file_name*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) NULL/*ntfs_collate_unicode_string*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static ntfs_collate_func_t ntfs_do_collate0x1[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ntfs_collate_ntofs_ulong,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) NULL/*ntfs_collate_ntofs_sid*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) NULL/*ntfs_collate_ntofs_security_hash*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) NULL/*ntfs_collate_ntofs_ulongs*/,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * ntfs_collate - collate two data items using a specified collation rule
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * @vol: ntfs volume to which the data items belong
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * @cr: collation rule to use when comparing the items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * @data1: first data item to collate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @data1_len: length in bytes of @data1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @data2: second data item to collate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * @data2_len: length in bytes of @data2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * Collate the two data items @data1 and @data2 using the collation rule @cr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * and return -1, 0, ir 1 if @data1 is found, respectively, to collate before,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * to match, or to collate after @data2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * For speed we use the collation rule @cr as an index into two tables of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * function pointers to call the appropriate collation function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int ntfs_collate(ntfs_volume *vol, COLLATION_RULE cr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) const void *data1, const int data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) const void *data2, const int data2_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) ntfs_debug("Entering.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * FIXME: At the moment we only support COLLATION_BINARY and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * COLLATION_NTOFS_ULONG, so we BUG() for everything else for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) BUG_ON(cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) i = le32_to_cpu(cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) BUG_ON(i < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (i <= 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) return ntfs_do_collate0x0[i](vol, data1, data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) data2, data2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) BUG_ON(i < 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) i -= 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (likely(i <= 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return ntfs_do_collate0x1[i](vol, data1, data1_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) data2, data2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }