def MoveFileEx(oldpath, newpath, flags): """Calls MoveFileEx, converting errors to WindowsError exceptions.""" old_p = fs.extend(oldpath) new_p = fs.extend(newpath) if not windll.kernel32.MoveFileExW(old_p, new_p, int(flags)): # pylint: disable=undefined-variable err = GetLastError() msg = u'MoveFileEx(%s, %s, %d): %s (%d)' % ( oldpath, newpath, flags, FormatError(err), err) raise WindowsError(err, msg.encode('utf-8'))
def hardlink(source, link_name): """Hardlinks a file. Add support for os.link() on Windows. """ assert isinstance(source, unicode), source assert isinstance(link_name, unicode), link_name if sys.platform == 'win32': if not ctypes.windll.kernel32.CreateHardLinkW( fs.extend(link_name), fs.extend(source), 0): raise OSError() else: fs.link(source, link_name)
def change_acl_for_delete(path): """Zaps the SECURITY_DESCRIPTOR's DACL on a directory entry that is tedious to delete. This function is a heavy hammer. It discards the SECURITY_DESCRIPTOR and creates a new one with only one DACL set to user:FILE_ALL_ACCESS. Used as last resort. """ STANDARD_RIGHTS_REQUIRED = 0xf0000 SYNCHRONIZE = 0x100000 FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff import win32security user, _domain, _type = win32security.LookupAccountName( '', getpass.getuser()) sd = win32security.SECURITY_DESCRIPTOR() sd.Initialize() sd.SetSecurityDescriptorOwner(user, False) dacl = win32security.ACL() dacl.Initialize() dacl.AddAccessAllowedAce( win32security.ACL_REVISION_DS, FILE_ALL_ACCESS, user) sd.SetSecurityDescriptorDacl(1, dacl, 0) # Note that this assumes the object is either owned by the current user or # its group or that the current ACL permits this. Otherwise it will silently # fail. win32security.SetFileSecurity( fs.extend(path), win32security.DACL_SECURITY_INFORMATION, sd) # It's important to also look for the read only bit after, as it's possible # the set_read_only() call to remove the read only bit had silently failed # because there was no DACL for the user. if not (os.stat(path).st_mode & stat.S_IWUSR): os.chmod(path, 0777)
def change_acl_for_delete(path): """Zaps the SECURITY_DESCRIPTOR's DACL on a directory entry that is tedious to delete. This function is a heavy hammer. It discards the SECURITY_DESCRIPTOR and creates a new one with only one DACL set to user:FILE_ALL_ACCESS. Used as last resort. """ STANDARD_RIGHTS_REQUIRED = 0xf0000 SYNCHRONIZE = 0x100000 FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3ff import win32security user, _domain, _type = win32security.LookupAccountName( '', getpass.getuser()) sd = win32security.SECURITY_DESCRIPTOR() sd.Initialize() sd.SetSecurityDescriptorOwner(user, False) dacl = win32security.ACL() dacl.Initialize() dacl.AddAccessAllowedAce( win32security.ACL_REVISION_DS, FILE_ALL_ACCESS, user) sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetFileSecurity( fs.extend(path), win32security.DACL_SECURITY_INFORMATION, sd)
def test_undeleteable_owner(self): # Create a file and a directory with an empty ACL. Then try to delete it. dirpath = os.path.join(self.tempdir, 'd') filepath = os.path.join(dirpath, 'f') os.mkdir(dirpath) with open(filepath, 'w') as f: f.write('hi') import win32security user, _domain, _type = win32security.LookupAccountName( '', getpass.getuser()) sd = win32security.SECURITY_DESCRIPTOR() sd.Initialize() sd.SetSecurityDescriptorOwner(user, False) # Create an empty DACL, which removes all rights. dacl = win32security.ACL() dacl.Initialize() sd.SetSecurityDescriptorDacl(1, dacl, 0) win32security.SetFileSecurity( fs.extend(filepath), win32security.DACL_SECURITY_INFORMATION, sd) win32security.SetFileSecurity( fs.extend(dirpath), win32security.DACL_SECURITY_INFORMATION, sd) file_path.rmtree(dirpath)
def GetLongPathName(short_path): """Returns the Windows long path equivalent for a 'short' path.""" path = fs.extend(short_path) chars = windll.kernel32.GetLongPathNameW(path, None, 0) if chars: p = create_unicode_buffer(chars) if windll.kernel32.GetLongPathNameW(path, p, chars): return fs.trim(p.value) err = GetLastError() if err: # pylint: disable=undefined-variable msg = u'GetLongPathName(%s): %s (%d)' % ( short_path, FormatError(err), err) raise WindowsError(err, msg.encode('utf-8'))
def GetLongPathName(short_path): """Returns the Windows long path equivalent for a 'short' path.""" path = fs.extend(short_path) chars = windll.kernel32.GetLongPathNameW(path, None, 0) if chars: p = create_unicode_buffer(chars) if windll.kernel32.GetLongPathNameW(path, p, chars): return fs.trim(p.value) err = GetLastError() if err: # pylint: disable=E0602 msg = u'GetLongPathName(%s): %s (%d)' % ( short_path, FormatError(err), err) raise WindowsError(err, msg.encode('utf-8'))