Made direct calls to collation functions

This commit is contained in:
jpandre 2009-12-16 10:20:57 +00:00
parent 195945cdc0
commit 7bea2202d7
4 changed files with 53 additions and 97 deletions

View File

@ -29,9 +29,6 @@
#define NTFS_COLLATION_ERROR -2
extern BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr);
extern int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr,
const void *data1, const int data1_len,
const void *data2, const int data2_len);
extern COLLATE ntfs_get_collate_function(COLLATION_RULES);
#endif /* _NTFS_COLLATE_H */

View File

@ -63,6 +63,9 @@
#define MAX_PARENT_VCN 32
typedef int (*COLLATE)(ntfs_volume *vol, const void *data1, int len1,
const void *data2, int len2);
/**
* struct ntfs_index_context -
* @ni: inode containing the @entry described by this context
@ -116,7 +119,7 @@ typedef struct {
INDEX_ENTRY *entry;
void *data;
u16 data_len;
COLLATION_RULES cr;
COLLATE collate;
BOOL is_in_root;
INDEX_ROOT *ir;
ntfs_attr_search_ctx *actx;

View File

@ -23,32 +23,23 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "attrib.h"
#include "index.h"
#include "collate.h"
#include "debug.h"
#include "unistr.h"
#include "logging.h"
BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr)
{
/*
* FIXME: At the moment we only support COLLATION_BINARY,
* COLLATION_NTOFS_ULONG and COLLATION_FILE_NAME so we return false
* for everything else.
* JPA added COLLATION_NTOFS_SECURITY_HASH
*/
if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG
&& cr != COLLATION_FILE_NAME
&& cr != COLLATION_NTOFS_SECURITY_HASH
&& cr != COLLATION_NTOFS_ULONGS)
return FALSE;
return TRUE;
}
/**
* ntfs_collate_binary - Which of two binary objects should be listed first
* @vol: unused
@ -245,76 +236,36 @@ static int ntfs_collate_file_name(ntfs_volume *vol,
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,
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*/,
ntfs_collate_ntofs_security_hash,
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, or 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.
*
* Return NTFS_COLLATION_ERROR if error occurred.
*/
int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr,
const void *data1, const int data1_len,
const void *data2, const int data2_len)
{
int i;
ntfs_log_trace("Entering.\n");
if (!vol || !data1 || !data2 || data1_len < 0 || data2_len < 0) {
ntfs_log_error("Invalid arguments passed.\n");
return NTFS_COLLATION_ERROR;
}
/*
* FIXME: At the moment we only support COLLATION_BINARY,
* COLLATION_NTOFS_ULONG and COLLATION_FILE_NAME so we return error
* for everything else.
* JPA added COLLATION_NTOFS_SECURITY_HASH
* JPA added COLLATION_NTOFS_ULONGS
* Get a pointer to appropriate collation function.
*
* Returns NULL if the needed function is not implemented
*/
if (cr != COLLATION_BINARY && cr != COLLATION_NTOFS_ULONG
&& cr != COLLATION_FILE_NAME
&& cr != COLLATION_NTOFS_SECURITY_HASH
&& cr != COLLATION_NTOFS_ULONGS)
goto err;
i = le32_to_cpu(cr);
if (i < 0)
goto err;
if (i <= 0x02)
return ntfs_do_collate0x0[i](vol, data1, data1_len,
data2, data2_len);
if (i < 0x10)
goto err;
i -= 0x10;
if (i <= 3)
return ntfs_do_collate0x1[i](vol, data1, data1_len,
data2, data2_len);
err:
ntfs_log_debug("Unknown collation rule.\n");
return NTFS_COLLATION_ERROR;
COLLATE ntfs_get_collate_function(COLLATION_RULES cr)
{
COLLATE collate;
switch (cr) {
case COLLATION_BINARY :
collate = ntfs_collate_binary;
break;
case COLLATION_FILE_NAME :
collate = ntfs_collate_file_name;
break;
case COLLATION_NTOFS_SECURITY_HASH :
collate = ntfs_collate_ntofs_security_hash;
break;
case COLLATION_NTOFS_ULONG :
collate = ntfs_collate_ntofs_ulong;
break;
case COLLATION_NTOFS_ULONGS :
collate = ntfs_collate_ntofs_ulongs;
break;
default :
errno = EOPNOTSUPP;
collate = (COLLATE)NULL;
break;
}
return (collate);
}

View File

@ -38,9 +38,9 @@
#endif
#include "attrib.h"
#include "collate.h"
#include "debug.h"
#include "index.h"
#include "collate.h"
#include "mst.h"
#include "dir.h"
#include "logging.h"
@ -517,8 +517,13 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
* Not a perfect match, need to do full blown collation so we
* know which way in the B+tree we have to go.
*/
rc = ntfs_collate(icx->ni->vol, icx->cr, key, key_len, &ie->key,
le16_to_cpu(ie->key_length));
if (!icx->collate) {
ntfs_log_error("Collation function not defined\n");
errno = EOPNOTSUPP;
return STATUS_ERROR;
}
rc = icx->collate(icx->ni->vol, key, key_len,
&ie->key, le16_to_cpu(ie->key_length));
if (rc == NTFS_COLLATION_ERROR) {
ntfs_log_error("Collation error. Perhaps a filename "
"contains invalid characters?\n");
@ -697,12 +702,12 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
icx->vcn_size_bits = ni->vol->cluster_size_bits;
else
icx->vcn_size_bits = ni->vol->sector_size_bits;
icx->cr = ir->collation_rule;
if (!ntfs_is_collation_rule_supported(icx->cr)) {
/* get the appropriate collation function */
icx->collate = ntfs_get_collate_function(ir->collation_rule);
if (!icx->collate) {
err = errno = EOPNOTSUPP;
ntfs_log_perror("Unknown collation rule 0x%x",
(unsigned)le32_to_cpu(icx->cr));
(unsigned)le32_to_cpu(ir->collation_rule));
goto err_out;
}