commit 3923d627d5168819b4982ac3e1698788668e3bc5 Author: Артем Коннов Date: Sun Jun 15 16:24:20 2025 +0000 Добавить 1 diff --git a/1 b/1 new file mode 100644 index 0000000..318379f --- /dev/null +++ b/1 @@ -0,0 +1,244 @@ +#include +#include +#include +#include + +#define BUFFER_SIZE 4096 +#define MAX_LINE_LENGTH 1024 + +typedef struct { + DWORD attributes; + FILETIME creationTime; + FILETIME lastAccessTime; + FILETIME lastWriteTime; + DWORD fileSizeHigh; + DWORD fileSizeLow; +} FileAttributes; + +void splitString(const char* str, char*** lines, int* lineCount) { + *lineCount = 0; + *lines = NULL; + + const char* start = str; + const char* current = str; + + while (*current) { + if (*current == '\r' || *current == '\n') { + size_t length = current - start; + if (length > 0) { + *lines = realloc(*lines, (*lineCount + 1) * sizeof(char*)); + (*lines)[*lineCount] = malloc(length + 1); + strncpy((*lines)[*lineCount], start, length); + (*lines)[*lineCount][length] = '\0'; + (*lineCount)++; + } + + if (*current == '\r' && *(current + 1) == '\n') { + current++; + } + + start = current + 1; + } + current++; + } + + size_t remaining = current - start; + if (remaining > 0) { + *lines = realloc(*lines, (*lineCount + 1) * sizeof(char*)); + (*lines)[*lineCount] = malloc(remaining + 1); + strncpy((*lines)[*lineCount], start, remaining); + (*lines)[*lineCount][remaining] = '\0'; + (*lineCount)++; + } +} + +void freeLines(char** lines, int lineCount) { + for (int i = 0; i < lineCount; i++) { + free(lines[i]); + } + free(lines); +} + +char* fileTimeToString(const FILETIME* ft) { + if (ft->dwLowDateTime == 0 && ft->dwHighDateTime == 0) { + return strdup("N/A"); + } + + SYSTEMTIME st; + FileTimeToSystemTime(ft, &st); + + char* buffer = malloc(64); + snprintf(buffer, 64, "%02d.%02d.%04d %02d:%02d:%02d", + st.wDay, st.wMonth, st.wYear, + st.wHour, st.wMinute, st.wSecond); + + return buffer; +} + +char* attributesToString(DWORD attrs) { + if (attrs == INVALID_FILE_ATTRIBUTES) { + return strdup("Invalid attributes"); + } + + char* result = calloc(256, 1); + int first = 1; + +#define ADD_ATTR(attr, name) \ + if (attrs & attr) { \ + if (!first) strcat(result, ", "); \ + strcat(result, name); \ + first = 0; \ + } + + ADD_ATTR(FILE_ATTRIBUTE_ARCHIVE, "Archive"); + ADD_ATTR(FILE_ATTRIBUTE_COMPRESSED, "Compressed"); + ADD_ATTR(FILE_ATTRIBUTE_DIRECTORY, "Directory"); + ADD_ATTR(FILE_ATTRIBUTE_ENCRYPTED, "Encrypted"); + ADD_ATTR(FILE_ATTRIBUTE_HIDDEN, "Hidden"); + ADD_ATTR(FILE_ATTRIBUTE_NORMAL, "Normal"); + ADD_ATTR(FILE_ATTRIBUTE_OFFLINE, "Offline"); + ADD_ATTR(FILE_ATTRIBUTE_READONLY, "Readonly"); + ADD_ATTR(FILE_ATTRIBUTE_SYSTEM, "System"); + ADD_ATTR(FILE_ATTRIBUTE_TEMPORARY, "Temporary"); + +#undef ADD_ATTR + + return result; +} + +FileAttributes getFileAttributesWin(const char* filePath) { + FileAttributes attrs = {0}; + WIN32_FILE_ATTRIBUTE_DATA fileInfo; + + if (GetFileAttributesExA(filePath, GetFileExInfoStandard, &fileInfo)) { + attrs.attributes = fileInfo.dwFileAttributes; + attrs.creationTime = fileInfo.ftCreationTime; + attrs.lastAccessTime = fileInfo.ftLastAccessTime; + attrs.lastWriteTime = fileInfo.ftLastWriteTime; + attrs.fileSizeHigh = fileInfo.nFileSizeHigh; + attrs.fileSizeLow = fileInfo.nFileSizeLow; + } else { + attrs.attributes = INVALID_FILE_ATTRIBUTES; + } + + return attrs; +} + +void runChildProcess(const char* handleStr) { + printf("Child process started.\n"); + + HANDLE hFile = (HANDLE)(INT_PTR)atoll(handleStr); + char buffer[BUFFER_SIZE]; + DWORD bytesRead; + char* totalData = calloc(1, 1); + size_t totalSize = 0; + + while (ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL) && bytesRead > 0) { + totalData = realloc(totalData, totalSize + bytesRead + 1); + memcpy(totalData + totalSize, buffer, bytesRead); + totalSize += bytesRead; + totalData[totalSize] = '\0'; + } + + CloseHandle(hFile); + + char** lines = NULL; + int lineCount = 0; + splitString(totalData, &lines, &lineCount); + free(totalData); + + for (int i = 0; i < lineCount; i++) { + if (strlen(lines[i]) == 0) continue; + + FileAttributes attrs = getFileAttributesWin(lines[i]); + ULONGLONG fileSize = ((ULONGLONG)attrs.fileSizeHigh << 32) | attrs.fileSizeLow; + + char* attrStr = attributesToString(attrs.attributes); + char* createdStr = fileTimeToString(&attrs.creationTime); + char* accessedStr = fileTimeToString(&attrs.lastAccessTime); + char* modifiedStr = fileTimeToString(&attrs.lastWriteTime); + + printf("\nFile: %s\n", lines[i]); + printf("Attributes: %s\n", attrStr); + printf("Size: %llu bytes\n", fileSize); + printf("Created: %s\n", createdStr); + printf("Last accessed: %s\n", accessedStr); + printf("Last modified: %s\n", modifiedStr); + + free(attrStr); + free(createdStr); + free(accessedStr); + free(modifiedStr); + } + + freeLines(lines, lineCount); +} + +void runParentProcess() { + printf("Parent process started.\n"); + + SECURITY_ATTRIBUTES sa = {0}; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = FALSE; + + HANDLE hFile = CreateFileA( + "test.txt", + GENERIC_READ, + FILE_SHARE_READ, + &sa, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + + if (hFile == INVALID_HANDLE_VALUE) { + fprintf(stderr, "Error opening file. Error: %lu\n", GetLastError()); + return; + } + + if (!SetHandleInformation(hFile, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) { + fprintf(stderr, "Failed to set handle inheritance. Error: %lu\n", GetLastError()); + CloseHandle(hFile); + return; + } + + char cmdLine[256]; + snprintf(cmdLine, sizeof(cmdLine), "%s child %lld", GetCommandLineA(), (long long)(INT_PTR)hFile); + + STARTUPINFOA si = {0}; + si.cb = sizeof(si); + PROCESS_INFORMATION pi = {0}; + + if (!CreateProcessA( + NULL, + cmdLine, + NULL, + NULL, + TRUE, + 0, + NULL, + NULL, + &si, + &pi)) { + fprintf(stderr, "Error creating child process. Error: %lu\n", GetLastError()); + CloseHandle(hFile); + return; + } + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + CloseHandle(hFile); +} + +int main(int argc, char* argv[]) { + if (argc == 1) { + runParentProcess(); + } else if (argc == 3 && strcmp(argv[1], "child") == 0) { + runChildProcess(argv[2]); + } else { + fprintf(stderr, "Invalid arguments.\n"); + return 1; + } + + return 0; +} \ No newline at end of file