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

📄 cifssmb.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,	       const char *searchName, FILE_ALL_INFO * findData,	       const struct nls_table *nls_codepage){/* level 257 SMB_ */	TRANSACTION2_FFIRST_REQ *pSMB = NULL;	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;	int rc = 0;	int bytes_returned;	int name_len;	__u16 params, byte_count;	cFYI(1, ("In FindUnique"));findUniqueRetry:	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {		name_len =		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 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(searchName, 530);		name_len++;	/* trailing null */		strncpy(pSMB->FileName, searchName, name_len);	}	params = 12 + name_len /* includes null */ ;	pSMB->TotalDataCount = 0;	/* no EAs */	pSMB->MaxParameterCount = cpu_to_le16(2);	pSMB->MaxDataCount = cpu_to_le16(4000);	/* BB find exact max SMB PDU from sess structure BB */	pSMB->MaxSetupCount = 0;	pSMB->Reserved = 0;	pSMB->Flags = 0;	pSMB->Timeout = 0;	pSMB->Reserved2 = 0;	pSMB->ParameterOffset = cpu_to_le16(        offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4);	pSMB->DataCount = 0;	pSMB->DataOffset = 0;	pSMB->SetupCount = 1;	/* one byte, no need to le convert */	pSMB->Reserved3 = 0;	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);	byte_count = params + 1 /* pad */ ;	pSMB->TotalParameterCount = cpu_to_le16(params);	pSMB->ParameterCount = pSMB->TotalParameterCount;	pSMB->SearchAttributes =	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |			ATTR_DIRECTORY);	pSMB->SearchCount = cpu_to_le16(16);	/* BB increase */	pSMB->SearchFlags = cpu_to_le16(1);	pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);	pSMB->SearchStorageType = 0;	/* BB what should we set this to? BB */	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, 0);	if (rc) {		cFYI(1, ("Send error in FindFileDirInfo = %d", rc));	} else {		/* decode response */		/* BB fill in */	}	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto findUniqueRetry;	return rc;}intCIFSFindFirst(const int xid, struct cifsTconInfo *tcon,	      const char *searchName, FILE_DIRECTORY_INFO * findData,	      T2_FFIRST_RSP_PARMS * findParms,	      const struct nls_table *nls_codepage, int *pUnicodeFlag,	      int *pUnixFlag){/* level 257 SMB_ */	TRANSACTION2_FFIRST_REQ *pSMB = NULL;	TRANSACTION2_FFIRST_RSP *pSMBr = NULL;	char *response_data;	int rc = 0;	int bytes_returned;	int name_len;	__u16 params, byte_count;	cFYI(1, ("In FindFirst"));findFirstRetry:	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {		name_len =		    cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 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(searchName, 530);		name_len++;	/* trailing null */		strncpy(pSMB->FileName, searchName, name_len);	}	params = 12 + name_len /* includes null */ ;	pSMB->TotalDataCount = 0;	/* no EAs */	pSMB->MaxParameterCount = cpu_to_le16(10);	pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf -					  MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);	pSMB->MaxSetupCount = 0;	pSMB->Reserved = 0;	pSMB->Flags = 0;	pSMB->Timeout = 0;	pSMB->Reserved2 = 0;	byte_count = params + 1 /* pad */ ;	pSMB->TotalParameterCount = cpu_to_le16(params);	pSMB->ParameterCount = pSMB->TotalParameterCount;	pSMB->ParameterOffset = cpu_to_le16(offsetof(struct         smb_com_transaction2_ffirst_req, SearchAttributes) - 4);	pSMB->DataCount = 0;	pSMB->DataOffset = 0;	pSMB->SetupCount = 1;	/* one byte no need to make endian neutral */	pSMB->Reserved3 = 0;	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);	pSMB->SearchAttributes =	    cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |			ATTR_DIRECTORY);	pSMB->SearchCount = cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));	/* should this be shrunk even more ? */	pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);	/* test for Unix extensions */	if (tcon->ses->capabilities & CAP_UNIX) {		pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);		*pUnixFlag = TRUE;	} else {		pSMB->InformationLevel =		    cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);		*pUnixFlag = FALSE;	}	pSMB->SearchStorageType = 0;	/* BB what should we set this to? It is not clear if it matters BB */	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, 0);	if (rc) {		/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */		cFYI(1, ("Error in FindFirst = %d", rc));	} else {		/* decode response */		/* BB add safety checks for these memcpys */		if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)			*pUnicodeFlag = TRUE;		else			*pUnicodeFlag = FALSE;		memcpy(findParms,		       (char *) &pSMBr->hdr.Protocol +		       le16_to_cpu(pSMBr->ParameterOffset),		       sizeof (T2_FFIRST_RSP_PARMS));		response_data =		    (char *) &pSMBr->hdr.Protocol +		    le16_to_cpu(pSMBr->DataOffset);		memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));	}	if (pSMB)		cifs_buf_release(pSMB);	if (rc == -EAGAIN)		goto findFirstRetry;	return rc;}intCIFSFindNext(const int xid, struct cifsTconInfo *tcon,		FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,		const __u16 searchHandle, char * resume_file_name, int name_len,		__u32 resume_key, int *pUnicodeFlag, int *pUnixFlag){/* level 257 SMB_ */	TRANSACTION2_FNEXT_REQ *pSMB = NULL;	TRANSACTION2_FNEXT_RSP *pSMBr = NULL;	char *response_data;	int rc = 0;	int bytes_returned;	__u16 params, byte_count;	cFYI(1, ("In FindNext"));	if(resume_file_name == NULL) {		return -EIO;	}	rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	params = 14;	/* includes 2 bytes of null string, converted to LE below */	byte_count = 0;	pSMB->TotalDataCount = 0;	/* no EAs */	pSMB->MaxParameterCount = cpu_to_le16(8);	pSMB->MaxDataCount =	    cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);	pSMB->MaxSetupCount = 0;	pSMB->Reserved = 0;	pSMB->Flags = 0;	pSMB->Timeout = 0;	pSMB->Reserved2 = 0;	pSMB->ParameterOffset =  cpu_to_le16(offsetof(        struct smb_com_transaction2_fnext_req,SearchHandle) - 4);	pSMB->DataCount = 0;	pSMB->DataOffset = 0;	pSMB->SetupCount = 1;	pSMB->Reserved3 = 0;	pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);	pSMB->SearchHandle = searchHandle;	/* always kept as le */	findParms->SearchCount = 0;	/* set to zero in case of error */	pSMB->SearchCount =	    cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));	/* test for Unix extensions */	if (tcon->ses->capabilities & CAP_UNIX) {		pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);		*pUnixFlag = TRUE;	} else {		pSMB->InformationLevel =		    cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);		*pUnixFlag = FALSE;	}	pSMB->ResumeKey = resume_key;	pSMB->SearchFlags =	    cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);	/* BB add check to make sure we do not cross end of smb */	if(name_len < CIFS_MAX_MSGSIZE) {		memcpy(pSMB->ResumeFileName, resume_file_name, name_len);		byte_count += name_len;	}	params += name_len;	byte_count = params + 1 /* pad */ ;	pSMB->TotalParameterCount = cpu_to_le16(params);	pSMB->ParameterCount = pSMB->TotalParameterCount;	/* BB improve error handling here */	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, 0);	if (rc) {		if (rc == -EBADF)			rc = 0;	/* search probably was closed at end of search above */		else			cFYI(1, ("FindNext returned = %d", rc));	} else {		/* decode response */		/* BB add safety checks for these memcpys */		if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)			*pUnicodeFlag = TRUE;		else			*pUnicodeFlag = FALSE;		memcpy(findParms,		       (char *) &pSMBr->hdr.Protocol +		       le16_to_cpu(pSMBr->ParameterOffset),		       sizeof (T2_FNEXT_RSP_PARMS));		response_data =		    (char *) &pSMBr->hdr.Protocol +		    le16_to_cpu(pSMBr->DataOffset);		memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));	}	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;}intCIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle){	int rc = 0;	FINDCLOSE_REQ *pSMB = NULL;	CLOSE_RSP *pSMBr = NULL;	int bytes_returned;	cFYI(1, ("In CIFSSMBFindClose"));	rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,		      (void **) &pSMBr);	/* no sense returning error if session restarted		file handle has been closed */	if(rc == -EAGAIN)		return 0;	if (rc)		return rc;	pSMB->FileID = searchHandle;	pSMB->ByteCount = 0;	rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cERROR(1, ("Send error in FindClose = %d", rc));	}	if (pSMB)		cifs_buf_release(pSMB);	/* Since session is dead, search handle closed on server already */	if (rc == -EAGAIN)		rc = 0;	return rc;}intCIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,		const unsigned char *searchName,		unsigned char **targetUNCs,		unsigned int *number_of_UNC_in_array,		const struct nls_table *nls_codepage){/* TRANS2_GET_DFS_REFERRAL */	TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;	TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;	struct dfs_referral_level_3 * referrals = NULL;	int rc = 0;	int bytes_returned;	int name_len;	unsigned int i;	char * temp;	__u16 params, byte_count;	*number_of_UNC_in_array = 0;	*targetUNCs = NULL;	cFYI(1, ("In GetDFSRefer the path %s", searchName));	if (ses == NULL)		return -ENODEV;getDFSRetry:	rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,		      (void **) &pSMBr);	if (rc)		return rc;	pSMB->hdr.Tid = ses->ipc_tid;	pSMB->hdr.Uid = ses->Suid;	if (ses->capabilities & CAP_STATUS32) {		pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;	}	if (ses->capabilities & CAP_DFS) {		pSMB->hdr.Flags2 |= SMBFLG2_DFS;	}	if (ses->capabilities & CAP_UNICODE) {		pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;		name_len =		    cifs_strtoUCS((wchar_t *) pSMB->RequestFileName,				  searchName, 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(searchName, 530);		name_len++;	/* trailing null */		strncpy(pSMB->RequestFileName, searchName, name_len);	}	params = 2 /* level */  + name_len /*includes null */ ;	pSMB->TotalDataCount = 0;	pSMB->DataCount = 0;	pSMB->DataOffset = 0;	pSMB->MaxParameterCount = 0;	pSMB->MaxDataCount = cpu_to_le16(4000);	/* BB find exact max SMB PDU from sess structure BB */	pSMB->MaxSetupCount = 0;	pSMB->Reserved = 0;	pSMB->Flags = 0;	pSMB->Timeout = 0;	pSMB->Reserved2 = 0;	pSMB->ParameterOffset = cpu_to_le16(offsetof(        struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);	pSMB->SetupCount = 1;	pSMB->Reserved3 = 0;	pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);	byte_count = params + 3 /* pad */ ;	pSMB->ParameterCount = cpu_to_le16(params);	pSMB->TotalParameterCount = pSMB->ParameterCount;	pSMB->MaxReferralLevel = cpu_to_le16(3);	pSMB->hdr.smb_buf_length += byte_count;	pSMB->ByteCount = cpu_to_le16(byte_count);	rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,			 (struct smb_hdr *) pSMBr, &bytes_returned, 0);	if (rc) {		cFYI(1, ("Send error in GetDFSRefer = %d", rc));	} else {		/* decode response *//* BB Add logic to parse referrals here */		__u16 data_offset = le16_to_cpu(pSMBr->DataOffset);		__u16 data_count = le16_to_cpu(pSMBr->DataCount);		cFYI(1,		     ("Decoding GetDFSRefer response.  BCC: %d  Offset %d",		      pSMBr->ByteCount, data_offset));		if ((pSMBr->ByteCount < 17) || (data_offset > 512))	/* BB also check enough total bytes returned */			rc = -EIO;	/* bad smb */		else {			referrals = 			    (struct dfs_referral_level_3 *) 					(8 /* sizeof start of data block */ +					data_offset +					(char *) &pSMBr->hdr.Protocol); 			cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x",				le16_to_cpu(pSMBr->NumberOfReferrals),le16_to_cpu(pSMBr->DFSFlags), le16_to_cpu(referrals->ReferralSize),le16_to_cpu(referrals->ServerType),le16_to_cpu(referrals->ReferralFlags),le16_to_cpu(referrals->TimeToLive)));			/* BB This field is actually two bytes in from start of			   data block so we could do safety check that DataBlock			   begins at address of pSMBr->NumberOfReferrals */			*number_of_UNC_in_array = le16_to_cpu(pSMBr->NumberOfReferrals);			/* BB Fix below so can return more than one referral */			if(*number_of_UNC_in_array > 1)				*number_of_UNC_in_array = 1;			/* get the length of the strings describing refs */			name_len = 0;			for(i=0;i<*number_of_UNC_in_array;i++) {				/* make sure that DfsPathOffset not past end */				__u16 offse

⌨️ 快捷键说明

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