Добавить 1
This commit is contained in:
commit
3923d627d5
244
1
Normal file
244
1
Normal file
@ -0,0 +1,244 @@
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user