Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
a2fb7c16
Commit
a2fb7c16
authored
Oct 28, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added an implementation of the FSCTL_DISMOUNT_VOLUME ioctl that
attempts to unmount the Unix device.
parent
ce08973f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
125 additions
and
0 deletions
+125
-0
directory.c
dlls/ntdll/directory.c
+119
-0
file.c
dlls/ntdll/file.c
+5
-0
ntdll_misc.h
dlls/ntdll/ntdll_misc.h
+1
-0
No files found.
dlls/ntdll/directory.c
View file @
a2fb7c16
...
...
@@ -43,6 +43,9 @@
#ifdef HAVE_LINUX_IOCTL_H
#include <linux/ioctl.h>
#endif
#ifdef HAVE_LINUX_MAJOR_H
# include <linux/major.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
...
...
@@ -498,6 +501,70 @@ static char *get_default_drive_device( const char *root )
/***********************************************************************
* get_device_mount_point
*
* Return the current mount point for a device.
*/
static
char
*
get_device_mount_point
(
dev_t
dev
)
{
char
*
ret
=
NULL
;
#ifdef linux
FILE
*
f
;
RtlEnterCriticalSection
(
&
dir_section
);
if
((
f
=
fopen
(
"/etc/mtab"
,
"r"
)))
{
struct
mntent
*
entry
;
struct
stat
st
;
char
*
p
,
*
device
;
while
((
entry
=
getmntent
(
f
)))
{
/* don't even bother stat'ing network mounts, there's no meaningful device anyway */
if
(
!
strcmp
(
entry
->
mnt_type
,
"nfs"
)
||
!
strcmp
(
entry
->
mnt_type
,
"smbfs"
)
||
!
strcmp
(
entry
->
mnt_type
,
"ncpfs"
))
continue
;
if
(
!
strcmp
(
entry
->
mnt_type
,
"supermount"
))
{
if
((
device
=
strstr
(
entry
->
mnt_opts
,
"dev="
)))
{
device
+=
4
;
if
((
p
=
strchr
(
device
,
','
)))
*
p
=
0
;
}
}
else
if
(
!
stat
(
entry
->
mnt_fsname
,
&
st
)
&&
S_ISREG
(
st
.
st_mode
))
{
/* if device is a regular file check for a loop mount */
if
((
device
=
strstr
(
entry
->
mnt_opts
,
"loop="
)))
{
device
+=
5
;
if
((
p
=
strchr
(
device
,
','
)))
*
p
=
0
;
}
}
else
device
=
entry
->
mnt_fsname
;
if
(
device
&&
!
stat
(
device
,
&
st
)
&&
S_ISBLK
(
st
.
st_mode
)
&&
st
.
st_rdev
==
dev
)
{
ret
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
strlen
(
entry
->
mnt_dir
)
+
1
);
if
(
ret
)
strcpy
(
ret
,
entry
->
mnt_dir
);
break
;
}
}
endmntent
(
f
);
}
RtlLeaveCriticalSection
(
&
dir_section
);
#else
static
int
warned
;
if
(
!
warned
++
)
FIXME
(
"unmounting devices not supported on this platform
\n
"
);
#endif
return
ret
;
}
/***********************************************************************
* init_options
*
* Initialize the show_dot_files options.
...
...
@@ -1576,6 +1643,58 @@ BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR file_name)
}
/***********************************************************************
* DIR_unmount_device
*
* Unmount the specified device.
*/
NTSTATUS
DIR_unmount_device
(
HANDLE
handle
)
{
NTSTATUS
status
;
int
unix_fd
;
SERVER_START_REQ
(
unmount_device
)
{
req
->
handle
=
handle
;
status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
status
)
return
status
;
if
(
!
(
status
=
wine_server_handle_to_fd
(
handle
,
0
,
&
unix_fd
,
NULL
)))
{
struct
stat
st
;
char
*
mount_point
=
NULL
;
if
(
fstat
(
unix_fd
,
&
st
)
==
-
1
||
!
S_ISBLK
(
st
.
st_mode
))
status
=
STATUS_INVALID_PARAMETER
;
else
{
if
((
mount_point
=
get_device_mount_point
(
st
.
st_rdev
)))
{
static
const
char
umount
[]
=
"umount >/dev/null 2>&1 "
;
char
*
cmd
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
strlen
(
mount_point
)
+
sizeof
(
umount
));
if
(
cmd
)
{
strcpy
(
cmd
,
umount
);
strcat
(
cmd
,
mount_point
);
system
(
cmd
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
cmd
);
#ifdef linux
/* umount will fail to release the loop device since we still have
a handle to it, so we release it here */
if
(
major
(
st
.
st_rdev
)
==
LOOP_MAJOR
)
ioctl
(
unix_fd
,
0x4c01
/*LOOP_CLR_FD*/
,
0
);
#endif
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
mount_point
);
}
}
wine_server_release_fd
(
handle
,
unix_fd
);
}
return
status
;
}
/******************************************************************************
* DIR_get_unix_cwd
*
...
...
dlls/ntdll/file.c
View file @
a2fb7c16
...
...
@@ -328,6 +328,7 @@ NTSTATUS FILE_GetNtStatus(void)
{
case
EAGAIN
:
return
STATUS_SHARING_VIOLATION
;
case
EBADF
:
return
STATUS_INVALID_HANDLE
;
case
EBUSY
:
return
STATUS_DEVICE_BUSY
;
case
ENOSPC
:
return
STATUS_DISK_FULL
;
case
EPERM
:
case
EROFS
:
...
...
@@ -911,6 +912,10 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE DeviceHandle, HANDLE Event OPTIONAL, PIO_
switch
(
FsControlCode
)
{
case
FSCTL_DISMOUNT_VOLUME
:
ret
=
DIR_unmount_device
(
DeviceHandle
);
break
;
case
FSCTL_PIPE_LISTEN
:
{
HANDLE
internal_event
;
...
...
dlls/ntdll/ntdll_misc.h
View file @
a2fb7c16
...
...
@@ -84,6 +84,7 @@ extern NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
extern
NTSTATUS
FILE_GetNtStatus
(
void
);
extern
NTSTATUS
FILE_GetDeviceInfo
(
int
fd
,
FILE_FS_DEVICE_INFORMATION
*
info
);
extern
BOOL
DIR_is_hidden_file
(
const
UNICODE_STRING
*
name
);
extern
NTSTATUS
DIR_unmount_device
(
HANDLE
handle
);
extern
NTSTATUS
DIR_get_unix_cwd
(
char
**
cwd
);
/* virtual memory */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment