View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0000503 | Far Manager | SetAttr | public | 2008-03-20 00:10 | 2009-12-04 16:18 |
Reporter | alexmitin | Assigned To | alexy | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | unable to reproduce | ||
Summary | 0000503: Access denied error while setting the file attributes | ||||
Description | Problem ---------------- 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 Information | FAR 1.80.0.452 | ||||
Tags | No tags attached. | ||||
Build | 0 | ||||
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; } |
|
See 0000504:0001389 in the 0000504 about the place where to set the initial permissions for the user account to test with. |
|
FAR 2.0 Build 1263. The issue is not reproducable. |
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 |