Skip to content

Commit d593cf3

Browse files
committed
Chore: merge new commits from dev
2 parents aa3a141 + 56eabbe commit d593cf3

File tree

17 files changed

+421
-105
lines changed

17 files changed

+421
-105
lines changed

src/common/impl/FFPlatform_windows.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ static void getExePath(FFPlatform* platform)
1919
wchar_t exePathW[MAX_PATH];
2020

2121
FF_AUTO_CLOSE_FD HANDLE hPath = CreateFileW(
22-
ffGetProcessParams()->ImagePathName.Buffer,
22+
ffGetPeb()->ProcessParameters->ImagePathName.Buffer,
2323
GENERIC_READ,
2424
FILE_SHARE_READ,
2525
NULL,
@@ -38,7 +38,10 @@ static void getExePath(FFPlatform* platform)
3838
}
3939

4040
if (platform->exePath.length == 0)
41-
ffStrbufSetNWS(&platform->exePath, ffGetProcessParams()->ImagePathName.Length / 2, ffGetProcessParams()->ImagePathName.Buffer);
41+
{
42+
PCUNICODE_STRING imagePathName = &ffGetPeb()->ProcessParameters->ImagePathName;
43+
ffStrbufSetNWS(&platform->exePath, imagePathName->Length / sizeof(wchar_t), imagePathName->Buffer);
44+
}
4245

