diff --git a/server/Windows/wf_mirage.c b/server/Windows/wf_mirage.c index 5b6160022..2bfc1ae1d 100644 --- a/server/Windows/wf_mirage.c +++ b/server/Windows/wf_mirage.c @@ -17,8 +17,195 @@ * limitations under the License. */ +#include #include #include "wf_mirage.h" +int wf_mirage_step1(wfPeerContext* context) +{ + BOOL result; + DWORD deviceNumber; + DISPLAY_DEVICE deviceInfo; + deviceNumber = 0; + deviceInfo.cb = sizeof(deviceInfo); + + printf("Detecting display devices:\n"); + + while (result = EnumDisplayDevices(NULL, deviceNumber, &deviceInfo, 0)) + { + _tprintf(_T("\t%s\n"), deviceInfo.DeviceString); + + if (_tcscmp(deviceInfo.DeviceString, _T("Mirage Driver")) == 0) + { + _tprintf(_T("\n\nFound our target of interest!\n")); + _tprintf(_T("Key: %s\n"), deviceInfo.DeviceKey); + _tprintf(_T("Name: %s\n"), deviceInfo.DeviceName); + _tprintf(_T("ID: %s\n"), deviceInfo.DeviceID); + + _tcsncpy_s(context->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName)); + } + + deviceNumber++; + } + + return 0; +} + +int wf_mirage_step2(wfPeerContext* context) +{ + LONG status; + DWORD rtype, rdata, rdata_size; + TCHAR reg_full[] = _T("System\\CurrentControlSet\\Control\\Video\\{0752CE80-4CE2-46BB-9EAE-5C2A03BF4CEC}\\0000"); + + _tprintf(_T("\nOpening registry key %s\n"), reg_full); + + rtype = 0; + rdata = 0; + rdata_size = sizeof(rdata); + + status = RegGetValue(HKEY_LOCAL_MACHINE, reg_full, + _T("Attach.ToDesktop"), RRF_RT_REG_DWORD, &rtype, &rdata, &rdata_size); + + if (status != ERROR_SUCCESS) + { + printf("Failed to read registry value.\n"); + printf("operation returned %d\n", status); + return -1; + } + + _tprintf(_T("type = %04X, data = %04X\n\nNow let's try attaching it...\n"), rtype, rdata); + + if (rdata == 0) + { + rdata = 1; + + status = RegSetKeyValue(HKEY_LOCAL_MACHINE, reg_full, + _T("Attach.ToDesktop"), REG_DWORD, &rdata, rdata_size); + + if (status != ERROR_SUCCESS) + { + _tprintf(_T("Failed to read registry value.\n")); + _tprintf(_T("operation returned %d\n"), status); + return -1; + } + + _tprintf(_T("Attached to Desktop\n\n")); + } + else if (rdata == 1) + { + _tprintf(_T("Already attached to desktop!\n")); + } + else + { + _tprintf(_T("Something went wrong with attaching to desktop...\nrdata=%d\n"), rdata); + return -1; + } + + return 0; +} + +int wf_mirage_step3(wfPeerContext* context) +{ + LONG status; + DWORD* extHdr; + WORD drvExtraSaved; + DEVMODE* deviceMode; + DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE; + + deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX); + deviceMode->dmDriverExtra = 2 * sizeof(DWORD); + + extHdr = (DWORD*)((BYTE*) &deviceMode + sizeof(DEVMODE)); + extHdr[0] = dmf_devmodewext_magic_sig; + extHdr[1] = 0; + + drvExtraSaved = deviceMode->dmDriverExtra; + memset(deviceMode, 0, sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX); + deviceMode->dmSize = sizeof(DEVMODE); + deviceMode->dmDriverExtra = drvExtraSaved; + + deviceMode->dmPelsWidth = 640; + deviceMode->dmPelsHeight = 480; + deviceMode->dmBitsPerPel = 32; + deviceMode->dmPosition.x = 0; + deviceMode->dmPosition.y = 0; + + deviceMode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION; + + _tcsncpy_s(deviceMode->dmDeviceName, 32, context->deviceName, _tcslen(context->deviceName)); + + status = ChangeDisplaySettingsEx(context->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL); + + switch (status) + { + case DISP_CHANGE_SUCCESSFUL: + printf("ChangeDisplaySettingsEx() was successfull\n"); + break; + + case DISP_CHANGE_BADDUALVIEW: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_BADDUALVIEW, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_BADFLAGS: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_BADFLAGS, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_BADMODE: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_BADMODE, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_BADPARAM: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_BADPARAM, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_FAILED: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_FAILED, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_NOTUPDATED: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_NOTUPDATED, code %d\n", status); + return -1; + break; + + case DISP_CHANGE_RESTART: + printf("ChangeDisplaySettingsEx() failed with DISP_CHANGE_RESTART, code %d\n", status); + return -1; + break; + } + + return 0; +} + +int wf_mirage_step4(wfPeerContext* context) +{ + int status; + + printf("\n\nCreating a device context...\n"); + + context->driverDC = CreateDC(context->deviceName, NULL, NULL, NULL); + + if (context->driverDC == NULL) + { + printf("Could not create device driver context!\n"); + return -1; + } + + context->changeBuffer = malloc(sizeof(GETCHANGESBUF)); + + printf("\n\nConnecting to driver...\n"); + status = ExtEscape(context->driverDC, dmf_esc_usm_pipe_map, 0, 0, sizeof(GETCHANGESBUF), (LPSTR) context->changeBuffer); + + if (status <= 0) + { + printf("Failed to map shared memory from the driver! Code %d\n", status); + } + + return 0; +} diff --git a/server/Windows/wf_mirage.h b/server/Windows/wf_mirage.h index 0214942ad..ad3935f87 100644 --- a/server/Windows/wf_mirage.h +++ b/server/Windows/wf_mirage.h @@ -109,6 +109,7 @@ typedef struct CHANGES_RECORD pointrect[MAXCHANGES_BUF]; } CHANGES_BUF; +#define EXT_DEVMODE_SIZE_MAX 3072 #define DMF_PIPE_SEC_SIZE_DEFAULT ALIGN64K(sizeof(CHANGES_BUF)) typedef struct @@ -199,4 +200,9 @@ typedef struct ULONG nColorBmPalEntries; } Esc_dmf_pointer_shape_get_OUT; +int wf_mirage_step1(wfPeerContext* context); +int wf_mirage_step2(wfPeerContext* context); +int wf_mirage_step3(wfPeerContext* context); +int wf_mirage_step4(wfPeerContext* context); + #endif /* WF_MIRAGE_H */ diff --git a/server/Windows/wf_peer.c b/server/Windows/wf_peer.c index 42fe2a228..9923304b2 100644 --- a/server/Windows/wf_peer.c +++ b/server/Windows/wf_peer.c @@ -25,7 +25,10 @@ void wf_peer_context_new(freerdp_peer* client, wfPeerContext* context) { - + wf_mirage_step1(context); + wf_mirage_step2(context); + wf_mirage_step3(context); + wf_mirage_step4(context); } void wf_peer_context_free(freerdp_peer* client, wfPeerContext* context) diff --git a/server/Windows/wfreerdp.h b/server/Windows/wfreerdp.h index d22b27b1a..e1f177274 100644 --- a/server/Windows/wfreerdp.h +++ b/server/Windows/wfreerdp.h @@ -25,7 +25,11 @@ struct wf_peer_context { rdpContext _p; + + HDC driverDC; boolean activated; + void* changeBuffer; + TCHAR deviceName[32]; }; typedef struct wf_peer_context wfPeerContext;