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