jborean93 / smbprotocol

Python SMBv2 and v3 Client
MIT License
316 stars 73 forks source link

Is there any way to read a file that is being used by another process? #220

Closed AdrianoCasimiro closed 1 year ago

AdrianoCasimiro commented 1 year ago

I'm trying to read a file via smb, but this file is being used by another process all day and smbclient always returns this error: smbprotocol.exceptions.SMBOSError: [Error 1] [NtStatus 0xc0000043] The process cannot access the file because it is being used by another process.

Is it possible to resolve this error using smbclient?

adiroiban commented 1 year ago

Hi,

Can you share your code used to open the file?

When you open the file for reading, is important to pass the FILE_SHARE_READ flag

Here is a quick copy paste from my openFileForReading code :)

I hope it helps

            handler = Open(tree, share_path)
            handler.create(
                impersonation_level=ImpersonationLevel.Impersonation,
                desired_access=(
                    FilePipePrinterAccessMask.FILE_READ_DATA
                    | FilePipePrinterAccessMask.FILE_READ_ATTRIBUTES
                    | FilePipePrinterAccessMask.FILE_READ_EA
                    ),
                file_attributes=SMBFileAttributes.FILE_ATTRIBUTE_NORMAL,
                share_access=ShareAccess.FILE_SHARE_READ,
                # Fail if file doesn't exist.
                create_disposition=CreateDisposition.FILE_OPEN,
                create_options=(
                    CreateOptions.FILE_NON_DIRECTORY_FILE
                    | CreateOptions.FILE_OPEN_REPARSE_POINT
                    ),
                )
AdrianoCasimiro commented 1 year ago

Hello, I used this example from the documentation:

with open_file(r"\\server\share\file.txt", mode="rb", username="admin", password="pass") as fd: file_contents = fd.read()

As I want to see bytes I passed the parameter mode="rb"

Link: https://github.com/jborean93/smbprotocol/blob/master/examples/high-level/file-management.py

AdrianoCasimiro commented 1 year ago

I found the problem, you have to pass these parameters also share_access="rw"

"Param share_access: String that specifies the type of access that is allowed when a handle to this file is opened by another process. The default is 'None' which exclusively locks the file until the file is closed. The available access values are: 'r': Allow other handles to be opened with read access. 'w': Allow other handles to be opened with write access. 'd': Allow other handles to be opened with delete access. A combination of values can be set to allow multiple access types together."

Thanks @adiroiban !

jborean93 commented 1 year ago

Yep the share access relate to the Windows FILE_SHARE_* values documented in https://learn.microsoft.com/en-us/windows/win32/fileio/creating-and-opening-files. The current behaviour defaults to how Python works when opening files on Windows with open(...). Glad you have it solved!