4346
ffStrbufReplaceAllC(&platform->exePath, '\\', '/');
4447
}
@@ -196,7 +199,7 @@ static void getUserShell(FFPlatform* platform)
196199
static const char* detectWine(void)
197200
{
198201
const char * __cdecl wine_get_version(void);
199-
HMODULE hntdll = GetModuleHandleW(L"ntdll.dll");
202+
void* hntdll = ffLibraryGetModule(L"ntdll.dll");
200203
if (!hntdll) return NULL;
201204
FF_LIBRARY_LOAD_SYMBOL_LAZY(hntdll, wine_get_version);
202205
if (!ffwine_get_version) return NULL;
@@ -296,16 +299,15 @@ static void getSystemArchitecture(FFPlatformSysinfo* info)
296299

297300
static void getCwd(FFPlatform* platform)
298301
{
299-
PCURDIR cwd = &ffGetProcessParams()->CurrentDirectory;
302+
PCURDIR cwd = &ffGetPeb()->ProcessParameters->CurrentDirectory;
300303
ffStrbufSetNWS(&platform->cwd, cwd->DosPath.Length / sizeof(WCHAR), cwd->DosPath.Buffer);
301304
ffStrbufReplaceAllC(&platform->cwd, '\\', '/');
302305
ffStrbufEnsureEndsWithC(&platform->cwd, '/');
303306
}
304307

305308
void ffPlatformInitImpl(FFPlatform* platform)
306309
{
307-
static_assert(offsetof(TEB, Reserved1[8]) == sizeof(NT_TIB) + sizeof(PVOID) /*EnvironmentPointer*/, "Structure layout mismatch detected.");
308-
platform->pid = (uint32_t) (uintptr_t) ((CLIENT_ID*) &NtCurrentTeb()->Reserved1[8])->UniqueProcess;
310+
platform->pid = (uint32_t) (uintptr_t) ffGetTeb()->ClientId.UniqueProcess;
309311
getExePath(platform);
310312
getCwd(platform);
311313
getHomeDir(platform);

src/common/impl/io_windows.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
static bool createSubfolders(wchar_t* fileName)
1010
{
11-
HANDLE hRoot = ffGetProcessParams()->CurrentDirectory.Handle;
11+
HANDLE hRoot = ffGetPeb()->ProcessParameters->CurrentDirectory.Handle;
1212
bool closeRoot = false;
1313
wchar_t* ptr = fileName;
1414

@@ -69,7 +69,7 @@ static bool createSubfolders(wchar_t* fileName)
6969
// Rooted path on current drive: \foo\bar
7070
else if (ptr[0] == L'\\')
7171
{
72-
UNICODE_STRING* dosPath = &ffGetProcessParams()->CurrentDirectory.DosPath;
72+
UNICODE_STRING* dosPath = &ffGetPeb()->ProcessParameters->CurrentDirectory.DosPath;
7373
wchar_t driveRoot[] = { dosPath->Buffer[0], L':', L'\\', L'\0' };
7474
hRoot = CreateFileW(
7575
driveRoot,

src/common/impl/library.c

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
#include "fastfetch.h"
22
#include "common/library.h"
33

4+
#if _WIN32
5+
#include "common/debug.h"
6+
#include "common/windows/nt.h"
7+
#include <errno.h>
8+
#include <ntstatus.h>
9+
#endif
10+
411
#ifndef FF_DISABLE_DLOPEN
512

613
#include <stdarg.h>
@@ -36,7 +43,7 @@ static void* libraryLoad(const char* path, int maxVersion)
3643
if (pathLen == instance.state.platform.exePath.length)
3744
return result;
3845

39-
char absPath[MAX_PATH + 1];
46+
char absPath[MAX_PATH * 2];
4047
strcpy(mempcpy(absPath, instance.state.platform.exePath.chars, pathLen + 1), path);
4148
return dlopen(absPath, FF_DLOPEN_FLAGS);
4249

@@ -92,3 +99,81 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...)
9299
}
93100

94101
#endif
102+
103+
#if _WIN32
104+
105+
void* dlopen(const char* path, FF_MAYBE_UNUSED int mode)
106+
{
107+
wchar_t pathW[MAX_PATH + 1];
108+
ULONG pathWBytes = 0;
109+
110+
NTSTATUS status = RtlUTF8ToUnicodeN(pathW, sizeof(pathW), &pathWBytes, path, (uint32_t)strlen(path) + 1);
111+
if (!NT_SUCCESS(status))
112+
{
113+
FF_DEBUG("RtlUTF8ToUnicodeN failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
114+
return NULL;
115+
}
116+
117+
PVOID module = NULL;
118+
status = LdrLoadDll(NULL, NULL, &(UNICODE_STRING) {
119+
.Length = (USHORT) pathWBytes - sizeof(wchar_t), // Exclude null terminator
120+
.MaximumLength = (USHORT) pathWBytes,
121+
.Buffer = pathW,
122+
}, &module);
123+
124+
if (!NT_SUCCESS(status))
125+
{
126+
FF_DEBUG("LdrLoadDll failed for path %s with status 0x%08lX: %s", path, status, ffDebugNtStatus(status));
127+
return NULL;
128+
}
129+
130+
return module;
131+
}
132+
133+
int dlclose(void* handle)
134+
{
135+
NTSTATUS status = LdrUnloadDll(handle);
136+
if (!NT_SUCCESS(status))
137+
{
138+
FF_DEBUG("LdrUnloadDll failed for handle %p with status 0x%08lX: %s", handle, status, ffDebugNtStatus(status));
139+
return -1;
140+
}
141+
return 0;
142+
}
143+
144+
void* dlsym(void* handle, const char* symbol)
145+
{
146+
void* address;
147+
USHORT symbolBytes = (USHORT) strlen(symbol) + 1;
148+
NTSTATUS status = LdrGetProcedureAddress(handle, &(ANSI_STRING) {
149+
.Length = symbolBytes - sizeof(char),
150+
.MaximumLength = symbolBytes,
151+
.Buffer = (char*) symbol,
152+
}, 0, &address);
153+
if (!NT_SUCCESS(status))
154+
{
155+
FF_DEBUG("LdrGetProcedureAddress failed for symbol %s with status 0x%08lX: %s", symbol, status, ffDebugNtStatus(status));
156+
return NULL;
157+
}
158+
return address;
159+
}
160+
161+
void* ffLibraryGetModule(const wchar_t* libraryFileName)
162+
{
163+
assert(libraryFileName != NULL && "Use \"ffGetPeb()->ImageBaseAddress\" instead");
164+
165+
void* module = NULL;
166+
USHORT libraryFileNameBytes = (USHORT) (wcslen(libraryFileName) * sizeof(wchar_t)) + sizeof(wchar_t);
167+
NTSTATUS status = LdrGetDllHandle(NULL, NULL, &(UNICODE_STRING) {
168+
.Length = libraryFileNameBytes - sizeof(wchar_t),
169+
.MaximumLength = libraryFileNameBytes,
170+
.Buffer = (wchar_t*) libraryFileName,
171+
}, &module);
172+
if (!NT_SUCCESS(status))
173+
{
174+
FF_DEBUG("LdrGetDllHandle failed for library %ls with status 0x%08lX: %s", libraryFileName, status, ffDebugNtStatus(status));
175+
return NULL;
176+
}
177+
return module;
178+
}
179+
#endif

src/common/impl/networking_windows.c

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ static const char* initWsaData(WSADATA* wsaData)
2424
}
2525

2626
//Dummy socket needed for WSAIoctl
27-
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
27+
SOCKET sockfd = WSASocketW(AF_INET, SOCK_STREAM, 0, NULL, 0, 0);
2828
if(sockfd == INVALID_SOCKET) {
29-
FF_DEBUG("socket(AF_INET, SOCK_STREAM) failed");
29+
FF_DEBUG("WSASocketW(AF_INET, SOCK_STREAM) failed");
3030
WSACleanup();
31-
return "socket(AF_INET, SOCK_STREAM) failed";
31+
return "WSASocketW(AF_INET, SOCK_STREAM) failed";
3232
}
3333

3434
DWORD dwBytes;
3535
GUID guid = WSAID_CONNECTEX;
3636
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
37-
&guid, sizeof(guid),
38-
&ConnectEx, sizeof(ConnectEx),
39-
&dwBytes, NULL, NULL) != 0) {
37+
&guid, sizeof(guid),
38+
&ConnectEx, sizeof(ConnectEx),
39+
&dwBytes, NULL, NULL) != 0) {
4040
FF_DEBUG("WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER) failed");
4141
closesocket(sockfd);
4242
WSACleanup();
@@ -92,26 +92,33 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
9292
return "initWsaData() failed before";
9393
}
9494

