OLE/COM Object Viewer reports STG_E_FILENOTFOUND - c++

I have created simple COM DLL using ATL and have added "ATL Simple Object" after that. To be sure server is registering I have placed messagebox:
STDAPI DllRegisterServer(void)
{
MessageBoxA ( NULL, "Hello World!", "Test", MB_OK );
HRESULT hr = _AtlModule.DllRegisterServer();
return hr;
}
Registering does fine. I decided to look how this object looks with OLE-COM Object Viewer that is part of SDK. Viewer reports error:
"LoadTypelib'(c:\pr\ILight.dll) failed.
<No system message defined> STG_E_FILENOTFOUND ($800300002)
Does it means my COM dll corrupted? How to make VIewer to show my dll information?
P.S.
Project RC file contians:
"REGISTRY"
IDR_ILIGHT
HKCR{}
IDR_LIGHT
HKCR
{
AboutiLight.1 = s 'Light Class'
{
CLSID = s '{DBC53EA8-A51E-4374-B104-06A834273B0C}'
}
AboutiLight = s 'Light Class'
{
CurVer = s 'AboutiLight.1'
}
NoRemove CLSID
{
ForceRemove {DBC53EA8-A51E-4374-B104-06A834273B0C} = s 'Light Class'
{
ProgID = s 'AboutiLight.1'
VersionIndependentProgID = s 'AboutiLight'
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{1D9F859D-10FF-4827-A341-4A8B8E318A61}'
Version = s '1.0'
}
}
}
String table
String table
ID=IDS_PROJNAME Value=100 Caption ILight
Version
VS_VERSION_INFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEMASK 0x3fL
FILEFLAGS 0x0L
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN

After having received the same error (STG_E_FILENOTFOUND), and seeing Joe Willcoxson's comment about 64-bit and 32-bit, I was able to find a solution.
If you are using OleView.exe, the OLE/COM Object Viewer, there are actually two versions of it: 32-bit, and 64-bit. Ensure that you are launching with the proper version of OleView. The version in the base "BIN" folder of the SDK will be the 32-bit version. The "x64" folder will have the 64-bit version of the application, which is not fully compatible with older binaries and their typelibs (made in a 32-bit world).
On the other hand, if your new DLL is actively being compiled for x64, then it's highly likely 32-bit OleView will not be able to read the data properly, either.

1) Check to make sure that is the right path to your DLL.
2) Open the DLL itself from Visual Studio and check to be sure that a type library is embedded in the resources. If a typelib isn't found, add one.
3) If all that fails, did you register it under an administrator account/shell. If you call regsvr32.exe on it, make sure you are running with elevated privileges.

Related

Create a Direct3D12 Device fails with E_NoInterface

I'm trying to create a D3D12 device as specified in
https://msdn.microsoft.com/en-us/library/dn899120%28v=vs.85%29.aspx
I have a NVidia 670 gtx, Windows 10 preview build 9926, and last 10041 windows sdk.
I also have latest NVidia beta driver, system information for GeForce reports a DirectX12 runtime.
Calling
ID3D12Device* device;
HRESULT hr = D3D12CreateDevice(NULL, D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE,
D3D12_CREATE_DEVICE_FLAG::D3D12_CREATE_DEVICE_NONE,
D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0, D3D12_SDK_VERSION, __uuidof(ID3D12Device), (void**)&device);
Returns me a HRESULT with NOINTERFACE error code
Strangely calling:
ID3D12Object* device;
HRESULT hr = D3D12CreateDevice(NULL, D3D_DRIVER_TYPE::D3D_DRIVER_TYPE_HARDWARE,
D3D12_CREATE_DEVICE_FLAG::D3D12_CREATE_DEVICE_NONE,
D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0, D3D12_SDK_VERSION, __uuidof(ID3D12Object), (void**)&device);
returns me a valid object, but I'm not able to use QueryInterface to get a valid device object afterwards.
Please note I already tried using LoadLibrary/GetProcAddress instead of using d3d12 headers, which returns same error code.
You should always use the same OS and SDK Build, because APIs can change betweens builds. Because you use SDK for Build 10041, you should also update Windows 10 to the Build 10041. Open the Settings App, and search for a new Windows 10 Build and install it.

Compiling an MFC GUI application as a DLL in VS2012

