Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
29444b4a
Commit
29444b4a
authored
Aug 15, 2007
by
Detlef Riekenberg
Committed by
Alexandre Julliard
Aug 16, 2007
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winspool: Implement AddPrinterDriverExW.
parent
931714e7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
257 additions
and
9 deletions
+257
-9
info.c
dlls/winspool.drv/info.c
+257
-9
No files found.
dlls/winspool.drv/info.c
View file @
29444b4a
...
...
@@ -86,6 +86,14 @@ static CRITICAL_SECTION printer_handles_cs = { &printer_handles_cs_debug, -1, 0,
/* ############################### */
typedef
struct
{
WCHAR
src
[
MAX_PATH
+
MAX_PATH
];
WCHAR
dst
[
MAX_PATH
+
MAX_PATH
];
DWORD
srclen
;
DWORD
dstlen
;
DWORD
copyflags
;
}
apd_data_t
;
typedef
struct
{
struct
list
entry
;
LPWSTR
name
;
LPWSTR
dllname
;
...
...
@@ -227,6 +235,7 @@ static const WCHAR PrinterDriverDataW[] = {'P','r','i','n','t','e','r','D','r','
static
const
WCHAR
ProviderW
[]
=
{
'P'
,
'r'
,
'o'
,
'v'
,
'i'
,
'd'
,
'e'
,
'r'
,
0
};
static
const
WCHAR
Separator_FileW
[]
=
{
'S'
,
'e'
,
'p'
,
'a'
,
'r'
,
'a'
,
't'
,
'o'
,
'r'
,
' '
,
'F'
,
'i'
,
'l'
,
'e'
,
0
};
static
const
WCHAR
Share_NameW
[]
=
{
'S'
,
'h'
,
'a'
,
'r'
,
'e'
,
' '
,
'N'
,
'a'
,
'm'
,
'e'
,
0
};
static
const
WCHAR
VersionW
[]
=
{
'V'
,
'e'
,
'r'
,
's'
,
'i'
,
'o'
,
'n'
,
0
};
static
const
WCHAR
WinPrintW
[]
=
{
'W'
,
'i'
,
'n'
,
'P'
,
'r'
,
'i'
,
'n'
,
't'
,
0
};
static
const
WCHAR
deviceW
[]
=
{
'd'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
0
};
static
const
WCHAR
devicesW
[]
=
{
'd'
,
'e'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
0
};
...
...
@@ -343,8 +352,82 @@ static LPSTR strdupWtoA( LPCWSTR str )
return
ret
;
}
/* Returns the number of bytes in an ansi \0\0 terminated string (multi_sz).
The result includes all \0s (specifically the last two). */
/******************************************************************
* apd_copyfile [internal]
*
* Copy a file from the driverdirectory to the versioned directory
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
*/
static
BOOL
apd_copyfile
(
LPWSTR
filename
,
apd_data_t
*
apd
)
{
LPWSTR
ptr
;
LPWSTR
srcname
;
DWORD
res
;
apd
->
src
[
apd
->
srclen
]
=
'\0'
;
apd
->
dst
[
apd
->
dstlen
]
=
'\0'
;
if
(
!
filename
||
!
filename
[
0
])
{
/* nothing to copy */
return
TRUE
;
}
ptr
=
strrchrW
(
filename
,
'\\'
);
if
(
ptr
)
{
ptr
++
;
}
else
{
ptr
=
filename
;
}
if
(
apd
->
copyflags
&
APD_COPY_FROM_DIRECTORY
)
{
/* we have an absolute Path */
srcname
=
filename
;
}
else
{
srcname
=
apd
->
src
;
lstrcatW
(
srcname
,
ptr
);
}
lstrcatW
(
apd
->
dst
,
ptr
);
TRACE
(
"%s => %s
\n
"
,
debugstr_w
(
filename
),
debugstr_w
(
apd
->
dst
));
/* FIXME: handle APD_COPY_NEW_FILES */
res
=
CopyFileW
(
srcname
,
apd
->
dst
,
FALSE
);
TRACE
(
"got %u with %u
\n
"
,
res
,
GetLastError
());
/* FIXME: install of wineps.drv must be fixed, before we return the real result
return res;
*/
return
TRUE
;
}
/******************************************************************
* 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).
*/
static
int
multi_sz_lenW
(
const
WCHAR
*
str
)
{
const
WCHAR
*
ptr
=
str
;
if
(
!
str
)
return
0
;
do
{
ptr
+=
lstrlenW
(
ptr
)
+
1
;
}
while
(
*
ptr
);
return
(
ptr
-
str
+
1
)
*
sizeof
(
WCHAR
);
}
/* ################################ */
static
int
multi_sz_lenA
(
const
char
*
str
)
{
const
char
*
ptr
=
str
;
...
...
@@ -6375,15 +6458,180 @@ BOOL WINAPI AddPrinterConnectionW( LPWSTR pName )
}
/******************************************************************************
* AddPrinterDriverExW (WINSPOOL.@)
* AddPrinterDriverExW (WINSPOOL.@)
*
* Install a Printer Driver with the Option to upgrade / downgrade the Files
*
* PARAMS
* pName [I] Servername or NULL (local Computer)
* level [I] Level for the supplied DRIVER_INFO_*W struct
* pDriverInfo [I] PTR to DRIVER_INFO_*W struct with the Driver Parameter
* dwFileCopyFlags [I] How to Copy / Upgrade / Downgrade the needed Files
*
* RESULTS
* Success: TRUE
* Failure: FALSE
*
*/
BOOL
WINAPI
AddPrinterDriverExW
(
LPWSTR
pName
,
DWORD
Level
,
LPBYTE
pDriverInfo
,
DWORD
dwFileCopyFlags
)
BOOL
WINAPI
AddPrinterDriverExW
(
LPWSTR
pName
,
DWORD
level
,
LPBYTE
pDriverInfo
,
DWORD
dwFileCopyFlags
)
{
FIXME
(
"%s %d %p %d
\n
"
,
debugstr_w
(
pName
),
Level
,
pDriverInfo
,
dwFileCopyFlags
);
SetLastError
(
ERROR_PRINTER_DRIVER_BLOCKED
);
return
FALSE
;
const
printenv_t
*
env
;
apd_data_t
apd
;
DRIVER_INFO_8W
di
;
LPWSTR
ptr
;
HKEY
hroot
;
HKEY
hdrv
;
DWORD
disposition
;
DWORD
len
;
LONG
lres
;
TRACE
(
"(%s, %d, %p, 0x%x)
\n
"
,
debugstr_w
(
pName
),
level
,
pDriverInfo
,
dwFileCopyFlags
);
if
(
level
<
2
||
level
==
5
||
level
==
7
||
level
>
8
)
{
SetLastError
(
ERROR_INVALID_LEVEL
);
return
FALSE
;
}
if
(
!
pDriverInfo
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
if
((
dwFileCopyFlags
&
~
APD_COPY_FROM_DIRECTORY
)
!=
APD_COPY_ALL_FILES
)
{
FIXME
(
"Flags 0x%x ignored (Fallback to APD_COPY_ALL_FILES)
\n
"
,
dwFileCopyFlags
&
~
APD_COPY_FROM_DIRECTORY
);
}
ptr
=
get_servername_from_name
(
pName
);
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
if
(
ptr
)
{
FIXME
(
"not suported for server: %s
\n
"
,
debugstr_w
(
pName
));
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
}
/* we need to set all entries in the Registry, independent from the Level of
DRIVER_INFO, that the caller supplied */
ZeroMemory
(
&
di
,
sizeof
(
di
));
if
(
pDriverInfo
&&
(
level
<
(
sizeof
(
di_sizeof
)
/
sizeof
(
di_sizeof
[
0
]))))
{
memcpy
(
&
di
,
pDriverInfo
,
di_sizeof
[
level
]);
}
/* dump the most used infos */
TRACE
(
"%p: .cVersion : 0x%x/%d
\n
"
,
pDriverInfo
,
di
.
cVersion
,
di
.
cVersion
);
TRACE
(
"%p: .pName : %s
\n
"
,
di
.
pName
,
debugstr_w
(
di
.
pName
));
TRACE
(
"%p: .pEnvironment: %s
\n
"
,
di
.
pEnvironment
,
debugstr_w
(
di
.
pEnvironment
));
TRACE
(
"%p: .pDriverPath : %s
\n
"
,
di
.
pDriverPath
,
debugstr_w
(
di
.
pDriverPath
));
TRACE
(
"%p: .pDataFile : %s
\n
"
,
di
.
pDataFile
,
debugstr_w
(
di
.
pDataFile
));
TRACE
(
"%p: .pConfigFile : %s
\n
"
,
di
.
pConfigFile
,
debugstr_w
(
di
.
pConfigFile
));
TRACE
(
"%p: .pHelpFile : %s
\n
"
,
di
.
pHelpFile
,
debugstr_w
(
di
.
pHelpFile
));
/* dump only the first of the additional Files */
TRACE
(
"%p: .pDependentFiles: %s
\n
"
,
di
.
pDependentFiles
,
debugstr_w
(
di
.
pDependentFiles
));
/* check environment */
env
=
validate_envW
(
di
.
pEnvironment
);
if
(
env
==
NULL
)
return
FALSE
;
/* ERROR_INVALID_ENVIRONMENT */
/* fill the copy-data / get the driverdir */
len
=
sizeof
(
apd
.
src
)
-
sizeof
(
Version3_SubdirW
)
-
sizeof
(
WCHAR
);
if
(
!
GetPrinterDriverDirectoryW
(
NULL
,
(
LPWSTR
)
env
->
envname
,
1
,
(
LPBYTE
)
apd
.
src
,
len
,
&
len
))
{
/* Should never Fail */
return
FALSE
;
}
memcpy
(
apd
.
dst
,
apd
.
src
,
len
);
lstrcatW
(
apd
.
src
,
backslashW
);
apd
.
srclen
=
lstrlenW
(
apd
.
src
);
lstrcatW
(
apd
.
dst
,
env
->
versionsubdir
);
lstrcatW
(
apd
.
dst
,
backslashW
);
apd
.
dstlen
=
lstrlenW
(
apd
.
dst
);
apd
.
copyflags
=
dwFileCopyFlags
;
CreateDirectoryW
(
apd
.
src
,
NULL
);
CreateDirectoryW
(
apd
.
dst
,
NULL
);
/* Fill the Registry for the Driver */
hroot
=
WINSPOOL_OpenDriverReg
(
env
->
envname
,
TRUE
);
if
(
!
hroot
)
{
ERR
(
"Can't create Drivers key
\n
"
);
return
FALSE
;
}
if
((
lres
=
RegCreateKeyExW
(
hroot
,
di
.
pName
,
0
,
NULL
,
REG_OPTION_NON_VOLATILE
,
KEY_WRITE
|
KEY_QUERY_VALUE
,
NULL
,
&
hdrv
,
&
disposition
))
!=
ERROR_SUCCESS
)
{
ERR
(
"can't create driver %s: %u
\n
"
,
debugstr_w
(
di
.
pName
),
lres
);
RegCloseKey
(
hroot
);
SetLastError
(
lres
);
return
FALSE
;
}
RegCloseKey
(
hroot
);
if
(
disposition
==
REG_OPENED_EXISTING_KEY
)
{
TRACE
(
"driver %s already installed
\n
"
,
debugstr_w
(
di
.
pName
));
RegCloseKey
(
hdrv
);
SetLastError
(
ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
);
return
FALSE
;
}
/* Verified with the Adobe PS Driver, that w2k does not use di.Version */
RegSetValueExW
(
hdrv
,
VersionW
,
0
,
REG_DWORD
,
(
LPBYTE
)
&
env
->
driverversion
,
sizeof
(
DWORD
));
RegSetValueExW
(
hdrv
,
DriverW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pDriverPath
,
(
lstrlenW
(
di
.
pDriverPath
)
+
1
)
*
sizeof
(
WCHAR
));
apd_copyfile
(
di
.
pDriverPath
,
&
apd
);
RegSetValueExW
(
hdrv
,
Data_FileW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pDataFile
,
(
lstrlenW
(
di
.
pDataFile
)
+
1
)
*
sizeof
(
WCHAR
));
apd_copyfile
(
di
.
pDataFile
,
&
apd
);
RegSetValueExW
(
hdrv
,
Configuration_FileW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pConfigFile
,
(
lstrlenW
(
di
.
pConfigFile
)
+
1
)
*
sizeof
(
WCHAR
));
apd_copyfile
(
di
.
pConfigFile
,
&
apd
);
/* settings for level 3 */
RegSetValueExW
(
hdrv
,
Help_FileW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pHelpFile
,
di
.
pHelpFile
?
(
lstrlenW
(
di
.
pHelpFile
)
+
1
)
*
sizeof
(
WCHAR
)
:
0
);
apd_copyfile
(
di
.
pHelpFile
,
&
apd
);
ptr
=
di
.
pDependentFiles
;
RegSetValueExW
(
hdrv
,
Dependent_FilesW
,
0
,
REG_MULTI_SZ
,
(
LPBYTE
)
di
.
pDependentFiles
,
di
.
pDependentFiles
?
multi_sz_lenW
(
di
.
pDependentFiles
)
:
0
);
while
((
ptr
!=
NULL
)
&&
(
ptr
[
0
]))
{
if
(
apd_copyfile
(
ptr
,
&
apd
))
{
ptr
+=
lstrlenW
(
ptr
)
+
1
;
}
else
{
WARN
(
"Failed to copy %s
\n
"
,
debugstr_w
(
ptr
));
ptr
=
NULL
;
}
}
/* The language-Monitor was already copied to "%SystemRoot%\system32" */
RegSetValueExW
(
hdrv
,
MonitorW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pMonitorName
,
di
.
pMonitorName
?
(
lstrlenW
(
di
.
pMonitorName
)
+
1
)
*
sizeof
(
WCHAR
)
:
0
);
RegSetValueExW
(
hdrv
,
DatatypeW
,
0
,
REG_SZ
,
(
LPBYTE
)
di
.
pDefaultDataType
,
di
.
pDefaultDataType
?
(
lstrlenW
(
di
.
pDefaultDataType
)
+
1
)
*
sizeof
(
WCHAR
)
:
0
);
/* settings for level 4 */
RegSetValueExW
(
hdrv
,
Previous_NamesW
,
0
,
REG_MULTI_SZ
,
(
LPBYTE
)
di
.
pszzPreviousNames
,
di
.
pszzPreviousNames
?
multi_sz_lenW
(
di
.
pszzPreviousNames
)
:
0
);
if
(
level
>
5
)
FIXME
(
"level %u for Driver %s is incomplete
\n
"
,
level
,
debugstr_w
(
di
.
pName
));
RegCloseKey
(
hdrv
);
FIXME
(
"### DrvDriverEvent(...,DRIVEREVENT_INITIALIZE) not implemented yet
\n
"
);
TRACE
(
"=> TRUE with %u
\n
"
,
GetLastError
());
return
TRUE
;
}
/******************************************************************************
...
...
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