SHGetFolderPath returns garbage string in distribute version - c++

char desktopPath[MAX_PATH];
HRESULT r = SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, 0, desktopPath);
if (r != S_OK) {
throw XArch(new XArchEvalWindows());
}
m_desktopPath = CString(desktopPath);
It is so weird. This piece of code works in VS2010 under both the release and debug modes. After I distribute it and run the application, I would get an error saying "The system cannot find the file specified". The more strange thing is my colleague runs the same application on his machine and it works.
In MSDN it says SHGetFolderPath is deprecated, so I tried to use SHGetKnownFolderPath. It is the same situation.
PWSTR desktopPathW = 0;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &desktopPathW);
if (!SUCCEEDED(hr)) {
throw XArch(new XArchEvalWindows());
}
CoTaskMemFree(static_cast<void*>(desktopPathW));
Any idea about what is going on? Or how am I suppose to debug this?
Thanks in advance.
Jerry

The comments explicitly state that S_OK is the only success result, and the error codes include S_FALSE, E_FAIL and E_INVALIDARG. You incorrectly assume that these 3 are the only error codes.

Related

Calling COM server, C++ CoCreateInstance throws "No such interface supported", C# works without issue

I'm trying to rewrite some code that calls a local COM Server from C# to C++. The C# code works without issue. The key part is:
Guid lr_FactoryGuid = Guid.Parse("AE7CFA4B-985A-4F76-8CC6-2011649FC8A9");
Guid lr_FactoryClass = Guid.Parse("1CA0D073-4ABB-4D06-B318-BFFDE38E4903");
IntPtr lk_FactoryPtr = new IntPtr();
CoGetClassObject(
ref lr_FactoryClass,
4,
new IntPtr(),
ref lr_FactoryGuid,
out lk_FactoryPtr);
if (lk_FactoryPtr == IntPtr.Zero)
{
MessageBox.Show("lk_FactoryPtr == IntPtr.Zero");
return false;
}
I've tried to rewrite this into C++ and I can't get any further than here, the error is give as "No such interface supported":
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CLSID clsid;
HRESULT hr = CLSIDFromString(L"{1CA0D073-4ABB-4D06-B318-BFFDE38E4903}", &clsid);
CLSID iid;
hr = CLSIDFromString(L"{AE7CFA4B-985A-4F76-8CC6-2011649FC8A9}", &iid);
void* pIFace;
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, iid, &pIFace);
if (!SUCCEEDED(hr))
{
_com_error err(hr);
LPCTSTR errMsg = err.ErrorMessage();
MessageBox(NULL, errMsg, L"SiteKiosk demo", MB_ICONEXCLAMATION | MB_OK);
}
There is a .tlb file that I used to generate the interop DLL for C# and to import into the C++, however it's currently commented out of the C++ in an attempt to keep the code smaller and I still get this error from CoCreateInstance.
The COM application I'm calling is a 32 bit app, so both my C# and C++ clients applications are also 32 bit. Both of the clients are Windows Console applications.
Is there anything else I need to set/do to get the C++ working?
The suggestion by Hans solved the problem, I used CoGetClassObject and the rest of the code then clicked into place.

How recognize Symbolic link files?

