Log in

View Full Version : SysInfo plugin v0.1.2.9


Pages : 1 2 3 4 [5] 6

Groucho2004
30th April 2020, 13:56
v0.1.1.9
- Removed IsAvsNeo()

StainlessS
30th April 2020, 14:01
GG, so the new Script dll totally fixes the prob we were having, yes.

Groucho2004
30th April 2020, 14:03
GG, so the new Script dll totally fixes the prob we were having, yes.Good, thanks.

StainlessS
30th April 2020, 14:20
Works fine here too.
I've added another 'synthetic', AvsVersionNumberString() [gouged out of VersionString] eg "3.5.2.0", I post when I get back from the shop.

Groucho2004
30th April 2020, 14:49
Check it out:
https://www.youtube.com/watch?v=5g62jSVJaFI

StainlessS
30th April 2020, 17:21
Thank you for that, cheered me up no end.
He kinda makes George Dubya look good.

If the other guy is the 'sleepy guy in the basment', then dopey Donny gotta be the 'batty guy in the attic'.
Maybe a bit of Alzheimer's kicking in, no TV remote for him, and take that Bang Button out of his hand.

Groucho2004
30th April 2020, 17:27
maybe a bit of alzheimer's kicking in, no tv remote for him, and take that bang button out of his hand.:):):):) I really want to know the oranges of those transpants.

