Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
fc932611
Commit
fc932611
authored
Mar 12, 2002
by
Mike McCormack
Committed by
Alexandre Julliard
Mar 12, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Begin to make wine an SMB client.
parent
ae6075c0
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1481 additions
and
6 deletions
+1481
-6
Makefile.in
files/Makefile.in
+1
-0
file.c
files/file.c
+7
-3
smb.c
files/smb.c
+1069
-0
smb.h
files/smb.h
+100
-0
server_protocol.h
include/wine/server_protocol.h
+44
-2
Makefile.in
server/Makefile.in
+1
-0
protocol.def
server/protocol.def
+27
-1
request.h
server/request.h
+4
-0
smb.c
server/smb.c
+192
-0
trace.c
server/trace.c
+36
-0
No files found.
files/Makefile.in
View file @
fc932611
...
...
@@ -12,6 +12,7 @@ C_SRCS = \
drive.c
\
file.c
\
profile.c
\
smb.c
\
tape.c
all
:
$(MODULE).o
...
...
files/file.c
View file @
fc932611
...
...
@@ -56,6 +56,8 @@
#include "heap.h"
#include "msdos.h"
#include "wincon.h"
#include "smb.h"
#include "wine/debug.h"
#include "wine/server.h"
...
...
@@ -74,6 +76,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
static
HANDLE
dos_handles
[
DOS_TABLE_SIZE
];
extern
WINAPI
HANDLE
FILE_SmbOpen
(
LPCSTR
name
);
/***********************************************************************
* FILE_ConvertOFMode
...
...
@@ -480,9 +483,8 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
/* If the name still starts with '\\', it's a UNC name. */
if
(
!
strncmp
(
filename
,
"
\\\\
"
,
2
))
{
FIXME
(
"UNC name (%s) not supported.
\n
"
,
filename
);
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
INVALID_HANDLE_VALUE
;
ret
=
SMB_CreateFileA
(
filename
,
access
,
sharing
,
sa
,
creation
,
attributes
,
template
);
goto
done
;
}
/* If the name contains a DOS wild card (* or ?), do no create a file */
...
...
@@ -1531,6 +1533,8 @@ BOOL WINAPI ReadFile( HANDLE hFile, LPVOID buffer, DWORD bytesToRead,
}
switch
(
type
)
{
case
FD_TYPE_SMB
:
return
SMB_ReadFile
(
hFile
,
buffer
,
bytesToRead
,
bytesRead
,
NULL
);
case
FD_TYPE_CONSOLE
:
return
ReadConsoleA
(
hFile
,
buffer
,
bytesToRead
,
bytesRead
,
NULL
);
...
...
files/smb.c
0 → 100644
View file @
fc932611
/*
* Copyright (C) 2002 Mike McCormack
*
* CIFS implementation for WINE
*
* This is a WINE's implementation of the Common Internet File System
*
* for specification see:
*
* http://www.codefx.com/CIFS_Explained.htm
* http://www.ubiqx.org/cifs/rfc-draft/rfc1002.html
* http://www.ubiqx.org/cifs/rfc-draft/draft-leach-cifs-v1-spec-02.html
* http://ubiqx.org/cifs/
* http://www.samba.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include "wine/port.h"
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <sys/time.h>
#include <sys/poll.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include "winerror.h"
#include "windef.h"
#include "winbase.h"
#include "file.h"
#include "heap.h"
#include "smb.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
file
);
#define MAX_HOST_NAME 15
#define NB_TIMEOUT 10000
USHORT
SMB_MultiplexId
=
0
;
static
int
netbios_name
(
const
char
*
p
,
unsigned
char
*
buffer
)
{
char
ch
;
int
i
,
len
=
0
;
buffer
[
len
++
]
=
' '
;
for
(
i
=
0
;
i
<=
MAX_HOST_NAME
;
i
++
)
{
if
(
i
<
MAX_HOST_NAME
)
{
if
(
*
p
)
ch
=
*
p
++&
0xdf
;
/* add character from hostname */
else
ch
=
' '
;
/* add padding */
}
else
ch
=
0
;
/* add terminator */
buffer
[
len
++
]
=
((
ch
&
0xf0
)
>>
4
)
+
'A'
;
buffer
[
len
++
]
=
(
ch
&
0x0f
)
+
'A'
;
}
buffer
[
len
++
]
=
0
;
/* add second terminator */
return
len
;
}
static
DWORD
NB_NameReq
(
LPCSTR
host
,
unsigned
char
*
buffer
,
int
len
)
{
int
trn
=
1234
,
i
=
0
;
NBR_ADDWORD
(
&
buffer
[
i
],
trn
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0110
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0001
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0000
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0000
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0000
);
i
+=
2
;
i
+=
netbios_name
(
host
,
&
buffer
[
i
]);
NBR_ADDWORD
(
&
buffer
[
i
],
0x0020
);
i
+=
2
;
NBR_ADDWORD
(
&
buffer
[
i
],
0x0001
);
i
+=
2
;
ERR
(
"packet is %d bytes in length
\n
"
,
i
);
{
int
j
;
for
(
j
=
0
;
j
<
i
;
j
++
)
printf
(
"%02x%c"
,
buffer
[
j
],(((
j
+
1
)
%
16
)
&&
((
j
+
1
)
!=
j
))
?
' '
:
'\n'
);
}
return
i
;
}
/* unc = \\hostname\share\file... */
static
BOOL
UNC_SplitName
(
LPSTR
unc
,
LPSTR
*
hostname
,
LPSTR
*
share
,
LPSTR
*
file
)
{
char
*
p
;
ERR
(
"%s
\n
"
,
unc
);
p
=
strchr
(
unc
,
'\\'
);
if
(
!
p
)
return
FALSE
;
p
=
strchr
(
p
+
1
,
'\\'
);
if
(
!
p
)
return
FALSE
;
*
hostname
=++
p
;
p
=
strchr
(
p
,
'\\'
);
if
(
!
p
)
return
FALSE
;
*
p
=
0
;
*
share
=
++
p
;
p
=
strchr
(
p
,
'\\'
);
if
(
!
p
)
return
FALSE
;
*
p
=
0
;
*
file
=
++
p
;
return
TRUE
;
}
static
BOOL
NB_Lookup
(
LPCSTR
host
,
struct
sockaddr_in
*
addr
)
{
int
fd
,
on
=
1
,
r
,
len
;
struct
pollfd
fds
;
struct
sockaddr_in
sin
;
unsigned
char
buffer
[
256
];
fd
=
socket
(
PF_INET
,
SOCK_DGRAM
,
IPPROTO_UDP
);
if
(
fd
<
0
)
return
FALSE
;
r
=
setsockopt
(
fd
,
SOL_SOCKET
,
SO_BROADCAST
,
&
on
,
sizeof
on
);
if
(
r
<
0
)
return
FALSE
;
if
(
0
==
inet_aton
(
"255.255.255.255"
,
(
struct
in_addr
*
)
&
sin
.
sin_addr
.
s_addr
))
{
FIXME
(
"Error getting bcast address
\n
"
);
return
FALSE
;
}
sin
.
sin_family
=
AF_INET
;
sin
.
sin_port
=
htons
(
137
);
len
=
NB_NameReq
(
host
,
buffer
,
sizeof
buffer
);
if
(
len
<=
0
)
return
FALSE
;
r
=
sendto
(
fd
,
buffer
,
len
,
0
,
&
sin
,
sizeof
sin
);
if
(
r
<
0
)
{
FIXME
(
"Error sending packet
\n
"
);
return
FALSE
;
}
fds
.
fd
=
fd
;
fds
.
events
=
POLLIN
;
fds
.
revents
=
0
;
r
=
poll
(
&
fds
,
1
,
NB_TIMEOUT
);
if
(
r
!=
1
)
return
FALSE
;
close
(
fd
);
TRACE
(
"Got response!
\n
"
);
return
TRUE
;
}
#define NB_FIRST 0x40
#define NB_HDRSIZE 4
#define NB_SESSION_MSG 0x00
#define NB_SESSION_REQ 0x81
/* RFC 1002, section 4.3.2 */
static
BOOL
NB_SessionReq
(
int
fd
,
char
*
called
,
char
*
calling
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
,
r
;
struct
pollfd
fds
;
ERR
(
"called %s, calling %s
\n
"
,
called
,
calling
);
buffer
[
0
]
=
NB_SESSION_REQ
;
buffer
[
1
]
=
NB_FIRST
;
netbios_name
(
called
,
&
buffer
[
NB_HDRSIZE
]);
len
+=
34
;
netbios_name
(
calling
,
&
buffer
[
NB_HDRSIZE
+
len
]);
len
+=
34
;
NBR_ADDWORD
(
&
buffer
[
2
],
len
);
/* for(i=0; i<(len+NB_HDRSIZE); i++)
DPRINTF("%02X%c",buffer[i],(((i+1)!=(len+4))&&((i+1)%16))?' ':'\n'); */
r
=
write
(
fd
,
buffer
,
len
+
4
);
if
(
r
<
0
)
{
ERR
(
"Write failed
\n
"
);
return
FALSE
;
}
fds
.
fd
=
fd
;
fds
.
events
=
POLLIN
;
fds
.
revents
=
0
;
r
=
poll
(
&
fds
,
1
,
NB_TIMEOUT
);
if
(
r
!=
1
)
{
ERR
(
"Poll failed
\n
"
);
return
FALSE
;
}
r
=
read
(
fd
,
buffer
,
NB_HDRSIZE
);
if
((
r
!=
NB_HDRSIZE
)
||
(
buffer
[
0
]
!=
0x82
))
{
ERR
(
"Received %d bytes
\n
"
,
r
);
ERR
(
"%02x %02x %02x %02x
\n
"
,
buffer
[
0
],
buffer
[
1
],
buffer
[
2
],
buffer
[
3
]);
return
FALSE
;
}
return
TRUE
;
}
static
BOOL
NB_SendData
(
int
fd
,
unsigned
char
*
data
,
int
size
)
{
unsigned
char
buffer
[
NB_HDRSIZE
];
int
r
;
/* CHECK: is it always OK to do this in two writes? */
/* perhaps use scatter gather sendmsg instead? */
buffer
[
0
]
=
NB_SESSION_MSG
;
buffer
[
1
]
=
NB_FIRST
;
NBR_ADDWORD
(
&
buffer
[
2
],
size
);
r
=
write
(
fd
,
buffer
,
NB_HDRSIZE
);
if
(
r
!=
NB_HDRSIZE
)
return
FALSE
;
r
=
write
(
fd
,
data
,
size
);
if
(
r
!=
size
)
{
ERR
(
"write failed
\n
"
);
return
FALSE
;
}
return
TRUE
;
}
static
BOOL
NB_RecvData
(
int
fd
,
unsigned
char
*
data
,
int
*
outlen
)
{
int
r
,
len
;
unsigned
char
buffer
[
NB_HDRSIZE
];
r
=
read
(
fd
,
buffer
,
NB_HDRSIZE
);
if
((
r
!=
NB_HDRSIZE
)
||
(
buffer
[
0
]
!=
NB_SESSION_MSG
))
{
ERR
(
"Received %d bytes
\n
"
,
r
);
return
FALSE
;
}
len
=
NBR_GETWORD
(
&
buffer
[
2
]);
r
=
read
(
fd
,
data
,
len
);
if
(
len
!=
r
)
{
ERR
(
"Received %d bytes
\n
"
,
r
);
return
FALSE
;
}
*
outlen
=
len
;
return
TRUE
;
}
static
BOOL
NB_Transaction
(
int
fd
,
unsigned
char
*
buffer
,
int
len
,
int
*
outlen
)
{
int
r
,
i
;
struct
pollfd
fds
;
DPRINTF
(
"Sending request:
\n
"
);
for
(
i
=
0
;
i
<
len
;
i
++
)
DPRINTF
(
"%02X%c"
,
buffer
[
i
],(((
i
+
1
)
!=
len
)
&&
((
i
+
1
)
%
16
))
?
' '
:
'\n'
);
if
(
!
NB_SendData
(
fd
,
buffer
,
len
))
return
FALSE
;
fds
.
fd
=
fd
;
fds
.
events
=
POLLIN
;
fds
.
revents
=
0
;
r
=
poll
(
&
fds
,
1
,
NB_TIMEOUT
);
if
(
r
!=
1
)
{
ERR
(
"Poll failed
\n
"
);
return
FALSE
;
}
if
(
!
NB_RecvData
(
fd
,
buffer
,
outlen
))
return
FALSE
;
len
=
*
outlen
;
DPRINTF
(
"Got response:
\n
"
);
for
(
i
=
0
;
i
<
len
;
i
++
)
DPRINTF
(
"%02X%c"
,
buffer
[
i
],(((
i
+
1
)
!=
len
)
&&
((
i
+
1
)
%
16
))
?
' '
:
'\n'
);
return
TRUE
;
}
#define SMB_ADDHEADER(b,l) { b[(l)++]=0xff; b[(l)++]='S'; b[(l)++]='M'; b[(l)++]='B'; }
#define SMB_ADDERRINFO(b,l) { b[(l)++]=0; b[(l)++]=0; b[(l)++]=0; b[(l)++]=0; }
#define SMB_ADDPADSIG(b,l) { memset(&b[l],0,12); l+=12; }
#define SMB_ERRCLASS 5
#define SMB_ERRCODE 7
#define SMB_TREEID 24
#define SMB_PROCID 26
#define SMB_USERID 28
#define SMB_PLEXID 30
#define SMB_PCOUNT 32
#define SMB_HDRSIZE 33
static
DWORD
SMB_GetError
(
unsigned
char
*
buffer
)
{
if
(
buffer
[
SMB_ERRCLASS
]
==
0
)
return
STATUS_SUCCESS
;
/* FIXME: return propper error codes */
return
STATUS_INVALID_PARAMETER
;
}
static
int
SMB_Header
(
unsigned
char
*
buffer
,
unsigned
char
command
,
USHORT
tree_id
,
USHORT
user_id
)
{
int
len
=
0
;
DWORD
id
;
/* 0 */
SMB_ADDHEADER
(
buffer
,
len
);
/* 4 */
buffer
[
len
++
]
=
command
;
/* 5 */
SMB_ADDERRINFO
(
buffer
,
len
)
/* 9 */
buffer
[
len
++
]
=
0x00
;
/* flags */
SMB_ADDWORD
(
&
buffer
[
len
],
1
);
len
+=
2
;
/* flags2 */
/* 12 */
SMB_ADDPADSIG
(
buffer
,
len
)
/* 24 */
SMB_ADDWORD
(
&
buffer
[
len
],
tree_id
);
len
+=
2
;
/* treeid */
id
=
GetCurrentThreadId
();
SMB_ADDWORD
(
&
buffer
[
len
],
id
);
len
+=
2
;
/* process id */
SMB_ADDWORD
(
&
buffer
[
len
],
user_id
);
len
+=
2
;
/* user id */
SMB_ADDWORD
(
&
buffer
[
len
],
SMB_MultiplexId
);
len
+=
2
;
/* multiplex id */
SMB_MultiplexId
++
;
return
len
;
}
static
const
char
*
SMB_ProtocolDialect
=
"NT LM 0.12"
;
/* = "Windows for Workgroups 3.1a"; */
/* FIXME: support multiple SMB dialects */
static
BOOL
SMB_NegotiateProtocol
(
int
fd
,
USHORT
*
dialect
)
{
unsigned
char
buffer
[
0x100
];
int
buflen
,
len
=
0
;
ERR
(
"
\n
"
);
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_NEGOTIATE
,
0
,
0
);
/* parameters */
buffer
[
len
++
]
=
0
;
/* no parameters */
/* command buffer */
buflen
=
strlen
(
SMB_ProtocolDialect
)
+
2
;
/* include type and nul byte */
SMB_ADDWORD
(
&
buffer
[
len
],
buflen
);
len
+=
2
;
buffer
[
len
]
=
0x02
;
strcpy
(
&
buffer
[
len
+
1
],
SMB_ProtocolDialect
);
len
+=
buflen
;
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
{
ERR
(
"Failed
\n
"
);
return
FALSE
;
}
/* FIXME: check response */
if
(
SMB_GetError
(
buffer
))
{
ERR
(
"returned error
\n
"
);
return
FALSE
;
}
*
dialect
=
0
;
return
TRUE
;
}
#define SMB_PARAM_COUNT(buffer) ((buffer)[SMB_PCOUNT])
#define SMB_PARAM(buffer,n) SMB_GETWORD(&(buffer)[SMB_HDRSIZE+2*(n)])
#define SMB_BUFFER_COUNT(buffer) SMB_GETWORD(buffer+SMB_HDRSIZE+2*SMB_PARAM_COUNT(buffer))
#define SMB_BUFFER(buffer,n) ((buffer)[SMB_HDRSIZE + 2*SMB_PARAM_COUNT(buffer) + 2 + (n) ])
static
BOOL
SMB_SessionSetup
(
int
fd
,
USHORT
*
userid
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
;
int
i
,
pcount
,
bcount
;
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_SESSION_SETUP_ANDX
,
0
,
0
);
buffer
[
len
++
]
=
0
;
/* no parameters? */
buffer
[
len
++
]
=
0xff
;
/* AndXCommand: secondary request */
buffer
[
len
++
]
=
0x00
;
/* AndXReserved */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* AndXOffset */
SMB_ADDWORD
(
&
buffer
[
len
],
0x400
);
len
+=
2
;
/* MaxBufferSize */
SMB_ADDWORD
(
&
buffer
[
len
],
1
);
len
+=
2
;
/* MaxMpxCount */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* VcNumber */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* SessionKey */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* SessionKey */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* Password length */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* Reserved */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* Reserved */
/* FIXME: add name and password here */
buffer
[
len
++
]
=
0
;
/* number of bytes in password */
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
return
FALSE
;
if
(
SMB_GetError
(
buffer
))
return
FALSE
;
pcount
=
SMB_PARAM_COUNT
(
buffer
);
if
(
(
SMB_HDRSIZE
+
pcount
*
2
)
>
len
)
{
ERR
(
"Bad parameter count %d
\n
"
,
pcount
);
return
FALSE
;
}
DPRINTF
(
"SMB_COM_SESSION_SETUP response, %d args: "
,
pcount
);
for
(
i
=
0
;
i
<
pcount
;
i
++
)
DPRINTF
(
"%04x "
,
SMB_PARAM
(
buffer
,
i
));
DPRINTF
(
"
\n
"
);
bcount
=
SMB_BUFFER_COUNT
(
buffer
);
if
(
(
SMB_HDRSIZE
+
pcount
*
2
+
2
+
bcount
)
>
len
)
{
ERR
(
"parameter count %x, buffer count %x, len %x
\n
"
,
pcount
,
bcount
,
len
);
return
FALSE
;
}
DPRINTF
(
"response buffer %d bytes: "
,
bcount
);
for
(
i
=
0
;
i
<
bcount
;
i
++
)
{
unsigned
char
ch
=
SMB_BUFFER
(
buffer
,
i
);
DPRINTF
(
"%c"
,
isprint
(
ch
)
?
ch
:
' '
);
}
DPRINTF
(
"
\n
"
);
*
userid
=
SMB_GETWORD
(
&
buffer
[
SMB_USERID
]);
return
TRUE
;
}
static
BOOL
SMB_TreeConnect
(
int
fd
,
USHORT
user_id
,
LPCSTR
share_name
,
USHORT
*
treeid
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
,
slen
;
ERR
(
"%s
\n
"
,
share_name
);
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_TREE_CONNECT
,
0
,
user_id
);
buffer
[
len
++
]
=
4
;
/* parameters */
buffer
[
len
++
]
=
0xff
;
/* AndXCommand: secondary request */
buffer
[
len
++
]
=
0x00
;
/* AndXReserved */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* AndXOffset */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* Flags */
SMB_ADDWORD
(
&
buffer
[
len
],
1
);
len
+=
2
;
/* Password length */
/* SMB command buffer */
SMB_ADDWORD
(
&
buffer
[
len
],
3
);
len
+=
2
;
/* command buffer len */
buffer
[
len
++
]
=
0
;
/* null terminated password */
slen
=
strlen
(
share_name
);
if
(
slen
<
(
sizeof
buffer
-
len
))
strcpy
(
&
buffer
[
len
],
share_name
);
else
return
FALSE
;
len
+=
slen
+
1
;
/* name of the service */
buffer
[
len
++
]
=
0
;
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
return
FALSE
;
if
(
SMB_GetError
(
buffer
))
return
FALSE
;
*
treeid
=
SMB_GETWORD
(
&
buffer
[
SMB_TREEID
]);
ERR
(
"OK, treeid = %04x
\n
"
,
*
treeid
);
return
TRUE
;
}
static
BOOL
SMB_NtCreateOpen
(
int
fd
,
USHORT
tree_id
,
USHORT
user_id
,
USHORT
dialect
,
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE
template
,
USHORT
*
file_id
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
,
slen
;
ERR
(
"%s
\n
"
,
filename
);
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_NT_CREATE_ANDX
,
tree_id
,
user_id
);
/* 0 */
buffer
[
len
++
]
=
24
;
/* parameters */
buffer
[
len
++
]
=
0xff
;
/* AndXCommand: secondary request */
buffer
[
len
++
]
=
0x00
;
/* AndXReserved */
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* AndXOffset */
buffer
[
len
++
]
=
0
;
/* reserved */
slen
=
strlen
(
filename
);
SMB_ADDWORD
(
&
buffer
[
len
],
slen
);
len
+=
2
;
/* name length */
/* 0x08 */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* flags */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* root directory fid */
/* 0x10 */
SMB_ADDDWORD
(
&
buffer
[
len
],
access
);
len
+=
4
;
/* access */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* allocation size */
/* 0x18 */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* root directory fid */
/* 0x1c */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* initial allocation */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* 0x24 */
SMB_ADDDWORD
(
&
buffer
[
len
],
attributes
);
len
+=
4
;
/* ExtFileAttributes*/
/* 0x28 */
SMB_ADDDWORD
(
&
buffer
[
len
],
sharing
);
len
+=
4
;
/* ShareAccess */
/* 0x2c */
ERR
(
"creation = %08lx
\n
"
,
creation
);
SMB_ADDDWORD
(
&
buffer
[
len
],
creation
);
len
+=
4
;
/* CreateDisposition */
/* 0x30 */
SMB_ADDDWORD
(
&
buffer
[
len
],
creation
);
len
+=
4
;
/* CreateOptions */
/* 0x34 */
SMB_ADDDWORD
(
&
buffer
[
len
],
0
);
len
+=
4
;
/* Impersonation */
/* 0x38 */
buffer
[
len
++
]
=
0
;
/* security flags */
/* 0x39 */
SMB_ADDWORD
(
&
buffer
[
len
],
slen
);
len
+=
2
;
/* size of buffer */
if
(
slen
<
(
sizeof
buffer
-
len
))
strcpy
(
&
buffer
[
len
],
filename
);
else
return
FALSE
;
len
+=
slen
+
1
;
/* name of the file */
buffer
[
len
++
]
=
0
;
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
return
FALSE
;
if
(
SMB_GetError
(
buffer
))
return
FALSE
;
ERR
(
"OK
\n
"
);
/* FIXME */
/* *file_id = SMB_GETWORD(&buffer[xxx]); */
*
file_id
=
0
;
return
FALSE
;
return
TRUE
;
}
static
USHORT
SMB_GetMode
(
DWORD
access
,
DWORD
sharing
)
{
USHORT
mode
=
0
;
switch
(
access
&
(
GENERIC_READ
|
GENERIC_WRITE
))
{
case
GENERIC_READ
:
mode
|=
OF_READ
;
break
;
case
GENERIC_WRITE
:
mode
|=
OF_WRITE
;
break
;
case
(
GENERIC_READ
|
GENERIC_WRITE
):
mode
|=
OF_READWRITE
;
break
;
}
switch
(
sharing
&
(
FILE_SHARE_READ
|
FILE_SHARE_WRITE
))
{
case
(
FILE_SHARE_READ
|
FILE_SHARE_WRITE
):
mode
|=
OF_SHARE_DENY_NONE
;
break
;
case
FILE_SHARE_READ
:
mode
|=
OF_SHARE_DENY_WRITE
;
break
;
case
FILE_SHARE_WRITE
:
mode
|=
OF_SHARE_DENY_READ
;
break
;
default:
mode
|=
OF_SHARE_EXCLUSIVE
;
break
;
}
return
mode
;
}
/* inverse of FILE_ConvertOFMode */
static
BOOL
SMB_OpenAndX
(
int
fd
,
USHORT
tree_id
,
USHORT
user_id
,
USHORT
dialect
,
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
DWORD
creation
,
DWORD
attributes
,
USHORT
*
file_id
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
;
USHORT
mode
;
ERR
(
"%s
\n
"
,
filename
);
mode
=
SMB_GetMode
(
access
,
sharing
);
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_OPEN_ANDX
,
tree_id
,
user_id
);
/* 0 */
buffer
[
len
++
]
=
15
;
/* parameters */
buffer
[
len
++
]
=
0xff
;
/* AndXCommand: secondary request */
buffer
[
len
++
]
=
0x00
;
/* AndXReserved */
SMB_ADDWORD
(
buffer
+
len
,
0
);
len
+=
2
;
/* AndXOffset */
SMB_ADDWORD
(
buffer
+
len
,
0
);
len
+=
2
;
/* Flags */
SMB_ADDWORD
(
buffer
+
len
,
mode
);
len
+=
2
;
/* desired access */
SMB_ADDWORD
(
buffer
+
len
,
0
);
len
+=
2
;
/* search attributes */
SMB_ADDWORD
(
buffer
+
len
,
0
);
len
+=
2
;
/*FIXME: complete */
return
FALSE
;
}
static
BOOL
SMB_Open
(
int
fd
,
USHORT
tree_id
,
USHORT
user_id
,
USHORT
dialect
,
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
DWORD
creation
,
DWORD
attributes
,
USHORT
*
file_id
)
{
unsigned
char
buffer
[
0x100
];
int
len
=
0
,
slen
,
pcount
,
i
;
USHORT
mode
=
SMB_GetMode
(
access
,
sharing
);
ERR
(
"%s
\n
"
,
filename
);
memset
(
buffer
,
0
,
sizeof
buffer
);
len
=
SMB_Header
(
buffer
,
SMB_COM_OPEN
,
tree_id
,
user_id
);
/* 0 */
buffer
[
len
++
]
=
2
;
/* parameters */
SMB_ADDWORD
(
buffer
+
len
,
mode
);
len
+=
2
;
SMB_ADDWORD
(
buffer
+
len
,
0
);
len
+=
2
;
/* search attributes */
slen
=
strlen
(
filename
)
+
2
;
/* inc. nul and BufferFormat */
SMB_ADDWORD
(
buffer
+
len
,
slen
);
len
+=
2
;
buffer
[
len
]
=
0x04
;
/* BufferFormat */
strcpy
(
&
buffer
[
len
+
1
],
filename
);
len
+=
slen
;
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
return
FALSE
;
if
(
SMB_GetError
(
buffer
))
return
FALSE
;
pcount
=
SMB_PARAM_COUNT
(
buffer
);
if
(
(
SMB_HDRSIZE
+
pcount
*
2
)
>
len
)
{
ERR
(
"Bad parameter count %d
\n
"
,
pcount
);
return
FALSE
;
}
ERR
(
"response, %d args: "
,
pcount
);
for
(
i
=
0
;
i
<
pcount
;
i
++
)
DPRINTF
(
"%04x "
,
SMB_PARAM
(
buffer
,
i
));
DPRINTF
(
"
\n
"
);
*
file_id
=
SMB_PARAM
(
buffer
,
0
);
ERR
(
"file_id = %04x
\n
"
,
*
file_id
);
return
TRUE
;
}
static
BOOL
SMB_Read
(
int
fd
,
USHORT
tree_id
,
USHORT
user_id
,
USHORT
dialect
,
USHORT
file_id
,
DWORD
offset
,
LPVOID
out
,
USHORT
count
,
LPUSHORT
read
)
{
unsigned
char
*
buffer
;
int
len
,
buf_size
,
n
,
i
;
ERR
(
"user %04x tree %04x file %04x count %04x offset %08lx
\n
"
,
user_id
,
tree_id
,
file_id
,
count
,
offset
);
buf_size
=
count
+
0x100
;
buffer
=
(
unsigned
char
*
)
HeapAlloc
(
GetProcessHeap
(),
0
,
buf_size
);
memset
(
buffer
,
0
,
buf_size
);
len
=
SMB_Header
(
buffer
,
SMB_COM_READ
,
tree_id
,
user_id
);
buffer
[
len
++
]
=
5
;
SMB_ADDWORD
(
&
buffer
[
len
],
file_id
);
len
+=
2
;
SMB_ADDWORD
(
&
buffer
[
len
],
count
);
len
+=
2
;
SMB_ADDDWORD
(
&
buffer
[
len
],
offset
);
len
+=
4
;
SMB_ADDWORD
(
&
buffer
[
len
],
0
);
len
+=
2
;
/* how many more bytes will be read */
buffer
[
len
++
]
=
0
;
if
(
!
NB_Transaction
(
fd
,
buffer
,
len
,
&
len
))
{
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
return
FALSE
;
}
if
(
SMB_GetError
(
buffer
))
{
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
return
FALSE
;
}
n
=
SMB_PARAM_COUNT
(
buffer
);
if
(
(
SMB_HDRSIZE
+
n
*
2
)
>
len
)
{
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
ERR
(
"Bad parameter count %d
\n
"
,
n
);
return
FALSE
;
}
ERR
(
"response, %d args: "
,
n
);
for
(
i
=
0
;
i
<
n
;
i
++
)
DPRINTF
(
"%04x "
,
SMB_PARAM
(
buffer
,
i
));
DPRINTF
(
"
\n
"
);
n
=
SMB_PARAM
(
buffer
,
5
)
-
3
;
if
(
n
>
count
)
n
=
count
;
memcpy
(
out
,
&
SMB_BUFFER
(
buffer
,
3
),
n
);
ERR
(
"Read %d bytes
\n
"
,
n
);
*
read
=
n
;
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
return
TRUE
;
}
static
int
SMB_LoginAndConnect
(
LPCSTR
host
,
LPCSTR
share
,
USHORT
*
tree_id
,
USHORT
*
user_id
,
USHORT
*
dialect
)
{
int
fd
=-
1
,
r
;
struct
sockaddr_in
sin
;
LPSTR
name
=
NULL
;
ERR
(
"host %s share %s
\n
"
,
host
,
share
);
/* FIXME: use various lookup methods */
if
(
0
)
NB_Lookup
(
host
,
&
sin
);
else
{
if
(
0
==
inet_aton
(
"127.0.0.1"
,
(
struct
in_addr
*
)
&
sin
.
sin_addr
.
s_addr
))
{
FIXME
(
"Error getting localhost address
\n
"
);
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
INVALID_HANDLE_VALUE
;
}
sin
.
sin_family
=
AF_INET
;
sin
.
sin_port
=
htons
(
139
);
/* netbios session */
}
fd
=
socket
(
PF_INET
,
SOCK_STREAM
,
IPPROTO_TCP
);
if
(
fd
<
0
)
goto
fail
;
ERR
(
"Connecting...
\n
"
);
r
=
connect
(
fd
,
&
sin
,
sizeof
sin
);
if
(
r
<
0
)
goto
fail
;
if
(
!
NB_SessionReq
(
fd
,
"*SMBSERVER"
,
"WINE"
))
goto
fail
;
if
(
!
SMB_NegotiateProtocol
(
fd
,
dialect
))
goto
fail
;
if
(
!
SMB_SessionSetup
(
fd
,
user_id
))
goto
fail
;
name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
strlen
(
host
)
+
strlen
(
share
)
+
5
);
if
(
!
name
)
goto
fail
;
sprintf
(
name
,
"
\\\\
%s
\\
%s"
,
host
,
share
);
if
(
!
SMB_TreeConnect
(
fd
,
*
user_id
,
name
,
tree_id
))
goto
fail
;
HeapFree
(
GetProcessHeap
(),
0
,
name
);
return
fd
;
fail:
if
(
name
)
HeapFree
(
GetProcessHeap
(),
0
,
name
);
ERR
(
"Failed
\n
"
);
if
(
fd
>=
0
)
close
(
fd
);
return
-
1
;
}
static
HANDLE
SMB_RegisterFile
(
int
fd
,
USHORT
tree_id
,
USHORT
user_id
,
USHORT
dialect
,
USHORT
file_id
)
{
int
r
;
HANDLE
ret
;
wine_server_send_fd
(
fd
);
SERVER_START_REQ
(
create_smb
)
{
req
->
tree_id
=
tree_id
;
req
->
user_id
=
user_id
;
req
->
file_id
=
file_id
;
req
->
dialect
=
0
;
req
->
fd
=
fd
;
SetLastError
(
0
);
r
=
wine_server_call_err
(
req
);
ret
=
reply
->
handle
;
}
SERVER_END_REQ
;
if
(
!
r
)
ERR
(
"created wineserver smb object, handle = %04x
\n
"
,
ret
);
else
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
ret
;
}
HANDLE
WINAPI
SMB_CreateFileA
(
LPCSTR
uncname
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE
template
)
{
int
fd
;
USHORT
tree_id
=
0
,
user_id
=
0
,
dialect
=
0
,
file_id
=
0
;
LPSTR
name
,
host
,
share
,
file
;
HANDLE
handle
=
0
;
name
=
HeapAlloc
(
GetProcessHeap
(),
0
,
lstrlenA
(
uncname
));
if
(
!
name
)
return
-
1
;
lstrcpyA
(
name
,
uncname
);
if
(
!
UNC_SplitName
(
name
,
&
host
,
&
share
,
&
file
)
)
{
HeapFree
(
GetProcessHeap
(),
0
,
name
);
return
handle
;
}
ERR
(
"server is %s, share is %s, file is %s
\n
"
,
host
,
share
,
file
);
fd
=
SMB_LoginAndConnect
(
host
,
share
,
&
tree_id
,
&
user_id
,
&
dialect
);
if
(
fd
<
0
)
{
HeapFree
(
GetProcessHeap
(),
0
,
name
);
return
handle
;
}
#if 0
if(!SMB_NtCreateOpen(fd, tree_id, user_id, dialect, file,
access, sharing, sa, creation, attributes, template, &file_id ))
{
close(fd);
HeapFree(GetProcessHeap(),0,name);
ERR("CreateOpen failed\n");
return handle;
}
#endif
if
(
!
SMB_Open
(
fd
,
tree_id
,
user_id
,
dialect
,
file
,
access
,
sharing
,
creation
,
attributes
,
&
file_id
))
{
close
(
fd
);
HeapFree
(
GetProcessHeap
(),
0
,
name
);
ERR
(
"CreateOpen failed
\n
"
);
return
handle
;
}
HeapFree
(
GetProcessHeap
(),
0
,
name
);
handle
=
SMB_RegisterFile
(
fd
,
tree_id
,
user_id
,
dialect
,
file_id
);
if
(
!
handle
)
{
ERR
(
"register failed
\n
"
);
close
(
fd
);
}
return
handle
;
}
static
BOOL
SMB_GetSmbInfo
(
HANDLE
hFile
,
USHORT
*
tree_id
,
USHORT
*
user_id
,
USHORT
*
dialect
,
USHORT
*
file_id
,
LPDWORD
offset
)
{
int
r
;
SERVER_START_REQ
(
get_smb_info
)
{
req
->
handle
=
hFile
;
req
->
flags
=
0
;
SetLastError
(
0
);
r
=
wine_server_call_err
(
req
);
if
(
tree_id
)
*
tree_id
=
reply
->
tree_id
;
if
(
user_id
)
*
user_id
=
reply
->
user_id
;
if
(
file_id
)
*
file_id
=
reply
->
file_id
;
if
(
dialect
)
*
dialect
=
reply
->
dialect
;
if
(
offset
)
*
offset
=
reply
->
offset
;
}
SERVER_END_REQ
;
return
!
r
;
}
static
BOOL
SMB_SetOffset
(
HANDLE
hFile
,
DWORD
offset
)
{
int
r
;
ERR
(
"offset = %08lx
\n
"
,
offset
);
SERVER_START_REQ
(
get_smb_info
)
{
req
->
handle
=
hFile
;
req
->
flags
=
SMBINFO_SET_OFFSET
;
req
->
offset
=
offset
;
SetLastError
(
0
);
r
=
wine_server_call_err
(
req
);
/* if(offset)
*offset = reply->offset; */
}
SERVER_END_REQ
;
return
!
r
;
}
WINAPI
BOOL
SMB_ReadFile
(
HANDLE
hFile
,
LPVOID
buffer
,
DWORD
bytesToRead
,
LPDWORD
bytesRead
,
LPOVERLAPPED
lpOverlapped
)
{
int
fd
;
DWORD
total
,
count
,
offset
;
USHORT
user_id
,
tree_id
,
dialect
,
file_id
,
read
;
BOOL
r
=
TRUE
;
ERR
(
"%04x %p %ld %p
\n
"
,
hFile
,
buffer
,
bytesToRead
,
bytesRead
);
if
(
!
SMB_GetSmbInfo
(
hFile
,
&
tree_id
,
&
user_id
,
&
dialect
,
&
file_id
,
&
offset
))
return
FALSE
;
fd
=
FILE_GetUnixHandle
(
hFile
,
GENERIC_READ
);
if
(
fd
<
0
)
return
FALSE
;
total
=
0
;
while
(
1
)
{
count
=
bytesToRead
-
total
;
if
(
count
>
0x400
)
count
=
0x400
;
if
(
count
==
0
)
break
;
read
=
0
;
r
=
SMB_Read
(
fd
,
tree_id
,
user_id
,
dialect
,
file_id
,
offset
,
buffer
,
count
,
&
read
);
if
(
!
r
)
break
;
if
(
!
read
)
break
;
total
+=
read
;
buffer
+=
read
;
offset
+=
read
;
if
(
total
>=
bytesToRead
)
break
;
}
close
(
fd
);
if
(
bytesRead
)
*
bytesRead
=
total
;
if
(
!
SMB_SetOffset
(
hFile
,
offset
))
return
FALSE
;
return
r
;
}
files/smb.h
0 → 100644
View file @
fc932611
/*
* Copyright (C) 2002 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __INC_SMB__
#define __INC_SMB__
#define NBR_ADDWORD(p,word) { (p)[1] = (word & 0xff); (p)[0] = ((word)>>8)&0xff; }
#define NBR_GETWORD(p) ( (((p)[0])<<8) | ((p)[1]) )
#define SMB_ADDWORD(p,word) { (p)[0] = (word & 0xff); (p)[1] = ((word)>>8)&0xff; }
#define SMB_GETWORD(p) ( (((p)[1])<<8) | ((p)[0]) )
#define SMB_ADDDWORD(p,w) { (p)[3]=((w)>>24)&0xff; (p)[2]=((w)>>16)&0xff; (p)[1]=((w)>>8)&0xff; (p)[0]=(w)&0xff; }
#define SMB_COM_CREATE_DIRECTORY 0x00
#define SMB_COM_DELETE_DIRECTORY 0x01
#define SMB_COM_OPEN 0x02
#define SMB_COM_CREATE 0x03
#define SMB_COM_CLOSE 0x04
#define SMB_COM_FLUSH 0x05
#define SMB_COM_DELETE 0x06
#define SMB_COM_RENAME 0x07
#define SMB_COM_QUERY_INFORMATION 0x08
#define SMB_COM_SET_INFORMATION 0x09
#define SMB_COM_READ 0x0A
#define SMB_COM_WRITE 0x0B
#define SMB_COM_LOCK_BYTE_RANGE 0x0C
#define SMB_COM_UNLOCK_BYTE_RANGE 0x0D
#define SMB_COM_CREATE_TEMPORARY 0x0E
#define SMB_COM_CREATE_NEW 0x0F
#define SMB_COM_CHECK_DIRECTORY 0x10
#define SMB_COM_PROCESS_EXIT 0x11
#define SMB_COM_SEEK 0x12
#define SMB_COM_LOCK_AND_READ 0x13
#define SMB_COM_WRITE_AND_UNLOCK 0x14
#define SMB_COM_READ_RAW 0x1A
#define SMB_COM_READ_MPX 0x1B
#define SMB_COM_READ_MPX_SECONDARY 0x1C
#define SMB_COM_WRITE_RAW 0x1D
#define SMB_COM_WRITE_MPX 0x1E
#define SMB_COM_WRITE_COMPLETE 0x20
#define SMB_COM_SET_INFORMATION2 0x22
#define SMB_COM_QUERY_INFORMATION2 0x23
#define SMB_COM_LOCKING_ANDX 0x24
#define SMB_COM_TRANSACTION 0x25
#define SMB_COM_TRANSACTION_SECONDARY 0x26
#define SMB_COM_IOCTL 0x27
#define SMB_COM_IOCTL_SECONDARY 0x28
#define SMB_COM_COPY 0x29
#define SMB_COM_MOVE 0x2A
#define SMB_COM_ECHO 0x2B
#define SMB_COM_WRITE_AND_CLOSE 0x2C
#define SMB_COM_OPEN_ANDX 0x2D
#define SMB_COM_READ_ANDX 0x2E
#define SMB_COM_WRITE_ANDX 0x2F
#define SMB_COM_CLOSE_AND_TREE_DISC 0x31
#define SMB_COM_TRANSACTION2 0x32
#define SMB_COM_TRANSACTION2_SECONDARY 0x33
#define SMB_COM_FIND_CLOSE2 0x34
#define SMB_COM_FIND_NOTIFY_CLOSE 0x35
#define SMB_COM_TREE_CONNECT 0x70
#define SMB_COM_TREE_DISCONNECT 0x71
#define SMB_COM_NEGOTIATE 0x72
#define SMB_COM_SESSION_SETUP_ANDX 0x73
#define SMB_COM_LOGOFF_ANDX 0x74
#define SMB_COM_TREE_CONNECT_ANDX 0x75
#define SMB_COM_QUERY_INFORMATION_DISK 0x80
#define SMB_COM_SEARCH 0x81
#define SMB_COM_FIND 0x82
#define SMB_COM_FIND_UNIQUE 0x83
#define SMB_COM_NT_TRANSACT 0xA0
#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
#define SMB_COM_NT_CREATE_ANDX 0xA2
#define SMB_COM_NT_CANCEL 0xA4
#define SMB_COM_OPEN_PRINT_FILE 0xC0
#define SMB_COM_WRITE_PRINT_FILE 0xC1
#define SMB_COM_CLOSE_PRINT_FILE 0xC2
#define SMB_COM_GET_PRINT_QUEUE 0xC3
extern
WINAPI
BOOL
SMB_ReadFile
(
HANDLE
hFile
,
LPVOID
buffer
,
DWORD
bytesToRead
,
LPDWORD
bytesRead
,
LPOVERLAPPED
lpOverlapped
);
extern
HANDLE
WINAPI
SMB_CreateFileA
(
LPCSTR
filename
,
DWORD
access
,
DWORD
sharing
,
LPSECURITY_ATTRIBUTES
sa
,
DWORD
creation
,
DWORD
attributes
,
HANDLE
template
);
#endif
/* __INC_SMB__ */
include/wine/server_protocol.h
View file @
fc932611
...
...
@@ -736,7 +736,8 @@ enum fd_type
{
FD_TYPE_INVALID
,
FD_TYPE_DEFAULT
,
FD_TYPE_CONSOLE
FD_TYPE_CONSOLE
,
FD_TYPE_SMB
};
#define FD_FLAG_OVERLAPPED 0x01
#define FD_FLAG_TIMEOUT 0x02
...
...
@@ -2321,6 +2322,41 @@ struct get_named_pipe_info_reply
};
struct
create_smb_request
{
struct
request_header
__header
;
int
fd
;
unsigned
int
tree_id
;
unsigned
int
user_id
;
unsigned
int
file_id
;
unsigned
int
dialect
;
};
struct
create_smb_reply
{
struct
reply_header
__header
;
handle_t
handle
;
};
struct
get_smb_info_request
{
struct
request_header
__header
;
handle_t
handle
;
unsigned
int
flags
;
unsigned
int
offset
;
};
struct
get_smb_info_reply
{
struct
reply_header
__header
;
unsigned
int
tree_id
;
unsigned
int
user_id
;
unsigned
int
dialect
;
unsigned
int
file_id
;
unsigned
int
offset
;
};
#define SMBINFO_SET_OFFSET 0x01
struct
create_window_request
{
...
...
@@ -2742,6 +2778,8 @@ enum request
REQ_wait_named_pipe
,
REQ_disconnect_named_pipe
,
REQ_get_named_pipe_info
,
REQ_create_smb
,
REQ_get_smb_info
,
REQ_create_window
,
REQ_link_window
,
REQ_destroy_window
,
...
...
@@ -2899,6 +2937,8 @@ union generic_request
struct
wait_named_pipe_request
wait_named_pipe_request
;
struct
disconnect_named_pipe_request
disconnect_named_pipe_request
;
struct
get_named_pipe_info_request
get_named_pipe_info_request
;
struct
create_smb_request
create_smb_request
;
struct
get_smb_info_request
get_smb_info_request
;
struct
create_window_request
create_window_request
;
struct
link_window_request
link_window_request
;
struct
destroy_window_request
destroy_window_request
;
...
...
@@ -3054,6 +3094,8 @@ union generic_reply
struct
wait_named_pipe_reply
wait_named_pipe_reply
;
struct
disconnect_named_pipe_reply
disconnect_named_pipe_reply
;
struct
get_named_pipe_info_reply
get_named_pipe_info_reply
;
struct
create_smb_reply
create_smb_reply
;
struct
get_smb_info_reply
get_smb_info_reply
;
struct
create_window_reply
create_window_reply
;
struct
link_window_reply
link_window_reply
;
struct
destroy_window_reply
destroy_window_reply
;
...
...
@@ -3075,6 +3117,6 @@ union generic_reply
struct
get_window_properties_reply
get_window_properties_reply
;
};
#define SERVER_PROTOCOL_VERSION 7
2
#define SERVER_PROTOCOL_VERSION 7
3
#endif
/* __WINE_WINE_SERVER_PROTOCOL_H */
server/Makefile.in
View file @
fc932611
...
...
@@ -31,6 +31,7 @@ C_SRCS = \
select
.c
\
semaphore.c
\
serial.c
\
smb.c
\
snapshot.c
\
sock.c
\
thread.c
\
...
...
server/protocol.def
View file @
fc932611
...
...
@@ -563,7 +563,8 @@ enum fd_type
{
FD_TYPE_INVALID,
FD_TYPE_DEFAULT,
FD_TYPE_CONSOLE
FD_TYPE_CONSOLE,
FD_TYPE_SMB
};
#define FD_FLAG_OVERLAPPED 0x01
#define FD_FLAG_TIMEOUT 0x02
...
...
@@ -1634,6 +1635,31 @@ enum message_type
@END
@REQ(create_smb)
int fd;
unsigned int tree_id;
unsigned int user_id;
unsigned int file_id;
unsigned int dialect;
@REPLY
handle_t handle;
@END
@REQ(get_smb_info)
handle_t handle;
unsigned int flags;
unsigned int offset;
@REPLY
unsigned int tree_id;
unsigned int user_id;
unsigned int dialect;
unsigned int file_id;
unsigned int offset;
@END
#define SMBINFO_SET_OFFSET 0x01
/* Create a window */
@REQ(create_window)
user_handle_t parent; /* parent window */
...
...
server/request.h
View file @
fc932611
...
...
@@ -232,6 +232,8 @@ DECL_HANDLER(connect_named_pipe);
DECL_HANDLER
(
wait_named_pipe
);
DECL_HANDLER
(
disconnect_named_pipe
);
DECL_HANDLER
(
get_named_pipe_info
);
DECL_HANDLER
(
create_smb
);
DECL_HANDLER
(
get_smb_info
);
DECL_HANDLER
(
create_window
);
DECL_HANDLER
(
link_window
);
DECL_HANDLER
(
destroy_window
);
...
...
@@ -388,6 +390,8 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(
req_handler
)
req_wait_named_pipe
,
(
req_handler
)
req_disconnect_named_pipe
,
(
req_handler
)
req_get_named_pipe_info
,
(
req_handler
)
req_create_smb
,
(
req_handler
)
req_get_smb_info
,
(
req_handler
)
req_create_window
,
(
req_handler
)
req_link_window
,
(
req_handler
)
req_destroy_window
,
...
...
server/smb.c
0 → 100644
View file @
fc932611
/*
* Server-side smb network file management
*
* Copyright (C) 1998 Alexandre Julliard
* Copyright (C) 2000, 2001, 2002 Mike McCormack
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* FIXME: if you can't find something to fix,
* you're not looking hard enough
*/
#include "config.h"
#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <utime.h>
#include <termios.h>
#include <sys/ioctl.h>
#include "winerror.h"
#include "winbase.h"
#include "handle.h"
#include "thread.h"
#include "request.h"
static
void
smb_dump
(
struct
object
*
obj
,
int
verbose
);
static
int
smb_get_fd
(
struct
object
*
obj
);
static
int
smb_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
,
int
*
flags
);
static
int
smb_get_poll_events
(
struct
object
*
obj
);
static
void
destroy_smb
(
struct
object
*
obj
);
struct
smb
{
struct
object
obj
;
unsigned
int
tree_id
;
unsigned
int
user_id
;
unsigned
int
dialect
;
unsigned
int
file_id
;
unsigned
int
offset
;
};
static
const
struct
object_ops
smb_ops
=
{
sizeof
(
struct
smb
),
/* size */
smb_dump
,
/* dump */
default_poll_add_queue
,
/* add_queue */
default_poll_remove_queue
,
/* remove_queue */
default_poll_signaled
,
/* signaled */
no_satisfied
,
/* satisfied */
smb_get_poll_events
,
/* get_poll_events */
default_poll_event
,
/* poll_event */
smb_get_fd
,
/* get_fd */
no_flush
,
/* flush */
smb_get_info
,
/* get_file_info */
NULL
,
/* queue_async */
destroy_smb
/* destroy */
};
static
void
destroy_smb
(
struct
object
*
obj
)
{
/* struct smb *smb = (struct smb *)obj; */
assert
(
obj
->
ops
==
&
smb_ops
);
}
static
void
smb_dump
(
struct
object
*
obj
,
int
verbose
)
{
struct
smb
*
smb
=
(
struct
smb
*
)
obj
;
assert
(
obj
->
ops
==
&
smb_ops
);
fprintf
(
stderr
,
"smb file with socket fd=%d
\n
"
,
smb
->
obj
.
fd
);
}
struct
smb
*
get_smb_obj
(
struct
process
*
process
,
handle_t
handle
,
unsigned
int
access
)
{
return
(
struct
smb
*
)
get_handle_obj
(
process
,
handle
,
access
,
&
smb_ops
);
}
static
int
smb_get_poll_events
(
struct
object
*
obj
)
{
/* struct smb *smb = (struct smb *)obj; */
int
events
=
0
;
assert
(
obj
->
ops
==
&
smb_ops
);
events
|=
POLLIN
;
/* fprintf(stderr,"poll events are %04x\n",events); */
return
events
;
}
static
int
smb_get_fd
(
struct
object
*
obj
)
{
struct
smb
*
smb
=
(
struct
smb
*
)
obj
;
assert
(
obj
->
ops
==
&
smb_ops
);
return
smb
->
obj
.
fd
;
}
static
int
smb_get_info
(
struct
object
*
obj
,
struct
get_file_info_reply
*
reply
,
int
*
flags
)
{
/* struct smb *smb = (struct smb *) obj; */
assert
(
obj
->
ops
==
&
smb_ops
);
if
(
reply
)
{
reply
->
type
=
FILE_TYPE_CHAR
;
reply
->
attr
=
0
;
reply
->
access_time
=
0
;
reply
->
write_time
=
0
;
reply
->
size_high
=
0
;
reply
->
size_low
=
0
;
reply
->
links
=
0
;
reply
->
index_high
=
0
;
reply
->
index_low
=
0
;
reply
->
serial
=
0
;
}
*
flags
=
0
;
return
FD_TYPE_SMB
;
}
/* create a smb */
DECL_HANDLER
(
create_smb
)
{
struct
smb
*
smb
;
int
fd
;
reply
->
handle
=
0
;
fd
=
thread_get_inflight_fd
(
current
,
req
->
fd
);
if
(
fd
==
-
1
)
{
set_error
(
STATUS_INVALID_HANDLE
);
return
;
}
smb
=
alloc_object
(
&
smb_ops
,
fd
);
if
(
smb
)
{
smb
->
tree_id
=
req
->
tree_id
;
smb
->
user_id
=
req
->
user_id
;
smb
->
dialect
=
req
->
dialect
;
smb
->
file_id
=
req
->
file_id
;
smb
->
offset
=
0
;
reply
->
handle
=
alloc_handle
(
current
->
process
,
smb
,
GENERIC_READ
,
0
);
release_object
(
smb
);
}
}
DECL_HANDLER
(
get_smb_info
)
{
struct
smb
*
smb
;
if
((
smb
=
get_smb_obj
(
current
->
process
,
req
->
handle
,
0
)))
{
if
(
req
->
flags
&
SMBINFO_SET_OFFSET
)
smb
->
offset
=
req
->
offset
;
reply
->
tree_id
=
smb
->
tree_id
;
reply
->
user_id
=
smb
->
user_id
;
reply
->
dialect
=
smb
->
dialect
;
reply
->
file_id
=
smb
->
file_id
;
reply
->
offset
=
smb
->
offset
;
release_object
(
smb
);
}
}
server/trace.c
View file @
fc932611
...
...
@@ -1843,6 +1843,36 @@ static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_rep
fprintf
(
stderr
,
" insize=%08x"
,
req
->
insize
);
}
static
void
dump_create_smb_request
(
const
struct
create_smb_request
*
req
)
{
fprintf
(
stderr
,
" fd=%d,"
,
req
->
fd
);
fprintf
(
stderr
,
" tree_id=%08x,"
,
req
->
tree_id
);
fprintf
(
stderr
,
" user_id=%08x,"
,
req
->
user_id
);
fprintf
(
stderr
,
" file_id=%08x,"
,
req
->
file_id
);
fprintf
(
stderr
,
" dialect=%08x"
,
req
->
dialect
);
}
static
void
dump_create_smb_reply
(
const
struct
create_smb_reply
*
req
)
{
fprintf
(
stderr
,
" handle=%d"
,
req
->
handle
);
}
static
void
dump_get_smb_info_request
(
const
struct
get_smb_info_request
*
req
)
{
fprintf
(
stderr
,
" handle=%d,"
,
req
->
handle
);
fprintf
(
stderr
,
" flags=%08x,"
,
req
->
flags
);
fprintf
(
stderr
,
" offset=%08x"
,
req
->
offset
);
}
static
void
dump_get_smb_info_reply
(
const
struct
get_smb_info_reply
*
req
)
{
fprintf
(
stderr
,
" tree_id=%08x,"
,
req
->
tree_id
);
fprintf
(
stderr
,
" user_id=%08x,"
,
req
->
user_id
);
fprintf
(
stderr
,
" dialect=%08x,"
,
req
->
dialect
);
fprintf
(
stderr
,
" file_id=%08x,"
,
req
->
file_id
);
fprintf
(
stderr
,
" offset=%08x"
,
req
->
offset
);
}
static
void
dump_create_window_request
(
const
struct
create_window_request
*
req
)
{
fprintf
(
stderr
,
" parent=%08x,"
,
req
->
parent
);
...
...
@@ -2193,6 +2223,8 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
dump_wait_named_pipe_request
,
(
dump_func
)
dump_disconnect_named_pipe_request
,
(
dump_func
)
dump_get_named_pipe_info_request
,
(
dump_func
)
dump_create_smb_request
,
(
dump_func
)
dump_get_smb_info_request
,
(
dump_func
)
dump_create_window_request
,
(
dump_func
)
dump_link_window_request
,
(
dump_func
)
dump_destroy_window_request
,
...
...
@@ -2346,6 +2378,8 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(
dump_func
)
0
,
(
dump_func
)
0
,
(
dump_func
)
dump_get_named_pipe_info_reply
,
(
dump_func
)
dump_create_smb_reply
,
(
dump_func
)
dump_get_smb_info_reply
,
(
dump_func
)
dump_create_window_reply
,
(
dump_func
)
dump_link_window_reply
,
(
dump_func
)
0
,
...
...
@@ -2499,6 +2533,8 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"wait_named_pipe"
,
"disconnect_named_pipe"
,
"get_named_pipe_info"
,
"create_smb"
,
"get_smb_info"
,
"create_window"
,
"link_window"
,
"destroy_window"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment