diff options
author | Andrew Tridgell <tridge@samba.org> | 2008-02-13 15:05:44 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2008-02-13 15:05:44 +1100 |
commit | 88d2e0522737fb8856fb0f52c2af8a2f56130f19 (patch) | |
tree | f07130f685c2be97b1b1b6eade93df0237ef7171 | |
parent | 7714a91f6762bb8d6578d89a49bfd5672aca054c (diff) | |
download | samba-88d2e0522737fb8856fb0f52c2af8a2f56130f19.tar.gz samba-88d2e0522737fb8856fb0f52c2af8a2f56130f19.tar.xz samba-88d2e0522737fb8856fb0f52c2af8a2f56130f19.zip |
updated SMB2 create operation to match WSPP.
Adding some defined for various new create options
(This used to be commit d037dc23ced3df6bce98cbf4810fb5f1247336bd)
-rw-r--r-- | source4/libcli/raw/interfaces.h | 25 | ||||
-rw-r--r-- | source4/libcli/smb2/create.c | 52 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2.h | 28 | ||||
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 4 | ||||
-rw-r--r-- | source4/smb_server/smb2/fileio.c | 22 | ||||
-rw-r--r-- | source4/torture/smb2/connect.c | 10 | ||||
-rw-r--r-- | source4/torture/smb2/lock.c | 8 | ||||
-rw-r--r-- | source4/torture/smb2/util.c | 40 |
8 files changed, 109 insertions, 80 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index ddbddf4c59e..ce6323f2e53 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -1552,16 +1552,16 @@ union smb_open { enum smb_open_level level; struct { /* static body buffer 56 (0x38) bytes */ - /* uint16_t buffer_code; 0x39 = 0x38 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ - uint32_t impersonation; - uint32_t unknown3[4]; - uint32_t access_mask; - - uint32_t file_attr; - uint32_t share_access; - uint32_t open_disposition; - uint32_t create_options; + uint8_t security_flags; /* SMB2_SECURITY_* */ + uint8_t oplock_level; /* SMB2_OPLOCK_LEVEL_* */ + uint32_t impersonation_level; /* SMB2_IMPERSONATION_* */ + uint64_t create_flags; + uint64_t reserved; + uint32_t desired_access; + uint32_t file_attributes; + uint32_t share_access; /* NTCREATEX_SHARE_ACCESS_* */ + uint32_t create_disposition; /* NTCREATEX_DISP_* */ + uint32_t create_options; /* NTCREATEX_OPTIONS_* */ /* uint16_t fname_ofs */ /* uint16_t fname_size */ @@ -1579,7 +1579,8 @@ union smb_open { /* static body buffer 88 (0x58) bytes */ /* uint16_t buffer_code; 0x59 = 0x58 + 1 */ - uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint8_t oplock_level; + uint8_t reserved; uint32_t create_action; NTTIME create_time; NTTIME access_time; @@ -1588,7 +1589,7 @@ union smb_open { uint64_t alloc_size; uint64_t size; uint32_t file_attr; - uint32_t _pad; + uint32_t reserved2; /* struct smb2_handle handle;*/ /* uint32_t blob_ofs; */ /* uint32_t blob_size; */ diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index ba11c22e87e..cca83a040c5 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -24,34 +24,33 @@ #include "libcli/smb2/smb2.h" #include "libcli/smb2/smb2_calls.h" -#define CREATE_TAG_EXTA 0x41747845 /* "ExtA" */ -#define CREATE_TAG_MXAC 0x6341784D /* "MxAc" */ - /* add a blob to a smb2_create attribute blob */ NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, - uint32_t tag, + const char *tag, DATA_BLOB add, bool last) { uint32_t ofs = blob->length; - uint8_t pad = smb2_padding_size(add.length, 8); - if (!data_blob_realloc(mem_ctx, blob, blob->length + 0x18 + add.length + pad)) + size_t tag_length = strlen(tag); + uint8_t pad = smb2_padding_size(add.length+tag_length, 8); + if (!data_blob_realloc(mem_ctx, blob, + blob->length + 0x14 + tag_length + add.length + pad)) return NT_STATUS_NO_MEMORY; if (last) { SIVAL(blob->data, ofs+0x00, 0); } else { - SIVAL(blob->data, ofs+0x00, 0x18 + add.length + pad); + SIVAL(blob->data, ofs+0x00, 0x14 + tag_length + add.length + pad); } SSVAL(blob->data, ofs+0x04, 0x10); /* offset of tag */ - SIVAL(blob->data, ofs+0x06, 0x04); /* tag length */ - SSVAL(blob->data, ofs+0x0A, 0x18); /* offset of data */ + SIVAL(blob->data, ofs+0x06, tag_length); /* tag length */ + SSVAL(blob->data, ofs+0x0A, 0x14 + tag_length); /* offset of data */ SIVAL(blob->data, ofs+0x0C, add.length); - SIVAL(blob->data, ofs+0x10, tag); - SIVAL(blob->data, ofs+0x14, 0); /* pad? */ - memcpy(blob->data+ofs+0x18, add.data, add.length); - memset(blob->data+ofs+0x18+add.length, 0, pad); + memcpy(blob->data+ofs+0x10, tag, tag_length); + SIVAL(blob->data, ofs+0x10+tag_length, 0); /* pad? */ + memcpy(blob->data+ofs+0x14+tag_length, add.data, add.length); + memset(blob->data+ofs+0x14+tag_length+add.length, 0, pad); return NT_STATUS_OK; } @@ -68,16 +67,15 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0); if (req == NULL) return NULL; - SSVAL(req->out.body, 0x02, io->in.oplock_flags); - SIVAL(req->out.body, 0x04, io->in.impersonation); - SIVAL(req->out.body, 0x08, io->in.unknown3[0]); - SIVAL(req->out.body, 0x0C, io->in.unknown3[1]); - SIVAL(req->out.body, 0x10, io->in.unknown3[2]); - SIVAL(req->out.body, 0x14, io->in.unknown3[3]); - SIVAL(req->out.body, 0x18, io->in.access_mask); - SIVAL(req->out.body, 0x1C, io->in.file_attr); + SCVAL(req->out.body, 0x02, io->in.security_flags); + SCVAL(req->out.body, 0x03, io->in.oplock_level); + SIVAL(req->out.body, 0x04, io->in.impersonation_level); + SBVAL(req->out.body, 0x08, io->in.create_flags); + SBVAL(req->out.body, 0x10, io->in.reserved); + SIVAL(req->out.body, 0x18, io->in.desired_access); + SIVAL(req->out.body, 0x1C, io->in.file_attributes); SIVAL(req->out.body, 0x20, io->in.share_access); - SIVAL(req->out.body, 0x24, io->in.open_disposition); + SIVAL(req->out.body, 0x24, io->in.create_disposition); SIVAL(req->out.body, 0x28, io->in.create_options); status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname); @@ -90,7 +88,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create DATA_BLOB b = data_blob_talloc(req, NULL, ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas)); ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas); - status = smb2_create_blob_add(req, &blob, CREATE_TAG_EXTA, b, false); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_EXTA, b, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); return NULL; @@ -100,7 +98,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create /* an empty MxAc tag seems to be used to ask the server to return the maximum access mask allowed on the file */ - status = smb2_create_blob_add(req, &blob, CREATE_TAG_MXAC, data_blob(NULL, 0), true); + status = smb2_create_blob_add(req, &blob, SMB2_CREATE_TAG_MXAC, + data_blob(NULL, 0), true); if (!NT_STATUS_IS_OK(status)) { talloc_free(req); @@ -132,7 +131,8 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct SMB2_CHECK_PACKET_RECV(req, 0x58, true); - io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.oplock_level = CVAL(req->in.body, 0x02); + io->out.reserved = CVAL(req->in.body, 0x03); io->out.create_action = IVAL(req->in.body, 0x04); io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); @@ -141,7 +141,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct io->out.alloc_size = BVAL(req->in.body, 0x28); io->out.size = BVAL(req->in.body, 0x30); io->out.file_attr = IVAL(req->in.body, 0x38); - io->out._pad = IVAL(req->in.body, 0x3C); + io->out.reserved2 = IVAL(req->in.body, 0x3C); smb2_pull_handle(req->in.body+0x40, &io->out.file.handle); status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 549b477ffd2..db13ab69b33 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -217,6 +217,34 @@ struct smb2_request { #define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM 0x0800 #define SMB2_SHAREFLAG_ALL 0x0F33 +/* SMB2 create security flags */ +#define SMB2_SECURITY_DYNAMIC_TRACKING 0x01 +#define SMB2_SECURITY_EFFECTIVE_ONLY 0x02 + +/* SMB2 requested oplock levels */ +#define SMB2_OPLOCK_LEVEL_NONE 0x00 +#define SMB2_OPLOCK_LEVEL_II 0x01 +#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08 +#define SMB2_OPLOCK_LEVEL_BATCH 0x09 + +/* SMB2 impersonation levels */ +#define SMB2_IMPERSONATION_ANONYMOUS 0x00 +#define SMB2_IMPERSONATION_IDENTIFICATION 0x01 +#define SMB2_IMPERSONATION_IMPERSONATION 0x02 +#define SMB2_IMPERSONATION_DELEGATE 0x03 + +/* SMB2 create tags */ +#define SMB2_CREATE_TAG_EXTA "ExtA" +#define SMB2_CREATE_TAG_MXAC "MxAc" +#define SMB2_CREATE_TAG_SECD "SecD" +#define SMB2_CREATE_TAG_DHNQ "DHnQ" +#define SMB2_CREATE_TAG_DHNC "DHnC" +#define SMB2_CREATE_TAG_ALSI "AlSi" +#define SMB2_CREATE_TAG_TWRP "TWrp" +#define SMB2_CREATE_TAG_QFID "QFid" + + + /* check that a body has the expected size */ diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 81cd984f0b5..92f0eadae1d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -322,7 +322,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); oi->smb2.out.file.ntvfs = p->handle; - oi->smb2.out.oplock_flags = oi->smb2.in.oplock_flags; + oi->smb2.out.oplock_level = oi->smb2.in.oplock_level; oi->smb2.out.create_action = NTCREATEX_ACTION_EXISTED; oi->smb2.out.create_time = 0; oi->smb2.out.access_time = 0; @@ -331,7 +331,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, oi->smb2.out.alloc_size = 4096; oi->smb2.out.size = 0; oi->smb2.out.file_attr = FILE_ATTRIBUTE_NORMAL; - oi->smb2.out._pad = 0; + oi->smb2.out.reserved2 = 0; oi->smb2.out.blob = data_blob(NULL, 0); return status; diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c index 0e83c786152..567243ba943 100644 --- a/source4/smb_server/smb2/fileio.c +++ b/source4/smb_server/smb2/fileio.c @@ -34,7 +34,8 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs) SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open); SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, io->smb2.out.blob.length)); - SSVAL(req->out.body, 0x02, io->smb2.out.oplock_flags); + SCVAL(req->out.body, 0x02, io->smb2.out.oplock_level); + SCVAL(req->out.body, 0x03, io->smb2.out.reserved); SIVAL(req->out.body, 0x04, io->smb2.out.create_action); SBVAL(req->out.body, 0x08, io->smb2.out.create_time); SBVAL(req->out.body, 0x10, io->smb2.out.access_time); @@ -43,7 +44,7 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs) SBVAL(req->out.body, 0x28, io->smb2.out.alloc_size); SBVAL(req->out.body, 0x30, io->smb2.out.size); SIVAL(req->out.body, 0x38, io->smb2.out.file_attr); - SIVAL(req->out.body, 0x3C, io->smb2.out._pad); + SIVAL(req->out.body, 0x3C, io->smb2.out.reserved2); smb2srv_push_handle(req->out.body, 0x40, io->smb2.out.file.ntvfs); SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, io->smb2.out.blob)); @@ -64,16 +65,15 @@ void smb2srv_create_recv(struct smb2srv_request *req) SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC); io->smb2.level = RAW_OPEN_SMB2; - io->smb2.in.oplock_flags = SVAL(req->in.body, 0x02); - io->smb2.in.impersonation = IVAL(req->in.body, 0x04); - io->smb2.in.unknown3[0] = IVAL(req->in.body, 0x08); - io->smb2.in.unknown3[1] = IVAL(req->in.body, 0x0C); - io->smb2.in.unknown3[2] = IVAL(req->in.body, 0x10); - io->smb2.in.unknown3[3] = IVAL(req->in.body, 0x14); - io->smb2.in.access_mask = IVAL(req->in.body, 0x18); - io->smb2.in.file_attr = IVAL(req->in.body, 0x1C); + io->smb2.in.security_flags = CVAL(req->in.body, 0x02); + io->smb2.in.oplock_level = CVAL(req->in.body, 0x03); + io->smb2.in.impersonation_level = IVAL(req->in.body, 0x04); + io->smb2.in.create_flags = BVAL(req->in.body, 0x08); + io->smb2.in.reserved = BVAL(req->in.body, 0x10); + io->smb2.in.desired_access = IVAL(req->in.body, 0x18); + io->smb2.in.file_attributes = IVAL(req->in.body, 0x1C); io->smb2.in.share_access = IVAL(req->in.body, 0x20); - io->smb2.in.open_disposition = IVAL(req->in.body, 0x24); + io->smb2.in.create_disposition = IVAL(req->in.body, 0x24); io->smb2.in.create_options = IVAL(req->in.body, 0x28); SMB2SRV_CHECK(smb2_pull_o16s16_string(&req->in, io, req->in.body+0x2C, &io->smb2.in.fname)); SMB2SRV_CHECK(smb2_pull_o32s32_blob(&req->in, io, req->in.body+0x30, &blob)); diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c index f1bc63dbbb8..0004ea958e1 100644 --- a/source4/torture/smb2/connect.c +++ b/source4/torture/smb2/connect.c @@ -147,10 +147,10 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree, TALLOC_CTX *tmp_ctx = talloc_new(tree); ZERO_STRUCT(io); - io.in.oplock_flags = 0; - io.in.access_mask = SEC_RIGHTS_FILE_ALL; - io.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.in.oplock_level = 0; + io.in.desired_access = SEC_RIGHTS_FILE_ALL; + io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| @@ -166,7 +166,7 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree, if (DEBUGLVL(1)) { printf("Open gave:\n"); - printf("oplock_flags = 0x%x\n", io.out.oplock_flags); + printf("oplock_flags = 0x%x\n", io.out.oplock_level); printf("create_action = 0x%x\n", io.out.create_action); printf("create_time = %s\n", nt_time_string(tmp_ctx, io.out.create_time)); printf("access_time = %s\n", nt_time_string(tmp_ctx, io.out.access_time)); diff --git a/source4/torture/smb2/lock.c b/source4/torture/smb2/lock.c index 98e412817bc..3cf2e93ee04 100644 --- a/source4/torture/smb2/lock.c +++ b/source4/torture/smb2/lock.c @@ -238,10 +238,10 @@ static bool test_lock_read_write(struct torture_context *torture, CHECK_VALUE(lck.out.unknown1, 0); ZERO_STRUCT(cr); - cr.in.oplock_flags = 0; - cr.in.access_mask = SEC_RIGHTS_FILE_ALL; - cr.in.file_attr = FILE_ATTRIBUTE_NORMAL; - cr.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + cr.in.oplock_level = 0; + cr.in.desired_access = SEC_RIGHTS_FILE_ALL; + cr.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + cr.in.create_disposition = NTCREATEX_DISP_OPEN_IF; cr.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| diff --git a/source4/torture/smb2/util.c b/source4/torture/smb2/util.c index fe88296a320..219c2140d30 100644 --- a/source4/torture/smb2/util.c +++ b/source4/torture/smb2/util.c @@ -55,9 +55,9 @@ NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname) NTSTATUS status; ZERO_STRUCT(io); - io.in.access_mask = SEC_RIGHTS_FILE_ALL; - io.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io.in.open_disposition = NTCREATEX_DISP_OPEN; + io.in.desired_access = SEC_RIGHTS_FILE_ALL; + io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io.in.create_disposition = NTCREATEX_DISP_OPEN; io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| @@ -107,9 +107,9 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname, smb2_util_unlink(tree, fname); ZERO_STRUCT(io); - io.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - io.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED; + io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF; io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| @@ -119,8 +119,8 @@ static NTSTATUS smb2_create_complex(struct smb2_tree *tree, const char *fname, if (dir) { io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE; - io.in.file_attr = FILE_ATTRIBUTE_DIRECTORY; - io.in.open_disposition = NTCREATEX_DISP_CREATE; + io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + io.in.create_disposition = NTCREATEX_DISP_CREATE; } if (strchr(fname, ':') == NULL) { @@ -334,10 +334,10 @@ NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname, NTSTATUS status; ZERO_STRUCT(io); - io.in.oplock_flags = 0; - io.in.access_mask = SEC_RIGHTS_FILE_ALL; - io.in.file_attr = FILE_ATTRIBUTE_NORMAL; - io.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.in.oplock_level = 0; + io.in.desired_access = SEC_RIGHTS_FILE_ALL; + io.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.share_access = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| @@ -370,10 +370,10 @@ NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname, NTSTATUS status; ZERO_STRUCT(io); - io.in.oplock_flags = 0; - io.in.access_mask = SEC_RIGHTS_DIR_ALL; - io.in.file_attr = FILE_ATTRIBUTE_DIRECTORY; - io.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.in.oplock_level = 0; + io.in.desired_access = SEC_RIGHTS_DIR_ALL; + io.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + io.in.create_disposition = NTCREATEX_DISP_OPEN_IF; io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE; io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; io.in.fname = fname; @@ -422,10 +422,10 @@ NTSTATUS smb2_util_roothandle(struct smb2_tree *tree, struct smb2_handle *handle NTSTATUS status; ZERO_STRUCT(io); - io.in.oplock_flags = 0; - io.in.access_mask = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST; - io.in.file_attr = 0; - io.in.open_disposition = NTCREATEX_DISP_OPEN; + io.in.oplock_level = 0; + io.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST; + io.in.file_attributes = 0; + io.in.create_disposition = NTCREATEX_DISP_OPEN; io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE; io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT; io.in.fname = ""; |