ReactOS  0.4.14-dev-599-g2d4d3f5
rfsd.c File Reference
#include "rfsd.h"
Include dependency graph for rfsd.c:

Go to the source code of this file.

Macros

#define MAGIC_KEY_LENGTH   9
 

Functions

PRFSD_SUPER_BLOCK RfsdLoadSuper (IN PRFSD_VCB Vcb, IN BOOLEAN bVerify)
 
BOOLEAN RfsdLoadInode (IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pKey, IN OUT PRFSD_INODE Inode)
 
BOOLEAN RfsdLoadBlock (IN PRFSD_VCB Vcb, IN ULONG dwBlk, IN OUT PVOID Buffer)
 
NTSTATUS RfsdBuildBDL2 (IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pKey, IN PRFSD_INODE pInode, OUT PULONG out_Count, OUT PRFSD_BDL *out_ppBdl)
 
BOOLEAN SuperblockContainsMagicKey (PRFSD_SUPER_BLOCK sb)
 
RFSD_KEY_VERSION DetermineOnDiskKeyFormat (const PRFSD_KEY_ON_DISK key)
 
__u32 ConvertKeyTypeUniqueness (__u32 k_uniqueness)
 
void FillInMemoryKey (IN PRFSD_KEY_ON_DISK pKeyOnDisk, IN RFSD_KEY_VERSION KeyVersion, IN OUT PRFSD_KEY_IN_MEMORY pKeyInMemory)
 
RFSD_KEY_COMPARISON CompareShortKeys (IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
 
RFSD_KEY_COMPARISON CompareKeysWithoutOffset (IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
 
RFSD_KEY_COMPARISON CompareKeys (IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
 
NTSTATUS NavigateToLeafNode (IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber)
 
NTSTATUS RfsdParseFilesystemTree (IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, IN RFSD_CALLBACK(fpDirectoryCallback), IN PVOID pContext)
 
NTSTATUS _NavigateToLeafNode (IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber, IN BOOLEAN ReturnOnFirstMatch, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY), RFSD_CALLBACK(fpDirectoryCallback), IN PVOID pContext)
 

Variables

PRFSD_GLOBAL RfsdGlobal
 

Macro Definition Documentation

◆ MAGIC_KEY_LENGTH

#define MAGIC_KEY_LENGTH   9

Function Documentation

◆ _NavigateToLeafNode()

NTSTATUS _NavigateToLeafNode ( IN PRFSD_VCB  Vcb,
IN PRFSD_KEY_IN_MEMORY  Key,
IN ULONG  StartingBlockNumber,
OUT PULONG  out_NextBlockNumber,
IN BOOLEAN  ReturnOnFirstMatch,
IN RFSD_KEY_COMPARISON(*)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY fpComparisonFunction,
RFSD_CALLBACK(fpDirectoryCallback)  ,
IN PVOID  pContext 
)

Returns the block number of the leaf node that should contain key (if that key exists at all within the disk tree).

STATUS_INVALID_HANDLE if a block or block header could not be read STATUS_INSUFFICIENT_RESOURCES if processing was terminated due to a failure of memory allocation STATUS_SUCCESS on success NOTE: the return value can also be anything defined by the invoked callback

Definition at line 2934 of file rfsd.c.

2946 {
2948  ULONG leafNodeBlockNumber; // The result to be calculated
2949  PRFSD_DISK_NODE_REF pTargetDiskNodeReference = NULL; //
2950 
2951  // Read in this disk node's data
2952  PUCHAR pBlockBuffer = RfsdAllocateAndLoadBlock(Vcb, StartingBlockNumber);
2953 
2954  // Read the block header
2955  PRFSD_BLOCK_HEAD pBlockHeader = (PRFSD_BLOCK_HEAD) pBlockBuffer;
2956 
2957  PAGED_CODE();
2958 
2959  // Sanity check that we could read the block and the header is there
2960  if (!pBlockBuffer) { return STATUS_INVALID_HANDLE; }
2961 
2962  // If this block is a leaf, just return it (or invoke the given callback on the leaf block)
2963  if (pBlockHeader->blk_level == RFSD_LEAF_BLOCK_LEVEL)
2964  {
2966 
2967  ExFreePool(pBlockBuffer);
2968 
2969  *out_NextBlockNumber = StartingBlockNumber;
2970 
2971  // If a callback should be invoked on finding a matching leaf node, do so...
2972  if (fpDirectoryCallback) return (*fpDirectoryCallback)(StartingBlockNumber, pContext);
2973  else return STATUS_SUCCESS;
2974  }
2975 
2976  // Otherwise, find the next node down in the tree, by obtaining pTargetDiskNodeReference
2977  {
2978  ULONG idxRightKey = 0;
2979  PRFSD_KEY_ON_DISK pLeftKeyOnDisk = NULL;
2980  PRFSD_KEY_ON_DISK pRightKeyOnDisk = NULL;
2981 
2982  RFSD_KEY_IN_MEMORY LeftKeyInMemory, RightKeyInMemory;
2983  RFSD_KEY_COMPARISON leftComparison, rightComparison;
2984 
2985  RightKeyInMemory.k_dir_id = 0; // (Dummy statement to prevent needless warning aboujt using RightKeyInMemory before being initialized)
2986 
2987  // Search (within the increasing list of target Keys), for the target key that Key is <= to.
2988  for (idxRightKey = 0; idxRightKey <= pBlockHeader->blk_nr_item; idxRightKey++)
2989  {
2990  // Advance the left key to become what was the right key, and the right key to become the next key
2991  pLeftKeyOnDisk = pRightKeyOnDisk;
2992  pRightKeyOnDisk = (idxRightKey == pBlockHeader->blk_nr_item) ?
2994  (PRFSD_KEY_ON_DISK) (pBlockBuffer + sizeof(RFSD_BLOCK_HEAD) + (idxRightKey * sizeof(RFSD_KEY_ON_DISK)));
2995 
2996  LeftKeyInMemory = RightKeyInMemory;
2997  if (pRightKeyOnDisk)
2998  FillInMemoryKey(pRightKeyOnDisk, RFSD_KEY_VERSION_UNKNOWN, &(RightKeyInMemory));
2999 
3000 
3001  // Find if the target key falls in the range in between the left and right keys...
3002  {
3003  // We must be smaller than the right key (if it exists). However, we will allow the key to match if short key comparisons are in use.
3004  rightComparison = pRightKeyOnDisk ? ((*fpComparisonFunction)(Key, &RightKeyInMemory)) : RFSD_KEY_SMALLER;
3005  if (fpComparisonFunction == &CompareShortKeys)
3006  { if (rightComparison == RFSD_KEY_LARGER) continue; }
3007  else
3008  { if (rightComparison != RFSD_KEY_SMALLER) continue; }
3009 
3010  // And larger than or equal to the left key.
3011  leftComparison = pLeftKeyOnDisk ? ((*fpComparisonFunction)(Key, &LeftKeyInMemory)) : RFSD_KEY_LARGER;
3012  if ( (leftComparison == RFSD_KEY_LARGER) || (leftComparison == RFSD_KEYS_MATCH) )
3013  {
3014  // The target range has been found. Read the reference to the disk node child, lower in the tree.
3015  // This returns the pointer preceding the righthand key.
3016  pTargetDiskNodeReference = (PRFSD_DISK_NODE_REF) (pBlockBuffer
3017  + sizeof(RFSD_BLOCK_HEAD) + (pBlockHeader->blk_nr_item * sizeof(RFSD_KEY_ON_DISK)) + (idxRightKey * sizeof(RFSD_DISK_NODE_REF)));
3018 
3019  // Continue recursion downwards; eventually a leaf node will be returned.
3021  Vcb, Key, pTargetDiskNodeReference->dc_block_number,
3022  &(leafNodeBlockNumber),
3023  ReturnOnFirstMatch, fpComparisonFunction, fpDirectoryCallback, pContext); // <
3024 
3025  if (ReturnOnFirstMatch || Status == STATUS_EVENT_DONE || // Success cases
3027  { goto return_results; }
3028  }
3029  }
3030  }
3031  }
3032 
3033 return_results:
3034 
3035  ExFreePool(pBlockBuffer);
3036  *out_NextBlockNumber = leafNodeBlockNumber;
3037  return Status;
3038 }
struct reiserfs_key RFSD_KEY_ON_DISK
Definition: rfsd.h:41
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG Key
Definition: fatprocs.h:2697
struct disk_child RFSD_DISK_NODE_REF
Definition: rfsd.h:43
#define STATUS_EVENT_DONE
Definition: ntstatus.h:132
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
PUCHAR RfsdAllocateAndLoadBlock(IN PRFSD_VCB Vcb, IN ULONG BlockIndex)
Definition: rfsdblock.c:34
__u16 blk_level
Definition: reiserfs_fs.h:679
struct reiserfs_key * PRFSD_KEY_ON_DISK
Definition: rfsd.h:41
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
#define PAGED_CODE()
Definition: video.h:57
RFSD_KEY_COMPARISON CompareShortKeys(IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
Definition: rfsd.c:2811
__u16 blk_nr_item
Definition: reiserfs_fs.h:680
smooth NULL
Definition: ftsmooth.c:416
struct disk_child * PRFSD_DISK_NODE_REF
Definition: rfsd.h:43
#define RFSD_KEY_SMALLER
Definition: rfsd.h:64
NTSTATUS _NavigateToLeafNode(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber, IN BOOLEAN ReturnOnFirstMatch, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY), RFSD_CALLBACK(fpDirectoryCallback), IN PVOID pContext)
Definition: rfsd.c:2934
#define RFSD_KEYS_MATCH
Definition: rfsd.h:63
#define Vcb
Definition: cdprocs.h:1425
#define RFSD_KEY_LARGER
Definition: rfsd.h:65
_In_ FLT_PREOP_CALLBACK_STATUS CallbackStatus
Definition: fltkernel.h:1020
void FillInMemoryKey(IN PRFSD_KEY_ON_DISK pKeyOnDisk, IN RFSD_KEY_VERSION KeyVersion, IN OUT PRFSD_KEY_IN_MEMORY pKeyInMemory)
Definition: rfsd.c:2777
#define RFSD_KEY_VERSION_UNKNOWN
Definition: rfsd.h:60
#define RFSD_LEAF_BLOCK_LEVEL
Definition: rfsd.h:68
Status
Definition: gdiplustypes.h:24
short RFSD_KEY_COMPARISON
Definition: rfsd.h:55
struct block_head * PRFSD_BLOCK_HEAD
Definition: rfsd.h:38
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2938
__u32 dc_block_number
Definition: reiserfs_fs.h:1114
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by NavigateToLeafNode(), and RfsdParseFilesystemTree().

◆ CompareKeys()

Compares two in memory keys, returning KEY_SMALLER, KEY_LARGER, or KEYS_MATCH relative to the first key given.

Definition at line 2856 of file rfsd.c.

2859 {
2860  PAGED_CODE();
2861 
2862  // compare 1. integer
2863  if( a->k_dir_id < b->k_dir_id ) return RFSD_KEY_SMALLER;
2864  if( a->k_dir_id > b->k_dir_id ) return RFSD_KEY_LARGER;
2865 
2866  // compare 2. integer
2867  if( a->k_objectid < b->k_objectid ) return RFSD_KEY_SMALLER;
2868  if( a->k_objectid > b->k_objectid ) return RFSD_KEY_LARGER;
2869 
2870  // compare 3. integer
2871  if( a->k_offset < b->k_offset ) return RFSD_KEY_SMALLER;
2872  if( a->k_offset > b->k_offset ) return RFSD_KEY_LARGER;
2873 
2874  // compare 4. integer
2875  // NOTE: Buchholz says that if we get to here in navigating the file tree, something has gone wrong...
2876  if( a->k_type < b->k_type ) return RFSD_KEY_SMALLER;
2877  if( a->k_type > b->k_type ) return RFSD_KEY_LARGER;
2878 
2879  return RFSD_KEYS_MATCH;
2880 }
#define PAGED_CODE()
Definition: video.h:57
#define RFSD_KEY_SMALLER
Definition: rfsd.h:64
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define RFSD_KEYS_MATCH
Definition: rfsd.h:63
#define RFSD_KEY_LARGER
Definition: rfsd.h:65
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Referenced by NavigateToLeafNode(), RfsdBuildBDL2(), and RfsdLoadInode().

◆ CompareKeysWithoutOffset()

RFSD_KEY_COMPARISON CompareKeysWithoutOffset ( IN PRFSD_KEY_IN_MEMORY  a,
IN PRFSD_KEY_IN_MEMORY  b 
)

Compares two in memory keys, returning KEY_SMALLER, KEY_LARGER, or KEYS_MATCH relative to the first key given.

Definition at line 2831 of file rfsd.c.

2834 {
2835  PAGED_CODE();
2836 
2837  // compare 1. integer
2838  if( a->k_dir_id < b->k_dir_id ) return RFSD_KEY_SMALLER;
2839  if( a->k_dir_id > b->k_dir_id ) return RFSD_KEY_LARGER;
2840 
2841  // compare 2. integer
2842  if( a->k_objectid < b->k_objectid ) return RFSD_KEY_SMALLER;
2843  if( a->k_objectid > b->k_objectid ) return RFSD_KEY_LARGER;
2844 
2845  // compare 4. integer
2846  // NOTE: Buchholz says that if we get to here in navigating the file tree, something has gone wrong...
2847  if( a->k_type < b->k_type ) return RFSD_KEY_SMALLER;
2848  if( a->k_type > b->k_type ) return RFSD_KEY_LARGER;
2849 
2850  return RFSD_KEYS_MATCH;
2851 }
#define PAGED_CODE()
Definition: video.h:57
#define RFSD_KEY_SMALLER
Definition: rfsd.h:64
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define RFSD_KEYS_MATCH
Definition: rfsd.h:63
#define RFSD_KEY_LARGER
Definition: rfsd.h:65
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Referenced by RfsdDirectoryCallback(), and RfsdScanDirCallback().

◆ CompareShortKeys()

Compares two in memory keys, returning KEY_SMALLER, KEY_LARGER, or KEYS_MATCH relative to the first key given.

Definition at line 2811 of file rfsd.c.

2814 {
2815  PAGED_CODE();
2816 
2817  // compare 1. integer
2818  if( a->k_dir_id < b->k_dir_id ) return RFSD_KEY_SMALLER;
2819  if( a->k_dir_id > b->k_dir_id ) return RFSD_KEY_LARGER;
2820 
2821  // compare 2. integer
2822  if( a->k_objectid < b->k_objectid ) return RFSD_KEY_SMALLER;
2823  if( a->k_objectid > b->k_objectid ) return RFSD_KEY_LARGER;
2824 
2825  return RFSD_KEYS_MATCH;
2826 }
#define PAGED_CODE()
Definition: video.h:57
#define RFSD_KEY_SMALLER
Definition: rfsd.h:64
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define RFSD_KEYS_MATCH
Definition: rfsd.h:63
#define RFSD_KEY_LARGER
Definition: rfsd.h:65
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204

Referenced by _NavigateToLeafNode(), RfsdParseFilesystemTree(), and RfsdSearchMcbTree().

◆ ConvertKeyTypeUniqueness()

__u32 ConvertKeyTypeUniqueness ( __u32  k_uniqueness)

Given the uniqueness value from a version 1 KEY_ON_DISK, convert that to the v2 equivalent type (which is used for the KEY_IN_MEMORY structures)

Definition at line 2758 of file rfsd.c.

2759 {
2760  switch (k_uniqueness)
2761  {
2766 
2767  default:
2768  RfsdPrint((DBG_ERROR, "Unexpected uniqueness value %i", k_uniqueness));
2769  // NOTE: If above value is 555, it's the 'any' value, which I'd be surprised to see on disk.
2770  DbgBreak();
2771  return 0xF; // We'll return v2 'any', just to see what happens...
2772  }
2773 }
#define RFSD_KEY_TYPE_v1_DIRENTRY
Definition: reiserfs.h:280
#define RFSD_KEY_TYPE_v2_STAT_DATA
Definition: reiserfs.h:282
#define RFSD_KEY_TYPE_v1_DIRECT
Definition: reiserfs.h:279
#define RFSD_KEY_TYPE_v1_STAT_DATA
Definition: reiserfs.h:277
#define RfsdPrint(arg)
Definition: rfsd.h:1069
#define DBG_ERROR
Definition: ffsdrv.h:1031
#define RFSD_KEY_TYPE_v2_DIRENTRY
Definition: reiserfs.h:285
#define RFSD_KEY_TYPE_v1_INDIRECT
Definition: reiserfs.h:278
#define RFSD_KEY_TYPE_v2_DIRECT
Definition: reiserfs.h:284
#define RFSD_KEY_TYPE_v2_INDIRECT
Definition: reiserfs.h:283
#define DbgBreak()
Definition: ext2fs.h:46

Referenced by FillInMemoryKey().

◆ DetermineOnDiskKeyFormat()

RFSD_KEY_VERSION DetermineOnDiskKeyFormat ( const PRFSD_KEY_ON_DISK  key)

Guess whether a key is v1, or v2, by investigating its type field. NOTE: I based this off Florian Buchholz's code snippet, which is from reisefs lib.

Old keys (on i386) have k_offset_v2.k_type == 15 (direct and indirect) or == 0 (dir items and stat data).

Definition at line 2743 of file rfsd.c.

2744 {
2745  int type = (int) key->u.k_offset_v2.k_type;
2746 
2747  PAGED_CODE();
2748 
2749  if ( type == 0x0 || type == 0xF )
2750  return RFSD_KEY_VERSION_1;
2751 
2752  return RFSD_KEY_VERSION_2;
2753 }
GLint x0
Definition: linetemp.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define PAGED_CODE()
Definition: video.h:57
#define RFSD_KEY_VERSION_2
Definition: rfsd.h:59
#define RFSD_KEY_VERSION_1
Definition: rfsd.h:58
Definition: path.c:41
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31

Referenced by FillInMemoryKey().

◆ FillInMemoryKey()

void FillInMemoryKey ( IN PRFSD_KEY_ON_DISK  pKeyOnDisk,
IN RFSD_KEY_VERSION  KeyVersion,
IN OUT PRFSD_KEY_IN_MEMORY  pKeyInMemory 
)

Fills an in-memory key structure with equivalent data as that given by an on-disk key, converting any older v1 information ito the new v2 formats.

Definition at line 2777 of file rfsd.c.

2781 {
2782  PAGED_CODE();
2783 
2784  // Sanity check that the input and output locations exist
2785  if (!pKeyOnDisk || !pKeyInMemory) { DbgBreak(); return; }
2786 
2787  // Copy over the fields that are compatible between keys
2788  pKeyInMemory->k_dir_id = pKeyOnDisk->k_dir_id;
2789  pKeyInMemory->k_objectid = pKeyOnDisk->k_objectid;
2790 
2791  if (KeyVersion == RFSD_KEY_VERSION_UNKNOWN)
2792  { KeyVersion = DetermineOnDiskKeyFormat(pKeyOnDisk); }
2793 
2794  // Copy over the fields that are incompatible between keys, converting older type fields to the v2 format
2795  switch (KeyVersion)
2796  {
2797  case RFSD_KEY_VERSION_1:
2798  pKeyInMemory->k_offset = pKeyOnDisk->u.k_offset_v1.k_offset;
2799  pKeyInMemory->k_type = ConvertKeyTypeUniqueness( pKeyOnDisk->u.k_offset_v1.k_uniqueness );
2800  break;
2801 
2802  case RFSD_KEY_VERSION_2:
2803  pKeyInMemory->k_offset = pKeyOnDisk->u.k_offset_v2.k_offset;
2804  pKeyInMemory->k_type = (__u32) pKeyOnDisk->u.k_offset_v2.k_type;
2805  break;
2806  }
2807 }
#define PAGED_CODE()
Definition: video.h:57
#define RFSD_KEY_VERSION_2
Definition: rfsd.h:59
__u32 ConvertKeyTypeUniqueness(__u32 k_uniqueness)
Definition: rfsd.c:2758
unsigned int __u32
Definition: compat.h:90
RFSD_KEY_VERSION DetermineOnDiskKeyFormat(const PRFSD_KEY_ON_DISK key)
Definition: rfsd.c:2743
#define RFSD_KEY_VERSION_UNKNOWN
Definition: rfsd.h:60
#define RFSD_KEY_VERSION_1
Definition: rfsd.h:58
#define DbgBreak()
Definition: ext2fs.h:46

Referenced by _NavigateToLeafNode(), and RfsdFindItemHeaderInBlock().

◆ NavigateToLeafNode()

NTSTATUS NavigateToLeafNode ( IN PRFSD_VCB  Vcb,
IN PRFSD_KEY_IN_MEMORY  Key,
IN ULONG  StartingBlockNumber,
OUT PULONG  out_NextBlockNumber 
)

Definition at line 2896 of file rfsd.c.

2902 {
2903  PAGED_CODE();
2904 
2905  return _NavigateToLeafNode(Vcb, Key, StartingBlockNumber, out_NextBlockNumber, TRUE, &CompareKeys, NULL, NULL);
2906 }
#define TRUE
Definition: types.h:120
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS _NavigateToLeafNode(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber, IN BOOLEAN ReturnOnFirstMatch, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY), RFSD_CALLBACK(fpDirectoryCallback), IN PVOID pContext)
Definition: rfsd.c:2934
#define Vcb
Definition: cdprocs.h:1425
RFSD_KEY_COMPARISON CompareKeys(IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
Definition: rfsd.c:2856

Referenced by RfsdLoadItem().

◆ RfsdBuildBDL2()

NTSTATUS RfsdBuildBDL2 ( IN PRFSD_VCB  Vcb,
IN PRFSD_KEY_IN_MEMORY  pKey,
IN PRFSD_INODE  pInode,
OUT PULONG  out_Count,
OUT PRFSD_BDL out_ppBdl 
)

Definition at line 675 of file rfsd.c.

681 {
683  BOOLEAN done = FALSE;
684 
685  RFSD_KEY_IN_MEMORY CurrentTargetKey = *pKey;
686  ULONGLONG CurrentOffset = 0;
687 
688  PRFSD_ITEM_HEAD pItemHeader = NULL; // The temporary storage for retrieving items from disk
689  PUCHAR pItemBuffer = NULL;
690  PUCHAR pBlockBuffer = NULL;
691 
692  ULONG idxCurrentBD = 0;
693  PRFSD_BDL pBdl = NULL; // The block descriptor list, which will be allocated, filled, and assigned to out_Bdl
694 
695  PAGED_CODE();
696 
697  // Allocate the BDL for the maximum number of block descriptors that will be needed (including the tail)
698  // FUTURE: sd_blocks DEFINITELY is not the number of blocks consumed by a file. (at least not the number of 4096-byte blocks)
699  // However, I'm unsure of how to calculate the number of blocks. Perhaps I should consider using a linked list instead?
700  KdPrint(("## Allocating %i BD's\n", pInode->i_size / Vcb->BlockSize + 3));
701  pBdl = ExAllocatePoolWithTag(NonPagedPool, sizeof(RFSD_BDL) * (SIZE_T) (pInode->i_size / Vcb->BlockSize + 3), RFSD_POOL_TAG);
702  if (!pBdl) { Status = STATUS_INSUFFICIENT_RESOURCES; goto errorout; }
703  //RtlZeroMemory(pBdl, sizeof(RFSD_BDL) * (pInode->sd_blocks + 1));
704  RtlZeroMemory(pBdl, sizeof(RFSD_BDL) * (SIZE_T) (pInode->i_size / Vcb->BlockSize + 3));
705 
706 
707  // Build descriptors for all of the indirect items associated with the file
708  while (!done)
709  {
710  // Search for an indirect item, corresponding to CurrentOffset...
711 
712  // Create the key to search for (note that the key always start with offset 1, even though it is for byte 0)
713  CurrentTargetKey.k_offset = CurrentOffset + 1;
714  CurrentTargetKey.k_type = RFSD_KEY_TYPE_v2_INDIRECT;
715 
716  // Perform the search
718  Vcb, &CurrentTargetKey,
719  &(pItemHeader), &(pItemBuffer), &(pBlockBuffer), NULL,
720  &CompareKeys
721  );
722 
723  // If there was no such indirect item...
724  if (Status == STATUS_NO_SUCH_MEMBER) { Status = STATUS_SUCCESS; break; }
725  if (!NT_SUCCESS(Status)) { goto errorout; }
726 
727  // Otherwise, create a block descriptor for each pointer in the indirect item
728  {
729  ULONG countBlockRefs = pItemHeader->ih_item_len / sizeof(ULONG);
730  ULONG idxBlockRef;
731 
732  for (idxBlockRef = 0; idxBlockRef < countBlockRefs; idxBlockRef++)
733  {
734  PULONG BlockRef = (PULONG) ((PUCHAR) pItemBuffer + sizeof(ULONG) * idxBlockRef);
735 
736  // Build a block descriptor for this block reference
737  pBdl[idxCurrentBD].Lba = (LONGLONG) *BlockRef * (LONGLONG) Vcb->BlockSize;
738  pBdl[idxCurrentBD].Length = Vcb->BlockSize;
739  pBdl[idxCurrentBD].Offset = CurrentOffset;
740 
741  // If this is the last reference in the indirect item, subtract the free space from the end
742  // TODO: this may not work, because the ih_free_space_reserved seems to be wrong / not there!
743  if (idxBlockRef == (countBlockRefs - 1))
744  pBdl[idxCurrentBD].Length -= pItemHeader->u.ih_free_space_reserved;
745 
746  // Advance to the next block reference
747  CurrentOffset += Vcb->BlockSize;
748  idxCurrentBD++;
749  }
750 
751  if (countBlockRefs <= 0) { done = TRUE; }
752  }
753 
754  if (pBlockBuffer) { ExFreePool(pBlockBuffer); pBlockBuffer = NULL; }
755  }
756 
757  // Cleanup the last remaining block buffer, from the indirect items
758  if (pBlockBuffer) { ExFreePool(pBlockBuffer); pBlockBuffer = NULL; }
759 
760  // Search for the tail of the file (its optional direct item), corresponding to CurrentOffset...
761  {
762  ULONG BlockNumber = 0;
763 
764  // Create the key to search for
765  CurrentTargetKey.k_offset = CurrentOffset + 1;
766  CurrentTargetKey.k_type = RFSD_KEY_TYPE_v2_DIRECT;
767 
768  // Perform the search
770  Vcb, &CurrentTargetKey,
771  &(pItemHeader), &(pItemBuffer), &(pBlockBuffer), &(BlockNumber),
772  &CompareKeys
773  );
774 
775  if (Status == STATUS_SUCCESS)
776  {
777  // If there was a tail, then build a block descriptor for it
778  pBdl[idxCurrentBD].Lba = (LONGLONG) BlockNumber * (LONGLONG) Vcb->BlockSize + pItemHeader->ih_item_location;
779  pBdl[idxCurrentBD].Length = pItemHeader->ih_item_len;
780  pBdl[idxCurrentBD].Offset = CurrentOffset;
781 
782  // Advance to the next block reference
783  CurrentOffset += pItemHeader->ih_item_len;
784  idxCurrentBD++;
785  }
786  else
787  {
788  if (Status == STATUS_NO_SUCH_MEMBER) { Status = STATUS_SUCCESS; goto errorout; } // If there wasn't a tail, it's fine
789  else { goto errorout; } // But if there was some other problem, let's report it.
790  }
791  }
792 
793  if (pBlockBuffer) { ExFreePool(pBlockBuffer); pBlockBuffer = NULL; }
794 
795  // Search for the second part of the tail of the file (its optional second direct item), corresponding to CurrentOffset...
796  {
797  ULONG BlockNumber = 0;
798 
799  // Create the key to search for
800  CurrentTargetKey.k_offset = CurrentOffset + 1;
801  CurrentTargetKey.k_type = RFSD_KEY_TYPE_v2_DIRECT;
802 
803  // Perform the search
805  Vcb, &CurrentTargetKey,
806  &(pItemHeader), &(pItemBuffer), &(pBlockBuffer), &(BlockNumber),
807  &CompareKeys
808  );
809 
810  if (Status == STATUS_SUCCESS)
811  {
812  // If there was a second part of the tail, then build a block descriptor for it
813  pBdl[idxCurrentBD].Lba = (LONGLONG) BlockNumber * (LONGLONG) Vcb->BlockSize + pItemHeader->ih_item_location;
814  pBdl[idxCurrentBD].Length = pItemHeader->ih_item_len;
815  pBdl[idxCurrentBD].Offset = CurrentOffset;
816 
817  idxCurrentBD++;
818  }
819  else
820  {
821  if (Status == STATUS_NO_SUCH_MEMBER) { Status = STATUS_SUCCESS; } // If there wasn't a second part of the tail, it's fine
822  else { goto errorout; } // But if there was some other problem, let's report it.
823  }
824  }
825 
826 errorout:
827  if (pBlockBuffer) { ExFreePool(pBlockBuffer); pBlockBuffer = NULL; }
828 
829  *out_ppBdl = pBdl;
830  *out_Count = idxCurrentBD;
831  return Status;
832 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NO_SUCH_MEMBER
Definition: ntstatus.h:597
ULONG Length
Definition: rfsd.h:833
__u16 ih_free_space_reserved
Definition: reiserfs_fs.h:530
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define RFSD_POOL_TAG
Definition: rfsd.h:99
NTSTATUS RfsdLoadItem(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pItemKey, OUT PRFSD_ITEM_HEAD *ppMatchingItemHeader, OUT PUCHAR *ppItemBuffer, OUT PUCHAR *ppBlockBuffer, OUT PULONG pBlockNumber, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY))
ULONGLONG Offset
Definition: rfsd.h:832
#define PAGED_CODE()
Definition: video.h:57
ULONGLONG Lba
Definition: rfsd.h:831
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
__u16 ih_item_location
Definition: reiserfs_fs.h:536
union item_head::@765 u
int64_t LONGLONG
Definition: typedefs.h:66
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
__u16 ih_item_len
Definition: reiserfs_fs.h:535
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Status
Definition: gdiplustypes.h:24
ULONG_PTR SIZE_T
Definition: typedefs.h:78
unsigned int * PULONG
Definition: retypes.h:1
RFSD_KEY_COMPARISON CompareKeys(IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
Definition: rfsd.c:2856
#define RFSD_KEY_TYPE_v2_DIRECT
Definition: reiserfs.h:284
unsigned int ULONG
Definition: retypes.h:1
#define RFSD_KEY_TYPE_v2_INDIRECT
Definition: reiserfs.h:283
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define KdPrint(x)
Definition: env_spec_w32.h:288
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by RfsdReadInode().

◆ RfsdLoadBlock()

BOOLEAN RfsdLoadBlock ( IN PRFSD_VCB  Vcb,
IN ULONG  dwBlk,
IN OUT PVOID  Buffer 
)

Just reads a block into a buffer

Definition at line 332 of file rfsd.c.

336 {
339 
340  PAGED_CODE();
341 
342  Offset = (LONGLONG) dwBlk;
343  Offset = Offset * Vcb->BlockSize;
344 
345  if (!RfsdCopyRead(
346  Vcb->StreamObj,
348  Vcb->BlockSize,
349  PIN_WAIT,
350  Buffer,
351  &IoStatus )) {
352  return FALSE;
353  }
354 
355  if (!NT_SUCCESS(IoStatus.Status)) {
356  return FALSE;
357  }
358 
359  return TRUE;
360 }
#define TRUE
Definition: types.h:120
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN OUT PIO_STATUS_BLOCK IoStatus
Definition: fatprocs.h:2650
#define PIN_WAIT
#define PAGED_CODE()
Definition: video.h:57
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
Definition: bufpool.h:45
int64_t LONGLONG
Definition: typedefs.h:66
BOOLEAN RfsdCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: read.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425

◆ RfsdLoadInode()

BOOLEAN RfsdLoadInode ( IN PRFSD_VCB  Vcb,
IN PRFSD_KEY_IN_MEMORY  pKey,
IN OUT PRFSD_INODE  Inode 
)

Reads an inode structure off disk into the Inode object (which has been allocated, but not filled with any data)

Definition at line 253 of file rfsd.c.

256 {
258 
259  PRFSD_ITEM_HEAD pItemHeader = NULL;
260  PUCHAR pItemBuffer = NULL;
261  PUCHAR pBlockBuffer = NULL;
262 
263  // Crate the target key for the stat item (stat items always have an offset of 0)
264  RFSD_KEY_IN_MEMORY TargetKey;
265 
266  PAGED_CODE();
267 
268  TargetKey = *pKey;
269  TargetKey.k_offset = 0x0;
270  TargetKey.k_type = RFSD_KEY_TYPE_v2_STAT_DATA;
271 
272  RfsdPrint((DBG_FUNC, /*__FUNCTION__*/ "on %i, %i\n", TargetKey.k_dir_id, TargetKey.k_objectid));
273 
274  //Load the stat data
275  Status = RfsdLoadItem(Vcb, &TargetKey,
276  &(pItemHeader), &(pItemBuffer), &(pBlockBuffer), NULL, //<
277  &CompareKeys
278  );
279  if (!NT_SUCCESS(Status))
280  { if (pBlockBuffer) {ExFreePool(pBlockBuffer);} return FALSE; }
281 
282  // Copy the item into the inode / stat data structure
283  RtlCopyMemory(Inode, pItemBuffer, sizeof(RFSD_INODE));
284 
285  // Cleanup
286  if (pBlockBuffer)
287  ExFreePool(pBlockBuffer);
288 
289  return TRUE;
290 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define RFSD_KEY_TYPE_v2_STAT_DATA
Definition: reiserfs.h:282
__u32 k_objectid
Definition: reiserfs.h:298
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS RfsdLoadItem(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY pItemKey, OUT PRFSD_ITEM_HEAD *ppMatchingItemHeader, OUT PUCHAR *ppItemBuffer, OUT PUCHAR *ppBlockBuffer, OUT PULONG pBlockNumber, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY))
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
#define DBG_FUNC
Definition: ffsdrv.h:1035
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
#define RfsdPrint(arg)
Definition: rfsd.h:1069
Status
Definition: gdiplustypes.h:24
RFSD_KEY_COMPARISON CompareKeys(IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
Definition: rfsd.c:2856
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by RfsdCreateFcbFromMcb(), RfsdCreateFile(), RfsdLookupFileName(), and RfsdProcessDirEntry().

◆ RfsdLoadSuper()

PRFSD_SUPER_BLOCK RfsdLoadSuper ( IN PRFSD_VCB  Vcb,
IN BOOLEAN  bVerify 
)

Definition at line 80 of file rfsd.c.

82 {
84  PRFSD_SUPER_BLOCK RfsdSb = NULL;
85 
86  PAGED_CODE();
87 
90  if (!RfsdSb) {
91  return NULL;
92  }
93 
95  Vcb,
98  (PVOID) RfsdSb,
99  bVerify );
100 
101  if (!NT_SUCCESS(Status)) {
102 
103  RfsdPrint((DBG_ERROR, "RfsdReadDisk: Read Block Device error.\n"));
104 
105  ExFreePool(RfsdSb);
106  return NULL;
107  }
108 
109  return RfsdSb;
110 }
struct _RFSD_SUPER_BLOCK * PRFSD_SUPER_BLOCK
NTSTATUS RfsdReadDisk(IN PRFSD_VCB Vcb, IN ULONGLONG Offset, IN ULONG Size, IN PVOID Buffer, IN BOOLEAN bVerify)
LONG NTSTATUS
Definition: precomp.h:26
#define RFSD_POOL_TAG
Definition: rfsd.h:99
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
static BOOL bVerify
Definition: verify.c:27
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
#define Vcb
Definition: cdprocs.h:1425
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define RfsdPrint(arg)
Definition: rfsd.h:1069
#define DBG_ERROR
Definition: ffsdrv.h:1031
#define SUPER_BLOCK_SIZE
Definition: ext2fs.h:86
Status
Definition: gdiplustypes.h:24
#define SUPER_BLOCK_OFFSET
Definition: ext2fs.h:85
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by RfsdMountVolume(), and RfsdVerifyVolume().

◆ RfsdParseFilesystemTree()

NTSTATUS RfsdParseFilesystemTree ( IN PRFSD_VCB  Vcb,
IN PRFSD_KEY_IN_MEMORY  Key,
IN ULONG  StartingBlockNumber,
IN   RFSD_CALLBACKfpDirectoryCallback,
IN PVOID  pContext 
)

Definition at line 2909 of file rfsd.c.

2916 {
2917  ULONG out = 0;
2918 
2919  PAGED_CODE();
2920 
2921  return _NavigateToLeafNode(Vcb, Key, StartingBlockNumber, &out, FALSE, &CompareShortKeys, fpDirectoryCallback, pContext);
2922 }
#define PAGED_CODE()
Definition: video.h:57
RFSD_KEY_COMPARISON CompareShortKeys(IN PRFSD_KEY_IN_MEMORY a, IN PRFSD_KEY_IN_MEMORY b)
Definition: rfsd.c:2811
NTSTATUS _NavigateToLeafNode(IN PRFSD_VCB Vcb, IN PRFSD_KEY_IN_MEMORY Key, IN ULONG StartingBlockNumber, OUT PULONG out_NextBlockNumber, IN BOOLEAN ReturnOnFirstMatch, IN RFSD_KEY_COMPARISON(*fpComparisonFunction)(PRFSD_KEY_IN_MEMORY, PRFSD_KEY_IN_MEMORY), RFSD_CALLBACK(fpDirectoryCallback), IN PVOID pContext)
Definition: rfsd.c:2934
#define Vcb
Definition: cdprocs.h:1425
static FILE * out
Definition: regtests2xml.c:44
unsigned int ULONG
Definition: retypes.h:1

Referenced by RfsdQueryDirectory(), and RfsdScanDir().

◆ SuperblockContainsMagicKey()

BOOLEAN SuperblockContainsMagicKey ( PRFSD_SUPER_BLOCK  sb)

Invoked by FSCTL.c on mount volume

Definition at line 2698 of file rfsd.c.

2699 {
2700 #define MAGIC_KEY_LENGTH 9
2701 
2702  UCHAR sz_MagicKey[] = REISER2FS_SUPER_MAGIC_STRING;
2703 #ifndef __REACTOS__
2704  BOOLEAN b_KeyMatches = TRUE;
2705 #endif
2706  UCHAR currentChar;
2707  int i;
2708 
2709  PAGED_CODE();
2710 
2711  // If any characters read from disk don't match the expected magic key, we don't have a ReiserFS volume.
2712  for (i = 0; i < MAGIC_KEY_LENGTH; i++)
2713  {
2714  currentChar = sb->s_magic[i];
2715  if (currentChar != sz_MagicKey[i])
2716  { return FALSE; }
2717  }
2718 
2719  return TRUE;
2720 }
#define TRUE
Definition: types.h:120
#define REISER2FS_SUPER_MAGIC_STRING
Definition: reiserfs.h:74
superblock * sb
Definition: btrfs.c:4137
#define PAGED_CODE()
Definition: video.h:57
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned char BOOLEAN
#define MAGIC_KEY_LENGTH
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by RfsdMountVolume().

Variable Documentation

◆ RfsdGlobal

PRFSD_GLOBAL RfsdGlobal

Definition at line 17 of file init.c.