I always used this solution to enumerate files and folders recursively. The code works very fine showing correct file/folder names to all found. But exists a trouble related to recognition of symbolic link files, making the linked solution fail, for example:
Like you can see on image above, these 3 files are symbolic link files pointing to dll files in some place. Then, executing the code mentioned will prints:
api-ms-win-core-console-l1-1-0.dll
instead of
api-ms-win-core-console-l1-1-0.symlink
Another similar case with some use of IoCreateFile() function. If this receive a wrong filename or objectattributes (still referring to code of linked answer), also will fail with a ntstatus error STATUS_OBJECT_PATH_NOT_FOUND or some other related to this trouble.
Then my question is:
Is threre some solution to recognize symbolic link files where the linked code that i had used could work (and also why not any other function like ZwOpenFile etc)?
Thanks in advance by any suggestion.
Edition:
Here is a code where IoCreateFile() function fails when a simbolic link is passed as filename:
#include <ntifs.h>
#include <ntddk.h>
HANDLE
MyIoOpenFile(
IN PCWSTR FileName,
IN ACCESS_MASK DesiredAccess,
IN ULONG ShareAccess)
{
NTSTATUS ntStatus;
UNICODE_STRING uniFileName;
OBJECT_ATTRIBUTES objectAttributes;
HANDLE ntFileHandle;
IO_STATUS_BLOCK ioStatus;
if (KeGetCurrentIrql() > PASSIVE_LEVEL) {
DbgPrint("KeGetCurrentIrql() > PASSIVE_LEVEL\n");
return 0;
}
RtlInitUnicodeString(&uniFileName, FileName);
InitializeObjectAttributes(&objectAttributes, &uniFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = IoCreateFile(&ntFileHandle,
DesiredAccess,
&objectAttributes,
&ioStatus,
0,
FILE_ATTRIBUTE_NORMAL,
ShareAccess,
FILE_OPEN,
0,
NULL,
0,
0,
NULL,
IO_NO_PARAMETER_CHECKING);
if (!NT_SUCCESS(ntStatus)) {
DbgPrint("IoCreateFile() error - 0x%X \n", ntStatus);
return 0;
}
return ntFileHandle;
}
//---------------------------------------------------------------------------
HANDLE hFileHandle = MyIoOpenFile(L"\\??\\C:\\Full-Path-FileName-Here",
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ);
if (hFileHandle != 0) {
DbgPrint("hFileHandle: %08X\n", hFileHandle);
ZwClose(hFileHandle);
}
From Microsoft docs:
FILE_ATTRIBUTE_REPARSE_POINT - A file or directory that has an associated reparse point, or a file that is a symbolic link.
So you can use GetFileAttributes to detect symbolic links:
LPCWSTR lpszFileName = /* get file name */;
if (GetFileAttributes(lpszFileName) & FILE_ATTRIBUTE_REPARSE_POINT)
{
// Symbolic link
}
See comments for further information about error checks and kernel mode API

How to check whether Microsoft outlook is opened or not in c++?

I want to perform a specific action in my application based on whether outlook is opened or not.
I tried this piece of code, but it is always returning false.
CLSID clsid;
HRESULT hr = CLSIDFromProgID(_T("Outlook.Application"), &clsid);
if (hr != S_OK)
return false;
IUnknown *pUnknown = NULL;
hr = GetActiveObject(clsid, 0, &pUnknown);
return (hr == S_OK);
Could anyone please let me know how do we check whether "Outlook" is opened or not in c++.
As far as I know, C++ standard will not help in this case, as your question is operating system specific.
You can use "WinAPI" if you are on windows OS.
Below are some steps. The code for below steps is available in below MSDN link. You can modify the code as required for your usage.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682623(v=vs.85).aspx
Call "EnumProcesses". Will return the list of process IDs.
Iterate through each process using process ID return by "EnumProcesses".
Then find the name of process using "OpenProcess" and "GetModuleBaseName" as shown in above MSDN link.
Search for the string "Outlook" in the process name returned by above step (step 3).
This is a rough way I know.
Get the snapshot of all process running in the system, iterate to find
whether "outlook" is present in any of the exe name.
void isOutlookRunning()
{
bool retval = false;
PROCESSENTRY32 t_entry;
t_entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE t_snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(t_snapshot, &t_entry))
{
while (Process32Next(t_snapshot, &t_entry))
{
if(StrStrI(t_entry.szExeFile,"outlook")
retval = true;
}
}
CloseHandle(t_snapshot);
return retval;
}

DirectX11 CreateShaderResourceView FromMemory or FromResource

Excuse me for my low english skills, I hope you will edit my post if you got enough karma.
I am trying to initialize ShaderResourceView from the Win32 Program Resource. I am using Visual Studio 2015.
Next code fails:
HMODULE hMod = GetModuleHandleW(0);
HRSRC hRes = FindResourceW(hMod, (const wchar*)MAKEINTRESOURCE(IDB_BITMAP1), RT_BITMAP);
HGLOBAL hGlob = LoadResource(hMod, hRes);
DWORD dwImageSize = SizeofResource(hMod, hRes);
byte *lpResourceData = (byte*)LockResource(hGlob);
HRESULT hr = D3DX11CreateShaderResourceViewFromMemory(lpDevice, lpResourceData, dwImageSize, NULL, NULL, &lpNodeTexture, NULL);
if(FAILED(hr)) {
Int3();
}
FreeResource(hGlob);
All of these WinApi functions are succeeded and I really have this resource in my program, but hresult always returns E_FAIL. Can you pls give me an advice. Thank you.
EDITED:
I forgot to add next code as well to the first post:
D3DX11CreateShaderResourceViewFromFileW(lpDevice, L"Node.bmp", 0, 0, &texture, 0).
Its working for me, but I need to pack my textures into application. Can the problem be more difficult than creating D3D Device with Debug Layer flag? Thanks.

URLDownloadToFile Error(0x80004004) in IDownloadManager::Download

I made custom downloader of IE using IDownloader Interface and URLDownloadToFile method.
But URLDownloadToFile return 0x80004004 error code.
I wonder! what's wrong in source code?
reference : http://social.msdn.microsoft.com/Forums/en/iewebdevelopment/thread/3fbcea06-4e69-4504-82e0-f4786368a5e2
STDMETHODIMP CDownloader::Download(IMoniker* pmk,
IBindCtx* pbc,
DWORD dwBindVerb,
LONG grfBINDF,
BINDINFO* pBindInfo,
LPCOLESTR pszHeaders,
LPCOLESTR pszRedir,
UINT uiCP )
{
LPOLESTR sDisplayName;
pmk->GetDisplayName(NULL, NULL, &sDisplayName);
HRESULT hr = URLDownloadToFile(NULL, sDisplayName, L"C:\\downloaded.exe", 0, NULL);
return S_OK;
}
This is an error code for E_ABORT, so it looks like your download operation was aborted
From MSDN:
"The download operation can be canceled by returning E_ABORT from any callback"
but since your callback is NULL, it is probably caused by some other problem.
I solved it.
COM object on Internet explorer must create file in IE template folder. Because IE protected mode.