remove VS sln

This commit is contained in:
Nikola Petrov
2024-01-14 20:45:34 +01:00
parent fef45749a1
commit 3935c3f34e
18 changed files with 3 additions and 312 deletions

308
source/arg_func.cpp Normal file
View File

@@ -0,0 +1,308 @@
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include "arg_func.h"
#include "func.h"
#include "win.h"
#include "func.h"
#include "buffer.h"
#include "cryptography.h"
void print_args()
{
printf_s(" Usage:\n\n");
printf_s(" password_manager.exe [flags]\n\n");
printf_s(" Flags:\n\n");
printf_s(" -h print this message\n");
printf_s(" <label> get password of this label can use GLOB\n");
printf_s(" -g <label> generate password of this label (or update if exists)\n");
printf_s(" -i <label> input new password for this label (or update if exists)\n");
printf_s(" -d <label> delete password of this label\n");
printf_s(" -s <label> show password for this label\n");
printf_s(" -u <label> update username for this label\n");
printf_s(" -n <label> update label name\n");
printf_s(" -l list all labels\n");
printf_s(" -p print all passwords\n");
printf_s(" -c change master password\n");
printf_s(" -f <folder path> select save folder\n");
}
Arg get_args(int argc, char** argv, char** label) {
if (argc < 2)
{
print_args();
return Arg::Error;
}
if (!strcmp("-h", argv[1]))
{
print_args();
return Arg::Error;
}
if (!strcmp("-l", argv[1])) return Arg::List;
if (!strcmp("-p", argv[1])) return Arg::Print_all_p;
if (!strcmp("-c", argv[1])) return Arg::Change;
if (argc < 3)
{
*label = argv[1];
return Arg::Get;
}
*label = argv[2];
if (!strcmp("-g", argv[1])) return Arg::Generate;
if (!strcmp("-d", argv[1])) return Arg::Delete;
if (!strcmp("-i", argv[1])) return Arg::Input;
if (!strcmp("-s", argv[1])) return Arg::Show;
if (!strcmp("-u", argv[1])) return Arg::Username;
if (!strcmp("-n", argv[1])) return Arg::Name;
if (!strcmp("-f", argv[1])) return Arg::File;
return Arg::Error;
}
std::optional<LoginInfoPointer> arg_get(Buffer& decrypted_buffer, const char* label)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0) {
printf_s("Password not found\n");
return {};
}
return get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
}
std::optional<LoginInfoPointer> arg_new_password(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto, bool generate)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
std::string username = "";
std::string name = label;
std::string password = "";
if (pass >= 0) {
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
username = lip.username;
name = lip.label;
delete_logininfo_from_buffer(decrypted_buffer, pass);
}
printf_s("New password for %s: \n", name.c_str());
if (pass < 0)
{
printf_s("Input username: ");
std::getline(std::cin, username);
}
if (generate)
{
int default_length = 15;
printf_s("Input password length [%d]: ", default_length);
std::string input;
int length = default_length;
std::getline(std::cin, input);
if (!input.empty())
{
std::istringstream iss(input);
if (!(iss >> length)) length = default_length;
}
generate_password(password, length);
}
else
{
printf_s("Input new password: \n");
password = get_user_password();
if (password.empty())
{
printf_s("error getting password\n");
return {};
}
}
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file();
Index* index = (Index*)decrypted_buffer.buffer;
return get_logininfo_pointer_from_buffer(decrypted_buffer, index->count - 1);
}
void arg_username(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0)
{
printf_s("LoginInfo not found\n");
return;
}
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
std::string password = lip.password;
std::string name = lip.label;
printf_s("Input username for %s: ", name.c_str());
std::string username;
std::getline(std::cin, username);
delete_logininfo_from_buffer(decrypted_buffer, pass);
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file();
}
void arg_label_name(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto)
{
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0)
{
printf_s("LoginInfo not found\n");
return;
}
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
std::string password = lip.password;
std::string username = lip.username;
printf_s("Input new label name for %s:", lip.label);
std::string name;
std::getline(std::cin, name);
delete_logininfo_from_buffer(decrypted_buffer, pass);
add_logininfo_to_buffer(decrypted_buffer, name.c_str(), username.c_str(), password.c_str());
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file();
}
void arg_list(Buffer& decrypted_buffer)
{
Index* index = (Index*)decrypted_buffer.buffer;
LoginInfo* pass = (LoginInfo*)(decrypted_buffer.buffer + sizeof(Index));
for (size_t i = 0; i < index->count; i++)
{
printf_s("label: %s\n", decrypted_buffer.buffer + pass[i].label + index->offset);
}
}
void arg_delete(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label_to_del, Cryptography& crypto)
{
printf_s("Deleting password for %s\n", label_to_del);
int pass = find_logininfo_in_buffer(decrypted_buffer, label_to_del);
if (pass < 0)
{
printf_s("Password not found\n");
return;
}
delete_logininfo_from_buffer(decrypted_buffer, pass);
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file();
printf_s("Password deleted\n");
}
void arg_print_all_p(Buffer& decrypted_buffer, std::string& user_pass)
{
printf_s("Input main password for confirmation:");
std::string new_string = get_user_password();
if (new_string.empty())
{
printf_s("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf_s("Wrong password\n");
return;
}
Index* index = (Index*)decrypted_buffer.buffer;
LoginInfo* pass = (LoginInfo*)(decrypted_buffer.buffer + sizeof(Index));
printf_s("\n");
for (size_t i = 0; i < index->count; i++)
{
printf_s("label: %-10s\t\t", decrypted_buffer.buffer + pass[i].label + index->offset);
printf_s("username: %-10s\t\t", decrypted_buffer.buffer + pass[i].username + index->offset);
printf_s("password: %s\n", decrypted_buffer.buffer + pass[i].password + index->offset);
}
}
void arg_change(Buffer& decrypted_buffer, Buffer& encrypted_buffer, std::string& user_pass, Cryptography& crypto)
{
printf_s("Input main password for confirmation:");
std::string new_string = get_user_password();
if (new_string.empty())
{
printf_s("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf_s("Passwords don't match\n");
return;
}
printf_s("Input new password:");
new_string = get_user_password();
if (new_string.empty())
{
printf_s("Error getting password\n");
return;
}
printf_s("Input new password again:");
user_pass = get_user_password();
if (user_pass.empty())
{
printf_s("Error getting password\n");
return;
}
if (new_string != user_pass)
{
printf_s("Passwords don't match\n");
return;
}
crypto.generate_key_and_iv_from_password(new_string.c_str(), new_string.size());
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file();
printf_s("Password changed\n");
}
void arg_show(Buffer& decrypted_buffer, const char* label) {
int pass = find_logininfo_in_buffer(decrypted_buffer, label);
if (pass < 0)
printf_s("Password not found\n");
else
{
LoginInfoPointer lip = get_logininfo_pointer_from_buffer(decrypted_buffer, pass);
printf_s("Username: %s\n", lip.username);
printf_s("Password: %s\n", lip.password);
}
}
void arg_file(Buffer& decrypted_buffer, Buffer& encrypted_buffer, const char* label, Cryptography& crypto, std::string& save_location_path)
{
std::string save(label);
save.append("\\passwords.bin");
std::ofstream file(save_location_path, std::ios::binary);
file << save << std::endl;
file.close();
if (decrypted_buffer.taken <= sizeof(Index)) return;
crypto.encrypt(&decrypted_buffer, &encrypted_buffer);
encrypted_buffer.save_to_file(save);
}

146
source/buffer.cpp Normal file
View File

@@ -0,0 +1,146 @@
#include "buffer.h"
#include <iostream>
#include <fstream>
Buffer::Buffer()
{
buffer = nullptr;
size = 0;
taken = 0;
}
Buffer::Buffer(size_t size)
{
this->size = size;
this->buffer = new uint8_t[size];
}
Buffer::~Buffer()
{
if (buffer) delete[] buffer;
}
bool Buffer::resize(size_t new_size)
{
if (size >= new_size) return true;
uint8_t* new_buffer = (uint8_t*)realloc(buffer, new_size);
if (!new_buffer)
{
printf_s("Error resizing buffer\n");
return false;
}
buffer = new_buffer;
size = new_size;
return true;
}
int Buffer::add_end(uint8_t* data, size_t data_size)
{
if (taken + data_size > size)
if (!resize(size + data_size)) return -1;
memcpy_s(buffer + taken, size - taken, data, data_size);
taken += data_size;
return taken - data_size;
}
int Buffer::add_middle(uint8_t* data, size_t data_size, size_t index)
{
if (taken + data_size > size)
if (!resize(size + data_size)) return -1;
memmove_s(buffer + index + data_size, size - index - data_size, buffer + index, taken - index);
memcpy_s(buffer + index, size - index, data, data_size);
taken += data_size;
return index;
}
void Buffer::remove_fast(uint8_t* data, size_t data_size)
{
int64_t index = data - buffer;
if (index < 0 || index > taken || index + data_size > taken)
{
printf_s("Error removing from buffer\n");
return;
}
memmove_s(buffer + index, size - index, buffer + index + data_size, taken - index - data_size);
taken -= data_size;
}
void Buffer::remove(size_t index, size_t data_size)
{
if (index + data_size > taken)
{
printf_s("Error removing from buffer\n");
return;
}
memmove_s(buffer + index, size - index, buffer + index + data_size, taken - index - data_size);
taken -= data_size;
}
size_t Buffer::find(uint8_t* data, size_t data_size)
{
for (size_t i = 0; i < taken; i++)
if (memcmp(buffer + i, data, data_size) == 0)
return i;
return -1;
}
void Buffer::remove(uint8_t* data, size_t data_size)
{
size_t index = find(data, data_size);
if (index == -1)
{
printf_s("Error removing from buffer\n");
return;
}
remove(index, data_size);
}
bool Buffer::save_to_file()
{
std::ofstream file(this->file_path, std::ios::binary | std::ios::out);
if (!file.is_open())
{
printf_s("Error saving file\n");
return false;
}
file.write((char*)this->buffer, this->taken);
file.close();
return true;
}
bool Buffer::save_to_file(std::string file_path)
{
this->file_path = file_path;
return save_to_file();
}
bool Buffer::load_from_file()
{
std::ifstream file(this->file_path, std::ios::binary | std::ios::in);
if (!file.is_open()) return false;
file.seekg(0, std::ios::end);
size_t file_size = file.tellg();
resize(file_size);
file.seekg(0, std::ios::beg);
file.read((char*)buffer, size);
if (file)
taken = file_size;
else
taken = file.gcount();
file.close();
return true;
}
bool Buffer::load_from_file(std::string file_path)
{
this->file_path = file_path;
return load_from_file();
}

87
source/cryptography.cpp Normal file
View File

@@ -0,0 +1,87 @@
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/aes.h>
#include <string>
#include <iostream>
#include <fstream>
#include "cryptography.h"
#include "Buffer.h"
Cryptography::Cryptography(const char* password, size_t size)
{
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
if (!generate_key_and_iv_from_password(password, size))
{
printf_s("Error generating key and IV from password\n");
return;
}
}
Cryptography::~Cryptography()
{
ERR_free_strings();
EVP_cleanup();
}
bool Cryptography::encrypt(Buffer* plain, Buffer* encrypted)
{
encrypted->resize(plain->taken + AES_BLOCK_SIZE);
ctx = EVP_CIPHER_CTX_new();
if (!ctx) return handleErrors();
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return handleErrors();
if (1 != EVP_EncryptUpdate(ctx, encrypted->buffer, (int*)&encrypted->taken, plain->buffer, plain->taken)) return handleErrors();
int final_len;
if (1 != EVP_EncryptFinal_ex(ctx, encrypted->buffer + encrypted->taken, &final_len)) return handleErrors();
encrypted->taken += final_len;
EVP_CIPHER_CTX_free(ctx);
return true;
}
bool Cryptography::decrypt(Buffer* encrypted, Buffer* decrypted)
{
decrypted->resize(encrypted->taken + AES_BLOCK_SIZE);
ctx = EVP_CIPHER_CTX_new();
if (!ctx) return handleErrors();
if (1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) return handleErrors();
if (1 != EVP_DecryptUpdate(ctx, decrypted->buffer, (int*)&decrypted->taken, encrypted->buffer, encrypted->taken)) return handleErrors();
int final_len;
if (1 != EVP_DecryptFinal_ex(ctx, decrypted->buffer + decrypted->taken, &final_len)) return handleErrors();
decrypted->taken += final_len;
EVP_CIPHER_CTX_free(ctx);
return true;
}
bool Cryptography::generate_key_and_iv_from_password(const char* password, size_t size)
{
int iterations = 10000;
// Derive key and IV using PBKDF2
if (1 != PKCS5_PBKDF2_HMAC(password, size, nullptr, 0, iterations, EVP_sha256(), 32, key)) return false;
if (1 != PKCS5_PBKDF2_HMAC(password, size, nullptr, 0, iterations, EVP_sha256(), 16, iv)) return false;
return true;
}
bool Cryptography::handleErrors()
{
EVP_CIPHER_CTX_free(ctx);
while (auto error = ERR_get_error())
{
char* error_string = ERR_error_string(error, nullptr);
printf_s("%s\n", error_string);
}
return false;
}

82
source/func.cpp Normal file
View File

@@ -0,0 +1,82 @@
#include <ctime>
#include "func.h"
#include "glob.h"
#include "Buffer.h"
int find_logininfo_in_buffer(Buffer& buffer, const char* label)
{
Index* index = (Index*)buffer.buffer;
LoginInfo* pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
for (size_t i = 0; i < index->count; i++)
{
if (glob(label, (const char*)buffer.buffer + pass[i].label + index->offset) == Glob_Result::MATCHED)
return i;
}
return -1;
}
void delete_logininfo_from_buffer(Buffer& buffer, int index_of_pass)
{
Index* in_index = (Index*)buffer.buffer;
LoginInfo* in_pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
int size_of_label = strlen((char*)buffer.buffer + in_pass[index_of_pass].label + in_index->offset) + 1;
int size_of_username = strlen((char*)buffer.buffer + in_pass[index_of_pass].username + in_index->offset) + 1;
int size_of_password = strlen((char*)buffer.buffer + in_pass[index_of_pass].password + in_index->offset) + 1;
int size_pass = size_of_label + size_of_username + size_of_password;
uint8_t* start_of_pass = buffer.buffer + in_pass[index_of_pass].label + in_index->offset;
buffer.remove_fast(start_of_pass, size_pass);
for (size_t i = index_of_pass; i < in_index->count; i++)
{
in_pass[i].label -= size_pass;
in_pass[i].password -= size_pass;
}
buffer.remove_fast((uint8_t*)&in_pass[index_of_pass], sizeof(LoginInfo));
in_index->count -= 1;
in_index->offset -= sizeof(LoginInfo);
}
void add_logininfo_to_buffer(Buffer& buffer, const char* label, const char* username, const char* password)
{
int label_start = buffer.add_end((uint8_t*)label, strlen(label) + 1);
int username_start = buffer.add_end((uint8_t*)username, strlen(username) + 1);
int password_start = buffer.add_end((uint8_t*)password, strlen(password) + 1);
Index* index = (Index*)buffer.buffer;
label_start = label_start - index->offset;
username_start = username_start - index->offset;
password_start = password_start - index->offset;
LoginInfo pass = { label_start, username_start, password_start };
index->count++;
index->offset += sizeof(LoginInfo);
buffer.add_middle((uint8_t*)&pass, sizeof(LoginInfo), index->offset - sizeof(LoginInfo));
}
LoginInfoPointer get_logininfo_pointer_from_buffer(Buffer& buffer, int index_of_pass)
{
Index* index = (Index*)buffer.buffer;
LoginInfo* pass = (LoginInfo*)(buffer.buffer + sizeof(Index));
LoginInfoPointer ret;
ret.label = (const char*)buffer.buffer + pass[index_of_pass].label + index->offset;
ret.username = (const char*)buffer.buffer + pass[index_of_pass].username + index->offset;
ret.password = (const char*)buffer.buffer + pass[index_of_pass].password + index->offset;
return ret;
}
void generate_password(std::string& password, int len)
{
srand(time(NULL));
char characters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~!@#$%^&*()_-+={[}]|:;<,>.?";
for (int i = 0; i < len; i++)
{
password += characters[rand() % (sizeof(characters) - 1)];
}
}

94
source/glob.cpp Normal file
View File

@@ -0,0 +1,94 @@
#include "glob.h"
Glob_Result glob(const char* pattern, const char* text)
{
while (*pattern != '\0' && *text != '\0') {
switch (*pattern) {
case '?': {
pattern += 1;
text += 1;
}
break;
case '*': {
Glob_Result result = glob(pattern + 1, text);
if (result != Glob_Result::UNMATCHED) return result;
text += 1;
}
break;
case '[': {
bool matched = false;
bool negate = false;
pattern += 1; // skipping [
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
if (*pattern == '!') {
negate = true;
pattern += 1;
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unclosed [
}
char prev = *pattern;
matched |= prev == *text;
pattern += 1;
while (*pattern != ']' && *pattern != '\0') {
switch (*pattern) {
case '-': {
pattern += 1;
switch (*pattern) {
case ']':
matched |= '-' == *text;
break;
case '\0':
return Glob_Result::SYNTAX_ERROR; // unclosed [
default: {
matched |= prev <= *text && *text <= *pattern;
prev = *pattern;
pattern += 1;
}
}
}
break;
default: {
prev = *pattern;
matched |= prev == *text;
pattern += 1;
}
}
}
if (*pattern != ']') return Glob_Result::SYNTAX_ERROR; // unclosed [
if (negate) matched = !matched;
if (!matched) return Glob_Result::UNMATCHED;
pattern += 1;
text += 1;
}
break;
case '\\':
pattern += 1;
if (*pattern == '\0') return Glob_Result::SYNTAX_ERROR; // unfinished escape
// fallthrough
default: {
if (*pattern == *text) {
pattern += 1;
text += 1;
}
else {
return Glob_Result::UNMATCHED;
}
}
}
}
if (*text == '\0') {
while (*pattern == '*') pattern += 1;
if (*pattern == '\0') return Glob_Result::MATCHED;
}
return Glob_Result::UNMATCHED;
}

156
source/main.cpp Normal file
View File

@@ -0,0 +1,156 @@
#include <iostream>
#include <fstream>
#include "win.h"
#include "buffer.h"
#include "cryptography.h"
#include "func.h"
#include "arg_func.h"
#ifdef _DEBUG
#define DEBUG 0
#endif // DEBUG
int main(int argc, char** argv)
{
std::string user_pass = "";
char* label = nullptr;
Arg args = Arg::Error;
std::optional<std::string> save_location_path = std::nullopt;
std::string save_location = "";
#if DEBUG
user_pass = "123";
args = Arg::Print_all_p;
std::string label_st = "facebook";
label = label_st.data();
save_location = "passwords.bin";
#else
args = get_args(argc, argv, &label);
if (args == Arg::Error) return 1;
save_location_path = get_save_path();
if (!save_location_path.has_value())
{
printf_s("Error geting file for save path\n");
return 1;
}
std::fstream ifile(save_location_path.value(), std::ios::binary || std::ios::in);
if (ifile.is_open())
{
std::getline(ifile, save_location);
ifile.close();
}
if (save_location.empty() && args != Arg::File)
{
printf_s("No save location, try selecting folder (-f)\n");
return 1;
}
#endif // DEBUG
Buffer encrypted_buffer;
//load file
if (!encrypted_buffer.load_from_file(save_location))
// if file doesn't exist, check if it's a new password is being generated if not, exit
if (!(args == Arg::Generate || args == Arg::Input || args == Arg::File)) {
printf_s("No passwords, try generating password (-g or -i)\n");
return 1;
}
#if !DEBUG
printf_s("Input main password:");
user_pass = get_user_password();
if (user_pass.empty())
{
printf_s("Error getting password\n");
return 1;
}
#endif // !1
Cryptography crypto(user_pass.c_str(), user_pass.size());
Buffer decrypted_buffer;
//check if encrypted buffer is empty if not, decrypt it
if (encrypted_buffer.size > 0)
if (!crypto.decrypt(&encrypted_buffer, &decrypted_buffer)) return 1;
//if decrypted buffer is empty, add index
if (decrypted_buffer.taken < sizeof(Index)) {
Index index = { 0 };
index.offset = sizeof(Index);
decrypted_buffer.add_end((uint8_t*)&index, sizeof(Index));
}
std::optional<LoginInfoPointer> login_info;
switch (args)
{
case Arg::Get:
login_info = arg_get(decrypted_buffer, label);
break;
case Arg::Generate:
login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, true);
break;
case Arg::List:
arg_list(decrypted_buffer);
break;
case Arg::Delete:
arg_delete(decrypted_buffer, encrypted_buffer, label, crypto);
break;
case Arg::Print_all_p:
arg_print_all_p(decrypted_buffer, user_pass);
break;
case Arg::Input:
login_info = arg_new_password(decrypted_buffer, encrypted_buffer, label, crypto, false);
break;
case Arg::Username:
arg_username(decrypted_buffer, encrypted_buffer, label, crypto);
break;
case Arg::Name:
arg_label_name(decrypted_buffer, encrypted_buffer, label, crypto);
break;
case Arg::Change:
arg_change(decrypted_buffer, encrypted_buffer, user_pass, crypto);
break;
case Arg::Show:
arg_show(decrypted_buffer, label);
break;
case Arg::File:
arg_file(decrypted_buffer, encrypted_buffer, label, crypto, save_location_path.value());
break;
}
if (!login_info.has_value()) return 0;
#if DEBUG
printf_s("Username: %s\n", login_info.value().username);
printf_s("Password: %s\n", login_info.value().password);
#else
printf_s("Username: %s\n", login_info.value().username);
put_data_on_clipboard(login_info.value().password);
printf_s("Password copied to clipboard\n");
#endif // _DEBUG
return 0;
}

108
source/win.cpp Normal file
View File

@@ -0,0 +1,108 @@
#include <Windows.h>
#include <iostream>
#include <string>
#include <shlobj.h>
#include "win.h"
#include "func.h"
bool put_data_on_clipboard(const char* text) {
size_t len = strlen(text);
if (len == 0) {
printf_s("Text is empty\n");
return false;
}
// Open the clipboard
if (!OpenClipboard(nullptr)) {
printf_s("Failed to open clipboard");
return false;
}
// Allocate global memory for the text
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, strlen(text) + 1);
if (!hMem) {
CloseClipboard();
printf_s("Failed to allocate memory for text");
return false;
}
// Copy the text to the allocated memory
char* memData = static_cast<char*>(GlobalLock(hMem));
if (!memData) {
CloseClipboard();
printf_s("Failed to lock memory for text");
return false;
}
strcpy_s(memData, strlen(text) + 1, text);
GlobalUnlock(hMem);
// Set the data to the clipboard
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
// Clean up and close the clipboard
CloseClipboard();
return true;
}
std::string get_user_password()
{
HANDLE hStdInput = GetStdHandle(STD_INPUT_HANDLE);
DWORD mode = 0;
// Create a restore point Mode
// is know 503
GetConsoleMode(hStdInput, &mode);
// Enable echo input
// set to 499
SetConsoleMode(hStdInput, mode & (~ENABLE_ECHO_INPUT));
// Take input
std::string ipt;
std::getline(std::cin, ipt);
// Otherwise next cout will print
// into the same line
std::cout << std::endl;
// Restore the mode
SetConsoleMode(hStdInput, mode);
return ipt;
}
std::optional<std::string> get_save_path()
{
PWSTR path = nullptr;
HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramData, 0, nullptr, &path);
if (!SUCCEEDED(result)) {
CoTaskMemFree(path); // Free the allocated memory
return{};
}
std::wstring userDirectory(path);
CoTaskMemFree(path); // Free the allocated memory
userDirectory.append(L"\\password_manager");
DWORD attrib = GetFileAttributes(userDirectory.c_str());
//check if it exists
if(!(attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY)))
{
if (!CreateDirectory(userDirectory.c_str(), nullptr)) return {};
}
userDirectory.append(L"\\save.txt");
int size = WideCharToMultiByte(CP_UTF8, 0, userDirectory.c_str(), -1, nullptr, 0, nullptr, nullptr);
if (size > 0) {
std::string str(size, 0);
WideCharToMultiByte(CP_UTF8, 0, userDirectory.c_str(), -1, &str[0], size, nullptr, nullptr);
return str;
}
return {};
}