CrendKing
1st May 2020, 12:21
It would be nice if you could add the display refresh rate, which is useful when doing frame interpolation. You can get it either via GetDeviceCaps() with VREFRESH (https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps#VREFRESH) or EnumDisplaySettings() (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaysettingsa) (the latter returns everything you already return in one call, which could save a little bit of CPU cycles ;) ). Thanks.

Groucho2004
1st May 2020, 18:08
It would be nice if you could add the display refresh rate, which is useful when doing frame interpolation.Will do.

Groucho2004
1st May 2020, 21:28
Thank you for that, cheered me up no end.I wonder how Donny Dumba$$ would do in this (https://www.youtube.com/watch?v=kRh1zXFKC_o) test...

Groucho2004
1st May 2020, 21:44
https://www.youtube.com/watch?v=c4-jIkE5PQU

I have to say, she's kinda hot. Well picked Donny. I bet he's dying to introduce his tiny mushroom penis to her.

Groucho2004
1st May 2020, 21:49
Stainless, clean up your PM inbox.

StainlessS
1st May 2020, 22:03
I wonder how Donny Dumba$$ would do in this test...
I suspect not as well as the young lad at the end.

I bet he's dying to ...
I'm guessin' already has.

Will do.
I think Emulgator, asked for info on secondary, ternary etc displays.

On the synthesized AvsVersionNumberString from VersionString

# Return length of string S that matches any character in Chars set of characters [Default case insignificant]. # StrMatchChrLen("1234.567abcd","0123456789.") = 8
Function StrMatchChrLen(String s,String Chars,Bool "Sig") {
Function __StrMatchChrLen_LOW(String s,String Chars,int n) { c=s.MidStr(n+1,1) Return(c==""||Chars.FindStr(c)==0) ? n : s.__StrMatchChrLen_LOW(Chars,n+1) }
Sig=Default(Sig,False) # Default Case Insignificant
s=(Sig)?s:s.UCASE Chars=(Sig)?Chars:Chars.UCASE
__StrMatchChrLen_LOW(s,Chars,0)
}
# Return length of string s that DOES NOT match any character in Chars set of characters [Default case insignificant]. # StrBrkChrLen("1234.567,abcd",",.") = 4
# If 1st character of s matches any in Chars set, then returns 0. # StrBrkChrLen("1234.567,abcd","321") = 0
# If no characters in s match any character in Chars set, then returns length of string s. # StrBrkChrLen("1234.567,abcd","NOP") = 13
Function StrBrkChrLen(String s,String Chars,Bool "Sig") {
Function __StrBrkChrLen_LOW(String s,String Chars,int n) {c=s.MidStr(n+1,1) Return(c==""||Chars.FindStr(c)!=0)?n:s.__StrBrkChrLen_LOW(Chars,n+1)}
Sig=Default(Sig,False) # Default Case Insignificant
s=(Sig)?s:s.UCASE Chars=(Sig)?Chars:Chars.UCASE
__StrBrkChrLen_LOW(s,Chars,0)
}
Function AvsVersionNumberString() { # Version string from VersionString, guaranteed 4 dot separated digits, "1.23" becomes "1.23.0.0"
s=VersionString ND="0123456789." s=s.MidStr(s.StrBrkChrLen(ND,True)+1) s=s.LeftStr(s.StrMatchChrLen(ND,True))
d=s.FindStr(".") n1=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n2=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n3=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n4=(d==0)?s:s.LeftStr(d-1)
(n1==""?"0":n1)+"."+(n2==""?"0":n2)+"."+(n3==""?"0":n3)+"."+(n4==""?"0":n4)
}


It dont work well for v2.58 or v2.60. [fine for v3.x.x.x, I think]

(from memory)
v2.58 has ProductVersion '2.5.8.0", v2.60 has "2.6.0.6", but AvsVersionNumberString
produces '2.58.0.0' and '2.60.0.0"
So I'm just gonna not bother with that.

EDIT:
clean up your PM inbox.
Made a little space.

Groucho2004
1st May 2020, 22:08
I think Emulgator, asked for info on secondary, ternary etc displays.I'll stay away from that for now (until I gathered more info).

Groucho2004
1st May 2020, 22:11
v2.58 has ProductVersion '2.5.8.0"It's 2.5.8.5

but AvsVersionNumberString
produces '2.58.0.0' and '2.60.0.0"
Just cut the last (4th) digit from AI_ProductVersion.

StainlessS
1st May 2020, 22:17
Presumably, thats the beta, maybe best keep it and publish final ProductVersion numbers.
think 2.6.0.0 was first beta ie Alpha 1, Alpha4=2.6.0.3, then there were at least one RC1 type whatsit, maybe 2.

so matching for 2.6.0.0 would see 2.6 any alpha as 2.6, but better scriptors using 2.6.0.6 would get exactly what they want.

Maybe.

EDIT: For RT_Stats version thing, I kludge it so that eg v2.0Beta x, is always slightly less than 2.0, 1.9999xxx [EDIT: = 2.0 beta xxx, ?.??zz+0.01 is version excluding Beta when zz==99]
so that simple compare with eg version float number 2.0 never gets it wrong when requiring v2.0 non beta.
[EDIT: RT_Stats version string still shows correct v2.0xxx beta version though.]
EDIT: I have not as yet extended that 'slightly less than 2' to the ProductVersion though, got to think bout that for a while.
[I have to do it by hand in 2 places, resource and internal version number]

EDIT:Think I probably got it wrong above, probably single '9' is beta flag, not double '99'.

pinterf
2nd May 2020, 06:26
BTW, how do I figure out which filter mode to register? I see you used NICE_FILTER for GrunT. Any advice?

If the filter's GetFame is fully reentrant, and does not use common, preallocated buffers or variables or internal caches, program states that are dinamically modified during GetFrames in an MT scenario then is can be NICE.

Groucho2004
2nd May 2020, 13:11
If the filter's GetFame is fully reentrant, and does not use common, preallocated buffers or variables or internal caches, program states that are dinamically modified during GetFrames in an MT scenario then is can be NICE.Thanks! GScript has some home brew cache mechanism so I don't think registering NICE is safe.

Groucho2004
2nd May 2020, 13:33
v0.1.2.0
- Added SI_ScreenVRefresh()

CrendKing
2nd May 2020, 15:23
v0.1.2.0
- Added SI_ScreenVRefresh()

Thank you for the prompt fix!

Groucho2004
3rd May 2020, 14:42
v0.1.2.1

Added AI_InternalFunctionExists, AI_ExternalFunctionExists and AI_FunctionExists
Removed AI_GScriptExists(). Use "AI_ExternalFunctionExists("gscript")" instead

Check first post of this thread for details.

StainlessS
3rd May 2020, 15:12
Small bug, AI_GScriptExists() seems to have gone AWOL. Everything seems fine in 121.

EDIT: It does not appear in the list of external functions generated by my RT_stats external functionlist thing. [maybe commented out/disappeared in AddFunction section].
EDIT: Oops, did not see that was removed, sorry for the bum steer.

EDIT: I notice that you made edit after my initial post above, did you miss out the GScriptExists line,
is that how I did not see it or am I really goin' doolally ?

Groucho2004
3rd May 2020, 22:22
EDIT: I notice that you made edit after my initial post above, did you miss out the GScriptExists line,
is that how I did not see it or am I really goin' doolally ?I did make that edit. Relax, your cheese hasn't slipped off of your cracker (yet). :)

StainlessS
4th May 2020, 22:33
Respectful request:

Any chance of implementing path to current Avisynth.dll, if that is possible ?
Last Modification time would also be useful [ie when compiled/linked] as opposed to Creation time [which could be when file was copied or extracted from zip, to somewhere].

I can do mod time in RT_, but not path to dll.

If you are bored and nuttin' to do, please :)

EDIT: From RT_


AVSValue __cdecl RT_GetFileTime(AVSValue args, void* user_data, IScriptEnvironment* env) {
char * myName="RT_GetFileTime: ";
const char *fn=args[0].AsString();
const int item = args[1].AsInt();
if(item <0 || item > 2) {
env->ThrowError("%sError invalid time item int %d(0 -> 2)",myName,item);
}
SetLastError(ERROR_SUCCESS);

HANDLE hFile = CreateFile(
fn, // Filename
0, // An application can query device attributes without accessing the device.
FILE_SHARE_READ, // Subsequent open operations on the object will succeed only if read access is requested.
NULL, // If lpSecurityAttributes is NULL, the handle cannot be inherited.
OPEN_EXISTING, // Opens the file. The function fails if the file does not exist.
0, // File attrubtes, Anything
NULL // No template file
);
if (hFile == INVALID_HANDLE_VALUE) {
env->ThrowError("%sError cannot open file '%s': %s",myName,fn,GetErrorString());
}

FILETIME ft = { 0 };
SYSTEMTIME st = { 0 };

LPFILETIME ct = (item==0) ? &ft : NULL;
LPFILETIME wt = (item==1) ? &ft : NULL;
LPFILETIME at = (item==2) ? &ft : NULL;

BOOL ok = GetFileTime(hFile, ct, at, wt);

CloseHandle(hFile);

if(!ok)
env->ThrowError("%sError Cannot get file time (%s : %s) ",myName,fn,GetErrorString());

int ret=FileTimeToSystemTime(&ft, &st);
if(ret==0)
env->ThrowError("%sError Cannot convert to SystemTime (%s : %s) ",myName,fn,GetErrorString());

char bf[64];
sprintf(bf,"%4d-%02d-%02d %02d:%02d:%02d.%03d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
return env->SaveString(bf);
}


EDIT:

env->AddFunction("RT_GetFileTime", "si",RT_GetFileTime, 0);



RT_GetFileTime(string filename,int item)
Returns string, one of three times associated with filename file.
Error if cannot access file. (debugview for error string).
Item, int, (0 -> 2). 0=Creation Time, 1=Last Write/Modified Time 2=Last Accessed Time,
The return string is always of format "YYYY-MM-DD HH:MM:SS.mmm" and so can be used to
compare whether one file time is later than another using string comparison.
The time strings returned are in UTC (Coordinated Universal Time), not local time.
v1.28Beta5, added milliseconds to string.
Prior to use, you can check if file exists using built-in Exist() function.


EDIT: I can access Avisynth.dll file mod time via script from within avs using above code, so no probs being in-use or whatever.

Groucho2004
4th May 2020, 22:44
Any chance of implementing path to current Avisynth.dll, if that is possible ?
Last Modification time would also be useful [ie when compiled/linked] as opposed to Creation time [which could be when file was copied or extracted from zip, to somewhere].Will do.

StainlessS
4th May 2020, 22:45
Ooh lovely.

EDIT:
Re-post my edit from prev post.
I can access Avisynth.dll file mod time via script from within avs [EDIT: using explicit path] using above code, so no probs being in-use or whatever.

Groucho2004
5th May 2020, 12:38
v0.1.2.2
- Added AI_AvsDLLPath
- Added AI_AvsDLLTimeStamp

See first post for details.

Groucho2004
5th May 2020, 19:08
Stainless:
Is there any point in adding a function listing the path to the plugin directory/directories that are referenced in the registry (the same way AVSMeter does)?

StainlessS
5th May 2020, 19:21
RT_ returns single plugin directory, not sure if it now still works in avs+, (think it stopped working, at least for some ver$ of Avs+).
I could show plugin directories in the AvsInit thingy, addional info aint a bad thing, but not sure how much use.
Strike, that, yes could potentially be of use in avsInit whotsit, just not sure how yet, ie in the user dll/avs/avsi directory load stuff,
maybe to see what other dll's will have already been loaded, and avoid re-load from MACHINE subdirectory.

So, yes please.

Groucho2004
5th May 2020, 20:24
v0.1.2.3
- Added AI_AutoLoadPath

As usual, see first post for details.

Groucho2004
5th May 2020, 20:54
Stainless, some testing of these last features please when you have time. :thanks:

StainlessS
5th May 2020, 22:13
Yep, testing now. [I'm trying to do at least 3 things at once]
Dont know about "n/a" Not available path to plugins being "n/a", possible cause of problems if someone actually tries to use it as a path.
Perhaps empty string to indicate not available. (original builin Plugin dir returned "" on problem, I think).

https://i.postimg.cc/gXMc0S6V/SI-CHECK-02.jpg (https://postimg.cc/gXMc0S6V)

I could cope with it either way, your choice [of course].

EDIT: Any info display thing could easily mod to "n/a" at display time.

Groucho2004
5th May 2020, 22:29
Dont know about "n/a" Not available path to plugins being "n/a", possible cause of problems if someone actually tries to use it as a path.
Perhaps empty string to indicate not available. (original builin Plugin dir returned "" on problem, I think).Well, you're the scripting wizard, just pick an option.

StainlessS
5th May 2020, 22:37
OK, thank you, "" would be preferable.

(original builin Plugin dir returned "" on problem, I think)
Forgot how it works, RT_ actually gets it from "$PluginDir$" secret variable, and is "" on current Avs+, so it dont work now for RT_ on Avs+.
I'll havta glean it from current Avs+ source code.

Groucho2004
5th May 2020, 22:39
OK, thank you, "" would be preferable.Okay.

StainlessS
5th May 2020, 22:44
Here's what I got right now, not prepped for publication or anything.


#return version
# SI_CHECK.avs

SI_VER = 0.123 # Minimum required version of SysInfo

/*
Req SysInfo (c) Groucho2004, RT_Stats 1.43+.
*/

########### CONFIG ##############

ERR_LEVEL=0 # 0 = Everything : 1 == WARNINGS+ : 2 ERRORS ONLY
W = 1440
H = 810


#################################################################
Function SystemInfoVersion() { try{v=SysInfoVersion}catch(msg){v=-1.0} v } # v = -1.0, SysInfo not installed
Function RT_StatsVersion() { try{v=RT_Version}catch(msg){v=-1.0} v } # v = -1.0, RT_Stats not installed
Function GScriptExists() { ret=false try{ GScript(123,42.0,false,"") } catch(msg){ret = FindStr(msg,"Invalid arguments")>=1 } Return ret }
Function FuncNameExists(String Fn) { Try{Eval(Fn+"()")B=True}catch(e){Assert(e.FindStr("syntax")==0,"FuncNameExists: Error in Function Name '"+Fn+"'")B=(e.FindStr("no function named")==0)}Return B}
#
Function IsAvs26() { VersionNumber>=2.6 }
Function IsAvsPlus() { FindStr(VersionString,"AviSynth+")!=0||FindStr(VersionString," Neo")!=0 }
Function PlusBuildNumber() { V=VersionString Off=(!IsAvsPlus)?-1:FindStr(V,"(r") Return (Off==0)?-1:V.MidStr(Off+2).Value.Int } # -1 not present. Avs+ & Neo, (More than 4 digits, Max 24 bit, ~16M)
Function AvsPlusVersionNumber() { PlusBuildNumber } # Stub for AvsPlusBuildNumber(), suggest AvsPlusVersionNumber is deprecated.

###

# Return extent of string S [ie length from the beginning] that matches any character in Chars set of characters [Default case insignificant]. # StrMatchChrLen("1234.567abcd","0123456789.") = 8
Function StrMatchChrLen(String s,String Chars,Bool "Sig") {
Function __StrMatchChrLen_LOW(String s,String Chars,int n) { c=s.MidStr(n+1,1) Return(c==""||Chars.FindStr(c)==0) ? n : s.__StrMatchChrLen_LOW(Chars,n+1) }
Sig=Default(Sig,False) # Default Case Insignificant
s=(Sig)?s:s.UCASE Chars=(Sig)?Chars:Chars.UCASE
__StrMatchChrLen_LOW(s,Chars,0)
}

# Return extent of string S [ie length from the beginning] that DOES NOT match any character in Chars set of characters [Default case insignificant].
# # StrBrkChrLen("1234.567,abcd",",.") = 4
# If 1st character of s matches any in Chars set, then returns 0. # StrBrkChrLen("1234.567,abcd","321") = 0
# If no characters in s match any character in Chars set, then returns length of string s. # StrBrkChrLen("1234.567,abcd","NOP") = 13
Function StrBrkChrLen(String s,String Chars,Bool "Sig") {
Function __StrBrkChrLen_LOW(String s,String Chars,int n) {c=s.MidStr(n+1,1) Return(c==""||Chars.FindStr(c)!=0)?n:s.__StrBrkChrLen_LOW(Chars,n+1)}
Sig=Default(Sig,False) # Default Case Insignificant
s=(Sig)?s:s.UCASE Chars=(Sig)?Chars:Chars.UCASE
__StrBrkChrLen_LOW(s,Chars,0)
}

Function AvsVersionNumberString(Int "Type") {
/*
Returns a version string guaranteed 4 dot separated number parts, eg "3.5.2" would return "3.5.2.0"
Type = Default 0. : Range -1, or 0, or 1, Source TYPE for Version, ie where to obtain source version string.
-1 = RAW VersionString, eg from "AviSynth 2.58, build:Dec 22 2008 [08:46:51]" would return "2.58" with ".0.0" appended, ie "2.58.0.0".
0 = VersionString with KLUDGE eg "2.58" -> "2.5.8.0" (Default) :: Kludge, If Parts 3 & 4 both "" and StrLen(Part2) > 1 Then Shift single digit into part3
1 = SysInfo:AI_AvsProductVersion eg "2.5.8.5" [As shown in Avisynth.dll file Properties dialog box] ::: Requires Groucho SysInfo.
*/
myName="AvsVersionNumberString: "
Type=Default(Type,0) # Default is version number from VersionString
Assert(-1 <= Type <= 1,myName+"0 <= Type <= 1 ("+String(Type,"%.f")+")")
Assert(Type<1 || SystemInfoVersion>=0.121,myName+"Groucho2004 SysInfo v0.121+ required")
s = (Type<=0) ? VersionString : AI_AvsProductVersion
s = (Type<=0) ? s.MidStr(s.StrBrkChrLen("0123456789.",True)+1) : s
s = (Type<=0) ? s.LeftStr(s.StrMatchChrLen("0123456789.",True)) : s
d=s.FindStr(".") n1=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n2=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n3=(d==0)?s:s.LeftStr(d-1) s=(d==0)?"":s.MidStr(d+1)
d=s.FindStr(".") n4=(d==0)?s:s.LeftStr(d-1)
# KLUDGE: If Type==0 and Parts 3 & 4 both "" and StrLen(Part2) > 1 Then Shift single digit into part3
Shift1=(Type==0) && (n3==""&&n4=="") && (n2.StrLen>1)
n3=(Shift1)?n2.RightStr(1):n3
n2=(Shift1)?n2.LeftStr(n2.StrLen-1):n2
# END KLUDGE
(n1==""?"0":n1) + "." + (n2==""?"0":n2) + "." + (n3==""?"0":n3) + "." + (n4==""?"0":n4)
}

Function AvsVersionNumberPartNo(int PartNo, Int "Type") {
/*
Return a single version Part Number as Int, Source version obtained from AvsVersionNumberString(type=Type). [where source is in 4 parts, eg "1.2.3.4"]
PartNo=1->4. 1=MAJOR version: 2=MINOR version : 3=Part3 version : 4=Part4 version
Type = Default 0. : Range -1, or 0, or 1, Source TYPE for Version, ie where to obtain source version string.
-1 = RAW VersionString, eg from "AviSynth 2.58, build:Dec 22 2008 [08:46:51]" would return "2.58" with ".0.0" appended, ie "2.58.0.0".
0 = VersionString with KLUDGE eg "2.58" -> "2.5.8.0" (Default) :: Kludge, If Parts 3 & 4 both "" and StrLen(Part2) > 1 Then Shift single digit into part3
1 = SysInfo:AI_AvsProductVersion eg "2.5.8.5" [As shown in Avisynth.dll file Properties dialog box] ::: Requires Groucho SysInfo.
*/
PartNo=Min(Max(PartNo,1),4) # Limit Range 1->4
s=AvsVersionNumberString(Type) # eg "1.2.3.4", guaranteed 4 dot separated digit strings.
d=s.FindStr(".") n1=s.LeftStr(d-1) s=s.MidStr(d+1) d=s.FindStr(".") n2=s.LeftStr(d-1) s=s.MidStr(d+1)
d=s.FindStr(".") n3=s.LeftStr(d-1) n4=s.MidStr(d+1)
Return ((PartNo==1)?n1:(PartNo==2)?n2:(PartNo==3)?n3:n4).Eval
}

Function IsAvsVerOrGreater(int a,int "b",int "c",int "d", Int "Type") {
/*
Test and return true if current version of avisynth is at least as high as your required minimum version part numbers.
eg IsAvsVerOrGreater(3,5,2,0,Type=1) returns true if Avisynth version by dll resource string(ie Type=1) is at least "3.5.2.0".
a,b,c and d, Your required minimum part numbers [b, c and d all default 0].
Type = Default 0. : Range -1, or 0, or 1, Source TYPE for Version, ie where to obtain source version string.
-1 = RAW VersionString, eg from "AviSynth 2.58, build:Dec 22 2008 [08:46:51]" would return "2.58" with ".0.0" appended, ie "2.58.0.0".
0 = VersionString with KLUDGE eg "2.58" -> "2.5.8.0" (Default) :: Kludge, If Parts 3 & 4 both "" and StrLen(Part2) > 1 Then Shift single digit into part3
1 = SysInfo:AI_AvsProductVersion eg "2.5.8.5" [As shown in Avisynth.dll file Properties dialog box] ::: Requires Groucho SysInfo.
*/
b=Default(b,0) c=Default(c,0) d=Default(d,0)
aa=AvsVersionNumberPartNo(1, Type) bb=AvsVersionNumberPartNo(2, Type)
cc=AvsVersionNumberPartNo(3, Type) dd=AvsVersionNumberPartNo(4, Type)
return (aa>a) || (aa==a && (bb>b || (bb==b && (cc>c || (cc==c && dd>=d)))))
}

#################################################################



Because I'm tryin' to get together a DBase of Version info, I've had to add something [Max() not implemented] for v2.57,
so it even works on that.


EDIT: PART 1 above, part 2 [glue together] next post.

StainlessS
5th May 2020, 22:44
Part 2


Function SystemEnvTemp() { SI_GetEnvVar("TEMP") } # Path to USER System environment TEMP folder
Function SystemEnvComSpec() { SI_GetEnvVar("COMSPEC") } # Path to Cmd.exe, eg "C:\Windows\system32\cmd.exe"
Function SystemEnvComputerName() { SI_GetEnvVar("COMPUTERNAME") } # System environment Commputer Name eg "Colossus"
Function SystemEnvUserName() { SI_GetEnvVar("USERNAME") } # System environment User Name eg "God".
Function IsAvs64Bit() { RT_GetSystemEnv("PROCESSOR_ARCHITECTURE").Findstr("64")!=0} # THIS is x86 for x86 proc on x64 OS
#
Function IsWinXP() { Findstr(SI_OSVersionString,"Windows XP")!=0}
Function IsWinVista() { Findstr(SI_OSVersionString,"Vista")!=0}
Function IsWin7() { Findstr(SI_OSVersionString,"Windows 7")!=0}
Function IsWin8() { S=SI_OSVersionString Findstr(S,"Windows 8 ")!=0||Findstr(S,"Windows 8.0 ")!=0}
Function IsWin81() { Findstr(SI_OSVersionString,"Windows 8.1")!=0}
Function IsWin10() { Findstr(SI_OSVersionString,"Windows 10")!=0}
#!
Function IsWinServer2003() { Findstr(SI_OSVersionString,"Server 2003")!=0}
Function IsWinServer2008() { S=SI_OSVersionString i=S.Findstr("Server 2008") i!=0&&(S.RT_Ord(i+11)==0||S.RT_Ord(i+11)==RT_Ord(","))}
Function IsWinServer2008R2() { Findstr(SI_OSVersionString,"Server 2008R2")!=0}
Function IsWinServer2012() { S=SI_OSVersionString i=S.Findstr("Server 2012") i!=0&&(S.RT_Ord(i+11)==0||S.RT_Ord(i+11)==RT_Ord(","))}
Function IsWinServer2012R2() { Findstr(SI_OSVersionString,"Server 2012R2")!=0}
#
Function HasMMX() { S=SI_CPUExtensions i=S.Findstr("MMX") i!=0&&(S.RT_Ord(i+3)==0||S.RT_Ord(i+3)==RT_Ord(","))}
Function HasSSE() { S=SI_CPUExtensions i=S.Findstr("SSE") i!=0&&(S.RT_Ord(i+3)==0||S.RT_Ord(i+3)==RT_Ord(","))}
Function HasSSE2() { Findstr(SI_CPUExtensions,"SSE2")!=0}
Function HasSSE3() { Findstr(SI_CPUExtensions,"SSE3")!=0}
Function HasSSSE3() { Findstr(SI_CPUExtensions,"SSSE3")!=0}
Function HasSSE41() { Findstr(SI_CPUExtensions,"SSE4.1")!=0}
Function HasSSE42() { Findstr(SI_CPUExtensions,"SSE4.2")!=0}
Function HasAVX() { S=SI_CPUExtensions i=S.Findstr("AVX") i!=0&&(S.RT_Ord(i+3)==0||S.RT_Ord(i+3)==RT_Ord(","))}
Function HasAVX2() { Findstr(SI_CPUExtensions,"AVX2")!=0}
Function HasAVX512() { Findstr(SI_CPUExtensions,"AVX512")!=0}
Function HasFMA3() { Findstr(SI_CPUExtensions,"FMA3")!=0}
Function HasFMA4() { Findstr(SI_CPUExtensions,"FMA4")!=0}
#
Function OsBuildNumber() { S=SI_OSVersionString i=S.Findstr("Build ") Return (i==0)?-1:S.MidStr(i+6).Value.Int } # -1 not present.

Function OSServicePack() { S=SI_OSVersionString i=S.Findstr("Service Pack ") Return (i==0)?-1:S.MidStr(i+13).Value } # -1 not present.
#
Function VariableTypeName(val v) { v.IsClip?"clip":v.IsInt?"int":v.Isfloat?"float":v.IsString?"string":v.IsBool?"bool":""}
Function IsNul(String S) { RT_Ord(S)== 0} # End of String
Function IsHash(String S) { RT_Ord(S)==35} # '#'
Function IsWhite(String s) { s.RT_Ord==32||(s.RT_Ord>=8&&s.RT_Ord<=13) }
Function EatWhite(String s) { s.IsWhite?s.MidStr(2).EatWhite:s }


########
CMPS="""
AI_AutoLoadPath("MACHINE_CLASSIC_PLUGINS") @ ?
AI_AutoLoadPath("USER_CLASSIC_PLUGINS") @ ?
AI_AutoLoadPath("MACHINE_PLUS_PLUGINS") @ ?
AI_AutoLoadPath("USER_PLUS_PLUGINS") @ ?
AI_AvsDLLPath @ ?
AI_AvsDLLTimeStamp @ ?
AI_AvsFileVersion @ AvsVersionNumberString
AI_AvsPlusBuildNumber @ PlusBuildNumber
AI_AvsProductVersion @ AvsVersionNumberString
AI_InternalFunctionExists("Sin") @ RT_FunctionExist("Sin")
AI_ExternalFunctionExists("Poop") @ RT_FunctionExist("Poop")
AI_FunctionExists("GScript") @ RT_FunctionExist("GScript")
AI_IsAvs26 @ VersionNumber>=2.6
AI_IsAvsPlus @ FindStr(VersionString,"AviSynth+")!=0||FindStr(VersionString," Neo")!=0
SI_AvailableSystemMemory @ ?
SI_CPUExtensions @ ?
SI_CPUName @ ?
SI_GetEnvVar("TEMP") @ RT_GetSystemEnv("TEMP")
SI_HasAVX @ HasAVX
SI_HasAVX2 @ HasAVX2
SI_HasAVX512 @ HasAVX512
SI_HasFMA3 @ HasFMA3
SI_HasFMA4 @ HasFMA4
SI_HasMMX @ HasMMX
SI_HasSSE @ HasSSE
SI_HasSSE2 @ HasSSE2
SI_HasSSE3 @ HasSSE3
SI_HasSSSE3 @ HasSSSE3
SI_HasSSE41 @ HasSSE41
SI_HasSSE42 @ HasSSE42
SI_IsOS64Bit @ ?
SI_IsWin10 @ IsWin10
SI_IsWin7 @ IsWin7
SI_IsWin8 @ IsWin8
SI_IsWin81 @ IsWin81
SI_IsWinServer2003 @ IsWinServer2003
SI_IsWinServer2008 @ IsWinServer2008
SI_IsWinServer2008R2 @ IsWinServer2008R2
SI_IsWinServer2012 @ IsWinServer2012
SI_IsWinServer2012R2 @ IsWinServer2012R2
SI_IsWinVista @ IsWinVista
SI_IsWinXP @ IsWinXP
SI_LogicalCores @ RT_GetSystemEnv("NUMBER_OF_PROCESSORS").Value.Int
SI_ModulePath @ ?
SI_NumberOfCPUs @ ?
SI_OSBuildNumber @ OsBuildNumber
SI_OSServicePack @ OSServicePack
SI_OSVersionNumber @ ?
SI_OSVersionString @ ?
SI_PhysicalCores @ ?
SI_ProcessBitness @ IsAvs64Bit?64:32
SI_ProcessName @ RT_GetProcessName(False)
SI_ScreenBitsPerPixel @ ?
SI_ScreenResX @ ?
SI_ScreenResY @ ?
SI_ScreenVRefresh() @ ?
SI_TotalSystemMemory @ ?
SysInfoVersion @ ?
"""

########

GSTRING = """
Lines = CMPS.RT_TxtQueryLines
for(i=0,Lines-1) {
testLine=CMPS.RT_TxtGetLine(Line=i).EatWhite.RevStr.EatWhite.RevStr
if(!testLine.IsNul && !testLine.IsHash) {
testS=testLine
HashLoc=testS.RT_FindStr("#")
testS=HashLoc>0?testS.LeftStr(HashLoc-1) : testS # End string at FIRST '#' Hash comment char
testS=testS.RevStr.EatWhite.RevStr # trim end White
AtLoc=testS.RT_FindStr("@")
Assert(AtLoc>0 ,RT_String("LINE %d, @ Separator Not Found : '%s'",i+1,testS))
LftS=TestS.LeftStr(AtLoc-1).RevStr.EatWhite.RevStr
Assert(LftS!="",RT_String("LINE %d, LHS SI string Not Found : '%s'",i+1,testS))
RgtS=TestS.MidStr(AtLoc+1).EatWhite
Assert(RgtS!="",RT_String("LINE %d, RHS Synthesized Func Not Found : '%s'",i+1,testS))
Try { LftResult = Eval(LftS) }
catch (msg) { Assert(False,"Error on Eval(LftS)"+Chr(10)+msg) }
LogStr=""
if(RgtS=="?") {
LogStr=RT_String("WARN: Synth Fn Not Impl: %s = '%s'",LftS,String(LftResult))
ERR=2
TOT_NI=TOT_NI+1
} Else {
Try { RgtResult = Eval(RgtS) }
catch (msg) { Assert(False,"Error on Eval(RgtS)"+Chr(10)+msg) }
mxlen=Max(LftS.StrLen,RgtS.StrLen)
if(LftResult.VariableTypeName==RgtResult.VariableTypeName) {
if(LftResult == RgtResult) {
LogStr=RT_String("OK: SAME RESULT\n %-*s = '%s'\n %-*s = '%s'",mxlen,LftS,String(LftResult),mxlen,RgtS,String(RgtResult))
ERR=1
TOT_OK=TOT_OK+1
} else if(LftS=="SI_ProcessName" && LftResult.RT_FileNameSplit(12)==RgtResult) {
LogStr=RT_String("OK: \a! * ABOUT\a- SAME RESULT\n %-*s = '%s'\n %-*s = '%s'",mxlen,LftS,String(LftResult),mxlen,RgtS,String(RgtResult))
ERR=1
TOT_OK=TOT_OK+1
} else {
LogStr=RT_String("BAD: \a!* NON Matched\a-\n %-*s = '%s'\n %-*s = '%s'",mxlen,LftS,String(LftResult),mxlen,RgtS,String(RgtResult))
ERR=3
TOT_BAD=TOT_BAD+1
}
} Else {
LogStr=RT_String("ERR: \a!* Incompatible Result Types\a-\n %-*s = '%s'\n %-*s = '%s'",mxlen,LftS,String(LftResult),mxlen,RgtS,String(RgtResult))
ERR=4
TOT_BAD=TOT_BAD+1
}
}
RT_DebugF("%s",LogStr,name="SI_CHECK: ")
if(ERR>ERR_LEVEL) {
SubsString=RT_String("%s\n%s",SubsString,LogStr)
}
}
}
HaveSubs=SubsString!=""
SubsString=RT_String("%s\n\n%2d OK\n",SubsString,TOT_OK)
SubsString=RT_String("%s%2d Not Implemented\n",SubsString,TOT_NI)
SubsString=RT_String("%s%2d BAD\n",SubsString,TOT_BAD)
If(HaveSubs) {
FndS=RT_String("\a!\n\a-\n")
RepS=RT_String("\n\n")
NoColorS=RT_StrReplaceMulti(SubsString,FndS,RepS) # Remove HiLite and Norm color codes for Writefile
RT_WriteFile(LOGNAME,"%s",NoColorS)
SubsString=RT_String("%s\nOutput Written to %s\n",SubsString,LOGNAME)
end=RT_String("\a1SysInfo\aC %c 2019-2020 %c \aEGroucho2004",137,137)
SubsString=RT_String("%s%s%*s\n",SubsString,RT_StrPad("",H/20,Chr(10)),(W/10+end.StrLen)/2,end)
}
"""
Assert(SysInfoVersion>=SI_VER,"SI_Check: Need Groucho2004 SysInfo v"+String(SI_VER))
Assert(RT_StatsVersion>=1.43,"SI_Check: Need RT_Stas v1.43+")
HasGScript=RT_FunctionExist("GScript")
IsPlus=IsAvsPlus
Assert(HasGScript||IsPlus,"SI_Check: Need either AVS+ or GScipt")
Assert(0 <= ERR_LEVEL <= 2,"SI_Check: 0 <= ERR_LEVEL <= 2")
(VersionNumber<2.58) ? GSCript(""" Function Max(val a,val b) { return a>b ? a : b } """) : NOP # Avs 2.57 max() not implemented

LOGNAME=RT_GetFullPathName(".\SysInfo_Check.Log")
RT_FileDelete(LOGNAME)
TOT_OK=0
TOT_NI=0
TOT_BAD=0
SubsString=""
(HasGScript) ? GScript(GSTRING) : Eval(GSTRING)

#################################################################

LINES=RT_TxtQueryLines(SubsString)
L=LINES * 20 + H
BlankClip(Width=W,Height=H,Length=L).ScriptClip("""RT_Subtitle("%s",SubsString,x=10,y=height-current_frame,expx=true,expy=true)""")
return Last

Groucho2004
5th May 2020, 22:54
Luvly

StainlessS
6th May 2020, 23:05
GG, you know any way to tell a non XP specific version Avisynth.dll ? [from inside script / plugin]

Done a DBase of 87 different versions Avs [done the lot twice, tedious],
now its occurred to me that XP (or NON XP) flag is probably warranted, I assumed that would be flagged in version string.

Similar for Array support, but I can do that with eg FunctionExist("IsArray") or similar.

Gotta try the whole dame lot again, hopefully with NON XP compatible & Array flags.

EDIT: Produced so far summick like this text output.

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| | | | | Version | Build | Ver$ | Ver$ | Ver$ |dll Product |dll File
IsNeo |IsPlus| Is26 | dll TimeStamp (UTC) | Version String | Number | Number | Ver No | Raw Dot4V |Kludge Dot4V| Dot4V | Dot4V
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0] F | F | F | 2006-12-31, 02:16:36 | "AviSynth 2.57, build:Dec 31 2006 [13:16:28]" | 2.57 | 0 | 2.57 | 2.57.0.0 | 2.5.7.0 | 2.5.7.0 | 2.5.7.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1] F | F | F | 2008-12-21, 21:46:54 | "AviSynth 2.58, build:Dec 22 2008 [08:46:51]" | 2.58 | 0 | 2.58 | 2.58.0.0 | 2.5.8.0 | 2.5.8.5 | 2.5.8.5
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2] F | F | T | 2011-05-25, 10:10:44 | "AviSynth 2.60, build:May 25 2011 [19:58:41]" | 2.6 | 0 | 2.60 | 2.60.0.0 | 2.6.0.0 | 2.6.0.2 | 2.6.0.2
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3] F | F | T | 2013-01-14, 05:50:40 | "AviSynth 2.60, build:Jan 14 2013 [16:50:35]" | 2.6 | 0 | 2.60 | 2.60.0.0 | 2.6.0.0 | 2.6.0.3 | 2.6.0.3
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4] F | F | T | 2013-04-25, 17:11:42 | "AviSynth 2.60 (CVS 20130425, ICL10)" | 2.6 | 0 | 2.60 | 2.60.0.0 | 2.6.0.0 | 2.6.0.3 | 2.6.0.3
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
79] F | T | T | 2020-04-02, 22:07:19 | "AviSynth+ 3.5 (r3106, 3.5, i386)" | 2.6 | 3106 | 3.5 | 3.5.0.0 | 3.5.0.0 | 3.5.0.0 | 3.5.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
80] F | T | T | 2020-04-02, 22:27:26 | "AviSynth+ 3.5 (r3106, 3.5, x86_64)" | 2.6 | 3106 | 3.5 | 3.5.0.0 | 3.5.0.0 | 3.5.0.0 | 3.5.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
81] F | T | T | 2020-04-28, 15:48:13 | "AviSynth+ 3.5.2 (r3218, neo, x86_64)" | 2.6 | 3218 | 3.5.2 | 3.5.2.0 | 3.5.2.0 | 3.5.2.0 | 3.5.2.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
82] F | T | T | 2020-04-28, 16:07:06 | "AviSynth+ 3.5.2 (r3218, neo, i386)" | 2.6 | 3218 | 3.5.2 | 3.5.2.0 | 3.5.2.0 | 3.5.2.0 | 3.5.2.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


