#ifndef __RKAPI_
#define __RKAPI_
//#pragma pack(1)
#include <wchar.h>
#include <wtypes.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

typedef unsigned int    __u32;
typedef unsigned __int64 __u64;

#define bool BOOL

#ifdef UNICODE
#define RKFindFirstFile      RKFindFirstFileW
#define RKGetFileAttribute   RKGetFileAttributeW
#define RKFindFastFirstFile  RKFindFastFirstFileW
#define RKFindNextFile       RKFindNextFileW
#else
#define RKFindFirstFile      RKFindFirstFileA
#define RKGetFileAttribute   RKGetFileAttributeA
#define RKFindFastFirstFile  RKFindFastFirstFileA
#define RKFindNextFile       RKFindNextFileW
#endif



FILE *RKfopen(const char *lpFileName, const char *mode);
/*
Function RKfopen(): Microsoft fopen() API replacement

  Parameters:
  - lpFileName: Ascii UTF8 Filename to open
  - mode
  Type of access allowed:
  'r':  Read File
  'w':  Write file (overwrite)
  'rw': Read / Write
  
    Return value: RKfopen() returns a pointer to the opened file if this can be located. If there is an error,  NULL is returned instead.
    extend error information can be gathered by calling GetLastError()
    
    NOTE: The returned FILE* isnt a real _iobuf struct, just a cast for compatibility with Microsoft CRT api, so data inside this struct
    should look invalid if accessed. The returned stream handle, can not be used with other Microsoft funcions, just with RK* api.
      
    RkDetector API uses native Unicode Support so calls to Unicode functions are faster. If possible, use RK_wfopen() instead of this one.
******************************************************************************/
FILE *RK_wfopen(const wchar_t *lpFilenameW, const wchar_t *mode);
/*
Function RKfopen(): Microsoft fopen() API replacement

  Parameters:
  - lpFileName: Unicode path to the Filename to open
  - mode
  Type of access allowed:
  'r':  Read File
  'w':  Write file (overwrite)
  'rw': Read / Write
  
    Return value: RKfopen() returns a pointer to the opened file if this can be located. If there is an error,  NULL is returned instead.
    extend error information can be gathered by calling GetLastError()
    
    NOTE: The returned FILE* isnt a really  _iobuf struct, just a cast for compatibility with Microsoft CRT api, so data inside this struct
    should look invalid if accessed. The returned stream handle, can not be used with other Microsoft funcions, just with RK* api.
      
    To maximize speed, RK_wfopen() is preffered instead of utf8 api RKfopen()
        
    RkDetector API uses native Unicode Support so calls to Unicode functions are faster. If possible, use RK_wfopen() instead
******************************************************************************/
HANDLE WINAPI RKCreateFileA(
    LPCSTR lpFileName,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
    );
/******************************************************************************/
HANDLE WINAPI RKCreateFileW(
    LPCWSTR lpFilenameW,
    DWORD dwDesiredAccess,
    DWORD dwShareMode,
    LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    DWORD dwCreationDisposition,
    DWORD dwFlagsAndAttributes,
    HANDLE hTemplateFile
    ) ;
