mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
win32: make rdpdr printer plugin working on win32
This commit is contained in:
@@ -41,8 +41,8 @@ endif()
|
||||
install(TARGETS rdpdr DESTINATION ${FREERDP_PLUGIN_PATH})
|
||||
|
||||
add_subdirectory(disk)
|
||||
add_subdirectory(printer)
|
||||
if(NOT WIN32)
|
||||
add_subdirectory(printer)
|
||||
add_subdirectory(parallel)
|
||||
add_subdirectory(serial)
|
||||
endif()
|
||||
|
||||
@@ -31,6 +31,13 @@ if(WITH_CUPS)
|
||||
add_definitions(-DWITH_CUPS)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(PRINTER_SRCS
|
||||
${PRINTER_SRCS}
|
||||
printer_win.c
|
||||
printer_win.h)
|
||||
endif()
|
||||
|
||||
include_directories(..)
|
||||
|
||||
add_library(printer ${PRINTER_SRCS})
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
|
||||
#include "printer_main.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include "printer_win.h"
|
||||
#endif
|
||||
|
||||
typedef struct _PRINTER_DEVICE PRINTER_DEVICE;
|
||||
struct _PRINTER_DEVICE
|
||||
{
|
||||
@@ -294,7 +298,11 @@ void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri
|
||||
freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev);
|
||||
}
|
||||
|
||||
#ifdef WITH_STATIC_PLUGINS
|
||||
int printer_entry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
#else
|
||||
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
#endif
|
||||
{
|
||||
rdpPrinterDriver* driver = NULL;
|
||||
rdpPrinter** printers;
|
||||
@@ -305,6 +313,9 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
#ifdef WITH_CUPS
|
||||
driver = printer_cups_get_driver();
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
driver = printer_win_get_driver();
|
||||
#endif
|
||||
if (driver == NULL)
|
||||
{
|
||||
|
||||
283
channels/rdpdr/client/printer/printer_win.c
Normal file
283
channels/rdpdr/client/printer/printer_win.c
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol client.
|
||||
* Print Virtual Channel - WIN driver
|
||||
*
|
||||
* Copyright 2012 Gerald Richter
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <winspool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "config.h"
|
||||
#include <freerdp/utils/memory.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "rdpdr_types.h"
|
||||
#include "printer_main.h"
|
||||
|
||||
#include "printer_win.h"
|
||||
|
||||
typedef struct rdp_win_printer_driver rdpWinPrinterDriver;
|
||||
typedef struct rdp_win_printer rdpWinPrinter;
|
||||
typedef struct rdp_win_print_job rdpWinPrintJob;
|
||||
|
||||
struct rdp_win_printer_driver
|
||||
{
|
||||
rdpPrinterDriver driver;
|
||||
|
||||
int id_sequence;
|
||||
};
|
||||
|
||||
struct rdp_win_printer
|
||||
{
|
||||
rdpPrinter printer;
|
||||
HANDLE hPrinter;
|
||||
rdpWinPrintJob* printjob;
|
||||
};
|
||||
|
||||
struct rdp_win_print_job
|
||||
{
|
||||
rdpPrintJob printjob;
|
||||
DOC_INFO_1 di;
|
||||
DWORD handle;
|
||||
|
||||
void* printjob_object;
|
||||
int printjob_id;
|
||||
};
|
||||
|
||||
static void printer_win_get_printjob_name(char* buf, int size)
|
||||
{
|
||||
time_t tt;
|
||||
struct tm* t;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
tt = time(NULL);
|
||||
t = localtime(&tt);
|
||||
snprintf(buf, size - 1, "FreeRDP Print Job %d%02d%02d%02d%02d%02d",
|
||||
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||
t->tm_hour, t->tm_min, t->tm_sec);
|
||||
|
||||
DEBUG_WINPR("buf: %s", buf);
|
||||
|
||||
}
|
||||
|
||||
static void printer_win_write_printjob(rdpPrintJob* printjob, uint8* data, int size)
|
||||
{
|
||||
rdpWinPrintJob* win_printjob = (rdpWinPrintJob*)printjob;
|
||||
|
||||
LPVOID pBuf = data;
|
||||
DWORD cbBuf = size;
|
||||
DWORD pcWritten;
|
||||
|
||||
if( ! WritePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter, pBuf, cbBuf, &pcWritten ) )
|
||||
DEBUG_WINPR("WritePrinter failed");
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
static void printer_win_close_printjob(rdpPrintJob* printjob)
|
||||
{
|
||||
rdpWinPrintJob* win_printjob = (rdpWinPrintJob*)printjob;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
if ( ! EndPagePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter ) )
|
||||
DEBUG_WINPR("EndPagePrinter failed");;
|
||||
if ( ! ClosePrinter( ((rdpWinPrinter*)printjob->printer)->hPrinter ) )
|
||||
DEBUG_WINPR("ClosePrinter failed");;
|
||||
|
||||
((rdpWinPrinter*)printjob->printer)->printjob = NULL;
|
||||
xfree(win_printjob) ;
|
||||
}
|
||||
|
||||
static rdpPrintJob* printer_win_create_printjob(rdpPrinter* printer, uint32 id)
|
||||
{
|
||||
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
|
||||
rdpWinPrintJob* win_printjob;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
if (win_printer->printjob != NULL)
|
||||
return NULL;
|
||||
|
||||
win_printjob = xnew(rdpWinPrintJob);
|
||||
|
||||
win_printjob->printjob.id = id;
|
||||
win_printjob->printjob.printer = printer;
|
||||
win_printjob->di.pDocName = L"FREERDPjob";
|
||||
win_printjob->di.pDatatype= NULL;
|
||||
win_printjob->di.pOutputFile = NULL;
|
||||
|
||||
win_printjob->handle = StartDocPrinter(win_printer->hPrinter, 1, (LPBYTE)&(win_printjob->di) );
|
||||
if(! win_printjob->handle) DEBUG_WINPR("StartDocPrinter failed");
|
||||
if ( ! StartPagePrinter(win_printer->hPrinter) )
|
||||
DEBUG_WINPR("ClosePrinter failed");
|
||||
|
||||
|
||||
win_printjob->printjob.Write = printer_win_write_printjob;
|
||||
win_printjob->printjob.Close = printer_win_close_printjob;
|
||||
|
||||
|
||||
|
||||
win_printer->printjob = win_printjob;
|
||||
|
||||
return (rdpPrintJob*)win_printjob;
|
||||
}
|
||||
|
||||
static rdpPrintJob* printer_win_find_printjob(rdpPrinter* printer, uint32 id)
|
||||
{
|
||||
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
if (win_printer->printjob == NULL)
|
||||
return NULL;
|
||||
if (win_printer->printjob->printjob.id != id)
|
||||
return NULL;
|
||||
|
||||
return (rdpPrintJob*)win_printer->printjob;
|
||||
}
|
||||
|
||||
static void printer_win_free_printer(rdpPrinter* printer)
|
||||
{
|
||||
rdpWinPrinter* win_printer = (rdpWinPrinter*)printer;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
if (win_printer->printjob)
|
||||
win_printer->printjob->printjob.Close((rdpPrintJob*)win_printer->printjob);
|
||||
xfree(printer->name);
|
||||
xfree(printer);
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, const char* name, const wchar_t* drivername, boolean is_default)
|
||||
{
|
||||
rdpWinPrinter* win_printer;
|
||||
wchar_t wname[256];
|
||||
DWORD needed;
|
||||
PRINTER_INFO_2 *prninfo=NULL;
|
||||
size_t charsConverted;
|
||||
DEBUG_WINPR("");
|
||||
|
||||
win_printer = xnew(rdpWinPrinter);
|
||||
|
||||
win_printer->printer.id = win_driver->id_sequence++;
|
||||
win_printer->printer.name = xstrdup(name);
|
||||
win_printer->printer.is_default = is_default;
|
||||
|
||||
win_printer->printer.CreatePrintJob = printer_win_create_printjob;
|
||||
win_printer->printer.FindPrintJob = printer_win_find_printjob;
|
||||
win_printer->printer.Free = printer_win_free_printer;
|
||||
|
||||
swprintf(wname, 256, L"%hs", name);
|
||||
OpenPrinter(wname, &(win_printer->hPrinter), NULL);
|
||||
DEBUG_WINPR("handle: 0x%08X", win_printer->hPrinter);
|
||||
|
||||
GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, 0, &needed);
|
||||
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
|
||||
GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, needed, &needed);
|
||||
|
||||
win_printer->printer.driver = xmalloc(1000);
|
||||
wcstombs_s(&charsConverted, win_printer->printer.driver, 1000, prninfo->pDriverName, _TRUNCATE);
|
||||
|
||||
return (rdpPrinter*)win_printer;
|
||||
}
|
||||
|
||||
static rdpPrinter** printer_win_enum_printers(rdpPrinterDriver* driver)
|
||||
{
|
||||
rdpPrinter** printers;
|
||||
int num_printers;
|
||||
int i;
|
||||
char pname[1000];
|
||||
size_t charsConverted;
|
||||
|
||||
PRINTER_INFO_2 *prninfo=NULL;
|
||||
DWORD needed, returned;
|
||||
|
||||
DEBUG_WINPR("");
|
||||
|
||||
|
||||
//find required size for the buffer
|
||||
EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &returned);
|
||||
|
||||
|
||||
//allocate array of PRINTER_INFO structures
|
||||
prninfo = (PRINTER_INFO_2*) GlobalAlloc(GPTR,needed);
|
||||
|
||||
//call again
|
||||
if ( !EnumPrinters(PRINTER_ENUM_LOCAL|PRINTER_ENUM_CONNECTIONS, NULL, 2, (LPBYTE) prninfo, needed, &needed, &returned) ) {
|
||||
DEBUG_WINPR("EnumPrinters failed");
|
||||
|
||||
} ; /* eRROR... */
|
||||
|
||||
DEBUG_WINPR("printers found: %d", returned);
|
||||
|
||||
|
||||
printers = (rdpPrinter**)xzalloc(sizeof(rdpPrinter*) * (returned + 1));
|
||||
num_printers = 0;
|
||||
|
||||
for (i = 0; i < (int)returned; i++)
|
||||
{
|
||||
wcstombs_s(&charsConverted, pname, 1000, prninfo[i].pPrinterName, _TRUNCATE);
|
||||
printers[num_printers++] = printer_win_new_printer((rdpWinPrinterDriver*)driver,
|
||||
pname, prninfo[i].pDriverName, 0);
|
||||
}
|
||||
|
||||
GlobalFree(prninfo);
|
||||
return printers;
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_win_get_printer(rdpPrinterDriver* driver, const char* name)
|
||||
{
|
||||
rdpWinPrinterDriver* win_driver = (rdpWinPrinterDriver*)driver;
|
||||
rdpPrinter *myPrinter = NULL;
|
||||
|
||||
DEBUG_WINPR("printer %s", name);
|
||||
|
||||
myPrinter = printer_win_new_printer(win_driver, name, L"", win_driver->id_sequence == 1 ? true : false);
|
||||
|
||||
return myPrinter;
|
||||
}
|
||||
|
||||
static rdpWinPrinterDriver* win_driver = NULL;
|
||||
|
||||
rdpPrinterDriver* printer_win_get_driver(void)
|
||||
{
|
||||
DEBUG_WINPR("");
|
||||
|
||||
if (win_driver == NULL)
|
||||
{
|
||||
win_driver = xnew(rdpWinPrinterDriver);
|
||||
|
||||
win_driver->driver.EnumPrinters = printer_win_enum_printers;
|
||||
win_driver->driver.GetPrinter = printer_win_get_printer;
|
||||
|
||||
win_driver->id_sequence = 1;
|
||||
|
||||
//#ifdef _win_API_1_4
|
||||
// DEBUG_SVC("using win API 1.4");
|
||||
//#else
|
||||
// DEBUG_SVC("using win API 1.2");
|
||||
//#endif
|
||||
}
|
||||
|
||||
return (rdpPrinterDriver*)win_driver;
|
||||
}
|
||||
|
||||
37
channels/rdpdr/client/printer/printer_win.h
Normal file
37
channels/rdpdr/client/printer/printer_win.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol client.
|
||||
* Print Virtual Channel - win driver
|
||||
*
|
||||
* Copyright 2012 Gerald Richter
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __PRINTER_WIN_H
|
||||
#define __PRINTER_WIN_H
|
||||
|
||||
|
||||
rdpPrinterDriver* printer_win_get_driver(void);
|
||||
|
||||
#ifdef WITH_DEBUG_WINPR
|
||||
#define DEBUG_WINPR(fmt, ...) DEBUG_CLASS(WINPR, fmt, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_WINPR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
@@ -36,7 +36,7 @@ add_executable(wfreerdp WIN32 ${FREERDP_CLIENT_WINDOWS_SRCS})
|
||||
if(WITH_MONOLITHIC_BUILD)
|
||||
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} freerdp)
|
||||
if(WITH_RDPDR)
|
||||
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} rdpdr disk)
|
||||
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS} rdpdr disk printer)
|
||||
endif()
|
||||
else()
|
||||
set(FREERDP_CLIENT_WINDOWS_LIBS ${FREERDP_CLIENT_WINDOWS_LIBS}
|
||||
|
||||
@@ -636,6 +636,7 @@ static DWORD WINAPI kbd_thread_func(LPVOID lpParam)
|
||||
#ifdef WITH_RDPDR
|
||||
DEFINE_SVC_PLUGIN_ENTRY(rdpdr) ;
|
||||
DEFINE_DEV_PLUGIN_ENTRY(disk) ;
|
||||
DEFINE_DEV_PLUGIN_ENTRY(printer) ;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -699,6 +700,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
#ifdef WITH_RDPDR
|
||||
REGISTER_SVC_PLUGIN_ENTRY(rdpdr) ;
|
||||
REGISTER_DEV_PLUGIN_ENTRY(disk) ;
|
||||
REGISTER_DEV_PLUGIN_ENTRY(printer) ;
|
||||
#endif
|
||||
|
||||
if (!CreateThread(NULL, 0, kbd_thread_func, NULL, 0, NULL))
|
||||
|
||||
Reference in New Issue
Block a user