Esempio n. 1
0
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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
	}
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}
Esempio n. 11
0
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 */
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
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;
}
Esempio n. 15
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);
}
Esempio n. 16
0
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;
	}
}
Esempio n. 17
0
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 */
}
Esempio n. 18
0
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);
}
Esempio n. 19
0
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;
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
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 */
}
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}