--- sourceforge.net/trunk/rdesktop/parallel.c 2004/01/23 08:35:52 580 +++ sourceforge.net/trunk/rdesktop/parallel.c 2004/10/02 01:30:33 776 @@ -4,16 +4,22 @@ #define IOCTL_PAR_QUERY_RAW_DEVICE_ID 0x0c -#define PARALLELDEV0 "/dev/lp0" - #include "rdesktop.h" #include #include +#include +#include + +#if defined(__linux__) +#include +#endif + +extern int errno; extern RDPDR_DEVICE g_rdpdr_device[]; -PARALLEL_DEVICE * -get_parallel_data(HANDLE handle) +static PARALLEL_DEVICE * +get_parallel_data(NTHANDLE handle) { int index; @@ -31,9 +37,8 @@ /* optarg looks like ':LPT1=/dev/lp0' */ /* when it arrives to this function. */ int -parallel_enum_devices(int *id, char *optarg) +parallel_enum_devices(uint32 * id, char *optarg) { - //TODO: Read from configuration file? CUPS? PARALLEL_DEVICE *ppar_info; char *pos = optarg; @@ -58,6 +63,7 @@ // set device type g_rdpdr_device[*id].device_type = DEVICE_TYPE_PARALLEL; g_rdpdr_device[*id].pdevice_data = (void *) ppar_info; + g_rdpdr_device[*id].handle = 0; count++; (*id)++; @@ -67,34 +73,87 @@ } static NTSTATUS -parallel_create(uint32 device_id, HANDLE * handle) +parallel_create(uint32 device_id, uint32 access, uint32 share_mode, uint32 disposition, + uint32 flags, char *filename, NTHANDLE * handle) { int parallel_fd; - parallel_fd = open(PARALLELDEV0, O_WRONLY); + parallel_fd = open(g_rdpdr_device[device_id].local_path, O_RDWR); if (parallel_fd == -1) + { + perror("open"); return STATUS_ACCESS_DENIED; + } + + /* all read and writes should be non blocking */ + if (fcntl(parallel_fd, F_SETFL, O_NONBLOCK) == -1) + perror("fcntl"); + +#if defined(LPABORT) + /* Retry on errors */ + ioctl(parallel_fd, LPABORT, (int) 1); +#endif + + g_rdpdr_device[device_id].handle = parallel_fd; *handle = parallel_fd; + return STATUS_SUCCESS; } static NTSTATUS -parallel_close(HANDLE handle) +parallel_close(NTHANDLE handle) { + int i = get_device_index(handle); + if (i >= 0) + g_rdpdr_device[i].handle = 0; close(handle); return STATUS_SUCCESS; } static NTSTATUS -parallel_write(HANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) +parallel_read(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) { - *result = write(handle, data, length); + *result = read(handle, data, length); return STATUS_SUCCESS; } static NTSTATUS -parallel_device_control(HANDLE handle, uint32 request, STREAM in, STREAM out) +parallel_write(NTHANDLE handle, uint8 * data, uint32 length, uint32 offset, uint32 * result) +{ + int rc = STATUS_SUCCESS; + + int n = write(handle, data, length); + if (n < 0) + { + int status; + + *result = 0; + switch (errno) + { + case EAGAIN: + rc = STATUS_DEVICE_OFF_LINE; + case ENOSPC: + rc = STATUS_DEVICE_PAPER_EMPTY; + case EIO: + rc = STATUS_DEVICE_OFF_LINE; + default: + rc = STATUS_DEVICE_POWERED_OFF; + } +#if defined(LPGETSTATUS) + if (ioctl(handle, LPGETSTATUS, &status) == 0) + { + /* coming soon: take care for the printer status */ + printf("parallel_write: status = %d, errno = %d\n", status, errno); + } +#endif + } + *result = n; + return rc; +} + +static NTSTATUS +parallel_device_control(NTHANDLE handle, uint32 request, STREAM in, STREAM out) { if ((request >> 16) != FILE_DEVICE_PARALLEL) return STATUS_INVALID_PARAMETER; @@ -120,7 +179,7 @@ DEVICE_FNS parallel_fns = { parallel_create, parallel_close, - NULL, + parallel_read, parallel_write, parallel_device_control };