
    wBf5                        d Z ddlZddlmZ ddlmZ ddlmZm	Z	 ddlm
Z ddlmZ dd	lmZ dd
lmZmZ dZ ee      Zej,                  j.                  dk(  Z	 ddlmZ eZesddlmZmZ eZeZnddlmZm Z  ejB                  jD                  Z#e jH                  e#_%        e jL                  e jL                  e jN                  ge#_(        	 ejB                  jR                  Z*e jH                  e*_%        e jL                  e jL                  e jV                  ge*_(        d Z-d Z.e-Ze.Zeresddlm/Z/ eZ
eZe/Z/yddl0Z0ddl1Z1ddlZddlm2Z2m3Z3m4Z4m5Z5m6Z6mZm Z  ddlm7Z7 ddlm8Z8 d Z
d ZdZ9dZ:dZ;dZ<dZ=dZ> G d de3      Z? e2e?      Z@ejB                  j                  ZBe j                  e@feB_(        e j                  eB_%        ejB                  j                  ZFe j                  e@feF_(        e j                  eF_%         e j                  d       j                  ZIejB                  j                  ZKe jV                  eK_%        e j                  feK_(        d! ZLd" ZM G d# d$e0j                        ZNd% ZOd& ZPd' ZQd( ZRd) ZSd* ZTdZUd+ZVd,ZWd-ZX e2e jV                        ZYe jN                  ZZ G d. d/e3      Z[ e2e[      Z\ejB                  j                  Z^e j                  e jV                  e jV                  e\e jV                  e jV                  e j                  fe^_(        e j                  e^_%        ejB                  j                  Z_e j                  fe__(        e j                  e__%        dd0lm`Z`maZambZbmcZcmdZdmeZe  G d1 d2e3      Zfd3 Z/ejB                  j                  Zge j                  e jV                  e jN                  e jV                  e jN                  e jV                  eYeZgeg_(        e jH                  eg_%        	 d5d4Zhy# e$ r d ZY w xY w# e,$ r dZ*Y w xY w)6a  Disk utility functions for symlinking files and folders.

Portions of the code within this module are taken from https://github.com/jaraco/jaraco.windows
which is MIT licensed by Jason R. Coombs.

https://github.com/jaraco/skeleton/issues/1#issuecomment-285448440
    N)	getLogger)chmod)abspathisdir)islink)lexists   )on_win)CondaOSError
ParseError)r   lchmodr   linkreadlinksymlinkpypy)r   c                 4    t        |       st        | |       y y N)r   os_chmod)pathmodes     8lib/python3.12/site-packages/conda/gateways/disk/link.pyr   r   !   s     d|T4      )r   r   )windllwintypesc                 @    t        || d      st        d|  d|       y)z;Equivalent to os.link, using the win32 CreateHardLink call.Nzwin32 hard link failed
  src: 
  dst: )CreateHardLinkr   srcdsts     r   win_hard_linkr!   ?   s,    c3-!@YseTUU .r   c                 t    t         t        d      t        || t        |             st        d|  d|       y)zBEquivalent to os.symlink, using the win32 CreateSymbolicLink call.Nzwin32 soft link not supportedzwin32 soft link failed
  src: r   )CreateSymbolicLinkr   r   r   s     r   win_soft_linkr$   D   sB    %>??!#sE#J7!@YseTUU 8r   )r   )POINTER	Structurebyrefc_uint64castr   r   )getcwd)isfilec                 2    t        |       xr t        |       S )z(Determine if the given path is a symlink)is_reparse_point
is_symlinkr   s    r   r   r   ^   s    %:*T*::r   c                 L    t        |       ryt        |       ryt        |       ryy)NTF)r   r   r+   r/   s    r   r   r   b   s#    $<;$<r   i  l     @ l    i      c            
          e Zd Zdej                  fdej
                  fdej
                  fdej
                  fdej                  dz  fdej                  dz  fdej                  ez  fd	ej                  d
z  fgZe	d        Z
y)WIN32_FIND_DATAfile_attributescreation_timelast_access_timelast_write_timefile_size_words   reservedfilenamealternate_filename   c                 \    t        | j                  t        t                    j                  S r   )r)   r8   r%   r(   contentsselfs    r   	file_sizezWIN32_FIND_DATA.file_size~   s     ,,gh.?@IIIr   N)__name__
__module____qualname__r   DWORDFILETIMEWCHARMAX_PATH_fields_propertyrB    r   r   r3   r3   r   s    /h//0!2!23 1 12 23!+,(23!8>>B#67	
 
	J 
	Jr   r3   c                 "    | dk(  r
