I'm writing C++ dll on Visual studio 2013. My dll should read parameters from ini file. So, I've created a function for this purpose (ReadConnectionSettings()). My static variable serverIP gets value properly during the function working, however once the function complete running the variable (serverIP) loses its value. What seems to be the problem?
static LPTSTR serverIP = _TEXT("");
void ReadConnectionSettings()
{
TCHAR url[256];
GetPrivateProfileString(_T("Connection"), _T("Url"), _T(""), url, 256, NameOfIniFile);
serverIP = url;
}
You are pointing the pointer serverIP at stack memory url.
This goes out of scope when the function exits, so your pointer is left pointing to junk.
What you could do is make serverIP a buffer instead, and copy the URL into it. Then it would persist.
That is:
static TCHAR serverIP[256] = _TEXT("");
Then:
_tcsnccpy(serverIP, url, 255);
Or as #DavidOtano suggested, you could keep your existing serverIP pointer, and use:
serverIP = _tcsdup(url);
But if you do this, you're dynamically allocating memory, so will need to remember to call:
free(serverIP);
when you no longer need it, to avoid a memory leak.
You're setting the static pointer variable to point at a local variable that does not exist anymore after the function has returned.
A good way to return a string from a function in a Windows program, is to return a std::wstring.
Try that.
Regarding LPTSTR and _TEXT, you only need this if you intend to support MFC in DLLs in Windows 9x. Is that the case? If not, just ditch that Microsoft silliness.
The code fixed according to above advice (off the cuff, untouched by compiler's hands):
auto connection_settings()
-> std::wstring
{
std::wstring url( 256, L'#' );
auto const n = GetPrivateProfileString( L"Connection", L"Url", L"", &url[0], url.size(), NameOfIniFile );
url.resize( n );
return url;
}
One nice property of this code is that it no longer modifies a global variable.
Related
Here is what is going on. When I try and run an AfxMessageBox from my CDialog extension class, I get an errror (see below). I've googled the internet but come up short. This is the only place the messagebox fails, and I know the rest of the code works (I stepped through it).
Does anyone know how to fix this?
Thanks in advance!
Error message when AFXMESSAGEBOX opens:
Unhandled exception at 0x014b4b70 in IsoPro.exe: 0xC0000005: Access violation reading location 0x34333345.
Code to launch AfxMessageBox, from within CDialog
LPTSTR temp;
mainPassword.GetWindowText((LPTSTR)temp,100);
CString cstr;
cstr.Format("mainPassword = %s",temp);
AfxMessageBox(cstr);
Code to display CDialog:
CEnterpriseManagementDialog* emd = new CEnterpriseManagementDialog();
emd->Create(IDD_ENTERPRISE_MANAGEMENT_DIALOG);
emd->ShowWindow(SW_SHOW);
The problem is how you use GetWindowText:
LPTSTR temp;
mainPassword.GetWindowText((LPTSTR)temp,100);
You are letting GetWindowText attempt to write to some unallocated memory passing the uninitialized temp pointer. If you really want to use a raw output buffer, you should allocate room for it before passing a pointer to GetWindowText, e.g.:
TCHAR temp[100];
mainPassword.GetWindowText(temp, _countof(temp));
// NOTE: No need to LPTSTR-cast
But, since you are using C++, you may want to just use a string class like CString, instead of raw buffers, e.g.:
CString password;
mainPassword.GetWindowText(password);
CString msg;
msg.Format(_T("mainPassword = %s"), password.GetString());
// or you can just concatenate CStrings using operator+ ...
AfxMessageBox(msg);
It looks like the variable temp is an uninitialized pointer (the definition of LPTSTR is a char *).
Try defining temp as an array instead:
TCHAR temp[64];
I have written a hooking dll using the mhook library. In a spezial case the NtOpenFile() fails when a std::wstring is defined as stack var. Defining it on the heap the code is working.
The code is working without problems except when a certain win32 application (lets call it nuisance.exe) tries to open an existing testfile (like c:\temp\anyfile.log) the access fails. Mostly STATUS_INVALID_ACL (0xC0000077) is returned then.
I have reduced my code line by line and finally found that the error happens when in a called function a std::wstring is defined (this example below). The error happens every time an on different OS's
NTSTATUS NtOpenFileApiHook::NtOpenFileHook(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
ULONG ShareAccess,
ULONG OpenOptions
)
{
NTSTATUS Status = STATUS_SUCCESS;
// using this function the call will fail
AfterThis_NtOpenFile_WillFail();
// using this function INSTEAD the call will work
AfterThis_NtOpenFile_WillWork();
// calling the real NtOpenFile using a pointer
// nothing was changed hier, the original parameters are passed
Status = RealNtOpenFile(FileHandle, ...);
return Status;
}
int AfterThis_NtOpenFile_WillFail()
{
std::wstring String = L"";
return 0;
}
int AfterThis_NtOpenFile_WillWork()
{
std::wstring * pString = new std::wstring();
pString->assign(L"");
delete pString;
return 0;
}
I have fixed it this way for this call. But I'm afraid that other functions in other circumstainces could fail so I'm looking for the reason and (probably) for a solution.
Nuisance.exe is a C# application with default stacksize callling a win32 dll about which I know nothing.
If Nuisance.exe was a C++ application, I would imagine that it calls NtOpenFile in a way similar to this, allocating one of pointer parameters on overwritten stack:
POBJECT_ATTRIBUTES MakeObjectAttributes()
{
POBJECT_ATTRIBUTES oa = {...};
return &oa; // Pointer to stack variable - UB
}
...
NtOpenFile(..., MakeObjectAttributes(), ...)
STATUS_INVALID_ACL (0xC0000077) error might suggest that SecurityDescriptor within OBJECT_ATTRIBUTES is allocated this way.
Then it matters how much stack is used by AfterThis_NtOpenFile_WillFail, and it is more than AfterThis_NtOpenFile_WillWork, since std::wstring would be larger than just a couple of pointers due to small string optimization.
If the call chain is always the same, the corruption may be deterministic.
I don't know if code equivalent of returning address of temporary is possible in C#. But the DLL may be in C/C++ or similar language that allows dandling pointers.
To prove/disprove the role of stack, try to allocate other data on stack that has std::wstring size. More precise proof could be checking passed pointer to see if they point to stack area that is about to be overwritten.
I have a Win32 C++ application and I need to modify the command line arguments in the application. Specifically, I want to edit the command line arguments in such a way that GetCommandLineW() returns my new arguments.
Believe it or not, this works (since we have a non-const pointer to the character array):
LPTSTR args = GetCommandLineW();
LPTSTR new_args = L"foo --bar=baz";
wmemcpy(args, new_args, lstrlenW(new_args));
// ...
LPTSTR args2 = GetGommentLineW(); // <- equals "foo --bar=baz"
But I don't know how long much memory Windows allocates for the LPTSTR provided by GetCommandLineW().
Is there another way to do this? Or does anyone know if there is a predictable amount of memory allocated for the command line arguments?
GetCommandLineW() does not allocate any memory. It simply returns a pointer to a buffer that is allocated by the OS in the process's PEB structure when the process is created. That buffer exists for the lifetime of the process.
The cleanest and safest way to modify what that function returns is to modify the function. Install a detour so that any calls to the function from inside your process are re-routed to a function that you provide.
Use the following code to inspect on PEB structure, where the CommandLine (unicode) string lies.
On my machine, under both x86 and x64 CommandLine is right after ImagePathName, so I think there won't be more space for the former one either. Writing a longer string to that buffer does might cause an overflow.
#include <winnt.h>
#include <winternl.h>
int main()
{
// Thread Environment Block (TEB)
#if defined(_M_X64) // x64
PTEB tebPtr = (PTEB)__readgsqword((DWORD) & (*(NT_TIB*)NULL).Self);
#else // x86
PTEB tebPtr = (PTEB)__readfsdword((DWORD) & (*(NT_TIB*)NULL).Self);
#endif
// Process Environment Block (PEB)
PPEB pebPtr = tebPtr->ProcessEnvironmentBlock;
PRTL_USER_PROCESS_PARAMETERS ppPtr = pebPtr->ProcessParameters;
printf("ImagePathName:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->ImagePathName.Length, ppPtr->ImagePathName.MaximumLength, ppPtr->ImagePathName.Buffer);
printf("CommandLine:\tlen=%d maxlen=%d ptr=%p\n", ppPtr->CommandLine.Length, ppPtr->CommandLine.MaximumLength, ppPtr->CommandLine.Buffer);
printf("GetCommandLineA:\tptr=%p\n", GetCommandLineA());
printf("GetCommandLineW:\tptr=%p\n", GetCommandLineW());
printf("Addr Delta between CommandLine and ImagePathName: %d\n", (char*)ppPtr->CommandLine.Buffer - (char*)ppPtr->ImagePathName.Buffer);
}
I have a win32 c++ application & I getting all the environment variables & storing them in a map.
When I call the Win32 function FreeEnvironmentStrings() in my application I get a weird Windows Breakpoint in MSVC++. First I dont know what this means & why its occuring?
How can I fix my problem & what is going wrong?
This the function that I call in my main function & the one that causes the breakpoint:
std::map <tstring, tstring> GetEnvironmentVariablesEx()
{
// Post: Get all windows environment variables & store in a
// map(key=env.. variable name, value=env variable value)
std::map <tstring, tstring> envVariables;
TCHAR* environVar = GetEnvironmentStrings();
TCHAR* pos = _tcschr( environVar, _T('\0') );
// Skip over the "=::=::\0" of the environVar string
if ( pos != NULL ) { environVar = ++pos; pos = _tcschr( environVar, _T('\0') ); }
else return envVariables;
// I removed the following code because its long & distracting: the error still occurs without the code
// Code: ...use cstring functions to extract environ variables & values & store in map
FreeEnvironmentStrings( environVar ); // Breakpoint triggered here: "Windows has triggered a breakpoint in the application. This may be due to a corruption of the heap, which indicates a bug in myApp.exe or any of the DLLs it has loaded."
return envVariables;
}
You're changing what environVar points to, so you're not handing the FreeEnvironmentString function a valid environment string pointer.
Save the original environVar somewhere before modifying it and use that in the Free call.
TCHAR* tobefreeed = GetEnvironmentStrings();
TCHAR* environVar = tobefreeed;
...
FreeEnvironmentStrings( tobefreeed );
After you skip reserved characters environVar no longer points at data area allocated by GetEnvironmentStrings. This causes FreeEnvironmentStrings to fail.
Preserve original pointer intact (modify a copy if you need) and you'll solve the problem.
I've created a function that will convert all the event notification codes to strings. Pretty simple stuff really.
I've got a bunch of consts like
const _bstr_t DIRECTSHOW_MSG_EC_ACTIVATE("A video window is being activated or deactivated.");
const _bstr_t DIRECTSHOW_MSG_EC_BUFFERING_DATA("The graph is buffering data, or has stopped buffering data.");
const _bstr_t DIRECTSHOW_MSG_EC_BUILT("Send by the Video Control when a graph has been built. Not forwarded to applications.");
.... etc....
and my function
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
case EC_ACTIVATE: return DIRECTSHOW_MSG_EC_ACTIVATE;
case EC_BUFFERING_DATA: return DIRECTSHOW_MSG_EC_BUFFERING_DATA;
case EC_BUILT: return DIRECTSHOW_MSG_EC_BUILT;
... etc ...
No big deal. Took me 5 minutes to throw together.
... but I simply don't trust that I've got all the possible values, so I want to have a default to return something like "Unexpected notification code (7410)" if no matches are found.
Unfortunately, I can't think of anyway to return a valid pointer, without forcing the caller to delete the string's memory ... which is not only nasty, but also conflicts with the simplicity of the other return values.
So I can't think of any way to do this without changing the return value to a parameter where the user passes in a buffer and a string length. Which would make my function look like
BOOL GetDirectShowMessageDisplayText( int messageNumber, TCHAR* outBuffer, int bufferLength )
{
... etc ...
I really don't want to do that. There must be a better way.
Is there?
I'm coming back to C++ after a 10 year hiatus, so if it's something obvious, don't discount that I've overlooked it for a reason.
C++? std::string. It's not going to destroy the performance on any modern computer.
However if you have some need to over-optimize this, you have three options:
Go with the buffer your example has.
Have the users delete the string afterwards. Many APIs like this provide their own delete function for deleting each kind of dynamically allocated return data.
Return a pointer to a static buffer which you fill in with the return string on each call. This does have some drawbacks, though, in that it's not thread safe, and it can be confusing because the returned pointer's value will change the next time someone calls the function. If non-thread-safety is acceptable and you document the limitations, it should be all right though.
If you are returning a point to a string constant, the caller will not have to delete the string - they'll only have to if you are new-ing the memory used by the string every time. If you're just returning a pointer to a string entry in a table of error messages, I would change the return type to TCHAR const * const and you should be OK.
Of course this will not prevent users of your code to attempt to delete the memory referenced by the pointer but there is only so much you can do to prevent abuse.
Just declare use a static string as a default result:
TCHAR* GetDirectShowMessageDisplayText( int messageNumber )
{
switch( messageNumber )
{
// ...
default:
static TCHAR[] default_value = "This is a default result...";
return default_value;
}
}
You may also declare "default_value" outside of the function.
UPDATE:
If you want to insert a message number in that string then it won't be thread-safe (if you are using multiple threads). However, the solution for that problem is to use thread-specific string. Here is an example using Boost.Thread:
#include <cstdio>
#include <boost/thread/tss.hpp>
#define TCHAR char // This is just because I don't have TCHAR...
static void errorMessageCleanup (TCHAR *msg)
{
delete []msg;
}
static boost::thread_specific_ptr<TCHAR> errorMsg (errorMessageCleanup);
static TCHAR *
formatErrorMessage (int number)
{
static const size_t MSG_MAX_SIZE = 256;
if (errorMsg.get () == NULL)
errorMsg.reset (new TCHAR [MSG_MAX_SIZE]);
snprintf (errorMsg.get (), MSG_MAX_SIZE, "Unexpected notification code (%d)", number);
return errorMsg.get ();
}
int
main ()
{
printf ("Message: %s\n", formatErrorMessage (1));
}
The only limitation of this solution is that returned string cannot be passed by the client to the other thread.
Perhaps have a static string buffer you return a pointer to:
std::ostringstream ss;
ss << "Unexpected notification code (" << messageNumber << ")";
static string temp = ss.str(); // static string always has a buffer
return temp.c_str(); // return pointer to buffer
This is not thread safe, and if you persistently hold the returned pointer and call it twice with different messageNumbers, they all point to the same buffer in temp - so both pointers now point to the same message. The solution? Return a std::string from the function - that's modern C++ style, try to avoid C style pointers and buffers. (It looks like you might want to invent a tstring which would be std::string in ANSI and std::wstring in unicode, although I'd recommend just going unicode-only... do you really have any reason to support non-unicode builds?)
You return some sort of self-releasing smart pointer or your own custom string class. You should follow the interface as it's defined in std::string for easiest use.
class bstr_string {
_bstr_t contents;
public:
bool operator==(const bstr_string& eq);
...
~bstr_string() {
// free _bstr_t
}
};
In C++, you never deal with raw pointers unless you have an important reason, you always use self-managing classes. Usually, Microsoft use raw pointers because they want their interfaces to be C-compatible, but if you don't care, then don't use raw pointers.
The simple solution does seem to be to just return a std::string. It does imply one dynamic memory allocation, but you'd probably get that in any case (as either the user or your function would have to make the allocation explicitly)
An alternative might be to allow the user to pass in an output iterator which you write the string into. Then the user is given complete control over how and when to allocate and store the string.
On the first go-round I missed that this was a C++ question rather than a plain C question. Having C++ to hand opens up another possibility: a self-managing pointer class that can be told whether or not to delete.
class MsgText : public boost::noncopyable
{
const char* msg;
bool shouldDelete;
public:
MsgText(const char *msg, bool shouldDelete = false)
: msg(msg), shouldDelete(shouldDelete)
{}
~MsgText()
{
if (shouldDelete)
free(msg);
}
operator const char*() const
{
return msg;
}
};
const MsgText GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
case EC_ACTIVATE:
return MsgText("A video window is being activated or deactivated.");
// etc
default: {
char *msg = asprintf("Undocumented message (%u)", messageNumber);
return MsgText(msg, true);
}
}
}
(I don't remember if Windows CRT has asprintf, but it's easy enough to rewrite the above on top of std::string if it doesn't.)
Note the use of boost::noncopyable, though - if you copy this kind of object you risk double frees. Unfortunately, that may cause problems with returning it from your message-pretty-printer function. I'm not sure what the right way to deal with that is, I'm not actually much of a C++ guru.
You already use _bstr_t, so if you can just return those directly:
_bstr_t GetDirectShowMessageDisplayText(int messageNumber);
If you need to build a different message at runtime you can pack it into a _bstr_t too. Now the ownership is clear and the use is still simple thanks to RAII.
The overhead is negligible (_bstr_t uses ref-counting) and the calling code can still use _bstr_ts conversion to wchar_t* and char* if needed.
There's no good answer here, but this kludge might suffice.
const char *GetDirectShowMessageDisplayText(int messageNumber)
{
switch(messageNumber)
{
// ...
default: {
static char defaultMessage[] = "Unexpected notification code #4294967296";
char *pos = defaultMessage + sizeof "Unexpected notification code #" - 1;
snprintf(pos, sizeof "4294967296" - 1, "%u", messageNumber);
return defaultMessage;
}
}
}
If you do this, callers must be aware that the string they get back from GetDirectShowMessageText might be clobbered by a subsequent call to the function. And it's not thread safe, obviously. But those might be acceptable limitations for your application.