View Issue Details

IDProjectCategoryView StatusLast Update
0000503Far ManagerSetAttrpublic2009-12-04 16:18
Reporteralexmitin Assigned Toalexy  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionunable to reproduce 
Summary0000503: Access denied error while setting the file attributes
DescriptionProblem
----------------
There is an access denied error while setting the file attributes.


Steps to reproduce:
-----------------------
1) Create a file c:\111\myfile.txt and assign the following permissions to it:
  
   Administrators: Full Control
   User: Read Attributes, Write Attributes

2) Start FAR under limited user account (not administrator)
3) Presss Ctrl+A on the c:\111\myfile.txt
4) Set the following attributes:

   [x] Read only
   [x] Archive
   [x] Hidden
   [x] System
   [ ] Compressed
   [ ] Encrypted
   [x] Not Indexed
   File modification time: current time
   File modification time: current time
   File modification time: current time

5) Press "Set"


Actual result
----------------------
Error: "Access denied. Cannot set attributes for 111.txt"


Expected result
----------------------
The file attributes are set according to specification on step 4.


Same problem exists for changing folder attributes. Just repeat steps 1 to 5 for folder instead of file.


Analysis
=========================
File: setattr.cpp

int ShellSetFileAttributes(Panel *SrcPanel)
{
...
    if (SelCount==1 && (FileAttr & FA_DIREC)==0)
    {
      if(IsFileWritable(strSelName,FileAttr,TRUE,MSetAttrCannotFor) == 1) <==[bug.1]==
      {
...
  if (CheckForEsc())
    break;

  RetCode=IsFileWritable(strSelName,FileAttr,TRUE,MSetAttrCannotFor); <==[bug.1]==
  if(!RetCode)
    break;
...
}

[bug.1] The function IsFileWritable() should not be called while setting the attributes. Using this function prevents the rest of the code to function correctly.

------------------
File: setattr.cpp

static int ReadFileTime(
   int Type,
   const wchar_t *Name,
   DWORD FileAttr,
   FILETIME *FileTime,
   const wchar_t *OSrcDate,
   const wchar_t *OSrcTime
)
{
...
  HANDLE hFile= apiCreateFile(
    Name,
    GENERIC_READ, <==[bug.2]== should be FILE_READ_ATTRIBUTES
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS : 0,
    NULL
  );
  if (hFile==INVALID_HANDLE_VALUE)
      return(FALSE);
...
}

[bug.2] The access right should be FILE_READ_ATTRIBUTES, not GENERIC_READ because we just need to get file times (via GetFileTime).


------------------
File: fileattr.cpp

int ESetFileTime(
  const wchar_t *Name,
  FILETIME *LastWriteTime,
  FILETIME *CreationTime,
  FILETIME *LastAccessTime,
  int FileAttr <==[bug.3]==
)
{
...
  HANDLE hFile=apiCreateFile(
    Name,
    GENERIC_WRITE, // <==[bug.4]== should be FILE_WRITE_ATTRIBUTES
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS : 0,
    NULL
  );
...
  SetTime = SetFileTime(hFile,CreationTime,LastAccessTime,LastWriteTime);
...
}

[bug.3] The type of the FileAttr parameter should be DWORD (not int).

[bug.4] The access right should be FILE_WRITE_ATTRIBUTES, not GENERIC_WRITE because we need to update file times (via SetFileTime).

See http://msdn2.microsoft.com/en-us/library/aa364399(VS.85).aspx the definition of FILE_WRITE_ATTRIBUTES and GENERIC_WRITE.

-----------
int ESetFileAttributes(const wchar_t *Name,int Attr) <==[bug.5]==
{
...
}

[bug.5] The type of the Attr parameter should be DWORD (not int).

-----------

int ESetFileEncryption(const wchar_t *Name,int State,int FileAttr,int Silent) <==[bug.6]==
{
...
}

[bug.6] The type of the FileAttr parameter should be DWORD (not int).
Additional InformationFAR 1.80.0.452
TagsNo tags attached.
Build0

Activities

2008-03-20 01:33

 

fix503.diff (29,017 bytes)   
Index: fileattr.cpp
===================================================================
--- fileattr.cpp	(revision 1567)
+++ fileattr.cpp	(working copy)
@@ -216,9 +216,15 @@
     if (FileAttr & FA_RDONLY)
       SetFileAttributesW(Name,FileAttr & ~FA_RDONLY);
 
-    HANDLE hFile=apiCreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
-                 NULL,OPEN_EXISTING,
-                 (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
+    HANDLE hFile=apiCreateFile(
+        Name,
+        FILE_WRITE_ATTRIBUTES,
+        FILE_SHARE_READ | FILE_SHARE_WRITE,
+        NULL,
+        OPEN_EXISTING,
+        (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS : 0,
+        NULL
+    );
     int SetTime;
     DWORD LastError=0;
     if (hFile==INVALID_HANDLE_VALUE)
Index: setattr.cpp
===================================================================
--- setattr.cpp	(revision 1567)
+++ setattr.cpp	(working copy)
@@ -109,27 +109,32 @@
 
   void Clear()
   {
-  	Plugin = 0;
-  	FileSystemFlags = 0;
-  	ModeDialog = 0;
-  	DateFormat = 0;
-  	strSelName = L"";
-  	memset(OriginalCBAttr,0,sizeof(OriginalCBAttr));
-  	memset(OriginalCBAttr2,0,sizeof(OriginalCBAttr2));
-  	memset(OriginalCBFlag,0,sizeof(OriginalCBFlag));
-  	OStateF_12 = 0;
-  	OStateC_8 = 0;
-  	OStateC_9 = 0;
-  	OLastWriteTime = 0;
-  	OCreationTime = 0;
-  	OLastAccessTime = 0;
-  	strFSysName = L"";
+    Plugin = 0;
+    FileSystemFlags = 0;
+    ModeDialog = 0;
+    DateFormat = 0;
+    strSelName = L"";
+    memset(OriginalCBAttr,0,sizeof(OriginalCBAttr));
+    memset(OriginalCBAttr2,0,sizeof(OriginalCBAttr2));
+    memset(OriginalCBFlag,0,sizeof(OriginalCBFlag));
+    OStateF_12 = 0;
+    OStateC_8 = 0;
+    OStateC_9 = 0;
+    OLastWriteTime = 0;
+    OCreationTime = 0;
+    OLastAccessTime = 0;
+    strFSysName = L"";
   }
 };
 
-static int IsFileWritable(const wchar_t *Name, DWORD FileAttr, BOOL IsShowErrMsg, int Msg);
-static int ReadFileTime(int Type,const wchar_t *Name,DWORD FileAttr,FILETIME *FileTime,
-                       const wchar_t *OSrcDate, const wchar_t *OSrcTime);
+static int ReadFileTime(
+    int Type,
+    const wchar_t *Name,
+    DWORD FileAttr,
+    FILETIME *FileTime,
+    const wchar_t *OSrcDate,
+    const wchar_t *OSrcTime
+);
 static void PR_ShellSetFileAttributesMsg(void);
 void ShellSetFileAttributesMsg(const wchar_t *Name);
 
@@ -618,17 +623,17 @@
             ConvertDate(FindData.ftCreationTime,  AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData,8,FALSE,FALSE,TRUE,TRUE);
             ConvertDate(FindData.ftLastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData,8,FALSE,FALSE,TRUE,TRUE);
           }
-          AttrDlg[SETATTR_RO].Selected=(FileAttr & FA_RDONLY)!=0;
-          AttrDlg[SETATTR_ARCHIVE].Selected=(FileAttr & FA_ARCH)!=0;
-          AttrDlg[SETATTR_HIDDEN].Selected=(FileAttr & FA_HIDDEN)!=0;
-          AttrDlg[SETATTR_SYSTEM].Selected=(FileAttr & FA_SYSTEM)!=0;
-          AttrDlg[SETATTR_COMPRESSED].Selected=(FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0;
-          AttrDlg[SETATTR_ENCRYPTED].Selected=(FileAttr & FILE_ATTRIBUTE_ENCRYPTED)!=0;
-          AttrDlg[SETATTR_INDEXED].Selected=(FileAttr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)!=0;
-          AttrDlg[SETATTR_SPARSE].Selected=(FileAttr & FILE_ATTRIBUTE_SPARSE_FILE)!=0;
-          AttrDlg[SETATTR_TEMP].Selected=(FileAttr & FILE_ATTRIBUTE_TEMPORARY)!=0;
-          AttrDlg[SETATTR_OFFLINE].Selected=(FileAttr & FILE_ATTRIBUTE_OFFLINE)!=0;
-          AttrDlg[SETATTR_VIRTUAL].Selected=(FileAttr & FILE_ATTRIBUTE_VIRTUAL)!=0;
+          AttrDlg[SETATTR_RO].Selected         = (FileAttr & FA_RDONLY)!=0;
+          AttrDlg[SETATTR_ARCHIVE].Selected    = (FileAttr & FA_ARCH)!=0;
+          AttrDlg[SETATTR_HIDDEN].Selected     = (FileAttr & FA_HIDDEN)!=0;
+          AttrDlg[SETATTR_SYSTEM].Selected     = (FileAttr & FA_SYSTEM)!=0;
+          AttrDlg[SETATTR_COMPRESSED].Selected = (FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0;
+          AttrDlg[SETATTR_ENCRYPTED].Selected  = (FileAttr & FILE_ATTRIBUTE_ENCRYPTED)!=0;
+          AttrDlg[SETATTR_INDEXED].Selected    = (FileAttr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)!=0;
+          AttrDlg[SETATTR_SPARSE].Selected     = (FileAttr & FILE_ATTRIBUTE_SPARSE_FILE)!=0;
+          AttrDlg[SETATTR_TEMP].Selected       = (FileAttr & FILE_ATTRIBUTE_TEMPORARY)!=0;
+          AttrDlg[SETATTR_OFFLINE].Selected    = (FileAttr & FILE_ATTRIBUTE_OFFLINE)!=0;
+          AttrDlg[SETATTR_VIRTUAL].Selected    = (FileAttr & FILE_ATTRIBUTE_VIRTUAL)!=0;
 
           // ������� 3-State
           for(I=SETATTR_ATTR_FIRST; I <= SETATTR_ATTR_LAST; ++I)
@@ -636,15 +641,15 @@
         }
         FolderPresent=TRUE;
 
-        // ��������� ����, ���� ��� SymLink
-        if(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT)
+        // ��������� ����, ���� ��� reparse point
+        if( FileAttr & FILE_ATTRIBUTE_REPARSE_POINT )
         {
           string strJuncName;
-          DWORD LenJunction=GetJunctionPointInfo(strSelName, strJuncName);
+          DWORD dwReparsePointTag = GetJunctionPointInfo(strSelName, strJuncName);
           //"\??\D:\Junc\Src\" ��� "\\?\Volume{..."
 
           AttrDlg[SETATTR_TITLE].Y2++;
-          for(I=3; I  < DlgCountItems; ++I)
+          for(I=3; I < DlgCountItems; ++I)
           {
             AttrDlg[I].Y1++;
             if (AttrDlg[I].Y2)
@@ -654,7 +659,7 @@
           JunctionPresent=TRUE;
 
           int ID_Msg, Width;
-          if(!wcsncmp((const wchar_t*)strJuncName+4,L"Volume{",7))
+          if(!wcsncmp((const wchar_t*)strJuncName,L"\\??\\Volume{",11))
           {
             string strJuncRoot;
             GetPathRootOne((const wchar_t*)strJuncName+4,strJuncRoot);
@@ -662,9 +667,9 @@
             wchar_t *lpwszJunc = strJuncName.GetBuffer ((int)strJuncRoot.GetLength()+5);
 
             if(strJuncRoot.At(1) == L':')
-              wcscpy(lpwszJunc+4,strJuncRoot);
+              wcscpy(lpwszJunc+4, strJuncRoot);
 
-            strJuncName.ReleaseBuffer ();
+            strJuncName.ReleaseBuffer();
 
             ID_Msg=MSetAttrVolMount;
             Width=38;
@@ -675,13 +680,20 @@
             Width=52;
           }
 
-          string strJuncTemp = (const wchar_t*)strJuncName+4;
+          int iOffset = 0;
+          if( !wcsncmp((const wchar_t*)strJuncName, L"\\??\\", 4) )
+          {
+              iOffset = 4;
+          }
 
+          string strJuncTemp = (const wchar_t*)strJuncName + iOffset;
 
-          AttrDlg[SETATTR_TITLELINK].strData.Format (UMSG(ID_Msg),
-                (LenJunction?
-                   (const wchar_t *)TruncPathStr(strJuncTemp,Width):
-                   UMSG(MSetAttrUnknownJunction)));
+          AttrDlg[SETATTR_TITLELINK].strData.Format(
+              UMSG(ID_Msg),
+              dwReparsePointTag
+                ? (const wchar_t *)TruncPathStr(strJuncTemp,Width)
+                : UMSG(MSetAttrUnknownJunction)
+          );
 
           /* $ 11.09.2001 SVS
              �������� �� ������ ������������ �������� ������ ������� ��
@@ -710,32 +722,29 @@
       AttrDlg[SETATTR_NAME].strData = strSelName;
       TruncStr(AttrDlg[SETATTR_NAME].strData,54);
 
-      AttrDlg[SETATTR_RO].Selected=(FileAttr & FA_RDONLY)!=0;
-      AttrDlg[SETATTR_ARCHIVE].Selected=(FileAttr & FA_ARCH)!=0;
-      AttrDlg[SETATTR_HIDDEN].Selected=(FileAttr & FA_HIDDEN)!=0;
-      AttrDlg[SETATTR_SYSTEM].Selected=(FileAttr & FA_SYSTEM)!=0;
-      AttrDlg[SETATTR_COMPRESSED].Selected=(FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0;
-      AttrDlg[SETATTR_ENCRYPTED].Selected=(FileAttr & FILE_ATTRIBUTE_ENCRYPTED)!=0;
-      AttrDlg[SETATTR_INDEXED].Selected=(FileAttr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)!=0;
-      AttrDlg[SETATTR_SPARSE].Selected=(FileAttr & FILE_ATTRIBUTE_SPARSE_FILE)!=0;
-      AttrDlg[SETATTR_TEMP].Selected=(FileAttr & FILE_ATTRIBUTE_TEMPORARY)!=0;
-      AttrDlg[SETATTR_OFFLINE].Selected=(FileAttr & FILE_ATTRIBUTE_OFFLINE)!=0;
-      AttrDlg[SETATTR_VIRTUAL].Selected=(FileAttr & FILE_ATTRIBUTE_VIRTUAL)!=0;
+      AttrDlg[SETATTR_RO].Selected         = (FileAttr & FA_RDONLY)!=0;
+      AttrDlg[SETATTR_ARCHIVE].Selected    = (FileAttr & FA_ARCH)!=0;
+      AttrDlg[SETATTR_HIDDEN].Selected     = (FileAttr & FA_HIDDEN)!=0;
+      AttrDlg[SETATTR_SYSTEM].Selected     = (FileAttr & FA_SYSTEM)!=0;
+      AttrDlg[SETATTR_COMPRESSED].Selected = (FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0;
+      AttrDlg[SETATTR_ENCRYPTED].Selected  = (FileAttr & FILE_ATTRIBUTE_ENCRYPTED)!=0;
+      AttrDlg[SETATTR_INDEXED].Selected    = (FileAttr & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)!=0;
+      AttrDlg[SETATTR_SPARSE].Selected     = (FileAttr & FILE_ATTRIBUTE_SPARSE_FILE)!=0;
+      AttrDlg[SETATTR_TEMP].Selected       = (FileAttr & FILE_ATTRIBUTE_TEMPORARY)!=0;
+      AttrDlg[SETATTR_OFFLINE].Selected    = (FileAttr & FILE_ATTRIBUTE_OFFLINE)!=0;
+      AttrDlg[SETATTR_VIRTUAL].Selected    = (FileAttr & FILE_ATTRIBUTE_VIRTUAL)!=0;
 
-      if(DlgParam.Plugin)
+      if( DlgParam.Plugin )
       {
-        ConvertDate(FindData.ftLastWriteTime,AttrDlg[SETATTR_MDATE].strData,AttrDlg[SETATTR_MTIME].strData,8,FALSE,FALSE,TRUE,TRUE);
-        ConvertDate(FindData.ftCreationTime,AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData,8,FALSE,FALSE,TRUE,TRUE);
-        ConvertDate(FindData.ftLastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData,8,FALSE,FALSE,TRUE,TRUE);
+        ConvertDate(FindData.ftLastWriteTime,  AttrDlg[SETATTR_MDATE].strData, AttrDlg[SETATTR_MTIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
+        ConvertDate(FindData.ftCreationTime,   AttrDlg[SETATTR_CDATE].strData, AttrDlg[SETATTR_CTIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
+        ConvertDate(FindData.ftLastAccessTime, AttrDlg[SETATTR_ADATE].strData, AttrDlg[SETATTR_ATIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
       }
-      else
+      else if( apiGetFindDataEx(strSelName, &FindData) )
       {
-        if ( apiGetFindDataEx (strSelName,&FindData))
-        {
-          ConvertDate(FindData.ftLastWriteTime,AttrDlg[SETATTR_MDATE].strData,AttrDlg[SETATTR_MTIME].strData,8,FALSE,FALSE,TRUE,TRUE);
-          ConvertDate(FindData.ftCreationTime,AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData,8,FALSE,FALSE,TRUE,TRUE);
-          ConvertDate(FindData.ftLastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData,8,FALSE,FALSE,TRUE,TRUE);
-        }
+        ConvertDate(FindData.ftLastWriteTime,  AttrDlg[SETATTR_MDATE].strData, AttrDlg[SETATTR_MTIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
+        ConvertDate(FindData.ftCreationTime,   AttrDlg[SETATTR_CDATE].strData, AttrDlg[SETATTR_CTIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
+        ConvertDate(FindData.ftLastAccessTime, AttrDlg[SETATTR_ADATE].strData, AttrDlg[SETATTR_ATIME].strData, 8, FALSE, FALSE, TRUE, TRUE);
       }
     }
     else
@@ -838,10 +847,7 @@
 
     if (SelCount==1 && (FileAttr & FA_DIREC)==0)
     {
-      if(IsFileWritable(strSelName,FileAttr,TRUE,MSetAttrCannotFor) == 1)
-      {
-        int NewAttr;
-        NewAttr=FileAttr & FA_DIREC;
+        int NewAttr = FileAttr & FA_DIREC;
         if (AttrDlg[SETATTR_RO].Selected)         NewAttr|=FA_RDONLY;
         if (AttrDlg[SETATTR_ARCHIVE].Selected)    NewAttr|=FA_ARCH;
         if (AttrDlg[SETATTR_HIDDEN].Selected)     NewAttr|=FA_HIDDEN;
@@ -866,35 +872,71 @@
             NewAttr|=FILE_ATTRIBUTE_VIRTUAL;
         */
 
-        SetWriteTime=     DlgParam.OLastWriteTime  && ReadFileTime(0,strSelName,FileAttr,&LastWriteTime,AttrDlg[SETATTR_MDATE].strData,AttrDlg[SETATTR_MTIME].strData);
-        SetCreationTime=  DlgParam.OCreationTime   && ReadFileTime(1,strSelName,FileAttr,&CreationTime,AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData);
-        SetLastAccessTime=DlgParam.OLastAccessTime && ReadFileTime(2,strSelName,FileAttr,&LastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData);
+        SetWriteTime = DlgParam.OLastWriteTime && ReadFileTime(
+            0,
+            strSelName,
+            FileAttr,
+            &LastWriteTime,
+            AttrDlg[SETATTR_MDATE].strData,
+            AttrDlg[SETATTR_MTIME].strData
+        );
+
+        SetCreationTime = DlgParam.OCreationTime && ReadFileTime(
+            1,
+            strSelName,
+            FileAttr, 
+            &CreationTime,
+            AttrDlg[SETATTR_CDATE].strData,
+            AttrDlg[SETATTR_CTIME].strData
+        );
+
+        SetLastAccessTime = DlgParam.OLastAccessTime && ReadFileTime(
+            2, 
+            strSelName,
+            FileAttr,
+            &LastAccessTime,
+            AttrDlg[SETATTR_ADATE].strData,
+            AttrDlg[SETATTR_ATIME].strData
+        );
   //_SVS(SysLog(L"\n\tSetWriteTime=%d\n\tSetCreationTime=%d\n\tSetLastAccessTime=%d",SetWriteTime,SetCreationTime,SetLastAccessTime));
         if(SetWriteTime || SetCreationTime || SetLastAccessTime)
-          SetWriteTimeRetCode=ESetFileTime(strSelName,
-                                           (SetWriteTime ? &LastWriteTime:NULL),
-                                           (SetCreationTime ? &CreationTime:NULL),
-                                           (SetLastAccessTime ? &LastAccessTime:NULL),
-                                           FileAttr);
+        {
+          SetWriteTimeRetCode = ESetFileTime(
+              strSelName,
+              (SetWriteTime ? &LastWriteTime:NULL),
+              (SetCreationTime ? &CreationTime:NULL),
+              (SetLastAccessTime ? &LastAccessTime:NULL),
+              FileAttr
+          );
+        }
         else
+        {
           SetWriteTimeRetCode=TRUE;
+        }
 
   //      if(NewAttr != (FileAttr & (~FA_DIREC))) // ����� �� ���-��� ����???
         if(SetWriteTimeRetCode == 1) // ���� ���� ������ �������...
         {
           if((NewAttr&FILE_ATTRIBUTE_COMPRESSED) && !(FileAttr&FILE_ATTRIBUTE_COMPRESSED))
+          {
             ESetFileCompression(strSelName,1,FileAttr);
+          }
           else if(!(NewAttr&FILE_ATTRIBUTE_COMPRESSED) && (FileAttr&FILE_ATTRIBUTE_COMPRESSED))
+          {
             ESetFileCompression(strSelName,0,FileAttr);
+          }
 
           if((NewAttr&FILE_ATTRIBUTE_ENCRYPTED) && !(FileAttr&FILE_ATTRIBUTE_ENCRYPTED))
+          {
             ESetFileEncryption(strSelName,1,FileAttr);
+          }
           else if(!(NewAttr&FILE_ATTRIBUTE_ENCRYPTED) && (FileAttr&FILE_ATTRIBUTE_ENCRYPTED))
+          {
             ESetFileEncryption(strSelName,0,FileAttr);
+          }
 
           ESetFileAttributes(strSelName,NewAttr&(~(FILE_ATTRIBUTE_ENCRYPTED|FILE_ATTRIBUTE_COMPRESSED)));
         }
-      }
     }
 
     /* Multi *********************************************************** */
@@ -922,7 +964,9 @@
         ClearAttr|=FILE_ATTRIBUTE_ENCRYPTED;
       }
       else if (!AttrDlg[SETATTR_COMPRESSED].Selected)
+	  {
         ClearAttr|=FILE_ATTRIBUTE_COMPRESSED;
+	  }
 
       if (AttrDlg[SETATTR_ENCRYPTED].Selected == 1)
       {
@@ -930,7 +974,9 @@
         ClearAttr|=FILE_ATTRIBUTE_COMPRESSED;
       }
       else if (!AttrDlg[SETATTR_ENCRYPTED].Selected)
+	  {
         ClearAttr|=FILE_ATTRIBUTE_ENCRYPTED;
+	  }
 
       if (AttrDlg[SETATTR_INDEXED].Selected == 1)        SetAttr|=FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
       else if (!AttrDlg[SETATTR_INDEXED].Selected)       ClearAttr|=FILE_ATTRIBUTE_NOT_CONTENT_INDEXED;
@@ -971,29 +1017,49 @@
         if (CheckForEsc())
           break;
 
-        RetCode=IsFileWritable(strSelName,FileAttr,TRUE,MSetAttrCannotFor);
-        if(!RetCode)
-          break;
-        if(RetCode == 2)
-          continue;
+        SetWriteTime = DlgParam.OLastWriteTime && ReadFileTime(
+            0,
+            strSelName,
+            FileAttr,
+            &LastWriteTime,
+            AttrDlg[SETATTR_MDATE].strData,
+            AttrDlg[SETATTR_MTIME].strData
+        );
 
-        SetWriteTime=     DlgParam.OLastWriteTime  && ReadFileTime(0,strSelName,FileAttr,&LastWriteTime,AttrDlg[SETATTR_MDATE].strData,AttrDlg[SETATTR_MTIME].strData);
-        SetCreationTime=  DlgParam.OCreationTime   && ReadFileTime(1,strSelName,FileAttr,&CreationTime,AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData);
-        SetLastAccessTime=DlgParam.OLastAccessTime && ReadFileTime(2,strSelName,FileAttr,&LastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData);
+        SetCreationTime = DlgParam.OCreationTime && ReadFileTime(
+            1,
+            strSelName,
+            FileAttr,
+            &CreationTime,
+            AttrDlg[SETATTR_CDATE].strData,
+            AttrDlg[SETATTR_CTIME].strData
+        );
+
+        SetLastAccessTime = DlgParam.OLastAccessTime && ReadFileTime(
+            2,
+            strSelName,
+            FileAttr,
+            &LastAccessTime,
+            AttrDlg[SETATTR_ADATE].strData,
+            AttrDlg[SETATTR_ATIME].strData
+        );
+
         if(!(FileAttr&FILE_ATTRIBUTE_REPARSE_POINT) && (SetWriteTime || SetCreationTime || SetLastAccessTime))
         {
           //if(StrstriW(DlgParam.strFSysName,L"FAT") && (FileAttr&FA_DIREC))
           //  RetCode=1;
           //else
-            RetCode=ESetFileTime(strSelName,
-                 (SetWriteTime ? &LastWriteTime:NULL),
-                 (SetCreationTime ? &CreationTime:NULL),
-                 (SetLastAccessTime ? &LastAccessTime:NULL),
-                 FileAttr);
-          if(!RetCode)
-            break;
-          if(RetCode == 2)
-            continue;
+            RetCode=ESetFileTime(
+                strSelName,
+                (SetWriteTime ? &LastWriteTime:NULL),
+                (SetCreationTime ? &CreationTime:NULL),
+                (SetLastAccessTime ? &LastAccessTime:NULL),
+                FileAttr
+                );
+            if(!RetCode)
+                break;
+            if(RetCode == 2)
+                continue;
         }
         if(((FileAttr|SetAttr)&(~ClearAttr)) != FileAttr)
         {
@@ -1038,34 +1104,52 @@
               break;
             }
 
-            RetCode=IsFileWritable(strFullName,FindData.dwFileAttributes,TRUE,MSetAttrCannotFor);
-            if(!RetCode)
-            {
-              Cancel=1;
-              break;
-            }
-            if(RetCode == 2)
-              continue;
+            SetWriteTime = DlgParam.OLastWriteTime && ReadFileTime(
+                0,
+                strFullName,
+                FindData.dwFileAttributes,
+                &LastWriteTime,
+                AttrDlg[SETATTR_MDATE].strData,
+                AttrDlg[SETATTR_MTIME].strData
+            );
 
-            SetWriteTime=     DlgParam.OLastWriteTime  && ReadFileTime(0,strFullName,FindData.dwFileAttributes,&LastWriteTime,AttrDlg[SETATTR_MDATE].strData,AttrDlg[SETATTR_MTIME].strData);
-            SetCreationTime=  DlgParam.OCreationTime   && ReadFileTime(1,strFullName,FindData.dwFileAttributes,&CreationTime,AttrDlg[SETATTR_CDATE].strData,AttrDlg[SETATTR_CTIME].strData);
-            SetLastAccessTime=DlgParam.OLastAccessTime && ReadFileTime(2,strFullName,FindData.dwFileAttributes,&LastAccessTime,AttrDlg[SETATTR_ADATE].strData,AttrDlg[SETATTR_ATIME].strData);
+            SetCreationTime = DlgParam.OCreationTime && ReadFileTime(
+                1,
+                strFullName,
+                FindData.dwFileAttributes,
+                &CreationTime,
+                AttrDlg[SETATTR_CDATE].strData,
+                AttrDlg[SETATTR_CTIME].strData
+            );
+
+            SetLastAccessTime = DlgParam.OLastAccessTime && ReadFileTime(
+                2,
+                strFullName,
+                FindData.dwFileAttributes,
+                &LastAccessTime,
+                AttrDlg[SETATTR_ADATE].strData,
+                AttrDlg[SETATTR_ATIME].strData
+            );
+
             if(!(FindData.dwFileAttributes&FILE_ATTRIBUTE_REPARSE_POINT) && (SetWriteTime || SetCreationTime || SetLastAccessTime))
             {
               //if(StrstriW(DlgParam.strFSysName,L"FAT") && (FileAttr&FA_DIREC))
               //  RetCode=1;
               //else
-                RetCode=ESetFileTime(strFullName,SetWriteTime ? &LastWriteTime:NULL,
-                           SetCreationTime ? &CreationTime:NULL,
-                           SetLastAccessTime ? &LastAccessTime:NULL,
-                           FindData.dwFileAttributes);
-              if(RetCode == 0)
-              {
-                Cancel=1;
-                break;
-              }
-              if(RetCode == 2)
-                continue;
+                RetCode = ESetFileTime(
+                    strFullName,
+                    SetWriteTime ? &LastWriteTime : NULL,
+                    SetCreationTime ? &CreationTime : NULL,
+                    SetLastAccessTime ? &LastAccessTime : NULL,
+                    FindData.dwFileAttributes
+                );
+                if(RetCode == 0)
+                {
+                    Cancel=1;
+                    break;
+                }
+                if(RetCode == 2)
+                    continue;
             }
             if(((FindData.dwFileAttributes|SetAttr)&(~ClearAttr)) !=
                  FindData.dwFileAttributes)
@@ -1121,38 +1205,54 @@
   return 1;
 }
 
-static int ReadFileTime(int Type,const wchar_t *Name,DWORD FileAttr,FILETIME *FileTime,
-                        const wchar_t *OSrcDate, const wchar_t *OSrcTime)
+static inline bool IsPartSet(unsigned uValue)    {  return (uValue != (unsigned) -1); }
+static inline bool IsPartNotSet(unsigned uValue) {  return (uValue == (unsigned) -1); }
+
+static int ReadFileTime(
+    int Type,
+    const wchar_t *Name,
+    DWORD FileAttr,
+    FILETIME *FileTime,
+    const wchar_t *OSrcDate,
+    const wchar_t *OSrcTime
+)
 {
-  FILETIME ft, oft;
-  SYSTEMTIME st, ost;
-  unsigned DateN[3],TimeN[3];
-  int DigitCount;
-  int /*SetTime,*/GetTime;
-  FILETIME *OriginalFileTime=0, OFTModify, OFTCreate, OFTLast;
+  FILETIME* pOriginalFileTime = NULL;
 
-  /*$ 17.07.2001 SKV
-    �� ���� ������, �������.
-  */
-  ZeroMemory(&st,sizeof(st));
-  /* SKV$*/
-
   // ****** ������ ��� ******** //
+  unsigned DateN[3];
   GetFileDateAndTime(OSrcDate,DateN,GetDateSeparator());
+
   // ****** ������ ������� ******** //
+  unsigned TimeN[3];
   GetFileDateAndTime(OSrcTime,TimeN,GetTimeSeparator());
 
   // ������� ����� �����������
-  if(DateN[0] == -1 || DateN[1] == -1 || DateN[2] == -1 ||
-     TimeN[0] == -1 || TimeN[1] == -1 || TimeN[2] == -1)
+  SYSTEMTIME ost;
+  if( IsPartNotSet(DateN[0]) || IsPartNotSet(DateN[1]) || IsPartNotSet(DateN[2])
+    || IsPartNotSet(TimeN[0])|| IsPartNotSet(TimeN[1]) || IsPartNotSet(TimeN[2])
+  )
   {
     // ������� ���� ��� ���������� ���� � ���� �����.
-    HANDLE hFile= apiCreateFile(Name,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,
-                 NULL,OPEN_EXISTING,
-                 (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
+    HANDLE hFile = apiCreateFile(
+        Name,
+        FILE_READ_ATTRIBUTES,
+        FILE_SHARE_READ | FILE_SHARE_WRITE,
+        NULL,
+        OPEN_EXISTING,
+        (FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS : 0,
+        NULL
+    );
     if (hFile==INVALID_HANDLE_VALUE)
+    {
       return(FALSE);
-    GetTime=GetFileTime(hFile,&OFTCreate,&OFTLast,&OFTModify);
+    }
+
+    FILETIME OFTModify;
+    FILETIME OFTCreate;
+    FILETIME OFTLast;
+
+    BOOL GetTime = GetFileTime(hFile, &OFTCreate, &OFTLast, &OFTModify);
     CloseHandle(hFile);
 
     if(!GetTime)
@@ -1160,110 +1260,78 @@
 
     switch(Type)
     {
-      case 0: // Modif
-        OriginalFileTime=&OFTModify;
+      case 0: // Modify
+        pOriginalFileTime = &OFTModify;
         break;
-      case 1: // Creat
-        OriginalFileTime=&OFTCreate;
+
+      case 1: // Create
+        pOriginalFileTime = &OFTCreate;
         break;
-      case 2: // Last
-        OriginalFileTime=&OFTLast;
+
+      case 2: // Last Access
+        pOriginalFileTime = &OFTLast;
         break;
     }
 
     // ���������� � �������� ����.
-    FileTimeToLocalFileTime(OriginalFileTime,&oft);
-    FileTimeToSystemTime(&oft,&ost);
-    DigitCount=TRUE;
+    FILETIME oft;
+    FileTimeToLocalFileTime(pOriginalFileTime,&oft);
+    FileTimeToSystemTime(&oft, &ost);
   }
-  else
-    DigitCount=FALSE;
 
   // "�������"
+  SYSTEMTIME st;
+  ZeroMemory(&st, sizeof(st));
   switch(GetDateFormat())
   {
     case 0:
-      st.wMonth=DateN[0]!=(unsigned)-1?DateN[0]:ost.wMonth;
-      st.wDay  =DateN[1]!=(unsigned)-1?DateN[1]:ost.wDay;
-      st.wYear =DateN[2]!=(unsigned)-1?DateN[2]:ost.wYear;
+      st.wMonth = IsPartSet(DateN[0]) ? DateN[0] : ost.wMonth;
+      st.wDay   = IsPartSet(DateN[1]) ? DateN[1] : ost.wDay;
+      st.wYear  = IsPartSet(DateN[2]) ? DateN[2] : ost.wYear;
       break;
+
     case 1:
-      st.wDay  =DateN[0]!=(unsigned)-1?DateN[0]:ost.wDay;
-      st.wMonth=DateN[1]!=(unsigned)-1?DateN[1]:ost.wMonth;
-      st.wYear =DateN[2]!=(unsigned)-1?DateN[2]:ost.wYear;
+      st.wDay   = IsPartSet(DateN[0]) ? DateN[0] : ost.wDay;
+      st.wMonth = IsPartSet(DateN[1]) ? DateN[1] : ost.wMonth;
+      st.wYear  = IsPartSet(DateN[2]) ? DateN[2] : ost.wYear;
       break;
+
     default:
-      st.wYear =DateN[0]!=(unsigned)-1?DateN[0]:ost.wYear;
-      st.wMonth=DateN[1]!=(unsigned)-1?DateN[1]:ost.wMonth;
-      st.wDay  =DateN[2]!=(unsigned)-1?DateN[2]:ost.wDay;
+      st.wYear  = IsPartSet(DateN[0]) ? DateN[0] : ost.wYear;
+      st.wMonth = IsPartSet(DateN[1]) ? DateN[1] : ost.wMonth;
+      st.wDay   = IsPartSet(DateN[2]) ? DateN[2] : ost.wDay;
       break;
   }
-  st.wHour   = TimeN[0]!=(unsigned)-1? (TimeN[0]):ost.wHour;
-  st.wMinute = TimeN[1]!=(unsigned)-1? (TimeN[1]):ost.wMinute;
-  st.wSecond = TimeN[2]!=(unsigned)-1? (TimeN[2]):ost.wSecond;
+  st.wHour   = IsPartSet(TimeN[0]) ? TimeN[0] : ost.wHour;
+  st.wMinute = IsPartSet(TimeN[1]) ? TimeN[1] : ost.wMinute;
+  st.wSecond = IsPartSet(TimeN[2]) ? TimeN[2] : ost.wSecond;
 
-  if (st.wYear<100)
-    if (st.wYear<80)
-      st.wYear+=2000;
-    else
-      st.wYear+=1900;
+  // year correction
+  if( st.wYear < 80 )
+  {
+      st.wYear += 2000;
+  }
+  else if( st.wYear < 100 )
+  {
+      st.wYear += 1900;
+  }
 
-  if(TimeN[0]==(unsigned)-1 && TimeN[1]==(unsigned)-1 && TimeN[2]==(unsigned)-1)
+  if( IsPartNotSet(TimeN[0]) && IsPartNotSet(TimeN[1]) && IsPartNotSet(TimeN[2]) )
   {
-    st.wMilliseconds=ost.wMilliseconds;
+    st.wMilliseconds = ost.wMilliseconds;
     // �� ����������� ��������� wDayOfWeek
     //SystemTimeToFileTime(&st,&ft);
     //FileTimeToSystemTime(&ft,&st);
   }
 
   // �������������� � "�����������" ������
-  SystemTimeToFileTime(&st,&ft);
-  LocalFileTimeToFileTime(&ft,FileTime);
-  if(DigitCount)
-    return (CompareFileTime(FileTime,OriginalFileTime) == 0)?FALSE:TRUE;
-  return TRUE;
-}
+  FILETIME ft;
+  SystemTimeToFileTime(&st, &ft);
+  LocalFileTimeToFileTime(&ft, FileTime);
 
-// ��������� 0 - �����, 1 - ��, 2 - Skip
-static int IsFileWritable(const wchar_t *Name, DWORD FileAttr, BOOL IsShowErrMsg, int Msg)
-{
-  if ((FileAttr & FA_DIREC) && WinVer.dwPlatformId!=VER_PLATFORM_WIN32_NT)
-    return 1;
-
-  while (1)
+  if( pOriginalFileTime != NULL )
   {
-    if (FileAttr & FA_RDONLY)
-      SetFileAttributesW(Name,FileAttr & ~FA_RDONLY);
-
-    HANDLE hFile= apiCreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,(FileAttr & FA_DIREC) ? FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
-    BOOL Writable=TRUE;
-    if(hFile == INVALID_HANDLE_VALUE)
-      Writable=FALSE;
-    else
-      CloseHandle(hFile);
-
-    DWORD LastError=GetLastError();
-    if (FileAttr & FA_RDONLY)
-      SetFileAttributesW(Name,FileAttr);
-    SetLastError(LastError);
-
-    if (Writable)
-      break;
-
-    int Code;
-    if(IsShowErrMsg)
-        Code=Message(MSG_DOWN|MSG_WARNING|MSG_ERRORTYPE,3,UMSG(MError),
-                     UMSG(Msg),Name,
-                     UMSG(MHRetry),UMSG(MHSkip),UMSG(MHCancel));
-    else
-       return 0;
-
-    if (Code<0)
-      return 0;
-    if(Code == 1)
-      return 2;
-    if(Code == 2)
-      return 0;
+    return (CompareFileTime(FileTime, pOriginalFileTime) == 0) ? FALSE : TRUE;
   }
-  return 1;
+  return TRUE;
 }
fix503.diff (29,017 bytes)   

alexmitin

2008-03-20 15:37

reporter   bugnote:0001392

See 0000504:0001389 in the 0000504 about the place where to set the initial permissions for the user account to test with.

alexmitin

2009-12-04 15:36

reporter   bugnote:0004671

FAR 2.0 Build 1263.

The issue is not reproducable.

Issue History

Date Modified Username Field Change
2008-03-20 00:10 alexmitin New Issue
2008-03-20 01:33 alexmitin File Added: fix503.diff
2008-03-20 15:37 alexmitin Note Added: 0001392
2009-12-04 15:36 alexmitin Note Added: 0004671
2009-12-04 15:36 alexmitin Status new => resolved
2009-12-04 16:18 alexy Build => 0
2009-12-04 16:18 alexy Status resolved => closed
2009-12-04 16:18 alexy Resolution open => unable to reproduce
2009-12-04 16:18 alexy Assigned To => alexy