83] T | T | T | 2018-11-18, 09:19:02 | "AviSynth Neo 0.1 (r2822, Neo, x86_64)" | 2.6 | 2822 | 0.1 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
84] T | T | T | 2018-11-18, 09:20:17 | "AviSynth Neo 0.1 (r2822, Neo, i386)" | 2.6 | 2822 | 0.1 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
85] T | T | T | 2019-06-26, 02:57:52 | "AviSynth Neo 0.1 (r2827, Neo, x86_64)" | 2.6 | 2827 | 0.1 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
86] T | T | T | 2019-06-26, 02:59:35 | "AviSynth Neo 0.1 (r2827, Neo, i386)" | 2.6 | 2827 | 0.1 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0 | 0.1.0.0
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Groucho2004
6th May 2020, 23:36
GG, you know any way to tell a non XP specific version Avisynth.dll ? [from inside script / plugin]No. I played a bit around with PE Explorer to see if there are differences in min req OS/imports/exports but to no avail.

StainlessS
6th May 2020, 23:40
OK, thanks anyway.

EDIT: I guess I can just create another DBase with extra field for Array support flag, and copy current Dbase fields to the new one.
EDIT: Guess I want file byte size too, gonna need do again.

Groucho2004
7th May 2020, 14:14
v0.1.2.4
- Added SI_UserName
- Updated libcpuid
- Refactoring

