Here is another code sample that tries to convert the input string back using System.Runtime.InteropServices.Marshal. It appears most of the methods exposed return a pointer of type VT_INT, which seems to convert to a WIL data type VT_I4. I then pass the pointer to a UDF that attempts to read the memory from that pointer using IntControl 32. However it seems to truncate the data att he last character and I am not quite sure how to resolve this.....yet.
;***************************************************************************
;** Create a SecureString and attempt to convert it back to a string.
;**
;** Purpose: Create a dotNet SecureString
;** Inputs: String
;** Outputs: Displays the converted string.
;** Reference:
;** REQUIRES WinBatch 2013A or newer
;**>> ISSUE: It appears most of the methods exposed return a pointer of type VT_INT, which seems to convert
;** to a WIL data type VT_I4. I then pass the pointer to a UDF that attempts to read the memory from that pointer
;** using IntControl 32. However it seems to truncate the data att he last character and I am not quite sure how to
;** resolve this.....yet.
;** Developer: Deana Falk 2014.04.07
;***************************************************************************
If Version( )< '2013A'
Pause('Notice', 'Need 2013A or Newer Version of WinBatch')
Exit
EndIf
#DefineFunction udfGetStringFromPointer(pointer)
DebugTrace(22)
strFromPointer=""
;errormode(@off)
cValue=IntControl(32, pointer, "LONG", 0, 0)
;errormode(@on)
While cValue
strFromPointer=strFromPointer:Num2Char(cValue)
pointer=pointer + 1
cValue=IntControl(32, pointer, "LONG", 0,0)
EndWhile
Return(strFromPointer)
#EndFunction
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Load assemblies into the WinBatch process.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; mscorlib assembly is automatically loaded by WinBatch when the CLR is loaded.
; ObjectClrOption ('use','mscorlib, version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
ObjectClrOption("use","System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Prompt for input
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;initString = '0123456789'
initString = 'TestString'
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Create a class implemented by a managed assembly.
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Create a SecureString
testString = ObjectClrNew( 'System.Security.SecureString')
length = StrCharCount( initString )
for i = 0 to length-1
ochar = ObjectClrNew( 'System.Char', Char2Num(StrSub( initString, i, 1 )) )
testString.AppendChar(ochar)
next
length = testString.Length
testString.MakeReadOnly
;Pause(testString.ToString(), Length)
;Note that SecureString has no members that inspect, compare, or convert the value of a SecureString. The absence of such members helps protect the value of the
;instance from accidental or malicious exposure. Use appropriate members of the System.Runtime.InteropServices.Marshal class, such as the SecureStringToBSTR method,
;to manipulate the value of a SecureString object.
;The SecureString class and its members are not visible to COM. For more information, see ComVisibleAttribute.
;When you wish to use the value stored in the SecureString object, you will have to use the Marshal class (which can be found in the System.Runtime.InteropServices namespace).
;Among other things, this class provides methods for allocating unmanaged memory and copying unmanaged memory blocks. This includes methods that will convert the contents of
;your SecureSting object into an object of type BSTR (basic string or binary string) or a block of ANSI or Unicode memory.
Marshal = ObjectClrNew("System.Runtime.InteropServices.Marshal")
; ptr Returned from the following methods is type VT INT which is not currently supported bt WinBatch
ptr = Marshal.SecureStringToGlobalAllocUnicode(testString)
;ptr = Marshal.SecureStringToGlobalAllocAnsi(testString)
;ptr = Marshal.SecureStringToBSTR(testString)
WILptr = ObjectType( 'I4', ptr )
result = udfGetStringFromPointer(WILptr)
Pause(initString, result)
Exit