Merge pull request #2639 from awakecoding/master
WLog, server-side rdpdr, remote assistance, byteswap, etc
This commit is contained in:
commit
36cb1e6dc9
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Device Redirection Virtual Channel Extension
|
||||
*
|
||||
* Copyright 2014 Dell Software <Mike.McDonald@software.dell.com>
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -20,6 +21,7 @@
|
||||
#ifndef FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H
|
||||
#define FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H
|
||||
|
||||
#include <winpr/collections.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
@ -39,6 +41,9 @@ struct _rdpdr_server_private
|
||||
char* ClientComputerName;
|
||||
|
||||
BOOL UserLoggedOnPdu;
|
||||
|
||||
wListDictionary* IrpList;
|
||||
UINT32 NextCompletionId;
|
||||
};
|
||||
|
||||
#define RDPDR_HEADER_LENGTH 4
|
||||
@ -67,4 +72,16 @@ struct _RDPDR_CAPABILITY_HEADER
|
||||
};
|
||||
typedef struct _RDPDR_CAPABILITY_HEADER RDPDR_CAPABILITY_HEADER;
|
||||
|
||||
struct _RDPDR_IRP
|
||||
{
|
||||
UINT32 CompletionId;
|
||||
UINT32 DeviceId;
|
||||
UINT32 FileId;
|
||||
char PathName[256];
|
||||
char ExtraBuffer[256];
|
||||
void *CallbackData;
|
||||
BOOL (*Callback)(RdpdrServerContext* context, wStream* s, struct _RDPDR_IRP* irp, UINT32 deviceId, UINT32 completionId, UINT32 ioStatus);
|
||||
};
|
||||
typedef struct _RDPDR_IRP RDPDR_IRP;
|
||||
|
||||
#endif /* FREERDP_CHANNEL_SERVER_RDPDR_MAIN_H */
|
||||
|
@ -133,7 +133,7 @@ BOOL wf_sw_desktop_resize(wfContext* wfc)
|
||||
rdpGdi* gdi;
|
||||
rdpContext* context;
|
||||
rdpSettings* settings;
|
||||
freerdp *instance = wfc->instance;
|
||||
freerdp* instance = wfc->instance;
|
||||
|
||||
context = (rdpContext*) wfc;
|
||||
settings = wfc->instance->settings;
|
||||
@ -142,7 +142,9 @@ BOOL wf_sw_desktop_resize(wfContext* wfc)
|
||||
wfc->width = settings->DesktopWidth;
|
||||
wfc->height = settings->DesktopHeight;
|
||||
|
||||
gdi->primary->bitmap->data = NULL;
|
||||
gdi_free(instance);
|
||||
|
||||
if (wfc->primary)
|
||||
{
|
||||
wf_image_free(wfc->primary);
|
||||
@ -154,6 +156,7 @@ BOOL wf_sw_desktop_resize(wfContext* wfc)
|
||||
|
||||
gdi = instance->context->gdi;
|
||||
wfc->hdc = gdi->primary->hdc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -49,18 +49,20 @@ HBITMAP wf_create_dib(wfContext* wfc, int width, int height, int bpp, BYTE* data
|
||||
negHeight = (height < 0) ? height : height * (-1);
|
||||
|
||||
hdc = GetDC(NULL);
|
||||
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
|
||||
bmi.bmiHeader.biWidth = width;
|
||||
bmi.bmiHeader.biHeight = negHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = wfc->dstBpp;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, (void**) &cdata, NULL, 0);
|
||||
|
||||
if (data != NULL)
|
||||
if (data)
|
||||
freerdp_image_convert(data, cdata, width, height, bpp, wfc->dstBpp, wfc->clrconv);
|
||||
|
||||
if (pdata != NULL)
|
||||
if (pdata)
|
||||
*pdata = cdata;
|
||||
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
@ -51,6 +51,7 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
pEntryPoints->GlobalInit();
|
||||
|
||||
instance = freerdp_new();
|
||||
|
||||
if (!instance)
|
||||
return NULL;
|
||||
|
||||
@ -59,11 +60,12 @@ rdpContext* freerdp_client_context_new(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
||||
instance->ContextNew = freerdp_client_common_new;
|
||||
instance->ContextFree = freerdp_client_common_free;
|
||||
instance->pClientEntryPoints = (RDP_CLIENT_ENTRY_POINTS*) malloc(pEntryPoints->Size);
|
||||
|
||||
if (!instance->pClientEntryPoints)
|
||||
goto out_fail;
|
||||
|
||||
|
||||
CopyMemory(instance->pClientEntryPoints, pEntryPoints, pEntryPoints->Size);
|
||||
|
||||
if (!freerdp_context_new(instance))
|
||||
goto out_fail2;
|
||||
|
||||
@ -202,7 +204,7 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc,
|
||||
|
||||
/* This function will call logic that is applicable to the settings
|
||||
* from command line parsing AND the rdp file parsing */
|
||||
if(!freerdp_client_settings_post_process(settings))
|
||||
if (!freerdp_client_settings_post_process(settings))
|
||||
status = -1;
|
||||
|
||||
return status;
|
||||
|
@ -932,33 +932,39 @@ int freerdp_map_keyboard_layout_name_to_id(char* name)
|
||||
RDP_KEYBOARD_LAYOUT* layouts;
|
||||
|
||||
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_STANDARD);
|
||||
|
||||
for (i = 0; layouts[i].code; i++)
|
||||
{
|
||||
if (_stricmp(layouts[i].name, name) == 0)
|
||||
id = layouts[i].code;
|
||||
}
|
||||
|
||||
free(layouts);
|
||||
|
||||
if (id)
|
||||
return id;
|
||||
|
||||
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_VARIANT);
|
||||
|
||||
for (i = 0; layouts[i].code; i++)
|
||||
{
|
||||
if (_stricmp(layouts[i].name, name) == 0)
|
||||
id = layouts[i].code;
|
||||
}
|
||||
|
||||
free(layouts);
|
||||
|
||||
if (id)
|
||||
return id;
|
||||
|
||||
layouts = freerdp_keyboard_get_layouts(RDP_KEYBOARD_LAYOUT_TYPE_IME);
|
||||
|
||||
for (i = 0; layouts[i].code; i++)
|
||||
{
|
||||
if (_stricmp(layouts[i].name, name) == 0)
|
||||
id = layouts[i].code;
|
||||
}
|
||||
|
||||
free(layouts);
|
||||
|
||||
if (id)
|
||||
@ -982,6 +988,14 @@ int freerdp_detect_command_line_pre_filter(void* context, int index, int argc, L
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 13)
|
||||
{
|
||||
if (_stricmp(&(argv[index])[length - 13], ".msrcIncident") == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -997,6 +1011,7 @@ int freerdp_detect_windows_style_command_line_syntax(int argc, char** argv,
|
||||
|
||||
flags = COMMAND_LINE_SEPARATOR_COLON;
|
||||
flags |= COMMAND_LINE_SIGIL_SLASH | COMMAND_LINE_SIGIL_PLUS_MINUS;
|
||||
|
||||
if (ignoreUnknown)
|
||||
{
|
||||
flags |= COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||
@ -1040,6 +1055,7 @@ int freerdp_detect_posix_style_command_line_syntax(int argc, char** argv,
|
||||
flags = COMMAND_LINE_SEPARATOR_SPACE;
|
||||
flags |= COMMAND_LINE_SIGIL_DASH | COMMAND_LINE_SIGIL_DOUBLE_DASH;
|
||||
flags |= COMMAND_LINE_SIGIL_ENABLE_DISABLE;
|
||||
|
||||
if (ignoreUnknown)
|
||||
{
|
||||
flags |= COMMAND_LINE_IGN_UNKNOWN_KEYWORD;
|
||||
|
@ -11,6 +11,8 @@ find_library(PULSE_LIBRARY pulse PATHS ${PULSE_LIBRARY_DIRS})
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pulse DEFAULT_MSG PULSE_INCLUDE_DIR PULSE_LIBRARY)
|
||||
|
||||
if(PULSE_LIBRARY)
|
||||
set(PULSE_FOUND 1)
|
||||
|
||||
file(STRINGS "${PULSE_INCLUDE_DIR}/pulse/version.h" STR1 REGEX "PA_MAJOR")
|
||||
file(STRINGS "${PULSE_INCLUDE_DIR}/pulse/version.h" STR2 REGEX "PA_MINOR")
|
||||
file(STRINGS "${PULSE_INCLUDE_DIR}/pulse/version.h" STR3 REGEX "PA_MICRO")
|
||||
|
@ -47,6 +47,11 @@ struct rdp_assistance_file
|
||||
|
||||
char* MachineAddress;
|
||||
UINT32 MachinePort;
|
||||
|
||||
UINT32 MachineCount;
|
||||
char** MachineAddresses;
|
||||
UINT32* MachinePorts;
|
||||
|
||||
char* RASessionId;
|
||||
char* RASpecificParams;
|
||||
};
|
||||
|
@ -129,9 +129,11 @@
|
||||
#define GDIOBJECT_REGION 0x05
|
||||
|
||||
/* Region return values */
|
||||
#ifndef NULLREGION
|
||||
#define NULLREGION 0x01
|
||||
#define SIMPLEREGION 0x02
|
||||
#define COMPLEXREGION 0x03
|
||||
#endif
|
||||
|
||||
struct _GDIOBJECT
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Device Redirection Virtual Channel Server Interface
|
||||
*
|
||||
* Copyright 2014 Dell Software <Mike.McDonald@software.dell.com>
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@ -32,9 +33,55 @@
|
||||
typedef struct _rdpdr_server_context RdpdrServerContext;
|
||||
typedef struct _rdpdr_server_private RdpdrServerPrivate;
|
||||
|
||||
struct _FILE_DIRECTORY_INFORMATION
|
||||
{
|
||||
UINT32 NextEntryOffset;
|
||||
UINT32 FileIndex;
|
||||
UINT64 CreationTime;
|
||||
UINT64 LastAccessTime;
|
||||
UINT64 LastWriteTime;
|
||||
UINT64 ChangeTime;
|
||||
UINT64 EndOfFile;
|
||||
UINT64 AllocationSize;
|
||||
UINT32 FileAttributes;
|
||||
char FileName[512];
|
||||
};
|
||||
typedef struct _FILE_DIRECTORY_INFORMATION FILE_DIRECTORY_INFORMATION;
|
||||
|
||||
typedef int (*psRdpdrStart)(RdpdrServerContext* context);
|
||||
typedef int (*psRdpdrStop)(RdpdrServerContext* context);
|
||||
|
||||
typedef BOOL (*psRdpdrDriveCreateDirectory)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path);
|
||||
typedef BOOL (*psRdpdrDriveDeleteDirectory)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path);
|
||||
typedef BOOL (*psRdpdrDriveQueryDirectory)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path);
|
||||
typedef BOOL (*psRdpdrDriveOpenFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path, UINT32 desiredAccess, UINT32 createDisposition);
|
||||
typedef BOOL (*psRdpdrDriveReadFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId, UINT32 length, UINT32 offset);
|
||||
typedef BOOL (*psRdpdrDriveWriteFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId, const char* buffer, UINT32 length, UINT32 offset);
|
||||
typedef BOOL (*psRdpdrDriveCloseFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, UINT32 fileId);
|
||||
typedef BOOL (*psRdpdrDriveDeleteFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* path);
|
||||
typedef BOOL (*psRdpdrDriveRenameFile)(RdpdrServerContext* context, void* callbackData, UINT32 deviceId, const char* oldPath, const char* newPath);
|
||||
|
||||
typedef void (*psRdpdrOnDriveCreate)(RdpdrServerContext* context, UINT32 deviceId, const char* name);
|
||||
typedef void (*psRdpdrOnDriveDelete)(RdpdrServerContext* context, UINT32 deviceId);
|
||||
typedef void (*psRdpdrOnDriveCreateDirectoryComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus);
|
||||
typedef void (*psRdpdrOnDriveDeleteDirectoryComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus);
|
||||
typedef void (*psRdpdrOnDriveQueryDirectoryComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus, FILE_DIRECTORY_INFORMATION* fdi);
|
||||
typedef void (*psRdpdrOnDriveOpenFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus, UINT32 deviceId, UINT32 fileId);
|
||||
typedef void (*psRdpdrOnDriveReadFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus, const char* buffer, UINT32 length);
|
||||
typedef void (*psRdpdrOnDriveWriteFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus, UINT32 bytesWritten);
|
||||
typedef void (*psRdpdrOnDriveCloseFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus);
|
||||
typedef void (*psRdpdrOnDriveDeleteFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus);
|
||||
typedef void (*psRdpdrOnDriveRenameFileComplete)(RdpdrServerContext* context, void* callbackData, UINT32 ioStatus);
|
||||
|
||||
typedef void (*psRdpdrOnPortCreate)(RdpdrServerContext* context, UINT32 deviceId, const char* name);
|
||||
typedef void (*psRdpdrOnPortDelete)(RdpdrServerContext* context, UINT32 deviceId);
|
||||
|
||||
typedef void (*psRdpdrOnPrinterCreate)(RdpdrServerContext* context, UINT32 deviceId, const char* name);
|
||||
typedef void (*psRdpdrOnPrinterDelete)(RdpdrServerContext* context, UINT32 deviceId);
|
||||
|
||||
typedef void (*psRdpdrOnSmartcardCreate)(RdpdrServerContext* context, UINT32 deviceId, const char* name);
|
||||
typedef void (*psRdpdrOnSmartcardDelete)(RdpdrServerContext* context, UINT32 deviceId);
|
||||
|
||||
struct _rdpdr_server_context
|
||||
{
|
||||
HANDLE vcm;
|
||||
@ -43,6 +90,51 @@ struct _rdpdr_server_context
|
||||
psRdpdrStop Stop;
|
||||
|
||||
RdpdrServerPrivate* priv;
|
||||
|
||||
/* Server self-defined pointer. */
|
||||
void* data;
|
||||
|
||||
/* Server supported redirections. Set by server. */
|
||||
BOOL supportsDrives;
|
||||
BOOL supportsPorts;
|
||||
BOOL supportsPrinters;
|
||||
BOOL supportsSmartcards;
|
||||
|
||||
/*** Drive APIs called by the server. ***/
|
||||
psRdpdrDriveCreateDirectory DriveCreateDirectory;
|
||||
psRdpdrDriveDeleteDirectory DriveDeleteDirectory;
|
||||
psRdpdrDriveQueryDirectory DriveQueryDirectory;
|
||||
psRdpdrDriveOpenFile DriveOpenFile;
|
||||
psRdpdrDriveReadFile DriveReadFile;
|
||||
psRdpdrDriveWriteFile DriveWriteFile;
|
||||
psRdpdrDriveCloseFile DriveCloseFile;
|
||||
psRdpdrDriveDeleteFile DriveDeleteFile;
|
||||
psRdpdrDriveRenameFile DriveRenameFile;
|
||||
|
||||
/*** Drive callbacks registered by the server. ***/
|
||||
psRdpdrOnDriveCreate OnDriveCreate;
|
||||
psRdpdrOnDriveDelete OnDriveDelete;
|
||||
psRdpdrOnDriveCreateDirectoryComplete OnDriveCreateDirectoryComplete;
|
||||
psRdpdrOnDriveDeleteDirectoryComplete OnDriveDeleteDirectoryComplete;
|
||||
psRdpdrOnDriveQueryDirectoryComplete OnDriveQueryDirectoryComplete;
|
||||
psRdpdrOnDriveOpenFileComplete OnDriveOpenFileComplete;
|
||||
psRdpdrOnDriveReadFileComplete OnDriveReadFileComplete;
|
||||
psRdpdrOnDriveWriteFileComplete OnDriveWriteFileComplete;
|
||||
psRdpdrOnDriveCloseFileComplete OnDriveCloseFileComplete;
|
||||
psRdpdrOnDriveDeleteFileComplete OnDriveDeleteFileComplete;
|
||||
psRdpdrOnDriveRenameFileComplete OnDriveRenameFileComplete;
|
||||
|
||||
/*** Port callbacks registered by the server. ***/
|
||||
psRdpdrOnPortCreate OnPortCreate;
|
||||
psRdpdrOnPortDelete OnPortDelete;
|
||||
|
||||
/*** Printer callbacks registered by the server. ***/
|
||||
psRdpdrOnPrinterCreate OnPrinterCreate;
|
||||
psRdpdrOnPrinterDelete OnPrinterDelete;
|
||||
|
||||
/*** Smartcard callbacks registered by the server. ***/
|
||||
psRdpdrOnSmartcardCreate OnSmartcardCreate;
|
||||
psRdpdrOnSmartcardDelete OnSmartcardDelete;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -1032,7 +1032,8 @@ struct rdp_settings
|
||||
ALIGN64 UINT32 RedirectionTsvUrlLength; /* 1227 */
|
||||
ALIGN64 UINT32 TargetNetAddressCount; /* 1228 */
|
||||
ALIGN64 char** TargetNetAddresses; /* 1229 */
|
||||
UINT64 padding1280[1280 - 1230]; /* 1230 */
|
||||
ALIGN64 UINT32* TargetNetPorts; /* 1230 */
|
||||
UINT64 padding1280[1280 - 1231]; /* 1231 */
|
||||
|
||||
/**
|
||||
* Security
|
||||
|
@ -141,6 +141,9 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
|
||||
|
||||
tokens = (char**) malloc(sizeof(char*) * count);
|
||||
|
||||
if (!tokens)
|
||||
return -1;
|
||||
|
||||
count = 0;
|
||||
tokens[count++] = str;
|
||||
|
||||
@ -153,6 +156,39 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
|
||||
}
|
||||
}
|
||||
|
||||
file->MachineCount = count;
|
||||
file->MachineAddresses = (char**) calloc(count, sizeof(char*));
|
||||
file->MachinePorts = (UINT32*) calloc(count, sizeof(UINT32));
|
||||
|
||||
if (!file->MachineAddresses || !file->MachinePorts)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
length = strlen(tokens[i]);
|
||||
|
||||
p = tokens[i];
|
||||
|
||||
q = strchr(p, ':');
|
||||
|
||||
if (!q)
|
||||
{
|
||||
free(tokens);
|
||||
return -1;
|
||||
}
|
||||
|
||||
q[0] = '\0';
|
||||
q++;
|
||||
|
||||
file->MachineAddresses[i] = _strdup(p);
|
||||
file->MachinePorts[i] = (UINT32) atoi(q);
|
||||
|
||||
if (!file->MachineAddresses[i])
|
||||
return -1;
|
||||
|
||||
q[-1] = ':';
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
length = strlen(tokens[i]);
|
||||
@ -179,6 +215,9 @@ int freerdp_assistance_parse_address_list(rdpAssistanceFile* file, char* list)
|
||||
file->MachineAddress = _strdup(p);
|
||||
file->MachinePort = (UINT32) atoi(q);
|
||||
|
||||
if (!file->MachineAddress)
|
||||
return -1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1049,6 +1088,10 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name)
|
||||
}
|
||||
|
||||
buffer = (BYTE*) malloc(fileSize + 2);
|
||||
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
readSize = fread(buffer, fileSize, 1, fp);
|
||||
|
||||
if (!readSize)
|
||||
@ -1077,6 +1120,8 @@ int freerdp_assistance_parse_file(rdpAssistanceFile* file, const char* name)
|
||||
|
||||
int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE);
|
||||
|
||||
if (!file->RASessionId)
|
||||
@ -1096,6 +1141,28 @@ int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* fil
|
||||
freerdp_set_param_string(settings, FreeRDP_ServerHostname, file->MachineAddress);
|
||||
freerdp_set_param_uint32(settings, FreeRDP_ServerPort, file->MachinePort);
|
||||
|
||||
freerdp_target_net_addresses_free(settings);
|
||||
|
||||
settings->TargetNetAddressCount = file->MachineCount;
|
||||
|
||||
if (settings->TargetNetAddressCount)
|
||||
{
|
||||
settings->TargetNetAddresses = (char**) calloc(file->MachineCount, sizeof(char*));
|
||||
settings->TargetNetPorts = (UINT32*) calloc(file->MachineCount, sizeof(UINT32));
|
||||
|
||||
if (!settings->TargetNetAddresses || !settings->TargetNetPorts)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < settings->TargetNetAddressCount; i++)
|
||||
{
|
||||
settings->TargetNetAddresses[i] = _strdup(file->MachineAddresses[i]);
|
||||
settings->TargetNetPorts[i] = file->MachinePorts[i];
|
||||
|
||||
if (!settings->TargetNetAddresses[i])
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1115,6 +1182,8 @@ rdpAssistanceFile* freerdp_assistance_file_new()
|
||||
|
||||
void freerdp_assistance_file_free(rdpAssistanceFile* file)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
@ -1130,5 +1199,13 @@ void freerdp_assistance_file_free(rdpAssistanceFile* file)
|
||||
free(file->MachineAddress);
|
||||
free(file->EncryptedPassStub);
|
||||
|
||||
for (i = 0; i < file->MachineCount; i++)
|
||||
{
|
||||
free(file->MachineAddresses[i]);
|
||||
}
|
||||
|
||||
free(file->MachineAddresses);
|
||||
free(file->MachinePorts);
|
||||
|
||||
free(file);
|
||||
}
|
||||
|
@ -610,9 +610,11 @@ void freerdp_target_net_addresses_free(rdpSettings* settings)
|
||||
free(settings->TargetNetAddresses[index]);
|
||||
|
||||
free(settings->TargetNetAddresses);
|
||||
free(settings->TargetNetPorts);
|
||||
|
||||
settings->TargetNetAddressCount = 0;
|
||||
settings->TargetNetAddresses = NULL;
|
||||
settings->TargetNetPorts = NULL;
|
||||
}
|
||||
|
||||
void freerdp_performance_flags_make(rdpSettings* settings)
|
||||
|
@ -2685,10 +2685,21 @@ BOOL rdp_read_bitmap_codecs_capability_set(wStream* s, UINT16 length, rdpSetting
|
||||
Stream_Read_UINT8(s, transformBits); /* transformBits (1 byte) */
|
||||
Stream_Read_UINT8(s, entropyBits); /* entropyBits (1 byte) */
|
||||
|
||||
if (version != 0x0100)
|
||||
return FALSE;
|
||||
if (version == 0x0009)
|
||||
{
|
||||
/* Version 0.9 */
|
||||
|
||||
if (tileSize != 0x0040)
|
||||
if (tileSize != 0x0080)
|
||||
return FALSE;
|
||||
}
|
||||
else if (version == 0x0100)
|
||||
{
|
||||
/* Version 1.0 */
|
||||
|
||||
if (tileSize != 0x0040)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
if (colConvBits != 1)
|
||||
|
@ -62,7 +62,7 @@ static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client, const char
|
||||
if (!mcsChannel->joined)
|
||||
continue;
|
||||
|
||||
if (strncmp(name, mcsChannel->Name, length) == 0)
|
||||
if (_strnicmp(name, mcsChannel->Name, length) == 0)
|
||||
{
|
||||
joined = TRUE;
|
||||
break;
|
||||
|
@ -590,10 +590,15 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->RedirectionTsvUrlLength = 0;
|
||||
_settings->TargetNetAddressCount = 0;
|
||||
_settings->TargetNetAddresses = NULL;
|
||||
_settings->TargetNetPorts = NULL;
|
||||
|
||||
if (settings->LoadBalanceInfo && settings->LoadBalanceInfoLength)
|
||||
{
|
||||
_settings->LoadBalanceInfo = (BYTE*) calloc(1, settings->LoadBalanceInfoLength + 2);
|
||||
|
||||
if (!_settings->LoadBalanceInfo)
|
||||
goto out_fail;
|
||||
|
||||
CopyMemory(_settings->LoadBalanceInfo, settings->LoadBalanceInfo, settings->LoadBalanceInfoLength);
|
||||
_settings->LoadBalanceInfoLength = settings->LoadBalanceInfoLength;
|
||||
}
|
||||
@ -601,6 +606,10 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
if (_settings->ServerRandomLength)
|
||||
{
|
||||
_settings->ServerRandom = (BYTE*) malloc(_settings->ServerRandomLength);
|
||||
|
||||
if (!_settings->ServerRandom)
|
||||
goto out_fail;
|
||||
|
||||
CopyMemory(_settings->ServerRandom, settings->ServerRandom, _settings->ServerRandomLength);
|
||||
_settings->ServerRandomLength = settings->ServerRandomLength;
|
||||
}
|
||||
@ -608,6 +617,10 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
if (_settings->ClientRandomLength)
|
||||
{
|
||||
_settings->ClientRandom = (BYTE*) malloc(_settings->ClientRandomLength);
|
||||
|
||||
if (!_settings->ClientRandom)
|
||||
goto out_fail;
|
||||
|
||||
CopyMemory(_settings->ClientRandom, settings->ClientRandom, _settings->ClientRandomLength);
|
||||
_settings->ClientRandomLength = settings->ClientRandomLength;
|
||||
}
|
||||
@ -615,61 +628,111 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
if (settings->RdpServerCertificate)
|
||||
{
|
||||
_settings->RdpServerCertificate = certificate_clone(settings->RdpServerCertificate);
|
||||
|
||||
if (!_settings->RdpServerCertificate)
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
_settings->ChannelCount = settings->ChannelCount;
|
||||
_settings->ChannelDefArraySize = settings->ChannelDefArraySize;
|
||||
_settings->ChannelDefArray = (CHANNEL_DEF*) malloc(sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
|
||||
if (!_settings->ChannelDefArray && _settings->ChannelDefArraySize)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->ChannelDefArray, settings->ChannelDefArray, sizeof(CHANNEL_DEF) * settings->ChannelDefArraySize);
|
||||
|
||||
_settings->MonitorCount = settings->MonitorCount;
|
||||
_settings->MonitorDefArraySize = settings->MonitorDefArraySize;
|
||||
_settings->MonitorDefArray = (rdpMonitor*) malloc(sizeof(rdpMonitor) * settings->MonitorDefArraySize);
|
||||
if (!_settings->MonitorDefArray && _settings->MonitorDefArraySize)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->MonitorDefArray, settings->MonitorDefArray, sizeof(rdpMonitor) * settings->MonitorDefArraySize);
|
||||
|
||||
_settings->MonitorIds = (UINT32*) calloc(16, sizeof(UINT32));
|
||||
if (!_settings->MonitorIds)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->MonitorIds, settings->MonitorIds, 16 * sizeof(UINT32));
|
||||
|
||||
_settings->ReceivedCapabilities = malloc(32);
|
||||
if (!_settings->ReceivedCapabilities)
|
||||
goto out_fail;
|
||||
_settings->OrderSupport = malloc(32);
|
||||
if (!_settings->OrderSupport)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->ReceivedCapabilities, settings->ReceivedCapabilities, 32);
|
||||
CopyMemory(_settings->OrderSupport, settings->OrderSupport, 32);
|
||||
|
||||
_settings->ClientHostname = malloc(32);
|
||||
if (!_settings->ClientHostname)
|
||||
goto out_fail;
|
||||
_settings->ClientProductId = malloc(32);
|
||||
if (!_settings->ClientProductId)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->ClientHostname, settings->ClientHostname, 32);
|
||||
CopyMemory(_settings->ClientProductId, settings->ClientProductId, 32);
|
||||
|
||||
_settings->BitmapCacheV2CellInfo = (BITMAP_CACHE_V2_CELL_INFO*) malloc(sizeof(BITMAP_CACHE_V2_CELL_INFO) * 6);
|
||||
if (!_settings->BitmapCacheV2CellInfo)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->BitmapCacheV2CellInfo, settings->BitmapCacheV2CellInfo, sizeof(BITMAP_CACHE_V2_CELL_INFO) * 6);
|
||||
|
||||
_settings->GlyphCache = malloc(sizeof(GLYPH_CACHE_DEFINITION) * 10);
|
||||
if (!_settings->GlyphCache)
|
||||
goto out_fail;
|
||||
_settings->FragCache = malloc(sizeof(GLYPH_CACHE_DEFINITION));
|
||||
if (!_settings->FragCache)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->GlyphCache, settings->GlyphCache, sizeof(GLYPH_CACHE_DEFINITION) * 10);
|
||||
CopyMemory(_settings->FragCache, settings->FragCache, sizeof(GLYPH_CACHE_DEFINITION));
|
||||
|
||||
_settings->ClientAutoReconnectCookie = (ARC_CS_PRIVATE_PACKET*) malloc(sizeof(ARC_CS_PRIVATE_PACKET));
|
||||
if (!_settings->ClientAutoReconnectCookie)
|
||||
goto out_fail;
|
||||
_settings->ServerAutoReconnectCookie = (ARC_SC_PRIVATE_PACKET*) malloc(sizeof(ARC_SC_PRIVATE_PACKET));
|
||||
if (!_settings->ServerAutoReconnectCookie)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->ClientAutoReconnectCookie, settings->ClientAutoReconnectCookie, sizeof(ARC_CS_PRIVATE_PACKET));
|
||||
CopyMemory(_settings->ServerAutoReconnectCookie, settings->ServerAutoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET));
|
||||
|
||||
_settings->ClientTimeZone = (TIME_ZONE_INFO*) malloc(sizeof(TIME_ZONE_INFO));
|
||||
if (!_settings->ClientTimeZone)
|
||||
goto out_fail;
|
||||
CopyMemory(_settings->ClientTimeZone, settings->ClientTimeZone, sizeof(TIME_ZONE_INFO));
|
||||
|
||||
_settings->TargetNetAddressCount = settings->TargetNetAddressCount;
|
||||
|
||||
if (settings->TargetNetAddressCount > 0)
|
||||
{
|
||||
_settings->TargetNetAddresses = (char**) malloc(sizeof(char*) * settings->TargetNetAddressCount);
|
||||
_settings->TargetNetAddresses = (char**) calloc(settings->TargetNetAddressCount, sizeof(char*));
|
||||
|
||||
if (!_settings->TargetNetAddresses)
|
||||
goto out_fail;
|
||||
|
||||
for (index = 0; index < settings->TargetNetAddressCount; index++)
|
||||
{
|
||||
_settings->TargetNetAddresses[index] = _strdup(settings->TargetNetAddresses[index]);
|
||||
|
||||
if (!_settings->TargetNetAddresses[index])
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
if (settings->TargetNetPorts)
|
||||
{
|
||||
_settings->TargetNetPorts = (UINT32*) calloc(settings->TargetNetAddressCount, sizeof(UINT32));
|
||||
|
||||
if (!_settings->TargetNetPorts)
|
||||
goto out_fail;
|
||||
|
||||
for (index = 0; index < settings->TargetNetAddressCount; index++)
|
||||
_settings->TargetNetPorts[index] = settings->TargetNetPorts[index];
|
||||
}
|
||||
}
|
||||
|
||||
_settings->DeviceCount = settings->DeviceCount;
|
||||
_settings->DeviceArraySize = settings->DeviceArraySize;
|
||||
_settings->DeviceArray = (RDPDR_DEVICE**) malloc(sizeof(RDPDR_DEVICE*) * _settings->DeviceArraySize);
|
||||
ZeroMemory(_settings->DeviceArray, sizeof(RDPDR_DEVICE*) * _settings->DeviceArraySize);
|
||||
_settings->DeviceArray = (RDPDR_DEVICE**) calloc(_settings->DeviceArraySize, sizeof(RDPDR_DEVICE*));
|
||||
|
||||
if (!_settings->DeviceArray && _settings->DeviceArraySize)
|
||||
goto out_fail;
|
||||
|
||||
for (index = 0; index < _settings->DeviceCount; index++)
|
||||
{
|
||||
@ -680,6 +743,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->StaticChannelArraySize = settings->StaticChannelArraySize;
|
||||
_settings->StaticChannelArray = (ADDIN_ARGV**) calloc(_settings->StaticChannelArraySize, sizeof(ADDIN_ARGV*));
|
||||
|
||||
if (!_settings->StaticChannelArray && _settings->StaticChannelArraySize)
|
||||
goto out_fail;
|
||||
|
||||
for (index = 0; index < _settings->StaticChannelCount; index++)
|
||||
{
|
||||
_settings->StaticChannelArray[index] = freerdp_static_channel_clone(settings->StaticChannelArray[index]);
|
||||
@ -689,16 +755,24 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->DynamicChannelArraySize = settings->DynamicChannelArraySize;
|
||||
_settings->DynamicChannelArray = (ADDIN_ARGV**) calloc(_settings->DynamicChannelArraySize, sizeof(ADDIN_ARGV*));
|
||||
|
||||
if (!_settings->DynamicChannelArray && _settings->DynamicChannelArraySize)
|
||||
goto out_fail;
|
||||
|
||||
for (index = 0; index < _settings->DynamicChannelCount; index++)
|
||||
{
|
||||
_settings->DynamicChannelArray[index] = freerdp_dynamic_channel_clone(settings->DynamicChannelArray[index]);
|
||||
}
|
||||
|
||||
_settings->SettingsModified = (BYTE*) malloc(sizeof(rdpSettings) / 8);
|
||||
ZeroMemory(_settings->SettingsModified, sizeof(rdpSettings) / 8);
|
||||
_settings->SettingsModified = (BYTE*) calloc(1, sizeof(rdpSettings) / 8);
|
||||
|
||||
if (!_settings->SettingsModified)
|
||||
goto out_fail;
|
||||
}
|
||||
|
||||
return _settings;
|
||||
out_fail:
|
||||
freerdp_settings_free(_settings);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void freerdp_settings_free(rdpSettings* settings)
|
||||
|
@ -816,7 +816,7 @@ BOOL freerdp_tcp_connect_timeout(int sockfd, struct sockaddr* addr, socklen_t ad
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
int freerdp_tcp_connect_multi(char** hostnames, int count, int port, int timeout)
|
||||
int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int port, int timeout)
|
||||
{
|
||||
int index;
|
||||
int sindex;
|
||||
@ -849,6 +849,9 @@ int freerdp_tcp_connect_multi(char** hostnames, int count, int port, int timeout
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (ports)
|
||||
sprintf_s(port_str, sizeof(port_str) - 1, "%u", ports[index]);
|
||||
|
||||
status = getaddrinfo(hostnames[index], port_str, &hints, &result);
|
||||
|
||||
if (status)
|
||||
@ -992,6 +995,143 @@ int freerdp_tcp_connect_multi(char** hostnames, int count, int port, int timeout
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int freerdp_tcp_connect_multi(char** hostnames, UINT32* ports, int count, int port, int timeout)
|
||||
{
|
||||
int index;
|
||||
int sindex;
|
||||
int status;
|
||||
SOCKET sockfd;
|
||||
SOCKET* sockfds;
|
||||
HANDLE* events;
|
||||
DWORD waitStatus;
|
||||
char port_str[16];
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* addr;
|
||||
struct addrinfo* result;
|
||||
struct addrinfo** addrs;
|
||||
struct addrinfo** results;
|
||||
|
||||
sindex = -1;
|
||||
|
||||
sprintf_s(port_str, sizeof(port_str) - 1, "%u", port);
|
||||
|
||||
sockfds = (SOCKET*) calloc(count, sizeof(SOCKET));
|
||||
events = (HANDLE*) calloc(count, sizeof(HANDLE));
|
||||
addrs = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
|
||||
results = (struct addrinfo**) calloc(count, sizeof(struct addrinfo*));
|
||||
|
||||
if (!sockfds || !events || !addrs || !results)
|
||||
{
|
||||
free(sockfds);
|
||||
free(events);
|
||||
free(addrs);
|
||||
free(results);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
ZeroMemory(&hints, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (ports)
|
||||
sprintf_s(port_str, sizeof(port_str) - 1, "%u", ports[index]);
|
||||
|
||||
status = getaddrinfo(hostnames[index], port_str, &hints, &result);
|
||||
|
||||
if (status)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
addr = result;
|
||||
|
||||
if ((addr->ai_family == AF_INET6) && (addr->ai_next != 0))
|
||||
{
|
||||
while ((addr = addr->ai_next))
|
||||
{
|
||||
if (addr->ai_family == AF_INET)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!addr)
|
||||
addr = result;
|
||||
}
|
||||
|
||||
sockfds[index] = _socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
|
||||
if (sockfds[index] < 0)
|
||||
{
|
||||
freeaddrinfo(result);
|
||||
sockfds[index] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
addrs[index] = addr;
|
||||
results[index] = result;
|
||||
}
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
if (!sockfds[index])
|
||||
continue;
|
||||
|
||||
sockfd = sockfds[index];
|
||||
addr = addrs[index];
|
||||
|
||||
/* set socket in non-blocking mode */
|
||||
|
||||
WSAEventSelect(sockfd, events[index], FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE);
|
||||
|
||||
/* non-blocking tcp connect */
|
||||
|
||||
status = _connect(sockfd, addr->ai_addr, addr->ai_addrlen);
|
||||
|
||||
if (status >= 0)
|
||||
{
|
||||
/* connection success */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
waitStatus = WaitForMultipleObjects(count, events, FALSE, timeout * 1000);
|
||||
|
||||
sindex = waitStatus - WAIT_OBJECT_0;
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
if (!sockfds[index])
|
||||
continue;
|
||||
|
||||
sockfd = sockfds[index];
|
||||
|
||||
/* set socket in blocking mode */
|
||||
|
||||
WSAEventSelect(sockfd, NULL, 0);
|
||||
}
|
||||
|
||||
if (sindex >= 0)
|
||||
{
|
||||
sockfd = sockfds[sindex];
|
||||
}
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
if (results[index])
|
||||
freeaddrinfo(results[index]);
|
||||
}
|
||||
|
||||
free(addrs);
|
||||
free(results);
|
||||
free(sockfds);
|
||||
free(events);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BOOL freerdp_tcp_set_keep_alive_mode(int sockfd)
|
||||
@ -1088,16 +1228,12 @@ int freerdp_tcp_connect(rdpSettings* settings, const char* hostname, int port, i
|
||||
|
||||
if (!settings->GatewayEnabled)
|
||||
{
|
||||
if (!freerdp_tcp_resolve_hostname(hostname))
|
||||
if (!freerdp_tcp_resolve_hostname(hostname) || settings->RemoteAssistanceMode)
|
||||
{
|
||||
if (settings->TargetNetAddressCount > 0)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
sockfd = freerdp_tcp_connect_multi(settings->TargetNetAddresses,
|
||||
settings->TargetNetAddressCount, port, timeout);
|
||||
#else
|
||||
hostname = settings->TargetNetAddresses[0];
|
||||
#endif
|
||||
settings->TargetNetPorts, settings->TargetNetAddressCount, port, timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,7 +482,7 @@ static BOOL gdi_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
|
||||
compressed = bitmap->compressed;
|
||||
bitsPerPixel = bitmap->bitsPerPixel;
|
||||
|
||||
if (gdi->bitmap_size < (nWidth * nHeight * 4))
|
||||
if (gdi->bitmap_size < (UINT32) (nWidth * nHeight * 4))
|
||||
{
|
||||
gdi->bitmap_size = nWidth * nHeight * 4;
|
||||
gdi->bitmap_buffer = (BYTE*) _aligned_realloc(gdi->bitmap_buffer, gdi->bitmap_size, 16);
|
||||
@ -557,7 +557,7 @@ static BOOL gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette)
|
||||
|
||||
palette32 = (UINT32*) gdi->palette;
|
||||
|
||||
for (index = 0; index < palette->number; index++)
|
||||
for (index = 0; index < (int) palette->number; index++)
|
||||
{
|
||||
pe = &(palette->entries[index]);
|
||||
palette32[index] = RGB32(pe->red, pe->green, pe->blue);
|
||||
|
@ -402,7 +402,6 @@ int win_shadow_enum_monitors(MONITOR_DEF* monitors, int maxMonitors)
|
||||
DWORD iDevNum = 0;
|
||||
int numMonitors = 0;
|
||||
MONITOR_DEF* monitor;
|
||||
MONITOR_DEF* virtualScreen;
|
||||
DISPLAY_DEVICE displayDevice;
|
||||
|
||||
ZeroMemory(&displayDevice, sizeof(DISPLAY_DEVICE));
|
||||
|
@ -63,19 +63,23 @@ static INLINE UINT64 _rotr64(UINT64 value, int shift) {
|
||||
|
||||
#else
|
||||
|
||||
#define _byteswap_ulong(_val) (((_val) >> 24) | \
|
||||
(((_val) & 0x00FF0000) >> 8) | \
|
||||
(((_val) & 0x0000FF00) << 8) | \
|
||||
((_val) << 24))
|
||||
static INLINE UINT32 _byteswap_ulong(UINT32 _val) {
|
||||
return (((_val) >> 24) | \
|
||||
(((_val) & 0x00FF0000) >> 8) | \
|
||||
(((_val) & 0x0000FF00) << 8) | \
|
||||
((_val) << 24));
|
||||
}
|
||||
|
||||
#define _byteswap_uint64(_val) (((_val) << 56) | \
|
||||
(((_val) << 40) & 0xFF000000000000) | \
|
||||
(((_val) << 24) & 0xFF0000000000) | \
|
||||
(((_val) << 8) & 0xFF00000000) | \
|
||||
(((_val) >> 8) & 0xFF000000) | \
|
||||
(((_val) >> 24) & 0xFF0000) | \
|
||||
(((_val) >> 40) & 0xFF00) | \
|
||||
((_val) >> 56))
|
||||
static INLINE UINT64 _byteswap_uint64(UINT64 _val) {
|
||||
return (((_val) << 56) | \
|
||||
(((_val) << 40) & 0xFF000000000000) | \
|
||||
(((_val) << 24) & 0xFF0000000000) | \
|
||||
(((_val) << 8) & 0xFF00000000) | \
|
||||
(((_val) >> 8) & 0xFF000000) | \
|
||||
(((_val) >> 24) & 0xFF0000) | \
|
||||
(((_val) >> 40) & 0xFF00) | \
|
||||
((_val) >> 56));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -85,7 +89,9 @@ static INLINE UINT64 _rotr64(UINT64 value, int shift) {
|
||||
|
||||
#else
|
||||
|
||||
#define _byteswap_ushort(_val) (((_val) >> 8) | ((_val) << 8))
|
||||
static INLINE UINT16 _byteswap_ushort(UINT16 _val) {
|
||||
return (((_val) >> 8) | ((_val) << 8));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -27,10 +27,10 @@ extern "C" {
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
WINPR_API void *winpr_backtrace(DWORD size);
|
||||
WINPR_API void winpr_backtrace_free(void *buffer);
|
||||
WINPR_API char **winpr_backtrace_symbols(void *buffer, size_t *used);
|
||||
WINPR_API void winpr_backtrace_symbols_fd(void *buffer, int fd);
|
||||
WINPR_API void* winpr_backtrace(DWORD size);
|
||||
WINPR_API void winpr_backtrace_free(void* buffer);
|
||||
WINPR_API char** winpr_backtrace_symbols(void* buffer, size_t* used);
|
||||
WINPR_API void winpr_backtrace_symbols_fd(void* buffer, int fd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
52
winpr/include/winpr/shell.h
Normal file
52
winpr/include/winpr/shell.h
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Shell Functions
|
||||
*
|
||||
* Copyright 2015 Dell Software <Mike.McDonald@software.dell.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_SHELL_H
|
||||
#define WINPR_SHELL_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <winpr/winpr.h>
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WINPR_API BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize);
|
||||
|
||||
WINPR_API BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNICODE
|
||||
#define GetUserProfileDirectory GetUserProfileDirectoryW
|
||||
#else
|
||||
#define GetUserProfileDirectory GetUserProfileDirectoryA
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_SHELL_H */
|
||||
|
@ -146,7 +146,7 @@ struct _wLogAppender
|
||||
WLOG_APPENDER_COMMON();
|
||||
};
|
||||
|
||||
#define WLOG_CONSOLE_DEFAULT 0
|
||||
#define WLOG_CONSOLE_DEFAULT 0
|
||||
#define WLOG_CONSOLE_STDOUT 1
|
||||
#define WLOG_CONSOLE_STDERR 2
|
||||
#define WLOG_CONSOLE_DEBUG 4
|
||||
|
@ -75,7 +75,7 @@ endmacro()
|
||||
|
||||
# Level "1" API as defined for MinCore.lib
|
||||
set(WINPR_CORE synch locale library file comm pipe interlocked security
|
||||
environment crypto registry credentials path io memory input
|
||||
environment crypto registry credentials path io memory input shell
|
||||
heap utils error com timezone sysinfo pool handle thread)
|
||||
|
||||
foreach(DIR ${WINPR_CORE})
|
||||
|
18
winpr/libwinpr/shell/CMakeLists.txt
Normal file
18
winpr/libwinpr/shell/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# WinPR: Windows Portable Runtime
|
||||
# libwinpr-shell cmake build script
|
||||
#
|
||||
# Copyright 2015 Dell Software <Mike.McDonald@software.dell.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
winpr_module_add(shell.c)
|
9
winpr/libwinpr/shell/ModuleOptions.cmake
Normal file
9
winpr/libwinpr/shell/ModuleOptions.cmake
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
set(MINWIN_LAYER "0")
|
||||
set(MINWIN_GROUP "none")
|
||||
set(MINWIN_MAJOR_VERSION "0")
|
||||
set(MINWIN_MINOR_VERSION "0")
|
||||
set(MINWIN_SHORT_NAME "shell")
|
||||
set(MINWIN_LONG_NAME "Shell Functions")
|
||||
set(MODULE_LIBRARY_NAME "${MINWIN_SHORT_NAME}")
|
||||
|
146
winpr/libwinpr/shell/shell.c
Normal file
146
winpr/libwinpr/shell/shell.c
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* Shell Functions
|
||||
*
|
||||
* Copyright 2015 Dell Software <Mike.McDonald@software.dell.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/shell.h>
|
||||
|
||||
/**
|
||||
* shell32.dll:
|
||||
*
|
||||
* GetUserProfileDirectoryA
|
||||
* GetUserProfileDirectoryW
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "../handle/handle.h"
|
||||
|
||||
#include "../security/security.h"
|
||||
|
||||
BOOL GetUserProfileDirectoryA(HANDLE hToken, LPSTR lpProfileDir, LPDWORD lpcchSize)
|
||||
{
|
||||
char* buf;
|
||||
int buflen;
|
||||
int status;
|
||||
DWORD cchDirSize;
|
||||
struct passwd pwd;
|
||||
struct passwd* pw = NULL;
|
||||
WINPR_ACCESS_TOKEN* token;
|
||||
|
||||
token = (WINPR_ACCESS_TOKEN*) hToken;
|
||||
|
||||
if (!token || (token->Type != HANDLE_TYPE_ACCESS_TOKEN) || !lpcchSize)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
|
||||
if (buflen == -1)
|
||||
buflen = 8196;
|
||||
|
||||
buf = (char*) malloc(buflen);
|
||||
|
||||
if (!buf)
|
||||
return FALSE;
|
||||
|
||||
status = getpwnam_r(token->Username, &pwd, buf, buflen, &pw);
|
||||
|
||||
if ((status != 0) || !pw)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cchDirSize = strlen(pw->pw_dir) + 1;
|
||||
|
||||
if (!lpProfileDir || (*lpcchSize < cchDirSize))
|
||||
{
|
||||
*lpcchSize = cchDirSize;
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ZeroMemory(lpProfileDir, *lpcchSize);
|
||||
strcpy(lpProfileDir, pw->pw_dir);
|
||||
*lpcchSize = cchDirSize;
|
||||
free(buf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL GetUserProfileDirectoryW(HANDLE hToken, LPWSTR lpProfileDir, LPDWORD lpcchSize)
|
||||
{
|
||||
BOOL bStatus;
|
||||
DWORD cchSizeA;
|
||||
LPSTR lpProfileDirA;
|
||||
|
||||
if (!lpcchSize)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cchSizeA = *lpcchSize;
|
||||
lpProfileDirA = NULL;
|
||||
|
||||
if (lpProfileDir)
|
||||
{
|
||||
lpProfileDirA = (LPSTR) malloc(cchSizeA);
|
||||
|
||||
if (lpProfileDirA == NULL)
|
||||
{
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bStatus = GetUserProfileDirectoryA(hToken, lpProfileDirA, &cchSizeA);
|
||||
|
||||
if (bStatus)
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0, lpProfileDirA, cchSizeA, lpProfileDir, *lpcchSize);
|
||||
}
|
||||
|
||||
if (lpProfileDirA)
|
||||
{
|
||||
free(lpProfileDirA);
|
||||
}
|
||||
|
||||
*lpcchSize = cchSizeA;
|
||||
|
||||
return bStatus;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
@ -188,7 +186,7 @@ fail:
|
||||
}
|
||||
#endif
|
||||
|
||||
void winpr_backtrace_free(void *buffer)
|
||||
void winpr_backtrace_free(void* buffer)
|
||||
{
|
||||
if (!buffer)
|
||||
{
|
||||
@ -197,7 +195,7 @@ void winpr_backtrace_free(void *buffer)
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXECINFO_H)
|
||||
t_execinfo *data = (t_execinfo *)buffer;
|
||||
t_execinfo* data = (t_execinfo*) buffer;
|
||||
|
||||
free(data->buffer);
|
||||
|
||||
@ -219,15 +217,15 @@ void winpr_backtrace_free(void *buffer)
|
||||
#endif
|
||||
}
|
||||
|
||||
void *winpr_backtrace(DWORD size)
|
||||
void* winpr_backtrace(DWORD size)
|
||||
{
|
||||
#if defined(HAVE_EXECINFO_H)
|
||||
t_execinfo *data = calloc(1, sizeof(t_execinfo));
|
||||
t_execinfo* data = calloc(1, sizeof(t_execinfo));
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
data->buffer = calloc(size, sizeof(void *));
|
||||
data->buffer = calloc(size, sizeof(void*));
|
||||
|
||||
if (!data->buffer)
|
||||
{
|
||||
@ -239,7 +237,7 @@ void *winpr_backtrace(DWORD size)
|
||||
data->used = backtrace(data->buffer, size);
|
||||
return data;
|
||||
#elif defined(ANDROID)
|
||||
t_corkscrew_data *data = calloc(1, sizeof(t_corkscrew_data));
|
||||
t_corkscrew_data* data = calloc(1, sizeof(t_corkscrew_data));
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
@ -258,20 +256,21 @@ void *winpr_backtrace(DWORD size)
|
||||
return data;
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
HANDLE process = GetCurrentProcess();
|
||||
t_win_stack *data = calloc(1, sizeof(t_win_stack));
|
||||
t_win_stack* data = calloc(1, sizeof(t_win_stack));
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
data->max = size;
|
||||
data->stack = calloc(data->max, sizeof(PVOID));
|
||||
|
||||
if (!data->stack)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SymInitialize( process, NULL, TRUE );
|
||||
SymInitialize(process, NULL, TRUE);
|
||||
data->used = CaptureStackBackTrace(2, size, data->stack, NULL);
|
||||
|
||||
return data;
|
||||
@ -281,7 +280,7 @@ void *winpr_backtrace(DWORD size)
|
||||
#endif
|
||||
}
|
||||
|
||||
char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
char** winpr_backtrace_symbols(void* buffer, size_t* used)
|
||||
{
|
||||
if (used)
|
||||
*used = 0;
|
||||
@ -293,16 +292,21 @@ char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXECINFO_H)
|
||||
t_execinfo *data = (t_execinfo *)buffer;
|
||||
assert(data);
|
||||
t_execinfo* data = (t_execinfo*) buffer;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
if (used)
|
||||
*used = data->used;
|
||||
|
||||
return backtrace_symbols(data->buffer, data->used);
|
||||
#elif defined(ANDROID)
|
||||
t_corkscrew_data *data = (t_corkscrew_data *)buffer;
|
||||
assert(data);
|
||||
t_corkscrew_data* data = (t_corkscrew_data*) buffer;
|
||||
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
pthread_once(&initialized, load_library);
|
||||
|
||||
if (!fkt)
|
||||
@ -314,9 +318,9 @@ char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
{
|
||||
size_t line_len = (data->max > 1024) ? data->max : 1024;
|
||||
size_t i;
|
||||
char *lines = calloc(data->used + 1, sizeof(char *) * line_len);
|
||||
char **vlines = (char **)lines;
|
||||
backtrace_symbol_t *symbols = calloc(data->used, sizeof(backtrace_symbol_t));
|
||||
char* lines = calloc(data->used + 1, sizeof(char *) * line_len);
|
||||
char** vlines = (char**) lines;
|
||||
backtrace_symbol_t* symbols = calloc(data->used, sizeof(backtrace_symbol_t));
|
||||
|
||||
if (!lines || !symbols)
|
||||
{
|
||||
@ -331,12 +335,12 @@ char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
|
||||
/* To allow a char** malloced array to be returned, allocate n+1 lines
|
||||
* and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */
|
||||
for (i=0; i<data->used; i++)
|
||||
for (i = 0; i < data->used; i++)
|
||||
vlines[i] = &lines[(i + 1) * line_len];
|
||||
|
||||
fkt->get_backtrace_symbols(data->buffer, data->used, symbols);
|
||||
|
||||
for (i=0; i<data->used; i++)
|
||||
for (i = 0; i <data->used; i++)
|
||||
fkt->format_backtrace_line(i, &data->buffer[i], &symbols[i], vlines[i], line_len);
|
||||
|
||||
fkt->free_backtrace_symbols(symbols, data->used);
|
||||
@ -345,61 +349,64 @@ char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
if (used)
|
||||
*used = data->used;
|
||||
|
||||
return (char **)lines;
|
||||
return (char**) lines;
|
||||
}
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
{
|
||||
HANDLE process = GetCurrentProcess();
|
||||
t_win_stack *data = (t_win_stack *)buffer;
|
||||
size_t line_len = 1024;
|
||||
size_t i;
|
||||
char *lines = calloc(data->used + 1, sizeof(char *) * line_len);
|
||||
char **vlines = (char **)lines;
|
||||
size_t line_len = 1024;
|
||||
HANDLE process = GetCurrentProcess();
|
||||
t_win_stack* data = (t_win_stack*) buffer;
|
||||
char *lines = calloc(data->used + 1, sizeof(char*) * line_len);
|
||||
char **vlines = (char**) lines;
|
||||
SYMBOL_INFO* symbol = calloc(sizeof(SYMBOL_INFO) + line_len * sizeof(char), 1);
|
||||
IMAGEHLP_LINE64 *line = (IMAGEHLP_LINE64 *)calloc(1, sizeof(IMAGEHLP_LINE64));
|
||||
IMAGEHLP_LINE64* line = (IMAGEHLP_LINE64*) calloc(1, sizeof(IMAGEHLP_LINE64));
|
||||
|
||||
if (!lines || !symbol || !line)
|
||||
{
|
||||
if (lines)
|
||||
free(lines);
|
||||
free(lines);
|
||||
|
||||
if (symbol)
|
||||
free(symbol);
|
||||
free(symbol);
|
||||
|
||||
if (line)
|
||||
free(line);
|
||||
|
||||
if (line)
|
||||
free(line);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
line->SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
symbol->MaxNameLen = line_len;
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
|
||||
/* To allow a char** malloced array to be returned, allocate n+1 lines
|
||||
* and fill in the first lines[i] char with the address of lines[(i+1) * 1024] */
|
||||
for (i=0; i<data->used; i++)
|
||||
vlines[i] = &lines[(i + 1) * line_len];
|
||||
for (i = 0; i < data->used; i++)
|
||||
vlines[i] = &lines[(i + 1) * line_len];
|
||||
|
||||
for (i=0; i<data->used; i++)
|
||||
for (i = 0; i < data->used; i++)
|
||||
{
|
||||
DWORD64 address = (DWORD64)(data->stack[i]);
|
||||
DWORD displacement;
|
||||
DWORD64 address = (DWORD64)(data->stack[i]);
|
||||
DWORD displacement;
|
||||
|
||||
SymFromAddr(process, address, 0, symbol);
|
||||
if (SymGetLineFromAddr64(process, address, &displacement, line))
|
||||
{
|
||||
_snprintf(vlines[i], line_len, "%08lX: %s in %s:%lu", symbol->Address, symbol->Name, line->FileName, line->LineNumber);
|
||||
}
|
||||
else
|
||||
_snprintf(vlines[i], line_len, "%08lX: %s", symbol->Address, symbol->Name);
|
||||
}
|
||||
SymFromAddr(process, address, 0, symbol);
|
||||
|
||||
if (used)
|
||||
if (SymGetLineFromAddr64(process, address, &displacement, line))
|
||||
{
|
||||
_snprintf(vlines[i], line_len, "%08lX: %s in %s:%lu", symbol->Address, symbol->Name, line->FileName, line->LineNumber);
|
||||
}
|
||||
else
|
||||
_snprintf(vlines[i], line_len, "%08lX: %s", symbol->Address, symbol->Name);
|
||||
}
|
||||
|
||||
if (used)
|
||||
*used = data->used;
|
||||
|
||||
free(symbol);
|
||||
free(line);
|
||||
free(symbol);
|
||||
free(line);
|
||||
|
||||
return (char **)lines;
|
||||
return (char**) lines;
|
||||
}
|
||||
#else
|
||||
LOGF(support_msg);
|
||||
@ -407,7 +414,7 @@ char **winpr_backtrace_symbols(void *buffer, size_t *used)
|
||||
#endif
|
||||
}
|
||||
|
||||
void winpr_backtrace_symbols_fd(void *buffer, int fd)
|
||||
void winpr_backtrace_symbols_fd(void* buffer, int fd)
|
||||
{
|
||||
if (!buffer)
|
||||
{
|
||||
@ -416,8 +423,11 @@ void winpr_backtrace_symbols_fd(void *buffer, int fd)
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXECINFO_H)
|
||||
t_execinfo *data = (t_execinfo *)buffer;
|
||||
assert(data);
|
||||
t_execinfo* data = (t_execinfo*) buffer;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
backtrace_symbols_fd(data->buffer, data->used, fd);
|
||||
#elif defined(_WIN32) || defined(_WIN64) || defined(ANDROID)
|
||||
{
|
||||
@ -432,7 +442,7 @@ void winpr_backtrace_symbols_fd(void *buffer, int fd)
|
||||
for (i = 0; i < used; i++)
|
||||
write(fd, lines[i], strlen(lines[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
LOGF(support_msg);
|
||||
#endif
|
||||
|
@ -222,12 +222,12 @@ int test_image_png_to_bmp()
|
||||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
snprintf(src_png, sizeof(src_png), "%s/lodepng_32bit.png", buffer);
|
||||
snprintf(src_bmp, sizeof(src_bmp), "%s/lodepng_32bit.bmp", buffer);
|
||||
snprintf(dst_png, sizeof(dst_png), "%s/lodepng_32bit.png", tmp);
|
||||
snprintf(dst_bmp, sizeof(dst_bmp), "%s/lodepng_32bit.bmp", tmp);
|
||||
snprintf(dst_png2, sizeof(dst_png2), "%s/lodepng_32bit-2.png", tmp);
|
||||
snprintf(dst_bmp2, sizeof(dst_bmp2), "%s/lodepng_32bit-2.bmp", tmp);
|
||||
sprintf_s(src_png, sizeof(src_png), "%s/lodepng_32bit.png", buffer);
|
||||
sprintf_s(src_bmp, sizeof(src_bmp), "%s/lodepng_32bit.bmp", buffer);
|
||||
sprintf_s(dst_png, sizeof(dst_png), "%s/lodepng_32bit.png", tmp);
|
||||
sprintf_s(dst_bmp, sizeof(dst_bmp), "%s/lodepng_32bit.bmp", tmp);
|
||||
sprintf_s(dst_png2, sizeof(dst_png2), "%s/lodepng_32bit-2.png", tmp);
|
||||
sprintf_s(dst_bmp2, sizeof(dst_bmp2), "%s/lodepng_32bit-2.bmp", tmp);
|
||||
|
||||
if (create_test(src_png, dst_png, dst_bmp))
|
||||
return -1;
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/environment.h>
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/thread.h>
|
||||
@ -188,6 +189,9 @@ int WLog_FileAppender_WriteImageMessage(wLog* log, wLogFileAppender* appender, w
|
||||
|
||||
wLogFileAppender* WLog_FileAppender_New(wLog* log)
|
||||
{
|
||||
LPSTR env;
|
||||
LPCSTR name;
|
||||
DWORD nSize;
|
||||
wLogFileAppender* FileAppender;
|
||||
|
||||
FileAppender = (wLogFileAppender*) malloc(sizeof(wLogFileAppender));
|
||||
@ -211,7 +215,33 @@ wLogFileAppender* WLog_FileAppender_New(wLog* log)
|
||||
FileAppender->FileName = NULL;
|
||||
FileAppender->FilePath = NULL;
|
||||
FileAppender->FullFileName = NULL;
|
||||
}
|
||||
|
||||
name = "WLOG_FILEAPPENDER_OUTPUT_FILE_PATH";
|
||||
nSize = GetEnvironmentVariableA(name, NULL, 0);
|
||||
if (nSize)
|
||||
{
|
||||
env = (LPSTR) malloc(nSize);
|
||||
if (env)
|
||||
{
|
||||
nSize = GetEnvironmentVariableA(name, env, nSize);
|
||||
WLog_FileAppender_SetOutputFilePath(log, FileAppender, env);
|
||||
free(env);
|
||||
}
|
||||
}
|
||||
|
||||
name = "WLOG_FILEAPPENDER_OUTPUT_FILE_NAME";
|
||||
nSize = GetEnvironmentVariableA(name, NULL, 0);
|
||||
if (nSize)
|
||||
{
|
||||
env = (LPSTR) malloc(nSize);
|
||||
if (env)
|
||||
{
|
||||
nSize = GetEnvironmentVariableA(name, env, nSize);
|
||||
WLog_FileAppender_SetOutputFileName(log, FileAppender, env);
|
||||
free(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FileAppender;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user