/******************************************************************************/
DWORD RKGetFileSize(  FILE *hFile,  LPDWORD lpFileSizeHigh);
/*
Function RKGetFileSize(): Microsoft GetFileSize() API replacement. Retrieves the size of the specified file.

  Parameters:
  - hFile [IN]: Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  - lpFileSizeHigh [ OUT ] A pointer to the variable where the high-order doubleword of the file size is returned. This parameter can be NULL if the application does not require the high-order doubleword
  
    Return value: If the function success, the function returns a dword with low order size bytes. If the file size is greater than 4Gb,
    lpFileSizeHigh is filled with the HigPart bytes. Otherwise RKGetFileSize
    
      If The function fails, RKGetFileSize() returns INVALID_FILE_SIZE. Check GetLastError() for extended information:
      - If lpFileSizeHigh is NULL, the function fails if file is greater than 4GB
      - If lpFileSizeHigh is not NULL and GetLastError Error Code is NO_ERROR, the function succeded.
      
*******************************************************************************/
long RKFtell(FILE *hFile);
/*
Function RKftell(): Microsoft ftell() API replacement. Retrieves the current file position.

  Parameters:
  - hFile [IN]: Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  
    Remarks:
    If no I/O operation has yet occurred on a file opened for appending, the file position is the beginning of the file.
    On error, 1L  is returned
    
      If the file size is greater than 4Gb, the value could look invalid, so RK_ftelli64 is preferred
*******************************************************************************/
__int64 RK_ftelli64(FILE *hFile);
/*
Function RK_ftelli64(): Microsoft ftell() API replacement. Retrieves the current file position.

  Parameters:
  - hFile [IN]: Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  
    Remarks:
    If no I/O operation has yet occurred on a file opened for appending, the file position is the beginning of the file.
    On error, 1L  is returned
    
*******************************************************************************/
int RKFeof(FILE *hFile) ;
/*
Function RKfeof(): Microsoft feof() API replacement. Checks end of file over a FILE stream opened by RKapis

  Parameters:
  - hFile [IN]: Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  
    Remarks: If the handle is invalid, TRUE will be returned
    
*******************************************************************************/
int RKFread(char *buffer, size_t size,size_t count, FILE * hFile ) ;
/*
Function RKFread(): Microsoft fread() API replacement. reads data from a stream

  Parameters:
  - Buffer [OUT]: Pointer to the buffer where data will be readed
  - size [IN]: Number of bytes to read
  - count [IN]: Unused. by default using '1' sizeof(char) )
  - hFile [IN]: Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  
  Remarks: If there is an error, zero is returned. Call GetLastError() for extended information
  RKFread() does not support external File handles, like stdin, stderr, stdout.

  NOTE:
  RKFread supports buffering for reading files. This means that you can read variable length chunks
  For optimum performance, specify size should be multiple of cluster Size
    
******************************************************************************/
int RKFwrite(const char *buffer,const unsigned int size,unsigned int __count, FILE *hFile  ) ;
   
/*
Function RKFwrite(): Microsoft fwrite() API replacement. reads data from a stream

  Parameters:
  - Buffer [IN]: Pointer to the buffer where data will be readed
  - size [IN]:   Number of bytes to read
  - count [IN]:  Unused. by default using '1' sizeof(char) )
  - hFile [IN]:  Handle to the file, returned by previous call to RKfopen() or RK_wfopen
  
    Remarks: If there is an error, 0 is returned. Call GetLastError() for extended information
    RKFwrite() does not support external File handles, like stdin, stderr, stdout.
    
 ******************************************************************************/
BOOL WINAPI RKSetFilePointerEx( const HANDLE hFile,const LARGE_INTEGER liDistanceToMove,PLARGE_INTEGER lpNewFilePointer,const DWORD dwMoveMethod) ;
/*
Function RKSetFilePointerEx(): Microsoft SetFilePointerEx() API replacement. Moves the file pointer of the specified file.

   Parameters
   - hFile [in] A handle to the file. The file handle must have been created with RKCreateFile() .
   - liDistanceToMove: [in] The number of bytes to move the file pointer. A positive value moves the pointer forward in the file and a negative value moves the file pointer backward.
   - lpNewFilePointer: [out, optional] A pointer to a variable to receive the new file pointer. If this parameter is NULL, the new file pointer is not returned.
   - dwMoveMethod:     [in] The starting point for the file pointer move. This parameter can be one of the following values: FILE_BEGIN, FILE_CURRENT: FILE_END

  If the function succeeds returns 1, otherwise 0 is returned.
  This function is preffered Instead of SetFilePointer()
******************************************************************************/
BOOL WINAPI RKSetFilePointer( const HANDLE hFile, const LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,const DWORD dwMoveMethod) ;
/*
Function RKSetFilePointer(): Microsoft SetFilePointer() API replacement. Moves the file pointer of the specified file.

   Parameters:
   - hFile: [in] A handle to the file.The file handle must be created with the RKCreateFile().
   - lDistanceToMove: [in] The low order 32-bits of a signed value that specifies the number of bytes to move the file pointer.
   - lpDistanceToMoveHigh: [in, out, optional] A pointer to the high order 32-bits of the signed 64-bit distance to move.
    If lpDistanceToMoveHigh is not NULL, lpDistanceToMoveHigh and lDistanceToMove form a single 64-bit signed value that specifies the distance to move.
    If you do not need the high order 32-bits, this pointer must be set to NULL.
   - dwMoveMethod: [in] The starting point for the file pointer move: FILE_BEGIN, FILE_CURRENT: FILE_END

  it is easier and faster to use the RKSetFilePointerEx() function
  Return Value: SetFilePointer() returns a DWORD with the low 32bits of the new pointer
  If the function fails, the return value is INVALID_SET_FILE_POINTER. To get extended error information, call GetLastError
******************************************************************************/
__inline int RKFseek(const FILE *stream,const __u32 size,const int whence  ) ;
/*
   Function RKFseek(): Microsoft CRT fseek() API replacement. Moves the file pointer of the specified stream
   
   Parameters:
   - stream:[IN] File Handle returned by previus RKFopen() call
   - whence: [IN]The starting point for the file pointer move: SEEK_BEGIN, SEEK_CUR, SEEK_END

  Fseek Implementation for NTFS/FAT32 - 4Gb Limitation
  If successful, fseek returns 0. Otherwise, it returns a nonzero value
******************************************************************************/

