once my opencl kernel file exceeds a certain length, it is not correctly loaded anymore. The program build log (clBuildProgram) returns lots of errors, where it seems like there are cuts in the middle of a line (example int test; -> error unknown identifier 't').
Here is the function with which I load the program source:
char * load_program_source(const char *filename)
{
FILE *fh;
char* source;
long lSize;
fh = fopen(filename, "r");
if (fh == 0)
return 0;
//Get Filesize
fseek(fh,0,SEEK_END);
lSize = ftell(fh);
rewind(fh);
source = (char *) malloc(lSize);
memset(source,'\0',lSize);
fread(source, sizeof(char), lSize, fh);
return source;
}
And here is the code where the program is build:
//load program from file, compile kernels
cl_program program[1];
cl_kernel kernel[13];
const char * filename = "addKernel.c";
char *program_source = load_program_source(filename);
program[0] = clCreateProgramWithSource(context, 1, (const char**)&program_source,
NULL, &err);
if (err == CL_OUT_OF_HOST_MEMORY){
textBox1->Text += "Error: out of Host Memory!\r\n";
}
else if (err == CL_INVALID_CONTEXT){
textBox1->Text += "Error: invalid Context!\r\n";
}
else if (err == CL_INVALID_VALUE){
textBox1->Text += "Error: invalid Value!\r\n";
}
err = clBuildProgram(program[0], 0, NULL, NULL, NULL, NULL);
textBox1->Text += "Program build error: " + err + "\r\n";
cl_build_status status;
size_t logSize;
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &status, NULL);
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &logSize);
char* programLog;
programLog = (char*)calloc(logSize + 1, sizeof(char));
clGetProgramBuildInfo(program[0], deviceID[0], CL_PROGRAM_BUILD_LOG, logSize + 1, programLog, NULL);
std::string tmp = std::string(programLog);
this->textBox1->Text += "Program build info: error=" + err + ", status=" + status + ", programLog:\r\n" + gcnew System::String(tmp.c_str()) + "\r\n" + "In case of an error please make sure that openCL has been initialized\r\n";
I would be happy if you cound help me out!
Try following code. If it doesn't help, attach your kernel source
File reading:
static char* Read_Source_File(const char *filename)
{
long int
size = 0,
res = 0;
char *src = NULL;
FILE *file = fopen(filename, "rb");
if (!file) return NULL;
if (fseek(file, 0, SEEK_END))
{
fclose(file);
return NULL;
}
size = ftell(file);
if (size == 0)
{
fclose(file);
return NULL;
}
rewind(file);
src = (char *)calloc(size + 1, sizeof(char));
if (!src)
{
src = NULL;
fclose(file);
return src;
}
res = fread(src, 1, sizeof(char) * size, file);
if (res != sizeof(char) * size)
{
fclose(file);
free(src);
return src;
}
src[size] = '\0'; /* NULL terminated */
fclose(file);
return src;
}
Programm building:
cl_int ret;
program = clCreateProgramWithSource(
context, 1, (const char**)&src_file, NULL, &ret);
if(ret != CL_SUCCESS){
fprintf(stderr, "Error with code %d happened.\n", ret);
}
// Warnings will be treated like errors, this is useful for debug
char build_params[] = {"-Werror"};
ret = clBuildProgram(program, 0, NULL, build_params, NULL, NULL);
if (ret != CL_SUCCESS)
{
size_t len = 0;
char *buffer;
clGetProgramBuildInfo(program,
device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
buffer = calloc(len, sizeof(char));
clGetProgramBuildInfo(program,
device_id, CL_PROGRAM_BUILD_LOG, len, buffer, NULL);
fprintf(stderr, "%s\n", buffer);
free(buffer);
}
Related
I wrote this code to encrypt a file in python with AES and now I send this file over HTTP to a client in C++ using Windows OS. And I want to decrypt this file on the C++ client, but I haven't found any libraries/usefull code to help me with this manner.
Here is the code for python:
def derive_key_and_iv(password, salt, key_length, iv_length):
d = d_i = b''
while len(d) < key_length + iv_length:
d_i = md5(d_i + str.encode(password) + salt).digest()
d += d_i
return d[:key_length], d[key_length:key_length + iv_length]
def encrypt(in_file, out_file, password, key_length=32):
bs = AES.block_size # 16 bytes
salt = urandom(bs)
key, iv = derive_key_and_iv(password, salt, key_length, bs)
cipher = AES.new(key, AES.MODE_CBC, iv)
out_file.write(salt)
finished = False
while not finished:
chunk = in_file.read(1024 * bs)
if len(chunk) == 0 or len(chunk) % bs != 0: #final block
padding_length = (bs - len(chunk) % bs) or bs
chunk += str.encode(padding_length * chr(padding_length))
finished = True
out_file.write(cipher.encrypt(chunk))
password = 'ABCDE' # some password
with open("some_file.bin", "rb") as in_file, open("enc_some_file.enc", "wb") as out_file:
encrypt(in_file, out_file, password)
Update:
I am updating this question regarding my try with WinCrypt. I am trying to compile from VS CODE using MSYS64 g++ compiler on Windows. Here is the code that I am trying to run. I also have some additional libraries to help me with the client-server part, such as libcurlpp and libcurl.
#include <string>
#include <sstream>
#include <conio.h>
#include <iostream>
#include <fstream>
#include <curlpp/cURLpp.hpp>
#include <curlpp/Easy.hpp>
#include <curlpp/Options.hpp>
#include <wincrypt.h>
#include <windows.h>
#define AES_KEY_SIZE 32
#define IN_CHUNK_SIZE (AES_KEY_SIZE * 10) // a buffer must be a multiple of the key size
#define OUT_CHUNK_SIZE (IN_CHUNK_SIZE * 2) // an output buffer (for encryption) must be twice as big
using namespace std;
string host = ""; #some host
int main(void)
{
curlpp::Easy req;
req.setOpt(new curlpp::options::Url(host));
ofstream myfile;
myfile.open("enc_calc.enc", ios::out | ios::binary);
myfile << req;
myfile.close();
getch();
wchar_t *in_file = (wchar_t *)"enc_calc.enc";
wchar_t *out_file = (wchar_t *)"calc.dll";
wchar_t default_key[] = L"ABCDE";
wchar_t *key_str = default_key;
const size_t len = lstrlenW(key_str);
const size_t key_size = len * sizeof(key_str[0]);
const wchar_t *filename1 = (const wchar_t *)"enc_calc.enc";
const wchar_t *filename2 = (const wchar_t *)"calc.dll";
HANDLE hInpFile = CreateFileW(filename1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (hInpFile == INVALID_HANDLE_VALUE) {
printf("Cannot open input file!\n");
system("pause");
return (-1);
}
HANDLE hOutFile = CreateFileW(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hOutFile == INVALID_HANDLE_VALUE) {
printf("Cannot open output file!\n");
system("pause");
return (-1);
}
DWORD dwStatus = 0;
BOOL bResult = FALSE;
wchar_t info[] = L"Microsoft Enhanced RSA and AES Cryptographic Provider";
HCRYPTPROV hProv;
if (!CryptAcquireContextW(&hProv, NULL, info, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
HCRYPTHASH hHash;
if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
dwStatus = GetLastError();
printf("CryptCreateHash failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
if (!CryptHashData(hHash, (BYTE*)key_str, key_size, 0)) {
DWORD err = GetLastError();
printf("CryptHashData Failed : %#x\n", err);
system("pause");
return (-1);
}
printf("[+] CryptHashData Success\n");
HCRYPTKEY hKey;
if (!CryptDeriveKey(hProv, CALG_AES_128, hHash, 0, &hKey)) {
dwStatus = GetLastError();
printf("CryptDeriveKey failed: %x\n", dwStatus);
CryptReleaseContext(hProv, 0);
system("pause");
return dwStatus;
}
printf("[+] CryptDeriveKey Success\n");
const size_t chunk_size = IN_CHUNK_SIZE;
BYTE *chunk = new BYTE[chunk_size];
DWORD out_len = 0;
BOOL isFinal = FALSE;
DWORD readTotalSize = 0;
DWORD inputSize = GetFileSize(hInpFile, NULL);
while (bResult = ReadFile(hInpFile, chunk, IN_CHUNK_SIZE, &out_len, NULL)) {
if (0 == out_len) {
break;
}
readTotalSize += out_len;
if (readTotalSize >= inputSize) {
isFinal = TRUE;
printf("Final chunk set, len: %d = %x\n", out_len, out_len);
}
if (!CryptDecrypt(hKey, NULL, isFinal, 0, chunk, &out_len)) {
printf("[-] CryptDecrypt failed: %x\n", GetLastError());
break;
}
DWORD written = 0;
if (!WriteFile(hOutFile, chunk, out_len, &written, NULL)) {
printf("writing failed!\n");
break;
}
memset(chunk, 0, chunk_size);
}
delete[]chunk; chunk = NULL;
CryptDestroyHash(hHash);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
CloseHandle(hInpFile);
CloseHandle(hOutFile);
printf("Finished. Processed %#x bytes.\n", readTotalSize);
return 0;
}
The errors I'm getting are regarding the windows.h library, such as:
"ULONG does not name a type" and other types in windows. and at runtime: "Cannot Open input file", not sure why, even tho the file is downloaded in the current folder and I'm trying to open it as such in the code.
I tried to build my kernel code but It doesn't work.
Even the error message and error code doesn't appear and
only
Could not open file: C:\Users\?
phrase was written on the console.
By partially commenting out, I found out the location of the error.
the below is the part making error.
err = clBuildProgram(program, 1, devices, "-cl-fast-relaxed-math", NULL, NULL);
CHECK_ERROR(err);
I think there is no problem on the kernel code because when I made syntax error deliberately on my kernel code, I received another message with error code
"Could not open file: C:\Users\?[D:\OpenCLProjects\Exam03\Exam02\Exam01.c:79] OpenCL error -11"
Belows are my entire code.
__kernel void vec_add(__global int* A, __global int* B, __global int* C) {
int i = get_global_id(0);
C[i] = A[i] + B[i];
}
#define _CRT_SECURE_NO_WARNINGS
#include <CL/cl.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_OF_INT 16384
#define CHECK_ERROR(err) \
if(err != CL_SUCCESS) { \
printf("[%s:%d] OpenCL error %d\n", __FILE__, __LINE__, err); \
exit(EXIT_FAILURE); \
}
char* get_source_code(const char* file_name, size_t * len);
int main()
{
cl_int err;
cl_uint num_platforms;
cl_platform_id* platforms;
cl_uint num_devices;
cl_device_id* devices;
cl_context context;
cl_command_queue queue;
cl_program program;
char* kernel_source;
size_t kernel_source_size;
cl_kernel kernel_vec_add;
cl_mem bufA, bufB, bufC;
err = clGetPlatformIDs(0, NULL, &num_platforms);
CHECK_ERROR(err);
platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * num_platforms);
err = clGetPlatformIDs(num_platforms, platforms, NULL);
CHECK_ERROR(err);
//
size_t plat_name_size;
clGetPlatformInfo(platforms[0], CL_PLATFORM_NAME, 0, NULL, &plat_name_size);
char* plat_name = (char*)malloc(plat_name_size);
clGetPlatformInfo(platforms[0], CL_PLATFORM_NAME, plat_name_size, plat_name, NULL);
printf("%s\n",plat_name);
//
err = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
CHECK_ERROR(err);
devices = (cl_device_id*)malloc(sizeof(cl_device_id) * num_devices);
err = clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_ALL, num_devices, devices, NULL);
CHECK_ERROR(err);
//
size_t dev_name_size;
clGetDeviceInfo(devices[0], CL_DEVICE_NAME, 0, NULL, &dev_name_size);
char* dev_name = (char*)malloc(dev_name_size);
clGetDeviceInfo(devices[0], CL_DEVICE_NAME, dev_name_size, dev_name, NULL);
printf("%s\n",dev_name);
//
context = clCreateContext(NULL, 1, &devices[0], NULL, NULL, &err);
CHECK_ERROR(err);
queue = clCreateCommandQueueWithProperties(context, devices[0], 0, &err);
CHECK_ERROR(err);
kernel_source = get_source_code("kernel.cl", &kernel_source_size);
program = clCreateProgramWithSource(context, 1, &kernel_source, &kernel_source_size, &err);
CHECK_ERROR(err);
err = clBuildProgram(program, 1, devices, "-cl-fast-relaxed-math", NULL, NULL);
CHECK_ERROR(err);
kernel_vec_add = clCreateKernel(program, "vec_add", &err);
CHECK_ERROR(err);
srand(time(NULL));
int* a = (int*)malloc(sizeof(int) * NUM_OF_INT);
int* b = (int*)malloc(sizeof(int) * NUM_OF_INT);
int* c = (int*)malloc(sizeof(int) * NUM_OF_INT);
for (int i = 0; i < NUM_OF_INT; i++) a[i] = rand() % (INT_MAX / 2);
for (int i = 0; i < NUM_OF_INT; i++) b[i] = rand() % (INT_MAX / 2);
bufA = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int) * NUM_OF_INT, NULL, &err);
CHECK_ERROR(err);
bufB = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int) * NUM_OF_INT, NULL, &err);
CHECK_ERROR(err);
bufC = clCreateBuffer(context, CL_MEM_READ_WRITE, sizeof(int) * NUM_OF_INT, NULL, &err);
CHECK_ERROR(err);
err = clEnqueueWriteBuffer(queue, bufA, CL_TRUE, 0, sizeof(int) * NUM_OF_INT, a, 0, NULL, NULL);
CHECK_ERROR(err);
err = clEnqueueWriteBuffer(queue, bufB, CL_TRUE, 0, sizeof(int) * NUM_OF_INT, b, 0, NULL, NULL);
CHECK_ERROR(err);
err = clSetKernelArg(kernel_vec_add, 0, sizeof(cl_mem), &bufA);
CHECK_ERROR(err);
err = clSetKernelArg(kernel_vec_add, 1, sizeof(cl_mem), &bufB);
CHECK_ERROR(err);
err = clSetKernelArg(kernel_vec_add, 2, sizeof(cl_mem), &bufC);
CHECK_ERROR(err);
size_t global_size = NUM_OF_INT;
size_t local_size = 1024;
err = clEnqueueNDRangeKernel(
queue, kernel_vec_add, 1, NULL,
&global_size, &local_size,
0, NULL, NULL);
CHECK_ERROR(err);
//clEnqueueCopyBuffer(queue, bufC, bufA, NULL, NULL, sizeof(int) * NUM_OF_INT, NULL, NULL, NULL);
clFinish(queue);
err = clEnqueueReadBuffer(queue, bufC, CL_TRUE, 0, sizeof(int) * NUM_OF_INT, c, 0, NULL, NULL);
CHECK_ERROR(err);
//for (int i = 0; i < NUM_OF_INT; i++) printf("%d = %d+%d\n", c[i],a[i],b[i]);
printf("\n");
return 0;
}
char* get_source_code(const char* file_name, size_t* len) {
char* source_code;
char buf[2] = "\0";
int cnt = 0;
size_t length;
FILE* file = fopen(file_name, "r");
if (file == NULL) {
printf("[%s:%d] FAiled to open %s\n", __FILE__, __LINE__, file_name);
exit(EXIT_FAILURE);
}
fseek(file, 0, SEEK_END);
length = (size_t)ftell(file);
rewind(file);
source_code = (char*)malloc(length + 1);
fread(source_code, length, 1, file);
for (int i = 0; i < length; i++) {
buf[0] = source_code[i];
if (buf[0] == '\n') cnt++;
}
source_code[length - cnt] = '\0';
fclose(file);
*len = length - cnt;
return source_code;
}
this is my full source code
I found the reason!
If you are using windows,
your account name of window must be ASCII code(a.k.a. english)
If your account name is UNICODE, change your account name or make a new account
I am getting invalid access to memory location when I run the following code
WIN32_FIND_DATAW FD;
WCHAR cPath[MAX_PATH], cFindPath[MAX_PATH];
if (!GetCurrentDirectoryW(MAX_PATH, cPath))
ErrorExit("GetCurrentDirectory");
else
printf("Current Path: %s\n", cPath);
StringCchCopyW(cFindPath, MAX_PATH, cPath);
StringCchCatW(cFindPath, MAX_PATH, L"\\*");
BOOL bsuccess;
HANDLE hFind = FindFirstFileW(cFindPath, &FD);
if (INVALID_HANDLE_VALUE != hFind)
{
vector<wstring> links;
do
{
WCHAR fullFileName[MAX_PATH];
StringCchPrintfW(fullFileName, MAX_PATH, L"\\\\?\\%s\\%s", cPath, FD.cFileName);
DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
REPARSE_DATA_BUFFER* rdata;
rdata = (REPARSE_DATA_BUFFER*)malloc(dwBufSize);
DWORD bytesReturned;
HANDLE hFile = CreateFileW(fullFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
if (DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, &rdata, dwBufSize, &bytesReturned, NULL))
{
if (IsReparseTagMicrosoft(rdata->ReparseTag))
{
if (rdata->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
printf("Symbolic-Link\n");
size_t slen = rdata->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else if (rdata->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
printf("Mount-Point\n");
size_t slen = rdata->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else
{
printf("No Mount-Point or Symblic-Link...\n");
}
}
else
{
printf("Not a Microsoft-reparse point - could not query data!\n");
}
free(rdata);
}
else
ErrorExit("DeviceIoControl");
}
CloseHandle(hFile);
} while (FindNextFileW(hFind, &FD));
}
else
ErrorExit("FindFirstFile");
but the following code works fine.
HANDLE hFile;
LPCTSTR szMyFile = ("C:\\Documents and Settings"); // Mount-Point (JUNCTION)
//LPCTSTR szMyFile = _T("C:\\Users\\All Users"); // Symbolic-Link (SYMLINKD)
hFile = CreateFile(szMyFile, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf(("Could not open dir '%s'; error: %d\n"), szMyFile, GetLastError());
return;
}
// Allocate the reparse data structure
DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
REPARSE_DATA_BUFFER* rdata;
rdata = (REPARSE_DATA_BUFFER*)malloc(dwBufSize);
// Query the reparse data
DWORD dwRetLen;
BOOL bRet = DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdata, dwBufSize, &dwRetLen, NULL);
if (bRet == FALSE)
{
printf(("DeviceIoControl failed with error: %d\n"), GetLastError());
CloseHandle(hFile);
return;
}
CloseHandle(hFile);
if (IsReparseTagMicrosoft(rdata->ReparseTag))
{
if (rdata->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
printf("Symbolic-Link\n");
size_t slen = rdata->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else if (rdata->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
printf("Mount-Point\n");
size_t slen = rdata->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else
{
printf("No Mount-Point or Symblic-Link...\n");
}
}
else
{
printf(("Not a Microsoft-reparse point - could not query data!\n"));
}
free(rdata);
I am trying to get the reparse data for the files in a given folder. This is my REPARSE_DATA_BUFFER
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags; // it seems that the docu is missing this entry (at least 2008-03-07)
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
} MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
I Dont know where I went wrong. Please help me fix my first code.
your code containing 2 errors how minimum
you unconditionally call FSCTL_GET_REPARSE_POINT for all files, but you must do this only
if (FD.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {..}
otherwise you got ERROR_NOT_A_REPARSE_POINT in DeviceIoControl and then ErrorExit("DeviceIoControl"); executed.
and second error at this line:
DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, &rdata, dwBufSize, &bytesReturned, NULL)
&rdata - !!
when must be
DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdata, dwBufSize, &bytesReturned, NULL)
The data between these two functions is becoming garbled. Inspecting the variables on each side show that the data is definitely different. The message size signal does work. It's the second read/write function that has the problem.
Here is my write function and its counter read function:
string Pipe::RecvCompressedMessage()
{
int message_size = 0;
DWORD dwBytesRead = 0;
string buf, data;
byte size_in[sizeof(int)];
if (!ReadFile(_h, &message_size, sizeof(int), &dwBytesRead, NULL))
{
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
Close();
return "";
}
if (message_size < 0)
return "";
buf.resize(message_size);
int total_bytes_read = 0;
while(total_bytes_read < message_size)
{
if (!ReadFile(_h, (LPVOID) &buf, message_size - total_bytes_read, &dwBytesRead, NULL))
{
int err = GetLastError();
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
Close();
return "";
}
data.append(buf);
total_bytes_read += dwBytesRead;
}
std::string decompressed;
boost::iostreams::filtering_streambuf<boost::iostreams::output> out;
out.push(boost::iostreams::bzip2_decompressor());
out.push(boost::iostreams::back_inserter(decompressed));
boost::iostreams::copy(boost::make_iterator_range(buf), out);
return decompressed;
}
void Pipe::SendCompressedMessage(string message)
{
std::string compressed;
boost::iostreams::filtering_streambuf<boost::iostreams::output> out;
out.push(boost::iostreams::bzip2_compressor());
out.push(boost::iostreams::back_inserter(compressed));
boost::iostreams::copy(boost::make_iterator_range(message), out);
DWORD dwBytesWritten;
int message_size = compressed.length();
if (WriteFile(_h, &message_size, sizeof(int), &dwBytesWritten, NULL) == 0)
{
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
Close();
return;
}
if (WriteFile(_h, (LPVOID *) &compressed, message_size, &dwBytesWritten, NULL) == 0)
{
debug->DebugMessage(Error::GetErrorMessageW(GetLastError()));
Close();
return;
}
}
string buf, data;
...
if (!ReadFile(_h, (LPVOID) &buf, message_size - total_bytes_read, &dwBytesRead, NULL))
You pass pointer to string object as lpBuffer to ReadFile. Replace string with vector<char>:
vector<char> buf;
...
buf.resize(message_size - total_bytes_read);
if (!ReadFile(_h, &buf[0], message_size - total_bytes_read, &dwBytesRead, NULL))
You are writing a std::string instead a char *:
if (WriteFile(_h, (LPVOID *) (compressed.c_str()), message_size, &dwBytesWritten, NULL) == 0)
The problem I'm having: CreateFile returns a handle of 0x194. ReadFileEx is saying that this handle is invalid. (Error 6.) Any ideas? The argument passed in is "C:\testfile.txt", which is a valid text file I made in Notepad. Despite being a C++ programmer for the last 12 years, this is my first time writing anything with "windows.h" or threads.
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
using namespace System;
int main(int argc, char **argv)
{
if (argc != 2)
{
printf("To display a file, you must enter the filename as the only command argument.");
scanf("\n");
return 0;
}
HANDLE file;
int nameLen = (strlen(argv[1]) + 1);
wchar_t *filename = new wchar_t[nameLen];
if (filename == 0)
{
printf("To display a file, you must enter the filename as the only command argument.");
scanf("\n");
return 0;
}
memset(filename, 0, nameLen);
::MultiByteToWideChar(CP_ACP, NULL, argv[1], -1, filename, nameLen);
file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == NULL)
{
printf("A valid filename is required.");
scanf("\n");
return 0;
}
char *buffer;
buffer = new char[1024];
OVERLAPPED overlapped;
overlapped.Offset = overlapped.OffsetHigh = 0;
ReadFileEx(file, &buffer, 1024, &overlapped, NULL);
WaitForSingleObject(&file, 0);
if (GetLastError() != ERROR_SUCCESS)
{
printf("A valid file is required., Error: %d", GetLastError());
scanf("\n");
return 0;
}
printf("%s", buffer);
scanf("\n");
delete buffer;
return 0;
}
My guess is to change
ReadFileEx(&file, &buffer, 1024, &overlapped, NULL);
to
ReadFileEx(file, &buffer, 1024, &overlapped, NULL);