C# Class Dse.Auth.Sspi.Buffers.SecureBufferAdapter

Prepares SecureBuffers for providing them to native API calls.
The native APIs consume lists of buffers, with each buffer indicating its type or purpose. The buffers themselves are simple byte arrays, and the native APIs consume arrays of buffers. Since winapi calling convention, perhaps as an extension of C calling convention, does not provide a standard convention means of communicating the length of any array, custom structures must be created to carry the buffer length and usage. Not only does the API need to know how long each buffer is, and how long the array of buffers is, it needs to communicate back how much of each buffer was filled; we may provide it a token buffer that is 12288 bytes long, but it might only use 125 bytes of that, which we need a way of knowing. As a result of this, the API requires byte arrays to be carried in structs that are natively known as SecureBuffers (known as SecureBufferInternal in this project), and then arrays of SecureBuffers are carried in a SecureBufferDescriptor structure. As such, this class has to do a significant amount of marshaling work just to get the buffers back and forth to the native APIs. * We have to pin all buffers * We have to pin the array of buffers * We have to obtain IntPtr handles to each of the buffers and to the array of buffers. * Since we provide EasyToUse SecureBuffer classes from the rest of the project, but we provide SecureBufferInternal structures from the native API, we have to copy back values from the SecureBufferInternal structs to our SecureBuffer class. To make this class easy to use, it accepts either one or many buffers as its constructor; and implements IDisposable to know when to marshal values back from the unmanaged structures and to release pinned handles. Additionally, in case the adapter is leaked without disposing, the adapter implements a Critical Finalizer, to ensure that the GCHandles are released, else we will permanently pin handles. The typical flow is to take one or many buffers; create and fill the neccessary unmanaged structures; pin memory; acquire the IntPtr handles; let the caller access the top-level IntPtr representing the SecureBufferDescriptor, to provide to the native APIs; wait for the caller to invoke the native API; wait for the caller to invoke our Dispose; marshal back any data from the native structures (buffer write counts); release all GCHandles to unpin memory. The total descriptor structure is as follows: |-- Descriptor handle |-- Array of buffers |-- Buffer 1 |-- Buffer 2 ... |-- Buffer N. Each object in that structure must be pinned and passed as an IntPtr to the native APIs. All this to pass what boils down to a List of byte arrays..
Inheritance: System.Runtime.ConstrainedExecution.CriticalFinalizerObject, IDisposable
ファイルを表示 Open project: datastax/csharp-driver-dse Class Usage Examples

Public Methods

Method Description
Dispose ( ) : void

Completes any buffer passing marshaling and releases all resources associated with the adapter.

SecureBufferAdapter ( IList buffers ) : System

Initializes the SecureBufferAdapter to carry a list of buffers to the native api.

SecureBufferAdapter ( SecureBuffer buffer ) : System

Initializes a SecureBufferAdapter to carry a single buffer to the native api.

Private Methods

Method Description
Dispose ( bool disposing ) : void

Method Details

Dispose() public method

Completes any buffer passing marshaling and releases all resources associated with the adapter.
public Dispose ( ) : void
return void

SecureBufferAdapter() public method

Initializes the SecureBufferAdapter to carry a list of buffers to the native api.
public SecureBufferAdapter ( IList buffers ) : System
buffers IList
return System

SecureBufferAdapter() public method

Initializes a SecureBufferAdapter to carry a single buffer to the native api.
public SecureBufferAdapter ( SecureBuffer buffer ) : System
buffer SecureBuffer
return System