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
ccfe6e9c
Commit
ccfe6e9c
authored
Feb 21, 2001
by
Ian Pilcher
Committed by
Alexandre Julliard
Feb 21, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement EnumPrinterDataEx{A|W}.
parent
7ad126dc
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
414 additions
and
0 deletions
+414
-0
info.c
dlls/winspool/info.c
+383
-0
winspool.drv.spec
dlls/winspool/winspool.drv.spec
+4
-0
winspool.h
include/winspool.h
+27
-0
No files found.
dlls/winspool/info.c
View file @
ccfe6e9c
...
...
@@ -2561,3 +2561,386 @@ DWORD WINAPI GetPrinterDataW(HANDLE hPrinter, LPWSTR pValueName, LPDWORD pType,
return
GetPrinterDataExW
(
hPrinter
,
PrinterDriverDataW
,
pValueName
,
pType
,
pData
,
nSize
,
pcbNeeded
);
}
/*******************************************************************************
* EnumPrinterDataExW [WINSPOOL.197]
*/
DWORD
WINAPI
EnumPrinterDataExW
(
HANDLE
hPrinter
,
LPCWSTR
pKeyName
,
LPBYTE
pEnumValues
,
DWORD
cbEnumValues
,
LPDWORD
pcbEnumValues
,
LPDWORD
pnEnumValues
)
{
HKEY
hkPrinter
,
hkSubKey
;
DWORD
r
,
ret
,
dwIndex
,
cValues
,
cbMaxValueNameLen
,
cbValueNameLen
,
cbMaxValueLen
,
cbValueLen
,
cbBufSize
,
dwType
;
LPWSTR
lpValueName
;
HANDLE
hHeap
;
PBYTE
lpValue
;
PPRINTER_ENUM_VALUESW
ppev
;
TRACE
(
"%08x %s
\n
"
,
hPrinter
,
debugstr_w
(
pKeyName
));
if
(
pKeyName
==
NULL
||
*
pKeyName
==
0
)
return
ERROR_INVALID_PARAMETER
;
ret
=
WINSPOOL_GetOpenedPrinterRegKey
(
hPrinter
,
&
hkPrinter
);
if
(
ret
!=
ERROR_SUCCESS
)
{
TRACE
(
"WINSPOOL_GetOpenedPrinterRegKey (%08x) returned %li
\n
"
,
hPrinter
,
ret
);
return
ret
;
}
ret
=
RegOpenKeyExW
(
hkPrinter
,
pKeyName
,
0
,
KEY_READ
,
&
hkSubKey
);
if
(
ret
!=
ERROR_SUCCESS
)
{
r
=
RegCloseKey
(
hkPrinter
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
TRACE
(
"RegOpenKeyExW (%08x, %s) returned %li
\n
"
,
hPrinter
,
debugstr_w
(
pKeyName
),
ret
);
return
ret
;
}
ret
=
RegCloseKey
(
hkPrinter
);
if
(
ret
!=
ERROR_SUCCESS
)
{
ERR
(
"RegCloseKey returned %li
\n
"
,
ret
);
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ret
;
}
ret
=
RegQueryInfoKeyW
(
hkSubKey
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
&
cValues
,
&
cbMaxValueNameLen
,
&
cbMaxValueLen
,
NULL
,
NULL
);
if
(
ret
!=
ERROR_SUCCESS
)
{
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
TRACE
(
"RegQueryInfoKeyW (%08x) returned %li
\n
"
,
hkSubKey
,
ret
);
return
ret
;
}
TRACE
(
"RegQueryInfoKeyW returned cValues = %li, cbMaxValueNameLen = %li, "
"cbMaxValueLen = %li
\n
"
,
cValues
,
cbMaxValueNameLen
,
cbMaxValueLen
);
if
(
cValues
==
0
)
/* empty key */
{
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
*
pcbEnumValues
=
*
pnEnumValues
=
0
;
return
ERROR_SUCCESS
;
}
++
cbMaxValueNameLen
;
/* allow for trailing '\0' */
hHeap
=
GetProcessHeap
();
if
(
hHeap
==
(
HANDLE
)
NULL
)
{
ERR
(
"GetProcessHeap failed
\n
"
);
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ERROR_OUTOFMEMORY
;
}
lpValueName
=
HeapAlloc
(
hHeap
,
0
,
cbMaxValueNameLen
*
sizeof
(
WCHAR
));
if
(
lpValueName
==
NULL
)
{
ERR
(
"Failed to allocate %li bytes from process heap
\n
"
,
cbMaxValueNameLen
*
sizeof
(
WCHAR
));
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ERROR_OUTOFMEMORY
;
}
lpValue
=
HeapAlloc
(
hHeap
,
0
,
cbMaxValueLen
);
if
(
lpValue
==
NULL
)
{
ERR
(
"Failed to allocate %li bytes from process heap
\n
"
,
cbMaxValueLen
);
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ERROR_OUTOFMEMORY
;
}
TRACE
(
"pass 1: calculating buffer required for all names and values
\n
"
);
cbBufSize
=
cValues
*
sizeof
(
PRINTER_ENUM_VALUESW
);
TRACE
(
"%li bytes required for %li headers
\n
"
,
cbBufSize
,
cValues
);
for
(
dwIndex
=
0
;
dwIndex
<
cValues
;
++
dwIndex
)
{
cbValueNameLen
=
cbMaxValueNameLen
;
cbValueLen
=
cbMaxValueLen
;
ret
=
RegEnumValueW
(
hkSubKey
,
dwIndex
,
lpValueName
,
&
cbValueNameLen
,
NULL
,
NULL
,
lpValue
,
&
cbValueLen
);
if
(
ret
!=
ERROR_SUCCESS
)
{
if
(
HeapFree
(
hHeap
,
0
,
lpValue
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
TRACE
(
"RegEnumValueW (%li) returned %li
\n
"
,
dwIndex
,
ret
);
return
ret
;
}
TRACE
(
"%s [%li]: name needs %li bytes, data needs %li bytes
\n
"
,
debugstr_w
(
lpValueName
),
dwIndex
,
(
cbValueNameLen
+
1
)
*
sizeof
(
WCHAR
),
cbValueLen
);
cbBufSize
+=
(
cbValueNameLen
+
1
)
*
sizeof
(
WCHAR
);
cbBufSize
+=
cbValueLen
;
}
TRACE
(
"%li bytes required for all %li values
\n
"
,
cbBufSize
,
cValues
);
*
pcbEnumValues
=
cbBufSize
;
*
pnEnumValues
=
cValues
;
if
(
cbEnumValues
<
cbBufSize
)
/* buffer too small */
{
if
(
HeapFree
(
hHeap
,
0
,
lpValue
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
TRACE
(
"%li byte buffer is not large enough
\n
"
,
cbEnumValues
);
return
ERROR_MORE_DATA
;
}
TRACE
(
"pass 2: copying all names and values to buffer
\n
"
);
ppev
=
(
PPRINTER_ENUM_VALUESW
)
pEnumValues
;
/* array of structs */
pEnumValues
+=
cValues
*
sizeof
(
PRINTER_ENUM_VALUESW
);
for
(
dwIndex
=
0
;
dwIndex
<
cValues
;
++
dwIndex
)
{
cbValueNameLen
=
cbMaxValueNameLen
;
cbValueLen
=
cbMaxValueLen
;
ret
=
RegEnumValueW
(
hkSubKey
,
dwIndex
,
lpValueName
,
&
cbValueNameLen
,
NULL
,
&
dwType
,
lpValue
,
&
cbValueLen
);
if
(
ret
!=
ERROR_SUCCESS
)
{
if
(
HeapFree
(
hHeap
,
0
,
lpValue
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
TRACE
(
"RegEnumValueW (%li) returned %li
\n
"
,
dwIndex
,
ret
);
return
ret
;
}
cbValueNameLen
=
(
cbValueNameLen
+
1
)
*
sizeof
(
WCHAR
);
memcpy
(
pEnumValues
,
lpValueName
,
cbValueNameLen
);
ppev
[
dwIndex
].
pValueName
=
(
LPWSTR
)
pEnumValues
;
pEnumValues
+=
cbValueNameLen
;
/* return # of *bytes* (including trailing \0), not # of chars */
ppev
[
dwIndex
].
cbValueName
=
cbValueNameLen
;
ppev
[
dwIndex
].
dwType
=
dwType
;
memcpy
(
pEnumValues
,
lpValue
,
cbValueLen
);
ppev
[
dwIndex
].
pData
=
pEnumValues
;
pEnumValues
+=
cbValueLen
;
ppev
[
dwIndex
].
cbData
=
cbValueLen
;
TRACE
(
"%s [%li]: copied name (%li bytes) and data (%li bytes)
\n
"
,
debugstr_w
(
lpValueName
),
dwIndex
,
cbValueNameLen
,
cbValueLen
);
}
if
(
HeapFree
(
hHeap
,
0
,
lpValue
)
==
0
)
{
ret
=
GetLastError
();
ERR
(
"HeapFree failed with code %li
\n
"
,
ret
);
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ret
;
}
if
(
HeapFree
(
hHeap
,
0
,
lpValueName
)
==
0
)
{
ret
=
GetLastError
();
ERR
(
"HeapFree failed with code %li
\n
"
,
ret
);
r
=
RegCloseKey
(
hkSubKey
);
if
(
r
!=
ERROR_SUCCESS
)
WARN
(
"RegCloseKey returned %li
\n
"
,
r
);
return
ret
;
}
ret
=
RegCloseKey
(
hkSubKey
);
if
(
ret
!=
ERROR_SUCCESS
)
{
ERR
(
"RegCloseKey returned %li
\n
"
,
ret
);
return
ret
;
}
return
ERROR_SUCCESS
;
}
/*******************************************************************************
* EnumPrinterDataExA [WINSPOOL.196]
*
* This functions returns value names and REG_SZ, REG_EXPAND_SZ, and
* REG_MULTI_SZ values as ASCII strings in Unicode-sized buffers. This is
* what Windows 2000 SP1 does.
*
*/
DWORD
WINAPI
EnumPrinterDataExA
(
HANDLE
hPrinter
,
LPCSTR
pKeyName
,
LPBYTE
pEnumValues
,
DWORD
cbEnumValues
,
LPDWORD
pcbEnumValues
,
LPDWORD
pnEnumValues
)
{
INT
len
;
LPWSTR
pKeyNameW
;
DWORD
ret
,
dwIndex
,
dwBufSize
;
HANDLE
hHeap
;
LPSTR
pBuffer
;
TRACE
(
"%08x %s
\n
"
,
hPrinter
,
pKeyName
);
if
(
pKeyName
==
NULL
||
*
pKeyName
==
0
)
return
ERROR_INVALID_PARAMETER
;
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
pKeyName
,
-
1
,
NULL
,
0
);
if
(
len
==
0
)
{
ret
=
GetLastError
();
ERR
(
"MultiByteToWideChar failed with code %li
\n
"
,
ret
);
return
ret
;
}
hHeap
=
GetProcessHeap
();
if
(
hHeap
==
(
HANDLE
)
NULL
)
{
ERR
(
"GetProcessHeap failed
\n
"
);
return
ERROR_OUTOFMEMORY
;
}
pKeyNameW
=
HeapAlloc
(
hHeap
,
0
,
len
*
sizeof
(
WCHAR
));
if
(
pKeyNameW
==
NULL
)
{
ERR
(
"Failed to allocate %li bytes from process heap
\n
"
,
(
LONG
)
len
*
sizeof
(
WCHAR
));
return
ERROR_OUTOFMEMORY
;
}
if
(
MultiByteToWideChar
(
CP_ACP
,
0
,
pKeyName
,
-
1
,
pKeyNameW
,
len
)
==
0
)
{
ret
=
GetLastError
();
ERR
(
"MultiByteToWideChar failed with code %li
\n
"
,
ret
);
if
(
HeapFree
(
hHeap
,
0
,
pKeyNameW
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
return
ret
;
}
ret
=
EnumPrinterDataExW
(
hPrinter
,
pKeyNameW
,
pEnumValues
,
cbEnumValues
,
pcbEnumValues
,
pnEnumValues
);
if
(
ret
!=
ERROR_SUCCESS
)
{
if
(
HeapFree
(
hHeap
,
0
,
pKeyNameW
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
TRACE
(
"EnumPrinterDataExW returned %li
\n
"
,
ret
);
return
ret
;
}
if
(
HeapFree
(
hHeap
,
0
,
pKeyNameW
)
==
0
)
{
ret
=
GetLastError
();
ERR
(
"HeapFree failed with code %li
\n
"
,
ret
);
return
ret
;
}
if
(
*
pnEnumValues
==
0
)
/* empty key */
return
ERROR_SUCCESS
;
dwBufSize
=
0
;
for
(
dwIndex
=
0
;
dwIndex
<
*
pnEnumValues
;
++
dwIndex
)
{
PPRINTER_ENUM_VALUESW
ppev
=
&
((
PPRINTER_ENUM_VALUESW
)
pEnumValues
)[
dwIndex
];
if
(
dwBufSize
<
ppev
->
cbValueName
)
dwBufSize
=
ppev
->
cbValueName
;
if
(
dwBufSize
<
ppev
->
cbData
&&
(
ppev
->
dwType
==
REG_SZ
||
ppev
->
dwType
==
REG_EXPAND_SZ
||
ppev
->
dwType
==
REG_MULTI_SZ
))
dwBufSize
=
ppev
->
cbData
;
}
TRACE
(
"Largest Unicode name or value is %li bytes
\n
"
,
dwBufSize
);
pBuffer
=
HeapAlloc
(
hHeap
,
0
,
dwBufSize
);
if
(
pBuffer
==
NULL
)
{
ERR
(
"Failed to allocate %li bytes from process heap
\n
"
,
dwBufSize
);
return
ERROR_OUTOFMEMORY
;
}
for
(
dwIndex
=
0
;
dwIndex
<
*
pnEnumValues
;
++
dwIndex
)
{
PPRINTER_ENUM_VALUESW
ppev
=
&
((
PPRINTER_ENUM_VALUESW
)
pEnumValues
)[
dwIndex
];
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
ppev
->
pValueName
,
ppev
->
cbValueName
/
sizeof
(
WCHAR
),
pBuffer
,
dwBufSize
,
NULL
,
NULL
);
if
(
len
==
0
)
{
ret
=
GetLastError
();
ERR
(
"WideCharToMultiByte failed with code %li
\n
"
,
ret
);
if
(
HeapFree
(
hHeap
,
0
,
pBuffer
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
return
ret
;
}
memcpy
(
ppev
->
pValueName
,
pBuffer
,
len
);
TRACE
(
"Converted '%s' from Unicode to ASCII
\n
"
,
pBuffer
);
if
(
ppev
->
dwType
!=
REG_SZ
&&
ppev
->
dwType
!=
REG_EXPAND_SZ
&&
ppev
->
dwType
!=
REG_MULTI_SZ
)
continue
;
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
(
LPWSTR
)
ppev
->
pData
,
ppev
->
cbData
/
sizeof
(
WCHAR
),
pBuffer
,
dwBufSize
,
NULL
,
NULL
);
if
(
len
==
0
)
{
ret
=
GetLastError
();
ERR
(
"WideCharToMultiByte failed with code %li
\n
"
,
ret
);
if
(
HeapFree
(
hHeap
,
0
,
pBuffer
)
==
0
)
WARN
(
"HeapFree failed with code %li
\n
"
,
GetLastError
());
return
ret
;
}
memcpy
(
ppev
->
pData
,
pBuffer
,
len
);
TRACE
(
"Converted '%s' from Unicode to ASCII
\n
"
,
pBuffer
);
TRACE
(
" (only first string of REG_MULTI_SZ printed)
\n
"
);
}
if
(
HeapFree
(
hHeap
,
0
,
pBuffer
)
==
0
)
{
ret
=
GetLastError
();
ERR
(
"HeapFree failed with code %li
\n
"
,
ret
);
return
ret
;
}
return
ERROR_SUCCESS
;
}
dlls/winspool/winspool.drv.spec
View file @
ccfe6e9c
...
...
@@ -80,6 +80,10 @@ debug_channels (winspool)
@ stub EnumPrintProcessorDatatypesW
@ stub EnumPrintProcessorsA
@ stub EnumPrintProcessorsW
@ stub EnumPrinterDataA
@ stdcall EnumPrinterDataExA(long str ptr long ptr ptr) EnumPrinterDataExA
@ stdcall EnumPrinterDataExW(long wstr ptr long ptr ptr) EnumPrinterDataExW
@ stub EnumPrinterDataW
@ stdcall EnumPrinterDriversA(str str long ptr long ptr ptr) EnumPrinterDriversA
@ stdcall EnumPrinterDriversW(wstr wstr long ptr long ptr ptr) EnumPrinterDriversW
@ stdcall EnumPrintersA(long ptr long ptr long ptr ptr) EnumPrintersA
...
...
include/winspool.h
View file @
ccfe6e9c
...
...
@@ -763,6 +763,25 @@ DECL_WINELIB_TYPE_AW(PROVIDOR_INFO_1)
DECL_WINELIB_TYPE_AW
(
PPROVIDOR_INFO_1
)
DECL_WINELIB_TYPE_AW
(
LPPROVIDOR_INFO_1
)
typedef
struct
_PRINTER_ENUM_VALUESA
{
LPSTR
pValueName
;
DWORD
cbValueName
;
DWORD
dwType
;
LPBYTE
pData
;
DWORD
cbData
;
}
PRINTER_ENUM_VALUESA
,
*
PPRINTER_ENUM_VALUESA
;
typedef
struct
_PRINTER_ENUM_VALUESW
{
LPWSTR
pValueName
;
DWORD
cbValueName
;
DWORD
dwType
;
LPBYTE
pData
;
DWORD
cbData
;
}
PRINTER_ENUM_VALUESW
,
*
PPRINTER_ENUM_VALUESW
;
DECL_WINELIB_TYPE_AW
(
PRINTER_ENUM_VALUES
)
DECL_WINELIB_TYPE_AW
(
PPRINTER_ENUM_VALUES
)
/* DECLARATIONS */
INT
WINAPI
DeviceCapabilitiesA
(
LPCSTR
pDevice
,
LPCSTR
pPort
,
WORD
fwCapability
,
LPSTR
pOutput
,
LPDEVMODEA
pDevMode
);
...
...
@@ -1083,6 +1102,14 @@ BOOL WINAPI DeletePrintProvidorW(LPWSTR pName, LPWSTR pEnvironment,
LPWSTR
pPrintProvidorName
);
#define DeletePrintProvidor WINELIB_NAME_AW(DeletePrintProvidor)
DWORD
WINAPI
EnumPrinterDataExA
(
HANDLE
hPrinter
,
LPCSTR
pKeyName
,
LPBYTE
pEnumValues
,
DWORD
cbEnumValues
,
LPDWORD
pcbEnumValues
,
LPDWORD
pnEnumValues
);
DWORD
WINAPI
EnumPrinterDataExW
(
HANDLE
hPrinter
,
LPCWSTR
pKeyName
,
LPBYTE
pEnumValues
,
DWORD
cbEnumValues
,
LPDWORD
pcbEnumValues
,
LPDWORD
pnEnumValues
);
#define EnumPrinterDataEx WINELIB_NAME_AW(EnumPrinterDataEx)
#ifdef __cplusplus
...
...
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