o
    juR                     @   s   d dl mZmZmZ d dlmZ d dlT d dlmZ d dl	m
Z
 d dlmZ d dlZd dlZd dlZd dlmZ d d	lmZ d d
lmZ G dd dZeddedefddZdd Zedkrkd dlZee  dS dS )    )PureWindowsPathPurePathPath)FileAccessMask)*)FileInfoClass)SecurityInfo)FileAttributesN)asynccontextmanager)SMBConnection)SECURITY_DESCRIPTORc                   @   s  e Zd Zdd Zdd Zdd ZedJded	efd
dZed	efddZ	ede
defddZedefddZede
defddZede
defddZede
defddZdd Zde
fddZd ed!efd"d#ZdKd%ed&efd'd(ZdLde
d+efd,d-ZejejB fde
d.efd/d0Zde
d+efd1d2ZdKd!ed3efd4d5ZdMd efd7d8ZdNd ed9efd:d;Zd%efd<d=Zd>e j!fd?d@Z"dAdB Z#dCdD Z$dEefdFdGZ%dHdI Z&d*S )OSMBFilec                 C   s|   d | _ d | _d | _d | _d | _d | _d | _d | _d | _d | _	d | _
d | _d | _d | _d | _d | _d| _d| _d | _d| _d S )Nr   F )tree_id
parent_dirfullpathunc_path
share_pathnamesizecreation_timelast_access_timelast_write_timechange_timeallocation_size
attributesfile_idsecurity_descriptor_SMBFile__connection_SMBFile__positionis_pipemaxreadsizemodeself r%   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/aiosmb/commons/interfaces/file.py__init__   s(   
zSMBFile.__init__c                    s   | S Nr%   r#   r%   r%   r&   
__aenter__(   s   zSMBFile.__aenter__c                    s   |   I d H  d S r(   )close)r$   exc_typeexc_valexc_tbr%   r%   r&   	__aexit__+   s   zSMBFile.__aexit__Tbasedirr   c                 C   s   | d}td| }|jd dd}|jd }|ddkr(|d d d }|d	u r:||gt|jd
d  }n||gt|jd
d   }t| j|  }|S )N\z\\\\   ._   $T   )	lstripr   partsreplacefindlistr   joinpathresolve)r/   r   path_with_fileunchostsharedirspath_to_creater%   r%   r&   prepare_mirror_path.   s   

zSMBFile.prepare_mirror_pathc                 C   s8   t | }t }|j|_|j|_d|jdd |_|S )zh
		Creates SMBFile object from the UNC path supplied.
		Example uncpath: \\127.0.0.1\C$\temp\test.exe
		r0   r1   N)r   r   driver   r   joinr9   r   )r   r@   fr%   r%   r&   from_uncpath=   s   zSMBFile.from_uncpath
connection
remotepathc                 C   s0   d}|d dkr
d}|| j  |f }t|S )zv
		Creates SMBFile object from the connection and the remote path supplied.
		Example remotepath: \C$\temp\test.exe
		z\\%s\%sr   r0   \\%s%s)targetget_hostname_or_ipr   rI   )rJ   rK   tempr@   r%   r%   r&   from_remotepathK   s
   
zSMBFile.from_remotepathrM   c                 C   sP   | j du rdS | j dd}|ddu rd| }d}||  |f }t|S )z3
		Creates SMBFile object from the SMBUrl object
		N/r0   FrL   )pathr:   
startswithrN   r   rI   )rM   fpathrO   r@   r%   r%   r&   from_smbtargetW   s   

zSMBFile.from_smbtargetpipenamec                 C   s   t d| j |f S )Nz\\%s\IPC$\%s)r   rI   rM   rN   )rJ   rV   r%   r%   r&   from_pipenamef   s   zSMBFile.from_pipenamec              
      s   z^t |}| |jI d H \}}|d ur||j}tjtjB }tj	}t
jt
jB }tj}	d}
| j||j||||	|
ddI d H \}}|d urH||d urU| ||I d H  | |I d H  W dS  tyu } z
d|fW  Y d }~S d }~ww Nr   Freturn_replyTN)r   rI   tree_connectr   r   r   DELETEFILE_READ_ATTRIBUTESShareAccessFILE_SHARE_DELETECreateOptionsFILE_NON_DIRECTORY_FILEFILE_DELETE_ON_CLOSECreateDisposition	FILE_OPENcreater   r*   tree_disconnect	ExceptionrJ   rK   remfile
tree_entryerrr   desired_access
share_modecreate_optionscreate_disposition
file_attrsr   er%   r%   r&   
delete_uncj   s.   
&zSMBFile.delete_uncc              
      s   z_t | |}| |jI d H \}}|d ur||j}tjtjB }tj	}t
