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;
}
Related
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 am trying to make a named Windows pipe in C. The pipe is used by a user and a server. The user sends trough the pipe a random int. Then the server searches in its current directory a file with the size greater or equal with the received int, and then sends back to the user the file name and a maximum of 100 bytes from the file.
My problem is that i don't know how to verify the size of every file from the directory, and then to return the filename and 100 bytes.
This is the function i'm trying to use for measuring a file size:
int fsize(char* file)
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
int len = (unsigned long)ftell(f);
fclose(f);
return len;
}
This is the "client" code:
#include <stdio.h>
#include <windows.h>
#define MAXLINIE 100
int main(int argc, char* argv[]) {
char rcvMsg[100];
char sndMsg[100];
DWORD rez;
HANDLE readHandle, writeHandle;
int r = rand();
char str[15];
sprintf(str, "%d", r);
writeHandle = CreateFile("\\\\.\\PIPE\\FirstPipe", GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
readHandle = CreateFile("\\\\.\\PIPE\\SecondPipe",GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL);
strcpy(sndMsg, r);
printf("Sending message to server: %s\n", sndMsg);
WriteFile(writeHandle, sndMsg, strlen(sndMsg), &rez, NULL);
printf("Message sent! Waiting for server to read the message!\n");
printf("Waiting for SERVER to write in the pipe...\n");
ReadFile(readHandle, rcvMsg, 100, &rez, NULL);
printf("Client revceived message: %s\n", rcvMsg);
CloseHandle(readHandle);
CloseHandle(writeHandle);
return 1;
}
This is the "server" code, excepting the file parsing part:
>
#include <stdio.h>
#include <windows.h>
#define MAXLINIE 100
//file lenght
int fsize(char* file)
{
FILE * f = fopen(file, "r");
fseek(f, 0, SEEK_END);
int len = (unsigned long)ftell(f);
fclose(f);
return len;
}
int main(int argc, char* argv[]) {
char rcvMsg[100];
char sndMsg[100];
DWORD rez;
HANDLE readHandle, writeHandle;
readHandle = CreateNamedPipe("\\\\.\\PIPE\\FirstPipe", PIPE_ACCESS_INBOUND,
PIPE_TYPE_BYTE|PIPE_WAIT,3,0,0,0,NULL);
writeHandle = CreateNamedPipe("\\\\.\\PIPE\\SecondPipe", PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE|PIPE_WAIT, 3, 0, 0, 0, NULL);
printf("Waiting for clients to connect...\n");
ConnectNamedPipe(writeHandle, NULL);
ConnectNamedPipe(readHandle, NULL);
printf("Waiting for a CLIENT to write in the pipe...\n");
ReadFile(readHandle, rcvMsg, 100, &rez, NULL);
printf("Server revceived message: %s\n", rcvMsg);
int num = atoi(rcvMsg); //the file lenght i'm looking for
//here i should process the files
strcpy(sndMsg, "File_name + 100 bytes");
printf("Server sends an answer: %s\n", sndMsg);
WriteFile(writeHandle, sndMsg, strlen(sndMsg), &rez, NULL);
printf("Waiting for client to read the message...\n");
// disconnecting and closing the handles
DisconnectNamedPipe(writeHandle);
CloseHandle(writeHandle);
DisconnectNamedPipe(readHandle);
CloseHandle(readHandle);
return 1;
}
FindFirstFile() and FindNextFile() to iterate through files... supports wildcards. When done call FindClose()
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx
Here is example code using FindFirstFile from cprogramming: (look in wfd struct for size attributes)
see other comments below code example
#include <stdio.h>
#include <string.h>
#include <windows.h>
void find(char* path,char* file) //Note: pass the path string appropriate for your scenario
{
static int found =0;
HANDLE fh;
WIN32_FIND_DATA wfd;
int i=0;
int j=0;
fh=FindFirstFile(path,&wfd);
if(fh)
{
if(strcmp(wfd.cFileName,file)==0)
{
path[strlen(path)-3]='\0';
strcat(path,file);
FindClose(fh);
return;
}
else
{
while(FindNextFile(fh,&wfd) && found ==0)
{
if(strcmp(wfd.cFileName,file)==0)
{
path[strlen(path)-3]='\0';
strcat(path,file);
FindClose(fh);
found =1;
return;
}
if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
strcmp(wfd.cFileName,"..")!=0 && strcmp(wfd.cFileName,".")!=0)
{
path[strlen(path)-3]='\0';
strcat(path,wfd.cFileName);
strcat(path,"\\*.*");
find(path,file);
}
}
if(found==0)
{
for(i=strlen(path)-1;i>0;i--)
{
if(j==1 && path[i]=='\\')
{
path[i]='\0';
strcat(path,"\\*.*");
break;
}
if(path[i]=='\\')
j=1;
}
}
}
FindClose(fh);
}
}
int main()
{
TCHAR path[512] = "C:\\*.*"; //Change this as necessary
find(path,"notepad.exe");
printf("%s\n",path);
return 0;
}
The file attributes will give you the file name, and size etc.
You can then write the 100 bytes to a char buffer by passing the name and path of the found file to fopen(): FILE *fp = fopen(fileNamePath, "r"); Then something like char buf[101];for(i=0;i<100;i++){buf[i] = fgetc(fp);}
***Don't forget to use fclose() when you are done with fp.
I'm trying to create an iterative program that reads all the folders from a specific starting folder using GSList and C. I haven't managed to find what the flaw in my code is for now.
The problem I'm having is that it reads each folder and all of it's subfolders until in reaches one with more subfolders. After that it just repeats to open only one directory.
The running result is below:
http://pastebin.com/jZMFBrxC
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
GSList *list = NULL;
list = g_slist_prepend(list, "/home/ravior/Documente"); /* Folder for searching */
DIR *d;
int index = 0;
while((char *)g_slist_nth_data(list, 0) != NULL) {
gchar *element = g_strdup((char *)g_slist_nth_data(list, 0));
d = opendir(element);
if(!d) {
fprintf(stderr, "Couldn't open '%s' : %s\n", (char *)g_slist_nth_data(list, 0), strerror(errno));
exit(EXIT_FAILURE);
}
printf("\n\nThe opened folder is: %s\n\n", (char *)g_slist_nth_data(list, 0));
while(TRUE) {
struct dirent *entry;
const char *d_name;
entry = readdir(d);
if(!entry) {
break;
}
d_name = entry->d_name;
/* Some code here... */
if(entry->d_type & DT_DIR && strcmp(d_name, "..") != 0 && strcmp(d_name, ".") != 0) {
int path_length;
static char path[PATH_MAX];
path_length = snprintf(path, PATH_MAX, "%s/%s",element, d_name);
if(path_length >= PATH_MAX) {
fprintf(stderr, "Path length has got too long.\n");
exit(EXIT_FAILURE);
}
printf("%s\n", path);
list = g_slist_append(list, path);
index++;
printf("The appended element is: %s\n", (char *)g_slist_nth_data(list, index));
}
}
if(closedir(d)){
fprintf(stderr, "Couldn't close' '%s': %s\n",(char *)g_slist_nth_data(list, 0), strerror(errno));
}
list = g_slist_remove(list, (char *)g_slist_nth_data(list, 0));
free(element);
element = NULL;
index--;
}
g_slist_free(list);
return EXIT_SUCCESS;
}
Any help to solve this is more than appreciated. Also, if you have any other implementation for this problem using C, sharing it will be more than appreciated.
I've managed to figure it out eventually.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <limits.h>
#include <errno.h>
#include <sys/types.h>
int main(int argc, char *argv[]) {
GSList *list = NULL;
list = g_slist_prepend(list, "/home/ravior/Documente"); /* Folder for searching */
DIR *d;
int index = 0;
while((char *)g_slist_nth_data(list, 0) != NULL) {
gchar *element = g_strdup((char *)g_slist_nth_data(list, 0));
d = opendir(element);
if(!d) {
fprintf(stderr, "Couldn't open '%s' : %s\n", element, strerror(errno));
exit(EXIT_FAILURE);
}
printf("\n\nThe opened folder is: %s\n\n", element);
while(TRUE) {
struct dirent *entry;
const char *d_name;
entry = readdir(d);
if(!entry) {
break;
}
d_name = entry->d_name;
/* Some code here... */
if(entry->d_type & DT_DIR && strcmp(d_name, "..") != 0 && strcmp(d_name, ".") != 0) {
int path_length;
static char path[PATH_MAX];
path_length = snprintf(path, PATH_MAX, "%s/%s",element, d_name);
if(path_length >= PATH_MAX) {
fprintf(stderr, "Path length has got too long.\n");
exit(EXIT_FAILURE);
}
printf("%s\n", path);
list = g_slist_append(list, strdup(path));
index++;
printf("The appended element is: %s\n", (char *)g_slist_nth_data(list, index));
}
}
if(closedir(d)){
fprintf(stderr, "Couldn't close' '%s': %s\n", element, strerror(errno));
}
list = g_slist_remove(list, (char *)g_slist_nth_data(list, 0));
free(element);
element = NULL;
index--;
}
g_slist_free(list);
return EXIT_SUCCESS;
}
I hope this piece of code will help someone in the future.
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]
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.