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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
/*****************************************************************************/
/* RootHandler.cpp Copyright (c) Ladislav Zezula 2015 */
/*---------------------------------------------------------------------------*/
/* Implementation of root handler */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 09.03.15 1.00 Lad Created */
/*****************************************************************************/
#define __CASCLIB_SELF__
#include "../CascLib.h"
#include "../CascCommon.h"
//-----------------------------------------------------------------------------
// Constructor and destructor - TFileTreeRoot
TFileTreeRoot::TFileTreeRoot(DWORD FileTreeFlags) : TRootHandler()
{
// Initialize the file tree
FileTree.Create(FileTreeFlags);
}
TFileTreeRoot::~TFileTreeRoot()
{
// Free the file tree
FileTree.Free();
dwFeatures = 0;
}
//-----------------------------------------------------------------------------
// Virtual functions - TFileTreeRoot
int TFileTreeRoot::Insert(
const char * szFileName,
PCASC_CKEY_ENTRY pCKeyEntry)
{
PCASC_FILE_NODE pFileNode;
pFileNode = FileTree.InsertByName(pCKeyEntry, szFileName, FileTree.GetNextFileDataId());
return (pFileNode != NULL) ? ERROR_SUCCESS : ERROR_CAN_NOT_COMPLETE;
}
PCASC_CKEY_ENTRY TFileTreeRoot::GetFile(TCascStorage * /* hs */, const char * szFileName)
{
PCASC_FILE_NODE pFileNode;
ULONGLONG FileNameHash = CalcFileNameHash(szFileName);
pFileNode = FileTree.Find(FileNameHash);
return (pFileNode != NULL) ? pFileNode->pCKeyEntry : NULL;
}
PCASC_CKEY_ENTRY TFileTreeRoot::GetFile(TCascStorage * /* hs */, DWORD FileDataId)
{
PCASC_FILE_NODE pFileNode;
pFileNode = FileTree.FindById(FileDataId);
return (pFileNode != NULL) ? pFileNode->pCKeyEntry : NULL;
}
PCASC_CKEY_ENTRY TFileTreeRoot::GetFile(size_t nFileIndex, char * szFileName, size_t ccFileName)
{
PCASC_CKEY_ENTRY pCKeyEntry = NULL;
PCASC_FILE_NODE pFileNode;
// Perform the search in the underlying file tree
if((pFileNode = FileTree.PathAt(szFileName, ccFileName, nFileIndex)) != NULL)
pCKeyEntry = pFileNode->pCKeyEntry;
return pCKeyEntry;
}
PCASC_CKEY_ENTRY TFileTreeRoot::Search(TCascSearch * pSearch, PCASC_FIND_DATA pFindData)
{
PCASC_FILE_NODE pFileNode;
size_t nMaxFileIndex = GetMaxFileIndex();
// Are we still inside the root directory range?
while(pSearch->nFileIndex < nMaxFileIndex)
{
//BREAKIF(pSearch->nFileIndex >= 2823765);
// Retrieve the file item
pFileNode = FileTree.PathAt(pFindData->szFileName, _countof(pFindData->szFileName), pSearch->nFileIndex++);
if(pFileNode != NULL)
{
// Ignore folders, but report mount points. These can and should be able to open and read
if((pFileNode->Flags & (CFN_FLAG_FOLDER | CFN_FLAG_MOUNT_POINT)) != CFN_FLAG_FOLDER)
{
// Check the wildcard
if(CascCheckWildCard(pFindData->szFileName, pSearch->szMask))
{
// Retrieve the extra values (FileDataId, file size and locale flags)
FileTree.GetExtras(pFileNode, &pFindData->dwFileDataId, &pFindData->dwLocaleFlags, &pFindData->dwContentFlags);
// Return the found CKey entry
return pFileNode->pCKeyEntry;
}
}
}
}
// No more entries
return NULL;
}
bool TFileTreeRoot::GetInfo(PCASC_CKEY_ENTRY pCKeyEntry, PCASC_FILE_FULL_INFO pFileInfo)
{
PCASC_FILE_NODE pFileNode;
// Can't do much if the root key is NULL
if(pCKeyEntry != NULL)
{
pFileNode = FileTree.Find(pCKeyEntry);
if(pFileNode != NULL)
{
FileTree.GetExtras(pFileNode, &pFileInfo->FileDataId, &pFileInfo->LocaleFlags, &pFileInfo->ContentFlags);
pFileInfo->FileNameHash = pFileNode->FileNameHash;
return true;
}
}
return false;
}
size_t TFileTreeRoot::Copy(TRootHandler * pRoot)
{
PCASC_CKEY_ENTRY pCKeyEntry;
size_t nMaxFileIndex = GetMaxFileIndex();
size_t nItemsCopied = 0;
char szFileName[0x200];
for(size_t nFileIndex = 0; nFileIndex < nMaxFileIndex; nFileIndex++)
{
if((pCKeyEntry = pRoot->GetFile(nFileIndex, szFileName, _countof(szFileName))) != NULL)
{
if(szFileName[0] != 0)
{
Insert(szFileName, pCKeyEntry);
nItemsCopied++;
}
}
}
return nItemsCopied;
}
size_t TFileTreeRoot::GetMaxFileIndex()
{
return FileTree.GetMaxFileIndex();
}
|