内存泄漏 GetNamedSecurityInfoW

问题描述 投票:0回答:1

我正在尝试使用 ctypes 获取文件所有者信息(域名和用户名)。在 python 中,我使用 os.walk 来获取文件列表。

for root, dirs, files in os.walk("c:\\"):
    for file in files:
    filename = os.path.join(root, file)
    owner = PL_Files.get_fileowner(filename)
    print(owner)

要获取“PL_Files.get_fileowner”中的所有者信息,我使用 GetNamedSecurityInfoW。它运行良好(它返回域名和用户名)。

@staticmethod
def get_fileowner(filename):
    dwRet = 0
    pSidOwner = c_void_p()
    ppSecurityDescriptor = c_void_p()
    dwAcctName = DWORD()
    dwDomainName = DWORD()
    peUse = DWORD(SidTypeUnknown)
        
    dwRet = GetNamedSecurityInfoW(filename, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, byref(pSidOwner), None, None, None, None)
        if dwRet != ERROR_SUCCESS:
            return "-1"

        LookupAccountSidW(None, pSidOwner, None, byref(dwAcctName), None, byref(dwDomainName), byref(peUse))
        
        AcctName = create_unicode_buffer(dwAcctName.value + 2)
        DomainName = create_unicode_buffer(dwDomainName.value + 2)
        
        if LookupAccountSidW(None, pSidOwner, AcctName, byref(dwAcctName), DomainName, byref(dwDomainName), byref(peUse)):
            return "{}\{}".format(DomainName.value, AcctName.value)
        else:
            return "-1"

问题是每次调用 PL_Files.get_fileowner(filename) 我的进程内存都会增加约 2MB。

当我评论(没有调用)LookupAccountSidW 函数时,结果相同。所以我认为 GetNamedSecurityInfoW 函数有问题。 GetNamedSecurityInfoW 不需要释放内存(如果您不使用 ppSecurityDescriptor)。

函数原型:

GetNamedSecurityInfoW = ADVAPI32.GetNamedSecurityInfoW
GetNamedSecurityInfoW.restype = DWORD
GetNamedSecurityInfoW.argtypes = [c_wchar_p, INT, DWORD, c_void_p, c_void_p, c_void_p, c_void_p, c_void_p]
python winapi ctypes pywin32
1个回答
0
投票

使用CTypes时需要注意:

  1. [SO]:通过 ctypes 从 Python 调用的 C 函数返回不正确的值(@CristiFati 的答案) 常见的陷阱

  2. 每个功能的文档(并按照其中的指示进行操作)

但是对于这种情况,值得一提的是 [GitHub]:mhammond/pywin32 - Python for Windows (pywin32) Extensions,它是 WinAPIPython 包装器。文档 (WiP) 可以在 [GitHub.MHammond]: Python for Win32 Extensions Help(或 [ME.TimGolden]: Python for Win32 Extensions Help)找到,因为问题也被标记为
这是利用它的替代实现。

code00.py

#!/usr/bin/env python

import os
import sys

import pywintypes as pwts
import win32security as wsec


def fileowner_pywin32(file_name):
    try:
        sec_desc = wsec.GetNamedSecurityInfo(file_name, wsec.SE_FILE_OBJECT, wsec.OWNER_SECURITY_INFORMATION)
    except pwts.error as e:
        #print(e)
        return None
    else:
        owner_sid = sec_desc.GetSecurityDescriptorOwner()
        #print(owner_sid)
        try:
            name, domain, _ = wsec.LookupAccountSid(None, owner_sid)
        except pwts.error as e:
            #print(e)
            return None
        else:
            return f"{domain}\\{name}"


def main(*argv):
    test_dir = argv[0] if argv else os.getcwd()
    max_files = int(argv[1]) if len(argv) >= 2 and argv[1].isdigit() else 10
    print(f"Display file (max: {max_files}) information for: {test_dir}")
    total_files = 0
    for root, dirs, files in os.walk(test_dir):
        for file in files:
            #print(root, file)
            file_full = os.path.join(root, file)
            owner = fileowner_pywin32(file_full)
            print(f"{file_full}: {owner}")
            total_files += 1
            if max_files > 0 and total_files >= max_files:
                return


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

输出

[cfati@CFATI-W10PC064:e:\Work\Dev\StackExchange\StackOverflow\q077878192]> "c:\Work\Dev\VEnvs\py_pc064_03.10_test0\Scripts\python.exe" ./code00.py "c:" 20
Python 3.10.10 (tags/v3.10.10:aad5f6a, Feb  7 2023, 17:20:36) [MSC v.1929 64 bit (AMD64)] 064bit on win32

Display file (max: 20) information for: c:
c:DumpStack.log: BUILTIN\Administrators
c:DumpStack.log.tmp: None
c:pagefile.sys: None
c:swapfile.sys: None
c:$GetCurrent\Logs\downlevel_2021_05_15_23_18_17_211.log: BUILTIN\Administrators
c:$GetCurrent\Logs\oobe_2021_05_16_04_23_10_420.log: NT AUTHORITY\SYSTEM
c:$GetCurrent\Logs\PartnerSetupCompleteResult.log: NT AUTHORITY\SYSTEM
c:$GetCurrent\SafeOS\GetCurrentOOBE.dll: BUILTIN\Administrators
c:$GetCurrent\SafeOS\GetCurrentRollback.ini: BUILTIN\Administrators
c:$GetCurrent\SafeOS\PartnerSetupComplete.cmd: BUILTIN\Administrators
c:$GetCurrent\SafeOS\preoobe.cmd: BUILTIN\Administrators
c:$GetCurrent\SafeOS\SetupComplete.cmd: BUILTIN\Administrators
c:$Recycle.Bin\S-1-5-18\desktop.ini: BUILTIN\Administrators
c:$Recycle.Bin\S-1-5-21-2542118664-3911450730-4233525012-1000\desktop.ini: None
c:$Recycle.Bin\S-1-5-21-2542118664-3911450730-4233525012-1001\desktop.ini: CFATI-W10PC064\cfati
c:Download\EnergyPlus-22.2.0-c249759bad-Windows-i386.zip: BUILTIN\Administrators
c:Download\strawberry-perl-5.32.1.1-64bit.msi: BUILTIN\Administrators
c:Install\MS\SysInternalsSuite\Version\accesschk.exe: BUILTIN\Administrators
c:Install\MS\SysInternalsSuite\Version\accesschk64.exe: BUILTIN\Administrators
c:Install\MS\SysInternalsSuite\Version\AccessEnum.exe: BUILTIN\Administrators

Done.
© www.soinside.com 2019 - 2024. All rights reserved.