きっかけはWTSEnumerateSessionsExのWTS_SESSION_INFO_1構造体
肝心のセッション情報がuwscからだと取れない!ファック!みたいな出来事があり
自前の構造体を作る、構造体からデータを読み出す、が出来るモジュールを書いてみた
とりあえずは想定通りに動いてはいるけどそのうちボロが出るぞきっとこれ
まぁでもuwscだって頑張ればこんなことも出来るよって話…てことで、ね
ifb GET_UWSC_NAME = "Module_Struct.uws" then
try
try
print "構造体を作ってデータを格納し、そこらから値を読むテスト"
print
hashtbl hTestStruct
Struct.AddMember(hTestStruct, "int", Struct.TYPE_INT, 1234)
Struct.AddMember(hTestStruct, "long", Struct.TYPE_LONG, 5678)
Struct.AddMember(hTestStruct, "word", Struct.TYPE_WORD, $FFFF)
Struct.AddMember(hTestStruct, "byte", Struct.TYPE_BYTE, $FF)
Struct.AddMember(hTestStruct, "string", Struct.TYPE_STRING, "hello world")
Struct.AddMember(hTestStruct, "double", Struct.TYPE_DOUBLE, 3.1415)
Struct.AddMember(hTestStruct, "float", Struct.TYPE_FLOAT, 3.1415)
dim pTestStruct
testStructSize = Struct.CreateStruct(hTestStruct, pTestStruct)
if testStructSize then
print "Address of testStruct: " + pTestStruct
print "Size of testStruct: " + testStructSize + "byte"
if Struct.GetStructValues(pTestStruct, hTestStruct) then
for i = 0 to length(hTestStruct) - 1
name = hTestStruct[i, HASH_KEY]
print "pTestStruct." + name + " = " + Struct.GetMember(hTestStruct, name)
next
else
print Struct.GetLastErrorString()
endif
Struct.FreeStruct(pTestStruct)
else
print Struct.GetLastErrorString()
endif
print
print "構造体を作ってdll関数に渡し、値を読むテスト"
print
def_dll GetWindowRect(hwnd, dword):long:user32
hashtbl hRect
dim pRect
Struct.AddMember(hRect, "left", Struct.TYPE_LONG, 0)
Struct.AddMember(hRect, "top", Struct.TYPE_LONG, 0)
Struct.AddMember(hRect, "right", Struct.TYPE_LONG, 0)
Struct.AddMember(hRect, "bottom", Struct.TYPE_LONG, 0)
StructSize = Struct.CreateStruct(hRect, pRect)
id = exec("notepad")
GetWindowRect(idtohnd(id), pRect)
if StructSize > 0 then
print "Address of pRect: " + pRect
print "Size of pRect: " + StructSize + "byte"
if Struct.GetStructValues(pRect, hRect) then
for i = 0 to length(hRect) - 1
name = hRect[i, HASH_KEY]
print "pRect." + name + " = " + Struct.GetMember(hRect, name)
next
print
print "比較用"
print "status(id, ST_X) = " + status(id, ST_X)
print "status(id, ST_Y) = " + status(id, ST_Y)
print "status(id, ST_X) + status(id, ST_WIDTH) = " + (status(id, ST_X) + status(id, ST_WIDTH))
print "status(id, ST_Y) + status(id, ST_HEIGHT)= " + (status(id, ST_Y) + status(id, ST_HEIGHT))
else
print Struct.GetLastErrorString()
endif
Struct.FreeStruct(pTestStruct)
else
print Struct.GetLastErrorString()
endif
ctrlwin(id, close)
print
print "WTSEnumerateSessionsExに挑戦"
print "第4引数がWTS_SESSION_INFO_1構造体の配列のアドレスを格納した変数のポインタ"
print "なので、def_dll宣言時に通常の{ }展開では値が取れない"
print
def_dll WTSEnumerateSessionsExA(dword, var dword, dword, var dword, var dword):bool:Wtsapi32
dim PWTS_SESSION_INFO_1, COUNT
dim pLevel = 1, Filter = 0
hashtbl hWtsSessionInfoType
Struct.AddMember(hWtsSessionInfoType, "ExecEnvId", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "State", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "SessionId", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "pSessionName", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "pHostName", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "pUserName", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "pDomainName", Struct.TYPE_DWORD, 0)
Struct.AddMember(hWtsSessionInfoType, "pFarmName", Struct.TYPE_DWORD, 0)
sizeOfWtsSessionInfoType = Struct.GetSizeOfStruct(hWtsSessionInfoType)
if WTSEnumerateSessionsExA(null, pLevel, Filter, PWTS_SESSION_INFO_1, COUNT) then
for i = 0 to COUNT - 1
ptr = PWTS_SESSION_INFO_1 + (i * sizeOfWtsSessionInfoType)
if Struct.GetStructValues(ptr, hWtsSessionInfoType) then
for i = 0 to length(hWtsSessionInfoType) - 1
name = hWtsSessionInfoType[i, HASH_KEY]
value = Struct.GetMember(hWtsSessionInfoType, name)
print name + " = " + value
if pos("p", name) = 1 then //p*****はstringのポインタなので値も取る
value = Struct.GetValueFromPointer(value, Struct.TYPE_STRING)
print " " + copy(name, 2) + " = " + value
endif
next
endif
print
next
endif
exit
except
print TRY_ERRLINE
print TRY_ERRMSG
endtry
finally
pid = getid(GET_LOGPRINT_WIN)
while status(pid, ST_VISIBLE)
sleep(0.1)
wend
endtry
endif
module Struct
procedure Struct
_hashTypeName[TYPE_INT ] = "TYPE_INT"
_hashTypeName[TYPE_LONG ] = "TYPE_LONG"
_hashTypeName[TYPE_BOOL ] = "TYPE_BOOL"
_hashTypeName[TYPE_UINT ] = "TYPE_UINT"
_hashTypeName[TYPE_HWND ] = "TYPE_HWND"
_hashTypeName[TYPE_STRING ] = "TYPE_STRING"
_hashTypeName[TYPE_WSTRING ] = "TYPE_WSTRING"
_hashTypeName[TYPE_FLOAT ] = "TYPE_FLOAT"
_hashTypeName[TYPE_DOUBLE ] = "TYPE_DOUBLE"
_hashTypeName[TYPE_WORD ] = "TYPE_WORD"
_hashTypeName[TYPE_DWORD ] = "TYPE_DWORD"
_hashTypeName[TYPE_BYTE ] = "TYPE_BYTE"
_hashTypeName[TYPE_CHAR ] = "TYPE_CHAR"
_hashTypeName[TYPE_PCHAR ] = "TYPE_PCHAR"
_hashTypeName[TYPE_WCHAR ] = "TYPE_WCHAR"
_hashTypeName[TYPE_PWCHAR ] = "TYPE_PWCHAR"
_hashTypeName[TYPE_BOOLEAN ] = "TYPE_BOOLEAN"
_hashTypeName[TYPE_LONGLONG ] = "TYPE_LONGLONG"
_hashTypeName[TYPE_EXTENDED ] = "TYPE_EXTENDED"
_hashTypeName[TYPE_SAFEARRAY] = "TYPE_SAFEARRAY"
fend
dim _lastErrorDescription
hashtbl _hashTypeName
const TYPE_INT = 0
const TYPE_LONG = 1
const TYPE_BOOL = 2
const TYPE_UINT = 3
const TYPE_HWND = 4
const TYPE_STRING = 5
const TYPE_WSTRING = 6
const TYPE_FLOAT = 7
const TYPE_DOUBLE = 8
const TYPE_WORD = 9
const TYPE_DWORD = 10
const TYPE_BYTE = 11
const TYPE_CHAR = 12
const TYPE_PCHAR = 13
const TYPE_WCHAR = 14
const TYPE_PWCHAR = 15
const TYPE_BOOLEAN = 16
const TYPE_LONGLONG = 17
const TYPE_EXTENDED = 18
const TYPE_SAFEARRAY = 19
const MEMBER_TYPE = 0
const MEMBER_VALUE = 1
const MEM_COMMIT = $1000
const PAGE_READWRITE = $4
const PAGE_EXECUTE_READWRITE = $40
Const MEM_RELEASE = $8000
const MEM_DECOMMIT = $4000
def_dll VirtualAlloc(dword, dword, dword, dword):dword:kernel32
def_dll VirtualFree(dword, dword, dword):long:kernel32
function CreateStruct(hashStruct[], var pStruct)
structSize = GetSizeOfStruct(hashStruct)
if structSize then
result = structSize
pStruct = VirtualAlloc(null, structSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
ptr = pStruct
for i = 0 to length(hashStruct) - 1
mName = hashStruct[i, HASH_KEY]
type = GetMember(hashStruct, mName, MEMBER_TYPE)
value = GetMember(hashStruct, mName, MEMBER_VALUE)
size = _copyVariableToPointer(ptr, value, type)
if size then
ptr = ptr + size
else
_setErrorString("CreateStruct: _copyVariableToPointer()が次のエラーを返しました -> " + GetLastErrorString())
result = 0
exit
endif
next
else
_setErrorString("CreateStruct: GetSizeOfStruct()が次のエラーを返しました -> " + GetLastErrorString())
result = 0
endif
fend
function GetStructValues(pStruct,var hashStruct[])
result = true
ptr = pStruct
for i = 0 to length(hashStruct) - 1
mName = hashStruct[i, HASH_KEY]
type = GetMember(hashStruct, mName, MEMBER_TYPE)
value = _getValueFromPointer(ptr, type)
if value = empty then
_setErrorString("GetStructValues: _getValueFromPointer()が次のエラーを返しました -> " + GetLastErrorString())
result = false
exit
else
_setMemberValue(hashStruct, mName, value)
ptr = ptr + _getSize(type, value)
endif
next
fend
function GetValueFromPointer(pointer, type)
if pointer then
result = _getValueFromPointer(pointer, type)
if result = empty then
_setErrorString("GetValueFromPointer: _getValueFromPointer()が次のエラーを返しました -> " + GetLastErrorString())
endif
else
_setErrorString("GetValueFromPointer: pointerが0です")
result = empty
endif
fend
function FreeStruct(hStruct, size = 0)
result = VirtualFree(hStruct, size, MEM_RELEASE)
fend
function GetLastErrorString()
result = _lastErrorDescription
fend
function GetSizeOfStruct(hashStruct[])
result = 0
for i = 0 to length(hashStruct) - 1
mName = hashStruct[i, HASH_KEY]
type = GetMember(hashStruct, mName, MEMBER_TYPE)
select type
case TYPE_STRING
value = GetMember(hashStruct, mName, MEMBER_VALUE)
size = _getSize(type, value)
default
size = _getSize(type)
selend
if size then
result = result + size
else
_setErrorString("GetSizeOfStruct: 未対応の型[" + _hashTypeName[type] + "]")
result = 0
break
endif
next
fend
procedure AddMember(var hashStruct[], menberName, memberType, memberValue)
sa = safearray(0,1)
sa[MEMBER_TYPE] = memberType
sa[MEMBER_VALUE] = memberValue
hashStruct[menberName] = sa
fend
function GetMember(hashStruct[], menberName, CONST_MEMBER = MEMBER_VALUE)
sa = hashStruct[menberName]
result = sa[CONST_MEMBER]
fend
procedure _setMemberValue(var hashStruct[], menberName, memberValue)
sa = hashStruct[menberName]
sa[MEMBER_VALUE] = memberValue
hashStruct[menberName] = sa
fend
function _getSize(type, str = "")
result = 0
select type
case TYPE_INT, TYPE_LONG, TYPE_BOOL, TYPE_UINT, TYPE_HWND, TYPE_DWORD
result = 4
case TYPE_STRING
result = lengthb(str)
mod4 = result mod 4
if mod4 then result = result + (4 - mod4)
// case TYPE_WSTRING
case TYPE_FLOAT
result = 4
case TYPE_DOUBLE
result = 8
case TYPE_WORD
result = 2
case TYPE_BYTE, TYPE_CHAR, TYPE_BOOLEAN
result = 1
case TYPE_PCHAR, TYPE_PWCHAR
result = 4
// case TYPE_WCHAR
case TYPE_LONGLONG
result = 8
// case TYPE_EXTENDED
// case TYPE_SAFEARRAY
default
result = 0
selend
fend
function _copyVariableToPointer(pointer, variable, const_type)
try
result = _getSize(const_type, variable)
if result
select const_type
case TYPE_INT
def_dll RtlMoveMemory(dword, var int, dword):kernel32
case TYPE_LONG
def_dll RtlMoveMemory(dword, var LONG, dword):kernel32
case TYPE_BOOL
def_dll RtlMoveMemory(dword, var BOOL, dword):kernel32
case TYPE_UINT
def_dll RtlMoveMemory(dword, var UINT, dword):kernel32
case TYPE_HWND
def_dll RtlMoveMemory(dword, var HWND, dword):kernel32
case TYPE_STRING
def_dll RtlMoveMemory(dword, var STRING, dword):kernel32
case TYPE_WSTRING
def_dll RtlMoveMemory(dword, var WSTRING, dword):kernel32
case TYPE_FLOAT
def_dll RtlMoveMemory(dword, var FLOAT, dword):kernel32
case TYPE_DOUBLE
def_dll RtlMoveMemory(dword, var DOUBLE, dword):kernel32
case TYPE_WORD
def_dll RtlMoveMemory(dword, var WORD, dword):kernel32
case TYPE_DWORD
def_dll RtlMoveMemory(dword, var DWORD, dword):kernel32
case TYPE_BYTE
def_dll RtlMoveMemory(dword, var BYTE, dword):kernel32
case TYPE_CHAR
def_dll RtlMoveMemory(dword, CHAR, dword):kernel32
case TYPE_PCHAR
def_dll RtlMoveMemory(dword, PCHAR, dword):kernel32
case TYPE_WCHAR
def_dll RtlMoveMemory(dword, WCHAR, dword):kernel32
case TYPE_PWCHAR
def_dll RtlMoveMemory(dword, PWCHAR, dword):kernel32
case TYPE_BOOLEAN
def_dll RtlMoveMemory(dword, var BOOLEAN, dword):kernel32
case TYPE_LONGLONG
def_dll RtlMoveMemory(dword, var LONGLONG, dword):kernel32
case TYPE_EXTENDED
def_dll RtlMoveMemory(dword, var EXTENDED, dword):kernel32
case TYPE_SAFEARRAY
def_dll RtlMoveMemory(dword, var SAFEARRAY, dword):kernel32
default
_setErrorString("_copyVariableToPointer: 型指定が不正 [" + const_type + "]")
result = 0
exit
selend
RtlMoveMemory(pointer, variable, result)
else
_setErrorString("_copyVariableToPointer: 未対応の型[" + _hashTypeName[const_type] + "]")
endif
except
_setErrorString("_copyVariableToPointer: コピー失敗 - " + TRY_ERRMSG + " " + TRY_ERRLINE)
result = 0
endtry
fend
function _getValueFromPointer(pointer, const_type, buffer = "")
select const_type
case TYPE_INT
def_dll RtlMoveMemory(var int, dword, dword):kernel32
case TYPE_LONG
def_dll RtlMoveMemory(var long, dword, dword):kernel32
case TYPE_BOOL
def_dll RtlMoveMemory(var bool, dword, dword):kernel32
case TYPE_UINT
def_dll RtlMoveMemory(var uint, dword, dword):kernel32
case TYPE_HWND
def_dll RtlMoveMemory(var hwnd, dword, dword):kernel32
case TYPE_STRING
def_dll RtlMoveMemory(var string, dword, dword):kernel32
buffer = format(chr(0), 1024)
case TYPE_WSTRING
def_dll RtlMoveMemory(var wstring, dword, dword):kernel32
case TYPE_FLOAT
def_dll RtlMoveMemory(var float, dword, dword):kernel32
case TYPE_DOUBLE
def_dll RtlMoveMemory(var double, dword, dword):kernel32
case TYPE_WORD
def_dll RtlMoveMemory(var word, dword, dword):kernel32
case TYPE_DWORD
def_dll RtlMoveMemory(var dword, dword, dword):kernel32
case TYPE_BYTE
def_dll RtlMoveMemory(var byte, dword, dword):kernel32
case TYPE_CHAR
def_dll RtlMoveMemory(char, dword, dword):kernel32
case TYPE_PCHAR
def_dll RtlMoveMemory(pchar, dword, dword):kernel32
case TYPE_WCHAR
def_dll RtlMoveMemory(wchar, dword, dword):kernel32
case TYPE_PWCHAR
def_dll RtlMoveMemory(pwchar, dword, dword):kernel32
case TYPE_BOOLEAN
def_dll RtlMoveMemory(var boolean, dword, dword):kernel32
case TYPE_LONGLONG
def_dll RtlMoveMemory(var longlong, dword, dword):kernel32
case TYPE_EXTENDED
def_dll RtlMoveMemory(var extended, dword, dword):kernel32
case TYPE_SAFEARRAY
def_dll RtlMoveMemory(var safearray, dword, dword):kernel32
default
_setErrorString("_getValueFromPointer: 型指定が不正 [" + const_type + "]")
result = 0
exit
selend
try
if lengthb(buffer) then
result = buffer
size = _getSize(const_type, buffer)
else
result = empty
size = _getSize(const_type)
endif
if size
RtlMoveMemory(result, pointer, size)
else
_setErrorString("_getValueFromPointer: 未対応の型[" + _hashTypeName[const_type] + "]")
endif
except
_setErrorString("_getValueFromPointer: コピー失敗 - " + TRY_ERRMSG + " " + TRY_ERRLINE)
result = empty
endtry
fend
procedure _setErrorString(str)
_lastErrorDescription = str
fend
endmodule