-
Notifications
You must be signed in to change notification settings - Fork 822
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement version detection for RivaTuner Statistics Server
- Loading branch information
1 parent
27aece3
commit 8878f17
Showing
7 changed files
with
354 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
.../java/me/jellysquid/mods/sodium/client/platform/windows/api/version/LanguageCodePage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package me.jellysquid.mods.sodium.client.platform.windows.api.version; | ||
|
||
import org.lwjgl.system.MemoryUtil; | ||
|
||
public record LanguageCodePage(int languageId, int codePage) { | ||
static final int STRIDE = Integer.BYTES; | ||
|
||
static LanguageCodePage decode(long address) { | ||
var value = MemoryUtil.memGetInt(address); | ||
|
||
int languageId = value & 0xFFFF; | ||
int codePage = (value & 0xFFFF0000) >> 16; | ||
|
||
return new LanguageCodePage(languageId, codePage); | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
src/main/java/me/jellysquid/mods/sodium/client/platform/windows/api/version/QueryResult.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
package me.jellysquid.mods.sodium.client.platform.windows.api.version; | ||
|
||
public record QueryResult(long address, int length) { | ||
} |
81 changes: 81 additions & 0 deletions
81
src/main/java/me/jellysquid/mods/sodium/client/platform/windows/api/version/Version.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package me.jellysquid.mods.sodium.client.platform.windows.api.version; | ||
|
||
import me.jellysquid.mods.sodium.client.platform.windows.api.Kernel32; | ||
import org.jetbrains.annotations.Nullable; | ||
import org.lwjgl.PointerBuffer; | ||
import org.lwjgl.system.*; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.nio.IntBuffer; | ||
|
||
public class Version { | ||
private static final SharedLibrary LIBRARY = APIUtil.apiCreateLibrary("version"); | ||
|
||
private static final long PFN_GetFileVersionInfoSizeW; | ||
private static final long PFN_GetFileVersionInfoW; | ||
|
||
private static final long PFN_VerQueryValueW; | ||
|
||
static { | ||
PFN_GetFileVersionInfoSizeW = APIUtil.apiGetFunctionAddress(LIBRARY, "GetFileVersionInfoSizeW"); | ||
PFN_GetFileVersionInfoW = APIUtil.apiGetFunctionAddress(LIBRARY, "GetFileVersionInfoW"); | ||
|
||
PFN_VerQueryValueW = APIUtil.apiGetFunctionAddress(LIBRARY, "VerQueryValueW"); | ||
} | ||
|
||
|
||
static @Nullable QueryResult query(ByteBuffer pBlock, String subBlock) { | ||
try (MemoryStack stack = MemoryStack.stackPush()) { | ||
ByteBuffer pSubBlock = stack.malloc(16, MemoryUtil.memLengthUTF16(subBlock, true)); | ||
MemoryUtil.memUTF16(subBlock, true, pSubBlock); | ||
|
||
PointerBuffer pBuffer = stack.callocPointer(1); | ||
IntBuffer pLen = stack.callocInt(1); | ||
|
||
int result = JNI.callPPPPI(MemoryUtil.memAddress(pBlock), MemoryUtil.memAddress(pSubBlock), | ||
MemoryUtil.memAddress(pBuffer), MemoryUtil.memAddress(pLen), Version.PFN_VerQueryValueW); | ||
|
||
if (result == 0) { | ||
return null; | ||
} | ||
|
||
return new QueryResult(pBuffer.get(), pLen.get()); | ||
} | ||
} | ||
|
||
public static @Nullable VersionInfo getModuleFileVersion(String filename) { | ||
ByteBuffer lptstrFilename = MemoryUtil.memAlignedAlloc(16, MemoryUtil.memLengthUTF16(filename, true)); | ||
|
||
try (MemoryStack stack = MemoryStack.stackPush()) { | ||
MemoryUtil.memUTF16(filename, true, lptstrFilename); | ||
|
||
IntBuffer lpdwHandle = stack.callocInt(1); | ||
int versionInfoLength = JNI.callPPI(MemoryUtil.memAddress(lptstrFilename), MemoryUtil.memAddress(lpdwHandle), PFN_GetFileVersionInfoSizeW); | ||
|
||
if (versionInfoLength == 0) { | ||
int error = Kernel32.getLastError(); | ||
|
||
switch (error) { | ||
case 0x714 /* ERROR_RESOURCE_DATA_NOT_FOUND */: | ||
case 0x715 /* ERROR_RESOURCE_TYPE_NOT_FOUND */: | ||
return null; | ||
default: | ||
throw new RuntimeException("GetFileVersionInfoSizeW failed, error=" + error); | ||
} | ||
} | ||
|
||
VersionInfo versionInfo = VersionInfo.allocate(versionInfoLength); | ||
int result = JNI.callPPI(MemoryUtil.memAddress(lptstrFilename), lpdwHandle.get(), versionInfoLength, versionInfo.address(), PFN_GetFileVersionInfoW); | ||
|
||
if (result == 0) { | ||
versionInfo.close(); | ||
|
||
throw new RuntimeException("GetFileVersionInfoW failed, error=" + Kernel32.getLastError()); | ||
} | ||
|
||
return versionInfo; | ||
} finally { | ||
MemoryUtil.memAlignedFree(lptstrFilename); | ||
} | ||
} | ||
} |
Oops, something went wrong.