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 #define NTFS_COLLATION_ERROR -2
extern BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr); extern COLLATE ntfs_get_collate_function(COLLATION_RULES);
extern int ntfs_collate(ntfs_volume *vol, COLLATION_RULES cr,
const void *data1, const int data1_len,
const void *data2, const int data2_len);
#endif /* _NTFS_COLLATE_H */ #endif /* _NTFS_COLLATE_H */

View File

@ -63,6 +63,9 @@
#define MAX_PARENT_VCN 32 #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 - * struct ntfs_index_context -
* @ni: inode containing the @entry described by this context * @ni: inode containing the @entry described by this context
@ -116,7 +119,7 @@ typedef struct {
INDEX_ENTRY *entry; INDEX_ENTRY *entry;
void *data; void *data;
u16 data_len; u16 data_len;
COLLATION_RULES cr; COLLATE collate;
BOOL is_in_root; BOOL is_in_root;
INDEX_ROOT *ir; INDEX_ROOT *ir;
ntfs_attr_search_ctx *actx; ntfs_attr_search_ctx *actx;

View File

@ -23,32 +23,23 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H #ifdef HAVE_STRING_H
#include <string.h> #include <string.h>
#endif #endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "attrib.h"
#include "index.h"
#include "collate.h" #include "collate.h"
#include "debug.h" #include "debug.h"
#include "unistr.h" #include "unistr.h"
#include "logging.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 * ntfs_collate_binary - Which of two binary objects should be listed first
* @vol: unused * @vol: unused
@ -245,76 +236,36 @@ static int ntfs_collate_file_name(ntfs_volume *vol,
return rc; return rc;
} }
typedef int (*ntfs_collate_func_t)(ntfs_volume *, const void *, const int, /*
const void *, const int); * Get a pointer to appropriate collation function.
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 * Returns NULL if the needed function is not implemented
* 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"); COLLATE ntfs_get_collate_function(COLLATION_RULES cr)
if (!vol || !data1 || !data2 || data1_len < 0 || data2_len < 0) { {
ntfs_log_error("Invalid arguments passed.\n"); COLLATE collate;
return NTFS_COLLATION_ERROR;
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);
* 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
*/
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;
} }

View File

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