|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
Packit |
1fb8d4 |
* FreeRDP Windows Server
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
Packit |
1fb8d4 |
* Copyright 2012-2013 Corey Clayton <can.of.tuna@gmail.com>
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/tchar.h>
|
|
Packit |
1fb8d4 |
#include <winpr/windows.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "wf_mirage.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#define DEVICE_KEY_PREFIX _T("\\Registry\\Machine\\")
|
|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
This function will iterate over the loaded display devices until it finds
|
|
Packit |
1fb8d4 |
the mirror device we want to load. If found, it will then copy the registry
|
|
Packit |
1fb8d4 |
key corresponding to the device to the wfi and returns TRUE. Otherwise
|
|
Packit |
1fb8d4 |
the function returns FALSE.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_find_display_device(wfInfo* wfi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BOOL result;
|
|
Packit |
1fb8d4 |
BOOL devFound;
|
|
Packit |
1fb8d4 |
DWORD deviceNumber;
|
|
Packit |
1fb8d4 |
DISPLAY_DEVICE deviceInfo;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
devFound = FALSE;
|
|
Packit |
1fb8d4 |
deviceNumber = 0;
|
|
Packit |
1fb8d4 |
deviceInfo.cb = sizeof(deviceInfo);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
while (result = EnumDisplayDevices(NULL, deviceNumber, &deviceInfo, 0))
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (_tcscmp(deviceInfo.DeviceString, _T("Mirage Driver")) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int deviceKeyLength;
|
|
Packit |
1fb8d4 |
int deviceKeyPrefixLength;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
deviceKeyPrefixLength = _tcslen(DEVICE_KEY_PREFIX);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (_tcsnicmp(deviceInfo.DeviceKey, DEVICE_KEY_PREFIX, deviceKeyPrefixLength) == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
deviceKeyLength = _tcslen(deviceInfo.DeviceKey) - deviceKeyPrefixLength;
|
|
Packit |
1fb8d4 |
wfi->deviceKey = (LPTSTR) malloc((deviceKeyLength + 1) * sizeof(TCHAR));
|
|
Packit |
1fb8d4 |
if (!wfi->deviceKey)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
_tcsncpy_s(wfi->deviceKey, deviceKeyLength + 1,
|
|
Packit |
1fb8d4 |
&deviceInfo.DeviceKey[deviceKeyPrefixLength], deviceKeyLength);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
_tcsncpy_s(wfi->deviceName, 32, deviceInfo.DeviceName, _tcslen(deviceInfo.DeviceName));
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
deviceNumber++;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* This function will attempt to access the the windows registry using the device
|
|
Packit |
1fb8d4 |
* key stored in the current wfi. It will attempt to read the value of the
|
|
Packit |
1fb8d4 |
* "Attach.ToDesktop" subkey and will return TRUE if the value is already set to
|
|
Packit |
1fb8d4 |
* val. If unable to read the subkey, this function will return FALSE. If the
|
|
Packit |
1fb8d4 |
* subkey is not set to val it will then attempt to set it to val and return TRUE. If
|
|
Packit |
1fb8d4 |
* unsuccessful or an unexpected value is encountered, the function returns
|
|
Packit |
1fb8d4 |
* FALSE.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_display_device_attach(wfInfo* wfi, DWORD mode)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
HKEY hKey;
|
|
Packit |
1fb8d4 |
LONG status;
|
|
Packit |
1fb8d4 |
DWORD dwType;
|
|
Packit |
1fb8d4 |
DWORD dwSize;
|
|
Packit |
1fb8d4 |
DWORD dwValue;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, wfi->deviceKey,
|
|
Packit |
1fb8d4 |
0, KEY_ALL_ACCESS | KEY_WOW64_64KEY, &hKey);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != ERROR_SUCCESS)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Error opening RegKey: status=0x%08lX", status);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status == ERROR_ACCESS_DENIED)
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "access denied. Do you have admin privleges?");
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
dwSize = sizeof(DWORD);
|
|
Packit |
1fb8d4 |
status = RegQueryValueEx(hKey, _T("Attach.ToDesktop"),
|
|
Packit |
1fb8d4 |
NULL, &dwType, (BYTE*) &dwValue, &dwSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != ERROR_SUCCESS)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Error querying RegKey: status=0x%08lX", status);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status == ERROR_ACCESS_DENIED)
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "access denied. Do you have admin privleges?");
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (dwValue ^ mode) //only if we want to change modes
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
dwValue = mode;
|
|
Packit |
1fb8d4 |
dwSize = sizeof(DWORD);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = RegSetValueEx(hKey, _T("Attach.ToDesktop"),
|
|
Packit |
1fb8d4 |
0, REG_DWORD, (BYTE*) &dwValue, dwSize);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != ERROR_SUCCESS)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Error writing registry key: %ld", status);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status == ERROR_ACCESS_DENIED)
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "access denied. Do you have admin privleges?");
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void wf_mirror_driver_print_display_change_status(LONG status)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
TCHAR disp_change[64];
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
switch (status)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_SUCCESSFUL:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_SUCCESSFUL"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_BADDUALVIEW:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_BADDUALVIEW"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_BADFLAGS:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_BADFLAGS"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_BADMODE:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_BADMODE"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_BADPARAM:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_BADPARAM"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_FAILED:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_FAILED"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_NOTUPDATED:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_NOTUPDATED"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case DISP_CHANGE_RESTART:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_RESTART"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
default:
|
|
Packit |
1fb8d4 |
_tcscpy(disp_change, _T("DISP_CHANGE_UNKNOWN"));
|
|
Packit |
1fb8d4 |
break;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status != DISP_CHANGE_SUCCESSFUL)
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "ChangeDisplaySettingsEx() failed with %s (%ld)", disp_change, status);
|
|
Packit |
1fb8d4 |
else
|
|
Packit |
1fb8d4 |
WLog_INFO(TAG, "ChangeDisplaySettingsEx() succeeded with %s (%ld)", disp_change, status);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* This function will attempt to apply the currently configured display settings
|
|
Packit |
1fb8d4 |
* in the registry to the display driver. It will return TRUE if successful
|
|
Packit |
1fb8d4 |
* otherwise it returns FALSE.
|
|
Packit |
1fb8d4 |
* If mode is MIRROR_UNLOAD then the the driver will be asked to remove itself.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_update(wfInfo* wfi, int mode)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
HDC dc;
|
|
Packit |
1fb8d4 |
BOOL status;
|
|
Packit |
1fb8d4 |
DWORD* extHdr;
|
|
Packit |
1fb8d4 |
WORD drvExtraSaved;
|
|
Packit |
1fb8d4 |
DEVMODE* deviceMode;
|
|
Packit |
1fb8d4 |
LONG disp_change_status;
|
|
Packit |
1fb8d4 |
DWORD dmf_devmodewext_magic_sig = 0xDF20C0DE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if ( (mode != MIRROR_LOAD) && (mode != MIRROR_UNLOAD) )
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Invalid mirror mode!");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
deviceMode = (DEVMODE*) malloc(sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
|
Packit |
1fb8d4 |
if (!deviceMode)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
deviceMode->dmDriverExtra = 2 * sizeof(DWORD);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
extHdr = (DWORD*)((BYTE*) &deviceMode + sizeof(DEVMODE));
|
|
Packit |
1fb8d4 |
extHdr[0] = dmf_devmodewext_magic_sig;
|
|
Packit |
1fb8d4 |
extHdr[1] = 0;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
drvExtraSaved = deviceMode->dmDriverExtra;
|
|
Packit |
1fb8d4 |
memset(deviceMode, 0, sizeof(DEVMODE) + EXT_DEVMODE_SIZE_MAX);
|
|
Packit |
1fb8d4 |
deviceMode->dmSize = sizeof(DEVMODE);
|
|
Packit |
1fb8d4 |
deviceMode->dmDriverExtra = drvExtraSaved;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (mode == MIRROR_LOAD)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
wfi->virtscreen_width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
|
Packit |
1fb8d4 |
wfi->virtscreen_height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
deviceMode->dmPelsWidth = wfi->virtscreen_width;
|
|
Packit |
1fb8d4 |
deviceMode->dmPelsHeight = wfi->virtscreen_height;
|
|
Packit |
1fb8d4 |
deviceMode->dmBitsPerPel = wfi->bitsPerPixel;
|
|
Packit |
1fb8d4 |
deviceMode->dmPosition.x = wfi->servscreen_xoffset;
|
|
Packit |
1fb8d4 |
deviceMode->dmPosition.y = wfi->servscreen_yoffset;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
deviceMode->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT | DM_POSITION;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
_tcsncpy_s(deviceMode->dmDeviceName, 32, wfi->deviceName, _tcslen(wfi->deviceName));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
disp_change_status = ChangeDisplaySettingsEx(wfi->deviceName, deviceMode, NULL, CDS_UPDATEREGISTRY, NULL);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = (disp_change_status == DISP_CHANGE_SUCCESSFUL) ? TRUE : FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!status)
|
|
Packit |
1fb8d4 |
wf_mirror_driver_print_display_change_status(disp_change_status);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return status;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_map_memory(wfInfo* wfi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int status;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
wfi->driverDC = CreateDC(wfi->deviceName, NULL, NULL, NULL);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wfi->driverDC == NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Could not create device driver context!");
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
LPVOID lpMsgBuf;
|
|
Packit |
1fb8d4 |
DWORD dw = GetLastError();
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
FormatMessage(
|
|
Packit |
1fb8d4 |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
Packit |
1fb8d4 |
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
Packit |
1fb8d4 |
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
Packit |
1fb8d4 |
NULL,
|
|
Packit |
1fb8d4 |
dw,
|
|
Packit |
1fb8d4 |
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
Packit |
1fb8d4 |
(LPTSTR) &lpMsgBuf,
|
|
Packit |
1fb8d4 |
0, NULL );
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
// Display the error message and exit the process
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "CreateDC failed on device [%s] with error %lu: %s", wfi->deviceName, dw, lpMsgBuf);
|
|
Packit |
1fb8d4 |
LocalFree(lpMsgBuf);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
wfi->changeBuffer = calloc(1, sizeof(GETCHANGESBUF));
|
|
Packit |
1fb8d4 |
if (!wfi->changeBuffer)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = ExtEscape(wfi->driverDC, dmf_esc_usm_pipe_map, 0, 0, sizeof(GETCHANGESBUF), (LPSTR) wfi->changeBuffer);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status <= 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Failed to map shared memory from the driver! code %d", status);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Unmap the shared memory and release the DC */
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_cleanup(wfInfo* wfi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
int status;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
status = ExtEscape(wfi->driverDC, dmf_esc_usm_pipe_unmap, sizeof(GETCHANGESBUF), (LPSTR) wfi->changeBuffer, 0, 0);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status <= 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Failed to unmap shared memory from the driver! code %d", status);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wfi->driverDC != NULL)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
status = DeleteDC(wfi->driverDC);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (status == 0)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_ERR(TAG, "Failed to release DC!");
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
free(wfi->changeBuffer);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL wf_mirror_driver_activate(wfInfo* wfi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (!wfi->mirrorDriverActive)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Activating Mirror Driver");
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wf_mirror_driver_find_display_device(wfi) == FALSE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Could not find dfmirage mirror driver! Is it installed?");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wf_mirror_driver_display_device_attach(wfi, 1) == FALSE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Could not attach display device!");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wf_mirror_driver_update(wfi, MIRROR_LOAD) == FALSE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "could not update system with new display settings!");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (wf_mirror_driver_map_memory(wfi) == FALSE)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Unable to map memory for mirror driver!");
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
wfi->mirrorDriverActive = TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
void wf_mirror_driver_deactivate(wfInfo* wfi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
if (wfi->mirrorDriverActive)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
WLog_DBG(TAG, "Deactivating Mirror Driver");
|
|
Packit |
1fb8d4 |
wf_mirror_driver_cleanup(wfi);
|
|
Packit |
1fb8d4 |
wf_mirror_driver_display_device_attach(wfi, 0);
|
|
Packit |
1fb8d4 |
wf_mirror_driver_update(wfi, MIRROR_UNLOAD);
|
|
Packit |
1fb8d4 |
wfi->mirrorDriverActive = FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|