void rdp_write_extended_info_packet(STREAM* s, rdpSettings* settings) { size_t length; uint16 clientAddressFamily; uint8* clientAddress; uint16 cbClientAddress; uint8* clientDir; uint16 cbClientDir; uint16 cbAutoReconnectLen; clientAddressFamily = settings->ipv6 ? ADDRESS_FAMILY_INET6 : ADDRESS_FAMILY_INET; clientAddress = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->ip_address, &length); cbClientAddress = length; clientDir = (uint8*) freerdp_uniconv_out(settings->uniconv, settings->client_dir, &length); cbClientDir = length; cbAutoReconnectLen = settings->client_auto_reconnect_cookie->cbLen; stream_write_uint16(s, clientAddressFamily); /* clientAddressFamily */ stream_write_uint16(s, cbClientAddress + 2); /* cbClientAddress */ if (cbClientAddress > 0) stream_write(s, clientAddress, cbClientAddress); /* clientAddress */ stream_write_uint16(s, 0); stream_write_uint16(s, cbClientDir + 2); /* cbClientDir */ if (cbClientDir > 0) stream_write(s, clientDir, cbClientDir); /* clientDir */ stream_write_uint16(s, 0); rdp_write_client_time_zone(s, settings); /* clientTimeZone */ stream_write_uint32(s, 0); /* clientSessionId, should be set to 0 */ stream_write_uint32(s, settings->performance_flags); /* performanceFlags */ stream_write_uint16(s, cbAutoReconnectLen); /* cbAutoReconnectLen */ if (cbAutoReconnectLen > 0) rdp_write_client_auto_reconnect_cookie(s, settings); /* autoReconnectCookie */ /* reserved1 (2 bytes) */ /* reserved2 (2 bytes) */ xfree(clientAddress); xfree(clientDir); }
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_SetContextIdentity(NTLM_CONTEXT* context, SEC_WINNT_AUTH_IDENTITY* identity) { size_t size; context->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI) { context->identity.User = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->User, &size); context->identity.UserLength = (uint32) size; if (identity->DomainLength > 0) { context->identity.Domain = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->Domain, &size); context->identity.DomainLength = (uint32) size; } else { context->identity.Domain = (uint16*) NULL; context->identity.DomainLength = 0; } context->identity.Password = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->Password, &size); context->identity.PasswordLength = (uint32) size; } else { context->identity.User = (uint16*) xmalloc(identity->UserLength); memcpy(context->identity.User, identity->User, identity->UserLength); context->identity.UserLength = identity->UserLength; if (identity->DomainLength > 0) { context->identity.Domain = (uint16*) xmalloc(identity->DomainLength); memcpy(context->identity.Domain, identity->Domain, identity->DomainLength); context->identity.DomainLength = identity->DomainLength; } else { context->identity.Domain = (uint16*) NULL; context->identity.DomainLength = 0; } context->identity.Password = (uint16*) xmalloc(identity->PasswordLength); memcpy(context->identity.Password, identity->Password, identity->PasswordLength); context->identity.PasswordLength = identity->PasswordLength; } }
void krb_SetContextIdentity(KRB_CONTEXT* context, SEC_WINNT_AUTH_IDENTITY* identity) { size_t size; /* TEMPORARY workaround for utf8 TODO: UTF16 to utf8 */ identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; context->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI) { context->identity.User = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->User, &size); context->identity.UserLength = (uint32) size; if (identity->DomainLength > 0) { context->identity.Domain = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->Domain, &size); context->identity.DomainLength = (uint32) size; } else { context->identity.Domain = (uint16*) NULL; context->identity.DomainLength = 0; } context->identity.Password = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) identity->Password, &size); context->identity.PasswordLength = (uint32) size; } else { context->identity.User = (uint16*) xzalloc(identity->UserLength + 1); memcpy(context->identity.User, identity->User, identity->UserLength); if (identity->DomainLength > 0) { context->identity.Domain = (uint16*) xmalloc(identity->DomainLength); memcpy(context->identity.Domain, identity->Domain, identity->DomainLength); } else { context->identity.Domain = (uint16*) NULL; context->identity.DomainLength = 0; } context->identity.Password = (uint16*) xzalloc(identity->PasswordLength + 1); memcpy(context->identity.Password, identity->Password, identity->PasswordLength); identity->Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; } }
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) { size_t length; uint8* standardName; uint8* daylightName; size_t standardNameLength; size_t daylightNameLength; TIME_ZONE_INFO* clientTimeZone; rdp_get_client_time_zone(s, settings); clientTimeZone = settings->client_time_zone; standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length); standardNameLength = length; daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length); daylightNameLength = length; if (standardNameLength > 62) standardNameLength = 62; if (daylightNameLength > 62) daylightNameLength = 62; stream_write_uint32(s, clientTimeZone->bias); /* Bias */ /* standardName (64 bytes) */ stream_write(s, standardName, standardNameLength); stream_write_zero(s, 64 - standardNameLength); rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ stream_write_uint32(s, clientTimeZone->standardBias); /* StandardBias */ /* daylightName (64 bytes) */ stream_write(s, daylightName, daylightNameLength); stream_write_zero(s, 64 - daylightNameLength); rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ stream_write_uint32(s, clientTimeZone->daylightBias); /* DaylightBias */ xfree(standardName); xfree(daylightName); }
void credssp_SetContextIdentity(rdpCredssp* context, char* user, char* domain, char* password) { size_t size; context->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; context->identity.User = (uint16*) freerdp_uniconv_out(context->uniconv, user, &size); context->identity.UserLength = (uint32) size; if (domain) { context->identity.Domain = (uint16*) freerdp_uniconv_out(context->uniconv, domain, &size); context->identity.DomainLength = (uint32) size; } else { context->identity.Domain = (uint16*) NULL; context->identity.DomainLength = 0; } context->identity.Password = (uint16*) freerdp_uniconv_out(context->uniconv, (char*) password, &size); context->identity.PasswordLength = (uint32) size; }
void ntlm_populate_server_av_pairs(NTLM_CONTEXT* context) { int length; size_t size; AV_PAIRS* av_pairs = context->av_pairs; av_pairs->NbDomainName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_NbDomainName, &size); av_pairs->NbDomainName.length = (uint16) size; av_pairs->NbComputerName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_NbComputerName, &size); av_pairs->NbComputerName.length = (uint16) size; av_pairs->DnsDomainName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_DnsDomainName, &size); av_pairs->DnsDomainName.length = (uint16) size; av_pairs->DnsComputerName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_DnsComputerName, &size); av_pairs->DnsComputerName.length = (uint16) size; length = ntlm_compute_av_pairs_length(context) + 4; sspi_SecBufferAlloc(&context->TargetInfo, length); ntlm_output_av_pairs(context, &context->TargetInfo); }
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; }
void rail_string_to_unicode_string(rdpRailOrder* rail_order, char* string, UNICODE_STRING* unicode_string) { char* buffer; size_t length = 0; if (unicode_string->string != NULL) xfree(unicode_string->string); unicode_string->string = NULL; unicode_string->length = 0; if (string == NULL || strlen(string) < 1) return; buffer = freerdp_uniconv_out(rail_order->uniconv, string, &length); unicode_string->string = (uint8*) buffer; unicode_string->length = (uint16) length; }
void rdp_write_info_packet(STREAM* s, rdpSettings* settings) { size_t length; uint32 flags; uint8* domain; uint16 cbDomain; uint8* userName; uint16 cbUserName; uint8* password; uint16 cbPassword; uint8* alternateShell; uint16 cbAlternateShell; uint8* workingDir; uint16 cbWorkingDir; flags = INFO_MOUSE | INFO_UNICODE | INFO_LOGONERRORS | INFO_LOGONNOTIFY | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | INFO_DISABLECTRLALTDEL | RNS_INFO_AUDIOCAPTURE; if (settings->autologon) flags |= INFO_AUTOLOGON; if (settings->remote_app) flags |= INFO_RAIL; if (settings->console_audio) flags |= INFO_REMOTECONSOLEAUDIO; if (settings->compression) flags |= INFO_COMPRESSION | INFO_PACKET_COMPR_TYPE_64K; domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length); cbDomain = length; userName = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->username, &length); cbUserName = length; password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &length); cbPassword = length; alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length); cbAlternateShell = length; workingDir = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->directory, &length); cbWorkingDir = length; stream_write_uint32(s, 0); /* CodePage */ stream_write_uint32(s, flags); /* flags */ stream_write_uint16(s, cbDomain); /* cbDomain */ stream_write_uint16(s, cbUserName); /* cbUserName */ stream_write_uint16(s, cbPassword); /* cbPassword */ stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */ stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */ if (cbDomain > 0) stream_write(s, domain, cbDomain); stream_write_uint16(s, 0); if (cbUserName > 0) stream_write(s, userName, cbUserName); stream_write_uint16(s, 0); if (cbPassword > 0) stream_write(s, password, cbPassword); stream_write_uint16(s, 0); if (cbAlternateShell > 0) stream_write(s, alternateShell, cbAlternateShell); stream_write_uint16(s, 0); if (cbWorkingDir > 0) stream_write(s, workingDir, cbWorkingDir); stream_write_uint16(s, 0); xfree(domain); xfree(userName); xfree(password); xfree(alternateShell); xfree(workingDir); if (settings->rdp_version >= 5) rdp_write_extended_info_packet(s, settings); /* extraInfo */ }
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; }
void ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName) { size_t size; context->TargetName.pvBuffer = (uint16*) freerdp_uniconv_out(context->uniconv, TargetName, &size); context->TargetName.cbBuffer = (uint32) size; }
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; }
void rdp_write_client_time_zone(STREAM* s, rdpSettings* settings) { uint32 bias; sint32 sbias; uint32 bias2c; size_t length; uint8* standardName; uint8* daylightName; size_t standardNameLength; size_t daylightNameLength; TIME_ZONE_INFO* clientTimeZone; clientTimeZone = settings->client_time_zone; freerdp_time_zone_detect(clientTimeZone); standardName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->standardName, &length); standardNameLength = length; daylightName = (uint8*) freerdp_uniconv_out(settings->uniconv, clientTimeZone->daylightName, &length); daylightNameLength = length; if (standardNameLength > 62) standardNameLength = 62; if (daylightNameLength > 62) daylightNameLength = 62; /* UTC = LocalTime + Bias <-> Bias = UTC - LocalTime */ /* Translate from biases used throughout libfreerdp-locale/timezone.c * to what RDP expects, which is minutes *west* of UTC. * Though MS-RDPBCGR specifies bias as unsigned, two's complement * (a negative integer) works fine for zones east of UTC. */ if (clientTimeZone->bias <= 720) bias = -1 * clientTimeZone->bias; else bias = 1440 - clientTimeZone->bias; stream_write_uint32(s, bias); /* Bias */ /* standardName (64 bytes) */ stream_write(s, standardName, standardNameLength); stream_write_zero(s, 64 - standardNameLength); rdp_write_system_time(s, &clientTimeZone->standardDate); /* StandardDate */ DEBUG_TIMEZONE("bias=%d stdName='%s' dlName='%s'", bias, clientTimeZone->standardName, clientTimeZone->daylightName); sbias = clientTimeZone->standardBias - clientTimeZone->bias; if (sbias < 0) bias2c = (uint32) sbias; else bias2c = ~((uint32) sbias) + 1; /* Note that StandardBias is ignored if no valid standardDate is provided. */ stream_write_uint32(s, bias2c); /* StandardBias */ DEBUG_TIMEZONE("StandardBias=%d", bias2c); /* daylightName (64 bytes) */ stream_write(s, daylightName, daylightNameLength); stream_write_zero(s, 64 - daylightNameLength); rdp_write_system_time(s, &clientTimeZone->daylightDate); /* DaylightDate */ sbias = clientTimeZone->daylightBias - clientTimeZone->bias; if (sbias < 0) bias2c = (uint32) sbias; else bias2c = ~((uint32) sbias) + 1; /* Note that DaylightBias is ignored if no valid daylightDate is provided. */ stream_write_uint32(s, bias2c); /* DaylightBias */ DEBUG_TIMEZONE("DaylightBias=%d", bias2c); xfree(standardName); xfree(daylightName); }
PCtxtHandle krbctx_client_init(rdpSettings* settings, SEC_WINNT_AUTH_IDENTITY* identity) { SECURITY_STATUS status; KDCENTRY* kdclist; KDCENTRY* entry; KRB_CONTEXT* krb_ctx; uint32 fContextReq; uint32 pfContextAttr; TimeStamp expiration; if (tcp_is_ipaddr(settings->hostname)) return NULL; kdclist = krb_locate_kdc(settings); /* start the state machine with initialized to zero */ krb_ctx = kerberos_ContextNew(); for (entry = kdclist;entry != NULL; entry = entry->next) { if(!krb_tcp_connect(krb_ctx, entry)) break; } if (entry == NULL) { xfree(krb_ctx); return NULL; } krb_SetContextIdentity(krb_ctx, identity); krb_ctx->realm = xstrtoup(settings->kerberos_realm); krb_ctx->cname = xstrdup((char*)krb_ctx->identity.User); krb_ctx->settings = settings; krb_ctx->passwd.data = freerdp_uniconv_out(krb_ctx->uniconv, (char*) krb_ctx->identity.Password, (size_t*) &(krb_ctx->passwd.length)); fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE; sspi_SecureHandleSetLowerPointer(&krb_ctx->context, krb_ctx); sspi_SecureHandleSetUpperPointer(&krb_ctx->context, (void*) KRB_PACKAGE_NAME); status = kerberos_InitializeSecurityContextA(NULL, &krb_ctx->context, NULL, fContextReq, 0, SECURITY_NATIVE_DREP, NULL, 0, &krb_ctx->context, NULL, &pfContextAttr, &expiration); if(status == SEC_E_INVALID_HANDLE) { printf("failed to init kerberos\n"); return NULL; } else if(status == SEC_I_COMPLETE_AND_CONTINUE) { printf("successfully obtained ticket for TERMSRV\n"); return &krb_ctx->context; } else if(status == -1) { printf("deadend \n "); return NULL; } else { printf("shit got wrong in state machine\n"); return NULL; } }
void gcc_write_client_core_data(STREAM* s, rdpSettings *settings) { uint32 version; uint8* clientName; size_t clientNameLength; uint8 connectionType; uint16 highColorDepth; uint16 supportedColorDepths; uint16 earlyCapabilityFlags; uint8* clientDigProductId; size_t clientDigProductIdLength; gcc_write_user_data_header(s, CS_CORE, 216); version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4; clientName = freerdp_uniconv_out(settings->uniconv, settings->client_hostname, &clientNameLength); clientDigProductId = freerdp_uniconv_out(settings->uniconv, settings->client_product_id, &clientDigProductIdLength); stream_write_uint32(s, version); /* version */ stream_write_uint16(s, settings->width); /* desktopWidth */ stream_write_uint16(s, settings->height); /* desktopHeight */ stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* colorDepth, ignored because of postBeta2ColorDepth */ stream_write_uint16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */ stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout */ stream_write_uint32(s, settings->client_build); /* clientBuild */ /* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */ if (clientNameLength > 30) { clientNameLength = 30; clientName[clientNameLength] = 0; clientName[clientNameLength + 1] = 0; } stream_write(s, clientName, clientNameLength + 2); stream_write_zero(s, 32 - clientNameLength - 2); xfree(clientName); stream_write_uint32(s, settings->kbd_type); /* keyboardType */ stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */ stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */ stream_write_zero(s, 64); /* imeFileName */ stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */ stream_write_uint16(s, 1); /* clientProductID */ stream_write_uint32(s, 0); /* serialNumber (should be initialized to 0) */ highColorDepth = MIN(settings->color_depth, 24); supportedColorDepths = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT; connectionType = 0; earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU; if (settings->performance_flags == PERF_FLAG_NONE) { earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE; connectionType = CONNECTION_TYPE_LAN; } if (settings->color_depth == 32) { supportedColorDepths |= RNS_UD_32BPP_SUPPORT; earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION; } stream_write_uint16(s, highColorDepth); /* highColorDepth */ stream_write_uint16(s, supportedColorDepths); /* supportedColorDepths */ stream_write_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */ /* clientDigProductId (64 bytes, null-terminated unicode, truncated to 30 characters) */ if (clientDigProductIdLength > 62) { clientDigProductIdLength = 62; clientDigProductId[clientDigProductIdLength] = 0; clientDigProductId[clientDigProductIdLength + 1] = 0; } stream_write(s, clientDigProductId, clientDigProductIdLength + 2); stream_write_zero(s, 64 - clientDigProductIdLength - 2); xfree(clientDigProductId); stream_write_uint8(s, connectionType); /* connectionType */ stream_write_uint8(s, 0); /* pad1octet */ stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */ }
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); }
boolean ntlm_client_init(rdpNtlm* ntlm, boolean confidentiality, char* user, char* domain, char* password) { size_t size; SECURITY_STATUS status; sspi_GlobalInit(); ntlm->confidentiality = confidentiality; #ifdef WITH_NATIVE_SSPI { HMODULE hSSPI; INIT_SECURITY_INTERFACE InitSecurityInterface; PSecurityFunctionTable pSecurityInterface = NULL; hSSPI = LoadLibrary(_T("secur32.dll")); #ifdef UNICODE InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceW"); #else InitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(hSSPI, "InitSecurityInterfaceA"); #endif ntlm->table = (*InitSecurityInterface)(); } #else ntlm->table = InitSecurityInterface(); #endif ntlm->identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; ntlm->identity.User = (uint16*) freerdp_uniconv_out(ntlm->uniconv, user, &size); ntlm->identity.UserLength = (uint32) size; if (domain) { ntlm->identity.Domain = (uint16*) freerdp_uniconv_out(ntlm->uniconv, domain, &size); ntlm->identity.DomainLength = (uint32) size; } else { ntlm->identity.Domain = (uint16*) NULL; ntlm->identity.DomainLength = 0; } ntlm->identity.Password = (uint16*) freerdp_uniconv_out(ntlm->uniconv, (char*) password, &size); ntlm->identity.PasswordLength = (uint32) size; status = ntlm->table->QuerySecurityPackageInfo(NTLMSP_NAME, &ntlm->pPackageInfo); if (status != SEC_E_OK) { printf("QuerySecurityPackageInfo status: 0x%08X\n", status); return false; } ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken; status = ntlm->table->AcquireCredentialsHandle(NULL, NTLMSP_NAME, SECPKG_CRED_OUTBOUND, NULL, &ntlm->identity, NULL, NULL, &ntlm->credentials, &ntlm->expiration); if (status != SEC_E_OK) { printf("AcquireCredentialsHandle status: 0x%08X\n", status); return false; } ntlm->haveContext = false; ntlm->haveInputBuffer = false; memset(&ntlm->inputBuffer, 0, sizeof(SecBuffer)); memset(&ntlm->outputBuffer, 0, sizeof(SecBuffer)); memset(&ntlm->ContextSizes, 0, sizeof(SecPkgContext_Sizes)); ntlm->fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_DELEGATE; if (ntlm->confidentiality) ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY; return true; }
void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation) { size_t size; context->Workstation = (uint16*) freerdp_uniconv_out(context->uniconv, Workstation, &size); context->WorkstationLength = (uint32) size; }
void rdp_write_info_packet(STREAM* s, rdpSettings* settings) { size_t length; uint32 flags; uint8* domain; uint16 cbDomain; uint8* userName; uint16 cbUserName; uint8* password; uint16 cbPassword; uint8* alternateShell; uint16 cbAlternateShell; uint8* workingDir; uint16 cbWorkingDir; boolean usedPasswordCookie = false; flags = INFO_MOUSE | INFO_UNICODE | INFO_LOGONERRORS | INFO_LOGONNOTIFY | INFO_MAXIMIZESHELL | INFO_ENABLEWINDOWSKEY | INFO_DISABLECTRLALTDEL; if (settings->audio_capture) flags |= RNS_INFO_AUDIOCAPTURE; if (!settings->audio_playback) flags |= INFO_NOAUDIOPLAYBACK; if (settings->autologon) flags |= INFO_AUTOLOGON; if (settings->remote_app) flags |= INFO_RAIL; if (settings->console_audio) flags |= INFO_REMOTECONSOLEAUDIO; if (settings->compression) flags |= INFO_COMPRESSION | INFO_PACKET_COMPR_TYPE_RDP6; domain = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->domain, &length); cbDomain = length; userName = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->username, &length); cbUserName = length; if (settings->password_cookie && settings->password_cookie->length > 0) { usedPasswordCookie = true; password = (uint8*)settings->password_cookie->data; cbPassword = settings->password_cookie->length - 2; /* Strip double zero termination */ } else { password = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->password, &length); cbPassword = length; } alternateShell = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->shell, &length); cbAlternateShell = length; workingDir = (uint8*)freerdp_uniconv_out(settings->uniconv, settings->directory, &length); cbWorkingDir = length; stream_write_uint32(s, 0); /* CodePage */ stream_write_uint32(s, flags); /* flags */ stream_write_uint16(s, cbDomain); /* cbDomain */ stream_write_uint16(s, cbUserName); /* cbUserName */ stream_write_uint16(s, cbPassword); /* cbPassword */ stream_write_uint16(s, cbAlternateShell); /* cbAlternateShell */ stream_write_uint16(s, cbWorkingDir); /* cbWorkingDir */ if (cbDomain > 0) stream_write(s, domain, cbDomain); stream_write_uint16(s, 0); if (cbUserName > 0) stream_write(s, userName, cbUserName); stream_write_uint16(s, 0); if (cbPassword > 0) stream_write(s, password, cbPassword); stream_write_uint16(s, 0); if (cbAlternateShell > 0) stream_write(s, alternateShell, cbAlternateShell); stream_write_uint16(s, 0); if (cbWorkingDir > 0) stream_write(s, workingDir, cbWorkingDir); stream_write_uint16(s, 0); xfree(domain); xfree(userName); xfree(alternateShell); xfree(workingDir); if (!usedPasswordCookie) xfree(password); if (settings->rdp_version >= 5) rdp_write_extended_info_packet(s, settings); /* extraInfo */ }
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; }
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; }