Okay, so I want to stop asking lots of questions on how to do most programming stuff because most of my questions are given answers that say "Read the MSDN" founded here. Thing is, I have no idea how to read it or most programming languages. For example, lets take the FtpCreateDirectory function on MSDN (which you can find here)
Now, pretend I just learned this feature and I want to try it out. How do I read it, how to I take the functions/commands it shows me. How do I type it? This reallt does not help:
BOOL FtpCreateDirectory(
_In_ HINTERNET hConnect,
_In_ LPCTSTR lpszDirectory
);
Thanks!
I've not used this myself, but let's step through and give an example:
HINTERNET hinternet = InternetConnect(...); //assume hinternet is valid
if (!FtpCreateDirectory(hinternet, "C:\\example")) {
std::cerr << "Error creating FTP directory. Code: " << GetLastError();
}
Step by step:
First, we get a HINTERNET handle. How? Well, the docs say this about the parameter:
Handle returned by a previous call to InternetConnect using INTERNET_SERVICE_FTP.
That's why I called InternetConnect in the example.
Next, we look at the second parameter. Looking at the Windows Data Types article, you can see that it takes either a CONST WCHAR * or CONST CHAR *, depending on whether UNICODE is defined. For simplicity, I acted as though it wasn't, though you can use the TEXT macro to make a string literal wide or narrow depending on UNICODE.
Pointer to a null-terminated string that contains the name of the directory to be created. This can be either a fully qualified path or a name relative to the current directory.
As we can see, it's just a path, so I passed in an example path. This is just an example, but keep in mind what the Remarks section says about this parameter.
Now, we check the return value:
Returns TRUE if successful, or FALSE otherwise. To get a specific error message, call GetLastError. (more not shown)
Therefore, we wrap the call in an if statement to catch an error, which we can retrieve the code for using GetLastError. It's important to use the error handling technique described in each function's article. A lot of them say that upon an error, you can use GetLastError, but some don't support GetLastError usage, and some support different types of error retrieving functions, so make sure to follow the guidelines for each function individually.
Other than that, the _In_ means that the parameter goes in and it's no use after. This is opposed to, among others, _Out_, which means that you'd pass in allocated memory and the function would write to it, so you can use it after the function call with the value the function writes.
in the refernce part of MSDN there is a basic assumption that you understand the context for the API set.
If win32 c(++) programming is what you want then you need to read an intro do windows programming / win32. Its not clear what your area of interest is, are you trying to write desktop apps, servers, drivers,....
For some cases classic books like Charles Petzold programming windows are a good place to start. MSDN has a lot of intro level stuff too (google 'start win32 programming')
Related
I'm trying to simply find out, and list, as much as I can about a window. I'm getting the window via FindWindow with the name of the window I'm curious about, then calling GetWindowInfo on that window handle to fill a WINDOWINFO structure. At this point, I get interesting information, but I'm unsure what to do with the WINDOWINFO.atomWindowType. I've read I can convert it to an LPCTSTR, but it must be in the low-order word component, whereas the high-order word must be zero. I'm not sure A.) how to make this conversion, and B.) what all I can extract from having gotten an ATOM from a window. I've seem the function GetClassInfo which I would like to call, but I'm not sure how to do the conversion, and from my reading it almost sounds like I wouldn't be able to get info out of it. Can someone guide me or provide an example of calling GetClassInfo with an ATOM, if it is possible, and hopefully in that example provide how to do the conversion to an LPCTSTR (which I've read is a const char*, and I wasn't able to make that dynamically). Thanks!
Use the MAKEINTATOM macro to convert the atom to a string pointer that can be passed to GetClassInfo. As for what you can do with the atom? Well, you can pass it to GetClassInfo or other functions that use class names. That's about it.
I am unsure if I have made a fundamental issue in my implementation or there is a bug in the Windows API with regards to formatting system error messages.
I have a Windows API wrapper method for the FormatMessage function. My implementation allows the caller to pass in additional parameters to allow for the formatting of system error messages.
The method signature is as follows:
bool setFormattedMessage(int arguments, ...)
Within this method I have the following block of code that doesn't appear to work for all my unit tests:
if (arguments)
{
va_list argumentsList;
va_start(argumentsList, arguments);
size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, language, (LPWSTR)&buffer, 0,
&argumentsList);
va_end(argumentsList);
}
Note:
code and language are members of the class set in the instantiation list (using GetLastError and LANGIDFROMLCID(GetThreadLocale()).
Here are some unit tests that pass without any problems:
If I create an instance of the class for an error code of 34 I will get the following if I call the method as test.setFormattedMessage(0) (note that this doesn't go into the block of code I posted due to the if (arguments) line):
The wrong diskette is in the drive. Insert %2 (Volume Serial Number: %3) into drive %1.`
If I call the method as test.setFormattedMessage(3, L"C:", L"disk 2", L"ABC123") I get the following:
The wrong diskette is in the drive. Insert disk 2 (Volume Serial Number: ABC123) into drive C:.;
However, for error messages that include such examples as %hs or %08lx I run into problems attempting to format the text.
Take the example of error code 573. When passing an argument of 0 into the method I get the following text (as expected):
{Missing System File} The required system file %hs is bad or missing.
But, if I pass in (1, "test") I end up with:
{Missing System File} The required system file hs is bad or missing.
In fact, I have found that regardless of whether I pass in "test", L"test", a copy of char, wchar_t etc I always end up with the error message above. The message created is the same as passing (0) with the exception of having the % dropped from the string.
I am finding the same problem for all other parameters unless they are numbered (such as %1). I am completely stuck at this point as to whether I have made a fundamental error or there really is a shortcoming in the FormatMessage function.
I was under the impression that I could pass in a replacement for the %hs placeholder in the same way I would do it for swprintf:
char * t = "file 123";
wchar_t a[2000];
int v = swprintf(a, 2000, L"Blah blah %hs", t);
std::wstring someText(a, v);
Blah blah file 123
If you read the FormatMessage() documentation, it specifically states:
Security Remarks
If this function is called without FORMAT_MESSAGE_IGNORE_INSERTS, the Arguments parameter must contain enough parameters to satisfy all insertion sequences in the message string, and they must be of the correct type. Therefore, do not use untrusted or unknown message strings with inserts enabled because they can contain more insertion sequences than Arguments provides, or those that may be of the wrong type. In particular, it is unsafe to take an arbitrary system error code returned from an API and use FORMAT_MESSAGE_FROM_SYSTEM without FORMAT_MESSAGE_IGNORE_INSERTS.
Your code is using FORMAT_MESSAGE_FROM_SYSTEM without using FORMAT_MESSAGE_IGNORE_INSERTS, which is not safe.
So, unless you are absolutely sure that you know the EXACT formatting of any given system error code, and your code has checked for that error code before deciding which formatting parameters to pass in, and you are absolutely sure that Microsoft will never change that format of that error message between OS versions, then you simply cannot safely use formatting arguments with system errors, so don't even try. Formatting arguments are only safe to use when you use your own error messages via FORMAT_MESSAGE_FROM_HMODULE to access your own EXE/DLL module resources, or FORMAT_MESSAGE_FROM_STRING to provide your own error message string in memory.
Following clarification from David Heffernan (see comments in the original question) it can be confirmed that the FormatMessage function doesn't support the ability to replace system error message placeholders unless they are numbered (%1). Therefore, a placeholder such as %hs will become hs.
Note that the above is only true when you are not using the FORMAT_MESSAGE_IGNORE_INSERTS flag.
I have checked through the system error messages using this link:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
The error messages listed here do not appear to mix the placeholder styles (an error message will either use numbered placeholders or uses the alternative format).
For numbered placeholders it is possible to continue using the functionality as described in the original question. For error messages that use the alternative style it is possible to use vswprintf, but only after calling the FormatMessage function with the FORMAT_MESSAGE_IGNORE_INSERTS flag (call vswprintf on the populated buffer, and remember to re-initialise the va_list).
There is perhaps a weakness in the overall approach when also supporting internationalisation. It is possible that the order of placeholders could differ across different languages.
The effort drastically increases if you really need to call FormatMessage to retrieve system error messages without using the FORMAT_MESSAGE_IGNORE_INSERTS flag. In addition to what has been described above, you can also get a C0000005 exception if your va_list doesn't match the number (and possibly types) of placeholders.
From IDispatch::GetTypeInfoCount
The return value obtained from the
returned HRESULT is one of the
following: [S_OK -> Success],
[E_NOTIMPL -> Failure]
And the sample at the bottom returns E_INVALIDARG and NOERROR.
As far as I see E_INVALIDARG is not S_OK, nor is it NOERROR, so what do you do? Do you check for invalid pointers or you don't?
It seems that COM is pretty much foundation for everything, and I can't find one good source of information about correct behavior of simple IDispatch. How do you approach such inconsistencies in your production code?
With COM, you should never check for specific return values unless you actually need to have special handling for those values. Instead, you should use the FAILED or SUCCEEDED macros when you just need to know if a call failed or succeeded. i.e.
HRESULT hr = ...;
if (FAILED(hr)) {
...
COM calls can often return a much wider range of error codes than is specified in the documentation. The called function is not the only source of errors. Depending on the call is actually made (in-process, out-of-process, DCOM) the COM system itself can return a whole host of errors.
NOERROR is defined to the very same value as S_OK. Checking for a null pointer before dereferencing is good style in any method but in this sample it should return E_POINTER.
Values NOERROR/S_OK and E_NOTIMPL are the most typical you should expect from that method unless you abuse the method, that list can of course omit codes like E_POINTER.
Anyway don't target for specific codes, use SUCCEEDED/FAILED macros.
I came across the following weird chunk of code.Imagine you have the following typedef:
typedef int (*MyFunctionPointer)(int param_1, int param_2);
And then , in a function , we are trying to run a function from a DLL in the following way:
LPCWSTR DllFileName; //Path to the dll stored here
LPCSTR _FunctionName; // (mangled) name of the function I want to test
MyFunctionPointer functionPointer;
HINSTANCE hInstLibrary = LoadLibrary( DllFileName );
FARPROC functionAddress = GetProcAddress( hInstLibrary, _FunctionName );
functionPointer = (MyFunctionPointer) functionAddress;
//The values are arbitrary
int a = 5;
int b = 10;
int result = 0;
result = functionPointer( a, b ); //Possible error?
The problem is, that there isn't any way of knowing if the functon whose address we got with LoadLibrary takes two integer arguments.The dll name is provided by the user at runtime, then the names of the exported functions are listed and the user selects the one to test ( again, at runtime :S:S ).
So, by doing the function call in the last line, aren't we opening the door to possible stack corruption? I know that this compiles, but what sort of run-time error is going to occur in the case that we are passing wrong arguments to the function we are pointing to?
There are three errors I can think of if the expected and used number or type of parameters and calling convention differ:
if the calling convention is different, wrong parameter values will be read
if the function actually expects more parameters than given, random values will be used as parameters (I'll let you imagine the consequences if pointers are involved)
in any case, the return address will be complete garbage, so random code with random data will be run as soon as the function returns.
In two words: Undefined behavior
I'm afraid there is no way to know - the programmer is required to know the prototype beforehand when getting the function pointer and using it.
If you don't know the prototype beforehand then I guess you need to implement some sort of protocol with the DLL where you can enumerate any function names and their parameters by calling known functions in the DLL. Of course, the DLL needs to be written to comply with this protocol.
If it's a __stdcall function and they've left the name mangling intact (both big ifs, but certainly possible nonetheless) the name will have #nn at the end, where nn is a number. That number is the number of bytes the function expects as arguments, and will clear off the stack before it returns.
So, if it's a major concern, you can look at the raw name of the function and check that the amount of data you're putting onto the stack matches the amount of data it's going to clear off the stack.
Note that this is still only a protection against Murphy, not Machiavelli. When you're creating a DLL, you can use an export file to change the names of functions. This is frequently used to strip off the name mangling -- but I'm pretty sure it would also let you rename a function from xxx#12 to xxx#16 (or whatever) to mislead the reader about the parameters it expects.
Edit: (primarily in reply to msalters's comment): it's true that you can't apply __stdcall to something like a member function, but you can certainly use it on things like global functions, whether they're written in C or C++.
For things like member functions, the exported name of the function will be mangled. In that case, you can use UndecorateSymbolName to get its full signature. Using that is somewhat nontrivial, but not outrageously complex either.
I do not think so, it is a good question, the only provision is that you MUST know what the parameters are for the function pointer to work, if you don't and blindly stuff the parameters and call it, it will crash or jump off into the woods never to be seen again... It is up to the programmer to convey the message on what the function expects and the type of parameters, luckily you could disassemble it and find out from looking at the stack pointer and expected address by way of the 'stack pointer' (sp) to find out the type of parameters.
Using PE Explorer for instance, you can find out what functions are used and examine the disassembly dump...
Hope this helps,
Best regards,
Tom.
It will either crash in the DLL code (since it got passed corrupt data), or: I think Visual C++ adds code in debug builds to detect this type of problem. It will say something like: "The value of ESP was not saved across a function call", and will point to code near the call. It helps but isn't totally robust - I don't think it'll stop you passing in the wrong but same-sized argument (eg. int instead of a char* parameter on x86). As other answers say, you just have to know, really.
There is no general answer. The Standard mandates that certain exceptions be thrown in certain circumstances, but aside from that describes how a conforming program will be executed, and sometimes says that certain violations must result in a diagnostic. (There may be something more specific here or there, but I certainly don't remember one.)
What the code is doing there isn't according to the Standard, and since there is a cast the compiler is entitled to go ahead and do whatever stupid thing the programmer wants without complaint. This would therefore be an implementation issue.
You could check your implementation documentation, but it's probably not there either. You could experiment, or study how function calls are done on your implementation.
Unfortunately, the answer is very likely to be that it'll screw something up without being immediately obvious.
Generally if you are calling LoadLibrary and GetProcByAddrees you have documentation that tells you the prototype. Even more commonly like with all of the windows.dll you are provided a header file. While this will cause an error if wrong its usually very easy to observe and not the kind of error that will sneak into production.
Most C/C++ compilers have the caller set up the stack before the call, and readjust the stack pointer afterwards. If the called function does not use pointer or reference arguments, there will be no memory corruption, although the results will be worthless. And as rerun says, pointer/reference mistakes almost always show up with a modicum of testing.
I've seen a lot of example c++ code that wraps function calls in a FAILED() function/method/macro.
Could someone explain to me how this works? And if possible does anyone know a c# equivalent?
It generally checks COM function errors. But checking any function that returns a HRESULT is what it's meant for, specifically. FAILED returns a true value if the HRESULT value is negative, which means that the function failed ("error" or "warning" severity). Both S_OK and S_FALSE are >= 0 and so they are not used to convey an error. With "negative" I mean that the high bit is set for HRESULT error codes, i.e., their hexadecimal representation, which can be found in, e.g., winerror.h, begins with an 8, as in 0x8000FFFF.
This page shows the half of the WinError.h include file that defines FAILED(). It's actually just a very simple macro, the entire definition goes like this:
#define FAILED(Status) ((HRESULT)(Status)<0)
And if possible does anyone know a c# equivalent?
You won't actually need that in C#, unless you're using COM objects. Most .NET functions either already return a (more or less) meaningful value (i.e. null, false) or throw an exception when they fail.
If you're directly accessing a COM object, you can define a simple Failed function that does what the macro in unwind's post does. Define that locally (protected/private), since the messy COM details shouldn't be visible in your app anyway.
In case you didn't know, there's also a SUCCEEDED macro in COM. No need to test for failure :)