hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
713 stars 180 forks source link

STATUS_SHARING_VIOLATION != Object Name Not Found #592

Closed bill01568 closed 3 years ago

bill01568 commented 3 years ago

I'm trying to open a file on the server in such a way that the open will fail if the file is still being written by another process. I locked the file from the server side, then opened the file, received an exception and checked the status values. Status code matches STATUS_OBJECT_NAME_NOT_FOUND even though the exception displays as STATUS_SHARING_VIOLATION! Am I performing the EnumSet checking correctly?

Log entry: diskShare.openFile(): Object Name Not Found: com.hierynomus.mssmb2.SMBApiException: STATUS_SHARING_VIOLATION (0xc0000043): Create failed for \T04512S001.hbc.com\c$\Token\TTM_1512_222_20201111_5.txt

Code:

  File serverFile;
  try {
     action = "diskShare.openFile()";
     serverFile = diskShare.openFile(
        from,
        EnumSet.of(AccessMask.GENERIC_ALL), // TODO: Is this the best access?
        EnumSet.of(FileAttributes.FILE_ATTRIBUTE_NORMAL),
        SMB2ShareAccess.ALL,
        SMB2CreateDisposition.FILE_OPEN, // FILE_OPEN: If the file already exists, return success; otherwise, fail the operation.
        EnumSet.of(SMB2CreateOptions.FILE_SEQUENTIAL_ONLY)
     );
  } catch (SMBApiException e) {
     // STATUS_OBJECT_NAME_NOT_FOUND (0xc0000034): Create failed for \\T04512S001.hbc.com\c$\DToken
     // STATUS_SHARING_VIOLATION (0xc0000043): Create failed for \\T04512S001.hbc.com\c$\Token\TTM_1512_222_20201111_5.txt
     if (EnumWithValue.EnumUtils.isSet(e.getStatusCode(), NtStatus.**STATUS_OBJECT_NAME_NOT_FOUND**)) {
        logger.info("    " + action + ": **Object Name Not Found**: " + e);
     } else if (EnumWithValue.EnumUtils.isSet(e.getStatusCode(), NtStatus.**STATUS_SHARING_VIOLATION**)) {
        logger.info("    " + action + ": Sharing Violation: " + e);
     } else {
        logger.error("    " + action + ": unknown status code: " + e);
     }
     return false;
  }
bill01568 commented 3 years ago

I had been searching for a while for example code that checked/compared the status code. I finally found some, and I was indeed doing it wrong. This works:

  } catch (SMBApiException e) {
     NtStatus ntStatus = NtStatus.valueOf(e.getStatusCode());
     if (ntStatus.equals(NtStatus.STATUS_OBJECT_NAME_NOT_FOUND)) {
        logger.info("    " + action + ": Object Name Not Found: " + e);
     } else if (ntStatus.equals(NtStatus.STATUS_SHARING_VIOLATION)) {
        logger.info("    " + action + ": Sharing Violation: " + e);
     } else {
        logger.error("    " + action + ": unknown status code: " + e);
     }
     return false;
  }

Closing this issue! Thanks, Bill