Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,45 @@ jobs:
shell: pwsh
run: work/thirdparty/tcc/build.ps1

- name: validate WinAPI declarations with x64 and i386 TCC
shell: pwsh
run: |
$probe = "work/thirdparty/tcc/tests/winapi_create_symbolic_link.c"
$x64Ansi = "$env:RUNNER_TEMP/winapi_create_symbolic_link_x64_ansi.exe"
$x64Unicode = "$env:RUNNER_TEMP/winapi_create_symbolic_link_x64_unicode.exe"
$i386Ansi = "$env:RUNNER_TEMP/winapi_create_symbolic_link_i386_ansi.exe"
$i386Unicode = "$env:RUNNER_TEMP/winapi_create_symbolic_link_i386_unicode.exe"

& work/thirdparty/tcc/tcc.exe `
-Werror=implicit-function-declaration `
-o $x64Ansi $probe
if ($LASTEXITCODE -ne 0) {
throw "x64 ANSI WinAPI conformance probe failed"
}

& work/thirdparty/tcc/tcc.exe `
-Werror=implicit-function-declaration `
-DUNICODE -D_UNICODE `
-o $x64Unicode $probe
if ($LASTEXITCODE -ne 0) {
throw "x64 Unicode WinAPI conformance probe failed"
}

& work/thirdparty/tcc/i386-win32-tcc.exe `
-Werror=implicit-function-declaration `
-o $i386Ansi $probe
if ($LASTEXITCODE -ne 0) {
throw "i386 ANSI WinAPI conformance probe failed"
}

& work/thirdparty/tcc/i386-win32-tcc.exe `
-Werror=implicit-function-declaration `
-DUNICODE -D_UNICODE `
-o $i386Unicode $probe
if ($LASTEXITCODE -ne 0) {
throw "i386 Unicode WinAPI conformance probe failed"
}

- name: run shared conformance tests
shell: pwsh
run: |
Expand Down
56 changes: 56 additions & 0 deletions 0003-win32-declare-CreateSymbolicLink.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
win32: declare and export CreateSymbolicLink APIs

CreateSymbolicLinkA/W and their flags are part of the Windows API from
_WIN32_WINNT 0x0600 onward. Add the missing declarations to winbase.h so
strict implicit-function-declaration diagnostics retain the correct Windows
calling convention, including on i386. Add the standard UNICODE/ANSI alias
beside CreateHardLink, and add the missing ANSI entry to kernel32.def so both
declared variants can be linked.

