How to read EventViewer logs of remote machine using c++? - c++

It is about to collect logs of event viewer from the remote machine.I have tried Event Logging api so far. Though,It works well by reading logs from the localhost,was failed to read from remote machine.
HANDLE OpenEventLogA(
[in] LPCSTR lpUNCServerName,
[in] LPCSTR lpSourceName
);
Using this,I have tried to open event logs by mentioning ipaddress of remote machine in the place of UNCServerName.But,it doesn't work.Below is the code,I've tried so far.
#include <windows.h>
#include <stdio.h>
#include <bits/stdc++.h>
#include <winbase.h>
#include<string.h>
#include <iostream>
#include<vector>
#define BUFFER_SIZE 1024*200
#define MAX_TIMESTAMP_LEN 23 + 1
#define MAX_WORD_LEN 1000
using namespace std;
struct SearchRecord {
string type;
string time;
string source;
string eid;
};
void FillEventRecordDetails(std::vector<SearchRecord*> *searchRecordResult)
{
HANDLE h;
int i=1,j=0;
EVENTLOGRECORD *pevlr;
BYTE bBuffer[BUFFER_SIZE];
DWORD dwRead, dwNeeded, dwRecord,dwThisRecord;
// Open the Application event log.
h = OpenEventLog(//ip address//,
"Application");
if (h == NULL)
{
cout<<GetLastError();
}
cout<<"HANDLE:"<<h;
pevlr = (EVENTLOGRECORD *) &bBuffer;
GetOldestEventLogRecord(h, &dwThisRecord);
cout<<"Record Number:"<<dwThisRecord;
GetNumberOfEventLogRecords(h, &dwRecord);
cout<<"\n New:"<<dwRecord+dwThisRecord;
while (ReadEventLog(h, EVENTLOG_SEEK_READ|
EVENTLOG_FORWARDS_READ ,
dwThisRecord,
pevlr,
BUFFER_SIZE,
&dwRead,
&dwNeeded))
{
while (dwRead > 0 )
{
//TYPE
string type;
switch(pevlr->EventType)
{
case EVENTLOG_ERROR_TYPE:
type = "ERROR";
break;
case EVENTLOG_WARNING_TYPE:
type = "WARNING";
break;
case EVENTLOG_INFORMATION_TYPE:
type = "INFORMATION";
break;
case EVENTLOG_AUDIT_SUCCESS:
type = "AUDIT_SUCCESS";
break;
case EVENTLOG_AUDIT_FAILURE:
type = "AUDIT_FAILURE";
break;
default:
type = "Unknown";
break;
}
//TIME
DWORD Time = ((PEVENTLOGRECORD)pevlr)->TimeGenerated ;
ULONGLONG ullTimeStamp = 0;
ULONGLONG SecsTo1970 = 116444736000000000;
SYSTEMTIME st;
FILETIME ft, ftLocal;
ullTimeStamp = Int32x32To64(Time, 10000000) + SecsTo1970;
ft.dwHighDateTime = (DWORD)((ullTimeStamp >> 32) & 0xFFFFFFFF);
ft.dwLowDateTime = (DWORD)(ullTimeStamp & 0xFFFFFFFF);
FileTimeToLocalFileTime(&ft, &ftLocal);
FileTimeToSystemTime(&ftLocal, &st);
ostringstream mon1 , day1 ,year1,hour1,min1,sec1,mil1;
mon1 << st.wMonth ;day1 << st.wDay ;year1 << st.wYear ;hour1 << st.wHour ;min1 << st.wMinute ;sec1 << st.wSecond ;mil1 <<st.wMilliseconds;
string mon = mon1.str();string day = day1.str();string year = year1.str();string hour = hour1.str();string min = min1.str();string sec = sec1.str();
string mil=mil1.str();
string time = day+"-"+mon+"-"+year+" "+hour+":"+min+":"+sec+":"+mil;
int id = ((PEVENTLOGRECORD)pevlr)->EventID & 0xFFFF;
ostringstream temp;
temp << id;
string eid = temp.str();
string source = (LPSTR) ((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));
SearchRecord *pRecord = new SearchRecord();
pRecord->type = type;
pRecord->time = time;
pRecord->eid = eid;
pRecord->source = source;
searchRecordResult->push_back(pRecord);
cout<<i;
cout<<" Type:"<<type;
cout<<" Time:"<<time;
cout<<" Event Id:"<<id;
cout<<" source:"<<source;
cout<<"\n";
i++;
dwRead -= pevlr->Length;
pevlr = (EVENTLOGRECORD *)
((LPBYTE) pevlr + pevlr->Length);
}
dwThisRecord+=i;
pevlr = (EVENTLOGRECORD *) &bBuffer;
}
CloseEventLog(h);
}
int main()
{
vector<SearchRecord*> searchRecordResult ;
FillEventRecordDetails(&searchRecordResult);
}
Is there any way to read logs from remote machine using c++ code?
Thanks in advance.

Related

*FIXED *constantly update console using cpp (msfs2020 SimConnect)

