diff --git a/source/java/org/alfresco/filesys/server/filesys/FileName.java b/source/java/org/alfresco/filesys/server/filesys/FileName.java index 512bdb2cb3..ee982ff684 100644 --- a/source/java/org/alfresco/filesys/server/filesys/FileName.java +++ b/source/java/org/alfresco/filesys/server/filesys/FileName.java @@ -48,8 +48,6 @@ public final class FileName public static String buildPath(String dev, String path, String filename, char sep) { - // Debug.println ( "BuildPath: dev=" + dev + ", path=" + path + ",filename=" + filename); - // Build the path string StringBuffer fullPath = new StringBuffer(); @@ -102,10 +100,6 @@ public final class FileName fullPath.append(filename); } - // Debug - - // Debug.println ( "BuildPath: " + fullPath.toString ()); - // Convert the file seperator characters in the path if we are not using the normal // DOS file seperator character. diff --git a/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java b/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java new file mode 100644 index 0000000000..d4bbd32719 --- /dev/null +++ b/source/java/org/alfresco/filesys/server/filesys/IOControlNotImplementedException.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.server.filesys; + +/** + * I/O Control Not Implemented Exception Class + * + *

This exception may be thrown by an IOCtlInterface implementation. + * + * @author gkspencer + */ +public class IOControlNotImplementedException extends Exception +{ + private static final long serialVersionUID = -7107739317519497749L; + + /** + * Default constructor. + */ + public IOControlNotImplementedException() + { + super(); + } + + /** + * Class constructor. + * + * @param s java.lang.String + */ + public IOControlNotImplementedException(String s) + { + super(s); + } +} diff --git a/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java b/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java new file mode 100644 index 0000000000..0a095b7a67 --- /dev/null +++ b/source/java/org/alfresco/filesys/server/filesys/IOCtlInterface.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.server.filesys; + +import org.alfresco.filesys.server.SrvSession; +import org.alfresco.filesys.smb.SMBException; +import org.alfresco.filesys.util.DataBuffer; + +/** + * IO Control Interface + * + *

Optional interface that a DiskInterface driver can implement to enable NT I/O control function + * processing. + * + * @author gkspencer + */ +public interface IOCtlInterface +{ + /** + * Process a filesystem I/O control request + * + * @param sess Server session + * @param tree Tree connection. + * @param ctrlCode I/O control code + * @param fid File id + * @param dataBuf I/O control specific input data + * @param isFSCtrl true if this is a filesystem control, or false for a device control + * @param filter if bit0 is set indicates that the control applies to the share root handle + * @return DataBuffer + * @exception IOControlNotImplementedException + * @exception SMBException + */ + public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf, + boolean isFSCtrl, int filter) throws IOControlNotImplementedException, SMBException; +} diff --git a/source/java/org/alfresco/filesys/smb/NTIOCtl.java b/source/java/org/alfresco/filesys/smb/NTIOCtl.java index 2b773b2d17..670877f6be 100644 --- a/source/java/org/alfresco/filesys/smb/NTIOCtl.java +++ b/source/java/org/alfresco/filesys/smb/NTIOCtl.java @@ -24,60 +24,60 @@ public class NTIOCtl // Device type codes - public static final int DeviceBeep = 0x0001; - public static final int DeviceCDRom = 0x0002; - public static final int DeviceCDRomFileSystem = 0x0003; - public static final int DeviceController = 0x0004; - public static final int DeviceDataLink = 0x0005; - public static final int DeviceDFS = 0x0006; - public static final int DeviceDisk = 0x0007; - public static final int DeviceDiskFileSystem = 0x0008; - public static final int DeviceFileSystem = 0x0009; - public static final int DeviceInportPort = 0x000A; - public static final int DeviceKeyboard = 0x000B; - public static final int DeviceMailSlot = 0x000C; - public static final int DeviceMidiIn = 0x000D; - public static final int DeviceMidiOut = 0x000E; - public static final int DeviceMouse = 0x000F; - public static final int DeviceMultiUNCProvider = 0x0010; - public static final int DeviceNamedPipe = 0x0011; - public static final int DeviceNetwork = 0x0012; - public static final int DeviceNetworkBrowser = 0x0013; - public static final int DeviceNetworkFileSystem = 0x0014; - public static final int DeviceNull = 0x0015; - public static final int DeviceParallelPort = 0x0016; - public static final int DevicePhysicalNetCard = 0x0017; - public static final int DevicePrinter = 0x0018; - public static final int DeviceScanner = 0x0019; - public static final int DeviceSerialMousePort = 0x001A; - public static final int DeviceSerialPort = 0x001B; - public static final int DeviceScreen = 0x001C; - public static final int DeviceSound = 0x001D; - public static final int DeviceStreams = 0x001E; - public static final int DeviceTape = 0x001F; - public static final int DeviceTapeFileSystem = 0x0020; - public static final int DeviceTransport = 0x0021; - public static final int DeviceUnknown = 0x0022; - public static final int DeviceVideo = 0x0023; - public static final int DeviceVirtualDisk = 0x0024; - public static final int DeviceWaveIn = 0x0025; - public static final int DeviceWaveOut = 0x0026; - public static final int Device8042Port = 0x0027; - public static final int DeviceNetworkRedirector = 0x0028; - public static final int DeviceBattery = 0x0029; - public static final int DeviceBusExtender = 0x002A; - public static final int DeviceModem = 0x002B; - public static final int DeviceVDM = 0x002C; - public static final int DeviceMassStorage = 0x002D; - public static final int DeviceSMB = 0x002E; - public static final int DeviceKS = 0x002F; - public static final int DeviceChanger = 0x0030; - public static final int DeviceSmartCard = 0x0031; - public static final int DeviceACPI = 0x0032; - public static final int DeviceDVD = 0x0033; - public static final int DeviceFullScreenVideo = 0x0034; - public static final int DeviceDFSFileSystem = 0x0035; - public static final int DeviceDFSVolume = 0x0036; + public static final int DeviceBeep = 0x0001; + public static final int DeviceCDRom = 0x0002; + public static final int DeviceCDRomFileSystem = 0x0003; + public static final int DeviceController = 0x0004; + public static final int DeviceDataLink = 0x0005; + public static final int DeviceDFS = 0x0006; + public static final int DeviceDisk = 0x0007; + public static final int DeviceDiskFileSystem = 0x0008; + public static final int DeviceFileSystem = 0x0009; + public static final int DeviceInportPort = 0x000A; + public static final int DeviceKeyboard = 0x000B; + public static final int DeviceMailSlot = 0x000C; + public static final int DeviceMidiIn = 0x000D; + public static final int DeviceMidiOut = 0x000E; + public static final int DeviceMouse = 0x000F; + public static final int DeviceMultiUNCProvider = 0x0010; + public static final int DeviceNamedPipe = 0x0011; + public static final int DeviceNetwork = 0x0012; + public static final int DeviceNetworkBrowser = 0x0013; + public static final int DeviceNetworkFileSystem = 0x0014; + public static final int DeviceNull = 0x0015; + public static final int DeviceParallelPort = 0x0016; + public static final int DevicePhysicalNetCard = 0x0017; + public static final int DevicePrinter = 0x0018; + public static final int DeviceScanner = 0x0019; + public static final int DeviceSerialMousePort = 0x001A; + public static final int DeviceSerialPort = 0x001B; + public static final int DeviceScreen = 0x001C; + public static final int DeviceSound = 0x001D; + public static final int DeviceStreams = 0x001E; + public static final int DeviceTape = 0x001F; + public static final int DeviceTapeFileSystem = 0x0020; + public static final int DeviceTransport = 0x0021; + public static final int DeviceUnknown = 0x0022; + public static final int DeviceVideo = 0x0023; + public static final int DeviceVirtualDisk = 0x0024; + public static final int DeviceWaveIn = 0x0025; + public static final int DeviceWaveOut = 0x0026; + public static final int Device8042Port = 0x0027; + public static final int DeviceNetworkRedirector = 0x0028; + public static final int DeviceBattery = 0x0029; + public static final int DeviceBusExtender = 0x002A; + public static final int DeviceModem = 0x002B; + public static final int DeviceVDM = 0x002C; + public static final int DeviceMassStorage = 0x002D; + public static final int DeviceSMB = 0x002E; + public static final int DeviceKS = 0x002F; + public static final int DeviceChanger = 0x0030; + public static final int DeviceSmartCard = 0x0031; + public static final int DeviceACPI = 0x0032; + public static final int DeviceDVD = 0x0033; + public static final int DeviceFullScreenVideo = 0x0034; + public static final int DeviceDFSFileSystem = 0x0035; + public static final int DeviceDFSVolume = 0x0036; // Method types for I/O and filesystem controls @@ -150,7 +150,11 @@ public class NTIOCtl public static final int FsCtlReadFileUsnData = 58; public static final int FsCtlWriteUsnCloseRecord = 59; public static final int FsCtlExtendVolume = 60; - + + // Base value for custom control codes + + public static final int FsCtlCustom = 0x800; + /** * Extract the device type from an I/O control code * diff --git a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java b/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java index 725299586e..5bc7fc7afb 100644 --- a/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java +++ b/source/java/org/alfresco/filesys/smb/server/NTProtocolHandler.java @@ -47,6 +47,8 @@ import org.alfresco.filesys.server.filesys.FileOpenParams; import org.alfresco.filesys.server.filesys.FileSharingException; import org.alfresco.filesys.server.filesys.FileStatus; import org.alfresco.filesys.server.filesys.FileSystem; +import org.alfresco.filesys.server.filesys.IOControlNotImplementedException; +import org.alfresco.filesys.server.filesys.IOCtlInterface; import org.alfresco.filesys.server.filesys.NetworkFile; import org.alfresco.filesys.server.filesys.NotifyChange; import org.alfresco.filesys.server.filesys.PathNotFoundException; @@ -69,6 +71,7 @@ import org.alfresco.filesys.smb.NTTime; import org.alfresco.filesys.smb.PCShare; import org.alfresco.filesys.smb.PacketType; import org.alfresco.filesys.smb.SMBDate; +import org.alfresco.filesys.smb.SMBException; import org.alfresco.filesys.smb.SMBStatus; import org.alfresco.filesys.smb.WinNT; import org.alfresco.filesys.smb.server.notify.NotifyChangeEventList; @@ -476,7 +479,8 @@ public class NTProtocolHandler extends CoreProtocolHandler logger.debug("NT Session setup from user=" + user + ", password=" + (uniPwd != null ? HexDump.hexString(uniPwd) : "none") + ", ANSIpwd=" + (ascPwd != null ? HexDump.hexString(ascPwd) : "none") + ", domain=" + domain + ", os=" + clientOS - + ", VC=" + vcNum + ", maxBuf=" + maxBufSize + ", maxMpx=" + maxMpx); + + ", VC=" + vcNum + ", maxBuf=" + maxBufSize + ", maxMpx=" + maxMpx + + ", challenge=" + HexDump.hexString(m_sess.getChallengeKey())); logger.debug(" MID=" + m_smbPkt.getMultiplexId() + ", UID=" + m_smbPkt.getUserId() + ", PID=" + m_smbPkt.getProcessId()); } @@ -6633,23 +6637,106 @@ public class NTProtocolHandler extends CoreProtocolHandler protected final void procNTTransactIOCtl(SrvTransactBuffer tbuf, NTTransPacket outPkt) throws IOException, SMBSrvException { - + // Get the tree connection details int treeId = tbuf.getTreeId(); TreeConnection conn = m_sess.findConnection(treeId); - if (conn == null) - { + if (conn == null) { m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidDrive, SMBStatus.ErrDos); return; } - // Send back an error, IOctl not supported + // Unpack the request details - m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); + DataBuffer setupBuf = tbuf.getSetupBuffer(); + + int ctrlCode = setupBuf.getInt(); + int fid = setupBuf.getShort(); + boolean fsctrl = setupBuf.getByte() == 1 ? true : false; + int filter = setupBuf.getByte(); + + // Debug + + if (logger.isDebugEnabled() && m_sess.hasDebug(SMBSrvSession.DBG_TRAN)) + logger.debug("NT IOCtl code=" + NTIOCtl.asString(ctrlCode) + ", fid=" + fid + ", fsctrl=" + fsctrl + ", filter=" + filter); + + // Access the disk interface that is associated with the shared device + + DiskInterface disk = null; + try { + + // Get the disk interface for the share + + disk = (DiskInterface) conn.getSharedDevice().getInterface(); + } + catch (InvalidDeviceInterfaceException ex) { + + // Failed to get/initialize the disk interface + + m_sess.sendErrorResponseSMB(SMBStatus.NTInvalidParameter, SMBStatus.DOSInvalidData, SMBStatus.ErrDos); + return; + } + + // Check if the disk interface implements the optional IO control interface + + if ( disk instanceof IOCtlInterface) { + + // Access the IO control interface + + IOCtlInterface ioControl = (IOCtlInterface) disk; + + try { + + // Pass the request to the IO control interface for processing + + DataBuffer response = ioControl.processIOControl(m_sess, conn, ctrlCode, fid, tbuf.getDataBuffer(), fsctrl, filter); + + // Pack the response + + if ( response != null) { + + // Pack the response data block + + outPkt.initTransactReply(null, 0, response.getBuffer(), response.getLength(), 1); + outPkt.setSetupParameter(0, response.getLength()); + } + else { + + // Pack an empty response data block + + outPkt.initTransactReply(null, 0, null, 0, 1); + outPkt.setSetupParameter(0, 0); + } + } + catch (IOControlNotImplementedException ex) { + + // Return a not implemented error status + + m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); + return; + } + catch (SMBException ex) { + + // Return the specified SMB status, this should be an NT status code + + m_sess.sendErrorResponseSMB(ex.getErrorCode(), SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv); + return; + } + + // Send the IOCtl response + + m_sess.sendResponseSMB(outPkt); + } + else { + + // Send back an error, IOctl not supported + + m_sess.sendErrorResponseSMB(SMBStatus.NTNotImplemented, SMBStatus.SRVNotSupported, SMBStatus.ErrSrv); + } } - + /** * Process an NT query security descriptor transaction * diff --git a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java index 167fffeb9a..f50cf79450 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/ContentDiskDriver.java @@ -25,10 +25,12 @@ import javax.transaction.UserTransaction; import org.alfresco.config.ConfigElement; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.filesys.server.SrvSession; +import org.alfresco.filesys.server.auth.SrvAuthenticator; import org.alfresco.filesys.server.core.DeviceContext; import org.alfresco.filesys.server.core.DeviceContextException; import org.alfresco.filesys.server.filesys.AccessDeniedException; import org.alfresco.filesys.server.filesys.AccessMode; +import org.alfresco.filesys.server.filesys.DiskDeviceContext; import org.alfresco.filesys.server.filesys.DiskInterface; import org.alfresco.filesys.server.filesys.FileInfo; import org.alfresco.filesys.server.filesys.FileName; @@ -36,13 +38,24 @@ import org.alfresco.filesys.server.filesys.FileOpenParams; import org.alfresco.filesys.server.filesys.FileSharingException; import org.alfresco.filesys.server.filesys.FileStatus; import org.alfresco.filesys.server.filesys.FileSystem; +import org.alfresco.filesys.server.filesys.IOControlNotImplementedException; +import org.alfresco.filesys.server.filesys.IOCtlInterface; import org.alfresco.filesys.server.filesys.NetworkFile; +import org.alfresco.filesys.server.filesys.NotifyChange; import org.alfresco.filesys.server.filesys.SearchContext; import org.alfresco.filesys.server.filesys.SrvDiskInfo; import org.alfresco.filesys.server.filesys.TreeConnection; +import org.alfresco.filesys.smb.NTIOCtl; +import org.alfresco.filesys.smb.SMBException; +import org.alfresco.filesys.smb.SMBStatus; import org.alfresco.filesys.smb.SharingMode; import org.alfresco.filesys.smb.server.repo.FileState.FileStateStatus; +import org.alfresco.filesys.util.DataBuffer; +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.lock.LockType; import org.alfresco.service.cmr.lock.NodeLockedException; +import org.alfresco.service.cmr.repository.ContentData; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; @@ -62,13 +75,19 @@ import org.apache.commons.logging.LogFactory; * * @author Derek Hulley */ -public class ContentDiskDriver implements DiskInterface +public class ContentDiskDriver implements DiskInterface, IOCtlInterface { - private static final String KEY_STORE = "store"; - private static final String KEY_ROOT_PATH = "rootPath"; + // Logging private static final Log logger = LogFactory.getLog(ContentDiskDriver.class); + // Configuration key names + + private static final String KEY_STORE = "store"; + private static final String KEY_ROOT_PATH = "rootPath"; + + // Services and helpers + private CifsHelper cifsHelper; private TransactionService transactionService; private NamespaceService namespaceService; @@ -77,7 +96,12 @@ public class ContentDiskDriver implements DiskInterface private SearchService unprotectedSearchService; private ContentService contentService; private PermissionService permissionService; + private CheckOutCheckInService checkInOutService; + // I/O control handler + + private IOControlHandler m_ioHandler; + /** * Class constructor * @@ -147,6 +171,16 @@ public class ContentDiskDriver implements DiskInterface this.permissionService = permissionService; } + /** + * Set the check in/out service + * + * @param checkInOutService CheckOutCheckInService + */ + public void setCheckInOutService(CheckOutCheckInService checkInOutService) + { + this.checkInOutService = checkInOutService; + } + /** * Parse and validate the parameter string and create a device context object for this instance * of the shared device. The same DeviceInterface implementation may be used for multiple @@ -260,6 +294,30 @@ public class ContentDiskDriver implements DiskInterface } } } + + // Load the I/O control handler, if available + + try + { + // Load the I/O control handler class + + Object ioctlObj = Class.forName("org.alfresco.filesys.server.smb.repo.ContentIOControlHandler").newInstance(); + + // Verify that the class is an I/O control interface + + if ( ioctlObj instanceof IOControlHandler) + { + // Set the I/O control handler, and initialize + + m_ioHandler = (IOControlHandler) ioctlObj; + m_ioHandler.initialize( this, cifsHelper, transactionService, nodeService, checkInOutService); + } + } + catch (Exception ex) + { + if ( logger.isDebugEnabled()) + logger.debug("No I/O control handler available"); + } // Return the context for this shared filesystem @@ -1464,7 +1522,7 @@ public class ContentDiskDriver implements DiskInterface * @return NodeRef * @exception FileNotFoundException */ - private NodeRef getNodeForPath(TreeConnection tree, String path) + public NodeRef getNodeForPath(TreeConnection tree, String path) throws FileNotFoundException { // Check if there is a cached state for the path @@ -1516,4 +1574,36 @@ public class ContentDiskDriver implements DiskInterface { // Nothing to do } + + /** + * Process a filesystem I/O control request + * + * @param sess Server session + * @param tree Tree connection. + * @param ctrlCode I/O control code + * @param fid File id + * @param dataBuf I/O control specific input data + * @param isFSCtrl true if this is a filesystem control, or false for a device control + * @param filter if bit0 is set indicates that the control applies to the share root handle + * @return DataBuffer + * @exception IOControlNotImplementedException + * @exception SMBException + */ + public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf, + boolean isFSCtrl, int filter) + throws IOControlNotImplementedException, SMBException + { + // Validate the file id + + NetworkFile netFile = tree.findFile(fid); + if ( netFile == null || netFile.isDirectory() == false) + throw new SMBException(SMBStatus.NTErr, SMBStatus.NTInvalidParameter); + + // Check if the I/O control handler is enabled + + if ( m_ioHandler != null) + return m_ioHandler.processIOControl( sess, tree, ctrlCode, fid, dataBuf, isFSCtrl, filter); + else + throw new IOControlNotImplementedException(); + } } diff --git a/source/java/org/alfresco/filesys/smb/server/repo/IOControlHandler.java b/source/java/org/alfresco/filesys/smb/server/repo/IOControlHandler.java new file mode 100644 index 0000000000..39eafacc9f --- /dev/null +++ b/source/java/org/alfresco/filesys/smb/server/repo/IOControlHandler.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the Mozilla Public License version 1.1 + * with a permitted attribution clause. You may obtain a + * copy of the License at + * + * http://www.alfresco.org/legal/license.txt + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the + * License. + */ + +package org.alfresco.filesys.smb.server.repo; + +import org.alfresco.filesys.server.filesys.IOCtlInterface; +import org.alfresco.service.cmr.coci.CheckOutCheckInService; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.transaction.TransactionService; + +/** + * I/O Control Handler Interface + * + * @author gkspencer + */ +public interface IOControlHandler extends IOCtlInterface +{ + /** + * Initialize the I/O control handler + * + * + * @param contentDriver ContentDiskDriver + * @param cifsHelper CifsHelper + * @param transService TransactionService + * @param nodeService NodeService + * @param cociService CheckOutCheckInService + */ + public void initialize( ContentDiskDriver contentDriver, CifsHelper cifsHelper, + TransactionService transService, NodeService nodeService, CheckOutCheckInService cociService); +} diff --git a/source/java/org/alfresco/filesys/util/DataBuffer.java b/source/java/org/alfresco/filesys/util/DataBuffer.java index bc93af5e0a..8f1b8b5963 100644 --- a/source/java/org/alfresco/filesys/util/DataBuffer.java +++ b/source/java/org/alfresco/filesys/util/DataBuffer.java @@ -254,8 +254,12 @@ public class DataBuffer maxlen = availLen; ret = DataPacker.getUnicodeString(m_data, m_pos, maxlen); - if (ret != null) - m_pos += (ret.length() * 2) + 2; + if (ret != null) { + if ( ret.length() < maxlen) + m_pos += (ret.length() * 2) + 2; + else + m_pos += maxlen * 2; + } } else { @@ -269,8 +273,12 @@ public class DataBuffer // Unpack the ASCII string ret = DataPacker.getString(m_data, m_pos, maxlen); - if (ret != null) - m_pos += ret.length() + 1; + if (ret != null) { + if ( ret.length() < maxlen) + m_pos += ret.length() + 1; + else + m_pos += maxlen; + } } // Return the string