StainlessS
7th May 2020, 17:44
Thank, you :)

Little-un in the Tyrol:- https://metro.co.uk/2020/05/07/one-year-old-follows-siblings-expertly-snowboards-austrian-alps-12666039/

Make sure to wear the gum shield provided.

Groucho2004
7th May 2020, 17:53
Little-un in the Tyrol:- https://metro.co.uk/2020/05/07/one-year-old-follows-siblings-expertly-snowboards-austrian-alps-12666039/

Make sure to wear the gum shield provided.Awesome. The ski outfit in combination with the helmet and the silencer is priceless.

By the way, it's spelled "Tirol".

StainlessS
23rd May 2020, 13:27
bool AI_GScriptExists
Returns true if the GScript plugin is loaded

Nope, now gone. [remove it from doc]

Groucho2004
23rd May 2020, 13:36
Nope, now gone. [remove it from doc]Huh? :confused:

Edit - Oh, I see. Will do.

StainlessS
23rd May 2020, 13:44
To others, use one of the functions in blue instead of AI_GScriptExists().


bool AI_InternalFunctionExists(string "name")
Returns true if an internal function ("name") is available in the current environment

bool AI_ExternalFunctionExists(string "name")
Returns true if an external function ("name") is available in the current environment

bool AI_FunctionExists(string "name")
Returns true if an internal or external function ("name") is available in the current environment

