%% options
copyright owner = Dirk Krause
copyright year = 2015-xxxx
license = bsd
%% header
/** @file
Obtain unique file identifier for path specified as char string.
On non-Windows systems the UFI consists of inode number and
device number. On Windows systems the volume serial number,
higher index number and lower index number are used.
CRT on Windows: Not used.
*/
#ifndef DK4UFI_H_INCLUDED
#include "dk4ufit.h"
#endif
#ifndef DK4ERROR_H_INCLUDED
#include "dk4error.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** Retrieve unique file identifier.
For symbolic links on non-Windows systems, retrieve
information about the link target.
@param dptr Destination buffer.
@param fn File name.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_INVALID_ARGUMENTS
if dptr or fn is NULL,
- DK4_E_SYSTEM
with errno value stored in iDetails1 if the stat() function fails on
non-Windows systems,
- DK4_E_CREATE_FILE_FAILED
with GetLastError() result in lDetails1 if the CreateFile() function
fails on Windows,
- DK4_E_FILE_INFORMATION_FAILED
with GetLastError() result in lDetails1 if the
GetFileInformationByHandle() function fails on Windows.
- DK4_E_NOT_FOUND
if the GetFileAttributes() function fails to retrieve file
attributes on Windows.
*/
int
dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
/** Retrieve unique file identifier.
For symbolic links on non-Windows systems, retrieve
information about the link.
@param dptr Destination buffer.
@param fn File name.
@param erp Error report, may be NULL.
@return 1 on success, 0 on error.
Error codes:
- DK4_E_INVALID_ARGUMENTS
if dptr or fn is NULL,
- DK4_E_SYSTEM
with errno value stored in iDetails1 if the lstat() function fails
on non-Windows systems,
- DK4_E_CREATE_FILE_FAILED
with GetLastError() result in lDetails1 if the CreateFile() function
fails on Windows,
- DK4_E_FILE_INFORMATION_FAILED
with GetLastError() result in lDetails1 if the
GetFileInformationByHandle() function fails on Windows.
- DK4_E_NOT_FOUND
if the GetFileAttributes() function fails to retrieve
file attributes on Windows.
*/
int
dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp);
#ifdef __cplusplus
}
#endif
%% module
#include "dk4conf.h"
#if DK4_ON_WINDOWS
#ifndef WINDOWS_H_INCLUDED
#include
#define WINDOWS_H_INCLUDED 1
#endif
#else
#include "dk4stat8.h"
#endif
#include "dk4ufi08.h"
int
dk4ufi_get_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
{
#if DK4_ON_WINDOWS
BY_HANDLE_FILE_INFORMATION bhfi;
WIN32_FIND_DATAA ffdata;
HANDLE han;
DWORD dwattr;
int i;
int back = 0;
if ((NULL != dptr) && (NULL != fn)) {
dwattr = GetFileAttributesA(fn);
if (INVALID_FILE_ATTRIBUTES == dwattr) {
han = FindFirstFileA(fn, &ffdata);
if (INVALID_HANDLE_VALUE != han) {
dwattr = ffdata.dwFileAttributes;
FindClose(han);
}
}
if (INVALID_FILE_ATTRIBUTES != dwattr) {
if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
}
for (i = 0; ((2 > i) && (0 == back)); i++) {
han = CreateFileA(
fn,
((0 == i) ? (0) : (GENERIC_READ)),
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
dwattr,
NULL
);
if (INVALID_HANDLE_VALUE != han) {
if (GetFileInformationByHandle(han, &bhfi)) {
back = 1;
dptr->ser = bhfi.dwVolumeSerialNumber;
dptr->inh = bhfi.nFileIndexHigh;
dptr->inl = bhfi.nFileIndexLow;
} else {
if (1 == i) {
/* ERROR: Failed */
dk4error_set_ldetails(
erp, DK4_E_FILE_INFORMATION_FAILED,
(long)((unsigned long)GetLastError())
);
}
}
CloseHandle(han);
} else {
if (1 == i) {
/* ERROR: Failed */
dk4error_set_ldetails(
erp, DK4_E_CREATE_FILE_FAILED,
(long)((unsigned long)GetLastError())
);
}
}
}
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4_stat_t stb;
int back = 0;
if ((NULL != dptr) && (NULL != fn)) {
if (0 != dk4stat_c8(&stb, fn, erp)) {
dptr->dev = stb.st_dev;
dptr->ino = stb.st_ino;
back = 1;
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#endif
}
int
dk4ufi_get_l_c8(dk4_ufi_t *dptr, const char *fn, dk4_er_t *erp)
{
#if DK4_ON_WINDOWS
BY_HANDLE_FILE_INFORMATION bhfi;
WIN32_FIND_DATAA ffdata;
HANDLE han;
DWORD dwattr;
int i;
int back = 0;
if ((NULL != dptr) && (NULL != fn)) {
dwattr = GetFileAttributesA(fn);
if (INVALID_FILE_ATTRIBUTES == dwattr) {
han = FindFirstFileA(fn, &ffdata);
if (INVALID_HANDLE_VALUE != han) {
dwattr = ffdata.dwFileAttributes;
FindClose(han);
}
}
if (INVALID_FILE_ATTRIBUTES != dwattr) {
if (0 != (FILE_ATTRIBUTE_DIRECTORY & dwattr)) {
dwattr |= FILE_FLAG_BACKUP_SEMANTICS;
}
dwattr |= FILE_FLAG_OPEN_REPARSE_POINT;
for (i = 0; ((2 > i) && (0 == back)); i++) {
han = CreateFileA(
fn,
((0 == i) ? (0) : (GENERIC_READ)),
(FILE_SHARE_READ | FILE_SHARE_WRITE),
NULL,
OPEN_EXISTING,
dwattr,
NULL
);
if (INVALID_HANDLE_VALUE != han) {
if (GetFileInformationByHandle(han, &bhfi)) {
back = 1;
dptr->ser = bhfi.dwVolumeSerialNumber;
dptr->inh = bhfi.nFileIndexHigh;
dptr->inl = bhfi.nFileIndexLow;
} else {
if (1 == i) {
/* ERROR: Failed */
dk4error_set_ldetails(
erp, DK4_E_FILE_INFORMATION_FAILED,
(long)((unsigned long)GetLastError())
);
}
}
CloseHandle(han);
} else {
if (1 == i) {
/* ERROR: Failed */
dk4error_set_ldetails(
erp, DK4_E_CREATE_FILE_FAILED,
(long)((unsigned long)GetLastError())
);
}
}
}
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#else
dk4_stat_t stb;
int back = 0;
if ((NULL != dptr) && (NULL != fn)) {
if (0 != dk4stat_l_c8(&stb, fn, erp)) {
dptr->dev = stb.st_dev;
dptr->ino = stb.st_ino;
back = 1;
}
} else {
dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS);
}
return back;
#endif
}