Is it possible to compile an MFC GUI EXE project into a DLL and then execute this DLL application from another application?
My progress so far is:
I changed "Configuration properties | General | Configuration type" to DLL
I added an exported function creating and running the application using this code:
theApp.m_hInstance = pModuleState->m_hCurrentInstanceHandle;
theApp.InitInstance();
theApp.Run();
I added code to DLLMain to initialize module state:
if (dwReason == DLL_PROCESS_ATTACH)
{
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
pModuleState->m_hCurrentInstanceHandle = hInstance;
pModuleState->m_hCurrentResourceHandle = hInstance;
I created a console application that loads the DLL and calls the function creating and running the DLL application.
Yet, I'm still getting various debug assertions as, for example, AfxGetThread returns NULL, etc. And the application fails to run.
Can someone tell me if my idea of making DLL from EXE is realistic?
Thanks in advance.

Problems with de-registering of COM (advanced installer)

Definition of problem:
Hangs up for sometime during COM de-registering and says The setup was unable to automatically close all requested applications. Please ensure that the applications holding files in use are closed before continuing with the installation. But actually my extension is successfully unloaded and uninstalled.
Definition of environment:
I created some kind of dummy shell namespace extension for tests. It implements IContextMenu and all methods returnS_OK and do nothing else and rgs file is
HKCR
{
xxx.sergz.dummyShellExt.1 = s 'DummyNSE Class'
{
CLSID = s '{6C0FBE00-9898-4BB0-806F-3ED7D2F1170D}'
}
xxx.sergz.dummyShellExt = s 'DummyNSE Class'
{
CurVer = s 'xxx.sergz.dummyShellExt.1'
}
NoRemove CLSID
{
ForceRemove {6C0FBE00-9898-4BB0-806F-3ED7D2F1170D} = s 'DummyNSE Class'
{
ProgID = s 'xxx.sergz.dummyShellExt.1'
VersionIndependentProgID = s 'xxx.sergz.dummyShellExt'
ForceRemove Programmable
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
TypeLib = s '{3DC947F0-6691-4043-B414-29F749209905}'
Version = s '1.0'
}
}
NoRemove Directory
{
NoRemove Background
{
NoRemove ShellEx
{
NoRemove ContextMenuHandlers
{
ForceRemove DummyShellExt = s '{6C0FBE00-9898-4BB0-806F-3ED7D2F1170D}'
}
}
}
}
}
HKLM
{
NoRemove Software
{
NoRemove Microsoft
{
NoRemove Windows
{
NoRemove CurrentVersion
{
NoRemove Shell Extensions
{
NoRemove Approved
{
val '{6C0FBE00-9898-4BB0-806F-3ED7D2F1170D}' = s 'xxx.sergz Dummy shell extension.'
}
}
}
}
}
}
}
I choose Professional installer and added only my dll file. On file properties Registration tab I choose Auto register file..., Extract registration info... and Synchronization is Enabled. In Product Information->Install Parameters->PackageType I choose 64-bit package for x64....
Now I build the MSI and install the extension.
Launch explorer and do right click somewhere on folder background. According to my log my extension is loaded and is DLL_PROCESS_ATTACH and a few times DLL_THREAD_ATTACH.
I launch the MSI again and choose Remove. It says that you have to close ... applications are using files... and there is only Windows Explorer in the list. I choose Automatically close ... and press OK.
All Explorer windows are closed but it seems that Explorer was not shutdown.
The status is "Shutting down applications", according to my log the dll is already unloaded. The problem is here. The dll is already unloaded but the MSI is still waiting for something and then it says The setup was unable to automatically close all requested applications. Please ensure that the applications holding files in use are closed before continuing with the installation.
I click OK and the process continues and my DLL is successfully removed in the end.
I use windows 8 64bit.
What are the reasons of this waiting and the message that applications can not be closed. How can I figure it out?
Right, this isn't going to work, the shell extension is very likely to be loaded and MSI isn't going to kill Explorer.exe. Nor would you want it to, it is rather a ghastly sight to the user.
You'll need to use an alternative way to un/register the extension. It isn't clear what "Professional installer" might mean. But you can always un/register a COM server by modifying the registry yourself rather than leaving it up to the DLL to do so. It is in fact the recommended way. You already know the registry keys from your .rgs file. You can also use the Heat.exe harvester from the WiX toolset. The DLL needs to be removed by delay-deleting it at the next user login, done by adding it to the PendingFileRenameOperations registry key. Check your installer creator tool for the proper procedure.

ADO objects instance creation failed on the target computer

I created an MFC application using VC++ 6.0 on my development computer installing Windows XP SP3. In this application, I used ADO objects to access SQL database server :
CoInitialize (NULL);
try
{
_ConnectionPtr pConn;
HRESULT hr = pConn.CreateInstance (__uuidof (Connection));
if (FAILED (hr))
{
AfxMessageBox ("Can't create intance of Connection");
}
//...
}
//...
Of course, the app works fine on my computer. However, I copied the whole Release folder of the app and then run it on another computer with Windows XP SP3 installed, the app failed at creating the Connection object with hr = -2147467262.
I searched on the internet much but don't see any resolution.
Does anyone know this issue and could you give me some guides on that?

CSIDL constant for user folder for Windows XP

I can't seem to find what is the CSIDL constant for "C:\Documents and Settings\username" folder for Windows XP?
EDIT: I'm retrieving this path using the following code:
HANDLE hUserToken = NULL;
if(WTSQueryUserToken(dwUserSessionID, &hUserToken))
{
PIDLIST_ABSOLUTE pIdl = NULL;
if(SHGetFolderLocation(NULL, nCSIDL, hUserToken, NULL, &pIdl) == S_OK)
{
SHGetPathFromIDList(pIdl, path_buf);
ILFree(pIdl);
}
CloseHandle(hUserToken);
}
The issue becomes that the code returns C:\WINDOWS\system32\config\systemprofile for an administrative account when I'm expecting C:\Documents and Settings\Administrator.
Check this reference: http://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx
The constant you are looking for is CSIDL_PROFILE.
Code snippet to obtain locations: ConstantSpecialItems.cpp + binary ConstantSpecialItems.exe if you want to print them yourself
Sample Locations:
Windows XP
Windows Vista
Windows 7
The one you ask for:
Windows version 5.1, Build 2600
CSIDL paths:
[...]
CSIDL_PROFILE: C:\Documents and Settings\John Doe