Access Denied when saving file in NT server
Hi,
my application is SDI and uses MFC architecture.
When it runs from my computer (XP Pro) works fine and saves the files in the server (Windows 2003).
When it runs from other computers (Windows 2000 Pro) it does not save the document in the server and reports the "Access to file .... denied" error. The application works fine when the file resides on the local PC.
All users have full access to the server and to the specific file.
Debugging the code, i have noticed that the Kernel 32 function "ReplaceFile" called from the CDocument class fails when the program runs in Windows 2000.
Any ideas to overcome this?
Thanks in advance.
Re: Access Denied when saving file in NT server
The problem seems to be a bug in Windows 2000 only.
Perhaps Microsoft has more urgent things to do (i.e. releasing anti-exploit hotfixes) than helping programmers out.
I can confirm that the problem does *not* exist when you invoke the "ReplaceFile" method under Windows XP. And it works fine under Windows NT4 too (and noone needed to know that, but what the heck ;-) )
- - -
I have just written a work-around that kicks in under Windows 2000 only. All other Windows versions will perform as hitherto.
In Visual Studio 6 I right clicked the document class and added a virtual function "OnSaveDocument".
I then entered the following contents (hope it'll be readable when I Ctrl+V Paste it in):
BOOL MyDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
// Coffee Zombie: Modified 2005-11-02:
//return CDocument::OnSaveDocument(lpszPathName);
bool bDoWin2kWorkAround = false;
char* pcBakFile = NULL;
OSVERSIONINFO OSinf;
OSinf.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&OSinf);
if (OSinf.dwPlatformId==VER_PLATFORM_WIN32_NT) // Windows NT 3, Windows 2000 or Windows XP or newer (not Win3.x or Win95 to WinME)
{
if (OSinf.dwMajorVersion==5) // Windows 2000 or XP
{
if (OSinf.dwMinorVersion==0) // Windows 2000
{
// Must do a work-around for buggy ReplaceFile method in KERNEL32 under Windows 2000 only:
pcBakFile = new char[strlen(lpszPathName)+10];
if (pcBakFile!=NULL) // Avoid out-of-memory errors:
{
// Rename any existing file to "*.*.bak":
strcpy(pcBakFile,lpszPathName);
strcat(pcBakFile,".bak");
::remove(pcBakFile); // Ignore error
DWORD dwRc = ::rename(lpszPathName,pcBakFile);
if (dwRc==0)
bDoWin2kWorkAround = true; // We succeded in renaming an existing file!
else
{
// We did not succeed in renaming the existing file.
// This either means that no file exists, or that some access priviledge is missing.
// Ignore error and fall through to normal behaviour: ....
}
}
}
}
}
BOOL bSuccess = CDocument::OnSaveDocument(lpszPathName);
if (bDoWin2kWorkAround)
{
if (bSuccess)
{
// We did it!
// Now clean up:
::remove(pcBakFile);
// Ignore error. After all it's only a temp file.
}
else
{
// An error occurred!
// Rename the original file back:
try
{
CFile::Rename(pcBakFile,lpszPathName);
}
catch (CFileException exFile)
{
exFile.ReportError();
}
}
}
if (pcBakFile!=NULL)
{
delete pcBakFile;
pcBakFile = NULL;
}
return bSuccess;
// .. Coffee Zombie
} // MyDoc::OnSaveDocument
Re: Access Denied when saving file in NT server
Ok then... I'll attach a file next time!
Re: Access Denied when saving file in NT server
Hello C Z,
From MSDN on CreateFile(...) - I'm not sure if this may help.
Jeff
Quote:
Files
If you try to create a file on a floppy drive that does not have a floppy disk or a CD-ROM drive that does not have a CD, the system displays a message for the user to insert a disk or a CD. To prevent the system from displaying this message, call the
SetErrorMode function with SEM_FAILCRITICALERRORS.
Windows Server 2003 and Windows XP/2000: If CREATE_ALWAYS and FILE_ATTRIBUTE_NORMAL are specified, CreateFile fails and sets the last error to ERROR_ACCESS_DENIED if the file exists and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_SYSTEM attribute. To avoid the error, specify the same attributes as the existing file.
For more information, see
Creating and Opening Files.
If you rename or delete a file and then restore it shortly afterward, the system searches the cache for file information to restore. Cached information includes its short/long name pair and creation time.
Windows Me/98/95: This remark does not apply.
If you call
CreateFile on a file that is pending deletion as a result of a previous call to
DeleteFile, the function fails. The operating system delays file deletion until all handles to the file are closed.
GetLastError returns ERROR_ACCESS_DENIED.
Re: Access Denied when saving file in NT server
Hi CZ,
This is a bit OT, but here goes.
One of my help desk technicians had a similar (not exact) problem under Windows XP workstation and Windows 2000 Server. In the end, we rejoined her computer to the domain.
Quote:
We have 'Modify' access to the files we own.
The Security Attributes property page will sometimes lie to you. Use cacls.exe instead for problems like yours when investigating permission issues.
Also, CODE tags on your post would improve readability :).
Jeff
Re: Access Denied when saving file in NT server
Coffee Zombie / Jeffrey
Many thanks for your replies.
I had worked out the problem in a way much similar to Coffee Zombie Code.
The key is to use MFC to replace the file and not KERNEL.
I haven't tried CZ Code yet but I don't see why it shouldn't work.