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"
32 #include "diasymreader_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(diasymreader
);
36 typedef struct SymWriter
{
37 ISymUnmanagedWriter5 iface
;
38 IPdbWriter IPdbWriter_iface
;
40 CRITICAL_SECTION lock
;
44 WCHAR pdb_filename
[MAX_PATH
];
47 typedef struct SymDocumentWriter
{
48 ISymUnmanagedDocumentWriter iface
;
52 static inline SymWriter
*impl_from_ISymUnmanagedWriter5(ISymUnmanagedWriter5
*iface
)
54 return CONTAINING_RECORD(iface
, SymWriter
, iface
);
57 static inline SymWriter
*impl_from_IPdbWriter(IPdbWriter
*iface
)
59 return CONTAINING_RECORD(iface
, SymWriter
, IPdbWriter_iface
);
62 static inline SymDocumentWriter
*impl_from_ISymUnmanagedDocumentWriter(ISymUnmanagedDocumentWriter
*iface
)
64 return CONTAINING_RECORD(iface
, SymDocumentWriter
, iface
);
67 static HRESULT WINAPI
SymDocumentWriter_QueryInterface(ISymUnmanagedDocumentWriter
*iface
, REFIID iid
,
70 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
72 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
74 if (IsEqualIID(&IID_IUnknown
, iid
) ||
75 IsEqualIID(&IID_ISymUnmanagedDocumentWriter
, iid
))
81 WARN("unknown interface %s\n", debugstr_guid(iid
));
86 IUnknown_AddRef((IUnknown
*)*ppv
);
90 static ULONG WINAPI
SymDocumentWriter_AddRef(ISymUnmanagedDocumentWriter
*iface
)
92 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
93 ULONG ref
= InterlockedIncrement(&This
->ref
);
95 TRACE("(%p) refcount=%lu\n", iface
, ref
);
100 static ULONG WINAPI
SymDocumentWriter_Release(ISymUnmanagedDocumentWriter
*iface
)
102 SymDocumentWriter
*This
= impl_from_ISymUnmanagedDocumentWriter(iface
);
103 ULONG ref
= InterlockedDecrement(&This
->ref
);
105 TRACE("(%p) refcount=%lu\n", iface
, ref
);
115 static HRESULT WINAPI
SymDocumentWriter_SetSource(ISymUnmanagedDocumentWriter
*iface
, ULONG32 sourceSize
,
118 FIXME("(%p,%u,%p)\n", iface
, sourceSize
, source
);
122 static HRESULT WINAPI
SymDocumentWriter_SetChecksum(ISymUnmanagedDocumentWriter
*iface
, GUID algorithmID
,
123 ULONG32 checkSumSize
, BYTE checkSum
[])
125 FIXME("(%p,%s,%u,%p)\n", iface
, debugstr_guid(&algorithmID
), checkSumSize
, checkSum
);
129 static const ISymUnmanagedDocumentWriterVtbl SymDocumentWriter_Vtbl
= {
130 SymDocumentWriter_QueryInterface
,
131 SymDocumentWriter_AddRef
,
132 SymDocumentWriter_Release
,
133 SymDocumentWriter_SetSource
,
134 SymDocumentWriter_SetChecksum
137 static HRESULT WINAPI
SymWriter_QueryInterface(ISymUnmanagedWriter5
*iface
, REFIID iid
,
140 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
142 TRACE("(%p,%s,%p)\n", iface
, debugstr_guid(iid
), ppv
);
144 if (IsEqualIID(&IID_IUnknown
, iid
) ||
145 IsEqualIID(&IID_ISymUnmanagedWriter
, iid
) ||
146 IsEqualIID(&IID_ISymUnmanagedWriter2
, iid
) ||
147 IsEqualIID(&IID_ISymUnmanagedWriter3
, iid
) ||
148 IsEqualIID(&IID_ISymUnmanagedWriter4
, iid
) ||
149 IsEqualIID(&IID_ISymUnmanagedWriter5
, iid
))
153 else if (IsEqualIID(&IID_IPdbWriter
, iid
))
155 *ppv
= &This
->IPdbWriter_iface
;
159 WARN("unknown interface %s\n", debugstr_guid(iid
));
161 return E_NOINTERFACE
;
164 IUnknown_AddRef((IUnknown
*)*ppv
);
168 static ULONG WINAPI
SymWriter_AddRef(ISymUnmanagedWriter5
*iface
)
170 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
171 ULONG ref
= InterlockedIncrement(&This
->ref
);
173 TRACE("(%p) refcount=%lu\n", iface
, ref
);
178 static ULONG WINAPI
SymWriter_Release(ISymUnmanagedWriter5
*iface
)
180 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
181 ULONG ref
= InterlockedDecrement(&This
->ref
);
183 TRACE("(%p) refcount=%lu\n", iface
, ref
);
187 This
->lock
.DebugInfo
->Spare
[0] = 0;
188 DeleteCriticalSection(&This
->lock
);
195 static HRESULT WINAPI
SymWriter_DefineDocument(ISymUnmanagedWriter5
*iface
, const WCHAR
*url
,
196 const GUID
*language
, const GUID
*languageVendor
, const GUID
*documentType
,
197 ISymUnmanagedDocumentWriter
** pRetVal
)
199 SymDocumentWriter
*result
;
201 FIXME("(%p,%s,%s,%s,%s,%p)\n", iface
, debugstr_w(url
), debugstr_guid(language
),
202 debugstr_guid(languageVendor
), debugstr_guid(documentType
), pRetVal
);
207 result
= malloc(sizeof(*result
));
209 return E_OUTOFMEMORY
;
211 result
->iface
.lpVtbl
= &SymDocumentWriter_Vtbl
;
213 *pRetVal
= &result
->iface
;
218 static HRESULT WINAPI
SymWriter_SetUserEntryPoint(ISymUnmanagedWriter5
*iface
, mdMethodDef entryMethod
)
220 FIXME("(%p,0x%x)\n", iface
, entryMethod
);
224 static HRESULT WINAPI
SymWriter_OpenMethod(ISymUnmanagedWriter5
*iface
, mdMethodDef method
)
226 FIXME("(%p,0x%x)\n", iface
, method
);
230 static HRESULT WINAPI
SymWriter_CloseMethod(ISymUnmanagedWriter5
*iface
)
232 FIXME("(%p)\n", iface
);
236 static HRESULT WINAPI
SymWriter_OpenScope(ISymUnmanagedWriter5
*iface
, ULONG32 startOffset
,
239 FIXME("(%p,%u,%p)\n", iface
, startOffset
, pRetVal
);
240 *pRetVal
= 0xdeadbeef;
244 static HRESULT WINAPI
SymWriter_CloseScope(ISymUnmanagedWriter5
*iface
, ULONG32 endOffset
)
246 FIXME("(%p,%u)\n", iface
, endOffset
);
250 static HRESULT WINAPI
SymWriter_SetScopeRange(ISymUnmanagedWriter5
*iface
, ULONG32 scopeID
, ULONG32 startOffset
,
253 FIXME("(%p,%u,%u,%u)\n", iface
, scopeID
, startOffset
, endOffset
);
257 static HRESULT WINAPI
SymWriter_DefineLocalVariable(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
258 ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
259 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
, ULONG32 startOffset
, ULONG32 endOffset
)
261 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, cSig
, addrKind
);
265 static HRESULT WINAPI
SymWriter_DefineParameter(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
266 ULONG32 attributes
, ULONG32 sequence
, ULONG32 addrKind
,
267 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
269 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, sequence
, addrKind
);
273 static HRESULT WINAPI
SymWriter_DefineField(ISymUnmanagedWriter5
*iface
, mdTypeDef parent
,
274 const WCHAR
*name
, ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
275 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
277 FIXME("(%p,0x%x,%s,0x%x,%u,%u)\n", iface
, parent
, debugstr_w(name
), attributes
, cSig
, addrKind
);
281 static HRESULT WINAPI
SymWriter_DefineGlobalVariable(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
,
282 ULONG32 attributes
, ULONG32 cSig
, unsigned char signature
[], ULONG32 addrKind
,
283 ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
285 FIXME("(%p,%s,0x%x,%u,%u)\n", iface
, debugstr_w(name
), attributes
, cSig
, addrKind
);
289 static HRESULT WINAPI
SymWriter_Close(ISymUnmanagedWriter5
*iface
)
291 FIXME("(%p)\n", iface
);
295 static HRESULT WINAPI
SymWriter_SetSymAttributes(ISymUnmanagedWriter5
*iface
, mdToken parent
,
296 const WCHAR
*name
, ULONG32 cData
, unsigned char data
[])
298 FIXME("(%p,0x%x,%s,%u)\n", iface
, parent
, debugstr_w(name
), cData
);
302 static HRESULT WINAPI
SymWriter_OpenNamespace(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
)
304 FIXME("(%p,%s)\n", iface
, debugstr_w(name
));
308 static HRESULT WINAPI
SymWriter_CloseNamespace(ISymUnmanagedWriter5
*iface
)
310 FIXME("(%p)\n", iface
);
314 static HRESULT WINAPI
SymWriter_UsingNamespace(ISymUnmanagedWriter5
*iface
, const WCHAR
*fullName
)
316 FIXME("(%p,%s)\n", iface
, debugstr_w(fullName
));
320 static HRESULT WINAPI
SymWriter_SetMethodSourceRange(ISymUnmanagedWriter5
*iface
, ISymUnmanagedDocumentWriter
*startDoc
,
321 ULONG32 startLine
, ULONG32 startColumn
, ISymUnmanagedDocumentWriter
*endDoc
, ULONG32 endLine
, ULONG32 endColumn
)
323 FIXME("(%p,%p,%u,%u,%p,%u,%u)\n", iface
, startDoc
, startLine
, startColumn
, endDoc
, endLine
, endColumn
);
327 static HRESULT WINAPI
SymWriter_Initialize(ISymUnmanagedWriter5
*iface
, IUnknown
*emitter
, const WCHAR
*filename
,
328 IStream
*pIStream
, BOOL fFullBuild
)
330 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
332 FIXME("(%p,%p,%s,%p,%u)\n", iface
, emitter
, debugstr_w(filename
), pIStream
, fFullBuild
);
334 EnterCriticalSection(&This
->lock
);
337 wcsncpy_s(This
->pdb_filename
, MAX_PATH
, filename
, _TRUNCATE
);
339 This
->pdb_timestamp
= _time32(NULL
);
341 LeaveCriticalSection(&This
->lock
);
346 static HRESULT WINAPI
SymWriter_GetDebugInfo(ISymUnmanagedWriter5
*iface
, IMAGE_DEBUG_DIRECTORY
*pIDD
, DWORD cData
,
347 DWORD
*pcData
, BYTE data
[])
349 SymWriter
*This
= impl_from_ISymUnmanagedWriter5(iface
);
350 DWORD name_length
, data_size
;
351 OMFSignatureRSDS
*rsds_data
= (OMFSignatureRSDS
*)data
;
353 TRACE("(%p,%p,%lu,%p,%p)\n", iface
, pIDD
, cData
, pcData
, data
);
355 EnterCriticalSection(&This
->lock
);
357 name_length
= WideCharToMultiByte(CP_UTF8
, 0, This
->pdb_filename
, -1, NULL
, 0, NULL
, NULL
);
358 data_size
= FIELD_OFFSET(OMFSignatureRSDS
, name
) + name_length
;
364 pIDD
->Characteristics
= 0;
365 pIDD
->MajorVersion
= 0;
366 pIDD
->MinorVersion
= 0;
367 pIDD
->Type
= IMAGE_DEBUG_TYPE_CODEVIEW
;
368 pIDD
->SizeOfData
= data_size
;
373 if (data_size
> cData
)
375 LeaveCriticalSection(&This
->lock
);
376 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER
);
379 memcpy(rsds_data
->Signature
, "RSDS", 4);
380 rsds_data
->guid
= This
->pdb_guid
;
381 rsds_data
->age
= This
->pdb_age
;
382 WideCharToMultiByte(CP_UTF8
, 0, This
->pdb_filename
, -1, rsds_data
->name
, name_length
, NULL
, NULL
);
385 LeaveCriticalSection(&This
->lock
);
390 static HRESULT WINAPI
SymWriter_DefineSequencePoints(ISymUnmanagedWriter5
*iface
, ISymUnmanagedDocumentWriter
*document
,
391 ULONG32 spCount
, ULONG32 offsets
[], ULONG32 lines
[], ULONG32 columns
[], ULONG32 endLines
[], ULONG32 endColumns
[])
393 FIXME("(%p,%p,%u)\n", iface
, document
, spCount
);
397 static HRESULT WINAPI
SymWriter_RemapToken(ISymUnmanagedWriter5
*iface
, mdToken oldToken
, mdToken newToken
)
399 FIXME("(%p,0x%x,0x%x)\n", iface
, oldToken
, newToken
);
403 static HRESULT WINAPI
SymWriter_Initialize2(ISymUnmanagedWriter5
*iface
, IUnknown
*emitter
, const WCHAR
*tempFilename
,
404 IStream
*pIStream
, BOOL fFullBuild
, const WCHAR
*finalFilename
)
406 FIXME("(%p,%p,%s,%p,%u,%s)\n", iface
, emitter
, debugstr_w(tempFilename
), pIStream
, fFullBuild
, debugstr_w(finalFilename
));
410 static HRESULT WINAPI
SymWriter_DefineConstant(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, VARIANT value
, ULONG32 cSig
,
411 unsigned char signature
[])
413 FIXME("(%p,%s,%s,%u,%p)\n", iface
, debugstr_w(name
), debugstr_variant(&value
), cSig
, signature
);
417 static HRESULT WINAPI
SymWriter_Abort(ISymUnmanagedWriter5
*iface
)
419 FIXME("(%p)\n", iface
);
423 static HRESULT WINAPI
SymWriter_DefineLocalVariable2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, ULONG32 attributes
,
424 mdSignature sigToken
, ULONG32 addrKind
, ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
,
425 ULONG32 startOffset
, ULONG32 endOffset
)
427 FIXME("(%p,%s,0x%x,0x%x,%u)\n", iface
, debugstr_w(name
), attributes
, sigToken
, addrKind
);
431 static HRESULT WINAPI
SymWriter_DefineGlobalVariable2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, ULONG32 attributes
,
432 mdSignature sigToken
, ULONG32 addrKind
, ULONG32 addr1
, ULONG32 addr2
, ULONG32 addr3
)
434 FIXME("(%p,%s,0x%x,0x%x,%u)\n", iface
, debugstr_w(name
), attributes
, sigToken
, addrKind
);
438 static HRESULT WINAPI
SymWriter_DefineConstant2(ISymUnmanagedWriter5
*iface
, const WCHAR
*name
, VARIANT value
, mdSignature sigToken
)
440 FIXME("(%p,%s,%s,0x%x)\n", iface
, debugstr_w(name
), debugstr_variant(&value
), sigToken
);
444 static HRESULT WINAPI
SymWriter_OpenMethod2(ISymUnmanagedWriter5
*iface
, mdMethodDef method
, ULONG32 isect
, ULONG32 offset
)
446 FIXME("(%p,0x%x,%u,%u)\n", iface
, method
, isect
, offset
);
450 static HRESULT WINAPI
SymWriter_Commit(ISymUnmanagedWriter5
*iface
)
452 FIXME("(%p)\n", iface
);
456 static HRESULT WINAPI
SymWriter_GetDebugInfoWithPadding(ISymUnmanagedWriter5
*iface
, IMAGE_DEBUG_DIRECTORY
*pIDD
, DWORD cbData
,
457 DWORD
* pcData
, BYTE data
[])
459 FIXME("(%p,%p,%lu,%p,%p)\n", iface
, pIDD
, cbData
, pcData
, data
);
463 static HRESULT WINAPI
SymWriter_OpenMapTokensToSourceSpans(ISymUnmanagedWriter5
*iface
)
465 FIXME("(%p)\n", iface
);
469 static HRESULT WINAPI
SymWriter_CloseMapTokensToSourceSpans(ISymUnmanagedWriter5
*iface
)
471 FIXME("(%p)\n", iface
);
475 static HRESULT WINAPI
SymWriter_MapTokenToSourceSpan(ISymUnmanagedWriter5
*iface
, mdToken token
, ISymUnmanagedDocumentWriter
* document
,
476 ULONG32 line
, ULONG32 column
, ULONG32 endLine
, ULONG32 endColumn
)
478 FIXME("(%p,%x,%p,%u,%u,%u,%u)\n", iface
, token
, document
, line
, column
, endLine
, endColumn
);
483 static const ISymUnmanagedWriter5Vtbl SymWriter_Vtbl
= {
484 SymWriter_QueryInterface
,
487 SymWriter_DefineDocument
,
488 SymWriter_SetUserEntryPoint
,
489 SymWriter_OpenMethod
,
490 SymWriter_CloseMethod
,
492 SymWriter_CloseScope
,
493 SymWriter_SetScopeRange
,
494 SymWriter_DefineLocalVariable
,
495 SymWriter_DefineParameter
,
496 SymWriter_DefineField
,
497 SymWriter_DefineGlobalVariable
,
499 SymWriter_SetSymAttributes
,
500 SymWriter_OpenNamespace
,
501 SymWriter_CloseNamespace
,
502 SymWriter_UsingNamespace
,
503 SymWriter_SetMethodSourceRange
,
504 SymWriter_Initialize
,
505 SymWriter_GetDebugInfo
,
506 SymWriter_DefineSequencePoints
,
507 SymWriter_RemapToken
,
508 SymWriter_Initialize2
,
509 SymWriter_DefineConstant
,
511 SymWriter_DefineLocalVariable2
,
512 SymWriter_DefineGlobalVariable2
,
513 SymWriter_DefineConstant2
,
514 SymWriter_OpenMethod2
,
516 SymWriter_GetDebugInfoWithPadding
,
517 SymWriter_OpenMapTokensToSourceSpans
,
518 SymWriter_CloseMapTokensToSourceSpans
,
519 SymWriter_MapTokenToSourceSpan
522 static HRESULT WINAPI
SymWriter_PdbWriter_QueryInterface(IPdbWriter
*iface
, REFIID iid
, void **ppv
)
524 SymWriter
*This
= impl_from_IPdbWriter(iface
);
525 return ISymUnmanagedWriter5_QueryInterface(&This
->iface
, iid
, ppv
);
528 static ULONG WINAPI
SymWriter_PdbWriter_AddRef(IPdbWriter
*iface
)
530 SymWriter
*This
= impl_from_IPdbWriter(iface
);
531 return ISymUnmanagedWriter5_AddRef(&This
->iface
);
534 static ULONG WINAPI
SymWriter_PdbWriter_Release(IPdbWriter
*iface
)
536 SymWriter
*This
= impl_from_IPdbWriter(iface
);
537 return ISymUnmanagedWriter5_Release(&This
->iface
);
540 static HRESULT WINAPI
SymWriter_SetPath(IPdbWriter
*iface
, const WCHAR
*fullpath
, IStream
*stream
, BOOL fullbuild
)
542 FIXME("(%p,%s,%p,%u)\n", iface
, debugstr_w(fullpath
), stream
, fullbuild
);
546 static HRESULT WINAPI
SymWriter_OpenMod(IPdbWriter
*iface
, const WCHAR
*modulename
, const WCHAR
*fullpath
)
548 FIXME("(%p,%s,%s)\n", iface
, debugstr_w(modulename
), debugstr_w(fullpath
));
552 static HRESULT WINAPI
SymWriter_CloseMod(IPdbWriter
*iface
)
554 FIXME("(%p)\n", iface
);
558 static HRESULT WINAPI
SymWriter_GetPath(IPdbWriter
*iface
, DWORD ccData
, DWORD
*pccData
, WCHAR
*path
)
560 FIXME("(%p,%lu,%p,%p)\n", iface
, ccData
, pccData
, path
);
564 static HRESULT WINAPI
SymWriter_GetSignatureAge(IPdbWriter
*iface
, DWORD
*timestamp
, DWORD
*age
)
566 SymWriter
*This
= impl_from_IPdbWriter(iface
);
568 TRACE("(%p,%p,%p)\n", This
, timestamp
, age
);
570 EnterCriticalSection(&This
->lock
);
573 *timestamp
= This
->pdb_timestamp
;
575 *age
= This
->pdb_age
;
577 LeaveCriticalSection(&This
->lock
);
582 static const IPdbWriterVtbl SymWriter_PdbWriter_Vtbl
= {
583 SymWriter_PdbWriter_QueryInterface
,
584 SymWriter_PdbWriter_AddRef
,
585 SymWriter_PdbWriter_Release
,
590 SymWriter_GetSignatureAge
593 HRESULT
SymWriter_CreateInstance(REFIID iid
, void **ppv
)
598 This
= malloc(sizeof(*This
));
600 return E_OUTOFMEMORY
;
602 This
->iface
.lpVtbl
= &SymWriter_Vtbl
;
603 This
->IPdbWriter_iface
.lpVtbl
= &SymWriter_PdbWriter_Vtbl
;
605 InitializeCriticalSection(&This
->lock
);
606 This
->lock
.DebugInfo
->Spare
[0] = (DWORD_PTR
)(__FILE__
": SymWriter.lock");
607 UuidCreate(&This
->pdb_guid
);
609 This
->pdb_filename
[0] = 0;
611 hr
= IUnknown_QueryInterface(&This
->iface
, iid
, ppv
);
613 ISymUnmanagedWriter5_Release(&This
->iface
);