lpSecurityAttributes
passed to CreateNamedPipe()
?The MSDN documentation for CreateNamedPipe() says:
lpSecurityAttributes [in, optional]
A pointer to a SECURITY_ATTRIBUTES structure that specifies a security descriptor for the new named pipe...
Emphasis mine. Does 'new' mean new named pipe, or new instance of the named pipe? It goes on to say:
Remarks
To create an instance of a named pipe by using CreateNamedPipe, the user must have FILE_CREATE_PIPE_INSTANCE access to the named pipe object. If a new named pipe is being created, the access control list (ACL) from the security attributes parameter defines the discretionary access control for the named pipe.
(Again, emphasis mine.) One could read this as meaning that lpSecurityAttributes
is used only when creating the first instance of the named pipe (a new named pipe), and is ignored when creating further instances of the same named pipe. If so, then only one instance of the lpSecurityAttributes
structure is required.
Or maybe you have to pass in a valid lpSecurityAttributes for each instance, but it can (should?) be the same one?
Or perhaps you have to allocate a new SECURITY_ATTRIBUTES structure for each pipe instance?
My related question - can the SECURITY_ATTRIBUTES structure be destroyed as soon as the call to CreateNamedPipe()
returns or does it have to remain valid until the last handle (to the pipe, or just that pipe instance?) is closed - isn't even addressed.
Does anyone have definitive answers to these two questions?
You need to pass either a valid SECURITY_ATTRIBUTES structure or NULL to every call to CreateNamedPipe. You can either reuse the same structure for additional calls or use separate structures, whichever is more convenient. It might not be safe to use the same structure in multiple simultaneous calls from separate threads - I suspect it would be OK, but I'd avoid it anyway.
'New' means 'new pipe' not 'new instance'. The ACL in the lpSecurityDescriptor member is not used if the named pipe already exists. Therefore, if you know you are creating a new instance of an existing pipe, and do not need to set bInheritHandle, you should just pass NULL for lpSecurityAttributes. If you do need to set bInheritHandle, then make sure that lpSecurityDescriptor is either NULL or points to a valid security descriptor.
As already mentioned, the content in lpSecurityAttributes can be discarded as soon as the call returns (unless you're planning to reuse it in another call!) and yes, that includes the memory allocated to the security descriptor.