1 | /* $Id: VBoxMpLogger.cpp 75443 2018-11-14 10:17:08Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBox WDDM Display logger implementation
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2018 Oracle Corporation
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | /* We're unable to use standard r3 vbgl-based backdoor logging API because win8 Metro apps
|
---|
19 | * can not do CreateFile/Read/Write by default.
|
---|
20 | * This is why we use miniport escape functionality to issue backdoor log string to the miniport
|
---|
21 | * and submit it to host via standard r0 backdoor logging api accordingly
|
---|
22 | */
|
---|
23 |
|
---|
24 | #include "UmHlpInternal.h"
|
---|
25 |
|
---|
26 | #include <../../../common/wddm/VBoxMPIf.h>
|
---|
27 |
|
---|
28 | #include <stdio.h>
|
---|
29 |
|
---|
30 | DECLCALLBACK(void) VBoxDispMpLoggerLog(const char *pszString)
|
---|
31 | {
|
---|
32 | D3DKMTFUNCTIONS const *d3dkmt = D3DKMTFunctions();
|
---|
33 | if (d3dkmt->pfnD3DKMTEscape == NULL)
|
---|
34 | return;
|
---|
35 |
|
---|
36 | D3DKMT_HANDLE hAdapter;
|
---|
37 | NTSTATUS Status = vboxDispKmtOpenAdapter(&hAdapter);
|
---|
38 | Assert(Status == STATUS_SUCCESS);
|
---|
39 | if (Status == 0)
|
---|
40 | {
|
---|
41 | uint32_t cbString = (uint32_t)strlen(pszString) + 1;
|
---|
42 | uint32_t cbCmd = RT_UOFFSETOF_DYN(VBOXDISPIFESCAPE_DBGPRINT, aStringBuf[cbString]);
|
---|
43 | PVBOXDISPIFESCAPE_DBGPRINT pCmd = (PVBOXDISPIFESCAPE_DBGPRINT)malloc(cbCmd);
|
---|
44 | Assert(pCmd);
|
---|
45 | if (pCmd)
|
---|
46 | {
|
---|
47 | pCmd->EscapeHdr.escapeCode = VBOXESC_DBGPRINT;
|
---|
48 | pCmd->EscapeHdr.u32CmdSpecific = 0;
|
---|
49 | memcpy(pCmd->aStringBuf, pszString, cbString);
|
---|
50 |
|
---|
51 | D3DKMT_ESCAPE EscapeData;
|
---|
52 | memset(&EscapeData, 0, sizeof(EscapeData));
|
---|
53 | EscapeData.hAdapter = hAdapter;
|
---|
54 | // EscapeData.hDevice = NULL;
|
---|
55 | EscapeData.Type = D3DKMT_ESCAPE_DRIVERPRIVATE;
|
---|
56 | // EscapeData.Flags.HardwareAccess = 0;
|
---|
57 | EscapeData.pPrivateDriverData = pCmd;
|
---|
58 | EscapeData.PrivateDriverDataSize = cbCmd;
|
---|
59 | // EscapeData.hContext = NULL;
|
---|
60 |
|
---|
61 | Status = d3dkmt->pfnD3DKMTEscape(&EscapeData);
|
---|
62 | Assert(Status == STATUS_SUCCESS);
|
---|
63 |
|
---|
64 | free(pCmd);
|
---|
65 | }
|
---|
66 |
|
---|
67 | Status = vboxDispKmtCloseAdapter(hAdapter);
|
---|
68 | Assert(Status == STATUS_SUCCESS);
|
---|
69 | }
|
---|
70 | }
|
---|
71 |
|
---|
72 | DECLCALLBACK(void) VBoxDispMpLoggerLogF(const char *pszString, ...)
|
---|
73 | {
|
---|
74 | char szBuffer[4096] = {0};
|
---|
75 | va_list pArgList;
|
---|
76 | va_start(pArgList, pszString);
|
---|
77 | _vsnprintf(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), pszString, pArgList);
|
---|
78 | va_end(pArgList);
|
---|
79 |
|
---|
80 | VBoxDispMpLoggerLog(szBuffer);
|
---|
81 | }
|
---|
82 |
|
---|
83 | /*
|
---|
84 | * Prefix the output string with module name and pid/tid.
|
---|
85 | */
|
---|
86 | static const char *vboxUmLogGetModuleName(void)
|
---|
87 | {
|
---|
88 | static int s_fModuleNameInited = 0;
|
---|
89 | static char s_szModuleName[MAX_PATH];
|
---|
90 |
|
---|
91 | if (!s_fModuleNameInited)
|
---|
92 | {
|
---|
93 | const DWORD cchName = GetModuleFileNameA(NULL, s_szModuleName, RT_ELEMENTS(s_szModuleName));
|
---|
94 | if (cchName == 0)
|
---|
95 | {
|
---|
96 | return "<no module>";
|
---|
97 | }
|
---|
98 | s_fModuleNameInited = 1;
|
---|
99 | }
|
---|
100 | return &s_szModuleName[0];
|
---|
101 | }
|
---|
102 |
|
---|
103 | DECLCALLBACK(void) VBoxWddmUmLog(const char *pszString)
|
---|
104 | {
|
---|
105 | char szBuffer[4096];
|
---|
106 | const int cbBuffer = sizeof(szBuffer);
|
---|
107 | char *pszBuffer = &szBuffer[0];
|
---|
108 |
|
---|
109 | int cbWritten = _snprintf(pszBuffer, cbBuffer, "['%s' 0x%x.0x%x]: ",
|
---|
110 | vboxUmLogGetModuleName(), GetCurrentProcessId(), GetCurrentThreadId());
|
---|
111 | if (cbWritten < 0 || cbWritten >= cbBuffer)
|
---|
112 | {
|
---|
113 | Assert(0);
|
---|
114 | pszBuffer[0] = 0;
|
---|
115 | cbWritten = 0;
|
---|
116 | }
|
---|
117 |
|
---|
118 | const size_t cbLeft = cbBuffer - cbWritten;
|
---|
119 | const size_t cbString = strlen(pszString) + 1;
|
---|
120 | if (cbString <= cbLeft)
|
---|
121 | {
|
---|
122 | memcpy(pszBuffer + cbWritten, pszString, cbString);
|
---|
123 | }
|
---|
124 | else
|
---|
125 | {
|
---|
126 | memcpy(pszBuffer + cbWritten, pszString, cbLeft - 1);
|
---|
127 | pszBuffer[cbWritten + cbLeft - 1] = 0;
|
---|
128 | }
|
---|
129 |
|
---|
130 | VBoxDispMpLoggerLog(szBuffer);
|
---|
131 | }
|
---|