or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmemory-management.mdptr-package.mdstructures-types.mdwindows.md

windows.mddocs/

0

# JNA Windows Integration

1

2

This document covers JNA's Windows-specific functionality including stdcall calling convention support, Win32 API integration, and Windows-specific utilities.

3

4

## Core Imports

5

6

```java { .api }

7

import com.sun.jna.win32.StdCall;

8

import com.sun.jna.win32.StdCallLibrary;

9

import com.sun.jna.win32.W32APIOptions;

10

import com.sun.jna.win32.StdCallFunctionMapper;

11

import com.sun.jna.win32.W32APIFunctionMapper;

12

import com.sun.jna.win32.W32APITypeMapper;

13

```

14

15

## StdCall Interface - Windows Calling Convention

16

17

```java { .api }

18

/**

19

* Marker interface for stdcall calling convention

20

* Used by Windows API functions

21

*/

22

public interface StdCall extends AltCallingConvention {

23

// Marker interface - no methods

24

}

25

26

/**

27

* Base interface for Windows stdcall libraries

28

*/

29

public interface StdCallLibrary extends Library, StdCall {

30

/** Stdcall calling convention constant */

31

int STDCALL_CONVENTION = Function.ALT_CONVENTION;

32

33

/** Auto-lookup of stdcall-decorated names */

34

FunctionMapper FUNCTION_MAPPER = new StdCallFunctionMapper();

35

36

/**

37

* Callback interface using stdcall convention

38

*/

39

public interface StdCallCallback extends Callback, StdCall {

40

// Marker interface for stdcall callbacks

41

}

42

}

43

```

44

45

## Win32 API Options and Configuration

46

47

```java { .api }

48

/**

49

* Standard options for Win32 API usage

50

*/

51

public interface W32APIOptions extends StdCallLibrary {

52

/** Options for Unicode (wide character) Win32 APIs */

53

Map<String, Object> UNICODE_OPTIONS = Collections.unmodifiableMap(new HashMap<String, Object>() {{

54

put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);

55

put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);

56

}});

57

58

/** Options for ASCII/MBCS Win32 APIs */

59

Map<String, Object> ASCII_OPTIONS = Collections.unmodifiableMap(new HashMap<String, Object>() {{

60

put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);

61

put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);

62

}});

63

64

/** Default options based on w32.ascii system property */

65

Map<String, Object> DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii")

66

? ASCII_OPTIONS : UNICODE_OPTIONS;

67

}

68

```

69

70

## Basic Windows Library Definition

71

72

```java { .api }

73

// Simple Windows library interface

74

public interface Kernel32 extends StdCallLibrary {

75

Kernel32 INSTANCE = Native.loadLibrary("kernel32", Kernel32.class);

76

77

/**

78

* Get current process ID

79

* DWORD GetCurrentProcessId(void);

80

*/

81

int GetCurrentProcessId();

82

83

/**

84

* Get handle to current process

85

* HANDLE GetCurrentProcess(void);

86

*/

87

Pointer GetCurrentProcess();

88

89

/**

90

* Sleep for specified milliseconds

91

* void Sleep(DWORD dwMilliseconds);

92

*/

93

void Sleep(int dwMilliseconds);

94

95

/**

96

* Get last Win32 error code

97

* DWORD GetLastError(void);

98

*/

99

int GetLastError();

100

101

/**

102

* Set last error code

103

* void SetLastError(DWORD dwErrCode);

104

*/

105

void SetLastError(int dwErrCode);

106

}

107

108

// Usage

109

int processId = Kernel32.INSTANCE.GetCurrentProcessId();

110

Pointer processHandle = Kernel32.INSTANCE.GetCurrentProcess();

111

Kernel32.INSTANCE.Sleep(1000); // Sleep for 1 second

112

```

113

114

## Unicode vs ASCII API Handling

115

116

