The following code will always throw
UnuthorizedAccessException (MemoryStream's internal buffer cannot be accessed.)
byte[] buf1 = { 2, 3, 5, 7, 11 };
var ms = new MemoryStream(buf1);
byte[] buf2 = ms.GetBuffer(); // exception will be thrown here
This is in a plain old console app and I'm running as an admin. I can't imagine a more privileged setting I could give this code. So why can't I get at this buffer? (And if nobody can, what's the point of the GetBuffer method?)
The MSDN docs say
To create a MemoryStream instance with
a publicly visible buffer, use
MemoryStream,
MemoryStream(array[], Int32,
Int32, Boolean, Boolean), or
MemoryStream(Int32).
Am I not doing that?
P.S. I don't want to use ToArray() because that makes a copy.
Here is the documentation for MemoryStream(byte[]) constructor that you're using. It specifically says:
This constructor does not expose the underlying stream. GetBuffer throws UnauthorizedAccessException.
You should use this constructor instead, with publiclyVisible = true.
Check the docs for MemoryStream.GetBuffer()
To create a MemoryStream instance with
a publicly visible buffer, use
MemoryStream, MemoryStream(Byte[],
Int32, Int32, Boolean, Boolean), or
MemoryStream(Int32). If the current
stream is resizable, two calls to this
method do not return the same array if
the underlying byte array is resized
between calls. For additional
information, see Capacity.
You need to use a different constructor.
To add to what others have already put in here...
Another way to get your code to work is change your code to the following line.
byte[] buf2 = ms.ToArray();
You appear to be using MemoryStream(array[]) which does not match any of the three versions mentioned in the docs.
Related
Given the following code how can I convert the v8::Local<v8::Value> into a uint32_t. Or other types based on the Is* method?
v8::Local<v8::Value> value;
v8::Local<v8::Context> context = v8::Context::New(v8::Isolate::GetCurrent());
if(value->IsUint32()) {
v8::MaybeLocal<Int32> maybeLocal = value->Uint32Value(context);
uint32_t i = maybeLocal;
}
Your posted code doesn't work because value->Uint32Value(context) doesn't return a v8::MaybeLocal<Int32>. C++ types are your friend (just like TypeScript)!
You have two possibilities:
(1) You can use Value::Uint32Value(...) which returns a Maybe<uint32_t>. Since you already checked that value->IsUint32(), this conversion cannot fail, so you can extract the uint32_t wrapped in the Maybe using Maybe::ToChecked().
(2) You can use Value::ToUint32(...) which returns a MaybeLocal<Uint32>. Again, since you already checked that value->IsUint32(), that cannot fail, so you can get a Local<Uint32> via MaybeLocal::ToLocalChecked(), and then simply use -> syntax to call the wrapped Uint32's Value() method, which gives a uint32_t.
If you're only interested in the final uint32_t (and not in the intermediate Local<Uint32>, which you could pass back to JavaScript), then option (1) will be slightly more efficient.
Note that IsUint32() will say false for objects like {valueOf: () => 42; }. If you want to handle such objects, then attempt the conversion, and handle failures, e.g.:
Maybe<uint32_t> maybe_uint = value->Uint32Value(context);
if (maybe_uint.IsJust()) {
uint32_t i = maybe_uint.FromJust();
} else {
// Conversion failed. Maybe it threw an exception (use a `v8::TryCatch` to catch it), or maybe the object wasn't convertible to a uint32.
// Handle that somehow.
}
Also, note that most of these concepts are illustrated in V8's samples and API tests. Reading comments and implementations in the API headers themselves also provides a lot of insight.
Final note: you'll probably want to track the current context you're using, rather than creating a fresh context every time you need one.
I use the MediaFoundation API to get samples from the camera and faced such a problem.
Сreating an source reader object (for example, with the function MFCreateSourceReaderFromMediaSource), we can use IMFSourceReader in asynchronous mode. For this, we must set the MF_SOURCE_READER_ASYNC_CALLBACK attribute on the attribute store. This attribute store is then passed to MFCreateSourceReaderFromMediaSource function.
HRESULT hr = S_OK;
IMFAttributes *pAttributes = NULL;
hr = MFCreateAttributes(&pAttributes, 1);
// set our callback
hr = pAttributes->SetUnknown(MF_SOURCE_READER_ASYNC_CALLBACK, pCallback);
// pass attributes and create source reader
hr = MFCreateSourceReaderFromMediaSource(pMediaSource, pAttributes, ppSourceReader);
Logically, the parameters we set when creating the IMFSourceReader should be stored somewhere in it.
Actually, the question. Is it possible to get the IMFAttributes of IMFSourceReader object (especially value of MF_SOURCE_READER_ASYNC_CALLBACK attribute), which we passed in MFCreateSourceReaderFromMediaSource?
I tried to get them with QueryInterface
pSourceReader->QueryInterface(IID_IMFAttributes, (void**)&pAttributes);
but the return value says that the interface is not supported.
Media source object returns attributes but does not contain the necessary attributes.
I think it is possible to get what I am looking for using IMFSourceReader::GetServiceForStream method, but I don't know what service is needed.
Thanks in advance, I will be glad of any help.
There is no defined method to read the value of callback back.
What is the idiomatic way to deal with unsized arrays in Go? I'm working on the ETW wrappers and the TdhGetEventInformation function fills in the provided memory buffer with event information. The event metadata is represented by TRACE_EVENT_INFO structure, which has an array member declared as:
EVENT_PROPERTY_INFO EventPropertyInfoArray[ANYSIZE_ARRAY];
I'm calling the TdhGetEventInformation function in a way that the provided buffer has enough space to populate event properties array:
var bufferSize uint32 = 4096
buffer := make([]byte, bufferSize)
tdhGetEventInformation.Call(
uintptr(unsafe.Pointer(eventRecord)),
0, 0,
uintptr(unsafe.Pointer(&buffer[0])),
uintptr(unsafe.Pointer(&bufferSize)),
)
However, since I'm tempting to model the Go counterpart struct with EventPropertyInfoArray field as
EventPropertyInfoArray [1]EventPropertyInfo
the compiler is not able to re dimension the array according to the number of available properties for each event, so I end up with one-array item.
Do you have any smart ideas on how handle this edge case?
Thanks in advance
So you want a variable sized array in Go? Use a slice?
EventPropertyInfoArray [1]EventPropertyInfo
Would be
EventPropertyInfoArray []EventPropertyInfo
If you have a rough idea of a maximum it could hold you could make an array using make something like this, but this wouldn't help you out in declaring a struct:
EventPropertyInfoArray = make([]EventPropertyInfo, len, capacity)
After lots of trial and error, I managed to get the right slice from the backing array through standard technique for turning arrays into slices:
properties := (*[1 << 30]EventPropertyInfo)(unsafe.Pointer(&trace.EventPropertyInfoArray[0]))[:trace.PropertyCount:trace.PropertyCount]
My application needs to manage a few of unicode strings (<10). The content of these strings is dynamic and can change through application run. To store strings I am using objects of type UnicodeString.
One approach to solving this problem is to create as many member variables as there are unicode strings like for example:
UnicodeString str1;
UnicodeString str2;
...
UnicodeString strN;
This solutions is pretty simple at least at first glance. But there is problem with scalability. If the number of string would rise in the future, we risk creating hard-to-read bigg code. So I thougth creating something like this for managing strings:
std::map<HWND, UnicodeString> file_names; ///< member variable of form TForm1
Every string is connected with some edit box. I can use window handle as key to dictionary.
What I don't understand - who should be responsible for allocating and deallocating space for storing unicode string in this case? Lets say I create UnicodeString variable on local stack:
void TForm1::ProcessFile(TEdit *edit_box)
{
UnicodeString str = "C:\\Temp\\ws.gdb";
file_name[edit_box->Handle] = str;
}
Will the content of str variable survive end of member function ProcessFile?
The memory storage of a UnicodeString is reference counted and managed by the RTL for you. You do not need to worry about deallocating it yourself, unless you allocate the UnicodeString itself using the new operator. In your code snippet, the str variable will be freed when ProcessFile() exits, but its contents will survive because file_name still has an active reference to it.
Do not use an HWND as the key for your std::map. The window managed by the TWinControl::Handle property is dynamic and can change value during the lifetime of the app. You can, however, use the TEdit* pointer instead:
std::map<TEdit*, UnicodeString> file_names;
void TForm1::ProcessFile(TEdit *edit_box)
{
UnicodeString str = "C:\\Temp\\ws.gdb";
file_names[edit_box] = str;
}
Lets say I have this class in foobar-shared.lib:
class FooBar {
std::string m_helloWorld;
}
And I have a call in foobar-from.exe using SendCopyData like so:
extern HWND hMainWnd; // foobar-from.exe
{
FooBar fooBar;
HWND hWnd = FindAppWindow(); // foobar-to.exe
COPYDATASTRUCT cds;
cds.dwData = ('f'|('o'<<8)|('o'<<16));
cds.cbData = sizeof(FooBar);
cds.lpData = (LPVOID)fooBar;
SendCopyData(hWnd, (WPARAM)hMainWnd, (LPARAM)&cds);
}
When from a foobar-to.exe, I handle OnCopyData:
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) {
if (pCopyDataStruct->dwData==('f'|('o'<<8)|('o'<<16))) {
FooBar fooBar = *(FooBar *)pCopyDataStruct->lpData;
}
}
This worked fine when FooBar was a struct, but now that it's a class I get this error:
First-chance exception at 0x0064ef81 in foobar-to.exe: 0xC0000005:
Access violation reading location 0x0231dd7c.
I assumed originally that this was because my fooBar instance is on the stack, so I tried moving it to the heap but got a slightly different error (I can post the result here if necessary).
According to MSDN, "The data being passed must not contain pointers or other references to objects not accessible to the application receiving the data." so I suspect that this only possible with struct data. Am I correct?
you are both correct and incorrect.
your problem here is that you don't know the implementation details of std::string. unfortunately, it seems this (standard) class uses a dynamicaly allocated buffer to store its character data. that's why WM_COPYDATA doesn't work with it.
but if your class does not contain a pointer to any external data, as suggested in the documentation, then it would be perfectly valid to copy it using WM_COPYDATA. unfortunately, this greatly limits the possible types for members of your class.
(think WM_COPYDATA is like sending data over a network: you should take care of serializing your class before sending it out in the wild...)