+2022-11-02 Keith Marshall <keith@users.osdn.me>
+
+ Clean up interlocked memory access API declarations.
+
+ * include/ddk/ntddk.h [_DDK_NTDDK_H]: Always defined, implying...
+ [__USE_NTOSKRNL__]: ...this, never defined elsewhere, and always true
+ when defined here; hence, macro is redundant; delete its definition,
+ together with its enclosing (redundant) repeat definition guard.
+
+ * include/winbase.h include/ddk/winddk.h
+ [__USE_NTOSKRNL__, __INTERLOCKED_DECLARED]: Delete references.
+ (InterlockedDecrement, InterlockedIncrement, InterlockedExchange)
+ (InterlockedCompareExchange, InterlockedCompareExchangePointer)
+ (InterlockedExchangePointer, InterlockedExchangeAdd): Factor out;
+ relocate declarations, and implementations as appropriate, to...
+ * include/winnt.h: ...here, per Microsoft's current documentation.
+ (__kernel_api): New local macro; define it conditionally...
+ [_DDK_NTDDK_H defined]: ...to match DDKFASTAPI usage, else...
+ [_DDK_NTDDK_H ! defined]: ...to match WINAPI usage.
+
+ * include/winbase.h (InterlockedPushEntrySList)
+ (InterlockedPopEntrySlist): Declare them, only if...
+ [_DDK_WINDDK_H ! defined]: ...not previously declared...
+ * include/ddk/winddk.h: ...thence.
+
+ * include/winnt.h (_WIN32_INTRINSIC): New macro; define, and...
+ (InterlockedCompareExchangePointer, InterlockedExchangePointer):
+ ...use it.
+
+ * include/ddk/winddk.h (InterlockedPushEntrySList)
+ (InterlockedPopEntrySlist): Declare them, only if...
+ [_WINBASE_H ! defined]: ...not previously declared...
+ * include/winbase.h: ...thence.
+
+ * include/ddk/winddk.h (FILE_LIST_DIRECTORY, FILE_READ_DATA)
+ (FILE_ADD_FILE, FILE_WRITE_DATA, FILE_ADD_SUBDIRECTORY)
+ (FILE_APPEND_DATA, FILE_CREATE_PIPE_INSTANCE, FILE_READ_EA)
+ (FILE_WRITE_EA, FILE_EXECUTE, FILE_TRAVERSE, FILE_DELETE_CHILD)
+ (FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ)
+ (FILE_SHARE_WRITE, FILE_SHARE_DELETE, FILE_SHARE_VALID_FLAGS)
+ (FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_HIDDEN)
+ (FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_DIRECTORY)
+ (FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_DEVICE, FILE_ATTRIBUTE_NORMAL)
+ (FILE_ATTRIBUTE_TEMPORARY, FILE_ATTRIBUTE_SPARSE_FILE)
+ (FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_COMPRESSED)
+ (FILE_ATTRIBUTE_OFFLINE, FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)
+ (FILE_ATTRIBUTE_ENCRYPTED, FILE_ATTRIBUTE_VIRTUAL)
+ (FILE_ATTRIBUTE_VALID_FLAGS, FILE_ATTRIBUTE_VALID_SET_FLAGS)
+ (FILE_COPY_STRUCTURED_STORAGE, FILE_STRUCTURED_STORAGE)
+ (FILE_VALID_OPTION_FLAGS, FILE_VALID_PIPE_OPTION_FLAGS)
+ (FILE_VALID_MAILSLOT_OPTION_FLAGS, FILE_VALID_SET_FLAGS)
+ (FILE_SUPERSEDE, FILE_OPEN, FILE_CREATE, FILE_OPEN_IF, FILE_OVERWRITE)
+ (FILE_OVERWRITE_IF, FILE_MAXIMUM_DISPOSITION, FILE_DIRECTORY_FILE)
+ (FILE_WRITE_THROUGH, FILE_SEQUENTIAL_ONLY)
+ (FILE_NO_INTERMEDIATE_BUFFERING, FILE_SYNCHRONOUS_IO_ALERT)
+ (FILE_SYNCHRONOUS_IO_NONALERT, FILE_NON_DIRECTORY_FILE)
+ (FILE_CREATE_TREE_CONNECTION, FILE_COMPLETE_IF_OPLOCKED)
+ (FILE_NO_EA_KNOWLEDGE, FILE_OPEN_FOR_RECOVERY, FILE_RANDOM_ACCESS)
+ (FILE_DELETE_ON_CLOSE, FILE_OPEN_BY_FILE_ID)
+ (FILE_OPEN_FOR_BACKUP_INTENT, FILE_NO_COMPRESSION)
+ (FILE_RESERVE_OPFILTER, FILE_OPEN_REPARSE_POINT, FILE_OPEN_NO_RECALL)
+ (FILE_OPEN_FOR_FREE_SPACE_QUERY, FILE_ALL_ACCESS)
+ (FILE_GENERIC_EXECUTE, FILE_GENERIC_READ, FILE_GENERIC_WRITE)
+ (DUPLICATE_CLOSE_SOURCE, DUPLICATE_SAME_ACCESS)
+ (DUPLICATE_SAME_ATTRIBUTES): Delete redundant definitions; all are...
+ * include/winnt.h: ...already defined thence.
+
2022-10-15 Keith Marshall <keith@users.osdn.me>
Do not define public symbols in <wspiapi.h>
* DBG - Debugging enabled/disabled (0/1)
* POOL_TAGGING - Enable pool tagging
* _X86_ - X86 environment
- * __USE_NTOSKRNL__ - Use ntoskrnl.exe instead of kernel32.dll
*
* $Id$
*
*
*/
#ifndef _DDK_NTDDK_H
-#define _DDK_NTDDK_H
#pragma GCC system_header
-
-#ifndef __USE_NTOSKRNL__
-#define __USE_NTOSKRNL__ 1
-#endif
+#define _DDK_NTDDK_H
#include <stdarg.h>
#include <windef.h>
#define FILE_EXISTS 0x00000004
#define FILE_DOES_NOT_EXIST 0x00000005
-#if 1
-/* FIXME: also in winnt.h; hence, already defined?
- */
-#define FILE_LIST_DIRECTORY 0x00000001
-#define FILE_READ_DATA 0x00000001
-#define FILE_ADD_FILE 0x00000002
-#define FILE_WRITE_DATA 0x00000002
-#define FILE_ADD_SUBDIRECTORY 0x00000004
-#define FILE_APPEND_DATA 0x00000004
-#define FILE_CREATE_PIPE_INSTANCE 0x00000004
-#define FILE_READ_EA 0x00000008
-#define FILE_WRITE_EA 0x00000010
-#define FILE_EXECUTE 0x00000020
-#define FILE_TRAVERSE 0x00000020
-#define FILE_DELETE_CHILD 0x00000040
-#define FILE_READ_ATTRIBUTES 0x00000080
-#define FILE_WRITE_ATTRIBUTES 0x00000100
-
-#define FILE_SHARE_READ 0x00000001
-#define FILE_SHARE_WRITE 0x00000002
-#define FILE_SHARE_DELETE 0x00000004
-#define FILE_SHARE_VALID_FLAGS 0x00000007
-
-#define FILE_ATTRIBUTE_READONLY 0x00000001
-#define FILE_ATTRIBUTE_HIDDEN 0x00000002
-#define FILE_ATTRIBUTE_SYSTEM 0x00000004
-#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
-#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
-#define FILE_ATTRIBUTE_DEVICE 0x00000040
-#define FILE_ATTRIBUTE_NORMAL 0x00000080
-#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
-#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
-#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
-#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
-#define FILE_ATTRIBUTE_OFFLINE 0x00001000
-#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
-#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
-#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
-
-#define FILE_ATTRIBUTE_VALID_FLAGS 0x00017fb7
-#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7
-
-#define FILE_COPY_STRUCTURED_STORAGE 0x00000041
-#define FILE_STRUCTURED_STORAGE 0x00000441
-
-#define FILE_VALID_OPTION_FLAGS 0x00ffffff
-#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
-#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
-#define FILE_VALID_SET_FLAGS 0x00000036
-
-#define FILE_SUPERSEDE 0x00000000
-#define FILE_OPEN 0x00000001
-#define FILE_CREATE 0x00000002
-#define FILE_OPEN_IF 0x00000003
-#define FILE_OVERWRITE 0x00000004
-#define FILE_OVERWRITE_IF 0x00000005
-#define FILE_MAXIMUM_DISPOSITION 0x00000005
-
-#define FILE_DIRECTORY_FILE 0x00000001
-#define FILE_WRITE_THROUGH 0x00000002
-#define FILE_SEQUENTIAL_ONLY 0x00000004
-#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
-#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
-#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
-#define FILE_NON_DIRECTORY_FILE 0x00000040
-#define FILE_CREATE_TREE_CONNECTION 0x00000080
-#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
-#define FILE_NO_EA_KNOWLEDGE 0x00000200
-#define FILE_OPEN_FOR_RECOVERY 0x00000400
-#define FILE_RANDOM_ACCESS 0x00000800
-#define FILE_DELETE_ON_CLOSE 0x00001000
-#define FILE_OPEN_BY_FILE_ID 0x00002000
-#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
-#define FILE_NO_COMPRESSION 0x00008000
-#define FILE_RESERVE_OPFILTER 0x00100000
-#define FILE_OPEN_REPARSE_POINT 0x00200000
-#define FILE_OPEN_NO_RECALL 0x00400000
-#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
-
-#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)
-
-#define FILE_GENERIC_EXECUTE \
- (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)
-
-#define FILE_GENERIC_READ \
- (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES \
- | FILE_READ_EA | SYNCHRONIZE)
-
-#define FILE_GENERIC_WRITE \
- (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES \
- | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)
-
-#endif /* winnt.h */
-
#define DIRECTORY_QUERY (0x0001)
#define DIRECTORY_TRAVERSE (0x0002)
#define DIRECTORY_CREATE_OBJECT (0x0004)
#define SYMBOLIC_LINK_QUERY 0x0001
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)
-#if 1
-/* FIXME: also in winnt.h; hence already defined?
- */
-#define DUPLICATE_CLOSE_SOURCE 0x00000001
-#define DUPLICATE_SAME_ACCESS 0x00000002
-#define DUPLICATE_SAME_ATTRIBUTES 0x00000004
-
-#endif /* winnt.h */
-
typedef
struct _OBJECT_NAME_INFORMATION
{ UNICODE_STRING Name;
((ULONG)KeGetCurrentKPCR()->Number)
-#if __USE_NTOSKRNL__
-/* CAREFUL: These are exported from ntoskrnl.exe as __fastcall functions,
- but are also exported from kernel32.dll and declared in winbase.h as
- __stdcall */
-#if !defined(__INTERLOCKED_DECLARED)
-#define __INTERLOCKED_DECLARED
-
-NTOSAPI LONG DDKFASTAPI
-InterlockedIncrement( /*IN*/ LONG VOLATILE *Addend );
-
-NTOSAPI LONG DDKFASTAPI
-InterlockedDecrement( /*IN*/ LONG VOLATILE *Addend );
-
-NTOSAPI LONG DDKFASTAPI
-InterlockedCompareExchange(
- /*IN OUT*/ PLONG VOLATILE Destination,
- /*IN*/ LONG Exchange,
- /*IN*/ LONG Comparand
-);
-
-NTOSAPI LONG DDKFASTAPI
-InterlockedExchange(
- /*IN OUT*/ PLONG VOLATILE Target,
- /*IN*/ LONG Value
-);
-
-NTOSAPI LONG DDKFASTAPI
-InterlockedExchangeAdd(
- /*IN OUT*/ PLONG VOLATILE Addend,
- /*IN*/ LONG Value
-);
-
-/* PVOID
- * InterlockedExchangePointer(
- * IN OUT PVOID VOLATILE *Target,
- * IN PVOID Value)
+/* Formerly declared here, on the assumption that we are building
+ * a Windows device driver, and thus exported by ntoskrnl.exe, with
+ * __fastcall calling convention, (as opposed to exports of the same
+ * functions from kernel32.dll, whence the __stdcall convention is
+ * applicable), the following:
+ *
+ * long InterlockedDecrement (long volatile *);
+ * long InterlockedIncrement (long volatile *);
+ *
+ * long InterlockedExchange (long volatile *, long);
+ * long InterlockedCompareExchange (long volatile *, long, long);
+ * long InterlockedExchangeAdd (long volatile *, long);
+ *
+ * together with intrinsic implementations of:
+ *
+ * void *InterlockedCompareExchangePointer (void *volatile *, void *, void *);
+ * void *InterlockedExchangePointer (void *volatile *, void *);
+ *
+ * are now declared in <winnt.h>, which is guaranteed to have been
+ * included already, with logic to determine the appropriate calling
+ * convention; thus, we may simply adopt the appropriately qualified
+ * <winnt.h> declarations, without repetition here.
+ *
+ * Similarly, (but without the guarantee of prior inclusion),
+ * introduced by WinXP...
*/
-#define InterlockedExchangePointer(Target, Value) \
- ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value))
-
-/* PVOID InterlockedCompareExchangePointer(
- * IN OUT PVOID *Destination,
- * IN PVOID Exchange,
- * IN PVOID Comparand
- * )
+#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP) && ! defined _WINBASE_H
+/* ...the following MAY have been declared already, if <winbase.h>
+ * has been included before we get to here; if it has, we simply adopt
+ * its declarations, but if it has not, we provide declarations here,
+ * (assuming use of the __fastcall exports from ntoskrnl.exe).
*/
-#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \
- ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand))
-
-#if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
PSLIST_ENTRY DDKFASTAPI
InterlockedPopEntrySList( /*IN*/ PSLIST_HEADER ListHead );
/*IN*/ PSLIST_HEADER ListHead,
/*IN*/ PSLIST_ENTRY ListEntry
);
-#endif /* _WIN32_WINNT >= _WIN32_WINNT_WINXP */
-
-#endif /* !__INTERLOCKED_DECLARED */
-#endif /* __USE_NTOSKRNL__ */
+#endif /* (_WIN32_WINNT >= _WIN32_WINNT_WINXP) && !_WINBASE_H */
NTOSAPI VOID DDKFASTAPI
KefAcquireSpinLockAtDpcLevel( /*IN*/ PKSPIN_LOCK SpinLock );
#define KeGetDcacheFillSize() 1L
-#endif /* _X86_ */
+#endif /* _X86_ */
/* Utility functions
*/
#define RTL_SOFT_VERIFY(exp) RTL_SOFT_ASSERT(exp)
#define RTL_SOFT_VERIFYMSG(msg, exp) RTL_SOFT_ASSERTMSG(msg, exp)
-#else /* !DBG */
+#else /* !DBG */
#define ASSERT(exp) ((VOID) 0)
#define ASSERTMSG(msg, exp) ((VOID) 0)
#define RTL_SOFT_VERIFY(exp) ((exp) ? TRUE : FALSE)
#define RTL_SOFT_VERIFYMSG(msg, exp) ((exp) ? TRUE : FALSE)
-#endif /* DBG */
+#endif /* DBG */
/* Driver support routines
/*IN*/ PKSPIN_LOCK Lock
);
-#if (__USE_NTOSKRNL__) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+#if _WIN32_WINNT >= _WIN32_WINNT_WINXP
#define ExInterlockedPopEntrySList(_ListHead, _Lock) \
InterlockedPopEntrySList(_ListHead)
#define ExInterlockedPushEntrySList(_ListHead, _ListEntry, _Lock) \
InterlockedPushEntrySList(_ListHead, _ListEntry)
-#endif /* __USE_NTOSKRNL__ */
+#endif /* _WIN32_WINNT >= _WIN32_WINNT_WINXP */
#define ExQueryDepthSList(ListHead) QueryDepthSList(ListHead)
}
}
-#if (__USE_NTOSKRNL__) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
+#if _WIN32_WINNT >= _WIN32_WINNT_WINXP
static __inline__ PVOID
ExAllocateFromPagedLookasideList(
}
}
-#else /* (__USE_NTOSKRNL__) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP) */
+#else /* _WIN32_WINNT >= _WIN32_WINNT_WINXP */
NTOSAPI PVOID DDKAPI
ExAllocateFromPagedLookasideList( /*IN*/ PPAGED_LOOKASIDE_LIST Lookaside );
/*IN*/ PVOID Entry
);
-#endif /* (__USE_NTOSKRNL__) && (_WIN32_WINNT >= _WIN32_WINNT_WINXP) */
+#endif /* _WIN32_WINNT >= _WIN32_WINNT_WINXP */
NTOSAPI PVOID DDKAPI
ExAllocatePoolWithQuotaTag(
#define ExAllocatePoolWithQuota(p,n) ExAllocatePoolWithQuotaTag(p,n,' kdD')
#define ExAllocatePool(p,n) ExAllocatePoolWithTag(p,n,' kdD')
-#else /* !POOL_TAGGING */
+#else /* !POOL_TAGGING */
NTOSAPI PVOID DDKAPI
ExAllocatePool( /*IN*/ POOL_TYPE PoolType, /*IN*/ SIZE_T NumberOfBytes );
NTOSAPI PVOID DDKAPI
ExAllocatePoolWithQuota( /*IN*/ POOL_TYPE PoolType, /*IN*/ SIZE_T NumberOfBytes );
-#endif /* POOL_TAGGING */
+#endif /* POOL_TAGGING */
NTOSAPI PVOID DDKAPI
ExAllocatePoolWithTagPriority(
#define KdBreakPoint() DbgBreakPoint()
#define KdBreakPointWithStatus(s) DbgBreakPointWithStatus(s)
-#else /* !DBG */
+#else /* !DBG */
#define KdPrint(_x_)
#define KdPrintEx(_x_)
#define KdBreakPoint()
#define KdBreakPointWithStatus(s)
-#endif /* !DBG */
+#endif /* !DBG */
extern NTOSAPI PBOOLEAN KdDebuggerNotPresent;
extern NTOSAPI PBOOLEAN KdDebuggerEnabled;
(PSECURITY_DESCRIPTOR, DWORD);
WINBASEAPI BOOL WINAPI InitializeSid (PSID, PSID_IDENTIFIER_AUTHORITY, BYTE);
-#if !(__USE_NTOSKRNL__)
-/* CAREFUL: These are exported from ntoskrnl.exe and declared in winddk.h
- as __fastcall functions, but are exported from kernel32.dll as __stdcall */
-#if (_WIN32_WINNT >= 0x0501)
+/* Formerly declared here, but now documented by Microsoft as being
+ * declared in <winnt.h>, (which has been automatically included by
+ * the time we get here), declarations of the following interlocked
+ * memory access functions:
+ *
+ * long InterlockedDecrement (long volatile *);
+ * long InterlockedIncrement (long volatile *);
+ *
+ * long InterlockedExchange (long volatile *, long);
+ * long InterlockedCompareExchange (long volatile *, long, long);
+ * long InterlockedExchangeAdd (long volatile *, long);
+ *
+ * together with the associated intrinsic implementations of:
+ *
+ * void *InterlockedCompareExchangePointer (void *volatile *, void *, void *);
+ * void *InterlockedExchangePointer (void *volatile *, void *);
+ *
+ * have been relocated accordingly.
+ */
+#if _WIN32_WINNT >= _WIN32_WINNT_WINXP
+/* FIXME: Microsoft's current documentation says that the following
+ * should be declared in <interlockedapi.h>, (which MinGW.OSDN doesn't
+ * provide at present); leave them here for the time being, but maybe
+ * consider a future relocation.
+ */
WINBASEAPI VOID WINAPI InitializeSListHead (PSLIST_HEADER);
-#endif
+WINBASEAPI PSLIST_ENTRY WINAPI InterlockedFlushSList (PSLIST_HEADER);
-#ifndef __INTERLOCKED_DECLARED
-/* FIXME: Is this another invitation for inconsistent definition?
- * Where else is this declared?
+#ifndef _DDK_WINDDK_H
+/*
+ * ** CAUTION **
+ *
+ * This pair is exported by both ntoskrnl.exe and kernel32.exe, but with
+ * incompatible calling conventions; intent to link with ntoskrnl.exe may
+ * have been indicated already, by prior inclusion of <ddk/winddk.h>, in
+ * which case these will have been declared already, with the appropriate
+ * __fastcall semantics, but if not, declare them here, with the choice
+ * between __stdcall and __fastcall determined appropriately by prior
+ * definition of __kernel_api, inherited from <winnt.h>, (which has
+ * been included previously).
*/
-#define __INTERLOCKED_DECLARED
-LONG WINAPI InterlockedCompareExchange (LONG volatile *, LONG, LONG);
-/* PVOID WINAPI InterlockedCompareExchangePointer (PVOID *, PVOID, PVOID); */
-#define InterlockedCompareExchangePointer(d, e, c) \
- (PVOID)InterlockedCompareExchange((LONG volatile *)(d),(LONG)(e),(LONG)(c))
-LONG WINAPI InterlockedDecrement (LONG volatile *);
-LONG WINAPI InterlockedExchange (LONG volatile *, LONG);
-/* PVOID WINAPI InterlockedExchangePointer (PVOID *, PVOID); */
-#define InterlockedExchangePointer(t, v) \
- (PVOID)InterlockedExchange((LONG volatile *)(t),(LONG)(v))
-LONG WINAPI InterlockedExchangeAdd (LONG volatile *, LONG);
-
-#if (_WIN32_WINNT >= 0x0501)
-PSLIST_ENTRY WINAPI InterlockedFlushSList (PSLIST_HEADER);
-#endif
-
-LONG WINAPI InterlockedIncrement (LONG volatile *);
+PSLIST_ENTRY __kernel_api InterlockedPushEntrySList (PSLIST_HEADER, PSLIST_ENTRY);
+PSLIST_ENTRY __kernel_api InterlockedPopEntrySList (PSLIST_HEADER);
-#if (_WIN32_WINNT >= 0x0501)
-PSLIST_ENTRY WINAPI InterlockedPopEntrySList (PSLIST_HEADER);
-PSLIST_ENTRY WINAPI InterlockedPushEntrySList (PSLIST_HEADER, PSLIST_ENTRY);
-#endif
-#endif /* __INTERLOCKED_DECLARED */
-#endif /* __USE_NTOSKRNL__ */
+#endif /* !_DDK_WINDDK_H */
+#endif /* _WIN32_WINNT >= _WIN32_WINNT_WINXP */
WINBASEAPI BOOL WINAPI IsBadCodePtr (FARPROC);
WINBASEAPI BOOL WINAPI IsBadHugeReadPtr (PCVOID, UINT);
#undef __mingw_thread_fence
#undef __mingw_fence_insn__
+#ifndef _DDK_NTDDK_H
+/* Several of the interlocked memory access API functions, which are
+ * declared below, are exported by both kernel32.dll, and ntoskrnl.exe,
+ * but with different (incompatible) calling conventions in each case.
+ *
+ * In the case where _DDK_NTDDL_H is NOT defined, it is assumed that
+ * the intent is to link with kernel32.dll, and the __stdcall calling
+ * convention is applicable...
+ */
+#define __kernel_api __stdcall
+#else
+/* ...whereas, when the _DDK_NTDDK_H guard IS defined, (as it will
+ * be when <ddk/ntddk.h> has been included beforehand), it is assumed
+ * that the intent is to build a Windows device driver, which will be
+ * linked with ntoskrnl.exe, and the __fastcall calling convention
+ * becomes applicable.
+ */
+#define __kernel_api __fastcall
+#endif
+/* Formerly declared within <winbase.h>, and relocated here, to
+ * conform with Microsoft's current documentation, the following,
+ * conforming to the __stdcall calling convention, are exported by
+ * kernel32.dll; alternative implementations of each, but conforming
+ * to the __fastcall calling convention, are exported by ntoskrnl.exe,
+ * so these are declared with the appropriate __kernel_api calling
+ * convention, as determined immediately above.
+ */
+LONG __kernel_api InterlockedDecrement (LONG volatile *);
+LONG __kernel_api InterlockedIncrement (LONG volatile *);
+
+LONG __kernel_api InterlockedExchange (LONG volatile *, LONG);
+LONG __kernel_api InterlockedCompareExchange (LONG volatile *, LONG, LONG);
+LONG __kernel_api InterlockedExchangeAdd (LONG volatile *, LONG);
+
+/* The interlocked pointer exchange functions are ALWAYS implemented
+ * as intrinsics, in terms of corresponding long int exchange functions.
+ */
+#define _WIN32_INTRINSIC extern __inline__ __attribute__((gnu_inline))
+
+_WIN32_INTRINSIC
+PVOID InterlockedCompareExchangePointer (PVOID volatile *D, PVOID X, PVOID C)
+{ return (PVOID)(
+ InterlockedCompareExchange ((LONG volatile *)(D), (LONG)(X), (LONG)(C))
+ );
+}
+_WIN32_INTRINSIC
+PVOID InterlockedExchangePointer (PVOID volatile *D, PVOID X)
+{ return (PVOID)(
+ InterlockedExchange ((LONG volatile *)(D), (LONG)(X))
+ );
+}
+
_END_C_DECLS
#endif /* ! RC_INVOKED */