```java { .api }

117

// Library supporting both ASCII and Unicode variants

118

public interface User32 extends StdCallLibrary {

119

User32 INSTANCE = Native.loadLibrary("user32", User32.class,

120

W32APIOptions.DEFAULT_OPTIONS);

121

122

/**

123

* Find window by class and window name

124

* Maps to FindWindowA or FindWindowW based on options

125

*/

126

Pointer FindWindow(String lpClassName, String lpWindowName);

127

128

/**

129

* Get window text

130

* Maps to GetWindowTextA or GetWindowTextW

131

*/

132

int GetWindowText(Pointer hWnd, char[] lpString, int nMaxCount);

133

134

/**

135

* Set window text

136

* Maps to SetWindowTextA or SetWindowTextW

137

*/

138

boolean SetWindowText(Pointer hWnd, String lpString);

139

140

/**

141

* Show message box

142

* Maps to MessageBoxA or MessageBoxW

143

*/

144

int MessageBox(Pointer hWnd, String lpText, String lpCaption, int uType);

145

}

146

147

// Explicit Unicode library

148

public interface User32W extends StdCallLibrary {

149

User32W INSTANCE = Native.loadLibrary("user32", User32W.class,

150

W32APIOptions.UNICODE_OPTIONS);

151

152

Pointer FindWindowW(WString lpClassName, WString lpWindowName);

153

int GetWindowTextW(Pointer hWnd, char[] lpString, int nMaxCount);

154

boolean SetWindowTextW(Pointer hWnd, WString lpString);

155

int MessageBoxW(Pointer hWnd, WString lpText, WString lpCaption, int uType);

156

}

157

158

// Explicit ASCII library

159

public interface User32A extends StdCallLibrary {

160

User32A INSTANCE = Native.loadLibrary("user32", User32A.class,

161

W32APIOptions.ASCII_OPTIONS);

162

163

Pointer FindWindowA(String lpClassName, String lpWindowName);

164

int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);

165

boolean SetWindowTextA(Pointer hWnd, String lpString);

166

int MessageBoxA(Pointer hWnd, String lpText, String lpCaption, int uType);

167

}

168

```

169

170

## Function Name Mapping

171

172

```java { .api }

173

/**

174

* Maps function names to stdcall-decorated names

175

*/

176

public class StdCallFunctionMapper implements FunctionMapper {

177

/**

178

* Get decorated function name for stdcall convention

179

* @param library Native library

180

* @param method Java method

181

* @return Decorated name (e.g., "_function@12")

182

*/

183

public String getFunctionName(NativeLibrary library, Method method);

184

}

185

186

/**

187

* Function mapper for Win32 API with ASCII/Unicode variants

188

*/

189

public class W32APIFunctionMapper implements FunctionMapper {

190

/** Mapper for Unicode APIs (adds W suffix) */

191

public static final FunctionMapper UNICODE = new W32APIFunctionMapper(true);

192

193

/** Mapper for ASCII APIs (adds A suffix) */

194

public static final FunctionMapper ASCII = new W32APIFunctionMapper(false);

195

196

/**

197

* Get function name with A or W suffix

198

* @param library Native library

199

* @param method Java method

200

* @return Function name with suffix

201

*/

202

public String getFunctionName(NativeLibrary library, Method method);

203

}

204

```

205

206

## Type Mapping for Win32

207

208

```java { .api }

209

/**

210

* Type mapper for Win32 API types (strings and BOOLs)

211

*/

212

public class W32APITypeMapper extends DefaultTypeMapper {

213

/** TypeMapper for Unicode Win32 APIs */

214

public static final TypeMapper UNICODE;

215

216

/** TypeMapper for ASCII/MBCS Win32 APIs */

217

public static final TypeMapper ASCII;

218

219

/** Default TypeMapper based on w32.ascii system property */

220

public static final TypeMapper DEFAULT;

221

222

static {

223

UNICODE = new W32APITypeMapper(true);

224

ASCII = new W32APITypeMapper(false);

225

DEFAULT = Boolean.getBoolean("w32.ascii") ? ASCII : UNICODE;

226

}

227

}

228

```

229

230

## Common Windows Data Types

231

232