t               y Nr   )OSError)results    r   handle_nonzero_successrR      s    Q;)O r   c           	         d}d}||z  }d}| }d}t        j                         }d}d}	t        j                  j	                  ||||t        |      ||	      }
t        |
       |j                  }t        j                  j                  |       |S )zr
        Call FormatMessage with a system error number to retrieve
        the descriptive error message.
           i   Nr   )	r   LPWSTRr   kernel32FormatMessageWr'   rR   value	LocalFree)errnoALLOCATE_BUFFERFROM_SYSTEMflagssource
message_idlanguage_idresult_bufferbuffer_size	argumentsbytesmessages               r   format_system_messagerf      s        +-
 )	..- 
 	u%%%!!-0r   c                   L     e Zd Zd fd	Zed        Zed        Zd Zd Z xZ	S )WindowsErrorc                     |t         j                  j                         }t        |      }d|d |f}t	        |   |  y rO   )r   rV   GetLastErrorrf   super__init__)rA   rX   strerrorargs	__class__s       r   rl   zWindowsError.__init__   s?    }446,U3Hhe+DGd#r   c                     | j                   S r   )rm   r@   s    r   re   zWindowsError.message       == r   c                     | j                   S r   )winerrorr@   s    r   codezWindowsError.code   rq   r   c                     | j                   S r   )re   r@   s    r   __str__zWindowsError.__str__   s    <<r   c                 6     dj                   di t               S )Nz*{self.__class__.__name__}({self.winerror})rL   )formatvarsr@   s    r   __repr__zWindowsError.__repr__   s    F?FFPPPr   r   )
rC   rD   rE   rl   rK   re   rt   rv   rz   __classcell__)ro   s   @r   rh   rh      s;    	$ 
	! 
	! 
	! 
	!	 	Qr   rh   c                 .    | j                   d   t        k(  S rO   )r:   IO_REPARSE_TAG_SYMLINK)	find_datas    r   _is_symlinkr      s    !!!$(>>>r   c                 x    | j                  d      r| S t        |       } | d   dk(  st               dd | z   } d| z   S )a;  
        Paths have a max length of api.MAX_PATH characters (260). If a target path
        is longer than that, it needs to be made absolute and prepended with
        \\?\ in order to work with API calls.
        See http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx for
        details.
        z\\?\   :Nr9   )
startswithr   r*   r/   s    r   _patch_pathr      sF     ??9%Kt}Aw#~8BQ<$&D4r   c                 t    t        j                         j                  j                  }| j	                  |      S )zFormat the string using variables in the caller's local namespace.

        .. code-block:: pycon
            >>> a = 3
            >>> local_format("{a:5}")
            '    3'
        )inspectcurrentframef_backf_locals
format_map)stringcontexts     r   local_formatr      s/     &&(//88  ))r   c                     t        |       } 	 t        t        t        |                   S # t        $ r%}d}t        j                  t        |            d}~ww xY w)z>Assuming path is a reparse point, determine if it's a symlink.z,Error accessing {path}: {orig_error.message}N)r   r   next
find_filesrP   builtinsrh   r   )r   
orig_errortmpls      r   r.   r.      sQ    4 	<tJt$4566 	<AD''T(:;;	<s   * 	A AAc              #   B  K   t               }t        | t        |            }	 |t        k(  r
t	               | t               }t        |t        |            }|dk(  r t               }|j                  t        k(  rn|\t        j                  j                  |       yw)a  
        A pythonic wrapper around the FindFirstFile/FindNextFile win32 api.
        >>> root_files = tuple(find_files(r'c:\*'))
        >>> len(root_files) > 1
        True
        >>> root_files[0].filename == root_files[1].filename
        False
        >>> # This test might fail on a non-standard installation
        >>> 'Windows' in (fd.filename for fd in root_files)
        True
        r   N)r3   FindFirstFiler'   INVALID_HANDLE_VALUErP   FindNextFilerh   rt   ERROR_NO_MORE_FILESr   rV   	FindClose)specfdhandlereserrors        r   r   r      s      tU2Y/--iH "BvuRy1Cax$::!44K  	!!&)s   BBc                 R    t        |       }|t        k7  xr t        |t        z        S )z
        Determine if the given path is a reparse point.
        Return False if the file does not exist or the file attributes cannot
        be determined.
        )GetFileAttributesINVALID_FILE_ATTRIBUTESboolFILE_ATTRIBUTE_REPARSE_POINT)r   r   s     r   r-   r-     s1      %-- 
$..3
 	
r   i    i   i 	 c                   ^    e Zd Zdej                  fdej
                  fdej                  ffZy)SECURITY_ATTRIBUTESlengthp_security_descriptorinherit_handleN)rC   rD   rE   r   rF   LPVOIDBOOLEANrJ   rL   r   r   r   r   %  s/    x~~&$hoo6x//0
