Introduction
This code helps us to list all the files and folders within a directory and sub-directory.
Background
The code should be written in win32 projects as a console application.
Code: C
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
//macro
#define DEFAULTSIZE 10
#define INTERNALTRAVERSING 1
#define FIRSTLEVELTRAVERSING 0
int main(int argc, char *argv[])
{
char* DirSpec;
int traversal;
char* substring;
// argv[1]="c:";
// argv[2]="/s";
// argc=2;
printf ("Target directory is %s.\n", argv[1]);
DirSpec=(char*)calloc ( strlen(argv[1])+1,sizeof(char))
strcpy(DirSpec,argv[1]);
printf("Name \t\t\t\t Dir/Size \t Created \t Attributes");
if(strcmp(argv[2],"/s")==0){
traversal=INTERNALTRAVERSING;
}else{
traversal=FIRSTLEVELTRAVERSING;
}
if(FindMatch(DirSpec)!=1){
if(GetFileAttributes(DirSpec)==FILE_ATTRIBUTE_DIRECTORY){
substring=NULL;
strcat(DirSpec,"\\*");
}else{
substring=GetSubstring(DirSpec);
}
}else{
substring=NULL;
}
WalkFolder(DirSpec,traversal,substring);
_getch();
free(DirSpec);
return (0);
}
void Display(WIN32_FIND_DATA *pFindFileData)
{
LPSYSTEMTIME lpst;
lpst=(LPSYSTEMTIME)calloc(1,sizeof(SYSTEMTIME)); //allocates memory for lpst.
FileTimeToSystemTime(&pFindFileData->ftCreationTime,lpst); //converts the time to system time.
if(pFindFileData->nFileSizeLow==0)
printf ("\n %s \t\t\t\t <Dir>\t\t ", pFindFileData->cFileName);
else
printf("\n %s \t %d \t ",pFindFileData->cFileName,pFindFileData->nFileSizeLow);
printf("%d/%d/%d %d:%d:%d \t ",lpst->wDay,lpst->wMonth,lpst->wYear,lpst->wHour,lpst->wMinute,lpst->wSecond);
PrintFileAttribute(pFindFileData->dwFileAttributes);
free(lpst); //frees the memory allocated for lpst.
}
void WalkFolder (char* pPath,BOOL pSub_folders,char* pSubstr)
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwError;
char ** allpath;
int index=0,i;
static int no_of_files=0;
static int no_of_folders=0;
printf("\n .................................................................");
printf("\n The display is for the path %s \n ", pPath);
allpath=(char **)calloc(DEFAULTSIZE,sizeof(char*));
hFind= INVALID_HANDLE_VALUE;
hFind = FindFirstFile(pPath, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE && pSub_folders!=INTERNALTRAVERSING ) {
printf ("Invalid file handle. Error is %u\n", GetLastError());
} else if(hFind!= INVALID_HANDLE_VALUE && pSubstr !=NULL){
PrintFileInfo(hFind,&FindFileData,&no_of_files);
}
if(pSubstr !=NULL && pSub_folders==INTERNALTRAVERSING){
RemoveSubString(pPath,pSubstr);
hFind = FindFirstFile(pPath, &FindFileData);
}
do{
if(pSubstr==NULL){
Display(&FindFileData);
}
if(FindFileData.nFileSizeLow==0 && (strcmp(FindFileData.cFileName,".")!=0)
&& (strcmp(FindFileData.cFileName,"..")!=0)&& pSub_folders==INTERNALTRAVERSING){
if((index+1)%DEFAULTSIZE==0 && index>0){
allpath=(char **)realloc(allpath,(index+DEFAULTSIZE));
}
allpath[index]=GetNewPath(pPath,FindFileData.cFileName,pSubstr);
index++;
}else if(FindFileData.nFileSizeLow!=0 && pSubstr==NULL){
no_of_files++;
}if(FindFileData.nFileSizeLow==0 ){
no_of_folders++;
}
}while (FindNextFile(hFind, &FindFileData) != 0 );
for(i=0;i<index;i++){
WalkFolder(allpath[i],pSub_folders,pSubstr);
}
dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
printf ("FindNextFile error. Error is %u\n", dwError);
}
}
char * GetNewPath(char* pPath,char *pFileName,char* pType)
{
char* path;
if(pType==NULL){
path=(char*)calloc(strlen(pPath)+strlen(pFileName)+1,sizeof(char));
}else{
path=(char*)calloc(strlen(pPath)+strlen(pFileName)+strlen(pType)+1,sizeof(char));
}
strcpy(path,pPath);
path[strlen(path)-1]='\0';
strcat(path,pFileName);
if(pType==NULL){
strcat(path,"\\*");
}else{
strcat(path,pType);
}
return path;
}
int FindMatch(char* pPath)
{
int i;
i=strlen(pPath)-1;
if(pPath[i]=='*'&& pPath[i-1]=='\\'){
return 1;
}
return 0;
}
char* GetSubstring(char* pPath)
{
char* substring;
int i;
int length;
for(i=strlen(pPath)-1;i>0;i--){
if(pPath[i]=='\\')
break;
}
length=strlen(pPath)+1-i;
substring=(char*)calloc(length,sizeof(char));
strcpy(substring,(pPath+i));
return substring;
}
void RemoveSubString(char *pPath,char* pSubstr)
{
int len;
len=strlen(pPath)-strlen(pSubstr)+4;
pPath=(char*)realloc(pPath,(len));
//len=strlen(pPath);
pPath[len-4]='\0';
strcat(pPath,"\\*.");
}
void PrintFileInfo(HANDLE hFind,WIN32_FIND_DATA *FindFileData,int *no_of_files)
{
do{
Display(FindFileData);
*no_of_files++;
}while(FindNextFile(hFind, FindFileData) != 0 );
}
void PrintFileAttribute(DWORD fileAttribute)
{
int index; ///< holds the index of attribute array
int flag; ///< holds the flag value
///< attribute array holds the file all attributes
int attribute[12] = {FILE_ATTRIBUTE_READONLY,
FILE_ATTRIBUTE_HIDDEN,
FILE_ATTRIBUTE_SYSTEM,
FILE_ATTRIBUTE_DIRECTORY,
FILE_ATTRIBUTE_ARCHIVE,
FILE_ATTRIBUTE_DEVICE,
FILE_ATTRIBUTE_NORMAL,
FILE_ATTRIBUTE_TEMPORARY,
FILE_ATTRIBUTE_SPARSE_FILE,
FILE_ATTRIBUTE_REPARSE_POINT,
FILE_ATTRIBUTE_COMPRESSED,
FILE_ATTRIBUTE_OFFLINE};
//Assign starting value zero to count
index =0;
//printf("\t");
//loop continue upto fileattribute greaterthan attribute[count]
while (fileAttribute >=(unsigned long) attribute[index]) {
//flag holds attribute value
flag = fileAttribute & attribute[index++];
switch (flag) {
//if the file attribute is readonly
case FILE_ATTRIBUTE_READONLY:
printf( "R ");
break;
//if the file attribute is hidden
case FILE_ATTRIBUTE_HIDDEN:
printf( "H ");
break;
//if the file attribute is system
case FILE_ATTRIBUTE_SYSTEM:
printf( "S ");
break;
//if the file attribute is archive
case FILE_ATTRIBUTE_ARCHIVE:
printf( "A ");
break;
//if the file attribute is device
case FILE_ATTRIBUTE_DEVICE:
printf( "D ");
break;
//if the file attribute is normal
case FILE_ATTRIBUTE_NORMAL:
printf( "N ");
break;
//if the file attribute is temporary
case FILE_ATTRIBUTE_TEMPORARY:
printf( "T ");
break;
//if the file attribute is sparse file
case FILE_ATTRIBUTE_SPARSE_FILE:
printf( "SF ");
break;
//if the file attribute is reparse point
case FILE_ATTRIBUTE_REPARSE_POINT:
printf( "RP ");
break;
//if the file attribute is compressed
case FILE_ATTRIBUTE_COMPRESSED:
printf( "C ");
break;
//if the file attribute is offline
case FILE_ATTRIBUTE_OFFLINE:
printf( "O ");
break;
}
}
}

