diff --git a/channels/printer/client/printer_main.c b/channels/printer/client/printer_main.c index dd7f18330..6a569a0c9 100644 --- a/channels/printer/client/printer_main.c +++ b/channels/printer/client/printer_main.c @@ -80,7 +80,8 @@ static UINT printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp) rdpPrintJob* printjob = NULL; if (printer_dev->printer) - printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, irp->devman->id_sequence++); + printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, + irp->devman->id_sequence++); if (printjob) { @@ -105,7 +106,8 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) rdpPrintJob* printjob = NULL; if (printer_dev->printer) - printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, + irp->FileId); if (!printjob) { @@ -117,7 +119,6 @@ static UINT printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp) } Stream_Zero(irp->output, 4); /* Padding(4) */ - return irp->Complete(irp); } @@ -132,13 +133,13 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) UINT64 Offset; rdpPrintJob* printjob = NULL; UINT error = CHANNEL_RC_OK; - Stream_Read_UINT32(irp->input, Length); Stream_Read_UINT64(irp->input, Offset); Stream_Seek(irp->input, 20); /* Padding */ if (printer_dev->printer) - printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId); + printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, + irp->FileId); if (!printjob) { @@ -158,7 +159,6 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) Stream_Write_UINT32(irp->output, Length); Stream_Write_UINT8(irp->output, 0); /* Padding */ - return irp->Complete(irp); } @@ -167,7 +167,8 @@ static UINT printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp) * * @return 0 on success, otherwise a Win32 error code */ -static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* irp) +static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, + IRP* irp) { Stream_Write_UINT32(irp->output, 0); /* OutputBufferLength */ return irp->Complete(irp); @@ -181,6 +182,7 @@ static UINT printer_process_irp_device_control(PRINTER_DEVICE* printer_dev, IRP* static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) { UINT error; + switch (irp->MajorFunction) { case IRP_MJ_CREATE: @@ -189,6 +191,7 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) WLog_ERR(TAG, "printer_process_irp_create failed with error %lu!", error); return error; } + break; case IRP_MJ_CLOSE: @@ -197,6 +200,7 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) WLog_ERR(TAG, "printer_process_irp_close failed with error %lu!", error); return error; } + break; case IRP_MJ_WRITE: @@ -205,14 +209,17 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) WLog_ERR(TAG, "printer_process_irp_write failed with error %lu!", error); return error; } + break; case IRP_MJ_DEVICE_CONTROL: if ((error = printer_process_irp_device_control(printer_dev, irp))) { - WLog_ERR(TAG, "printer_process_irp_device_control failed with error %lu!", error); + WLog_ERR(TAG, "printer_process_irp_device_control failed with error %lu!", + error); return error; } + break; default: @@ -220,6 +227,7 @@ static UINT printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp) return irp->Complete(irp); break; } + return CHANNEL_RC_OK; } @@ -229,25 +237,25 @@ static void* printer_thread_func(void* arg) PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) arg; HANDLE obj[] = {printer_dev->event, printer_dev->stopEvent}; UINT error = CHANNEL_RC_OK; - freerdp_channel_init_thread_context(printer_dev->rdpcontext); + while (1) { DWORD rc = WaitForMultipleObjects(2, obj, FALSE, INFINITE); - if (rc == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); - break; - } + + if (rc == WAIT_FAILED) + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu!", error); + break; + } if (rc == WAIT_OBJECT_0 + 1) break; - else if( rc != WAIT_OBJECT_0 ) + else if (rc != WAIT_OBJECT_0) continue; ResetEvent(printer_dev->event); - irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList); if (irp == NULL) @@ -263,11 +271,12 @@ static void* printer_thread_func(void* arg) break; } } + if (error && printer_dev->rdpcontext) - setChannelError(printer_dev->rdpcontext, error, "printer_thread_func reported an error"); + setChannelError(printer_dev->rdpcontext, error, + "printer_thread_func reported an error"); ExitThread((DWORD) error); - return NULL; } @@ -279,9 +288,7 @@ static void* printer_thread_func(void* arg) static UINT printer_irp_request(DEVICE* device, IRP* irp) { PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; - InterlockedPushEntrySList(printer_dev->pIrpList, &(irp->ItemEntry)); - SetEvent(printer_dev->event); return CHANNEL_RC_OK; } @@ -295,15 +302,15 @@ static UINT printer_free(DEVICE* device) { IRP* irp; PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*) device; - UINT error; - + UINT error; SetEvent(printer_dev->stopEvent); + if (WaitForSingleObject(printer_dev->thread, INFINITE) == WAIT_FAILED) - { - error = GetLastError(); - WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); - return error; - } + { + error = GetLastError(); + WLog_ERR(TAG, "WaitForSingleObject failed with error %lu", error); + return error; + } while ((irp = (IRP*) InterlockedPopEntrySList(printer_dev->pIrpList)) != NULL) irp->Discard(irp); @@ -311,7 +318,6 @@ static UINT printer_free(DEVICE* device) CloseHandle(printer_dev->thread); CloseHandle(printer_dev->stopEvent); CloseHandle(printer_dev->event); - _aligned_free(printer_dev->pIrpList); if (printer_dev->printer) @@ -319,9 +325,8 @@ static UINT printer_free(DEVICE* device) free(printer_dev->device.name); Stream_Free(printer_dev->device.data, TRUE); - free(printer_dev); - return CHANNEL_RC_OK; + return CHANNEL_RC_OK; } /** @@ -329,7 +334,8 @@ static UINT printer_free(DEVICE* device) * * @return 0 on success, otherwise a Win32 error code */ -UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer) +UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, + rdpPrinter* printer) { char* port; UINT32 Flags; @@ -341,16 +347,17 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri BYTE* CachedPrinterConfigData; PRINTER_DEVICE* printer_dev; UINT error; - port = malloc(10); + if (!port) { WLog_ERR(TAG, "malloc failed!"); return CHANNEL_RC_NO_MEMORY; } - sprintf_s(port, 10, "PRN%d", printer->id); + sprintf_s(port, 10, "PRN%d", printer->id); printer_dev = (PRINTER_DEVICE*) calloc(1, sizeof(PRINTER_DEVICE)); + if (!printer_dev) { WLog_ERR(TAG, "calloc failed!"); @@ -363,21 +370,21 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri printer_dev->device.IRPRequest = printer_irp_request; printer_dev->device.Free = printer_free; printer_dev->rdpcontext = pEntryPoints->rdpcontext; - printer_dev->printer = printer; - CachedFieldsLen = 0; CachedPrinterConfigData = NULL; - Flags = 0; if (printer->is_default) Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; - DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, 0) * 2; - PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, 0) * 2; + DriverNameLen = ConvertToUnicode(CP_UTF8, 0, printer->driver, -1, &DriverName, + 0) * 2; + PrintNameLen = ConvertToUnicode(CP_UTF8, 0, printer->name, -1, &PrintName, + 0) * 2; + printer_dev->device.data = Stream_New(NULL, + 28 + DriverNameLen + PrintNameLen + CachedFieldsLen); - printer_dev->device.data = Stream_New(NULL, 28 + DriverNameLen + PrintNameLen + CachedFieldsLen); if (!printer_dev->device.data) { WLog_ERR(TAG, "calloc failed!"); @@ -400,19 +407,22 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri if (CachedFieldsLen > 0) { - Stream_Write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); + Stream_Write(printer_dev->device.data, CachedPrinterConfigData, + CachedFieldsLen); } free(DriverName); free(PrintName); + printer_dev->pIrpList = (WINPR_PSLIST_HEADER) _aligned_malloc(sizeof( + WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); - printer_dev->pIrpList = (WINPR_PSLIST_HEADER) _aligned_malloc(sizeof(WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); if (!printer_dev->pIrpList) { WLog_ERR(TAG, "_aligned_malloc failed!"); error = CHANNEL_RC_NO_MEMORY; goto error_out; } + InitializeSListHead(printer_dev->pIrpList); if (!(printer_dev->event = CreateEvent(NULL, TRUE, FALSE, NULL))) @@ -421,6 +431,7 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri error = ERROR_INTERNAL_ERROR; goto error_out; } + if (!(printer_dev->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "CreateEvent failed!"); @@ -428,14 +439,15 @@ UINT printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* pri goto error_out; } - if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev))) + if ((error = pEntryPoints->RegisterDevice(pEntryPoints->devman, + (DEVICE*) printer_dev))) { WLog_ERR(TAG, "RegisterDevice failed with error %d!", error); goto error_out; } if (!(printer_dev->thread = CreateThread(NULL, 0, - (LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL))) + (LPTHREAD_START_ROUTINE) printer_thread_func, (void*) printer_dev, 0, NULL))) { WLog_ERR(TAG, "CreateThread failed!"); error = ERROR_INTERNAL_ERROR; @@ -474,11 +486,9 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) RDPDR_PRINTER* device; rdpPrinterDriver* driver = NULL; UINT error; - #ifdef WITH_CUPS driver = printer_cups_get_driver(); #endif - #if defined(_WIN32) && !defined(_UWP) driver = printer_win_get_driver(); #endif @@ -516,12 +526,12 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) for (i = 0; printers[i]; i++) { printer = printers[i]; + if ((error = printer_register(pEntryPoints, printer))) { WLog_ERR(TAG, "printer_register failed with error %lu!", error); free(printers); return error; - } }