#pragma once
/*
  Полезные инструменты для Malware.
*/

#include "crypt.h"

namespace MalwareTools
{
  //Флаги форматирования имени.
  enum
  {
    NCF_ALL_LOWER    = 0x0, //Все в нижнем регистре.
    //NCF_ALL_UPPER   = 0x1, Пока не нужен
    NCF_FIRST_UPPER  = 0x2, //Первый символ в верхенм регистре, остальное в нижнем.
    NCF_ALLOW_SPACES = 0x4 //Разрешить пробелы.
  };

  //Область видимости объекта ядра.
  enum
  {
    KON_DEFAULT, //По умолчанию, без префикса.
    KON_SESSION, //Внутри текущей сессии, префикс Local.
    KON_GLOBAL,  //Глобальный, префикс Global.
  };
  
  /*
    Инициализация.
  */
  void init(void);

  /*
    Деинициализация.
  */
  void uninit(void);

  /*
    Генерация имени.

    IN dwCaseFlags - флаги NCF_*.
    OUT pstrName   - буфер для имени.
    IN bMinChars   - минимальное количество символов в имени.
    IN bMaxChars   - макимальное количество символов в имени.
  */
  void _GenerateRandomNameW(DWORD dwCaseFlags, LPWSTR pstrName, BYTE bMinChars, BYTE bMaxChars);
  void _GenerateRandomNameA(DWORD dwCaseFlags, LPSTR pstrName, BYTE bMinChars, BYTE bMaxChars);

  /*
    Надстройка над _GenerateRandomNameW, которая проверяет свободно ли данное имя в директории.

    IN dwCaseFlags   - флаги NCF_*.
    IN pstrPath      - директория для проверки.
    OUT pstrName     - полный путь файла, размер буфера должен быть не менее MAX_PATH сиволов 
                       включая нулевой символ.
    IN pstrExtension - расширение файла, или NULL.
    IN bMinChars     - минимальное количество символов в имени.
    IN bMaxChars     - макимальное количество символов в имени.

    Return           - true - в случаи успеха,
                       false - в случаи ошибки.
  */
  bool _GenerateRandomFileName(DWORD dwCaseFlags, LPWSTR pstrPath, LPWSTR pstrName, LPWSTR pstrExtension, BYTE bMinChars, BYTE bMaxChars);

  
  /*
    Надстройка над _GenerateRandomNameW, которая проверяет свободен ли данный ключ в реестре.

    IN dwCaseFlags - флаги NCF_*.
    IN hRoot       - открытй путь реестра.
    IN pstrPath    - путь для проверки.
    OUT pstrName   - сгенерированое имя относительно pstrPath.
    IN bMinChars   - минимальное количество символов в имени.
    IN bMaxChars   - макимальное количество символов в имени.

    Return         - true - в случаи успеха,
                     false - в случаи ошибки.
  */
  bool _GenerateRandomRegKeyName(DWORD dwCaseFlags, HKEY hRoot, LPWSTR pstrPath, LPWSTR pstrName, BYTE bMinChars, BYTE bMaxChars);
  
  /*
    Получение уникального ID системы.

    OUT guid - ID системы.

    Return   - true - в случаи успеха,
               false - в случаи ошибки (pGUID будет заполнен нулями).
  */
  bool _getOsGuid(GUID *guid);

  /*
    Генерирование уникального имени для объекта ядра в виде GUID.

    IN osGuid          - результат _getOsGuid().
    IN advId1          - дополнительный индефикатор 1.
    IN advId2          - дополнительный индефикатор 2.
    OUT buffer         - буфер для "CLSID", как минимум 40 символов. А если (asLocal == true), то 50.
    IN rc4Key          - ключ для шифрования(не изменяется), или NULL.
    IN objectNamespace - видимость элемента KON_*.
  */
  void _generateKernelObjectName(GUID *osGuid, DWORD advId1, DWORD advId2, LPWSTR buffer, Crypt::RC4KEY *rc4Key, BYTE objectNamespace);
};
