RESOLUTION
To work around this problem, an application can implement its own "Replace File" routine and not specify WRITE_DAC access when it opens the replacement file. Following is sample code to demonstrate this approach.
Sample Code
The following sample code implements a simple replace file function that does not require WRITE_DAC access to the replacement file. Note that this routine does not have all the features of the Windows 2000
ReplaceFile function. That is, this routine does not preserve the following attributes of the original file:
- Short file name
- Object identifier
- DACLs
- Encryption
- Compression
- Named streams not already in the replacement file
BOOL SimpleReplaceFile(LPTSTR szReplaced, LPTSTR szReplacement) {
HANDLE hReplaced = INVALID_HANDLE_VALUE;
BOOL fSuccess = FALSE;
WIN32_FILE_ATTRIBUTE_DATA fad;
__try {
// Validate parameters.
if (szReplaced == NULL || szReplacement == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
__leave;
}
// Retrieve attributes from the file to be replaced.
if (!GetFileAttributesEx(szReplaced, GetFileExInfoStandard, &fad))
__leave;
// Delete the file that is being replaced.
if (!DeleteFile(szReplaced))
__leave;
// Rename the replacement file.
if (!MoveFile(szReplacement, szReplaced))
__leave;
// This is enough to report success.
fSuccess = TRUE;
// Try to preserve the following attributes from the original file:
fad.dwFileAttributes &= FILE_ATTRIBUTE_ARCHIVE
| FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_NORMAL
| FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
| FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_TEMPORARY;
if (!SetFileAttributes(szReplaced, fad.dwFileAttributes))
__leave;
// Try to set the creation time to match the original file.
hReplaced = CreateFile(szReplaced, 0, FILE_SHARE_READ
| FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, 0, NULL);
if (hReplaced == NULL)
__leave;
if (!SetFileTime(hReplaced, &(fad.ftCreationTime), NULL, NULL))
__leave;
} __finally {
if (hReplaced != INVALID_HANDLE_VALUE)
CloseHandle(hReplaced);
}
return fSuccess;
}