C++ LogFont Embed Into XPS - c++

I am attempting to marry a couple of APIs together to facilitate XPS Printing. As True Type Fonts are sometimes restricted on how they may be used it is suggested that you query the OS (Windows) for the license associated with a font. The proscribed method I've found for doing that looks like this:
HDC hDC = CreateDC(L"DISPLAY", NULL, NULL, NULL);
// logfont is a valid instance of LOGFONTW
HGDIOBJ hfont = ::CreateFontIndirect(&logfont);
if (!SelectObject(hDC, hfont))
return;
ULONG privstatus = 0;
LONG ttStatus;
ttStatus = TTGetEmbeddingType(hDC, &privstatus);
At this point ttStatus should be E_NONE if TTGetEmbeddingType succeeded and privstatus should be one of {EMBED_PREVIEWPRINT, EMBED_EDITABLE, EMBED_INSTALLABLE, EMBED_NOEMBEDDING}. I had this example working Friday. Today when I run my executable TTGetEmbeddingType returns 0x0A (E_NOTATRUETYPEFONT) instead of E_NONE. Wat? Am I missing something fundamental about the OS's ability to determine whether a font can be embedded?

The error message text you quoted ("The environment is incorrect") belongs to the ERROR_BAD_ENVIRONMENT system error code, which has a numeric value of 10 (0x0A). However, TTGetEmbeddingType() does not return a system error code. The TTGetEmbeddingType() documentation states:
If successful, returns E_NONE.
This function reads the embedding privileges stored in the font and transfers the privileges to pulPrivStatus.
Otherwise, returns an error code described in Embedding-Function Error Messages.
If you look at the actual definitions in T2embapi.h, a return value of 0x000A is E_NOTATRUETYPEFONT
The specified font is not a TrueType font.

Related

Cannot get an image handle from a bitmap within the resources when using "LoadImageA()" and cannot understand why

I am trying to load an image resource using the LoadImageA() function, yet it doesn't work and I don't understand why.
Here's a bit of my code :
bool isRessource = IS_INTRESOURCE(107);
// Load the resource to the HGLOBAL.
HGLOBAL imageResDataHandle = LoadImageA(
NULL,
MAKEINTRESOURCEA(107),
IMAGE_BITMAP,
0,
0,
LR_SHARED
);
HRESULT hr = (imageResDataHandle ? S_OK : E_FAIL);
The image I want to load is a bitmap saved in the resources, and represented as such within resources.h:
#define IDB_BITMAP1 107
When I execute the code, isRessource is equal to true, yet hr is equal to E_FAIL.
Any idea as to why this is happening? I am using Visual Studio 2019, and I made the image using Gimp.
After making the same image with the same format on another application (I used "Krita") and importing it again, the image finally loads with the same code (I only changed the reference to the resource). I guess that all types of bitmaps made from Gimp won't work in Visual Studio (I tried most formats of bitmaps from Gimp).
The first link searched with LoadImage gimp as a keyword is enough to answer this question.
This is some useful information:
The bitmap exported by GIMP has a broken header. Specifically, the
code seems to not write the RGBA masks, which AFAIK are not optional
in a BITMAPV5HEADER. This misaligns and changes the size of the entire
extended header, incidentally making it look like a BITMAPV4HEADER,
which explains why most programs will still open it fine. Without
having done any testing, I'd guess LoadImage() is more picky about the
values in this extended header; returning NULL is how it indicates
failure.
By the way, when you import a bitmap, the system does not remind you that the format of the image is unknown?
Like:
After testing, use LoadImage to load such an image will return NULL, and GetLastError will also return 0.

Trying to understand process mitigation policies that can be set by SetProcessMitigationPolicy function

