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

#include "crypt.h"

namespace MalwareTools
{
  //Flags format name.
  enum
  {
    NCF_ALL_LOWER    = 0x0, //All in lowercase.
    //NCF_ALL_UPPER = 0x1, yet do not need
    NCF_FIRST_UPPER  = 0x2, //The first character in verhenm register, the rest at the bottom.
    NCF_ALLOW_SPACES = 0x4 //Allow spaces.
  };

  //The scope of a kernel object.
  enum
  {
    KON_DEFAULT, //By default, no prefix.
    KON_SESSION, //Within the current session, the prefix Local.
    KON_GLOBAL,  //Global, prefix 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);

  /*В В В В Generating a unique name for the kernel object in the form of GUID.

В В В В IN osGuid - result _getOsGuid ().
В В В В IN advId1 - additional indefikator 1.
В В В В IN advId2 - additional indefikator 2.
В В В В OUT buffer - a buffer for "CLSID", at least 40 characters. And if (asLocal == true), then 50.
В В В В IN rc4Key - key to encrypt (unchanged), or NULL.
В В В В IN objectNamespace - visibility element KON_ *.
В В */
  void _generateKernelObjectName(GUID *osGuid, DWORD advId1, DWORD advId2, LPWSTR buffer, Crypt::RC4KEY *rc4Key, BYTE objectNamespace);
};
