1 17 package org.alfresco.filesys.server.smb.repo; 18 19 import java.io.FileNotFoundException ; 20 21 import org.alfresco.filesys.server.SrvSession; 22 import org.alfresco.filesys.server.filesys.DiskDeviceContext; 23 import org.alfresco.filesys.server.filesys.FileName; 24 import org.alfresco.filesys.server.filesys.IOControlNotImplementedException; 25 import org.alfresco.filesys.server.filesys.NetworkFile; 26 import org.alfresco.filesys.server.filesys.NotifyChange; 27 import org.alfresco.filesys.server.filesys.TreeConnection; 28 import org.alfresco.filesys.smb.NTIOCtl; 29 import org.alfresco.filesys.smb.SMBException; 30 import org.alfresco.filesys.smb.SMBStatus; 31 import org.alfresco.filesys.smb.server.repo.CifsHelper; 32 import org.alfresco.filesys.smb.server.repo.ContentDiskDriver; 33 import org.alfresco.filesys.smb.server.repo.IOControlHandler; 34 import org.alfresco.filesys.util.DataBuffer; 35 import org.alfresco.model.ContentModel; 36 import org.alfresco.service.cmr.coci.CheckOutCheckInService; 37 import org.alfresco.service.cmr.lock.LockType; 38 import org.alfresco.service.cmr.repository.ContentData; 39 import org.alfresco.service.cmr.repository.NodeRef; 40 import org.alfresco.service.cmr.repository.NodeService; 41 import org.alfresco.service.transaction.TransactionService; 42 import org.apache.commons.logging.Log; 43 import org.apache.commons.logging.LogFactory; 44 45 52 public class ContentIOControlHandler implements IOControlHandler 53 { 54 56 private static final Log logger = LogFactory.getLog(ContentIOControlHandler.class); 57 58 60 private CifsHelper cifsHelper; 61 private TransactionService transactionService; 62 private NodeService nodeService; 63 private CheckOutCheckInService checkInOutService; 64 65 private ContentDiskDriver contentDriver; 66 67 70 public ContentIOControlHandler() 71 { 72 } 73 74 83 public void initialize( ContentDiskDriver contentDriver, CifsHelper cifsHelper, 84 TransactionService transService, NodeService nodeService, CheckOutCheckInService cociService) 85 { 86 this.contentDriver = contentDriver; 87 this.cifsHelper = cifsHelper; 88 this.transactionService = transService; 89 this.nodeService = nodeService; 90 this.checkInOutService = cociService; 91 } 92 93 107 public DataBuffer processIOControl(SrvSession sess, TreeConnection tree, int ctrlCode, int fid, DataBuffer dataBuf, 108 boolean isFSCtrl, int filter) 109 throws IOControlNotImplementedException, SMBException 110 { 111 113 NetworkFile netFile = tree.findFile(fid); 114 if ( netFile == null || netFile.isDirectory() == false) 115 throw new SMBException(SMBStatus.NTErr, SMBStatus.NTInvalidParameter); 116 117 119 int devType = NTIOCtl.getDeviceType(ctrlCode); 120 int ioFunc = NTIOCtl.getFunctionCode(ctrlCode); 121 122 if ( devType != NTIOCtl.DeviceFileSystem || dataBuf == null) 123 throw new IOControlNotImplementedException(); 124 125 127 if ( dataBuf.getLength() < IOControl.Signature.length()) 128 throw new IOControlNotImplementedException("Bad request length"); 129 130 String sig = dataBuf.getString(IOControl.Signature.length(), false); 131 132 if ( sig == null || sig.compareTo(IOControl.Signature) != 0) 133 throw new IOControlNotImplementedException("Bad request signature"); 134 135 137 NodeRef folderNode = null; 138 139 try 140 { 141 folderNode = contentDriver.getNodeForPath(tree, netFile.getFullName()); 142 143 if ( cifsHelper.isDirectory( folderNode) == false) 144 folderNode = null; 145 } 146 catch ( FileNotFoundException ex) 147 { 148 folderNode = null; 149 } 150 151 153 if ( folderNode == null) 154 throw new SMBException(SMBStatus.NTErr, SMBStatus.NTAccessDenied); 155 156 158 if ( logger.isInfoEnabled()) { 159 logger.info("IO control func=0x" + Integer.toHexString(ioFunc) + ", fid=" + fid + ", buffer=" + dataBuf); 160 logger.info(" Folder nodeRef=" + folderNode); 161 } 162 163 165 DataBuffer retBuffer = null; 166 167 switch ( ioFunc) 168 { 169 171 case IOControl.CmdProbe: 172 173 175 retBuffer = new DataBuffer(IOControl.Signature.length()); 176 retBuffer.putFixedString(IOControl.Signature, IOControl.Signature.length()); 177 retBuffer.putInt(IOControl.StsSuccess); 178 break; 179 180 182 case IOControl.CmdFileStatus: 183 184 186 retBuffer = procIOFileStatus( sess, tree, dataBuf, folderNode); 187 break; 188 189 191 case IOControl.CmdCheckIn: 192 193 195 retBuffer = procIOCheckIn( sess, tree, dataBuf, folderNode, netFile); 196 break; 197 198 200 case IOControl.CmdCheckOut: 201 202 204 retBuffer = procIOCheckOut( sess, tree, dataBuf, folderNode, netFile); 205 break; 206 207 209 default: 210 throw new IOControlNotImplementedException(); 211 } 212 213 215 return retBuffer; 216 } 217 218 227 private final DataBuffer procIOFileStatus( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode) 228 { 229 231 sess.beginTransaction( transactionService, true); 232 233 235 String fName = reqBuf.getString( true); 236 logger.info(" File status, fname=" + fName); 237 238 240 DataBuffer respBuf = new DataBuffer(256); 241 respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length()); 242 243 245 NodeRef childNode = null; 246 247 try 248 { 249 childNode = cifsHelper.getNodeRef( folderNode, fName); 250 } 251 catch (FileNotFoundException ex) 252 { 253 } 254 255 257 if ( childNode == null) 258 { 259 261 respBuf.putInt(IOControl.StsFileNotFound); 262 return respBuf; 263 } 264 265 267 if ( cifsHelper.isDirectory( childNode)) 268 { 269 271 respBuf.putInt(IOControl.StsSuccess); 272 respBuf.putInt(IOControl.TypeFolder); 273 } 274 else 275 { 276 278 respBuf.putInt(IOControl.StsSuccess); 279 respBuf.putInt(IOControl.TypeFile); 280 281 283 if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_WORKING_COPY)) 284 { 285 287 respBuf.putInt(IOControl.True); 288 289 291 String owner = (String ) nodeService.getProperty( childNode, ContentModel.PROP_WORKING_COPY_OWNER); 292 String copiedFrom = null; 293 294 if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_COPIEDFROM)) 295 { 296 298 NodeRef fromNode = (NodeRef) nodeService.getProperty( childNode, ContentModel.PROP_COPY_REFERENCE); 299 if ( fromNode != null) 300 copiedFrom = (String ) nodeService.getProperty( fromNode, ContentModel.PROP_NAME); 301 } 302 303 305 respBuf.putString(owner != null ? owner : "", true, true); 306 respBuf.putString(copiedFrom != null ? copiedFrom : "", true, true); 307 } 308 else 309 { 310 312 respBuf.putInt(IOControl.False); 313 } 314 315 317 if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_LOCKABLE)) 318 { 319 321 String lockTypeStr = (String ) nodeService.getProperty( childNode, ContentModel.PROP_LOCK_TYPE); 322 String lockOwner = null; 323 324 if ( lockTypeStr != null) 325 lockOwner = (String ) nodeService.getProperty( childNode, ContentModel.PROP_LOCK_OWNER); 326 327 329 if ( lockTypeStr == null) 330 respBuf.putInt(IOControl.LockNone); 331 else 332 { 333 LockType lockType = LockType.valueOf( lockTypeStr); 334 335 respBuf.putInt(lockType == LockType.READ_ONLY_LOCK ? IOControl.LockRead : IOControl.LockWrite); 336 respBuf.putString(lockOwner != null ? lockOwner : "", true, true); 337 } 338 } 339 else 340 { 341 343 respBuf.putInt(IOControl.LockNone); 344 } 345 346 348 ContentData contentData = (ContentData) nodeService.getProperty( childNode, ContentModel.PROP_CONTENT); 349 350 if ( contentData != null) 351 { 352 354 String mimeType = contentData.getMimetype(); 355 356 358 respBuf.putInt( IOControl.True); 359 respBuf.putLong( contentData.getSize()); 360 respBuf.putString( mimeType != null ? mimeType : "", true, true); 361 } 362 else 363 { 364 366 respBuf.putInt( IOControl.False); 367 } 368 } 369 370 372 return respBuf; 373 } 374 375 385 private final DataBuffer procIOCheckIn( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode, 386 NetworkFile netFile) 387 { 388 390 sess.beginTransaction( transactionService, false); 391 392 394 String fName = reqBuf.getString( true); 395 boolean keepCheckedOut = reqBuf.getInt() == IOControl.True ? true : false; 396 397 logger.info(" CheckIn, fname=" + fName + ", keepCheckedOut=" + keepCheckedOut); 398 399 401 DataBuffer respBuf = new DataBuffer(256); 402 respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length()); 403 404 406 NodeRef childNode = null; 407 408 try 409 { 410 childNode = cifsHelper.getNodeRef( folderNode, fName); 411 } 412 catch (FileNotFoundException ex) 413 { 414 } 415 416 418 if ( childNode == null) 419 { 420 422 respBuf.putInt(IOControl.StsFileNotFound); 423 return respBuf; 424 } 425 426 428 if ( cifsHelper.isDirectory( childNode)) 429 { 430 432 respBuf.putInt(IOControl.StsBadParameter); 433 } 434 else 435 { 436 438 if ( nodeService.hasAspect( childNode, ContentModel.ASPECT_WORKING_COPY)) 439 { 440 try 441 { 442 444 checkInOutService.checkin( childNode, null, null, keepCheckedOut); 445 446 448 respBuf.putInt( IOControl.StsSuccess); 449 450 452 DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); 453 if (diskCtx.hasChangeHandler()) { 454 455 457 String fileName = FileName.buildPath( netFile.getFullName(), null, fName, FileName.DOS_SEPERATOR); 458 459 461 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionRemoved, fileName); 462 } 463 } 464 catch (Exception ex) 465 { 466 468 respBuf.setPosition( IOControl.Signature.length()); 469 respBuf.putInt(IOControl.StsError); 470 respBuf.putString( ex.getMessage(), true, true); 471 } 472 } 473 else 474 { 475 477 respBuf.putInt(IOControl.StsNotWorkingCopy); 478 } 479 } 480 481 483 return respBuf; 484 } 485 486 496 private final DataBuffer procIOCheckOut( SrvSession sess, TreeConnection tree, DataBuffer reqBuf, NodeRef folderNode, 497 NetworkFile netFile) 498 { 499 501 sess.beginTransaction( transactionService, false); 502 503 505 String fName = reqBuf.getString( true); 506 507 logger.info(" CheckOut, fname=" + fName); 508 509 511 DataBuffer respBuf = new DataBuffer(256); 512 respBuf.putFixedString(IOControl.Signature, IOControl.Signature.length()); 513 514 516 NodeRef childNode = null; 517 518 try 519 { 520 childNode = cifsHelper.getNodeRef( folderNode, fName); 521 } 522 catch (FileNotFoundException ex) 523 { 524 } 525 526 528 if ( childNode == null) 529 { 530 532 respBuf.putInt(IOControl.StsFileNotFound); 533 return respBuf; 534 } 535 536 538 if ( cifsHelper.isDirectory( childNode)) 539 { 540 542 respBuf.putInt(IOControl.StsBadParameter); 543 } 544 else 545 { 546 try 547 { 548 550 NodeRef workingCopyNode = checkInOutService.checkout( childNode); 551 552 554 String workingCopyName = (String ) nodeService.getProperty( workingCopyNode, ContentModel.PROP_NAME); 555 556 558 respBuf.putInt( IOControl.StsSuccess); 559 respBuf.putString( workingCopyName, true, true); 560 561 563 DiskDeviceContext diskCtx = (DiskDeviceContext) tree.getContext(); 564 if (diskCtx.hasChangeHandler()) { 565 566 568 String fileName = FileName.buildPath( netFile.getFullName(), null, workingCopyName, FileName.DOS_SEPERATOR); 569 570 572 diskCtx.getChangeHandler().notifyFileChanged(NotifyChange.ActionAdded, fileName); 573 } 574 } 575 catch (Exception ex) 576 { 577 579 respBuf.setPosition( IOControl.Signature.length()); 580 respBuf.putInt(IOControl.StsError); 581 respBuf.putString( ex.getMessage(), true, true); 582 } 583 } 584 585 587 return respBuf; 588 } 589 } 590 | Popular Tags |