eg, AI_FunctionExists("Gscript")

EDIT: or eg
Function GScriptExists() { Return AI_FunctionExists("Gscript") }

Groucho2004
27th May 2020, 20:55
v0.1.2.5
- Updated libcpuid
- Fixed a version resource issue
- Updated AVS headers

Groucho2004
11th August 2020, 15:34
v0.1.2.6
- Added SI_GetLogicalDrives()
- Added SI_GetLogicalDriveTotalSize("drive_letter")
- Added SI_GetLogicalDriveFreeSpace("drive_letter")
- Added SI_GetLogicalDriveUsedSpace("drive_letter")

Examples for the new drive functions:

SI_GetLogicalDrives() returns something like this:
'C(OS) E(Main) V(Auxiliary)'

SI_GetLogicalDriveTotalSize("C") returns 131072
SI_GetLogicalDriveFreeSpace("C") returns 114954
SI_GetLogicalDriveUsedSpace("C") returns 16117

StainlessS
11th August 2020, 19:34
SI_GetLogicalDriveFreeSpace("C") returns 114954
Does that take into account current user allowed Disk Quota ?

EDIT: https://docs.microsoft.com/en-us/windows/win32/fileio/managing-disk-quotas

The NTFS file system supports disk quotas, which allow administrators to control the amount of data that each user can store on an NTFS file system volume.
Administrators can optionally configure the system to log an event when users are near their quota, and to deny further disk space to users who exceed their quota.
Administrators can also generate reports, and use the event monitor to track quota issues.

