diff --git a/win32ss/printing/base/spoolsv/printers.c b/win32ss/printing/base/spoolsv/printers.c index b1eb9070a06..1aa41413b59 100644 --- a/win32ss/printing/base/spoolsv/printers.c +++ b/win32ss/printing/base/spoolsv/printers.c @@ -30,8 +30,23 @@ _RpcAbortPrinter(WINSPOOL_PRINTER_HANDLE hPrinter) DWORD _RpcAddPrinter(WINSPOOL_HANDLE pName, WINSPOOL_PRINTER_CONTAINER* pPrinterContainer, WINSPOOL_DEVMODE_CONTAINER* pDevModeContainer, WINSPOOL_SECURITY_CONTAINER* pSecurityContainer, WINSPOOL_PRINTER_HANDLE* pHandle) { - UNIMPLEMENTED; - return ERROR_INVALID_FUNCTION; + DWORD dwErrorCode; + + dwErrorCode = RpcImpersonateClient(NULL); + if (dwErrorCode != ERROR_SUCCESS) + { + ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); + return dwErrorCode; + } + + *pHandle = AddPrinterW(pName,pPrinterContainer->Level,(LPBYTE)pPrinterContainer->PrinterInfo.pPrinterInfo2); + if (!*pHandle) + goto End; +End: + if(dwErrorCode) + dwErrorCode = GetLastError(); + RpcRevertToSelf(); + return dwErrorCode; } DWORD diff --git a/win32ss/printing/base/winspool/printers.c b/win32ss/printing/base/winspool/printers.c index 6011571d341..83222a1d4b9 100644 --- a/win32ss/printing/base/winspool/printers.c +++ b/win32ss/printing/base/winspool/printers.c @@ -215,6 +215,7 @@ AddPrinterA(PSTR pName, DWORD Level, PBYTE pPrinter) PWSTR pwszPrintProcessor = NULL; PWSTR pwszDatatype = NULL; PWSTR pwszParameters = NULL; + PWSTR pPrintProcessor = NULL; PDEVMODEW pdmw = NULL; TRACE("AddPrinterA(%s, %d, %p)\n", debugstr_a(pName), Level, pPrinter); @@ -288,6 +289,11 @@ AddPrinterA(PSTR pName, DWORD Level, PBYTE pPrinter) pwszPrinterName = AsciiToUnicode(&usBuffer, ppi2a->pPrinterName); if (!(ppi2w->pPrinterName = pwszPrinterName)) goto Cleanup; } + if (ppi2a->pPrintProcessor) + { + pPrintProcessor = AsciiToUnicode(&usBuffer, ppi2a->pPrintProcessor); + if (!(ppi2w->pPrintProcessor = pPrintProcessor)) goto Cleanup; + } ret = AddPrinterW(pwstrNameW, Level, (LPBYTE)ppi2w); diff --git a/win32ss/printing/providers/localspl/main.c b/win32ss/printing/providers/localspl/main.c index a8d6118e1bc..b916e1e74b5 100644 --- a/win32ss/printing/providers/localspl/main.c +++ b/win32ss/printing/providers/localspl/main.c @@ -36,7 +36,7 @@ static const PRINTPROVIDOR _PrintProviderFunctions = { LocalSetJob, // fpSetJob LocalGetJob, // fpGetJob LocalEnumJobs, // fpEnumJobs - NULL, // fpAddPrinter + LocalAddPrinter, // fpAddPrinter NULL, // fpDeletePrinter NULL, // fpSetPrinter LocalGetPrinter, // fpGetPrinter diff --git a/win32ss/printing/providers/localspl/precomp.h b/win32ss/printing/providers/localspl/precomp.h index 20ecdec0ba0..2ec1015bf99 100644 --- a/win32ss/printing/providers/localspl/precomp.h +++ b/win32ss/printing/providers/localspl/precomp.h @@ -342,6 +342,7 @@ BOOL WINAPI LocalWritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD BOOL WINAPI LocalEndPagePrinter(HANDLE hPrinter); BOOL WINAPI LocalEndDocPrinter(HANDLE hPrinter); BOOL WINAPI LocalClosePrinter(HANDLE hPrinter); +HANDLE WINAPI LocalAddPrinter(LPWSTR pName, DWORD level, LPBYTE pPrinterInfo); VOID BroadcastChange(PLOCAL_HANDLE pHandle); // printingthread.c diff --git a/win32ss/printing/providers/localspl/printers.c b/win32ss/printing/providers/localspl/printers.c index 9bab1ba22ff..ee8b88804ce 100644 --- a/win32ss/printing/providers/localspl/printers.c +++ b/win32ss/printing/providers/localspl/printers.c @@ -213,8 +213,13 @@ InitializePrinterList(VOID) pPort = FindPort(pwszPort); if (!pPort) { - ERR("Invalid Port \"%S\" for Printer \"%S\"!\n", pwszPort, wszPrinterName); - continue; + //FIXME - virtual port - we create it but monitor is neecessary to make the "Print" button clickable and not hardcoding Ready status - in Windows at least + if(CreatePortEntry(pwszPort,NULL)) + pPort = FindPort(pwszPort); + if(!pPort){ + ERR("Invalid Port \"%S\" for Printer \"%S\"!\n", pwszPort, wszPrinterName); + continue; + } } // Create a new LOCAL_PRINTER structure for it. @@ -1175,9 +1180,9 @@ _LocalOpenPrinterHandle(PWSTR pwszPrinterName, PWSTR pwszJobParameter, PHANDLE p // Check if a DevMode was given, otherwise use the default. if (pDefault && pDefault->pDevMode) pPrinterHandle->pDevMode = DuplicateDevMode(pDefault->pDevMode); - else + else{ pPrinterHandle->pDevMode = DuplicateDevMode(pPrinter->pDefaultDevMode); - + } // Check if the caller wants a handle to an existing Print Job. if (pwszJobParameter) { @@ -1227,7 +1232,6 @@ _LocalOpenPrinterHandle(PWSTR pwszPrinterName, PWSTR pwszJobParameter, PHANDLE p // This prevents the caller from doing further StartDocPrinter, WritePrinter, etc. calls on it. pPrinterHandle->pJob = pJob; } - // Make the generic handle a Printer handle. pHandle->HandleType = HandleType_Printer; pHandle->pSpecificHandle = pPrinterHandle; @@ -1405,7 +1409,7 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef PWSTR pwszSecondParameter; WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1]; - TRACE("LocalOpenPrinter(%S, %p, %p)\n", lpPrinterName, phPrinter, pDefault); + ERR("LocalOpenPrinter(%S, %p, %p)\n", lpPrinterName, phPrinter, pDefault); ASSERT(phPrinter); *phPrinter = NULL; @@ -1994,3 +1998,88 @@ LocalClosePrinter(HANDLE hPrinter) FIXME("LocalClosePrinter 3\n"); return TRUE; } + +HANDLE WINAPI +LocalAddPrinter(LPWSTR pName, DWORD level, LPBYTE pPrinterInfo){ + BOOL bRet; + DWORD dwErrorCode; + LOCAL_HANDLE hLocalPrinter; + HANDLE hPrinter; + HKEY hPrinterKey = NULL; + PLOCAL_PRINTER pLocalPrinter; + + PPRINTER_INFO_2W pInfo = (PPRINTER_INFO_2W)pPrinterInfo; + + if(!pInfo->pDatatype) + pInfo->pDatatype = L"RAW"; + + if(!pInfo->pDevMode){ + pInfo->pDevMode = DllAllocSplMem(sizeof(DEVMODEW)); + wcscpy(pInfo->pDevMode->dmDeviceName,pInfo->pPrinterName); + pInfo->pDevMode->dmSize = sizeof(DEVMODEW); + } + if(!pInfo->pLocation) + pInfo->pLocation = L""; + + if(!pInfo->pPrinterName) + goto End; + dwErrorCode = RegCreateKeyEx(hPrintersKey,pInfo->pPrinterName,0,NULL,0,KEY_SET_VALUE|KEY_CREATE_SUB_KEY,NULL,&hPrinterKey,NULL); + if(dwErrorCode) + goto End; + + if(!pInfo->pPortName) + goto End; + dwErrorCode = RegSetValueEx(hPrinterKey,L"Port",0,REG_SZ,(PBYTE)pInfo->pPortName,(wcslen(pInfo->pPortName)+1)*sizeof(WCHAR)); + if(dwErrorCode) + goto End; + + if(!pInfo->pPrintProcessor) + goto End; + dwErrorCode = RegSetValueEx(hPrinterKey,L"Print Processor",0,REG_SZ,(PBYTE)pInfo->pPrintProcessor,(wcslen(pInfo->pPrintProcessor) + 1) * sizeof(WCHAR)); + if(dwErrorCode) + goto End; + + if(!pInfo->pDriverName) + goto End; + dwErrorCode = RegSetValueEx(hPrinterKey,L"Printer Driver",0,REG_SZ,(PBYTE)pInfo->pDriverName,(wcslen(pInfo->pDriverName)+1)*sizeof(WCHAR)); + if(dwErrorCode) + goto End; + + if(pInfo->pDevMode) + RegSetValueEx(hPrinterKey,L"Default DevMode",0,REG_BINARY,(PBYTE)pInfo->pDevMode,sizeof(DEVMODEW)); + if(pInfo->pComment) + RegSetValueEx(hPrinterKey,L"Description",0,REG_SZ,(PBYTE)pInfo->pComment,(wcslen(pInfo->pComment)+1)*sizeof(WCHAR)); + + RegSetValueEx(hPrinterKey,L"Location",0,REG_SZ,(PBYTE)pInfo->pLocation,(wcslen(pInfo->pLocation)+1)*sizeof(WCHAR)); + RegSetValueEx(hPrinterKey,L"Status",0,REG_DWORD,(PBYTE)&(pInfo->Status),sizeof(DWORD)); + RegSetValueEx(hPrinterKey,L"Attributes",0,REG_DWORD,(PBYTE)&(pInfo->Attributes),sizeof(DWORD)); + RegSetValueEx(hPrinterKey,L"Datatype",0,REG_SZ,(PBYTE)pInfo->pDatatype,(wcslen(pInfo->pDatatype)+1)*sizeof(WCHAR)); + RegSetValueEx(hPrinterKey,L"Name",0,REG_SZ,(PBYTE)pInfo->pPrinterName,(wcslen(pInfo->pPrinterName)+1)*sizeof(WCHAR)); + + RegCloseKey(hPrintKey); + + pLocalPrinter = DllAllocSplMem(sizeof(LOCAL_PRINTER)); + pLocalPrinter->pwszPrinterName = pInfo->pPrinterName; + pLocalPrinter->dwAttributes = pInfo->Attributes; + pLocalPrinter->pwszLocation = pInfo->pLocation; + pLocalPrinter->pwszDescription = pInfo->pComment; + pLocalPrinter->pwszDefaultDatatype = pInfo->pDatatype; + pLocalPrinter->pDefaultDevMode = pInfo->pDevMode; + pLocalPrinter->pPrintProcessor = FindPrintProcessor(pInfo->pPrintProcessor); + pLocalPrinter->pPort = FindPort(pInfo->pPortName); + + InitializePrinterJobList(pLocalPrinter); + + InsertElementSkiplist(&PrinterList, pLocalPrinter); + + hLocalPrinter.pSpecificHandle = pPrinterInfo; + hLocalPrinter.HandleType = HandleType_Printer; + + bRet = LocalOpenPrinter(pInfo->pPrinterName,&hPrinter,NULL); + +End: + if(hPrinterKey) + RegCloseKey(hPrintKey); + SetLastError(dwErrorCode); + return hPrinter; +}