async def create( self, path: Union[str, PureWindowsPath], session: SMBv2Session, tree_id: int, requested_oplock_level: OplockLevel = OplockLevel. SMB2_OPLOCK_LEVEL_BATCH, impersonation_level: ImpersonationLevel = ImpersonationLevel. IMPERSONATION, desired_access: Union[FilePipePrinterAccessMask, DirectoryAccessMask] = FilePipePrinterAccessMask( file_read_data=True, file_read_attributes=True), file_attributes: FileAttributes = FileAttributes(normal=True), share_access: ShareAccess = ShareAccess(read=True), create_disposition: CreateDisposition = CreateDisposition.FILE_OPEN, create_options: CreateOptions = CreateOptions(non_directory_file=True), create_context_list: CreateContextList = None ) -> AsyncContextManager[CreateResponse]: """ Create/open a file or directory in an SMB share and close it once finished with it. The default parameters reflect read only access to an existing file. :param path: The share relative path of the file or directory which to operate on. :param session: An SMB session with to access the file or directory. :param tree_id: The tree ID of the SMB share where the specified file or directory will be or is located. :param requested_oplock_level: :param impersonation_level: :param desired_access: :param file_attributes: :param share_access: :param create_disposition: :param create_options: :param create_context_list: :return: """ create_response: CreateResponse = (await self._create( path=path, session=session, tree_id=tree_id, requested_oplock_level=requested_oplock_level, impersonation_level=impersonation_level, desired_access=desired_access, file_attributes=file_attributes, share_access=share_access, create_disposition=create_disposition, create_options=create_options, create_context_list=create_context_list)) yield create_response await self.close(session=session, tree_id=tree_id, file_id=create_response.file_id)
async def create_dir( self, path: Union[str, PureWindowsPath], session: SMBv2Session, tree_id: int, requested_oplock_level: OplockLevel = OplockLevel. SMB2_OPLOCK_LEVEL_NONE, impersonation_level: ImpersonationLevel = ImpersonationLevel. IMPERSONATION, desired_access: DirectoryAccessMask = DirectoryAccessMask( file_list_directory=True, file_read_attributes=True), file_attributes: FileAttributes = FileAttributes(directory=True), share_access: ShareAccess = ShareAccess(read=True), create_disposition: CreateDisposition = CreateDisposition. FILE_OPEN, create_options: CreateOptions = CreateOptions(directory_file=True), create_context_list: CreateContextList = None): """ :param path: :param session: :param tree_id: :param requested_oplock_level: :param impersonation_level: :param desired_access: :param file_attributes: :param share_access: :param create_disposition: :param create_options: :param create_context_list: :return: """ create_response: CreateResponse = (await self._create( path=path, session=session, tree_id=tree_id, requested_oplock_level=requested_oplock_level, impersonation_level=impersonation_level, desired_access=desired_access, file_attributes=file_attributes, share_access=share_access, create_disposition=create_disposition, create_options=create_options, create_context_list=create_context_list)) yield create_response await self.close(session=session, tree_id=tree_id, file_id=create_response.file_id)
async def _create( self, path: Union[str, PureWindowsPath], tree_id: int, requested_oplock_level: OplockLevel = OplockLevel. SMB2_OPLOCK_LEVEL_BATCH, impersonation_level: ImpersonationLevel = ImpersonationLevel. IMPERSONATION, desired_access: Union[ FilePipePrinterAccessMask, DirectoryAccessMask] = FilePipePrinterAccessMask( file_read_data=True, file_read_ea=True, file_read_attributes=True), file_attributes: FileAttributes = FileAttributes(normal=True), share_access: ShareAccess = ShareAccess(read=True), create_disposition: CreateDisposition = CreateDisposition. FILE_OPEN, create_options: CreateOptions = CreateOptions( non_directory_file=True), create_context_list: CreateContextList = None) -> CreateResponse: create_context_list = create_context_list if create_context_list is not None else CreateContextList( ) if self.connection.negotiated_details.dialect is not Dialect.SMB_2_1: raise NotImplementedError create_response: CreateResponse = await self.connection._obtain_response( request_message=CreateRequest( header=SMB210SyncRequestHeader( command=SMBv2Command.SMB2_CREATE, session_id=self.session_id, tree_id=tree_id, ), requested_oplock_level=requested_oplock_level, impersonation_level=impersonation_level, desired_access=desired_access, file_attributes=file_attributes, share_access=share_access, create_disposition=create_disposition, create_options=create_options, name=str(path), create_context_list=create_context_list), sign_key=self.session_key) # TODO: I need to add stuff to some connection table, don't I? # TODO: Consider what to return from this function. There is a lot of information in the response. return create_response
async def make_smbv2_transport( self, session: SMBv2Session, # TODO: Is this the correct name? pipe: str, # TODO: This argument does not make much sense to me... server_address: Optional[Union[str, IPv4Address, IPv6Address]] = None, ): async with self.tree_connect( share_name='IPC$', session=session, server_address=server_address) as (tree_id, share_type): if share_type is not ShareType.SMB2_SHARE_TYPE_PIPE: # TODO: Use proper exception. raise ValueError create_options: Dict[str, Any] = dict( path=pipe, session=session, tree_id=tree_id, requested_oplock_level=OplockLevel.SMB2_OPLOCK_LEVEL_NONE, desired_access=FilePipePrinterAccessMask(file_read_data=True, file_write_data=True), file_attributes=FileAttributes(normal=True), share_access=ShareAccess(), create_disposition=CreateDisposition.FILE_OPEN, create_options=CreateOptions(non_directory_file=True)) async with self.create(**create_options) as create_response: yield ( partial( self.read, file_id=create_response.file_id, # TODO: Not sure about this value. file_size=self.negotiated_details.max_read_size, session=session, tree_id=tree_id, use_generator=False), partial(self.write, file_id=create_response.file_id, session=session, tree_id=tree_id, offset=0, remaining_bytes=0, flags=WriteFlag()))