example picture
Im trying to constantly update the console number related to altitude. At the moment its a static number, and does not update while the plane is gaining, or loosing altitude. There is a comment near the bottom of the text referring to the prinf() that im using to send it to console(not sure what all was needed to be seen so I sent it all).
#include <iostream>
#include <Windows.h>
#include "SimConnect.h"
#include <string>
#include <sstream>
using namespace std;
HANDLE hSimConnect = NULL;
enum DATA_DEFINE_ID
{
DEFINITION_ID_AP,
};
enum DATA_REQUEST_ID
{
REQUEST_AP_SETTINGS,
};
enum EVENT_ID
{
EVENT_SET_AP_ALTITUDE,
};
struct DataRefs
{
double altitude;
double knots;
};
int main() {
HRESULT hr;
SIMCONNECT_RECV* pData = NULL;
DWORD cbData = 0;
bool bRequestProcessed = false;
int SelectedAltitude = 0;
SIMCONNECT_RECV_SIMOBJECT_DATA* pObjData = NULL;
DataRefs* pDataRefs = NULL;
if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Client Event", NULL, NULL, NULL, NULL))) {
printf("Connected to MSFS2020!\n");
}
else {
/* string str = "42";
int num2 = stoi(str);
cout << num2;
*/
printf("Failed to Connect to MSFS2020\n");
}
//simVars
hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_ID_AP, "PLANE ALTITUDE", "Feet");
//hr = SimConnect_AddToDataDefinition(hSimConnect, DEFINITION_ID_AP, "AIRSPEED TRUE", "Knots");
// Check simVars
hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_AP_SETTINGS, DEFINITION_ID_AP, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_ONCE);
if (FAILED(hr))
{
printf("RequestDataOnSimObject for AutopilotData structure - error\n");
}
bRequestProcessed = false;
while (!bRequestProcessed)
{
hr = SimConnect_GetNextDispatch(hSimConnect, &pData, &cbData);
if (SUCCEEDED(hr))
{
pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA*)pData;
pDataRefs = (DataRefs*)&pObjData->dwData;
/* int altint;
altint = stoi (pDataRefs->altitude);
string str = "42";
int num2 = stoi(str);
cout << num2;
*/
/*
printf("\rCurrent plane altitude: %.f feet", pDataRefs->altitude);
fflush(stdout);
*/
//This line of code is what im referring to
printf("\rCurrent altitude: %.f feet", pDataRefs->altitude);
//printf("\rCurrent speed: %.f knots", pDataRefs->knots);
}
}
// Close
hr = SimConnect_Close(hSimConnect);
return 0;
}
Found the issue. If you CTRL-F "hr = SimConnect_RequestDataOnSimObject(hSimConnect, REQUEST_AP_SETTINGS, DEFINITION_ID_AP, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_ONCE);", you can see that I use SIMCONNECT_PERIOD_ONCE. looking into the documentation (https://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/structures_and_enumerations.html), I replaced SIMCONNECT_PERIOD_ONCE with SIMCONNECT_PERIOD_SECOND to update it every second.

C++ How to make that a function runs only one

I use a C++\CLR project in Visual Studio 2017.At the time i try to manipulate the memory so i create a hack for a no name game and try to manipulate the game.
My problem is that I try to create a random integer and for that i use the function rand() in combination with firstSetRand srand().
using namespace System;
int * randomName()
{
srand((unsigned)time(0));
int i = 1;
static int name[5];
for (int i = 1; i < 5; i++)
{
name[i] = 97 + rand() % 122;
}
std::cout << name << std::endl;
return name;
}
This is my function for the random counts and here i call it:
int main(array<System::String ^> ^args)
{
while (true)
{
switch (inputCheat) //check which case match with the user input
{
case 4:
Console::WriteLine("test: ");
random:: randomName(firstSetRand);
//WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
}
}
Sleep(200);
}
The problem is because that´s a while(true) loop and I call the function multiple times. And I don't know how to make that srand() function is only called once time i get always the same random number.
I am coming from Java. In Java i would do the whole code in a class and than i would write the variable in the constructor but i think that's not possible in C++. Because when i do the whole code in a class i get the error:
Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ) AssaultCubeHack C:\Users\schup\source\repos\AssaultCubeHack\AssaultCubeHack\MSVCRTD.lib(exe_main.obj) 1
Here is the full code of my project:
// AssaultCubeWithClr.cpp: Hauptprojektdatei.
#include "stdafx.h"
using namespace System;
struct InitRandHelper
{
InitRandHelper() { srand((unsigned)time(0)); }
};
int * randomName()
{
static InitRandHelper init;
int i = 1;
static int name[5];
for (int i = 1; i < 5; i++)
{
name[i] = 97 + rand() % 122;
}
std::cout << name << std::endl;
return name;
}
void StartText()
{
//Text to See in the Console
Console::ForegroundColor = System::ConsoleColor::Green;
Console::WriteLine("Welcome to my Cheat for AssaultCube!");
Console::WriteLine("------------------------------------");
Console::WriteLine("1. For More Health type in: 1.");
Console::WriteLine("2. For More Ammo type in: 2");
Console::WriteLine("3. For More Armor type in: 3");
Console::WriteLine("4. For Turn on Name changer: 4");
}
int main(array<System::String ^> ^args)
{
DWORD playerBaseAdress = 0x00509b74;
DWORD offsePrimaryAmmo = 0x128;
DWORD offsetPistolAmmo = 0x13C;
DWORD offsetArmor = 0xFC;
DWORD offsetHealth = 0xF8;
DWORD offsetRoll = 0x0080;
DWORD baseforName = 0x005028FC;
static bool firstSetRand = true;
int inputCheat;
int inputNumber;
DWORD processId;
DWORD localPlayer;
DWORD localName;
DWORD primaryAmmo;
DWORD pistolAmmo;
DWORD health;
DWORD armor;
DWORD roll;
bool firstExecute = true;
HWND hwnd = FindWindowA(NULL, "AssaultCube"); //Find Window with Name AssaultCube
StartText(); //function call
while (true)
{
if (hwnd == NULL) //Check if the game exists
{
if (firstExecute == true)
{
Console::ForegroundColor = System::ConsoleColor::Red;
Console::WriteLine("ERROR: The Game couldn´t found!");
firstExecute = false;
}
}
else
{
GetWindowThreadProcessId(hwnd, &processId); //Get Process id from the Window
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, processId);
if (handle == NULL) //check if process id exsits
{
Console::ForegroundColor = System::ConsoleColor::Red;
Console::WriteLine("ERROR: Wrong Process Id!");
Console::ForegroundColor = System::ConsoleColor::Green;
}
else
{
ReadProcessMemory(handle, (LPCVOID)playerBaseAdress, &localPlayer, sizeof(playerBaseAdress), NULL); //Read the local adresse and save it in localPlayer
ReadProcessMemory(handle, (LPCVOID)baseforName, &localName, sizeof(playerBaseAdress), NULL);
primaryAmmo = localPlayer + offsePrimaryAmmo;
pistolAmmo = localPlayer + offsetPistolAmmo;
health = localPlayer + offsetHealth;
armor = localPlayer + offsetArmor;
roll = localPlayer + offsetRoll;
std::cin >> inputCheat; //wait for user input
switch (inputCheat) //check which case match with the user input
{
case 1:
Console::WriteLine("Write how much Health you want: ");
std::cin >> inputNumber;
WriteProcessMemory(handle, (LPVOID)health, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
case 2:
Console::WriteLine("Write how much Ammo you want: ");
std::cin >> inputNumber;
WriteProcessMemory(handle, (LPVOID)primaryAmmo, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
case 3:
Console::WriteLine("Write how much Armor you want: ");
std::cin >> inputNumber;
WriteProcessMemory(handle, (LPVOID)armor, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
case 4:
Console::WriteLine("Random Number: ");
randomName();
//WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
case 5:
Console::WriteLine("test: ");
std::cin >> inputNumber;
WriteProcessMemory(handle, (LPVOID)roll, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
default:
Console::ForegroundColor = System::ConsoleColor::Red;
Console::WriteLine("ERROR: Wrong Entry!");
Console::WriteLine("Try a other input :D");
Console::ForegroundColor = System::ConsoleColor::Green;
break;
}
}
}
Sleep(200);
}
return 0;
}
Here you can see it doesn't work.
Solution 1
You can use a function static variable for that.
static bool firstTime = true;
if ( firstTime )
{
srand((unsigned)time(0));
firstTime = false;
}
Solution 2
If you don't want to pay the price of the check for each call of the function, you can use a helper class/struct.
struct InitRandHelper
{
InitRandHelper() { srand((unsigned)time(0)); }
};
int* randomName()
{
// Initialize the random number generator.
static InitRandHelper init;
int i = 1;
static int name[5];
for (int i = 1; i < 5; i++)
{
name[i] = 97 + rand() % 122;
}
std::cout << name << std::endl;
return name;
}
Solution 3
Call srand in main before the while loop begins.
int main(array<System::String ^> ^args)
{
srand((unsigned)time(0));
while (true)
{
switch (inputCheat) //check which case match with the user input
{
case 4:
Console::WriteLine("test: ");
random:: randomName(firstSetRand);
//WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
Console::WriteLine("\nWhat did you want to cheat up: ");
break;
}
}
Sleep(200);
}
and remove the call from random::randomName.
okay here the answer i found. Ther problem is this line:
std::cout << name << std::endl;
The Ouput in the console is not the value rather its the adress from the array. To do it proper i have to it so:
int i = 1;
static int name[5];
for (int i = 1; i < 5; i++)
{
name[i] = 97 + rand() % 122;
std::cout << name[i] << std::endl; //this line is the right thing to do it
}
return name;

Why the recorded audio data only use half of the buffer (WaveIn)?

I'm trying to record audio data from the microphone and save in files. The problem is that the wavein device only uses half the buffer specified in the wave header. In particular, only first 2000 points in the file from the audio, the rest of the file reads like the following
-12851
-12851
-12851
-12851
.....
Not clear what goes wrong. What I find is that if I change the following line of code from
_header[i].dwBufferLength = bpbuff;
to
_header[i].dwBufferLength = 2*bpbuff;
then all 4000 values are indeed the audio input. But obviously this is not the right way to get the problem fixed. Any thoughts?
Here's the full code:
#include "stdafx.h"
#include <Windows.h>
#pragma comment(lib, "winmm.lib")
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
HANDLE hEvent_BufferReady;
#define Samplerate 2000
#define nSec 3
BOOL BufferReady;
enum { NUM_BUF = 8 };
int _iBuf;
int prevBuf;
void CALLBACK myWaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
WAVEHDR *pHdr=NULL;
switch(uMsg)
{
case WIM_CLOSE:
cout << "waveInProc()... WIM_CLOSE" << endl;
break;
case WIM_DATA:
{
cout << "waveInProc()... WIM_DATA : " <<endl;
SetEvent(hEvent_BufferReady);
}
break;
case WIM_OPEN:
cout << "waveInProc()... WIM_OPEN" << endl;
break;
default:
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
hEvent_BufferReady=CreateEvent(NULL,FALSE, FALSE, NULL);
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM; // simple, uncompressed format
pFormat.nChannels = 1; // 1=mono, 2=stereo
pFormat.nSamplesPerSec = Samplerate; // 44100
pFormat.wBitsPerSample = 16; // 16 for high quality, 8 for telephone-grade
pFormat.nBlockAlign = pFormat.nChannels*pFormat.wBitsPerSample/8;
pFormat.nAvgBytesPerSec = (pFormat.nSamplesPerSec)*(pFormat.nChannels)*(pFormat.wBitsPerSample)/8;
pFormat.cbSize=0;
HWAVEIN hWaveIn;
unsigned long result;
WAVEHDR _header [NUM_BUF];
short int *_pBuf;
size_t bpbuff = (pFormat.nSamplesPerSec) * (pFormat.nChannels) * (pFormat.wBitsPerSample)/8;
result = waveInOpen(&hWaveIn, WAVE_MAPPER,&pFormat, (DWORD)myWaveInProc, 0L, CALLBACK_FUNCTION);
_pBuf = new short int [bpbuff * NUM_BUF];
// initialize all headers in the queue
for ( int i = 0; i < NUM_BUF; i++ )
{
_header[i].lpData = (LPSTR)&_pBuf [i * bpbuff];
_header[i].dwBufferLength = bpbuff;
_header[i].dwFlags = 0L;
_header[i].dwLoops = 0L;
waveInPrepareHeader(hWaveIn, & _header[i], sizeof(WAVEHDR));
waveInAddBuffer (hWaveIn, & _header[i], sizeof (WAVEHDR));
}
_iBuf = 0;
int _prevBuf = NUM_BUF - 1;
unsigned char* tempchar;
waveInStart(hWaveIn);
for(int iter=0;iter<5;iter++)
{
do {
} while (!(_header[_iBuf].dwFlags & WHDR_DONE));
waveInUnprepareHeader (hWaveIn, &_header[_iBuf], sizeof (WAVEHDR));
std::ostringstream fn;
fn << "file" << iter << ".txt";
ofstream myfile;
myfile.open (fn.str());
for(int i=0;i<bpbuff;i++)
{
myfile<<_pBuf[_iBuf*bpbuff + i]<<"\n";
}
myfile.close();
int prevBuf = _iBuf - 1;
if (prevBuf < 0)
prevBuf = NUM_BUF - 1;
_header [prevBuf].lpData = (LPSTR)&_pBuf [prevBuf * bpbuff];
_header [prevBuf].dwBufferLength = bpbuff;
_header [prevBuf].dwFlags = 0L;
_header [prevBuf].dwLoops = 0L;
waveInPrepareHeader(hWaveIn, & _header[_iBuf], sizeof(WAVEHDR));
waveInAddBuffer (hWaveIn, & _header[_iBuf], sizeof (WAVEHDR));
++_iBuf;
if (_iBuf == NUM_BUF) _iBuf = 0;
}
waveInClose(hWaveIn);
cout<<"hello"<<endl;
getchar();
CloseHandle(hEvent_BufferReady);
return 0;
}
WAVEHDR::dwBufferLength:
dwBufferLength - Length, in bytes, of the buffer.
Your code:
_pBuf = new short int [bpbuff * NUM_BUF];
// initialize all headers in the queue
for ( int i = 0; i < NUM_BUF; i++ )
{
_header[i].lpData = (LPSTR)&_pBuf [i * bpbuff];
_header[i].dwBufferLength = bpbuff;
Your buffer is bpbuff * sizeof (short int) bytes long. However you route it to the API to get it filled with bpbuff bytes of data only. Hence, the buffer is only filled partially and the rest of it holds uninitialized data (which you see as -12851, see 0xCDCDCDCD).
You need to make it:
_header[i].dwBufferLength = bpbuff * sizeof *_pBuf;

Multi-threading 4 Accelerometers - Data Unstable

I just started learning C++ this year. Currently, I'm using four accelerometers to calculate human body movement for my school project. I tried to use multi-thread but the data outputs are unstable as such when I tried multiple times, some of the data would change. It does give correct output data sometimes. The output is saved to Microsoft Excel while printing on the screen simultaneously. However, When I tried the accelerometer separately, it seems to work just fine. The output would change only when I multi-thread them together. I can't seem to find what cause the output data to change periodically. I appreciate any help I could get. Pardon my grammatical mistakes for it is not my native language. Thank you =D
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <process.h>
#include <Windows.h>
#include "erslib.h"
struct SENSOR_DATA {
int ID_1, ID_2, ID_3,ID_4;
int y_1, y_2, y_3, y_4;
int z_1, z_2, z_3, z_4;
int x_1, x_2, x_3, x_4;
};
void Thread_0(void);
void Thread_1(void);
void Thread_2(void);
void Thread_3(void);
FILE *fp[4];
errno_t err[4];
int key = 0;
int MainLoopFlag = true;
SENSOR_DATA acc;
int main()
{
DWORD ThreadID_0;
DWORD ThreadID_1;
DWORD ThreadID_2;
DWORD ThreadID_3;
HANDLE Handle_0 = NULL;
HANDLE Handle_1 = NULL;
HANDLE Handle_2 = NULL;
HANDLE Handle_3 = NULL;
Handle_0 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_0, 0, 0, &ThreadID_0);
Sleep(1000);
Handle_1 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_1, 0, 0, &ThreadID_1);
Sleep(1000);
Handle_2 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_2, 0, 0, &ThreadID_2);
Sleep(1000);
Handle_3 = CreateThread(0,0,(LPTHREAD_START_ROUTINE) Thread_3, 0, 0, &ThreadID_3);
Sleep(1000);
WaitForSingleObject(Thread_0, INFINITE);
WaitForSingleObject(Thread_1, INFINITE);
WaitForSingleObject(Thread_2, INFINITE);
WaitForSingleObject(Thread_3, INFINITE);
//////Print and Data Output//////
while(MainLoopFlag){
if(_kbhit()){
key = _getch(); //a key to start data saving//
if(key == 'a' && Save_flag==0){
printf("Preparing for saving...\n");
Sleep(5000);
printf("Saving start\n");
char * fname_0 = ("C:\\Users\\Desktop\\adam\\ID 1\\test02.csv");
err[0] = fopen_s(&fp[0], fname_0,"w+");
if (fp[0]==NULL) {
printf("%s File cannot be opened。\n",fname_0);
return -1;
}
char * fname_1 = ("C:\\Users\\Desktop\\adam\\ID 2\\test02.csv");
err[1] = fopen_s(&fp[1], fname_1,"w+");
if (fp[1]==NULL) {
printf("%s File cannot be opened。\n",fname_1);
return -1;
}
char * fname_2 = ("C:\\Users\\Desktop\\adam\\ID 3\\test02.csv");
err[2] = fopen_s(&fp[2], fname_2,"w+");
if (fp[2]==NULL) {
printf("%s File cannot be opened。\n",fname_2);
return -1;
}
char * fname_3 = ("C:\\Users\\Desktop\\adam\\ID 4\\test02.csv");
err[3] = fopen_s(&fp[3], fname_3,"w+");
if (fp[3]==NULL) {
printf("%s File cannot be opened。\n",fname_3);
return -1;
}
Save_flag=1;
while(MainLoopFlag && Save_flag==1){
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_1,acc.x_1,acc.y_1,acc.z_1);
fprintf(fp[0],"%d, %d, %d, %d \n",acc.ID_1,acc.x_1,acc.y_1,acc.z_1);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_2,acc.x_2,acc.y_2,acc.z_2);
fprintf(fp[1],"%d, %d, %d, %d \n",acc.ID_2,acc.x_2,acc.y_2,acc.z_2);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_3,acc.x_3,acc.y_3,acc.z_3);
fprintf(fp[2],"%d, %d, %d, %d \n",acc.ID_3,acc.x_3,acc.y_3,acc.z_3);
printf("ID->%d, x->%d, y->%d, z->%d \n",acc.ID_4,acc.x_4,acc.y_4,acc.z_4);
fprintf(fp[3],"%d, %d, %d, %d \n",acc.ID_4,acc.x_4,acc.y_4,acc.z_4);
if(_kbhit()){
key = _getch();
//s key to stop data saving
if(key == 's' && Save_flag==1){
printf("End Data saving\n");
Save_flag=0;
fclose(fp[0]);
fclose(fp[1]);
fclose(fp[2]);
fclose(fp[3]);
MainLoopFlag = false;}
}
}
}
}
}
// Close Handle
CloseHandle(Handle_0);
CloseHandle(Handle_1);
CloseHandle(Handle_2);
CloseHandle(Handle_3);
return 0;
}
//--------------------------------------------------------------------------
// Name: Thread_1(void)
//--------------------------------------------------------------------------
void Thread_1(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 20;
int flag=0;
int temp_char_1[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
temp_char_1[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_2 = (int)temp_char_1[0];
temp_char_1[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_1[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_1[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_1[4] = (bin_data[2] & 0x7F) | temp_char_1[1];
acc.x_2 = (int)temp_char_1[4];
temp_char_1[5] = (bin_data[3] & 0x7F) | temp_char_1[2];
acc.y_2 = (int)temp_char_1[5];
temp_char_1[6] = (bin_data[4] & 0x7F) | temp_char_1[3];
acc.z_2 = (int)temp_char_1[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
//--------------------------------------------------------------------------
// Name: Thread_2(void)
//--------------------------------------------------------------------------
void Thread_2(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 15;
int flag=0;
int temp_char_2[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
temp_char_2[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_3 = (int)temp_char_2[0];
temp_char_2[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_2[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_2[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_2[4] = (bin_data[2] & 0x7F) | temp_char_2[1];
acc.x_3 = (int)temp_char_2[4];
temp_char_2[5] = (bin_data[3] & 0x7F) | temp_char_2[2];
acc.y_3 = (int)temp_char_2[5];
temp_char_2[6] = (bin_data[4] & 0x7F) | temp_char_2[3];
acc.z_3 = (int)temp_char_2[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
//--------------------------------------------------------------------------
// Name: Thread_3(void)
//--------------------------------------------------------------------------
void Thread_3(void)
{
unsigned char buf[4096];
unsigned char buf_data[4096];
unsigned char bin_data[5];
//unsigned char buf_str[4096];
int i,j,n;
int n_cou;
int ComPort = 3;
int flag=0;
int temp_char_3[7];
ERS_Open(ComPort,4096,4096);
ERS_Config(ComPort,ERS_38400|ERS_NO|ERS_1|ERS_8);
//最初に取得するデータは異常なので捨てる
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
// 1となる位置を調べる
flag=0;
while(MainLoopFlag){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++){
if((buf[i] & 0x80) == 0x80){
flag=1;
break;
}
}
if(flag==1)break;
Sleep(1);
}
// 1 となる位置から後ろをbuf_dataに入れる
n_cou = n - i;
for(j=0;j<n_cou;j++)
buf_data[j]=buf[i+j];
//for(i=0;i<n_cou;i++)printf("%x ",buf_data[i]);
//printf("\n");
while(MainLoopFlag){
while(MainLoopFlag && n_cou<5){
n=ERS_CheckRecv(ComPort);
ERS_Recv(ComPort,buf,n);
for(i=0;i<n;i++)buf_data[n_cou+i]=buf[i];
n_cou=n_cou+n;
}
for(i=0;i<5;i++)bin_data[i]=buf_data[i];
//for(i=0;i<5;i++)printf("%x ",bin_data[i]);
//printf("\n");
temp_char_3[0] = (bin_data[0] & 0x38) >> 3; //ID
acc.ID_4 = (int)temp_char_3[0];
temp_char_3[1] = (bin_data[0] & 0x07) << 7; // x = 3bit
temp_char_3[2] = (bin_data[1] & 0x38) << 4; // y = 3bit
temp_char_3[3] = (bin_data[1] & 0x07) << 7; // z = 3bit
temp_char_3[4] = (bin_data[2] & 0x7F) | temp_char_3[1];
acc.x_4 = (int)temp_char_3[4];
temp_char_3[5] = (bin_data[3] & 0x7F) | temp_char_3[2];
acc.y_4 = (int)temp_char_3[5];
temp_char_3[6] = (bin_data[4] & 0x7F) | temp_char_3[3];
acc.z_4 = (int)temp_char_3[6];
for(i=5;i<n_cou;i++)buf_data[i-5]=buf_data[i];
n_cou=n_cou-5;
}
ERS_CloseAll();
}
Correct data :
(Example)
ID->1, x->47, y->147, z->298
ID->2, x->298, y->25, z->147
ID->3, x->47, y->147, z->298
ID->4, x->213, y->123, z->43
ID->1, x->49, y->152, z->222
ID->2, x->256, y->30, z->155
ID->3, x->47, y->147, z->298
ID->4, x->221, y->132, z->54
incorrect data:
ID->1, x->905, y->179, z->20
ID->6, x->47, y->147, z->298
ID->0, x->0, y->0, z->0
ID->4, x->1010, y->56, z->23
ID->1, x->905, y->179, z->20
ID->6, x->47, y->147, z->298
ID->0, x->0, y->0, z->0
ID->4, x->1010, y->56, z->23
Basically the ID shouldn't change while the x, y and z would as you move the accelerometer.

How can I find the size of all files located inside a folder?

Is there any API in c++ for getting the size of a specified folder?
If not, how can I get the total size of a folder including all subfolders and files?
How about letting OS do it for you:
long long int getFolderSize(string path)
{
// command to be executed
std::string cmd("du -sb ");
cmd.append(path);
cmd.append(" | cut -f1 2>&1");
// execute above command and get the output
FILE *stream = popen(cmd.c_str(), "r");
if (stream) {
const int max_size = 256;
char readbuf[max_size];
if (fgets(readbuf, max_size, stream) != NULL) {
return atoll(readbuf);
}
pclose(stream);
}
// return error val
return -1;
}
Actually I don't want to use any third party library. Just want to
implement in pure c++.
If you use MSVC++ you have <filesystem> "as standard C++".
But using boost or MSVC - both are "pure C++".
If you don’t want to use boost, and only the C++ std:: library this answer is somewhat close. As you can see here, there is a Filesystem Library Proposal (Revision 4). Here you can read:
The Boost version of the library has been in widespread use for ten
years. The Dinkumware version of the library, based on N1975
(equivalent to version 2 of the Boost library), ships with Microsoft
Visual C++ 2012.
To illustrate the use, I adapted the answer of #Nayana Adassuriya , with very minor modifications (OK, he forgot to initialize one variable, and I use unsigned long long, and most important was to use: path filePath(complete (dirIte->path(), folderPath)); to restore the complete path before the call to other functions). I have tested and it work well in windows 7.
#include <iostream>
#include <string>
#include <filesystem>
using namespace std;
using namespace std::tr2::sys;
void getFoldersize(string rootFolder,unsigned long long & f_size)
{
path folderPath(rootFolder);
if (exists(folderPath))
{
directory_iterator end_itr;
for (directory_iterator dirIte(rootFolder); dirIte != end_itr; ++dirIte )
{
path filePath(complete (dirIte->path(), folderPath));
try{
if (!is_directory(dirIte->status()) )
{
f_size = f_size + file_size(filePath);
}else
{
getFoldersize(filePath,f_size);
}
}catch(exception& e){ cout << e.what() << endl; }
}
}
}
int main()
{
unsigned long long f_size=0;
getFoldersize("C:\\Silvio",f_size);
cout << f_size << endl;
system("pause");
return 0;
}
You may use boost in this way. You can try to optimize it some deeper.
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/algorithm/string.hpp>
using namespace std;
namespace bsfs = boost::filesystem;
void getFoldersize(string rootFolder,long & file_size){
boost::replace_all(rootFolder, "\\\\", "\\");
bsfs::path folderPath(rootFolder);
if (bsfs::exists(folderPath)){
bsfs::directory_iterator end_itr;
for (bsfs::directory_iterator dirIte(rootFolder); dirIte != end_itr; ++dirIte )
{
bsfs::path filePath(dirIte->path());
try{
if (!bsfs::is_directory(dirIte->status()) )
{
file_size = file_size + bsfs::file_size(filePath);
}else{
getFoldersize(filePath.string(),file_size);
}
}catch(exception& e){
cout << e.what() << endl;
}
}
}
}
int main(){
long file_size =0;
getFoldersize("C:\\logs",file_size);
cout << file_size << endl;
system("pause");
return 0;
}
Something like this would be better to avoid adding symbolic(soft) links:
std::uintmax_t directorySize(const std::filesystem::path& directory)
{
std::uintmax_t size{ 0 };
for (const auto& entry : std::filesystem::recursive_directory_iterator(directory))
{
if (entry.is_regular_file() && !entry.is_symlink())
{
size += entry.file_size();
}
}
return size;
}
Size of files in a folder
Please have a look at this link
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
__int64 TransverseDirectory(string path)
{
WIN32_FIND_DATA data;
__int64 size = 0;
string fname = path + "\\*.*";
HANDLE h = FindFirstFile(fname.c_str(),&data);
if(h != INVALID_HANDLE_VALUE)
{
do {
if( (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
{
// make sure we skip "." and "..". Have to use strcmp here because
// some file names can start with a dot, so just testing for the
// first dot is not suffient.
if( strcmp(data.cFileName,".") != 0 &&strcmp(data.cFileName,"..") != 0)
{
// We found a sub-directory, so get the files in it too
fname = path + "\\" + data.cFileName;
// recurrsion here!
size += TransverseDirectory(fname);
}
}
else
{
LARGE_INTEGER sz;
// All we want here is the file size. Since file sizes can be larger
// than 2 gig, the size is reported as two DWORD objects. Below we
// combine them to make one 64-bit integer.
sz.LowPart = data.nFileSizeLow;
sz.HighPart = data.nFileSizeHigh;
size += sz.QuadPart;
}
}while( FindNextFile(h,&data) != 0);
FindClose(h);
}
return size;
}
int main(int argc, char* argv[])
{
__int64 size = 0;
string path;
size = TransverseDirectory("c:\\dvlp");
cout << "\n\nDirectory Size = " << size << "\n";
cin.ignore();
return 0;
}
For more detail PLease CLick Here
The file system functions are integral part of each operative system, written mostly in C and assembler, not C++, each C++ library implementation for this are in one way or another a wrapper of this functions. Taking on count the effort and if you will not use your implementation in different OS, maybe is a good idea to use this functions directly and save some overhead and time.
Best regards.
I have my types definition file with:
typedef std::wstring String;
typedef std::vector<String> StringVector;
typedef unsigned long long uint64_t;
and code is:
uint64_t CalculateDirSize(const String &path, StringVector *errVect = NULL, uint64_t size = 0)
{
WIN32_FIND_DATA data;
HANDLE sh = NULL;
sh = FindFirstFile((path + L"\\*").c_str(), &data);
if (sh == INVALID_HANDLE_VALUE )
{
//if we want, store all happened error
if (errVect != NULL)
errVect ->push_back(path);
return size;
}
do
{
// skip current and parent
if (!IsBrowsePath(data.cFileName))
{
// if found object is ...
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
// directory, then search it recursievly
size = CalculateDirSize(path + L"\\" + data.cFileName, NULL, size);
else
// otherwise get object size and add it to directory size
size += (uint64_t) (data.nFileSizeHigh * (MAXDWORD ) + data.nFileSizeLow);
}
} while (FindNextFile(sh, &data)); // do
FindClose(sh);
return size;
}
bool IsBrowsePath(const String& path)
{
return (path == _T(".") || path == _T(".."));
}
This uses UNICODE and returns failed dirs if you want that.
To call use:
StringVector vect;
CalculateDirSize(L"C:\\boost_1_52_0", &vect);
CalculateDirSize(L"C:\\boost_1_52_0");
But never pass size
//use FAT32
#undef UNICODE // to flag window deactive unicode
#include<Windows.h> //to use windows api
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#pragma pack(1) //tell compiler do'nt do prag
struct BPB
{
BYTE JMP[3];
BYTE OEM[8];
WORD NumberOfBytesPerSector;
BYTE NumberOfSectorsPerCluster;
WORD NumberOfReservedSectors;
BYTE NumberOfFATs;
WORD NumberOfRootEntries16;
WORD LowNumbferOfSectors;
BYTE MediaDescriptor;
WORD NumberOfSectorsPerFAT16;
WORD NumberOfSectorsPerTrack;
WORD NumberOfHeads;
DWORD NumberOfHiddenSectors;
DWORD HighNumberOfSectors;
DWORD NumberOfSectorsPerFAT32;
WORD Flags;
WORD FATVersionNumber;
DWORD RootDirectoryClusterNumber;
WORD FSInfoSector;
WORD BackupSector;
BYTE Reserver[12];
BYTE BiosDrive;
BYTE WindowsNTFlag;
BYTE Signature;
DWORD VolumeSerial;
BYTE VolumeLabel[11];
BYTE SystemID[8];
BYTE CODE[420];
WORD BPBSignature;
};
//-----------------------------------------------------------
struct DirectoryEntry
{
BYTE Name[11];
BYTE Attributes;
BYTE Reserved;
BYTE CreationTimeTenth;
WORD CreationTime;
WORD CreationDate;
WORD LastAccessTime;
WORD HiClusterNumber;
WORD WriteTime;
WORD WriteDate;
WORD LowClusterNumber;
DWORD FileSize; //acual size of file
};
//---------------------------------------------------
void dirFunction(string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "Error " << GetLastError()<<endl;
return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value
SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry* root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
for (int i = 0; i < NumberOfEntries; i++)
{
if (root[i].Name[0] == 0)//there no entery after this
break;
if (root[i].Name[0] == 0xE5)
continue;
if ((root[i].Attributes & 0xF) == 0xF)
continue;
for (int j = 0; j < 8; j++)
cout << root[i].Name[j];
if((root[i].Attributes & 0x10) != 0x10){
cout<<".";
for (int j = 8; j < 11; j++)
cout << root[i].Name[j];
}
if ((root[i].Attributes & 0x10) == 0x10){
cout << "\t<Folder>" ;
}else{
cout<<"\t<File>" ;
}
clusterNumber = root[i].HiClusterNumber << 16;
clusterNumber |= root[i].LowClusterNumber;
cout <<"\t"<<root[i].FileSize<<"bytes" << "\t" << clusterNumber<<"cluster" << endl;
}
CloseHandle(hFile);
}
//---------------------------------------------------------------
string convertLowerToUpper(string f){
string temp = "";
for (int i = 0; i < f.size(); i++){
temp += toupper(f[i]);
}
return temp;
}
//---------------------------------------------------------------
string getFileName(BYTE filename[11]){
string name = "";
for (int i = 0; i < 8; i++){
if (filename[i] != ' ')
name += filename[i];
}
return (name);
}
//------------------------------------------------------------------
int findEntryNumber(DirectoryEntry* root, int NumberOfEntries, string required){
string n;
int j = 0;
for (int i = 0; i < NumberOfEntries; i++){
if (strcmp((getFileName(root[i].Name).c_str()), convertLowerToUpper(required).c_str()) == 0){
return i;
}
}
return -1;
}
//---------------------------------------------------------------
void typeFunction(string fileName, string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "Error " << GetLastError()<<endl;
return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value
SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry* root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
int index = findEntryNumber(root, NumberOfEntries, fileName);
if (index == -1){
cout << "File is not found" << endl;
return;
}
if (((root[index].Attributes & 0x10) == 0x10) ){
cout << "Is not file name" << endl;
return;
}
clusterNumber = root[index].HiClusterNumber << 16;
clusterNumber |= root[index].LowClusterNumber;
ULONG temp = (clusterNumber - 2) * clusterSize;
distance += temp;
t = 0;
SetFilePointer(hFile, distance, &t, FILE_BEGIN);
BYTE* buffer = new BYTE[clusterSize];
readBytes = 0;
ReadFile(hFile, (BYTE*)buffer, clusterSize, &readBytes, 0);
for (int i = 0; i < root[index].FileSize; i++){
cout << buffer[i];
}
cout << endl;
CloseHandle(hFile);
}
//----------------------------------------------------------------------
void delFunction(string filename, string s){
string path = "\\\\.\\" + s + ":";
HANDLE hFile = CreateFile(path.c_str(), GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);//open partition
BPB bootSector;//var from bootSector structure
DWORD readBytes = 0;
if (hFile == INVALID_HANDLE_VALUE)
{
cout << "Error " << GetLastError()<<endl;
return;
}
ReadFile(hFile, (BYTE*)&bootSector, sizeof(bootSector), &readBytes, 0);//read partition and load bootSector information inside our structure
LONG t = 0;
ULONG distance = bootSector.NumberOfReservedSectors +
bootSector.NumberOfFATs*bootSector.NumberOfSectorsPerFAT32;//distance from begine until Root Directory or content of partetion
distance *= bootSector.NumberOfBytesPerSector;//convert distance number to bytes value
SetFilePointer(hFile, distance, &t, FILE_BEGIN);//set pointer to root directory begine or begine of data
int clusterSize = bootSector.NumberOfBytesPerSector*bootSector.NumberOfSectorsPerCluster; //cluster size
int NumberOfEntries = clusterSize / sizeof(DirectoryEntry); //number of record inside cluster
DirectoryEntry* root = new DirectoryEntry[NumberOfEntries];//descripe the partetion
ReadFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
DWORD clusterNumber;
readBytes = 0;
t = 0;
int index = findEntryNumber(root, NumberOfEntries, filename);
if (index == -1){
cout << "FIle is not found" << endl;
return;
}
if ((root[index].Attributes & 0x10) == 0x10){
cout << "Is not file name" << endl;
return;
}
//delete file
root[index].Name[0] = 0xE5;
SetFilePointer(hFile, distance, &t, FILE_BEGIN);
WriteFile(hFile, (BYTE*)root, clusterSize, &readBytes, 0);
cout<<filename<<" is deleted\n";
CloseHandle(hFile);
}
//----------------------------------------------------------------------
string removeExtention(string s){
string t = "";
for (int i = 0; i < s.size(); i++){
if (s[i] == '.')break;
t += s[i];
}
return t;
}
//-------------------------------------------------------------------
void main()
{
string swich_value;
string directory;
string file_name;
//dirFunction("G");
cout<<"plz, Enter single Partition character ------> example E or G\n\n";
cin>>directory;
string path = "\\\\.\\" + directory + ":";
cout<<"current directory is "<<path<<endl;
cout<<"Enter Options: \n1- dir \n2- type file_name.extention \n3- del file_name.extention\n\n";
again:
cin>>swich_value;
if(swich_value.at(1)!='i')
cin>>file_name;
string answer;
switch(swich_value.at(1)){
case 'i':
dirFunction(directory);
cout<<"\nare you want to do another process: y or n?";
cin>>answer;
if (answer.at(0)=='y')
goto again;
break;
case 'y':
typeFunction(removeExtention(file_name), directory);
cout<<"\nare you want to do another process: y or n?";
cin>>answer;
if (answer.at(0)=='y')
goto again;
break;
case 'e':
delFunction(removeExtention(file_name), directory);
cout<<"\nare you want to do another process: y or n?";
cin>>answer;
if (answer.at(0)=='y')
goto again;
break;
}
}
You can use "boost::filesystem"
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
unsigned long long int get_directory_size(const fs::path& directory){
if (!fs::exists(directory)) return 0;
if (fs::is_directory(directory)){
unsigned long long int ret_size = 0;
fs::directory_iterator m_dir_itr(directory);
for (m_dir_itr = fs::begin(m_dir_itr); m_dir_itr != fs::end(m_dir_itr); ++m_dir_itr){
fs::directory_entry m_dir_entry = *m_dir_itr;
if (fs::is_regular_file(m_dir_entry.path())){
ret_size += fs::file_size(m_dir_entry.path());
}else if (fs::is_directory(m_dir_entry.path())){
ret_size += get_directory_size(m_dir_entry.path());
}
}
return ret_size;
} else if (fs::is_regular_file(directory)){
return fs::file_size(directory);
}
return 0;
}
#include <stdio.h>
int main(int /*argc*/, char** /*argv*/) {
// Assuming 'C:/Folder' be any directory then its size can be found using
auto folder_size = get_directory_size("C:/Folder");
printf("Size of 'C:/Folder' is %d\n",folder_size);
return 0;
}
With the introduction of std::filesystem, you no more have to use any system APIs or any external libraries.
#include <filesystem>
namespace n_fs = ::std::filesystem;
double archive::getFolderSize(std::string path)
{
double r = 0.0;
try{
if (!n_fs::is_directory(path))
{
r += (double)n_fs::file_size(path);
}
else
{
for(auto entry: n_fs::directory_iterator(path))
getFolderSize(entry.path().string());
}
}
catch(exception& e)
{
std::cout << e.what() << std::endl();
}
return r;
}
int main(){
double folderSize = getFolderSize("~/dev/"); //Replace with your path
std::cout << "Size of Folder: " << folderSize;
}
Try using GetFileSizeEx function. Following is some sample code for this. You need to get the size from the LARGE_INTEGER union though.
#include <iostream>
#include <windows.h>
#include <stdio.h>
#include <io.h>
using namespace std;
int main()
{
FILE *fp;
fp = fopen("C:\test.txt","r");
int fileNo = _fileno(fp);
HANDLE cLibHandle = (HANDLE)_get_osfhandle(fileNo);
long int fileSize = 0;
LARGE_INTEGER fileSizeL;
GetFileSizeEx(cLibHandle, &fileSizeL);
return 0;
}
5 years and not a simple solution with standard C++, that's why I would like to contribute my solution to this question:
uint64_t GetDirSize(const std::string &path)
{
uint64_t size = 0;
for (const auto & entry : std::experimental::filesystem::directory_iterator(path))
{
if(entry.status().type() == std::experimental::filesystem::file_type::regular)
size += std::experimental::filesystem::file_size(entry.path());
if (entry.status().type() == std::experimental::filesystem::file_type::directory)
size += GetDirSize(entry.path().generic_string());
}
return size;
}
Use it for example by calling
GetDirSize("C:\\dir_name")
if you're using Windows.
Calculating a folder size in bytes on Windows.
size_t GetFolderSizeInBytes(std::wstring path)
{
size_t result = 0;
WIN32_FIND_DATA findData;
HANDLE hFileHandle;
std::wstring sourcePath(path);
if (GetFileAttributes(sourcePath.c_str()) & FILE_ATTRIBUTE_DIRECTORY)
sourcePath.push_back(L'\\');
std::wstring fileName(sourcePath);
fileName.append(L"*");
hFileHandle = FindFirstFileEx(
fileName.data(),
FindExInfoStandard,
&findData,
FindExSearchNameMatch,
NULL,
FIND_FIRST_EX_ON_DISK_ENTRIES_ONLY);
if (hFileHandle != INVALID_HANDLE_VALUE)
{
do
{
if (!wcscmp(findData.cFileName, L".") || !wcscmp(findData.cFileName, L".."))
continue;
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
// Folder
std::wstring newPath = path + L"\\" + findData.cFileName;
result += GetFolderSizeInBytes(newPath);
}
else
{
// File
unsigned long high = findData.nFileSizeHigh;
unsigned long low = findData.nFileSizeLow;
size_t size = size_t(high * (MAXWORD + 1)) + low;
result += size;
}
} while (FindNextFile(hFileHandle, &findData));
FindClose(hFileHandle);
}
return result;
}