LoadImage stopped working after Windows Update - c++

The updates involved are: KB4532938 and KB4528760
This is the code:
#include "pch.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
HMODULE hInst;
HANDLE hImg = NULL;
hInst = LoadLibrary(L"C:\\Users\\asd\\Desktop\\asd\\test.exe");
hImg = LoadImageW(hInst, MAKEINTRESOURCEW(5234), 2, 0, 0, 0);
if (!hImg)
cout << GetLastError() << endl;
cout << hImg;
}
This is the .exe containing the cursor (it's a blank ahk script)
Before the updates:
Output: NOT-null handle and error-code 1813
It works!
After the updates:
Output: NULL handle and error-code 1813
It doesn't work!
The only difference is the installed updates.
The questions are:
Is it a bug?
How is it possible that the resource exists, the name is correct, the format is correct and it fails?
What changed that made it break, was it a bug that made it work in the first place?
How can I report this to Microsoft?

Since it is not easy to clear in comments, I post it as an answer.
I did tests to reproduce this problem and found that it was only related to "KB4528760 update"(you don't need uninstall both of them).
I use EnumResourceTypes, EnumResourceNames to get that the resource does exist:
name = MAKEINTRESOURCE(5234), type = RT_ANICURSOR.
Use FindResource and specify the resource type to RT_ANICURSOR did work.
#include "pch.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
HMODULE hInst;
HANDLE hImg = NULL;
hInst = LoadLibrary(L"C:\\Users\\asd\\Desktop\\asd\\test.exe");
HRSRC hResInfo = FindResource(hInst, MAKEINTRESOURCE(5234), RT_ANICURSOR);
hImg = LoadResource(hInst, hResInfo);
if (!hImg)
cout << GetLastError() << endl;
cout << hImg;
}

Related

why dbghelp.h's symbol related functions always return 126 error code?

When i try to use the functions SymbolFromName() e SymbolFromAddress() the return code always return 126 (MODULE_NOT_FOUND), the code is :
#include<dbghelp.h>
#include <iostream>
#include <Windows.h>
#include <windows.h>
#include <debugapi.h>
#include <WinBase.h>
using namespace std;
int main(){
DWORD error;
HANDLE hProcess;
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
hProcess = GetCurrentProcess();
if (!SymInitialize(hProcess, NULL, TRUE))
{
// SymInitialize failed
error = GetLastError();
cout << "SymInitialize returned error " << error << endl;;
return FALSE;
}}
hProcess = GetCurrentProcess();
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
SymInitialize(hProcess, NULL, TRUE);
TCHAR szSymbolName[MAX_SYM_NAME];
ULONG64 buffer[(sizeof(SYMBOL_INFOW) +
MAX_SYM_NAME * sizeof(TCHAR) +
sizeof(ULONG64) - 1) /
sizeof(ULONG64)];
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
_tcscpy_s(szSymbolName, MAX_SYM_NAME, TEXT("mainCRTStartup")); // i
know the entrypoint name by using >>nm command in windows for extract
symbol
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
if (SymFromName(hProcess, szSymbolName, pSymbol)){
cout << pSybol->address
} // this return always 126
}
i use VisualStudio and the default debugger for testing it.
Part of the code above is taken from MSDN documentation, here.
EDIT : i know the main simbol thanks to nm, that can extract a list of symbols, in my case it contains :
00401300 T _WinMainCRTStartup
00401460 T _main
004012e0 T _mainCRTStartup
I also try to using different symbols name like main, mainCRTStartup, wWinMain, WinMain and so on, without any results

How to call GetAltMonthNames to fill a safe array of foreign locale month strings?

I saw this function and was wondering how to call this. I might like to write a component and export this function to a COM client so I wanted to fill a safearray of strings (other Automation types are fine). So I wanted to leverage an ATL smart class. This is what I have so far, a console application.
#include "pch.h"
#include <iostream>
// in pch.h ...
//#include "windows.h"
//#include "comutil.h"
//#include "atlbase.h"
//#include <comdef.h>
//#include "atlsafe.h"
int main()
{
LCID germany(7);
LPOLESTR *rgp;
HRESULT hr;
hr=::GetAltMonthNames(germany, &rgp); // can't see results
if (hr != S_OK) return hr;
CComSafeArray<BSTR> months;
hr = ::GetAltMonthNames(germany,(LPOLESTR**) &months); //forced compile but no joy
if (hr != S_OK) return hr;
std::cout << "Hello World!\n";
}
Your first code is ok but there's no alternate names for German language defined. Try Polish:
LPOLESTR* rgp;
if (SUCCEEDED(GetAltMonthNames(1045, &rgp)))
{
int i = 0;
while (rgp[i])
{
wprintf(L"%s\n", rgp[i++]);
}
}
Documentation says:
Useful for Hijri, Polish and Russian alternate month names.

CryptDestroyKey access violation exception in VS2015

