?? smbproto.c
字號:
if (rc < 0) return rc;
return 0;
}
int smb_connect_tree(struct smb_share *share)
{
struct smb *smb;
int rc;
char *p;
char buf[SMB_NAMELEN];
// Connect to share
smb = smb_init(share, 1);
smb->params.req.connect.andx.cmd = 0xFF;
smb->params.req.connect.password_length = strlen(share->server->password) + 1;
p = buf;
p = addstrz(p, share->server->password);
p = addstrz(p, share->sharename);
p = addstrz(p, SMB_SERVICE_DISK);
rc = smb_request(share, smb, SMB_COM_TREE_CONNECT_ANDX, 4, buf, p - buf, 0);
if (rc < 0) return rc;
share->tid = smb->tid;
share->mounttime = time(0);
return 0;
}
int smb_disconnect_tree(struct smb_share *share)
{
struct smb *smb;
// Disconnect from share
smb = smb_init(share, 1);
smb_request(share, smb, SMB_COM_TREE_DISCONNECT, 0, NULL, 0, 0);
share->tid = 0xFFFF;
return 0;
}
int smb_connect(struct smb_share *share)
{
struct smb_server *server = share->server;
struct smb *smb;
struct sockaddr_in sin;
int rc;
unsigned short max_mpx_count;
char *p;
char buf[SMB_NAMELEN];
// Connect to SMB server on port 445
rc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP, &server->sock);
if (rc < 0) return rc;
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = server->ipaddr.addr;
sin.sin_port = htons(445);
rc = connect(server->sock, (struct sockaddr *) &sin, sizeof(sin));
if (rc < 0) goto error;
// Negotiate protocol version
smb = smb_init(share, 1);
rc = smb_request(share, smb, SMB_COM_NEGOTIATE, 0, "\002NT LM 0.12", 12, 0);
if (rc < 0) goto error;
if (smb->params.rsp.negotiate.dialect_index == 0xFFFF)
{
rc = -EREMOTEIO;
goto error;
}
server->tzofs = smb->params.rsp.negotiate.server_timezone * 60;
server->server_caps = smb->params.rsp.negotiate.capabilities;
server->max_buffer_size = smb->params.rsp.negotiate.max_buffer_size;
max_mpx_count = smb->params.rsp.negotiate.max_mpx_count;
// Setup session
smb = smb_init(share, 1);
smb->params.req.setup.andx.cmd = 0xFF;
smb->params.req.setup.max_buffer_size = (unsigned short) SMB_MAX_BUFFER;
smb->params.req.setup.max_mpx_count = max_mpx_count;
smb->params.req.setup.ansi_password_length = strlen(server->password) + 1;
smb->params.req.setup.unicode_password_length = 0;
smb->params.req.setup.capabilities = SMB_CAP_NT_SMBS;
p = buf;
p = addstrz(p, server->password);
p = addstrz(p, server->username);
p = addstrz(p, server->domain);
p = addstrz(p, SMB_CLIENT_OS);
p = addstrz(p, SMB_CLIENT_LANMAN);
rc = smb_request(share, smb, SMB_COM_SESSION_SETUP_ANDX, 13, buf, p - buf, 0);
if (rc < 0) goto error;
server->uid = smb->uid;
return 0;
error:
if (server->sock)
{
closesocket(server->sock);
server->sock = NULL;
}
return rc;
}
int smb_disconnect(struct smb_share *share)
{
struct smb_server *server = share->server;
struct smb *smb;
if (server->sock)
{
// Logoff server
if (server->uid != 0xFFFF)
{
smb = smb_init(share, 1);
smb->params.andx.cmd = 0xFF;
smb_request(share, smb, SMB_COM_LOGOFF_ANDX, 2, NULL, 0, 0);
server->uid = 0xFFFF;
}
// Close socket
closesocket(server->sock);
server->sock = NULL;
}
return 0;
}
int smb_get_connection(struct smb_share *share, struct ip_addr *ipaddr, char *domain, char *username, char *password)
{
struct smb_server *server;
int rc;
// Try to find existing connection to server
server = servers;
while (server)
{
if (ip_addr_cmp(&server->ipaddr, ipaddr))
{
// Add share to server
share->server = server;
share->next = server->shares;
server->shares = share;
server->refcnt++;
return 0;
}
server = server->next;
}
// Allocate new server block
server = (struct smb_server *) kmalloc(sizeof(struct smb_server));
if (!server) return -ENOMEM;
memset(server, 0, sizeof(struct smb_server));
server->ipaddr = *ipaddr;
strcpy(server->domain, domain);
strcpy(server->username, username);
strcpy(server->password, password);
server->uid = 0xFFFF;
init_mutex(&server->lock, 0);
// Add share to server
share->tid = 0xFFFF;
share->server = server;
share->next = server->shares;
server->shares = share;
server->refcnt++;
// Connect to server
rc = smb_connect(share);
if (rc < 0)
{
share->server = NULL;
kfree(server);
return rc;
}
// Add server to server list
server->next = servers;
servers = server;
return 0;
}
int smb_release_connection(struct smb_share *share)
{
struct smb_server *server = share->server;
if (!server) return 0;
if (--server->refcnt > 0)
{
// Remove share from server list
if (server->shares == share)
server->shares = share->next;
else
{
struct smb_share *s;
for (s = server->shares; s != NULL; s = s->next)
{
if (s->next == share)
{
s->next = share->next;
break;
}
}
}
share->server = NULL;
return 0;
}
// Disconnect from server
smb_disconnect(share);
// Remove server block
if (servers == server)
servers = server->next;
else
{
struct smb_server *s;
for (s = servers; s != NULL; s = s->next)
{
if (s->next == server)
{
s->next = server->next;
break;
}
}
}
kfree(server);
share->server = NULL;
return 0;
}
int smb_check_connection(struct smb_share *share)
{
struct smb_server *server = share->server;
int rc;
if (!server->sock)
{
// Create new connection to server
rc = smb_connect(share);
if (rc < 0) return rc;
}
if (share->tid == 0xFFFF)
{
// Reconnect share
rc = smb_connect_tree(share);
if (rc < 0) return rc;
}
return 0;
}
int smb_reconnect(struct smb_share *share)
{
struct smb_server *server = share->server;
struct smb_share *s;
int rc;
s = server->shares;
while (s)
{
s->tid = 0xFFFF;
s = s->next;
}
server->uid = 0xFFFF;
if (server->sock) smb_disconnect(share);
rc = smb_connect(share);
if (rc < 0) return rc;
rc = smb_connect_tree(share);
if (rc < 0) return rc;
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -