static uint32 printer_process_update_printer_event(SERVICE * srv, const char * data, int data_len) { uint32 printerNameLen; char * printerName; uint32 configDataLen; UNICONV * uniconv; printerNameLen = GET_UINT32(data, 0); configDataLen = GET_UINT32(data, 4); if (printerNameLen + configDataLen + 8 > data_len) { LLOGLN(0, ("printer_process_update_printer_event: expect %d+%d+8 got %d", printerNameLen, configDataLen, data_len)); return 1; } uniconv = freerdp_uniconv_new(); printerName = freerdp_uniconv_in(uniconv, (unsigned char*) (data + 8), printerNameLen); LLOGLN(10, ("printer_process_update_printer_event: %s %d", printerName, configDataLen)); printer_save_data(printerName, data + 8 + printerNameLen, configDataLen); xfree(printerName); freerdp_uniconv_free(uniconv); return 0; }
void settings_free(rdpSettings* settings) { if (settings != NULL) { freerdp_uniconv_free(settings->uniconv); xfree(settings->hostname); xfree(settings->username); xfree(settings->password); xfree(settings->domain); xfree(settings->shell); xfree(settings->directory); xfree(settings->ip_address); xfree(settings->client_dir); xfree(settings->cert_file); xfree(settings->privatekey_file); freerdp_blob_free(settings->server_random); freerdp_blob_free(settings->server_certificate); xfree(settings->server_random); xfree(settings->server_certificate); xfree(settings->rdp_key_file); certificate_free(settings->server_cert); xfree(settings->client_auto_reconnect_cookie); xfree(settings->server_auto_reconnect_cookie); xfree(settings->client_time_zone); xfree(settings->bitmapCacheV2CellInfo); xfree(settings->glyphCache); xfree(settings->fragCache); key_free(settings->server_key); xfree(settings->config_path); xfree(settings->current_path); xfree(settings->development_path); xfree(settings); } }
static void rdpdr_send_client_name_request(rdpdrPlugin* rdpdr) { STREAM* data_out; size_t computerNameLenW; UNICONV* uniconv; char* s; uniconv = freerdp_uniconv_new(); if (!rdpdr->computerName[0]) gethostname(rdpdr->computerName, sizeof(rdpdr->computerName) - 1); s = freerdp_uniconv_out(uniconv, rdpdr->computerName, &computerNameLenW); data_out = stream_new(16 + computerNameLenW + 2); stream_write_uint16(data_out, RDPDR_CTYP_CORE); stream_write_uint16(data_out, PAKID_CORE_CLIENT_NAME); stream_write_uint32(data_out, 1); /* unicodeFlag, 0 for ASCII and 1 for Unicode */ stream_write_uint32(data_out, 0); /* codePage, must be set to zero */ stream_write_uint32(data_out, computerNameLenW + 2); /* computerNameLen, including null terminator */ stream_write(data_out, s, computerNameLenW); stream_write_uint16(data_out, 0); /* null terminator */ xfree(s); freerdp_uniconv_free(uniconv); svc_plugin_send((rdpSvcPlugin*)rdpdr, data_out); }
void ntlm_free(rdpNtlm* ntlm) { if (ntlm != NULL) { freerdp_uniconv_free(ntlm->uniconv); } }
void rail_order_free(rdpRailOrder* rail_order) { if (rail_order != NULL) { freerdp_uniconv_free(rail_order->uniconv); xfree(rail_order); } }
static void cliprdr_process_terminate(rdpSvcPlugin* plugin) { cliprdrPlugin* cliprdr_plugin = (cliprdrPlugin*) plugin; if (cliprdr_plugin->uniconv != NULL) freerdp_uniconv_free(cliprdr_plugin->uniconv); xfree(plugin); }
void credssp_free(rdpCredssp* credssp) { if (credssp != NULL) { sspi_SecBufferFree(&credssp->ts_credentials); freerdp_uniconv_free(credssp->uniconv); xfree(credssp); } }
static void xf_cliprdr_process_unicodetext(clipboardContext* cb, uint8* data, int size) { UNICONV* uniconv; uniconv = freerdp_uniconv_new(); cb->data = (uint8*) freerdp_uniconv_in(uniconv, data, size); freerdp_uniconv_free(uniconv); cb->data_length = strlen((char*) cb->data); crlf2lf(cb->data, &cb->data_length); }
void rail_free(rdpRail* rail) { if (rail != NULL) { icon_cache_free(rail->cache); window_list_free(rail->list); freerdp_uniconv_free(rail->uniconv); xfree(rail->clrconv); xfree(rail); } }
void irp_process_create_request(IRP* irp, char* data, int data_size) { UNICONV * uniconv; uint32 pathLength; char * path; irp->desiredAccess = GET_UINT32(data, 0); /* desiredAccess */ //irp->allocationSize = GET_UINT64(data, 4); /* allocationSize */ irp->fileAttributes = GET_UINT32(data, 12); /* fileAttributes */ irp->sharedAccess = GET_UINT32(data, 16); /* sharedAccess */ irp->createDisposition = GET_UINT32(data, 20); /* createDisposition */ irp->createOptions = GET_UINT32(data, 24); /* createOptions */ pathLength = GET_UINT32(data, 28); /* pathLength */ uniconv = freerdp_uniconv_new(); path = freerdp_uniconv_in(uniconv, (unsigned char*) (&data[32]), pathLength); freerdp_uniconv_free(uniconv); if (!irp->dev->service->create) { irp->ioStatus = RD_STATUS_NOT_SUPPORTED; } else { irp->ioStatus = irp->dev->service->create(irp, path); } free(path); /* construct create response */ irp->outputResult = irp->fileID; irp->outputBufferLength = 1; irp->outputBuffer = malloc(1); switch (irp->createDisposition) { case FILE_SUPERSEDE: case FILE_OPEN: case FILE_CREATE: case FILE_OVERWRITE: irp->outputBuffer[0] = FILE_SUPERSEDED; break; case FILE_OPEN_IF: irp->outputBuffer[0] = FILE_OPENED; break; case FILE_OVERWRITE_IF: irp->outputBuffer[0] = FILE_OVERWRITTEN; break; default: irp->outputBuffer[0] = 0; break; } }
void credssp_free(rdpCredssp* credssp) { if (credssp != NULL) { credssp->table->DeleteSecurityContext(&credssp->context); sspi_SecBufferFree(&credssp->PublicKey); sspi_SecBufferFree(&credssp->ts_credentials); freerdp_uniconv_free(credssp->uniconv); xfree(credssp->identity.User); xfree(credssp->identity.Domain); xfree(credssp->identity.Password); xfree(credssp); } }
void settings_free(rdpSettings* settings) { if (settings != NULL) { freerdp_uniconv_free(settings->uniconv); xfree(settings->hostname); xfree(settings->username); xfree(settings->password); xfree(settings->domain); xfree(settings->shell); xfree(settings->directory); xfree(settings->client_dir); xfree(settings); } }
boolean nego_send_preconnection_pdu(rdpNego* nego) { STREAM* s; uint32 cbSize; UNICONV* uniconv; uint16 cchPCB_times2 = 0; char* wszPCB = NULL; if (!nego->send_preconnection_pdu) return true; DEBUG_NEGO("Sending preconnection PDU"); if (!nego_tcp_connect(nego)) return false; /* it's easier to always send the version 2 PDU, and it's just 2 bytes overhead */ cbSize = PRECONNECTION_PDU_V2_MIN_SIZE; if (nego->preconnection_blob) { size_t size; uniconv = freerdp_uniconv_new(); wszPCB = freerdp_uniconv_out(uniconv, nego->preconnection_blob, &size); cchPCB_times2 = (uint16) size; freerdp_uniconv_free(uniconv); cchPCB_times2 += 2; /* zero-termination */ cbSize += cchPCB_times2; } s = transport_send_stream_init(nego->transport, cbSize); stream_write_uint32(s, cbSize); /* cbSize */ stream_write_uint32(s, 0); /* Flags */ stream_write_uint32(s, PRECONNECTION_PDU_V2); /* Version */ stream_write_uint32(s, nego->preconnection_id); /* Id */ stream_write_uint16(s, cchPCB_times2 / 2); /* cchPCB */ if (wszPCB) { stream_write(s, wszPCB, cchPCB_times2); /* wszPCB */ xfree(wszPCB); } if (transport_write(nego->transport, s) < 0) return false; return true; }
static uint8* xf_cliprdr_process_requested_unicodetext(uint8* data, int* size) { uint8* inbuf; uint8* outbuf; size_t out_size; UNICONV* uniconv; inbuf = lf2crlf(data, size); uniconv = freerdp_uniconv_new(); outbuf = (uint8*) freerdp_uniconv_out(uniconv, (char*) inbuf, &out_size); freerdp_uniconv_free(uniconv); xfree(inbuf); *size = (int) out_size + 2; return outbuf; }
static void parallel_process_irp_create(PARALLEL_DEVICE* parallel, IRP* irp) { uint32 PathLength; char* path; UNICONV* uniconv; stream_seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ stream_read_uint32(irp->input, PathLength); uniconv = freerdp_uniconv_new(); path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); freerdp_uniconv_free(uniconv); parallel->id = irp->devman->id_sequence++; parallel->file = open(parallel->path, O_RDWR); if (parallel->file < 0) { irp->IoStatus = STATUS_ACCESS_DENIED; parallel->id = 0; DEBUG_WARN("failed to create %s: %s", parallel->path, strerror(errno)); } else { /* all read and write operations should be non-blocking */ if (fcntl(parallel->file, F_SETFL, O_NONBLOCK) == -1) DEBUG_WARN("%s fcntl %s", path, strerror(errno)); DEBUG_SVC("%s(%d) created", parallel->path, parallel->file); } stream_write_uint32(irp->output, parallel->id); stream_write_uint8(irp->output, 0); xfree(path); irp->Complete(irp); }
static uint32 printer_process_delete_printer_event(SERVICE * srv, const char * data, int data_len) { uint32 printerNameLen; char * printerName; char * filename; UNICONV * uniconv; printerNameLen = GET_UINT32(data, 0); uniconv = freerdp_uniconv_new(); printerName = freerdp_uniconv_in(uniconv, (unsigned char*) (data + 4), printerNameLen); freerdp_uniconv_free(uniconv); filename = printer_get_filename(printerName); remove(filename); LLOGLN(0, ("printer_process_delete_printer_event: %s deleted", filename)); free(filename); xfree(printerName); return 0; }
static void serial_process_irp_create(SERIAL_DEVICE* serial, IRP* irp) { SERIAL_TTY* tty; uint32 PathLength; uint32 FileId; char* path; UNICONV* uniconv; stream_seek(irp->input, 28); /* DesiredAccess(4) AllocationSize(8), FileAttributes(4) */ /* SharedAccess(4) CreateDisposition(4), CreateOptions(4) */ stream_read_uint32(irp->input, PathLength); uniconv = freerdp_uniconv_new(); path = freerdp_uniconv_in(uniconv, stream_get_tail(irp->input), PathLength); freerdp_uniconv_free(uniconv); FileId = irp->devman->id_sequence++; tty = serial_tty_new(serial->path, FileId); if (tty == NULL) { irp->IoStatus = STATUS_UNSUCCESSFUL; FileId = 0; DEBUG_WARN("failed to create %s", path); } else { serial->tty = tty; DEBUG_SVC("%s(%d) created.", serial->path, FileId); } stream_write_uint32(irp->output, FileId); stream_write_uint8(irp->output, 0); xfree(path); irp->Complete(irp); }
void irp_process_query_directory_request(IRP* irp, char* data, int data_size) { UNICONV * uniconv; uint8 initialQuery; uint32 pathLength; char * path; irp->infoClass = GET_UINT32(data, 0); /* fsInformationClass */ initialQuery = GET_UINT8(data, 4); /* initialQuery */ pathLength = GET_UINT32(data, 5); /* pathLength */ /* 23-byte pad */ uniconv = freerdp_uniconv_new(); path = freerdp_uniconv_in(uniconv, (unsigned char*) (&data[32]), pathLength); freerdp_uniconv_free(uniconv); if (!irp->dev->service->query_directory) { irp->ioStatus = RD_STATUS_NOT_SUPPORTED; } else { irp->ioStatus = irp->dev->service->query_directory(irp, initialQuery, path); } free(path); if (irp->ioStatus == RD_STATUS_NO_MORE_FILES) { /* [MS-RDPEFS] said it's an optional padding, however it's *required* for this last query!!! */ irp->outputBufferLength = 1; irp->outputBuffer = malloc(1); irp->outputBuffer[0] = '\0'; } else { irp->outputResult = irp->outputBufferLength; } }
void ntlm_ContextFree(NTLM_CONTEXT* context) { if (!context) return; freerdp_uniconv_free(context->uniconv); crypto_rc4_free(context->SendRc4Seal); crypto_rc4_free(context->RecvRc4Seal); sspi_SecBufferFree(&context->NegotiateMessage); sspi_SecBufferFree(&context->ChallengeMessage); sspi_SecBufferFree(&context->AuthenticateMessage); sspi_SecBufferFree(&context->TargetInfo); sspi_SecBufferFree(&context->TargetName); sspi_SecBufferFree(&context->NtChallengeResponse); sspi_SecBufferFree(&context->LmChallengeResponse); xfree(context->identity.User); xfree(context->identity.Password); xfree(context->identity.Domain); xfree(context->Workstation); xfree(context->av_pairs->Timestamp.value); xfree(context->av_pairs); xfree(context); }
static uint8* xf_cliprdr_process_requested_html(uint8* data, int* size) { uint8* inbuf; uint8* in; uint8* outbuf; char num[11]; UNICONV* uniconv; inbuf = NULL; if (*size > 2) { if ((uint8) data[0] == 0xFE && (uint8) data[1] == 0xFF) { be2le(data, *size); } if ((uint8) data[0] == 0xFF && (uint8) data[1] == 0xFE) { uniconv = freerdp_uniconv_new(); inbuf = (uint8*) freerdp_uniconv_in(uniconv, data + 2, *size - 2); freerdp_uniconv_free(uniconv); } } if (inbuf == NULL) { inbuf = xzalloc(*size + 1); memcpy(inbuf, data, *size); } outbuf = (uint8*) xzalloc(*size + 200); strcpy((char*) outbuf, "Version:0.9\r\n" "StartHTML:0000000000\r\n" "EndHTML:0000000000\r\n" "StartFragment:0000000000\r\n" "EndFragment:0000000000\r\n"); in = (uint8*) strstr((char*) inbuf, "<body"); if (in == NULL) { in = (uint8*) strstr((char*) inbuf, "<BODY"); } /* StartHTML */ snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); memcpy(outbuf + 23, num, 10); if (in == NULL) { strcat((char*) outbuf, "<HTML><BODY>"); } strcat((char*) outbuf, "<!--StartFragment-->"); /* StartFragment */ snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); memcpy(outbuf + 69, num, 10); strcat((char*) outbuf, (char*) inbuf); /* EndFragment */ snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); memcpy(outbuf + 93, num, 10); strcat((char*) outbuf, "<!--EndFragment-->"); if (in == NULL) { strcat((char*) outbuf, "</BODY></HTML>"); } /* EndHTML */ snprintf(num, sizeof(num), "%010lu", (unsigned long) strlen((char*) outbuf)); memcpy(outbuf + 43, num, 10); *size = strlen((char*) outbuf) + 1; xfree(inbuf); return outbuf; }
boolean disk_file_query_directory(DISK_FILE* file, uint32 FsInformationClass, uint8 InitialQuery, const char* path, STREAM* output) { struct dirent* ent; char* ent_path; struct stat st; UNICONV* uniconv; size_t len; boolean ret; DEBUG_SVC("path %s FsInformationClass %d", path, FsInformationClass); if (InitialQuery != 0) { rewinddir(file->dir); } ent = readdir(file->dir); if (ent == NULL) { stream_write_uint32(output, 0); /* Length */ stream_write_uint8(output, 0); /* Padding */ return false; } memset(&st, 0, sizeof(struct stat)); ent_path = xmalloc(strlen(file->fullpath) + strlen(ent->d_name) + 2); sprintf(ent_path, "%s/%s", file->fullpath, ent->d_name); if (stat(ent_path, &st) != 0) { DEBUG_WARN("stat %s failed.", ent_path); } xfree(ent_path); uniconv = freerdp_uniconv_new(); ent_path = freerdp_uniconv_out(uniconv, ent->d_name, &len); freerdp_uniconv_free(uniconv); ret = true; switch (FsInformationClass) { case FileDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232097.aspx */ stream_write_uint32(output, 64 + len); /* Length */ stream_check_size(output, 64 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_uint64(output, st.st_size); /* EndOfFile */ stream_write_uint64(output, st.st_size); /* AllocationSize */ stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_uint32(output, len); /* FileNameLength */ stream_write(output, ent_path, len); break; case FileFullDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232068.aspx */ stream_write_uint32(output, 68 + len); /* Length */ stream_check_size(output, 68 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_uint64(output, st.st_size); /* EndOfFile */ stream_write_uint64(output, st.st_size); /* AllocationSize */ stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_uint32(output, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write(output, ent_path, len); break; case FileBothDirectoryInformation: /* http://msdn.microsoft.com/en-us/library/cc232095.aspx */ stream_write_uint32(output, 93 + len); /* Length */ stream_check_size(output, 93 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* CreationTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_atime)); /* LastAccessTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_mtime)); /* LastWriteTime */ stream_write_uint64(output, FILE_TIME_SYSTEM_TO_RDP(st.st_ctime)); /* ChangeTime */ stream_write_uint64(output, st.st_size); /* EndOfFile */ stream_write_uint64(output, st.st_size); /* AllocationSize */ stream_write_uint32(output, FILE_ATTR_SYSTEM_TO_RDP(file, st)); /* FileAttributes */ stream_write_uint32(output, len); /* FileNameLength */ stream_write_uint32(output, 0); /* EaSize */ stream_write_uint8(output, 0); /* ShortNameLength */ /* Reserved(1), MUST NOT be added! */ stream_write_zero(output, 24); /* ShortName */ stream_write(output, ent_path, len); break; case FileNamesInformation: /* http://msdn.microsoft.com/en-us/library/cc232077.aspx */ stream_write_uint32(output, 12 + len); /* Length */ stream_check_size(output, 12 + len); stream_write_uint32(output, 0); /* NextEntryOffset */ stream_write_uint32(output, 0); /* FileIndex */ stream_write_uint32(output, len); /* FileNameLength */ stream_write(output, ent_path, len); break; default: stream_write_uint32(output, 0); /* Length */ stream_write_uint8(output, 0); /* Padding */ DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); ret = false; break; } xfree(ent_path); return ret; }
boolean disk_file_set_information(DISK_FILE* file, uint32 FsInformationClass, uint32 Length, STREAM* input) { char* s; mode_t m; uint64 size; char* fullpath; struct stat st; UNICONV* uniconv; struct timeval tv[2]; uint64 LastWriteTime; uint32 FileAttributes; uint32 FileNameLength; switch (FsInformationClass) { case FileBasicInformation: /* http://msdn.microsoft.com/en-us/library/cc232094.aspx */ stream_seek_uint64(input); /* CreationTime */ stream_seek_uint64(input); /* LastAccessTime */ stream_read_uint64(input, LastWriteTime); stream_seek_uint64(input); /* ChangeTime */ stream_read_uint32(input, FileAttributes); if (fstat(file->fd, &st) != 0) return false; tv[0].tv_sec = st.st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = (LastWriteTime > 0 ? FILE_TIME_RDP_TO_SYSTEM(LastWriteTime) : st.st_mtime); tv[1].tv_usec = 0; futimes(file->fd, tv); if (FileAttributes > 0) { m = st.st_mode; if ((FileAttributes & FILE_ATTRIBUTE_READONLY) == 0) m |= S_IWUSR; else m &= ~S_IWUSR; if (m != st.st_mode) fchmod(file->fd, st.st_mode); } break; case FileEndOfFileInformation: /* http://msdn.microsoft.com/en-us/library/cc232067.aspx */ case FileAllocationInformation: /* http://msdn.microsoft.com/en-us/library/cc232076.aspx */ stream_read_uint64(input, size); if (ftruncate(file->fd, size) != 0) return false; break; case FileDispositionInformation: /* http://msdn.microsoft.com/en-us/library/cc232098.aspx */ stream_read_uint8(input, file->delete_pending); break; case FileRenameInformation: /* http://msdn.microsoft.com/en-us/library/cc232085.aspx */ stream_seek_uint8(input); /* ReplaceIfExists */ stream_seek_uint8(input); /* RootDirectory */ stream_read_uint32(input, FileNameLength); uniconv = freerdp_uniconv_new(); s = freerdp_uniconv_in(uniconv, stream_get_tail(input), FileNameLength); freerdp_uniconv_free(uniconv); fullpath = disk_file_combine_fullpath(file->basepath, s); xfree(s); if (rename(file->fullpath, fullpath) == 0) { DEBUG_SVC("renamed %s to %s", file->fullpath, fullpath); disk_file_set_fullpath(file, fullpath); } else { DEBUG_WARN("rename %s to %s failed", file->fullpath, fullpath); free(fullpath); return false; } break; default: DEBUG_WARN("invalid FsInformationClass %d", FsInformationClass); return false; } return true; }
void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer) { PRINTER_DEVICE* printer_dev; char* port; UNICONV* uniconv; uint32 Flags; size_t DriverNameLen; char* DriverName; size_t PrintNameLen; char* PrintName; uint32 CachedFieldsLen; uint8* CachedPrinterConfigData; port = xmalloc(10); snprintf(port, 10, "PRN%d", printer->id); printer_dev = xnew(PRINTER_DEVICE); printer_dev->device.type = RDPDR_DTYP_PRINT; printer_dev->device.name = port; printer_dev->device.IRPRequest = printer_irp_request; printer_dev->device.Free = printer_free; printer_dev->printer = printer; CachedFieldsLen = 0; CachedPrinterConfigData = NULL; log_debug("Printer '%s' registered", printer->name); Flags = 0; if (printer->is_default) Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; uniconv = freerdp_uniconv_new(); DriverName = freerdp_uniconv_out(uniconv, printer->driver, &DriverNameLen); PrintName = freerdp_uniconv_out(uniconv, printer->name, &PrintNameLen); freerdp_uniconv_free(uniconv); printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen); stream_write_uint32(printer_dev->device.data, Flags); stream_write_uint32(printer_dev->device.data, 0); /* CodePage, reserved */ stream_write_uint32(printer_dev->device.data, 0); /* PnPNameLen */ stream_write_uint32(printer_dev->device.data, DriverNameLen + 2); stream_write_uint32(printer_dev->device.data, PrintNameLen + 2); stream_write_uint32(printer_dev->device.data, CachedFieldsLen); stream_write(printer_dev->device.data, DriverName, DriverNameLen); stream_write_uint16(printer_dev->device.data, 0); stream_write(printer_dev->device.data, PrintName, PrintNameLen); stream_write_uint16(printer_dev->device.data, 0); if (CachedFieldsLen > 0) { stream_write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen); } xfree(DriverName); xfree(PrintName); printer_dev->irp_list = list_new(); printer_dev->thread = freerdp_thread_new(); pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) printer_dev); freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev); }
static uint32 disk_query_volume_info(IRP * irp) { FILE_INFO * finfo; struct STATFS_T stat_fs; uint32 status; int size; char * buf; size_t len; UNICONV * uniconv; char * s; LLOGLN(10, ("disk_query_volume_info: class=%d id=%d", irp->infoClass, irp->fileID)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL) { LLOGLN(0, ("disk_query_volume_info: invalid file id")); return RD_STATUS_INVALID_HANDLE; } if (STATFS_FN(finfo->fullpath, &stat_fs) != 0) { LLOGLN(0, ("disk_query_volume_info: statfs failed")); return RD_STATUS_ACCESS_DENIED; } size = 0; buf = NULL; status = RD_STATUS_SUCCESS; uniconv = freerdp_uniconv_new(); switch (irp->infoClass) { case FileFsVolumeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT64(buf, 0, 0); /* VolumeCreationTime */ SET_UINT32(buf, 8, 0); /* VolumeSerialNumber */ s = freerdp_uniconv_out(uniconv, "FREERDP", &len); memcpy(buf + 17, s, len); xfree(s); SET_UINT32(buf, 12, len); /* VolumeLabelLength */ SET_UINT8(buf, 16, 0); /* SupportsObjects */ size = 17 + len; break; case FileFsSizeInformation: size = 24; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* AvailableAllocationUnits */ SET_UINT32(buf, 16, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 20, 0x200); /* BytesPerSector */ break; case FileFsAttributeInformation: buf = malloc(256); memset(buf, 0, 256); SET_UINT32(buf, 0, FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ SET_UINT32(buf, 4, F_NAMELEN(stat_fs)); /* MaximumComponentNameLength */ s = freerdp_uniconv_out(uniconv, "FREERDP", &len); memcpy(buf + 17, s, len); xfree(s); SET_UINT32(buf, 8, len); /* FileSystemNameLength */ size = 12 + len; break; case FileFsFullSizeInformation: size = 32; buf = malloc(size); memset(buf, 0, size); SET_UINT64(buf, 0, stat_fs.f_blocks); /* TotalAllocationUnits */ SET_UINT64(buf, 8, stat_fs.f_bfree); /* CallerAvailableAllocationUnits */ SET_UINT64(buf, 16, stat_fs.f_bfree); /* ActualAvailableAllocationUnits */ SET_UINT32(buf, 24, stat_fs.f_bsize / 0x200); /* SectorsPerAllocationUnit */ SET_UINT32(buf, 28, 0x200); /* BytesPerSector */ break; case FileFsDeviceInformation: size = 8; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, FILE_DEVICE_DISK); /* DeviceType */ SET_UINT32(buf, 4, 0); /* BytesPerSector */ break; default: LLOGLN(0, ("disk_query_volume_info: invalid info class")); status = RD_STATUS_NOT_SUPPORTED; break; } freerdp_uniconv_free(uniconv); irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }
static uint32 disk_set_info(IRP * irp) { FILE_INFO *finfo; uint32 status; uint64 len; char * buf; char * fullpath; struct stat file_stat; struct utimbuf tvs; int mode; uint32 attr; time_t t; UNICONV * uniconv; LLOGLN(10, ("disk_set_info: class=%d id=%d", irp->infoClass, irp->fileID)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL) { LLOGLN(0, ("disk_set_info: invalid file id")); return RD_STATUS_INVALID_HANDLE; } status = RD_STATUS_SUCCESS; switch (irp->infoClass) { case FileBasicInformation: if (stat(finfo->fullpath, &file_stat) != 0) return get_error_status(); /* Change file time */ tvs.actime = file_stat.st_atime; tvs.modtime = file_stat.st_mtime; t = get_system_filetime(GET_UINT64(irp->inputBuffer, 8)); /* LastAccessTime */ if (t > 0) tvs.actime = t; t = get_system_filetime(GET_UINT64(irp->inputBuffer, 16)); /* LastWriteTime */ if (t > 0) tvs.modtime = t; utime(finfo->fullpath, &tvs); /* Change read-only flag */ attr = GET_UINT32(irp->inputBuffer, 32); if (attr == 0) break; mode = file_stat.st_mode; if (attr & FILE_ATTRIBUTE_READONLY) mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); else mode |= S_IWUSR; mode &= 0777; chmod(finfo->fullpath, mode); break; case FileEndOfFileInformation: case FileAllocationInformation: len = GET_UINT64(irp->inputBuffer, 0); set_file_size(finfo->file, len); break; case FileDispositionInformation: /* Delete on close */ finfo->delete_pending = 1; break; case FileRenameInformation: //replaceIfExists = GET_UINT8(irp->inputBuffer, 0); /* ReplaceIfExists */ //rootDirectory = GET_UINT8(irp->inputBuffer, 1); /* RootDirectory */ len = GET_UINT32(irp->inputBuffer, 2); uniconv = freerdp_uniconv_new(); buf = freerdp_uniconv_in(uniconv, (unsigned char*) (irp->inputBuffer + 6), len); freerdp_uniconv_free(uniconv); fullpath = disk_get_fullpath(irp->dev, buf); xfree(buf); LLOGLN(10, ("disk_set_info: rename %s to %s", finfo->fullpath, fullpath)); if (rename(finfo->fullpath, fullpath) == 0) { free(finfo->fullpath); finfo->fullpath = fullpath; } else { free(fullpath); return get_error_status(); } break; default: LLOGLN(0, ("disk_set_info: invalid info class")); status = RD_STATUS_NOT_SUPPORTED; break; } return status; }
static uint32 disk_query_directory(IRP * irp, uint8 initialQuery, const char * path) { DISK_DEVICE_INFO * info; FILE_INFO * finfo; char * p; uint32 status; char * buf; int size; size_t len; struct dirent * pdirent; struct stat file_stat; uint32 attr; UNICONV * uniconv; LLOGLN(10, ("disk_query_directory: class=%d id=%d init=%d path=%s", irp->infoClass, irp->fileID, initialQuery, path)); finfo = disk_get_file_info(irp->dev, irp->fileID); if (finfo == NULL || finfo->dir == NULL) { LLOGLN(0, ("disk_query_directory: invalid file id")); return RD_STATUS_INVALID_HANDLE; } info = (DISK_DEVICE_INFO *) irp->dev->info; if (initialQuery) { if (finfo->pattern) free(finfo->pattern); p = strrchr(path, '\\'); p = (p ? p + 1 : (char *)path); finfo->pattern = malloc(strlen(p) + 1); strcpy(finfo->pattern, p); rewinddir(finfo->dir); } status = RD_STATUS_SUCCESS; buf = NULL; size = 0; pdirent = readdir(finfo->dir); while (pdirent && finfo->pattern[0] && fnmatch(finfo->pattern, pdirent->d_name, 0) != 0) pdirent = readdir(finfo->dir); if (pdirent == NULL) { return RD_STATUS_NO_MORE_FILES; } memset(&file_stat, 0, sizeof(struct stat)); p = malloc(strlen(finfo->fullpath) + strlen(pdirent->d_name) + 2); sprintf(p, "%s/%s", finfo->fullpath, pdirent->d_name); if (stat(p, &file_stat) != 0) { LLOGLN(0, ("disk_query_directory: stat %s failed (%i)\n", p, errno)); } free(p); attr = get_file_attribute(pdirent->d_name, &file_stat); uniconv = freerdp_uniconv_new(); switch (irp->infoClass) { case FileBothDirectoryInformation: size = 93 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ? file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */ SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */ SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */ SET_UINT32(buf, 56, attr); /* FileAttributes */ SET_UINT32(buf, 64, 0); /* EaSize */ SET_UINT8(buf, 68, 0); /* ShortNameLength */ /* [MS-FSCC] has one byte padding here but RDP does not! */ //SET_UINT8(buf, 69, 0); /* Reserved */ /* ShortName 24 bytes */ p = freerdp_uniconv_out(uniconv, pdirent->d_name, &len); memcpy(buf + 93, p, len); xfree(p); SET_UINT32(buf, 60, len); /* FileNameLength */ size = 93 + len; break; case FileFullDirectoryInformation: size = 68 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ? file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */ SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */ SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */ SET_UINT32(buf, 56, attr); /* FileAttributes */ SET_UINT32(buf, 64, 0); /* EaSize */ p = freerdp_uniconv_out(uniconv, pdirent->d_name, &len); memcpy(buf + 68, p, len); xfree(p); SET_UINT32(buf, 60, len); /* FileNameLength */ size = 68 + len; break; case FileNamesInformation: size = 12 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ p = freerdp_uniconv_out(uniconv, pdirent->d_name, &len); memcpy(buf + 12, p, len); xfree(p); SET_UINT32(buf, 8, len); /* FileNameLength */ size = 12 + len; break; case FileDirectoryInformation: size = 64 + strlen(pdirent->d_name) * 2; buf = malloc(size); memset(buf, 0, size); SET_UINT32(buf, 0, 0); /* NextEntryOffset */ SET_UINT32(buf, 4, 0); /* FileIndex */ SET_UINT64(buf, 8, get_rdp_filetime(file_stat.st_ctime < file_stat.st_mtime ? file_stat.st_ctime : file_stat.st_mtime)); /* CreationTime */ SET_UINT64(buf, 16, get_rdp_filetime(file_stat.st_atime)); /* LastAccessTime */ SET_UINT64(buf, 24, get_rdp_filetime(file_stat.st_mtime)); /* LastWriteTime */ SET_UINT64(buf, 32, get_rdp_filetime(file_stat.st_ctime)); /* ChangeTime */ SET_UINT64(buf, 40, file_stat.st_size); /* EndOfFile */ SET_UINT64(buf, 48, file_stat.st_size); /* AllocationSize */ SET_UINT32(buf, 56, attr); /* FileAttributes */ p = freerdp_uniconv_out(uniconv, pdirent->d_name, &len); memcpy(buf + 64, p, len); xfree(p); SET_UINT32(buf, 60, len); /* FileNameLength */ size = 64 + len; break; default: LLOGLN(0, ("disk_query_directory: invalid info class %d", irp->infoClass)); status = RD_STATUS_NOT_SUPPORTED; break; } freerdp_uniconv_free(uniconv); irp->outputBuffer = buf; irp->outputBufferLength = size; return status; }
int printer_register(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints, SERVICE * srv, const char * name, const char * driver, int is_default, int * port) { DEVICE * dev; char buf[8]; uint32 flags; int size; int offset; size_t len; char * s; char * cache_data; int cache_data_len; UNICONV * uniconv; LLOGLN(0, ("printer_register: %s (default=%d)", name, is_default)); if (driver == NULL) { /* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */ driver = "MS Publisher Imagesetter"; } snprintf(buf, sizeof(buf) - 1, "PRN%d", *port); *port += 1; dev = pEntryPoints->pDevmanRegisterDevice(pDevman, srv, buf); dev->info = printer_hw_new(name); cache_data = printer_get_data(name, &cache_data_len); size = 24 + 4 + (strlen(name) + 1) * 2 + (strlen(driver) + 1) * 2 + cache_data_len; dev->data = malloc(size); memset(dev->data, 0, size); /*flags = RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT;*/ flags = 0; if (is_default) flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER; uniconv = freerdp_uniconv_new(); SET_UINT32 (dev->data, 0, flags); /* Flags */ SET_UINT32 (dev->data, 4, 0); /* CodePage, reserved */ SET_UINT32 (dev->data, 8, 0); /* PnPNameLen */ SET_UINT32 (dev->data, 20, cache_data_len); /* CachedFieldsLen */ offset = 24; s = freerdp_uniconv_out(uniconv, (char *) driver, &len); memcpy(&dev->data[offset], s, len); xfree(s); len += 2; SET_UINT32 (dev->data, 12, len); /* DriverNameLen */ offset += len; s = freerdp_uniconv_out(uniconv, (char *) name, &len); memcpy(&dev->data[offset], s, len); xfree(s); len += 2; SET_UINT32 (dev->data, 16, len); /* PrintNameLen */ offset += len; if (cache_data) { memcpy(&dev->data[offset], cache_data, cache_data_len); offset += cache_data_len; free(cache_data); } dev->data_len = offset; freerdp_uniconv_free(uniconv); return 0; }