So I am trying to create a folder structure after a registry key. This is what I did so far
#include "stdafx.h"
#include "windows.h"
#define MAX_KEY_LENGTH 200
#define MAX_VALUE_NAME 16383
DWORD retCode;
void RecursiveQueryKey(HKEY hKey)
{
HKEY nextKey;
WCHAR achKey[MAX_KEY_LENGTH];
DWORD cbName;
DWORD retCode = NULL;
DWORD i=0;
while(retCode !=ERROR_NO_MORE_ITEMS)
{
cbName = MAX_KEY_LENGTH;
retCode = RegEnumKeyEx(hKey, i,achKey,&cbName,NULL,NULL,NULL,NULL);
if (retCode == ERROR_SUCCESS)
{
wprintf(L"(%d) %s\n", i+1, achKey);
WCHAR path[MAX_KEY_LENGTH];
wchar_t *wcsncat(wchar_t *path, const wchar_t *achKey, size_t n);
if(CreateDirectoryEx(TEXT("D:\\csso\\"),achKey, NULL) != 0){
wprintf(L"Directory created in D:\\csso\\%s\n", achKey);
} else {
printf("Directory failed with the error:");
}
wprintf(L"%d\n", GetLastError());
if(RegOpenKeyEx(hKey, achKey, 0, KEY_READ | KEY_WOW64_64KEY, &nextKey) == ERROR_SUCCESS)
{
RecursiveQueryKey(nextKey);
}
}
i++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HKEY hKey;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Apple Inc."), 0, KEY_READ | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)
{
printf("RegOpenKeyEx() is OK!\n");
RecursiveQueryKey(hKey);
}
else
printf("RegOpenKeyEx() failed!\n");
RegCloseKey(hKey);
}
I'm pretty new at this, but when I first run the program it says that directory's have all been created but they are not, when I run it again I get error 183 (Already Existent).
I'm really not sure what is the problem here.
OK so I figured it out, the problem came from my inability to create a path, apparently it was pretty simple, here is my final code, maybe it will help someone out.
#include "stdafx.h"
#include "windows.h"
#include "tchar.h"
#include <iostream>
#define KEY_LENGHT 255
#define MAX_VALUE_NAME 16000
#define DEFAULT_KEY L"Apple Inc."
WCHAR path[1024] = L"D:\\csso\\" DEFAULT_KEY;
void Query(HKEY key, WCHAR *path) {
HKEY next;
WCHAR name[KEY_LENGHT];
DWORD lpcname;
DWORD returncode = NULL;
DWORD i = 0;
WCHAR xpath[1024];
while(returncode != ERROR_NO_MORE_ITEMS) {
lpcname = KEY_LENGHT;
returncode =
RegEnumKeyEx(key, i, name, &lpcname, NULL, NULL, NULL, NULL);
if (returncode ==ERROR_SUCCESS) {
wcscpy(xpath, path);
wcscat(xpath, L"\\");
wcscat(xpath, name);
if(CreateDirectory(xpath, NULL)) {
wprintf(L"Creat Folder %s\n", xpath);
} else {
printf("Folder nu a putut fi creat! \n");
wprintf(L"%d\n", GetLastError());
}
DWORD verif =
RegOpenKeyEx(key, name, 0, KEY_READ | KEY_WOW64_64KEY, &next);
if(verif == ERROR_SUCCESS) {
Query(next, xpath);
}
i++;
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
HKEY key;
DWORD verif =
RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\" DEFAULT_KEY), 0, KEY_READ | KEY_WOW64_64KEY, &key);
if(verif == ERROR_SUCCESS) {
printf("RegOpenKeyEx SUCCESS! \n");
if(!CreateDirectory(_T("D:\\csso\\" DEFAULT_KEY), NULL)) {
printf("Folder nu a putut fi creat! \n");
} else {
Query(key, path);
}
} else {
printf("RegOpenKeyEx FAIL! \n");
wprintf(L"%d\n", GetLastError);
}
RegCloseKey(key);
}
Cheers and best of luck to you guys.
Related
I do not know english. I'm using google translate. I apologize in advance.
I will use ESP8266 in a project that I will run on battery. For this reason, I do not want to use an SD card.
I will use the database in FLASH using SPIFFS.
The example I got from the ESP8266 sqlite3 library runs the sql commands in the SETUP paragraph. But when I call these commands from outside of SETUP with FUNCTION, the device is reset. Below I present both codes for your information.
I am already grateful for your help.
This is the original library sample. It always works.
/*
This creates two empty databases, populates values, and retrieves them back
from the SPIFFS file system.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <vfs.h>
#include <SPI.h>
#include <FS.h>
extern "C" {
#include "user_interface.h"
}
#include <ESP8266WiFi.h>
void WiFiOff() {
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_set_sleep_type(MODEM_SLEEP_T);
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
}
const char* data = "Callback function called";
static int callback(void *data, int argc, char **argv, char **azColName) {
int i;
Serial.printf("%s: ", (const char*)data);
for (i = 0; i<argc; i++){
Serial.printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
Serial.printf("\n");
return 0;
}
int db_open(const char *filename, sqlite3 **db) {
int rc = sqlite3_open(filename, db);
if (rc) {
Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db));
return rc;
} else {
Serial.printf("Opened database successfully\n");
}
return rc;
}
char *zErrMsg = 0;
int db_exec(sqlite3 *db, const char *sql) {
Serial.println(sql);
long start = micros();
int rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK) {
Serial.printf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
} else {
Serial.printf("Operation done successfully\n");
}
Serial.print(F("Time taken:"));
Serial.println(micros()-start);
return rc;
}
void setup() {
Serial.begin(74880);
sqlite3 *db1;
sqlite3 *db2;
int rc;
system_update_cpu_freq(SYS_CPU_160MHZ);
WiFiOff();
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
// list SPIFFS contents
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
Serial.printf("FS File: %s, size: %ld\n", fileName.c_str(), (long) fileSize);
}
Serial.printf("\n");
// remove existing file
SPIFFS.remove("/test1.db");
SPIFFS.remove("/test2.db");
sqlite3_initialize();
// Open databases
File db_file_obj_1;
vfs_set_spiffs_file_obj(&db_file_obj_1);
if (db_open("/FLASH/test1.db", &db1))
return;
File db_file_obj_2;
vfs_set_spiffs_file_obj(&db_file_obj_2);
if (db_open("/FLASH/test2.db", &db2))
return;
rc = db_exec(db1, "CREATE TABLE test1 (id INTEGER, content);");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
rc = db_exec(db2, "CREATE TABLE test2 (id INTEGER, content);");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
rc = db_exec(db1, "INSERT INTO test1 VALUES (1, 'Hello, World from test1');");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
rc = db_exec(db2, "INSERT INTO test2 VALUES (1, 'Hello, World from test2');");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
rc = db_exec(db1, "SELECT * FROM test1");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
rc = db_exec(db2, "SELECT * FROM test2");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
sqlite3_close(db2);
return;
}
sqlite3_close(db1);
sqlite3_close(db2);
}
void loop() {
}
This is the version of the function called from outside of SETUP.
The device resets when other functions are called except OPENDATABASE (such as Select Values ()).
/*
This creates two empty databases, populates values, and retrieves them back
from the SPIFFS file system.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <vfs.h>
#include <SPI.h>
#include <FS.h>
extern "C" {
#include "user_interface.h"
}
#include <ESP8266WiFi.h>
sqlite3* db1;
void WiFiOff() {
wifi_station_disconnect();
wifi_set_opmode(NULL_MODE);
wifi_set_sleep_type(MODEM_SLEEP_T);
wifi_fpm_open();
wifi_fpm_do_sleep(0xFFFFFFF);
}
const char* data = "Callback function called";
static int callback(void* data, int argc, char** argv, char** azColName) {
int i;
Serial.printf("%s: ", (const char*)data);
for (i = 0; i < argc; i++) {
Serial.printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
Serial.printf("\n");
return 0;
}
int db_open(const char* filename, sqlite3** db) {
int rc = sqlite3_open(filename, db);
if (rc) {
Serial.printf("Can't open database: %s\n", sqlite3_errmsg(*db));
return rc;
}
else {
Serial.printf("Opened database successfully\n");
}
return rc;
}
char* zErrMsg = 0;
int db_exec(sqlite3* db, const char* sql) {
Serial.println(sql);
long start = micros();
int rc = sqlite3_exec(db, sql, callback, (void*)data, &zErrMsg);
if (rc != SQLITE_OK) {
Serial.printf("SQL error: %s\n", zErrMsg);
sqlite3_free(zErrMsg);
}
else {
Serial.printf("Operation done successfully\n");
}
Serial.print(F("Time taken:"));
Serial.println(micros() - start);
return rc;
}
void OpenDatabase();
void CreateTable();
void InsertValues();
void SelectValues();
void setup() {
Serial.begin(74880);
system_update_cpu_freq(SYS_CPU_160MHZ);
WiFiOff();
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
return;
}
// list SPIFFS contents
Dir dir = SPIFFS.openDir("/");
while (dir.next()) {
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
Serial.printf("FS File: %s, size: %ld\n", fileName.c_str(), (long)fileSize);
}
Serial.printf("\n");
// remove existing file
SPIFFS.remove("/test1.db");
sqlite3_initialize();
OpenDatabase();
CreateTable();
InsertValues();
SelectValues(); */
// list SPIFFS contents
dir = SPIFFS.openDir("/");
while (dir.next()) {
String fileName = dir.fileName();
size_t fileSize = dir.fileSize();
Serial.printf("FS File: %s, size: %ld\n", fileName.c_str(), (long)fileSize);
}
Serial.printf("\n");
}
void loop() {
}
void OpenDatabase() {
int rc;
// Open databases
File db_file_obj_1;
vfs_set_spiffs_file_obj(&db_file_obj_1);
if (db_open("/test1.db", &db1)) return;
}
void CreateTable() {
int rc;
// Create Table
rc = db_exec(db1, "CREATE TABLE IF NOT EXISTS test1 (id INTEGER, content);");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
return;
}
}
void InsertValues() {
int rc;
// Insert Values
rc = db_exec(db1, "INSERT INTO test1 VALUES (1, 'Hello, Hurol from test1');");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
return;
}
}
void SelectValues() {
int rc;
// Select Values
rc = db_exec(db1, "SELECT * FROM test1");
if (rc != SQLITE_OK) {
sqlite3_close(db1);
return;
}
}
}
worked!
File db_file_obj_1; vfs_set_spiffs_file_obj(&db_file_obj_1); I left this command in the setup section. So once it worked.
In this block, SPIFFS is set again each time.
Final: ... SETUP >
sqlite3_initialize();
File db_file_obj_1;
vfs_set_spiffs_file_obj(&db_file_obj_1);
OpenDatabase();
CreateTable();
InsertValues();
SelectValues();
... }
void OpenDatabase() {
int rc;
// Open databases
if (db_open("/test1.db", &db1)) return;
}
Life is beautiful when shared.
I'm writing my very first C program and I was really doing well. The application talks to RESTful server. All was good until I decided to use an embedded database(libdb) for storage. I got this code below that was part of my entire program. My problem is it keeps on crashing on this line:
my_archive->db_home_dir = DEFAULT_HOMEDIR;
I thought I was running out of stack so I malloc'd all my lengthy variables but the problem was still occuring so I decided to separate this libdb part into a new code, but the problem still remains.
Any idea what has gone wrong here?
P.S. I'm doing all the coding in Xcode and stepping through each line after debug breakpoint right after main() doesn't help me a bit. Always ends up on the same error line. Or perhaps I just don't know what I'm doing.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
#include "db.h"
#define DEFAULT_HOMEDIR "/Users/mark/Documents/bdb/"
#define URLSDB "urls"
typedef struct archive_dbs {
DB *URLS_dbp;
char *db_home_dir;
char *URLS_db_name;
} ARCHIVE_DBS;
void initialize_archivedbs(ARCHIVE_DBS *my_archive)
{
my_archive->db_home_dir = DEFAULT_HOMEDIR; //CRASHES HERE: Thread 1: EXC_BAD_ACCESS (code=2, address=0x1000061da)
my_archive->URLS_dbp = NULL;
my_archive->URLS_db_name = NULL;
}
void set_db_filenames(ARCHIVE_DBS *my_archive)
{
size_t size;
size = strlen(my_archive->db_home_dir) + strlen(URLSDB) + 1;
my_archive->URLS_db_name = malloc(size);
snprintf(my_archive->URLS_db_name, size, "%s%s", my_archive->db_home_dir, URLSDB);
}
int open_database(DB **dbpp, const char *file_name, const char *program_name, FILE *error_file_pointer)
{
DB *dbp;
u_int32_t open_flags;
int ret;
ret = db_create(&dbp, NULL, 0);
if (ret != 0) {
fprintf(error_file_pointer, "%s: %s\n", program_name,
db_strerror(ret));
return(ret);
}
*dbpp = dbp;
dbp->set_errfile(dbp, error_file_pointer);
dbp->set_errpfx(dbp, program_name);
open_flags = DB_CREATE;
ret = dbp->open(dbp,
NULL,
file_name,
NULL,
DB_BTREE,
open_flags,
0);
if (ret != 0) {
dbp->err(dbp, ret, "Database '%s' open failed.", file_name);
return(ret);
}
return (0);
}
int databases_setup(ARCHIVE_DBS *my_archive, const char *program_name, FILE *error_file_pointer)
{
int ret;
ret = open_database(&(my_archive->URLS_dbp), my_archive->URLS_db_name, program_name, error_file_pointer);
if (ret != 0)
return (ret);
printf("databases opened successfully\n");
return (0);
}
int databases_close(ARCHIVE_DBS *my_archive)
{
int ret;
if (my_archive->URLS_dbp != NULL) {
ret = my_archive->URLS_dbp->close(my_archive->URLS_dbp, 0);
if (ret != 0)
fprintf(stderr, "URLS database close failed: %s\n",
db_strerror(ret));
}
printf("databases closed.\n");
return (0);
}
int main(void){
ARCHIVE_DBS *archivedbs;
initialize_archivedbs(archivedbs);
set_db_filenames(archivedbs);
databases_setup(archivedbs, "urlfetcher", NULL);
open_database(&archivedbs->URLS_dbp, "URLS.db", "urlfetcher",
NULL);
databases_close(archivedbs);
}
The program recursively navigates the given folder, creates registry for folders, but after the execution of the RegSetValueEx function nothing happend in the registry, what should I change ? I mean the program Works perfect but nothing change in registry about RegSetValuesEx function just RegCreateKeys worked well.
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <iostream>
using namespace std;
#define DEFAULT_KEY_DIR "HKEY_CURRENT_USER"
#define DEFAULT_KEY_SUBDIR "Software\\CSSO"
#define DEFAULT_DIRECTORY "D:\\Example"
char xPath[2048] = "Software\\CSSO";
bool ListDirectoryContents(const char *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;
LARGE_INTEGER filesize;
DWORD return_value;
char sPath[2048];
HKEY hKey;
sprintf(sPath, "%s\\*", sDir);
if ((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
printf("Path not found: [%s]\n", sDir);
return false;
}
do
{
if (strcmp(fdFile.cFileName, ".") != 0
&& strcmp(fdFile.cFileName, "..") != 0)
{
sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);
if (fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
{
printf("%s\n", sPath);
memset(&xPath[0], 0, sizeof(xPath));
strcpy(xPath, DEFAULT_KEY_SUBDIR);
int j = strlen(DEFAULT_KEY_SUBDIR);
for (int i = strlen(DEFAULT_DIRECTORY); i < strlen(sPath); i++)
{
xPath[j] = sPath[i];
j++;
}
RegCreateKeyEx(
HKEY_CURRENT_USER,
xPath,
0, 0, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, 0, &hKey, 0
);
ListDirectoryContents(sPath); //Recursion, I love it!
}
else {
filesize.LowPart = fdFile.nFileSizeLow;
filesize.HighPart = fdFile.nFileSizeHigh;
_tprintf(TEXT("%s %ld bytes\n"),sPath, filesize.QuadPart);
return_value = RegSetValueEx(
hKey,
fdFile.cFileName, 0,
REG_DWORD,
(BYTE*)filesize.QuadPart,
strlen(sPath)
);
}
}
} while (FindNextFile(hFind, &fdFile));
FindClose(hFind);
return true;
}
int main()
{
ListDirectoryContents("D:\\Example");
system("PAUSE");
return 0;
}
Above code is going through a recursive loop, it is adding a lot of junk to the registry. This is not recommended.
return_value = RegSetValueEx(
hKey,
fdFile.cFileName, 0,
REG_DWORD,
(BYTE*)filesize.QuadPart,
strlen(sPath))
(BYTE*)filesize.QuadPart is wrong. It is similar to writing:
BYTE* ptr = (BYTE*)123;
This creates a pointer to the memory address 123 which we are not allowed to mess with. You mean to write (BYTE*)&filesize.QuadPart instead.
Assuming that you want to write the filesize, use REG_QWORD instead of REG_DWORD. Use sizeof(filesize.QuadPart) instead of strlen(path).
if (ERROR_SUCCESS != RegSetValueEx(hKey, fdFile.cFileName, 0, REG_QWORD,
(BYTE*)&filesize.QuadPart, sizeof(filesize.QuadPart))
{
printf("RegSetValueEx error\n");
}
However, you should use the registry for adding initialization data only. If you have a lot of data then save to file, or just save it in memory.
I figured out what I did wrong, thank you guys for answers I will post the final code maybe will help someone.
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <iostream>
using namespace std;
#define DEFAULT_KEY_DIR "HKEY_CURRENT_USER"
#define DEFAULT_KEY_SUBDIR "Software\\CSSO"
#define DEFAULT_DIRECTORY "D:\\Example"
char xPath[2048] = "Software\\CSSO";
bool ListDirectoryContents(const char *sDir)
{
WIN32_FIND_DATA fdFile;
HANDLE hFind = NULL;
LARGE_INTEGER filesize;
DWORD return_value;
char sPath[2048];
HKEY hKey, hKey2;
//Specify a file mask. *.* = We want everything!
sprintf(sPath, "%s\\*", sDir);
if ((hFind = FindFirstFile(sPath, &fdFile)) == INVALID_HANDLE_VALUE)
{
printf("Path not found: [%s]\n", sDir);
return false;
}
do
{
//Find first file will always return "."
// and ".." as the first two directories.
if (strcmp(fdFile.cFileName, ".") != 0
&& strcmp(fdFile.cFileName, "..") != 0)
{
//Build up our file path using the passed in
// [sDir] and the file/foldername we just found:
sprintf(sPath, "%s\\%s", sDir, fdFile.cFileName);
//Is the entity a File or Folder?
if (fdFile.dwFileAttributes &FILE_ATTRIBUTE_DIRECTORY)
{
printf("%s\n", sPath);
memset(&xPath[0], 0, sizeof(xPath));
strcpy(xPath, DEFAULT_KEY_SUBDIR);
int j = strlen(DEFAULT_KEY_SUBDIR);
for (int i = strlen(DEFAULT_DIRECTORY); i < strlen(sPath); i++)
{
xPath[j] = sPath[i];
j++;
}
RegCreateKeyEx(
HKEY_CURRENT_USER,
xPath,
0, 0, REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS, 0, &hKey, 0
);
ListDirectoryContents(sPath); //Recursion, I love it!
}
else {
filesize.LowPart = fdFile.nFileSizeLow;
filesize.HighPart = fdFile.nFileSizeHigh;
_tprintf(TEXT("%s %ld bytes\n"), sPath, filesize.QuadPart);
RegOpenKeyEx(
HKEY_CURRENT_USER,
xPath,
REG_OPTION_NON_VOLATILE,
KEY_WRITE,
&hKey);
RegSetValueEx(
hKey,
fdFile.cFileName, NULL,
REG_DWORD, (LPBYTE)&filesize.QuadPart,
sizeof(DWORD));
}
}
} while (FindNextFile(hFind, &fdFile)); //Find the next file.
FindClose(hFind); //Always, Always, clean things up!
return true;
}
int main()
{
ListDirectoryContents("D:\\Example");
system("PAUSE");
return 0;
}
I have a program that generates a hash key from a file. And also verifies if the result hash is equal to the expected hash. But the program is just working for one file each time. Now, I was trying to generate a hash key from each file in a given directory and do the comparison with each expected hash.
For that I have the code below to read the directory. But I am not having success to associate the expected hash to each file that I have in the directory.
With strcmp I can compare and it is already working, but then how can I associate the correct expected hash with the corresponding file? Do you know how to do that?
PCSTR text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
DIR *d;
d = opendir("C:\\Users\\Jax\\Desktop\\files\\files2\\");
struct dirent *dir;
char name[256][256];
int count = 0;
int index = 0;
char TextExpected[] = "811676652bf08c0a91a849d66bb2a46c";
char PptxExpected[] = "b011367338c3264f1f3f74107060d788";
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
strcpy(name[count],dir->d_name);
count++;
if(strcmp(dir->d_name,"test.pptx") == 0){
// how can I do here to associate the hashExpected to the file "test.pptx"
}
if(strcmp(dir->d_name,"test.txt") == 0){
// how can I do here to associate the hashExpected to the file "test.txt"
}
}
closedir(d);
while( count > 0 )
{
...
Inside the while ( count > 0) I execute the code to generate the hash key for each file in the directory(count > 0).
This is the complete program, it is working just that associating part I am not having success in getting it to work:
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <dirent.h>
#include <stdbool.h>
#define BUFSIZE 1024
#define MD5LEN 16
int main()
{
DWORD dwStatus = 0;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
PCSTR text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
DIR *d;
d = opendir("C:\\Users\\Jax\\Desktop\\files\\files2\\");
struct dirent *dir;
struct dirent *test;
char name[256][256];
int count = 0;
int index = 0;
int expected[25];
int countcount;
char testtest[256][256];
char TextExpected[] = "811676652bf08c0a91a849d66bb2a46c";
char PptxExpected[] = "b011367338c3264f1f3f74107060d788";
while ((dir = readdir(d)) != NULL)
{
printf("%s\n", dir->d_name);
strcpy(name[count],dir->d_name);
count++;
if(strcmp(dir->d_name,"test.pptx") == 0){
// how can I do here to associate the hashExpected to the file "test.pptx"
}
if(strcmp(dir->d_name,"test.txt") == 0){
// how can I do here to associate the hashExpected to the file "test.txt"
}
}
closedir(d);
while( count > 0 )
{
bool incorrect = FALSE;
char hashResult[MD5LEN * 2 + 1] = "";
hFile = CreateFile(text, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
incorrect = TRUE;
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", text, dwStatus);
return (int)dwStatus;
}
// Get handle to the crypto provider
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
return (int)dwStatus;
}
if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", dwStatus);
CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
return (int)dwStatus;
}
while(ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
{
if(0 == cbRead)
break;
if(!CryptHashData(hHash, rgbFile, cbRead, 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
return (int)dwStatus;
}
}
cbHash = MD5LEN;
if(CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
DWORD i;
printf("MD5 expected, versus MD5 of file %s is:\n", text);
printf("%s\n", TextExpected);
for(i = 0; i < cbHash; i++)
{
printf("%c%c",
rgbDigits[rgbHash[i] >> 4],
rgbDigits[rgbHash[i] & 0xf]);
hashResult[i * 2] = rgbDigits[rgbHash[i] >> 4];
hashResult[i * 2 + 1] = rgbDigits[rgbHash[i] & 0xf];
}
printf("\n");
if(_strcmpi(hashResult, TextExpected) == 0)
printf("Hash is the same\n");
else
printf("Hash is different\n");
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", dwStatus);
}
CryptDestroyHash(hHash);
CryptReleaseContext(hProv, 0);
CloseHandle(hFile);
return (int)dwStatus;
}
}
strcpy(name[count],dir->d_name);
d_name is relative filename, for example "test.txt", but most likely you want to use full path name for crypt functions. Use full path instead. Example:
strcpy(name[count],"c:\\dir\\");
strcat(name[count],dir->d_name);
readdir's result includes "." and ".." which are basically useless, you want to skip them:
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0)
continue;
while( count > 0 ) puts the code in infinite loop. You mean to do this instead:
int index = 0;
while( index < count )
{
const char* filename = name[index];
index++;
}
Note, you want to use name[index] and not name. You probably don't want to exit the loop whenever error occurs, instead you want to continue.
Finally, add a function which will look up the expect hash value for known files. Example:
#include <stdio.h>
#include <windows.h>
#include <Wincrypt.h>
#include <dirent.h>
#include <stdbool.h>
#define BUFSIZE 1024
#define MD5LEN 16
const char* get_expected_hash(const char* filename)
{
PCSTR text = "C:\\Users\\Jax\\Desktop\\files\\files2\\txt_1.txt";
PCSTR pptx = "C:\\Users\\Jax\\Desktop\\files\\files2\\Test.pptx";
const char* TextExpected = "811676652bf08c0a91a849d66bb2a46c";
const char* PptxExpected = "b011367338c3264f1f3f74107060d788";
if (stricmp(filename, text) == 0)
return TextExpected;
if (stricmp(filename, pptx) == 0)
return PptxExpected;
return "unknown hash";
}
int main()
{
DWORD dwStatus = 0;
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
HANDLE hFile = NULL;
BYTE rgbFile[BUFSIZE];
DWORD cbRead = 0;
BYTE rgbHash[MD5LEN];
DWORD cbHash = 0;
CHAR rgbDigits[] = "0123456789abcdef";
//const char* dirname = "C:\\Users\\Jax\\Desktop\\files\\files2\\";
const char* dirname = "c:\\test\\";
DIR *d;
d = opendir(dirname);
struct dirent *dir;
char files[256][256];
int count = 0;
while ((dir = readdir(d)) != NULL)
{
if(strcmp(dir->d_name,".") == 0 || strcmp(dir->d_name,"..") == 0)
continue;
strcpy(files[count],dirname);
strcat(files[count],dir->d_name);
count++;
}
closedir(d);
// Get handle to the crypto provider
if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", (int)dwStatus);
CloseHandle(hFile);
return (int)dwStatus;
}
int index = 0;
while( index < count )
{
const char* filename = files[index];
index++;
printf("%s\n", filename);
char hashResult[MD5LEN * 2 + 1] = "";
hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
//incorrect = TRUE;
dwStatus = GetLastError();
printf("Error opening file %s\nError: %d\n", filename, (int)dwStatus);
return (int)dwStatus;
}
if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
{
dwStatus = GetLastError();
printf("CryptAcquireContext failed: %d\n", (int)dwStatus);
CloseHandle(hFile);
CryptReleaseContext(hProv, 0);
continue;
}
while(ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL))
{
if(0 == cbRead)
break;
if(!CryptHashData(hHash, rgbFile, cbRead, 0))
{
dwStatus = GetLastError();
printf("CryptHashData failed: %d\n", (int)dwStatus);
CryptReleaseContext(hProv, 0);
CryptDestroyHash(hHash);
CloseHandle(hFile);
continue;
}
}
cbHash = MD5LEN;
if(CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
{
DWORD i;
printf("MD5 expected, versus MD5 of file %s is:\n", filename);
const char* TextExpected = get_expected_hash(filename);
printf("%s\n", TextExpected);
for(i = 0; i < cbHash; i++)
{
printf("%c%c", rgbDigits[rgbHash[i] >> 4], rgbDigits[rgbHash[i] & 0xf]);
hashResult[i * 2] = rgbDigits[rgbHash[i] >> 4];
hashResult[i * 2 + 1] = rgbDigits[rgbHash[i] & 0xf];
}
//printf("\n");
if(_strcmpi(hashResult, TextExpected) == 0)
printf("Hash is the same\n");
else
printf("Hash is different\n");
}
else
{
dwStatus = GetLastError();
printf("CryptGetHashParam failed: %d\n", (int)dwStatus);
continue;
}
CryptDestroyHash(hHash);
CloseHandle(hFile);
}
CryptReleaseContext(hProv, 0);
return 0;
}
I'm not strong in C code and this is my problem:
I try to write REG_DWORD to registry (I use minGW).
However I get an error 998 ERROR_NOACCESS and don't know why.
All stuff seems valid.
In my case I try to write 777
It's really strange why so basic task, like to add value to registry seems so complicated and Google doesn't contains any information
Please, help
this is my code:
#define _WIN32_WINNT 0x0501
//#define _WIN32_WINNT 0x0500 // Windows 2000
//#define _WIN32_WINNT 0x0400 // Windows NT 4.0
//#define _WIN32_WINDOWS 0x0500 // Windows ME
//#define _WIN32_WINDOWS 0x0410 // Windows 98
//#define _WIN32_WINDOWS 0x0400 // Windows 95
#include <windows.h>
#include <stdio.h>
....
const char *WriteValue()
{
HKEY hkey;
LONG result_open, result_close;
const char *defaultVal = "0";
DWORD data = 777;
DWORD dwValue, dwType, dwSize = sizeof(dwValue);
DWORD szType = REG_DWORD;
printf("Opening Key...\n");
result_open = RegOpenKeyEx(HKEY_CURRENT_USER,
"Software\\screen-capture-recorder",
0, KEY_WRITE, &hkey);
if(result_open != ERROR_SUCCESS) {
if(result_open == ERROR_FILE_NOT_FOUND) {
printf("Not found\n");
} else {
printf("Error Opening Key\n");
}
} else {
printf("SUCCESS!!!\n");
}
printf("Writing Value named capture_height\n");
LONG result_write = RegSetValueEx(hkey, "capture_height", 0, szType, (LPBYTE)data, dwSize+1);
if(result_write != ERROR_SUCCESS) {
printf("Error Writing Value\n");
} else {
printf("SUCCESS!!!\n");
}
printf("Closing Key...\n");
result_close = RegCloseKey(hkey);
if(result_close != ERROR_SUCCESS) {
printf("Error Closing Key\n");
} else {
printf("SUCCESS!!!!\n");
}
return defaultVal;
}
[Compilation]
$ gcc -L/local/lib -I/local/include -o readRegistry readRegistry.c
[Run]
$ ./readRegistry.exe
Opening Key...
SUCCESS!!!
Writing Value named capture_height
Error Writing Value
Closing Key...
SUCCESS!!!!
[Registry before]
[EDIT 1]
Regards to #Mat comment:
I get error 998, from Winerror.h
ERROR_NOACCESS 998L
[EDIT 2]
When I run:
LONG result_write = RegSetValueEx(hkey, "capture_height", 0, szType, (LPBYTE)"0x00000006", dwSize+1);
I get no error but in registry I see Invalid DWORD (32-bit) value.
I tried to use:
int32_t i;
i = 0x00000777;
LONG result_write = RegSetValueEx(hkey, "capture_height", 0, szType, (LPBYTE)i, dwSize+1);
get the same error
[EDIT 3]
To be sure that i have right infra i run some test:
LONG result_write = RegSetValueEx(hkey, "capture_height1", 0, REG_SZ, (LPBYTE)"bobo", dwSizeI*2+1);
And I get in registry right value "bobo" defined as REG_SZ
Thanks to #Edward Clements and #Mat for help,
After hours of "monkey-work" at last I did it:
I need add mode: KEY_ALL_ACCESS
result_open = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\screen-capture-recorder", 0, KEY_ALL_ACCESS, &hkey);
and change LPBYTE to BYTE
LONG result_write = RegSetValueEx(hkey, "capture_height1", 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
so now this is working code:
const char *WriteValue()
{
HKEY hkey;
LONG result_open, result_close;
const char *defaultVal = "0";
result_open = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\screen-capture-recorder", 0, KEY_ALL_ACCESS, &hkey);
if(result_open != ERROR_SUCCESS) {
if(result_open == ERROR_FILE_NOT_FOUND) {
printf("Not found\n");
} else {
printf("Error Opening Key\n");
}
} else {
printf("SUCCESS!!!\n");
}
DWORD value=777;
printf("Writing Value named capture_height\n");
LONG result_write = RegSetValueEx(hkey, "capture_height1", 0, REG_DWORD, (const BYTE*)&value, sizeof(value));
printf("response %ld\n", result_write);
if(result_write != ERROR_SUCCESS) {
printf("Error Writing Value\n");
} else {
printf("SUCCESS!!!\n");
}
printf("Closing Key...\n");
result_close = RegCloseKey(hkey);
if(result_close != ERROR_SUCCESS) {
printf("Error Closing Key\n");
} else {
printf("SUCCESS!!!!\n");
}
return defaultVal;
}
I used for answer this example
Could you try adding KEY_READ in your call to RegOpenKeyEx() so that the 4th parameter reads KEY_READ | KEY_WRITE?
[It could be that you also need to ask for the read permission when you are updating existing values]