/* limpador do luca0N! 3 Copyright (C) 2020 luca0N! This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Contact me by e-mail via . */ #include "about.h" #include "str.h" #include "cfg.h" // Because this program is currently targeted at Windows only, the use of ANSI colors are no longer used as of May 5, 2020. #include "colors.h" #include #include #include #include #include #include #include void setConsoleColor(int consoleColor){ HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); WORD wColor; CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(h, &info); wColor = info.wAttributes; SetConsoleTextAttribute(h, consoleColor); } // Prints the program license to the user. int printLicense(int full){ if (full == 0) { printf("%s\n", LICENSE); return 0; } else { FILE* flic = fopen(PATH_LICENSE, "r"); if (flic == NULL){ printf("%s\n", STR_ERROR_LIC); return -1; } char c; while ((c = fgetc(flic)) != EOF) { printf("%c", c); } } } // Cleans a directory. void cleanDir(const char* path, unsigned* objectCount, unsigned long* totalDeletedBytes){ const char* validPath = path; //char validPath[sizeof(path) + 1]; //strcpy(validPath, path); // Check if the path ends with '\' // Because the last character of a string is null, we should check the character before that one. if (path[strlen(path) - 1] != '\\'){ strcat(validPath, "\\"); } // Path with wildcard char wildPath[strlen(validPath) + 1]; strcpy(wildPath, validPath); strcat(wildPath, "*"); printf(STR_CLEANING_DIR, wildPath); // Fetch files in dir WIN32_FIND_DATA data; HANDLE hFind = FindFirstFile(wildPath, &data); unsigned int iteration = 0; if (hFind != INVALID_HANDLE_VALUE){ do{ // Ignore pseudo dirs (. and ..) iteration++; if (iteration <= 2) continue; printf(STR_FOUND_ITEM, data.cFileName); // Attempt to delete item... int pathSize = strlen(wildPath) + strlen(data.cFileName); char fullPath[pathSize]; strcpy(fullPath, validPath); strcat(fullPath, data.cFileName); // If the item is a directory, call cleanDir on that directory. if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){ cleanDir(fullPath, objectCount, totalDeletedBytes); /*int shellReturnCode = shellRemoveDir(fullPath); if (shellReturnCode != 0){ printf(" %s\n", STR_FAILED_DIR); printf(" --> %s\n", fullPath); printf(" --> %#010x\n", shellReturnCode); }*/ continue; } // Get the length of the file before deleting it. HANDLE fileHandle = CreateFile(fullPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); LARGE_INTEGER size; unsigned long length = 0; if (fileHandle != INVALID_HANDLE_VALUE){ if (GetFileSizeEx(fileHandle, &size)){ length = size.QuadPart; } CloseHandle(fileHandle); } if (DeleteFile(fullPath) == 0){ setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_RED); int lastError = GetLastError(); printf(STR_FAILED_FILE); printf(" --> %s\n", fullPath); printf(" --> %#010x\n", lastError); setConsoleColor(RESET_CONSOLE_COLOR); } else { setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_BLUE); printf(STR_DELETED_FILE); // Update the deleted object count if the process was successful. (*objectCount)++; (*totalDeletedBytes) += length; setConsoleColor(RESET_CONSOLE_COLOR); } } while(FindNextFile(hFind, &data)); } else { printf("%s\n", STR_FAILED_DIR_LIST); } } // Gets the user defined directories void getAdditionalDirs(bool safeMode){ unsigned* objectCount = 0; unsigned long* totalDeletedBytes = 0; printf("\n%s\n", STR_FETCHING_ADD_DIRS); int dirs; dirs = GetPrivateProfileInt("Pastas", "Pastas", 3, PATH_CFG); printf(STR_DIR_COUNT, dirs); fflush(stdout); for(unsigned short x = 0; x < dirs; x++){ char dirKey[7] = "Pasta"; char* intPtr = (char*) (x + 1) + '0'; strcat(dirKey, (char*) &intPtr); _TCHAR currentPath[128]; GetPrivateProfileString("Pastas", dirKey, "null", currentPath, sizeof(currentPath) / sizeof(currentPath[0]), PATH_CFG); // Check if the specified path is an environment variable. // If it starts with %, then we should treat it as such. bool containsVars = false; for (unsigned c = 0; c < strlen(currentPath); c++) if (currentPath[c] == '%'){ containsVars = true; break; } if (containsVars){ char* buffer; char* varBuffer; if ((buffer = malloc(512)) == NULL || (varBuffer = malloc(64)) == NULL){ printf("%s\n", STR_MEM_ERR); } buffer[0] = '\0'; varBuffer[0] = '\0'; bool fetchingVar = false; for (unsigned c = 0; c < strlen(currentPath); c++){ if (currentPath[c] == '%') if (!fetchingVar) fetchingVar = true; else { // Get the environment variable char varValBuffer[256]; GetEnvironmentVariable( varBuffer, &varValBuffer, sizeof(varValBuffer) ); strncat(buffer, &varValBuffer, strlen(varValBuffer)); fetchingVar = false; } else if (fetchingVar) strncat(varBuffer, ¤tPath[c], 1); else strncat(buffer, ¤tPath[c], 1); } printf(STR_FOUND_DIR, dirKey, buffer); if (!safeMode) cleanDir(buffer, &objectCount, &totalDeletedBytes); free(buffer); free(varBuffer); continue; } printf(STR_FOUND_DIR, dirKey, currentPath); if (!safeMode) cleanDir(currentPath, &objectCount, &totalDeletedBytes); } setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_GREEN); printf(STR_OBJECT_COUNT, objectCount); // Determine whether we should output the size as bytes, KiB, MiB or GiB. if (totalDeletedBytes < 1024){ printf(STR_TOTAL_DELETED_BYTES, totalDeletedBytes); } else if (totalDeletedBytes < (unsigned long) pow(1024, 2)){ float kib = (unsigned long) totalDeletedBytes / pow(1024, 1); printf(STR_TOTAL_DELETED_KIBIBYTES, kib); } else if (totalDeletedBytes < (unsigned long) pow(1024, 3)){ float mib = (unsigned long) totalDeletedBytes / pow(1024, 2);// / (float) 1024 / (float) 1024; printf(STR_TOTAL_DELETED_MEBIBYTES, mib); } else { float gib = (unsigned long) totalDeletedBytes / pow(1024, 3); printf(STR_TOTAL_DELETED_GIBIBYTES, gib); } setConsoleColor(RESET_CONSOLE_COLOR); printf(STR_EXIT_PAUSE); fflush(stdout); getch(); } int main(void){ SetConsoleOutputCP(CP_UTF8); setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_YELLOW); printLicense(0); setConsoleColor(RESET_CONSOLE_COLOR); setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_BLUE); printf("%s\n%s %d, %s-%s (%s)\n", STR_LN, PROGRAM_NAME, PROGRAM_SEASON, PROGRAM_VERSION, PROGRAM_VERSION_BRANCH, PROGRAM_VERSION_TIMESTAMP); printf("%s\n%s\n\n", PROGRAM_COPYRIGHT, STR_LN); setConsoleColor(FOREGROUND_INTENSITY | FOREGROUND_YELLOW); printf(STR_TAMPER_WARNING); unsigned int ignoreWarning = GetPrivateProfileInt("Geral", "IgnorarAlerta", 0, PATH_CFG); unsigned int licenseAccepted = GetPrivateProfileInt("Geral", "AceitarLicença", 0, PATH_CFG); if (!ignoreWarning || !licenseAccepted){ printf("%s ", STR_USE_WARNING, ignoreWarning, licenseAccepted); char in; fflush(stdout); setConsoleColor(RESET_CONSOLE_COLOR); scanf("%c", &in); if (in == 'w' || in == 'c') if (printLicense(1) != 0) return -2; if (in != 's' && in != 'S' && in != 'y' && in != 'Y') return 0; } setConsoleColor(RESET_CONSOLE_COLOR); unsigned int safeMode = GetPrivateProfileInt("Geral", "ModoSeguro", 1, PATH_CFG); getAdditionalDirs(safeMode); return 0; }