```java { .api }

233

// Windows handle types

234

public static class HANDLE extends PointerType {

235

public HANDLE() { }

236

public HANDLE(Pointer p) { setPointer(p); }

237

}

238

239

public static class HWND extends HANDLE {

240

public HWND() { }

241

public HWND(Pointer p) { super(p); }

242

}

243

244

public static class HMODULE extends HANDLE {

245

public HMODULE() { }

246

public HMODULE(Pointer p) { super(p); }

247

}

248

249

// Windows integer types

250

public static class DWORD extends IntegerType {

251

public DWORD() { super(4, true); } // 4-byte unsigned

252

public DWORD(long value) { super(4, value, true); }

253

}

254

255

public static class WORD extends IntegerType {

256

public WORD() { super(2, true); } // 2-byte unsigned

257

public WORD(long value) { super(2, value, true); }

258

}

259

260

public static class BYTE extends IntegerType {

261

public BYTE() { super(1, true); } // 1-byte unsigned

262

public BYTE(long value) { super(1, value, true); }

263

}

264

265

// BOOL type (maps to int)

266

public static class BOOL implements NativeMapped {

267

private final boolean value;

268

269

public BOOL() { this.value = false; }

270

public BOOL(boolean value) { this.value = value; }

271

272

public boolean booleanValue() { return value; }

273

274

@Override

275

public Object fromNative(Object nativeValue, FromNativeContext context) {

276

return new BOOL(((Integer) nativeValue) != 0);

277

}

278

279

@Override

280

public Object toNative() {

281

return value ? 1 : 0;

282

}

283

284

@Override

285

public Class<?> nativeType() {

286

return Integer.class;

287

}

288

}

289

```

290

291

## Windows Structures

292

293

```java { .api }

294

// RECT structure

295

public static class RECT extends Structure {

296

public int left;

297

public int top;

298

public int right;

299

public int bottom;

300

301

public RECT() { }

302

303

public RECT(int left, int top, int right, int bottom) {

304

this.left = left;

305

this.top = top;

306

this.right = right;

307

this.bottom = bottom;

308

write();

309

}

310

311

@Override

312

protected List<String> getFieldOrder() {

313

return Arrays.asList("left", "top", "right", "bottom");

314

}

315

}

316

317

// POINT structure

318

public static class POINT extends Structure {

319

public int x;

320

public int y;

321

322

public POINT() { }

323

324

public POINT(int x, int y) {

325

this.x = x;

326

this.y = y;

327

write();

328

}

329

330

@Override

331

protected List<String> getFieldOrder() {

332

return Arrays.asList("x", "y");

333

}

334

}

335

336

// SYSTEMTIME structure

337

public static class SYSTEMTIME extends Structure {

338

public short wYear;

339

public short wMonth;

340

public short wDayOfWeek;

341

public short wDay;

342

public short wHour;

343

public short wMinute;

344

public short wSecond;

345

public short wMilliseconds;

346

347

@Override

348

protected List<String> getFieldOrder() {

349

return Arrays.asList("wYear", "wMonth", "wDayOfWeek", "wDay",

350

"wHour", "wMinute", "wSecond", "wMilliseconds");

351

}

352

}

353

```

354

355

## Complete Windows API Example

356

357

