(self, service_name, path, file_obj, callback, errback, starting_offset, truncate = False, timeout = 30, show_progress = False, tqdm_kwargs = { })
| 2559 | self._storeFileFromOffset_SMB1(service_name, path, file_obj, callback, errback, 0, True, timeout, show_progress, tqdm_kwargs) |
| 2560 | |
| 2561 | def _storeFileFromOffset_SMB1(self, service_name, path, file_obj, callback, errback, starting_offset, truncate = False, timeout = 30, show_progress = False, tqdm_kwargs = { }): |
| 2562 | if not self.has_authenticated: |
| 2563 | raise NotReadyError('SMB connection not authenticated') |
| 2564 | |
| 2565 | path = path.replace('/', '\\') |
| 2566 | messages_history = [ ] |
| 2567 | |
| 2568 | def sendOpen(tid): |
| 2569 | m = SMBMessage(ComOpenAndxRequest(filename = path, |
| 2570 | access_mode = 0x0041, # Sharing mode: Deny nothing to others + Open for writing |
| 2571 | open_mode = 0x0012 if truncate else 0x0011, # Create file if file does not exist. Overwrite or append depending on truncate parameter. |
| 2572 | search_attributes = SMB_FILE_ATTRIBUTE_HIDDEN | SMB_FILE_ATTRIBUTE_SYSTEM, |
| 2573 | timeout = timeout * 1000)) |
| 2574 | m.tid = tid |
| 2575 | self._sendSMBMessage(m) |
| 2576 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, openCB, errback) |
| 2577 | self._pushToArray(messages_history, m) |
| 2578 | |
| 2579 | def openCB(open_message, **kwargs): |
| 2580 | self._pushToArray(messages_history, open_message) |
| 2581 | if not open_message.status.hasError: |
| 2582 | if show_progress: |
| 2583 | tqdm_kwargs.setdefault("unit", "B") |
| 2584 | tqdm_kwargs.setdefault("unit_scale", True) |
| 2585 | tqdm_kwargs.setdefault("unit_divisor", 1024) |
| 2586 | tqdm_kwargs.setdefault("desc", f"Uploading {path}") |
| 2587 | self.pbar = tqdm(**tqdm_kwargs) |
| 2588 | sendWrite(open_message.tid, open_message.payload.fid, starting_offset) |
| 2589 | else: |
| 2590 | errback(OperationFailure('Failed to store %s on %s: Unable to open file' % ( path, service_name ), messages_history)) |
| 2591 | |
| 2592 | def sendWrite(tid, fid, offset): |
| 2593 | # [MS-SMB] 2.2.4.5.2.2: The total SMB message size (inclusive of SMB header) must be not exceed the max_buffer_size. |
| 2594 | write_count = min(self.max_buffer_size-64, 0xFFFF-64) # SMB header is 32-bytes. We factor in another 32-bytes for the message parameter block |
| 2595 | data_bytes = file_obj.read(write_count) |
| 2596 | data_len = len(data_bytes) |
| 2597 | if data_len > 0: |
| 2598 | m = SMBMessage(ComWriteAndxRequest(fid = fid, offset = offset, data_bytes = data_bytes)) |
| 2599 | m.tid = tid |
| 2600 | self._sendSMBMessage(m) |
| 2601 | self.pending_requests[m.mid] = _PendingRequest(m.mid, int(time.time()) + timeout, writeCB, errback, fid = fid, offset = offset+data_len) |
| 2602 | else: |
| 2603 | if self.pbar: |
| 2604 | self.pbar.close() |
| 2605 | self.pbar = None |
| 2606 | closeFid(tid, fid) |
| 2607 | callback(( file_obj, offset )) # Note that this is a tuple of 2-elements |
| 2608 | |
| 2609 | def writeCB(write_message, **kwargs): |
| 2610 | # To avoid crazy memory usage when saving large files, we do not save every write_message in messages_history. |
| 2611 | if not write_message.status.hasError: |
| 2612 | if self.pbar: |
| 2613 | self.pbar.update(kwargs['offset']) |
| 2614 | sendWrite(write_message.tid, kwargs['fid'], kwargs['offset']) |
| 2615 | else: |
| 2616 | if self.pbar: |
| 2617 | self.pbar.close() |
| 2618 | self.pbar = None |
no test coverage detected