A gamepad can be found and its state read by many interfaces.
Here are some that I saw used:
Detect and read state
XInput
Dinput
HID
Raw Input
Only Detect
WbemLocator
SetupDiEnumDeviceInfo and SetupDiGetDeviceInstanceId
Thursday, August 24, 2017
Tuesday, May 23, 2017
WM_CHAR is not a real message
While investigating how to send capital-letter to an application, I found the message WM_CHAR.
Apparently, this message is not generated by the OS, but by TranslateMessage.
TranslateMessage get the WM_KEYDOWN, and if it is a character, check the modifiers, (such as shift, caps-lock, and other keys) and emit a WM_CHAR.
TranslateMessage is an kernel-level function, and check the status of the physical keys. so you can't mess with it. Also, because it is kernel-level, the message looks like the OS sent it.
Apparently, this message is not generated by the OS, but by TranslateMessage.
TranslateMessage get the WM_KEYDOWN, and if it is a character, check the modifiers, (such as shift, caps-lock, and other keys) and emit a WM_CHAR.
TranslateMessage is an kernel-level function, and check the status of the physical keys. so you can't mess with it. Also, because it is kernel-level, the message looks like the OS sent it.
Tuesday, March 21, 2017
How to make you game easy to be added to cloud gaming service
There are a few cloud gaming services active. If you want to sell them you game, and make it easy for them to use your game, here are a few tips:
- Use the popular Direct3D version.
Most of the games use 9, 9ex, 11.0/1. - Make rendering in a dedicated thread.
Everything that can hinder rendering is bad. especially loading. - Always show something.
Even if it is a stupid loading animation. because you can never know how long doing that operation will take. - Load data / save file / whatever in a separate thread.
- Test your game under extreme CPU condition.
Something running in the background?
run with only 1 CPU?
How many cores your game need to function? cores is money. - Test your game under extreme FPS conditions.
Does your game runs OK in 20 fps? 100 fps? - How GPU intensive is your game?
While heavy games will take half of the GPU time per frame, (=60 fps)
There is no reason why your side-scroller will take more then quarter, or even a sixth of the GPU.
GPU time is money. - Test your game under heavy disk load.
If the disk is very busy doing other things when the game is running, how is the experience? - Make your menus clean and simple.
We are blocking the user from doing certain things, and if the menus are messy, moving and dynamic it will be very difficult. - Separate user-configs and system configs
Things that user should be able to change: volume, subtitles.
Should not be able to change: graphic settings, controller.
Should be changes system-wise: language.
Keep these in separate places.
The Registry is considered separate places. - Run the game under various graphic settings
Full screen, windowed, vsync on, vsync off. and such.
Activating Windows Loader debug messages
When you want to know what went wrong in loading the process.
My sources:
Entry Point Not Found, and other DLL Loading Problems
Microsoft System Journal, Under the Hood, September 1999
Basically, they highlight the usage of Windows Debugging Tools utility Global Flags.
It should be able to add a flag "Show Loader Snaps" to the target process.
Well, it doesn't do anything on my machine. So:
Go to
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"
Add a key with your EXE name, such as "ConsoleApplication1.exe" (without path)
Add a value to that key, Type: DWORD, name: "GlobalFlag", value 2.
Now run the process under debugger.
Running and external debug messages collectors such as WinDbg or DebugView won't work.
But running it using Visual Studio or Ollydbg, the loader messages are showing in the output window.
My sources:
Entry Point Not Found, and other DLL Loading Problems
Microsoft System Journal, Under the Hood, September 1999
Basically, they highlight the usage of Windows Debugging Tools utility Global Flags.
It should be able to add a flag "Show Loader Snaps" to the target process.
Well, it doesn't do anything on my machine. So:
Go to
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options"
Add a key with your EXE name, such as "ConsoleApplication1.exe" (without path)
Add a value to that key, Type: DWORD, name: "GlobalFlag", value 2.
Now run the process under debugger.
Running and external debug messages collectors such as WinDbg or DebugView won't work.
But running it using Visual Studio or Ollydbg, the loader messages are showing in the output window.
Tuesday, February 7, 2017
Errors in Windows header files
From time to time I find errors in the WinAPI header files.
Usually, they are small errors, which can be very annoying in certain cases.
Example #1:
Some function definitions lack the DECLSPEC_IMPORT (which is a macro for DLL import/export tag)
Usually, it is not a problem. The compiler identify it as external, and the linker finds it in the WinAPI. But it means that the function pointer does not point directly to the DLL, but indirectly using stubs. On normal usage you won't notice that, but it causes problems with MSDetour library.
Example #2:
EnumPageFiles accept a callback of type PENUM_PAGE_CALLBACK.
But in the definition of that in Psapi.h, they forgot to add the CALLBACK modifier, that should make it to stdcall.
So, if you are using the function, at best you get a weird compilation error, or simply a crash.
Usually, they are small errors, which can be very annoying in certain cases.
Example #1:
Some function definitions lack the DECLSPEC_IMPORT (which is a macro for DLL import/export tag)
Usually, it is not a problem. The compiler identify it as external, and the linker finds it in the WinAPI. But it means that the function pointer does not point directly to the DLL, but indirectly using stubs. On normal usage you won't notice that, but it causes problems with MSDetour library.
Example #2:
EnumPageFiles accept a callback of type PENUM_PAGE_CALLBACK.
But in the definition of that in Psapi.h, they forgot to add the CALLBACK modifier, that should make it to stdcall.
So, if you are using the function, at best you get a weird compilation error, or simply a crash.
Saturday, November 19, 2016
SHGetKnownFolderPath: why is it linked with two jumps?
I noticed a weird behaviour when trying to detour SHGetKnownFolderPath, and investigaed a bit. So I worte a tiny program, and then loaded it in IDA.
The program:
The program:
#include "stdafx.h"
#include "windows.h"
#include "FileAPI.h"
#include "Shlobj.h"
int main()
{
HANDLE hFile = CreateFileA(NULL, 0, 0, NULL, 0, 0, NULL);
SHGetKnownFolderPath(FOLDERID_LocalAppDataLow, 0, NULL, NULL);
return 0;
}
Looking in IDA, I see for CreateFileA:
call ds:__imp__CreateFileA@28 ; CreateFileA(x,x,x,x,x,x,x)
Which takes me to:
.idata:0041B000 ; HANDLE __stdcall CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
.idata:0041B000 extrn __imp__CreateFileA@28:dword ; CODE XREF: _main+2Ep
.idata:0041B000 ; DATA XREF: _main+2Er ...
On the other hand, for SHGetKnownFolderPath I see:
call j__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
Which redirect to:
; __stdcall SHGetKnownFolderPath(x, x, x, x)
j__SHGetKnownFolderPath@16 proc near
jmp _SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
j__SHGetKnownFolderPath@16 endp
Which redirect to:
; __stdcall SHGetKnownFolderPath(x, x, x, x)
_SHGetKnownFolderPath@16 proc near
jmp ds:__imp__SHGetKnownFolderPath@16 ; SHGetKnownFolderPath(x,x,x,x)
_SHGetKnownFolderPath@16 endp
Which redirect to:
.idata:0041B09C ; __declspec(dllimport) __stdcall SHGetKnownFolderPath(x, x, x, x)
.idata:0041B09C extrn __imp__SHGetKnownFolderPath@16:dword
.idata:0041B09C ; DATA XREF: SHGetKnownFolderPath(x,x,x,x)r
So SHGetKnownFolderPath have two more jumps then CreateFileA. I did nothing to the project to make it do it. so why?
Update:
Removing Incremental Linking removed j__SHGetKnownFolderPath@16, but left _SHGetKnownFolderPath@16.
From the VS /INCREMENTAL documentation:
- May contain jump thunks to handle relocation of functions to new addresses
So we have half a solution, and another question: why does this setting effect only this DLL, and not other DLLs? (especially other system DLLs)
Update 2: Solved.
Found out that SHGetKnownFolderPath does not have a __declspec(dllimport) in the definition. Adding it made it be called identical to CreateFileA.
Without it, the compiler created a stub, the linker add a stub of its own for the incremental linking, and only then connected it to the DLL.
Update 2: Solved.
Found out that SHGetKnownFolderPath does not have a __declspec(dllimport) in the definition. Adding it made it be called identical to CreateFileA.
Without it, the compiler created a stub, the linker add a stub of its own for the incremental linking, and only then connected it to the DLL.
Sunday, September 25, 2016
Detecting loaded DLL modules in process
I collected this code from various sources across the net, cleaned and tested it. (VS2015, x86 and x64)
Note that this is for listing the DLL from inside the process, and not from a different one.
It is important to use Loader Lock when dealing with the loader internal structures. It will also make you tread-safe, and make sure that nobody will load another DLL while you are processing the current list.
Alternative to part 1 is the WinAPI call EnumProcessModules.
#include <Windows.h>
#include <winnt.h>
#include <winternl.h>
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
NTSTATUS(NTAPI *LdrLockLoaderLock)(ULONG Flags, ULONG *State, UINT_PTR *Cookie)
= (NTSTATUS(NTAPI *)(ULONG, ULONG *, UINT_PTR *))GetProcAddress(ntdll, "LdrLockLoaderLock");
NTSTATUS(NTAPI *LdrUnlockLoaderLock)(ULONG Flags, UINT_PTR Cookie)
= (NTSTATUS(NTAPI *)(ULONG, UINT_PTR))GetProcAddress(ntdll, "LdrUnlockLoaderLock");
Note that this is for listing the DLL from inside the process, and not from a different one.
It is important to use Loader Lock when dealing with the loader internal structures. It will also make you tread-safe, and make sure that nobody will load another DLL while you are processing the current list.
Alternative to part 1 is the WinAPI call EnumProcessModules.
Part 1: listing currently loaded DLLs
#include <Windows.h>
#include <winnt.h>
#include <winternl.h>
void ListCurrentModules()
{
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
NTSTATUS(NTAPI *LdrLockLoaderLock)(ULONG Flags, ULONG *State, UINT_PTR *Cookie)
= (NTSTATUS(NTAPI *)(ULONG, ULONG *, UINT_PTR *))GetProcAddress(ntdll, "LdrLockLoaderLock");
NTSTATUS(NTAPI *LdrUnlockLoaderLock)(ULONG Flags, UINT_PTR Cookie)
= (NTSTATUS(NTAPI *)(ULONG, UINT_PTR))GetProcAddress(ntdll, "LdrUnlockLoaderLock");
UINT_PTR ldrCookie;
LdrLockLoaderLock(0, NULL, &ldrCookie);
#if defined(_M_X64) // x64
auto pTeb = reinterpret_cast<PTEB>(__readgsqword(reinterpret_cast<UINT_PTR>(&static_cast<NT_TIB*>(nullptr)->Self)));
#elif defined(_M_ARM) // ARM
auto pTeb = reinterpret_cast<PTEB>(_MoveFromCoprocessor(15, 0, 13, 0, 2)); // CP15_TPIDRURW
#else // x86
auto pTeb = reinterpret_cast<PTEB>(__readfsdword(reinterpret_cast<DWORD>(&static_cast<NT_TIB*>(nullptr)->Self)));
#endif
auto pPeb = pTeb->ProcessEnvironmentBlock;
auto pLdrData = pPeb->Ldr;
auto pModListHdr = &pLdrData->InMemoryOrderModuleList;
for (auto pModListCurrent = pModListHdr->Flink; pModListCurrent != pModListHdr; pModListCurrent = pModListCurrent->Flink)
{
// Get current module in list
auto pModEntry = reinterpret_cast<PLDR_DATA_TABLE_ENTRY>(pModListCurrent);
HMODULE moduleHandle = (HMODULE)pModEntry->Reserved2[0]; // ModuleBaseAddress
printf("Module [%S] handle is [%p]\n",
pModEntry->FullDllName.Buffer, moduleHandle);
}
LdrUnlockLoaderLock(0, ldrCookie);
LdrUnlockLoaderLock(0, ldrCookie);
}
Part 2: Getting notifications for DLL loading
I'm using the non official function, LdrRegisterDllNotification.
enum NotificationReasonEnum
{
LDR_DLL_NOTIFICATION_REASON_LOADED = 1,
LDR_DLL_NOTIFICATION_REASON_UNLOADED = 2
};
typedef struct _LDR_DLL_LOADED_NOTIFICATION_DATA {
ULONG Flags; //Reserved.
PCUNICODE_STRING FullDllName; //The full path name of the DLL module.
PCUNICODE_STRING BaseDllName; //The base file name of the DLL module.
PVOID DllBase; //A pointer to the base address for the DLL in memory.
ULONG SizeOfImage; //The size of the DLL image, in bytes.
} LDR_DLL_LOADED_NOTIFICATION_DATA, *PLDR_DLL_LOADED_NOTIFICATION_DATA;
typedef struct _LDR_DLL_UNLOADED_NOTIFICATION_DATA {
ULONG Flags; //Reserved.
PCUNICODE_STRING FullDllName; //The full path name of the DLL module.
PCUNICODE_STRING BaseDllName; //The base file name of the DLL module.
PVOID DllBase; //A pointer to the base address for the DLL in memory.
ULONG SizeOfImage; //The size of the DLL image, in bytes.
} LDR_DLL_UNLOADED_NOTIFICATION_DATA, *PLDR_DLL_UNLOADED_NOTIFICATION_DATA;
typedef union _LDR_DLL_NOTIFICATION_DATA {
LDR_DLL_LOADED_NOTIFICATION_DATA Loaded;
LDR_DLL_UNLOADED_NOTIFICATION_DATA Unloaded;
} LDR_DLL_NOTIFICATION_DATA, *PLDR_DLL_NOTIFICATION_DATA;
void NTAPI DllNotificationCallback(NotificationReasonEnum eAction, LDR_DLL_NOTIFICATION_DATA *NotificationData, void *Context)
{
if (eAction == LDR_DLL_NOTIFICATION_REASON_LOADED)
{
HANDLE moduleHandle = NotificationData->Loaded.DllBase;
printf("Module [%S] dynamically loaded handle=%p\n", NotificationData->Loaded.BaseDllName->Buffer, moduleHandle);
}
}
void RegisterDLLNotifications(PVOID Context)
{
HMODULE ntdll = LoadLibraryA("ntdll.dll");
NTSTATUS(NTAPI *LdrRegisterDllNotification)(ULONG Flags, void *NotificationFunction, PVOID Context, PVOID *Cookie)
= (NTSTATUS(NTAPI *)(ULONG, void *, PVOID, PVOID *))GetProcAddress(ntdll, "LdrRegisterDllNotification");
void *cookie;
LdrRegisterDllNotification(0, (void*)DllNotificationCallback, Context, &cookie);
}
Context can be NULL. Surprisingly, cookie is not optional, but you can just discard the value if you don't need to unregister the callback.
Subscribe to:
Posts (Atom)