/**************************************************************************** Aaru Data Preservation Suite ----------------------------------------------------------------------------- Filename : win32.c Author(s) : Natalia Portillo --[ Description ] ----------------------------------------------------------- Contains 32-bit and 64-bit Windows code --[ License ] --------------------------------------------------------------- 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 . ----------------------------------------------------------------------------- Copyright (C) 2011-2021 Natalia Portillo *****************************************************************************/ // ReSharper disable CppJoinDeclarationAndAssignment // ReSharper disable CppDeprecatedEntity #if defined(__WINDOWS__) || defined(__TOS_WIN__) || defined(__WIN32__) || defined(_WIN64) || defined(_WIN32) || \ defined(__NT__) #define _CRT_SECURE_NO_WARNINGS 1 #include #include #include #include #include "win32.h" #include "links.h" #include "../include/consts.h" #include "../include/defs.h" static DWORD dwMaxNameSize = MAX_PATH + 1; static DWORD dwFilePermissions = GENERIC_READ | GENERIC_WRITE; static DWORD oldVersion; static HINSTANCE kernel32; void Links(const char* path) { BOOL ret; DWORD error; WIN_OSVERSIONINFO verInfo; void* func; DWORD dwNumberOfBytesWritten; DWORD rc, wRc, cRc, lRc; char message[300]; HANDLE h; LPSTR lpRootPathName; size_t pathSize = strlen(path); if(WinGetVersionExA) { verInfo.dwOSVersionInfoSize = sizeof(WIN_OSVERSIONINFO); ret = WinGetVersionExA(&verInfo); if(!ret) { error = GetLastError(); printf("Error %lu querying Windows version.\n", error); return; } } else if(oldVersion == 0) verInfo.dwPlatformId = VER_PLATFORM_WIN32_NT; if(verInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { // Not supported on Windows 9x return; } lpRootPathName = malloc(dwMaxNameSize); if(!lpRootPathName) { printf("Could not allocate memory.\n"); return; } memset(lpRootPathName, 0x00, MAX_PATH); strncpy(lpRootPathName, path, MAX_PATH); if(path[pathSize - 1] != '\\') { lpRootPathName[pathSize] = '\\'; } ret = SetCurrentDirectoryA(lpRootPathName); if(!ret) { error = GetLastError(); printf("Error %lu changing to specified path.\n", error); return; } ret = CreateDirectoryA("LINKS", NULL); if(!ret) { error = GetLastError(); printf("Error %lu creating working directory.\n", error); return; } ret = SetCurrentDirectoryA("LINKS"); if(!ret) { error = GetLastError(); printf("Error %lu changing to working directory.\n", error); return; } kernel32 = LoadLibraryA("kernel32.dll"); if(!kernel32) { error = GetLastError(); printf("Error %lu loading KERNEL32.DLL.\n", error); return; } func = GetProcAddress(kernel32, "CreateSymbolicLinkA"); if(!func) { error = GetLastError(); printf("Error %lu finding CreateSymbolicLinkA.\n", error); } else { WinNtCreateSymbolicLinkA = func; printf("Creating symbolic links.\n"); h = CreateFileA("TARGET", dwFilePermissions, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; lRc = 0; if(h == INVALID_HANDLE_VALUE) rc = GetLastError(); else { memset(message, 0, 300); sprintf(message, "This file is the target of a symbolic link.\n"); ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); if(!ret) wRc = GetLastError(); ret = CloseHandle(h); if(!ret) cRc = GetLastError(); ret = WinNtCreateSymbolicLinkA("SYMLINK", "TARGET", 0); if(!ret) lRc = GetLastError(); } printf("\tSymbolic link, rc = 0x%08lx, wRc = %lu, cRc = %lu, lRc = %lu\n", rc, wRc, cRc, lRc); } func = GetProcAddress(kernel32, "CreateHardLinkA"); if(!func) { error = GetLastError(); printf("Error %lu finding CreateHardLinkA.\n", error); } else { WinNtCreateHardLinkA = func; printf("Creating hard links.\n"); h = CreateFileA("HARDTRGT", dwFilePermissions, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); rc = 0; wRc = 0; cRc = 0; lRc = 0; if(h == INVALID_HANDLE_VALUE) rc = GetLastError(); else { memset(message, 0, 300); sprintf(message, "This file is part of a hard link.\n"); ret = WriteFile(h, message, strlen(message), &dwNumberOfBytesWritten, NULL); if(!ret) wRc = GetLastError(); ret = CloseHandle(h); if(!ret) cRc = GetLastError(); ret = WinNtCreateHardLinkA("HARDLINK", "HARDTRGT", NULL); if(!ret) lRc = GetLastError(); } printf("\tHard link, rc = 0x%08lx, wRc = %lu, cRc = %lu, lRc = %lu\n", rc, wRc, cRc, lRc); } } #endif