code: def _win32_restrict_file_to_user_ctypes(fname: str) -> None:
      """Secure a windows file to read-only access for the user.
  
      Follows guidance from win32 library creator:
      http://timgolden.me.uk/python/win32_how_do_i/add-security-to-a-file.html
  
      This method should be executed against an already generated file which
      has no secrets written to it yet.
  
      Parameters
      ----------
  
      fname : unicode
          The path to the file to secure
      """
      import ctypes
      from ctypes import wintypes
  
      advapi32 = ctypes.WinDLL(
          "advapi32", use_last_error=True
      )  # type:ignore[attr-defined]
      secur32 = ctypes.WinDLL(
          "secur32", use_last_error=True
      )  # type:ignore[attr-defined]
  
      NameSamCompatible = 2
      WinBuiltinAdministratorsSid = 26
      DACL_SECURITY_INFORMATION = 4
      ACL_REVISION = 2
      ERROR_INSUFFICIENT_BUFFER = 122
      ERROR_MORE_DATA = 234
  
      SYNCHRONIZE = 0x100000
      DELETE = 0x00010000
      STANDARD_RIGHTS_REQUIRED = 0xF0000
      STANDARD_RIGHTS_READ = 0x20000
      STANDARD_RIGHTS_WRITE = 0x20000
      FILE_READ_DATA = 1
      FILE_READ_EA = 8
      FILE_READ_ATTRIBUTES = 128
      FILE_WRITE_DATA = 2
      FILE_APPEND_DATA = 4
      FILE_WRITE_EA = 16
      FILE_WRITE_ATTRIBUTES = 256
      FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
      FILE_GENERIC_READ = (
          STANDARD_RIGHTS_READ
          | FILE_READ_DATA
          | FILE_READ_ATTRIBUTES
          | FILE_READ_EA
          | SYNCHRONIZE
      )
      FILE_GENERIC_WRITE = (
          STANDARD_RIGHTS_WRITE
          | FILE_WRITE_DATA
          | FILE_WRITE_ATTRIBUTES
          | FILE_WRITE_EA
          | FILE_APPEND_DATA
          | SYNCHRONIZE
      )
  
      class ACL(ctypes.Structure):
          _fields_ = [
              ("AclRevision", wintypes.BYTE),
              ("Sbz1", wintypes.BYTE),
              ("AclSize", wintypes.WORD),
              ("AceCount", wintypes.WORD),
              ("Sbz2", wintypes.WORD),
          ]
  
      PSID = ctypes.c_void_p
      PACL = ctypes.POINTER(ACL)
      PSECURITY_DESCRIPTOR = ctypes.POINTER(wintypes.BYTE)
  
      def _nonzero_success(
          result: int, func: Any, args: Any
      ) -> Any:  # noqa: ARG001
          if not result:
              raise ctypes.WinError(
                  ctypes.get_last_error()
              )  # type:ignore[attr-defined]
          return args
  
      secur32.GetUserNameExW.errcheck = _nonzero_success
      secur32.GetUserNameExW.restype = wintypes.BOOL
      secur32.GetUserNameExW.argtypes = (
          ctypes.c_int,  # EXTENDED_NAME_FORMAT NameFormat
          wintypes.LPWSTR,  # LPWSTR lpNameBuffer,
          wintypes.PULONG,  # PULONG nSize
      )
  
      advapi32.CreateWellKnownSid.errcheck = _nonzero_success
      advapi32.CreateWellKnownSid.restype = wintypes.BOOL
      advapi32.CreateWellKnownSid.argtypes = (
          wintypes.DWORD,  # WELL_KNOWN_SID_TYPE WellKnownSidType
          PSID,  # PSID DomainSid
          PSID,  # PSID pSid
          wintypes.PDWORD,  # DWORD *cbSid
      )
  
      advapi32.LookupAccountNameW.errcheck = _nonzero_success
      advapi32.LookupAccountNameW.restype = wintypes.BOOL
      advapi32.LookupAccountNameW.argtypes = (
          wintypes.LPWSTR,  # LPCWSTR lpSystemName
          wintypes.LPWSTR,  # LPCWSTR lpAccountName
          PSID,  # PSID Sid
          wintypes.LPDWORD,  # LPDWORD cbSid
          wintypes.LPWSTR,  # LPCWSTR ReferencedDomainName
          wintypes.LPDWORD,  # LPDWORD cchReferencedDomainName
          wintypes.LPDWORD,  # PSID_NAME_USE peUse
      )
  
      advapi32.AddAccessAllowedAce.errcheck = _nonzero_success
      advapi32.AddAccessAllowedAce.restype = wintypes.BOOL
      advapi32.AddAccessAllowedAce.argtypes = (
          PACL,  # PACL pAcl
          wintypes.DWORD,  # DWORD dwAceRevision
          wintypes.DWORD,  # DWORD AccessMask
          PSID,  # PSID pSid
      )
  
      advapi32.SetSecurityDescriptorDacl.errcheck = _nonzero_success
      advapi32.SetSecurityDescriptorDacl.restype = wintypes.BOOL
      advapi32.SetSecurityDescriptorDacl.argtypes = (
          PSECURITY_DESCRIPTOR,  # PSECURITY_DESCRIPTOR pSecurityDescriptor
          wintypes.BOOL,  # BOOL bDaclPresent
          PACL,  # PACL pDacl
          wintypes.BOOL,  # BOOL bDaclDefaulted
      )
  
      advapi32.GetFileSecurityW.errcheck = _nonzero_success
      advapi32.GetFileSecurityW.restype = wintypes.BOOL
      advapi32.GetFileSecurityW.argtypes = (
          wintypes.LPCWSTR,  # LPCWSTR lpFileName
          wintypes.DWORD,  # SECURITY_INFORMATION RequestedInformation
          PSECURITY_DESCRIPTOR,  # PSECURITY_DESCRIPTOR pSecurityDescriptor
          wintypes.DWORD,  # DWORD nLength
          wintypes.LPDWORD,  # LPDWORD lpnLengthNeeded
      )
  
      advapi32.SetFileSecurityW.errcheck = _nonzero_success
      advapi32.SetFileSecurityW.restype = wintypes.BOOL
      advapi32.SetFileSecurityW.argtypes = (
          wintypes.LPCWSTR,  # LPCWSTR lpFileName
          wintypes.DWORD,  # SECURITY_INFORMATION SecurityInformation
          PSECURITY_DESCRIPTOR,  # PSECURITY_DESCRIPTOR pSecurityDescriptor
      )
  
      advapi32.MakeAbsoluteSD.errcheck = _nonzero_success
      advapi32.MakeAbsoluteSD.restype = wintypes.BOOL
      advapi32.MakeAbsoluteSD.argtypes = (
          PSECURITY_DESCRIPTOR,  # pSelfRelativeSecurityDescriptor
          PSECURITY_DESCRIPTOR,  # pAbsoluteSecurityDescriptor
          wintypes.LPDWORD,  # LPDWORD lpdwAbsoluteSecurityDescriptorSize
          PACL,  # PACL pDacl
          wintypes.LPDWORD,  # LPDWORD lpdwDaclSize
          PACL,  # PACL pSacl
          wintypes.LPDWORD,  # LPDWORD lpdwSaclSize
          PSID,  # PSID pOwner
          wintypes.LPDWORD,  # LPDWORD lpdwOwnerSize
          PSID,  # PSID pPrimaryGroup
          wintypes.LPDWORD,  # LPDWORD lpdwPrimaryGroupSize
      )
  
      advapi32.MakeSelfRelativeSD.errcheck = _nonzero_success
      advapi32.MakeSelfRelativeSD.restype = wintypes.BOOL
      advapi32.MakeSelfRelativeSD.argtypes = (
          PSECURITY_DESCRIPTOR,  # pAbsoluteSecurityDescriptor
          PSECURITY_DESCRIPTOR,  # pSelfRelativeSecurityDescriptor
          wintypes.LPDWORD,  # LPDWORD lpdwBufferLength
      )
  
      advapi32.InitializeAcl.errcheck = _nonzero_success
      advapi32.InitializeAcl.restype = wintypes.BOOL
      advapi32.InitializeAcl.argtypes = (
          PACL,  # PACL pAcl,
          wintypes.DWORD,  # DWORD nAclLength,
          wintypes.DWORD,  # DWORD dwAclRevision
      )
  
      def CreateWellKnownSid(WellKnownSidType: Any) -> Any:
          # return a SID for predefined aliases
          pSid = (ctypes.c_char * 1)()
          cbSid = wintypes.DWORD()
          try:
              advapi32.CreateWellKnownSid(
                  WellKnownSidType, None, pSid, ctypes.byref(cbSid)
              )
          except OSError as e:
              if (
                  e.winerror != ERROR_INSUFFICIENT_BUFFER
              ):  # type:ignore[attr-defined]
                  raise
              pSid = (ctypes.c_char * cbSid.value)()
              advapi32.CreateWellKnownSid(
                  WellKnownSidType, None, pSid, ctypes.byref(cbSid)
              )
          return pSid[:]
  
      def GetUserNameEx(NameFormat: Any) -> Any:
          # return the user or other security principal associated with
          # the calling thread
          nSize = ctypes.pointer(ctypes.c_ulong(0))
          try:
              secur32.GetUserNameExW(NameFormat, None, nSize)
          except OSError as e:
              if (
                  e.winerror != ERROR_MORE_DATA
              ):  # type:ignore[attr-defined]
                  raise
          if not nSize.contents.value:
              return None
          lpNameBuffer = ctypes.create_unicode_buffer(
              nSize.contents.value
          )
          secur32.GetUserNameExW(NameFormat, lpNameBuffer, nSize)
          return lpNameBuffer.value
  
      def LookupAccountName(
          lpSystemName: Any, lpAccountName: Any
      ) -> Any:
          # return a security identifier (SID) for an account on a system
          # and the name of the domain on which the account was found
          cbSid = wintypes.DWORD(0)
          cchReferencedDomainName = wintypes.DWORD(0)
          peUse = wintypes.DWORD(0)
          try:
              advapi32.LookupAccountNameW(
                  lpSystemName,
                  lpAccountName,
                  None,
                  ctypes.byref(cbSid),
                  None,
                  ctypes.byref(cchReferencedDomainName),
                  ctypes.byref(peUse),
              )
          except OSError as e:
              if (
                  e.winerror != ERROR_INSUFFICIENT_BUFFER
              ):  # type:ignore[attr-defined]
                  raise
          Sid = ctypes.create_unicode_buffer("", cbSid.value)
          pSid = ctypes.cast(ctypes.pointer(Sid), wintypes.LPVOID)
          lpReferencedDomainName = ctypes.create_unicode_buffer(
              "", cchReferencedDomainName.value + 1
          )
          success = advapi32.LookupAccountNameW(
              lpSystemName,
              lpAccountName,
              pSid,
              ctypes.byref(cbSid),
              lpReferencedDomainName,
              ctypes.byref(cchReferencedDomainName),
              ctypes.byref(peUse),
          )
          if not success:
              raise ctypes.WinError()  # type:ignore[attr-defined]
          return pSid, lpReferencedDomainName.value, peUse.value
  
      def AddAccessAllowedAce(
          pAcl: Any, dwAceRevision: Any, AccessMask: Any, pSid: Any
      ) -> Any:
          # add an access-allowed access control entry (ACE)
          # to an access control list (ACL)
          advapi32.AddAccessAllowedAce(
              pAcl, dwAceRevision, AccessMask, pSid
          )
  
      def GetFileSecurity(
          lpFileName: Any, RequestedInformation: Any
      ) -> Any:
          # return information about the security of a file or directory
          nLength = wintypes.DWORD(0)
          try:
              advapi32.GetFileSecurityW(
                  lpFileName,
                  RequestedInformation,
                  None,
                  0,
                  ctypes.byref(nLength),
              )
          except OSError as e:
              if (
                  e.winerror != ERROR_INSUFFICIENT_BUFFER
              ):  # type:ignore[attr-defined]
                  raise
          if not nLength.value:
              return None
          pSecurityDescriptor = (wintypes.BYTE * nLength.value)()
          advapi32.GetFileSecurityW(
              lpFileName,
              RequestedInformation,
              pSecurityDescriptor,
              nLength,
              ctypes.byref(nLength),
          )
          return pSecurityDescriptor
  
      def SetFileSecurity(
          lpFileName: Any,
          RequestedInformation: Any,
          pSecurityDescriptor: Any,
      ) -> Any:
          # set the security of a file or directory object
          advapi32.SetFileSecurityW(
              lpFileName, RequestedInformation, pSecurityDescriptor
          )
  
      def SetSecurityDescriptorDacl(
          pSecurityDescriptor: Any,
          bDaclPresent: Any,
          pDacl: Any,
          bDaclDefaulted: Any,
      ) -> Any:
          # set information in a discretionary access control list (DACL)
          advapi32.SetSecurityDescriptorDacl(
              pSecurityDescriptor, bDaclPresent, pDacl, bDaclDefaulted
          )
  
      def MakeAbsoluteSD(pSelfRelativeSecurityDescriptor: Any) -> Any:
          # return a security descriptor in absolute format
          # by using a security descriptor in self-relative format as a template
          pAbsoluteSecurityDescriptor = None
          lpdwAbsoluteSecurityDescriptorSize = wintypes.DWORD(0)
          pDacl = None
          lpdwDaclSize = wintypes.DWORD(0)
          pSacl = None
          lpdwSaclSize = wintypes.DWORD(0)
          pOwner = None
          lpdwOwnerSize = wintypes.DWORD(0)
          pPrimaryGroup = None
          lpdwPrimaryGroupSize = wintypes.DWORD(0)
          try:
              advapi32.MakeAbsoluteSD(
                  pSelfRelativeSecurityDescriptor,
                  pAbsoluteSecurityDescriptor,
                  ctypes.byref(lpdwAbsoluteSecurityDescriptorSize),
                  pDacl,
                  ctypes.byref(lpdwDaclSize),
                  pSacl,
                  ctypes.byref(lpdwSaclSize),
                  pOwner,
                  ctypes.byref(lpdwOwnerSize),
                  pPrimaryGroup,
                  ctypes.byref(lpdwPrimaryGroupSize),
              )
          except OSError as e:
              if (
                  e.winerror != ERROR_INSUFFICIENT_BUFFER
              ):  # type:ignore[attr-defined]
                  raise
          pAbsoluteSecurityDescriptor = (
              wintypes.BYTE * lpdwAbsoluteSecurityDescriptorSize.value
          )()
          pDaclData = (wintypes.BYTE * lpdwDaclSize.value)()
          pDacl = ctypes.cast(pDaclData, PACL).contents
          pSaclData = (wintypes.BYTE * lpdwSaclSize.value)()
          pSacl = ctypes.cast(pSaclData, PACL).contents
          pOwnerData = (wintypes.BYTE * lpdwOwnerSize.value)()
          pOwner = ctypes.cast(pOwnerData, PSID)
          pPrimaryGroupData = (
              wintypes.BYTE * lpdwPrimaryGroupSize.value
          )()
          pPrimaryGroup = ctypes.cast(pPrimaryGroupData, PSID)
          advapi32.MakeAbsoluteSD(
              pSelfRelativeSecurityDescriptor,
              pAbsoluteSecurityDescriptor,
              ctypes.byref(lpdwAbsoluteSecurityDescriptorSize),
              pDacl,
              ctypes.byref(lpdwDaclSize),
              pSacl,
              ctypes.byref(lpdwSaclSize),
              pOwner,
              lpdwOwnerSize,
              pPrimaryGroup,
              ctypes.byref(lpdwPrimaryGroupSize),
          )
          return pAbsoluteSecurityDescriptor
  
      def MakeSelfRelativeSD(pAbsoluteSecurityDescriptor: Any) -> Any:
          # return a security descriptor in self-relative format
          # by using a security descriptor in absolute format as a template
          pSelfRelativeSecurityDescriptor = None
          lpdwBufferLength = wintypes.DWORD(0)
          try:
              advapi32.MakeSelfRelativeSD(
                  pAbsoluteSecurityDescriptor,
                  pSelfRelativeSecurityDescriptor,
                  ctypes.byref(lpdwBufferLength),
              )
          except OSError as e:
              if (
                  e.winerror != ERROR_INSUFFICIENT_BUFFER
              ):  # type:ignore[attr-defined]
                  raise
          pSelfRelativeSecurityDescriptor = (
              wintypes.BYTE * lpdwBufferLength.value
          )()
          advapi32.MakeSelfRelativeSD(
              pAbsoluteSecurityDescriptor,
              pSelfRelativeSecurityDescriptor,
              ctypes.byref(lpdwBufferLength),
          )
          return pSelfRelativeSecurityDescriptor
  
      def NewAcl() -> Any:
          # return a new, initialized ACL (access control list) structure
          nAclLength = (
              32767  # TODO: calculate this: ctypes.sizeof(ACL) + ?
          )
          acl_data = ctypes.create_string_buffer(nAclLength)
          pAcl = ctypes.cast(acl_data, PACL).contents
          advapi32.InitializeAcl(pAcl, nAclLength, ACL_REVISION)
          return pAcl
  
      SidAdmins = CreateWellKnownSid(WinBuiltinAdministratorsSid)
      SidUser = LookupAccountName("", GetUserNameEx(NameSamCompatible))[
          0
      ]
  
      Acl = NewAcl()
      AddAccessAllowedAce(Acl, ACL_REVISION, FILE_ALL_ACCESS, SidAdmins)
      AddAccessAllowedAce(
          Acl,
          ACL_REVISION,
          FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE,
          SidUser,
      )
  
      SelfRelativeSD = GetFileSecurity(fname, DACL_SECURITY_INFORMATION)
      AbsoluteSD = MakeAbsoluteSD(SelfRelativeSD)
      SetSecurityDescriptorDacl(AbsoluteSD, 1, Acl, 0)
      SelfRelativeSD = MakeSelfRelativeSD(AbsoluteSD)
  
      SetFileSecurity(fname, DACL_SECURITY_INFORMATION, SelfRelativeSD)
  
imports: from __future__ import annotations
  import errno
  import os
  import site
  import stat
  import sys
  import tempfile
  import warnings
  from contextlib import contextmanager
  from pathlib import Path
  from typing import Any, Iterator, Optional
  import platformdirs
  from .utils import deprecation
label_desc: Use image node_id 17 for calling a global function with example usage: _win32_restrict_file_to_user_ctypes(fname) and returns: args, pSid, lpNameBuffer, pSid,  lpReferencedDomainName,  peUse, pSecurityDescriptor, pAbsoluteSecurityDescriptor, pSelfRelativeSecurityDescriptor, pAcl, None, None