95-
struct addrinfo* addr;
96-
struct addrinfo hints = {
95+
ADDRINFOW* addr;
96+
ADDRINFOW hints = {
97+
.ai_flags = AI_NUMERICSERV,
9798
.ai_family = state->ipv6 ? AF_INET6 : AF_INET,
9899
.ai_socktype = SOCK_STREAM,
99-
.ai_flags = AI_NUMERICSERV,
100100
};
101101

102+
wchar_t hostW[256];
103+
if (!NT_SUCCESS(RtlUTF8ToUnicodeN(hostW, (ULONG) sizeof(hostW), NULL, host, (ULONG) strlen(host) + 1)))
104+
{
105+
FF_DEBUG("Failed to convert host to wide string: %s", host);
106+
return "Failed to convert host to wide string";
107+
}
108+
102109
FF_DEBUG("Resolving address: %s (%s)", host, state->ipv6 ? "IPv6" : "IPv4");
103-
if(getaddrinfo(host, "80", &hints, &addr) != 0)
110+
if(GetAddrInfoW(hostW, L"80", &hints, &addr) != 0)
104111
{
105-
FF_DEBUG("getaddrinfo() failed");
106-
return "getaddrinfo() failed";
112+
FF_DEBUG("GetAddrInfoW() failed");
113+
return "GetAddrInfoW() failed";
107114
}
108115

109-
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
116+
state->sockfd = WSASocketW(addr->ai_family, addr->ai_socktype, addr->ai_protocol, NULL, 0, 0);
110117
if(state->sockfd == INVALID_SOCKET)
111118
{
112-
FF_DEBUG("socket() failed");
113-
freeaddrinfo(addr);
114-
return "socket() failed";
119+
FF_DEBUG("WSASocketW() failed");
120+
FreeAddrInfoW(addr);
121+
return "WSASocketW() failed";
115122
}
116123

117124
DWORD flag = 1;
@@ -143,7 +150,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
143150
{
144151
FF_DEBUG("bind() failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
145152
closesocket(state->sockfd);
146-
freeaddrinfo(addr);
153+
FreeAddrInfoW(addr);
147154
state->sockfd = INVALID_SOCKET;
148155
return "bind() failed";
149156
}
@@ -156,7 +163,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
156163
if (state->overlapped.hEvent == WSA_INVALID_EVENT) {
157164
FF_DEBUG("WSACreateEvent() failed");
158165
closesocket(state->sockfd);
159-
freeaddrinfo(addr);
166+
FreeAddrInfoW(addr);
160167
state->sockfd = INVALID_SOCKET;
161168
return "WSACreateEvent() failed";
162169
}
@@ -200,7 +207,7 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho
200207
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen,
201208
state->command.chars, state->command.length, &sent, &state->overlapped);
202209

203-
freeaddrinfo(addr);
210+
FreeAddrInfoW(addr);
204211
addr = NULL;
205212

206213
if(!result)
@@ -302,10 +309,14 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
302309
FF_DEBUG("Data reception loop #%d, current buffer size: %u, available space: %u",
303310
++recvCount, buffer->length, ffStrbufGetFree(buffer));
304311

305-
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
312+
DWORD received = 0, recvFlags = 0;
313+
int recvResult = WSARecv(state->sockfd, &(WSABUF) {
314+
.buf = buffer->chars + buffer->length,
315+
.len = (ULONG) ffStrbufGetFree(buffer),
316+
}, 1, &received, &recvFlags, NULL, NULL);
306317

307-
if (received <= 0) {
308-
if (received == 0) {
318+
if (recvResult == SOCKET_ERROR || received == 0) {
319+
if (recvResult == 0 && received == 0) {
309320
FF_DEBUG("Connection closed (received=0)");
310321
} else {
311322
FF_DEBUG("Reception failed: %s", ffDebugWin32Error((DWORD) WSAGetLastError()));
@@ -316,7 +327,7 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf
316327
buffer->length += (uint32_t) received;
317328
buffer->chars[buffer->length] = '\0';
318329

319-
FF_DEBUG("Successfully received %zd bytes of data, total: %u bytes", received, buffer->length);
330+
FF_DEBUG("Successfully received %u bytes of data, total: %u bytes", (unsigned) received, buffer->length);
320331

321332
// Check if HTTP header end marker is found
322333
if (headerEnd == 0) {

src/common/library.h

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
#ifndef FF_DISABLE_DLOPEN
77

88
#if defined(_WIN32)
9-
#include <libloaderapi.h>
109
#define FF_DLOPEN_FLAGS 0
11-
FF_C_NODISCARD static inline void* dlopen(const char* path, int mode) { FF_UNUSED(mode); return LoadLibraryA(path); }
12-
FF_C_NODISCARD static inline void* dlsym(void* handle, const char* symbol) { return (void*) GetProcAddress((HMODULE)handle, symbol); }
13-
static inline int dlclose(void* handle) { return !FreeLibrary((HMODULE)handle); }
10+
FF_C_NODISCARD void* dlopen(const char* path, int mode);
11+
FF_C_NODISCARD void* dlsym(void* handle, const char* symbol);
12+
int dlclose(void* handle);
1413
#else
1514
#include <dlfcn.h>
1615
#endif
@@ -30,6 +29,10 @@ static inline void ffLibraryUnload(void** handle)
3029
dlclose(*handle);
3130
}
3231

32+
#if __cplusplus
33+
#define __auto_type auto
34+
#endif
35+
3336
#define FF_LIBRARY_SYMBOL(symbolName) \
3437
__typeof__(&symbolName) ff ## symbolName;
3538

@@ -38,13 +41,8 @@ static inline void ffLibraryUnload(void** handle)
3841
if(libraryObjectName == NULL) \
3942
return returnValue;
4043

41-
#if _WIN32
42-
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
43-
FF_LIBRARY_LOAD(libraryObjectName, "LoadLibraryA(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
44-
#else
4544
#define FF_LIBRARY_LOAD_MESSAGE(libraryObjectName, libraryFileName, maxVersion, ...) \
4645
FF_LIBRARY_LOAD(libraryObjectName, "dlopen(" libraryFileName ") failed", libraryFileName, maxVersion, ##__VA_ARGS__)
47-
#endif
4846

4947
#define FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, symbolMapping, symbolName, returnValue) \
5048
symbolMapping = (__typeof__(&symbolName)) dlsym(library, #symbolName); \
@@ -106,3 +104,7 @@ void* ffLibraryLoad(const char* path, int maxVersion, ...);
106104
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(library, (varName)->ff ## symbolName, symbolName, returnValue);
107105

108106
#endif
107+
108+
#if _WIN32
109+
void* ffLibraryGetModule(const wchar_t* libraryFileName);
110+
#endif

src/common/windows/com.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ static const char* doInitCom()
1717
return "CoInitializeEx() failed";
1818

1919
// Set general COM security levels
20-
if (FAILED(CoInitializeSecurity(
20+
21+
HRESULT hRes = CoInitializeSecurity(
2122
NULL,
2223
-1, // COM authentication
2324
NULL, // Authentication services
@@ -27,7 +28,9 @@ static const char* doInitCom()
2728
NULL, // Authentication info
2829
EOAC_NONE, // Additional capabilities
2930
NULL // Reserved
30-
)))
31+
);
32+
33+
if (FAILED(hRes) && hRes != RPC_E_TOO_LATE /* Has been set by a random dll */)
3134
{
3235
CoUninitialize();
3336
return "CoInitializeSecurity() failed";

0 commit comments

Comments
 (0)