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
857e9429
Commit
857e9429
authored
Feb 08, 2009
by
Detlef Riekenberg
Committed by
Alexandre Julliard
Feb 09, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winspool: Move EnumPortsW to the backend.
parent
51f078bd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
241 additions
and
200 deletions
+241
-200
provider.c
dlls/localspl/provider.c
+228
-1
info.c
dlls/winspool.drv/info.c
+13
-199
No files found.
dlls/localspl/provider.c
View file @
857e9429
...
...
@@ -298,6 +298,27 @@ static void monitor_unload(monitor_t * pm)
}
/******************************************************************
* monitor_unloadall [internal]
*
* release all printmonitors and unload them from memory, when needed
*
*/
static
void
monitor_unloadall
(
void
)
{
monitor_t
*
pm
;
monitor_t
*
next
;
EnterCriticalSection
(
&
monitor_handles_cs
);
/* iterate through the list, with safety against removal */
LIST_FOR_EACH_ENTRY_SAFE
(
pm
,
next
,
&
monitor_handles
,
monitor_t
,
entry
)
{
monitor_unload
(
pm
);
}
LeaveCriticalSection
(
&
monitor_handles_cs
);
}
/******************************************************************
* monitor_load [internal]
*
* load a printmonitor, get the dllname from the registry, when needed
...
...
@@ -457,6 +478,40 @@ cleanup:
}
/******************************************************************
* monitor_loadall [internal]
*
* Load all registered monitors
*
*/
static
DWORD
monitor_loadall
(
void
)
{
monitor_t
*
pm
;
DWORD
registered
=
0
;
DWORD
loaded
=
0
;
HKEY
hmonitors
;
WCHAR
buffer
[
MAX_PATH
];
DWORD
id
=
0
;
if
(
RegOpenKeyW
(
HKEY_LOCAL_MACHINE
,
monitorsW
,
&
hmonitors
)
==
ERROR_SUCCESS
)
{
RegQueryInfoKeyW
(
hmonitors
,
NULL
,
NULL
,
NULL
,
&
registered
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
TRACE
(
"%d monitors registered
\n
"
,
registered
);
while
(
id
<
registered
)
{
buffer
[
0
]
=
'\0'
;
RegEnumKeyW
(
hmonitors
,
id
,
buffer
,
MAX_PATH
);
pm
=
monitor_load
(
buffer
,
NULL
);
if
(
pm
)
loaded
++
;
id
++
;
}
RegCloseKey
(
hmonitors
);
}
TRACE
(
"%d monitors loaded
\n
"
,
loaded
);
return
loaded
;
}
/******************************************************************
* Return the number of bytes for an multi_sz string.
* The result includes all \0s
* (specifically the extra \0, that is needed as multi_sz terminator).
...
...
@@ -617,6 +672,95 @@ static DWORD get_local_monitors(DWORD level, LPBYTE pMonitors, DWORD cbBuf, LPDW
return
needed
;
}
/******************************************************************
* enumerate the local Ports from all loaded monitors (internal)
*
* returns the needed size (in bytes) for pPorts
* and *lpreturned is set to number of entries returned in pPorts
*
*/
static
DWORD
get_ports_from_all_monitors
(
DWORD
level
,
LPBYTE
pPorts
,
DWORD
cbBuf
,
LPDWORD
lpreturned
)
{
monitor_t
*
pm
;
LPWSTR
ptr
;
LPPORT_INFO_2W
cache
;
LPPORT_INFO_2W
out
;
LPBYTE
pi_buffer
=
NULL
;
DWORD
pi_allocated
=
0
;
DWORD
pi_needed
;
DWORD
pi_index
;
DWORD
pi_returned
;
DWORD
res
;
DWORD
outindex
=
0
;
DWORD
needed
;
DWORD
numentries
;
DWORD
entrysize
;
TRACE
(
"(%d, %p, %d, %p)
\n
"
,
level
,
pPorts
,
cbBuf
,
lpreturned
);
entrysize
=
(
level
==
1
)
?
sizeof
(
PORT_INFO_1W
)
:
sizeof
(
PORT_INFO_2W
);
numentries
=
*
lpreturned
;
/* this is 0, when we scan the registry */
needed
=
entrysize
*
numentries
;
ptr
=
(
LPWSTR
)
&
pPorts
[
needed
];
numentries
=
0
;
needed
=
0
;
LIST_FOR_EACH_ENTRY
(
pm
,
&
monitor_handles
,
monitor_t
,
entry
)
{
if
((
pm
->
monitor
)
&&
(
pm
->
monitor
->
pfnEnumPorts
))
{
pi_needed
=
0
;
pi_returned
=
0
;
res
=
pm
->
monitor
->
pfnEnumPorts
(
NULL
,
level
,
pi_buffer
,
pi_allocated
,
&
pi_needed
,
&
pi_returned
);
if
(
!
res
&&
(
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
))
{
/* Do not use heap_realloc (we do not need the old data in the buffer) */
heap_free
(
pi_buffer
);
pi_buffer
=
heap_alloc
(
pi_needed
);
pi_allocated
=
(
pi_buffer
)
?
pi_needed
:
0
;
res
=
pm
->
monitor
->
pfnEnumPorts
(
NULL
,
level
,
pi_buffer
,
pi_allocated
,
&
pi_needed
,
&
pi_returned
);
}
TRACE
(
"(%s) got %d with %d (need %d byte for %d entries)
\n
"
,
debugstr_w
(
pm
->
name
),
res
,
GetLastError
(),
pi_needed
,
pi_returned
);
numentries
+=
pi_returned
;
needed
+=
pi_needed
;
/* fill the output-buffer (pPorts), if we have one */
if
(
pPorts
&&
(
cbBuf
>=
needed
)
&&
pi_buffer
)
{
pi_index
=
0
;
while
(
pi_returned
>
pi_index
)
{
cache
=
(
LPPORT_INFO_2W
)
&
pi_buffer
[
pi_index
*
entrysize
];
out
=
(
LPPORT_INFO_2W
)
&
pPorts
[
outindex
*
entrysize
];
out
->
pPortName
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pPortName
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
if
(
level
>
1
)
{
out
->
pMonitorName
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pMonitorName
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
out
->
pDescription
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pDescription
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
out
->
fPortType
=
cache
->
fPortType
;
out
->
Reserved
=
cache
->
Reserved
;
}
pi_index
++
;
outindex
++
;
}
}
}
}
/* the temporary portinfo-buffer is no longer needed */
heap_free
(
pi_buffer
);
*
lpreturned
=
numentries
;
TRACE
(
"need %d byte for %d entries
\n
"
,
needed
,
numentries
);
return
needed
;
}
/*****************************************************************************
* open_driver_reg [internal]
*
...
...
@@ -1197,6 +1341,89 @@ em_cleanup:
return
(
res
);
}
/******************************************************************************
* fpEnumPorts [exported through PRINTPROVIDOR]
*
* Enumerate available Ports
*
* PARAMS
* pName [I] Servername or NULL (local Computer)
* Level [I] Structure-Level (1 or 2)
* pPorts [O] PTR to Buffer that receives the Result
* cbBuf [I] Size of Buffer at pPorts
* pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPorts
* pcReturned [O] PTR to DWORD that receives the number of Ports in pPorts
*
* RETURNS
* Success: TRUE
* Failure: FALSE and in pcbNeeded the Bytes required for pPorts, if cbBuf is too small
*
*/
static
BOOL
WINAPI
fpEnumPorts
(
LPWSTR
pName
,
DWORD
Level
,
LPBYTE
pPorts
,
DWORD
cbBuf
,
LPDWORD
pcbNeeded
,
LPDWORD
pcReturned
)
{
DWORD
needed
=
0
;
DWORD
numentries
=
0
;
LONG
lres
;
BOOL
res
=
FALSE
;
TRACE
(
"(%s, %d, %p, %d, %p, %p)
\n
"
,
debugstr_w
(
pName
),
Level
,
pPorts
,
cbBuf
,
pcbNeeded
,
pcReturned
);
lres
=
copy_servername_from_name
(
pName
,
NULL
);
if
(
lres
)
{
FIXME
(
"server %s not supported
\n
"
,
debugstr_w
(
pName
));
SetLastError
(
ERROR_INVALID_NAME
);
goto
emP_cleanup
;
}
if
(
!
Level
||
(
Level
>
2
))
{
SetLastError
(
ERROR_INVALID_LEVEL
);
goto
emP_cleanup
;
}
if
(
!
pcbNeeded
||
(
!
pPorts
&&
(
cbBuf
>
0
)))
{
SetLastError
(
RPC_X_NULL_REF_POINTER
);
goto
emP_cleanup
;
}
EnterCriticalSection
(
&
monitor_handles_cs
);
monitor_loadall
();
/* Scan all local Ports */
numentries
=
0
;
needed
=
get_ports_from_all_monitors
(
Level
,
NULL
,
0
,
&
numentries
);
/* we calculated the needed buffersize. now do the error-checks */
if
(
cbBuf
<
needed
)
{
monitor_unloadall
();
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
goto
emP_cleanup_cs
;
}
else
if
(
!
pPorts
||
!
pcReturned
)
{
monitor_unloadall
();
SetLastError
(
RPC_X_NULL_REF_POINTER
);
goto
emP_cleanup_cs
;
}
/* Fill the Buffer */
needed
=
get_ports_from_all_monitors
(
Level
,
pPorts
,
cbBuf
,
&
numentries
);
res
=
TRUE
;
monitor_unloadall
();
emP_cleanup_cs:
LeaveCriticalSection
(
&
monitor_handles_cs
);
emP_cleanup:
if
(
pcbNeeded
)
*
pcbNeeded
=
needed
;
if
(
pcReturned
)
*
pcReturned
=
(
res
)
?
numentries
:
0
;
TRACE
(
"returning %d with %d (%d byte for %d of %d entries)
\n
"
,
(
res
),
GetLastError
(),
needed
,
(
res
)
?
numentries
:
0
,
numentries
);
return
(
res
);
}
/*****************************************************
* setup_provider [internal]
*/
...
...
@@ -1241,7 +1468,7 @@ void setup_provider(void)
NULL
,
/* fpSetForm */
NULL
,
/* fpEnumForms */
fpEnumMonitors
,
NULL
,
/* fpEnumPorts */
fpEnumPorts
,
NULL
,
/* fpAddPort */
NULL
,
/* fpConfigurePort */
NULL
,
/* fpDeletePort */
...
...
dlls/winspool.drv/info.c
View file @
857e9429
...
...
@@ -6,7 +6,7 @@
* Copyright 1999 Klaas van Gend
* Copyright 1999, 2000 Huw D M Davies
* Copyright 2001 Marcus Meissner
* Copyright 2005-200
8
Detlef Riekenberg
* Copyright 2005-200
9
Detlef Riekenberg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -790,26 +790,6 @@ static void monitor_unload(monitor_t * pm)
}
/******************************************************************
* monitor_unloadall [internal]
*
* release all printmonitors and unload them from memory, when needed
*/
static
void
monitor_unloadall
(
void
)
{
monitor_t
*
pm
;
monitor_t
*
next
;
EnterCriticalSection
(
&
monitor_handles_cs
);
/* iterate through the list, with safety against removal */
LIST_FOR_EACH_ENTRY_SAFE
(
pm
,
next
,
&
monitor_handles
,
monitor_t
,
entry
)
{
monitor_unload
(
pm
);
}
LeaveCriticalSection
(
&
monitor_handles_cs
);
}
/******************************************************************
* monitor_load [internal]
*
* load a printmonitor, get the dllname from the registry, when needed
...
...
@@ -969,42 +949,6 @@ cleanup:
}
/******************************************************************
* monitor_loadall [internal]
*
* Load all registered monitors
*
*/
static
DWORD
monitor_loadall
(
void
)
{
monitor_t
*
pm
;
DWORD
registered
=
0
;
DWORD
loaded
=
0
;
HKEY
hmonitors
;
WCHAR
buffer
[
MAX_PATH
];
DWORD
id
=
0
;
if
(
RegOpenKeyW
(
HKEY_LOCAL_MACHINE
,
MonitorsW
,
&
hmonitors
)
==
ERROR_SUCCESS
)
{
RegQueryInfoKeyW
(
hmonitors
,
NULL
,
NULL
,
NULL
,
&
registered
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
);
TRACE
(
"%d monitors registered
\n
"
,
registered
);
EnterCriticalSection
(
&
monitor_handles_cs
);
while
(
id
<
registered
)
{
buffer
[
0
]
=
'\0'
;
RegEnumKeyW
(
hmonitors
,
id
,
buffer
,
MAX_PATH
);
pm
=
monitor_load
(
buffer
,
NULL
);
if
(
pm
)
loaded
++
;
id
++
;
}
LeaveCriticalSection
(
&
monitor_handles_cs
);
RegCloseKey
(
hmonitors
);
}
TRACE
(
"%d monitors loaded
\n
"
,
loaded
);
return
loaded
;
}
/******************************************************************
* monitor_loadui [internal]
*
* load the userinterface-dll for a given portmonitor
...
...
@@ -1107,94 +1051,6 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname)
}
/******************************************************************
* enumerate the local Ports from all loaded monitors (internal)
*
* returns the needed size (in bytes) for pPorts
* and *lpreturned is set to number of entries returned in pPorts
*
*/
static
DWORD
get_ports_from_all_monitors
(
DWORD
level
,
LPBYTE
pPorts
,
DWORD
cbBuf
,
LPDWORD
lpreturned
)
{
monitor_t
*
pm
;
LPWSTR
ptr
;
LPPORT_INFO_2W
cache
;
LPPORT_INFO_2W
out
;
LPBYTE
pi_buffer
=
NULL
;
DWORD
pi_allocated
=
0
;
DWORD
pi_needed
;
DWORD
pi_index
;
DWORD
pi_returned
;
DWORD
res
;
DWORD
outindex
=
0
;
DWORD
needed
;
DWORD
numentries
;
DWORD
entrysize
;
TRACE
(
"(%d, %p, %d, %p)
\n
"
,
level
,
pPorts
,
cbBuf
,
lpreturned
);
entrysize
=
(
level
==
1
)
?
sizeof
(
PORT_INFO_1W
)
:
sizeof
(
PORT_INFO_2W
);
numentries
=
*
lpreturned
;
/* this is 0, when we scan the registry */
needed
=
entrysize
*
numentries
;
ptr
=
(
LPWSTR
)
&
pPorts
[
needed
];
numentries
=
0
;
needed
=
0
;
LIST_FOR_EACH_ENTRY
(
pm
,
&
monitor_handles
,
monitor_t
,
entry
)
{
if
((
pm
->
monitor
)
&&
(
pm
->
monitor
->
pfnEnumPorts
))
{
pi_needed
=
0
;
pi_returned
=
0
;
res
=
pm
->
monitor
->
pfnEnumPorts
(
NULL
,
level
,
pi_buffer
,
pi_allocated
,
&
pi_needed
,
&
pi_returned
);
if
(
!
res
&&
(
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
))
{
/* Do not use HeapReAlloc (we do not need the old data in the buffer) */
HeapFree
(
GetProcessHeap
(),
0
,
pi_buffer
);
pi_buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
pi_needed
);
pi_allocated
=
(
pi_buffer
)
?
pi_needed
:
0
;
res
=
pm
->
monitor
->
pfnEnumPorts
(
NULL
,
level
,
pi_buffer
,
pi_allocated
,
&
pi_needed
,
&
pi_returned
);
}
TRACE
(
"(%s) got %d with %d (need %d byte for %d entries)
\n
"
,
debugstr_w
(
pm
->
name
),
res
,
GetLastError
(),
pi_needed
,
pi_returned
);
numentries
+=
pi_returned
;
needed
+=
pi_needed
;
/* fill the output-buffer (pPorts), if we have one */
if
(
pPorts
&&
(
cbBuf
>=
needed
)
&&
pi_buffer
)
{
pi_index
=
0
;
while
(
pi_returned
>
pi_index
)
{
cache
=
(
LPPORT_INFO_2W
)
&
pi_buffer
[
pi_index
*
entrysize
];
out
=
(
LPPORT_INFO_2W
)
&
pPorts
[
outindex
*
entrysize
];
out
->
pPortName
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pPortName
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
if
(
level
>
1
)
{
out
->
pMonitorName
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pMonitorName
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
out
->
pDescription
=
ptr
;
lstrcpyW
(
ptr
,
cache
->
pDescription
);
ptr
+=
(
lstrlenW
(
ptr
)
+
1
);
out
->
fPortType
=
cache
->
fPortType
;
out
->
Reserved
=
cache
->
Reserved
;
}
pi_index
++
;
outindex
++
;
}
}
}
}
/* the temporary portinfo-buffer is no longer needed */
HeapFree
(
GetProcessHeap
(),
0
,
pi_buffer
);
*
lpreturned
=
numentries
;
TRACE
(
"need %d byte for %d entries
\n
"
,
needed
,
numentries
);
return
needed
;
}
/******************************************************************
* get_servername_from_name (internal)
*
* for an external server, a copy of the serverpart from the full name is returned
...
...
@@ -5504,80 +5360,38 @@ cleanup:
* Enumerate available Ports
*
* PARAMS
*
name
[I] Servername or NULL (local Computer)
*
level
[I] Structure-Level (1 or 2)
*
buffer
[O] PTR to Buffer that receives the Result
*
bufsize [I] Size of Buffer at buffer
*
bufneeded [O] PTR to DWORD that receives the size in Bytes used / required for buffer
*
bufreturned [O] PTR to DWORD that receives the number of Ports in buffer
*
pName
[I] Servername or NULL (local Computer)
*
Level
[I] Structure-Level (1 or 2)
*
pPorts
[O] PTR to Buffer that receives the Result
*
cbBuf [I] Size of Buffer at pPorts
*
pcbNeeded [O] PTR to DWORD that receives the size in Bytes used / required for pPorts
*
pcReturned [O] PTR to DWORD that receives the number of Ports in pPorts
*
* RETURNS
* Success: TRUE
* Failure: FALSE and in
bufneeded the Bytes required for buffer, if bufsize
is too small
* Failure: FALSE and in
pcbNeeded the Bytes required for pPorts, if cbBuf
is too small
*
*/
BOOL
WINAPI
EnumPortsW
(
LPWSTR
pName
,
DWORD
Level
,
LPBYTE
pPorts
,
DWORD
cbBuf
,
LPDWORD
pcbNeeded
,
LPDWORD
pcReturned
)
{
DWORD
needed
=
0
;
DWORD
numentries
=
0
;
BOOL
res
=
FALSE
;
TRACE
(
"(%s, %d, %p, %d, %p, %p)
\n
"
,
debugstr_w
(
pName
),
Level
,
pPorts
,
cbBuf
,
pcbNeeded
,
pcReturned
);
if
(
pName
&&
(
pName
[
0
]))
{
FIXME
(
"not implemented for Server %s
\n
"
,
debugstr_w
(
pName
));
SetLastError
(
ERROR_ACCESS_DENIED
);
goto
emP_cleanup
;
}
if
((
backend
==
NULL
)
&&
!
load_backend
())
return
FALSE
;
/* Level is not checked in win9x */
if
(
!
Level
||
(
Level
>
2
))
{
WARN
(
"level (%d) is ignored in win9x
\n
"
,
Level
);
SetLastError
(
ERROR_INVALID_LEVEL
);
goto
emP_cleanup
;
}
if
(
!
pcbNeeded
)
{
SetLastError
(
RPC_X_NULL_REF_POINTER
);
goto
emP_cleanup
;
}
EnterCriticalSection
(
&
monitor_handles_cs
);
monitor_loadall
();
/* Scan all local Ports */
numentries
=
0
;
needed
=
get_ports_from_all_monitors
(
Level
,
NULL
,
0
,
&
numentries
);
/* we calculated the needed buffersize. now do the error-checks */
if
(
cbBuf
<
needed
)
{
monitor_unloadall
();
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
goto
emP_cleanup_cs
;
return
FALSE
;
}
else
if
(
!
pPorts
||
!
pcReturned
)
{
monitor_unloadall
();
if
(
!
pcbNeeded
||
(
!
pPorts
&&
(
cbBuf
>
0
)))
{
SetLastError
(
RPC_X_NULL_REF_POINTER
);
goto
emP_cleanup_cs
;
return
FALSE
;
}
/* Fill the Buffer */
needed
=
get_ports_from_all_monitors
(
Level
,
pPorts
,
cbBuf
,
&
numentries
);
res
=
TRUE
;
monitor_unloadall
();
emP_cleanup_cs
:
LeaveCriticalSection
(
&
monitor_handles_cs
);
emP_cleanup
:
if
(
pcbNeeded
)
*
pcbNeeded
=
needed
;
if
(
pcReturned
)
*
pcReturned
=
(
res
)
?
numentries
:
0
;
TRACE
(
"returning %d with %d (%d byte for %d of %d entries)
\n
"
,
(
res
),
GetLastError
(),
needed
,
(
res
)
?
numentries
:
0
,
numentries
);
return
(
res
);
return
backend
->
fpEnumPorts
(
pName
,
Level
,
pPorts
,
cbBuf
,
pcbNeeded
,
pcReturned
);
}
/******************************************************************************
...
...
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