unit FProc;

interface

uses
  Windows;

function IsFileExist(const fn: WideString): boolean; overload;
function IsFileExist(const fn: WideString; var IsDir: boolean): boolean; overload;
function IsDirExist(const fn: WideString): boolean;
function FFullName(const fn: WideString; var fnOut: WideString): boolean;

function ToOEM(const s: string): AnsiString;
function ToANSI(const s: AnsiString): string;

const
  FILE_ATTRIBUTE_DEVICE               = $00000040;
  FILE_ATTRIBUTE_SPARSE_FILE          = $00000200;
  FILE_ATTRIBUTE_REPARSE_POINT        = $00000400;
  FILE_ATTRIBUTE_OFFLINE              = $00001000;
  FILE_ATTRIBUTE_NOT_CONTENT_INDEXED  = $00002000;
  FILE_ATTRIBUTE_ENCRYPTED            = $00004000;

type
  TGetFinalPathNameByHandleW = function(
    hFile: THandle;
    FilePath: PWideChar;
    FilePathSize: DWORD;
    Flags: DWORD): DWORD; stdcall;

type
  TCreateSymbolicLink = function(
    SymlinkFileName,
    TargetFileName: PWideChar;
    Flags: DWORD): BOOL; stdcall;

const
  FILE_NAME_NORMALIZED = 0;
  SYMBOLIC_LINK_FLAG_DIRECTORY = $1;


function IsWindowsVista: boolean;
function SFormatLastError(ErrorCode: DWORD): WideString;


implementation

uses
  SysUtils;

//----------------------------------------------
function IsFileExist(const fn: WideString; var IsDir: boolean): boolean;
var
  h: THandle;
  fdA: TWin32FindDataA;
  fdW: TWin32FindDataW;
begin
  Result:= false;
  IsDir:= false;
  if fn='' then Exit;

  if Win32Platform = VER_PLATFORM_WIN32_NT then
    begin
    h:= FindFirstFileW(PWideChar(fn), fdW);
    Result:= h <> INVALID_HANDLE_VALUE;
    if Result then
      begin
      IsDir:= (fdW.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
      Windows.FindClose(h);
      end;
    end
  else
    begin
    h:= FindFirstFileA(PAnsiChar(AnsiString(fn)), fdA);
    Result:= h <> INVALID_HANDLE_VALUE;
    if Result then
      begin
      IsDir:= (fdA.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0;
      Windows.FindClose(h);
      end;
    end;
end;

//----------------------------------------------
function IsFileExist(const fn: WideString): boolean;
var
  IsDir: boolean;
begin
  Result:= IsFileExist(fn, IsDir);
end;

function IsDirExist(const fn: WideString): boolean;
var
  IsDir: boolean;
begin
  Result:= IsFileExist(fn, IsDir) and IsDir;
end;

//----------------------------------------------
function FFullName(const fn: WideString; var fnOut: WideString): boolean;
var
  bufA: array[0 .. MAX_PATH - 1] of AnsiChar;
  bufW: array[0 .. MAX_PATH - 1] of WideChar;
  partA: PAnsiChar;
  partW: PWideChar;
begin
  fnOut:= '';
  if Win32Platform = VER_PLATFORM_WIN32_NT then
    begin
    FillChar(bufW, SizeOf(bufW), 0);
    Result:= GetFullPathNameW(PWideChar(fn), SizeOf(bufW) div 2, bufW, partW) <> 0;
    if Result then
      fnOut:= bufW;
    end
  else
    begin
    FillChar(bufA, SizeOf(bufA), 0);
    Result:= GetFullPathNameA(PAnsiChar(Ansistring(fn)), SizeOf(bufA), bufA, partA) <> 0;
    if Result then
      fnOut:= WideString(AnsiString(bufA));
    end;
end;

//----------------------------------------------
function ToOEM(const s: string): Ansistring;
begin
  SetLength(Result, Length(s));
  CharToOemBuff(PChar(s), PAnsiChar(Result), Length(s));
end;

function ToANSI(const s: AnsiString): string;
begin
  SetLength(Result, Length(s));
  OemToCharBuff(PAnsiChar(s), PWideChar(Result), Length(s));
end;

//----------------------------------------------
function IsWindowsVista: boolean;
begin
  Result:=
    (Win32Platform = VER_PLATFORM_WIN32_NT) and
    (Win32MajorVersion >= 6);
end;

//----------------------------------------------
function SFormatLastError(ErrorCode: DWORD): WideString;
var
  bufA: array[0..500] of AnsiChar;
  bufW: array[0..500] of WideChar;
begin
  Result:= '';
  if Win32Platform = VER_PLATFORM_WIN32_NT then
    begin
    if FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,
      nil, ErrorCode, 0, bufW, SizeOf(bufW) div 2, nil)>0 then
      Result:= bufW;
    end
  else
    begin
    if FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_ARGUMENT_ARRAY,
      nil, ErrorCode, 0, bufA, SizeOf(bufA), nil)>0 then
      Result:= string(bufA);
    end;
end;


end.
