1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

Add async open&x

(This used to be commit faf353edd6)
This commit is contained in:
Volker Lendecke 2008-08-02 18:44:39 +02:00
parent 8f408a676e
commit de9fcfc795
2 changed files with 122 additions and 35 deletions

View File

@ -4378,6 +4378,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname,
uint32 CreateDisposition, uint32 CreateOptions,
uint8 SecuityFlags);
int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess);
struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct cli_state *cli,
const char *fname, int flags, int share_mode);
NTSTATUS cli_open_recv(struct async_req *req, int *fnum);
int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode);
struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
struct cli_state *cli, int fnum);

View File

@ -781,19 +781,61 @@ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0);
}
static uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str)
{
size_t buflen = talloc_get_size(buf);
char *converted;
size_t converted_size;
/*
* We're pushing into an SMB buffer, align odd
*/
if (ucs2 && (buflen % 2 == 0)) {
buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1);
if (buf == NULL) {
return NULL;
}
buf[buflen] = '\0';
buflen += 1;
}
if (!convert_string_allocate(talloc_tos(), CH_UNIX,
ucs2 ? CH_UTF16LE : CH_DOS,
str, strlen(str)+1, &converted,
&converted_size, true)) {
return NULL;
}
buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t,
buflen + converted_size);
if (buf == NULL) {
return NULL;
}
memcpy(buf + buflen, converted, converted_size);
TALLOC_FREE(converted);
return buf;
}
/****************************************************************************
Open a file
WARNING: if you open with O_WRONLY then getattrE won't work!
****************************************************************************/
int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode)
struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct cli_state *cli,
const char *fname, int flags, int share_mode)
{
char *p;
unsigned openfn=0;
unsigned accessmode=0;
unsigned openfn = 0;
unsigned accessmode = 0;
uint8_t additional_flags = 0;
uint8_t *bytes;
uint16_t vwv[15];
struct async_req *result;
if (flags & O_CREAT)
if (flags & O_CREAT) {
openfn |= (1<<4);
}
if (!(flags & O_EXCL)) {
if (flags & O_TRUNC)
openfn |= (1<<1);
@ -819,46 +861,88 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode
accessmode = 0xFF;
}
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
cli_set_message(cli->outbuf,15,0, true);
SCVAL(cli->outbuf,smb_com,SMBopenX);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
SSVAL(cli->outbuf,smb_vwv3,accessmode);
SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
SSVAL(cli->outbuf,smb_vwv5,0);
SSVAL(cli->outbuf,smb_vwv8,openfn);
SCVAL(vwv + 0, 0, 0xFF);
SCVAL(vwv + 0, 1, 0);
SSVAL(vwv + 1, 0, 0);
SSVAL(vwv + 2, 0, 0); /* no additional info */
SSVAL(vwv + 3, 0, accessmode);
SSVAL(vwv + 4, 0, aSYSTEM | aHIDDEN);
SSVAL(vwv + 5, 0, 0);
SIVAL(vwv + 6, 0, 0);
SSVAL(vwv + 8, 0, openfn);
SIVAL(vwv + 9, 0, 0);
SIVAL(vwv + 11, 0, 0);
SIVAL(vwv + 13, 0, 0);
if (cli->use_oplocks) {
/* if using oplocks then ask for a batch oplock via
core and extended methods */
SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)|
FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK);
SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
additional_flags =
FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
SSVAL(vwv+2, 0, SVAL(vwv+2, 0) | 6);
}
p = smb_buf(cli->outbuf);
p += clistr_push(cli, p, fname,
cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE);
cli_setup_bcc(cli, p);
cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return -1;
bytes = talloc_array(talloc_tos(), uint8_t, 0);
if (bytes == NULL) {
return NULL;
}
if (cli_is_error(cli)) {
return -1;
bytes = smb_bytes_push_str(
bytes, (cli->capabilities & CAP_UNICODE) != 0, fname);
if (bytes == NULL) {
return NULL;
}
return SVAL(cli->inbuf,smb_vwv2);
result = cli_request_send(mem_ctx, cli, SMBopenX, additional_flags,
15, vwv, talloc_get_size(bytes), bytes);
TALLOC_FREE(bytes);
return result;
}
NTSTATUS cli_open_recv(struct async_req *req, int *fnum)
{
struct cli_request *cli_req = cli_request_get(req);
NTSTATUS status;
SMB_ASSERT(req->state >= ASYNC_REQ_DONE);
if (req->state == ASYNC_REQ_ERROR) {
return req->status;
}
status = cli_pull_error(cli_req->inbuf);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
*fnum = SVAL(cli_req->inbuf, smb_vwv2);
return NT_STATUS_OK;
}
int cli_open(struct cli_state *cli, const char *fname, int flags,
int share_mode)
{
TALLOC_CTX *frame = talloc_stackframe();
struct async_req *req;
int result = -1;
if (cli_tmp_event_ctx(frame, cli) == NULL) {
goto fail;
}
req = cli_open_send(frame, cli, fname, flags, share_mode);
if (req == NULL) {
goto fail;
}
while (req->state < ASYNC_REQ_DONE) {
event_loop_once(cli->event_ctx);
}
cli_open_recv(req, &result);
fail:
TALLOC_FREE(frame);
return result;
}
/****************************************************************************