How to Initialize Win32 HANDLE appropriately? - winapi

Is it OK to initialize the Win32 HANDLE to NULL? Or are there any better or recommended way to initialize HANDLEs?
For example,
void foo()
{
HANDLE hFile;
hFile = CreateFile(/* necessary arguments*/);
}
What shall i initialize the hFile with?

In your example code you don't need to initialise hFile to anything since it is initialised by the CreateFile function.
The Windows API is not completely consistent on what it considers a "null" handle. Some APIs (like CreateFile) return INVALID_HANDLE_VALUE on failure, whereas others return NULL on failure. So the way you test if a HANDLE is valid or not depends on the function you are getting it from - check the actual documentation for the function and see what it says is the return value on failure.

Related

Calling XGetErrorText() from X11 error handler

Is it safe to call XGetErrorText from a error handler set by XSetErrorHandler?
E.g.
int errorHandler(Display *dpy, XErrorEvent *err)
{
char buf[BUFLEN];
XGetErrorText(dpy, err->error_code, buf, BUFLEN);
printf("%s\n", buf)
return 0;
}
XSetErrorHandler(errorHandler);
I'm asking because the man page says you should not call any functions (directly or indirectly) on the display that will generate protocol requests but it does not tell if XGetErrorText does.
XGetErrorText doesn't generate any server traffic. It's not supposed to: the server doesn't know your locale, for example, and cannot supply localised messages. XLib can, and indeed does with a couple of local Xrm database lookups.
The source code of XGetErrorText can be viewed e.g. here. We can see that XGetErrorText calls XGetErrorDatabaseText, and this latter function is not even using its dpy parameter.
Each X extension provides its own error-event-to-error-string translation function. This function does accept a dpy parameter, but, just like XGetErrorDatabaseText is not supposed to use it too generate any server traffic. This error-handling function is by default generateed by the XEXT_GENERATE_ERROR_STRING macro here, which just encapsulates another call to XGetErrorDatabaseText.

CopyFileEx returns ERROR_INVALID_PARAMETER even if the copy is successful on Win2012R2

CopyFileEx with a following call to GetLastError returns ERROR_INVALID_PARAMETER even if the copy is successful on Win2012R2 since around 2 months back (maybe from December 2015). On Windows XP till Windows 7 and Win 2k3 till Win2k8R2 this does not happen and GetLastError always returns 0 (ERROR_SUCCESS).
Is this expected behavior of this kind of Win32 API?
Do you have to add both result and GetLastError code be sure of the result?
This KB seems related to the problem but applying this patch does not alter the API behavior. There was probably another KB that caused the problem to appear but I have been unable to find it
https://support.microsoft.com/en-us/kb/2963918
Documentation for GetLastError:
Return value
The return value is the calling thread's last-error code.
The Return Value section of the documentation for each function that
sets the last-error code notes the conditions under which the function
sets the last-error code. Most functions that set the thread's
last-error code set it when they fail. However, some functions also
set the last-error code when they succeed. If the function is not
documented to set the last-error code, the value returned by this
function is simply the most recent last-error code to have been set;
some functions set the last-error code to 0 on success and others do
not.
From the documentation:
Return value
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error
information call GetLastError.
In other words, if the function succeeds, you are not expected to call GetLastError, and no promise is made about what will be returned if you do.
So, you are ascribing meaning to the value returned by GetLastError where no meaning should be ascribed.
This is a common pattern in Win32. A great many functions are similar. The value returned by GetLastError is only meaningful in the event that the return value of the function indicates failure. That is not a universal rule though, so you do need to check the documentation on a function by function basis.
The typical form of a call to such a Win32 function looks like this:
if (CopyFileEx(...))
{
// function call succeeded, continue
}
else
{
DWORD err = GetLastError();
// do something with err
}
Note that GetLastError is only called if the function indicates failure through its return value.

How do I intercept an OS X API call in an app

I am using a 3rd party library that invokes a Core Foundation function.
Since that lib has a bug, passing incorrect values to a CF function, I need to intercept that call to fix the passed values.
How do I hook into the CF function call so that I can look at the passed parameters, change them and then call the actual (original) function?
I have the impression I can get to the actual function with the CFBundleGetFunctionPointerForName, passing CFBundleGetMainBundle()as the first parameter and the name of the CF function as the second parameter.
In my particular case, that would be:
void *p = CFBundleGetFunctionPointerForName (CFBundleGetMainBundle(), "CFRunLoopTimerCreate");
But that returns NULL.
I also tried this:
void *p = CFBundleGetFunctionPointerForName (CFBundleGetBundleWithIdentifier("com.apple.Cocoa"), "CFRunLoopTimerCreate");
That returns a non-null value but it still does not appear to be a pointer I could change but rather the actual starting address of the function's code.
So, how do I get an address of a function pointer to an imported API function that I can save and then change to point to my intercepting function? Or how else could I hook into an imported function?
CFBundleGetFunctionPointerForName will just return the address of a function in a given bundle; this will never let you change the destination of calls to the function. If you really want to do something like that, please refer to Is it possible to hook API calls on Mac OS? Note that this is highly not recommended.

Failed to create a file in windows using createFile API

I am failing to create a file in windows using the CreateFile API, GetLastError returns the error code 80 which means the file exists, but actually the file was not existing.
hFile = CreateFile((LPCTSTR) FILEPATH, // name of the write
GENERIC_READ|GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
printf("GET LAST ERROR VALUE IS: %d\n", GetLastError());
What am I doing wrong?
Your error checking is wrong. The documentation says:
Return value
If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot.
If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
In other words, failure is determined by the return value. You cannot use GetLastError to determine failure. You must check the return value and compare against INVALID_HANDLE_VALUE. When you do so I predict that you will find that the return value is not equal to INVALID_HANDLE_VALUE.
In fact, this API uses the last error value to convey extra information even when the function succeeds.
From the documentation of CREATE_ALWAYS:
If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS (183).
And from the documentation of CREATE_NEW:
Creates a new file, only if it does not already exist.
If the specified file exists, the function fails and the last-error code is set to ERROR_FILE_EXISTS (80).
And so on.
The golden rule, one that you must burn into your memory, is that error checking varies from function to function and that you must read the documentation from top to tail.
Note that I am rather sceptical of your (LPCTSTR) cast. That's just asking for trouble. If the path is the wrong type, the compiler will save you from yourself, unless you use that cast. That cast just tells the compiler to shut up. But here it knows better. That cast will allow you to pass ANSI text to a wide API and vice versa. You really should remove it.
GetLastError can cause trouble.
Note the docs say
"If the function fails, the return value is INVALID_HANDLE_VALUE. To
get extended error information, call GetLastError."
So, first, only call GetLastError if you get and INVALID_HANDLE_VALUE handle back from CreateFile.
Second, the last error code can be the , well, liertally, last error code - i.e. the most recent call may be OK, but something previously failed: again from the docs
"If the function is not documented to set the last-error code, the value returned by
this function is simply the most recent last-error
code to have been set; some functions set the last-error code to 0 on
success and others do not."

If RegOpenKeyEx Does Not Return ERROR_SUCCESS Am I Guaranteed that the HKEY Was Not Opened?

Reading Microsoft's documentation on RegOpenKeyEx and RegCloseKey I am unsure of whether or not I need to call the close function if RegOpenKeyEx fails.
Please point me to a definitive source indicating if I need to always call RegCloseKey or if it only needs to be called when RegOpenKeyEx returns ERROR_SUCCESS.
References:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724897%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724837%28v=vs.85%29.aspx
RegOpenKeyEx will only return a valid key handle if ERROR_SUCCESS is the returned value. This is where the caller is responsible for closing the key, otherwise no closing required and key is not opened. This is the the assumed agreement regarding responsibility to close the opened handle, though not explicitly mentioned in RegOpenKeyEx function documentation.
This is also consistent across API samples. If you are unsure after checking sample code in the MSDN article, here is another one: http://msdn.microsoft.com/en-us/library/aa384182%28VS.85%29.aspx
I think if you look at the example listed under your reference links you can see that it does not call RegCloseKey if lResult does not return ERROR_SUCCESS
This is the link to it:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724235(v=vs.85).aspx

Resources