```java { .api }

358

// Extended Kernel32 interface

359

public interface Kernel32 extends StdCallLibrary {

360

Kernel32 INSTANCE = Native.loadLibrary("kernel32", Kernel32.class,

361

W32APIOptions.DEFAULT_OPTIONS);

362

363

// Process functions

364

int GetCurrentProcessId();

365

Pointer GetCurrentProcess();

366

Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, int dwProcessId);

367

boolean CloseHandle(Pointer hObject);

368

boolean TerminateProcess(Pointer hProcess, int uExitCode);

369

370

// Memory functions

371

Pointer VirtualAlloc(Pointer lpAddress, int dwSize, int flAllocationType, int flProtect);

372

boolean VirtualFree(Pointer lpAddress, int dwSize, int dwFreeType);

373

374

// Module functions

375

Pointer GetModuleHandle(String lpModuleName);

376

Pointer LoadLibrary(String lpFileName);

377

boolean FreeLibrary(Pointer hModule);

378

Pointer GetProcAddress(Pointer hModule, String lpProcName);

379

380

// System info

381

void GetSystemTime(SYSTEMTIME lpSystemTime);

382

void GetLocalTime(SYSTEMTIME lpSystemTime);

383

int GetTickCount();

384

385

// File functions

386

Pointer CreateFile(String lpFileName, int dwDesiredAccess, int dwShareMode,

387

Pointer lpSecurityAttributes, int dwCreationDisposition,

388

int dwFlagsAndAttributes, Pointer hTemplateFile);

389

boolean ReadFile(Pointer hFile, Pointer lpBuffer, int nNumberOfBytesToRead,

390

IntByReference lpNumberOfBytesRead, Pointer lpOverlapped);

391

boolean WriteFile(Pointer hFile, Pointer lpBuffer, int nNumberOfBytesToWrite,

392

IntByReference lpNumberOfBytesWritten, Pointer lpOverlapped);

393

394

// Constants

395

int PROCESS_ALL_ACCESS = 0x1F0FFF;

396

int MEM_COMMIT = 0x1000;

397

int MEM_RESERVE = 0x2000;

398

int MEM_RELEASE = 0x8000;

399

int PAGE_READWRITE = 0x04;

400

int GENERIC_READ = 0x80000000;

401

int GENERIC_WRITE = 0x40000000;

402

int CREATE_ALWAYS = 2;

403

int OPEN_EXISTING = 3;

404

}

405

406

// Extended User32 interface

407

public interface User32 extends StdCallLibrary {

408

User32 INSTANCE = Native.loadLibrary("user32", User32.class,

409

W32APIOptions.DEFAULT_OPTIONS);

410

411

// Window functions

412

Pointer FindWindow(String lpClassName, String lpWindowName);

413

Pointer GetForegroundWindow();

414

boolean SetForegroundWindow(Pointer hWnd);

415

boolean ShowWindow(Pointer hWnd, int nCmdShow);

416

boolean IsWindowVisible(Pointer hWnd);

417

418

// Window properties

419

int GetWindowText(Pointer hWnd, char[] lpString, int nMaxCount);

420

boolean SetWindowText(Pointer hWnd, String lpString);

421

boolean GetWindowRect(Pointer hWnd, RECT lpRect);

422

boolean SetWindowPos(Pointer hWnd, Pointer hWndInsertAfter,

423

int X, int Y, int cx, int cy, int uFlags);

424

425

// Input functions

426

boolean GetCursorPos(POINT lpPoint);

427

boolean SetCursorPos(int X, int Y);

428

short GetKeyState(int nVirtKey);

429

430

// Message functions

431

int MessageBox(Pointer hWnd, String lpText, String lpCaption, int uType);

432

boolean PostMessage(Pointer hWnd, int Msg, Pointer wParam, Pointer lParam);

433

int SendMessage(Pointer hWnd, int Msg, Pointer wParam, Pointer lParam);

434

435

// Constants

436

int SW_HIDE = 0;

437

int SW_NORMAL = 1;

438

int SW_MAXIMIZE = 3;

439

int SW_MINIMIZE = 6;

440

int MB_OK = 0x00000000;

441

int MB_YESNO = 0x00000004;

442

int WM_CLOSE = 0x0010;

443

int VK_RETURN = 0x0D;

444

int VK_ESCAPE = 0x1B;

445

}

446

```

447

448

## Windows-specific Callback Support

449

450

