⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cifssmb.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	} else {		/* BB improve the check for buffer overruns BB */		name_len = strnlen(fileName, 530);		name_len++;	/* trailing null */		strncpy(pSMB->fileName, fileName, name_len);	}	pSMB->SearchAttributes =	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);	pSMB->BufferFormat = 0x04;	pSMB->hdr.smb_buf_length += name_len + 1;	pSMB->ByteCount = cpu_to_le16(name_len + 1);	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cFYI(1, ("Error in RMFile = %d", rc));	} #ifdef CONFIG_CIFS_STATS        else {		atomic_inc(&tcon->num_deletes);        }#endif	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto DelFileRetry;	return rc;}intCIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,	     const char *dirName, const struct nls_table *nls_codepage){	DELETE_DIRECTORY_REQ *pSMB = NULL;	DELETE_DIRECTORY_RSP *pSMBr = NULL;	int rc = 0;	int bytes_returned;	int name_len;	cFYI(1, ("In CIFSSMBRmDir"));RmDirRetry:	rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {		name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, 530				/* find define for this maxpathcomponent */				, nls_codepage);		name_len++;	/* trailing null */		name_len *= 2;	} else {		/* BB improve the check for buffer overruns BB */		name_len = strnlen(dirName, 530);		name_len++;	/* trailing null */		strncpy(pSMB->DirName, dirName, name_len);	}	pSMB->BufferFormat = 0x04;	pSMB->hdr.smb_buf_length += name_len + 1;	pSMB->ByteCount = cpu_to_le16(name_len + 1);	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cFYI(1, ("Error in RMDir = %d", rc));	}#ifdef CONFIG_CIFS_STATS        else {		atomic_inc(&tcon->num_rmdirs);        }#endif	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto RmDirRetry;	return rc;}intCIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,	     const char *name, const struct nls_table *nls_codepage){	int rc = 0;	CREATE_DIRECTORY_REQ *pSMB = NULL;	CREATE_DIRECTORY_RSP *pSMBr = NULL;	int bytes_returned;	int name_len;	cFYI(1, ("In CIFSSMBMkDir"));MkDirRetry:	rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {		name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, 530					 /* find define for this maxpathcomponent */					 , nls_codepage);		name_len++;	/* trailing null */		name_len *= 2;	} else {		/* BB improve the check for buffer overruns BB */		name_len = strnlen(name, 530);		name_len++;	/* trailing null */		strncpy(pSMB->DirName, name, name_len);	}	pSMB->BufferFormat = 0x04;	pSMB->hdr.smb_buf_length += name_len + 1;	pSMB->ByteCount = cpu_to_le16(name_len + 1);	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cFYI(1, ("Error in Mkdir = %d", rc));	}#ifdef CONFIG_CIFS_STATS        else {		atomic_inc(&tcon->num_mkdirs);        }#endif	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto MkDirRetry;	return rc;}intCIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,	    const char *fileName, const int openDisposition,	    const int access_flags, const int create_options, __u16 * netfid,	    int *pOplock, FILE_ALL_INFO * pfile_info, 	    const struct nls_table *nls_codepage){	int rc = -EACCES;	OPEN_REQ *pSMB = NULL;	OPEN_RSP *pSMBr = NULL;	int bytes_returned;	int name_len;	__u16 count;openRetry:	rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	pSMB->AndXCommand = 0xFF;	/* none */	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {		count = 1;	/* account for one byte pad to word boundary */		name_len =		    cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1),				  fileName, 530				  /* find define for this maxpathcomponent */				  , nls_codepage);		name_len++;	/* trailing null */		name_len *= 2;		pSMB->NameLength = cpu_to_le16(name_len);	} else {		/* BB improve the check for buffer overruns BB */		count = 0;	/* no pad */		name_len = strnlen(fileName, 530);		name_len++;	/* trailing null */		pSMB->NameLength = cpu_to_le16(name_len);		strncpy(pSMB->fileName, fileName, name_len);	}	if (*pOplock & REQ_OPLOCK)		pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);	else if (*pOplock & REQ_BATCHOPLOCK) {		pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);	}	pSMB->DesiredAccess = cpu_to_le32(access_flags);	pSMB->AllocationSize = 0;	pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);	/* XP does not handle ATTR_POSIX_SEMANTICS */	/* but it helps speed up case sensitive checks for other	servers such as Samba */	if (tcon->ses->capabilities & CAP_UNIX)		pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);	/* if ((omode & S_IWUGO) == 0)		pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/	/*  Above line causes problems due to vfs splitting create into two		pieces - need to set mode after file created not while it is		being created */	pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);	pSMB->CreateDisposition = cpu_to_le32(openDisposition);	pSMB->CreateOptions = cpu_to_le32(create_options);	pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);	/* BB ??*/	pSMB->SecurityFlags =	    SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;	count += name_len;	pSMB->hdr.smb_buf_length += count;	pSMB->ByteCount = cpu_to_le16(count);	/* long_op set to 1 to allow for oplock break timeouts */	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 1);	if (rc) {		cFYI(1, ("Error in Open = %d", rc));	} else {		*pOplock = pSMBr->OplockLevel;	/* one byte no need to le_to_cpu */		*netfid = pSMBr->Fid;	/* cifs fid stays in le */		/* Let caller know file was created so we can set the mode. */		/* Do we care about the CreateAction in any other cases? */		if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)			*pOplock |= CIFS_CREATE_ACTION; 		if(pfile_info) {		    memcpy((char *)pfile_info,(char *)&pSMBr->CreationTime,			36 /* CreationTime to Attributes */);		    /* the file_info buf is endian converted by caller */		    pfile_info->AllocationSize = pSMBr->AllocationSize;		    pfile_info->EndOfFile = pSMBr->EndOfFile;		    pfile_info->NumberOfLinks = cpu_to_le32(1);		}#ifdef CONFIG_CIFS_STATS		atomic_inc(&tcon->num_opens);#endif	}	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto openRetry;	return rc;}/* If no buffer passed in, then caller wants to do the copy	as in the case of readpages so the SMB buffer must be	freed by the caller */intCIFSSMBRead(const int xid, struct cifsTconInfo *tcon,	    const int netfid, const unsigned int count,	    const __u64 lseek, unsigned int *nbytes, char **buf){	int rc = -EACCES;	READ_REQ *pSMB = NULL;	READ_RSP *pSMBr = NULL;	char *pReadData = NULL;	int bytes_returned;	*nbytes = 0;	rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	/* tcon and ses pointer are checked in smb_init */	if (tcon->ses->server == NULL)		return -ECONNABORTED;	pSMB->AndXCommand = 0xFF;	/* none */	pSMB->Fid = netfid;	pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);	pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);	pSMB->Remaining = 0;	pSMB->MaxCount = cpu_to_le16(count);	pSMB->MaxCountHigh = 0;	pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cERROR(1, ("Send error in read = %d", rc));	} else {		__u16 data_length = le16_to_cpu(pSMBr->DataLength);		*nbytes = data_length;		/*check that DataLength would not go beyond end of SMB */		if ((data_length > CIFS_MAX_MSGSIZE) 				|| (data_length > count)) {			cFYI(1,("bad length %d for count %d",data_length,count));			rc = -EIO;			*nbytes = 0;		} else {			pReadData =			    (char *) (&pSMBr->hdr.Protocol) +			    le16_to_cpu(pSMBr->DataOffset);/*			if(rc = copy_to_user(buf, pReadData, data_length)) {				cERROR(1,("Faulting on read rc = %d",rc));				rc = -EFAULT;			}*/ /* can not use copy_to_user when using page cache*/			if(*buf)			    memcpy(*buf,pReadData,data_length);		}	}	if (pSMB) {		if(*buf)			cifs_buf_release(pSMB);		else			*buf = (char *)pSMB;	}	/* Note: On -EAGAIN error only caller can retry on handle based calls 		since file handle passed in no longer valid */	return rc;}intCIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,	     const int netfid, const unsigned int count,	     const __u64 offset, unsigned int *nbytes, const char *buf,	     const int long_op){	int rc = -EACCES;	WRITE_REQ *pSMB = NULL;	WRITE_RSP *pSMBr = NULL;	int bytes_returned;	unsigned bytes_sent;	__u16 byte_count;	rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	/* tcon and ses pointer are checked in smb_init */	if (tcon->ses->server == NULL)		return -ECONNABORTED;	pSMB->AndXCommand = 0xFF;	/* none */	pSMB->Fid = netfid;	pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);	pSMB->OffsetHigh = cpu_to_le32(offset >> 32);	pSMB->Remaining = 0;	bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF;	if (bytes_sent > count)		bytes_sent = count;	pSMB->DataLengthHigh = 0;	pSMB->DataOffset =	    cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);	memcpy(pSMB->Data,buf,bytes_sent);	byte_count = bytes_sent + 1 /* pad */ ;	pSMB->DataLengthLow = cpu_to_le16(bytes_sent);	pSMB->DataLengthHigh = 0;	pSMB->hdr.smb_buf_length += byte_count;	pSMB->ByteCount = cpu_to_le16(byte_count);	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);	if (rc) {		cFYI(1, ("Send error in write = %d", rc));		*nbytes = 0;	} else		*nbytes = le16_to_cpu(pSMBr->Count);	if (pSMB)		cifs_buf_release(pSMB);	/* Note: On -EAGAIN error only caller can retry on handle based calls 		since file handle passed in no longer valid */	return rc;}intCIFSSMBLock(const int xid, struct cifsTconInfo *tcon,	    const __u16 smb_file_id, const __u64 len,	    const __u64 offset, const __u32 numUnlock,	    const __u32 numLock, const __u8 lockType, const int waitFlag){	int rc = 0;	LOCK_REQ *pSMB = NULL;	LOCK_RSP *pSMBr = NULL;	int bytes_returned;	int timeout = 0;	__u16 count;	cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));	rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {		timeout = -1; /* no response expected */		pSMB->Timeout = 0;	} else if (waitFlag == TRUE) {		timeout = 3;  /* blocking operation, no timeout */		pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */	} else {		pSMB->Timeout = 0;	}	pSMB->NumberOfLocks = cpu_to_le16(numLock);	pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);	pSMB->LockType = lockType;	pSMB->AndXCommand = 0xFF;	/* none */	pSMB->Fid = smb_file_id; /* netfid stays le */	if((numLock != 0) || (numUnlock != 0)) {		pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);		/* BB where to store pid high? */		pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);		pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));		pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);		pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));		count = sizeof(LOCKING_ANDX_RANGE);	} else {		/* oplock break */		count = 0;	}	pSMB->hdr.smb_buf_length += count;	pSMB->ByteCount = cpu_to_le16(count);	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);	if (rc) {		cFYI(1, ("Send error in Lock = %d", rc));	}	if (pSMB)		cifs_buf_release(pSMB);	/* Note: On -EAGAIN error only caller can retry on handle based calls 	since file handle passed in no longer valid */	return rc;}intCIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id){	int rc = 0;	CLOSE_REQ *pSMB = NULL;	CLOSE_RSP *pSMBr = NULL;	int bytes_returned;	cFYI(1, ("In CIFSSMBClose"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -