My code for loading the file from resource is given below
void LoadFileInResource(int name, int type, DWORD& size, const char*& data)
{
HMODULE handle = ::GetModuleHandle(NULL);
HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name),MAKEINTRESOURCE(type));
HGLOBAL rcData = ::LoadResource(handle, rc);
size = ::SizeofResource(handle, rc);
data = static_cast<const char*>(::LockResource(rcData));
}
This code works perfect if its just an application. When the same code is used as a DLL, I am getting null in rc, which is post the FindResource.
I have defined the symbols in resourceful file as shows below:
#define TEXTFILE 256
#define IDR_MYTEXTFILE 105
Also the file which I need to add is defined in rc file:
IDR_MYTEXTFILE TEXTFILE "C:/Docs/Lib.XML"
As I mentioned earlier, this code is perfectly working when its an application, converting it to DLL is creating issue.
LoadFileInResource function is called as given below:
LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data);
Related
public class Watcher: Object
{
private int _fd;
private uint _watch;
private IOChannel _channel;
private uint8[] _buffer;
private int BUFFER_LENGTH;
public Watcher(string path, Linux.InotifyMaskFlags mask){
_buffer = new uint8[BUFFER_LENGTH];
//➔ Initialize notify subsystem
_fd = Linux.inotify_init();
if(_fd < 0){
error(#"Failed to initialize the notify subsystem: $(strerror(errno))");
}
//➔ actually adding abstraction to linux file descriptor
_channel = new IOChannel.unix_new(_fd);
//➔ watch the channel for given condition
//➔ IOCondition.IN => When the channel is ready for reading , IOCondition.HUP=>Hangup(Error)
_watch = _channel.add_watch(IOCondition.IN | IOCondition.HUP, onNotified);
if(_watch < 0){
error(#"Failed to add watch to channel");
}
//➔ Tell linux kernel to watch for any mask(for ex; access, modify) on a given filepath
var ok = Linux.inotify_add_watch(_fd, path, mask);
if(ok < 0){
error(#"Failed to add watch to path -- $path : $(strerror(errno))");
}
print(#"Watching for $(mask) on $path");
}
protected bool onNotified(IOChannel src, IOCondition condition)
{
if( (condition & IOCondition.HUP) == IOCondition.HUP){
error(#"Received hang up from inotify, can't get update");
}
if( (condition & IOCondition.IN) == IOCondition.IN){
var bytesRead = Posix.read(_fd, _buffer, BUFFER_LENGTH);
Linux.InotifyEvent *pevent = (Linux.InotifyEvent*) _buffer;
handleEvent(*pevent);
}
return true;
}
protected void handleEvent(Linux.InotifyEvent ev){
print("Access Detected!\n");
Posix.exit(0);
}
~Watcher(){
if(_watch != 0){
Source.remove(_watch);
}
if(_fd != -1){
Posix.close(_fd);
}
}
}
int main(string[] args) requires (args.length > 1)
{
var watcher = new Watcher(args[1], Linux.InotifyMaskFlags.ACCESS);
var loop = new MainLoop();
loop.run();
return 0;
}
The above code can be found on "Introducing Vala Programming - Michael Lauer"
Proof of failure:
Image displaying failure on access to the file being watched for access
Terminal 1:
./inotifyWatcher
Terminal 2:
cat
As soon as I access the file, segmentation fault occurs.
I have also tried using gdb for the cause of failure, but it's mostly cryptic for me. I am using parrot(debian/64-bit) on my machine. Also, I am new to this(stackoverflow, linux kernel program).
Vala source line numbers can be included in the binary when compiling with the --debug switch. The line numbers appear in the .debug_line DWARF section of an ELF binary:
valac --debug --pkg linux inotifyWatcher.vala
Run the binary using gdb in the first terminal:
gdb --args ./inotifyWatcher .
(gdb) run
The dot specifies to watch the current directory. Then when the current directory is access with a command like ls the watching program segmentation faults. The output from GDB is:
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401a86 in watcher_onNotified (self=0x412830, src=0x40e6e0, condition=G_IO_IN) at inotifyWatcher.vala:51
51 handleEvent(*pevent);
GDB includes the line number, 51, from the source file and shows the line.
So the problem is to do with reading from the file descriptor then passing the buffer to handleEvent. You probably want to check bytesRead is greater than zero and I'm not sure about the use of pointers in this example. Explicit pointers like that should rarely need to be used in Vala, it may require a change to the binding, e.g. using ref to modify the way the argument is passed.
I found a particular 100MB bin file (CarveObj_k5_rgbThreshold10_triangleCameraMatches.bin in minimal example), where cereal fails to load throwing exception "Failed to read 368 bytes from input stream! Read 288"
The respective 900MB XML file (CarveObj_k5_rgbThreshold10_triangleCameraMatches.xml in minimal example), built from the same data, loads normally.
The XML file was produced by
// {
// std::ofstream outFile(base + "_triangleCameraMatches.xml");
// cereal::XMLOutputArchive oarchive(outFile);
// oarchive(m_triangleCameraMatches);
// }
and the binary version was produced by
// {
// std::ofstream outFile(base + "_triangleCameraMatches.bin");
// cereal::BinaryOutputArchive oarchive(outFile);
// oarchive(m_triangleCameraMatches);
// }
Minimal example: https://www.dropbox.com/sh/fu9e8km0mwbhxvu/AAAfrbqn_9Tnokj4BVXB8miea?dl=0
Version of Cereal used: 1.3.0
MSVS 2017
Windows 10
Is this a bug? Am I missing something obvious?
Created a bug report in the meanwhile: https://github.com/USCiLab/cereal/issues/607
In this particular instance, the "failed to read from input stream exception" thrown from line 105 of binary.hpp arises because the ios::binary flag is missing from the ifstream constructor call. (This is needed, otherwise ifstream will attempt to interpret some of the file contents as carriage return and linefeed characters. See this question for more information.)
So the few lines of code in your minimal example that read from the .bin file should look like this:
vector<vector<float>> testInBinary;
{
std::ifstream is("CarveObj_k5_rgbThreshold10_triangleCameraMatches.bin", ios::binary);
cereal::BinaryInputArchive iarchive(is);
iarchive(testInBinary);
}
However, even after this is fixed there does also seem to be another problem with the data in that particular .bin file, as when I try to read it I get a different exception thrown, seemingly arising from an incorrectly encoded size value. I don't know if this is an artefact of copying to/from Dropbox though.
There doesn't seem to be a fundamental 100MB limit on Cereal binary files. The following minimal example creates a binary file of around 256MB and reads it back fine:
#include <iostream>
#include <fstream>
#include <vector>
#include <cereal/types/vector.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/archives/xml.hpp>
#include <cereal/archives/binary.hpp>
using namespace std;
int main(int argc, char* argv[])
{
vector<vector<double>> test;
test.resize(32768, vector<double>(1024, -1.2345));
{
std::ofstream outFile("test.bin");
cereal::BinaryOutputArchive oarchive(outFile, ios::binary);
oarchive(test);
}
vector<vector<double>> testInBinary;
{
std::ifstream is("test.bin", ios::binary);
cereal::BinaryInputArchive iarchive(is);
iarchive(testInBinary);
}
return 0;
}
It might be worth noting that in your example code on Dropbox, you're also missing the ios::binary flag on the ofstream constructor when you're writing the .bin file:
/// Produced by:
// {
// std::ofstream outFile(base + "_triangleCameraMatches.bin");
// cereal::BinaryOutputArchive oarchive(outFile);
// oarchive(m_triangleCameraMatches);
// }
It might be worth trying with the flag set. Hope some of this helps.
I am trying to build UWP app in C#. My app has a native library written in C++. Whenever the app tries to read a file in ApplicationData.LocalFolder, CreateFile2 api is returning ERROR_NOT_SUPPORTED_IN_APPCONTAINER. The file exists in the path specified to this api.
This is the sequence of operation in my app.
Launch app. App creates file & writes some data
Later on based on user input app tries to read data in this file
Step 1 is working fine. App is able to create the file & write data in it. Only when app tries to access it later on, does it get this error.
I get the path to ApplicationData.LocalFolder using
Windows.Storage.ApplicationData.Current.LocalFolder.Path
This is the actual path I see in the app:
C:\Users\xxxxx\AppData\Local\Packages\ac7a11e4-c1d6-4d37-b9eb-a4b0dc8f67b8_yyjvd81p022em\LocalState\temp.txt
My code is as below:
CREATEFILE2_EXTENDED_PARAMETERS ms_param = {0};
ms_param.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
ms_param.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
ms_param.dwFileFlags = FILE_FLAG_NO_BUFFERING;
ms_param.dwSecurityQosFlags = SECURITY_DELEGATION;
ms_param.lpSecurityAttributes = NULL;
ms_param.hTemplateFile = NULL;
g_hfile = CreateFile2(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, OPEN_EXISTING, &ms_param);
if (g_hfile == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
I tried CreateFile2 with both OPEN_EXISTING & OPEN_ALWAYS option for dwCreationDisposition parameter, but I see the same error in either case.
I had similar issue with CreateFile2 earlier. But that was an problem with my app & I have fixed that issue. This time though the file is available within the LocalFolder, still I get the error.
The problem here is related to the dwSecurityQosFlags you've set in CREATEFILE2_EXTENDED_PARAMETERS.
When called from a Windows Store app, CreateFile2 is simplified. You can open only files or directories inside the ApplicationData.LocalFolder or Package.InstalledLocation directories. You can't open named pipes or mailslots or create encrypted files (FILE_ATTRIBUTE_ENCRYPTED).
The dwSecurityQosFlags parameter specifies SQOS information. In Windows Stroe app, we can only set it to SECURITY_ANONYMOUS. Using other flag will raise ERROR_NOT_SUPPORTED_IN_APPCONTAINER exception. This indicates that it is not supported in UWP app.
Following is the code I used to test:
StorageFolder^ localFolder = ApplicationData::Current->LocalFolder;
String^ path = localFolder->Path;
path += L"\\MyFile.txt";
CREATEFILE2_EXTENDED_PARAMETERS ms_param = { 0 };
ms_param.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
ms_param.dwFileAttributes = FILE_ATTRIBUTE_READONLY;
ms_param.dwFileFlags = FILE_FLAG_NO_BUFFERING;
ms_param.dwSecurityQosFlags = SECURITY_ANONYMOUS;
ms_param.lpSecurityAttributes = NULL;
ms_param.hTemplateFile = NULL;
HANDLE g_hfile = CreateFile2(path->Data(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_EXISTING, &ms_param);
DWORD error = GetLastError();
If I don't have "MyFile.txt" under LocalFolder, I will get ERROR_FILE_NOT_FOUND exception, otherwise it will be ERROR_SUCCESS.
Now I'm developing a usb-serial application with its dll in Node.js.
This dll returns INVALID_HANDLE_VALUE, if it fails to open com port. So I want to handle the ret value in Node.js. In this case, How do I handle below ?
I'm not sure how do I compare the ret value and SlowBuffer.
DLL
#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1
typedef HANDLE (*OPEN)(int);
__declspec(dllexport) HANDLE opencom(int ncom)
Node.js with node-ffi
var ffi = require('ffi');
var lib = ffi.Library('serialmw.dll', {
'opencom' : ['pointer', ['int']]
});
var hcom = null;
hcom = lib.opencom(1);
console.log(hcom); // <SlowBuffer#0xFFFFFFFFFFFFFFFF >
A SlowBuffer is just a Buffer which is just a bunch of raw binary bytes. If you want to compare two Buffers byte-for-byte, you will have to use a for-loop or something like the buffertools' compare() with both Buffers.
In my node.js server I am downloading a file from another server. The downloaded file is a JPG image data encoded with Base64 two times, that means I have to decode it 2 times. Given is my code.
var base64DecodedFileData = new Buffer(file_data, 'base64').toString('binary');
var tmp = base64DecodedFileData.split("base64,");
var base64DecodedFileData = new Buffer(tmp[1], 'base64').toString('binary');
var file = fs.createWriteStream(file_path, stream_options);
file.write(base64DecodedFileData);
file.end();
I know my image data is valid the first time I have decoded it ( I have verified that data in online base64 decoders by decoding it second time and I have got the proper image), but when I decode it second time and create a file with this data. I am not getting a valid JPG file.
I have compared it with the actual image, start and ends of both files seems fine but something is not right in my constructed file. The constructed file is also of bigger in size than the original one.
PS: I am doing the split before decoding second time because the data after the first decoding starts with
data:; base64, DATASTARTS
Any thoughts.
Farrukh Arshad.
I have solve My problem. The problem seems to be in the decoding from the node.js so I have written a C++ addon to do the job. Here is the code. I am pretty much sure the problem will remain if we have image file encoded only once.
.js file
ModUtils.generateImageFromData(file_data, file_path);
c++ addon: This uses the base64 C++ encoder/decoder from
http://www.adp-gmbh.ch/cpp/common/base64.html
#define BUILDING_NODE_EXTENSION
#include <node.h>
#include <iostream>
#include <fstream>
#include "base64.h"
using namespace std;
using namespace v8;
static const std::string decoding_prefix =
"data:;base64,";
// --------------------------------------------------------
// Decode the image data and save it as image
// --------------------------------------------------------
Handle<Value> GenerateImageFromData(const Arguments& args) {
HandleScope scope;
// FIXME: Improve argument checking here.
// FIXME: Add error handling here.
if ( args.Length() < 2) return v8::Undefined();
Handle<Value> fileDataArg = args[0];
Handle<Value> filePathArg = args[1];
String::Utf8Value encodedData(fileDataArg);
String::Utf8Value filePath(filePathArg);
std::string std_FilePath = std::string(*filePath);
// We have received image data which is encoded with Base64 two times
// so we have to decode it twice.
std::string decoderParam = std::string(*encodedData);
std::string decodedString = base64_decode(decoderParam);
// After first decoding the data will also contains a encoding prefix like
// data:;base64,
// We have to remove this prefix to get actual encoded image data.
std::string second_pass = decodedString.substr(decoding_prefix.length(), (decodedString.length() - decoding_prefix.length()));
std::string imageData = base64_decode(second_pass);
// Write image to file
ofstream image;
image.open(std_FilePath.c_str());
image << imageData;
image.close();
return scope.Close(String::New(" "));
//return scope.Close(decoded);
}
void Init(Handle<Object> target) {
// Register all functions here
target->Set(String::NewSymbol("generateImageFromData"),
FunctionTemplate::New(GenerateImageFromData)->GetFunction());
}
NODE_MODULE(modutils, Init);
Hope it will help for someone else.