jt
jB }tj}	d}
| j||j||||	|
ddI d H \}}|d urI||d urV| ||I d H  | |I d H  W dS  tyv } z
d|fW  Y d }~S d }~ww rX   )r   rP   r\   r   r   r   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   r   r*   rg   rh   ri   r%   r%   r&   delete_rempath   s.   &zSMBFile.delete_rempathc              
      s   zd|   I dH  | j| jI dH \}}|dur||j}tjtjB }tj	}t
jt
jB }tj}d}| jj|| j|||||ddI dH \}	}|durL||	durZ| j ||	I dH  | j|I dH  W dS  ty{ }
 z
d|
fW  Y d}
~
S d}
~
ww )zcDeletes the file. If the file is open, a flush will be performed followed by a close then a delete.Nr   FrY   r[   )r*   r   r\   r   r   r   r]   r^   r_   r`   ra   rb   rc   rd   re   rf   r   rg   rh   )r$   rk   rl   r   rm   rn   ro   rp   rq   r   rr   r%   r%   r&   delete   s@   zSMBFile.deletec              
      s  | j du rd}zzi| j}| jdu r&|| jI dH \}}|dur#||j}tj}tj}tj	tj
B }d}	tj}
||| j||||
|	I dH \}}|durN||j||tjtjtjtjB tjB tjB ddI dH \| _ }|durq|W n7 ty } z+d|fW  Y d}~W |dur|||I dH  |dur| jdu r||I dH  S S S d}~ww W |dur|||I dH  |dur| jdu r||I dH  n!|dur|||I dH  |dur| jdu r||I dH  w w w | j dfS )z,Fetches the security descriptor of the file.Nr   )	info_typeinformation_classadditional_informationflags)r   r   r\   r   r   READ_CONTROLr_   FILE_SHARE_READra   rb   FILE_SYNCHRONOUS_IO_NONALERTrd   re   rf   r   
query_infoQueryInfoTypeSECURITYr   NONEr   ATTRIBUTE_SECURITY_INFORMATIONDACL_SECURITY_INFORMATIONOWNER_SECURITY_INFORMATIONGROUP_SECURITY_INFORMATIONrh   r*   rg   )r$   rJ   r   r   rk   rl   rm   rn   ro   rq   rp   rr   r%   r%   r&   get_security_descriptor   sd   

"
zSMBFile.get_security_descriptorr   offsetc           	         s  | j dkr| jj| j| j||dI dH \}}}||fS d}|| jjkrc|| jj }t|d D ]*}| jj| j| j|| jjdI dH \}}}|durPd|f  S |t|7 }||7 }q0|d| |fS | jj| j| j|| jjdI dH \}}}|durd|fS ||7 }|d| |fS )a!  
		This is the main function for reading.
		It does not do buffering, so if more data is returned it will just discard it
		If less data is returned than requested it will do more reads until the requested size is reached.
		Do not call this directly as it could go in an infinite loop 
		T)r   lengthN    r1   )r    r   readr   r   MaxReadSizerangelen)	r$   r   r   data	remainingrl   bufferir3   r%   r%   r&   __read   s&   
$(
(zSMBFile.__readr   r   position_in_filec           	   
      s   z@t |}d}d}|dkr=| jj| j| j||t | || dI dH \}}|dur-|||7 }||8 }||7 }|dks|dfW S  tyW } z
d|fW  Y d}~S d}~ww )z
		Data must be bytes
		r   )r   N)r   r   writer   r   rh   )	r$   r   r   r   total_bytes_writtenr   bytes_writtenrl   rr   r%   r%   r&   __write  s$   2
zSMBFile.__writerNr"   c              
      s  z|| _ |j| _|| _d| jv rd| _d| _| js/|| jI d H \}}|d ur+||j| _d|v r;d|v r;t	dd|v r|t
jt
jB }|d u rLtjn|}tjtjB }d}tj}	|j| j| j||||	|ddI d H \| _}
}|d uru||
j| _W d	S d|v rt
jt
jB }|d u rtjtjB n|}tjtjB }d}tj}	|j| j| j||||	|ddI d H \| _}
}|d ur||
j| _W d	S td ty } z
d
|fW  Y d }~S d }~ww )NpTr   r   wz(must have exactly one of read/write moderY   z/ONLY read and write is supported at the moment!r[   F)r   r   r!   r"   r    r   r   r\   r   
ValueErrorr   FILE_READ_DATAr^   r_   r{   ra   rb   r|   rd   re   rf   r   r   	EndofFileGENERIC_READGENERIC_WRITEFILE_SHARE_WRITEFILE_OPEN_IFrh   )r$   rJ   r"   rn   rk   rl   rm   ro   rq   rp   	smb_replyrr   r%   r%   r&   open#  sT   
,,zSMBFile.open
local_pathc           
   
      s  zz| j du r
dnd}| jrtd| jdurtd| j|d|dI dH \}}|dur/|t|}| r=|| j}t|d%}| 	 2 z3 dH W \}}|durU||sY n|
| qG6 W d   n1 sjw   Y  t| dfW W |  I dH  | j dur|du r|| j I dH  S S S  ty }	 z&d|	fW  Y d}	~	W |  I dH  | j dur|du r|| j I dH  S S S d}	~	ww |  I dH  | j dur|du r|| j I dH  w w w )	z<Downloads the file to the local path. File must not be open.NTFzCannot download a pipe!z,Cannot download a file that is already open!r   )rn   wb)r   r    rh   r   r   r   is_dirr=   r   read_chunkedr   strabsoluter*   rg   )
r$   rJ   r   rn   	closetreer3   rl   rH   r   rr   r%   r%   r&   downloadV  sP   
zSMBFile.downloadc              
      s   z\|| _ d| _d| _d}d}d}tj}d}d|v r|tjO }d|v r(|tjO }| j | j	I d H \}}	|	d ur:|	|j
| _
| j j| j
| j|||||ddI d H \| _}
}	|	d ur[|	W dS  tys } z
d|fW  Y d }~S d }~ww )	NTr      r   r   rY   r[   F)r   r    r   rd   re   r   r   FILE_WRITE_DATAr\   r   r   rf   r   r   rh   )r$   rJ   r"   rn   rq   ro   rp   rm   rk   rl   r   rr   r%   r%   r&   	open_pipex  s4   

.zSMBFile.open_pipewhencec              
      s   zg|dkr|dk rt d|| jkrt d|| _W dS |dkrBd| j|   k r/| jk r>n t d|  j|7  _W dS t d|dkrfd| j|   k rT| jk rbn t d| j| | _W dS t dW dS  t y~ } z
d|fW  Y d}~S d}~ww )zASets the current position of the file buffer to the given offset.r   z#Offset must be > 0 when whence is 0zSeeking outside of file size!r1   r4   r[   N)rh   r   r   )r$   r   r   rr   r%   r%   r&   seek  s4   

zSMBFile.seekr6   c              
      sd  z| j du r|dkr| jj}| |dI d H \}}||fW S || jkr&d}|dkr-W dS |dkr^| j| jkr:W dS | | j| j | jI d H \}}|d urP||  jt|7  _||fW S |dkr| j| jkrkW dS || j | jkry| j| j }| || jI d H \}}|d ur||  jt|7  _||fW S W d S  ty } z
d |fW  Y d }~S d }~ww )NTr6   r   )r   N)r    r   r   _SMBFile__readr   r   r   rh   )r$   r   r   rl   rr   r%   r%   r&   r     sD   


 

zSMBFile.read	chunksizec                 C  s\  | j du r
td|dkr| jj}|dkrdV  dS |dkrX	 |}| j| j |k r9| j| j }|dkr9dV  t| || jI dH \}}|du rR|  jt|7  _||fV  q |dkr| j| jkrgdV  t|| j | jkru| j| j }	 |}|| j |k r|| j }|dkrdV  t| || jI dH \}}|du r|  jt|7  _||fV  qvdS )aH  
		Much like read, but yields chuks of chunksize untill the full size is read
		Use this when reading large files as a whole, as this method doesn't caches 
		the whole data read in memory, only chunskize
		chunksize -1 will use the maximum chunk allowed by the underlying connection layer, it is advised to not set manually!
		TzCant stream pipes!r6   r   )NNN)	r    rh   r   r   r   r   StopIterationr   r   )r$   r   r   req_sizer   rl   r%   r%   r&   r     sN   




zSMBFile.read_chunkedc              
      s   zht || jjk r-| || jI dH \}}|dur|| jdkr(|  j|7  _|dfW S d}|t |kre| |||| jj  | jI dH \}}|durO|||7 }| jdkr_|  j|7  _|t |ks5|dfW S  ty } z
d|fW  Y d}~S d}~ww )z=Writes the given bytes to the file from the current position.NFr   )r   r   MaxWriteSize_SMBFile__writer   r    rh   )r$   r   countrl   total_writenrr   r%   r%   r&   r     s.   

(

zSMBFile.writer   c              
      s   zD| j dkrtdd}	 tdI dH  || jj}t|dkr(|dfW S | || j	I dH \}}|dur:||  j	|7  _	||7 }q ty[ } z
d|fW  Y d}~S d}~ww )zVWrites the contents of the buffer(or file handle) to the file. Doesnt work with pipes!TzDoesnt work with pipes!r   N)
r    rh   asynciosleepr   r   r   r   r   r   )r$   r   r   chunkr   rl   rr   r%   r%   r&   write_buffer"  s(   

zSMBFile.write_bufferc                    s,   d| j vrdS | j| j| jI dH  dS )z*Issues a flush command on the SMB protocolr   N)r"   r   flushr   r   r#   r%   r%   r&   r   8  s   
zSMBFile.flushc                    sV   | j du rdS | jdu rdS z	|  I dH  W n   Y | j| j| j I dH  dS )z$Closes the file including the fileIdN)r   r   r   r   r*   r#   r%   r%   r&   r*   >  s   

zSMBFile.closereturnc                 C   s   | j S )z Returns current position in file)r   r#   r%   r%   r&   tellK  s   zSMBFile.tellc                 C   s6   d}| j D ]}|drq|d|| j | f 7 }q|S )Nz===== FILE =====
parent_z	%s : %s
)__dict__rS   )r$   tkr%   r%   r&   __str__O  s   

zSMBFile.__str__)T)r   r   N)r6   )r6   r6   )'__name__
__module____qualname__r'   r)   r.   staticmethodr   rE   rI   r   rP   rU   rW   rs   rt   ru   r   intr   bytesr   r   r_   r{   r   r   r   r   r   r   r   ioBytesIOr   r   r*   r   r   r%   r%   r%   r&   r      sD    &*3"(2r   r   rR   r   c              	   C  s  z|   drddlm} || }|du rp| }|4 I dH B | I dH \}}|dur2|| }|||I dH \}}|durG||V  	 W d  I dH  W |durb|	 I dH  dS dS 1 I dH sjw   Y  nR| }|||I dH \}}|dur||V  W |dur|	 I dH  dS dS t
|| }|||I dH \}}|dur||V  W |dur|	 I dH  dS dS W |dur|	 I dH  dS dS |dur|	 I dH  w w )zj
	Opens a file on the remote server
	path can be a smb:// url or a path like \\server\share\path\to\file
	smbr   SMBConnectionFactoryN)lowerrS   !aiosmb.commons.connection.factoryr   from_urlget_connectionloginget_filer   r*   r   rP   )rR   r"   rJ   r   factoryr3   rl   filer%   r%   r&   smb_openX  s\   
	r   c               	      s"  d} t | d4 I d H }|dI d H \}}t| tt| W d   I d H  n1 I d H s1w   Y  ddlm} ||  }| I d H \}}|d urR|t dd|d4 I d H &}	 |dI d H \}}t| tt| |d	krxnq_W d   I d H  n1 I d H sw   Y  t d
d|d4 I d H }|	dI d H \}}|d urt| W d   I d H  n1 I d H sw   Y  t d
d|d4 I d H 3}|dI d H \}}|d urt| 	 W d   I d H  d S t| tt| W d   I d H  n1 I d H sw   Y  td d S )NzSsmb2+ntlm-password://TEST\Administrator:Passw0rd!1@10.10.10.2/C$/temp/repodata.jsonrbi   r   r   zC$/temp/repodata.json)rJ   Tr   zC$/temp/repodata1.jsonr   s   HELLOzDONE!)
r   r   printr   r   r   r   r   r   r   )urlrH   r   rl   r   rJ   r3   r%   r%   r&   amain  sJ   (((*r   __main__r   )pathlibr   r   r   aiosmb.wintypes.access_maskr   aiosmb.protocol.smb2.commands-aiosmb.wintypes.fscc.structures.fileinfoclassr   (aiosmb.protocol.smb2.commands.query_infor   #aiosmb.wintypes.fscc.FileAttributesr	   r   datetimer   
contextlibr
   aiosmb.connectionr   winacl.dtyp.security_descriptorr   r   r   r   r   r   runr%   r%   r%   r&   <module>   s0        M($