1
0
mirror of https://github.com/UzixLS/KernelEx.git synced 2025-07-18 23:11:19 +03:00
Files
KernelEx/apilibs/kexbasen/winspool/uniwinspool.c
2018-11-03 16:22:27 +03:00

368 lines
10 KiB
C
Executable File

/*
* KernelEx
* Copyright (C) 2010, Tihiy
* Copyright (C) 2010, Xeno86
*
* Parts adapted from WINE Project.
* Copyright 1996 John Harvey
* Copyright 1998 Andreas Mohr
* Copyright 1999 Klaas van Gend
* Copyright 1999, 2000 Huw D M Davies
* Copyright 2001 Marcus Meissner
* Copyright 2005-2009 Detlef Riekenberg
*
* This file is part of KernelEx source code.
*
* KernelEx is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation; version 2 of the License.
*
* KernelEx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Make; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include "common.h"
#include "unifwd.h"
#include <winspool.h>
static const DWORD pi_sizeof[] = {0, sizeof(PRINTER_INFO_1), sizeof(PRINTER_INFO_2),
sizeof(PRINTER_INFO_3), sizeof(PRINTER_INFO_4),
sizeof(PRINTER_INFO_5)};
/***********************************************************
* DEVMODEdupWtoA
* Creates an ansi copy of supplied devmode
*/
static LPDEVMODEW DEVMODEdupAtoW(const DEVMODEA *dmA)
{
LPDEVMODEW dmW;
WORD size;
if (!dmA) return NULL;
size = dmA->dmSize + CCHDEVICENAME +
((dmA->dmSize > FIELD_OFFSET(DEVMODEA, dmFormName)) ? CCHFORMNAME : 0);
dmW = (LPDEVMODEW) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + dmA->dmDriverExtra);
if (!dmW) return NULL;
MultiByteToWideChar(CP_ACP, 0, (LPSTR)dmA->dmDeviceName, -1,
dmW->dmDeviceName, CCHDEVICENAME);
if (FIELD_OFFSET(DEVMODEA, dmFormName) >= dmA->dmSize) {
memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion,
dmA->dmSize - FIELD_OFFSET(DEVMODEA, dmSpecVersion));
}
else
{
memcpy(&dmW->dmSpecVersion, &dmA->dmSpecVersion,
FIELD_OFFSET(DEVMODEA, dmFormName) - FIELD_OFFSET(DEVMODEA, dmSpecVersion));
MultiByteToWideChar(CP_ACP, 0, (LPSTR)dmA->dmFormName, -1,
dmW->dmFormName, CCHFORMNAME);
memcpy(&dmW->dmLogPixels, &dmA->dmLogPixels, dmA->dmSize - FIELD_OFFSET(DEVMODEA, dmLogPixels));
}
dmW->dmSize = size;
memcpy((char *)dmW + dmW->dmSize, (const char *)dmA + dmA->dmSize, dmA->dmDriverExtra);
return dmW;
}
static void convert_printerinfo_WtoA(LPBYTE outW, LPBYTE pPrintersA,
DWORD level, DWORD outlen, DWORD numentries)
{
DWORD id = 0;
LPWSTR ptr;
INT len;
len = pi_sizeof[level] * numentries;
ptr = (LPWSTR) (outW + len);
/* first structures */
outlen -= len;
/* then text in unicode (we count in wchars from now on) */
outlen /= 2;
/* copy the numbers of all PRINTER_INFO_* first */
memcpy(outW, pPrintersA, len);
while (id < numentries) {
switch (level) {
case 1:
{
PRINTER_INFO_1W * piW = (PRINTER_INFO_1W *) outW;
PRINTER_INFO_1A * piA = (PRINTER_INFO_1A *) pPrintersA;
if (piA->pDescription) {
piW->pDescription = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pDescription, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pName) {
piW->pName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pComment) {
piW->pComment = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pComment, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
break;
}
case 2:
{
PRINTER_INFO_2W * piW = (PRINTER_INFO_2W *) outW;
PRINTER_INFO_2A * piA = (PRINTER_INFO_2A *) pPrintersA;
LPDEVMODEW dmW;
if (piA->pServerName) {
piW->pServerName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pServerName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pPrinterName) {
piW->pPrinterName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPrinterName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pShareName) {
piW->pShareName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pShareName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pPortName) {
piW->pPortName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPortName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pDriverName) {
piW->pDriverName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pDriverName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pComment) {
piW->pComment = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pComment, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pLocation) {
piW->pLocation = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pLocation, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
dmW = DEVMODEdupAtoW(piA->pDevMode);
if (dmW) {
/* align DEVMODEA to a DWORD boundary */
len = (2 - ( (DWORD_PTR) ptr & 1)) & 1;
ptr += len;
outlen -= len;
piW->pDevMode = (LPDEVMODEW) ptr;
len = dmW->dmSize + dmW->dmDriverExtra;
memcpy(ptr, dmW, len);
HeapFree(GetProcessHeap(), 0, dmW);
ptr += len/2+1;
outlen -= len/2+1;
}
if (piA->pSepFile) {
piW->pSepFile = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pSepFile, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pPrintProcessor) {
piW->pPrintProcessor = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPrintProcessor, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pDatatype) {
piW->pDatatype = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pDatatype, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pParameters) {
piW->pParameters = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pParameters, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pSecurityDescriptor) {
piW->pSecurityDescriptor = NULL;
}
break;
}
case 4:
{
PRINTER_INFO_4W * piW = (PRINTER_INFO_4W *) outW;
PRINTER_INFO_4A * piA = (PRINTER_INFO_4A *) pPrintersA;
if (piA->pPrinterName) {
piW->pPrinterName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPrinterName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pServerName) {
piW->pServerName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pServerName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
break;
}
case 5:
{
PRINTER_INFO_5W * piW = (PRINTER_INFO_5W *) outW;
PRINTER_INFO_5A * piA = (PRINTER_INFO_5A *) pPrintersA;
if (piA->pPrinterName) {
piW->pPrinterName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPrinterName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
if (piA->pPortName) {
piW->pPortName = ptr;
len = MultiByteToWideChar(CP_ACP, 0, piA->pPortName, -1,
ptr, outlen);
ptr += len;
outlen -= len;
}
break;
}
}
pPrintersA += pi_sizeof[level];
outW += pi_sizeof[level];
id++;
}
}
//AddForm - not supported
FORWARD_TO_UNICOWS(AddJobW);
FORWARD_TO_UNICOWS(AddMonitorW);
FORWARD_TO_UNICOWS(AddPortW);
//AddPrinterConnection - not supported
FORWARD_TO_UNICOWS(AddPrinterDriverW);
FORWARD_TO_UNICOWS(AddPrinterW);
FORWARD_TO_UNICOWS(AddPrintProcessorW);
FORWARD_TO_UNICOWS(AddPrintProvidorW); //lol providor
FORWARD_TO_UNICOWS(AdvancedDocumentPropertiesW);
FORWARD_TO_UNICOWS(ConfigurePortW);
//DeleteForm - not supported
FORWARD_TO_UNICOWS(DeleteMonitorW);
FORWARD_TO_UNICOWS(DeletePortW);
//DeletePrinterConnection - not supported
FORWARD_TO_UNICOWS(DeletePrinterDriverW);
FORWARD_TO_UNICOWS(DeletePrintProcessorW);
FORWARD_TO_UNICOWS(DeletePrintProvidorW);
FORWARD_TO_UNICOWS(DeviceCapabilitiesW);
FORWARD_TO_UNICOWS(DocumentPropertiesW);
//EnumForms - not supported
//EnumJobsW - not implemented
//EnumMonitorsW - not implemented
//EnumPortsW - not implemented
//EnumPrinterDriversW - not implemented
/* MAKE_EXPORT EnumPrintersW_new=EnumPrintersW */
BOOL WINAPI EnumPrintersW_new(
DWORD Flags,
LPWSTR NameW,
DWORD Level,
LPBYTE pPrinterEnumW,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
BOOL ret;
DWORD needed;
DWORD returned;
LPBYTE pPrinterEnumA;
ALLOC_WtoA(Name);
pPrinterEnumA = (pPrinterEnumW && cbBuf) ? (LPBYTE) HeapAlloc(GetProcessHeap(), 0, cbBuf) : NULL;
ret = EnumPrintersA(Flags, NameA, Level, pPrinterEnumA, cbBuf, &needed, &returned);
if (Level <= 5)
needed = (needed - pi_sizeof[Level]) * 2 + pi_sizeof[Level];
if (pcbNeeded)
*pcbNeeded = needed;
if (pcReturned)
*pcReturned = returned;
if (ret)
{
if (cbBuf >= needed)
{
convert_printerinfo_WtoA(pPrinterEnumW, pPrinterEnumA, Level, needed, returned);
}
else
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
if (pcReturned)
*pcReturned = 0;
ret = FALSE;
}
}
HeapFree(GetProcessHeap(), 0, pPrinterEnumA);
return ret;
}
//EnumPrintProcessorDatatypesW - not implemented
//EnumPrintProcessorsW - not implemented
//GetForm - not supported
//GetJobW - not implemented
//GetPrinterDataW - not implemented
FORWARD_TO_UNICOWS(GetPrinterDriverDirectoryW);
//GetPrinterDriverW - not implemented
//GetPrinterW - not implemented
FORWARD_TO_UNICOWS(GetPrintProcessorDirectoryW);
FORWARD_TO_UNICOWS(OpenPrinterW);
FORWARD_TO_UNICOWS(ResetPrinterW);
//SetForm - not supported
FORWARD_TO_UNICOWS(SetJobW);
//SetPrinterDataW - not implemented
FORWARD_TO_UNICOWS(SetPrinterDataW); //lol lazy bastards
FORWARD_TO_UNICOWS(SetPrinterW);
FORWARD_TO_UNICOWS(StartDocPrinterW);