Sorry, if it's too broad of a question. I'm trying to see what exactly SetProcessMitigationPolicy function does in Windows 10, but I can't find much about it online (besides my previous forays into this subject.) I'm testing its PROCESS_MITIGATION_POLICY options one-by-one, and I have some questions about these:
ProcessSystemCallDisablePolicy states that it "Disables the ability to use NTUser/GDI functions at the lowest layer.". So I'm testing it as such:
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY pmscdp = {0};
pmscdp.DisallowWin32kSystemCalls = 1;
BOOL bR = ::SetProcessMitigationPolicy(ProcessSystemCallDisablePolicy, &pmscdp, sizeof(pmscdp));
int err = ::GetLastError();
::GdiFlush(); //Try to trip it here
But it always fails with error code 19, or ERROR_WRITE_PROTECT.
So what exactly is it supposed to do and how do I set it?
ProcessExtensionPointDisablePolicy states that it "... prevents legacy extension point DLLs from being loaded into the process."
PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY pmepdp = {0};
pmepdp.DisableExtensionPoints = 1;
BOOL bR = ::SetProcessMitigationPolicy(ProcessExtensionPointDisablePolicy, &pmepdp, sizeof(pmepdp));
int err = ::GetLastError();
Sorry for my naivete, but what is the extension point DLL? And how can I test one?
ProcessSignaturePolicy states that it can "restrict image loading to those images that are either signed by Microsoft, by the Windows Store, or by Microsoft, the Windows Store and the Windows Hardware Quality Labs (WHQL)".
First off, it seems to have no effect on CreateProcess and only works with LoadLibrary-type functions. So if I do this:
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY pmbsp = {0};
pmbsp.MicrosoftSignedOnly = 1;
//pmbsp.StoreSignedOnly = 1; //always seems to fail with this flag
//pmbsp.MitigationOptIn = 1; //Doesn't seem to have any effect
BOOL bR = ::SetProcessMitigationPolicy(ProcessSignaturePolicy, &pmbsp, sizeof(pmbsp));
BOOL err = ::GetLastError();
And then try to load some of my test DLLs:
HMODULE hModDll = ::LoadLibrary(L".\\Dll1.dll");
The LoadLibrary function fails with the MessageBox that reads:
Bad Image
Dll-Name is either not designed to run on Windows or it
contains an error. Try installing the program again using the original
installation media or contact your system administrator or the
software vendor for support. Error status 0xc0000428.
Interestingly, if I call it on some System32 DLL that is not signed:
HMODULE hModDll = ::LoadLibrary(L"iologmsg.dll");
it seems to work fine. But if I place a copy of my test Dll1.dll into System32 folder and load it this way:
HMODULE hModDll = ::LoadLibrary(L"Dll1_.dll");
it still fails with the same message box:
This is interesting. How can it tell the difference between iologmsg.dll and Dll1_.dll? Both files aren't signed.
PS. And that modal message box can throw in a really nasty wrench into the mix if the app (or the service) does not expect any UI to be shown there.
ProcessFontDisablePolicy lastly, I'm totally lost about this one. It states that it "turns off the ability of the process to load non-system fonts."
So after I enable it in my MFC GUI app:
PROCESS_MITIGATION_FONT_DISABLE_POLICY pmfdp = {0};
pmfdp.DisableNonSystemFonts = 1;
BOOL bR = ::SetProcessMitigationPolicy(ProcessFontDisablePolicy, &pmfdp, sizeof(pmfdp));
int err = ::GetLastError();
the app has a Richedit control that I can load a custom font in. So I went online and downloaded a totally random font. Then installed it in Windows Explorer and tried to use it from the app after that policy has been enabled:
//Set format for the text window
CHARFORMAT cf = { 0 };
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_FACE | CFM_SIZE;
cf.yHeight = 18 * 20;
VERIFY(SUCCEEDED(::StringCchCopy(cf.szFaceName, _countof(cf.szFaceName), L"Action Man")));
VERIFY(SetDefaultCharFormat(cf));
The app was able to display and use that (clearly non-system) font without any issues:
So what am I missing here in that policy?
This is guessing, but since many links in the function's documentation are 404s, I believe that the following would be valid:
1.Probably not implemented, yet.
2.Only a guess (since the link is also 404), but it might refer to DLLs used in obsolete situtations (like the XP and below login DLL, replaced in Vista with Credential Providers).
3.Windows DLLs are treated as signed (without actually having a digital signature attached), not only because they reside in System32, but because Windows keeps internally a map for them. For your DLLs, it won't work. Also, this has no point in CreateProcess() because the new process cannot interact with yours (without your knowledge) and, therefore, cannot hijack it, where a DLL loaded with LoadLibrary can do anything to ruin your process.
4.It probably refers to fonts not installed by Explorer, but fonts added with AddFontResource.

I can't get SHGetFileInfo to return an icon location

