jcifs.smb.SmbException Maven / Gradle / Ivy
Show all versions of jcifs-krb5-jdk7 Show documentation
/* jcifs smb client library in Java
* Copyright (C) 2000 "Michael B. Allen"
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcifs.smb;
import java.io.IOException;
import java.io.StringWriter;
import java.io.PrintWriter;
import jcifs.util.Hexdump;
/**
* There are hundreds of error codes that may be returned by a CIFS
* server. Rather than represent each with it's own Exception
* class, this class represents all of them. For many of the popular
* error codes, constants and text messages like "The device is not ready"
* are provided.
*
* The jCIFS client maps DOS error codes to NTSTATUS codes. This means that
* the user may recieve a different error from a legacy server than that of
* a newer varient such as Windows NT and above. If you should encounter
* such a case, please report it to jcifs at samba dot org and we will
* change the mapping.
*/
public class SmbException extends IOException implements NtStatus, DosError, WinError {
static String getMessageByCode( int errcode ) {
/* Note there's a signedness error here because 0xC0000000 based values are
* negative so it with NT_STATUS_SUCCESS (0) the binary search will not be
* performed properly. The effect is that the code at index 1 is never found
* (NT_STATUS_UNSUCCESSFUL). So here we factor out NT_STATUS_SUCCESS
* as a special case (which it is).
*/
if (errcode == 0) {
return "NT_STATUS_SUCCESS";
}
if(( errcode & 0xC0000000 ) == 0xC0000000 ) {
int min = 1; /* Don't include NT_STATUS_SUCCESS */
int max = NT_STATUS_CODES.length - 1;
while( max >= min ) {
int mid = (min + max) / 2;
if( errcode > NT_STATUS_CODES[mid] ) {
min = mid + 1;
} else if( errcode < NT_STATUS_CODES[mid] ) {
max = mid - 1;
} else {
return NT_STATUS_MESSAGES[mid];
}
}
} else {
int min = 0;
int max = DOS_ERROR_CODES.length - 1;
while( max >= min ) {
int mid = (min + max) / 2;
if( errcode > DOS_ERROR_CODES[mid][0] ) {
min = mid + 1;
} else if( errcode < DOS_ERROR_CODES[mid][0] ) {
max = mid - 1;
} else {
return DOS_ERROR_MESSAGES[mid];
}
}
}
return "0x" + Hexdump.toHexString( errcode, 8 );
}
static int getStatusByCode( int errcode ) {
if(( errcode & 0xC0000000 ) != 0 ) {
return errcode;
} else {
int min = 0;
int max = DOS_ERROR_CODES.length - 1;
while( max >= min ) {
int mid = (min + max) / 2;
if( errcode > DOS_ERROR_CODES[mid][0] ) {
min = mid + 1;
} else if( errcode < DOS_ERROR_CODES[mid][0] ) {
max = mid - 1;
} else {
return DOS_ERROR_CODES[mid][1];
}
}
}
return NT_STATUS_UNSUCCESSFUL;
}
static String getMessageByWinerrCode( int errcode ) {
int min = 0;
int max = WINERR_CODES.length - 1;
while( max >= min ) {
int mid = (min + max) / 2;
if( errcode > WINERR_CODES[mid] ) {
min = mid + 1;
} else if( errcode < WINERR_CODES[mid] ) {
max = mid - 1;
} else {
return WINERR_MESSAGES[mid];
}
}
return errcode + "";
}
private int status;
private Throwable rootCause;
SmbException() {
}
SmbException( int errcode, Throwable rootCause ) {
super( getMessageByCode( errcode ));
status = getStatusByCode( errcode );
this.rootCause = rootCause;
}
SmbException( String msg ) {
super( msg );
status = NT_STATUS_UNSUCCESSFUL;
}
SmbException( String msg, Throwable rootCause ) {
super( msg );
this.rootCause = rootCause;
status = NT_STATUS_UNSUCCESSFUL;
}
public SmbException( int errcode, boolean winerr ) {
super( winerr ? getMessageByWinerrCode( errcode ) : getMessageByCode( errcode ));
status = winerr ? errcode : getStatusByCode( errcode );
}
public int getNtStatus() {
return status;
}
public Throwable getRootCause() {
return rootCause;
}
public String toString() {
if( rootCause != null ) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter( sw );
rootCause.printStackTrace( pw );
return super.toString() + "\n" + sw;
} else {
return super.toString();
}
}
}