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