```java { .api }

451

/**

452

* Callback that can be used in DLL context on Windows

453

*/

454

public interface DLLCallback extends Callback {

455

// Marker interface for DLL-compatible callbacks

456

}

457

458

// Windows callback examples

459

public interface WindowEnumProc extends StdCallLibrary.StdCallCallback {

460

boolean callback(Pointer hWnd, Pointer lParam);

461

}

462

463

public interface HookProc extends StdCallLibrary.StdCallCallback {

464

int callback(int nCode, Pointer wParam, Pointer lParam);

465

}

466

467

// Usage with Win32 APIs

468

public interface User32Extended extends StdCallLibrary {

469

User32Extended INSTANCE = Native.loadLibrary("user32", User32Extended.class);

470

471

/**

472

* Enumerate all top-level windows

473

* BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

474

*/

475

boolean EnumWindows(WindowEnumProc lpEnumFunc, Pointer lParam);

476

477

/**

478

* Install hook procedure

479

* HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);

480

*/

481

Pointer SetWindowsHookEx(int idHook, HookProc lpfn, Pointer hMod, int dwThreadId);

482

483

/**

484

* Remove hook procedure

485

* BOOL UnhookWindowsHookEx(HHOOK hhk);

486

*/

487

boolean UnhookWindowsHookEx(Pointer hhk);

488

}

489

490

// Callback implementations

491

WindowEnumProc windowEnumerator = new WindowEnumProc() {

492

@Override

493

public boolean callback(Pointer hWnd, Pointer lParam) {

494

char[] windowText = new char[512];

495

User32.INSTANCE.GetWindowText(hWnd, windowText, windowText.length);

496

String title = new String(windowText).trim();

497

498

if (!title.isEmpty()) {

499

System.out.println("Window: " + title);

500

}

501

return true; // Continue enumeration

502

}

503

};

504

505

// Enumerate all windows

506

User32Extended.INSTANCE.EnumWindows(windowEnumerator, Pointer.NULL);

507

```

508

509

## Practical Windows Usage Examples

510

511

```java { .api }

512

// Get current window information

513

public class WindowInfo {

514

public static void main(String[] args) {

515

// Get foreground window

516

Pointer hwnd = User32.INSTANCE.GetForegroundWindow();

517

if (hwnd != null) {

518

// Get window title

519

char[] titleBuffer = new char[512];

520

int titleLength = User32.INSTANCE.GetWindowText(hwnd, titleBuffer, titleBuffer.length);

521

String title = new String(titleBuffer, 0, titleLength);

522

523

// Get window position

524

RECT rect = new RECT();

525

User32.INSTANCE.GetWindowRect(hwnd, rect);

526

527

System.out.println("Active window: " + title);

528

System.out.println("Position: (" + rect.left + ", " + rect.top +

529

") - (" + rect.right + ", " + rect.bottom + ")");

530

}

531

}

532

}

533

534

// System information

535

public class SystemInfo {

536

public static void main(String[] args) {

537

// Get current time

538

SYSTEMTIME time = new SYSTEMTIME();

539

Kernel32.INSTANCE.GetSystemTime(time);

540

541

System.out.printf("Current UTC time: %04d-%02d-%02d %02d:%02d:%02d.%03d%n",

542

time.wYear, time.wMonth, time.wDay,

543

time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);

544

545

// Get process info

546

int processId = Kernel32.INSTANCE.GetCurrentProcessId();

547

Pointer processHandle = Kernel32.INSTANCE.GetCurrentProcess();

548

549

System.out.println("Process ID: " + processId);

550

System.out.println("Process handle: " + processHandle);

551

}

552

}

553

554

// File operations

555

public class FileOperations {

556

public static void writeFile(String filename, String content) {

557

Pointer hFile = Kernel32.INSTANCE.CreateFile(

558

filename,

559

Kernel32.GENERIC_WRITE,

560

0, // No sharing

561

null, // Default security

562

Kernel32.CREATE_ALWAYS,

563

0, // Normal attributes

564

null // No template

565

);

566

567

if (hFile == null || hFile.equals(Pointer.createConstant(-1))) {

568

throw new RuntimeException("Failed to create file: " +

569

Kernel32.INSTANCE.GetLastError());

570

}

571

572

try {

573

byte[] data = content.getBytes("UTF-8");

574

Memory buffer = new Memory(data.length);

575

buffer.write(0, data, 0, data.length);

576

577

IntByReference bytesWritten = new IntByReference();

578

boolean success = Kernel32.INSTANCE.WriteFile(

579

hFile, buffer, data.length, bytesWritten, null);

580

581

if (!success) {

582

throw new RuntimeException("Failed to write file: " +

583

Kernel32.INSTANCE.GetLastError());

584

}

585

586

System.out.println("Wrote " + bytesWritten.getValue() + " bytes");

587

588

} catch (Exception e) {

589

throw new RuntimeException("Error writing file", e);

590

} finally {

591

Kernel32.INSTANCE.CloseHandle(hFile);

592

}

593

}

594

}

595

```

596

597

## Error Handling with GetLastError

598

599

```java { .api }

600

// Error handling pattern

601

public class Win32ErrorHandler {

602

public static void checkResult(boolean success, String operation) {

603

if (!success) {

604

int errorCode = Kernel32.INSTANCE.GetLastError();

605

throw new Win32Exception(errorCode, operation + " failed");

606

}

607

}

608

609

public static void checkHandle(Pointer handle, String operation) {

610

if (handle == null || handle.equals(Pointer.createConstant(-1))) {

611

int errorCode = Kernel32.INSTANCE.GetLastError();

612

throw new Win32Exception(errorCode, operation + " failed");

613

}

614

}

615

}

616

617

// Custom exception for Win32 errors

618

public class Win32Exception extends RuntimeException {

619

private final int errorCode;

620

621

public Win32Exception(int errorCode, String message) {

622

super(message + " (error code: " + errorCode + ")");

623

this.errorCode = errorCode;

624

}

625

626

public int getErrorCode() {

627

return errorCode;

628

}

629

}

630

631

// Usage

632

try {

633

Pointer handle = Kernel32.INSTANCE.CreateFile(filename, access, share, null, disposition, flags, null);

634

Win32ErrorHandler.checkHandle(handle, "CreateFile");

635

636

boolean success = Kernel32.INSTANCE.WriteFile(handle, buffer, size, bytesWritten, null);

637

Win32ErrorHandler.checkResult(success, "WriteFile");

638

639

} catch (Win32Exception e) {

640

System.err.println("Win32 operation failed: " + e.getMessage());

641

System.err.println("Error code: " + e.getErrorCode());

642

}

643

```

644

645

## Advanced Windows Features

646

647

```java { .api }

648

// Registry access

649

public interface Advapi32 extends StdCallLibrary {

650

Advapi32 INSTANCE = Native.loadLibrary("advapi32", Advapi32.class);

651

652

int RegOpenKeyEx(Pointer hKey, String lpSubKey, int ulOptions, int samDesired, PointerByReference phkResult);

653

int RegQueryValueEx(Pointer hKey, String lpValueName, Pointer lpReserved, IntByReference lpType,

654

Pointer lpData, IntByReference lpcbData);

655

int RegCloseKey(Pointer hKey);

656

657

// Registry constants

658

Pointer HKEY_CURRENT_USER = Pointer.createConstant(0x80000001L);

659

Pointer HKEY_LOCAL_MACHINE = Pointer.createConstant(0x80000002L);

660

int KEY_READ = 0x20019;

661

}

662

663

// Performance counters

664

public interface Pdh extends StdCallLibrary {

665

Pdh INSTANCE = Native.loadLibrary("pdh", Pdh.class);

666

667

int PdhOpenQuery(Pointer szDataSource, Pointer dwUserData, PointerByReference phQuery);

668

int PdhAddCounter(Pointer hQuery, String szFullCounterPath, Pointer dwUserData, PointerByReference phCounter);

669

int PdhCollectQueryData(Pointer hQuery);

670

int PdhGetFormattedCounterValue(Pointer hCounter, int dwFormat, Pointer lpdwType, Pointer pValue);

671

int PdhCloseQuery(Pointer hQuery);

672

}

673

```

674

675

This comprehensive Windows integration provides full access to Win32 APIs with proper calling convention support, automatic function name resolution, type mapping, and error handling for robust Windows application development.