views:

78

answers:

2

I am using this code to get the windows version:

#define BUFSIZE 256

bool config::GetOS(LPTSTR OSv)
{
   OSVERSIONINFOEX osve;
   BOOL bOsVersionInfoEx;

   ZeroMemory(&osve, sizeof(OSVERSIONINFOEX));

   osve.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osve)) )
      return false;

   TCHAR buf[BUFSIZE];
   StringCchPrintf(buf, BUFSIZE, TEXT("%u.%u.%u.%u"), 
        osve.dwPlatformId,
            osve.dwMajorVersion,
            osve.dwMinorVersion,
            osve.dwBuildNumber);

   StringCchCat(OSv, BUFSIZE, buf);

   return true;
}

And I am testing it with:

LPTSTR OSv= new TCHAR[BUFSIZE];
config c;
c.GetOS(OSv);
MessageBox(OSv, 0, 0);

And in the msgbox I get something like this äì5.1.20 (where 5.1.20 is = to OSv) but the first 2 or 3 chars are some weird characters that I don't know when they came from. Even stranger, if I call that second piece again it shows it ok, it only show the weird characters the first time I execute it.

Does someone has an idea what's going on here?

+2  A: 

LPTSTR OSv= new TCHAR[BUFSIZE];. <-- You've not initialized the memory block. It's filled with random garbage.

You tagged your question C++ -- is there any reason you're not using a std::vector<wchar_t> or std::wstring here instead of manually managing memory?

std::wstring config::GetOS()
{
   OSVERSIONINFOEX osve;
   BOOL bOsVersionInfoEx;

   ZeroMemory(&osve, sizeof(OSVERSIONINFOEX));

   osve.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osve)) )
      return L"ERROR"; //Actually the right thing to do here is throw an exception
                       //but I could see how that could be a problem for some code

   std::wstringstream formatter;
   formatter << osve.dwPlatformId << L'.'
             << osve.dwMajorVersion << L'.'
             << osve.dwMinorVersion << L'.'
             << osve.dwBuildNumber;
   return formatter.str();
}
Billy ONeal
I dont know how to use std::I started using cpp a few days ago. What includes, etc do i need to use std?
extintor
`std` is the namespace in which entire standard library resides. You're probably learning with a `using namespace std;` somewhere which takes care of that for you, in which case you could remove the `std::` s from the above code. For the above code, you'll need `<sstream>` for `std::wstringstream`, and you'll need `<string>` for `std::wstring`.
Billy ONeal
Im trying to keep my project with the minimal includes posible, what libraries will "using namespace std;" add? Will the computers where the application run have to have installed something to make it work?
extintor
@extintor: All the standard library includes are provided by your C++ runtime. Of course if you `#include` a nonstandard header, such as `windows.h`, which relies on external DLLs and such, then you'll need those bits. Namespaces in C++ are strictly to prevent naming collisions. It's discouraged to import the standard namespace in production code though simply because you could conflict with standard library names.
Billy ONeal
formatter << osve.dwPlatformId << L'.' << osve.dwMajorVersion << L'.' << osve.dwMinorVersion << L'.' << osve.dwBuildNumber;is giving me only the first value (2) for dwPlatformId, any clue?
extintor
@extintor: No, I don't know why that might be happening. It works correctly on my compiler, and it should work correctly according to the standard. Check and make sure your stream's `failbit` isn't set.
Billy ONeal
+3  A: 

Your problem is that you should be using StringCchCopy and not StringCchCat.

StringCchCat will search until it finds a 0 in the string, and then append the result there. Since you are not initializing your output string buffer to 0's, you cannot assume it will start with a 0.

Brian R. Bondy
The root of the problem is the uninitialized memory block, but using copy instead of cat is one way to take care of that. +1.
Billy ONeal
likewise, either way works. The root problem is either in a misunderstanding of StringCchCat or forgetting to initialize the buffer.
Brian R. Bondy
How do I initialize the memory block?
extintor
@extintor: You would use ZeroMemory is the Win32 API way.
Brian R. Bondy