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
2143dee7
Commit
2143dee7
authored
Jan 04, 2008
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mountmgr.sys: Create disk devices for all configured drives.
parent
07e92a7d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
199 additions
and
0 deletions
+199
-0
mountmgr.c
dlls/mountmgr.sys/mountmgr.c
+199
-0
No files found.
dlls/mountmgr.sys/mountmgr.c
View file @
2143dee7
...
...
@@ -38,6 +38,178 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
mountmgr
);
#define MAX_DOS_DRIVES 26
#define MAX_MOUNT_POINTS (2 * MAX_DOS_DRIVES)
/* extra info for disk devices, stored in DeviceExtension */
struct
disk_device_info
{
UNICODE_STRING
name
;
/* device name */
};
struct
mount_point
{
DEVICE_OBJECT
*
device
;
UNICODE_STRING
link
;
/* DOS device symlink */
void
*
id
;
/* device unique id */
unsigned
int
id_len
;
};
static
struct
mount_point
mount_points
[
MAX_MOUNT_POINTS
];
static
inline
UNICODE_STRING
*
get_device_name
(
DEVICE_OBJECT
*
dev
)
{
return
&
((
struct
disk_device_info
*
)
dev
->
DeviceExtension
)
->
name
;
}
/* read a Unix symlink; returned buffer must be freed by caller */
static
char
*
read_symlink
(
const
char
*
path
)
{
char
*
buffer
;
int
ret
,
size
=
128
;
for
(;;)
{
if
(
!
(
buffer
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
ret
=
readlink
(
path
,
buffer
,
size
);
if
(
ret
==
-
1
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buffer
);
return
0
;
}
if
(
ret
!=
size
)
{
buffer
[
ret
]
=
0
;
return
buffer
;
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buffer
);
size
*=
2
;
}
}
static
NTSTATUS
create_disk_device
(
DRIVER_OBJECT
*
driver
,
DWORD
type
,
DEVICE_OBJECT
**
dev_obj
)
{
static
const
WCHAR
harddiskW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'H'
,
'a'
,
'r'
,
'd'
,
'd'
,
'i'
,
's'
,
'k'
,
'V'
,
'o'
,
'l'
,
'u'
,
'm'
,
'e'
,
'%'
,
'u'
,
0
};
static
const
WCHAR
cdromW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'C'
,
'd'
,
'R'
,
'o'
,
'm'
,
'%'
,
'u'
,
0
};
static
const
WCHAR
floppyW
[]
=
{
'\\'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
'\\'
,
'F'
,
'l'
,
'o'
,
'p'
,
'p'
,
'y'
,
'%'
,
'u'
,
0
};
UINT
i
,
first
=
0
;
NTSTATUS
status
=
0
;
const
WCHAR
*
format
;
UNICODE_STRING
name
;
struct
disk_device_info
*
info
;
switch
(
type
)
{
case
DRIVE_REMOVABLE
:
format
=
floppyW
;
break
;
case
DRIVE_CDROM
:
format
=
cdromW
;
break
;
case
DRIVE_FIXED
:
default:
/* FIXME */
format
=
harddiskW
;
first
=
1
;
/* harddisk volumes start counting from 1 */
break
;
}
name
.
MaximumLength
=
(
strlenW
(
format
)
+
10
)
*
sizeof
(
WCHAR
);
name
.
Buffer
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
name
.
MaximumLength
);
for
(
i
=
first
;
i
<
32
;
i
++
)
{
sprintfW
(
name
.
Buffer
,
format
,
i
);
name
.
Length
=
strlenW
(
name
.
Buffer
)
*
sizeof
(
WCHAR
);
status
=
IoCreateDevice
(
driver
,
sizeof
(
*
info
),
&
name
,
0
,
0
,
FALSE
,
dev_obj
);
if
(
status
!=
STATUS_OBJECT_NAME_COLLISION
)
break
;
}
if
(
!
status
)
{
info
=
(
*
dev_obj
)
->
DeviceExtension
;
info
->
name
=
name
;
}
else
{
FIXME
(
"IoCreateDevice %s got %x
\n
"
,
debugstr_w
(
name
.
Buffer
),
status
);
RtlFreeUnicodeString
(
&
name
);
}
return
status
;
}
static
NTSTATUS
add_mount_point
(
DRIVER_OBJECT
*
driver
,
DWORD
type
,
int
drive
,
const
void
*
id
,
unsigned
int
id_len
)
{
static
const
WCHAR
driveW
[]
=
{
'\\'
,
'D'
,
'o'
,
's'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
'\\'
,
'%'
,
'c'
,
':'
,
0
};
static
const
WCHAR
volumeW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'V'
,
'o'
,
'l'
,
'u'
,
'm'
,
'e'
,
'{'
,
'%'
,
'0'
,
'8'
,
'x'
,
'-'
,
'%'
,
'0'
,
'4'
,
'x'
,
'-'
,
'%'
,
'0'
,
'4'
,
'x'
,
'-'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'-'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'}'
,
0
};
WCHAR
*
drive_link
,
*
volume_link
;
NTSTATUS
status
;
GUID
guid
;
UINT
i
;
struct
mount_point
*
mount_drive
=
NULL
,
*
mount_volume
=
NULL
;
/* find two free mount points */
for
(
i
=
0
;
i
<
MAX_MOUNT_POINTS
;
i
++
)
{
if
(
mount_points
[
i
].
device
)
continue
;
if
(
!
mount_drive
)
{
mount_drive
=
&
mount_points
[
i
];
continue
;
}
mount_volume
=
&
mount_points
[
i
];
break
;
}
if
(
!
mount_volume
)
return
STATUS_NO_MEMORY
;
/* create the volume */
memset
(
&
guid
,
0
,
sizeof
(
guid
)
);
/* FIXME */
guid
.
Data4
[
7
]
=
'A'
+
drive
;
drive_link
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
driveW
)
);
volume_link
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
sizeof
(
volumeW
)
);
sprintfW
(
drive_link
,
driveW
,
'A'
+
drive
);
sprintfW
(
volume_link
,
volumeW
,
guid
.
Data1
,
guid
.
Data2
,
guid
.
Data3
,
guid
.
Data4
[
0
],
guid
.
Data4
[
1
],
guid
.
Data4
[
2
],
guid
.
Data4
[
3
],
guid
.
Data4
[
4
],
guid
.
Data4
[
5
],
guid
.
Data4
[
6
],
guid
.
Data4
[
7
]);
RtlInitUnicodeString
(
&
mount_drive
->
link
,
drive_link
);
RtlInitUnicodeString
(
&
mount_volume
->
link
,
volume_link
);
status
=
create_disk_device
(
driver
,
type
,
&
mount_drive
->
device
);
if
(
status
)
{
RtlFreeUnicodeString
(
&
mount_drive
->
link
);
RtlFreeUnicodeString
(
&
mount_volume
->
link
);
return
status
;
}
mount_volume
->
device
=
mount_drive
->
device
;
/* FIXME: incr ref count */
mount_drive
->
id
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
id_len
);
mount_drive
->
id_len
=
id_len
;
memcpy
(
mount_drive
->
id
,
id
,
id_len
);
mount_volume
->
id
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
id_len
);
mount_volume
->
id_len
=
id_len
;
memcpy
(
mount_volume
->
id
,
id
,
id_len
);
IoCreateSymbolicLink
(
&
mount_drive
->
link
,
get_device_name
(
mount_drive
->
device
)
);
IoCreateSymbolicLink
(
&
mount_volume
->
link
,
get_device_name
(
mount_volume
->
device
)
);
TRACE
(
"created device %s symlinks %s %s
\n
"
,
debugstr_w
(
get_device_name
(
mount_drive
->
device
)
->
Buffer
),
debugstr_w
(
mount_drive
->
link
.
Buffer
),
debugstr_w
(
mount_volume
->
link
.
Buffer
)
);
return
STATUS_SUCCESS
;
}
/* handler for ioctls on the mount manager device */
static
NTSTATUS
WINAPI
mountmgr_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
...
...
@@ -78,6 +250,31 @@ static NTSTATUS WINAPI harddisk_ioctl( DEVICE_OBJECT *device, IRP *irp )
return
irp
->
IoStatus
.
u
.
Status
;
}
/* create mount points for mapped drives */
static
void
create_drive_mount_points
(
DRIVER_OBJECT
*
driver
)
{
const
char
*
config_dir
=
wine_get_config_dir
();
char
*
buffer
,
*
p
,
*
link
;
unsigned
int
i
;
if
((
buffer
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
strlen
(
config_dir
)
+
sizeof
(
"/dosdevices/a:"
)
)))
{
strcpy
(
buffer
,
config_dir
);
strcat
(
buffer
,
"/dosdevices/a:"
);
p
=
buffer
+
strlen
(
buffer
)
-
2
;
for
(
i
=
0
;
i
<
MAX_DOS_DRIVES
;
i
++
)
{
*
p
=
'a'
+
i
;
if
(
!
(
link
=
read_symlink
(
buffer
)))
continue
;
add_mount_point
(
driver
,
DRIVE_FIXED
,
i
,
link
,
strlen
(
link
)
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
link
);
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buffer
);
}
}
/* driver entry point for the harddisk driver */
static
NTSTATUS
WINAPI
harddisk_driver_entry
(
DRIVER_OBJECT
*
driver
,
UNICODE_STRING
*
path
)
{
...
...
@@ -101,6 +298,8 @@ static NTSTATUS WINAPI harddisk_driver_entry( DRIVER_OBJECT *driver, UNICODE_STR
return
status
;
}
create_drive_mount_points
(
driver
);
return
status
;
}
...
...
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