movefile() fails error 2 or 123 - c++

I'm updating a c++ routine to move files that was written in visual studio express 2008/2010. I'm now running VS Express 2012
Obviously there are changes to the compiler because string functions have to be upgraded to strcpy_s etc. No problem. This is a console app. I never extended my C++ knowledge past C++ to C# etc. as I need little more than to be able to write small utils to do things on the command line. Still I'm able to write somewhat complex utilities.
My issue is movefile() function always fails to move with either error 2 or 123. I'm working in C:\users\alan\downloads folder so I know I have permission. I know the file is there. Small snippet of code is:
char source=".\\test.txt"; // edited for clarity.
char dest=".\\test.txt1";
printf("\nMove\n %s\n to %s\n",source,dest); // just to see what is going on
MoveFile((LPCWSTR) source, (LPCWSTR) dest);
printf("Error %u\n",GetLastError());
output is :
Move
.\test.txt
to .\test.txt1
Error 2
All of my strings are simple char strings and I'm not exactly sure, even after reading, what LPCWSTR was type def'd for and if this is the culprit. So to get this to compile I simply typedef'd my strings. And it compiles. But still it won't move the files.
The code is more complex in developing the source & dest variables but I've reduce it to a simple "just append a 1 to the file name" situation to see if I can just simply rename it. I thought C:\xxx\yyy\zzz\test.txt was maybe wrong in some fashion but that idea fell though with the above test. I've done it with and without the .\ same issue. I'm running out of ideas other than making my own fileopen read/write binary function to replace movefile(). I'm really against that but if I have to I will.
EDIT: I pasted the printf from original code that used FullPathName, I've corrected the snippet.

The fact that you are casting your arguments to LPCWSTR suggests that you are compiling your program with UNICODE defined, which means you are calling MoveFileW and the compiler warned about an argument type mismatch.
Inserting a cast does not fix that. You are telling the compiler to stop complaining, but you haven't actually fixed the problem (the underlying data is still wrong).
Actual solutions:
Use WCHAR as MoveFileW expects (or TCHAR/LPTSTR and the _T macro).
Explicitly call MoveFileA
Compile without UNICODE defined.

Thanks Andrew Medico. I used MoveFileA and the program seems to work now.
I'm not sure I turned off unicode, but I did change one item in the properties.
I'll need to read up on the compiler about unicode/ansi settings. But for now the issue is fixed and I'm sure I've got the idea of what I need to do. "research"!!!!

Related

Pass CString to fprintf

I have ran the code analyzer in visual studio on a large code base and i got about a billion of this error:
warning C6284: Object passed as parameter '3' when string is required in call to 'fprintf'
According to http://msdn.microsoft.com/en-us/library/ta308ywy.aspx "This defect might produce incorrect output or crashes." My colleague however states that we can just ignore all these errors without any problems. So one of my questions is do we need to do anything about this or can we just leave it as is?
If these errors need to be solved what is the nicest approach to solve it?
Would it work to do like this:
static_cast<const char*>(someCString)
Is there a better or more correct approach for this?
The following lines generate this warning:
CString str;
fprintf(pFile, "text %s", str);
I'm assuming that you're passing a Microsoft "CString" object to a printf()-family function where the corresponding format specifier is %s. If I'm right, then your answer is here: How can CString be passed to format string %s? (in short, your code is OK).
It seems that originally an implementation detail allowed CString to be passed directly to printf(), and later it was made part of the contract. So you're good to go as far as your program being correct, but if you want to avoid the static analysis warning, you may indeed need to use the static_cast to a char pointer. I'm not sure it's worth it here...maybe there's some other way to make these tools place nice together, since they're all from Microsoft.
Following the MSDN suggestions in C6284, you may cast the warnings away. Using C++ casts will be the most maintainable option to do this. Your example above would change to
fprintf(pFile, "text %s", static_cast<const TCHAR*>(str));
or, just another spelling of the same, to
fprintf(pFile, "text %s", static_cast<LPCTSTR>(str));
The most convincing option (100% cast-free, see Edits section) is
fprintf(pFile, "text %s", str.GetString());
Of course, following any of these change patterns will be a first porting step, and if nothing indicates a need for it, this may be harmful (not only for your team atmosphere).
Edits: (according to the comment of xMRi)
1) I added const because the argument is read-only for fprintf
2) notes to the cast-free solution CSimpleStringT::GetString: the CSimpleStringT class template is used for the definition of CStringT which again is used to typedef the class CString used in the original question
3) reworked answer to remove noise.
4) reduced the intro about the casting option
Technically speaking it is ok because the c-string is stored in such a way in CString that you can use it as stated but it is not good rely on how CString is implemented to do a shortcut. printf is a C-runtime function and knows nothing about C++ objects but here one is relying on an that the string is stored first in the CString - an implementation detail.
If I recall correctly originally CString could not be used that way and one had to cast the CString to a c-string to print it out but in later versions MS changed the implementation to allow for it to be treated as a c-string.
Another breaking issue is UNICODE, it will definitely not work if you one day decide to compile the program with UNICODE character set since even if you changed all string formatters to %ld, embedded 0s will sometimes prevent the string from being printed.
The actual problem is rather why are you using printf instead of C++ to print/write files?

