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
fca258ef
Commit
fca258ef
authored
Nov 27, 2022
by
Piotr Caban
Committed by
Alexandre Julliard
Nov 29, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
localspl: Add pipe port extension.
parent
aa4e9c39
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
313 additions
and
8 deletions
+313
-8
Makefile.in
dlls/localspl/Makefile.in
+2
-0
cups.c
dlls/localspl/cups.c
+227
-0
localmon.c
dlls/localspl/localmon.c
+51
-8
localspl_private.h
dlls/localspl/localspl_private.h
+29
-0
provider.c
dlls/localspl/provider.c
+4
-0
No files found.
dlls/localspl/Makefile.in
View file @
fca258ef
MODULE
=
localspl.dll
UNIXLIB
=
localspl.so
IMPORTS
=
spoolss user32 advapi32
EXTRADLLFLAGS
=
-Wb
,--prefer-native
C_SRCS
=
\
cups.c
\
localmon.c
\
provider.c
...
...
dlls/localspl/cups.c
0 → 100644
View file @
fca258ef
/*
* CUPS functions
*
* Copyright 2021 Huw Davies
* Copyright 2022 Piotr Caban
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep unix
#endif
#include "config.h"
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "wine/debug.h"
#include "localspl_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
localspl
);
typedef
struct
_doc_t
{
BOOL
(
*
write_doc
)(
struct
_doc_t
*
,
const
BYTE
*
buf
,
unsigned
int
size
);
BOOL
(
*
end_doc
)(
struct
_doc_t
*
);
union
{
struct
{
pid_t
pid
;
int
fd
;
}
pipe
;
};
}
doc_t
;
static
BOOL
pipe_write_doc
(
doc_t
*
doc
,
const
BYTE
*
buf
,
unsigned
int
size
)
{
return
write
(
doc
->
pipe
.
fd
,
buf
,
size
)
==
size
;
}
static
BOOL
pipe_end_doc
(
doc_t
*
doc
)
{
pid_t
wret
;
int
status
;
close
(
doc
->
pipe
.
fd
);
do
{
wret
=
waitpid
(
doc
->
pipe
.
pid
,
&
status
,
0
);
}
while
(
wret
<
0
&&
errno
==
EINTR
);
if
(
wret
<
0
)
{
ERR
(
"waitpid() failed!
\n
"
);
return
FALSE
;
}
if
(
!
WIFEXITED
(
status
)
||
WEXITSTATUS
(
status
))
{
ERR
(
"child process failed! %d
\n
"
,
status
);
return
FALSE
;
}
return
TRUE
;
}
static
BOOL
pipe_start_doc
(
doc_t
*
doc
,
const
WCHAR
*
cmd
)
{
char
*
cmdA
;
int
fds
[
2
];
DWORD
len
;
doc
->
write_doc
=
pipe_write_doc
;
doc
->
end_doc
=
pipe_end_doc
;
len
=
wcslen
(
cmd
);
cmdA
=
malloc
(
len
*
3
+
1
);
ntdll_wcstoumbs
(
cmd
,
len
+
1
,
cmdA
,
len
*
3
+
1
,
FALSE
);
TRACE
(
"printing with: %s
\n
"
,
cmdA
);
if
(
pipe
(
fds
))
{
ERR
(
"pipe() failed!
\n
"
);
free
(
cmdA
);
return
FALSE
;
}
if
((
doc
->
pipe
.
pid
=
fork
())
==
0
)
{
close
(
0
);
dup2
(
fds
[
0
],
0
);
close
(
fds
[
1
]);
/* reset signals that we previously set to SIG_IGN */
signal
(
SIGPIPE
,
SIG_DFL
);
execl
(
"/bin/sh"
,
"/bin/sh"
,
"-c"
,
cmdA
,
NULL
);
_exit
(
1
);
}
close
(
fds
[
0
]);
free
(
cmdA
);
if
(
doc
->
pipe
.
pid
==
-
1
)
{
ERR
(
"fork() failed!
\n
"
);
close
(
fds
[
1
]);
return
FALSE
;
}
doc
->
pipe
.
fd
=
fds
[
1
];
return
TRUE
;
}
static
NTSTATUS
start_doc
(
void
*
args
)
{
const
struct
start_doc_params
*
params
=
args
;
doc_t
*
doc
=
malloc
(
sizeof
(
*
doc
));
BOOL
ret
=
FALSE
;
if
(
!
doc
)
return
STATUS_NO_MEMORY
;
if
(
params
->
type
==
PORT_IS_PIPE
)
ret
=
pipe_start_doc
(
doc
,
params
->
port
+
1
/* strlen("|") */
);
if
(
ret
)
*
params
->
doc
=
(
size_t
)
doc
;
else
free
(
doc
);
return
ret
;
}
static
NTSTATUS
write_doc
(
void
*
args
)
{
const
struct
write_doc_params
*
params
=
args
;
doc_t
*
doc
=
(
doc_t
*
)(
size_t
)
params
->
doc
;
return
doc
->
write_doc
(
doc
,
params
->
buf
,
params
->
size
);
}
static
NTSTATUS
end_doc
(
void
*
args
)
{
const
struct
end_doc_params
*
params
=
args
;
doc_t
*
doc
=
(
doc_t
*
)(
size_t
)
params
->
doc
;
NTSTATUS
ret
;
ret
=
doc
->
end_doc
(
doc
);
free
(
doc
);
return
ret
;
}
const
unixlib_entry_t
__wine_unix_call_funcs
[]
=
{
start_doc
,
write_doc
,
end_doc
,
};
#ifdef _WIN64
typedef
ULONG
PTR32
;
static
NTSTATUS
wow64_start_doc
(
void
*
args
)
{
struct
{
unsigned
int
type
;
const
PTR32
port
;
INT64
*
doc
;
}
const
*
params32
=
args
;
struct
start_doc_params
params
=
{
params32
->
type
,
ULongToPtr
(
params32
->
port
),
params32
->
doc
,
};
return
start_doc
(
&
params
);
}
static
NTSTATUS
wow64_write_doc
(
void
*
args
)
{
struct
{
INT64
doc
;
const
PTR32
buf
;
unsigned
int
size
;
}
const
*
params32
=
args
;
struct
write_doc_params
params
=
{
params32
->
doc
,
ULongToPtr
(
params32
->
buf
),
params32
->
size
,
};
return
write_doc
(
&
params
);
}
const
unixlib_entry_t
__wine_unix_call_wow64_funcs
[]
=
{
wow64_start_doc
,
wow64_write_doc
,
end_doc
,
};
#endif
/* _WIN64 */
dlls/localspl/localmon.c
View file @
fca258ef
...
...
@@ -66,6 +66,7 @@ typedef struct {
struct
list
entry
;
DWORD
type
;
HANDLE
hfile
;
INT64
doc_handle
;
WCHAR
nameW
[
1
];
}
port_t
;
...
...
@@ -95,7 +96,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
case
DLL_PROCESS_ATTACH
:
DisableThreadLibraryCalls
(
hinstDLL
);
localspl_instance
=
hinstDLL
;
break
;
return
!
__wine_init_unix_call
()
;
}
return
TRUE
;
}
...
...
@@ -249,7 +250,7 @@ getports_cleanup:
*
*/
static
DWORD
get_type_from_name
(
LPCWSTR
name
)
static
DWORD
get_type_from_name
(
LPCWSTR
name
,
BOOL
check_filename
)
{
HANDLE
hfile
;
...
...
@@ -274,6 +275,9 @@ static DWORD get_type_from_name(LPCWSTR name)
if
(
!
wcsncmp
(
name
,
L"LPR:"
,
ARRAY_SIZE
(
L"LPR:"
)
-
1
))
return
PORT_IS_LPR
;
if
(
!
check_filename
)
return
PORT_IS_UNKNOWN
;
/* Must be a file or a directory. Does the file exist ? */
hfile
=
CreateFileW
(
name
,
GENERIC_WRITE
,
0
,
NULL
,
OPEN_EXISTING
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
TRACE
(
"%p for OPEN_EXISTING on %s
\n
"
,
hfile
,
debugstr_w
(
name
));
...
...
@@ -301,9 +305,12 @@ static DWORD get_type_from_local_name(LPCWSTR nameW)
LPWSTR
myname
=
NULL
;
DWORD
needed
=
0
;
DWORD
numentries
=
0
;
DWORD
id
=
0
;
DWORD
id
;
TRACE
(
"(%s)
\n
"
,
debugstr_w
(
myname
));
TRACE
(
"(%s)
\n
"
,
debugstr_w
(
nameW
));
if
((
id
=
get_type_from_name
(
nameW
,
FALSE
))
>=
PORT_IS_WINE
)
return
id
;
needed
=
get_ports_from_reg
(
1
,
NULL
,
0
,
&
numentries
);
pi
=
malloc
(
needed
);
...
...
@@ -313,17 +320,17 @@ static DWORD get_type_from_local_name(LPCWSTR nameW)
if
(
pi
&&
needed
&&
numentries
>
0
)
{
/* we got a number of valid ports. */
while
((
myname
==
NULL
)
&&
(
id
<
numentries
)
)
for
(
id
=
0
;
id
<
numentries
;
id
++
)
{
if
(
lstrcmpiW
(
nameW
,
pi
[
id
].
pName
)
==
0
)
{
TRACE
(
"(%lu) found %s
\n
"
,
id
,
debugstr_w
(
pi
[
id
].
pName
));
myname
=
pi
[
id
].
pName
;
break
;
}
id
++
;
}
}
id
=
(
myname
)
?
get_type_from_name
(
myname
)
:
PORT_IS_UNKNOWN
;
id
=
myname
?
get_type_from_name
(
myname
,
TRUE
)
:
PORT_IS_UNKNOWN
;
free
(
pi
);
return
id
;
...
...
@@ -478,6 +485,7 @@ static BOOL WINAPI localmon_OpenPortW(LPWSTR pName, PHANDLE phPort)
port
->
type
=
type
;
port
->
hfile
=
INVALID_HANDLE_VALUE
;
port
->
doc_handle
=
0
;
lstrcpyW
(
port
->
nameW
,
pName
);
*
phPort
=
port
;
...
...
@@ -498,6 +506,19 @@ static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name,
TRACE
(
"(%p %s %ld %ld %p)
\n
"
,
hport
,
debugstr_w
(
printer_name
),
job_id
,
level
,
doc_info
);
if
(
port
->
type
==
PORT_IS_PIPE
)
{
struct
start_doc_params
params
;
if
(
port
->
doc_handle
)
return
TRUE
;
params
.
type
=
port
->
type
;
params
.
port
=
port
->
nameW
;
params
.
doc
=
&
port
->
doc_handle
;
return
UNIX_CALL
(
start_doc
,
&
params
);
}
if
(
port
->
type
!=
PORT_IS_FILE
)
{
SetLastError
(
ERROR_CALL_NOT_IMPLEMENTED
);
...
...
@@ -525,6 +546,19 @@ static BOOL WINAPI localmon_WritePort(HANDLE hport, BYTE *buf, DWORD size,
TRACE
(
"(%p %p %lu %p)
\n
"
,
hport
,
buf
,
size
,
written
);
if
(
port
->
type
==
PORT_IS_PIPE
)
{
struct
write_doc_params
params
;
BOOL
ret
;
params
.
doc
=
port
->
doc_handle
;
params
.
buf
=
buf
;
params
.
size
=
size
;
ret
=
UNIX_CALL
(
write_doc
,
&
params
);
*
written
=
ret
?
size
:
0
;
return
ret
;
}
return
WriteFile
(
port
->
hfile
,
buf
,
size
,
written
,
NULL
);
}
...
...
@@ -534,6 +568,15 @@ static BOOL WINAPI localmon_EndDocPort(HANDLE hport)
TRACE
(
"(%p)
\n
"
,
hport
);
if
(
port
->
type
==
PORT_IS_PIPE
)
{
struct
end_doc_params
params
;
params
.
doc
=
port
->
doc_handle
;
port
->
doc_handle
=
0
;
return
UNIX_CALL
(
end_doc
,
&
params
);
}
CloseHandle
(
port
->
hfile
);
port
->
hfile
=
INVALID_HANDLE_VALUE
;
return
TRUE
;
...
...
@@ -712,7 +755,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
if
(
!
lstrcmpW
(
pszDataName
,
L"PortIsValid"
))
{
TRACE
(
"InputData (%ld): %s
\n
"
,
cbInputData
,
debugstr_w
(
(
LPWSTR
)
pInputData
));
res
=
get_type_from_name
((
LPCWSTR
)
pInputData
);
res
=
get_type_from_name
((
LPCWSTR
)
pInputData
,
TRUE
);
TRACE
(
"detected as %lu
\n
"
,
res
);
/* names, that we have recognized, are valid */
if
(
res
)
return
ERROR_SUCCESS
;
...
...
dlls/localspl/localspl_private.h
View file @
fca258ef
...
...
@@ -22,6 +22,8 @@
#define __WINE_LOCALSPL_PRIVATE__
#include <windef.h>
#include "winternl.h"
#include "wine/unixlib.h"
extern
HINSTANCE
localspl_instance
DECLSPEC_HIDDEN
;
...
...
@@ -165,5 +167,32 @@ extern HINSTANCE localspl_instance DECLSPEC_HIDDEN;
#define PORT_IS_CUPS 7
#define PORT_IS_LPR 8
struct
start_doc_params
{
unsigned
int
type
;
const
WCHAR
*
port
;
INT64
*
doc
;
};
struct
write_doc_params
{
INT64
doc
;
const
BYTE
*
buf
;
unsigned
int
size
;
};
struct
end_doc_params
{
INT64
doc
;
};
#define UNIX_CALL(func, params) WINE_UNIX_CALL(unix_ ## func, params)
enum
cups_funcs
{
unix_start_doc
,
unix_write_doc
,
unix_end_doc
,
};
#endif
/* __WINE_LOCALSPL_PRIVATE__ */
dlls/localspl/provider.c
View file @
fca258ef
...
...
@@ -987,6 +987,10 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname)
TRACE
(
"(%s)
\n
"
,
debugstr_w
(
portname
));
/* wine specific ports */
if
(
portname
[
0
]
==
'|'
)
return
monitor_load
(
L"Local Port"
,
NULL
);
/* Try the Local Monitor first */
if
(
RegOpenKeyW
(
HKEY_LOCAL_MACHINE
,
winnt_cv_portsW
,
&
hroot
)
==
ERROR_SUCCESS
)
{
if
(
RegQueryValueExW
(
hroot
,
portname
,
NULL
,
NULL
,
NULL
,
&
len
)
==
ERROR_SUCCESS
)
{
...
...
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