-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdir.c
141 lines (113 loc) · 3.76 KB
/
dir.c
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
#include <stdlib.h>
#include <string.h>
#include "dir.h"
#include "general.h"
#include "debug.h"
#include "internal.h"
#include "file.h"
#include "inode.h"
#include "file_info.h"
int MxfsFindFileInDir(MINIX_FS *FileSys, unsigned Inode, minix_inode *DirInfo, const char *Filename)
{
unsigned TotalEntries, i, j = 0, Offset;
int Result;
minix_dir_entry Entries[MINIX_BLOCK_SIZE / sizeof(minix_dir_entry)];
TotalEntries = DirInfo->d2_size / sizeof(minix_dir_entry);
for(i = 0; i < TotalEntries; ++i)
{
if(i % COUNTOF(Entries) == 0)
{
Offset = i * sizeof(minix_dir_entry);
Result = MxfsGetBlockFromFileOffset(FileSys, Inode, DirInfo, Offset, FALSE);
if(Result < 0)
return Result;
Result = MxfsCacheRead(FileSys, Entries, Result, 0, MINIX_BLOCK_SIZE);
if(Result < 0)
return Result;
j = 0;
}
if(Entries[j].inode != 0 && strncmp(Filename, Entries[j].name, MAX_NAME_LEN) == 0)
return Entries[j].inode;
++j;
}
return -1;
}
int MxfsParsePath(MINIX_FS *FileSys, const char *Path, BOOL Parent)
{
char Filename[32];
unsigned FilenameLen = 0;
int Result = 1;
minix_inode DirInfo;
while(1)
{
if(*Path != '/' && *Path != '\\' && *Path != '\0')
{
if(FilenameLen + 1 >= sizeof(Filename))
return -ERROR_NOT_FOUND;
Filename[FilenameLen++] = *Path;
}
else if(FilenameLen != 0)
{
if(Parent && *Path == '\0')
break;
Filename[FilenameLen] = '\0';
MxfsReadInode(FileSys, Result, &DirInfo);
if(!(DirInfo.d2_mode & I_DIRECTORY))
return -ERROR_NOT_FOUND;
Result = MxfsFindFileInDir(FileSys, Result, &DirInfo, Filename);
FilenameLen = 0;
}
if(Result < 0 || *Path == '\0')
break;
++Path;
}
return Result;
}
int DOKAN_CALLBACK MxfsFindFiles(
LPCWSTR PathName,
PFillFindData Callback,
PDOKAN_FILE_INFO FileInfo)
{
TRACE("%ls %p", PathName, FileInfo);
ASSERT(FileInfo->IsDirectory);
int Result;
minix_dir_entry Entries[MINIX_BLOCK_SIZE / sizeof(minix_dir_entry)];
unsigned TotalEntries, FileIdx, Offset, i, j;
minix_inode DirInfo, Info;
MINIX_FS *FileSys = (MINIX_FS*)(LONG_PTR)FileInfo->DokanOptions->GlobalContext;
FILE_CTX *FileCtx = (FILE_CTX*)(LONG_PTR)FileInfo->Context;
ASSERT(FileCtx);
Result = MxfsReadInode(FileSys, FileCtx->Index, &DirInfo);
if(Result < 0)
return Result;
TotalEntries = DirInfo.d2_size / sizeof(minix_dir_entry);
if(TotalEntries == 0)
return 0; // empty dir
WIN32_FIND_DATAW wfd;
ZeroMemory(&wfd, sizeof(wfd));
for(i = 0, j = 0; i < TotalEntries; ++i, ++j)
{
if(i % COUNTOF(Entries) == 0)
{
Offset = i * sizeof(minix_dir_entry);
Result = MxfsGetBlockFromFileOffset(FileSys, FileCtx->Index, &DirInfo, Offset, FALSE);
if(Result < 0)
return Result;
Result = MxfsCacheRead(FileSys, Entries, Result, 0, MINIX_BLOCK_SIZE);
if(Result < 0)
return Result;
j = 0;
}
FileIdx = Entries[j].inode;
if(!FileIdx)
continue;
if(MxfsReadInode(FileSys, FileIdx, &Info) < 0)
{
WARN("Invalid node in directory\n");
continue;
}
MxfsFillFindData(&wfd, &Entries[j], &Info);
Callback(&wfd, FileInfo);
}
return 0;
}