Changeset 31145 in vbox
- Timestamp:
- Jul 27, 2010 3:53:05 PM (14 years ago)
- Location:
- trunk/src/VBox/Additions/WINNT/VBoxTray
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/VBoxTray/Makefile.kmk
r31002 r31145 30 30 VBoxTray_SOURCES = \ 31 31 VBoxTray.cpp \ 32 VBoxDispIf.cpp \ 32 33 VBoxSeamless.cpp \ 33 34 VBoxClipboard.cpp \ -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.cpp
r31002 r31145 663 663 return DefWindowProc(hwnd, msg, wParam, lParam); 664 664 } 665 666 /* display driver interface abstraction for XPDM & WDDM667 * with WDDM we can not use ExtEscape to communicate with our driver668 * because we do not have XPDM display driver any more, i.e. escape requests are handled by cdd669 * that knows nothing about us */670 DWORD VBoxDispIfInit(PVBOXDISPIF pIf)671 {672 pIf->enmMode = VBOXDISPIF_MODE_XPDM;673 return NO_ERROR;674 }675 676 DWORD VBoxDispIfTerm(PVBOXDISPIF pIf)677 {678 pIf->enmMode = VBOXDISPIF_MODE_UNKNOWN;679 return NO_ERROR;680 }681 682 static DWORD vboxDispIfEscapeXPDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData)683 {684 HDC hdc = GetDC(HWND_DESKTOP);685 VOID *pvData = cbData ? VBOXDISPIFESCAPE_DATA(pEscape, VOID) : NULL;686 int iRet = ExtEscape(hdc, pEscape->escapeCode, cbData, (LPCSTR)pvData, 0, NULL);687 ReleaseDC(HWND_DESKTOP, hdc);688 if (iRet > 0)689 return VINF_SUCCESS;690 else if (iRet == 0)691 return ERROR_NOT_SUPPORTED;692 /* else */693 return ERROR_GEN_FAILURE;694 }695 696 #ifdef VBOXWDDM697 static DWORD vboxDispIfSwitchToWDDM(PVBOXDISPIF pIf)698 {699 DWORD err = NO_ERROR;700 OSVERSIONINFO OSinfo;701 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);702 GetVersionEx (&OSinfo);703 if (OSinfo.dwMajorVersion >= 6)704 {705 /* this is vista and up */706 Log((__FUNCTION__": this is vista and up\n"));707 HMODULE hGdi32 = GetModuleHandle("gdi32");708 if (hGdi32 != NULL)709 {710 bool bSupported = true;711 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromHdc");712 Log((__FUNCTION__"pfnD3DKMTOpenAdapterFromHdc = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc));713 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromHdc);714 715 pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName");716 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName));717 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName);718 719 pIf->modeData.wddm.pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(hGdi32, "D3DKMTCloseAdapter");720 Log((__FUNCTION__": pfnD3DKMTCloseAdapter = %p\n", pIf->modeData.wddm.pfnD3DKMTCloseAdapter));721 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter);722 723 pIf->modeData.wddm.pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(hGdi32, "D3DKMTEscape");724 Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pIf->modeData.wddm.pfnD3DKMTEscape));725 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTCloseAdapter);726 727 pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn = (PFND3DKMT_INVALIDATEACTIVEVIDPN)GetProcAddress(hGdi32, "D3DKMTInvalidateActiveVidPn");728 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn = %p\n", pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn));729 bSupported &= !!(pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn);730 731 if (!bSupported)732 {733 Log((__FUNCTION__": one of pfnD3DKMT function pointers failed to initialize\n"));734 err = ERROR_NOT_SUPPORTED;735 }736 }737 else738 {739 Log((__FUNCTION__": GetModuleHandle(gdi32) failed, err(%d)\n", GetLastError()));740 err = ERROR_NOT_SUPPORTED;741 }742 }743 else744 {745 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_WDDM, because os is not Vista or upper\n"));746 err = ERROR_NOT_SUPPORTED;747 }748 749 return err;750 }751 752 typedef DECLCALLBACK(BOOLEAN) FNVBOXDISPIFWDDM_ADAPTEROP(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, LPCWSTR pDevName, PVOID pContext);753 typedef FNVBOXDISPIFWDDM_ADAPTEROP *PFNVBOXDISPIFWDDM_ADAPTEROP;754 static DWORD vboxDispIfWDDMAdapterOp(PCVBOXDISPIF pIf, LPCWSTR pDevName, PFNVBOXDISPIFWDDM_ADAPTEROP pfnOp, PVOID pContext)755 {756 D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME OpenAdapterData = {0};757 wcsncpy(OpenAdapterData.DeviceName, pDevName, RT_ELEMENTS(OpenAdapterData.DeviceName) - 1 /* the last one is always \0 */);758 DWORD err = ERROR_GEN_FAILURE;759 NTSTATUS Status = pIf->modeData.wddm.pfnD3DKMTOpenAdapterFromGdiDisplayName(&OpenAdapterData);760 if (!Status)761 {762 BOOLEAN bCloseAdapter = pfnOp(pIf, OpenAdapterData.hAdapter, OpenAdapterData.DeviceName, pContext);763 764 if (bCloseAdapter)765 {766 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0};767 ClosaAdapterData.hAdapter = OpenAdapterData.hAdapter;768 Status = pIf->modeData.wddm.pfnD3DKMTCloseAdapter(&ClosaAdapterData);769 if (Status)770 {771 Log((__FUNCTION__": pfnD3DKMTCloseAdapter failed, Status (0x%x)\n", Status));772 /* ignore */773 Status = 0;774 }775 }776 }777 else778 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName failed, Status (0x%x)\n", Status));779 780 return err;781 }782 783 typedef struct784 {785 NTSTATUS Status;786 PVBOXDISPIFESCAPE pEscape;787 int cbData;788 } VBOXDISPIFWDDM_ESCAPEOP_CONTEXT, *PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT;789 790 DECLCALLBACK(BOOLEAN) vboxDispIfEscapeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, LPCWSTR pDevName, PVOID pContext)791 {792 PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_ESCAPEOP_CONTEXT)pContext;793 794 D3DKMT_ESCAPE EscapeData = {0};795 EscapeData.hAdapter = hAdapter;796 //EscapeData.hDevice = NULL;797 EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;798 EscapeData.Flags.HardwareAccess = 1;799 EscapeData.pPrivateDriverData = pCtx->pEscape;800 EscapeData.PrivateDriverDataSize = VBOXDISPIFESCAPE_SIZE(pCtx->cbData);801 //EscapeData.hContext = NULL;802 803 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTEscape(&EscapeData);804 805 return TRUE;806 }807 808 static DWORD vboxDispIfEscapeWDDM(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData)809 {810 VBOXDISPIFWDDM_ESCAPEOP_CONTEXT Ctx = {0};811 Ctx.pEscape = pEscape;812 Ctx.cbData = cbData;813 DWORD err = vboxDispIfWDDMAdapterOp(pIf, L"\\\\.\\DISPLAY1", vboxDispIfEscapeWDDMOp, &Ctx);814 if (err == NO_ERROR)815 {816 if (!Ctx.Status)817 err = NO_ERROR;818 else819 {820 if (Ctx.Status == 0xC00000BBL) /* not supported */821 err = ERROR_NOT_SUPPORTED;822 else823 err = ERROR_GEN_FAILURE;824 Log((__FUNCTION__": pfnD3DKMTEscape failed, Status (0x%x)\n", Ctx.Status));825 }826 }827 else828 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err));829 830 return err;831 }832 833 typedef struct834 {835 NTSTATUS Status;836 VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO Info;837 } VBOXDISPIFWDDM_RESIZEOP_CONTEXT, *PVBOXDISPIFWDDM_RESIZEOP_CONTEXT;838 839 DECLCALLBACK(BOOLEAN) vboxDispIfResizeWDDMOp(PCVBOXDISPIF pIf, D3DKMT_HANDLE hAdapter, LPCWSTR pDevName, PVOID pContext)840 {841 PVBOXDISPIFWDDM_RESIZEOP_CONTEXT pCtx = (PVBOXDISPIFWDDM_RESIZEOP_CONTEXT)pContext;842 843 D3DKMT_INVALIDATEACTIVEVIDPN IAVidPnData = {0};844 uint32_t cbData = VBOXWDDM_RECOMMENDVIDPN_SIZE(1);845 PVBOXWDDM_RECOMMENDVIDPN pData = (PVBOXWDDM_RECOMMENDVIDPN)malloc(cbData);846 if (pData)847 {848 memset(pData, 0, cbData);849 pData->cScreenInfos = 1;850 memcpy(&pData->aScreenInfos[0], &pCtx->Info, sizeof (VBOXWDDM_RECOMMENDVIDPN_SCREEN_INFO));851 852 IAVidPnData.hAdapter = hAdapter;853 IAVidPnData.pPrivateDriverData = pData;854 IAVidPnData.PrivateDriverDataSize = cbData;855 856 pCtx->Status = pIf->modeData.wddm.pfnD3DKMTInvalidateActiveVidPn(&IAVidPnData);857 if (pCtx->Status)858 Log((__FUNCTION__": pfnD3DKMTInvalidateActiveVidPn failed, Status (0x%x)\n", pCtx->Status));859 860 free(pData);861 }862 else863 {864 Log((__FUNCTION__": malloc failed\n"));865 pCtx->Status = -1;866 }867 868 return TRUE;869 }870 871 static DWORD vboxDispIfResizeWDDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)872 {873 VBOXDISPIFWDDM_RESIZEOP_CONTEXT Ctx = {0};874 Ctx.Info.Id = Id;875 Ctx.Info.Width = Width;876 Ctx.Info.Height = Height;877 Ctx.Info.BitsPerPixel = BitsPerPixel;878 DWORD err = vboxDispIfWDDMAdapterOp(pIf, L"\\\\.\\DISPLAY1", vboxDispIfResizeWDDMOp, &Ctx);879 if (err == NO_ERROR)880 {881 if (!Ctx.Status)882 err = NO_ERROR;883 else884 {885 if (Ctx.Status == 0xC00000BBL) /* not supported */886 err = ERROR_NOT_SUPPORTED;887 else888 err = ERROR_GEN_FAILURE;889 Log((__FUNCTION__": vboxDispIfResizeWDDMOp failed, Status (0x%x)\n", Ctx.Status));890 }891 }892 else893 Log((__FUNCTION__": vboxDispIfWDDMAdapterOp failed, err (%d)\n", err));894 895 return err;896 }897 #endif898 899 DWORD VBoxDispIfEscape(PCVBOXDISPIF pIf, PVBOXDISPIFESCAPE pEscape, int cbData)900 {901 switch (pIf->enmMode)902 {903 case VBOXDISPIF_MODE_XPDM_NT4:904 case VBOXDISPIF_MODE_XPDM:905 return vboxDispIfEscapeXPDM(pIf, pEscape, cbData);906 #ifdef VBOXWDDM907 case VBOXDISPIF_MODE_WDDM:908 return vboxDispIfEscapeWDDM(pIf, pEscape, cbData);909 #endif910 default:911 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));912 return ERROR_INVALID_PARAMETER;913 }914 }915 916 static DWORD vboxDispIfResizeXPDM(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)917 {918 return ERROR_NOT_SUPPORTED;919 }920 921 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel)922 {923 switch (pIf->enmMode)924 {925 case VBOXDISPIF_MODE_XPDM_NT4:926 return ERROR_NOT_SUPPORTED;927 case VBOXDISPIF_MODE_XPDM:928 return vboxDispIfResizeXPDM(pIf, Id, Width, Height, BitsPerPixel);929 #ifdef VBOXWDDM930 case VBOXDISPIF_MODE_WDDM:931 return vboxDispIfResizeWDDM(pIf, Id, Width, Height, BitsPerPixel);932 #endif933 default:934 Log((__FUNCTION__": unknown mode (%d)\n", pIf->enmMode));935 return ERROR_INVALID_PARAMETER;936 }937 }938 939 static DWORD vboxDispIfSwitchToXPDM_NT4(PVBOXDISPIF pIf)940 {941 return NO_ERROR;942 }943 944 static DWORD vboxDispIfSwitchToXPDM(PVBOXDISPIF pIf)945 {946 DWORD err = NO_ERROR;947 AssertBreakpoint();948 OSVERSIONINFO OSinfo;949 OSinfo.dwOSVersionInfoSize = sizeof (OSinfo);950 GetVersionEx (&OSinfo);951 if (OSinfo.dwMajorVersion >= 5)952 {953 HMODULE hUser = GetModuleHandle("USER32");954 if (NULL != hUser)955 {956 bool bSupported = true;957 *(uintptr_t *)&pIf->modeData.xpdm.pfnChangeDisplaySettingsEx = (uintptr_t)GetProcAddress(hUser, "ChangeDisplaySettingsExA");958 Log((__FUNCTION__": pfnChangeDisplaySettingsEx = %p\n", pIf->modeData.xpdm.pfnChangeDisplaySettingsEx));959 bSupported &= !!(pIf->modeData.xpdm.pfnChangeDisplaySettingsEx);960 961 if (!bSupported)962 {963 Log((__FUNCTION__": pfnChangeDisplaySettingsEx function pointer failed to initialize\n"));964 err = ERROR_NOT_SUPPORTED;965 }966 }967 else968 {969 Log((__FUNCTION__": failed to get USER32 handle, err (%d)\n", GetLastError()));970 err = ERROR_NOT_SUPPORTED;971 }972 }973 else974 {975 Log((__FUNCTION__": can not switch to VBOXDISPIF_MODE_XPDM, because os is not >= w2k\n"));976 err = ERROR_NOT_SUPPORTED;977 }978 979 return err;980 }981 982 DWORD VBoxDispIfSwitchMode(PVBOXDISPIF pIf, VBOXDISPIF_MODE enmMode, VBOXDISPIF_MODE *penmOldMode)983 {984 /* @todo: may need to addd synchronization in case we want to change modes dynamically985 * i.e. currently the mode is supposed to be initialized once on service initialization */986 if (penmOldMode)987 *penmOldMode = pIf->enmMode;988 989 if (enmMode == pIf->enmMode)990 return VINF_ALREADY_INITIALIZED;991 992 DWORD err = NO_ERROR;993 switch (enmMode)994 {995 case VBOXDISPIF_MODE_XPDM_NT4:996 Log((__FUNCTION__": request to switch to VBOXDISPIF_MODE_XPDM_NT4\n"));997 err = vboxDispIfSwitchToXPDM_NT4(pIf);998 if (err == NO_ERROR)999 {1000 Log((__FUNCTION__": successfully switched to XPDM_NT4 mode\n"));1001 pIf->enmMode = VBOXDISPIF_MODE_XPDM_NT4;1002 }1003 else1004 Log((__FUNCTION__": failed to switch to XPDM_NT4 mode, err (%d)\n", err));1005 break;1006 case VBOXDISPIF_MODE_XPDM:1007 Log((__FUNCTION__": request to switch to VBOXDISPIF_MODE_XPDM\n"));1008 err = vboxDispIfSwitchToXPDM(pIf);1009 if (err == NO_ERROR)1010 {1011 Log((__FUNCTION__": successfully switched to XPDM mode\n"));1012 pIf->enmMode = VBOXDISPIF_MODE_XPDM;1013 }1014 else1015 Log((__FUNCTION__": failed to switch to XPDM mode, err (%d)\n", err));1016 break;1017 #ifdef VBOXWDDM1018 case VBOXDISPIF_MODE_WDDM:1019 {1020 Log((__FUNCTION__": request to switch to VBOXDISPIF_MODE_WDDM\n"));1021 err = vboxDispIfSwitchToWDDM(pIf);1022 if (err == NO_ERROR)1023 {1024 Log((__FUNCTION__": successfully switched to WDDM mode\n"));1025 pIf->enmMode = VBOXDISPIF_MODE_WDDM;1026 }1027 else1028 Log((__FUNCTION__": failed to switch to WDDM mode, err (%d)\n", err));1029 break;1030 }1031 #endif1032 default:1033 err = ERROR_INVALID_PARAMETER;1034 break;1035 }1036 return err;1037 } -
trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxTray.h
r28800 r31145 33 33 #include <VBox/VBoxGuestLib.h> 34 34 #include <VBoxDisplay.h> 35 #ifdef VBOXWDDM 36 # include <d3dkmthk.h> 37 #endif 35 36 #include "VBoxDispIf.h" 38 37 39 38 #define WM_VBOX_RESTORED WM_APP + 1 … … 44 43 #define ID_TRAYICON 2000 45 44 46 typedef enum47 {48 VBOXDISPIF_MODE_UNKNOWN = 0,49 VBOXDISPIF_MODE_XPDM_NT4 = 1,50 VBOXDISPIF_MODE_XPDM51 #ifdef VBOXWDDM52 , VBOXDISPIF_MODE_WDDM53 #endif54 } VBOXDISPIF_MODE;55 /* display driver interface abstraction for XPDM & WDDM56 * with WDDM we can not use ExtEscape to communicate with our driver57 * because we do not have XPDM display driver any more, i.e. escape requests are handled by cdd58 * that knows nothing about us59 * NOTE: DispIf makes no checks whether the display driver is actually a VBox driver,60 * it just switches between using different backend OS API based on the VBoxDispIfSwitchMode call61 * It's caller's responsibility to initiate it to work in the correct mode */62 typedef struct VBOXDISPIF63 {64 VBOXDISPIF_MODE enmMode;65 /* with WDDM the approach is to call into WDDM miniport driver via PFND3DKMT API provided by the GDI,66 * The PFND3DKMT is supposed to be used by the OpenGL ICD according to MSDN, so this approach is a bit hacky */67 union68 {69 struct70 {71 LONG (WINAPI * pfnChangeDisplaySettingsEx)(LPCSTR lpszDeviceName, LPDEVMODE lpDevMode, HWND hwnd, DWORD dwflags, LPVOID lParam);72 } xpdm;73 #ifdef VBOXWDDM74 struct75 {76 /* open adapter */77 PFND3DKMT_OPENADAPTERFROMHDC pfnD3DKMTOpenAdapterFromHdc;78 PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME pfnD3DKMTOpenAdapterFromGdiDisplayName;79 /* close adapter */80 PFND3DKMT_CLOSEADAPTER pfnD3DKMTCloseAdapter;81 /* escape */82 PFND3DKMT_ESCAPE pfnD3DKMTEscape;83 /* auto resize support */84 PFND3DKMT_INVALIDATEACTIVEVIDPN pfnD3DKMTInvalidateActiveVidPn;85 } wddm;86 #endif87 } modeData;88 } VBOXDISPIF, *PVBOXDISPIF;89 typedef const struct VBOXDISPIF *PCVBOXDISPIF;90 91 /* initializes the DispIf92 * Initially the DispIf is configured to work in XPDM mode93 * call VBoxDispIfSwitchMode to switch the mode to WDDM */94 DWORD VBoxDispIfInit(PVBOXDISPIF pIf);95 DWORD VBoxDispIfSwitchMode(PVBOXDISPIF pIf, VBOXDISPIF_MODE enmMode, VBOXDISPIF_MODE *penmOldMode);96 DECLINLINE(VBOXDISPIF_MODE) VBoxDispGetMode(PVBOXDISPIF pIf) { return pIf->enmMode; }97 DWORD VBoxDispIfTerm(PVBOXDISPIF pIf);98 DWORD VBoxDispIfEscape(PCVBOXDISPIF const pIf, PVBOXDISPIFESCAPE pEscape, int cbData);99 DWORD VBoxDispIfResize(PCVBOXDISPIF const pIf, ULONG Id, DWORD Width, DWORD Height, DWORD BitsPerPixel);100 45 101 46 /* The environment information for services. */
Note:
See TracChangeset
for help on using the changeset viewer.