I am working on a task in a C++ project to upgrade some components from building with VS2010 to build with VS2015 and noticed a strange behavior that I could not find any discussions online. Simplified code is as follows:
#include "stdafx.h"
int main()
{
HCRYPTPROV hCryptProv = NULL;
LPCTSTR UserName = L"MyKeyContainer";
HCRYPTKEY hKey = NULL;
bool result = CryptAcquireContext(&hCryptProv, UserName, NULL, PROV_RSA_FULL, 0);
result = CryptGenKey(hCryptProv, CALG_RC4, 25 << 16, &hKey); // this line is meant to produce an invalid hKey.
result = CryptDestroyKey(hKey);
result = CryptReleaseContext(hCryptProv, 0);
return 0;
}
and precompiled header:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <Wincrypt.h>
If I try to build and run this code snippet with VS2010, CryptGenKey returns a false result and hKey value of 0.
Passing hKey to the CryptDestroyKey returns false, but does not throw an exception.
If I try to build and run this code snippet with VS2015, CryptGenKey returns a false result and hKey value of 0.
Passing hKey to the CryptDestroyKey throws an access violation exception.
Could someone explain the reason behind this implementation and why Windows won't handle 0 in the more up to date VS version? This could be a potential problem for other projects if they do not manage the 0 themselves.

Debug content of shared memory

I got two processes. In process A, application Alpha is prepared for using shared memory. In process B, my windows console application with a main method accesses this shared memory. It works, I can connect to the memory. Unfortunately if I store the memory content in a variable (here pBuf) and inspect the variable via MsVisualStudioDebugger, there is only one letter in the buffer - what went wrong? How am I able to look in the memory/file to get a clue, what objects are stored in the memory? Thanks in advance.
Here is the code of my console app:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
using namespace std;
#define BUF_SIZE 256
TCHAR szName[] = TEXT("SIMITSHM"); // Name des SHMs;
int main(void){
std::cout << "*** start SharedMemory ***\n";
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
if (hMapFile == NULL){
MessageBox(NULL, TEXT("Could not open file mapping object"), TEXT("FEHLER"), MB_OK);
return 1;
}
pBuf = (LPTSTR) MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
if (pBuf == NULL){
MessageBox(NULL, TEXT("Could not map view of file"), TEXT("FEHLER"), MB_OK);
CloseHandle(hMapFile);
return 1;
}
MessageBox(NULL, pBuf, TEXT("SIMIT-SHM"), MB_OK); // content of memory
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
std::cout << "*** close app by typing a number. ***\n";
int a = 0;
cin >> a;
return 0;
}
UPDATE: after doing more research on this issue, I guess the problem is the casting of the return value of MapViewOfFile()-function.
UPDATE-2: Thanks Hans! I was able to look the pBuf content as a hexdump, see:
UPDATE-3: Thanks Hans! Due to your advice I was able to use fwrite() to put the shared-memory-content in a file on my local machine. Moreover I am able to see some familiar names, i.e. names like EingangMotor1 which I configured in application-Alpha and it seems this content was stored in shared memory. Now I hope to play around with application-Alpha, recognize the related changes in shared-memory and afterwards hopefully I will be able to change the values of the shared memory variable values, so application-Alpha will change its behaviour on the fly.
UPDATE-4: current code - thanks in advance for feedback, which lines needs to be improved.
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <strsafe.h>
#include <fstream>
#include <sstream>
#include <vector>
#pragma comment(lib, "user32.lib")
using namespace std;
#define BUF_SIZE 256
TCHAR szName[] = TEXT("SIMITSHM"); // Name des SHMs;
int main(void){
std::cout << "*** Start SharedMemory ***\n";
HANDLE hMapFile;
FILE * pBuf;
hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szName);
if (hMapFile == NULL){
MessageBox(NULL, TEXT("Could not open file mapping object"), TEXT("ERROR"), MB_OK);
return 1;
}
// MapViewOfFile return a pointer to void, so you need to cast it to a suitable structure
pBuf = (FILE*) MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, BUF_SIZE);
if (pBuf == NULL){
MessageBox(NULL, TEXT("Could not map view of file"), TEXT("ERROR"), MB_OK);
CloseHandle(hMapFile);
return 1;
}
// write file
FILE * pFile;
pFile = fopen ("shm-main-simit-content-fwrite.txt","w");
fwrite(pBuf, 50, 20, pFile);
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
std::cout << "*** close app by typing a number. ***\n";
int a = 0;
cin >> a;
return 0;
}
Yes, you certainly have a type mismatch. That file is very unlikely to contain a properly zero-terminated C string. Using the TCHAR macros adds to the randomness, there is no point in using them anymore. The last non-Unicode version of Windows died 10 years ago.
Answering the question: use Debug + Windows + Memory + Memory 1 and put "pBuf" in the Address box. You'll see a raw hex dump of the shared memory content.

Windows IStillImage interface: can't get device list

Please take a look at my code:
#include <windows.h>
#include <Sti.h>
#include <iostream>
#pragma comment (lib, "Sti.Lib")
using namespace std;
void main ()
{
HRESULT hr = CoInitialize(NULL);
PSTI iface = 0;
hr = StiCreateInstance(GetModuleHandle(NULL), STI_VERSION, &iface, NULL);
DWORD numDevices = 0;
STI_DEVICE_INFORMATION* devices = NULL;
hr = iface->GetDeviceList(NULL, NULL, &numDevices, (void**) &devices);
cout << hr;
hr = iface->Release();
cin.get();
}
GetDeviceList gives me "There was no match for the specified key in the index." Any idea as to what it means? Google doesn't seem to help here.
Everything else is OK (initialization, I mean).
Thanks in advance.
Update: It works on Win XP virtual machine, but still fails on host Win 7 x64. Odd.
STI only works on Win XP, that's all.