Microsoft KB Archive/274487

{|
 * width="100%"|

BUG: ReplaceFile Requires WRITE_DAC Access on Replacement File

 * }

Q274487

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * the operating system: Microsoft Windows 2000

-

SYMPTOMS
The ReplaceFile function in Windows 2000 replaces one file (the &quot;replaced file&quot;) with another file (the &quot;replacement file&quot;). This function doesn't work if the calling user does not have access to open the replacement file with WRITE_DAC permission. This situation is likely to occur if the replacement file resides on an NTFS network share to which the user has only change and/or read access.

CAUSE
To obtain WRITE_DAC access for a file on a network share, either the caller must have full control over the share or the caller must be an administrator on the remote server.

RESOLUTION
To work around this problem, an application can implement its own &quot;Replace File&quot; 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; }

STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.

Additional query words:

Keywords : kbAPI kbFileIO kbKernBase kbOSWin2000bug kbSDKWin32 kbSecurity kbDSupport kbGrpDSKernBase

Issue type : kbbug

Technology : kbAudDeveloper kbWin32sSearch kbWin32API