Strange strings in executable VC++

I created simple C++ Hello world program, then I compiled it using MSVC++, and then I looked into executable using Notepad++ (I know it is not the best program to open binary files with it, but I wanted to know, if there are any human readable strings). I found there strings like A cast to a smaller data type has caused a loss of data. If this was intentional, you should mask the source of the cast with the appropriate bitmask.
The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
What are those strings, and where they came from, and how I can get rid of them?
All constant strings are human readable through the use of a text editor. Try looking for "hello world" in your program and it will pop up. (ran into this for the first time when we were trying to figure out if obfuscating our opencl code was worth it...it wasn't).
These strings are the error strings that windows throws on top of every executable. I have no idea how to get rid of them.

Replacing CString in mingw compiler for eclipse

I have some code which is relatively big, but there is one part of it which uses something called CString (http://msdn.microsoft.com/en-us/library/aa300688%28v=vs.60%29.aspx) . Right now I am using the mingw compiler on eclipse and it doesnt seem to recognize it which makes sense. But I need to use the other part of the code. I know I can replace the CString with a const char * but there are several function like append which the code uses which are not defined. I was wondering whats the best way to port this code? Also there are other stdafx.h dependencies also like _T(). Whats the best approach I should take now?
There is a CString replacement over on CodeProject. I just googled for "CString alternative". I haven't looked at it but it should be easier to use that instead of std::string.

What is causing boost::lower to fail an is_singular assertion?

I am occasionally getting odd behavior from boost::lower, when called on a std::wstring. In particular, I have seen the following assertion fail in a release build (but not in a debug build):
Assertion failed: !is_singular(), file C:\boost_1_40_0\boost/range/iterator_range.hpp, line 281
I have also seen what appear to be memory errors after calling boost::to_lower in contexts such as:
void test(const wchar_t* word) {
std::wstring buf(word);
boost::to_lower(buf);
...
}
Replacing the calls boost::tolower(wstr) with std::transform(wstr.begin(), wstr.end(), wstr.begin(), towlower) appears to fix the problem; but I'd like to know what's going wrong.
My best guess is that perhaps the problem has something to do with changing the case of unicode characters -- perhaps the encoding size of the downcased character is different from the encoding size of the source character?
Does anyone have any ideas what might be going on here? It might help if I knew what "is_singular()" means in the context of boost, but after doing a few google searches I wasn't able to find any documentation for it.
Relevant software versions: Boost 1.40.0; MS Visual Studio 2008.
After further debugging, I figured out what was going on.
The cause of my trouble was that one project in the solution was not defining NDEBUG (despite being in release mode), while all the other modules were. Boost allocates some extra fields in its data structures, which it uses to store debug information (such as whether a data structure has been initialized). If module A has debugging turned off, then it will create data structures that don't contain those fields. Then when module B, which has debugging turned on, gets its hands on that data structure, it will try to check those fields (which were not allocated), resulting in random memory errors.
Defining NDEBUG in all projects in the solution fixed the problem.
An iterator range should only be singular if it's been constructed with the default constructor (stores singular iterators, i.e doesn't represent a range). As it's rather hard to believe that the boost's to_lower function manages to create a singular range, it suggests that the problem might also be elsewhere (a result of some undefined behavior, such as using uninitialized variables which might be initialized to some known value in debug builds).
Read more on Heisenbugs.

Not naming a type - C++

I am trying to convert an Adobe CS4 based plugin to CS5. This project has never been mine, this is the first time that i am seeing it.
When I compile the source with what i was given, I get errors like: Does not name a type
Example:
SPAPI SPErr SPBasicAcquireSuite( const char *name, int64 version, const void **suite );
I get that:
SPErr does not name a type
I dont see any classes with SPErr being defined, but I doubt that Adobe has left this out of the SDK.
I am using the PS_CS5_SDK_3 SDK
I do not have the possibility to be specific because, of course, I do not have the code. Typically this problem occurs when a type, a class, is not correctly compiled by compiler... meaning that it cannot find it and asks: "what is this?". See macros, or better inspect your code in your hpp files... Probably when porting to CS5 some types have been removed or some...