|
Re: SmbFile.getDiskFreeSpace bug: msg#00132network.samba.java
The Windows Explorer is reporting the correct value. Windows XP is using information level 1007 instead of information level 1 which JCIFS uses. According the the Samba sources this isOf course it didn't work on their machine... I just copied the int64 handling from Trans2QueryFSInformationResponse.readSmbQueryFSSizeInfoWireFormat(). That code doesn't work when actually more than 32 bit of the int64 are used. I'm now using readInt8() and it works fine. I also fixed readSmbQueryFSSizeInfoWireFormat(). I attached the fixed version of the patch. Thomas diff -Naur jcifs_1.1.7_org/src/jcifs/smb/SmbFile.java jcifs_1.1.7/src/jcifs/smb/SmbFile.java --- jcifs_1.1.7_org/src/jcifs/smb/SmbFile.java 2005-01-16 18:55:22.000000000 +0100 +++ jcifs_1.1.7/src/jcifs/smb/SmbFile.java 2005-01-27 14:03:50.203000000 +0100 @@ -2183,21 +2183,35 @@ */ public long getDiskFreeSpace() throws SmbException { if( getType() == TYPE_SHARE || type == TYPE_FILESYSTEM ) { - Trans2QueryFSInformationResponse response; - int level = Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION; - - response = new Trans2QueryFSInformationResponse( level ); - sendTransaction( new Trans2QueryFSInformation( level ), response ); - - if( type == TYPE_SHARE ) { - size = response.info.getCapacity(); - sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; + try { + return queryFSInformation(Trans2QueryFSInformationResponse.SMB_FS_FULL_SIZE_INFORMATION); } - - return response.info.getFree(); + catch(SmbException ex) { + if(ex.getNtStatus() == NtStatus.NT_STATUS_INVALID_INFO_CLASS) { + // SMB_FS_FULL_SIZE_INFORMATION not supported by the server. + return queryFSInformation(Trans2QueryFSInformationResponse.SMB_INFO_ALLOCATION); + } + + throw ex; + } + } return 0L; } + + private long queryFSInformation( int level ) throws SmbException { + Trans2QueryFSInformationResponse response; + + response = new Trans2QueryFSInformationResponse( level ); + sendTransaction( new Trans2QueryFSInformation( level ), response ); + + if( type == TYPE_SHARE ) { + size = response.info.getCapacity(); + sizeExpiration = System.currentTimeMillis() + attrExpirationPeriod; + } + + return response.info.getFree(); + } /** * Creates a directory with the path specified by this diff -Naur jcifs_1.1.7_org/src/jcifs/smb/Trans2QueryFSInformationResponse.java jcifs_1.1.7/src/jcifs/smb/Trans2QueryFSInformationResponse.java --- jcifs_1.1.7_org/src/jcifs/smb/Trans2QueryFSInformationResponse.java 2005-01-16 18:55:22.000000000 +0100 +++ jcifs_1.1.7/src/jcifs/smb/Trans2QueryFSInformationResponse.java 2005-01-27 21:09:10.453125000 +0100 @@ -25,6 +25,7 @@ // information levels static final int SMB_INFO_ALLOCATION = 1; static final int SMB_QUERY_FS_SIZE_INFO = 0x103; + static final int SMB_FS_FULL_SIZE_INFORMATION = 1007; class SmbInfoAllocation implements AllocInfo { long alloc; // Also handles SmbQueryFSSizeInfo @@ -77,6 +78,8 @@ return readSmbInfoAllocationWireFormat( buffer, bufferIndex ); case SMB_QUERY_FS_SIZE_INFO: return readSmbQueryFSSizeInfoWireFormat( buffer, bufferIndex ); + case SMB_FS_FULL_SIZE_INFORMATION: + return readFsFullSizeInformationWireFormat( buffer, bufferIndex ); default: return 0; } @@ -110,19 +113,42 @@ SmbInfoAllocation info = new SmbInfoAllocation(); - info.alloc = readInt4( buffer, bufferIndex ); - bufferIndex += 4; - info.alloc |= readInt4( buffer, bufferIndex ) << 32L; - bufferIndex += 4; + info.alloc = readInt8( buffer, bufferIndex ); + bufferIndex += 8; - info.free = readInt4( buffer, bufferIndex ); + info.free = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + info.sectPerAlloc = readInt4( buffer, bufferIndex ); bufferIndex += 4; - info.free |= readInt4( buffer, bufferIndex ) << 32L; + + info.bytesPerSect = readInt4( buffer, bufferIndex ); bufferIndex += 4; + this.info = info; + + return bufferIndex - start; + } + int readFsFullSizeInformationWireFormat( byte[] buffer, int bufferIndex ) + { + int start = bufferIndex; + + SmbInfoAllocation info = new SmbInfoAllocation(); + + // Read total allocation units. + info.alloc = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + // read caller available allocation units + info.free = readInt8( buffer, bufferIndex ); + bufferIndex += 8; + + // skip actual free units + bufferIndex += 8; + info.sectPerAlloc = readInt4( buffer, bufferIndex ); bufferIndex += 4; - + info.bytesPerSect = readInt4( buffer, bufferIndex ); bufferIndex += 4; @@ -130,6 +156,7 @@ return bufferIndex - start; } + public String toString() { return new String( "Trans2QueryFSInformationResponse[" + super.toString() + "]" ); |
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: Batching command in CIFS: 00132, Cellina Lin |
|---|---|
| Next by Date: | Re: Hung threads accessing domain controller: 00132, Scott Christensen |
| Previous by Thread: | Re: SmbFile.getDiskFreeSpace bugi: 00132, Thomas Krammer |
| Next by Thread: | Re: SmbFile.getDiskFreeSpace bug: 00132, Michael B Allen |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |