Mercurial > hg > xemacs-beta
diff src/fileio.c @ 3728:6765f2581182
[xemacs-hg @ 2006-12-08 02:21:53 by vins]
Added Benson Margulies's patch to avoid the dreaded: "File not found and
directory write-protected" message under Windows.
author | vins |
---|---|
date | Fri, 08 Dec 2006 02:22:02 +0000 |
parents | a0adf5f08c44 |
children | a257e03c580e |
line wrap: on
line diff
--- a/src/fileio.c Fri Dec 08 02:17:16 2006 +0000 +++ b/src/fileio.c Fri Dec 08 02:22:02 2006 +0000 @@ -2291,6 +2291,75 @@ static int check_writable (const Ibyte *filename) { +#if defined(WIN32_NATIVE) || defined(CYGWIN) +#ifdef CYGWIN + char filename_buffer[PATH_MAX]; +#endif + // Since this has to work for a directory, we can't just call 'CreateFile' + PSECURITY_DESCRIPTOR pDesc; /* Must be freed with LocalFree */ + /* these need not be freed, they point into pDesc */ + PSID psidOwner; + PSID psidGroup; + PACL pDacl; + PACL pSacl; + /* end of insides of descriptor */ + DWORD error; + DWORD attributes; + HANDLE tokenHandle; + GENERIC_MAPPING genericMapping; + DWORD accessMask; + PRIVILEGE_SET PrivilegeSet; + DWORD dwPrivSetSize = sizeof( PRIVILEGE_SET ); + BOOL fAccessGranted = FALSE; + DWORD dwAccessAllowed; + Extbyte *fnameext; + +#ifdef CYGWIN + cygwin_conv_to_full_win32_path(filename, filename_buffer); + filename = (Ibyte*)filename_buffer; +#endif + + C_STRING_TO_TSTR(filename, fnameext); + /* Win32 prototype lacks const. */ + error = qxeGetNamedSecurityInfo(fnameext, SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|OWNER_SECURITY_INFORMATION, + &psidOwner, &psidGroup, &pDacl, &pSacl, &pDesc); + if(error != ERROR_SUCCESS) { // FAT? + attributes = qxeGetFileAttributes((Extbyte *)filename); + return (attributes & FILE_ATTRIBUTE_DIRECTORY) || (0 == (attributes & FILE_ATTRIBUTE_READONLY)); + } + + genericMapping.GenericRead = FILE_GENERIC_READ; + genericMapping.GenericWrite = FILE_GENERIC_WRITE; + genericMapping.GenericExecute = FILE_GENERIC_EXECUTE; + genericMapping.GenericAll = FILE_ALL_ACCESS; + + if(!ImpersonateSelf(SecurityDelegation)) { + return 0; + } + if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &tokenHandle)) { + return 0; + } + + accessMask = GENERIC_WRITE; + MapGenericMask(&accessMask, &genericMapping); + + if(!AccessCheck(pDesc, tokenHandle, accessMask, &genericMapping, + &PrivilegeSet, // receives privileges used in check + &dwPrivSetSize, // size of PrivilegeSet buffer + &dwAccessAllowed, // receives mask of allowed access rights + &fAccessGranted)) + { + CloseHandle(tokenHandle); + RevertToSelf(); + LocalFree(pDesc); + return 0; + } + CloseHandle(tokenHandle); + RevertToSelf(); + LocalFree(pDesc); + return fAccessGranted == TRUE; +#else #ifdef HAVE_EACCESS return (qxe_eaccess (filename, W_OK) >= 0); #else @@ -2301,6 +2370,7 @@ but would lose for directories. */ return (qxe_access (filename, W_OK) >= 0); #endif +#endif } DEFUN ("file-exists-p", Ffile_exists_p, 1, 1, 0, /*