MarshalledBuffer_t (Compact 2013)
3/28/2014
This class is a wrapper for the CeOpenCallerBuffer, the CeCloseCallerBuffer, the CeAllocAsynchronousBuffer, and the CeFreeAsynchronousBuffer functions. Only use it with embedded pointers that have not already been access-checked or marshaled by the kernel.
To duplicate a buffer that has already been marshaled, use the DuplicatedBuffer_t function. To obtain asynchronous access to a buffer that has already been marshaled, use the AsynchronousBuffer_t function.
Syntax
class MarshalledBuffer_t {
public:
MarshalledBuffer_t()
MarshalledBuffer_t()
MarshalledBuffer_t(
PVOID pSrcUnmarshalled,
DWORD cbSrc,
DWORD ArgumentDescriptor,
BOOL ForceDuplicate = TRUE,
BOOL Asynchronous = FALSE
);
MarshalledBuffer_t(
PCVOID pSrcUnmarshalled,
DWORD cbSrc,
DWORD ArgumentDescriptor,
BOOL ForceDuplicate = TRUE,
BOOL Asynchronous = FALSE
);
HRESULT Marshal(
PVOID pSrcUnmarshalled,
DWORD cbSrc,
DWORD ArgumentDescriptor,
BOOL ForceDuplicate = TRUE,
BOOL Asynchronous = FALSE
);
HRESULT Marshal(
PCVOID pSrcUnmarshalled,
DWORD cbSrc,
DWORD ArgumentDescriptor,
BOOL ForceDuplicate = TRUE,
BOOL Asynchronous = FALSE
);
HRESULT Flush();
HRESULT Unmarshal();
LPVOID ptr() const;
DWORD size() const;
};
Methods
Methods |
Description |
---|---|
|
Access-checks and marshals a buffer pointer from the source process, so that it can be accessed by the current process. Exposes the marshaled pointer with the ptr accessor. Any allocated resources related to the marshaling are freed only by a subsequent call to Unmarshal, or by the destructor. Typically, you would either use the default constructor and Marshal to marshal the buffer or the marshaling constructor. Use the former method if you require an HRESULT. Similarly, you can allow the destructor to release marshaling resources, or use Unmarshal. If an HRESULT is required, use the Unmarshal function. |
|
If marshaling fails, ptr returns NULL, and size retursn zero. Otherwise, the marshaled buffer is accessible with ptr and size. For more information, see CeOpenCallerBuffer and CeAllocAsynchronousBuffer. |
|
Takes a constructor pSrcUnmarshalled. This method can be used only with ARG_I_* types. |
|
Takes a constructor pSrcMarshalled. |
|
Takes a constructor pSrcMarshalled. This method can only be used with ARG_I_* types. |
|
Takes a constructor pSrcMarshalled. |
|
Takes a const pSrcMarshalled. This method can be used only with ARG_I_* types. |
|
Once a MarshalledBuffer is marshaled using the marshaling constructor or the Marshal method, it cannot be re-used by calling Marshal until after Unmarshal is called. An attempt to do so returns ERROR_ALREADY_EXISTS. If Marshal fails, ptr returns NULL, and size returns zero. Otherwise, the marshaled buffer is accessible with ptr and size. For more information, see CeOpenCallerBuffer and CeAllocAsynchronousBuffer. |
|
Takes a constructor pSrcUnmarshalled. This method can be used only with ARG_I_* types. |
|
If the buffer has already been unmarshaled or if it is not an asynchronous buffer, this method fails with ERROR_INVALID_PARAMETER. For more information, see CeFlushAsynchronousBuffer. |
|
If the buffer has already been unmarshaled, this method fails with ERROR_ALREADY_EXISTS. For more information, see CeCloseCallerBuffer. |
|
Returns a pointer to the marshaled buffer, or NULL if the buffer has not been marshaled or has already been unmarshaled. |
|
Returns the size of the marshaled buffer, or zero if the buffer has not been marshaled or has already been unmarshaled. |
Remarks
You may choose to optimize large asynchronous buffer accesses by using the MARSHAL_FORCE_ALIAS flag. If your code is running inside the kernel process, and you are using an ARM microprocessor with a virtually tagged cache, you can pass MARSHAL_FORCE_ALIAS as part of the ArgumentDescriptor. On all other CPUs, MARSHAL_FORCE_ALIAS has no effect.
Use the MARSHAL_FORCE_ALIAS flag only if you are using buffers greater than 16 KB.
On ARM CPUs that use a virtually tagged cache, inside the kernel process, CeAllocAsynchronousBuffer creates a duplicate copy of the memory on the heap by default. On large buffers, creating the duplicate heap can affect performance. To prevent duplication, pass the MARSHAL_FORCE_ALIAS flag to cause CeAllocAsynchronousBuffer to create an alias, instead. However, the creation of aliased memory on ARM CPUs that use a virtually tagged cache causes both the source and destination memory to be accessed as uncached, until the alias is destroyed by CeFreeAsynchronousBuffer. This means that the memory accesses become slower at both the source and destination.
On all CPUs, inside user-mode processes, CeAllocAsynchronousBuffer always creates a duplicate of the memory with VirtualCopy, regardless of whether the MARSHAL_FORCE_ALIAS flag is passed. There is no way to force the creation of an alias from user mode.
If you pass MARSHAL_FORCE_ALIAS to CeAllocAsynchronousBuffer, you should also pass it when you call CeFlushAsynchronousBuffer and CeFreeAsynchronousBuffer. Not passing it can cause the system to become unresponsive or resource leaks.
The following table describes the descriptors.
Descriptors |
Purpose |
---|---|
ARG_I_PTR |
Input-only pointer. |
ARG_I_WSTR |
Input-only Unicode string. |
ARG_I_ASTR |
Input-only ASCII string. |
ARG_I_PDW |
Input-only pointer to a DWORD. |
ARG_O_PTR |
Output-only pointer. |
ARG_O_PDW |
Output-only pointer to a DWORD. |
ARG_O_PI64 |
Output-only pointer to a 64-bit value. |
ARG_IO_PTR |
Input and output pointer. |
ARG_IO_PDW |
I/O pointer to a DWORD. |
ARG_IO_PI64 |
I/O pointer to a 64-bit value. |
Requirements
Header |
marshal.hpp |
Library |
coredll.lib |
See Also
Reference
Kernel Buffer Marshaling Classes
CeOpenCallerBuffer
CeCloseCallerBuffer
CeAllocAsynchronousBuffer
CeFlushAsynchronousBuffer
CeFreeAsynchronousBuffer
DuplicatedBuffer_t
AsynchronousBuffer_t