I use code like this to enumerate all shader files in subdirectory shaders:
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
shader_counter = 1;
pclog("searching shader files \n");
hFind = FindFirstFile("shaders\\*.fx", &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
pclog("no shader files found \n");
}
else
{
pclog("shader files found \n");
while(hFind!=INVALID_HANDLE_VALUE)
{
pclog("Filename=%s\n",FindFileData.cFileName);
hFind = FindNextFile(hFind, &FindFileData);
shader_counter++;
}
pclog("Exit loop\n");
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
But it only outputs 3 files out of many and crashes. What am I doing wrong ?
Edit , this is correct code to enumerate subdirectory using wildcard , maybe someone will find it usefull:
HANDLE hFind;
WIN32_FIND_DATA FindFileData;
BOOL found = TRUE;
hFind = FindFirstFile("shaders\\*.fx", &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{ // directory/wildcard not found
}
else
{
while(found)
{
//printf("Filename=%s\n",FindFileData.cFileName);
found = FindNextFile(hFind, &FindFileData);
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
According to the Microsoft documentation, the return value to FindNextFile is not the same as for FindFirstFile. FindNextFile returns a boolean value:
...
BOOL found = TRUE;
printf("shader files found \n");
while (found)
{
printf("Filename=%s\n",FindFileData.cFileName);
found = FindNextFile(hFind, &FindFileData);
shader_counter++;
}
printf("Exit loop\n");
FindClose(hFind);
...
(It has to be an independent value, otherwise you would pass an invalid handle to FindClose.)
Related
I need to check if file is PE file or not. I need to check first two byte is MZ or not and I did this.
This is my task: When verifying the PE format, not only according to the MZ expression, but also using the conditions that the IMAGE_NT_HEADERS structure is read and the Signature field is verified by reading the IMAGE_FILE_HEADER field and the Machine field is equal to the Th value IMAGE_FILE_MACHINE_I386 or IMAGE_FILE_MACHINE_AMD64.
I cannot figure how can do the rest of them. I hope you can help me.
int checkPE(char *file){
int fd=open(file,READ_FLAGS,0777);
char buffer[TWOBYTE+1] = {'\0'};
size_t bytes_read;
char ch;
if(fd==-1){ //if file cannot be opened give a error message.
perror("The file cannot be opened.\n");
return -1;
}
bytes_read = read(fd,buffer,TWOBYTE);
if(bytes_read==-1){
perror("Error while reading file\n");
return -1;
}
if(strcmp(buffer,MZ)!=0){
return -1;
}
int closeFlag = close(fd);
if(closeFlag==-1){
perror("The file cannot be closed.\n");
return -1;
}
}
There is nothing more than just parsing some structures. You have already the algorithm. I assume that you just need the implementation. Consider the following example utility.
PS: For further details, just comment it below.
#include <stdio.h>
#include <windows.h>
BOOL CheckValidity(BYTE* baseAddress);
int main(int argc, char* argv[]) {
if (argc != 2)
{
printf("You didn't specified a PE file.\n");
printf("Usage: CheckPEImage.exe <Full path of PE File>\n");
return -1;
}
HANDLE hFile = CreateFileA(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE)
return -1;
HANDLE hMemoryMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (!hMemoryMap)
return -2;
PBYTE baseAddress = (PBYTE)MapViewOfFile(hMemoryMap, FILE_MAP_READ, 0, 0, 0);
if (!baseAddress)
return -3;
printf("PE Image is %s.\n", CheckValidity(baseAddress) ? "valid" : "invalid");
getchar();
return 0;
}
BOOL CheckValidity(BYTE* baseAddress)
{
PIMAGE_DOS_HEADER lpDosHeader;
PIMAGE_FILE_HEADER lpFileHeader;
PIMAGE_NT_HEADERS lpNtHeaders;
PIMAGE_OPTIONAL_HEADER lpOptionalHeader;
lpDosHeader = (PIMAGE_DOS_HEADER)baseAddress;
lpNtHeaders = (PIMAGE_NT_HEADERS)(baseAddress + lpDosHeader->e_lfanew);
if (lpDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
if (lpNtHeaders->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
if (lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 && lpNtHeaders->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
return FALSE;
return TRUE;
}
So, im writing a program to recursively print the directories/sub-directories and files in a given path. im able to go in the first sub-directory and print all the files in it. my problem right now is i need find a way to step back one directory level and continue from where i left off reading. Until the condition occurs at the original directory level.
#include "Everything.h"
#include "Strsafe.h"
WIN32_FIND_DATA ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
LARGE_INTEGER fileSize;
DWORD dwError;
void showdir(TCHAR *szDir);
int _tmain(int argc, LPCTSTR argv[])
{
TCHAR szDir[MAX_PATH];
size_t lengthOfArg;
// verify number of parameters
if (argc != 2)
{
ReportError(_T("Error: Incorrect number of arguments"), 1, FALSE);
}
// get the length of the entered directory
StringCchLength(argv[1], MAX_PATH, &lengthOfArg);
// verify that the directory path is not too long
if (lengthOfArg > MAX_PATH - 2)
{
ReportError(_T("Error: Directory too long"), 2, FALSE);
}
// attach an asterisk (wildcard search char) to end of directory path
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, _T("*"));
showdir(szDir);
}
void showdir(TCHAR *szDir)
{
// begin the search; find the first file in the directory
hFind = FindFirstFile(szDir, &ffd);
if (hFind == INVALID_HANDLE_VALUE)
{
ReportError(_T("Error in searching"), 3, TRUE);
}
//hFind = FindFirstFile(szDir, &ffd);
while (FindNextFile(hFind, &ffd) != 0)
{
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
fileSize.LowPart = ffd.nFileSizeLow;
fileSize.HighPart = ffd.nFileSizeHigh;
_tprintf(_T("%s %ld\n"), ffd.cFileName, fileSize.QuadPart);
}
// did we find a directory?
// ffd.dwFileAttributes says this is a directory (FILE_ATTRIBUTE_DIRECTORY)
if ((ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& (_tcscmp(ffd.cFileName, _T(".")) != 0 && (_tcscmp(ffd.cFileName, _T("..")) != 0)))
{
TCHAR fullpath[MAX_PATH];
StringCchCopy(fullpath, strlen(szDir) - 0, szDir);
StringCchCat(fullpath, MAX_PATH, ffd.cFileName);
StringCchCat(fullpath, MAX_PATH, "\\");
_tprintf(_T("<DIR> %s \n"), fullpath);
StringCchCat(fullpath, MAX_PATH, _T("*"));
showdir(fullpath);
}
// continue the search; try to find more files
}
// figure out if we encountered an error other than "no more files"
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
ReportError(_T("Error in searching"), 4, TRUE);
}
FindClose(hFind);
}
Your global variables
WIN32_FIND_DATA ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
LARGE_INTEGER fileSize;
DWORD dwError;
should all be local variables of showdir().
Then each recursion level has its own search handle, and when a nested showdir()
returns, the calling showdir() can simply continue enumerating its directory.
Note also that your code ignores the first file in each directory (the result
of FindFirstFile()). You could it rewrite as (error checking omitted for brevity):
hFind = FindFirstFile(szDir, &ffd);
do {
// ... handle ffd ...
} while (FindNextFile(hFind, &ffd))
I am trying to use zlib and minizip. When I build 6 projects in one soltuion which are included in archive I downloaded everything works and project will create exe files (minizip and miniunz). Here is the problem, I don't know how to use miniunz and minizip source codes in my application and google isn't helping. Can somebody, who has experience with these libs, provide step by step tutorial how to include these lib in my application?
Or if you have other libraries to work with password protected files and can provide some tutorial how to include it in project that will help too, I tried to find something but there was no tutorial how to install them to projects
Thanks
Code based on minizip unzip.c.
include stdio.h zip.h unzip.h
First, create a zip with a file inside with a password.
The zip file must be in the same directory as the executable.
Run the program from a prompt in the directory of the generated program.
This example only extracts the first file!
/*-----------start-------------- */
/*Tries to open the zip in the current directory.*/
unzFile zfile = unzOpen("teste.zip");
if(zfile==NULL)
{
printf("Error!");
return;
}
printf("OK Zip teste.zip opened...\n");
int err = unzGoToFirstFile(zfile);/*go to first file in zip*/
if (err != UNZ_OK)
{
printf("error %d with zipfile in unzGoToFirstFile\n", err);
unzClose(zfile);/*close zip*/
}
/*At this point zfile points to the first file contained in the zip*/
char filename_inzip[256] = {0};/* The file name will be returned here */
unz_file_info file_info = {0};/*strcuture with info of the first file*/
err = unzGetCurrentFileInfo(zfile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
}
else
{
int len = 8192;/*size of chunk*/
char buffer[8192]={0};/*buffer used to save uncompressed data*/
printf("name of first file is :%s\n",filename_inzip);
printf("uncompressed_size = %d\n",file_info.uncompressed_size);
/*Use your password here, the same one used to create your zip */
err = unzOpenCurrentFilePassword(zfile, "yourpassword");
if (err != UNZ_OK)
printf("error %d with zipfile in unzOpenCurrentFilePassword\n", err);
else
printf("password ok\n");
FILE *fp = fopen(filename_inzip, "wb");/*file for data binary type*/
if (fp != NULL)
{
do
{/*read the current file returned by unzGoToFirstFile to buffer in chunks of the 8192*/
err = unzReadCurrentFile(zfile, &buffer, len );
if (err < 0)
{
printf("error %d with zipfile in unzReadCurrentFile\n", err);
break;
}
if (err == 0)
break;
/*Save the chunk read to the file*/
if (fwrite(&buffer, err, 1, fp) != 1)/*if error break*/
{
printf("error %d in writing extracted file\n", errno);
err = UNZ_ERRNO;
break;
}/*else continue*/
}
while (err > 0);
/*close file*/
fclose(fp);
}
}
unzClose(zfile);
Code that I am running now:
int main(int argc, char *argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError;
LPSTR DirSpec;
size_t length_of_arg;
int i,j;
char cd[256],schar[500];
FILE *fp;
DirSpec = (LPSTR) malloc (BUFSIZE);
// Check for command-line parameter; otherwise, print usage.
if(argc != 2)
{
printf("Usage: Test <dir>\n");
return 2;
}
// Check that the input is not larger than allowed.
//scanf("%s",argv[1]);
StringCbLength(argv[1], BUFSIZE, &length_of_arg);
if (length_of_arg > (BUFSIZE - 2))
{
printf("Input directory is too large.\n");
return 3;
}
printf ("Target directory is %s.\n", argv[1]);
StringCbCopyN (DirSpec, BUFSIZE, argv[1], length_of_arg+1);
StringCbCatN (DirSpec, BUFSIZE, "\\namefile.b11", 18);
hFind = FindFirstFile(DirSpec, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("Invalid file handle. Error is %u.\n", GetLastError());
return (-1);
}
else
{
printf ("First file name is %s.\n", FindFileData.cFileName);
fp=fopen(DirSpec,"rb");
for(i=0;i< 8;i++)
{
schar[i]= fgetc(fp);//get each character from file
}
if ( i > 7 )
{
cd[i]=schar[6]*65336+schar[5]*256+schar[4];
printf("%d",cd[i]);
}
// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
{
printf ("Next file name is %s.\n", FindFileData.cFileName);
}
dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
printf ("FindNextFile error. Error is %u.\n", dwError);
return (-1);
}
}
free(DirSpec);
getchar();
return (0);
}
This is working fine. If I concatinate the file name directly by using StringCbCatN().
But for every file I need to change the file name.which I don't want. Is it possible to print the file with file extension?
I am using the Windows API and would like to be able to search through a specified directory and return the names of any files that reside within it.
I've made a start at it however i've hit a brick wall as i'm unsure of how to go any further.
Here is my progress so far:
#include <stdio.h>
#include <windows.h>
void main()
{
HANDLE fileHandle;
WIN32_FIND_DATAA fileData;
fileHandle = FindFirstFileA("*.txt", &fileData);
if(fileHandle != INVALID_HANDLE_VALUE)
{
printf("%s \n", fileData.cFileName);
}
}
You need to call FindNextFile in a loop to find all the files. There's a full example here, here are the interesting bits:
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
return dwError;
do
{
printf("%s\n"), ffd.cFileName);
}
while (FindNextFile(hFind, &ffd) != 0);
#include <stdio.h>
#include <windows.h>
void main()
{
HANDLE fileHandle;
WIN32_FIND_DATA ffd;
LARGE_INTEGER szDir;
WIN32_FIND_DATA fileData;
fileHandle = FindFirstFile("C:\\Users\\rest_of_the_Address\\*", &ffd);
if (INVALID_HANDLE_VALUE == fileHandle)
printf("Invalid File Handle Value \n");
do
{
printf("%s\n", ffd.cFileName);
} while (FindNextFile(fileHandle, &ffd) != 0);
system("pause");
}
You were missing some declarations, and had some syntax errors, fixed up here, and also, remember to check the msdn documentation (here is a msdn example for the program)