r   r   )Arrayc_bytec_ulongc_ushortcreate_string_buffersizeofc                   X    e Zd Zdefdefdefdefdefdefdefdefd	ed
z  fg	Zd Zd Zy)REPARSE_DATA_BUFFERtagdata_lengthr:   substitute_name_offsetsubstitute_name_lengthprint_name_offsetprint_name_lengthr]   path_bufferr   c                    t        t        j                        }t        j                  | j                  |z  z  }t	        | j
                  | j                        }t        |t        |            j                  j                  S r   )r   r   rH   r   r'   r   r   r)   r%   r?   rX   rA   
wchar_sizearr_typdatas       r   get_print_namez"REPARSE_DATA_BUFFER.get_print_nameM  s_    /Jnn(>(>*(LMG))4+A+ABDgg./88>>>r   c                    t        t        j                        }t        j                  | j                  |z  z  }t	        | j
                  | j                        }t        |t        |            j                  j                  S r   )r   r   rH   r   r'   r   r   r)   r%   r?   rX   r   s       r   get_substitute_namez'REPARSE_DATA_BUFFER.get_substitute_nameS  s_    /Jnn(C(Cz(QRG))4+F+FGDgg./88>>>r   N)	rC   rD   rE   r   r   r   rJ   r   r   rL   r   r   r   r   @  s_    GH%"%x0%x0 (+ (+gFQJ'

	?	?r   r   c           	         t        | dddt        t        t        z  d      }|t        k(  r
t               t        |t        dd      }t        |      }t        |t        t                    }|j                  }|j                  t        k(  st        d|j                  z        t!        t#        |             |j%                         S )zsReturn a string representing the path to which the symbolic link points.

        readlink(link) -> target
        r   Ni (  z+Expected IO_REPARSE_TAG_SYMLINK, but got %d)
CreateFileOPEN_EXISTINGFILE_FLAG_OPEN_REPARSE_POINTFILE_FLAG_BACKUP_SEMANTICSr   rP   reparse_DeviceIoControlFSCTL_GET_REPARSE_POINTr   r)   r%   r   r?   r   r}   r   rR   CloseHandler   )r   r   r   rd   p_rdbrdbs         r   r   r   Y  s    
 (+EE
 )))O%f.EtUS$S)UG$789nnww00JSWWTUU{623&&((r   c           
      @   |t        d      t        |t              rt        |      }|t	        |      nd}t	        |      }t        |t
              sJ t        j                         }t        | |||||||      }t        |       t        |       |d |j                   S )Nz$overlapped handles not yet supportedr   )NotImplementedError
isinstanceintr   lenr   r   rF   DeviceIoControlrR   rX   )	deviceio_control_code	in_buffer
out_buffer
overlappedin_buffer_sizeout_buffer_sizereturned_bytesr   s	            r   r   r     s     !%&LMMj#&-j9J+4+@Yaj/*e,,,!)	
 	s#~.0N0011r   r   )i__doc__sysloggingr   osr   r   os.pathr   r   r   	os_islinkr   
os_lexistscommon.compatr
   
exceptionsr   r   __all__rC   logimplementationnamePYPYr   	os_lchmodImportErrorr   r   ctypesr   r   rV   CreateHardLinkWr   BOOLrestypeLPCWSTRr   argtypesCreateSymbolicLinkWr#   rF   AttributeErrorr!   r$   r   r   r   r%   r&   r'   r(   r)   r*   r+   rI   r}   r   r   NULLr   r3   LPWIN32_FIND_DATAFindFirstFileWr   rU   HANDLEFindNextFileWr   r   rX   r   GetFileAttributesWr   rR   rf   rh   r   r   r   r.   r   r-   r   r   r   r   LPDWORDLPOVERLAPPEDr   LPSECURITY_ATTRIBUTESCreateFileWr   r   r   r   r   r   r   r   r   r   r   rL   r   r   <module>r      s       " ' ) # 2
H
&(
!&F  DG (__44N%]]N'//1A1A8??SN	"#__@@%-]]"NN'
#V
V DG 	4FGH RRR; H'(#( DJ) J   0OO22M&oo/@AM$OOM??00L%__.?@L#++L*8??2.44:: ("*//!3!FQx,, Q0?  	*<*<	
 M#- !*%hnn%G??L
i 
 $$78,,JJ "J//--K$OO-K"**KUU?i ?2): oo55O	 O 'mmO DH2I  !!!:  "!"s%   O0 AO? 0O<;O<?P
	P
