I tried to find working solution on my qestion, but not found.
I want to "connect" managed C# .NET code with native C++ code (DLL). My C++ returns unmanaged BYTE* pointer and count of elements.
How to initialize new array<Byte>^ from BYTE* without loop? Because it may be to 5 Megabytes. (Encrypting data)
Help if you can please.
EDIT:
With loop it works:
array<Byte>^ a = gcnew array<Byte>(resultDataSize);
for (int i = 0; i < resultDataSize; i++)
{
a[i] = resultData[i];
}
But I'd like get something like:
a = new array<Byte>(resultData, resultDataSize);
EDIT 2:
Now in my C++ i have function:
void Decrypt(BYTE* dataToDecrypt, DWORD dataToDecryptLength, wchar_t* senderName, wchar_t* receiverName, BYTE** result, DWORD* resultSize)
{
...
*result = main.Data;
*resultSize = main.Length;
}
Where main is a class with BYTE* Data and DWORD Length and other functions.
In my CLR:
array<Byte>^ Decrypt(array<Byte>^ dataToDecrypt, String^ senderName, String^ receiverName)
{
...
BYTE* resultData = nullptr;
DWORD resultDataSize = 0;
// Call my c++
DecryptFunction(dataToDecryptBytes, dataToDecrypt->Length, sender, receiver, &resultData, &resultDataSize);
array<Byte>^ result = gcnew array<Byte>(resultDataSize);
for (int i = 0; i < resultDataSize; i++)
{
result[i] = resultData[i];
}
....
return result;
}
In C#:
byte[] data = ...;
...
byte[] decrypted = provider.Decrypt(data, "user1", "user2");
...
Related
I'm using openssl library to implement an ETSI standard and, more specifically, to realize communications with a PKI.
To do that I must use the ECIES encryption scheme but it isn't implemented in openssl.
I have found this piece of code here in the crypto++ google group:
int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group((EC_KEY*)m_pPrivKey));
EC_KEY* temp_key = EC_KEY_new_by_curve_name(curve_id);
size_t uPubLen = i2o_ECPublicKey((EC_KEY*)m_pPrivKey, NULL);
o2i_ECPublicKey(&temp_key, (const byte**)&pCiphertext, uPubLen); // warnign this moves the pCiphertext pointer
uCiphertextSize -= uPubLen;
size_t SecLen = (EC_GROUP_get_degree(EC_KEY_get0_group((EC_KEY*)m_pPrivKey)) + 7) / 8;
byte* pSec = new byte[SecLen];
int ret = ECDH_compute_key(pSec, SecLen, EC_KEY_get0_public_key(temp_key), (EC_KEY*)m_pPrivKey, NULL);
ASSERT(ret == SecLen);
EC_KEY_free(temp_key);
CHashFunction GenFx(CHashFunction::eSHA1); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
uPlaintextSize = (uCiphertextSize > GenFx.GetSize()) ? (uCiphertextSize - GenFx.GetSize()) : 0;
int mac_key_len = 16;
int GenLen = uPlaintextSize + mac_key_len;
uint32 counter = 1;
CBuffer GenHash;
while(GenHash.GetSize() < GenLen)
{
GenFx.Add(pSec, SecLen);
CBuffer Buff;
Buff.WriteValue<uint32>(counter++, true);
GenFx.Add(&Buff);
GenFx.Finish();
GenHash.AppendData(GenFx.GetKey(), GenFx.GetSize());
GenFx.Reset();
}
GenHash.SetSize(GenLen); // truncate
delete pSec;
byte* key = GenHash.GetBuffer();
byte* macKey = key + uPlaintextSize;
unsigned char* result;
size_t mac_len = uCiphertextSize - uPlaintextSize;
ASSERT(mac_len == 20);
byte* mac_result = new byte[mac_len];
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, macKey, mac_key_len, EVP_sha1(), NULL);
HMAC_Update(&ctx, pCiphertext, uPlaintextSize);
HMAC_Final(&ctx, mac_result, &mac_len);
HMAC_CTX_cleanup(&ctx);
Ret = memcmp(pCiphertext + uPlaintextSize, mac_result, mac_len) == 0 ? 1 : 0;
delete mac_result;
ASSERT(pPlaintext == NULL);
pPlaintext = new byte[uPlaintextSize];
for(int i=0; i < uPlaintextSize; i++)
pPlaintext[i] = pCiphertext[i] ^ key[i];
But I am not sure that it works correctly and I don't know how use this piece of code.
Have anyone already implemented this scheme?
I am trying to initialize the Vulkan API.
The problem I am having is that I get an access violation error after I call vkCreateInstance and I think the problem comes from the extension and layer lists.
I am using a char buff[20][256] to transfer them from strings to the structure for the API call, and the layer and extension names I see in the debugger(3 extensions and 15 layers) are all a lot shorter than 256 characters and are all null terminated.
There is no buffer overflow with the extension or layer names, yet it crashes.
The layer and extension lists of strings I received trough using vkEnumerateInstanceExtensionProperties and vkEnumerateInstanceLayerProperties beforehand and are all valid null-terminated strings like "VK_KHR_surface", etc.
Is it possible that even tho it says I support some extensions, that I don't really support them and the API is crashing when it's trying to initialize an extension I don't support?
void InitializeInstance(void** instance, const vector<string>& layers, const vector<string>& extensions)
{
VkApplicationInfo applicationInfo;
VkInstanceCreateInfo instanceInfo;
VkInstance* instanceOut = (VkInstance*)instance;
applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
applicationInfo.pNext = nullptr;
applicationInfo.pApplicationName = "MyApp";
applicationInfo.pEngineName = "MyEngine";
applicationInfo.engineVersion = 1;
applicationInfo.apiVersion = VK_API_VERSION_1_0;
instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
instanceInfo.pNext = null;
instanceInfo.flags = 0;
instanceInfo.pApplicationInfo = &applicationInfo;
char buffLayer[20][256];
char buffExt[20][256];
if(!layers.empty())
{
instanceInfo.enabledLayerCount = layers.size();
for(int i = 0; i < layers.size(); i++)
{
strcpy(buffLayer[i], layers[i].c_str());
}
instanceInfo.ppEnabledLayerNames = (char**)buffLayer;
}
else
{
instanceInfo.enabledLayerCount = 0;
instanceInfo.ppEnabledLayerNames = nullptr;
}
if(!extensions.empty())
{
instanceInfo.enabledExtensionCount = extensions.size();
for(int i = 0; i < extensions.size(); i++)
{
strcpy(buffExt[i], extensions[i].c_str());
}
instanceInfo.ppEnabledExtensionNames = (char**)buffExt;
}
else
{
instanceInfo.enabledExtensionCount = 0;
instanceInfo.ppEnabledExtensionNames = nullptr;
}
vkCreateInstance(&instanceInfo, nullptr, instanceOut);
}
When I have only 0 extensions AND 0 layers, it creates successfully. If any of them is not 0, it crashes.
char buffLayer[20][256];
instanceInfo.ppEnabledLayerNames = (char**)buffLayer;
ppEnabledLayerNames is supposed to be an array of pointers to character arrays. But you're passing it a 2D array of characters, which is effectively just an array of 20*256 characters.
If you're on a machine with 32-bit pointers, the driver is going to take the first four bytes in buffLayer and treat them as a pointer to a character array. But you've just stored the first four characters of a layer name there, and 'VK_K' is probably not going to be a valid pointer value :). So the loader will crash when trying to dereference that invalid pointer.
Probably the simplest change would be to add:
char* layerNames[20];
for (int i = 0; i < 20; i++)
layerNames[i] = &buffLayer[i][0];
and pass layerNames as ppEnabledLayerNames.
To process my previewFrames of my camera in OpenCV, I need access to the raw Pixel data / bytes. So, there is the new SoftwareBitmap, which should exactly provide this.
There is an example for c#, but in visual c++ I can't get the IMemoryBufferByteAccess (see remarks) Interface working.
Code with Exceptions:
// Capture the preview frame
return create_task(_mediaCapture->GetPreviewFrameAsync(videoFrame))
.then([this](VideoFrame^ currentFrame)
{
// Collect the resulting frame
auto previewFrame = currentFrame->SoftwareBitmap;
auto buffer = previewFrame->LockBuffer(Windows::Graphics::Imaging::BitmapBufferAccessMode::ReadWrite);
auto reference = buffer->CreateReference();
// Get a pointer to the pixel buffer
byte* pData = nullptr;
UINT capacity = 0;
// Obtain ByteAccess
ComPtr<IUnknown> inspectable = reinterpret_cast<IUnknown*>(buffer);
// Query the IBufferByteAccess interface.
Microsoft::WRL::ComPtr<IMemoryBufferByteAccess> bufferByteAccess;
ThrowIfFailed(inspectable.As(&bufferByteAccess)); // ERROR ---> Throws HRESULT = E_NOINTERFACE
// Retrieve the buffer data.
ThrowIfFailed(bufferByteAccess->GetBuffer(_Out_ &pData, _Out_ &capacity)); // ERROR ---> Throws HRESULT = E_NOINTERFACE, because bufferByteAccess is null
I tried this too:
HRESULT hr = ((IMemoryBufferByteAccess*)reference)->GetBuffer(&pData, &capacity);
HRESULT is ok, but I can't access pData -> Access Violation reading Memory.
Thanks for your help.
You should use reference instead of buffer in reinterpret_cast.
#include "pch.h"
#include <wrl\wrappers\corewrappers.h>
#include <wrl\client.h>
MIDL_INTERFACE("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d")
IMemoryBufferByteAccess : IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetBuffer(
BYTE **value,
UINT32 *capacity
);
};
auto previewFrame = currentFrame->SoftwareBitmap;
auto buffer = previewFrame->LockBuffer(BitmapBufferAccessMode::ReadWrite);
auto reference = buffer->CreateReference();
ComPtr<IMemoryBufferByteAccess> bufferByteAccess;
HRESULT result = reinterpret_cast<IInspectable*>(reference)->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
if (result == S_OK)
{
WriteLine("Get interface successfully");
BYTE* data = nullptr;
UINT32 capacity = 0;
result = bufferByteAccess->GetBuffer(&data, &capacity);
if (result == S_OK)
{
WriteLine("get data access successfully, capacity: " + capacity);
}
}
Based on answer from #jeffrey-chen and example from #kennykerr, I've assembled a tiny bit cleaner solution:
#include <wrl/client.h>
// other includes, as required by your project
MIDL_INTERFACE("5b0d3235-4dba-4d44-865e-8f1d0e4fd04d")
IMemoryBufferByteAccess : ::IUnknown
{
virtual HRESULT __stdcall GetBuffer(BYTE **value, UINT32 *capacity) = 0;
};
// your code:
auto previewFrame = currentFrame->SoftwareBitmap;
auto buffer = previewFrame->LockBuffer(BitmapBufferAccessMode::ReadWrite);
auto bufferByteAccess= buffer->CreateReference().as<IMemoryBufferByteAccess>();
WriteLine("Get interface successfully"); // otherwise - exception is thrown
BYTE* data = nullptr;
UINT32 capacity = 0;
winrt::check_hresult(bufferByteAccess->GetBuffer(&data, &capacity));
WriteLine("get data access successfully, capacity: " + capacity);
I'm currently accessing the raw unsigned char* data from each frame I obtain on a MediaFrameReader::FrameArrived event without using WRL and COM...
Here it is how:
void MainPage::OnFrameArrived(MediaFrameReader ^reader, MediaFrameArrivedEventArgs ^args)
{
MediaFrameReference ^mfr = reader->TryAcquireLatestFrame();
VideoMediaFrame ^vmf = mfr->VideoMediaFrame;
VideoFrame ^vf = vmf->GetVideoFrame();
SoftwareBitmap ^sb = vf->SoftwareBitmap;
Buffer ^buff = ref new Buffer(sb->PixelHeight * sb->PixelWidth * 2);
sb->CopyToBuffer(buff);
DataReader ^dataReader = DataReader::FromBuffer(buffer);
Platform::Array<unsigned char, 1> ^arr = ref new Platform::Array<unsigned char, 1>(buffer->Length);
dataReader->ReadBytes(arr);
// here arr->Data is a pointer to the raw pixel data
}
NOTE: The MediaCapture object needs to be configured with MediaCaptureMemoryPreference::Cpu in order to have a valid SoftwareBitmap
Hope the above helps someone
I am using Silverlight4 with java webervices in jsp page. I want to save an image to the server so trying to do this with java webservice. I am using below lines of code but output is damaged. I dont understand why. Please help me. This is really important for me. When i try to open 3mb jpeg file contains "Windows Photo Viewer cant open this picture because file appears to be damaged, corrupted or is too large."
Client Side COde
WriteableBitmap wb = new WriteableBitmap(bitmapImage);
byte[] bb = ToByteArray(wb);
public byte[] ToByteArray(WriteableBitmap bmp)
{
int[] p = bmp.Pixels;
int len = p.Length * 4;
byte[] result = new byte[len]; // ARGB
Buffer.BlockCopy(p, 0, result, 0, len);
return result;
}
WebService Code
#WebMethod(operationName = "saveImage")
public Boolean saveImage(#WebParam(name = "img")
byte[] img, #WebParam(name = "path")
String path) {
try{
FileOutputStream fos = new FileOutputStream("C:\\Users\\TheIntersect\\Desktop\\sharp_serializer_dll\\saved.jpg");
fos.write(img);
fos.close();
return true;
}
catch(Exception e){
return false;
}
}
I found my answer on forums.silverlight.net
It is very interesting when i try to call ReadFully(Stream) just after the Stream definition it works but when i call 10 lines of code later it returns all 0.
FUnction
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[input.Length];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
Fail Code
using (Stream str = opd.File.OpenRead())
{
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(str);
image.Tag = bitmapImage.UriSource.ToString();
image.Source = bitmapImage;
image.Width = width;
image.Height = height;
image.Stretch = Stretch.Uniform;
container.Child = image;
rtb.Selection.Insert(container);
ServiceReference1.webWordWebServiceClient s = new ServiceReference1.webWordWebServiceClient();
byte[] bb = ReadFully(str);
s.saveImageCompleted += new EventHandler<ServiceReference1.saveImageCompletedEventArgs>(s_saveImageCompleted);
s.saveImageAsync(bb, "gungorrrr");
}
Successfull Code
using (Stream str = opd.File.OpenRead())
{
byte[] bb = ReadFully(str);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(str);
image.Tag = bitmapImage.UriSource.ToString();
image.Source = bitmapImage;
image.Width = width;
image.Height = height;
image.Stretch = Stretch.Uniform;
container.Child = image;
rtb.Selection.Insert(container);
ServiceReference1.webWordWebServiceClient s = new ServiceReference1.webWordWebServiceClient();
(bitmapImage);
s.saveImageCompleted += new EventHandler<ServiceReference1.saveImageCompletedEventArgs>(s_saveImageCompleted);
s.saveImageAsync(bb, "gungorrrr");
}
Link: http://forums.silverlight.net/forums/p/234126/576070.aspx#576070
** This is still unsolved **
I'm trying to call an ObjC/C++ function code from C#. I've done my best to follow different example code, the latest being mostly from:
http://msdn.microsoft.com/en-us/library/ms146631(v=VS.80).aspx
This is for an iPhone/MonoTouch environment, so I'm not sure I've done everything I should. The bytes appear to be ok in the ObjC/C++ function, but the byte array I get back into C# ends up containing 0 0 0 0 0 0 etc.
** Update **
Corrected for loop initializer, and now its giving a EXC_BAD_ACCESS signal on the *returnbytes[i] = bytes[i]; line.
C# code:
[DllImport ("__Internal")]
private static extern int _getjpeg(string url,ref IntPtr thebytes);
void somefunction(string image_id) {
int maxsize = 50000;
byte[] thebytes = new byte[maxsize];
IntPtr byteptr = Marshal.AllocHGlobal(maxsize);
int imagesize = _getjpeg(image_id,ref byteptr);
Debug.Log("Getting _picturesize()... "+ image_id);
int picsize = _picturesize();
Marshal.Copy(byteptr,thebytes,0,picsize);
var texture = new Texture2D(1,1);
string bytedebug = "";
for (int i=5000 ; i < 5020 ; i++)
bytedebug+=thebytes[i] + " ";
Debug.Log("Bytes length is "+imagesize);
Debug.Log("Bytes content is "+bytedebug);
}
C++/ObjC code:
int _getjpeg(const char* url,unsigned char** returnbytes) {
ALAsset* asset = [_pictures objectForKey:[NSString stringWithUTF8String:url]];
if(asset != NULL)
NSLog(#"_getjpeg() found URL: %#",[NSString stringWithUTF8String: url]);
else {
NSLog(#"_getjpeg() could not find URL: %#",[NSString stringWithUTF8String: url]);
return NULL;
}
UIImage *image = [UIImage imageWithCGImage: [asset thumbnail]];
NSData* pictureData = UIImageJPEGRepresentation (image, 1.0);
picturesize = (int)[pictureData length];
unsigned char* bytes = (unsigned char*)[pictureData bytes];
// This test does not give EXC_BAD_ACCESS
*returnbytes[5] = (unsigned int)3;
// updated below initializer in below for loop according to Eikos suggestion
for(int i=0 ; i < picturesize ; i++) {
// below lines gives EXC_BAD_ACCESS
*returnbytes[i] = bytes[i];
}
NSString* debugstr = [NSString string];
for(int i=5000; i < 5020 ; i++) {
unsigned char byteint = bytes[i];
debugstr = [debugstr stringByAppendingString:[NSString stringWithFormat:#"%i ",byteint]];
}
NSLog(#"bytes %s",[debugstr UTF8String]);
return picturesize;
}
Thanks
Keep in mind that the JPGRepresentation is probably not exactly the same as you put into it, so the length may differ.
In
for(int i;i < picturesize;i++) {
// *** Not sure I'm doing this correctly ***
*returnbytes[i] = bytes[i];
}
you forget to initialize i, so it might start with a random value which is bigger than picturesize, so the loop won't run at all.
You want unsigned char*, not **. You are passing a pointer in that is already allocated. A ** is for when you are passing in a pointer to variable that is itself a pointer to data: i.e. when the callee will allocate the memory and the caller wants to know about it.
Just pass in unsigned char* and then use
returnbytes[i] = bytes[i];
Alternatively, allocate in the calee and use an out, not a ref.