* autoload.cc (LoadDLLfuncNt): Re-invent.
(NtCreateTransaction): Define. (NtCommitTransaction): Define. (NtRollbackTransaction): Define. (RtlGetCurrentTransaction): Define. (RtlSetCurrentTransaction): Define. * ntdll.h (TRANSACTION_ALL_ACCESS): Define. (NtCreateTransaction): Declare. (NtCommitTransaction): Declare. (NtRollbackTransaction): Declare. (RtlGetCurrentTransaction): Declare. (RtlSetCurrentTransaction): Declare. * syscalls.cc (start_transaction): New static function to start TxF transaction. (stop_transaction): New static function to end TxF transaction. (rename): Call start_transaction and stop_transaction where appropriate on systems supporting transactions. * wincap.h (wincaps::has_transactions): New element. * wincap.cc: Implement above element throughout.
This commit is contained in:
parent
43334bd027
commit
4c153b24d9
|
@ -1,3 +1,25 @@
|
||||||
|
2008-05-15 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (LoadDLLfuncNt): Re-invent.
|
||||||
|
(NtCreateTransaction): Define.
|
||||||
|
(NtCommitTransaction): Define.
|
||||||
|
(NtRollbackTransaction): Define.
|
||||||
|
(RtlGetCurrentTransaction): Define.
|
||||||
|
(RtlSetCurrentTransaction): Define.
|
||||||
|
* ntdll.h (TRANSACTION_ALL_ACCESS): Define.
|
||||||
|
(NtCreateTransaction): Declare.
|
||||||
|
(NtCommitTransaction): Declare.
|
||||||
|
(NtRollbackTransaction): Declare.
|
||||||
|
(RtlGetCurrentTransaction): Declare.
|
||||||
|
(RtlSetCurrentTransaction): Declare.
|
||||||
|
* syscalls.cc (start_transaction): New static function to start TxF
|
||||||
|
transaction.
|
||||||
|
(stop_transaction): New static function to end TxF transaction.
|
||||||
|
(rename): Call start_transaction and stop_transaction where appropriate
|
||||||
|
on systems supporting transactions.
|
||||||
|
* wincap.h (wincaps::has_transactions): New element.
|
||||||
|
* wincap.cc: Implement above element throughout.
|
||||||
|
|
||||||
2008-05-14 Corinna Vinschen <corinna@vinschen.de>
|
2008-05-14 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Drop
|
* fhandler_disk_file.cc (fhandler_disk_file::readdir_helper): Drop
|
||||||
|
|
|
@ -311,6 +311,15 @@ LoadDLLfunc (NetLocalGroupGetMembers, 32, netapi32)
|
||||||
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
|
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
|
||||||
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
|
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
|
||||||
|
|
||||||
|
/* 0xc000007a == STATUS_PROCEDURE_NOT_FOUND */
|
||||||
|
#define LoadDLLfuncNt(name, n, dllname) \
|
||||||
|
LoadDLLfuncEx2(name, n, dllname, 1, 0xc000007a)
|
||||||
|
LoadDLLfuncNt (NtCommitTransaction, 8, ntdll)
|
||||||
|
LoadDLLfuncNt (NtCreateTransaction, 40, ntdll)
|
||||||
|
LoadDLLfuncNt (NtRollbackTransaction, 8, ntdll)
|
||||||
|
LoadDLLfuncNt (RtlGetCurrentTransaction, 0, ntdll)
|
||||||
|
LoadDLLfuncNt (RtlSetCurrentTransaction, 4, ntdll)
|
||||||
|
|
||||||
LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1)
|
LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1)
|
||||||
LoadDLLfuncEx (GetModuleFileNameExW, 16, psapi, 1)
|
LoadDLLfuncEx (GetModuleFileNameExW, 16, psapi, 1)
|
||||||
LoadDLLfuncEx (GetModuleInformation, 16, psapi, 1)
|
LoadDLLfuncEx (GetModuleInformation, 16, psapi, 1)
|
||||||
|
|
|
@ -77,6 +77,9 @@
|
||||||
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
|
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
|
||||||
#define FILE_DEVICE_SECURE_OPEN 0x00000100
|
#define FILE_DEVICE_SECURE_OPEN 0x00000100
|
||||||
|
|
||||||
|
/* Transaction access rights. */
|
||||||
|
#define TRANSACTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x3F)
|
||||||
|
|
||||||
typedef enum _FILE_INFORMATION_CLASS
|
typedef enum _FILE_INFORMATION_CLASS
|
||||||
{
|
{
|
||||||
FileDirectoryInformation = 1,
|
FileDirectoryInformation = 1,
|
||||||
|
@ -855,6 +858,7 @@ extern "C"
|
||||||
NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
|
NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
|
||||||
ULONG, PTOKEN_PRIVILEGES, PULONG);
|
ULONG, PTOKEN_PRIVILEGES, PULONG);
|
||||||
NTSTATUS NTAPI NtClose (HANDLE);
|
NTSTATUS NTAPI NtClose (HANDLE);
|
||||||
|
NTSTATUS NTAPI NtCommitTransaction (HANDLE, BOOLEAN);
|
||||||
NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
|
NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
|
||||||
POBJECT_ATTRIBUTES);
|
POBJECT_ATTRIBUTES);
|
||||||
NTSTATUS NTAPI NtCreateEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
NTSTATUS NTAPI NtCreateEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||||
|
@ -876,6 +880,9 @@ extern "C"
|
||||||
PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
|
PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
|
||||||
PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL,
|
PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL,
|
||||||
PTOKEN_SOURCE);
|
PTOKEN_SOURCE);
|
||||||
|
NTSTATUS NTAPI NtCreateTransaction (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
|
||||||
|
LPGUID, HANDLE, ULONG, ULONG, ULONG,
|
||||||
|
PLARGE_INTEGER, PUNICODE_STRING);
|
||||||
NTSTATUS NTAPI NtFsControlFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
|
NTSTATUS NTAPI NtFsControlFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
|
||||||
PIO_STATUS_BLOCK, ULONG, PVOID, ULONG,
|
PIO_STATUS_BLOCK, ULONG, PVOID, ULONG,
|
||||||
PVOID, ULONG);
|
PVOID, ULONG);
|
||||||
|
@ -929,6 +936,7 @@ extern "C"
|
||||||
NTSTATUS NTAPI NtReadFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
|
NTSTATUS NTAPI NtReadFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
|
||||||
PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
|
PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
|
||||||
PULONG);
|
PULONG);
|
||||||
|
NTSTATUS NTAPI NtRollbackTransaction (HANDLE, BOOLEAN);
|
||||||
NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
|
NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
|
||||||
NTSTATUS NTAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
|
NTSTATUS NTAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
|
||||||
FILE_INFORMATION_CLASS);
|
FILE_INFORMATION_CLASS);
|
||||||
|
@ -957,6 +965,7 @@ extern "C"
|
||||||
VOID NTAPI RtlFreeAnsiString (PANSI_STRING);
|
VOID NTAPI RtlFreeAnsiString (PANSI_STRING);
|
||||||
VOID NTAPI RtlFreeOemString (POEM_STRING);
|
VOID NTAPI RtlFreeOemString (POEM_STRING);
|
||||||
VOID NTAPI RtlFreeUnicodeString (PUNICODE_STRING);
|
VOID NTAPI RtlFreeUnicodeString (PUNICODE_STRING);
|
||||||
|
HANDLE NTAPI RtlGetCurrentTransaction ();
|
||||||
VOID NTAPI RtlInitEmptyUnicodeString (PUNICODE_STRING, PCWSTR, USHORT);
|
VOID NTAPI RtlInitEmptyUnicodeString (PUNICODE_STRING, PCWSTR, USHORT);
|
||||||
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
|
VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
|
||||||
NTSTATUS NTAPI RtlIntegerToUnicodeString (ULONG, ULONG, PUNICODE_STRING);
|
NTSTATUS NTAPI RtlIntegerToUnicodeString (ULONG, ULONG, PUNICODE_STRING);
|
||||||
|
@ -968,6 +977,7 @@ extern "C"
|
||||||
BOOLEAN);
|
BOOLEAN);
|
||||||
VOID NTAPI RtlReleasePebLock ();
|
VOID NTAPI RtlReleasePebLock ();
|
||||||
VOID NTAPI RtlSecondsSince1970ToTime (ULONG, PLARGE_INTEGER);
|
VOID NTAPI RtlSecondsSince1970ToTime (ULONG, PLARGE_INTEGER);
|
||||||
|
BOOLEAN NTAPI RtlSetCurrentTransaction (HANDLE);
|
||||||
NTSTATUS NTAPI RtlUnicodeStringToAnsiString (PANSI_STRING, PUNICODE_STRING,
|
NTSTATUS NTAPI RtlUnicodeStringToAnsiString (PANSI_STRING, PUNICODE_STRING,
|
||||||
BOOLEAN);
|
BOOLEAN);
|
||||||
NTSTATUS NTAPI RtlUnicodeStringToOemString (PANSI_STRING, PUNICODE_STRING,
|
NTSTATUS NTAPI RtlUnicodeStringToOemString (PANSI_STRING, PUNICODE_STRING,
|
||||||
|
|
|
@ -1461,6 +1461,36 @@ rename_append_suffix (path_conv &pc, const char *path, size_t len,
|
||||||
pc.check (buf, PC_SYM_NOFOLLOW);
|
pc.check (buf, PC_SYM_NOFOLLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
start_transaction (HANDLE &old_trans, HANDLE &trans)
|
||||||
|
{
|
||||||
|
NTSTATUS status = NtCreateTransaction (&trans,
|
||||||
|
SYNCHRONIZE | TRANSACTION_ALL_ACCESS,
|
||||||
|
NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
old_trans = RtlGetCurrentTransaction ();
|
||||||
|
RtlSetCurrentTransaction (trans);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf ("NtCreateTransaction failed, %p", status);
|
||||||
|
old_trans = trans = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE trans)
|
||||||
|
{
|
||||||
|
RtlSetCurrentTransaction (old_trans);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
status = NtCommitTransaction (trans, TRUE);
|
||||||
|
else
|
||||||
|
status = NtRollbackTransaction (trans, TRUE);
|
||||||
|
NtClose (trans);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
rename (const char *oldpath, const char *newpath)
|
rename (const char *oldpath, const char *newpath)
|
||||||
{
|
{
|
||||||
|
@ -1473,6 +1503,7 @@ rename (const char *oldpath, const char *newpath)
|
||||||
bool equal_path;
|
bool equal_path;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
HANDLE fh = NULL, nfh;
|
HANDLE fh = NULL, nfh;
|
||||||
|
HANDLE old_trans = NULL, trans = NULL;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
|
@ -1681,6 +1712,13 @@ rename (const char *oldpath, const char *newpath)
|
||||||
}
|
}
|
||||||
dstpc = (removepc == &newpc) ? &new2pc : &newpc;
|
dstpc = (removepc == &newpc) ? &new2pc : &newpc;
|
||||||
|
|
||||||
|
/* Opening the file must be part of the transaction. It's not sufficient
|
||||||
|
to call only NtSetInformationFile under the transaction. Therefore we
|
||||||
|
have to start the transaction here, if necessary. */
|
||||||
|
if (wincap.has_transactions ()
|
||||||
|
&& (dstpc->isdir () || dstpc->has_attribute (FILE_ATTRIBUTE_READONLY)))
|
||||||
|
start_transaction (old_trans, trans);
|
||||||
|
|
||||||
/* DELETE is required to rename a file. */
|
/* DELETE is required to rename a file. */
|
||||||
status = NtOpenFile (&fh, DELETE, oldpc.get_object_attr (attr, sec_none_nih),
|
status = NtOpenFile (&fh, DELETE, oldpc.get_object_attr (attr, sec_none_nih),
|
||||||
&io, FILE_SHARE_VALID_FLAGS,
|
&io, FILE_SHARE_VALID_FLAGS,
|
||||||
|
@ -1789,9 +1827,36 @@ rename (const char *oldpath, const char *newpath)
|
||||||
existing file, if the permissions of the existing file aren't right.
|
existing file, if the permissions of the existing file aren't right.
|
||||||
Like directories, we have to handle this separately by removing the
|
Like directories, we have to handle this separately by removing the
|
||||||
destination before renaming. */
|
destination before renaming. */
|
||||||
if (status == STATUS_ACCESS_DENIED && dstpc->exists () && !dstpc->isdir ()
|
if (status == STATUS_ACCESS_DENIED && dstpc->exists () && !dstpc->isdir ())
|
||||||
&& NT_SUCCESS (status = unlink_nt (*dstpc)))
|
{
|
||||||
status = NtSetInformationFile (fh, &io, pfri, size, FileRenameInformation);
|
if (wincap.has_transactions () && !trans)
|
||||||
|
{
|
||||||
|
start_transaction (old_trans, trans);
|
||||||
|
/* As mentioned earlier, opening the file must be part of the
|
||||||
|
transaction. Therefore we have to reopen the file here if the
|
||||||
|
transaction hasn't been started already. Unfortunately we can't
|
||||||
|
use the NT "reopen file from existing handle" feature. In that
|
||||||
|
case NtOpenFile returns STATUS_TRANSACTIONAL_CONFLICT. We *have*
|
||||||
|
to close the handle to the file first, *then* we can re-open it.
|
||||||
|
Fortunately nothing has happened yet, so the atomicity of the
|
||||||
|
rename functionality is not spoiled. */
|
||||||
|
NtClose (fh);
|
||||||
|
status = NtOpenFile (&fh, DELETE,
|
||||||
|
oldpc.get_object_attr (attr, sec_none_nih),
|
||||||
|
&io, FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
|
| (oldpc.is_rep_symlink ()
|
||||||
|
? FILE_OPEN_REPARSE_POINT : 0));
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NT_SUCCESS (status = unlink_nt (*dstpc)))
|
||||||
|
status = NtSetInformationFile (fh, &io, pfri, size,
|
||||||
|
FileRenameInformation);
|
||||||
|
}
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
if (removepc)
|
if (removepc)
|
||||||
|
@ -1804,6 +1869,8 @@ rename (const char *oldpath, const char *newpath)
|
||||||
out:
|
out:
|
||||||
if (fh)
|
if (fh)
|
||||||
NtClose (fh);
|
NtClose (fh);
|
||||||
|
if (wincap.has_transactions () && trans)
|
||||||
|
stop_transaction (status, old_trans, trans);
|
||||||
syscall_printf ("%d = rename (%s, %s)", res, oldpath, newpath);
|
syscall_printf ("%d = rename (%s, %s)", res, oldpath, newpath);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ static NO_COPY wincaps wincap_unknown = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4 = {
|
static NO_COPY wincaps wincap_nt4 = {
|
||||||
|
@ -72,6 +73,7 @@ static NO_COPY wincaps wincap_nt4 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4sp4 = {
|
static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
|
@ -102,6 +104,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2000 = {
|
static NO_COPY wincaps wincap_2000 = {
|
||||||
|
@ -132,6 +135,7 @@ static NO_COPY wincaps wincap_2000 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2000sp4 = {
|
static NO_COPY wincaps wincap_2000sp4 = {
|
||||||
|
@ -162,6 +166,7 @@ static NO_COPY wincaps wincap_2000sp4 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_xp = {
|
static NO_COPY wincaps wincap_xp = {
|
||||||
|
@ -192,6 +197,7 @@ static NO_COPY wincaps wincap_xp = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_xpsp1 = {
|
static NO_COPY wincaps wincap_xpsp1 = {
|
||||||
|
@ -222,6 +228,7 @@ static NO_COPY wincaps wincap_xpsp1 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_xpsp2 = {
|
static NO_COPY wincaps wincap_xpsp2 = {
|
||||||
|
@ -252,6 +259,7 @@ static NO_COPY wincaps wincap_xpsp2 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2003 = {
|
static NO_COPY wincaps wincap_2003 = {
|
||||||
|
@ -282,6 +290,7 @@ static NO_COPY wincaps wincap_2003 = {
|
||||||
has_gaa_on_link_prefix:false,
|
has_gaa_on_link_prefix:false,
|
||||||
supports_all_posix_ai_flags:false,
|
supports_all_posix_ai_flags:false,
|
||||||
has_restricted_stack_args:true,
|
has_restricted_stack_args:true,
|
||||||
|
has_transactions:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_vista = {
|
static NO_COPY wincaps wincap_vista = {
|
||||||
|
@ -312,6 +321,7 @@ static NO_COPY wincaps wincap_vista = {
|
||||||
has_gaa_on_link_prefix:true,
|
has_gaa_on_link_prefix:true,
|
||||||
supports_all_posix_ai_flags:true,
|
supports_all_posix_ai_flags:true,
|
||||||
has_restricted_stack_args:false,
|
has_restricted_stack_args:false,
|
||||||
|
has_transactions:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
|
|
@ -40,6 +40,7 @@ struct wincaps
|
||||||
unsigned has_gaa_on_link_prefix : 1;
|
unsigned has_gaa_on_link_prefix : 1;
|
||||||
unsigned supports_all_posix_ai_flags : 1;
|
unsigned supports_all_posix_ai_flags : 1;
|
||||||
unsigned has_restricted_stack_args : 1;
|
unsigned has_restricted_stack_args : 1;
|
||||||
|
unsigned has_transactions : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
|
@ -86,6 +87,7 @@ public:
|
||||||
bool IMPLEMENT (has_gaa_on_link_prefix)
|
bool IMPLEMENT (has_gaa_on_link_prefix)
|
||||||
bool IMPLEMENT (supports_all_posix_ai_flags)
|
bool IMPLEMENT (supports_all_posix_ai_flags)
|
||||||
bool IMPLEMENT (has_restricted_stack_args)
|
bool IMPLEMENT (has_restricted_stack_args)
|
||||||
|
bool IMPLEMENT (has_transactions)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue