Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tobias Hunger
qt-creator
Commits
56d36649
Commit
56d36649
authored
Nov 18, 2010
by
Friedemann Kleint
Browse files
Debugger: Add extension library to be loaded into CDB.exe
parent
8477c7bc
Changes
24
Hide whitespace changes
Inline
Side-by-side
src/libs/libs.pro
View file @
56d36649
...
...
@@ -14,3 +14,5 @@ SUBDIRS = \
qmleditorwidgets
\
symbianutils
\
3
rdparty
win32
:
SUBDIRS
+=
qtcreatorcdbext
src/libs/qtcreatorcdbext/base64.cpp
0 → 100644
View file @
56d36649
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "base64.h"
#include <ostream>
static
void
base64EncodeTriple
(
std
::
ostream
&
str
,
const
unsigned
char
triple
[
3
],
size_t
length
=
3
)
{
static
const
char
base64Encoding
[]
=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
;
// Convert 3 bytes of triplet into 4 bytes, write out 64 bit-wise using a character mapping,
// see description of base64.
unsigned
tripleValue
=
triple
[
0
]
*
256
;
tripleValue
+=
triple
[
1
];
tripleValue
*=
256
;
tripleValue
+=
triple
[
2
];
char
result
[
4
]
=
{
0
,
0
,
0
,
0
};
for
(
int
i
=
3
;
i
>=
0
;
i
--
)
{
result
[
i
]
=
base64Encoding
[
tripleValue
%
64
];
tripleValue
/=
64
;
}
// Write out quad and pad if it is a padding triple.
const
size_t
writeLength
=
length
+
1
;
size_t
i
=
0
;
for
(
;
i
<
writeLength
;
i
++
)
str
<<
result
[
i
];
for
(
;
i
<
4
;
i
++
)
str
<<
'='
;
}
void
base64Encode
(
std
::
ostream
&
str
,
const
unsigned
char
*
source
,
size_t
sourcelen
)
{
if
(
!
sourcelen
)
{
str
<<
"===="
;
return
;
}
/* Encode triples */
const
unsigned
char
*
sourceEnd
=
source
+
sourcelen
;
for
(
const
unsigned
char
*
triple
=
source
;
triple
<
sourceEnd
;
)
{
const
unsigned
char
*
nextTriple
=
triple
+
3
;
if
(
nextTriple
<=
sourceEnd
)
{
// Encode full triple, including very last one
base64EncodeTriple
(
str
,
triple
);
triple
=
nextTriple
;
}
else
{
// Past end and some padding required.
unsigned
char
paddingTriple
[
3
]
=
{
0
,
0
,
0
};
std
::
copy
(
triple
,
sourceEnd
,
paddingTriple
);
base64EncodeTriple
(
str
,
paddingTriple
,
sourceEnd
-
triple
);
break
;
}
}
}
src/libs/qtcreatorcdbext/base64.h
0 → 100644
View file @
56d36649
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef BASE64_H
#define BASE64_H
#include <iosfwd>
// Base 64 encoding helper
void
base64Encode
(
std
::
ostream
&
str
,
const
unsigned
char
*
source
,
size_t
sourcelen
);
#endif // BASE64_H
src/libs/qtcreatorcdbext/cdb_detect.pri
0 → 100644
View file @
56d36649
# Detect presence of "Debugging Tools For Windows"
# in case MS VS compilers are used.
CDB_PATH=""
win32 {
contains(QMAKE_CXX, cl) {
CDB_PATH="$$(CDB_PATH)"
isEmpty(CDB_PATH):CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows/sdk"
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows (x86)/sdk"
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows (x64)/sdk"
!exists($$CDB_PATH):CDB_PATH="$$(ProgramFiles)/Debugging Tools For Windows 64-bit/sdk"
}
}
src/libs/qtcreatorcdbext/common.cpp
0 → 100644
View file @
56d36649
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "common.h"
#include "iinterfacepointer.h"
#include <sstream>
std
::
string
winErrorMessage
(
unsigned
long
error
)
{
char
*
lpMsgBuf
;
const
int
len
=
FormatMessageA
(
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
NULL
,
error
,
0
,
(
LPSTR
)
&
lpMsgBuf
,
0
,
NULL
);
if
(
len
)
{
const
std
::
string
rc
(
lpMsgBuf
,
len
);
LocalFree
(
lpMsgBuf
);
return
rc
;
}
std
::
ostringstream
str
;
str
<<
"Unknown error "
<<
error
;
return
str
.
str
();
}
std
::
string
winErrorMessage
()
{
return
winErrorMessage
(
GetLastError
());
}
std
::
string
msgDebugEngineComResult
(
HRESULT
hr
)
{
switch
(
hr
)
{
case
S_OK
:
return
std
::
string
(
"S_OK"
);
case
S_FALSE
:
return
std
::
string
(
"S_FALSE"
);
case
E_FAIL
:
break
;
case
E_INVALIDARG
:
return
std
::
string
(
"E_INVALIDARG"
);
case
E_NOINTERFACE
:
return
std
::
string
(
"E_NOINTERFACE"
);
case
E_OUTOFMEMORY
:
return
std
::
string
(
"E_OUTOFMEMORY"
);
case
E_UNEXPECTED
:
return
std
::
string
(
"E_UNEXPECTED"
);
case
E_NOTIMPL
:
return
std
::
string
(
"E_NOTIMPL"
);
}
if
(
hr
==
HRESULT_FROM_WIN32
(
ERROR_ACCESS_DENIED
))
return
std
::
string
(
"ERROR_ACCESS_DENIED"
);;
if
(
hr
==
HRESULT_FROM_NT
(
STATUS_CONTROL_C_EXIT
))
return
std
::
string
(
"STATUS_CONTROL_C_EXIT"
);
return
std
::
string
(
"E_FAIL "
)
+
winErrorMessage
(
HRESULT_CODE
(
hr
));
}
std
::
string
msgDebugEngineComFailed
(
const
char
*
func
,
HRESULT
hr
)
{
std
::
string
rc
=
func
;
rc
+=
" failed: "
;
rc
+=
msgDebugEngineComResult
(
hr
);
return
rc
;
}
ULONG
currentThreadId
(
IDebugSystemObjects
*
sysObjects
)
{
ULONG
id
=
0
;
if
(
sysObjects
->
GetCurrentThreadId
(
&
id
)
==
S_OK
)
return
id
;
return
0
;
}
ULONG
currentThreadId
(
CIDebugClient
*
client
)
{
IInterfacePointer
<
IDebugSystemObjects
>
sysObjects
(
client
);
if
(
sysObjects
)
return
currentThreadId
(
sysObjects
.
data
());
return
0
;
}
ULONG
currentProcessId
(
IDebugSystemObjects
*
sysObjects
)
{
ULONG64
handle
=
0
;
if
(
sysObjects
->
GetCurrentProcessHandle
(
&
handle
)
==
S_OK
)
return
GetProcessId
((
HANDLE
)
handle
);
return
0
;
}
ULONG
currentProcessId
(
CIDebugClient
*
client
)
{
IInterfacePointer
<
IDebugSystemObjects
>
sysObjects
(
client
);
if
(
sysObjects
)
return
currentProcessId
(
sysObjects
.
data
());
return
0
;
}
src/libs/qtcreatorcdbext/common.h
0 → 100644
View file @
56d36649
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef COMMON_H
#define COMMON_H
// Define KDEXT_64BIT to make all wdbgexts APIs recognize 64 bit addresses
// It is recommended for extensions to use 64 bit headers from wdbgexts so
// the extensions could support 64 bit targets.
#include <string>
#include <sstream>
#include <windows.h>
#define KDEXT_64BIT
#include <wdbgexts.h>
#include <dbgeng.h>
static
const
char
creatorOutputPrefixC
[]
=
"QtCreatorExt: "
;
typedef
IDebugControl
CIDebugControl
;
typedef
IDebugSymbols3
CIDebugSymbols
;
typedef
IDebugSymbolGroup2
CIDebugSymbolGroup
;
typedef
IDebugClient5
CIDebugClient
;
typedef
IDebugSystemObjects
CIDebugSystemObjects
;
typedef
IDebugDataSpaces4
CIDebugDataSpaces
;
typedef
IDebugAdvanced2
CIDebugAdvanced
;
typedef
IDebugRegisters2
CIDebugRegisters
;
// Utility messages
std
::
string
winErrorMessage
(
unsigned
long
error
);
std
::
string
winErrorMessage
();
std
::
string
msgDebugEngineComResult
(
HRESULT
hr
);
std
::
string
msgDebugEngineComFailed
(
const
char
*
func
,
HRESULT
hr
);
// Debug helper for anything streamable as in 'DebugPrint() << object'
// Derives from std::ostringstream and print out everything accumulated in destructor.
struct
DebugPrint
:
public
std
::
ostringstream
{
DebugPrint
()
{}
~
DebugPrint
()
{
dprintf
(
"DEBUG: %s
\n
"
,
str
().
c_str
());
}
};
ULONG
currentThreadId
(
IDebugSystemObjects
*
sysObjects
);
ULONG
currentThreadId
(
CIDebugClient
*
client
);
ULONG
currentProcessId
(
IDebugSystemObjects
*
sysObjects
);
ULONG
currentProcessId
(
CIDebugClient
*
client
);
#endif // COMMON_H
src/libs/qtcreatorcdbext/eventcallback.cpp
0 → 100644
View file @
56d36649
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "eventcallback.h"
#include "extensioncontext.h"
#include "stringutils.h"
#include "gdbmihelpers.h"
static
const
char
eventContextC
[]
=
"event"
;
static
const
char
moduleContextC
[]
=
"module"
;
// Special exception codes (see dbgwinutils.cpp).
enum
{
winExceptionCppException
=
0xe06d7363
,
winExceptionStartupCompleteTrap
=
0x406d1388
,
winExceptionRpcServerUnavailable
=
0x6ba
,
winExceptionRpcServerInvalid
=
0x6a6
,
winExceptionDllNotFound
=
0xc0000135
,
winExceptionDllEntryPointNoFound
=
0xc0000139
,
winExceptionDllInitFailed
=
0xc0000142
,
winExceptionMissingSystemFile
=
0xc0000143
,
winExceptionAppInitFailed
=
0xc0000143
};
EventCallback
::
EventCallback
(
IDebugEventCallbacks
*
wrapped
)
:
m_wrapped
(
wrapped
)
{
}
EventCallback
::~
EventCallback
()
{
}
STDMETHODIMP
EventCallback
::
QueryInterface
(
THIS_
IN
REFIID
InterfaceId
,
OUT
PVOID
*
Interface
)
{
*
Interface
=
NULL
;
if
(
IsEqualIID
(
InterfaceId
,
__uuidof
(
IUnknown
))
||
IsEqualIID
(
InterfaceId
,
__uuidof
(
IDebugOutputCallbacks
)))
{
*
Interface
=
(
IDebugOutputCallbacks
*
)
this
;
AddRef
();
return
S_OK
;
}
else
{
return
E_NOINTERFACE
;
}
}
STDMETHODIMP_
(
ULONG
)
EventCallback
::
AddRef
(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
return
1
;
}
STDMETHODIMP_
(
ULONG
)
EventCallback
::
Release
(
THIS
)
{
// This class is designed to be static so
// there's no true refcount.
return
0
;
}
STDMETHODIMP
EventCallback
::
GetInterestMask
(
THIS_
__out
PULONG
mask
)
{
if
(
m_wrapped
)
m_wrapped
->
GetInterestMask
(
mask
);
*
mask
|=
DEBUG_EVENT_CREATE_PROCESS
|
DEBUG_EVENT_EXIT_PROCESS
|
DEBUG_EVENT_BREAKPOINT
|
DEBUG_EVENT_EXCEPTION
|
DEBUG_EVENT_LOAD_MODULE
|
DEBUG_EVENT_UNLOAD_MODULE
;
return
S_OK
;
}
STDMETHODIMP
EventCallback
::
Breakpoint
(
THIS_
__in
PDEBUG_BREAKPOINT
b
)
{
// Breakpoint hit - Set the stop reason parameters on the extension context.
typedef
ExtensionContext
::
StopReasonMap
StopReasonMap
;
typedef
ExtensionContext
::
StopReasonMap
::
value_type
StopReasonMapValue
;
ULONG
id
=
0
;
ULONG64
address
=
0
;
b
->
GetId
(
&
id
);
b
->
GetOffset
(
&
address
);
StopReasonMap
stopReason
;
stopReason
.
insert
(
StopReasonMapValue
(
std
::
string
(
"breakpointId"
),
toString
(
id
)));
if
(
address
)
stopReason
.
insert
(
StopReasonMapValue
(
std
::
string
(
"breakpointAddress"
),
toString
(
address
)));
ExtensionContext
::
instance
().
setStopReason
(
stopReason
,
"breakpoint"
);
return
m_wrapped
?
m_wrapped
->
Breakpoint
(
b
)
:
S_OK
;
}
static
inline
ExtensionContext
::
StopReasonMap
exceptionParameters
(
const
EXCEPTION_RECORD64
&
e
,
unsigned
firstChance
)
{
typedef
ExtensionContext
::
StopReasonMap
StopReasonMap
;
typedef
ExtensionContext
::
StopReasonMap
::
value_type
StopReasonMapValue
;
// Fill exception record
StopReasonMap
parameters
;
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"firstChance"
),
toString
(
firstChance
)));
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionAddress"
),
toString
(
e
.
ExceptionAddress
)));
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionCode"
),
toString
(
e
.
ExceptionCode
)));
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionFlags"
),
toString
(
e
.
ExceptionFlags
)));
// Hard code some parameters (used for access violations)
if
(
e
.
NumberParameters
>=
1
)
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionInformation0"
),
toString
(
e
.
ExceptionInformation
[
0
])));
if
(
e
.
NumberParameters
>=
2
)
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionInformation1"
),
toString
(
e
.
ExceptionInformation
[
1
])));
// Add top stack frame if possible
StackFrame
frame
;
std
::
string
errorMessage
;
// If it is a C++ exception, get frame #2 (first outside MSVC runtime)
const
unsigned
frameNumber
=
e
.
ExceptionCode
==
winExceptionCppException
?
2
:
0
;
if
(
getFrame
(
frameNumber
,
&
frame
,
&
errorMessage
))
{
if
(
!
frame
.
fullPathName
.
empty
())
{
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionFile"
),
wStringToString
(
frame
.
fullPathName
)));
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionLine"
),
toString
(
frame
.
line
)));
}
if
(
!
frame
.
function
.
empty
())
parameters
.
insert
(
StopReasonMapValue
(
std
::
string
(
"exceptionFunction"
),
wStringToString
(
frame
.
function
)));
}
// getCurrentFrame
return
parameters
;
}
STDMETHODIMP
EventCallback
::
Exception
(
THIS_
__in
PEXCEPTION_RECORD64
Ex
,
__in
ULONG
FirstChance
)
{
// Report the exception as GBMI and set potential stop reason
const
ExtensionContext
::
StopReasonMap
parameters
=
exceptionParameters
(
*
Ex
,
FirstChance
);
std
::
ostringstream
str
;
formatGdbmiHash
(
str
,
parameters
);
ExtensionContext
::
instance
().
setStopReason
(
parameters
,
"exception"
);
ExtensionContext
::
instance
().
report
(
'E'
,
0
,
"exception"
,
"%s"
,
str
.
str
().
c_str
());
return
m_wrapped
?
m_wrapped
->
Exception
(
Ex
,
FirstChance
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
CreateThread
(
THIS_
__in
ULONG64
Handle
,
__in
ULONG64
DataOffset
,
__in
ULONG64
StartOffset
)
{
return
m_wrapped
?
m_wrapped
->
CreateThread
(
Handle
,
DataOffset
,
StartOffset
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
ExitThread
(
THIS_
__in
ULONG
ExitCode
)
{
return
m_wrapped
?
m_wrapped
->
ExitThread
(
ExitCode
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
CreateProcess
(
THIS_
__in
ULONG64
ImageFileHandle
,
__in
ULONG64
Handle
,
__in
ULONG64
BaseOffset
,
__in
ULONG
ModuleSize
,
__in_opt
PCSTR
ModuleName
,
__in_opt
PCSTR
ImageName
,
__in
ULONG
CheckSum
,
__in
ULONG
TimeDateStamp
,
__in
ULONG64
InitialThreadHandle
,
__in
ULONG64
ThreadDataOffset
,
__in
ULONG64
StartOffset
)
{
return
m_wrapped
?
m_wrapped
->
CreateProcess
(
ImageFileHandle
,
Handle
,
BaseOffset
,
ModuleSize
,
ModuleName
,
ImageName
,
CheckSum
,
TimeDateStamp
,
InitialThreadHandle
,
ThreadDataOffset
,
StartOffset
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
ExitProcess
(
THIS_
__in
ULONG
ExitCode
)
{
ExtensionContext
::
instance
().
report
(
'E'
,
0
,
eventContextC
,
"Process exited (%lu)"
,
ExitCode
);
dprintf
(
"%s ExitProcess %u
\n
"
,
creatorOutputPrefixC
,
ExitCode
);
return
m_wrapped
?
m_wrapped
->
ExitProcess
(
ExitCode
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
LoadModule
(
THIS_
__in
ULONG64
ImageFileHandle
,
__in
ULONG64
BaseOffset
,
__in
ULONG
ModuleSize
,
__in_opt
PCSTR
ModuleName
,
__in_opt
PCSTR
ImageName
,
__in
ULONG
CheckSum
,
__in
ULONG
TimeDateStamp
)
{
ExtensionContext
::
instance
().
report
(
'E'
,
0
,
moduleContextC
,
"L:%s:%s:0x%llx:0x%llx
\n
"
,
ModuleName
,
ImageName
,
BaseOffset
,
ModuleSize
);
return
m_wrapped
?
m_wrapped
->
LoadModule
(
ImageFileHandle
,
BaseOffset
,
ModuleSize
,
ModuleName
,
ImageName
,
CheckSum
,
TimeDateStamp
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
UnloadModule
(
THIS_
__in_opt
PCSTR
ImageBaseName
,
__in
ULONG64
BaseOffset
)
{
ExtensionContext
::
instance
().
report
(
'U'
,
0
,
moduleContextC
,
"U:%s
\n
"
,
ImageBaseName
);
return
m_wrapped
?
m_wrapped
->
UnloadModule
(
ImageBaseName
,
BaseOffset
)
:
S_OK
;
}
STDMETHODIMP
EventCallback
::
SystemError
(
THIS_
__in
ULONG
Error
,
__in
ULONG
Level
)
{
return
m_wrapped
?
m_wrapped
->
SystemError
(
Error
,
Level
)
:
S_OK
;
}