Commit 58d1e2fa authored by Detlef Riekenberg's avatar Detlef Riekenberg Committed by Alexandre Julliard

winspool: Support the local computername as servername for OpenPrinter.

parent c3dc692b
......@@ -115,6 +115,7 @@ typedef struct {
typedef struct {
LPWSTR name;
LPWSTR printername;
jobqueue_t *queue;
started_doc_t *doc;
} opened_printer_t;
......@@ -1297,6 +1298,68 @@ static DWORD get_ports_from_all_monitors(DWORD level, LPBYTE pPorts, DWORD cbBuf
}
/******************************************************************
* get_servername_from_name (internal)
*
* for an external server, a copy of the serverpart from the full name is returned
*
*/
static LPWSTR get_servername_from_name(LPCWSTR name)
{
LPWSTR server;
LPWSTR ptr;
WCHAR buffer[MAX_PATH];
DWORD len;
if (name == NULL) return NULL;
if ((name[0] != '\\') || (name[1] != '\\')) return NULL;
server = strdupW(&name[2]); /* skip over both backslash */
if (server == NULL) return NULL;
/* strip '\' and the printername */
ptr = strchrW(server, '\\');
if (ptr) ptr[0] = '\0';
TRACE("found %s\n", debugstr_w(server));
len = sizeof(buffer)/sizeof(buffer[0]);
if (GetComputerNameW(buffer, &len)) {
if (lstrcmpW(buffer, server) == 0) {
/* The requested Servername is our computername */
HeapFree(GetProcessHeap(), 0, server);
return NULL;
}
}
return server;
}
/******************************************************************
* get_basename_from_name (internal)
*
* skip over the serverpart from the full name
*
*/
static LPCWSTR get_basename_from_name(LPCWSTR name)
{
if (name == NULL) return NULL;
if ((name[0] == '\\') && (name[1] == '\\')) {
/* skip over the servername and search for the following '\' */
name = strchrW(&name[2], '\\');
if ((name) && (name[1])) {
/* found a seperator ('\') followed by a name:
skip over the seperator and return the rest */
name++;
}
else
{
/* no basename present (we found only a servername) */
return NULL;
}
}
return name;
}
/******************************************************************
* get_opened_printer_entry
* Get the first place empty in the opened printer table
*
......@@ -1308,6 +1371,27 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
UINT_PTR handle = nb_printer_handles, i;
jobqueue_t *queue = NULL;
opened_printer_t *printer = NULL;
LPWSTR servername;
LPCWSTR printername;
HKEY hkeyPrinters;
HKEY hkeyPrinter;
servername = get_servername_from_name(name);
if (servername) {
FIXME("server %s not supported\n", debugstr_w(servername));
HeapFree(GetProcessHeap(), 0, servername);
SetLastError(ERROR_INVALID_PRINTER_NAME);
return NULL;
}
printername = get_basename_from_name(name);
if (name != printername) TRACE("converted %s to %s\n", debugstr_w(name), debugstr_w(printername));
/* an empty printername is invalid */
if (printername && (!printername[0])) {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
EnterCriticalSection(&printer_handles_cs);
......@@ -1350,13 +1434,39 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
goto end;
}
if(name) {
printer->name = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1) * sizeof(WCHAR));
if (!printer->name) {
/* clone the base name. This is NULL for the printserver */
printer->printername = strdupW(printername);
/* clone the full name */
printer->name = strdupW(name);
if (name && (!printer->name)) {
handle = 0;
goto end;
}
if (printername) {
/* Does the Printer exist? */
if (RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) != ERROR_SUCCESS) {
ERR("Can't create Printers key\n");
handle = 0;
goto end;
}
if (RegOpenKeyW(hkeyPrinters, printername, &hkeyPrinter) != ERROR_SUCCESS) {
WARN("Printer not found in Registry: '%s'\n", debugstr_w(printername));
RegCloseKey(hkeyPrinters);
SetLastError(ERROR_INVALID_PRINTER_NAME);
handle = 0;
goto end;
}
strcpyW(printer->name, name);
RegCloseKey(hkeyPrinter);
RegCloseKey(hkeyPrinters);
}
else
{
TRACE("using the local printserver\n");
}
if(queue)
......@@ -1378,7 +1488,8 @@ static HANDLE get_opened_printer_entry(LPCWSTR name, LPPRINTER_DEFAULTSW pDefaul
end:
LeaveCriticalSection(&printer_handles_cs);
if (!handle && printer) {
/* Something Failed: Free the Buffers */
/* Something failed: Free all resources */
HeapFree(GetProcessHeap(), 0, printer->printername);
HeapFree(GetProcessHeap(), 0, printer->name);
if (!queue) HeapFree(GetProcessHeap(), 0, printer->queue);
HeapFree(GetProcessHeap(), 0, printer);
......@@ -1812,8 +1923,6 @@ BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter,
*/
BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAULTSW pDefault)
{
HKEY hkeyPrinters = NULL;
HKEY hkeyPrinter = NULL;
TRACE("(%s, %p, %p)\n", debugstr_w(lpPrinterName), phPrinter, pDefault);
if (pDefault) {
......@@ -1821,25 +1930,6 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAU
debugstr_w(pDefault->pDatatype), pDefault->pDevMode, pDefault->DesiredAccess);
}
if(lpPrinterName != NULL)
{
/* Check any Printer exists */
if(RegCreateKeyW(HKEY_LOCAL_MACHINE, PrintersW, &hkeyPrinters) != ERROR_SUCCESS) {
ERR("Can't create Printers key\n");
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
if((lpPrinterName[0] == '\0') || /* explicitly exclude "" */
(RegOpenKeyW(hkeyPrinters, lpPrinterName, &hkeyPrinter) != ERROR_SUCCESS)) {
WARN("Printer not found in Registry: '%s'\n", debugstr_w(lpPrinterName));
RegCloseKey(hkeyPrinters);
SetLastError(ERROR_INVALID_PRINTER_NAME);
return FALSE;
}
RegCloseKey(hkeyPrinter);
RegCloseKey(hkeyPrinters);
}
if(!phPrinter) {
/* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */
SetLastError(ERROR_INVALID_PARAMETER);
......@@ -1848,6 +1938,7 @@ BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter, LPPRINTER_DEFAU
/* Get the unique handle of the printer or Printserver */
*phPrinter = get_opened_printer_entry(lpPrinterName, pDefault);
TRACE("returning %d with 0x%x and %p\n", *phPrinter != NULL, GetLastError(), *phPrinter);
return (*phPrinter != 0);
}
......@@ -2788,6 +2879,7 @@ BOOL WINAPI ClosePrinter(HANDLE hPrinter)
}
HeapFree(GetProcessHeap(), 0, printer->queue);
}
HeapFree(GetProcessHeap(), 0, printer->printername);
HeapFree(GetProcessHeap(), 0, printer->name);
HeapFree(GetProcessHeap(), 0, printer);
printer_handles[i - 1] = NULL;
......
......@@ -1294,11 +1294,9 @@ static void test_OpenPrinter(void)
hprinter = (HANDLE) 0xdeadbeef;
SetLastError(0xdeadbeef);
res = OpenPrinter(local_server, &hprinter, NULL);
todo_wine {
ok(res || (!res && GetLastError() == ERROR_INVALID_PARAMETER),
"returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n",
res, GetLastError());
}
if(res) ClosePrinter(hprinter);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment