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
80444dfe
Commit
80444dfe
authored
Nov 30, 2005
by
Vitaliy Margolen
Committed by
Alexandre Julliard
Nov 30, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement symbolic link object in wineserver.
Implement Nt[Create|Open|Query]SymbolicLinkObject. Change tests accordingly.
parent
ab86f8cd
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
515 additions
and
50 deletions
+515
-50
om.c
dlls/ntdll/om.c
+117
-24
om.c
dlls/ntdll/tests/om.c
+16
-18
server_protocol.h
include/wine/server_protocol.h
+57
-1
Makefile.in
server/Makefile.in
+1
-0
directory.c
server/directory.c
+32
-7
object.h
server/object.h
+6
-0
protocol.def
server/protocol.def
+32
-0
request.h
server/request.h
+6
-0
symlink.c
server/symlink.c
+196
-0
trace.c
server/trace.c
+52
-0
No files found.
dlls/ntdll/om.c
View file @
80444dfe
...
...
@@ -2,6 +2,7 @@
* Object management functions
*
* Copyright 1999, 2000 Juergen Schmied
* Copyright 2005 Vitaliy Margolen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -470,45 +471,137 @@ NTSTATUS WINAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PDIRECTORY
/******************************************************************************
* NtOpenSymbolicLinkObject [NTDLL.@]
* ZwOpenSymbolicLinkObject [NTDLL.@]
*
* Open a namespace symbolic link object.
*
* PARAMS
* LinkHandle [O] Destination for the new symbolic link handle
* DesiredAccess [I] Desired access to the symbolic link
* ObjectAttributes [I] Structure describing the symbolic link
*
* RETURNS
* Success: ERROR_SUCCESS.
* Failure: An NTSTATUS error code.
*/
NTSTATUS
WINAPI
NtOpenSymbolicLinkObject
(
OUT
PHANDLE
LinkHandle
,
IN
ACCESS_MASK
DesiredAccess
,
IN
POBJECT_ATTRIBUTES
ObjectAttributes
)
NTSTATUS
WINAPI
NtOpenSymbolicLinkObject
(
OUT
PHANDLE
LinkHandle
,
IN
ACCESS_MASK
DesiredAccess
,
IN
POBJECT_ATTRIBUTES
ObjectAttributes
)
{
FIXME
(
"(%p,0x%08lx,%p) stub
\n
"
,
LinkHandle
,
DesiredAccess
,
ObjectAttributes
);
dump_ObjectAttributes
(
ObjectAttributes
);
return
STATUS_OBJECT_NAME_NOT_FOUND
;
NTSTATUS
ret
;
TRACE
(
"(%p,0x%08lx,%p)
\n
"
,
LinkHandle
,
DesiredAccess
,
ObjectAttributes
);
dump_ObjectAttributes
(
ObjectAttributes
);
if
(
!
LinkHandle
)
return
STATUS_ACCESS_VIOLATION
;
if
(
!
ObjectAttributes
)
return
STATUS_INVALID_PARAMETER
;
/* Have to test it here because server won't know difference between
* ObjectName == NULL and ObjectName == "" */
if
(
!
ObjectAttributes
->
ObjectName
)
{
if
(
ObjectAttributes
->
RootDirectory
)
return
STATUS_OBJECT_NAME_INVALID
;
else
return
STATUS_OBJECT_PATH_SYNTAX_BAD
;
}
SERVER_START_REQ
(
open_symlink
)
{
req
->
access
=
DesiredAccess
;
req
->
attributes
=
ObjectAttributes
?
ObjectAttributes
->
Attributes
:
0
;
req
->
rootdir
=
ObjectAttributes
?
ObjectAttributes
->
RootDirectory
:
0
;
if
(
ObjectAttributes
->
ObjectName
)
wine_server_add_data
(
req
,
ObjectAttributes
->
ObjectName
->
Buffer
,
ObjectAttributes
->
ObjectName
->
Length
);
ret
=
wine_server_call
(
req
);
*
LinkHandle
=
reply
->
handle
;
}
SERVER_END_REQ
;
return
ret
;
}
/******************************************************************************
* NtCreateSymbolicLinkObject [NTDLL.@]
* ZwCreateSymbolicLinkObject [NTDLL.@]
*
* Open a namespace symbolic link object.
*
* PARAMS
* SymbolicLinkHandle [O] Destination for the new symbolic link handle
* DesiredAccess [I] Desired access to the symbolic link
* ObjectAttributes [I] Structure describing the symbolic link
* TargetName [I] Name of the target symbolic link points to
*
* RETURNS
* Success: ERROR_SUCCESS.
* Failure: An NTSTATUS error code.
*/
NTSTATUS
WINAPI
NtCreateSymbolicLinkObject
(
OUT
PHANDLE
SymbolicLinkHandle
,
IN
ACCESS_MASK
DesiredAccess
,
IN
POBJECT_ATTRIBUTES
ObjectAttributes
,
IN
PUNICODE_STRING
Name
)
NTSTATUS
WINAPI
NtCreateSymbolicLinkObject
(
OUT
PHANDLE
SymbolicLinkHandle
,
IN
ACCESS_MASK
DesiredAccess
,
IN
POBJECT_ATTRIBUTES
ObjectAttributes
,
IN
PUNICODE_STRING
TargetName
)
{
FIXME
(
"(%p,0x%08lx,%p, %p) stub
\n
"
,
SymbolicLinkHandle
,
DesiredAccess
,
ObjectAttributes
,
debugstr_us
(
Name
));
dump_ObjectAttributes
(
ObjectAttributes
);
return
0
;
NTSTATUS
ret
;
TRACE
(
"(%p,0x%08lx,%p, -> %s)
\n
"
,
SymbolicLinkHandle
,
DesiredAccess
,
ObjectAttributes
,
debugstr_us
(
TargetName
));
dump_ObjectAttributes
(
ObjectAttributes
);
if
(
!
SymbolicLinkHandle
||
!
TargetName
)
return
STATUS_ACCESS_VIOLATION
;
if
(
!
TargetName
->
Buffer
)
return
STATUS_INVALID_PARAMETER
;
SERVER_START_REQ
(
create_symlink
)
{
req
->
access
=
DesiredAccess
;
req
->
attributes
=
ObjectAttributes
?
ObjectAttributes
->
Attributes
:
0
;
req
->
rootdir
=
ObjectAttributes
?
ObjectAttributes
->
RootDirectory
:
0
;
if
(
ObjectAttributes
->
ObjectName
)
{
req
->
name_len
=
ObjectAttributes
->
ObjectName
->
Length
;
wine_server_add_data
(
req
,
ObjectAttributes
->
ObjectName
->
Buffer
,
ObjectAttributes
->
ObjectName
->
Length
);
}
else
req
->
name_len
=
0
;
wine_server_add_data
(
req
,
TargetName
->
Buffer
,
TargetName
->
Length
);
ret
=
wine_server_call
(
req
);
*
SymbolicLinkHandle
=
reply
->
handle
;
}
SERVER_END_REQ
;
return
ret
;
}
/******************************************************************************
* NtQuerySymbolicLinkObject [NTDLL.@]
* ZwQuerySymbolicLinkObject [NTDLL.@]
*
* Query a namespace symbolic link object target name.
*
* PARAMS
* LinkHandle [I] Handle to a symbolic link object
* LinkTarget [O] Destination for the symbolic link target
* ReturnedLength [O] Size of returned data
*
* RETURNS
* Success: ERROR_SUCCESS.
* Failure: An NTSTATUS error code.
*/
NTSTATUS
WINAPI
NtQuerySymbolicLinkObject
(
IN
HANDLE
LinkHandle
,
IN
OUT
PUNICODE_STRING
LinkTarget
,
OUT
PULONG
ReturnedLength
OPTIONAL
)
NTSTATUS
WINAPI
NtQuerySymbolicLinkObject
(
IN
HANDLE
LinkHandle
,
IN
OUT
PUNICODE_STRING
LinkTarget
,
OUT
PULONG
ReturnedLength
OPTIONAL
)
{
FIXME
(
"(%p,%p,%p) stub
\n
"
,
LinkHandle
,
debugstr_us
(
LinkTarget
)
,
ReturnedLength
);
NTSTATUS
ret
;
TRACE
(
"(%p,%p,%p)
\n
"
,
LinkHandle
,
LinkTarget
,
ReturnedLength
);
return
0
;
if
(
!
LinkTarget
)
return
STATUS_ACCESS_VIOLATION
;
SERVER_START_REQ
(
query_symlink
)
{
req
->
handle
=
LinkHandle
;
wine_server_set_reply
(
req
,
LinkTarget
->
Buffer
,
LinkTarget
->
MaximumLength
);
if
(
!
(
ret
=
wine_server_call
(
req
)))
{
LinkTarget
->
Length
=
wine_server_reply_size
(
reply
);
if
(
ReturnedLength
)
*
ReturnedLength
=
LinkTarget
->
Length
;
}
}
SERVER_END_REQ
;
return
ret
;
}
/******************************************************************************
...
...
dlls/ntdll/tests/om.c
View file @
80444dfe
...
...
@@ -185,9 +185,7 @@ static void test_name_collisions(void)
InitializeObjectAttributes
(
&
attr
,
&
str
,
0
,
0
,
NULL
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"
\\
"
);
h
=
0
;
DIR_TEST_CREATE_FAILURE
(
&
h
,
STATUS_OBJECT_NAME_COLLISION
)
ok
(
h
==
0
,
"Failed create returned valid handle! (%p)
\n
"
,
h
);
InitializeObjectAttributes
(
&
attr
,
&
str
,
OBJ_OPENIF
,
0
,
NULL
);
DIR_TEST_CREATE_FAILURE
(
&
h
,
STATUS_OBJECT_NAME_EXISTS
)
...
...
@@ -336,11 +334,11 @@ void test_directory(void)
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"
\\
BaseNamedObjects
\\
Local"
);
InitializeObjectAttributes
(
&
attr
,
&
str
,
0
,
0
,
NULL
);
status
=
pNtOpenSymbolicLinkObject
(
&
dir
,
SYMBOLIC_LINK_QUERY
,
&
attr
);
\
todo_wine
ok
(
status
==
STATUS_SUCCESS
,
"Failed to open SymbolicLink(%08lx)
\n
"
,
status
);
ok
(
status
==
STATUS_SUCCESS
,
"Failed to open SymbolicLink(%08lx)
\n
"
,
status
);
pRtlFreeUnicodeString
(
&
str
);
InitializeObjectAttributes
(
&
attr
,
&
str
,
0
,
dir
,
NULL
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"one more level"
);
todo_wine
{
DIR_TEST_CREATE_FAILURE
(
&
h
,
STATUS_OBJECT_TYPE_MISMATCH
)
}
DIR_TEST_CREATE_FAILURE
(
&
h
,
STATUS_OBJECT_TYPE_MISMATCH
)
pRtlFreeUnicodeString
(
&
str
);
pNtClose
(
h
);
pNtClose
(
dir
);
...
...
@@ -396,15 +394,15 @@ void test_directory(void)
InitializeObjectAttributes
(
&
attr
,
&
str
,
0
,
0
,
NULL
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"
\\
BaseNamedObjects
\\
Global
\\
om.c-test"
);
todo_wine
{
DIR_TEST_CREATE_SUCCESS
(
&
dir
)
}
DIR_TEST_CREATE_SUCCESS
(
&
dir
)
pRtlFreeUnicodeString
(
&
str
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"
\\
BaseNamedObjects
\\
Local
\\
om.c-test
\\
one more level"
);
todo_wine
{
DIR_TEST_CREATE_SUCCESS
(
&
h
)
}
DIR_TEST_CREATE_SUCCESS
(
&
h
)
pRtlFreeUnicodeString
(
&
str
);
pNtClose
(
h
);
InitializeObjectAttributes
(
&
attr
,
&
str
,
0
,
dir
,
NULL
);
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
"one more level"
);
todo_wine
{
DIR_TEST_CREATE_SUCCESS
(
&
dir
)
}
DIR_TEST_CREATE_SUCCESS
(
&
dir
)
pRtlFreeUnicodeString
(
&
str
);
pNtClose
(
h
);
...
...
@@ -476,18 +474,18 @@ void test_symboliclink(void)
IO_STATUS_BLOCK
iosb
;
/* No name and/or no attributes */
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
NULL
,
""
,
""
,
STATUS_ACCESS_VIOLATION
)
}
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
NULL
,
""
,
""
,
STATUS_ACCESS_VIOLATION
)
status
=
pNtCreateSymbolicLinkObject
(
&
h
,
SYMBOLIC_LINK_QUERY
,
NULL
,
NULL
);
todo_wine
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
"NtCreateSymbolicLinkObject should have failed with STATUS_ACCESS_VIOLATION got(%08lx)
\n
"
,
status
);
status
=
pNtOpenSymbolicLinkObject
(
&
h
,
SYMBOLIC_LINK_QUERY
,
NULL
);
todo_wine
ok
(
status
==
STATUS_INVALID_PARAMETER
,
ok
(
status
==
STATUS_INVALID_PARAMETER
,
"NtOpenSymbolicLinkObject should have failed with STATUS_INVALID_PARAMETER got(%08lx)
\n
"
,
status
);
InitializeObjectAttributes
(
&
attr
,
NULL
,
0
,
0
,
NULL
);
todo_wine
{
SYMLNK_TEST_CREATE_FAILURE
(
&
link
,
STATUS_INVALID_PARAMETER
)
}
todo_wine
{
SYMLNK_TEST_OPEN_FAILURE
(
&
h
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
}
SYMLNK_TEST_CREATE_FAILURE
(
&
link
,
STATUS_INVALID_PARAMETER
)
SYMLNK_TEST_OPEN_FAILURE
(
&
h
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
/* Bad name */
pRtlCreateUnicodeStringFromAsciiz
(
&
target
,
"anywhere"
);
...
...
@@ -495,7 +493,7 @@ void test_symboliclink(void)
pRtlCreateUnicodeStringFromAsciiz
(
&
str
,
""
);
SYMLNK_TEST_CREATE_SUCCESS
(
&
link
)
todo_wine
{
SYMLNK_TEST_OPEN_FAILURE
(
&
h
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
}
SYMLNK_TEST_OPEN_FAILURE
(
&
h
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
pNtClose
(
link
);
pRtlFreeUnicodeString
(
&
str
);
...
...
@@ -504,11 +502,11 @@ void test_symboliclink(void)
pRtlFreeUnicodeString
(
&
str
);
pRtlFreeUnicodeString
(
&
target
);
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"BaseNamedObjects"
,
"->Somewhere"
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
}
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\
"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
}
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\\\
BaseNamedObjects"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
}
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\\\
om.c-test"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
}
todo_wine
{
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\
om.c-test
\\
"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
}
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"BaseNamedObjects"
,
"->Somewhere"
,
STATUS_OBJECT_PATH_SYNTAX_BAD
)
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\
"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\\\
BaseNamedObjects"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\\\
om.c-test"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
SYMLNK_TEST_CREATE_OPEN_FAILURE
(
&
h
,
"
\\
BaseNamedObjects
\\
om.c-test
\\
"
,
"->Somewhere"
,
STATUS_OBJECT_NAME_INVALID
)
/* Compaund test */
...
...
include/wine/server_protocol.h
View file @
80444dfe
...
...
@@ -3609,6 +3609,53 @@ struct open_directory_reply
};
struct
create_symlink_request
{
struct
request_header
__header
;
unsigned
int
access
;
unsigned
int
attributes
;
obj_handle_t
rootdir
;
size_t
name_len
;
/* VARARG(name,unicode_str,name_len); */
/* VARARG(target_name,unicode_str); */
};
struct
create_symlink_reply
{
struct
reply_header
__header
;
obj_handle_t
handle
;
};
struct
open_symlink_request
{
struct
request_header
__header
;
unsigned
int
access
;
unsigned
int
attributes
;
obj_handle_t
rootdir
;
/* VARARG(name,unicode_str); */
};
struct
open_symlink_reply
{
struct
reply_header
__header
;
obj_handle_t
handle
;
};
struct
query_symlink_request
{
struct
request_header
__header
;
obj_handle_t
handle
;
};
struct
query_symlink_reply
{
struct
reply_header
__header
;
/* VARARG(target_name,unicode_str); */
};
enum
request
{
REQ_new_process
,
...
...
@@ -3818,6 +3865,9 @@ enum request
REQ_set_mailslot_info
,
REQ_create_directory
,
REQ_open_directory
,
REQ_create_symlink
,
REQ_open_symlink
,
REQ_query_symlink
,
REQ_NB_REQUESTS
};
...
...
@@ -4032,6 +4082,9 @@ union generic_request
struct
set_mailslot_info_request
set_mailslot_info_request
;
struct
create_directory_request
create_directory_request
;
struct
open_directory_request
open_directory_request
;
struct
create_symlink_request
create_symlink_request
;
struct
open_symlink_request
open_symlink_request
;
struct
query_symlink_request
query_symlink_request
;
};
union
generic_reply
{
...
...
@@ -4244,8 +4297,11 @@ union generic_reply
struct
set_mailslot_info_reply
set_mailslot_info_reply
;
struct
create_directory_reply
create_directory_reply
;
struct
open_directory_reply
open_directory_reply
;
struct
create_symlink_reply
create_symlink_reply
;
struct
open_symlink_reply
open_symlink_reply
;
struct
query_symlink_reply
query_symlink_reply
;
};
#define SERVER_PROTOCOL_VERSION 20
0
#define SERVER_PROTOCOL_VERSION 20
1
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/Makefile.in
View file @
80444dfe
...
...
@@ -40,6 +40,7 @@ C_SRCS = \
signal.c
\
snapshot.c
\
sock.c
\
symlink.c
\
thread.c
\
timer.c
\
token.c
\
...
...
server/directory.c
View file @
80444dfe
...
...
@@ -285,34 +285,59 @@ obj_handle_t open_object_dir( struct directory *root, const struct unicode_str *
/* Global initialization */
static
struct
directory
*
dir_global
,
*
dir_driver
,
*
dir_device
,
*
dir_basenamed
;
static
struct
directory
*
dir_driver
,
*
dir_device
;
static
struct
symlink
*
link_dosdev
,
*
link_global1
,
*
link_global2
,
*
link_local
;
void
init_directories
(
void
)
{
/* Directories */
static
const
WCHAR
dir_globalW
[]
=
{
'?'
,
'?'
};
static
const
WCHAR
dir_globalW
[]
=
{
'
\\'
,
'
?'
,
'?'
};
static
const
WCHAR
dir_driverW
[]
=
{
'D'
,
'r'
,
'i'
,
'v'
,
'e'
,
'r'
};
static
const
WCHAR
dir_deviceW
[]
=
{
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
};
static
const
WCHAR
dir_basenamedW
[]
=
{
'B'
,
'a'
,
's'
,
'e'
,
'N'
,
'a'
,
'm'
,
'e'
,
'd'
,
'O'
,
'b'
,
'j'
,
'e'
,
'c'
,
't'
,
's'
};
static
const
WCHAR
dir_basenamedW
[]
=
{
'
\\'
,
'
B'
,
'a'
,
's'
,
'e'
,
'N'
,
'a'
,
'm'
,
'e'
,
'd'
,
'O'
,
'b'
,
'j'
,
'e'
,
'c'
,
't'
,
's'
};
static
const
struct
unicode_str
dir_global_str
=
{
dir_globalW
,
sizeof
(
dir_globalW
)};
static
const
struct
unicode_str
dir_driver_str
=
{
dir_driverW
,
sizeof
(
dir_driverW
)};
static
const
struct
unicode_str
dir_device_str
=
{
dir_deviceW
,
sizeof
(
dir_deviceW
)};
static
const
struct
unicode_str
dir_basenamed_str
=
{
dir_basenamedW
,
sizeof
(
dir_basenamedW
)};
/* symlinks */
static
const
WCHAR
link_dosdevW
[]
=
{
'D'
,
'o'
,
's'
,
'D'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
};
static
const
WCHAR
link_globalW
[]
=
{
'G'
,
'l'
,
'o'
,
'b'
,
'a'
,
'l'
};
static
const
WCHAR
link_localW
[]
=
{
'L'
,
'o'
,
'c'
,
'a'
,
'l'
};
static
const
struct
unicode_str
link_dosdev_str
=
{
link_dosdevW
,
sizeof
(
link_dosdevW
)};
static
const
struct
unicode_str
link_global_str
=
{
link_globalW
,
sizeof
(
link_globalW
)};
static
const
struct
unicode_str
link_local_str
=
{
link_localW
,
sizeof
(
link_localW
)};
struct
directory
*
dir_global
,
*
dir_basenamed
;
root_directory
=
create_directory
(
NULL
,
NULL
,
0
,
HASH_SIZE
);
dir_global
=
create_directory
(
root_directory
,
&
dir_global_str
,
0
,
HASH_SIZE
);
dir_driver
=
create_directory
(
root_directory
,
&
dir_driver_str
,
0
,
HASH_SIZE
);
dir_device
=
create_directory
(
root_directory
,
&
dir_device_str
,
0
,
HASH_SIZE
);
dir_global
=
create_directory
(
NULL
,
&
dir_global_str
,
0
,
HASH_SIZE
);
/* use a larger hash table for this one since it can contain a lot of objects */
dir_basenamed
=
create_directory
(
root_directory
,
&
dir_basenamed_str
,
0
,
37
);
dir_basenamed
=
create_directory
(
NULL
,
&
dir_basenamed_str
,
0
,
37
);
/* symlinks */
link_dosdev
=
create_symlink
(
root_directory
,
&
link_dosdev_str
,
0
,
&
dir_global_str
);
link_global1
=
create_symlink
(
dir_global
,
&
link_global_str
,
0
,
&
dir_global_str
);
link_global2
=
create_symlink
(
dir_basenamed
,
&
link_global_str
,
0
,
&
dir_basenamed_str
);
link_local
=
create_symlink
(
dir_basenamed
,
&
link_local_str
,
0
,
&
dir_basenamed_str
);
/* the symlinks hold references so we can release these */
release_object
(
dir_global
);
release_object
(
dir_basenamed
);
}
void
close_directories
(
void
)
{
release_object
(
dir_global
);
release_object
(
link_dosdev
);
release_object
(
link_global1
);
release_object
(
link_global2
);
release_object
(
link_local
);
release_object
(
dir_driver
);
release_object
(
dir_device
);
release_object
(
dir_basenamed
);
release_object
(
root_directory
);
}
...
...
server/object.h
View file @
80444dfe
...
...
@@ -193,6 +193,12 @@ extern obj_handle_t open_object_dir( struct directory *root, const struct unicod
extern
void
init_directories
(
void
);
extern
void
close_directories
(
void
);
/* symbolic link functions */
extern
struct
symlink
*
create_symlink
(
struct
directory
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
const
struct
unicode_str
*
target
);
/* global variables */
/* command-line options */
...
...
server/protocol.def
View file @
80444dfe
...
...
@@ -2527,3 +2527,35 @@ enum message_type
@REPLY
obj_handle_t handle; /* handle to the directory */
@END
/* Create a symbolic link object */
@REQ(create_symlink)
unsigned int access; /* access flags */
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
size_t name_len; /* length of the symlink name in bytes */
VARARG(name,unicode_str,name_len); /* symlink name */
VARARG(target_name,unicode_str); /* target name */
@REPLY
obj_handle_t handle; /* handle to the symlink */
@END
/* Open a symbolic link object */
@REQ(open_symlink)
unsigned int access; /* access flags */
unsigned int attributes; /* object attributes */
obj_handle_t rootdir; /* root directory */
VARARG(name,unicode_str); /* symlink name */
@REPLY
obj_handle_t handle; /* handle to the symlink */
@END
/* Query a symbolic link object */
@REQ(query_symlink)
obj_handle_t handle; /* handle to the symlink */
@REPLY
VARARG(target_name,unicode_str); /* target name */
@END
server/request.h
View file @
80444dfe
...
...
@@ -317,6 +317,9 @@ DECL_HANDLER(open_mailslot);
DECL_HANDLER
(
set_mailslot_info
);
DECL_HANDLER
(
create_directory
);
DECL_HANDLER
(
open_directory
);
DECL_HANDLER
(
create_symlink
);
DECL_HANDLER
(
open_symlink
);
DECL_HANDLER
(
query_symlink
);
#ifdef WANT_REQUEST_HANDLERS
...
...
@@ -530,6 +533,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_set_mailslot_info
,
(
req_handler
)
req_create_directory
,
(
req_handler
)
req_open_directory
,
(
req_handler
)
req_create_symlink
,
(
req_handler
)
req_open_symlink
,
(
req_handler
)
req_query_symlink
,
};
#endif
/* WANT_REQUEST_HANDLERS */
...
...
server/symlink.c
0 → 100644
View file @
80444dfe
/*
* Server-side symbolic link object management
*
* Copyright (C) 2005 Vitaliy Margolen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "winternl.h"
#include "ddk/wdm.h"
#include "handle.h"
#include "request.h"
#include "object.h"
#include "unicode.h"
struct
symlink
{
struct
object
obj
;
/* object header */
WCHAR
*
target
;
/* target of the symlink */
size_t
len
;
/* target len in bytes */
};
static
void
symlink_dump
(
struct
object
*
obj
,
int
verbose
);
static
struct
object
*
symlink_lookup_name
(
struct
object
*
obj
,
struct
unicode_str
*
name
,
unsigned
int
attr
);
static
void
symlink_destroy
(
struct
object
*
obj
);
static
const
struct
object_ops
symlink_ops
=
{
sizeof
(
struct
symlink
),
/* size */
symlink_dump
,
/* dump */
no_add_queue
,
/* add_queue */
NULL
,
/* remove_queue */
NULL
,
/* signaled */
NULL
,
/* satisfied */
no_signal
,
/* signal */
no_get_fd
,
/* get_fd */
symlink_lookup_name
,
/* lookup_name */
no_close_handle
,
/* close_handle */
symlink_destroy
/* destroy */
};
static
void
symlink_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
symlink
*
symlink
=
(
struct
symlink
*
)
obj
;
assert
(
obj
->
ops
==
&
symlink_ops
);
fprintf
(
stderr
,
"Symlink "
);
dump_object_name
(
obj
);
fprintf
(
stderr
,
" -> L
\"
"
);
dump_strW
(
symlink
->
target
,
symlink
->
len
/
sizeof
(
WCHAR
),
stderr
,
"
\"\"
"
);
fprintf
(
stderr
,
"
\"\n
"
);
}
static
struct
object
*
symlink_lookup_name
(
struct
object
*
obj
,
struct
unicode_str
*
name
,
unsigned
int
attr
)
{
struct
symlink
*
symlink
=
(
struct
symlink
*
)
obj
;
struct
unicode_str
target_str
,
name_left
;
struct
object
*
target
;
assert
(
obj
->
ops
==
&
symlink_ops
);
if
(
attr
&
OBJ_OPENLINK
)
return
NULL
;
target_str
.
str
=
symlink
->
target
;
target_str
.
len
=
symlink
->
len
;
if
((
target
=
find_object_dir
(
NULL
,
&
target_str
,
attr
,
&
name_left
)))
{
if
(
name_left
.
len
)
{
release_object
(
target
);
target
=
NULL
;
set_error
(
STATUS_OBJECT_PATH_NOT_FOUND
);
}
}
return
target
;
}
static
void
symlink_destroy
(
struct
object
*
obj
)
{
struct
symlink
*
symlink
=
(
struct
symlink
*
)
obj
;
assert
(
obj
->
ops
==
&
symlink_ops
);
free
(
symlink
->
target
);
}
struct
symlink
*
create_symlink
(
struct
directory
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
const
struct
unicode_str
*
target
)
{
struct
symlink
*
symlink
;
if
(
!
target
->
len
)
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
NULL
;
}
if
((
symlink
=
create_named_object_dir
(
root
,
name
,
attr
,
&
symlink_ops
))
&&
(
get_error
()
!=
STATUS_OBJECT_NAME_EXISTS
))
{
if
((
symlink
->
target
=
memdup
(
target
->
str
,
target
->
len
)))
symlink
->
len
=
target
->
len
;
else
{
release_object
(
symlink
);
symlink
=
NULL
;
}
}
return
symlink
;
}
/* create a symbolic link object */
DECL_HANDLER
(
create_symlink
)
{
struct
symlink
*
symlink
;
struct
unicode_str
name
,
target
;
struct
directory
*
root
=
NULL
;
if
(
req
->
name_len
>
get_req_data_size
())
{
set_error
(
STATUS_INVALID_PARAMETER
);
return
;
}
name
.
str
=
get_req_data
();
target
.
str
=
name
.
str
+
req
->
name_len
/
sizeof
(
WCHAR
);
name
.
len
=
(
target
.
str
-
name
.
str
)
*
sizeof
(
WCHAR
);
target
.
len
=
((
get_req_data_size
()
-
name
.
len
)
/
sizeof
(
WCHAR
))
*
sizeof
(
WCHAR
);
if
(
req
->
rootdir
&&
!
(
root
=
get_directory_obj
(
current
->
process
,
req
->
rootdir
,
0
)))
return
;
if
((
symlink
=
create_symlink
(
root
,
&
name
,
req
->
attributes
,
&
target
)))
{
reply
->
handle
=
alloc_handle
(
current
->
process
,
symlink
,
req
->
access
,
req
->
attributes
&
OBJ_INHERIT
);
release_object
(
symlink
);
}
if
(
root
)
release_object
(
root
);
}
/* open a symbolic link object */
DECL_HANDLER
(
open_symlink
)
{
struct
unicode_str
name
;
struct
directory
*
root
=
NULL
;
get_req_unicode_str
(
&
name
);
if
(
req
->
rootdir
&&
!
(
root
=
get_directory_obj
(
current
->
process
,
req
->
rootdir
,
0
)))
return
;
reply
->
handle
=
open_object_dir
(
root
,
&
name
,
req
->
attributes
|
OBJ_OPENLINK
,
&
symlink_ops
,
req
->
access
);
if
(
root
)
release_object
(
root
);
}
/* query a symbolic link object */
DECL_HANDLER
(
query_symlink
)
{
struct
symlink
*
symlink
;
symlink
=
(
struct
symlink
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
SYMBOLIC_LINK_QUERY
,
&
symlink_ops
);
if
(
!
symlink
)
return
;
if
(
get_reply_max_size
()
<
symlink
->
len
)
set_error
(
STATUS_BUFFER_TOO_SMALL
);
else
set_reply_data
(
symlink
->
target
,
symlink
->
len
);
release_object
(
symlink
);
}
server/trace.c
View file @
80444dfe
...
...
@@ -3121,6 +3121,49 @@ static void dump_open_directory_reply( const struct open_directory_reply *req )
fprintf
(
stderr
,
" handle=%p"
,
req
->
handle
);
}
static
void
dump_create_symlink_request
(
const
struct
create_symlink_request
*
req
)
{
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
fprintf
(
stderr
,
" attributes=%08x,"
,
req
->
attributes
);
fprintf
(
stderr
,
" rootdir=%p,"
,
req
->
rootdir
);
fprintf
(
stderr
,
" name_len=%d,"
,
req
->
name_len
);
fprintf
(
stderr
,
" name="
);
dump_varargs_unicode_str
(
min
(
cur_size
,
req
->
name_len
)
);
fputc
(
','
,
stderr
);
fprintf
(
stderr
,
" target_name="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
void
dump_create_symlink_reply
(
const
struct
create_symlink_reply
*
req
)
{
fprintf
(
stderr
,
" handle=%p"
,
req
->
handle
);
}
static
void
dump_open_symlink_request
(
const
struct
open_symlink_request
*
req
)
{
fprintf
(
stderr
,
" access=%08x,"
,
req
->
access
);
fprintf
(
stderr
,
" attributes=%08x,"
,
req
->
attributes
);
fprintf
(
stderr
,
" rootdir=%p,"
,
req
->
rootdir
);
fprintf
(
stderr
,
" name="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
void
dump_open_symlink_reply
(
const
struct
open_symlink_reply
*
req
)
{
fprintf
(
stderr
,
" handle=%p"
,
req
->
handle
);
}
static
void
dump_query_symlink_request
(
const
struct
query_symlink_request
*
req
)
{
fprintf
(
stderr
,
" handle=%p"
,
req
->
handle
);
}
static
void
dump_query_symlink_reply
(
const
struct
query_symlink_reply
*
req
)
{
fprintf
(
stderr
,
" target_name="
);
dump_varargs_unicode_str
(
cur_size
);
}
static
const
dump_func
req_dumpers
[
REQ_NB_REQUESTS
]
=
{
(
dump_func
)
dump_new_process_request
,
(
dump_func
)
dump_get_new_process_info_request
,
...
...
@@ -3329,6 +3372,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_set_mailslot_info_request
,
(
dump_func
)
dump_create_directory_request
,
(
dump_func
)
dump_open_directory_request
,
(
dump_func
)
dump_create_symlink_request
,
(
dump_func
)
dump_open_symlink_request
,
(
dump_func
)
dump_query_symlink_request
,
};
static
const
dump_func
reply_dumpers
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -3539,6 +3585,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_set_mailslot_info_reply
,
(
dump_func
)
dump_create_directory_reply
,
(
dump_func
)
dump_open_directory_reply
,
(
dump_func
)
dump_create_symlink_reply
,
(
dump_func
)
dump_open_symlink_reply
,
(
dump_func
)
dump_query_symlink_reply
,
};
static
const
char
*
const
req_names
[
REQ_NB_REQUESTS
]
=
{
...
...
@@ -3749,6 +3798,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"set_mailslot_info"
,
"create_directory"
,
"open_directory"
,
"create_symlink"
,
"open_symlink"
,
"query_symlink"
,
};
static
const
struct
...
...
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