NativeAPI Implementation
GetExtendedFileAttributesW()
and SetExtendedFileAttributesW()
functions for
Microsoft®
Windows™ NT
to get, set and remove
extended (file & directory) attributes.
Extended (directory & file) attributes(a legacy from OS/2) are name/value pairs, with names of up to 255 printable extended (upper-case) ASCII characters except
"
,
*
, +
,
,
, /
,
:
, ;
,
<
,
>
,
?
,
=
,
[
,
\
,
]
plus
|
, and values of up to 65535
bytes. They are stored with files as well as directories on
FAT-12,
FAT-16 and
NTFS file
systems (mutually exclusive with the latter’s
reparse points)
and not supported by the Win32
API!
Note: the Win32 functions
CopyFileEx()
and
CreateFile()
provide only indirect support for
extended attributes
.
The MSDN article Creating and Opening Files specifies:
An application creating a new file can supply an optional handle to a template file, from which CreateFile takes file attributes and extended attributes for creation of the new file.The MSDN article File Attribute Constants specifies:
File attributes are metadata values stored by the file system on disk and are used by the system and are available to developers via various file I/O APIs.OOPS: both constants have the same numerical value![…]
Constant/value Description … … FILE_ATTRIBUTE_EA
262144 (0x00040000)A file or directory with extended attributes. IMPORTANT: This constant is for internal use only.
… … FILE_ATTRIBUTE_RECALL_ON_OPEN
262144 (0x00040000)This attribute only appears in directory enumeration classes (FILE_DIRECTORY_INFORMATION, FILE_BOTH_DIR_INFORMATION, etc.). When this attribute is set, it means that the file or directory has no physical representation on the local system; the item is virtual. Opening the item will be more expensive than normal, e.g. it will cause at least some of it to be fetched from a remote store.
Finally see the MSDN articles Kernel Extended Attributes and File Permissions for WSL.
NativeAPI Implementation
GetExtendedFileAttributeW()
and
SetExtendedFileAttributeW()
functions, implemented
with Windows NT’s nativeAPI provided by
NTDLL.dll
.
Create the text file ext-attr.c
with the following
content in an arbitrary, preferable empty directory:
// Copyright © 2004-2025, Stefan Kanthak <stefan.kanthak@nexgo.de>
#ifndef _DLL
#pragma comment(compiler)
#pragma comment(lib, "ext-attr")
#pragma intrinsic(__movsb, strlen)
#define STRICT
#define UNICODE
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define FILE_SHARE_NONE 0UL
#define FILE_OPEN 1UL
#define FILE_OPENED 1UL
#define FILE_CREATE 2UL
#define FILE_CREATED 2UL
#define FILE_OPEN_IF 3UL
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020UL
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000UL
#define OBJ_CASE_INSENSITIVE 64UL
#define STATUS_SUCCESS 0L
#define STATUS_BUFFER_OVERFLOW 0x80000005L // ERROR_MORE_DATA
#define STATUS_NO_MORE_EAS 0x80000012L // ERROR_NO_MORE_ITEMS
#define STATUS_INVALID_EA_NAME 0x80000013L // ERROR_INVALID_EA_NAME
#define STATUS_EA_LIST_INCONSISTENT 0x80000014L // ERROR_EA_LIST_INCONSISTENT
#define STATUS_INVALID_EA_FLAG 0x80000015L // ERROR_EA_LIST_INCONSISTENT
#define STATUS_BUFFER_TOO_SMALL 0xC0000023L // ERROR_INSUFFICIENT_BUFFER
#define STATUS_EAS_NOT_SUPPORTED 0xC000004FL // ERROR_EAS_NOT_SUPPORTED
#define STATUS_EA_TOO_LARGE 0xC0000050L // ERROR_EA_LIST_INCONSISTENT
#define STATUS_NONEXISTENT_EA_ENTRY 0xC0000051L // ERROR_FILE_CORRUPT
#define STATUS_NO_EAS_ON_FILE 0xC0000052L // ERROR_FILE_CORRUPT
#define STATUS_EA_CORRUPT_ERROR 0xC0000053L // ERROR_FILE_CORRUPT
#define STATUS_INSUFFICIENT_RESOURCES 0xC000009AL // ERROR_NO_SYSTEM_RESOURCES
typedef LONG NTSTATUS;
typedef enum _FILE_INFORMATION_CLASS
{
FileEaInformation = 7,
FileFullEaInformation = 15
} FILE_INFORMATION_CLASS;
typedef struct _FILE_EA_INFORMATION
{
DWORD EaSize;
} FILE_EA_INFORMATION;
#pragma pack(push, 1)
typedef struct _FILE_GET_EA_INFORMATION
{
DWORD NextEntryOffset;
BYTE EaNameLength;
CHAR EaName[256];
} FILE_GET_EA_INFORMATION;
typedef struct _FILE_FULL_EA_INFORMATION
{
DWORD NextEntryOffset;
BYTE Flags;
BYTE EaNameLength;
WORD EaValueLength;
CHAR EaName[1];
// BYTE EaValue[1];
} FILE_FULL_EA_INFORMATION;
#pragma pack(pop)
typedef struct _UNICODE_STRING
{
WORD Length;
WORD MaximumLength;
LPWSTR Buffer;
} UNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES
{
DWORD Length;
HANDLE RootDirectory;
UNICODE_STRING *ObjectName;
DWORD Attributes;
LPVOID SecurityDescriptor;
LPVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK
{
union
{
LONG Status;
LPVOID Pointer;
};
DWORD_PTR Information;
} IO_STATUS_BLOCK;
typedef struct _RTLP_CURDIR_REF
{
LONG RefCount;
HANDLE Handle;
} RTLP_CURDIR_REF;
typedef struct _RTL_RELATIVE_NAME_U
{
UNICODE_STRING RelativeName;
HANDLE ContainingDirectory;
RTLP_CURDIR_REF *CurDirRef;
} RTL_RELATIVE_NAME_U;
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
BYTE Reserved1[16];
LPVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_LDR_DATA
{
BYTE Reserved1[8];
LPVOID Reserved2[3];
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA;
typedef VOID (NTAPI PS_POST_PROCESS_INIT_ROUTINE) (VOID);
typedef struct _PEB
{
BYTE Reserved1[2];
BOOLEAN BeingDebugged;
BYTE Reserved2[1];
LPVOID Reserved3[2];
PEB_LDR_DATA *Ldr;
RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
#if 0
LPVOID Reserved4[3];
#else
LPVOID SubSystemData;
HANDLE ProcessHeap;
RTL_CRITICAL_SECTION *FastPebLock;
#endif
LPVOID AtlThunkSListPtr;
LPVOID Reserved5;
DWORD Reserved6;
LPVOID Reserved7;
DWORD Reserved8;
DWORD AtlThunkSListPtr32;
LPVOID Reserved9[45];
BYTE Reserved10[96];
PS_POST_PROCESS_INIT_ROUTINE *PostProcessInitRoutine;
BYTE Reserved11[128];
LPVOID Reserved12[1];
DWORD SessionId;
} PEB;
typedef struct _TEB
{
LPVOID Reserved1[12];
PEB *ProcessEnvironmentBlock;
LPVOID Reserved2[399];
BYTE Reserved3[1952];
LPVOID TlsSlots[64];
LIST_ENTRY TlsLinks;
LPVOID Reserved5[26];
LPVOID ReservedForOle;
LPVOID Reserved6[4];
LPVOID *TlsExpansionSlots;
} TEB;
__declspec(dllimport)
LONG NTAPI NtClose(HANDLE Handle);
__declspec(dllimport)
LONG NTAPI NtCreateFile(HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
LARGE_INTEGER *AllocationSize,
DWORD FileAttributes,
DWORD ShareAccess,
DWORD CreateDisposition,
DWORD CreateOptions,
FILE_FULL_EA_INFORMATION *EaBuffer,
DWORD EaLength);
__declspec(dllimport)
LONG NTAPI NtOpenFile(HANDLE *FileHandle,
ACCESS_MASK DesiredAccess,
OBJECT_ATTRIBUTES *ObjectAttributes,
IO_STATUS_BLOCK *IoStatusBlock,
DWORD ShareAccess,
DWORD OpenOptions);
__declspec(dllimport)
LONG NTAPI NtQueryEaFile(HANDLE FileHandle,
IO_STATUS_BLOCK *IoStatusBlock,
FILE_FULL_EA_INFORMATION *EaBuffer,
DWORD EaBufferLength,
BOOLEAN ReturnSingleEntry,
FILE_GET_EA_INFORMATION *EaList,
DWORD EaListLength,
LPDWORD EaIndex,
BOOLEAN RestartScan);
__declspec(dllimport)
LONG NTAPI NtQueryInformationFile(HANDLE FileHandle,
IO_STATUS_BLOCK *IoStatusBlock,
VOID *FileInformation,
DWORD FileInformationLength,
FILE_INFORMATION_CLASS FileInformationClass);
__declspec(dllimport)
LONG NTAPI NtSetEaFile(HANDLE FileHandle,
IO_STATUS_BLOCK *IoStatusBlock,
VOID *Buffer,
DWORD Length);
__declspec(dllimport)
LONG NTAPI NtSetInformationFile(HANDLE FileHandle,
IO_STATUS_BLOCK *IoStatusBlock,
VOID *FileInformation,
DWORD FileInformationLength,
FILE_INFORMATION_CLASS FileInformationClass);
__declspec(dllimport)
LPVOID NTAPI RtlAllocateHeap(LPCVOID HeapHandle,
DWORD Flags,
SIZE_T Size);
__declspec(dllimport)
LONG NTAPI RtlDosPathNameToNtPathName_U_WithStatus(LPCWSTR DosName,
UNICODE_STRING *NtName,
LPCWSTR *PartName,
RTL_RELATIVE_NAME_U *RelativeName);
__declspec(dllimport)
BOOL NTAPI RtlFreeHeap(LPCVOID HeapHandle,
DWORD Flags,
LPCVOID HeapBase);
__declspec(dllimport)
VOID NTAPI RtlFreeUnicodeString(UNICODE_STRING *UnicodeString);
__declspec(dllimport)
VOID NTAPI RtlSetLastWin32ErrorAndNtStatusFromNtStatus(NTSTATUS Status);
BOOL WINAPI FreeExtendedFileAttributes(LPCVOID lpBlock)
{
LPCVOID lpHeap = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap;
LONG ntStatus = STATUS_INVALID_PARAMETER;
if (lpBlock != NULL)
return RtlFreeHeap(lpHeap, 0UL, lpBlock);
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(ntStatus);
return FALSE;
}
LPCVOID WINAPI GetExtendedFileAttributesW(LPCWSTR lpSource)
{
LPCVOID lpHeap = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap;
LONG ntStatus = STATUS_INVALID_PARAMETER;
DWORD dwSource;
HANDLE hSource;
IO_STATUS_BLOCK ioSource;
UNICODE_STRING usSource;
OBJECT_ATTRIBUTES oaSource = {sizeof(oaSource),
(HANDLE) NULL,
(UNICODE_STRING *) NULL,
OBJ_CASE_INSENSITIVE,
NULL,
NULL};
FILE_FULL_EA_INFORMATION *eaSource = NULL;
if (lpSource != NULL && *lpSource != L'\0')
{
ntStatus = RtlDosPathNameToNtPathName_U_WithStatus(lpSource,
&usSource,
(LPCWSTR *) NULL,
NULL);
if (ntStatus == STATUS_SUCCESS)
{
oaSource.ObjectName = &usSource;
ntStatus = NtOpenFile(&hSource,
FILE_READ_EA | SYNCHRONIZE,
&oaSource,
&ioSource,
FILE_SHARE_NONE,
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT);
RtlFreeUnicodeString(&usSource);
if (ntStatus == STATUS_SUCCESS)
{
ntStatus = NtQueryInformationFile(hSource,
&ioSource,
&dwSource,
sizeof(dwSource),
FileEaInformation);
if (ntStatus == STATUS_SUCCESS)
if (dwSource == 0UL)
ntStatus = STATUS_NO_EAS_ON_FILE;
else
{
#if 0 // CAVEAT: NtQueryInformationFile() returns for FileEaInformation
// a value (number of EAs - 1) * 4 lower than the buffer size!
eaSource = RtlAllocateHeap(lpHeap, 0UL, dwSource);
#else
eaSource = RtlAllocateHeap(lpHeap, 0UL, dwSource = 65536UL);
#endif
if (eaSource == NULL)
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
else
{
#if 0 // CAVEAT: NtQueryInformationFile() fails with STATUS_NOT_IMPLEMENTED for FileFullEaInformation!
ntStatus = NtQueryInformationFile(hSource,
&ioSource,
eaSource,
dwSource,
FileFullEaInformation);
#else
ntStatus = NtQueryEaFile(hSource,
&ioSource,
eaSource,
dwSource,
FALSE,
(FILE_GET_EA_INFORMATION *) NULL,
0UL,
(LPDWORD) NULL,
TRUE);
#endif
if (ntStatus != STATUS_SUCCESS)
{
RtlFreeHeap(lpHeap, 0UL, eaSource);
eaSource = NULL;
}
}
}
NtClose(hSource);
}
}
}
if (eaSource == NULL)
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(ntStatus);
return eaSource;
}
__declspec(safebuffers)
DWORD WINAPI GetExtendedFileAttributeW(LPCWSTR lpSource,
LPCSTR lpEaName,
LPVOID lpEaValue,
DWORD dwEaValue)
{
LPCVOID lpHeap = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap;
LONG ntStatus = STATUS_INVALID_PARAMETER;
DWORD dwEaName;
DWORD dwSource = 0UL;
HANDLE hSource;
IO_STATUS_BLOCK ioSource;
UNICODE_STRING usSource;
OBJECT_ATTRIBUTES oaSource = {sizeof(oaSource),
(HANDLE) NULL,
(UNICODE_STRING *) NULL,
OBJ_CASE_INSENSITIVE,
NULL,
NULL};
FILE_GET_EA_INFORMATION eaQuery;
FILE_FULL_EA_INFORMATION *eaSource;
if (lpSource != NULL && *lpSource != L'\0'
&& lpEaName != NULL && *lpEaName != '\0'
&& (dwEaName = strlen(lpEaName)) < 256UL
&& (dwEaValue == 0UL || dwEaValue != 0UL && lpEaValue != NULL))
{
ntStatus = RtlDosPathNameToNtPathName_U_WithStatus(lpSource,
&usSource,
(LPCWSTR *) NULL,
NULL);
if (ntStatus == STATUS_SUCCESS)
{
oaSource.ObjectName = &usSource;
ntStatus = NtOpenFile(&hSource,
FILE_READ_EA | SYNCHRONIZE,
&oaSource,
&ioSource,
FILE_SHARE_NONE,
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT);
RtlFreeUnicodeString(&usSource);
if (ntStatus == STATUS_SUCCESS)
{
eaSource = RtlAllocateHeap(lpHeap, 0UL, 65536UL);
if (eaSource == NULL)
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
else
{
eaQuery.NextEntryOffset = 0UL;
eaQuery.EaNameLength = (BYTE) dwEaName;
__movsb(eaQuery.EaName, lpEaName, dwEaName + 1UL);
ntStatus = NtQueryEaFile(hSource,
&ioSource,
eaSource,
65536UL,
TRUE,
&eaQuery,
sizeof(eaQuery),
(LPDWORD) NULL,
TRUE);
if (ntStatus == STATUS_SUCCESS)
{
dwSource = eaSource->EaValueLength;
if (dwSource > dwEaValue)
ntStatus = STATUS_BUFFER_TOO_SMALL;
else if (dwSource == 0UL)
ntStatus = STATUS_NONEXISTENT_EA_ENTRY;
else if (lpEaValue != NULL)
__movsb(lpEaValue,
eaSource->EaName + eaSource->EaNameLength + 1,
eaSource->EaValueLength);
}
RtlFreeHeap(lpHeap, 0UL, eaSource);
}
NtClose(hSource);
}
}
}
if (dwSource == 0UL)
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(ntStatus);
return dwSource;
}
BOOL WINAPI SetExtendedFileAttributeW(LPCWSTR lpTarget,
LPCSTR lpEaName,
LPCVOID lpEaValue,
DWORD dwEaValue)
{
LPCVOID lpHeap = NtCurrentTeb()->ProcessEnvironmentBlock->ProcessHeap;
LONG ntStatus = STATUS_INVALID_PARAMETER;
DWORD dwEaName;
DWORD dwTarget;
BOOL bTarget = FALSE;
HANDLE hTarget;
IO_STATUS_BLOCK ioTarget;
UNICODE_STRING usTarget;
OBJECT_ATTRIBUTES oaTarget = {sizeof(oaTarget),
(HANDLE) NULL,
(UNICODE_STRING *) NULL,
OBJ_CASE_INSENSITIVE,
NULL,
NULL};
FILE_FULL_EA_INFORMATION *eaTarget;
if (lpTarget != NULL && *lpTarget != L'\0'
&& lpEaName != NULL && *lpEaName != '\0'
&& (dwEaValue == 0UL || dwEaValue != 0UL && lpEaValue != NULL)
&& (dwEaName = strlen(lpEaName)) < 256UL
&& (dwTarget = sizeof(*eaTarget) + dwEaName + dwEaValue) < 65536UL)
{
eaTarget = RtlAllocateHeap(lpHeap, 0UL, dwTarget);
if (eaTarget == NULL)
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
else
{
eaTarget->NextEntryOffset = 0UL;
eaTarget->Flags = 0;
eaTarget->EaNameLength = (BYTE) dwEaName;
eaTarget->EaValueLength = (WORD) dwEaValue;
__movsb(eaTarget->EaName, lpEaName, dwEaName + 1UL);
__movsb(eaTarget->EaName + dwEaName + 1UL, lpEaValue, dwEaValue);
ntStatus = RtlDosPathNameToNtPathName_U_WithStatus(lpTarget,
&usTarget,
(LPCWSTR *) NULL,
NULL);
if (ntStatus == STATUS_SUCCESS)
{
oaTarget.ObjectName = &usTarget;
ntStatus = NtCreateFile(&hTarget,
FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | SYNCHRONIZE,
&oaTarget,
&ioTarget,
(LARGE_INTEGER *) NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_NONE,
FILE_OPEN_IF,
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
eaTarget,
dwTarget);
RtlFreeUnicodeString(&usTarget);
if (ntStatus == STATUS_SUCCESS)
{
if (ioTarget.Information == FILE_CREATED)
bTarget = TRUE;
else
{
#if 0 // CAVEAT: NtSetInformationFile() fails with STATUS_INVALID_INFO_CLASS for FileFullEaInformation!
ntStatus = NtSetInformationFile(hTarget,
&ioTarget,
eaTarget,
dwTarget,
FileFullEaInformation);
#else
ntStatus = NtSetEaFile(hTarget,
&ioTarget,
eaTarget,
dwTarget);
#endif
if (ntStatus == STATUS_SUCCESS)
bTarget = TRUE;
}
NtClose(hTarget);
}
}
RtlFreeHeap(lpHeap, 0UL, eaTarget);
}
}
if (!bTarget)
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(ntStatus);
return bTarget;
}
#else // _DLL
__declspec(dllexport)
long NtClose(void *_1)
{ return 0; }
__declspec(dllexport)
long NtCreateFile(void *_1, long _2, void *_3, void *_4, void *_5, long _6, long _7, long _8, long _9, void *_10, long _11)
{ return 0; }
__declspec(dllexport)
long NtOpenFile(void *_1, long _2, void *_3, void *_4, long _5, long _6)
{ return 0; }
__declspec(dllexport)
long NtQueryEaFile(void *_1, void *_2, void *_3, long _4, long _5, void *_6, long _7, void *_8, long _9)
{ return 0; }
__declspec(dllexport)
long NtQueryInformationFile(void *_1, void *_2, void *_3, long _4, long _5)
{ return 0; }
__declspec(dllexport)
long NtSetEaFile(void *_1, void *_2, void *_3, long _4)
{ return 0; }
__declspec(dllexport)
long NtSetInformationFile(void *_1, void *_2, void *_3, long _4, long _5)
{ return 0; }
__declspec(dllexport)
void *RtlAllocateHeap(void *_1, long _2, void *_3)
{ return 0; }
__declspec(dllexport)
long RtlDosPathNameToNtPathName_U_WithStatus(void *_1, void *_2, void *_3, void *_4)
{ return 0; }
__declspec(dllexport)
long RtlFreeHeap(void *_1, long _2, void *_3)
{ return 0; }
__declspec(dllexport)
void RtlFreeUnicodeString(void *_1)
{}
__declspec(dllexport)
void RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long _1)
{}
#endif // _DLL
NtCurrentTeb()
Calling Internal APIs
Miscellaneous Low-Level Client Support
NtClose()
NtCreateFile()
NtOpenFile()
NtQueryEaFile()
NtQueryEaFile()
NtQueryInformationFile()
NtQueryInformationFile()
NtSetEaFile()
NtSetEaFile()
NtSetInformationFile()
NtSetInformationFile()
RtlAllocateHeap()
RtlFreeHeap()
RtlFreeUnicodeString()
FILE_INFORMATION_CLASS
FILE_EA_INFORMATION
FILE_GET_EA_INFORMATION
FILE_FULL_EA_INFORMATION
IO_STATUS_BLOCK
OBJECT_ATTRIBUTES
PEB
RTL_USER_PROCESS_PARAMETERS
TEB
UNICODE_STRING
Compile the source file ext-attr.c
created in
step 1. a first time and build the
import library
ext-attr.lib
from the generated object file
ext-attr.obj
:
CL.EXE /c /Gz /MD /W4 /wd4100 /X /Zl ext-attr.c LINK.EXE /LIB /DEF /EXPORT:NtClose /EXPORT:NtCreateFile /EXPORT:NtOpenFile /EXPORT:NtQueryEaFile /EXPORT:NtQueryInformationFile /EXPORT:NtSetEaFile /EXPORT:NtSetInformationFile /EXPORT:RtlAllocateHeap /EXPORT:RtlDosPathNameToNtPathName_U_WithStatus /EXPORT:RtlFreeHeap /EXPORT:RtlFreeUnicodeString /EXPORT:RtlSetLastWin32ErrorAndNtStatusFromNtStatus /NAME:NTDLL /NODEFAULTLIB ext-attr.obj
Note: the command lines can be copied and pasted as block into a Command Processor window.
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. ext-attr.c Microsoft (R) Library Manager Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved. Creating library ext-attr.lib and object ext-attr.exp
Compile the source file ext-attr.c
created in
step 1. a second time and put the generated object file
ext-attr.obj
into the import (as well as object)
library ext-attr.lib
built in step 2.:
CL.EXE /c /Gy /Oxy /W4 /Zl ext-attr.c LINK.EXE /LIB /NODEFAULTLIB ext-attr.lib ext-attr.obj
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. ext-attr.c ext-attr.c(97) : warning C4201: nonstandard extension used : nameless struct/union Microsoft (R) Library Manager Version 10.00.40219.386 Copyright (C) Microsoft Corporation. All rights reserved.
Use the X.509 certificate to send S/MIME encrypted mail.
Note: email in weird format and without a proper sender name is likely to be discarded!
I dislike
HTML (and even
weirder formats too) in email, I prefer to receive plain text.
I also expect to see your full (real) name as sender, not your
nickname.
I abhor top posts and expect inline quotes in replies.
as iswithout any warranty, neither express nor implied.
cookiesin the web browser.
The web service is operated and provided by
Telekom Deutschland GmbH The web service provider stores a session cookie
in the web
browser and records every visit of this web site with the following
data in an access log on their server(s):