I'm on Windows 10 Pro and Visual Studio 2013, and I'm using SHGetFileInfoW to get an icon location (path + index) for a file type:
std::wstring wFile { L"a.bas" };
SHFILEINFOW fi {};
DWORD success = ::SHGetFileInfoW(wFile.c_str(),
FILE_ATTRIBUTE_NORMAL,
&fi,
sizeof(fi),
SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION);
No matter whether wFile refers to an existing file or is just any filename, the call returns 1 indicating success. The iIcon member of fi is set to a number, but szDisplayString is empty. Not just the drive letter is overwritten with \0 (as seemed to happen here) but it is completely filled with \0.
Microsoft recommends using IExtractIcon::GetIconLocation as an alternative, but I need to get the icon for files which are not on a local filesystem, so I can't get an IShellInfo object which would get me this interface pointer.
Getting an icon handle works, on the other hand. Is this function just buggy or am I doing something wrong? Is there a workaround?
Icons can be dynamically generated and might not expose the path to its images. Icon handlers communicate this to the shell by setting the GIL_NOTFILENAME flag in their IExtractIcon::GetIconLocation implementation. If GIL_SIMULATEDOC is set the shell must also typically generate a icon on the fly.
If you call SHGetFileInfo with the SHGFI_SELECTED flag set then then function probably has to generate a new icon no matter which file type you are asking for.
If you are displaying a file list in a ListView/TreeView then you typically use SHGFI_SYSICONINDEX|SHGFI_SHELLICONSIZE|SHGFI_SMALLICON and use the system image list.
Use SHGFI_ICON if you need a HICON.
If SHGFI_ICONLOCATION is specified then SHGetFileInfo uses IExtractIcon:
Retrieve the name of the file that contains the icon representing the file specified by pszPath, as returned by the IExtractIcon::GetIconLocation method of the file's icon handler.

SDL and Visual Studio 2010 resources

I have a simple question. I use SDL and SDL_image in my c++ program and image loading is fine from a single png file.
SDL_Surface *dot = NULL;
dot = load_image("dot.png");
But how can I load the png file if I add it to the resources? so I don't want to store in a png file next to the exe. Is it possible to load from the resources?
Tried
dot = load_image(MAKEINTRESOURCE(IDB_PNG1));
but it didn't work.
It is fully possible to load an image or something else into SDL from a windows resource. To do this you need to get the raw data and pass it to the appropriate RWOPS.
HMODULE hModule = GetModuleHandle(_T("myapp.exe"));
HRSRC hWhite = FindResource(hModule, MAKEINTRESOURCE(IDB_WHITE_PNG), _T("PNG"));
unsigned int white_size = SizeofResource(hModule, hWhite);
HGLOBAL hgWhite = LoadResource(hModule, hWhite);
unsigned char* white_data = (unsigned char*)LockResource(hgWhite);
SDL_Surface* white = IMG_Load_RW(SDL_RWFromConstMem(white_data, white_size), 1);
This assumes that you have something similar in your *.rc file:
IDB_WHITE_PNG PNG "White.png"
According to the MAKEINTRESOURCE documentation :
The return value should be passed only to functions which explicitly indicate that they accept MAKEINTRESOURCE as a parameter.
You don't give the content of load_image (BTW, please include the content of the functions you use in your question, you'll get better answers ...) but I bet it's not using its parameter to call one of the Windows SDK functions which accept MAKEINTRESOURCE ... as far as I know these resources are supposed to hold some specific Windows UI data like mouse cursors, icons, etc.. for use with Windows functions, not with other libraries like SDL, so I'm not surprised it doesn't work.

How to trigger "running state" in Flash Player?

If I use windowed activation (giving a valid HWND to the Flash PLayer in the GetWindow function is enough to trigger this), the player will run the loaded swf file. However, if I use windowless activation, the loaded file does not run, only the very first frame is displayed. This article claims that I'm supposed to call
DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)this, 0, NULL, NULL);
However, this does not have any effect. What am I doing wrong?
Edit: Since I made this post, I found out that it returns -2147467259, which is not a known HRESULT, but certainly not 0. What does it mean?
After some more digging I found out that the return value is OLE_E_NOTRUNNING.
I have found the problem. Before this call, I was doing:
hr = _shockwaveFlash->put_WMode(BSTR("opaque"));
BUT I blatantly ignored the HRESULT there. It made the Flash Player confused, because it is not a valid way to insert a BSTR constant in the code (which is a wide string). Correctly:
hr = _shockwaveFlash->put_WMode(L"opaque");
Now it works as it should. Check you HRESULTs, kids :)