diff --git a/win32/include/winapi/winbase.h b/win32/include/winapi/winbase.h
--- a/win32/include/winapi/winbase.h
+++ b/win32/include/winapi/winbase.h
@@ -2252,7 +2252,8 @@
#define MoveFileEx MoveFileExW
#define MoveFileWithProgress MoveFileWithProgressW
#define ReplaceFile ReplaceFileW
#define CreateHardLink CreateHardLinkW
+#define CreateSymbolicLink CreateSymbolicLinkW
#define CreateNamedPipe CreateNamedPipeW
#define GetNamedPipeHandleState GetNamedPipeHandleStateW
#define CallNamedPipe CallNamedPipeW
@@ -2306,7 +2307,8 @@
#define MoveFileEx MoveFileExA
#define MoveFileWithProgress MoveFileWithProgressA
#define ReplaceFile ReplaceFileA
#define CreateHardLink CreateHardLinkA
+#define CreateSymbolicLink CreateSymbolicLinkA
#define CreateNamedPipe CreateNamedPipeA
#define GetNamedPipeHandleState GetNamedPipeHandleStateA
#define CallNamedPipe CallNamedPipeA
@@ -2384,6 +2386,12 @@
WINBASEAPI WINBOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,LPCWSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved);
WINBASEAPI WINBOOL WINAPI CreateHardLinkA(LPCSTR lpFileName,LPCSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
WINBASEAPI WINBOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName,LPCWSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
-
+#if _WIN32_WINNT >= 0x0600
+#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
+#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
+ WINBASEAPI BOOLEAN WINAPI CreateSymbolicLinkA(LPCSTR lpSymlinkFileName,LPCSTR lpTargetFileName,DWORD dwFlags);
+ WINBASEAPI BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR lpSymlinkFileName,LPCWSTR lpTargetFileName,DWORD dwFlags);
+#endif
+
typedef enum _STREAM_INFO_LEVELS {
FindStreamInfoStandard,FindStreamInfoMaxInfoLevel

diff --git a/win32/lib/kernel32.def b/win32/lib/kernel32.def
--- a/win32/lib/kernel32.def
+++ b/win32/lib/kernel32.def
@@ -87,5 +87,7 @@ CreateRemoteThread
CreateSemaphoreA
CreateSemaphoreW
CreateSocketHandle
+CreateSymbolicLinkA
+CreateSymbolicLinkW
CreateTapePartition
CreateThread
3 changes: 3 additions & 0 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if (-not (Test-Path (Join-Path $RepoRoot "vlib\v\compiler_errors_test.v"))) {
$TccBaseCommit = "d9d02c56401e43be43760b63f7d82f771a7ed1f6"
$TccPatch1 = Join-Path $PSScriptRoot "0001-tccpe-strip-quotes-and-default-.dll-extension-in-DEF.patch"
$TccPatch2 = Join-Path $PSScriptRoot "0002-win32-don-t-treat-DBG_PRINTEXCEPTION_C-as-a-fatal-cr.patch"
$TccPatch3 = Join-Path $PSScriptRoot "0003-win32-declare-CreateSymbolicLink.patch"
$GcPatch = Join-Path $PSScriptRoot "v-ae88ee5-tinycc-bdwgc.patch"
$OutDir = $PSScriptRoot

Expand All @@ -41,6 +42,8 @@ try {
if ($LASTEXITCODE -ne 0) { throw "$TccPatch1 failed to apply" }
git apply $TccPatch2
if ($LASTEXITCODE -ne 0) { throw "$TccPatch2 failed to apply" }
git apply $TccPatch3
if ($LASTEXITCODE -ne 0) { throw "$TccPatch3 failed to apply" }

Set-Location win32
& .\build-tcc.bat -clean
Expand Down
8 changes: 8 additions & 0 deletions include/winapi/winbase.h
Original file line number Diff line number Diff line change
Expand Up @@ -2253,6 +2253,7 @@ extern "C" {
#define MoveFileWithProgress MoveFileWithProgressW
#define ReplaceFile ReplaceFileW
#define CreateHardLink CreateHardLinkW
#define CreateSymbolicLink CreateSymbolicLinkW
#define CreateNamedPipe CreateNamedPipeW
#define GetNamedPipeHandleState GetNamedPipeHandleStateW
#define CallNamedPipe CallNamedPipeW
Expand Down Expand Up @@ -2307,6 +2308,7 @@ extern "C" {
#define MoveFileWithProgress MoveFileWithProgressA
#define ReplaceFile ReplaceFileA
#define CreateHardLink CreateHardLinkA
#define CreateSymbolicLink CreateSymbolicLinkA
#define CreateNamedPipe CreateNamedPipeA
#define GetNamedPipeHandleState GetNamedPipeHandleStateA
#define CallNamedPipe CallNamedPipeA
Expand Down Expand Up @@ -2384,6 +2386,12 @@ extern "C" {
WINBASEAPI WINBOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName,LPCWSTR lpReplacementFileName,LPCWSTR lpBackupFileName,DWORD dwReplaceFlags,LPVOID lpExclude,LPVOID lpReserved);
WINBASEAPI WINBOOL WINAPI CreateHardLinkA(LPCSTR lpFileName,LPCSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
WINBASEAPI WINBOOL WINAPI CreateHardLinkW(LPCWSTR lpFileName,LPCWSTR lpExistingFileName,LPSECURITY_ATTRIBUTES lpSecurityAttributes);
#if _WIN32_WINNT >= 0x0600
#define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x2
WINBASEAPI BOOLEAN WINAPI CreateSymbolicLinkA(LPCSTR lpSymlinkFileName,LPCSTR lpTargetFileName,DWORD dwFlags);
WINBASEAPI BOOLEAN WINAPI CreateSymbolicLinkW(LPCWSTR lpSymlinkFileName,LPCWSTR lpTargetFileName,DWORD dwFlags);
#endif

typedef enum _STREAM_INFO_LEVELS {
FindStreamInfoStandard,FindStreamInfoMaxInfoLevel
Expand Down
1 change: 1 addition & 0 deletions lib/kernel32.def
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ CreateRemoteThread
CreateSemaphoreA
CreateSemaphoreW
CreateSocketHandle
CreateSymbolicLinkA
CreateSymbolicLinkW
CreateTapePartition
CreateThread
Expand Down
15 changes: 15 additions & 0 deletions tests/winapi_create_symbolic_link.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#define WINVER 0x0600
#define _WIN32_WINNT 0x0600
#include <windows.h>
#include <tchar.h>

int main(void)
{
DWORD flags = SYMBOLIC_LINK_FLAG_DIRECTORY |
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
(void)CreateSymbolicLinkA("tccbin-probe-link-a", "tccbin-probe-target-a", flags);
(void)CreateSymbolicLinkW(L"tccbin-probe-link-w", L"tccbin-probe-target-w", flags);
(void)CreateSymbolicLink(TEXT("tccbin-probe-link"),
_T("tccbin-probe-target"), flags);
return 0;
}
Loading