Actually there is no need to use DllRegisterServer or CLSCTX_INPROC_SERVER
MSdia can be loaded "unregistered". The routine i used for this is:
Proc GetMSDiaLibrary:
Arguments @SzOutput, @phDiaLib
Uses esi, edi, ecx, ebx, edx
call InitializeDiaInterface {U$ "msdia120.dll" 0}, CLSID_DiaSourceAlt, IID_IDiaDataSource, g_pDiaDataSource, D@phDiaLib
If eax <> &S_OK
xor eax eax
ExitP
End_If
icall DIA_LOADDATA_FROMPDB D$g_pDiaDataSource, D@SzOutput
.If eax <> &S_OK
call TryLoadingSymbolForExe D@SzOutput
On eax = &FALSE, EXitP
.End_If
icall DIA_OPENSESSION D$g_pDiaDataSource, g_pDiaSession
If eax <> &S_OK
call ReportWinError {'DiaDataSource: OpenSession' 0} ; show cause of failure
xor eax eax
ExitP
End_If
icall DIA_SESSION_GET_GLOBALSCOPE D$g_pDiaSession, g_pDiaSymbol
If eax <> &S_OK
call ReportWinError {'DiaSession: GlobalScope' 0} ; show cause of failure
xor eax eax
Else
mov eax &TRUE
End_If
EndP
; Initialize an object not registered
; http://msdn.microsoft.com/en-us/library/windows/desktop/ms680760%28v=vs.85%29.aspx
Proc InitializeDiaInterface:
Arguments @lpLibFileName, @pClsid, @pIID, @pOut, @phDiaLib
Local @hpfDllGetClassObject, @ppv
Uses esi, edi, ecx, ebx, edx
call 'KERNEL32.LoadLibraryExW' D@lpLibFileName, 0, &LOAD_WITH_ALTERED_SEARCH_PATH
.If eax = 0
call ReportWinError {'LoadLibraryExW' 0} ; show cause of failure
mov eax &E_FAIL
ExitP
.End_If
mov edi D@phDiaLib | mov D$edi eax
call 'KERNEL32.GetProcAddress' eax, {B$ "DllGetClassObject", 0}
.If eax = 0
call ReportWinError {'msdia120.dll' 0} ; show cause of failure
mov eax &E_FAIL
ExitP
.End_If
mov D@hpfDllGetClassObject eax
lea ecx D@ppv | mov D$ecx 0
call D@hpfDllGetClassObject D@pClsid, IID_IClassFactory, ecx
mov esi eax
.If eax = &S_OK ; points to CreateInstance
icall ICLASS_FACTORY_CREATE_INSTANCE D@ppv, 0, D@pIID, D@pOut
mov esi eax
call ReleaseInterface D@ppv
.End_If
mov eax esi
EndP
The function is called like this:
[HeaderSaveFilter: U$ 0 #&MAX_PATH] ; The path and name of the pdb file (In unicode string)
[hDiaLib: D$ 0] ; A variable that is used to store the msdia120.dll handle
call GetMSDiaLibrary HeaderSaveFilter, hDiaLib
MSdia contains as an export this function DllGetClassObject, which is used to load unregistered classes
http://msdn.microsoft.com/en-us/library/windows/desktop/ms680760%28v=vs.85%29.aspxSo, if a dll contains this function, you can simply use this routines i did, to load it without registering the interface. Not sure what are other dlls that have this external Api, but for what i saw, whenever a dll have it (and uses classes) you can use it, and therefore, you can put the dll in whatever folder to avoid relying on the system folder. This is particular good if you have 2 dlls containing tteh same (or similar) interfaces, but you want to use the most recent one on your own directory and not the one that is provided in system32 directory
For loading the symbols from a exe/dll, You example may not work if you don´t set the proper servers like this:
Proc TryLoadingSymbolForExe:
Arguments @SzOutput
Local @callback
icall DIA_LOADDATA_FOREXE D$g_pDiaDataSource, D@SzOutput, &NULL, &NULL
If eax = &S_OK
mov eax &TRUE
ExitP
End_If
icall DIA_LOADDATA_FOREXE D$g_pDiaDataSource, D@SzOutput, {U$ "srv*C:\temp*http://srv.symbolsource.org/pdb/Public;srv*C:\temp*http://symbols.mozilla.org/firefox;srv*C:\temp*http://referencesource.microsoft.com/symbols;srv*C:\temp*http://msdl.microsoft.com/download/symbols", 0}, &NULL
..If eax <> &S_OK
call ReportWinError {'DiaDataSource: LoadDataFromPdb' 0} ; show cause of failure
xor eax eax
ExitP
..End_If
mov eax &TRUE
EndP
The 3rd parameter of the loadDataForExe function (the 2nd one in your function) is used to check where to load the pdb. If it is NULL, the function tries to load the pdb on the same directory as in your main file. If it can´t find it, it returns something else then S_OK. Then you can simply see if on the proper servers there is a pdb to be loaded. (I presume you did that on LireEr_Com ?)
Since i´m testing the loaddataforexe, the downloaded pdbs are saved on "C:\temp". Later i´ll make some routines to allow the user to choose the directory he wants for the downloaded files. ANd also some routines to check if the loaded pdb matches to the exe/dll (Through it´s age and signature). If it don´t match there is a way to force a match, simply resetting it´s age, as long the signature is the same.
Also, it is important that symsrv.dll be at the same directory as your msdia120.dll. Otherwise it may not work as expected.
For the syntax used to load the pdb/dbg from the servers (ms or other), the correct is:
srv*C:\temp*http://msdl.microsoft.com/download/symbols
that means:
srv = the token to activate the download
* = a separator. Must be used
c:\temp = the directory for the downloaded files
* = a separator. Must be used
http://msdl.microsoft.com/download/symbols = the server from where you want to dl the pdb
Also. To use more then 1 servers to be searched and dwonloaded, you must separate the syntaxes with a ";" token, like this:
C:\temp*http://referencesource.microsoft.com/symbols
;srv*C:\temp*http://msdl.microsoft.com/download/symbols
And the whole string MUST be in Unicode format. This is why i put ' "U$" datatype in my code and not a "B$" in icall DIA_LOADDATA_FOREXE. In RosAsm the "U$" token refers to a Unicode String