__inline int RK_fseeki64(const FILE *stream,const __int64 size,const int whence  ) ;
/*
   Function RKFseek(): Microsoft CRT fseek() API replacement. Moves the file pointer of the specified stream
   
   Parameters:
   - stream:[IN] File Handle returned by previus RKFopen() call
   - whence: [IN]The starting point for the file pointer move: SEEK_BEGIN, SEEK_CUR, SEEK_END

  Fseek Implementation for NTFS/FAT32 - 4Gb Limitation
  If successful, fseek returns 0. Otherwise, it returns a nonzero value
******************************************************************************/
BOOL RKCloseHandle(HANDLE hFile) ;
/*
   Function RKCloseHandle(): Microsoft  fclose() API replacement. Closes a stream

   Parameters:
   - stream:[IN] File Handle returned by previus RKFopen() call

   If successful, fseek returns 0. Otherwise, it returns zero
******************************************************************************/
int RKFClose(FILE *stream) ;
/*
   Function RKFClose(): Microsoft  fclose() API replacement. Closes a stream

   Parameters:
   - stream:[IN] File Handle returned by previus RKFopen() call

   If successful, RKFclose returns Zero.
******************************************************************************/
__inline DWORD RKGetFastFileAttributes(FILE *stream) ;
/*
    Rkdetector - Fast implementation of RKGetFileAttributes.

    Parameters:
     - stream: FILE * returned by previous call to RKfopen()

     return value: If succes, returns a DWORD with FAT file attributes,
******************************************************************************/
__inline DWORD RKGetFastHandleAttributes(HANDLE hFile) ;
/*
    Rkdetector - Fast implementation of RKGetFileAttributes.

    Parameters:
     - hFile: HANDLE returned by previous Call to RKCreateFile()

    return value: If succes, returns a DWORD with FAT file attributes,
******************************************************************************/
DWORD RKGetFileAttributesW( const wchar_t *lpFileName) ;
/*
   Function RKGetFileAttributesW(): Microsoft  GetFileAttributesW() API replacement.
   Retrieves a set of FAT file system attributes for a specified file or directory.

   Parameters:
   - lpFileName:[IN] Unicode FileName

   If the function succeeds, the return value contains the attributes of the specified file or directory.
   If the function fails, the return value is INVALID_FILE_ATTRIBUTES. To get extended error information.

   Note: This function is slow, call RKGetFastFileAttributes() or  RKGetFastHandleAttributes() if possible
******************************************************************************/
DWORD RKGetFileAttributesA(  const char *lpFileName) ;
/*
   Function RKGetFileAttributesW(): Microsoft  GetFileAttributesW() API replacement.
   Retrieves a set of FAT file system attributes for a specified file or directory.

   Parameters:
   - lpFileName:[IN] Ascii UTF8 FileName

   If the function succeeds, the return value contains the attributes of the specified file or directory.
   If the function fails, the return value is INVALID_FILE_ATTRIBUTES. To get extended error information.

   Note: This function is slow, call RKGetFastFileAttributes() or  RKGetFastHandleAttributes() if possible
******************************************************************************/
/******          RKDetector - FindFirstFile api replacement     ***************/
/******************************************************************************/
HANDLE RKFindFirstFileA(const char *lpPath, WIN32_FIND_DATA *lpFindFileData) ;
/*
   Function RKFindFirstFileA(): Microsoft  FindFirstFileA() API replacement.
   Searches a directory for files or subdirectories.

   Parameters:
   - lpPath:[IN] Ascii UTF8 path to FileName
   - lpFindFileData: [OUT] A pointer to the WIN32_FIND_DATAA structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is a search handle used in a subsequent call to RKFindNextFile or RKFindClose.
   If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError..

   NOTE:
   - The name passed MUST be a path, and wildcards are not allowed.
   - RKFindFirstFileA() Doesn't return "." and ".."
   - This function is the most time-consuming of all. On the good side, RKFindNextFile() uses almost no CPU and, keep this in mind:
    * RKFINDNEXTFILE DOES NOT ACCESS THE DISK - IT HAS A CACHED LIST.
    * That's why FindFirstFile is the most time-consuming.

   Note: Rkdetector API is builtin with Unicode support by default. RkxxxW() Functions area faster because Utf8 ->Unicode -> Utf8 operations are not performed.
   You should keep this in mind and call RKFindFirstFileW() instead.

   * There is an optimized version of RKFindFirstFileA() Api named RKFindFastFirstFileA() that will save up to 40% of the analysis when browsing the fulll drive.
******************************************************************************/
HANDLE RKFindFirstFileW(const wchar_t *lpPathW, WIN32_FIND_DATAW *lpFindFileDataW) ;
   /*
   Function RKFindFirstFileW(): Microsoft  FindFirstFileW() API replacement.
   Searches a directory for files or subdirectories.

   Parameters:
   - lpPath:[IN] Unicode path to FileName
   - lpFindFileDataW: [OUT] A pointer to the WIN32_FIND_DATAW structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is a search handle used in a subsequent call to RKFindNextFile or RKFindClose.
   If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError..

   NOTE:
   - The name passed MUST be a path, and wildcards are not allowed.
   - RKFindFirstFileW() Doesn't return "." and ".."
   - This function is the most time-consuming of all. On the good side, RKFindNextFile() uses almost no CPU and, keep this in mind:
    * RKFINDNEXTFILE DOES NOT ACCESS THE DISK - IT HAS A CACHED LIST.
    * That's why FindFirstFile is the most time-consuming.

   Note: Rkdetector API is builtin with Unicode support by default.Use RKFindFirstFileW() instead of Ascii utf8 implementations

   * There is an optimized version of RKFindFirstFileW() Api named RKFindFastFirstFileW() that will save up to 40% of the analysis when browsing the full drive.
******************************************************************************/
/******          RKDetector - Fast FindFirstFile api replacement     **********/
/******************************************************************************/
HANDLE RKFindFastFirstFileA(const char *lpPath, WIN32_FIND_DATA *lpFindFileData) ;
/*
   Function RKFindFastFirstFileA(): Optimized RKFindFirstFileA() Api
   Searches a directory for files or subdirectories.

   Parameters:
   - lpPath:[IN] Ascii UTF8 path to FileName
   - lpFindFileData: [OUT] A pointer to the WIN32_FIND_DATAA structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is a search handle used in a subsequent call to RKFindNextFile or RKFindClose.
   If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

   NOTE:
   - The name passed MUST be a path, and wildcards are not allowed.
   - RKFindFirstFastFileA() Doesn't return "." and ".."
   - Rkdetector API is builtin with Unicode support by default.Use RKFindFastFirstFileW() instead of Ascii utf8 implementations

  REMARKS:
  RKFindFirstFileA Api has an internal cache table but will perform more disks IO operations than RKFindFastFirstFileA
  All calls to RKFindxxxFile() returns a filled Win32_find_Data struct. Under NTFS the value lpFindFileData->dwReserved1 always stores the value of the
  File mft record or the file cluster under FAT32/16.
  If this function is called with a non Zero value at dwReserved1 the mft/cluster record will be directly readed instead of reparsing all the paths

  If possible, call the Unicode function RKFindFastFirstFileW
  
  Example: There is an example at the SDK directory

******************************************************************************/
HANDLE RKFindFastFirstFileW(const wchar_t *lpPathW, WIN32_FIND_DATAW *lpFindFileDataW) ;
/*
   Function RKFindFastFirstFileW(): Optimized RKFindFirstFileW() Api
   Searches a directory for files or subdirectories.

   Parameters:
   - lpPathW:[IN] Unicode path to FileName
   - lpFindFileDataW: [OUT] A pointer to the WIN32_FIND_DATAW structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is a search handle used in a subsequent call to RKFindNextFile or RKFindClose.
   If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.

   NOTE:
   - The name passed MUST be a path, and wildcards are not allowed.
   - RKFindFirstFastFileW() Doesn't return "." and ".."

  REMARKS:
  RKFindFirstFileW Api has an internal cache table but is slower because it will perform more disks IO operations than RKFindFastFirstFileW
  All calls to RKFindxxxFileW() returns a filled Win32_find_DataW struct. Under NTFS the value lpFindFileData->dwReserved1 always stores the value of the
  File mft record or the file cluster under FAT32/16.
  If this function is called with a non Zero value at dwReserved1 the mft/cluster record will be directly readed instead of reparsing all the paths

  For opening a directory, this API is the best choice
  
  Example: There is an example at the SDK directory

******************************************************************************/
/******          RKDetector - FindNextFile api replacement     ***************/
/******************************************************************************/
BOOL RKFindNextFileA(const HANDLE handle, WIN32_FIND_DATA *lpFindFileData) ;
 /*
   Function RKFindNextFileA(): Microsoft  FindNextFileA() API replacement.
   Continues a file search from a previous call to the RKFindFirstFile Function

   Parameters:
   - handle:[IN] Directory handle recurned by previous call to RKFindFirstFile or RKFindFirstFastFile
   - lpFindFileData: [OUT] A pointer to the WIN32_FIND_DATAA structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is nonzero
   If the function fails, the return value is zero. To get extended error information, call GetLastError.
   ERROR_NO_MORE_FILES will be returned if there are no more files in the subdirectory. 
   Note that RKDetector API does not return the first "." and ".." entries so an INVALID_HANDLE_VALUE with GetLastError()==ERROR_NO_MORE_FILES
   will be returned sometimes

   NOTE:
   - If possible, call the Unicode function RKFindNextFileW()
******************************************************************************/
BOOL RKFindNextFileW(const HANDLE handle, WIN32_FIND_DATAW *lpFindFileData) ;
 /*
   Function RKFindNextFileW(): Microsoft  FindNextFileW() API replacement.
   Continues a file search from a previous call to the RKFindFirstFile Function

   Parameters:
   - handle:[IN] Directory handle recurned by previous call to RKFindFirstFile or RKFindFirstFastFile
   - lpFindFileData: [OUT] A pointer to the WIN32_FIND_DATAW structure that receives information about a found file or subdirectory

   Return Value:
   If the function succeeds, the return value is nonzero
   If the function fails, the return value is zero. To get extended error information, call GetLastError.
   ERROR_NO_MORE_FILES will be returned if there are no more files in the subdirectory. 
   Note that RKDetector API does not return the first "." and ".." entries so an INVALID_HANDLE_VALUE with GetLastError()==ERROR_NO_MORE_FILES
   will be returned sometimes
******************************************************************************/
BOOL RKFindClose(HANDLE hFindFile) ;
 /*
   Function RKFindClose(): Microsoft  FindClose() API replacement.
   Closes a file search handle opened by the FindFirstFile of FindFastFirstFile()

   Parameters:
   - hFindFile:[IN] handle recurned by previous call to RKFindFirstFile or RKFindFirstFastFile

   Return Value:
   If the function succeeds, the return value is nonzero.
   If the function fails, the return value is zero. To get extended error information, call GetLastError.
   
     Remarks:
   After the RKFindClose function is called, the handle specified by the hFindFile parameter cannot be used in subsequent calls to the RKFindNextFile Function

******************************************************************************/



#endif