InterlockedCompareExchange in windows 98 environment - winapi

I am forced to run some applications in windows 98 se. vc6 has strange InterlockedCompareExchange definition:
void* InterlockedCompareExchange(void**, void*, void*);
msdn defines it like this however (since windows xp):
LONG InterlockedCompareExchange(LONG*, LONG, LONG);
Does anyone remembers how to use it (I need to atomically get value of interlocked variable)?

Windows 98 did not support 64bit, so void* and LONG are the same byte size. Most OSes actually use the LONG definition, but if VC6 is using `void* then simply type-cast where needed:
LONG value;
LONG ret = (LONG) InterlockedCompareExchange((void**)&value, (void*)ExchangeValue, (void*)CompareValue);

Related

Resolving Error R6016 - Not enough space for thread data

My statically-linked Visual C++ 2012 program sporadically generates a CRTL error: "R6016 - Not enough space for thread data".
The minimal documentation from Microsoft says this error message is generated when a new thread is spawned, but not enough memory can be allocated for it.
However, my code only explicitly spawns a new thread in a couple of well-defined cases, neither of which are occurring here (although certainly the Microsoft libraries internally spawn threads at well). One user reported this problem when the program was just existing in the background.
Not sure if it's relevant, but I haven't overridden the default 1MB reserved stack size or heap size, and the total memory in use by my program is usually quite small (3MB-10MB on a system with 12GB actual RAM, over half of which is unallocated).
This happens very rarely (so I can't track it down), and it's been reported on more than one machine. I've only heard about this on Windows 8.1, but I wouldn't read too much into that.
Is there some compiler setting somewhere that might influence this error? Or programming mistake?
This turned out to be caused by calling CreateThread rather than _beginthread. Microsoft documentation in the Remarks section states that CreateThread causes conflicts when using the CRT library, and indeed, once we made the change, we never saw that error again.
You have to call TlsAlloc in DllMain if the Windows version is Vista or higher .
implicit TLS handling was rewritten in Windows Vista [...]
threadprivate and __declspec(thread) should function correctly in
run-time loaded DLLs since then.
BOOL APIENTRY DllMain(HINSTANCE hinstDll, DWORD fdwReason,
LPVOID lpvReserved)
{
static BOOL fFirstProcess = TRUE;
BOOL fWin32s = FALSE;
DWORD dwVersion = GetVersion();
static DWORD dwIndex;
if ( !(dwVersion & 0x80000000) && LOBYTE(LOWORD(dwVersion))<4 )
fWin32s = TRUE;
if (dwReason == DLL_PROCESS_ATTACH) {
if (fFirstProcess || !fWin32s) {
dwIndex = TlsAlloc();
}
fFirstProcess = FALSE;
}
}
kb 118816
When a program is started the size of the TLS is determined by taking
into account the TLS size required by the executable as well as the
TLS requirements of all other implicitly loaded DLLs. When you load
another DLL dynamically with LoadLibrary or unload it with
FreeLibrary, the system has to examine all running threads and to
enlarge or compact their TLS storage accordingly.
Your DLL code should be modified to use such TLS functions as TlsAlloc, and to allocate TLS if the DLL is loaded with LoadLibrary. Or, the DLL that is using __declspec(thread) should only be implicitly loaded into the application.
Bottom line: LoadLibrary ain't thread-safe.
I discovered that process is in 32 bit.
In this case I increase memory to process with the command
bcdedit /set increaseuserva 3072

Windows 64-bit and 32-bit incompatibilities

I know that 64-bit applications need 64-bit Windows.
Which c/c++ code will work only for 64-bit or 32-bit exclusively?
Edit: I have found it here
Can I determine proccess word size on runtime: Like I will have 32-bit application which returns if OS is 32 or 64 bit and then runs sub/new proccess with right word size.
You can find out if your system is 32-bit or 64-bit with GetNativeSystemInfo. For example, you could do something like this:
typedef void (WINAPI *GetNativeSystemInfo_t)(LPSYSTEM_INFO lpSystemInfo);
BOOL IsSystem64Bit()
{
HANDLE kernel32 = LoadLibrary("kernel32.dll");
SYSTEM_INFO si;
GetNativeSystemInfo_t GetNativeSystemInfoPtr
= (GetNativeSystemInfo_t)GetProcAddress(kernel32, "GetNativeSystemInfo");
if (GetNativeSystemInfoPtr == NULL)
return FALSE;
GetNativeSystemInfoPtr(&si);
return (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64);
}
The reason the function is resolved dynamically is because it doesn't exist on versions of Windows prior to XP. (And on those versions of windows, we already know that the system is not 64-bit)
I'm not sure about Windows, and so obviously this will be limited in helpfulness, but on Linux you can determine word size at runtime. A long int will be the word size. On 64-bit Linux long is 64-bits and 32-bits on 32-bit Linux.
So, this seems really stupid and inconsistent, but you could do something like
char ws[3];
sprintf(ws, "%d", sizeof(long));
fprintf(stderr, "%s\n", ws);
You can then compare ws with different values to see what the word size is. I'm sure that Windows has a comparable basic type that can help you tell what the word size is.

Is it possible to read process memory of a 64 bit process from a 32bit app?

On windows 64 bit, I've got a 32 bit process that reads the memory of other 32 bit processes, and I'd like it to be able to read 64 bit processes too.
ReadProcessMemory is being used to read the memory, but it has a 32 bit limitation. Is there any way of doing the equivalent of a ReadProcessMemory on a 64 bit process?
I know I could write a 64 bit process and launch that from my 32 bit process to do the work, but I'm wondering if there's some other option so that I don't need to write a 64 bit process.
Thanks.
It's possible.
For an example you may refer to the excellent sample in the answer of tofucoder.
For one more sample you may refer to this link.
For explanation why it actually works please check this thread.
Another sample may be found here.
The whole trick is to call 64-bit version of ReadProcessMemory function. Intuitively it's not an option from 32-bit process however the link above explains: x64 version of ntdll.dll is also loaded as a part of 32-bit process in Windows WOW64 emulator. It has a function called NtReadVirtualMemory with the same prototype as ReadProcessMemory64:
__declspec(SPEC)BOOL __cdecl ReadProcessMemory64(HANDLE hProcess, DWORD64 lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
The address is 64-bit long and thus the whole virtual address space of 64-bit process may be referred.
You may wonder how to get the address of this function. It's when another function in ntdll.dll comes in handy: LdrGetProcedureAddress. Its prototype is the same as of GetProcAddress:
__declspec(SPEC)DWORD64 __cdecl GetProcAddress64(DWORD64 hModule, char* funcName);
We are to examine export directory of x64 ntdll.dll and manually found this function's entry. Then we can obtain address of any other function.
Another question is left uncovered so far: how to obtain start address of x64 ntdll.dll? We need to manually walk through x64 PEB structure of our process and traverse loaded modules' list - as one of the variants. And how to get PEB address? Please refer to the links above, not to overflow this post with too many details.
All this is covered in sample from the first link.
Alternative variants with usage of NtReadVirtualMemory & NtWow64ReadVirtualMemory64 functions are provided in second & third links (as well as alternative ways to get PEB address).
Summary: it is possible to interact with x64 process from x86 one. It can be done either with direct call to x64 version of function (from x64 ntdll.dll which is loaded as a part of WOW64 process) or with the call of specific x86 function which is intended to work with x64 process (namely NtWow64ReadVirtualMemory64).
P.S. One may say it's undocumented and is more like hack - but it's just not officially documented. Soft like Unlocker, ProcessHacker or ProcessExplorer, for example, makes use of these undocumented features (and many more), and it's up to you to decide, of course.
The library wow64ext seems to have solved this problem and offers a function ReadProcessMemory64 The Visual Studio Extension VSDebugTool seems to use this library and works for me with 64 bit processes.
Anyway, it shouldn't be impossibe because the (32 bit) Visual Studio Debugger handles 64 bit Debuggees very well.
No: http://blogs.msdn.com/b/oldnewthing/archive/2008/10/20/9006720.aspx
There's no way to get around this. One solution is to stop using the WOW64 emulator and write a 64 bit process. Another solution is to use IPC rather than direct memory reading.
ReadProcessMemory can read any size of memory including from x86 processes reading x64 processes.
You can without a problem, in an x86 program, do the following:
DWORD64 test = 0;
ReadProcessMemory(hProcess, (LPCVOID)lpBaseAddress, &test, sizeof(DWORD64), NULL);
Which would allow you to dereference an x64 pointer from a x86 process.

Are the *A Win32 API calls still relevant?

I still see advice about using the LPTSTR/TCHAR types, etc., instead of LPWSTR/WCHAR. I believe the Unicode stuff was well introduced at Win2k, and I frankly don't write code for Windows 98 anymore. (Excepting special cases, of course.) Given that I don't care about Windows 98 (or, even less, ME) as they're decade old OS, is there any reason to use the compatibility TCHAR, etc. types? Why still advise people to use TCHAR - what benefit does it add over using WCHAR directly?
If someone tells you to walk up to 1,000,000 lines of non-_UNICODE C++, with plenty of declarations using char instead of wchar_t or TCHAR or WCHAR, you had better be prepared to cope with the non-Unicode Win32 API. Conversion on a large scale is quite costly, and may not be something the source-o-money is prepared to pay for.
As for new code, well, there's so much example code out there using TCHAR that it may be easier to cut and paste, and there is in some cases some friction between WCHAR as wchar_t and WCHAR as unsigned short.
Who knows, maybe some day MS will add a UTF-32 data type under TCHAR?
Actually, the unicode versions of functions were introduced with Win32 in 1993 with Windows NT 3.1. In fact, on the NT based oses, almost all the *A functions just convert to Unicode and call the *W version internally. Also, support for the *W functions on 9x does exist through Microsoft Layer for Unicode.
For new programs, I would definately recommend using the TCHAR macros or WCHARs directly. I doubt MS will be adding support for any other character sizes during NT's lifetime. For existing code bases, I guess it would depend on how important it is to support Unicode vs cost of fixing it. The *A functions need to stay in Win32 forever for backward compatibility.

DWORD_PTR, INT_PTR, LONG_PTR, UINT_PTR, ULONG_PTR When, How and Why?

I found that Windows has some new Windows Data Types
DWORD_PTR, INT_PTR, LONG_PTR, UINT_PTR, ULONG_PTR
can you tell me when, how and why to use them?
The *_PTR types were added to the Windows API in order to support Win64's 64bit addressing.
Because 32bit APIs typically passed pointers using data types like DWORD, it was necessary to create new types for 64 bit compatibility that could substitute for DWORD in 32bit applications, but were extended to 64bits when used in a 64bit applications.
So, for example, application developers who want to write code that works as 32bit OR 64bit the windows 32bit API SetWindowLong(HWND,int,LONG) was changed to SetWindowLongPtr(HWND,int,LONG_PTR)
In a 32bit build, SetWindowLongPtr is simply a macro that resolves to SetWindowLong, and LONG_PTR is likewise a macro that resolves to LONG.
In a 64bit build on the other hand, SetWindowLongPtr is an API that accepts a 64bit long as its 3rd parameter, and ULONG_PTR is typedef for unsigned __int64.
By using these _PTR types, one codebase can compile for both Win32 and Win64 targets.
When performing pointer arithmetic, these types should also be used in 32bit code that needs to be compatible with 64bit.
so, if you need to access an array with more than 4billion elements, you would need to use an INT_PTR rather than an INT
CHAR* pHuge = new CHAR[0x200000000]; // allocate 8 billion bytes
INT idx;
INT_PTR idx2;
pHuge[idx]; // can only access the 1st 4 billion elements.
pHuge[idx2]; // can access all 64bits of potential array space.
Chris Becke is pretty much correct. Its just worth noting that these _PTR types are just types that are 32-bits wide on a 32-bit app and 64-bits wide on a 64-bit app. Its as simple as that.
You could easily use __int3264 instead of INT_PTR for example.

Resources