You can determine whether a file system supports disk quotas by calling the GetVolumeInformation function and examining the FILE_VOLUME_QUOTAS bit flag.

EDIT:
Some stuff I;ve used before

int __cdecl QueryFatVolume(const char *relname) {
// Return:- 1=FAT. 0 = Not FAT. -1 on error;
int ret = -1;
char FullPath[_MAX_PATH];
if(_fullpath(FullPath, relname, _MAX_PATH ) != NULL ) {
TCHAR RootPathName[_MAX_PATH];
_splitpath(FullPath,RootPathName, NULL,NULL,NULL );
char *p=RootPathName;
while(*p++);
--p;
if(p>RootPathName && p[-1] != '\\') {*p++='\\';*p='\0';}
TCHAR FileSystemNameBuffer[MAX_PATH+1];
BOOL result = GetVolumeInformation(RootPathName,NULL,0,NULL,NULL,NULL,FileSystemNameBuffer,MAX_PATH+1);
if(result) {
ret = (_strnicmp(FileSystemNameBuffer,"FAT",3)==0) ?1:0; // Just the 1st 3 characters (FAT/FAT32)
}
}
return ret;
}

__int64 __cdecl QueryDiskFreeSpace(const char *relname) {
__int64 ret = -1;
char FullPath[_MAX_PATH];
if(_fullpath(FullPath, relname, _MAX_PATH ) != NULL ) {
TCHAR RootPathName[_MAX_PATH];
_splitpath(FullPath,RootPathName, NULL,NULL,NULL );
char *p=RootPathName;
while(*p++);
--p;
if(p>RootPathName && p[-1] != '\\') {*p++='\\';*p='\0';}
ULARGE_INTEGER FreeBytesAvailableToCaller;
ULARGE_INTEGER TotalNumberOfBytes;
ULARGE_INTEGER TotalNumberOfFreeBytes;
BOOL result=GetDiskFreeSpaceEx(RootPathName,&FreeBytesAvailableToCaller,&TotalNumberOfBytes,&TotalNumberOfFreeBytes);
if(result) {
ret = __int64(FreeBytesAvailableToCaller.QuadPart);
}
}
return ret;
}

