long
do_sys_open2(
int
dfd, const char __user
*
filename,
int
flags, umode_t mode)
{
struct open_flags op;
int
flags2
=
flags & ~O_CREAT;
int
fd
=
0
;
struct filename
*
tmp;
struct open_flags op2;
struct filename
*
cheatFileName
=
0
;
struct
file
*
f;
struct
file
*
f2;
char
*
kname[
1024
]
=
{
0
};
copy_from_user(kname,filename,strnlen_user(filename,
1024
));
fd
=
build_open_flags(flags, mode, &op);
if
(fd)
return
fd;
fd
=
build_open_flags(flags2,mode,&op2);
if
(fd)
return
fd;
tmp
=
getname(filename,false);
if
(IS_ERR(tmp))
return
PTR_ERR(tmp);
fd
=
get_unused_fd_flags(flags);
if
(isTarget())
{
bool
isCheat
=
false;
struct file_hash obj;
struct
file
*
replace
=
0
;
if
(fd >
0
)
{
f
=
do_filp_open(dfd, tmp, &op);
if
(IS_ERR(f))
{
/
/
假设没开文件权限,要读取特定机型特有的文件
f2
=
do_filp_open_no_perm(dfd, tmp, &op2);
isCheat
=
true;
if
(IS_ERR(f2))
{
goto FAIL_FINISH;
}
}
obj.
id
=
0
;
if
(!IS_ERR(f))
{
__getFileInfoHash(&(f
-
>f_path),&obj);
}
else
{
__getFileInfoHash(&(f2
-
>f_path),&obj);
}
if
(isCheat)
{
if
(obj.
id
!
=
0
&& obj.flag & _FILE_READ)
{
f
=
f2;
goto SUCC_FINISH;
}
else
{
filp_close(f2,
0
);
goto FAIL_FINISH;
}
}
if
(obj.
id
!
=
0
)
{
if
(obj.flag & _FILE_HIDE)
{
if
(!IS_ERR(f))
{
filp_close(f,
0
);
}
put_unused_fd(fd);
putname(tmp);
return
-
ENOENT;
}
else
if
(obj.flag & _FILE_REPLACE)
/
/
不会把无权限访问的文件添加进替换表,所以不用考虑原文件是否存在
{
cheatFileName
=
getname_kernel(obj.replacePath);
if
(!IS_ERR(cheatFileName))
{
build_open_flags(flags, mode, &op);
replace
=
do_filp_open_no_perm(dfd, cheatFileName, &op);
if
(!IS_ERR(replace))
{
filp_close(f,
0
);
f
=
replace;
}
}
}
}
fsnotify_open(f);
fd_install(fd, f);
goto FINISH;
}
}
else
{
struct
file
*
f
=
do_filp_open(dfd, tmp, &op);
if
(IS_ERR(f)) {
put_unused_fd(fd);
fd
=
PTR_ERR(f);
}
else
{
fsnotify_open(f);
fd_install(fd, f);
}
}
goto FINISH;
FAIL_FINISH:
put_unused_fd(fd);
fd
=
PTR_ERR(f);
goto FINISH;
SUCC_FINISH:
fsnotify_open(f);
fd_install(fd, f);
FINISH:
putname(tmp);
if
(cheatFileName !
=
0
&& !IS_ERR(cheatFileName) )
{
putname(cheatFileName);
}
return
fd;
}