Basic AMD64 System::Call support
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6444 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
a7261be70c
commit
a7076ff238
9 changed files with 268 additions and 46 deletions
|
@ -26,14 +26,25 @@ docs = Split("""
|
|||
|
||||
Import('BuildPlugin env')
|
||||
|
||||
if env['TARGET_ARCH'] != 'amd64':
|
||||
defs = ['SYSTEM_EXPORTS']
|
||||
msvc = 'msvc' in env['TOOLS'] or 'mstoolkit' in env['TOOLS']
|
||||
|
||||
if env['TARGET_ARCH'] != 'amd64' or msvc: # BUGBUG: Call-amd64.S is missing GAS macros
|
||||
srcsuff = ''
|
||||
if env['TARGET_ARCH'] != 'x86':
|
||||
srcsuff = '-' + env['TARGET_ARCH']
|
||||
defs += ['SYSTEM_NOCALLBACKS'] # BUGBUG: Remove this when CallBack() is implemented
|
||||
if msvc: # BUGBUG: Remove this when GAS is fixed
|
||||
defs += ['SYSTEM_PARTIALCALLSUPPORT']
|
||||
filename = 'Call' + srcsuff
|
||||
|
||||
conf = env.Configure()
|
||||
if conf.TryCompile('END', '.S'):
|
||||
files += ['Source/Call.S']
|
||||
files += ['Source/'+filename+'.S']
|
||||
elif conf.TryCompile('.end', '.sx'):
|
||||
files += ['Source/Call.sx']
|
||||
files += ['Source/'+filename+'.sx']
|
||||
else:
|
||||
print 'WARNING: System.dll: unable to find assembler for Call.S'
|
||||
print 'WARNING: System.dll: unable to find assembler for '+filename+'.S'
|
||||
conf.Finish()
|
||||
else:
|
||||
print 'WARNING: System.dll: missing Win64 code, dynamic function calls not supported'
|
||||
|
@ -45,7 +56,7 @@ BuildPlugin(
|
|||
examples,
|
||||
docs,
|
||||
nodeflib = False,
|
||||
defines = ['SYSTEM_EXPORTS']
|
||||
defines = defs
|
||||
)
|
||||
|
||||
res = 'Resource/Resource.rc'
|
||||
|
|
181
Contrib/System/Source/Call-amd64.S
Normal file
181
Contrib/System/Source/Call-amd64.S
Normal file
|
@ -0,0 +1,181 @@
|
|||
;#
|
||||
;# This file is a part of NSIS.
|
||||
;#
|
||||
;# Copyright (C) 2014 Anders Kjersem
|
||||
;#
|
||||
;# Licensed under the zlib/libpng license (the "License");
|
||||
;# you may not use this file except in compliance with the License.
|
||||
;#
|
||||
;# Licence details can be found in the file COPYING.
|
||||
;#
|
||||
;# This software is provided 'as-is', without any express or implied
|
||||
;# warranty.
|
||||
;#
|
||||
;#
|
||||
;# MASM:
|
||||
;# ml64.exe /c Call-amd64.S
|
||||
;#
|
||||
|
||||
; .if 0
|
||||
;# MASM
|
||||
|
||||
SECTION_DATA equ .data
|
||||
SECTION_CODE equ .code
|
||||
|
||||
FUNC_DECL MACRO name
|
||||
name PROC
|
||||
ENDM
|
||||
FUNC_END MACRO name
|
||||
name ENDP
|
||||
ENDM
|
||||
|
||||
;# ~MASM
|
||||
IF 0
|
||||
; .else
|
||||
;# GNU
|
||||
.intel_syntax noprefix
|
||||
|
||||
#define IFDEF .ifdef
|
||||
#define ELSE .else
|
||||
#define ENDIF .endif
|
||||
|
||||
#define SECTION_DATA .data
|
||||
#define SECTION_CODE .text
|
||||
|
||||
#define END .end
|
||||
#define EXTERN .extern
|
||||
|
||||
;# ~GNU
|
||||
ENDIF
|
||||
|
||||
|
||||
EXTERN __imp_GetLastError : PROC
|
||||
IFDEF SYSTEM_LOG_DEBUG
|
||||
EXTERN __imp_IsDebuggerPresent : PROC
|
||||
ENDIF
|
||||
|
||||
EXTERN LastError : DWORD
|
||||
|
||||
EXTERN GetProcOffset : PROC
|
||||
EXTERN GetParamsOffset : PROC
|
||||
EXTERN GetSizeOfProcParam : PROC
|
||||
EXTERN GetValueOffsetParam : PROC
|
||||
EXTERN SetProcResultOk : PROC
|
||||
EXTERN GetErrorOption : PROC
|
||||
|
||||
|
||||
SECTION_CODE
|
||||
|
||||
|
||||
FUNC_DECL CallProc2 ;# rcx=SystemProc* edx=ParamCount
|
||||
mov [rsp+8h], r12
|
||||
mov [rsp+10h], r13
|
||||
mov [rsp+18h], r14
|
||||
;#mov [rsp+20h], r15
|
||||
|
||||
;# The stack is unaligned on function entry. We have to calculate the required
|
||||
;# stack size for our parameters + maybe 8 padding bytes to end up 16 byte aligned.
|
||||
pSystemProc equ r14
|
||||
mov pSystemProc, rcx ;# Save SystemProc*
|
||||
;# Not required since we zero-extend eax: xor rax, rax
|
||||
mov r13d, edx ;# Save ParamCount
|
||||
imul eax, edx, 8
|
||||
and edx, 1
|
||||
jnz noparamalignpadding
|
||||
lea eax, [eax+8] ;# sizeof(params) + 8 will make us 16 byte aligned
|
||||
noparamalignpadding:
|
||||
cmp eax, 28h ;# The ABI guarantees shadow space for the 4 register parameters
|
||||
ja computedstacksize
|
||||
mov eax, 28h ;# Minimum (4*8) + 8 to align
|
||||
computedstacksize:
|
||||
mov r12d, eax ;# Save stack size (Zero-extended mov)
|
||||
sub rsp, r12
|
||||
|
||||
IFDEF SYSTEM_LOG_DEBUG
|
||||
;# BUGBUG: Remove this
|
||||
call qword ptr [__imp_IsDebuggerPresent]
|
||||
test eax, eax
|
||||
jz nodbgbrk
|
||||
int 3
|
||||
nodbgbrk:
|
||||
ENDIF
|
||||
|
||||
;# We are going to set all stack parameters including the first 4,
|
||||
;# it does not hurt to do that and it allows us to copy them to
|
||||
;# their registers without reading pSystemProc->Params[1..3] again
|
||||
call GetSizeOfProcParam
|
||||
mov r9, rax ;# Store sizeof(ProcParameter)
|
||||
call GetValueOffsetParam
|
||||
mov r8, rax ;# Store FIELD_OFFSET(ProcParameter,Value)
|
||||
call GetParamsOffset
|
||||
lea r10, [pSystemProc+rax] ;# Store pSystemProc+FIELD_OFFSET(SystemProc,Params)
|
||||
mov ecx, r13d ;# Zero-extended mov
|
||||
test rcx, rcx
|
||||
jz callthefunc
|
||||
setparameter:
|
||||
mov rax, r9
|
||||
mul rcx ;# rax = sizeof(ProcParameter) * paramidx (paramidx is 1 based because the return value is stored in Params[0])
|
||||
add rax, r10 ;# rax += pSystemProc->Params
|
||||
mov rax, qword ptr [rax+r8] ;# rax = pSystemProc->Params[paramidx].Value
|
||||
dec rcx
|
||||
mov [rsp+(8*rcx)], rax
|
||||
inc rcx
|
||||
loop setparameter
|
||||
;# The 4 parameter registers are all volatile so we might as well assign all of them:
|
||||
;# setparam4:
|
||||
;# cmp r13d, 4
|
||||
;# jb setparam3
|
||||
mov r9, [rsp+(8*3)]
|
||||
;# setparam3:
|
||||
;# cmp r13d, 3
|
||||
;# jb setparam2
|
||||
mov r8, [rsp+(8*2)]
|
||||
;# setparam2:
|
||||
;# cmp r13d, 2
|
||||
;# jb setparam1
|
||||
mov rdx, [rsp+(8*1)]
|
||||
;# setparam1:
|
||||
;# cmp r13d, 1
|
||||
;# jb callthefunc
|
||||
mov rcx, [rsp+(8*0)]
|
||||
|
||||
callthefunc:
|
||||
call GetProcOffset
|
||||
mov r10, qword ptr [pSystemProc+rax]
|
||||
xor rax, rax ;# Fix bug #1535007
|
||||
call r10
|
||||
mov r13, rax ;# Save return value
|
||||
|
||||
mov rcx, pSystemProc
|
||||
call GetErrorOption
|
||||
test eax, eax
|
||||
jz capturegle_done
|
||||
call qword ptr [__imp_GetLastError]
|
||||
mov dword ptr [LastError], eax
|
||||
capturegle_done:
|
||||
|
||||
;# proc->Params[0].Value = pSystemProc->Proc's return value
|
||||
call GetParamsOffset
|
||||
mov rdx, rax ;# This assumes that the next function is not going to clobber rdx!
|
||||
call GetValueOffsetParam
|
||||
add rdx, rax
|
||||
mov qword ptr [pSystemProc+rdx], r13
|
||||
|
||||
mov rcx, pSystemProc
|
||||
call SetProcResultOk ;# BUGBUG: This is pointless, system.c should just assume we are OK
|
||||
|
||||
mov rax, pSystemProc ;# Return SystemProc*
|
||||
;# Epilog:
|
||||
;# http://msdn.microsoft.com/en-us/library/tawsa7cb claims that only
|
||||
;# add/lea rsp and pop is valid in the epilog. Unwind might fail on our version?
|
||||
add rsp, r12 ;# Restore stack
|
||||
;# Restore nonvolatile registers:
|
||||
mov r12, [rsp+8h]
|
||||
mov r13, [rsp+10h]
|
||||
mov r14, [rsp+18h]
|
||||
;#mov r15, [rsp+20h]
|
||||
ret
|
||||
FUNC_END CallProc2
|
||||
|
||||
|
||||
END
|
|
@ -275,6 +275,7 @@ TODO: CallProc/Back not implemeted.
|
|||
Fake the behavior of the System plugin for the LoadImage API function so MUI works.
|
||||
BUGBUG: MUI is leaking DeleteObject and failing GetClientRect
|
||||
*/
|
||||
#ifndef SYSTEM_PARTIALCALLSUPPORT
|
||||
SystemProc* CallProc(SystemProc *proc)
|
||||
{
|
||||
INT_PTR ret, *place;
|
||||
|
@ -294,12 +295,13 @@ SystemProc* CallProc(SystemProc *proc)
|
|||
if (place) *place = ret;
|
||||
return proc;
|
||||
}
|
||||
#endif // ~SYSTEM_PARTIALCALLSUPPORT
|
||||
SystemProc* CallBack(SystemProc *proc)
|
||||
{
|
||||
proc->ProcResult = PR_ERROR;
|
||||
return proc;
|
||||
}
|
||||
#endif
|
||||
#endif // ~_WIN64
|
||||
|
||||
|
||||
PLUGINFUNCTION(Call)
|
||||
|
@ -355,7 +357,7 @@ PLUGINFUNCTION(Call)
|
|||
proc->Params[0] = pp; // Restore old return param
|
||||
}
|
||||
else
|
||||
ParamsOut(proc);
|
||||
ParamsOut(proc);
|
||||
}
|
||||
|
||||
if (proc->ProcResult != PR_CALLBACK)
|
||||
|
@ -768,7 +770,9 @@ SystemProc *PrepareProc(BOOL NeedForCall)
|
|||
break;
|
||||
case _T('!'): temp = -temp; break;
|
||||
case _T('c'):
|
||||
#ifndef _WIN64
|
||||
temp2 = POPT_CDECL;
|
||||
#endif
|
||||
break;
|
||||
case _T('r'):
|
||||
temp2 = POPT_ALWRETURN;
|
||||
|
@ -993,16 +997,19 @@ void ParamsIn(SystemProc *proc)
|
|||
#ifdef SYSTEM_LOG_DEBUG
|
||||
{
|
||||
TCHAR buf[666];
|
||||
wsprintf(buf, _T("\t\t\tParam In %d: type %d value ")SYSFMT_HEXPTR _T(" value2 0x%08X"), i,
|
||||
par->Type, par->Value, par->_value);
|
||||
UINT32 hi32 = 0;
|
||||
#ifndef _WIN64
|
||||
hi32 = par->_value;
|
||||
#endif
|
||||
wsprintf(buf, _T("\t\t\tParam In %d:\tType=%d Value=")SYSFMT_HEXPTR _T(" hi32=0x%08X"), i,
|
||||
par->Type, par->Value, hi32);
|
||||
SYSTEM_LOG_ADD(buf);
|
||||
SYSTEM_LOG_POST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (i == 0) break;
|
||||
if (i == proc->ParamCount) i = 0;
|
||||
else i++;
|
||||
if (i == proc->ParamCount) i = 0; else i++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1101,7 +1108,7 @@ void ParamsOut(SystemProc *proc)
|
|||
#ifdef SYSTEM_LOG_DEBUG
|
||||
{
|
||||
TCHAR dbgbuf[99];
|
||||
wsprintf(dbgbuf, _T(") %d:\tType=%d Optn=%d Size=%d Data="),
|
||||
wsprintf(dbgbuf, _T(")\t%d:\tType=%d Optn=%d Size=%d Data="),
|
||||
i, proc->Params[i].Type, proc->Params[i].Option, proc->Params[i].Size);
|
||||
SYSTEM_LOG_ADD(dbgbuf);
|
||||
SYSTEM_LOG_ADD(realbuf);
|
||||
|
@ -1118,7 +1125,7 @@ void ParamsOut(SystemProc *proc)
|
|||
|
||||
HANDLE CreateCallback(SystemProc *cbproc)
|
||||
{
|
||||
#ifdef SYSTEM_X64
|
||||
#ifdef SYSTEM_AMD64
|
||||
return BUGBUG64(HANDLE) NULL;
|
||||
#else
|
||||
char *mem;
|
||||
|
@ -1285,7 +1292,7 @@ BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID lpReserved)
|
|||
#ifdef SYSTEM_X86
|
||||
retexpr[0] = (char) 0xC2;
|
||||
retexpr[2] = 0x00;
|
||||
#elif defined(SYSTEM_X64)
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
retexpr[0] = BUGBUG64(0);
|
||||
#else
|
||||
#error TODO
|
||||
|
@ -1329,9 +1336,9 @@ unsigned int GetErrorOption(SystemProc *proc)
|
|||
/*
|
||||
Returns offset for element Proc of SystemProc structure
|
||||
*/
|
||||
unsigned int GetProcOffset(void)
|
||||
UINT_PTR GetProcOffset(void)
|
||||
{
|
||||
return (unsigned int)(&(((SystemProc *)0)->Proc));
|
||||
return (UINT_PTR)(&(((SystemProc *)0)->Proc));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1369,15 +1376,15 @@ unsigned int GetParamCount(SystemProc *proc)
|
|||
/*
|
||||
Returns offset for element Params of SystemProc structure
|
||||
*/
|
||||
unsigned int GetParamsOffset(void)
|
||||
UINT_PTR GetParamsOffset(void)
|
||||
{
|
||||
return (unsigned int)(&(((SystemProc *)0)->Params));
|
||||
return (UINT_PTR)(&(((SystemProc *)0)->Params));
|
||||
}
|
||||
|
||||
/*
|
||||
Returns size of ProcParameter structure
|
||||
*/
|
||||
unsigned int GetSizeOfProcParam(void)
|
||||
UINT_PTR GetSizeOfProcParam(void)
|
||||
{
|
||||
return (sizeof(ProcParameter));
|
||||
}
|
||||
|
@ -1393,11 +1400,12 @@ unsigned int GetSizeOffsetParam(void)
|
|||
/*
|
||||
Returns offset for element Value of ProcParameter structure
|
||||
*/
|
||||
unsigned int GetValueOffsetParam(void)
|
||||
UINT_PTR GetValueOffsetParam(void)
|
||||
{
|
||||
return (unsigned int)(&(((ProcParameter *)0)->Value));
|
||||
return (UINT_PTR)(&(((ProcParameter *)0)->Value));
|
||||
}
|
||||
|
||||
#ifndef _WIN64
|
||||
/*
|
||||
Returns offset for element _value of ProcParameter structure
|
||||
*/
|
||||
|
@ -1405,6 +1413,7 @@ unsigned int Get_valueOffsetParam(void)
|
|||
{
|
||||
return (unsigned int)(&(((ProcParameter *)0)->_value));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Sets "CLONE" option
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
// This should probably be moved to platform.h at some point
|
||||
|
||||
#if defined(_M_X64) || defined(_M_AMD64) || defined(__amd64__)
|
||||
# define SYSTEM_X64
|
||||
# define SYSTEM_AMD64
|
||||
#elif defined(_M_IX86) || defined(__i386__) || defined(_X86_)
|
||||
# define SYSTEM_X86
|
||||
# define SYSTEM_X86
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
#define SYSFMT_HEXPTR _T("0x%016IX")
|
||||
# define SYSFMT_HEXPTR _T("0x%016IX")
|
||||
#else
|
||||
#define SYSFMT_HEXPTR _T("0x%08X")
|
||||
# define SYSFMT_HEXPTR _T("0x%08X")
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -25,9 +26,9 @@
|
|||
// defined with this macro as being exported.
|
||||
|
||||
#ifdef SYSTEM_EXPORTS
|
||||
#define SYSTEM_API __declspec(dllexport)
|
||||
# define SYSTEM_API __declspec(dllexport)
|
||||
#else
|
||||
#define SYSTEM_API __declspec(dllimport)
|
||||
# define SYSTEM_API __declspec(dllimport) // BUGBUG: This is a plugin, who is going to import the functions directly?
|
||||
#endif
|
||||
|
||||
#define NEW_STACK_SIZE 256*256
|
||||
|
@ -123,7 +124,7 @@ struct tag_CallbackThunk
|
|||
#pragma pack(pop)
|
||||
*/
|
||||
char asm_code[10];
|
||||
#elif defined(SYSTEM_X64)
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
char asm_code[BUGBUG64(1)]; // TODO: BUGBUG64
|
||||
#else
|
||||
#error "Asm thunk not implemeted for this architecture!"
|
||||
|
@ -135,7 +136,7 @@ struct tag_CallbackThunk
|
|||
// Free() only knows about pNext in CallbackThunk, it does not know anything about the assembly, that is where this helper comes in...
|
||||
#ifdef SYSTEM_X86
|
||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) ( (SystemProc*) *(unsigned int*) (((char*)(pCbT))+1) )
|
||||
#elif defined(SYSTEM_X64)
|
||||
#elif defined(SYSTEM_AMD64)
|
||||
# define GetAssociatedSysProcFromCallbackThunkPtr(pCbT) BUGBUG64(NULL)
|
||||
#else
|
||||
# error "GetAssociatedSysProcFromCallbackThunkPtr not defined for the current architecture!"
|
||||
|
@ -145,14 +146,23 @@ struct tag_CallbackThunk
|
|||
extern const int ParamSizeByType[]; // Size of every parameter type (*4 bytes)
|
||||
|
||||
extern HANDLE CreateCallback(SystemProc *cbproc);
|
||||
extern SystemProc *PrepareProc(BOOL NeedForCall);
|
||||
extern SystemProc* PrepareProc(BOOL NeedForCall);
|
||||
extern void ParamAllocate(SystemProc *proc);
|
||||
extern void ParamsDeAllocate(SystemProc *proc);
|
||||
extern void ParamsIn(SystemProc *proc);
|
||||
extern void ParamsOut(SystemProc *proc);
|
||||
extern SystemProc *CallProc(SystemProc *proc);
|
||||
extern SystemProc *CallBack(SystemProc *proc);
|
||||
extern SystemProc *RealCallBack();
|
||||
#ifdef SYSTEM_AMD64
|
||||
#ifdef SYSTEM_PARTIALCALLSUPPORT
|
||||
extern SystemProc* CallProc2(SystemProc *proc, UINT_PTR ParamCount);
|
||||
#define CallProc(p) CallProc2((p), (p)->ParamCount) // ParamCount is passed as a parameter so CallProc2 can determine the required stack size without a function call
|
||||
#endif
|
||||
#else // !SYSTEM_AMD64
|
||||
extern SystemProc* CallProc(SystemProc *proc);
|
||||
#endif // ~SYSTEM_AMD64
|
||||
#ifndef SYSTEM_NOCALLBACKS
|
||||
extern SystemProc* CallBack(SystemProc *proc);
|
||||
extern SystemProc* RealCallBack();
|
||||
#endif
|
||||
extern void CallStruct(SystemProc *proc);
|
||||
|
||||
#ifdef _UNICODE
|
||||
|
|
|
@ -422,7 +422,7 @@ System::Free $0
|
|||
<blockquote>
|
||||
<ul>
|
||||
<li>To find out the index of a member in a COM interface, you need to search for the definition of this COM interface in the header files that come with Visual C/C++ or the Platform SDK. Remember the index is zero based.</li>
|
||||
<li>If a function can't be found, an `A' will be appended to its name and it will be looked up again. This is done because a lot of Windows API functions have two versions, one for ANSI strings and one for Unicode strings. The ANSI version of the function is marked with `A' and the Unicode version is marked with `W'. For example: lstrcpyA and lstrcpyW.</li>
|
||||
<li>If a function can't be found or the <code>t</code> parameter type was used, an `A' or `W' will be appended to its name and it will be looked up again. This is done because a lot of Windows API functions have two versions, one for ANSI strings and one for Unicode strings. The ANSI version of the function is marked with `A' and the Unicode version is marked with `W'. For example: lstrcpyA and lstrcpyW.</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
|
||||
|
@ -436,7 +436,7 @@ System::Free $0
|
|||
</tr>
|
||||
<tr>
|
||||
<th>c</th>
|
||||
<td>cdecl calling convention (the stack restored by caller). By default stdcall calling convention is used (the stack restored by callee).</td>
|
||||
<td>cdecl calling convention (the stack restored by caller). By default stdcall calling convention is used on x86 (the stack restored by callee).</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -6,6 +6,12 @@ Released on ?, 2014
|
|||
|
||||
\S1{v3.0b0-rl} Release Notes
|
||||
|
||||
\S1{v3.0b0-cl} Changelog
|
||||
|
||||
\S2{} Major Changes
|
||||
|
||||
\b Basic AMD64 System::Call support
|
||||
|
||||
\S2{} Minor Changes
|
||||
|
||||
\b Added Int<32|64|Ptr><Op|Cmp[U]> helper macros to Util.nsh
|
||||
|
|
|
@ -45,7 +45,8 @@ defenv.Append(CPPDEFINES = [('NSISCALL', '$STDCALL')])
|
|||
|
||||
### asm
|
||||
|
||||
defenv.Append(ASFLAGS = ['/coff'])
|
||||
if 'x86' in defenv.get('TARGET_ARCH','x86'):
|
||||
defenv.Append(ASFLAGS = ['/coff']) # ML64 does not support /coff
|
||||
|
||||
### debug
|
||||
|
||||
|
|
|
@ -287,9 +287,10 @@ def generate(env):
|
|||
|
||||
|
||||
include_path, lib_path, exe_path, sdk_path = "", "", "", ""
|
||||
targ_arc = env.get('TARGET_ARCH', 'x86')
|
||||
|
||||
if os.environ.has_key('MSVC_USE_SCRIPT') and "None" == os.environ['MSVC_USE_SCRIPT']:
|
||||
for x in ['INCLUDE', 'LIB', 'PATH']: env['ENV'][x] = ""
|
||||
for x in ['INCLUDE', 'LIB', 'PATH', 'CL', 'LINK', 'ML']: env['ENV'][x] = ""
|
||||
if not env.WhereIs('cl', os.environ['PATH']):
|
||||
raise SCons.Errors.InternalError("CL not found in %s" % os.environ['PATH'])
|
||||
include_path = os.environ['INCLUDE']
|
||||
|
@ -309,8 +310,8 @@ def generate(env):
|
|||
env.PrependENVPath('INCLUDE', include_path)
|
||||
env.PrependENVPath('LIB', lib_path)
|
||||
env.PrependENVPath('PATH', exe_path)
|
||||
|
||||
env['ENV']['CPU'] = 'i386' # TODO: Check TARGET_ARCH for AMD64
|
||||
|
||||
env['ENV']['CPU'] = (targ_arc.upper(), 'i386')['x86' in targ_arc.lower()] # i386 or AMD64
|
||||
env['ENV']['TARGETOS'] = 'BOTH'
|
||||
env['ENV']['APPVER'] = '4.0'
|
||||
env['ENV']['MSSDK'] = sdk_path
|
||||
|
@ -319,7 +320,7 @@ def generate(env):
|
|||
env['ENV']['INETSDK'] = sdk_path
|
||||
env['ENV']['MSSDK'] = sdk_path
|
||||
env['ENV']['MSTOOLS'] = sdk_path
|
||||
|
||||
|
||||
env['CFILESUFFIX'] = '.c'
|
||||
env['CXXFILESUFFIX'] = '.cc'
|
||||
|
||||
|
@ -329,7 +330,10 @@ def generate(env):
|
|||
env['AR'] = '"' + sdk_path_AR + '"'
|
||||
env['ARFLAGS'] = SCons.Util.CLVar('/nologo')
|
||||
env['ARCOM'] = "${TEMPFILE('$AR $ARFLAGS /OUT:$TARGET $SOURCES')}"
|
||||
|
||||
|
||||
if 'AMD64' in targ_arc.upper():
|
||||
env['AS'] = 'ml64'
|
||||
|
||||
env['SHLINK'] = '$LINK'
|
||||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS /dll')
|
||||
env['_SHLINK_TARGETS'] = win32ShlinkTargets
|
||||
|
|
|
@ -1056,11 +1056,11 @@ static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
{
|
||||
BOOL (WINAPI *GDFSE)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER) =
|
||||
#ifdef _WIN64
|
||||
GetDiskFreeSpaceEx;
|
||||
GetDiskFreeSpaceEx;
|
||||
#else
|
||||
myGetProcAddress(MGA_GetDiskFreeSpaceEx);
|
||||
#endif
|
||||
myGetProcAddress(MGA_GetDiskFreeSpaceEx);
|
||||
if (GDFSE)
|
||||
#endif
|
||||
{
|
||||
ULARGE_INTEGER available64;
|
||||
ULARGE_INTEGER a, b;
|
||||
|
@ -1093,7 +1093,7 @@ static INT_PTR CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
}
|
||||
}
|
||||
|
||||
if (!available_set) // TODO: Can GetDiskFreeSpace succeed when ..Ex failed on x64?
|
||||
if (!available_set && sizeof(void*) <= 4)
|
||||
{
|
||||
DWORD spc, bps, fc, tc;
|
||||
TCHAR *root;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue