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
36419837
Commit
36419837
authored
Feb 25, 2020
by
Zebediah Figura
Committed by
Alexandre Julliard
Feb 27, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Reimplement DefineDosDevice() on top of NT symbolic links.
Signed-off-by:
Zebediah Figura
<
zfigura@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
4ab43e28
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
36 additions
and
81 deletions
+36
-81
volume.c
dlls/kernel32/tests/volume.c
+6
-6
volume.c
dlls/kernel32/volume.c
+30
-75
No files found.
dlls/kernel32/tests/volume.c
View file @
36419837
...
...
@@ -126,11 +126,11 @@ static void test_dos_devices(void)
}
ret
=
DefineDosDeviceA
(
0
,
drivestr
,
"C:/windows/"
);
todo_wine
ok
(
ret
,
"failed to define drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ok
(
ret
,
"failed to define drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ret
=
QueryDosDeviceA
(
drivestr
,
buf
,
sizeof
(
buf
)
);
todo_wine
ok
(
ret
,
"failed to query drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
todo_wine
ok
(
!
strcmp
(
buf
,
"
\\
??
\\
C:
\\
windows
\\
"
),
"got path %s
\n
"
,
debugstr_a
(
buf
));
ok
(
ret
,
"failed to query drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ok
(
!
strcmp
(
buf
,
"
\\
??
\\
C:
\\
windows
\\
"
),
"got path %s
\n
"
,
debugstr_a
(
buf
));
sprintf
(
buf
,
"%s/system32"
,
drivestr
);
file
=
CreateFileA
(
buf
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
...
...
@@ -146,7 +146,7 @@ static void test_dos_devices(void)
todo_wine
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"got error %u
\n
"
,
GetLastError
());
ret
=
DefineDosDeviceA
(
DDD_REMOVE_DEFINITION
,
drivestr
,
NULL
);
todo_wine
ok
(
ret
,
"failed to remove drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ok
(
ret
,
"failed to remove drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ret
=
QueryDosDeviceA
(
drivestr
,
buf
,
sizeof
(
buf
)
);
ok
(
!
ret
,
"expected failure
\n
"
);
...
...
@@ -164,8 +164,8 @@ static void test_dos_devices(void)
ok
(
ret
,
"failed to define drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ret
=
QueryDosDeviceA
(
drivestr
,
buf
,
sizeof
(
buf
)
);
todo_wine
ok
(
ret
,
"failed to query drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
todo_wine
ok
(
!
strcmp
(
buf
,
"
\\
??
\\
C:
\\
windows
\\
"
),
"got path %s
\n
"
,
debugstr_a
(
buf
));
ok
(
ret
,
"failed to query drive %s, error %u
\n
"
,
drivestr
,
GetLastError
());
ok
(
!
strcmp
(
buf
,
"
\\
??
\\
C:
\\
windows
\\
"
),
"got path %s
\n
"
,
debugstr_a
(
buf
));
sprintf
(
buf
,
"%s/system32"
,
drivestr
);
file
=
CreateFileA
(
buf
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
...
...
dlls/kernel32/volume.c
View file @
36419837
...
...
@@ -39,6 +39,7 @@
#include "ntddcdrm.h"
#define WINE_MOUNTMGR_EXTENSIONS
#include "ddk/mountmgr.h"
#include "ddk/wdm.h"
#include "kernel_private.h"
#include "wine/library.h"
#include "wine/unicode.h"
...
...
@@ -68,29 +69,6 @@ enum fs_type
FS_UDF
/* For reference [E] = Ecma-167.pdf, [U] = udf260.pdf */
};
/* get the path of a dos device symlink in the $WINEPREFIX/dosdevices directory */
static
char
*
get_dos_device_path
(
LPCWSTR
name
)
{
const
char
*
config_dir
=
wine_get_config_dir
();
char
*
buffer
,
*
dev
;
int
i
;
if
(
!
(
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
config_dir
)
+
sizeof
(
"/dosdevices/"
)
+
5
)))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
}
strcpy
(
buffer
,
config_dir
);
strcat
(
buffer
,
"/dosdevices/"
);
dev
=
buffer
+
strlen
(
buffer
);
/* no codepage conversion, DOS device names are ASCII anyway */
for
(
i
=
0
;
i
<
5
;
i
++
)
if
(
!
(
dev
[
i
]
=
(
char
)
tolowerW
(
name
[
i
])))
break
;
dev
[
5
]
=
0
;
return
buffer
;
}
/* read the contents of an NT symlink object */
static
NTSTATUS
read_nt_symlink
(
const
WCHAR
*
name
,
WCHAR
*
target
,
DWORD
size
)
{
...
...
@@ -1128,73 +1106,50 @@ err_ret:
/***********************************************************************
* DefineDosDeviceW (KERNEL32.@)
*/
BOOL
WINAPI
DefineDosDeviceW
(
DWORD
flags
,
LPCWSTR
devname
,
LPCWSTR
targetpath
)
BOOL
WINAPI
DefineDosDeviceW
(
DWORD
flags
,
const
WCHAR
*
device
,
const
WCHAR
*
target
)
{
DWORD
len
,
dosdev
;
BOOL
ret
=
FALSE
;
char
*
path
=
NULL
,
*
target
,
*
p
;
WCHAR
link_name
[
15
]
=
{
'\\'
,
'D'
,
'o'
,
's'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
'\\'
,
0
};
UNICODE_STRING
nt_name
,
nt_target
;
OBJECT_ATTRIBUTES
attr
;
NTSTATUS
status
;
HANDLE
handle
;
TRACE
(
"%
x, %s, %s
\n
"
,
flags
,
debugstr_w
(
devname
),
debugstr_w
(
targetpath
));
TRACE
(
"%
#x, %s, %s
\n
"
,
flags
,
debugstr_w
(
device
),
debugstr_w
(
target
));
if
(
!
(
flags
&
DDD_REMOVE_DEFINITION
))
if
(
flags
&
~
(
DDD_RAW_TARGET_PATH
|
DDD_REMOVE_DEFINITION
))
FIXME
(
"Ignoring flags %#x.
\n
"
,
flags
&
~
(
DDD_RAW_TARGET_PATH
|
DDD_REMOVE_DEFINITION
));
strcatW
(
link_name
,
device
);
RtlInitUnicodeString
(
&
nt_name
,
link_name
);
InitializeObjectAttributes
(
&
attr
,
&
nt_name
,
OBJ_CASE_INSENSITIVE
,
0
,
NULL
);
if
(
flags
&
DDD_REMOVE_DEFINITION
)
{
if
(
!
(
flags
&
DDD_RAW_TARGET_PATH
))
{
FIXME
(
"(0x%08x,%s,%s) DDD_RAW_TARGET_PATH flag not set, not supported yet
\n
"
,
flags
,
debugstr_w
(
devname
),
debugstr_w
(
targetpath
)
);
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
if
(
!
set_ntstatus
(
NtOpenSymbolicLinkObject
(
&
handle
,
0
,
&
attr
)
))
return
FALSE
;
}
len
=
WideCharToMultiByte
(
CP_UNIXCP
,
0
,
targetpath
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
((
target
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
)))
SERVER_START_REQ
(
unlink_object
)
{
WideCharToMultiByte
(
CP_UNIXCP
,
0
,
targetpath
,
-
1
,
target
,
len
,
NULL
,
NULL
);
for
(
p
=
target
;
*
p
;
p
++
)
if
(
*
p
==
'\\'
)
*
p
=
'/'
;
req
->
handle
=
wine_server_obj_handle
(
handle
);
status
=
wine_server_call
(
req
)
;
}
else
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
}
else
target
=
NULL
;
/* first check for a DOS device */
if
((
dosdev
=
RtlIsDosDeviceName_U
(
devname
)))
{
WCHAR
name
[
5
];
SERVER_END_REQ
;
NtClose
(
handle
);
memcpy
(
name
,
devname
+
HIWORD
(
dosdev
)
/
sizeof
(
WCHAR
),
LOWORD
(
dosdev
)
);
name
[
LOWORD
(
dosdev
)
/
sizeof
(
WCHAR
)]
=
0
;
path
=
get_dos_device_path
(
name
);
}
else
if
(
isalphaW
(
devname
[
0
])
&&
devname
[
1
]
==
':'
&&
!
devname
[
2
])
/* drive mapping */
{
path
=
get_dos_device_path
(
devname
);
return
set_ntstatus
(
status
);
}
else
SetLastError
(
ERROR_FILE_NOT_FOUND
);
if
(
path
)
if
(
!
(
flags
&
DDD_RAW_TARGET_PATH
)
)
{
if
(
target
)
if
(
!
RtlDosPathNameToNtPathName_U
(
target
,
&
nt_target
,
NULL
,
NULL
)
)
{
TRACE
(
"creating symlink %s -> %s
\n
"
,
path
,
target
);
unlink
(
path
);
if
(
!
symlink
(
target
,
path
))
ret
=
TRUE
;
else
FILE_SetDosError
();
}
else
{
TRACE
(
"removing symlink %s
\n
"
,
path
);
if
(
!
unlink
(
path
))
ret
=
TRUE
;
else
FILE_SetDosError
();
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
FALSE
;
}
HeapFree
(
GetProcessHeap
(),
0
,
path
);
}
HeapFree
(
GetProcessHeap
(),
0
,
target
);
return
ret
;
else
RtlInitUnicodeString
(
&
nt_target
,
target
);
return
set_ntstatus
(
NtCreateSymbolicLinkObject
(
&
handle
,
SYMBOLIC_LINK_ALL_ACCESS
,
&
attr
,
&
nt_target
)
);
}
...
...
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