Unfortunately, the accepted answer appears to be incorrect
EDIT: Apr 18 2021 - xitalogy - the OP on the accepted answer put a comment on it and edited it to correct it. It was a simple typo. I will leave this answer here, though, because I feel anyone who wants to go through the (rather lengthy and technical) answer here could benefit from some of the additional information.
Click this link, then scroll down to DWORD:
https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types
It says the following (copied/pasted):
DWORD A 32-bit unsigned integer. The range is 0 through 4294967295 decimal.
This type is declared in IntSafe.h as follows:
typedef unsigned long DWORD;
I verified the typedef in IntSafe.h in the Windows 10 SDK
NOTE: 0x is the C/C++ prefix to indicate hexadecimal notation
32 bits / 8 bits per byte == 4 bytes: 0xFF == 255 (one byte) 4 bytes would be 0xFFFFFFFF == 4294967295 (4 FFs put together, not 3 as in your answer, which would be 24 bits, not 32 bits) for a DWORD (unsigned long)
Copied directly from WinUser.h in the Windows 10 SDK:
#define ASFW_ANY ((DWORD)-1)
This gives 4294967295 (decimal) for a DWORD (unsigned long) or -1 (decimal) for a long (signed). Both would show 0xFFFFFFFF when displayed in hexadecimal (see test results below).
Testing
Here are the results of some test code I wrote in Visual Studio 2019 Preview (C++) with identical results for 64 bit and 32 bit targets (numbers should be identical in Windows XP Pro and Windows 7 Pro):
DWORD DWORD_var (hex)................: 0xFFFFFFFF (dec): 4294967295
DWORD DWORD_var (AFSW_ANY - hex).....: 0xFFFFFFFF (dec): 4294967295
unsigned long unsigned_long_var (hex): 0xFFFFFFFF (dec): 4294967295
long long_var (hex)..................: 0xFFFFFFFF (dec): -1
long long_var (hex)..................: 0xFFFFFFFE (dec): -2
long long_var (hex)..................: 0x80000000 (dec): -2147483648
long long_var (hex)..................: 0x7FFFFFFF (dec): 2147483647
long long_var (hex)..................: 0x7FFFFFFE (dec): 2147483646
long long_var (hex)..................: 0xFFFFFF (dec): 16777215
long long_var (hex)..................: 0xFFFFFE (dec): 16777214
Here is that code (C++):
DWORD DWORD_var = 0xFFFFFFFF;
unsigned long unsigned_long_var = 0xFFFFFFFF;
long long_var = 0xFFFFFFFF;
std::wostringstream wostringstream;
wostringstream << std::endl << "DWORD DWORD_var (hex)................: 0x" << std::hex << std::uppercase << DWORD_var << " (dec): " << std::dec << DWORD_var;
DWORD_var = ASFW_ANY; // From WinUser.h: #define ASFW_ANY ((DWORD)-1)
wostringstream << std::endl << "DWORD DWORD_var (AFSW_ANY - hex).....: 0x" << std::hex << std::uppercase << DWORD_var << " (dec): " << std::dec << DWORD_var;
wostringstream << std::endl << "unsigned long unsigned_long_var (hex): 0x" << std::hex << std::uppercase << unsigned_long_var << " (dec): " << std::dec << unsigned_long_var;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0xFFFFFFFE;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0x80000000;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0x7FFFFFFF;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0x7FFFFFFE;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0xFFFFFF;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
long_var = 0xFFFFFE;
wostringstream << std::endl << "long long_var (hex)..................: 0x" << std::hex << std::uppercase << long_var << " (dec): " << std::dec << long_var;
OutputDebugString(wostringstream.str().c_str());
Final Note on Process/Thread ID Limits
Mark Russinovich wrote the following in a 2009 blog post. My guess is it is still accurate in Windows 10 today.:
Unlike some UNIX variants, most resources in Windows have no fixed upper bound compiled into the operating system, but rather derive their limits based on basic operating system resources that I’ve already covered. Process and threads, for example, require physical memory, virtual memory, and pool memory, so the number of processes or threads that can be created on a given Windows system is ultimately determined by one of these resources, depending on the way that the processes or threads are created and which constraint is hit first.
Link to that post:
https://techcommunity.microsoft.com/t5/windows-blog-archive/pushing-the-limits-of-windows-processes-and-threads/ba-p/723824
Obviously, though practically speaking unreachable, the upper limit of a DWORD would be a hard constraint, however, and since -1 is not a valid value, I kind of wonder if any number resulting in a negative if signed might be invalid, which would give a hard (but again, practically speaking unreachable) upper limit of 2147483647. That is just speculation, though