diff -rc linux.orig/fs/ncpfs/file.c linux/fs/ncpfs/file.c
*** linux.orig/fs/ncpfs/file.c	Mon Sep 10 21:04:53 2001
--- linux/fs/ncpfs/file.c	Fri Apr 19 17:58:24 2002
***************
*** 87,99 ****
  		atomic_set(&NCP_FINFO(inode)->opened, 1);
  	}
  
! 	access = NCP_FINFO(inode)->access;
  	PPRINTK("ncp_make_open: file open, access=%x\n", access);
  	if (access == right || access == O_RDWR) {
  		atomic_inc(&NCP_FINFO(inode)->opened);
  		error = 0;
  	}
  
  out_unlock:
  	up(&NCP_FINFO(inode)->open_sem);
  out:
--- 87,197 ----
  		atomic_set(&NCP_FINFO(inode)->opened, 1);
  	}
  
! 	access = (NCP_FINFO(inode)->access) & O_ACCMODE;
  	PPRINTK("ncp_make_open: file open, access=%x\n", access);
  	if (access == right || access == O_RDWR) {
  		atomic_inc(&NCP_FINFO(inode)->opened);
  		error = 0;
  	}
  
+ out_unlock:
+ 	up(&NCP_FINFO(inode)->open_sem);
+ out:
+ 	return error;
+ }
+ 
+ int
+ ncp_openmode(struct inode *inode, struct file *file, int excl)
+ {
+ 	int error;
+ 	int right;
+ 	int access;
+ 
+ 	error = -EINVAL;
+ 	if (!inode) {
+ 		printk(KERN_ERR "ncp_openmode: got NULL inode\n");
+ 		goto out;
+ 	}
+ 
+ 	error = -EIO;
+ 	if (!ncp_conn_valid(NCP_SERVER(inode)))
+ 		goto out;
+ 
+ 	error = -EINVAL;
+ 	if (!S_ISREG(inode->i_mode)) {
+ 		DPRINTK("ncp_openmode: open non-file, mode %07o\n",
+ 			inode->i_mode);
+ 		goto out;
+ 	}
+ 
+ 	DPRINTK("ncp_openmode: opened=%d, volume # %u, dir entry # %u\n",
+ 		atomic_read(&NCP_FINFO(inode)->opened),
+ 		NCP_FINFO(inode)->volNumber,
+ 		NCP_FINFO(inode)->dirEntNum);
+ 
+ 	error = -EACCES;
+ 
+ 	down(&NCP_FINFO(inode)->open_sem);
+ 
+ 	right = file->f_flags & O_ACCMODE;
+ 
+ 	if (!atomic_read(&NCP_FINFO(inode)->opened)) {
+ 		struct ncp_entry_info finfo;
+ 		int result;
+                 int exclf;
+ 
+ 		exclf = excl?(N_AR_DENY_READ|N_AR_DENY_WRITE):0;
+ 		PPRINTK("ncp_file_open: exclusive flag %d\n", exclf);
+ 		finfo.i.dirEntNum = NCP_FINFO(inode)->dirEntNum;
+ 		finfo.i.volNumber = NCP_FINFO(inode)->volNumber;
+ 		/* tries max. rights */
+ 		finfo.access = O_RDWR;
+ 		result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+ 					NULL, NULL, OC_MODE_OPEN,
+ 					0, AR_READ | AR_WRITE | exclf, &finfo);
+ 		if (!result)
+ 			goto update;
+ 		/* RDWR did not succeeded, try readonly or writeonly as requested */
+ 		switch (right) {
+ 			case O_RDONLY:
+ 				finfo.access = O_RDONLY;
+ 				result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+ 					NULL, NULL, OC_MODE_OPEN,
+ 					0, AR_READ | exclf, &finfo);
+ 				break;
+ 			case O_WRONLY:
+ 				finfo.access = O_WRONLY;
+ 				result = ncp_open_create_file_or_subdir(NCP_SERVER(inode),
+ 					NULL, NULL, OC_MODE_OPEN,
+ 					0, AR_WRITE | exclf, &finfo);
+ 				break;
+ 		}
+ 
+ 		if (result) {
+ 			PPRINTK("ncp_file_open: failed, result=%d\n", result);
+ 			goto out_unlock;
+ 		}
+ 		/*
+ 		 * Update the inode information.
+ 		 */
+ 	update:
+         	if (excl)
+                 	finfo.access |= O_EXCL;
+ 		ncp_update_inode(inode, &finfo);
+ 		atomic_set(&NCP_FINFO(inode)->opened, 1);
+ 		error = 0;
+ 	}
+ 	else {
+         	int fl;
+ 
+ 		fl = NCP_FINFO(inode)->access;
+                 if ( excl || (fl & O_EXCL))
+                 {
+ 			PPRINTK("ncp_file_open: exclusive failed\n");
+ 			goto out_unlock;
+                 }
+ 		error = 0;
+         }
  out_unlock:
  	up(&NCP_FINFO(inode)->open_sem);
  out:
diff -rc linux.orig/fs/ncpfs/ioctl.c linux/fs/ncpfs/ioctl.c
*** linux.orig/fs/ncpfs/ioctl.c	Fri Apr 19 13:24:24 2002
--- linux/fs/ncpfs/ioctl.c	Fri Apr 19 17:59:19 2002
***************
*** 626,631 ****
--- 626,639 ----
  			return 0;
  		}
  
+ 	case NCP_IOC_OPENMODE:
+         	{
+                 	int excl;
+ 			if (get_user(excl, (int *) arg))
+ 				return -EFAULT;
+ 			return ncp_openmode(inode, filp, excl);
+                 }
+ 
  	}
  /* #ifdef CONFIG_UID16 */
  	/* NCP_IOC_GETMOUNTUID may be same as NCP_IOC_GETMOUNTUID2,
diff -rc linux.orig/include/linux/ncp_fs.h linux/include/linux/ncp_fs.h
*** linux.orig/include/linux/ncp_fs.h	Tue Apr 16 16:03:07 2002
--- linux/include/linux/ncp_fs.h	Fri Apr 19 18:00:33 2002
***************
*** 135,140 ****
--- 135,158 ----
  #define NCP_IOC_SETDENTRYTTL		_IOR('n', 12, __u32)
  
  /*
+  * This ioctl allow work in dos-specific share/exclusive open mode
+  * without using lockfiles and so on, and in compatible with dos
+  * applications way.
+  *
+  * if ioctl *arg == 0, request for share open
+  * else request for exclusive open
+  * ioctl returns EINVAL if this feature is absent (invalid ioctl),
+  * 0 on success, and other value on share errors.
+  *
+  * Paul Lasarev <paul@itk.ru>
+  */
+ #define NCP_IOC_OPENMODE		_IOW('n', 21, int)
+ 
+ #define N_AR_DENY_READ      (ntohs(0x0400))
+ #define N_AR_DENY_WRITE     (ntohs(0x0800))
+ int ncp_openmode(struct inode *inode, struct file *file, int exclusive);
+ 
+ /*
   * The packet size to allocate. One page should be enough.
   */
  #define NCP_PACKET_SIZE 4070