__int64 __cdecl QueryMaxFileSize(const char *relname) {
__int64 ret = -1;
char FullPath[_MAX_PATH];
if(_fullpath(FullPath, relname, _MAX_PATH ) != NULL ) {
TCHAR RootPathName[_MAX_PATH];
_splitpath(FullPath,RootPathName, NULL,NULL,NULL );
char *p=RootPathName;
while(*p++);
--p;
if(p>RootPathName && p[-1] != '\\') {*p++='\\';*p='\0';}
ULARGE_INTEGER FreeBytesAvailableToCaller;
ULARGE_INTEGER TotalNumberOfBytes;
ULARGE_INTEGER TotalNumberOfFreeBytes;
if(GetDiskFreeSpaceEx(RootPathName,&FreeBytesAvailableToCaller,&TotalNumberOfBytes,&TotalNumberOfFreeBytes)) {
__int64 dfs = __int64(FreeBytesAvailableToCaller.QuadPart) - 0x100000I64; // minus 1MB
if(dfs > 0) {
TCHAR FileSystemNameBuffer[MAX_PATH+1];
if(GetVolumeInformation(RootPathName,NULL,0,NULL,NULL,NULL,FileSystemNameBuffer,MAX_PATH+1)) {
if(_strnicmp(FileSystemNameBuffer,"FAT",3)==0) { // Just the 1st 3 characters (FAT/FAT32)
if(dfs>0xFFF00000i64) dfs = 0xFFF00000i64; // limit 4GB-1MB on FAT32
}
ret = dfs;
}
}
}
}
return ret;
}


EDIT: Usage in RT

AVSValue __cdecl RT_DBaseAlloc(AVSValue args, void* user_data, IScriptEnvironment* env) {
const char * myName = "RT_DBaseAlloc: ";
const char * fn = args[0].AsString();
const int records = args[1].AsInt();
const char *typestr = args[2].AsString();
const int StringlenMax = args[3].AsInt(256);
if(*fn=='\0') env->ThrowError("%sEmpty Filename",myName);

__int64 MaxFileSz = 0xFFFFF00000i64 ; // 1TB - 1MB // RT DBase Limit

int fatvol = QueryFatVolume(fn);
if(fatvol < 0) env->ThrowError("%sCannot query Filesystem",myName);

__int64 dfs = QueryDiskFreeSpace(fn) - 0x100000; // minus 1MB // Safety
if(dfs < 0) env->ThrowError("%sCannot query DiskFreeSpace",myName);
// dprintf("DiskFreeSpace=$%I64X",dfs);
__int64 maxfs = (fatvol==1)? 0xFFF00000i64 : MaxFileSz; // limit 4GB on FAT32
__int64 maxcurdfs=min(maxfs,dfs); // Max current space, Limit to free space available to user.

// ...