Your code should be something like more like this:
errno_t result = fopen_s(&plltCreateFile, fqnCreate,"w"));
if(result != 0)
{
...
}
else
{
....
fclose(pltCreateFile);
}
Main Topics
Browse All TopicsI recently got charged with updating / modifying an existing C++ DLL. I starting updating some of the functions to their security-friendly counterparts and am running into problems.
It seems that I am having problems with my change of fopen() to fopen_s(). For some reason the files aren't closing anymore, since I can't open them in windows. I get an access violation saying another program is still accessing it.
So my question is: What all do I need to do to update to fopen_s()?
<snip>
//if( (plltCreateFile = fopen(fqnCreate,"w")) == NULL) //Old code
if( (fopen_s(&plltCreateFile, fqnCreate,"w")) == NULL)
{
returnValue = (-1);
}
else
{
// New stuff
sprintf_s(fqnLine,"%sIn\\l
fprintf(plltCreateFile,"%s
fclose(plltCreateFile);
plltCreateFile = NULL;
}
I don't have a great deal of experience with C++, so any help is greatly appreciated.
--Charly
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
You are converting code that is using POSIX compliant functions to Microsoft's "secure" versions. Question -- why? What is your rational? Because Microsoft said so? If you ever need to port this code it'll be a can of worms you'll have to open all over again! Besides, I wonder, are these functions really anymore secure than their Posix counterparts?
If you are prepared to go down this route I'd just bite the bullet and convert the code base to use STL streams. You'll get all the flexibility of streams with all the portability of STL (did I really say that?).
Your example rewritten is something like this...
#include <fstream>
#include <sstream>
int main() // Exception handling omitted for clarity
{
int retval = -1;
std::ofstream fs("myfile.txt");
if(fs.is_open())
{
std::stringstream ssLine;
ssLine
<< Zebra.shareName
<< "In\\"
<< LineNumber
<< ".dat";
fs
<< PalletCreate(ssLine.str().
<< std::endl;
retval = fs.good() ? 0 : -1;
}
return retval;
}
>>>> You are converting code that is using POSIX compliant
>>>> functions to Microsoft's "secure" versions.
There is nothing wrong with that as long as you accept that it is not portable. The _s functions check input parameters and throw exceptions if for example you are passing a NULL pointer.
>>>> if( (fopen_s(&plltCreateFile, fqnCreate,"w")) == NULL)
The problem is that fopen_s returns errno_t (and not FILE pointer). So, the fopen_s returns 0 for success and the code in the else branch never was called. See http://msdn2.microsoft.com
Regards, Alex
>>>> I didn't say it was wrong
You said:
- Because Microsoft said so?
- it'll be a can of worms you'll have to open all over again!
- I wonder, are these functions really anymore secure than
their Posix counterparts?
I would interpret your statements as a non-recommendation and calling that 'pointing out possibles issue of portability' surely is a euphemism. Are you a politician?
MS made a lot of bad attempts to prevent developers from making portable code. The _s functions maybe is one of these attempts but the idea to have more secure wrappers for some old and unsafe runtime functions is good and you easily could add these function wrappers to any other system/platform if needed for portability without 'opening a can of worms'.
Actually, I don't have much experience with C++ at all, so all I did was do a bit of google research on the warnings the compiler was giving me. That's pretty much the whole rationale for it. I just don't want to leave a legacy of crappy code behind for the next guy. So if it isn't necessary to update it I would actually prefer to leave it as is.
Are there any significant risks in not updating it? The DLL in question is just a small, couple 100 line program which I need to invoke Windows system calls (print, file I/O) from a PLC controller (Programmable Logic Computer, used in the automation industry).
Thanks again for the advice guys.
--Charly
dleehanson: -
Based upon your rational, it is my opinion that these changes are unnecessary. Providing Posix compliant functions are used correctly, they are just as safe as Microsoft's "secure" versions. If the code already works without problem and there is no other compelling reason than to do so I wouldn't change it. The more you change the more you break!
You can disable the warnings very simply by defining the following macro as a compile time parameter to the compiler: _CRT_SECURE_NO_WARNINGS (set this in the project settings). Alternatively, if you just want to disbale the warnings specifically at source you can just use a #pragma warning block around the offending lines.
More info can be found here...
http://msdn2.microsoft.com
I hope this helps.
Good luck :)
No, it doesn't look like the previous developer did that. Here is all I think he does:
if( (plltCreateFile = fopen(fqnCreate,"w")) == NULL)
{
returnValue = (-1);
}//PLLTCREAT dat can't be created
else
{
// New stuff
sprintf(fqnLine,"%sIn\\lin
fprintf(plltCreateFile,"%s
fclose(plltCreateFile);
plltCreateFile = NULL;
}//PLLTCREAT dat file can be created
If the code is running as a DLL, there isn't a console to print to, correct? So what would happen if I put that code in there? A console pops up? It gets ignored? Throws an exception?
Thanks for the continued help.
--Charly
>>>> Are there any significant risks in not updating it?
No. There are no risks in updating it to fopen_s and to not updating it.
>>>> What all do I need to do to update to fopen_s()?
You have to change the if statement to
errno_t ret = 0;
if( (ret = fopen_s(&plltCreateFile, fqnCreate,"w")) != 0) // NOTE, ret == 0 is SUCCESS
{
returnValue = ret; // we got an error
}
else
{
...
}
Regards, Alex
>>>> You can disable the warnings very simply by defining the following macro
Actually, you got some funny advice here.
At the one hand you should not change old code (though it is only a change from == to !=) and at the other hand you should add code to suppress warnings.
If there is any unnecessary change then code to suppress warnings is the most unnecessary one.
>>>> The Posix functions (like any tool) are safe when used safely.
Yes, and the sky is blue and the meadow is green.
evilrix, the fopen_s wasn't the problem but only the wrong interpretation of the return value. And it won't be an issue even if you will post another 100 comments with wild attacks against MS.
Ok, I don't want to get into needless debate about this, but...
(a) I wasn't advocating... I was providing information, how it is used is up to the reader.
(b) It's not a code change, it's a simple project setting, hence I stated "(set this in the project settings)".
(c) The MSDN page I provided gives details of how to do this and what is involved!
If he's happy with the warnings fine, if he's not and would like to suppress them this will do it!
All I added was code to suppress the one type of warning
#pragma warning(disable : 4996):
Are there any other further ranging effects to doing this? If anything it just makes things easier to debug, since I don't get a horde of warnings all the time.
I'm also getting this warning:
warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
Can I supress this too, or is there an important problem to address here?
Thanks everyone.
--Charly
>>Are there any other further ranging effects to doing this?
Usually not. The old code will compile.
>> warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO'
>>specification
You can safely ignore that one. '/EDITANDCONTINUE' means that you can change the code during debugging (which in some cases can be useful) and that this is being disabled.
I would add the project macro I stated above as it will be global (and doesn't change any code). The only effect of this setting is to suppress warnings about "insecure" functions!
The other warning is because you have edit and continue enabled with incremental linking disabled. Just disable the former or enable the latter; but make sure you know what both these settings do before you decide which to change!
jkr,
There isn't anything wrong when I run the original code. I don't get any files hanging open etc. The problems arose when I was making changes, which I plan on not doing now.
evilrix,
I think I know what edit and continue means, but not what incremental linking is. All I do is compile my project and copy it into my PLC test program, so I don't really need any fancy debugging features in VS.
--Charly
>>>> warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
>>>> Can I supress this too, or is there an important problem to address here?
It is a linker warning that only happens in debug mode. Your debugger was able to 'compile on the fly' while debugging, but the option was discarded because of project settings. Actually it is a MS bug and has *no* importance. You can safely ignore it.
Incremental Linking -- in detail...
http://www.airs.com/blog/a
Ok, I think I have gotten all of my questions answered on this topic. Here's how I am going to do the points:
125 to peetm for answering my initial question
75 to evilrix, itsmeandnobodyelse, and jkr for helping with all the subsequent questions.
I hope this seems fair to everyone as I greatly appreciate everyone's help.
--Charly
Business Accounts
Answer for Membership
by: peetmPosted on 2007-10-24 at 14:04:41ID: 20142900
The docs for fopen_s say that the function returns 0 for success. As NULL is most often #defined as 0 surely your code shows that the function fails if it actually works!?
So, your fclose() call is in the wrong branch - and doesn't get called in other words??