2 * Copyright 2022 Esme Povirk
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/mscvpdb.h"
30 #include "wine/debug.h"
31 #include "wine/heap.h"
33 #include "diasymreader_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(diasymreader
);
37 typedef struct SymWriter
{
38 ISymUnmanagedWriter5 iface
;
39 IPdbWriter IPdbWriter_iface
;
41 CRITICAL_SECTION lock
;
45 WCHAR pdb_filename
[MAX_PATH
];
48 typedef struct SymDocumentWriter
{
49 ISymUnmanagedDocumentWriter iface
;
53 static inline SymWriter
*impl_from_ISymUnmanagedWriter5(ISymUnmanagedWriter5
*iface
)
55 return CONTAINING_RECORD(iface
, SymWriter
, iface
);
58 static inline SymWriter
*impl_from_IPdbWriter(IPdbWriter
*iface
)
60 return CONTAINING_RECORD(iface
, SymWriter
, IPdbWriter_iface
);
63 static inline SymDocumentWriter
*impl_from_ISymUnmanagedDocumentWriter(ISymUnmanagedDocumentWriter
*iface
)
65 return CONTAINING_RECORD(iface
, SymDocumentWriter
, iface
);
68 static HRESULT WINAPI
SymDocumentWriter_QueryInterface(ISymUnmanagedDocumentWriter
*iface
, REFIID iid
,
71 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
73 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
75 if (IsEqualIID(&IID_IUnknown
, iid
) ||
76 IsEqualIID(&IID_ISymUnmanagedDocumentWriter
, iid
))
82 WARN("unknown interface %s\n", debugstr_guid(iid
));
87 IUnknown_AddRef((IUnknown
*)*ppv
);
91 static ULONG WINAPI
SymDocumentWriter_AddRef(ISymUnmanagedDocumentWriter
*iface
)
93 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
94 ULONG ref
= InterlockedIncrement(&This
->ref
);
96 TRACE("(%p) refcount=%lu\n", iface
, ref
);
101 static ULONG WINAPI
SymDocumentWriter_Release(ISymUnmanagedDocumentWriter
*iface
)
103 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
104 ULONG ref
= InterlockedDecrement(&This
->ref
);
106 TRACE("(%p) refcount=%lu\n", iface
, ref
);
116 static HRESULT WINAPI
SymDocumentWriter_SetSource(ISymUnmanagedDocumentWriter
*iface
, ULONG32 sourceSize
,
119 FIXME("(%p,%u,%p)\n", iface
, sourceSize
, source
);
123 static HRESULT WINAPI
SymDocumentWriter_SetChecksum(ISymUnmanagedDocumentWriter
*iface
, GUID algorithmID
,
124 ULONG32 checkSumSize
, BYTE checkSum
[])
126 FIXME("(%p,%s,%u,%p)\n", iface
, debugstr_guid(&algorithmID
), checkSumSize
, checkSum
);
130 static const ISymUnmanagedDocumentWriterVtbl SymDocumentWriter_Vtbl
= {
131 SymDocumentWriter_QueryInterface
,
132 SymDocumentWriter_AddRef
,
133 SymDocumentWriter_Release
,
134 SymDocumentWriter_SetSource
,
135 SymDocumentWriter_SetChecksum
138 static HRESULT WINAPI
SymWriter_QueryInterface(ISymUnmanagedWriter5
*iface
, REFIID iid
,
141 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
143 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
145 if (IsEqualIID(&IID_IUnknown
, iid
) ||
146 IsEqualIID(&IID_ISymUnmanagedWriter
, iid
) ||
147 IsEqualIID(&IID_ISymUnmanagedWriter2
, iid
) ||
148 IsEqualIID(&IID_ISymUnmanagedWriter3
, iid
) ||
149 IsEqualIID(&IID_ISymUnmanagedWriter4
, iid
) ||
150 IsEqualIID(&IID_ISymUnmanagedWriter5
, iid
))
154 else if (IsEqualIID(&IID_IPdbWriter
, iid
))
156 *ppv
= &This
->IPdbWriter_iface
;
160 WARN("unknown interface %s\n", debugstr_guid(iid
));
162 return E_NOINTERFACE
;
165 IUnknown_AddRef((IUnknown
*)*ppv
);
169 static ULONG WINAPI
SymWriter_AddRef(ISymUnmanagedWriter5
*iface
)
171 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
172 ULONG ref
= InterlockedIncrement(&This
->ref
);
174 TRACE("(%p) refcount=%lu\n", iface
, ref
);
179 static ULONG WINAPI
SymWriter_Release(ISymUnmanagedWriter5
*iface
)
181 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
182 ULONG ref
= InterlockedDecrement(&This
->ref
);
184 TRACE("(%p) refcount=%lu\n", iface
, ref
);
188 This
->lock
.DebugInfo
->Spare
[0] = 0;
189 DeleteCriticalSection(&This
->lock
);
196 static HRESULT WINAPI
SymWriter_DefineDocument(ISymUnmanagedWriter5
*iface
, const WCHAR
*url
,
197 const GUID
*language
, const GUID
*languageVendor
, const GUID
*documentType
,
198 ISymUnmanagedDocumentWriter
** pRetVal
)
200 SymDocumentWriter
*result
;
202 FIXME("(%p,%s,%s,%s,%s,%p)\n", iface
, debugstr_w(url
), debugstr_guid(language
),
203 debugstr_guid(languageVendor
), debugstr_guid(documentType
), pRetVal
);
208 result
= heap_alloc(sizeof(*result
));
210 return E_OUTOFMEMORY
;
212 result
->iface
.lpVtbl
= &SymDocumentWriter_Vtbl
;
214 *pRetVal
= &result
->iface
;
219 static HRESULT WINAPI
SymWriter_SetUserEntryPoint(ISymUnmanagedWriter5
*iface
, mdMethodDef entryMethod
)
221 FIXME("(%p,0x%x)\n", iface
, entryMethod
);
225 static HRESULT WINAPI
SymWriter_OpenMethod(ISymUnmanagedWriter5
*iface
, mdMethodDef method
)
227 FIXME("(%p,0x%x)\n", iface
, method
);
231 static HRESULT WINAPI
SymWriter_CloseMethod(ISymUnmanagedWriter5
*iface
)
233 FIXME("(%p)\n", iface
);
237 static HRESULT WINAPI
SymWriter_OpenScope(ISymUnmanagedWriter5
*iface
, ULONG32 startOffset
,
240 FIXME("(%p,%u,%p)\n", iface
, startOffset
, pRetVal
);
241 *pRetVal
= 0xdeadbeef;
245 static HRESULT WINAPI
SymWriter_CloseScope(ISymUnmanagedWriter5
*iface
, ULONG32 endOffset
)
247 FIXME("(%p,%u)\n", iface
, endOffset
);
251 static HRESULT WINAPI
SymWriter_SetScopeRange(ISymUnmanagedWriter5
*iface
, ULONG32 scopeID
, ULONG32 startOffset
,
254 FIXME("(%p,%u,%u,%u)\n", iface
, scopeID
, startOffset
, endOffset
);
258 static HRESULT WINAPI
SymWriter_DefineLocalVariable(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
259 ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
260 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
, ULONG32 startOffset
, ULONG32 endOffset
)
262 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, cSig
, addrKind
);
266 static HRESULT WINAPI
SymWriter_DefineParameter(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
267 ULONG32 attributes
, ULONG32 sequence
, ULONG32 addrKind
,
268 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
270 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, sequence
, addrKind
);
274 static HRESULT WINAPI
SymWriter_DefineField(ISymUnmanagedWriter5
*iface
, mdTypeDef parent
,
275 const WCHAR
*name
, ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
276 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
278 FIXME("(%p,0x%x,%s,0x%x,%u,%u)\n", iface
, parent
, debugstr_w(name
), attributes
, cSig
, addrKind
);
282 static HRESULT WINAPI
SymWriter_DefineGlobalVariable(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
283 ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
284 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
286 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, cSig
, addrKind
);
290 static HRESULT WINAPI
SymWriter_Close(ISymUnmanagedWriter5
*iface
)
292 FIXME("(%p)\n", iface
);
296 static HRESULT WINAPI
SymWriter_SetSymAttributes(ISymUnmanagedWriter5
*iface
, mdToken parent
,
297 const WCHAR
*name
, ULONG32 cData
, unsigned char data
[])
299 FIXME("(%p,0x%x,%s,%u)\n", iface
, parent
, debugstr_w(name
), cData
);
303 static HRESULT WINAPI
SymWriter_OpenNamespace(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
)
305 FIXME("(%p,%s)\n", iface
, debugstr_w(name
));
309 static HRESULT WINAPI
SymWriter_CloseNamespace(ISymUnmanagedWriter5
*iface
)
311 FIXME("(%p)\n", iface
);
315 static HRESULT WINAPI
SymWriter_UsingNamespace(ISymUnmanagedWriter5
*iface
, const WCHAR
*fullName
)
317 FIXME("(%p,%s)\n", iface
, debugstr_w(fullName
));
321 static HRESULT WINAPI
SymWriter_SetMethodSourceRange(ISymUnmanagedWriter5
*iface
, ISymUnmanagedDocumentWriter
*startDoc
,
322 ULONG32 startLine
, ULONG32 startColumn
, ISymUnmanagedDocumentWriter
*endDoc
, ULONG32 endLine
, ULONG32 endColumn
)
324 FIXME("(%p,%p,%u,%u,%p,%u,%u)\n", iface
, startDoc
, startLine
, startColumn
, endDoc
, endLine
, endColumn
);
328 static HRESULT WINAPI
SymWriter_Initialize(ISymUnmanagedWriter5
*iface
, IUnknown
*emitter
, const WCHAR
*filename
,
329 IStream
*pIStream
, BOOL fFullBuild
)
331 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
333 FIXME("(%p,%p,%s,%p,%u)\n", iface
, emitter
, debugstr_w(filename
), pIStream
, fFullBuild
);
335 EnterCriticalSection(&This
->lock
);
338 wcsncpy_s(This
->pdb_filename
, MAX_PATH
, filename
, _TRUNCATE
);
340 This
->pdb_timestamp
= _time32(NULL
);
342 LeaveCriticalSection(&This
->lock
);
347 static HRESULT WINAPI
SymWriter_GetDebugInfo(ISymUnmanagedWriter5
*iface
, IMAGE_DEBUG_DIRECTORY
*pIDD
, DWORD cData
,
348 DWORD
*pcData
, BYTE data
[])
350 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
351 DWORD name_length
, data_size
;
352 OMFSignatureRSDS
*rsds_data
= (OMFSignatureRSDS
*)data
;
354 TRACE("(%p,%p,%lu,%p,%p)\n", iface
, pIDD
, cData
, pcData
, data
);
356 EnterCriticalSection(&This
->lock
);
358 name_length
= WideCharToMultiByte(CP_UTF8
, 0, This
->pdb_filename
, -1, NULL
, 0, NULL
, NULL
);
359 data_size
= FIELD_OFFSET(OMFSignatureRSDS
, name
) + name_length
;
365 pIDD
->Characteristics
= 0;
366 pIDD
->MajorVersion
= 0;
367 pIDD
->MinorVersion
= 0;
368 pIDD
->Type
= IMAGE_DEBUG_TYPE_CODEVIEW
;
369 pIDD
->SizeOfData
= data_size
;
374 if (data_size
> cData
)
376 LeaveCriticalSection(&This
->lock
);
377 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
380 memcpy(rsds_data
->Signature
, "RSDS", 4);
381 rsds_data
->guid
= This
->pdb_guid
;
382 rsds_data
->age
= This
->pdb_age
;
383 WideCharToMultiByte(CP_UTF8
, 0, This
->pdb_filename
, -1, rsds_data
->name
, name_length
, NULL
, NULL
);
386 LeaveCriticalSection(&This
->lock
);
391 static HRESULT WINAPI
SymWriter_DefineSequencePoints(ISymUnmanagedWriter5
*iface
, ISymUnmanagedDocumentWriter
*document
,
392 ULONG32 spCount
, ULONG32 offsets
[], ULONG32 lines
[], ULONG32 columns
[], ULONG32 endLines
[], ULONG32 endColumns
[])
394 FIXME("(%p,%p,%u)\n", iface
, document
, spCount
);
398 static HRESULT WINAPI
SymWriter_RemapToken(ISymUnmanagedWriter5
*iface
, mdToken oldToken
, mdToken newToken
)
400 FIXME("(%p,0x%x,0x%x)\n", iface
, oldToken
, newToken
);
404 static HRESULT WINAPI
SymWriter_Initialize2(ISymUnmanagedWriter5
*iface
, IUnknown
*emitter
, const WCHAR
*tempFilename
,
405 IStream
*pIStream
, BOOL fFullBuild
, const WCHAR
*finalFilename
)
407 FIXME("(%p,%p,%s,%p,%u,%s)\n", iface
, emitter
, debugstr_w(tempFilename
), pIStream
, fFullBuild
, debugstr_w(finalFilename
));
411 static HRESULT WINAPI
SymWriter_DefineConstant(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, VARIANT value
, ULONG32 cSig
,
412 unsigned char signature
[])
414 FIXME("(%p,%s,%s,%u,%p)\n", iface
, debugstr_w(name
), debugstr_variant(&value
), cSig
, signature
);
418 static HRESULT WINAPI
SymWriter_Abort(ISymUnmanagedWriter5
*iface
)
420 FIXME("(%p)\n", iface
);
424 static HRESULT WINAPI
SymWriter_DefineLocalVariable2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, ULONG32 attributes
,
425 mdSignature sigToken
, ULONG32 addrKind
, ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
,
426 ULONG32 startOffset
, ULONG32 endOffset
)
428 FIXME("(%p,%s,0x%x,0x%x,%u)\n", iface
, debugstr_w(name
), attributes
, sigToken
, addrKind
);
432 static HRESULT WINAPI
SymWriter_DefineGlobalVariable2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, ULONG32 attributes
,
433 mdSignature sigToken
, ULONG32 addrKind
, ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
435 FIXME("(%p,%s,0x%x,0x%x,%u)\n", iface
, debugstr_w(name
), attributes
, sigToken
, addrKind
);
439 static HRESULT WINAPI
SymWriter_DefineConstant2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, VARIANT value
, mdSignature sigToken
)
441 FIXME("(%p,%s,%s,0x%x)\n", iface
, debugstr_w(name
), debugstr_variant(&value
), sigToken
);
445 static HRESULT WINAPI
SymWriter_OpenMethod2(ISymUnmanagedWriter5
*iface
, mdMethodDef method
, ULONG32 isect
, ULONG32 offset
)
447 FIXME("(%p,0x%x,%u,%u)\n", iface
, method
, isect
, offset
);
451 static HRESULT WINAPI
SymWriter_Commit(ISymUnmanagedWriter5
*iface
)
453 FIXME("(%p)\n", iface
);
457 static HRESULT WINAPI
SymWriter_GetDebugInfoWithPadding(ISymUnmanagedWriter5
*iface
, IMAGE_DEBUG_DIRECTORY
*pIDD
, DWORD cbData
,
458 DWORD
* pcData
, BYTE data
[])
460 FIXME("(%p,%p,%lu,%p,%p)\n", iface
, pIDD
, cbData
, pcData
, data
);
464 static HRESULT WINAPI
SymWriter_OpenMapTokensToSourceSpans(ISymUnmanagedWriter5
*iface
)
466 FIXME("(%p)\n", iface
);
470 static HRESULT WINAPI
SymWriter_CloseMapTokensToSourceSpans(ISymUnmanagedWriter5
*iface
)
472 FIXME("(%p)\n", iface
);
476 static HRESULT WINAPI
SymWriter_MapTokenToSourceSpan(ISymUnmanagedWriter5
*iface
, mdToken token
, ISymUnmanagedDocumentWriter
* document
,
477 ULONG32 line
, ULONG32 column
, ULONG32 endLine
, ULONG32 endColumn
)
479 FIXME("(%p,%x,%p,%u,%u,%u,%u)\n", iface
, token
, document
, line
, column
, endLine
, endColumn
);
484 static const ISymUnmanagedWriter5Vtbl SymWriter_Vtbl
= {
485 SymWriter_QueryInterface
,
488 SymWriter_DefineDocument
,
489 SymWriter_SetUserEntryPoint
,
490 SymWriter_OpenMethod
,
491 SymWriter_CloseMethod
,
493 SymWriter_CloseScope
,
494 SymWriter_SetScopeRange
,
495 SymWriter_DefineLocalVariable
,
496 SymWriter_DefineParameter
,
497 SymWriter_DefineField
,
498 SymWriter_DefineGlobalVariable
,
500 SymWriter_SetSymAttributes
,
501 SymWriter_OpenNamespace
,
502 SymWriter_CloseNamespace
,
503 SymWriter_UsingNamespace
,
504 SymWriter_SetMethodSourceRange
,
505 SymWriter_Initialize
,
506 SymWriter_GetDebugInfo
,
507 SymWriter_DefineSequencePoints
,
508 SymWriter_RemapToken
,
509 SymWriter_Initialize2
,
510 SymWriter_DefineConstant
,
512 SymWriter_DefineLocalVariable2
,
513 SymWriter_DefineGlobalVariable2
,
514 SymWriter_DefineConstant2
,
515 SymWriter_OpenMethod2
,
517 SymWriter_GetDebugInfoWithPadding
,
518 SymWriter_OpenMapTokensToSourceSpans
,
519 SymWriter_CloseMapTokensToSourceSpans
,
520 SymWriter_MapTokenToSourceSpan
523 static HRESULT WINAPI
SymWriter_PdbWriter_QueryInterface(IPdbWriter
*iface
, REFIID iid
, void **ppv
)
525 SymWriter
*This
= impl_from_IPdbWriter(iface
);
526 return ISymUnmanagedWriter5_QueryInterface(&This
->iface
, iid
, ppv
);
529 static ULONG WINAPI
SymWriter_PdbWriter_AddRef(IPdbWriter
*iface
)
531 SymWriter
*This
= impl_from_IPdbWriter(iface
);
532 return ISymUnmanagedWriter5_AddRef(&This
->iface
);
535 static ULONG WINAPI
SymWriter_PdbWriter_Release(IPdbWriter
*iface
)
537 SymWriter
*This
= impl_from_IPdbWriter(iface
);
538 return ISymUnmanagedWriter5_Release(&This
->iface
);
541 static HRESULT WINAPI
SymWriter_SetPath(IPdbWriter
*iface
, const WCHAR
*fullpath
, IStream
*stream
, BOOL fullbuild
)
543 FIXME("(%p,%s,%p,%u)\n", iface
, debugstr_w(fullpath
), stream
, fullbuild
);
547 static HRESULT WINAPI
SymWriter_OpenMod(IPdbWriter
*iface
, const WCHAR
*modulename
, const WCHAR
*fullpath
)
549 FIXME("(%p,%s,%s)\n", iface
, debugstr_w(modulename
), debugstr_w(fullpath
));
553 static HRESULT WINAPI
SymWriter_CloseMod(IPdbWriter
*iface
)
555 FIXME("(%p)\n", iface
);
559 static HRESULT WINAPI
SymWriter_GetPath(IPdbWriter
*iface
, DWORD ccData
, DWORD
*pccData
, WCHAR
*path
)
561 FIXME("(%p,%lu,%p,%p)\n", iface
, ccData
, pccData
, path
);
565 static HRESULT WINAPI
SymWriter_GetSignatureAge(IPdbWriter
*iface
, DWORD
*timestamp
, DWORD
*age
)
567 SymWriter
*This
= impl_from_IPdbWriter(iface
);
569 TRACE("(%p,%p,%p)\n", This
, timestamp
, age
);
571 EnterCriticalSection(&This
->lock
);
574 *timestamp
= This
->pdb_timestamp
;
576 *age
= This
->pdb_age
;
578 LeaveCriticalSection(&This
->lock
);
583 static const IPdbWriterVtbl SymWriter_PdbWriter_Vtbl
= {
584 SymWriter_PdbWriter_QueryInterface
,
585 SymWriter_PdbWriter_AddRef
,
586 SymWriter_PdbWriter_Release
,
591 SymWriter_GetSignatureAge
594 HRESULT
SymWriter_CreateInstance(REFIID iid
, void **ppv
)
599 This
= heap_alloc(sizeof(*This
));
601 return E_OUTOFMEMORY
;
603 This
->iface
.lpVtbl
= &SymWriter_Vtbl
;
604 This
->IPdbWriter_iface
.lpVtbl
= &SymWriter_PdbWriter_Vtbl
;
606 InitializeCriticalSection(&This
->lock
);
607 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": SymWriter.lock");
608 UuidCreate(&This
->pdb_guid
);
610 This
->pdb_filename
[0] = 0;
612 hr
= IUnknown_QueryInterface(&This
->iface
, iid
, ppv
);
614 ISymUnmanagedWriter5_Release(&This
->iface
);